[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