210 lines
4.8 KiB
C
Executable File
210 lines
4.8 KiB
C
Executable File
/* 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 <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/pgmspace.h> /* needed by usbdrv.h */
|
|
#include "oddebug.h"
|
|
#include "usbdrv.h"
|
|
#include "uart.h"
|
|
#include "hcs12ss59t/hcs12ss59t.h"
|
|
#include <stdlib.h>
|
|
#include <avr/wdt.h>
|
|
|
|
#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];
|
|
|
|
void uartInit(ulong baudrate, uchar parity, uchar stopbits, uchar databits)
|
|
{
|
|
usbDWord_t br;
|
|
|
|
br.dword = ((F_CPU>>3)+(baudrate>>1)) / baudrate - 1;
|
|
UCSR0A |= (1<<U2X0);
|
|
|
|
#if DEBUG_LEVEL < 1
|
|
/* USART configuration */
|
|
UCSR0B = 0;
|
|
UCSR0C = URSEL_MASK | ((parity==1? 3:parity)<<UPM00) | ((stopbits>>1)<<USBS0) | ((databits-5)<<UCSZ00);
|
|
UBRR0L = br.bytes[0];
|
|
UBRR0H = br.bytes[1];
|
|
#else
|
|
DBG1(0xf0, br.bytes, 2);
|
|
#endif /* DEBUG_LEVEL */
|
|
|
|
}
|
|
|
|
void txs(char *string)
|
|
{
|
|
while (*string) {
|
|
TX(*string);
|
|
string++;
|
|
}
|
|
}
|
|
|
|
void uartPoll(void)
|
|
{
|
|
uchar next;
|
|
uchar data;
|
|
uchar temp;
|
|
int echo = 0;
|
|
int ok = 1;
|
|
|
|
while(tx_write_ptr!=tx_read_ptr) {
|
|
data = tx_buf[tx_read_ptr];
|
|
if ((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 '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<ASCII>...\r\n");
|
|
txs(" : S<RAW>...\r\n");
|
|
//txs("reset : r / R\r\n");
|
|
break;
|
|
default:
|
|
ok = 0;
|
|
break;
|
|
}
|
|
|
|
if (ok)
|
|
txs("OK.");
|
|
else
|
|
txs("ERR");
|
|
|
|
cmd = 0;
|
|
byte_counter = 0;
|
|
}
|
|
if (data = '\n')
|
|
txs("\r\n>");
|
|
} else { // ASCII character
|
|
if (cmd == 0) {
|
|
echo = 1;
|
|
cmd = data;
|
|
for (int i = 0; i < BUFSZ; ++i) {
|
|
dbuf[i] = 0;
|
|
}
|
|
|
|
} else {
|
|
if (cmd == 's' || cmd == 'S') {
|
|
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<next; i++ )
|
|
rx_buf[RX_SIZE+i] = rx_buf[i];
|
|
}
|
|
usbSetInterrupt(rx_buf+rx_read_ptr, bytesRead);
|
|
rx_read_ptr = next;
|
|
if( bytesRead ) {
|
|
// UART_CTRL_PORT |= (1<<UART_CTRL_RTS);
|
|
}
|
|
|
|
/* send an empty block after last data block to indicate transfer end */
|
|
sendEmptyFrame = (bytesRead==HW_CDC_BULK_IN_SIZE && rx_write_ptr==rx_read_ptr)? 1:0;
|
|
}
|
|
}
|
|
|