Skip to content

Commit b24afed

Browse files
committed
SPI fpga test: use get_capabilities() function to skip test cases for unsupported features
1 parent 4b1b4f7 commit b24afed

File tree

2 files changed

+109
-24
lines changed
  • TESTS/mbed_hal_fpga_ci_test_shield/spi
  • targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52

2 files changed

+109
-24
lines changed

TESTS/mbed_hal_fpga_ci_test_shield/spi/main.cpp

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ typedef enum {
4141
TRANSFER_SPI_MASTER_TRANSFER_ASYNC
4242
} transfer_type_t;
4343

44-
#define FREQ_500_KHZ 500000
45-
#define FREQ_1_MHZ 1000000
46-
#define FREQ_2_MHZ 2000000
44+
#define FREQ_500_KHZ 500000
45+
#define FREQ_1_MHZ 1000000
46+
#define FREQ_2_MHZ 2000000
47+
#define FREQ_MIN ((uint32_t)0)
48+
#define FREQ_MAX ((uint32_t)-1)
49+
50+
#define TEST_CAPABILITY_BIT(MASK, CAP) ((1 << CAP) & (MASK))
4751

4852
const int TRANSFER_COUNT = 300;
4953
SPIMasterTester tester(DefaultFormFactor::pins(), DefaultFormFactor::restricted_pins());
@@ -62,6 +66,36 @@ void spi_async_handler()
6266
}
6367
#endif
6468

69+
/* Auxiliary function to check platform capabilities against test case. */
70+
static bool check_capabilities(const spi_capabilities_t *capabilities, SPITester::SpiMode spi_mode, uint32_t sym_size, transfer_type_t transfer_type, uint32_t frequency)
71+
{
72+
// Symbol size
73+
if (!TEST_CAPABILITY_BIT(capabilities->word_length, (sym_size - 1))) {
74+
utest_printf("\n<Specified symbol size is not supported on this platform> skipped ");
75+
return false;
76+
}
77+
78+
// SPI clock mode
79+
if (!TEST_CAPABILITY_BIT(capabilities->clk_modes, spi_mode)) {
80+
utest_printf("\n<Specified spi clock mode is not supported on this platform> skipped");
81+
return false;
82+
}
83+
84+
// Frequency
85+
if (frequency != FREQ_MAX && frequency != FREQ_MIN && frequency < capabilities->minimum_frequency && frequency > capabilities->maximum_frequency) {
86+
utest_printf("\n<Specified frequency is not supported on this platform> skipped ");
87+
return false;
88+
}
89+
90+
// Async mode
91+
if (transfer_type == TRANSFER_SPI_MASTER_TRANSFER_ASYNC && capabilities->async_mode == false) {
92+
utest_printf("\n<Async mode is not supported on this platform> skipped ");
93+
return false;
94+
}
95+
96+
return true;
97+
}
98+
6599
void fpga_spi_test_init_free(PinName mosi, PinName miso, PinName sclk, PinName ssel)
66100
{
67101
spi_init(&spi, mosi, miso, sclk, ssel);
@@ -72,6 +106,15 @@ void fpga_spi_test_init_free(PinName mosi, PinName miso, PinName sclk, PinName s
72106

73107
void fpga_spi_test_common(PinName mosi, PinName miso, PinName sclk, PinName ssel, SPITester::SpiMode spi_mode, uint32_t sym_size, transfer_type_t transfer_type, uint32_t frequency)
74108
{
109+
spi_capabilities_t capabilities;
110+
111+
112+
spi_get_capabilities(ssel, false, &capabilities);
113+
114+
if (check_capabilities(&capabilities, spi_mode, sym_size, transfer_type, frequency) == false) {
115+
return;
116+
}
117+
75118
uint32_t sym_mask = ((1 << sym_size) - 1);
76119

77120
// Remap pins for test
@@ -178,14 +221,10 @@ Case cases[] = {
178221
Case("SPI - mode testing (MODE_1)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode1, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
179222
Case("SPI - mode testing (MODE_2)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode2, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
180223
Case("SPI - mode testing (MODE_3)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode3, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
181-
#if !defined(TARGET_NRF52840_DK)
182224
Case("SPI - symbol size testing (16)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 16, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_1_MHZ> >),
183-
#endif
184225
Case("SPI - frequency testing (500 kHz)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_500_KHZ> >),
185226
Case("SPI - frequency testing (2 MHz)", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_WRITE_SYNC, FREQ_2_MHZ> >),
186-
187227
Case("SPI - block write", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_BLOCK_WRITE_SYNC, FREQ_1_MHZ> >),
188-
189228
#if DEVICE_SPI_ASYNCH
190229
Case("SPI - async mode", one_peripheral<SPIPort, DefaultFormFactor, fpga_spi_test_common<SPITester::Mode0, 8, TRANSFER_SPI_MASTER_TRANSFER_ASYNC, FREQ_1_MHZ> >)
191230
#endif

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/spi_api.c

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static void spi_configure_driver_instance(spi_t *obj)
105105

106106
/* Clean up and uninitialize peripheral if already initialized. */
107107
if (nordic_nrf5_spi_initialized[instance]) {
108-
nrfx_spi_uninit(&nordic_nrf5_spi_instance[instance]);
108+
nrfx_spi_uninit(&nordic_nrf5_spi_instance[instance]);
109109
}
110110

111111
#if DEVICE_SPI_ASYNCH
@@ -128,6 +128,51 @@ static void spi_configure_driver_instance(spi_t *obj)
128128
}
129129
}
130130

131+
void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap)
132+
{
133+
if (slave) {
134+
cap->minimum_frequency = 200000; // 200 kHz
135+
cap->maximum_frequency = 2000000; // 2 MHz
136+
cap->word_length = 0x00000080; // 8 bit symbols
137+
cap->support_slave_mode = false; // to be determined later based on ssel
138+
cap->hw_cs_handle = false; // irrelevant in slave mode
139+
cap->slave_delay_between_symbols_ns = 2500; // 2.5 us
140+
cap->clk_modes = 0x0f; // all clock modes
141+
#if DEVICE_SPI_ASYNCH
142+
cap->async_mode = true;
143+
#else
144+
cap->async_mode = false;
145+
#endif
146+
} else {
147+
cap->minimum_frequency = 200000; // 200 kHz
148+
cap->maximum_frequency = 2000000; // 2 MHz
149+
cap->word_length = 0x00000080; // 8 bit symbols
150+
cap->support_slave_mode = false; // to be determined later based on ssel
151+
cap->hw_cs_handle = false; // to be determined later based on ssel
152+
cap->slave_delay_between_symbols_ns = 0; // irrelevant in master mode
153+
cap->clk_modes = 0x0f; // all clock modes
154+
#if DEVICE_SPI_ASYNCH
155+
cap->async_mode = true;
156+
#else
157+
cap->async_mode = false;
158+
#endif
159+
}
160+
161+
// check if given ssel pin is in the cs pinmap
162+
const PinMap *cs_pins = spi_master_cs_pinmap();
163+
PinName pin = NC;
164+
while (cs_pins->pin != NC) {
165+
if (cs_pins->pin == ssel) {
166+
#if DEVICE_SPISLAVE
167+
cap->support_slave_mode = true;
168+
#endif
169+
cap->hw_cs_handle = true;
170+
break;
171+
}
172+
cs_pins++;
173+
}
174+
}
175+
131176
/** Initialize the SPI peripheral
132177
*
133178
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
@@ -191,7 +236,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
191236
/* Register interrupt handlers in driver with the NVIC. */
192237
NVIC_SetVector(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn, (uint32_t) SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler);
193238
NVIC_SetVector(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn, (uint32_t) SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler);
194-
NVIC_SetVector(SPIM2_SPIS2_SPI2_IRQn, (uint32_t) SPIM2_SPIS2_SPI2_IRQHandler);
239+
NVIC_SetVector(SPIM2_SPIS2_SPI2_IRQn, (uint32_t) SPIM2_SPIS2_SPI2_IRQHandler);
195240
}
196241
}
197242

@@ -247,13 +292,13 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
247292
nrf_spi_mode_t new_mode = NRF_SPI_MODE_0;
248293

249294
/* Convert Mbed HAL mode to Nordic mode. */
250-
if(mode == 0) {
295+
if (mode == 0) {
251296
new_mode = NRF_SPI_MODE_0;
252-
} else if(mode == 1) {
297+
} else if (mode == 1) {
253298
new_mode = NRF_SPI_MODE_1;
254-
} else if(mode == 2) {
299+
} else if (mode == 2) {
255300
new_mode = NRF_SPI_MODE_2;
256-
} else if(mode == 3) {
301+
} else if (mode == 3) {
257302
new_mode = NRF_SPI_MODE_3;
258303
}
259304

@@ -351,8 +396,9 @@ int spi_master_write(spi_t *obj, int value)
351396
desc.rx_length = 1;
352397
ret = nrfx_spi_xfer(&nordic_nrf5_spi_instance[instance], &desc, 0);
353398

354-
if (ret != NRFX_SUCCESS)
399+
if (ret != NRFX_SUCCESS) {
355400
DEBUG_PRINTF("%d error returned from nrf_spi_xfer\n\r");
401+
}
356402

357403
/* Manually set chip select pin if defined. */
358404
if (spi_inst->cs != NC) {
@@ -421,25 +467,25 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, cha
421467
int tx_actual_length = (tx_length > 255) ? 255 : tx_length;
422468

423469
/* Set tx buffer pointer. Set to NULL if no data is going to be transmitted. */
424-
const uint8_t * tx_actual_buffer = (tx_actual_length > 0) ?
425-
(const uint8_t *)(tx_buffer + tx_offset) :
426-
NULL;
470+
const uint8_t *tx_actual_buffer = (tx_actual_length > 0) ?
471+
(const uint8_t *)(tx_buffer + tx_offset) :
472+
NULL;
427473

428474
/* Check if rx_length is larger than 255 and if so, limit to 255. */
429475
int rx_actual_length = (rx_length > 255) ? 255 : rx_length;
430476

431477
/* Set rx buffer pointer. Set to NULL if no data is going to be received. */
432-
uint8_t * rx_actual_buffer = (rx_actual_length > 0) ?
433-
(uint8_t *)(rx_buffer + rx_offset) :
434-
NULL;
478+
uint8_t *rx_actual_buffer = (rx_actual_length > 0) ?
479+
(uint8_t *)(rx_buffer + rx_offset) :
480+
NULL;
435481

436482
/* Blocking transfer. */
437483
desc.p_tx_buffer = tx_actual_buffer;
438484
desc.p_rx_buffer = rx_actual_buffer;
439485
desc.tx_length = tx_actual_length;
440486
desc.rx_length = rx_actual_length;
441487
result = nrfx_spi_xfer(&nordic_nrf5_spi_instance[instance],
442-
&desc, 0);
488+
&desc, 0);
443489

444490
/* Update loop variables. */
445491
tx_length -= tx_actual_length;
@@ -596,7 +642,7 @@ static ret_code_t spi_master_transfer_async_continue(spi_t *obj)
596642
desc.rx_length = rx_length;
597643

598644
ret_code_t result = nrfx_spi_xfer(&nordic_nrf5_spi_instance[obj->spi.instance],
599-
&desc, 0);
645+
&desc, 0);
600646
return result;
601647
}
602648

@@ -662,7 +708,7 @@ static void nordic_nrf5_spi_event_handler(nrfx_spi_evt_t const *p_event, void *p
662708
callback();
663709
}
664710

665-
/* Transfer failed, signal error if mask is set. */
711+
/* Transfer failed, signal error if mask is set. */
666712
} else if (signal_error) {
667713

668714
/* Signal error if event mask matches and event handler is set. */
@@ -721,7 +767,7 @@ void spi_master_transfer(spi_t *obj,
721767
struct buffer_s *buffer_pointer;
722768

723769
buffer_pointer = &obj->tx_buff;
724-
buffer_pointer->buffer = (void*) tx;
770+
buffer_pointer->buffer = (void *) tx;
725771
buffer_pointer->length = tx_length;
726772
buffer_pointer->pos = 0;
727773
buffer_pointer->width = 8;

0 commit comments

Comments
 (0)