diff --git a/src/makefile b/src/Makefile similarity index 89% rename from src/makefile rename to src/Makefile index dec5d5f..a974b77 100755 --- a/src/makefile +++ b/src/Makefile @@ -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 = diff --git a/src/command_config.h b/src/command_config.h new file mode 100755 index 0000000..9274a55 --- /dev/null +++ b/src/command_config.h @@ -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 +#include + +#include +#include + +#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 + diff --git a/src/command_ctrl.c b/src/command_ctrl.c new file mode 100755 index 0000000..e119c5f --- /dev/null +++ b/src/command_ctrl.c @@ -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; + } +} + +/*****************************************************************************/ diff --git a/src/command_ctrl.h b/src/command_ctrl.h new file mode 100755 index 0000000..c89a2f7 --- /dev/null +++ b/src/command_ctrl.h @@ -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 + +/*****************************************************************************/ + +#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 diff --git a/src/command_functions.c b/src/command_functions.c new file mode 100755 index 0000000..644e91d --- /dev/null +++ b/src/command_functions.c @@ -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) {}; +} + +/*****************************************************************************/ + diff --git a/src/globals.h b/src/globals.h new file mode 100755 index 0000000..775c253 --- /dev/null +++ b/src/globals.h @@ -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 + +/*****************************************************************************/ + diff --git a/src/USB2SerialMux.c b/src/main.c similarity index 92% rename from src/USB2SerialMux.c rename to src/main.c index 27e7092..3a107f7 100755 --- a/src/USB2SerialMux.c +++ b/src/main.c @@ -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(); diff --git a/src/USB2SerialMux.h b/src/main.h similarity index 93% rename from src/USB2SerialMux.h rename to src/main.h index eea9774..956d133 100755 --- a/src/USB2SerialMux.h +++ b/src/main.h @@ -41,11 +41,16 @@ #include #include #include + #include #include #include "Descriptors.h" + #include "globals.h" + + #include "command_ctrl.h" + #include #include @@ -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