Skip to content

Commit

Permalink
Merge pull request #110 from shinhub/4k_slot1_memory_overlap_fix
Browse files Browse the repository at this point in the history
4k memory overlap fix #41 + SPI_FLASHINFO rewrite
  • Loading branch information
iceman1001 authored Aug 12, 2019
2 parents 0b5cc0a + 7d60b6d commit 55030a5
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 60 deletions.
72 changes: 43 additions & 29 deletions Firmware/Chameleon-Mini/Memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,22 +168,39 @@ INLINE void FlashClearPage(uint16_t PageAddress) {
MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS;
}

void FlashReadManufacturerDeviceInfo(void* Buffer) {
flashManufacturerInfo_t GetFlashManufacturerInfo(void) {
flashManufacturerInfo_t ret;

while(FlashIsBusy());

MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_CS;
SPITransferByte(FLASH_CMD_READMANUFDEVICEINFO);
SPIReadBlock(Buffer, 4);
SPIReadBlock(ret.data, 4);
MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS;

ret.manufacturerId = ret.data[0];
ret.familyCode = ret.data[1] >> 5;
ret.densityCode = ret.data[1] & 0x1F;
ret.MLCCode = ret.data[2] >> 5;
ret.productVersionCode = ret.data[2] & 0x1F;
ret.sizeMbits = 0;
// Minimum: AT45DB011D Density Code : 00010 = 1-Mbit
// Maximum: AT45DB642D Density Code : 01000 = 64-Mbit
if ((ret.densityCode >= 2) && (ret.densityCode <= 8) && (ret.familyCode == 1))
ret.sizeMbits = 1 << (ret.densityCode - 2);
// Precalculated 1024 / 8 = 128, to prevent uint16_t overflow for possible 64-Mbit flash
ret.sizeKbytes = ret.sizeMbits * 128;

return ret;
}

void MemoryInit(void) {
/* Configure MEMORY_FLASH_USART for SPI master mode 0 with maximum clock frequency */
MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_CS;

MEMORY_FLASH_PORT.OUTCLR = MEMORY_FLASH_SCK;
MEMORY_FLASH_PORT.OUTSET = MEMORY_FLASH_MOSI;

MEMORY_FLASH_PORT.DIRSET = MEMORY_FLASH_SCK | MEMORY_FLASH_MOSI | MEMORY_FLASH_CS;

MEMORY_FLASH_USART.BAUDCTRLA = 0;
Expand All @@ -196,49 +213,46 @@ void MemoryInit(void) {
/* Configure for 256 byte Dataflash if not already done. */
FlashConfigurePageSize();
}

FlashManufacturerInfo = GetFlashManufacturerInfo();
}

uint32_t GetFlashAddressForSetting(uint32_t Setting, uint32_t Address) {
uint32_t FlashAddress = Address;
if ( Setting > 0 )
FlashAddress = Address + MEMORY_SIZE_PER_SETTING_4K + ((uint16_t) Setting - 1) * MEMORY_SIZE_PER_SETTING_1K;
return FlashAddress;
}

void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount) {
if (ByteCount == 0)
return;

uint32_t FlashAddress;
if ( GlobalSettings.ActiveSetting == 0 )
FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING_4K;
else
FlashAddress = (uint32_t) Address + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING_1K;

FlashRead(Buffer, FlashAddress, ByteCount);
FlashRead(Buffer, GetFlashAddressForSetting(GlobalSettings.ActiveSetting, Address), ByteCount);
}

