Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updated PPS support to include a single enum for the peripheral funct…

…ion, and a single function (mapPps()) to do the mapping. This allows for better error checking and a slightly simpler API.
  • Loading branch information...
commit 83c8f68c4c5f9f7a31ea9f6286031e761a32be53 1 parent 26b3720
@EmbeddedMan EmbeddedMan authored
View
13 hardware/pic32/cores/pic32/HardwareSerial.cpp
@@ -60,8 +60,9 @@
//* Sep 8, 2012 <BrianSchmalz> Fix dropping bytes on USB RX bug
//* Jul 26, 2012 <GeneApperson> Added PPS support for PIC32MX1xx/MX2xx devices
//************************************************************************
+#ifndef __LANGUAGE_C__
#define __LANGUAGE_C__
-
+#endif
#include <stdio.h>
#include <string.h>
@@ -112,7 +113,7 @@
*/
#if defined(__PIC32MX1XX__) || defined(__PIC32MX2XX__)
-HardwareSerial::HardwareSerial(p32_uart * uartT, int irqT, int vecT, int iplT, int splT, int pinT, int pinR, int ppsT, int ppsR)
+HardwareSerial::HardwareSerial(p32_uart * uartT, int irqT, int vecT, int iplT, int splT, int pinT, int pinR, ppsFunctionType ppsT, ppsFunctionType ppsR)
#else
HardwareSerial::HardwareSerial(p32_uart * uartT, int irqT, int vecT, int iplT, int splT)
#endif
@@ -128,8 +129,8 @@ HardwareSerial::HardwareSerial(p32_uart * uartT, int irqT, int vecT, int iplT, i
#if defined(__PIC32MX1XX__) || defined(__PIC32MX2XX__)
pinTx = (uint8_t)pinT;
pinRx = (uint8_t)pinR;
- ppsTx = (uint8_t)ppsT;
- ppsRx = (uint8_t)ppsR;
+ ppsTx = ppsT;
+ ppsRx = ppsR;
#endif
/* The interrupt flag and enable control register addresses and
@@ -183,11 +184,11 @@ void HardwareSerial::begin(unsigned long baudRate)
#if defined(__PIC32MX1XX__) || defined(__PIC32MX2XX__)
/* Map the UART TX to the appropriate pin.
*/
- mapPpsOutput(pinTx, ppsTx);
+ mapPps(pinTx, ppsTx);
/* Map the UART RX to the appropriate pin.
*/
- mapPpsInput(pinRx, ppsRx);
+ mapPps(pinRx, ppsRx);
#endif
/* Compute the address of the interrupt priority control
View
8 hardware/pic32/cores/pic32/HardwareSerial.h
@@ -41,7 +41,9 @@
#ifndef HardwareSerial_h
#define HardwareSerial_h
+#ifndef __LANGUAGE_C__
#define __LANGUAGE_C__
+#endif
#include <inttypes.h>
#include <p32xxxx.h>
@@ -89,8 +91,8 @@ class HardwareSerial : public Stream
#if defined(__PIC32MX1XX__) || defined(__PIC32MX2XX__)
uint8_t pinTx; //digital pin number of TX
uint8_t pinRx; //digital pin number for RX
- uint8_t ppsTx; //PPS select for UART TX
- uint8_t ppsRx; //PPS select for UART RX
+ ppsFunctionType ppsTx; //PPS select for UART TX
+ ppsFunctionType ppsRx; //PPS select for UART RX
#endif
p32_regset * ifs; //interrupt flag register set
p32_regset * iec; //interrupt enable control register set
@@ -101,7 +103,7 @@ class HardwareSerial : public Stream
public:
#if defined(__PIC32MX1XX__) || defined(__PIC32MX2XX__)
- HardwareSerial(p32_uart * uartP, int irq, int vec, int ipl, int spl, int pinT, int pinR, int ppsT, int ppsR);
+ HardwareSerial(p32_uart * uartP, int irq, int vec, int ipl, int spl, int pinT, int pinR, ppsFunctionType ppsT, ppsFunctionType ppsR);
#else
HardwareSerial(p32_uart * uartP, int irq, int vec, int ipl, int spl);
#endif
View
116 hardware/pic32/cores/pic32/p32_defs.h
@@ -38,9 +38,11 @@
//* Jul 26, 2012 <GeneApperson> Added PPS support for PIC32MX1xx/MX2xx devices
//************************************************************************
-#if !defined(_P32_DEFS_H)
+
+#ifndef _P32_DEFS_H
#define _P32_DEFS_H
+#include "cpudefs.h"
#include <inttypes.h>
/* ------------------------------------------------------------ */
@@ -277,39 +279,46 @@ typedef struct {
*/
typedef uint32_t p32_ppsout;
+#define _PPS_INPUT_BIT (1 << 15)
+#define PPS_OUT_MASK 0x000F
+#define PPS_IN_MASK 0x00FF
+#define NUM_PPS_IN 44 // This must be set to the highest PPS_IN_xxx value
+#define NUM_PPS_OUT 7 // This must be set to the highest PPS_OUT_xxx value
+
+/* This enum specifies all of the possible input and output peripherals you can
+** pass into the mapPps() function's <func> parameter. All of the inputs
+** have their _PPS_INPUT_BIT set, while the outputs don't. (Thats how the
+** mapPps() function can tell the difference.)
+*/
+
+typedef enum {
/* The following symbols define the output functions that are mappable with
** PPS. These give the select values used to map a peripheral function to a PPS
** output pin combined with their set membership. The PPS output select values
** are divided into four sets. Some peripheral functions are duplicated in more
** than one set. In this case they have the same select value in each set.
*/
-#define PPS_OUT_MASK 0x000F
-
-#define PPS_OUT_GPIO (0 + (_PPS_SET_A|_PPS_SET_B|_PPS_SET_C|_PPS_SET_D))
+ PPS_OUT_GPIO = (0 + (_PPS_SET_A|_PPS_SET_B|_PPS_SET_C|_PPS_SET_D)),
-#define PPS_OUT_U1TX (1 + _PPS_SET_A)
-#define PPS_OUT_U2RTS (2 + _PPS_SET_A)
-#define PPS_OUT_SS1 (3 + _PPS_SET_A)
-#define PPS_OUT_OC1 (5 + _PPS_SET_A)
-#define PPS_OUT_C2OUT (7 + _PPS_SET_A)
+ PPS_OUT_U1TX = (1 + _PPS_SET_A),
+ PPS_OUT_U2RTS = (2 + _PPS_SET_A),
+ PPS_OUT_SS1 = (3 + _PPS_SET_A),
+ PPS_OUT_OC1 = (5 + _PPS_SET_A),
+ PPS_OUT_C2OUT = (7 + _PPS_SET_A),
-#define PPS_OUT_SDO1 (3 + (_PPS_SET_B|_PPS_SET_C))
-#define PPS_OUT_SDO2 (4 + (_PPS_SET_B|_PPS_SET_C))
-#define PPS_OUT_OC2 (5 + _PPS_SET_B)
+ PPS_OUT_SDO1 = (3 + (_PPS_SET_B | _PPS_SET_C)),
+ PPS_OUT_SDO2 = (4 + (_PPS_SET_B | _PPS_SET_C)),
+ PPS_OUT_OC2 = (5 + _PPS_SET_B),
-#define PPS_OUT_OC4 (5 + _PPS_SET_C)
-#define PPS_OUT_OC5 (6 + _PPS_SET_C)
-#define PPS_OUT_REFCLKO (7 + _PPS_SET_C)
+ PPS_OUT_OC4 = (5 + _PPS_SET_C),
+ PPS_OUT_OC5 = (6 + _PPS_SET_C),
+ PPS_OUT_REFCLKO = (7 + _PPS_SET_C),
-#define PPS_OUT_U1RTS (1 + _PPS_SET_D)
-#define PPS_OUT_U2TX (2 + _PPS_SET_D)
-#define PPS_OUT_SS2 (4 + _PPS_SET_D)
-#define PPS_OUT_OC3 (5 + _PPS_SET_D)
-#define PPS_OUT_C1OUT (7 + _PPS_SET_D)
-
-/* Data type for PPS input select register.
-*/
-typedef uint32_t p32_ppsin;
+ PPS_OUT_U1RTS = (1 + _PPS_SET_D),
+ PPS_OUT_U2TX = (2 + _PPS_SET_D),
+ PPS_OUT_SS2 = (4 + _PPS_SET_D),
+ PPS_OUT_OC3 = (5 + _PPS_SET_D),
+ PPS_OUT_C1OUT = (7 + _PPS_SET_D),
/* The following symbols define the input functions that are mappable
** using PPS. These are used as an index to the input selection mapping
@@ -318,34 +327,39 @@ typedef uint32_t p32_ppsin;
** new input functions, or change the order of the input select registers,
** this mapping will have to be changed to be done through a table.
*/
-#define PPS_IN_MASK 0x00FF
-#define PPS_IN_INT1 (0 + _PPS_SET_D)
-#define PPS_IN_INT2 (1 + _PPS_SET_C)
-#define PPS_IN_INT3 (2 + _PPS_SET_B)
-#define PPS_IN_INT4 (3 + _PPS_SET_A)
-#define PPS_IN_T2CK (5 + _PPS_SET_A)
-#define PPS_IN_T3CK (6 + _PPS_SET_B)
-#define PPS_IN_T4CK (7 + _PPS_SET_C)
-#define PPS_IN_T5CK (8 + _PPS_SET_D)
-#define PPS_IN_IC1 (9 + _PPS_SET_C)
-#define PPS_IN_IC2 (10 + _PPS_SET_D)
-#define PPS_IN_IC3 (11 + _PPS_SET_B)
-#define PPS_IN_IC4 (12 + _PPS_SET_A)
-#define PPS_IN_IC5 (13 + _PPS_SET_C)
-#define PPS_IN_OCFA (17 + _PPS_SET_D)
-#define PPS_IN_OCFB (18 + _PPS_SET_C)
-#define PPS_IN_U1RX (19 + _PPS_SET_C)
-#define PPS_IN_U1CTS (20 + _PPS_SET_B)
-#define PPS_IN_U2RX (21 + _PPS_SET_B)
-#define PPS_IN_U2CTS (22 + _PPS_SET_C)
-#define PPS_IN_SDI1 (31 + _PPS_SET_B)
-#define PPS_IN_SS1 (32 + _PPS_SET_A)
-#define PPS_IN_SDI2 (34 + _PPS_SET_C)
-#define PPS_IN_SS2 (35 + _PPS_SET_D)
-#define PPS_IN_REFCLKI (44 + _PPS_SET_A)
-
-#define NUM_PPS_IN 24
+ PPS_IN_INT1 = (0 + _PPS_SET_D + _PPS_INPUT_BIT),
+ PPS_IN_INT2 = (1 + _PPS_SET_C + _PPS_INPUT_BIT),
+ PPS_IN_INT3 = (2 + _PPS_SET_B + _PPS_INPUT_BIT),
+ PPS_IN_INT4 = (3 + _PPS_SET_A + _PPS_INPUT_BIT),
+ PPS_IN_T2CK = (5 + _PPS_SET_A + _PPS_INPUT_BIT),
+ PPS_IN_T3CK = (6 + _PPS_SET_B + _PPS_INPUT_BIT),
+ PPS_IN_T4CK = (7 + _PPS_SET_C + _PPS_INPUT_BIT),
+ PPS_IN_T5CK = (8 + _PPS_SET_D + _PPS_INPUT_BIT),
+ PPS_IN_IC1 = (9 + _PPS_SET_C + _PPS_INPUT_BIT),
+ PPS_IN_IC2 = (10 + _PPS_SET_D + _PPS_INPUT_BIT),
+ PPS_IN_IC3 = (11 + _PPS_SET_B + _PPS_INPUT_BIT),
+ PPS_IN_IC4 = (12 + _PPS_SET_A + _PPS_INPUT_BIT),
+ PPS_IN_IC5 = (13 + _PPS_SET_C + _PPS_INPUT_BIT),
+ PPS_IN_OCFA = (17 + _PPS_SET_D + _PPS_INPUT_BIT),
+ PPS_IN_OCFB = (18 + _PPS_SET_C + _PPS_INPUT_BIT),
+ PPS_IN_U1RX = (19 + _PPS_SET_C + _PPS_INPUT_BIT),
+ PPS_IN_U1CTS = (20 + _PPS_SET_B + _PPS_INPUT_BIT),
+ PPS_IN_U2RX = (21 + _PPS_SET_B + _PPS_INPUT_BIT),
+ PPS_IN_U2CTS = (22 + _PPS_SET_C + _PPS_INPUT_BIT),
+ PPS_IN_SDI1 = (31 + _PPS_SET_B + _PPS_INPUT_BIT),
+ PPS_IN_SS1 = (32 + _PPS_SET_A + _PPS_INPUT_BIT),
+ PPS_IN_SDI2 = (34 + _PPS_SET_C + _PPS_INPUT_BIT),
+ PPS_IN_SS2 = (35 + _PPS_SET_D + _PPS_INPUT_BIT),
+ PPS_IN_REFCLKI = (44 + _PPS_SET_A + _PPS_INPUT_BIT),
+
+} ppsFunctionType;
+
+
+/* Data type for PPS input select register.
+*/
+typedef uint32_t p32_ppsin;
+
/* These symbols define the values to load into a PPS input select register
** to assign the actual input pin. The PIC32 architecture divides these values
View
9 hardware/pic32/cores/pic32/pins_arduino.h
@@ -165,13 +165,16 @@
#define isPpsPin(P) ((digital_pin_to_pps_out_PGM[P] == NOT_PPS_PIN) ? 0 : 1)
-#define ppsOutputRegister(P) (volatile uint32_t *)((uint32_t)(&_RPOBASE) + 4*digital_pin_to_pps_out_PGM[P])
-#define ppsInputRegister(F) ((uint32_t *)(4*((F) & 0x00FF) + (uint32_t)&_RPIBASE))
#define ppsInputSelect(P) (digital_pin_to_pps_in_PGM[P] & 0x000F)
#define ppsOutputSelect(F) ((F) & PPS_OUT_MASK)
#define ppsSetFromPin(P) ((digital_pin_to_pps_in_PGM[P] >> 4) & 0x000F)
#define ppsSetFromFunc(F) (((F) >> 8) & 0x000F)
-#define ppsInputFromFunc(F) ((F) & 0x00FF)
+#define ppsInputFromFunc(F) ((F) & PPS_IN_MASK)
+#define ppsOutputFromFunc(F) ((F) & PPS_OUT_MASK)
+#define ppsFuncIsInput(F) ((F) & _PPS_INPUT_BIT)
+#define ppsFuncIsOutput(F) (~ppsFuncIsInput(F))
+#define ppsOutputRegister(P) (volatile uint32_t *)((uint32_t)(&_RPOBASE) + 4*digital_pin_to_pps_out_PGM[P])
+#define ppsInputRegister(F) ((uint32_t *)(4*(ppsInputFromFunc(F)) + (uint32_t)&_RPIBASE))
#define timerOCtoDigitalPin(P) (uint8_t)(output_compare_to_digital_pin_PGM[P])
View
68 hardware/pic32/cores/pic32/wiring.c
@@ -96,6 +96,9 @@ volatile unsigned long gMicros_calculating = 0;
// SoftPWM library update function pointer
uint32_t (*gSoftPWMServoUpdate)(void) = NULL;
+// PPS lock variable
+uint8_t ppsGlobalLock = false;
+
//************************************************************************
unsigned long millis()
{
@@ -236,22 +239,53 @@ void _board_init(void);
*/
#if defined(__PIC32MX1XX__) || defined(__PIC32MX2XX__)
-
+// Locks all PPS functions so that calls to mapPpsInput() or mapPpsOutput() always fail.
+// You would use this function if you set up all of your PPS settings at the beginning
+// of your sketch, and then wanted to prevent any changes while running the rest of the
+// sketch. Can be unlocked with unlockPps().
void lockPps()
{
-
+ ppsGlobalLock = true;
}
+// Once the PPS system has been locked with logkPps(), this function will unlock it.
+// Use this function before making any changes with mapPpsInput() or mapPpsOutput()
+// functions.
void unlockPps()
{
-
+ ppsGlobalLock = false;
}
-int mapPpsInput(uint8_t pin, int func)
+// Use this function to connect up a input or output function (peripheral) with a
+// digitial pin.
+// <pin> : Digital pin to connect
+// <func> : Input or output name from ppsFunctionType enum (see p32_defs.h)
+// Note that this function will fail if the pps system is locked, or if
+// <pin> can't be mapped to <func>. There are only certain pins (up to 8)
+// that can be mapped ro each <func>.
+boolean mapPps(uint8_t pin, ppsFunctionType func)
{
p32_ppsin * pps;
- if (!isPpsPin(pin) || (ppsInputFromFunc(func) >= NUM_PPS_IN))
+ // if the pps system is locked, then don't do anything
+ if (ppsGlobalLock)
+ {
+ return false;
+ }
+
+ if (!isPpsPin(pin))
+ {
+ return false;
+ }
+
+ // Check for valid PPS pin number and valid function number (input or output)
+ if (
+ !isPpsPin(pin)
+ ||
+ ((ppsInputFromFunc(func) > NUM_PPS_IN) && ppsFuncIsInput(func))
+ ||
+ ((ppsOutputFromFunc(func) > NUM_PPS_OUT) && ppsFuncIsOutput(func))
+ )
{
return false;
}
@@ -264,40 +298,24 @@ int mapPpsInput(uint8_t pin, int func)
return false;
}
+ if (ppsFuncIsInput(func))
+ {
/* An input is mapped from the pin to the peripheral input
** function by storing the select value into the register associated
** with the peripheral function.
*/
pps = ppsInputRegister(func);
*pps = ppsInputSelect(pin);
-
- return true;
-
-}
-
-int mapPpsOutput(uint8_t pin, int func)
-{
- p32_ppsout * pps;
-
- if (!isPpsPin(pin))
- {
- return false;
}
-
- /* Check if the requested peripheral output function can be mapped to
- ** the requested pin.
- */
- if ((ppsSetFromPin(pin) & ppsSetFromFunc(func)) == 0)
+ else
{
- return false;
- }
/* An output is mapped by storing the select value for the output function
** being mapped into the mapping register associated with the pin.
*/
pps = ppsOutputRegister(pin);
*pps = ppsOutputSelect(func);
-
+ }
return true;
}
View
37 hardware/pic32/cores/pic32/wiring.h
@@ -37,12 +37,15 @@
#if defined(__AVR__)
#include <avr/io.h>
+#elif defined(__PIC32MX__)
+ #include "p32_defs.h"
#endif
#include <inttypes.h>
#include "binary.h"
#include "cpudefs.h" //* This file is designed to provide some of the cpu specific definitions
//* that are available for avr chips and not for other chips (i.e. pic32)
+ //* It now contains PIC32 speciffic defines as well.
#ifdef __cplusplus
extern "C"{
@@ -159,14 +162,11 @@ unsigned int executeSoftReset(uint32_t options);
unsigned int attachCoreTimerService(uint32_t (*)(uint32_t count));
unsigned int detachCoreTimerService(uint32_t (*)(uint32_t count));
-unsigned int callCoreTimerServiceNow(uint32_t (* service)(uint32_t));
+unsigned int callCoreTimerServiceNow(uint32_t (* service)(uint32_t));
void setup(void);
void loop(void);
-#ifdef __cplusplus
-} // extern "C"
-#endif
#if !defined(__AVR__)
#define _BV(bit) (1ul << (bit))
@@ -312,4 +312,33 @@ extern const IMAGE_HEADER_INFO _image_header_info; // this is the header in
extern unsigned int __PIC32_pbClk;
#endif
+#if defined(__PIC32MX1XX__) || defined(__PIC32MX2XX__)
+
+// PPS Support for PIC32MX1 and PIC32MX2 parts
+// Locks all PPS functions so that calls to mapPpsInput() or mapPpsOutput() always fail.
+// You would use this function if you set up all of your PPS settings at the beginning
+// of your sketch, and then wanted to prevent any changes while running the rest of the
+// sketch. Can be unlocked with unlockPps().
+void lockPps();
+
+// Once the PPS system has been locked with logkPps(), this function will unlock it.
+// Use this function before making any changes with mapPpsInput() or mapPpsOutput()
+// functions.
+void unlockPps();
+
+// Use this function to assign a digital pin to a particular digital peripheral function.
+// <pin> is the digital pin you want to change
+// <func> is the name of the periphreal function to assign <pin> to. (see ppsFunctionType
+// enum in p32_defs.h)
+// Note that for a given <func> there are only a certain subset of possible pins that
+// can be assigned (up to 8 possible, as defined in the PIC32 datasheet). If you pass
+// in a <pin> that can't be assigned to <func>, this function will return 'false'.
+boolean mapPps(uint8_t pin, ppsFunctionType func);
+
+#endif // defined(__PIC32MX1XX__) || defined(__PIC32MX2XX__)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
#endif
Please sign in to comment.
Something went wrong with that request. Please try again.