Fix stm32l readmem32.
authorKarl Palsson <karlp@tweak.net.au>
Wed, 12 Oct 2011 01:45:28 +0000 (01:45 +0000)
committerKarl Palsson <karlp@tweak.net.au>
Wed, 12 Oct 2011 01:45:28 +0000 (01:45 +0000)
As noted, the usb transfer only has a 1 byte length, but it also has a different mode
to enter.

Tidied up and removed more duplicate and hard coded code, tried to add some notes on
where the magic came from.

No idea where the chip ids came from, I can't find them in the datasheets anywhere.

gdbserver/gdb-server.c
src/stlink-common.c
src/stlink-common.h
src/stlink-usb.c
src/stlink-usb.h
src/test_usb.c

index 2520c306e9a142e0b42116dba121319e0862b716..77d7562a4ab147543fe86c31f0af325665b31508 100644 (file)
@@ -36,18 +36,22 @@ struct chip_params {
        uint32_t bootrom_base, bootrom_size;
 } const devices[] = {
        { 0x412, "Low-density device",
-         0x8000,   0x400, 0x2800,  0x1ffff000, 0x800  },
+         0x8000,   0x400, 0x2800,  0x1ffff000, 0x800  }, // table 1, pm0063
        { 0x410, "Medium-density device",
-         0x20000,  0x400, 0x5000,  0x1ffff000, 0x800  },
+         0x20000,  0x400, 0x5000,  0x1ffff000, 0x800  }, // table 2, pm0063
        { 0x414, "High-density device",
-         0x80000,  0x800, 0x10000, 0x1ffff000, 0x800  },
+         0x80000,  0x800, 0x10000, 0x1ffff000, 0x800  },  // table 3 pm0063 
+          // This ignores the EEPROM! (and uses the page erase size,
+          // not the sector write protection...)
+        { 0x416, "EnergyLite device",
+          0x2000, 0x100, 0x4000, 0x1ff00000, 0x1000 },
        { 0x418, "Connectivity line device",
          0x40000,  0x800, 0x10000, 0x1fffb000, 0x4800 },
        { 0x420, "Medium-density value line device",
          0x20000,  0x400, 0x2000,  0x1ffff000, 0x800  },
        { 0x428, "High-density value line device",
          0x80000,  0x800, 0x8000,  0x1ffff000, 0x800  },
-       { 0x430, "XL-density device",
+       { 0x430, "XL-density device",   // pm0068
          0x100000, 0x800, 0x18000, 0x1fffe000, 0x1800 },
        { 0 }
 };
@@ -69,12 +73,7 @@ int main(int argc, char** argv) {
        if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE)
                stlink_enter_swd_mode(sl);
 
-       uint32_t chip_id;
-
-       stlink_read_mem32(sl, 0xE0042000, 4);
-       chip_id = sl->q_buf[0] | (sl->q_buf[1] << 8) | (sl->q_buf[2] << 16) |
-               (sl->q_buf[3] << 24);
-
+       uint32_t chip_id = stlink_chip_id(sl);
        printf("Chip ID is %08x.\n", chip_id);
 
        const struct chip_params* params = NULL;
@@ -99,7 +98,7 @@ int main(int argc, char** argv) {
 
        uint32_t flash_size;
 
-       stlink_read_mem32(sl, 0x1FFFF7E0, 4);
+       stlink_read_mem32(sl, 0x1FFFF7E0, 4);  // FIXME - that's never going to work!
        flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8);
 
        printf("Flash size is %d KiB.\n", flash_size);
index e3d6631d45ca19fd5c4af486aaa32e147e09eb22..a3170074e402c3ea939ef684c1a097152d17d83b 100644 (file)
@@ -285,6 +285,13 @@ void stlink_core_id(stlink_t *sl) {
     DD(sl, "core_id = 0x%08x\n", sl->core_id);
 }
 
