Skip to content
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

Create some examples which demonstrate realistic use-cases #284

Open
johnnyegel opened this issue Nov 17, 2020 · 5 comments
Open

Create some examples which demonstrate realistic use-cases #284

johnnyegel opened this issue Nov 17, 2020 · 5 comments
Labels
good first issue Good for newcomers

Comments

@johnnyegel
Copy link
Contributor

All examples seems to put all code in the main() function, and demonstrate some static condition happening once. However, this does not reflect any real use cases, and I struggle really hard to implement anything actually useful using the HAL (unless of course I would put all logic into the main() function). There should be some examples which shows actual useful use-cases, and not just PoCs.

For example, one thing I failed to implement: Create a simple "driver struct", which takes an SPI instance with DMA support (WriteDma trait) and a viable buffer (static mut!) via the new() function. Then implement a send() function for this struct which generate a new byte sequence in the buffer, and transmit it using DMA. The send function returns the "Transmit" instance. Then, in the main loop, call send() once every second (or similar).

This would be an actual useful example, as dynamically filling a buffer with data and then transmitting it with DMA is something you would do in a real-life application (compared to sending some static data once in the main function). Further, using Peripherals in driver structs (in separate driver modules) is also typically something you would want to do when creating libraries.
(I would love to provide such examples myself, but I am simply not remotely capable of making anything work except in said main() function).

@johnnyegel johnnyegel changed the title Create some examples which present realistic usage Create some examples which demonstrate realistic use-cases Nov 17, 2020
@TheZoq2
Copy link
Member

TheZoq2 commented Nov 20, 2020

I agree, DMA, and probably some other modules really do need a better usage example.

In the meantime, I have a use case for DMA that is similar to what you describe here https://gitlab.com/TheZoq2/ws2812-spi-dma/-/blob/master/src/lib.rs that might be of interest

@TheZoq2 TheZoq2 added the good first issue Good for newcomers label Nov 20, 2020
@thalesfragoso
Copy link
Member

I'm not sure if the HAL repo is the best place for such examples. I see the examples as just a place to show how to use the peripheral interface/abstraction created by the HAL, real world examples can get quite complex and we would need to maintain them at each breaking PR, which can be a lot of work for people making already big PRs.

A better place for this is probably the showcase or other repositories like that. I guess it all depends on how real you want these examples to be, if is just more complex examples that might be okay, but is hard to draw a line.

As a side note, another "real world example" for the F1: https://github.com/thalesfragoso/keykey

@johnnyegel
Copy link
Contributor Author

johnnyegel commented Nov 23, 2020

I agree, DMA, and probably some other modules really do need a better usage example.
In the meantime, I have a use case for DMA that is similar to what you describe here https://gitlab.com/TheZoq2/ws2812-spi-dma/-/blob/master/src/lib.rs that might be of interest

The really fun thing here is that this use-case is exactly what I was trying to make myself ;) So thank you very much 👍

I also discovered the Showcase repo / page some time after posting this request. A lot of useful stuff in there for sure, but this is way over on the other side of complexity once more.

I really was after some really basic example, which shows the bare minimum on how to use a peripheral for something close to a real-life use case. Lets take the SPI-DMA example for instance (which was the one I was mainly interested in at the time). This example has the following limitations:

  • It sends a static immutable string (normally, data to send is generated by code)
  • It sends the message once (normally, a buffer is reused to send multiple and possibly different messages)
  • SPI sending is never done in the main() function (except of course in bare minimum examples that is).

This example would be WAY much better if:

  • It generates some data in a buffer (random numbers or simply a sequence from 1..10 would suffice)
  • It sends these data periodically in a loop. That is: Send, Wait 1 second, repeat...
  • It calls a send_my_data() function providing the proper abstraction (the WriteDma trait), which actually generates the data and handles the sending. Preferably, this function returns the Transmit reference, which in turn is waited on in the main loop.

Still, a very simple example, and the additional maintenance would be minimal. But oh so very much more useful to noobs like myself.

Thanks to TheZoq2 however, I can now probably manage to create such an example myself and provide a Pull Request. So once more, thanks a lot for your input on this :)

@johnnyegel
Copy link
Contributor Author

I agree, DMA, and probably some other modules really do need a better usage example.

In the meantime, I have a use case for DMA that is similar to what you describe here https://gitlab.com/TheZoq2/ws2812-spi-dma/-/blob/master/src/lib.rs that might be of interest

It seems this example use the 0.6.x version of the HAL. When attempting to create a pull request for this, it of course was no good, as the Transferable trait has been removed in 0.7.0. It's probably really obvious to anyone that actually know Rust. But I am really not able to figure out how to actually make the wait() function of the Transfer "instance" callable without this trait being implemented. I would like to fix this, but I have (yet again) struggled for hours trying to figure out how this all hangs together, without being able to :/

@pdgilbert
Copy link

FWIW, I am a newbie struggling with some of the same issues and started keeping a scoreboard of my success working out examples. (https://pdgilbert.github.io/eg_stm_hal/) There are some that are a small bit more realistic than what can be put in a crate's examples. The oled_gps example reads a gps on USART and displays on OLED with i2c. The lora_spi_gps example reads a gps on USART and transmits over LoRa using the spi.

Unfortunately, neither of these use dma. I have been struggling with dma in two simpler examples, serial_string and echo_string. My problem is that I am trying to make the examples work with multiple stm32*xx_hal's and the hals are presenting different APIs. I hoped that embedded-dma might solve that but so far no luck. (I think embedded-dma's read_buffer() and write_buffer() may be the answer but have not found examples of these implemented in any of the stm32*xx_hals.)

A variation of your not being able to create a pull request has been one of my main problems as a newbie: many examples depend on such old versions of everything that they really no longer work. The examples included with the stm32*xx_hal's are better in this respect but not perfect. (Some hals don't seem to have their CI running their examples.)

BTW, if anyone can point me to stm32*xx_hals testing embedded-hal v 1.0.0 alpha.4 I would appreciate it. The rust-radio-sx127x crate to used in the lora_spi_gps example has switched to e-h 1.0.0 alpha.4 and I would like to test it. (For stm32f4xx-hal I do have a pointer to stm32-rs/stm32f4xx-hal#144, just have not figured out how to use it yet.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

4 participants