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

📄 channel.c

📁 freescale atk source code
💻 C
字号:
/******************************************************************************* channel.c**** Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.**** This file contains copyrighted material. Use of this file is** restricted by the provisions of a Freescale Software License** Agreement, which has either been electronically accepted by** you or has been expressly executed between the parties.**** Description: Explanation for the usage of this file.**** Revision History:** -----------------*****************************************************************************//*! * @file channel.c * * @brief the RAM Kernel channel source file * * @ingroup RAM Kernel *//****************************************************************************** <Includes>*****************************************************************************/#include "channel.h"#include "protocol.h"#include "debug.h"#include "platform.h"/****************************************************************************** <Macros>*****************************************************************************//****************************************************************************** <Typedefs>*****************************************************************************//* function declare *//* USB functions */static void setup_dTD(u32 base, u32 next_linkptr, u8 Terminate, u16 total_bytes,			u8 ioc, u8 Status, u32 BufferPtr0, u16 CurrentOffset, u32 BufferPtr1, 			u32 BufferPtr2, u32 BufferPtr3, u32 BufferPtr4);/* EP1out and EP2in rx/tx channel setup function */static void setup_EP1out_rx(u32 buf_addr, u32 offset, u32 count);static void setup_EP2in_tx(u32 buf_addr, u32 count);/* UART get/put functions */static u8 uart_getchar(void);static void uart_putchar(u8 c);/****************************************************************************** <Global Variables>*****************************************************************************/static u8 channel;/****************************************************************************** <Local Variables>*****************************************************************************/#define WD_TIMEOUT 0x20static inline void watchdog_service(void){	if (*(volatile u16 *)WDOG_WCR & 0x04) {		*(volatile u16 *)WDOG_WSR = 0x5555;		*(volatile u16 *)WDOG_WSR = 0xAAAA;	}}/*! * delay */static void delay(void){    int i;    for (i=0;i<100;i++) {    } }/*==================================================================================================FUNCTION: setup_dTDDESCRIPTION:    	This function is used to setup the dTDARGUMENTS PASSED:	u32 base_dTD - Base Address of the dTD	u32 NextLinkPtr - Next Link Pointer, 	u8 	terminate - Terminate - TERMINATE; not Terminate - NOT_TERMINATE	u16 total_bytes - Total Bytes to be transfered in this dQH	u8 	ioc - interrupt on complete, set - IOC_SET, not set - IOC_NOTSET	u8 	Status - Status 	u32 BuffPtr0 - Buffer Pointer page 0	u16 CurrentOffset - current offset	u32 BuffPtr1 - Buffer Pointer page 1	u32 BuffPtr2 - Buffer Pointer page 1	u32 BuffPtr3 - Buffer Pointer page 1	u32 BuffPtr4 - Buffer Pointer page 1	  RETURN VALUE:	None		IMPORTANT NOTES:	None		==================================================================================================*/void setup_dTD(u32 base, u32 next_linkptr, u8 terminate, u16 total_bytes, 				u8 ioc, u8 status,				u32 bufptr0, u16 offset, u32 bufptr1, 				u32 bufptr2, u32 bufptr3, u32 bufptr4){	volatile struct s_dTD_SETUP* dTD_word = (volatile struct s_dTD_SETUP*)base;		// Bit31:5 Next Link Pointer ; Bit0 terminate	dTD_word->dTD_WORD0 = (next_linkptr & 0xFFFFFFE0) | terminate;		// Bit30:16 total_bytes, Bit15 ioc, Bit7:0 status	dTD_word->dTD_WORD1 = (((u32)total_bytes & 0x7FFF) << 16)| ((u32)ioc <<15) | (status);		// Bit31:12 Buffer Pointer Page 0 ; Bit11:0 Current Offset	dTD_word->dTD_WORD2 = (bufptr0 & 0xFFFFF000) | (offset & 0xFFF);		// Bit31:12 Buffer Pointer Page 1 ; Bit10:0 Frame Number	dTD_word->dTD_WORD3 = (bufptr1 & 0xFFFFF000);	// Bit31:12 Buffer Pointer Page 2 ;	dTD_word->dTD_WORD4 = (bufptr2 & 0xFFFFF000);	// Bit31:12 Buffer Pointer Page 3 ; 	dTD_word->dTD_WORD5 = (bufptr3 & 0xFFFFF000);	// Bit31:12 Buffer Pointer Page 4 ; 	dTD_word->dTD_WORD6 = (bufptr4 & 0xFFFFF000);}/*==================================================================================================FUNCTION: setup_EP1outDESCRIPTION:    	This function is used to prepare the Setup command from PC and prime the endpointARGUMENTS PASSED:	None  RETURN VALUE:	None	IMPORTANT NOTES:	None==================================================================================================*/void setup_EP1out(u32 read_byte){	// setup dTD	// dTD for status of GET_DEVICE_DESCRIPTOR	setup_dTD(dTD0_EP1OUT, dTD1_EP1OUT, TERMINATE, read_byte, IOC_SET, ACTIVE, BUFPTR_P0_EP1OUT,(BUFPTR_P0_EP1OUT & 0xFFF),0,0,0,0);	// 1. write dQH next ptr and dQH terminate bit to 0 	*(u32 *)(dQH2_EP1OUT+0x8)= (dTD0_EP1OUT);		// 2. clear active & halt bit in dQH	*(u32 *)(dQH2_EP1OUT+0xC) &= ~0xFF;		// 3. prime endpoint by writing '1' in ENDPTPRIME	*(u32 *)USB_OTG_ENDPTPRIME |= EP1OUT_PRIME;	}/*! * Function to setup the receive from host channel *  * @buf_addr  receive data buffer * @count  receive data size * * @return */void setup_EP1out_rx(u32 buf_addr, u32 offset, u32 count){	u32 bufpage0, bufpage1, bufpage2,	    bufpage3, bufpage4;	/* fill the buffer page address */	bufpage0 = buf_addr;	bufpage1 = buf_addr + 0x1000;	bufpage2 = buf_addr + 0x2000;	bufpage3 = buf_addr + 0x3000;	bufpage4 = buf_addr + 0x4000;		/* Clear the EP1 OUT complete status if set */	if (*(u32 *)USB_OTG_ENDPTCOMPLETE & BIT1)		*(u32 *)USB_OTG_ENDPTCOMPLETE = BIT1;		/* setup dTD for status of GET_DEVICE_DESCRIPTOR */	setup_dTD(dTD0_EP1OUT, dTD1_EP1OUT, TERMINATE, count, IOC_SET, ACTIVE,			bufpage0, offset, bufpage1, bufpage2,			bufpage3, bufpage4);	/* write dQH next ptr and dQH terminate bit to 0 */	*(u32 *)(dQH2_EP1OUT + 0x8)= (dTD0_EP1OUT);		/* clear active & halt bit in dQH */	*(u32 *)(dQH2_EP1OUT + 0xC) &= ~0xFF;		/* prime endpoint by writing '1' in ENDPTPRIME */	*(u32 *)USB_OTG_ENDPTPRIME |= EP1OUT_PRIME;		/* Wait for the Complete Status */	while (!(*(volatile u32 *)USB_OTG_ENDPTCOMPLETE & BIT1));	/* clear the complete status */	*(volatile u32 *)USB_OTG_ENDPTCOMPLETE = BIT1;	return;}/*! * Function to setup the transmit to host channel *  * @buf_addr  transmit data buffer * @count  transmit data size * * @return */void setup_EP2in_tx(u32 buf_addr, u32 count){	u32 bufpage0, bufpage1, bufpage2,	    bufpage3, bufpage4;	/* fill the buffer page address */	bufpage0 = buf_addr;	bufpage1 = buf_addr + 0x1000;	bufpage2 = buf_addr + 0x2000;	bufpage3 = buf_addr + 0x3000;	bufpage4 = buf_addr + 0x4000;	/* setup the dTD with buffer page */	setup_dTD(dTD0_EP2IN, dTD1_EP2IN, TERMINATE, count, IOC_SET, ACTIVE,			bufpage0, bufpage0 & 0xFFF, bufpage1, 			bufpage2, bufpage3, bufpage4);		/* write dQH next ptr and dQH terminate bit to 0 */	*(u32 *)(dQH5_EP2IN + 0x8)= dTD0_EP2IN;		/* clear active & halt bit in dQH */	*(u32 *)(dQH5_EP2IN + 0xC) &= ~0xFF;		/* prime endpoint by writing '1' in ENDPTPRIME */	*(u32 *)USB_OTG_ENDPTPRIME = EP2IN_PRIME;		/* wait for complete set and clear */	while (!(*(volatile u32 *)USB_OTG_ENDPTCOMPLETE & EP2IN_COMPLETE));		*(u32 *)USB_OTG_ENDPTCOMPLETE = EP2IN_COMPLETE;	return;}/*! * Function to get a character from UART FIFO * * @return character value */static u8 uart_getchar(void){	return (*(volatile u32 *)UART1_URXD_1 & 0xFF);}/*! * Function to put a character into UART FIFO */static void uart_putchar(u8 c){	*(volatile u32 *)UART1_UTXD_1 = c;}/*! * Function to initial channel of USB or UART * * @ch channel type */void atk_channel_init(u8 ch){	/* disable watchdog */	watchdog_service();	//*(volatile u16 *)0x53FDC000 &= ~0x08;	channel = ch;	dbg("Initial the channel finish\n");	return;}/*! * Function to receive data from host through channel * * @buf  buffer to fill in * @count  read data size * * @return 0 */u32 atk_channel_recv(u8 *buf, u32 count){	u32 i = 0, len;	u32 to = WD_TIMEOUT;		if (channel == CHAN_USB) {		while (count) {			/* fix the size length to 16K due to HW limit */			if (count > MAX_USB_DATA_LEN) {				len = MAX_USB_DATA_LEN; 			} else {				len = count;			}			/* setup EP out rx channel */			setup_EP1out_rx((u32)&buf[i], (u32)(&buf[i]) & 0xFFF, len);			count -= len;			i += len;		}	} else {		watchdog_service();		for (i=0; i < count; i++) {			/* check the receive status */			while (!(*(volatile u32 *)UART1_USR2_1 & 0x1)) {				if (--to <= 0) {					watchdog_service();					to = WD_TIMEOUT;				}			}			buf[i] = uart_getchar(); 			if (--to <= 0) {				watchdog_service();				to = WD_TIMEOUT;			}		}	}	return 0;}/*! * Function to send data to host through channel * * @buf  buf to send * @count  send data size * * @return 0 */u32 atk_channel_send(const u8 *buf, u32 count){	u32 size;	u32 i;	u32 to = WD_TIMEOUT;	if (channel == CHAN_USB) {		while (count) {			size = count > MAX_USB_DATA_LEN ? MAX_USB_DATA_LEN : count;			/* FIXME: if the buffer is messed by the USB, use static buffer arrary */			/* setup EP2 Tx data channel */			setup_EP2in_tx((u32)buf, size);			count -= size;			buf += size; /* update buffer addr */		}			} else {		watchdog_service();		for (i = 0; i < count; i++) {			delay();			/* put data to UART transmit fifo */			uart_putchar(buf[i]);			/* wait for TF empty */			while (!(*(volatile u32 *)UART1_USR2_1 & 0x4000)){			if (--to <= 0) {					watchdog_service();					to = WD_TIMEOUT;				}			}			if (--to <= 0) {				watchdog_service();				to = WD_TIMEOUT;			}		}		}	return 0;}

⌨️ 快捷键说明

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