+uint16_t stlink_chip_id(stlink_t *sl) {
+    stlink_read_mem32(sl, 0xE0042000, 4);
+    uint32_t chip_id = sl->q_buf[0] | (sl->q_buf[1] << 8) | (sl->q_buf[2] << 16) |
+            (sl->q_buf[3] << 24);
+    return chip_id;
+}
+
 void stlink_reset(stlink_t *sl) {
     D(sl, "\n*** stlink_reset ***\n");
     sl->backend->reset(sl);
@@ -404,18 +411,16 @@ void stlink_step(stlink_t *sl) {
 }
 
 int stlink_current_mode(stlink_t *sl) {
-    D(sl, "\n*** stlink_current_mode ***\n");
     int mode = sl->backend->current_mode(sl);
-    stlink_print_data(sl);
     switch (mode) {
         case STLINK_DEV_DFU_MODE:
-            DD(sl, "stlink mode: dfu\n");
+            DD(sl, "stlink current mode: dfu\n");
             return mode;
         case STLINK_DEV_DEBUG_MODE:
-            DD(sl, "stlink mode: debug (jtag or swd)\n");
+            DD(sl, "stlink current mode: debug (jtag or swd)\n");
             return mode;
         case STLINK_DEV_MASS_MODE:
-            DD(sl, "stlink mode: mass\n");
+            DD(sl, "stlink current mode: mass\n");
             return mode;
     }
     DD(sl, "stlink mode: unknown!\n");
index b77a89922853a7ea0cdb0f70572c1db0af8bb8ac..a716f4d45b9b3d07b799bea26cca75e07ef20672 100644 (file)
@@ -38,6 +38,7 @@ extern "C" {
 #define STLINK_DEBUG_COMMAND           0xF2
 #define STLINK_DFU_COMMAND             0xF3
 #define STLINK_DFU_EXIT                0x07
+    // enter dfu could be 0x08?
 
     // STLINK_GET_CURRENT_MODE
 #define STLINK_DEV_DFU_MODE            0x00
@@ -65,6 +66,10 @@ extern "C" {
 #define STLINK_DEBUG_WRITEDEBUGREG     0x0f
 #define STLINK_DEBUG_ENTER_SWD         0xa3
 #define STLINK_DEBUG_ENTER_JTAG        0x00
+    
+    // TODO - possible poor names...
+#define STLINK_SWD_ENTER 0x30
+#define STLINK_SWD_READCOREID 0x32  // TBD
 
     typedef struct {
         uint32_t r[16];
@@ -109,12 +114,12 @@ extern "C" {
         void (*reset) (stlink_t * stl);
         void (*run) (stlink_t * stl);
         void (*status) (stlink_t * stl);
-        void (*version) (stlink_t * stl);
+        void (*version) (stlink_t *sl);
         void (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len);
         void (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len);
         void (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len);
-        void (*read_all_regs) (stlink_t *sl, reg* regp);
-        void (*read_reg) (stlink_t *sl, int r_idx, reg* regp);
+        void (*read_all_regs) (stlink_t *sl, reg * regp);
+        void (*read_reg) (stlink_t *sl, int r_idx, reg * regp);
         void (*write_reg) (stlink_t *sl, uint32_t reg, int idx);
         void (*step) (stlink_t * stl);
         int (*current_mode) (stlink_t * stl);
@@ -189,6 +194,9 @@ extern "C" {
 
     int stlink_erase_flash_mass(stlink_t* sl);
     int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, unsigned length);
+    
+    // PUBLIC
+    uint16_t stlink_chip_id(stlink_t *sl);
 
     // privates, publics, the rest....
     // TODO sort what is private, and what is not
index e30a98060138f85a8f7d901e0161387725fae8cd..90d5913bb882e2b6bc97870b62abbf7286237d2b 100644 (file)
@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -145,7 +146,7 @@ static int is_stlink_device(libusb_device * dev) {
     return 1;
 }
 
-void _stlink_usb_version(stlink_t * sl) {
+void _stlink_usb_version(stlink_t *sl) {
     struct stlink_libusb * const slu = sl->backend_data;
     unsigned char* const buf = sl->q_buf;
     ssize_t size;
@@ -154,7 +155,7 @@ void _stlink_usb_version(stlink_t * sl) {
     buf[0] = STLINK_GET_VERSION;
     buf[1] = 0x80;
 
-    size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
+    size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
     if (size == -1) {
         printf("[!] send_recv\n");
         return;
@@ -181,26 +182,17 @@ void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
 
 
 int _stlink_usb_current_mode(stlink_t * sl) {
-    int mode = -1;
-
     struct stlink_libusb * const slu = sl->backend_data;
     unsigned char* const buf = sl->q_buf;
     ssize_t size;
-
     memset(buf, 0, sizeof (sl->q_buf));
-
     buf[0] = STLINK_GET_CURRENT_MODE;
-
-    size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
+    size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
     if (size == -1) {
         printf("[!] send_recv\n");
         return -1;
     }
-
-    /* mode = (int)read_uint16(buf, 0); */
-    mode = (int) buf[0];
-    DD(sl, "mode == 0x%x\n", mode);
-    return mode;
+    return sl->q_buf[0];
 }
 
 void _stlink_usb_core_id(stlink_t * sl) {
@@ -212,7 +204,7 @@ void _stlink_usb_core_id(stlink_t * sl) {
     buf[0] = STLINK_DEBUG_COMMAND;
     buf[1] = STLINK_DEBUG_READCOREID;
 
-    size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
+    size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
     if (size == -1) {
         printf("[!] send_recv\n");
         return;
@@ -231,7 +223,7 @@ void _stlink_usb_status(stlink_t * sl) {
     buf[0] = STLINK_DEBUG_COMMAND;
     buf[1] = STLINK_DEBUG_GETSTATUS;
 
-    size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
+    size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
     if (size == -1) {
         printf("[!] send_recv\n");
         return;
@@ -246,7 +238,7 @@ void _stlink_usb_status(stlink_t * sl) {
 
 }
 
-void _stlink_enter_swd_mode(stlink_t * sl) {
+void _stlink_usb_enter_swd_mode(stlink_t * sl) {
     struct stlink_libusb * const slu = sl->backend_data;
     unsigned char* const buf = sl->q_buf;
     ssize_t size;
@@ -254,15 +246,14 @@ void _stlink_enter_swd_mode(stlink_t * sl) {
     memset(buf, 0, sizeof (sl->q_buf));
 
     buf[0] = STLINK_DEBUG_COMMAND;
-    buf[1] = 0x30; /* needed byte */
-    buf[2] = STLINK_DEBUG_ENTER_JTAG;
+    buf[1] = STLINK_SWD_ENTER;
+    buf[2] = STLINK_DEBUG_ENTER_SWD;
 
-    size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
+    size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
     if (size == -1) {
         printf("[!] send_recv\n");
         return;
     }
-
 }
 
 void _stlink_usb_exit_dfu_mode(stlink_t* sl) {
@@ -290,7 +281,7 @@ void _stlink_usb_reset(stlink_t * sl) {
     buf[0] = STLINK_DEBUG_COMMAND;
     buf[1] = STLINK_DEBUG_RESETSYS;
 
-    size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
+    size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
     if (size == -1) {
         printf("[!] send_recv\n");
         return;
@@ -307,7 +298,7 @@ void _stlink_usb_step(stlink_t* sl) {
     buf[0] = STLINK_DEBUG_COMMAND;
     buf[1] = STLINK_DEBUG_STEPCORE;
 
-    size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
+    size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
     if (size == -1) {
         printf("[!] send_recv\n");
         return;
@@ -323,7 +314,7 @@ void _stlink_usb_run(stlink_t* sl) {
     buf[0] = STLINK_DEBUG_COMMAND;
     buf[1] = STLINK_DEBUG_RUNCORE;
 
-    size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
+    size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
     if (size == -1) {
         printf("[!] send_recv\n");
         return;
@@ -353,18 +344,18 @@ void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
     ssize_t size;
 
     /* assume len < sizeof(sl->q_buf) */
+    assert(len < sizeof(sl->q_buf));  // makes a compiler warning? always true?
 
     memset(buf, 0, sizeof (sl->q_buf));
     buf[0] = STLINK_DEBUG_COMMAND;
     buf[1] = STLINK_DEBUG_READMEM_32BIT;
     write_uint32(buf + 2, addr);
-    write_uint16(buf + 6, len);
-#if 0
     /* windows usb logs show only one byte is used for length ... */
+    // Presumably, this is because usb transfers can't be 16 bits worth of bytes long...
+    assert (len < 256);
     buf[6] = (uint8_t) len;
-#endif
 
-    size = send_recv(slu, buf, 0x10, buf, sizeof (sl->q_buf));
+    size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
     if (size == -1) {
         printf("[!] send_recv\n");
         return;
@@ -394,8 +385,8 @@ void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) {
 stlink_backend_t _stlink_usb_backend = {
     _stlink_usb_close,
     _stlink_usb_exit_debug_mode,
-    _stlink_enter_swd_mode,
-    NULL,
+    _stlink_usb_enter_swd_mode,
+    NULL,  // no enter_jtag_mode here...
     _stlink_usb_exit_dfu_mode,
     _stlink_usb_core_id,
     _stlink_usb_reset,
index 4b8b46b08b370d91b827192dcda074854370c658..4ed655b7e29c1b9e6a634f1f74b0e78bbd774b37 100644 (file)
@@ -14,6 +14,8 @@ extern "C" {
 
 #include <libusb-1.0/libusb.h>
 #include "stlink-common.h"
+    
+#define STLINK_CMD_SIZE 16
 
 #if defined(CONFIG_USE_LIBUSB)
     struct stlink_libusb {
index 1ffd47b2547242db8bfbedf84ab7efac2388d6a8..0c4232f8477c7098abf051a93059a33a78a597df 100644 (file)
@@ -9,6 +9,8 @@ int main(int ac, char** av) {
     if (sl != NULL) {
         printf("-- version\n");
         stlink_version(sl);
+        
+        printf("mode before doing anything: %d\n", stlink_current_mode(sl));
 
         if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
             printf("-- exit_dfu_mode\n");
@@ -18,11 +20,11 @@ int main(int ac, char** av) {
         printf("-- enter_swd_mode\n");
         stlink_enter_swd_mode(sl);
 
-        printf("-- current_mode\n");
-        stlink_current_mode(sl);
+        printf("-- mode after entering swd mode: %d\n", stlink_current_mode(sl));
 
-        /*     printf("-- core_id\n"); */
-        /*     stlink_core_id(sl); */
+        printf("-- chip id: %#x\n", stlink_chip_id(sl));
+        printf("-- core_id\n");
+        stlink_core_id(sl);
 
         printf("-- read_sram\n");
         static const uint32_t sram_base = 0x8000000;