This patch add the below commands (just for determining stuff).

 1. read_bits for reading Fuse/Lock bits.
 2. read_byte for reading Signature/Calibration byte.

 Usage as below:
 1. avrf read_bits <bank>
 2. avrf read_byte <bank> <type> <addr>
    <type> is the type of byte you want to read.
    <addr> is the location of that byte.

 If succeed, it will show you the bits/byte on terminal.
 Tested in at90scr100.

 No write function as it's too *dangerous*.

 Regards.


Signed-off-by: zeal <[email protected]>
---
 src/flash/nor/avrf.c |  188 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 188 insertions(+), 0 deletions(-)

diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c
index 4dc7c23..ab2c6ed 100644
--- a/src/flash/nor/avrf.c
+++ b/src/flash/nor/avrf.c
@@ -57,6 +57,7 @@ static struct avrf_type avft_chips_info[] =
  */
        {"atmega128",   0x9702, 256, 512, 8, 512},
        {"at90can128",  0x9781, 256, 512, 8, 512},
+       {"at90scr100",  0x96C1, 256, 256, 32, 128},
 };
 
 /* avr program functions */
@@ -123,6 +124,7 @@ static int avr_jtagprg_chiperase(struct avr_common *avr)
        return ERROR_OK;
 }
 
+
 static int avr_jtagprg_writeflashpage(struct avr_common *avr, uint8_t 
*page_buf, uint32_t buf_size, uint32_t addr, uint32_t page_size)
 {
        uint32_t i, poll_value;
@@ -464,6 +466,180 @@ COMMAND_HANDLER(avrf_handle_mass_erase_command)
        return ERROR_OK;
 }
 
