SAMD21 SPI not working.

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

I've been working on converting from lovely 8-bit ATMEGA controllers to this fancy 32bit stuff. Not gonna lie it is not the kind of fun i'd expect. 
USB was easier than i thought to get up and working but i've been struggling a lot with SPI. 
The IC I'm using is SAMD21G18A

 

Things I've spotted:
Using spi_set_baudrate(&config_spi_master, 1000000); causes it to crash, hangs at a "void Dummy_Handler(void)"
I stepped though the code and yes it does indeed cause it to go into interrupt.

 

Troubleshooting done:
-If I don't use the set_baudrate the code simply just runs but does not write anything to SPI, it just sits there.
-I can see that the slave CS pin is being pulled low and high within around 90us.
WHICH funny enough is close to what i'd expect. Default baudrate is 100KHz so 1/100K = 10us * 8 bytes = 80us.
AND then there is time for pulling the CS pin high and low so it does seem like it is transmitting.
- Mux config should be correctly. I've validated it against the AT03255 page 64 which shows pinout of DO/DI and mux settings.
- I tried configuring the SPI pins as input/output like a GPIO but that didn't solve anything.
- I checked the SS pin is not being pulled LOW so it goes into slave mode.
- Tried changing the GCLK to 8MHz internal.

FYI. logic analyser attached to the pins so I can check them.

 

Test procedure: 
- SPI_TEST is the code that is being executed for testing. Simply just write 0x22 onto the SPI bus every 500ms.
- There are NO SPI devices connected to the MCU currently so there should not be any devices causing issues.

Code:
 

#include "asf.h"
#include "SPI2.h"

struct spi_module spi_master_instance;
struct spi_slave_inst disp_slave;
struct spi_config config_spi_master;
struct spi_slave_inst_config slave_dev_config;

// Configure slave device for display
void init_SPI_display() {
    spi_slave_inst_get_config_defaults(&slave_dev_config);
    slave_dev_config.ss_pin = PIN_PA21;
    spi_attach_slave(&disp_slave, &slave_dev_config);
}

void configure_spi_master(void) {
    
    spi_get_config_defaults(&config_spi_master);

    config_spi_master.mode = SPI_MODE_MASTER;
    
    config_spi_master.mux_setting = SPI_SIGNAL_MUX_SETTING_D;
    config_spi_master.pinmux_pad0 = PIN_PA16C_SERCOM1_PAD0;
    config_spi_master.pinmux_pad1 = PIN_PA17C_SERCOM1_PAD1;
    config_spi_master.pinmux_pad2 = PIN_PA18C_SERCOM1_PAD2;
    config_spi_master.pinmux_pad3 = PIN_PA19C_SERCOM1_PAD3;
    
    spi_init(&spi_master_instance, Sercom1, &config_spi_master);
    spi_enable(&spi_master_instance);

}

void init_SPI(void) {
    init_SPI_display();
    configure_spi_master();
    
}

uint8_t SPI_TEST(void) {
    spi_select_slave(&spi_master_instance, &disp_slave, true);
    uint8_t error = spi_write_buffer_wait(&spi_master_instance, 0x22, 1);
    spi_select_slave(&spi_master_instance, &disp_slave, false);
    return(error);
}

Attachment(s): 

This topic has a solution.
Last Edited: Fri. Sep 24, 2021 - 03:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I managed to get it working using the START PROJECT guide thingie.
Tho i really hate the drivers, no proper documentation at all 
Even worse than ASF documentation. 
I guess i'll have to start tearing this crap down until i figure something out. Man this is exhausting 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still not figured out this C**p.
I can't believe it has to be this difficult to get working. 
Normally I would have expected this to be a hardware issue but now that I've managed to get the thing working I can't say it is hardware related. 
So why the heck does a simple example like that not work with the slight modification I've done?

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Finally got this c**p working!
I found a post by Lajon(Lars) showing a configuration. 
I've tried SO many examples and this is the first one that worked! Bare metal code > ASF c**p 
That is one way to spend +10 hours 

Code specifies it runs 2 / CPU FREQ
And it does!
I even tried pushing it harder by enabling DFLL. My logic analyser cannot measure the 24MHz bits but it could measure the clock period of 333us so 1/(333us / 8 bits) = 24MHz!
Not bad at all! I haven't had a proper scope connected to it yet as I just wanna get all my code up and running first. 

Comment #5
https://community.atmel.com/foru...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Hi Decee1,

 

Actually I've been struggling with a basic spi communication.  I am trying to communicate two SAMD21 Xplained Pro with a Bare Code. The clock system is working properly and i think the spi configuration of the boards master and slave are correct.

 

For the spi communication i am using the functions  from this application note AN2465 (Basic Configuration 5.1)

 

Master:    spi_master_send() and SERCOM3_Handler()

Slave:       spi_slave_rx_data() and SERCOM3_Handler()

 

In the Basic configuration application, the master will transmit a data buffer of a few bytes to the slave and the slave will re-transmit the same data buffer to the master.

 

With the logic analyzer i can see the MOSI wire with the 5 bytes (0x01, 0x02, 0x03, 0x04, 0x05) but the MISO wire in not working properly:

 

 

 

The figure below is a screen shot oh the basic configuration transaction between master and slave of the application note AN2465:

 

 

 

*** Have you "send()"/"receive()" functions example with a Bare Code?

 

 

Hier my code:

 

// --- Master

 

#include <stdbool.h>
#include "sam.h"

#define SWITCH_CPU_TO_DFPLL96M_WITH_INT_OSC8M	0
#define CS_LOW		PORT->Group[0].OUTCLR.reg = PORT_PA18
#define CS_HIGH		PORT->Group[0].OUTSET.reg = PORT_PA18
#define SIZE_BUFF	5

volatile bool tx_done;		// variable to indicate transmission is done
uint8_t tx_buff[SIZE_BUFF] = {0x01, 0x02, 0x03, 0x04, 0x05};
uint8_t rx_buff[SIZE_BUFF];
uint8_t i=0;    
uint8_t j=0;   

void initClock();
void initSPI();
void set_spi_speed(Sercom * S, uint8_t baudval);
void spi_master_send(void);

/******************************************************************************/
/*** Peripheral configuration and initialization		            ***/
/******************************************************************************/
void set_spi_speed( Sercom * S, uint8_t baudval)
{
	if(S->SPI.CTRLA.bit.ENABLE)
	{
		S->SPI.CTRLA.bit.ENABLE = 0;
		while(S->SPI.SYNCBUSY.bit.ENABLE);
		S->SPI.BAUD.reg = baudval;
		S->SPI.CTRLA.bit.ENABLE = 1;
		while(S->SPI.SYNCBUSY.bit.ENABLE);
	}
	else
		S->SPI.BAUD.reg = baudval;
}

void initClock()
{
	// ---------- activate GCLK debug outputs ----------
 	REG_PORT_DIRSET1 = PORT_PB22;						// With FDPLL96M: 40Mhz
 	PORT->Group[1].PINCFG[22].reg |= PORT_PINCFG_PMUXEN;
 	PORT->Group[1].PMUX[22 >> 1].bit.PMUXE = PORT_PMUX_PMUXE_H_Val;

	REG_PORT_DIRSET0 = PORT_PA10;						// With FDPLL96M: 10Mhz
	PORT->Group[0].PINCFG[10].reg |= PORT_PINCFG_PMUXEN;
	PORT->Group[0].PMUX[10 >> 1].bit.PMUXE = PORT_PMUX_PMUXE_H_Val;

	// ---------- configure wait states ----------
	NVMCTRL->CTRLB.bit.RWS=2;

	PM->APBAMASK.reg |= PM_APBAMASK_GCLK;
	GCLK->CTRL.reg = GCLK_CTRL_SWRST;
        while (GCLK->CTRL.bit.SWRST && GCLK->STATUS.bit.SYNCBUSY);

#ifdef SWITCH_CPU_TO_DFPLL96M_WITH_INT_OSC8M
	// ---------- configure GCLK3 to run at 1Mhz ----------
	SYSCTRL->OSC8M.bit.ONDEMAND = 0;
	GCLK->GENDIV.reg = GCLK_GENDIV_ID(3) | GCLK_GENDIV_DIV(1);
	// --- Generic Clock Generator
	GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(3)
		          | GCLK_GENCTRL_SRC(GCLK_SOURCE_OSC8M)
			  | GCLK_GENCTRL_OE
			  | GCLK_GENCTRL_RUNSTDBY
			  | GCLK_GENCTRL_GENEN;
        while(GCLK->STATUS.bit.SYNCBUSY);      										

	// ---------- switch GCLK3 to DFLL ----------
	// --- Generic Clock Controller
	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_FDPLL
			  | GCLK_CLKCTRL_GEN_GCLK3
			  | GCLK_CLKCTRL_CLKEN;
        while(GCLK->STATUS.bit.SYNCBUSY); 	

	// ---------- configure FDPLL96M ----------
	SYSCTRL->DPLLRATIO.reg = SYSCTRL_DPLLRATIO_LDR(79)
	 	               | SYSCTRL_DPLLRATIO_LDRFRAC(0);
	SYSCTRL->DPLLCTRLB.reg = SYSCTRL_DPLLCTRLB_LTIME_DEFAULT
	 		       | SYSCTRL_DPLLCTRLB_REFCLK_GCLK;
	SYSCTRL->DPLLCTRLA.reg = SYSCTRL_DPLLCTRLA_RUNSTDBY
			       | SYSCTRL_DPLLCTRLA_ENABLE;
        while (!SYSCTRL->DPLLSTATUS.bit.ENABLE);
	SYSCTRL->DPLLCTRLB.bit.LBYPASS=1;

	// ---------- switch main clock to DFLL ----------
	GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) | GCLK_GENDIV_DIV(2);
	GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(0)
			  | GCLK_GENCTRL_SRC(GCLK_SOURCE_DPLL96M)
		          | GCLK_GENCTRL_OE
			  | GCLK_GENCTRL_RUNSTDBY
			  | GCLK_GENCTRL_IDC
			  | GCLK_GENCTRL_GENEN;
       while (GCLK->STATUS.bit.SYNCBUSY);

