I have questions about how the sample project works. The customer used the code from the sample project to evaluate the electrostatic sensor board.
In the process of 'PROCESS_DATA' of Switch condition statement of main.c, the customer code saves the value of buttonStatus in a static variable and controls the GPIO to notify the status to the main CPU.
Continuously touching the CSD sensor causes PSoC to stop responding.
(Customer refer "CE210709_CapSense_Linear_Slider_and_Buttons")
[Results of customer analysis]:
1) GPIO which notifies the sensor touch event to the main CPU is not working.
2) However, when a problem occurs, "PROCESS_DATA" is executed normally in the debugger, and the sensor touch status can be acquired accurately. (Q1)
3) Furthermore, the GPIO control function (IRQpin_Write (0)) that notifies the main CPU is also executed normally. This can also be confirmed from the fact that the intended value can be obtained with the IRQpin_Read () function. (Q1)
4) According to the oscilloscope waveform, GPIO is not working.
5) Once in this state, the GPIO remains inactive even if the sensor touch operation is performed.
6) When I2C communication from the main CPU occurs, PSoC returns to normal operation and GPIO is controlled according to the sensor touch operation.
7) If CySysPmSleep () is deleted, this problem does not occur.
According to the customer's report, the debugger normally exits sleep (CySysPmSleep ()) and shifts to "PROCESS_DATA" processing, but isn't the sleep function invalid during the debug processing of PSoC Creator?
- Isn't the CySysPmSleep () running in the "WAIT_FOR_SCAN_COMPLETE" state not returning from the sleep mode after the completion of the key scan?
- 6) Isn't the problem solved by I2C communication from the main CPU because PSoC returned from sleep mode by the interrupt by I2C communication?
[Additional analysis result]:
From the source code of "CE224899_PSoC4_Low_Power_CapSense_Hybrid_Sensing01"
Before CySysPmSleep ();
Added interruptState = CyEnterCriticalSection ();
After CySysPmSleep ();
Added CyExitCriticalSection (interruptState);
The above solved the problem. (See attached sheet)
CyEnterCriticalSection () has already been done inside the CySysPmSleep () function, so the addition of this code only makes a double critical section transition.
Why does adding CyEnterCriticalSection () solve this problem?