- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
It is my first message in the forum but I tend to visit it when I have problems in my designs. I always get good information in this forum but in this case, I haven't been able to solve my problem. I don't have a great deal of experience using altera devices and my doubt might be a little simple. I am using the SPI core of SOPC Builder in the NIOS II EDS. Particularly, I am doing a communication using SPI between a cyclone II FPGA and a flash SPI memory. I have checked clock polarity, clock pahse and data direction are suitable for the memory and I have defined a 8bits width data. The communication is very easy: firstly I send the write enable, then I write 0xAA in the address memory 0x0000F0 and finally I read and display it in a LED's array. In my first attempt I used the function...int alt_avalon_spi_command(alt_u32 base, alt_u32 slave,
alt_u32 write_length, const alt_u8 * write_data,
alt_u32 read_length, alt_u8 * read_data,
alt_u32 flags); and the program was ok, so the system definition is ok. However, now I want/need to develop my own driver to use a SPI communication but my attemps end up in failure. I don't know which the mistake is and I will be completely grateful if anyone can give me any tip about my problem. Many thanks! My code is (it is a little long but it is very easy to understand): # include "system.h"# include "altera_avalon_pio_regs.h" //iord & iowr led's# include "altera_avalon_spi_regs.h" //definition of status spi# include "altera_avalon_spi.h" //alt_avalon_spi_command# include "unistd.h" //sleep/usleep# include "os_cpu.h" //definition of int8u type
int main(void){
int8u wdata,slave=0x01,write_en=0x06,page_program=0x02,read_mem=0x03,led_val=0x55;
// initial state led's (01010101)
iowr_altera_avalon_pio_data(led_base,led_val);
usleep(1000000);
// select slave
iowr_altera_avalon_spi_slave_sel(spi_base,slave);
// clean receiver buffer
iord_altera_avalon_spi_rxdata(spi_base);
////////////////////// write enable //////////////////////
// enable chip select selected slave
iowr_altera_avalon_spi_control(spi_base,altera_avalon_spi_control_sso_msk);
wdata=write_en;
// wait until spi bus is empty to transmit
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait until data has been sent
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
// disable chip select of selected slave
iowr_altera_avalon_spi_control(spi_base,0x00);
////////// write byte 0xaa in address memory 0x0000f0 //////////
// enable chip select selected slave
iowr_altera_avalon_spi_control(spi_base,altera_avalon_spi_control_sso_msk);
wdata=page_program;
// wait until spi bus is empty to transmit
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait until data has been sent
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
wdata=0x00;
// wait until spi bus is empty to transmit
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait until data has been sent
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
wdata=0x00;
// wait until spi bus is empty to transmit
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait until data has been sent
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
wdata=0xf0;
// wait until spi bus is empty to transmit
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait until data has been sent
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
wdata=0xaa;
// wait until spi bus is empty to transmit
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
// disable chip select of selected slave
iowr_altera_avalon_spi_control(spi_base,0x00);
///////// read address memory 0x0000f0/////////
iowr_altera_avalon_spi_control(spi_base,altera_avalon_spi_control_sso_msk);
// realizo la comunicación
wdata=read_mem;
// wait until spi bus is empty to transmit
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait until data has been sent
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
wdata=0x00;
// wait until spi bus is empty to transmit
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait until data has been sent
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
wdata=0x00;
// wait until spi bus is empty to transmit
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait until data has been sent
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
wdata=0xf0;
// wait until spi bus is empty
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait until data has been sent
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
// wait until spi bus is empty to receive
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_rrdy_msk)==0);
// read data from spi bus
led_val=iord_altera_avalon_spi_rxdata(spi_base);
// disable chip select of selected slave
iowr_altera_avalon_spi_control(spi_base,0x00);
// display data of memory address 0x0000f0 in led's
// if everything was ok, it is supposed to be 10101010
iowr_altera_avalon_pio_data(led_base,led_val);
return(0);
}
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does it freeze somewhere or does it execute all the code?
I suggest to put some signaltap probes on the SPI signals and check the differences on the resulting signals when you use your version and the driver. It will help you find where the difference comes from.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
First of all, many thanks for your reply Daixiwen and I am sorry for my delay to answer. I have got an oscilloscope and could see the spi signals. The mistake must make in this reception part of my code. This part is:
// last byte of spi memory address
// wait to transmit
wdata=0xf0;
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
////////////// wait the end of transmission //////////////
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
// wait to receive
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_rrdy_msk)==0);
// clean data
iord_altera_avalon_spi_rxdata(spi_base);
iowr_altera_avalon_spi_status(spi_base,0x00);
////// dummy bite to read the spi memory ifnormation
// wait to transmit
wdata=0x00;
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_trdy_msk)==0);
// send data
iowr_altera_avalon_spi_txdata(spi_base,wdata);
// wait the end of transmission
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_tmt_msk)==0);
// wait to receive
while ((iord_altera_avalon_spi_status(spi_base) & altera_avalon_spi_status_rrdy_msk)==0);
// read data
led_val=iord_altera_avalon_spi_rxdata(spi_base);
iowr_altera_avalon_spi_status(spi_base,0x00);
//disable cs
iowr_altera_avalon_spi_control(spi_base,~altera_avalon_spi_control_sso_msk);
usleep(25);
// display data
iowr_altera_avalon_pio_data(led_base,led_val);
The problem is when I send to the spi memory the last byte of the address which I want to read (emphasized in bold). The MOSI signal appears in the oscilloscopi such as I expected. By contrast, the MISO signal is not working when the spi memory, in principle, is sending the data of the desired address (0x0000F0). I have already checked the hardware connection several time, so I think the mistake must be by software. I would be very grateful if anyone could give a piece of advice about my problem. Many thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But it does work with the standard driver, doesn't it? Are you sure all the signals are the same between the two runs? Check especially the timing between the clock signal and the chip select and MOSI.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First of all, thank you for your reply.
The code works well, the problem was that the spi memory was not working... It is natural my driver did not receive anything. I used other device and everything worked perfect. Anyway, thank you for your interest to help me :o- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- First of all, thank you for your reply. The code works well, the problem was that the spi memory was not working... It is natural my driver did not receive anything. I used other device and everything worked perfect. Anyway, thank you for your interest to help me :o --- Quote End --- Can you share your original implementation when you used the alt_avalon_spi_command function? There isn't a lot of help on how to use this function properly. Thanks in advance.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page