212 lines
4.8 KiB
C
212 lines
4.8 KiB
C
/*
|
|
* HSC26 Artemis II
|
|
*
|
|
* 2026 true
|
|
*
|
|
* todo:
|
|
* - implement SPI master for accelerometer (done, blocking / basic)
|
|
* - configure ADC to get touchpads (done)
|
|
* - get main tick interrupt working
|
|
*
|
|
* - get user input working (buttons, touchpads)
|
|
* - configure accelerometer for wakeup / sleep
|
|
* - configure buttons to wake up in case of sleep
|
|
* - write lightshows
|
|
* - write userconfig stuff, save to end of FLASH
|
|
*/
|
|
|
|
|
|
#include "ch32x035_conf.h"
|
|
|
|
#include "comms/soft_i2c_master.h"
|
|
#include "comms/spi_master.h"
|
|
|
|
#include "driver/adc.h"
|
|
|
|
#include "led/matrix.h"
|
|
#include "led/ledprog.h"
|
|
|
|
#include "ui/btn.h"
|
|
|
|
/*
|
|
*@Note
|
|
***Only PA0--PA15 and PC16--PC17 support input pull-down.
|
|
*/
|
|
|
|
|
|
uint16_t cnt = 0;
|
|
volatile uint32_t wake_uptime = 0;
|
|
|
|
volatile uint8_t lp_render = 0;
|
|
|
|
|
|
|
|
inline void clk_init()
|
|
{
|
|
SystemCoreClockUpdate();
|
|
}
|
|
|
|
|
|
static inline 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);
|
|
}
|
|
|
|
static inline void gpio_init()
|
|
{
|
|
GPIO_InitTypeDef gpio = {0};
|
|
|
|
gpio.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
|
// PA0-PA4 touch0-touch4
|
|
gpio.GPIO_Mode = GPIO_Mode_AIN;
|
|
gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
|
|
GPIO_Init(GPIOA, &gpio);
|
|
// PB0 touch8
|
|
gpio.GPIO_Pin = GPIO_Pin_0;
|
|
GPIO_Init(GPIOB, &gpio);
|
|
// PC0 VBAT, PC3 touch13
|
|
gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_3;
|
|
GPIO_Init(GPIOC, &gpio);
|
|
|
|
// PA5 SCK, PA7 MOSI
|
|
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
gpio.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
|
|
GPIO_Init(GPIOA, &gpio);
|
|
|
|
// PA6 MISO
|
|
gpio.GPIO_Mode = GPIO_Mode_IPU;
|
|
gpio.GPIO_Pin = GPIO_Pin_6;
|
|
GPIO_Init(GPIOA, &gpio);
|
|
|
|
// PB3 LIS_INT, PB8 soft I2C SCL, PB9 soft I2C SDA, PB11 btn0, PB12 btn1
|
|
gpio.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11 | GPIO_Pin_12;
|
|
GPIO_Init(GPIOB, &gpio);
|
|
|
|
// PC16 USB DM (unused), PC17 USB DP (btn2)
|
|
gpio.GPIO_Mode = GPIO_Mode_IPD;
|
|
gpio.GPIO_Pin = GPIO_Pin_16 | GPIO_Pin_17;
|
|
GPIO_Init(GPIOC, &gpio);
|
|
|
|
// PB4 LSENS A, PB5 LSENS_K, PB6 SPI softCS, PB7 LED HWEN, PB10 STAT LED
|
|
GPIOB->BCR = 0x4f0;
|
|
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
|
gpio.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_10;
|
|
GPIO_Init(GPIOB, &gpio);
|
|
|
|
// PC14 CC1, PC15 CC2
|
|
// todo later
|
|
}
|
|
|
|
static inline 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);
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
* @fn main
|
|
*
|
|
* @brief Main program.
|
|
*
|
|
* @return none
|
|
*/
|
|
int main(void)
|
|
{
|
|
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
|
|
|
|
clk_init();
|
|
periphclk_init();
|
|
gpio_init();
|
|
|
|
// initialize led programs
|
|
lp_ribbon_init();
|
|
|
|
// set up soft I2C and configure lighting controller
|
|
i2cm_init();
|
|
matrix_init();
|
|
|
|
// set up touchsensing and light sensing
|
|
adc_init();
|
|
|
|
// set up accelerometer
|
|
spim_init();
|
|
|
|
// configure AWU to provide ~997Hz wakeup interrupt for main program
|
|
// TODO: confirm if the counter is reset / preloaded
|
|
awu_init();
|
|
|
|
while (1) {
|
|
// low-priority tasks like
|
|
// rendering next LED program output frame
|
|
if (lp_render) {
|
|
lp_render = 0;
|
|
lp_ribbon_upward(200, 3, 4);
|
|
}
|
|
|
|
// stay a while
|
|
// __WFI();
|
|
// PWR_EnterSTANDBYMode();
|
|
}
|
|
}
|
|
|
|
|
|
void AWU_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
|
|
|
void AWU_IRQHandler(void)
|
|
{
|
|
// clear interrupt flag
|
|
EXTI_ClearFlag(EXTI_Line27);
|
|
|
|
// SetSysClock_HSI(HCLK_24MHZ);
|
|
|
|
cnt++;
|
|
if (cnt >= 1000) {
|
|
cnt = 0;
|
|
wake_uptime++;
|
|
}
|
|
|
|
// handle render new frame at ~100Hz
|
|
if ((cnt % 10) == 0) {
|
|
lp_render = 1;
|
|
}
|
|
|
|
// send led matrix data to matrix chip
|
|
matrix_send();
|
|
|
|
// handle ADC
|
|
adc_next();
|
|
|
|
// handle buttons and touch sensors
|
|
btn_process();
|
|
} |