tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/flash/flash.go (about) 1 package flash 2 3 import ( 4 "time" 5 ) 6 7 const ( 8 // BlockSize is the number of bytes in a block for most/all NOR flash memory 9 BlockSize = 64 * 1024 10 11 // SectorSize is the number of bytes in a sector for most/all NOR flash memory 12 SectorSize = 4 * 1024 13 14 // PageSize is the number of bytes in a page for most/all NOR flash memory 15 PageSize = 256 16 ) 17 18 // Device represents a NOR flash memory device accessible using SPI 19 type Device struct { 20 trans transport 21 attrs Attrs 22 } 23 24 // DeviceConfig contains the parameters that can be set when configuring a 25 // flash memory device. 26 type DeviceConfig struct { 27 Identifier DeviceIdentifier 28 } 29 30 // JedecID encapsules the ID values that unique identify a flash memory device. 31 type JedecID struct { 32 ManufID uint8 33 MemType uint8 34 Capacity uint8 35 } 36 37 // Uint32 returns the JEDEC ID packed into a uint32 38 func (id JedecID) Uint32() uint32 { 39 return uint32(id.ManufID)<<16 | uint32(id.MemType)<<8 | uint32(id.Capacity) 40 } 41 42 // SerialNumber represents a serial number read from a flash memory device 43 type SerialNumber uint64 44 45 // Attrs represent the differences in hardware characteristics and capabilities 46 // of various SPI flash memory devices. 47 type Attrs struct { 48 49 // TotalSize is the number of bytes that the flash device can store 50 TotalSize uint32 51 52 // StartUp is the duration of time between when the device is reset and when 53 // it is ready to operation 54 StartUp time.Duration 55 56 // Three response bytes to 0x9f JEDEC ID command. 57 JedecID 58 59 // Max clock speed for all operations and the fastest read mode. 60 MaxClockSpeedMHz uint8 61 62 // Bitmask for Quad Enable bit if present. 0x00 otherwise. This is for the 63 // highest byte in the status register. 64 QuadEnableBitMask uint8 65 66 HasSectorProtection bool 67 68 // Supports the 0x0b fast read command with 8 dummy cycles. 69 SupportsFastRead bool 70 71 // Supports the fast read, quad output command 0x6b with 8 dummy cycles. 72 SupportsQSPI bool 73 74 // Supports the quad input page program command 0x32. This is known as 1-1-4 75 // because it only uses all four lines for data. 76 SupportsQSPIWrites bool 77 78 // Requires a separate command 0x31 to write to the second byte of the status 79 // register. Otherwise two byte are written via 0x01. 80 WriteStatusSplit bool 81 82 // True when the status register is a single byte. This implies the Quad 83 // Enable bit is in the first byte and the Read Status Register 2 command 84 // (0x35) is unsupported. 85 SingleStatusByte bool 86 } 87 88 // Configure sets up the device and the underlying transport mechanism. The 89 // DeviceConfig argument allows the caller to specify an instance of the 90 // DeviceIdentifier interface that, if provided, will be used to retrieve the 91 // attributes of the device based on the JEDEC ID. 92 func (dev *Device) Configure(config *DeviceConfig) (err error) { 93 94 dev.trans.configure(config) 95 96 var id JedecID 97 if id, err = dev.ReadJEDEC(); err != nil { 98 return err 99 } 100 101 // try to ascertain the vendor-specific attributes of the chip using the 102 // provided Identifier 103 if config.Identifier != nil { 104 dev.attrs = config.Identifier.Identify(id) 105 } else { 106 dev.attrs = Attrs{JedecID: id} 107 } 108 109 // We don't know what state the flash is in so wait for any remaining 110 // writes and then reset. 111 112 // The write in progress bit should be low. 113 for s, err := dev.ReadStatus(); (s & 0x01) > 0; s, err = dev.ReadStatus() { 114 if err != nil { 115 return err 116 } 117 } 118 // The suspended write/erase bit should be low. 119 for s, err := dev.ReadStatus2(); (s & 0x80) > 0; s, err = dev.ReadStatus2() { 120 if err != nil { 121 return err 122 } 123 } 124 // perform device reset 125 if err := dev.trans.runCommand(cmdEnableReset); err != nil { 126 return err 127 } 128 if err := dev.trans.runCommand(cmdReset); err != nil { 129 return err 130 } 131 132 // Wait for the reset - 30us by default 133 time.Sleep(30 * time.Microsecond) 134 135 // Speed up to max device frequency 136 // I propose a check here for max frequency, but not put that functionality directly into the driver. 137 // Either that or we have to change the signature of the SPI interface in the machine package itself. 138 if dev.attrs.MaxClockSpeedMHz > 0 { 139 err := dev.trans.setClockSpeed(uint32(dev.attrs.MaxClockSpeedMHz) * 1e6) 140 if err != nil { 141 return err 142 } 143 } 144 145 // Enable Quad Mode if available 146 if dev.trans.supportQuadMode() && dev.attrs.QuadEnableBitMask > 0 { 147 // Verify that QSPI mode is enabled. 148 var status byte 149 if dev.attrs.SingleStatusByte { 150 status, err = dev.ReadStatus() 151 } else { 152 status, err = dev.ReadStatus2() 153 } 154 if err != nil { 155 return err 156 } 157 // Check and set the quad enable bit. 158 if status&dev.attrs.QuadEnableBitMask == 0 { 159 if err := dev.WriteEnable(); err != nil { 160 return err 161 } 162 fullStatus := []byte{0x00, dev.attrs.QuadEnableBitMask} 163 if dev.attrs.WriteStatusSplit { 164 err = dev.trans.writeCommand(cmdWriteStatus2, fullStatus[1:]) 165 } else if dev.attrs.SingleStatusByte { 166 err = dev.trans.writeCommand(cmdWriteStatus, fullStatus[1:]) 167 } else { 168 err = dev.trans.writeCommand(cmdWriteStatus, fullStatus) 169 } 170 if err != nil { 171 return err 172 } 173 } 174 } 175 176 // disable sector protection if the chip has it 177 if dev.attrs.HasSectorProtection { 178 if err := dev.WriteEnable(); err != nil { 179 return err 180 } 181 if err := dev.trans.writeCommand(cmdWriteStatus, []byte{0x00}); err != nil { 182 return err 183 } 184 } 185 186 // write disable 187 if err := dev.trans.runCommand(cmdWriteDisable); err != nil { 188 return err 189 } 190 return dev.WaitUntilReady() 191 } 192 193 // Attrs returns the attributes of the device determined from the most recent 194 // call to Configure(). If no call to Configure() has been made, this will be 195 // the zero value of the Attrs struct. 196 func (dev *Device) Attrs() Attrs { 197 return dev.attrs 198 } 199 200 // ReadJEDEC reads the JEDEC ID from the device; this ID can then be used to 201 // ascertain the attributes of the chip from a list of known devices. 202 func (dev *Device) ReadJEDEC() (JedecID, error) { 203 jedecID := make([]byte, 3) 204 if err := dev.trans.readCommand(cmdReadJedecID, jedecID); err != nil { 205 return JedecID{}, err 206 } 207 return JedecID{jedecID[0], jedecID[1], jedecID[2]}, nil 208 } 209 210 // ReadSerialNumber reads the serial numbers from the connected device. 211 // TODO: maybe check if byte order / endianess is correct, probably is not 212 func (dev *Device) ReadSerialNumber() (SerialNumber, error) { 213 sn := make([]byte, 12) 214 if err := dev.trans.readCommand(0x4B, sn); err != nil { 215 return 0, err 216 } 217 return SerialNumber(uint64(sn[11]) | uint64(sn[10])<<0x8 | 218 uint64(sn[9])<<0x10 | uint64(sn[8])<<0x18 | uint64(sn[7])<<0x20 | 219 uint64(sn[6])<<0x28 | uint64(sn[5])<<0x30 | uint64(sn[4])<<0x38), nil 220 } 221 222 // Size returns the size of this memory, in bytes. 223 func (dev *Device) Size() int64 { 224 if dev.attrs.TotalSize < 1 { 225 // in case a DeviceIdentifier function wasn't used, use the capacity 226 // specified in the JEDEC ID instead 227 return int64(dev.attrs.Capacity) 228 } 229 return int64(dev.attrs.TotalSize) 230 } 231 232 // ReadAt satisfies the io.ReaderAt interface, and fills the provided buffer 233 // with memory read from the device starting at the provided address. 234 func (dev *Device) ReadAt(buf []byte, addr int64) (int, error) { 235 if err := dev.WaitUntilReady(); err != nil { 236 return 0, err 237 } 238 if err := dev.trans.readMemory(uint32(addr), buf); err != nil { 239 return 0, err 240 } 241 return len(buf), nil 242 } 243 244 // WriteAt satisfies the io.WriterAt interface and writes data to the device, 245 // one page at a time, starting at the provided address. This method assumes 246 // that the destination is already erased. 247 func (dev *Device) WriteAt(buf []byte, addr int64) (n int, err error) { 248 remain := uint32(len(buf)) 249 idx := uint32(0) 250 loc := uint32(addr) 251 for remain > 0 { 252 if err = dev.WaitUntilReady(); err != nil { 253 return 254 } 255 if err = dev.WriteEnable(); err != nil { 256 return 257 } 258 leftOnPage := PageSize - (loc & (PageSize - 1)) 259 toWrite := remain 260 if leftOnPage < remain { 261 toWrite = leftOnPage 262 } 263 if err = dev.trans.writeMemory(loc, buf[idx:idx+toWrite]); err != nil { 264 return 265 } 266 idx += toWrite 267 loc += toWrite 268 remain -= toWrite 269 } 270 return len(buf) - int(remain), nil 271 } 272 273 // WriteBlockSize returns the block size in which data can be written to 274 // memory. It can be used by a client to optimize writes, non-aligned writes 275 // should always work correctly. 276 // For SPI NOR flash this is the page size, usually/always 256. 277 func (dev *Device) WriteBlockSize() int64 { 278 return PageSize 279 } 280 281 // EraseBlockSize returns the smallest erasable area on this particular chip 282 // in bytes. This is used for the block size in EraseBlocks. 283 // For SPI NOR flash this is the sector size, usually/always 4096. 284 func (dev *Device) EraseBlockSize() int64 { 285 return SectorSize 286 } 287 288 // EraseBlocks erases the given number of blocks. An implementation may 289 // transparently coalesce ranges of blocks into larger bundles if the chip 290 // supports this. The start and len parameters are in block numbers, use 291 // EraseBlockSize to map addresses to blocks. 292 func (dev *Device) EraseBlocks(start, len int64) error { 293 for i := start; i < start+len; i++ { 294 if err := dev.EraseBlock(uint32(i)); err != nil { 295 return err 296 } 297 } 298 return nil 299 } 300 301 func (dev *Device) WriteEnable() error { 302 return dev.trans.runCommand(cmdWriteEnable) 303 } 304 305 // EraseBlock erases a block of memory at the specified index 306 func (dev *Device) EraseBlock(blockNumber uint32) error { 307 if err := dev.WaitUntilReady(); err != nil { 308 return err 309 } 310 if err := dev.WriteEnable(); err != nil { 311 return err 312 } 313 return dev.trans.eraseCommand(cmdEraseBlock, blockNumber*BlockSize) 314 } 315 316 // EraseSector erases a sector of memory at the given index 317 func (dev *Device) EraseSector(sectorNumber uint32) error { 318 if err := dev.WaitUntilReady(); err != nil { 319 return err 320 } 321 if err := dev.WriteEnable(); err != nil { 322 return err 323 } 324 return dev.trans.eraseCommand(cmdEraseSector, sectorNumber*SectorSize) 325 } 326 327 // EraseChip erases the entire flash memory chip 328 func (dev *Device) EraseAll() error { 329 if err := dev.WaitUntilReady(); err != nil { 330 return err 331 } 332 if err := dev.WriteEnable(); err != nil { 333 return err 334 } 335 return dev.trans.runCommand(cmdEraseChip) 336 } 337 338 // ReadStatus reads the value from status register 1 of the device 339 func (dev *Device) ReadStatus() (status byte, err error) { 340 buf := make([]byte, 1) 341 err = dev.trans.readCommand(cmdReadStatus, buf) 342 return buf[0], err 343 } 344 345 // ReadStatus2 reads the value from status register 2 of the device 346 func (dev *Device) ReadStatus2() (status byte, err error) { 347 buf := make([]byte, 1) 348 err = dev.trans.readCommand(cmdReadStatus2, buf) 349 return buf[0], err 350 } 351 352 // WaitUntilReady queries the status register until the device is ready for the 353 // next operation. 354 func (dev *Device) WaitUntilReady() error { 355 expire := time.Now().UnixNano() + int64(1*time.Second) 356 for s, err := dev.ReadStatus(); (s & 0x03) > 0; s, err = dev.ReadStatus() { 357 if err != nil { 358 return err 359 } 360 if time.Now().UnixNano() > expire { 361 return ErrWaitExpired 362 } 363 } 364 return nil 365 } 366 367 const ( 368 cmdRead = 0x03 // read memory using single-bit transfer 369 cmdQuadRead = 0x6B // read with 1 line address, 4 line data 370 cmdReadJedecID = 0x9F // read the JEDEC ID from the device 371 cmdPageProgram = 0x02 // write a page of memory using single-bit transfer 372 cmdQuadPageProgram = 0x32 // write with 1 line address, 4 line data 373 cmdReadStatus = 0x05 // read status register 1 374 cmdReadStatus2 = 0x35 // read status register 2 375 cmdWriteStatus = 0x01 // write status register 1 376 cmdWriteStatus2 = 0x31 // write status register 2 377 cmdEnableReset = 0x66 // enable reset 378 cmdReset = 0x99 // perform reset 379 cmdWriteEnable = 0x06 // write-enable memory 380 cmdWriteDisable = 0x04 // write-protect memory 381 cmdEraseSector = 0x20 // erase a sector of memory 382 cmdEraseBlock = 0xD8 // erase a block of memory 383 cmdEraseChip = 0xC7 // erase the entire chip 384 ) 385 386 type Error uint8 387 388 const ( 389 _ = iota 390 ErrInvalidClockSpeed Error = iota 391 ErrInvalidAddrRange 392 ErrWaitExpired 393 ) 394 395 func (err Error) Error() string { 396 switch err { 397 case ErrInvalidClockSpeed: 398 return "flash: invalid clock speed" 399 case ErrInvalidAddrRange: 400 return "flash: invalid address range" 401 case ErrWaitExpired: 402 return "flash: wait until ready expired" 403 default: 404 return "flash: unspecified error" 405 } 406 }