Przeglądaj źródła

add lipo shim reading

Thomas Buck 1 rok temu
rodzic
commit
25aa485d8f
7 zmienionych plików z 149 dodań i 4 usunięć
  1. 2
    0
      CMakeLists.txt
  2. 1
    1
      README.md
  3. 28
    0
      include/lipo.h
  4. 8
    2
      src/console.c
  5. 105
    0
      src/lipo.c
  6. 4
    0
      src/main.c
  7. 1
    1
      src/usb_descriptors.c

+ 2
- 0
CMakeLists.txt Wyświetl plik

@@ -54,6 +54,7 @@ target_sources(gadget PUBLIC
54 54
     src/fat_disk.c
55 55
     src/debug.c
56 56
     src/buttons.c
57
+    src/lipo.c
57 58
 
58 59
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
59 60
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c
@@ -97,6 +98,7 @@ target_link_libraries(gadget
97 98
     tinyusb_device
98 99
     tinyusb_board
99 100
     hardware_spi
101
+    hardware_adc
100 102
     pico_btstack_ble
101 103
     pico_btstack_cyw43
102 104
     pico_cyw43_arch_threadsafe_background

+ 1
- 1
README.md Wyświetl plik

@@ -2,7 +2,7 @@
2 2
 
3 3
 For use with Raspberry Pi Pico W boards with the [Waveshare Pico LCD 1.3](https://www.waveshare.com/wiki/Pico-LCD-1.3) and the [Pimoroni Pico Lipo Shim](https://shop.pimoroni.com/products/pico-lipo-shim).
4 4
 
5
-Adapted from the [tinyusb-cdc-example](https://github.com/hathach/tinyusb/blob/master/examples/device/cdc_msc/src/main.c), [standalone client example](https://github.com/raspberrypi/pico-examples/blob/master/pico_w/bt/standalone/client.c) and my [Trackball firmware](https://git.xythobuz.de/thomas/Trackball).
5
+Adapted from the [tinyusb-cdc-example](https://github.com/hathach/tinyusb/blob/master/examples/device/cdc_msc/src/main.c), [adc example](https://github.com/raspberrypi/pico-examples/tree/master/adc/read_vsys), [standalone client example](https://github.com/raspberrypi/pico-examples/blob/master/pico_w/bt/standalone/client.c) and my [Trackball firmware](https://git.xythobuz.de/thomas/Trackball).
6 6
 
7 7
 ## Quick Start
8 8
 

+ 28
- 0
include/lipo.h Wyświetl plik

@@ -0,0 +1,28 @@
1
+/*
2
+ * lipo.h
3
+ *
4
+ * https://github.com/raspberrypi/pico-examples/blob/master/adc/read_vsys/power_status.c
5
+ *
6
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * See <http://www.gnu.org/licenses/>.
19
+ */
20
+
21
+#ifndef __LIPO_H__
22
+#define __LIPO_H__
23
+
24
+bool lipo_charging(void);
25
+float lipo_voltage(void);
26
+float lipo_percentage(float voltage);
27
+
28
+#endif // __LIPO_H__

+ 8
- 2
src/console.c Wyświetl plik

@@ -28,6 +28,7 @@
28 28
 #include "usb_msc.h"
29 29
 #include "debug.h"
30 30
 #include "console.h"
31
+#include "lipo.h"
31 32
 
32 33
 #define CNSL_BUFF_SIZE 1024
33 34
 #define CNSL_REPEAT_MS 500
@@ -65,13 +66,13 @@ static void cnsl_interpret(const char *line) {
65 66
     } else if ((strcmp(line, "help") == 0)
66 67
             || (strcmp(line, "h") == 0)
67 68
             || (strcmp(line, "?") == 0)) {
68
-        println("Trackball Firmware Usage:");
69
+        println("VolcanoRC Firmware Usage:");
69 70
         println("  reset - reset back into this firmware");
70 71
         println("   \\x18 - reset to bootloader");
71 72
         println(" repeat - repeat last command every %d milliseconds", CNSL_REPEAT_MS);
72 73
         println("   help - print this message");
73 74
         println("  mount - make mass storage medium (un)available");
74
-        //println("    foo - bar");
75
+        println("  power - show Lipo battery status");
75 76
         println("Press Enter with no input to repeat last command.");
76 77
         println("Use repeat to continuously execute last command.");
77 78
         println("Stop this by calling repeat again.");
@@ -83,6 +84,11 @@ static void cnsl_interpret(const char *line) {
83 84
                 state ? "mounted" : "unmounted",
84 85
                 state ? "Unplugging" : "Plugging in");
85 86
         msc_set_medium_available(!state);
87
+    } else if (strcmp(line, "power") == 0) {
88
+        float volt = lipo_voltage();
89
+        println("Battery: %.2fV = %.1f%% @ %s",
90
+                volt, lipo_percentage(volt),
91
+                lipo_charging() ? "charging" : "draining");
86 92
     } else {
87 93
         println("unknown command \"%s\"", line);
88 94
     }

+ 105
- 0
src/lipo.c Wyświetl plik

@@ -0,0 +1,105 @@
1
+/*
2
+ * lipo.c
3
+ *
4
+ * https://github.com/raspberrypi/pico-examples/blob/master/adc/read_vsys/power_status.c
5
+ *
6
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * See <http://www.gnu.org/licenses/>.
19
+ */
20
+
21
+#include "stdbool.h"
22
+#include "hardware/adc.h"
23
+
24
+#include "config.h"
25
+#include "lipo.h"
26
+
27
+#if CYW43_USES_VSYS_PIN
28
+#include "pico/cyw43_arch.h"
29
+#endif
30
+
31
+#ifndef PICO_POWER_SAMPLE_COUNT
32
+#define PICO_POWER_SAMPLE_COUNT 3
33
+#endif
34
+
35
+// Pin used for ADC 0
36
+#define PICO_FIRST_ADC_PIN 26
37
+
38
+static const float full_battery = 4.1f;
39
+static const float empty_battery = 3.2f;
40
+
41
+bool lipo_charging(void) {
42
+#if defined CYW43_WL_GPIO_VBUS_PIN
43
+    return cyw43_arch_gpio_get(CYW43_WL_GPIO_VBUS_PIN);
44
+#elif defined PICO_VBUS_PIN
45
+    gpio_set_function(PICO_VBUS_PIN, GPIO_FUNC_SIO);
46
+    return gpio_get(PICO_VBUS_PIN);
47
+#else
48
+#error "No VBUS Pin available!"
49
+#endif
50
+}
51
+
52
+float lipo_voltage(void) {
53
+#ifndef PICO_VSYS_PIN
54
+#error "No VSYS Pin available!"
55
+#endif
56
+
57
+#if CYW43_USES_VSYS_PIN
58
+    cyw43_thread_enter();
59
+    // Make sure cyw43 is awake
60
+    cyw43_arch_gpio_get(CYW43_WL_GPIO_VBUS_PIN);
61
+#endif
62
+
63
+    // setup adc
64
+    adc_gpio_init(PICO_VSYS_PIN);
65
+    adc_select_input(PICO_VSYS_PIN - PICO_FIRST_ADC_PIN);
66
+
67
+    adc_fifo_setup(true, false, 0, false, false);
68
+    adc_run(true);
69
+
70
+    // We seem to read low values initially - this seems to fix it
71
+    int ignore_count = PICO_POWER_SAMPLE_COUNT;
72
+    while (!adc_fifo_is_empty() || ignore_count-- > 0) {
73
+        (void)adc_fifo_get_blocking();
74
+    }
75
+
76
+    // read vsys
77
+    uint32_t vsys = 0;
78
+    for(int i = 0; i < PICO_POWER_SAMPLE_COUNT; i++) {
79
+        uint16_t val = adc_fifo_get_blocking();
80
+        vsys += val;
81
+    }
82
+
83
+    adc_run(false);
84
+    adc_fifo_drain();
85
+
86
+    vsys /= PICO_POWER_SAMPLE_COUNT;
87
+
88
+#if CYW43_USES_VSYS_PIN
89
+    cyw43_thread_exit();
90
+#endif
91
+
92
+    // Generate voltage
93
+    const float conversion_factor = 3.3f / (1 << 12);
94
+    return vsys * 3 * conversion_factor;
95
+}
96
+
97
+float lipo_percentage(float voltage) {
98
+    float percentage = 100.0f * ((voltage - empty_battery) / (full_battery - empty_battery));
99
+    if (percentage >= 100.0f) {
100
+        percentage = 100.0f;
101
+    } else if (percentage < 0.0f) {
102
+        percentage = 0.0f;
103
+    }
104
+    return percentage;
105
+}

+ 4
- 0
src/main.c Wyświetl plik

@@ -19,6 +19,7 @@
19 19
 #include "pico/stdlib.h"
20 20
 #include "pico/cyw43_arch.h"
21 21
 #include "hardware/watchdog.h"
22
+#include "hardware/adc.h"
22 23
 
23 24
 #include "config.h"
24 25
 #include "util.h"
@@ -39,6 +40,9 @@ int main(void) {
39 40
         debug("reset by watchdog");
40 41
     }
41 42
 
43
+    // required for LiPo voltage reading
44
+    adc_init();
45
+
42 46
     if (cyw43_arch_init()) {
43 47
         debug("cyw43_arch failed");
44 48
     }

+ 1
- 1
src/usb_descriptors.c Wyświetl plik

@@ -43,7 +43,7 @@
43 43
  *   [MSB]         HID | MSC | CDC          [LSB]
44 44
  */
45 45
 #define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n))
46
-#define USB_PID (0x4200 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) \
46
+#define USB_PID (0x2300 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) \
47 47
     | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )
48 48
 
49 49
 #define USB_VID   0xCafe

Ładowanie…
Anuluj
Zapisz