Estoy tratando de hacer que la operación SPI básica funcione en un chip STM32F107VC usando la placa de desarrollo WaveShare Port107. Estoy tratando de inicializar SPI1 que reside en PA4-PA7.
Estoy intentando una prueba de bucle invertido simple, por lo que MISO está conectado directamente a MOSI. También he adjuntado un osciloscopio a NSS y SCK.
A continuación se muestra 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 loopback, envío un byte, luego leo el byte (lo configuré para usar un 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;
}
Monitoreando CLK y NSS (y MISO/MOSI) con un osciloscopio, cuando NSS pasa a su estado bajo activo, no oscila ninguna línea de reloj. Incluso si hay una transmisión que intenta ocurrir, los bits se establecen en el registro de datos, pero no creo que estén siendo expulsados de DR porque RXNE nunca sube (lo que tiene sentido porque no hay una línea de reloj activa).
¿Alguien podría indicarme por qué la línea clk nunca oscila? ¿Está mal mi configuración?
Saludos
Quite el comentario de 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
Gesto de desaprobación
venny
venny
ospho
ospho