00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <avr/io.h>
00012 #include <avr/interrupt.h>
00013 #include <stdlib.h>
00014 #include "system.h"
00015 #include "xserial.h"
00016 #include "task.h"
00017 #include "cio.h"
00018
00019 static void InitXPort(xSERIAL *pS,unsigned short nTSize,unsigned short nRSize, unsigned short nPort,long nBaudRate);
00020 static int ROpen(IOCB *pIOCB);
00021 static int RGetC(IOCB *pIOCB);
00022 static int RPutC(IOCB *pIOCB,int c);
00023 static int RWrite(IOCB *pIOCB,char *b,int l);
00024 static int RStatus(IOCB *pIOCB,int m);
00025
00026 static xSERIAL *gXSerial[RS232_N_PORTS];
00027
00028 static H_JVEC RJump = {
00029 ROpen,
00030 0,
00031 RGetC,
00032 0,
00033 RPutC,
00034 RWrite,
00035 RStatus,
00036 0,
00037 RInit
00038 };
00039
00040
00041 static xRREG SAdr = {
00042 (unsigned char *)0xf050,
00043 (unsigned char *)0xf055,
00044 (unsigned char *)0xf056,
00045 (unsigned char *)0xf057,
00046 (unsigned char *)0xf051,
00047 (unsigned char *)0xf052,
00048 (unsigned short *)0xf053
00049 };
00050
00051 static int ROpen(IOCB *pIOCB)
00052 {
00053 if(pIOCB->devnum < RS232_N_PORTS)
00054 {
00055 pIOCB->p = (void *)malloc(sizeof(xSERIAL));
00056 InitXPort((xSERIAL *)pIOCB->p,XRS232_DEF_T_BUFF_SIZE,XRS232_DEF_R_BUFF_SIZE,pIOCB->devnum,XRS232_DEF_BAUDRATE);
00057 gXSerial[pIOCB->devnum-1] = (xSERIAL *)pIOCB->p;
00058 }
00059 return 0;
00060 }
00061
00062 static int RGetC(IOCB *pIOCB)
00063 {
00064 int retval;
00065 char sr;
00066 xSERIAL *pI = (xSERIAL *)pIOCB->p;
00067
00068 PendSemaphore(pI->Rx.pSem,0);
00069 sr = Disable();
00070 if(pI->Rx.nChar)
00071 {
00072 retval = (int)pI->Rx.buff[pI->Rx.tail++];
00073 if(pI->Rx.tail == pI->Rx.size) pI->Rx.tail = 0;
00074 pI->Rx.nChar--;
00075 }
00076 else
00077 retval = -1;
00078 Enable(sr);
00079 return retval;
00080 }
00081
00082
00083 static int RPutC(IOCB *pIOCB,int c)
00084 {
00085 char sr;
00086 xSERIAL *pI = (xSERIAL *)pIOCB->p;
00087
00088 sr = Disable();
00089 if(pI->Tx.nChar < pI->Tx.size)
00090 {
00091 pI->Tx.buff[pI->Tx.head++] = (unsigned char)c;
00092 if(pI->Tx.head == pI->Tx.size) pI->Tx.head = 0;
00093 if(!pI->Tx.nChar)
00094 *pI->regs->pIER |= BIT(XRS232_IER_TXMT);
00095 pI->Tx.nChar++;
00096 }
00097 Enable(sr);
00098 return 0;
00099 }
00100
00101 static int RWrite(IOCB *pIOCB,char *b,int l)
00102 {
00103 int i = 0;
00104 xSERIAL *pI = (xSERIAL *)pIOCB->p;
00105
00106 PendSemaphore(pI->Tx.pSem,0);
00107 for(i=0;i<l;++i)
00108 RPutC(pIOCB,b[i]);
00109 PostSemaphore(pI->Tx.pSem,0);
00110 return i;
00111 }
00112
00113 static int RStatus(IOCB *pIOCB,int m)
00114 {
00115 int rv=0;
00116
00117 xSERIAL *pI = (xSERIAL *)pIOCB->p;
00118 switch(m)
00119 {
00120 case RS232_STAT_NREC:
00121 rv = pI->Rx.nChar;
00122 break;
00123 case RS232_STAT_TMT:
00124 if(pI->Tx.nChar == 0) rv = 1;
00125 else rv = 0;
00126 break;
00127 }
00128 return rv;
00129 }
00130
00131 static unsigned short xCalculateBaudRate(long nBR)
00132 {
00133 long br;
00134 br = nBR * 8192L;
00135 br /= 390625L;
00136 return (unsigned short)br;
00137 }
00138
00139 static char *PNames[2] = {
00140 "RX0",
00141 "RX1"
00142 };
00143
00144 static char *TNames[2] = {
00145 "TX0",
00146 "TX1"
00147 };
00148
00149 static void InitXPort(xSERIAL *pS,unsigned short nTSize,unsigned short nRSize, unsigned short nPort,long nBaudRate)
00150 {
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 pS->regs = &SAdr;
00161 pS->Tx.buff = malloc(nTSize);
00162 pS->Tx.head = 0;
00163 pS->Tx.tail = 0;
00164 pS->Tx.nChar = 0;
00165 pS->Tx.size = nTSize;
00166 pS->Tx.pSem = NewSemaphore(1,SEMAPHORE_MODE_BLOCKING,TNames[nPort]);
00167 pS->Rx.buff = malloc(nRSize);
00168 pS->Rx.head = 0;
00169 pS->Rx.tail = 0;
00170 pS->Rx.nChar = 0;
00171 pS->Rx.size = nRSize;
00172 pS->Rx.pSem = NewSemaphore(0,SEMAPHORE_MODE_BLOCKING,PNames[nPort]);
00173 *pS->regs->pUBRR = xCalculateBaudRate(nBaudRate);
00174
00175 *pS->regs->pIER = 1;
00176 }
00177
00178 int xRInit(void)
00179 {
00180 CioAddHandler("XR",&RJump);
00181 EIFR = BIT(INT6);
00182 EIMSK |= BIT(INT6);
00183 EIFR = BIT(INT6);
00184 return 0;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 static void RxIsr(xSERIAL *pI)
00194 {
00195 while(!(*pI->regs->pRSR & BIT(XRS232_RSR_FIFO_MT)) )
00196 {
00197 pI->Rx.buff[pI->Rx.head++] = *pI->regs->pUDR;
00198 if(pI->Rx.head == pI->Rx.size) pI->Rx.head = 0;
00199 pI->Rx.nChar++;
00200 PostSemaphore(pI->Rx.pSem,0);
00201 }
00202 }
00203
00204 static void TxIsr(xSERIAL *pI)
00205 {
00206 char loop = 1;
00207
00208
00209 while(!(*pI->regs->pTSR & BIT(XRS232_TSR_FIFO_FULL)) && loop)
00210 {
00211 if(pI->Tx.nChar)
00212 {
00213 *pI->regs->pUDR = pI->Tx.buff[pI->Tx.tail++];
00214 if(pI->Tx.tail == pI->Tx.size) pI->Tx.tail = 0;
00215 pI->Tx.nChar--;
00216 }
00217 else
00218 {
00219
00220 *pI->regs->pIER &= ~(BIT(XRS232_IER_TXMT));
00221 loop = 0;
00222 }
00223 }
00224 }
00225
00226 static void TxDoneIsr(xSERIAL *pI)
00227 {
00228 }
00229
00230 static void (*irqfunc[3])(xSERIAL *pI) = {
00231 RxIsr,
00232 TxIsr,
00233 TxDoneIsr
00234 };
00235
00236 void INT6_vect(void) __attribute__ ((naked));
00237 void INT6_vect(void)
00238 {
00239 SAVE_IRQ();
00240 ++InterruptCount;
00241 (*irqfunc[*(gXSerial[0]->regs->pIVR)])(gXSerial[0]);
00242 EIFR = BIT(INT6);
00243 ExitInterrupt();
00244 RESTORE_IRQ();
00245 }
00246
00247
00248
00249
00250
00251
00252