2014-10-30 11:17:48 +03:00

328 lines
7.6 KiB
C

/*
* user_proto.c
*
* Copyright 2014 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "cdcacm.h"
#include "main.h"
#include "uart.h"
#include "hardware_ini.h"
// integer value given by user
static volatile int32_t User_value = 0;
// number of motor to process
static volatile uint8_t active_motor = 6;
// last active send function - to post "anonymous" replies
sendfun lastsendfun = usb_send; // make it usb_send by default (to prevent suspension)
// flag: !=0 when user value reading ends - for character terminals
enum{
UVAL_START, // user start to write integer value
UVAL_CHECKED, // user checks the value & enters + that it's right
UVAL_PRINTED, // value printed to user
UVAL_ENTERED, // value entered but not printed
UVAL_BAD // entered bad value
};
uint8_t Uval_ready = UVAL_PRINTED;
int read_int(char *buf, int cnt);
intfun I = NULL; // function to process entered integer
#define READINT() do{i += read_int(&buf[i+1], len-i-1);}while(0)
#define WRONG_COMMAND() do{command = '?';}while(0)
/**
* displays all TRD values
* @param s -- current output
*/
void print_ad_vals(sendfun s){
int j;
if(ad7794_on){
for(j = 0; j < TRD_NO; j++){
print_int(ad7794_values[j], s);
s(' ');
}
newline(s);
}
}
void parce_incoming_buf(char *buf, int len, sendfun s){
uint8_t command;
uint8_t onewire_addr[8];
int i = 0, j, m;
lastsendfun = s;
if(Uval_ready == UVAL_START){ // we are in process of user's value reading
i += read_int(buf, len);
}
if(Uval_ready == UVAL_ENTERED){
print_int(User_value, s); // printout readed integer value for error control
Uval_ready = UVAL_PRINTED;
}
if(I && Uval_ready == UVAL_CHECKED){
Uval_ready = UVAL_BAD; // clear Uval_ready
I(User_value, s);
}
for(; i < len; i++){
command = buf[i];
if(!command) continue; // omit zero
if(command >= '0' && command <= '4'){ // stepper motors
active_motor = command - '0';
I = stepper_proc;
READINT();
}else switch (command){
case 'P':
run_dmatimer();
break;
case 'x': // set period of TIM1 (motors 1..3)
active_motor = 1;
I = set_timr;
READINT();
break;
case 'X': // set period of TIM2 (motors 4,5)
active_motor = 4;
I = set_timr;
READINT();
break;
case 'B': // stop all motors
for(m = 0; m < 5; m++)
stop_motor(m);
break;
case 'W': // scan for one 1-wire device
if(1 == OW_Scan(onewire_addr, 1)){
P("found 1-wire: ", s);
print_hex(onewire_addr, 8, s);
}else
P("1-wire error",s );
P("\r\n", s);
break;
case 'S': // single conversion
doubleconv = 0;
break;
case 'D': // double conversion
doubleconv = 1;
break;
case 'A': // show ADC value
//adc_start_conversion_direct(ADC1);
P("\r\n ADC value: ", s);
for(j = 0; j < 8; j++){
print_int(ADC_value[j], s);
P("\t", s);
}
newline(s);
break;
case 'i': // init AD7794
AD7794_init();
break;
case 'I': // turn off flag AD7794
ad7794_on = 0;
break;
case '+': // user check number value & confirm it's right
if(Uval_ready == UVAL_PRINTED) Uval_ready = UVAL_CHECKED;
else WRONG_COMMAND();
break;
case '-': // user check number value & confirm it's wrong
if(Uval_ready == UVAL_PRINTED) Uval_ready = UVAL_BAD;
else WRONG_COMMAND();
break;
case 'g': // change gain
I = set_ADC_gain;
READINT();
break;
case 's': // read ADC val through SPI
if(!ad7794_on){
AD7794_init();
P("wait: values aren't ready yet\n", s);
break;
}
P("AD7794 values: ", s);
print_ad_vals(s);
break;
case 'u': // check USB connection
P("\r\nUSB ", s);
if(!USB_connected) P("dis", s);
P("connected\r\n",s);
break;
case 'M': // ADC monitoring ON
ADC_monitoring = !ADC_monitoring;
break;
case 'T': // print time
print_time(s);
newline(s);
break;
/* case 'U': // test: init USART1
UART_init(USART1);
break; */
case '\n': // show newline as is
break;
case '\r':
break;
default:
WRONG_COMMAND(); // echo '?' on unknown command
}
s(command); // echo readed byte
}
}
/*
* Send char array wrd thru USB or UART
*/
void prnt(uint8_t *wrd, sendfun s){
if(!wrd) return;
while(*wrd) s(*wrd++);
}
/*
void newline(sendfun s){
P("\r\n", s);
}
*/
// sign of readed value
int32_t sign;
/**
* Read from TTY integer value given by user (in DEC).
* Reading stops on first non-numeric symbol.
* To work with symbol terminals reading don't stops on buffer's end,
* it waits for first non-numeric char.
* When working on string terminals, terminate string by '\n', 0 or any other symbol
* @param buf - buffer to read from
* @param cnt - buffer length
* @return amount of readed symbols
*/
int read_int(char *buf, int cnt){
int readed = 0, i;
if(Uval_ready){ // this is first run
Uval_ready = UVAL_START; // clear flag
User_value = 0; // clear value
sign = 1; // clear sign
}
if(!cnt) return 0;
for(i = 0; i < cnt; i++, readed++){
uint8_t chr = buf[i];
if(chr == '-'){
if(sign == 1){
sign = -1;
continue;
}else{ // '-' after numbers
Uval_ready = UVAL_ENTERED;
break;
}
}
if(chr < '0' || chr > '9'){
Uval_ready = UVAL_ENTERED;
break;
}
User_value = User_value * 10 + (int32_t)(chr - '0');
}
if(Uval_ready != UVAL_START) // reading has met an non-numeric character
User_value *= sign;
return readed;
}
/**
* Print buff as hex values
* @param buf - buffer to print
* @param l - buf length
* @param s - function to send a byte
*/
void print_hex(uint8_t *buff, uint8_t l, sendfun s){
void putc(uint8_t c){
if(c < 10)
s(c + '0');
else
s(c + 'a' - 10);
}
s('0'); s('x'); // prefix 0x
while(l--){
putc(buff[l] >> 4);
putc(buff[l] & 0x0f);
}
}
/**
* Print decimal integer value
* @param N - value to print
* @param s - function to send a byte
*/
void print_int(int32_t N, sendfun s){
uint8_t buf[10], L = 0;
if(N < 0){
s('-');
N = -N;
}
if(N){
while(N){
buf[L++] = N % 10 + '0';
N /= 10;
}
while(L--) s(buf[L]);
}else s('0');
}
/*
void process_int(int32_t v, sendfun s){
newline(s);
P("You have entered a value ", s);
print_int(v, s);
newline(s);
}
*/
void set_ADC_gain(int32_t v, sendfun s){
if(ad7794_on){
P("Change gain to ", s);
print_int(v, s);
newline(s);
change_AD7794_gain(v);
AD7794_calibration(0);
}
}
/**
* Process stepper
* @param v - user value
* @param s - active sendfunction
*/
void stepper_proc(int32_t v, sendfun s){
if(active_motor > 4){
P("wrong motor number\r\n", s);
return; // error
}
MSG("move ");
lastsendfun('0' + active_motor);
MSG(" to ");
print_int(v, lastsendfun);
MSG("\r\n");
move_motor(active_motor, v);
active_motor = 6;
}
void set_timr(int32_t v, sendfun s){
if(active_motor > 4){
P("wrong motor number\r\n", s);
return; // error
}
MSG("set period: ");
print_int(v, lastsendfun);
MSG("\r\n");
set_motor_period(active_motor, (uint16_t)v);
active_motor = 6;
}