Spikes on UNO R4 DAC output using analogWrite()

I tried using the UNO R4 Minima (and WiFi) a few months ago to generate some triangle waves with a period of maybe 5 seconds for some testing. My results didn't make sense until I realised there were spikes on the output. I didn't capture these but I've just spotted a recent Playduino YouTube video which shows these.

I've included some screen grabs here from the video. First shows analogWrite(A0, 127) in a loop which one would hope would produce a constant 2.5V (in 8bit mode) but you can see the noise on this, appears to mainly be upward spikes.

This is an attempt at a 12bit sine wave and again it has many upward spikes and possibly a few smaller downward ones, that's less clear.

Looking at forum posts I see Hairy output on R4 DAC but the noise there was far more dramatic and attributed to some undesirable side-effects from constant re-initialisation of the DAC under the covers. This must have been fixed.

Does analogWrite() still need fixing to get clean output from the DAC?

I think that the issue is worse than that still from the video shows.

The DS1062CA oscilloscope used is an obsolete model with a limited memory depth of 10 kpts. The user manual is dated December 2009.

Using a more modern oscilloscope with higher memory depth/resolution it is possible to see the spikes more clearly:

Thanks, I was hoping someone else could confirm this and look more closely/accurately with some good test equipment.

If the spikes are towards the midpoint voltage it's strange that the 127 values constantly output in 8bit DAC mode are so upwardly spiky.

In order to make all relevant information available to any who are interested in this subject, I'll share a link to the formal report @kevinjwalters submitted to the developers of the "Arduino UNO R4 Boards" platform:

@kevinjwalters - best to use direct register operations to avoid the uncertainties of other's libraries.

Look at D7 for the interrupt processing - sine calculation time.

Apologies for all the header stuff, should be put into a separate .H header file. Defines for UNO R4 Minima.

/*  Arduino UNO R4 test code for fast non-blocking ADC analog-read, and DAC analog-write operation
 *  With fast sine calculation of frequency from ADC value using Timer 7 interrupt at c. 44.1kHz
 *
 *  Susan Parker - 4th April 2025.
 *    Realtime sine calc with Paul Stoffregen's 11th order Taylor Series Approximation
 *    https://www.pjrc.com/high-precision-sine-wave-synthesis-using-taylor-series/
 *    Note: I have condensed the Taylor Series code to a single set of inline asm calls
 *
 * This code is "AS IS" without warranty or liability. 
 * There may be glitches, etc. please let me know if you find any; thanks.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
*/

// ARM-developer - Accessing memory-mapped peripherals
// https://developer.arm.com/documentation/102618/0100

// ==== Interrupt Control Unit ====

/* Default Arduino Startup - see section 13.3.2 for Event Number info
 0 33 USBFS_USBI
 1 34 USBFS_USBR
 2 31 USBFS_D0FIFO
 3 32 USBFS_D1FIFO
 4 1E AGT0_AGTI
 ...
*/

#define ICUBASE 0x40000000 // ICU Base - See 13.2.6 page 233
// 32 bits - 
#define IELSR 0x6300 // ICU Event Link Setting Register n
#define ICU_IELSR00 ((volatile unsigned int *)(ICUBASE + IELSR))            //
#define ICU_IELSR01 ((volatile unsigned int *)(ICUBASE + IELSR + ( 1 * 4))) // 
#define ICU_IELSR02 ((volatile unsigned int *)(ICUBASE + IELSR + ( 2 * 4))) // 
#define ICU_IELSR03 ((volatile unsigned int *)(ICUBASE + IELSR + ( 3 * 4))) // 
#define ICU_IELSR04 ((volatile unsigned int *)(ICUBASE + IELSR + ( 4 * 4))) // 
#define ICU_IELSR05 ((volatile unsigned int *)(ICUBASE + IELSR + ( 5 * 4))) // 
#define ICU_IELSR06 ((volatile unsigned int *)(ICUBASE + IELSR + ( 6 * 4))) // 
#define ICU_IELSR07 ((volatile unsigned int *)(ICUBASE + IELSR + ( 7 * 4))) // 
#define ICU_IELSR08 ((volatile unsigned int *)(ICUBASE + IELSR + ( 8 * 4))) // 
#define ICU_IELSR09 ((volatile unsigned int *)(ICUBASE + IELSR + ( 9 * 4))) // 
#define ICU_IELSR10 ((volatile unsigned int *)(ICUBASE + IELSR + (10 * 4))) // 
#define ICU_IELSR11 ((volatile unsigned int *)(ICUBASE + IELSR + (11 * 4))) // 
#define ICU_IELSR12 ((volatile unsigned int *)(ICUBASE + IELSR + (12 * 4))) // 
#define ICU_IELSR13 ((volatile unsigned int *)(ICUBASE + IELSR + (13 * 4))) // 
#define ICU_IELSR14 ((volatile unsigned int *)(ICUBASE + IELSR + (14 * 4))) // 
#define ICU_IELSR15 ((volatile unsigned int *)(ICUBASE + IELSR + (15 * 4))) // 
#define ICU_IELSR16 ((volatile unsigned int *)(ICUBASE + IELSR + (16 * 4))) // 
#define ICU_IELSR17 ((volatile unsigned int *)(ICUBASE + IELSR + (17 * 4))) // 
#define ICU_IELSR18 ((volatile unsigned int *)(ICUBASE + IELSR + (18 * 4))) // 
#define ICU_IELSR19 ((volatile unsigned int *)(ICUBASE + IELSR + (19 * 4))) // 
#define ICU_IELSR20 ((volatile unsigned int *)(ICUBASE + IELSR + (20 * 4))) // 
#define ICU_IELSR21 ((volatile unsigned int *)(ICUBASE + IELSR + (21 * 4))) // 
#define ICU_IELSR22 ((volatile unsigned int *)(ICUBASE + IELSR + (22 * 4))) // 
#define ICU_IELSR23 ((volatile unsigned int *)(ICUBASE + IELSR + (23 * 4))) // 
#define ICU_IELSR24 ((volatile unsigned int *)(ICUBASE + IELSR + (24 * 4))) // 
#define ICU_IELSR25 ((volatile unsigned int *)(ICUBASE + IELSR + (25 * 4))) // 
#define ICU_IELSR26 ((volatile unsigned int *)(ICUBASE + IELSR + (26 * 4))) // 
#define ICU_IELSR27 ((volatile unsigned int *)(ICUBASE + IELSR + (27 * 4))) // 
#define ICU_IELSR28 ((volatile unsigned int *)(ICUBASE + IELSR + (28 * 4))) // 
#define ICU_IELSR29 ((volatile unsigned int *)(ICUBASE + IELSR + (29 * 4))) // 
#define ICU_IELSR30 ((volatile unsigned int *)(ICUBASE + IELSR + (30 * 4))) // 
#define ICU_IELSR31 ((volatile unsigned int *)(ICUBASE + IELSR + (31 * 4))) // 

// IRQ Event Numbers
#define IRQ_NO_EVENT         0x00
#define IRQ_PORT_IRQ0        0x01
#define IRQ_PORT_IRQ1        0x02
#define IRQ_PORT_IRQ2        0x03
#define IRQ_PORT_IRQ3        0x04
#define IRQ_PORT_IRQ4        0x05
#define IRQ_PORT_IRQ5        0x06
#define IRQ_PORT_IRQ6        0x07
#define IRQ_PORT_IRQ7        0x08
#define IRQ_PORT_IRQ8        0x09
#define IRQ_PORT_IRQ9        0x0A
#define IRQ_PORT_IRQ10       0x0B
#define IRQ_PORT_IRQ11       0x0C
#define IRQ_PORT_IRQ12       0x0D
//      IRQ_PORT_UNUSED      0x0E
#define IRQ_PORT_IRQ14       0x0F
#define IRQ_PORT_IRQ15       0x10
#define IRQ_DMAC0_INT        0x11
#define IRQ_DMAC1_INT        0x12
#define IRQ_DMAC2_INT        0x13
#define IRQ_DMAC3_INT        0x14
#define IRQ_DTC_COMPLETE     0x15
//      IRQ_UNUSED           0x16
#define IRQ_ICU_SNZCANCEL    0x17
#define IRQ_FCU_FRDYI        0x18
#define IRQ_LVD_LVD1         0x19
#define IRQ_LVD_LVD2         0x1A
#define IRQ_VBATT_LVD        0x1B
#define IRQ_MOSC_STOP        0x1C
#define IRQ_SYSTEM_SNZREQ    0x1D
#define IRQ_AGT0_AGTI        0x1E
#define IRQ_AGT0_AGTCMAI     0x1F
#define IRQ_AGT0_AGTCMBI     0x20
#define IRQ_AGT1_AGTI        0x21
#define IRQ_AGT1_AGTCMAI     0x22
#define IRQ_AGT1_AGTCMBI     0x23
#define IRQ_IWDT_NMIUNDF     0x24
#define IRQ_WDT_NMIUNDF      0x25
#define IRQ_RTC_ALM          0x26
#define IRQ_RTC_PRD          0x27
#define IRQ_RTC_CUP          0x28
#define IRQ_ADC140_ADI       0x29
#define IRQ_ADC140_GBADI     0x2A
#define IRQ_ADC140_CMPAI     0x2B
#define IRQ_ADC140_CMPBI     0x2C
#define IRQ_ADC140_WCMPM     0x2D
#define IRQ_ADC140_WCMPUM    0x2E
#define IRQ_ACMP_LP0         0x2F
#define IRQ_ACMP_LP1         0x30
#define IRQ_USBFS_D0FIFO     0x31
#define IRQ_USBFS_D1FIFO     0x32
#define IRQ_USBFS_USBI       0x33
#define IRQ_USBFS_USBR       0x34
#define IRQ_IIC0_RXI         0x35
#define IRQ_IIC0_TXI         0x36
#define IRQ_IIC0_TEI         0x37
#define IRQ_IIC0_EEI         0x38
#define IRQ_IIC0_WUI         0x39
#define IRQ_IIC1_RXI         0x3A
#define IRQ_IIC1_TXI         0x3B
#define IRQ_IIC1_TEI         0x3C
#define IRQ_IIC1_EEI         0x3D
#define IRQ_SSIE0_SSITXI     0x3E
#define IRQ_SSIE0_SSIRXI     0x3F
//      IRQ_UNUSED           0x40
#define IRQ_SSIE0_SSIF       0x41
#define IRQ_CTSU_CTSUWR      0x42
#define IRQ_CTSU_CTSURD      0x43
#define IRQ_CTSU_CTSUFN      0x44
#define IRQ_KEY_INTKR        0x45
#define IRQ_DOC_DOPCI        0x46
#define IRQ_CAC_FERRI        0x47
#define IRQ_CAC_MENDI        0x48
#define IRQ_CAC_OVFI         0x49
#define IRQ_CAN0_ERS         0x4A
#define IRQ_CAN0_RXF         0x4B
#define IRQ_CAN0_TXF         0x4C
#define IRQ_CAN0_RXM         0x4D
#define IRQ_CAN0_TXM         0x4E
#define IRQ_IOPORT_GROUP1    0x4F
#define IRQ_IOPORT_GROUP2    0x50
#define IRQ_IOPORT_GROUP3    0x51
#define IRQ_IOPORT_GROUP4    0x52
#define IRQ_ELC_SWEVT0       0x53
#define IRQ_ELC_SWEVT1       0x54
#define IRQ_POEG_GROUP0      0x55
#define IRQ_POEG_GROUP1      0x56
#define IRQ_GPT0_CCMPA       0x57
#define IRQ_GPT0_CCMPB       0x58
#define IRQ_GPT0_CMPC        0x59
#define IRQ_GPT0_CMPD        0x5A
#define IRQ_GPT0_CMPE        0x5B
#define IRQ_GPT0_CMPF        0x5C
#define IRQ_GPT0_OVF         0x5D
#define IRQ_GPT0_UDF         0x5E
#define IRQ_GPT1_CCMPA       0x5F
#define IRQ_GPT1_CCMPB       0x60
#define IRQ_GPT1_CMPC        0x61
#define IRQ_GPT1_CMPD        0x62
#define IRQ_GPT1_CMPE        0x63
#define IRQ_GPT1_CMPF        0x64
#define IRQ_GPT1_OVF         0x65
#define IRQ_GPT1_UDF         0x66
#define IRQ_GPT2_CCMPA       0x67
#define IRQ_GPT2_CCMPB       0x68
#define IRQ_GPT2_CMPC        0x69
#define IRQ_GPT2_CMPD        0x6A
#define IRQ_GPT2_CMPE        0x6B
#define IRQ_GPT2_CMPF        0x6C
#define IRQ_GPT2_OVF         0x6D
#define IRQ_GPT2_UDF         0x6E
#define IRQ_GPT3_CCMPA       0x6F
#define IRQ_GPT3_CCMPB       0x70
#define IRQ_GPT3_CMPC        0x71
#define IRQ_GPT3_CMPD        0x72
#define IRQ_GPT3_CMPE        0x73
#define IRQ_GPT3_CMPF        0x74
#define IRQ_GPT3_OVF         0x75
#define IRQ_GPT3_UDF         0x76
#define IRQ_GPT4_CCMPA       0x77
#define IRQ_GPT4_CCMPB       0x78
#define IRQ_GPT4_CMPC        0x79
#define IRQ_GPT4_CMPD        0x7A
#define IRQ_GPT4_CMPE        0x7B
#define IRQ_GPT4_CMPF        0x7C
#define IRQ_GPT4_OVF         0x7D
#define IRQ_GPT4_UDF         0x7E
#define IRQ_GPT5_CCMPA       0x7F
#define IRQ_GPT5_CCMPB       0x80
#define IRQ_GPT5_CMPC        0x81
#define IRQ_GPT5_CMPD        0x82
#define IRQ_GPT5_CMPE        0x83
#define IRQ_GPT5_CMPF        0x84
#define IRQ_GPT5_OVF         0x85
#define IRQ_GPT5_UDF         0x86
#define IRQ_GPT6_CCMPA       0x87
#define IRQ_GPT6_CCMPB       0x88
#define IRQ_GPT6_CMPC        0x89
#define IRQ_GPT6_CMPD        0x8A
#define IRQ_GPT6_CMPE        0x8B
#define IRQ_GPT6_CMPF        0x8C
#define IRQ_GPT6_OVF         0x8D
#define IRQ_GPT6_UDF         0x8E
#define IRQ_GPT7_CCMPA       0x8F
#define IRQ_GPT7_CCMPB       0x90
#define IRQ_GPT7_CMPC        0x91
#define IRQ_GPT7_CMPD        0x92
#define IRQ_GPT7_CMPE        0x93
#define IRQ_GPT7_CMPF        0x94
#define IRQ_GPT7_OVF         0x95
#define IRQ_GPT7_UDF         0x96
#define IRQ_GPT_UVWEDGE      0x97
#define IRQ_SCI0_RXI         0x98
#define IRQ_SCI0_TXI         0x99
#define IRQ_SCI0_TEI         0x9A
#define IRQ_SCI0_ERI         0x9B
#define IRQ_SCI0_AM          0x9C
#define IRQ_SCI0_RXI_OR_ERI  0x9D
#define IRQ_SCI1_RXI         0x9E
#define IRQ_SCI1_TXI         0x9F
#define IRQ_SCI1_TEI         0xA0
#define IRQ_SCI1_ERI         0xA1
#define IRQ_SCI1_AM          0xA2
#define IRQ_SCI2_RXI         0xA3
#define IRQ_SCI2_TXI         0xA4
#define IRQ_SCI2_TEI         0xA5
#define IRQ_SCI2_ERI         0xA6
#define IRQ_SCI2_AM          0xA7
#define IRQ_SCI9_RXI         0xA8
#define IRQ_SCI9_TXI         0xA9
#define IRQ_SCI9_TEI         0xAA
#define IRQ_SCI9_ERI         0xAB
#define IRQ_SCI9_AM          0xAC
#define IRQ_SPI0_SPRI        0xAD
#define IRQ_SPI0_SPTI        0xAE
#define IRQ_SPI0_SPII        0xAF
#define IRQ_SPI0_SPEI        0xB0
#define IRQ_SPI0_SPTEND      0xB1
#define IRQ_SPI1_SPRI        0xB2
#define IRQ_SPI1_SPTI        0xB3
#define IRQ_SPI1_SPII        0xB4
#define IRQ_SPI1_SPEI        0xB5
#define IRQ_SPI1_SPTEND      0xB6


// Low Power Mode Control - See datasheet section 10
#define SYSTEM 0x40010000 // System Registers
#define SYSTEM_SBYCR   ((volatile unsigned short *)(SYSTEM + 0xE00C))      // Standby Control Register
#define SYSTEM_MSTPCRA ((volatile unsigned int   *)(SYSTEM + 0xE01C))      // Module Stop Control Register A

#define MSTP 0x40040000 // Module Registers
#define MSTP_MSTPCRB   ((volatile unsigned int   *)(MSTP + 0x7000))      // Module Stop Control Register B
#define MSTPB2   2 // CAN0
#define MSTPB8   8 // IIC1
#define MSTPB9   9 // IIC0
#define MSTPB18 18 // SPI1
#define MSTPB19 19 // SPI0
#define MSTPB22 22 // SCI9
#define MSTPB29 29 // SCI2
#define MSTPB30 30 // SCI1
#define MSTPB31 31 // SCI0

#define MSTP_MSTPCRC   ((volatile unsigned int   *)(MSTP + 0x7004))      // Module Stop Control Register C
#define MSTP_MSTPCRD   ((volatile unsigned int   *)(MSTP + 0x7008))      // Module Stop Control Register D
#define MSTPD2   2 // AGT1   - Asynchronous General Purpose Timer 1 Module
#define MSTPD3   3 // AGT0   - Asynchronous General Purpose Timer 0 Module
#define MSTPD5   5 // GPT320 and GPT321 General 32 bit PWM Timer Module
#define MSTPD6   6 // GPT162 to GPT167 General 16 bit PWM Timer Module
#define MSTPD14 14 // POEG   - Port Output Enable for GPT Module Stop
#define MSTPD16 16 // ADC140 - 14-Bit A/D Converter Module
#define MSTPD19 19 // DAC8   -  8-Bit D/A Converter Module
#define MSTPD20 20 // DAC12  - 12-Bit D/A Converter Module
#define MSTPD29 29 // ACMPLP - Low-Power Analog Comparator Module
#define MSTPD31 31 // OPAMP  - Operational Amplifier Module

// The Mode Control bits are read as 1, the write value should be 1.
// Bit value 0: Cancel the module-stop state 
// Bit value 1: Enter the module-stop state.

// ====  Asynchronous General Purpose Timer (AGT) =====
#define AGTBASE 0x40084000 
#define AGT0_AGTCR    ((volatile unsigned char  *)(AGTBASE + 0x008))  // AGT Control Register

// =========== ADC14 ============
// 35.2 Register Descriptions
#define ADCBASE 0x40050000 /* ADC Base */

#define ADC140_ADCSR   ((volatile unsigned short *)(ADCBASE + 0xC000)) // A/D Control Register
#define ADC140_ADANSA0 ((volatile unsigned short *)(ADCBASE + 0xC004)) // A/D Channel Select Register A0
#define ADC140_ADANSA1 ((volatile unsigned short *)(ADCBASE + 0xC006)) // A/D Channel Select Register A1
#define ADC140_ADADS0  ((volatile unsigned short *)(ADCBASE + 0xC008)) // A/D-Converted Value Addition/Average Channel Select Register 0
#define ADC140_ADADS1  ((volatile unsigned short *)(ADCBASE + 0xC00A)) // A/D-Converted Value Addition/Average Channel Select Register 1
#define ADC140_ADCER   ((volatile unsigned short *)(ADCBASE + 0xC00E)) // A/D Control Extended Register 
#define ADC140_ADSTRGR ((volatile unsigned short *)(ADCBASE + 0xC010)) // A/D Conversion Start Trigger Select Register
#define ADC140_ADEXICR ((volatile unsigned short *)(ADCBASE + 0xC012)) // A/D Conversion Extended Input Control Register
#define ADC140_ADANSB0 ((volatile unsigned short *)(ADCBASE + 0xC014)) // A/D Channel Select Register B0
#define ADC140_ADANSB1 ((volatile unsigned short *)(ADCBASE + 0xC016)) // A/D Channel Select Register B1
#define ADC140_ADTSDR  ((volatile unsigned short *)(ADCBASE + 0xC01A)) // A/D conversion result of temperature sensor output
#define ADC140_ADOCDR  ((volatile unsigned short *)(ADCBASE + 0xC01C)) // A/D result of internal reference voltage
#define ADC140_ADRD    ((volatile unsigned short *)(ADCBASE + 0xC01E)) // A/D Self-Diagnosis Data Register

#define ADC140_ADDR00 ((volatile unsigned short *)(ADCBASE + 0xC020))      // A1 (P000 AN00 AMP+)
#define ADC140_ADDR01 ((volatile unsigned short *)(ADCBASE + 0xC020 +  2)) // A2 (P001 AN01 AMP-) 
#define ADC140_ADDR02 ((volatile unsigned short *)(ADCBASE + 0xC020 +  4)) // A3 (P002 AN02 AMPO) 
#define ADC140_ADDR05 ((volatile unsigned short *)(ADCBASE + 0xC020 + 10)) // Aref (P010 AN05 VrefH0)
#define ADC140_ADDR09 ((volatile unsigned short *)(ADCBASE + 0xC020 + 18)) // A0 (P014 AN09 DAC)
#define ADC140_ADDR21 ((volatile unsigned short *)(ADCBASE + 0xC040 + 10)) // A4 (P101 AN21 SDA) 
#define ADC140_ADDR22 ((volatile unsigned short *)(ADCBASE + 0xC040 + 12)) // A5 (P100 AN20 SCL) 

#define ADC140_ADHVREFCNT ((volatile unsigned char  *)(ADCBASE + 0xC08A)) // A/D High-Potential/Low-Potential Reference Voltage Control Register
#define ADC140_ADADC      ((volatile unsigned char  *)(ADCBASE + 0xC00C)) // A/D-Converted Value Addition/Average Count Select Register

#define ADC140_ADSSTR00 ((volatile unsigned char *)(ADCBASE + 0xC0E0))      // AN00 A/D Sampling State Register

// 12-Bit D/A Converter
#define DACBASE 0x40050000          // DAC Base - DAC output on A0 (P014 AN09 DAC)
#define DAC12_DADR0    ((volatile unsigned short *)(DACBASE + 0xE000))      // D/A Data Register 0 
#define DAC12_DACR     ((volatile unsigned char  *)(DACBASE + 0xE004))      // D/A Control Register
#define DAC12_DADPR    ((volatile unsigned char  *)(DACBASE + 0xE005))      // DADR0 Format Select Register
#define DAC12_DAADSCR  ((volatile unsigned char  *)(DACBASE + 0xE006))      // D/A A/D Synchronous Start Control Register
#define DAC12_DAVREFCR ((volatile unsigned char  *)(DACBASE + 0xE007))      // D/A VREF Control Register


// =========== Ports ============
// 19.2.5 Port mn Pin Function Select Register (PmnPFS/PmnPFS_HA/PmnPFS_BY) (m = 0 to 9; n = 00 to 15)
#define PORTBASE 0x40040000 /* Port Base */

#define P000PFS 0x0800  // Port 0 Pin Function Select Register
#define PFS_P000PFS ((volatile unsigned int *)(PORTBASE + P000PFS))            // A1 / D15 - AN00 - AMP0+ - IRQ6
#define PFS_P001PFS ((volatile unsigned int *)(PORTBASE + P000PFS + ( 1 * 4))) // A2 / D16 - AN01 - AMP0- - IRQ7
#define PFS_P002PFS ((volatile unsigned int *)(PORTBASE + P000PFS + ( 2 * 4))) // A3 / D17 - AN03 - AMP0O - IRQ2
#define PFS_P003PFS ((volatile unsigned int *)(PORTBASE + P000PFS + ( 3 * 4))) // N/C - AN03
#define PFS_P004PFS ((volatile unsigned int *)(PORTBASE + P000PFS + ( 4 * 4))) // N/C - AN04 - IRQ3
#define PFS_P005PFS ((volatile unsigned int *)(PORTBASE + P000PFS + ( 5 * 4))) // N/A - AN11 - IRQ10
#define PFS_P006PFS ((volatile unsigned int *)(PORTBASE + P000PFS + ( 6 * 4))) // N/A - AN12
#define PFS_P007PFS ((volatile unsigned int *)(PORTBASE + P000PFS + ( 7 * 4))) // N/A - AN13
#define PFS_P008PFS ((volatile unsigned int *)(PORTBASE + P000PFS + ( 8 * 4))) // N/A - AN14
// #define PFS_P009PFS ((volatile unsigned int *)(PORTBASE + P000PFS + ( 9 * 4))) // Does not exist
#define PFS_P010PFS ((volatile unsigned int *)(PORTBASE + P000PFS + (10 * 4))) // N/A - AN05
#define PFS_P011PFS ((volatile unsigned int *)(PORTBASE + P000PFS + (11 * 4))) // N/C - AN06 - IRQ15
#define PFS_P012PFS ((volatile unsigned int *)(PORTBASE + P000PFS + (12 * 4))) // TxLED - AN07
#define PFS_P013PFS ((volatile unsigned int *)(PORTBASE + P000PFS + (13 * 4))) // RxLED - AN08
#define PFS_P014PFS ((volatile unsigned int *)(PORTBASE + P000PFS + (14 * 4))) // A0 / D14 - AN09 - DAC0
#define PFS_P015PFS ((volatile unsigned int *)(PORTBASE + P000PFS + (15 * 4))) // N/C - AN10 - IRQ7

#define P100PFS 0x0840  // Port 1 Pin Function Select Register
#define PFS_P100PFS ((volatile unsigned int *)(PORTBASE + P100PFS))            // A5 / D19 - MISOA - SCL1 - IRQ2
#define PFS_P101PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 1 * 4))) // A4 / D18 - MOSIA - SDA1 - IRQ1
#define PFS_P102PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 2 * 4))) // D5 - RSPCKA
#define PFS_P103PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 3 * 4))) // D4 - SSLA0
#define PFS_P104PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 4 * 4))) // D3 - IRQ1
#define PFS_P105PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 5 * 4))) // D2 - IRQ0
#define PFS_P106PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 6 * 4))) // D6
#define PFS_P107PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 7 * 4))) // D7
#define PFS_P108PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 8 * 4))) // SWD p2 SWDIO
#define PFS_P109PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 9 * 4))) // D11 / MOSI
#define PFS_P110PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (10 * 4))) // D12 / MISO - IRQ3
#define PFS_P111PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (11 * 4))) // D13 / SCLK - IRQ4
#define PFS_P112PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (12 * 4))) // D10 / CS
#define PFS_P113PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (13 * 4))) // N/C
#define PFS_P114PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (14 * 4))) // N/A
#define PFS_P115PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (15 * 4))) // N/A

#define P200PFS 0x0880  // Port 2 Pin Function Select Register
#define PFS_P200PFS ((volatile unsigned int *)(PORTBASE + P200PFS))           // NMI
#define PFS_P201PFS ((volatile unsigned int *)(PORTBASE + P200PFS + (1 * 4))) // MD
#define PFS_P202PFS ((volatile unsigned int *)(PORTBASE + P200PFS + (2 * 4))) // N/A
#define PFS_P203PFS ((volatile unsigned int *)(PORTBASE + P200PFS + (3 * 4))) // N/A
#define PFS_P204PFS ((volatile unsigned int *)(PORTBASE + P200PFS + (4 * 4))) // LOVE (Heart Pad on underside of board)
#define PFS_P205PFS ((volatile unsigned int *)(PORTBASE + P200PFS + (5 * 4))) // N/C - IRQ1
#define PFS_P206PFS ((volatile unsigned int *)(PORTBASE + P200PFS + (6 * 4))) // N/C - IRQ0
// Pins P212, P213, P214, and P215 are Crystal functions, or N/C

#define P300PFS 0x08C0  // Port 3 Pin Function Select Register
#define PFS_P300PFS ((volatile unsigned int *)(PORTBASE + P300PFS))            // SWD p4 SWCLK
#define PFS_P301PFS ((volatile unsigned int *)(PORTBASE + P300PFS + ( 1 * 4))) // D0 / RxD - IRQ6
#define PFS_P302PFS ((volatile unsigned int *)(PORTBASE + P300PFS + ( 2 * 4))) // D1 / TxD - IRQ5
#define PFS_P303PFS ((volatile unsigned int *)(PORTBASE + P300PFS + ( 3 * 4))) // D9
#define PFS_P304PFS ((volatile unsigned int *)(PORTBASE + P300PFS + ( 4 * 4))) // D8  - IRQ9
#define PFS_P305PFS ((volatile unsigned int *)(PORTBASE + P300PFS + ( 5 * 4))) // N/C - IRQ8
#define PFS_P306PFS ((volatile unsigned int *)(PORTBASE + P300PFS + ( 6 * 4))) // N/C
#define PFS_P307PFS ((volatile unsigned int *)(PORTBASE + P300PFS + ( 7 * 4))) // N/C

#define P400PFS 0x0900  // Port 4 Pin Function Select Register
#define PFS_P400PFS ((volatile unsigned int *)(PORTBASE + P100PFS))            // N/C - IRQ0
#define PFS_P401PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 1 * 4))) // N/C - IRQ5
#define PFS_P402PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 2 * 4))) // N/C - IRQ4
#define PFS_P403PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 3 * 4))) // N/A
#define PFS_P404PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 4 * 4))) // N/A
#define PFS_P405PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 5 * 4))) // N/A
#define PFS_P406PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 6 * 4))) // N/A
#define PFS_P407PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 7 * 4))) // ADTRG0 - R7, R8, and R9 divider.
#define PFS_P408PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 8 * 4))) // N/C - IRQ7
#define PFS_P409PFS ((volatile unsigned int *)(PORTBASE + P100PFS + ( 9 * 4))) // N/C - IRQ6
#define PFS_P410PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (10 * 4))) // N/C - IRQ5
#define PFS_P411PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (11 * 4))) // N/C - IRQ4
#define PFS_P412PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (12 * 4))) // N/A
#define PFS_P413PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (13 * 4))) // N/A
#define PFS_P414PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (14 * 4))) // N/A - IRQ9
#define PFS_P415PFS ((volatile unsigned int *)(PORTBASE + P100PFS + (15 * 4))) // N/A - IRQ8

#define P500PFS 0x0940  // Port 5 Pin Function Select Register
#define PFS_P500PFS ((volatile unsigned int *)(PORTBASE + P500PFS))           // AN016 in R10/R26 divider
#define PFS_P501PFS ((volatile unsigned int *)(PORTBASE + P500PFS + (1 * 4))) // SWD p8 TxD - IRQ11
#define PFS_P502PFS ((volatile unsigned int *)(PORTBASE + P500PFS + (2 * 4))) // SWD p7 RxD - IRQ12
#define PFS_P503PFS ((volatile unsigned int *)(PORTBASE + P500PFS + (3 * 4))) // N/A
#define PFS_P504PFS ((volatile unsigned int *)(PORTBASE + P500PFS + (4 * 4))) // N/A
#define PFS_P505PFS ((volatile unsigned int *)(PORTBASE + P500PFS + (5 * 4))) // N/A - IRQ14

#define PFS_PODR   0  // Pin Output Data     - 0: Low output; 1: High output
#define PFS_PIDR   1  // Pin Input State     - Read 0: Low level; 1: High level
#define PFS_PDR    2  // Pin Direction       - 0: Input (input pin); 1: Output (output pin)
#define PFS_PCR    4  // Pull-up Control     - 1: Enable internal pull-up 
#define PFS_NCODR  6  // N-Channel Open Drain Control - 1: NMOS open-drain output.
#define PFS_DSCR  10  // Port Drive Capability - 1: Middle drive; Default 0: Low drive
#define PFS_EOR   12  // Event on Rising     - 1: Detect rising edge  - Set EOR and EOF both to 1
#define PFS_EOF   13  // Event on Falling    - 1: Detect falling edge - ... for Detect both edges
#define PFS_ISEL  14  // IRQ Input Enable    - 1: Used as an IRQn input pin.
#define PFS_ASEL  15  // Analog Input Enable - 1: Used as an analog pin.
#define PFS_PMR   16  // Pin Mode Control    - 1: Used as an I/O port for peripheral functions
#define PFS_PSEL_4_0 24 // Peripheral Function Select

// 16 bit register access
#define PFS_P100PFS_HA ((volatile unsigned short *)(PORTBASE + 0x0842))
#define PFS_P115PFS_HA ((volatile unsigned short *)(PORTBASE + 0x0842 + (15 * 2))) 
#define PFS_P200PFS_HA ((volatile unsigned short *)(PORTBASE + 0x0882))
#define PFS_P206PFS_HA ((volatile unsigned short *)(PORTBASE + 0x0882 + (06 * 2))) //

// 8 bits - Used for fast pin set/clear operations of register lower byte

#define PFS_P100PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843))   // 8 bits - A5
#define PFS_P101PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + ( 1 * 4))) // A4
#define PFS_P102PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + ( 2 * 4))) // D5
#define PFS_P103PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + ( 3 * 4))) // D4
#define PFS_P104PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + ( 4 * 4))) // D3
#define PFS_P105PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + ( 5 * 4))) // D2
#define PFS_P106PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + ( 6 * 4))) // D6
#define PFS_P107PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + ( 7 * 4))) // D7
#define PFS_P108PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + ( 8 * 4))) // SWDIO
#define PFS_P109PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + ( 9 * 4))) // D11 / MOSI
#define PFS_P110PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + (10 * 4))) // D12 / MISO
#define PFS_P111PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + (11 * 4))) // D13 / SCLK
#define PFS_P112PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x0843 + (12 * 4))) // D10 / CS
#define PFS_P300PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x08C3))            // SWCLK (P300)
#define PFS_P301PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x08C3 + (01 * 4))) // D0 / RxD (P301)
#define PFS_P302PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x08C3 + (02 * 4))) // D1 / TxD (P302) 
#define PFS_P303PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x08C3 + (03 * 4))) // D9
#define PFS_P304PFS_BY ((volatile unsigned char  *)(PORTBASE + 0x08C3 + (04 * 4))) // D8


// ==== General PWM Timer (GPT) ====
#define GPTBASE 0x40070000 /* PWM Base */

#define GTWP 0x8000  // General PWM Timer Write-Protection Register
#define GPT320_GTWP ((volatile unsigned int *)(GPTBASE + GTWP))           
#define GPT321_GTWP ((volatile unsigned int *)(GPTBASE + GTWP + 0x0100))
#define GPT162_GTWP ((volatile unsigned int *)(GPTBASE + GTWP + 0x0200))
#define GPT163_GTWP ((volatile unsigned int *)(GPTBASE + GTWP + 0x0300))
#define GPT164_GTWP ((volatile unsigned int *)(GPTBASE + GTWP + 0x0400))
#define GPT165_GTWP ((volatile unsigned int *)(GPTBASE + GTWP + 0x0500))
#define GPT166_GTWP ((volatile unsigned int *)(GPTBASE + GTWP + 0x0600))
#define GPT167_GTWP ((volatile unsigned int *)(GPTBASE + GTWP + 0x0700))

#define GTSTR 0x8004  // General PWM Timer Software Start Register
#define GPT320_GTSTR ((volatile unsigned int *)(GPTBASE + GTSTR))           
#define GPT321_GTSTR ((volatile unsigned int *)(GPTBASE + GTSTR + 0x0100))
#define GPT162_GTSTR ((volatile unsigned int *)(GPTBASE + GTSTR + 0x0200))
#define GPT163_GTSTR ((volatile unsigned int *)(GPTBASE + GTSTR + 0x0300))
#define GPT164_GTSTR ((volatile unsigned int *)(GPTBASE + GTSTR + 0x0400))
#define GPT165_GTSTR ((volatile unsigned int *)(GPTBASE + GTSTR + 0x0500))
#define GPT166_GTSTR ((volatile unsigned int *)(GPTBASE + GTSTR + 0x0600))
#define GPT167_GTSTR ((volatile unsigned int *)(GPTBASE + GTSTR + 0x0700))

#define GTSTP 0x8008  // General PWM Timer Software Stop Register
#define GPT320_GTSTP ((volatile unsigned int *)(GPTBASE + GTSTP))           
#define GPT321_GTSTP ((volatile unsigned int *)(GPTBASE + GTSTP + 0x0100))
#define GPT162_GTSTP ((volatile unsigned int *)(GPTBASE + GTSTP + 0x0200))
#define GPT163_GTSTP ((volatile unsigned int *)(GPTBASE + GTSTP + 0x0300))
#define GPT164_GTSTP ((volatile unsigned int *)(GPTBASE + GTSTP + 0x0400))
#define GPT165_GTSTP ((volatile unsigned int *)(GPTBASE + GTSTP + 0x0500))
#define GPT166_GTSTP ((volatile unsigned int *)(GPTBASE + GTSTP + 0x0600))
#define GPT167_GTSTP ((volatile unsigned int *)(GPTBASE + GTSTP + 0x0700))

#define GTCLR 0x800C  // General PWM Timer Software Clear Register
#define GPT320_GTCLR ((volatile unsigned int *)(GPTBASE + GTCLR))           
#define GPT321_GTCLR ((volatile unsigned int *)(GPTBASE + GTCLR + 0x0100))
#define GPT162_GTCLR ((volatile unsigned int *)(GPTBASE + GTCLR + 0x0200))
#define GPT163_GTCLR ((volatile unsigned int *)(GPTBASE + GTCLR + 0x0300))
#define GPT164_GTCLR ((volatile unsigned int *)(GPTBASE + GTCLR + 0x0400))
#define GPT165_GTCLR ((volatile unsigned int *)(GPTBASE + GTCLR + 0x0500))
#define GPT166_GTCLR ((volatile unsigned int *)(GPTBASE + GTCLR + 0x0600))
#define GPT167_GTCLR ((volatile unsigned int *)(GPTBASE + GTCLR + 0x0700))

#define GTSSR 0x8010  // General PWM Timer Start Source Select Register
#define GPT320_GTSSR ((volatile unsigned int *)(GPTBASE + GTSSR))           
#define GPT321_GTSSR ((volatile unsigned int *)(GPTBASE + GTSSR + 0x0100))
#define GPT162_GTSSR ((volatile unsigned int *)(GPTBASE + GTSSR + 0x0200))
#define GPT163_GTSSR ((volatile unsigned int *)(GPTBASE + GTSSR + 0x0300))
#define GPT164_GTSSR ((volatile unsigned int *)(GPTBASE + GTSSR + 0x0400))
#define GPT165_GTSSR ((volatile unsigned int *)(GPTBASE + GTSSR + 0x0500))
#define GPT166_GTSSR ((volatile unsigned int *)(GPTBASE + GTSSR + 0x0600))
#define GPT167_GTSSR ((volatile unsigned int *)(GPTBASE + GTSSR + 0x0700))

#define GTPSR 0x8014  // General PWM Timer Stop Source Select Register
#define GPT320_GTPSR ((volatile unsigned int *)(GPTBASE + GTPSR))           
#define GPT321_GTPSR ((volatile unsigned int *)(GPTBASE + GTPSR + 0x0100))
#define GPT162_GTPSR ((volatile unsigned int *)(GPTBASE + GTPSR + 0x0200))
#define GPT163_GTPSR ((volatile unsigned int *)(GPTBASE + GTPSR + 0x0300))
#define GPT164_GTPSR ((volatile unsigned int *)(GPTBASE + GTPSR + 0x0400))
#define GPT165_GTPSR ((volatile unsigned int *)(GPTBASE + GTPSR + 0x0500))
#define GPT166_GTPSR ((volatile unsigned int *)(GPTBASE + GTPSR + 0x0600))
#define GPT167_GTPSR ((volatile unsigned int *)(GPTBASE + GTPSR + 0x0700))

#define GTCSR 0x8018  // General PWM Timer Clear Source Select Register
#define GPT320_GTCSR ((volatile unsigned int *)(GPTBASE + GTCSR))           
#define GPT321_GTCSR ((volatile unsigned int *)(GPTBASE + GTCSR + 0x0100))
#define GPT162_GTCSR ((volatile unsigned int *)(GPTBASE + GTCSR + 0x0200))
#define GPT163_GTCSR ((volatile unsigned int *)(GPTBASE + GTCSR + 0x0300))
#define GPT164_GTCSR ((volatile unsigned int *)(GPTBASE + GTCSR + 0x0400))
#define GPT165_GTCSR ((volatile unsigned int *)(GPTBASE + GTCSR + 0x0500))
#define GPT166_GTCSR ((volatile unsigned int *)(GPTBASE + GTCSR + 0x0600))
#define GPT167_GTCSR ((volatile unsigned int *)(GPTBASE + GTCSR + 0x0700))

#define GTUPSR 0x801C  // General PWM Timer Up Count Source Select Register
#define GPT320_GTUPSR ((volatile unsigned int *)(GPTBASE + GTUPSR))           
#define GPT321_GTUPSR ((volatile unsigned int *)(GPTBASE + GTUPSR + 0x0100))
#define GPT162_GTUPSR ((volatile unsigned int *)(GPTBASE + GTUPSR + 0x0200))
#define GPT163_GTUPSR ((volatile unsigned int *)(GPTBASE + GTUPSR + 0x0300))
#define GPT164_GTUPSR ((volatile unsigned int *)(GPTBASE + GTUPSR + 0x0400))
#define GPT165_GTUPSR ((volatile unsigned int *)(GPTBASE + GTUPSR + 0x0500))
#define GPT166_GTUPSR ((volatile unsigned int *)(GPTBASE + GTUPSR + 0x0600))
#define GPT167_GTUPSR ((volatile unsigned int *)(GPTBASE + GTUPSR + 0x0700))

#define GTDNSR 0x8020  // General PWM Timer Down Count Source Select Register
#define GPT320_GTDNSR ((volatile unsigned int *)(GPTBASE + GTDNSR))           
#define GPT321_GTDNSR ((volatile unsigned int *)(GPTBASE + GTDNSR + 0x0100))
#define GPT162_GTDNSR ((volatile unsigned int *)(GPTBASE + GTDNSR + 0x0200))
#define GPT163_GTDNSR ((volatile unsigned int *)(GPTBASE + GTDNSR + 0x0300))
#define GPT164_GTDNSR ((volatile unsigned int *)(GPTBASE + GTDNSR + 0x0400))
#define GPT165_GTDNSR ((volatile unsigned int *)(GPTBASE + GTDNSR + 0x0500))
#define GPT166_GTDNSR ((volatile unsigned int *)(GPTBASE + GTDNSR + 0x0600))
#define GPT167_GTDNSR ((volatile unsigned int *)(GPTBASE + GTDNSR + 0x0700))

#define GTICASR 0x8024 // General PWM Timer Input Capture Source Select Register A 
#define GTICBSR 0x8028 // General PWM Timer Input Capture Source Select Register B 

#define GTCR 0x802C // General PWM Timer Control Register
#define GPT320_GTCR ((volatile unsigned int *)(GPTBASE + GTCR))           
#define GPT321_GTCR ((volatile unsigned int *)(GPTBASE + GTCR + 0x0100))
#define GPT162_GTCR ((volatile unsigned int *)(GPTBASE + GTCR + 0x0200))
#define GPT163_GTCR ((volatile unsigned int *)(GPTBASE + GTCR + 0x0300))
#define GPT164_GTCR ((volatile unsigned int *)(GPTBASE + GTCR + 0x0400))
#define GPT165_GTCR ((volatile unsigned int *)(GPTBASE + GTCR + 0x0500))
#define GPT166_GTCR ((volatile unsigned int *)(GPTBASE + GTCR + 0x0600))
#define GPT167_GTCR ((volatile unsigned int *)(GPTBASE + GTCR + 0x0700))

#define GTUDDTYC 0x8030 // General PWM Timer Count Direction and Duty Setting Register
#define GPT320_GTUDDTYC ((volatile unsigned int *)(GPTBASE + GTUDDTYC))           
#define GPT321_GTUDDTYC ((volatile unsigned int *)(GPTBASE + GTUDDTYC + 0x0100))
#define GPT162_GTUDDTYC ((volatile unsigned int *)(GPTBASE + GTUDDTYC + 0x0200))
#define GPT163_GTUDDTYC ((volatile unsigned int *)(GPTBASE + GTUDDTYC + 0x0300))
#define GPT164_GTUDDTYC ((volatile unsigned int *)(GPTBASE + GTUDDTYC + 0x0400))
#define GPT165_GTUDDTYC ((volatile unsigned int *)(GPTBASE + GTUDDTYC + 0x0500))
#define GPT166_GTUDDTYC ((volatile unsigned int *)(GPTBASE + GTUDDTYC + 0x0600))
#define GPT167_GTUDDTYC ((volatile unsigned int *)(GPTBASE + GTUDDTYC + 0x0700))

#define GTIOR 0x8034 // General PWM Timer I/O Control Register
#define GPT320_GTIOR ((volatile unsigned int *)(GPTBASE + GTIOR))           
#define GPT321_GTIOR ((volatile unsigned int *)(GPTBASE + GTIOR + 0x0100))
#define GPT162_GTIOR ((volatile unsigned int *)(GPTBASE + GTIOR + 0x0200))
#define GPT163_GTIOR ((volatile unsigned int *)(GPTBASE + GTIOR + 0x0300))
#define GPT164_GTIOR ((volatile unsigned int *)(GPTBASE + GTIOR + 0x0400))
#define GPT165_GTIOR ((volatile unsigned int *)(GPTBASE + GTIOR + 0x0500))
#define GPT166_GTIOR ((volatile unsigned int *)(GPTBASE + GTIOR + 0x0600))
#define GPT167_GTIOR ((volatile unsigned int *)(GPTBASE + GTIOR + 0x0700))

#define GTST 0x803C // General PWM Timer Status Register
#define GPT320_GTST ((volatile unsigned int *)(GPTBASE + GTST))           
#define GPT321_GTST ((volatile unsigned int *)(GPTBASE + GTST + 0x0100))
#define GPT162_GTST ((volatile unsigned int *)(GPTBASE + GTST + 0x0200))
#define GPT163_GTST ((volatile unsigned int *)(GPTBASE + GTST + 0x0300))
#define GPT164_GTST ((volatile unsigned int *)(GPTBASE + GTST + 0x0400))
#define GPT165_GTST ((volatile unsigned int *)(GPTBASE + GTST + 0x0500))
#define GPT166_GTST ((volatile unsigned int *)(GPTBASE + GTST + 0x0600))
#define GPT167_GTST ((volatile unsigned int *)(GPTBASE + GTST + 0x0700))

#define GTBER 0x8040 // General PWM Timer Buffer Enable Register
#define GPT320_GTBER ((volatile unsigned int *)(GPTBASE + GTBER))           
#define GPT321_GTBER ((volatile unsigned int *)(GPTBASE + GTBER + 0x0100))
#define GPT162_GTBER ((volatile unsigned int *)(GPTBASE + GTBER + 0x0200))
#define GPT163_GTBER ((volatile unsigned int *)(GPTBASE + GTBER + 0x0300))
#define GPT164_GTBER ((volatile unsigned int *)(GPTBASE + GTBER + 0x0400))
#define GPT165_GTBER ((volatile unsigned int *)(GPTBASE + GTBER + 0x0500))
#define GPT166_GTBER ((volatile unsigned int *)(GPTBASE + GTBER + 0x0600))
#define GPT167_GTBER ((volatile unsigned int *)(GPTBASE + GTBER + 0x0700))

// Note: GTCNT can only be written to after the counting stops
#define GTCNT 0x8048 // General PWM Timer Counter
#define GPT320_GTCNT ((volatile unsigned int *)(GPTBASE + GTCNT))           
#define GPT321_GTCNT ((volatile unsigned int *)(GPTBASE + GTCNT + 0x0100))
#define GPT162_GTCNT ((volatile unsigned int *)(GPTBASE + GTCNT + 0x0200))
#define GPT163_GTCNT ((volatile unsigned int *)(GPTBASE + GTCNT + 0x0300))
#define GPT164_GTCNT ((volatile unsigned int *)(GPTBASE + GTCNT + 0x0400))
#define GPT165_GTCNT ((volatile unsigned int *)(GPTBASE + GTCNT + 0x0500))
#define GPT166_GTCNT ((volatile unsigned int *)(GPTBASE + GTCNT + 0x0600))
#define GPT167_GTCNT ((volatile unsigned int *)(GPTBASE + GTCNT + 0x0700))

#define GTCCRA 0x804C // General PWM Timer Compare Capture Register A
#define GPT320_GTCCRA ((volatile unsigned int *)(GPTBASE + GTCCRA))           
#define GPT321_GTCCRA ((volatile unsigned int *)(GPTBASE + GTCCRA + 0x0100))
#define GPT162_GTCCRA ((volatile unsigned int *)(GPTBASE + GTCCRA + 0x0200))
#define GPT163_GTCCRA ((volatile unsigned int *)(GPTBASE + GTCCRA + 0x0300))
#define GPT164_GTCCRA ((volatile unsigned int *)(GPTBASE + GTCCRA + 0x0400))
#define GPT165_GTCCRA ((volatile unsigned int *)(GPTBASE + GTCCRA + 0x0500))
#define GPT166_GTCCRA ((volatile unsigned int *)(GPTBASE + GTCCRA + 0x0600))
#define GPT167_GTCCRA ((volatile unsigned int *)(GPTBASE + GTCCRA + 0x0700))

#define GTCCRB 0x8050 // General PWM Timer Compare Capture Register B
#define GPT320_GTCCRB ((volatile unsigned int *)(GPTBASE + GTCCRB))           
#define GPT321_GTCCRB ((volatile unsigned int *)(GPTBASE + GTCCRB + 0x0100))
#define GPT162_GTCCRB ((volatile unsigned int *)(GPTBASE + GTCCRB + 0x0200))
#define GPT163_GTCCRB ((volatile unsigned int *)(GPTBASE + GTCCRB + 0x0300))
#define GPT164_GTCCRB ((volatile unsigned int *)(GPTBASE + GTCCRB + 0x0400))
#define GPT165_GTCCRB ((volatile unsigned int *)(GPTBASE + GTCCRB + 0x0500))
#define GPT166_GTCCRB ((volatile unsigned int *)(GPTBASE + GTCCRB + 0x0600))
#define GPT167_GTCCRB ((volatile unsigned int *)(GPTBASE + GTCCRB + 0x0700))

#define GTCCRC 0x8054 // General PWM Timer Compare Capture Register C
#define GPT320_GTCCRC ((volatile unsigned int *)(GPTBASE + GTCCRC))           
#define GPT321_GTCCRC ((volatile unsigned int *)(GPTBASE + GTCCRC + 0x0100))
#define GPT162_GTCCRC ((volatile unsigned int *)(GPTBASE + GTCCRC + 0x0200))
#define GPT163_GTCCRC ((volatile unsigned int *)(GPTBASE + GTCCRC + 0x0300))
#define GPT164_GTCCRC ((volatile unsigned int *)(GPTBASE + GTCCRC + 0x0400))
#define GPT165_GTCCRC ((volatile unsigned int *)(GPTBASE + GTCCRC + 0x0500))
#define GPT166_GTCCRC ((volatile unsigned int *)(GPTBASE + GTCCRC + 0x0600))
#define GPT167_GTCCRC ((volatile unsigned int *)(GPTBASE + GTCCRC + 0x0700))

