#define LUT0(opcode, pads, operand) (FLEXSPI_LUT_INSTRUCTION((opcode), (pads), (operand)))
#define LUT1(opcode, pads, operand) (FLEXSPI_LUT_INSTRUCTION((opcode), (pads), (operand)) << 16)
#define CMD_SDR FLEXSPI_LUT_OPCODE_CMD_SDR
#define ADDR_SDR FLEXSPI_LUT_OPCODE_RADDR_SDR
#define READ_SDR FLEXSPI_LUT_OPCODE_READ_SDR
#define WRITE_SDR FLEXSPI_LUT_OPCODE_WRITE_SDR
#define DUMMY_SDR FLEXSPI_LUT_OPCODE_DUMMY_SDR
#define PINS1 FLEXSPI_LUT_NUM_PADS_1
#define PINS4 FLEXSPI_LUT_NUM_PADS_4
// Config/status register addresses
#define W25N01G_PROT_REG 0xA0
#define W25N01G_CONF_REG 0xB0
#define W25N01G_STAT_REG 0xC0
[COLOR="#FF0000"]static const uint32_t flashBaseAddr = 0x01000000u;[/COLOR]
static const uint32_t eramBaseAddr = 0x07000000u;
static char flashID[4];
void setup(){
Serial.begin(115200);
delay(1000);
Serial.println("Begin Init");
memset(flashID, 0, sizeof(flashID));
FLEXSPI2_FLSHA2CR0 = 128u * 1024u * 1024u; //Flash Size in KByte, 1F400
FLEXSPI2_FLSHA2CR1 = FLEXSPI_FLSHCR1_CSINTERVAL(2) //minimum interval between flash device Chip selection deassertion and flash device Chip selection assertion.
| FLEXSPI_FLSHCR1_TCSH(3) //Serial Flash CS Hold time.
| FLEXSPI_FLSHCR1_TCSS(3); //Serial Flash CS setup time
FLEXSPI2_FLSHA2CR2 = FLEXSPI_FLSHCR2_AWRSEQID(6) //Sequence Index for AHB Write triggered Command
| FLEXSPI_FLSHCR2_AWRSEQNUM(0) //Sequence Number for AHB Read triggered Command in LUT.
| FLEXSPI_FLSHCR2_ARDSEQID(5) //Sequence Index for AHB Read triggered Command in LUT
| FLEXSPI_FLSHCR2_ARDSEQNUM(0); //Sequence Number for AHB Read triggered Command in LUT.
[COLOR="#FF0000"] // cmd index 7 = read ID bytes
//Serial.println("LUT28: JDEC");
FLEXSPI2_LUT28 = LUT0(CMD_SDR, PINS1, 0x9F) ; //9fh Read JDEC
FLEXSPI2_LUT29 = LUT0(DUMMY_SDR, PINS1, 8) | LUT0(READ_SDR, PINS1, 1);[/COLOR]
[COLOR="#FF0000"] // cmd index 8 = read Status register #1 SPI
FLEXSPI2_LUT32 = LUT0(CMD_SDR, PINS1, 0x05)
| LUT1(CMD_SDR, PINS1, W25N01G_STAT_REG); //5h Status Register, sr addr 0xC0
FLEXSPI2_LUT33 = LUT0(READ_SDR, PINS1, 1);[/COLOR]
// cmd index 9 = read Status register #2 SPI
//FLEXSPI2_LUT36 = LUT0(CMD_SDR, PINS1, 0x35)
// | LUT1(READ_SDR, PINS1, 1); //There is no status reg #2
//cmd index 10 = exit QPI mode
//FLEXSPI2_LUT40 = LUT0(CMD_SDR, PINS4, 0xFF);
//cmd index 11 = write enable QPI
//FLEXSPI2_LUT44 = LUT0(CMD_SDR, PINS4, 0x06);
//cmd index 12 = sector erase
///FLEXSPI2_LUT48 = LUT0(CMD_SDR, PINS4, 0x20)
//| LUT1(ADDR_SDR, PINS4, 24);
//cmd index 13 = page program
//FLEXSPI2_LUT52 = LUT0(CMD_SDR, PINS4, 0x02)
//| LUT1(ADDR_SDR, PINS4, 24);
//FLEXSPI2_LUT53 = LUT0(WRITE_SDR, PINS4, 1);
//cmd index 14 = set read parameters
//FLEXSPI2_LUT56 = LUT0(CMD_SDR, PINS4, 0xc0)
//| LUT1(CMD_SDR, PINS4, 0x20);
//cmd index 15 = enter QPI mode
//FLEXSPI2_LUT60 = LUT0(CMD_SDR, PINS1, 0x38);
// reset the chip
flexspi_ip_command(2, flashBaseAddr); //reset
delayMicroseconds(150);
Serial.println(); Serial.println("Status after Reset (S/B 0):");
printStatusRegs();
Serial.print("FLASH ID:");
flexspi_ip_read(7, flashBaseAddr, flashID, sizeof(flashID) ); // flash begins at offset 0x01000000
for (unsigned i = 0; i < sizeof(flashID); i++) Serial.printf(" %02X", flashID[i]);
Serial.printf("\n");
Serial.printf("at 0x %x\n", flashBaseAddr);
flexspi2_flash_id(flashBaseAddr);
}
void loop(){}
void flexspi_ip_read(uint32_t index, uint32_t addr, void *data, uint32_t length)
{
uint32_t n;
uint8_t *p = (uint8_t *)data;
const uint8_t *src;
FLEXSPI2_IPCR0 = addr;
FLEXSPI2_IPCR1 = FLEXSPI_IPCR1_ISEQID(index) | FLEXSPI_IPCR1_IDATSZ(length);
FLEXSPI2_IPCMD = FLEXSPI_IPCMD_TRG;
while (!((n = FLEXSPI2_INTR) & FLEXSPI_INTR_IPCMDDONE)) {
if (n & FLEXSPI_INTR_IPRXWA) {
//Serial.print("*");
if (length >= 8) {
length -= 8;
*(uint32_t *)(p+0) = FLEXSPI2_RFDR0;
*(uint32_t *)(p+4) = FLEXSPI2_RFDR1;
p += 8;
} else {
src = (const uint8_t *)&FLEXSPI2_RFDR0;
while (length > 0) {
length--;
*p++ = *src++;
}
}
FLEXSPI2_INTR = FLEXSPI_INTR_IPRXWA;
}
}
if (n & FLEXSPI_INTR_IPCMDERR) {
Serial.printf("Error: FLEXSPI2_IPRXFSTS=%08lX\r\n", FLEXSPI2_IPRXFSTS);
}
FLEXSPI2_INTR = FLEXSPI_INTR_IPCMDDONE;
Serial.printf(" FLEXSPI2_RFDR0=%08lX\r\n", FLEXSPI2_RFDR0);
if (length > 4) Serial.printf(" FLEXSPI2_RFDR1=%08lX\n", FLEXSPI2_RFDR1);
if (length > 8) Serial.printf(" FLEXSPI2_RFDR1=%08lX\n", FLEXSPI2_RFDR2);
if (length > 16) Serial.printf(" FLEXSPI2_RFDR1=%08lX\n", FLEXSPI2_RFDR3);
src = (const uint8_t *)&FLEXSPI2_RFDR0;
while (length > 0) {
*p++ = *src++;
length--;
}
if (FLEXSPI2_INTR & FLEXSPI_INTR_IPRXWA) FLEXSPI2_INTR = FLEXSPI_INTR_IPRXWA;
}
void printStatusRegs() {
#if 1
uint8_t val;
flexspi_ip_read(8, flashBaseAddr, &val, 1 );
Serial.print("Status 1:");
Serial.printf(" %02X", val);
Serial.printf("\n");
Serial.print("Binary: "); Serial.println(val, BIN);
Serial.println();
// cmd index 9 = read Status register #2 SPI
//flexspi_ip_read(9, flashBaseAddr[_spiffs_region], &val, 1 );
//Serial.print("Status 2:");
//Serial.printf(" %02X", val);
//Serial.printf("\n");
#endif
}
void flexspi_ip_command(uint32_t index, uint32_t addr)
{
uint32_t n;
FLEXSPI2_IPCR0 = addr;
FLEXSPI2_IPCR1 = FLEXSPI_IPCR1_ISEQID(index);
FLEXSPI2_IPCMD = FLEXSPI_IPCMD_TRG;
while (!((n = FLEXSPI2_INTR) & FLEXSPI_INTR_IPCMDDONE)); // wait
if (n & FLEXSPI_INTR_IPCMDERR) {
Serial.printf("Error: FLEXSPI2_IPRXFSTS=%08lX\n", FLEXSPI2_IPRXFSTS);
}
FLEXSPI2_INTR = FLEXSPI_INTR_IPCMDDONE;
}
FLASHMEM static uint32_t flexspi2_flash_id(uint32_t addr)
{
FLEXSPI2_IPCR0 = addr;
FLEXSPI2_IPCR1 = FLEXSPI_IPCR1_ISEQID(7) | FLEXSPI_IPCR1_IDATSZ(4);
FLEXSPI2_IPCMD = FLEXSPI_IPCMD_TRG;
while (!(FLEXSPI2_INTR & FLEXSPI_INTR_IPCMDDONE)); // wait
uint32_t id = FLEXSPI2_RFDR0;
FLEXSPI2_INTR = FLEXSPI_INTR_IPCMDDONE | FLEXSPI_INTR_IPRXWA;
Serial.println();
Serial.print("FLASH ID2: "); Serial.println(id , HEX);
return 0;
}