Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork22
Description
After this last batch of Pull Requests, several of my sketches failed to run. They would hang or look like a reboot
when SPI1.tranfer was called. SPI worked but SPI1 did not.
Most of the time I was using a real simple sketch to debug
#define SPIX SPI1#include <SPI.h>#define CS_PIN 10void setup() { Serial.begin(115200); while (!Serial && millis() < 5000) {} pinMode(CS_PIN, OUTPUT); digitalWrite(CS_PIN, HIGH); SPIX.begin(); SPIX.beginTransaction(SPISettings(3000000, MSBFIRST, SPI_MODE0)); pinMode(LED_BUILTIN, OUTPUT);}void loop() { digitalWrite(CS_PIN, LOW); digitalWrite(LED_BUILTIN, HIGH); for (uint8_t i = 'a'; i <= 'f'; i++) SPIX.transfer(i); digitalWrite(LED_BUILTIN, LOW); digitalWrite(CS_PIN, HIGH); delay(50); Serial.println("Paused"); while (Serial.read() == -1) {} while (Serial.read() != -1) {}}
I am not sure if anyone would want to see all of the debug stuff I put into the zephyr spi code:
spi_ll_stm32.zip
But included it just in case.
We found that it hung in the function:
/* Shift a SPI frame as master. */static void spi_stm32_shift_m(const struct spi_stm32_config *cfg, struct spi_stm32_data *data){if (cfg->fifo_enabled) {spi_stm32_shift_fifo(cfg->spi, data);} else {printk("@1");while (!ll_func_tx_is_not_full(cfg->spi)) {/* NOP */}printk("@2%x", LL_SPI_ReadReg(cfg->spi, SR));spi_stm32_send_next_frame(cfg->spi, data);printk("@3");uint8_t loop_count = 0;uint32_t error_count = 0;while (!ll_func_rx_is_not_empty(cfg->spi)) {loop_count++;if ((loop_count == 0) && (error_count < 5)) {printk("\t%x\n",LL_SPI_ReadReg(cfg->spi, SR));error_count++;}/* NOP */}printk("@4");spi_stm32_read_next_frame(cfg->spi, data);printk("@5\n");}}
in the while (!ll_func_rx_is_not_empty(cfg->spi)) ...
A debug output run:
uart:~$ sketchEnter transceive(0x805bb18 0x2400f568 0x2400d350 0x2400d360)spi_stm32_[00:00:12.460,000] <inf> usb_cdc_acm: Device suspendedconfigure(0x805bb18, 0x2400f568) freq: 3000000 clock:120000000 br:6 hardware CS[00:00:12.473,000] <dbg> spi_ll_stm32: spi_stm32_configure: Installed config 0x2400f568: freq 1875000Hz (div = 64), mode 0/0/0, slave 0[00:00:12.485,000] <dbg> spi_ll_stm32: spi_context_buffers_setup: tx_bufs 0x2400d350 - rx_bufs 0x2400d360 - 1[00:00:12.496,000] <dbg> spi_ll_stm32: spi_context_buffers_setup: current_tx 0x2400d348 (1), current_rx 0x2400d358 (1), tx buf/len 0x2400d33f/1, rx buf/len 0x2400d347/1 Call LL_SPI_StartMasterTransfer returned - Wait while ! IsActiveMasterTransfer Call spi_stm32_cs_controlSPI: 0x40015000 00000201 00000000 50070007 20400000 00000000 00001002 00000000 00000000RCC: clks:00000000 RST 1:0 5:0 EN 1:1000 5:100000SPI init called on: 0x40013000 0x40015000 0 0 0 Call ll_func_enable_int_errors Call ll_func_enable_int_tx_emptyI:1002 3e3SPI pins: 5 5 5 : SPI1 2 3 1SF M N@1@21002[00:00:12.548,000] <dbg> spi_ll_stm32: spi_context_update_tx: tx buf/len 0/0@3 1002 1002 1002 1002 1002
I also have had it running with Logic Analyzer hooked up to pins 10-13, and only pin 10 showed anything.
So I wondered about what were the IO pins for SPI1 configured for:
So I added the following to the start of the transfer code... Actually to the start of the ISR...
static void spi_stm32_isr(const struct device *dev){const struct spi_stm32_config *cfg = dev->config;struct spi_stm32_data *data = dev->data;SPI_TypeDef *spi = cfg->spi;int err;printk("I:%x %x\n", LL_SPI_ReadReg(spi, SR), LL_SPI_ReadReg(spi, IER));// PB3 PD7 PG9 : PH6 PJ10 PJ11printk("SPI pins: %x %x %x : SPI1 %x %x %x\n",(GPIOB->AFR[0] >> (3 * 4 )) & 0xf, (GPIOD->AFR[0] >> (7 * 4 )) & 0xf, (GPIOG->AFR[1] >> ((9-8) * 4 )) & 0xf,(GPIOH->AFR[0] >> (6 * 4 )) & 0xf, (GPIOJ->AFR[1] >> ((10-8) * 4 )) & 0xf, ((GPIOJ->AFR[1] >> ((11-8) * 4 )) & 0xf));
I ran the sketch using only SPI1, but the output was shown above, but:SPI pins: 5 5 5 : SPI1 2 3 1
The SPI (spi1) pins make sense as the Alternate functions for those pins are:
The one for SPI1 (spi5) - don't, need to double check pin 13s one but the other two are timers
Then remembered that these pins were added to the PWM list, and I am guessing probably all of the pins from pin2-13
currently have their alternate pin function set to the PWM timer used.
I did a quick and dirty removal of the timer entries for pins 11-13 from the overlay and rebuilt and then SPI1 started working again.
Will probably introduce a PR to do this, at least for now. Hopefully at some point there will be a system in place that allows
the sketch to select what usage that want for each pin. I know that there is a discussion going on with zephyr on this.
The good news is that I am learning a lot more about parts of the system :D The bad news is, it took a lot longer to figure this out
than it should have.