main.c
Go to the documentation of this file.
00001 /*
00002         Aseba - an event-based framework for distributed robot control
00003         Copyright (C) 2007--2010:
00004                 Stephane Magnenat <stephane at magnenat dot net>
00005                 (http://stephane.magnenat.net)
00006                 and other contributors, see authors.txt for details
00007         
00008         This program is free software: you can redistribute it and/or modify
00009         it under the terms of the GNU Lesser General Public License as published
00010         by the Free Software Foundation, version 3 of the License.
00011         
00012         This program is distributed in the hope that it will be useful,
00013         but WITHOUT ANY WARRANTY; without even the implied warranty of
00014         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015         GNU Lesser General Public License for more details.
00016         
00017         You should have received a copy of the GNU Lesser General Public License
00018         along with this program. If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "hardware.h"
00022 #include <transport/can/can-net.h>
00023 #include <common/consts.h>
00024 #include <can/can.h>
00025 #include <dma/dma.h>
00026 #include <gpio/gpio.h>
00027 #include <uart/uart-software-fc.h>
00028 #include <clock/clock.h>
00029 #include <error/error.h>
00030 #include <types/types.h>
00031 #include <timer/timer.h>
00032 #include <ei/ei.h>
00033 #include <adc/adc.h>
00034 
00035 #include "morse.h"
00036 
00037 
00038 _FWDT(FWDTEN_OFF);              // Watchdog Timer disabled
00039 _FOSCSEL(FNOSC_FRCPLL); // override oscillator configuration bits
00040 _FOSC(POSCMD_NONE & OSCIOFNC_ON);
00041 // ICD communicates on PGC1/EMUC1 and disable JTAG
00042 _FICD(ICS_PGD1 & JTAGEN_OFF);
00043 
00044 #define PRIO_CAN 5
00045 #define PRIO_UART 5
00046 #define PRIO_UART_TH 6
00047 
00048 #define TIMER_UART TIMER_1
00049 
00050 /* buffers for can-net */
00051 #define SEND_QUEUE_SIZE 260
00052 static  __attribute((far)) CanFrame sendQueue[SEND_QUEUE_SIZE];
00053 #define RECV_QUEUE_SIZE 1100
00054 static  __attribute((far)) CanFrame recvQueue[RECV_QUEUE_SIZE];
00055 
00056 /* buffers for uart */
00057 static __attribute((far)) __attribute((aligned(2))) unsigned char uartSendBuffer[ASEBA_MAX_OUTER_PACKET_SIZE];
00058 static unsigned uartSendPos;
00059 static unsigned uartSendSize;
00060 static __attribute((far))  __attribute((aligned(2))) unsigned char uartRecvBuffer[ASEBA_MAX_OUTER_PACKET_SIZE];
00061 static unsigned uartRecvPos;
00062 
00063 
00064 
00065 volatile int global_flag = 0;
00066 
00067 #define OUTPUT_ERROR(err)  do{ for(;;) output_error(err,LED0,0,1); }while(0)
00068 
00069 static void can_tx_cb(void)
00070 {
00071         if(global_flag)
00072                 OUTPUT_ERROR(global_flag);
00073         global_flag = 1;
00074 
00075         AsebaCanFrameSent();
00076         
00077         // A message is waiting on the uart (it's complete but still waiting because we were full)
00078         // Check if we can send it now
00079         if ((uartRecvPos >= 6) && (uartRecvPos == 6 + ((uint16 *)uartRecvBuffer)[0])) 
00080         {
00081                 uint16 source = ((uint16 *)uartRecvBuffer)[1];
00082                 if (AsebaCanSendSpecificSource(uartRecvBuffer+4, uartRecvPos-4, source) == 1)
00083                 {
00084                         uartRecvPos = 0;
00085                         uart_read_pending_data(U_UART);
00086                 } 
00087         }
00088         global_flag = 0;
00089 }
00090 
00091 static void can_rx_cb(const can_frame* frame)
00092 {
00093         if(global_flag)
00094                 OUTPUT_ERROR(global_flag);
00095         global_flag = 2;
00096         
00097         // we do a nasty cast because the two data structure are compatible, i.e. they have the same leading members
00098         AsebaCanFrameReceived((CanFrame *) frame);
00099         
00100         uint16 source;
00101                 
00102         if(uartSendPos == uartSendSize) 
00103         {
00104                 int amount = AsebaCanRecv(uartSendBuffer+4, ASEBA_MAX_INNER_PACKET_SIZE, &source);
00105                 if (amount > 0)
00106                 {
00107                         ((uint16 *)uartSendBuffer)[0] = (uint16)amount - 2;
00108                         ((uint16 *)uartSendBuffer)[1] = source;
00109                         uartSendSize = (unsigned)amount + 4;
00110 
00111                         if(uart_transmit_byte(U_UART, uartSendBuffer[0]))
00112                                 uartSendPos = 1;
00113                         else
00114                                 uartSendPos = 0;
00115                 }
00116         }
00117         global_flag = 0;
00118         
00119 }
00120 
00121 static bool uart_rx_cb(int __attribute((unused)) uart_id, unsigned char data, void * __attribute((unused)) user_data)
00122 {
00123         if(global_flag)
00124                 OUTPUT_ERROR(global_flag);
00125         global_flag = 3;
00126         
00127         // TODO: in case of bug, we might want to test for overflow here, but it should never happen if higher layer conform to specification
00128         uartRecvBuffer[uartRecvPos++] = data;
00129         
00130         // if we have received the header and all the message payload data forward it to the can layer
00131         if ((uartRecvPos >= 6) && (uartRecvPos == 6 + ((uint16 *)uartRecvBuffer)[0])) 
00132         {
00133                         
00134                 uint16 source = ((uint16 *)uartRecvBuffer)[1];
00135                 if (AsebaCanSendSpecificSource(uartRecvBuffer+4, uartRecvPos-4, source) == 1)
00136                 {
00137                         // Was able to queue frame to can layer. Setup the buffer pointer for next reception
00138                         uartRecvPos = 0;
00139                         global_flag = 0;
00140                         return true;
00141                 } else {
00142                         // Stop reception, flow control will help us to not lose any packet
00143                         global_flag = 0;
00144                         return false;
00145                 }
00146         }
00147         global_flag = 0;
00148         return true;
00149 }
00150 
00151 static bool uart_tx_cb(int __attribute((unused)) uart_id, unsigned char* data, void*  __attribute((unused)) user_data)
00152 {
00153         if(global_flag)
00154                 OUTPUT_ERROR(global_flag);
00155         global_flag = 4;
00156         
00157         if (uartSendPos < uartSendSize)
00158         {
00159                 *data = uartSendBuffer[uartSendPos++];
00160                 global_flag = 0;
00161                 return true;
00162         }
00163         else
00164         {
00165                 // We finished sending the previous packet
00166         
00167                 // ...and if there is a new message on CAN, read it
00168                 uint16 source;
00169                         
00170                 int amount = AsebaCanRecv(uartSendBuffer+4, ASEBA_MAX_INNER_PACKET_SIZE, &source);
00171                 if (amount > 0)
00172                 {
00173                         ((uint16 *)uartSendBuffer)[0] = (uint16)amount - 2;
00174                         ((uint16 *)uartSendBuffer)[1] = source;
00175                         uartSendSize = (unsigned)amount + 4;
00176                         uartSendPos = 1;
00177                         *data = uartSendBuffer[0];
00178                         global_flag = 0;
00179                         return true;
00180                 }
00181         
00182                 global_flag = 0;
00183                 return false;
00184         }
00185 }
00186 
00187 void AsebaIdle(void) {
00188         // Should NEVER be called
00189         OUTPUT_ERROR(5);
00190 }
00191 
00192 uint16 AsebaShouldDropPacket(uint16 source, const uint8* data) {
00193         return 0;
00194 }       
00195 
00196 static void received_packet_dropped(void)
00197 {
00198         // light a LED, we have dropped an aseba message from the CAN because we were not able to send previous ones fast enough on UART
00199         gpio_write(LED1, 0);
00200 }
00201 
00202 static void sent_packet_dropped(void)
00203 {
00204         // light a LED, the packet is in fact not dropped because UART has flow control and the translator will try again later
00205         gpio_write(LED1, 0);
00206 }
00207 
00208 void __attribute__((noreturn)) error_handler(const char __attribute((unused))  * file, int __attribute((unused)) line, int id, void* __attribute((unused)) arg) {
00209         OUTPUT_ERROR(id);       
00210 }
00211 
00212 /* initialization and main loop */
00213 int main(void)
00214 {
00215         int i;
00216                         
00217         if(_POR) {
00218                 _POR = 0;
00219                 asm __volatile("reset");
00220         }
00221         
00222         clock_init_internal_rc_30();
00223         
00224         // Wait about 1 s before really starting. The Bluetooth chip need a LOT of time before 
00225         // having stable output (else we recieve "Phantom" character on uart)
00226         
00227         for(i = 0; i < 1000; i++) 
00228                 clock_delay_us(1000);
00229         
00230         gpio_write(LED0, 1);
00231         gpio_write(LED1, 1);
00232         gpio_set_dir(LED0, GPIO_OUTPUT);
00233         gpio_set_dir(LED1, GPIO_OUTPUT);
00234 
00235         error_register_callback(error_handler);
00236 
00237 
00238         adc1_init_simple(NULL, 1, 0x0UL, 30);
00239         
00240         can_init(can_rx_cb, can_tx_cb, DMA_CHANNEL_0, DMA_CHANNEL_1, CAN_SELECT_MODE, 1000, PRIO_CAN);
00241         uart_init(U_UART, 921600, UART_CTS, UART_RTS, TIMER_UART, uart_rx_cb, uart_tx_cb, PRIO_UART_TH, PRIO_UART, NULL);
00242 
00243         AsebaCanInit(0, (AsebaCanSendFrameFP)can_send_frame, can_is_frame_room, received_packet_dropped, sent_packet_dropped, sendQueue, SEND_QUEUE_SIZE, recvQueue, RECV_QUEUE_SIZE);
00244 
00245         
00246         while (1)
00247         {
00248                 // Sleep until something happens
00249                 Idle();
00250         };
00251 }
00252 


aseba
Author(s): Stéphane Magnenat
autogenerated on Sun Oct 5 2014 23:46:38