hx711-pico-c
|
#include <assert.h>
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <strings.h>
#include "hardware/dma.h"
#include "hardware/gpio.h"
#include "hardware/irq.h"
#include "hardware/pio.h"
#include "pico/mutex.h"
#include "pico/platform.h"
#include "pico/time.h"
#include "pico/types.h"
#include "../include/hx711.h"
#include "../include/hx711_multi.h"
#include "../include/util.h"
Go to the source code of this file.
Functions | |
void | hx711_multi__init_asert (const hx711_multi_config_t *const config) |
void | hx711_multi__init_pio (hx711_multi_t *const hxm) |
Subroutine for initialising PIO. More... | |
void | hx711_multi__init_dma (hx711_multi_t *const hxm) |
Subroutine for initialising DMA. More... | |
void | hx711_multi__init_irq (hx711_multi_t *const hxm) |
Subroutine for initialising IRQ. More... | |
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... | |
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... | |
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... | |
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... | |
void | hx711_multi__async_start_dma (hx711_multi_t *const hxm) |
Triggers DMA reading; moves request state from WAITING to READING. More... | |
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) |
void __isr __not_in_flash_func() | hx711_multi__async_pio_irq_handler () |
ISR handler for PIO IRQs. More... | |
void __isr __not_in_flash_func() | hx711_multi__async_dma_irq_handler () |
ISR handler for DMA IRQs. More... | |
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... | |
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) |
static bool | hx711_multi__is_state_machines_enabled (hx711_multi_t *const hxm) |
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_power_up (hx711_multi_t *const hxm, const hx711_gain_t gain) |
void | hx711_multi_power_down (hx711_multi_t *const hxm) |
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 [] |
Array of hxm for ISR to access. This is a global variable. More... | |
bool hx711_multi__async_add_reader | ( | hx711_multi_t *const | hxm | ) |
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().
void __isr __not_in_flash_func() hx711_multi__async_dma_irq_handler | ( | ) |
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().
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.
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 |
Definition at line 335 of file hx711_multi.c.
References 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__is_initd(), HX711_MULTI_CONVERSION_DONE_IRQ_NUM, and util_pio_get_pis_from_pio_interrupt_num().
Referenced by hx711_multi__async_dma_irq_handler(), hx711_multi_get_values_timeout(), and hx711_multi_power_down().
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.
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().
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.
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().
bool hx711_multi__async_is_running | ( | hx711_multi_t *const | hxm | ) |
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().
void __isr __not_in_flash_func() hx711_multi__async_pio_irq_handler | ( | ) |
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().
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.
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().
void hx711_multi__async_remove_reader | ( | const hx711_multi_t *const | hxm | ) |
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().
void hx711_multi__async_start_dma | ( | hx711_multi_t *const | hxm | ) |
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().
void hx711_multi__init_asert | ( | const hx711_multi_config_t *const | config | ) |
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().
void hx711_multi__init_dma | ( | hx711_multi_t *const | hxm | ) |
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().
void hx711_multi__init_irq | ( | hx711_multi_t *const | hxm | ) |
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().
void hx711_multi__init_pio | ( | hx711_multi_t *const | hxm | ) |
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 |
Definition at line 439 of file hx711_multi.c.
References 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_sm, hx711_multi__async_dma_irq_handler(), hx711_multi__async_pio_irq_handler(), util_dma_get_irqn(), and util_pio_get_irq_from_index().
Referenced by hx711_multi__async_dma_irq_is_set(), hx711_multi__async_finish(), hx711_multi__async_pio_irq_is_set(), hx711_multi__is_state_machines_enabled(), hx711_multi_async_done(), hx711_multi_async_get_values(), hx711_multi_close(), hx711_multi_power_down(), hx711_multi_power_up(), and hx711_multi_sync().
|
static |
Definition at line 455 of file hx711_multi.c.
References hx711_multi_t::_awaiter_sm, hx711_multi_t::_pio, hx711_multi_t::_reader_sm, hx711_multi__is_initd(), and util_pio_sm_is_enabled().
Referenced by hx711_multi__async_dma_irq_handler(), hx711_multi__async_is_running(), hx711_multi__async_pio_irq_handler(), hx711_multi__async_start_dma(), hx711_multi_async_start(), hx711_multi_get_sync_state(), hx711_multi_get_values(), hx711_multi_get_values_timeout(), hx711_multi_is_syncd(), and hx711_multi_set_gain().
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_power_down | ( | hx711_multi_t *const | hxm | ) |
Definition at line 830 of file hx711_multi.c.
References hx711_multi_t::_awaiter_sm, hx711_multi_t::_clock_pin, hx711_multi_t::_mut, hx711_multi_t::_pio, hx711_multi_t::_reader_sm, hx711_multi__async_finish(), hx711_multi__is_initd(), HX711_MUTEX_BLOCK, and UTIL_INTERRUPTS_OFF_BLOCK.
Referenced by hx711_multi_sync().
void hx711_multi_power_up | ( | hx711_multi_t *const | hxm, |
const hx711_gain_t | gain | ||
) |
Definition at line 783 of file hx711_multi.c.
References hx711_multi_t::_awaiter_default_config, hx711_multi_t::_awaiter_offset, hx711_multi_t::_awaiter_sm, hx711_multi_t::_clock_pin, hx711_multi_t::_mut, hx711_multi_t::_pio, hx711_multi_t::_reader_default_config, hx711_multi_t::_reader_offset, hx711_multi_t::_reader_sm, hx711_gain_to_pio_gain(), hx711_is_pio_gain_valid(), hx711_multi__is_initd(), and HX711_MUTEX_BLOCK.
Referenced by hx711_multi_sync().
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().
hx711_multi_t* hx711_multi__async_read_array[] |
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().