@@ -83,11 +83,52 @@ bool spi_flash_sector_command(uint8_t command, uint32_t address) {
8383}
8484
8585bool spi_flash_write_data (uint32_t address , uint8_t * data , uint32_t length ) {
86+ // TODO: In theory, this also needs to handle unaligned data and
87+ // non-multiple-of-4 length. (in practice, I don't think the fat layer
88+ // generates such writes)
8689 return nrfx_qspi_write (data , length , address ) == NRFX_SUCCESS ;
8790}
8891
8992bool spi_flash_read_data (uint32_t address , uint8_t * data , uint32_t length ) {
90- return nrfx_qspi_read (data , length , address ) == NRFX_SUCCESS ;
93+ int misaligned = ((intptr_t )data ) & 3 ;
94+ // If the data is misaligned, we need to read 4 bytes
95+ // into an aligned buffer, and then copy 1, 2, or 3 bytes from the aligned
96+ // buffer to data.
97+ if (misaligned ) {
98+ int sz = 4 - misaligned ;
99+ __attribute__((aligned (4 ))) uint8_t buf [4 ];
100+
101+ if (nrfx_qspi_read (buf , 4 , address ) != NRFX_SUCCESS ) {
102+ return false;
103+ }
104+ memcpy (data , buf , sz );
105+ data += sz ;
106+ address += sz ;
107+ length -= sz ;
108+ }
109+
110+ // nrfx_qspi_read works in 4 byte increments, though it doesn't
111+ // signal an error if sz is not a multiple of 4. Read (directly into data)
112+ // all but the last 1, 2, or 3 bytes depending on the (remaining) length.
113+ uint32_t sz = length & ~(uint32_t )3 ;
114+ if (nrfx_qspi_read (data , sz , address ) != NRFX_SUCCESS ) {
115+ return false;
116+ }
117+ data += sz ;
118+ address += sz ;
119+ length -= sz ;
120+
121+ // Now, if we have any bytes left over, we must do a final read of 4
122+ // bytes and copy 1, 2, or 3 bytes to data.
123+ if (length ) {
124+ __attribute__((aligned (4 ))) uint8_t buf [4 ];
125+ if (nrfx_qspi_read (buf , 4 , address ) != NRFX_SUCCESS ) {
126+ return false;
127+ }
128+ memcpy (data , buf , length );
129+ }
130+
131+ return true;
91132}
92133
93134void spi_flash_init (void ) {
0 commit comments