13
13
#include <zephyr/drivers/flash.h>
14
14
#include <zephyr/logging/log.h>
15
15
#include <zephyr/irq.h>
16
- #include <zephyr/toolchain.h>
17
16
18
17
#include <hardware/flash.h>
19
- #include <hardware/regs/io_qspi.h>
20
- #include <hardware/regs/pads_qspi.h>
21
- #include <hardware/structs/ssi.h>
22
- #include <hardware/structs/xip_ctrl.h>
23
- #include <hardware/resets.h>
24
- #include <pico/bootrom.h>
25
18
26
19
LOG_MODULE_REGISTER (flash_rpi_pico , CONFIG_FLASH_LOG_LEVEL );
27
20
@@ -31,162 +24,14 @@ LOG_MODULE_REGISTER(flash_rpi_pico, CONFIG_FLASH_LOG_LEVEL);
31
24
#define SECTOR_SIZE DT_PROP(DT_CHOSEN(zephyr_flash), erase_block_size)
32
25
#define ERASE_VALUE 0xff
33
26
#define FLASH_SIZE KB(CONFIG_FLASH_SIZE)
34
- #define FLASH_BASE CONFIG_FLASH_BASE_ADDRESS
35
- #define SSI_BASE_ADDRESS DT_REG_ADDR(DT_CHOSEN(zephyr_flash_controller))
36
27
37
28
static const struct flash_parameters flash_rpi_parameters = {
38
29
.write_block_size = 1 ,
39
30
.erase_value = ERASE_VALUE ,
40
31
};
41
32
42
- /**
43
- * Low level flash functions are based on:
44
- * github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c
45
- * and
46
- * github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_flash/flash.c
47
- */
48
-
49
- #define FLASHCMD_PAGE_PROGRAM 0x02
50
- #define FLASHCMD_READ_STATUS 0x05
51
- #define FLASHCMD_WRITE_ENABLE 0x06
52
- #define BOOT2_SIZE_WORDS 64
53
-
54
- enum outover {
55
- OUTOVER_NORMAL = 0 ,
56
- OUTOVER_INVERT ,
57
- OUTOVER_LOW ,
58
- OUTOVER_HIGH
59
- };
60
-
61
- static ssi_hw_t * const ssi = (ssi_hw_t * )SSI_BASE_ADDRESS ;
62
- static uint32_t boot2_copyout [BOOT2_SIZE_WORDS ];
63
- static bool boot2_copyout_valid ;
64
33
static uint8_t flash_ram_buffer [PAGE_SIZE ];
65
34
66
- static void __no_inline_not_in_flash_func (flash_init_boot2_copyout )(void )
67
- {
68
- if (boot2_copyout_valid ) {
69
- return ;
70
- }
71
- for (int i = 0 ; i < BOOT2_SIZE_WORDS ; ++ i ) {
72
- boot2_copyout [i ] = ((uint32_t * )FLASH_BASE )[i ];
73
- }
74
- __compiler_memory_barrier ();
75
- boot2_copyout_valid = true;
76
- }
77
-
78
- static void __no_inline_not_in_flash_func (flash_enable_xip_via_boot2 )(void )
79
- {
80
- ((void (* )(void ))((uint32_t )boot2_copyout + 1 ))();
81
- }
82
-
83
- void __no_inline_not_in_flash_func (flash_cs_force )(enum outover over )
84
- {
85
- io_rw_32 * reg = (io_rw_32 * ) (IO_QSPI_BASE + IO_QSPI_GPIO_QSPI_SS_CTRL_OFFSET );
86
- * reg = (* reg & ~IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS )
87
- | (over << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB );
88
- (void ) * reg ;
89
- }
90
-
91
- int __no_inline_not_in_flash_func (flash_was_aborted )()
92
- {
93
- return * (io_rw_32 * ) (IO_QSPI_BASE + IO_QSPI_GPIO_QSPI_SD1_CTRL_OFFSET )
94
- & IO_QSPI_GPIO_QSPI_SD1_CTRL_INOVER_BITS ;
95
- }
96
-
97
- void __no_inline_not_in_flash_func (flash_put_get )(const uint8_t * tx , uint8_t * rx , size_t count ,
98
- size_t rx_skip )
99
- {
100
- const uint max_in_flight = 16 - 2 ;
101
- size_t tx_count = count ;
102
- size_t rx_count = count ;
103
- bool did_something ;
104
- uint32_t tx_level ;
105
- uint32_t rx_level ;
106
- uint8_t rxbyte ;
107
-
108
- while (tx_count || rx_skip || rx_count ) {
109
- tx_level = ssi_hw -> txflr ;
110
- rx_level = ssi_hw -> rxflr ;
111
- did_something = false;
112
- if (tx_count && tx_level + rx_level < max_in_flight ) {
113
- ssi -> dr0 = (uint32_t ) (tx ? * tx ++ : 0 );
114
- -- tx_count ;
115
- did_something = true;
116
- }
117
- if (rx_level ) {
118
- rxbyte = ssi -> dr0 ;
119
- did_something = true;
120
- if (rx_skip ) {
121
- -- rx_skip ;
122
- } else {
123
- if (rx ) {
124
- * rx ++ = rxbyte ;
125
- }
126
- -- rx_count ;
127
- }
128
- }
129
-
130
- if (!did_something && __builtin_expect (flash_was_aborted (), 0 )) {
131
- break ;
132
- }
133
- }
134
- flash_cs_force (OUTOVER_HIGH );
135
- }
136
-
137
- void __no_inline_not_in_flash_func (flash_put_get_wrapper )(uint8_t cmd , const uint8_t * tx ,
138
- uint8_t * rx , size_t count )
139
- {
140
- flash_cs_force (OUTOVER_LOW );
141
- ssi -> dr0 = cmd ;
142
- flash_put_get (tx , rx , count , 1 );
143
- }
144
-
145
- static ALWAYS_INLINE void flash_put_cmd_addr (uint8_t cmd , uint32_t addr )
146
- {
147
- flash_cs_force (OUTOVER_LOW );
148
- addr |= cmd << 24 ;
149
- for (int i = 0 ; i < 4 ; ++ i ) {
150
- ssi -> dr0 = addr >> 24 ;
151
- addr <<= 8 ;
152
- }
153
- }
154
-
155
- void __no_inline_not_in_flash_func (flash_write_partial_internal )(uint32_t addr , const uint8_t * data ,
156
- size_t size )
157
- {
158
- uint8_t status_reg ;
159
-
160
- flash_put_get_wrapper (FLASHCMD_WRITE_ENABLE , NULL , NULL , 0 );
161
- flash_put_cmd_addr (FLASHCMD_PAGE_PROGRAM , addr );
162
- flash_put_get (data , NULL , size , 4 );
163
-
164
- do {
165
- flash_put_get_wrapper (FLASHCMD_READ_STATUS , NULL , & status_reg , 1 );
166
- } while (status_reg & 0x1 && !flash_was_aborted ());
167
- }
168
-
169
- void __no_inline_not_in_flash_func (flash_write_partial )(uint32_t flash_offs , const uint8_t * data ,
170
- size_t count )
171
- {
172
- rom_connect_internal_flash_fn connect_internal_flash = (rom_connect_internal_flash_fn )
173
- rom_func_lookup_inline (ROM_FUNC_CONNECT_INTERNAL_FLASH );
174
- rom_flash_exit_xip_fn exit_xip = (rom_flash_exit_xip_fn )
175
- rom_func_lookup_inline (ROM_FUNC_FLASH_EXIT_XIP );
176
- rom_flash_flush_cache_fn flush_cache = (rom_flash_flush_cache_fn )
177
- rom_func_lookup_inline (ROM_FUNC_FLASH_FLUSH_CACHE );
178
-
179
- flash_init_boot2_copyout ();
180
-
181
- __compiler_memory_barrier ();
182
-
183
- connect_internal_flash ();
184
- exit_xip ();
185
- flash_write_partial_internal (flash_offs , data , count );
186
- flush_cache ();
187
- flash_enable_xip_via_boot2 ();
188
- }
189
-
190
35
static bool is_valid_range (off_t offset , uint32_t size )
191
36
{
192
37
return (offset >= 0 ) && ((offset + size ) <= FLASH_SIZE );
0 commit comments