Serial.h 8.51 KB
Newer Older
1
2
/*
             LUFA Library
3
     Copyright (C) Dean Camera, 2011.
4

5
  dean [at] fourwalledcubicle [dot] com
6
           www.lufa-lib.org
7
8
9
*/

/*
10
  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
  Permission to use, copy, modify, distribute, and sell this
13
  software and its documentation for any purpose is hereby granted
14
  without fee, provided that the above copyright notice appear in
15
  all copies and that both that the copyright notice and this
16
17
18
  permission notice and warranty disclaimer appear in supporting
  documentation, and that the name of the author not be used in
  advertising or publicity pertaining to distribution of the
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  software without specific, written prior permission.

  The author disclaim all warranties with regard to this
  software, including all implied warranties of merchantability
  and fitness.  In no event shall the author be liable for any
  special, indirect or consequential damages or any damages
  whatsoever resulting from loss of use, data or profits, whether
  in an action of contract, negligence or other tortious action,
  arising out of or in connection with the use or performance of
  this software.
*/

/** \file
 *  \brief Master include file for the USART peripheral driver.
 *
 *  Driver for the USART subsystem on supported USB AVRs.
 */
36

37
38
39
40
41
/** \ingroup Group_PeripheralDrivers
 *  @defgroup Group_Serial Serial USART Driver - LUFA/Drivers/Peripheral/Serial.h
 *
 *  \section Sec_Dependencies Module Source Dependencies
 *  The following files must be built with any user project that uses this module:
42
 *    - LUFA/Drivers/Peripheral/Serial.c <i>(Makefile source module name: LUFA_SRC_SERIAL)</i>
43
 *
44
 *  \section Sec_ModDescription Module Description
45
46
47
 *  Hardware serial USART driver. This module provides an easy to use driver for
 *  the setup of and transfer of data over the AVR's USART port.
 *
48
49
50
51
 *  \section Sec_ExampleUsage Example Usage
 *  The following snippet is an example of how this module may be used within a typical
 *  application.
 *
52
53
54
55
56
57
58
59
60
61
62
 *  \code
 *      // Initialise the serial USART driver before first use, with 9600 baud (and no double-speed mode)
 *      Serial_Init(9600, false);
 *
 *      // Send a string through the USART
 *      Serial_TxString("Test String\r\n");
 *
 *      // Receive a byte through the USART
 *      uint8_t DataByte = Serial_RxByte();
 *  \endcode
 *
63
64
 *  @{
 */
65

66
67
68
69
70
71
72
#ifndef __SERIAL_H__
#define __SERIAL_H__

	/* Includes: */
		#include <avr/io.h>
		#include <avr/pgmspace.h>
		#include <stdbool.h>
73
		#include <stdio.h>
74

