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

📄 mcard.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
字号:
/*
*******************************************************************************
*                               Magic Pixel
*                  5F, No.3, Creation Road III, Science_Based 
*                   Industrial Park, Hsinchu, Taiwan, R.O.C
*               (c) Copyright 2004, Magic Pixel Inc, Hsinchu, Taiwan
*
* All rights reserved. Magic Pixel's source code is an unpublished work and the 
* use of a copyright notice does not imply otherwise. This source code contains
* confidential, trad secret material. Any attempt or participation in 
* deciphering, decoding, reverse engineering or in ay way altering the source 
* code is strictly prohibited, unless the prior written consent of Magic 
* Pixel is obtained.
*
* Filename      : mcard.c
* Programmer(s) : 
* Created       : 
* Descriptions  :
*******************************************************************************
*/

/*
// define this module show debug message or not,  0 : disable, 1 : enable
*/
#define LOCAL_DEBUG_ENABLE 0

/*
// Include section 
*/
#include "global612.h"
#include "mpTrace.h"

#include "devio.h"
//#include "uti.h"
#include "mcard.h"
#include "os.h"
#include "taskid.h"
#include "ata.h"
#include "ms.h"
#include "sd.h"
#include "sm.h"
//#include "usbh.h"
#include "ata.h"

/*
// Variable declarations
*/
ST_MCARD_DEVS McardDev;
ST_MCARD_DEVS *psMcardDev;

/*
// Constant declarations
*/

/*
// Static function prototype
*/
static void DeviceEnable(BYTE bMcardID);
static void DeviceTask(void);

/*
// Definition of external functions
*/
///
///@ingroup DEVICE
///
///@brief   Initial device's driver and create memory card task.
///
///@remark  The Mcard_Init function installs designate device's driver,
///                 and then create memory task to current system.
///                  
///
void Mcard_Init(void)
{
	WORD i;

	psMcardDev = (ST_MCARD_DEVS *) ((DWORD) & McardDev | 0xa0000000);

	//create mcard message
	MailboxCreate(MCARD_MAIL_ID, OS_ATTR_PRIORITY);

	//not install any Device
	psMcardDev->dwDevInsCnt = 0x00;

	//offset value to skip usb host id  
	psMcardDev->bIdOffsetValue = 1;	//(MAX_USB_HOST_NUM + 1);

	// init all Mcard device to not install, not init
	for (i = 0; i < (MAX_MCARD_NUM + MAX_USB_HOST_NUM); i++)
	{
		psMcardDev->sMDevice[i].wMcardType = 0;
		psMcardDev->sMDevice[i].pbIcon = 0x00;
		psMcardDev->sMDevice[i].sMcardRMail = 0;
		psMcardDev->sMDevice[i].dwCapacity = 0x0;
		psMcardDev->sMDevice[i].wSectorSize = 0x00;
		psMcardDev->sMDevice[i].wProperty0 = 0x00;
		psMcardDev->sMDevice[i].wProperty1 = 0x00;
		psMcardDev->sMDevice[i].wProperty2 = 0x00;
		psMcardDev->sMDevice[i].wRenewCounter = 0x00;
		psMcardDev->sMDevice[i].swStatus = 0x00;
		psMcardDev->sMDevice[i].dwAccumulation = 0x00;
		psMcardDev->sMDevice[i].Flag.Present = 0;
		psMcardDev->sMDevice[i].Flag.Detected = 0;
		psMcardDev->sMDevice[i].Flag.Installed = 0;
		psMcardDev->sMDevice[i].Flag.ReadOnly = 0;
		psMcardDev->sMDevice[i].Flag.PipeEnable = 0;
		psMcardDev->sMDevice[i].Flag.Accumulatable = 0;
	}

	for (i = 0; i < (MAX_LUN + 1); i++)
	{
		psMcardDev->dwDevLunCurSetting[i] = NULL_DEVICE;
	}


#if NAND_ENABLE
	DeviceEnable(NAND);
#endif
#if SM_ENABLE
	DeviceEnable(SM);
#endif
#if XD_ENABLE
	DeviceEnable(XD);
#endif
#if MS_ENABLE
	DeviceEnable(MS);
#endif
#if SD_MMC_ENABLE
	DeviceEnable(SD_MMC);
#endif
#if CF_ENABLE
	DeviceEnable(CF);
#endif
#if HD_ENABLE
	DeviceEnable(HD);
#endif



	// create and start McardeTask 
	TaskCreate(MCARD_TASK, DeviceTask, DRIVER_PRIORITY, 4096);	//2048);
	TaskStartup(MCARD_TASK);
}

