[GreatFET] ssp -> spi in libgreat
Garret Kelly
garret.kelly at gmail.com
Sun Sep 29 21:15:50 EDT 2019
Hi GreatFET gang,
I was looking at adding SPI support to libgreat, and was thinking
about how SSPs aren't SPI. Is the thinking that there should be an
API that looks something like:
platform_ssp_t *ssp = platform_ssp1_init();
spi_t *spi = platform_ssp_to_spi(ssp);
spi_write(spi, data, len);
And spi_t would have function pointers for write or transact and
spi_write would just be an inline call through that function pointer.
The platform_ssp_to_spi would build a spi_t that could unwrap the
spi_t back to platform_ssp_t so it could do the actual write.
But it does mean there would still need to be platform-specific init
code that knows how to 'get' an spi_t for a specific class. Maybe I'm
thinking about this wrong and spi_init should behave like:
spi_t *spi = spi_init(PLATFORM_SSP0);
spi_write(spi, data, len);
And spi_init would defer to platform_spi_init, which would know how to
turn specific platform_spi_handle_t (or some better name) into the
corresponding spi_t that wrapped the SSP it was referencing.
Having written that out I like the look of the approach because it
looks more concise, and has a very uniform pattern:
spi_init(PLATFORM_SPI_SPI); // bare SPI controller on lpc43xx (not SSP)
spi_init(PLATFORM_SPI_SSP0); // SPI on SSP0, etc.
But it does mean that there's going to be a big switch somewhere that
dispatches the choice of which static spi_t implementation struct to
return probably. I was thinking that one of the downsides of that
approach is that now platform_ssp_t isn't available when you want to
do more complex things, but I think that platform_spi_init could just
as easily be written in terms of the first approach:
spi_init(platform_spi_handle_t) calls platform_spi_init calls
platform_sspX_init, wraps and returns it with platform_ssp_to_spi,
etc.
The only remaining nit I have with the second approach is that
spi_init is not platform code, so making it take a platform type feels
gross. In the first approach there will be per-platform code for
particular classes, but no layering violations like in the second
approach.
Therefore, I think I'm concluding that the first approach is my
favourite. Before I go write this, does anyone have any different
conclusions or additional thoughts?
Sorry for rambling!
Thanks!
Garret
More information about the GreatFET
mailing list