diff --git a/arch/arm/src/sama5/chip/sam_hsmc.h b/arch/arm/src/sama5/chip/sam_hsmc.h index d7ea2837bb..cec7027ffd 100644 --- a/arch/arm/src/sama5/chip/sam_hsmc.h +++ b/arch/arm/src/sama5/chip/sam_hsmc.h @@ -79,31 +79,31 @@ #define SAM_HSMC_PMECCIMR_OFFSET 0x0094 /* PMECC Interrupt Mask Register */ #define SAM_HSMC_PMECCISR_OFFSET 0x0098 /* PMECC Interrupt Status Register */ /* 0x009c-0x00ac Reserved */ -#define SAM_HSMC_PMECC_OFFSET(sec) (0x00b0+((sec) << 6)) /* PMECC sector offset */ -#define SAM_HSMC_PMECC0_OFFSET(sec) (0x00b0+((sec) << 6)) /* PMECC Redundancy 0 Register */ -#define SAM_HSMC_PMECC1_OFFSET(sec) (0x00b4+((sec) << 6)) /* PMECC Redundancy 1 Register */ -#define SAM_HSMC_PMECC2_OFFSET(sec) (0x00b8+((sec) << 6)) /* PMECC Redundancy 2 Register */ -#define SAM_HSMC_PMECC3_OFFSET(sec) (0x00bc+((sec) << 6)) /* PMECC Redundancy 3 Register */ -#define SAM_HSMC_PMECC4_OFFSET(sec) (0x00c0+((sec) << 6)) /* PMECC Redundancy 4 Register */ -#define SAM_HSMC_PMECC5_OFFSET(sec) (0x00c4+((sec) << 6)) /* PMECC Redundancy 5 Register */ -#define SAM_HSMC_PMECC6_OFFSET(sec) (0x00c8+((sec) << 6)) /* PMECC Redundancy 6 Register */ -#define SAM_HSMC_PMECC7_OFFSET(sec) (0x00cc+((sec) << 6)) /* PMECC Redundancy 7 Register */ -#define SAM_HSMC_PMECC8_OFFSET(sec) (0x00d0+((sec) << 6)) /* PMECC Redundancy 8 Register */ -#define SAM_HSMC_PMECC9_OFFSET(sec) (0x00d4+((sec) << 6)) /* PMECC Redundancy 9 Register */ -#define SAM_HSMC_PMECC10_OFFSET(sec) (0x00d8+((sec) << 6)) /* PMECC Redundancy 10 Register */ -#define SAM_HSMC_PEM_OFFSET(sec) (0x02b0+((sec) << 6)) /* PMECC Remainder offset */ -#define SAM_HSMC_REM0_OFFSET(sec) (0x02b0+((sec) << 6)) /* PMECC Remainder 0 Register */ -#define SAM_HSMC_REM1_OFFSET(sec) (0x02b4+((sec) << 6)) /* PMECC Remainder 1 Register */ -#define SAM_HSMC_REM2_OFFSET(sec) (0x02b8+((sec) << 6)) /* PMECC Remainder 2 Register */ -#define SAM_HSMC_REM3_OFFSET(sec) (0x02bc+((sec) << 6)) /* PMECC Remainder 3 Register */ -#define SAM_HSMC_REM4_OFFSET(sec) (0x02b0+((sec) << 6)) /* PMECC Remainder 4 Register */ -#define SAM_HSMC_REM5_OFFSET(sec) (0x02b4+((sec) << 6)) /* PMECC Remainder 5 Register */ -#define SAM_HSMC_REM6_OFFSET(sec) (0x02b8+((sec) << 6)) /* PMECC Remainder 6 Register */ -#define SAM_HSMC_REM7_OFFSET(sec) (0x02bc+((sec) << 6)) /* PMECC Remainder 7 Register */ -#define SAM_HSMC_REM8_OFFSET(sec) (0x02b0+((sec) << 6)) /* PMECC Remainder 8 Register */ -#define SAM_HSMC_REM9_OFFSET(sec) (0x02b4+((sec) << 6)) /* PMECC Remainder 9 Register */ -#define SAM_HSMC_REM10_OFFSET(sec) (0x02b8+((sec) << 6)) /* PMECC Remainder 10 Register */ -#define SAM_HSMC_REM11_OFFSET(sec) (0x02bc+((sec) << 6)) /* PMECC Remainder 11 Register */ +#define SAM_HSMC_PMECC_OFFSET(n) (0x00b0 + ((n) << 6)) /* PMECC sector offset */ +# define SAM_HSMC_PMECC0_OFFSET(n) (0x00b0 + ((n) << 6)) /* PMECC Redundancy 0 Register */ +# define SAM_HSMC_PMECC1_OFFSET(n) (0x00b4 + ((n) << 6)) /* PMECC Redundancy 1 Register */ +# define SAM_HSMC_PMECC2_OFFSET(n) (0x00b8 + ((n) << 6)) /* PMECC Redundancy 2 Register */ +# define SAM_HSMC_PMECC3_OFFSET(n) (0x00bc + ((n) << 6)) /* PMECC Redundancy 3 Register */ +# define SAM_HSMC_PMECC4_OFFSET(n) (0x00c0 + ((n) << 6)) /* PMECC Redundancy 4 Register */ +# define SAM_HSMC_PMECC5_OFFSET(n) (0x00c4 + ((n) << 6)) /* PMECC Redundancy 5 Register */ +# define SAM_HSMC_PMECC6_OFFSET(n) (0x00c8 + ((n) << 6)) /* PMECC Redundancy 6 Register */ +# define SAM_HSMC_PMECC7_OFFSET(n) (0x00cc + ((n) << 6)) /* PMECC Redundancy 7 Register */ +# define SAM_HSMC_PMECC8_OFFSET(n) (0x00d0 + ((n) << 6)) /* PMECC Redundancy 8 Register */ +# define SAM_HSMC_PMECC9_OFFSET(n) (0x00d4 + ((n) << 6)) /* PMECC Redundancy 9 Register */ +# define SAM_HSMC_PMECC10_OFFSET(n) (0x00d8 + ((n) << 6)) /* PMECC Redundancy 10 Register */ +#define SAM_HSMC_REM_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder offset */ +# define SAM_HSMC_REM0_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder 0 Register */ +# define SAM_HSMC_REM1_OFFSET(n) (0x02b4 + ((n) << 6)) /* PMECC Remainder 1 Register */ +# define SAM_HSMC_REM2_OFFSET(n) (0x02b8 + ((n) << 6)) /* PMECC Remainder 2 Register */ +# define SAM_HSMC_REM3_OFFSET(n) (0x02bc + ((n) << 6)) /* PMECC Remainder 3 Register */ +# define SAM_HSMC_REM4_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder 4 Register */ +# define SAM_HSMC_REM5_OFFSET(n) (0x02b4 + ((n) << 6)) /* PMECC Remainder 5 Register */ +# define SAM_HSMC_REM6_OFFSET(n) (0x02b8 + ((n) << 6)) /* PMECC Remainder 6 Register */ +# define SAM_HSMC_REM7_OFFSET(n) (0x02bc + ((n) << 6)) /* PMECC Remainder 7 Register */ +# define SAM_HSMC_REM8_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder 8 Register */ +# define SAM_HSMC_REM9_OFFSET(n) (0x02b4 + ((n) << 6)) /* PMECC Remainder 9 Register */ +# define SAM_HSMC_REM10_OFFSET(n) (0x02b8 + ((n) << 6)) /* PMECC Remainder 10 Register */ +# define SAM_HSMC_REM11_OFFSET(n) (0x02bc + ((n) << 6)) /* PMECC Remainder 11 Register */ /* 0x04a0-0x04fc Reserved */ #define SAM_HSMC_ELCFG_OFFSET 0x0500 /* PMECC Error Location Configuration Register */ #define SAM_HSMC_ELPRIM_OFFSET 0x0504 /* PMECC Error Location Primitive Register */ @@ -115,7 +115,7 @@ #define SAM_HSMC_ELIMR_OFFSET 0x051c /* PMECC Error Location Interrupt Mask Register */ #define SAM_HSMC_ELISR_OFFSET 0x0520 /* PMECC Error Location Interrupt Status Register */ /* 0x0524-0x052c Reserved */ -#define SAM_HSMC_SIGMA_OFFSET(n) (0x0528+((n)<<2)) /* PMECC Error Location SIGMA n Register */ +#define SAM_HSMC_SIGMA_OFFSET(n) (0x0528 + ((n) << 2)) /* PMECC Error Location SIGMA n Register */ # define SAM_HSMC_SIGMA0_OFFSET 0x0528 /* PMECC Error Location SIGMA 0 Register */ # define SAM_HSMC_SIGMA1_OFFSET 0x052c /* PMECC Error Location SIGMA 1 Register */ # define SAM_HSMC_SIGMA2_OFFSET 0x0530 /* PMECC Error Location SIGMA 2 Register */ @@ -141,7 +141,7 @@ # define SAM_HSMC_SIGMA22_OFFSET 0x0580 /* PMECC Error Location SIGMA 22 Register */ # define SAM_HSMC_SIGMA23_OFFSET 0x0584 /* PMECC Error Location SIGMA 23 Register */ # define SAM_HSMC_SIGMA24_OFFSET 0x0588 /* PMECC Error Location SIGMA 24 Register */ -#define SAM_HSMC_ERRLOC_OFFSET(n) (0x058c+((n)<<2)) /* PMECC Error Location n Register */ +#define SAM_HSMC_ERRLOC_OFFSET(n) (0x058c + ((n) << 2)) /* PMECC Error Location n Register */ # define SAM_HSMC_ERRLOC0_OFFSET 0x058c /* PMECC Error Location 0 Register */ # define SAM_HSMC_ERRLOC1_OFFSET 0x0590 /* PMECC Error Location 1 Register */ # define SAM_HSMC_ERRLOC2_OFFSET 0x0594 /* PMECC Error Location 2 Register */ @@ -167,11 +167,11 @@ # define SAM_HSMC_ERRLOC22_OFFSET 0x05e4 /* PMECC Error Location 22 Register */ # define SAM_HSMC_ERRLOC23_OFFSET 0x05e8 /* PMECC Error Location 23 Register */ /* 0x05ec-0x05fc Reserved */ -#define SAM_HSMC_SETUP_OFFSET(cs) (0x0600+0x14*(cs)) /* HSMC Setup Register */ -#define SAM_HSMC_PULSE_OFFSET(cs) (0x0604+0x14*(cs)) /* HSMC Pulse Register */ -#define SAM_HSMC_CYCLE_OFFSET(cs) (0x0608+0x14*(cs)) /* HSMC Cycle Register */ -#define SAM_HSMC_TIMINGS_OFFSET(cs) (0x060c+0x14*(cs)) /* HSMC Timings Register */ -#define SAM_HSMC_MODE_OFFSET(cs) (0x0610+0x14*(cs)) /* HSMC Mode Register */ +#define SAM_HSMC_SETUP_OFFSET(n) (0x0600 + 0x14 * (n)) /* HSMC Setup Register */ +#define SAM_HSMC_PULSE_OFFSET(n) (0x0604 + 0x14 * (n)) /* HSMC Pulse Register */ +#define SAM_HSMC_CYCLE_OFFSET(n) (0x0608 + 0x14 * (n)) /* HSMC Cycle Register */ +#define SAM_HSMC_TIMINGS_OFFSET(n) (0x060c + 0x14 * (n)) /* HSMC Timings Register */ +#define SAM_HSMC_MODE_OFFSET(n) (0x0610 + 0x14 * (n)) /* HSMC Mode Register */ #define SAM_HSMC_OCMS_OFFSET 0x06a0 /* HSMC OCMS Register */ #define SAM_HSMC_KEY1_OFFSET 0x06a4 /* HSMC OCMS KEY1 Register */ #define SAM_HSMC_KEY2_OFFSET 0x06a8 /* HSMC OCMS KEY2 Register */ @@ -200,31 +200,31 @@ #define SAM_HSMC_PMECCIDR (SAM_HSMC_VBASE+SAM_HSMC_PMECCIDR_OFFSET) #define SAM_HSMC_PMECCIMR (SAM_HSMC_VBASE+SAM_HSMC_PMECCIMR_OFFSET) #define SAM_HSMC_PMECCISR (SAM_HSMC_VBASE+SAM_HSMC_PMECCISR_OFFSET) -#define SAM_HSMC_PMECC_BASE(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC_OFFSET(sec)) -# define SAM_HSMC_PMECC0(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC0_OFFSET(sec)) -# define SAM_HSMC_PMECC1(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC1_OFFSET(sec)) -# define SAM_HSMC_PMECC2(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC2_OFFSET(sec)) -# define SAM_HSMC_PMECC3(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC3_OFFSET(sec)) -# define SAM_HSMC_PMECC4(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC4_OFFSET(sec)) -# define SAM_HSMC_PMECC5(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC5_OFFSET(sec)) -# define SAM_HSMC_PMECC6(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC6_OFFSET(sec)) -# define SAM_HSMC_PMECC7(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC7_OFFSET(sec)) -# define SAM_HSMC_PMECC8(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC8_OFFSET(sec)) -# define SAM_HSMC_PMECC9(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC9_OFFSET(sec)) -# define SAM_HSMC_PMECC10(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC10_OFFSET(sec)) -#define SAM_HSMC_REM_BASE(sec) (SAM_HSMC_VBASE+SAM_HSMC_PEM_OFFSET(sec)) -# define SAM_HSMC_REM0(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM0_OFFSET(sec)) -# define SAM_HSMC_REM1(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM1_OFFSET(sec)) -# define SAM_HSMC_REM2(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM2_OFFSET(sec)) -# define SAM_HSMC_REM3(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM3_OFFSET(sec)) -# define SAM_HSMC_REM4(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM4_OFFSET(sec)) -# define SAM_HSMC_REM5(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM5_OFFSET(sec)) -# define SAM_HSMC_REM6(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM6_OFFSET(sec)) -# define SAM_HSMC_REM7(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM7_OFFSET(sec)) -# define SAM_HSMC_REM8(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM8_OFFSET(sec)) -# define SAM_HSMC_REM9(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM9_OFFSET(sec)) -# define SAM_HSMC_REM10(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM10_OFFSET(sec)) -# define SAM_HSMC_REM11(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM11_OFFSET(sec)) +#define SAM_HSMC_PMECC_BASE(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC_OFFSET(n)) +# define SAM_HSMC_PMECC0(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC0_OFFSET(n)) +# define SAM_HSMC_PMECC1(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC1_OFFSET(n)) +# define SAM_HSMC_PMECC2(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC2_OFFSET(n)) +# define SAM_HSMC_PMECC3(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC3_OFFSET(n)) +# define SAM_HSMC_PMECC4(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC4_OFFSET(n)) +# define SAM_HSMC_PMECC5(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC5_OFFSET(n)) +# define SAM_HSMC_PMECC6(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC6_OFFSET(n)) +# define SAM_HSMC_PMECC7(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC7_OFFSET(n)) +# define SAM_HSMC_PMECC8(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC8_OFFSET(n)) +# define SAM_HSMC_PMECC9(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC9_OFFSET(n)) +# define SAM_HSMC_PMECC10(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC10_OFFSET(n)) +#define SAM_HSMC_REM_BASE(n) (SAM_HSMC_VBASE+SAM_HSMC_REM_OFFSET(n)) +# define SAM_HSMC_REM0(n) (SAM_HSMC_VBASE+SAM_HSMC_REM0_OFFSET(n)) +# define SAM_HSMC_REM1(n) (SAM_HSMC_VBASE+SAM_HSMC_REM1_OFFSET(n)) +# define SAM_HSMC_REM2(n) (SAM_HSMC_VBASE+SAM_HSMC_REM2_OFFSET(n)) +# define SAM_HSMC_REM3(n) (SAM_HSMC_VBASE+SAM_HSMC_REM3_OFFSET(n)) +# define SAM_HSMC_REM4(n) (SAM_HSMC_VBASE+SAM_HSMC_REM4_OFFSET(n)) +# define SAM_HSMC_REM5(n) (SAM_HSMC_VBASE+SAM_HSMC_REM5_OFFSET(n)) +# define SAM_HSMC_REM6(n) (SAM_HSMC_VBASE+SAM_HSMC_REM6_OFFSET(n)) +# define SAM_HSMC_REM7(n) (SAM_HSMC_VBASE+SAM_HSMC_REM7_OFFSET(n)) +# define SAM_HSMC_REM8(n) (SAM_HSMC_VBASE+SAM_HSMC_REM8_OFFSET(n)) +# define SAM_HSMC_REM9(n) (SAM_HSMC_VBASE+SAM_HSMC_REM9_OFFSET(n)) +# define SAM_HSMC_REM10(n) (SAM_HSMC_VBASE+SAM_HSMC_REM10_OFFSET(n)) +# define SAM_HSMC_REM11(n) (SAM_HSMC_VBASE+SAM_HSMC_REM11_OFFSET(n)) #define SAM_HSMC_ELCFG (SAM_HSMC_VBASE+SAM_HSMC_ELCFG_OFFSET) #define SAM_HSMC_ELPRIM (SAM_HSMC_VBASE+SAM_HSMC_ELPRIM_OFFSET) #define SAM_HSMC_ELEN (SAM_HSMC_VBASE+SAM_HSMC_ELEN_OFFSET) @@ -285,11 +285,11 @@ # define SAM_HSMC_ERRLOC21 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC21_OFFSET) # define SAM_HSMC_ERRLOC22 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC22_OFFSET) # define SAM_HSMC_ERRLOC23 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC23_OFFSET) -#define SAM_HSMC_SETUP(cs) (SAM_HSMC_VBASE+SAM_HSMC_SETUP_OFFSET(cs)) -#define SAM_HSMC_PULSE(cs) (SAM_HSMC_VBASE+SAM_HSMC_PULSE_OFFSET(cs)) -#define SAM_HSMC_CYCLE(cs) (SAM_HSMC_VBASE+SAM_HSMC_CYCLE_OFFSET(cs)) -#define SAM_HSMC_TIMINGS(cs) (SAM_HSMC_VBASE+SAM_HSMC_TIMINGS_OFFSET(cs)) -#define SAM_HSMC_MODE(cs) (SAM_HSMC_VBASE+SAM_HSMC_MODE_OFFSET(cs)) +#define SAM_HSMC_SETUP(n) (SAM_HSMC_VBASE+SAM_HSMC_SETUP_OFFSET(n)) +#define SAM_HSMC_PULSE(n) (SAM_HSMC_VBASE+SAM_HSMC_PULSE_OFFSET(n)) +#define SAM_HSMC_CYCLE(n) (SAM_HSMC_VBASE+SAM_HSMC_CYCLE_OFFSET(n)) +#define SAM_HSMC_TIMINGS(n) (SAM_HSMC_VBASE+SAM_HSMC_TIMINGS_OFFSET(n)) +#define SAM_HSMC_MODE(n) (SAM_HSMC_VBASE+SAM_HSMC_MODE_OFFSET(n)) #define SAM_HSMC_OCMS (SAM_HSMC_VBASE+SAM_HSMC_OCMS_OFFSET) #define SAM_HSMC_KEY1 (SAM_HSMC_VBASE+SAM_HSMC_KEY1_OFFSET) #define SAM_HSMC_KEY2 (SAM_HSMC_VBASE+SAM_HSMC_KEY2_OFFSET) @@ -428,7 +428,7 @@ /* PMECC Interrupt Status Register */ -#define HSMC_PMECCISR_ERRIS(sec) (1 << (sec)) /* Bits 0-7: Error Interrupt Status */ +#define HSMC_PMECCISR_ERRIS(n) (1 << (n)) /* Bits 0-7: Error Interrupt Status */ /* PMECC Redundancy x Register (32-bit ECC value) */ diff --git a/arch/arm/src/sama5/sam_dmac.c b/arch/arm/src/sama5/sam_dmac.c index d6831210e4..da58c2971c 100644 --- a/arch/arm/src/sama5/sam_dmac.c +++ b/arch/arm/src/sama5/sam_dmac.c @@ -58,6 +58,7 @@ #include "chip.h" #include "sam_dmac.h" #include "sam_periphclks.h" +#include "sam_memories.h" #include "chip/sam_pmc.h" #include "chip/sam_dmac.h" diff --git a/arch/arm/src/sama5/sam_nand.c b/arch/arm/src/sama5/sam_nand.c index 8227ba4d25..29c8fc38d3 100644 --- a/arch/arm/src/sama5/sam_nand.c +++ b/arch/arm/src/sama5/sam_nand.c @@ -220,7 +220,7 @@ static int nand_dma_write(struct sam_nandcs_s *priv, /* Raw Data Transfer Helpers */ static int nand_nfcsram_read(struct sam_nandcs_s *priv, - uint8_t *buffer, uint16_t buflen); + uint8_t *buffer, uint16_t buflen, uint16_t offset); #ifdef CONFIG_SAMA5_HAVE_PMECC static int nand_read(struct sam_nandcs_s *priv, uint8_t *buffer, uint16_t buflen); @@ -1466,13 +1466,18 @@ static int nand_dma_write(struct sam_nandcs_s *priv, ****************************************************************************/ static int nand_nfcsram_read(struct sam_nandcs_s *priv, uint8_t *buffer, - uint16_t buflen) + uint16_t buflen, uint16_t offset) { + uintptr_t src; int remaining; int ret; fvdbg("buffer=%p buflen=%d\n", buffer, buflen); + /* Get the offset data source address */ + + src = NFCSRAM_BASE + (uintptr_t)offset; + #ifdef CONFIG_SAMA5_NAND_DMA /* Then perform the transfer via memory-to-memory DMA or not, depending * on if we have a DMA channel assigned and if the transfer is @@ -1493,8 +1498,7 @@ static int nand_nfcsram_read(struct sam_nandcs_s *priv, uint8_t *buffer, /* Transfer using DMA */ - ret = nand_dma_read(priv, NFCSRAM_BASE, (uintptr_t)buffer, buflen, - dmaflags); + ret = nand_dma_read(priv, src, (uintptr_t)buffer, buflen, dmaflags); } else #endif @@ -1502,7 +1506,7 @@ static int nand_nfcsram_read(struct sam_nandcs_s *priv, uint8_t *buffer, /* Transfer without DMA */ { - uint8_t *src8 = (uint8_t *)NFCSRAM_BASE; + uint8_t *src8 = (uint8_t *)src; uint8_t *dest8 = buffer; for (remaining = buflen; remaining > 0; remaining--) @@ -1699,11 +1703,17 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block, nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DATA); +#if 0 /* Don't use NFC SRAM */ + nand_nfc_cleale(priv, + HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN | HSMC_CLE_VCMD2_EN | HSMC_CLE_DATA_EN, + COMMAND_READ_1, COMMAND_READ_2, 0, rowaddr); +#else nand_setup_rbedge(priv); nand_nfc_cleale(priv, HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN | HSMC_CLE_VCMD2_EN, COMMAND_READ_1, COMMAND_READ_2, 0, rowaddr); nand_wait_rbedge(priv); +#endif /* Reset the PMECC module */ @@ -1718,7 +1728,11 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block, * busy below would hang. */ +#if 0 /* Don't use NFC SRAM */ + ret = nand_nfcsram_read(priv, (uint8_t *)data, pagesize, 0); +#else ret = nand_read(priv, (uint8_t *)data, pagesize); +#endif if (ret < 0) { fdbg("ERROR: nand_read for data region failed: %d\n", ret); @@ -1727,7 +1741,11 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block, /* Now read the spare area into priv->raw.spare (sparesize bytes). */ +#if 0 /* Don't use NFC SRAM */ + ret = nand_nfcsram_read(priv, priv->raw.spare, sparesize, pagesize); +#else ret = nand_read(priv, priv->raw.spare, sparesize); +#endif if (ret < 0) { fdbg("ERROR: nand_read for spare region failed: %d\n", ret); @@ -1989,7 +2007,7 @@ static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block, if (data) { - ret = nand_nfcsram_read(priv, (uint8_t *)data, pagesize); + ret = nand_nfcsram_read(priv, (uint8_t *)data, pagesize, 0); if (ret < 0) { fdbg("ERROR: nand_nfcsram_read for data region failed: %d\n", ret); @@ -2004,7 +2022,7 @@ static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block, if (spare) { - ret = nand_nfcsram_read(priv, (uint8_t *)spare, sparesize); + ret = nand_nfcsram_read(priv, (uint8_t *)spare, sparesize, 0); if (ret < 0) { fdbg("ERROR: nand_nfcsram_read for spare region failed: %d\n", ret); @@ -2309,7 +2327,7 @@ static int nand_writepage_noecc(struct sam_nandcs_s *priv, off_t block, #ifdef CONFIG_SAMA5_HAVE_PMECC static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, - unsigned int page, const void *data) + unsigned int page, const void *data) { uint32_t regval; volatile uint8_t *pmecc; @@ -2348,23 +2366,21 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, /* Calculate physical address of the page */ rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page; - fvdbg("pagesize=%d eccsaddr=%d rowaddr=%d\n", pagesize, eccsaddr, rowaddr); - /* Write data area if needed */ +#if 1 /* Use NFC SRAM */ + /* Write the data area to NFC SRAM */ - if (data) + ret = nand_nfcsram_write(priv, (uint8_t *)data, pagesize, 0); + if (ret < 0) { - ret = nand_nfcsram_write(priv, (uint8_t *)data, pagesize, 0); - if (ret < 0) - { - fdbg("ERROR: Block %d page %d nand_nfcsram_write for data region failed: %d\n", - block, page, ret); - goto errout; - } + fdbg("ERROR: Block %d page %d nand_nfcsram_write for data region failed: %d\n", + block, page, ret); + goto errout; } +#endif - /* Get the number of sectors per page */ + /* Get the encoded number of sectors per page */ switch (pmecc_get_pagesize()) { @@ -2402,7 +2418,8 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, regval |= HSMC_PMECCFG_NANDWR_WRITE; nand_putreg(SAM_HSMC_PMECCFG, regval); - /* Configure the NFC */ +#if 1 /* Use NFC SRAM */ + /* Setup the NFC and wait for the transfer to complete */ nand_setup_xfrdone(priv); nand_nfc_cleale(priv, @@ -2410,16 +2427,34 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, HSMC_ALE_ROW_EN | HSMC_CLE_DATA_EN, COMMAND_WRITE_1, 0, 0, rowaddr); nand_wait_xfrdone(priv); +#else + /* Setup the for the data transfer */ nand_nfc_cleale(priv, - HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN, + HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN, + COMMAND_WRITE_1, 0, 0, rowaddr); + + /* Transfer the data via the NAND */ + + ret = nand_write(priv, (uint8_t *)data, pagesize, 0); + if (ret < 0) + { + fdbg("ERROR: Block %d page %d nand_write for data region failed: %d\n", + block, page, ret); + goto errout; + } +#endif + + /* Set up for the ECC transfer */ + + nand_nfc_cleale(priv, HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN, COMMAND_RANDOM_IN, 0, eccsaddr, 0); /* Wait until the kernel of the PMECC is not busy */ while ((nand_getreg(SAM_HSMC_PMECCSR) & HSMC_PMECCSR_BUSY) != 0); - /* Write the ECC */ + /* Get the ECC values from the PMECC */ eccpersector = (pmecc_get_eccsize()) / sectersperpage; eccsize = sectersperpage * eccpersector; @@ -2430,8 +2465,9 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, #ifdef CONFIG_SAMA5_PMECC_TRIMPAGE if (nand_trrimffs(priv) && page >= nand_get_trimpage(priv)) { - /* This behaviour was found to fix both UBI and JFFS2 images written to - * cleanly erased NAND partitions + /* Comments in the Atmel sample say that this behavior was found to + * fix both UBI and JFFS2 images written to cleanly erased NAND + * partitions */ memset(g_nand.ecctab, 0xff, eccsize); @@ -2455,6 +2491,8 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, } } + /* Write the ECC to NAND */ + ret = nand_write(priv, (uint8_t *)g_nand.ecctab, eccsize, 0); if (ret < 0) { @@ -3017,20 +3055,14 @@ struct mtd_dev_s *sam_nand_initialize(int cs) return NULL; } +#ifdef CONFIG_SAMA5_NAND_DMA /* Allocate a DMA channel for NAND transfers. The channels will be - * configured as needed on-the-fly + * configured as needed on-the-fly. NOTE that no failure is declared + * if we fail to allocate DMA channel; in that case, only non-DMA + * transfers will be performed. */ -#ifdef CONFIG_SAMA5_NAND_DMA - if (nandmodel_getbuswidth(&priv->raw.model) == 16) - { - priv->dma = sam_dmachannel(NAND_DMAC, 0); - } - else - { - priv->dma = sam_dmachannel(NAND_DMAC, 0); - } - + priv->dma = sam_dmachannel(NAND_DMAC, 0); if (!priv->dma) { fdbg("ERROR: Failed to allocate the DMA channel for CS%d\n", cs); diff --git a/configs/sama5d3x-ek/README.txt b/configs/sama5d3x-ek/README.txt index 6a3743bab2..4c14af7d3e 100644 --- a/configs/sama5d3x-ek/README.txt +++ b/configs/sama5d3x-ek/README.txt @@ -99,7 +99,7 @@ Contents Development Environment ======================= - Several possibile development enviorments may be use: + Several possible development environments may be use: - Linux or OSX native - Cygwin unders Windows @@ -160,7 +160,7 @@ GNU Toolchain Options An alias in your .bashrc file might make that less painful. 3. Dependencies are not made when using Windows versions of the GCC. This is - because the dependencies are generated using Windows pathes which do not + because the dependencies are generated using Windows paths which do not work with the Cygwin make. MKDEP = $(TOPDIR)/tools/mknulldeps.sh @@ -253,9 +253,9 @@ NuttX OABI "buildroot" Toolchain ================================ The older, OABI buildroot toolchain is also available. To use the OABI - toolchain, use the build instructtions above, but (1) modify the + toolchain, use the build instructions above, but (1) modify the cortexm3-eabi-defconfig-4.6.3 configuration to use OABI (using 'make - menuconfig'), or (2) use an exising OABI configuration such as + menuconfig'), or (2) use an existing OABI configuration such as cortexm3-defconfig-4.3.3 NXFLAT Toolchain @@ -321,9 +321,9 @@ Writing to FLASH using SAM-BA Assumed starting configuration: - 1. You have installed the J-Lnk CDC USB driver (Windows only, there is + 1. You have installed the J-Link CDC USB driver (Windows only, there is no need to install a driver on any regular Linux distribution), - 2. You have the USB connected to DBGU poort (J14) + 2. You have the USB connected to DBGU port (J14) 3. Terminal configuration: 115200 8N1 Using SAM-BA to write to FLASH: @@ -507,7 +507,7 @@ Buttons and LEDs LED_IDLE MCU is is sleep mode Not used Thus if the blue LED is statically on, NuttX has successfully booted and - is, apparently, running normmally. If the red is flashing at + is, apparently, running normally. If the red is flashing at approximately 2Hz, then a fatal error has been detected and the system has halted. @@ -817,11 +817,11 @@ HSMCI Card Slots -------------- The SAMA5D3x-EK provides a two SD memory card slots: (1) a full size SD - card slot (J7 labeled MCI0), and (2) a microSD memory card slot (J6 - labeled MCI1). + card slot (J7 labelled MCI0), and (2) a microSD memory card slot (J6 + labelled MCI1). The full size SD card slot connects via HSMCI0. The card detect discrete - is available on PB17 (pulled high). The write protect descrete is tied to + is available on PB17 (pulled high). The write protect discrete is tied to ground (via PP6) and not available to software. The slot supports 8-bit wide transfer mode, but the NuttX driver currently uses only the 4-bit wide transfer mode @@ -853,9 +853,9 @@ HSMCI Card Slots ---------------------- Enabling HSMCI support. The SAMA5D3x-EK provides a two SD memory card - slots: (1) a full size SD card slot (J7 labeled MCI0), and (2) a - microSD memory card slot (J6 labeled MCI1). The full size SD card slot - connects via HSMCI0; the microSD connects vi HSMCI1. Supportfor both SD + slots: (1) a full size SD card slot (J7 labelled MCI0), and (2) a + microSD memory card slot (J6 labelled MCI1). The full size SD card slot + connects via HSMCI0; the microSD connects vi HSMCI1. Support for both SD slots can be enabled with the following settings: System Type->ATSAMA5 Peripheral Support @@ -942,7 +942,7 @@ USB Ports lower port All three USB host ports are equipped with 500 mA high-side power switch - for self-powered and buspowered applications. The USB device port feature + for self-powered and bus powered applications. The USB device port feature VBUS inserts detection function. Port A @@ -1073,7 +1073,7 @@ USB High-Speed Device There is normal console debug output available that can be enabled with CONFIG_DEBUG + CONFIG_DEBUG_USB. However, USB device operation is very - time critical and enabling this debug ouput WILL interfere with the + time critical and enabling this debug output WILL interfere with the operation of the UDPHS. USB device tracing is a less invasive way to get debug information: If tracing is enabled, the USB device will save encoded trace output in in-memory buffer; if the USB monitor is also @@ -1100,7 +1100,7 @@ USB High-Speed Device CONFIG_SYSTEM_USBMONITOR_TRACECONTROLLER=y CONFIG_SYSTEM_USBMONITOR_TRACEINTERRUPTS=y - NOTE: If USB debug output is also enabled, both outpus will appear on the + NOTE: If USB debug output is also enabled, both outputs will appear on the serial console. However, the debug output will be asynchronous with the trace output and, hence, difficult to interpret. @@ -1354,9 +1354,13 @@ NAND Support ============ NAND support is only partial in that there is no file system that works - with it properly. It should be considered a work in progress. You will - not want to use NAND unless you are interested in investing a little - effort. See the STATUS section below. + with it properly. Lower-level NAND support has been developed and + verified, but there is no way to use it in the current NuttX architecture + other than through the raw MTD interface. + + NAND should be considered a work in progress. You will not want to use + NAND unless you are interested in investing a little effort, particularly + in infrastructure. See the "STATUS SUMMARY" section below. NAND Support ------------ @@ -1365,11 +1369,10 @@ NAND Support NuttX configuration file as follows: Build Setup - CONFIG_EXPERIMENTAL=y : NXFFS implemention is incomplete and + CONFIG_EXPERIMENTAL=y : NXFFS implementation is incomplete and : not yet fully functional. - System Type -> SAMA5 Peripheal support - CONFIG_SAMA5_DMAC1=y : Use DMA1 for memory-to-memory DMA + System Type -> SAMA5 Peripheral support CONFIG_SAMA5_HSMC=y : Make sure that the SMC is enabled Drivers -> Memory Technology Device (MTD) Support @@ -1408,7 +1411,7 @@ NAND Support then start the image in NOR FLASH. See the discussion of the NORBOOT configuration in the "Creating and Using NORBOOT" section above. - NOTE thathere is jumper on the CM module that must be closed to enable + NOTE that there is jumper on the CM module that must be closed to enable use of the AT25 Serial Flash. Also, if you are using using SAM-BA, make sure that you load the NOR boot program into the boot area via the pull-down menu. @@ -1417,6 +1420,43 @@ NAND Support of this writing. The following sections discussion issues/problems with using NXFFS and FAT. + PMECC + ----- + + Hardware ECC calculation using the SAMA5D3's PMECC can be enable as + follows: + + Drivers -> Memory Technology Device (MTD) Support + CONFIG_MTD_NAND_SWECC=y : Don't use S/W ECC calculation + CONFIG_MTD_NAND_HWECC=y : Use H/W ECC instead + + System Type -> External Memory Configuration + CONFIG_SAMA5_EBICS3_SWECC=n : Don't use S/W ECC calculation + CONFIG_SAMA5_HAVE_PMECC=n : Use H/W ECC instead + + Other PMECC-related default settings should be okay. + + STATUS: As of the writing, NAND transfers using PMECC appear to + work correctly. However, the PMECC based systems do not work as + as well with FAT or NXFFS. My belief that that the FAT/NXFFS layers + are inappropriate for NAND and, as a result, happen not to work with + the PMECC ECC calculation. See also the "STATUS SUMMARY" section below. + + DMA Support + ----------- + + DMA support can be enabled as follows: + + System Type -> SAMA5 Peripheral support + CONFIG_SAMA5_DMAC0=y : Use DMAC0 for memory-to-memory DMA + + System Type -> External Memory Configuration + CONFIG_SAMA5_NAND_DMA=y : Use DMAC0 for NAND data transfers + + STATUS: DMA appears to be functional, but probably has not been + exercised enough to claim that with any certainty. See also the "STATUS + SUMMARY" section below. + NXFFS ----- @@ -1437,13 +1477,16 @@ NAND Support CONFIG_SAMA5_NAND_NXFFS=y : Use the NXFFS file system Other file systems are not recommended because only NXFFS can handle - bad blocks and only NXFFS performs wear-leveling. + bad blocks and only NXFFS performs wear-levelling. FAT --- - Another option is FAT. FAT, however, will not handle bad blocks and - does not perform any wear leveling. + Another option is FAT. FAT, however, is not appropriate for use with + NAND: FAT will not handle bad blocks, does not perform any wear + levelling, and may not conform to writing ordering requirements of NAND. + Also, there appear to be issues with FAT when PMECC is enabled (see + "STATUS SUMMARY" below). File Systems: CONFIG_FS_FAT=y : Enable the FAT FS @@ -1515,10 +1558,10 @@ NAND Support 2. On subsequent boots, after the NXFFS file system has been created the delay will be less. When the new file system is empty, it will be very fast. But the NAND-related boot time can become substantial - whenthere has been a lot of usage of the NAND. This is because + when there has been a lot of usage of the NAND. This is because NXFFS needs to scan the NAND device and build the in-memory dataset needed to access NAND and there is more that must be scanned after - the device has been used. You may want tocreate a separate thread at + the device has been used. You may want to create a separate thread at boot time to bring up NXFFS so that you don't delay the boot-to-prompt time excessively in these longer delay cases. @@ -1567,7 +1610,7 @@ NAND Support nsh> echo "This is a test" > /mnt/nand/atest.txt NOTE: This will take a long time because it will require reading, - modifying, and re-writting the 128KB erase page! + modifying, and re-writing the 128KB erase page! nsh> ls -l /mnt/nand /mnt/nand: @@ -1578,10 +1621,10 @@ NAND Support NOTES: - 1. Unlike NXFFS, FAT can work with NAND. But there are some - signifcant issues. + 1. Unlike NXFFS, FAT can work with NAND (at least with PMECC disabled). + But there are some significant issues. - 2. First, each NAND write access will cause a 256KB data transefer: It + 2. First, each NAND write access will cause a 256KB data transfer: It will read the entire 128KB erase block, modify it and write it back to memory. There is some caching logic so that this cached erase block can be re-used if possible and writes will be deferred as long @@ -1600,14 +1643,23 @@ NAND Support Another, less general, option would be support bad blocks within FAT. - STATUS - ------ + STATUS SUMMARY + -------------- - 1. PMECC has not been tested and is, most likely, non-functional. + 1. PMECC appears to be working in that I can write a NAND block with its + ECC and read the block back and verify that that is are no bit + failures. However, when attempting to work with FAT, it does not + work correctly: The MBR is written and read back correctly, but gets + corrupted later for unknown reasons. - 2. DMA works (with software ECC), but I see occasional wild memory - clobbering. DMA should not be used until this problem can be - worked out. + 2. DMA works (with software ECC), but I have seen occasional failurs. I + believe that these issue have been resolved but I recommend enabling + DMA with caution. + + In NuttX, DMA will also cost two context switches (and, hence, four + register state transfers). With smaller NAND page sizes (say 2KiB and + below), I would not expect a great performance improvement with DMA + for this reason. 3. NXFFS does not work with NAND. NAND differs from other other FLASH types several ways. For one thing, NAND requires error correction @@ -2102,7 +2154,7 @@ Watchdog Timer Drivers (this will automatically be selected): CONFIG_WATCHDOG=y : Enables watchdog timer driver support - Application Configuration -> Eamples + Application Configuration -> Examples CONFIG_EXAMPLES_WATCHDOG=y : Enable apps/examples/watchdog The WDT timer is driven off the slow, 32768Hz clock divided by 128. As a @@ -2165,7 +2217,7 @@ Touchscreen Testing These options may also be applied to enable a built-in touchscreen test application: - Applicaton Configuration: + Application Configuration: CONFIG_EXAMPLES_TOUCHSCREEN=y : Enable the touchscreen built-int test CONFIG_EXAMPLES_TOUCHSCREEN_MINOR=0 : To match the board selection CONFIG_EXAMPLES_TOUCHSCREEN_DEVPATH="/dev/input0" @@ -2213,7 +2265,7 @@ I2S Audio Support ================= The SAMA5D3x-EK has two devices on-board that can be used for verification - of I2S functionaly: HDMI and a WM8904 audio CODEC. As of this writing, + of I2S functionality: HDMI and a WM8904 audio CODEC. As of this writing, the I2S driver is present, but there are not drivers for either the HDMI or the WM8904. @@ -2377,7 +2429,7 @@ SAMA5D3x-EK Configuration Options CONFIG_ARCH_CALIBRATION - Enables some build in instrumentation that cause a 100 second delay during boot-up. This 100 second delay - serves no purpose other than it allows you to calibratre + serves no purpose other than it allows you to calibrate CONFIG_ARCH_LOOPSPERMSEC. You simply use a stop watch to measure the 100 second delay then adjust CONFIG_ARCH_LOOPSPERMSEC until the delay actually is 100 seconds. @@ -2642,8 +2694,8 @@ Configurations entitle "AT25 Serial FLASH" for detailed configuration settings. 7. Support for HSMCI car slots. The SAMA5D3x-EK provides a two SD memory - card slots: (1) a full size SD card slot (J7 labeled MCI0), and (2) - a microSD memory card slot (J6 labeled MCI1). The full size SD card + card slots: (1) a full size SD card slot (J7 labelled MCI0), and (2) + a microSD memory card slot (J6 labelled MCI1). The full size SD card slot connects via HSMCI0; the microSD connects vi HSMCI1. Relevant configuration settings can be found in the section entitle "HSMCI Card Slots" above. @@ -2762,7 +2814,7 @@ Configurations However, no built-in applications are selected in the base configuration. 5. This configuration has support for the FAT file system built in. However, - by default, there are no block drivers initializeed. The FAT file system can + by default, there are no block drivers initialized. The FAT file system can still be used to create RAM disks. 6. SDRAM support can be enabled by modifying your NuttX configuration as @@ -2825,7 +2877,7 @@ Configurations See the To-Do list below I2C - 2013-9-12: I have been unusuccessful getting the external serial + 2013-9-12: I have been unsuccessful getting the external serial AT24 EEPROM to work. I am pretty sure that this is a problem with my external AT24 board (the TWI0 bus hangs when the AT24 is plugged in). I will skip the AT24 integration since it is not on the critical @@ -2852,7 +2904,7 @@ Configurations The NxWM window manager is a tiny window manager tailored for use with smaller LCDs. It supports a toolchain, a start window, and multiple application windows. However, to make the best use of - the visible LCD space, only one application window is visiable at + the visible LCD space, only one application window is visible at at time. The NxWM window manager can be found here: diff --git a/configs/sama5d3x-ek/src/sam_nandflash.c b/configs/sama5d3x-ek/src/sam_nandflash.c index a597f0d558..6346f5d4d4 100644 --- a/configs/sama5d3x-ek/src/sam_nandflash.c +++ b/configs/sama5d3x-ek/src/sam_nandflash.c @@ -219,7 +219,7 @@ int sam_nand_automount(int minor) return ret; } #endif - /* Now we are initializeed */ + /* Now we are initialized */ initialized = true; }