+static int avr_jtagprg_readbits(struct avr_common *avr)
+{
+       uint32_t ext = 0, hi = 0, lo = 0, lock = 0;
+
+       avr_jtag_sendinstr(avr->jtag_info.tap, NULL, 
AVR_JTAG_INS_PROG_COMMANDS);
+       // Enter Fuse/Lock Bit Read
+       avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2304, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+       // Read Fuses and Lock Bits
+       avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3A00, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+       avr_jtag_senddat(avr->jtag_info.tap, &ext, 0x3E00, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+       avr_jtag_senddat(avr->jtag_info.tap, &hi, 0x3200, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+       avr_jtag_senddat(avr->jtag_info.tap, &lo, 0x3600, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+       avr_jtag_senddat(avr->jtag_info.tap, &lock, 0x3700, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+
+       if (ERROR_OK != mcu_execute_queue())
+       {
+               LOG_INFO("failure");
+               return ERROR_FAIL;
+       }
+
+       LOG_INFO("Fuse Ext byte  = 0x%02" PRIx32 "", (uint8_t)ext);
+       LOG_INFO("Fuse High byte = 0x%02" PRIx32 "", (uint8_t)hi);
+       LOG_INFO("Fuse Low byte  = 0x%02" PRIx32 "", (uint8_t)lo);
+       LOG_INFO("Lock bits      = 0x%02" PRIx32 "", (uint8_t)lock);
+       return ERROR_OK;
+}
+
+static int avrf_read_bits(struct flash_bank *bank)
+{
+       struct target *target = bank->target;
+       struct avr_common *avr = target->arch_info;
+
+       if (target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       if ((ERROR_OK != avr_jtagprg_enterprogmode(avr))
+               || (ERROR_OK != avr_jtagprg_readbits(avr))
+               || (ERROR_OK != avr_jtagprg_leaveprogmode(avr)))
+       {
+               return ERROR_FAIL;
+       }
+
+       return ERROR_OK;
+}
+
+/* XXX: Check your actually 'read_bits' commands before using it. */
+COMMAND_HANDLER(avrf_handle_read_bits_command)
+{
+       if (CMD_ARGC < 1)
+       {
+               command_print(CMD_CTX, "avr read_bits <bank>");
+               return ERROR_OK;
+       }
+
+       struct flash_bank *bank;
+       int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+       if (ERROR_OK != retval)
+               return retval;
+
+       if (avrf_read_bits(bank) == ERROR_OK)
+       {
+               command_print(CMD_CTX, "avr read bits success");
+       }
+       else
+       {
+               command_print(CMD_CTX, "avr read bits failure");
+       }
+
+       LOG_DEBUG("%s", __FUNCTION__);
+       return ERROR_OK;
+}
+
+/* avrf read_byte <bank> <type> <addr> */
+#define AVR_READ_BYTE_TYPE_SIGN        0x00    /* for Signature byte */
+#define AVR_READ_BYTE_TYPE_CALI        0x01    /* for Calibration byte */
+#define AVR_READ_BYTE_TYPE_UNKNOWN     0x02    /* unknown type */
+
+static int avr_jtagprg_readbyte(struct avr_common *avr, uint8_t type, uint8_t 
addr)
+{
+       uint32_t res;
+
+       avr_jtag_sendinstr(avr->jtag_info.tap, NULL, 
AVR_JTAG_INS_PROG_COMMANDS);
+       // Enter XXX Byte Read
+       avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2308, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+       // Load Address Byte
+       avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x0300 | addr, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+       // Read XXX Byte
+       if (type != AVR_READ_BYTE_TYPE_SIGN && type != 
AVR_READ_BYTE_TYPE_UNKNOWN)
+               return ERROR_FAIL;
+
+       if (type == AVR_READ_BYTE_TYPE_SIGN) {
+               avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3200, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+               avr_jtag_senddat(avr->jtag_info.tap, &res, 0x3300, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+       } else if (type == AVR_READ_BYTE_TYPE_CALI) {
+               avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3600, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+               avr_jtag_senddat(avr->jtag_info.tap, &res, 0x3700, 
AVR_JTAG_REG_ProgrammingCommand_Len);
+       }
+
+       if (ERROR_OK != mcu_execute_queue())
+       {
+               LOG_INFO("failure");
+               return ERROR_FAIL;
+       }
+       LOG_INFO("%s byte[0x%04" PRIx32 "]" " = 0x%02" PRIx32 "",
+                type == AVR_READ_BYTE_TYPE_SIGN ? "Sign" : "Cali",
+                addr, (uint8_t)res);
+
+       return ERROR_OK;
+}
+
+static int avrf_read_byte(struct flash_bank *bank, uint8_t type, uint8_t addr)
+{
+       struct target *target = bank->target;
+       struct avr_common *avr = target->arch_info;
+
+       if (target->state != TARGET_HALTED)
+       {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       if ((ERROR_OK != avr_jtagprg_enterprogmode(avr))
+               || (ERROR_OK != avr_jtagprg_readbyte(avr, type, addr))
+               || (ERROR_OK != avr_jtagprg_leaveprogmode(avr)))
+       {
+               return ERROR_FAIL;
+       }
+
+       return ERROR_OK;
+}
+
+/* XXX: Check your actually 'read_byte' commands before using it. */
+COMMAND_HANDLER(avrf_handle_read_byte_command)
+{
+       int retval;
+       struct flash_bank *bank;
+       uint8_t addr, type;
+
+       if (CMD_ARGC < 3)
+       {
+               command_print(CMD_CTX, "avr read_byte <bank> <type> <addr>");
+               return ERROR_OK;
+       }
+
+       retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+       if (ERROR_OK != retval)
+               return retval;
+
+       if (0 == strncmp(CMD_ARGV[1], "sign", 4))
+               type = AVR_READ_BYTE_TYPE_SIGN;
+       else if (0 == strncmp(CMD_ARGV[1], "cali", 4))
+               type = AVR_READ_BYTE_TYPE_CALI;
+       else
+               type = AVR_READ_BYTE_TYPE_UNKNOWN;
+       if (type == AVR_READ_BYTE_TYPE_UNKNOWN)
+               return ERROR_INVALID_ARGUMENTS;
+
+       COMMAND_PARSE_NUMBER(u8, CMD_ARGV[2], addr);
+
+       if (avrf_read_byte(bank, type, addr) == ERROR_OK)
+       {
+               command_print(CMD_CTX, "avr read_byte success");
+       }
+       else
+       {
+               command_print(CMD_CTX, "avr read_byte failure");
+       }
+
+       return ERROR_OK;
+}
+
 static const struct command_registration avrf_exec_command_handlers[] = {
        {
                .name = "mass_erase",
@@ -471,6 +647,18 @@ static const struct command_registration 
avrf_exec_command_handlers[] = {
                .mode = COMMAND_EXEC,
                .help = "erase entire device",
        },
+       {
+               .name = "read_bits",
+               .handler = avrf_handle_read_bits_command,
+               .mode = COMMAND_EXEC,
+               .help = "read FUSE/Lock bits",
+       },
+       {
+               .name = "read_byte",
+               .handler = avrf_handle_read_byte_command,
+               .mode = COMMAND_EXEC,
+               .help = "read Sign/Cali Byte",
+       },
        COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration avrf_command_handlers[] = {
-- 
1.5.6.5

_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to