DeqingSun / ch55xduino

An Arduino-like programming API for the CH55X
GNU Lesser General Public License v2.1
449 stars 87 forks source link

Low Power CH552 #106

Closed sabas1080 closed 1 year ago

sabas1080 commented 1 year ago

Hi @DeqingSun

I am trying to activate the sleep mode on the ch552, based on this example, but the chip never returns from sleep

https://github.com/kimbc2848/test/blob/master/examples/sleep/main.c

My Sketch

uint8_t counter = 0;
bool LED = true;
void setWakeup(){
    WAKE_CTRL = WAKE_CTRL | bWAK_P1_5_LO | bWAK_P1_4_LO | bWAK_P1_3_LO |bWAK_RST_HI ;

}

void enterSleep(){

    PCON = PCON | PD;

}

/*******************************************************************************
* Function Name  : CH554WDTModeSelect(uint8_t mode)
* Description    : CH554 watchdog mode selection
* Input          : uint8_t mode
                   0  timer
                   1  watchDog
* Output         : None
* Return         : None
*******************************************************************************/
inline void CH554WDTModeSelect(uint8_t mode)
{
   SAFE_MOD = 0x55;
   SAFE_MOD = 0xaa;                                                             //Enter Safe Mode
   if(mode){
     GLOBAL_CFG |= bWDOG_EN;                                                    //Start watchdog reset
   }
   else 
   {
    GLOBAL_CFG &= ~bWDOG_EN;                                              //Start watchdog only as a timer
   }
   SAFE_MOD = 0x00;                                                             //exit safe Mode
   WDOG_COUNT = 0;                                                              //Watchdog assignment initial value

}

/*******************************************************************************
* Function Name  : CH554WDTFeed(uint8_t tim)
* Description    : CH554 watchdog timer time setting
* Input          : uint8_t tim watchdog reset time setting
                   00H(6MHz)=2.8s
                   80H(6MHz)=1.4s
* Output         : None
* Return         : None
*******************************************************************************/
inline void CH554WDTFeed(uint8_t tim)
{

   WDOG_COUNT = tim;                                                            // Watchdog counter assignment

}
void setup() {
  setWakeup();
  CH554WDTModeSelect(0x1);
  pinMode(17, OUTPUT);
}

void loop() {
        delay(500);
        CH554WDTFeed(0x0A);
        LED = !LED;
        digitalWrite(17,LED);
        counter++;

        if (counter > 10) {
            counter = 0;
            enterSleep();
        }

}

thanks

DeqingSun commented 1 year ago

This example seems want to wake up the chip by WDT but it won't work.

The datasheet mentioned

When CH552 does not need to run at all, PD in PCON can be set to enter the sleep state. In the sleep state, wakeup can be implemented via USB, UART0, UART1, SPI0 and part of GPIOs.

And this post confirmed it.

You can use this sketch and see if you can wake the chip with GPIO.

sabas1080 commented 1 year ago

Thanks @DeqingSun , I have tried with this example and I have not been able to wake it up via RESET

uint8_t counter = 0;
bool LED = true;
void setWakeup(){
    WAKE_CTRL = WAKE_CTRL | bWAK_P1_5_LO | bWAK_P1_4_LO | bWAK_P1_3_LO |bWAK_RST_HI ;

}

void enterSleep(){

    PCON = PCON | PD;

}

void setup() {
  setWakeup();
  CH554WDTModeSelect(0x1);
  pinMode(17, OUTPUT);
}

void loop() {
        delay(500);
        LED = !LED;
        digitalWrite(17,LED);
        counter++;

        if (counter > 10) {
            counter = 0;
            enterSleep();
        }

}
DeqingSun commented 1 year ago

How about P13~P15?

sabas1080 commented 1 year ago

I have noticed that my 552G chip does not have P13 and I have removed it, but it still cannot wake up from sleep mode with P14 and P15.

uint8_t counter = 0;
bool LED = true;
void setWakeup(){
    WAKE_CTRL = WAKE_CTRL | bWAK_P1_5_LO | bWAK_P1_4_LO |bWAK_RST_HI ;

}

void enterSleep(){

    PCON = PCON | PD;

}

void setup() {
  setWakeup();
  CH554WDTModeSelect(0x1);
  pinMode(17, OUTPUT);
}

void loop() {
        delay(500);
        LED = !LED;
        digitalWrite(17,LED);
        counter++;

        if (counter > 10) {
            counter = 0;
            enterSleep();
        }

}
DeqingSun commented 1 year ago

@sabas1080

uint8_t counter = 0;
bool LED = true;

#define LED_BUILTIN 33

void setup() {
  SAFE_MOD = 0x55;
  SAFE_MOD = 0xaa;
  WAKE_CTRL = WAKE_CTRL | bWAK_P1_5_LO | bWAK_P1_4_LO | bWAK_RST_HI ;
  SAFE_MOD = 0x00;

  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  LED = !LED;
  digitalWrite(LED_BUILTIN, LED);
  PCON = PCON | PD;
}

I've tested this works.

Please note:

_Wakeup control register (WAKECTRL), only can be written in safe mode:

sabas1080 commented 1 year ago

Working!! Thanks @DeqingSun