test clock frequencies. This measures the actual SPI clock frequencies on all configured SPI buses. Used during board bringup to validate clock configuration */
| 509 | to validate clock configuration |
| 510 | */ |
| 511 | void SPIDevice::test_clock_freq(void) |
| 512 | { |
| 513 | // delay for USB to come up |
| 514 | DEV_PRINTF("Waiting for USB\n"); |
| 515 | for (uint8_t i=0; i<3; i++) { |
| 516 | hal.scheduler->delay(1000); |
| 517 | DEV_PRINTF("Waiting %u\n", (unsigned)AP_HAL::millis()); |
| 518 | } |
| 519 | DEV_PRINTF("CLOCKS=\n"); |
| 520 | for (uint8_t i=0; i<ARRAY_SIZE(bus_clocks); i++) { |
| 521 | DEV_PRINTF("%u:%u ", unsigned(i+1), unsigned(bus_clocks[i])); |
| 522 | } |
| 523 | DEV_PRINTF("\n"); |
| 524 | |
| 525 | // we will send 1024 bytes without any CS asserted and measure the |
| 526 | // time it takes to do the transfer |
| 527 | uint16_t len = 1024; |
| 528 | uint8_t *buf1 = (uint8_t *)hal.util->malloc_type(len, AP_HAL::Util::MEM_DMA_SAFE); |
| 529 | uint8_t *buf2 = (uint8_t *)hal.util->malloc_type(len, AP_HAL::Util::MEM_DMA_SAFE); |
| 530 | for (uint8_t i=0; i<ARRAY_SIZE(spi_devices); i++) { |
| 531 | SPIConfig spicfg {}; |
| 532 | const uint32_t target_freq = 2000000UL; |
| 533 | // use a clock divisor of 256 for maximum resolution |
| 534 | #if defined(STM32H7) |
| 535 | spicfg.cfg1 = derive_freq_flag_bus(spi_devices[i].busid, target_freq); |
| 536 | #else |
| 537 | spicfg.cr1 = derive_freq_flag_bus(spi_devices[i].busid, target_freq); |
| 538 | #endif |
| 539 | spiAcquireBus(spi_devices[i].driver); |
| 540 | spiStart(spi_devices[i].driver, &spicfg); |
| 541 | uint32_t t0 = AP_HAL::micros(); |
| 542 | spiStartExchange(spi_devices[i].driver, len, buf1, buf2); |
| 543 | chSysLock(); |
| 544 | msg_t msg = osalThreadSuspendTimeoutS(&spi_devices[i].driver->thread, chTimeMS2I(100)); |
| 545 | chSysUnlock(); |
| 546 | if (msg == MSG_TIMEOUT) { |
| 547 | spiAbort(spi_devices[i].driver); |
| 548 | DEV_PRINTF("SPI[%u] FAIL %p %p\n", spi_devices[i].busid, buf1, buf2); |
| 549 | spiStop(spi_devices[i].driver); |
| 550 | spiReleaseBus(spi_devices[i].driver); |
| 551 | continue; |
| 552 | } |
| 553 | uint32_t t1 = AP_HAL::micros(); |
| 554 | spiStop(spi_devices[i].driver); |
| 555 | spiReleaseBus(spi_devices[i].driver); |
| 556 | DEV_PRINTF("SPI[%u] clock=%u\n", unsigned(spi_devices[i].busid), unsigned(1000000ULL * len * 8ULL / uint64_t(t1 - t0))); |
| 557 | } |
| 558 | hal.util->free_type(buf1, len, AP_HAL::Util::MEM_DMA_SAFE); |
| 559 | hal.util->free_type(buf2, len, AP_HAL::Util::MEM_DMA_SAFE); |
| 560 | } |
| 561 | #endif // HAL_SPI_CHECK_CLOCK_FREQ |
| 562 | |
| 563 | #endif // HAL_USE_SPI |
nothing calls this directly
no test coverage detected