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 #include <avr/signal.h>
00021
00022 #include "global.h"
00023 #include "timer.h"
00024 #include "uartsw.h"
00025
00026
00027
00028
00029
00030
00031 static volatile u08 UartswTxBusy;
00032 static volatile u08 UartswTxData;
00033 static volatile u08 UartswTxBitNum;
00034
00035
00036 static volatile u16 UartswBaudRateDiv;
00037
00038
00039 static volatile u08 UartswRxBusy;
00040 static volatile u08 UartswRxData;
00041 static volatile u08 UartswRxBitNum;
00042
00043 static cBuffer uartswRxBuffer;
00044
00045 static char uartswRxData[UARTSW_RX_BUFFER_SIZE];
00046
00047
00048
00049
00050 void uartswInit(void)
00051 {
00052
00053 uartswInitBuffers();
00054
00055 sbi(UARTSW_TX_DDR, UARTSW_TX_PIN);
00056 cbi(UARTSW_RX_DDR, UARTSW_RX_PIN);
00057 cbi(UARTSW_RX_PORT, UARTSW_RX_PIN);
00058
00059 uartswSetBaudRate(9600);
00060
00061
00062 UartswTxBusy = FALSE;
00063
00064 cbi(TIMSK, OCIE1A);
00065
00066 timerAttach(TIMER1OUTCOMPAREA_INT, uartswTxBitService);
00067
00068
00069 UartswRxBusy = FALSE;
00070
00071 cbi(TIMSK, OCIE1B);
00072
00073 timerAttach(TIMER1OUTCOMPAREB_INT, uartswRxBitService);
00074
00075 timerAttach(TIMER1INPUTCAPTURE_INT, uartswRxBitService);
00076
00077 sbi(TCCR1B, ICES1);
00078
00079 sbi(TIMSK, TICIE1);
00080
00081
00082 sei();
00083 }
00084
00085
00086 void uartswInitBuffers(void)
00087 {
00088
00089 bufferInit(&uartswRxBuffer, uartswRxData, UARTSW_RX_BUFFER_SIZE);
00090 }
00091
00092
00093 void uartswOff(void)
00094 {
00095
00096 cbi(TIMSK, OCIE1A);
00097 cbi(TIMSK, OCIE1B);
00098 cbi(TIMSK, TICIE1);
00099
00100 timerDetach(TIMER1OUTCOMPAREA_INT);
00101 timerDetach(TIMER1OUTCOMPAREB_INT);
00102 timerDetach(TIMER1INPUTCAPTURE_INT);
00103 }
00104
00105 void uartswSetBaudRate(u32 baudrate)
00106 {
00107
00108 timer1SetPrescaler(TIMER_CLK_DIV1);
00109
00110 UartswBaudRateDiv = (u16)((F_CPU+(baudrate/2L))/(baudrate*1L));
00111 }
00112
00113
00114 cBuffer* uartswGetRxBuffer(void)
00115 {
00116
00117 return &uartswRxBuffer;
00118 }
00119
00120 void uartswSendByte(u08 data)
00121 {
00122
00123 while(UartswTxBusy);
00124
00125 UartswTxBusy = TRUE;
00126
00127 UartswTxData = data;
00128
00129 UartswTxBitNum = 9;
00130
00131
00132 #ifdef UARTSW_INVERT
00133 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00134 #else
00135 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00136 #endif
00137
00138
00139 outw(OCR1A, inw(TCNT1) + UartswBaudRateDiv);
00140
00141 sbi(TIMSK, OCIE1A);
00142 }
00143
00144
00145 u08 uartswReceiveByte(u08* rxData)
00146 {
00147
00148 if(uartswRxBuffer.size)
00149 {
00150
00151 if(uartswRxBuffer.datalength)
00152 {
00153
00154 *rxData = bufferGetFromFront(&uartswRxBuffer);
00155 return TRUE;
00156 }
00157 else
00158 {
00159
00160 return FALSE;
00161 }
00162 }
00163 else
00164 {
00165
00166 return FALSE;
00167 }
00168 }
00169
00170 void uartswTxBitService(void)
00171 {
00172 if(UartswTxBitNum)
00173 {
00174
00175 if(UartswTxBitNum > 1)
00176 {
00177
00178 #ifdef UARTSW_INVERT
00179 if( !(UartswTxData & 0x01) )
00180 #else
00181 if( (UartswTxData & 0x01) )
00182 #endif
00183 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00184 else
00185 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00186
00187 UartswTxData = UartswTxData>>1;
00188 }
00189 else
00190 {
00191
00192 #ifdef UARTSW_INVERT
00193 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00194 #else
00195 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00196 #endif
00197 }
00198
00199 outw(OCR1A, inw(OCR1A) + UartswBaudRateDiv);
00200
00201 UartswTxBitNum--;
00202 }
00203 else
00204 {
00205
00206
00207 UartswTxBusy = FALSE;
00208 }
00209 }
00210
00211 void uartswRxBitService(void)
00212 {
00213
00214
00215
00216 if(!UartswRxBusy)
00217 {
00218
00219
00220 cbi(TIMSK, TICIE1);
00221
00222 outw(OCR1B, inw(TCNT1) + UartswBaudRateDiv + UartswBaudRateDiv/2);
00223
00224 sbi(TIFR, OCF1B);
00225
00226 sbi(TIMSK, OCIE1B);
00227
00228 UartswRxBusy = TRUE;
00229
00230 UartswRxBitNum = 0;
00231
00232 UartswRxData = 0;
00233 }
00234 else
00235 {
00236
00237
00238
00239
00240 UartswRxData = UartswRxData>>1;
00241
00242
00243 #ifdef UARTSW_INVERT
00244 if( !(inb(UARTSW_RX_PORTIN) & (1<<UARTSW_RX_PIN)) )
00245 #else
00246 if( !(inb(UARTSW_RX_PORTIN) & (1<<UARTSW_RX_PIN)) )
00247 #endif
00248 {
00249
00250
00251 UartswRxData |= 0x80;
00252 }
00253
00254
00255 UartswRxBitNum++;
00256
00257 outw(OCR1B, inw(OCR1B) + UartswBaudRateDiv);
00258
00259
00260 if(UartswRxBitNum >= 8)
00261 {
00262
00263 bufferAddToEnd(&uartswRxBuffer, UartswRxData);
00264
00265 cbi(TIMSK, OCIE1B);
00266
00267 sbi(TIFR, ICF1);
00268
00269 sbi(TIMSK, TICIE1);
00270
00271 UartswRxBusy = FALSE;
00272 }
00273 }
00274 }
00275
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