diff --git a/include/py32f0xx_it.h b/include/py32f0xx_it.h
index 447d294..f6405f0 100644
--- a/include/py32f0xx_it.h
+++ b/include/py32f0xx_it.h
@@ -1,24 +1,24 @@
/**
- ******************************************************************************
- * @file py32f0xx_it.h
- * @author MCU Application Team
- * @brief This file contains the headers of the interrupt handlers.
- ******************************************************************************
- * @attention
- *
- *
© Copyright (c) Puya Semiconductor Co.
- * All rights reserved.
- *
- * © Copyright (c) 2016 STMicroelectronics.
- * All rights reserved.
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
+ ******************************************************************************
+ * @file py32f0xx_it.h
+ * @author MCU Application Team
+ * @brief This file contains the headers of the interrupt handlers.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) Puya Semiconductor Co.
+ * All rights reserved.
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __PY32F0XX_IT_H
diff --git a/src/adc.c b/src/adc.c
index 1eaa915..6c076d9 100644
--- a/src/adc.c
+++ b/src/adc.c
@@ -56,12 +56,12 @@ static uint8_t calibrate = 0;
void adc_init()
{
- // ensure ADC is DISABLED to write to registers
+ // ensure ADC is DISABLED to write to registers
// this is opposite of what the RM says... the RM is wrong
- ADC1->CR = 0;
-
- // enable VREFINT
- ADC->CCR = ADC_CCR_VREFEN; // ADC_CCR_TSEN |
+ ADC1->CR = 0;
+
+ // enable VREFINT
+ ADC->CCR = ADC_CCR_VREFEN; // ADC_CCR_TSEN |
// enable end of conversion interrupt
ADC1->IER = ADC_IER_EOCIE;
@@ -73,18 +73,18 @@ void adc_init()
// default clock
ADC1->CFGR2 = 0;
- // configure scan channels, sampling time (11 = temp, 12 = vrefint)
- ADC1->SMPR = SAMPLE_TIME;
+ // configure scan channels, sampling time (11 = temp, 12 = vrefint)
+ ADC1->SMPR = SAMPLE_TIME;
ADC1->CHSELR = CONF_SET1_AN | PROBE_AN | // note: SET1 and VREFEXT are
- CONF_MODE_AN | CONF_SET0_AN | // shared and reflect one chan
- ADC_CHSELR_CHSEL12;
+ CONF_MODE_AN | CONF_SET0_AN | // shared and reflect one chan
+ ADC_CHSELR_CHSEL12;
// calibration configuration
- ADC1->CCSR = LL_ADC_CAL_SAMPLINGTIME_8CYCLES | ADC_CCSR_CALSEL;
+ ADC1->CCSR = LL_ADC_CAL_SAMPLINGTIME_8CYCLES | ADC_CCSR_CALSEL;
// and enable the interrupt source in the NVIC
NVIC_EnableIRQ(ADC_COMP_IRQn);
- NVIC_SetPriority(ADC_COMP_IRQn, 3);
+ NVIC_SetPriority(ADC_COMP_IRQn, 3);
}
/*
@@ -110,7 +110,7 @@ void adc_go()
ADC1->CR = ADC_CR_ADEN; // enable ADC
adc_seq = 0; // reset channel read sequence
ADC1->ISR = 0x1e; // clear all interrupt flags (per DS; mistranslated)
- ADC1->CR = ADC_CR_ADSTART | ADC_CR_ADEN; // begin conversion
+ ADC1->CR = ADC_CR_ADSTART | ADC_CR_ADEN; // begin conversion
}
/*
@@ -149,12 +149,12 @@ uint8_t adc_next()
}
// start ADC calibration
- if (calibrate) {
+ if (calibrate) {
adc_stop();
// disable ADC and start calibration
- ADC1->CR &= ~(ADC_CR_ADEN);
- ADC1->CR |= ADC_CR_ADCAL;
+ ADC1->CR &= ~(ADC_CR_ADEN);
+ ADC1->CR |= ADC_CR_ADCAL;
// clear cal flag; reset sequence to allow conversions to start
calibrate = 0;
@@ -170,7 +170,7 @@ uint8_t adc_next()
adc_go();
return ADC_SEQ_STARTUP;
- }
+ }
if (adc_seq == ADC_SEQ_RDY) {
// copy read data to history
diff --git a/src/flash.c b/src/flash.c
index d00f48c..e9a1cd8 100644
--- a/src/flash.c
+++ b/src/flash.c
@@ -27,36 +27,36 @@ struct UConf conf = {0};
*/
void flash_set_timing(uint32_t *timing_table)
{
- // load flash write timings from provided timing table
- // these are listed in the datasheet, but are also in ROM on the MCU
+ // load flash write timings from provided timing table
+ // these are listed in the datasheet, but are also in ROM on the MCU
- // note: if you decide to operate at a different frequency other than
- // a supported frequency for which timing tables do not exist
- // in ROM, you'll have to figure out what these values actually mean,
- // as the meaning of the values isn't documented in DS or RM
+ // note: if you decide to operate at a different frequency other than
+ // a supported frequency for which timing tables do not exist
+ // in ROM, you'll have to figure out what these values actually mean,
+ // as the meaning of the values isn't documented in DS or RM
- // note: the PRETPE and SMERTPE values seem to differ in MCU ROM from
- // the values listed in the reference manual. this is true of
- // all versions I have access to - English v1.0 and Chinese v1.2.
- // for example, @8MHz, RM says 0x5dc0 for PERTPE but ROM holds 0x6b60
- // in testing, either ROM or RM value seems to work.
+ // note: the PRETPE and SMERTPE values seem to differ in MCU ROM from
+ // the values listed in the reference manual. this is true of
+ // all versions I have access to - English v1.0 and Chinese v1.2.
+ // for example, @8MHz, RM says 0x5dc0 for PERTPE but ROM holds 0x6b60
+ // in testing, either ROM or RM value seems to work.
- // note: the datasheet doesn't say it anywhere, but if flash is not unlocked,
- // then flash timing values aren't writeable
+ // note: the datasheet doesn't say it anywhere, but if flash is not unlocked,
+ // then flash timing values aren't writeable
- // apply flash table timing values
- FLASH->TS0 = (timing_table[0] >> 0) & 0xff;
- FLASH->TS3 = (timing_table[0] >> 8) & 0xff;
- FLASH->TS1 = (timing_table[0] >> 16) & 0x1ff;
-
- FLASH->TS2P = (timing_table[1] >> 0) & 0xff;
- FLASH->TPS3 = (timing_table[1] >> 16) & 0x7ff;
+ // apply flash table timing values
+ FLASH->TS0 = (timing_table[0] >> 0) & 0xff;
+ FLASH->TS3 = (timing_table[0] >> 8) & 0xff;
+ FLASH->TS1 = (timing_table[0] >> 16) & 0x1ff;
+
+ FLASH->TS2P = (timing_table[1] >> 0) & 0xff;
+ FLASH->TPS3 = (timing_table[1] >> 16) & 0x7ff;
- FLASH->PERTPE = timing_table[2]; // & 0x1ffff;
- FLASH->SMERTPE = timing_table[3]; // & 0x1ffff;
+ FLASH->PERTPE = timing_table[2]; // & 0x1ffff;
+ FLASH->SMERTPE = timing_table[3]; // & 0x1ffff;
- FLASH->PRGTPE = (timing_table[4] >> 0) & 0xffff;
- FLASH->PRETPE = (timing_table[4] >> 16) & 0x7ff;
+ FLASH->PRGTPE = (timing_table[4] >> 0) & 0xffff;
+ FLASH->PRETPE = (timing_table[4] >> 16) & 0x7ff;
}
/*
@@ -66,48 +66,48 @@ void flash_set_timing(uint32_t *timing_table)
*/
__attribute__ ((long_call, section(".ramfunc"))) void flash_init()
{
- // unlock flash (necessary for writing timing registers
- FLASH->KEYR = FLASH_KEY1;
- FLASH->KEYR = FLASH_KEY2;
- while (FLASH->CR & FLASH_CR_LOCK); // still locked? then stall forever
-
- // configure flash timings
- flash_set_timing(FLASH_HSI_8MHz);
+ // unlock flash (necessary for writing timing registers
+ FLASH->KEYR = FLASH_KEY1;
+ FLASH->KEYR = FLASH_KEY2;
+ while (FLASH->CR & FLASH_CR_LOCK); // still locked? then stall forever
+
+ // configure flash timings
+ flash_set_timing(FLASH_HSI_8MHz);
- // is the PF2/NRST pin configured as reset?
- if ((FLASH->OPTR & FLASH_OPTR_NRST_MODE) == OB_RESET_MODE_RESET) {
- // it is but shouldn't be, so let's configure it as GPIO.
-
- // per datasheet, we must unlock FLASH->CR (already done above)
- // and then unlock OPTLOCK
- FLASH->OPTKEYR = FLASH_OPTKEY1;
- FLASH->OPTKEYR = FLASH_OPTKEY2;
- while (FLASH->CR & FLASH_CR_OPTLOCK); // somehow, OB is still locked
-
- // write new OPTR values
- FLASH->OPTR = OB_RESET_MODE_GPIO | OB_WWDG_SW | OB_IWDG_SW | OB_BOR_LEVEL_2p3_2p4 | FLASH_OPTR_RDP_LEVEL_0;
- // OB_BOR_ENABLE
+ // is the PF2/NRST pin configured as reset?
+ if ((FLASH->OPTR & FLASH_OPTR_NRST_MODE) == OB_RESET_MODE_RESET) {
+ // it is but shouldn't be, so let's configure it as GPIO.
+
+ // per datasheet, we must unlock FLASH->CR (already done above)
+ // and then unlock OPTLOCK
+ FLASH->OPTKEYR = FLASH_OPTKEY1;
+ FLASH->OPTKEYR = FLASH_OPTKEY2;
+ while (FLASH->CR & FLASH_CR_OPTLOCK); // somehow, OB is still locked
+
+ // write new OPTR values
+ FLASH->OPTR = OB_RESET_MODE_GPIO | OB_WWDG_SW | OB_IWDG_SW | OB_BOR_LEVEL_2p3_2p4 | FLASH_OPTR_RDP_LEVEL_0;
+ // OB_BOR_ENABLE
- // enable EOPIE (per DS, EOP isn't set unless EOPIE is set)
- // and signal that we want to write option bits,
- FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_OPTSTRT;
- // then trigger the write by writing to a random address shown in the DS
- *((__IO uint32_t *)(0x40022080)) = 0x55aa55aa;
+ // enable EOPIE (per DS, EOP isn't set unless EOPIE is set)
+ // and signal that we want to write option bits,
+ FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_OPTSTRT;
+ // then trigger the write by writing to a random address shown in the DS
+ *((__IO uint32_t *)(0x40022080)) = 0x55aa55aa;
- // wait for BSY to go low, then EOP to go high
- while (FLASH->SR & FLASH_SR_BSY);
- while (!(FLASH->SR & FLASH_SR_EOP));
+ // wait for BSY to go low, then EOP to go high
+ while (FLASH->SR & FLASH_SR_BSY);
+ while (!(FLASH->SR & FLASH_SR_EOP));
- // do an OBL_LAUNCH reset to load the new option bits
- // this must be done while OPTLOCK is cleared
- FLASH->CR |= FLASH_CR_OBL_LAUNCH;
+ // do an OBL_LAUNCH reset to load the new option bits
+ // this must be done while OPTLOCK is cleared
+ FLASH->CR |= FLASH_CR_OBL_LAUNCH;
- // as the MCU should have reset, we should never get here.
- while(1);
- }
+ // as the MCU should have reset, we should never get here.
+ while(1);
+ }
- // re-lock flash when done
- FLASH->CR = FLASH_CR_LOCK;
+ // re-lock flash when done
+ FLASH->CR = FLASH_CR_LOCK;
}
/*
@@ -115,46 +115,46 @@ __attribute__ ((long_call, section(".ramfunc"))) void flash_init()
*/
void flash_load_conf()
{
- int8_t i, j;
- uint8_t loaded = 0;
-
- struct UConf *fconf;
- uint32_t *f32;
- uint32_t *u32;
+ int8_t i, j;
+ uint8_t loaded = 0;
+
+ struct UConf *fconf;
+ uint32_t *f32;
+ uint32_t *u32;
- for (i = (UCONF_COUNT - 1); i >= 0; i--) {
- fconf = (struct UConf *)(UCONF_FLASH_START + (UCONF_SIZE * i));
- f32 = (uint32_t *)fconf;
-
- // empty flash = nothing here
- if (fconf->crc32 == 0xffffffff) continue;
+ for (i = (UCONF_COUNT - 1); i >= 0; i--) {
+ fconf = (struct UConf *)(UCONF_FLASH_START + (UCONF_SIZE * i));
+ f32 = (uint32_t *)fconf;
+
+ // empty flash = nothing here
+ if (fconf->crc32 == 0xffffffff) continue;
- // invalid header = skip
- if (fconf->conf_key != UCONF_KEY) continue;
-
- // calculate crc32
- CRC->CR = CRC_CR_RESET;
- while (CRC->CR & CRC_CR_RESET);
+ // invalid header = skip
+ if (fconf->conf_key != UCONF_KEY) continue;
+
+ // calculate crc32
+ CRC->CR = CRC_CR_RESET;
+ while (CRC->CR & CRC_CR_RESET);
- for (j = 0; j < ((UCONF_SIZE / 4) - 1); j++) {
- CRC->DR = f32[j];
- }
+ for (j = 0; j < ((UCONF_SIZE / 4) - 1); j++) {
+ CRC->DR = f32[j];
+ }
- // check crc32
- if (CRC->DR == f32[(UCONF_SIZE / 4) - 1]) {
- // it passes. copy to RAM and break out
- u32 = (uint32_t *)&conf;
- for (j = 0; j < (UCONF_SIZE / 4); j++) {
- *u32++ = *f32++;
- }
- loaded = 1;
- break;
- }
- }
+ // check crc32
+ if (CRC->DR == f32[(UCONF_SIZE / 4) - 1]) {
+ // it passes. copy to RAM and break out
+ u32 = (uint32_t *)&conf;
+ for (j = 0; j < (UCONF_SIZE / 4); j++) {
+ *u32++ = *f32++;
+ }
+ loaded = 1;
+ break;
+ }
+ }
- if (!loaded) {
- // default config of zeroes works
- }
+ if (!loaded) {
+ // default config of zeroes works
+ }
}
/*
@@ -162,38 +162,38 @@ void flash_load_conf()
*/
__attribute__ ((long_call, section(".ramfunc"))) void flash_erase_page(uint32_t addr)
{
- uint32_t primask;
+ uint32_t primask;
- // ensure flash is not busy
- while (FLASH->SR & FLASH_SR_BSY);
+ // ensure flash is not busy
+ while (FLASH->SR & FLASH_SR_BSY);
- // unlock flash
- FLASH->KEYR = FLASH_KEY1;
- FLASH->KEYR = FLASH_KEY2;
- while (FLASH->CR & FLASH_CR_LOCK); // still locked? then stall forever
+ // unlock flash
+ FLASH->KEYR = FLASH_KEY1;
+ FLASH->KEYR = FLASH_KEY2;
+ while (FLASH->CR & FLASH_CR_LOCK); // still locked? then stall forever
- // enable EOPIE (per DS, EOP isn't set unless EOPIE is set)
- // and signal that we want to erase a page
- FLASH->SR = FLASH_SR_EOP;
- FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_PER;
+ // enable EOPIE (per DS, EOP isn't set unless EOPIE is set)
+ // and signal that we want to erase a page
+ FLASH->SR = FLASH_SR_EOP;
+ FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_PER;
- // disable interrupts
- primask = __get_PRIMASK();
- __disable_irq();
+ // disable interrupts
+ primask = __get_PRIMASK();
+ __disable_irq();
- // trigger the erase by writing to a random address shown in the DS
- *((__IO uint32_t *)(addr)) = 0x55aa55aa;
+ // trigger the erase by writing to a random address shown in the DS
+ *((__IO uint32_t *)(addr)) = 0x55aa55aa;
- // ensure flash is not busy, then wait for end of programming
- while (FLASH->SR & FLASH_SR_BSY);
- while (!(FLASH->SR & FLASH_SR_EOP));
- FLASH->SR |= FLASH_SR_EOP;
+ // ensure flash is not busy, then wait for end of programming
+ while (FLASH->SR & FLASH_SR_BSY);
+ while (!(FLASH->SR & FLASH_SR_EOP));
+ FLASH->SR |= FLASH_SR_EOP;
- // re-lock flash
- FLASH->CR = FLASH_CR_LOCK;
-
- // re-enable interrupts
- __set_PRIMASK(primask);
+ // re-lock flash
+ FLASH->CR = FLASH_CR_LOCK;
+
+ // re-enable interrupts
+ __set_PRIMASK(primask);
}
/*
@@ -203,51 +203,51 @@ __attribute__ ((long_call, section(".ramfunc"))) void flash_erase_page(uint32_t
*/
__attribute__ ((long_call, section(".ramfunc"))) void flash_write_page(uint32_t addr, uint32_t *data)
{
- uint32_t primask;
-
- uint8_t i;
+ uint32_t primask;
+
+ uint8_t i;
- uint32_t *src;
- uint32_t *dst;
+ uint32_t *src;
+ uint32_t *dst;
- // ensure flash is not busy
- while (FLASH->SR & FLASH_SR_BSY);
+ // ensure flash is not busy
+ while (FLASH->SR & FLASH_SR_BSY);
- // unlock flash
- FLASH->KEYR = FLASH_KEY1;
- FLASH->KEYR = FLASH_KEY2;
- while (FLASH->CR & FLASH_CR_LOCK); // still locked? then stall forever
+ // unlock flash
+ FLASH->KEYR = FLASH_KEY1;
+ FLASH->KEYR = FLASH_KEY2;
+ while (FLASH->CR & FLASH_CR_LOCK); // still locked? then stall forever
- // enable EOPIE (per DS, EOP isn't set unless EOPIE is set)
- // and signal that we want to write a page
- FLASH->SR = FLASH_SR_EOP;
- FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_PG;
+ // enable EOPIE (per DS, EOP isn't set unless EOPIE is set)
+ // and signal that we want to write a page
+ FLASH->SR = FLASH_SR_EOP;
+ FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_PG;
- // disable interrupts
- primask = __get_PRIMASK();
- __disable_irq();
+ // disable interrupts
+ primask = __get_PRIMASK();
+ __disable_irq();
- // write data to flash
- src = data;
- dst = (uint32_t *)addr;
- for (i = 0; i < (FLASH_PAGE_SIZE / 4) - 1; i++) {
- *dst++ = *src++;
- }
+ // write data to flash
+ src = data;
+ dst = (uint32_t *)addr;
+ for (i = 0; i < (FLASH_PAGE_SIZE / 4) - 1; i++) {
+ *dst++ = *src++;
+ }
- // for the last word, enable the PGSTRT bit then write the word to commit to flash
- FLASH->CR |= FLASH_CR_PGSTRT;
- *dst = *src;
+ // for the last word, enable the PGSTRT bit then write the word to commit to flash
+ FLASH->CR |= FLASH_CR_PGSTRT;
+ *dst = *src;
- // ensure flash is not busy, then wait for end of programming
- while (FLASH->SR & FLASH_SR_BSY);
- while (!(FLASH->SR & FLASH_SR_EOP));
- FLASH->SR |= FLASH_SR_EOP;
+ // ensure flash is not busy, then wait for end of programming
+ while (FLASH->SR & FLASH_SR_BSY);
+ while (!(FLASH->SR & FLASH_SR_EOP));
+ FLASH->SR |= FLASH_SR_EOP;
- // re-lock flash
- FLASH->CR = FLASH_CR_LOCK;
-
- // re-enable interrupts
- __set_PRIMASK(primask);
+ // re-lock flash
+ FLASH->CR = FLASH_CR_LOCK;
+
+ // re-enable interrupts
+ __set_PRIMASK(primask);
}
/*
@@ -256,95 +256,95 @@ __attribute__ ((long_call, section(".ramfunc"))) void flash_write_page(uint32_t
*/
void flash_commit_conf()
{
- uint32_t i;
-
- uint8_t flash_idx = 0;
- uint8_t flash_full = 0;
+ uint32_t i;
+
+ uint8_t flash_idx = 0;
+ uint8_t flash_full = 0;
- struct UConf *fconf;
- uint32_t *f32, *u32;
- uint32_t write[(FLASH_PAGE_SIZE / 4)];
+ struct UConf *fconf;
+ uint32_t *f32, *u32;
+ uint32_t write[(FLASH_PAGE_SIZE / 4)];
- // find first free page index
- for (i = 0; i < UCONF_COUNT; i++) {
- fconf = (struct UConf *)(UCONF_FLASH_START + (UCONF_SIZE * i));
- if ((fconf->crc32 == 0xffffffff) || (fconf->conf_key != UCONF_KEY)) {
- flash_idx = i;
- break;
- }
- }
+ // find first free page index
+ for (i = 0; i < UCONF_COUNT; i++) {
+ fconf = (struct UConf *)(UCONF_FLASH_START + (UCONF_SIZE * i));
+ if ((fconf->crc32 == 0xffffffff) || (fconf->conf_key != UCONF_KEY)) {
+ flash_idx = i;
+ break;
+ }
+ }
- // if all pages are occupied, we'll erase all the pages
- if (i == UCONF_COUNT) {
- flash_full = 1;
- }
+ // if all pages are occupied, we'll erase all the pages
+ if (i == UCONF_COUNT) {
+ flash_full = 1;
+ }
- // ensure live config header is correct, and calculate CRC
- conf.conf_key = UCONF_KEY;
- conf.update_cntr++;
- u32 = (uint32_t *)&conf;
-
- CRC->CR = CRC_CR_RESET;
- while (CRC->CR & CRC_CR_RESET);
+ // ensure live config header is correct, and calculate CRC
+ conf.conf_key = UCONF_KEY;
+ conf.update_cntr++;
+ u32 = (uint32_t *)&conf;
+
+ CRC->CR = CRC_CR_RESET;
+ while (CRC->CR & CRC_CR_RESET);
- for (i = 0; i < (UCONF_SIZE / 4) - 1; i++) {
- CRC->DR = u32[i];
- }
- u32[(UCONF_SIZE / 4) - 1] = CRC->DR;
-
- // do we need to actually update data?
- // check checksum of our data against checksum of prior entry
- if (flash_idx) {
- fconf = (struct UConf *)(UCONF_FLASH_START + (UCONF_SIZE * (flash_idx - 1)));
- if (fconf->crc32 == conf.crc32) {
- // nothing to update; we can break out
- return;
- }
- }
+ for (i = 0; i < (UCONF_SIZE / 4) - 1; i++) {
+ CRC->DR = u32[i];
+ }
+ u32[(UCONF_SIZE / 4) - 1] = CRC->DR;
+
+ // do we need to actually update data?
+ // check checksum of our data against checksum of prior entry
+ if (flash_idx) {
+ fconf = (struct UConf *)(UCONF_FLASH_START + (UCONF_SIZE * (flash_idx - 1)));
+ if (fconf->crc32 == conf.crc32) {
+ // nothing to update; we can break out
+ return;
+ }
+ }
- // set empty write buffer to 0xff
- for (i = 0; i < 32; i++) {
- write[i] = 0xffffffff;
- }
+ // set empty write buffer to 0xff
+ for (i = 0; i < 32; i++) {
+ write[i] = 0xffffffff;
+ }
- // set write buffer
- u32 = (uint32_t *)write;
+ // set write buffer
+ u32 = (uint32_t *)write;
- // if this is the second entry in a flash page,
- // copy first half of flash page from ROM to the write buffer,
- // as our config size (64 bytes) is smaller than the page write size (128 bytes)
- if (flash_idx & 1) {
- f32 = (uint32_t *)fconf;
- for (i = 0; i < (UCONF_SIZE / 4); i++) {
- *u32++ = *f32++;
- }
- }
+ // if this is the second entry in a flash page,
+ // copy first half of flash page from ROM to the write buffer,
+ // as our config size (64 bytes) is smaller than the page write size (128 bytes)
+ if (flash_idx & 1) {
+ f32 = (uint32_t *)fconf;
+ for (i = 0; i < (UCONF_SIZE / 4); i++) {
+ *u32++ = *f32++;
+ }
+ }
- // correct flash_idx if it is out of bounds
- // (we will usually have 1-8, only getting 0 on the very first write)
- if (flash_idx == UCONF_COUNT) {
- flash_idx = 0;
- }
+ // correct flash_idx if it is out of bounds
+ // (we will usually have 1-8, only getting 0 on the very first write)
+ if (flash_idx == UCONF_COUNT) {
+ flash_idx = 0;
+ }
- // copy user config from RAM to write buffer at the appropriate offset
- f32 = (uint32_t *)&conf;
- for (i = 0; i < (UCONF_SIZE / 4); i++) {
- *u32++ = *f32++;
- }
+ // copy user config from RAM to write buffer at the appropriate offset
+ f32 = (uint32_t *)&conf;
+ for (i = 0; i < (UCONF_SIZE / 4); i++) {
+ *u32++ = *f32++;
+ }
- // we now need the flash page boundary, so remove lowest bit from flash_idx
- flash_idx &= ~1;
+ // we now need the flash page boundary, so remove lowest bit from flash_idx
+ flash_idx &= ~1;
- // erase this page
- flash_erase_page(UCONF_FLASH_START + (UCONF_SIZE * flash_idx));
+ // erase this page
+ flash_erase_page(UCONF_FLASH_START + (UCONF_SIZE * flash_idx));
- // commit to flash
- flash_write_page(UCONF_FLASH_START + (UCONF_SIZE * flash_idx), write);
+ // commit to flash
+ flash_write_page(UCONF_FLASH_START + (UCONF_SIZE * flash_idx), write);
- // if flash was full, erase other pages
- if (flash_full) {
- for (i = (UCONF_FLASH_START + FLASH_PAGE_SIZE); i < FLASH_END; i += FLASH_PAGE_SIZE) {
- flash_erase_page(i);
- }
- }
+ // if flash was full, erase other pages
+ if (flash_full) {
+ for (i = (UCONF_FLASH_START + FLASH_PAGE_SIZE); i < FLASH_END; i += FLASH_PAGE_SIZE) {
+ flash_erase_page(i);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/led.c b/src/led.c
index 73dc771..f07d245 100644
--- a/src/led.c
+++ b/src/led.c
@@ -129,31 +129,31 @@ void led_buzz(uint8_t buzz)
*/
void led_init()
{
- LL_TIM_InitTypeDef tim = {0};
+ LL_TIM_InitTypeDef tim = {0};
LL_TIM_OC_InitTypeDef pwm = {0};
// configure timer
- tim.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
- tim.CounterMode = LL_TIM_COUNTERMODE_UP;
- tim.Prescaler = 0;
- /* PWM period = 1000 */
- tim.Autoreload = 1000 - 1; // ~8KHz operation, roughly 10-bit
- tim.RepetitionCounter = 0;
-
- LL_TIM_Init(TIM_RGB, &tim);
+ tim.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
+ tim.CounterMode = LL_TIM_COUNTERMODE_UP;
+ tim.Prescaler = 0;
+ /* PWM period = 1000 */
+ tim.Autoreload = 1000 - 1; // ~8KHz operation, roughly 10-bit
+ tim.RepetitionCounter = 0;
+
+ LL_TIM_Init(TIM_RGB, &tim);
// configure timer outputs
pwm.OCMode = LL_TIM_OCMODE_PWM2;
- pwm.OCState = LL_TIM_OCSTATE_ENABLE;
- pwm.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
- pwm.OCIdleState = LL_TIM_OCIDLESTATE_LOW;
+ pwm.OCState = LL_TIM_OCSTATE_ENABLE;
+ pwm.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
+ pwm.OCIdleState = LL_TIM_OCIDLESTATE_LOW;
- pwm.CompareValue = 0;
- LL_TIM_OC_Init(TIM_RGB, TIM_RGB_R_CH, &pwm);
- LL_TIM_OC_Init(TIM_RGB, TIM_RGB_G_CH, &pwm);
- LL_TIM_OC_Init(TIM_RGB, TIM_RGB_B_CH, &pwm);
+ pwm.CompareValue = 0;
+ LL_TIM_OC_Init(TIM_RGB, TIM_RGB_R_CH, &pwm);
+ LL_TIM_OC_Init(TIM_RGB, TIM_RGB_G_CH, &pwm);
+ LL_TIM_OC_Init(TIM_RGB, TIM_RGB_B_CH, &pwm);
// clear all outputs
@@ -163,7 +163,7 @@ void led_init()
// enable timer
LL_TIM_EnableAllOutputs(TIM_RGB);
- LL_TIM_EnableCounter(TIM_RGB);
+ LL_TIM_EnableCounter(TIM_RGB);
// other setup
led_mode = MODE_RGB;
diff --git a/src/main.c b/src/main.c
index b067fdd..7cf1e0e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -31,68 +31,68 @@ uint32_t uptime;
static inline void gpio_init()
{
- // set registers manually instead of with
- // LL functions to save space.
- // though we probably don't _need_ this space...
+ // set registers manually instead of with
+ // LL functions to save space.
+ // though we probably don't _need_ this space...
- // PF2=OUT(high), low speed
- // unused pins are analog
- GPIOF->ODR = (1 << 2);
- GPIOF->MODER = 0xFFFFFCDF;
+ // PF2=OUT(high), low speed
+ // unused pins are analog
+ GPIOF->ODR = (1 << 2);
+ GPIOF->MODER = 0xFFFFFCDF;
// set I2C outputs as open drain
- GPIOA->OTYPER = 0x000c;
- // enable pullups on I2C outputs
- GPIOA->PUPDR = 0x24000050;
- // datasheet doesn't say what the speeds are for GPIO...
- // so set SWDIO to very high speed, PA12 low speed, all other outputs as high speed
- GPIOA->OSPEEDR = 0x2C002AA0;
- // alternate function select
- // PA6=T3C1, PA5=T3C2, PA4=T3C3, PA3=I2C_SCL, PA2=I2C_SDA
- GPIOA->AFR[0] = 0x01DDCC00;
+ GPIOA->OTYPER = 0x000c;
+ // enable pullups on I2C outputs
+ GPIOA->PUPDR = 0x24000050;
+ // datasheet doesn't say what the speeds are for GPIO...
+ // so set SWDIO to very high speed, PA12 low speed, all other outputs as high speed
+ GPIOA->OSPEEDR = 0x2C002AA0;
+ // alternate function select
+ // PA6=T3C1, PA5=T3C2, PA4=T3C3, PA3=I2C_SCL, PA2=I2C_SDA
+ GPIOA->AFR[0] = 0x01DDCC00;
// PA12=OUT(high)
GPIOA->ODR = (1 << 12);
- // PA14=ALT, PA13=ALT, PA12=OUT, PA11=OUT
- // PA7=AN, PA6=AF, PA5=AF, PA4=AF
- // PA3=AF, PA2=AF, PA1=AN, PA0=AN
- // unused pins are digital inputs
- GPIOA->MODER = 0x2900EAAF;
-
+ // PA14=ALT, PA13=ALT, PA12=OUT, PA11=OUT
+ // PA7=AN, PA6=AF, PA5=AF, PA4=AF
+ // PA3=AF, PA2=AF, PA1=AN, PA0=AN
+ // unused pins are digital inputs
+ GPIOA->MODER = 0x2900EAAF;
+
- // PB1=OUT(HIGH), PB0=AN
- // unused pins are analog, all outputs are low speed
- GPIOB->OSPEEDR = 0x00000000;
+ // PB1=OUT(HIGH), PB0=AN
+ // unused pins are analog, all outputs are low speed
+ GPIOB->OSPEEDR = 0x00000000;
GPIOB->ODR = (1 << 1);
- GPIOB->MODER = 0xfffffff7;
+ GPIOB->MODER = 0xfffffff7;
}
static inline void clk_init()
{
- // run all buses at core clock speed
- LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
- LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
+ // run all buses at core clock speed
+ LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
+ LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
- // enable GPIO and peripheral clocks
- RCC->IOPENR = LL_IOP_GRP1_PERIPH_GPIOA |
- LL_IOP_GRP1_PERIPH_GPIOB |
- LL_IOP_GRP1_PERIPH_GPIOF;
+ // enable GPIO and peripheral clocks
+ RCC->IOPENR = LL_IOP_GRP1_PERIPH_GPIOA |
+ LL_IOP_GRP1_PERIPH_GPIOB |
+ LL_IOP_GRP1_PERIPH_GPIOF;
- RCC->AHBENR |= LL_AHB1_GRP1_PERIPH_CRC;
+ RCC->AHBENR |= LL_AHB1_GRP1_PERIPH_CRC;
- RCC->APBENR1 = LL_APB1_GRP1_PERIPH_TIM3;
- RCC->APBENR2 = LL_APB1_GRP2_PERIPH_ADC1;
+ RCC->APBENR1 = LL_APB1_GRP1_PERIPH_TIM3;
+ RCC->APBENR2 = LL_APB1_GRP2_PERIPH_ADC1;
}
static inline void systick_init()
{
- // configure nvic
- NVIC_EnableIRQ(SysTick_IRQn);
- NVIC_SetPriority(SysTick_IRQn, 0);
-
- // configure timebase with interrupt at 4096Hz
- // this assumes we'll always be running at 8MHz
- SysTick_Config((8000000 / 4096) - 1);
+ // configure nvic
+ NVIC_EnableIRQ(SysTick_IRQn);
+ NVIC_SetPriority(SysTick_IRQn, 0);
+
+ // configure timebase with interrupt at 4096Hz
+ // this assumes we'll always be running at 8MHz
+ SysTick_Config((8000000 / 4096) - 1);
}
/*
@@ -101,35 +101,35 @@ static inline void systick_init()
*/
int main()
{
- // base hardware initialization
- clk_init();
- flash_init(); // also configures option bytes to enable PF2, if necessary
- gpio_init();
+ // base hardware initialization
+ clk_init();
+ flash_init(); // also configures option bytes to enable PF2, if necessary
+ gpio_init();
- // load configuration from flash
- flash_load_conf();
+ // load configuration from flash
+ flash_load_conf();
- // peripheral initialization
- led_init();
- adc_init();
+ // peripheral initialization
+ led_init();
+ adc_init();
- // mainline loop interrupt
- systick_init();
+ // mainline loop interrupt
+ systick_init();
- // let's go
- __enable_irq();
+ // let's go
+ __enable_irq();
- while (1) {
- // run LED programs out of interrupt context at 256Hz
- if (!(ctr & 0xf)) {
- if (userio_get_mode() == MODE_FUN) {
- rgbprog_run();
- }
- }
+ while (1) {
+ // run LED programs out of interrupt context at 256Hz
+ if (!(ctr & 0xf)) {
+ if (userio_get_mode() == MODE_FUN) {
+ rgbprog_run();
+ }
+ }
- // nap time
- __WFI();
- }
+ // nap time
+ __WFI();
+ }
}
/*
@@ -140,43 +140,43 @@ volatile uint16_t adc_sec; // ADC cycles per second (used w/debugger)
void SysTick_Handler(void)
{
- uint16_t cs;
+ uint16_t cs;
- ctr++;
+ ctr++;
- // run LED programs quickly
- led_next();
+ // run LED programs quickly
+ led_next();
- // limit counter to 4096 counts
- ctr &= 0xfff;
- if (!ctr) {
- uptime++;
- adc_sec = adc_ctr;
- adc_ctr = 0;
- }
+ // limit counter to 4096 counts
+ ctr &= 0xfff;
+ if (!ctr) {
+ uptime++;
+ adc_sec = adc_ctr;
+ adc_ctr = 0;
+ }
- // run main logic at 2048Hz
- if (!(ctr & 0x1)) {
- // shifted counter for use in the program
- cs = ctr >> 1;
+ // run main logic at 2048Hz
+ if (!(ctr & 0x1)) {
+ // shifted counter for use in the program
+ cs = ctr >> 1;
// adc tested to result in about 61 reads/second
if (!adc_next()) {
// adc has new computed results
- adc_ctr++;
+ adc_ctr++;
- // start using ADC results only after the first cycle
+ // start using ADC results only after the first cycle
if (uptime || cs) {
- // figure out knobs, buttons, switches
+ // figure out knobs, buttons, switches
userio_parse();
- // initialize randomness
- rand_init((knob[0] << 8) | knob[1]);
+ // initialize randomness
+ rand_init((knob[0] << 8) | knob[1]);
- // show probe measurement results, or if not in a measurement mode,
- // run RGBLED program
- probe_measure();
+ // show probe measurement results, or if not in a measurement mode,
+ // run RGBLED program
+ probe_measure();
}
}
- }
+ }
}
diff --git a/src/py32f0xx_it.c b/src/py32f0xx_it.c
index 4e5664b..f0356bd 100644
--- a/src/py32f0xx_it.c
+++ b/src/py32f0xx_it.c
@@ -1,24 +1,24 @@
/**
- ******************************************************************************
- * @file py32f0xx_it.c
- * @author MCU Application Team
- * @brief Interrupt Service Routines.
- ******************************************************************************
- * @attention
- *
- * © Copyright (c) Puya Semiconductor Co.
- * All rights reserved.
- *
- * © Copyright (c) 2016 STMicroelectronics.
- * All rights reserved.
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
+ ******************************************************************************
+ * @file py32f0xx_it.c
+ * @author MCU Application Team
+ * @brief Interrupt Service Routines.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) Puya Semiconductor Co.
+ * All rights reserved.
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
/* Includes ------------------------------------------------------------------*/
#include "py32f0xx_it.h"
@@ -36,15 +36,15 @@
/* Cortex-M0+ Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
- * @brief This function handles Non maskable interrupt.
- */
+ * @brief This function handles Non maskable interrupt.
+ */
void NMI_Handler(void)
{
}
/**
- * @brief This function handles Hard fault interrupt.
- */
+ * @brief This function handles Hard fault interrupt.
+ */
void HardFault_Handler(void)
{
while (1)
@@ -53,22 +53,22 @@ void HardFault_Handler(void)
}
/**
- * @brief This function handles System service call via SWI instruction.
- */
+ * @brief This function handles System service call via SWI instruction.
+ */
void SVC_Handler(void)
{
}
/**
- * @brief This function handles Pendable request for system service.
- */
+ * @brief This function handles Pendable request for system service.
+ */
void PendSV_Handler(void)
{
}
/**
- * @brief This function handles System tick timer.
- */
+ * @brief This function handles System tick timer.
+ */
/*
void SysTick_Handler(void)
{
diff --git a/src/userio.c b/src/userio.c
index 00c624b..f298277 100644
--- a/src/userio.c
+++ b/src/userio.c
@@ -58,7 +58,7 @@ static uint8_t mode = 0xff;
static uint8_t mode_next;
static uint8_t mode_count;
static const int16_t mode_targets[] = {
- MODE_CONT_TARGET, MODE_FUN_TARGET, MODE_DIODE_TARGET
+ MODE_CONT_TARGET, MODE_FUN_TARGET, MODE_DIODE_TARGET
};
uint8_t knob[2];
@@ -70,11 +70,11 @@ static uint16_t btn_held = 0;
void userio_parse()
{
- uint8_t i;
- int16_t m, w;
+ uint8_t i;
+ int16_t m, w;
uint32_t x;
-
- // button
+
+ // button
{
// debounce is handled by the fact that we've had to have averaged
// about 16ms of measured hold time below the zero threshold.
@@ -92,7 +92,7 @@ void userio_parse()
}
}
- // mode
+ // mode
if (!btn) {
for (i = 0; i < 4; i++) {
// clear mode_count if we aren't actively changing modes