1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

* line ending change

This commit is contained in:
Kaspar Schleiser 2010-09-24 14:42:50 +02:00
parent bb67f8d88a
commit 8c45f4751c

View File

@ -1,205 +1,216 @@
/****************************************************************************** /******************************************************************************
Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved. Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de). and Telematics group (http://cst.mi.fu-berlin.de).
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
This file is part of FeuerWare. This file is part of FeuerWare.
This program is free software: you can redistribute it and/or modify it under This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later Foundation, either version 3 of the License, or (at your option) any later
version. version.
FeuerWare is distributed in the hope that it will be useful, but WITHOUT FeuerWare is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see http://www.gnu.org/licenses/ . this program. If not, see http://www.gnu.org/licenses/ .
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
For further information and questions please use the web site For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site) and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/ *******************************************************************************/
/* /*
* debug_uart.c: provides initial serial debug output * debug_uart.c: provides initial serial debug output
* *
* Copyright (C) 2008, 2009 Kaspar Schleiser <kaspar@schleiser.de> * Copyright (C) 2008, 2009 Kaspar Schleiser <kaspar@schleiser.de>
* Heiko Will <hwill@inf.fu-berlin.de> * Heiko Will <hwill@inf.fu-berlin.de>
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "lpc23xx.h" #include "lpc23xx.h"
#include "VIC.h" #include "VIC.h"
/** #include <msg.h>
* @file #include <ringbuffer.h>
* @ingroup lpc2387 #include "uart0.h"
*
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project /**
* @version $Revision$ * @file
* * @ingroup lpc2387
* @note $Id$ *
*/ * @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
* @version $Revision$
typedef struct toprint { *
unsigned int len; * @note $Id$
char content[]; */
}toprint;
typedef struct toprint {
#define QUEUESIZE 255 unsigned int len;
static volatile toprint* queue[QUEUESIZE]; char content[];
static volatile unsigned char queue_head = 0; }toprint;
static volatile unsigned char queue_tail = 0;
static volatile unsigned char queue_items = 0; #define QUEUESIZE 255
static volatile toprint* queue[QUEUESIZE];
static volatile unsigned int actual_pos = 0; static volatile unsigned char queue_head = 0;
static volatile unsigned int running = 0; static volatile unsigned char queue_tail = 0;
static volatile unsigned int fifo = 0; static volatile unsigned char queue_items = 0;
static volatile toprint* actual = NULL; static volatile unsigned int actual_pos = 0;
void (*uart0_callback)(int); static volatile unsigned int running = 0;
static volatile unsigned int fifo = 0;
static inline void enqueue(void) {
queue_items++; static volatile toprint* actual = NULL;
queue_tail++;
} int uart0_handler_pid = 0;
extern ringbuffer uart0_ringbuffer;
static inline void dequeue(void) {
actual = (queue[queue_head]); static inline void enqueue(void) {
queue_items--; queue_items++;
queue_head++; queue_tail++;
} }
static void push_queue(void) { static inline void dequeue(void) {
running = 1; actual = (queue[queue_head]);
start: queue_items--;
if (!actual) { queue_head++;
if (queue_items) { }
dequeue();
} else { static void push_queue(void) {
running = 0; running = 1;
if (!fifo) start:
while(!(U0LSR & BIT6)){}; if (!actual) {
return; if (queue_items) {
} dequeue();
} } else {
while ((actual_pos < actual->len) && (fifo++ < 16)){ running = 0;
U0THR = actual->content[actual_pos++]; if (!fifo)
} while(!(U0LSR & BIT6)){};
if (actual_pos == actual->len) { return;
free((void*)actual); }
actual = NULL; }
actual_pos = 0; while ((actual_pos < actual->len) && (fifo++ < 16)){
goto start; U0THR = actual->content[actual_pos++];
} }
} if (actual_pos == actual->len) {
free((void*)actual);
int uart_active(void){ actual = NULL;
return (running || fifo); actual_pos = 0;
} goto start;
}
static inline void receive(int c) }
{
if (uart0_callback != NULL) uart0_callback(c); int uart_active(void){
} return (running || fifo);
}
void stdio_flush(void)
{ static void notify_handler() {
U0IER &= ~BIT1; // disable THRE interrupt if (uart0_handler_pid) {
while(running) { msg m;
while(!(U0LSR & (BIT5|BIT6))){}; // transmit fifo m.type = 0;
fifo=0; msg_send_int(&m, uart0_handler_pid);
push_queue(); // dequeue to fifo }
} }
U0IER |= BIT1; // enable THRE interrupt
} void stdio_flush(void)
{
void UART0_IRQHandler(void) __attribute__((interrupt("IRQ"))); U0IER &= ~BIT1; // disable THRE interrupt
void UART0_IRQHandler(void) while(running) {
{ while(!(U0LSR & (BIT5|BIT6))){}; // transmit fifo
int iir; fifo=0;
iir = U0IIR; push_queue(); // dequeue to fifo
}
switch(iir & UIIR_ID_MASK) { U0IER |= BIT1; // enable THRE interrupt
case UIIR_THRE_INT: // Transmit Holding Register Empty }
fifo=0;
push_queue(); void UART0_IRQHandler(void) __attribute__((interrupt("IRQ")));
break; void UART0_IRQHandler(void)
{
case UIIR_CTI_INT: // Character Timeout Indicator int iir;
case UIIR_RDA_INT: // Receive Data Available iir = U0IIR;
do {
int c = U0RBR; switch(iir & UIIR_ID_MASK) {
receive(c); case UIIR_THRE_INT: // Transmit Holding Register Empty
} while (U0LSR & ULSR_RDR); fifo=0;
break; push_queue();
break;
default:
U0LSR; case UIIR_CTI_INT: // Character Timeout Indicator
U0RBR; case UIIR_RDA_INT: // Receive Data Available
break; do {
} // switch int c = U0RBR;
VICVectAddr = 0; // Acknowledge Interrupt rb_add_element(&uart0_ringbuffer, c);
} } while (U0LSR & ULSR_RDR);
static inline int uart0_puts(char *astring,int length) notify_handler();
{ break;
while (queue_items == (QUEUESIZE-1)) {} ;
U0IER = 0; default:
queue[queue_tail] = malloc(length+sizeof(unsigned int)); U0LSR;
queue[queue_tail]->len = length; U0RBR;
memcpy(&queue[queue_tail]->content,astring,length); break;
enqueue(); } // switch
if (!running) VICVectAddr = 0; // Acknowledge Interrupt
push_queue(); }
U0IER |= BIT0 | BIT1; // enable RX irq
static inline int uart0_puts(char *astring,int length)
/* alternative without queue: {
int i; while (queue_items == (QUEUESIZE-1)) {} ;
for (i=0;i<length;i++) { U0IER = 0;
while (!(U0LSR & BIT5)); queue[queue_tail] = malloc(length+sizeof(unsigned int));
U0THR = astring[i]; queue[queue_tail]->len = length;
} memcpy(&queue[queue_tail]->content,astring,length);
*/ enqueue();
if (!running)
return length; push_queue();
} U0IER |= BIT0 | BIT1; // enable RX irq
int fw_puts(char *astring,int length) /* alternative without queue:
{ int i;
return uart0_puts(astring, length); for (i=0;i<length;i++) {
} while (!(U0LSR & BIT5));
U0THR = astring[i];
int }
bl_uart_init(void) */
{
PCONP |= PCUART0; // power on return length;
}
// UART0 clock divider is CCLK/8
PCLKSEL0 |= BIT6 + BIT7; int fw_puts(char *astring,int length)
{
U0LCR = 0x83; // 8 bits, no Parity, 1 Stop bit return uart0_puts(astring, length);
}
// TODO: UART Baudrate calculation using uart->config->speed
/* int
* Baudrate calculation bl_uart_init(void)
* BR = PCLK (9 MHz) / (16 x 256 x DLM + DLL) x (1/(DIVADDVAL/MULVAL)) {
*/ PCONP |= PCUART0; // power on
U0FDR = 0x92; // DIVADDVAL = 0010 = 2, MULVAL = 1001 = 9
U0DLM = 0x00; // UART0 clock divider is CCLK/8
U0DLL = 0x04; PCLKSEL0 |= BIT6 + BIT7;
U0LCR = 0x03; // DLAB = 0 U0LCR = 0x83; // 8 bits, no Parity, 1 Stop bit
U0FCR = 0x07; // Enable and reset TX and RX FIFO
// TODO: UART Baudrate calculation using uart->config->speed
/* irq */ /*
install_irq(UART0_INT, UART0_IRQHandler, 6); * Baudrate calculation
U0IER |= BIT0 | BIT1; // enable RX+TX irq * BR = PCLK (9 MHz) / (16 x 256 x DLM + DLL) x (1/(DIVADDVAL/MULVAL))
return 1; */
} U0FDR = 0x92; // DIVADDVAL = 0010 = 2, MULVAL = 1001 = 9
U0DLM = 0x00;
U0DLL = 0x04;
U0LCR = 0x03; // DLAB = 0
U0FCR = 0x07; // Enable and reset TX and RX FIFO
/* irq */
install_irq(UART0_INT, UART0_IRQHandler, 6);
U0IER |= BIT0 | BIT1; // enable RX+TX irq
return 1;
}