//#define GTCCRD 0x805C // General PWM Timer Compare Capture Register D  - See page 425 22.2.19
#define GTCCRD 0x8058 // General PWM Timer Compare Capture Register D
#define GPT320_GTCCRD ((volatile unsigned int *)(GPTBASE + GTCCRD))           
#define GPT321_GTCCRD ((volatile unsigned int *)(GPTBASE + GTCCRD + 0x0100))
#define GPT162_GTCCRD ((volatile unsigned int *)(GPTBASE + GTCCRD + 0x0200))
#define GPT163_GTCCRD ((volatile unsigned int *)(GPTBASE + GTCCRD + 0x0300))
#define GPT164_GTCCRD ((volatile unsigned int *)(GPTBASE + GTCCRD + 0x0400))
#define GPT165_GTCCRD ((volatile unsigned int *)(GPTBASE + GTCCRD + 0x0500))
#define GPT166_GTCCRD ((volatile unsigned int *)(GPTBASE + GTCCRD + 0x0600))
#define GPT167_GTCCRD ((volatile unsigned int *)(GPTBASE + GTCCRD + 0x0700))

//#define GTCCRE 0x8058 // General PWM Timer Compare Capture Register E  - As above...
#define GTCCRE 0x805C // General PWM Timer Compare Capture Register E
#define GPT320_GTCCRE ((volatile unsigned int *)(GPTBASE + GTCCRE))           
#define GPT321_GTCCRE ((volatile unsigned int *)(GPTBASE + GTCCRE + 0x0100))
#define GPT162_GTCCRE ((volatile unsigned int *)(GPTBASE + GTCCRE + 0x0200))
#define GPT163_GTCCRE ((volatile unsigned int *)(GPTBASE + GTCCRE + 0x0300))
#define GPT164_GTCCRE ((volatile unsigned int *)(GPTBASE + GTCCRE + 0x0400))
#define GPT165_GTCCRE ((volatile unsigned int *)(GPTBASE + GTCCRE + 0x0500))
#define GPT166_GTCCRE ((volatile unsigned int *)(GPTBASE + GTCCRE + 0x0600))
#define GPT167_GTCCRE ((volatile unsigned int *)(GPTBASE + GTCCRE + 0x0700))

#define GTCCRF 0x8060 // General PWM Timer Compare Capture Register F
#define GPT320_GTCCRF ((volatile unsigned int *)(GPTBASE + GTCCRF))           
#define GPT321_GTCCRF ((volatile unsigned int *)(GPTBASE + GTCCRF + 0x0100))
#define GPT162_GTCCRF ((volatile unsigned int *)(GPTBASE + GTCCRF + 0x0200))
#define GPT163_GTCCRF ((volatile unsigned int *)(GPTBASE + GTCCRF + 0x0300))
#define GPT164_GTCCRF ((volatile unsigned int *)(GPTBASE + GTCCRF + 0x0400))
#define GPT165_GTCCRF ((volatile unsigned int *)(GPTBASE + GTCCRF + 0x0500))
#define GPT166_GTCCRF ((volatile unsigned int *)(GPTBASE + GTCCRF + 0x0600))
#define GPT167_GTCCRF ((volatile unsigned int *)(GPTBASE + GTCCRF + 0x0700))

#define GTPR 0x8064 // General PWM Timer Cycle Setting Register
#define GPT320_GTPR ((volatile unsigned int *)(GPTBASE + GTPR))           
#define GPT321_GTPR ((volatile unsigned int *)(GPTBASE + GTPR + 0x0100))
#define GPT162_GTPR ((volatile unsigned int *)(GPTBASE + GTPR + 0x0200))
#define GPT163_GTPR ((volatile unsigned int *)(GPTBASE + GTPR + 0x0300))
#define GPT164_GTPR ((volatile unsigned int *)(GPTBASE + GTPR + 0x0400))
#define GPT165_GTPR ((volatile unsigned int *)(GPTBASE + GTPR + 0x0500))
#define GPT166_GTPR ((volatile unsigned int *)(GPTBASE + GTPR + 0x0600))
#define GPT167_GTPR ((volatile unsigned int *)(GPTBASE + GTPR + 0x0700))

#define GTPBR 0x8068 // General PWM Timer Cycle Setting Buffer Register
#define GPT320_GTPBR ((volatile unsigned int *)(GPTBASE + GTPBR))           
#define GPT321_GTPBR ((volatile unsigned int *)(GPTBASE + GTPBR + 0x0100))
#define GPT162_GTPBR ((volatile unsigned int *)(GPTBASE + GTPBR + 0x0200))
#define GPT163_GTPBR ((volatile unsigned int *)(GPTBASE + GTPBR + 0x0300))
#define GPT164_GTPBR ((volatile unsigned int *)(GPTBASE + GTPBR + 0x0400))
#define GPT165_GTPBR ((volatile unsigned int *)(GPTBASE + GTPBR + 0x0500))
#define GPT166_GTPBR ((volatile unsigned int *)(GPTBASE + GTPBR + 0x0600))
#define GPT167_GTPBR ((volatile unsigned int *)(GPTBASE + GTPBR + 0x0700))

// ==== NVIC Interrupt Controller ====
#define NVICBASE 0xE0000000 // NVIC Interrupt Controller

// asm volatile("dsb"); // <<<< use a DSB instruction to ensure bus-synchronisition for NVIC write operations

#define NVIC_ICTR    ((volatile unsigned int  *)(NVICBASE + 0xE004))              // Interrupt Controller Type Register
// Total number of interrupt lines in groups of 32: [3:0]	INTLINESNUM
// b0000 = 0...32   << RA4M1 returns 0 - Has only 32 Interrupts - See Table 13.3 Interrupt vector table p.237
// b0001 = 33...64
// b0010 = 65...96
// b0011 = 97...128
// b0100 = 129...160
// b0101 = 161...192
// b0110 = 193...224
// b0111 = 225...256


// NVIC IRQ registers - Generic ARM Cortex-M4F; not all are necessiraly present in the RA4M1
// x = 0..7 for each register type, with 32 bits per register, to support up to 240 IRQs
// * Each bit controls one interrupt, identified by its IRQ# (0..239)
// * Register# x = IRQ# DIV 32
// * Bit n in the register = IRQ# MOD 32

#define NVICISER 0xE100     // Interrupt Set-Enable Registers
#define NVIC_ISER0  ((volatile unsigned int  *)(NVICBASE + NVICISER +(0 * 4)))     // Register 0
#define NVIC_ISER1  ((volatile unsigned int  *)(NVICBASE + NVICISER +(1 * 4)))     // Register 1
#define NVIC_ISER2  ((volatile unsigned int  *)(NVICBASE + NVICISER +(2 * 4)))     // Register 2
#define NVIC_ISER3  ((volatile unsigned int  *)(NVICBASE + NVICISER +(3 * 4)))     // Register 3
#define NVIC_ISER4  ((volatile unsigned int  *)(NVICBASE + NVICISER +(4 * 4)))     // Register 4
#define NVIC_ISER5  ((volatile unsigned int  *)(NVICBASE + NVICISER +(5 * 4)))     // Register 5
#define NVIC_ISER6  ((volatile unsigned int  *)(NVICBASE + NVICISER +(6 * 4)))     // Register 6
#define NVIC_ISER7  ((volatile unsigned int  *)(NVICBASE + NVICISER +(7 * 4)))     // Register 7
#define NVICICER 0xE180     // Interrupt Clear-Enable Registers
#define NVIC_ICER0  ((volatile unsigned int  *)(NVICBASE + NVICICER +(0 * 4)))     // Register 0
#define NVIC_ICER1  ((volatile unsigned int  *)(NVICBASE + NVICICER +(1 * 4)))     // Register 1
#define NVIC_ICER2  ((volatile unsigned int  *)(NVICBASE + NVICICER +(2 * 4)))     // Register 2
#define NVIC_ICER3  ((volatile unsigned int  *)(NVICBASE + NVICICER +(3 * 4)))     // Register 3
#define NVIC_ICER4  ((volatile unsigned int  *)(NVICBASE + NVICICER +(4 * 4)))     // Register 4
#define NVIC_ICER5  ((volatile unsigned int  *)(NVICBASE + NVICICER +(5 * 4)))     // Register 5
#define NVIC_ICER6  ((volatile unsigned int  *)(NVICBASE + NVICICER +(6 * 4)))     // Register 6
#define NVIC_ICER7  ((volatile unsigned int  *)(NVICBASE + NVICICER +(7 * 4)))     // Register 7

#define NVICISPR 0xE200     // Interrupt Set-Pending Registers
#define NVIC_ISPR0  ((volatile unsigned int  *)(NVICBASE + NVICISPR +(0 * 4)))     // Register 0
#define NVIC_ISPR1  ((volatile unsigned int  *)(NVICBASE + NVICISPR +(1 * 4)))     // Register 1
#define NVIC_ISPR2  ((volatile unsigned int  *)(NVICBASE + NVICISPR +(2 * 4)))     // Register 2
#define NVIC_ISPR3  ((volatile unsigned int  *)(NVICBASE + NVICISPR +(3 * 4)))     // Register 3
#define NVIC_ISPR4  ((volatile unsigned int  *)(NVICBASE + NVICISPR +(4 * 4)))     // Register 4
#define NVIC_ISPR5  ((volatile unsigned int  *)(NVICBASE + NVICISPR +(5 * 4)))     // Register 5
#define NVIC_ISPR6  ((volatile unsigned int  *)(NVICBASE + NVICISPR +(6 * 4)))     // Register 6
#define NVIC_ISPR7  ((volatile unsigned int  *)(NVICBASE + NVICISPR +(7 * 4)))     // Register 7
#define NVICICPR 0xE280     // Interrupt Clear-Pending Registers
#define NVIC_ICPR0  ((volatile unsigned int  *)(NVICBASE + NVICICPR +(0 * 4)))     // Register 0
#define NVIC_ICPR1  ((volatile unsigned int  *)(NVICBASE + NVICICPR +(1 * 4)))     // Register 1
#define NVIC_ICPR2  ((volatile unsigned int  *)(NVICBASE + NVICICPR +(2 * 4)))     // Register 2
#define NVIC_ICPR3  ((volatile unsigned int  *)(NVICBASE + NVICICPR +(3 * 4)))     // Register 3
#define NVIC_ICPR4  ((volatile unsigned int  *)(NVICBASE + NVICICPR +(4 * 4)))     // Register 4
#define NVIC_ICPR5  ((volatile unsigned int  *)(NVICBASE + NVICICPR +(5 * 4)))     // Register 5
#define NVIC_ICPR6  ((volatile unsigned int  *)(NVICBASE + NVICICPR +(6 * 4)))     // Register 6
#define NVIC_ICPR7  ((volatile unsigned int  *)(NVICBASE + NVICICPR +(7 * 4)))     // Register 7

#define NVICIABR 0xE300     // Interrupt Active Bit Register - Read Only: Read 1 if interrupt in active state
#define NVIC_IABR0  ((volatile unsigned int  *)(NVICBASE + NVICIABR +(0 * 4)))     // Register 0
#define NVIC_IABR1  ((volatile unsigned int  *)(NVICBASE + NVICIABR +(1 * 4)))     // Register 1
#define NVIC_IABR2  ((volatile unsigned int  *)(NVICBASE + NVICIABR +(2 * 4)))     // Register 2
#define NVIC_IABR3  ((volatile unsigned int  *)(NVICBASE + NVICIABR +(3 * 4)))     // Register 3
#define NVIC_IABR4  ((volatile unsigned int  *)(NVICBASE + NVICIABR +(4 * 4)))     // Register 4
#define NVIC_IABR5  ((volatile unsigned int  *)(NVICBASE + NVICIABR +(5 * 4)))     // Register 5
#define NVIC_IABR6  ((volatile unsigned int  *)(NVICBASE + NVICIABR +(6 * 4)))     // Register 6
#define NVIC_IABR7  ((volatile unsigned int  *)(NVICBASE + NVICIABR +(7 * 4)))     // Register 7

// NVIC_IPRx (x=0..59) – Interrupt Priority Registers
// * Supports up to 240 interrupts: 0..239 (32 in RA4M1)
// *  8-bit priority field for each interrupts (4-bit field for RA4M1)
// *  4 priority values per register (MSB aligned bits of each byte for prioity i.e. 0x10 thru 0xF0)
// *  0 = highest priority, F = lowest priority (USBs are all at 0xC0, mS Timer on AGT is 0xE0)
// *  Register# x = IRQ# DIV 4
// *  Byte offset within the register = IRQ# MOD 4
// *  Ex. IRQ85:
// *  85/4 = 21 with remainder 1 (register 21, byte offset 1): Write priority<<8 to NVIC_IPR2
// *  85/32 = 2 with remainder 21: write 1<<21 to NVIC_SER2


#define NVICIPR  0xE400     // Interrupt Priority Register
#define NVIC_IPR00  ((volatile unsigned int  *)(NVICBASE + NVICIPR +(0 * 4)))     // Register 0: NVIC_IPR0 TO 3
#define NVIC_IPR04  ((volatile unsigned int  *)(NVICBASE + NVICIPR +(1 * 4)))     // Register 1
#define NVIC_IPR08  ((volatile unsigned int  *)(NVICBASE + NVICIPR +(2 * 4)))     // Register 2
#define NVIC_IPR12  ((volatile unsigned int  *)(NVICBASE + NVICIPR +(3 * 4)))     // Register 3
#define NVIC_IPR16  ((volatile unsigned int  *)(NVICBASE + NVICIPR +(4 * 4)))     // Register 4
#define NVIC_IPR20  ((volatile unsigned int  *)(NVICBASE + NVICIPR +(5 * 4)))     // Register 5
#define NVIC_IPR24  ((volatile unsigned int  *)(NVICBASE + NVICIPR +(6 * 4)))     // Register 6
#define NVIC_IPR28  ((volatile unsigned int  *)(NVICBASE + NVICIPR +(7 * 4)))     // Register 7

// Also byte accessible:
#define NVIC_IPR00_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  0 ))     // For direct byte access
#define NVIC_IPR01_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  1 ))     // For direct byte access
#define NVIC_IPR02_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  2 ))     // For direct byte access
#define NVIC_IPR03_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  3 ))     // For direct byte access
#define NVIC_IPR04_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  4 ))     // For direct byte access
#define NVIC_IPR05_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  5 ))     // For direct byte access
#define NVIC_IPR06_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  6 ))     // For direct byte access
#define NVIC_IPR07_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  7 ))     // For direct byte access
#define NVIC_IPR08_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  8 ))     // For direct byte access
#define NVIC_IPR09_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR +  9 ))     // For direct byte access
#define NVIC_IPR10_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 10 ))     // For direct byte access
#define NVIC_IPR11_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 11 ))     // For direct byte access
#define NVIC_IPR12_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 12 ))     // For direct byte access
#define NVIC_IPR13_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 13 ))     // For direct byte access
#define NVIC_IPR14_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 14 ))     // For direct byte access
#define NVIC_IPR15_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 15 ))     // For direct byte access
#define NVIC_IPR16_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 16 ))     // For direct byte access
#define NVIC_IPR17_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 17 ))     // For direct byte access
#define NVIC_IPR18_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 18 ))     // For direct byte access
#define NVIC_IPR19_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 19 ))     // For direct byte access
#define NVIC_IPR20_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 20 ))     // For direct byte access
#define NVIC_IPR21_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 21 ))     // For direct byte access
#define NVIC_IPR22_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 22 ))     // For direct byte access
#define NVIC_IPR23_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 23 ))     // For direct byte access
#define NVIC_IPR24_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 24 ))     // For direct byte access
#define NVIC_IPR25_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 25 ))     // For direct byte access
#define NVIC_IPR26_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 26 ))     // For direct byte access
#define NVIC_IPR27_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 27 ))     // For direct byte access
#define NVIC_IPR28_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 28 ))     // For direct byte access
#define NVIC_IPR29_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 29 ))     // For direct byte access
#define NVIC_IPR30_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 30 ))     // For direct byte access
#define NVIC_IPR31_BY  ((volatile unsigned char  *)(NVICBASE + NVICIPR + 31 ))     // For direct byte access




// === Local Defines

// #define ADC_EXT_AREF         // Use external ADC Aref source
// #define ADC_AVARAGE          // Enable 4x averaging i.e. four sucessive conversions
#define ADSSTR00               // Enable Sampling State Register change from default
#define ADSSTR00_VAL 0x08      // A/D Sampling State Register 0 - Default is 0x0D


// ==== Global Variables ====

static bool wake_from_int_flag = false;

static uint16_t adc_val_A1;
static uint16_t adc_val_A2;


void setup()
  {
  attachInterrupt(13, timer7interrupt, FALLING);        // This IRQ will be asigned to Slot 05 IELSR05 as 0x001 PORT_IRQ0 - Table 13.4
  *ICU_IELSR05 = IRQ_GPT7_OVF;                          // Assign Slot 05 IELSR05 for GPT7_OVF
  *PFS_P111PFS = 0x00000000;                            // Clear D13 ISEL pin assigned Interrupt Enable
	asm volatile("dsb");                                  // Data bus Synchronization instruction
  *NVIC_IPR05_BY = 0x40;                                // Bounce ICU_IELSR05 irq priority up from 0xC0 to 0x40

  Serial.begin(115200);
//  while (!Serial){};

  setup_adc();
  setup_dac();

  *ADC140_ADCSR   |= (0x01 << 15);   // Start an ADC conversion
  delayMicroseconds(10);
  *AGT0_AGTCR = 0;                     // disable Millis counter, delay etc. don't want this Interrupt messing up output stability

// Setup fast IRQ timers ABSOLUTLY last!!!  
  setup_timer_7();
  }


void loop()
  {
  *PFS_P111PFS_BY = 0x04;        // D13 - CLEAR LED
  if(wake_from_int_flag == true)
    asm volatile("wfi");           // Stop here and wait for an interrupt
  *PFS_P111PFS_BY = 0x05;        // D13 - Set LED

  if(Serial.available() > 0)
    {
    char input_char = Serial.read();  // get one byte from serial buffer
    Serial.println(input_char);
    switch(input_char)
      {
      case 's':
        {
        Serial.println("\nEnable Wake from Interrupt");
        wake_from_int_flag = true; 
        break;
        }
      case 'r':
        {
        Serial.println("\nDisable Wake from Interrupt");
        wake_from_int_flag = false;       // Disable WFI, otherwsie double tap on Reset-Button needed
        break;
        }
      case '?':
        {
        serial_commands();
        break;
        }
      default:
        break;
      }
    }

  }

void serial_commands(void)
  {
  Serial.println("\nGPT Timer Setup");
  Serial.println("s = Enable Wake from Interrupt");
  Serial.println("r = Disable Wake from Interrupt");
  Serial.println("? = This Help List");
  }


void timer7interrupt(void)
  {
//  static uint16_t localValA0 = 0;  // Board input ADC A0 used for DAC output
  static uint16_t localValA1 = 0;  // Board input ADC A1
  static uint16_t localValA2 = 0;  // Board input ADC A2
  static uint16_t localCount = 0;
  static uint8_t test = 0;

  *PFS_P107PFS_BY = 0x05;         // D7 start of Timer Interrupt

// ==== ADC ====

  adc_val_A1 = *ADC140_ADDR00;    //  
  adc_val_A2 = *ADC140_ADDR01;    //  
  *ADC140_ADCSR |= (0x01 << 15);  // Next ADC conversion = c. 300nS

// ==== DAC Monitor ====

          int32_t out, a , b;
          int32_t result_taylor_sine;
   static int32_t sine_amp_local = 0x7FFFFFFF;
  static uint32_t freq_time_accumulate = 0;
//  static uint32_t freq_time_delta = 0x1 << 24;  //  
  static uint32_t freq_time_delta = 0x1 << 18;  // This value gives 
          int16_t result_sine;

  int32_t angle, sum, p1, p2, p3, p5, p7, p9, p11, term; 
  uint32_t ph;
  uint16_t analog_read_value;
  uint16_t analog_write_value;

  *PFS_P103PFS_BY = 0x05;      // Pulse on D4 to trigger scope 
  *PFS_P103PFS_BY = 0x04;      // Each Port Output bit clear or set takes c. 83nS 

//  *PFS_P107PFS_BY = 0x05;      //  
  analog_read_value = *ADC140_ADDR00;    // adcValue = analogRead(analogPin); // Internal 16bit register read = c. 123nS 
  *ADC140_ADCSR |= (0x01 << 15);  // Next ADC conversion = write to register c. 300nS
//  *PFS_P107PFS_BY = 0x04;      //  

#ifdef ADC_RIGHT_JUST
  freq_time_accumulate += (uint32_t)analog_read_value << 11;   // Core DDS frequency-synthesis incriment
#else
  freq_time_accumulate += (uint32_t)analog_read_value << 9;   // Core DDS frequency-synthesis incriment
#endif

  if (freq_time_accumulate >= 0xC0000000u || freq_time_accumulate < 0x40000000u)
    {
    angle = (int32_t)freq_time_accumulate; // valid from -90 to +90 degrees
    } 
  else
    {
    angle = (int32_t)(0x7FFFFFFFu - freq_time_accumulate);
    }
  term = angle << 1;
	asm volatile("smmulr %0, %1, %2" : "=r" (p1) : "r" (term), "r" (1686629713));
	asm volatile("smmulr %0, %1, %2" : "=r" (term) : "r" (p1), "r" (p1));
  p2 = term << 3;
	asm volatile("smmulr %0, %1, %2" : "=r" (term) : "r" (p2), "r" (p1));
  p3 = term << 3;
  term = p1 << 1;
	asm volatile("smmlsr %0, %2, %3, %1" : "=r" (sum) : "r" (term), "r" (p3), "r" (1431655765));
	asm volatile("smmulr %0, %1, %2" : "=r" (term) : "r" (p3), "r" (p2));
  p5 = term << 1;
	asm volatile("smmlar %0, %2, %3, %1" : "=r" (sum) : "r" (sum), "r" (p5), "r" (286331153));
	asm volatile("smmulr %0, %1, %2" : "=r" (p7) : "r" (p5), "r" (p2));
	asm volatile("smmlsr %0, %2, %3, %1" : "=r" (sum) : "r" (sum), "r" (p7), "r" (54539267));
/*  
// Uncommet this for 25bit precision calculation
	asm volatile("smmulr %0, %1, %2" : "=r" (p9) : "r" (p7), "r" (p2));
	asm volatile("smmlar %0, %2, %3, %1" : "=r" (sum) : "r" (sum), "r" (p9), "r" (6059919));
	asm volatile("smmulr %0, %1, %2" : "=r" (p11) : "r" (p9), "r" (p2));
	asm volatile("smmlsr %0, %2, %3, %1" : "=r" (sum) : "r" (sum), "r" (p11), "r" (440721));
*/

  result_taylor_sine = sum << 1;   

//	asm volatile("smmulr %0, %1, %2" : "=r" (out) : "r" (result_taylor_sine), "r" (sine_amp_local));
//  result_sine = (int16_t)(out >> 19);

#ifdef DAC_RIGHT_JUST
  result_sine = (int16_t)(result_taylor_sine >> 20);   // 32 - 12 = 20
  *DAC12_DADR0 = result_sine + 2048;
#else
  result_sine = (int16_t)(result_taylor_sine >> 16);   // 
  *DAC12_DADR0 = result_sine + 32767;
#endif
  *PFS_P107PFS_BY = 0x04;         // D7 end of Timer Interrupt

  }


void setup_adc(void)
  {
  *MSTP_MSTPCRD &= (0xFFFFFFFF - (0x01 << MSTPD16));  // Enable ADC140 module
#ifdef ADC_EXT_AREF
  *ADC140_ADHVREFCNT = 0x01;         // Set External Aref = analogReference(AR_EXTERNAL);      
#endif
#ifdef ADC_RIGHT_JUST
  *ADC140_ADCER = 0x06;              // 14 bit mode, right justified
#else
  *ADC140_ADCER = 0x8006;            // 14 bit mode, left-justified
//  *ADC140_ADCER = 0x8000;            // 12 bit mode, left-justified
#endif
  *ADC140_ADANSA0 |= (0x01 << 0);    // Selected ANSA00 = A1 as DAC is on A0
#ifdef ADC_AVARAGE
  *ADC140_ADADC    = 0x83;           // Average mode - 4x and b7 to enable averaging
  *ADC140_ADADS0  |= (0x01 << 0);    // Enable Averaging for ANSA00 channel
#endif
#ifdef ADSSTR00
  *ADC140_ADSSTR00 = ADSSTR00_VAL;   // A/D Sampling State Register 0 - Default is 0x0D
#endif
  }

void setup_dac(void)       // Note make sure ADC is stopped before setup DAC
  {
  *MSTP_MSTPCRD &= (0xFFFFFFFF - (0x01 << MSTPD20));  // Enable DAC12 module
#ifdef DAC_RIGHT_JUST
  *DAC12_DADPR    = 0x00;        // DADR0 Format Select Register - Set right-justified format
#else
  *DAC12_DADPR    = 0x80;        // DADR0 Format Select Register - Set left-justified format i.e. 16 bit format, 4 LSBs not used
#endif
//  *DAC12_DAADSCR  = 0x80;        // D/A A/D Synchronous Start Control Register - Enable
  *DAC12_DAADSCR  = 0x00;        // D/A A/D Synchronous Start Control Register - Default
// 36.3.2 Notes on Using the Internal Reference Voltage as the Reference Voltage
  *DAC12_DAVREFCR = 0x00;        // D/A VREF Control Register - Write 0x00 first - see 36.2.5
  *DAC12_DADR0    = 0x0000;      // D/A Data Register 0 
   delayMicroseconds(10);        
  *DAC12_DAVREFCR = 0x01;        // D/A VREF Control Register - Select AVCC0/AVSS0 for Vref
//  *DAC12_DAVREFCR = 0x03;        // D/A VREF Control Register - Select Internal reference voltage/AVSS0
//  *DAC12_DAVREFCR = 0x06;        // D/A VREF Control Register - Select External Vref; set VREFH&L pins used for LEDs
  *DAC12_DACR     = 0x5F;        // D/A Control Register - 
   delayMicroseconds(5);         // 
#ifdef DAC_RIGHT_JUST
  *DAC12_DADR0    = 0x0800;      // Set D/A Data Register to Midrange "Zero" Value 
#else
  *DAC12_DADR0    = 0x8000;      // Set D/A Data Register to Midrange "Zero" Value 
#endif
  *PFS_P014PFS   = 0x00000000;   // Make sure all cleared
  *PFS_P014PFS  |= (0x1 << 15);  // Port Mode Control - Used as an analog pin
  }

// ==== GPT - General Purpose Timers ==== //

void setup_timer_7(void)
  {
  *MSTP_MSTPCRD &= (0xFFFFFFFF - (0x01 << MSTPD6));  // Enable GTP16 timer module
                //   76543210
  *GPT167_GTSTP  = 0b10000000; // Stop Timer 7  - Doesn't matter which timer is addressed

// Timer 7 - Sawtooth Mode 
  *GPT167_GTSSR = 0x80000000; // b31 CSTRT Software Source Counter Start Enable
  *GPT167_GTPSR = 0x80000000; // b31 CSTOP Software Source Counter Stop Enable
  *GPT167_GTCSR = 0x80000000; // b31 CCLR  Software Source Counter Clear Enable

  *GPT167_GTUDDTYC = 0x1;
  *GPT167_GTCNT  = 0x0000;     // Set Counter value
  *GPT167_GTCCRA = 0x0000;     // 
  *GPT167_GTCCRB = 0x0000;     // 
  *GPT167_GTCCRC = 0x0000;     // 
  *GPT167_GTCCRD = 0x0000;     // 
  *GPT167_GTPR   = 0x043F;     // 
  *GPT167_GTPBR  = 0x043F;     // 
  *GPT167_GTBER  = 0x00150000; // PR, CCRB, and CCRA set to single buffer operation 

// b26-b24 - b26 to b24 TPCS[2:0] Timer Prescaler Select
//  0 0 0: PCLKD/1 
//  0 0 1: PCLKD/4
//  0 1 0: PCLKD/16
//  0 1 1: PCLKD/64
//  1 0 0: PCLKD/256
//  1 0 1: PCLKD/1024.
  *GPT167_GTCR   = 0x0;           // Set Sawtooth mode, PreScale to PCLKD/1 = 1465Hz with Counter set to 0x7FFF
#ifdef PRE_SCALE_DIV64
  *GPT167_GTCR   = 0b011 << 24;   // Set PreScale to PCLKD/64 = 22.89Hz with Counter set to 0x7FFF
#endif

/* Not currently using PWM outputs
// RA4M1 Data-Sheet - 22.2.14 General PWM Timer I/O Control Register (GTIOR)
//                  - Table 22.5 Settings of GTIOA[4:0] and GTIOB[4:0] bits
  *GPT167_GTIOR  = 0x00000000;   // Clear I/O Control Register
//  *GPT167_GTIOR |=  0b01001       ; // GTIOA[4:0] = 01001b - Initial output is low; Low Output at GTCCRA compare match; HIGH at end
//  *GPT167_GTIOR |= (0b01001 << 16); // GTIOB[4:0] = 01001b - Initial output is low; Low Output at GTCCRB compare match; HIGH at end
  *GPT167_GTIOR |=  0b00110       ; // GTIOA[4:0] = 01001b - Initial output is low; High Output at GTCCRA compare match; LOW at end
  *GPT167_GTIOR |= (0b00110 << 16); // GTIOB[4:0] = 01001b - Initial output is low; High Output at GTCCRB compare match; LOW at end
  *GPT167_GTIOR |= 0x01000100; // Set OBE and OAE bits 

  *PFS_P304PFS   = (0b00011 << 24);  // Select PSEL[4:0] for GTIOC7A - See Table 19.10
  *PFS_P304PFS  |= (0x1 << 16);      // Port Mode Control - Used as an I/O port for peripheral function
  *PFS_P303PFS   = (0b00011 << 24);  // Select PSEL[4:0] for GTIOC7B - See Table 19.10
  *PFS_P303PFS  |= (0x1 << 16);      // Port Mode Control - Used as an I/O port for peripheral function
*/

  *GPT167_GTSTR  = 0b10000000;  // Start Timer 7 - Doesn't matter which timer is addressed
  *GPT167_GTCR   |= 0x1;        // Start Timer 7 with a PreScale of zero
//  *GPT167_GTCLR  = 0b10000000;  // Clear Timer 7 - use to clear multipl times to align counts, not needed for single timer
  }

Add a 10k load to DAC output make the spike even worse. analogWrite does not work well on such tasks. Direct write to the registers works for me.

#define DACBASE 0x40050000          // DAC Base - DAC output on A0 (P014 AN09 DAC)
#define DAC12_DADR0    ((volatile unsigned short *)(DACBASE + 0xE000)) 
...
*DAC12_DADR0 = sineTable[index]);
...