Data Structures | Defines | Functions

usarts.c File Reference

generic USART access implementation More...

#include "config.h"
#include "usarts.h"
#include <avr/interrupt.h>
#include "xpal_board.h"
#include "usarts_int.h"
#include "usarts_all.h"
#include "baud-params.h"

Data Structures

struct  serial_param_s

Defines

#define USART_DEF   USART_DEF_CTRL
#define BAUD_TOL   (1)

Functions

baudrate_t usart_set_baudrate (usart_control_t *uc, baudrate_t baud)
 set baud rate for USART
baudrate_t usart_change_baudrate (usart_control_t *uc, int8_t incdec)
 change baud rate for USART
void usart_power (usart_control_t *uc, uint8_t onoff)
 power-off USART
usart_control_tusart_init (hlog_usart_t which, fifo_item_t *txbuf, fifo_size_t txsize, fifo_item_t *rxbuf, fifo_size_t rxsize)
void usart_disable (usart_control_t *uc)
 disable USART
void usart_enable (usart_control_t *uc)
 enable USART

Detailed Description

generic USART access implementation


Function Documentation

baudrate_t usart_change_baudrate ( usart_control_t uc,
int8_t  incdec 
)

change baud rate for USART

usart_change_baudrate() increases or decreases the baudrate of the USART according to the sign of incdec.

Parameters:
uc pointer to USART control structure
incdec >0: increase rate, <0: decrease rate by one step
Returns:
baud rate after change

{
  const struct serial_param_s *p;
  uint16_t rate_used = UBRRn(uc);
  uint8_t using_2x = UCSRnA(uc) & _BV(U2X0);
  uint16_t rate;
  uint8_t use_2x;

  /* find current rate */
  for (p = serial_param; (rate = pgm_read_word(&p->rate)); p++) {
    if (rate == rate_used && (using_2x!=0) == (pgm_read_byte(&p->use_2x) != 0))
      break;
  }
  if (rate == 0) return 0;

  if (incdec < 0) {
    /* decrease rate */
    if (p == serial_param)
      /* already at lowest, keep */
      return pgm_read_dword (&p->baud);
    p--;
    rate = pgm_read_word(&p->rate);
    use_2x = pgm_read_byte (&p->use_2x);
  } else if (incdec > 0) {
    /* increase rate */
    p++;
    rate = pgm_read_word (&p->rate);
    if (rate == 0)
      /* already at highest, keep */
      return pgm_read_dword (&p[-1].baud);
    use_2x = pgm_read_byte (&p->use_2x);
  } else {
    /* keep rate, return actual rate */
    return pgm_read_dword (&p->baud);
  }
  UBRRn(uc) = rate;
  if (use_2x)
    UCSRnA(uc) |= _BV(U2X0);
  else
    UCSRnA(uc) &= ~_BV(U2X0);

  return pgm_read_dword (&p->baud);
}

void usart_disable ( usart_control_t  ) 

disable USART

Parameters:
uc pointer to USART control structure

{
  UCSRnB(uc) &= ~(_BV(RXCIE0)|_BV(TXCIE0)|_BV(UDRIE0)
                  |_BV(RXEN0)|_BV(TXEN0));
}

void usart_enable ( usart_control_t uc  ) 

enable USART

This actually switches on the USART indicated by uc.

Parameters:
uc pointer to USART control structure

{
  UCSRnA(uc) &= _BV(U2X0); /* reset all bits except U2X (double baudrate) */
  UCSRnB(uc) |= (fifo_get_buffer(&uc->rxbuf) ? (_BV(RXCIE0)|_BV(RXEN0)) : 0)
    | (fifo_get_buffer(&uc->txbuf) ? (_BV(UDRIE0)|_BV(TXEN0)) : 0);
}

void usart_power ( usart_control_t ,
uint8_t  onoff 
)

power-off USART

This puts the USART into power-down mode

Parameters:
uc pointer to USART control structure
onoff when 0, power-off; else power-on

{
  if (onoff) {
    if (uc == &usart_control_3) {
      HL_EX232_CTL_PORT &= ~_BV(HL_EX232_EN);
    }
    /* enable power */
    *(uc->prr) &= ~(uc->prusart);
  } else {
    *(uc->prr) |= (uc->prusart);
    if (uc == &usart_control_3) {
      /* external */
      HL_EX232_CTL_PORT |= _BV(HL_EX232_EN);
    }
  }
}

baudrate_t usart_set_baudrate ( usart_control_t uc,
baudrate_t  baud 
)

set baud rate for USART

Parameters:
uc pointer to USART control structure
baud wanted rate
Returns:
actual rate, 0 if not possible

{
  const struct serial_param_s *p;
  baudrate_t bd;

  for (p = serial_param; (bd = pgm_read_dword(&p->baud), bd && (bd != baud)); p++);

  if (bd) {
    uint16_t rate = pgm_read_word (&p->rate);
    uint8_t use_2x = pgm_read_byte (&p->use_2x);
    UBRRn(uc) = rate;
    if (use_2x)
      UCSRnA(uc) |= _BV(U2X0);
    else
      UCSRnA(uc) &= ~_BV(U2X0);

    return baud;
  }
  return 0;
}