The SFRBIT macro can only be used with SFRs with an address that is a multiple of 8. You should use the definitions provided by cc2511_map.h to access PICTL and P0IFG. If you continue to have trouble, please post a description of how you are testing the code along with the expected behavior and the actual behavior.
The SFRBIT macro is not documented at all because it is not intended to be used outside of cc2511_map.h. That macro uses the __sbit keyword. The documentation of __sbit in the SDCC Manual (version 3.4.1, section 3.5.1.7) says:
Since you are enabling interrupts on four pins (P0_0, P0_1, P0_2, and P0_3), you probably need to clear the P0IFG flags for all of those pins in your ISR or else you risk getting stuck in the ISR forever. After clearing those, it looks like you need to clear IRCON.P0IF. During initialization, you should write “EA = 1;” to explicitly enable interrupts instead of depending on the Wixel libraries to do it for you. The P0_0_interrupt variable should be volatile. There might be more issues that I have not thought of.
I asked about SFRBIT documentation because it is listed in the Wixel SDK help and it does not include any warnings about alignment. I know it is documenting the .h file.
I have the test code working and thought I would post it for anyone in the future.
Thanks again,
Mark
#include <wixel.h>
#include <usb.h>
#include <usb_hid.h>
#include <gpio.h>
#include <board.h>
#include <stdio.h>
#include <cc2511_map.h>
unsigned char P0_0_interrupt;
//P0IFG interrupt status port 0
//PICTL bit 3 interrupt control port 0, input 0-3
//IEN0 Interrupt Enable for many
//IEN1 Interrupt Enable 0 Register
ISR(P0INT,0)
{
if (P0IFG & 0b00000001)
{
P0_0_interrupt = 1;
}
P0IFG = 0; //clear them all, safety
IRCON &= 0b10011111; //clear port 0 flag and docs say bit six must always be 0
}
void initialize()
{
systemInit();
usbInit();
//setup a falling edge interrupt on P0_1.
PICTL = 0b00001001; //Port 0, inputs 3 to 0 interrupt enable, only for now
//and falling edge interrupt
IEN1 = 0b00100000; //enable port 0 interrupts
EA = 1; //enable all interrupts
}
void main()
{
initialize();
while(1)
{
if (P0_0_interrupt == 1)
{
LED_RED_TOGGLE();
P0_0_interrupt = 0;
}
}
}
I have three analog inputs P0_0 to P0_2. I would like to trigger an interrupt either on both falling or rising edge. With the published code it will be either rising or falling edge? If I use Timer 1 in input capture mode can I get the desired results? T1CCTL0 = 0b01000011 and T1CC0H:T1CC0L = 0x0BB7? Using Timer 1 helps in capturing the time of event?
The comments in Mark’s code mention four registers that are important for for setting up interrupts: P0IFG, PICTL, IEN0, and IEN1. I recommend reading the documentation of each of these registers in the CC2511F32 datasheet. In particular, PICTL has some bits in it that let you specify a falling edge or a rising edge, and Mark chose the falling edge in his code above. The chip does not directly support interrupting on both a rising edge and a falling edge, but you could probably use one pin to detect falling edges and another pin on a different port to detect rising edges of the same signal.
I have not tried using Timer 1 in input capture mode, but it might work for you. Alternatively, you might consider letting Timer 1 run freely and then reading its count register in your interrupt. If your interrupt has the highest priority of all the active interrupts in the system, that should give you readings that are accurate to within a few instruction cycles.