📄 nand2k_x_hw.c
字号:
/*
**********************************************************************
* Micrium, Inc.
* 949 Crestview Circle
* Weston, FL 33327-1848
*
* uC/FS
*
* (c) Copyright 2001 - 2006, Micrium, Inc.
* All rights reserved.
*
***********************************************************************
----------------------------------------------------------------------
File : NAND2k_X_HW.c
Purpose : Large page NAND flash hardware layer for Atmel AT91SAM7xxx
----------------------------------------------------------------------
Known problems or limitations with current version
----------------------------------------------------------------------
None.
---------------------------END-OF-HEADER------------------------------
*/
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "FS_ConfDefaults.h"
#if FS_USE_NAND2K_DRIVER
#include "AT91SAM7S256.h"
#ifdef __ICCARM__
#define __inline inline __arm __ramfunc
#define OPTIMIZE __arm __ramfunc
#endif
#include "lib_AT91SAM7S256.h"
#include "at91sam7sxxx.h"
#include "NAND.h"
#include "NAND_2k_X_HW.h"
/*********************************************************************
*
* #define Macros
*
**********************************************************************
*/
#define FLASH_nCE_PA20_PIN_16 AT91C_PIO_PA20
#define FLASH_CLE_PA16_PIN_19 AT91C_PIO_PA16
#define FLASH_ALE_PA17_PIN_9 AT91C_PIO_PA17
#define FLASH_nWE_PA18_PIN_10 AT91C_PIO_PA18
#define FLASH_nRE_PA19_PIN_13 AT91C_PIO_PA19
#define FLASH_DATA0_PA24_PIN_23 AT91C_PIO_PA24
#define FLASH_DATA1_PA25_PIN_25 AT91C_PIO_PA25
#define FLASH_DATA2_PA26_PIN_26 AT91C_PIO_PA26
#define FLASH_DATA3_PA27_PIN_37 AT91C_PIO_PA27
#define FLASH_DATA4_PA28_PIN_38 AT91C_PIO_PA28
#define FLASH_DATA5_PA29_PIN_41 AT91C_PIO_PA29
#define FLASH_DATA6_PA30_PIN_42 AT91C_PIO_PA30
#define FLASH_DATA7_PA31_PIN_52 AT91C_PIO_PA31
#define FLASH_CONTROL_PINS (FLASH_nCE_PA20_PIN_16 | FLASH_CLE_PA16_PIN_19 | \
FLASH_ALE_PA17_PIN_9 | FLASH_nWE_PA18_PIN_10 | \
FLASH_nRE_PA19_PIN_13)
#define FLASH_DATA_PINS (FLASH_DATA0_PA24_PIN_23 | FLASH_DATA1_PA25_PIN_25 | \
FLASH_DATA2_PA26_PIN_26 | FLASH_DATA3_PA27_PIN_37 | \
FLASH_DATA4_PA28_PIN_38 | FLASH_DATA5_PA29_PIN_41 | \
FLASH_DATA6_PA30_PIN_42 | FLASH_DATA7_PA31_PIN_52)
/*********************************************************************
*
* Macros for setting timer
*
* Please define here how to setup your timer. (Hardware or software)
*
*
**********************************************************************
*/
/*********************************************************************
*
* Macros for setting the pin to configure card
*
* Please define here the sfr (special function register)
* of your processor.
*
*
**********************************************************************
*/
/* Port direction registers */
#define SET_DATA2INPUT() (AT91F_PIO_CfgInput(AT91C_BASE_PIOA, FLASH_DATA_PINS))
#define SET_DATA2OUTPUT() (AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, FLASH_DATA_PINS))
/*********************************************************************
*
* defines
*
**********************************************************************
*/
#define NAND_GET_DATA(Data) Data = (FS_U8)(AT91F_PIO_GetInput(AT91C_BASE_PIOA) >> 24)
#define NAND_SET_DATA(Data) (AT91F_PIO_ForceOutput(AT91C_BASE_PIOA, (((FS_U32)Data) << 24)))
#define NAND_SET_ALE() AT91F_PIO_SetOutput(AT91C_BASE_PIOA, (FLASH_ALE_PA17_PIN_9))
#define NAND_CLR_ALE() AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, (FLASH_ALE_PA17_PIN_9))
#define NAND_SET_CE() AT91F_PIO_SetOutput(AT91C_BASE_PIOA, (FLASH_nCE_PA20_PIN_16))
#define NAND_CLR_CE() AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, (FLASH_nCE_PA20_PIN_16))
#define NAND_SET_CLE() AT91F_PIO_SetOutput(AT91C_BASE_PIOA, (FLASH_CLE_PA16_PIN_19))
#define NAND_CLR_CLE() AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, (FLASH_CLE_PA16_PIN_19))
#define NAND_SET_RE() AT91F_PIO_SetOutput(AT91C_BASE_PIOA, (FLASH_nRE_PA19_PIN_13))
#define NAND_CLR_RE() AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, (FLASH_nRE_PA19_PIN_13))
#define NAND_SET_WE() AT91F_PIO_SetOutput(AT91C_BASE_PIOA, (FLASH_nWE_PA18_PIN_10))
#define NAND_CLR_WE() AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, (FLASH_nWE_PA18_PIN_10))
#define NAND_GET_READY()
/*********************************************************************
*
* _NANDFlashInit
*/
static void _NANDFlashInit(void) {
AT91PS_PIO pPio = AT91C_BASE_PIOA;
/* Next, enable the clock of the PIO, needed by everyone */
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;
/* first just get the control signal lines set properly, initially all output highs */
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, (FLASH_CONTROL_PINS)); /* set high */
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, (FLASH_CONTROL_PINS)); /* make outputs, give PIO control */
pPio->PIO_PPUDR = FLASH_CONTROL_PINS; /* disable the pullup resistors */
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, (FLASH_CLE_PA16_PIN_19 | FLASH_ALE_PA17_PIN_9)); /* set low */
/* now setup the data pins as initially all inputs */
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, (FLASH_DATA_PINS)); /* make inputs */
pPio->PIO_PPUER = FLASH_DATA_PINS; /* enable the pullup resistors */
/* lastly, setup so we can write to the data pins simultaneously */
AT91F_PIO_CfgDirectDrive(AT91C_BASE_PIOA, FLASH_DATA_PINS); /* write data to flash via PIO_ODSR */
}
/*********************************************************************
*
* _Timer2Config
*/
static void _Timer2Config(void) {
AT91PS_TC pTc = AT91C_BASE_TC2;
/* step 2) disable the clock to TC.TC2 until we have it all initialized */
pTc->TC_CCR = AT91C_TC_CLKDIS;
/* step 3) enable the clock to TC.TC2 */
AT91F_TC2_CfgPMC ();
/* step 4) set up timer/counter, PA0=TIOA, PA1=TIOB, = channel 0, waveform mode, */
/* only have RC affect TIOA and TIOB, and for idle state have it set these outputs on a compare */
pTc->TC_CMR = (AT91C_TC_BSWTRG_NONE | AT91C_TC_BEEVT_NONE | AT91C_TC_BCPC_NONE |
AT91C_TC_BCPB_NONE | AT91C_TC_ASWTRG_NONE | AT91C_TC_AEEVT_NONE |
AT91C_TC_ACPC_NONE | AT91C_TC_ACPA_NONE | AT91C_TC_WAVE |
AT91C_TC_WAVESEL_UP | AT91C_TC_NO_ENETRG | AT91C_TC_EEVT_XC0 |
AT91C_TC_EEVTEDG_NONE | AT91C_TC_NO_CPCDIS | AT91C_TC_NO_CPCSTOP |
AT91C_TC_BURST_NONE | AT91C_TC_NO_CLKI | AT91C_TC_CLKS_TIMER_DIV4_CLOCK);
pTc->TC_CCR = AT91C_TC_CLKEN; /* start TC.TC2 running */
pTc->TC_CCR = AT91C_TC_SWTRG; /* start TC.TC2 running */
}
/*********************************************************************
*
* FS_NAND_HW_X_SetData
*/
OPTIMIZE void FS_NAND_HW_X_SetData(FS_U8 Unit) {
FS_USE_PARA(Unit);
/* nCE low, CLE low, ALE low */
NAND_CLR_CE();
NAND_CLR_CLE();
NAND_CLR_ALE();
}
/*********************************************************************
*
* FS_NAND_HW_X_SetCmd
*/
OPTIMIZE void FS_NAND_HW_X_SetCmd(FS_U8 Unit) {
FS_USE_PARA(Unit);
/* nCE low, CLE high, ALE low */
NAND_CLR_CE();
NAND_SET_CLE();
NAND_CLR_ALE();
}
/*********************************************************************
*
* FS_NAND_HW_X_SetAddr
*/
OPTIMIZE void FS_NAND_HW_X_SetAddr(FS_U8 Unit) {
FS_USE_PARA(Unit);
/* nCE low, CLE low, ALE high */
NAND_CLR_CE();
NAND_CLR_CLE();
NAND_SET_ALE();
}
/*********************************************************************
*
* FS_NAND_HW_X_SetStandby
*/
OPTIMIZE void FS_NAND_HW_X_SetStandby(FS_U8 Unit) {
/* nCE high, CLE low, ALE low */
NAND_SET_CE();
NAND_CLR_CLE();
NAND_CLR_ALE();
}
/*********************************************************************
*
* FS_NAND_HW_X_Read
*/
OPTIMIZE void FS_NAND_HW_X_Read(FS_U8 Unit, FS_U8 * pBuffer, unsigned NumBytes) {
SET_DATA2INPUT();
do {
NAND_CLR_RE(); /* RE is active low */
NAND_GET_DATA(*pBuffer);
pBuffer++;
NAND_SET_RE(); /* disable RE */
} while (--NumBytes);
}
/*********************************************************************
*
* FS_NAND_HW_X_Write
*/
OPTIMIZE void FS_NAND_HW_X_Write(FS_U8 Unit, const FS_U8 * pData, unsigned NumBytes) {
SET_DATA2OUTPUT();
do {
NAND_CLR_WE(); /* WE is active low */
NAND_SET_DATA(*pData);
pData++;
NAND_SET_WE(); /* disable WE */
} while (--NumBytes);
}
/*********************************************************************
*
* FS_NAND_HW_X_IsWriteProtected
*/
int FS_NAND_HW_X_IsWriteProtected(FS_U8 Unit) {
FS_USE_PARA(Unit);
return 0;
}
/*********************************************************************
*
* FS_NAND_HW_X_IsBusy
*/
OPTIMIZE int FS_NAND_HW_X_IsBusy(FS_U8 Unit) {
/* If hardware does not support checking RDY/BSY,
* we check status by asking the card.
*/
#if FS_NAND2K_SUPPORT_BUSYLINE_CHECK == 0
{
FS_U8 Cmd;
FS_U8 Busy;
Cmd = NAND_CMD_READ_STATUS;
FS_NAND_HW_X_SetCmd(Unit);
FS_NAND_HW_X_Write(Unit, &Cmd, 1);
FS_NAND_HW_X_SetData(Unit);
FS_NAND_HW_X_Read(Unit, &Busy, 1);
FS_NAND_HW_X_SetStandby(Unit);
if (Busy & 0x40) {
return 0;
}
return 1;
}
#else
/* Ready = high -> return 0
* Busy = low -> return 1
*/
;
return NAND_GET_RDY() ? 0 : 1;
#endif
}
/*********************************************************************
*
* FS_NAND_HW_X_BusyLedOn
*/
void FS_NAND_HW_X_BusyLedOn(FS_U8 Unit) {
}
/*********************************************************************
*
* FS_NAND_HW_X_BusyLedOff
*/
void FS_NAND_HW_X_BusyLedOff(FS_U8 Unit) {
}
/*********************************************************************
*
* FS_NAND_HW_X_Init
*/
void FS_NAND_HW_X_Init(FS_U8 Unit) {
_Timer2Config();
_NANDFlashInit();
}
/*********************************************************************
*
* FS_NAND_HW_X_WaitTimer
*/
OPTIMIZE void FS_NAND_HW_X_Delayus(unsigned Period) {
AT91PS_TC pTc;
unsigned Status;
FS_U16 CurrentTime;
FS_U16 SetTime;
pTc = AT91C_BASE_TC2;
Status = pTc->TC_SR;
CurrentTime = (unsigned short)((pTc->TC_CV) & 0x0000FFFF);
SetTime = (CurrentTime + (Period * 3));
pTc->TC_RC = (unsigned int)SetTime;
do {
Status = pTc->TC_SR;
} while ((Status & AT91C_TC_CPCS) == 0);
}
#else
void NAND_2K_HW_c(void);
void NAND_2K_HW_c(void) {}
#endif
/**************************** end of file ***************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -