Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:39

0001 /*
0002  * Copyright (C) 2024 Contemporary Software
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  * 1. Redistributions of source code must retain the above copyright
0008  *    notice, this list of conditions and the following disclaimer.
0009  * 2. Redistributions in binary form must reproduce the above copyright
0010  *    notice, this list of conditions and the following disclaimer in the
0011  *    documentation and/or other materials provided with the distribution.
0012  *
0013  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
0014  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0015  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0016  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0017  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0018  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0019  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0020  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0021  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0022  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0023  * POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #include <rtems.h>
0027 #include <string.h>
0028 #include <unistd.h>
0029 #include <stdio.h>
0030 #include <stdint.h>
0031 
0032 #include <dev/spi/zynq-qspi-flash.h>
0033 #include <dev/spi/zynq-qspi-flash-defs.h>
0034 #include <dev/spi/jedec_flash.h>
0035 
0036 /*
0037  * Debug tracing.
0038  */
0039 #define ZQSPI_FLASH_TRACE_TRANSFER 0
0040 
0041 #if ZQSPI_FLASH_TRACE_TRANSFER
0042 static bool zqspi_trace = 1;
0043 #endif
0044 
0045 #if ZQSPI_FLASH_TRACE_TRANSFER
0046 static void zqspi_transfer_trace_header(
0047   const char* message,
0048   const zqspi_transfer_buffer* transfer
0049 )
0050 {
0051   if (zqspi_trace)
0052     printf(" %s: length=%ld in=%ld out=%ld padding=%ld\n",
0053          message, transfer->length, transfer->in,
0054          transfer->out, transfer->padding);
0055 }
0056 #endif
0057 
0058 void zqspi_transfer_trace(
0059   const char* message,
0060   const zqspi_transfer_buffer* transfer
0061 )
0062 {
0063 #if ZQSPI_FLASH_TRACE_TRANSFER
0064   if (zqspi_trace)
0065   {
0066     size_t c;
0067     zqspi_transferTraceHeader(message, transfer);
0068     for (c = 0; c < transfer->length; ++c)
0069     {
0070       if ((c % 16) == 0)
0071       {
0072         if (c)
0073           printf("\n");
0074         printf("  %04lx ", c);
0075       }
0076       printf("%02x", transfer->buffer[c + transfer->padding]);
0077       if ((c % 16) == 7)
0078         printf("-");
0079       else
0080         printf(" ");
0081     }
0082     printf("\n");
0083   }
0084 #endif
0085 }
0086 
0087 void qspi_reg_write(uint32_t reg, uint32_t value)
0088 {
0089   volatile uint32_t* ap = (uint32_t*)(ZQSPI_QSPI_BASE + reg);
0090   *ap = value;
0091 }
0092 
0093 uint32_t qspi_reg_read(uint32_t reg)
0094 {
0095   volatile uint32_t* ap = (uint32_t*)(ZQSPI_QSPI_BASE + reg);
0096   return *ap;
0097 }
0098 
0099 static inline uint8_t zqspi_get8(const uint8_t* data)
0100 {
0101   return *data;
0102 }
0103 
0104 static inline uint16_t zqspi_get16(const uint8_t* data)
0105 {
0106   return (((uint16_t) data[1]) << 8) | data[0];
0107 }
0108 
0109 static void zqspi_transfer_buffer_clear(zqspi_transfer_buffer* transfer)
0110 {
0111   transfer->length = 0;
0112   transfer->padding = 0;
0113   transfer->in = 0;
0114   transfer->out = 0;
0115 }
0116 
0117 static void zqspi_transfer_buffer_set_length(
0118   zqspi_transfer_buffer* transfer,
0119   size_t length
0120 )
0121 {
0122   transfer->length = length;
0123   transfer->padding = (4 - (length & 3)) & 3;
0124   transfer->in = transfer->padding;
0125   transfer->out = transfer->padding;
0126 }
0127 
0128 static zqspi_error zqspi_transfer_buffer_fill(
0129   zqspi_transfer_buffer* transfer,
0130   const uint8_t data,
0131   size_t length
0132 )
0133 {
0134   if ((transfer->in + length) >= transfer->size) {
0135     return ZQSPI_FLASH_BUFFER_OVERFLOW;
0136   }
0137 
0138   memset(transfer->buffer + transfer->in, data, length);
0139 
0140   transfer->in += length;
0141 
0142   return ZQSPI_FLASH_NO_ERROR;
0143 }
0144 
0145 static zqspi_error zqspi_transfer_buffer_set8(
0146   zqspi_transfer_buffer* transfer,
0147   const uint8_t data
0148 )
0149 {
0150   if (transfer->in >= transfer->size) {
0151     return ZQSPI_FLASH_BUFFER_OVERFLOW;
0152   }
0153 
0154   volatile uint8_t* p = &transfer->buffer[transfer->in++];
0155   *p = data;
0156 
0157   return ZQSPI_FLASH_NO_ERROR;
0158 }
0159 
0160 zqspi_error zqspi_transfer_buffer_skip(
0161   zqspi_transfer_buffer* transfer,
0162   const size_t size
0163 )
0164 {
0165   if ((transfer->length - (transfer->out - transfer->padding)) < size) {
0166     return ZQSPI_FLASH_BUFFER_UNDERFLOW;
0167   }
0168 
0169   transfer->out += size;
0170   return ZQSPI_FLASH_NO_ERROR;
0171 }
0172 
0173 static zqspi_error zqspi_transfer_buffer_get8(
0174   zqspi_transfer_buffer* transfer,
0175   uint8_t* data
0176 )
0177 {
0178   if ((transfer->length - (transfer->out - transfer->padding)) <
0179         sizeof(uint8_t)) {
0180     return ZQSPI_FLASH_BUFFER_UNDERFLOW;
0181   }
0182 
0183   *data = transfer->buffer[transfer->out++];
0184 
0185   return ZQSPI_FLASH_NO_ERROR;
0186 }
0187 
0188 static zqspi_error zqspi_transfer_buffer_get16(
0189   zqspi_transfer_buffer* transfer,
0190   uint16_t* data
0191 )
0192 {
0193   if ((transfer->length - (transfer->out - transfer->padding)) <
0194         sizeof(uint16_t)) {
0195     return ZQSPI_FLASH_BUFFER_UNDERFLOW;
0196   }
0197 
0198   *data = ((uint16_t) transfer->buffer[transfer->out++]) << 8;
0199   *data |= transfer->buffer[transfer->out++];
0200 
0201   return ZQSPI_FLASH_NO_ERROR;
0202 }
0203 
0204 static zqspi_error zqspi_transfer_buffer_copy_out(
0205   zqspi_transfer_buffer* transfer,
0206   uint8_t* data,
0207   const size_t length
0208 )
0209 {
0210   if ((transfer->length - (transfer->out - transfer->padding)) < length) {
0211     return ZQSPI_FLASH_BUFFER_UNDERFLOW;
0212   }
0213   memcpy(data, transfer->buffer + transfer->out, length);
0214   transfer->out += length;
0215 
0216   return ZQSPI_FLASH_NO_ERROR;
0217 }
0218 
0219 static zqspi_error zqspi_transfer_buffer_copy_in(
0220   zqspi_transfer_buffer* transfer,
0221   const uint8_t* data,
0222   const size_t length
0223 )
0224 {
0225   if ((transfer->in + length) > transfer->size) {
0226     return ZQSPI_FLASH_BUFFER_OVERFLOW;
0227   }
0228 
0229   memcpy(transfer->buffer + transfer->in, data, length);
0230   transfer->in += length;
0231 
0232   return ZQSPI_FLASH_NO_ERROR;
0233 }
0234 
0235 static void zqspi_transfer_buffer_set_addr(
0236   zqspi_transfer_buffer* transfer,
0237   uint32_t address
0238 )
0239 {
0240 #if ZQSPI_FLASH_4BYTE_ADDRESSING
0241   zqspi_transfer_buffer_set8(transfer, (address >> 24) & 0xff);
0242 #endif
0243   zqspi_transfer_buffer_set8(transfer, (address >> 16) & 0xff);
0244   zqspi_transfer_buffer_set8(transfer, (address >> 8) & 0xff);
0245   zqspi_transfer_buffer_set8(transfer, address & 0xff);
0246 }
0247 
0248 static void zqspi_transfer_buffer_set_dir(
0249   zqspi_transfer_buffer* transfer,
0250   int trans_dir
0251 )
0252 {
0253   transfer->trans_dir = trans_dir;
0254 }
0255 
0256 static void zqspi_transfer_buffer_set_command_len(
0257   zqspi_transfer_buffer* transfer,
0258   int comm_len
0259 )
0260 {
0261   transfer->command_len = comm_len;
0262 }
0263 
0264 static zqspi_error zqspi_read_register(
0265   zqspiflash *driver,
0266   uint8_t reg,
0267   uint16_t* value
0268 )
0269 {
0270   zqspi_error fe;
0271 
0272   zqspi_transfer_buffer_clear(&driver->buf);
0273   zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE + 2);
0274   zqspi_transfer_buffer_set8(&driver->buf, reg);
0275   zqspi_transfer_buffer_set8(&driver->buf, 0);
0276   zqspi_transfer_buffer_set8(&driver->buf, 0);
0277   zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
0278   zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0279 
0280   fe = zqspi_transfer(&driver->buf, &driver->initialised);
0281   if (fe != ZQSPI_FLASH_NO_ERROR)
0282     return fe;
0283 
0284   zqspi_transfer_buffer_get16(&driver->buf, value);
0285 
0286   return ZQSPI_FLASH_NO_ERROR;
0287 }
0288 
0289 static zqspi_error zqspi_wait_for_write(zqspiflash *driver, uint32_t wait)
0290 {
0291   uint16_t status;
0292   zqspi_error fe;
0293   uint32_t checks = 100;
0294 
0295   while (true) {
0296     fe = zqspi_read_register(driver, ZQSPI_FLASH_READ_STATUS_FLAG_CMD, &status);
0297     if (fe != ZQSPI_FLASH_NO_ERROR) {
0298       return fe;
0299     }
0300 
0301     status = status & 0xFF;
0302 
0303     if ((status & ZQSPI_FLASH_SR_E_ERR) != 0) {
0304       return ZQSPI_FLASH_ERASE_FAILURE;
0305     }
0306 
0307     /*
0308      * A succuessful write requires the write latch and the write in
0309      * progress have cleared. If the write in progress is not set yet the
0310      * write latch remains set it is an error and the write command was not
0311      * received the flash device.
0312      */
0313     fe = zqspi_read_register(driver, ZQSPI_FLASH_READ_STATUS_CMD, &status);
0314     status = status & 0xFF;
0315     if (fe != ZQSPI_FLASH_NO_ERROR) {
0316       return fe;
0317     }
0318 
0319     if ((status & ZQSPI_FLASH_SR_WIP) == 0)
0320     {
0321       if ((status & ZQSPI_FLASH_SR_WEL) == 0) {
0322         break;
0323       }
0324       if (checks == 0) {
0325         return ZQSPI_FLASH_WRITE_ERASE_CMD_FAIL;
0326       }
0327       --checks;
0328     }
0329 
0330     if (wait) {
0331       usleep(wait);
0332     }
0333   }
0334   return ZQSPI_FLASH_NO_ERROR;
0335 }
0336 
0337 static zqspi_error zqspi_set_WEL(zqspiflash *driver)
0338 {
0339   uint16_t status;
0340   zqspi_error fe;
0341 
0342   zqspi_transfer_buffer_clear(&driver->buf);
0343   zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0344   zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_WRITE_ENABLE_CMD);
0345   zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0346   zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0347 
0348   fe = zqspi_transfer(&driver->buf, &driver->initialised);
0349   if (fe != ZQSPI_FLASH_NO_ERROR) {
0350     return fe;
0351   }
0352 
0353   fe = zqspi_read_register(driver, ZQSPI_FLASH_READ_STATUS_CMD, &status);
0354   if (fe != ZQSPI_FLASH_NO_ERROR) {
0355     return fe;
0356   }
0357 
0358   if ((status & ZQSPI_FLASH_SR_WEL) == 0) {
0359     return ZQSPI_FLASH_READ_ONLY;
0360   }
0361 
0362   return ZQSPI_FLASH_NO_ERROR;
0363 }
0364 
0365 static zqspi_error zqspi_clear_WEL(zqspiflash *driver) {
0366   uint16_t status;
0367   zqspi_error fe;
0368 
0369   zqspi_transfer_buffer_clear(&driver->buf);
0370   zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0371   zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_WRITE_DISABLE_CMD);
0372   zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0373   zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0374 
0375   fe = zqspi_transfer(&driver->buf, &driver->initialised);
0376   if (fe != ZQSPI_FLASH_NO_ERROR) {
0377     return fe;
0378   }
0379 
0380   fe = zqspi_read_register(driver, ZQSPI_FLASH_READ_STATUS_CMD, &status);
0381   if (fe != ZQSPI_FLASH_NO_ERROR) {
0382     return fe;
0383   }
0384 
0385   if ((status & ZQSPI_FLASH_SR_WEL) != 0) {
0386     return ZQSPI_FLASH_WRITE_LATCH_CLEAR_FAIL;
0387   }
0388 
0389   return ZQSPI_FLASH_NO_ERROR;
0390 }
0391 
0392 zqspi_error zqspi_read(
0393   zqspiflash *driver,
0394   uint32_t address,
0395   void* buffer,
0396   size_t length
0397 )
0398 {
0399   uint8_t* data = buffer;
0400 
0401   while (length)
0402   {
0403     zqspi_error fe;
0404     size_t    size;
0405 
0406     if (driver->flash_page_size == 0) {
0407       return ZQSPI_FLASH_INVALID_DEVICE;
0408     }
0409     size = length > driver->flash_page_size ? driver->flash_page_size : length;
0410 
0411     zqspi_transfer_buffer_clear(&driver->buf);
0412     zqspi_transfer_buffer_set_length(
0413       &driver->buf,
0414       ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE +
0415         driver->flash_read_dummies + size
0416     );
0417     zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_READ_CMD);
0418     zqspi_transfer_buffer_set_addr(&driver->buf, address);
0419     fe = zqspi_transfer_buffer_fill(&driver->buf, 0,
0420            driver->flash_read_dummies + size);
0421     if (fe != ZQSPI_FLASH_NO_ERROR) {
0422       return fe;
0423     }
0424     zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
0425     zqspi_transfer_buffer_set_command_len(&driver->buf,
0426         ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE +
0427         driver->flash_read_dummies);
0428 
0429     fe = zqspi_transfer(&driver->buf, &driver->initialised);
0430     if (fe != ZQSPI_FLASH_NO_ERROR) {
0431       return fe;
0432     }
0433 
0434     zqspi_transfer_buffer_skip(&driver->buf,
0435       ZQSPI_FLASH_ADDRESS_SIZE + driver->flash_read_dummies);
0436 
0437     fe = zqspi_transfer_buffer_copy_out(&driver->buf, data, size);
0438     if (fe != ZQSPI_FLASH_NO_ERROR) {
0439       return fe;
0440     }
0441 
0442     length -= size;
0443     data += size;
0444     address += size;
0445   }
0446 
0447   return ZQSPI_FLASH_NO_ERROR;
0448 }
0449 
0450 zqspi_error zqspi_blank(zqspiflash *driver, uint32_t address, size_t length)
0451 {
0452   zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0453 
0454   if (
0455     (address >= driver->flash_size) ||
0456     ((address + length) > driver->flash_size)
0457   )
0458   {
0459     return ZQSPI_FLASH_BAD_ADDRESS;
0460   }
0461 
0462   while (length)
0463   {
0464     size_t    size;
0465 
0466     if (driver->flash_page_size == 0) {
0467       return ZQSPI_FLASH_INVALID_DEVICE;
0468     }
0469     size = length > driver->flash_page_size ? driver->flash_page_size : length;
0470 
0471     zqspi_transfer_buffer_clear(&driver->buf);
0472     zqspi_transfer_buffer_set_length(&driver->buf,
0473                      ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE
0474                      + driver->flash_read_dummies + size);
0475     zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_READ_CMD);
0476     zqspi_transfer_buffer_set_addr(&driver->buf, address);
0477     fe = zqspi_transfer_buffer_fill(&driver->buf, 0,
0478       driver->flash_read_dummies + size);
0479     if (fe != ZQSPI_FLASH_NO_ERROR) {
0480       return fe;
0481     }
0482     zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
0483     zqspi_transfer_buffer_set_command_len(&driver->buf,
0484       ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE
0485       + driver->flash_read_dummies);
0486 
0487     fe = zqspi_transfer(&driver->buf, &driver->initialised);
0488     if (fe != ZQSPI_FLASH_NO_ERROR) {
0489       return fe;
0490     }
0491 
0492     zqspi_transfer_buffer_skip(&driver->buf, ZQSPI_FLASH_ADDRESS_SIZE);
0493 
0494     length -= size;
0495     address += size;
0496 
0497     while (size) {
0498       uint8_t byte = 0;
0499       zqspi_transfer_buffer_get8(&driver->buf, &byte);
0500       if (byte != 0xff) {
0501         return ZQSPI_FLASH_NOT_BLANK;
0502       }
0503       --size;
0504     }
0505   }
0506 
0507   return fe;
0508 }
0509 
0510 zqspi_error zqspi_erase(zqspiflash *driver, uint32_t address, size_t length)
0511 {
0512   zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0513   bool done = false;
0514 
0515   if (
0516     (address >= driver->flash_size) ||
0517     ((address + length) > driver->flash_size)
0518   ) {
0519     return ZQSPI_FLASH_BAD_ADDRESS;
0520   }
0521   if (driver->flash_page_size == 0) {
0522     return ZQSPI_FLASH_INVALID_DEVICE;
0523   }
0524 
0525   while (!done) {
0526     fe = zqspi_erase_sector(driver,
0527            (address - (address%(driver->flash_erase_sector_size))));
0528     if (fe != ZQSPI_FLASH_NO_ERROR) {
0529       return fe;
0530     }
0531 
0532     if (length <= driver->flash_erase_sector_size) {
0533       done = true;
0534     } else {
0535       address += driver->flash_erase_sector_size;
0536       length -= driver->flash_erase_sector_size;
0537     }
0538   }
0539   return fe;
0540 }
0541 
0542 zqspi_error zqspi_erase_sector(zqspiflash *driver, uint32_t address)
0543 {
0544   zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0545   uint32_t base = 0;
0546   size_t length = 0;
0547 
0548   if (
0549     (address >= driver->flash_size) ||
0550     ((address + length) > driver->flash_size)
0551   )
0552   {
0553     return ZQSPI_FLASH_BAD_ADDRESS;
0554   }
0555 
0556   zqspi_write_unlock(driver);
0557 
0558   fe = zqspi_set_WEL(driver);
0559   if (fe != ZQSPI_FLASH_NO_ERROR)
0560   {
0561     zqspi_write_lock(driver);
0562     return fe;
0563   }
0564 
0565   zqspi_transfer_buffer_clear(&driver->buf);
0566   zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE
0567     + ZQSPI_FLASH_ADDRESS_SIZE);
0568   zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_SEC_ERASE_CMD);
0569   zqspi_transfer_buffer_set_addr(&driver->buf, address);
0570   zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0571   zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE
0572     + ZQSPI_FLASH_ADDRESS_SIZE);
0573 
0574   fe = zqspi_transfer(&driver->buf, &driver->initialised);
0575   if (fe != ZQSPI_FLASH_NO_ERROR)
0576   {
0577     zqspi_clear_WEL(driver);
0578     zqspi_write_lock(driver);
0579     return fe;
0580   }
0581 
0582   fe = zqspi_wait_for_write(driver, 1000);
0583   if (fe != ZQSPI_FLASH_NO_ERROR)
0584   {
0585     zqspi_clear_WEL(driver);
0586     zqspi_write_lock(driver);
0587     return fe;
0588   }
0589 
0590   zqspi_write_lock(driver);
0591 
0592   fe = zqspi_blank(driver, base, length);
0593   if (fe != ZQSPI_FLASH_NO_ERROR)
0594     return fe;
0595 
0596   return fe;
0597 }
0598 
0599 zqspi_error zqspi_erase_device(zqspiflash *driver)
0600 {
0601   zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0602 
0603   zqspi_write_unlock(driver);
0604 
0605   fe = zqspi_set_WEL(driver);
0606   if (fe != ZQSPI_FLASH_NO_ERROR)
0607   {
0608     zqspi_write_lock(driver);
0609     return fe;
0610   }
0611 
0612   zqspi_transfer_buffer_clear(&driver->buf);
0613   zqspi_transfer_buffer_set_length(&driver->buf, 1);
0614   zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_BULK_ERASE_CMD);
0615   zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0616   zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE);
0617 
0618   fe = zqspi_transfer(&driver->buf, &driver->initialised);
0619   if (fe != ZQSPI_FLASH_NO_ERROR)
0620   {
0621     zqspi_clear_WEL(driver);
0622     zqspi_write_lock(driver);
0623     return fe;
0624   }
0625 
0626   fe = zqspi_wait_for_write(driver, 1000000);
0627   if (fe != ZQSPI_FLASH_NO_ERROR)
0628   {
0629     zqspi_clear_WEL(driver);
0630     zqspi_write_lock(driver);
0631     return fe;
0632   }
0633 
0634   zqspi_write_lock(driver);
0635 
0636   return fe;
0637 }
0638 
0639 zqspi_error zqspi_write(
0640   zqspiflash *driver,
0641   uint32_t address,
0642   const void* buffer,
0643   size_t length
0644 )
0645 {
0646   zqspi_error fe = ZQSPI_FLASH_NO_ERROR;
0647   const uint8_t* data = buffer;
0648   size_t size;
0649   size_t byte;
0650   bool write_block = false;
0651 
0652   if (
0653     (address >= driver->flash_size) ||
0654     ((address + length) > driver->flash_size)
0655   )
0656   {
0657     return ZQSPI_FLASH_BAD_ADDRESS;
0658   }
0659 
0660   zqspi_write_unlock(driver);
0661 
0662   while (length) {
0663     if (driver->flash_page_size == 0) {
0664       return ZQSPI_FLASH_INVALID_DEVICE;
0665     }
0666     size = length > driver->flash_page_size ? driver->flash_page_size : length;
0667 
0668     /*
0669      * If the address is not aligned to the start of a page transfer
0670      * the remainder of the page so the address is aligned.
0671      */
0672     if ((address % driver->flash_page_size) != 0)
0673     {
0674       size_t remaining = driver->flash_page_size
0675         - (address % driver->flash_page_size);
0676       if (size > remaining)
0677         size = remaining;
0678     }
0679 
0680     /*
0681      * If the block is blank do not write it.
0682      */
0683     for (byte = 0; byte < size; ++byte)
0684     {
0685       if (data[byte] != 0xff)
0686       {
0687         write_block = true;
0688         break;
0689       }
0690     }
0691 
0692     if (write_block)
0693     {
0694       fe = zqspi_set_WEL(driver);
0695       if (fe != ZQSPI_FLASH_NO_ERROR)
0696       {
0697         zqspi_write_lock(driver);
0698         return fe;
0699       }
0700 
0701       zqspi_transfer_buffer_clear(&driver->buf);
0702       zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE
0703           + ZQSPI_FLASH_ADDRESS_SIZE + size);
0704       zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_WRITE_CMD);
0705       zqspi_transfer_buffer_set_addr(&driver->buf, address);
0706       zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
0707       zqspi_transfer_buffer_set_command_len(&driver->buf,
0708         ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE);
0709       fe = zqspi_transfer_buffer_copy_in(&driver->buf, data, size);
0710       if (fe != ZQSPI_FLASH_NO_ERROR)
0711       {
0712         zqspi_write_lock(driver);
0713         return fe;
0714       }
0715 
0716       fe = zqspi_transfer(&driver->buf, &driver->initialised);
0717       if (fe != ZQSPI_FLASH_NO_ERROR)
0718       {
0719         zqspi_clear_WEL(driver);
0720         zqspi_write_lock(driver);
0721         return fe;
0722       }
0723 
0724       fe = zqspi_wait_for_write(driver, 1000);
0725       if (fe != ZQSPI_FLASH_NO_ERROR)
0726       {
0727         zqspi_clear_WEL(driver);
0728         zqspi_write_lock(driver);
0729         return fe;
0730       }
0731     }
0732 
0733     address += size;
0734     data += size;
0735     length -= size;
0736   }
0737 
0738   zqspi_write_lock(driver);
0739 
0740   return fe;
0741 }
0742 
0743 zqspi_error zqspi_readid(zqspiflash *driver, uint32_t *jedec_id)
0744 {
0745   zqspi_error fe;
0746   uint8_t value = 0;
0747   int index = 0;
0748 
0749   if (driver->jedec_id != 0) {
0750     if (jedec_id != NULL) {
0751       *jedec_id = driver->jedec_id;
0752     }
0753     return ZQSPI_FLASH_NO_ERROR;
0754   }
0755 
0756   zqspi_transfer_buffer_clear(&driver->buf);
0757   zqspi_transfer_buffer_set_length(&driver->buf, 1 + 3);
0758   zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_READ_ID);
0759   zqspi_transfer_buffer_fill(&driver->buf, 0x00, 3);
0760   zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
0761   zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE);
0762 
0763   fe = zqspi_transfer(&driver->buf, &driver->initialised);
0764   if (fe != ZQSPI_FLASH_NO_ERROR)
0765     return fe;
0766 
0767   zqspi_transfer_buffer_get8(&driver->buf, &value);
0768   driver->jedec_id |= value << 16;
0769   zqspi_transfer_buffer_get8(&driver->buf, &value);
0770   driver->jedec_id |= value << 8;
0771   zqspi_transfer_buffer_get8(&driver->buf, &value);
0772   driver->jedec_id |= value;
0773 
0774   if (jedec_id != NULL) {
0775     *jedec_id = driver->jedec_id;
0776   }
0777 
0778   while (flash_dev_table[index].jedec_id != driver->jedec_id) {
0779     if (flash_dev_table[index].jedec_id == 0) {
0780       return ZQSPI_FLASH_INVALID_DEVICE;
0781     }
0782     index++;
0783   }
0784   driver->flash_size = flash_dev_table[index].flash_size;
0785   driver->flash_erase_sector_size = flash_dev_table[index].sec_size;
0786   driver->flash_page_size = flash_dev_table[index].page_size;
0787 #if ZQSPI_FLASH_FAST_READ
0788   driver->flash_read_dummies = 1;
0789 #endif
0790 
0791   return ZQSPI_FLASH_NO_ERROR;
0792 }
0793 
0794 size_t zqspi_device_size(zqspiflash *driver)
0795 {
0796   return driver->flash_size;
0797 }
0798 
0799 size_t zqspi_device_sector_erase_size(zqspiflash *driver)
0800 {
0801   return driver->flash_erase_sector_size;
0802 }
0803 
0804 zqspi_error zqspi_init(zqspiflash *driver)
0805 {
0806   rtems_status_code sc;
0807   uint8_t *zqspizqspi_buf = calloc(1, ZQSPI_FLASH_BUFFER_SIZE);
0808 
0809   driver->buf.size = ZQSPI_FLASH_BUFFER_SIZE;
0810   driver->buf.length = 0;
0811   driver->buf.padding = 0;
0812   driver->buf.in = 0;
0813   driver->buf.out = 0;
0814   driver->buf.trans_dir = 0;
0815   driver->buf.command_len = 0;
0816   driver->buf.buffer = zqspizqspi_buf;
0817   driver->buf.tx_data = NULL;
0818   driver->buf.rx_data = NULL;
0819   driver->buf.tx_length = 0;
0820   driver->buf.rx_length = 0;
0821   driver->buf.sending = 0;
0822   driver->buf.start = false;
0823   driver->initialised = false;
0824   driver->jedec_id = 0;
0825   driver->flash_size = 0;
0826   driver->flash_read_dummies = 0;
0827   driver->flash_erase_sector_size = 0;
0828   driver->flash_page_size = 0;
0829 
0830   sc = rtems_interrupt_handler_install(
0831     ZQPSI_ZYNQ_QSPI_IRQ,
0832     NULL,
0833     RTEMS_INTERRUPT_UNIQUE,
0834     (rtems_interrupt_handler) zqspi_transfer_intr,
0835     driver
0836   );
0837   if (sc != RTEMS_SUCCESSFUL) {
0838     free(driver->buf.buffer);
0839     return ZQSPI_FLASH_RTEMS_INTR;
0840   }
0841 
0842   return zqspi_readid(driver, NULL);
0843 }
0844 
0845 void zqspi_close(zqspiflash *driver)
0846 {
0847   free(driver->buf.buffer);
0848 }