int Mcard_Format(BYTE bDevID)
{
	ST_MCARD_MAIL sMcardRMail;
	BYTE bMcardMailId;

	if (bDevID == NULL_DEVICE)
	{
		return MCARD_CMD_FAIL;
	}
	sMcardRMail.wMCardId = bDevID;
	sMcardRMail.wCmd = FORMAT_CMD;
	sMcardRMail.dwBlockAddr = 0;
	sMcardRMail.dwBlockCount = 0;
	sMcardRMail.dwBuffer = 0;
	MailboxSend(MCARD_MAIL_ID, (BYTE *) (&sMcardRMail.dwBlockAddr), sizeof(ST_MCARD_MAIL),
				&bMcardMailId);
	MailTrack(bMcardMailId);
	return Mcard_GetStatus(bDevID);
}

///
///@ingroup DEVICE
///@brief   Get the description of the memory card
///
///@param   bMcardID    ID number of the memory card
///
///@retval  BYTE*   the pointer of the description
/// 
///@remark  The Mcard_GetDescriptor function returns the pointer of the description, 
///                 which is according to the bMcardID. 
///
BYTE *Mcard_GetDescriptor(BYTE bMcardID)
{
	BYTE bMcardTransferID;

	bMcardTransferID = bMcardID - psMcardDev->bIdOffsetValue;
	return psMcardDev->sMDevice[bMcardTransferID].pbDescriptor;
}

///
///@ingroup DEVICE
///@brief   Get the current status of the memory card
///
///@param   bMcardID    ID number of the memory card
///
///@retval  SWORD   if no error occurs, it returns PASS. Otherwise it returns non-zero value.
/// 
///@remark  The Mcard_GetStatus function returns current status after executing any commands.
///
SWORD Mcard_GetStatus(BYTE bMcardID)
{
	BYTE bMcardTransferID;

	bMcardTransferID = bMcardID - psMcardDev->bIdOffsetValue;
	if((bMcardID==MS) &&(psMcardDev->sMDevice[bMcardTransferID].swStatus))
	{
		MP_DEBUG3("***Memory unknow change****Mcard_GetStatus bMcardID = %d , bMcardTransferID=%d,Status=%d",bMcardID,bMcardTransferID,psMcardDev->sMDevice[bMcardTransferID].swStatus);
		return 0;
	}
	return psMcardDev->sMDevice[bMcardTransferID].swStatus;
}

///
///@ingroup DEVICE
///@brief   Initiate the designate memory card 
///
///@param   bMcardID    ID number of the memory card
///
///@retval  MCARD_CMD_PASS  Initial command already sent.
/// 
///@remark  The Mcard_DeviceInit function sends INIT_CARD_CMD command to the designate memory card.
///                 But It doesn't check initial command completion or not.
///
SWORD Mcard_DeviceInit(BYTE bMcardID)
{
	ST_MCARD_MAIL sMcardRMail;
	BYTE bMcardMailId;

	sMcardRMail.wMCardId = bMcardID;
	sMcardRMail.wCmd = INIT_CARD_CMD;
	MailboxSend(MCARD_MAIL_ID, (BYTE *) (&sMcardRMail.dwBlockAddr), sizeof(ST_MCARD_MAIL),
				&bMcardMailId);
	MailTrack(bMcardMailId);
	return MCARD_CMD_PASS;
}

