nand_sam3.c
Go to the documentation of this file.00001
00038 #include <drv/nand.h>
00039 #include <cfg/log.h>
00040 #include <io/sam3.h>
00041 #include <drv/timer.h>
00042 #include <cpu/power.h>
00043
00044
00045
00046
00047
00048 #define NAND_PIN_CE BV(6)
00049 #define NAND_PIN_RB BV(2)
00050 #define NAND_PINS_PORTA (NAND_PIN_CE | NAND_PIN_RB)
00051 #define NAND_PERIPH_PORTA PIO_PERIPH_B
00052
00053 #define NAND_PIN_OE BV(19)
00054 #define NAND_PIN_WE BV(20)
00055 #define NAND_PIN_IO 0x0000FFFF
00056 #define NAND_PINS_PORTC (NAND_PIN_OE | NAND_PIN_WE | NAND_PIN_IO)
00057 #define NAND_PERIPH_PORTC PIO_PERIPH_A
00058
00059 #define NAND_PIN_CLE BV(9)
00060 #define NAND_PIN_ALE BV(8)
00061 #define NAND_PINS_PORTD (NAND_PIN_CLE | NAND_PIN_ALE)
00062 #define NAND_PERIPH_PORTD PIO_PERIPH_A
00063
00064
00065
00066
00067
00068
00069
00070 bool nand_waitReadyBusy(UNUSED_ARG(Nand *, chip), time_t timeout)
00071 {
00072 time_t start = timer_clock();
00073
00074 while (!(SMC_SR & SMC_SR_RB_EDGE0))
00075 {
00076 cpu_relax();
00077 if (timer_clock() - start > timeout)
00078 {
00079 LOG_INFO("nand: R/B timeout\n");
00080 return false;
00081 }
00082 }
00083
00084 return true;
00085 }
00086
00087
00088
00089
00090
00091
00092 bool nand_waitTransferComplete(UNUSED_ARG(Nand *, chip), time_t timeout)
00093 {
00094 time_t start = timer_clock();
00095
00096 while (!(SMC_SR & SMC_SR_XFRDONE))
00097 {
00098 cpu_relax();
00099 if (timer_clock() - start > timeout)
00100 {
00101 LOG_INFO("nand: xfer complete timeout\n");
00102 return false;
00103 }
00104 }
00105
00106 return true;
00107 }
00108
00109
00110
00111
00112
00113 void nand_sendCommand(Nand *chip,
00114 uint32_t cmd1, uint32_t cmd2,
00115 int num_cycles, uint32_t cycle0, uint32_t cycle1234)
00116 {
00117 reg32_t *cmd_addr;
00118 uint32_t cmd_val;
00119
00120 while (HWREG(NFC_CMD_BASE_ADDR + NFC_CMD_NFCCMD) & 0x8000000);
00121
00122 if (num_cycles == 5)
00123 SMC_ADDR = cycle0;
00124
00125 cmd_val = NFC_CMD_NFCCMD
00126 | ((chip->chip_select << NFC_CMD_CSID_SHIFT) & NFC_CMD_CSID_MASK)
00127 | ((num_cycles << NFC_CMD_ACYCLE_SHIFT) & NFC_CMD_ACYCLE_MASK)
00128 | cmd1 << 2
00129 | cmd2 << 10;
00130
00131
00132 if (cmd1 == NAND_CMD_WRITE_1 || cmd1 == NAND_CMD_READ_1 || cmd1 == NAND_CMD_READID)
00133 cmd_val |= NFC_CMD_NFCEN;
00134
00135
00136 if (cmd1 == NAND_CMD_WRITE_1)
00137 cmd_val |= NFC_CMD_NFCWR;
00138
00139
00140 if (cmd2)
00141 cmd_val |= NFC_CMD_VCMD2;
00142
00143 cmd_addr = (reg32_t *)(NFC_CMD_BASE_ADDR + cmd_val);
00144 *cmd_addr = cycle1234;
00145
00146 while (!(SMC_SR & SMC_SR_CMDDONE));
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156 uint8_t nand_getChipStatus(UNUSED_ARG(Nand *, chip))
00157 {
00158 return (uint8_t)HWREG(NFC_CMD_BASE_ADDR);
00159 }
00160
00161
00162
00163
00164
00165
00166 void *nand_dataBuffer(UNUSED_ARG(Nand *, chip))
00167 {
00168 return (void *)NFC_SRAM_BASE_ADDR;
00169 }
00170
00171
00172
00173
00174
00175 bool nand_checkEcc(UNUSED_ARG(Nand *, chip))
00176 {
00177 uint32_t sr1 = SMC_ECC_SR1;
00178 if (sr1)
00179 {
00180 LOG_INFO("ECC error, ECC_SR1=0x%lx\n", sr1);
00181 return false;
00182 }
00183 else
00184 return true;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 void nand_computeEcc(UNUSED_ARG(Nand *, chip),
00198 UNUSED_ARG(const void *, buf), UNUSED_ARG(size_t, size), uint32_t *ecc, size_t ecc_size)
00199 {
00200 size_t i;
00201 for (i = 0; i < ecc_size; i++)
00202 ecc[i] = *((reg32_t *)(SMC_BASE + SMC_ECC_PR0_OFF) + i);
00203 }
00204
00205
00206
00207
00208
00209 void nand_hwInit(UNUSED_ARG(Nand *, chip))
00210 {
00211
00212
00213
00214 pmc_periphEnable(PIOA_ID);
00215 pmc_periphEnable(PIOC_ID);
00216 pmc_periphEnable(PIOD_ID);
00217
00218 PIO_PERIPH_SEL(PIOA_BASE, NAND_PINS_PORTA, NAND_PERIPH_PORTA);
00219 PIOA_PDR = NAND_PINS_PORTA;
00220 PIOA_PUER = NAND_PINS_PORTA;
00221
00222 PIO_PERIPH_SEL(PIOC_BASE, NAND_PINS_PORTC, NAND_PERIPH_PORTC);
00223 PIOC_PDR = NAND_PINS_PORTC;
00224 PIOC_PUER = NAND_PINS_PORTC;
00225
00226 PIO_PERIPH_SEL(PIOD_BASE, NAND_PINS_PORTD, NAND_PERIPH_PORTD);
00227 PIOD_PDR = NAND_PINS_PORTD;
00228 PIOD_PUER = NAND_PINS_PORTD;
00229
00230 pmc_periphEnable(SMC_SDRAMC_ID);
00231
00232
00233 SMC_SETUP0 = SMC_SETUP_NWE_SETUP(0)
00234 | SMC_SETUP_NCS_WR_SETUP(0)
00235 | SMC_SETUP_NRD_SETUP(0)
00236 | SMC_SETUP_NCS_RD_SETUP(0);
00237
00238 SMC_PULSE0 = SMC_PULSE_NWE_PULSE(2)
00239 | SMC_PULSE_NCS_WR_PULSE(3)
00240 | SMC_PULSE_NRD_PULSE(2)
00241 | SMC_PULSE_NCS_RD_PULSE(3);
00242
00243 SMC_CYCLE0 = SMC_CYCLE_NWE_CYCLE(3)
00244 | SMC_CYCLE_NRD_CYCLE(3);
00245
00246 SMC_TIMINGS0 = SMC_TIMINGS_TCLR(1)
00247 | SMC_TIMINGS_TADL(6)
00248 | SMC_TIMINGS_TAR(4)
00249 | SMC_TIMINGS_TRR(2)
00250 | SMC_TIMINGS_TWB(9)
00251 | SMC_TIMINGS_RBNSEL(7)
00252 | SMC_TIMINGS_NFSEL;
00253
00254 SMC_MODE0 = SMC_MODE_READ_MODE
00255 | SMC_MODE_WRITE_MODE;
00256
00257 SMC_CFG = SMC_CFG_PAGESIZE_PS2048_64
00258 | SMC_CFG_EDGECTRL
00259 | SMC_CFG_DTOMUL_X1048576
00260 | SMC_CFG_DTOCYC(0xF)
00261 | SMC_CFG_WSPARE
00262 | SMC_CFG_RSPARE;
00263
00264
00265 SMC_IDR = ~0;
00266 SMC_CTRL = 0;
00267 SMC_CTRL = SMC_CTRL_NFCEN;
00268
00269
00270 SMC_ECC_CTRL = SMC_ECC_CTRL_SWRST;
00271 SMC_ECC_MD = SMC_ECC_MD_ECC_PAGESIZE_PS2048_64 | SMC_ECC_MD_TYPCORREC_C256B;
00272 }