STM32F10x SPI - Sin reloj

2

Estoy intentando que la operación SPI básica funcione en un chip STM32F107VC utilizando la placa de desarrollo WaveShare Port107. Estoy intentando inicializar SPI1 que reside en PA4-PA7.
Estoy intentando realizar una prueba de bucle invertido simple, por lo que MISO está directamente conectado a MOSI. También he conectado un osciloscopio a NSS y SCK.

Debajo está mi código:

// 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.

Ahora, para realizar la prueba de bucle invertido, envío un byte y luego leo el byte (lo he configurado para usar el registro de desplazamiento de 8 bits).

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;
}

La supervisión de CLK y NSS (y MISO / MOSI) con un osciloscopio, cuando NSS pasa a su estado bajo activo, no oscila la línea del reloj. Incluso si hay una transmisión que intenta ocurrir, los bits se configuran en el registro de datos pero no creo que se estén eliminando de DR porque RXNE nunca pasa a nivel alto (lo que tiene sentido porque no hay una línea de reloj activa).

¿Podría alguien dirigirme a por qué la línea clk nunca está oscilando? ¿Mi configuración es incorrecta?

Saludos

    
pregunta Ospho

1 respuesta

1

Descomente las líneas que permiten que SSM (CR1 bit 9) use la selección manual de esclavos.

SPI1->CR1 |= SPI_CR1_SSM; //disable automatic SS
    
respondido por el venny

Lea otras preguntas en las etiquetas