Skip to content

Commit 3a2f6e9

Browse files
authored
Merge pull request #8832 from j3hill/nRF52840_QSPI
nRF52840_DK: "qspi_api.c" check read/write WORD alignment, set clock frequency divider
2 parents 99778bd + 2c4a3d5 commit 3a2f6e9

File tree

1 file changed

+61
-5
lines changed

1 file changed

+61
-5
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ TODO
5353
- dummy cycles
5454
*/
5555

56-
#define MBED_HAL_QSPI_HZ_TO_CONFIG(hz) ((32000000/(hz))-1)
5756
#define MBED_HAL_QSPI_MAX_FREQ 32000000UL
5857

5958
// NRF supported R/W opcodes
@@ -68,10 +67,15 @@ TODO
6867
#define PP4O_opcode 0x32
6968
#define PP4IO_opcode 0x38
7069

70+
#define SCK_DELAY 0x05
71+
#define WORD_MASK 0x03
72+
7173
static nrf_drv_qspi_config_t config;
7274

7375
// Private helper function to track initialization
7476
static ret_code_t _qspi_drv_init(void);
77+
// Private helper function to set NRF frequency divider
78+
nrf_qspi_frequency_t nrf_frequency(int hz);
7579

7680
qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, bool write)
7781
{
@@ -207,8 +211,8 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
207211
config.pins.io3_pin = (uint32_t)io3;
208212
config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;
209213

210-
config.phy_if.sck_freq = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz);
211-
config.phy_if.sck_delay = 0x05;
214+
config.phy_if.sck_freq = nrf_frequency(hz);
215+
config.phy_if.sck_delay = SCK_DELAY;
212216
config.phy_if.dpmen = false;
213217
config.phy_if.spi_mode = mode == 0 ? NRF_QSPI_MODE_0 : NRF_QSPI_MODE_1;
214218

@@ -232,8 +236,8 @@ qspi_status_t qspi_free(qspi_t *obj)
232236

233237
qspi_status_t qspi_frequency(qspi_t *obj, int hz)
234238
{
235-
config.phy_if.sck_freq = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz);
236-
239+
config.phy_if.sck_freq = nrf_frequency(hz);
240+
237241
// use sync version, no handler
238242
ret_code_t ret = _qspi_drv_init();
239243
if (ret == NRF_SUCCESS ) {
@@ -247,6 +251,11 @@ qspi_status_t qspi_frequency(qspi_t *obj, int hz)
247251

248252
qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void *data, size_t *length)
249253
{
254+
// length needs to be rounded up to the next WORD (4 bytes)
255+
if ((*length & WORD_MASK) > 0) {
256+
return QSPI_STATUS_INVALID_PARAMETER;
257+
}
258+
250259
qspi_status_t status = qspi_prepare_command(obj, command, true);
251260
if (status != QSPI_STATUS_OK) {
252261
return status;
@@ -263,6 +272,11 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
263272

264273
qspi_status_t qspi_read(qspi_t *obj, const qspi_command_t *command, void *data, size_t *length)
265274
{
275+
// length needs to be rounded up to the next WORD (4 bytes)
276+
if ((*length & WORD_MASK) > 0) {
277+
return QSPI_STATUS_INVALID_PARAMETER;
278+
}
279+
266280
qspi_status_t status = qspi_prepare_command(obj, command, false);
267281
if (status != QSPI_STATUS_OK) {
268282
return status;
@@ -344,6 +358,48 @@ static ret_code_t _qspi_drv_init(void)
344358
return ret;
345359
}
346360

361+
// Private helper to set NRF frequency divider
362+
nrf_qspi_frequency_t nrf_frequency(int hz)
363+
{
364+
nrf_qspi_frequency_t freq = NRF_QSPI_FREQ_32MDIV16;
365+
366+
// Convert hz to closest NRF frequency divider
367+
if (hz < 2130000)
368+
freq = NRF_QSPI_FREQ_32MDIV16; // 2.0 MHz, minimum supported frequency
369+
else if (hz < 2290000)
370+
freq = NRF_QSPI_FREQ_32MDIV15; // 2.13 MHz
371+
else if (hz < 2460000)
372+
freq = NRF_QSPI_FREQ_32MDIV14; // 2.29 MHz
373+
else if (hz < 2660000)
374+
freq = NRF_QSPI_FREQ_32MDIV13; // 2.46 Mhz
375+
else if (hz < 2900000)
376+
freq = NRF_QSPI_FREQ_32MDIV12; // 2.66 MHz
377+
else if (hz < 3200000)
378+
freq = NRF_QSPI_FREQ_32MDIV11; // 2.9 MHz
379+
else if (hz < 3550000)
380+
freq = NRF_QSPI_FREQ_32MDIV10; // 3.2 MHz
381+
else if (hz < 4000000)
382+
freq = NRF_QSPI_FREQ_32MDIV9; // 3.55 MHz
383+
else if (hz < 4570000)
384+
freq = NRF_QSPI_FREQ_32MDIV8; // 4.0 MHz
385+
else if (hz < 5330000)
386+
freq = NRF_QSPI_FREQ_32MDIV7; // 4.57 MHz
387+
else if (hz < 6400000)
388+
freq = NRF_QSPI_FREQ_32MDIV6; // 5.33 MHz
389+
else if (hz < 8000000)
390+
freq = NRF_QSPI_FREQ_32MDIV5; // 6.4 MHz
391+
else if (hz < 10600000)
392+
freq = NRF_QSPI_FREQ_32MDIV4; // 8.0 MHz
393+
else if (hz < 16000000)
394+
freq = NRF_QSPI_FREQ_32MDIV3; // 10.6 MHz
395+
else if (hz < 32000000)
396+
freq = NRF_QSPI_FREQ_32MDIV2; // 16 MHz
397+
else
398+
freq = NRF_QSPI_FREQ_32MDIV1; // 32 MHz
399+
400+
return freq;
401+
}
402+
347403

348404
#endif
349405

0 commit comments

Comments
 (0)