| 
 | 1 | +/* mbed Microcontroller Library  | 
 | 2 | + * Copyright (c) 2018-2018 ARM Limited  | 
 | 3 | + *  | 
 | 4 | + * Licensed under the Apache License, Version 2.0 (the "License");  | 
 | 5 | + * you may not use this file except in compliance with the License.  | 
 | 6 | + * You may obtain a copy of the License at  | 
 | 7 | + *  | 
 | 8 | + *     http://www.apache.org/licenses/LICENSE-2.0  | 
 | 9 | + *  | 
 | 10 | + * Unless required by applicable law or agreed to in writing, software  | 
 | 11 | + * distributed under the License is distributed on an "AS IS" BASIS,  | 
 | 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  | 
 | 13 | + * See the License for the specific language governing permissions and  | 
 | 14 | + * limitations under the License.  | 
 | 15 | + */  | 
 | 16 | +#ifndef MBED_QSPI_FLASH_W25Q32JV_H  | 
 | 17 | +#define MBED_QSPI_FLASH_W25Q32JV_H  | 
 | 18 | + | 
 | 19 | + | 
 | 20 | +#define QSPI_FLASH_CHIP_STRING "Winbond W25Q32JV"  | 
 | 21 | + | 
 | 22 | +// Command for reading status register  | 
 | 23 | +#define QSPI_CMD_RDSR                           0x05  | 
 | 24 | +// Command for reading configuration register  | 
 | 25 | +#define QSPI_CMD_RDCR0                          0x35  | 
 | 26 | +#define QSPI_CMD_RDCR1                          0x15  | 
 | 27 | +// Command for writing status/configuration register  | 
 | 28 | +#define QSPI_CMD_WRSR                           0x01  | 
 | 29 | +// Command for writing configuration register  | 
 | 30 | +#define QSPI_CMD_WRCR0                          0x31  | 
 | 31 | +#define QSPI_CMD_WRCR1                          0x11  | 
 | 32 | +// Command for reading security register  | 
 | 33 | +#define QSPI_CMD_RDSCUR                         0x48  | 
 | 34 | + | 
 | 35 | +// Command for setting Reset Enable  | 
 | 36 | +#define QSPI_CMD_RSTEN                          0x66  | 
 | 37 | +// Command for setting Reset  | 
 | 38 | +#define QSPI_CMD_RST                            0x99  | 
 | 39 | + | 
 | 40 | +// Command for setting write enable  | 
 | 41 | +#define QSPI_CMD_WREN                           0x06  | 
 | 42 | +// Command for setting write disable  | 
 | 43 | +#define QSPI_CMD_WRDI                           0x04  | 
 | 44 | + | 
 | 45 | +// WRSR operations max time [us] (datasheet max time + 15%)  | 
 | 46 | +#define QSPI_WRSR_MAX_TIME                      34500   // 30ms  | 
 | 47 | +// general wait max time [us]  | 
 | 48 | +#define QSPI_WAIT_MAX_TIME                      100000  // 100ms  | 
 | 49 | + | 
 | 50 | + | 
 | 51 | +// Commands for writing (page programming)  | 
 | 52 | +#define QSPI_CMD_WRITE_1IO                      0x02    // 1-1-1 mode  | 
 | 53 | + | 
 | 54 | +// write operations max time [us] (datasheet max time + 15%)  | 
 | 55 | +#define QSPI_PAGE_PROG_MAX_TIME                 11500   // 10ms  | 
 | 56 | + | 
 | 57 | +#define QSPI_PAGE_SIZE                          256     // 256B  | 
 | 58 | +#define QSPI_SECTOR_SIZE                        4096    // 4kB  | 
 | 59 | +#define QSPI_SECTOR_COUNT                       1024  | 
 | 60 | + | 
 | 61 | +// Commands for reading  | 
 | 62 | +#define QSPI_CMD_READ_1IO_FAST                  0x0B   // 1-1-1 mode  | 
 | 63 | +#define QSPI_CMD_READ_1IO                       0x03   // 1-1-1 mode  | 
 | 64 | +#define QSPI_CMD_READ_2IO                       0xBB   // 1-2-2 mode  | 
 | 65 | +#define QSPI_CMD_READ_1I2O                      0x3B   // 1-1-2 mode  | 
 | 66 | +#define QSPI_CMD_READ_4IO                       0xEB   // 1-4-4 mode  | 
 | 67 | +#define QSPI_CMD_READ_1I4O                      0x6B   // 1-1-4 mode  | 
 | 68 | + | 
 | 69 | +#define QSPI_READ_1IO_DUMMY_CYCLE               0  | 
 | 70 | +#define QSPI_READ_FAST_DUMMY_CYCLE              8  | 
 | 71 | +#define QSPI_READ_2IO_DUMMY_CYCLE               4  | 
 | 72 | +#define QSPI_READ_1I2O_DUMMY_CYCLE              8  | 
 | 73 | +#define QSPI_READ_4IO_DUMMY_CYCLE               6  | 
 | 74 | +#define QSPI_READ_1I4O_DUMMY_CYCLE              8  | 
 | 75 | + | 
 | 76 | +// Commands for erasing  | 
 | 77 | +#define QSPI_CMD_ERASE_SECTOR                   0x20    // 4kB  | 
 | 78 | +#define QSPI_CMD_ERASE_BLOCK_32                 0x52    // 32kB  | 
 | 79 | +#define QSPI_CMD_ERASE_BLOCK_64                 0xD8    // 64kB  | 
 | 80 | +#define QSPI_CMD_ERASE_CHIP                     0x60    // or 0xC7  | 
 | 81 | + | 
 | 82 | +// erase operations max time [us] (datasheet max time + 15%)  | 
 | 83 | +#define QSPI_ERASE_SECTOR_MAX_TIME              480000      // 400 ms  | 
 | 84 | +#define QSPI_ERASE_BLOCK_32_MAX_TIME            3450000     // 3s  | 
 | 85 | +#define QSPI_ERASE_BLOCK_64_MAX_TIME            4025000     // 3.5s  | 
 | 86 | + | 
 | 87 | +// max frequency for basic rw operation (for fast mode)  | 
 | 88 | +#define QSPI_COMMON_MAX_FREQUENCY               32000000  | 
 | 89 | + | 
 | 90 | +#define QSPI_STATUS_REG_SIZE                    1  | 
 | 91 | +#define QSPI_CONFIG_REG_0_SIZE                  1  | 
 | 92 | +#define QSPI_CONFIG_REG_1_SIZE                  1  | 
 | 93 | + | 
 | 94 | +#define QSPI_SECURITY_REG_SIZE                  1  | 
 | 95 | +#define QSPI_MAX_REG_SIZE                       1  | 
 | 96 | + | 
 | 97 | +// status register  | 
 | 98 | +#define STATUS_BIT_WIP   (1 << 0)   // write in progress bit  | 
 | 99 | +#define STATUS_BIT_WEL   (1 << 1)   // write enable latch  | 
 | 100 | +#define STATUS_BIT_BP0   (1 << 2)   // block protect 0  | 
 | 101 | +#define STATUS_BIT_BP1   (1 << 3)   // block protect 1  | 
 | 102 | +#define STATUS_BIT_BP2   (1 << 4)   // block protect 2  | 
 | 103 | +#define STATUS_BIT_BP_TB (1 << 5)   // block protect top/bottom  | 
 | 104 | +#define STATUS_BIT_SP    (1 << 6)   // sector protect  | 
 | 105 | +#define STATUS_BIT_SRWD  (1 << 7)   // status register protect  | 
 | 106 | + | 
 | 107 | +// configuration register 0  | 
 | 108 | +// bit 2 reserved  | 
 | 109 | +#define CONFIG0_BIT_SRL  (1 << 0)   // status register lock  | 
 | 110 | +#define CONFIG0_BIT_QE   (1 << 1)   // quad enable  | 
 | 111 | +#define CONFIG0_BIT_LB1  (1 << 3)   // security register lock 1  | 
 | 112 | +#define CONFIG0_BIT_LB2  (1 << 4)   // security register lock 2  | 
 | 113 | +#define CONFIG0_BIT_LB3  (1 << 5)   // security register lock 3  | 
 | 114 | +#define CONFIG0_BIT_CMP  (1 << 6)   // complement protect  | 
 | 115 | +#define CONFIG0_BIT_SUS  (1 << 7)   // suspend status  | 
 | 116 | + | 
 | 117 | +// configuration register 1  | 
 | 118 | +// bits 0, 1, 3, 4, 7 reserved  | 
 | 119 | +#define CONFIG1_BIT_WPS  (1 << 2)   // write protect selection  | 
 | 120 | +#define CONFIG1_BIT_DRV2 (1 << 5)   // output driver strength 2  | 
 | 121 | +#define CONFIG1_BIT_DRV1 (1 << 6)   // output driver strength 1  | 
 | 122 | + | 
 | 123 | + | 
 | 124 | + | 
 | 125 | +#define QUAD_ENABLE()                                                           \  | 
 | 126 | +                                                                                \  | 
 | 127 | +    uint8_t reg_data[QSPI_CONFIG_REG_0_SIZE];                                   \  | 
 | 128 | +                                                                                \  | 
 | 129 | +    memset(reg_data, 0, QSPI_CONFIG_REG_0_SIZE);                                \  | 
 | 130 | +    if (read_register(QSPI_CMD_RDCR0, reg_data,                                 \  | 
 | 131 | +            QSPI_CONFIG_REG_0_SIZE, qspi) != QSPI_STATUS_OK) {                  \  | 
 | 132 | +        return QSPI_STATUS_ERROR;                                               \  | 
 | 133 | +    }                                                                           \  | 
 | 134 | +    if (write_enable(qspi) != QSPI_STATUS_OK) {                                 \  | 
 | 135 | +        return QSPI_STATUS_ERROR;                                               \  | 
 | 136 | +    }                                                                           \  | 
 | 137 | +                                                                                \  | 
 | 138 | +    reg_data[0] = reg_data[0] & ~(CONFIG0_BIT_QE);                              \  | 
 | 139 | +    if (write_register(QSPI_CMD_WRCR0, reg_data,                                \  | 
 | 140 | +            QSPI_CONFIG_REG_0_SIZE, qspi) != QSPI_STATUS_OK) {                  \  | 
 | 141 | +        return QSPI_STATUS_ERROR;                                               \  | 
 | 142 | +    }                                                                           \  | 
 | 143 | +    qspi.cmd.configure(MODE_4_4_4, ADDR_SIZE_24, ALT_SIZE_8);                   \  | 
 | 144 | +    WAIT_FOR(WRSR_MAX_TIME, qspi);                                              \  | 
 | 145 | +    memset(reg_data, 0, QSPI_CONFIG_REG_0_SIZE);                                \  | 
 | 146 | +    if (read_register(QSPI_CMD_RDCR0, reg_data,                                 \  | 
 | 147 | +            QSPI_CONFIG_REG_0_SIZE, qspi) != QSPI_STATUS_OK) {                  \  | 
 | 148 | +        return QSPI_STATUS_ERROR;                                               \  | 
 | 149 | +    }                                                                           \  | 
 | 150 | +                                                                                \  | 
 | 151 | +    return ((reg_data[0] & (CONFIG0_BIT_QE)) == 0 ?                             \  | 
 | 152 | +                QSPI_STATUS_OK : QSPI_STATUS_ERROR)  | 
 | 153 | + | 
 | 154 | + | 
 | 155 | +#define QUAD_DISABLE()                                                          \  | 
 | 156 | +                                                                                \  | 
 | 157 | +    uint8_t reg_data[QSPI_CONFIG_REG_0_SIZE];                                   \  | 
 | 158 | +                                                                                \  | 
 | 159 | +    memset(reg_data, 0, QSPI_CONFIG_REG_0_SIZE);                                \  | 
 | 160 | +    if (read_register(QSPI_CMD_RDCR0, reg_data,                                 \  | 
 | 161 | +            QSPI_CONFIG_REG_0_SIZE, qspi) != QSPI_STATUS_OK) {                  \  | 
 | 162 | +        return QSPI_STATUS_ERROR;                                               \  | 
 | 163 | +    }                                                                           \  | 
 | 164 | +    if (write_enable(qspi) != QSPI_STATUS_OK) {                                 \  | 
 | 165 | +        return QSPI_STATUS_ERROR;                                               \  | 
 | 166 | +    }                                                                           \  | 
 | 167 | +                                                                                \  | 
 | 168 | +    reg_data[0] = reg_data[0] | (CONFIG0_BIT_QE);                               \  | 
 | 169 | +    if (write_register(QSPI_CMD_WRCR0, reg_data,                                \  | 
 | 170 | +            QSPI_CONFIG_REG_0_SIZE, qspi) != QSPI_STATUS_OK) {                  \  | 
 | 171 | +        return QSPI_STATUS_ERROR;                                               \  | 
 | 172 | +    }                                                                           \  | 
 | 173 | +    WAIT_FOR(WRSR_MAX_TIME, qspi);                                              \  | 
 | 174 | +    qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);                   \  | 
 | 175 | +    memset(reg_data, 0, QSPI_CONFIG_REG_0_SIZE);                                \  | 
 | 176 | +    if (read_register(QSPI_CMD_RDCR0, reg_data,                                 \  | 
 | 177 | +            QSPI_CONFIG_REG_0_SIZE, qspi) != QSPI_STATUS_OK) {                  \  | 
 | 178 | +        return QSPI_STATUS_ERROR;                                               \  | 
 | 179 | +    }                                                                           \  | 
 | 180 | +                                                                                \  | 
 | 181 | +    return ((reg_data[0] & CONFIG0_BIT_QE) != 1 ?                               \  | 
 | 182 | +                QSPI_STATUS_OK : QSPI_STATUS_ERROR)  | 
 | 183 | + | 
 | 184 | +#endif // MBED_QSPI_FLASH_W25Q32JV_H  | 
0 commit comments