summaryrefslogtreecommitdiff
path: root/digital/zigbit/bitcloud/stack/Components/HAL/avr/atmega1281/common/src/halUsart.c
blob: 90388ed07666a2bb953418d62232055ede0a7858 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/**************************************************************************//**
\file  halUsart.c

\brief Implementation of usart hardware-dependent module.

\author
    Atmel Corporation: http://www.atmel.com \n
    Support email: avr@atmel.com

  Copyright (c) 2008-2011, Atmel Corporation. All rights reserved.
  Licensed under Atmel's Limited License Agreement (BitCloudTM).

\internal
  History:
    29/05/07 E. Ivanov - Created
*******************************************************************************/
/******************************************************************************
 *   WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK.  *
 *   EXPERT USERS SHOULD PROCEED WITH CAUTION.                                *
 ******************************************************************************/
/******************************************************************************
                   Includes section
******************************************************************************/
#include <types.h>
#include <sleep.h>
#include <usart.h>
#include <halSleepTimerClock.h>
#include <halAppClock.h>
#include <halIrq.h>
#include <halDiagnostic.h>

/******************************************************************************
                   Prototypes section
******************************************************************************/
void halPostUsartTask(HalUsartTaskId_t taskId);

/******************************************************************************
                   External global variables section
******************************************************************************/
extern volatile bool halEnableDtrWakeUp;
extern void (* dtrWakeUpCallback)(void);

/******************************************************************************
                   Implementations section
******************************************************************************/
/**************************************************************************//**
  \brief Sets USART module parameters.
  \param
    usartmode - pointer to HAL_UsartDescriptor_t
  \return
    none.
******************************************************************************/
void halSetUsartConfig(HAL_UsartDescriptor_t *usartMode)
{
  UCSRnB(usartMode->tty) = 0x00; // disable usart
  UBRRn(usartMode->tty) = usartMode->baudrate; // usart speed

  if (USART_MODE_ASYNC == usartMode->mode)
  {
    UCSRnA(usartMode->tty) = (uint8_t)USART_DOUBLE_SPEED << U2X0; // Double the USART Transmition Speed
    UCSRnC(usartMode->tty) = 0x00;
  }
  else
  {
    UCSRnA(usartMode->tty) = 0;
    UCSRnC(usartMode->tty) = usartMode->edge; // edge select
  }

  UCSRnC(usartMode->tty) |= usartMode->mode;
  UCSRnC(usartMode->tty) |= usartMode->dataLength;     // character size
  UCSRnC(usartMode->tty) |= usartMode->parity;   // parity mode
  UCSRnC(usartMode->tty) |= usartMode->stopbits; // stop bit select
  UCSRnA(usartMode->tty) |= (1 << RXC0); // clear receive interrupt
  UCSRnB(usartMode->tty) |= (1 << RXEN1) | (1 << TXEN1); // usart enable
  UCSRnB(usartMode->tty) |= (1 << RXCIE0) ; // receive interrupt enable
}

/**************************************************************************//**
 \brief The interrupt handler of USART0 - data register is empty.
******************************************************************************/
ISR(USART0_UDRE_vect)
{
  BEGIN_MEASURE
  // We must disable the interrupt because we must "break" context.
  halDisableUsartDremInterrupt(USART_CHANNEL_0);
  halPostUsartTask(HAL_USART_TASK_USART0_DRE);
  END_MEASURE(HALISR_USART0_UDR_TIME_LIMIT)
}

/**************************************************************************//**
 \brief The interrupt handler of USART0 - transmission is completed.
******************************************************************************/
ISR(USART0_TX_vect)
{
  BEGIN_MEASURE
  halDisableUsartTxcInterrupt(USART_CHANNEL_0);
  halPostUsartTask(HAL_USART_TASK_USART0_TXC);
  END_MEASURE(HALISR_USART0_TX_TIME_LIMIT)
}

/**************************************************************************//**
 \brief The interrupt handler of USART0 - reception is completed.
******************************************************************************/
ISR(USART0_RX_vect)
{
  BEGIN_MEASURE
  uint8_t  status = UCSR0A;
  uint8_t  data = UDR0;

  if (!(status & ((1 << FE0) | (1 << DOR0) | (1 << UPE0))))
  {
    halUsartRxBufferFiller(USART_CHANNEL_0, data);
    halPostUsartTask(HAL_USART_TASK_USART0_RXC);
  }
  #if defined(_USE_USART_ERROR_EVENT_)
    else // There is an error in the received byte.
    {
      halUsartSaveErrorReason(USART_CHANNEL_0, status);
      halPostUsartTask(HAL_USART_TASK_USART0_ERR);
    }
  #endif

  END_MEASURE(HALISR_USART0_RX_TIME_LIMIT)
}

/**************************************************************************//**
 \brief The interrupt handler of USART1 - data register is empty.
******************************************************************************/
ISR(USART1_UDRE_vect)
{
  BEGIN_MEASURE
  // We must disable the interrupt because we must "break" context.
  halDisableUsartDremInterrupt(USART_CHANNEL_1);
  halPostUsartTask(HAL_USART_TASK_USART1_DRE);
  END_MEASURE(HALISR_USART1_UDRE_TIME_LIMIT)
}

/**************************************************************************//**
 \brief The interrupt handler of USART1 - transmission is completed.
******************************************************************************/
ISR(USART1_TX_vect)
{
  BEGIN_MEASURE
  halDisableUsartTxcInterrupt(USART_CHANNEL_1);
  halPostUsartTask(HAL_USART_TASK_USART1_TXC);
  END_MEASURE(HALISR_USART1_TX_TIME_LIMIT)
}

/**************************************************************************//**
 \brief The interrupt handler of USART1 - reception is completed.
******************************************************************************/
ISR(USART1_RX_vect)
{
  BEGIN_MEASURE
  uint8_t  status = UCSR1A;
  uint8_t  data = UDR1;

  if (!(status & ((1 << FE1) | (1 << DOR1) | (1 << UPE1))))
  {
    halUsartRxBufferFiller(USART_CHANNEL_1, data);
    halPostUsartTask(HAL_USART_TASK_USART1_RXC);
  }
  #if defined(_USE_USART_ERROR_EVENT_)
    else // There is an error in the received byte.
    {
      halUsartSaveErrorReason(USART_CHANNEL_1, status);
      halPostUsartTask(HAL_USART_TASK_USART1_ERR);
    }
  #endif
  END_MEASURE(HALISR_USART1_RX_TIME_LIMIT)
}

/**************************************************************************//**
/brief External interrupt 4 (DTR) handler
******************************************************************************/
ISR(INT4_vect)
{
  BEGIN_MEASURE
  halWakeupFromIrq();

  if (halEnableDtrWakeUp)
  { /* enable DTR (irq 4) wake up */
    halDisableIrqInterrupt(IRQ_4);
  } /* enable DTR (irq 4) wake up */

  if (NULL != dtrWakeUpCallback)
    dtrWakeUpCallback();
  END_MEASURE(HALISR_INT4_TIME_LIMIT)
}
// eof halUsart.c