Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TM1637 7-segment display driver #21112

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Conversation

KSKNico
Copy link
Contributor

@KSKNico KSKNico commented Dec 27, 2024

Contribution description

This is a 4 digit display driver for the TM1637 7-segment display. It can display base 10 integers on a range from 9999 to -999, with or without leading zeros and variable brightness. The display can be cleared, too.

The driver was implemented according to a subset of all functionality and adheres to the specification .

Testing procedure

A test can be found in tests/drivers/tm1637/. The test covers all possible configurations for the driver and contains default pin configuration in tm1637_params.h.

Issues/PRs references

A similar display driver is still in review at PR #20981, but isn't compatible with this 4 pin display.

Images

20241227_184429

@github-actions github-actions bot added Area: doc Area: Documentation Area: tests Area: tests and testing framework Area: drivers Area: Device drivers labels Dec 27, 2024
Copy link
Member

@maribu maribu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thx, this looks quite good to me.

The CI has a few comments (check in the code view here):

  • One line is longer than 100 chars, please add a line break
  • A few files have no terminating newline. (Btw: What editor are you using? Maybe we can add a config to our repo that your editor will pick up. IMO it is better to automate such tedious style things and concentrate.)

Btw: I think negative numbers and leading zeros will result in the minus sign to be overwritten by a zero, or did I read the code incorrectly?

Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, great code quality! I have mostly nits below.

You've rightfully already mentioned #20981. IIRC, the idea was there to provide a unified driver for different kinds of 7-segment displays. How does yours differ and could it be integrated somehow? Otherwise, we should rename the driver in the other PR back to something more specific.

@mguetschow mguetschow added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jan 3, 2025
@riot-ci
Copy link

riot-ci commented Jan 3, 2025

Murdock results

✔️ PASSED

b1d57b2 Makefile changed

Success Failures Total Runtime
10289 0 10289 09m:53s

Artifacts

Copy link
Contributor

@Enoch247 Enoch247 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mostly reviewed the API only so far. I had a few suggestions that I noted. Thank you for the great contribution!

* @brief Configuration parameters
*
*/
tm1637_params_t params;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The driver should hold a pointer to tm1637_params_t. Not a copy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I based my works on the hd44780 driver. Why should my driver hold a pointer while the other keeps a copy of the parameters? Wouldn't the pointer method lead to problems with the lifetime of the parameter struct because it is managed by the user?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to repeat mistakes of the past ;)

Having a copy in RAM results having to spent precious RAM on it in addition to having to spent precious flash on it. With a pointer you only need to pay sizeof(void *) in RAM in addition to the ROM price.

TM1637_PW_12_16 = 0x05,
TM1637_PW_13_16 = 0x06,
TM1637_PW_14_16 = 0x07
} tm1637_brightness_t;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning of these values is unclear to me. I assume they are fractions of full brightness, but the doc does not say this. If they are fractions, why are some values skipped?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be addressed in the newest commit.

/**
* @brief see @ref tm1637_params_t
*/
#define TM1637_PARAM_CLK GPIO_PIN(0, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest setting the default to GPIO_UNDEF. Then add an assert to the init function to check that the pins are defined. There is no sane default you could ever define. Better to fail loudly then quietly do the wrong thing.

@KSKNico KSKNico requested a review from mguetschow February 19, 2025 15:47
Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is almost ready I'd say. If you bring the hardware one of those days I can test locally and confirm its working :)

Comment on lines 34 to 44
#define DATA_COMMAND 0x40

/**
* @brief Sets the brightness and display state to on/off
*/
#define DISPLAY_AND_CONTROL_COMMAND 0x80

/**
* @brief Sets the address where data is written
*/
#define ADDRESS_COMMAND 0xC0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define DATA_COMMAND 0x40
/**
* @brief Sets the brightness and display state to on/off
*/
#define DISPLAY_AND_CONTROL_COMMAND 0x80
/**
* @brief Sets the address where data is written
*/
#define ADDRESS_COMMAND 0xC0
#define COMMAND_DATA 0x40
/**
* @brief Sets the brightness and display state to on/off
*/
#define COMMAND_DISPLAY_AND_CONTROL 0x80
/**
* @brief Sets the address where data is written
*/
#define COMMAND_ADDRESS 0xC0

would keep them logically grouped (similar below for the bit mask). Not a must though.

/**
* @brief Delay between bits in milliseconds
*/
#define BIT_TIME_MS 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any maximum times? If not, then I'd say leave as is.

* @param[in] segments array of length 4 encoding the display's segments
*/
static void transmit_segments(const tm1637_t *dev,
const uint8_t *segments,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const uint8_t *segments,
const uint8_t segments[4],

or even

Suggested change
const uint8_t *segments,
const uint8_t segments[DIGIT_COUNT],

*
* @param[in] dev device descriptor of the display
*/
static void stop(const tm1637_t *dev)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static void stop(const tm1637_t *dev)
static void _stop(const tm1637_t *dev)

prefixing internal function with underscore is a common convention, I leave it to you to decide whether you want to adopt it or not

Comment on lines 7 to 8
CFLAGS += -DTM1637_PARAM_CLK=GPIO_PIN\(0\,\ 0\)
CFLAGS += -DTM1637_PARAM_DIO=GPIO_PIN\(0\,\ 1\)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CFLAGS += -DTM1637_PARAM_CLK=GPIO_PIN\(0\,\ 0\)
CFLAGS += -DTM1637_PARAM_DIO=GPIO_PIN\(0\,\ 1\)
CFLAGS += "-DTM1637_PARAM_CLK=GPIO_PIN(0, 0)"
CFLAGS += "-DTM1637_PARAM_DIO=GPIO_PIN(0, 1)"

I think ™️ that should also work without the backslash escapes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: doc Area: Documentation Area: drivers Area: Device drivers Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants