fix various bugs. editor button initial WIP.

setting cursor to off would keep its last state active. fixed.

cursor wouldn't turn off all the way and would glitch out. fixed.

cursor now has a nicer fadeout.

fixed potentiometer scaling factors.

tried fixing clockspeed stuff. with these changes clock speed can more reliably change to 24MHz or 48MHz, but this isn't thoroughly tested. 3MHz to 24MHz was still crashing. as ADC is in use, code would need to be refactored to not change clock speed while ADC is converting. since I don't want to do this right now, this will run at a fixed speed at the expense of 0.5-1mA.

editor buttons working and updated to the new arrangement, but not tested in depth.

pressing and holding to exit parameter editor while edit mode active would result in next entry into parameter editor being in edit mode. fixed.

lsens / stat LED now functioning in program and parameter edit modes.
This commit is contained in:
true 2025-07-24 16:03:48 -07:00
parent 35653d25e3
commit efaeb803a5
8 changed files with 401 additions and 390 deletions

View File

@ -11,9 +11,7 @@
#define SYSCLK_FREQ_NORMAL SYSCLK_FREQ_24MHz_HSI
#define SYSCLK_FREQ_USEI2C SYSCLK_FREQ_24MHz_HSI
#define SYSCLK_FREQ_IDLE SYSCLK_FREQ_12MHz_HSI
#define SYSCLK_FREQ_STARTUP SYSCLK_FREQ_16MHz_HSI

View File

@ -52,9 +52,9 @@ void awu_init(void)
AWU_SetWindowValue(47);
AutoWakeUpCmd(ENABLE);
// if rising edge and interrupt isn't set on EXTI line 27,
// interrupt won't fire.
EXTI->RTENR = EXTI_RTENR_TR27;
// in order to fire AWU interrupt, enable EXTI interrupt on rising edge on EXTI line 27.
// this isn't explicitly stated in the DS, but AWU interrupt == EXTI line27 interrupt.
EXTI->RTENR = EXTI_RTENR_TR27;
EXTI->INTENR = EXTI_INTENR_MR27;
NVIC_EnableIRQ(AWU_IRQn);
@ -64,9 +64,9 @@ void gpio_init()
{
GPIO_InitTypeDef gpio = {0};
// only one GPIO speed on this bad boy
gpio.GPIO_Speed = GPIO_Speed_50MHz;
// jogwheel digital inputs, active low (PA4-PA6)
gpio.GPIO_Mode = GPIO_Mode_IPU;
gpio.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
@ -75,7 +75,7 @@ void gpio_init()
// lightsense LED cathode (PA7, A8)
gpio.GPIO_Mode = GPIO_Mode_AIN;
gpio.GPIO_Pin = GPIO_Pin_7;
GPIOA->BSHR = GPIO_Pin_7;
GPIOA->BCR = GPIO_Pin_7;
GPIO_Init(GPIOA, &gpio);
// potentiometer (PB1, A9)

View File

@ -84,25 +84,31 @@ void adc_read()
}
}
void adc_use_lsens()
void adc_lsens_input()
{
GPIO_InitTypeDef gpio = {0};
// configure GPIO
gpio.GPIO_Mode = GPIO_Mode_AIN;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
gpio.GPIO_Pin = LSENS_K_PIN;
GPIO_Init(LSENS_K_PORT, &gpio);
}
void adc_lsens_start()
{
// enable injected channel
// note: this code is not done
ADC_AutoInjectedConvCmd(ADC1, ENABLE);
}
void adc_stop_lsens()
void adc_lsens_output()
{
GPIO_InitTypeDef gpio = {0};
// configure GPIO
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
gpio.GPIO_Pin = LSENS_K_PIN;
GPIO_Init(LSENS_K_PORT, &gpio);
}
@ -116,13 +122,13 @@ uint8_t adc_get_pot()
if (pot < POT_LO) pot = 0; else pot -= POT_LO;
// scale to upper bound
pot <<= 10;
pot <<= 12;
pot /= POT_HI;
// 8 bits is good enough for us
pot >>= 2;
pot >>= 4;
return 255 - (pot & 0xff);
return (pot & 0xff);
}
uint16_t adc_get_lsens()

View File

@ -29,8 +29,9 @@ void adc_config_lsens();
void adc_convert();
void adc_read();
void adc_use_lsens();
void adc_reset_lsens();
void adc_lsens_input();
void adc_lsens_start();
void adc_lsens_output();
uint8_t adc_get_pot();
uint16_t adc_get_lsens();

View File

@ -8,6 +8,8 @@
#include <stdint.h>
#include "ui.h"
#include "adc.h"
#include "btn.h"
#include "config.h"
@ -58,303 +60,6 @@ static uint8_t config_save_timer;
void ui_btn_push_cb(uint8_t idx)
{
uint8_t i, w;
// are both buttons pushed?
if ((btn[0]._mask & BTN_PUSH) && (btn[1]._mask & BTN_PUSH)) {
// are none held?
if (!(btn[0]._mask & BTN_HOLD) && !(btn[1]._mask & BTN_HOLD)) {
// can only enter programming mode if the cursor is flashing
if (userconf.cursor_color != CONF_CURSOR_OFF) {
// put both buttons into ignore mode, so hold and release events
// do not fire
btn[0]._mask |= BTN_IGNORE;
btn[1]._mask |= BTN_IGNORE;
// both buttons are pushed at the same time quickly, and not held
// this will toggle modes
mode++;
// parameter mode only works if a program is enabled to adjust
if (mode == MODE_PARAMETER) {
if (!userconf.ledprog_ena_mask) mode = MODE_RUN;
}
// parameter mode is the last mode
if (mode > MODE_PARAMETER) {
mode = MODE_RUN;
}
// ensure a valid program is selected
if (mode == MODE_PARAMETER) {
w = preview_idx;
for (i = 0; i < 8; i++) {
w &= 0x7;
if (userconf.ledprog_ena_mask & (1 << w)) {
preview_idx = w;
break;
}
w++;
}
}
// reset any LED program
led_rgb_firstrun();
// configure the preview index to be the first available
// depending on the mode
if (mode == MODE_PROGRAM) preview_idx = 0;
if (mode == MODE_PARAMETER) {
/*
preview_idx = 0;
for (i = 0; i < 5; i++) {
if (userconf.ledprog_ena_mask & (1 << preview_idx)) {
preview_idx = i;
break;
}
}
*/
}
return;
}
}
}
// there are no on-push events.
switch (mode) {
case MODE_RUN: {
}
}
}
void ui_btn_hold_cb(uint8_t idx)
{
switch (mode) {
case MODE_PARAMETER: {
switch (idx) {
case 0: {
if (rgb_prog_is_editing) {
userconf.ledprog_setting[preview_idx][0]++;
}
}
}
}
}
}
void ui_btn_release_cb(uint8_t idx)
{
uint8_t i;
uint8_t w;
switch (mode) {
/* button logic flow:
*
* mode changes happen by pressing both buttons.
* this is handled in the push event handler.
*
* if cursor is off, mode changing cannot occur.
*/
/*
* NORMAL MODE: cursor is flashing (or off if disabled).
*
* cursor changes are committed to EEPROM about a second after changing is done.
*
* any program which is enabled will run. the active program randomly changes after random delays.
*/
case MODE_RUN: {
switch (idx) {
case 0: { // - top button: changes cursor color (white, green, orange, off)
userconf.cursor_color++;
userconf.cursor_color &= 0x3;
// force cursor to change immediately, force cursor on
cursor_flash = 0;
cursor_state = 0;
config_save_timer = UI_CONF_SAVE_TIMEOUT;
break;
}
case 1: { // - bot button: changes cursor flash rate. press and hold
// while cursor is not off to enter program change mode.
userconf.cursor_flash++;
userconf.cursor_flash &= 0x7;
config_save_timer = UI_CONF_SAVE_TIMEOUT;
break;
}
}
break;
}
/*
* PROGRAM CHANGE MODE: cursor is on.
*
* by default, all are disabled. selected program will flash.
* cursor will light on the selected program if it is enabled.
*
* letters in TECH preview the currently selected program.
* letters in RETRO will each preview their own program (any flash / twinkle will always have idle light)
*/
case MODE_PROGRAM: {
switch (idx) {
case 0: { // - top button: tap enables or disables the program. push and hold does nothing.
w = userconf.ledprog_ena_mask;
if (userconf.ledprog_ena_mask & (1 << preview_idx)) {
userconf.ledprog_ena_mask &= ~(1 << preview_idx);
} else {
userconf.ledprog_ena_mask |= (1 << preview_idx);
}
break;
}
case 1: { // - bot button: tap selects the next program index. push and hold does nothing.
preview_idx++;
if (preview_idx >= 5) preview_idx = 0;
break;
}
}
break;
}
/*
* PARAMETER CHANGE MODE: cursor is off (or rather, very dimly on).
*
* letters in RETRO only show enabled programs. dark for disabled programs.
* RETRO letters will flash to indicate currently selected program.
*
* letters in TECH preview the current program, at some fixed brightness.
*
* - top button: change some parameter
* - knob: change some parameter (color/hue, etc)
*/
case MODE_PARAMETER: {
switch (idx) {
case 0: { // - top button: when editing disabled: selects the next program
// when editing enabled: tapped or held: increments a value, with loop
if (rgb_prog_is_editing) {
userconf.ledprog_setting[preview_idx][0]++;
} else {
w = preview_idx;
for (i = 0; i < 8; i++) {
w++;
w &= 0x7;
if (userconf.ledprog_ena_mask & (1 << w)) {
preview_idx = w;
break;
}
}
}
break;
}
case 1: { // - bot button: enables / disables editing of selected program
rgb_prog_is_editing = !rgb_prog_is_editing;
break;
}
}
break;
}
}
}
static void ui_cursor_flash()
{
uint8_t color, flash;
uint8_t level = 0;
color = userconf.cursor_color;
flash = userconf.cursor_flash;
switch (mode) {
case MODE_RUN: {
if (rgb_prog_idx != 4) {
if (!cursor_flash) {
// toggle on/off
cursor_state++;
cursor_state &= 1;
// set new cursor rate, force cursor on
cursor_flash = cursor_flash_rates[flash] >> 1;
// set all colors off
cursor[0] = cursor[1] = cursor[2] = 0;
}
// wind down counter
cursor_flash--;
// set brightness of led, if we're in an on state
if (color < CONF_CURSOR_OFF) {
if (cursor_state) {
// first frame of on = not quite full brightness
level = (cursor_flash == cursor_flash_rates[flash] - 1) ? 160 : 255;
// at final frames, dim
if (cursor_flash <= 4) {
level >>= (4 - cursor_flash);
}
}
// set the level on the cursor
if (cursor[color] != level) {
cursor[color] = led_gamma(level);
led_is_updated();
}
} else {
// clear any cursors that may have been left on
cursor[0] = 0;
cursor[1] = 0;
cursor[2] = 0;
}
}
break;
}
case MODE_PROGRAM: {
// cursor is on if this program is flagged as on
cursor[0] = (userconf.ledprog_ena_mask & (1 << preview_idx)) ? 127 : 0;
cursor[1] = 0;
cursor[2] = 0;
break;
}
case MODE_PARAMETER: {
// cursor is on when program is being edited
cursor[0] = rgb_prog_is_editing ? 127 : 0;
cursor[1] = 0;
cursor[2] = 0;
break;
}
}
}
void ui_init()
{
btn[0].hold = 420 >> 1;
btn[0].repeat = (1000 / 20) >> 1;
btn[0].cb_push = ui_btn_push_cb;
btn[0].cb_hold = ui_btn_hold_cb;
btn[0].cb_release = ui_btn_release_cb;
btn[2].hold = 420 >> 1;
btn[2].repeat = 0;
btn[2].cb_push = ui_btn_push_cb;
btn[2].cb_hold = ui_btn_hold_cb;
btn[2].cb_release = ui_btn_release_cb;
}
static void rgb_prog_random_timer_generate() {
uint32_t t;
@ -391,6 +96,345 @@ static uint8_t rgb_prog_random_select()
return 1;
}
void ui_btn_push_cb(uint8_t idx)
{
// there are no on-push events.
switch (mode) {
case MODE_RUN: {
}
}
}
void ui_btn_hold_cb(uint8_t idx)
{
uint8_t i, w;
switch (idx) {
// enter programming mode when holding jogwheel in normal run mode
case UI_JOG_PUSH: {
// can only enter programming mode if the cursor is flashing
if (userconf.cursor_color != CONF_CURSOR_OFF) {
// put main button into ignore mode,
// so hold and release events do not fire
btn[UI_JOG_PUSH]._mask |= BTN_IGNORE;
// set the next UI mode, and make sure we aren't in edit mode when changing modes
mode++;
rgb_prog_is_editing = 0;
// parameter mode only works if a program is enabled to adjust
if (mode == MODE_PARAMETER) {
if (!userconf.ledprog_ena_mask) mode = MODE_RUN;
}
// parameter mode is the last mode
if (mode > MODE_PARAMETER) {
mode = MODE_RUN;
}
// ensure a valid program is selected for editing
if (mode == MODE_PARAMETER) {
w = preview_idx;
for (i = 0; i < 8; i++) {
w &= 0x7;
if (userconf.ledprog_ena_mask & (1 << w)) {
preview_idx = w;
break;
}
w++;
}
}
// randomly select a new program when editing is complete
// (this fixes bug where disabled program continues to run)
if (mode == MODE_RUN) {
rgb_prog_random_select();
}
// reset any LED program
led_rgb_firstrun();
// configure the preview index to be the first available
// depending on the mode
if (mode == MODE_PROGRAM) preview_idx = 0;
if (mode == MODE_PARAMETER) {
/*
preview_idx = 0;
for (i = 0; i < 5; i++) {
if (userconf.ledprog_ena_mask & (1 << preview_idx)) {
preview_idx = i;
break;
}
}
*/
}
}
break;
}
}
switch (mode) {
case MODE_PARAMETER: {
if (rgb_prog_is_editing) {
switch (idx) {
case UI_JOG_UP: { userconf.ledprog_setting[preview_idx][0]++; break; }
case UI_JOG_DN: { userconf.ledprog_setting[preview_idx][0]--; break; }
}
}
break;
}
}
}
void ui_btn_release_cb(uint8_t idx)
{
uint8_t i;
uint8_t w;
switch (mode) {
/* button logic flow:
*
* mode changes happen by pressing both buttons.
* this is handled in the push event handler.
*
* if cursor is off, mode changing cannot occur.
*/
/*
* NORMAL MODE: cursor is flashing (or off if disabled).
*
* cursor changes are committed to EEPROM about a second after changing is done.
*
* any program which is enabled will run. the active program randomly changes after random delays.
*/
case MODE_RUN: {
switch (idx) {
case UI_JOG_UP: { // - top button: changes cursor color (white, green, orange, off)
userconf.cursor_color++;
userconf.cursor_color &= 0x3;
// force cursor to change immediately, force cursor on
cursor_flash = 0;
cursor_state = 0;
config_save_timer = UI_CONF_SAVE_TIMEOUT;
break;
}
case UI_JOG_DN: { // - bot button: changes cursor flash rate. press and hold
// while cursor is not off to enter program change mode.
userconf.cursor_flash++;
userconf.cursor_flash &= 0x7;
config_save_timer = UI_CONF_SAVE_TIMEOUT;
break;
}
}
break;
}
/*
* PROGRAM CHANGE MODE: cursor is on.
*
* by default, all are disabled. selected program will flash.
* cursor will light on the selected program if it is enabled.
*
* letters in TECH preview the currently selected program.
* letters in RETRO will each preview their own program (any flash / twinkle will always have idle light)
*/
case MODE_PROGRAM: {
switch (idx) {
case UI_JOG_PUSH: { // - top button: tap enables or disables the program. push and hold does nothing.
w = userconf.ledprog_ena_mask;
if (userconf.ledprog_ena_mask & (1 << preview_idx)) {
userconf.ledprog_ena_mask &= ~(1 << preview_idx);
} else {
userconf.ledprog_ena_mask |= (1 << preview_idx);
}
break;
}
case UI_JOG_UP: { // - bot button: tap selects the next program index. push and hold does nothing.
preview_idx++;
if (preview_idx >= 5) preview_idx = 0;
break;
}
case UI_JOG_DN: { // - bot button: tap selects the next program index. push and hold does nothing.
if (preview_idx == 0) preview_idx = 5;
preview_idx--;
break;
}
}
break;
}
/*
* PARAMETER CHANGE MODE: cursor is off (or rather, very dimly on).
*
* letters in RETRO only show enabled programs. dark for disabled programs.
* RETRO letters will flash to indicate currently selected program.
*
* letters in TECH preview the current program, at some fixed brightness.
*
* - top button: change some parameter
* - knob: change some parameter (color/hue, etc)
*/
case MODE_PARAMETER: {
switch (idx) {
case UI_JOG_PUSH: { // - ctr button: enables / disables editing of selected program
rgb_prog_is_editing = !rgb_prog_is_editing;
break;
}
case UI_JOG_UP: { // - top button: when editing disabled: selects the next program
// when editing enabled: tapped or held: increments a value, with loop
if (rgb_prog_is_editing) {
userconf.ledprog_setting[preview_idx][0]++;
} else {
w = preview_idx;
for (i = 0; i < 8; i++) {
w++;
w &= 0x7;
if (userconf.ledprog_ena_mask & (1 << w)) {
preview_idx = w;
break;
}
}
}
break;
}
case UI_JOG_DN: { // - bot button: when editing disabled: selects the previous program
// when editing enabled: tapped or held: decrement a value, with loop
if (rgb_prog_is_editing) {
userconf.ledprog_setting[preview_idx][0]--;
} else {
w = preview_idx;
for (i = 0; i < 8; i++) {
if (!w) w = 8;
w--;
if (userconf.ledprog_ena_mask & (1 << w)) {
preview_idx = w;
break;
}
}
}
break;
}
}
break;
}
}
}
static void ui_cursor_flash()
{
uint8_t color, flash;
uint8_t level = 0;
uint8_t new_state = 0;
color = userconf.cursor_color;
flash = userconf.cursor_flash;
switch (mode) {
case MODE_RUN: {
// flash the cursor in all but the auto-typing program
if (rgb_prog_idx != 4) {
if (!cursor_flash) {
new_state = 1;
// flash on/off toggle
cursor_state++;
cursor_state &= 1;
// set new flash rate
cursor_flash = cursor_flash_rates[flash] >> 1;
// clear cursor
cursor[0] = cursor[1] = cursor[2] = 0;
led_is_updated();
}
// set led to programmed brightness if it's supposed to be on
if (cursor_state) {
// first frame of on = not quite full brightness
level = (new_state) ? 160 : 255;
// at final frames, dim, but only for slower modes
if (flash < 5) {
if (cursor_flash < 12) {
level >>= (4 - (cursor_flash >> 2));
}
}
// set the level on the cursor
level = led_gamma(level);
if (cursor[color] != level) {
cursor[color] = level;
led_is_updated();
}
} else {
// clear any cursors that may have been left on
if (cursor[0] | cursor[1] | cursor[2]) {
cursor[0] = cursor[1] = cursor[2] = 0;
led_is_updated();
}
}
cursor_flash--;
}
break;
}
case MODE_PROGRAM: {
// cursor is on if this program is flagged as on
cursor[0] = (userconf.ledprog_ena_mask & (1 << preview_idx)) ? 127 : 0;
cursor[1] = 0;
cursor[2] = 0;
break;
}
case MODE_PARAMETER: {
// cursor is on when program is being edited
cursor[0] = rgb_prog_is_editing ? 127 : 0;
cursor[1] = 0;
cursor[2] = 0;
break;
}
}
}
void ui_init()
{
btn[0].hold = 420 >> 1;
btn[0].repeat = (1000 / 20) >> 1;
btn[0].cb_push = ui_btn_push_cb;
btn[0].cb_hold = ui_btn_hold_cb;
btn[0].cb_release = ui_btn_release_cb;
btn[1].hold = 420 >> 1;
btn[1].repeat = (1000 / 20) >> 1;
btn[1].cb_push = ui_btn_push_cb;
btn[1].cb_hold = ui_btn_hold_cb;
btn[1].cb_release = ui_btn_release_cb;
btn[2].hold = 420 >> 1;
btn[2].repeat = (1000 / 20) >> 1;
btn[2].cb_push = ui_btn_push_cb;
btn[2].cb_hold = ui_btn_hold_cb;
btn[2].cb_release = ui_btn_release_cb;
}
void ui_render()
{
uint8_t i;
@ -530,6 +574,7 @@ void ui_render()
// rapidly flash lsens
if ((tick & 0x7) == 0) {
adc_lsens_output();
LSENS_A_PORT->OUTDR ^= LSENS_A_PIN;
}
@ -574,6 +619,7 @@ void ui_render()
// slowly flash lsnes
if ((tick & 0x20) == 0) {
adc_lsens_output();
LSENS_A_PORT->OUTDR ^= LSENS_A_PIN;
}

View File

@ -10,6 +10,12 @@
#define UI_JOG_UP 0 // BTN0
#define UI_JOG_PUSH 1 // BTN1
#define UI_JOG_DN 2 // BTN2
extern const uint16_t cursor_flash_rates[8];

View File

@ -1,60 +1,21 @@
/********************************** (C) COPYRIGHT *******************************
/*******************************************************************************
* File Name : system_ch32x035.c
* Author : WCH
* Version : V1.0.0
* Date : 2023/04/06
* Description : CH32X035 Device Peripheral Access Layer System Source File.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include "ch32x035.h"
#include "global.h"
/*
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
* reset the HSI is used as SYSCLK source).
*/
/* Clock Definitions */
/*
#ifdef SYSCLK_FREQ_8MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_8MHz_HSI; // System Clock Frequency (Core Clock)
#elif defined SYSCLK_FREQ_12MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_12MHz_HSI; // System Clock Frequency (Core Clock)
#elif defined SYSCLK_FREQ_16MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_16MHz_HSI; // System Clock Frequency (Core Clock)
#elif defined SYSCLK_FREQ_24MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz_HSI; // System Clock Frequency (Core Clock)
#else
uint32_t SystemCoreClock = HSI_VALUE; // System Clock Frequency (Core Clock)
#endif
*/
uint32_t SystemCoreClock;
__I uint8_t AHBPrescTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8};
/* system_private_function_proto_types */
void SetSysClock(uint32_t clock);
/*
#ifdef SYSCLK_FREQ_8MHz_HSI
static void SetSysClockTo8_HSI( void );
#elif defined SYSCLK_FREQ_12MHz_HSI
static void SetSysClockTo12_HSI( void );
#elif defined SYSCLK_FREQ_16MHz_HSI
static void SetSysClockTo16_HSI( void );
#elif defined SYSCLK_FREQ_24MHz_HSI
static void SetSysClockTo24_HSI( void );
#elif defined SYSCLK_FREQ_48MHz_HSI
static void SetSysClockTo48_HSI( void );
#endif
*/
static void SetSysClockToX_HSI(uint32_t div, uint32_t latency);
static void SetSysClockToX_HSI(uint32_t div, uint8_t latency);
/*********************************************************************
@ -67,10 +28,16 @@ static void SetSysClockToX_HSI(uint32_t div, uint32_t latency);
*/
void SystemInit (void)
{
RCC->CTLR |= (uint32_t)0x00000001;
RCC->CFGR0 |= (uint32_t)0x00000050;
RCC->CFGR0 &= (uint32_t)0xF8FFFF5F;
SetSysClock(SYSCLK_FREQ_NORMAL);
// ensure internal oscillator is running and ready
RCC->CTLR |= (uint32_t)RCC_HSION;
while (!(RCC->CTLR & RCC_HSIRDY)) {};
// default to 8MHz before doing anything else
// this is POR default
RCC->CFGR0 = (uint32_t)RCC_HPRE_DIV6;
// set user-requested startup clock
SetSysClock(SYSCLK_FREQ_STARTUP);
}
/*********************************************************************
@ -87,12 +54,9 @@ void SystemCoreClockUpdate (void)
SystemCoreClock = HSI_VALUE;
tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
if(((RCC->CFGR0 & RCC_HPRE) >> 4) < 8)
{
if(((RCC->CFGR0 & RCC_HPRE) >> 4) < 8) {
SystemCoreClock /= tmp;
}
else
{
} else {
SystemCoreClock >>= tmp;
}
}
@ -107,10 +71,11 @@ void SystemCoreClockUpdate (void)
void SetSysClock(uint32_t clock)
{
switch (clock) {
case SYSCLK_FREQ_48MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV1, FLASH_ACTLR_LATENCY_2); break; }
case SYSCLK_FREQ_24MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV2, FLASH_ACTLR_LATENCY_1); break; }
case SYSCLK_FREQ_16MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV3, FLASH_ACTLR_LATENCY_1); break; }
case SYSCLK_FREQ_12MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV4, FLASH_ACTLR_LATENCY_0); break; }
case SYSCLK_FREQ_48MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV1, FLASH_ACTLR_LATENCY_2); break; }
case SYSCLK_FREQ_24MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV2, FLASH_ACTLR_LATENCY_1); break; }
case SYSCLK_FREQ_16MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV3, FLASH_ACTLR_LATENCY_1); break; }
case SYSCLK_FREQ_12MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV4, FLASH_ACTLR_LATENCY_0); break; }
case SYSCLK_FREQ_3MHz_HSI: { SetSysClockToX_HSI(RCC_HPRE_DIV16, FLASH_ACTLR_LATENCY_0); break; }
default: {
SetSysClockToX_HSI(RCC_HPRE_DIV6, FLASH_ACTLR_LATENCY_0);
clock = 8000000;
@ -119,36 +84,24 @@ void SetSysClock(uint32_t clock)
}
SystemCoreClock = clock;
/*
#ifdef SYSCLK_FREQ_8MHz_HSI
SetSysClockTo8_HSI();
#elif defined SYSCLK_FREQ_12MHz_HSI
SetSysClockTo12_HSI();
#elif defined SYSCLK_FREQ_16MHz_HSI
SetSysClockTo16_HSI();
#elif defined SYSCLK_FREQ_24MHz_HSI
SetSysClockTo24_HSI();
#elif defined SYSCLK_FREQ_48MHz_HSI
SetSysClockTo48_HSI();
#endif
*/
}
static void SetSysClockToX_HSI(uint32_t div, uint32_t latency)
static void SetSysClockToX_HSI(uint32_t div, uint8_t latency)
{
uint32_t actlr;
uint32_t cfgr0;
/* Flash 2 wait state */
actlr = FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
FLASH->ACTLR = (uint32_t)actlr | FLASH_ACTLR_LATENCY_2;
// set flash access to 2 wait states (boot default is 0 at 48MHz??)
FLASH->ACTLR = (uint32_t)FLASH_ACTLR_LATENCY_2;
// the vendor didn't wait here. but switching from slow to high speed
// often causes crashes without this.
asm("nop"); asm("nop"); asm("nop");
/* HCLK = SYSCLK = APB1 */
cfgr0 = RCC->CFGR0 &= (uint32_t)0xFFFFFF0F;
RCC->CFGR0 = (uint32_t)cfgr0 | (div & 0xf0);
cfgr0 = RCC->CFGR0 &= (uint32_t)~RCC_HPRE;
RCC->CFGR0 = (uint32_t)(cfgr0 | (div & 0xf0));
/* Flash set wait state */
FLASH->ACTLR = (uint32_t)actlr | (latency & 0x03);
FLASH->ACTLR = (uint32_t)(latency & 0x03);
}

View File

@ -18,6 +18,7 @@
#define SYSCLK_FREQ_3MHz_HSI 3000000
#define SYSCLK_FREQ_8MHz_HSI 8000000
#define SYSCLK_FREQ_12MHz_HSI 12000000
#define SYSCLK_FREQ_16MHz_HSI 16000000