Code:
enum {
COMM_INIT = 0,
COMM_WAIT_DLR,
COMM_WAIT_CR,
COMM_DELAY
} COMM_STATES;
// UCHAR FPGA_image[32],D2A_image[20];
//-----------------------------------------------------------------------------
UCHAR COM1_get_chr(void)
{
UCHAR x;
x = COM1_rbuf[COM1_rxo];
if (++COM1_rxo >= COM1_RX_LEN)
COM1_rxo = 0;
if (COM1_rcnt)
COM1_rcnt--;
return x;
}
//-----------------------------------------------------------------------------
void COM1_send_str(UCHAR * str)
{
UCHAR x, pos, tab_stop;
disable_interrupts(int_RDA);
output_high(MAINEN);
delay_us(100);
pos = 0;
while (*str) {
x = *str++;
if (x != '\t') {
U1TXREG = (UINT) x & 255;
U2TXREG = (UINT) x & 255;
pos++;
delay_us(300);
x = U1RXREG;
} else {
tab_stop = 32;
if (pos >= tab_stop)
tab_stop = pos + 2;
while (pos < tab_stop) {
U1TXREG = (UINT) ' ';
U2TXREG = (UINT) ' ';
pos++;
delay_us(300);
x = U1RXREG;
}
}
}
delay_us(100);
output_low(MAINEN);
x = U1RXREG;
enable_interrupts(int_RDA);
}
//-----------------------------------------------------------------------------
void COM1_init(void)
{
COM1_rxi = COM1_rxo = COM1_rcnt = 0;
comm_state = COMM_INIT;
enable_interrupts(int_RDA);
enable_interrupts(int_RDA2);
}
//----------------------------------------------------------------------------
#separate
UINT get_char(void)
{
return comm_buf[comm_ptr++];
}
//----------------------------------------------------------------------------
#separate
UINT peek_char(void)
{
// skip_spc();
return comm_buf[comm_ptr];
}
//----------------------------------------------------------------------------
#separate
void skip_spc(void)
{
while (comm_buf[comm_ptr] && (comm_buf[comm_ptr] == ',' || comm_buf[comm_ptr] == ' '))
comm_ptr++;
}
//----------------------------------------------------------------------------
#separate
SINT get_int(void)
{
SINT num, sign = 1;
skip_spc();
if (comm_buf[comm_ptr]) {
num = 0;
if (peek_char() == '-') {
sign = -1;
get_char();
}
while (isdigit(comm_buf[comm_ptr]))
num = (num * 10) + (comm_buf[comm_ptr++] - '0');
}
// skip_spc();
return num * sign;
}
//----------------------------------------------------------------------------
#separate
ULONG str_to_long(void)
{
ULONG num;
skip_spc();
if (comm_buf[comm_ptr]) {
num = 0;
while (isdigit(comm_buf[comm_ptr]))
num = (num * 10) + (comm_buf[comm_ptr++] - '0');
}
// skip_spc();
return num;
}
//----------------------------------------------------------------------------
#separate
ULONG get_hex(void)
{
ULONG num;
UCHAR chr;
skip_spc();
if (peek_char()) {
num = 0;
while (isxdigit(peek_char())) {
chr = get_char();
chr = toupper(chr);
if (chr <= '9')
chr -= '0';
else
chr = chr - ('A' - 10);
num = num * 16 + (ULONG) chr;
}
}
return num;
}
//----------------------------------------------------------------------------
UINT get_frequency(void)
{
UINT freq;
freq = get_int() * 10;
if (peek_char() == '.') {
get_char(); // skip '.'
freq += get_char() - '0';
}
return freq;
}
//----------------------------------------------------------------------------
void send_two_lines(void)
{
COM1_send_str("\r\n\n");
}
//----------------------------------------------------------------------------
void list_help(void)
{
COM1_send_str("\r\n");
COM1_send_str("$S <synchronizer><cr> \tSet synchronizer channel 1 or 2\r\n");
COM1_send_str("$BR <bitrate><cr> \tSet video data rate in 100Kbps increments\r\n");
COM1_send_str("$DP <datapolarity><cr> \tSet data polarity (0,1)\r\n");
COM1_send_str("$CP <clockphase><cr> \tSet clock output phase (0..3)\r\n");
COM1_send_str("$IM <impedance><cr> \tSet impedance low/high (0..1)\r\n");
COM1_send_str("$DF <filter><cr> \tSelect filter (0..1)\r\n");
COM1_send_str("$IN <input select><cr> \tSet input select (1..2)\r\n");
COM1_send_str("$L <loop bw><cr> \tloop bandwidth (0..31)\r\n");
COM1_send_str("$DE <encoding><cr> \tSet input encoding (0..5)\r\n");
COM1_send_str("$R <random><cr> \tSelect with/without randomizer and mode (0..3)\r\n");
COM1_send_str("$Q<cr> \tRequest status\r\n");
COM1_send_str("\r\n");
}
//----------------------------------------------------------------------------
// command format:
// $<cmd> [<number>[,<number>]]<cr>
// where:
// <cmd> a two letter operation specifier
// <number> value to be used in operation
// <cr> 0x0D character ending command string
//
UCHAR process_setup(void)
{
UCHAR chr, run, OFF, den, buf[64];
// ULONG freq, bitrate;
UINT idx, value, v[4];
chr = 2;
comm_ptr = 0;
switch (toupper(get_char())) {
case 'H':
case '?':
list_help();
return 0;
break;
case 'S':
value = get_int();
if (value && value < 3) {
selected_channel = value - 1;
set_selected_channel_led();
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case 'B':
if (toupper(get_char()) == 'R')
value = get_int();
if (value && value < 300) {
setup[selected_channel].bitrate = value;
store_setup();
update_all();
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case 'D':
skip_spc();
switch (toupper(get_char())) {
case 'P':
value = get_int();
if (value < 2) {
setup[selected_channel].input_polarity = value;
store_setup();
update_all();
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case 'F':
value = get_int();
if (value && value < 2) {
setup[selected_channel].filter_select = value;
store_setup();
update_all();
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case 'E':
value = get_int();
if (value < 6) {
if (value == 0) {
den = "NRZL";
setup[selected_channel].input_enc = den;
store_setup();
update_all();
} else if (value == 1) {
den = "NRZM";
setup[selected_channel].input_enc = den;
store_setup();
update_all();
} else if (value == 2) {
den = "NRZS";
setup[selected_channel].input_enc = den;
store_setup();
update_all();
} else if (value == 3) {
den = "BI-PHASE";
setup[selected_channel].input_enc = den;
store_setup();
update_all();
} else if (value == 4) {
den = "BI-PHASE M";
setup[selected_channel].input_enc = den;
store_setup();
update_all();
} else {
den = "BI-PHASE S";
setup[selected_channel].input_enc = den;
store_setup();
update_all();
}
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case 'C':
if (toupper(get_char()) == 'P') {
value = get_int();
if (value < 4) {
setup[selected_channel].output_clock_phase = value;
store_setup();
update_all();
}
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case 'L':
value = get_int();
if (value < 32) {
setup[selected_channel].loop_bw = value;
store_setup();
update_all();
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case 'R':
value = get_int();
if (value < 4) {
if (value == 0) {
setup[selected_channel].random_length = value;
store_setup();
update_all();
} else if (value == 1) {
run = 7;
setup[selected_channel].random_length = run;
store_setup();
update_all();
} else if (value == 2) {
run = 11;
setup[selected_channel].random_length = run;
store_setup();
update_all();
} else {
run = 15;
setup[selected_channel].random_length = run;
store_setup();
update_all();
}
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case 'I':
skip_spc();
switch (toupper(get_char())) {
case 'M':
value = get_int();
if (value < 2) {
setup[selected_channel].impedance = value;
store_setup();
update_all();
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case 'N':
value = get_int();
if (value && value < 3) {
setup[selected_channel].input_select = value - 1;
store_setup();
update_all();
} else
COM1_send_str("\r\n$FAIL\r\n");
}
break;
case 'B':
value = get_int();
if (value < 32) {
setup[selected_channel].loop_bw = value;
store_setup();
update_all();
} else
COM1_send_str("\r\n$FAULT\r\n");
break;
case 'Q':
send_two_lines();
COM1_send_str(VERSION);
sprintf(buf, "\r\nID=%u DC=%02u%02u\r\n", unit_id.id, unit_id.year, unit_id.week);
COM1_send_str(buf);
for (idx = 0; idx < 2; idx++) {
sprintf(buf, "\r\n\r\nSynchronizer %u\r\n", idx + 1);
COM1_send_str(buf);
sprintf(buf, "\r\nIN=%u IMP=%u\r\n", setup[idx].input_select + 1, setup[idx].impedance);
COM1_send_str(buf);
sprintf(buf, "BR=%lu BW=%u IDE=%u RL=%u\r\n",
setup[idx].bitrate, setup[idx].loop_bw, setup[idx].input_enc,
setup[idx].random_length);
COM1_send_str(buf);
sprintf(buf, "IDP=%u CP=%u DFL=%u\r\n",
setup[idx].input_polarity, setup[idx].output_clock_phase * 90,
setup[idx].filter_select);
COM1_send_str(buf);
sprintf(buf, "\r\nSignal=%u Lock=%u\r\n",
(FPGA_bits[idx] & 0x80) != 0, (FPGA_bits[idx] & 0x40) != 0);
COM1_send_str(buf);
}
break;
case 'X':
v[0] = get_int();
v[1] = get_int();
v[2] = get_int();
v[3] = get_int();
if (v[0] == 17951) {
unit_id.id = v[1];
unit_id.year = v[2];
unit_id.week = v[3];
store_setup();
}
default:
printf("\r\n$FAIL\r\n");
return 0;
}
return 0;
}
//----------------------------------------------------------------------------
void clear_com_errors(void) {
UCHAR chr;
Line 471:if (U1STA.OERR) {
U1STA.OERR = 0;
}
if (U1STA.FERR) {
U1STA.FERR = 0;
Line 478:chr = U1RXREG;
}
if (U2STA.OERR) {
U2STA.OERR = 0;
}
if (U2STA.FERR) {
U2STA.FERR = 0;
Line 488:chr = U2RXREG;
}
}
//----------------------------------------------------------------------------
#separate
void comm_handler(void) {
UINT chr, ret, buf[10];
Line 498:clear_com_errors();
switch (comm_state) {
case COMM_INIT:
comm_ridx = 0;
comm_state++;
break;
case COMM_WAIT_DLR:
#ignore_warnings 201
if (COM1_rcnt)
if ((chr = COM1_get_chr()) == '$') {
comm_state++;
comm_timeout = 0;
} else
COM1_send_str("\r\n$FAIL\r\n");
break;
case COMM_WAIT_CR:
if (COM1_rcnt) {
comm_timeout = 0;
chr = COM1_get_chr();
comm_buf[comm_ridx++] = chr;
if (comm_ridx > 70) {
comm_state = 0;
break;
}
if (chr == 13) {
ret = process_setup();
if (ret == 1) {
store_setup();
update_all();
}
if (ret != 255)
COM1_send_str("\r\n$OK\r\n");
sprintf(buf, "S%u> ", selected_channel + 1);
COM1_send_str(buf);
COM1_init();
} else if (chr == 27) {
COM1_send_str("\r\n\n$BREAK\r\n");
comm_state = 0;
}
}
if (comm_state > COMM_WAIT_DLR)
if (TMR_100MS_COMM_TO) {
TMR_100MS_COMM_TO = 0;
if (++comm_timeout > 10000) // time out after 10 seconds from last char
comm_state = 0;
}
break;
case COMM_DELAY:
break;
}
}