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 "uartsw2.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 u08 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 #ifdef UARTSW_INVERT
00056 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00057 #else
00058 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00059 #endif
00060 cbi(UARTSW_RX_DDR, UARTSW_RX_PIN);
00061 cbi(UARTSW_RX_PORT, UARTSW_RX_PIN);
00062
00063 uartswSetBaudRate(9600);
00064
00065
00066 UartswTxBusy = FALSE;
00067
00068 cbi(TIMSK, OCIE2);
00069
00070 timerAttach(TIMER2OUTCOMPARE_INT, uartswTxBitService);
00071
00072
00073 UartswRxBusy = FALSE;
00074
00075 cbi(TIMSK, OCIE0);
00076
00077 timerAttach(TIMER0OUTCOMPARE_INT, uartswRxBitService);
00078
00079 #ifdef UARTSW_INVERT
00080 sbi(MCUCSR, ISC2);
00081 #else
00082 cbi(MCUCSR, ISC2);
00083 #endif
00084
00085 sbi(GICR, INT2);
00086
00087
00088 sei();
00089 }
00090
00091
00092 void uartswInitBuffers(void)
00093 {
00094
00095 bufferInit(&uartswRxBuffer, uartswRxData, UARTSW_RX_BUFFER_SIZE);
00096 }
00097
00098
00099 void uartswOff(void)
00100 {
00101
00102 cbi(TIMSK, OCIE2);
00103 cbi(TIMSK, OCIE0);
00104 cbi(GICR, INT2);
00105
00106 timerDetach(TIMER2OUTCOMPARE_INT);
00107 timerDetach(TIMER0OUTCOMPARE_INT);
00108 }
00109
00110 void uartswSetBaudRate(u32 baudrate)
00111 {
00112 u16 div;
00113
00114
00115 if( baudrate > (F_CPU/64L*256L) )
00116 {
00117
00118
00119 timer2SetPrescaler(TIMERRTC_CLK_DIV64);
00120 timer0SetPrescaler(TIMER_CLK_DIV64);
00121 div = 64;
00122 }
00123 else
00124 {
00125
00126
00127 timer2SetPrescaler(TIMERRTC_CLK_DIV256);
00128 timer0SetPrescaler(TIMER_CLK_DIV256);
00129 div = 256;
00130 }
00131
00132
00133
00134
00135 UartswBaudRateDiv = (u08)(((F_CPU/div)+(baudrate/2L))/(baudrate*1L));
00136 }
00137
00138
00139 cBuffer* uartswGetRxBuffer(void)
00140 {
00141
00142 return &uartswRxBuffer;
00143 }
00144
00145 void uartswSendByte(u08 data)
00146 {
00147
00148 while(UartswTxBusy);
00149
00150 UartswTxBusy = TRUE;
00151
00152 UartswTxData = data;
00153
00154 UartswTxBitNum = 9;
00155
00156
00157 #ifdef UARTSW_INVERT
00158 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00159 #else
00160 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00161 #endif
00162
00163 outb(OCR2, inb(TCNT2) + UartswBaudRateDiv);
00164
00165 sbi(TIMSK, OCIE2);
00166 }
00167
00168
00169 u08 uartswReceiveByte(u08* rxData)
00170 {
00171
00172 if(uartswRxBuffer.size)
00173 {
00174
00175 if(uartswRxBuffer.datalength)
00176 {
00177
00178 *rxData = bufferGetFromFront(&uartswRxBuffer);
00179 return TRUE;
00180 }
00181 else
00182 {
00183
00184 return FALSE;
00185 }
00186 }
00187 else
00188 {
00189
00190 return FALSE;
00191 }
00192 }
00193
00194 void uartswTxBitService(void)
00195 {
00196 if(UartswTxBitNum)
00197 {
00198
00199 if(UartswTxBitNum > 1)
00200 {
00201
00202 #ifdef UARTSW_INVERT
00203 if( !(UartswTxData & 0x01) )
00204 #else
00205 if( (UartswTxData & 0x01) )
00206 #endif
00207 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00208 else
00209 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00210
00211 UartswTxData = UartswTxData>>1;
00212 }
00213 else
00214 {
00215
00216 #ifdef UARTSW_INVERT
00217 cbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00218 #else
00219 sbi(UARTSW_TX_PORT, UARTSW_TX_PIN);
00220 #endif
00221 }
00222
00223 outb(OCR2, inb(OCR2) + UartswBaudRateDiv);
00224
00225 UartswTxBitNum--;
00226 }
00227 else
00228 {
00229
00230
00231 UartswTxBusy = FALSE;
00232
00233 cbi(TIMSK, OCIE2);
00234 }
00235 }
00236
00237 void uartswRxBitService(void)
00238 {
00239
00240
00241
00242 if(!UartswRxBusy)
00243 {
00244
00245
00246
00247
00248 cbi(GICR, INT2);
00249
00250 outb(OCR0, inb(TCNT0) + UartswBaudRateDiv + UartswBaudRateDiv/2);
00251
00252 sbi(TIFR, OCF0);
00253
00254 sbi(TIMSK, OCIE0);
00255
00256 UartswRxBusy = TRUE;
00257
00258 UartswRxBitNum = 0;
00259
00260 UartswRxData = 0;
00261 }
00262 else
00263 {
00264
00265
00266
00267
00268 UartswRxData = UartswRxData>>1;
00269
00270
00271 #ifdef UARTSW_INVERT
00272 if( !(inb(UARTSW_RX_PORTIN) & (1<<UARTSW_RX_PIN)) )
00273 #else
00274 if( (inb(UARTSW_RX_PORTIN) & (1<<UARTSW_RX_PIN)) )
00275 #endif
00276 {
00277
00278
00279 UartswRxData |= 0x80;
00280 }
00281
00282
00283 UartswRxBitNum++;
00284
00285 outb(OCR0, inb(OCR0) + UartswBaudRateDiv);
00286
00287
00288 if(UartswRxBitNum >= 8)
00289 {
00290
00291 bufferAddToEnd(&uartswRxBuffer, UartswRxData);
00292
00293 cbi(TIMSK, OCIE0);
00294
00295 sbi(GIFR, INTF2);
00296
00297 sbi(GICR, INT2);
00298
00299 UartswRxBusy = FALSE;
00300 }
00301 }
00302 }
00303
00304 SIGNAL(SIG_INTERRUPT2)
00305 {
00306
00307 uartswRxBitService();
00308 }