When attempting to read and write to a qspi chip on my C10GX board, writes do not seem to be working properly (assuming the reads are working properly). I am using the Generic QUAD SPI Controller II Intel FPGA IP, and have been able to boot my NIOS application from it to show that it is working properly. The problems arise when I am trying to read and write data to the qspi device.
For example, when writing 0x55 to the first page of NOR Flash memory (256 bytes), I get the following result when reading back the values:
And when writing 0xAA to the second page of NOR Flash memory, I get the following result when reading back the values:
here's my code I'm using for this test, which works fine on a NIOS II application with a spi flash chip:
int flash_check(void) {
printf("starting flash test\r\n");
const unsigned int pageSize = 256;
int flag = 0;
struct flash_region *flash_info = {0, 0, 0, 0};
alt_flash_fd* fd;
fd = alt_flash_open_dev(GENERIC_QUAD_SPI_CONTROLLER2_0_AVL_MEM_NAME); // from system.h
if (fd == NULL) {
printf("Flash initialization failed!\r\n");
return 1;
}
char retdata[pageSize];
int retval = 0;
printf("erasing memory\r\n");
retval = alt_qspi_controller2_erase_block(fd, 0);
if (retval != 0) {
printf("NOR Flash could not be erased.\r\n");
flag = 1;
}
int num_regions = 0;
retval = alt_qspi_controller2_get_info(fd, &flash_info, &num_regions);
printf("retval=%d\r\n", retval);
printf("num_regions=%d\r\n", num_regions);
printf("flash region offset: 0x%0x\r\n", flash_info->offset);
printf("flash region size: 0x%0x\r\n", flash_info->region_size);
printf("flash region number of blocks: 0x%0x\r\n", flash_info->number_of_blocks);
printf("flash region block size: 0x%0x\r\n\r\n", flash_info->block_size);
printf("setting memory to 0x55 from 0x%08x - 0x%08x\r\n", 0, pageSize-1);
memset(retdata, (char)0x55, pageSize);
retval = alt_qspi_controller2_write_block(fd, 0, 0, retdata, pageSize);
if (retval != 0) {
printf("Could not write to flash memory.\r\n");
flag = 1;
}
printf("setting memory to 0xaa from 0x%08x - 0x%08x\r\n", pageSize, pageSize*2-1);
memset(retdata, (char)0xaa, pageSize);
retval = alt_qspi_controller2_write_block(fd, 0, pageSize, retdata, pageSize);
if (retval != 0) {
printf("Could not write to flash memory.\r\n");
flag = 1;
}
printf("reading memory 0x%08x - 0x%08x\r\n", 0, pageSize-1);
retval = (int) alt_qspi_controller2_read(fd, 0, retdata, pageSize);
for (unsigned int i = 0; i < pageSize; i++) {
if ((retdata[i] & 0xFF) != 0x55) {
printf("index: %d\tread value: 0x%02x\texpected value: 0x%02x\n\r", i, retdata[i] & 0xFF, 0x55);
flag = 1;
} else {
printf("index: %d\tgot expected result!\r\n", i);
}
}
printf("reading memory 0x%08x - 0x%08x\r\n", pageSize, pageSize*2-1);
retval = (int) alt_qspi_controller2_read(fd, pageSize, retdata, pageSize);
for (unsigned int i = 0; i < pageSize; i++) {
if ((retdata[i] & 0xFF) != 0xaa) {
printf("index: %d\tread value: 0x%02x\texpected value: 0x%02x\n\r", i, retdata[i] & 0xFF, 0xaa);
flag = 1;
} else {
printf("index: %d\tgot expected result!\r\n", i);
}
}
// erase the memory so the NOR Flash is empty for the customer
printf("erasing memory\r\n");
retval = alt_qspi_controller2_erase_block(fd, 0);
if (retval != 0) {
printf("Flash memory could not be erased.\r\n");
flag = 1;
}
return flag;
}
Other potentially useful information:
NOR Flash part number: MT25QU256ABA8E12-1SIT
Active serial clock is set to internal 50 MHz oscillator under device and pin options
QSYS params for Generic QUAD SPI Controller II Intel FPGA IP:
- Disable dedicated active serial interface is not checked
- Enable SPI pins interface is checked
- Enable flash simulation model is not checked
- Configuration device type is set to MT25QU256
- Choose I/O mode is set to QUAD
- Number of chip selects used is set to 1 (there are no other devices hooked up to to qspi bus)