UAVX Multicopter Flight Controller.

Dependencies:   mbed

Committer:
gke
Date:
Tue Apr 26 12:12:29 2011 +0000
Revision:
2:90292f8bd179
Parent:
0:62a1c91a859a
Not flightworthy. Posted for others to make use of the I2C SW code.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gke 0:62a1c91a859a 1 /*
gke 0:62a1c91a859a 2 Copyright (c) 2010 Andy Kirkham
gke 0:62a1c91a859a 3
gke 0:62a1c91a859a 4 Permission is hereby granted, free of charge, to any person obtaining a copy
gke 0:62a1c91a859a 5 of this software and associated documentation files (the "Software"), to deal
gke 0:62a1c91a859a 6 in the Software without restriction, including without limitation the rights
gke 0:62a1c91a859a 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
gke 0:62a1c91a859a 8 copies of the Software, and to permit persons to whom the Software is
gke 0:62a1c91a859a 9 furnished to do so, subject to the following conditions:
gke 0:62a1c91a859a 10
gke 0:62a1c91a859a 11 The above copyright notice and this permission notice shall be included in
gke 0:62a1c91a859a 12 all copies or substantial portions of the Software.
gke 0:62a1c91a859a 13
gke 0:62a1c91a859a 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
gke 0:62a1c91a859a 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
gke 0:62a1c91a859a 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
gke 0:62a1c91a859a 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
gke 0:62a1c91a859a 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
gke 0:62a1c91a859a 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
gke 0:62a1c91a859a 20 THE SOFTWARE.
gke 0:62a1c91a859a 21 */
gke 0:62a1c91a859a 22
gke 0:62a1c91a859a 23
gke 0:62a1c91a859a 24 #include "mbed.h"
gke 0:62a1c91a859a 25
gke 0:62a1c91a859a 26 #ifndef SERIALBUFFERED_C
gke 0:62a1c91a859a 27 #define SERIALBUFFERED_C
gke 0:62a1c91a859a 28 #endif
gke 0:62a1c91a859a 29
gke 0:62a1c91a859a 30 #include "SerialBuffered.h"
gke 0:62a1c91a859a 31 #include "sb_globals.h"
gke 0:62a1c91a859a 32
gke 0:62a1c91a859a 33 enum { None, One, Two };
gke 0:62a1c91a859a 34 enum { WordLength5, WordLength6, WordLength7, WordLength8 };
gke 0:62a1c91a859a 35 enum { NoParity, OddParity, EvenParity, Forced1, Forced0 };
gke 0:62a1c91a859a 36 enum { StopBit1, StopBit2 };
gke 0:62a1c91a859a 37
gke 0:62a1c91a859a 38 SerialBuffered::SerialBuffered(PinName tx, PinName rx) : Serial(tx, rx) {
gke 0:62a1c91a859a 39
gke 0:62a1c91a859a 40 // Depending upon the pins used, set-up the Uart.
gke 0:62a1c91a859a 41 if (tx == p9 || rx == p10) {
gke 0:62a1c91a859a 42 uart_number = 3;
gke 0:62a1c91a859a 43 uart_base = LPC_UART3_BASE;
gke 0:62a1c91a859a 44 set_uart3(tx, rx);
gke 0:62a1c91a859a 45 }
gke 0:62a1c91a859a 46 else if (tx == p13 || tx == p26 || rx == p14 || rx == p25) {
gke 0:62a1c91a859a 47 uart_number = 1;
gke 0:62a1c91a859a 48 uart_base = LPC_UART1_BASE;
gke 0:62a1c91a859a 49 set_uart1(tx, rx);
gke 0:62a1c91a859a 50 }
gke 0:62a1c91a859a 51 else if (tx == p28 || rx == p27) {
gke 0:62a1c91a859a 52 uart_number = 2;
gke 0:62a1c91a859a 53 uart_base = LPC_UART2_BASE;
gke 0:62a1c91a859a 54 set_uart2(tx, rx);
gke 0:62a1c91a859a 55 }
gke 0:62a1c91a859a 56 else if (tx == USBTX || rx == USBRX) {
gke 0:62a1c91a859a 57 uart_number = 0;
gke 0:62a1c91a859a 58 uart_base = LPC_UART0_BASE;
gke 0:62a1c91a859a 59 set_uart0(tx, rx);
gke 0:62a1c91a859a 60 }
gke 0:62a1c91a859a 61 else {
gke 0:62a1c91a859a 62 uart_number = -1;
gke 0:62a1c91a859a 63 return;
gke 0:62a1c91a859a 64 }
gke 0:62a1c91a859a 65 }
gke 0:62a1c91a859a 66
gke 0:62a1c91a859a 67 SerialBuffered::~SerialBuffered() {
gke 0:62a1c91a859a 68 if (_tx_buffer_used_malloc[uart_number] && _tx_buffer[uart_number]) free(_tx_buffer[uart_number]);
gke 0:62a1c91a859a 69 if (_rx_buffer_used_malloc[uart_number] && _rx_buffer[uart_number]) free(_rx_buffer[uart_number]);
gke 0:62a1c91a859a 70 }
gke 0:62a1c91a859a 71
gke 0:62a1c91a859a 72 /** SerialBuffered_ISR
gke 0:62a1c91a859a 73 *
gke 0:62a1c91a859a 74 * The main Uart interrupt handler.
gke 0:62a1c91a859a 75 */
gke 0:62a1c91a859a 76 extern "C" void SerialBuffered_ISR(unsigned long uart_base, int uart_number) {
gke 0:62a1c91a859a 77 char c __attribute__((unused));
gke 0:62a1c91a859a 78 volatile uint32_t iir, lsr;
gke 0:62a1c91a859a 79
gke 0:62a1c91a859a 80 iir = GET_REGISTER(SERIALBUFFERED_IIR);
gke 0:62a1c91a859a 81
gke 0:62a1c91a859a 82 if (iir & 1) {
gke 0:62a1c91a859a 83 return; /* Eh, wtf? */
gke 0:62a1c91a859a 84 }
gke 0:62a1c91a859a 85
gke 0:62a1c91a859a 86 iir = (iir >> 1) & 0x3;
gke 0:62a1c91a859a 87
gke 0:62a1c91a859a 88 if (iir == 2) {
gke 0:62a1c91a859a 89 while(GET_REGISTER(SERIALBUFFERED_LSR) & 0x1) {
gke 0:62a1c91a859a 90 if (_rx_buffer_in[uart_number] == _rx_buffer_out[uart_number] && _rx_buffer_full[uart_number]) {
gke 0:62a1c91a859a 91 c = GET_REGISTER(SERIALBUFFERED_RBR); /* Oh dear, we need a bigger buffer!, send to dev/null */
gke 0:62a1c91a859a 92 _rx_buffer_overflow[uart_number] = true;
gke 0:62a1c91a859a 93 }
gke 0:62a1c91a859a 94 else {
gke 0:62a1c91a859a 95 if (_rx_buffer[uart_number]) { /* Ensure buffer pointer is not null before use. */
gke 0:62a1c91a859a 96 c = GET_REGISTER(SERIALBUFFERED_RBR);
gke 0:62a1c91a859a 97 _rx_buffer[uart_number][_rx_buffer_in[uart_number]++] = c;
gke 0:62a1c91a859a 98 if (_rx_buffer_in[uart_number] >= _rx_buffer_size[uart_number]) _rx_buffer_in[uart_number] = 0;
gke 0:62a1c91a859a 99 if (_rx_buffer_in[uart_number] == _rx_buffer_out[uart_number]) _rx_buffer_full[uart_number] = true;
gke 0:62a1c91a859a 100 }
gke 0:62a1c91a859a 101 }
gke 0:62a1c91a859a 102 }
gke 0:62a1c91a859a 103 }
gke 0:62a1c91a859a 104
gke 0:62a1c91a859a 105 if (iir == 1) {
gke 0:62a1c91a859a 106 if (_tx_buffer[uart_number]) { /* Ensure buffer pointer is not null before use. */
gke 0:62a1c91a859a 107 if (_tx_buffer_in[uart_number] != _tx_buffer_out[uart_number] || _tx_buffer_full[uart_number]) {
gke 0:62a1c91a859a 108 SET_REGISTER(SERIALBUFFERED_THR, (uint32_t)(_tx_buffer[uart_number][_tx_buffer_out[uart_number]++]));
gke 0:62a1c91a859a 109 if (_tx_buffer_out[uart_number] >= _tx_buffer_size[uart_number]) _tx_buffer_out[uart_number] = 0;
gke 0:62a1c91a859a 110 _tx_buffer_full[uart_number] = false;
gke 0:62a1c91a859a 111 }
gke 0:62a1c91a859a 112 else {
gke 0:62a1c91a859a 113 SET_REGISTER(SERIALBUFFERED_IER, 1);
gke 0:62a1c91a859a 114 }
gke 0:62a1c91a859a 115 }
gke 0:62a1c91a859a 116 }
gke 0:62a1c91a859a 117
gke 0:62a1c91a859a 118 if (iir == 3) {
gke 0:62a1c91a859a 119 /* We need to provide an error handling system. For now, just dismiss the IRQ. */
gke 0:62a1c91a859a 120 lsr = GET_REGISTER(SERIALBUFFERED_LSR);
gke 0:62a1c91a859a 121 }
gke 0:62a1c91a859a 122 }
gke 0:62a1c91a859a 123