diff --git a/msba2/drivers/Jamfile b/msba2/drivers/Jamfile index 79705aca0a..f7b223ce01 100644 --- a/msba2/drivers/Jamfile +++ b/msba2/drivers/Jamfile @@ -3,4 +3,4 @@ SubDir TOP board msba2 drivers ; Module board_cc1100 : msba2-cc1100.c ; Module board_hal : msba2-hal.c ; Module board_ltc4150 : msba2-ltc4150.c : gpioint ; -Module board_common : msba2-uart0.c ; +Module board_common : msba2-uart0.c msba2-uart0_thread.c : ringbuffer ; diff --git a/msba2/drivers/include/uart0.h b/msba2/drivers/include/uart0.h new file mode 100644 index 0000000000..0c580becc2 --- /dev/null +++ b/msba2/drivers/include/uart0.h @@ -0,0 +1,8 @@ +#ifndef __UART0_H +#define __UART0_H + +#define UART0_BUFSIZE 32 + +extern int uart0_handler_pid; + +#endif /* __UART0_H */ diff --git a/msba2/drivers/msba2-uart0_thread.c b/msba2/drivers/msba2-uart0_thread.c new file mode 100644 index 0000000000..c9c34c23d7 --- /dev/null +++ b/msba2/drivers/msba2-uart0_thread.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "uart0.h" + +//#define ENABLE_DEBUG +#include + +static char buffer[UART0_BUFSIZE]; +ringbuffer uart0_ringbuffer; + +static void uart0_loop(); + +void uart0_init() { + ringbuffer_init(&uart0_ringbuffer, buffer, UART0_BUFSIZE); + int pid = thread_create(KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN-1, CREATE_STACKTEST, uart0_loop, "uart0"); + uart0_handler_pid = pid; + puts("uart0_init() [OK]"); +} + +static int min(int a, int b) { + if (b>a) return a; + else return b; +} + +static void uart0_loop() { + msg m; + + int pid = thread_getpid(); + + int reader_pid = -1; + struct posix_iop *r = NULL; + + puts("UART0 thread started."); + + while (1) { + msg_receive(&m); + + if (m.sender_pid == pid) { + } else { + switch (m.type) { + case OPEN: + if (reader_pid == -1) { + reader_pid = m.sender_pid; + m.content.value = 0; // no error + } else { + m.content.value = -EBUSY; + } + msg_reply(&m,&m); + break; + case READ: + if (m.sender_pid != reader_pid) { + m.content.value = -EINVAL; + msg_reply(&m, &m); + } else { + r = (struct posix_iop *)m.content.ptr; + } + break; + case CLOSE: + if (m.sender_pid == reader_pid) { + DEBUG("uart0_thread: closing file from %i\n", reader_pid); + reader_pid = -1; + r = NULL; + m.content.value = 0; + } else { + m.content.value = -EINVAL; + } + msg_reply(&m,&m); + break; + default: + m.content.value = -EINVAL; + msg_reply(&m, &m); + } + } + + if (uart0_ringbuffer.avail && (r != NULL)) { + int state = disableIRQ(); + int nbytes = min(r->nbytes, uart0_ringbuffer.avail); + DEBUG("uart0_thread: sending %i bytes to pid %i\n", nbytes, reader_pid); + rb_get_elements(&uart0_ringbuffer, r->buffer, nbytes); + r->nbytes = nbytes; + + m.sender_pid = reader_pid; + m.type = OPEN; + m.content.ptr = (char*)r; + + msg_reply(&m, &m); + // DEBUG("uart0_thread: sending res=%i\n", res); + + r = NULL; + restoreIRQ(state); + } + } +}