2
\$\begingroup\$

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

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Your configurations are very difficult to read. Why don't you use the Standard Peripherals Library? There should be some good descriptions in the source files on how to set things up. \$\endgroup\$
    – Tut
    Aug 26, 2014 at 12:49
  • 1
    \$\begingroup\$ Your configurations are easy to read because they do not obscure things like the library functions do. But using aliases for bit numbers would improve readability and portability. \$\endgroup\$
    – venny
    Aug 26, 2014 at 12:53
  • \$\begingroup\$ Why is NSS configured as input? \$\endgroup\$
    – venny
    Aug 26, 2014 at 12:54
  • \$\begingroup\$ @venny I configured NSS as both input and also AF push-pull output, both configurations did not work. \$\endgroup\$
    – Ospho
    Aug 26, 2014 at 13:05
  • \$\begingroup\$ I will also use aliasing for pin numbers, thanks for the tip \$\endgroup\$
    – Ospho
    Aug 26, 2014 at 13:07

1 Answer 1

1
\$\begingroup\$

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

SPI1->CR1 |= SPI_CR1_SSM; //disable automatic SS
\$\endgroup\$
2
  • \$\begingroup\$ If I don't write anything to the buffer and I hold NSS low, will the CLK oscillate? \$\endgroup\$
    – Ospho
    Aug 27, 2014 at 9:31
  • \$\begingroup\$ No, when not using automatic mode, NSS is completely independent and is useful only for the receiving slave. The CLK will oscilate only to shift out predefined number of bits after a value is written to the transmit data register. \$\endgroup\$
    – venny
    Aug 27, 2014 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.