/*put bytes to tx buffer, return value is the actually put out bytes*/ static kal_uint16 USB2UART_PutBytes(UART_PORT port, kal_uint8 *buffaddr, kal_uint16 length, module_type ownerid) { kal_uint16 real_count; // kal_uint16 index; kal_uint32 savedMask; kal_uint8 ep_num = 0; kal_bool setup_dma = KAL_FALSE; kal_int32 remain; BUFFER_INFO *tx_info = &(USB2UARTPort.Tx_Buffer); if(ownerid != USB2UARTPort.ownerid) { #ifdef __PRODUCTION_RELEASE__ return 0; #else /* __PRODUCTION_RELEASE__ */ EXT_ASSERT( 0, (kal_uint32) ownerid, USB2UARTPort.ownerid, 0); #endif } /* return directly if not match condition */ if ( (gUsbDevice.device_type != USB_CDC_ACM) || (USB2UARTPort.initialized == KAL_FALSE) || (gUsbDevice.nDevState!=DEVSTATE_CONFIG)) { if(((gUsbDevice.device_type == USB_CDC_ACM)||(gUsbDevice.usb_comport_boot == KAL_TRUE)) && (USB2UARTPort.initialized == KAL_TRUE)&&(gUsbDevice.nDevState != DEVSTATE_CONFIG)) { g_UsbACM.config_send_Txilm = KAL_TRUE; /* for PC set config later then can issue the first message */ } return 0; } /* The same issue as USB2UART_GetBytes() The area to determine send_Txilm must also contain in critical section. Otherwise if DMA callback activated before send_Txilm setting as true, this message will be lost */ savedMask = SaveAndSetIRQMask(); Buf_GetRoomLeft(tx_info, real_count); /* determine real sent data count */ if (real_count > length) { real_count = length; } else { g_UsbACM.send_Txilm = KAL_TRUE; /*After this time put bytes, buffer will be full */ g_UsbACM.config_send_Txilm = KAL_TRUE; /* if be reseted, then it can issue the message waited for*/ } RestoreIRQMask(savedMask); if(g_UsbACM.send_Txilm == KAL_TRUE) { if(ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_PUT_BYTES_BUF_FULL, ownerid); // kal_prompt_trace(MOD_USB, "RDY W %d", ownerid); } } if(real_count != 0) { remain = (BWrite(tx_info) + real_count) - BLength(tx_info); if(remain < 0) { /* dest, src, len */ kal_mem_cpy(BuffWrite(tx_info), buffaddr, real_count); BWrite(tx_info) += real_count; } else { kal_mem_cpy(BuffWrite(tx_info), buffaddr, real_count-remain); kal_mem_cpy(BStartAddr(tx_info), (kal_uint8 *)(buffaddr+real_count-remain), remain); BWrite(tx_info) = remain; } } /* push data from caller buffer to ring buffer */ /* for (index = 0; index < real_count; index++) { Buf_Push(&(USB2UARTPort.Tx_Buffer), *(buffaddr+index)); } */ savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section */ if(gUsbDevice.device_type == USB_CDC_ACM) { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) if(g_UsbACM.setup_dma == KAL_FALSE) { g_UsbACM.setup_dma = KAL_TRUE; setup_dma = KAL_TRUE; ep_num = g_UsbACM.txpipe->byEP; } } RestoreIRQMask(savedMask); if(setup_dma == KAL_TRUE) { USB_Dbg_Trace(USB_ACM_DMA_SETUP_1, drv_get_current_time(), ep_num, 0); USB2UART_DMATransmit(ep_num, KAL_FALSE); } #ifndef __PRODUCTION_RELEASE__ if(ownerid != USB2UARTPort.ownerid) { EXT_ASSERT( 0, (kal_uint32) ownerid, (kal_uint32)USB2UARTPort.ownerid, 0); } if(ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_PUT_BYTES, real_count); // kal_prompt_trace(MOD_USB, "Put %d", real_count); } #endif return real_count; }
/* put bytes to ISR tx buffer, return value is the actually put out bytes */ static kal_uint16 USB2UART_PutISRBytes(UART_PORT port, kal_uint8 *buffaddr, kal_uint16 length, module_type ownerid) { kal_uint16 real_count; // kal_uint16 index; kal_uint32 savedMask; kal_uint8 ep_num = 0; kal_bool setup_dma = KAL_FALSE; kal_int32 remain; BUFFER_INFO *tx_isr_info = &(USB2UARTPort.Tx_Buffer_ISR); if(ownerid != USB2UARTPort.ownerid) { #ifdef __PRODUCTION_RELEASE__ return 0; #else /* __PRODUCTION_RELEASE__ */ EXT_ASSERT( 0, (kal_uint32) ownerid, USB2UARTPort.ownerid, 0); #endif } if ( (gUsbDevice.device_type != USB_CDC_ACM) || (USB2UARTPort.initialized == KAL_FALSE) || (gUsbDevice.nDevState!=DEVSTATE_CONFIG)) return 0; savedMask = SaveAndSetIRQMask(); Buf_GetRoomLeft(tx_isr_info, real_count); RestoreIRQMask(savedMask); /* determine real sent data count */ if (real_count > length) real_count = length; if(real_count != 0) { remain = (BWrite(tx_isr_info) + real_count) - BLength(tx_isr_info); if(remain < 0) { /* dest, src, len */ kal_mem_cpy(BuffWrite(tx_isr_info), buffaddr, real_count); BWrite(tx_isr_info) += real_count; } else { kal_mem_cpy(BuffWrite(tx_isr_info), buffaddr, real_count-remain); kal_mem_cpy(BStartAddr(tx_isr_info), (kal_uint8 *)(buffaddr+real_count-remain), remain); BWrite(tx_isr_info) = remain; } } /* push data from caller buffer to ring buffer */ /* for (index = 0; index < real_count; index++) { Buf_Push(tx_isr_info, *(buffaddr+index)); } */ savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section */ if(gUsbDevice.device_type == USB_CDC_ACM) { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) if(g_UsbACM.setup_dma == KAL_FALSE) { g_UsbACM.setup_dma = KAL_TRUE; setup_dma = KAL_TRUE; ep_num = g_UsbACM.txpipe->byEP; } } RestoreIRQMask(savedMask); if(setup_dma == KAL_TRUE) { USB_Dbg_Trace(USB_ACM_DMA_SETUP_2, drv_get_current_time(), ep_num, 0); USB2UART_DMATransmit(ep_num, KAL_FALSE); } #ifndef __PRODUCTION_RELEASE__ if(ownerid != USB2UARTPort.ownerid) { EXT_ASSERT( 0, (kal_uint32) ownerid, (kal_uint32)USB2UARTPort.ownerid, 0); } #endif if(ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_PUT_ISR_BYTES, real_count); // kal_prompt_trace(MOD_USB, "PutISR %d", real_count); } return real_count; }
/* put bytes to ISR tx buffer, handle the special character in this function(add escape character) return value is the actually put out bytes*/ static kal_uint16 USB2UART_SendISRData(UART_PORT port, kal_uint8 *buffaddr, kal_uint16 length, kal_uint8 mode, kal_uint8 escape_char, module_type ownerid) { kal_int16 real_count, index; kal_uint8 data; kal_uint32 savedMask; kal_uint8 ep_num = 0; kal_bool setup_dma = KAL_FALSE; BUFFER_INFO *tx_isr_info = &(USB2UARTPort.Tx_Buffer_ISR); if(ownerid != USB2UARTPort.ownerid) { #ifdef __PRODUCTION_RELEASE__ return 0; #else EXT_ASSERT( 0, (kal_uint32) ownerid, USB2UARTPort.ownerid, 0); #endif } if ( (gUsbDevice.device_type != USB_CDC_ACM) || (USB2UARTPort.initialized == KAL_FALSE) || (gUsbDevice.nDevState!=DEVSTATE_CONFIG)) return 0; if (mode == 0) { real_count = USB2UART_PutISRBytes(port, buffaddr, length, ownerid); } else { savedMask = SaveAndSetIRQMask(); Buf_GetRoomLeft(tx_isr_info, real_count); RestoreIRQMask(savedMask); /* determine real sent data count */ if (real_count > length) real_count = length; for (index = 0; index < real_count; index++) { kal_uint16 roomleft; savedMask = SaveAndSetIRQMask(); Buf_GetRoomLeft(tx_isr_info, roomleft); RestoreIRQMask(savedMask); data = *(buffaddr + index); /* if the character is special character, translate it. PC has the ability to distinguish it*/ if (data == USB2UARTPort.DCB.xonChar) { if ( roomleft >= 2 ) { Buf_Push(tx_isr_info, escape_char); Buf_Push(tx_isr_info, 0x01); } else { break; } } else if (data == USB2UARTPort.DCB.xoffChar) { if ( roomleft >= 2 ) { Buf_Push(tx_isr_info, escape_char); Buf_Push(tx_isr_info, 0x02); } else { break; } } else if (data == escape_char) { if ( roomleft >= 2 ) { Buf_Push(tx_isr_info, escape_char); Buf_Push(tx_isr_info, 0x03); } else { break; } } else { if (roomleft) { Buf_Push(tx_isr_info, data); } else { break; } } } real_count = index; savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section */ if(gUsbDevice.device_type == USB_CDC_ACM) { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) if(g_UsbACM.setup_dma == KAL_FALSE) { g_UsbACM.setup_dma = KAL_TRUE; setup_dma = KAL_TRUE; ep_num = g_UsbACM.txpipe->byEP; } } RestoreIRQMask(savedMask); if(setup_dma == KAL_TRUE) { USB_Dbg_Trace(USB_ACM_DMA_SETUP_3, drv_get_current_time(), ep_num, 0); USB2UART_DMATransmit(ep_num, KAL_FALSE); } } #ifndef __PRODUCTION_RELEASE__ if(ownerid != USB2UARTPort.ownerid) { EXT_ASSERT( 0, (kal_uint32) ownerid, (kal_uint32)USB2UARTPort.ownerid, 0); } #endif if(ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_SEND_ISR_DATA, real_count); // kal_prompt_trace(MOD_USB, "SendISR %d", real_count); } return real_count; }
/* DMA callback function for TX sent out data */ static void USB2UART_Tx_DMA_Callback(void) { kal_uint32 savedMask; kal_uint8 ep_num = 0; kal_bool setup_dma = KAL_FALSE; kal_bool b_force_isr_buffer = KAL_FALSE; if(USB2UARTPort.ownerid != MOD_TST_READER) { drv_trace1(TRACE_FUNC, USBACM_DMA_CALLBACK, USB2Uart_WriteLength); // kal_prompt_trace(MOD_USB, "DMA %d", USB2Uart_WriteLength); } /* tx complete callback*/ USB2UARTPort.tx_cb(uart_port_usb); #if 0 /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ #endif /*update read pointer for previously sent out buffer */ savedMask = SaveAndSetIRQMask(); USB2UART_Update_Transmit_Data(); RestoreIRQMask(savedMask); /* USB2Uart_MemType and USB2Uart_WriteLength are updated, so clear dma running state here*/ g_UsbACM.setup_dma = KAL_FALSE; // USB_DMA_Set_Run_Status(g_UsbACM.txpipe->byEP, KAL_FALSE); if(USB2UARTPort.Tx_Buffer_ISR.Read == USB2UARTPort.Tx_Buffer_ISR.Write) { /* no more data to send */ if(USB2UARTPort.Tx_Buffer.Read == USB2UARTPort.Tx_Buffer.Write) return; } /* must send ISR buffer again */ else if(USB2Uart_MemType == USBTRX_MEM_ISR) { b_force_isr_buffer = KAL_TRUE; } /* send data again in TX buffer or TXISR buffer */ savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section */ if(gUsbDevice.device_type == USB_CDC_ACM) { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) if(g_UsbACM.setup_dma == KAL_FALSE) { g_UsbACM.setup_dma = KAL_TRUE; setup_dma = KAL_TRUE; ep_num = g_UsbACM.txpipe->byEP; } } RestoreIRQMask(savedMask); if(setup_dma == KAL_TRUE) { USB_Dbg_Trace(USB_ACM_DMA_CALLBACK, drv_get_current_time(), ep_num, 0); USB2UART_DMATransmit(ep_num, b_force_isr_buffer); } // savedMask = SaveAndSetIRQMask(); /* in case usb is plugged out just before this critical section*/ // if(gUsbDevice.device_type == USB_CDC_ACM) // { // if(USB_DMA_Get_Run_Status(g_UsbACM.txpipe->byEP) == KAL_FALSE) // { // USB2UART_DMATransmit(g_UsbACM.txpipe->byEP); // } // } // RestoreIRQMask(savedMask); }