Skip to content

Commit 096519d

Browse files
gerargzmicrobit-carlos
authored andcommitted
ARMmbed#112 Add I2C Encoding window command for filesystem parser workaround
1 parent a11edd8 commit 096519d

File tree

3 files changed

+72
-3
lines changed

3 files changed

+72
-3
lines changed

source/board/microbitv2/i2c_commands.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,44 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
615615
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
616616
}
617617
break;
618+
case gFlashCfgEncWindow_c:
619+
if (size == 1) {
620+
/* If size is 1 (only cmd id), this means it's a read */
621+
uint32_t tempFileEncWindowStart = __REV(gflashConfig.fileEncWindowStart);
622+
uint32_t tempFileEncWindowEnd = __REV(gflashConfig.fileEncWindowEnd);
623+
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
624+
i2c_fillBuffer((uint8_t*) &tempFileEncWindowStart, 1, sizeof(gflashConfig.fileEncWindowStart));
625+
i2c_fillBuffer((uint8_t*) &tempFileEncWindowEnd, 5, sizeof(gflashConfig.fileEncWindowEnd));
626+
} else if (size == 9) {
627+
/* If size is 9 (cmd id + 8B data), this means it's a write */
628+
uint32_t tempFileEncWindowStart = pI2cCommand->cmdData.data[0] << 24 |
629+
pI2cCommand->cmdData.data[1] << 16 |
630+
pI2cCommand->cmdData.data[2] << 8 |
631+
pI2cCommand->cmdData.data[3] << 0;
632+
uint32_t tempFileEncWindowEnd = pI2cCommand->cmdData.data[4] << 24 |
633+
pI2cCommand->cmdData.data[5] << 16 |
634+
pI2cCommand->cmdData.data[6] << 8 |
635+
pI2cCommand->cmdData.data[7] << 0;
636+
637+
/* Validate encoding window */
638+
if (tempFileEncWindowStart <= tempFileEncWindowEnd) {
639+
gflashConfig.fileEncWindowStart = tempFileEncWindowStart;
640+
tempFileEncWindowStart = __REV(gflashConfig.fileEncWindowStart);
641+
gflashConfig.fileEncWindowEnd = tempFileEncWindowEnd;
642+
tempFileEncWindowEnd = __REV(gflashConfig.fileEncWindowEnd);
643+
644+
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
645+
i2c_fillBuffer((uint8_t*) &tempFileEncWindowStart, 1, sizeof(gflashConfig.fileEncWindowStart));
646+
i2c_fillBuffer((uint8_t*) &tempFileEncWindowEnd, 5, sizeof(gflashConfig.fileEncWindowEnd));
647+
} else {
648+
pI2cCommand->cmdId = gFlashError_c;
649+
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
650+
}
651+
} else {
652+
pI2cCommand->cmdId = gFlashError_c;
653+
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
654+
}
655+
break;
618656
case gFlashCfgFileVisible_c:
619657
if (size == 1) {
620658
/* If size is 1 (only cmd id), this means it's a read */
@@ -658,6 +696,8 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
658696
memcpy(gflashConfig.fileName, FLASH_CFG_FILENAME, 11);
659697
gflashConfig.fileSize = FLASH_CFG_FILESIZE;
660698
gflashConfig.fileVisible = FLASH_CFG_FILEVISIBLE;
699+
gflashConfig.fileEncWindowStart = 0;
700+
gflashConfig.fileEncWindowEnd = 0;
661701
}
662702
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
663703
break;

source/board/microbitv2/i2c_commands.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ typedef __PACKED_STRUCT flashConfig_tag {
124124
vfs_filename_t fileName;
125125
uint32_t fileSize;
126126
bool fileVisible;
127+
uint32_t fileEncWindowStart;
128+
uint32_t fileEncWindowEnd;
127129
} flashConfig_t;
128130

