-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
SIM3U support #57871
SIM3U support #57871
Conversation
This bumps the hal_silabs in order to add initial support for sim3u SoCs. WIP, because the revision wasn't merged, yet. Signed-off-by: Michael Zimmermann <[email protected]>
The following west manifest projects have been modified in this Pull Request:
Note: This message is automatically posted and updated by the Manifest GitHub Action. |
I don't understand the cause this error:
I'm not declaring a struct in any of those places and the variable names also don't shadow any other variables. |
Includes the SoC, pinctrl, flash and devicetree. I had to include the flash driver that early because I couldn't make zephyr compile without flash driver nodes in the device tree. Signed-off-by: Michael Zimmermann <[email protected]>
this serves two main purposes: - change the CPU clock via devicetree nodes - provide the APB frequency to device drivers via the clock driver interface Theoretically this could also support choosing between the available clock sources, but right now we only support LPOSC0 going into PLL0, going into AHB. Turning the PLL back off is also not supported since the only current usecase is to set the PLL frequency, turn it on, and switch the AHB over to it. Signed-off-by: Michael Zimmermann <[email protected]>
This is just the driver for banks 0,1,2,3. Bank 4 will come via a separate commit since it needs a different driver. Signed-off-by: Michael Zimmermann <[email protected]>
The code looks very similar to the normal one but it uses different hardware registers and has additional features to configure the high drive functionality. Signed-off-by: Michael Zimmermann <[email protected]>
This supports polling and interrupt APIs, but not the async API. Signed-off-by: Michael Zimmermann <[email protected]>
This only supports master mode right now. Signed-off-by: Michael Zimmermann <[email protected]>
This is the radiomodule used in the current GARDENA smart gateways. - SPI si4467 transceiver - controls an RGB LED via high drive pins. It's expected to mirror the state of 3 low-drive pins coming from the Linux SoC. - UART is connected to the Linux SoC. Usually it's used for PPP, but it can also be used for debugging when PPP is not active. Signed-off-by: Michael Zimmermann <[email protected]>
/* Set pin function to GPIO. | ||
* This is the only supported mode for now. | ||
*/ | ||
switch (pin) { |
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 entire switch statement looks like it should be reduced to 1 line of code. Is there really no function that takes the pin as a parameter?
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.
There isn't because we only use the register-descriptions of the HAL so there's not much abstraction or simplification on top of what the registers look like. We also can't just calculate the offset within the PBHD4_PBFSEL
register based on the pin number because pin5 is special and uses a different number of bits.
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 could use the FOR_EACH
macro from Zephyr to avoid this code duplication.
@@ -0,0 +1,194 @@ | |||
/* |
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 would suggest using a DT property to differentiate between high and non-high drive support, potentially incorporating Zephyr GPIO flags in a better way to enable that functionality, and combining these two gpio drivers.
There should be several drivers that can be used for reference.
Additionally, I just wanted to make sure that there is no potential overlap with the gecko silabs gpio drivers.
@fkokosinski might know as silabs maintainer.
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 would suggest using a DT property to differentiate between high and non-high drive support, potentially incorporating Zephyr GPIO flags in a better way to enable that functionality, and combining these two gpio drivers.
During development I thought about that but decided against it because the registers look completely different and have different data types, so it would end up in every function needing an if/else block. I didn't like that because it wouldn't save any lines of code, would make the code harder to follow and (less importantly) reduce performance since you have to do that check for every gpio API call.
config CLOCK_CONTROL_SI32_APB | ||
bool "SI32 APB clock control" | ||
default y | ||
depends on DT_HAS_SILABS_SI32_APB_ENABLED |
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.
Please add help strings to these 3 symbols in this file.
return -ENODEV; | ||
} | ||
|
||
if (config->freq != 20000000) { |
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.
Why is this check needed? What happens if clock freq in the device config is 20000000
?
GPIO_DEVICE_INIT(DT_NODELABEL(gpio##__suffix), __suffix, \ | ||
DT_REG_ADDR(DT_NODELABEL(gpio##__suffix))) | ||
|
||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio0), okay) |
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 use DT_FOREACH_STATUS_OKAY
for this GPIO_DEVICE_INIT_SI32
section?
/* Set pin function to GPIO. | ||
* This is the only supported mode for now. | ||
*/ | ||
switch (pin) { |
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 could use the FOR_EACH
macro from Zephyr to avoid this code duplication.
default y | ||
depends on DT_HAS_SILABS_SI32_USART_ENABLED | ||
select SERIAL_HAS_DRIVER | ||
select SERIAL_SUPPORT_INTERRUPT |
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.
Add help string.
config SPI_SI32 | ||
bool "SI32 SPI controller driver" | ||
default y | ||
depends on DT_HAS_SILABS_SI32_SPI_ENABLED |
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.
Add missing help string.
const: 2 | ||
|
||
disable-pullups: | ||
required: false |
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.
Remove this line. Required is false by default.
const: 2 | ||
|
||
nchannel-current-limit: | ||
required: false |
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.
Ditto in this file - remove required: false
.
/** @endcond */ | ||
|
||
/** Enable port bank current limit on this pin. */ | ||
#define SI32_GPIO_DS_ENABLE_CURRENT_LIMIT (0x0U << SI32_HD_GPIO_DS_POS) |
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.
Is this intentionally always 0?
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.
oops, nice catch
@@ -126,7 +126,7 @@ manifest: | |||
groups: | |||
- hal | |||
- name: hal_silabs | |||
revision: 249c08f16f5ee9663c8b225b68faf8ec54a21e8e | |||
revision: 785f4ed3aadb57d1b694be48c6f06fd5617df609 |
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.
Wrong revision? I think you want to point to your PR in the hal_silabs
repository with pull/<pr_num>/head
here.
/** | ||
* @name GPIO drive strength flags | ||
* | ||
* The drive strength flags are a Zephyr specific extension of the standard GPIO | ||
* flags specified by the Linux GPIO binding. Only applicable for Espressif | ||
* ESP32 SoCs. | ||
* | ||
* The interface supports two different drive strengths: | ||
* `DFLT` - The lowest drive strength supported by the HW | ||
* `ALT` - The highest drive strength supported by the HW | ||
* | ||
* @{ | ||
*/ | ||
/** @cond INTERNAL_HIDDEN */ |
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 was obviously copy&pasted from esp32. I'll fix that.
|
||
static bool flash_si32_valid_range(off_t offset, uint32_t size, bool write) | ||
{ | ||
if ((offset > SOC_NV_FLASH_SIZE) || ((offset + size) > SOC_NV_FLASH_SIZE)) { |
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.
off_t
can take negative value.
if (!flash_si32_valid_range(offset, size, false)) { | ||
return -EINVAL; | ||
} | ||
|
||
if (!size) { | ||
return 0; | ||
} |
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.
If size
is zero then no work will be done anyway, why not check this before validating range?
if (!size) { | ||
return 0; | ||
} |
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.
If size
is zero then no work will be done anyway, why not check this before validating range?
.erase_value = 0xff, | ||
}; | ||
|
||
static bool flash_si32_valid_range(off_t offset, uint32_t size, bool write) |
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.
Instead of the bool write
you could just pass op_alignment
and have universal check for range validation, just a suggestion.
if (!size) { | ||
return 0; | ||
} |
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.
Lots of validation happens before size == 0
decides that no work will be done.
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 split up the commits to make this easier to review. If you think that this PR is too big I can create multiple PRs as well.
Thank you for submitting this. However, I would prefer seeing this PR split into multiple PRs. An initial PR for adding the board with UART and GPIO support, and separate PRs for the remaining peripherals. The rationale is, that these various drivers need to be reviewed by different groups of people, which is difficult with a PR of this size - the other is the size of the PR itself. Reviewing changes to 60+ files with 3k+ changes is way more difficult than reviewing smaller changes.
Please see https://docs.zephyrproject.org/latest/contribute/contributor_expectations.html
Also, you lack documentation for the newly added board :) |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
I missed the stale notification 🤷 |
Here's the new PR: #64209 It's still big because I was only able to remove the highdrive UART driver and the SPI driver. Everything else is actually needed just to get UART working. |
This is cherry-picked from the PR already opened by Michael Zimmermann: zephyrproject-rtos#57871 Eventually, this commit should be updated with the new PR posted here: zephyrproject-rtos#64209 For this reason, do not merge substantial improvements over the original PR into this commit - it would (likely) be forgotten when switching to the new PR. Note: As requested by the reviewers upstream, the new PR is reduced in scope and therefore, the extracted parts need to be brought back manually. (cherry picked from commit a2ce87510b7ee119f3df179192ffb5ff083b6100) (squashed ab4505ff0d234c457aaa0d3ddc27833157d0d0ad)
I split up the commits to make this easier to review. If you think that this PR is too big I can create multiple PRs as well.
This depends on zephyrproject-rtos/hal_silabs#29
Overview: #55287