Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions source/board/steami/steami32.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ typedef enum {

TASK_READ_SECTOR,

TASK_WRITE_CONFIG,
TASK_READ_CONFIG,
TASK_CLEAR_CONFIG,

TASK_WAIT_FLASH_BUSY,
} steami_task;

Expand Down Expand Up @@ -205,6 +209,40 @@ static void on_I2C_receive_command(steami_i2c_command cmd, uint8_t* rx, uint16_t
break;
}

case WRITE_CONFIG:{
if(is_busy()){
steami_uart_write_string("ERROR I2C busy.\n");
break;
}
if(rx_len < 3){
error_status_bad_parameter(&status_error);
break;
}
current_task = TASK_WRITE_CONFIG;
memcpy(task_rx, rx, rx_len);
task_rx_len = rx_len;
break;
}

case READ_CONFIG:{
if(is_busy()){
steami_uart_write_string("ERROR I2C busy.\n");
break;
}
current_task = TASK_READ_CONFIG;
memcpy(task_rx, rx, rx_len);
task_rx_len = rx_len;
break;
}

case CLEAR_CONFIG:
if(is_busy()){
steami_uart_write_string("ERROR I2C busy.\n");
break;
}
current_task = TASK_CLEAR_CONFIG;
break;

case STATUS:{
uint8_t status = 0x00;

Expand Down Expand Up @@ -394,6 +432,69 @@ void process_task()
}


case TASK_WRITE_CONFIG:{
if( steami_flash_is_busy() ){
break;
}
// task_rx: [offset_hi, offset_lo, len, data...]
if( task_rx_len >= 3 ){
uint16_t offset = ((uint16_t)task_rx[0] << 8) | task_rx[1];
uint16_t len = task_rx[2];
if( len > task_rx_len - 3 ){
error_status_bad_parameter(&status_error);
steami_uart_write_string("ERROR Bad config write parameters.\n");
}
else if( steami_flash_write_config(offset, task_rx + 3, len) ){
steami_uart_write_string("Config written.\n");
}
else{
error_status_set_last_command_fail(&status_error);
steami_uart_write_string("ERROR Unable to write config.\n");
}
}
else{
error_status_bad_parameter(&status_error);
}
current_task = TASK_NONE;
break;
}

case TASK_READ_CONFIG:{
if( steami_flash_is_busy() ){
break;
}
if( task_rx_len == 2 ){
uint16_t offset = ((uint16_t)task_rx[0] << 8) | task_rx[1];
if( steami_flash_read_config(offset, buffer_sector, STEAMI_FLASH_SECTOR) ){
steami_i2c_set_tx_data(buffer_sector, STEAMI_FLASH_SECTOR);
}
else{
error_status_set_last_command_fail(&status_error);
steami_uart_write_string("ERROR Unable to read config.\n");
}
}
else{
error_status_bad_parameter(&status_error);
}
current_task = TASK_NONE;
break;
}

case TASK_CLEAR_CONFIG:{
if( steami_flash_is_busy() ){
break;
}
if( steami_flash_erase_config() ){
steami_uart_write_string("Config erased.\n");
}
else{
error_status_set_last_command_fail(&status_error);
steami_uart_write_string("ERROR Unable to erase config.\n");
}
current_task = TASK_NONE;
break;
}

