target_t -> struct target
[fw/openocd] / src / flash / lpc288x.c
index 1f47896452856892dc55eba0f2ac54ebfb8bfb58..dbd0dab51c1f447b4d48a3208cf9c8f52644b819 100644 (file)
 #include "config.h"
 #endif
 
-#include "replacements.h"
-
 #include "lpc288x.h"
-
-#include "flash.h"
-#include "target.h"
-#include "log.h"
 #include "binarybuffer.h"
-#include "types.h"
 
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
 
 #define LOAD_TIMER_ERASE       0
 #define LOAD_TIMER_WRITE       1
 /* F_CLK_TIME */
 #define FCT_CLK_DIV_MASK    0x0FFF
 
-static int lpc288x_register_commands(struct command_context_s *cmd_ctx);
-static int lpc288x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
-static int lpc288x_erase(struct flash_bank_s *bank, int first, int last);
-static int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int last);
-static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
-static int lpc288x_probe(struct flash_bank_s *bank);
-static int lpc288x_erase_check(struct flash_bank_s *bank);
-static int lpc288x_protect_check(struct flash_bank_s *bank);
-static int lpc288x_info(struct flash_bank_s *bank, char *buf, int buf_size);
-static u32 lpc288x_wait_status_busy(flash_bank_t *bank, int timeout);
-static void lpc288x_load_timer(int erase, struct target_s *target);
+static uint32_t lpc288x_wait_status_busy(struct flash_bank_s *bank, int timeout);
+static void lpc288x_load_timer(int erase, struct target *target);
 static void lpc288x_set_flash_clk(struct flash_bank_s *bank);
-static u32 lpc288x_system_ready(struct flash_bank_s *bank);
-
-flash_driver_t lpc288x_flash =
-{
-       .name = "lpc288x",
-       .register_commands = lpc288x_register_commands,
-       .flash_bank_command = lpc288x_flash_bank_command,
-       .erase = lpc288x_erase,
-       .protect = lpc288x_protect,
-       .write = lpc288x_write,
-       .probe = lpc288x_probe,
-       .auto_probe = lpc288x_probe,
-       .erase_check = lpc288x_erase_check,
-       .protect_check = lpc288x_protect_check,
-       .info = lpc288x_info
-};
-
-static int lpc288x_register_commands(struct command_context_s *cmd_ctx)
-{
-       return ERROR_OK;
-}
+static uint32_t lpc288x_system_ready(struct flash_bank_s *bank);
 
-static u32 lpc288x_wait_status_busy(flash_bank_t *bank, int timeout)
+static uint32_t lpc288x_wait_status_busy(flash_bank_t *bank, int timeout)
 {
-       u32 status;
-       target_t *target = bank->target;
+       uint32_t status;
+       struct target *target = bank->target;
        do
        {
                alive_sleep(1);
                timeout--;
                target_read_u32(target, F_STAT, &status);
-       }while (((status & FS_DONE) == 0) && timeout);
-       
-       if(timeout == 0)
+       } while (((status & FS_DONE) == 0) && timeout);
+
+       if (timeout == 0)
        {
                LOG_DEBUG("Timedout!");
                return ERROR_FLASH_OPERATION_FAILED;
@@ -150,34 +111,34 @@ static u32 lpc288x_wait_status_busy(flash_bank_t *bank, int timeout)
 /* Read device id register and fill in driver info structure */
 static int lpc288x_read_part_info(struct flash_bank_s *bank)
 {
-       lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
-       target_t *target = bank->target;
-       u32 cidr;
-       
+       struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
+       struct target *target = bank->target;
+       uint32_t cidr;
+
        int i = 0;
-       u32 offset;
-       
+       uint32_t offset;
+
        if (lpc288x_info->cidr == 0x0102100A)
                return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */
-               
+
        /* Read and parse chip identification register */
        target_read_u32(target, DBGU_CIDR, &cidr);
-       
+
        if (cidr != 0x0102100A)
        {
-               LOG_WARNING("Cannot identify target as an LPC288X (%08X)",cidr);
+               LOG_WARNING("Cannot identify target as an LPC288X (%08" PRIx32 ")",cidr);
                return ERROR_FLASH_OPERATION_FAILED;
        }
-       
+
        lpc288x_info->cidr = cidr;
        lpc288x_info->sector_size_break = 0x000F0000;
        lpc288x_info->target_name = "LPC288x";
-       
+
        /* setup the sector info... */
        offset = bank->base;
        bank->num_sectors = 23;
-       bank->sectors = malloc(sizeof(flash_sector_t) * 23);
-       
+       bank->sectors = malloc(sizeof(struct flash_sector) * 23);
+
        for (i = 0; i < 15; i++)
        {
                bank->sectors[i].offset = offset;
@@ -194,7 +155,7 @@ static int lpc288x_read_part_info(struct flash_bank_s *bank)
                bank->sectors[i].is_erased = -1;
                bank->sectors[i].is_protected = 1;
        }
-       
+
        return ERROR_OK;
 }
 
@@ -204,35 +165,35 @@ static int lpc288x_protect_check(struct flash_bank_s *bank)
 }
 
 /* flash_bank LPC288x 0 0 0 0 <target#> <cclk> */
-static int lpc288x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
+FLASH_BANK_COMMAND_HANDLER(lpc288x_flash_bank_command)
 {
-       lpc288x_flash_bank_t *lpc288x_info;
-       
+       struct lpc288x_flash_bank *lpc288x_info;
+
        if (argc < 6)
        {
                LOG_WARNING("incomplete flash_bank LPC288x configuration");
                return ERROR_FLASH_BANK_INVALID;
        }
-       
-       lpc288x_info = malloc(sizeof(lpc288x_flash_bank_t));
+
+       lpc288x_info = malloc(sizeof(struct lpc288x_flash_bank));
        bank->driver_priv = lpc288x_info;
-       
+
        /* part wasn't probed for info yet */
        lpc288x_info->cidr = 0;
-       lpc288x_info->cclk = strtoul(args[6], NULL, 0);
-       
+       COMMAND_PARSE_NUMBER(u32, args[6], lpc288x_info->cclk);
+
        return ERROR_OK;
 }
 
-/* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
- * This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.
+/* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.
+ * This must be programmed such that the Flash Programming clock frequency is 66 kHz Â± 20%.
  * AHB = 12 MHz ?
  * 12000000/66000 = 182
  * CLK_DIV = 60 ? */
 static void lpc288x_set_flash_clk(struct flash_bank_s *bank)
 {
-       u32 clk_time;
-       lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
+       uint32_t clk_time;
+       struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
        clk_time = (lpc288x_info->cclk / 66000) / 3;
        target_write_u32(bank->target, F_CTRL, FC_CS | FC_WEN);
        target_write_u32(bank->target, F_CLK_TIME, clk_time);
@@ -240,11 +201,11 @@ static void lpc288x_set_flash_clk(struct flash_bank_s *bank)
 
 /* AHB tcyc (in ns) 83 ns
  * LOAD_TIMER_ERASE            FPT_TIME        = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512
- *                                                                     = 9412 (9500) (AN10548 9375)
+ *                                                                     = 9412 (9500) (AN10548 9375)
  * LOAD_TIMER_WRITE            FPT_TIME        = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512
- *                                                                     = 23 (75) (AN10548 72 - is this wrong?)
+ *                                                                     = 23 (75) (AN10548 72 - is this wrong?)
  * TODO: Sort out timing calcs ;) */
-static void lpc288x_load_timer(int erase, struct target_s *target)
+static void lpc288x_load_timer(int erase, struct target *target)
 {
        if (erase == LOAD_TIMER_ERASE)
        {
@@ -256,14 +217,14 @@ static void lpc288x_load_timer(int erase, struct target_s *target)
        }
 }
 
-static u32 lpc288x_system_ready(struct flash_bank_s *bank)
+static uint32_t lpc288x_system_ready(struct flash_bank_s *bank)
 {
-       lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
+       struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
        if (lpc288x_info->cidr == 0)
        {
                return ERROR_FLASH_BANK_NOT_PROBED;
        }
-       
+
        if (bank->target->state != TARGET_HALTED)
        {
                LOG_ERROR("Target not halted");
@@ -274,48 +235,48 @@ static u32 lpc288x_system_ready(struct flash_bank_s *bank)
 
 static int lpc288x_erase_check(struct flash_bank_s *bank)
 {
-       u32 status = lpc288x_system_ready(bank);        /* probed? halted? */
+       uint32_t status = lpc288x_system_ready(bank);   /* probed? halted? */
        if (status != ERROR_OK)
        {
                LOG_INFO("Processor not halted/not probed");
                return status;
        }
-       
+
        return ERROR_OK;
 }
 
 static int lpc288x_erase(struct flash_bank_s *bank, int first, int last)
 {
-       u32 status;
+       uint32_t status;
        int sector;
-       target_t *target = bank->target;
-       
+       struct target *target = bank->target;
+
        status = lpc288x_system_ready(bank);    /* probed? halted? */
        if (status != ERROR_OK)
        {
                return status;
        }
-       
+
        if ((first < 0) || (last < first) || (last >= bank->num_sectors))
        {
                LOG_INFO("Bad sector range");
                return ERROR_FLASH_SECTOR_INVALID;
        }
-       
+
        /* Configure the flash controller timing */
        lpc288x_set_flash_clk(bank);
-       
+
        for (sector = first; sector <= last; sector++)
        {
                if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)
                {
                        return ERROR_FLASH_OPERATION_FAILED;
                }
-               
+
                lpc288x_load_timer(LOAD_TIMER_ERASE,target);
-               
+
                target_write_u32(target, bank->sectors[sector].offset, 0x00);
-               
+
                target_write_u32(target, F_CTRL, FC_PROG_REQ | FC_PROTECT | FC_CS);
        }
        if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)
@@ -325,25 +286,25 @@ static int lpc288x_erase(struct flash_bank_s *bank, int first, int last)
        return ERROR_OK;
 }
 
-static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
+static int lpc288x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
 {
-       u8 page_buffer[FLASH_PAGE_SIZE];
-       u32 status, source_offset,dest_offset;
-       target_t *target = bank->target;
-       u32 bytes_remaining = count;
-       u32 first_sector, last_sector, sector, page;
+       uint8_t page_buffer[FLASH_PAGE_SIZE];
+       uint32_t status, source_offset,dest_offset;
+       struct target *target = bank->target;
+       uint32_t bytes_remaining = count;
+       uint32_t first_sector, last_sector, sector, page;
        int i;
-       
+
        /* probed? halted? */
        status = lpc288x_system_ready(bank);
        if (status != ERROR_OK)
        {
                return status;
        }
-       
+
        /* Initialise search indices */
        first_sector = last_sector = 0xffffffff;
-       
+
        /* validate the write range... */
        for (i = 0; i < bank->num_sectors; i++)
        {
@@ -355,7 +316,7 @@ static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32
                        /* all writes must start on a sector boundary... */
                        if (offset % bank->sectors[i].size)
                        {
-                               LOG_INFO("offset 0x%x breaks required alignment 0x%x", offset, bank->sectors[i].size);
+                               LOG_INFO("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32 "", offset, bank->sectors[i].size);
                                return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
                        }
                }
@@ -366,21 +327,21 @@ static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32
                        last_sector = i;
                }
        }
-       
+
        /* Range check... */
        if (first_sector == 0xffffffff || last_sector == 0xffffffff)
        {
-               LOG_INFO("Range check failed %x %x", offset, count);
+               LOG_INFO("Range check failed %" PRIx32 " %" PRIx32 "", offset, count);
                return ERROR_FLASH_DST_OUT_OF_BANK;
        }
-       
+
        /* Configure the flash controller timing */
        lpc288x_set_flash_clk(bank);
-       
+
        /* initialise the offsets */
        source_offset = 0;
        dest_offset = 0;
-       
+
        for (sector = first_sector; sector <= last_sector; sector++)
        {
                for (page = 0; page < bank->sectors[sector].size / FLASH_PAGE_SIZE; page++)
@@ -401,24 +362,24 @@ static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32
                                count = FLASH_PAGE_SIZE;
                                memcpy(page_buffer, &buffer[source_offset], count);
                        }
-                       
+
                        /* Wait for flash to become ready */
                        if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)
                        {
                                return ERROR_FLASH_OPERATION_FAILED;
                        }
