Skip to content

Commit 853be94

Browse files
committed
use macro __SCB_DCACHE_LINE_SIZE to allocate cache-aligned buffer for FATFileSystem
added a split_buffer_by_cacheline function to split a buffer into cache-aligned parts and cache-unaligned parts added a QSPI_DMA_THRESHOLD_BYTES macro to define the minimum number of bytes to be transferred using DMA
1 parent 7ac16fa commit 853be94

File tree

2 files changed

+41
-51
lines changed

2 files changed

+41
-51
lines changed

storage/filesystem/fat/source/FATFileSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ extern "C" DWORD get_fattime(void)
156156
extern "C" void *ff_memalloc(UINT size)
157157
{
158158
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
159-
return aligned_alloc(32U, size);
159+
return aligned_alloc(__SCB_DCACHE_LINE_SIZE, size);
160160
#else
161161
return malloc(size);
162162
#endif

targets/TARGET_STM/qspi_api.c

Lines changed: 40 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@
4242
/* hence 2^(31+1), then FLASH_SIZE_DEFAULT = 1<<31 */
4343
#define QSPI_FLASH_SIZE_DEFAULT 0x80000000
4444

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+
4550
#if defined(QUADSPI)
4651
static QSPI_HandleTypeDef * qspiHandle; // Handle of whatever QSPI structure is used for QUADSPI
4752

@@ -1031,7 +1036,7 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
10311036
tr_error("HAL_OSPI_Command error");
10321037
status = QSPI_STATUS_ERROR;
10331038
} else {
1034-
if(st_command.NbData >= 32) {
1039+
if(st_command.NbData >= QSPI_DMA_THRESHOLD_BYTES) {
10351040
qspi_init_dma(obj);
10361041
NVIC_ClearPendingIRQ(obj->qspiIRQ);
10371042
NVIC_SetPriority(obj->qspiIRQ, 1);
@@ -1085,7 +1090,7 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
10851090
if (HAL_QSPI_Command(&obj->handle, &st_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
10861091
status = QSPI_STATUS_ERROR;
10871092
} else {
1088-
if(st_command.NbData >= 32) {
1093+
if(st_command.NbData >= QSPI_DMA_THRESHOLD_BYTES) {
10891094
qspi_init_dma(obj);
10901095
NVIC_ClearPendingIRQ(QUADSPI_IRQn);
10911096
NVIC_SetPriority(QUADSPI_IRQn, 1);
@@ -1123,42 +1128,50 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
11231128
}
11241129
#endif /* OCTOSPI */
11251130

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)
11291132
{
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;
11381136
if(*length < __SCB_DCACHE_LINE_SIZE)
11391137
{
1140-
pre_aligned_size = *length;
1138+
*pre_aligned_size = *length;
11411139
}
11421140
else
11431141
{
1144-
size_t address_remainder = (size_t) data % __SCB_DCACHE_LINE_SIZE;
1142+
size_t address_remainder = (size_t) buffer % __SCB_DCACHE_LINE_SIZE;
11451143
if(address_remainder == 0)
11461144
{
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;
11491147
}
11501148
else
11511149
{
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;
11551153
}
1156-
if(aligned_size == 0)
1154+
if(*aligned_size == 0)
11571155
{
1158-
pre_aligned_size = *length;
1159-
post_aligned_size = 0;
1156+
*pre_aligned_size = *length;
1157+
*post_aligned_size = 0;
11601158
}
11611159
}
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);
11621175
if(pre_aligned_size > 0)
11631176
{
11641177
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,
12271240
tr_error("HAL_OSPI_Command error");
12281241
status = QSPI_STATUS_ERROR;
12291242
} else {
1230-
if(st_command.NbData >= 32) {
1243+
if(st_command.NbData >= QSPI_DMA_THRESHOLD_BYTES) {
12311244
qspi_init_dma(obj);
12321245
NVIC_ClearPendingIRQ(obj->qspiIRQ);
12331246
NVIC_SetPriority(obj->qspiIRQ, 1);
@@ -1272,31 +1285,8 @@ qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data,
12721285
}
12731286

12741287
#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);
13001290
if(pre_aligned_size > 0)
13011291
{
13021292
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,
13651355
tr_error("HAL_QSPI_Command error");
13661356
status = QSPI_STATUS_ERROR;
13671357
} else {
1368-
if(st_command.NbData >= 32) {
1358+
if(st_command.NbData >= QSPI_DMA_THRESHOLD_BYTES) {
13691359
qspi_init_dma(obj);
13701360
NVIC_ClearPendingIRQ(QUADSPI_IRQn);
13711361
NVIC_SetPriority(QUADSPI_IRQn, 1);

0 commit comments

Comments
 (0)