-
Notifications
You must be signed in to change notification settings - Fork 2.1k
drivers/digit7seg: add 4-digit 7-segment display driver #20981
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
base: master
Are you sure you want to change the base?
Conversation
Hi @Enoch247, I’ve finished my PR! I'm sure it can be improved, especially the sha5461as_display function. Could you please review it when you have a moment? |
Thanks for the contribution. I'll try to review this tonight. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the level of abstraction provided by the driver is too low. I expected to be able to pass it a number or array of digits to display. Currently the driver requires applications to manually set a bitfield with each bit corresponding to the display's segments. The application must also know the mapping of the bits to segments.
597003f
to
9050c76
Compare
Thank you for reviewing my PR. |
9050c76
to
005250f
Compare
It is not my preference, but if you have a reason to do it this way, can you please describe it so that I better understand. |
BTW, in the future, please hold off to squash/force push until requested once a PR is submitted. It makes the process a bit easier. See here for some helpful tips. |
Great work adding the documentation for the driver! Its not always the fun part of writing code, but it will really help users of your driver in the future. |
61d694f
to
50d790a
Compare
Thanks. Sorry for the delay. I will set aside some time this weekend to look it over, if not sooner. |
As state before, I think that there needs to be a way for applications to send numbers to the display. As far as I see, the driver's API allows to manually set the display's segments, but that is the exception rather than the normal way an application would want to interact with a numeric display driver. Something like: int digit7seg_set(digit7seg_t *dev, int val, int scale);
int digit7seg_set_digit(digit7seg_t *dev, unsigned digit, unsigned val);
|
OK, I'll do it as soon as I can! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your work on this! Some first comments from my side below.
drivers/digit7seg/digit7seg.c
Outdated
/** | ||
* @ingroup drivers_digit7seg | ||
* @file | ||
* @brief Device driver for less than 5 digits of 7 segments without IC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @brief Device driver for less than 5 digits of 7 segments without IC | |
* @brief Device driver for up to 4 digits of 7 segments without IC |
do we really want such restriction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, most 7-digit segments are composed of 4 digits, which is easier to manage.
drivers/include/digit7seg.h
Outdated
* b the second.... dp the 8th bit. | ||
* | ||
* @return 0 on success | ||
* @return -1 when an incorrect digit is passed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @return -1 when an incorrect digit is passed | |
* @return -1 when an invalid index is passed |
?
drivers/digit7seg/doc.txt
Outdated
|
||
## About | ||
|
||
This driver was developed to works with [5461AS](http://www.topliteusa.com/uploadfile/2014/0825/A-5461AS.pdf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This driver was developed to works with [5461AS](http://www.topliteusa.com/uploadfile/2014/0825/A-5461AS.pdf) | |
This driver was developed to work with [5461AS](http://www.topliteusa.com/uploadfile/2014/0825/A-5461AS.pdf) |
drivers/digit7seg/doc.txt
Outdated
## About | ||
|
||
This driver was developed to works with [5461AS](http://www.topliteusa.com/uploadfile/2014/0825/A-5461AS.pdf) | ||
in a way that all 4 digits (and less) with 7 segments without integrated controller |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in a way that all 4 digits (and less) with 7 segments without integrated controller | |
in a way that up to 4 digits with 7 segments without integrated controller |
drivers/digit7seg/digit7seg.c
Outdated
uint32_t temp_value = value << (index * BYTE_BITS); | ||
uint32_t up_value = dev->value >> ((index + 1) * BYTE_BITS); | ||
up_value <<= ((index + 1) * BYTE_BITS); | ||
uint32_t down_value = ((0b00000001 << (index * BYTE_BITS)) - 1) & dev->value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe it's worth adding some explaining comments to what this code does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right
drivers/include/digit7seg.h
Outdated
|
||
#define DIGIT7SEG_MAX_DIGITS (4) /**< Max pin number, can be below or equal */ | ||
#ifndef DIGIT7SEG_TIMER_HZ | ||
# define DIGIT7SEG_TIMER_HZ MHZ(1) /**< default timer hz */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# define DIGIT7SEG_TIMER_HZ MHZ(1) /**< default timer hz */ | |
# define DIGIT7SEG_TIMER_HZ MHZ(1) /**< default timer hz */ |
as per the Coding Convention. please also check other places
#ifndef DIGIT7SEG_TIMER_HZ | ||
# define DIGIT7SEG_TIMER_HZ MHZ(1) /**< default timer hz */ | ||
#endif | ||
#ifndef DIGIT7SEG_DELAY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to prefix all those "over-writeable" parameters with CONFIG_
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You raise a good point, but as all drivers do it this way, is it worth doing it any other way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Older code my do otherwise, but my understanding is that new code should prefix with CONFIG_
if it is a value that is allowed to be changed/overridden and not just a constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Enoch247 is correct. The CONFIG_
prefix allows for easier grep
ing and allows to expose configuration options via KConfig.
Code not following this convention is due to the code base being older than this convention. And also: Reviewers will not always spot any issue or deviation from the coding convention
Hello @mguetschow I hope you're well! |
@Enoch247, 2 months later, it's done! :) |
@mguetschow @Enoch247 I've made all the requested changes, what do you think? |
I'm sorry I haven't found the time to take another look at it yet (it's on my todo), but one high-level remark: After another 7-segment display is now in with #21112, this driver should be renamed back to refer to the models it works with. In a separate step, a more generic 7-segment-driver could be introduced as a higher-level API to both #21112 and this one. |
The problem with renaming is that this driver can be used with any generic 7 segment display. So it doesn't make since to rename it after any hardware module. If you wanted to reserve the generic name for a top level API, I supose you cold prefix this one with I will try review the PR this coming week. |
Thank you, I look forward to hearing your comments on the PR! |
Hi @mguetschow @Enoch247, It seems the PR has been blocked for a long time, are there any problems? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thx.
I resolved all comments that have been addressed and added some of my own. Sorry that the review process as been a bit slow here; all maintainers are volunteers and sometimes life get's in the way.
Feel free to ping me again when this is ready. You may squash at will to safe one round-trip-time before getting this merged.
#ifndef DIGIT7SEG_TIMER_HZ | ||
# define DIGIT7SEG_TIMER_HZ MHZ(1) /**< default timer hz */ | ||
#endif | ||
#ifndef DIGIT7SEG_DELAY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Enoch247 is correct. The CONFIG_
prefix allows for easier grep
ing and allows to expose configuration options via KConfig.
Code not following this convention is due to the code base being older than this convention. And also: Reviewers will not always spot any issue or deviation from the coding convention
/** | ||
* @brief Display bitfield for numbers between [0, 9] | ||
*/ | ||
static const uint8_t digit7seg_bitfield[] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this really be in the header?
Every compilation unit that actually makes use of this array will end up adding its own copy. If it would be added to a C file, we don't get duplicates.
* @param[in] value the value between [0, 9] | ||
* | ||
*/ | ||
int digit7seg_set_int_value(digit7seg_t *dev, int index, uint8_t value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int digit7seg_set_int_value(digit7seg_t *dev, int index, uint8_t value); | |
int digit7seg_set_int_value(digit7seg_t *dev, unsigned index, uint8_t value); |
Since negative indices are not allowed per API doc, we could encode this also into thr type.
* will be displayed as 234,1 but with | ||
* precision = 100 it will be 34,15 | ||
*/ | ||
int digit7seg_set_float_value(digit7seg_t *dev, float value, int precision); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We support a lot of MCUs that do not have an FPU. And soft FPU implementations are surprisingly large (in terms of ROM size) and also slowish.
How about providing the value as integer type and a second integer gives the position of the decimal?
E.g. value=1337
and decimal=2
would be printed as 13.37
?
Do you have examples of other such generic 7 segment displays? I'd just like to confirm that the driver would indeed fit them, too. Otherwise I'd favor your suggestion of prefixing with |
Contribution description
Added riot/drivers/sha5461as to control a 4-digit 7-segment display (plus decimal point).Testing procedure
A test is available in tests/drivers/sha5461as, designed for the Arduino Nano 33 BLE. The test will display "8" segment by segment on each digit, followed by "RIOT," and then it will stop.Issues/PRs references