📄 main.c
字号:
//*----------------------------------------------------------------------------
//* 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 : main application written in C
//* Creation : ODi 01/06/2003
//*
//*----------------------------------------------------------------------------
#include "AT91RM9200.h"
#include "lib_AT91RM9200.h"
#include "ohci.h"
#include "timeout.h"
extern void AT91F_DBGU_Printk(char *);
// =====================================
// Memory allocation for UHP:
// =====================================
// UHP HCCA memory location:
__align(32) AT91S_UHP_HCCA HCCA;
// UHP transfer descriptors:
__align(32) AT91S_UHP_ED pUHPEd[1];
__align(32) AT91S_UHP_ED pUHPTd[4];
// UHP data area
const char pUHPSetup[8] = {
0x08,
0x06,
0x00,
0x01,
0x00,
0x00,
0x40,
0x00
};
#define DataSIZE 0x12
char pUHPData[DataSIZE];
// =====================================
// Memory allocation for UDP:
// =====================================
// UDP data area
char pUDPSetup[8];
const char pUDPData[DataSIZE] = {
0x12,
0x01,
0x00,
0x01,
0x00,
0x00,
0x00,
0x08,
0x7B,
0x05,
0x00,
0x00,
0x04,
0x03,
0x01,
0x02,
0x00,
0x01
};
#define AT91C_PRDSTRTVAL 0x2240
#define AT91C_FRINTERVAL 0x2710
#define AT91C_FSMAXPKTSZ (((AT91C_FRINTERVAL * 6) / 7) - 180)
#define AT91C_PRDSTRT AT91C_PRDSTRTVAL
#define AT91C_FMINTERVAL ((AT91C_FSMAXPKTSZ << 16) | AT91C_FRINTERVAL)
//*----------------------------------------------------------------------------
//* \fn main
//* \brief
//*----------------------------------------------------------------------------
int main()
{
AT91PS_UHP pUhp = AT91C_BASE_UHP;
AT91PS_UDP pUdp = AT91C_BASE_UDP;
unsigned int i;
AT91S_TIMEOUT timeout;
AT91F_DBGU_Printk(
"\n\n\r-I- ======================================\n\r\
-I- AT91RM9200 basic UHP example\n\r\
-I- --------------------------------------\n\r\
-I- Connect the UDP port to a UHP port...\n\r\
-I- ======================================\n\r");
/* ************************************************ */
/* Desactivate UDP pull up PIOD5 */
/* ************************************************ */
AT91F_PIO_CfgOutput(AT91C_BASE_PIOD, AT91C_PIO_PD5);
AT91F_PIO_ClearOutput(AT91C_BASE_PIOD, AT91C_PIO_PD5);
/* ************************************************ */
/* Open UDP+UHP clocks */
/* ************************************************ */
// Open clocks for USB host + device
AT91F_UHP_CfgPMC();
AT91F_UDP_CfgPMC();
AT91C_BASE_PMC->PMC_SCER |= (AT91C_PMC_UHP | AT91C_PMC_UDP);
/* ************************************************ */
/* Configure the UHP */
/* ************************************************ */
// Desactivate all IT
pUdp->UDP_IDR = (unsigned int) -1;
// Disable all pending IT
pUdp->UDP_ICR = (unsigned int) -1;
// RESET UDP
pUdp->UDP_RSTEP = 0;
pUdp->UDP_GLBSTATE = 0;
// Forcing UHP_Hc to reset
pUhp->UHP_HcControl = 0;
// Writing the UHP_HCCA
pUhp->UHP_HcHCCA = (unsigned int) &HCCA;
// Enabling list processing
pUhp->UHP_HcControl = 0;
// Set the frame interval
pUhp->UHP_HcFmInterval = AT91C_FMINTERVAL;
pUhp->UHP_HcPeriodicStart = AT91C_PRDSTRT;
// Create a default endpoint descriptor
AT91F_CreateEd(
(unsigned int) pUHPEd, // ED Address
8, // Max packet
0, // TD format
0, // Skip
0, // Speed
0x0, // Direction
0x0, // Endpoint
0x0, // Func Address
(unsigned int) &pUHPTd[3], // TDQTailPointer
(unsigned int) &pUHPTd[0], // TDQHeadPointer
0, // ToggleCarry
0x0); // NextED
// Setup PID
AT91F_CreateGenTd(
(unsigned int) &pUHPTd[0], // TD Address
2, // Data Toggle
0x7, // DelayInterrupt
0x0, // Direction
1, // Buffer Rounding
(unsigned int) pUHPSetup, // Current Buffer Pointer
(unsigned int) &pUHPTd[1], // Next TD
8); // Buffer Length
// Data IN
AT91F_CreateGenTd(
(unsigned int) &pUHPTd[1], // TD Address
0, // Data Toggle
0x7, // DelayInterrupt
0x2, // Direction
1, // Buffer Rounding
(unsigned int) pUHPData, // Current Buffer Pointer
(unsigned int) &pUHPTd[2], // Next TD
DataSIZE); // Buffer Length
// Status OUT
AT91F_CreateGenTd(
(unsigned int) &pUHPTd[2], // TD Address
3, // Data Toggle
0x7, // DelayInterrupt
0x1, // Direction
1, // Buffer Rounding
0x0, // Current Buffer Pointer
(unsigned int) &pUHPTd[3], // Next TD
0x0); // Buffer Length
AT91F_CreateGenTd(
(unsigned int) &pUHPTd[3], // TD Address
3, // Data Toggle
0x7, // DelayInterrupt
0x1, // Direction
1, // Buffer Rounding
0x0, // Current Buffer Pointer
(unsigned int) 0, // Next TD
0x0); // Buffer Length
// Programming the BHED
pUhp->UHP_HcControlHeadED = (unsigned int) pUHPEd;
// Programming the BCED
pUhp->UHP_HcControlCurrentED = (unsigned int) pUHPEd;
// Initializing the UHP_HcDoneHead
pUhp->UHP_HcBulkDoneHead = 0x00;
HCCA.UHP_HccaDoneHead = 0x0000;
// Forcing UHP_Hc to Operational State
pUhp->UHP_HcControl = 0x80;
// Enabling port power
pUhp->UHP_HcRhPortStatus[0] = 0x00000100;
pUhp->UHP_HcRhPortStatus[1] = 0x00000100;
pUhp->UHP_HcRhStatus = 0x00010000;
/* ************************************************ */
/* Activate UDP pull up PIOA18 */
/* ************************************************ */
// UDP: Connect a pull-up
AT91F_PIO_SetOutput(AT91C_BASE_PIOD, AT91C_PIO_PD5);
/* ************************************************ */
/* Detect a connected deviced, generate a reset... */
/* ************************************************ */
// UHP: Detect the device on one port, generate a reset and enable the port
AT91F_InitTimeout(&timeout, 2);
while (1) {
if ( (pUhp->UHP_HcRhPortStatus[0] & 0x01) ) {
AT91F_DBGU_Printk("-I- Device detected on port 0\n\r");
pUhp->UHP_HcRhPortStatus[0] = (1 << 4); // SetPortReset
while (pUhp->UHP_HcRhPortStatus[0] & (1 << 4)); // Wait for the end of reset
pUhp->UHP_HcRhPortStatus[0] = (1 << 1); // SetPortEnable
break;
}
else if ( (pUhp->UHP_HcRhPortStatus[1] & 0x01) ) {
pUhp->UHP_HcRhPortStatus[1] = (1 << 4); // SetPortReset
while (pUhp->UHP_HcRhPortStatus[1] & (1 << 4)); // Wait for the end of reset
pUhp->UHP_HcRhPortStatus[1] = (1 << 1); // SetPortEnable
break;
}
else if ( !AT91F_TestTimeout(&timeout) ) {
AT91F_DBGU_Printk("-E- Please connect the UHP port to the UDP port\n\r");
goto error;
}
}
// UHP: UHP is now operational and control list processing is enabled
pUhp->UHP_HcControl = 0x90;
// UDP: Wait for end bus reset
AT91F_InitTimeout(&timeout, 2);
while ( !(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES)) {
if ( !AT91F_TestTimeout(&timeout)) {
AT91F_DBGU_Printk("-E- End of bus reset not received\n\r");
goto error;
}
}
pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
pUdp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
AT91F_DBGU_Printk("-I- A reset has been detected by the UDP\n\r");
/* ************************************************ */
/* Generate traffic between UHP and UDP */
/* ************************************************ */
// UHP: Notify the Hc that the Control list is filled
pUhp->UHP_HcCommandStatus = 0x02;
// UDP: Wait for a Setup packet
AT91F_InitTimeout(&timeout, 2);
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP)) {
if ( !AT91F_TestTimeout(&timeout)) {
AT91F_DBGU_Printk("-E- No setup packet has been received by the UDP\n\r");
goto error;
}
}
for (i = 0; i < 8; ++i)
pUDPSetup[i] = pUdp->UDP_FDR[0];
pUdp->UDP_CSR[0] |= AT91C_UDP_DIR; // Data stage will be DATA IN transactions
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RXSETUP);
AT91F_DBGU_Printk("-I- A setup packet has been sent by UDP and received by UHP\n\r");
// UDP: Send several Data packets
for (i = 0; i < DataSIZE; ++ i) {
pUdp->UDP_FDR[0] = pUDPData[i];
// UDP: Detect a packet frontier, send it and wait for the end of transmition
if ( !((i+1) % 8) || (i == (DataSIZE - 1))) {
pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
AT91F_InitTimeout(&timeout, 2);
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP)) {
if ( !AT91F_TestTimeout(&timeout)) {
AT91F_DBGU_Printk("-E- A data packet has not been acknowledged by the UHP\n\r");
goto error;
}
}
pUdp->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
AT91F_DBGU_Printk("-I- A data packet has been sent by UDP and received by UHP\n\r");
}
}
// UDP: Wait for the status sent by the host
AT91F_InitTimeout(&timeout, 2);
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0)) {
if ( !AT91F_TestTimeout(&timeout)) {
AT91F_DBGU_Printk("-E- No status packet has been sent by the UHP\n\r");
goto error;
}
}
pUdp->UDP_CSR[0] = ~AT91C_UDP_RX_DATA_BK0;
AT91F_DBGU_Printk("-I- A status data packet has been sent by UHP and received by UDP\n\r");
/* ************************************************ */
/* Compare data sent and received */
/* ************************************************ */
AT91F_DBGU_Printk("-I- Compare sent/received setup packet ...");
for (i = 0; i < 8; ++i) {
if (pUHPSetup[i] != pUDPSetup[i]) {
AT91F_DBGU_Printk("Failed\n\r");
goto error;
}
}
AT91F_DBGU_Printk(" Success\n\r");
AT91F_DBGU_Printk("-I- Compare sent/received data packet ...");
for (i = 0; i < DataSIZE; ++i) {
if (pUHPData[i] != pUDPData[i]) {
AT91F_DBGU_Printk("Failed\n\r");
goto error;
}
}
AT91F_DBGU_Printk(" Success\n\r");
AT91F_DBGU_Printk("-I- Test successfull...\n\r");
while (1);
error:
AT91F_DBGU_Printk("-F- Test failed...\n\r");
while (1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -