Electronic – STM32F10x SPI – No Clock

armcortex-m3serialspistm32

I'm trying to get basic SPI operation working on an STM32F107VC chip using the WaveShare Port107 development board. I'm trying to initialise SPI1 which resides on PA4-PA7.
I'm attempting a simple loopback test, so MISO is directly connected to MOSI.
I have also attached an oscilloscope to NSS and SCK.

Below is my code:

// Clock configuration
RCC->APB2ENR |= 1;              // Alternate Function Clock Enable
RCC->APB2ENR |= 1<<2;           // Enable clock to Port A.
RCC->APB2ENR |= 1<<12;          // Enable clock for SPI1.

// Pin configuration (no remapping)
// Output = AF PushPull 50MHz. 
// Input = Active Pullup/Pulldown
// I have tried NSS as AFPuP, Active Pullup/Pulldown, GPIO output etc...
// NSS (PA4) = input, CLK (PA5) = output, MISO (PA6) = input, MOSI (PA7) = output
GPIOA->CRL = 0xB8B80000;

// General SPI configuration
SPI1->CR1 = 0;
SPI1->CR1 |= 7<<3;                  // Lowest frequency.    
SPI1->CR1 &= ~(1<<0);               // Clock phase. 1st clock transition starts data capture
SPI1->CR1 |= 1<<1;                  // Clock polarity. High when idle.
SPI1->CR1 &= ~(1<<11);              // Use 8 bit data
SPI1->CR1 |= 1<<7;                  // LSB transmitted first.
//SPI1->CR1 |= 1<<9;                // Software slave management
//SPI1->CR1 |= 1<<8                 // Software NSS bit high
SPI1->CR1 |= 1<<2;                  // Master device.
SPI1->CR1 &= ~(1<<10);              // Use both RX and TX
SPI1->CR1 &= ~(3<<12);              // No CRC
SPI1->CR1 &= ~(1<<15);              // 2-line unidirectional mode
SPI1->CR2 = 0;                      // Polling mode (no interrupts)
SPI1->CR1 |= 1<<6;                  // Enable SPI1.

Now, to perform the loopback test, I send a byte, then read back the byte (I have configured to use 8-bit shift register).

void loopback(unsigned char byte)
{
    GPIOA->BSRR &= ~(1<<4); // !NSS line set to low (active) state. I have
                            // also attempted to use GPIOA->ODR and
                            // also attempted software NSS mode.
    //  while ((SPI1->SR & (1 << 7)) != 0 );    // Wait for BUSY to clear. not using.
    while (!(SPI1->SR & (1 << 1))); // Wait TXE (Transmit buffer empty)
    SPI1->DR = byte;

    // read it back
    unsigned char readByte = ReadByte();

    if (byte == readByte)
    {
         // ... Test passed!
    }
    GPIOA->BSRR |= 1<<4;     //!NSS set high. (unactive state).
}

unsigned char ReadByte(void)
{
    while (!(SPI1->SR & (1 << 0))); // Wait RXNE (Receive not empty (we have data))
    unsigned char readByte = SPI1->DR;
    return readByte;
}

Monitoring the CLK and NSS (and MISO/MOSI) with an oscilloscope, when NSS goes to its active low state, no clock line oscillates. Even if there is transmission attempting to occur the bits are set on the data register but I dont think they are being pushed out of DR because RXNE never goes high (which makes sense because no clock line is active).

Could anyone direct me to why the clk line is never oscillating? Is my config wrong?

Regards

Best Answer

Uncomment lines that enable SSM (CR1 bit 9) to use manual slave selection.

SPI1->CR1 |= SPI_CR1_SSM; //disable automatic SS