-
Notifications
You must be signed in to change notification settings - Fork 3k
Add QSPI #7783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add QSPI #7783
Changes from all commits
b3037af
510d743
4564383
10e7b5f
a3c8117
d1b51b6
2df58e2
009cc8b
219d0c6
16d121c
9deecac
10a6fd6
0f7cc36
d903686
04ec07c
cb4308a
273cf05
894f8bd
6274cd4
0612ab2
1557ce3
1d234aa
3db3364
910f1a8
b71f2a1
784c473
7da0ac2
5e75b39
11ae100
8da072d
6e5b889
551f044
660d250
2766672
16ca742
5038b38
fff2072
8783956
c778c90
99f2107
0f7fd75
ae7bb17
d282c81
4145316
d54bac2
05899e9
8e08740
8d2f426
c57a47e
2b234c2
0714ac3
50b8225
9b4b28f
293d1bd
c00e49f
2f06423
dd4e236
d444abc
1f4cc95
42935bb
67798d6
c2cc559
8b36d6b
4432737
de46a54
e5e05df
1534426
43258a8
5c26e15
893cf2a
7dda4e4
6095ccf
948d1a3
e692334
3bf9df7
c94f22c
ad49388
883ea2f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
/* mbed Microcontroller Library | ||
* Copyright (c) 2018-2018 ARM Limited | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
#ifndef MBED_QSPI_FLASH_MX25R6435F_H | ||
#define MBED_QSPI_FLASH_MX25R6435F_H | ||
|
||
|
||
#define QSPI_FLASH_CHIP_STRING "macronix MX25R6435F" | ||
|
||
// Command for reading status register | ||
#define QSPI_CMD_RDSR 0x05 | ||
// Command for reading configuration register | ||
#define QSPI_CMD_RDCR0 0x15 | ||
// Command for writing status/configuration register | ||
#define QSPI_CMD_WRSR 0x01 | ||
// Command for reading security register | ||
#define QSPI_CMD_RDSCUR 0x2B | ||
|
||
// Command for setting Reset Enable | ||
#define QSPI_CMD_RSTEN 0x66 | ||
// Command for setting Reset | ||
#define QSPI_CMD_RST 0x99 | ||
|
||
// Command for setting write enable | ||
#define QSPI_CMD_WREN 0x06 | ||
// Command for setting write disable | ||
#define QSPI_CMD_WRDI 0x04 | ||
|
||
// WRSR operations max time [us] (datasheet max time + 15%) | ||
#define QSPI_WRSR_MAX_TIME 34500 // 30ms | ||
// general wait max time [us] | ||
#define QSPI_WAIT_MAX_TIME 100000 // 100ms | ||
|
||
|
||
// Commands for writing (page programming) | ||
#define QSPI_CMD_WRITE_1IO 0x02 // 1-1-1 mode | ||
#define QSPI_CMD_WRITE_4IO 0x38 // 1-4-4 mode | ||
|
||
// write operations max time [us] (datasheet max time + 15%) | ||
#define QSPI_PAGE_PROG_MAX_TIME 11500 // 10ms | ||
|
||
#define QSPI_PAGE_SIZE 256 // 256B | ||
|
||
// Commands for reading | ||
#define QSPI_CMD_READ_1IO_FAST 0x0B // 1-1-1 mode | ||
#define QSPI_CMD_READ_1IO 0x03 // 1-1-1 mode | ||
#define QSPI_CMD_READ_2IO 0xBB // 1-2-2 mode | ||
#define QSPI_CMD_READ_1I2O 0x3B // 1-1-2 mode | ||
#define QSPI_CMD_READ_4IO 0xEB // 1-4-4 mode | ||
#define QSPI_CMD_READ_1I4O 0x6B // 1-1-4 mode | ||
|
||
#define QSPI_READ_1IO_DUMMY_CYCLE 0 | ||
#define QSPI_READ_FAST_DUMMY_CYCLE 8 | ||
#define QSPI_READ_2IO_DUMMY_CYCLE 4 | ||
#define QSPI_READ_1I2O_DUMMY_CYCLE 8 | ||
#define QSPI_READ_4IO_DUMMY_CYCLE 6 | ||
#define QSPI_READ_1I4O_DUMMY_CYCLE 8 | ||
|
||
// Commands for erasing | ||
#define QSPI_CMD_ERASE_SECTOR 0x20 // 4kB | ||
#define QSPI_CMD_ERASE_BLOCK_32 0x52 // 32kB | ||
#define QSPI_CMD_ERASE_BLOCK_64 0xD8 // 64kB | ||
#define QSPI_CMD_ERASE_CHIP 0x60 // or 0xC7 | ||
|
||
// erase operations max time [us] (datasheet max time + 15%) | ||
#define QSPI_ERASE_SECTOR_MAX_TIME 276000 // 240 ms | ||
#define QSPI_ERASE_BLOCK_32_MAX_TIME 3450000 // 3s | ||
#define QSPI_ERASE_BLOCK_64_MAX_TIME 4025000 // 3.5s | ||
|
||
// max frequency for basic rw operation | ||
#define QSPI_COMMON_MAX_FREQUENCY 32000000 | ||
|
||
#define QSPI_STATUS_REG_SIZE 1 | ||
#define QSPI_CONFIG_REG_0_SIZE 2 | ||
#define QSPI_SECURITY_REG_SIZE 1 | ||
#define QSPI_MAX_REG_SIZE 2 | ||
|
||
// status register | ||
#define STATUS_BIT_WIP (1 << 0) // write in progress bit | ||
#define STATUS_BIT_WEL (1 << 1) // write enable latch | ||
#define STATUS_BIT_BP0 (1 << 2) // | ||
#define STATUS_BIT_BP1 (1 << 3) // | ||
#define STATUS_BIT_BP2 (1 << 4) // | ||
#define STATUS_BIT_BP3 (1 << 5) // | ||
#define STATUS_BIT_QE (1 << 6) // Quad Enable | ||
#define STATUS_BIT_SRWD (1 << 7) // status register write protect | ||
|
||
// configuration register 0 | ||
// bit 0, 1, 2, 4, 5, 7 reserved | ||
#define CONFIG0_BIT_TB (1 << 3) // Top/Bottom area protect | ||
#define CONFIG0_BIT_DC (1 << 6) // Dummy Cycle | ||
|
||
// configuration register 1 | ||
// bit 0, 2, 3, 4, 5, 6, 7 reserved | ||
#define CONFIG1_BIT_LH (1 << 1) // 0 = Ultra Low power mode, 1 = High performance mode | ||
|
||
|
||
// single quad enable flag for both dual and quad mode | ||
#define QUAD_ENABLE() \ | ||
\ | ||
uint8_t reg_data[QSPI_STATUS_REG_SIZE]; \ | ||
\ | ||
if (write_enable(qspi) != QSPI_STATUS_OK) { \ | ||
return QSPI_STATUS_ERROR; \ | ||
} \ | ||
WAIT_FOR(WRSR_MAX_TIME, qspi); \ | ||
\ | ||
reg_data[0] = STATUS_BIT_QE; \ | ||
qspi.cmd.build(QSPI_CMD_WRSR); \ | ||
\ | ||
if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), \ | ||
reg_data, QSPI_STATUS_REG_SIZE, NULL, 0) != QSPI_STATUS_OK) { \ | ||
return QSPI_STATUS_ERROR; \ | ||
} \ | ||
WAIT_FOR(WRSR_MAX_TIME, qspi); \ | ||
\ | ||
memset(reg_data, 0, QSPI_STATUS_REG_SIZE); \ | ||
if (read_register(STATUS_REG, reg_data, \ | ||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \ | ||
return QSPI_STATUS_ERROR; \ | ||
} \ | ||
\ | ||
return ((reg_data[0] & STATUS_BIT_QE) != 0 ? \ | ||
QSPI_STATUS_OK : QSPI_STATUS_ERROR) | ||
|
||
|
||
|
||
#define QUAD_DISABLE() \ | ||
\ | ||
uint8_t reg_data[QSPI_STATUS_REG_SIZE]; \ | ||
\ | ||
if (write_enable(qspi) != QSPI_STATUS_OK) { \ | ||
return QSPI_STATUS_ERROR; \ | ||
} \ | ||
WAIT_FOR(WRSR_MAX_TIME, qspi); \ | ||
\ | ||
reg_data[0] = 0; \ | ||
qspi.cmd.build(QSPI_CMD_WRSR); \ | ||
\ | ||
if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), \ | ||
reg_data, QSPI_STATUS_REG_SIZE, NULL, 0) != QSPI_STATUS_OK) { \ | ||
return QSPI_STATUS_ERROR; \ | ||
} \ | ||
WAIT_FOR(WRSR_MAX_TIME, qspi); \ | ||
\ | ||
reg_data[0] = 0; \ | ||
if (read_register(STATUS_REG, reg_data, \ | ||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \ | ||
return QSPI_STATUS_ERROR; \ | ||
} \ | ||
\ | ||
return ((reg_data[0] & STATUS_BIT_QE) == 0 ? \ | ||
QSPI_STATUS_OK : QSPI_STATUS_ERROR) | ||
|
||
|
||
|
||
#define FAST_MODE_ENABLE() \ | ||
\ | ||
qspi_status_t ret; \ | ||
const int32_t reg_size = QSPI_STATUS_REG_SIZE + QSPI_CONFIG_REG_0_SIZE; \ | ||
uint8_t reg_data[reg_size]; \ | ||
\ | ||
if (read_register(STATUS_REG, reg_data, \ | ||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \ | ||
return QSPI_STATUS_ERROR; \ | ||
} \ | ||
if (read_register(CONFIG_REG0, reg_data + QSPI_STATUS_REG_SIZE, \ | ||
QSPI_CONFIG_REG_0_SIZE, qspi) != QSPI_STATUS_OK) { \ | ||
return QSPI_STATUS_ERROR; \ | ||
} \ | ||
\ | ||
reg_data[2] |= CONFIG1_BIT_LH; \ | ||
qspi.cmd.build(QSPI_CMD_WRSR); \ | ||
\ | ||
return qspi_command_transfer(&qspi.handle, qspi.cmd.get(), \ | ||
reg_data, reg_size, NULL, 0) | ||
|
||
|
||
|
||
#endif // MBED_QSPI_FLASH_MX25R6435F_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
/* mbed Microcontroller Library | ||
* Copyright (c) 2018-2018 ARM Limited | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
#ifndef MBED_QSPI_FLASH_N25Q128A_H | ||
#define MBED_QSPI_FLASH_N25Q128A_H | ||
|
||
|
||
#define QSPI_FLASH_CHIP_STRING "Micron N25Q128A" | ||
|
||
// Command for reading status register | ||
#define QSPI_CMD_RDSR 0x05 | ||
// Command for reading configuration register 0 (NONVOLATILE CONFIGURATION REGISTER) | ||
#define QSPI_CMD_RDCR0 0xB5 | ||
// Command for reading configuration register 1 (VOLATILE CONFIGURATION REGISTER) | ||
#define QSPI_CMD_RDCR1 0x85 | ||
// Command for reading configuration register 2 (ENHANCED VOLATILE CONFIGURATION REGISTER) | ||
#define QSPI_CMD_RDCR2 0x65 | ||
// Command for writing status | ||
#define QSPI_CMD_WRSR 0x01 | ||
// Command for writing configuration register 0 (NONVOLATILE CONFIGURATION REGISTER) | ||
#define QSPI_CMD_WRCR0 0xB1 | ||
// Command for writing configuration register 1 (VOLATILE CONFIGURATION REGISTER) | ||
#define QSPI_CMD_WRCR1 0x81 | ||
// Command for writing configuration register 2 (ENHANCED VOLATILE CONFIGURATION REGISTER) | ||
#define QSPI_CMD_WRCR2 0x61 | ||
// Command for reading security register | ||
#define QSPI_CMD_RDSCUR 0x2B | ||
|
||
// Command for setting Reset Enable | ||
#define QSPI_CMD_RSTEN 0x66 | ||
// Command for setting Reset | ||
#define QSPI_CMD_RST 0x99 | ||
|
||
// Command for setting write enable | ||
#define QSPI_CMD_WREN 0x06 | ||
// Command for setting write disable | ||
#define QSPI_CMD_WRDI 0x04 | ||
|
||
// WRSR operations max time [us] (datasheet max time + 15%) | ||
#define QSPI_WRSR_MAX_TIME 9200 // 8ms | ||
// general wait max time [us] | ||
#define QSPI_WAIT_MAX_TIME 100000 // 100ms | ||
|
||
|
||
// Commands for writing (page programming) | ||
#define QSPI_CMD_WRITE_1IO 0x02 // 1-1-1 mode | ||
#define QSPI_CMD_WRITE_2IO 0xD2 // 1-2-2 mode | ||
#define QSPI_CMD_WRITE_4IO 0x12 // 1-4-4 mode | ||
|
||
// write operations max time [us] (datasheet max time + 15%) | ||
#define QSPI_PAGE_PROG_MAX_TIME 5750 // 5ms | ||
|
||
#define QSPI_PAGE_SIZE 256 // 256B | ||
|
||
// Commands for reading | ||
#define QSPI_CMD_READ_1IO_FAST 0x0B // 1-1-1 mode | ||
#define QSPI_CMD_READ_1IO 0x03 // 1-1-1 mode | ||
#define QSPI_CMD_READ_2IO 0xBB // 1-2-2 mode | ||
#define QSPI_CMD_READ_1I2O 0x3B // 1-1-2 mode | ||
#define QSPI_CMD_READ_4IO 0xEB // 1-4-4 mode | ||
#define QSPI_CMD_READ_1I4O 0x6B // 1-1-4 mode | ||
|
||
|
||
#define QSPI_READ_1IO_DUMMY_CYCLE 0 | ||
#define QSPI_READ_FAST_DUMMY_CYCLE 8 | ||
// 8 dummy (10 dummy when quad SPI protocol is enabled) | ||
#define QSPI_READ_2IO_DUMMY_CYCLE 8 | ||
#define QSPI_READ_1I2O_DUMMY_CYCLE 8 | ||
#define QSPI_READ_4IO_DUMMY_CYCLE 10 | ||
#define QSPI_READ_1I4O_DUMMY_CYCLE 8 | ||
|
||
// Commands for erasing | ||
#define QSPI_CMD_ERASE_SECTOR 0x20 // 4kB | ||
#define QSPI_CMD_ERASE_BLOCK_32 0x52 // 32kB | ||
#define QSPI_CMD_ERASE_BLOCK_64 0xD8 // 64kB | ||
#define QSPI_CMD_ERASE_CHIP 0x60 // or 0xC7 | ||
|
||
// erase operations max time [us] (datasheet max time + 15%) | ||
#define QSPI_ERASE_SECTOR_MAX_TIME 276000 // 240 ms | ||
#define QSPI_ERASE_BLOCK_32_MAX_TIME 3000000 // 3s | ||
#define QSPI_ERASE_BLOCK_64_MAX_TIME 3500000 // 3.5s | ||
|
||
// max frequency for basic rw operation | ||
#define QSPI_COMMON_MAX_FREQUENCY 50000000 | ||
|
||
#define QSPI_STATUS_REG_SIZE 1 | ||
#define QSPI_CONFIG_REG_0_SIZE 2 | ||
#define QSPI_CONFIG_REG_1_SIZE 1 | ||
#define QSPI_CONFIG_REG_2_SIZE 1 | ||
#define QSPI_MAX_REG_SIZE 2 | ||
|
||
// status register | ||
#define STATUS_BIT_WIP (1 << 0) // write in progress bit | ||
#define STATUS_BIT_WEL (1 << 1) // write enable latch | ||
#define STATUS_BIT_BP0 (1 << 2) // block | ||
#define STATUS_BIT_BP1 (1 << 3) // | ||
#define STATUS_BIT_BP2 (1 << 4) // | ||
#define STATUS_BIT_BP_TB (1 << 5) // Block protect top/bottom | ||
#define STATUS_BIT_BP3 (1 << 6) // | ||
#define STATUS_BIT_SRWD (1 << 7) // status register write protect | ||
|
||
// configuration register 0 (Nonvolatile Configuration Register) | ||
// bit 1, 5, reserved | ||
#define CONFIG0_BIT_LOCK (1 << 0) // Lock nonvolatile configuration register | ||
#define CONFIG0_BIT_DE (1 << 2) // Dual Enable 0 = Enabled / 1 = Disabled | ||
#define CONFIG0_BIT_QE (1 << 3) // Quad Enable 0 = Enabled / 1 = Disabled | ||
#define CONFIG0_BIT_RH (1 << 4) // Reset/hold | ||
#define CONFIG0_BIT_ODS0 (1 << 6) // Output driver strength | ||
#define CONFIG0_BIT_ODS1 (1 << 7) // Output driver strength | ||
#define CONFIG0_BIT_ODS2 (1 << 8) // Output driver strength | ||
#define CONFIG0_BIT_XIP_MODE0 (1 << 9) // XIP mode at power-on reset | ||
#define CONFIG0_BIT_XIP_MODE1 (1 << 10) // XIP mode at power-on reset | ||
#define CONFIG0_BIT_XIP_MODE2 (1 << 11) // XIP mode at power-on reset | ||
#define CONFIG0_BIT_DCYCLE0 (1 << 12) // Dummy Cycle | ||
#define CONFIG0_BIT_DCYCLE1 (1 << 13) // Dummy Cycle | ||
#define CONFIG0_BIT_DCYCLE2 (1 << 14) // Dummy Cycle | ||
#define CONFIG0_BIT_DCYCLE3 (1 << 15) // Dummy Cycle | ||
#define CONFIG0_BITS_DEFAULT 0xFFFF // reg default state | ||
|
||
|
||
// configuration register 1 (Volatile Configuration Register) | ||
// bit 2, reserved | ||
#define CONFIG1_BIT_WRAP0 (1 << 0) // Output data wrap | ||
#define CONFIG1_BIT_WRAP1 (1 << 1) // Output data wrap | ||
#define CONFIG1_BIT_XIP (1 << 3) // 0 = Enable / 1 = Disable (default) | ||
#define CONFIG1_BIT_DCYCLE0 (1 << 4) // Number of dummy clock cycles | ||
#define CONFIG1_BIT_DCYCLE1 (1 << 5) // Number of dummy clock cycles | ||
#define CONFIG1_BIT_DCYCLE2 (1 << 6) // Number of dummy clock cycles | ||
#define CONFIG1_BIT_DCYCLE3 (1 << 7) // Number of dummy clock cycles | ||
#define CONFIG1_BITS_DEFAULT 0xB // reg default state | ||
|
||
|
||
// configuration register 2 (Enhanced Volatile Configuration Register) | ||
// bit 5, reserved | ||
#define CONFIG2_BIT_ODS0 (1 << 0) // Output driver strength 111 = 30 Ohms (Default) | ||
#define CONFIG2_BIT_ODS1 (1 << 1) // Output driver strength | ||
#define CONFIG2_BIT_ODS2 (1 << 2) // Output driver strength | ||
#define CONFIG2_BIT_VPP (1 << 3) // VPP accelerator 1 = Disabled (Default) | ||
#define CONFIG2_BIT_RH (1 << 4) // Reset/hold | ||
#define CONFIG2_BIT_DE (1 << 6) // Dual I/O protocol 0 = Enabled / 1 = Disabled (Default, extended SPI protocol) | ||
#define CONFIG2_BIT_QE (1 << 7) // Quad I/O protocol 0 = Enabled / 1 = Disabled (Default, extended SPI protocol) | ||
#define CONFIG2_BITS_DEFAULT 0xDF // reg default state | ||
|
||
|
||
#define DUAL_ENABLE() \ | ||
/* TODO: add implementation */ \ | ||
return QSPI_STATUS_OK | ||
|
||
|
||
#define DUAL_DISABLE() \ | ||
/* TODO: add implementation */ \ | ||
return QSPI_STATUS_OK | ||
|
||
|
||
#define QUAD_ENABLE() \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see currently those are TODOs, is there a plan to test QUAD? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure dual/quad will be tested, currently we have problems to enable dual/quad mode on targets with N25Q128A memory chip |
||
/* TODO: add implementation */ \ | ||
return QSPI_STATUS_OK | ||
|
||
|
||
#define QUAD_DISABLE() \ | ||
/* TODO: add implementation */ \ | ||
return QSPI_STATUS_OK | ||
|
||
|
||
#define FAST_MODE_ENABLE() \ | ||
/* TODO: add implementation */ \ | ||
return QSPI_STATUS_OK | ||
|
||
|
||
#endif // MBED_QSPI_FLASH_N25Q128A_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it common practice to use specific commercial manufacturers setups in mbed Tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's common, actually it's first time. But how to figure out what frequency or what dummy cycle count is supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@OPpuolitaival Please review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how the configuration works but this sounds wrong place to put board specific configuration. We should have some mechanism existing for these configs
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it's memory chip specific configuration.The configuration covers: max supported frequency, dummy_cycles_count for different write/read modes, mechanisms for enabling/disabling dual/quad/fast modes (which flag in which register to be set).
Here is example of adding QSPI support to new target by vendor, also contain new memory chip description file (link)
Alternatives:
QSPI SFDP Flash - Block Device
link, but it's high level mechanism, not sure if it's adequate hereThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maciejbocianski - I have no advise on this subject, sorry.
Other than that looks great to me - thanks.