From 408d820b9fbfef17503b18d418ee45114d0fe881 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 9 Jan 2017 19:58:14 -0500 Subject: [PATCH] usb serial --- Makefile | 2 ++ VCOM_lib/lpcusb_type.h | 9 +++------ VCOM_lib/usbSerial.c | 33 +++++++++++++++++++++++++-------- VCOM_lib/usbSerial.h | 22 ++++++++++++++-------- VCOM_lib/usbcontrol.c | 1 + grbl/serial.c | 25 +++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 0a7dbd4..fdebc9e 100644 --- a/Makefile +++ b/Makefile @@ -29,12 +29,14 @@ INCLUDES = \ -I grbl \ -I lpc17xx \ -I smoother \ + -I VCOM_lib \ # Compile all .c and .cpp files in these directories # Hack: .c files are compiled as if they were c++. SRC_DIRS = \ grbl \ smoother \ + VCOM_lib \ # Compile all .c files in these directories, except ones on the exclude list. # These files get extra -Wno-* flags to reduce spam. diff --git a/VCOM_lib/lpcusb_type.h b/VCOM_lib/lpcusb_type.h index 1c76543..494c332 100644 --- a/VCOM_lib/lpcusb_type.h +++ b/VCOM_lib/lpcusb_type.h @@ -40,9 +40,6 @@ #ifndef _LPCUSB_TYPE_H_ #define _LPCUSB_TYPE_H_ -// CodeRed - include NXP-produced type.h file -#include "type.h" - typedef unsigned char U8; /**< unsigned 8-bit */ typedef unsigned short int U16; /**< unsigned 16-bit */ typedef unsigned int U32; /**< unsigned 32-bit */ @@ -50,10 +47,10 @@ typedef unsigned int U32; /**< unsigned 32-bit */ // CodeRed - comment out defines duplicated in NXP type.h -//typedef int BOOL; /**< #TRUE or #FALSE */ +typedef int BOOL; /**< #TRUE or #FALSE */ -//#define TRUE 1 /**< TRUE */ -//#define FALSE 0 /**< FALSE */ +#define TRUE 1 /**< TRUE */ +#define FALSE 0 /**< FALSE */ //#ifndef NULL //#define NULL ((void*)0) /**< NULL pointer */ diff --git a/VCOM_lib/usbSerial.c b/VCOM_lib/usbSerial.c index fc3e31b..ceed39e 100644 --- a/VCOM_lib/usbSerial.c +++ b/VCOM_lib/usbSerial.c @@ -60,6 +60,9 @@ void VCOM_gets_echo(char *str); // gets string terminated in '\r' or '\n' and ec */ +/* Modified by Todd Fleming (TBF), 2017 + Replaced read polling API with callback API +*/ #include "usbSerial.h" @@ -78,10 +81,12 @@ static U8 abBulkBuf[64]; static U8 abClassReqData[8]; static U8 txdata[VCOM_FIFO_SIZE]; -static U8 rxdata[VCOM_FIFO_SIZE]; +//static U8 rxdata[VCOM_FIFO_SIZE]; static fifo_t txfifo; -static fifo_t rxfifo; +//static fifo_t rxfifo; + +static UsbSerialReadCallback* usbSerialReadCallback = nullptr; // forward declaration of interrupt handler void USBIntHandler(void); @@ -207,15 +212,20 @@ static const U8 abDescriptors[] = { */ static void BulkOut(U8 bEP, U8 bEPStatus) { - int i, iLen; + int iLen; bEPStatus = bEPStatus; + /* TBF: replaced rxfifo with callback if (fifo_free(&rxfifo) < MAX_PACKET_SIZE) { // may not fit into fifo return; } + */ // get data from USB into intermediate buffer iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf)); + if(usbSerialReadCallback) + usbSerialReadCallback(abBulkBuf, iLen); + /* TBF: replaced rxfifo with callback for (i = 0; i < iLen; i++) { // put into FIFO if (!fifo_put(&rxfifo, abBulkBuf[i])) { @@ -224,6 +234,7 @@ static void BulkOut(U8 bEP, U8 bEPStatus) break; } } + */ } @@ -307,7 +318,7 @@ static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData) void VCOM_init(void) { fifo_init(&txfifo, txdata); - fifo_init(&rxfifo, rxdata); + //fifo_init(&rxfifo, rxdata); } @@ -328,13 +339,14 @@ int VCOM_putchar(int c) @returns character read, or EOF if character could not be read */ +/* TBF: replaced with callback int VCOM_getchar(void) { U8 c; return fifo_get(&rxfifo, &c) ? c : EOF; } - +*/ /** Interrupt handler @@ -342,7 +354,7 @@ int VCOM_getchar(void) Simply calls the USB ISR */ //void USBIntHandler(void) -void USB_IRQHandler(void) +extern "C" void USB_IRQHandler(void) { USBHwISR(); } @@ -364,8 +376,10 @@ void enable_USB_interrupts(void); main ==== **************************************************************************/ -int usbSerialInit() +int usbSerialInit(UsbSerialReadCallback* usbSerialReadCallback) { + ::usbSerialReadCallback = usbSerialReadCallback; + // initialise stack USBInit(); @@ -428,6 +442,7 @@ void VCOM_putc(char c) { while(VCOM_putchar(c) == EOF); } +/* TBF: replaced with callback char VCOM_getc() { int c; @@ -438,6 +453,7 @@ char VCOM_getc() } return (char)c; } +*/ void VCOM_putHex(uint8_t hex) { uint8_t temp; @@ -454,6 +470,7 @@ void VCOM_putHex(uint8_t hex) VCOM_putc((char)temp); } +/* TBF: replaced with callback void VCOM_gets(char* str) { char c; @@ -483,7 +500,7 @@ void VCOM_gets_echo(char *str) } *str = '\0'; } - +*/ /* Original code by ELM_ChaN. Modified by Martin Thomas */ int xatoi (char **str, long *res) { diff --git a/VCOM_lib/usbSerial.h b/VCOM_lib/usbSerial.h index 568cd1b..e05db60 100644 --- a/VCOM_lib/usbSerial.h +++ b/VCOM_lib/usbSerial.h @@ -60,11 +60,15 @@ void VCOM_gets_echo(char *str); // gets string terminated in '\r' or '\n' and ec */ +/* Modified by Todd Fleming (TBF), 2017 + Replaced read polling API with callback API +*/ + #ifndef __USB_SERIAL_H__ #define __USB_SERIAL_H__ #ifdef __cplusplus -extern "C" { +//extern "C" { #endif #include @@ -94,8 +98,10 @@ extern "C" { #include "serial_fifo.h" -int usbSerialInit(); // run once in main b4 main loop starts. +// Receives serial data. Called by an interrupt. +typedef void UsbSerialReadCallback(const U8* data, unsigned len); +int usbSerialInit(UsbSerialReadCallback* usbSerialReadCallback); // run once in main b4 main loop starts. /* Writes one character to VCOM port @@ -110,20 +116,20 @@ int VCOM_putchar(int c); @returns character read, or EOF if character could not be read */ -int VCOM_getchar(void); +//int VCOM_getchar(void); void VCOM_puts(const char* str); //writes a null terminated string. void VCOM_putc(char c); // writes a character. void VCOM_putHex(uint8_t hex); // writes 0x.. hex value on the terminal. -char VCOM_getc(); // returns character entered in the terminal. blocking function -void VCOM_gets(char* str); // returns a string. '\r' or '\n' will terminate character collection. -char VCOM_getc_echo(); // returns character entered and echoes the same back. -void VCOM_gets_echo(char *str); // gets string terminated in '\r' or '\n' and echoes back the same. +//char VCOM_getc(); // returns character entered in the terminal. blocking function +//void VCOM_gets(char* str); // returns a string. '\r' or '\n' will terminate character collection. +//char VCOM_getc_echo(); // returns character entered and echoes the same back. +//void VCOM_gets_echo(char *str); // gets string terminated in '\r' or '\n' and echoes back the same. void VCOM_printf(const char* str, ...); // Original code by Elm_CHaN. Modified by Martin Thomas #ifdef __cplusplus -} +//} #endif #endif \ No newline at end of file diff --git a/VCOM_lib/usbcontrol.c b/VCOM_lib/usbcontrol.c index df96714..f4d671c 100644 --- a/VCOM_lib/usbcontrol.c +++ b/VCOM_lib/usbcontrol.c @@ -118,6 +118,7 @@ static void StallControlPipe(U8 bEPStat) // dump setup packet DBG("STALL on ["); pb = (U8 *)&Setup; + pb = pb; for (i = 0; i < 8; i++) { DBG(" %02x", *pb++); } diff --git a/grbl/serial.c b/grbl/serial.c index 0dc9228..420db7d 100644 --- a/grbl/serial.c +++ b/grbl/serial.c @@ -20,7 +20,14 @@ */ #include "grbl.h" + +#define USE_USB + +#ifdef USE_USB +#include "usbSerial.h" +#else #include "Driver_USART.h" +#endif #define RX_RING_BUFFER (RX_BUFFER_SIZE+1) #define TX_RING_BUFFER (TX_BUFFER_SIZE+1) @@ -33,8 +40,10 @@ uint8_t serial_tx_buffer[TX_RING_BUFFER]; uint8_t serial_tx_buffer_head = 0; volatile uint8_t serial_tx_buffer_tail = 0; +#ifndef USE_USB extern ARM_DRIVER_USART Driver_USART0; #define serialDriver Driver_USART0 +#endif void serialInterrupt(uint32_t event); void legacy_ISR(uint8_t data); @@ -70,6 +79,12 @@ uint8_t serial_get_tx_buffer_count() void serial_init() { +#ifdef USE_USB + usbSerialInit([](const U8* data, unsigned len) { + while(len--) + legacy_ISR(*data++); + }); +#else int32_t uartFlags = ARM_USART_MODE_ASYNCHRONOUS | ARM_USART_DATA_BITS_8 | ARM_USART_PARITY_NONE | @@ -84,6 +99,7 @@ void serial_init() //Issue first read serialDriver.Receive(arm_rx_buf, 1); +#endif } void legacy_serial_init() @@ -107,6 +123,12 @@ void legacy_serial_init() // Writes one byte to the TX serial buffer. Called by main program. void serial_write(uint8_t data) { +#ifdef USE_USB + while(VCOM_putchar(data) == EOF) { + // TODO: Restructure st_prep_buffer() calls to be executed here during a long print. + if (sys_rt_exec_state & EXEC_RESET) { return; } // Only check for abort to avoid an endless loop. + } +#else //We're just really cheating here. We dont need the grbl fifo because the driver already //provides one. But we have to have a place to keep the data safe until the driver has completed //the transmit and is ready for more bytes. @@ -120,6 +142,7 @@ void serial_write(uint8_t data) { // the original GRBL TX Interrupt. serial_tx_buffer[0] = data; serialDriver.Send(serial_tx_buffer, 1); +#endif } // Writes one byte to the TX serial buffer. Called by main program. @@ -145,6 +168,7 @@ void legacy_serial_write(uint8_t data) { //Device driver interrupt // The CMSIS Driver doesn't have seperate interrupts/callbacks available for TX and RX but instead // is a single composite interrupt. +#ifndef USE_USB void serialInterrupt(uint32_t event) { if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) { //We got our single byte read, so put the data into our fifo and issue another read @@ -152,6 +176,7 @@ void serialInterrupt(uint32_t event) { serialDriver.Receive(arm_rx_buf, 1); } } +#endif //We don't use TX interrupts directly with the ARM Driver. // Data Register Empty Interrupt handler