mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 10:38:41 +00:00
490 lines
15 KiB
Go
490 lines
15 KiB
Go
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,
|
|
}
|
|
}
|