void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount) {
if (ByteCount == 0)
return;
uint16_t FlashAddress;
if ( GlobalSettings.ActiveSetting == 0 )
FlashAddress = Address + (uint16_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING_4K;
else
FlashAddress = Address + (uint16_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING_1K;
FlashWrite(Buffer, FlashAddress, ByteCount);
FlashWrite(Buffer, GetFlashAddressForSetting(GlobalSettings.ActiveSetting, Address), ByteCount);
}

void MemoryClear(void) {
uint16_t PageAddress;
uint16_t PageCount;
if ( GlobalSettings.ActiveSetting == 0 ) {
PageAddress = ((uint16_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING_4K) / MEMORY_PAGE_SIZE;

PageAddress = ((uint16_t)GetFlashAddressForSetting(GlobalSettings.ActiveSetting, (uint32_t)0)) / MEMORY_PAGE_SIZE;
if ( GlobalSettings.ActiveSetting == 0 )
PageCount = MEMORY_SIZE_PER_SETTING_4K / MEMORY_PAGE_SIZE;
} else {
PageAddress = ((uint16_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING_1K) / MEMORY_PAGE_SIZE;
else
PageCount = MEMORY_SIZE_PER_SETTING_1K / MEMORY_PAGE_SIZE;
}

while(PageCount > 0) {
FlashClearPage(PageAddress);
PageCount--;
PageAddress++;
}
}

void MemoryRecall(void) {
/* Recall memory from permanent flash */
//FlashRead(Memory, (uint16_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING);
Expand Down Expand Up @@ -305,9 +319,9 @@ bool MemoryDownloadBlock(void* Buffer, uint16_t BlockAddress, uint16_t ByteCount
}

// EEPROM functions

static inline void NVM_EXEC(void)
{
{
void *z = (void *)&NVM_CTRLA;

__asm__ volatile("out %[ccp], %[ioreg]" "\n\t"
Expand All @@ -319,14 +333,14 @@ static inline void NVM_EXEC(void)
[z] "z" (z)
);
}

void WaitForNVM(void)
{
{
while (NVM.STATUS & NVM_NVMBUSY_bm) { };
}

void FlushNVMBuffer(void)
{
{
WaitForNVM();

if ((NVM.STATUS & NVM_EELOAD_bm) != 0) {
Expand Down
18 changes: 15 additions & 3 deletions Firmware/Chameleon-Mini/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,32 @@
#define MEMORY_FLASH_MISO PIN2_bm
#define MEMORY_FLASH_SCK PIN1_bm

#define MEMORY_PAGE_SIZE 256
#define MEMORY_PAGE_SIZE 256
#define MEMORY_SIZE_PER_SETTING_4K 4096
#define MEMORY_SIZE_PER_SETTING_1K 1024


// extra config memory section
// 8 slots possible,
// 8 slots possible,
// 2byte ataq
// 1byte sak
// 1 bit magic gen1a
// 1 bit magic gen1b
// 1 bit magic gen2

void FlashReadManufacturerDeviceInfo(void* Buffer);
// Flash manufacturer info
typedef struct {
uint8_t data[4];
uint8_t manufacturerId;
uint8_t familyCode;
uint8_t densityCode;
uint8_t MLCCode;
uint8_t productVersionCode;
uint16_t sizeMbits;
uint32_t sizeKbytes;
} flashManufacturerInfo_t;
flashManufacturerInfo_t FlashManufacturerInfo;
flashManufacturerInfo_t GetFlashManufacturerInfo(void);

void MemoryInit(void);
void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount);
Expand Down
43 changes: 15 additions & 28 deletions Firmware/Chameleon-Mini/Terminal/Commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,23 +97,23 @@ CommandStatusIdType CommandExecConfig(char* OutMessage) {

CommandStatusIdType CommandGetAtqa(char* OutParam) {
uint16_t Atqa;

ApplicationGetAtqa(&Atqa);

// Convert uint16 to uint8 buffer[]
uint8_t atqaBuffer[2] = { 0,0 };
atqaBuffer[1] = (uint8_t)Atqa;
atqaBuffer[0] = Atqa >> 8;

BufferToHexString(OutParam, TERMINAL_BUFFER_SIZE, &atqaBuffer, sizeof(uint16_t));

return COMMAND_INFO_OK_WITH_TEXT_ID;
}

CommandStatusIdType CommandSetAtqa(char* OutMessage, const char* InParam) {
uint8_t AtqaBuffer[2] = { 0, 0 };
uint16_t Atqa = 0;

if (HexStringToBuffer(&AtqaBuffer, sizeof(AtqaBuffer), InParam) != sizeof(uint16_t)) {
// This has to be 4 digits (2 bytes), e.g.: 0004
return COMMAND_ERR_INVALID_PARAM_ID;
Expand All @@ -133,7 +133,7 @@ CommandStatusIdType CommandSetAtqa(char* OutMessage, const char* InParam) {

CommandStatusIdType CommandGetSak(char* OutParam) {
uint8_t Sak;

ApplicationGetSak(&Sak);

BufferToHexString(OutParam, TERMINAL_BUFFER_SIZE, &Sak, sizeof(uint8_t));
Expand All @@ -142,7 +142,7 @@ CommandStatusIdType CommandGetSak(char* OutParam) {

CommandStatusIdType CommandSetSak(char* OutMessage, const char* InParam) {
uint8_t Sak;

if (HexStringToBuffer(&Sak, sizeof(uint8_t), InParam) != sizeof(uint8_t)) {
// This has to be 2 digits (1 byte), e.g.: 04
return COMMAND_ERR_INVALID_PARAM_ID;
Expand Down Expand Up @@ -347,7 +347,7 @@ CommandStatusIdType CommandGetUltralightPassword(char* OutParam) {
return COMMAND_INFO_OK_WITH_TEXT_ID;
}

#ifdef CONFIG_MF_DETECTION_SUPPORT
#ifdef CONFIG_MF_DETECTION_SUPPORT
#define MEM_OFFSET_DETECTION_DATA 4096 + 16
#define MEM_LEN_DETECTION_DATA 192

Expand Down Expand Up @@ -375,7 +375,7 @@ CommandStatusIdType CommandGetUltralightPassword(char* OutParam) {

/* add file integrity to byte !! 209, 210 !! */
ISO14443AAppendCRCA(OutParam, 208);

/* encrypt data , but not CRC*/
ComPass(OutParam, (int)123321, 208);

Expand All @@ -399,29 +399,16 @@ CommandStatusIdType CommandGetUltralightPassword(char* OutParam) {

CommandStatusIdType CommandExecSPIFlashInfo(char* OutMessage)
{
uint8_t b[4];
FlashReadManufacturerDeviceInfo(b);
uint8_t ManufacturerId = b[0];
uint8_t FamilyCode = b[1] >> 5;
uint8_t DensityCode = b[1] & 0x1F;
uint8_t MLC_Code = b[2] >> 5;
uint8_t ProductVersionCode = b[2] & 0x1F;
uint16_t Mbits = 0;
if ((DensityCode >= 2) && (DensityCode <= 8) && (FamilyCode == 1))
Mbits = 1 << (DensityCode - 2);
// Minimum: AT45DB011D Density Code : 00010 = 1-Mbit
// Maximum: AT45DB642D Density Code : 01000 = 64-Mbit
snprintf_P(OutMessage, TERMINAL_BUFFER_SIZE,
PSTR("Manufacturer ID: %02xh\r\nFamily code: %d\r\nDensity code: %d\r\nMLC Code: %d\r\nProduct version: %d\r\nFlash memory size: %d-Mbit (%d-KByte)"),
ManufacturerId, FamilyCode, DensityCode, MLC_Code, ProductVersionCode, Mbits, Mbits * 128);
// Precalculated 1024 / 8 = 128, to prevent uint16_t overflow for possible 64-Mbit flash
snprintf_P(OutMessage, TERMINAL_BUFFER_SIZE,
PSTR("Manufacturer ID: %02x\r\nFamily code: %d\r\nDensity code: %d\r\nMLC Code: %d\r\nProduct version: %d\r\nFlash memory size: %dMbits (%dKBytes)"),
FlashManufacturerInfo.manufacturerId, FlashManufacturerInfo.familyCode, FlashManufacturerInfo.densityCode, FlashManufacturerInfo.MLCCode, FlashManufacturerInfo.productVersionCode, FlashManufacturerInfo.sizeMbits, FlashManufacturerInfo.sizeKbytes);
return COMMAND_INFO_OK_WITH_TEXT_ID;
}

CommandStatusIdType CommandGetSPIFlashInfo(char* OutParam)
{
uint8_t b[4];
FlashReadManufacturerDeviceInfo(b);
snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%02x%02x%02x%02x"), b[0], b[1], b[2], b[3]);
snprintf_P(OutParam, TERMINAL_BUFFER_SIZE,
PSTR("%02x%02x%02x%02x"),
FlashManufacturerInfo.data[0], FlashManufacturerInfo.data[1], FlashManufacturerInfo.data[2], FlashManufacturerInfo.data[3]);
return COMMAND_INFO_OK_WITH_TEXT_ID;
}

0 comments on commit 55030a5

Please sign in to comment.