]> code.bitgloo.com Git - clyne/stm-game.git/commitdiff
use rtc for timing
authorClyne Sullivan <clyne@bitgloo.com>
Fri, 17 Sep 2021 11:26:50 +0000 (07:26 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Fri, 17 Sep 2021 11:26:50 +0000 (07:26 -0400)
cfg/chconf.h
cfg/halconf.h
cfg/mcuconf.h
dogs.c
main.c
openocd.sh

index dc2ccc133c12fb600b3410d63aa27416df10fd50..25d444a4417d88ea46cbfd5110f19cde340798f4 100644 (file)
  * @note    This macro can be used to activate a power saving mode.\r
  */\r
 #define CH_CFG_IDLE_ENTER_HOOK() {                                          \\r
-    RCC->ICSCR = (RCC->ICSCR & ~RCC_ICSCR_MSIRANGE_Msk); \\r
-    while (!(RCC->CR & RCC_CR_MSIRDY)); \\r
-    PWR->CR &= ~PWR_CR_LPRUN; \\r
-    PWR->CR |= PWR_CR_LPRUN; \\r
 }\r
+//    RCC->ICSCR = (RCC->ICSCR & ~RCC_ICSCR_MSIRANGE_Msk);\r
+//    while (!(RCC->CR & RCC_CR_MSIRDY));\r
+//    PWR->CR &= ~PWR_CR_LPRUN;\r
+//    PWR->CR |= PWR_CR_LPRUN;\r
 \r
 /**\r
  * @brief   Idle thread leave hook.\r
  * @note    This macro can be used to deactivate a power saving mode.\r
  */\r
 #define CH_CFG_IDLE_LEAVE_HOOK() {                                          \\r
-    RCC->ICSCR |= 6 << RCC_ICSCR_MSIRANGE_Pos; \\r
-    while (!(RCC->CR & RCC_CR_MSIRDY)); \\r
-    PWR->CR &= ~PWR_CR_LPRUN; \\r
 }\r
+//    RCC->ICSCR |= 6 << RCC_ICSCR_MSIRANGE_Pos;\r
+//    while (!(RCC->CR & RCC_CR_MSIRDY));\r
+//    PWR->CR &= ~PWR_CR_LPRUN;\r
 \r
 /**\r
  * @brief   System halt hook.\r
index 5cdb5e0ecf407dc28830a0f872eb25b1c81d46c9..6688b95793eac20e4b39745f52fe6a1d8ec332ff 100644 (file)
  * @brief   Enables the RTC subsystem.\r
  */\r
 #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)\r
-#define HAL_USE_RTC                         FALSE\r
+#define HAL_USE_RTC                         TRUE\r
 #endif\r
 \r
 /**\r
index 217d13fafa8a9e543d065d1ec8d451b5a4bcc17a..96e9080b5e19b7cc6a309f81d819e9e413527be9 100644 (file)
 #define STM32_PLS                           STM32_PLS_LEV4\r
 #define STM32_HSI16_ENABLED                 TRUE\r
 #define STM32_HSI16_DIVIDER_ENABLED         FALSE\r
-#define STM32_LSI_ENABLED                   FALSE\r
+#define STM32_LSI_ENABLED                   TRUE\r
 #define STM32_HSE_ENABLED                   FALSE\r
 #define STM32_LSE_ENABLED                   FALSE\r
 #define STM32_ADC_CLOCK_ENABLED             TRUE\r
 #define STM32_MSIRANGE                      STM32_MSIRANGE_4M\r
 #define STM32_SW                            STM32_SW_MSI\r
-#define STM32_PLLSRC                        STM32_PLLSRC_HSI16\r
-#define STM32_PLLMUL_VALUE                  3\r
-#define STM32_PLLDIV_VALUE                  4\r
+#define STM32_PLLSRC                        STM32_PLLSRC_NONE\r
+#define STM32_PLLMUL_VALUE                  1\r
+#define STM32_PLLDIV_VALUE                  8\r
 #define STM32_HPRE                          STM32_HPRE_DIV1\r
 #define STM32_PPRE1                         STM32_PPRE1_DIV1\r
 #define STM32_PPRE2                         STM32_PPRE2_DIV1\r
 #define STM32_MCOSEL                        STM32_MCOSEL_NOCLOCK\r
 #define STM32_MCOPRE                        STM32_MCOPRE_DIV1\r
-#define STM32_RTCSEL                        STM32_RTCSEL_NOCLOCK\r
-#define STM32_RTCPRE                        STM32_RTCPRE_DIV2\r
+#define STM32_RTCSEL                        STM32_RTCSEL_LSI // ~37kHz\r
+#define STM32_RTCPRE                        STM32_RTCPRE_DIV2 // HSE only!\r
 #define STM32_USART2SEL                     STM32_USART2SEL_APB\r
 #define STM32_LPUART1SEL                    STM32_LPUART1SEL_APB\r
 #define STM32_I2C1SEL                       STM32_I2C1SEL_APB\r
diff --git a/dogs.c b/dogs.c
index a29ee2cd78e99879098c455cd8a0d494a7f89823..7d3269842db12816695fa3b24afa3a2f87a96660 100644 (file)
--- a/dogs.c
+++ b/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,10 @@ 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;
@@ -165,24 +166,25 @@ void dogs_clear()
         *ptr++ = 0;
         *ptr++ = 0;
         *ptr++ = 0;
-    }
-    for (; --count >= 0;)
         *ptr++ = 0;
+        *ptr++ = 0;
+        *ptr++ = 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;
 }
diff --git a/main.c b/main.c
index 5c963fc5b264e048bc1df93d29b85306240b994d..37c1471760e59b577bb87f717065bafe674a5af1 100644 (file)
--- a/main.c
+++ b/main.c
  *  - 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);
-}
-
index 6cf8e57094773fe69a56e97c2e84a56b59b84ed6..90d40529a6a2c06bb4972409d729d8a603fec48f 100755 (executable)
@@ -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