Updates along with SDK1.3.0 release (#181)
Bug fixes and new examples Co-authored-by: Paulo Marques <pm@quant-insight.com> Co-authored-by: martin <admin@crossleys.biz> Co-authored-by: matiasilva <matias.silva@raspberrypi.com> Co-authored-by: Uri Shaked <uri@urishaked.com> Co-authored-by: Diego Solano <diegosolano@gmail.com> Co-authored-by: Andrew Scheller <andrew.scheller@raspberrypi.com> Co-authored-by: Adrian Hesketh <a-h@users.noreply.github.com> Co-authored-by: Emircan Gündoğdu <58917386+emircangun@users.noreply.github.com> Co-authored-by: Josef Wegner <80200012+josefwegner@users.noreply.github.com> Co-authored-by: pmarques-dev <72901351+pmarques-dev@users.noreply.github.com> Co-authored-by: Paulo Marques <pm@quant-insight.com> Co-authored-by: mjcross <mjcross@users.noreply.github.com> Co-authored-by: martin <admin@crossleys.biz>
This commit is contained in:
19
pio/ir_nec/nec_receive_library/CMakeLists.txt
Normal file
19
pio/ir_nec/nec_receive_library/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
# build a normal library
|
||||
#
|
||||
add_library(nec_receive_library nec_receive.c)
|
||||
|
||||
# invoke pio_asm to assemble the state machine program
|
||||
#
|
||||
pico_generate_pio_header(nec_receive_library ${CMAKE_CURRENT_LIST_DIR}/nec_receive.pio)
|
||||
|
||||
target_link_libraries(nec_receive_library PRIVATE
|
||||
pico_stdlib
|
||||
hardware_pio
|
||||
)
|
||||
|
||||
# add the `binary` directory so that the generated headers are included in the project
|
||||
#
|
||||
target_include_directories (nec_receive_library PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
79
pio/ir_nec/nec_receive_library/nec_receive.c
Normal file
79
pio/ir_nec/nec_receive_library/nec_receive.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2021 mjcross
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// SDK types and declarations
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/clocks.h" // for clock_get_hz()
|
||||
|
||||
#include "nec_receive.h"
|
||||
|
||||
// import the assembled PIO state machine program
|
||||
#include "nec_receive.pio.h"
|
||||
|
||||
// Claim an unused state machine on the specified PIO and configure it
|
||||
// to receive NEC IR frames on the given GPIO pin.
|
||||
//
|
||||
// Returns: the state machine number on success, otherwise -1
|
||||
int nec_rx_init(PIO pio, uint pin_num) {
|
||||
|
||||
// disable pull-up and pull-down on gpio pin
|
||||
gpio_disable_pulls(pin_num);
|
||||
|
||||
// install the program in the PIO shared instruction space
|
||||
uint offset;
|
||||
if (pio_can_add_program(pio, &nec_receive_program)) {
|
||||
offset = pio_add_program(pio, &nec_receive_program);
|
||||
} else {
|
||||
return -1; // the program could not be added
|
||||
}
|
||||
|
||||
// claim an unused state machine on this PIO
|
||||
int sm = pio_claim_unused_sm(pio, true);
|
||||
if (sm == -1) {
|
||||
return -1; // we were unable to claim a state machine
|
||||
}
|
||||
|
||||
// configure and enable the state machine
|
||||
nec_receive_program_init(pio, sm, offset, pin_num);
|
||||
|
||||
return sm;
|
||||
}
|
||||
|
||||
|
||||
// Validate a 32-bit frame and store the address and data at the locations
|
||||
// provided.
|
||||
//
|
||||
// Returns: `true` if the frame was valid, otherwise `false`
|
||||
bool nec_decode_frame(uint32_t frame, uint8_t *p_address, uint8_t *p_data) {
|
||||
|
||||
// access the frame data as four 8-bit fields
|
||||
//
|
||||
union {
|
||||
uint32_t raw;
|
||||
struct {
|
||||
uint8_t address;
|
||||
uint8_t inverted_address;
|
||||
uint8_t data;
|
||||
uint8_t inverted_data;
|
||||
};
|
||||
} f;
|
||||
|
||||
f.raw = frame;
|
||||
|
||||
// a valid (non-extended) 'NEC' frame should contain 8 bit
|
||||
// address, inverted address, data and inverted data
|
||||
if (f.address != (f.inverted_address ^ 0xff) ||
|
||||
f.data != (f.inverted_data ^ 0xff)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// store the validated address and data
|
||||
*p_address = f.address;
|
||||
*p_data = f.data;
|
||||
|
||||
return true;
|
||||
}
|
||||
13
pio/ir_nec/nec_receive_library/nec_receive.h
Normal file
13
pio/ir_nec/nec_receive_library/nec_receive.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) 2021 mjcross
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/pio.h"
|
||||
|
||||
// public API
|
||||
|
||||
int nec_rx_init(PIO pio, uint pin);
|
||||
bool nec_decode_frame(uint32_t sm, uint8_t *p_address, uint8_t *p_data);
|
||||
96
pio/ir_nec/nec_receive_library/nec_receive.pio
Normal file
96
pio/ir_nec/nec_receive_library/nec_receive.pio
Normal file
@@ -0,0 +1,96 @@
|
||||
;
|
||||
; Copyright (c) 2021 mjcross
|
||||
;
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;
|
||||
|
||||
|
||||
.program nec_receive
|
||||
|
||||
; Decode IR frames in NEC format and push 32-bit words to the input FIFO.
|
||||
;
|
||||
; The input pin should be connected to an IR detector with an 'active low' output.
|
||||
;
|
||||
; This program expects there to be 10 state machine clock ticks per 'normal' 562.5us burst period
|
||||
; in order to permit timely detection of start of a burst. The initailisation function below sets
|
||||
; the correct divisor to achive this relative to the system clock.
|
||||
;
|
||||
; Within the 'NEC' protocol frames consists of 32 bits sent least-siginificant bit first; so the
|
||||
; Input Shift Register should be configured to shift right and autopush after 32 bits, as in the
|
||||
; initialisation function below.
|
||||
;
|
||||
.define BURST_LOOP_COUNTER 30 ; the detection threshold for a 'frame sync' burst
|
||||
.define BIT_SAMPLE_DELAY 15 ; how long to wait after the end of the burst before sampling
|
||||
|
||||
.wrap_target
|
||||
|
||||
next_burst:
|
||||
set X, BURST_LOOP_COUNTER
|
||||
wait 0 pin 0 ; wait for the next burst to start
|
||||
|
||||
burst_loop:
|
||||
jmp pin data_bit ; the burst ended before the counter expired
|
||||
jmp X-- burst_loop ; wait for the burst to end
|
||||
|
||||
; the counter expired - this is a sync burst
|
||||
mov ISR, NULL ; reset the Input Shift Register
|
||||
wait 1 pin 0 ; wait for the sync burst to finish
|
||||
jmp next_burst ; wait for the first data bit
|
||||
|
||||
data_bit:
|
||||
nop [ BIT_SAMPLE_DELAY - 1 ] ; wait for 1.5 burst periods before sampling the bit value
|
||||
in PINS, 1 ; if the next burst has started then detect a '0' (short gap)
|
||||
; otherwise detect a '1' (long gap)
|
||||
; after 32 bits the ISR will autopush to the receive FIFO
|
||||
.wrap
|
||||
|
||||
|
||||
% c-sdk {
|
||||
static inline void nec_receive_program_init (PIO pio, uint sm, uint offset, uint pin) {
|
||||
|
||||
// Set the GPIO function of the pin (connect the PIO to the pad)
|
||||
//
|
||||
pio_gpio_init(pio, pin);
|
||||
|
||||
// Set the pin direction to `input` at the PIO
|
||||
//
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
|
||||
|
||||
// Create a new state machine configuration
|
||||
//
|
||||
pio_sm_config c = nec_receive_program_get_default_config (offset);
|
||||
|
||||
// configure the Input Shift Register
|
||||
//
|
||||
sm_config_set_in_shift (&c,
|
||||
true, // shift right
|
||||
true, // enable autopush
|
||||
32); // autopush after 32 bits
|
||||
|
||||
// join the FIFOs to make a single large receive FIFO
|
||||
//
|
||||
sm_config_set_fifo_join (&c, PIO_FIFO_JOIN_RX);
|
||||
|
||||
// Map the IN pin group to one pin, namely the `pin`
|
||||
// parameter to this function.
|
||||
//
|
||||
sm_config_set_in_pins (&c, pin);
|
||||
|
||||
// Map the JMP pin to the `pin` parameter of this function.
|
||||
//
|
||||
sm_config_set_jmp_pin (&c, pin);
|
||||
|
||||
// Set the clock divider to 10 ticks per 562.5us burst period
|
||||
//
|
||||
float div = clock_get_hz (clk_sys) / (10.0 / 526.6e-6);
|
||||
sm_config_set_clkdiv (&c, div);
|
||||
|
||||
// Apply the configuration to the state machine
|
||||
//
|
||||
pio_sm_init (pio, sm, offset, &c);
|
||||
|
||||
// Set the state machine running
|
||||
//
|
||||
pio_sm_set_enabled (pio, sm, true);
|
||||
}
|
||||
%}
|
||||
Reference in New Issue
Block a user