flash: Move page handling from flashcmd.c to flash.c

Allow the low-level board code to handle each flash page.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-05-16 14:57:55 -04:00 committed by Eric Callahan
parent 9f9a872176
commit 7287670002
3 changed files with 55 additions and 43 deletions

View File

@ -6,7 +6,7 @@
#include <string.h> // memmove #include <string.h> // memmove
#include "autoconf.h" // CONFIG_BLOCK_SIZE #include "autoconf.h" // CONFIG_BLOCK_SIZE
#include "board/flash.h" // flash_write_page #include "board/flash.h" // flash_write_block
#include "board/misc.h" // application_jump #include "board/misc.h" // application_jump
#include "byteorder.h" // cpu_to_le32 #include "byteorder.h" // cpu_to_le32
#include "command.h" // command_respond_ack #include "command.h" // command_respond_ack
@ -57,10 +57,6 @@ DECL_TASK(complete_task);
* Flash commands * Flash commands
****************************************************************/ ****************************************************************/
static uint8_t page_buffer[CONFIG_MAX_FLASH_PAGE_SIZE] __aligned(4);
// Page Tracking
static uint32_t last_page_address = 0;
static uint8_t page_pending = 0;
static uint8_t is_in_transfer; static uint8_t is_in_transfer;
int int
@ -69,15 +65,6 @@ flashcmd_is_in_transfer(void)
return is_in_transfer; return is_in_transfer;
} }
static void
write_page(uint32_t page_address)
{
flash_write_page(page_address, page_buffer);
memset(page_buffer, 0xFF, sizeof(page_buffer));
last_page_address = page_address;
page_pending = 0;
}
void void
command_read_block(uint32_t *data) command_read_block(uint32_t *data)
{ {
@ -93,38 +80,32 @@ void
command_write_block(uint32_t *data) command_write_block(uint32_t *data)
{ {
is_in_transfer = 1; is_in_transfer = 1;
if (command_get_arg_count(data) != (CONFIG_BLOCK_SIZE / 4) + 1) { if (command_get_arg_count(data) != (CONFIG_BLOCK_SIZE / 4) + 1)
command_respond_command_error(); goto fail;
return;
}
uint32_t block_address = le32_to_cpu(data[1]); uint32_t block_address = le32_to_cpu(data[1]);
if (block_address < CONFIG_APPLICATION_START) { if (block_address < CONFIG_APPLICATION_START)
command_respond_command_error(); goto fail;
return; int ret = flash_write_block(block_address, &data[2]);
} if (ret < 0)
uint32_t flash_page_size = flash_get_page_size(); goto fail;
uint32_t page_pos = block_address % flash_page_size;
memcpy(&page_buffer[page_pos], (uint8_t *)&data[2], CONFIG_BLOCK_SIZE);
page_pending = 1;
if (page_pos + CONFIG_BLOCK_SIZE == flash_page_size)
write_page(block_address - page_pos);
uint32_t out[4]; uint32_t out[4];
out[2] = cpu_to_le32(block_address); out[2] = cpu_to_le32(block_address);
command_respond_ack(CMD_RX_BLOCK, out, ARRAY_SIZE(out)); command_respond_ack(CMD_RX_BLOCK, out, ARRAY_SIZE(out));
return;
fail:
command_respond_command_error();
} }
void void
command_eof(uint32_t *data) command_eof(uint32_t *data)
{ {
is_in_transfer = 0; is_in_transfer = 0;
uint32_t flash_page_size = flash_get_page_size(); int ret = flash_complete();
if (page_pending) { if (ret < 0) {
write_page(last_page_address + flash_page_size); command_respond_command_error();
return;
} }
flash_complete();
uint32_t out[4]; uint32_t out[4];
out[2] = cpu_to_le32( out[2] = cpu_to_le32(ret);
((last_page_address - CONFIG_APPLICATION_START)
/ flash_page_size) + 1);
command_respond_ack(CMD_RX_EOF, out, ARRAY_SIZE(out)); command_respond_ack(CMD_RX_EOF, out, ARRAY_SIZE(out));
} }

View File

@ -4,9 +4,10 @@
// //
// This file may be distributed under the terms of the GNU GPLv3 license. // This file may be distributed under the terms of the GNU GPLv3 license.
#include <string.h> // memset
#include "autoconf.h" // CONFIG_MACH_STM32F103 #include "autoconf.h" // CONFIG_MACH_STM32F103
#include "board/io.h" // writew #include "board/io.h" // writew
#include "flash.h" // flash_write_page #include "flash.h" // flash_write_block
#include "internal.h" // FLASH #include "internal.h" // FLASH
#define STM32F4_MIN_SECTOR_SIZE 16384 #define STM32F4_MIN_SECTOR_SIZE 16384
@ -16,7 +17,7 @@
#define FLASH_KEY2 (0xCDEF89ABUL) #define FLASH_KEY2 (0xCDEF89ABUL)
#endif #endif
uint32_t static uint32_t
flash_get_page_size(void) flash_get_page_size(void)
{ {
if (CONFIG_MACH_STM32F103) { if (CONFIG_MACH_STM32F103) {
@ -122,7 +123,7 @@ flash_write_stm32f1xx(uint32_t page_address, uint16_t *data)
#endif #endif
} }
void static void
flash_write_page(uint32_t page_address, void *data) flash_write_page(uint32_t page_address, void *data)
{ {
if (CONFIG_MACH_STM32F4) { if (CONFIG_MACH_STM32F4) {
@ -132,8 +133,39 @@ flash_write_page(uint32_t page_address, void *data)
} }
} }
void static uint8_t page_buffer[CONFIG_MAX_FLASH_PAGE_SIZE] __aligned(4);
// Page Tracking
static uint32_t last_page_address = 0;
static uint8_t page_pending = 0;
static void
write_page(uint32_t page_address)
{
flash_write_page(page_address, page_buffer);
memset(page_buffer, 0xFF, sizeof(page_buffer));
last_page_address = page_address;
page_pending = 0;
}
int
flash_write_block(uint32_t block_address, uint32_t *data)
{
uint32_t flash_page_size = flash_get_page_size();
uint32_t page_pos = block_address % flash_page_size;
memcpy(&page_buffer[page_pos], (uint8_t *)&data[2], CONFIG_BLOCK_SIZE);
page_pending = 1;
if (page_pos + CONFIG_BLOCK_SIZE == flash_page_size)
write_page(block_address - page_pos);
return 0;
}
int
flash_complete(void) flash_complete(void)
{ {
lock_flash(); uint32_t flash_page_size = flash_get_page_size();
if (page_pending) {
write_page(last_page_address + flash_page_size);
}
return ((last_page_address - CONFIG_APPLICATION_START)
/ flash_page_size) + 1;
} }

View File

@ -3,8 +3,7 @@
#include <stdint.h> #include <stdint.h>
uint32_t flash_get_page_size(void); int flash_write_block(uint32_t block_address, uint32_t *data);
void flash_complete(void); int flash_complete(void);
void flash_write_page(uint32_t page_address, void *data);
#endif #endif