use rtc for timing
This commit is contained in:
parent
6790246c3c
commit
c61598fe95
14
cfg/chconf.h
14
cfg/chconf.h
@ -451,11 +451,11 @@
|
||||
* @note This macro can be used to activate a power saving mode.
|
||||
*/
|
||||
#define CH_CFG_IDLE_ENTER_HOOK() { \
|
||||
RCC->ICSCR = (RCC->ICSCR & ~RCC_ICSCR_MSIRANGE_Msk); \
|
||||
while (!(RCC->CR & RCC_CR_MSIRDY)); \
|
||||
PWR->CR &= ~PWR_CR_LPRUN; \
|
||||
PWR->CR |= PWR_CR_LPRUN; \
|
||||
}
|
||||
// RCC->ICSCR = (RCC->ICSCR & ~RCC_ICSCR_MSIRANGE_Msk);
|
||||
// while (!(RCC->CR & RCC_CR_MSIRDY));
|
||||
// PWR->CR &= ~PWR_CR_LPRUN;
|
||||
// PWR->CR |= PWR_CR_LPRUN;
|
||||
|
||||
/**
|
||||
* @brief Idle thread leave hook.
|
||||
@ -464,10 +464,10 @@
|
||||
* @note This macro can be used to deactivate a power saving mode.
|
||||
*/
|
||||
#define CH_CFG_IDLE_LEAVE_HOOK() { \
|
||||
RCC->ICSCR |= 6 << RCC_ICSCR_MSIRANGE_Pos; \
|
||||
while (!(RCC->CR & RCC_CR_MSIRDY)); \
|
||||
PWR->CR &= ~PWR_CR_LPRUN; \
|
||||
}
|
||||
// RCC->ICSCR |= 6 << RCC_ICSCR_MSIRANGE_Pos;
|
||||
// while (!(RCC->CR & RCC_CR_MSIRDY));
|
||||
// PWR->CR &= ~PWR_CR_LPRUN;
|
||||
|
||||
/**
|
||||
* @brief System halt hook.
|
||||
|
@ -128,7 +128,7 @@
|
||||
* @brief Enables the RTC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_RTC FALSE
|
||||
#define HAL_USE_RTC TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -44,22 +44,22 @@
|
||||
#define STM32_PLS STM32_PLS_LEV4
|
||||
#define STM32_HSI16_ENABLED TRUE
|
||||
#define STM32_HSI16_DIVIDER_ENABLED FALSE
|
||||
#define STM32_LSI_ENABLED FALSE
|
||||
#define STM32_LSI_ENABLED TRUE
|
||||
#define STM32_HSE_ENABLED FALSE
|
||||
#define STM32_LSE_ENABLED FALSE
|
||||
#define STM32_ADC_CLOCK_ENABLED TRUE
|
||||
#define STM32_MSIRANGE STM32_MSIRANGE_4M
|
||||
#define STM32_SW STM32_SW_MSI
|
||||
#define STM32_PLLSRC STM32_PLLSRC_HSI16
|
||||
#define STM32_PLLMUL_VALUE 3
|
||||
#define STM32_PLLDIV_VALUE 4
|
||||
#define STM32_PLLSRC STM32_PLLSRC_NONE
|
||||
#define STM32_PLLMUL_VALUE 1
|
||||
#define STM32_PLLDIV_VALUE 8
|
||||
#define STM32_HPRE STM32_HPRE_DIV1
|
||||
#define STM32_PPRE1 STM32_PPRE1_DIV1
|
||||
#define STM32_PPRE2 STM32_PPRE2_DIV1
|
||||
#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
|
||||
#define STM32_MCOPRE STM32_MCOPRE_DIV1
|
||||
#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK
|
||||
#define STM32_RTCPRE STM32_RTCPRE_DIV2
|
||||
#define STM32_RTCSEL STM32_RTCSEL_LSI // ~37kHz
|
||||
#define STM32_RTCPRE STM32_RTCPRE_DIV2 // HSE only!
|
||||
#define STM32_USART2SEL STM32_USART2SEL_APB
|
||||
#define STM32_LPUART1SEL STM32_LPUART1SEL_APB
|
||||
#define STM32_I2C1SEL STM32_I2C1SEL_APB
|
||||
|
50
dogs.c
50
dogs.c
@ -21,6 +21,17 @@ unsigned char dogs_buffer[DISP_WIDTH * DISP_HEIGHT / 8];
|
||||
|
||||
static volatile bool dogs_spi_done = false;
|
||||
|
||||
static void spi_send(unsigned char *data, unsigned int len)
|
||||
{
|
||||
dogs_spi_done = false;
|
||||
spiStartSend(&SPID1, len, data);
|
||||
while (!dogs_spi_done)
|
||||
asm("wfi");
|
||||
|
||||
//for (; len > 0; --len)
|
||||
// spiPolledExchange(&SPID1, *data++);
|
||||
}
|
||||
|
||||
static void dogs_init_display();
|
||||
static void dogs_spi_callback(SPIDriver *spid)
|
||||
{
|
||||
@ -54,27 +65,15 @@ void dogs_init()
|
||||
dogs_flush();
|
||||
}
|
||||
|
||||
void dogs_write_data(unsigned char byte)
|
||||
{
|
||||
SET_DATA;
|
||||
dogs_spi_done = false;
|
||||
spiStartSend(&SPID1, 1, &byte);
|
||||
while (!dogs_spi_done);
|
||||
}
|
||||
void dogs_write_cmd(unsigned char byte)
|
||||
{
|
||||
SET_CMD;
|
||||
dogs_spi_done = false;
|
||||
spiStartSend(&SPID1, 1, &byte);
|
||||
while (!dogs_spi_done);
|
||||
spi_send(&byte, 1);
|
||||
}
|
||||
|
||||
void dogs_set_column(unsigned int col)
|
||||
{
|
||||
//if (col < DISP_WIDTH) {
|
||||
dogs_write_cmd(0x10 | ((col >> 4) & 0xF));
|
||||
dogs_write_cmd(0x00 | (col & 0xF));
|
||||
//}
|
||||
dogs_write_cmd(0x10 | ((col >> 4) & 0xF));
|
||||
dogs_write_cmd(0x00 | (col & 0xF));
|
||||
}
|
||||
void dogs_set_power(unsigned int bits)
|
||||
{
|
||||
@ -133,6 +132,7 @@ void dogs_set_advanced(unsigned int bits)
|
||||
|
||||
void dogs_init_display()
|
||||
{
|
||||
SET_CMD;
|
||||
CS_LOW;
|
||||
dogs_reset();
|
||||
CS_HIGH;
|
||||
@ -154,9 +154,14 @@ void dogs_init_display()
|
||||
|
||||
void dogs_clear()
|
||||
{
|
||||
unsigned char *ptr = dogs_buffer;
|
||||
int count = sizeof(dogs_buffer);
|
||||
for (; count > 8; count -= 8) {
|
||||
uint32_t *ptr = (uint32_t *)dogs_buffer;
|
||||
unsigned int count = sizeof(dogs_buffer) / sizeof(uint32_t) / 12;
|
||||
|
||||
for (; count; --count) {
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
@ -166,23 +171,20 @@ void dogs_clear()
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
}
|
||||
for (; --count >= 0;)
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
void dogs_flush()
|
||||
{
|
||||
unsigned char *ptr = dogs_buffer;
|
||||
CS_LOW;
|
||||
for (int page = 0; page < 8; page++) {
|
||||
for (int page = 0; page < 8; ++page) {
|
||||
SET_CMD;
|
||||
dogs_set_page(page);
|
||||
dogs_set_column(30);
|
||||
|
||||
SET_DATA;
|
||||
dogs_spi_done = false;
|
||||
spiStartSend(&SPID1, 102, ptr);
|
||||
spi_send(ptr, 102);
|
||||
ptr += 102;
|
||||
while (!dogs_spi_done);
|
||||
}
|
||||
CS_HIGH;
|
||||
}
|
||||
|
153
main.c
153
main.c
@ -29,9 +29,93 @@
|
||||
* - Run at 4MHz, drop to low-power run/sleep @ 64kHz for idle: 375uA (also lowered contrast)
|
||||
* - Sleep display for 'pause': ~240uA
|
||||
*
|
||||
* - Use RTC for delay, Stop mode when idle: 348uA
|
||||
*
|
||||
* - Flappy bird is going, 2048 next
|
||||
*/
|
||||
|
||||
static int readVddmv();
|
||||
|
||||
THD_WORKING_AREA(waThread2, 128);
|
||||
THD_FUNCTION(Thread2, arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
dogs_init();
|
||||
flapbird_init();
|
||||
}
|
||||
THD_TABLE_BEGIN
|
||||
THD_TABLE_THREAD(0, "game", waThread2, Thread2, NULL)
|
||||
THD_TABLE_END
|
||||
|
||||
static void alarm_callback(RTCDriver *rtcp, rtcevent_t event)
|
||||
{
|
||||
(void)rtcp;
|
||||
(void)event;
|
||||
|
||||
static bool sleep = false;
|
||||
|
||||
bool sleep_button = (button_state & BUTTON_1) != 0;
|
||||
if (sleep && !sleep_button)
|
||||
return;
|
||||
|
||||
RCC->ICSCR |= 6 << RCC_ICSCR_MSIRANGE_Pos;
|
||||
dogs_set_sleep(false);
|
||||
|
||||
if (sleep_button) {
|
||||
sleep ^= true;
|
||||
if (sleep) {
|
||||
draw_number(DISP_WIDTH - 33, 0,
|
||||
!(PWR->CSR & PWR_CSR_PVDO) ? readVddmv() : 1);
|
||||
dogs_flush();
|
||||
}
|
||||
}
|
||||
|
||||
if (!sleep)
|
||||
flapbird_loop();
|
||||
|
||||
dogs_set_sleep(true);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
halInit();
|
||||
chSysInit();
|
||||
buttons_init();
|
||||
|
||||
static const RTCWakeup wakeupcfg = {
|
||||
(0 << 16) | // wucksel (37k /16 = ~2k)
|
||||
240 // wut (hope for 10Hz)
|
||||
};
|
||||
rtcSTM32SetPeriodicWakeup(&RTCD1, &wakeupcfg);
|
||||
rtcSetCallback(&RTCD1, alarm_callback);
|
||||
|
||||
RCC->CR &= ~RCC_CR_HSION;
|
||||
PWR->CR |= PWR_CR_LPSDSR | PWR_CR_ULP;
|
||||
PWR->CR |= PWR_CR_LPRUN;
|
||||
SCB->SCR = 6;
|
||||
FLASH->ACR |= FLASH_ACR_SLEEP_PD;
|
||||
|
||||
// Below code for serial -- note that it cuts off debugging, and MUST be used in a thread
|
||||
//chThdSleepMilliseconds(2000);
|
||||
//palSetPadMode(GPIOA, 13, PAL_MODE_ALTERNATE(6));
|
||||
//palSetPadMode(GPIOA, 14, PAL_MODE_ALTERNATE(6));
|
||||
//sdStart(&LPSD1, NULL);
|
||||
//chnWrite(&LPSD1, (const uint8_t *)"Hello World!\r\n", 14);
|
||||
|
||||
/* This is now the idle thread loop, you may perform here a low priority
|
||||
task but YOU MUST NEVER TRY TO SLEEP OR WAIT in this loop. Note that
|
||||
this tasks runs at the lowest priority level so any instruction added
|
||||
here will be executed after all other tasks have been started. */
|
||||
while (1)
|
||||
asm("wfe");
|
||||
}
|
||||
|
||||
void HardFault_Handler()
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
static volatile bool adc_is_complete = false;
|
||||
static void adc_callback(ADCDriver *adcd)
|
||||
{
|
||||
@ -55,7 +139,7 @@ static const ADCConversionGroup adcgrpcfg = {
|
||||
.chselr = ADC_CHSELR_CHSEL17 /* CHSELR */
|
||||
};
|
||||
|
||||
static int readVddmv()
|
||||
int readVddmv()
|
||||
{
|
||||
adcsample_t reading = 0;
|
||||
|
||||
@ -74,70 +158,3 @@ static int readVddmv()
|
||||
|
||||
return 3000 * /* CAL */ *((adcsample_t *)0x1FF80078) / reading;
|
||||
}
|
||||
|
||||
THD_WORKING_AREA(waThread2, 128);
|
||||
THD_FUNCTION(Thread2, arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
dogs_init();
|
||||
|
||||
flapbird_init();
|
||||
|
||||
bool sleep = false;
|
||||
while (1) {
|
||||
if (button_state & BUTTON_1) {
|
||||
sleep ^= true;
|
||||
if (sleep) {
|
||||
draw_number(DISP_WIDTH - 33, 0,
|
||||
!(PWR->CSR & PWR_CSR_PVDO) ? readVddmv() : 1);
|
||||
dogs_flush();
|
||||
}
|
||||
dogs_set_sleep(sleep);
|
||||
}
|
||||
|
||||
int dtime = 100;
|
||||
if (!sleep) {
|
||||
dtime = flapbird_loop();
|
||||
}
|
||||
|
||||
chThdSleepS(TIME_MS2I(dtime) / 64);
|
||||
}
|
||||
}
|
||||
|
||||
THD_TABLE_BEGIN
|
||||
THD_TABLE_THREAD(0, "game", waThread2, Thread2, NULL)
|
||||
THD_TABLE_END
|
||||
|
||||
int main(void)
|
||||
{
|
||||
halInit();
|
||||
chSysInit();
|
||||
|
||||
RCC->CR &= ~RCC_CR_HSION;
|
||||
PWR->CR |= PWR_CR_LPSDSR;
|
||||
|
||||
buttons_init();
|
||||
|
||||
// Below code for serial -- note that it cuts off debugging, and MUST be used in a thread
|
||||
//chThdSleepMilliseconds(2000);
|
||||
//palSetPadMode(GPIOA, 13, PAL_MODE_ALTERNATE(6));
|
||||
//palSetPadMode(GPIOA, 14, PAL_MODE_ALTERNATE(6));
|
||||
//sdStart(&LPSD1, NULL);
|
||||
//chnWrite(&LPSD1, (const uint8_t *)"Hello World!\r\n", 14);
|
||||
|
||||
|
||||
|
||||
/* This is now the idle thread loop, you may perform here a low priority
|
||||
task but YOU MUST NEVER TRY TO SLEEP OR WAIT in this loop. Note that
|
||||
this tasks runs at the lowest priority level so any instruction added
|
||||
here will be executed after all other tasks have been started. */
|
||||
while (1)
|
||||
asm("wfi");
|
||||
}
|
||||
|
||||
void HardFault_Handler()
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
sudo openocd -f /usr/local/share/openocd/scripts/interface/cmsis-dap.cfg -f /usr/local/share/openocd/scripts/target/stm32l0.cfg
|
||||
sudo openocd -f /usr/local/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/local/share/openocd/scripts/target/stm32l0.cfg
|
||||
|
Loading…
x
Reference in New Issue
Block a user