spiFlash: fix base addr, add method to read flash content and (non)volatile registers + cleanup
This commit is contained in:
parent
d64f6f5055
commit
4bfb764e75
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
|
|
@ -25,17 +26,6 @@
|
|||
#include "spiFlash.hpp"
|
||||
#include "spiInterface.hpp"
|
||||
|
||||
static uint8_t reverseByte(uint8_t src)
|
||||
{
|
||||
uint8_t dst = 0;
|
||||
for (int i=0; i < 8; i++) {
|
||||
dst = (dst << 1) | (src & 0x01);
|
||||
src >>= 1;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
/* read/write status register : 0B addr + 0 dummy */
|
||||
#define FLASH_WRSR 0x01
|
||||
#define FLASH_RDSR 0x05
|
||||
|
|
@ -52,7 +42,10 @@ static uint8_t reverseByte(uint8_t src)
|
|||
#define FLASH_POWER_DOWN 0xB9
|
||||
/* read/write non volatile register: 0B addr + 0 dummy */
|
||||
#define FLASH_RDNVCR 0xB5
|
||||
#define FLASH_WRNVCR 0x81
|
||||
#define FLASH_WRNVCR 0xB1
|
||||
/* read/write volatile register */
|
||||
#define FLASH_RDVCR 0x85
|
||||
#define FLASH_WRVCR 0x81
|
||||
/* bulk erase */
|
||||
#define FLASH_BE 0xC7
|
||||
/* sector (64kb) erase */
|
||||
|
|
@ -64,9 +57,6 @@ static uint8_t reverseByte(uint8_t src)
|
|||
#define FLASH_CLFSR 0x50
|
||||
#define FLASH_RFSR 0x70
|
||||
/* */
|
||||
#define FLASH_WRVCR 0x81
|
||||
#define FLASH_RDVCR 0x85
|
||||
/* */
|
||||
#define FLASH_WRVECR 0x61
|
||||
#define FLASH_RDVECR 0x65
|
||||
|
||||
|
|
@ -84,17 +74,19 @@ int SPIFlash::bulk_erase()
|
|||
|
||||
int SPIFlash::sector_erase(int addr)
|
||||
{
|
||||
uint8_t tx[3] = {(uint8_t)(0xff & (addr >> 16)),
|
||||
(uint8_t)(0xff & (addr >> 8)),
|
||||
(uint8_t)(addr & 0xff)};
|
||||
_spi->spi_put(FLASH_SE, tx, NULL, 3);
|
||||
uint8_t tx[4];
|
||||
tx[0] = (uint8_t)(FLASH_SE );
|
||||
tx[1] = (uint8_t)(0xff & (addr >> 16));
|
||||
tx[2] = (uint8_t)(0xff & (addr >> 8));
|
||||
tx[3] = (uint8_t)(0xff & (addr ));
|
||||
_spi->spi_put(tx, NULL, 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SPIFlash::sectors_erase(int base_addr, int size)
|
||||
{
|
||||
int start_addr = base_addr;
|
||||
int end_addr = (size + 0xffff) & ~0xffff;
|
||||
int end_addr = (base_addr + size + 0xffff) & ~0xffff;
|
||||
ProgressBar progress("Erasing", end_addr, 50);
|
||||
for (int addr = start_addr; addr < end_addr; addr += 0x10000) {
|
||||
if (write_enable() == -1)
|
||||
|
|
@ -113,15 +105,11 @@ int SPIFlash::write_page(int addr, uint8_t *data, int len)
|
|||
{
|
||||
uint8_t tx[len+3];
|
||||
tx[0] = (uint8_t)(0xff & (addr >> 16));
|
||||
tx[1] = (uint8_t)(0xff & (addr >> 8));
|
||||
tx[2] = (uint8_t)(addr & 0xff);
|
||||
tx[1] = (uint8_t)(0xff & (addr >> 8));
|
||||
tx[2] = (uint8_t)(0xff & (addr ));
|
||||
|
||||
memcpy(tx+3, data, len);
|
||||
|
||||
/*uint8_t tx[len+3] = {(uint8_t)(0xff & (addr >> 16)),
|
||||
(uint8_t)(0xff & (addr >> 8)),
|
||||
(uint8_t)(addr & 0xff)};*/
|
||||
for (int i=0; i < len; i++) {
|
||||
tx[i+3] = data[i];
|
||||
}
|
||||
if (write_enable() == -1)
|
||||
return -1;
|
||||
|
||||
|
|
@ -129,6 +117,22 @@ int SPIFlash::write_page(int addr, uint8_t *data, int len)
|
|||
return _spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, 1000);
|
||||
}
|
||||
|
||||
int SPIFlash::read(int base_addr, uint8_t *data, int len)
|
||||
{
|
||||
uint8_t tx[len+3];
|
||||
uint8_t rx[len+3];
|
||||
tx[0] = (uint8_t)(0xff & (base_addr >> 16));
|
||||
tx[1] = (uint8_t)(0xff & (base_addr >> 8));
|
||||
tx[2] = (uint8_t)(0xff & (base_addr ));
|
||||
|
||||
int ret = _spi->spi_put(0x03, tx, rx, len+3);
|
||||
if (ret == 0)
|
||||
memcpy(data, rx+3, len);
|
||||
else
|
||||
printf("error\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len)
|
||||
{
|
||||
/* check Block Protect Bits */
|
||||
|
|
@ -140,14 +144,14 @@ int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len)
|
|||
return -1;
|
||||
}
|
||||
ProgressBar progress("Writing", len, 50);
|
||||
if (sectors_erase(0, len) == -1)
|
||||
if (sectors_erase(base_addr, len) == -1)
|
||||
return -1;
|
||||
|
||||
uint8_t *ptr = data;
|
||||
int size = 0;
|
||||
for (int addr = base_addr; addr < len; addr += size, ptr+=size) {
|
||||
for (int addr = 0; addr < len; addr += size, ptr+=size) {
|
||||
size = (addr + 256 > len)?(len-addr) : 256;
|
||||
if (write_page(addr, ptr, size) == -1)
|
||||
if (write_page(base_addr + addr, ptr, size) == -1)
|
||||
return -1;
|
||||
progress.display(addr);
|
||||
}
|
||||
|
|
@ -157,7 +161,8 @@ int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len)
|
|||
|
||||
void SPIFlash::reset()
|
||||
{
|
||||
uint8_t data[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
uint8_t data[8];
|
||||
memset(data, 0xff, 8);
|
||||
_spi->spi_put(0xff, data, NULL, 8);
|
||||
}
|
||||
|
||||
|
|
@ -221,6 +226,24 @@ uint8_t SPIFlash::read_status_reg()
|
|||
return rx;
|
||||
}
|
||||
|
||||
uint16_t SPIFlash::readNonVolatileCfgReg()
|
||||
{
|
||||
uint8_t rx[2];
|
||||
_spi->spi_put(FLASH_RDNVCR, NULL, rx, 2);
|
||||
if (_verbose)
|
||||
printf("Non Volatile %x %x\n", rx[0], rx[1]);
|
||||
return (rx[1] << 8) | rx[0];
|
||||
}
|
||||
|
||||
uint16_t SPIFlash::readVolatileCfgReg()
|
||||
{
|
||||
uint8_t rx[2];
|
||||
_spi->spi_put(FLASH_RDVCR, NULL, rx, 2);
|
||||
if (_verbose)
|
||||
printf("Volatile %x %x\n", rx[0], rx[1]);
|
||||
return (rx[1] << 8) | rx[0];
|
||||
}
|
||||
|
||||
void SPIFlash::power_up()
|
||||
{
|
||||
_spi->spi_put(FLASH_POWER_UP, NULL, NULL, 0);
|
||||
|
|
|
|||
|
|
@ -37,11 +37,15 @@ class SPIFlash {
|
|||
int sectors_erase(int base_addr, int len);
|
||||
/* write */
|
||||
int write_page(int addr, uint8_t *data, int len);
|
||||
/* read */
|
||||
int read(int base_addr, uint8_t *data, int len);
|
||||
/* combo flash + erase */
|
||||
int erase_and_prog(int base_addr, uint8_t *data, int len);
|
||||
/* display/info */
|
||||
uint8_t read_status_reg();
|
||||
void read_id();
|
||||
uint16_t readNonVolatileCfgReg();
|
||||
uint16_t readVolatileCfgReg();
|
||||
private:
|
||||
SPIInterface *_spi;
|
||||
bool _verbose;
|
||||
|
|
|
|||
Loading…
Reference in New Issue