|
From: Paul F. <fer...@gm...> - 2001-09-17 00:00:00
|
This patch implements flashing EEPROM over JTAG, represented as bank 1.
Tested on atmega128.
Signed-off-by: Paul Fertser <fer...@gm...>
---
src/flash/nor/avrf.c | 87 +++++++++++++++++++++++++++++++++++++++++++----
src/flash/nor/avrf.h | 7 ++++
tcl/target/mega128.cfg | 6 +++-
3 files changed, 91 insertions(+), 9 deletions(-)
diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c
index 6c2d17f..2a67a08 100644
--- a/src/flash/nor/avrf.c
+++ b/src/flash/nor/avrf.c
@@ -180,11 +180,61 @@ static int avr_jtagprg_writeflashpage(struct avr_common *avr, uint8_t *page_buf,
return ERROR_OK;
}
+static int avr_jtagprg_writeeeprompage(struct avr_common *avr, uint8_t *page_buf, uint32_t buf_size, uint32_t addr, uint32_t page_size)
+{
+ uint32_t i, poll_value;
+
+ avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2311, AVR_JTAG_REG_ProgrammingCommand_Len);
+
+ // load addr high byte
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x0700 | ((addr >> 8) & 0xFF), AVR_JTAG_REG_ProgrammingCommand_Len);
+ for (i = 0; i < page_size; i++)
+ {
+ // load addr low byte
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x0300 | (addr & 0xFF), AVR_JTAG_REG_ProgrammingCommand_Len);
+ addr++;
+
+ if (i < buf_size)
+ {
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x1300 | page_buf[i], AVR_JTAG_REG_ProgrammingCommand_Len);
+ }
+ else
+ {
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x13FF, AVR_JTAG_REG_ProgrammingCommand_Len);
+ }
+ // latch data
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len);
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x7700, AVR_JTAG_REG_ProgrammingCommand_Len);
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len);
+ }
+
+ // write page
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3300, AVR_JTAG_REG_ProgrammingCommand_Len);
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3100, AVR_JTAG_REG_ProgrammingCommand_Len);
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3300, AVR_JTAG_REG_ProgrammingCommand_Len);
+ avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3300, AVR_JTAG_REG_ProgrammingCommand_Len);
+
+ do {
+ poll_value = 0;
+ avr_jtag_senddat(avr->jtag_info.tap, &poll_value, 0x3300, AVR_JTAG_REG_ProgrammingCommand_Len);
+ if (ERROR_OK != mcu_execute_queue())
+ {
+ return ERROR_FAIL;
+ }
+ LOG_DEBUG("poll_value = 0x%04" PRIx32 "", poll_value);
+ } while (!(poll_value & 0x0200));
+
+ return ERROR_OK;
+}
+
+
FLASH_BANK_COMMAND_HANDLER(avrf_flash_bank_command)
{
struct avrf_flash_bank *avrf_info;
+ int is_flash;
- if (CMD_ARGC < 6)
+ if (CMD_ARGC < 7)
{
LOG_WARNING("incomplete flash_bank avr configuration");
return ERROR_FLASH_BANK_INVALID;
@@ -194,6 +244,8 @@ FLASH_BANK_COMMAND_HANDLER(avrf_flash_bank_command)
bank->driver_priv = avrf_info;
avrf_info->probed = 0;
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[6], is_flash);
+ avrf_info->type = is_flash;
return ERROR_OK;
}
@@ -248,7 +300,14 @@ static int avrf_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset,
{
cur_buffer_size = count;
}
- avr_jtagprg_writeflashpage(avr, buffer + cur_size, cur_buffer_size, offset + cur_size, page_size);
+ if (((struct avrf_flash_bank*)(bank->driver_priv))->type == FLASH)
+ {
+ avr_jtagprg_writeflashpage(avr, buffer + cur_size, cur_buffer_size, offset + cur_size, page_size );
+ }
+ else
+ {
+ avr_jtagprg_writeeeprompage(avr, buffer + cur_size, cur_buffer_size, offset + cur_size, page_size );
+ }
count -= cur_buffer_size;
cur_size += cur_buffer_size;
@@ -302,16 +361,28 @@ static int avrf_probe(struct flash_bank *bank)
if (avr_info != NULL)
{
+ int page_size;
+ int page_num;
+
+ if (avrf_info->type == FLASH) {
+ page_size = avr_info->flash_page_size;
+ page_num = avr_info->flash_page_num;
+ } else {
+ page_size = avr_info->eeprom_page_size;
+ page_num = avr_info->eeprom_page_num;
+ }
+
// chip found
bank->base = 0x00000000;
- bank->size = (avr_info->flash_page_size * avr_info->flash_page_num);
- bank->num_sectors = avr_info->flash_page_num;
- bank->sectors = malloc(sizeof(struct flash_sector) * avr_info->flash_page_num);
- for (i = 0; i < avr_info->flash_page_num; i++)
+ bank->size = (page_size * page_num);
+ bank->num_sectors = page_num;
+ bank->sectors = malloc(sizeof(struct flash_sector) * page_num);
+
+ for (i = 0; i < page_num; i++)
{
- bank->sectors[i].offset = i * avr_info->flash_page_size;
- bank->sectors[i].size = avr_info->flash_page_size;
+ bank->sectors[i].offset = i * page_size;
+ bank->sectors[i].size = page_size;
bank->sectors[i].is_erased = -1;
bank->sectors[i].is_protected = 1;
}
diff --git a/src/flash/nor/avrf.h b/src/flash/nor/avrf.h
index 1a69e86..43bd523 100644
--- a/src/flash/nor/avrf.h
+++ b/src/flash/nor/avrf.h
@@ -30,10 +30,17 @@ struct avrf_type
int eeprom_page_num;
};
+enum flash_type
+{
+ FLASH,
+ EEPROM
+};
+
struct avrf_flash_bank
{
int ppage_size;
int probed;
+ enum flash_type type;
};
#endif /* AVRF_H */
diff --git a/tcl/target/mega128.cfg b/tcl/target/mega128.cfg
index 2cf31d6..94bbfd2 100644
--- a/tcl/target/mega128.cfg
+++ b/tcl/target/mega128.cfg
@@ -23,7 +23,10 @@ target create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME
#$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0
set _FLASHNAME $_CHIPNAME.flash
-flash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME
+# flash
+flash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME 0
+# eeprom
+flash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME 1
#to use it, script will be like:
#init
@@ -36,6 +39,7 @@ flash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME
#poll
#avr mass_erase 0
#flash write_image E:/Versaloon/Software/CAMERAPROTOCOLAGENT.hex
+#flash write_bank 1 E:/Versaloon/Software/CAMERAPROTOCOLAGENT.eeprom.bin 0
#reset run
#shutdown
#
--
1.5.6.5
--cPi+lWm09sJ+d57q--
|