All pastes #246945 Raw Edit

Someone

public c v1 · immutable
#246945 ·published 2006-11-12 21:45 UTC
rendered paste body
// config.c#include "global.h"#include "ctboard.h"#include "serial.h"#include "config.h"#include "loop.h"#include "command.h"#include "rprintf.h"#include <eeprom.h>#include <string.h>// current menu entry:#define MENU_OFF		0#define MENU_BAUD		1#define MENU_ECHO		2#define MENU_RXLE		3#define MENU_TXLE		4#define MENU_EEPROM		5#define MENU_NUM		6// ----- prototypes -----static void saveConfigToEEPROM(void);static byte loadConfigFromEEPROM(void);static void changeMenu(byte up);// ----- local vars -----static byte menuMode = MENU_OFF;// current pos in sniff sequencestatic byte linkSeqPos = 0;// do we need a hardware updatestatic byte needHWUp = 0;// currently in link modestatic byte linked = 0;// map calibration: lower and upper sample valuestatic u16 adcL=0,mapL=0,adcU=10,mapU=10;// ----- CONFIG BYTES -----#define MAX_LINK_START_CMD	8typedef struct {	u16  adcMin[2],adcMax[2];	u16  mapMin[2],mapMax[2];	byte baudRate;	byte startLinked;	byte sniff;	byte source;	byte rxLineEnd;	byte txLineEnd;	byte echo;	byte linkStartLen;	byte linkStartCmd[MAX_LINK_START_CMD];	byte checkSum;} config_t;config_t config = {	.adcMin = { 0,0 },	.adcMax = { 0x3ff,0x3ff },	.mapMin = { 0,0 },	.mapMax = { 100,100 },	.baudRate     = BAUD_RATE_9600,	.startLinked  = 0,	.sniff        = 1,	.source       = MPLEX_SRC_XPT,	.rxLineEnd    = LINE_END_CR,	.txLineEnd    = LINE_END_CRLF,	.echo         = 1,	.linkStartLen = 2,	.linkStartCmd = {'l','c'}};// eeprom configconfig_t configEEPROM __attribute__ ((section (".eeprom")));// ---------- remap ADC value ----------u16 remapADC(byte port,u16 value){	u16 adcRange  = config.adcMax[port] - config.adcMin[port];	u16 realRange = config.mapMax[port] - config.mapMin[port];	if(value<config.adcMin[port])		return config.mapMin[port];	else if(value>config.adcMax[port])		return config.mapMax[port];	value -= config.adcMin[port];		u32 vl = (u32)value;	u32 ar = (u32)adcRange;	u32 rr = (u32)realRange;	u32 rs = vl * rr / ar;	u16 r  = (u16)rs;	r += config.mapMin[port];	return r;}// ----- calibMapping -----// setup the adc and map range for an ADC port// a linear monotonous mapping from adc to map// given are the two samples (adcL,mapL) and (adcU,mapU)// with adcL < adcU and mapL < mapU#define ADC_MAX 0x03ff#define MAP_MAX 0xffffbyte calibMapping(byte port){	// check parameters	if((adcL>=adcU)||(mapL>=mapU))		return EXEC_ERROR;	u16 adcDelta = adcU - adcL;	u16 mapDelta = mapU - mapL;	u32 md = (u32)mapDelta;	u32 ad = (u32)adcDelta;	u32 ml = (u32)mapL;	u32 al = (u32)adcL;	// ----- determine ADC range -----	u32	A = al * md;	u32 B = ad * ml;	u32 pos;	// MIN: origin	if(A == B) {		config.mapMin[port] = 0;		config.adcMin[port] = 0;	}	// MIN: limit ADC range	else if(A > B) {		pos = B / md;		config.mapMin[port] = 0;		config.adcMin[port] = (u16)pos;	}	//MIN: limit MAP range	else {		pos = A / ad;		config.mapMin[port] = ml - (u16)pos;		config.adcMin[port] = 0;	}	A = (MAP_MAX - ml) * ad;	B = (ADC_MAX - al) * md;	// MAX: both max	if(A == B) {		config.mapMax[port] = MAP_MAX;		config.adcMax[port] = ADC_MAX;	}	// MAX: limit MAP range	else if(A > B) {		pos = B / ad;		config.mapMax[port] = ml + (u16)pos;		config.adcMax[port] = ADC_MAX;	}	// MAX: limit ADC range	else {		pos = A / md;		config.mapMax[port] = MAP_MAX;		config.adcMax[port] = al + (u16)pos;	}		return EXEC_OK;}// ---------- HW Update & Init ----------byte needHWUpdate(void){	return needHWUp;}void doHWUpdate(void){	needHWUp = 0;	setMplex(linked,config.source);	setBaud(config.baudRate);	ct_beep(1);}void initConfig(){	// load fails... beep and save default	if(!loadConfigFromEEPROM()) {		ct_beep(3);		saveConfigToEEPROM();	}	linked = config.startLinked;	doHWUpdate();}static void linkStart(void){	needHWUp = 1;	linked = 1;}static void linkEnd(void){	needHWUp = 1;	linked = 0;}byte isLinked(void){	return linked;}// ----- check link stard cmd -----void checkLinkStartCmd(byte b){	byte found = 0;	byte retry = 0;	// CRLF mode: start sequence finally found?	if(linkSeqPos == config.linkStartLen+1) {		if(b == '\n')			found = 1;		else			retry = 1;	}	// CR, LF mode: check for final char	else if(linkSeqPos == config.linkStartLen) {		// check for LF,CR,CRLF		if(config.rxLineEnd==LINE_END_LF) {			if(b == '\n') 				found = 1;			else				retry = 1;		} else if(config.rxLineEnd==LINE_END_CR) {			// CR/CRLF			if(b == '\r')				found = 1;			else				retry = 1;		} else { // CRLF			if(b == '\r')				linkSeqPos++;			else				retry = 1;		}	} 	// still in start sequence?	else if(b == config.linkStartCmd[linkSeqPos])		linkSeqPos++;	else		retry = 1;	// restart search	if(retry) {		linkSeqPos = 0;		if(b == config.linkStartCmd[0])			linkSeqPos++;	}	// found sequence start -> enter link mode	if(found)		linkStart();}byte cmdExit(void){	linkEnd();	return EXEC_QUIT;}// ---------- key handling ---------void handleMenuKeys(byte keys){	// RED: next menu item	if(keys & CT_LED_RED) {		menuMode++;		if(menuMode==MENU_NUM)			menuMode=1;	}	// ORANGE: dec value	if(keys & CT_LED_ORANGE) {		changeMenu(0);	}	// YELLOW: inc value	if(keys & CT_LED_YELLOW) {		changeMenu(1);	}	// GREEN: leave menu	if(keys & CT_LED_GREEN) {		menuMode = 0;	}}void handleNormalKeys(byte keys){	// RED: enter menu	if(keys & CT_LED_RED) {		menuMode = 1;	}	// ORANGE: toggle source	if(keys & CT_LED_ORANGE) {		if(config.source == MPLEX_SRC_XPT)			config.source = MPLEX_SRC_COM;		else			config.source = MPLEX_SRC_XPT;		needHWUp = 1;	}	// YELLOW: toggle pass/sniff	if(keys & CT_LED_YELLOW) {		config.sniff = 1-config.sniff;	}	// GREEN: enter link mode	if(keys & CT_LED_GREEN) {		linkStart();	}}static void handleLinkKeys(byte keys) {	// RED: key command	if(keys & CT_LED_RED) {		keyCommand(0);	}	// ORANGE: key command	if(keys & CT_LED_ORANGE) {		keyCommand(1);	}	// YELLOW: key command	if(keys & CT_LED_YELLOW) {		keyCommand(2);	}	// GREEN: leave link mode	if(keys & CT_LED_GREEN) {		linkEnd();	}}void handleKeys(byte keys){	if(menuMode!=MENU_OFF)		return handleMenuKeys(keys);	else if(linked)		return handleLinkKeys(keys);	else		return handleNormalKeys(keys);}// ---------- status ----------static void showStatusOnLCD(void){	byte *str;	ct_lcd_clear();		// current connection src	if(config.source==MPLEX_SRC_XPT)		rprintfStr("XPort ");	else		rprintfStr("RS232 ");	// current connection mode	if(linked)		rprintfStr("LINK ");	else if(config.sniff)		rprintfStr("snif ");	else		rprintfStr("pass ");			// baud baud rate	switch(config.baudRate) {	case BAUD_RATE_9600:  str = "  9.6"; break;	case BAUD_RATE_19200: str = " 19.2"; break;	case BAUD_RATE_38400: str = " 38.4"; break;	case BAUD_RATE_57600: str = " 57.6"; break;	case BAUD_RATE_115200:str = "115.2"; break;	default: str = "?"; break;	}	rprintfStr(str);}static void showStatusOnLEDs(void) {	// RED/ORANGE: connection src	if(config.source == MPLEX_SRC_COM) {		ct_led_on (CT_LED_RED);		ct_led_off(CT_LED_ORANGE);	} else {		ct_led_off(CT_LED_RED);		ct_led_on (CT_LED_ORANGE);	}		// YELLOW: green led is sniff mode LED		if(config.sniff)		ct_led_on (CT_LED_YELLOW);	else 		ct_led_off(CT_LED_YELLOW);	// GREEN: connection mode	if(linked)		ct_led_on (CT_LED_GREEN);	else		ct_led_off(CT_LED_GREEN);}	void showStatus(void){	if((menuMode==MENU_OFF)&&(!linked))		showStatusOnLEDs();	showStatusOnLCD();}// ---------- menu control ----------byte isMenuOpen(void){	return menuMode != MENU_OFF;}static void showOnOffOnLCD(byte value){	if(value)		rprintfStr("on");	else		rprintfStr("off");}static void showLineEndOnLCD(byte value){	if(value==LINE_END_LF)		rprintfStr("LF");	else if(value==LINE_END_CR)		rprintfStr("CR");	else		rprintfStr("CRLF");}static void showMenuOnLCD(void){	ct_lcd_pos(0,1);	rprintfChar('@');			switch(menuMode) {	default:		break;	case MENU_BAUD:		rprintfStr("baud rate");		break;	case MENU_ECHO:		rprintfStr("echo char: ");		showOnOffOnLCD(config.echo);		break;	case MENU_RXLE:		rprintfStr("rx eol: ");		showLineEndOnLCD(config.rxLineEnd);		break;	case MENU_TXLE:		rprintfStr("tx eol: ");		showLineEndOnLCD(config.txLineEnd);		break;	case MENU_EEPROM:		rprintfStr("save/load");		break;	}}static void showOnOffOnLEDs(byte value){	ct_led_off(CT_LED_ALL);	if(value)		ct_led_on(CT_LED_GREEN);	else		ct_led_on(CT_LED_RED);}static void showValueOnLEDs(byte value){	ct_led_off(CT_LED_ALL);	if(value==0)		ct_led_on(CT_LED_RED);	else if(value==1)		ct_led_on(CT_LED_ORANGE);	else if(value==2)		ct_led_on(CT_LED_YELLOW);	else		ct_led_on(CT_LED_GREEN);}static void showMenuOnLEDs(void){	switch(menuMode) {	default:		break;	case MENU_BAUD:		ct_led_bits(config.baudRate+1);		break;	case MENU_ECHO:		showOnOffOnLEDs(config.echo);		break;	case MENU_RXLE:		showValueOnLEDs(config.rxLineEnd);		break;	case MENU_TXLE:		showValueOnLEDs(config.txLineEnd);		break;	case MENU_EEPROM:		ct_led_off(CT_LED_ALL);		break;	}}void showMenu(void){	showMenuOnLCD();	showMenuOnLEDs();}static void changeMenu(byte up){	switch(menuMode) {	default:		break;	case MENU_BAUD:		if(up) {			if(config.baudRate<BAUD_RATE_LAST)				config.baudRate++;		} else {			if(config.baudRate>0)				config.baudRate--;		}		needHWUp = 1;		break;	case MENU_ECHO:		config.echo = up;		break;	case MENU_RXLE:		if(up) {			if(config.rxLineEnd<LINE_END_LAST)				config.rxLineEnd++;		} else {			if(config.rxLineEnd>0)				config.rxLineEnd--;		}		break;	case MENU_TXLE:		if(up) {			if(config.txLineEnd<LINE_END_LAST)				config.txLineEnd++;		} else {			if(config.txLineEnd>0)				config.txLineEnd--;		}		break;	case MENU_EEPROM:		if(up) {			if(!loadConfigFromEEPROM())				ct_beep(3);			else				ct_beep(1);		} else {			saveConfigToEEPROM();			ct_beep(1);		}		break;	}}// ---------- command ----------byte cmdConfig(byte *cmd){	byte port;	u16  value,value2;	switch(cmd[0]) {		// load/save	case 'S': // cs - save config to EEPROM		saveConfigToEEPROM();		break;	case 'L': // cl - load config from EEPROM		if(!loadConfigFromEEPROM())			return EXEC_ERROR;		break;		// settings	case 'e': // ce0 ce1 - set echo mode, ce - print echo mode		if(cmd[1]=='0')			config.echo = 0;		else if(cmd[1]=='1')			config.echo = 1;		else if(cmd[1]!=0)			return EXEC_ERROR;		rprintfChar('0'+config.echo);		return EXEC_OK | EXEC_RESULT;	case 'r': // rx eol: 0=LF 1=CR 2=CR+LF		if(parseNibble(cmd[1],&port)) {			if(port>LINE_END_LAST)				return EXEC_ERROR;			config.rxLineEnd = port;		}		rprintfu04(config.rxLineEnd);		return EXEC_OK | EXEC_RESULT;	case 't': // tx eol: 0=LF 1=CR 2=CR+LF		if(parseNibble(cmd[1],&port)) {			if(port>LINE_END_LAST)				return EXEC_ERROR;			config.txLineEnd = port;		}		rprintfu04(config.txLineEnd);		return EXEC_OK | EXEC_RESULT;	case 'b': // set baud rate		if(parseNibble(cmd[1],&port)) {			if(port>BAUD_RATE_LAST)				return EXEC_ERROR;			config.baudRate = port;		}		rprintfu04(config.baudRate);		return EXEC_OK | EXEC_RESULT;	case 'k': // set key word		if(cmd[1]!=0) {			cmd++;			byte len = 0;			while(cmd[len]!=0) {				config.linkStartCmd[len] = cmd[len];				len++;			}			config.linkStartLen = len;		}		rprintfStrLen(config.linkStartCmd,0,config.linkStartLen);		return EXEC_OK | EXEC_RESULT;	case 's': // set link source: 0=COM 1=LAN		if(parseNibble(cmd[1],&port)) {			if(port>1)				return EXEC_ERROR;			config.source = port;		}		rprintfu04(config.source);		return EXEC_OK | EXEC_RESULT;	case 'l': // set link state: 1=link 0=sniff/pass-through		if(parseNibble(cmd[1],&port)) {			if(port>1)				return EXEC_ERROR;			config.startLinked = port;		}		rprintfu04(config.startLinked);		return EXEC_OK | EXEC_RESULT;	case 'i': // set sniff mode: 1=sniff 0=pass-through		if(parseNibble(cmd[1],&port)) {			if(port>1)				return EXEC_ERROR;			config.sniff = port;		}		rprintfu04(config.sniff);		return EXEC_OK | EXEC_RESULT;			case 'm': // real range mapping		if(cmd[1]=='r') {			if(cmd[2]=='l') { // lower sample				value  = adcL;				value2 = mapL;			}			else if(cmd[2]=='u') { // upper sample				value  = adcU;				value2 = mapU;			}			else {				if(!parseNibble(cmd[2],&port))					return EXEC_ERROR;				if(port>1)					return EXEC_ERROR;				if(cmd[3]=='a') { // get adc range					value  = config.adcMin[port];					value2 = config.adcMax[port];				}				else if(cmd[3]=='m') { // get map range					value  = config.mapMin[port];					value2 = config.mapMax[port];				}				else					return EXEC_ERROR;			}		} else if(cmd[1]=='w') {			byte pos = 4;			if((cmd[2]=='l')||(cmd[2]=='u'))				pos = 3;			if(!parseWord(&cmd[pos],&value))				return EXEC_ERROR;			if(!parseWord(&cmd[pos+5],&value2))				return EXEC_ERROR;			if(cmd[2]=='l') { // lower sample				adcL = value;				mapL = value2;			}			else if(cmd[2]=='u') { // upper sample				adcU = value;				mapU = value2;			}			else {				if(!parseNibble(cmd[2],&port))					return EXEC_ERROR;				if(port>1)					return EXEC_ERROR;				if(cmd[3]=='a') { // set adc range					config.adcMin[port] = value;					config.adcMax[port] = value2;				}				else if(cmd[3]=='m') { // set map range					config.mapMin[port] = value;					config.mapMax[port] = value2;				}				else					return EXEC_ERROR;			}		} else if(cmd[1]=='c') { // calibrate with lower and upper sample 			if(!parseNibble(cmd[2],&port))				return EXEC_ERROR;			if(port>1)				return EXEC_ERROR;			return calibMapping(port);		} else			return EXEC_ERROR;		rprintfu16(value);		rprintfChar(' ');		rprintfu16(value2);		return EXEC_OK | EXEC_RESULT;				default:		return EXEC_ERROR;	}	return EXEC_OK;}// ---------- query config ----------byte isStartLinked(void){	return config.startLinked;}byte isSniff(void){	return config.sniff;}byte doEcho(void){	return config.echo;}void sendEOL(void){	sendLineEnd(config.txLineEnd);}void sendLineEOL(const byte *line){	sendLine(config.txLineEnd,line);}byte isEOL(byte b){	if(b=='\r') {		if(config.rxLineEnd==LINE_END_CR)			return 1;		else if(config.rxLineEnd==LINE_END_CRLF)			return 2;		else			return 0;	}	else if(b=='\n') {		if(config.rxLineEnd!=LINE_END_CR)			return 1;		else			return 0;	}	else		return 0;}// ---------- eeprom ----------void saveConfigToEEPROM(void){	// calc check sum	config.checkSum = 0;	byte *adr = (byte *)&config;	byte sum = 0;	for(byte i=0;i<sizeof(config_t);i++)		sum += adr[i];	config.checkSum = sum;		eeprom_write_block(&config,&configEEPROM,sizeof(config_t));}byte loadConfigFromEEPROM(void){	config_t tempConfig;		eeprom_read_block(&tempConfig,&configEEPROM,sizeof(config_t));	byte tempSum = tempConfig.checkSum;	tempConfig.checkSum = 0;	byte sum = 0;	byte *adr = (byte *)&tempConfig;	for(byte i=0;i<sizeof(config_t);i++)		sum += adr[i];		// check sum ok	if(sum == tempSum) {		memcpy(&config,&tempConfig,sizeof(config_t));		return 1;	}	return 0;}