This is an automated email from Gerrit.

Andrea Merello ([email protected]) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/4034

-- gerrit

commit 2de167e36a128841f23c0ab1e244ec287c3448c1
Author: Andrea Merello <[email protected]>
Date:   Wed Mar 1 11:32:07 2017 +0100

    flash: efm32: add support for EFR-familty (e.g. bluegecko)
    
    This patch adds support for Blue Gecko and Mighty Gecko chips from
    Silabs.
    
    They have different EFM32_MSC_REGBASE and LOCK register offset.
    
    Based on the original patch from Andreas Kemnade.
    
    Change-Id: I166c14960ced7c880b68083badd1b31372fefabe
    Cc: Andreas Kemnade <[email protected]>
    Signed-off-by: Andrea Merello <[email protected]>

diff --git a/contrib/loaders/flash/efm32.S b/contrib/loaders/flash/efm32.S
index 25d6301..c4dd372 100644
--- a/contrib/loaders/flash/efm32.S
+++ b/contrib/loaders/flash/efm32.S
@@ -44,6 +44,8 @@
 #define EFM32_MSC_ADDRB_OFFSET          0x010
 #define EFM32_MSC_WDATA_OFFSET          0x018
 #define EFM32_MSC_STATUS_OFFSET         0x01c
+
+/* This needs to be changed in 0x040 for EFR32-family */
 #define EFM32_MSC_LOCK_OFFSET           0x03c
 
        /* unlock MSC */
diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c
index 81c1a37..781eddf 100644
--- a/src/flash/nor/efm32.c
+++ b/src/flash/nor/efm32.c
@@ -48,6 +48,8 @@
 #define EFM_FAMILY_ID_HAPPY_GECKO      77
 #define EZR_FAMILY_ID_WONDER_GECKO             120
 #define EZR_FAMILY_ID_LEOPARD_GECKO            121
+#define EFR_FAMILY_ID_MIGHTY_GECKO     16
+#define EFR_FAMILY_ID_BLUE_GECKO       20
 
 #define EFM32_FLASH_ERASE_TMO           100
 #define EFM32_FLASH_WDATAREADY_TMO      100
@@ -71,27 +73,31 @@
 #define EFM32_MSC_DI_PROD_REV           (EFM32_MSC_DEV_INFO+0x1ff)
 
 #define EFM32_MSC_REGBASE               0x400c0000
-#define EFM32_MSC_WRITECTRL             (EFM32_MSC_REGBASE+0x008)
+#define EFR32_MSC_REGBASE               0x400e0000
+#define EFM32_MSC_REG_WRITECTRL         0x008
 #define EFM32_MSC_WRITECTRL_WREN_MASK   0x1
-#define EFM32_MSC_WRITECMD              (EFM32_MSC_REGBASE+0x00c)
+#define EFM32_MSC_REG_WRITECMD          0x00c
 #define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1
 #define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2
 #define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8
-#define EFM32_MSC_ADDRB                 (EFM32_MSC_REGBASE+0x010)
-#define EFM32_MSC_WDATA                 (EFM32_MSC_REGBASE+0x018)
-#define EFM32_MSC_STATUS                (EFM32_MSC_REGBASE+0x01c)
+#define EFM32_MSC_REG_ADDRB             0x010
+#define EFM32_MSC_REG_WDATA             0x018
+#define EFM32_MSC_REG_STATUS            0x01c
 #define EFM32_MSC_STATUS_BUSY_MASK      0x1
 #define EFM32_MSC_STATUS_LOCKED_MASK    0x2
 #define EFM32_MSC_STATUS_INVADDR_MASK   0x4
 #define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8
 #define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10
 #define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20
-#define EFM32_MSC_LOCK                  (EFM32_MSC_REGBASE+0x03c)
+#define EFM32_MSC_REG_LOCK              0x03c
+#define EFR32_MSC_REG_LOCK              0x040
 #define EFM32_MSC_LOCK_LOCKKEY          0x1b71
 
 struct efm32x_flash_bank {
        int probed;
        uint32_t lb_page[LOCKBITS_PAGE_SZ/4];
+       uint32_t reg_base;
+       uint8_t reg_lock;
 };
 
 struct efm32_info {
@@ -131,11 +137,30 @@ static int efm32x_get_prod_rev(struct flash_bank *bank, 
uint8_t *prev)
        return target_read_u8(bank->target, EFM32_MSC_DI_PROD_REV, prev);
 }
 
+static int efm32x_read_reg_u32(struct flash_bank *bank, target_addr_t address,
+                              uint32_t *value)
+{
+       struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
+       uint32_t base = efm32x_info->reg_base;
+
+       return target_read_u32(bank->target, base + address, value);
+}
+
+static int efm32x_write_reg_u32(struct flash_bank *bank, target_addr_t address,
+                              uint32_t value)
+{
+       struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
+       uint32_t base = efm32x_info->reg_base;
+
+       return target_write_u32(bank->target, base + address, value);
+}
+
 static int efm32x_read_info(struct flash_bank *bank,
        struct efm32_info *efm32_info)
 {
        int ret;
        uint32_t cpuid = 0;
+       struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
 
        memset(efm32_info, 0, sizeof(struct efm32_info));
 
@@ -174,6 +199,13 @@ static int efm32x_read_info(struct flash_bank *bank,
        if (ERROR_OK != ret)
                return ret;
 
+       if (EFR_FAMILY_ID_BLUE_GECKO == efm32_info->part_family ||
+           EFR_FAMILY_ID_MIGHTY_GECKO == efm32_info->part_family) {
+               efm32x_info->reg_base = EFR32_MSC_REGBASE;
+       } else {
+               efm32x_info->reg_base = EFM32_MSC_REGBASE;
+       }
+
        if (EFM_FAMILY_ID_GECKO == efm32_info->part_family ||
                        EFM_FAMILY_ID_TINY_GECKO == efm32_info->part_family)
                efm32_info->page_size = 512;
@@ -206,7 +238,9 @@ static int efm32x_read_info(struct flash_bank *bank,
                }
        } else if (EFM_FAMILY_ID_WONDER_GECKO == efm32_info->part_family ||
                        EZR_FAMILY_ID_WONDER_GECKO == efm32_info->part_family ||
-                       EZR_FAMILY_ID_LEOPARD_GECKO == efm32_info->part_family) 
{
+                       EZR_FAMILY_ID_LEOPARD_GECKO == efm32_info->part_family 
||
+                       EFR_FAMILY_ID_BLUE_GECKO == efm32_info->part_family ||
+                       EFR_FAMILY_ID_MIGHTY_GECKO == efm32_info->part_family) {
                uint8_t pg_size = 0;
                ret = target_read_u8(bank->target, EFM32_MSC_DI_PAGE_SIZE,
                        &pg_size);
@@ -238,6 +272,10 @@ static int efm32x_decode_info(struct efm32_info *info, 
char *buf, int buf_size)
                case EZR_FAMILY_ID_LEOPARD_GECKO:
                        printed = snprintf(buf, buf_size, "EZR32 ");
                        break;
+               case EFR_FAMILY_ID_MIGHTY_GECKO:
+               case EFR_FAMILY_ID_BLUE_GECKO:
+                       printed = snprintf(buf, buf_size, "EFR32 ");
+                       break;
                default:
                        printed = snprintf(buf, buf_size, "EFM32 ");
        }
@@ -272,6 +310,12 @@ static int efm32x_decode_info(struct efm32_info *info, 
char *buf, int buf_size)
                case EFM_FAMILY_ID_HAPPY_GECKO:
                        printed = snprintf(buf, buf_size, "Happy Gecko");
                        break;
+               case EFR_FAMILY_ID_BLUE_GECKO:
+                       printed = snprintf(buf, buf_size, "Blue Gecko");
+                       break;
+               case EFR_FAMILY_ID_MIGHTY_GECKO:
+                       printed = snprintf(buf, buf_size, "Mighty Gecko");
+                       break;
        }
 
        buf += printed;
@@ -315,7 +359,7 @@ static int efm32x_set_reg_bits(struct flash_bank *bank, 
uint32_t reg,
        int ret = 0;
        uint32_t reg_val = 0;
 
-       ret = target_read_u32(bank->target, reg, &reg_val);
+       ret = efm32x_read_reg_u32(bank, reg, &reg_val);
        if (ERROR_OK != ret)
                return ret;
 
@@ -324,18 +368,19 @@ static int efm32x_set_reg_bits(struct flash_bank *bank, 
uint32_t reg,
        else
                reg_val &= ~bitmask;
 
-       return target_write_u32(bank->target, reg, reg_val);
+       return efm32x_write_reg_u32(bank, reg, reg_val);
 }
 
 static int efm32x_set_wren(struct flash_bank *bank, int write_enable)
 {
-       return efm32x_set_reg_bits(bank, EFM32_MSC_WRITECTRL,
+       return efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECTRL,
                EFM32_MSC_WRITECTRL_WREN_MASK, write_enable);
 }
 
 static int efm32x_msc_lock(struct flash_bank *bank, int lock)
 {
-       return target_write_u32(bank->target, EFM32_MSC_LOCK,
+       struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
+       return efm32x_write_reg_u32(bank, efm32x_info->reg_lock,
                (lock ? 0 : EFM32_MSC_LOCK_LOCKKEY));
 }
 
@@ -346,7 +391,7 @@ static int efm32x_wait_status(struct flash_bank *bank, int 
timeout,
        uint32_t status = 0;
 
        while (1) {
-               ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status);
+               ret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);
                if (ERROR_OK != ret)
                        break;
 
@@ -385,16 +430,16 @@ static int efm32x_erase_page(struct flash_bank *bank, 
uint32_t addr)
 
        LOG_DEBUG("erasing flash page at 0x%08" PRIx32, addr);
 
-       ret = target_write_u32(bank->target, EFM32_MSC_ADDRB, addr);
+       ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_ADDRB, addr);
        if (ERROR_OK != ret)
                return ret;
 
-       ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD,
+       ret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,
                EFM32_MSC_WRITECMD_LADDRIM_MASK, 1);
        if (ERROR_OK != ret)
                return ret;
 