75
76
77
78
79
80
81
82
		#include "../../Common/Common.h"
		#include "../Misc/TerminalCodes.h"

	/* Enable C linkage for C++ Compilers: */
		#if defined(__cplusplus)
			extern "C" {
		#endif

83
84
85
86
87
88
89
90
91
92
93
94
	/* Private Interface - For use in library only: */
	#if !defined(__DOXYGEN__)
		/* External Variables: */
			extern FILE USARTSerialStream;
	
		/* Function Prototypes: */
			int Serial_putchar(char DataByte,
			                   FILE *Stream);
			int Serial_getchar(FILE *Stream);
			int Serial_getchar_Blocking(FILE *Stream);
	#endif

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
	/* Public Interface - May be used in end-application: */
		/* Macros: */
			/** Macro for calculating the baud value from a given baud rate when the U2X (double speed) bit is
			 *  not set.
			 */
			#define SERIAL_UBBRVAL(baud)    ((((F_CPU / 16) + (baud / 2)) / (baud)) - 1)

			/** Macro for calculating the baud value from a given baud rate when the U2X (double speed) bit is
			 *  set.
			 */
			#define SERIAL_2X_UBBRVAL(baud) ((((F_CPU / 8) + (baud / 2)) / (baud)) - 1)

		/* Function Prototypes: */
			/** Transmits a given string located in program space (FLASH) through the USART.
			 *
110
			 *  \param[in] FlashStringPtr  Pointer to a string located in program space.
111
			 */
112
			void Serial_SendString_P(const char* FlashStringPtr) ATTR_NON_NULL_PTR_ARG(1);
113
114
115

			/** Transmits a given string located in SRAM memory through the USART.
			 *
116
			 *  \param[in] StringPtr  Pointer to a string located in SRAM space.
117
			 */
118
119
			void Serial_SendString(const char* StringPtr) ATTR_NON_NULL_PTR_ARG(1);
			
120
121
122
123
124
125
126
			/** Transmits a given buffer located in SRAM memory through the USART.
			 *
			 *  \param[in] Buffer  Pointer to a buffer containing the data to send.
			 *  \param[in] Length  Length of the data to send, in bytes.
			 */
			void Serial_SendData(const uint8_t* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);

127
		/* Inline Functions: */
128
			/** Initializes the USART, ready for serial data transmission and reception. This initializes the interface to
129
130
			 *  standard 8-bit, no parity, 1 stop bit settings suitable for most applications.
			 *
131
132
			 *  \param[in] BaudRate     Serial baud rate, in bits per second.
			 *  \param[in] DoubleSpeed  Enables double speed mode when set, halving the sample time to double the baud rate.
133
			 */
134
135
			static inline void Serial_Init(const uint32_t BaudRate,
			                               const bool DoubleSpeed)
136
			{
137
138
139
				UBRR1  = (DoubleSpeed ? SERIAL_2X_UBBRVAL(BaudRate) : SERIAL_UBBRVAL(BaudRate));

				UCSR1C = ((1 << UCSZ11) | (1 << UCSZ10));
140
141
				UCSR1A = (DoubleSpeed ? (1 << U2X1) : 0);
				UCSR1B = ((1 << TXEN1)  | (1 << RXEN1));
142

143
				DDRD  |= (1 << 3);
144
145
146
147
148
149
150
				PORTD |= (1 << 2);
			}

			/** Turns off the USART driver, disabling and returning used hardware to their default configuration. */
			static inline void Serial_ShutDown(void)
			{
				UCSR1B = 0;
151
				UCSR1A = 0;
152
				UCSR1C = 0;
153
154

				UBRR1  = 0;
155

156
				DDRD  &= ~(1 << 3);
157
158
				PORTD &= ~(1 << 2);
			}
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
			/** Creates a standard character stream from the USART so that it can be used with all the regular functions
			 *  in the avr-libc \c <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created
			 *  stream is bidirectional and can be used for both input and output functions.
			 *
			 *  Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
			 *  fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
			 *  be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
			 *  line buffering.
			 *
			 *  \param[in,out] Stream  Pointer to a FILE structure where the created stream should be placed, if \c NULL stdio
			 *                         and stdin will be configured to use the USART.
			 *
			 *  \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used.
			 */
			static inline void Serial_CreateStream(FILE* Stream)
			{
				if (!(Stream))
				{
					Stream = &USARTSerialStream;
					stdin  = Stream;
					stdout = Stream;
				}
			
				*Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar, _FDEV_SETUP_RW);
			}

			/** Identical to \ref Serial_CreateStream(), except that reads are blocking until the calling stream function terminates
			 *  the transfer.
			 *
			 *  \param[in,out] Stream  Pointer to a FILE structure where the created stream should be placed, if \c NULL stdio
			 *                         and stdin will be configured to use the USART.
			 *
			 *  \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used.
			 */
			static inline void Serial_CreateBlockingStream(FILE* Stream)
			{
				if (!(Stream))
				{
					Stream = &USARTSerialStream;
					stdin  = Stream;
					stdout = Stream;
				}

				*Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar_Blocking, _FDEV_SETUP_RW);
			}

206
207
			/** Indicates whether a character has been received through the USART.
			 *
208
			 *  \return Boolean \c true if a character has been received, \c false otherwise.
209
210
211
212
213
214
			 */
			static inline bool Serial_IsCharReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
			static inline bool Serial_IsCharReceived(void)
			{
				return ((UCSR1A & (1 << RXC1)) ? true : false);
			}
215

216
217
			/** Transmits a given byte through the USART.
			 *
218
			 *  \param[in] DataByte  Byte to transmit through the USART.
219
			 */
220
221
			static inline void Serial_SendByte(const char DataByte) ATTR_ALWAYS_INLINE;
			static inline void Serial_SendByte(const char DataByte)
222
223
224
225
226
			{
				while (!(UCSR1A & (1 << UDRE1)));
				UDR1 = DataByte;
			}

227
			/** Receives the next byte from the USART.
228
			 *
229
			 *  \return Next byte received from the USART, or a negative value if no byte has been received.
230
			 */
231
232
			static inline int16_t Serial_ReceiveByte(void) ATTR_ALWAYS_INLINE;
			static inline int16_t Serial_ReceiveByte(void)
233
			{
234
235
236
				if (!(Serial_IsCharReceived()))
				  return -1;
				
237
				return UDR1;
238
239
240
241
242
243
			}

	/* Disable C linkage for C++ Compilers: */
		#if defined(__cplusplus)
			}
		#endif
244

245
246
247
#endif

/** @} */
248