xref: /btstack/platform/chibios/hal_flash_bank_chibios.c (revision f508b0b10e06bf2724fa1db0745a2d5459c18262)
1065fc9a3SMatthias Ringwald /*
2065fc9a3SMatthias Ringwald  * Copyright (C) 2022 BlueKitchen GmbH
3065fc9a3SMatthias Ringwald  *
4065fc9a3SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5065fc9a3SMatthias Ringwald  * modification, are permitted provided that the following conditions
6065fc9a3SMatthias Ringwald  * are met:
7065fc9a3SMatthias Ringwald  *
8065fc9a3SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9065fc9a3SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10065fc9a3SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11065fc9a3SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12065fc9a3SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13065fc9a3SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14065fc9a3SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15065fc9a3SMatthias Ringwald  *    from this software without specific prior written permission.
16065fc9a3SMatthias Ringwald  *
17065fc9a3SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
18065fc9a3SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19065fc9a3SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20065fc9a3SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
21065fc9a3SMatthias Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22065fc9a3SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23065fc9a3SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24065fc9a3SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25065fc9a3SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26065fc9a3SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27065fc9a3SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28065fc9a3SMatthias Ringwald  * SUCH DAMAGE.
29065fc9a3SMatthias Ringwald  *
30065fc9a3SMatthias Ringwald  */
31065fc9a3SMatthias Ringwald 
32065fc9a3SMatthias Ringwald /*
33065fc9a3SMatthias Ringwald  *  hal_flash_bank_chbios.c
34065fc9a3SMatthias Ringwald  *
35065fc9a3SMatthias Ringwald  *  HAL abstraction for Flash memory using hal_flash and hal_efl.h on ELFD1
36065fc9a3SMatthias Ringwald  */
37065fc9a3SMatthias Ringwald 
38065fc9a3SMatthias Ringwald #define BTSTACK_FILE__ "hal_flash_bank_chibios.c"
39065fc9a3SMatthias Ringwald 
40065fc9a3SMatthias Ringwald #include "hal_flash_bank.h"
41065fc9a3SMatthias Ringwald #include "btstack_debug.h"
42065fc9a3SMatthias Ringwald #include "btstack_util.h"
43065fc9a3SMatthias Ringwald 
44065fc9a3SMatthias Ringwald #include "hal_flash_bank_chibios.h"
45065fc9a3SMatthias Ringwald #include "hal.h"
46065fc9a3SMatthias Ringwald 
47065fc9a3SMatthias Ringwald #include <inttypes.h>
48065fc9a3SMatthias Ringwald #include <string.h> // memcpy
49065fc9a3SMatthias Ringwald 
hal_flash_bank_chibios_get_size(void * context)50065fc9a3SMatthias Ringwald uint32_t hal_flash_bank_chibios_get_size(void * context){
51065fc9a3SMatthias Ringwald     hal_flash_bank_chbios_t * self = (hal_flash_bank_chbios_t *) context;
52065fc9a3SMatthias Ringwald     return self->sector_size;
53065fc9a3SMatthias Ringwald }
54065fc9a3SMatthias Ringwald 
hal_flash_bank_chibios_get_alignment(void * context)55065fc9a3SMatthias Ringwald uint32_t hal_flash_bank_chibios_get_alignment(void * context){
56065fc9a3SMatthias Ringwald     UNUSED(context);
57065fc9a3SMatthias Ringwald     return 4;
58065fc9a3SMatthias Ringwald }
59065fc9a3SMatthias Ringwald 
hal_flash_bank_chibios_erase(void * context,int bank)60065fc9a3SMatthias Ringwald void hal_flash_bank_chibios_erase(void * context, int bank){
61065fc9a3SMatthias Ringwald     hal_flash_bank_chbios_t * self = (hal_flash_bank_chbios_t *) context;
62065fc9a3SMatthias Ringwald     if (bank > 1) return;
63065fc9a3SMatthias Ringwald     flashStartEraseSector(&EFLD1, self->sectors[bank]);
64065fc9a3SMatthias Ringwald     // poll until done
65065fc9a3SMatthias Ringwald     bool done = false;
66065fc9a3SMatthias Ringwald     while (!done){
67065fc9a3SMatthias Ringwald         uint32_t retry_delay_ms;
68065fc9a3SMatthias Ringwald         flash_error_t result = flashQueryErase(&EFLD1, &retry_delay_ms);
69065fc9a3SMatthias Ringwald         switch (result){
70065fc9a3SMatthias Ringwald             case FLASH_BUSY_ERASING:
71065fc9a3SMatthias Ringwald                 chThdSleepMilliseconds( retry_delay_ms );
72065fc9a3SMatthias Ringwald                 break;
73065fc9a3SMatthias Ringwald             case FLASH_NO_ERROR:
74065fc9a3SMatthias Ringwald                 done = true;
75065fc9a3SMatthias Ringwald                 break;
76065fc9a3SMatthias Ringwald             default:
77065fc9a3SMatthias Ringwald                 btstack_assert(false);
78065fc9a3SMatthias Ringwald                 break;
79065fc9a3SMatthias Ringwald         }
80065fc9a3SMatthias Ringwald     }
81065fc9a3SMatthias Ringwald }
82065fc9a3SMatthias Ringwald 
hal_flash_bank_chibios_read(void * context,int bank,uint32_t offset,uint8_t * buffer,uint32_t size)83065fc9a3SMatthias Ringwald void hal_flash_bank_chibios_read(void * context, int bank, uint32_t offset, uint8_t * buffer, uint32_t size){
84065fc9a3SMatthias Ringwald     hal_flash_bank_chbios_t * self = (hal_flash_bank_chbios_t *) context;
85065fc9a3SMatthias Ringwald 
86065fc9a3SMatthias Ringwald     if (bank > 1) return;
87065fc9a3SMatthias Ringwald     if (offset > self->sector_size) return;
88065fc9a3SMatthias Ringwald     if ((offset + size) > self->sector_size) return;
89065fc9a3SMatthias Ringwald 
90065fc9a3SMatthias Ringwald     flashRead(&EFLD1, self->banks[bank] + offset, size, buffer);
91065fc9a3SMatthias Ringwald }
92065fc9a3SMatthias Ringwald 
hal_flash_bank_chibios_write(void * context,int bank,uint32_t offset,const uint8_t * data,uint32_t size)93065fc9a3SMatthias Ringwald void hal_flash_bank_chibios_write(void * context, int bank, uint32_t offset, const uint8_t * data, uint32_t size){
94065fc9a3SMatthias Ringwald     hal_flash_bank_chbios_t * self = (hal_flash_bank_chbios_t *) context;
95065fc9a3SMatthias Ringwald 
96065fc9a3SMatthias Ringwald     if (bank > 1) return;
97065fc9a3SMatthias Ringwald     if (offset > self->sector_size) return;
98065fc9a3SMatthias Ringwald     if ((offset + size) > self->sector_size) return;
99065fc9a3SMatthias Ringwald 
100065fc9a3SMatthias Ringwald     flashProgram(&EFLD1, self->banks[bank] + offset, size, data);
101065fc9a3SMatthias Ringwald }
102065fc9a3SMatthias Ringwald 
103065fc9a3SMatthias Ringwald static const hal_flash_bank_t hal_flash_bank_chibios = {
104065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_get_size,
105065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_get_alignment,
106065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_erase,
107065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_read,
108065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_write
109065fc9a3SMatthias Ringwald };
110065fc9a3SMatthias Ringwald 
hal_flash_bank_chibios_init_instance(hal_flash_bank_chbios_t * context,uint16_t bank_0_sector,uint16_t bank_1_sector)111065fc9a3SMatthias Ringwald const hal_flash_bank_t * hal_flash_bank_chibios_init_instance(hal_flash_bank_chbios_t * context,
112065fc9a3SMatthias Ringwald     uint16_t bank_0_sector, uint16_t bank_1_sector){
113065fc9a3SMatthias Ringwald 
114*f508b0b1SMatthias Ringwald     // start EFL driver
115*f508b0b1SMatthias Ringwald     eflStart(&EFLD1, NULL);
116*f508b0b1SMatthias Ringwald 
117065fc9a3SMatthias Ringwald     const flash_descriptor_t * descriptor = flashGetDescriptor(&EFLD1);
118065fc9a3SMatthias Ringwald     btstack_assert(bank_0_sector < descriptor->sectors_count);
119065fc9a3SMatthias Ringwald     btstack_assert(bank_1_sector < descriptor->sectors_count);
120065fc9a3SMatthias Ringwald 
121065fc9a3SMatthias Ringwald     // get bank size and offsets from chibios flash descriptor
122065fc9a3SMatthias Ringwald     uint32_t bank_0_offset = descriptor->sectors[bank_0_sector].offset;
123065fc9a3SMatthias Ringwald     uint32_t bank_1_offset = descriptor->sectors[bank_1_sector].offset;
124065fc9a3SMatthias Ringwald     uint32_t sector_size = btstack_min(descriptor->sectors[bank_0_sector].size, descriptor->sectors[bank_1_sector].size);
125065fc9a3SMatthias Ringwald 
126065fc9a3SMatthias Ringwald     context->sector_size = sector_size;
127065fc9a3SMatthias Ringwald     context->sectors[0] = bank_0_sector;
128065fc9a3SMatthias Ringwald     context->sectors[1] = bank_1_sector;
129065fc9a3SMatthias Ringwald     context->banks[0]   = bank_0_offset;
130065fc9a3SMatthias Ringwald     context->banks[1]   = bank_1_offset;
131*f508b0b1SMatthias Ringwald 
132065fc9a3SMatthias Ringwald     log_info("Bank size %" PRIu32 " bytes", sector_size);
133065fc9a3SMatthias Ringwald     log_info("Bank 0 uses sector %u, offset %" PRIx32, bank_0_sector, bank_0_offset);
134065fc9a3SMatthias Ringwald     log_info("Bank 1 uses sector %u, offset %" PRIx32, bank_1_sector, bank_1_offset);
135*f508b0b1SMatthias Ringwald 
136065fc9a3SMatthias Ringwald     return &hal_flash_bank_chibios;
137065fc9a3SMatthias Ringwald }
138