📄 usart.c
字号:
* Returns: USART_SUCCESS or USART_INVALID_INPUT */int usart_init_modem(volatile struct avr32_usart_t * usart, struct usart_options_t * opt, long cpu_hz){ int retval; /* First: Setup standard RS323 */ if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS) return retval; /* Clear previous mode */ usart-> mr &= ~(0xf << AVR32_USART_MR_MODE_OFFSET); /* Set Modem mode */ usart-> mr |= (USART_MODE_MODEM << AVR32_USART_MR_MODE_OFFSET); return USART_SUCCESS;}/* * Description: Setup the usart to use the RS485 protocol * Arguments: *usart: Base address of the usart * *opt: Options needed to set up RS232 communcation (see usart_options_t) * cpu_hz: The module's clock frequency * Returns: USART_SUCCESS: mode successfully initialized * USART_INVALID_INPUT: one of the arguments are out of valid range * USART_MODE_FAULT: mode not initialized with multidrop parity */int usart_init_rs485(volatile struct avr32_usart_t * usart, struct usart_options_t * opt, long cpu_hz){ int retval; /* First: Setup standard RS323 */ if ((retval = usart_init_rs232(usart, opt, cpu_hz)) != USART_SUCCESS) return retval; /* Clear previous mode */ usart->mr &= ~(0xf << AVR32_USART_MR_MODE_OFFSET); /* Set Modem mode */ usart->mr |= (USART_MODE_RS485 << AVR32_USART_MR_MODE_OFFSET); return USART_SUCCESS;}/* * Description: Setup the usart to use ISO7816 T=0 or T=1 smartcard protocol * Arguments: *usart: Base address of the usart * *opt: Options needed to set up ISO7816 (see iso7816_options_t) * t: Which ISO7816 mode to use (T=0 or T=1) * Returns: USART_SUCCESS or USART_INVALID_INPUT */int usart_init_iso7816(volatile struct avr32_usart_t * usart, const struct iso7816_options_t * opt, int t, const long cpu_hz){ int retval; /* Reset the usart and shutdown RX and TX */ usart_reset(usart); if (opt == 0) /* Null pointer */ return USART_INVALID_INPUT; /* Don't care about charlength, parity or channelmode; All these fields are ignored in iso7816 mode. 8bit characters and even parity is always used */ if (t == 0) { /* Set USART mode to ISO7816, T=0 */ /* The T=0 protocol always use 2 stop bits */ usart->mr = (USART_MODE_ISO7816_T0 << AVR32_USART_MR_MODE_OFFSET) | (2 << AVR32_USART_MR_NBSTOP_OFFSET) | (opt->bit_order << AVR32_USART_MR_MSBF_OFFSET); /* Allow MSBF in T=0 */ } else if (t == 1) { /* Only LSB first in the T=1 protocol */ if (opt->bit_order != 0) return USART_INVALID_INPUT; /* max_iterations field is only used in T=0 mode */ if (opt->max_iterations != 0) return USART_INVALID_INPUT; /* Set USART mode to ISO7816, T=1 */ usart->mr = (USART_MODE_ISO7816_T1 << AVR32_USART_MR_MODE_OFFSET); /* The T=1 protocol always use 1 stop bit (no change needed) */ } else return USART_INVALID_INPUT; if ((retval = usart_set_baudrate(usart, opt->iso7816_hz, cpu_hz)) != USART_SUCCESS) return retval; /* Set FIDI register: bit rate = selected clock/FI_DI_ratio/16 */ usart->fidi = opt->fidi_ratio; /* Set ISO7816 spesific options in the MODE register */ usart->mr |= (opt->inhibit_nack << AVR32_USART_MR_INACK_OFFSET) | (opt->dis_suc_nack << AVR32_USART_MR_DSNACK_OFFSET) | (opt->max_iterations << AVR32_USART_MR_MAX_ITERATION_OFFSET) | (1 << AVR32_USART_MR_CLKO_OFFSET); /* Enable clock output */ /* Setup complete; enable input */ /* Leave TX disabled for now */ usart->cr |= (1<<AVR32_USART_CR_RXEN_OFFSET); return USART_SUCCESS;} /*---------------------------------------------------------------------------+ | | | READ AND RESET ERROR STATUS BITS | | | +---------------------------------------------------------------------------*//* * Description: This function resets the status bits indicating that a parity error, * framing error or overrun has occured. The rxbreak bit, indicating * a start/end of break condition on the rx-line, is also reset. * Arguments: *usart: Base address of the usart * Returns: nothing */void usart_reset_status(volatile struct avr32_usart_t * usart){ usart->cr |= (1<<AVR32_USART_CR_RSTSTA_OFFSET);}/* * Description: Checks if a parity error has occured since last status reset * Arguments: *usart: Base address of the usart * Returns: 1 if a parity error has been detected, otherwise 0 */int usart_parity_error(volatile struct avr32_usart_t * usart){ return ((usart->csr & (1<<AVR32_USART_CSR_PARE_OFFSET)) != 0);}/* * Description: Checks if a framing error has occured since last status reset * Arguments: *usart: Base address of the usart * Returns: 1 if a framing error has been detected, otherwise 0 */int usart_framing_error(volatile struct avr32_usart_t * usart){ return ((usart->csr & (1<<AVR32_USART_CSR_FRAME_OFFSET)) != 0);}/* * Description: Checks if a overrun error has occured since last status reset * Arguments: *usart: Base address of the usart * Returns: 1 if a overrun error has been detected, otherwise 0 */int usart_overrun_error(volatile struct avr32_usart_t * usart){ return ((usart->csr & AVR32_USART_CSR_OVRE_OFFSET)) != 0;} /*---------------------------------------------------------------------------+ | | | TRANSMIT/RECEIVE FUNCTIONS | | | +---------------------------------------------------------------------------*//* * Description: While in RS485-mode, receviers only accept data addressed to them. * A packet/char with the address tag set has to preceed any data. * usart_send_address() is used to address a receiver. This receiver should read * all the following data, until an address packet addresses someone else. * Arguments: *usart: Base address of the usart * addr: the address of the target device * Returns: USART_SUCCESS if the current mode is RS485 * USART_MODE_FAULT if called while in wrong mode */int usart_send_address(volatile struct avr32_usart_t * usart, int address){ /* Check if usart is in multidrop / RS485 mode */ if ( usart_mode_is_multidrop(usart) ) { /* Prepare to send an address */ usart->cr |= (1<<AVR32_USART_CR_SENDA_OFFSET); /* Write the address to TX */ usart_bw_write_char(usart, address); return USART_SUCCESS; } else { return USART_MODE_FAULT; }}/* * Description: Wait until the transmitter it ready (potentially forever), * then transmit the given character * Arguments: *usart: Base address of the usart * c: The character (up to 9 bits) to transmit * Returns: nothing */inline void usart_bw_write_char(volatile struct avr32_usart_t * usart, int c){ while (usart_write_char(usart, c) != USART_SUCCESS) { } return;}int usart_write_char(volatile struct avr32_usart_t * usart, int c){ if ((usart->csr & (1<<AVR32_USART_CSR_TXRDY_OFFSET)) != 0) { usart->thr = c; return USART_SUCCESS; } else return USART_TX_BUSY;}int usart_read_char(volatile struct avr32_usart_t * usart, int * c){ /* Check for errors; Frame, parity and overrun In RS485 mode a parity error would mean that we received an address char */ if (usart->csr & ((1 << AVR32_USART_CSR_OVRE_OFFSET) | (1 << AVR32_USART_CSR_FRAME_OFFSET) | (1 << AVR32_USART_CSR_PARE_OFFSET))) { return USART_RX_ERROR; } /* No error; if we really did receive a char, read it and return SUCCESS */ else if ((usart->csr & (1<<AVR32_USART_CSR_RXRDY_OFFSET)) != 0) { *c = (unsigned short)usart->rhr; return USART_SUCCESS; } else { return USART_RX_EMPTY; }} /* usart_read */int usart_getchar(volatile struct avr32_usart_t * usart){ int c, ret; while (((ret = usart_read_char(usart, &c)) == USART_RX_EMPTY)) { } if (ret == USART_RX_ERROR) return -1; else return c;}int usart_putchar(volatile struct avr32_usart_t * usart, int c){ int timeout = USART_DEFAULT_TIMEOUT; if (c == '\n'){ while ((usart_write_char(usart, '\r') != USART_SUCCESS) && (timeout>0) ){ timeout--; } if (timeout == 0) return -1; timeout = USART_DEFAULT_TIMEOUT; } while ((usart_write_char(usart, c) != USART_SUCCESS) && ( timeout>0 )){ timeout--; } if (timeout == 0) return -1; else return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -