PIC24 Support Libraries
pic24_uart.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 
31 
32 
33 #include "pic24_clockfreq.h"
34 #include "pic24_uart.h"
35 #include "pic24_ports.h"
36 #include "pic24_unittest.h"
37 #include "pic24_delay.h"
38 #include "pic24_util.h"
39 
40 // Only include if this UART exists.
41 #if (NUM_UART_MODS >= 1)
42 
43 // For the bootloader, include only configUART1 to minimize size.
44 # ifndef BOOTLOADER
45 
46 
47 // Documentation for this file. If the \file tag is not present,
48 // this file will not be documented.
49 // Note: place this comment below the #if NUM_UART_MODS so Doxygen
50 // will only see it once.
51 /** \file
52 * UART support functions.
53 * \par Interrupt-driven TX/RX
54 * By default, the UART functions use polling for both RX and TX.
55 * Define the macro UARTx_TX_INTERRUPT (i.e., UART1_TX_INTERRUPT) in your project file if you want interrupt-driven TX for the UARTx (i.e., UART1) module.
56 * For interrupt-driven TX, macro UARTx_TX_FIFO_SIZE sets the TX software FIFO size (default 32), and UARTx_TX_INTERRUPT_PRIORITY sets the priority (default 1).
57 * \par
58 * Define the macro UARTx_RX_INTERRUPT (i.e., UART1_RX_INTERRUPT) in your project file if you want interrupt-driven RX for the UARTx (i.e., UART1) module.
59 * For interrupt-driven RX, macro UARTx_RX_FIFO_SIZE sets the RX software FIFO size (default 32), and UARTx_RX_INTERRUPT_PRIORITY sets the priority (default 1).
60 */
61 
62 
63 /*********************************************************
64  * Public functions intended to be called by other files *
65  *********************************************************/
66 /**
67 * Check UART1 RX for error, call \em reportError() if error found.
68 *
69 */
70 void checkRxErrorUART1(void) {
71  uint8_t u8_c;
72  //check for errors, reset if detected.
73  if (U1STAbits.PERR) {
74  u8_c = U1RXREG; //clear error
75  reportError("UART1 parity error\n");
76  }
77  if (U1STAbits.FERR) {
78  u8_c = U1RXREG; //clear error
79  reportError("UART1 framing error\n");
80  }
81  if (U1STAbits.OERR) {
82  U1STAbits.OERR = 0; //clear error
83  reportError("UART1 overrun error\n");
84  }
85 }
86 
87 
88 
89 
90 #ifdef UART1_TX_INTERRUPT
91 /**
92 
93 */
94 # ifndef UART1_TX_FIFO_SIZE
95 # define UART1_TX_FIFO_SIZE 32 //choose a size
96 # endif
97 
98 # ifndef UART1_TX_INTERRUPT_PRIORITY
99 # define UART1_TX_INTERRUPT_PRIORITY 1
100 # endif
101 
102 volatile uint8_t au8_txFifo1[UART1_TX_FIFO_SIZE];
103 volatile uint16_t u16_txFifo1Head = 0;
104 volatile uint16_t u16_txFifo1Tail = 0;
105 
106 /**
107 * Output \em u8_c to UART1 TX.
108 * \param u8_c Character to write
109 */
110 void outChar1(uint8_t u8_c) {
111  uint16_t u16_tmp;
112 
113  u16_tmp = u16_txFifo1Head;
114  u16_tmp++;
115  if (u16_tmp == UART1_TX_FIFO_SIZE) u16_tmp = 0; //wrap if needed
116  while (u16_tmp == u16_txFifo1Tail)
117  doHeartbeat();
118 
119  au8_txFifo1[u16_tmp] = u8_c; //write to buffer
120  u16_txFifo1Head = u16_tmp; //update head
121  _U1TXIE = 1; //enable interrupt
122 }
123 
124 void _ISR _U1TXInterrupt (void) {
125  if (u16_txFifo1Head == u16_txFifo1Tail) {
126  //empty TX buffer, disable the interrupt, do not clear the flag
127  _U1TXIE = 0;
128  } else {
129  //at least one free spot in the TX buffer!
130  u16_txFifo1Tail++; //increment tail pointer
131  if (u16_txFifo1Tail == UART1_TX_FIFO_SIZE)
132  u16_txFifo1Tail = 0; //wrap if needed
133  _U1TXIF = 0; //clear the interrupt flag
134  //transfer character from software buffer to transmit buffer
135  U1TXREG = au8_txFifo1[u16_txFifo1Tail];
136  }
137 }
138 
139 
140 #else
141 /**
142 * Output \em u8_c to UART1 TX.
143 * \param u8_c Character to write
144 */
145 void outChar1(uint8_t u8_c) {
146  //wait for transmit buffer to be empty
148  doHeartbeat();
149  U1TXREG = u8_c;
150 }
151 #endif
152 
153 #ifdef UART1_RX_INTERRUPT
154 //Interrupt driven RX
155 # ifndef UART1_RX_FIFO_SIZE
156 # define UART1_RX_FIFO_SIZE 32 //choose a size
157 # endif
158 
159 # ifndef UART1_RX_INTERRUPT_PRIORITY
160 # define UART1_RX_INTERRUPT_PRIORITY 1
161 # endif
162 
163 volatile uint8_t au8_rxFifo1[UART1_RX_FIFO_SIZE];
164 volatile uint16_t u16_rxFifo1Head = 0;
165 volatile uint16_t u16_rxFifo1Tail = 0;
166 
167 /**
168 * Return true if character is ready to be read
169 */
170 uint8_t isCharReady1(void) {
171  return(u16_rxFifo1Head != u16_rxFifo1Tail);
172 }
173 
174 /**
175 * Wait for a byte to be available from UART1 RX.
176 * \return Character read from UART1 RX.
177 */
178 uint8_t inChar1(void) {
179  while (u16_rxFifo1Head == u16_rxFifo1Tail)
180  doHeartbeat();
181  u16_rxFifo1Tail++;
182  if (u16_rxFifo1Tail == UART1_RX_FIFO_SIZE) u16_rxFifo1Tail=0; //wrap
183  return au8_rxFifo1[u16_rxFifo1Tail]; //return the character
184 }
185 
186 void _ISR _U1RXInterrupt (void) {
187  int8_t u8_c;
188 
189  _U1RXIF = 0; //clear the UART RX interrupt bit
191  u8_c = U1RXREG; //read character
192  u16_rxFifo1Head++; //increment head pointer
193  if (u16_rxFifo1Head == UART1_RX_FIFO_SIZE)
194  u16_rxFifo1Head = 0; //wrap if needed
195  if (u16_rxFifo1Head == u16_rxFifo1Tail) {
196  //FIFO overrun!, report error
197  reportError("UART1 RX Interrupt FIFO overrun!");
198  }
199  au8_rxFifo1[u16_rxFifo1Head] = u8_c; //place in buffer
200 }
201 
202 #else
203 /**
204 * Return true if character is ready to be read
205 */
207  return(IS_CHAR_READY_UART1());
208 }
209 
210 /**
211 * Wait for a byte to be available from UART1 RX.
212 * \return Character read from UART1 RX.
213 */
215  //do heartbeat while waiting for character.
216  // Use a do-while to insure error checks
217  // are always run.
218  while (!IS_CHAR_READY_UART1())
219  doHeartbeat();
221  return U1RXREG; //read the receive register
222 }
223 #endif
224 
225 
226 // Include this for the non-bootloader case. Also include it for the bootloader if this is the UART the bootloader uses.
227 #endif // # ifndef BOOTLOADER
228 #if !defined(BOOTLOADER) || (DEFAULT_UART == 1)
229 
230 /** Chose a default BRGH for UART1, used by
231  * \ref configUART1 to set up UART1.
232  */
233 #ifndef DEFAULT_BRGH1
234 # define DEFAULT_BRGH1 DEFAULT_BRGH
235 #endif
236 
237 #if (DEFAULT_BRGH1 != 0) && (DEFAULT_BRGH1 != 1)
238 # error "Invalid value specified for DEFAULT_BRGH1."
239 #endif
240 
241 
242 /** Configure the UART. Settings chosen:
243  * - TX is on RP11
244  * - RX is on RP10
245  * - Format is 8 data bits, no parity, 1 stop bit
246  * - CTS, RTS, and BCLK not used
247  *
248  * \param u32_baudRate The baud rate to use.
249  */
250 void configUART1(uint32_t u32_baudRate) {
251  /************************* UART config ********************/
252  // See comments in the #warning statements below for
253  // instructions on how to modify this configuration.
254  // More information on each of these board is given
255  // in the HARDWARE_PLATFORM section of pic24_libconfig.h.
256 #if (HARDWARE_PLATFORM == EXPLORER16_100P) || (HARDWARE_PLATFORM == HARDMAPPED_UART)
257  // There's nothing to do, since pins on these boards are
258  // mapped to fixed ports.
259 #elif (1 == 1)
260  // The following pin mappings will apply only to UART 1.
261  // Change them as necessary for your device.
262 # if (HARDWARE_PLATFORM == DANGEROUS_WEB)
263 # warning Building configUART1() for the Dangerous Web target.
264  CONFIG_RB14_AS_DIG_INPUT(); // RX pin must be digital input
265  CONFIG_U1RX_TO_RP(RB14_RP); // U1RX <- RB14
266  CONFIG_RB15_AS_DIG_OUTPUT(); // TX pin must be digital output
267  CONFIG_U1TX_TO_RP(RB15_RP); // U1TX -> RB15
268 # elif (HARDWARE_PLATFORM == STARTER_BOARD_28P)
269 # warning Building configUART1() for the StarterBoard_28P target.
270  CONFIG_RB9_AS_DIG_INPUT(); // RX pin must be digital input
271  CONFIG_U1RX_TO_RP(RB9_RP); // U1RX <- RB9
272  CONFIG_RB8_AS_DIG_OUTPUT(); // TX pin must be digital output
273  CONFIG_U1TX_TO_RP(RB8_RP); // U1TX -> RB8
274 # elif (HARDWARE_PLATFORM == DEFAULT_DESIGN) || (HARDWARE_PLATFORM == MICROSTICK2)
275  CONFIG_RB10_AS_DIG_INPUT(); // RX pin must be digital input
276  CONFIG_U1RX_TO_RP(RB10_RP); // U1RX <- RB10
277  CONFIG_RB11_AS_DIG_OUTPUT(); // TX pin must be digital output
278  CONFIG_U1TX_TO_RP(RB11_RP); // U1TX -> RB11
279 # elif (HARDWARE_PLATFORM == EMBEDDED_C1)
280 # warning Building configUART1() for the Rev.C1 Embedded Systems target.
281  CONFIG_RB12_AS_DIG_INPUT(); // RX pin must be digital input
282  CONFIG_U1RX_TO_RP(RB12_RP); // U1RX <- RB12
283  CONFIG_RC8_AS_DIG_OUTPUT(); // TX pin must be digital output
284  CONFIG_U1TX_TO_RP(RC8_RP); // U1TX -> RC8
285 # elif (HARDWARE_PLATFORM == EMBEDDED_F14)
286 # warning Building configUART1() for the Rev.F14 Embedded Systems target.
287  CONFIG_RB10_AS_DIG_INPUT(); // RX pin must be digital input
288  CONFIG_U1RX_TO_RP(RB10_RP); // U1RX <- RB10
289  CONFIG_RF0_AS_DIG_OUTPUT(); // TX pin must be digital output
290  CONFIG_U1TX_TO_RP(RF0_RP); // U1TX -> RF0??? (Use RF0 for now.)
291 # else
292 # error "Unknown hardware platform."
293 # endif
294 #else
295 # warning "UART1 pin mappings not defined. See comments below for more info."
296  // If your device has more than one UART, ****** CHANGE THE MAPPING ******
297  // since multiple UARTs can not share the same pins. In particular:
298  // 1. Change the statement #if (1 == 1) to #if 1
299  // 2. Change the pin numbers above
300  // to something valid for your device.
301  // If your device does not have remappable I/O,
302  // (typical for >44 pin packages), skip this step --
303  // the UART I/O pins are already assigned to something
304  // valid.
305 #endif
306 
307  // First, disable the UART, clearing all errors, terminating
308  // any in-progress transmissions/receptions, etc.
309  // In particular, this clears UTXEN.
310  U1MODE = (0u << 15); // UARTEN = 0 to disable.
311 
312  // Configure UART baud rate, based on \ref FCY.
313  U1BRG = compute_brg(FCY, DEFAULT_BRGH1, u32_baudRate);
314 
315  // Set up the UART mode register
316  U1MODE =
317  (1u << 15) | // UARTEN = 1 (enable the UART)
318  (0u << 13) | // USIDL = 0 (continue operation in idle mode)
319  (0u << 12) | // IREN = 0 (IrDA encoder and decoder disabled)
320  (0u << 11) | // RTSMD = 0 (UxRTS# in flow control mode. Given
321  // // the UEN setting below, this doesn't matter.)
322  (0b00 << 8) | // UEN = 00 (UxTX and UxRx pins are enabled and used;
323  // // used; UxCTS, UxRTS, and BCLKx pins are
324  // // controlled by port latches)
325  (0u << 7) | // WAKE = 0 (Wake-up on start bit detect during
326  // // sleep mode disabled)
327  (0u << 6) | // LPBACK = 0 (UARTx loopback mode is disabled)
328  (0u << 5) | // ABAUD = 0 (Auto-baud disabled)
329  (0u << 4) | // URXINV = 0 (Receve polarity inversion bit:
330  // // UxRX idle state is 1)
331  (DEFAULT_BRGH1 << 3) | // BRGH (High/low baud rate select bit:
332  // // 1 = high speed, 0 = low speed)
333  (0b00 << 1) | // PDSEL = 00 (8-bit data, no parity)
334  (0u << 0); // STSEL = 0 (1 stop bit)
335 
336  // Set up the UART status and control register
337  U1STA =
338  (0u << 15) | // UTXISEL1 = 0 (See bit 13 below for explanation)
339  (0u << 14) | // UTXINV = 0 (UxTX idle state is 1 (though docs
340  // // say 0))
341  (0u << 13) | // UTXISEL0 = 0 (With bit 15 above, UTXISEL = 00:
342  // // Interrupt generated when any character
343  // // is transferred to the Transmit Shift Register).
344 #if (defined(__dsPIC33E__) || defined(__PIC24E__))
345  (1u << 12) | //URXEN=1, defined on some dsPIC33E/PIC24E members, enables RX.
346 #endif
347  (0u << 11) | // UTXBRK = 0 (Sync break transmission disabled)
348  (1u << 10) | // UTXEN = 0 (UARTx transmitter enabled. NOTE: per
349  // // the data sheet, this must be set *AFTER* UARTEN
350  // // is set to 1 (see UxMODE assignment above).
351  (0b00 << 6) | // URXISEL = 00 (Interrupt flag bit is set when a
352  // // character is received)
353  (0u << 5) | // ADDEN = 0 (Address detect mode disabled)
354  (0u << 1); // OERR = 0 (Clear any overrun errors)
355 
356  // Delay 1 ms (at least one bit time) before beginning transmission,
357  // since the UxTX pin is initially configured as an input on device
358  // reset. It needs to be high for at least one bit time before
359  // a character is sent in order for the start bit to be recognized.
360  // See 24H FRM Sec. 17.5 for more details.
361  ASSERT(u32_baudRate >= 1000L);
362  // Note: If the baud rate is less than 1000, this delay
363  // isn't long encough. The alternative is to use floating-point
364  // math to compute the correct delay, which seems worse than the
365  // problem.
366  DELAY_MS(1);
367 
368  // Clear any errors
369  U1STAbits.OERR = 0;
370  while (U1STAbits.PERR || U1STAbits.FERR) {
371  U1RXREG; //clear errors by reading RXREG
372  }
373 
374  // Set up interrupts if requested
375 #ifdef UART1_RX_INTERRUPT
376  _U1RXIF = 0; //clear the flag
377  _U1RXIP = UART1_RX_INTERRUPT_PRIORITY; //choose a priority
378  _U1RXIE = 1; //enable the interrupt
379 #endif
380 #ifdef UART1_TX_INTERRUPT
381  //do not clear the U1TXIF flag!
382  _U1TXIP = UART1_TX_INTERRUPT_PRIORITY; //choose a priority
383  //do not enable the interrupt until we try to write to the UART
384 #endif
385 
386 }
387 
388 #endif // #if !defined(BOOTLOADER) || (DEFAULT_UART == 1)
389 
390 #endif // #if (NUM_UARTS >= 1)
391 /*
392  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
393  * All rights reserved.
394  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
395  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
396  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
397  *
398  * Permission to use, copy, modify, and distribute this software and its
399  * documentation for any purpose, without fee, and without written agreement is
400  * hereby granted, provided that the above copyright notice, the following
401  * two paragraphs and the authors appear in all copies of this software.
402  *
403  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
404  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
405  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
406  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
407  *
408  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
409  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
410  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
411  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
412  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
413  *
414  * Please maintain this header in its entirety when copying/modifying
415  * these files.
416  *
417  *
418  */
419 
420 
421 
422 
423 #include "pic24_clockfreq.h"
424 #include "pic24_uart.h"
425 #include "pic24_ports.h"
426 #include "pic24_unittest.h"
427 #include "pic24_delay.h"
428 #include "pic24_util.h"
429 
430 // Only include if this UART exists.
431 #if (NUM_UART_MODS >= 2)
432 
433 // For the bootloader, include only configUART2 to minimize size.
434 # ifndef BOOTLOADER
435 
436 
437 // Documentation for this file. If the \file tag is not present,
438 // this file will not be documented.
439 // Note: place this comment below the #if NUM_UART_MODS so Doxygen
440 // will only see it once.
441 /** \file
442 * UART support functions.
443 * \par Interrupt-driven TX/RX
444 * By default, the UART functions use polling for both RX and TX.
445 * Define the macro UARTx_TX_INTERRUPT (i.e., UART1_TX_INTERRUPT) in your project file if you want interrupt-driven TX for the UARTx (i.e., UART1) module.
446 * For interrupt-driven TX, macro UARTx_TX_FIFO_SIZE sets the TX software FIFO size (default 32), and UARTx_TX_INTERRUPT_PRIORITY sets the priority (default 1).
447 * \par
448 * Define the macro UARTx_RX_INTERRUPT (i.e., UART1_RX_INTERRUPT) in your project file if you want interrupt-driven RX for the UARTx (i.e., UART1) module.
449 * For interrupt-driven RX, macro UARTx_RX_FIFO_SIZE sets the RX software FIFO size (default 32), and UARTx_RX_INTERRUPT_PRIORITY sets the priority (default 1).
450 */
451 
452 
453 /*********************************************************
454  * Public functions intended to be called by other files *
455  *********************************************************/
456 /**
457 * Check UART2 RX for error, call \em reportError() if error found.
458 *
459 */
460 void checkRxErrorUART2(void) {
461  uint8_t u8_c;
462  //check for errors, reset if detected.
463  if (U2STAbits.PERR) {
464  u8_c = U2RXREG; //clear error
465  reportError("UART2 parity error\n");
466  }
467  if (U2STAbits.FERR) {
468  u8_c = U2RXREG; //clear error
469  reportError("UART2 framing error\n");
470  }
471  if (U2STAbits.OERR) {
472  U2STAbits.OERR = 0; //clear error
473  reportError("UART2 overrun error\n");
474  }
475 }
476 
477 
478 
479 
480 #ifdef UART2_TX_INTERRUPT
481 /**
482 
483 */
484 # ifndef UART2_TX_FIFO_SIZE
485 # define UART2_TX_FIFO_SIZE 32 //choose a size
486 # endif
487 
488 # ifndef UART2_TX_INTERRUPT_PRIORITY
489 # define UART2_TX_INTERRUPT_PRIORITY 1
490 # endif
491 
492 volatile uint8_t au8_txFifo2[UART2_TX_FIFO_SIZE];
493 volatile uint16_t u16_txFifo2Head = 0;
494 volatile uint16_t u16_txFifo2Tail = 0;
495 
496 /**
497 * Output \em u8_c to UART2 TX.
498 * \param u8_c Character to write
499 */
500 void outChar2(uint8_t u8_c) {
501  uint16_t u16_tmp;
502 
503  u16_tmp = u16_txFifo2Head;
504  u16_tmp++;
505  if (u16_tmp == UART2_TX_FIFO_SIZE) u16_tmp = 0; //wrap if needed
506  while (u16_tmp == u16_txFifo2Tail)
507  doHeartbeat();
508 
509  au8_txFifo2[u16_tmp] = u8_c; //write to buffer
510  u16_txFifo2Head = u16_tmp; //update head
511  _U2TXIE = 1; //enable interrupt
512 }
513 
514 void _ISR _U2TXInterrupt (void) {
515  if (u16_txFifo2Head == u16_txFifo2Tail) {
516  //empty TX buffer, disable the interrupt, do not clear the flag
517  _U2TXIE = 0;
518  } else {
519  //at least one free spot in the TX buffer!
520  u16_txFifo2Tail++; //increment tail pointer
521  if (u16_txFifo2Tail == UART2_TX_FIFO_SIZE)
522  u16_txFifo2Tail = 0; //wrap if needed
523  _U2TXIF = 0; //clear the interrupt flag
524  //transfer character from software buffer to transmit buffer
525  U2TXREG = au8_txFifo2[u16_txFifo2Tail];
526  }
527 }
528 
529 
530 #else
531 /**
532 * Output \em u8_c to UART2 TX.
533 * \param u8_c Character to write
534 */
535 void outChar2(uint8_t u8_c) {
536  //wait for transmit buffer to be empty
537  while (IS_TRANSMIT_BUFFER_FULL_UART2())
538  doHeartbeat();
539  U2TXREG = u8_c;
540 }
541 #endif
542 
543 #ifdef UART2_RX_INTERRUPT
544 //Interrupt driven RX
545 # ifndef UART2_RX_FIFO_SIZE
546 # define UART2_RX_FIFO_SIZE 32 //choose a size
547 # endif
548 
549 # ifndef UART2_RX_INTERRUPT_PRIORITY
550 # define UART2_RX_INTERRUPT_PRIORITY 1
551 # endif
552 
553 volatile uint8_t au8_rxFifo2[UART2_RX_FIFO_SIZE];
554 volatile uint16_t u16_rxFifo2Head = 0;
555 volatile uint16_t u16_rxFifo2Tail = 0;
556 
557 /**
558 * Return true if character is ready to be read
559 */
560 uint8_t isCharReady2(void) {
561  return(u16_rxFifo2Head != u16_rxFifo2Tail);
562 }
563 
564 /**
565 * Wait for a byte to be available from UART2 RX.
566 * \return Character read from UART2 RX.
567 */
568 uint8_t inChar2(void) {
569  while (u16_rxFifo2Head == u16_rxFifo2Tail)
570  doHeartbeat();
571  u16_rxFifo2Tail++;
572  if (u16_rxFifo2Tail == UART2_RX_FIFO_SIZE) u16_rxFifo2Tail=0; //wrap
573  return au8_rxFifo2[u16_rxFifo2Tail]; //return the character
574 }
575 
576 void _ISR _U2RXInterrupt (void) {
577  int8_t u8_c;
578 
579  _U2RXIF = 0; //clear the UART RX interrupt bit
580  checkRxErrorUART2();
581  u8_c = U2RXREG; //read character
582  u16_rxFifo2Head++; //increment head pointer
583  if (u16_rxFifo2Head == UART2_RX_FIFO_SIZE)
584  u16_rxFifo2Head = 0; //wrap if needed
585  if (u16_rxFifo2Head == u16_rxFifo2Tail) {
586  //FIFO overrun!, report error
587  reportError("UART2 RX Interrupt FIFO overrun!");
588  }
589  au8_rxFifo2[u16_rxFifo2Head] = u8_c; //place in buffer
590 }
591 
592 #else
593 /**
594 * Return true if character is ready to be read
595 */
596 uint8_t isCharReady2(void) {
597  return(IS_CHAR_READY_UART2());
598 }
599 
600 /**
601 * Wait for a byte to be available from UART2 RX.
602 * \return Character read from UART2 RX.
603 */
604 uint8_t inChar2(void) {
605  //do heartbeat while waiting for character.
606  // Use a do-while to insure error checks
607  // are always run.
608  while (!IS_CHAR_READY_UART2())
609  doHeartbeat();
610  checkRxErrorUART2();
611  return U2RXREG; //read the receive register
612 }
613 #endif
614 
615 
616 // Include this for the non-bootloader case. Also include it for the bootloader if this is the UART the bootloader uses.
617 #endif // # ifndef BOOTLOADER
618 #if !defined(BOOTLOADER) || (DEFAULT_UART == 2)
619 
620 /** Chose a default BRGH for UART2, used by
621  * \ref configUART2 to set up UART2.
622  */
623 #ifndef DEFAULT_BRGH2
624 # define DEFAULT_BRGH2 DEFAULT_BRGH
625 #endif
626 
627 #if (DEFAULT_BRGH2 != 0) && (DEFAULT_BRGH2 != 1)
628 # error "Invalid value specified for DEFAULT_BRGH2."
629 #endif
630 
631 
632 /** Configure the UART. Settings chosen:
633  * - TX is on RP11
634  * - RX is on RP10
635  * - Format is 8 data bits, no parity, 1 stop bit
636  * - CTS, RTS, and BCLK not used
637  *
638  * \param u32_baudRate The baud rate to use.
639  */
640 void configUART2(uint32_t u32_baudRate) {
641  /************************* UART config ********************/
642  // See comments in the #warning statements below for
643  // instructions on how to modify this configuration.
644  // More information on each of these board is given
645  // in the HARDWARE_PLATFORM section of pic24_libconfig.h.
646 #if (HARDWARE_PLATFORM == EXPLORER16_100P) || (HARDWARE_PLATFORM == HARDMAPPED_UART)
647  // There's nothing to do, since pins on these boards are
648  // mapped to fixed ports.
649 #elif (2 == 1)
650  // The following pin mappings will apply only to UART 1.
651  // Change them as necessary for your device.
652 # if (HARDWARE_PLATFORM == DANGEROUS_WEB)
653 # warning Building configUART2() for the Dangerous Web target.
654  CONFIG_RB14_AS_DIG_INPUT(); // RX pin must be digital input
655  CONFIG_U1RX_TO_RP(RB14_RP); // U1RX <- RB14
656  CONFIG_RB15_AS_DIG_OUTPUT(); // TX pin must be digital output
657  CONFIG_U1TX_TO_RP(RB15_RP); // U1TX -> RB15
658 # elif (HARDWARE_PLATFORM == STARTER_BOARD_28P)
659 # warning Building configUART2() for the StarterBoard_28P target.
660  CONFIG_RB9_AS_DIG_INPUT(); // RX pin must be digital input
661  CONFIG_U1RX_TO_RP(RB9_RP); // U1RX <- RB9
662  CONFIG_RB8_AS_DIG_OUTPUT(); // TX pin must be digital output
663  CONFIG_U1TX_TO_RP(RB8_RP); // U1TX -> RB8
664 # elif (HARDWARE_PLATFORM == DEFAULT_DESIGN) || (HARDWARE_PLATFORM == MICROSTICK2)
665  CONFIG_RB10_AS_DIG_INPUT(); // RX pin must be digital input
666  CONFIG_U1RX_TO_RP(RB10_RP); // U1RX <- RB10
667  CONFIG_RB11_AS_DIG_OUTPUT(); // TX pin must be digital output
668  CONFIG_U1TX_TO_RP(RB11_RP); // U1TX -> RB11
669 # elif (HARDWARE_PLATFORM == EMBEDDED_C1)
670 # warning Building configUART2() for the Rev.C1 Embedded Systems target.
671  CONFIG_RB12_AS_DIG_INPUT(); // RX pin must be digital input
672  CONFIG_U1RX_TO_RP(RB12_RP); // U1RX <- RB12
673  CONFIG_RC8_AS_DIG_OUTPUT(); // TX pin must be digital output
674  CONFIG_U1TX_TO_RP(RC8_RP); // U1TX -> RC8
675 # elif (HARDWARE_PLATFORM == EMBEDDED_F14)
676 # warning Building configUART2() for the Rev.F14 Embedded Systems target.
677  CONFIG_RB10_AS_DIG_INPUT(); // RX pin must be digital input
678  CONFIG_U1RX_TO_RP(RB10_RP); // U1RX <- RB10
679  CONFIG_RF0_AS_DIG_OUTPUT(); // TX pin must be digital output
680  CONFIG_U1TX_TO_RP(RF0_RP); // U1TX -> RF0??? (Use RF0 for now.)
681 # else
682 # error "Unknown hardware platform."
683 # endif
684 #else
685 # warning "UART2 pin mappings not defined. See comments below for more info."
686  // If your device has more than one UART, ****** CHANGE THE MAPPING ******
687  // since multiple UARTs can not share the same pins. In particular:
688  // 1. Change the statement #if (2 == 1) to #if 1
689  // 2. Change the pin numbers above
690  // to something valid for your device.
691  // If your device does not have remappable I/O,
692  // (typical for >44 pin packages), skip this step --
693  // the UART I/O pins are already assigned to something
694  // valid.
695 #endif
696 
697  // First, disable the UART, clearing all errors, terminating
698  // any in-progress transmissions/receptions, etc.
699  // In particular, this clears UTXEN.
700  U2MODE = (0u << 15); // UARTEN = 0 to disable.
701 
702  // Configure UART baud rate, based on \ref FCY.
703  U2BRG = compute_brg(FCY, DEFAULT_BRGH2, u32_baudRate);
704 
705  // Set up the UART mode register
706  U2MODE =
707  (1u << 15) | // UARTEN = 1 (enable the UART)
708  (0u << 13) | // USIDL = 0 (continue operation in idle mode)
709  (0u << 12) | // IREN = 0 (IrDA encoder and decoder disabled)
710  (0u << 11) | // RTSMD = 0 (UxRTS# in flow control mode. Given
711  // // the UEN setting below, this doesn't matter.)
712  (0b00 << 8) | // UEN = 00 (UxTX and UxRx pins are enabled and used;
713  // // used; UxCTS, UxRTS, and BCLKx pins are
714  // // controlled by port latches)
715  (0u << 7) | // WAKE = 0 (Wake-up on start bit detect during
716  // // sleep mode disabled)
717  (0u << 6) | // LPBACK = 0 (UARTx loopback mode is disabled)
718  (0u << 5) | // ABAUD = 0 (Auto-baud disabled)
719  (0u << 4) | // URXINV = 0 (Receve polarity inversion bit:
720  // // UxRX idle state is 1)
721  (DEFAULT_BRGH2 << 3) | // BRGH (High/low baud rate select bit:
722  // // 1 = high speed, 0 = low speed)
723  (0b00 << 1) | // PDSEL = 00 (8-bit data, no parity)
724  (0u << 0); // STSEL = 0 (1 stop bit)
725 
726  // Set up the UART status and control register
727  U2STA =
728  (0u << 15) | // UTXISEL1 = 0 (See bit 13 below for explanation)
729  (0u << 14) | // UTXINV = 0 (UxTX idle state is 1 (though docs
730  // // say 0))
731  (0u << 13) | // UTXISEL0 = 0 (With bit 15 above, UTXISEL = 00:
732  // // Interrupt generated when any character
733  // // is transferred to the Transmit Shift Register).
734 #if (defined(__dsPIC33E__) || defined(__PIC24E__))
735  (1u << 12) | //URXEN=1, defined on some dsPIC33E/PIC24E members, enables RX.
736 #endif
737  (0u << 11) | // UTXBRK = 0 (Sync break transmission disabled)
738  (1u << 10) | // UTXEN = 0 (UARTx transmitter enabled. NOTE: per
739  // // the data sheet, this must be set *AFTER* UARTEN
740  // // is set to 1 (see UxMODE assignment above).
741  (0b00 << 6) | // URXISEL = 00 (Interrupt flag bit is set when a
742  // // character is received)
743  (0u << 5) | // ADDEN = 0 (Address detect mode disabled)
744  (0u << 1); // OERR = 0 (Clear any overrun errors)
745 
746  // Delay 1 ms (at least one bit time) before beginning transmission,
747  // since the UxTX pin is initially configured as an input on device
748  // reset. It needs to be high for at least one bit time before
749  // a character is sent in order for the start bit to be recognized.
750  // See 24H FRM Sec. 17.5 for more details.
751  ASSERT(u32_baudRate >= 1000L);
752  // Note: If the baud rate is less than 1000, this delay
753  // isn't long encough. The alternative is to use floating-point
754  // math to compute the correct delay, which seems worse than the
755  // problem.
756  DELAY_MS(1);
757 
758  // Clear any errors
759  U2STAbits.OERR = 0;
760  while (U2STAbits.PERR || U2STAbits.FERR) {
761  U2RXREG; //clear errors by reading RXREG
762  }
763 
764  // Set up interrupts if requested
765 #ifdef UART2_RX_INTERRUPT
766  _U2RXIF = 0; //clear the flag
767  _U2RXIP = UART2_RX_INTERRUPT_PRIORITY; //choose a priority
768  _U2RXIE = 1; //enable the interrupt
769 #endif
770 #ifdef UART2_TX_INTERRUPT
771  //do not clear the U2TXIF flag!
772  _U2TXIP = UART2_TX_INTERRUPT_PRIORITY; //choose a priority
773  //do not enable the interrupt until we try to write to the UART
774 #endif
775 
776 }
777 
778 #endif // #if !defined(BOOTLOADER) || (DEFAULT_UART == 2)
779 
780 #endif // #if (NUM_UARTS >= 2)
781 /*
782  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
783  * All rights reserved.
784  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
785  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
786  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
787  *
788  * Permission to use, copy, modify, and distribute this software and its
789  * documentation for any purpose, without fee, and without written agreement is
790  * hereby granted, provided that the above copyright notice, the following
791  * two paragraphs and the authors appear in all copies of this software.
792  *
793  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
794  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
795  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
796  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
797  *
798  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
799  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
800  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
801  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
802  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
803  *
804  * Please maintain this header in its entirety when copying/modifying
805  * these files.
806  *
807  *
808  */
809 
810 
811 
812 
813 #include "pic24_clockfreq.h"
814 #include "pic24_uart.h"
815 #include "pic24_ports.h"
816 #include "pic24_unittest.h"
817 #include "pic24_delay.h"
818 #include "pic24_util.h"
819 
820 // Only include if this UART exists.
821 #if (NUM_UART_MODS >= 3)
822 
823 // For the bootloader, include only configUART3 to minimize size.
824 # ifndef BOOTLOADER
825 
826 
827 // Documentation for this file. If the \file tag is not present,
828 // this file will not be documented.
829 // Note: place this comment below the #if NUM_UART_MODS so Doxygen
830 // will only see it once.
831 /** \file
832 * UART support functions.
833 * \par Interrupt-driven TX/RX
834 * By default, the UART functions use polling for both RX and TX.
835 * Define the macro UARTx_TX_INTERRUPT (i.e., UART1_TX_INTERRUPT) in your project file if you want interrupt-driven TX for the UARTx (i.e., UART1) module.
836 * For interrupt-driven TX, macro UARTx_TX_FIFO_SIZE sets the TX software FIFO size (default 32), and UARTx_TX_INTERRUPT_PRIORITY sets the priority (default 1).
837 * \par
838 * Define the macro UARTx_RX_INTERRUPT (i.e., UART1_RX_INTERRUPT) in your project file if you want interrupt-driven RX for the UARTx (i.e., UART1) module.
839 * For interrupt-driven RX, macro UARTx_RX_FIFO_SIZE sets the RX software FIFO size (default 32), and UARTx_RX_INTERRUPT_PRIORITY sets the priority (default 1).
840 */
841 
842 
843 /*********************************************************
844  * Public functions intended to be called by other files *
845  *********************************************************/
846 /**
847 * Check UART3 RX for error, call \em reportError() if error found.
848 *
849 */
850 void checkRxErrorUART3(void) {
851  uint8_t u8_c;
852  //check for errors, reset if detected.
853  if (U3STAbits.PERR) {
854  u8_c = U3RXREG; //clear error
855  reportError("UART3 parity error\n");
856  }
857  if (U3STAbits.FERR) {
858  u8_c = U3RXREG; //clear error
859  reportError("UART3 framing error\n");
860  }
861  if (U3STAbits.OERR) {
862  U3STAbits.OERR = 0; //clear error
863  reportError("UART3 overrun error\n");
864  }
865 }
866 
867 
868 
869 
870 #ifdef UART3_TX_INTERRUPT
871 /**
872 
873 */
874 # ifndef UART3_TX_FIFO_SIZE
875 # define UART3_TX_FIFO_SIZE 32 //choose a size
876 # endif
877 
878 # ifndef UART3_TX_INTERRUPT_PRIORITY
879 # define UART3_TX_INTERRUPT_PRIORITY 1
880 # endif
881 
882 volatile uint8_t au8_txFifo3[UART3_TX_FIFO_SIZE];
883 volatile uint16_t u16_txFifo3Head = 0;
884 volatile uint16_t u16_txFifo3Tail = 0;
885 
886 /**
887 * Output \em u8_c to UART3 TX.
888 * \param u8_c Character to write
889 */
890 void outChar3(uint8_t u8_c) {
891  uint16_t u16_tmp;
892 
893  u16_tmp = u16_txFifo3Head;
894  u16_tmp++;
895  if (u16_tmp == UART3_TX_FIFO_SIZE) u16_tmp = 0; //wrap if needed
896  while (u16_tmp == u16_txFifo3Tail)
897  doHeartbeat();
898 
899  au8_txFifo3[u16_tmp] = u8_c; //write to buffer
900  u16_txFifo3Head = u16_tmp; //update head
901  _U3TXIE = 1; //enable interrupt
902 }
903 
904 void _ISR _U3TXInterrupt (void) {
905  if (u16_txFifo3Head == u16_txFifo3Tail) {
906  //empty TX buffer, disable the interrupt, do not clear the flag
907  _U3TXIE = 0;
908  } else {
909  //at least one free spot in the TX buffer!
910  u16_txFifo3Tail++; //increment tail pointer
911  if (u16_txFifo3Tail == UART3_TX_FIFO_SIZE)
912  u16_txFifo3Tail = 0; //wrap if needed
913  _U3TXIF = 0; //clear the interrupt flag
914  //transfer character from software buffer to transmit buffer
915  U3TXREG = au8_txFifo3[u16_txFifo3Tail];
916  }
917 }
918 
919 
920 #else
921 /**
922 * Output \em u8_c to UART3 TX.
923 * \param u8_c Character to write
924 */
925 void outChar3(uint8_t u8_c) {
926  //wait for transmit buffer to be empty
927  while (IS_TRANSMIT_BUFFER_FULL_UART3())
928  doHeartbeat();
929  U3TXREG = u8_c;
930 }
931 #endif
932 
933 #ifdef UART3_RX_INTERRUPT
934 //Interrupt driven RX
935 # ifndef UART3_RX_FIFO_SIZE
936 # define UART3_RX_FIFO_SIZE 32 //choose a size
937 # endif
938 
939 # ifndef UART3_RX_INTERRUPT_PRIORITY
940 # define UART3_RX_INTERRUPT_PRIORITY 1
941 # endif
942 
943 volatile uint8_t au8_rxFifo3[UART3_RX_FIFO_SIZE];
944 volatile uint16_t u16_rxFifo3Head = 0;
945 volatile uint16_t u16_rxFifo3Tail = 0;
946 
947 /**
948 * Return true if character is ready to be read
949 */
950 uint8_t isCharReady3(void) {
951  return(u16_rxFifo3Head != u16_rxFifo3Tail);
952 }
953 
954 /**
955 * Wait for a byte to be available from UART3 RX.
956 * \return Character read from UART3 RX.
957 */
958 uint8_t inChar3(void) {
959  while (u16_rxFifo3Head == u16_rxFifo3Tail)
960  doHeartbeat();
961  u16_rxFifo3Tail++;
962  if (u16_rxFifo3Tail == UART3_RX_FIFO_SIZE) u16_rxFifo3Tail=0; //wrap
963  return au8_rxFifo3[u16_rxFifo3Tail]; //return the character
964 }
965 
966 void _ISR _U3RXInterrupt (void) {
967  int8_t u8_c;
968 
969  _U3RXIF = 0; //clear the UART RX interrupt bit
970  checkRxErrorUART3();
971  u8_c = U3RXREG; //read character
972  u16_rxFifo3Head++; //increment head pointer
973  if (u16_rxFifo3Head == UART3_RX_FIFO_SIZE)
974  u16_rxFifo3Head = 0; //wrap if needed
975  if (u16_rxFifo3Head == u16_rxFifo3Tail) {
976  //FIFO overrun!, report error
977  reportError("UART3 RX Interrupt FIFO overrun!");
978  }
979  au8_rxFifo3[u16_rxFifo3Head] = u8_c; //place in buffer
980 }
981 
982 #else
983 /**
984 * Return true if character is ready to be read
985 */
986 uint8_t isCharReady3(void) {
987  return(IS_CHAR_READY_UART3());
988 }
989 
990 /**
991 * Wait for a byte to be available from UART3 RX.
992 * \return Character read from UART3 RX.
993 */
994 uint8_t inChar3(void) {
995  //do heartbeat while waiting for character.
996  // Use a do-while to insure error checks
997  // are always run.
998  while (!IS_CHAR_READY_UART3())
999  doHeartbeat();
1000  checkRxErrorUART3();
1001  return U3RXREG; //read the receive register
1002 }
1003 #endif
1004 
1005 
1006 // Include this for the non-bootloader case. Also include it for the bootloader if this is the UART the bootloader uses.
1007 #endif // # ifndef BOOTLOADER
1008 #if !defined(BOOTLOADER) || (DEFAULT_UART == 3)
1009 
1010 /** Chose a default BRGH for UART3, used by
1011  * \ref configUART3 to set up UART3.
1012  */
1013 #ifndef DEFAULT_BRGH3
1014 # define DEFAULT_BRGH3 DEFAULT_BRGH
1015 #endif
1016 
1017 #if (DEFAULT_BRGH3 != 0) && (DEFAULT_BRGH3 != 1)
1018 # error "Invalid value specified for DEFAULT_BRGH3."
1019 #endif
1020 
1021 
1022 /** Configure the UART. Settings chosen:
1023  * - TX is on RP11
1024  * - RX is on RP10
1025  * - Format is 8 data bits, no parity, 1 stop bit
1026  * - CTS, RTS, and BCLK not used
1027  *
1028  * \param u32_baudRate The baud rate to use.
1029  */
1030 void configUART3(uint32_t u32_baudRate) {
1031  /************************* UART config ********************/
1032  // See comments in the #warning statements below for
1033  // instructions on how to modify this configuration.
1034  // More information on each of these board is given
1035  // in the HARDWARE_PLATFORM section of pic24_libconfig.h.
1036 #if (HARDWARE_PLATFORM == EXPLORER16_100P) || (HARDWARE_PLATFORM == HARDMAPPED_UART)
1037  // There's nothing to do, since pins on these boards are
1038  // mapped to fixed ports.
1039 #elif (3 == 1)
1040  // The following pin mappings will apply only to UART 1.
1041  // Change them as necessary for your device.
1042 # if (HARDWARE_PLATFORM == DANGEROUS_WEB)
1043 # warning Building configUART3() for the Dangerous Web target.
1044  CONFIG_RB14_AS_DIG_INPUT(); // RX pin must be digital input
1045  CONFIG_U1RX_TO_RP(RB14_RP); // U1RX <- RB14
1046  CONFIG_RB15_AS_DIG_OUTPUT(); // TX pin must be digital output
1047  CONFIG_U1TX_TO_RP(RB15_RP); // U1TX -> RB15
1048 # elif (HARDWARE_PLATFORM == STARTER_BOARD_28P)
1049 # warning Building configUART3() for the StarterBoard_28P target.
1050  CONFIG_RB9_AS_DIG_INPUT(); // RX pin must be digital input
1051  CONFIG_U1RX_TO_RP(RB9_RP); // U1RX <- RB9
1052  CONFIG_RB8_AS_DIG_OUTPUT(); // TX pin must be digital output
1053  CONFIG_U1TX_TO_RP(RB8_RP); // U1TX -> RB8
1054 # elif (HARDWARE_PLATFORM == DEFAULT_DESIGN) || (HARDWARE_PLATFORM == MICROSTICK2)
1055  CONFIG_RB10_AS_DIG_INPUT(); // RX pin must be digital input
1056  CONFIG_U1RX_TO_RP(RB10_RP); // U1RX <- RB10
1057  CONFIG_RB11_AS_DIG_OUTPUT(); // TX pin must be digital output
1058  CONFIG_U1TX_TO_RP(RB11_RP); // U1TX -> RB11
1059 # elif (HARDWARE_PLATFORM == EMBEDDED_C1)
1060 # warning Building configUART3() for the Rev.C1 Embedded Systems target.
1061  CONFIG_RB12_AS_DIG_INPUT(); // RX pin must be digital input
1062  CONFIG_U1RX_TO_RP(RB12_RP); // U1RX <- RB12
1063  CONFIG_RC8_AS_DIG_OUTPUT(); // TX pin must be digital output
1064  CONFIG_U1TX_TO_RP(RC8_RP); // U1TX -> RC8
1065 # elif (HARDWARE_PLATFORM == EMBEDDED_F14)
1066 # warning Building configUART3() for the Rev.F14 Embedded Systems target.
1067  CONFIG_RB10_AS_DIG_INPUT(); // RX pin must be digital input
1068  CONFIG_U1RX_TO_RP(RB10_RP); // U1RX <- RB10
1069  CONFIG_RF0_AS_DIG_OUTPUT(); // TX pin must be digital output
1070  CONFIG_U1TX_TO_RP(RF0_RP); // U1TX -> RF0??? (Use RF0 for now.)
1071 # else
1072 # error "Unknown hardware platform."
1073 # endif
1074 #else
1075 # warning "UART3 pin mappings not defined. See comments below for more info."
1076  // If your device has more than one UART, ****** CHANGE THE MAPPING ******
1077  // since multiple UARTs can not share the same pins. In particular:
1078  // 1. Change the statement #if (3 == 1) to #if 1
1079  // 2. Change the pin numbers above
1080  // to something valid for your device.
1081  // If your device does not have remappable I/O,
1082  // (typical for >44 pin packages), skip this step --
1083  // the UART I/O pins are already assigned to something
1084  // valid.
1085 #endif
1086 
1087  // First, disable the UART, clearing all errors, terminating
1088  // any in-progress transmissions/receptions, etc.
1089  // In particular, this clears UTXEN.
1090  U3MODE = (0u << 15); // UARTEN = 0 to disable.
1091 
1092  // Configure UART baud rate, based on \ref FCY.
1093  U3BRG = compute_brg(FCY, DEFAULT_BRGH3, u32_baudRate);
1094 
1095  // Set up the UART mode register
1096  U3MODE =
1097  (1u << 15) | // UARTEN = 1 (enable the UART)
1098  (0u << 13) | // USIDL = 0 (continue operation in idle mode)
1099  (0u << 12) | // IREN = 0 (IrDA encoder and decoder disabled)
1100  (0u << 11) | // RTSMD = 0 (UxRTS# in flow control mode. Given
1101  // // the UEN setting below, this doesn't matter.)
1102  (0b00 << 8) | // UEN = 00 (UxTX and UxRx pins are enabled and used;
1103  // // used; UxCTS, UxRTS, and BCLKx pins are
1104  // // controlled by port latches)
1105  (0u << 7) | // WAKE = 0 (Wake-up on start bit detect during
1106  // // sleep mode disabled)
1107  (0u << 6) | // LPBACK = 0 (UARTx loopback mode is disabled)
1108  (0u << 5) | // ABAUD = 0 (Auto-baud disabled)
1109  (0u << 4) | // URXINV = 0 (Receve polarity inversion bit:
1110  // // UxRX idle state is 1)
1111  (DEFAULT_BRGH3 << 3) | // BRGH (High/low baud rate select bit:
1112  // // 1 = high speed, 0 = low speed)
1113  (0b00 << 1) | // PDSEL = 00 (8-bit data, no parity)
1114  (0u << 0); // STSEL = 0 (1 stop bit)
1115 
1116  // Set up the UART status and control register
1117  U3STA =
1118  (0u << 15) | // UTXISEL1 = 0 (See bit 13 below for explanation)
1119  (0u << 14) | // UTXINV = 0 (UxTX idle state is 1 (though docs
1120  // // say 0))
1121  (0u << 13) | // UTXISEL0 = 0 (With bit 15 above, UTXISEL = 00:
1122  // // Interrupt generated when any character
1123  // // is transferred to the Transmit Shift Register).
1124 #if (defined(__dsPIC33E__) || defined(__PIC24E__))
1125  (1u << 12) | //URXEN=1, defined on some dsPIC33E/PIC24E members, enables RX.
1126 #endif
1127  (0u << 11) | // UTXBRK = 0 (Sync break transmission disabled)
1128  (1u << 10) | // UTXEN = 0 (UARTx transmitter enabled. NOTE: per
1129  // // the data sheet, this must be set *AFTER* UARTEN
1130  // // is set to 1 (see UxMODE assignment above).
1131  (0b00 << 6) | // URXISEL = 00 (Interrupt flag bit is set when a
1132  // // character is received)
1133  (0u << 5) | // ADDEN = 0 (Address detect mode disabled)
1134  (0u << 1); // OERR = 0 (Clear any overrun errors)
1135 
1136  // Delay 1 ms (at least one bit time) before beginning transmission,
1137  // since the UxTX pin is initially configured as an input on device
1138  // reset. It needs to be high for at least one bit time before
1139  // a character is sent in order for the start bit to be recognized.
1140  // See 24H FRM Sec. 17.5 for more details.
1141  ASSERT(u32_baudRate >= 1000L);
1142  // Note: If the baud rate is less than 1000, this delay
1143  // isn't long encough. The alternative is to use floating-point
1144  // math to compute the correct delay, which seems worse than the
1145  // problem.
1146  DELAY_MS(1);
1147 
1148  // Clear any errors
1149  U3STAbits.OERR = 0;
1150  while (U3STAbits.PERR || U3STAbits.FERR) {
1151  U3RXREG; //clear errors by reading RXREG
1152  }
1153 
1154  // Set up interrupts if requested
1155 #ifdef UART3_RX_INTERRUPT
1156  _U3RXIF = 0; //clear the flag
1157  _U3RXIP = UART3_RX_INTERRUPT_PRIORITY; //choose a priority
1158  _U3RXIE = 1; //enable the interrupt
1159 #endif
1160 #ifdef UART3_TX_INTERRUPT
1161  //do not clear the U3TXIF flag!
1162  _U3TXIP = UART3_TX_INTERRUPT_PRIORITY; //choose a priority
1163  //do not enable the interrupt until we try to write to the UART
1164 #endif
1165 
1166 }
1167 
1168 #endif // #if !defined(BOOTLOADER) || (DEFAULT_UART == 3)
1169 
1170 #endif // #if (NUM_UARTS >= 3)
1171 /*
1172  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
1173  * All rights reserved.
1174  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
1175  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
1176  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
1177  *
1178  * Permission to use, copy, modify, and distribute this software and its
1179  * documentation for any purpose, without fee, and without written agreement is
1180  * hereby granted, provided that the above copyright notice, the following
1181  * two paragraphs and the authors appear in all copies of this software.
1182  *
1183  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
1184  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
1185  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
1186  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1187  *
1188  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
1189  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
1190  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
1191  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
1192  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
1193  *
1194  * Please maintain this header in its entirety when copying/modifying
1195  * these files.
1196  *
1197  *
1198  */
1199 
1200 
1201 
1202 
1203 #include "pic24_clockfreq.h"
1204 #include "pic24_uart.h"
1205 #include "pic24_ports.h"
1206 #include "pic24_unittest.h"
1207 #include "pic24_delay.h"
1208 #include "pic24_util.h"
1209 
1210 // Only include if this UART exists.
1211 #if (NUM_UART_MODS >= 4)
1212 
1213 // For the bootloader, include only configUART4 to minimize size.
1214 # ifndef BOOTLOADER
1215 
1216 
1217 // Documentation for this file. If the \file tag is not present,
1218 // this file will not be documented.
1219 // Note: place this comment below the #if NUM_UART_MODS so Doxygen
1220 // will only see it once.
1221 /** \file
1222 * UART support functions.
1223 * \par Interrupt-driven TX/RX
1224 * By default, the UART functions use polling for both RX and TX.
1225 * Define the macro UARTx_TX_INTERRUPT (i.e., UART1_TX_INTERRUPT) in your project file if you want interrupt-driven TX for the UARTx (i.e., UART1) module.
1226 * For interrupt-driven TX, macro UARTx_TX_FIFO_SIZE sets the TX software FIFO size (default 32), and UARTx_TX_INTERRUPT_PRIORITY sets the priority (default 1).
1227 * \par
1228 * Define the macro UARTx_RX_INTERRUPT (i.e., UART1_RX_INTERRUPT) in your project file if you want interrupt-driven RX for the UARTx (i.e., UART1) module.
1229 * For interrupt-driven RX, macro UARTx_RX_FIFO_SIZE sets the RX software FIFO size (default 32), and UARTx_RX_INTERRUPT_PRIORITY sets the priority (default 1).
1230 */
1231 
1232 
1233 /*********************************************************
1234  * Public functions intended to be called by other files *
1235  *********************************************************/
1236 /**
1237 * Check UART4 RX for error, call \em reportError() if error found.
1238 *
1239 */
1240 void checkRxErrorUART4(void) {
1241  uint8_t u8_c;
1242  //check for errors, reset if detected.
1243  if (U4STAbits.PERR) {
1244  u8_c = U4RXREG; //clear error
1245  reportError("UART4 parity error\n");
1246  }
1247  if (U4STAbits.FERR) {
1248  u8_c = U4RXREG; //clear error
1249  reportError("UART4 framing error\n");
1250  }
1251  if (U4STAbits.OERR) {
1252  U4STAbits.OERR = 0; //clear error
1253  reportError("UART4 overrun error\n");
1254  }
1255 }
1256 
1257 
1258 
1259 
1260 #ifdef UART4_TX_INTERRUPT
1261 /**
1262 
1263 */
1264 # ifndef UART4_TX_FIFO_SIZE
1265 # define UART4_TX_FIFO_SIZE 32 //choose a size
1266 # endif
1267 
1268 # ifndef UART4_TX_INTERRUPT_PRIORITY
1269 # define UART4_TX_INTERRUPT_PRIORITY 1
1270 # endif
1271 
1272 volatile uint8_t au8_txFifo4[UART4_TX_FIFO_SIZE];
1273 volatile uint16_t u16_txFifo4Head = 0;
1274 volatile uint16_t u16_txFifo4Tail = 0;
1275 
1276 /**
1277 * Output \em u8_c to UART4 TX.
1278 * \param u8_c Character to write
1279 */
1280 void outChar4(uint8_t u8_c) {
1281  uint16_t u16_tmp;
1282 
1283  u16_tmp = u16_txFifo4Head;
1284  u16_tmp++;
1285  if (u16_tmp == UART4_TX_FIFO_SIZE) u16_tmp = 0; //wrap if needed
1286  while (u16_tmp == u16_txFifo4Tail)
1287  doHeartbeat();
1288 
1289  au8_txFifo4[u16_tmp] = u8_c; //write to buffer
1290  u16_txFifo4Head = u16_tmp; //update head
1291  _U4TXIE = 1; //enable interrupt
1292 }
1293 
1294 void _ISR _U4TXInterrupt (void) {
1295  if (u16_txFifo4Head == u16_txFifo4Tail) {
1296  //empty TX buffer, disable the interrupt, do not clear the flag
1297  _U4TXIE = 0;
1298  } else {
1299  //at least one free spot in the TX buffer!
1300  u16_txFifo4Tail++; //increment tail pointer
1301  if (u16_txFifo4Tail == UART4_TX_FIFO_SIZE)
1302  u16_txFifo4Tail = 0; //wrap if needed
1303  _U4TXIF = 0; //clear the interrupt flag
1304  //transfer character from software buffer to transmit buffer
1305  U4TXREG = au8_txFifo4[u16_txFifo4Tail];
1306  }
1307 }
1308 
1309 
1310 #else
1311 /**
1312 * Output \em u8_c to UART4 TX.
1313 * \param u8_c Character to write
1314 */
1315 void outChar4(uint8_t u8_c) {
1316  //wait for transmit buffer to be empty
1317  while (IS_TRANSMIT_BUFFER_FULL_UART4())
1318  doHeartbeat();
1319  U4TXREG = u8_c;
1320 }
1321 #endif
1322 
1323 #ifdef UART4_RX_INTERRUPT
1324 //Interrupt driven RX
1325 # ifndef UART4_RX_FIFO_SIZE
1326 # define UART4_RX_FIFO_SIZE 32 //choose a size
1327 # endif
1328 
1329 # ifndef UART4_RX_INTERRUPT_PRIORITY
1330 # define UART4_RX_INTERRUPT_PRIORITY 1
1331 # endif
1332 
1333 volatile uint8_t au8_rxFifo4[UART4_RX_FIFO_SIZE];
1334 volatile uint16_t u16_rxFifo4Head = 0;
1335 volatile uint16_t u16_rxFifo4Tail = 0;
1336 
1337 /**
1338 * Return true if character is ready to be read
1339 */
1340 uint8_t isCharReady4(void) {
1341  return(u16_rxFifo4Head != u16_rxFifo4Tail);
1342 }
1343 
1344 /**
1345 * Wait for a byte to be available from UART4 RX.
1346 * \return Character read from UART4 RX.
1347 */
1348 uint8_t inChar4(void) {
1349  while (u16_rxFifo4Head == u16_rxFifo4Tail)
1350  doHeartbeat();
1351  u16_rxFifo4Tail++;
1352  if (u16_rxFifo4Tail == UART4_RX_FIFO_SIZE) u16_rxFifo4Tail=0; //wrap
1353  return au8_rxFifo4[u16_rxFifo4Tail]; //return the character
1354 }
1355 
1356 void _ISR _U4RXInterrupt (void) {
1357  int8_t u8_c;
1358 
1359  _U4RXIF = 0; //clear the UART RX interrupt bit
1360  checkRxErrorUART4();
1361  u8_c = U4RXREG; //read character
1362  u16_rxFifo4Head++; //increment head pointer
1363  if (u16_rxFifo4Head == UART4_RX_FIFO_SIZE)
1364  u16_rxFifo4Head = 0; //wrap if needed
1365  if (u16_rxFifo4Head == u16_rxFifo4Tail) {
1366  //FIFO overrun!, report error
1367  reportError("UART4 RX Interrupt FIFO overrun!");
1368  }
1369  au8_rxFifo4[u16_rxFifo4Head] = u8_c; //place in buffer
1370 }
1371 
1372 #else
1373 /**
1374 * Return true if character is ready to be read
1375 */
1376 uint8_t isCharReady4(void) {
1377  return(IS_CHAR_READY_UART4());
1378 }
1379 
1380 /**
1381 * Wait for a byte to be available from UART4 RX.
1382 * \return Character read from UART4 RX.
1383 */
1384 uint8_t inChar4(void) {
1385  //do heartbeat while waiting for character.
1386  // Use a do-while to insure error checks
1387  // are always run.
1388  while (!IS_CHAR_READY_UART4())
1389  doHeartbeat();
1390  checkRxErrorUART4();
1391  return U4RXREG; //read the receive register
1392 }
1393 #endif
1394 
1395 
1396 // Include this for the non-bootloader case. Also include it for the bootloader if this is the UART the bootloader uses.
1397 #endif // # ifndef BOOTLOADER
1398 #if !defined(BOOTLOADER) || (DEFAULT_UART == 4)
1399 
1400 /** Chose a default BRGH for UART4, used by
1401  * \ref configUART4 to set up UART4.
1402  */
1403 #ifndef DEFAULT_BRGH4
1404 # define DEFAULT_BRGH4 DEFAULT_BRGH
1405 #endif
1406 
1407 #if (DEFAULT_BRGH4 != 0) && (DEFAULT_BRGH4 != 1)
1408 # error "Invalid value specified for DEFAULT_BRGH4."
1409 #endif
1410 
1411 
1412 /** Configure the UART. Settings chosen:
1413  * - TX is on RP11
1414  * - RX is on RP10
1415  * - Format is 8 data bits, no parity, 1 stop bit
1416  * - CTS, RTS, and BCLK not used
1417  *
1418  * \param u32_baudRate The baud rate to use.
1419  */
1420 void configUART4(uint32_t u32_baudRate) {
1421  /************************* UART config ********************/
1422  // See comments in the #warning statements below for
1423  // instructions on how to modify this configuration.
1424  // More information on each of these board is given
1425  // in the HARDWARE_PLATFORM section of pic24_libconfig.h.
1426 #if (HARDWARE_PLATFORM == EXPLORER16_100P) || (HARDWARE_PLATFORM == HARDMAPPED_UART)
1427  // There's nothing to do, since pins on these boards are
1428  // mapped to fixed ports.
1429 #elif (4 == 1)
1430  // The following pin mappings will apply only to UART 1.
1431  // Change them as necessary for your device.
1432 # if (HARDWARE_PLATFORM == DANGEROUS_WEB)
1433 # warning Building configUART4() for the Dangerous Web target.
1434  CONFIG_RB14_AS_DIG_INPUT(); // RX pin must be digital input
1435  CONFIG_U1RX_TO_RP(RB14_RP); // U1RX <- RB14
1436  CONFIG_RB15_AS_DIG_OUTPUT(); // TX pin must be digital output
1437  CONFIG_U1TX_TO_RP(RB15_RP); // U1TX -> RB15
1438 # elif (HARDWARE_PLATFORM == STARTER_BOARD_28P)
1439 # warning Building configUART4() for the StarterBoard_28P target.
1440  CONFIG_RB9_AS_DIG_INPUT(); // RX pin must be digital input
1441  CONFIG_U1RX_TO_RP(RB9_RP); // U1RX <- RB9
1442  CONFIG_RB8_AS_DIG_OUTPUT(); // TX pin must be digital output
1443  CONFIG_U1TX_TO_RP(RB8_RP); // U1TX -> RB8
1444 # elif (HARDWARE_PLATFORM == DEFAULT_DESIGN) || (HARDWARE_PLATFORM == MICROSTICK2)
1445  CONFIG_RB10_AS_DIG_INPUT(); // RX pin must be digital input
1446  CONFIG_U1RX_TO_RP(RB10_RP); // U1RX <- RB10
1447  CONFIG_RB11_AS_DIG_OUTPUT(); // TX pin must be digital output
1448  CONFIG_U1TX_TO_RP(RB11_RP); // U1TX -> RB11
1449 # elif (HARDWARE_PLATFORM == EMBEDDED_C1)
1450 # warning Building configUART4() for the Rev.C1 Embedded Systems target.
1451  CONFIG_RB12_AS_DIG_INPUT(); // RX pin must be digital input
1452  CONFIG_U1RX_TO_RP(RB12_RP); // U1RX <- RB12
1453  CONFIG_RC8_AS_DIG_OUTPUT(); // TX pin must be digital output
1454  CONFIG_U1TX_TO_RP(RC8_RP); // U1TX -> RC8
1455 # elif (HARDWARE_PLATFORM == EMBEDDED_F14)
1456 # warning Building configUART4() for the Rev.F14 Embedded Systems target.
1457  CONFIG_RB10_AS_DIG_INPUT(); // RX pin must be digital input
1458  CONFIG_U1RX_TO_RP(RB10_RP); // U1RX <- RB10
1459  CONFIG_RF0_AS_DIG_OUTPUT(); // TX pin must be digital output
1460  CONFIG_U1TX_TO_RP(RF0_RP); // U1TX -> RF0??? (Use RF0 for now.)
1461 # else
1462 # error "Unknown hardware platform."
1463 # endif
1464 #else
1465 # warning "UART4 pin mappings not defined. See comments below for more info."
1466  // If your device has more than one UART, ****** CHANGE THE MAPPING ******
1467  // since multiple UARTs can not share the same pins. In particular:
1468  // 1. Change the statement #if (4 == 1) to #if 1
1469  // 2. Change the pin numbers above
1470  // to something valid for your device.
1471  // If your device does not have remappable I/O,
1472  // (typical for >44 pin packages), skip this step --
1473  // the UART I/O pins are already assigned to something
1474  // valid.
1475 #endif
1476 
1477  // First, disable the UART, clearing all errors, terminating
1478  // any in-progress transmissions/receptions, etc.
1479  // In particular, this clears UTXEN.
1480  U4MODE = (0u << 15); // UARTEN = 0 to disable.
1481 
1482  // Configure UART baud rate, based on \ref FCY.
1483  U4BRG = compute_brg(FCY, DEFAULT_BRGH4, u32_baudRate);
1484 
1485  // Set up the UART mode register
1486  U4MODE =
1487  (1u << 15) | // UARTEN = 1 (enable the UART)
1488  (0u << 13) | // USIDL = 0 (continue operation in idle mode)
1489  (0u << 12) | // IREN = 0 (IrDA encoder and decoder disabled)
1490  (0u << 11) | // RTSMD = 0 (UxRTS# in flow control mode. Given
1491  // // the UEN setting below, this doesn't matter.)
1492  (0b00 << 8) | // UEN = 00 (UxTX and UxRx pins are enabled and used;
1493  // // used; UxCTS, UxRTS, and BCLKx pins are
1494  // // controlled by port latches)
1495  (0u << 7) | // WAKE = 0 (Wake-up on start bit detect during
1496  // // sleep mode disabled)
1497  (0u << 6) | // LPBACK = 0 (UARTx loopback mode is disabled)
1498  (0u << 5) | // ABAUD = 0 (Auto-baud disabled)
1499  (0u << 4) | // URXINV = 0 (Receve polarity inversion bit:
1500  // // UxRX idle state is 1)
1501  (DEFAULT_BRGH4 << 3) | // BRGH (High/low baud rate select bit:
1502  // // 1 = high speed, 0 = low speed)
1503  (0b00 << 1) | // PDSEL = 00 (8-bit data, no parity)
1504  (0u << 0); // STSEL = 0 (1 stop bit)
1505 
1506  // Set up the UART status and control register
1507  U4STA =
1508  (0u << 15) | // UTXISEL1 = 0 (See bit 13 below for explanation)
1509  (0u << 14) | // UTXINV = 0 (UxTX idle state is 1 (though docs
1510  // // say 0))
1511  (0u << 13) | // UTXISEL0 = 0 (With bit 15 above, UTXISEL = 00:
1512  // // Interrupt generated when any character
1513  // // is transferred to the Transmit Shift Register).
1514 #if (defined(__dsPIC33E__) || defined(__PIC24E__))
1515  (1u << 12) | //URXEN=1, defined on some dsPIC33E/PIC24E members, enables RX.
1516 #endif
1517  (0u << 11) | // UTXBRK = 0 (Sync break transmission disabled)
1518  (1u << 10) | // UTXEN = 0 (UARTx transmitter enabled. NOTE: per
1519  // // the data sheet, this must be set *AFTER* UARTEN
1520  // // is set to 1 (see UxMODE assignment above).
1521  (0b00 << 6) | // URXISEL = 00 (Interrupt flag bit is set when a
1522  // // character is received)
1523  (0u << 5) | // ADDEN = 0 (Address detect mode disabled)
1524  (0u << 1); // OERR = 0 (Clear any overrun errors)
1525 
1526  // Delay 1 ms (at least one bit time) before beginning transmission,
1527  // since the UxTX pin is initially configured as an input on device
1528  // reset. It needs to be high for at least one bit time before
1529  // a character is sent in order for the start bit to be recognized.
1530  // See 24H FRM Sec. 17.5 for more details.
1531  ASSERT(u32_baudRate >= 1000L);
1532  // Note: If the baud rate is less than 1000, this delay
1533  // isn't long encough. The alternative is to use floating-point
1534  // math to compute the correct delay, which seems worse than the
1535  // problem.
1536  DELAY_MS(1);
1537 
1538  // Clear any errors
1539  U4STAbits.OERR = 0;
1540  while (U4STAbits.PERR || U4STAbits.FERR) {
1541  U4RXREG; //clear errors by reading RXREG
1542  }
1543 
1544  // Set up interrupts if requested
1545 #ifdef UART4_RX_INTERRUPT
1546  _U4RXIF = 0; //clear the flag
1547  _U4RXIP = UART4_RX_INTERRUPT_PRIORITY; //choose a priority
1548  _U4RXIE = 1; //enable the interrupt
1549 #endif
1550 #ifdef UART4_TX_INTERRUPT
1551  //do not clear the U4TXIF flag!
1552  _U4TXIP = UART4_TX_INTERRUPT_PRIORITY; //choose a priority
1553  //do not enable the interrupt until we try to write to the UART
1554 #endif
1555 
1556 }
1557 
1558 #endif // #if !defined(BOOTLOADER) || (DEFAULT_UART == 4)
1559 
1560 #endif // #if (NUM_UARTS >= 4)
#define CONFIG_RC8_AS_DIG_OUTPUT()
void doHeartbeat(void)
Definition: pic24_util.c:104
#define DELAY_MS(ms)
Definition: pic24_delay.h:71
#define RB12_RP
#define CONFIG_RB12_AS_DIG_INPUT()
#define DEFAULT_BRGH1
Definition: pic24_uart.c:234
#define IS_CHAR_READY_UART1()
Definition: pic24_uart.h:57
#define RC8_RP
#define RB15_RP
#define CONFIG_U1RX_TO_RP(pin)
Definition: pic24_ports.h:287
#define IS_TRANSMIT_BUFFER_FULL_UART1()
Definition: pic24_uart.h:63
#define CONFIG_RF0_AS_DIG_OUTPUT()
#define RB14_RP
uint8_t inChar1(void)
Definition: pic24_uart.c:214
Configures the system clock.
#define RB11_RP
void configUART1(uint32_t u32_baudRate)
Definition: pic24_uart.c:250
#define RB8_RP
void outChar1(uint8_t u8_c)
Definition: pic24_uart.c:145
#define CONFIG_RB11_AS_DIG_OUTPUT()
uint16_t compute_brg(uint32_t u32_fcy, uint16_t u16_brgh, uint32_t u32_baudrate)
Definition: pic24_util.c:474
#define RF0_RP
#define CONFIG_RB8_AS_DIG_OUTPUT()
#define FCY
void checkRxErrorUART1(void)
Definition: pic24_uart.c:70
#define CONFIG_RB10_AS_DIG_INPUT()
#define ASSERT(test)
#define RB10_RP
#define CONFIG_U1TX_TO_RP(Rxy_RP)
Definition: pic24_ports.h:443
#define CONFIG_RB14_AS_DIG_INPUT()
#define CONFIG_RB9_AS_DIG_INPUT()
#define RB9_RP
unsigned char uint8_t
An abbreviation for an 8-bit unsigned integer.
Definition: dataXferImpl.h:194
void reportError(const char *sz_errorMessage)
Definition: pic24_util.c:183
#define CONFIG_RB15_AS_DIG_OUTPUT()
uint8_t isCharReady1(void)
Definition: pic24_uart.c:206