1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
//! # l293x
//! A platform independent, `no_std` driver to interface the
//! [L293 and L293D](https://www.ti.com/lit/ds/symlink/l293.pdf)
//! (Quadruple Half-H Driver) chips.
//!
//! This crate uses [`embedded-hal`](embedded_hal) traits to allow it to be reused in on
//! multiple platforms and boards.
//!
//! ## Basic usage
//! Include the library as a dependency in your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! l293x = { version = "0.1.0" }
//! ```
//!
//! Then you can instantiate a new L293x chip using the corresponding pins
//! from `embedded-hal`.
//!
//! E.g. with an ESP32 Chip using the `esp-hal` crate:
//!
//! ```
//! #[no_std]
//! #[no_main]
//! use esp_hal::{
//! gpio::{Io, Level, Output},
//! peripherals::Peripherals,
//! prelude::*,
//! };
//! use embedded_hal::digital::OutputPin;
//! use l293x::L293x;
//!
//! #[entry]
//! fn main() -> ! {
//! // Initialize the peripherals
//! let peripherals = Peripherals::take();
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//!
//! // Create a L293x half bridge motor driver
//! let mut l293x = L293x::new(
//! Output::new(io.pins.gpio34, Level::Low), // Input1
//! Output::new(io.pins.gpio35, Level::Low), // Input2
//! Output::new(io.pins.gpio32, Level::Low), // Enable12
//! Output::new(io.pins.gpio33, Level::Low), // Input3
//! Output::new(io.pins.gpio25, Level::Low), // Input4
//! Output::new(io.pins.gpio26, Level::Low), // Enable34
//! ).unwrap();
//!
//! loop {
//! for i in 1..=4 {
//! match i {
//! 1 => l293x.toggle_output1().unwrap(),
//! 2 => l293x.toggle_output2().unwrap(),
//! 3 => l293x.toggle_output3().unwrap(),
//! 4 => l293x.toggle_output4().unwrap(),
//! }
//! }
//! }
//! }
//! ```
//!
//! ## Usage as Motor driver
//!
//! The L293 and L293D drivers will most likely be used as motor drivers. Thus, it is
//! possible to pass [`embedded_hal::pwm::SetDutyCycle`] pins as inputs as well. This
//! allows to explicitly set the duties of the different outputs, which allows to control
//! the speed of the motor(s):
//!
//! ```
//! use l293x::L293x;
//!
//! // [...] create the PWM pins
//! let mut motors = L293x::new(
//! m1_forward,
//! m1_reverse,
//! m1_enable,
//! m2_forward,
//! m2_reverse,
//! m2_enable,
//! ).unwrap();
//!
//! loop {
//! // Full speed forward
//! motors.set_outpu1_duty_cycle_fully_on();
//! motors.set_outpu3_duty_cycle_fully_on();
//! delay::delay_millis(500);
//! motors.set_output1_duty_cycle_fully_off();
//! motors.set_output3_duty_cycle_fully_off();
//!
//! // Full speed reverse
//! motors.set_output2_duty_cycle_fully_on();
//! motors.set_output4_duty_cycle_fully_on();
//! delay::delay_millis(500);
//! motors.set_output2_duty_cycle_fully_off();
//! motors.set_output4_duty_cycle_fully_off();
//! }
//! ```
//!
//! ## Usage as input to other drivers
//!
//! In some cases, it might be necessary, to use parts of the controller as inputs to other
//! components. Because of this, The outputs of the L293x driver implement the
//! [embedded_hal] traits as well.
//!
//! Depending on the traits implemented by the corresponding input, the output might
//! either implement the [embedded_hal::digital::OutputPin], [embedded_hal::digital::StatefulOutputPin],
//! or the [embedded_hal::pwm::SetDutyCycle] traits.
//!
//! > **⚠️ WARNING:**
//! > Because the Half-H-Bridges 1 & 2 as well as 3 & 4 each share an enable pin, they can
//! > only be enabled or disabled together!
//!
//! ```
//! use l293x::L293x;
//! use embedded_hal::digital::OutputPin;
//!
//! let l293x = L293x::new(/* ... */).unwrap(); //!
//! // The outputs can be accessed using the y1-y4 fields
//! l293x.y1.set_high().unwrap();
//! ```
//!
//! ## Using only parts of the L293x chip
//!
//! In case only parts of the L293x chips shall be used, this crate implements
//! a [`HalfH`](bridge::HalfH) struct as well. It can be used to address a single Half-H bridge of
//! the L293x chip.
//!
//! ```
//! # use l293x::HalfH;
//! // [...] create the input pins
//! let mut gate = HalfH::new(input1, enable).unwrap();
//! ```
//!
//! For more information, see the struct documentation.
#![no_std]
#![deny(unstable_features, unsafe_code)]
mod l293x;
#[cfg(test)]
mod mock;
// Exports
pub mod bridge;
pub mod shared_pin;
pub use l293x::*;