mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #20089 from maribu/tests/periph/selftest_shield2
tests/periph/selftest_shield: improve SPI test
This commit is contained in:
commit
4e7f972303
@ -19,6 +19,7 @@
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
@ -134,7 +135,7 @@
|
|||||||
* directly, so the CPU clock is the highest clock frequency available. But
|
* directly, so the CPU clock is the highest clock frequency available. But
|
||||||
* some can't, so we handle them here explicitly. */
|
* some can't, so we handle them here explicitly. */
|
||||||
#ifndef TIMER_FREQ_SPI_TEST
|
#ifndef TIMER_FREQ_SPI_TEST
|
||||||
# if defined(CPU_SAM3)
|
# if defined(CPU_SAM3) || defined(CPU_STM32)
|
||||||
# define TIMER_FREQ_SPI_TEST CLOCK_CORECLOCK / 4
|
# define TIMER_FREQ_SPI_TEST CLOCK_CORECLOCK / 4
|
||||||
# elif defined(CPU_NRF52) || defined(CPU_NRF51)
|
# elif defined(CPU_NRF52) || defined(CPU_NRF51)
|
||||||
# define TIMER_FREQ_SPI_TEST MHZ(16)
|
# define TIMER_FREQ_SPI_TEST MHZ(16)
|
||||||
@ -781,13 +782,14 @@ static bool periph_spi_rxtx_test(spi_t bus, spi_mode_t mode, spi_clk_t clk,
|
|||||||
const char *test_in_detail)
|
const char *test_in_detail)
|
||||||
{
|
{
|
||||||
(void)test_in_detail;
|
(void)test_in_detail;
|
||||||
bool failed = 0;
|
bool failed = false;
|
||||||
|
bool transfer_too_fast = false;
|
||||||
print_start("SPI", test_in_detail);
|
print_start("SPI", test_in_detail);
|
||||||
uint16_t byte_transfer_ticks = 0;
|
uint16_t byte_transfer_ticks = 0;
|
||||||
memset(&serial_buf, 0, sizeof(serial_buf));
|
memset(&serial_buf, 0, sizeof(serial_buf));
|
||||||
|
|
||||||
if (IS_USED(MODULE_PERIPH_TIMER)) {
|
if (IS_USED(MODULE_PERIPH_TIMER)) {
|
||||||
byte_transfer_ticks = 8ULL * TIMER_FREQ_UART_TEST / clk_hz;
|
byte_transfer_ticks = 8ULL * TIMER_FREQ_SPI_TEST / clk_hz;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* D10 is C̅S̅, D7 is connected to C̅S̅ */
|
/* D10 is C̅S̅, D7 is connected to C̅S̅ */
|
||||||
@ -805,6 +807,7 @@ static bool periph_spi_rxtx_test(spi_t bus, spi_mode_t mode, spi_clk_t clk,
|
|||||||
/* C̅S̅ should still be HIGH while no chip is selected */
|
/* C̅S̅ should still be HIGH while no chip is selected */
|
||||||
failed |= TEST(gpio_read(cs_check) != 0);
|
failed |= TEST(gpio_read(cs_check) != 0);
|
||||||
|
|
||||||
|
uint16_t byte_time;
|
||||||
for (uint8_t i = 0; i < UINT8_MAX; i++) {
|
for (uint8_t i = 0; i < UINT8_MAX; i++) {
|
||||||
uint16_t start = 0;
|
uint16_t start = 0;
|
||||||
if (IS_USED(MODULE_PERIPH_TIMER)) {
|
if (IS_USED(MODULE_PERIPH_TIMER)) {
|
||||||
@ -816,15 +819,25 @@ static bool periph_spi_rxtx_test(spi_t bus, spi_mode_t mode, spi_clk_t clk,
|
|||||||
stop = timer_read(TIMER);
|
stop = timer_read(TIMER);
|
||||||
}
|
}
|
||||||
failed |= TEST(received == i);
|
failed |= TEST(received == i);
|
||||||
uint16_t byte_time = (uint16_t)(stop - start);
|
if (IS_USED(MODULE_PERIPH_TIMER)) {
|
||||||
/* We allow the actual SPI clock to be slower than requested, but not
|
byte_time = (uint16_t)(stop - start);
|
||||||
* faster. So the transfer needs to take *at least* the theoretical
|
/* We allow the actual SPI clock to be slower than requested, but
|
||||||
* time. Given the overhead of, this already has some room for error */
|
* not faster. So the transfer needs to take *at least* the
|
||||||
failed |= TEST(byte_time >= byte_transfer_ticks);
|
* theoretical time. Given the overhead of, this already has some
|
||||||
/* C̅S̅ should be still LOW while chip is selected */
|
* room for error */
|
||||||
|
transfer_too_fast |= (byte_time < byte_transfer_ticks);
|
||||||
|
/* C̅S̅ should be still LOW while chip is selected */
|
||||||
|
}
|
||||||
failed |= TEST(gpio_read(cs_check) == 0);
|
failed |= TEST(gpio_read(cs_check) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DETAILED_OUTPUT && transfer_too_fast) {
|
||||||
|
printf("Ticks expected to transfer byte: >= %" PRIu16 ", but got: %"
|
||||||
|
PRIu16 "\n",
|
||||||
|
byte_transfer_ticks, byte_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
failed |= TEST(!transfer_too_fast);
|
||||||
failed |= TEST(spi_transfer_byte(bus, cs, false, UINT8_MAX) == UINT8_MAX);
|
failed |= TEST(spi_transfer_byte(bus, cs, false, UINT8_MAX) == UINT8_MAX);
|
||||||
/* C̅S̅ should be again HIGH while now that no chip is selected */
|
/* C̅S̅ should be again HIGH while now that no chip is selected */
|
||||||
failed |= TEST(gpio_read(cs_check) != 0);
|
failed |= TEST(gpio_read(cs_check) != 0);
|
||||||
@ -868,8 +881,8 @@ static bool periph_spi_test(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
static const spi_clk_t clocks[] = { SPI_CLK_100KHZ, SPI_CLK_1MHZ, SPI_CLK_10MHZ };
|
static const spi_clk_t clocks[] = { SPI_CLK_400KHZ, SPI_CLK_1MHZ, SPI_CLK_10MHZ };
|
||||||
static const uint32_t clk_hzs[] = { KHZ(100), MHZ(1), MHZ(10) };
|
static const uint32_t clk_hzs[] = { KHZ(400), MHZ(1), MHZ(10) };
|
||||||
|
|
||||||
if (IS_USED(MODULE_PCF857X)) {
|
if (IS_USED(MODULE_PCF857X)) {
|
||||||
for (int i = 0; i < (int)ARRAY_SIZE(spi_clk_check_pins); i++) {
|
for (int i = 0; i < (int)ARRAY_SIZE(spi_clk_check_pins); i++) {
|
||||||
@ -885,6 +898,9 @@ static bool periph_spi_test(void)
|
|||||||
for (unsigned j = 0; j < ARRAY_SIZE(clocks); j++) {
|
for (unsigned j = 0; j < ARRAY_SIZE(clocks); j++) {
|
||||||
spi_clk_t clk = clocks[j];
|
spi_clk_t clk = clocks[j];
|
||||||
uint32_t clk_hz = clk_hzs[j];
|
uint32_t clk_hz = clk_hzs[j];
|
||||||
|
if (DETAILED_OUTPUT) {
|
||||||
|
printf("SPI CLK %" PRIu32 " Hz\n", clk_hz);
|
||||||
|
}
|
||||||
failed |= periph_spi_rxtx_test(bus, SPI_MODE_0, clk, clk_hz, clk_check, false, "mode 0");
|
failed |= periph_spi_rxtx_test(bus, SPI_MODE_0, clk, clk_hz, clk_check, false, "mode 0");
|
||||||
failed |= periph_spi_rxtx_test(bus, SPI_MODE_1, clk, clk_hz, clk_check, false, "mode 1");
|
failed |= periph_spi_rxtx_test(bus, SPI_MODE_1, clk, clk_hz, clk_check, false, "mode 1");
|
||||||
failed |= periph_spi_rxtx_test(bus, SPI_MODE_2, clk, clk_hz, clk_check, true, "mode 2");
|
failed |= periph_spi_rxtx_test(bus, SPI_MODE_2, clk, clk_hz, clk_check, true, "mode 2");
|
||||||
|
Loading…
Reference in New Issue
Block a user