summaryrefslogtreecommitdiff
path: root/firmware/uart_fifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/uart_fifo.c')
-rw-r--r--firmware/uart_fifo.c368
1 files changed, 368 insertions, 0 deletions
diff --git a/firmware/uart_fifo.c b/firmware/uart_fifo.c
new file mode 100644
index 0000000..d4da869
--- /dev/null
+++ b/firmware/uart_fifo.c
@@ -0,0 +1,368 @@
+#include <inttypes.h>
+#include <avr/io.h>
+
+#include "uart.h"
+#include "common.h"
+#include "protocol.h"
+#include "fifo.h"
+
+#define BUFSIZE_IN 5
+#define BUFSIZE_OUT 5
+
+uint8_t inbuf0[BUFSIZE_IN];
+uint8_t inbuf1[BUFSIZE_IN];
+fifo_t infifo0;
+fifo_t infifo1;
+
+uint8_t outbuf1[BUFSIZE_OUT];
+uint8_t outbuf0[BUFSIZE_OUT];
+fifo_t outfifo0;
+fifo_t outfifo1;
+
+
+void uart_parser(char *buf)
+{
+ answer[0] = buf[0];
+
+ switch(buf[0])
+ {
+ case CMD_UART_INIT:
+ uart_init_usb((char)buf[2]);
+ break;
+ case CMD_UART_DEINIT:
+ uart_deinit_usb((char)buf[2]);
+ break;
+
+ case CMD_UART_BAUDRATE:
+ uart_baudrate_usb((char)buf[2], (char)buf[3], (char)buf[4], (char)buf[5], (char)buf[6]);
+ break;
+ case CMD_UART_STOPBITS:
+ uart_stopbits_usb((char)buf[2], (char)buf[3]);
+ break;
+ case CMD_UART_DATABITS:
+ uart_stopbits_usb((char)buf[2], (char)buf[3]);
+ break;
+ case CMD_UART_PARITY:
+ uart_parity_usb((char)buf[2], (char)buf[3]);
+ break;
+
+ case CMD_UART_SEND:
+ uart_send_usb((char)buf[2], (char)buf[3], &buf[4]);
+ break;
+ case CMD_UART_RECV:
+ uart_recv_usb((char)buf[2], (char)buf[3]);
+ break;
+ default:
+ answer[1] = RSP_UNKOWN_CMD;
+ answer[2] = 0;
+ CommandAnswer(3);
+ }
+}
+
+void uart_init_usb(char uartport)
+{
+ answer[1] = (unsigned char)uart_init(uartport);
+ answer[2] = 0;
+
+ CommandAnswer(3);
+}
+
+char uart_init(char uartport)
+{
+ switch(uartport)
+ {
+ case 0:
+ octopus.ports[41] = PIN_UART;
+ octopus.ports[42] = PIN_UART;
+ /* enable transmitter receiver */
+ UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
+ break;
+ case 1:
+ octopus.ports[14] = PIN_UART;
+ octopus.ports[15] = PIN_UART;
+ /* enable transmitter receiver */
+ UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);
+ break;
+ default:
+ return RSP_UNKOWN_PIN;
+ }
+
+ return RSP_OK;
+}
+
+void uart_deinit_usb(char uartport)
+{
+ answer[1] = (unsigned char)uart_deinit(uartport);
+ answer[2] = 0;
+
+ CommandAnswer(3);
+}
+
+char uart_deinit(char uartport)
+{
+ switch(uartport)
+ {
+ case 0:
+ octopus.ports[41] = PIN_NONE;
+ octopus.ports[42] = PIN_NONE;
+ UBRR0H = 0;
+ UBRR0L = 0;
+ UCSR0B = 0;
+ UCSR0C = 0;
+ break;
+ case 1:
+ octopus.ports[14] = PIN_NONE;
+ octopus.ports[15] = PIN_NONE;
+ UBRR1H = 0;
+ UBRR1L = 0;
+ UCSR1B = 0;
+ UCSR1C = 0;
+ break;
+ default:
+ return RSP_UNKOWN_PIN;
+ }
+
+ return RSP_OK;
+}
+
+void uart_baudrate_usb(char uartport, char ubrrll, char ubrrlh, char ubrrhl, char ubrrhh)
+{
+ answer[1] = (unsigned char)uart_baudrate(uartport, ubrrll, ubrrlh, ubrrhl, ubrrhh);
+ answer[2] = 0;
+
+ CommandAnswer(3);
+}
+
+char uart_baudrate(char uartport, char ubrrll, char ubrrlh, char ubrrhl, char ubrrhh)
+{
+ switch(uartport)
+ {
+ case 0:
+ UBRR0H = (ubrrhh << 8) | ubrrhl;
+ UBRR0L = (ubrrhl << 8) | ubrrll;
+ break;
+ case 1:
+ UBRR1H = (ubrrhh << 8) | ubrrhl;
+ UBRR1L = (ubrrhl << 8) | ubrrll;
+ break;
+ default:
+ return RSP_UNKOWN_PIN;
+ }
+
+ return RSP_OK;
+}
+
+void uart_stopbits_usb(char uartport, char stopbits)
+{
+ answer[1] = (unsigned char)uart_stopbits(uartport, stopbits);
+ answer[2] = 0;
+
+ CommandAnswer(3);
+}
+
+char uart_stopbits(char uartport, char stopbits)
+{
+ char usbs;
+
+ switch(stopbits)
+ {
+ case 1: usbs = 0; break;
+ case 2: usbs = 2; break;
+ default: usbs = 0; break;
+ }
+
+ switch(uartport)
+ {
+ case 0:
+ UCSR0C |= (usbs << USBS0);
+ break;
+ case 1:
+ UCSR1C |= (usbs << USBS1);
+ break;
+ default:
+ return RSP_UNKOWN_PIN;
+ }
+
+ return RSP_OK;
+}
+
+void uart_databits_usb(char uartport, char databits)
+{
+ answer[1] = (unsigned char)uart_databits(uartport, databits);
+ answer[2] = 0;
+
+ CommandAnswer(3);
+}
+
+char uart_databits(char uartport, char databits)
+{
+ char ucsz1,ucsz0;
+
+ switch(databits) {
+ case 5: ucsz1 = 0; ucsz0 = 0; break;
+ case 6: ucsz1 = 0; ucsz0 = 1; break;
+ case 7: ucsz1 = 1; ucsz0 = 0; break;
+ case 8: ucsz1 = 1; ucsz0 = 1; break;
+ default: ucsz1 = 1; ucsz0 = 1; break;
+ }
+
+ switch(uartport)
+ {
+ case 0:
+ UCSR0C |= (ucsz1 << UCSZ01) | (ucsz0 << UCSZ00);
+ break;
+ case 1:
+ UCSR1C |= (ucsz1 << UCSZ11) | (ucsz0 << UCSZ10);
+ break;
+ default:
+ return RSP_UNKOWN_PIN;
+ }
+
+ return RSP_OK;
+}
+
+void uart_parity_usb(char uartport, char parity)
+{
+ answer[1] = (unsigned char)uart_databits(uartport, parity);
+ answer[2] = 0;
+
+ CommandAnswer(3);
+}
+
+char uart_parity(char uartport, char parity)
+{
+ char upm1, upm0;
+ switch(parity)
+ {
+ case 'N': upm1 = 0; upm0 = 0; break;
+ case 'E': upm1 = 1; upm0 = 0; break;
+ case 'O': upm1 = 1; upm0 = 1; break;
+ default: upm1 = 0; upm0 = 0; break;
+ }
+
+ switch(uartport)
+ {
+ case 0:
+ UCSR0C |= (upm1 << UPM01) | (upm0 << UPM00);
+ break;
+ case 1:
+ UCSR1C |= (upm1 << UPM11) | (upm0 << UPM10);
+ break;
+ default:
+ return RSP_UNKOWN_PIN;
+ }
+
+ return RSP_OK;
+}
+
+void uart_send_usb(char uartport, char length, char *buf)
+{
+ answer[1] = (unsigned char)uart_send(uartport, length, buf);
+ answer[2] = 0;
+
+ CommandAnswer(3);
+}
+
+
+char uart_send(char uartport, unsigned int length, char *buf)
+{
+ if(uartport != 0 && uartport != 1)
+ return RSP_UNKOWN_PIN;
+
+ while(length--)
+ uart_putchar(uartport, *buf++);
+
+ return RSP_OK;
+}
+
+char uart_putchar(char uartport, char data)
+{
+ switch(uartport)
+ {
+ case 0:
+ fifo_put (&outfifo0, data);
+ UCSR0B |= (1 << UDRIE0);
+ break;
+ case 1:
+ fifo_put (&outfifo1, data);
+ UCSR1B |= (1 << UDRIE1);
+ break;
+ default:
+ return RSP_UNKOWN_PIN;
+ }
+
+ return RSP_OK;
+}
+
+
+void uart_recv_usb(char uartport, int length)
+{
+ char data[length];
+ int i;
+
+ answer[1] = (char)uart_recv(uartport, data, length);
+
+ for(i = 0; i < length; i++)
+ answer[2+i] = data[i];
+
+ answer[2+length] = 0;
+
+ CommandAnswer(3+length);
+}
+
+char uart_recv(char uartport, char * buf, int length)
+{
+ if(uartport != 0 && uartport != 1)
+ return RSP_UNKOWN_PIN;
+
+ while(length-- > 0)
+ *buf++ = uart_getchar(uartport);
+
+ return RSP_OK;
+}
+
+char uart_getchar(char uartport)
+{
+ char c;
+
+ switch(uartport)
+ {
+ case 0:
+ while (!(UCSR0A & (1 << RXC0)));
+ c = UDR0;
+ break;
+ case 1:
+ while (!(UCSR1A & (1 << RXC1)));
+ c = UDR1;
+ break;
+ default:
+ return RSP_UNKOWN_PIN;
+ }
+
+ return c;
+}
+
+// Empfangene Zeichen werden in die Eingabgs-FIFO gespeichert und warten dort
+//SIGNAL (SIG_UART0_RECV)
+//{
+// _inline_fifo_put (&infifo0, UDR0);
+//}
+
+// Ein Zeichen aus der Ausgabe-FIFO lesen und ausgeben
+// Ist das Zeichen fertig ausgegeben, wird ein neuer SIG_UART_DATA-IRQ getriggert
+// Ist die FIFO leer, deaktiviert die ISR ihren eigenen IRQ.
+SIGNAL (SIG_UART0_DATA)
+{
+ PORTC ^= 5;
+ if (outfifo0.count > 0)
+ {
+ PORTC ^= 2;
+ UDR0 = _inline_fifo_get (&outfifo0);
+ }
+ else
+ {
+ PORTC ^= 3;
+ UCSR0B &= ~(1 << UDRIE0);
+ }
+}
+