00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <avr/io.h>
00019 #include <avr/interrupt.h>
00020
00021 #include "global.h"
00022 #include "timer.h"
00023 #include "uartsw.h"
00024
00025
00026
00027
00028
00029
00030 static volatile u08 UartswTxBusy;
00031 static volatile u08 UartswTxData;
00032 static volatile u08 UartswTxBitNum;
00033
00034
00035 static volatile u16 UartswBaudRateDiv;
00036
00037
00038 static volatile u08 UartswRxBusy;
00039 static volatile u08 UartswRxData;
00040 static volatile u08 UartswRxBitNum;
00041
00042 static cBuffer uartswRxBuffer;
00043
00044 static char uartswRxData[UARTSW_RX_BUFFER_SIZE];
00045
00046
00047
00048
00049 void uartswInit(void)
00050 {
00051
00052 uartswInitBuffers();
00053
00054 sbi(UARTSW_TX_DDR, UARTSW_TX_PIN);
00055 cbi(UARTSW_RX_DDR, UARTSW_RX_PIN);
00056 cbi(UARTSW_RX_PORT, UARTSW_RX_PIN);
00057
00058 uartswSetBaudRate(9600);
00059
00060
00061 UartswTxBusy = FALSE;
00062
00063 cbi(TIMSK, OCIE1A);
00064
00065 timerAttach(TIMER1OUTCOMPAREA_INT, uartswTxBitService);
00066
00067
00068 UartswRxBusy = FALSE;
00069
00070 cbi(TIMSK, OCIE1B);
00071
00072 timerAttach(TIMER1OUTCOMPAREB_INT, uartswRxBitService);
00073
00074 timerAttach(TIMER1INPUTCAPTURE_INT, uartswRxBitService);
00075 #ifdef UARTSW_INVERT
00076
00077 sbi(TCCR1B, ICES1);
00078 #else
00079
00080 cbi(TCCR1B, ICES1);
00081 #endif
00082
00083 sbi(TIMSK, TICIE1);
00084
00085
00086 sei();
00087 }
00088
00089
00090 void uartswInitBuffers(void)
00091 {
00092
00093 bufferInit(&uartswRxBuffer, uartswRxData, UARTSW_RX_BUFFER_SIZE);
00094 }
00095
00096
00097 void uartswOff(void)
00098 {
00099
00100 cbi(TIMSK, OCIE1A);
00101 cbi(TIMSK, OCIE1B);
00102 cbi(TIMSK, TICIE1);
00103
00104 timerDetach(TIMER1OUTCOMPAREA_INT);
00105 timerDetach(TIMER1OUTCOMPAREB_INT);
00106 timerDetach(TIMER1INPUTCAPTURE_INT);
00107 }
00108
00109 void uartswSetBaudRate(u32 baudrate)
00110 {
00111
00112 timer1SetPrescaler(TIMER_CLK_DIV1);
00113
00114 UartswBaudRateDiv = (u16)((F_CPU+(baudrate/2L))/(baudrate*1L));
00115 }
00116
00117
00118 cBuffer* uartswGetRxBuffer(void)
00119 {
00120
00121 return &uartswRxBuffer;
00122 }
00123
00124 void uartswSendByte(u08 data)
00125 {
00126
00127 while(UartswTxBusy);
00128
00129 UartswTxBusy = TRUE;
00130
00131 UartswTxData = data;
00132
00133 UartswTxBitNum = 9;
00134
00135
00136 #ifdef UARTSW_INVERT
00137 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00138 #else
00139 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00140 #endif
00141
00142
00143 outw(OCR1A, inw(TCNT1) + UartswBaudRateDiv);
00144
00145 sbi(TIMSK, OCIE1A);
00146 }
00147
00148
00149 u08 uartswReceiveByte(u08* rxData)
00150 {
00151
00152 if(uartswRxBuffer.size)
00153 {
00154
00155 if(uartswRxBuffer.datalength)
00156 {
00157
00158 *rxData = bufferGetFromFront(&uartswRxBuffer);
00159 return TRUE;
00160 }
00161 else
00162 {
00163
00164 return FALSE;
00165 }
00166 }
00167 else
00168 {
00169
00170 return FALSE;
00171 }
00172 }
00173
00174 void uartswTxBitService(void)
00175 {
00176 if(UartswTxBitNum)
00177 {
00178
00179 if(UartswTxBitNum > 1)
00180 {
00181
00182 #ifdef UARTSW_INVERT
00183 if( !(UartswTxData & 0x01) )
00184 #else
00185 if( (UartswTxData & 0x01) )
00186 #endif
00187 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00188 else
00189 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00190
00191 UartswTxData = UartswTxData>>1;
00192 }
00193 else
00194 {
00195
00196 #ifdef UARTSW_INVERT
00197 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00198 #else
00199 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00200 #endif
00201 }
00202
00203 outw(OCR1A, inw(OCR1A) + UartswBaudRateDiv);
00204
00205 UartswTxBitNum--;
00206 }
00207 else
00208 {
00209
00210
00211 UartswTxBusy = FALSE;
00212 }
00213 }
00214
00215 void uartswRxBitService(void)
00216 {
00217
00218
00219
00220 if(!UartswRxBusy)
00221 {
00222
00223
00224 cbi(TIMSK, TICIE1);
00225
00226 outw(OCR1B, inw(TCNT1) + UartswBaudRateDiv + UartswBaudRateDiv/2);
00227
00228 sbi(TIFR, OCF1B);
00229
00230 sbi(TIMSK, OCIE1B);
00231
00232 UartswRxBusy = TRUE;
00233
00234 UartswRxBitNum = 0;
00235
00236 UartswRxData = 0;
00237 }
00238 else
00239 {
00240
00241
00242
00243
00244 UartswRxData = UartswRxData>>1;
00245
00246
00247 #ifdef UARTSW_INVERT
00248 if( !(inb(UARTSW_RX_PORTIN) & (1<<UARTSW_RX_PIN)) )
00249 #else
00250 if( (inb(UARTSW_RX_PORTIN) & (1<<UARTSW_RX_PIN)) )
00251 #endif
00252 {
00253
00254
00255 UartswRxData |= 0x80;
00256 }
00257
00258
00259 UartswRxBitNum++;
00260
00261 outw(OCR1B, inw(OCR1B) + UartswBaudRateDiv);
00262
00263
00264 if(UartswRxBitNum >= 8)
00265 {
00266
00267 bufferAddToEnd(&uartswRxBuffer, UartswRxData);
00268
00269 cbi(TIMSK, OCIE1B);
00270
00271 sbi(TIFR, ICF1);
00272
00273 sbi(TIMSK, TICIE1);
00274
00275 UartswRxBusy = FALSE;
00276 }
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375