hx711-pico-c
hx711_multi.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2023 Daniel Robertson
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #ifndef HX711_MULTI_H_253BF37A_8356_462B_B8F9_39E09A7193E6
24 #define HX711_MULTI_H_253BF37A_8356_462B_B8F9_39E09A7193E6
25 
26 #include <stdint.h>
27 #include <strings.h>
28 #include "hardware/pio.h"
29 #include "pico/mutex.h"
30 #include "pico/platform.h"
31 #include "hx711.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
43 #define HX711_MULTI_CONVERSION_DONE_IRQ_NUM UINT8_C(0)
44 
52 #define HX711_MULTI_DATA_READY_IRQ_NUM UINT8_C(4)
53 
60 #define HX711_MULTI_ASYNC_READ_COUNT UINT8_C(NUM_PIOS)
61 
65 #define HX711_MULTI_ASYNC_PIO_IRQ_IDX UINT8_C(0)
66 #define HX711_MULTI_ASYNC_DMA_IRQ_IDX UINT8_C(0)
67 
71 #define HX711_MULTI_MIN_CHIPS UINT8_C(1)
72 
80 #define HX711_MULTI_MAX_CHIPS UINT8_C(MIN(NUM_BANK0_GPIOS, 32))
81 
85 typedef enum {
91 
92 typedef struct {
93 
94  uint _clock_pin;
96  size_t _chips_len;
97 
98  PIO _pio;
99 
100  const pio_program_t* _awaiter_prog;
101  pio_sm_config _awaiter_default_config;
104 
105  const pio_program_t* _reader_prog;
106  pio_sm_config _reader_default_config;
109 
111 
112  uint32_t _buffer[HX711_READ_BITS];
113 
117 
118 #ifndef HX711_NO_MUTEX
119  mutex_t _mut;
120 #endif
121 
122 } hx711_multi_t;
123 
124 typedef void (*hx711_multi_pio_init_t)(hx711_multi_t* const);
126 
127 typedef struct {
128 
132  uint clock_pin;
133 
138 
142  size_t chips_len;
143 
144 
150 
156 
157 
161  PIO pio;
162 
169 
170 
174  const pio_program_t* awaiter_prog;
175 
182 
183 
187  const pio_program_t* reader_prog;
188 
195 
197 
204 
205 static void hx711_multi__init_asert(
206  const hx711_multi_config_t* const config);
207 
213 static void hx711_multi__init_pio(hx711_multi_t* const hxm);
214 
220 static void hx711_multi__init_dma(hx711_multi_t* const hxm);
221 
227 static void hx711_multi__init_irq(hx711_multi_t* const hxm);
228 
238  hx711_multi_t* const hxm);
239 
249  hx711_multi_t* const hxm);
250 
258 
266 
272 static void hx711_multi__async_start_dma(
273  hx711_multi_t* const hxm);
274 
283  hx711_multi_t* const hxm);
284 
292  hx711_multi_t* const hxm);
293 
297 static void __isr __not_in_flash_func(hx711_multi__async_pio_irq_handler)();
298 
302 static void __isr __not_in_flash_func(hx711_multi__async_dma_irq_handler)();
303 
313  hx711_multi_t* const hxm);
314 
321  const hx711_multi_t* const hxm);
322 
330 static bool hx711_multi__is_initd(hx711_multi_t* const hxm);
331 
341  hx711_multi_t* const hxm);
342 
352  const uint32_t* const pinvals,
353  int32_t* const values,
354  const size_t len);
355 
356 void hx711_multi_init(
357  hx711_multi_t* const hxm,
358  const hx711_multi_config_t* const config);
359 
365 void hx711_multi_close(hx711_multi_t* const hxm);
366 
374  hx711_multi_t* const hxm,
375  const hx711_gain_t gain);
376 
385  hx711_multi_t* const hxm,
386  int32_t* const values);
387 
400  hx711_multi_t* const hxm,
401  int32_t* const values,
402  const uint timeout);
403 
410 void hx711_multi_async_start(hx711_multi_t* const hxm);
411 
420 bool hx711_multi_async_done(hx711_multi_t* const hxm);
421 
430  hx711_multi_t* const hxm,
431  int32_t* const values);
432 
442  hx711_multi_t* const hxm,
443  const hx711_gain_t gain);
444 
452 void hx711_multi_power_down(hx711_multi_t* const hxm);
453 
461 void hx711_multi_sync(
462  hx711_multi_t* const hxm,
463  const hx711_gain_t gain);
464 
473  hx711_multi_t* const hxm);
474 
483  hx711_multi_t* const hxm);
484 
485 #ifdef __cplusplus
486 }
487 #endif
488 
489 #endif
#define HX711_READ_BITS
Definition: hx711.h:49
hx711_gain_t
Definition: hx711.h:67
void hx711_multi_power_up(hx711_multi_t *const hxm, const hx711_gain_t gain)
Definition: hx711_multi.c:783
void hx711_multi_power_down(hx711_multi_t *const hxm)
Definition: hx711_multi.c:830
static void hx711_multi__async_finish(hx711_multi_t *const hxm)
Stop any current async reads and stop listening for DMA and PIO IRQs.
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.
Definition: hx711_multi.c:772
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.
Definition: hx711_multi.c:40
void hx711_multi_init(hx711_multi_t *const hxm, const hx711_multi_config_t *const config)
Definition: hx711_multi.c:516
void hx711_multi_set_gain(hx711_multi_t *const hxm, const hx711_gain_t gain)
Sets the HX711s' gain.
Definition: hx711_multi.c:655
hx711_multi_async_state_t
State of the read as it moves through the async process.
Definition: hx711_multi.h:85
@ HX711_MULTI_ASYNC_STATE_WAITING
Definition: hx711_multi.h:87
@ HX711_MULTI_ASYNC_STATE_NONE
Definition: hx711_multi.h:86
@ HX711_MULTI_ASYNC_STATE_READING
Definition: hx711_multi.h:88
@ HX711_MULTI_ASYNC_STATE_DONE
Definition: hx711_multi.h:89
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.
Definition: hx711_multi.c:243
static void __isr __not_in_flash_func() hx711_multi__async_pio_irq_handler()
ISR handler for PIO IRQs.
Definition: hx711_multi.c:361
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.
Definition: hx711_multi.c:254
void(* hx711_multi_program_init_t)(hx711_multi_t *const)
Definition: hx711_multi.h:125
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.
static bool hx711_multi__async_is_running(hx711_multi_t *const hxm)
Check whether an async read is currently occurring.
Definition: hx711_multi.c:319
static void hx711_multi__init_dma(hx711_multi_t *const hxm)
Subroutine for initialising DMA.
Definition: hx711_multi.c:108
static void hx711_multi__async_start_dma(hx711_multi_t *const hxm)
Triggers DMA reading; moves request state from WAITING to READING.
Definition: hx711_multi.c:294
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.
Definition: hx711_multi.c:274
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 timeo...
Definition: hx711_multi.c:698
bool hx711_multi_async_done(hx711_multi_t *const hxm)
Check whether an asynchronous read is complete. This function is not mutex protected.
Definition: hx711_multi.c:767
static void hx711_multi__init_asert(const hx711_multi_config_t *const config)
Definition: hx711_multi.c:44
static void __isr __not_in_flash_func() hx711_multi__async_dma_irq_handler()
ISR handler for DMA IRQs.
Definition: hx711_multi.c:383
void hx711_multi_async_start(hx711_multi_t *const hxm)
Start an asynchronos read. This function is not mutex protected.
Definition: hx711_multi.c:734
#define HX711_MULTI_ASYNC_READ_COUNT
Only one instance of a hx711_multi can operate within a PIO. So the maximum number of concurrent asyn...
Definition: hx711_multi.h:60
static bool hx711_multi__is_initd(hx711_multi_t *const hxm)
Check whether the hxm struct has been initialised.
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.
Definition: hx711_multi.c:853
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.
Definition: hx711_multi.c:682
static void hx711_multi__async_remove_reader(const hx711_multi_t *const hxm)
Removes the given hxm from the request array.
Definition: hx711_multi.c:421
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.
Definition: hx711_multi.c:462
bool hx711_multi_is_syncd(hx711_multi_t *const hxm)
Determines whether all chips are in sync.
Definition: hx711_multi.c:868
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,...
Definition: hx711_multi.c:862
void hx711_multi_close(hx711_multi_t *const hxm)
Stop communication with all HX711s.
Definition: hx711_multi.c:566
static void hx711_multi__init_pio(hx711_multi_t *const hxm)
Subroutine for initialising PIO.
Definition: hx711_multi.c:79
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.
Definition: hx711_multi.c:232
void(* hx711_multi_pio_init_t)(hx711_multi_t *const)
Definition: hx711_multi.h:124
static void hx711_multi__init_irq(hx711_multi_t *const hxm)
Subroutine for initialising IRQ.
Definition: hx711_multi.c:182
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.
Definition: hx711_multi.c:405
size_t chips_len
Number of HX711 chips connected.
Definition: hx711_multi.h:142
uint data_pin_base
Lowest GPIO pin number connected to a HX711 chip.
Definition: hx711_multi.h:137
uint dma_irq_index
Which index to use for a DMA interrupt. Either 0 or 1. Corresponds to DMA_IRQ[IRQ_INDEX] NVIC IRQ num...
Definition: hx711_multi.h:155
const pio_program_t * awaiter_prog
PIO awaiter program.
Definition: hx711_multi.h:174
hx711_multi_program_init_t awaiter_prog_init
PIO awaiter init function. This is called to set up the State Machine for the awaiter program....
Definition: hx711_multi.h:181
const pio_program_t * reader_prog
PIO reader program.
Definition: hx711_multi.h:187
hx711_multi_program_init_t reader_prog_init
PIO reader init function. This is called to set up the State Machine for the reader program....
Definition: hx711_multi.h:194
uint clock_pin
GPIO pin number connected to all HX711 chips.
Definition: hx711_multi.h:132
PIO pio
Which PIO to use. Either pio0 or pio1.
Definition: hx711_multi.h:161
hx711_multi_pio_init_t pio_init
PIO init function. This is called to set up any PIO functions (pio_*) as opposed to any State Machine...
Definition: hx711_multi.h:168
uint pio_irq_index
Which index to use for a PIO interrupt. Either 0 or 1. Corresponds to PIO[PIO_INDEX]_IRQ[IRQ_INDEX] N...
Definition: hx711_multi.h:149
uint _data_pin_base
Definition: hx711_multi.h:95
pio_sm_config _awaiter_default_config
Definition: hx711_multi.h:101
volatile hx711_multi_async_state_t _async_state
Definition: hx711_multi.h:116
uint _dma_irq_index
Definition: hx711_multi.h:115
uint _reader_offset
Definition: hx711_multi.h:108
const pio_program_t * _reader_prog
Definition: hx711_multi.h:105
pio_sm_config _reader_default_config
Definition: hx711_multi.h:106
uint _pio_irq_index
Definition: hx711_multi.h:114
mutex_t _mut
Definition: hx711_multi.h:119
const pio_program_t * _awaiter_prog
Definition: hx711_multi.h:100
size_t _chips_len
Definition: hx711_multi.h:96
uint _awaiter_offset
Definition: hx711_multi.h:103