diff --git a/sw/airborne/arm7/usb_msc_hw.c b/sw/airborne/arm7/usb_msc_hw.c index df0e1fc095..4c54c2ce29 100755 --- a/sw/airborne/arm7/usb_msc_hw.c +++ b/sw/airborne/arm7/usb_msc_hw.c @@ -61,6 +61,7 @@ #include #include "std.h" #include "LPC21xx.h" +#include "armVIC.h" #include CONFIG #include "lpcusb/usbapi.h" diff --git a/sw/airborne/arm7/usb_ser_hw.c b/sw/airborne/arm7/usb_ser_hw.c index fd4a7e3cea..41f61816e7 100644 --- a/sw/airborne/arm7/usb_ser_hw.c +++ b/sw/airborne/arm7/usb_ser_hw.c @@ -77,7 +77,7 @@ #define GET_LINE_CODING 0x21 #define SET_CONTROL_LINE_STATE 0x22 -#define VCOM_FIFO_SIZE 128 +#define VCOM_FIFO_SIZE 8192 #define EOF (-1) #define ASSERT(x) @@ -96,6 +96,8 @@ typedef struct { uint8_t bDataBits; } TLineCoding; +int allow_line_coding = 0; + /* this settings are virtual unless you enable line coding */ static TLineCoding LineCoding = {115200, 0, 0, 8}; static uint8_t abBulkBuf[64]; static uint8_t abClassReqData[8]; @@ -113,6 +115,11 @@ static void USBIntHandler(void) __attribute__ ((interrupt("IRQ"))); static void BulkOut(U8 bEP, U8 bEPStatus); +#ifdef USE_USB_LINE_CODING +void set_linecoding(TLineCoding linecoding); +void VCOM_allow_linecoding(uint8_t mode); +#endif + void fifo_init(fifo_t *fifo, U8 *buf); BOOL fifo_put(fifo_t *fifo, U8 c); BOOL fifo_get(fifo_t *fifo, U8 *pc); @@ -285,6 +292,80 @@ int fifo_free(fifo_t *fifo) return (VCOM_FIFO_SIZE - 1 - fifo_avail(fifo)); } +#ifdef USE_USB_LINE_CODING +void set_linecoding(TLineCoding linecoding) +{ + uint16_t baud; + uint8_t mode; + + // set the baudrate + baud = (uint16_t)((PCLK / ((linecoding.dwDTERate) * 16.0)) + 0.5); + + // set the number of characters and other + // user specified operating parameters + switch (linecoding.bCharFormat) + { + case 0: /* 1 stop bit */ + mode = ULCR_STOP_1; + break; + case 1: /* 1.5 stop bit (only with 5 bit character) */ + case 2: /* 2 stop bit */ + mode = ULCR_STOP_2; + break; + default: + mode = ULCR_STOP_1; + break; + } + switch (linecoding.bParityType) + { + case 0: mode += ULCR_PAR_NO; + break; + case 1: mode += ULCR_PAR_ODD; + break; + case 2: mode += ULCR_PAR_EVEN; + break; + case 3: mode += ULCR_PAR_MARK; + break; + case 4: mode += ULCR_PAR_SPACE; + break; + default: mode += ULCR_PAR_NO; + break; + } + switch (linecoding.bDataBits) + { + case 5: mode += ULCR_CHAR_5; + break; + case 6: mode += ULCR_CHAR_6; + break; + case 7: mode += ULCR_CHAR_7; + break; + case 8: mode += ULCR_CHAR_8; + break; + case 16: + default: mode += ULCR_CHAR_8; + break; + } + +#ifdef USE_UART0 + U0LCR = ULCR_DLAB_ENABLE; // select divisor latches + U0DLL = (uint8_t)baud; // set for baud low byte + U0DLM = (uint8_t)(baud >> 8); // set for baud high byte + U0LCR = (mode & ~ULCR_DLAB_ENABLE); +#endif +#ifdef USE_UART1 + U1LCR = ULCR_DLAB_ENABLE; // select divisor latches + U1DLL = (uint8_t)baud; // set for baud low byte + U1DLM = (uint8_t)(baud >> 8); // set for baud high byte + U1LCR = (mode & ~ULCR_DLAB_ENABLE); +#endif +} +#endif + +void VCOM_allow_linecoding(uint8_t mode) +{ + allow_line_coding = mode; +} + /** Writes one character to VCOM port @@ -310,8 +391,8 @@ int VCOM_getchar(void) result = fifo_get(&rxfifo, &c) ? c : EOF; if (BulkOut_is_blocked && fifo_free(&rxfifo) >= MAX_PACKET_SIZE) { - // get more data from usb bus disableIRQ(); + // get more data from usb bus BulkOut(BULK_OUT_EP, 0); BulkOut_is_blocked = false; enableIRQ(); @@ -417,6 +498,12 @@ static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData) case SET_LINE_CODING: memcpy((U8 *)&LineCoding, *ppbData, 7); *piLen = 7; +#ifdef USE_USB_LINE_CODING + if (allow_line_coding) + { + set_linecoding(LineCoding); + } +#endif break; // get line coding @@ -427,7 +514,7 @@ static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData) // set control line state case SET_CONTROL_LINE_STATE: - // bit0 = DTR, bit = RTS + // bit0 = DTR, bit1 = RTS break; default: @@ -461,6 +548,10 @@ static void USBFrameHandler(U16 wFrame) void VCOM_init(void) { // initialise stack USBInit(); +#ifdef USE_USB_LINE_CODING + // set default line coding + set_linecoding(LineCoding); +#endif // register descriptors USBRegisterDescriptors(abDescriptors); diff --git a/sw/airborne/arm7/usb_tunnel.c b/sw/airborne/arm7/usb_tunnel.c new file mode 100644 index 0000000000..6445e29a05 --- /dev/null +++ b/sw/airborne/arm7/usb_tunnel.c @@ -0,0 +1,59 @@ + +#include "std.h" +#include "init_hw.h" +#include "sys_time.h" +#include "led.h" +#include "interrupt_hw.h" +#include "uart_hw.h" +#include "uart.h" +#include "usb_serial.h" + +int main( void ) { + unsigned char inc; + + hw_init(); + sys_time_init(); + led_init(); + +#ifdef USE_UART0 + Uart0Init(); +#else +#ifdef USE_UART1 + Uart1Init(); +#else +#error no serial port defined +#endif +#endif + +#ifdef USE_USB_SERIAL + VCOM_init(); +#endif + + int_enable(); + +#ifdef USE_UART0 + while(1) { + if (Uart0ChAvailable() && VCOM_check_free_space(1)) { + inc = Uart0Getch(); + VCOM_putchar(inc); + } + if (VCOM_check_available() && uart0_check_free_space(1)) { + inc = VCOM_getchar(); + uart0_transmit(inc); + } + } +#else + while(1) { + if (Uart1ChAvailable() && VCOM_check_free_space(1)) { + inc = Uart1Getch(); + VCOM_putchar(inc); + } + if (VCOM_check_available() && uart1_check_free_space(1)) { + inc = VCOM_getchar(); + uart1_transmit(inc); + } + } +#endif + + return 0; +} diff --git a/sw/airborne/usb_serial.h b/sw/airborne/usb_serial.h index e1f79fa460..ff22a067c2 100644 --- a/sw/airborne/usb_serial.h +++ b/sw/airborne/usb_serial.h @@ -39,6 +39,7 @@ int VCOM_putchar(int c); int VCOM_getchar(void); bool_t VCOM_check_free_space(uint8_t len); int VCOM_check_available(void); +void VCOM_set_linecoding(uint8_t mode); #define UsbSInit() VCOM_init() #define UsbSCheckFreeSpace(_x) VCOM_check_free_space(_x)