⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ata.c

📁 s3c6400 ADS下官方测试程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/**************************************************************************************
* 
*	Project Name : S3C6400 Validation
*
*	Copyright 2006 by Samsung Electronics, Inc.
*	All rights reserved.
*
*	Project Description :
*		This software is only for validating functions of the S3C6400.
*		Anybody can use this software without our permission.
*  
*--------------------------------------------------------------------------------------
* 
*	File Name : ata.c
*  
*	File Description : This file implements the driver functions for CF Controller and PIO/UDMA mode on it.
*
*	Author : Sunil,Roe
*	Dept. : AP Development Team
*	Created Date : 2007/1/26
*	Version : 0.1 
* 
*	History
*	- Created(Sunil,Roe 2007/1/26)
*   
**************************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "def.h"
#include "option.h"
#include "library.h"
#include "sfr6400.h"
#include "system.h"
#include "timer.h"
#include "cf.h"
#include "ata.h"
#include "gpio.h"


#define ATA(__n) 				( ( volatile oATA_REGS * ) ( g_paATASFRBase[__n] ) )

#define SMDK6400 1
/*=========================================================================
 *          	               ata Command
 *=========================================================================
 */
#define ATA_CMD_IDENTIFYDEVICE	0xec
#define ATA_CMD_READSECTOR		0x20
#define ATA_CMD_READMULTIPLE		0xc4
#define ATA_CMD_READDMA			0xc8
#define ATA_CMD_WRITESECTOR		0x30
#define ATA_CMD_WRITEMULTIPLE		0xc5
#define ATA_CMD_WRITEDMA			0xca
#define ATA_CMD_SETFEATURES		0xEF

typedef struct tag_ATA_REGS
{
	u32	rrATA_CONTROL;		// ATA enable and clock down status
	u32	rrATA_STATUS;		// ATA status
	u32	rrATA_COMMAND;		// ATA command
	u32	rrATA_SWRST;		// ATA software reset
	u32	rrATA_IRQ;			// ATA interrupt sources
	u32	rrATA_IRQ_MASK;		// ATA interrupt mask
	u32	rrATA_CFG;			// ATA configuration for ATA interface
	u32	rReserved1;
	u32	rReserved2;
	u32	rReserved3;
	u32	rReserved4;
	u32	rrATA_PIO_TIME;		// ATA PIO timing
	u32	rrATA_UDMA_TIME;	// ATA UDMA timing
	u32	rrATA_XFR_NUM;		// ATA transfer number
	u32	rrATA_XFR_CNT;		// ATA current transfer count
	u32	rrATA_TBUF_START;	// ATA start address of track buffer
	u32	rrATA_TBUF_SIZE;	// ATA size of track buffer
	u32	rrATA_SBUF_START;	// ATA start address of source buffer
	u32	rrATA_SBUF_SIZE;	// ATA size of source buffer
	u32	rrATA_CADR_TBUF;	// ATA current write address of track buffer
	u32	rrATA_CADR_SBUF;	// ATA current read address of source buffer
	u32	rrATA_PIO_DTR;		// ATA PIO device data register
	u32	rrATA_PIO_FED;		// ATA PIO device Feature/Error register
	u32	rrATA_PIO_SCR;		// ATA PIO sector count register
	u32	rrATA_PIO_LLR;		// ATA PIO device LBA Low register
	u32	rrATA_PIO_LMR;		// ATA PIO device LBA middle register
	u32	rrATA_PIO_LHR;		// ATA PIO device LBA high register
	u32	rrATA_PIO_DVR;		// ATA PIO device register
	u32	rrATA_PIO_CSD;		// ATA PIO device command/status register
	u32	rrATA_PIO_DAD;		// ATA PIO device control/alternate status register
	u32	rrATA_PIO_READY;	// ATA PIO read data from device data register	
	u32	rrATA_PIO_RDATA;	// ATA PIO read data from device data register
	u32	rReserved5;
	u32	rReserved6;
	u32	rReserved7;
	u32	rReserved8;
	u32	rrBUS_FIFO_STATUS;	// ATA internal AHB FIFO status
	u32	rrATA_FIFO_STATUS;	// ATA internal ATA FIFO status
} 
oATA_REGS;

// define global variables
static void *				g_paATASFRBase[ATA_CONNUM];
extern volatile ATA_oInform	g_oaATAInform[];

/*---------------------------------- Init Functions  ---------------------------------*/
void ATA_SetSFRBaseAddr(u8 ucCon, u32 uBaseAddress);
void ATA_InitPort(u8, u8);
void ATA_InitBufferControl(void);
void ATA_SetTimingParams(u8 ucCon, eATA_MODE_6400 eMode, u32 uValue);
/*---------------------------------- Functions for Implement ATA Test functions ---------------------------------*/
void ATA_WaitForDeviceReady(u8 ucCon);
u8 ATA_GetDeviceReg(u8 ucCon, eCF_TASKFILE_Id eTaskFileRegId);
u16 ATA_GetDataFromDevice(u8 ucCon);
void ATA_SetDataToDevice(u8 ucCon, u16 usData);
bool ATA_WriteSectors_PIO(u8 ucCon, u32 uLBA, u32 uSectorCount, u32 uSrcAddress);
bool ATA_ReadSectors_PIO(u8 ucCon, u32 uLBA, u32 uSectorCount, u32 uDstAddress);
bool ATA_WriteSectors_PDMA(u8 ucCon, u32 uLBA, u32 uSectorCount, u32 uSrcAddress);
bool ATA_ReadSectors_PDMA(u8 ucCon, u32 uLBA, u32 uSectorCount, u32 uSrcAddress);
bool ATA_WriteSectors_UDMA(u8 ucCon, u32 uLBA, u32 uSectorCount, u32 uSrcAddress);
bool ATA_ReadSectors_UDMA(u8 ucCon, u32 uLBA, u32 uSectorCount, u32 uSrcAddress);
void ATA_SetDevicePosition(u8 ucCon, u32 uLba, u32 uSectorCount);
bool ATA_IsWritingSectorsDone(u8 ucCon);
bool ATA_IsReadingSectorsDone(u8 ucCon);
bool ATA_IsWritingBlocksDone(u8 ucCon);
bool ATA_IsReadingBlocksDone(u8 ucCon);
bool ATA_IsDmaDone(u8 ucCon);
/*---------------------------------- APIs of ATA_STATUS Registers ---------------------------------*/
void ATA_WaitForTransferDone(u8 ucCon);
void ATA_SetSwRst(u8 ucCon, u8 ucEnFlag);
void ATA_SetTransferCommand(u8 ucCon, eATA_XFR_CMD eXfrCmd);
void ATA_SetIRQ(u8 ucCon, eATA_IRQ_SRC eIrqSrc);
void ATA_SetIRQMask(u8 ucCon, eATA_IRQ_SRC eIrqSrc);
/*---------------------------------- APIs of ATA_CFG Registers ---------------------------------*/
void ATA_SetConfig(u8 ucCon, eATA_MODE_6400 eMode, eATA_DMA_DIR eDmaDir);
void ATA_SetUdmaAutoMode(u8 ucCon, u8 ucEnFlag);
void ATA_SetEndian(u8 ucCon, eATA_ENDIAN eEndianMode);
void ATA_SetDMAXferDir(u8 ucCon, eATA_DMA_DIR eDmaDir);
void ATA_SetXferMode(u8 ucCon, eATA_MODE_6400 eAtaMode);
void ATA_SetIORDY(u8 ucCon, u8 ucEnFlag);
void ATA_SetRst(u8 ucCon, u8 ucEnFlag);
void ATA_SetSBufStart(u8 ucCon, u32 uBufAddr);
void ATA_SetTBufStart(u8 ucCon, u32 uBufAddr);
void ATA_SetSBufSize(u8 ucCon, u32 uSize);
void ATA_SetTBufSize(u8 ucCon, u32 uSize);
void ATA_SetXfrNum(u8 ucCon, u32 uNum);
u8 ATA_GetTaskFileRegValue(u8 ucCon, eCF_TASKFILE_Id uATATaskFileRegId);
u16 ATA_GetTaskFileRegValue16(u8 ucCon, eCF_TASKFILE_Id uATATaskFileRegId);
void ATA_SetTaskFileRegValue(u8 ucCon, eCF_TASKFILE_Id uATATaskFileRegId, u32 uValue);
void ATA_SetTaskFileRegValue16(u8 ucCon, eCF_TASKFILE_Id uATATaskFileRegId, u16 uValue);
/*---------------------------------- APIs of ATA_FIFO_STATUS Registers ---------------------------------*/
void ATA_WaitForHostReady(u8 ucCon);
/*---------------------------------- APIs of general ATA ---------------------------------*/
u32 ATA_GetRegAddr(u8 ucCon, eATA_Id uATARegId);
u32 ATA_GetRegValue(u8 ucCon, eATA_Id uATARegId);
void ATA_SetRegValue(u8 ucCon, eATA_Id uATARegId, u32 uValue);

/*---------------------------------- Init Functions  ---------------------------------*/
//////////
// Function Name : ATA_Init
// Function Description : This function initializes a certain ATA Controller.
// Input : 	ucCon - ATA Controller Number 
// Output : 	TRUE 	- Memory Device is reset
//			FALSE	- Memory Device is not reset because of ERROR
// Version : v0.1
bool	ATA_Init(u8 ucCon, u8 ucOpMode)
{
	u32 uSFRBaseAddress;			// for PCCARD Controller Base Register

	Assert( (ucCon == ATA_CON0) );

	if (ucCon == ATA_CON0)
	{
		uSFRBaseAddress			= ATA_BASE;
	}
	else
	{	
		return FALSE;
	}

	// EBI Setup for CF controller
	CF_SetEBI(ucOpMode);
	ATA_SetSFRBaseAddr(ucCon, uSFRBaseAddress);
	ATA_InitBuffer(ucCon);
	ATA_InitPort(ucCon,ucOpMode);

	return TRUE;
}

//////////
// Function Name : ATA_SetSFRBaseAddr
// Function Description : This function sets up the base address of ATA Registers.
// Input : 	ucCon		- ATA controller number
//			uBaseAddress	- the baseaddress of ATA registers
// Output : 	NONE
// Version : v0.1
void ATA_SetSFRBaseAddr(u8 ucCon, u32 uBaseAddress)
{
	g_paATASFRBase[ucCon] = (void *)uBaseAddress;
}

//////////
// Function Name : ATA_InitBuffer
// Function Description : This function sets up the buffer address of ATA Registers.
// Input : 	ucCon		- ATA controller number
// Output : 	NONE
// Version : v0.1
void ATA_InitBuffer(u8 ucCon)
{
	g_oaATAInform[ucCon].puATAWriteBuf = (u32*) CF_WRITE_BUF;
	g_oaATAInform[ucCon].puATAReadBuf = (u32*) (CF_WRITE_BUF + 0x400000); 
}

//////////
// Function Name : ATA_InitPort
// Function Description : 
//   This function Initialize ports as ATA.
// Input : ucCon - ATA Controller Number 
// Output : NONE
// Version : v0.1 
void ATA_InitPort(u8 ucCon, u8 ucOpMode)
{
	switch(ucCon)
	{
		case ATA_CON0 :
		 	if (ucOpMode == DIRECT_MODE)	
		 	{ 
#if 1	// default.. OK 	A1,D1,C1
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// D: Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_L, 0x00000666, 0x0);			// A: Set XhiADDR[2:0] pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_M, 0x00066666, 0x0);			// C: Set Xhi control pins as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// OK 	A1,D1,C2
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// D: Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_L, 0x00000666, 0x00055555);	// A1: Set XhiADDR[2:0] pins as CF ADDR[2:0], C2 : Set XhiADDR[12:8] as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// A1,D1,D2,C2
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x00000055);	// D1: Set XhiDATA[9:0] pins as CF Data[9:0] 
				GPIO_SetFunctionAll(eGPIO_M, 0x00555555, 0x00000000);	// D2: Set Xhi control pins as CF Data[15:10] 
				GPIO_SetFunctionAll(eGPIO_L, 0x00000666, 0x00055555);	// A1: Set XhiADDR[2:0] pins as CF ADDR[2:0], C2 : Set XhiADDR[12:8] as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// A1,D1,D2,D3,C2
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x00000000);	// D1: Set XhiDATA[7:0] pins as CF Data[7:0] 
				GPIO_SetFunctionAll(eGPIO_M, 0x00555555, 0x00000000);	// D2: Set Xhi control pins as CF Data[15:10] 
				GPIO_SetFunctionAll(eGPIO_L, 0x00000666, 0x05555555);	// A1: Set XhiADDR[2:0] pins as CF ADDR[2:0], C2 : Set XhiADDR[12:8] as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0]), D3 : Set XhiData[17:16] as CF Data[9:8] 
#endif
#if 0	// OK		A4,D1,C2
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_B, 0x00000555, 0x00000000);	// Set XuRXD2, XuTXD2, XuRXD3 pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_L, 0x00000000, 0x00055555);	// Set XhiADDR[12:8] as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// only for type2 CPU board	A10,D1,C2
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_H, 0x66000000, 0x00000006);	// Set MMC1DATA[6:4] pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_L, 0x00000000, 0x00055555);	// Set XhiADDR[12:8] as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// for GPIO test :A1, A2, D1,D2,D3,C2
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x00000000);	// D: Set XhiDATA[7:0] pins as CF Data[7:0] 
				GPIO_SetFunctionAll(eGPIO_M, 0x00066666, 0x00000000);	// D2: Set Xhi control pins as CF Data[15:10] 				
				GPIO_SetFunctionAll(eGPIO_A, 0x00005500, 0x00000000);	// A2: Set XuCTSn0, XuRTSn0 pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_L, 0x00060000, 0x02255555);	// A1: Set XhiADDR2 pin as CF ADDR2, D3: Set XhiDATA[17:16] pins as CF Data[9:8] , C: Set Xhi control pins as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])				
