usb serial

This commit is contained in:
Todd Fleming 2017-01-09 19:58:14 -05:00
parent 99a520a442
commit 408d820b9f
6 changed files with 70 additions and 22 deletions

View File

@ -29,12 +29,14 @@ INCLUDES = \
-I grbl \ -I grbl \
-I lpc17xx \ -I lpc17xx \
-I smoother \ -I smoother \
-I VCOM_lib \
# Compile all .c and .cpp files in these directories # Compile all .c and .cpp files in these directories
# Hack: .c files are compiled as if they were c++. # Hack: .c files are compiled as if they were c++.
SRC_DIRS = \ SRC_DIRS = \
grbl \ grbl \
smoother \ smoother \
VCOM_lib \
# Compile all .c files in these directories, except ones on the exclude list. # Compile all .c files in these directories, except ones on the exclude list.
# These files get extra -Wno-* flags to reduce spam. # These files get extra -Wno-* flags to reduce spam.

View File

@ -40,9 +40,6 @@
#ifndef _LPCUSB_TYPE_H_ #ifndef _LPCUSB_TYPE_H_
#define _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 char U8; /**< unsigned 8-bit */
typedef unsigned short int U16; /**< unsigned 16-bit */ typedef unsigned short int U16; /**< unsigned 16-bit */
typedef unsigned int U32; /**< unsigned 32-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 // 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 TRUE 1 /**< TRUE */
//#define FALSE 0 /**< FALSE */ #define FALSE 0 /**< FALSE */
//#ifndef NULL //#ifndef NULL
//#define NULL ((void*)0) /**< NULL pointer */ //#define NULL ((void*)0) /**< NULL pointer */

View File

@ -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" #include "usbSerial.h"
@ -78,10 +81,12 @@ static U8 abBulkBuf[64];
static U8 abClassReqData[8]; static U8 abClassReqData[8];
static U8 txdata[VCOM_FIFO_SIZE]; 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 txfifo;
static fifo_t rxfifo; //static fifo_t rxfifo;
static UsbSerialReadCallback* usbSerialReadCallback = nullptr;
// forward declaration of interrupt handler // forward declaration of interrupt handler
void USBIntHandler(void); void USBIntHandler(void);
@ -207,15 +212,20 @@ static const U8 abDescriptors[] = {
*/ */
static void BulkOut(U8 bEP, U8 bEPStatus) static void BulkOut(U8 bEP, U8 bEPStatus)
{ {
int i, iLen; int iLen;
bEPStatus = bEPStatus; bEPStatus = bEPStatus;
/* TBF: replaced rxfifo with callback
if (fifo_free(&rxfifo) < MAX_PACKET_SIZE) { if (fifo_free(&rxfifo) < MAX_PACKET_SIZE) {
// may not fit into fifo // may not fit into fifo
return; return;
} }
*/
// get data from USB into intermediate buffer // get data from USB into intermediate buffer
iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf)); iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf));
if(usbSerialReadCallback)
usbSerialReadCallback(abBulkBuf, iLen);
/* TBF: replaced rxfifo with callback
for (i = 0; i < iLen; i++) { for (i = 0; i < iLen; i++) {
// put into FIFO // put into FIFO
if (!fifo_put(&rxfifo, abBulkBuf[i])) { if (!fifo_put(&rxfifo, abBulkBuf[i])) {
@ -224,6 +234,7 @@ static void BulkOut(U8 bEP, U8 bEPStatus)
break; break;
} }
} }
*/
} }
@ -307,7 +318,7 @@ static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
void VCOM_init(void) void VCOM_init(void)
{ {
fifo_init(&txfifo, txdata); 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 @returns character read, or EOF if character could not be read
*/ */
/* TBF: replaced with callback
int VCOM_getchar(void) int VCOM_getchar(void)
{ {
U8 c; U8 c;
return fifo_get(&rxfifo, &c) ? c : EOF; return fifo_get(&rxfifo, &c) ? c : EOF;
} }
*/
/** /**
Interrupt handler Interrupt handler
@ -342,7 +354,7 @@ int VCOM_getchar(void)
Simply calls the USB ISR Simply calls the USB ISR
*/ */
//void USBIntHandler(void) //void USBIntHandler(void)
void USB_IRQHandler(void) extern "C" void USB_IRQHandler(void)
{ {
USBHwISR(); USBHwISR();
} }
@ -364,8 +376,10 @@ void enable_USB_interrupts(void);
main main
==== ====
**************************************************************************/ **************************************************************************/
int usbSerialInit() int usbSerialInit(UsbSerialReadCallback* usbSerialReadCallback)
{ {
::usbSerialReadCallback = usbSerialReadCallback;
// initialise stack // initialise stack
USBInit(); USBInit();
@ -428,6 +442,7 @@ void VCOM_putc(char c)
{ {
while(VCOM_putchar(c) == EOF); while(VCOM_putchar(c) == EOF);
} }
/* TBF: replaced with callback
char VCOM_getc() char VCOM_getc()
{ {
int c; int c;
@ -438,6 +453,7 @@ char VCOM_getc()
} }
return (char)c; return (char)c;
} }
*/
void VCOM_putHex(uint8_t hex) void VCOM_putHex(uint8_t hex)
{ {
uint8_t temp; uint8_t temp;
@ -454,6 +470,7 @@ void VCOM_putHex(uint8_t hex)
VCOM_putc((char)temp); VCOM_putc((char)temp);
} }
/* TBF: replaced with callback
void VCOM_gets(char* str) void VCOM_gets(char* str)
{ {
char c; char c;
@ -483,7 +500,7 @@ void VCOM_gets_echo(char *str)
} }
*str = '\0'; *str = '\0';
} }
*/
/* Original code by ELM_ChaN. Modified by Martin Thomas */ /* Original code by ELM_ChaN. Modified by Martin Thomas */
int xatoi (char **str, long *res) int xatoi (char **str, long *res)
{ {

View File

@ -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__ #ifndef __USB_SERIAL_H__
#define __USB_SERIAL_H__ #define __USB_SERIAL_H__
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { //extern "C" {
#endif #endif
#include <stdarg.h> #include <stdarg.h>
@ -94,8 +98,10 @@ extern "C" {
#include "serial_fifo.h" #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 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 @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_puts(const char* str); //writes a null terminated string.
void VCOM_putc(char c); // writes a character. void VCOM_putc(char c); // writes a character.
void VCOM_putHex(uint8_t hex); // writes 0x.. hex value on the terminal. void VCOM_putHex(uint8_t hex); // writes 0x.. hex value on the terminal.
char VCOM_getc(); // returns character entered in the terminal. blocking function //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. //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. //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_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 void VCOM_printf(const char* str, ...); // Original code by Elm_CHaN. Modified by Martin Thomas
#ifdef __cplusplus #ifdef __cplusplus
} //}
#endif #endif
#endif #endif

View File

@ -118,6 +118,7 @@ static void StallControlPipe(U8 bEPStat)
// dump setup packet // dump setup packet
DBG("STALL on ["); DBG("STALL on [");
pb = (U8 *)&Setup; pb = (U8 *)&Setup;
pb = pb;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
DBG(" %02x", *pb++); DBG(" %02x", *pb++);
} }

View File

@ -20,7 +20,14 @@
*/ */
#include "grbl.h" #include "grbl.h"
#define USE_USB
#ifdef USE_USB
#include "usbSerial.h"
#else
#include "Driver_USART.h" #include "Driver_USART.h"
#endif
#define RX_RING_BUFFER (RX_BUFFER_SIZE+1) #define RX_RING_BUFFER (RX_BUFFER_SIZE+1)
#define TX_RING_BUFFER (TX_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; uint8_t serial_tx_buffer_head = 0;
volatile uint8_t serial_tx_buffer_tail = 0; volatile uint8_t serial_tx_buffer_tail = 0;
#ifndef USE_USB
extern ARM_DRIVER_USART Driver_USART0; extern ARM_DRIVER_USART Driver_USART0;
#define serialDriver Driver_USART0 #define serialDriver Driver_USART0
#endif
void serialInterrupt(uint32_t event); void serialInterrupt(uint32_t event);
void legacy_ISR(uint8_t data); void legacy_ISR(uint8_t data);
@ -70,6 +79,12 @@ uint8_t serial_get_tx_buffer_count()
void serial_init() 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 | int32_t uartFlags = ARM_USART_MODE_ASYNCHRONOUS |
ARM_USART_DATA_BITS_8 | ARM_USART_DATA_BITS_8 |
ARM_USART_PARITY_NONE | ARM_USART_PARITY_NONE |
@ -84,6 +99,7 @@ void serial_init()
//Issue first read //Issue first read
serialDriver.Receive(arm_rx_buf, 1); serialDriver.Receive(arm_rx_buf, 1);
#endif
} }
void legacy_serial_init() void legacy_serial_init()
@ -107,6 +123,12 @@ void legacy_serial_init()
// Writes one byte to the TX serial buffer. Called by main program. // Writes one byte to the TX serial buffer. Called by main program.
void serial_write(uint8_t data) { 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 //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 //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. //the transmit and is ready for more bytes.
@ -120,6 +142,7 @@ void serial_write(uint8_t data) {
// the original GRBL TX Interrupt. // the original GRBL TX Interrupt.
serial_tx_buffer[0] = data; serial_tx_buffer[0] = data;
serialDriver.Send(serial_tx_buffer, 1); serialDriver.Send(serial_tx_buffer, 1);
#endif
} }
// Writes one byte to the TX serial buffer. Called by main program. // 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 //Device driver interrupt
// The CMSIS Driver doesn't have seperate interrupts/callbacks available for TX and RX but instead // The CMSIS Driver doesn't have seperate interrupts/callbacks available for TX and RX but instead
// is a single composite interrupt. // is a single composite interrupt.
#ifndef USE_USB
void serialInterrupt(uint32_t event) { void serialInterrupt(uint32_t event) {
if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) { if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) {
//We got our single byte read, so put the data into our fifo and issue another read //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); serialDriver.Receive(arm_rx_buf, 1);
} }
} }
#endif
//We don't use TX interrupts directly with the ARM Driver. //We don't use TX interrupts directly with the ARM Driver.
// Data Register Empty Interrupt handler // Data Register Empty Interrupt handler