I am using the SD card driver from nRF5 SDK v17.0.2. Device nrf52840, IDE Segger, Custom PCB. nRF52 DK as progremmer.
There are problems when deinitializing the SD card.
If initialization failed, the deinitialization procedure is called in the interrupt handler, but then the card state is assigned the value IDLE instead of UNINITIALIZED, as a result, if we call deinitialization again in our program, the program freezes, due to the fact that the state of the card is IDLE and the state of SPI is UNINITIALIZED. An attempt to re-initialize SPI will result in an error and the program will hang.
1. I have made changes and ask the experts to comment on whether I did the right thing?
I also made changes in original driver that allow the card to work on SPI3 at a frequency of 32 MHz. But it doesn't matter for the described problem.
Part of the original code from the interrupt handler, which handles command responce missing:
if (!rx_data && m_cb.state.op != SDC_OP_RESET) { // Command response missing. sdc_evt_t evt; evt.result = SDC_ERROR_NOT_RESPONDING; switch (m_cb.state.op) { case SDC_OP_RESET: case SDC_OP_IDENTIFICATION: evt.type = SDC_EVT_INIT; m_cb.state.op = SDC_OP_IDLE; APP_ERROR_CHECK(app_sdc_uninit()); break; case SDC_OP_READ: evt.type = SDC_EVT_READ; break; case SDC_OP_WRITE: evt.type = SDC_EVT_WRITE; break; default: APP_ERROR_CHECK(NRF_ERROR_INTERNAL); break; } SDC_CS_DEASSERT(); m_cb.state.op = SDC_OP_IDLE; m_cb.handler(&evt); return; }
With my change:
if (!rx_data && m_cb.state.op != SDC_OP_RESET) { // Command response missing. sdc_evt_t evt; evt.result = SDC_ERROR_NOT_RESPONDING; switch (m_cb.state.op) { case SDC_OP_RESET: case SDC_OP_IDENTIFICATION: evt.type = SDC_EVT_INIT; m_cb.state.op = SDC_OP_IDLE; APP_ERROR_CHECK(app_sdc_uninit()); SDC_CS_DEASSERT(); m_cb.handler(&evt); break; case SDC_OP_READ: evt.type = SDC_EVT_READ; SDC_CS_DEASSERT(); m_cb.state.op = SDC_OP_IDLE; m_cb.handler(&evt); break; case SDC_OP_WRITE: evt.type = SDC_EVT_WRITE; SDC_CS_DEASSERT(); m_cb.state.op = SDC_OP_IDLE; m_cb.handler(&evt); break; default: APP_ERROR_CHECK(NRF_ERROR_INTERNAL); SDC_CS_DEASSERT(); m_cb.state.op = SDC_OP_IDLE; m_cb.handler(&evt); break; } return; }