Power Down operation
SUMMARY:
Power Down introduction
μ-controller power down it's a feature that allows to mitigate disturbances by stopping μ-controller clock. In addition a small save is also obtained in ower consumption. Power Down implementation in our fw is quite flexible: it can be set ON or OFF and the time to wait before power down is active can be also set.
The variable that account for the power down wait is POWER_DOWN_TEMPO_ATTESA. It is reset after any wake up and at startup. It is increased within SysTick_Handler() and is a multiple of 10 ms. Maximum elapsed time before power down is set by the user through POWER_DOWN_MAX_ATTESA. This is done in the main() :
277 per_non_ripetere = 255;
void LED_remote_ON_OFF(void)
LEDs can be set ON/OFF from remote.
void LED_accendi_spegni(uint8_t LED, uint8_t accendi_1_spegni_0)
This function turns ON or OFF any of the selcted LED.
volatile uint32_t POWER_DOWN_MAX_ATTESA
upper limit for POWER_DOWN_TEMPO_ATTESA
volatile uint32_t POWER_DOWN_ABILITA_CONTEGGIO
Power down couter and anable is set if this variable is true.
void PowerControl_PowerDown(void)
Power down managing function.
volatile uint32_t POWER_DOWN_TEMPO_ATTESA
Counter to wait for power down, multiple of 10 ms.
bool flag_power_down
if flag_power_down is true the u-controller goes in power down after a while
As it can be seen, power down is enabled or not in relation to the 2 boolean variables POWER_DOWN_ABILITA_CONTEGGIO and flag_power_down. The first one, POWER_DOWN_ABILITA_CONTEGGIO, is set false by the fw whenever there is an action into operation. The switch flag_power_down is instead set by the user with the proper instuction, se below.
The function that manages the poower down, invoked above, is PowerControl_PowerDown().
Power down managing
Power down to take place needs of a few steps:
- Preparation of the peripheral which will be sensitive to wake up;
- Turn off of all the peripherals that could inhibit the power down to start;
- turn off of the PLL and set the clock to a default;
- Start of power down;
- Operations to be down at wake up: clock, peripherals,...
Our μ-controller has the possibility to be waked-up from the activity on the CAN bus line. However, we encontered some difficulties in exploiting that feature and have used in previous μ-controllers the wake-up from the pin. For doing that the CAN is first disabled, than the receiving pin is set as GPIO input, and enabled as interruput from wake-up, as listed here:
303#ifdef power_down_conEINT3
307 status =
CANdrv ->PowerControl(ARM_POWER_OFF);
308 status =
CANdrv -> Uninitialize();
310 PIN_Configure(CAN_RD_PORT, CAN_RD_BIT, PIN_FUNC_0, PIN_PINMODE_TRISTATE, PIN_PINMODE_NORMAL);
311 NVIC_DisableIRQ(EINT3_IRQn);
314 NVIC_SetPriority(EINT3_IRQn,31);
315 NVIC_SetPriority (SysTick_IRQn, 29);
316 NVIC_ClearPendingIRQ(EINT3_IRQn);
317 NVIC_EnableIRQ(EINT3_IRQn);
324 I2CAdrv->PowerControl (ARM_POWER_OFF);
325 I2CAdrv->Uninitialize ();
326 I2CBdrv->PowerControl (ARM_POWER_OFF);
327 I2CBdrv->Uninitialize ();
328 SPIdrv->PowerControl (ARM_POWER_OFF);
329 SPIdrv->Uninitialize ();
As it can be seen, the other communication peripherals used are disabled, too.
The next important step is to disable the PLL of the clock:
344 LPC_SC->PLL0CON &= ~(1<<1) ;
352 LPC_SC->PLL0FEED = 0xAA;
353 LPC_SC->PLL0FEED = 0x55;
355 while ((LPC_SC->PLL0STAT & (1<<25)) != 0x00);
357 LPC_SC->PLL0CON &= ~(1<<0);
359 LPC_SC->PLL0FEED = 0xAA;
360 LPC_SC->PLL0FEED = 0x55;
362 while ((LPC_SC->PLL0STAT & (1<<24)) != 0x00){}
Finally, the μ-controller is ready to sleep:
370 if( ( CoreDebug ->DHCSR & 1 )==0 ){
The switch on CoreDebug ->DHCSR is done to avoid conflict during the debug phase, if the debugger is connected to the JTAG.
Wake-up managing
The function EINT3_IRQHandler() is called at the wake-up, when the control room starts the activity on the CAN bus. The first action is to restor the pins dedicated to CAN and the shutting down of the waking interrupt pin in the function WakeResetCAN():
399 NVIC_ClearPendingIRQ(EINT3_IRQn);
400 NVIC_DisableIRQ(EINT3_IRQn);
401 PIN_Configure(CAN_RD_PORT, CAN_RD_BIT, CAN_RD_FUNC, PIN_PINMODE_TRISTATE, PIN_PINMODE_NORMAL);
void WakeResetCAN(void)
CAN pins restoring.
Finally the clock and all the communication peripherals are re-activated in CANActivity_IRQHandler_mio():
212#ifdef power_down_conCAN
214 LPC_SC->CANSLEEPCLR|=2U;
215 LPC_CAN1->MOD &=~(1<<4);
216 LPC_SC->CANWAKEFLAGS|= 2U;
217 LPC_CAN1->IER &= ~(1<< 4);
218 NVIC_DisableIRQ(CANActivity_IRQn);
228 LPC_SC->PCON &=~ 0x01;
229 SCB->SCR &=~ (1UL << 2);
231 can_clock=
CANdrv->GetClock();
235 LPC_CAN1->GSR &= ~CAN_GSR_TXERR_Msk;
237 uint32_t LPC_dummy= LPC_CAN1->ICR;
238 SystemCoreClockUpdate();
uint32_t tx_obj_idx
This is the variable which resembles the flags from the communication.
unsigned int indirizzo_CAN_della_scheda
Per ora lo assegnamo cos\i l'indirizzo della scheda.
void CAN_Inizialize(void)
The CAN initialization function.
void I2C_0_Initialize(void)
The I2C_0 initialize.
void I2C_1_Initialize(void)
The I2C_1 initialize.
void CANActivity_IRQHandler_mio(void)
Peripherals Wake-up.
void SPI_Inizialize(void)
SPI is initialized here. Its ise t at 8 bits and 100 KHz, as default.
- See also
- The instruction over the CAN to set the Power Down parametrs is instr_Shut_Down_ON_OFF.