First mostly working - but untested - firmware include a working command parser baudrate modification functionality and also a untested bidirectional redirect ability for the second virtual serial device.
This commit is contained in:
parent
5a0e74de7a
commit
945a9c81c2
8 changed files with 381 additions and 22 deletions
|
@ -17,8 +17,8 @@ ARCH = AVR8
|
|||
F_CPU = 16000000
|
||||
F_USB = $(F_CPU)
|
||||
OPTIMIZATION = s
|
||||
TARGET = USB2SerialMux
|
||||
SRC = $(TARGET).c Descriptors.c uart/uart.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
||||
TARGET = main
|
||||
SRC = $(TARGET).c Descriptors.c uart/uart.c command_ctrl.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
||||
LUFA_PATH = ../LUFA/LUFA
|
||||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -Iuart/
|
||||
LD_FLAGS =
|
76
src/command_config.h
Executable file
76
src/command_config.h
Executable file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Author: klaute -Kai Lauterbach - @kailauterbach - me@klaute.de
|
||||
* Date: 08/2016
|
||||
* License: GPLv3
|
||||
*/
|
||||
|
||||
#ifndef __COMMAND_CONFIG_H__
|
||||
#define __COMMAND_CONFIG_H__
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/eeprom.h>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#include "uart/uart.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
void cc_setBaudrate(void);
|
||||
void cc_getBaudrate(void);
|
||||
void cc_startBootloader(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define CC_CMD_SET_BAUDRATE 0x0A
|
||||
#define CC_CMD_GET_BAUDRATE 0x14
|
||||
#define CC_CMD_START_BTLDR 0x32
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define CC_CMD_SET_BAUDRATE_FUNC &cc_setBaudrate
|
||||
#define CC_CMD_GET_BAUDRATE_FUNC &cc_getBaudrate
|
||||
#define CC_CMD_START_BTLDR_FUNC &cc_startBootloader
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define CC_CMD_SET_BAUDRATE_DATA_TO_READ 4 // set baudrate
|
||||
#define CC_CMD_GET_BAUDRATE_DATA_TO_READ 0 // get baudrate
|
||||
#define CC_CMD_START_BTLDR_DATA_TO_READ 0 // start bootloader
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define CC_READ_DATA_MAX 64
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
uint8_t cc_commands[] = {
|
||||
CC_CMD_SET_BAUDRATE,
|
||||
CC_CMD_GET_BAUDRATE,
|
||||
CC_CMD_START_BTLDR,
|
||||
};
|
||||
|
||||
void (*cc_cmd_functions[])() = {
|
||||
CC_CMD_SET_BAUDRATE_FUNC,
|
||||
CC_CMD_GET_BAUDRATE_FUNC,
|
||||
CC_CMD_START_BTLDR_FUNC,
|
||||
};
|
||||
|
||||
uint8_t cc_cmd_data_to_read[] = {
|
||||
CC_CMD_SET_BAUDRATE_DATA_TO_READ,
|
||||
CC_CMD_GET_BAUDRATE_DATA_TO_READ,
|
||||
CC_CMD_START_BTLDR_DATA_TO_READ,
|
||||
};
|
||||
|
||||
uint8_t cc_read_data[CC_READ_DATA_MAX];
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
146
src/command_ctrl.c
Executable file
146
src/command_ctrl.c
Executable file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Author: klaute -Kai Lauterbach - @kailauterbach - me@klaute.de
|
||||
* Date: 08/2016
|
||||
* License: GPLv3
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "command_ctrl.h"
|
||||
|
||||
#include "command_config.h"
|
||||
|
||||
// include user specific command control configuration and function definition
|
||||
#include "command_config.h"
|
||||
#include "command_functions.c"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
uint8_t cc_state = CC_STATE_READ_SOM1;
|
||||
|
||||
uint8_t cc_cmd_to_call = CC_CMD_NO_CMD;
|
||||
|
||||
uint8_t cc_cmd_received_correct = MSG_INCOMPLETE;
|
||||
|
||||
uint8_t cc_cmd_data_read_cnt = 0;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void cc_init()
|
||||
{
|
||||
cc_state = CC_STATE_READ_SOM1;
|
||||
cc_cmd_to_call = CC_CMD_NO_CMD;
|
||||
cc_cmd_data_read_cnt = 0;
|
||||
cc_cmd_received_correct = MSG_INCOMPLETE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void cc_abort()
|
||||
{
|
||||
// send abort message, then init
|
||||
char* tmp = " ";
|
||||
sprintf(tmp, "%c%c%c%c%c", MSG_SOM1, MSG_SOM2,
|
||||
MSG_TYPE_ANSWER_NOK,
|
||||
MSG_EOM1, MSG_EOM2);
|
||||
USB_serialStreamWriteC(tmp, strlen(tmp));
|
||||
cc_init();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void cc_processData(uint8_t c)
|
||||
{
|
||||
switch (cc_state)
|
||||
{
|
||||
//*********************************//
|
||||
case CC_STATE_READ_SOM1:;
|
||||
if (c == MSG_SOM1)
|
||||
cc_state = CC_STATE_READ_SOM2;
|
||||
else
|
||||
cc_abort();
|
||||
break;
|
||||
|
||||
//*********************************//
|
||||
case CC_STATE_READ_SOM2:;
|
||||
if (c == MSG_SOM2)
|
||||
cc_state = CC_STATE_READ_CMD;
|
||||
else
|
||||
cc_abort();
|
||||
break;
|
||||
|
||||
//*********************************//
|
||||
case CC_STATE_READ_CMD:;
|
||||
for (uint8_t i = 0; i < sizeof(cc_commands)/sizeof(uint8_t); i++)
|
||||
{
|
||||
if (cc_commands[i] == c)
|
||||
{
|
||||
if (cc_cmd_data_to_read[i] > 0)
|
||||
cc_state = CC_STATE_READ_DATA;
|
||||
else
|
||||
cc_state = CC_STATE_READ_EOM1;
|
||||
|
||||
cc_cmd_to_call = i; // remember the index of command to call
|
||||
|
||||
break; // break the loop
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//*********************************//
|
||||
case CC_STATE_READ_DATA:;
|
||||
// write the variable c to the input buffer
|
||||
cc_read_data[cc_cmd_data_read_cnt] = c;
|
||||
|
||||
if (cc_cmd_data_read_cnt >= cc_cmd_data_to_read[cc_cmd_to_call]-1)
|
||||
{
|
||||
cc_state = CC_STATE_READ_EOM1;
|
||||
}
|
||||
|
||||
cc_cmd_data_read_cnt++;
|
||||
|
||||
break;
|
||||
|
||||
//*********************************//
|
||||
case CC_STATE_READ_EOM1:;
|
||||
if (c == MSG_EOM1)
|
||||
cc_state = CC_STATE_READ_EOM2;
|
||||
else
|
||||
cc_abort();
|
||||
break;
|
||||
|
||||
//*********************************//
|
||||
case CC_STATE_READ_EOM2:;
|
||||
if (c == MSG_EOM2)
|
||||
{
|
||||
cc_cmd_received_correct = MSG_COMPLETE;
|
||||
} else
|
||||
cc_abort();
|
||||
break;
|
||||
|
||||
default:
|
||||
cc_abort();
|
||||
}
|
||||
|
||||
//*********************************//
|
||||
if (cc_cmd_received_correct == MSG_COMPLETE)
|
||||
{
|
||||
// call the function using the received data
|
||||
(*cc_cmd_functions[cc_cmd_to_call])();
|
||||
// clear the read buffer
|
||||
cc_clearReadDataBuffer();
|
||||
cc_init();
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void cc_clearReadDataBuffer()
|
||||
{
|
||||
for (uint8_t i = 0; i < CC_READ_DATA_MAX; i++)
|
||||
{
|
||||
cc_read_data[i] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
39
src/command_ctrl.h
Executable file
39
src/command_ctrl.h
Executable file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Author: klaute -Kai Lauterbach - @kailauterbach - me@klaute.de
|
||||
* Date: 08/2016
|
||||
* License: GPLv3
|
||||
*/
|
||||
|
||||
#ifndef __COMMAND_CTRL_H__
|
||||
#define __COMMAND_CTRL_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define CC_STATE_READ_SOM1 20
|
||||
#define CC_STATE_READ_SOM2 30
|
||||
#define CC_STATE_READ_CMD 40
|
||||
#define CC_STATE_READ_DATA 50
|
||||
#define CC_STATE_READ_EOM1 60
|
||||
#define CC_STATE_READ_EOM2 70
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define CC_CMD_NO_CMD 0
|
||||
|
||||
#define MSG_INCOMPLETE 10
|
||||
#define MSG_COMPLETE 20
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
extern void USB_serialStreamWriteC(char*, uint16_t);
|
||||
|
||||
void cc_init(void);
|
||||
void cc_abort(void);
|
||||
void cc_processData(uint8_t);
|
||||
void cc_clearReadDataBuffer(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
62
src/command_functions.c
Executable file
62
src/command_functions.c
Executable file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Author: klaute -Kai Lauterbach - @kailauterbach - me@klaute.de
|
||||
* Date: 08/2016
|
||||
* License: GPLv3
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
extern void USB_serialStreamWriteC(char*, uint16_t);
|
||||
|
||||
extern uint32_t eep_baudrate;
|
||||
extern uint32_t baudrate;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void cc_setBaudrate()
|
||||
{
|
||||
baudrate = (uint32_t)cc_read_data[0] << 24;
|
||||
baudrate += (uint32_t)cc_read_data[1] << 16;
|
||||
baudrate += (uint32_t)cc_read_data[2] << 8;
|
||||
baudrate += (uint32_t)cc_read_data[3];
|
||||
|
||||
eeprom_busy_wait();
|
||||
|
||||
eeprom_write_dword(&eep_baudrate, baudrate);
|
||||
|
||||
eeprom_busy_wait();
|
||||
|
||||
uart_init( UART_BAUD_SELECT(baudrate, F_CPU) );
|
||||
|
||||
char* sBody = " ";
|
||||
sprintf(sBody, "%c%c%c%c%c", MSG_SOM1, MSG_SOM2, MSG_TYPE_ANSWER_OK, MSG_EOM1, MSG_EOM2);
|
||||
USB_serialStreamWriteC(sBody, strlen(sBody));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void cc_getBaudrate()
|
||||
{
|
||||
char* sBody = " ";
|
||||
sprintf(sBody, "%c%c%c%c%c%c%c%c%c", MSG_SOM1, MSG_SOM2, MSG_TYPE_BAUDRATE,
|
||||
(uint8_t)((baudrate & 0xff000000) >> 24),
|
||||
(uint8_t)((baudrate & 0xff0000) >> 16),
|
||||
(uint8_t)((baudrate & 0xff00) >> 8),
|
||||
(uint8_t) (baudrate & 0xff),
|
||||
MSG_EOM1, MSG_EOM2);
|
||||
USB_serialStreamWriteC(sBody, strlen(sBody));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void cc_startBootloader()
|
||||
{
|
||||
// enable the watchdog without a time interval to use
|
||||
wdt_enable(0);
|
||||
|
||||
// trigger watchdog
|
||||
while(1) {};
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
15
src/globals.h
Executable file
15
src/globals.h
Executable file
|
@ -0,0 +1,15 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Message byte definitions: */
|
||||
#define MSG_SOM1 0x3c
|
||||
#define MSG_SOM2 0x3e
|
||||
#define MSG_EOM1 0x0d
|
||||
#define MSG_EOM2 0x0a
|
||||
|
||||
#define MSG_TYPE_ANSWER_OK 0x01
|
||||
#define MSG_TYPE_ANSWER_NOK 0x02
|
||||
#define MSG_TYPE_BAUDRATE 0x03
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -34,7 +34,15 @@
|
|||
* is responsible for the initial application hardware configuration.
|
||||
*/
|
||||
|
||||
#include "USB2SerialMux.h"
|
||||
#include "main.h"
|
||||
|
||||
/**************************************************************************************/
|
||||
|
||||
uint32_t EEMEM eep_baudrate;
|
||||
|
||||
uint32_t baudrate = 115200; // replacement for the UART_BAUDRATE definition
|
||||
|
||||
/**************************************************************************************/
|
||||
|
||||
/** Contains the current baud rate and other settings of the first virtual serial port. While this demo does not use
|
||||
* the physical USART and thus does not use these settings, they must still be retained and returned to the host
|
||||
|
@ -70,8 +78,18 @@ int main(void)
|
|||
{
|
||||
SetupHardware();
|
||||
|
||||
eeprom_busy_wait();
|
||||
baudrate = eeprom_read_dword(&eep_baudrate);
|
||||
|
||||
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
|
||||
if (baudrate == 0xffffffff)
|
||||
{
|
||||
eeprom_busy_wait();
|
||||
baudrate = 115200;
|
||||
eeprom_write_dword(&eep_baudrate, baudrate);
|
||||
}
|
||||
|
||||
// initialize the command interpreter
|
||||
cc_init();
|
||||
|
||||
SET_ERR_MASK(ERRMASK_USB_NOTREADY);
|
||||
GlobalInterruptEnable();
|
||||
|
@ -109,7 +127,7 @@ void SetupHardware(void)
|
|||
#endif
|
||||
|
||||
/* UART Hardware Initialization */
|
||||
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
|
||||
uart_init( UART_BAUD_SELECT(baudrate, F_CPU) );
|
||||
|
||||
/* USB Hardware Initialization */
|
||||
USB_Init();
|
||||
|
@ -208,9 +226,6 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
*/
|
||||
void CDC1_Task(void)
|
||||
{
|
||||
char* ReportString = NULL;
|
||||
static bool ActionSent = false;
|
||||
|
||||
/* Device must be connected and configured for the task to run */
|
||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return;
|
||||
|
@ -221,9 +236,6 @@ void CDC1_Task(void)
|
|||
|
||||
if (Endpoint_IsOUTReceived())
|
||||
{
|
||||
// TODO disable this line if data should be received
|
||||
Endpoint_ClearOUT(); // Throw away any received data from the host at this point
|
||||
|
||||
/* Create a temp buffer big enough to hold the incoming endpoint packet */
|
||||
uint8_t Buffer[Endpoint_BytesInEndpoint()];
|
||||
|
||||
|
@ -236,30 +248,32 @@ void CDC1_Task(void)
|
|||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
// TODO Read the data from the host
|
||||
// process the received data and descide to do an action
|
||||
// uint8_t cmd = processReceivedControlData(&Buffer, DataLength);
|
||||
// if (cmd != NULL)
|
||||
// {
|
||||
// call(cmd)
|
||||
// }
|
||||
for (uint16_t i = 0; i < DataLength; i++)
|
||||
{
|
||||
// process the received data and descide to do an action
|
||||
cc_processData(Buffer[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void USB_serialStreamWriteC(char *data, uint16_t len)
|
||||
{
|
||||
//===========================================================================
|
||||
/* Determine if data/answeres should be sent to the host
|
||||
* the previous RX section should be clarify that behaviour.
|
||||
*/
|
||||
|
||||
/* Flag management - Only allow one string to be sent per action */
|
||||
if ((ReportString != NULL) && (ActionSent == false) && LineEncoding1.BaudRateBPS)
|
||||
if (data != NULL && len > 0 && LineEncoding1.BaudRateBPS)
|
||||
{
|
||||
ActionSent = true;
|
||||
|
||||
/* Select the Serial Tx Endpoint */
|
||||
Endpoint_SelectEndpoint(CDC1_TX_EPADDR);
|
||||
|
||||
/* Write the String to the Endpoint */
|
||||
Endpoint_Write_Stream_LE(ReportString, strlen(ReportString), NULL);
|
||||
Endpoint_Write_Stream_LE(data, len, NULL);
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearIN();
|
|
@ -41,11 +41,16 @@
|
|||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/eeprom.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#include "command_ctrl.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Platform/Platform.h>
|
||||
|
||||
|
@ -53,7 +58,7 @@
|
|||
|
||||
/* UART definitions: */
|
||||
|
||||
#define UART_BAUD_RATE 115200
|
||||
//#define UART_BAUD_RATE 115200
|
||||
#define OUTPUT_BUFFER_SIZE 100
|
||||
|
||||
#include "uart/uart.h" // include after the definition
|
||||
|
@ -84,5 +89,7 @@
|
|||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_ControlRequest(void);
|
||||
|
||||
void USB_serialStreamWriteC(char*, uint16_t);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in a new issue