case TASK_WAIT_FLASH_BUSY:
if( !steami_flash_is_busy() ){
current_task = TASK_NONE;
Expand Down
47 changes: 46 additions & 1 deletion source/board/steami/steami_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ uint32_t steami_flash_get_size(){

for(uint16_t i = 0; i < STEAMI_FLASH_MAX_DATA_SIZE; ++i){
if( data[i] == 0xFF ){
return STEAMI_FLASH_FILE_ADDR + offset + i;
return offset + i;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Restore file-base offset before programming appended data

Changing steami_flash_get_size() to return offset + i makes the size relative to the file partition, but steami_flash_append_file() still uses that value as an absolute flash address in w25q64_page_program. With STEAMI_FLASH_FILE_ADDR now non-zero, WRITE_DATA writes into 0x000000 (config area) while reads/size scans start at 0x001000, so appended file data is not visible in the MSC file and config bytes can be corrupted.

Useful? React with 👍 / 👎.

}
}

Expand Down Expand Up @@ -219,4 +219,49 @@ uint16_t steami_flash_read_file(uint8_t* data, uint16_t data_len, uint32_t offse

bool steami_flash_is_busy(){
return w25q64_is_busy();
}

bool steami_flash_erase_config(){
steami_led_turn_on_blue();

w25q64_write_enable();
wait_w25q64_wel();
wait_w25q64_busy();
bool result = w25q64_sector_erase(STEAMI_FLASH_CONFIG_ADDR);
wait_w25q64_busy();

steami_led_turn_off_blue();
return result;
}

bool steami_flash_write_config(uint16_t offset, uint8_t* data, uint16_t len){
if( len == 0 || len > 256 ){
return false;
}
if( offset + len > STEAMI_FLASH_CONFIG_SIZE ){
return false;
}
if( (offset % 256) + len > 256 ){
return false;
}

steami_led_turn_on_blue();

w25q64_write_enable();
wait_w25q64_wel();
wait_w25q64_busy();
bool result = w25q64_page_program(data, STEAMI_FLASH_CONFIG_ADDR + offset, len);
wait_w25q64_busy();

steami_led_turn_off_blue();
return result;
}

bool steami_flash_read_config(uint16_t offset, uint8_t* data, uint16_t len){
if( offset + len > STEAMI_FLASH_CONFIG_SIZE ){
return false;
}

wait_w25q64_busy();
return w25q64_read_data(data, STEAMI_FLASH_CONFIG_ADDR + offset, len);
}
37 changes: 33 additions & 4 deletions source/board/steami/steami_flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
#include <stdint.h>
#include <stdbool.h>

#define STEAMI_FLASH_FILE_ADDR (uint32_t)0x00000000
#define STEAMI_FLASH_NAME_ADDR (uint32_t)0x007FF000
#define STEAMI_FLASH_FILE_ADDR (uint32_t)0x00000000
#define STEAMI_FLASH_CONFIG_ADDR (uint32_t)0x007FE000 /* last 4K before filename */
#define STEAMI_FLASH_CONFIG_SIZE 4096
#define STEAMI_FLASH_NAME_ADDR (uint32_t)0x007FF000

#define STEAMI_FLASH_FILE_SIZE 8384512
#define STEAMI_FLASH_FILE_SIZE 8380416 /* 0x7FE000 - 0x000000 (excludes config) */

#define STEAMI_FLASH_SECTOR 256
#define STEAMI_FLASH_4K 4096
Expand Down Expand Up @@ -108,4 +110,31 @@ uint16_t steami_flash_read_file(uint8_t* data, uint16_t data_len, uint32_t offse
*
* @return TRUE if the flash is buzy flag is high, FALSE otherwise
*/
bool steami_flash_is_busy();
bool steami_flash_is_busy();

/**
* @brief Erase the 4K config zone at STEAMI_FLASH_CONFIG_ADDR.
*
* @return TRUE if successful, FALSE otherwise
*/
bool steami_flash_erase_config();

/**
* @brief Write data to the config zone.
*
* @param offset byte offset within the config zone (0-4095)
* @param data data array
* @param len number of bytes to write (max 28 per call via I2C, must stay within one 256-byte page)
* @return TRUE if successful, FALSE otherwise
*/
bool steami_flash_write_config(uint16_t offset, uint8_t* data, uint16_t len);

/**
* @brief Read data from the config zone.
*
* @param offset byte offset within the config zone (0-4095)
* @param data buffer for read data
* @param len number of bytes to read
* @return TRUE if successful, FALSE otherwise
*/
bool steami_flash_read_config(uint16_t offset, uint8_t* data, uint16_t len);
12 changes: 12 additions & 0 deletions source/board/steami/steami_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ static bool is_command_valid(uint8_t cmd){
case GET_FILENAME:
case WRITE_DATA:
case READ_SECTOR:
case WRITE_CONFIG:
case READ_CONFIG:
case CLEAR_CONFIG:
case STATUS:
case ERROR_STATUS:
return true;
Expand Down Expand Up @@ -65,6 +68,15 @@ static uint16_t get_argument_byte_number(uint8_t cmd){
case READ_SECTOR:
return 2;

case WRITE_CONFIG:
return 31; /* fixed frame: [offset_hi, offset_lo, len, data(28 bytes max)] */

case READ_CONFIG:
return 2;

case CLEAR_CONFIG:
return 0;

case STATUS:
return 0;

Expand Down
6 changes: 5 additions & 1 deletion source/board/steami/steami_i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ typedef enum {
WRITE_DATA = 0x11,

READ_SECTOR = 0x20,


WRITE_CONFIG = 0x30,
READ_CONFIG = 0x31,
CLEAR_CONFIG = 0x32,

STATUS = 0x80,
ERROR_STATUS = 0x81,
} steami_i2c_command;
Expand Down