//Athena 03.11.2006 seperate card in & out
SWORD Mcard_DeviceRemove(BYTE bMcardID)
{
	ST_MCARD_MAIL sMcardRMail;
	BYTE bMcardMailId;

	sMcardRMail.wMCardId = bMcardID;
	sMcardRMail.wCmd = REMOVE_CARD_CMD;
	MailboxSend(MCARD_MAIL_ID, (BYTE *) (&sMcardRMail.dwBlockAddr), sizeof(ST_MCARD_MAIL),
				&bMcardMailId);
	MailTrack(bMcardMailId);
	return MCARD_CMD_PASS;
}

///
///@ingroup DEVICE
///
///@brief   Get the count of the installed device's driver. 
///
///@remark  The Mcard_GetDeviceNum function returns the count of the installed device's driver.
///                  
///
BYTE Mcard_GetDeviceNum(void)
{
	return psMcardDev->dwDevInsCnt;
}

///
///@ingroup DEVICE
///@brief   Get the capcity of the memory card 
///
///@param   bMcardID    ID number of the memory card
///
///@retval  DWORD   The total sectors
/// 
///@remark  The Mcard_GetCapacity function returns the total sectors
/// 
DWORD Mcard_GetCapacity(BYTE bMcardID)
{
	BYTE bMcardTransferID;

	bMcardTransferID = bMcardID - psMcardDev->bIdOffsetValue;
	return psMcardDev->sMDevice[bMcardTransferID].dwCapacity;
}

///
///@ingroup DEVICE
///@brief   Get max lun 
///
///@retval  DWORD   max lun
/// 
///@remark  The Mcard_GetMaxLun function returns the total lun
/// 
extern BYTE g_bRealMaxLun;
BYTE Mcard_GetMaxLun(void)
{
	return g_bRealMaxLun;		// abel modify for modulized
}

///
///@ingroup DEVICE
///@brief   Using lun number to get current card ID
///
///@retval  DWORD   lun number
/// 
///@remark  The Mcard_CurLunGetCardID function returns the card id
/// 
BYTE Mcard_CurLunGetCardID(BYTE bLunNum)
{
	return psMcardDev->dwDevLunCurSetting[bLunNum];
}

SWORD Mcard_Read(BYTE bDevID, DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr)
{
	ST_MCARD_MAIL sMcardRMail;
	BYTE bMcardMailId;

	if (bDevID == NULL_DEVICE)
	{
		return MCARD_CMD_FAIL;
	}
	sMcardRMail.wMCardId = bDevID;
	sMcardRMail.wCmd = READ_PAGE_CMD;
	sMcardRMail.dwBlockAddr = dwLogAddr;
	sMcardRMail.dwBlockCount = dwSectorCount;
	sMcardRMail.dwBuffer = dwBufferAddress;
	MailboxSend(MCARD_MAIL_ID, (BYTE *) (&sMcardRMail.dwBlockAddr), sizeof(ST_MCARD_MAIL),
				&bMcardMailId);
	MailTrack(bMcardMailId);
	return Mcard_GetStatus(bDevID);
}

SWORD Mcard_Write(BYTE bDevID, DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr)
{
	ST_MCARD_MAIL sMcardRMail;
	BYTE bMcardMailId;

	if (bDevID == NULL_DEVICE)
	{
		return MCARD_CMD_FAIL;
	}
	sMcardRMail.wMCardId = bDevID;
	sMcardRMail.wCmd = WRITE_PAGE_CMD;
	sMcardRMail.dwBlockAddr = dwLogAddr;
	sMcardRMail.dwBlockCount = dwSectorCount;
	sMcardRMail.dwBuffer = dwBufferAddress;
	MailboxSend(MCARD_MAIL_ID, (BYTE *) (&sMcardRMail.dwBlockAddr), sizeof(ST_MCARD_MAIL),
				&bMcardMailId);
	MailTrack(bMcardMailId);
	return Mcard_GetStatus(bDevID);
}