129131
/*! Flash interface command type */
@@ -136,6 +138,7 @@ typedef enum flashCmdId_tag {
136138
gFlashStorageSize_c = 0x06,
137139
gFlashSectorSize_c = 0x07,
138140
gFlashRemountMSD_c = 0x08,
141+
gFlashCfgEncWindow_c = 0x09,
139142
gFlashDataRead_c = 0x0A,
140143
gFlashDataWrite_c = 0x0B,
141144
gFlashDataErase_c = 0x0C,

source/board/microbitv2/microbitv2.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ flashConfig_t gflashConfig = {
7171
.fileName = FLASH_CFG_FILENAME,
7272
.fileSize = FLASH_CFG_FILESIZE,
7373
.fileVisible = FLASH_CFG_FILEVISIBLE,
74+
.fileEncWindowStart = 0,
75+
.fileEncWindowEnd = 0,
7476
};
7577

7678
typedef enum {
@@ -528,7 +530,8 @@ void vfs_user_build_filesystem_hook() {
528530
}
529531
}
530532

531-
file_size = gflashConfig.fileSize;
533+
// Add encoding window file size. 1B encoded into 2B ASCII
534+
file_size = gflashConfig.fileSize + (gflashConfig.fileEncWindowEnd - gflashConfig.fileEncWindowStart);
532535

533536
if (gflashConfig.fileVisible) {
534537
vfs_create_file(gflashConfig.fileName, read_file_data_txt, 0, file_size);
@@ -538,9 +541,32 @@ void vfs_user_build_filesystem_hook() {
538541
// File callback to be used with vfs_add_file to return file contents
539542
static uint32_t read_file_data_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
540543
{
544+
uint32_t read_address = FLASH_STORAGE_ADDRESS + (VFS_SECTOR_SIZE * sector_offset);
545+
uint32_t encoded_data_offset = (gflashConfig.fileEncWindowEnd - gflashConfig.fileEncWindowStart);
546+
541547
// Ignore out of bound reads
542-
if ( (FLASH_STORAGE_ADDRESS + VFS_SECTOR_SIZE * sector_offset) < (FLASH_CONFIG_ADDRESS + FLASH_INTERFACE_SIZE) ) {
543-
memcpy(data, (uint8_t *) (FLASH_STORAGE_ADDRESS + VFS_SECTOR_SIZE * sector_offset), VFS_SECTOR_SIZE);
548+
if ( read_address < (FLASH_CONFIG_ADDRESS + FLASH_INTERFACE_SIZE + encoded_data_offset) ) {
549+
for (uint32_t i = 0; i < VFS_SECTOR_SIZE; i++) {
550+
if (i + (VFS_SECTOR_SIZE * sector_offset) < gflashConfig.fileEncWindowStart) {
551+
// If data is before encoding window, no offset is needed
552+
data[i] = *(uint8_t *) (read_address + i);
553+
} else if(i + (VFS_SECTOR_SIZE * sector_offset) < (gflashConfig.fileEncWindowStart + encoded_data_offset * 2)) {
554+
// Data inside encoding window needs to consider encoding window start and size
555+
uint8_t enc_byte = *(uint8_t *) (FLASH_STORAGE_ADDRESS + ((VFS_SECTOR_SIZE * sector_offset) + gflashConfig.fileEncWindowStart + i ) / 2);
556+
if (i % 2 == 0) {
557+
// High nibble
558+
enc_byte = 0x0F & (enc_byte >> 4);
559+
} else {
560+
// Low nibble
561+
enc_byte = 0x0F & enc_byte;
562+
}
563+
// Encode one nibble to one ASCII byte
564+
data[i] = enc_byte <= 9 ? enc_byte + 0x30 : enc_byte + 0x37;
565+
} else {
566+
// If data is after encoding window, adjustment is needed
567+
data[i] = *(uint8_t *) (read_address + i - encoded_data_offset);
568+
}
569+
}
544570
}
545571

546572
return VFS_SECTOR_SIZE;

0 commit comments

Comments
 (0)