cancel
Showing results for 
Search instead for 
Did you mean: 

Failing to receive data on MCU set up as SPI slave

KSchr.11
Associate II

Trying to receive data on MCU (L432KC) configured as SPI slave. I have tried using interrupt and DMA, but no luck.

I have set up the circuit like this : 1 MCU acts as master sending 1,2,3 every 500ms interval (I hooked up master lines to scope and the signals are generated correctly). On the other MCU configured as slave, I've connected a RGB led, which is supposed to react to 1,2,3.

Here's my code (interrupt handler commented)

#include "stm32l4xx.h"                  // Device header
 
//RGB led is common anode 
 
#define RED_ON (GPIOB->ODR &=~(1<<1))
#define RED_OFF (GPIOB->ODR |=1<<1)
 
#define BLUE_ON (GPIOB->ODR &=~(1<<6))
#define BLUE_OFF (GPIOB->ODR |= 1<<6)
 
#define GREEN_ON (GPIOB->ODR &=~(1<<7))
#define GREEN_OFF (GPIOB->ODR |= 1<<7);
 
void SPI1_Slave_init(void);
void delayms(int count);
int SPI1_read(void);
void SPI1rx_DMA_init(int c);
 
 
int main()
{
	int c=1;
	SPI1_Slave_init();
	SPI1rx_DMA_init(c);
	RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN;
	
	GPIOB->MODER &=~(3<<2 | 3<<12 | 3<<14);
	GPIOB->MODER |= 1<<2 | 1<<12 | 1<<14;
	
	GPIOB->ODR |= (1<<1 | 1<<6 | 1<<7);
	
	//NVIC_EnableIRQ(SPI1_IRQn);
	
	while(1)
	{
		DMA1_Channel2->CCR |= DMA_CCR_EN;			//enable channel 
		
		while(!(DMA1->ISR & DMA_ISR_TCIF2));			//wait till channel 2 transfer is complete
		
		
		
		
		switch(c)
		{
			case 1: GREEN_OFF;
			BLUE_OFF;
			RED_ON;
			break;
			
			case 2: RED_OFF;
			BLUE_OFF;
			GREEN_ON;
			break;
			
			case 3: RED_OFF;
			GREEN_OFF;
			BLUE_ON;
			break;
			
		}
		
		DMA1->IFCR |= DMA_IFCR_CTCIF2;
		
		DMA1_Channel2->CCR &=~ (DMA_CCR_EN);		//disable channel
		
	}
}
 
void SPI1_Slave_init(void)
{
	RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
	
	RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
	
	GPIOA->MODER &=~(3<<8 | 3<<10 | 3<<12 | 3<<14);
	GPIOA->MODER |= (2<<8 | 2<<10 | 2<<12 | 2<<14);			//set as AF
	
	
	GPIOA->AFR[0] &=~(0xF<<16 | 0XF<<20 | 0xF<<24 | 0xF<<28);
	GPIOA->AFR[0] |= (5<<16 | 5<<20 | 5<<24 | 5<<28);				//AF5 
	
	SPI1->CR1 &=~ (SPI_CR1_SPE);			//disable SPI
	
	SPI1->CR1 &=~ (SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_MSTR);			//slave
	
	SPI1->CR1 |= (1<<3);			// 1MHz baud rate
	
	SPI1->CR2 &= ~(0xF<<8);
	SPI1->CR2 |= 7<<8;				//8 bit data
	
	//SPI1->CR2 |= SPI_CR2_RXNEIE;			//enable RXNE interrupt
	
	SPI1->CR1 |= SPI_CR1_SPE;
}
 
void SPI1rx_DMA_init(int c)
{
	
	RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
	
	//DMA channel config
	DMA1_Channel2->CCR &=~(DMA_CCR_EN);
	DMA1_Channel2->CCR &=~(DMA_CCR_DIR);
	DMA1_Channel2->CNDTR = 1;
	DMA1_Channel2->CPAR = (uint32_t)&SPI1->DR;			
	DMA1_Channel2->CMAR = (uint32_t)c;
	DMA1_CSELR->CSELR |= 1<<4;				//DMA1 Channel 2 mapped to request no 2 (SPI1_RX)
	
	SPI1->CR2 |= SPI_CR2_RXDMAEN;
	
}
 
 
 
/*
void SPI1_IRQHandler(void)
{
	uint8_t c;
	
	if(SPI1->SR & SPI_SR_RXNE)
	{
		c = *(__IO uint8_t *)&SPI1->DR;
		
		switch(c)
		{
			case 1: GREEN_OFF;
			BLUE_OFF;
			RED_ON;
			break;
			
			case 2: RED_OFF;
			BLUE_OFF;
			GREEN_ON;
			break;
			
			case 3: RED_OFF;
			GREEN_OFF;
			BLUE_ON;
			break;
			
		}
	}
	
}
 
*/

I've tested the LED part of code separately, blinking R,G and B and it also works fine.

Again, tested interrupt and DMA separately, so ignore one while considering the other in the code. I've tested it with a normal receive subroutine too, but I had not much hope with it anyway.

Just failing to receive data on slave. What am I doing wrong?

EDIT : Here are the waveforms on scope. When disconnected from slave, the waveforms are perfect. However when I connect the master to slave, there is some noise and the SCL line has a amplitude of 900mV.

0693W000001rE5UQAU.png0693W000001rE5PQAU.png

12 REPLIES 12

> I checked user manual to see if PA5 was connected to something and don't really see anything.

Hummm...

In a minimal program, try only setting PA5 as GPIO Input with pulldown, and measure.

JW

No, I use barebone gdb which is not the easiest thing to use; but Keil should be usable for it.

JW

> My slave in this program is a Nucleo L432KC.

> I checked user manual to see if PA5 was connected to something and don't really see anything.

Which user manual did you check?

0693W000001rEhEQAU.png

JW