SAM D21 SPI communication (Slave not reading)

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

Hi,

My first post and i am beginner.

I am using two atsamd21g16a and want to do SPI communication between them.
I tested Master atsamd21g16a with arduino board and its working.i can get data on arduino side.

But when i want to read data on slave atsamd21g16a, it's not working. 

connections are;

Master ------- Slave (SERCOM0)

PA04  <------  PA04 (MISO)

PA05  -------->PA05 (SS)

PA06  -------->PA06 (MOSI)

PA07  -------->PA07 (SCK)

 

Bellow i am pasting the code i am using : Check the Redline in the bottom, i am not getting anyvalue there what i am sending from master.

Master:

 

//! [buf_length]
#define BUF_LENGTH 1
//! [buf_length]
//! [slave_select_pin]
#define SLAVE_SELECT_PIN PIN_PA05
//! [slave_select_pin]
//! [buffer]
uint8_t buffer[BUF_LENGTH] = {};

struct spi_module spi_master_instance;

//! [dev_inst]
//! [slave_dev_inst]
struct spi_slave_inst slave;
//! [slave_dev_inst]
//! [setup]

void configure_spi_master(void);

//! [configure_spi]
void configure_spi_master(void)
{
    //! [config]
    struct spi_config config_spi_master;
    //! [config]
    //! [slave_config]
    struct spi_slave_inst_config slave_dev_config;
    //! [slave_config]
    /* Configure and initialize software device instance of peripheral slave */
    //! [slave_conf_defaults]
    spi_slave_inst_get_config_defaults(&slave_dev_config);
    //! [slave_conf_defaults]
    //! [ss_pin]
    slave_dev_config.ss_pin = SLAVE_SELECT_PIN;
    //! [ss_pin]
    //! [slave_init]
    spi_attach_slave(&slave, &slave_dev_config);
    //! [slave_init]
    /* Configure, initialize and enable SERCOM SPI module */
    //! [conf_defaults]
    spi_get_config_defaults(&config_spi_master);
    //! [conf_defaults]
    //! [mux_setting]
    config_spi_master.mux_setting = SPI_SIGNAL_MUX_SETTING_E;
    //! [mux_setting]
    /* Configure pad 0 for data in */
    //! [di]
    config_spi_master.pinmux_pad0 = PINMUX_PA04D_SERCOM0_PAD0 ;
    //! [di]
    /* Configure pad 1 as unused */
    //! [ss]
    config_spi_master.pinmux_pad1 = PINMUX_UNUSED;
    //! [ss]
    /* Configure pad 2 for data out */
    //! [do]
    config_spi_master.pinmux_pad2 = PINMUX_PA06D_SERCOM0_PAD2;
    //! [do]
    /* Configure pad 3 for SCK */
    //! [sck]
    config_spi_master.pinmux_pad3 = PINMUX_PA07D_SERCOM0_PAD3;

    spi_init(&spi_master_instance, SERCOM0, &config_spi_master);

    spi_enable(&spi_master_instance);
  

}

int main(void)
{

    system_init();
    configure_spi_master();    

    while (true) {
               
            spi_select_slave(&spi_master_instance, &slave, true);
            
            spi_write_buffer_wait(&spi_master_instance, buffer, BUF_LENGTH);
            
            spi_select_slave(&spi_master_instance, &slave, false);
                
        }

}

 

Slave:

#define BUF_LENGTH 1
//! [buf_length]

//! [buffer]
uint8_t buffer[BUF_LENGTH] = {0x00};
//! [buffer]
uint16_t dummy;
//! [dev_inst]
struct spi_module spi_slave_instance;
//! [dev_inst]
//! [setup]

//! [configure_spi]
void configure_spi_slave(void)
{
//! [config]
    struct spi_config config_spi_slave;
//! [config]
    /* Configure, initialize and enable SERCOM SPI module */
//! [conf_defaults]
    spi_get_config_defaults(&config_spi_slave);
//! [conf_defaults]
//! [conf_spi_slave_instance]
    config_spi_slave.mode = SPI_MODE_SLAVE;
//! [conf_spi_slave_instance]
//! [conf_preload]
    config_spi_slave.mode_specific.slave.preload_enable = true;
//! [conf_preload]
//! [conf_format]
    config_spi_slave.mode_specific.slave.frame_format = SPI_FRAME_FORMAT_SPI_FRAME;
//! [conf_format]
//! [mux_setting]
    config_spi_slave.mux_setting = SPI_SIGNAL_MUX_SETTING_E;
//! [mux_setting]
    /* Configure pad 0 for data in */
//! [di]
    config_spi_slave.pinmux_pad0 = PINMUX_PA04D_SERCOM0_PAD0;
//! [di]
    /* Configure pad 1 as unused */
//! [ss]
    config_spi_slave.pinmux_pad1 = PINMUX_PA05D_SERCOM0_PAD1;
//! [ss]
    /* Configure pad 2 for data out */
//! [do]
    config_spi_slave.pinmux_pad2 = PINMUX_PA06D_SERCOM0_PAD2;
//! [do]
    /* Configure pad 3 for SCK */
//! [sck]
    config_spi_slave.pinmux_pad3 = PINMUX_PA07D_SERCOM0_PAD3;
//! [sck]
//! [init]
    spi_init(&spi_slave_instance, SERCOM0, &config_spi_slave);
//! [init]

//! [enable]
    spi_enable(&spi_slave_instance);
//! [enable]

}
//! [configure_spi]
uint8_t data=0x00;
int main(void)
{
//! [main_start]
    /* Initialize system */
//! [system_init]
    system_init();
//! [system_init]

//! [run_config]
    configure_spi_slave();
 

 

    while (true) {
        /* Infinite loop */

        
        

            while (spi_read_buffer_wait(&spi_slave_instance, buffer, BUF_LENGTH, dummy) != STATUS_OK) {
                /* Wait for transfer from master */
                
                data = buffer[0]; // Nothing coming in data
            }

 

}

 

 

Thanks for your help!!!

 

Last Edited: Thu. Oct 15, 2015 - 11:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note that the SAM D21 is not an AVR - it is an ARM Cortex-M0+

 

The ARM Forums are here: http://www.at91.com/

 

Cortex-M0+ specifically: http://www.at91.com/discussions/...

 

Edit:

 

That was before the ARM sections were added here!

 

Still worth checking at AT91.com to see if there's any prior discussion there

Last Edited: Fri. Jul 3, 2015 - 06:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks!!

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

koolkiller wrote:

            while (spi_read_buffer_wait(&spi_slave_instance, buffer, BUF_LENGTH, dummy) != STATUS_OK) {
                /* Wait for transfer from master */
                
                data = buffer[0]; // Nothing coming in data
            }

Do you mean that spi_read_buffer_wait() never returns, or that it does return, but the buffer is empty?

 

Have you looked at the SPI lines with  an oscilloscope?

 

I tested Master atsamd21g16a with arduino board and its working.

What about Arduino as Master and  atsamd21g16a as slave?

 

Is it a custom atsamd21g16a board, or a dev kit?

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

Hi,

The slave gets busy whenever i try to send something so there is interrupt but buffer doesn't get the value. I tried spi_write_buffer wait() and spi_read_buffer_wait().

​No I didn't, unfortunately i don't have that setup :(.

 

I did try but it didn't work.

Well i used Xplained pro d21 and custom atsamd21g16a also.

 

Thanks for looking in to it.

 

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

Might I point out that the new ARM sections already have more traffic than the 91 forums

274,207,281-1 The largest known Mersenne Prime

Measure twice, cry, go back to the hardware store

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

I am having a similar problem with the SPI SERCOM module on the ATSAMD10 using AtmelStudio7 and ASF. 

 

 

When I configure the SERCOM module in Master mode, it works OK.

Master mode settings:-

 

    spi_get_config_defaults(&config_spi);

    config_spi.mode = SPI_MODE_MASTER;
    config_spi.mode_specific.slave.preload_enable = true;
    config_spi.mode_specific.slave.frame_format = SPI_FRAME_FORMAT_SPI_FRAME;
    config_spi.transfer_mode = SPI_TRANSFER_MODE_3;
 
    config_spi.mux_setting = SPI_SIGNAL_MUX_SETTING_D;                                        //  (DOPO = 0 , DIPO = 3  )  
    config_spi.pinmux_pad0 = PINMUX_PA22C_SERCOM1_PAD0;                                 //  MOSI_PIN output
    config_spi.pinmux_pad1 = PINMUX_PA23C_SERCOM1_PAD1;                                 // SCLK
    config_spi.pinmux_pad2 = PINMUX_UNUSED;//PINMUX_PA16C_SERCOM1_PAD2;  // SS
    config_spi.pinmux_pad3 = PINMUX_PA17C_SERCOM1_PAD3;                                 // MISO_PIN   input
    config_spi.mode_specific.master.baudrate = 100000;
    config_spi.master_slave_select_enable = false;
    spi_init(&spi, SERCOM1, &config_spi);

 

 

but setting up in Slave mode I get no receive data.

 

Setting up for Slave mode:-

 

the SERCOM1 module is connect up as follows:

 

#define SS_PIN               PIN_PA16   // Digital input
#define MOSI_PIN           PIN_PA22   // Digital input
#define MISO_PIN           PIN_PA17   // Digital output
#define SCLK_PIN           PIN_PA23   // Digital input

 

the function configuring the SERCOM1 module:

void config_spi()

{

    spi_get_config_defaults(&config);
    config.mode = SPI_MODE_SLAVE;
    config.mode_specific.slave.preload_enable = true;
    config.mode_specific.slave.frame_format = SPI_FRAME_FORMAT_SPI_FRAME;
    
    config.transfer_mode = SPI_TRANSFER_MODE_3;
    config.mux_setting = SPI_SIGNAL_MUX_SETTING_I;            // DOPO: 0x2, DIPO: 0x0 (changed from master above to swap signal lines)
    config.pinmux_pad0 = PINMUX_PA22C_SERCOM1_PAD0;    // DO  (MISO)
    config.pinmux_pad1 = PINMUX_PA23C_SERCOM1_PAD1;    // SCLK
    config.pinmux_pad2 = PINMUX_PA16C_SERCOM1_PAD2;    // SS
    config.pinmux_pad3 = PINMUX_PA17C_SERCOM1_PAD3;    // DI  (MOSI)

    config.select_slave_low_detect_enable = true;
    
    spi_init(&spi, SERCOM1, &config);
    spi_enable(&spi);

}

 

Looking with an oscilloscope  I can clearly see the clock , data and select signals from my master test device on the SAMD10 port pins as expected.

If anyone has been able to get the device with the ASF lib running in slave mode I would be grateful for some help.

 

Thanks

 

 

 

 

 

 

DaveW

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

DOPO: 0x2, DIPO: 0x0 gives you DO (MISO) on PAD[3] and DI (MOSI) on PAD[0], i.e., it does not match your comments. 

/Lars

 

 

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

Thank you for responding.

 

Still getting to grips with the ASF library and the ATMEL SAMD10, it looks like a very flexible part (perhaps to flexible).

 

Yes the comments for MISO & MISO are incorrect, they should be as below:-

 

    config.data_order    = SPI_DATA_ORDER_MSB;
    config.transfer_mode = SPI_TRANSFER_MODE_3;
    config.mux_setting   = SPI_SIGNAL_MUX_SETTING_I;            //
    config.pinmux_pad0   = PINMUX_PA22C_SERCOM1_PAD0;    // DI
    config.pinmux_pad1   = PINMUX_PA23C_SERCOM1_PAD1;    // SCLK
    config.pinmux_pad2   = PINMUX_PA16C_SERCOM1_PAD2;    // SS
    config.pinmux_pad3   = PINMUX_PA17C_SERCOM1_PAD3;    // DO
    config.select_slave_low_detect_enable = true;

 

The actual problem was that the clock and data wires had been swapped over, didn't spot the deliberate mistake until late of Friday. The big lesson is to check the hardware before blaming the software :).  

 

I have now managed to get the Slave SPI port to communicate with a Bus Pirate. 

 

The examples for using the ASF SPI could be improved by clearly showing how the MUX settings and pin configuration are configured. In the example (Atmel AT03665: ASF Manual (SAM D20) the code uses defines which I have been unable to find. 

 

config_spi_slave.mux_setting = EXT1_SPI_SERCOM_MUX_SETTING;
/* Configure pad 0 for data in */
config_spi_slave.pinmux_pad0 = EXT1_SPI_SERCOM_PINMUX_PAD0;
/* Configure pad 1 as unused */
config_spi_slave.pinmux_pad1 = EXT1_SPI_SERCOM_PINMUX_PAD1;
/* Configure pad 2 for data out */
config_spi_slave.pinmux_pad2 = EXT1_SPI_SERCOM_PINMUX_PAD2;
/* Configure pad 3 for SCK */
config_spi_slave.pinmux_pad3 = EXT1_SPI_SERCOM_PINMUX_PAD3;

 

It was also unclear if the ASF SPI driver configures the I/O pins for input and output.

 

Thanks again

David

 

 

 

 

 

 

 

 

 

 

 

 

 

DaveW

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

I am with difficulties with SPI PINMUX in a SAMD21 device, I need to set the following configuration:

 

SPI_MOSI         PIN_PA16

SPI_SCK           PIN_PA17

SPI_SS_0         PIN_PA18
SPI_MISO         PIN_PA19

 

so, i defined pins as follows:

 

#define EXT1_SPI_MODULE              SERCOM1
#define EXT1_SPI_SERCOM_MUX_SETTING  SPI_SIGNAL_MUX_SETTING_D
#define EXT1_SPI_SERCOM_PINMUX_PAD0  PINMUX_PA16C_SERCOM1_PAD0 //MOSI
#define EXT1_SPI_SERCOM_PINMUX_PAD1  PINMUX_PA17C_SERCOM1_PAD1 //CLK
#define EXT1_SPI_SERCOM_PINMUX_PAD2  PINMUX_PA18C_SERCOM1_PAD2 //CS
#define EXT1_SPI_SERCOM_PINMUX_PAD3  PINMUX_PA19C_SERCOM1_PAD3 //MISO
#define EXT1_SPI_SERCOM_DMAC_ID_TX   SERCOM1_DMAC_ID_TX
#define EXT1_SPI_SERCOM_DMAC_ID_RX   SERCOM1_DMAC_ID_RX

 

But i cannot see CLK signal on a scope and CS signal is apparently on pin PIN_PA16.

 

Any idea? (I AM USING SPI MASTER)

Last Edited: Thu. Nov 9, 2017 - 12:43 PM