Coder Social home page Coder Social logo

Get pin number about avr-hal HOT 6 CLOSED

wlwatkins avatar wlwatkins commented on July 30, 2024
Get pin number

from avr-hal.

Comments (6)

Rahix avatar Rahix commented on July 30, 2024 1

Hi @wlwatkins,

I'm trying to port the firmata firmware in rust, more as an exercise to learn arduino coding than anything else.

The specific challenge that you chose proves to be have some unique difficulties with the current API of avr-hal, as you have encountered :)

The problem lies in the fact that the API is mostly geared towards static use where pins are given predefined functions at compile-time and not dynamically, at runtime. You, however, need to do the latter here. So let's see what we can do. I'll begin by sketching the current situation:

In static world, a pin is represented as Pin<MODE, PIN> where MODE is the chosen pin function and PIN is a specific pin. For example, a concrete pin type might be Pin<Output, PC1>. Note that an object of this type can only represent this one specific pin in this specific mode. The next pin object would have a different type. For example, Pin<Output, PC2>. This allows for crazy optimizations, but of course is not dynamic at all.

So to cater dynamic usecases, at least to some degree, you can call the .downgrade() method. Calling that method on a pin object yields an object of a pin-generic type. In practice:

Pin<Output, PC1>::downgrade() -> Pin<Output, Dynamic>
Pin<Output, PC2>::downgrade() -> Pin<Output, Dynamic>
Pin<Output, PC3>::downgrade() -> Pin<Output, Dynamic>
// etc.

This means you can now dynamically handle any pin, as long as it is in the same mode. For example, you could put them all into an array:

let outputs = [
    pins.d0.into_output().downgrade(),
    pins.d1.into_output().downgrade(),
    pins.d2.into_output().downgrade(),
    pins.d3.into_output().downgrade(),
];

This gets us a step closer to your original question about pin numbers. But first, I have to tell you that we actually don't really know about the pin numbers at the moment. They only exist from the name of the fields in the Pins struct. But using an array like the one shown above, you can now index into it using pin numbers:

let pin_number = 3;

outputs[pin_number].set_high();

The remaining problem is one of handling different modes. This is where things get a bit tricky. There is no dynamic downgrade for the mode, like there is for the concrete pin. An alternative might be to define an enum which can hold the different pin modes:

use arduino_hal::port::{self, mode};

enum IoPin {
    Input(port::Pin<mode::Input<mode::AnyInput>>),
    Output(port::Pin<mode::Output>),
}

let pins: [IoPin; 4] = [
    IoPin::Input(pins.d0.downgrade().forget_imode()),
    IoPin::Input(pins.d1.downgrade().forget_imode()),
    IoPin::Input(pins.d2.downgrade().forget_imode()),
    IoPin::Input(pins.d3.downgrade().forget_imode()),
];

This should allow you to dynamically handle pins in either input or output mode. Let me know if this helps or if you have any questions...


Writing all this out makes me thing what we could add to the pins abstraction to make this easier. Maybe the HAL should already provide a way to get a fully downgraded array of all pins for users who need it. But I am not sure what such an API should look like...

from avr-hal.

Rahix avatar Rahix commented on July 30, 2024 1

Regarding the modification of the Hal, my understanding is that is we want to shift the industry into using rust for embedded, wouldn't we need the same features to be available?

For the majority of usecases you don't need dynamic pin configuration which is why everyone is focusing on the static pin API. It just allows catching a large number of potential bugs at compiletime which dynamic config cannot.

I agree that it would be nice to also provide a fully dynamic API, but it's just not as important for most users.

from avr-hal.

stappersg avatar stappersg commented on July 30, 2024

from avr-hal.

stappersg avatar stappersg commented on July 30, 2024

from avr-hal.

wlwatkins avatar wlwatkins commented on July 30, 2024

For me here are X and Y
X = Learn how to do embedded programming in rust
Y = Port Firmata in rust

I'm trying to port the firmata firmware in rust, more as an exercise to learn arduino coding than anything else.

- User wants to do X.
- User doesn't know how to do X, but thinks they can fumble their way to a solution if they can just manage to do Y.
- User doesn't know how to do Y either.
- User asks for help with Y.
- Others try to help user with Y, but are confused because Y seems like a strange problem to want to solve.
- After much interaction and wasted time, it finally becomes clear that the user really wants help with X, and that Y wasn't even a suitable solution for X.

from avr-hal.

wlwatkins avatar wlwatkins commented on July 30, 2024

Hi, thanks for the comprehensive explanation. I was thinking about reimplementing some kid of struct to store each pin, which can later access the avr_hal API to work with it. But your approach is indeed interesting, and I appreciate the time you've put in the explanation.
Regarding the modification of the Hal, my understanding is that is we want to shift the industry into using rust for embedded, wouldn't we need the same features to be available?
Anyway, I'll try this out thanks
thanks

from avr-hal.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.