Hello everyone. I’m trying to communicate to a FLASH Memory (W25Q64) via SPI, but it won’t work. I’ve tried with multiple modules.
I’m sending a message of four bytes (90h;00;00;00) to which the module should answer with its manufacturer/device ID in 2 bytes.
This is the code I’m using. I’m not able to check with an oscilloscope given that I haven’t got one.
int main (void)
{
set_freq_320MHz();
uint16_t sckdiv;
sckdiv = cpu_freq / (2 * 80000) - 1;
GPIO_REG(GPIO_IOF_EN) |= (1 << GPIO_SPI1_MISO);
GPIO_REG(GPIO_IOF_SEL) &= ~(1 << GPIO_SPI1_MISO);
GPIO_REG(GPIO_IOF_EN) |= (1 << GPIO_SPI1_MOSI);
GPIO_REG(GPIO_IOF_SEL) &= ~(1 << GPIO_SPI1_MOSI);
GPIO_REG(GPIO_IOF_EN) |= (1 << GPIO_SPI1_SCK);
GPIO_REG(GPIO_IOF_SEL) &= ~(1 << GPIO_SPI1_SCK);
GPIO_REG(GPIO_IOF_EN) |= (1 << GPIO_SPI1_SS0);
GPIO_REG(GPIO_IOF_SEL) &= ~(1 << GPIO_SPI1_SS0);
GPIO_REG(GPIO_IOF_EN) |= (1 << 2);
GPIO_REG(GPIO_IOF_SEL) &= ~(1 << 2);
SPI1_REG(SPI_REG_CSDEF) = 0xFFFFFFFFUL;
SPI1_REG(SPI_REG_CSID) = 0;
SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
uint8_t instr[8] = {0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t recv[2];
SPI1_REG(SPI_REG_CSDEF) &= ~(1 << 0);
for(int i = 0; i < 4; i++) {
while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL)
{
asm volatile("nop");
}
SPI1_REG(SPI_REG_TXFIFO) = instr[i];
while (SPI1_REG(SPI_REG_RXFIFO) <= 0xFF)
;
}
unsigned long data;
for(int i = 0; i < 2; i++) {
while (1) {
data = SPI1_REG(SPI_REG_RXFIFO); // Read the RX register EXACTLY once
if (data <= 0xFF) {
break;
}
}
recv[i] = (char) (data & 0xFF);
}
SPI1_REG(SPI_REG_CSDEF) |= (1 << 0);
while (1)
{
}
return 0;
}
EDIT:
The amount of data received before the RXFIFO becomes empty is exactly of the amount requested.
E.g. Request Manufacturer/Device ID, 2 bytes (0x00) received
Power Up Device, 0 bytes received, as per datasheet
But this happens only if I detach the CS from hardware control and pull high/low the relevant GPIO pin. If it is in HW control, using HOLD, it receives nothing.