|
发表于 2010-10-2 10:26:23
|
显示全部楼层
下面提供一个CDC的主函数和处理函数 ,希望对大家有用
//*--------------------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*--------------------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*--------------------------------------------------------------------------------------
//* File Name : main.c
//* Object :
//* Translator :
//* 1.0 08/Sep/04 JPP : Creation
//*--------------------------------------------------------------------------------------
#include <string.h>
#include "board.h"
#include "cdc_enumerate.h"
#include "Packet.h"
//#define FW_VERSION_MAJOR 0
//#define FW_VERSION_MINOR 1
//#define FW_VERSION_BUILD 0x1
#define FW_REVISION 0x0006 //((FW_VERSION_MAJOR << 24) | (FW_VERSION_MINOR << 16) | FW_VERSION_BUILD)
#define SIZEBUFMAX 64
#define CHAINDATAMAX 8192
#define TDIOFFSET 8
/*
#define PIO_INTERRUPT_LEVEL 6
#define IRQ0_INTERRUPT_LEVEL 2
#define SOFT_INTERRUPT_LEVEL 5
#define FIQ_INTERRUPT_LEVEL 0
*/
/*
#define PIO_TRST AT91C_PIO_PA28
#define PIO_TCK AT91C_PIO_PA29
#define PIO_TMS AT91C_PIO_PA30
#define PIO_TDI AT91C_PIO_PA31
#define PIO_TDO AT91C_PIO_PA27
*/
#define PIO_TRST AT91C_PIO_PA7
#define PIO_BLUE_LED AT91C_PIO_PA3
// Variable
struct _AT91S_CDC pCDC;
char g_aTms[] = {0x6A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00};
//char g_aTms[] = {0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00};
//char g_aTms[] = {0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00};
char g_aTmsIdle[1024];
char g_aTdiIdle[8];
char g_aTdoIdle[1024];
char g_aTapData[CHAINDATAMAX + TDIOFFSET];
volatile int g_nPause;
volatile int g_nTckDiv;
//*----------------------------------------------------------------------------
//* \fn AT91F_USB_Open
//* \brief This function Open the USB device
//*----------------------------------------------------------------------------
/*__ramfunc*/ void AT91F_USB_Open(void)
{
// Set the PLL USB Divider
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
// Specific Chip USB Initialisation
// Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock
AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
// Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
// Set in PIO mode and Configure in Output
/*
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA,AT91C_PIO_PA16);
// Set
AT91F_PIO_SetOutput(AT91C_BASE_PIOA,AT91C_PIO_PA16);
for (unsigned i=0; i<g_nPause; i++);
// Clear
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,AT91C_PIO_PA16);
*/
// CDC Open by structure initialization
AT91F_CDC_Open(&pCDC);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_L0USB_PUT_Data
//* \brief This function allows data tx by USART
//*----------------------------------------------------------------------------
/*__ramfunc*/ inline void AT91F_L0USB_PUT_Data(char* data,unsigned int length)
{
pCDC.Write(&pCDC, data, length);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_L0USB_GET_Data
//* \brief This function allows data tx by USART
//*----------------------------------------------------------------------------
/*__ramfunc*/ inline int AT91F_L0USB_GET_Data(char* data,unsigned int length, int wait_all=0)
{
return pCDC.Read(&pCDC, data, length, wait_all);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_L1USB_PUT_Data
//* \brief This function allows data tx by USART
//*----------------------------------------------------------------------------
/*__ramfunc*/ void AT91F_L1USB_PUT_Data(char* data,unsigned int length)
{
unsigned int size;
while(length)
{
size = (length<SIZEBUFMAX) ? length : SIZEBUFMAX;
AT91F_L0USB_PUT_Data(data, size);
length -= size;
data += size;
}
}
//*----------------------------------------------------------------------------
//* \fn AT91F_L1USB_GET_Data
//* \brief This function allows data tx by USART
//*----------------------------------------------------------------------------
/*__ramfunc*/ void AT91F_L1USB_GET_Data(char* data,unsigned int length)
{
unsigned int size;
while(length)
{
size = AT91F_L0USB_GET_Data(data, (length<SIZEBUFMAX) ? length : SIZEBUFMAX);
length -= size;
data += size;
}
}
/*
void AIC_Reset(void)
{
unsigned int i;
// AT91C_BASE_AIC->AIC_EOICR = 0x0;
// 悟觌噱?怦?桉蝾黜桕?镳屦囗栝
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
// 西棂噱?怦?镳屦囗?
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
// 悟觌噱?镥痂翦痂?铗 耔耱屐眍泐 觌铌?
AT91C_BASE_PMC->PMC_PCDR = 0xFFFFFFFF;
// 厌疣覃忄屐 綦嚆?蜞殪屦钼
i = AT91C_BASE_TC0->TC_SR;
i = AT91C_BASE_TC1->TC_SR;
i = AT91C_BASE_TC0->TC_SR;
for (i=0;i < 8;i++)
{
// 埋?镳屦囗? 玎觐眵屙?
AT91C_BASE_AIC->AIC_EOICR = 0xFFFFFFFF;
}
}
*/
/*__ramfunc*/ inline void SPI_Init()
{
AT91F_SPI_Disable(AT91C_BASE_SPI);
AT91F_SPI_Reset(AT91C_BASE_SPI);
AT91F_SPI_CfgMode(AT91C_BASE_SPI,
// AT91C_SPI_MSTR |
AT91C_SPI_PS_FIXED);
AT91F_SPI_CfgCs(AT91C_BASE_SPI, 0,
AT91C_SPI_CPOL |
(AT91C_SPI_BITS & AT91C_SPI_BITS_8) |
(AT91C_SPI_DLYBS & (2 << 16))
// (AT91C_SPI_SCBR & (CS_BAUD << 8))
);
AT91F_SPI_Enable(AT91C_BASE_SPI);
}
/*__ramfunc*/ inline void SSC_Init(unsigned nDiv)
{
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST | AT91C_SSC_RXDIS | AT91C_SSC_TXDIS;
// AT91C_BASE_SSC->SSC_RCMR = 0;
// AT91C_BASE_SSC->SSC_RFMR = 0;
AT91C_BASE_SSC->SSC_CMR = nDiv; // (MCK/512)
AT91C_BASE_SSC->SSC_RCMR = AT91C_SSC_CKS_RK |
// AT91C_SSC_CKS_TK |
AT91C_SSC_CKI |
// AT91C_SSC_START_CONTINOUS |
AT91C_SSC_START_FALL_RF
// AT91C_SSC_START_LOW_RF// |
// AT91C_SSC_START_TX// |
// (AT91C_SSC_STTDLY&(1<<16))
// AT91C_SSC_PERIOD&(31<<24)
;
AT91C_BASE_SSC->SSC_RFMR = AT91C_SSC_DATLEN&7 |
(AT91C_SSC_DATNB&(7<<8));
AT91C_BASE_SSC->SSC_TCMR = AT91C_SSC_CKS_DIV |
AT91C_SSC_CKO_CONTINOUS |
// AT91C_SSC_CKI |
// AT91C_SSC_START_LOW_RF |
AT91C_SSC_START_CONTINOUS// |
// (AT91C_SSC_STTDLY&(2<<16))
// AT91C_SSC_PERIOD&(4<<24)
;
AT91C_BASE_SSC->SSC_TFMR = AT91C_SSC_DATLEN&7 |
AT91C_SSC_MSBF |
AT91C_SSC_DATNB&(7<<8) |
AT91C_SSC_FSOS_LOW
;
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
}
/*__ramfunc*/ inline void ResetAll()
{
AT91F_PIO_CfgPeriph( AT91C_BASE_PIOA, // PIO controller base address
AT91C_PA11_NPCS0 | // CS
AT91C_PA12_MISO | // SPI Slave Out
AT91C_PA13_MOSI | // SPI Master Out
AT91C_PA14_SPCK | // SPI Slave Clock
AT91C_PA15_TF | // SSC Tx Frame Sync
AT91C_PA16_TK | // SSC Tx Clock
AT91C_PA17_TD | // SSC Tx Data
AT91C_PA20_RF | // SSC Rx Frame Sync
AT91C_PA19_RK | // SSC Rx Clock
AT91C_PA18_RD, 0); // SSC Rx Data
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, PIO_TRST);
// AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PIO_TRST); // Clear Output ?
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, PIO_TRST);
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, PIO_BLUE_LED);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PIO_BLUE_LED);
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST | AT91C_SSC_RXDIS | AT91C_SSC_TXDIS;
AT91F_SPI_Disable(AT91C_BASE_SPI);
AT91F_SPI_Reset(AT91C_BASE_SPI);
}
/*__ramfunc*/ inline void DMA_Init()
{
AT91F_PDC_Open(AT91C_BASE_PDC_SPI);
AT91F_PDC_Open(AT91C_BASE_PDC_SSC);
}
/*__ramfunc*/ inline void DMA_WaitUntilEmpty()
{
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
SSC_Init(g_nTckDiv);
// DMA_Init();
}
/*__ramfunc*/ void PacketHandler(CPacket *pPacket)
{
switch (pPacket->m_nId)
{
case PKT_ID_SETUP:
{
CSetupPacket *pIn = (CSetupPacket *) pPacket;
AT91F_SPI_CfgPMC();
SPI_Init();
AT91F_SSC_CfgPMC();
SSC_Init(pIn->m_nTckDiv);
g_nTckDiv = pIn->m_nTckDiv;
DMA_Init();
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PIO_TRST);
break;
}
case PKT_ID_CHAIN:
{
CChainPacket *pIn = (CChainPacket *) pPacket;
int i;
// memset(g_aTapData, 0xAA, 64); // Debug
DMA_WaitUntilEmpty();
if (pIn->m_bReset)
{
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, PIO_TRST);
// AT91F_PDC_SetTx(AT91C_BASE_PDC_SPI, g_aTdiIdle, pIn->m_nBDataSize); // NEW
AT91F_PDC_SetRx(AT91C_BASE_PDC_SSC, g_aTdoIdle, pIn->m_nBDataSize);
AT91F_PDC_SetTx(AT91C_BASE_PDC_SSC, g_aTmsIdle, pIn->m_nBDataSize);
DMA_WaitUntilEmpty();
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PIO_TRST);
// AT91F_PDC_SetTx(AT91C_BASE_PDC_SPI, g_aTdiIdle, pIn->m_nIdleCount); // NEW
AT91F_PDC_SetRx(AT91C_BASE_PDC_SSC, g_aTdoIdle, pIn->m_nIdleCount);
AT91F_PDC_SetTx(AT91C_BASE_PDC_SSC, g_aTmsIdle, pIn->m_nIdleCount);
DMA_WaitUntilEmpty();
break;
}
AT91F_L0USB_GET_Data(g_aTapData + TDIOFFSET, pIn->m_nBDataSize, 1);
SPI_Init();
AT91F_PDC_SetTx(AT91C_BASE_PDC_SPI, g_aTdiIdle, 3);
AT91F_PDC_SetNextTx(AT91C_BASE_PDC_SPI, g_aTapData+TDIOFFSET, 5);
AT91F_PDC_SetRx(AT91C_BASE_PDC_SSC, g_aTdoIdle, 1);
AT91F_PDC_SetNextRx(AT91C_BASE_PDC_SSC, g_aTapData, 7);
AT91F_PDC_SetTx(AT91C_BASE_PDC_SSC, g_aTms, 8);
// for (i=4; i>=0; i--)
// g_aTapData
unsigned nCount = (pIn->m_nBDataSize*52429) >> 18; // div 5
for (i=1; i<nCount; i++)
{
DMA_WaitUntilEmpty();
// AT91F_PDC_SetTx(AT91C_BASE_PDC_SPI, g_aTdiIdle, pIn->m_nIdleCount); // NEW
// <rev.6>
// g_nPause = 1024;
// while (g_nPause && (AT91F_PDC_ReceiveFrame(AT91C_BASE_PDC_SSC, g_aTdoIdle, pIn->m_nIdleCount, NULL, 0) != 2)) g_nPause--;
// while (g_nPause && (AT91F_PDC_SendFrame(AT91C_BASE_PDC_SSC, g_aTmsIdle, pIn->m_nIdleCount, NULL, 0) != 2)) g_nPause--;
// </rev.6>
AT91F_PDC_SetRx(AT91C_BASE_PDC_SSC, g_aTdoIdle, pIn->m_nIdleCount); // 6
AT91F_PDC_SetTx(AT91C_BASE_PDC_SSC, g_aTmsIdle, pIn->m_nIdleCount); // 6
DMA_WaitUntilEmpty();
SPI_Init();
// <rev.6>
// while (g_nPause && (AT91F_PDC_SendFrame(AT91C_BASE_PDC_SPI, g_aTdiIdle, 3, g_aTapData+TDIOFFSET+i*5, 5) != 2)) g_nPause--;
// while (g_nPause && (AT91F_PDC_ReceiveFrame(AT91C_BASE_PDC_SSC, g_aTdoIdle, 1, g_aTapData+i*5, 7) != 2)) g_nPause--;
// while (g_nPause && (AT91F_PDC_SendFrame(AT91C_BASE_PDC_SSC, g_aTms, 8, NULL, 0) != 2)) g_nPause--;
// </rev.6>
AT91F_PDC_SetTx(AT91C_BASE_PDC_SPI, g_aTdiIdle, 3); // 6
AT91F_PDC_SetNextTx(AT91C_BASE_PDC_SPI, g_aTapData+TDIOFFSET+i*5, 5); // 6
AT91F_PDC_SetRx(AT91C_BASE_PDC_SSC, g_aTdoIdle, 1); // 6
AT91F_PDC_SetNextRx(AT91C_BASE_PDC_SSC, g_aTapData+i*5, 7); // 6
AT91F_PDC_SetTx(AT91C_BASE_PDC_SSC, g_aTms, 8); // 6
}
DMA_WaitUntilEmpty();
// AT91F_PDC_SetTx(AT91C_BASE_PDC_SPI, g_aTdiIdle, pIn->m_nIdleCount); // NEW
AT91F_PDC_SetRx(AT91C_BASE_PDC_SSC, g_aTdoIdle, pIn->m_nIdleCount);
AT91F_PDC_SetTx(AT91C_BASE_PDC_SSC, g_aTmsIdle, pIn->m_nIdleCount);
break;
}
case PKT_ID_GET_DATA:
{
CGetDataPacket *pIn = (CGetDataPacket *) pPacket;
DMA_WaitUntilEmpty();
AT91F_L0USB_PUT_Data(g_aTapData+pIn->m_nOffset, pIn->m_nBDataSize);
break;
}
case PKT_ID_GET_STATUS:
{
CGetStatusPacket *pIn = (CGetStatusPacket *) pPacket;
pIn->m_nFwRevision = FW_REVISION;
pIn->m_nTms = AT91C_BASE_PDC_SSC->PDC_TCR;
pIn->m_nTdi = AT91C_BASE_PDC_SPI->PDC_TCR;
pIn->m_nTdo = AT91C_BASE_PDC_SSC->PDC_RCR;
AT91F_L0USB_PUT_Data((char*) pIn, pIn->m_nBPacketSize);
break;
}
case PKT_ID_RESET:
{
ResetAll();
break;
}
}
}
//*--------------------------------------------------------------------------------------
//* Function Name : main
//* Object :
//* Input Parameters :
//* Output Parameters :
//*--------------------------------------------------------------------------------------
/*__ramfunc*/ int main (void)
{
char aPacket[SIZEBUFMAX];
int nLen;
int i;
for (i=0; i<sizeof(g_aTmsIdle); i++)
g_aTmsIdle = 0;
for (i=0; i<sizeof(g_aTdiIdle); i++)
g_aTdiIdle = 0xFF;
// memset(g_aTmsIdle, 0, sizeof(g_aTmsIdle));
// memset(g_aTdiIdle, 0xFF, sizeof(g_aTdiIdle));
// Init USB device
AT91F_USB_Open();
ResetAll();
/*
AT91F_PIO_CfgPeriph( AT91C_BASE_PIOA, // PIO controller base address
AT91C_PA11_NPCS0 | // CS
AT91C_PA12_MISO | // SPI Slave Out
AT91C_PA13_MOSI | // SPI Master Out
AT91C_PA14_SPCK | // SPI Slave Clock
AT91C_PA15_TF | // SSC Tx Frame Sync
AT91C_PA16_TK | // SSC Tx Clock
AT91C_PA17_TD | // SSC Tx Data
AT91C_PA20_RF | // SSC Rx Frame Sync
AT91C_PA19_RK | // SSC Rx Clock
AT91C_PA18_RD, 0); // SSC Rx Data
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, PIO_TRST);
// AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PIO_TRST); // Clear Output ?
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, PIO_TRST);
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, PIO_BLUE_LED);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PIO_BLUE_LED);
*/
// Wait enumeration
while(!pCDC.IsConfigured(&pCDC));
// Start waiting some cmd
while (1)
{
nLen = AT91F_L0USB_GET_Data(aPacket, SIZEBUFMAX);
if (nLen)
{
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, PIO_BLUE_LED);
PacketHandler((CPacket *)aPacket);
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PIO_BLUE_LED);
}
}
} |
|