@@ -41,9 +41,60 @@ extern "C" {
4141 feature = "esp32c3" ,
4242 ) ) ]
4343 fn ets_efuse_get_spiconfig ( ) -> u32 ;
44+ }
45+
46+ #[ cfg( feature = "esp32s3" ) ]
47+ #[ allow( non_camel_case_types) ]
48+ mod s3 {
49+
50+ type spi_flash_func_t = unsafe extern "C" fn ( ) ;
51+ type spi_flash_op_t = unsafe extern "C" fn ( ) -> i32 ;
52+ type spi_flash_erase_t = unsafe extern "C" fn ( u32 ) -> i32 ;
53+ type spi_flash_rd_t = unsafe extern "C" fn ( u32 , * mut ( ) , i32 ) -> i32 ;
54+ type spi_flash_wr_t = unsafe extern "C" fn ( u32 , * const u32 , i32 ) -> i32 ;
55+ type spi_flash_ewr_t = unsafe extern "C" fn ( u32 , * const ( ) , u32 ) -> i32 ;
56+ type spi_flash_wren_t = unsafe extern "C" fn ( * mut ( ) ) -> i32 ;
57+ type spi_flash_erase_area_t = unsafe extern "C" fn ( u32 , u32 ) -> i32 ;
58+
59+ #[ repr( C ) ]
60+ pub struct spiflash_legacy_funcs_t {
61+ pub pp_addr_bit_len : u8 ,
62+ pub se_addr_bit_len : u8 ,
63+ pub be_addr_bit_len : u8 ,
64+ pub rd_addr_bit_len : u8 ,
65+ pub read_sub_len : u32 ,
66+ pub write_sub_len : u32 ,
67+ pub unlock : Option < spi_flash_op_t > ,
68+ pub erase_sector : Option < spi_flash_erase_t > ,
69+ pub erase_block : Option < spi_flash_erase_t > ,
70+ pub read : Option < spi_flash_rd_t > ,
71+ pub write : Option < spi_flash_wr_t > ,
72+ pub encrypt_write : Option < spi_flash_ewr_t > ,
73+ pub check_sus : Option < spi_flash_func_t > ,
74+ pub wren : Option < spi_flash_wren_t > ,
75+ pub wait_idle : Option < spi_flash_op_t > ,
76+ pub erase_area : Option < spi_flash_erase_area_t > ,
77+ }
78+ }
79+
80+ #[ cfg( feature = "esp32s3" ) ]
81+ use s3:: * ;
82+
83+ #[ cfg( feature = "esp32s3" ) ]
84+ extern "C" {
85+
86+ static mut rom_spiflash_legacy_funcs: * const spiflash_legacy_funcs_t ;
87+ static mut rom_spiflash_legacy_data: * mut ( ) ;
4488
45- #[ cfg( feature = "esp32s3" ) ]
4689 fn ets_efuse_flash_octal_mode ( ) -> bool ;
90+
91+ fn esp_rom_opiflash_wait_idle ( ) -> i32 ;
92+ fn esp_rom_opiflash_erase_block_64k ( addr : u32 ) -> i32 ;
93+ fn esp_rom_opiflash_erase_sector ( addr : u32 ) -> i32 ;
94+ fn esp_rom_opiflash_read ( addr : u32 , buf : * mut ( ) , len : i32 ) -> i32 ;
95+ fn esp_rom_opiflash_write ( addr : u32 , data : * const u32 , len : i32 ) -> i32 ;
96+ fn esp_rom_opiflash_wren ( p : * mut ( ) ) -> i32 ;
97+ fn esp_rom_opiflash_erase_area ( start_addr : u32 , end_addr : u32 ) -> i32 ;
4798}
4899
49100pub fn attach ( ) -> i32 {
@@ -65,6 +116,15 @@ pub fn attach() -> i32 {
65116 #[ cfg( feature = "esp32s3" ) ]
66117 if unsafe { ets_efuse_flash_octal_mode ( ) } {
67118 init_ospi_funcs ( ) ;
119+ } else {
120+ // For some reason, the default pointers are not set on boot. I'm not sure if
121+ // probe-rs does something wrong, or the ROM bootloader doesn't initialize memory properly under some conditions.
122+ // Leaving these uninitialized ends up with a division by zero exception. These addresses have been mined out of
123+ // the ROM elf, these supposed to be the default values of these variables.
124+ unsafe {
125+ rom_spiflash_legacy_funcs = 0x3FCEF670 as _ ;
126+ rom_spiflash_legacy_data = 0x3FCEF6A4 as _ ;
127+ }
68128 }
69129
70130 let config_result = unsafe {
@@ -126,49 +186,7 @@ pub fn wait_for_idle() -> i32 {
126186}
127187
128188#[ cfg( feature = "esp32s3" ) ]
129- #[ allow( non_camel_case_types) ]
130189fn init_ospi_funcs ( ) {
131- #[ repr( C ) ]
132- struct spiflash_legacy_funcs_t {
133- pp_addr_bit_len : u8 ,
134- se_addr_bit_len : u8 ,
135- be_addr_bit_len : u8 ,
136- rd_addr_bit_len : u8 ,
137- read_sub_len : u32 ,
138- write_sub_len : u32 ,
139- unlock : Option < spi_flash_op_t > ,
140- erase_sector : Option < spi_flash_erase_t > ,
141- erase_block : Option < spi_flash_erase_t > ,
142- read : Option < spi_flash_rd_t > ,
143- write : Option < spi_flash_wr_t > ,
144- encrypt_write : Option < spi_flash_ewr_t > ,
145- check_sus : Option < spi_flash_func_t > ,
146- wren : Option < spi_flash_wren_t > ,
147- wait_idle : Option < spi_flash_op_t > ,
148- erase_area : Option < spi_flash_erase_area_t > ,
149- }
150-
151- type spi_flash_func_t = unsafe extern "C" fn ( ) ;
152- type spi_flash_op_t = unsafe extern "C" fn ( ) -> i32 ;
153- type spi_flash_erase_t = unsafe extern "C" fn ( u32 ) -> i32 ;
154- type spi_flash_rd_t = unsafe extern "C" fn ( u32 , * mut ( ) , i32 ) -> i32 ;
155- type spi_flash_wr_t = unsafe extern "C" fn ( u32 , * const u32 , i32 ) -> i32 ;
156- type spi_flash_ewr_t = unsafe extern "C" fn ( u32 , * const ( ) , u32 ) -> i32 ;
157- type spi_flash_wren_t = unsafe extern "C" fn ( * mut ( ) ) -> i32 ;
158- type spi_flash_erase_area_t = unsafe extern "C" fn ( u32 , u32 ) -> i32 ;
159-
160- extern "C" {
161- static mut rom_spiflash_legacy_funcs: * const spiflash_legacy_funcs_t ;
162-
163- fn esp_rom_opiflash_wait_idle ( ) -> i32 ;
164- fn esp_rom_opiflash_erase_block_64k ( addr : u32 ) -> i32 ;
165- fn esp_rom_opiflash_erase_sector ( addr : u32 ) -> i32 ;
166- fn esp_rom_opiflash_read ( addr : u32 , buf : * mut ( ) , len : i32 ) -> i32 ;
167- fn esp_rom_opiflash_write ( addr : u32 , data : * const u32 , len : i32 ) -> i32 ;
168- fn esp_rom_opiflash_wren ( p : * mut ( ) ) -> i32 ;
169- fn esp_rom_opiflash_erase_area ( start_addr : u32 , end_addr : u32 ) -> i32 ;
170- }
171-
172190 static FUNCS : spiflash_legacy_funcs_t = spiflash_legacy_funcs_t {
173191 pp_addr_bit_len : 24 ,
174192 se_addr_bit_len : 24 ,
0 commit comments