#endif	//-- switch_cpu_to_fdpll96m
}

void initSPI()
{
	// ---------- enable SPI_SERCOM3 pins (MISO/MOSI/SCK/_SS) ----------
	// --- GPIO
	PORT->Group[0].DIRSET.reg = PORT_PA18;  // SS
	PORT->Group[0].OUTSET.reg = PORT_PA18;								

	// --- Multiplexing
	REG_PORT_DIRSET0 = PORT_PA16;           // MOSI
	PORT->Group[0].PINCFG[16].reg |= PORT_PINCFG_PMUXEN;
	PORT->Group[0].PMUX[16 >> 1].bit.PMUXE = PORT_PMUX_PMUXE_D_Val;		

	REG_PORT_DIRSET0 = PORT_PA17;           // SCLK
	PORT->Group[0].PINCFG[17].reg |= PORT_PINCFG_PMUXEN;
	PORT->Group[0].PMUX[17 >> 1].bit.PMUXO = PORT_PMUX_PMUXE_D_Val;		

	REG_PORT_DIRCLR0 = PORT_PA19;           // MISO
	PORT->Group[0].PINCFG[19].reg |= PORT_PINCFG_PMUXEN;
	PORT->Group[0].PMUX[19 >> 1].bit.PMUXO = PORT_PMUX_PMUXE_D_Val;		

	// ---------- configure GCLK 4 ----------
 	GCLK->GENDIV.reg = GCLK_GENDIV_ID(4) | GCLK_GENDIV_DIV(8);
 	GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(4)
 			  | GCLK_GENCTRL_SRC(GCLK_SOURCE_DPLL96M)
 			  | GCLK_GENCTRL_OE
 			  | GCLK_GENCTRL_RUNSTDBY
 			  | GCLK_GENCTRL_GENEN;
        while(GCLK->STATUS.bit.SYNCBUSY);         

	// 	---------- configure SPI ----------
	PM->APBCMASK.reg |= PM_APBCMASK_SERCOM3;									

	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
		          | GCLK_CLKCTRL_GEN_GCLK4
			  | GCLK_CLKCTRL_ID_SERCOM3_CORE;
	while(GCLK->STATUS.bit.SYNCBUSY);											

	SERCOM3->SPI.CTRLA.bit.ENABLE = 0;
	while(SERCOM3->SPI.SYNCBUSY.bit.ENABLE);									

	SERCOM3->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(0x0)
			       | SERCOM_SPI_CTRLA_DIPO(0x3)
			       | SERCOM_SPI_CTRLA_CPOL
			       | SERCOM_SPI_CTRLA_CPHA
			       | SERCOM_SPI_CTRLA_MODE_SPI_MASTER;
	                //   | SERCOM_SPI_CTRLA_RUNSTDBY;
       while(SERCOM3->SPI.SYNCBUSY.bit.CTRLB);

	SERCOM3->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_RXEN;
	while(SERCOM3->SPI.SYNCBUSY.bit.CTRLB);
	set_spi_speed(SERCOM3, 1);
	SERCOM3->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
	while(SERCOM3->SPI.SYNCBUSY.reg & SERCOM_SPI_SYNCBUSY_ENABLE);
}

/******************************************************************************/
/*** Peripheral functions	            	                            ***/
/******************************************************************************/
void spi_master_send(void)
{
	i=0;
	j=0;
	tx_done = false;

	CS_LOW;
	SERCOM3->SPI.INTENSET.reg = SERCOM_SPI_INTENSET_DRE
				  | SERCOM_SPI_INTENSET_RXC;
	while(!tx_done);
	CS_HIGH;
	SERCOM3->SPI.CTRLA.reg &=~SERCOM_SPI_CTRLA_ENABLE;
	while(SERCOM3->SPI.SYNCBUSY.reg & SERCOM_SPI_SYNCBUSY_ENABLE);
}

/******************************************************************************/
/*** Peripherals handlers                          			    ***/
/******************************************************************************/
void SERCOM3_Handler(void)	// --- SPI
{
	// ---------- data register empty ----------
	if(SERCOM3->SPI.INTFLAG.bit.DRE && SERCOM3->SPI.INTENSET.bit.DRE)
	{
		SERCOM3->SPI.DATA.reg = tx_buff[i++];				// write into data
		if(i==5)
			SERCOM3->SPI.INTENCLR.reg = SERCOM_SPI_INTENCLR_DRE;
	}
	// ---------- receive complete interrupt ---------
	if(SERCOM3->SPI.INTFLAG.bit.RXC && SERCOM3->SPI.INTENSET.bit.RXC)
	{
		rx_buff[j++] = SERCOM3->SPI.DATA.reg;				// read from data
		if(j==5)
		{
			SERCOM3->SPI.INTENCLR.reg = SERCOM_SPI_INTENCLR_RXC;
			tx_done = true;
		}
	}
}

void enableInterrupts()
{
	NVIC_DisableIRQ(SERCOM3_IRQn);
	NVIC_ClearPendingIRQ(SERCOM3_IRQn);
	NVIC_EnableIRQ(SERCOM3_IRQn);
}

int main(void)
{
	// Initialize the SAM system
	SystemInit();

	// Initialize peripherals
	initClock();
	for (int i=0; i<10000; i++) { asm("nop\n"); }
	initSPI();
	for (int i=0; i<10000; i++) { asm("nop\n"); }

	enableInterrupts();

	while (1)
        {
		for (int i=0; i<10000; i++) { asm("nop\n"); }
		spi_master_send();
 	}
}

 

// --- Slave

 

#include <stdbool.h>
#include "sam.h"

#define SWITCH_CPU_TO_DFPLL96M_WITH_INT_OSC8M	0
#define SIZE_BUFF	5    

volatile bool rx_done=false;
uint8_t rx_buff[SIZE_BUFF];
uint8_t tx_buff[SIZE_BUFF];
uint8_t i=0;
uint8_t j=0;

void initClock();
void initSPI();
void spi_slave_rx_data();

/******************************************************************************/
/*** Peripheral configuration and initialization			    ***/
/******************************************************************************/
void initClock()
{
	// ---------- activate GCLK debug outputs ----------
 	REG_PORT_DIRSET1 = PORT_PB22;						// With FDPLL96M: 40Mhz
 	PORT->Group[1].PINCFG[22].reg |= PORT_PINCFG_PMUXEN;
 	PORT->Group[1].PMUX[22 >> 1].bit.PMUXE = PORT_PMUX_PMUXE_H_Val;

	REG_PORT_DIRSET0 = PORT_PA10;						// With FDPLL96M: 10Mhz
	PORT->Group[0].PINCFG[10].reg |= PORT_PINCFG_PMUXEN;
	PORT->Group[0].PMUX[10 >> 1].bit.PMUXE = PORT_PMUX_PMUXE_H_Val;

	// ---------- configure wait states ----------
	NVMCTRL->CTRLB.bit.RWS=2;
        PM->APBAMASK.reg |= PM_APBAMASK_GCLK;
	GCLK->CTRL.reg = GCLK_CTRL_SWRST;
        while (GCLK->CTRL.bit.SWRST && GCLK->STATUS.bit.SYNCBUSY);

#ifdef SWITCH_CPU_TO_DFPLL96M_WITH_INT_OSC8M
	// ---------- configure GCLK3 to run at 1Mhz ----------
	SYSCTRL->OSC8M.bit.ONDEMAND = 0;
	GCLK->GENDIV.reg = GCLK_GENDIV_ID(3) | GCLK_GENDIV_DIV(1);
	// --- Generic Clock Generator
	GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(3)
			  | GCLK_GENCTRL_SRC(GCLK_SOURCE_OSC8M)
			  | GCLK_GENCTRL_OE
			  | GCLK_GENCTRL_RUNSTDBY
			  | GCLK_GENCTRL_GENEN;
        while(GCLK->STATUS.bit.SYNCBUSY);											

	// ---------- switch GCLK3 to DFLL ----------
	// --- Generic Clock Controller
	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_FDPLL
			  | GCLK_CLKCTRL_GEN_GCLK3
			  | GCLK_CLKCTRL_CLKEN;
        while(GCLK->STATUS.bit.SYNCBUSY);											

	// ---------- configure FDPLL96M ----------
	SYSCTRL->DPLLRATIO.reg = SYSCTRL_DPLLRATIO_LDR(79)
	          	       | SYSCTRL_DPLLRATIO_LDRFRAC(0);
	SYSCTRL->DPLLCTRLB.reg = SYSCTRL_DPLLCTRLB_LTIME_DEFAULT
	 		       | SYSCTRL_DPLLCTRLB_REFCLK_GCLK;
	SYSCTRL->DPLLCTRLA.reg = SYSCTRL_DPLLCTRLA_RUNSTDBY
	                       | SYSCTRL_DPLLCTRLA_ENABLE;
        while (!SYSCTRL->DPLLSTATUS.bit.ENABLE);
	SYSCTRL->DPLLCTRLB.bit.LBYPASS=1;

        // ---------- switch main clock to DFLL ----------
	GCLK->GENDIV.reg = GCLK_GENDIV_ID(0) | GCLK_GENDIV_DIV(2);
	GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(0)
			  | GCLK_GENCTRL_SRC(GCLK_SOURCE_DPLL96M)
			  | GCLK_GENCTRL_OE
		          | GCLK_GENCTRL_RUNSTDBY
			  | GCLK_GENCTRL_IDC
		          | GCLK_GENCTRL_GENEN;
        while (GCLK->STATUS.bit.SYNCBUSY);
#endif	//-- switch_cpu_to_fdpll96m
}

void initSPI()
{
	// ---------- enable SPI_SERCOM3 pins (MISO/MOSI/SCK/_SS) ----------
        // --- Multiplexing
	REG_PORT_DIRCLR0 = PORT_PA16;           // MOSI
	PORT->Group[0].PINCFG[16].reg |= PORT_PINCFG_PMUXEN;
	PORT->Group[0].PMUX[16 >> 1].bit.PMUXE = PORT_PMUX_PMUXE_D_Val;		

	REG_PORT_DIRCLR0 = PORT_PA17;		    // SCLK
	PORT->Group[0].PINCFG[17].reg |= PORT_PINCFG_PMUXEN;
	PORT->Group[0].PMUX[17 >> 1].bit.PMUXO = PORT_PMUX_PMUXE_D_Val;		

	// Pull-resistor is set into high
	PORT->Group[0].PINCFG[18].reg = PORT_PINCFG_INEN
	          		      | PORT_PINCFG_PULLEN;
	PORT->Group[0].OUTSET.reg = PORT_PA18;  // SS
	PORT->Group[0].PINCFG[18].reg |= PORT_PINCFG_PMUXEN;
	PORT->Group[0].PMUX[18 >> 1].bit.PMUXE = PORT_PMUX_PMUXE_D_Val;		

	REG_PORT_DIRSET0 = PORT_PA19;		    // MISO
	PORT->Group[0].PINCFG[19].reg |= PORT_PINCFG_PMUXEN;
	PORT->Group[0].PMUX[19 >> 1].bit.PMUXO = PORT_PMUX_PMUXE_D_Val;		

	// ---------- configure GCLK 4 ----------
	GCLK->GENDIV.reg = GCLK_GENDIV_ID(4) | GCLK_GENDIV_DIV(8);
	GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(4)
			  | GCLK_GENCTRL_SRC(GCLK_SOURCE_DPLL96M)
			  | GCLK_GENCTRL_OE
			  | GCLK_GENCTRL_RUNSTDBY
			  | GCLK_GENCTRL_GENEN;
        while(GCLK->STATUS.bit.SYNCBUSY);											

	// ---------- configure SPI ----------
	PM->APBCMASK.reg |= PM_APBCMASK_SERCOM3;

        GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN
		          | GCLK_CLKCTRL_GEN_GCLK4
			  | GCLK_CLKCTRL_ID_SERCOM3_CORE;
        while(GCLK->STATUS.bit.SYNCBUSY);											

	SERCOM3->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(0x0)
	         	       | SERCOM_SPI_CTRLA_DIPO(0x3)
			       | SERCOM_SPI_CTRLA_CPOL
			       | SERCOM_SPI_CTRLA_CPHA
			       | SERCOM_SPI_CTRLA_MODE_SPI_SLAVE;
			//   | SERCOM_SPI_CTRLA_RUNSTDBY;
        //while(SERCOM3->SPI.SYNCBUSY.bit.CTRLB);
	SERCOM3->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_RXEN;
        while(SERCOM3->SPI.SYNCBUSY.bit.CTRLB);
	SERCOM3->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
        while(SERCOM3->SPI.SYNCBUSY.reg & SERCOM_SPI_SYNCBUSY_ENABLE);
}

/******************************************************************************/
/*** Peripheral functions	         	                            ***/
/******************************************************************************/
void spi_slave_rx_data()
{
	i = 0;
	SERCOM3->SPI.DATA.reg = tx_buff[0];	// write into data
	j = 1;
	SERCOM3->SPI.INTENSET.reg = SERCOM_SPI_INTENSET_DRE
				  | SERCOM_SPI_INTENSET_RXC;
 	while (!rx_done);
 }

/******************************************************************************/
/*** Peripherals handlers                          			    ***/
/******************************************************************************/
void SERCOM3_Handler()
{
	// ---------- data register empty ----------
	if(SERCOM3->SPI.INTFLAG.bit.DRE && SERCOM3->SPI.INTENSET.bit.DRE)
	{
		SERCOM3->SPI.DATA.reg = tx_buff[j++];
		if(j==5)
			SERCOM3->SPI.INTENCLR.reg = SERCOM_SPI_INTENCLR_DRE;
	}
	// ---------- receive complete interrupt ---------
	if(SERCOM3->SPI.INTFLAG.bit.RXC && SERCOM3->SPI.INTENSET.bit.RXC)
	{
		rx_buff[i++] = SERCOM3->SPI.DATA.reg;	// read from data
		if(i==5)
		{
			SERCOM3->SPI.INTENCLR.reg = SERCOM_SPI_INTENCLR_RXC;
			rx_done = true;
		}
	}
}

void enableInterrupts()
{
	NVIC_DisableIRQ(SERCOM3_IRQn);
	NVIC_ClearPendingIRQ(SERCOM3_IRQn);
	NVIC_EnableIRQ(SERCOM3_IRQn);
}

int main(void)
{
	// Initialize the SAM system
	SystemInit();

	// Initialize peripherals
	initClock();
	for (int i=0; i<10000; i++) { asm("nop\n"); }
	initSPI();
	for (int i=0; i<10000; i++) { asm("nop\n"); }

	enableInterrupts();

	while (1)
	{
		for (int i=0; i<10000; i++) { asm("nop\n"); }
		spi_slave_rx_data();

	}
}

 

Thank you very much

 

 

Last Edited: Fri. Oct 1, 2021 - 02:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DIPO and DOPO are set wrong for the slave. Quick check: For a slave MOSI is setup with DIPO where you have 3 hence MOSI is PAD[3] (PA19) which you have commented should be MISO.

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lajon wrote:

DIPO and DOPO are set wrong for the slave. Quick check: For a slave MOSI is setup with DIPO where you have 3 hence MOSI is PAD[3] (PA19) which you have commented should be MISO.

/Lars

 

Hi Lars,

 

thank you so much. You are right, the DIPO and DOPO were set wrong for the slave but i still have the same problem. I have initialized the tx_buff[] = {0x00, 0x06, 0x07, 0x08, 0x09} for the slave but the MISO wire receives the same values as before (0x00 | 0x00 | 0x00 | 0x00 | 0x00) .