File indexing completed on 2025-05-11 08:23:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <rtems.h>
0027 #include <stdint.h>
0028
0029 #include <dev/spi/zynq-qspi-flash-defs.h>
0030
0031
0032
0033
0034
0035 rtems_id transfer_task;
0036
0037 __attribute__((weak)) void zqspi_write_unlock(zqspiflash *driver)
0038 {
0039 }
0040
0041 __attribute__((weak)) void zqspi_write_lock(zqspiflash *driver)
0042 {
0043 }
0044
0045 static void qspi_flash_rx(void) {
0046 while (true) {
0047 if (
0048 (qspi_reg_read(ZQSPI_QSPI_REG_INTR_STATUS) &
0049 ZQSPI_QSPI_IXR_RXNEMPTY) == 0
0050 )
0051 {
0052 break;
0053 }
0054 qspi_reg_read(ZQSPI_QSPI_REG_RX_DATA);
0055 }
0056 }
0057
0058 zqspi_error zqspi_transfer(
0059 zqspi_transfer_buffer* transfer,
0060 bool *initialised
0061 )
0062 {
0063 uint32_t tx_reg;
0064 uint32_t sr;
0065 rtems_status_code sc;
0066 transfer_task = rtems_task_self();
0067
0068 if (*initialised == false)
0069 {
0070 qspi_reg_write(ZQSPI_QSPI_REG_EN, 0);
0071 qspi_reg_write(ZQSPI_QSPI_REG_LSPI_CFG, 0x00a002eb);
0072 qspi_flash_rx();
0073 qspi_reg_write(
0074 ZQSPI_QSPI_REG_CONFIG,
0075 ZQSPI_QSPI_CR_SSFORCE | ZQSPI_QSPI_CR_MANSTRTEN | ZQSPI_QSPI_CR_HOLDB_DR |
0076 ZQSPI_QSPI_CR_BAUD_RATE | ZQSPI_QSPI_CR_MODE_SEL
0077 );
0078 *initialised = true;
0079 }
0080
0081 zqspi_transfer_trace("transfer:TX", transfer);
0082
0083
0084
0085
0086 qspi_reg_write(ZQSPI_QSPI_REG_CONFIG,
0087 qspi_reg_read(ZQSPI_QSPI_REG_CONFIG) & ~ZQSPI_QSPI_CR_PCS);
0088
0089
0090
0091
0092 qspi_reg_write(ZQSPI_QSPI_REG_EN, ZQSPI_QSPI_EN_SPI_ENABLE);
0093
0094
0095
0096
0097 transfer->tx_data = (uint32_t*) transfer->buffer;
0098 transfer->rx_data = (uint32_t*) transfer->buffer;
0099 transfer->tx_length = transfer->length;
0100 transfer->rx_length = transfer->length;
0101
0102
0103
0104
0105
0106
0107
0108 switch (transfer->padding)
0109 {
0110 case 3:
0111 *(transfer->tx_data) >>= 24;
0112 tx_reg = ZQSPI_QSPI_REG_TXD1;
0113 transfer->tx_length -= 1;
0114 transfer->sending += 1;
0115 transfer->start = true;
0116 break;
0117 case 2:
0118 *(transfer->tx_data) >>= 16;
0119 tx_reg = ZQSPI_QSPI_REG_TXD2;
0120 transfer->tx_length -= 2;
0121 transfer->sending += 2;
0122 transfer->start = true;
0123 break;
0124 case 1:
0125 *(transfer->tx_data) >>= 8;
0126 tx_reg = ZQSPI_QSPI_REG_TXD3;
0127 transfer->tx_length -= 3;
0128 transfer->sending += 3;
0129 transfer->start = true;
0130 break;
0131 default:
0132 tx_reg = ZQSPI_QSPI_REG_TXD0;
0133 transfer->tx_length -= 4;
0134 transfer->sending += 4;
0135 if (transfer->tx_length == 0)
0136 transfer->start = true;
0137 break;
0138 }
0139
0140 qspi_reg_write (tx_reg, *(transfer->tx_data));
0141 ++(transfer->tx_data);
0142
0143 if (transfer->start)
0144 {
0145 qspi_reg_write(ZQSPI_QSPI_REG_CONFIG,
0146 qspi_reg_read(ZQSPI_QSPI_REG_CONFIG) | ZQSPI_QSPI_CR_MANSTRT);
0147
0148 sr = qspi_reg_read(ZQSPI_QSPI_REG_INTR_STATUS);
0149 while ((sr & ZQSPI_QSPI_IXR_TXOW) == 0)
0150 {
0151 sr = qspi_reg_read(ZQSPI_QSPI_REG_INTR_STATUS);
0152 }
0153 }
0154
0155
0156 qspi_reg_write(ZQSPI_QSPI_REG_INTR_DISABLE,
0157 ~(ZQSPI_QSPI_IXR_RXNEMPTY | ZQSPI_QSPI_IXR_TXUF));
0158 qspi_reg_write(ZQSPI_QSPI_REG_INTR_ENABLE,
0159 (ZQSPI_QSPI_IXR_RXNEMPTY | ZQSPI_QSPI_IXR_TXUF));
0160
0161
0162 sc = rtems_event_transient_receive(RTEMS_WAIT, ZQSPI_TIMEOUT_TICKS);
0163 if (sc != RTEMS_SUCCESSFUL) {
0164 rtems_event_transient_clear();
0165 return ZQPSI_FLASH_TRANSFER_FAILED;
0166 }
0167
0168
0169
0170
0171 zqspi_transfer_buffer_skip(transfer, 1);
0172
0173
0174
0175
0176 qspi_reg_write(ZQSPI_QSPI_REG_CONFIG,
0177 qspi_reg_read(ZQSPI_QSPI_REG_CONFIG) | ZQSPI_QSPI_CR_PCS);
0178
0179
0180
0181
0182 qspi_reg_write(ZQSPI_QSPI_REG_EN, 0);
0183
0184 zqspi_transfer_trace("transfer:RX", transfer);
0185
0186 return ZQSPI_FLASH_NO_ERROR;
0187 }
0188
0189 void zqspi_transfer_intr(zqspiflash *driver)
0190 {
0191 uint32_t sr;
0192 zqspi_transfer_buffer* transfer = &(driver->buf);
0193
0194
0195 qspi_reg_write(ZQSPI_QSPI_REG_INTR_DISABLE, 0xFFFFFFFF);
0196 qspi_reg_write(ZQSPI_QSPI_REG_INTR_STATUS, 0xFFFFFFFF);
0197 sr = qspi_reg_read(ZQSPI_QSPI_REG_INTR_STATUS);
0198
0199 if (transfer->rx_length)
0200 {
0201 while (transfer->start && transfer->sending)
0202 {
0203 if ((sr & ZQSPI_QSPI_IXR_RXNEMPTY) != 0)
0204 {
0205 *(transfer->rx_data) = qspi_reg_read(ZQSPI_QSPI_REG_RX_DATA);
0206 ++(transfer->rx_data);
0207 if (transfer->rx_length > sizeof(uint32_t)) {
0208 transfer->rx_length -= sizeof(uint32_t);
0209 } else {
0210 transfer->rx_length = 0;
0211 }
0212 if (transfer->sending > sizeof(uint32_t)) {
0213 transfer->sending -= sizeof(uint32_t);
0214 } else {
0215 transfer->sending = 0;
0216 }
0217 }
0218
0219 sr = qspi_reg_read(ZQSPI_QSPI_REG_INTR_STATUS);
0220 }
0221 }
0222
0223 if (transfer->tx_length)
0224 {
0225 transfer->start = false;
0226 while (transfer->tx_length && ((sr & ZQSPI_QSPI_IXR_TXFULL) == 0))
0227 {
0228 qspi_reg_write (ZQSPI_QSPI_REG_TXD0, *(transfer->tx_data));
0229 ++(transfer->tx_data);
0230 if (transfer->tx_length > sizeof(uint32_t)) {
0231 transfer->tx_length -= sizeof(uint32_t);
0232 } else {
0233 transfer->tx_length = 0;
0234 }
0235 transfer->sending += sizeof(uint32_t);
0236 transfer->start = true;
0237
0238 sr = qspi_reg_read(ZQSPI_QSPI_REG_INTR_STATUS);
0239 }
0240
0241 if (transfer->start)
0242 {
0243 qspi_reg_write(ZQSPI_QSPI_REG_CONFIG,
0244 qspi_reg_read(ZQSPI_QSPI_REG_CONFIG) | ZQSPI_QSPI_CR_MANSTRT);
0245 }
0246 }
0247
0248 if (transfer->tx_length) {
0249 qspi_reg_write(ZQSPI_QSPI_REG_INTR_ENABLE,
0250 qspi_reg_read(ZQSPI_QSPI_REG_INTR_ENABLE) | ZQSPI_QSPI_IXR_TXUF);
0251 }
0252 if (transfer->rx_length) {
0253 qspi_reg_write(ZQSPI_QSPI_REG_INTR_ENABLE,
0254 qspi_reg_read(ZQSPI_QSPI_REG_INTR_ENABLE) | ZQSPI_QSPI_IXR_RXNEMPTY);
0255 }
0256 if (transfer->tx_length == 0 && transfer->rx_length == 0) {
0257 (void) rtems_event_transient_send(transfer_task);
0258 }
0259 }