#endif
#if 0	// for GPIO test :A1, A3,D1,C1
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// D: Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_L, 0x00000600, 0x00000000);	// A1: Set XhiADDR2 pins as CF ADDR2
				GPIO_SetFunctionAll(eGPIO_A, 0x55000000, 0x00000000);	// A3: Set XuCTSn1, XuRTSn1 pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_M, 0x00066666, 0x00000000);	// C: Set Xhi control pins as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// for GPIO test :A5,D1,C1
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// D: Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_C, 0x00000555, 0x00000000);	// A5: Set XspiMISO0, XspiCLK0, XspiMOSI0 pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_M, 0x00066666, 0x00000000);	// C: Set Xhi control pins as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// for GPIO test :A6,D1,C1
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// D: Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_D, 0x00000ddd, 0x00000000);	// A6: Set XpcmDCLK0, XpcmEXTCLK0, XpcmFSYNC0 pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_M, 0x00066666, 0x00000000);	// C: Set Xhi control pins as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// for GPIO test :A7,D1,C1
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// D: Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_N, 0x003f0000, 0x00000000);	// A7: Set XEINT[10:8] pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_M, 0x00066666, 0x00000000);	// C: Set Xhi control pins as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// for GPIO test : A8,D1,C1
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// D: Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_G, 0x00000555, 0x00000000);	// A8: Set XmmcCLK0, XmmcCMD0, XmmcDAT0 pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_M, 0x00066666, 0x00000000);	// C: Set Xhi control pins as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
#if 0	// for GPIO test :A9,D1,C1
				GPIO_SetFunctionAll(eGPIO_K, 0x55555555, 0x55555555);	// D: Set XhiDATA[15:0] pins as CF Data[15:0] 
				GPIO_SetFunctionAll(eGPIO_H, 0x00000555, 0x00000000);	// A9: Set XmmcCLK1, XmmcCMD1, XmmcDAT1 pins as CF ADDR[2:0]
				GPIO_SetFunctionAll(eGPIO_M, 0x00066666, 0x00000000);	// C: Set Xhi control pins as CF control pins(IORDY, IOWR, IORD, CE[1], CE[0])
#endif
				OpenConsole();		// This line must be here because Uart ports(GPIO_A) are changed after setting GPIO_K.
		 	}
			
			//--- CF controller - PC card mode setting ---//
			// Output pad disable, Card power off, PC card mode
			CF_SetMUXReg(eCF_MUX_OUTPUT_DISABLE, eCF_MUX_CARDPWR_OFF, eCF_MUX_MODE_IDE);
//			DelayfrTimer( milli, 100);	// wait for 100ms, be positively necessary
			// Output pad enable, Card power off, PC card mode
			CF_SetMUXReg(eCF_MUX_OUTPUT_ENABLE, eCF_MUX_CARDPWR_OFF, eCF_MUX_MODE_IDE);
