00001 #include "usart.h"
00002
00003
00004
00005
00006
00007
00008 static int usart_mode_is_multidrop(volatile avr32_usart_t * usart)
00009 {
00010 return (((usart->mr & 0x00000600)>>(AVR32_USART_MR_PAR_OFFSET+1)) == 3);
00011 }
00012
00013 void usart_reset(volatile avr32_usart_t * usart)
00014 {
00015
00016
00017 usart->idr = 0xFFFFffff;
00018
00019
00020
00021 usart->mr = 0;
00022 usart->rtor = 0;
00023 usart->ttgr = 0;
00024
00025
00026
00027
00028 usart->cr = (1 << AVR32_USART_CR_RSTRX_OFFSET) |
00029 (1 << AVR32_USART_CR_RSTTX_OFFSET) |
00030 (1 << AVR32_USART_CR_RSTSTA_OFFSET) |
00031 (1 << AVR32_USART_CR_RSTIT_OFFSET) |
00032 (1 << AVR32_USART_CR_RSTNACK_OFFSET) |
00033 (1 << AVR32_USART_CR_DTRDIS_OFFSET) |
00034 (1 << AVR32_USART_CR_RTSDIS_OFFSET);
00035 }
00036
00037
00048 static int usart_set_baudrate(volatile avr32_usart_t * usart, unsigned int baudrate, long cpu_hz)
00049 {
00050 int cd;
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 if (baudrate > (cpu_hz/16)) {
00062
00063 usart->mr |= (1<<AVR32_USART_MR_OVER_OFFSET);
00064 cd = cpu_hz / (8*baudrate);
00065
00066 if (cd < 2) {
00067 return USART_INVALID_INPUT;
00068 }
00069 usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
00070 } else {
00071
00072 usart->mr &= ~(1<<AVR32_USART_MR_OVER_OFFSET);
00073 cd = cpu_hz / (16*baudrate);
00074
00075 if (cd > 65535) {
00076
00077 return USART_INVALID_INPUT;
00078 }
00079 usart->brgr = (cd << AVR32_USART_BRGR_CD_OFFSET);
00080 }
00081
00082 return USART_SUCCESS;
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 int usart_init_rs232(volatile avr32_usart_t * usart, struct usart_options_t * opt, long cpu_hz)
00096 {
00097 int retval;
00098
00099
00100 usart_reset(usart);
00101
00102
00103 if (opt == 0)
00104 return USART_INVALID_INPUT;
00105 if (opt->charlength < 5 || opt->charlength > 9)
00106 return USART_INVALID_INPUT;
00107 if (opt->paritytype > 7)
00108 return USART_INVALID_INPUT;
00109 if (opt->stopbits > 2+255)
00110 return USART_INVALID_INPUT;
00111 if (opt->channelmode > 3)
00112 return USART_INVALID_INPUT;
00113
00114 if ((retval = usart_set_baudrate(usart, opt->baudrate, cpu_hz)) != \
00115 USART_SUCCESS)
00116 return retval;
00117
00118 if (opt->charlength == 9) {
00119
00120 usart->mr |= (1<<AVR32_USART_MR_MODE9_OFFSET);
00121 } else {
00122
00123 usart->mr |=
00124 ((opt->charlength-5) << AVR32_USART_MR_CHRL_OFFSET);
00125 }
00126
00127 usart->mr |= (opt->channelmode << AVR32_USART_MR_CHMODE_OFFSET) |
00128 (opt->paritytype << AVR32_USART_MR_PAR_OFFSET);
00129
00130 if (opt->stopbits > 2)
00131 {
00132
00133 usart->mr |= (2 << AVR32_USART_MR_NBSTOP_OFFSET);
00134
00135 usart->ttgr = (opt->stopbits-2);
00136 }
00137 else
00138
00139 usart->mr |= (opt->stopbits << AVR32_USART_MR_NBSTOP_OFFSET);
00140
00141
00142
00143 usart->cr |= (1<<AVR32_USART_CR_TXEN_OFFSET) |
00144 (1<<AVR32_USART_CR_RXEN_OFFSET);
00145
00146 return USART_SUCCESS;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 int usart_init_handshaking(volatile avr32_usart_t * usart, struct usart_options_t * opt,
00164 long cpu_hz, int software_handshaking,
00165 char xon_char, char xoff_char)
00166 {
00167 int retval;
00168
00169
00170 if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS)
00171 return retval;
00172
00173 if (software_handshaking == 0)
00174 {
00175
00176 usart-> mr &= ~(0xf << AVR32_USART_MR_USART_MODE_OFFSET);
00177
00178 usart-> mr |= (USART_MODE_HW_HSH << AVR32_USART_MR_USART_MODE_OFFSET);
00179 }
00180 else if (software_handshaking == 1)
00181 {
00182
00183 usart-> mr &= ~(0xf << AVR32_USART_MR_USART_MODE_OFFSET);
00184
00185 usart-> mr |= (USART_MODE_SW_HSH << AVR32_USART_MR_USART_MODE_OFFSET);
00186
00187 usart->xxr = (xon_char << AVR32_USART_XXR_XON_OFFSET) |
00188 (xoff_char << AVR32_USART_XXR_XOFF_OFFSET);
00189 }
00190 else
00191 return USART_INVALID_INPUT;
00192
00193 return USART_SUCCESS;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 int usart_init_IrDA(volatile avr32_usart_t * usart, struct usart_options_t * opt,
00205 long cpu_hz, unsigned char irda_filter)
00206 {
00207 int retval;
00208
00209
00210 if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS)
00211 return retval;
00212
00213
00214 usart->ifr = irda_filter;
00215
00216
00217 usart->mr |= (1 << AVR32_USART_MR_FILTER_OFFSET);
00218 return USART_SUCCESS;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228 int usart_init_modem(volatile avr32_usart_t * usart, struct usart_options_t * opt, long cpu_hz)
00229 {
00230 int retval;
00231
00232
00233 if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS)
00234 return retval;
00235
00236
00237 usart-> mr &= ~(0xf << AVR32_USART_MR_USART_MODE_OFFSET);
00238
00239 usart-> mr |= (USART_MODE_MODEM << AVR32_USART_MR_USART_MODE_OFFSET);
00240 return USART_SUCCESS;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 int usart_init_rs485(volatile avr32_usart_t * usart, struct usart_options_t * opt, long cpu_hz)
00254 {
00255 int retval;
00256
00257
00258 if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS)
00259 return retval;
00260
00261
00262
00263
00264
00265
00266 usart->mr &= ~(0xf << AVR32_USART_MR_USART_MODE_OFFSET);
00267
00268 usart->mr |= (USART_MODE_RS485 << AVR32_USART_MR_USART_MODE_OFFSET);
00269 return USART_SUCCESS;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 int usart_init_iso7816(volatile avr32_usart_t * usart, const struct iso7816_options_t * opt, int t, const long cpu_hz)
00281 {
00282 int retval;
00283
00284
00285 usart_reset(usart);
00286
00287 if (opt == 0)
00288
00289 return USART_INVALID_INPUT;
00290
00291
00292
00293
00294
00295 if (t == 0)
00296 {
00297
00298
00299 usart->mr = (USART_MODE_ISO7816_T0 << AVR32_USART_MR_USART_MODE_OFFSET) |
00300 (2 << AVR32_USART_MR_NBSTOP_OFFSET) |
00301 (opt->bit_order << AVR32_USART_MR_MSBF_OFFSET);
00302 }
00303 else if (t == 1)
00304 {
00305
00306 if (opt->bit_order != 0)
00307 return USART_INVALID_INPUT;
00308
00309 if (opt->max_iterations != 0)
00310 return USART_INVALID_INPUT;
00311
00312 usart->mr = (USART_MODE_ISO7816_T1 << AVR32_USART_MR_USART_MODE_OFFSET);
00313
00314 }
00315 else
00316 return USART_INVALID_INPUT;
00317
00318 if ((retval = usart_set_baudrate(usart, opt->iso7816_hz, cpu_hz)) != USART_SUCCESS)
00319 return retval;
00320
00321
00322 usart->fidi = opt->fidi_ratio;
00323
00324 usart->mr |= (opt->inhibit_nack << AVR32_USART_MR_INACK_OFFSET) |
00325 (opt->dis_suc_nack << AVR32_USART_MR_DSNACK_OFFSET) |
00326 (opt->max_iterations << AVR32_USART_MR_MAX_ITERATION_OFFSET) |
00327 (1 << AVR32_USART_MR_CLKO_OFFSET);
00328
00329
00330
00331 usart->cr |= (1<<AVR32_USART_CR_RXEN_OFFSET);
00332
00333 return USART_SUCCESS;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 void usart_reset_status(volatile avr32_usart_t * usart)
00353 {
00354 usart->cr |= (1<<AVR32_USART_CR_RSTSTA_OFFSET);
00355 }
00356
00357
00358
00359
00360
00361
00362 int usart_parity_error(volatile avr32_usart_t * usart)
00363 {
00364 return ((usart->csr & (1<<AVR32_USART_CSR_PARE_OFFSET)) != 0);
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 int usart_framing_error(volatile avr32_usart_t * usart)
00374 {
00375 return ((usart->csr & (1<<AVR32_USART_CSR_FRAME_OFFSET)) != 0);
00376 }
00377
00378
00379
00380
00381
00382
00383
00384 int usart_overrun_error(volatile avr32_usart_t * usart)
00385 {
00386 return ((usart->csr & AVR32_USART_CSR_OVRE_OFFSET)) != 0;
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 int usart_send_address(volatile avr32_usart_t * usart, int address)
00409 {
00410
00411 if (usart_mode_is_multidrop(usart))
00412 {
00413
00414 usart->cr |= (1<<AVR32_USART_CR_SENDA_OFFSET);
00415
00416
00417 usart_bw_write_char(usart, address);
00418 return USART_SUCCESS;
00419 } else {
00420 return USART_MODE_FAULT;
00421 }
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431 inline void usart_bw_write_char(volatile avr32_usart_t * usart, int c)
00432 {
00433 while (usart_write_char(usart, c) != USART_SUCCESS) {
00434 }
00435
00436 return;
00437 }
00438
00439 int usart_write_char(volatile avr32_usart_t * usart, int c)
00440 {
00441
00442 if ((usart->csr & (1<<AVR32_USART_CSR_TXRDY_OFFSET)) != 0) {
00443 usart->thr = c;
00444 return USART_SUCCESS;
00445 }
00446 else
00447 return USART_TX_BUSY;
00448 }
00449
00450
00451 int usart_read_char(volatile avr32_usart_t * usart, int * c)
00452 {
00453
00454
00455 if (usart->csr &
00456 ((1 << AVR32_USART_CSR_OVRE_OFFSET) |
00457 (1 << AVR32_USART_CSR_FRAME_OFFSET) |
00458 (1 << AVR32_USART_CSR_PARE_OFFSET))) {
00459 return USART_RX_ERROR;
00460 }
00461
00462 else if ((usart->csr & (1<<AVR32_USART_CSR_RXRDY_OFFSET)) != 0) {
00463 *c = (unsigned short)usart->rhr;
00464 return USART_SUCCESS;
00465 } else {
00466 return USART_RX_EMPTY;
00467 }
00468 }
00469
00470
00471 int usart_getchar(volatile avr32_usart_t * usart)
00472 {
00473 int c, ret;
00474 while (((ret = usart_read_char(usart, &c)) == USART_RX_EMPTY)) {
00475 }
00476
00477 if (ret == USART_RX_ERROR)
00478 return -1;
00479 else
00480 return c;
00481 }
00482
00483
00484 int usart_putchar(volatile avr32_usart_t * usart, int c)
00485 {
00486 int timeout = USART_DEFAULT_TIMEOUT;
00487
00488 if (c == '\n'){
00489 while ((usart_write_char(usart, '\r') != USART_SUCCESS) && --timeout)
00490 ;
00491 if (timeout == 0)
00492 return -1;
00493 timeout = USART_DEFAULT_TIMEOUT;
00494 }
00495
00496 while ((usart_write_char(usart, c) != USART_SUCCESS) && --timeout)
00497 ;
00498 if (timeout == 0)
00499 return -1;
00500 else
00501 return 0;
00502 }
00503
00504
00505
00506 int usart_write_line(volatile avr32_usart_t * usart, char * string)
00507 {
00508 while (*string != '\0')
00509 usart_putchar(usart, *string++);
00510 return 0;
00511 }