Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20688 Discussions

NIOS II SPI communication

Altera_Forum
Honored Contributor II
4,736 Views

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 :)
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
2,407 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
2,407 Views

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.

0 Kudos
Altera_Forum
Honored Contributor II
2,407 Views

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);
0 Kudos
Altera_Forum
Honored Contributor II
2,407 Views

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
0 Kudos
Reply