Commit ba761c13 authored by Kevin Gillespie's avatar Kevin Gillespie Committed by Kevin

max32xxx: Cleanup, 128-bit flash, new targets.

Removing unused variable and buffer manipulation in
get_info function. Recompiling assembly files to
get propper data into write_code.

Adding support for 128-bit flash operations.

Adding configuration files for new targets. Moving common
configuration into shared file.

Change-Id: I043e861f958c6926a46735f23f6b6b466edf2a92
Signed-off-by: default avatarKevin Gillespie <kgills@gmail.com>
parent a4ac5615
/* Autogenerated with ../../../../src/helper/bin2char.sh */
0xdf,0xf8,0x44,0x40,0xd0,0xf8,0x00,0x80,0xb8,0xf1,0x00,0x0f,0x1a,0xd0,0x47,0x68,
0x47,0x45,0xf7,0xd0,0x22,0x60,0x02,0xf1,0x04,0x02,0x57,0xf8,0x04,0x8b,0xc4,0xf8,
0x30,0x80,0xa5,0x68,0x45,0xf0,0x01,0x05,0xa5,0x60,0xd4,0xf8,0x08,0x80,0x18,0xf0,
0x01,0x0f,0xfa,0xd1,0x8f,0x42,0x28,0xbf,0x00,0xf1,0x08,0x07,0x47,0x60,0x01,0x3b,
0x03,0xb1,0xdf,0xe7,0x00,0xbe,0x00,0xbf,0x00,0x00,0x00,0x40,
0xa6,0x68,0x46,0xf0,0x10,0x06,0xa6,0x60,0x15,0xf0,0x01,0x0f,0x03,0xd0,0xa6,0x68,
0x26,0xf0,0x10,0x06,0xa6,0x60,0xd0,0xf8,0x00,0x80,0xb8,0xf1,0x00,0x0f,0x55,0xd0,
0x47,0x68,0x47,0x45,0xf7,0xd0,0x22,0x60,0x02,0xf1,0x04,0x02,0x15,0xf0,0x01,0x0f,
0x01,0xd0,0x02,0xf1,0x0c,0x02,0x57,0xf8,0x04,0x8b,0xc4,0xf8,0x30,0x80,0x8f,0x42,
0x28,0xbf,0x00,0xf1,0x08,0x07,0x47,0x60,0x15,0xf0,0x01,0x0f,0x32,0xd0,0xd0,0xf8,
0x00,0x80,0xb8,0xf1,0x00,0x0f,0x39,0xd0,0x47,0x68,0x47,0x45,0xf7,0xd0,0x57,0xf8,
0x04,0x8b,0xc4,0xf8,0x34,0x80,0x8f,0x42,0x28,0xbf,0x00,0xf1,0x08,0x07,0x47,0x60,
0xd0,0xf8,0x00,0x80,0xb8,0xf1,0x00,0x0f,0x28,0xd0,0x47,0x68,0x47,0x45,0xf7,0xd0,
0x57,0xf8,0x04,0x8b,0xc4,0xf8,0x38,0x80,0x8f,0x42,0x28,0xbf,0x00,0xf1,0x08,0x07,
0x47,0x60,0xd0,0xf8,0x00,0x80,0xb8,0xf1,0x00,0x0f,0x17,0xd0,0x47,0x68,0x47,0x45,
0xf7,0xd0,0x57,0xf8,0x04,0x8b,0xc4,0xf8,0x3c,0x80,0x8f,0x42,0x28,0xbf,0x00,0xf1,
0x08,0x07,0x47,0x60,0xa6,0x68,0x46,0xf0,0x01,0x06,0xa6,0x60,0xd4,0xf8,0x08,0x80,
0x18,0xf0,0x07,0x0f,0xfa,0xd1,0x01,0x3b,0x03,0xb1,0xa4,0xe7,0xa6,0x68,0x46,0xf0,
0x10,0x06,0xa6,0x60,0x00,0xbe,
......@@ -27,44 +27,120 @@
* r0 = workarea start
* r1 = workarea end
* r2 = target address
* r3 = count (32bit words)
* r3 = count (number of writes)
* r4 = pFLASH_CTRL_BASE
*
* r5 = 128-bit write
* Clobbered:
* r5 = FLASHWRITECMD
* r6 = FLASHWRITECMD
* r7 - rp
* r8 - wp, tmp
*/
write:
/* write in 32-bit units by default */
ldr r6, [r4, #0x08] /* FLSH_CN */
orr r6, r6, #0x10 /* Width 32 bits */
str r6, [r4, #0x08] /* FLSH_CN */
tst r5, #1 /* Check 32-bit write options */
beq wait_fifo
/* Enable 128-bit write */
ldr r6, [r4, #0x08] /* FLSH_CN */
bic r6, r6, #0x10 /* Width 128 bits */
str r6, [r4, #0x08] /* FLSH_CN */
wait_fifo:
ldr r8, [r0, #0] /* read wp */
cmp r8, #0 /* abort if wp == 0 */
beq exit
ldr r7, [r0, #4] /* read rp */
cmp r7, r8 /* wait until rp != wp */
beq wait_fifo
ldr r8, [r0, #0x00] /* read wp */
cmp r8, #0x00 /* abort if wp == 0 */
beq exit
ldr r7, [r0, #0x04] /* read rp */
cmp r7, r8 /* wait until rp != wp */
beq wait_fifo
mainloop:
str r2, [r4, #0x00] /* FLSH_ADDR - write address */
add r2, r2, #4 /* increment target address */
ldr r8, [r7], #4
str r8, [r4, #0x30] /* FLSH_DATA0 - write data */
ldr r5, [r4, #0x08] /* FLSH_CN */
orr r5, r5, #1
str r5, [r4, #0x08] /* FLSH_CN - enable write */
str r2, [r4, #0x00] /* FLSH_ADDR - write address */
add r2, r2, #0x04 /* increment target address */
tst r5, #1 /* Check 32-bit write options */
beq inc32
add r2, r2, #0x0C /* additional 12 if 128-bit write*/
inc32:
ldr r8, [r7], #0x04
str r8, [r4, #0x30] /* FLSH_DATA0 - write data */
cmp r7, r1 /* wrap rp at end of buffer */
it cs
addcs r7, r0, #0x08 /* skip loader args */
str r7, [r0, #0x04] /* store rp */
tst r5, #1 /* Check 32-bit write options */
beq write32
wait_fifo0:
ldr r8, [r0, #0x00] /* read wp */
cmp r8, #0x00 /* abort if wp == 0 */
beq exit
ldr r7, [r0, #0x04] /* read rp */
cmp r7, r8 /* wait until rp != wp */
beq wait_fifo0
ldr r8, [r7], #0x04
str r8, [r4, #0x34] /* FLSH_DATA1 - write data */
cmp r7, r1 /* wrap rp at end of buffer */
it cs
addcs r7, r0, #0x08 /* skip loader args */
str r7, [r0, #0x04] /* store rp */
wait_fifo1:
ldr r8, [r0, #0x00] /* read wp */
cmp r8, #0x00 /* abort if wp == 0 */
beq exit
ldr r7, [r0, #0x04] /* read rp */
cmp r7, r8 /* wait until rp != wp */
beq wait_fifo1
ldr r8, [r7], #0x04
str r8, [r4, #0x38] /* FLSH_DATA2 - write data */
cmp r7, r1 /* wrap rp at end of buffer */
it cs
addcs r7, r0, #0x08 /* skip loader args */
str r7, [r0, #0x04] /* store rp */
wait_fifo2:
ldr r8, [r0, #0x00] /* read wp */
cmp r8, #0x00 /* abort if wp == 0 */
beq exit
ldr r7, [r0, #0x04] /* read rp */
cmp r7, r8 /* wait until rp != wp */
beq wait_fifo2
ldr r8, [r7], #0x04
str r8, [r4, #0x3C] /* FLSH_DATA3 - write data */
cmp r7, r1 /* wrap rp at end of buffer */
it cs
addcs r7, r0, #0x08 /* skip loader args */
str r7, [r0, #0x04] /* store rp */
write32:
ldr r6, [r4, #0x08] /* FLSH_CN */
orr r6, r6, #0x01 /* WE */
str r6, [r4, #0x08] /* FLSH_CN - enable write */
busy:
ldr r8, [r4, #0x08] /* FLSH_CN */
tst r8, #1
bne busy
cmp r7, r1 /* wrap rp at end of buffer */
it cs
addcs r7, r0, #8 /* skip loader args */
str r7, [r0, #4] /* store rp */
subs r3, r3, #1 /* decrement word count */
cbz r3, exit /* loop if not done */
b wait_fifo
ldr r8, [r4, #0x08] /* FLSH_CN */
tst r8, #0x07
bne busy
subs r3, r3, #0x01 /* decrement write count */
cbz r3, exit /* loop if not done */
b wait_fifo
exit:
bkpt
/* restore flash settings */
ldr r6, [r4, #0x08] /* FLSH_CN */
orr r6, r6, #0x10 /* Width 32 bits */
str r6, [r4, #0x08] /* FLSH_CN */
bkpt
......@@ -24,48 +24,71 @@
#include <target/algorithm.h>
#include <target/armv7m.h>
/* Register Addresses */
#define FLSH_ADDR 0x000
#define FLSH_CLKDIV 0x004
#define FLSH_CN 0x008
#define PR1E_ADDR 0x00C
#define PR2S_ADDR 0x010
#define PR2E_ADDR 0x014
#define PR3S_ADDR 0x018
#define PR3E_ADDR 0x01C
#define FLSH_MD 0x020
#define FLSH_INT 0x024
#define FLSH_DATA0 0x030
#define FLSH_DATA1 0x034
#define FLSH_DATA2 0x038
#define FLSH_DATA3 0x03C
#define FLSH_BL_CTRL 0x170
#define FLSH_PROT 0x300
#define ARM_PID_REG 0xE00FFFE0
#define MAX326XX_ID_REG 0x40000838
/* Register addresses */
#define FLC_ADDR 0x00000000
#define FLC_CLKDIV 0x00000004
#define FLC_CN 0x00000008
#define FLC_PR1E_ADDR 0x0000000C
#define FLC_PR2S_ADDR 0x00000010
#define FLC_PR2E_ADDR 0x00000014
#define FLC_PR3S_ADDR 0x00000018
#define FLC_PR3E_ADDR 0x0000001C
#define FLC_MD 0x00000020
#define FLC_INT 0x00000024
#define FLC_DATA0 0x00000030
#define FLC_DATA1 0x00000034
#define FLC_DATA2 0x00000038
#define FLC_DATA3 0x0000003C
#define FLC_BL_CTRL 0x00000170
#define FLC_PROT 0x00000300
#define ARM_PID_REG 0xE00FFFE0
#define MAX326XX_ID_REG 0x40000838
/* Register settings */
#define FLSH_INT_AF 0x00000002
#define FLSH_CN_UNLOCK_MASK 0xF0000000
#define FLSH_CN_UNLOCK_VALUE 0x20000000
#define FLSH_CN_PEND 0x01000000
#define FLSH_CN_ERASE_CODE_MASK 0x0000FF00
#define FLSH_CN_ERASE_CODE_PGE 0x00005500
#define FLSH_CN_ERASE_CODE_ME 0x0000AA00
#define FLSH_CN_PGE 0x00000004
#define FLSH_CN_ME 0x00000002
#define FLSH_CN_WR 0x00000001
#define FLASH_BL_CTRL_23 0x00020000
#define FLASH_BL_CTRL_IFREN 0x00000001
#define ARM_PID_DEFAULT_CM3 0xB4C3
#define ARM_PID_DEFAULT_CM4 0xB4C4
#define MAX326XX_ID 0x4D
#define FLC_INT_AF 0x00000002
#define FLC_CN_UNLOCK_MASK 0xF0000000
#define FLC_CN_UNLOCK_VALUE 0x20000000
#define FLC_CN_PEND 0x01000000
#define FLC_CN_ERASE_CODE_MASK 0x0000FF00
#define FLC_CN_ERASE_CODE_PGE 0x00005500
#define FLC_CN_ERASE_CODE_ME 0x0000AA00
#define FLC_CN_32BIT 0x00000010
#define FLC_CN_PGE 0x00000004
#define FLC_CN_ME 0x00000002
#define FLC_CN_WR 0x00000001
#define FLC_CN_PGE 0x00000004
#define FLC_CN_ME 0x00000002
#define FLC_CN_WR 0x00000001
#define FLC_BL_CTRL_23 0x00020000
#define FLC_BL_CTRL_IFREN 0x00000001
#define MASK_FLASH_BUSY (0x048800E0 & ~0x04000000)
#define MASK_DISABLE_INTS (0xFFFFFCFC)
#define MASK_FLASH_UNLOCKED (0xF588FFEF & ~0x04000000)
#define MASK_FLASH_LOCK (0xF588FFEF & ~0x04000000)
#define MASK_FLASH_ERASE (0xF588FFEF & ~0x04000000)
#define MASK_FLASH_ERASED (0xF48800EB & ~0x04000000)
#define MASK_ACCESS_VIOLATIONS (0xFFFFFCFC)
#define MASK_FLASH_WRITE (0xF588FFEF & ~0x04000000)
#define MASK_WRITE_ALIGNED (0xF588FFEF & ~0x04000000)
#define MASK_WRITE_COMPLETE (0xF488FFEE & ~0x04000000)
#define MASK_WRITE_BURST (0xF588FFEF & ~0x04000000)
#define MASK_BURST_COMPLETE (0xF488FFEE & ~0x04000000)
#define MASK_WRITE_REMAINING (0xF588FFEF & ~0x04000000)
#define MASK_REMAINING_COMPLETE (0xF488FFEE & ~0x04000000)
#define MASK_MASS_ERASE (0xF588FFEF & ~0x04000000)
#define MASK_ERASE_COMPLETE (0xF48800ED & ~0x04000000)
#define ARM_PID_DEFAULT_CM3 0x0000B4C3
#define ARM_PID_DEFAULT_CM4 0x0000B4C4
#define MAX326XX_ID 0x0000004D
#define WRITE32BIT 0
#define WRITE128BIT 1
static int max32xxx_mass_erase(struct flash_bank *bank);
......@@ -85,7 +108,7 @@ static const uint8_t write_code[] = {
#include "../../contrib/loaders/flash/max32xxx/max32xxx.inc"
};
/* Config Command: flash bank name driver base size chip_width bus_width target [driver_option]
/* Config Command: flash bank name driver base size chip_width bus_width target [driver_option]
flash bank max32xxx <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]
*/
FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command)
......@@ -93,7 +116,10 @@ FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command)
struct max32xxx_flash_bank *info;
if (CMD_ARGC < 9) {
LOG_WARNING("incomplete flash bank max32xxx configuration: <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]");
LOG_ERROR("incorrect flash bank max32xxx configuration: <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]");
return ERROR_FLASH_BANK_INVALID;
} else if (CMD_ARGC > 10) {
LOG_ERROR("incorrect flash bank max32xxx configuration: <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]");
return ERROR_FLASH_BANK_INVALID;
}
......@@ -103,10 +129,17 @@ FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], info->sector_size);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[8], info->clkdiv_value);
if (CMD_ARGC > 9)
if (CMD_ARGC == 10)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[9], info->burst_size_bits);
else
else {
/* Default burst size of 32 bits */
info->burst_size_bits = 32;
}
if ((info->burst_size_bits != 128) && (info->burst_size_bits != 32)) {
LOG_ERROR("Invalid burst size %d, must be 32 or 128", info->burst_size_bits);
return ERROR_FLASH_BANK_INVALID;
}
info->int_state = 0;
bank->driver_priv = info;
......@@ -115,75 +148,73 @@ FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command)
static int get_info(struct flash_bank *bank, char *buf, int buf_size)
{
int printed;
struct max32xxx_flash_bank *info = bank->driver_priv;
if (info->probed == 0)
return ERROR_FLASH_BANK_NOT_PROBED;
printed = snprintf(buf, buf_size, "\nMaxim Integrated max32xxx flash driver\n");
buf += printed;
buf_size -= printed;
snprintf(buf, buf_size, "\nMaxim Integrated max32xxx flash driver\n");
return ERROR_OK;
}
/***************************************************************************
* flash operations
***************************************************************************/
static int max32xxx_flash_busy(uint32_t flash_cn)
{
if (flash_cn & (FLC_CN_PGE | FLC_CN_ME | FLC_CN_WR))
return ERROR_FLASH_BUSY;
return ERROR_OK;
}
static int max32xxx_flash_op_pre(struct flash_bank *bank)
{
struct target *target = bank->target;
struct max32xxx_flash_bank *info = bank->driver_priv;
uint32_t flsh_cn;
uint32_t flash_cn;
uint32_t bootloader;
/* Check if the flash controller is busy */
target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
if (flsh_cn & (FLSH_CN_PEND | FLSH_CN_ERASE_CODE_MASK | FLSH_CN_PGE |
FLSH_CN_ME | FLSH_CN_WR))
target_read_u32(target, info->flc_base + FLC_CN, &flash_cn);
if (max32xxx_flash_busy(flash_cn))
return ERROR_FLASH_BUSY;
/* Refresh flash controller timing */
target_write_u32(target, info->flc_base + FLSH_CLKDIV, info->clkdiv_value);
target_write_u32(target, info->flc_base + FLC_CLKDIV, info->clkdiv_value);
/* Clear and disable flash programming interrupts */
target_read_u32(target, info->flc_base + FLSH_INT, &info->int_state);
target_write_u32(target, info->flc_base + FLSH_INT, 0x00000000);
target_read_u32(target, info->flc_base + FLC_INT, &info->int_state);
target_write_u32(target, info->flc_base + FLC_INT, 0);
/* Clear the lower bit in the bootloader configuration register in case flash page 0 has been replaced */
if (target_read_u32(target, info->flc_base + FLSH_BL_CTRL, &bootloader) != ERROR_OK) {
LOG_ERROR("Read failure on FLSH_BL_CTRL");
if (target_read_u32(target, info->flc_base + FLC_BL_CTRL, &bootloader) != ERROR_OK) {
LOG_ERROR("Read failure on FLC_BL_CTRL");
return ERROR_FAIL;
}
if (bootloader & FLASH_BL_CTRL_23) {
LOG_WARNING("FLSH_BL_CTRL indicates BL mode 2 or mode 3.");
if (bootloader & FLASH_BL_CTRL_IFREN) {
if (bootloader & FLC_BL_CTRL_23) {
LOG_WARNING("FLC_BL_CTRL indicates BL mode 2 or mode 3.");
if (bootloader & FLC_BL_CTRL_IFREN) {
LOG_WARNING("Flash page 0 swapped out, attempting to swap back in for programming");
bootloader &= ~(FLASH_BL_CTRL_IFREN);
if (target_write_u32(target, info->flc_base + FLSH_BL_CTRL, bootloader) != ERROR_OK) {
LOG_ERROR("Write failure on FLSH_BL_CTRL");
bootloader &= ~(FLC_BL_CTRL_IFREN);
if (target_write_u32(target, info->flc_base + FLC_BL_CTRL, bootloader) != ERROR_OK) {
LOG_ERROR("Write failure on FLC_BL_CTRL");
return ERROR_FAIL;
}
if (target_read_u32(target, info->flc_base + FLSH_BL_CTRL, &bootloader) != ERROR_OK) {
LOG_ERROR("Read failure on FLSH_BL_CTRL");
if (target_read_u32(target, info->flc_base + FLC_BL_CTRL, &bootloader) != ERROR_OK) {
LOG_ERROR("Read failure on FLC_BL_CTRL");
return ERROR_FAIL;
}
if (bootloader & FLASH_BL_CTRL_IFREN) {
/* Bummer */
if (bootloader & FLC_BL_CTRL_IFREN)
LOG_ERROR("Unable to swap flash page 0 back in. Writes to page 0 will fail.");
}
}
}
/* Unlock flash */
flsh_cn &= ~FLSH_CN_UNLOCK_MASK;
flsh_cn |= FLSH_CN_UNLOCK_VALUE;
target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
flash_cn &= ~(FLC_CN_UNLOCK_MASK);
flash_cn |= FLC_CN_UNLOCK_VALUE;
target_write_u32(target, info->flc_base + FLC_CN, flash_cn);
/* Confirm flash is unlocked */
target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
if ((flsh_cn & FLSH_CN_UNLOCK_VALUE) != FLSH_CN_UNLOCK_VALUE)
target_read_u32(target, info->flc_base + FLC_CN, &flash_cn);
if ((flash_cn & FLC_CN_UNLOCK_VALUE) != FLC_CN_UNLOCK_VALUE)
return ERROR_FAIL;
return ERROR_OK;
......@@ -193,15 +224,15 @@ static int max32xxx_flash_op_post(struct flash_bank *bank)
{
struct target *target = bank->target;
struct max32xxx_flash_bank *info = bank->driver_priv;
uint32_t flsh_cn;
uint32_t flash_cn;
/* Restore flash programming interrupts */
target_write_u32(target, info->flc_base + FLSH_INT, info->int_state);
target_write_u32(target, info->flc_base + FLC_INT, info->int_state);
/* Lock flash */
target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
flsh_cn &= ~FLSH_CN_UNLOCK_MASK;
target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
target_read_u32(target, info->flc_base + FLC_CN, &flash_cn);
flash_cn &= ~(FLC_CN_UNLOCK_MASK);
target_write_u32(target, info->flc_base + FLC_CN, flash_cn);
return ERROR_OK;
}
......@@ -225,7 +256,7 @@ static int max32xxx_protect_check(struct flash_bank *bank)
/* Check the protection */
for (i = 0; i < bank->num_sectors; i++) {
if (i%32 == 0)
target_read_u32(target, info->flc_base + FLSH_PROT + ((i/32)*4), &temp_reg);
target_read_u32(target, info->flc_base + FLC_PROT + ((i/32)*4), &temp_reg);
if (temp_reg & (0x1 << i%32))
bank->sectors[i].is_protected = 1;
......@@ -238,7 +269,7 @@ static int max32xxx_protect_check(struct flash_bank *bank)
static int max32xxx_erase(struct flash_bank *bank, int first, int last)
{
int banknr;
uint32_t flsh_cn, flsh_int;
uint32_t flash_cn, flash_int;
struct max32xxx_flash_bank *info = bank->driver_priv;
struct target *target = bank->target;
int retval;
......@@ -275,22 +306,22 @@ static int max32xxx_erase(struct flash_bank *bank, int first, int last)
erased = 1;
/* Address is first word in page */
target_write_u32(target, info->flc_base + FLSH_ADDR, banknr * info->sector_size);
target_write_u32(target, info->flc_base + FLC_ADDR, banknr * info->sector_size);
/* Write page erase code */
target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
flsh_cn |= FLSH_CN_ERASE_CODE_PGE;
target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
target_read_u32(target, info->flc_base + FLC_CN, &flash_cn);
flash_cn |= FLC_CN_ERASE_CODE_PGE;
target_write_u32(target, info->flc_base + FLC_CN, flash_cn);
/* Issue page erase command */
flsh_cn |= 0x4;
target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
flash_cn |= FLC_CN_PGE;
target_write_u32(target, info->flc_base + FLC_CN, flash_cn);
/* Wait until erase complete */
retry = 1000;
do {
target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
} while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
target_read_u32(target, info->flc_base + FLC_CN, &flash_cn);
} while ((--retry > 0) && max32xxx_flash_busy(flash_cn));
if (retry <= 0) {
LOG_ERROR("Timed out waiting for flash page erase @ 0x%08x",
......@@ -299,10 +330,10 @@ static int max32xxx_erase(struct flash_bank *bank, int first, int last)
}
/* Check access violations */
target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
if (flsh_int & FLSH_INT_AF) {
target_read_u32(target, info->flc_base + FLC_INT, &flash_int);
if (flash_int & FLC_INT_AF) {
LOG_ERROR("Error erasing flash page %i", banknr);
target_write_u32(target, info->flc_base + FLSH_INT, 0);
target_write_u32(target, info->flc_base + FLC_INT, 0);
max32xxx_flash_op_post(bank);
return ERROR_FLASH_OPERATION_FAILED;
}
......@@ -347,15 +378,15 @@ static int max32xxx_protect(struct flash_bank *bank, int set, int first, int las
for (page = first; page <= last; page++) {
if (set) {
/* Set the write/erase bit for this page */
target_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);
target_read_u32(target, info->flc_base + FLC_PROT + (page/32), &temp_reg);
temp_reg |= (0x1 << page%32);
target_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);
target_write_u32(target, info->flc_base + FLC_PROT + (page/32), temp_reg);
bank->sectors[page].is_protected = 1;
} else {
/* Clear the write/erase bit for this page */
target_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);
target_read_u32(target, info->flc_base + FLC_PROT + (page/32), &temp_reg);
temp_reg &= ~(0x1 << page%32);
target_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);
target_write_u32(target, info->flc_base + FLC_PROT + (page/32), temp_reg);
bank->sectors[page].is_protected = 0;
}
}
......@@ -372,7 +403,7 @@ static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
struct working_area *source;
struct working_area *write_algorithm;
uint32_t address = bank->base + offset;
struct reg_param reg_params[5];
struct reg_param reg_params[6];
struct armv7m_algorithm armv7m_info;
int retval = ERROR_OK;
/* power of two, and multiple of word size */
......@@ -418,14 +449,23 @@ static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);
init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
buf_set_u32(reg_params[0].value, 0, 32, source->address);
buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
buf_set_u32(reg_params[2].value, 0, 32, address);
buf_set_u32(reg_params[3].value, 0, 32, wcount);
buf_set_u32(reg_params[4].value, 0, 32, info->flc_base);
if (info->burst_size_bits == 32) {
buf_set_u32(reg_params[3].value, 0, 32, wcount);
buf_set_u32(reg_params[5].value, 0, 32, WRITE32BIT);
} else {
buf_set_u32(reg_params[3].value, 0, 32, wcount/4);
buf_set_u32(reg_params[5].value, 0, 32, WRITE128BIT);
}
retval = target_run_flash_async_algorithm(target, buffer, wcount, 4, 0, NULL,
5, reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info);
6, reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info);
if (retval == ERROR_FLASH_OPERATION_FAILED)
LOG_ERROR("error %d executing max32xxx flash write algorithm", retval);
......@@ -437,6 +477,7 @@ static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
destroy_reg_param(&reg_params[2]);
destroy_reg_param(&reg_params[3]);
destroy_reg_param(&reg_params[4]);
destroy_reg_param(&reg_params[5]);
return retval;
}
......@@ -445,7 +486,7 @@ static int max32xxx_write(struct flash_bank *bank, const uint8_t *buffer,
{
struct max32xxx_flash_bank *info = bank->driver_priv;
struct target *target = bank->target;
uint32_t flsh_cn, flsh_int;
uint32_t flash_cn, flash_int;
uint32_t address = offset;
uint32_t remaining = count;
uint32_t words_remaining;
......@@ -463,9 +504,16 @@ static int max32xxx_write(struct flash_bank *bank, const uint8_t *buffer,
if (info->probed == 0)
return ERROR_FLASH_BANK_NOT_PROBED;
if (offset & 0x3) {
LOG_WARNING("offset size must be word aligned");
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
if (info->burst_size_bits == 32) {
if (offset & 0x3) {
LOG_ERROR("offset size must be 32-bit aligned");
return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
}
} else {
if (offset & 0xF) {