|
42 | 42 | /* hence 2^(31+1), then FLASH_SIZE_DEFAULT = 1<<31 */ |
43 | 43 | #define QSPI_FLASH_SIZE_DEFAULT 0x80000000 |
44 | 44 |
|
| 45 | +/* Minimum number of bytes to be transferred using DMA, when DCACHE is not available */ |
| 46 | +/* When less than 32 bytes of data is transferred at a time, using DMA may actually be slower than polling */ |
| 47 | +/* When DACHE is available, DMA will be used when the buffer contains at least one cache-aligned block */ |
| 48 | +#define QSPI_DMA_THRESHOLD_BYTES 32 |
| 49 | + |
45 | 50 | #if defined(QUADSPI) |
46 | 51 | static QSPI_HandleTypeDef * qspiHandle; // Handle of whatever QSPI structure is used for QUADSPI |
47 | 52 |
|
@@ -1031,7 +1036,7 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void |
1031 | 1036 | tr_error("HAL_OSPI_Command error"); |
1032 | 1037 | status = QSPI_STATUS_ERROR; |
1033 | 1038 | } else { |
1034 | | - if(st_command.NbData >= 32) { |
| 1039 | + if(st_command.NbData >= QSPI_DMA_THRESHOLD_BYTES) { |
1035 | 1040 | qspi_init_dma(obj); |
1036 | 1041 | NVIC_ClearPendingIRQ(obj->qspiIRQ); |
1037 | 1042 | NVIC_SetPriority(obj->qspiIRQ, 1); |
@@ -1085,7 +1090,7 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void |
1085 | 1090 | if (HAL_QSPI_Command(&obj->handle, &st_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { |
1086 | 1091 | status = QSPI_STATUS_ERROR; |
1087 | 1092 | } else { |
1088 | | - if(st_command.NbData >= 32) { |
| 1093 | + if(st_command.NbData >= QSPI_DMA_THRESHOLD_BYTES) { |
1089 | 1094 | qspi_init_dma(obj); |
1090 | 1095 | NVIC_ClearPendingIRQ(QUADSPI_IRQn); |
1091 | 1096 | NVIC_SetPriority(QUADSPI_IRQn, 1); |
@@ -1123,42 +1128,50 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void |
1123 | 1128 | } |
1124 | 1129 | #endif /* OCTOSPI */ |
1125 | 1130 |
|
1126 | | - |
1127 | | -#if defined(OCTOSPI1) |
1128 | | -qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length) |
| 1131 | +static void split_buffer_by_cacheline(void *buffer, const size_t *length, size_t *pre_aligned_size, size_t *aligned_size, size_t *post_aligned_size) |
1129 | 1132 | { |
1130 | | - OSPI_RegularCmdTypeDef st_command; |
1131 | | - qspi_status_t status = qspi_prepare_command(command, &st_command); |
1132 | | - if (status != QSPI_STATUS_OK) { |
1133 | | - return status; |
1134 | | - } |
1135 | | - |
1136 | | -#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
1137 | | - size_t pre_aligned_size = 0, aligned_size = 0, post_aligned_size = 0; |
| 1133 | + *pre_aligned_size = 0; |
| 1134 | + *aligned_size = 0; |
| 1135 | + *post_aligned_size = 0; |
1138 | 1136 | if(*length < __SCB_DCACHE_LINE_SIZE) |
1139 | 1137 | { |
1140 | | - pre_aligned_size = *length; |
| 1138 | + *pre_aligned_size = *length; |
1141 | 1139 | } |
1142 | 1140 | else |
1143 | 1141 | { |
1144 | | - size_t address_remainder = (size_t) data % __SCB_DCACHE_LINE_SIZE; |
| 1142 | + size_t address_remainder = (size_t) buffer % __SCB_DCACHE_LINE_SIZE; |
1145 | 1143 | if(address_remainder == 0) |
1146 | 1144 | { |
1147 | | - aligned_size = *length & ~(__SCB_DCACHE_LINE_SIZE - 1); |
1148 | | - post_aligned_size = *length - aligned_size; |
| 1145 | + *aligned_size = *length & ~(__SCB_DCACHE_LINE_SIZE - 1); |
| 1146 | + *post_aligned_size = *length - *aligned_size; |
1149 | 1147 | } |
1150 | 1148 | else |
1151 | 1149 | { |
1152 | | - pre_aligned_size = __SCB_DCACHE_LINE_SIZE - address_remainder; |
1153 | | - aligned_size = (*length - pre_aligned_size) & ~(__SCB_DCACHE_LINE_SIZE - 1); |
1154 | | - post_aligned_size = *length - pre_aligned_size - aligned_size; |
| 1150 | + *pre_aligned_size = __SCB_DCACHE_LINE_SIZE - address_remainder; |
| 1151 | + *aligned_size = (*length - *pre_aligned_size) & ~(__SCB_DCACHE_LINE_SIZE - 1); |
| 1152 | + *post_aligned_size = *length - *pre_aligned_size - *aligned_size; |
1155 | 1153 | } |
1156 | | - if(aligned_size == 0) |
| 1154 | + if(*aligned_size == 0) |
1157 | 1155 | { |
1158 | | - pre_aligned_size = *length; |
1159 | | - post_aligned_size = 0; |
| 1156 | + *pre_aligned_size = *length; |
| 1157 | + *post_aligned_size = 0; |
1160 | 1158 | } |
1161 | 1159 | } |
| 1160 | +} |
| 1161 | + |
| 1162 | + |
| 1163 | +#if defined(OCTOSPI1) |
| 1164 | +qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length) |
| 1165 | +{ |
| 1166 | + OSPI_RegularCmdTypeDef st_command; |
| 1167 | + qspi_status_t status = qspi_prepare_command(command, &st_command); |
| 1168 | + if (status != QSPI_STATUS_OK) { |
| 1169 | + return status; |
| 1170 | + } |
| 1171 | + |
| 1172 | +#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
| 1173 | + size_t pre_aligned_size, aligned_size, post_aligned_size; |
| 1174 | + split_buffer_by_cacheline(data, length, &pre_aligned_size, &aligned_size, &post_aligned_size); |
1162 | 1175 | if(pre_aligned_size > 0) |
1163 | 1176 | { |
1164 | 1177 | st_command.NbData = pre_aligned_size; |
@@ -1227,7 +1240,7 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, |
1227 | 1240 | tr_error("HAL_OSPI_Command error"); |
1228 | 1241 | status = QSPI_STATUS_ERROR; |
1229 | 1242 | } else { |
1230 | | - if(st_command.NbData >= 32) { |
| 1243 | + if(st_command.NbData >= QSPI_DMA_THRESHOLD_BYTES) { |
1231 | 1244 | qspi_init_dma(obj); |
1232 | 1245 | NVIC_ClearPendingIRQ(obj->qspiIRQ); |
1233 | 1246 | NVIC_SetPriority(obj->qspiIRQ, 1); |
@@ -1272,31 +1285,8 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, |
1272 | 1285 | } |
1273 | 1286 |
|
1274 | 1287 | #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) |
1275 | | - size_t pre_aligned_size = 0, aligned_size = 0, post_aligned_size = 0; |
1276 | | - if(*length < __SCB_DCACHE_LINE_SIZE) |
1277 | | - { |
1278 | | - pre_aligned_size = *length; |
1279 | | - } |
1280 | | - else |
1281 | | - { |
1282 | | - size_t address_remainder = (size_t) data % __SCB_DCACHE_LINE_SIZE; |
1283 | | - if(address_remainder == 0) |
1284 | | - { |
1285 | | - aligned_size = *length & ~(__SCB_DCACHE_LINE_SIZE - 1); |
1286 | | - post_aligned_size = *length - aligned_size; |
1287 | | - } |
1288 | | - else |
1289 | | - { |
1290 | | - pre_aligned_size = __SCB_DCACHE_LINE_SIZE - address_remainder; |
1291 | | - aligned_size = (*length - pre_aligned_size) & ~(__SCB_DCACHE_LINE_SIZE - 1); |
1292 | | - post_aligned_size = *length - pre_aligned_size - aligned_size; |
1293 | | - } |
1294 | | - if(aligned_size == 0) |
1295 | | - { |
1296 | | - pre_aligned_size = *length; |
1297 | | - post_aligned_size = 0; |
1298 | | - } |
1299 | | - } |
| 1288 | + size_t pre_aligned_size, aligned_size, post_aligned_size; |
| 1289 | + split_buffer_by_cacheline(data, length, &pre_aligned_size, &aligned_size, &post_aligned_size); |
1300 | 1290 | if(pre_aligned_size > 0) |
1301 | 1291 | { |
1302 | 1292 | st_command.NbData = pre_aligned_size; |
@@ -1365,7 +1355,7 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, |
1365 | 1355 | tr_error("HAL_QSPI_Command error"); |
1366 | 1356 | status = QSPI_STATUS_ERROR; |
1367 | 1357 | } else { |
1368 | | - if(st_command.NbData >= 32) { |
| 1358 | + if(st_command.NbData >= QSPI_DMA_THRESHOLD_BYTES) { |
1369 | 1359 | qspi_init_dma(obj); |
1370 | 1360 | NVIC_ClearPendingIRQ(QUADSPI_IRQn); |
1371 | 1361 | NVIC_SetPriority(QUADSPI_IRQn, 1); |
|
0 commit comments