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

📄 lib_uhp.c

📁 关于测试at91sam9260的各种驱动和功能的测试源代码。
💻 C
字号:
/*************************************** Copyright (c) *************************************************
*
*			            POLAR STAR
*				   北天星国际有限公司
*				   http://www.po-star.com
*
*文 件 名: lib_uhp.c    
*文件描述:uhp test
*编译环境:ADS1.2
*
********************************************************************************************************/

#include "main.h"
#include "ohci.h"
#include "timeout.h"


#undef LOW_SPEED

int g_port;

// =====================================
// 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

#ifdef LOW_SPEED
const char pUHPSetup[8] = {
	0x80,
	0x06,
	0x00,
	0x01,
	0x00,
	0x00,
	0x40,
	0x00
};
#else
const char pUHPSetup[8] = {
	0x08,
	0x06,
	0x00,
	0x01,
	0x00,
	0x00,
	0x40,
	0x00
};
#endif

#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 AT91F_testUHP()
{
	AT91PS_UHP      pUhp = AT91C_BASE_UHP;
	AT91PS_UDP      pUdp = AT91C_BASE_UDP;

	unsigned int i;
	AT91S_TIMEOUT timeout;

	/* ************************************************ */
	/* Deactivate UDP pull up 		                    */
	/* ************************************************ */
//	AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB30);
//	AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB30);
	AT91C_BASE_UDP->UDP_TXVC &= (~AT91C_UDP_PUON);


	/* ************************************************ */
	/* Open UDP+UHP clocks                              */
	/* ************************************************ */
    AT91F_UHP_CfgPMC();
    AT91F_UDP_CfgPMC();
    AT91C_BASE_PMC->PMC_SCER = (AT91C_PMC_UHP | AT91C_PMC_UDP); // AT91C_PMC_HCK0

	/* ************************************************ */
	/* 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
#ifdef LOW_SPEED
	AT91F_CreateEd(
		(unsigned int) pUHPEd, // ED Address
		8,      // Max packet
		0,      // TD format
		0,      // Skip
		1,      // Speed = 1 (Low)  0 (Full)
		0x0,    // Direction
		0x0,    // Endpoint
		0x0,    // Func Address
		(unsigned int) &pUHPTd[3],    // TDQTailPointer
		(unsigned int) &pUHPTd[0],    // TDQHeadPointer
		0,      // ToggleCarry
		0x0);   // NextED
#else
	AT91F_CreateEd(
		(unsigned int) pUHPEd, // ED Address
		8,      // Max packet
		0,      // TD format
		0,      // Skip
		0,      // Speed = 1 (Low)  0 (Full)
		0x0,    // Direction
		0x0,    // Endpoint
		0x0,    // Func Address
		(unsigned int) &pUHPTd[3],    // TDQTailPointer
		(unsigned int) &pUHPTd[0],    // TDQHeadPointer
		0,      // ToggleCarry
		0x0);   // NextED
#endif
	// 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 PIOB30                      */
	/* ************************************************ */
	// UDP: Connect a pull-up
//	AT91F_PIO_SetOutput(AT91C_BASE_PIOB, AT91C_PIO_PB30);
	AT91C_BASE_UDP->UDP_TXVC |= (AT91C_UDP_PUON);

	/* ************************************************ */
	/* 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) ) {
			g_port = 0;
			AT91F_DBGU_Printk("# USB A ");
			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) ) {
			g_port = 1;
			AT91F_DBGU_Printk("# USB B ");
			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) ) {
			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)) {
			goto error;
		}
	}

	pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
	pUdp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);


	/* ************************************************ */
	/* 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)) {
			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
	while ( !(pUdp->UDP_CSR[0] & (AT91C_UDP_DIR)) );
	pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RXSETUP);
	while ( pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP );

	// 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)) {
					goto error;
				}
			}
			pUdp->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
			while ( pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP );
		}
	}

	// 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)) {
			goto error;
		}
	}
	pUdp->UDP_CSR[0] = ~AT91C_UDP_RX_DATA_BK0;
	while ( pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0 );

	/* ************************************************ */
	/* Compare data sent and received                   */
	/* ************************************************ */
	for (i = 0; i < 8; ++i) {
		if (pUHPSetup[i] != pUDPSetup[i]) {
			goto error;
		}
	}
	
	for (i = 0; i < DataSIZE; ++i) {
		if (pUHPData[i] != pUDPData[i]) {
			goto error;
		}
	}
	
	AT91F_DBGU_Printk("-I- Test OK\n\r");
	return 0;

error:
	AT91F_DBGU_Printk("-E- FAIL ***\n\r");
	return -1;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_TestUHP
//* \brief 
//*----------------------------------------------------------------------------
int AT91F_TestUHP()
{
	int err_0 = 0, err_1 = 0, err = 0;

    AT91F_DBGU_Printk("\n\r-I- Step 10. Test USB UHP/UDP\n\r");
	AT91F_DBGU_Printk("-I- Please connect the USB cable onto the first plug\n\r");
	AT91F_DBGU_Printk("-I- Hit a key when ready !!!\n\r");
	AT91F_Wait4KeyPressed();

	// Perform first test on first connector
	err = AT91F_testUHP();
	
	if (g_port == 0)
		err_0 = err;
	else
		err_1 = err;

	AT91F_DBGU_Printk("-I- Please connect the USB cable onto the second plug\n\r");
	AT91F_DBGU_Printk("-I- Hit a key when ready !!!\n\r");
	AT91F_Wait4KeyPressed();
	
	// Perform second test on second connector
	err = AT91F_testUHP();

	if (g_port == 0)
		err_0 = err; 
	else
		err_1 = err;		

	if ((err_0 < 0 ) || (err_1 < 0))
		return -1;
	
	return 0;
}

⌨️ 快捷键说明

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