|
@@ -0,0 +1,625 @@
|
|
|
+#include "cmdInterpreter.h"
|
|
|
+
|
|
|
+#define CMD_M_MAX_LENGTH 121
|
|
|
+#define CMD_N_MAX_LENGTH 240
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+cmdInterpreter::cmdInterpreter() {
|
|
|
+ this->prepareForNextCommand();
|
|
|
+ this->debug = false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ * prepare everything for the next command
|
|
|
+ */
|
|
|
+void cmdInterpreter::prepareForNextCommand(void) {
|
|
|
+ memset((void *) this->cmdBuffer, 0x00, CMD_BUFFER_LENGTH);
|
|
|
+ this->cmdBuffer_ptr = this->cmdBuffer;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ * analyse command
|
|
|
+ */
|
|
|
+return_code_t cmdInterpreter::interprete(pca9635 pwm_driver[], uint8_t cnt, uint8_t oe_pin) {
|
|
|
+ uint8_t cmd_len = (uint8_t) strlen((char *) this->cmdBuffer);
|
|
|
+ uint8_t *cmd_buf_pntr = this->cmdBuffer;
|
|
|
+ cmd_buf_pntr++;
|
|
|
+ return_code_t returncode = RETURN_ERROR;
|
|
|
+
|
|
|
+
|
|
|
+ while (*cmd_buf_pntr) {
|
|
|
+ if(*cmd_buf_pntr == CMD_CR){
|
|
|
+ *cmd_buf_pntr = 68;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isxdigit(*cmd_buf_pntr)) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ ++cmd_buf_pntr;
|
|
|
+ }
|
|
|
+ cmd_buf_pntr = this->cmdBuffer;
|
|
|
+
|
|
|
+ switch(*cmd_buf_pntr) {
|
|
|
+
|
|
|
+ case 'S': {
|
|
|
+ uint8_t data[2] = {0};
|
|
|
+ returncode = readParameters(cmd_buf_pntr, cmd_len, data, 2);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data[0] >= 120) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ char s[64] = {'\0'};
|
|
|
+ if (this->debug) {
|
|
|
+ sprintf(s, " set channel %d to %d", data[0], data[1]);
|
|
|
+ doubleS.writeSerial(s);
|
|
|
+ }
|
|
|
+
|
|
|
+ uint8_t dev = data[0] / 10;
|
|
|
+ uint8_t port = data[0] % 10;
|
|
|
+
|
|
|
+ if (this->debug) {
|
|
|
+ sprintf(s, " (dev: %d ch %d)", dev, port);
|
|
|
+ doubleS.writeSerial(s);
|
|
|
+ }
|
|
|
+ if (dev < cnt && pwm_driver[dev].isAvailable()) {
|
|
|
+ if (pwm_driver[dev].set_led_pwm(port, data[1])) {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" channel is set!");
|
|
|
+ } else {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" error while setting channel!");
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" dev not available!");
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ case 'R': {
|
|
|
+ uint8_t data[1] = {0};
|
|
|
+ returncode = readParameters(cmd_buf_pntr, cmd_len, data, 1);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data[0] >= 120) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ uint8_t dev = data[0] / 10;
|
|
|
+ uint8_t port = data[0] % 10;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (dev < cnt && pwm_driver[dev].isAvailable()) {
|
|
|
+ uint8_t pwm = pwm_driver[dev].getPWMValue(port);
|
|
|
+
|
|
|
+ char s[64] = {'\0'};
|
|
|
+ sprintf(s, " pwm value of channel %d is %d (hex: %X)", data[0],pwm, pwm);
|
|
|
+ doubleS.writeSerial(s);
|
|
|
+
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ case 'O': {
|
|
|
+ uint8_t data[1] = {0};
|
|
|
+ returncode = readParameters(cmd_buf_pntr, cmd_len, data, 1);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ digitalWrite(oe_pin, !data[0]);
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ case 'I': {
|
|
|
+ uint8_t data[1] = {0};
|
|
|
+ returncode = readParameters(cmd_buf_pntr, cmd_len, data, 1);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ char s[64] = {'\0'};
|
|
|
+ if (this->debug) {
|
|
|
+ sprintf(s, " set group interval to : %d (%dms)", data[0], (416*(data[0]+1))/10);
|
|
|
+ doubleS.writeSerial(s);
|
|
|
+ }
|
|
|
+ for (uint8_t i = 0; i < cnt; i++) {
|
|
|
+ if (pwm_driver[i].isAvailable()) {
|
|
|
+ if (pwm_driver[i].set_group_blinking(data[0])) {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" set!");
|
|
|
+ } else {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" error while setting!");
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ case 'i': {
|
|
|
+ uint8_t data[1] = {0};
|
|
|
+ returncode = readParameters(cmd_buf_pntr, cmd_len, data, 1);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ char s[64] = {'\0'};
|
|
|
+ if (this->debug) {
|
|
|
+ sprintf(s, " set group duty to : %d", data[0]);
|
|
|
+ doubleS.writeSerial(s);
|
|
|
+ }
|
|
|
+ for (uint8_t i = 0; i < cnt; i++) {
|
|
|
+ if (pwm_driver[i].isAvailable()) {
|
|
|
+ if (pwm_driver[i].set_group_dimming(data[0])) {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" set!");
|
|
|
+ } else {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" error while setting!");
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ case 'G': {
|
|
|
+ uint8_t data[2] = {0};
|
|
|
+ returncode = readParameters(cmd_buf_pntr, cmd_len, data, 2);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data[0] >= 120) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ uint8_t dev = data[0] / 10;
|
|
|
+ uint8_t port = data[0] % 10;
|
|
|
+
|
|
|
+ if (data[1] > 1) {
|
|
|
+ data[1] = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ char s[64] = {'\0'};
|
|
|
+ if (this->debug) {
|
|
|
+ sprintf(s, " set group blinking of channel %d (dev: %d port: %d) to %d", data[0], dev, port, data[1]);
|
|
|
+ doubleS.writeSerial(s);
|
|
|
+ }
|
|
|
+ if (pwm_driver[dev].isAvailable()) {
|
|
|
+ if (pwm_driver[dev].set_led_mode(port, data[1]+2)) {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" set!");
|
|
|
+ } else {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" error while setting!");
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (this->debug)
|
|
|
+ doubleS.writeSerial(" dev not available!");
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ case 'm': {
|
|
|
+ uint8_t data[CMD_M_MAX_LENGTH] = {0};
|
|
|
+ uint8_t length = CMD_M_MAX_LENGTH;
|
|
|
+ char tmp[50];
|
|
|
+ returncode = readParametersWithLength(cmd_buf_pntr, cmd_len, data, &length, MODE_SINGLE_VALUE);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this->debug) {
|
|
|
+ doubleS.writeSerial(" Data: ");
|
|
|
+ PrintHex8(tmp, data, length);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ sprintf(tmp, " array length: %d", length);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ boolean change_pwm[12*10] = {false};
|
|
|
+ uint8_t new_pwm[12*10] = {0};
|
|
|
+ for (uint8_t i = 0; i < data[0]; i++) {
|
|
|
+ uint8_t channel = data[i+1];
|
|
|
+ if (!pwm_driver[channel/10].isAvailable()) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ new_pwm[channel] = data[length-1];
|
|
|
+ change_pwm[channel] = true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for (uint8_t i = 0; i < cnt; i++) {
|
|
|
+ int8_t channel_start = -1;
|
|
|
+ int8_t channel_end = -1;
|
|
|
+
|
|
|
+ for (uint8_t j = 0; j < 10; j++) {
|
|
|
+ if (change_pwm[i*10+j]) {
|
|
|
+ if (channel_start == -1)
|
|
|
+ channel_start = j;
|
|
|
+ channel_end = j;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (channel_start == -1 && channel_end == -1) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (this->debug) {
|
|
|
+ sprintf(tmp, "\rdev: %d changes: ", i);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ PrintHex8(tmp, &change_pwm[i*10], 10);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+
|
|
|
+ sprintf(tmp, " start: %d end %d", channel_start, channel_end);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+
|
|
|
+ doubleS.writeSerial("\r values: ");
|
|
|
+ PrintHex8(tmp, &new_pwm[i*10], 10);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (uint8_t j = channel_start; j <= channel_end; j++) {
|
|
|
+ if (!change_pwm[i*10+j]) {
|
|
|
+ new_pwm[i*10+j] = pwm_driver[i].getPWMValue(j);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (this->debug) {
|
|
|
+ doubleS.writeSerial("\rfilled values: ");
|
|
|
+ PrintHex8(tmp, &new_pwm[i*10], 10);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ boolean ret = pwm_driver[i].set_all_led_pwm(channel_start, channel_end-channel_start+1, &new_pwm[i*10+channel_start]);
|
|
|
+ if (!ret) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ case 'n': {
|
|
|
+ uint8_t data[CMD_N_MAX_LENGTH] = {0};
|
|
|
+ uint8_t length = CMD_N_MAX_LENGTH;
|
|
|
+ char tmp[50];
|
|
|
+ returncode = readParametersWithLength(cmd_buf_pntr, cmd_len, data, &length, MODE_MULTIPLE_VALUE);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this->debug) {
|
|
|
+ doubleS.writeSerial(" Data: ");
|
|
|
+ PrintHex8(tmp, data, length);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ sprintf(tmp, " array length: %d", length);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ boolean change_pwm[12*10] = {false};
|
|
|
+ uint8_t new_pwm[12*10] = {0};
|
|
|
+ for (uint8_t i = 0; i < data[0]; i++) {
|
|
|
+ uint8_t channel = data[i+1];
|
|
|
+ if (!pwm_driver[channel/10].isAvailable()) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ new_pwm[channel] = data[i+1+data[0]];
|
|
|
+ change_pwm[channel] = true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for (uint8_t i = 0; i < cnt; i++) {
|
|
|
+ int8_t channel_start = -1;
|
|
|
+ int8_t channel_end = -1;
|
|
|
+
|
|
|
+ for (uint8_t j = 0; j < 10; j++) {
|
|
|
+ if (change_pwm[i*10+j]) {
|
|
|
+ if (channel_start == -1)
|
|
|
+ channel_start = j;
|
|
|
+ channel_end = j;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (channel_start == -1 && channel_end == -1) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (this->debug) {
|
|
|
+ sprintf(tmp, "\rdev: %d changes: ", i);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ PrintHex8(tmp, &change_pwm[i*10], 10);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+
|
|
|
+ sprintf(tmp, " start: %d end %d", channel_start, channel_end);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+
|
|
|
+ doubleS.writeSerial("\r values: ");
|
|
|
+ PrintHex8(tmp, &new_pwm[i*10], 10);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (uint8_t j = channel_start; j <= channel_end; j++) {
|
|
|
+ if (!change_pwm[i*10+j]) {
|
|
|
+ new_pwm[i*10+j] = pwm_driver[i].getPWMValue(j);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (this->debug) {
|
|
|
+ doubleS.writeSerial("\rfilled values: ");
|
|
|
+ PrintHex8(tmp, &new_pwm[i*10], 10);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ boolean ret = pwm_driver[i].set_all_led_pwm(channel_start, channel_end-channel_start+1, &new_pwm[i*10+channel_start]);
|
|
|
+ if (!ret) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ case 'g': {
|
|
|
+ uint8_t data[CMD_N_MAX_LENGTH] = {0};
|
|
|
+ uint8_t length = CMD_N_MAX_LENGTH;
|
|
|
+ char tmp[50];
|
|
|
+ returncode = readParametersWithLength(cmd_buf_pntr, cmd_len, data, &length, MODE_MULTIPLE_VALUE);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this->debug) {
|
|
|
+ doubleS.writeSerial(" Data: ");
|
|
|
+ PrintHex8(tmp, data, length);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ sprintf(tmp, " array length: %d", length);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ uint8_t new_mode[12][10] = {0};
|
|
|
+ uint8_t new_led[12][10] = {0};
|
|
|
+ uint8_t change_cnt[12] = {0};
|
|
|
+ for (uint8_t i = 0; i < data[0]; i++) {
|
|
|
+ uint8_t channel = data[i+1];
|
|
|
+ if (!pwm_driver[channel/10].isAvailable()) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ new_mode[channel/10][change_cnt[channel/10]] = data[i+1+data[0]] + 2;
|
|
|
+ new_led[channel/10][change_cnt[channel/10]] = channel%10;
|
|
|
+ change_cnt[channel/10]++;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for (uint8_t i = 0; i < cnt; i++) {
|
|
|
+
|
|
|
+ if (change_cnt[i] == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (this->debug) {
|
|
|
+ sprintf(tmp, "\rdev: %d leds: ", i);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ PrintHex8(tmp, new_led[i], 10);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+
|
|
|
+ sprintf(tmp, " cnt: %d\r values: ", change_cnt[i]);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ PrintHex8(tmp, new_mode[i], 10);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ boolean ret = pwm_driver[i].set_all_led_modes(change_cnt[i], new_led[i], new_mode[i]);
|
|
|
+ if (!ret) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ case 'L': {
|
|
|
+ returncode = readParameters(cmd_buf_pntr, cmd_len, NULL, 0);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ char s[64] = {'\0'};
|
|
|
+
|
|
|
+ for (uint8_t i = 0; i < cnt; i++) {
|
|
|
+ if (pwm_driver[i].isAvailable()) {
|
|
|
+ sprintf(s, "dev %d available (channel: %d to: %d hex: %.2X to %.2X)\r\n", i, i*10, i*10+9, i*10, i*10+9);
|
|
|
+ doubleS.writeSerial(s);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ case 'D': {
|
|
|
+ returncode = readParameters(cmd_buf_pntr, cmd_len, NULL, 0);
|
|
|
+
|
|
|
+ if (returncode != RETURN_CR) {
|
|
|
+ return returncode;
|
|
|
+ }
|
|
|
+
|
|
|
+ this->debug = !this->debug;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ default: {
|
|
|
+
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return RETURN_CR;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+return_code_t cmdInterpreter::readParameters(uint8_t *cmd_buf_pntr, uint8_t cmd_len, uint8_t parameters[], uint8_t num_parameters) {
|
|
|
+ if (cmd_len != (2+2*num_parameters)) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (uint8_t i = 0; i < num_parameters; i++) {
|
|
|
+ parameters[i] = 0;
|
|
|
+ parameters[i] = ascii2byte(++cmd_buf_pntr) << 4;
|
|
|
+ parameters[i] += ascii2byte(++cmd_buf_pntr);
|
|
|
+
|
|
|
+ }
|
|
|
+ return RETURN_CR;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * this commands reads from a array and checks if the first hex block is a length that matches the rest of the data
|
|
|
+ * all parameters from string are converted to byte and stored in paramters array.
|
|
|
+ * the num_parameter pointer reads the maximal length of the parameters array and contains the written paraeters to parameters after the method.
|
|
|
+ * m controls the meode this method calculated the amount of expected parameters:
|
|
|
+ * - MODE_SINGLE_VALUE means there is an length field, length*bytes and a value field
|
|
|
+ * - MODE_MULTUPLE_VALUE means there is an length field, length*bytes and again length*value fields
|
|
|
+ */
|
|
|
+return_code_t cmdInterpreter::readParametersWithLength(uint8_t *cmd_buf_pntr, uint8_t cmd_len, uint8_t parameters[], uint8_t *num_parameters, cmdInterpreter::interpreteMode_t m) {
|
|
|
+
|
|
|
+ if (cmd_len < (2+2)) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+ parameters[0] = 0;
|
|
|
+ parameters[0] = ascii2byte(++cmd_buf_pntr) << 4;
|
|
|
+ parameters[0] += ascii2byte(++cmd_buf_pntr);
|
|
|
+
|
|
|
+
|
|
|
+ uint8_t dataLength = 0;
|
|
|
+ switch(m) {
|
|
|
+ case MODE_SINGLE_VALUE:
|
|
|
+ dataLength = 2*parameters[0] + 2;
|
|
|
+ break;
|
|
|
+ case MODE_MULTIPLE_VALUE:
|
|
|
+ dataLength = 2*parameters[0] + 2*parameters[0];
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cmd_len != (2+2+dataLength) || (dataLength/2+1) > *num_parameters) {
|
|
|
+ return RETURN_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for (uint8_t i = 1; i < dataLength+1; i++) {
|
|
|
+ parameters[i] = 0;
|
|
|
+ parameters[i] = ascii2byte(++cmd_buf_pntr) << 4;
|
|
|
+ parameters[i] += ascii2byte(++cmd_buf_pntr);
|
|
|
+ }
|
|
|
+ *num_parameters = dataLength/2+1;
|
|
|
+ return RETURN_CR;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ * add to buffer and check if end of command is detected
|
|
|
+ * will return true if a end of command is detected
|
|
|
+ */
|
|
|
+boolean cmdInterpreter::addToBuffer(uint8_t d) {
|
|
|
+ *this->cmdBuffer_ptr = d;
|
|
|
+ if (d == CMD_CR) {
|
|
|
+ if (this->debug) {
|
|
|
+ doubleS.writeSerial("Buffer: ");
|
|
|
+ char tmp[50];
|
|
|
+ PrintHex8(tmp, this->cmdBuffer, 20);
|
|
|
+ doubleS.writeSerial(tmp);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ (this->cmdBuffer_ptr)++;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ * prints 8-bit data in hex with leading zeroes
|
|
|
+ */
|
|
|
+void PrintHex8(char *dstptr, uint8_t *srcdata, uint8_t length) {
|
|
|
+ for (int i=0; i<length; i++) {
|
|
|
+ sprintf(dstptr+(i*2), "%.2X",srcdata[i]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * prints boolean data
|
|
|
+ */
|
|
|
+void PrintHex8(char *dstptr, boolean *srcdata, uint8_t length) {
|
|
|
+ for (int i=0; i<length; i++) {
|
|
|
+ sprintf(dstptr+(i*2), " %.1X",srcdata[i]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ * takes a pointer to a string and convert the current characters to a binary
|
|
|
+ */
|
|
|
+uint8_t ascii2byte(const uint8_t *val) {
|
|
|
+ uint8_t temp = *val;
|
|
|
+
|
|
|
+ if (temp > 0x60)
|
|
|
+ temp -= 0x27;
|
|
|
+ else if (temp > 0x40)
|
|
|
+ temp -= 0x07;
|
|
|
+ temp -= 0x30;
|
|
|
+
|
|
|
+ return (uint8_t) (temp & 0x0F);
|
|
|
+}
|