I'm trying to send SPI data to a MAX7219 from an STM32F042 (the protocol is one-way without MISO). I must be missing something very obvious. With the code below, the only visible side effect is the GPIO nCS line wiggling. Neither clock nor MOSI show any activity.
What am I missing?
#include "stm32f0xx.h"
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
// SCK
GPIOB->MODER |= GPIO_MODER_MODER3_1; // alternate function
// GPIOB->OTYPER default push-pull
// GPIOB->AFR[] default AF 0: SPI1_SCK,
// MOSI
GPIOB->MODER |= GPIO_MODER_MODER5_1; // alternate function
// soft nCS
GPIOB->MODER |= GPIO_MODER_MODER4_0; // GPO
GPIOB->ODR = GPIO_ODR_4; // deselect
// SPI configuration
SPI1->CR1 |= SPI_CR1_MSTR; // master mode
SPI1->CR1 |= SPI_CR1_BR_1; // spi_sck = SystemCoreClock / 8 = 6 MHz
SPI1->CR1 |= SPI_CR1_SSI; // software CS
SPI1->CR2 |= SPI_CR2_DS_3 | SPI_CR2_DS_2 |
SPI_CR2_DS_1 | SPI_CR2_DS_0; // 16 bit format
SPI1->CR1 |= SPI_CR1_SPE; // SPI Enable
// transmit test packet
while(!(SPI1->SR & SPI_SR_TXE)); // make sure TX buffer is empty
while(SPI1->SR & SPI_SR_BSY); // make sure SPI isn't busy
GPIOB->ODR &= ~GPIO_ODR_4; // chip select
uint16_t data = 0xAAAA; // test packet
SPI1->DR = data;
while(!(SPI1->SR & SPI_SR_TXE)); // make sure TX buffer is empty
while(SPI1->SR & SPI_SR_BSY); // make sure SPI isn't busy
GPIOB->ODR |= GPIO_ODR_4; // deselect
while(1);
}
Best Answer
Enable SPI_CR1_SSM.
The output now remains high-z since chip select is low.
Aside from clock setup and gpio, this is minimal init for SPI: