N3rdpad based command control manager implementation added.

This commit is contained in:
klaute 2016-09-17 19:02:36 +02:00
parent 8f815588a0
commit 0551403788
4 changed files with 474 additions and 0 deletions

110
command_config.h Normal file
View file

@ -0,0 +1,110 @@
/*
* 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 "config_helper.h"
#include "led_matrix.h"
#include "globals.h"
/*****************************************************************************/
extern uint8_t key_config[EEP_KEY_CNT][EEP_KEY_SEQ_LEN][EEP_KEY_TUPLE_LEN];
extern uint8_t os_type;
extern uint8_t keystroke_delay;
/*****************************************************************************/
void cc_getConfig(void);
void cc_setKeyConfig(void);
void cc_setLEDState(void);
void cc_setOSType(void);
void cc_startBootloader(void);
void cc_saveFullSampleCfg(void);
void cc_setKeyStrokeDelay(void);
/*****************************************************************************/
#define CC_CMD_GET_CONFIG 0x0A
#define CC_CMD_SET_KEY_CONFIG 0x14
#define CC_CMD_SET_LED_STATE 0x1E
#define CC_CMD_SET_OS_TYPE 0x28
#define CC_CMD_START_BTLDR 0x32
#define CC_CMD_SSKC 0x3C
#define CC_CMD_SET_KS_DELAY 0x46
//#define CC_CMD_SET_BAUDRATE 0x32
/*****************************************************************************/
#define CC_CMD_GET_CONFIG_FUNC &cc_getConfig
#define CC_CMD_SET_KEY_CONFIG_FUNC &cc_setKeyConfig
#define CC_CMD_SET_LED_STATE_FUNC &cc_setLEDState
#define CC_CMD_SET_OS_TYPE_FUNC &cc_setOSType
#define CC_CMD_START_BTLDR_FUNC &cc_startBootloader
#define CC_CMD_SSKC_FUNC &cc_saveFullSampleCfg
#define CC_CMD_SET_KS_DELAY_FUNC &cc_setKeyStrokeDelay
//#define CC_CMD_SET_BAUDRATE_FUNC &cc_setBaudrate
/*****************************************************************************/
#define CC_CMD_GET_CONFIG_DATA_TO_READ 0
#define CC_CMD_SET_KEY_CONFIG_DATA_TO_READ 41 // Key number, 40 byte sequence data
#define CC_CMD_SET_LED_STATE_DATA_TO_READ 2 // LED number, state
#define CC_CMD_SET_OS_TYPE_DATA_TO_READ 1 // the OS type
#define CC_CMD_START_BTLDR_DATA_TO_READ 0 // start bootloader
#define CC_CMD_SSKC_DATA_TO_READ 0 // save sample key config
#define CC_CMD_SET_KS_DELAY_DATA_TO_READ 1 // the keystroke delay value
/*****************************************************************************/
#define CC_READ_DATA_MAX 64
/*****************************************************************************/
uint8_t cc_commands[] = {
CC_CMD_GET_CONFIG,
CC_CMD_SET_KEY_CONFIG,
CC_CMD_SET_LED_STATE,
CC_CMD_SET_OS_TYPE,
CC_CMD_START_BTLDR,
CC_CMD_SSKC,
CC_CMD_SET_KS_DELAY,
};
void (*cc_cmd_functions[])() = {
CC_CMD_GET_CONFIG_FUNC,
CC_CMD_SET_KEY_CONFIG_FUNC,
CC_CMD_SET_LED_STATE_FUNC,
CC_CMD_SET_OS_TYPE_FUNC,
CC_CMD_START_BTLDR_FUNC,
CC_CMD_SSKC_FUNC,
CC_CMD_SET_KS_DELAY_FUNC,
};
uint8_t cc_cmd_data_to_read[] = {
CC_CMD_GET_CONFIG_DATA_TO_READ,
CC_CMD_SET_KEY_CONFIG_DATA_TO_READ,
CC_CMD_SET_LED_STATE_DATA_TO_READ,
CC_CMD_SET_OS_TYPE_DATA_TO_READ,
CC_CMD_START_BTLDR_DATA_TO_READ,
CC_CMD_SSKC_DATA_TO_READ,
CC_CMD_SET_KS_DELAY_DATA_TO_READ,
};
uint8_t cc_read_data[CC_READ_DATA_MAX];
/*****************************************************************************/
#endif

146
command_ctrl.c Normal file
View 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_serialStreamWrite(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
command_ctrl.h Normal file
View 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_serialStreamWrite(char*);
void cc_init(void);
void cc_abort(void);
void cc_processData(uint8_t);
void cc_clearReadDataBuffer(void);
/*****************************************************************************/
#endif

179
command_functions.c Normal file
View file

@ -0,0 +1,179 @@
/*
* Author: klaute -Kai Lauterbach - @kailauterbach - me@klaute.de
* Date: 08/2016
* License: GPLv3
*/
/*****************************************************************************/
extern void USB_serialStreamWriteC(char*, uint16_t);
extern void USB_serialStreamWrite(char*);
/*****************************************************************************/
// send the key configuration to the USB host
void cc_getConfig()
{
char* sBody = " ";
sprintf(sBody, "%c%c%c", MSG_SOM1, MSG_SOM2, MSG_TYPE_CONFIG);
USB_serialStreamWrite(sBody);
for (uint8_t key = 0; key < EEP_KEY_CNT; key++)
{
char* sKey = " ";
sprintf(sKey, "%c", key);
USB_serialStreamWriteC(sKey, 1);
for (uint8_t seqnum = 0; seqnum < EEP_KEY_SEQ_LEN; seqnum++)
{
char* sSeq = " ";
sprintf(sSeq, "%c%c", key_config[key][seqnum][0], key_config[key][seqnum][1]);
USB_serialStreamWriteC(sSeq, 2);
}
}
sBody = " ";
sprintf(sBody, "%c%c", MSG_EOM1, MSG_EOM2);
USB_serialStreamWrite(sBody);
}
/*****************************************************************************/
// receive the key configuration for one key
void cc_setKeyConfig()
{
uint8_t key = cc_read_data[0];
uint8_t seqnum = 0;
for (uint8_t pos = 1; pos < EEP_KEY_SEQ_LEN; pos += EEP_KEY_TUPLE_LEN)
{
key_config[key][seqnum][0] = cc_read_data[pos]; // first byte f the tuple
key_config[key][seqnum][1] = cc_read_data[pos+1]; // second byte f the tuple
seqnum++;
}
// TODO should be called by an other function
ch_writeConfig();
char* sBody = " ";
sprintf(sBody, "%c%c%c%c%c", MSG_SOM1, MSG_SOM2, MSG_TYPE_ANSWER_OK, MSG_EOM1, MSG_EOM2);
USB_serialStreamWrite(sBody);
}
/*****************************************************************************/
void cc_setLEDState()
{
uint8_t led = cc_read_data[0]; // LED number
uint8_t state = cc_read_data[1]; // state
if (led < 0 || led >= EEP_KEY_CNT)
{
char* sBody = " ";
sprintf(sBody, "%c%c%c%c%c", MSG_SOM1, MSG_SOM2, MSG_TYPE_ANSWER_NOK, MSG_EOM1, MSG_EOM2);
USB_serialStreamWrite(sBody);
return;
}
if (state == 0)
lm_ledOff(led);
else
lm_ledOn(led);
char* sBody = " ";
sprintf(sBody, "%c%c%c%c%c", MSG_SOM1, MSG_SOM2, MSG_TYPE_ANSWER_OK, MSG_EOM1, MSG_EOM2);
USB_serialStreamWrite(sBody);
}
/*****************************************************************************/
void cc_setOSType()
{
cn_writeOSType(cc_read_data[0]);
char* sBody = " ";
sprintf(sBody, "%c%c%c%c%c", MSG_SOM1, MSG_SOM2, MSG_TYPE_ANSWER_OK, MSG_EOM1, MSG_EOM2);
USB_serialStreamWrite(sBody);
}
/*****************************************************************************/
void cc_startBootloader()
{
// enable the watchdog without a time interval to use
wdt_enable(0);
// trigger watchdog
while(1) {};
}
/*****************************************************************************/
// Wert: | 0x80 | 0x40 | 0x20 | 0x10 | 0x08 | 0x04 | 0x02 | 0x01
// Wert: | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1
// Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
// Descr: | delay | - | fn | meta | altgr | alt | ctrl | shift
// max 40 byte / 20 tupel
uint8_t sample_seq[] = {
0x01, 0x0b, // H
0x80, 0x0f, // delay 16 cycles
0x00, 0x04, // a
0x00, 0x0f, // l
0x80, 0x80, // delay 128 cycles
0x00, 0x0f, // l
0x00, 0x12, // o
0x80, 0x0f, // delay 16 cycles
0x10, 0x00, // meta modifier
0x80, 0x80, // delay 128
0x10, 0x00, // meta modifier
0xff, 0xff, // in case that length of the sequence is less than 40 byte add a (0xff, 0xff) tuple - only allowed firmware internal
0xff, 0xff, // one 0xff 0xff tuple is required, the other tuples are added to clean up the eeprom content
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
0xff, 0xff,
};
// Example hexadecimal data:
// 2 byte: message header
// 1 byte: 0x14 = set configuration command identifier
// 1 byte: 0x00 = key number to modify
// 40 byte: sequence data (tuples) full filled using (0xff, 0xff) tuples
// 2 byte: message footer
// 3C3E1400010B80FF000A000F8080000F001280FF100080801000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D0A
void cc_saveFullSampleCfg()
{
for (uint8_t k = 0; k < EEP_KEY_CNT; k++)
{
for (uint8_t s = 0; s < 40; s++)
{
ch_writeKeyConfigMV(k, s, sample_seq[2*s], sample_seq[2*s+1]);
}
}
ch_readConfig();
char* sBody = " ";
sprintf(sBody, "%c%c%c%c%c", MSG_SOM1, MSG_SOM2, MSG_TYPE_ANSWER_OK, MSG_EOM1, MSG_EOM2);
USB_serialStreamWrite(sBody);
}
/*****************************************************************************/
void cc_setKeyStrokeDelay()
{
ch_setKeyStrokeDelay(cc_read_data[0]);
char* sBody = " ";
sprintf(sBody, "%c%c%c%c%c", MSG_SOM1, MSG_SOM2, MSG_TYPE_ANSWER_OK, MSG_EOM1, MSG_EOM2);
USB_serialStreamWrite(sBody);
}
/*****************************************************************************/