WORD Mcard_GetRenewCounter(BYTE bMcardID)
{
	BYTE bMcardTransferID;

	bMcardTransferID = bMcardID - psMcardDev->bIdOffsetValue;
	return psMcardDev->sMDevice[bMcardTransferID].wRenewCounter;
}

void Mcard_Isr(void)
{
	McardIsr();
}

void DmaMcardIsr(void)
{
	register CHANNEL *sChannel;

	sChannel = (CHANNEL *) (DMA_MC_BASE);
	sChannel->Control = 0;
	DmaIntDis(IM_MCRDDM);
	TaskWakeup(MCARD_TASK);
}

WORD Mcard_GetSectorSize(BYTE bMcardID)
{
	BYTE bMcardTransferID;

	bMcardTransferID = bMcardID - psMcardDev->bIdOffsetValue;
	return psMcardDev->sMDevice[bMcardTransferID].wSectorSize;
}


BYTE Mcard_GetFlagPresent(BYTE bMcardID)
{
	BYTE bMcardTransferID;
	
	DRIVE *sDrv;
	sDrv=DriveGet(bMcardID);
	//sDrv = DriveChange(bMcardID);
	bMcardTransferID = bMcardID - psMcardDev->bIdOffsetValue;
	return (psMcardDev->sMDevice[bMcardTransferID].Flag.Present | sDrv->Flag.Present);
	//return (psMcardDev->sMDevice[bMcardTransferID].Flag.Present );

}

BYTE Mcard_GetFlagReadOnly(BYTE bMcardID)
{
	BYTE bMcardTransferID;

	bMcardTransferID = bMcardID - McardDev.bIdOffsetValue;
	return psMcardDev->sMDevice[bMcardTransferID].Flag.ReadOnly;
}

BYTE Mcard_GetDetected(BYTE bMcardID)
{
	BYTE bMcardTransferID;

	bMcardTransferID = bMcardID - psMcardDev->bIdOffsetValue;
	return psMcardDev->sMDevice[bMcardTransferID].Flag.Detected;
}

/*
// Definition of internal functions
*/
void McardSetCurLun(BYTE bLunNum, BYTE bMcardID)
{
	psMcardDev->dwDevLunCurSetting[bLunNum] = bMcardID;
}

void DeviceEnableByMcardId(BYTE mcardId)
{
	DeviceEnable(mcardId);
}

DWORD Mcard_GetSdSpeed(void)
{
	return SdGetSpeed();
}

void McardInitforClk(BYTE bMcardID)
{
	switch (bMcardID)
	{
#if MS_ENABLE	
	case MS:
		MsInitForClk();
		break;
#endif
	case SD_MMC:
		SdInitForClk();
		break;

	default:
		return;
	}
}

/*
// Definition of local functions 
*/
static void DeviceTask(void)
{
	volatile ST_MCARD_MAIL *sMcardRMail;
	BYTE bMcardMailId, bMcardTransferID;

	while (1)
	{
		MailboxReceive(MCARD_MAIL_ID, &bMcardMailId);

		if (MailGetBufferStart(bMcardMailId, (DWORD) (&sMcardRMail)) == OS_STATUS_OK)
		{
			bMcardTransferID = sMcardRMail->wMCardId - psMcardDev->bIdOffsetValue;
			psMcardDev->sMDevice[bMcardTransferID].sMcardRMail = (ST_MCARD_MAIL *) sMcardRMail;
			psMcardDev->sMDevice[bMcardTransferID].CommandProcess(&psMcardDev->sMDevice[bMcardTransferID]);
		}
		MailRelease(bMcardMailId);
	}
}

