/* Name: uart.c * Project: AVR USB driver for CDC interface on Low-Speed USB * Author: Osamu Tamura * Creation Date: 2006-06-18 * Tabsize: 4 * Copyright: (c) 2006 by Recursion Co., Ltd. * License: Proprietary, free under certain conditions. See Documentation. * * 2006-07-08 adapted to higher baudrate by T.Kitazawa */ /* General Description: This module implements the UART rx/tx system of the USB-CDC driver. */ #include #include #include /* needed by usbdrv.h */ #include "oddebug.h" #include "usbdrv.h" #include "uart.h" #include "hcs12ss59t/hcs12ss59t.h" #include #include #define TX(data) {rx_buf[rx_write_ptr] = data; rx_write_ptr = (rx_write_ptr+1) & RX_MASK;} extern uchar sendEmptyFrame; /* UART buffer */ uchar rx_read_ptr, tx_write_ptr, tx_read_ptr, rx_write_ptr; uchar rx_buf[RX_SIZE+HW_CDC_BULK_IN_SIZE], tx_buf[TX_SIZE]; uchar byte_counter = 0; uchar cmd = 0; #define BUFSZ 12 char dbuf[BUFSZ]; uchar cmax = 0; void uartInit(ulong baudrate, uchar parity, uchar stopbits, uchar databits) { usbDWord_t br; br.dword = ((F_CPU>>3)+(baudrate>>1)) / baudrate - 1; UCSR0A |= (1<>1)<= cmax)) { data = 0; cmax = 0; } if ((!cmax) && ((data < 32) || (data > 127))) { // any control character - cmd done if (cmd) { txs("\r\n"); switch (cmd) { case 't': hcs12ss59t_set_text(dbuf); break; case 'T': hcs12ss59t_set_buffer(dbuf); break; case 'b': temp = atol(dbuf); if (temp < 16) { hcs12ss59t_set_brightness(temp); } else { ok = 0; } break; case 'B': temp = dbuf[0]; if (temp < 16) { hcs12ss59t_set_brightness(temp); } else { ok = 0; } break; case 'p': if (dbuf[0] == '1') { FILAMENT_EN; hcs12ss59t_set_lights(HCS12SS59T_LINORM); } else if (dbuf[0] == '0') { FILAMENT_DIS; hcs12ss59t_set_lights(HCS12SS59T_LIOFF); } else if (dbuf[0] == 't') { FILAMENT_EN; hcs12ss59t_set_lights(HCS12SS59T_LION); } else { ok = 0; } break; case 'r': hcs12ss59t_set_text(" "); hcs12ss59t_reset(); break; case 'R': cli(); hcs12ss59t_set_text(" "); wdt_enable(WDTO_15MS); while (1); // WD Timeout -> CPU reset break; case 'C': hcs12ss59t_set_character(dbuf[0], dbuf+1, 1); break; case 'h': case '?': txs("text : t<12b ASCII>\r\n"); txs(" : T<12b RAW>\r\n"); txs("power : p<0/1>\r\n"); txs("brgn : b<0 - 15>\r\n"); txs("shift : s...\r\n"); txs(" : S...\r\n"); //txs("reset : r / R\r\n"); //txs("cgram : C<2b RAW>\r\n"); //txs("p-bar : xx enable progressbar\r\n"); //txs(" : x<00-60> <00-60>\r\n"); //txs(" : X<2b RAW>\r\n"); break; case 'x': if (dbuf[0] == 'x') { hcs12ss59t_set_progress(0, 0); hcs12ss59t_en_progress(); } else { hcs12ss59t_set_progress(atol(dbuf), atol(dbuf + 3)); } break; case 'X': hcs12ss59t_set_progress(dbuf[0], dbuf[1]); break; default: ok = 0; break; } if (ok) txs("OK."); else txs("ERR"); cmd = 0; byte_counter = 0; } txs("\r\n>"); } else { // ASCII character if (cmd == 0) { echo = 1; cmd = data; for (int i = 0; i < BUFSZ; ++i) { dbuf[i] = 0; } switch (cmd) { case 'T': cmax = BUFSZ; break; case 'B': cmax = 1; break; case 'C': cmax = 3; break; default: cmax = 0; break; } } else { if (cmd == 's' || cmd == 'S') { // Shift mode for (int i = 1; i < HCS12SS59T_NUMDIGITS; ++i) { dbuf[i - 1] = dbuf[i]; } dbuf[HCS12SS59T_NUMDIGITS - 1] = data; if (cmd == 's') hcs12ss59t_set_text(dbuf); else hcs12ss59t_set_buffer(dbuf); echo = 1; } else if (byte_counter < BUFSZ) { echo = 1; dbuf[byte_counter] = data; byte_counter++; } } } if (echo) TX(data); // Echo tx_read_ptr = (tx_read_ptr+1) & TX_MASK; if( usbAllRequestsAreDisabled() && uartTxBytesFree()>HW_CDC_BULK_OUT_SIZE ) { usbEnableAllRequests(); } } /* USB <= device */ if( usbInterruptIsReady() && (rx_write_ptr!=rx_read_ptr || sendEmptyFrame) ) { uchar bytesRead, i; bytesRead = (rx_write_ptr-rx_read_ptr) & RX_MASK; if(bytesRead>HW_CDC_BULK_IN_SIZE) bytesRead = HW_CDC_BULK_IN_SIZE; next = rx_read_ptr + bytesRead; if( next>=RX_SIZE ) { next &= RX_MASK; for( i=0; i