mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 11:55:24 +00:00
os/pin_driver: support for time-multiplexed in/out
This patch equips the pin-driver framework with support for the time-multiplexed operation of a pin as output or input. This is needed when implementing I2C communication via a bit-banging driver. To operate pin in both directions, a driver obtains both a pin-state and a pin-control session for the same pin. The pin-state session can be used to sense the current pin state. The control session allows the client to set the pin to high or low (using the 'state' method), or to set it to high-impedance via the 'yield' method. Once switched to high-impedance, the pin can be used as input. Issue genodelabs/genode-allwinner#10
This commit is contained in:
parent
cd8538da9a
commit
49b4b8597d
@ -39,6 +39,8 @@ namespace Pin {
|
||||
{
|
||||
using Pin::Root<Irq_session_component<ID>, Direction::IN>::Root;
|
||||
};
|
||||
|
||||
enum class Level { LOW, HIGH, HIGH_IMPEDANCE };
|
||||
}
|
||||
|
||||
|
||||
@ -53,7 +55,7 @@ struct Pin::Driver : Interface
|
||||
/**
|
||||
* Set pin state
|
||||
*/
|
||||
virtual void pin_state(ID, bool enabled) = 0;
|
||||
virtual void pin_state(ID, Level) = 0;
|
||||
|
||||
/**
|
||||
* Return pin ID assigned to the specified session label
|
||||
|
@ -39,6 +39,12 @@ class Pin_control::Session_component : public Session_object<Session>
|
||||
|
||||
using Session_object<Session>::label;
|
||||
|
||||
void _state(Pin::Level level)
|
||||
{
|
||||
if (_assignment.target.constructed())
|
||||
_assignment.driver.pin_state(_assignment.target->id, level);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
using Pin_id = ID;
|
||||
@ -57,8 +63,15 @@ class Pin_control::Session_component : public Session_object<Session>
|
||||
*/
|
||||
void state(bool enabled) override
|
||||
{
|
||||
if (_assignment.target.constructed())
|
||||
_assignment.driver.pin_state(_assignment.target->id, enabled);
|
||||
_state(enabled ? Pin::Level::HIGH : Pin::Level::LOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pin_control::Session interface
|
||||
*/
|
||||
void yield() override
|
||||
{
|
||||
_state(Pin::Level::HIGH_IMPEDANCE);
|
||||
}
|
||||
|
||||
void update_assignment()
|
||||
|
@ -35,6 +35,8 @@ struct Pin_control::Connection : private Genode::Connection<Session>,
|
||||
{ }
|
||||
|
||||
void state(bool enabled) override { call<Rpc_state>(enabled); }
|
||||
|
||||
void yield() override { call<Rpc_yield>(); }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PIN_CONTROL_SESSION__CONNECTION_H_ */
|
||||
|
@ -40,8 +40,11 @@ struct Pin_control::Session : Genode::Session
|
||||
|
||||
virtual void state(bool) = 0;
|
||||
|
||||
virtual void yield() = 0;
|
||||
|
||||
GENODE_RPC(Rpc_state, void, state, bool);
|
||||
GENODE_RPC_INTERFACE(Rpc_state);
|
||||
GENODE_RPC(Rpc_yield, void, yield);
|
||||
GENODE_RPC_INTERFACE(Rpc_state, Rpc_yield);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PIN_CONTROL_SESSION__PIN_CONTROL_SESSION_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user