46 lines
1.5 KiB
C++
46 lines
1.5 KiB
C++
|
#include "string.h"
|
||
|
#include "norflash.h"
|
||
|
|
||
|
/// Enumerace povelů pro SPI FLASH.
|
||
|
enum FLASH_COMMANDS : uint8_t {
|
||
|
/* single byte commands */
|
||
|
FLASH_WRDI = 0x04, // nepoužito
|
||
|
FLASH_WREN = 0x06,
|
||
|
FLASH_RDID = 0x9F,
|
||
|
FLASHRSTEN = 0x66, // nepoužito
|
||
|
FLASH__RST = 0x99, // nepoužito
|
||
|
FLASH__RES = 0xAB, // release from power down, nepoužito
|
||
|
FLASH__DPD = 0xB9, // power down, nepoužito
|
||
|
// multi - byte
|
||
|
FLASH_RDSR1 = 0x05,
|
||
|
// dále se mohou povely lišit
|
||
|
FLASH_RDSR2 = 0x35, // nepoužito
|
||
|
FLASH_4READ = 0x03,
|
||
|
FLASH_4PP = 0x02,
|
||
|
FLASH_4SE = 0x20,
|
||
|
};
|
||
|
union FlashCommandHeader {
|
||
|
struct {
|
||
|
FLASH_COMMANDS cmd : 8;
|
||
|
uint32_t adr : 24; // adresa je BIG ENDIEN - vyšší byte vystupuje po SPI dříve (MSB FIRST).
|
||
|
}__attribute__((packed));
|
||
|
uint8_t bytes [4];
|
||
|
}__attribute__((packed));
|
||
|
static inline uint32_t be_set_24 (const uint32_t p) {
|
||
|
return ((p & 0x000000ff) << 16)
|
||
|
| ((p & 0x0000ff00) << 0)
|
||
|
| ((p & 0x00ff0000) >> 16);
|
||
|
}
|
||
|
/* Nic jiného zatím není potřeba, ale šlo by dodělat i zápis včetně mazání bloku.
|
||
|
*/
|
||
|
unsigned int NorFlash::ReadBlock(const unsigned int addr, uint8_t * data, const unsigned int len) {
|
||
|
FlashCommandHeader header;
|
||
|
header.cmd = FLASH_4READ;
|
||
|
header.adr = be_set_24(addr);
|
||
|
spi.ChipSelect(true);
|
||
|
for (unsigned n=0u; n<sizeof(header); n++) spi.ReadWriteByte(header.bytes[n]);
|
||
|
for (unsigned n=0u; n<len; n++) data [n] = spi.ReadWriteByte(0xff);
|
||
|
spi.ChipSelect(false);
|
||
|
return len;
|
||
|
}
|