From cd06a168d69ccac33aaf2801e7de0c85a933484d Mon Sep 17 00:00:00 2001 From: "K.Ohta" Date: Thu, 14 Nov 2013 13:41:46 +0900 Subject: [PATCH 1/1] [UART] Load via S-Record is okay. Setting is 57600bps, 8N1, but some of noise (bit7='1') happens, will fix. --- euart.c | 36 ++++++++++++++------- euart.h | 2 +- shell_strutl.c | 99 ++++++++++++++++++++++++++++++++++++---------------------- shell_strutl.h | 8 +++-- term_shell.c | 98 +++++++++++++++++++++++++++++++++++++++++---------------- uart_termio.c | 17 +++++----- 6 files changed, 174 insertions(+), 86 deletions(-) diff --git a/euart.c b/euart.c index 247a4f3..8941051 100644 --- a/euart.c +++ b/euart.c @@ -49,6 +49,7 @@ static unsigned char uart_rx_xon; static unsigned char uart_tx_xon; static unsigned char uart_rx_wakeup; +#define UART_BAUD_FACTOR 34 // 57600bps on 8MHz,BRGH=1,BRG16=1 void uart_sleep(void) { @@ -57,13 +58,13 @@ void uart_sleep(void) IPR1bits.TX1IP = 0; // Low IPR1bits.RC1IP = 1; // High RCSTA = 0b10010000; //SPEN, 8bit, ASYNC, CREN = 0 - BAUDCON = 0b00001010; // IDLE High, BRG16, -ABDEN, WUE - TXSTA = 0b00100000; //8bit, ASYNC, TXEN, Break + BAUDCON = 0b00001010; // IDLE High, DTRXP=0(Positive), BRG16, -ABDEN, WUE + TXSTA = 0b00100100; //8bit, ASYNC, TXEN, Break, BRGH=1 PIE1bits.TX1IE = 0; PIE1bits.RC1IE = 1; uart_rx_wakeup = 0; - SPBRGH = 51 / 256; - SPBRG = 51 % 256; + SPBRGH = UART_BAUD_FACTOR / 256; + SPBRG = UART_BAUD_FACTOR % 256; } void uart_wakeup(void) @@ -73,13 +74,13 @@ void uart_wakeup(void) IPR1bits.TX1IP = 0; // Low IPR1bits.RC1IP = 1; // High RCSTA = 0b10010000; //SPEN, 8bit, ASYNC, CREN - BAUDCON = 0b00001010; // IDLE High, BRG16, -ABDEN, WUE - TXSTA = 0b00100000; //8bit, ASYNC, TXEN, Break + BAUDCON = 0b00001010; // IDLE High, DTRXP=0(Positive),BRG16, -ABDEN, WUE + TXSTA = 0b00100100; //8bit, ASYNC, TXEN, Break, BRGH=1 PIE1bits.TX1IE = 0; PIE1bits.RC1IE = 1; // uart_rx_wakeup = 0xff; - SPBRGH = 51 / 256; - SPBRG = 51 % 256; + SPBRGH = UART_BAUD_FACTOR / 256; + SPBRG = UART_BAUD_FACTOR % 256; } void uart_init(void) @@ -108,21 +109,30 @@ void uart_inthdr_rx(void) goto _l0; // Exit } #endif + c = RCREG; if(RCSTAbits.OERR == 0) { if(RCSTAbits.FERR == 0) { uart_rx_sts = 0; // Clear error - c = RCREG; +// c = RCREG; if(c == UART_CH_XOFF) { uart_tx_xon = 0; // XOFF Sequence for TX } else if(c == UART_CH_XON) { // XON Sequence for TX uart_tx_xon = 0xff; - } else { //if(uart_rx_bytes < UART_BUF_SIZE) { // + } else if(uart_rx_bytes < UART_BUF_SIZE) { // uart_rfifo[uart_rx_wptr++] = c; if(uart_rx_wptr >= UART_BUF_SIZE) uart_rx_wptr = 0; uart_rx_bytes++; if(uart_rx_bytes >= UART_BUF_SIZE) uart_rx_bytes = UART_BUF_SIZE; + if((uart_rx_xon != 0) && (uart_rx_bytes >= ((UART_BUF_SIZE * 7) / 10))) { + uart_pushxoff(100); + uart_rx_xon = 0; + } + // uart_pushchar(c, 0x0000); - } + }// else { + // If overflow, discard. + //} + } else { // Frame Error uart_rx_sts != UART_FRAMEERROR; } @@ -150,6 +160,10 @@ unsigned char uart_pullchar(void) if(uart_rx_rptr > UART_BUF_SIZE) uart_rx_rptr = 0; uart_rx_bytes--; if(uart_rx_bytes <= 0) uart_rx_bytes = 0; + if((uart_rx_xon == 0) && (uart_rx_bytes < ((UART_BUF_SIZE * 7) / 10))) { + uart_pushxon(100); + uart_rx_xon = 0xff; + } return c; } diff --git a/euart.h b/euart.h index 071df60..d20bc6a 100644 --- a/euart.h +++ b/euart.h @@ -47,7 +47,7 @@ extern void uart_inthdr_rx(void); extern unsigned char uart_pullchar(void); extern unsigned char uart_pushchar(unsigned char c, unsigned int timeout); extern void uart_pushxon(unsigned int timeout); -extern void uart_pushxff(unsigned int timeout); +extern void uart_pushxoff(unsigned int timeout); extern void uart_break(void); extern unsigned char uart_getstat(void); diff --git a/shell_strutl.c b/shell_strutl.c index accd770..c4e5e85 100644 --- a/shell_strutl.c +++ b/shell_strutl.c @@ -35,22 +35,43 @@ #include #include "shell_strutl.h" +#include "euart.h" +#include "uart_termio.h" +void bin2hex(char *s, unsigned char v) +{ + unsigned char c; + c = v >> 4; + if(c > 9) { + c = c - 10 + 'A'; + } else { + c = c + '0'; + } + s[0] = c; + + c = v & 0x0f; + if(c > 9) { + c = c - 10 + 'A'; + } else { + c = c + '0'; + } + s[1] = c; + s[2] = 0x00; +} unsigned char c2h(unsigned char c) { - if(c < '1') return 0xff; + if(c < '0') return 0xff; if(c > 'F') return 0xff; if(c <= '9') return c - '0'; if(c >= 'A') return c - 'A' + 10; return 0xff; } - unsigned char hex2byte(unsigned char *p) { unsigned char h, l; h = c2h(p[0]); - l = c2h(p[1]); + l = c2h(p[1]); if((h >= 0x10) || (l >= 0x10)) return 0; return (h << 4) | l; } @@ -89,31 +110,50 @@ unsigned char migrate_hex(unsigned char *p) return 0xff; } +int search_head_s(unsigned char *s) +{ + int i; + for(i = 0; i < 127; i++) { + switch(s[i]) { + case 'S': + return i; + break; + case '\0': + return -1; // Not found 'S' until eoln. + break; + default: + break; + } + } + return -1; // Error +} + /* * Saving or Loading use MOTOROLLA S FORMAT with 24bit address. * See details: * http://www.geocities.jp/chako_ratta/micon/s_format.html (written in Japanese) * */ -char str_shexheader(unsigned char *s, unsigned char *file) +int str_shexheader(unsigned char *s, unsigned char *file) { unsigned char pp; unsigned char sum; unsigned char c; unsigned char bytes; unsigned int i; + unsigned char sbuf[4]; // if(check_eol(s) != 0) return TERM_NULL; if((s[0] != 'S') || (s[1] != '0')) return TERM_NONSREC; - + uart_term_putstr("\nHEAD"); if(migrate_hex(&s[2]) == 0) return TERM_NONSREC; bytes = hex2byte(&s[2]); if(bytes <= 2) return TERM_SRECERR; for(i = 4; i < 8; i++) if(s[i] != '0') return TERM_NONHDR; - sum = 0; - bytes -= 2; + sum = bytes; + bytes -= 3; pp = 0; - while(bytes > 1) { + while(bytes > 0) { if(migrate_hex(&s[i]) == 0) return TERM_SRECERR; c = hex2byte(&s[i]); sum += c; @@ -126,7 +166,11 @@ char str_shexheader(unsigned char *s, unsigned char *file) if(migrate_hex(&s[i]) == 0) return TERM_SRECERR; c = hex2byte(&s[i]); sum = ~sum; + bin2hex(sbuf, sum); + uart_term_putstr(sbuf); + if(c != sum) return TERM_SUMERR; + uart_term_putstr("...OK\n"); return TERM_OK; } @@ -135,7 +179,7 @@ char str_shexheader(unsigned char *s, unsigned char *file) * 'S1' record to hex * Accept only S2 and S8. */ -char str_shex2bin(unsigned char *s, unsigned char *p, unsigned long *addr, unsigned char *len) +int str_shex2bin(unsigned char *s, unsigned char *p, unsigned long *addr, unsigned char *len) { unsigned char sum = 0; unsigned char pp; @@ -146,9 +190,9 @@ char str_shex2bin(unsigned char *s, unsigned char *p, unsigned long *addr, unsig // Get Header if(s[0] != 'S') return TERM_NONSREC; if(s[1] == '2') { // Data core - for(i = 2; i < 8; i += 2) if(migrate_hex(&s[i]) == 0) return TERM_SRECERR; + for(i = 2; i < 10; i += 2) if(migrate_hex(&s[i]) == 0) return TERM_SRECERR; bytes = hex2byte(&s[2]); - if(bytes <= 4) return TERM_SRECERR; + if(bytes <= 3) return TERM_SRECERR; sum = bytes; h = hex2byte(&s[4]); l = hex2byte(&s[6]); @@ -176,45 +220,26 @@ char str_shex2bin(unsigned char *s, unsigned char *p, unsigned long *addr, unsig * OK! */ } else if(s[1] == '8') { - if((s[2] != '0') || (s[3] != '3')) return TERM_SRECERR; + if((s[2] != '0') || (s[3] != '4')) return TERM_SRECERR; + uart_term_putstr("TAIL"); for(i = 4; i < 10; i += 2) if(migrate_hex(&s[i]) == 0) return TERM_SRECERR; - sum = 3; + sum = 4; h = hex2byte(&s[4]); l = hex2byte(&s[6]); l2 = hex2byte(&s[8]); c = hex2byte(&s[10]); - *addr = (h * 65536) | (l << 8) | l2; +// *addr = (h * 65536) | (l << 8) | l2; *len = 0; sum = ~(sum + h + l + l2); if(c != sum) return TERM_SUMERR; + uart_term_putstr(" OK."); return TERM_SRECEND; } else { - return TERM_UNDSREC; } return TERM_OK; } -void bin2hex(char *s, unsigned char v) -{ - unsigned char c; - c = v >> 4; - if(c > 9) { - c = c - 10 + 'A'; - } else { - c = c + '0'; - } - s[0] = c; - - c = v & 0x0f; - if(c > 9) { - c = c - 10 + 'A'; - } else { - c = c + '0'; - } - s[1] = c; - s[2] = 0x00; -} /* * Set "S1" Record @@ -270,7 +295,7 @@ unsigned char str_put_shexheader(unsigned char *s, char *filename) s[1] = '0'; len = shell_strlen(filename); if(len > 252) len = 252; - sum = len+3; + sum = len + 3; bin2hex(&s[2], len + 3); for(i = 4; i < 8; i++) s[i] = '0'; @@ -278,7 +303,7 @@ unsigned char str_put_shexheader(unsigned char *s, char *filename) pp = 0; while(pp != len){ bin2hex(&s[i], filename[pp]); - sum += s[i]; + sum += filename[pp]; i += 2; pp++; } diff --git a/shell_strutl.h b/shell_strutl.h index b9fb162..d11701a 100644 --- a/shell_strutl.h +++ b/shell_strutl.h @@ -42,13 +42,15 @@ extern "C" { #define TERM_NULL -16 #define TERM_NONHDR -17 +extern void bin2hex(char *s, unsigned char v); + extern unsigned char hex2byte(unsigned char *p); extern unsigned char check_eol(unsigned char *p); extern unsigned char c2h(unsigned char c); extern unsigned char migrate_hex(unsigned char *p); - -extern char str_shexheader(unsigned char *s, unsigned char *file); -extern char str_shex2bin(unsigned char *s, unsigned char *p, unsigned long *addr, unsigned char *len); +extern int search_head_s(unsigned char *s); +extern int str_shexheader(unsigned char *s, unsigned char *file); +extern int str_shex2bin(unsigned char *s, unsigned char *p, unsigned long *addr, unsigned char *len); extern unsigned char str_put_shexheader(unsigned char *s, char *filename); extern unsigned char str_bin2hex(unsigned char *s, unsigned char *p, unsigned long addr, unsigned char len); diff --git a/term_shell.c b/term_shell.c index 65f2cdf..8be9569 100644 --- a/term_shell.c +++ b/term_shell.c @@ -46,8 +46,8 @@ #include "eeprom_util.h" -unsigned char cmd_shellstr[127]; -static char shell_strbuf[127]; +unsigned char cmd_shellstr[130]; +static char shell_strbuf[130]; static char xarg1[66]; static char xarg2[66]; static char xarg3[66]; @@ -190,6 +190,7 @@ static void save_hex_page(unsigned char *p, unsigned int len, unsigned long base put_hexline(&p[pp], pp + baseaddr, l); break; } + idle_time_ms(100); // Line wait. } } @@ -204,35 +205,71 @@ void shell_memcpy(unsigned char *to, unsigned char *from, unsigned char len) static char wait_for_sheader(unsigned char *file, unsigned char retry) { unsigned char _try = 0; - char stat; - + unsigned char _err = 0; + int stat; + file[0] = '\0'; + do { shell_strbuf[0] = '\0'; - uart_term_getstr(shell_strbuf, 1000, 0); // With Echo, timeout=100Sec. - uart_term_putstr(shell_strbuf); - stat = str_shexheader(shell_strbuf, file); + uart_term_getstr(shell_strbuf, 100, 0); // With Echo, timeout=10Sec. + stat = search_head_s(shell_strbuf); + if(stat < 0) { + _err++; + if(_err > 100) return -1; // Error + continue; + } + _err = 0; + stat = str_shexheader(&shell_strbuf[stat], file); if(stat == TERM_OK) break; _try++; } while(_try <= retry); return stat; } -static unsigned long load_hex_page(unsigned char *p, unsigned int len) +static unsigned long load_hex_page(unsigned char *p, unsigned long *addr, unsigned int len) { - char stat; + int stat; unsigned char l; - unsigned long addr; - + unsigned long a; + unsigned char __err = 0; + unsigned long bytes = 0; + int pos; + unsigned char sbuf[20]; + while(len > 0){ - uart_term_getstr(shell_strbuf, 100, 0); // With Echo, timeout=10Sec. - stat = str_shex2bin(shell_strbuf, p, &addr, &l); - uart_term_putstr(shell_strbuf); - if(stat < 0) return 0xffffffff; // Some error - if(l < len) return addr + l; // End addr +_l0: + + shell_strbuf[0] = '\0'; + uart_term_getstr(shell_strbuf, 1000, 0); // Without Echo, timeout=100Sec. + + stat = search_head_s(shell_strbuf); + if(stat < 0) { + __err++; + if(__err > 100) { + return 0xffffffff; // Error + } + ClrWdt(); + idle_time_ms(10); + goto _l0; + } + __err = 0; + pos = stat; + stat = str_shex2bin(&shell_strbuf[stat], p, &a, &l); + if(stat == TERM_SRECEND) { + return bytes; // Return head + } + + if(stat != TERM_OK) { + return 0xffffffff; // Some error + } + + bytes += l; + *addr = a; + if(l >= len) break; // End addr p += l; len -= l; } - return addr + l; + return bytes; } /* * Load from S record. @@ -242,26 +279,32 @@ static void load_from_term(unsigned char *p) unsigned char slen = shell_gettok(xarg1, p); unsigned long addr = 0; unsigned char *pv; - unsigned char len; + unsigned int len; unsigned char fbuf[128]; - char stat; + unsigned long l; + int stat; if(shell_strcmp(xarg1, "INT") > 0) { // Internal EEPROM uart_term_putstr("\nPls. start internal eeprom data...\n"); + stat = wait_for_sheader(fbuf, 10); + if(stat != TERM_OK) goto _loaderr; - if(shell_strcmp(fbuf, "INT_EEPRPOM") < 0) goto _fileerr; + if(shell_strcmp(fbuf, "INT_EEPROM") < 0) goto _fileerr; len = sizeof(__radioset_t); - pv = &tmparea; - addr = load_hex_page(pv, len); - if(addr == 0xffffffff) goto _loaderr; - if((addr & 0xffff0000) != 0) goto _addrerr; + pv = tmparea; +// pv = &setup; + l = load_hex_page(pv, &addr, len); + if(l == 0xffffffff) goto _loaderr; + if(addr >= 255) goto _loaderr; // Too large + shell_memcpy((unsigned char *)(&setup) , &tmparea, len); setup_akc6955(); // DO! } else if(shell_strcmp(xarg1, "FTBL") > 0) { // External EEPROM, Freq TBL } else if(shell_strcmp(xarg1, "BAND") > 0) { // band } _OK: + uart_term_putstr("\nOK.\n"); return; @@ -510,14 +553,15 @@ char term_shell(unsigned int timeout) break; case 15: // Exit uart_term_putstr("\nBye... (^^)/~~\n"); - uart_init(); - return SHELL_CMD_OK; - break; + goto _l0; + break; default: uart_term_putstr("\n?? CMD Error\n"); break; } } while(1); +_l0: + uart_init(); return SHELL_CMD_OK; } diff --git a/uart_termio.c b/uart_termio.c index 1af1c8e..5e70e25 100644 --- a/uart_termio.c +++ b/uart_termio.c @@ -49,7 +49,7 @@ unsigned char uart_term_putstr(unsigned char *s) if((uart_getstat() & UART_WAKEUP) == 0) return 0; // Error while(s[p] != 0x00) { - uart_pushchar(s[p], 100); // Timeout = 10ms + uart_pushchar(s[p], 200); // Timeout = 10ms p++; if(p >= 255) return 0; // Overlen } @@ -58,7 +58,7 @@ unsigned char uart_term_putstr(unsigned char *s) void uart_term_getstr(unsigned char *s, unsigned int timeout, unsigned char echo) { - unsigned char i = 0; + unsigned int i = 0; unsigned char c = 0x00; unsigned int tim; unsigned char pwr; @@ -76,12 +76,15 @@ void uart_term_getstr(unsigned char *s, unsigned int timeout, unsigned char echo cnt = 0; } cnt++; - if(echo != 0) uart_pushchar(c, 0); // Echoback + if(echo != 0) uart_pushchar(c, 200); // Echoback if(c == '\b') { // BS - if(i > 0) i--; - s[i] = '\0'; - } else { - s[i] = c; + if(i > 0) { + s[i] = '\0'; + i--; + } + } else + if(c < 0x80) { + s[i] = c; i++; if((c == '\t') || (c == '\n') || (c == '\r')) break; // TAB OR CR if(i >= 128) break; -- 2.11.0