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