Skip to content

Commit

Permalink
ARMmbed#112 Add I2C Encoding window command for filesystem parser wor…
Browse files Browse the repository at this point in the history
…karound
  • Loading branch information
gerargz authored and microbit-carlos committed Aug 24, 2021
1 parent a11edd8 commit 096519d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
40 changes: 40 additions & 0 deletions source/board/microbitv2/i2c_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,44 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
}
break;
case gFlashCfgEncWindow_c:
if (size == 1) {
/* If size is 1 (only cmd id), this means it's a read */
uint32_t tempFileEncWindowStart = __REV(gflashConfig.fileEncWindowStart);
uint32_t tempFileEncWindowEnd = __REV(gflashConfig.fileEncWindowEnd);
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
i2c_fillBuffer((uint8_t*) &tempFileEncWindowStart, 1, sizeof(gflashConfig.fileEncWindowStart));
i2c_fillBuffer((uint8_t*) &tempFileEncWindowEnd, 5, sizeof(gflashConfig.fileEncWindowEnd));
} else if (size == 9) {
/* If size is 9 (cmd id + 8B data), this means it's a write */
uint32_t tempFileEncWindowStart = pI2cCommand->cmdData.data[0] << 24 |
pI2cCommand->cmdData.data[1] << 16 |
pI2cCommand->cmdData.data[2] << 8 |
pI2cCommand->cmdData.data[3] << 0;
uint32_t tempFileEncWindowEnd = pI2cCommand->cmdData.data[4] << 24 |
pI2cCommand->cmdData.data[5] << 16 |
pI2cCommand->cmdData.data[6] << 8 |
pI2cCommand->cmdData.data[7] << 0;

/* Validate encoding window */
if (tempFileEncWindowStart <= tempFileEncWindowEnd) {
gflashConfig.fileEncWindowStart = tempFileEncWindowStart;
tempFileEncWindowStart = __REV(gflashConfig.fileEncWindowStart);
gflashConfig.fileEncWindowEnd = tempFileEncWindowEnd;
tempFileEncWindowEnd = __REV(gflashConfig.fileEncWindowEnd);

i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
i2c_fillBuffer((uint8_t*) &tempFileEncWindowStart, 1, sizeof(gflashConfig.fileEncWindowStart));
i2c_fillBuffer((uint8_t*) &tempFileEncWindowEnd, 5, sizeof(gflashConfig.fileEncWindowEnd));
} else {
pI2cCommand->cmdId = gFlashError_c;
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
}
} else {
pI2cCommand->cmdId = gFlashError_c;
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
}
break;
case gFlashCfgFileVisible_c:
if (size == 1) {
/* If size is 1 (only cmd id), this means it's a read */
Expand Down Expand Up @@ -658,6 +696,8 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
memcpy(gflashConfig.fileName, FLASH_CFG_FILENAME, 11);
gflashConfig.fileSize = FLASH_CFG_FILESIZE;
gflashConfig.fileVisible = FLASH_CFG_FILEVISIBLE;
gflashConfig.fileEncWindowStart = 0;
gflashConfig.fileEncWindowEnd = 0;
}
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
break;
Expand Down
3 changes: 3 additions & 0 deletions source/board/microbitv2/i2c_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ typedef __PACKED_STRUCT flashConfig_tag {
vfs_filename_t fileName;
uint32_t fileSize;
bool fileVisible;
uint32_t fileEncWindowStart;
uint32_t fileEncWindowEnd;
} flashConfig_t;

/*! Flash interface command type */
Expand All @@ -136,6 +138,7 @@ typedef enum flashCmdId_tag {
gFlashStorageSize_c = 0x06,
gFlashSectorSize_c = 0x07,
gFlashRemountMSD_c = 0x08,
gFlashCfgEncWindow_c = 0x09,
gFlashDataRead_c = 0x0A,
gFlashDataWrite_c = 0x0B,
gFlashDataErase_c = 0x0C,
Expand Down
32 changes: 29 additions & 3 deletions source/board/microbitv2/microbitv2.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ flashConfig_t gflashConfig = {
.fileName = FLASH_CFG_FILENAME,
.fileSize = FLASH_CFG_FILESIZE,
.fileVisible = FLASH_CFG_FILEVISIBLE,
.fileEncWindowStart = 0,
.fileEncWindowEnd = 0,
};

typedef enum {
Expand Down Expand Up @@ -528,7 +530,8 @@ void vfs_user_build_filesystem_hook() {
}
}

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

if (gflashConfig.fileVisible) {
vfs_create_file(gflashConfig.fileName, read_file_data_txt, 0, file_size);
Expand All @@ -538,9 +541,32 @@ void vfs_user_build_filesystem_hook() {
// File callback to be used with vfs_add_file to return file contents
static uint32_t read_file_data_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
{
uint32_t read_address = FLASH_STORAGE_ADDRESS + (VFS_SECTOR_SIZE * sector_offset);
uint32_t encoded_data_offset = (gflashConfig.fileEncWindowEnd - gflashConfig.fileEncWindowStart);

// Ignore out of bound reads
if ( (FLASH_STORAGE_ADDRESS + VFS_SECTOR_SIZE * sector_offset) < (FLASH_CONFIG_ADDRESS + FLASH_INTERFACE_SIZE) ) {
memcpy(data, (uint8_t *) (FLASH_STORAGE_ADDRESS + VFS_SECTOR_SIZE * sector_offset), VFS_SECTOR_SIZE);
if ( read_address < (FLASH_CONFIG_ADDRESS + FLASH_INTERFACE_SIZE + encoded_data_offset) ) {
for (uint32_t i = 0; i < VFS_SECTOR_SIZE; i++) {
if (i + (VFS_SECTOR_SIZE * sector_offset) < gflashConfig.fileEncWindowStart) {
// If data is before encoding window, no offset is needed
data[i] = *(uint8_t *) (read_address + i);
} else if(i + (VFS_SECTOR_SIZE * sector_offset) < (gflashConfig.fileEncWindowStart + encoded_data_offset * 2)) {
// Data inside encoding window needs to consider encoding window start and size
uint8_t enc_byte = *(uint8_t *) (FLASH_STORAGE_ADDRESS + ((VFS_SECTOR_SIZE * sector_offset) + gflashConfig.fileEncWindowStart + i ) / 2);
if (i % 2 == 0) {
// High nibble
enc_byte = 0x0F & (enc_byte >> 4);
} else {
// Low nibble
enc_byte = 0x0F & enc_byte;
}
// Encode one nibble to one ASCII byte
data[i] = enc_byte <= 9 ? enc_byte + 0x30 : enc_byte + 0x37;
} else {
// If data is after encoding window, adjustment is needed
data[i] = *(uint8_t *) (read_address + i - encoded_data_offset);
}
}
}

return VFS_SECTOR_SIZE;
Expand Down

0 comments on commit 096519d

Please sign in to comment.