static void DeviceEnable(BYTE bMcardID)
{
	BYTE bTransferID;

	bTransferID = bMcardID - psMcardDev->bIdOffsetValue;
	switch (bMcardID)
	{
#if SC_USBHOST
#if USB_HOST_ID1_ENABLE //byAlexWang 24jun2007 m2project
	case USB_HOST_ID1:
		UsbhStorageInit(&psMcardDev->sMDevice[bTransferID], USB_HOST_ID1);
		break;
#endif
#if USB_HOST_ID2_ENABLE
	case USB_HOST_ID2:
		UsbhStorageInit(&psMcardDev->sMDevice[bTransferID], USB_HOST_ID2);
		break;
#endif
#if USB_HOST_ID3_ENABLE
	case USB_HOST_ID3:
		UsbhStorageInit(&psMcardDev->sMDevice[bTransferID], USB_HOST_ID3);
		break;
#endif
#if USB_HOST_ID4_ENABLE
	case USB_HOST_ID4:
		UsbhStorageInit(&psMcardDev->sMDevice[bTransferID], USB_HOST_ID4);
		break;
#endif
#if USBHOST_PTP
case USB_HOST_PTP:
		UsbhStorageInit(&psMcardDev->sMDevice[bTransferID], USB_HOST_PTP);
		break;
#endif		
#endif // SC_USBHOST
#if NAND_ENABLE
	case NAND:
		SmInit(&psMcardDev->sMDevice[bTransferID], NAND);
		break;
#endif
#if SM_ENABLE
	case SM:
		SmInit(&psMcardDev->sMDevice[bTransferID], SM);
		break;
#endif
#if XD_ENABLE
	case XD:
		SmInit(&psMcardDev->sMDevice[bTransferID], XD);
		break;
#endif		
#if MS_ENABLE
	case MS:
		MsInit(&psMcardDev->sMDevice[bTransferID]);
		break;
#endif
	case SD_MMC:
		SdInit(&psMcardDev->sMDevice[bTransferID]);
		break;
#if CF_ENABLE
	case CF:
		CfInit(&psMcardDev->sMDevice[bTransferID]);
		break;
#endif
#if HD_ENABLE
	case HD:
		AtaInit(&psMcardDev->sMDevice[bTransferID]);
		break;
#endif
	default:
		return;
	}
	psMcardDev->dwDevInsCnt++;
	MP_DEBUG2("Enable Device %d (Total Count %d)", bMcardID, psMcardDev->dwDevInsCnt);
}

#if 0
/*
*******************************************************************************
*        LOCAL FUNCTION PROTOTYPES
*******************************************************************************
*/

void McardInit();


/*
*******************************************************************************
*        LOCAL FUNCTIONS
*******************************************************************************
*/



/*
*******************************************************************************
*        GLOBAL FUNCTIONS
*******************************************************************************
*/
int MDevRead(BYTE DevID, BYTE * buffer, DWORD lba, DWORD len)
{
	MCARD_MAIL McardSMailDrv;
	BYTE mail_id;

	McardSMailDrv.MCardId = DevID;
	McardSMailDrv.Cmd = WRITE_PAGE_CMD;
	McardSMailDrv.BlockAddr = lba;
	McardSMailDrv.BlockCount = len;
	McardSMailDrv.Buffer = (DWORD) buffer;
	MailboxSend(MCARD_MAIL_ID, (BYTE *) (&McardSMailDrv.BlockAddr), sizeof(MCARD_MAIL), &mail_id);
	MailTrack(mail_id);

	return MCARD_CMD_PASS;
}

int MDevWrite(BYTE DevID, BYTE * buffer, DWORD lba, DWORD len)
{
	MCARD_MAIL McardSMailDrv;
	BYTE mail_id;

	McardSMailDrv.MCardId = DevID;
	McardSMailDrv.Cmd = WRITE_PAGE_CMD;
	McardSMailDrv.BlockAddr = lba;
	McardSMailDrv.BlockCount = len;
	McardSMailDrv.Buffer = (DWORD) buffer;
	MailboxSend(MCARD_MAIL_ID, (BYTE *) (&McardSMailDrv.BlockAddr), sizeof(MCARD_MAIL), &mail_id);
	MailTrack(mail_id);

	return MCARD_CMD_PASS;
}


MCARD_DEV *GetMDev(BYTE McardID)
{

	return &(McardDev.MDevice[McardID]);
}


#endif

⌨️ 快捷键说明

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