It often makes a difference adding the NOP right after SLEEP.Code:@ SLEEP @ NOP
It often makes a difference adding the NOP right after SLEEP.Code:@ SLEEP @ NOP
at a guess is it possible there is still activity on the serial input ie a cr/lf after the command.
your code might see a RCIDL condition between these chrs and pop into and straight out of sleep
try a small delay before calling sleepmode a 2chr time delay can't hurt here
which you have already is necessary, the extra two in use may not be adding much value but won't hurtIt often makes a difference adding the NOP right after SLEEP.
Warning I'm not a teacher
PIC16F1936, PBP PRO 2.60, MPASM,
My Slave Board receives com from the Master Board and runs Subroutines.
Slave operates in tight loop at Start.
On EUSART INT Slave receives one command Byte from Master and advances to CaseAction (Multi-IF THENs) which will branch to Sub to take action.
When Slave receives a code for Sleep Mode (CASE 7) is run.
Here’s where my problems start!
It seams that the RCIDL bit is never being set after Rx.
Will not go into SLEEP mode with or without -
BTFSS BAUDCON,RCIDL ;Check for High, no receive in progress
GOTO $-1
Before WUE bit is set.
What would prevent RCIDL from being set? Even after a hundred cycles after Comm is complete? Data Sheet says this bit should be set on EUSART Stop bit. At this time no Rx is coming from the Master. Can’t get any SLEEP!
Wayne
Code:Start: @ nop @ BTFSS _INTbit ;if set - gosub CaseAction @ goto $-1 INTbit=0 ‘My INT flag bit gosub CaseAction goto Start ;---------------------------------------------------------------------------------- RXceiveINT: ‘ISR INTbit=1 'Set INTbit to break out of Start loop hserin [Bvar] @ INT_RETURN ;goes back to INTerrupt locaion. which is Start loop. ;---------------------------------------------------------------------------------- CaseAction: ‘PBP multi IF THEN’s busy=1 @ MOVF BAUDCON,0 ;What is in the RCIDL bit? ;TESTING @ MOVWF _Avar ;TESTING serout2 USB_Tx,84, [" BAUDCON=",bin8 Avar,13,10] ;TESTING Bvar=Bvar+1 'On wakeup Slave receives %00000000 from Master, Select Case Bvar Case 1 ;No action taken if Not in Sleep Mode gosub Dummy ;------------ CASE 7 gosub SleepMode end select busy=0 return ;---------------------------------------------------------------------------------- ;------------------Case7 SleepMode: @ INT_DISABLE RX_INT ‘ASM- disable EUSART interrupt PortA.1=1 ‘Flash LED when entering Sleep Mode routine pause 100 PortA.1=0 @ MOVF BAUDCON,0 ‘Is RCIDL idel? Set for Idel ‘For testing @ MOVWF _Avar ‘For testing Avar=Avar dig 6 ‘For testing serout2 USB_Tx,84, [" RCIDL=",dec Avar,13,10] ‘display contents of RCIDL ‘For testing ASM BSF BAUDCON, ABDEN ;enable Auto Detect in sleep mode - tried with and without BTFSS BAUDCON,RCIDL ;Check for High, no receive in progress - tried with and without GOTO $-1 ;return to previous line BSF BAUDCON,WUE ;Set to Wake on Rx from Master SLEEP nop ‘WAKE from EUSART Rx should occur here nop nop ; ENDASM for Avar = 1 to 10 ‘flash LED on wakeup for TESTNG PortA.3=1 pause 50 PortA.3=0 pause 50 next Avar @ INT_ENABLE RX_INT ‘ASM- reenter EUSART interrupt Return END
your code is an uncompilable snippet so its hard to know whats going on
there are issues here
what bank is baudcon in ?Code:@ MOVF BAUDCON,0 ‘Is RCIDL idel? Set for Idel ‘For testing @ MOVWF _Avar ‘For testing Avar=Avar dig 6 ‘For testing
what bank is Avar in ?
from the looks of it Avar must be byte , how can it ever have a Dig 6
whats wrong with one of these ,one of them will produce efficient code i'm sure
if baudcon & 64 then
avar=1
else
avar=0
endif
or
avar=baudcon.6
or
avar=(baudcon&64) >>6
Warning I'm not a teacher
Here is something from me:
1. Leave the RX pin unconnected for testing. Check the pin state. Does it stay low or high? If it is high and you get int at high already, then it never sleeps.
2. IF all ok, then before sleep instructon, disable GIE and PEIE first. Disable eusart module. Then re-enable it. clear the flags. Then enable GIE, PEIE and lastly usart int bit. Make sure usart flag is cleared, and Usart int bit enabled at the last just before SLEEP command.
3. There should be at least two NOP() immediately after SLEEP.
4. If there are some other ints in your code not shown here, than they may be the cause of wake up. Remember, Most of the ext int sources wake the device up eventhough you do not care for them. Make sure you disable all other ext int sources (if you are using any) before SLEEP.
Last edited by sayzer; - 11th May 2020 at 09:42.
"If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte
not as i read the data sheet3. There should be at least two NOP() immediately after SLEEP.
When the SLEEP instruction is being executed, the next
instruction (PC + 1) is prefetched. For the device to
wake-up through an interrupt event, the corresponding
interrupt enable bit must be enabled. Wake-up will
occur regardless of the state of the GIE bit. If the GIE
bit is disabled, the device continues execution at the
instruction after the SLEEP instruction. If the GIE bit is
enabled, the device executes the instruction after the
SLEEP instruction, the device will call the Interrupt Service
Routine. In cases where the execution of the
instruction following SLEEP is not desirable, the user
should have a NOP after the SLEEP instruction.
Warning I'm not a teacher
One NOP is enough and should be a good practice to have one in any case. After all a NOP delay is too small to create any short of problem.
Ioannis
Bookmarks