-                       
+
                        /* fill flash data latches with 1's */
                        target_write_u32(target, F_CTRL, FC_CS | FC_SET_DATA | FC_WEN | FC_FUNC);
-                       
+
                        target_write_u32(target, F_CTRL, FC_CS | FC_WEN | FC_FUNC);
                        /*would be better to use the clean target_write_buffer() interface but
                         * it seems not to be a LOT slower....
                         * bulk_write_memory() is no quicker :(*/
 #if 1
-                       if (target->type->write_memory(target, offset + dest_offset, 4, 128, page_buffer) != ERROR_OK)
+                       if (target_write_memory(target, offset + dest_offset, 4, 128, page_buffer) != ERROR_OK)
                        {
-                               LOG_ERROR("Write failed s %x p %x", sector, page);
+                               LOG_ERROR("Write failed s %" PRIx32 " p %" PRIx32 "", sector, page);
                                return ERROR_FLASH_OPERATION_FAILED;
                        }
 #else
@@ -431,33 +392,33 @@ static int lpc288x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32
                        dest_offset += FLASH_PAGE_SIZE;
                        source_offset += count;
                        bytes_remaining -= count;
-                       
+
                        lpc288x_load_timer(LOAD_TIMER_WRITE, target);
-                       
+
                        target_write_u32(target, F_CTRL, FC_PROG_REQ | FC_PROTECT | FC_FUNC | FC_CS);
                }
        }
-       
+
        return ERROR_OK;
 }
 
 static int lpc288x_probe(struct flash_bank_s *bank)
 {
        /* we only deal with LPC2888 so flash config is fixed */
-       lpc288x_flash_bank_t *lpc288x_info = bank->driver_priv;
+       struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;
        int retval;
-       
+
        if (lpc288x_info->cidr != 0)
        {
                return ERROR_OK; /* already probed */
        }
-       
+
        if (bank->target->state != TARGET_HALTED)
        {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
-       
+
        retval = lpc288x_read_part_info(bank);
        if (retval != ERROR_OK)
                return retval;
@@ -473,24 +434,24 @@ static int lpc288x_info(struct flash_bank_s *bank, char *buf, int buf_size)
 static int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int last)
 {
        int lockregion, status;
-       u32 value;
-       target_t *target = bank->target;
-       
+       uint32_t value;
+       struct target *target = bank->target;
+
        /* probed? halted? */
-       status = lpc288x_system_ready(bank);   
+       status = lpc288x_system_ready(bank);
        if (status != ERROR_OK)
        {
                return status;
        }
-       
+
        if ((first < 0) || (last < first) || (last >= bank->num_sectors))
        {
                return ERROR_FLASH_SECTOR_INVALID;
        }
-       
+
        /* Configure the flash controller timing */
-       lpc288x_set_flash_clk(bank);   
-       
+       lpc288x_set_flash_clk(bank);
+
        for (lockregion = first; lockregion <= last; lockregion++)
        {
                if (set)
@@ -506,6 +467,19 @@ static int lpc288x_protect(struct flash_bank_s *bank, int set, int first, int la
                target_write_u32(target, bank->sectors[lockregion].offset, value);
                target_write_u32(target, F_CTRL, FC_LOAD_REQ | FC_PROTECT | FC_WEN | FC_FUNC | FC_CS);
        }
-       
+
        return ERROR_OK;
 }
+
+struct flash_driver lpc288x_flash = {
+               .name = "lpc288x",
+               .flash_bank_command = &lpc288x_flash_bank_command,
+               .erase = &lpc288x_erase,
+               .protect = &lpc288x_protect,
+               .write = &lpc288x_write,
+               .probe = &lpc288x_probe,
+               .auto_probe = &lpc288x_probe,
+               .erase_check = &lpc288x_erase_check,
+               .protect_check = &lpc288x_protect_check,
+               .info = &lpc288x_info,
+       };