Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
10 years ago

NIOS II SPI communication

Hi All!

I've a problem with Nios SPI communication. I studied "Embedded Peripherals IP User Guide" but I didn't understand how to use alt_avalon_spi_command() function. I understood that an Avalon-MM master peripheral controls and communicates with the SPI core via six 32-bitregisters. So I searched more examples on web but I only found this:

//------------------------------------ MAIN ------------------------------------------------------------

int main(void){

void send(alt_u16 write);

alt_u16 receive();

alt_u16 wrdata=0xabcd;

alt_u16 rddata;

IOWR_ALTERA_AVALON_SPI_SLAVE_SEL(SPI_BASE, 1);

IORD_ALTERA_AVALON_SPI_RXDATA(SPI_BASE);

while(1){

send(wrdata);

rddata=receive();

}

return 0;

}

//-------------------------------------- SEND -------------------------------------------------------------------------

void send(alt_u16 write){

alt_u32 status;

alt_u16 data;

IOWR_ALTERA_AVALON_SPI_CONTROL(SPI_BASE, 0x0400);

IORD_ALTERA_AVALON_SPI_RXDATA(SPI_BASE);

do{

status = IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE);

}

while (((status & ALTERA_AVALON_SPI_STATUS_TRDY_MSK) == 0)&&(status & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) == 0);

IOWR_ALTERA_AVALON_SPI_TXDATA(SPI_BASE , write);

data=IORD_ALTERA_AVALON_SPI_RXDATA(SPI_BASE);

do{

status = IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE);

}

while ((status & ALTERA_AVALON_SPI_STATUS_TMT_MSK) == 0);

IOWR_ALTERA_AVALON_SPI_CONTROL(SPI_BASE, 0);

}

//----------------------------------- RECEIVE --------------------------------------------------------------------------

alt_u16 receive(){

alt_u16 data;

alt_u32 status;

IOWR_ALTERA_AVALON_SPI_CONTROL(SPI_BASE, 0x0400);

IORD_ALTERA_AVALON_SPI_RXDATA(SPI_BASE);

do{

status = IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE);

}

while (((status & ALTERA_AVALON_SPI_STATUS_TRDY_MSK) == 0 ) && (status & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) == 0);

IOWR_ALTERA_AVALON_SPI_TXDATA(SPI_BASE , 0x00);

data=IORD_ALTERA_AVALON_SPI_RXDATA(SPI_BASE);

do{

status = IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE);

}

while ((status & ALTERA_AVALON_SPI_STATUS_TMT_MSK) == 0);

IOWR_ALTERA_AVALON_SPI_CONTROL(SPI_BASE, 0);

return data;

}

The question is "What's the difference between alt_avalon_spi_command() and IOWR_ALTERA_AVALON_SPI_TXDATA() to transmit a data via SPI"?

Thank you all :)

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The difference should be clear from the description in the user guide? alt_avalon_spi_command() performs the sequence of actions described in the manual, while IOWR_ALTERA_AVALON_SPI_TXDATA() just writes the TXDATA register.

    You can read the source to the alt_avalon_spi_command() function and see how it uses IOWR_ALTERA_AVALON_SPI_TXDATA() and everything else that it does to gain better understanding.

    There is also an example use of the function here:

    http://www.alterawiki.com/wiki/spi_core
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you, you were so clear. I have another question please. What have I do to set NIOS in slave mode in SPI communication? I explane my problem. I have to load Cyclone V firmware into an external EPCQ128 with a microcontroller that communicates with NIOS via SPI. And so, I need to set my microcontroller as master, and NIOS as slave in SPI communication.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I tried to write a simple code section in C language to make SPI communication, with NIOS as slave. Can you check if my code is good please?

    static void spi_rx_isr(void* isr_context);

    static void spi_rx_isr(void* isr_context){

    IOWR_ALTERA_AVALON_SPI_STATUS(SPI_SLAVE_BASE, 0x0);

    }

    int ret;

    int status;

    alt_u16 rddata;

    //this registers slave IRQ with NIOS

    ret = alt_iic_isr_register(SPI_SLAVE_IRQ_INTERRUPT_CONTROLLER_ID,SPI_SLAVE_IRQ,spi_rx_isr,(void *)spi_command_string_tx,0x0);

    //check if slave status is good

    do{

    status = IORD_ALTERA_AVALON_SPI_STATUS(SPI_SLAVE_BASE);

    }

    while ((status & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) == 0);

    //copy received byte into rddata variable

    rddata = IORD_ALTERA_AVALON_SPI_RXDATA(SPI_SLAVE_BASE);

    //set slave IRQ to enable a new byte receiving

    IOWR_ALTERA_AVALON_SPI_CONTROL(SPI_SLAVE_BASE, ALTERA_AVALON_SPI_CONTROL_SSO_MSK | ALTERA_AVALON_SPI_CONTROL_IRRDY_MSK);
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    HI fmv,

    i'm facing the same problems that you had. I tried both codes you have proposed but i still have several problems to obtain data and retransmitt data back to the Master defined as a microcontroller. I was wondering if you could provide me the entire code that you've used in order to solve the problem or some advices to adopt.

    Thanks