1 #define SPIFLASH_READ_STATUS 0x05 // Read Status Register
2 #define SPIFLASH_BSY_BIT 0x00000001 // WIP Bit of SPI SR on SMI SR
5 #define FESPI_REG_FMT 0x40
6 #define FESPI_REG_TXFIFO 0x48
7 #define FESPI_REG_RXFIFO 0x4c
8 #define FESPI_REG_IP 0x74
11 #define FESPI_IP_TXWM 0x1
12 #define FESPI_FMT_DIR(x) (((x) & 0x1) << 3)
14 // To enter, jump to the start of command_table (ie. offset 0).
15 // a0 - FESPI base address
16 // a1 - start address of buffer
18 // The buffer contains a "program" in byte sequences. The first byte in a
19 // sequence determines the operation. Some operation will read more data from
20 // the program, while some will not. The operation byte is the offset into
21 // command_table, so eg. 4 means exit, 8 means transmit, and so on.
34 // Execute the program.
42 // Read 1 byte the contains the number of bytes to transmit. Then read those
43 // bytes from the program and transmit them one by one.
45 lbu t1, 0(a1) // read number of bytes to transmit
47 1: lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear
49 lbu t0, 0(a1) // Load byte to write
50 sw t0, FESPI_REG_TXFIFO(a0)
56 // Wait until TXWM is set.
58 1: lw t0, FESPI_REG_IP(a0)
59 andi t0, t0, FESPI_IP_TXWM
63 // Read 1 byte that contains the offset of the register to write, and 1 byte
64 // that contains the data to write.
66 lbu t0, 0(a1) // read register to write
68 lbu t1, 1(a1) // read value to write
74 li a2, SPIFLASH_READ_STATUS
76 // discard first result
79 andi t0, a2, SPIFLASH_BSY_BIT
83 txrx_byte: // transmit the byte in a2, receive a bit into a2
84 lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear
86 sw a2, FESPI_REG_TXFIFO(a0)
87 1: lw a2, FESPI_REG_RXFIFO(a0)
92 lw t0, FESPI_REG_FMT(a0)
93 li t1, ~(FESPI_FMT_DIR(0xFFFFFFFF))
95 lbu t1, 0(a1) // read value to OR in
98 sw t0, FESPI_REG_FMT(a0)