diff options
author | lonkaars <loek@pipeframe.xyz> | 2022-03-19 11:24:39 +0100 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2022-03-19 11:24:39 +0100 |
commit | b3344df3e3a3594f133c2c051df981d75e0112b8 (patch) | |
tree | 2c61bc9d4c67afa9b6d9794fdad041bc85260927 /src/tm1637.c |
initial commit (i think my display is broken)
Diffstat (limited to 'src/tm1637.c')
-rw-r--r-- | src/tm1637.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/tm1637.c b/src/tm1637.c new file mode 100644 index 0000000..4e6e68c --- /dev/null +++ b/src/tm1637.c @@ -0,0 +1,110 @@ +#include "main.h" +#include "tm1637.h" +#include "stm32f091xc.h" + +void _tm1637_micro_delay() { + timer_delay(10); + // for(unsigned int x = 0; x < 10e4; x++); +} + +/** @brief reset gpio mode registers for dio */ +void _tm1637_GPIOMODE_reset() { + GPIOA->MODER &= ~(0b11 << (PINOUT_DISP_DIO * 2)); + GPIOA->PUPDR &= ~(0b11 << (PINOUT_DISP_DIO * 2)); + GPIOA->OTYPER &= ~(0b1 << PINOUT_DISP_DIO); +} + +/** @brief set dio to general-purpose output mode */ +void _tm1637_GPIOMODE_gp_output() { + _tm1637_GPIOMODE_reset(); + + GPIOA->MODER |= (0b01 << (PINOUT_DISP_DIO * 2)); +} + +/** @brief set dio to open drain input mode */ +void _tm1637_GPIOMODE_open_drain() { + _tm1637_GPIOMODE_reset(); + + GPIOA->MODER |= (0b10 << (PINOUT_DISP_DIO * 2)); + GPIOA->OTYPER |= (0b1 << PINOUT_DISP_DIO); +} + +/** + * @brief gpio write abstraction function + * @param pin pin to write + * @param state state to set `pin` to + */ +void _tm1637_pin_write(uint32_t pin, bool state) { + GPIOA->ODR ^= (((GPIOA->ODR & (1 << pin)) >> pin) ^ state) << pin; + + if (pin == PINOUT_DISP_CLK) led_write(0, state); + if (pin == PINOUT_DISP_DIO) led_write(1, state); +} + +void tm1637_begin() { + _tm1637_GPIOMODE_gp_output(); + + // general purpose output mode for clk + GPIOA->MODER &= ~(0b11 << (PINOUT_DISP_CLK * 2)); + GPIOA->MODER |= (0b01 << (PINOUT_DISP_CLK * 2)); + + _tm1637_pin_write(PINOUT_DISP_CLK, 1); + _tm1637_pin_write(PINOUT_DISP_DIO, 1); + + _tm1637_micro_delay(); +} + +void _tm1637_start() { + _tm1637_pin_write(PINOUT_DISP_DIO, 0); + _tm1637_micro_delay(); +} + +void _tm1637_stop() { + _tm1637_pin_write(PINOUT_DISP_CLK, 1); + _tm1637_pin_write(PINOUT_DISP_DIO, 1); + _tm1637_micro_delay(); +} + +bool _tm1637_ack() { + _tm1637_pin_write(PINOUT_DISP_CLK, 0); + _tm1637_pin_write(PINOUT_DISP_DIO, 0); + _tm1637_GPIOMODE_open_drain(); + _tm1637_micro_delay(); + _tm1637_pin_write(PINOUT_DISP_CLK, 1); + _tm1637_micro_delay(); + _tm1637_pin_write(PINOUT_DISP_CLK, 0); + _tm1637_GPIOMODE_gp_output(); + _tm1637_micro_delay(); + return true; +} + +/** + * @brief send data to TM1637 + * @param command command to send + * @return response data as TM1637Response struct + */ +TM1637Sequence _tm1637_send(TM1637Sequence command) { + TM1637Sequence response = { .data = 0, .length = 0 }; + + _tm1637_start(); + + for (uint32_t byte = 0; byte < command.length; byte++) { + for (uint8_t bit = 0; bit < 8; bit++) { + uint8_t rev_bit = 7 - bit; + _tm1637_pin_write(PINOUT_DISP_CLK, 0); + _tm1637_pin_write(PINOUT_DISP_DIO, (command.data[byte] & (1 << rev_bit)) >> rev_bit); + _tm1637_micro_delay(); + _tm1637_pin_write(PINOUT_DISP_CLK, 1); + _tm1637_micro_delay(); + } + //TODO: confirm ack + /*bool ack =*/ _tm1637_ack(); + } + + _tm1637_micro_delay(); + + // stop condition + _tm1637_stop(); + + return response; +} |