xref: /btstack/platform/chibios/hal_flash_bank_chibios.c (revision 065fc9a3d9ed4f0d223eff283968bd32564011a2)
1*065fc9a3SMatthias Ringwald /*
2*065fc9a3SMatthias Ringwald  * Copyright (C) 2022 BlueKitchen GmbH
3*065fc9a3SMatthias Ringwald  *
4*065fc9a3SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*065fc9a3SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*065fc9a3SMatthias Ringwald  * are met:
7*065fc9a3SMatthias Ringwald  *
8*065fc9a3SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*065fc9a3SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*065fc9a3SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*065fc9a3SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*065fc9a3SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*065fc9a3SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*065fc9a3SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*065fc9a3SMatthias Ringwald  *    from this software without specific prior written permission.
16*065fc9a3SMatthias Ringwald  *
17*065fc9a3SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
18*065fc9a3SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*065fc9a3SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20*065fc9a3SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
21*065fc9a3SMatthias Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22*065fc9a3SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23*065fc9a3SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24*065fc9a3SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25*065fc9a3SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26*065fc9a3SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27*065fc9a3SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*065fc9a3SMatthias Ringwald  * SUCH DAMAGE.
29*065fc9a3SMatthias Ringwald  *
30*065fc9a3SMatthias Ringwald  */
31*065fc9a3SMatthias Ringwald 
32*065fc9a3SMatthias Ringwald /*
33*065fc9a3SMatthias Ringwald  *  hal_flash_bank_chbios.c
34*065fc9a3SMatthias Ringwald  *
35*065fc9a3SMatthias Ringwald  *  HAL abstraction for Flash memory using hal_flash and hal_efl.h on ELFD1
36*065fc9a3SMatthias Ringwald  */
37*065fc9a3SMatthias Ringwald 
38*065fc9a3SMatthias Ringwald #define BTSTACK_FILE__ "hal_flash_bank_chibios.c"
39*065fc9a3SMatthias Ringwald 
40*065fc9a3SMatthias Ringwald #include "hal_flash_bank.h"
41*065fc9a3SMatthias Ringwald #include "btstack_debug.h"
42*065fc9a3SMatthias Ringwald #include "btstack_util.h"
43*065fc9a3SMatthias Ringwald 
44*065fc9a3SMatthias Ringwald #include "hal_flash_bank_chibios.h"
45*065fc9a3SMatthias Ringwald #include "hal.h"
46*065fc9a3SMatthias Ringwald 
47*065fc9a3SMatthias Ringwald #include <inttypes.h>
48*065fc9a3SMatthias Ringwald #include <string.h> // memcpy
49*065fc9a3SMatthias Ringwald 
50*065fc9a3SMatthias Ringwald uint32_t hal_flash_bank_chibios_get_size(void * context){
51*065fc9a3SMatthias Ringwald     hal_flash_bank_chbios_t * self = (hal_flash_bank_chbios_t *) context;
52*065fc9a3SMatthias Ringwald     return self->sector_size;
53*065fc9a3SMatthias Ringwald }
54*065fc9a3SMatthias Ringwald 
55*065fc9a3SMatthias Ringwald uint32_t hal_flash_bank_chibios_get_alignment(void * context){
56*065fc9a3SMatthias Ringwald     UNUSED(context);
57*065fc9a3SMatthias Ringwald     return 4;
58*065fc9a3SMatthias Ringwald }
59*065fc9a3SMatthias Ringwald 
60*065fc9a3SMatthias Ringwald void hal_flash_bank_chibios_erase(void * context, int bank){
61*065fc9a3SMatthias Ringwald     hal_flash_bank_chbios_t * self = (hal_flash_bank_chbios_t *) context;
62*065fc9a3SMatthias Ringwald     if (bank > 1) return;
63*065fc9a3SMatthias Ringwald     flashStartEraseSector(&EFLD1, self->sectors[bank]);
64*065fc9a3SMatthias Ringwald     // poll until done
65*065fc9a3SMatthias Ringwald     bool done = false;
66*065fc9a3SMatthias Ringwald     while (!done){
67*065fc9a3SMatthias Ringwald         uint32_t retry_delay_ms;
68*065fc9a3SMatthias Ringwald         flash_error_t result = flashQueryErase(&EFLD1, &retry_delay_ms);
69*065fc9a3SMatthias Ringwald         switch (result){
70*065fc9a3SMatthias Ringwald             case FLASH_BUSY_ERASING:
71*065fc9a3SMatthias Ringwald                 chThdSleepMilliseconds( retry_delay_ms );
72*065fc9a3SMatthias Ringwald                 break;
73*065fc9a3SMatthias Ringwald             case FLASH_NO_ERROR:
74*065fc9a3SMatthias Ringwald                 done = true;
75*065fc9a3SMatthias Ringwald                 break;
76*065fc9a3SMatthias Ringwald             default:
77*065fc9a3SMatthias Ringwald                 btstack_assert(false);
78*065fc9a3SMatthias Ringwald                 break;
79*065fc9a3SMatthias Ringwald         }
80*065fc9a3SMatthias Ringwald     }
81*065fc9a3SMatthias Ringwald }
82*065fc9a3SMatthias Ringwald 
83*065fc9a3SMatthias Ringwald void hal_flash_bank_chibios_read(void * context, int bank, uint32_t offset, uint8_t * buffer, uint32_t size){
84*065fc9a3SMatthias Ringwald     hal_flash_bank_chbios_t * self = (hal_flash_bank_chbios_t *) context;
85*065fc9a3SMatthias Ringwald 
86*065fc9a3SMatthias Ringwald     if (bank > 1) return;
87*065fc9a3SMatthias Ringwald     if (offset > self->sector_size) return;
88*065fc9a3SMatthias Ringwald     if ((offset + size) > self->sector_size) return;
89*065fc9a3SMatthias Ringwald 
90*065fc9a3SMatthias Ringwald     flashRead(&EFLD1, self->banks[bank] + offset, size, buffer);
91*065fc9a3SMatthias Ringwald }
92*065fc9a3SMatthias Ringwald 
93*065fc9a3SMatthias Ringwald void hal_flash_bank_chibios_write(void * context, int bank, uint32_t offset, const uint8_t * data, uint32_t size){
94*065fc9a3SMatthias Ringwald     hal_flash_bank_chbios_t * self = (hal_flash_bank_chbios_t *) context;
95*065fc9a3SMatthias Ringwald 
96*065fc9a3SMatthias Ringwald     if (bank > 1) return;
97*065fc9a3SMatthias Ringwald     if (offset > self->sector_size) return;
98*065fc9a3SMatthias Ringwald     if ((offset + size) > self->sector_size) return;
99*065fc9a3SMatthias Ringwald 
100*065fc9a3SMatthias Ringwald     flashProgram(&EFLD1, self->banks[bank] + offset, size, data);
101*065fc9a3SMatthias Ringwald }
102*065fc9a3SMatthias Ringwald 
103*065fc9a3SMatthias Ringwald static const hal_flash_bank_t hal_flash_bank_chibios = {
104*065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_get_size,
105*065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_get_alignment,
106*065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_erase,
107*065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_read,
108*065fc9a3SMatthias Ringwald     &hal_flash_bank_chibios_write
109*065fc9a3SMatthias Ringwald };
110*065fc9a3SMatthias Ringwald 
111*065fc9a3SMatthias Ringwald const hal_flash_bank_t * hal_flash_bank_chibios_init_instance(hal_flash_bank_chbios_t * context,
112*065fc9a3SMatthias Ringwald     uint16_t bank_0_sector, uint16_t bank_1_sector){
113*065fc9a3SMatthias Ringwald 
114*065fc9a3SMatthias Ringwald     const flash_descriptor_t * descriptor = flashGetDescriptor(&EFLD1);
115*065fc9a3SMatthias Ringwald     btstack_assert(bank_0_sector < descriptor->sectors_count);
116*065fc9a3SMatthias Ringwald     btstack_assert(bank_1_sector < descriptor->sectors_count);
117*065fc9a3SMatthias Ringwald 
118*065fc9a3SMatthias Ringwald     // get bank size and offsets from chibios flash descriptor
119*065fc9a3SMatthias Ringwald     uint32_t bank_0_offset = descriptor->sectors[bank_0_sector].offset;
120*065fc9a3SMatthias Ringwald     uint32_t bank_1_offset = descriptor->sectors[bank_1_sector].offset;
121*065fc9a3SMatthias Ringwald     uint32_t sector_size = btstack_min(descriptor->sectors[bank_0_sector].size, descriptor->sectors[bank_1_sector].size);
122*065fc9a3SMatthias Ringwald 
123*065fc9a3SMatthias Ringwald     context->sector_size = sector_size;
124*065fc9a3SMatthias Ringwald     context->sectors[0] = bank_0_sector;
125*065fc9a3SMatthias Ringwald     context->sectors[1] = bank_1_sector;
126*065fc9a3SMatthias Ringwald     context->banks[0]   = bank_0_offset;
127*065fc9a3SMatthias Ringwald     context->banks[1]   = bank_1_offset;
128*065fc9a3SMatthias Ringwald     log_info("Bank size %" PRIu32 " bytes", sector_size);
129*065fc9a3SMatthias Ringwald     log_info("Bank 0 uses sector %u, offset %" PRIx32, bank_0_sector, bank_0_offset);
130*065fc9a3SMatthias Ringwald     log_info("Bank 1 uses sector %u, offset %" PRIx32, bank_1_sector, bank_1_offset);
131*065fc9a3SMatthias Ringwald     return &hal_flash_bank_chibios;
132*065fc9a3SMatthias Ringwald }
133