cmd: add missing usage var
[fw/openocd] / src / flash / nor / at91sam7.c
index f9b87babb23708da4c6542e43a36d408eb5c8271..c2506be35a01b4741078476e548b76d45c3ea234 100644 (file)
 #include "config.h"
 #endif
 
-#include "at91sam7.h"
-#include "binarybuffer.h"
+#include "imp.h"
+#include <helper/binarybuffer.h>
+
+
+/* AT91SAM7 control registers */
+#define DBGU_CIDR                      0xFFFFF240
+#define CKGR_MCFR                      0xFFFFFC24
+#define CKGR_MOR                       0xFFFFFC20
+#define CKGR_MCFR_MAINRDY      0x10000
+#define CKGR_PLLR                      0xFFFFFC2c
+#define CKGR_PLLR_DIV          0xff
+#define CKGR_PLLR_MUL          0x07ff0000
+#define PMC_MCKR                       0xFFFFFC30
+#define PMC_MCKR_CSS           0x03
+#define PMC_MCKR_PRES          0x1c
+
+/* Flash Controller Commands */
+#define WP             0x01
+#define SLB            0x02
+#define WPL            0x03
+#define CLB            0x04
+#define EA             0x08
+#define SGPB   0x0B
+#define CGPB   0x0D
+#define SSB            0x0F
+
+/* MC_FSR bit definitions */
+#define MC_FSR_FRDY                    1
+#define MC_FSR_EOL                     2
+
+/* AT91SAM7 constants */
+#define RC_FREQ                                32000
+
+/* Flash timing modes */
+#define FMR_TIMING_NONE                0
+#define FMR_TIMING_NVBITS      1
+#define FMR_TIMING_FLASH       2
+
+/* Flash size constants */
+#define FLASH_SIZE_8KB         1
+#define FLASH_SIZE_16KB                2
+#define FLASH_SIZE_32KB                3
+#define FLASH_SIZE_64KB                5
+#define FLASH_SIZE_128KB       7
+#define FLASH_SIZE_256KB       9
+#define FLASH_SIZE_512KB       10
+#define FLASH_SIZE_1024KB      12
+#define FLASH_SIZE_2048KB      14
+
 
 static int at91sam7_protect_check(struct flash_bank *bank);
 static int at91sam7_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count);
@@ -66,6 +113,50 @@ static uint32_t MC_FSR[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
 
 static char * EPROC[8]= {"Unknown","ARM946-E","ARM7TDMI","Unknown","ARM920T","ARM926EJ-S","Unknown","Unknown"};
 
+struct at91sam7_flash_bank
+{
+       /* chip id register */
+       uint32_t cidr;
+       uint16_t cidr_ext;
+       uint16_t cidr_nvptyp;
+       uint16_t cidr_arch;
+       uint16_t cidr_sramsiz;
+       uint16_t cidr_nvpsiz;
+       uint16_t cidr_nvpsiz2;
+       uint16_t cidr_eproc;
+       uint16_t cidr_version;
+       const char *target_name;
+
+       /* flash auto-detection */
+       uint8_t  flash_autodetection;
+
+       /* flash geometry */
+       uint16_t pages_per_sector;
+       uint16_t pagesize;
+       uint16_t pages_in_lockregion;
+
+       /* nv memory bits */
+       uint16_t num_lockbits_on;
+       uint16_t lockbits;
+       uint16_t num_nvmbits;
+       uint16_t num_nvmbits_on;
+       uint16_t nvmbits;
+       uint8_t  securitybit;
+
+       /* 0: not init
+        * 1: fmcn for nvbits (1uS)
+        * 2: fmcn for flash (1.5uS) */
+       uint8_t  flashmode;
+
+       /* main clock status */
+       uint8_t  mck_valid;
+       uint32_t mck_freq;
+
+       /* external clock frequency */
+       uint32_t ext_freq;
+
+};
+
 #if 0
 static long SRAMSIZ[16] = {
        -1,
@@ -297,7 +388,7 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
        uint32_t ext_freq;
        uint32_t bank_size;
        uint32_t base_address = 0;
-       char *target_name = "Unknown";
+       char *target_name_t = "Unknown";
 
        at91sam7_info = t_bank->driver_priv;
 
@@ -385,7 +476,7 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
                        if (arch == 0x70)
                        {
                                num_nvmbits = 2;
-                               target_name = "AT91SAM7S161/16";
+                               target_name_t = "AT91SAM7S161/16";
                        }
                        break;
 
@@ -398,12 +489,12 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
                        if (arch == 0x70)
                        {
                                num_nvmbits = 2;
-                               target_name = "AT91SAM7S321/32";
+                               target_name_t = "AT91SAM7S321/32";
                        }
                        if (arch == 0x72)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7SE32";
+                               target_name_t = "AT91SAM7SE32";
                        }
                        break;
 
@@ -416,7 +507,7 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
                        if (arch == 0x70)
                        {
                                num_nvmbits = 2;
-                               target_name = "AT91SAM7S64";
+                               target_name_t = "AT91SAM7S64";
                        }
                        break;
 
@@ -429,22 +520,22 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
                        if (arch == 0x70)
                        {
                                num_nvmbits = 2;
-                               target_name = "AT91SAM7S128";
+                               target_name_t = "AT91SAM7S128";
                        }
                        if (arch == 0x71)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7XC128";
+                               target_name_t = "AT91SAM7XC128";
                        }
                        if (arch == 0x72)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7SE128";
+                               target_name_t = "AT91SAM7SE128";
                        }
                        if (arch == 0x75)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7X128";
+                               target_name_t = "AT91SAM7X128";
                        }
                        break;
 
@@ -457,27 +548,27 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
                        if (arch == 0x60)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7A3";
+                               target_name_t = "AT91SAM7A3";
                        }
                        if (arch == 0x70)
                        {
                                num_nvmbits = 2;
-                               target_name = "AT91SAM7S256";
+                               target_name_t = "AT91SAM7S256";
                        }
                        if (arch == 0x71)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7XC256";
+                               target_name_t = "AT91SAM7XC256";
                        }
                        if (arch == 0x72)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7SE256";
+                               target_name_t = "AT91SAM7SE256";
                        }
                        if (arch == 0x75)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7X256";
+                               target_name_t = "AT91SAM7X256";
                        }
                        break;
 
@@ -490,22 +581,22 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
                        if (arch == 0x70)
                        {
                                num_nvmbits = 2;
-                               target_name = "AT91SAM7S512";
+                               target_name_t = "AT91SAM7S512";
                        }
                        if (arch == 0x71)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7XC512";
+                               target_name_t = "AT91SAM7XC512";
                        }
                        if (arch == 0x72)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7SE512";
+                               target_name_t = "AT91SAM7SE512";
                        }
                        if (arch == 0x75)
                        {
                                num_nvmbits = 3;
-                               target_name = "AT91SAM7X512";
+                               target_name_t = "AT91SAM7X512";
                        }
                        break;
 
@@ -516,7 +607,7 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
                        break;
        }
 
