target/unix/asuro_unix.c

Go to the documentation of this file.
00001 /**@file 
00002  * 
00003  * This part attempts to simulate the ATmega8 pin port interface under UNIX.
00004  * 
00005  * @author Denis Martin
00006  * 
00007  * This program is free software; you can redistribute it and/or modify it under
00008  * the terms of the GNU General Public License as published by the Free Software
00009  * Foundation; either version 2 of the License, or (at your option) any later
00010  * version.
00011  * This program is distributed in the hope that it will be useful, but WITHOUT
00012  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
00014  * details. You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation, Inc.,
00016  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018  
00019 #include "asuro_unix.h"
00020 #include "asuro_unix_decode.h"
00021 #include "asuro_defs.h"
00022 
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <signal.h>
00027 #include <sys/time.h>
00028 #include <sys/resource.h>
00029 #include <sys/types.h>
00030 #include <unistd.h>
00031 
00032 volatile int AS_unix_alarmCount = 0;
00033 volatile double AS_unix_simTime = 0.0;
00034 volatile int AS_unix_ioLock = 0;
00035 
00036 /**
00037  * Call SIG_OUTPUT_COMPARE2 ISR and evaulate IO vector.
00038  */
00039 void AS_unix_sh_SIGALRM(int signo, siginfo_t *info, void *context) 
00040 {
00041     if (signo == SIGALRM) {
00042         int i;
00043         for (i = 0; i < 255; i++) {
00044             SIG_OUTPUT_COMPARE2();
00045             
00046         }
00047         
00048         AS_unix_alarmCount++;
00049         if (AS_unix_alarmCount >= 28) {
00050             AS_unix_simTime += 0.003556*28;
00051             AS_unix_alarmCount = 0;
00052             
00053             AS_unix_decode();
00054             
00055         }
00056     
00057     }
00058     
00059 }
00060 
00061 /**
00062  * This function is called just before any read or write access to the IO 
00063  * vector. Any reactions on IO requests have to be handled here.
00064  * 
00065  * At the moment, the following is handled here:
00066  *  - Writes to the serial interface.
00067  * 
00068  * @param io_addr   IO vector offset that is being accessed.
00069  * 
00070  * @return Always io_addr
00071  */
00072 int AS_unix_prepareIo(int io_addr)
00073 {
00074     // avoid endless recursive calls (this is not thread/signal safe)
00075     if (AS_unix_ioLock) return io_addr;
00076     AS_unix_ioLock = 1;
00077     
00078     switch (io_addr) {
00079         // UCSRB
00080         case 0x0A: {
00081             UDR = '\0'; // clear UDR
00082             UCSRA |= 0x20 | 0x40; // write-ready and TX complete
00083             UCSRA &= ~0x80; // not read-ready
00084             break;
00085         }
00086         
00087         // UDR
00088         case 0x0C: {
00089             if (UCSRB == 0x08) {
00090                 // TX mode
00091                 printf("%c", UDR); // push previous character out
00092                 fflush(stdout);
00093                 
00094             } else if (UCSRB == 0x10) {
00095                 // RX mode (TODO)
00096                 
00097             }
00098             break;
00099         }
00100         
00101         default: {}
00102     }
00103     
00104     AS_unix_ioLock = 0;
00105     return io_addr;
00106 }
00107 
00108 /**
00109  * Initialization for simsuro
00110  */
00111 inline void AS_Init(void) 
00112 {
00113     fprintf(stderr, "AS_Init()\n");
00114     
00115     // clear IO vector
00116     memset(AS_unix_ioVector, 0, sizeof(AS_unix_ioVector));
00117     
00118     // set signal action
00119     struct sigaction act;
00120     memset(&act, 0, sizeof(act));
00121     act.sa_flags = SA_SIGINFO;
00122     act.sa_sigaction = AS_unix_sh_SIGALRM;
00123     sigaction(SIGALRM, &act, NULL);
00124     
00125     // set timer
00126     struct itimerval itimer;
00127     memset(&itimer, 0, sizeof(itimer));
00128     itimer.it_interval.tv_usec = 7000;
00129     itimer.it_value.tv_usec = 7000;
00130     setitimer(ITIMER_REAL, &itimer, NULL);
00131     
00132     // low priority (uses busy waiting on UNIX!)
00133     setpriority(PRIO_PROCESS, getpid(), 5);
00134     
00135 }

Generated on Fri May 12 10:11:15 2006 for simsuro by  doxygen 1.4.6