Skip to content

Commit

Permalink
Nonblocking w25n01g code tidy up (betaflight#13562)
Browse files Browse the repository at this point in the history
* In case of BUS_ABORT still process and linked segments

* Tidy up segments

* Set SPI clock speed for w25n01g
  • Loading branch information
SteveCEvans authored Apr 22, 2024
1 parent d447d79 commit e0c0b64
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 21 deletions.
9 changes: 7 additions & 2 deletions src/main/drivers/bus_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,13 @@ FAST_IRQ_HANDLER static void spiIrqHandler(const extDevice_t *dev)
break;

case BUS_ABORT:
bus->curSegment = (busSegment_t *)BUS_SPI_FREE;
return;
// Skip to the end of the segment list
nextSegment = (busSegment_t *)bus->curSegment + 1;
while (nextSegment->len != 0) {
bus->curSegment = nextSegment;
nextSegment = (busSegment_t *)bus->curSegment + 1;
}
break;

case BUS_READY:
default:
Expand Down
42 changes: 23 additions & 19 deletions src/main/drivers/flash_w25n01g.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,10 @@ bool w25n01g_identify(flashDevice_t *fdevice, uint32_t jedecID)
fdevice->couldBeBusy = true; // Just for luck we'll assume the chip could be busy even though it isn't specced to be
fdevice->vTable = &w25n01g_vTable;

#ifndef USE_QUADSPI
// Need to set clock speed for 8kHz logging support with SPI
spiSetClkDivisor(fdevice->io.handle.dev, spiCalculateDivider(100000000));
#endif // USE_QUADSPI

return true;
}
Expand Down Expand Up @@ -663,26 +666,29 @@ uint32_t w25n01g_pageProgramContinue(flashDevice_t *fdevice, uint8_t const **buf
STATIC_DMA_DATA_AUTO uint8_t progExecDataLoad[] = { W25N01G_INSTRUCTION_PROGRAM_DATA_LOAD, 0, 0};
STATIC_DMA_DATA_AUTO uint8_t progRandomProgDataLoad[] = { W25N01G_INSTRUCTION_RANDOM_PROGRAM_DATA_LOAD, 0, 0};

static busSegment_t segmentsFlash[] = {
static busSegment_t segmentsDataLoad[] = {
{.u.buffers = {readStatus, readyStatus}, sizeof(readStatus), true, w25n01g_callbackReady},
{.u.buffers = {writeEnable, NULL}, sizeof(writeEnable), true, w25n01g_callbackWriteEnable},
{.u.buffers = {progExecCmd, NULL}, sizeof(progExecCmd), true, w25n01g_callbackWriteComplete},
{.u.buffers = {progExecDataLoad, NULL}, sizeof(progExecDataLoad), false, NULL},
{.u.link = {NULL, NULL}, 0, true, NULL},
};

static busSegment_t segmentsDataLoad[] = {
static busSegment_t segmentsRandomDataLoad[] = {
{.u.buffers = {readStatus, readyStatus}, sizeof(readStatus), true, w25n01g_callbackReady},
{.u.buffers = {writeEnable, NULL}, sizeof(writeEnable), true, w25n01g_callbackWriteEnable},
{.u.buffers = {progExecDataLoad, NULL}, sizeof(progExecDataLoad), false, NULL},
{.u.buffers = {NULL, NULL}, 0, true, NULL}, // Patch in pointer to data buffer here
{.u.buffers = {progRandomProgDataLoad, NULL}, sizeof(progRandomProgDataLoad), false, NULL},
{.u.link = {NULL, NULL}, 0, true, NULL},
};

static busSegment_t segmentsRandomDataLoad[] = {
static busSegment_t segmentsBuffer[] = {
{.u.buffers = {NULL, NULL}, 0, true, NULL},
{.u.link = {NULL, NULL}, 0, true, NULL},
};

static busSegment_t segmentsFlash[] = {
{.u.buffers = {readStatus, readyStatus}, sizeof(readStatus), true, w25n01g_callbackReady},
{.u.buffers = {writeEnable, NULL}, sizeof(writeEnable), true, w25n01g_callbackWriteEnable},
{.u.buffers = {progRandomProgDataLoad, NULL}, sizeof(progRandomProgDataLoad), false, NULL},
{.u.buffers = {NULL, NULL}, 0, true, NULL}, // Patch in pointer to data buffer here
{.u.buffers = {progExecCmd, NULL}, sizeof(progExecCmd), true, w25n01g_callbackWriteComplete},
{.u.link = {NULL, NULL}, 0, true, NULL},
};

Expand All @@ -698,22 +704,23 @@ uint32_t w25n01g_pageProgramContinue(flashDevice_t *fdevice, uint8_t const **buf
// Set the address and buffer details for the random data load
progRandomProgDataLoad[1] = (columnAddress >> 8) & 0xff;
progRandomProgDataLoad[2] = columnAddress & 0xff;
segmentsRandomDataLoad[3].u.buffers.txData = (uint8_t *)buffers[0];
segmentsRandomDataLoad[3].len = bufferSizes[0];

programSegment = segmentsRandomDataLoad;
} else {
programStartAddress = programLoadAddress = fdevice->currentWriteAddress;
columnAddress = W25N01G_LINEAR_TO_COLUMN(programLoadAddress);
// Set the address and buffer details for the data load
progExecDataLoad[1] = (columnAddress >> 8) & 0xff;
progExecDataLoad[2] = columnAddress & 0xff;
segmentsDataLoad[3].u.buffers.txData = (uint8_t *)buffers[0];
segmentsDataLoad[3].len = bufferSizes[0];

programSegment = segmentsDataLoad;
}

// Add the data buffer
segmentsBuffer[0].u.buffers.txData = (uint8_t *)buffers[0];
segmentsBuffer[0].len = bufferSizes[0];
segmentsBuffer[0].callback = NULL;

spiLinkSegments(fdevice->io.handle.dev, programSegment, segmentsBuffer);

bufferDirty = true;
programLoadAddress += bufferSizes[0];

Expand All @@ -724,17 +731,14 @@ uint32_t w25n01g_pageProgramContinue(flashDevice_t *fdevice, uint8_t const **buf
progExecCmd[2] = (currentPage >> 8) & 0xff;
progExecCmd[3] = currentPage & 0xff;

// Don't callback on completion of data load but rather after flashing
programSegment[3].callback = NULL;

spiLinkSegments(fdevice->io.handle.dev, programSegment, segmentsFlash);
spiLinkSegments(fdevice->io.handle.dev, segmentsBuffer, segmentsFlash);

bufferDirty = false;

programStartAddress = programLoadAddress;
} else {
// Callback on completion of data load
programSegment[3].callback = w25n01g_callbackWriteComplete;
segmentsBuffer[0].callback = w25n01g_callbackWriteComplete;
}

if (!fdevice->couldBeBusy) {
Expand Down

0 comments on commit e0c0b64

Please sign in to comment.