1fc456f6dSMatthias Ringwald /*
2fc456f6dSMatthias Ringwald * Copyright (C) 2017 BlueKitchen GmbH
3fc456f6dSMatthias Ringwald *
4fc456f6dSMatthias Ringwald * Redistribution and use in source and binary forms, with or without
5fc456f6dSMatthias Ringwald * modification, are permitted provided that the following conditions
6fc456f6dSMatthias Ringwald * are met:
7fc456f6dSMatthias Ringwald *
8fc456f6dSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright
9fc456f6dSMatthias Ringwald * notice, this list of conditions and the following disclaimer.
10fc456f6dSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright
11fc456f6dSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the
12fc456f6dSMatthias Ringwald * documentation and/or other materials provided with the distribution.
13fc456f6dSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of
14fc456f6dSMatthias Ringwald * contributors may be used to endorse or promote products derived
15fc456f6dSMatthias Ringwald * from this software without specific prior written permission.
16fc456f6dSMatthias Ringwald *
17*2fca4dadSMilanka Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
18fc456f6dSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19fc456f6dSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20*2fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
21*2fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22fc456f6dSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23fc456f6dSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24fc456f6dSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25fc456f6dSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26fc456f6dSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27fc456f6dSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28fc456f6dSMatthias Ringwald * SUCH DAMAGE.
29fc456f6dSMatthias Ringwald *
30fc456f6dSMatthias Ringwald */
31fc456f6dSMatthias Ringwald
32fc456f6dSMatthias Ringwald /*
33fc456f6dSMatthias Ringwald * hal_flash_bank_stm32.c
34fc456f6dSMatthias Ringwald *
35fc456f6dSMatthias Ringwald * HAL abstraction for Flash memory that can be written anywhere
36fc456f6dSMatthias Ringwald * after being erased
37fc456f6dSMatthias Ringwald */
38fc456f6dSMatthias Ringwald
39fc456f6dSMatthias Ringwald #include <stdint.h>
40fc456f6dSMatthias Ringwald #include <string.h> // memcpy
41fc456f6dSMatthias Ringwald
42fc456f6dSMatthias Ringwald #include "hal_flash_bank_msp432.h"
43fc456f6dSMatthias Ringwald #include "driverlib.h"
44fc456f6dSMatthias Ringwald #include "btstack_defines.h"
45fc456f6dSMatthias Ringwald
hal_flash_bank_msp432_get_size(void * context)46fc456f6dSMatthias Ringwald static uint32_t hal_flash_bank_msp432_get_size(void * context){
47fc456f6dSMatthias Ringwald hal_flash_bank_msp432_t * self = (hal_flash_bank_msp432_t *) context;
48fc456f6dSMatthias Ringwald return self->sector_size;
49fc456f6dSMatthias Ringwald }
50fc456f6dSMatthias Ringwald
hal_flash_bank_memory_msp432_get_alignment(void * context)51fc456f6dSMatthias Ringwald static uint32_t hal_flash_bank_memory_msp432_get_alignment(void * context){
52fc456f6dSMatthias Ringwald UNUSED(context);
53fc456f6dSMatthias Ringwald return 4;
54fc456f6dSMatthias Ringwald }
55fc456f6dSMatthias Ringwald
hal_flash_bank_msp432_erase(void * context,int bank)56fc456f6dSMatthias Ringwald static void hal_flash_bank_msp432_erase(void * context, int bank){
57fc456f6dSMatthias Ringwald
58fc456f6dSMatthias Ringwald hal_flash_bank_msp432_t * self = (hal_flash_bank_msp432_t *) context;
59fc456f6dSMatthias Ringwald if (bank > 1) return;
60fc456f6dSMatthias Ringwald
61fc456f6dSMatthias Ringwald /* Unprotecting sector */
62fc456f6dSMatthias Ringwald MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,self->sectors[bank]);
63fc456f6dSMatthias Ringwald
64fc456f6dSMatthias Ringwald /* Trying to erase the sector. Within this function, the API will
65fc456f6dSMatthias Ringwald automatically try to erase the maximum number of tries. If it fails,
66fc456f6dSMatthias Ringwald trap in an infinite loop */
67fc456f6dSMatthias Ringwald if(!MAP_FlashCtl_eraseSector(self->banks[bank]))
68fc456f6dSMatthias Ringwald while(1);
69fc456f6dSMatthias Ringwald
70fc456f6dSMatthias Ringwald /* Setting the sector back to protected */
71fc456f6dSMatthias Ringwald MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,self->sectors[bank]);
72fc456f6dSMatthias Ringwald }
73fc456f6dSMatthias Ringwald
hal_flash_bank_msp432_read(void * context,int bank,uint32_t offset,uint8_t * buffer,uint32_t size)74fc456f6dSMatthias Ringwald static void hal_flash_bank_msp432_read(void * context, int bank, uint32_t offset, uint8_t * buffer, uint32_t size){
75fc456f6dSMatthias Ringwald hal_flash_bank_msp432_t * self = (hal_flash_bank_msp432_t *) context;
76fc456f6dSMatthias Ringwald
77fc456f6dSMatthias Ringwald if (bank > 1) return;
78fc456f6dSMatthias Ringwald if (offset > self->sector_size) return;
79fc456f6dSMatthias Ringwald if ((offset + size) > self->sector_size) return;
80fc456f6dSMatthias Ringwald
81fc456f6dSMatthias Ringwald memcpy(buffer, ((uint8_t *) self->banks[bank]) + offset, size);
82fc456f6dSMatthias Ringwald }
83fc456f6dSMatthias Ringwald
hal_flash_bank_msp432_write(void * context,int bank,uint32_t offset,const uint8_t * data,uint32_t size)84fc456f6dSMatthias Ringwald static void hal_flash_bank_msp432_write(void * context, int bank, uint32_t offset, const uint8_t * data, uint32_t size){
85fc456f6dSMatthias Ringwald hal_flash_bank_msp432_t * self = (hal_flash_bank_msp432_t *) context;
86fc456f6dSMatthias Ringwald
87fc456f6dSMatthias Ringwald if (bank > 1) return;
88fc456f6dSMatthias Ringwald if (offset > self->sector_size) return;
89fc456f6dSMatthias Ringwald if ((offset + size) > self->sector_size) return;
90fc456f6dSMatthias Ringwald
91fc456f6dSMatthias Ringwald /* Unprotecting sector */
92fc456f6dSMatthias Ringwald MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,self->sectors[bank]);
93fc456f6dSMatthias Ringwald
94fc456f6dSMatthias Ringwald /* Trying to program the memory. Within this function, the API will
95fc456f6dSMatthias Ringwald automatically try to program the maximum number of tries. If it fails,
96fc456f6dSMatthias Ringwald trap inside an infinite loop */
97fc456f6dSMatthias Ringwald if(!MAP_FlashCtl_programMemory( (void *) data,
98fc456f6dSMatthias Ringwald (void*) ((uint8_t *) self->banks[bank]) + offset, size))
99fc456f6dSMatthias Ringwald while(1);
100fc456f6dSMatthias Ringwald
101fc456f6dSMatthias Ringwald /* Setting the sector back to protected */
102fc456f6dSMatthias Ringwald MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,self->sectors[bank]);
103fc456f6dSMatthias Ringwald }
104fc456f6dSMatthias Ringwald
105fc456f6dSMatthias Ringwald static const hal_flash_bank_t hal_flash_bank_msp432_impl = {
106fc456f6dSMatthias Ringwald /* uint32_t (*get_size)() */ &hal_flash_bank_msp432_get_size,
107fc456f6dSMatthias Ringwald /* uint32_t (*get_alignment)(..); */ &hal_flash_bank_memory_msp432_get_alignment,
108fc456f6dSMatthias Ringwald /* void (*erase)(..); */ &hal_flash_bank_msp432_erase,
109fc456f6dSMatthias Ringwald /* void (*read)(..); */ &hal_flash_bank_msp432_read,
110fc456f6dSMatthias Ringwald /* void (*write)(..); */ &hal_flash_bank_msp432_write,
111fc456f6dSMatthias Ringwald };
112fc456f6dSMatthias Ringwald
hal_flash_bank_msp432_init_instance(hal_flash_bank_msp432_t * context,uint32_t sector_size,uint32_t bank_0_sector,uint32_t bank_1_sector,uintptr_t bank_0_addr,uintptr_t bank_1_addr)113fc456f6dSMatthias Ringwald const hal_flash_bank_t * hal_flash_bank_msp432_init_instance(hal_flash_bank_msp432_t * context, uint32_t sector_size,
114fc456f6dSMatthias Ringwald uint32_t bank_0_sector, uint32_t bank_1_sector, uintptr_t bank_0_addr, uintptr_t bank_1_addr){
115fc456f6dSMatthias Ringwald context->sector_size = sector_size;
116fc456f6dSMatthias Ringwald context->sectors[0] = bank_0_sector;
117fc456f6dSMatthias Ringwald context->sectors[1] = bank_1_sector;
118fc456f6dSMatthias Ringwald context->banks[0] = bank_0_addr;
119fc456f6dSMatthias Ringwald context->banks[1] = bank_1_addr;
120fc456f6dSMatthias Ringwald return &hal_flash_bank_msp432_impl;
121fc456f6dSMatthias Ringwald }
122