#pragma once
#ifndef LED_H
#define LED_H

// time to show one led digit, ms
#define LED_ONE_PERIOD  2
#define LED_DIGITS_NUM  8

/* LED segments pins
 AAA
F   B
F   B
 GGG
E   C
E   C
 DDD P
*/
#define LED_SEG_CG_ODR    GPIOA->ODR
#define LED_SEG_C         GPIO_PIN_1
#define LED_SEG_G         GPIO_PIN_2
#define LED_SEG_CG        (LED_SEG_C | LED_SEG_G)
#define LED_SEG_CG_ON(a)  LED_SEG_CG_ODR &= ~(a)

#define LED_SEG_DH_ODR    GPIOB->ODR
#define LED_SEG_H         GPIO_PIN_4
#define LED_SEG_D         GPIO_PIN_5
#define LED_SEG_DH        (LED_SEG_D | LED_SEG_H)
#define LED_SEG_DH_ON(a)  LED_SEG_DH_ODR &= ~(a)

#define LED_SEG_BE_ODR    GPIOC->ODR
#define LED_SEG_B         GPIO_PIN_6
#define LED_SEG_E         GPIO_PIN_7
#define LED_SEG_BE        (LED_SEG_B | LED_SEG_E)
#define LED_SEG_BE_ON(a)  LED_SEG_BE_ODR &= ~(a)

#define LED_SEG_AF_ODR    GPIOD->ODR
#define LED_SEG_A         GPIO_PIN_1
#define LED_SEG_F         GPIO_PIN_2
#define LED_SEG_AF        (LED_SEG_A | LED_SEG_F)
#define LED_SEG_AF_ON(a)  LED_SEG_AF_ODR &= ~(a)

/* LED symbols */
#define LED_OUT_OFF   {LED_SEG_CG_ODR |= LED_SEG_CG; LED_SEG_DH_ODR |= LED_SEG_DH; LED_SEG_BE_ODR |= LED_SEG_BE; LED_SEG_AF_ODR |= LED_SEG_AF;}
#define LED_OUT_DP    LED_SEG_DH_ON(LED_SEG_H)
#define LED_OUT_MM    LED_SEG_CG_ON(LED_SEG_G)
#define LED_OUT_0     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_BE_ON(LED_SEG_BE); LED_SEG_CG_ON(LED_SEG_C); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_1     LED_SEG_BE_ON(LED_SEG_B); LED_SEG_CG_ON(LED_SEG_C)
#define LED_OUT_2     LED_SEG_AF_ON(LED_SEG_A); LED_SEG_BE_ON(LED_SEG_BE); LED_SEG_CG_ON(LED_SEG_G); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_3     LED_SEG_AF_ON(LED_SEG_A); LED_SEG_BE_ON(LED_SEG_B); LED_SEG_CG_ON(LED_SEG_CG); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_4     LED_SEG_BE_ON(LED_SEG_B); LED_SEG_AF_ON(LED_SEG_F); LED_SEG_CG_ON(LED_SEG_CG)
#define LED_OUT_5     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_CG_ON(LED_SEG_CG); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_6     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_BE_ON(LED_SEG_E); LED_SEG_CG_ON(LED_SEG_CG); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_7     LED_SEG_AF_ON(LED_SEG_A); LED_SEG_BE_ON(LED_SEG_B); LED_SEG_CG_ON(LED_SEG_C)
#define LED_OUT_8     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_CG_ON(LED_SEG_CG); LED_SEG_BE_ON(LED_SEG_BE); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_9     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_BE_ON(LED_SEG_B); LED_SEG_CG_ON(LED_SEG_CG); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_H     LED_SEG_BE_ON(LED_SEG_BE); LED_SEG_AF_ON(LED_SEG_F); LED_SEG_CG_ON(LED_SEG_CG)
#define LED_OUT_PL    LED_SEG_BE_ON(LED_SEG_B); LED_SEG_CG_ON(LED_SEG_CG)
#define LED_OUT_O     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_BE_ON(LED_SEG_B); LED_SEG_CG_ON(LED_SEG_G);
#define LED_OUT_U     LED_SEG_AF_ON(LED_SEG_F); LED_SEG_BE_ON(LED_SEG_BE); LED_SEG_CG_ON(LED_SEG_C); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_A     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_BE_ON(LED_SEG_BE); LED_SEG_CG_ON(LED_SEG_CG)
#define LED_OUT_B     LED_SEG_AF_ON(LED_SEG_F); LED_SEG_BE_ON(LED_SEG_E); LED_SEG_CG_ON(LED_SEG_CG); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_C     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_BE_ON(LED_SEG_E); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_D     LED_SEG_BE_ON(LED_SEG_BE); LED_SEG_CG_ON(LED_SEG_CG); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_E     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_BE_ON(LED_SEG_E); LED_SEG_CG_ON(LED_SEG_G); LED_SEG_DH_ON(LED_SEG_D)
#define LED_OUT_F     LED_SEG_AF_ON(LED_SEG_AF); LED_SEG_BE_ON(LED_SEG_E); LED_SEG_CG_ON(LED_SEG_G)

/* shift register control pins */
#define SPI_PORT      GPIOC
#define SPI_SCK       GPIO_PIN_5
#define SPI_DATA      GPIO_PIN_3

typedef enum {
  led_A = 0xa,
  led_B = 0xb,
  led_C = 0xc,
  led_D = 0xd,
  led_E = 0xe,
  led_F = 0xf,
  led_H = 0x11,
  led_U = 0x12,
  led_Plus = 0x21,
  led_Minus = 0x22,
  led_O = 0x23, /* gradus */
  led_Off = 0xff
} led_sym_t;

extern uint8_t LedDigits[];
extern uint8_t LedPoint[];

void led_OutputValue(void);

#endif // LED_H
