I am trying to interface the Grove 4 Digit Display(TM1637) with the nRF52840 DK.I have successfully interfaced it with ESP32 and get clear output after researching for the CODE in the Internet.I have included that code , below:
main.c
#include "tm1637.h" #include <stdlib.h> #include <stdbool.h> #include <string.h> #include <math.h> #include <drivers/gpio.h> #define CONFIG_TM1637_CLK_PIN 20 #define CONFIG_TM1637_DIO_PIN 21 const gpio_num_t LED_CLK = CONFIG_TM1637_CLK_PIN; const gpio_num_t LED_DTA = CONFIG_TM1637_DIO_PIN; void app_main(void) { tm1637_led_t * lcd = tm1637_init(LED_CLK, LED_DTA); tm1637_set_number(lcd, 8008); //Displays Number 8008 on Four Digit Display tm1637_set_brightness(lcd, 7); }
tm1637.h
#ifndef TM1637_H #define TM1637_H #include <inttypes.h> #include <stdbool.h> #include <drivers/gpio.h> #ifdef __cplusplus extern "C" { #endif struct tm; typedef enum { GPIO_NUM_20 = 20, /*!< GPIO0, input and output ,Can take any of these two pins as CLK and DIO*/ GPIO_NUM_21 = 21, GPIO_NUM_22 = 22, GPIO_NUM_23 = 23, //This is the GPIO definition in ESP32, But I don't know how to define GPIO GPIO_NUM_24 = 24, // pins for nRF52840 chips.Please help me to find the solution to this part GPIO_NUM_25 = 25, GPIO_NUM_26 = 26 } gpio_num_t; typedef struct { gpio_num_t m_pin_clk; gpio_num_t m_pin_dta; uint8_t m_brightness; } tm1637_led_t; /** * @brief Constructs new LED TM1637 object * * @param pin_clk GPIO pin for CLK input of LED module * @param pin_data GPIO pin for DIO input of LED module * @return */ tm1637_led_t * tm1637_init(gpio_num_t pin_clk, gpio_num_t pin_data); /** * @brief Set brightness level. Note - will be set after next display render * @param led LED object * @param level Brightness level 0..7 value */ void tm1637_set_brightness(tm1637_led_t * led, uint8_t level); /** * @brief Set one-segment number, also controls dot of this segment * @param led LED object * @param segment_idx Segment index (0..3) * @param num Number to set (0x00..0x0F, 0xFF for clear) * @param dot Display dot of this segment */ void tm1637_set_segment_number(tm1637_led_t * led, const uint8_t segment_idx, const uint8_t num, const bool dot); /** * @brief Set one-segment raw segment data * @param led LED object * @param segment_idx Segment index (0..3) * @param data Raw data, bitmask is XGFEDCBA */ void tm1637_set_segment_raw(tm1637_led_t * led, const uint8_t segment_idx, const uint8_t data); /** * @brief Set full display number, in decimal encoding * @param led LED object * @param number Display number (0...9999) */ void tm1637_set_number(tm1637_led_t * led, uint16_t number); /** * @brief Set full display number, in decimal encoding + control leading zero * @param led LED object * @param number Display number (0...9999) * @param lead_zero Display leading zero(s) */ void tm1637_set_number_lead(tm1637_led_t * led, uint16_t number, const bool lead_zero); /** * @brief Set full display number, in decimal encoding + control leading zero + control dot display * @param led LED object * @param number Display number (0...9999) * @param lead_zero Display leading zero(s) * @param dot_mask Dot mask, bits left-to-right */ void tm1637_set_number_lead_dot(tm1637_led_t * led, uint16_t number, const bool lead_zero, const uint8_t dot_mask); /** * @brief Set full display OFF * @param led LED object */ void tm1637_display_off(tm1637_led_t *led, uint16_t number, bool lead_zero, const uint8_t dot_mask); #ifdef __cplusplus } #endif #endif // TM1637_H
tm1637.c
#include "tm1637.h" #include <stdlib.h> #include <stdbool.h> #include <string.h> #include <math.h> #include <drivers/gpio.h> #define TM1637_ADDR_AUTO 0x40 #define TM1637_ADDR_FIXED 0x44 #define MINUS_SIGN_IDX 16 static const int8_t tm1637_symbols[] = { // XGFEDCBA 0x3f, // 0b00111111, // 0 0x06, // 0b00000110, // 1 0x5b, // 0b01011011, // 2 0x4f, // 0b01001111, // 3 0x66, // 0b01100110, // 4 0x6d, // 0b01101101, // 5 0x7d, // 0b01111101, // 6 0x07, // 0b00000111, // 7 0x7f, // 0b01111111, // 8 0x6f, // 0b01101111, // 9 0x77, // 0b01110111, // A 0x7c, // 0b01111100, // b 0x39, // 0b00111001, // C 0x5e, // 0b01011110, // d 0x79, // 0b01111001, // E 0x71, // 0b01110001 // F 0x40, // 0b01000000 // minus sign }; void tm1637_start(tm1637_led_t *led); void tm1637_stop(tm1637_led_t *led); void tm1637_off(tm1637_led_t *led); static void tm1637_send_byte(tm1637_led_t *led, uint8_t byte); static void tm1637_delay(); static inline float nearestf(float val, int precision) { int scale = pow(10, precision); return roundf(val * scale) / scale; } void tm1637_start(tm1637_led_t *led) { // Send start signal // Both outputs are expected to be HIGH beforehand gpio_pin_set(dev, led->m_pin_dta, 0); tm1637_delay(); } void tm1637_stop(tm1637_led_t *led) { // Send stop signal // CLK is expected to be LOW beforehand gpio_pin_set(dev, led->m_pin_dta, 0); tm1637_delay(); gpio_pin_set(dev, led->m_pin_clk, 1); tm1637_delay(); gpio_pin_set(dev, led->m_pin_dta, 1); tm1637_delay(); } void tm1637_send_byte(tm1637_led_t *led, uint8_t byte) { for (uint8_t i = 0; i < 8; ++i) { gpio_pin_set(dev, led->m_pin_clk, 0); tm1637_delay(); gpio_pin_set(dev, led->m_pin_dta, byte & 0x01); // Send current bit byte >>= 1; tm1637_delay(); gpio_pin_set(dev, led->m_pin_clk, 1); tm1637_delay(); } // The TM1637 signals an ACK by pulling DIO low from the falling edge of // CLK after sending the 8th bit, to the next falling edge of CLK. // DIO needs to be set as input during this time to avoid having both // chips trying to drive DIO at the same time. gpio_pin_configure(dev, led->m_pin_dta, GPIO_INPUT); gpio_pin_set(dev, led->m_pin_clk, 0); // TM1637 starts ACK (pulls DIO low) tm1637_delay(); gpio_pin_set(dev, led->m_pin_clk, 1); tm1637_delay(); gpio_pin_set(dev, led->m_pin_clk, 0); // TM1637 ends ACK (releasing DIO) tm1637_delay(); gpio_pin_configure(dev, led->m_pin_dta, GPIO_OUTPUT); } void tm1637_delay() { hal_delay(3); } // PUBLIC PART: tm1637_led_t *tm1637_init(gpio_num_t pin_clk, gpio_num_t pin_data) { const struct device *dev; tm1637_led_t *led = (tm1637_led_t *)malloc(sizeof(tm1637_led_t)); led->m_pin_clk = pin_clk; led->m_pin_dta = pin_data; led->m_brightness = 0x06; // Set CLK to low during DIO initialization to avoid sending a start signal by mistake gpio_pin_configure(dev, pin_clk, GPIO_OUTPUT); gpio_pin_set(dev, pin_clk, 0); tm1637_delay(); gpio_pin_configure(dev, pin_data, GPIO_OUTPUT); gpio_pin_set(dev, pin_data, 1); tm1637_delay(); gpio_pin_set(dev, pin_clk, 1); tm1637_delay(); return led; } void tm1637_set_brightness(tm1637_led_t *led, uint8_t level) { if (level > 0x07) { level = 0x07; } // Check max level led->m_brightness = level; } void tm1637_set_segment_number(tm1637_led_t *led, const uint8_t segment_idx, const uint8_t num, const bool dot) { uint8_t seg_data = 0x00; if (num < (sizeof(tm1637_symbols) / sizeof(tm1637_symbols[0]))) { seg_data = tm1637_symbols[num]; // Select proper segment image } if (dot) { seg_data |= 0x80; // Set DOT segment flag } tm1637_set_segment_raw(led, segment_idx, seg_data); } void tm1637_set_segment_raw(tm1637_led_t *led, const uint8_t segment_idx, const uint8_t data) { tm1637_start(led); tm1637_send_byte(led, TM1637_ADDR_FIXED); tm1637_stop(led); tm1637_start(led); tm1637_send_byte(led, segment_idx | 0xc0); tm1637_send_byte(led, data); tm1637_stop(led); tm1637_start(led); tm1637_send_byte(led, led->m_brightness | 0x88); tm1637_stop(led); } void tm1637_set_number(tm1637_led_t *led, uint16_t number) { tm1637_set_number_lead_dot(led, number, false, 0x00); } void tm1637_set_number_lead(tm1637_led_t *led, uint16_t number, const bool lead_zero) { tm1637_set_number_lead_dot(led, number, lead_zero, 0x00); } void tm1637_set_number_lead_dot(tm1637_led_t *led, uint16_t number, bool lead_zero, const uint8_t dot_mask) { uint8_t lead_number = lead_zero ? 0xFF : tm1637_symbols[0]; if (number < 10) { tm1637_set_segment_number(led, 3, number, dot_mask & 0x01); tm1637_set_segment_number(led, 2, lead_number, dot_mask & 0x02); tm1637_set_segment_number(led, 1, lead_number, dot_mask & 0x04); tm1637_set_segment_number(led, 0, lead_number, dot_mask & 0x08); } else if (number < 100) { tm1637_set_segment_number(led, 3, number % 10, dot_mask & 0x01); tm1637_set_segment_number(led, 2, (number / 10) % 10, dot_mask & 0x02); tm1637_set_segment_number(led, 1, lead_number, dot_mask & 0x04); tm1637_set_segment_number(led, 0, lead_number, dot_mask & 0x08); } else if (number < 1000) { tm1637_set_segment_number(led, 3, number % 10, dot_mask & 0x01); tm1637_set_segment_number(led, 2, (number / 10) % 10, dot_mask & 0x02); tm1637_set_segment_number(led, 1, (number / 100) % 10, dot_mask & 0x04); tm1637_set_segment_number(led, 0, lead_number, dot_mask & 0x08); } else { tm1637_set_segment_number(led, 3, number % 10, dot_mask & 0x01); tm1637_set_segment_number(led, 2, (number / 10) % 10, dot_mask & 0x02); tm1637_set_segment_number(led, 1, (number / 100) % 10, dot_mask & 0x04); tm1637_set_segment_number(led, 0, (number / 1000) % 10, dot_mask & 0x08); } } void tm1637_display_off(tm1637_led_t *led, uint16_t number, bool lead_zero, const uint8_t dot_mask) { uint8_t lead_number = lead_zero ? 0xFF : tm1637_symbols[0]; tm1637_set_segment_number(led, 3, lead_number, dot_mask & 0x01); tm1637_set_segment_number(led, 2, lead_number, dot_mask & 0x02); tm1637_set_segment_number(led, 1, lead_number, dot_mask & 0x04); tm1637_set_segment_number(led, 0, lead_number, dot_mask & 0x08); }
I have modified the above code to work for nRF52840 DK as well as nRF52840 Dongle.So only I won't use the SCL and SDA pins .
Problems:
1)In ESP32 , they have gpio_types.h file, where they declared the GPIO pin numbers in enum as gpio_num_t. But , for nordic chips , I don't find any such file for GPIO definition and declaration.Where can I find such declaration for GPIO pins in Nordic chips?
2)In tm1637.c file, line number : 98 , I have use hal_delay() function to delay.Is it the correct One?
3)I have finished all the program in DevAcademy for Nordic chips.In that they use Device tree to define LEDs and BUTTONs in the DK.But it won't give any steps to define the separete GPIO pins.If I have to declare the GPIO pins in Device tree , Please explain me How to do that...
One more thing.This program perfectly works for ESP32 and I got the desired OUTPUT on the Four Digit Seven Segment Display.This clearly shows the logic of the program is correct.I have to know , How can I implement same logic in nRF chips?
Please reply as soon as possible.
Thankyou.
-Vicky.