We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I'm using the STM32F030K6T6 M0 processor and C++ in STM32CubeIDE and no matter what I try I'm outputting 16 bits instead of 8.
I created 2 projects; One HAL and the one shown partially below. I run them in debug and the GPIOA and SPI setting are the same. The HAL output is 8 bit format as it should be b ut the other outputs 16 bits per transaction as shown in the logic image below.
CSpi::CSpi() { // Enable PA clock RCC->AHBENR |= (1 << 17); // Set PA5, PA6 and PA7 to Alt. Func. GPIOA->MODER &= ~(0x3F << 10); GPIOA->MODER |= (0x2A << 10); GPIOA->AFR[0] &= ~(0xFFF << 20); } void CSpi::SpiInit() { RCC->APB2ENR |= (1 << 12); // enable SPI1 clock SPI1->CR1 = 0x31C; // Master, clk/16, SSM/SSI SPI1->CR2 = 0x01708; // 8 bit SPI1->CR1 |= (1 << 6); // enable SPI1 module } bool CSpi::ConfigureChannel(uint8_t chan, GPIO_TypeDef* port, uint16_t pin) { if (chan > MAX_CHANNELS) return false; _chanInfo[chan].port = port; _chanInfo[chan].pin = pin; // TODO Figure pin and do shift // Set PA4 as output for CS port->MODER &= ~(0x03 << (pin << 1)); port->MODER |= (1 << (pin << 1)); return true; } void CSpi::SetState(uint8_t chan, BSTATE state) { if (chan > MAX_CHANNELS) return; if (state) _chanInfo[chan].port->BSRR = (1 << _chanInfo[chan].pin); else _chanInfo[chan].port->BSRR = (1 << (_chanInfo[chan].pin + 16)); } void CSpi::Write(uint8_t chr) { while (!((SPI1->SR)&(1<<1))) {}; // wait for TXE bit to set -> This will indicate that the buffer is empty SPI1->DR = chr; // load the data into the Data Registe while (!((SPI1->SR)&(1<<1))); // wait for TXE bit to set -> This will indicate that the buffer is empty while (((SPI1->SR)&(1<<7))); // wait for BSY bit to Reset -> This will indicate that SPI is not busy in communication }
and in my main routine I have;
spi.SpiInit(); spi.ConfigureChannel(0, GPIOA, 4); while(1) { spi.SetState(0, LOW); spi.Write(0x31); spi.SetState(0, HIGH); delay(5); }
Not sure what I'm doing wrong.
Any help appreciated.
I found the answer to the problem after 2 days of hair pulling.
uint8_t CSpi::Write(uint8_t chr) { while ((SPI1->SR & SPI_SR_TXE) == 0); // wait for TXE bit to set -> This will indicate that the buffer is empty // Have to force it to output 8 bits, even though configured for 8. *(volatile uint8_t *)&SPI1->DR = (uint8_t)chr; while ((SPI1->SR & SPI_SR_RXNE) == 0); while ((SPI1->SR & SPI_SR_BSY) != 0); // wait for BSY bit to Reset }