openwch / ch32v003

CH32V003 is an ultra-cheap RISC-V MCU with 2KB SRAM, 16KB flash, and up to 18 GPIOs that sells for under $0.10
393 stars 58 forks source link

The clock security system is not working (fixed) #48

Closed git2fa closed 1 month ago

git2fa commented 1 month ago

One own evaluation board is crashing after about ten minutes, when the external crystal is activated with #define FUNCONF_USE_HSE 1 in funconfig.h

RTFM (CH32V003RM.PDF) and the debug output shows, that the clock security system is active but not working!

  1. The HSE crystal can be turned on and off by setting the HSEON bit in the RCC_CTLR register. The HSERDY bit indicates whether the HSE crystal oscillation is stable or not, and the hardware feeds the clock into the system only after HSERDY position 1.

  2. Note: If the HSE crystal oscillator fails, the HSI clock is used as a backup clock source (clock safety system)

  3. HSI is enabled and disabled by setting the HSION bit in the RCC_CTLR register, and the HSIRDY bit indicates whether the HSI RC oscillator is stable or not.

  4. By configuring the RCC_CFGR0 register and the extended register EXTEND_CTR, the internal PLL clock can select 2 clock sources, these settings must be done before PLL is turned on, once PLL is started these parameters cannot be changed.

  5. Once the HSE clock fails during system operation, the HSE oscillator will be turned off, the clock failure event will be sent to the brake input of the advanced- control timer (TIM1) and a clock safety interrupt will be generated with CSSF position 1 and the application enters the NMI non- maskable interrupt. Read RCC->INTR Bit CSSF (7). By setting the CSSC bit, the CSSF bit flag can be cleared and the NMI interrupt pending bit can be undone. (PDF page 20)

  6. The clock security system is activated by setting CSSON position 1 of the RCC_CTLR register.

It seems that the NMI-Interrupt is occuring but no interrupt routine is defined, and so without a configured watchdog the controller is hanging.

The Register RCC-CTLR shows the actual status:

Register-RCC-CTLR

Sorry, github does not allow to upload the Calc-Sheet for decoding here.

The problem could be fixed with adding the following Interrupt routine now:

volatile uint8_t  ClockFailure; // Flag for HSE clock failure

void NMI_Handler(void) __attribute__((interrupt));
void NMI_Handler(void) {
    ClockFailure = (RCC->INTR & 0xFF);      // CSSF Bit 7 and more
    RCC->INTR |= RCC_CSSC;              // Clear CSSF with CSSC
}

It is very interesting that after adding this routine to the source the controller does not crash any more and the crystal is running stable now (for more than 2 hours).

git2fa commented 1 month ago

CH32V003 Register ods

Ah - the Calc-Sheet can be uploaded when the file ending is jpg instead of ods. You must do a "save as" and then rename the file with the ending "ods" to use it.

You can decode comfortable 3 registers with it now. Additional you can document the pin assignment for a project in it.