]> git.sur5r.net Git - openocd/blobdiff - src/flash/nor/xmc4xxx.c
xmc4xxx: Add support for XMC4300
[openocd] / src / flash / nor / xmc4xxx.c
index d4242a24df20e9312a996bd0663ee47c15d32f4d..02df46a3fd2444a3c0ec4b9d94bea5eb8daea459 100644 (file)
@@ -11,6 +11,8 @@
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
+*   You should have received a copy of the GNU General Public License     *
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
 
 /* Flash controller configuration values */
 #define FLASH_ID_XMC4500        0xA2
+#define FLASH_ID_XMC4300_XMC4700_4800   0x92
 #define FLASH_ID_XMC4100_4200   0x9C
 #define FLASH_ID_XMC4400        0x9F
 
@@ -251,6 +254,10 @@ static const unsigned int sector_capacity_12[12] = {
        16, 16, 16, 16, 16, 16, 16, 16, 128, 256, 256, 256
 };
 
+static const unsigned int sector_capacity_16[16] = {
+       16, 16, 16, 16, 16, 16, 16, 16, 128, 256, 256, 256, 256, 256, 256, 256
+};
+
 static int xmc4xxx_write_command_sequence(struct flash_bank *bank,
                                         struct xmc4xxx_command_seq *seq,
                                         int seq_len)
@@ -285,6 +292,9 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank)
        case 12:
                capacity = sector_capacity_12;
                break;
+       case 16:
+               capacity = sector_capacity_16;
+               break;
        default:
                LOG_ERROR("Unexpected number of sectors, %d\n",
                          bank->num_sectors);
@@ -309,8 +319,8 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank)
        }
 
        /* This part doesn't follow the typical standard of 0xff
-        * being the default padding value.*/
-       bank->default_padded_value = 0x00;
+        * being the erased value.*/
+       bank->default_padded_value = bank->erased_value = 0x00;
 
        return ERROR_OK;
 }
@@ -373,6 +383,10 @@ static int xmc4xxx_probe(struct flash_bank *bank)
                bank->num_sectors = 12;
                LOG_DEBUG("XMC4xxx: XMC4500 detected.");
                break;
+       case FLASH_ID_XMC4300_XMC4700_4800:
+               bank->num_sectors = 16;
+               LOG_DEBUG("XMC4xxx: XMC4700/4800 detected.");
+               break;
        default:
                LOG_ERROR("XMC4xxx: Unexpected flash ID. got %02" PRIx8,
                          flash_id);
@@ -603,106 +617,6 @@ static int xmc4xxx_enter_page_mode(struct flash_bank *bank)
        return res;
 }
 
-/* The logical erase value of an xmc4xxx memory cell is 0x00,
- * therefore, we cannot use the built in flash blank check and must
- * implement our own */
-
-/** Checks whether a memory region is zeroed. */
-int xmc4xxx_blank_check_memory(struct target *target,
-       uint32_t address, uint32_t count, uint32_t *blank)
-{
-       struct working_area *erase_check_algorithm;
-       struct reg_param reg_params[3];
-       struct armv7m_algorithm armv7m_info;
-       int retval;
-
-       /* see contrib/loaders/erase_check/armv7m_0_erase_check.s for src */
-
-       static const uint8_t erase_check_code[] = {
-               /* loop: */
-               0x03, 0x78,             /* ldrb r3, [r0] */
-               0x01, 0x30,             /* adds r0, #1 */
-               0x1A, 0x43,             /* orrs r2, r2, r3 */
-               0x01, 0x39,             /* subs r1, r1, #1 */
-               0xFA, 0xD1,             /* bne  loop */
-               0x00, 0xBE              /* bkpt #0 */
-       };
-
-       /* make sure we have a working area */
-       if (target_alloc_working_area(target, sizeof(erase_check_code),
-               &erase_check_algorithm) != ERROR_OK)
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-
-       retval = target_write_buffer(target, erase_check_algorithm->address,
-                       sizeof(erase_check_code), (uint8_t *)erase_check_code);
-       if (retval != ERROR_OK)
-               return retval;
-
-       armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
-       armv7m_info.core_mode = ARM_MODE_THREAD;
-
-       init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
-       buf_set_u32(reg_params[0].value, 0, 32, address);
-
-       init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
-       buf_set_u32(reg_params[1].value, 0, 32, count);
-
-       init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
-       buf_set_u32(reg_params[2].value, 0, 32, 0x00);
-
-       retval = target_run_algorithm(target,
-                                     0,
-                                     NULL,
-                                     3,
-                                     reg_params,
-                                     erase_check_algorithm->address,
-                                     erase_check_algorithm->address + (sizeof(erase_check_code) - 2),
-                                     10000,
-                                     &armv7m_info);
-
-       if (retval == ERROR_OK)
-               *blank = buf_get_u32(reg_params[2].value, 0, 32);
-
-       destroy_reg_param(&reg_params[0]);
-       destroy_reg_param(&reg_params[1]);
-       destroy_reg_param(&reg_params[2]);
-
-       target_free_working_area(target, erase_check_algorithm);
-
-       return retval;
-}
-
-static int xmc4xxx_flash_blank_check(struct flash_bank *bank)
-{
-       struct target *target = bank->target;
-       int i;
-       int retval;
-       uint32_t blank;
-
-       if (bank->target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       for (i = 0; i < bank->num_sectors; i++) {
-               uint32_t address = bank->base + bank->sectors[i].offset;
-               uint32_t size = bank->sectors[i].size;
-
-               LOG_DEBUG("Erase checking 0x%08"PRIx32, address);
-               retval = xmc4xxx_blank_check_memory(target, address, size, &blank);
-
-               if (retval != ERROR_OK)
-                       break;
-
-               if (blank == 0x00)
-                       bank->sectors[i].is_erased = 1;
-               else
-                       bank->sectors[i].is_erased = 0;
-       }
-
-       return ERROR_OK;
-}
-
 static int xmc4xxx_write_page(struct flash_bank *bank, const uint8_t *pg_buf,
                              uint32_t offset, bool user_config)
 {
@@ -937,6 +851,14 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_
                        break;
                }
                break;
+       case 0x300:
+               dev_str = "XMC4300";
+
+               switch (rev_id) {
+               case 0x1:
+                       rev_str = "AA";
+               }
+               break;
        case 0x400:
                dev_str = "XMC4400";
 
@@ -971,6 +893,24 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_
                        break;
                }
                break;
+       case 0x700:
+               dev_str = "XMC4700";
+
+               switch (rev_id) {
+               case 0x1:
+                       rev_str = "EES-AA";
+                       break;
+               }
+               break;
+       case 0x800:
+               dev_str = "XMC4800";
+
+               switch (rev_id) {
+               case 0x1:
+                       rev_str = "EES-AA";
+                       break;
+               }
+               break;
 
        default:
                snprintf(buf, buf_size,
@@ -1066,11 +1006,6 @@ static int xmc4xxx_flash_unprotect(struct flash_bank *bank, int32_t level)
        uint32_t addr;
        int res;
 
-       if ((level < 0) || (level > 1)) {
-               LOG_ERROR("Invalid user level. Must be 0-1");
-               return ERROR_FAIL;
-       }
-
        switch (level) {
        case 0:
                addr = UCB0_BASE;
@@ -1078,6 +1013,9 @@ static int xmc4xxx_flash_unprotect(struct flash_bank *bank, int32_t level)
        case 1:
                addr = UCB1_BASE;
                break;
+       default:
+               LOG_ERROR("Invalid user level. Must be 0-1");
+               return ERROR_FAIL;
        }
 
        res = xmc4xxx_erase_sector(bank, addr, true);
@@ -1414,7 +1352,7 @@ struct flash_driver xmc4xxx_flash = {
        .read = default_flash_read,
        .probe = xmc4xxx_probe,
        .auto_probe = xmc4xxx_probe,
-       .erase_check = xmc4xxx_flash_blank_check,
+       .erase_check = default_flash_blank_check,
        .info = xmc4xxx_get_info_command,
        .protect_check = xmc4xxx_protect_check,
        .protect = xmc4xxx_protect,