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:
20
pio/ir_nec/nec_transmit_library/CMakeLists.txt
Normal file
20
pio/ir_nec/nec_transmit_library/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
# build a normal library
|
||||
#
|
||||
add_library(nec_transmit_library nec_transmit.c)
|
||||
|
||||
# invoke pio_asm to assemble the PIO state machine programs
|
||||
#
|
||||
pico_generate_pio_header(nec_transmit_library ${CMAKE_CURRENT_LIST_DIR}/nec_carrier_burst.pio)
|
||||
pico_generate_pio_header(nec_transmit_library ${CMAKE_CURRENT_LIST_DIR}/nec_carrier_control.pio)
|
||||
|
||||
target_link_libraries(nec_transmit_library PRIVATE
|
||||
pico_stdlib
|
||||
hardware_pio
|
||||
)
|
||||
|
||||
# add the `binary` directory so that the generated headers are included in the project
|
||||
#
|
||||
target_include_directories (nec_transmit_library PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
61
pio/ir_nec/nec_transmit_library/nec_carrier_burst.pio
Normal file
61
pio/ir_nec/nec_transmit_library/nec_carrier_burst.pio
Normal file
@@ -0,0 +1,61 @@
|
||||
;
|
||||
; Copyright (c) 2021 mjcross
|
||||
;
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;
|
||||
|
||||
|
||||
.program nec_carrier_burst
|
||||
|
||||
; Generate bursts of carrier.
|
||||
;
|
||||
; Repeatedly wait for an IRQ to be set then clear it and generate 21 cycles of
|
||||
; carrier with 25% duty cycle
|
||||
;
|
||||
.define NUM_CYCLES 21 ; how many carrier cycles to generate
|
||||
.define BURST_IRQ 7 ; which IRQ should trigger a carrier burst
|
||||
.define public TICKS_PER_LOOP 4 ; the number of instructions in the loop (for timing)
|
||||
|
||||
.wrap_target
|
||||
set X, (NUM_CYCLES - 1) ; initialise the loop counter
|
||||
wait 1 irq BURST_IRQ ; wait for the IRQ then clear it
|
||||
cycle_loop:
|
||||
set pins, 1 ; set the pin high (1 cycle)
|
||||
set pins, 0 [1] ; set the pin low (2 cycles)
|
||||
jmp X--, cycle_loop ; (1 more cycle)
|
||||
.wrap
|
||||
|
||||
|
||||
% c-sdk {
|
||||
static inline void nec_carrier_burst_program_init(PIO pio, uint sm, uint offset, uint pin, float freq) {
|
||||
// Create a new state machine configuration
|
||||
//
|
||||
pio_sm_config c = nec_carrier_burst_program_get_default_config (offset);
|
||||
|
||||
// Map the SET pin group to one pin, namely the `pin`
|
||||
// parameter to this function.
|
||||
//
|
||||
sm_config_set_set_pins (&c, pin, 1);
|
||||
|
||||
// Set the GPIO function of the pin (connect the PIO to the pad)
|
||||
//
|
||||
pio_gpio_init (pio, pin);
|
||||
|
||||
// Set the pin direction to output at the PIO
|
||||
//
|
||||
pio_sm_set_consecutive_pindirs (pio, sm, pin, 1, true);
|
||||
|
||||
// Set the clock divider to generate the required frequency
|
||||
//
|
||||
float div = clock_get_hz (clk_sys) / (freq * nec_carrier_burst_TICKS_PER_LOOP);
|
||||
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);
|
||||
}
|
||||
%}
|
||||
79
pio/ir_nec/nec_transmit_library/nec_carrier_control.pio
Normal file
79
pio/ir_nec/nec_transmit_library/nec_carrier_control.pio
Normal file
@@ -0,0 +1,79 @@
|
||||
;
|
||||
; Copyright (c) 2021 mjcross
|
||||
;
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;
|
||||
|
||||
|
||||
.program nec_carrier_control
|
||||
|
||||
; Transmit an encoded 32-bit frame in NEC IR format.
|
||||
;
|
||||
; Accepts 32-bit words from the transmit FIFO and sends them least-significant bit first
|
||||
; using pulse position modulation.
|
||||
;
|
||||
; Carrier bursts are generated using the nec_carrier_burst program, which is expected to be
|
||||
; running on a separate state machine.
|
||||
;
|
||||
; This program expects there to be 2 state machine ticks per 'normal' 562.5us
|
||||
; burst period.
|
||||
;
|
||||
.define BURST_IRQ 7 ; the IRQ used to trigger a carrier burst
|
||||
.define NUM_INITIAL_BURSTS 16 ; how many bursts to transmit for a 'sync burst'
|
||||
|
||||
.wrap_target
|
||||
pull ; fetch a data word from the transmit FIFO into the
|
||||
; output shift register, blocking if the FIFO is empty
|
||||
|
||||
set X, (NUM_INITIAL_BURSTS - 1) ; send a sync burst (9ms)
|
||||
long_burst:
|
||||
irq BURST_IRQ
|
||||
jmp X-- long_burst
|
||||
|
||||
nop [15] ; send a 4.5ms space
|
||||
irq BURST_IRQ [1] ; send a 562.5us burst to begin the first data bit
|
||||
|
||||
data_bit:
|
||||
out X, 1 ; shift the least-significant bit from the OSR
|
||||
jmp !X burst ; send a short delay for a '0' bit
|
||||
nop [3] ; send an additional delay for a '1' bit
|
||||
burst:
|
||||
irq BURST_IRQ ; send a 562.5us burst to end the data bit
|
||||
|
||||
jmp !OSRE data_bit ; continue sending bits until the OSR is empty
|
||||
|
||||
.wrap ; fetch another data word from the FIFO
|
||||
|
||||
|
||||
% c-sdk {
|
||||
static inline void nec_carrier_control_program_init (PIO pio, uint sm, uint offset, float tick_rate, int bits_per_frame) {
|
||||
|
||||
// create a new state machine configuration
|
||||
//
|
||||
pio_sm_config c = nec_carrier_control_program_get_default_config(offset);
|
||||
|
||||
// configure the output shift register
|
||||
//
|
||||
sm_config_set_out_shift (&c,
|
||||
true, // shift right
|
||||
false, // disable autopull
|
||||
bits_per_frame);
|
||||
|
||||
// join the FIFOs to make a single large transmit FIFO
|
||||
//
|
||||
sm_config_set_fifo_join (&c, PIO_FIFO_JOIN_TX);
|
||||
|
||||
// configure the clock divider
|
||||
//
|
||||
float div = clock_get_hz (clk_sys) / tick_rate;
|
||||
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);
|
||||
}
|
||||
%}
|
||||
78
pio/ir_nec/nec_transmit_library/nec_transmit.c
Normal file
78
pio/ir_nec/nec_transmit_library/nec_transmit.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 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_transmit.h"
|
||||
|
||||
// import the assembled PIO state machine programs
|
||||
#include "nec_carrier_burst.pio.h"
|
||||
#include "nec_carrier_control.pio.h"
|
||||
|
||||
// Claim an unused state machine on the specified PIO and configure it
|
||||
// to transmit NEC IR frames on the specificied GPIO pin.
|
||||
//
|
||||
// Returns: on success, the number of the carrier_control state machine
|
||||
// otherwise -1
|
||||
int nec_tx_init(PIO pio, uint pin_num) {
|
||||
|
||||
// install the carrier_burst program in the PIO shared instruction space
|
||||
uint carrier_burst_offset;
|
||||
if (pio_can_add_program(pio, &nec_carrier_burst_program)) {
|
||||
carrier_burst_offset = pio_add_program(pio, &nec_carrier_burst_program);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// claim an unused state machine on this PIO
|
||||
int carrier_burst_sm = pio_claim_unused_sm(pio, true);
|
||||
if (carrier_burst_sm == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// configure and enable the state machine
|
||||
nec_carrier_burst_program_init(pio,
|
||||
carrier_burst_sm,
|
||||
carrier_burst_offset,
|
||||
pin_num,
|
||||
38.222e3); // 38.222 kHz carrier
|
||||
|
||||
// install the carrier_control program in the PIO shared instruction space
|
||||
uint carrier_control_offset;
|
||||
if (pio_can_add_program(pio, &nec_carrier_control_program)) {
|
||||
carrier_control_offset = pio_add_program(pio, &nec_carrier_control_program);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// claim an unused state machine on this PIO
|
||||
int carrier_control_sm = pio_claim_unused_sm(pio, true);
|
||||
if (carrier_control_sm == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// configure and enable the state machine
|
||||
nec_carrier_control_program_init(pio,
|
||||
carrier_control_sm,
|
||||
carrier_control_offset,
|
||||
2 * (1 / 562.5e-6f), // 2 ticks per 562.5us carrier burst
|
||||
32); // 32 bits per frame
|
||||
|
||||
return carrier_control_sm;
|
||||
}
|
||||
|
||||
|
||||
// Create a frame in `NEC` format from the provided 8-bit address and data
|
||||
//
|
||||
// Returns: a 32-bit encoded frame
|
||||
uint32_t nec_encode_frame(uint8_t address, uint8_t data) {
|
||||
// a normal 32-bit frame is encoded as address, inverted address, data, inverse data,
|
||||
return address | (address ^ 0xff) << 8 | data << 16 | (data ^ 0xff) << 24;
|
||||
}
|
||||
13
pio/ir_nec/nec_transmit_library/nec_transmit.h
Normal file
13
pio/ir_nec/nec_transmit_library/nec_transmit.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_tx_init(PIO pio, uint pin);
|
||||
uint32_t nec_encode_frame(uint8_t address, uint8_t data);
|
||||
Reference in New Issue
Block a user