Nut/OS  4.10.3
API Reference
usart.c
Go to the documentation of this file.
00001 
00036 /*
00037  * $Log: usart.c,v $
00038  *
00039  */
00040 
00041 #include <cfg/clock.h>
00042 
00043 #include <sys/atom.h>
00044 #include <sys/event.h>
00045 #include <sys/timer.h>
00046 
00047 #include <dev/irqreg.h>
00048 #include <dev/gpio.h>
00049 #include <dev/usartavr32.h>
00050 
00051 #include <avr32/io.h>
00052 #include <arch/avr32/gpio.h>
00053 
00058 
00059 /* \brief ASCII code for software flow control, starts transmitter. */
00060 #define ASCII_XON   0x11
00061 /* \brief ASCII code for software flow control, stops transmitter. */
00062 #define ASCII_XOFF  0x13
00063 
00064 /* \brief XON transmit pending flag. */
00065 #define XON_PENDING     0x10
00066 /* \brief XOFF transmit pending flag. */
00067 #define XOFF_PENDING    0x20
00068 /* \brief XOFF sent flag. */
00069 #define XOFF_SENT       0x40
00070 /* \brief XOFF received flag. */
00071 #define XOFF_RCVD       0x80
00072 
00073 
00077 static ureg_t rx_errors;
00078 
00082 static uint_fast8_t flow_control;
00083 
00087 static uint_fast8_t tx_aframe;
00088 
00089 #ifdef UART_HDX_BIT
00090         /* define in cfg/modem.h */
00091 #ifdef UART_HDX_FLIP_BIT        /* same as RTS toggle by Windows NT driver */
00092 #define UART_HDX_TX             cbi
00093 #define UART_HDX_RX             sbi
00094 #else                           /* previous usage by Ethernut */
00095 #define UART_HDX_TX             sbi
00096 #define UART_HDX_RX             cbi
00097 #endif
00098 #endif
00099 
00100 
00101 #ifdef UART_HDX_BIT
00102 
00108 static uint_fast8_t hdx_control;
00109 #endif
00110 
00111 //#if defined(UART_RTS_BIT) || defined(US_MODE_HWHANDSHAKE)
00118 static uint_fast8_t rts_control;
00119 //#endif
00120 
00121 //#if defined(UART_CTS_BIT) || defined(US_MODE_HWHANDSHAKE)
00128 static uint_fast8_t cts_sense;
00129 //#endif
00130 
00131 #ifdef UART_CTS_BIT
00132 
00142 static void Avr32UsartCts(void *arg)
00143 {
00144     /* Enable transmit interrupt. */
00145     //sbi(UCSRnB, UDRIE);
00146     /* Disable CTS sense interrupt. */
00147     //cbi(EIMSK, UART_CTS_BIT);
00148 }
00149 #endif
00150 
00151 #ifdef UART_HDX_BIT
00152 /*
00153  * \brief USARTn transmitter empty interrupt handler.
00154  *
00155  * Used with half duplex communication to switch from tranmit to receive
00156  * mode after the last character has been transmitted.
00157  *
00158  * This routine exists only if the hardware configuration defines a
00159  * port bit to switch between receive and transmit mode.
00160  *
00161  * \param arg Pointer to the transmitter ring buffer.
00162  */
00163 static void Avr32UsartTxEmpty(RINGBUF * rbf)
00164 {
00165     /*
00166      * Check if half duplex mode has been enabled and if all characters
00167      * had been sent out.
00168      */
00169     if (hdx_control && rbf->rbf_cnt == 0) {
00170         /* Switch to receiver mode. */
00171         UART_HDX_RX(UART_HDX_PORT, UART_HDX_BIT);
00172     }
00173 }
00174 #endif
00175 
00176 /*
00177  * \brief USARTn transmitter ready interrupt handler.
00178  *
00179  * \param rbf Pointer to the transmitter ring buffer.
00180  */
00181 static void Avr32UsartTxReady(RINGBUF * rbf)
00182 {
00183     register uint8_t *cp = rbf->rbf_tail;
00184 
00185     /*
00186      * Process pending software flow controls first.
00187      */
00188     if (flow_control & (XON_PENDING | XOFF_PENDING)) {
00189         if (flow_control & XON_PENDING) {
00190             USARTn_BASE.thr = (ASCII_XOFF << AVR32_USART_THR_TXCHR_OFFSET) & AVR32_USART_THR_TXCHR_MASK;
00191             flow_control |= XOFF_SENT;
00192         } else {
00193             USARTn_BASE.thr = (ASCII_XON << AVR32_USART_THR_TXCHR_OFFSET) & AVR32_USART_THR_TXCHR_MASK;
00194             flow_control &= ~XOFF_SENT;
00195         }
00196         flow_control &= ~(XON_PENDING | XOFF_PENDING);
00197         return;
00198     }
00199 
00200     if (flow_control & XOFF_RCVD) {
00201         /*
00202          * If XOFF has been received, we disable the transmit interrupts
00203          * and return without sending anything.
00204          */
00205         USARTn_BASE.IDR.txrdy = 1;
00206         USARTn_BASE.csr;
00207         return;
00208     }
00209 
00210     if (rbf->rbf_cnt) {
00211 
00212 #ifdef UART_CTS_BIT
00213         /*
00214          * If CTS has been disabled, we disable the transmit interrupts
00215          * and return without sending anything.
00216          */
00217         if (cts_sense && bit_is_set(UART_CTS_PIN, UART_CTS_BIT)) {
00218             USARTn_BASE.IDR.txrdy = 1;
00219             USARTn_BASE.csr;
00220 //            sbi(EIMSK, UART_CTS_BIT);
00221             return;
00222         }
00223 #endif
00224         rbf->rbf_cnt--;
00225 
00226         /*
00227          * Send address in multidrop mode.
00228          */
00229         if (tx_aframe) {
00230             USARTn_BASE.cr |= AVR32_USART_CR_SENDA_MASK;
00231         }
00232 
00233         /*
00234          * Start transmission of the next character.
00235          */
00236         USARTn_BASE.thr = (*cp << AVR32_USART_THR_TXCHR_OFFSET) & AVR32_USART_THR_TXCHR_MASK;
00237 
00238         /*
00239          * Wrap around the buffer pointer if we reached its end.
00240          */
00241         if (++cp == rbf->rbf_last) {
00242             cp = rbf->rbf_start;
00243         }
00244         rbf->rbf_tail = cp;
00245         if (rbf->rbf_cnt == rbf->rbf_lwm) {
00246             NutEventPostFromIrq(&rbf->rbf_que);
00247         }
00248     }
00249 
00250     /*
00251      * Nothing left to transmit, disable interrupt.
00252      */
00253     else {
00254         USARTn_BASE.IDR.txrdy = 1;
00255         USARTn_BASE.csr;
00256         rbf->rbf_cnt = 0;
00257         NutEventPostFromIrq(&rbf->rbf_que);
00258     }
00259 }
00260 
00261 
00262 /*
00263  * \brief USARTn receiver ready interrupt handler.
00264  *
00265  *
00266  * \param rbf Pointer to the receiver ring buffer.
00267  */
00268 
00269 static void Avr32UsartRxReady(RINGBUF * rbf)
00270 {
00271     register size_t cnt;
00272     register uint8_t ch;
00273 
00274     /*
00275      * We read the received character as early as possible to avoid overflows
00276      * caused by interrupt latency.
00277      */
00278     ch = (USARTn_BASE.rhr & AVR32_USART_RHR_RXCHR_MASK) >> AVR32_USART_RHR_RXCHR_OFFSET;
00279 
00280     /* Collect receiver errors. */
00281     rx_errors |= USARTn_BASE.csr & (AVR32_USART_CSR_OVRE_MASK | AVR32_USART_CSR_FRAME_MASK | AVR32_USART_CSR_PARE_MASK);
00282 
00283     /*
00284      * Handle software handshake. We have to do this before checking the
00285      * buffer, because flow control must work in write-only mode, where
00286      * there is no receive buffer.
00287      */
00288     if (flow_control) {
00289         /* XOFF character disables transmit interrupts. */
00290         if (ch == ASCII_XOFF) {
00291             USARTn_BASE.IDR.txrdy = 1;
00292             USARTn_BASE.csr;
00293             flow_control |= XOFF_RCVD;
00294             return;
00295         }
00296         /* XON enables transmit interrupts. */
00297         else if (ch == ASCII_XON) {
00298             USARTn_BASE.IER.txrdy = 1;
00299             flow_control &= ~XOFF_RCVD;
00300             return;
00301         }
00302     }
00303 
00304     /*
00305      * Check buffer overflow.
00306      */
00307     cnt = rbf->rbf_cnt;
00308     if (cnt >= rbf->rbf_siz) {
00309         rx_errors |= AVR32_USART_CSR_OVRE_MASK;
00310         return;
00311     }
00312 
00313     /* Wake up waiting threads if this is the first byte in the buffer. */
00314     if (cnt++ == 0) {
00315         NutEventPostFromIrq(&rbf->rbf_que);
00316     }
00317 
00318     /*
00319      * Check the high watermark for software handshake. If the number of
00320      * buffered bytes is above this mark, then send XOFF.
00321      */
00322     else if (flow_control) {
00323         if (cnt >= rbf->rbf_hwm) {
00324             if ((flow_control & XOFF_SENT) == 0) {
00325                 if (USARTn_BASE.csr & AVR32_USART_CSR_TXRDY_MASK) {
00326                     USARTn_BASE.thr = (ASCII_XOFF << AVR32_USART_THR_TXCHR_OFFSET) & AVR32_USART_THR_TXCHR_MASK;
00327                     flow_control |= XOFF_SENT;
00328                     flow_control &= ~XOFF_PENDING;
00329                 } else {
00330                     flow_control |= XOFF_PENDING;
00331                 }
00332             }
00333         }
00334     }
00335 #ifdef UART_RTS_BIT
00336     /*
00337      * Check the high watermark for hardware handshake. If the number of
00338      * buffered bytes is above this mark, then disable RTS.
00339      */
00340     else if (rts_control && cnt >= rbf->rbf_hwm) {
00341         sbi(UART_RTS_PORT, UART_RTS_BIT);
00342     }
00343 #endif
00344 
00345     /*
00346      * Store the character and increment and the ring buffer pointer.
00347      */
00348     *rbf->rbf_head++ = ch;
00349     if (rbf->rbf_head == rbf->rbf_last) {
00350         rbf->rbf_head = rbf->rbf_start;
00351     }
00352 
00353     /* Update the ring buffer counter. */
00354     rbf->rbf_cnt = cnt;
00355 }
00356 
00362 static void Avr32UsartInterrupt(void *arg)
00363 {
00364     USARTDCB *dcb = (USARTDCB *) arg;
00365     ureg_t csr = USARTn_BASE.csr;
00366 
00367     if (csr & AVR32_USART_CSR_RXRDY_MASK) {
00368         Avr32UsartRxReady(&dcb->dcb_rx_rbf);
00369     }
00370     if (csr & AVR32_USART_CSR_TXRDY_MASK) {
00371         Avr32UsartTxReady(&dcb->dcb_tx_rbf);
00372     }
00373 #ifdef UART_HDX_BIT
00374     if (csr & AVR32_USART_CSR_TXEMPTY_MASK) {
00375         Avr32UsartTxEmpty(&dcb->dcb_tx_rbf);
00376     }
00377 #endif                          /*  UART_HDX_BIT */
00378 }
00379 
00386 static void Avr32UsartEnable(void)
00387 {
00388     NutEnterCritical();
00389 
00390     /* Enable UART receiver and transmitter. */
00391     USARTn_BASE.cr |= AVR32_USART_CR_RXEN_MASK | AVR32_USART_CR_TXEN_MASK;
00392 
00393     /* Enable UART receiver and transmitter interrupts. */
00394     USARTn_BASE.ier = AVR32_USART_IER_RXRDY_MASK | AVR32_USART_IER_TXRDY_MASK;
00395     //NutIrqEnable(&SIG_UART);
00396 
00397 #ifdef UART_HDX_BIT
00398     if (hdx_control) {
00399         /* Enable transmit complete interrupt. */
00400         USARTn_BASE.ier = AVR32_USART_IER_TXEMPTY_MASK;
00401     }
00402 #endif
00403 
00404     NutExitCritical();
00405 }
00406 
00410 static void Avr32UsartDisable(void)
00411 {
00412     /*
00413      * Disable USART interrupts.
00414      */
00415     NutEnterCritical();
00416     USARTn_BASE.idr = 0xFFFFFFFF;
00417     USARTn_BASE.csr;
00418     NutExitCritical();
00419 
00420     /*
00421      * Allow incoming or outgoing character to finish.
00422      */
00423     NutDelay(10);
00424 
00425     /*
00426      * Disable USART transmit and receive.
00427      */
00428     USARTn_BASE.cr |= AVR32_USART_CR_RXDIS_MASK | AVR32_USART_CR_TXDIS_MASK;
00429 }
00430 
00439 static uint32_t Avr32UsartGetSpeed(void)
00440 {
00441     uint32_t clk = NutClockGet(NUT_HWCLK_PERIPHERAL_A);
00442     uint32_t cd = USARTn_BASE.BRGR.cd;
00443 
00444     if (USARTn_BASE.BRGR.fp) {
00445         cd += USARTn_BASE.BRGR.fp / 8;
00446     }
00447 
00448     return clk / (8UL * (2 - USARTn_BASE.MR.over) * cd);
00449 }
00450 
00461 static int Avr32UsartSetSpeed(uint32_t rate)
00462 {
00463     const unsigned long pba_hz = NutClockGet(NUT_HWCLK_PERIPHERAL_A);
00464     const unsigned int over = (pba_hz >= 16 * rate) ? 16 : 8;
00465     const unsigned int cd_fp = ((1 << AVR32_USART_BRGR_FP_SIZE) * pba_hz + (over * rate) / 2) / (over * rate);
00466     const unsigned int cd = cd_fp >> AVR32_USART_BRGR_FP_SIZE;
00467     const unsigned int fp = cd_fp & ((1 << AVR32_USART_BRGR_FP_SIZE) - 1);
00468 
00469     if (cd < 1 || cd > (1 << AVR32_USART_BRGR_CD_SIZE) - 1)
00470         return -1;
00471 
00472     Avr32UsartDisable();
00473     USARTn_BASE.mr = (USARTn_BASE.mr & ~(AVR32_USART_MR_USCLKS_MASK |
00474                                          AVR32_USART_MR_SYNC_MASK |
00475                                          AVR32_USART_MR_OVER_MASK)) |
00476         AVR32_USART_MR_USCLKS_MCK << AVR32_USART_MR_USCLKS_OFFSET |
00477         ((over == 16) ? AVR32_USART_MR_OVER_X16 : AVR32_USART_MR_OVER_X8) << AVR32_USART_MR_OVER_OFFSET;
00478 
00479     USARTn_BASE.brgr = cd << AVR32_USART_BRGR_CD_OFFSET | fp << AVR32_USART_BRGR_FP_OFFSET;
00480     Avr32UsartEnable();
00481 
00482     return 0;
00483 }
00484 
00493 static uint8_t Avr32UsartGetDataBits(void)
00494 {
00495     uint8_t val;
00496     if (USARTn_BASE.mr & AVR32_USART_MR_MODE9_MASK) {
00497         val = 9;
00498     } else {
00499         val = USARTn_BASE.MR.chrl + 5;
00500     }
00501     return (uint8_t) val;
00502 }
00503 
00512 static int Avr32UsartSetDataBits(uint8_t bits)
00513 {
00514     Avr32UsartDisable();
00515     if (bits == 9) {
00516         /* Character length set to 9 bits. MODE9 dominates CHRL. */
00517         USARTn_BASE.mr |= AVR32_USART_MR_MODE9_MASK;
00518     } else {
00519         USARTn_BASE.mr |= (bits - 5) << AVR32_USART_MR_CHRL_OFFSET;
00520     }
00521     Avr32UsartEnable();
00522 
00523     /*
00524      * Verify the result.
00525      */
00526     if (Avr32UsartGetDataBits() != bits) {
00527         return -1;
00528     }
00529     return 0;
00530 }
00531 
00540 static uint8_t Avr32UsartGetParity(void)
00541 {
00542     uint8_t val;
00543 
00544     if (USARTn_BASE.MR.mode9) {
00545         val = 9;
00546     } else {
00547         if (USARTn_BASE.MR.par == AVR32_USART_MR_PAR_ODD) {
00548             val = 1;
00549         } else if (USARTn_BASE.MR.par == AVR32_USART_MR_PAR_EVEN) {
00550             val = 2;
00551         } else {
00552             val = 0;
00553         }
00554     }
00555     return val;
00556 }
00557 
00568 static int Avr32UsartSetParity(uint8_t mode)
00569 {
00570     Avr32UsartDisable();
00571     switch (mode) {
00572     case 0:
00573         USARTn_BASE.MR.par = AVR32_USART_MR_PAR_NONE;
00574         break;
00575     case 1:
00576         USARTn_BASE.MR.par = AVR32_USART_MR_PAR_ODD;
00577         break;
00578     case 2:
00579         USARTn_BASE.MR.par = AVR32_USART_MR_PAR_EVEN;
00580         break;
00581     }
00582     Avr32UsartEnable();
00583 
00584     /*
00585      * Verify the result.
00586      */
00587     if (Avr32UsartGetParity() != mode) {
00588         return -1;
00589     }
00590     return 0;
00591 }
00592 
00601 static uint8_t Avr32UsartGetStopBits(void)
00602 {
00603     switch (USARTn_BASE.MR.nbstop) {
00604     case AVR32_USART_MR_NBSTOP_1:
00605         return 1;
00606     case AVR32_USART_MR_NBSTOP_2:
00607         return 2;
00608     case AVR32_USART_MR_NBSTOP_1_5:
00609         return 3;
00610     }
00611     return 0;
00612 }
00613 
00622 static int Avr32UsartSetStopBits(uint8_t bits)
00623 {
00624     Avr32UsartDisable();
00625     switch (bits) {
00626     case 1:
00627         USARTn_BASE.MR.nbstop = AVR32_USART_MR_NBSTOP_1;
00628         break;
00629     case 2:
00630         USARTn_BASE.MR.nbstop = AVR32_USART_MR_NBSTOP_2;
00631         break;
00632     case 3:
00633         USARTn_BASE.MR.nbstop = AVR32_USART_MR_NBSTOP_1_5;
00634         break;
00635     }
00636     Avr32UsartEnable();
00637 
00638     /*
00639      * Verify the result.
00640      */
00641     if (Avr32UsartGetStopBits() != bits) {
00642         return -1;
00643     }
00644     return 0;
00645 }
00646 
00652 static uint32_t Avr32UsartGetStatus(void)
00653 {
00654     uint32_t rc = 0;
00655 #if defined(US_MODE_HWHANDSHAKE)
00656     uint32_t csr = USARTn_BASE.csr;
00657 #endif
00658 
00659     /*
00660      * Set receiver error flags.
00661      */
00662     if ((rx_errors & AVR32_USART_CSR_FRAME_MASK) != 0) {
00663         rc |= UART_FRAMINGERROR;
00664     }
00665     if ((rx_errors & AVR32_USART_CSR_OVRE_MASK) != 0) {
00666         rc |= UART_OVERRUNERROR;
00667     }
00668     if ((rx_errors & AVR32_USART_CSR_PARE_MASK) != 0) {
00669         rc |= UART_PARITYERROR;
00670     }
00671 
00672     /*
00673      * Determine software handshake status. The flow control status may
00674      * change during interrupt, but this doesn't really hurt us.
00675      */
00676     if (flow_control) {
00677         if (flow_control & XOFF_SENT) {
00678             rc |= UART_RXDISABLED;
00679         }
00680         if (flow_control & XOFF_RCVD) {
00681             rc |= UART_TXDISABLED;
00682         }
00683     }
00684 
00685     /*
00686      * Determine hardware handshake control status.
00687      */
00688 #if defined(UART_RTS_BIT)
00689     if (bit_is_set(UART_RTS_PORT, UART_RTS_BIT)) {
00690         rc |= UART_RTSDISABLED;
00691         if (rts_control) {
00692             rc |= UART_RXDISABLED;
00693         }
00694     } else {
00695         rc |= UART_RTSENABLED;
00696     }
00697 #elif defined(US_MODE_HWHANDSHAKE)
00698     /* How to find out? */
00699 #endif
00700 
00701     /*
00702      * Determine hardware handshake sense status.
00703      */
00704 #ifdef UART_CTS_BIT
00705     if (bit_is_set(UART_CTS_PIN, UART_CTS_BIT)) {
00706         rc |= UART_CTSDISABLED;
00707         if (cts_sense) {
00708             rc |= UART_RXDISABLED;
00709         }
00710     } else {
00711         rc |= UART_CTSENABLED;
00712     }
00713 #elif defined(US_MODE_HWHANDSHAKE)
00714     if (csr & AVR32_USART_CSR_CTS_MASK) {
00715         rc |= UART_CTSDISABLED;
00716         if (cts_sense) {
00717             rc |= UART_RXDISABLED;
00718         }
00719     } else {
00720         rc |= UART_CTSENABLED;
00721     }
00722 #endif
00723 
00724     /*
00725      * Determine hardware modem sense status.
00726      */
00727 #if defined(US_MODE_HWHANDSHAKE) && 0
00728     /* I'm confused. Awful flag mismatch? Why do we have uart.h and usart.h? */
00729     if (csr & AVR32_USART_CSR_RI_MASK) {
00730         rc |= UART_RIDISABLED;
00731     } else {
00732         rc |= UART_RIENABLED;
00733     }
00734     if (csr & AVR32_USART_CSR_DSR_MASK) {
00735         rc |= UART_DSRDISABLED;
00736     } else {
00737         rc |= UART_DSRENABLED;
00738     }
00739     if (csr & AVR32_USART_CSR_DCD_MASK) {
00740         rc |= UART_DCDDISABLED;
00741     } else {
00742         rc |= UART_DCDENABLED;
00743     }
00744 #endif
00745 
00746     /*
00747      * If transmitter and receiver haven't been detected disabled by any
00748      * of the checks above, then they are probably enabled.
00749      */
00750     if ((rc & UART_RXDISABLED) == 0) {
00751         rc |= UART_RXENABLED;
00752     }
00753     if ((rc & UART_TXDISABLED) == 0) {
00754         rc |= UART_TXENABLED;
00755     }
00756 
00757     /*
00758      * Process multidrop setting.
00759      */
00760     if (tx_aframe) {
00761         rc |= UART_TXADDRFRAME;
00762     } else {
00763         rc |= UART_TXNORMFRAME;
00764     }
00765     return rc;
00766 }
00767 
00775 static int Avr32UsartSetStatus(uint32_t flags)
00776 {
00777     /*
00778      * Process software handshake control.
00779      */
00780     if (flow_control) {
00781 
00782         /* Access to the flow control status must be atomic. */
00783         NutEnterCritical();
00784 
00785         /*
00786          * Enabling or disabling the receiver means to behave like
00787          * having sent a XON or XOFF character resp.
00788          */
00789         if (flags & UART_RXENABLED) {
00790             flow_control &= ~XOFF_SENT;
00791         } else if (flags & UART_RXDISABLED) {
00792             flow_control |= XOFF_SENT;
00793         }
00794 
00795         /*
00796          * Enabling or disabling the transmitter means to behave like
00797          * having received a XON or XOFF character resp.
00798          */
00799         if (flags & UART_TXENABLED) {
00800             flow_control &= ~XOFF_RCVD;
00801         } else if (flags & UART_TXDISABLED) {
00802             flow_control |= XOFF_RCVD;
00803         }
00804         NutExitCritical();
00805     }
00806 
00807     /*
00808      * Process hardware handshake control.
00809      */
00810 #if defined(UART_RTS_BIT)
00811     /* Manually controlled via GPIO. */
00812     if (rts_control) {
00813         if (flags & UART_RXDISABLED) {
00814             sbi(UART_RTS_PORT, UART_RTS_BIT);
00815         }
00816         if (flags & UART_RXENABLED) {
00817             cbi(UART_RTS_PORT, UART_RTS_BIT);
00818         }
00819     }
00820     if (flags & UART_RTSDISABLED) {
00821         sbi(UART_RTS_PORT, UART_RTS_BIT);
00822     }
00823     if (flags & UART_RTSENABLED) {
00824         cbi(UART_RTS_PORT, UART_RTS_BIT);
00825     }
00826 #elif defined(US_MODE_HWHANDSHAKE)
00827     /* Build in hardware. */
00828     if (rts_control) {
00829         if (flags & UART_RXDISABLED) {
00830             USARTn_BASE.CR.rtsdis = 1;
00831         }
00832         if (flags & UART_RXENABLED) {
00833             USARTn_BASE.CR.rtsen = 1;
00834         }
00835     }
00836     if (flags & UART_RTSDISABLED) {
00837         USARTn_BASE.CR.rtsdis = 1;
00838     }
00839     if (flags & UART_RTSENABLED) {
00840         USARTn_BASE.CR.rtsen = 1;
00841     }
00842 #endif
00843 
00844     /*
00845      * Process hardware modem control.
00846      */
00847 #if defined(UART_DTR_BIT)
00848     /* Manually controlled via GPIO. */
00849     if (flags & UART_DTRDISABLED) {
00850         sbi(UART_DTR_PORT, UART_DTR_BIT);
00851     }
00852     if (flags & UART_DTRENABLED) {
00853         cbi(UART_DTR_PORT, UART_DTR_BIT);
00854     }
00855 #elif defined(US_MODE_HWHANDSHAKE)
00856     /* Build in hardware. */
00857     if (flags & UART_DTRDISABLED) {
00858         USARTn_BASE.CR.dtrdis = 1;
00859     }
00860     if (flags & UART_DTRENABLED) {
00861         USARTn_BASE.CR.dtren = 1;
00862     }
00863 #endif
00864 
00865     /*
00866      * Process multidrop setting.
00867      */
00868     if (flags & UART_TXADDRFRAME) {
00869         tx_aframe = 1;
00870     }
00871     if (flags & UART_TXNORMFRAME) {
00872         tx_aframe = 0;
00873     }
00874 
00875     /*
00876      * Clear UART receive errors.
00877      */
00878     if (flags & UART_ERRORS) {
00879         USARTn_BASE.CR.rststa = 1;
00880     }
00881 
00882     /*
00883      * Verify the result.
00884      */
00885     if ((Avr32UsartGetStatus() & ~UART_ERRORS) != flags) {
00886         return -1;
00887     }
00888     return 0;
00889 }
00890 
00900 static uint8_t Avr32UsartGetClockMode(void)
00901 {
00902     uint8_t rc = 0;
00903 
00904     return rc;
00905 }
00906 
00918 static int Avr32UsartSetClockMode(uint8_t mode)
00919 {
00920     /*
00921      * Verify the result.
00922      */
00923     if (Avr32UsartGetClockMode() != mode) {
00924         return -1;
00925     }
00926     return 0;
00927 }
00928 
00937 static uint32_t Avr32UsartGetFlowControl(void)
00938 {
00939     uint32_t rc = 0;
00940 
00941     if (flow_control) {
00942         rc |= USART_MF_XONXOFF;
00943     } else {
00944         rc &= ~USART_MF_XONXOFF;
00945     }
00946 
00947 #ifdef UART_RTS_BIT
00948     if (rts_control) {
00949         rc |= USART_MF_RTSCONTROL;
00950     } else {
00951         rc &= ~USART_MF_RTSCONTROL;
00952     }
00953 #endif
00954 
00955 #ifdef UART_CTS_BIT
00956     if (cts_sense) {
00957         rc |= USART_MF_CTSSENSE;
00958     } else {
00959         rc &= ~USART_MF_CTSSENSE;
00960     }
00961 #endif
00962 
00963 #ifdef UART_HDX_BIT
00964     if (hdx_control) {
00965         rc |= USART_MF_HALFDUPLEX;
00966     } else {
00967         rc &= ~USART_MF_HALFDUPLEX;
00968     }
00969 #endif
00970 
00971     return rc;
00972 }
00973 
00984 static int Avr32UsartSetFlowControl(uint32_t flags)
00985 {
00986     /*
00987      * Set software handshake mode.
00988      */
00989     if (flags & USART_MF_XONXOFF) {
00990         if (flow_control == 0) {
00991             NutEnterCritical();
00992             flow_control = 1 | XOFF_SENT;       /* force XON to be sent on next read */
00993             NutExitCritical();
00994         }
00995     } else {
00996         NutEnterCritical();
00997         flow_control = 0;
00998         NutExitCritical();
00999     }
01000 
01001     /*
01002      * Set RTS control mode.
01003      */
01004     if (flags & USART_MF_RTSCONTROL) {
01005 #if defined(UART_RTS_BIT)
01006         sbi(UART_RTS_PORT, UART_RTS_BIT);
01007         sbi(UART_RTS_DDR, UART_RTS_BIT);
01008         rts_control = 1;
01009 #endif
01010     } else if (rts_control) {
01011         rts_control = 0;
01012 #if defined(UART_RTS_BIT)
01013         cbi(UART_RTS_DDR, UART_RTS_BIT);
01014 #endif
01015     }
01016 
01017 /*
01018  * Set CTS sense mode.
01019  */
01020     if (flags & USART_MF_CTSSENSE) {
01021 #if defined(UART_CTS_BIT)
01022         /* Register CTS sense interrupt. */
01023         if (NutRegisterIrqHandler(&UART_CTS_SIGNAL, Avr32UsartCts, 0)) {
01024             return -1;
01025         }
01026         sbi(UART_CTS_PORT, UART_CTS_BIT);
01027         cbi(UART_CTS_DDR, UART_CTS_BIT);
01028         cts_sense = 1;
01029 #elif defined(US_MODE_HWHANDSHAKE)
01030         USARTn_BASE.MR.mode = AVR32_USART_MR_MODE_HARDWARE;
01031         cts_sense = 1;
01032         rts_control = 1;
01033 #endif
01034     } else if (cts_sense) {
01035 #if defined(UART_CTS_BIT)
01036         /* Deregister CTS sense interrupt. */
01037         NutRegisterIrqHandler(&UART_CTS_SIGNAL, 0, 0);
01038         cbi(UART_CTS_DDR, UART_CTS_BIT);
01039 #elif defined(US_MODE_HWHANDSHAKE)
01040         USARTn_BASE.MR.mode = AVR32_USART_MR_MODE_NORMAL;
01041         rts_control = 0;
01042 #endif
01043         cts_sense = 0;
01044     }
01045 #ifdef UART_HDX_BIT
01046     /*
01047      * Set half duplex mode.
01048      */
01049     if (flags & USART_MF_HALFDUPLEX) {
01050         /* Register transmit complete interrupt. */
01051         if (NutRegisterIrqHandler(&sig_UART_TRANS, Avr32UsartTxComplete, &dcb_usart.dcb_rx_rbf)) {
01052             return -1;
01053         }
01054         /* Initially enable the receiver. */
01055         UART_HDX_RX(UART_HDX_PORT, UART_HDX_BIT);
01056         sbi(UART_HDX_DDR, UART_HDX_BIT);
01057         hdx_control = 1;
01058         /* Enable transmit complete interrupt. */
01059         sbi(UCSRnB, TXCIE);
01060     } else if (hdx_control) {
01061         hdx_control = 0;
01062         /* disable transmit complete interrupt */
01063         cbi(UCSRnB, TXCIE);
01064         /* Deregister transmit complete interrupt. */
01065         NutRegisterIrqHandler(&sig_UART_TRANS, 0, 0);
01066         cbi(UART_HDX_DDR, UART_HDX_BIT);
01067     }
01068 #endif
01069 
01070     /*
01071      * Verify the result.
01072      */
01073     if (Avr32UsartGetFlowControl() != flags) {
01074         return -1;
01075     }
01076     return 0;
01077 }
01078 
01086 static void Avr32UsartTxStart(void)
01087 {
01088 #ifdef UART_HDX_BIT
01089     if (hdx_control) {
01090         /* Enable half duplex transmitter. */
01091         UART_HDX_TX(UART_HDX_PORT, UART_HDX_BIT);
01092     }
01093 #endif
01094     /* Enable transmit interrupts. */
01095     USARTn_BASE.IER.txrdy = 1;
01096 }
01097 
01106 static void Avr32UsartRxStart(void)
01107 {
01108     /*
01109      * Do any required software flow control.
01110      */
01111     if (flow_control && (flow_control & XOFF_SENT) != 0) {
01112         NutEnterCritical();
01113         if (USARTn_BASE.CSR.txrdy) {
01114             USARTn_BASE.thr = (ASCII_XON << AVR32_USART_THR_TXCHR_OFFSET) & AVR32_USART_THR_TXCHR_MASK;
01115             flow_control &= ~XON_PENDING;
01116         } else {
01117             flow_control |= XON_PENDING;
01118         }
01119         flow_control &= ~(XOFF_SENT | XOFF_PENDING);
01120         NutExitCritical();
01121     }
01122 #ifdef UART_RTS_BIT
01123     if (rts_control) {
01124         /* Enable RTS. */
01125         cbi(UART_RTS_PORT, UART_RTS_BIT);
01126     }
01127 #endif
01128 }
01129 
01130 /*
01131  * \brief Initialize the USART hardware driver.
01132  *
01133  * This function is called during device registration by the upper level
01134  * USART driver through the USARTDCB jump table.
01135  *
01136  * \return 0 on success, -1 otherwise.
01137  */
01138 static int Avr32UsartInit(void)
01139 {
01140     /*
01141      * Register receive and transmit interrupts.
01142      */
01143     if (NutRegisterIrqHandler(&SIG_UART, Avr32UsartInterrupt, &dcb_usart)) {
01144         return -1;
01145     }
01146 
01147     /* Disable GPIO on UART tx/rx pins. */
01148     gpio_enable_module_pin(USART_RX_PIN, USART_RX_FUNCTION);
01149     gpio_enable_module_pin(USART_TX_PIN, USART_TX_FUNCTION);
01150 
01151     /* Disable all USART interrupts.
01152      ** Interrupts needed should be set explicitly on every reset. */
01153     USARTn_BASE.idr = 0xFFFFFFFF;
01154     USARTn_BASE.csr;
01155 
01156     /* Reset mode and other registers that could cause unpredictable behavior after reset. */
01157     USARTn_BASE.mr = 0;
01158     USARTn_BASE.rtor = 0;
01159     USARTn_BASE.ttgr = 0;
01160 
01161     /* Shutdown TX and RX (will be re-enabled when setup has successfully completed),
01162      ** reset status bits and turn off DTR and RTS. */
01163     USARTn_BASE.cr = AVR32_USART_CR_RSTRX_MASK |
01164         AVR32_USART_CR_RSTTX_MASK |
01165         AVR32_USART_CR_RSTSTA_MASK |
01166         AVR32_USART_CR_RSTIT_MASK | AVR32_USART_CR_RSTNACK_MASK | AVR32_USART_CR_DTRDIS_MASK | AVR32_USART_CR_RTSDIS_MASK;
01167 
01168     USARTn_BASE.mr |= (8 - 5) << AVR32_USART_MR_CHRL_OFFSET |   /* 8 bit character length */
01169         AVR32_USART_MR_PAR_NONE << AVR32_USART_MR_PAR_OFFSET |  /* No parity */
01170         AVR32_USART_MR_CHMODE_NORMAL << AVR32_USART_MR_CHMODE_OFFSET | AVR32_USART_MR_NBSTOP_1 << AVR32_USART_MR_NBSTOP_OFFSET;
01171 
01172     /* Set normal mode. */
01173     USARTn_BASE.mr = (USARTn_BASE.mr & ~AVR32_USART_MR_MODE_MASK) | AVR32_USART_MR_MODE_NORMAL << AVR32_USART_MR_MODE_OFFSET;
01174 
01175     /* Enable input and output. */
01176     USARTn_BASE.cr |= AVR32_USART_CR_RXEN_MASK | AVR32_USART_CR_TXEN_MASK;
01177 
01178     return 0;
01179 }
01180 
01181 /*
01182  * \brief Deinitialize the USART hardware driver.
01183  *
01184  * This function is called during device deregistration by the upper
01185  * level USART driver through the USARTDCB jump table.
01186  *
01187  * \return 0 on success, -1 otherwise.
01188  */
01189 static int Avr32UsartDeinit(void)
01190 {
01191     /* Deregister receive and transmit interrupts. */
01192     NutRegisterIrqHandler(&SIG_UART, 0, 0);
01193 
01194     /* Shutdown TX and RX (will be re-enabled when setup has successfully completed),
01195      ** reset status bits and turn off DTR and RTS. */
01196     USARTn_BASE.cr = AVR32_USART_CR_RSTRX_MASK |
01197         AVR32_USART_CR_RSTTX_MASK |
01198         AVR32_USART_CR_RSTSTA_MASK |
01199         AVR32_USART_CR_RSTIT_MASK | AVR32_USART_CR_RSTNACK_MASK | AVR32_USART_CR_DTRDIS_MASK | AVR32_USART_CR_RTSDIS_MASK;
01200 
01201     /* Disable all UART interrupts. */
01202     USARTn_BASE.idr = 0xFFFFFFFF;
01203     USARTn_BASE.csr;
01204 
01205     /* Disable UART clock. */
01206 
01207     /* Enable GPIO on UART tx/rx pins. */
01208 
01209     /*
01210      * Disabling flow control shouldn't be required here, because it's up
01211      * to the upper level to do this on the last close or during
01212      * deregistration.
01213      */
01214 #ifdef UART_HDX_BIT
01215     /* Deregister transmit complete interrupt. */
01216     if (hdx_control) {
01217         hdx_control = 0;
01218         NutRegisterIrqHandler(&sig_UART_TRANS, 0, 0);
01219     }
01220 #endif
01221 
01222 #ifdef UART_CTS_BIT
01223     if (cts_sense) {
01224         cts_sense = 0;
01225         cbi(UART_CTS_DDR, UART_CTS_BIT);
01226         /* Deregister CTS sense interrupt. */
01227         NutRegisterIrqHandler(&UART_CTS_SIGNAL, 0, 0);
01228     }
01229 #endif
01230 
01231 #ifdef UART_RTS_BIT
01232     if (rts_control) {
01233         rts_control = 0;
01234         cbi(UART_RTS_DDR, UART_RTS_BIT);
01235     }
01236 #endif
01237 
01238     return 0;
01239 }
01240