📄 channel.c
字号:
}/*! * This function is used to enable input * * @return */ void EnableEP2IN(void){ // EP2 IN response = 4 bytes u32 TotalBytes = 0x4; struct s_dQH qhead; qhead.dQHBase = dQH5_EP2IN; qhead.ZLT = ZLT_DISABLE; qhead.MPS = MPS_64; qhead.ios = IOS_SET; qhead.NextLinkPtr = dTD0_EP2IN; qhead.Terminate = TERMINATE; qhead.TotalBytes = TotalBytes; qhead.ioc = IOC_SET; qhead.Status = NO_STATUS; qhead.BuffPtr0 = BUFPTR_P0_EP2IN; qhead.CurrentOffset = (BUFPTR_P0_EP2IN & 0xFFF); qhead.BuffPtr1 = 0; qhead.BuffPtr2 = 0; qhead.BuffPtr3 = 0; qhead.BuffPtr4 = 0; // EP1 OUT command = 16 bytes setup_dQH(&qhead); // Endpoint 2: MPS = 64, IN (Tx endpoint) *(u32 *)USB_OTG_ENDPTCTRL2 = 0x00480008; // Enable EP2 IN *(u32 *)USB_OTG_ENDPTCTRL2 |= EP2IN_ENABLE; // 3. prime endpoint by writing '1' in ENDPTPRIME *(u32 *)USB_OTG_ENDPTPRIME |= EP2IN_PRIME; }/*! * This function is used to transmit the data for READ command * @BufPtrAddress * @TotalBytes * @return */ void setup_EP2in_tx(u32 buf_addr, u32 count){ struct s_dTD td; td.dTDBase = dTD0_EP2IN; td.dTDNextLinkPtr = dTD1_EP2IN; td.Terminate = TERMINATE; td.TotalBytes = count; td.ioc = IOC_SET; td.Status = ACTIVE; td.BuffPtr0 = buf_addr; td.CurrentOffset = buf_addr & 0xFFF; td.BuffPtr1 = buf_addr + 0x1000; td.BuffPtr2 = buf_addr + 0x2000; td.BuffPtr3 = buf_addr + 0x3000; td.BuffPtr4 = buf_addr + 0x4000; setup_dTD(&td); // 1. write dQH next ptr and dQH terminate bit to 0 *(u32 *)(dQH5_EP2IN+0x8)= (dTD0_EP2IN); // 2. clear active & halt bit in dQH *(u32 *)(dQH5_EP2IN+0xC) &= ~0xFF; // 3. 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;}/*! * 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;}#ifdef UNIT_TEST/*! * Function to initial the UART1 */static void uart_init(void){ /*! * configure GPIO for UART1 */ /* Configure TXD1 as functional output, RX1 as functional input */ *(volatile u32 *)SW_MUX_CTL_CSPI2_SCLK_CSPI2_SPI_RDY_RXD1_TXD1 &= 0xffff0000; *(volatile u32 *)SW_MUX_CTL_CSPI2_SCLK_CSPI2_SPI_RDY_RXD1_TXD1 |= 0x00001210; /* Configure CTS1 as functional output, RTS1 as functional input */ *(volatile u32 *)SW_MUX_CTL_RTS1_CTS1_DTR_DCE1_DSR_DCE1 &= 0x0000ffff; *(volatile u32 *)SW_MUX_CTL_RTS1_CTS1_DTR_DCE1_DSR_DCE1 |= 0x12100000; /*! * enable the UART1 clock */ /* re-write reset values to CCM_MPCTL */ *(volatile u32 *)CCM_PDR0 = 0xFF870B48; /* Verify that UART1 clock is enabled: CGR[23:22]=11 */ *(volatile u32 *)CCM_CGR0 |= 0x00C00000; /* Finally program pll and wait for lock... */ if (*(volatile u32 *)CCM_MPCTL != 0x04001800) { *(volatile u32 *)CCM_MPCTL= 0x04001800 ; } /*! * configure the UART1 HW */ /* set to odd parity, 1 stop bit, 8bit tx/rx length */ *(volatile u32 *)UART1_UCR2_1 = 0x60A6; /* Control register3:RXDMUXSEL = 1 */ *(volatile u32 *)UART1_UCR3_1 = 0x0004; /* Control register4: 32 characters in the RxFIFO */ *(volatile u32 *)UART1_UCR4_1 = 0x8000; /* Control register1: Enable UART */ *(volatile u32 *)UART1_UCR1_1 = 0x0001; /** * Set up reference freq divide for UART module * ipg_perclk=13MHz * ref_clk=ipg_perclk/RFDIV; ref_clk=13MHz --> RFDIV=1 */ *(volatile u32 *)UART1_UFCR_1 = 0x0A81; /* Make sure that no test mode is active */ *(volatile u32 *)UART1_UTS_1 = 0x0000; /** * Set Boud Rate to 115200 KBPS * (Boud Rate)=RefFreq/(16x(UBMR+1)/(UBIR+1)) * (UBMR+1)=16; (UBIR+1)=426 * UBIR register MUST be updated before the UBMR register */ *(volatile u32 *)UART1_UBIR_1 = 0x0F; /* rel 2.9 clock mode detection */ if (((*(volatile u32 *)CCM_CCMR ) & CLOCK_SEL_MASK )== CKIL_CLOCK_SEL) { /** * RefFreq= ( 32 * 1024 *6) / 4 = 48*1024 Khz * (UBMR+1)=16; (UBIR+1)=426 * So Baudrate = (48 * 1024 )/( 16 * 426 / 16 ) =115380 ; */ *(volatile u32 *)UART1_UBMR_1 = 0x1A9; } else { /** * RefFreq= ( 26 *6) / 4 = 39 Mhz * (UBMR+1)=16; (UBIR+1)= 339 ; * So Baudrate = (39 )/( 16 * 339 / 16 ) =115044 ; */ *(volatile u32 *)UART1_UBMR_1 = 0x152; }}#endif/*! * Function to initial channel of USB or UART * * @ch channel type */void atk_channel_init(u8 ch){ channel = ch; dbg("Initial the channel finish\n");#ifdef UNIT_TEST /* initial UART to test the basic function of RAM Kernel */ //uart_init();#endif /* FIXME, this is just a workaround for usb * use NFC internal RAM, set init state */ if (channel == CHAN_USB) cache_usb.sate = STATE_EMPTY; return;}/* FIXME, this is just a workaround for the rom usb * use NFC internal RAM */ static __inline void pop_usb_dqh(void) { if(cache_usb.sate == STATE_DIRTY) memcpy((u16*)dQHBASE,&cache_usb.data[0],sizeof(cache_usb.data));}static __inline void push_usb_dqh(void){ if(cache_usb.sate == STATE_EMPTY) { memcpy(&cache_usb.data[0],(u16*)dQHBASE,sizeof(cache_usb.data)); cache_usb.sate = STATE_DIRTY; } }/*! * 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; if (channel == CHAN_USB) { /* FIXME, this is just a workaround for usb * use NFC internal RAM, need recovery the usb information * from the back up buffer.The back up buffer was filled when * the first time trans data */ pop_usb_dqh(); 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; } /* FIXME, this is just a workaround for usb * use NFC internal RAM.The back up buffer was * filled when the first time trans data */ push_usb_dqh(); } else { for (i=0; i < count; i++) { /* check the receive status */ while (!(*(volatile u32 *)UART1_USR2_1 & 0x1)); buf[i] = uart_getchar(); } } 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; if (channel == CHAN_USB) { /* FIXME, this is just a workaround for usb * use NFC internal RAM, need recovery the usb information * from the back up buffer.The back up buffer was filled when * the first time trans data */ pop_usb_dqh(); 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 */ } /* FIXME, this is just a workaround for usb * use NFC internal RAM.The back up buffer was * filled when the first time usb trans data */ push_usb_dqh(); } else { for (i = 0; i < count; i++) { /* put data to UART transmit fifo */ delay(); uart_putchar(buf[i]); /* wait for TF empty */ while (!(*(volatile u32 *)UART1_USR2_1 & 0x4000)); } } return 0;}#ifdef _DEBUGvoid atk_debug(const char *format, /* args*/ ...){ u8 strData[DBG_LOG_LEN] = { 0 }; u8 strPatten[RKL_RESPONSE_LEN] = {'d','b','g','_','l','o','g','s'}; va_list args ; va_start(args, format) ; vsnprintf((char*)strData, 256, format, args) ; va_end(args) ; atk_channel_send(strPatten, sizeof(strPatten)); atk_channel_send(strData, sizeof(strData));}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -