@rtel Thank you for your reply. I have asked Microchip and at least two of their people are looking at this issue. One of them encouraged me to ask for help at FreeRTOS, since they knew more about the integration than Microchip did!
Interrupt handlers in Harmony 3, at least the part I am expected to code, look very different than those of the past. Most interrupt processing now takes place “under the hood” it seems. In fact the Interrupt handler for the UART is not my code at all, Harmony creates it. Anyway here they are:
In the case of the CN pin, the only part I need to create is a read-back routine, and then register it. Here is the code for the callback:
uintptr_t cn7_context;
int cn_registration_success;
void callback_fn( CN_PIN pin, uintptr_t cn7_context ) {
GPIO_PinToggle(GPIO_PIN_RD0); // on-board RED led
}
Here is the code to register and enable interrupts on the pin:
cn7_context = 0;
cn_registration_success = GPIO_PinInterruptCallbackRegister( CN7_PIN, callback_fn, cn7_context);
GPIO_PinInterruptEnable(CN7_PIN);
This is the code (created by Harmony 3 I am guessing) that calls my read-back routine:
/* Function:
void CHANGE_NOTICE_InterruptHandler()
Summary:
Interrupt Handler for change notice interrupt.
Remarks:
It is an internal function called from ISR, user should not call it directly.
*/
void CHANGE_NOTICE_InterruptHandler()
{
uint8_t i, bitPosition;
uint32_t latestPortValue, mask;
bool currPinValue;
/* Check which CN interrupt has occurred and call callback if registered */
for(i = 0; i < TOTAL_NUM_OF_INT_USED; i++)
{
latestPortValue = *(volatile uint32_t *)(&PORTA + ((cnPinObj[i].gpioPin >> 4) * 0x10));
bitPosition = cnPinObj[i].gpioPin % 16;
mask = 1 << bitPosition;
currPinValue = (bool)((latestPortValue & mask) >> bitPosition);
if((cnPinObj[i].prevPinValue != currPinValue) && (cnPinObj[i].callback != NULL))
{
cnPinObj[i].prevPinValue = currPinValue;
cnPinObj[i].callback (cnPinObj[i].cnPin, cnPinObj[i].context);
}
}
IFS1CLR = _IFS1_CNIF_MASK;
}
Here is the code (Harmony 3 created probably) for the UART interrupts:
void UART_2_InterruptHandler (void)
{
/* Call RX handler if RX interrupt flag is set */
if ((IFS1 & _IFS1_U2RXIF_MASK) && (IEC1 & _IEC1_U2RXIE_MASK))
{
UART2_RX_InterruptHandler();
}
/* Call TX handler if TX interrupt flag is set */
else if ((IFS1 & _IFS1_U2TXIF_MASK) && (IEC1 & _IEC1_U2TXIE_MASK))
{
UART2_TX_InterruptHandler();
}
/* Call Error handler if Error interrupt flag is set */
else if ((IFS1 & _IFS1_U2EIF_MASK) && (IEC1 & _IEC1_U2EIE_MASK))
{
UART2_FAULT_InterruptHandler();
}
}
In the case of a TX interrupt (the only type I am using right now) is here (again this is not code I wrote myself. Like most above, it was created by Microchip tools.
static void UART2_TX_InterruptHandler (void)
{
if(uart2Obj.txBusyStatus == true)
{
while((!(U2STA & _U2STA_UTXBF_MASK)) && (uart2Obj.txSize > uart2Obj.txProcessedSize) )
{
U2TXREG = uart2Obj.txBuffer[uart2Obj.txProcessedSize++];
}
/* Clear UART2TX Interrupt flag after writing to buffer */
IFS1CLR = _IFS1_U2TXIF_MASK;
/* Check if the buffer is done */
if(uart2Obj.txProcessedSize >= uart2Obj.txSize)
{
uart2Obj.txBusyStatus = false;
/* Disable the transmit interrupt, to avoid calling ISR continuously */
IEC1CLR = _IEC1_U2TXIE_MASK;
if(uart2Obj.txCallback != NULL)
{
uart2Obj.txCallback(uart2Obj.txContext);
}
}
}
else
{
// Nothing to process ;
}
}
There is a file called interrupts.c, which is of little help either:
void CHANGE_NOTICE_InterruptHandler( void );
void UART_2_InterruptHandler( void );
/* All the handlers are defined here. Each will call its PLIB-specific function. */
void CHANGE_NOTICE_Handler (void)
{
CHANGE_NOTICE_InterruptHandler();
}
void UART_2_Handler (void)
{
UART_2_InterruptHandler();
}
---------------------------------------
and there is another, called interrupts_a.S shown here:
#include <xc.h>
#include "ISR_Support.h"
.extern CHANGE_NOTICE_Handler
.section .vector_26,code, keep
.equ __vector_dispatch_26, IntVectorCHANGE_NOTICE_Handler
.global __vector_dispatch_26
.set nomicromips
.set noreorder
.set nomips16
.set noat
.ent IntVectorCHANGE_NOTICE_Handler
IntVectorCHANGE_NOTICE_Handler:
la $26, _CHANGE_NOTICE_Handler
jr $26
nop
.end IntVectorCHANGE_NOTICE_Handler
.section .CHANGE_NOTICE_Handler_vector_text, code, keep
.set nomicromips
.set noreorder
.set nomips16
.set noat
.ent _CHANGE_NOTICE_Handler
_CHANGE_NOTICE_Handler:
portSAVE_CONTEXT
la s6, CHANGE_NOTICE_Handler
jalr s6
nop
portRESTORE_CONTEXT
.end _CHANGE_NOTICE_Handler
.extern UART_2_Handler
.section .vector_32,code, keep
.equ __vector_dispatch_32, IntVectorUART_2_Handler
.global __vector_dispatch_32
.set nomicromips
.set noreorder
.set nomips16
.set noat
.ent IntVectorUART_2_Handler
IntVectorUART_2_Handler:
la $26, _UART_2_Handler
jr $26
nop
.end IntVectorUART_2_Handler
.section .UART_2_Handler_vector_text, code, keep
.set nomicromips
.set noreorder
.set nomips16
.set noat
.ent _UART_2_Handler
_UART_2_Handler:
portSAVE_CONTEXT
la s6, UART_2_Handler
jalr s6
nop
portRESTORE_CONTEXT
.end _UART_2_Handler