Add support for Winbond 64Mbit SPI flash chip
This commit is contained in:
parent
f24782b961
commit
01b811cd8c
|
@ -134,9 +134,17 @@ tubing instead.
|
||||||

|

|
||||||
|
|
||||||
### Onboard dataflash storage
|
### Onboard dataflash storage
|
||||||
The full version of the Naze32 and the CC3D have an onboard "m25p16" 2 megayte dataflash storage chip which can be used
|
Some flight controllers have an onboard SPI NOR flash chip which can be used to store flight logs instead of using an
|
||||||
to store flight logs instead of using an OpenLog. This is a small chip with 8 fat legs, which can be found at the base
|
OpenLog.
|
||||||
of the Naze32's direction arrow. This chip is not present on the "Acro" version of the Naze32.
|
|
||||||
|
The full version of the Naze32 and the CC3D have an onboard "m25p16" 2 megayte dataflash storage chip. This is a small
|
||||||
|
chip with 8 fat legs, which can be found at the base of the Naze32's direction arrow. This chip is not present on the
|
||||||
|
"Acro" version of the Naze32.
|
||||||
|
|
||||||
|
These chips are also supported:
|
||||||
|
|
||||||
|
* Micron/ST M25P16 - 16 Mbit
|
||||||
|
* Winbond W25Q64 - 64 Mbit
|
||||||
|
|
||||||
## Enabling the Blackbox (CLI)
|
## Enabling the Blackbox (CLI)
|
||||||
In the [Cleanflight Configurator][] , enter the CLI tab. Enable the Blackbox feature by typing in `feature BLACKBOX` and
|
In the [Cleanflight Configurator][] , enter the CLI tab. Enable the Blackbox feature by typing in `feature BLACKBOX` and
|
||||||
|
|
|
@ -20,12 +20,12 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct flashGeometry_t {
|
typedef struct flashGeometry_t {
|
||||||
uint8_t sectors;
|
uint8_t sectors; // Count of the number of erasable blocks on the device
|
||||||
|
|
||||||
uint16_t pagesPerSector;
|
uint16_t pagesPerSector;
|
||||||
uint16_t pageSize;
|
uint16_t pageSize; // In bytes
|
||||||
|
|
||||||
uint32_t sectorSize;
|
uint32_t sectorSize; // This is just pagesPerSector * pageSize
|
||||||
|
|
||||||
uint32_t totalSize;
|
uint32_t totalSize; // This is just sectorSize * sectors
|
||||||
} flashGeometry_t;
|
} flashGeometry_t;
|
||||||
|
|
|
@ -38,6 +38,10 @@
|
||||||
#define M25P16_STATUS_FLAG_WRITE_IN_PROGRESS 0x01
|
#define M25P16_STATUS_FLAG_WRITE_IN_PROGRESS 0x01
|
||||||
#define M25P16_STATUS_FLAG_WRITE_ENABLED 0x02
|
#define M25P16_STATUS_FLAG_WRITE_ENABLED 0x02
|
||||||
|
|
||||||
|
// Format is manufacturer, memory type, then capacity
|
||||||
|
#define JEDEC_ID_MICRON_M25P16 0x202015
|
||||||
|
#define JEDEC_ID_WINBOND_W25Q64 0xEF4017
|
||||||
|
|
||||||
#define DISABLE_M25P16 GPIO_SetBits(M25P16_CS_GPIO, M25P16_CS_PIN)
|
#define DISABLE_M25P16 GPIO_SetBits(M25P16_CS_GPIO, M25P16_CS_PIN)
|
||||||
#define ENABLE_M25P16 GPIO_ResetBits(M25P16_CS_GPIO, M25P16_CS_PIN)
|
#define ENABLE_M25P16 GPIO_ResetBits(M25P16_CS_GPIO, M25P16_CS_PIN)
|
||||||
|
|
||||||
|
@ -124,6 +128,7 @@ static bool m25p16_readIdentification()
|
||||||
{
|
{
|
||||||
uint8_t out[] = { M25P16_INSTRUCTION_RDID, 0, 0, 0};
|
uint8_t out[] = { M25P16_INSTRUCTION_RDID, 0, 0, 0};
|
||||||
uint8_t in[4];
|
uint8_t in[4];
|
||||||
|
uint32_t chipID;
|
||||||
|
|
||||||
delay(50); // short delay required after initialisation of SPI device instance.
|
delay(50); // short delay required after initialisation of SPI device instance.
|
||||||
|
|
||||||
|
@ -139,12 +144,30 @@ static bool m25p16_readIdentification()
|
||||||
// Clearing the CS bit terminates the command early so we don't have to read the chip UID:
|
// Clearing the CS bit terminates the command early so we don't have to read the chip UID:
|
||||||
DISABLE_M25P16;
|
DISABLE_M25P16;
|
||||||
|
|
||||||
// Check manufacturer, memory type, and capacity
|
// Manufacturer, memory type, and capacity
|
||||||
if (in[1] == 0x20 && in[2] == 0x20 && in[3] == 0x15) {
|
chipID = (in[1] << 16) | (in[2] << 8) | (in[3]);
|
||||||
// In the future we can support other chip geometries here:
|
|
||||||
|
switch (chipID) {
|
||||||
|
case JEDEC_ID_MICRON_M25P16:
|
||||||
geometry.sectors = 32;
|
geometry.sectors = 32;
|
||||||
geometry.pagesPerSector = 256;
|
geometry.pagesPerSector = 256;
|
||||||
geometry.pageSize = 256;
|
geometry.pageSize = 256;
|
||||||
|
break;
|
||||||
|
case JEDEC_ID_WINBOND_W25Q64:
|
||||||
|
geometry.sectors = 128;
|
||||||
|
geometry.pagesPerSector = 256;
|
||||||
|
geometry.pageSize = 256;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unsupported chip or not an SPI NOR flash
|
||||||
|
geometry.sectors = 0;
|
||||||
|
geometry.pagesPerSector = 0;
|
||||||
|
geometry.pageSize = 0;
|
||||||
|
|
||||||
|
geometry.sectorSize = 0;
|
||||||
|
geometry.totalSize = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
geometry.sectorSize = geometry.pagesPerSector * geometry.pageSize;
|
geometry.sectorSize = geometry.pagesPerSector * geometry.pageSize;
|
||||||
geometry.totalSize = geometry.sectorSize * geometry.sectors;
|
geometry.totalSize = geometry.sectorSize * geometry.sectors;
|
||||||
|
@ -152,16 +175,6 @@ static bool m25p16_readIdentification()
|
||||||
couldBeBusy = true; // Just for luck we'll assume the chip could be busy even though it isn't specced to be
|
couldBeBusy = true; // Just for luck we'll assume the chip could be busy even though it isn't specced to be
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
geometry.sectors = 0;
|
|
||||||
geometry.pagesPerSector = 0;
|
|
||||||
geometry.pageSize = 0;
|
|
||||||
|
|
||||||
geometry.sectorSize = 0;
|
|
||||||
geometry.totalSize = 0;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue