|
@@ -0,0 +1,186 @@
|
|
|
+#include "led_spi.h"
|
|
|
+#include <HardwarePWM.h>
|
|
|
+
|
|
|
+/* Private defines */
|
|
|
+#define LED_NUM 4
|
|
|
+
|
|
|
+#define PinSet(pin) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, ((uint16_t)1<<(pin)))
|
|
|
+#define PinRes(pin) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, ((uint16_t)1<<(pin)))
|
|
|
+
|
|
|
+#define PIN_DOUT 14
|
|
|
+#define PIN_CLK 13
|
|
|
+#define PIN_LOAD 12
|
|
|
+#define PIN_OUTE 0
|
|
|
+
|
|
|
+/* Private typedefs */
|
|
|
+typedef enum t_led_pos {
|
|
|
+ pos_led1 = 0x1,
|
|
|
+ pos_led2 = 0x2,
|
|
|
+ pos_led3 = 0x4,
|
|
|
+ pos_led4 = 0x8
|
|
|
+} led_pos_t;
|
|
|
+
|
|
|
+typedef enum t_segment {
|
|
|
+ seg_A = 0x01,
|
|
|
+ seg_B = 0x02,
|
|
|
+ seg_C = 0x04,
|
|
|
+ seg_D = 0x08,
|
|
|
+ seg_E = 0x10,
|
|
|
+ seg_F = 0x20,
|
|
|
+ seg_G = 0x40,
|
|
|
+ seg_DP = 0x80
|
|
|
+} segment_t;
|
|
|
+
|
|
|
+/* LED Symbol map:
|
|
|
+ A
|
|
|
+ F B
|
|
|
+ G
|
|
|
+ E C
|
|
|
+ D DP
|
|
|
+*/
|
|
|
+typedef enum t_led_symb {
|
|
|
+ sym_Blank = 0x0,
|
|
|
+ sym_0 = (uint8_t)(seg_A | seg_B | seg_C | seg_D | seg_E | seg_F),
|
|
|
+ sym_1 = (uint8_t)(seg_B | seg_C),
|
|
|
+ sym_2 = (uint8_t)(seg_A | seg_B | seg_G | seg_E | seg_D),
|
|
|
+ sym_3 = (uint8_t)(seg_A | seg_B | seg_G | seg_C | seg_D),
|
|
|
+ sym_4 = (uint8_t)(seg_F | seg_G | seg_B | seg_C),
|
|
|
+ sym_5 = (uint8_t)(seg_A | seg_F | seg_G | seg_E | seg_D),
|
|
|
+ sym_6 = (uint8_t)(seg_A | seg_F | seg_G | seg_E | seg_D | seg_C),
|
|
|
+ sym_7 = (uint8_t)(seg_A | seg_B | seg_C),
|
|
|
+ sym_8 = (uint8_t)(seg_A | seg_B | seg_C | seg_D | seg_E | seg_F | seg_G),
|
|
|
+ sym_9 = (uint8_t)(seg_A | seg_B | seg_C | seg_D | seg_G | seg_F),
|
|
|
+ sym_DP = seg_DP
|
|
|
+} led_symb_t;
|
|
|
+
|
|
|
+/* Private variables */
|
|
|
+static const led_pos_t led_pos[LED_NUM] = {
|
|
|
+ pos_led1, pos_led2, pos_led3, pos_led4
|
|
|
+};
|
|
|
+static const led_symb_t led_dig[10] = {
|
|
|
+ sym_0, sym_1, sym_2, sym_3, sym_4, sym_5, sym_6, sym_7, sym_8, sym_9
|
|
|
+};
|
|
|
+static led_symb_t led_bufer[LED_NUM] = {sym_0, sym_1, sym_2, sym_3};
|
|
|
+static Timer ledTimer;
|
|
|
+static uint8_t hw_pwm_pins[1] = {PIN_OUTE};
|
|
|
+static HardwarePWM OE_pwm(hw_pwm_pins, 1);
|
|
|
+static uint32 MaxDuty;
|
|
|
+
|
|
|
+/* Private functions */
|
|
|
+void LED_writeData (led_pos_t pos, led_symb_t data) {
|
|
|
+ PinRes(PIN_LOAD); // down latch
|
|
|
+ // software spi
|
|
|
+ uint8_t i;
|
|
|
+ uint16_t sdata = (pos << 8) | data;
|
|
|
+ for (i = 16; i != 0; i--) {
|
|
|
+ PinRes(PIN_CLK); // prepare CLK
|
|
|
+ if (sdata >= 0x8000) {
|
|
|
+ // if msb bit 1
|
|
|
+ PinSet(PIN_DOUT); // MOSI = 1
|
|
|
+ } else {
|
|
|
+ // if msb bit 0
|
|
|
+ PinRes(PIN_DOUT); // MOSI = 0
|
|
|
+ }
|
|
|
+ PinSet(PIN_CLK); // lock CLK
|
|
|
+ sdata <<= 1;
|
|
|
+ }
|
|
|
+ PinSet(PIN_LOAD); // up latch
|
|
|
+}
|
|
|
+
|
|
|
+void LED_ShowLed(void) {
|
|
|
+ static uint8_t cnt = 0;
|
|
|
+ LED_writeData(led_pos[cnt], led_bufer[cnt]);
|
|
|
+ cnt ++;
|
|
|
+ if (cnt >= LED_NUM) {
|
|
|
+ cnt = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* Exported functions */
|
|
|
+void LED_Init (void) {
|
|
|
+ Serial.println("BIG LED SPI init!");
|
|
|
+
|
|
|
+
|
|
|
+ /* in future, replace by pwm */
|
|
|
+ pinMode(PIN_OUTE, OUTPUT);
|
|
|
+ PinRes(PIN_OUTE); // output enable
|
|
|
+/*
|
|
|
+ MaxDuty = OE_pwm.getMaxDuty();
|
|
|
+ LED_SetBright(50);
|
|
|
+/*
|
|
|
+ /* prepare soft spi */
|
|
|
+ pinMode(PIN_DOUT, OUTPUT);
|
|
|
+ pinMode(PIN_CLK, OUTPUT);
|
|
|
+ pinMode(PIN_LOAD, OUTPUT);
|
|
|
+
|
|
|
+ PinSet(PIN_CLK);
|
|
|
+ PinSet(PIN_LOAD);
|
|
|
+
|
|
|
+ /* Start timer for refresh leds */
|
|
|
+ ledTimer.initializeMs(5, LED_ShowLed).start();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Show two Bin number to LED
|
|
|
+ *
|
|
|
+ * @param hbin High/Left Bin value 0..99
|
|
|
+ * @param lbin Low/Right Bin Value 0..99
|
|
|
+ */
|
|
|
+void LED_ShowBin(uint8_t hbin, uint8_t lbin) {
|
|
|
+ uint8_t a = hbin / 10;
|
|
|
+ uint8_t b = hbin % 10;
|
|
|
+ uint8_t c = lbin / 10;
|
|
|
+ uint8_t d = lbin % 10;
|
|
|
+
|
|
|
+ if (a > 9) { a = 9; }
|
|
|
+ if (b > 9) { b = 9; }
|
|
|
+ if (c > 9) { c = 9; }
|
|
|
+ if (d > 9) { d = 9; }
|
|
|
+
|
|
|
+ led_bufer[0] = led_dig[a];
|
|
|
+ led_bufer[1] = led_dig[b];
|
|
|
+ led_bufer[2] = led_dig[c];
|
|
|
+ led_bufer[3] = led_dig[d];
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Set value 0..9 in single led
|
|
|
+ *
|
|
|
+ * @param pos Led num 0..3
|
|
|
+ * @param bin Bin value 0..9
|
|
|
+ */
|
|
|
+void LED_ShowBinPos(uint8_t pos, uint8_t bin) {
|
|
|
+ if (pos >= LED_NUM) { return; }
|
|
|
+ if (bin > 9) { bin = 9; }
|
|
|
+
|
|
|
+ led_bufer[pos] = led_dig[bin];
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief On semicolon
|
|
|
+ */
|
|
|
+void LED_SemicolonOn(void) {
|
|
|
+ led_bufer[1] = led_symb_t((uint8_t)led_bufer[1] | (uint8_t)sym_DP);
|
|
|
+ led_bufer[2] = led_symb_t((uint8_t)led_bufer[2] | (uint8_t)sym_DP);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Off semicolon
|
|
|
+ */
|
|
|
+void LED_SemicolonOFF(void) {
|
|
|
+ led_bufer[1] = led_symb_t((uint8_t)led_bufer[1] & ~((uint8_t)sym_DP));
|
|
|
+ led_bufer[2] = led_symb_t((uint8_t)led_bufer[2] & ~((uint8_t)sym_DP));
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Set LED bright.
|
|
|
+ *
|
|
|
+ * @param bright Percent value 0..100
|
|
|
+ */
|
|
|
+void LED_SetBright(uint8_t bright) {
|
|
|
+ if (bright > 100) { bright = 100;}
|
|
|
+ bright = 100 - bright;
|
|
|
+
|
|
|
+ uint32 new_duty = MaxDuty * bright / 100;
|
|
|
+ OE_pwm.setDutyChan(0, bright);
|
|
|
+}
|