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 }