-       ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status);
+       ret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);
        if (ERROR_OK != ret)
                return ret;
 
@@ -408,7 +453,7 @@ static int efm32x_erase_page(struct flash_bank *bank, 
uint32_t addr)
                return ERROR_FAIL;
        }
 
-       ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD,
+       ret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,
                EFM32_MSC_WRITECMD_ERASEPAGE_MASK, 1);
        if (ERROR_OK != ret)
                return ret;
@@ -585,10 +630,15 @@ static int efm32x_write_block(struct flash_bank *bank, 
const uint8_t *buf,
        uint32_t address = bank->base + offset;
        struct reg_param reg_params[5];
        struct armv7m_algorithm armv7m_info;
+       struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
        int ret = ERROR_OK;
 
+       /* str     r6, [r0, #EFM32_MSC_LOCK_OFFSET] */
+       static const uint8_t efr_lock_str_r6[] = {0x06, 0x64};
+       static const uint8_t efm_lock_str_r6[] = {0xc6, 0x63};
+
        /* see contrib/loaders/flash/efm32.S for src */
-       static const uint8_t efm32x_flash_write_code[] = {
+       static uint8_t efm32x_flash_write_code[] = {
                /* #define EFM32_MSC_WRITECTRL_OFFSET      0x008 */
                /* #define EFM32_MSC_WRITECMD_OFFSET       0x00c */
                /* #define EFM32_MSC_ADDRB_OFFSET          0x010 */
@@ -597,7 +647,7 @@ static int efm32x_write_block(struct flash_bank *bank, 
const uint8_t *buf,
                /* #define EFM32_MSC_LOCK_OFFSET           0x03c */
 
                        0x15, 0x4e,    /* ldr     r6, =#0x1b71 */
-                       0xc6, 0x63,    /* str     r6, [r0, 
#EFM32_MSC_LOCK_OFFSET] */
+                       0, 0,          /* fill with: str r6, [r0, 
#EFM32_MSC_LOCK_OFFSET] */
                        0x01, 0x26,    /* movs    r6, #1 */
                        0x86, 0x60,    /* str     r6, [r0, 
#EFM32_MSC_WRITECTRL_OFFSET] */
 
@@ -661,6 +711,12 @@ static int efm32x_write_block(struct flash_bank *bank, 
const uint8_t *buf,
                        0x71, 0x1b, 0x00, 0x00
        };
 
+       /* patch the above bin blob for different LOCK reg offsets */
+       if (efm32x_info->reg_lock == EFM32_MSC_REG_LOCK)
+               memcpy(efm32x_flash_write_code + 2, efm_lock_str_r6, 2);
+       else
+               memcpy(efm32x_flash_write_code + 2, efr_lock_str_r6, 2);
+
        /* flash write code */
        if (target_alloc_working_area(target, sizeof(efm32x_flash_write_code),
                        &write_algorithm) != ERROR_OK) {
@@ -693,7 +749,7 @@ static int efm32x_write_block(struct flash_bank *bank, 
const uint8_t *buf,
        init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);    /* buffer end */
        init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target 
address */
 
-       buf_set_u32(reg_params[0].value, 0, 32, EFM32_MSC_REGBASE);
+       buf_set_u32(reg_params[0].value, 0, 32, efm32x_info->reg_base);
        buf_set_u32(reg_params[1].value, 0, 32, count);
        buf_set_u32(reg_params[2].value, 0, 32, source->address);
        buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
@@ -758,16 +814,16 @@ static int efm32x_write_word(struct flash_bank *bank, 
uint32_t addr,
        /* if not called, GDB errors will be reported during large writes */
        keep_alive();
 
-       ret = target_write_u32(bank->target, EFM32_MSC_ADDRB, addr);
+       ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_ADDRB, addr);
        if (ERROR_OK != ret)
                return ret;
 
-       ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD,
+       ret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,
                EFM32_MSC_WRITECMD_LADDRIM_MASK, 1);
        if (ERROR_OK != ret)
                return ret;
 
-       ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status);
+       ret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);
        if (ERROR_OK != ret)
                return ret;
 
@@ -788,13 +844,13 @@ static int efm32x_write_word(struct flash_bank *bank, 
uint32_t addr,
                return ret;
        }
 
-       ret = target_write_u32(bank->target, EFM32_MSC_WDATA, val);
+       ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_WDATA, val);
        if (ERROR_OK != ret) {
                LOG_ERROR("WDATA write failed");
                return ret;
        }
 
-       ret = target_write_u32(bank->target, EFM32_MSC_WRITECMD,
+       ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_WRITECMD,
                EFM32_MSC_WRITECMD_WRITEONCE_MASK);
        if (ERROR_OK != ret) {
                LOG_ERROR("WRITECMD write failed");

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to