#include "led_spi.h" #include "configuration.h" #include /* Private defines */ #define LED_NUM 4 #define LED_REFRESH_MS 3 #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_CLK 14 #define PIN_DOUT 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_C | 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_Blank, sym_Blank, sym_Blank, sym_Blank}; static Timer ledTimer; static uint8_t hw_pwm_pins[1] = {PIN_OUTE}; static HardwarePWM OE_pwm(hw_pwm_pins, 1); static uint32 MaxDuty, DutyStep; /* 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 } asm("nop;"); PinSet(PIN_CLK); // lock CLK sdata <<= 1; } asm("nop;"); PinSet(PIN_LOAD); // up latch asm("nop;"); PinRes(PIN_CLK); PinRes(PIN_LOAD); } void LED_ShowLed(void) { static uint8_t cnt = 0; LED_writeData(led_pos[cnt], sym_Blank); cnt ++; if (cnt >= LED_NUM) { cnt = 0; } LED_writeData(led_pos[cnt], led_bufer[cnt]); } /* Exported functions */ void LED_Init (void) { Serial.println("BIG LED SPI init!"); /* pinMode(PIN_OUTE, OUTPUT); PinRes(PIN_OUTE); // output enable */ MaxDuty = OE_pwm.getMaxDuty(); DutyStep = MaxDuty / LedBrightMax; LED_SetBright(LedBrightMiddl); /* prepare soft spi */ pinMode(PIN_DOUT, OUTPUT); pinMode(PIN_CLK, OUTPUT); pinMode(PIN_LOAD, OUTPUT); PinRes(PIN_CLK); PinRes(PIN_LOAD); /* Start timer for refresh leds */ ledTimer.initializeMs(LED_REFRESH_MS, 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 > LedBrightMax) { bright = LedBrightMax;} bright = LedBrightMax - bright; uint32 new_duty = DutyStep * bright; //MaxDuty * bright / LedBrightMax; OE_pwm.setDutyChan(0, bright); }