Write NOP register 00ABCD
------- read NOP register 80ABCD
------- read NOP register 800000
------- read NOP register 800000
why?Error?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
Each read cycle requires two command,
1. read command access ; set read register address
2. dummy read cycle ; read back data from previous set address
In your case getting data 2nd and 3rd read NOP is expected .
1. Write NOP with register address to be read back
2. Issue read NOP to get data.
Hope it will clarify your doubts.
FPGA Nios II
SPI Mode 1
SPI CLk 1MHZ
//------------------Write to NOP ---------------
addr = 0x00;
data = 0xabcd;
isWrite = 1;
ret = pkgCmd(addr, data, isWrite);
printf("写NOP寄存器 %06X\n", (unsigned int)ret);
tx_data_array[0] = ret;
rx_data_array[0] = 0x000000;
SPI_OLED_WR(tx_data_array, rx_data_array, len);
//--------------------Read From NOP--------------
isWrite = 0;
addr = 0x00; //地址
ret = pkgCmd(addr, data, isWrite);
tx_data_array[0] = ret;
rx_data_array[0] = 0x000000;
SPI_OLED_WR(tx_data_array, rx_data_array, len);
SPI_OLED_WR(tx_data_array, rx_data_array, len);
printf("------- 读 NOP 寄存器 %06X\n", (unsigned int) (rx_data_array[0]));
/**
* SPIWrite Func
*/
void SPI_OLED_WR(alt_u32* tx_data, alt_u32* rx_data, int len) {
wifi_spi_command_pc(SPI_CTRL_CARD_BASE, 0, len, tx_data, len, rx_data, 0);
/*alt_avalon_spi_command(SPI_CTRL_CARD_BASE, 0,
len, tx_data, len, rx_data, 0);*/
}
;
//Pkg CMD
alt_u32 pkgCmd(alt_u8 addr, alt_u16 data, int isWrite) {
alt_u32 ret = 0x000000;
ret = (addr << 16) | data; //8 + 16 = 24位
if (isWrite == 1) {
//写操作 最高位置0
ret = ret & 0x7fffff;
} else {
//读操作 最高位置1 1000 0000 ff ff ff ff
ret = ret | 0x800000;
}
return ret;
};
//----------------------------------spi func-----------------------------------------------------------
/******************************************************************************
* *
* License Agreement *
* author: pc
* pcjiushizhu@qq.com
******************************************************************************/
#include "alt_types.h"
#include "wifi_spi_base.h"
#include "altera_avalon_spi_regs.h"
#include "altera_avalon_pio_regs.h"
#include "io.h"
#include "system.h"
#include <unistd.h> // usleep()
#define READ_NOW
#define DELAY 1
int wifi_spi_command_pc(alt_u32 base, alt_u32 slave,
alt_u32 write_length, alt_u32 * write_data,
alt_u32 read_length, alt_u32 * read_data,
alt_u32 flags)
{
const alt_u32 * write_end = write_data + write_length;
alt_u32 status;
/* Warning: this function is not currently safe if called in a multi-threaded
* environment, something above must perform locking to make it safe if more
* than one thread intends to use it.
*/
IOWR_ALTERA_AVALON_SPI_SLAVE_SEL(base, 1 << slave);
/* Set the SSO bit (force chipselect) only if the toggle flag is not set */
if ((flags & ALT_AVALON_SPI_COMMAND_TOGGLE_SS_N) == 0) {
IOWR_ALTERA_AVALON_SPI_CONTROL(base, ALTERA_AVALON_SPI_CONTROL_SSO_MSK);
}
//2016.5.5,增加同步操作,同步线操作,拉高同步头,主程序没有改。
IOWR(PIO_SYNC_BASE,0, 0x01);
/*
* Discard any stale data present in the RXDATA register, in case
* previous communication was interrupted and stale data was left
* behind.清空rx
*/
IORD_32DIRECT(base,0);
/* Keep clocking until all the data has been processed. */
for (;;) {
//------------发送数据 --------------
do {
status = IORD_8DIRECT(base,8); //读SPI的status寄存器
} while ((status & 0x40) != 0x40); //TRDY=1表示txdata寄存器空,可以发起新的一次写入,TRDY=0则等待
{
if (write_data < write_end) {
IOWR_32DIRECT(base,4,(*write_data));
write_data++;
}
}
// usleep(10); //如果优化级别高了,就需要延时了。
//------------紧接着接收数据------------
do {
status = IORD_8DIRECT(base,8); //读SPI的status寄存器
} while ((status & 0x80) != 0x80); //RRDY=1表示rxdata寄存器满,可供读取,RRDY=0则等待
{
alt_u32 rxdata = IORD_32DIRECT(base,0);
(*read_data) = rxdata;
read_data++;
if (write_data == write_end)
break;
}
// usleep(10);//如果优化级别高了,就需要延时了。
}
/* Wait until the interface has finished transmitting */
do
{
status = IORD_ALTERA_AVALON_SPI_STATUS(base);
}
while ((status & ALTERA_AVALON_SPI_STATUS_TMT_MSK) == 0);
/* Clear SSO (release chipselect) unless the caller is going to
* keep using this chip
*/
if ((flags & ALT_AVALON_SPI_COMMAND_MERGE) == 0){
// int i=1000, j=1000;
// for(i=1000;i>0;i--){
//// for(j=1000;j>0;j--){
//// ;
//// }
// }
IOWR_ALTERA_AVALON_SPI_CONTROL(base, 0);
// usleep(5);
}
//同步线操作,拉低同步头
IOWR(PIO_SYNC_BASE,0, 0x00);
return read_length;
}
1st read;
1. Write NOP with register address to be read back
//------------------Write to NOP ---------------
addr = 0x00;
data = 0xabcd;
isWrite = 1;
ret = pkgCmd(addr, data, isWrite);
printf("写NOP寄存器 %06X\n", (unsigned int)ret);
tx_data_array[0] = ret;
rx_data_array[0] = 0x000000;
SPI_OLED_WR(tx_data_array, rx_data_array, len);
2. dummy read cycle ; read back data from previous set address
//--------------------Read From NOP--------------
isWrite = 0;
addr = 0x00; //地址
ret = pkgCmd(addr, data, isWrite);
tx_data_array[0] = ret;
rx_data_array[0] = 0x000000;
SPI_OLED_WR(tx_data_array, rx_data_array, len);
SPI_OLED_WR(tx_data_array, rx_data_array, len);
printf("------- 读 NOP 寄存器 %06X\n", (unsigned int) (rx_data_array[0]));
2nd read;
repeat above step 1 & 2
3rd read;
repeat above step 1 & 2
please try above sequence in your code.
Thanks