package flash import "time" // A DeviceIdentifier can be passed to the Configure() method of a flash Device // in order provide a means of discovery of device-specific attributes based on // the JEDEC ID read from the device. type DeviceIdentifier interface { // Identify returns an Attrs struct based on the provided JEDEC ID Identify(id JedecID) Attrs } // DeviceIdentifierFunc is a functional Identifier implementation type DeviceIdentifierFunc func(id JedecID) Attrs // Identify implements the Identifier interface func (fn DeviceIdentifierFunc) Identify(id JedecID) Attrs { return fn(id) } // DefaultDeviceIndentifier is a DeviceIdentifier that is capable of recognizing // JEDEC IDs for all of the known memory devices in this package. If you are // have no way to be sure about the type of memory device that might be on a // board you are targeting, this can be a good starting point to use. The // downside of using this function is that it will prevent the compiler from // being able to mark any of the functions for the various devices as unused, // resulting in larger code size. If code size is a concern, and if you know // ahead of time you are only dealing with a limited set of memory devices, it // might be worthwhile to use your own implementation of a DeviceIdentifier // that only references those devices, so that more methods are marked unused. var DefaultDeviceIdentifier = DeviceIdentifierFunc(func(id JedecID) Attrs { switch id.Uint32() { case 0x010617: return S25FL064L() case 0x014015: return S25FL216K() case 0x1F4501: return AT25DF081A() case 0xC22015: return MX25L1606() case 0xC22016: return MX25L3233F() case 0xC22817: return MX25R6435F() case 0xC84015: return GD25Q16C() case 0xC84017: return GD25Q64C() case 0x856015: return P25Q16H() case 0xEF4014: return W25Q80DV() case 0xEF4015: return W25Q16JVIQ() case 0xEF4016: return W25Q32FV() case 0xEF4017: return W25Q64JVIQ() case 0xEF4018: return W25Q128JVSQ() case 0xEF6014: return W25Q80DL() case 0xEF6015: return W25Q16FW() case 0xEF6016: return W25Q32BV() case 0xEF7015: return W25Q16JVIM() case 0xEF7016: return W25Q32JVIM() case 0xEF7017: return W25Q64JVIM() case 0xEF7018: return W25Q128JVPM() default: return Attrs{JedecID: id} } }) // Settings for the Cypress (was Spansion) S25FL064L 8MiB SPI flash. // Datasheet: http://www.cypress.com/file/316661/download func S25FL064L() Attrs { return Attrs{ TotalSize: 1 << 23, // 8 MiB StartUp: 300 * time.Microsecond, JedecID: JedecID{0x01, 0x60, 0x17}, MaxClockSpeedMHz: 108, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Cypress (was Spansion) S25FL116K 2MiB SPI flash. // Datasheet: http://www.cypress.com/file/196886/download func S25FL116K() Attrs { return Attrs{ TotalSize: 1 << 21, // 2 MiB StartUp: 10000 * time.Microsecond, JedecID: JedecID{0x01, 0x40, 0x15}, MaxClockSpeedMHz: 108, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: false, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Cypress (was Spansion) S25FL216K 2MiB SPI flash. // Datasheet: http://www.cypress.com/file/197346/download func S25FL216K() Attrs { return Attrs{ TotalSize: 1 << 21, // 2 MiB StartUp: 10000 * time.Microsecond, JedecID: JedecID{0x01, 0x40, 0x15}, MaxClockSpeedMHz: 65, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: false, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Adesto Tech AT25DF081A 1MiB SPI flash. Its on the SAMD21 // Xplained board. // Datasheet: https://www.adestotech.com/wp-content/uploads/doc8715.pdf func AT25DF081A() Attrs { return Attrs{ TotalSize: 1 << 20, // 1 MiB StartUp: 10000 * time.Microsecond, JedecID: JedecID{0x1F, 0x45, 0x01}, MaxClockSpeedMHz: 85, QuadEnableBitMask: 0x00, HasSectorProtection: true, SupportsFastRead: true, SupportsQSPI: false, SupportsQSPIWrites: false, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Macronix MX25L1606 2MiB SPI flash. // Datasheet: func MX25L1606() Attrs { return Attrs{ TotalSize: 1 << 21, // 2 MiB, StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xC2, 0x20, 0x15}, MaxClockSpeedMHz: 8, QuadEnableBitMask: 0x40, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: true, } } // Settings for the Macronix MX25L3233F 4MiB SPI flash. // Datasheet: // http://www.macronix.com/Lists/Datasheet/Attachments/7426/MX25L3233F,%203V,%2032Mb,%20v1.6.pdf func MX25L3233F() Attrs { return Attrs{ TotalSize: 1 << 22, // 4 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xC2, 0x20, 0x16}, MaxClockSpeedMHz: 133, QuadEnableBitMask: 0x40, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Macronix MX25R6435F 8MiB SPI flash. // Datasheet: // http://www.macronix.com/Lists/Datasheet/Attachments/7428/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.4.pdf // By default its in lower power mode which can only do 8mhz. In high power mode // it can do 80mhz. func MX25R6435F() Attrs { return Attrs{ TotalSize: 1 << 23, // 8 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xC2, 0x28, 0x17}, MaxClockSpeedMHz: 8, QuadEnableBitMask: 0x40, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: true, } } // Settings for the Gigadevice GD25Q16C 2MiB SPI flash. // Datasheet: http://www.gigadevice.com/datasheet/gd25q16c/ func GD25Q16C() Attrs { return Attrs{ TotalSize: 1 << 21, // 2 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xC8, 0x40, 0x15}, MaxClockSpeedMHz: 104, QuadEnableBitMask: 0x02, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Gigadevice GD25Q64C 8MiB SPI flash. // Datasheet: http://www.elm-tech.com/en/products/spi-flash-memory/gd25q64/gd25q64.pdf func GD25Q64C() Attrs { return Attrs{ TotalSize: 1 << 23, // 8 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xC8, 0x40, 0x17}, MaxClockSpeedMHz: 104, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: true, SingleStatusByte: false, } } // Settings for the Puya P25Q16H 2MiB SPI flash. // Datasheet: https://files.seeedstudio.com/wiki/github_weiruanexample/Flash_P25Q16H-UXH-IR_Datasheet.pdf func P25Q16H() Attrs { return Attrs{ TotalSize: 1 << 21, // 2 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0x85, 0x60, 0x15}, MaxClockSpeedMHz: 55, QuadEnableBitMask: 0x02, HasSectorProtection: true, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: true, SingleStatusByte: false, } } // Settings for the Winbond W25Q16JV-IQ 2MiB SPI flash. Note that JV-IM has a // different .memory_type (0x70) Datasheet: // https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf func W25Q16JVIQ() Attrs { return Attrs{ TotalSize: 1 << 21, // 2 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x40, 0x15}, MaxClockSpeedMHz: 133, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q16FW 2MiB SPI flash. // Datasheet: // https://www.winbond.com/resource-files/w25q16fw%20revj%2005182017%20sfdp.pdf func W25Q16FW() Attrs { return Attrs{ TotalSize: 1 << 21, // 2 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x60, 0x15}, MaxClockSpeedMHz: 133, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q16JV-IM 2MiB SPI flash. Note that JV-IQ has a // different .memory_type (0x40) Datasheet: // https://www.winbond.com/resource-files/w25q16jv%20spi%20revf%2005092017.pdf func W25Q16JVIM() Attrs { return Attrs{ TotalSize: 1 << 21, // 2 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x70, 0x15}, MaxClockSpeedMHz: 133, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q32BV 4MiB SPI flash. // Datasheet: // https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf func W25Q32BV() Attrs { return Attrs{ TotalSize: 1 << 22, // 4 MiB StartUp: 10000 * time.Microsecond, JedecID: JedecID{0xEF, 0x60, 0x16}, MaxClockSpeedMHz: 104, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: false, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q32JV-IM 4MiB SPI flash. // Datasheet: // https://www.winbond.com/resource-files/w25q32jv%20revg%2003272018%20plus.pdf func W25Q32JVIM() Attrs { return Attrs{ TotalSize: 1 << 22, // 4 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x70, 0x16}, MaxClockSpeedMHz: 133, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q64JV-IM 8MiB SPI flash. Note that JV-IQ has a // different .memory_type (0x40) Datasheet: // http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf func W25Q64JVIM() Attrs { return Attrs{ TotalSize: 1 << 23, // 8 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x70, 0x17}, MaxClockSpeedMHz: 133, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q64JV-IQ 8MiB SPI flash. Note that JV-IM has a // different .memory_type (0x70) Datasheet: // http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf func W25Q64JVIQ() Attrs { return Attrs{ TotalSize: 1 << 23, // 8 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x40, 0x17}, MaxClockSpeedMHz: 133, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q80DL 1MiB SPI flash. // Datasheet: // https://www.winbond.com/resource-files/w25q80dv%20dl_revh_10022015.pdf func W25Q80DL() Attrs { return Attrs{ TotalSize: 1 << 20, // 1 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x60, 0x14}, MaxClockSpeedMHz: 80, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: false, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q80DV 2MiB SPI flash. // Datasheet: // https://www.winbond.com/resource-files/w25q80dv%20dl_revh_10022015.pdf func W25Q80DV() Attrs { return Attrs{ TotalSize: 1 << 21, // 2 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x40, 0x14}, MaxClockSpeedMHz: 104, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: false, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q128JV-SQ 16MiB SPI flash. Note that JV-IM has a // different .memory_type (0x70) Datasheet: // https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf func W25Q128JVSQ() Attrs { return Attrs{ TotalSize: 1 << 24, // 16 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x40, 0x18}, MaxClockSpeedMHz: 133, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q128JV-PM 16MiB SPI flash. Note that JV-IM has a // different .memory_type (0x70) Datasheet: // https://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf func W25Q128JVPM() Attrs { return Attrs{ TotalSize: 1 << 24, // 16 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x70, 0x18}, MaxClockSpeedMHz: 133, QuadEnableBitMask: 0x02, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: true, SupportsQSPIWrites: true, WriteStatusSplit: false, SingleStatusByte: false, } } // Settings for the Winbond W25Q32FV 4MiB SPI flash. // Datasheet:http://www.winbond.com/resource-files/w25q32fv%20revj%2006032016.pdf?__locale=en func W25Q32FV() Attrs { return Attrs{ TotalSize: 1 << 22, // 4 MiB StartUp: 5000 * time.Microsecond, JedecID: JedecID{0xEF, 0x40, 0x16}, MaxClockSpeedMHz: 104, QuadEnableBitMask: 0x00, HasSectorProtection: false, SupportsFastRead: true, SupportsQSPI: false, SupportsQSPIWrites: false, WriteStatusSplit: false, SingleStatusByte: false, } }