cancel
Showing results for 
Search instead for 
Did you mean: 

SPI CLK sends out 16 cycles when it should send 8 cycles

Hesseltjuuh
Associate III

I've been having this problem where I configure my STM32F303VCT6 to send out 8 bits but the CLK sends out 16 cycles. I already tried casting the data as proposed on other forum posts but it doesn't work for me. Does anyone see the problem?

 - - - Library Code - - -

void LLD_SPI_INIT(SPI spi){
	uint32_t *RCC_APB2ENR = (uint32_t*)0x40021018;		//RCC Register for AHB which holds clock to SPI peripheral

	//Configure SPI pins
	LLD_GPIO_INIT(spi.MISO);
	LLD_GPIO_INIT(spi.MOSI);
	LLD_GPIO_INIT(spi.SCK);
	LLD_GPIO_INIT(spi.CS);

	LLD_GPIO_CONFIG(spi.MISO);
	LLD_GPIO_CONFIG(spi.MOSI);
	LLD_GPIO_CONFIG(spi.SCK);
	LLD_GPIO_CONFIG(spi.CS);

	LLD_GPIO_SET_PIN(spi.CS, 1);

	//Enable clock for SPI pin
	*RCC_APB2ENR |= (1 << 12);
}

void LLD_SPI_CONFIG(){
	uint32_t *SPIx_CR1 = (uint32_t*)0x40013000;		//SPI control register 1
	uint32_t *SPIx_CR2 = (uint32_t*)0x40013004;		//SPI control register 2

	//Disable SPI
	*SPIx_CR1 &= ~(0x01 << 6);		//Clear bits

	//Baud rate
	*SPIx_CR1 &= ~(0x07 << 3);		//Clear bits
	*SPIx_CR1 |= (0x03 << 3);		//Set bits

	//Master configuration
	*SPIx_CR1 |= (0x01 << 2);		//Set bits

	//Set SSI bit
	*SPIx_CR1 |= (0x01 << 8);		//Set bits

	//Set SSM bit
	*SPIx_CR1 |= (0x01 << 9);		//Set bits

	//Clock is usually low
	*SPIx_CR1 &= ~(0x01 << 1);		//Clear bits

	//On upcoming clock flank
	*SPIx_CR1 &= ~(0x01 << 0);		//Clear bits

	//RXNE when FIFO level is greater than 8 bits
	*SPIx_CR2 |= (0x01 << 12);		//Set bits

	//Send 8 bits
	*SPIx_CR2 &= ~(0x0F << 8);		//Clear bits
	*SPIx_CR2 |= (0x07 << 8);		//Set bits

	//Enable SPI
	*SPIx_CR1 |= (0x01 << 6);		//Set bits
}

void LLD_SPI_SEND_8BITS(SPI spi, uint8_t *data, uint32_t size){
	uint32_t *SPIx_DR = (uint32_t*)0x4001300C;		//SPI data register
	uint32_t *SPIx_SR = (uint32_t*)0x40013008;		//SPI status register

	LLD_GPIO_SET_PIN(spi.CS, 0);
	for(int i = 0; i < size; i++){
		//Wait until TXE bit is set
		while(((*SPIx_SR >> 1) & 0x01) == 0);

		//Load data into Data Register
		//*(volatile uint8_t*)&SPIx_DR = data[i];	//SPI doesnt send anything
		*SPIx_DR = data[i];
	}
	LLD_GPIO_SET_PIN(spi.CS, 1);
}

 

 

 

 

- - - Main - - -

 

 

pindef LCD_EN = {GPIOC, 0, Output, PushPull, LowSpeed, NoUpDown, 0};	//Backlight
pindef LCD_RS = {GPIOC, 1, Output, PushPull, LowSpeed, NoUpDown, 0};	//Command/Read		low = command, high = read

LLD_GPIO_INIT(LCD_EN);
LLD_GPIO_CONFIG(LCD_EN);
LLD_GPIO_SET_PIN(LCD_EN, 1);

LLD_GPIO_INIT(LCD_RS);
LLD_GPIO_CONFIG(LCD_RS);
LLD_GPIO_SET_PIN(LCD_RS, 1);

pindef MISO = {GPIOA, 6, Alternate, PushPull, MediumSpeed, NoUpDown, 5};
pindef MOSI = {GPIOA, 7, Alternate, PushPull, MediumSpeed, NoUpDown, 5};
pindef SCK = {GPIOA, 5, Alternate, PushPull, MediumSpeed, NoUpDown, 5};
pindef CS = {GPIOF, 10, Output, PushPull, MediumSpeed, NoUpDown, 0};

SPI SPI1 = {MISO, MOSI, SCK, CS};

LLD_SPI_INIT(SPI1);
LLD_SPI_CONFIG();


/* Loop forever */
while(1){
        delay_us(100000);

	//LCD command
	uint8_t data[] = {0x28};

	LLD_GPIO_SET_PIN(LCD_RS, 0);	//Command
	LLD_SPI_SEND_8BITS(SPI1, data, 1);
	LLD_GPIO_SET_PIN(LCD_RS, 1);	//Read

}

 

 

 

- - - Oscilloscope - - -

Hesseltjuuh_0-1692467262055.jpeg

 

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

Change

uint32_t *SPIx_DR = (uint32_t*)0x4001300C;

to

volatile uint8_t* SPIx_DR = (volatile uint8_t*) 0x4001300C;
If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

3 REPLIES 3

Write DR with byte width not word

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I'm sorry I'm pretty new to programming so I don't understand what you're saying. 

What should I change in my code?

TDK
Guru

Change

uint32_t *SPIx_DR = (uint32_t*)0x4001300C;

to

volatile uint8_t* SPIx_DR = (volatile uint8_t*) 0x4001300C;
If you feel a post has answered your question, please click "Accept as Solution".