Skip to content

drivers: spi: introduce basic spi driver for wch #90243

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

Merged
merged 2 commits into from
May 29, 2025

Conversation

VynDragon
Copy link
Collaborator

introduces a basic SPI driver for CH32 series

@VynDragon
Copy link
Collaborator Author

Only tested on ch32v203 for now, will test more later.

@VynDragon VynDragon requested a review from nzmichaelh May 20, 2025 21:31
Copy link
Collaborator

@nzmichaelh nzmichaelh left a comment

Choose a reason for hiding this comment

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

Looking good, thanks!


struct spi_wch_config {
SPI_TypeDef *regs;
const struct pinctrl_dev_config *pcfg;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: for consistency with the other WCH drivers, call this 'pin_cfg'.

SPI_TypeDef *regs;
const struct pinctrl_dev_config *pcfg;
const struct device *clk_dev;
uint8_t clk_id;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: s/clk_id/clock_id/


#include <ch32fun.h>

#define SPI_CTLR1_LSBFIRST ((uint16_t)0x0080)
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: Zephyr style seems to be to use BIT(7).

uint8_t div = 0;
int div_val = 2;

for (;div < 8; div++) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: use for (div = 0; div < 8; div++) so the initialisation is next to the first use.

}
div_val *= 2;
}
return div;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: blank line before

spi_context_cs_control(&data->ctx, true);

/* Start SPI *AFTER* setting CS */
cfg->regs->CTLR1 |= SPI_CTLR1_SPE;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add a SPI_Typedef *regs = cfg->regs above and use it everywhere.

while (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)) {
if (spi_context_tx_buf_on(&data->ctx)) {
cfg->regs->DATAR = *(uint8_t *)(data->ctx.tx_buf);
while(!(cfg->regs->STATR & SPI_STATR_TXE)) {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

For consistency, use while ((regs->STATR & SPI_START_TXE) != 0U) { }

Copy link
Collaborator Author

@VynDragon VynDragon May 21, 2025

Choose a reason for hiding this comment

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

not quite... more like while ((regs->STATR & SPI_START_TXE) == 0U) { }

cfg->regs->DATAR = *(uint8_t *)(data->ctx.tx_buf);
while(!(cfg->regs->STATR & SPI_STATR_TXE)) {}
} else {
cfg->regs->DATAR = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm pretty sure this should still wait for TXE before writing, even if it's writing a zero.

cfg->regs->DATAR = 0;
}
spi_context_update_tx(&data->ctx, 1, 1);
while(!(cfg->regs->STATR & SPI_STATR_RXNE)) {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

ditto re: testing for a flag.

@VynDragon
Copy link
Collaborator Author

(all changes you suggested were done @nzmichaelh)

@VynDragon
Copy link
Collaborator Author

VynDragon commented May 22, 2025

CH32V00x pinctrl for SPI looks very wrong
Edit: ok no they're just weird and incomplete.

@VynDragon
Copy link
Collaborator Author

Tested working on ch32v006 with st7567 so ill assume it works on everything else.

nzmichaelh
nzmichaelh previously approved these changes May 24, 2025
Copy link
Collaborator

@nzmichaelh nzmichaelh left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!


spi2: spi@40003800 {
compatible = "wch,spi";
reg = <40003800 0x24>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
reg = <40003800 0x24>;
reg = <0x40003800 0x24>;

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

VynDragon added 2 commits May 26, 2025 13:22
introduces a basic SPI driver for CH32 series

Signed-off-by: Camille BAUD <[email protected]>
This fixes incorrect/incomplete pinctrl for CH32V006

Signed-off-by: Camille BAUD <[email protected]>
Copy link

@kartben kartben merged commit 11a18da into zephyrproject-rtos:main May 29, 2025
26 checks passed
@VynDragon VynDragon deleted the wch_spi branch May 30, 2025 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Pinctrl area: RISCV RISCV Architecture (32-bit & 64-bit) area: SPI SPI bus platform: WinChipHead
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants