/* * Copyright (c) 2021 Titouan Christophe * * SPDX-License-Identifier: Apache-2.0 */ #include "display_7seg.h" #include #include #include const uint8_t DISPLAY_OFF[4] = { CHAR_OFF, CHAR_OFF, CHAR_OFF, CHAR_OFF }; const uint8_t TEXT_Err[4] = { CHAR_E, CHAR_r, CHAR_r, CHAR_OFF }; static bool initialized; static const struct device *const expander1 = DEVICE_DT_GET(DT_NODELABEL(expander1_x_nucleo_53l0a1)); static const struct device *const expander2 = DEVICE_DT_GET(DT_NODELABEL(expander2_x_nucleo_53l0a1)); static const uint8_t digits[16] = { CHAR_0, CHAR_1, CHAR_2, CHAR_3, CHAR_4, CHAR_5, CHAR_6, CHAR_7, CHAR_8, CHAR_9, CHAR_A, CHAR_b, CHAR_C, CHAR_d, CHAR_E, CHAR_F, }; static const int max_positive_for_base[17] = { 0, 1, 16, 81, 256, 625, 1296, 2401, 4096, 6561, 10000, 14641, 20736, 28561, 38416, 50625, 65536, }; static const int max_negative_for_base[17] = { -0, -1, -8, -27, -64, -125, -216, -343, -512, -729, -1000, -1331, -1728, -2197, -2744, -3375, -4096, }; static int init_display(void) { int ret; for (int i = 0; i < 14; i++) { ret = gpio_pin_configure(expander1, i, GPIO_OUTPUT | GPIO_OUTPUT_INIT_HIGH); if (ret) { printk("Error in configure pin %d on expander1: %d", i, ret); return ret; } ret = gpio_pin_configure(expander2, i, GPIO_OUTPUT | GPIO_OUTPUT_INIT_HIGH); if (ret) { printk("Error in configure pin %d on expander2: %d", i, ret); return ret; } } initialized = true; return 0; } int display_chars(const uint8_t chars[4]) { int r; uint16_t port1, port2; if (!initialized) { r = init_display(); if (r) { return r; } } port1 = ((chars[3] & 0x7f) << 7) | (chars[2] & 0x7f); port2 = ((chars[1] & 0x7f) << 7) | (chars[0] & 0x7f); /* Common anode: invert the output (LOW = led on) */ r = gpio_port_set_masked(expander1, 0x3fff, port1 ^ 0x3fff); if (r) { return r; } return gpio_port_set_masked(expander2, 0x3fff, port2 ^ 0x3fff); } int display_number(int num, unsigned int base) { int d, i, neg = 0; uint8_t representation[4] = { CHAR_E, CHAR_r, CHAR_r, CHAR_OFF }; /* Unsupported base */ if (base > 16) { return -EINVAL; } /* Number too large to be displayed */ if (num <= max_negative_for_base[base] || num >= max_positive_for_base[base]) { return -EINVAL; } if (num < 0) { num = -num; representation[0] = CHAR_DASH; neg = 1; } for (i = 3; i >= neg; i--) { if (num > 0 || i == 3) { d = num % base; representation[i] = digits[d]; num /= base; } else { representation[i] = CHAR_OFF; } } return display_chars(representation); }