No clock signal on PA5 bit(SPI1-SCK)
Hello,
I'm learning to use the SPI module. I'm using an STM32F446RET development board. I want to configure the SPI1 module and send some message 'out into the world'(this means I only have one master devices which sends some bytes and no slave to recieve them).
I have configured the pins in this fasion:
- PA5: Alternate function(5-SPI1_SCK), push-pull, fast speed, no PUPD
- PA6: Alternate function(5-SPI1_MOSI), same configuration as PA5
- PA7(MISO) and PA4(NSS) I have not configured as I'm not using any slaves
I have written a code that's supposed to send 1's continuously.
main.c(please ignore my comments at the end :D)
#include "init_functions.h"
#include<string.h>
void SPI_SendData(uint8_t *strbuff, uint32_t len)
{
while(len > 0)
{
while( !(SPI1->SR & 2) ); // wait untill tx buffer is not empty
SPI1->DR = *strbuff;
len--;
strbuff++; // point to next byte
}
}
void SPI_SendOnes()
{
while( (SPI1->SR & 2) == 0 ); // wait untill tx buffer is not empty
SPI1->DR = 1;
int a = SPI1->DR;
}
int main()
{
char user_data[] = "Hello world";
init_GPIOS_SPI1();
config_SPI1();
while(1)
{
// send data
SPI_SendOnes();
while( (SPI1->SR & (1 << 7)) ) // wait till SPI is not busy
{
}
// disable spi
//SPI1->CR1 &= ~( 1 << 6 );
}
return 0;
}
//SPI1->SR[bit 7] -> busy flag(0 - not busy; 1 - SPI (or I2S) is busy in communication or Tx buffer is not empty ). set/cleared by hw
//SPI1->SR[bit 1] -> transmit buffer empty(1 - tx buffer empty; 0 not empty)
//SPI1->SR[bit 0] -> recieve buffer...
//SPI1->DR -> data register(data recieved or to be transmitted). A write to the data register will write into the Tx buffer and a read
// from the data register will return the value held in the Rx buffer.int_functions.c
#include "init_functions.h"
void init_GPIOS_SPI1(void)
{
/*
SPI1 - APB2(90Mhz)
Address range SPI_1: 0x4001 3000 - 0x4001 33FF
PA4 - SPI1_NSS
PA5 - SPI1_SCK
PA6 - SPI1_MISO
PA7 - SPI1_MOSI
*/
/* Enable GPIOA bus clock */
RCC->AHB1ENR |= 1;
/* Configure SPI pins */
//SCLK(PA5)
GPIOA->MODER |= ( 1 << 11 ); // af mode
GPIOA->MODER &= ~( 1 << 10 );
GPIOA->OTYPER &= ~( 1 << 5 ); // push-pull
GPIOA->OSPEEDR |= ( 1 << 11 ); // fast speed
GPIOA->OSPEEDR &= ~( 1 << 10 );
GPIOA->PUPDR &= ~( 1 << 10 ); // no pull up/down
GPIOA->PUPDR &= ~( 1 << 11 );
GPIOA->AFR[0] |= ( 1 << 22 ); // AF5(SPI1_SCK)
GPIOA->AFR[0] |= ( 1 << 20 );
//MOSI(PA6)
GPIOA->MODER |= ( 1 << 13 ); // af mode
GPIOA->MODER &= ~( 1 << 12 );
GPIOA->OTYPER &= ~( 1 << 6 ); // push-pull
GPIOA->OSPEEDR |= ( 1 << 13 ); // fast speed
GPIOA->OSPEEDR &= ~( 1 << 12 );
GPIOA->PUPDR &= ~( 1 << 12 ); // no pull up/down
GPIOA->PUPDR &= ~( 1 << 13 );
GPIOA->AFR[0] |= ( 1 << 26 ); // AF5(SPI1_MOSI)
GPIOA->AFR[0] |= ( 1 << 24 );
//MISO(PA7)
//NSS(PA4)
}
void config_SPI1(void)
{
RCC->APB2ENR |= ( 1 << 12 ); //SPI1 clock enable
SPI1->CR1 |= ( 1 << 15 ); // 1 line bidirectional mode selected
SPI1->CR1 |= ( 1 << 14 ); // output enabled: transmit only mode
SPI1->CR1 &= ~( 1 << 11 ); // 8-bit data frame format for transmission/reception
SPI1->CR1 &= ~( 1 << 7 ); // MSB transmitted first
SPI1->CR1 |= ( 1 << 6 ); // SPI1 enabled
SPI1->CR1 |= ( 1 << 2 ); // master configuration
SPI1->CR1 |= ( 1 << 1 ); // CK to 1 when idle
SPI1->CR1 &= ~( 1 << 0 ); // first clock transition is the first data capture edge
}I have checked with an oscilloscope and expected to see a continous clock signal as the application is supposed to continously send 1's to the outside world. I have put the probe on the PA5(CLK) pin but it just stays low.
I then inspected the code and I have discovered that the code halts when it gets to this line the second time:
while( (SPI1->SR & 2) == 0 ); // wait untill tx buffer is not emptyWhich means the data I want to send gets put into the transmit/recieve buffer but then it does not get put into the TX buffer to get transmited through the bus into the 'world'.
I cannot see what I've configured wrong. Please if possible help me correct this. Thanks.