Hi,
I have a working CAN interface code and now want the micro to go to sleep when there are no CAN messages on the bus and to wake on reception of a CAN message.
To test this I have a variable I write to with the debug interface to tell it to sleep. This works as I can see the current supply drop when I activate my sleep.
Then I send some CAN frames and nothing happens.
I have 3 CAN interfaces active although only one will provide the wake up event. I have code to re-initialise the other CANs inside their Wake interrupts.
This is a sample of my code. For brevity I show only CAN0 where possible.
if (Go_to_Sleep == 99) // Test if I must sleep ?
{
CAN0CTL0 |= WUPE;
CAN1CTL0 |= WUPE;
CAN4CTL0 |= WUPE;
CAN0RIER |= WUPIE;
CAN1RIER |= WUPIE;
CAN4RIER |= WUPIE;
CAN0CTL0 |= SLPRQ; // Request sleep mode
CAN1CTL0 |= SLPRQ; // Request sleep mode
CAN4CTL0 |= SLPRQ; // Request sleep mode
while ((CAN0CTL1 & SLPAK) != 0) ; // Wait for SLPAK to == 1
while ((CAN1CTL1 & SLPAK) != 0) ; // Wait for SLPAK to == 1
while ((CAN4CTL1 & SLPAK) != 0) ; // Wait for SLPAK to == 1
_asm ("ANDCC #$7f"); // Clear S bit
_asm ("nop");
_asm ("STOP"); // Enter STOP mode
// Processor will now SLEEP here
// And wakeup here.
}
ISR // Interrupt on wake
void Isr_CAN0_Wake(void) // Triggers when the procesor wakes on a Can packet receive
{
if ((CAN0CTL1 & INITAK) != 0)
return; // Not initialised yet
if (((CAN0CTL0 & SLPRQ) != 0) && ((CAN0CTL1 & SLPAK) == 0))
return; // Not yet in Sleep mode: cannot clear SLPRQ
else
{
DisableInterrupts; // SEI
CAN0RIER |= WUPIE; // clear wakeup interrupt
CAN1RIER |= WUPIE;
CAN4RIER |= WUPIE;
EnableInterrupts; // CLI
CAN0CTL0 &= ~SLPRQ; // clear SLPRQ
CAN1CTL0 &= ~SLPRQ; //
CAN4CTL0 &= ~SLPRQ; //
}
Go_to_Sleep = 0; // Clear my Variable
}
void CAN_Init_(void) // CAN initialisation called at start up.
{
CAN0CTL0 |= INITRQ; // set INITRQ, this will also set INITAK
while ((CAN0CTL1 & INITAK) != 1) ; // wait for init mode to occur
CAN0CTL1 = CTL1; // == CANE | BORM
CAN0BTR0 = BTR0_500; // == 0xc0
CAN0BTR1 = BTR1_500; // == 0x34
CAN0IDAC = IDAM0; // Four 16 bit acceptance filters
CAN0_Dont_care(); // Setup Acceptance registers
CAN0CTL0 &= ~INITRQ; // clear INITRQ. Restart and synchronise
while ((CAN0CTL1 & INITAK) != 0) ; // Wait for acknowledge
CAN0RIER = CSCIE | RSTATE0 | TSTATE0 | OVRIE | RXFIE; // enable receive interrupt RXFIE
CAN0RFLG = WUPIF | OVRIF | RXF; // Reset Error Flags
}
The CAN1 and CAN4 are initialised with the same values. The Wake is also the same.
My debug interface disconnects when I enter sleep so this is rather difficult to debug.
Can you help?
Regards,
Wade