Hallo Gerhard,
also jetzt wo du es sagst – der 'rustonian way' das zu implementieren wäre eigentlich eine API in dieser Art:
Code:
use crate::ports::*;
pub fn set_leds(value: u8) {
// set LEDs 1-3 connected on PORTC
PinGroup([c6, c5, c4])
.ensure_outputs()
.set(value);
// set LEDs 4-6 connected on PORTB
PinGroup([b0, b1, b7])
.ensure_outputs()
.set(value >> 3);
}
Oder gar das 'ensure_output()' in der '.set(...)' Funktion handhaben... aber da bin ich mir dann nicht sicher ob das nicht "unnötig Zyklen verschwendet"? Was meint Ihr dazu? Sollte so eine API lieber priorisieren dass der Pin auf jeden Fall als Output gesetzt ist und dazu das DDR Register jedes mal überschreiben? (So hat das jedenfalls die RP6Lib implementiert bei den LEDs.)
Und wenn man dann schon dabei ist, könnte man die LEDs die an verschiedenen PORTs angehängt sind ja auch gleich noch als 'MixedPinGroup' Typ implementieren..., dann bekäme man direkt eine Funktion '.set(...)' die dann die 6 verschiedenen Bits richtig ansteuert. Also (ein etwas vollständigeres Beispiel):
Code:
use crate::ports::*;
pub struct RobotBase {
LEDS: MixedPinGroup;
}
impl RobotBase {
const LEDS = MixedPinGroup([b0, b1, b7, c6, c5, c4]);
}
Und in der main dann:
Code:
use rp6::*;
pub extern "C" fn main() {
RobotBase::init();
loop {
RobotBase::LEDS.set(0b111111);
delay_ms(1000);
RobotBase::LEDS.set(0b000000);
delay_ms(1000);
}
}
Möglichkeiten über Möglichkeiten... was meint Ihr?
Grüße,
Roland
Lesezeichen