diff --git a/firmware/.cproject b/firmware/.cproject
index 3c7c55f..844e6ed 100644
--- a/firmware/.cproject
+++ b/firmware/.cproject
@@ -91,7 +91,7 @@
-
+
@@ -230,7 +230,7 @@
-
+
diff --git a/firmware/.template b/firmware/.template
index 0665099..3baab94 100644
--- a/firmware/.template
+++ b/firmware/.template
@@ -10,10 +10,10 @@ PeripheralVersion=1.9
Description=Website: https://www.wch.cn/products/CH32X035.html?\nROM(byte): 62K, SRAM(byte): 20K, CHIP PINS: 28, GPIO PORTS: 27.\nWCH CH32X035 series of mainstream MCUs covers the needs of a large variety of applications in the industrial,medical and consumer markets. High performance with first-class peripherals and low-power,low-voltage operation is paired with a high level of integration at accessible prices with a simple architecture and easy-to-use tools.
Mcu Type=CH32X035
Address=0x08000000
-Target Path=obj/CH32X035G8U6.hex
+Target Path=obj\hsc26_art2.hex
Exe Path=
Exe Arguments=
-CLKSpeed=1
+CLKSpeed=2
DebugInterfaceMode=0
Erase All=true
Program=true
diff --git a/firmware/app/comms/soft_i2c_master.c b/firmware/app/comms/soft_i2c_master.c
index 96b6f28..8ae476e 100644
--- a/firmware/app/comms/soft_i2c_master.c
+++ b/firmware/app/comms/soft_i2c_master.c
@@ -46,27 +46,31 @@
#define SDA_PIN 9
#define SDA_BIT (1 << SDA_PIN)
-#define SDA_CONFOFF ((SDA_PIN % 8) * 4)
+#define SDA_CONFOFFS ((SDA_PIN % 8) * 4)
#define SDA_GPIO GPIOB
-#define SDA_CFGR GPIOB->CFGHR
+#define SDA_CFGR SDA_GPIO->CFGHR
#define SCL_PIN 8
#define SCL_BIT (1 << SCL_PIN)
-#define SCL_CONFOFF ((SCL_PIN % 8) * 4)
+#define SCL_CONFOFFS ((SCL_PIN % 8) * 4)
#define SCL_GPIO GPIOB
-#define SCL_CFGR GPIOB->CFGHR
+#define SCL_CFGR SCL_GPIO->CFGHR
#define GPIO_CFG_LO 0x1
-#define GPIO_CFG_HI 0x8
+#define GPIO_CFG_HI 0x4
-#define SDA_IN_HI() { SDA_CFGR &= ~(0xf << SDA_CONFOFF); SDA_CFGR |= (GPIO_CFG_HI << SDA_CONFOFF); }
-#define SDA_OUTLO() { SDA_CFGR &= ~(0xf << SDA_CONFOFF); SDA_CFGR |= (GPIO_CFG_LO << SDA_CONFOFF); }
+#define SDA_IN_HI() { uint32_t sda = SDA_CFGR & ~(0xf << SDA_CONFOFFS); \
+ sda |= (GPIO_CFG_HI << SDA_CONFOFFS); SDA_CFGR = sda; }
+#define SDA_OUTLO() { uint32_t sda = SDA_CFGR & ~(0xf << SDA_CONFOFFS); \
+ sda |= (GPIO_CFG_LO << SDA_CONFOFFS); SDA_CFGR = sda; }
#define SDA_SET_LO() SDA_GPIO->BCR = SDA_BIT
#define SDA_GET() ( SDA_GPIO->INDR & SDA_BIT )
-#define SCL_IN_HI() { SCL_CFGR &= ~(0xf << SCL_CONFOFF); SCL_CFGR |= (GPIO_CFG_HI << SCL_CONFOFF); }
-#define SCL_OUTLO() { SCL_CFGR &= ~(0xf << SCL_CONFOFF); SCL_CFGR |= (GPIO_CFG_LO << SCL_CONFOFF); }
+#define SCL_IN_HI() { uint32_t scl = SCL_CFGR & ~(0xf << SCL_CONFOFFS); \
+ scl |= (GPIO_CFG_HI << SCL_CONFOFFS); SCL_CFGR = scl; }
+#define SCL_OUTLO() { uint32_t scl = SCL_CFGR & ~(0xf << SCL_CONFOFFS); \
+ scl |= (GPIO_CFG_LO << SCL_CONFOFFS); SCL_CFGR = scl; }
#define SCL_SET_LO() SCL_GPIO->BCR = SCL_BIT
#define SCL_GET() ( SCL_GPIO->INDR & SCL_BIT )
diff --git a/firmware/app/led/ledprog.c b/firmware/app/led/ledprog.c
index e1815c1..f3dcc58 100644
--- a/firmware/app/led/ledprog.c
+++ b/firmware/app/led/ledprog.c
@@ -55,16 +55,16 @@ void lp_ribbon_upward(uint16_t wait, uint16_t rate, uint8_t fade)
x = s[2]++;
// are we done?
- if (x > sizeof(led_set.ribbon)) {
+ if (x >= sizeof(led_set.ribbon)) {
s[0] = 0;
s[1] = wait;
break;
}
// fade in and up
- led_set.ribbon[x] = 0x40;
- if (x) led_set.ribbon[x - 1] = 0x70;
- if (x > 1) led_set.ribbon[x - 2] = 0xff;
+ led_set.ribbon[x] = 0x20;
+ if (x) led_set.ribbon[x - 1] = 0x66;
+ if (x > 1) led_set.ribbon[x - 2] = 0xd0;
}
}
@@ -73,7 +73,7 @@ void lp_ribbon_upward(uint16_t wait, uint16_t rate, uint8_t fade)
if (led_set.ribbon[i] >= fade) {
led_set.ribbon[i] -= fade;
} else {
- led_set.ribbon[i] = 0;
+ led_set.ribbon[i] >>= 1;
}
}
diff --git a/firmware/app/led/matrix.c b/firmware/app/led/matrix.c
index 9925eb9..e51a33a 100644
--- a/firmware/app/led/matrix.c
+++ b/firmware/app/led/matrix.c
@@ -13,7 +13,7 @@
-#define AW20X_DIM 31 // initial global current setting
+#define AW20X_DIM 28 // initial global current setting
#define AW20X_COLS 6
#define AW20X_ROWS 12
@@ -24,17 +24,16 @@
AW20x awled;
-static uint8_t awled_fade[AW20X_FADE_COUNT];
+uint8_t awled_fade[AW20X_FADE_COUNT];
static uint8_t led_matrix_needs_update = 0;
-uint16_t led_map_size;
const LedMap led_map = {
// map is 1-based to match part numbers on the board
- { // ribbon
- 1, 25, 13, 49,
+ .ribbon = { // ribbon
+ 13, 25, 1, 49,
37, 14,
- 28, 2, 38,
+ 26, 2, 38,
50, 3,
27, 15,
39, 51,
@@ -54,19 +53,20 @@ const LedMap led_map = {
55, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8, 20, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+ 8, 0, 0, 20, 0, 0, 32,
0, 0
},
- { // "A"
+ .a = { // "A"
9, 21, 33, 0, 0, 0, 45, 57, 10,
22,
34, 46, 58, 11, 23, 35, 47, 59, 12
},
- { // "//" left one
+ .ii_lf = { // "//" left one
61, 62, 63, 64, 44
},
- { // "//" right one
+ .ii_rt = { // "//" right one
60, 48, 36, 24, 56
}
};
@@ -95,8 +95,6 @@ void matrix_init()
aw20x_set_dim_global(&awled, AW20X_DIM);
aw20x_set_fade(&awled);
aw20x_led_enable_range(&awled, 0, (AW20X_COLS * AW20X_MAX_ROWS) - 1);
-
- led_map_size = sizeof(led_map.ribbon) + sizeof(led_map.a) + sizeof(led_map.ii_lf) + sizeof(led_map.ii_rt);
}
void matrix_flag_update()
@@ -104,9 +102,14 @@ void matrix_flag_update()
led_matrix_needs_update = 1;
}
+/*
+static uint8_t delay = 0;
+static uint8_t work = 0;
+*/
+
void matrix_send()
{
- int8_t i;
+ uint32_t i;
uint8_t *fade = awled_fade;
uint8_t *map = (uint8_t *)&led_map;
uint8_t *set = (uint8_t *)&led_set;
@@ -115,14 +118,35 @@ void matrix_send()
led_matrix_needs_update = 0;
// remap data for sending
- for (i = 0; i < led_map_size; i++) {
- if ((*map) & (*map <= AW20X_FADE_COUNT)) {
- fade[*map - 1] = *set;
+ for (i = 0; i < sizeof(led_map); i++) {
+ if ((*map) && ((*map) <= AW20X_FADE_COUNT)) {
+ fade[(*map) - 1] = *set;
}
- map++;
- set++;
+ map++; set++;
}
+ /* testing
+ if (delay) {
+ delay--;
+ } else {
+ delay = 20;
+ for (int i = 0; i < sizeof(led_map.ribbon); i++) {
+ if (led_map.ribbon[i]) {
+ awled_fade[led_map.ribbon[i] - 1] = 0;
+ }
+ }
+
+ if (led_map.ribbon[work]) {
+ awled_fade[led_map.ribbon[work] - 1] = 0xff;
+ }
+ work++;
+
+ if (work >= sizeof(led_map.ribbon)) work = 0;
+
+ matrix_flag_update();
+ }
+ */
+
aw20x_set_fade(&awled);
}
}
\ No newline at end of file
diff --git a/firmware/app/led/matrix.h b/firmware/app/led/matrix.h
index 8effc38..785db4d 100644
--- a/firmware/app/led/matrix.h
+++ b/firmware/app/led/matrix.h
@@ -13,7 +13,7 @@
// 0 index = bottom.
// 0 value = no LED here.
typedef struct LedMap {
- uint8_t ribbon[80]; // a "linear" bottom to top map, with gaps for the spacing.
+ uint8_t ribbon[88]; // a "linear" bottom to top map, with gaps for the spacing.
uint8_t a[20]; // left to right, bottom to apex to bottom.
uint8_t ii_lf[5]; // top to bottom.
uint8_t ii_rt[5]; // top to bottom.
@@ -22,6 +22,7 @@ typedef struct LedMap {
extern LedMap led_set;
+extern uint8_t awled_fade[6*12];
diff --git a/firmware/app/main.c b/firmware/app/main.c
index 0329c6c..2bf7f00 100644
--- a/firmware/app/main.c
+++ b/firmware/app/main.c
@@ -47,10 +47,15 @@ void clk_init()
void periphclk_init()
{
+ // needed for GPIO, remap, ADC, SPI
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO |
RCC_APB2Periph_ADC1 | RCC_APB2Periph_SPI1, ENABLE);
+ // may be needed for AWU
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
+
+ // needed for DMA, USBPD
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_USBPD, ENABLE);
}
@@ -100,6 +105,31 @@ void gpio_init()
// todo later
}
+void awu_init()
+{
+ NVIC_InitTypeDef nvic;
+ EXTI_InitTypeDef exti = {0};
+
+ // configure AWU
+ AWU_SetPrescaler(AWU_Prescaler_1);
+ AWU_SetWindowValue(0x2f);
+ AutoWakeUpCmd(ENABLE);
+
+ // configure EXTI line
+ exti.EXTI_Line = EXTI_Line27;
+ exti.EXTI_Mode = EXTI_Mode_Interrupt;
+ exti.EXTI_Trigger = EXTI_Trigger_Rising;
+ exti.EXTI_LineCmd = ENABLE;
+ EXTI_Init(&exti);
+
+ // configure PFIC interrupt
+ nvic.NVIC_IRQChannel = AWU_IRQn;
+ nvic.NVIC_IRQChannelPreemptionPriority = 0;
+ nvic.NVIC_IRQChannelSubPriority = 0;
+ nvic.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&nvic);
+}
+
/*********************************************************************
@@ -130,22 +160,20 @@ int main(void)
// set up accelerometer
spim_init();
- // configure AWU to provide ~1440Hz wakeup interrupt for main program
+ // configure AWU to provide ~997Hz wakeup interrupt for main program
// TODO: confirm if the counter is reset / preloaded
- AWU_SetPrescaler(AWU_Prescaler_32);
- AWU_SetWindowValue(0x3e);
- AutoWakeUpCmd(ENABLE);
+ awu_init();
while (1) {
// low-priority tasks like
// rendering next LED program output frame
if (lp_render) {
lp_render = 0;
- lp_ribbon_upward(800, 3, 2);
+ lp_ribbon_upward(200, 3, 4);
}
// stay a while
- // __WFI();
+ __WFI();
}
}
@@ -154,13 +182,13 @@ void AWU_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void AWU_IRQHandler(void)
{
cnt++;
- if (cnt >= 1440) {
+ if (cnt >= 1000) {
cnt = 0;
wake_uptime++;
}
- // handle render new frame at 90Hz
- if ((cnt & 0xf) == 0) {
+ // handle render new frame at ~100Hz
+ if ((cnt % 10) == 0) {
lp_render = 1;
}
@@ -172,4 +200,7 @@ void AWU_IRQHandler(void)
// handle buttons
// do we sleep?
+
+ // clear interrupt
+ EXTI_ClearFlag(EXTI_Line27);
}
\ No newline at end of file
diff --git a/firmware/app/system_ch32x035.c b/firmware/app/system_ch32x035.c
index 2f32b9c..f9bd572 100644
--- a/firmware/app/system_ch32x035.c
+++ b/firmware/app/system_ch32x035.c
@@ -10,6 +10,7 @@
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include "ch32x035.h"
+#include "system_ch32x035.h"
/*
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
@@ -90,10 +91,10 @@ void SetSysClock_HSI(uint32_t divider)
// set wait states depending on speed
if (divider > RCC_HPRE_DIV1) { // 48MHz is already set to 2 cycles
- if (divider >= RCC_HPRE_DIV1) { // 24MHz is 1 cycle
- actlr |= (uint32_t)FLASH_ACTLR_LATENCY_0;
- } else { // all others are 0 cycle
+ if (divider == RCC_HPRE_DIV2) { // 24MHz is 1 cycle
actlr |= (uint32_t)FLASH_ACTLR_LATENCY_1;
+ } else { // all others are 0 cycle
+ actlr |= (uint32_t)FLASH_ACTLR_LATENCY_0;
}
FLASH->ACTLR = actlr;
diff --git a/firmware/hsc26_art2.launch b/firmware/hsc26_art2.launch
index 7e24111..65451ad 100644
--- a/firmware/hsc26_art2.launch
+++ b/firmware/hsc26_art2.launch
@@ -40,8 +40,8 @@
-
-
+
+
@@ -54,7 +54,7 @@
-
+
diff --git a/firmware/hsc26_art2.wvproj b/firmware/hsc26_art2.wvproj
index 9707ea8..580954d 100644
--- a/firmware/hsc26_art2.wvproj
+++ b/firmware/hsc26_art2.wvproj
@@ -259,7 +259,7 @@
},
"createFlash": {
"enabled": true,
- "outputFileFormat": "ihex",
+ "outputFileFormat": "ihexAndbinary",
"copy_only_section_text": false,
"copy_only_section_data": false,
"copy_only_sections": [],
@@ -313,8 +313,8 @@
"flashConfig": {
"mcutype": "CH32X035",
"address": "0x08000000",
- "target_path": "obj/hsc26_art2.hex",
- "clkSpeed": "High",
+ "target_path": "obj\\hsc26_art2.hex",
+ "clkSpeed": "Middle",
"debug_interface_mode": "1-wire serial",
"erase": true,
"program": true,