1
+ /* ----------------------------------------------------------------------------
2
+ * SAM Software Package License
3
+ * ----------------------------------------------------------------------------
4
+ * Copyright (c) 2011-2012, Atmel Corporation
5
+ *
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following condition is met:
10
+ *
11
+ * Redistributions of source code must retain the above copyright notice,
12
+ * this list of conditions and the disclaimer below.
13
+ *
14
+ * Atmel's name may not be used to endorse or promote products derived from
15
+ * this software without specific prior written permission.
16
+ *
17
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ * ----------------------------------------------------------------------------
28
+ */
29
+
30
+ #include "uart_driver.h"
31
+
32
+ bool uart_drv_error_flag = false;
33
+
34
+ uint32_t uart_get_sercom_index (Sercom * sercom_instance )
35
+ {
36
+ /* Save all available SERCOM instances for compare. */
37
+ Sercom * sercom_instances [SERCOM_INST_NUM ] = SERCOM_INSTS ;
38
+
39
+ /* Find index for sercom instance. */
40
+ for (uint32_t i = 0 ; i < SERCOM_INST_NUM ; i ++ ) {
41
+ if ((uintptr_t )sercom_instance == (uintptr_t )sercom_instances [i ]) {
42
+ return i ;
43
+ }
44
+ }
45
+
46
+ return 0 ;
47
+ }
48
+
49
+ void uart_basic_init (Sercom * sercom , uint16_t baud_val , enum uart_pad_settings pad_conf )
50
+ {
51
+ /* Wait for synchronization */
52
+ while (sercom -> USART .SYNCBUSY .bit .ENABLE );
53
+ /* Disable the SERCOM UART module */
54
+ sercom -> USART .CTRLA .bit .ENABLE = 0 ;
55
+ /* Wait for synchronization */
56
+ while (sercom -> USART .SYNCBUSY .bit .SWRST );
57
+ /* Perform a software reset */
58
+ sercom -> USART .CTRLA .bit .SWRST = 1 ;
59
+ /* Wait for synchronization */
60
+ while (sercom -> USART .CTRLA .bit .SWRST );
61
+ /* Wait for synchronization */
62
+ while (sercom -> USART .SYNCBUSY .bit .SWRST || sercom -> USART .SYNCBUSY .bit .ENABLE );
63
+ /* Update the UART pad settings, mode and data order settings */
64
+ sercom -> USART .CTRLA .reg = pad_conf | SERCOM_USART_CTRLA_MODE (1 ) | SERCOM_USART_CTRLA_DORD ;
65
+ /* Wait for synchronization */
66
+ while (sercom -> USART .SYNCBUSY .bit .CTRLB );
67
+ /* Enable transmit and receive and set data size to 8 bits */
68
+ sercom -> USART .CTRLB .reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE (0 );
69
+ /* Load the baud value */
70
+ sercom -> USART .BAUD .reg = baud_val ;
71
+ /* Wait for synchronization */
72
+ while (sercom -> USART .SYNCBUSY .bit .ENABLE );
73
+ /* Enable SERCOM UART */
74
+ sercom -> USART .CTRLA .bit .ENABLE = 1 ;
75
+ }
76
+
77
+ void uart_disable (Sercom * sercom )
78
+ {
79
+ /* Wait for synchronization */
80
+ while (sercom -> USART .SYNCBUSY .bit .ENABLE );
81
+ /* Disable SERCOM UART */
82
+ sercom -> USART .CTRLA .bit .ENABLE = 0 ;
83
+ }
84
+
85
+ void uart_write_byte (Sercom * sercom , uint8_t data )
86
+ {
87
+ /* Wait for Data Register Empty flag */
88
+ while (!sercom -> USART .INTFLAG .bit .DRE );
89
+ /* Write the data to DATA register */
90
+ sercom -> USART .DATA .reg = (uint16_t )data ;
91
+ }
92
+
93
+ uint8_t uart_read_byte (Sercom * sercom )
94
+ {
95
+ /* Wait for Receive Complete flag */
96
+ while (!sercom -> USART .INTFLAG .bit .RXC );
97
+ /* Check for errors */
98
+ if (sercom -> USART .STATUS .bit .PERR || sercom -> USART .STATUS .bit .FERR || sercom -> USART .STATUS .bit .BUFOVF )
99
+ /* Set the error flag */
100
+ uart_drv_error_flag = true;
101
+ /* Return the read data */
102
+ return ((uint8_t )sercom -> USART .DATA .reg );
103
+ }
104
+
105
+ void uart_write_buffer_polled (Sercom * sercom , uint8_t * ptr , uint16_t length )
106
+ {
107
+ /* Do the following for specified length */
108
+ do {
109
+ /* Wait for Data Register Empty flag */
110
+ while (!sercom -> USART .INTFLAG .bit .DRE );
111
+ /* Send data from the buffer */
112
+ sercom -> USART .DATA .reg = (uint16_t )* ptr ++ ;
113
+ } while (length -- );
114
+ }
115
+
116
+ void uart_read_buffer_polled (Sercom * sercom , uint8_t * ptr , uint16_t length )
117
+ {
118
+ /* Do the following for specified length */
119
+ do {
120
+ /* Wait for Receive Complete flag */
121
+ while (!sercom -> USART .INTFLAG .bit .RXC );
122
+ /* Check for errors */
123
+ if (sercom -> USART .STATUS .bit .PERR || sercom -> USART .STATUS .bit .FERR || sercom -> USART .STATUS .bit .BUFOVF )
124
+ /* Set the error flag */
125
+ uart_drv_error_flag = true;
126
+ /* Store the read data to the buffer */
127
+ * ptr ++ = (uint8_t )sercom -> USART .DATA .reg ;
128
+ } while (length -- );
129
+ }
0 commit comments