/** * @file uart1.c * @brief UART1 module * * @author Rustem Kalimullin * @par E-mail: * hellos@mail.ru */ #include "common.h" #include "circ_buf.h" #ifndef UART1_BUFFER_SIZE #define UART1_BUFFER_SIZE 0x10 #endif #if (UART1_BUFFER_SIZE & (UART1_BUFFER_SIZE-1)) #error UART1_BUFFER_SIZE must be power of 2 #endif DECLARE_CIRC_BUFFER( RxBuf1, UART1_BUFFER_SIZE ); DECLARE_CIRC_BUFFER( TxBuf1, UART1_BUFFER_SIZE ); //--------------------------------------------------------- void uart1_purge(int mask) { istate_t int_state = __get_interrupt_state(); __disable_interrupt(); if( mask & PURGE_RXCLEAR ) circ_Init(&RxBuf1.b); if( mask & PURGE_TXCLEAR ) circ_Init(&TxBuf1.b); if( mask & PURGE_ABORT ) { U1CTL |= SWRST; __no_operation(); U1CTL &= ~SWRST; U1IE |= (URXIE1 | UTXIE1); } __set_interrupt_state(int_state); } //--------------------------------------------------------- void uart1_enable_parity(void) { istate_t int_state = __get_interrupt_state(); U1CTL = PENA | PEV | SWRST; // 7e1, Software Reset U1CTL &= ~SWRST; U1IE |= (URXIE1 | UTXIE1); __set_interrupt_state(int_state); } //--------------------------------------------------------- void uart1_init(long baud) { istate_t int_state = __get_interrupt_state(); unsigned int uart_div = (long)xtal_freq / (long)baud; __disable_interrupt(); U1CTL = CHAR | SWRST; // 8n1, Software Reset U1TCTL = SSEL1; // UCLK = SMCLK U1MCTL = 0x00; // no modulation U1BR0 = (unsigned char) (uart_div & 0xFF); U1BR1 = (unsigned char) (uart_div >> 8); uart1_purge( PURGE_ABORT | PURGE_RXCLEAR | PURGE_TXCLEAR ); P3SEL |= (1<<6)|(1<<7); // P3.6,7 = USART1 option select P3DIR |= (1<<6); // P3.6 = output direction U1ME |= (URXE1 | UTXE1); U1CTL &= ~SWRST; U1IE |= (URXIE1 | UTXIE1); __set_interrupt_state(int_state); } //--------------------------------------------------------- unsigned char uart1_getchar(void) { int t; do { t = circ_Get( &RxBuf1.b ); } while( t == -1 ); return t; } //--------------------------------------------------------- int uart1_getchar_timeout( unsigned int tot ) { int t; do { t = circ_Get( &RxBuf1.b ); if( t != -1 ) break; } while( --tot ); return t; } //--------------------------------------------------------- void uart1_putchar( unsigned char ch ) { while( circ_Put( &TxBuf1.b, ch ) == -1 ) continue; if ((U1TCTL & TXEPT)) SET_BITS(U1IFG,UTXIFG1); } //--------------------------------------------------------- void uart1_puts(const char *s) { while(*s) uart1_putchar(*s++); } //--------------------------------------------------------- int uart1_is_rxdata(void) { return ( circ_HasData( &RxBuf1.b ) ); } //--------------------------------------------------------- int uart1_is_txdata(void) { if ( circ_HasData( &TxBuf1.b ) ) { return 1; } else { return (U1IFG & UTXIFG1); } } //--------------------------------------------------------- #pragma vector=USART1RX_VECTOR __interrupt void uart1_rx_handler(void) { circ_Put( &RxBuf1.b, U1RXBUF ); } //--------------------------------------------------------- #pragma vector=USART1TX_VECTOR __interrupt void uart1_tx_handler(void) { int t = circ_Get( &TxBuf1.b ); if( t != -1 ) { U1TXBUF = t; } else { U1TCTL |= TXEPT; } }
#ifndef KR_UART1_INCLUDED #define KR_UART1_INCLUDED enum { PURGE_ABORT=1, PURGE_TXCLEAR=2, PURGE_RXCLEAR=4 }; void uart1_init( long baud ); void uart1_purge( int mask ); unsigned char uart1_getchar( void ); int uart1_getchar_timeout( unsigned int tot ); void uart1_putchar( unsigned char ch ); void uart1_puts( const char *s ); int uart1_is_rxdata( void ); int uart1_is_txdata( void ); void uart1_enable_parity( void ); #endif