-       if (strcmp(target_name, "Unknown") == 0)
+       if (strcmp(target_name_t, "Unknown") == 0)
        {
                LOG_ERROR("Target autodetection failed! Please specify target parameters in configuration file");
                return ERROR_FLASH_OPERATION_FAILED;
@@ -531,16 +622,19 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
        {
                if (bnk > 0)
                {
-                       /* create a new flash bank element */
-                       struct flash_bank *fb = malloc(sizeof(struct flash_bank));
-                       fb->target = target;
-                       fb->driver = bank->driver;
-                       fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
-                       fb->next = NULL;
-
-                       /* link created bank in 'flash_banks' list and redirect t_bank */
-                       t_bank->next = fb;
-                       t_bank = fb;
+                       if (!t_bank->next) {
+                               /* create a new flash bank element */
+                               struct flash_bank *fb = malloc(sizeof(struct flash_bank));
+                               fb->target = target;
+                               fb->driver = bank->driver;
+                               fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
+                               fb->name = "sam7_probed";
+                               fb->next = NULL;
+
+                               /* link created bank in 'flash_banks' list */
+                               t_bank->next = fb;
+                       }
+                       t_bank = t_bank->next;
                }
 
                t_bank->bank_number = bnk;
@@ -572,7 +666,7 @@ static int at91sam7_read_part_info(struct flash_bank *bank)
                at91sam7_info->cidr_eproc = (cidr >> 5)&0x0007;
                at91sam7_info->cidr_version = cidr&0x001F;
 
-               at91sam7_info->target_name  = target_name;
+               at91sam7_info->target_name  = target_name_t;
                at91sam7_info->flashmode = 0;
                at91sam7_info->ext_freq = ext_freq;
                at91sam7_info->num_nvmbits = num_nvmbits;
@@ -730,7 +824,7 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
        uint16_t page_size;
        uint16_t num_nvmbits;
 
-       char *target_name;
+       char *target_name_t;
 
        int bnk, sec;
 
@@ -774,8 +868,8 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
                return ERROR_OK;
        }
 
-       target_name = calloc(strlen(CMD_ARGV[7]) + 1, sizeof(char));
-       strcpy(target_name, CMD_ARGV[7]);
+       target_name_t = calloc(strlen(CMD_ARGV[7]) + 1, sizeof(char));
+       strcpy(target_name_t, CMD_ARGV[7]);
 
        /* calculate bank size  */
        bank_size = num_sectors * pages_per_sector * page_size;
@@ -784,16 +878,19 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
        {
                if (bnk > 0)
                {
-                       /* create a new bank element */
-                       struct flash_bank *fb = malloc(sizeof(struct flash_bank));
-                       fb->target = target;
-                       fb->driver = bank->driver;
-                       fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
-                       fb->next = NULL;
-
-                       /* link created bank in 'flash_banks' list and redirect t_bank */
-                       t_bank->next = fb;
-                       t_bank = fb;
+                       if (!t_bank->next) {
+                               /* create a new bank element */
+                               struct flash_bank *fb = malloc(sizeof(struct flash_bank));
+                               fb->target = target;
+                               fb->driver = bank->driver;
+                               fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
+                               fb->name = "sam7_probed";
+                               fb->next = NULL;
+
+                               /* link created bank in 'flash_banks' list */
+                               t_bank->next = fb;
+                       }
+                       t_bank = t_bank->next;
                }
 
                t_bank->bank_number = bnk;
@@ -815,7 +912,7 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
 
                at91sam7_info = t_bank->driver_priv;
 
-               at91sam7_info->target_name  = target_name;
+               at91sam7_info->target_name  = target_name_t;
                at91sam7_info->flashmode = 0;
                at91sam7_info->ext_freq  = ext_freq;
                at91sam7_info->num_nvmbits = num_nvmbits;
@@ -1033,7 +1130,7 @@ static int at91sam7_probe(struct flash_bank *bank)
        return ERROR_OK;
 }
 
-static int at91sam7_info(struct flash_bank *bank, char *buf, int buf_size)
+static int get_at91sam7_info(struct flash_bank *bank, char *buf, int buf_size)
 {
        int printed;
        struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
@@ -1077,14 +1174,11 @@ static int at91sam7_info(struct flash_bank *bank, char *buf, int buf_size)
        buf += printed;
        buf_size -= printed;
 
-       printed = snprintf(buf, buf_size,
+       snprintf(buf, buf_size,
                " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n",
                at91sam7_info->securitybit, at91sam7_info->num_nvmbits,
                at91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits);
 
-       buf += printed;
-       buf_size -= printed;
-
        return ERROR_OK;
 }
 
@@ -1109,8 +1203,7 @@ COMMAND_HANDLER(at91sam7_handle_gpnvm_command)
 
        if (CMD_ARGC != 2)
        {
-               command_print(CMD_CTX, "at91sam7 gpnvm <bit> <set | clear>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        bank = get_flash_bank_by_num_noprobe(0);
@@ -1170,7 +1263,7 @@ COMMAND_HANDLER(at91sam7_handle_gpnvm_command)
 
        /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
        status = at91sam7_get_flash_status(bank->target, 0);
-       LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value %d, status 0x%" PRIx32 " \n", flashcmd, bit, status);
+       LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value %d, status 0x%" PRIx32, flashcmd, bit, status);
 
        /* check protect state */
        at91sam7_protect_check(bank);
@@ -1181,10 +1274,11 @@ COMMAND_HANDLER(at91sam7_handle_gpnvm_command)
 static const struct command_registration at91sam7_exec_command_handlers[] = {
        {
                .name = "gpnvm",
-               .handler = &at91sam7_handle_gpnvm_command,
+               .handler = at91sam7_handle_gpnvm_command,
                .mode = COMMAND_EXEC,
-               .usage = "gpnvm <bit> set | clear, "
-                       "set or clear one gpnvm bit",
+               .help = "set or clear one General Purpose Non-Volatile Memory "
+                       "(gpnvm) bit",
+               .usage = "bitnum ('set'|'clear')",
        },
        COMMAND_REGISTRATION_DONE
 };
@@ -1193,21 +1287,24 @@ static const struct command_registration at91sam7_command_handlers[] = {
                .name = "at91sam7",
                .mode = COMMAND_ANY,
                .help = "at91sam7 flash command group",
+               .usage = "",
                .chain = at91sam7_exec_command_handlers,
        },
        COMMAND_REGISTRATION_DONE
 };
 
 struct flash_driver at91sam7_flash = {
-               .name = "at91sam7",
-               .commands = at91sam7_command_handlers,
-               .flash_bank_command = &at91sam7_flash_bank_command,
-               .erase = &at91sam7_erase,
-               .protect = &at91sam7_protect,
-               .write = &at91sam7_write,
-               .probe = &at91sam7_probe,
-               .auto_probe = &at91sam7_probe,
-               .erase_check = &at91sam7_erase_check,
-               .protect_check = &at91sam7_protect_check,
-               .info = &at91sam7_info,
-       };
+       .name = "at91sam7",
+       .usage = "gpnvm <bit> <set | clear>",
+       .commands = at91sam7_command_handlers,
+       .flash_bank_command = at91sam7_flash_bank_command,
+       .erase = at91sam7_erase,
+       .protect = at91sam7_protect,
+       .write = at91sam7_write,
+       .read = default_flash_read,
+       .probe = at91sam7_probe,
+       .auto_probe = at91sam7_probe,
+       .erase_check = at91sam7_erase_check,
+       .protect_check = at91sam7_protect_check,
+       .info = get_at91sam7_info,
+};