From 501da8cc226ea58b734d41d766a0c62d081b9e5a Mon Sep 17 00:00:00 2001
From: schneider <schneider@blinkenlichts.net>
Date: Wed, 11 Sep 2019 23:51:30 +0200
Subject: [PATCH] feat(pmic): show options on display. untested.

---
 epicardium/modules/pmic.c | 139 ++++++++++++++++++++++++++------------
 1 file changed, 96 insertions(+), 43 deletions(-)

diff --git a/epicardium/modules/pmic.c b/epicardium/modules/pmic.c
index 33022bcb..0bc11d6f 100644
--- a/epicardium/modules/pmic.c
+++ b/epicardium/modules/pmic.c
@@ -135,6 +135,7 @@ done:
 	return ret;
 }
 
+#if 0
 /*
  * Read the interrupt flag register and handle all interrupts which the PMIC has
  * sent.  In most cases this will be the buttons.
@@ -151,25 +152,35 @@ pmic_poll_interrupts(TickType_t *button_start_tick, TickType_t duration)
 	uint8_t int_flag = MAX77650_getINT_GLBL();
 	hwlock_release(HWLOCK_I2C);
 
-	if (int_flag & MAX77650_INT_nEN_F) {
-		/* Button was pressed */
-		*button_start_tick = xTaskGetTickCount();
+
+	/* TODO: Remove when all interrupts are handled */
+	if (int_flag & ~(MAX77650_INT_nEN_F | MAX77650_INT_nEN_R)) {
+		LOG_WARN("pmic", "Unhandled PMIC Interrupt: %x", int_flag);
 	}
-	if (int_flag & MAX77650_INT_nEN_R) {
-		/* Button was released */
-		*button_start_tick = 0;
-		if (duration < pdMS_TO_TICKS(400)) {
-			return_to_menu();
-		} else {
-			LOG_WARN("pmic", "Resetting ...");
-			card10_reset();
-		}
+}
+#endif
+
+/*
+ * Read the interrupt flag register and handle all interrupts which the PMIC has
+ * sent.  In most cases this will be the buttons.
+ */
+static uint8_t
+pmic_poll_interrupts(void)
+{
+	while (hwlock_acquire(HWLOCK_I2C, LOCK_WAIT) < 0) {
+		LOG_WARN("pmic", "Failed to acquire I2C. Retrying ...");
+		vTaskDelay(pdMS_TO_TICKS(100));
 	}
 
+	uint8_t int_flag = MAX77650_getINT_GLBL();
+	hwlock_release(HWLOCK_I2C);
+
 	/* TODO: Remove when all interrupts are handled */
 	if (int_flag & ~(MAX77650_INT_nEN_F | MAX77650_INT_nEN_R)) {
 		LOG_WARN("pmic", "Unhandled PMIC Interrupt: %x", int_flag);
 	}
+
+    return int_flag;
 }
 
 __attribute__((noreturn)) static void pmic_die(float u_batt)
@@ -398,7 +409,6 @@ void gpio_low_power(void)
         GPIO_Config(&pins_low_power[i]);
     }
 
-    epic_disp_backlight(0);
 }
 
 void GPIOWAKE_IRQHandler(void)
@@ -408,37 +418,37 @@ void GPIOWAKE_IRQHandler(void)
 void powersave(void)
 {
 	LOG_WARN("pmic", "Powersave");
+    epic_disp_backlight(0);
+    epic_leds_set_rocket(0, 0);
+    epic_leds_set_rocket(1, 0);
+    epic_leds_set_rocket(2, 0);
 #if 1
     max86150_begin();
     max86150_getINT1();
     max86150_getINT2();
     max86150_shutDown();
 #endif
-	if(MAX77650_setEN_SBB2(0b100)){
-        //printf("turn off ok\n");
-	    LOG_WARN("pmic", "turn off ok");
-    } else {
-        //printf("turn off fail\n");
-	    LOG_WARN("pmic", "turn off fail");
-    }
+	MAX77650_setEN_SBB2(0b100);
     core1_stop();
     MAX77650_getINT_GLBL();
     gpio_low_power();
     turnOffClocks();
     switchToHIRC();
-    __SEV();
-    __WFE();
+    //__SEV();
+    //__WFE();
     deepsleep();
     turnOnClocks();
     MXC_GCR->clkcn = old_clkcn;
     while(!(MXC_GCR->clkcn & MXC_F_GCR_CLKCN_CKRDY)); // Wait for the switch to occur
     SystemCoreClockUpdate();
-	if(MAX77650_setEN_SBB2(0b110)) printf("turn on ok\n");
-    //while(1);
+	MAX77650_setEN_SBB2(0b110);
 }
+
 void vPmicTask(void *pvParameters)
 {
 	pmic_task_id = xTaskGetCurrentTaskHandle();
+    uint8_t interrupts = 0;
+    uint32_t reason = 0;
 
 	ADC_Init(0x9, NULL);
 	GPIO_Config(&gpio_cfg_adc0);
@@ -462,30 +472,73 @@ void vPmicTask(void *pvParameters)
 	xTimerStart(pmic_timer, 0);
 
 	while (1) {
-		uint32_t reason;
-		if (button_start_tick == 0) {
-			reason = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
-		} else {
-			reason = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(100));
-		}
-
-		TickType_t duration = xTaskGetTickCount() - button_start_tick;
-
-		if (button_start_tick != 0 && duration > pdMS_TO_TICKS(1000)) {
-			LOG_WARN("pmic", "Poweroff");
-            powersave();
-            powersave();
-            //while(1);
-            card10_reset();
-
-			//MAX77650_setSFT_RST(0x2);
-		}
+		interrupts |= pmic_poll_interrupts();
+        if(interrupts == 0) {
+		    reason |= ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
+        }
 
+        /* New interrupts */
 		if (reason & PMIC_NOTIFY_IRQ) {
-			pmic_poll_interrupts(&button_start_tick, duration);
+            reason ^= PMIC_NOTIFY_IRQ;
+			interrupts |= pmic_poll_interrupts();
 		}
 
+        if (interrupts & MAX77650_INT_nEN_F) {
+            /* Button was pressed */
+            interrupts ^= MAX77650_INT_nEN_F; // Mark as handled
+
+            button_start_tick = xTaskGetTickCount();
+            while (true) {
+                TickType_t duration = xTaskGetTickCount() - button_start_tick;
+
+                if(duration > 400) {
+                    disp_forcelock();
+                    epic_disp_clear(0x0000);
+
+                    epic_disp_print(0, 0 , "Release for reset", 0xffff, 0x0000);
+	                epic_disp_print(0, 20, "Press   for sleep", 0xffff, 0x0000);
+	                epic_disp_print(0, 40, "Press   for shutdown", 0xffff, 0x0000);
+                    epic_disp_update();
+                }
+
+                if(duration > 1000) {
+                    epic_disp_clear(0x0000);
+                    epic_disp_print(0, 20, "Release for sleep", 0xffff, 0x0000);
+	                epic_disp_print(0, 40, "Press   for shutdown", 0xffff, 0x0000);
+                    epic_disp_update();
+                }
+
+                if(interrupts & MAX77650_INT_nEN_R) {
+                    /* Button is released */
+                    interrupts ^= MAX77650_INT_nEN_R; // Mark as handled
+
+                    if (duration < pdMS_TO_TICKS(400)) {
+                        return_to_menu();
+                    }
+                    if (duration >= pdMS_TO_TICKS(400) &&
+                            duration <= pdMS_TO_TICKS(1000)) {
+                        LOG_WARN("pmic", "Resetting ...");
+                        card10_reset();
+                    }
+                    if (duration > pdMS_TO_TICKS(1000)) {
+                        LOG_WARN("pmic", "Poweroff");
+                        powersave();
+                        card10_reset();
+                    }
+                    break;
+                }
+
+		        reason |= ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(200));
+                if (reason & PMIC_NOTIFY_IRQ) {
+                    /* New interrupts */
+                    reason ^= PMIC_NOTIFY_IRQ;
+                    interrupts |= pmic_poll_interrupts();
+                }
+            }
+        }
+
 		if (reason & PMIC_NOTIFY_MONITOR) {
+            reason ^= PMIC_NOTIFY_MONITOR;
 			pmic_check_battery();
 		}
 	}
-- 
GitLab