generated from libhal/libhal-__device__
-
Notifications
You must be signed in to change notification settings - Fork 2
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
✨ Add tla2528 driver #5
Open
MichaelYKersey
wants to merge
16
commits into
libhal:main
Choose a base branch
from
MichaelYKersey:tla2528
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
5647074
copy tla2528 from SJSU-robotics
MichaelYKersey 60fb10f
adapted to be buildable
MichaelYKersey 335ca66
tla2528.test.cpp
MichaelYKersey 4cdb5ad
tla 2528 datasheet
MichaelYKersey 36dc193
include forrmating and demo namespaces
MichaelYKersey 5f0fb1a
update doc spacing
MichaelYKersey 962f136
add default input pin settings
MichaelYKersey 23dbb01
throw_if_invalid_channel helper formating
MichaelYKersey a97b9a0
fix adapter deconstuctors
MichaelYKersey edd0a36
mark technical debt
MichaelYKersey 72a2b16
rerun formator
MichaelYKersey f83d2db
move reset issue label
MichaelYKersey 8f8f4d1
update CMakeList
MichaelYKersey bea3799
doc update pass 2
MichaelYKersey 25a4b91
doc update pass 3
MichaelYKersey 77b7fc7
constexper and logic labels
MichaelYKersey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include <array> | ||
|
||
#include <libhal-expander/tla2528.hpp> | ||
#include <libhal-expander/tla2528_adapters.hpp> | ||
#include <libhal-util/bit.hpp> | ||
#include <libhal-util/i2c.hpp> | ||
#include <libhal-util/serial.hpp> | ||
#include <libhal-util/steady_clock.hpp> | ||
#include <libhal/input_pin.hpp> | ||
#include <libhal/units.hpp> | ||
|
||
#include <resource_list.hpp> | ||
|
||
using namespace hal::literals; | ||
using namespace std::chrono_literals; | ||
|
||
void application(resource_list& p_map) | ||
{ | ||
auto& terminal = *p_map.console.value(); | ||
auto& i2c = *p_map.i2c.value(); | ||
auto& steady_clock = *p_map.clock.value(); | ||
auto adc_mux = hal::expander::tla2528(i2c); | ||
std::array<hal::expander::tla2528_adc, 8> adcs{ | ||
make_adc(adc_mux, 0), make_adc(adc_mux, 1), make_adc(adc_mux, 2), | ||
make_adc(adc_mux, 3), make_adc(adc_mux, 4), make_adc(adc_mux, 5), | ||
make_adc(adc_mux, 6), make_adc(adc_mux, 7) | ||
}; | ||
|
||
while (true) { | ||
hal::print(terminal, "\nvalues:\n"); | ||
for (int i = 0; i < 8; i++) { | ||
hal::print<64>(terminal, "%d:%f\n", i, adcs[i].read()); | ||
} | ||
hal::delay(steady_clock, 500ms); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#include <array> | ||
|
||
#include <libhal-expander/tla2528.hpp> | ||
#include <libhal-expander/tla2528_adapters.hpp> | ||
#include <libhal-util/bit.hpp> | ||
#include <libhal-util/i2c.hpp> | ||
#include <libhal-util/serial.hpp> | ||
#include <libhal-util/steady_clock.hpp> | ||
#include <libhal/input_pin.hpp> | ||
#include <libhal/units.hpp> | ||
|
||
#include <resource_list.hpp> | ||
|
||
using namespace hal::literals; | ||
using namespace std::chrono_literals; | ||
|
||
void application(resource_list& p_map) | ||
{ | ||
auto& terminal = *p_map.console.value(); | ||
auto& i2c = *p_map.i2c.value(); | ||
auto& steady_clock = *p_map.clock.value(); | ||
auto gpi_expander = hal::expander::tla2528(i2c); | ||
std::array<hal::expander::tla2528_input_pin, 8> gpis{ | ||
make_input_pin(gpi_expander, 0), make_input_pin(gpi_expander, 1), | ||
make_input_pin(gpi_expander, 2), make_input_pin(gpi_expander, 3), | ||
make_input_pin(gpi_expander, 4), make_input_pin(gpi_expander, 5), | ||
make_input_pin(gpi_expander, 6), make_input_pin(gpi_expander, 7) | ||
}; | ||
|
||
while (true) { | ||
hal::print(terminal, "\nvalues:"); | ||
for (int i = 0; i < 8; i++) { | ||
hal::print<4>(terminal, "%x", gpis[i].level()); | ||
} | ||
hal::delay(steady_clock, 500ms); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include <array> | ||
|
||
#include <libhal-expander/tla2528.hpp> | ||
#include <libhal-expander/tla2528_adapters.hpp> | ||
#include <libhal-util/bit.hpp> | ||
#include <libhal-util/i2c.hpp> | ||
#include <libhal-util/serial.hpp> | ||
#include <libhal-util/steady_clock.hpp> | ||
#include <libhal/output_pin.hpp> | ||
#include <libhal/units.hpp> | ||
|
||
#include <resource_list.hpp> | ||
|
||
using namespace hal::literals; | ||
using namespace std::chrono_literals; | ||
|
||
void application(resource_list& p_map) | ||
{ | ||
constexpr bool demo_open_drain = false; | ||
|
||
auto& terminal = *p_map.console.value(); | ||
auto& i2c = *p_map.i2c.value(); | ||
auto& steady_clock = *p_map.clock.value(); | ||
auto gpo_expander = hal::expander::tla2528(i2c); | ||
constexpr hal::output_pin::settings output_pin_config = { | ||
.resistor = hal::pin_resistor::none, .open_drain = demo_open_drain | ||
}; | ||
std::array<hal::expander::tla2528_output_pin, 8> gpos{ | ||
make_output_pin(gpo_expander, 0, output_pin_config), | ||
make_output_pin(gpo_expander, 1, output_pin_config), | ||
make_output_pin(gpo_expander, 2, output_pin_config), | ||
make_output_pin(gpo_expander, 3, output_pin_config), | ||
make_output_pin(gpo_expander, 4, output_pin_config), | ||
make_output_pin(gpo_expander, 5, output_pin_config), | ||
make_output_pin(gpo_expander, 6, output_pin_config), | ||
make_output_pin(gpo_expander, 7, output_pin_config) | ||
}; | ||
|
||
// output counts in binary to go though all out put combinations | ||
hal::byte counter = 0; | ||
hal::print(terminal, "Starting Binary Count\n"); | ||
while (true) { | ||
counter++; | ||
for (int i = 0; i < 8; i++) { | ||
gpos[i].level(hal::bit_extract(hal::bit_mask::from(i), counter)); | ||
} | ||
hal::print<16>(terminal, "count:%x\n", counter); | ||
hal::delay(steady_clock, 200ms); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
#pragma once | ||
#include <libhal/i2c.hpp> | ||
#include <libhal/steady_clock.hpp> | ||
#include <libhal/units.hpp> | ||
|
||
namespace hal::expander { | ||
|
||
// adapters | ||
class tla2528_adc; | ||
class tla2528_input_pin; | ||
class tla2528_output_pin; | ||
|
||
/** | ||
* @brief tla2528 is a gpio expander & adc mux driver | ||
* | ||
* tla2528 has 8 pins which can be independently operated as an adc, | ||
* digital input, and digital out over i2c. The i2c address is configured by | ||
* resistors connected to the chip There are no options for internal pull up or | ||
* pull down resistors. The output pins have the option of push-pull or | ||
* open-drain. When in adc mode there is an option (UNIMPLEMENTED) to increase | ||
* reading granularity though sampling averaging. | ||
*/ | ||
class tla2528 | ||
{ | ||
public: | ||
enum class pin_mode : hal::byte | ||
{ | ||
analog_input, | ||
digital_input, | ||
digital_output_open_drain, | ||
digital_output_push_pull | ||
}; | ||
|
||
/** | ||
* @param p_i2c i2c bus of the device | ||
* | ||
* @param p_i2c_address i2c address configured on the tla, by default is set | ||
* to the i2c address of no resistors attached to address config pins. | ||
*/ | ||
tla2528(hal::i2c& p_i2c, hal::byte p_i2c_address = default_address); | ||
|
||
/** | ||
* @brief set what service a pin will provide | ||
* | ||
* @param p_mode tla2528::pin_mode enum of desired pin mode | ||
* @param p_channel which pin to configure | ||
* @throws hal::argument_out_of_domain - if p_channel out of range (>7) | ||
* @throws hal::resource_unavailable_try_again - if adapters are made for a | ||
* pin an exception may be thrown to prevent invalid behavior | ||
*/ | ||
void set_pin_mode(pin_mode p_mode, hal::byte p_channel); | ||
|
||
/** | ||
* @brief set digital output level pin | ||
* | ||
* The device will write to a register that caches the desired output state. | ||
* When a pin is in a digital output mode it will reference the desired state | ||
* cache. If the pin is not set to digital output it will just be stored. | ||
* | ||
* @param p_channel pin to set output | ||
* @param p_high the output level of the pin, true is high, false is low. | ||
* @throws hal::argument_out_of_domain - if p_channel out of range (>7) | ||
*/ | ||
void set_digital_out(hal::byte p_channel, bool p_high); | ||
/** | ||
* @brief set digital output levels on all pins | ||
* | ||
* The device will write to a register that caches the desired output state. | ||
* When a pin is in a digital output mode it will reference the desired state | ||
* cache. If the pin is not set to digital output it will just be stored. | ||
* | ||
* @param p_values The byte is used as a bit field of bool values to set the | ||
* pin outputs. i.e the 0th bit in the byte will set the 0 pin. If a bit is | ||
* 1 it is high. If the bit is 0 it is low. | ||
*/ | ||
void set_digital_bus_out(hal::byte p_values); | ||
/** | ||
* @brief read digital output state register of an output pin | ||
* | ||
* @param p_channel pin you would like to get the ouput value | ||
* @return true if the pin's output value register is high. If a pin is not set to | ||
* output pin the returned state will be used once it changes to an output | ||
* pin. | ||
* @throws hal::argument_out_of_domain - if p_channel out of range (>7) | ||
*/ | ||
bool get_digital_out(hal::byte p_channel); | ||
/** | ||
* @brief read digital output state register of all output pins | ||
* | ||
* @return The byte is used as a bit field of bool values to give the pins' | ||
* register. i.e the 0th bit in the byte will be the 0 pin's stored value. If | ||
* a bit is 1 it is high. If the bit is 0 it is low. If the pin is not set to | ||
* output pin the returned state will be used once it changes to an output | ||
* pin. | ||
*/ | ||
hal::byte get_digital_bus_out(); | ||
|
||
/** | ||
* @brief read the digital level of a pins | ||
* | ||
* @return true if the pin's digital read value is high. If a pin is not set to | ||
* digital input or output the returned value may not correlate with the true | ||
* value. | ||
* @throws hal::argument_out_of_domain - if p_channel out of range. (>7) | ||
* | ||
*/ | ||
bool get_digital_in(hal::byte p_channel); | ||
/** | ||
* @brief read the digital levels of all pins | ||
* | ||
* @return The byte is used as a bit field of bool values to give the pins' | ||
* digital read values. i.e the 0th bit in the byte will be the 0 pin's stored | ||
* value. If a bit is 1 it is high. If the bit is 0 it is low. If the pin is | ||
* not set to digital input or output the returned value may not correlate | ||
* with the true value. | ||
* | ||
*/ | ||
hal::byte get_digital_bus_in(); | ||
|
||
/** | ||
* @brief read the analog input of a pin. | ||
* | ||
* @param p_channel if out of range (>7) an exception will be thrown | ||
* @return adc reading as a float between 0 and 1 inclusive. If the pin is not | ||
* set to analog input the returned value may not correlate with the true | ||
* value. | ||
* @throws hal::argument_out_of_domain - if p_channel out of range. (>7) | ||
*/ | ||
float get_analog_in(hal::byte p_channel); | ||
|
||
friend tla2528_adc; | ||
friend tla2528_input_pin; | ||
friend tla2528_output_pin; | ||
|
||
private: | ||
// i2c address for no resistors | ||
static constexpr hal::byte default_address = 0x10; | ||
|
||
void set_analog_channel(hal::byte p_channel); | ||
void throw_if_invalid_channel(hal::byte p_channel); | ||
void throw_if_channel_occupied(hal::byte p_channel); | ||
void reset(); | ||
|
||
hal::i2c& m_i2c_bus; | ||
hal::byte m_i2c_address; | ||
hal::byte m_channel = 0x08; // stores selected channel to reduce i2c requests | ||
hal::byte m_object_created = 0x00; // tracks adapter channel reservations | ||
hal::byte m_gpo_value = 0x00; | ||
}; | ||
} // namespace hal::expander |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#pragma once | ||
#include <libhal-expander/tla2528.hpp> | ||
#include <libhal/adc.hpp> | ||
#include <libhal/input_pin.hpp> | ||
#include <libhal/output_pin.hpp> | ||
|
||
namespace hal::expander { | ||
|
||
class tla2528_output_pin : public hal::output_pin | ||
{ | ||
public: | ||
~tla2528_output_pin(); | ||
friend tla2528_output_pin make_output_pin( | ||
tla2528& p_tla2528, | ||
hal::byte p_channel, | ||
hal::output_pin::settings const& p_settings); | ||
|
||
private: | ||
tla2528_output_pin(tla2528& p_tla2528, | ||
hal::byte p_channel, | ||
hal::output_pin::settings const& p_settings); | ||
void driver_configure(settings const& p_settings); | ||
void driver_level(bool p_high); | ||
bool driver_level(); | ||
tla2528* m_tla2528 = nullptr; | ||
hal::byte m_channel; | ||
}; | ||
/** | ||
* @brief create a hal::output_pin driver using the tla2528 driver | ||
* | ||
* @param p_channel pin acting as an output pin | ||
* @param p_settings output pin settings, default is push-pull and no resistor | ||
* @throws hal::argument_out_of_domain - if p_channel out of range (>7) | ||
* @throws hal::resource_unavailable_try_again - if an adapter has already been | ||
* been made for the pin | ||
* @throws hal::operation_not_supported - if the settings could not be achieved. | ||
*/ | ||
tla2528_output_pin make_output_pin( | ||
tla2528& p_tla2528, | ||
hal::byte p_channel, | ||
hal::output_pin::settings const& p_settings = { | ||
.resistor = pin_resistor::none }); | ||
|
||
class tla2528_input_pin : public hal::input_pin | ||
{ | ||
public: | ||
~tla2528_input_pin(); | ||
friend tla2528_input_pin make_input_pin( | ||
tla2528& p_tla2528, | ||
hal::byte p_channel, | ||
hal::input_pin::settings const& p_settings); | ||
|
||
private: | ||
tla2528_input_pin(tla2528& p_tla2528, | ||
hal::byte p_channel, | ||
hal::input_pin::settings const& p_settings); | ||
void driver_configure(settings const& p_settings); | ||
bool driver_level(); | ||
tla2528* m_tla2528 = nullptr; | ||
hal::byte m_channel; | ||
}; | ||
/** | ||
* @brief create a hal::input_pin driver using the tla2528 driver | ||
* | ||
* @param p_channel pin acting as an input pin | ||
* @param p_settings input pin settings, default is no resistor | ||
* @throws hal::argument_out_of_domain - if p_channel out of range (>7) | ||
* @throws hal::resource_unavailable_try_again - if an adapter has already been | ||
* been made for the pin | ||
* @throws hal::operation_not_supported - if the settings could not be achieved. | ||
*/ | ||
tla2528_input_pin make_input_pin(tla2528& p_tla2528, | ||
hal::byte p_channel, | ||
hal::input_pin::settings const& p_settings = { | ||
.resistor = pin_resistor::none }); | ||
|
||
class tla2528_adc : public hal::adc | ||
{ | ||
public: | ||
~tla2528_adc(); | ||
friend tla2528_adc make_adc(tla2528& p_tla2528, hal::byte p_channel); | ||
|
||
private: | ||
tla2528_adc(tla2528& p_tla2528, hal::byte p_channel); | ||
float driver_read(); | ||
tla2528* m_tla2528 = nullptr; | ||
hal::byte m_channel; | ||
}; | ||
/** | ||
* @brief create a hal::adc driver using the tla2528 driver | ||
* | ||
* @param p_channel pin acting as an input pin | ||
* @throws hal::argument_out_of_domain - if p_channel out of range (>7) | ||
* @throws hal::resource_unavailable_try_again - if an adapter has already been | ||
* been made for the pin | ||
*/ | ||
tla2528_adc make_adc(tla2528& p_tla2528, hal::byte p_channel); | ||
|
||
} // namespace hal::expander |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well use the same terminology we use for the interfaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which interface are you referring to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hal::input_pin
andhal::output_pin
so you can use the terms input pin and output pin which assume they are digital.