hx711-pico-c
|
#include <stdint.h>
#include <strings.h>
#include "hardware/pio.h"
#include "pico/mutex.h"
#include "pico/platform.h"
#include "hx711.h"
Go to the source code of this file.
Data Structures | |
struct | hx711_multi_t |
struct | hx711_multi_config_t |
Macros | |
#define | HX711_MULTI_CONVERSION_DONE_IRQ_NUM UINT8_C(0) |
PIO interrupt number which is set by the reader PIO State Machine when a conversion period ends. It is the period of time between a conversion ending and the next period beginning. More... | |
#define | HX711_MULTI_DATA_READY_IRQ_NUM UINT8_C(4) |
PIO interrupt number which is used between the awaiter and reader PIO State Machines to indicate when data is ready to be retrieved. It is not used directly within the main set of code, but is used to validate that the IRQ number is properly available. More... | |
#define | HX711_MULTI_ASYNC_READ_COUNT UINT8_C(NUM_PIOS) |
Only one instance of a hx711_multi can operate within a PIO. So the maximum number of concurrent asynchronous read processes is limited to the numeer of PIOs available. More... | |
#define | HX711_MULTI_ASYNC_PIO_IRQ_IDX UINT8_C(0) |
IRQ index defaults for PIO and DMA. More... | |
#define | HX711_MULTI_ASYNC_DMA_IRQ_IDX UINT8_C(0) |
#define | HX711_MULTI_MIN_CHIPS UINT8_C(1) |
Minimum number of chips to connect to a hx711_multi. More... | |
#define | HX711_MULTI_MAX_CHIPS UINT8_C(MIN(NUM_BANK0_GPIOS, 32)) |
The max number of chips could technically be the same as the number of bits output from the PIO State Machine. But this is always going to be limited by the number of GPIO input pins available on the RP2040. So we take the minimum of the two just in case it ever increases. More... | |
Typedefs | |
typedef void(* | hx711_multi_pio_init_t) (hx711_multi_t *const) |
typedef void(* | hx711_multi_program_init_t) (hx711_multi_t *const) |
Enumerations | |
enum | hx711_multi_async_state_t { HX711_MULTI_ASYNC_STATE_NONE = 0 , HX711_MULTI_ASYNC_STATE_WAITING , HX711_MULTI_ASYNC_STATE_READING , HX711_MULTI_ASYNC_STATE_DONE } |
State of the read as it moves through the async process. More... | |
Functions | |
static void | hx711_multi__init_asert (const hx711_multi_config_t *const config) |
static void | hx711_multi__init_pio (hx711_multi_t *const hxm) |
Subroutine for initialising PIO. More... | |
static void | hx711_multi__init_dma (hx711_multi_t *const hxm) |
Subroutine for initialising DMA. More... | |
static void | hx711_multi__init_irq (hx711_multi_t *const hxm) |
Subroutine for initialising IRQ. More... | |
static bool | hx711_multi__async_dma_irq_is_set (hx711_multi_t *const hxm) |
Whether a given hxm is the cause of the current DMA IRQ. More... | |
static bool | hx711_multi__async_pio_irq_is_set (hx711_multi_t *const hxm) |
Whether a given hxm is the cause of the current PIO IRQ. More... | |
static hx711_multi_t *const | hx711_multi__async_get_dma_irq_request () |
Get the hxm which caused the current DMA IRQ. Returns NULL if none found. More... | |
static hx711_multi_t *const | hx711_multi__async_get_pio_irq_request () |
Get the hxm which caused the current PIO IRQ. Returns NULL if none found. More... | |
static void | hx711_multi__async_start_dma (hx711_multi_t *const hxm) |
Triggers DMA reading; moves request state from WAITING to READING. More... | |
static bool | hx711_multi__async_is_running (hx711_multi_t *const hxm) |
Check whether an async read is currently occurring. More... | |
static void | hx711_multi__async_finish (hx711_multi_t *const hxm) |
Stop any current async reads and stop listening for DMA and PIO IRQs. More... | |
static void __isr __not_in_flash_func() | hx711_multi__async_pio_irq_handler () |
ISR handler for PIO IRQs. More... | |
static void __isr __not_in_flash_func() | hx711_multi__async_dma_irq_handler () |
ISR handler for DMA IRQs. More... | |
static bool | hx711_multi__async_add_reader (hx711_multi_t *const hxm) |
Adds hxm to the array for ISR access. Returns false if no space. More... | |
static void | hx711_multi__async_remove_reader (const hx711_multi_t *const hxm) |
Removes the given hxm from the request array. More... | |
static bool | hx711_multi__is_initd (hx711_multi_t *const hxm) |
Check whether the hxm struct has been initialised. More... | |
static bool | hx711_multi__is_state_machines_enabled (hx711_multi_t *const hxm) |
Check whether the hxm struct has PIO State Machines which are enabled. More... | |
void | hx711_multi_pinvals_to_values (const uint32_t *const pinvals, int32_t *const values, const size_t len) |
Convert an array of pinvals to regular HX711 values. More... | |
void | hx711_multi_init (hx711_multi_t *const hxm, const hx711_multi_config_t *const config) |
void | hx711_multi_close (hx711_multi_t *const hxm) |
Stop communication with all HX711s. More... | |
void | hx711_multi_set_gain (hx711_multi_t *const hxm, const hx711_gain_t gain) |
Sets the HX711s' gain. More... | |
void | hx711_multi_get_values (hx711_multi_t *const hxm, int32_t *const values) |
Fill an array with one value from each HX711. Blocks until values are obtained. More... | |
bool | hx711_multi_get_values_timeout (hx711_multi_t *const hxm, int32_t *const values, const uint timeout) |
Fill an array with one value from each HX711, timing out if failing to obtain values within the timeout period. More... | |
void | hx711_multi_async_start (hx711_multi_t *const hxm) |
Start an asynchronos read. This function is not mutex protected. More... | |
bool | hx711_multi_async_done (hx711_multi_t *const hxm) |
Check whether an asynchronous read is complete. This function is not mutex protected. More... | |
void | hx711_multi_async_get_values (hx711_multi_t *const hxm, int32_t *const values) |
Get the values from the last asynchronous read. This function is not mutex protected. More... | |
void | hx711_multi_sync (hx711_multi_t *const hxm, const hx711_gain_t gain) |
Attempt to synchronise all connected chips. This does not include a settling time. More... | |
uint32_t | hx711_multi_get_sync_state (hx711_multi_t *const hxm) |
Returns the state of each chip as a bitmask. The 0th bit is the first chip, 1th bit is the second, and so on. More... | |
bool | hx711_multi_is_syncd (hx711_multi_t *const hxm) |
Determines whether all chips are in sync. More... | |
Variables | |
hx711_multi_t * | hx711_multi__async_read_array [HX711_MULTI_ASYNC_READ_COUNT] |
Array of hxm for ISR to access. This is a global variable. More... | |
#define HX711_MULTI_ASYNC_DMA_IRQ_IDX UINT8_C(0) |
Definition at line 66 of file hx711_multi.h.
#define HX711_MULTI_ASYNC_PIO_IRQ_IDX UINT8_C(0) |
IRQ index defaults for PIO and DMA.
Definition at line 65 of file hx711_multi.h.
#define HX711_MULTI_ASYNC_READ_COUNT UINT8_C(NUM_PIOS) |
Only one instance of a hx711_multi can operate within a PIO. So the maximum number of concurrent asynchronous read processes is limited to the numeer of PIOs available.
Definition at line 60 of file hx711_multi.h.
#define HX711_MULTI_CONVERSION_DONE_IRQ_NUM UINT8_C(0) |
PIO interrupt number which is set by the reader PIO State Machine when a conversion period ends. It is the period of time between a conversion ending and the next period beginning.
Definition at line 43 of file hx711_multi.h.
#define HX711_MULTI_DATA_READY_IRQ_NUM UINT8_C(4) |
PIO interrupt number which is used between the awaiter and reader PIO State Machines to indicate when data is ready to be retrieved. It is not used directly within the main set of code, but is used to validate that the IRQ number is properly available.
Definition at line 52 of file hx711_multi.h.
#define HX711_MULTI_MAX_CHIPS UINT8_C(MIN(NUM_BANK0_GPIOS, 32)) |
The max number of chips could technically be the same as the number of bits output from the PIO State Machine. But this is always going to be limited by the number of GPIO input pins available on the RP2040. So we take the minimum of the two just in case it ever increases.
Definition at line 80 of file hx711_multi.h.
#define HX711_MULTI_MIN_CHIPS UINT8_C(1) |
Minimum number of chips to connect to a hx711_multi.
Definition at line 71 of file hx711_multi.h.
typedef void(* hx711_multi_pio_init_t) (hx711_multi_t *const) |
Definition at line 124 of file hx711_multi.h.
typedef void(* hx711_multi_program_init_t) (hx711_multi_t *const) |
Definition at line 125 of file hx711_multi.h.
State of the read as it moves through the async process.
Enumerator | |
---|---|
HX711_MULTI_ASYNC_STATE_NONE | |
HX711_MULTI_ASYNC_STATE_WAITING | |
HX711_MULTI_ASYNC_STATE_READING | |
HX711_MULTI_ASYNC_STATE_DONE |
Definition at line 85 of file hx711_multi.h.
|
static |
Adds hxm to the array for ISR access. Returns false if no space.
hxm |
Definition at line 405 of file hx711_multi.c.
References hx711_multi__async_read_array, and HX711_MULTI_ASYNC_READ_COUNT.
Referenced by hx711_multi_init().
|
static |
ISR handler for DMA IRQs.
Definition at line 383 of file hx711_multi.c.
References hx711_multi_t::_async_state, hx711_multi_t::_dma_channel, hx711_multi_t::_dma_irq_index, hx711_multi__async_finish(), hx711_multi__async_get_dma_irq_request(), hx711_multi__is_state_machines_enabled(), HX711_MULTI_ASYNC_STATE_DONE, HX711_MULTI_ASYNC_STATE_READING, and util_dma_get_irqn().
Referenced by hx711_multi__init_irq(), and hx711_multi__is_initd().
|
static |
Whether a given hxm is the cause of the current DMA IRQ.
hxm |
Definition at line 232 of file hx711_multi.c.
References hx711_multi_t::_dma_channel, hx711_multi_t::_dma_irq_index, and hx711_multi__is_initd().
Referenced by hx711_multi__async_get_dma_irq_request().
|
static |
Stop any current async reads and stop listening for DMA and PIO IRQs.
hxm |
|
static |
Get the hxm which caused the current DMA IRQ. Returns NULL if none found.
Definition at line 254 of file hx711_multi.c.
References hx711_multi__async_dma_irq_is_set(), hx711_multi__async_read_array, and HX711_MULTI_ASYNC_READ_COUNT.
Referenced by hx711_multi__async_dma_irq_handler().
|
static |
Get the hxm which caused the current PIO IRQ. Returns NULL if none found.
Definition at line 274 of file hx711_multi.c.
References hx711_multi__async_pio_irq_is_set(), hx711_multi__async_read_array, and HX711_MULTI_ASYNC_READ_COUNT.
Referenced by hx711_multi__async_pio_irq_handler().
|
static |
Check whether an async read is currently occurring.
hxm |
Definition at line 319 of file hx711_multi.c.
References hx711_multi_t::_async_state, hx711_multi__is_state_machines_enabled(), HX711_MULTI_ASYNC_STATE_READING, and HX711_MULTI_ASYNC_STATE_WAITING.
Referenced by hx711_multi_async_start(), hx711_multi_get_values(), and hx711_multi_get_values_timeout().
|
static |
ISR handler for PIO IRQs.
Definition at line 361 of file hx711_multi.c.
References hx711_multi_t::_async_state, hx711_multi_t::_pio, hx711_multi_t::_pio_irq_index, hx711_multi__async_get_pio_irq_request(), hx711_multi__async_start_dma(), hx711_multi__is_state_machines_enabled(), HX711_MULTI_ASYNC_STATE_WAITING, HX711_MULTI_CONVERSION_DONE_IRQ_NUM, util_pio_get_irq_from_index(), and util_pio_get_pis_from_pio_interrupt_num().
Referenced by hx711_multi__init_irq(), hx711_multi__is_initd(), and hx711_multi_close().
|
static |
Whether a given hxm is the cause of the current PIO IRQ.
hxm |
Definition at line 243 of file hx711_multi.c.
References hx711_multi_t::_pio, hx711_multi__is_initd(), and HX711_MULTI_CONVERSION_DONE_IRQ_NUM.
Referenced by hx711_multi__async_get_pio_irq_request().
|
static |
Removes the given hxm from the request array.
hxm |
Definition at line 421 of file hx711_multi.c.
References hx711_multi__async_read_array, and HX711_MULTI_ASYNC_READ_COUNT.
Referenced by hx711_multi_close().
|
static |
Triggers DMA reading; moves request state from WAITING to READING.
hxm |
Definition at line 294 of file hx711_multi.c.
References hx711_multi_t::_async_state, hx711_multi_t::_buffer, hx711_multi_t::_dma_channel, hx711_multi_t::_dma_irq_index, hx711_multi_t::_pio, hx711_multi_t::_reader_sm, hx711_multi__is_state_machines_enabled(), HX711_MULTI_ASYNC_STATE_READING, HX711_MULTI_ASYNC_STATE_WAITING, and util_pio_sm_clear_rx_fifo().
Referenced by hx711_multi__async_pio_irq_handler(), and hx711_multi_async_start().
|
static |
Definition at line 44 of file hx711_multi.c.
References hx711_multi_config_t::awaiter_prog, hx711_multi_config_t::awaiter_prog_init, hx711_multi_config_t::chips_len, hx711_multi_config_t::clock_pin, hx711_multi_config_t::data_pin_base, hx711_multi_config_t::dma_irq_index, HX711_MULTI_MAX_CHIPS, HX711_MULTI_MIN_CHIPS, hx711_multi_config_t::pio, hx711_multi_config_t::pio_init, hx711_multi_config_t::pio_irq_index, hx711_multi_config_t::reader_prog, hx711_multi_config_t::reader_prog_init, util_dma_irq_index_is_valid(), and util_pio_irq_index_is_valid().
Referenced by hx711_multi_init().
|
static |
Subroutine for initialising DMA.
hxm |
Casting dma_claim_unused_channel to uint is OK in this circumstance. Ordinarily it would return -1 if the claim failed, but since the flag is given to require a DMA channel, panic would be called instead.
Do not set ring buffer. ie. do not use channel_config_set_ring. If, for whatever reason, the DMA transfer fails, subsequent transfer invocations will reset the write address.
PIO RX FIFO output is 32 bits, so the DMA read needs to match or be larger.
DMA is always going to read from the same location, which is the PIO FIFO.
Each successive read from the PIO RX FIFO needs to be to the next array buffer position.
DMA transfers are paced based on the PIO RX DREQ.
Quiet needs to be disabled in order for DMA to raise an interrupt when each transfer is complete. This is necessary for this implementation to work.
Definition at line 108 of file hx711_multi.c.
References hx711_multi_t::_dma_channel, hx711_multi_t::_pio, hx711_multi_t::_reader_sm, and HX711_READ_BITS.
Referenced by hx711_multi_init().
|
static |
Subroutine for initialising IRQ.
hxm |
The idea here is that the PIO and DMA IRQs can be set up, enabled, and routed out to NVIC IRQs and be enabled at this point. If and when IRQs need to be disabled, they can be done at the source BEFORE being routed out to NVIC and triggering a system-wide interrupt.
DMA interrupts can always remain enabled. They will only trigger following a PIO interrupt.
The PIO source interrupt MUST REMAIN DISABLED until the point at which it is required to listen to them.
Definition at line 182 of file hx711_multi.c.
References hx711_multi_t::_dma_channel, hx711_multi_t::_dma_irq_index, hx711_multi_t::_pio, hx711_multi_t::_pio_irq_index, hx711_multi__async_dma_irq_handler(), hx711_multi__async_pio_irq_handler(), HX711_MULTI_CONVERSION_DONE_IRQ_NUM, util_dma_get_irqn(), util_pio_get_irq_from_index(), and util_pio_get_pis_from_pio_interrupt_num().
Referenced by hx711_multi_init().
|
static |
Subroutine for initialising PIO.
hxm |
Casting pio_claim_unused_sm to uint is OK in this circumstance. Ordinarily it would return -1 if the claim failed, but since the flag is given to require a PIO State Machine, panic would be called instead.
Definition at line 79 of file hx711_multi.c.
References hx711_multi_t::_awaiter_offset, hx711_multi_t::_awaiter_prog, hx711_multi_t::_awaiter_sm, hx711_multi_t::_pio, hx711_multi_t::_reader_offset, hx711_multi_t::_reader_prog, and hx711_multi_t::_reader_sm.
Referenced by hx711_multi_init().
|
static |
Check whether the hxm struct has been initialised.
hxm |
|
static |
Check whether the hxm struct has PIO State Machines which are enabled.
hxm |
bool hx711_multi_async_done | ( | hx711_multi_t *const | hxm | ) |
Check whether an asynchronous read is complete. This function is not mutex protected.
hxm |
Definition at line 767 of file hx711_multi.c.
References hx711_multi_t::_async_state, hx711_multi__is_initd(), and HX711_MULTI_ASYNC_STATE_DONE.
Referenced by hx711_multi_async_get_values(), hx711_multi_get_values(), hx711_multi_get_values_timeout(), and hx711_multi_set_gain().
void hx711_multi_async_get_values | ( | hx711_multi_t *const | hxm, |
int32_t *const | values | ||
) |
Get the values from the last asynchronous read. This function is not mutex protected.
hxm | |
values |
Definition at line 772 of file hx711_multi.c.
References hx711_multi_t::_buffer, hx711_multi_t::_chips_len, hx711_multi__is_initd(), hx711_multi_async_done(), and hx711_multi_pinvals_to_values().
Referenced by hx711_multi_get_values(), and hx711_multi_get_values_timeout().
void hx711_multi_async_start | ( | hx711_multi_t *const | hxm | ) |
Start an asynchronos read. This function is not mutex protected.
hxm |
Definition at line 734 of file hx711_multi.c.
References hx711_multi_t::_async_state, hx711_multi_t::_mut, hx711_multi_t::_pio, hx711_multi_t::_pio_irq_index, hx711_multi__async_is_running(), hx711_multi__async_start_dma(), hx711_multi__is_state_machines_enabled(), HX711_MULTI_ASYNC_STATE_WAITING, HX711_MULTI_CONVERSION_DONE_IRQ_NUM, and util_pio_get_irq_from_index().
Referenced by hx711_multi_get_values(), hx711_multi_get_values_timeout(), and hx711_multi_set_gain().
void hx711_multi_close | ( | hx711_multi_t *const | hxm | ) |
Stop communication with all HX711s.
hxm |
Definition at line 566 of file hx711_multi.c.
References hx711_multi_t::_async_state, hx711_multi_t::_awaiter_offset, hx711_multi_t::_awaiter_prog, hx711_multi_t::_awaiter_sm, hx711_multi_t::_dma_channel, hx711_multi_t::_dma_irq_index, hx711_multi_t::_mut, hx711_multi_t::_pio, hx711_multi_t::_pio_irq_index, hx711_multi_t::_reader_offset, hx711_multi_t::_reader_prog, hx711_multi_t::_reader_sm, hx711_multi__async_pio_irq_handler(), hx711_multi__async_remove_reader(), hx711_multi__is_initd(), HX711_MULTI_ASYNC_STATE_NONE, HX711_MULTI_CONVERSION_DONE_IRQ_NUM, util_dma_channel_set_quiet(), util_dma_get_irqn(), UTIL_INTERRUPTS_OFF_BLOCK, util_pio_get_irq_from_index(), and util_pio_get_pis_from_pio_interrupt_num().
uint32_t hx711_multi_get_sync_state | ( | hx711_multi_t *const | hxm | ) |
Returns the state of each chip as a bitmask. The 0th bit is the first chip, 1th bit is the second, and so on.
hxm |
Definition at line 862 of file hx711_multi.c.
References hx711_multi_t::_awaiter_sm, hx711_multi_t::_pio, and hx711_multi__is_state_machines_enabled().
Referenced by hx711_multi_is_syncd().
void hx711_multi_get_values | ( | hx711_multi_t *const | hxm, |
int32_t *const | values | ||
) |
Fill an array with one value from each HX711. Blocks until values are obtained.
hxm | |
values |
Definition at line 682 of file hx711_multi.c.
References hx711_multi__async_is_running(), hx711_multi__is_state_machines_enabled(), hx711_multi_async_done(), hx711_multi_async_get_values(), and hx711_multi_async_start().
bool hx711_multi_get_values_timeout | ( | hx711_multi_t *const | hxm, |
int32_t *const | values, | ||
const uint | timeout | ||
) |
Fill an array with one value from each HX711, timing out if failing to obtain values within the timeout period.
hxm | |
values | |
timeout | microseconds |
Definition at line 698 of file hx711_multi.c.
References hx711_multi__async_finish(), hx711_multi__async_is_running(), hx711_multi__is_state_machines_enabled(), hx711_multi_async_done(), hx711_multi_async_get_values(), hx711_multi_async_start(), and UTIL_INTERRUPTS_OFF_BLOCK.
void hx711_multi_init | ( | hx711_multi_t *const | hxm, |
const hx711_multi_config_t *const | config | ||
) |
Definition at line 516 of file hx711_multi.c.
References hx711_multi_t::_async_state, hx711_multi_t::_awaiter_prog, hx711_multi_t::_chips_len, hx711_multi_t::_clock_pin, hx711_multi_t::_data_pin_base, hx711_multi_t::_dma_irq_index, hx711_multi_t::_mut, hx711_multi_t::_pio, hx711_multi_t::_pio_irq_index, hx711_multi_t::_reader_prog, hx711_multi_config_t::awaiter_prog, hx711_multi_config_t::awaiter_prog_init, hx711_multi_config_t::chips_len, hx711_multi_config_t::clock_pin, hx711_multi_config_t::data_pin_base, hx711_multi_config_t::dma_irq_index, hx711_multi__async_add_reader(), hx711_multi__init_asert(), hx711_multi__init_dma(), hx711_multi__init_irq(), hx711_multi__init_pio(), HX711_MULTI_ASYNC_STATE_NONE, HX711_MUTEX_BLOCK, hx711_multi_config_t::pio, hx711_multi_config_t::pio_init, hx711_multi_config_t::pio_irq_index, hx711_multi_config_t::reader_prog, hx711_multi_config_t::reader_prog_init, util_gpio_set_contiguous_input_pins(), and util_gpio_set_output().
bool hx711_multi_is_syncd | ( | hx711_multi_t *const | hxm | ) |
Determines whether all chips are in sync.
hxm |
Definition at line 868 of file hx711_multi.c.
References hx711_multi_t::_chips_len, hx711_multi__is_state_machines_enabled(), and hx711_multi_get_sync_state().
void hx711_multi_pinvals_to_values | ( | const uint32_t *const | pinvals, |
int32_t *const | values, | ||
const size_t | len | ||
) |
Convert an array of pinvals to regular HX711 values.
pinvals | |
values | |
len | number of values to convert |
Definition at line 462 of file hx711_multi.c.
References hx711_get_twos_comp(), hx711_is_value_valid(), and HX711_READ_BITS.
Referenced by hx711_multi_async_get_values().
void hx711_multi_set_gain | ( | hx711_multi_t *const | hxm, |
const hx711_gain_t | gain | ||
) |
Sets the HX711s' gain.
hxm | |
gain |
Definition at line 655 of file hx711_multi.c.
References hx711_multi_t::_pio, hx711_multi_t::_reader_sm, hx711_gain_to_pio_gain(), hx711_is_pio_gain_valid(), hx711_multi__is_state_machines_enabled(), hx711_multi_async_done(), and hx711_multi_async_start().
void hx711_multi_sync | ( | hx711_multi_t *const | hxm, |
const hx711_gain_t | gain | ||
) |
Attempt to synchronise all connected chips. This does not include a settling time.
hxm | |
gain | initial gain to set to all chips |
Definition at line 853 of file hx711_multi.c.
References hx711_multi__is_initd(), hx711_multi_power_down(), hx711_multi_power_up(), and hx711_wait_power_down().
|
extern |
Array of hxm for ISR to access. This is a global variable.
Definition at line 40 of file hx711_multi.c.
Referenced by hx711_multi__async_add_reader(), hx711_multi__async_get_dma_irq_request(), hx711_multi__async_get_pio_irq_request(), and hx711_multi__async_remove_reader().