//			DelayfrTimer( milli, 100);	// wait for 100ms, be positively necessary
			// Card Power on (PC Card mode)
			CF_SetMUXReg(eCF_MUX_OUTPUT_ENABLE, eCF_MUX_CARDPWR_ON, eCF_MUX_MODE_IDE);
			DelayfrTimer( milli, 100);	// wait for 100ms, be positively necessary
			
			// Card configuration
			ATA_SetTimingParams(ucCon, eATA_MODE_PIO, 0x1C238);
			ATA_SetTimingParams(ucCon, eATA_MODE_UDMA, 0x20B1362);
			ATA_SetEndian(ucCon, eATA_ENDIAN_LITTLE);	
			ATA_SetEnable(ucCon, ENABLE);
			DelayfrTimer( milli, 100);	// wait for 200ms, be positively necessary

#if 0	// for pull-down-dedicated nCD pins
			GPIO_SetFunctionEach(eGPIO_P, eGPIO_14, 1);	// set CData/EINT as output
			GPIO_SetDataEach(eGPIO_P, eGPIO_14 , 1); 		//GPN[8] -> High
			DelayfrTimer(milli,500);						//Delay about 10ms

			GPIO_SetFunctionEach(eGPIO_P, eGPIO_14, 2);	// set CData/EINT as CData
			GPIO_SetDataEach(eGPIO_P, eGPIO_14 , 1); 		//GPN[8] -> High
			DelayfrTimer(milli,500);						//Delay about 10ms
#endif
#if 1	// for CF card boot up signal
			GPIO_SetFunctionEach(eGPIO_N, eGPIO_8, 1);	// set XEINT8/ADDR_CF0/GPN8 as output
			GPIO_SetDataEach(eGPIO_N, eGPIO_8 , 1); 		//GPN[8] -> High
			DelayfrTimer(milli,100);						//Delay about 10ms
			GPIO_SetDataEach(eGPIO_N, eGPIO_8 , 0); 		//GPN[8] -> Low	
#endif			
			break;
		default :
			break;
	}

}

void ATA_InitBufferControl(void) // added by junon for second UDMA test b'd 060902
{
#if 0
#ifdef __EVT1
	rGPACDH = 0x1aa8a; // GPA10 RDATA_OEN setting
#else
	rGPBCON = rGPBCON & ~((3<<8)|(3)) | (1<<8)|(1); // GPB0,4 output setting (TOUT0, TCLK - TP21,20)
	rGPBCON = rGPBCON & ~((3<<12)|(3<<10)) | (1<<12)|(1<<10); // GPB5,6 output setting (nXBACK, nXBREQ)
	rGPBDAT = rGPBDAT & ~((7<<4)|(1)) | (1<<6); // GPB6->high, GPB0,4,5->low
#endif	
	Disp("IBC - rGPBCON = 0x%x \n",rGPBCON);
#endif
}

//extern u8 g_ucATAConNum;
void 	ATA_ChangeBufferControl(eATA_MODE_6400 mode) // only for SMDK b'd 060902 using additianal logic
{
#if 0
	Disp("MODE5:%d, mode:%d\n", g_oaATAInform[g_ucATAConNum].eAtaMode, mode);
	if (mode == eATA_MODE_UDMA)
		rGPBDAT = rGPBDAT | (1<<4)|(1); // GPB0->high,GPB4->high => UDMA mode 
	else // PIO
		rGPBDAT = rGPBDAT & ~(1<<4) | (1); // GPB0->high,GPB4->low => ATA PIO mode	  	
	Disp("BC - rGPBDAT = 0x%x \n",(u32)rGPBDAT);
#endif	
}

void ATA_SetTimingParams(u8 ucCon, eATA_MODE_6400 eMode, u32 uValue)
{
	switch(eMode)
	{
		case eATA_MODE_PIOCPU:
		case eATA_MODE_PIODMA:
			ATA_SetRegValue(ucCon, eATA_PIO_TIME, uValue);
			break;
		case eATA_MODE_UDMA :
			ATA_SetRegValue(ucCon, eATA_UDMA_TIME, uValue);
			break;			
	}
}
/*---------------------------------- Functions for Implement ATA Test functions ---------------------------------*/
//////////
// Function Name : ATA_TestResetAll
// Function Description : This function implements reset function of ATA device.
// Input : 	ucCon - ATA Controller Number
// Output : 	NONE
// Version : v0.1
void ATA_TestResetAll(u8 ucCon)
{
	// TDelay timer setting
	DelayfrTimer( milli, 2);	// wait for 2ms
	DelayfrTimer( micro, 25);	// wait for 25us

	ATA_SetSwRst( ucCon, RESET);	// CF controller reset
	DelayfrTimer( micro, 5);	// wait for 5us

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -