Skip to main content
DVovk.1
Associate
May 20, 2021
Question

Wrong data through SPI on STM32F7

Hello dear community. I'd tried so long so i decided to ask for you.

I need to send some data pack from STM32F7(master) to STM32F1.

I use STM32CubeIDE platform. My code is below.

Problem is that in receiving back data by master. First byte has always corrupts.

Lower SPI speed does not solve the problem.

Second question is about MSIZE bit. Why it is set to "0x1" against my code?

Master:

#define SPI_DATLEN_BYTE 26
uint8_t bufRX[26];
uint8_t bufTX[26];

void SPIInit(void)
{
GPIO_InitTypeDef Init;
 
 RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // SPI1
 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // GPIOA
 RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; // DMA2
 
 /*Configure GPIO pin : PA5,PA6,PA7 */
	Init.Pin = SPI1_MASTER_MOSI|SPI1_MASTER_MISO|SPI1_MASTER_CLK;
	Init.Mode = GPIO_MODE_AF_PP;
	Init.Pull = GPIO_NOPULL;
	Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SPI1_PORT, &Init);
 
	/*Configure GPIO pin : PA3,PA4 */
	Init.Pin = SPI1_MASTER_NSS1|SPI1_MASTER_NSS2;
	Init.Mode = GPIO_MODE_OUTPUT_PP;
	Init.Pull = GPIO_NOPULL;
	Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SPI1_PORT, &Init);
 
 // SPI settings
 SPI1->CR2 = 0x7 << SPI_CR2_DS_Pos ; //frame size 8 bit
 SPI1->CR2 |= 1<<SPI_CR2_TXDMAEN_Pos; //Enable DMA requests
 SPI1->CR2 |= 1<<SPI_CR2_RXDMAEN_Pos;
 
 SPI1->CR1 = 0<<SPI_CR1_LSBFIRST_Pos //MSB first
		 	 | 1<<SPI_CR1_SSM_Pos //soft SS enable
				| 1<<SPI_CR1_SSI_Pos //SS pin high
				| 0x02<<SPI_CR1_BR_Pos //speed: F_PCLK/8 (000: fPCLK/2 001: fPCLK/4 010: fPCLK/8 011: fPCLK/16 100: fPCLK/32 101: fPCLK/64 110: fPCLK/128)
				| 1<<SPI_CR1_MSTR_Pos //master
				| 0<<SPI_CR1_CPOL_Pos | 0<<SPI_CR1_CPHA_Pos; //SPI mode: 0
 
 SPI1->CR1 |= 1<<SPI_CR1_SPE_Pos; //SPI1 enable
}
void SPI_Send(void)
{
	 //disable stream0
	 DMA2_Stream0->CR &= ~(DMA_SxCR_EN);
	 while (DMA2_Stream0->CR & DMA_SxCR_EN) { }
 
	 //DMA settings
	 DMA2_Stream0->PAR = (uint32_t)(&SPI1->DR); //Peripheral address of SPI1->DR
	 DMA2_Stream0->M0AR = (uint32_t)(&bufRX[0]); //Memory address is variable
	 DMA2_Stream0->NDTR = SPI_DATLEN_BYTE; //DATA LENTH = 26 bytes
 
	 DMA2_Stream0->CR =
	 0x00 << DMA_SxCR_PL_Pos 	 //priority low
	 | 0x00 << DMA_SxCR_MSIZE_Pos //memory 8bit
	 | 0x01 << DMA_SxCR_PSIZE_Pos //peripheral register is 16bit
	 | 1 << DMA_SxCR_MINC_Pos 	 //increase the memory
	 | 0 << DMA_SxCR_PINC_Pos //do not increase periph
	 | 0 << DMA_SxCR_CIRC_Pos 	 //circular off
	 | 0 << DMA_SxCR_DIR_Pos 	 //'0' from peripheral to memory
		| (DMA_SxCR_CHSEL_0|DMA_SxCR_CHSEL_1); //channel 3 connect
 
	 //disable stream3
	 DMA2_Stream3->CR &= ~(DMA_SxCR_EN);
	 while (DMA2_Stream3->CR & DMA_SxCR_EN) {}
	 DMA2->LIFCR = 0xFFFFFFFF;
 
	 //DMA settings
	 DMA2_Stream3->PAR = (uint32_t)(&SPI1->DR); //Peripheral address of SPI1->DR
	 DMA2_Stream3->M0AR = (uint32_t)(&bufTX[0]); //Memory address is variable
	 DMA2_Stream3->NDTR = SPI_DATLEN_BYTE; //DATA LENTH = 26 bytes
 
	 DMA2_Stream3->CR =
	 0x00 << DMA_SxCR_PL_Pos //priority low
	 | 0x00 << DMA_SxCR_MSIZE_Pos //memory 8bit
	 | 0x01 << DMA_SxCR_PSIZE_Pos //peripheral register is 16bit
	 | 1 << DMA_SxCR_MINC_Pos //increase the memory
	 | 0 << DMA_SxCR_PINC_Pos //do not increase periph
	 | 0 << DMA_SxCR_CIRC_Pos //circular off
	 | 1 << DMA_SxCR_DIR_Pos //'1' from memory to peripheral
	 | (DMA_SxCR_CHSEL_0|DMA_SxCR_CHSEL_1); //channel 3 connect
 
		DMA2_Stream0->CR |= (1 << DMA_SxCR_EN_Pos); //enable receive
		DMA2_Stream3->CR |= 1 << DMA_SxCR_EN_Pos; //enable transmit
}
void initial(void) {
	GPIO_InitTypeDef Init;
	uint32_t i;
	uint32_t random_num;
 
	/*Configure GPIO pin : PA3,PA4 */
	__HAL_RCC_GPIOA_CLK_ENABLE();
 
	/*Configure GPIO pin : PA3,PA4 */
	Init.Pin = SPI1_MASTER_NSS1 | SPI1_MASTER_NSS2;
	Init.Mode = GPIO_MODE_OUTPUT_PP;
	Init.Pull = GPIO_NOPULL;
	Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SPI1_PORT, &Init);
 
	HAL_GPIO_WritePin(SPI1_PORT, SPI1_MASTER_NSS1, GPIO_PIN_RESET);
	HAL_Delay(50);
 
	/*----Count rows-----*/
	//fill the bufTX
	for (i = 0; i < 26; i++) {
		bufTX[i] = i;
	}
 
	//clear the bufRX
	for (i = 0; i < 26; i++) {
		bufRX[i] = 0;
	}
 
	while (1) {
 
		//clear the bufRX
		for (i = 0; i < 26; i++) {
			bufRX[i] = 0;
		}
 
//		random_num = rnd_between(1, 3);
//		printf("RND:%d\n", random_num);
//
//		switch (random_num) {
//		case 1:
//			bufTX[0] = NOTHING;
//			break;
//		case 2:
//			bufTX[0] = SEND_ROWS;
//			break;
//		case 3:
//			bufTX[0] = SHUT_DOWN_LEADS;
//			break;
//		default:
//			break;
//		}
 
		if (SPI_CHECK_FLAG(SPI1->SR, SPI_FLAG_OVR) == SET) {
			printf("OVER\n");
		}
 
		if (DMA2->LISR & DMA_LISR_TCIF3) {
			printf("CH3:TRANS COMP\n");
		}
		if (DMA2->LISR & DMA_LISR_HTIF3) {
			printf("CH3:HALF TRANS\n");
		}
		if (DMA2->LISR & DMA_LISR_DMEIF3) {
			printf("CH3:DIRMOD ERR\n");
		}
		if (DMA2->LISR & DMA_LISR_TEIF3) {
			printf("CH3:TRANS ERR\n");
		}
		if (DMA2->LISR & DMA_LISR_FEIF3) {
			printf("CH3:FIFO ERR\n");
		}
 
		if (DMA2->LISR & DMA_LISR_TCIF0) {
			printf("CH0:TRANS COMP\n");
		}
		if (DMA2->LISR & DMA_LISR_HTIF0) {
			printf("CH0:HALF TRANS\n");
		}
		if (DMA2->LISR & DMA_LISR_DMEIF0) {
			printf("CH0:DIRMOD ERR\n");
		}
		if (DMA2->LISR & DMA_LISR_TEIF0) {
			printf("CH0:TRANS ERR\n");
		}
		if (DMA2->LISR & DMA_LISR_FEIF0) {
			printf("CH0:FIFO ERR\n");
		}
 
		//Impulse to slave
		HAL_GPIO_WritePin(SPI1_PORT, SPI1_MASTER_NSS1, GPIO_PIN_SET);
		__asm("NOP");
		HAL_GPIO_WritePin(SPI1_PORT, SPI1_MASTER_NSS1, GPIO_PIN_RESET);
 
		SPI_Send();
 
		for (i = 0; i < 26; i++) {
			printf("T[%X]R[%X]\n", bufTX[i], bufRX[i]);
		}
		printf("-------------------------------------------------\n");
		HAL_Delay(1000);
	}
}

This topic has been closed for replies.

14 replies

DVovk.1
DVovk.1Author
Associate
May 20, 2021

Slave STM32F103RCT6:

#define SPI_DATLEN_BYTE 26
extern uint8_t bufRX[26];
extern uint8_t bufTX[26];
void SPIInit(void) {
	GPIO_InitTypeDef Init;
 
	RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // SPI1
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // GPIOA
	RCC->AHBENR |= RCC_AHBENR_DMA1EN; // DMA2
 
	/*Configure GPIO pin : PA5,PA6,PA4 */
	Init.Pin = SPI1_SLAVE_MOSI | SPI1_SLAVE_CLK | SPI1_SLAVE_NSS;
	Init.Mode = GPIO_MODE_INPUT;
	Init.Pull = GPIO_NOPULL;
	Init.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(SPI1_PORT, &Init);
 
	Init.Pin = SPI1_SLAVE_MISO;
	Init.Mode = GPIO_MODE_AF_PP;
	Init.Pull = GPIO_NOPULL;
	Init.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(SPI1_PORT, &Init);
 
	//SPI settings
	SPI1->CR1 = 0 << SPI_CR1_DFF_Pos //frame size 8
	| 0 << SPI_CR1_LSBFIRST_Pos //MSB first
	| 1 << SPI_CR1_SSM_Pos //sofr SS
	| 0 << SPI_CR1_SSI_Pos //SS low state
	| 0x06 << SPI_CR1_BR_Pos //speed F_PCLK/128
	| 0 << SPI_CR1_MSTR_Pos //mode slave
	| 0 << SPI_CR1_CPOL_Pos | 0 << SPI_CR1_CPHA_Pos; //SPI mode: 0
 
	SPI1->CR2 |= 1 << SPI_CR2_TXDMAEN_Pos;
	SPI1->CR2 |= 1 << SPI_CR2_RXDMAEN_Pos;
	SPI1->CR1 |= 1 << SPI_CR1_SPE_Pos; //enable SPI
 
	//disable Channel2
	DMA1_Channel2->CCR &= ~(1 << DMA_CCR_EN_Pos);
 
	DMA1_Channel2->CPAR = (uint32_t) (&SPI1->DR); //perih address
	DMA1_Channel2->CMAR = (uint32_t) &bufRX[0]; //memory address
	DMA1_Channel2->CNDTR = SPI_DATLEN_BYTE; //byte count
 
	//DMA settings
	DMA1_Channel2->CCR = 0 << DMA_CCR_MEM2MEM_Pos //MEM2MEM disabled
	| 0x00 << DMA_CCR_PL_Pos //low priority
	| 0x00 << DMA_CCR_MSIZE_Pos //memory size 8 bit
	| 0x01 << DMA_CCR_PSIZE_Pos //periph size 16 bit
	| 1 << DMA_CCR_MINC_Pos 	//memory inc on
	| 0 << DMA_CCR_PINC_Pos 	//periph inc off
	| 0 << DMA_CCR_CIRC_Pos //circular off
	| 0 << DMA_CCR_DIR_Pos; //'0' from periph to memory
 
	//disable Channel3
	DMA1_Channel3->CCR &= ~(1 << DMA_CCR_EN_Pos);
 
	DMA1_Channel3->CPAR = (uint32_t) (&SPI1->DR); //perih address
	DMA1_Channel3->CMAR = (uint32_t) &bufTX[0]; //memory address
	DMA1_Channel3->CNDTR = SPI_DATLEN_BYTE; //byte count
 
	//DMA settings
	DMA1_Channel3->CCR = 0 << DMA_CCR_MEM2MEM_Pos //MEM2MEM disabled
	| 0x00 << DMA_CCR_PL_Pos //low priority
	| 0x00 << DMA_CCR_MSIZE_Pos //memory size 8 bit
	| 0x01 << DMA_CCR_PSIZE_Pos //periph size 16 bit
	| 1 << DMA_CCR_MINC_Pos //memory inc on
	| 0 << DMA_CCR_PINC_Pos //periph inc off
	| 0 << DMA_CCR_CIRC_Pos //circular off
	| 1 << DMA_CCR_DIR_Pos; //'0' from memory to peripheral
//	DMA1_Channel2->CCR |= 1 << DMA_CCR_EN_Pos; //start receive
//	DMA1_Channel3->CCR |= 1 << DMA_CCR_EN_Pos; //start transmit
}
	while (1) {
/* USER CODE END WHILE */
 
/* USER CODE BEGIN 3 */
 
		//clear bufRX
		for (i = 0; i < 26; i++) {
			bufRX[i]=0;
		}
 
		bufTX[0]=5;
		
		DMA1_Channel2->CCR &= ~(1 << DMA_CCR_EN_Pos);//disable DMA channel		
		DMA1_Channel3->CCR &= ~(1 << DMA_CCR_EN_Pos);
		
		while(DMA1_Channel2->CCR & DMA_CCR_EN){}
		while(DMA1_Channel3->CCR & DMA_CCR_EN){}
		
		DMA1->IFCR = 0xFFFFFFFF;//Clear flags
 
		DMA1_Channel2->CNDTR = SPI_DATLEN_BYTE;
		DMA1_Channel3->CNDTR = SPI_DATLEN_BYTE;
		DMA1_Channel2->CCR |= 1 << DMA_CCR_EN_Pos; //enable DMA channel
		DMA1_Channel3->CCR |= 1 << DMA_CCR_EN_Pos; //enable DMA channel
 
 
		while(exti4_event==0) {}
			while( !(DMA1->ISR & (DMA_ISR_HTIF2|DMA_ISR_TEIF2) ) );
			exti4_event = 0;
			command = bufRX[0];
 
			switch (command) {
			case NOTHING:
				printf("Nothing received.\n");
				break;
			case SPI_ERROR:
				printf("SPI_ERROR error!\n");
				break;
			case SPI_BUSY:
				printf("SPI_BUSY error!\n");
				break;
			case SPI_TIMEOUT:
				printf("SPI_TIMEOUT error!\n");
				break;
 
			case SEND_ROWS: //send rows_count
				bufTX[1] = rows_count;
				bufTX[0] = ROWS_SENT; //rows_counted
				break;
			case SHUT_DOWN_LEADS: //shut down leads
				res = ShutDownLeads();
				if (res == 0) {
					bufTX[0] = LEADS_OFF;
					printf("'ShutDownLeads' result: %u\n", (unsigned int) res);
				}
				break;
			default:
				printf("'command' unknown!\n");
				break;
			}
			asm("nop");
 
			for (i = 0; i < 26; i++) {
				printf("T[%X]R[%X]\n", bufTX[i], bufRX[i]);
			}
 
			printf("-------------------------------------------------\n");
 
 
	} //while(1)

TDK
May 20, 2021

> Second question is about MSIZE bit. Why it is set to "0x1" against my code?

From the reference manual:

In direct mode, MSIZE is forced by hardware to the same value as PSIZE as soon as bit EN = '1'.

"If you feel a post has answered your question, please click ""Accept as Solution""."
waclawek.jan
Super User
May 20, 2021

Observe the SPI lines using logic analyzer/oscilloscope.

JW

DVovk.1
DVovk.1Author
Associate
May 24, 2021

Ok so i have inspected with oscilloscope. First thing is that no incorrect byte is received (just wrong 'printf' timing).

But new problem appeared. The data shifts on one byte: in case of SPI clock is about F_PCLK/4 - on the slave side. If SPI clock is F_PCLK/128 - on the Master side.

See screeshots.

By the way i have noticed that the master(F7) sends 26 bytes twice. I reduced 'SPI_DATLEN_BYTES' to 26/2. Ok, this settings is not a byte count, rather it is "item count".

But why on the slave(f103) side i leave this option as 26? SPI has the same DR 16 bit long!!? how it works.

DVovk.1
DVovk.1Author
Associate
May 24, 2021

Green - MISO

Yell - MOSI

SPI speed is about PLCK/128

DVovk.1
DVovk.1Author
Associate
May 24, 2021

..

TDK
May 24, 2021
Set PSIZE to the size you want to send, in this case 1 byte.
"If you feel a post has answered your question, please click ""Accept as Solution""."
DVovk.1
DVovk.1Author
Associate
May 24, 2021

PSIZE 0x0 8bit

MSIZE 0x0 8bit

SPI speed max: 72MHz/4

TDK
May 24, 2021

You're not waiting for the transaction to complete. You're starting the transfer and then immediately calling printf on the RX buffer (which doesn't have new data yet), so you're getting the value from the previous transaction.

"If you feel a post has answered your question, please click ""Accept as Solution""."
DVovk.1
DVovk.1Author
Associate
May 24, 2021

Yes, i have updated the code. Now it prints right. Please see oscilloscope shot, there are wrong impulses at the begin.

TDK
May 24, 2021

I don't see an oscilloscope plot.

Keep in mind pins can toggle during initialization. Typically this is solved by keeping the CS line high.

I would suggest having a closer eye on the Reference Manual if you're going to use register access for everything.

"If you feel a post has answered your question, please click ""Accept as Solution""."
DVovk.1
DVovk.1Author
Associate
May 26, 2021

Finely problem was that FRXTH was '0'.

0: RXNE event is generated if the FIFO level is greater than or equal to 1/2 (16-bit)

1: RXNE event is generated if the FIFO level is greater than or equal to 1/4 (8-bit)

Now it works fine at maximum speed 72/4 MHz.

Thanks for answers!

DVovk.1
DVovk.1Author
Associate
May 27, 2021

New problem please help.

After i polished SPI function everything works fine.

But now i put it into FreeRTOS and no action is detected on MOSI and consequently on MISO pins. Just low level on its.

New code below:

void SPIInit(void) {
	GPIO_InitTypeDef Init;
 
	RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // SPI1
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // GPIOA
	RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; // DMA2
 
	/*Configure GPIO pin : PA5,PA6,PA7 */
	Init.Pin = SPI1_MASTER_MOSI | SPI1_MASTER_MISO | SPI1_MASTER_CLK;
	Init.Mode = GPIO_MODE_AF_PP;
	Init.Pull = GPIO_NOPULL;
	Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SPI1_PORT, &Init);
 
	/*Configure GPIO pin : PA3,PA4 */
	Init.Pin = SPI1_MASTER_NSS1 | SPI1_MASTER_NSS2;
	Init.Mode = GPIO_MODE_OUTPUT_PP;
	Init.Pull = GPIO_NOPULL;
	Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(SPI1_PORT, &Init);
 
/*-----------------------------------DMA--------------------------------------------*/
	//disable stream0 && stream3
	do {
	 DMA2_Stream0->CR &= ~(DMA_SxCR_EN);
	 DMA2_Stream3->CR &= ~(DMA_SxCR_EN);
	} while( (DMA2_Stream0->CR & DMA_SxCR_EN) && (DMA2_Stream3->CR & DMA_SxCR_EN) );
 
	DMA2->LIFCR = 0xFFFFFFFF; //Clear flags
 
	//DMA receive settings
	DMA2_Stream0->PAR = (uint32_t) (&SPI1->DR); //Peripheral address of SPI1->DR
	DMA2_Stream0->M0AR = (uint32_t) (&bufRX[0]); //Memory address is variable
	DMA2_Stream0->NDTR = SPI_DATLEN_BYTE; //DATA LENTH = 26 bytes
 
	DMA2_Stream0->CR = 0x00 << DMA_SxCR_PL_Pos 	 //priority low
	| 0x00 << DMA_SxCR_MSIZE_Pos //memory 8bit
	| 0x00 << DMA_SxCR_PSIZE_Pos //peripheral register is 16bit
	| 1 << DMA_SxCR_MINC_Pos 	 //increase the memory
	| 0 << DMA_SxCR_PINC_Pos //do not increase periph
	| 0 << DMA_SxCR_CIRC_Pos 	 //circular off
	| 0 << DMA_SxCR_DIR_Pos 	 //'0' from peripheral to memory
	| (DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1); //channel 3 connect
 
	//DMA transmit settings
	DMA2_Stream3->PAR = (uint32_t) (&SPI1->DR); //Peripheral address of SPI1->DR
	DMA2_Stream3->M0AR = (uint32_t) (&bufTX[0]); //Memory address is variable
	DMA2_Stream3->NDTR = SPI_DATLEN_BYTE; //DATA LENTH = 26 bytes
 
	DMA2_Stream3->CR
	= 0x00 << DMA_SxCR_PL_Pos //priority low
	| 0x00 << DMA_SxCR_MSIZE_Pos //memory 8bit
	| 0x00 << DMA_SxCR_PSIZE_Pos //peripheral register is 16bit
	| 1 << DMA_SxCR_MINC_Pos //increase the memory
	| 0 << DMA_SxCR_PINC_Pos //do not increase periph
	| 0 << DMA_SxCR_CIRC_Pos //circular off
	| 1 << DMA_SxCR_DIR_Pos //'1' from memory to peripheral
	| (DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1); //channel 3 connect
/*----------------------------------------------------------------------------------*/
 
/*-----------------------------------SPI--------------------------------------------*/
	// SPI settings
	SPI1->CR2 = 0x7 << SPI_CR2_DS_Pos; //frame size 8 bit
	SPI1->CR2 |= 1 << SPI_CR2_TXDMAEN_Pos; //Enable DMA requests
	SPI1->CR2 |= 1 << SPI_CR2_RXDMAEN_Pos;
	SPI1->CR2 |= 0x1 << SPI_CR2_FRXTH_Pos; //1: RXNE event is generated if the FIFO level is greater than or equal to 1/4 (8-bit)
 
	SPI1->CR1
	= 0 << SPI_CR1_LSBFIRST_Pos //MSB first
	| 1 << SPI_CR1_SSM_Pos //soft SS enable
	| 1 << SPI_CR1_SSI_Pos //SS pin high
	| 0x01 << SPI_CR1_BR_Pos //speed: F_PCLK/8 (000: fPCLK/2 001: fPCLK/4 010: fPCLK/8 011: fPCLK/16 100: fPCLK/32 101: fPCLK/64 110: fPCLK/128)
	| 1 << SPI_CR1_MSTR_Pos //master
	| 0 << SPI_CR1_CPOL_Pos | 0 << SPI_CR1_CPHA_Pos; //SPI mode: 0
 
	SPI1->CR1 |= 1 << SPI_CR1_SPE_Pos; //SPI1 enable
/*----------------------------------------------------------------------------------*/
}
void SPI_Send(void)
{
	 //disable stream0 && stream3
	 do {
		 DMA2_Stream0->CR &= ~(DMA_SxCR_EN);
		 DMA2_Stream3->CR &= ~(DMA_SxCR_EN);
	 } while( (DMA2_Stream0->CR & DMA_SxCR_EN) && (DMA2_Stream3->CR & DMA_SxCR_EN) );
 
	 DMA2->LIFCR = 0xFFFFFFFF;//Clear flags
	 DMA2_Stream3->NDTR = SPI_DATLEN_BYTE;//DATA LENTH = 26 bytes
	 DMA2_Stream0->NDTR = SPI_DATLEN_BYTE;//DATA LENTH = 26 bytes
 
	 DMA2_Stream0->CR |= 1 << DMA_SxCR_EN_Pos; //enable receive
	 DMA2_Stream3->CR |= 1 << DMA_SxCR_EN_Pos; //enable transmit
}
void initial(void) {
	GPIO_InitTypeDef Init;
	uint32_t i;
	uint32_t random_num;
 
	HAL_Delay(500);//Wait untill the slave
 
	/*----Count rows-----*/
	//fill the bufTX
	for (i = 0; i < 26; i++) {
		bufTX[i] = i;
	}
 
	//clear the bufRX
	for (i = 0; i < 26; i++) {
		bufRX[i] = 0;
	}
 
	//clear the bufRX
	for (i = 0; i < 26; i++) {
		bufRX[i] = 0;
	}
 
	random_num = rnd_between(1, 3);
 //printf("RND:%d\n", (random_num);
 
	switch (random_num) {
	case 1:
		bufTX[0] = NOTHING;
		break;
	case 2:
		bufTX[0] = SEND_ROWS;
		break;
	case 3:
		bufTX[0] = SHUT_DOWN_LEADS;
		break;
	default:
		break;
	}
 
	SPI_Send();
	HAL_Delay(1000);
 
	for (i = 0; i < 26; i++) {
		printf("T[%X]R[%X]\n", bufTX[i], bufRX[i]);
	}
	printf("-------------------------------------------------\n");
}

Standard FreeRTOS task with default parameters:

void spiSendLoop(void *argument){
 while(1){
	 initial();
 }
}

I do not use interrupts!

All registers has the same value as without freertos.

GPIO has normal values.

spiSendLoop task works normally, 'printf' prints values '0' but oscilloscope detect no action on MOSI pin

DVovk.1
DVovk.1Author
Associate
May 29, 2021

This time GPIOA->AFR register was set to wrong values.

So many mystical in my codes)