Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ch32fun/ch32v30xhw.h
Original file line number Diff line number Diff line change
Expand Up @@ -8601,7 +8601,7 @@ typedef struct
#define PWR_FLAG_WU ((uint32_t)0x00000001)
#define PWR_FLAG_SB ((uint32_t)0x00000002)
#define PWR_FLAG_PVDO ((uint32_t)0x00000004)

#define PVD_MAX_THRESHOLD_LVL 7


/* ch32v00x_rcc.h ------------------------------------------------------------*/
Expand Down
1 change: 1 addition & 0 deletions ch32fun/ch32x00xhw.h
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,7 @@ typedef struct

/******************* Bit definition for PWR_CSR register ********************/
#define PWR_CSR_PVDO ((uint16_t)0x0004) /* PVD Output */
#define PVD_MAX_THRESHOLD_LVL 3

/******************************************************************************/
/* Reset and Clock Control */
Expand Down
12 changes: 12 additions & 0 deletions examples_v30x/pvd_voltageDetect_test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
all : flash

TARGET:=pvd_voltageDetect_test
TARGET_MCU:=CH32V303
TARGET_MCU_PACKAGE:=CH32V303

include ../../ch32fun/ch32fun.mk

flash : cv_flash
clean : cv_clean


13 changes: 13 additions & 0 deletions examples_v30x/pvd_voltageDetect_test/funconfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef _FUNCONFIG_H
#define _FUNCONFIG_H

#define FUNCONF_SYSTICK_USE_HCLK 1
#define FUNCONF_USE_HSI 1
#define FUNCONF_USE_PLL 0
#define FUNCONF_PLL_MULTIPLIER 2

#define FUNCONF_USE_DEBUGPRINTF 1
#define FUNCONF_SYSTEM_CORE_CLOCK 8 * 1000 * 1000

#endif

43 changes: 43 additions & 0 deletions examples_v30x/pvd_voltageDetect_test/pvd_voltageDetect_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Simple example that shows how to use the PVD voltage detector functions
// the datasheet shows 2 different PVD levels selection options one for VLEVEL 0 and one for VLEVEL 1
// It's not mentioned anywhere (that I can find) what chip uses what PVD level, if you find it let me know
// When the input supply voltage drop bellow the threshold the PVD will trigger an alert

// Testing Methods:
// Method 1: Using a Potentiometer
// Connect a potentiometer across the power supply input and ground
// Adjust the potentiometer to vary the input voltage
// Observe the PVD status output as the voltage crosses the threshold

// Method 2: Using a Voltage Divider
// Add a series resistor to the power input to create a voltage drop
// Monitor the PVD output to detect when voltage falls below the set threshold

#define VLEVEL 1
// #define VLEVEL 0

#include "ch32fun.h"
#include <stdio.h>
#include "lib_pvd.h"

void PVD_statusPrint() {
const char *v1[] = { "2.29", "2.46", "2.55", "2.67", "2.78", "2.93", "3.06", "3.19" };
const char *v0[] = { "2.13", "2.25", "2.32", "2.42", "2.51", "2.61", "2.69", "2.79" };
const char *threshold_str = (VLEVEL == 0) ? v0[PVD_getThreshold()] : v1[PVD_getThreshold()];

printf("\nThreshold: %sV", threshold_str);
printf("\nStatus: %s\n", PVD_getAlert() ? "BELOW THRESHOLD!" : "Normal");
}

int main() {
SystemInit();
Delay_Ms(100);

printf("\n~ PVD Voltage Detector Test ~\n");
PVD_init(7); // select threshold 0-7

while(1) {
PVD_statusPrint();
Delay_Ms(1000);
}
}
46 changes: 9 additions & 37 deletions examples_x00x/pvd_voltage_detector/pvd_voltage_detector.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,53 +19,25 @@

#include "ch32fun.h"
#include <stdio.h>
#include "register_debug_utilities.h"
#include "lib_pvd.h"

void configure_PVD(u8 threshold) {
// Enable PWR clock
RCC->APB1PCENR |= RCC_APB1Periph_PWR;

// Enable PVD
PWR->CTLR |= PWR_CTLR_PVDE;

if (threshold > 3) threshold = 3;
printf("\n");
printf("Before write:\n");
UTIL_PRINT_REG16(PWR->CTLR, "PWR_CTLR");

// set the PLS[1:0] bits
PWR->CTLR &= ~(0b011 << 5); // clear bits
PWR->CTLR |= (threshold << 5);
printf("After setting:\n");
UTIL_PRINT_REG16(PWR->CTLR, "PWR_CTLR");
printf("\n");
}

// threshold1 = 2.1V, theshold2 = 2.3V, threshold3 = 3.0V, threshold4 = 4.0V
void check_PVD_status(void) {
// Get threshold setting: the PLS[1:0] bits
uint8_t threshold_setting = (PWR->CTLR >> 5) & 0x03;

// get the PVD0 status bit: it's set when the voltage drops below the threshold
uint8_t pvd_alert = (PWR->CSR >> 2) & 0x01;

void PVD_statusPrint() {
const char *thresholds[] = { "2.1V", "2.3V", "3.0V", "4.0V" };
printf("\nThreshold: %s ", thresholds[threshold_setting]);
printf("Status: %s\n", pvd_alert ? "BELOW THRESHOLD!" : "Normal");
const char *threshold_str = thresholds[PVD_getThreshold()];

printf("\nThreshold: %sV", threshold_str);
printf("\nStatus: %s\n", PVD_getAlert() ? "BELOW THRESHOLD!" : "Normal");
}

int main() {
SystemInit();
funGpioInitAll(); // Enable GPIOs
Delay_Ms(100);

printf("\n~PVD Voltage Detector Example~\n");
// printf("Chip ID: %08lX\r\n", ESIG->UID0);
// printf("Chip Capacity: %d KB\r\n", ESIG->CAP);
configure_PVD(1);
PVD_init(1);

while(1) {
check_PVD_status();
PVD_statusPrint();
Delay_Ms(1000);
// printf("IM HERE\n");
}
}
26 changes: 26 additions & 0 deletions extralibs/lib_pvd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Tested with CH32V002, CH32V006, and CH32V303

#include "ch32fun.h"

void PVD_init(u8 threshold) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be static.

if (threshold > PVD_MAX_THRESHOLD_LVL) threshold = PVD_MAX_THRESHOLD_LVL;

// Enable PWR clock
RCC->APB1PCENR |= RCC_APB1Periph_PWR;

// Enable PVD
PWR->CTLR |= PWR_CTLR_PVDE;

// Clear the existing PLS bits and set new threshold
PWR->CTLR = (PWR->CTLR & ~PWR_CTLR_PLS) | (threshold << 5);
}

// Get threshold setting: the PLS[1:0] bits
u8 PVD_getThreshold() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in general, make these ints so that the compiler doesn't do any extra masking.

Here, it's fine it's not a big deal, and the compiler will produce fine code, but in other cases it may not.

return (PWR->CTLR & PWR_CTLR_PLS) >> 5;
}

// return PVD flag: 1 if VDD below threshold
u8 PVD_getAlert() {
return PWR->CSR & PWR_CSR_PVDO;
}