Skip to content

Commit 134582d

Browse files
committed
tests/periph/selftest_shield: improve SPI test
- fix a copy-paste error (`TIMER_FREQ_UART_TEST` was used in the SPI test, but that should be `TIMER_FREQ_SPI_TEST`) - use 400 kHz as slow SPI frequency, as faster STM32 MCUs just cannot divide the APB clock down to 100 kHz - when detailed output is enabled, print the SPI clock in addition to the SPI mode to ease figuring out what went wrong - only have one `FAILURE` message for a too fast byte transfer per check, rather than per transmitted byte, to reduce the noise - work around a bug of `periph_timer` on STM32 by reducing the clock speed of the timer for the SPI test
1 parent b4dc8e3 commit 134582d

File tree

1 file changed

+27
-11
lines changed
  • tests/periph/selftest_shield

1 file changed

+27
-11
lines changed

tests/periph/selftest_shield/main.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* @}
2020
*/
2121

22+
#include <inttypes.h>
2223
#include <stdbool.h>
2324
#include <stdint.h>
2425
#include <stdatomic.h>
@@ -137,7 +138,7 @@
137138
* directly, so the CPU clock is the highest clock frequency available. But
138139
* some can't, so we handle them here explicitly. */
139140
#ifndef TIMER_FREQ_SPI_TEST
140-
# if defined(CPU_SAM3)
141+
# if defined(CPU_SAM3) || defined(CPU_STM32)
141142
# define TIMER_FREQ_SPI_TEST CLOCK_CORECLOCK / 4
142143
# elif defined(CPU_NRF52) || defined(CPU_NRF51)
143144
# define TIMER_FREQ_SPI_TEST MHZ(16)
@@ -784,13 +785,14 @@ static bool periph_spi_rxtx_test(spi_t bus, spi_mode_t mode, spi_clk_t clk,
784785
const char *test_in_detail)
785786
{
786787
(void)test_in_detail;
787-
bool failed = 0;
788+
bool failed = false;
789+
bool transfer_too_fast = false;
788790
print_start("SPI", test_in_detail);
789791
uint16_t byte_transfer_ticks = 0;
790792
memset(&serial_buf, 0, sizeof(serial_buf));
791793

792794
if (IS_USED(MODULE_PERIPH_TIMER)) {
793-
byte_transfer_ticks = 8ULL * TIMER_FREQ_UART_TEST / clk_hz;
795+
byte_transfer_ticks = 8ULL * TIMER_FREQ_SPI_TEST / clk_hz;
794796
}
795797

796798
/* D10 is C̅S̅, D7 is connected to C̅S̅ */
@@ -808,6 +810,7 @@ static bool periph_spi_rxtx_test(spi_t bus, spi_mode_t mode, spi_clk_t clk,
808810
/* C̅S̅ should still be HIGH while no chip is selected */
809811
failed |= TEST(gpio_read(cs_check) != 0);
810812

813+
uint16_t byte_time;
811814
for (uint8_t i = 0; i < UINT8_MAX; i++) {
812815
uint16_t start = 0;
813816
if (IS_USED(MODULE_PERIPH_TIMER)) {
@@ -819,15 +822,25 @@ static bool periph_spi_rxtx_test(spi_t bus, spi_mode_t mode, spi_clk_t clk,
819822
stop = timer_read(TIMER);
820823
}
821824
failed |= TEST(received == i);
822-
uint16_t byte_time = (uint16_t)(stop - start);
823-
/* We allow the actual SPI clock to be slower than requested, but not
824-
* faster. So the transfer needs to take *at least* the theoretical
825-
* time. Given the overhead of, this already has some room for error */
826-
failed |= TEST(byte_time >= byte_transfer_ticks);
827-
/* C̅S̅ should be still LOW while chip is selected */
825+
if (IS_USED(MODULE_PERIPH_TIMER)) {
826+
byte_time = (uint16_t)(stop - start);
827+
/* We allow the actual SPI clock to be slower than requested, but
828+
* not faster. So the transfer needs to take *at least* the
829+
* theoretical time. Given the overhead of, this already has some
830+
* room for error */
831+
transfer_too_fast |= (byte_time < byte_transfer_ticks);
832+
/* C̅S̅ should be still LOW while chip is selected */
833+
}
828834
failed |= TEST(gpio_read(cs_check) == 0);
829835
}
830836

837+
if (DETAILED_OUTPUT && transfer_too_fast) {
838+
printf("Ticks expected to transfer byte: >= %" PRIu16 ", but got: %"
839+
PRIu16 "\n",
840+
byte_transfer_ticks, byte_time);
841+
}
842+
843+
failed |= TEST(!transfer_too_fast);
831844
failed |= TEST(spi_transfer_byte(bus, cs, false, UINT8_MAX) == UINT8_MAX);
832845
/* C̅S̅ should be again HIGH while now that no chip is selected */
833846
failed |= TEST(gpio_read(cs_check) != 0);
@@ -871,8 +884,8 @@ static bool periph_spi_test(void)
871884
}
872885

873886
bool failed = false;
874-
static const spi_clk_t clocks[] = { SPI_CLK_100KHZ, SPI_CLK_1MHZ, SPI_CLK_10MHZ };
875-
static const uint32_t clk_hzs[] = { KHZ(100), MHZ(1), MHZ(10) };
887+
static const spi_clk_t clocks[] = { SPI_CLK_400KHZ, SPI_CLK_1MHZ, SPI_CLK_10MHZ };
888+
static const uint32_t clk_hzs[] = { KHZ(400), MHZ(1), MHZ(10) };
876889

877890
if (IS_USED(MODULE_PCF857X)) {
878891
for (int i = 0; i < (int)ARRAY_SIZE(spi_clk_check_pins); i++) {
@@ -888,6 +901,9 @@ static bool periph_spi_test(void)
888901
for (unsigned j = 0; j < ARRAY_SIZE(clocks); j++) {
889902
spi_clk_t clk = clocks[j];
890903
uint32_t clk_hz = clk_hzs[j];
904+
if (DETAILED_OUTPUT) {
905+
printf("SPI CLK %" PRIu32 " Hz\n", clk_hz);
906+
}
891907
failed |= periph_spi_rxtx_test(bus, SPI_MODE_0, clk, clk_hz, clk_check, false, "mode 0");
892908
failed |= periph_spi_rxtx_test(bus, SPI_MODE_1, clk, clk_hz, clk_check, false, "mode 1");
893909
failed |= periph_spi_rxtx_test(bus, SPI_MODE_2, clk, clk_hz, clk_check, true, "mode 2");

0 commit comments

Comments
 (0)