Cleanup 3rd party samples; update README.md; add some missing copyright, fix builds for boards without certain pin definitions
This commit is contained in:
parent
1300621684
commit
fa09f2c88e
@ -118,6 +118,7 @@ App|Description
|
|||||||
[differential_manchester](pio/differential_manchester)| Send and receive differential Manchester-encoded serial (BMC).
|
[differential_manchester](pio/differential_manchester)| Send and receive differential Manchester-encoded serial (BMC).
|
||||||
[hub75](pio/hub75)| Display an image on a 128x64 HUB75 RGB LED matrix.
|
[hub75](pio/hub75)| Display an image on a 128x64 HUB75 RGB LED matrix.
|
||||||
[i2c](pio/i2c)| Scan an I2C bus.
|
[i2c](pio/i2c)| Scan an I2C bus.
|
||||||
|
[ir_nec](pio/ir_nec)| Sending and receiving IR (infra-red) codes using the PIO.
|
||||||
[logic_analyser](pio/logic_analyser)| Use PIO and DMA to capture a logic trace of some GPIOs, whilst a PWM unit is driving them.
|
[logic_analyser](pio/logic_analyser)| Use PIO and DMA to capture a logic trace of some GPIOs, whilst a PWM unit is driving them.
|
||||||
[manchester_encoding](pio/manchester_encoding)| Send and receive Manchester-encoded serial.
|
[manchester_encoding](pio/manchester_encoding)| Send and receive Manchester-encoded serial.
|
||||||
[pio_blink](pio/pio_blink)| Set up some PIO state machines to blink LEDs at different frequencies, according to delay counts pushed into their FIFOs.
|
[pio_blink](pio/pio_blink)| Set up some PIO state machines to blink LEDs at different frequencies, according to delay counts pushed into their FIFOs.
|
||||||
@ -125,6 +126,7 @@ App|Description
|
|||||||
[spi](pio/spi)| Use PIO to erase, program and read an external SPI flash chip. A second example runs a loopback test with all four CPHA/CPOL combinations.
|
[spi](pio/spi)| Use PIO to erase, program and read an external SPI flash chip. A second example runs a loopback test with all four CPHA/CPOL combinations.
|
||||||
[squarewave](pio/squarewave)| Drive a fast square wave onto a GPIO. This example accesses low-level PIO registers directly, instead of using the SDK functions.
|
[squarewave](pio/squarewave)| Drive a fast square wave onto a GPIO. This example accesses low-level PIO registers directly, instead of using the SDK functions.
|
||||||
[st7789_lcd](pio/st7789_lcd)| Set up PIO for 62.5 Mbps serial output, and use this to display a spinning image on a ST7789 serial LCD.
|
[st7789_lcd](pio/st7789_lcd)| Set up PIO for 62.5 Mbps serial output, and use this to display a spinning image on a ST7789 serial LCD.
|
||||||
|
[quadrature_encoder](pio/quadrature_encoder)| A quadrature encoder using PIO to maintain counts independent of the CPU.
|
||||||
[uart_rx](pio/uart_rx)| Implement the receive component of a UART serial port. Attach it to the spare Arm UART to see it receive characters.
|
[uart_rx](pio/uart_rx)| Implement the receive component of a UART serial port. Attach it to the spare Arm UART to see it receive characters.
|
||||||
[uart_tx](pio/uart_tx)| Implement the transmit component of a UART serial port, and print hello world.
|
[uart_tx](pio/uart_tx)| Implement the transmit component of a UART serial port, and print hello world.
|
||||||
[ws2812](pio/ws2812)| Examples of driving WS2812 addressable RGB LEDs.
|
[ws2812](pio/ws2812)| Examples of driving WS2812 addressable RGB LEDs.
|
||||||
|
|||||||
@ -209,14 +209,14 @@ void bmp280_get_calib_params(struct bmp280_calib_param* params) {
|
|||||||
int main() {
|
int main() {
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
|
|
||||||
// useful information for picotool
|
|
||||||
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
|
||||||
bi_decl(bi_program_description("BMP280 I2C example for the Raspberry Pi Pico"));
|
|
||||||
|
|
||||||
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
|
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
|
||||||
#warning i2c / bmp280_i2c example requires a board with I2C pins
|
#warning i2c / bmp280_i2c example requires a board with I2C pins
|
||||||
puts("Default I2C pins were not defined");
|
puts("Default I2C pins were not defined");
|
||||||
#else
|
#else
|
||||||
|
// useful information for picotool
|
||||||
|
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
||||||
|
bi_decl(bi_program_description("BMP280 I2C example for the Raspberry Pi Pico"));
|
||||||
|
|
||||||
printf("Hello, BMP280! Reading temperaure and pressure values from sensor...\n");
|
printf("Hello, BMP280! Reading temperaure and pressure values from sensor...\n");
|
||||||
|
|
||||||
// I2C is "open drain", pull ups to keep signal high when no data is being sent
|
// I2C is "open drain", pull ups to keep signal high when no data is being sent
|
||||||
|
|||||||
@ -66,7 +66,7 @@ float mcp9808_convert_temp(uint8_t upper_byte, uint8_t lower_byte) {
|
|||||||
return temperature;
|
return temperature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef i2c_default
|
||||||
void mcp9808_set_limits() {
|
void mcp9808_set_limits() {
|
||||||
|
|
||||||
//Set an upper limit of 30°C for the temperature
|
//Set an upper limit of 30°C for the temperature
|
||||||
@ -97,7 +97,7 @@ void mcp9808_set_limits() {
|
|||||||
buf[2] = crit_temp_lsb;;
|
buf[2] = crit_temp_lsb;;
|
||||||
i2c_write_blocking(i2c_default, ADDRESS, buf, 3, false);
|
i2c_write_blocking(i2c_default, ADDRESS, buf, 3, false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
@ -117,7 +117,6 @@ int main() {
|
|||||||
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
|
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
|
||||||
// Make the I2C pins available to picotool
|
// Make the I2C pins available to picotool
|
||||||
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
||||||
#endif
|
|
||||||
|
|
||||||
mcp9808_set_limits();
|
mcp9808_set_limits();
|
||||||
|
|
||||||
@ -144,4 +143,5 @@ int main() {
|
|||||||
|
|
||||||
sleep_ms(1000);
|
sleep_ms(1000);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,11 +56,13 @@ float mma8451_convert_accel(uint16_t raw_accel) {
|
|||||||
return acceleration;
|
return acceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef i2c_default
|
||||||
void mma8451_set_state(uint8_t state) {
|
void mma8451_set_state(uint8_t state) {
|
||||||
buf[0] = REG_CTRL_REG1;
|
buf[0] = REG_CTRL_REG1;
|
||||||
buf[1] = state; // Set RST bit to 1
|
buf[1] = state; // Set RST bit to 1
|
||||||
i2c_write_blocking(i2c_default, ADDRESS, buf, 2, false);
|
i2c_write_blocking(i2c_default, ADDRESS, buf, 2, false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
|
|||||||
@ -231,14 +231,14 @@ void render(uint8_t *buf, struct render_area *area) {
|
|||||||
int main() {
|
int main() {
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
|
|
||||||
// useful information for picotool
|
|
||||||
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
|
||||||
bi_decl(bi_program_description("OLED I2C example for the Raspberry Pi Pico"));
|
|
||||||
|
|
||||||
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
|
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
|
||||||
#warning i2c / oled_i2d example requires a board with I2C pins
|
#warning i2c / oled_i2d example requires a board with I2C pins
|
||||||
puts("Default I2C pins were not defined");
|
puts("Default I2C pins were not defined");
|
||||||
#else
|
#else
|
||||||
|
// useful information for picotool
|
||||||
|
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
||||||
|
bi_decl(bi_program_description("OLED I2C example for the Raspberry Pi Pico"));
|
||||||
|
|
||||||
printf("Hello, OLED display! Look at my raspberries..\n");
|
printf("Hello, OLED display! Look at my raspberries..\n");
|
||||||
|
|
||||||
// I2C is "open drain", pull ups to keep signal high when no data is being
|
// I2C is "open drain", pull ups to keep signal high when no data is being
|
||||||
|
|||||||
@ -20,11 +20,11 @@
|
|||||||
GND (physical pin 38) -> GND on PCF8520 board
|
GND (physical pin 38) -> GND on PCF8520 board
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef i2c_default
|
||||||
|
|
||||||
// By default these devices are on bus address 0x68
|
// By default these devices are on bus address 0x68
|
||||||
static int addr = 0x68;
|
static int addr = 0x68;
|
||||||
|
|
||||||
#ifdef i2c_default
|
|
||||||
|
|
||||||
static void pcf8520_reset() {
|
static void pcf8520_reset() {
|
||||||
// Two byte reset. First byte register, second byte data
|
// Two byte reset. First byte register, second byte data
|
||||||
// There are a load more options to set up the device in different ways that could be added here
|
// There are a load more options to set up the device in different ways that could be added here
|
||||||
@ -90,8 +90,6 @@ void pcf8520_set_alarm() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void pcf8520_check_alarm() {
|
void pcf8520_check_alarm() {
|
||||||
// Check bit 3 of control register 2 for alarm flags
|
// Check bit 3 of control register 2 for alarm flags
|
||||||
uint8_t status[1];
|
uint8_t status[1];
|
||||||
@ -106,6 +104,7 @@ void pcf8520_check_alarm() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pcf8520_convert_time(int conv_time[7], const uint8_t raw_time[7]) {
|
void pcf8520_convert_time(int conv_time[7], const uint8_t raw_time[7]) {
|
||||||
// Convert raw data into time
|
// Convert raw data into time
|
||||||
conv_time[0] = (10 * (int) ((raw_time[0] & 0x70) >> 4)) + ((int) (raw_time[0] & 0x0F));
|
conv_time[0] = (10 * (int) ((raw_time[0] & 0x70) >> 4)) + ((int) (raw_time[0] & 0x0F));
|
||||||
@ -116,6 +115,7 @@ void pcf8520_convert_time(int conv_time[7], const uint8_t raw_time[7]) {
|
|||||||
conv_time[5] = (10 * (int) ((raw_time[5] & 0x10) >> 4)) + ((int) (raw_time[5] & 0x0F));
|
conv_time[5] = (10 * (int) ((raw_time[5] & 0x10) >> 4)) + ((int) (raw_time[5] & 0x0F));
|
||||||
conv_time[6] = (10 * (int) ((raw_time[6] & 0xF0) >> 4)) + ((int) (raw_time[6] & 0x0F));
|
conv_time[6] = (10 * (int) ((raw_time[6] & 0xF0) >> 4)) + ((int) (raw_time[6] & 0x0F));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
@ -158,7 +158,7 @@ int main() {
|
|||||||
// Clear terminal
|
// Clear terminal
|
||||||
printf("\e[1;1H\e[2J");
|
printf("\e[1;1H\e[2J");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,3 +1,9 @@
|
|||||||
|
;
|
||||||
|
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||||
|
;
|
||||||
|
; SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
;
|
||||||
|
|
||||||
.program addition
|
.program addition
|
||||||
|
|
||||||
; Pop two 32 bit integers from the TX FIFO, add them together, and push the
|
; Pop two 32 bit integers from the TX FIFO, add them together, and push the
|
||||||
|
|||||||
@ -1,3 +1,9 @@
|
|||||||
|
;
|
||||||
|
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||||
|
;
|
||||||
|
; SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
;
|
||||||
|
|
||||||
.program hub75_row
|
.program hub75_row
|
||||||
|
|
||||||
; side-set pin 0 is LATCH
|
; side-set pin 0 is LATCH
|
||||||
|
|||||||
@ -25,43 +25,37 @@ int main() {
|
|||||||
uint rx_gpio = 15; // choose which GPIO pin is connected to the IR detector
|
uint rx_gpio = 15; // choose which GPIO pin is connected to the IR detector
|
||||||
|
|
||||||
// configure and enable the state machines
|
// configure and enable the state machines
|
||||||
//
|
int tx_sm = nec_tx_init(pio, tx_gpio); // uses two state machines, 16 instructions and one IRQ
|
||||||
int tx_sm = nec_tx_init (pio, tx_gpio); // uses two state machines, 16 instructions and one IRQ
|
int rx_sm = nec_rx_init(pio, rx_gpio); // uses one state machine and 9 instructions
|
||||||
int rx_sm = nec_rx_init (pio, rx_gpio); // uses one state machine and 9 instructions
|
|
||||||
|
|
||||||
if (tx_sm == -1 || rx_sm == -1) {
|
if (tx_sm == -1 || rx_sm == -1) {
|
||||||
printf ("could not configure PIO\n");
|
printf("could not configure PIO\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// transmit and receive frames
|
// transmit and receive frames
|
||||||
//
|
|
||||||
uint8_t tx_address = 0x00, tx_data = 0x00, rx_address, rx_data;
|
uint8_t tx_address = 0x00, tx_data = 0x00, rx_address, rx_data;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
// create a 32-bit frame and add it to the transmit FIFO
|
// create a 32-bit frame and add it to the transmit FIFO
|
||||||
//
|
uint32_t tx_frame = nec_encode_frame(tx_address, tx_data);
|
||||||
uint32_t tx_frame = nec_encode_frame (tx_address, tx_data);
|
pio_sm_put(pio, tx_sm, tx_frame);
|
||||||
pio_sm_put (pio, tx_sm, tx_frame);
|
printf("\nsent: %02x, %02x", tx_address, tx_data);
|
||||||
printf ("\nsent: %02x, %02x", tx_address, tx_data);
|
|
||||||
|
|
||||||
// allow time for the frame to be transmitted (optional)
|
// allow time for the frame to be transmitted (optional)
|
||||||
//
|
sleep_ms(100);
|
||||||
sleep_ms (100);
|
|
||||||
|
|
||||||
// display any frames in the receive FIFO
|
// display any frames in the receive FIFO
|
||||||
//
|
while (!pio_sm_is_rx_fifo_empty(pio, rx_sm)) {
|
||||||
while (!pio_sm_is_rx_fifo_empty (pio, rx_sm)) {
|
uint32_t rx_frame = pio_sm_get(pio, rx_sm);
|
||||||
uint32_t rx_frame = pio_sm_get (pio, rx_sm);
|
|
||||||
|
|
||||||
if (nec_decode_frame (rx_frame, &rx_address, &rx_data)) {
|
if (nec_decode_frame(rx_frame, &rx_address, &rx_data)) {
|
||||||
printf ("\treceived: %02x, %02x", rx_address, rx_data);
|
printf("\treceived: %02x, %02x", rx_address, rx_data);
|
||||||
} else {
|
} else {
|
||||||
printf ("\treceived: %08x", rx_frame);
|
printf("\treceived: %08x", rx_frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep_ms (900);
|
sleep_ms(900);
|
||||||
tx_data += 1;
|
tx_data += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,56 +4,40 @@
|
|||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// SDK types and declarations
|
// SDK types and declarations
|
||||||
//
|
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/pio.h"
|
#include "hardware/pio.h"
|
||||||
#include "hardware/clocks.h" // for clock_get_hz()
|
#include "hardware/clocks.h" // for clock_get_hz()
|
||||||
|
|
||||||
|
|
||||||
// declare the public API functions
|
|
||||||
//
|
|
||||||
#include "nec_receive.h"
|
#include "nec_receive.h"
|
||||||
|
|
||||||
|
|
||||||
// import the assembled PIO state machine program
|
// import the assembled PIO state machine program
|
||||||
//
|
|
||||||
#include "nec_receive.pio.h"
|
#include "nec_receive.pio.h"
|
||||||
|
|
||||||
|
|
||||||
// define the public API functions
|
|
||||||
//
|
|
||||||
|
|
||||||
// Claim an unused state machine on the specified PIO and configure it
|
// Claim an unused state machine on the specified PIO and configure it
|
||||||
// to receive NEC IR frames on the given GPIO pin.
|
// to receive NEC IR frames on the given GPIO pin.
|
||||||
//
|
//
|
||||||
// Returns: the state machine number on success, otherwise -1
|
// Returns: the state machine number on success, otherwise -1
|
||||||
//
|
|
||||||
int nec_rx_init(PIO pio, uint pin_num) {
|
int nec_rx_init(PIO pio, uint pin_num) {
|
||||||
|
|
||||||
// disable pull-up and pull-down on gpio pin
|
// disable pull-up and pull-down on gpio pin
|
||||||
//
|
gpio_disable_pulls(pin_num);
|
||||||
gpio_disable_pulls (pin_num);
|
|
||||||
|
|
||||||
// install the program in the PIO shared instruction space
|
// install the program in the PIO shared instruction space
|
||||||
//
|
|
||||||
uint offset;
|
uint offset;
|
||||||
if (pio_can_add_program (pio, &nec_receive_program)) {
|
if (pio_can_add_program(pio, &nec_receive_program)) {
|
||||||
offset = pio_add_program (pio, &nec_receive_program);
|
offset = pio_add_program(pio, &nec_receive_program);
|
||||||
} else {
|
} else {
|
||||||
return -1; // the program could not be added
|
return -1; // the program could not be added
|
||||||
}
|
}
|
||||||
|
|
||||||
// claim an unused state machine on this PIO
|
// claim an unused state machine on this PIO
|
||||||
//
|
int sm = pio_claim_unused_sm(pio, true);
|
||||||
int sm = pio_claim_unused_sm (pio, true);
|
|
||||||
if (sm == -1) {
|
if (sm == -1) {
|
||||||
return -1; // we were unable to claim a state machine
|
return -1; // we were unable to claim a state machine
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure and enable the state machine
|
// configure and enable the state machine
|
||||||
//
|
|
||||||
nec_receive_program_init(pio, sm, offset, pin_num);
|
nec_receive_program_init(pio, sm, offset, pin_num);
|
||||||
|
|
||||||
return sm;
|
return sm;
|
||||||
@ -64,8 +48,7 @@ int nec_rx_init(PIO pio, uint pin_num) {
|
|||||||
// provided.
|
// provided.
|
||||||
//
|
//
|
||||||
// Returns: `true` if the frame was valid, otherwise `false`
|
// Returns: `true` if the frame was valid, otherwise `false`
|
||||||
//
|
bool nec_decode_frame(uint32_t frame, uint8_t *p_address, uint8_t *p_data) {
|
||||||
bool nec_decode_frame (uint32_t frame, uint8_t *p_address, uint8_t *p_data) {
|
|
||||||
|
|
||||||
// access the frame data as four 8-bit fields
|
// access the frame data as four 8-bit fields
|
||||||
//
|
//
|
||||||
@ -83,14 +66,12 @@ bool nec_decode_frame (uint32_t frame, uint8_t *p_address, uint8_t *p_data) {
|
|||||||
|
|
||||||
// a valid (non-extended) 'NEC' frame should contain 8 bit
|
// a valid (non-extended) 'NEC' frame should contain 8 bit
|
||||||
// address, inverted address, data and inverted data
|
// address, inverted address, data and inverted data
|
||||||
//
|
|
||||||
if (f.address != (f.inverted_address ^ 0xff) ||
|
if (f.address != (f.inverted_address ^ 0xff) ||
|
||||||
f.data != (f.inverted_data ^ 0xff)) {
|
f.data != (f.inverted_data ^ 0xff)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the validated address and data
|
// store the validated address and data
|
||||||
//
|
|
||||||
*p_address = f.address;
|
*p_address = f.address;
|
||||||
*p_data = f.data;
|
*p_data = f.data;
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 mjcross
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/pio.h"
|
#include "hardware/pio.h"
|
||||||
|
|
||||||
// public API
|
// public API
|
||||||
//
|
|
||||||
int nec_rx_init (PIO pio, uint pin);
|
int nec_rx_init(PIO pio, uint pin);
|
||||||
bool nec_decode_frame (uint32_t sm, uint8_t *p_address, uint8_t *p_data);
|
bool nec_decode_frame(uint32_t sm, uint8_t *p_address, uint8_t *p_data);
|
||||||
|
|||||||
@ -10,48 +10,34 @@
|
|||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/pio.h"
|
#include "hardware/pio.h"
|
||||||
#include "hardware/clocks.h" // for clock_get_hz()
|
#include "hardware/clocks.h" // for clock_get_hz()
|
||||||
|
|
||||||
|
|
||||||
// declare the public API functions
|
|
||||||
//
|
|
||||||
#include "nec_transmit.h"
|
#include "nec_transmit.h"
|
||||||
|
|
||||||
|
|
||||||
// import the assembled PIO state machine programs
|
// import the assembled PIO state machine programs
|
||||||
//
|
|
||||||
#include "nec_carrier_burst.pio.h"
|
#include "nec_carrier_burst.pio.h"
|
||||||
#include "nec_carrier_control.pio.h"
|
#include "nec_carrier_control.pio.h"
|
||||||
|
|
||||||
|
|
||||||
// define the public API functions
|
|
||||||
//
|
|
||||||
|
|
||||||
// Claim an unused state machine on the specified PIO and configure it
|
// Claim an unused state machine on the specified PIO and configure it
|
||||||
// to transmit NEC IR frames on the specificied GPIO pin.
|
// to transmit NEC IR frames on the specificied GPIO pin.
|
||||||
//
|
//
|
||||||
// Returns: on success, the number of the carrier_control state machine
|
// Returns: on success, the number of the carrier_control state machine
|
||||||
// otherwise -1
|
// otherwise -1
|
||||||
//
|
|
||||||
int nec_tx_init(PIO pio, uint pin_num) {
|
int nec_tx_init(PIO pio, uint pin_num) {
|
||||||
|
|
||||||
// install the carrier_burst program in the PIO shared instruction space
|
// install the carrier_burst program in the PIO shared instruction space
|
||||||
//
|
|
||||||
uint carrier_burst_offset;
|
uint carrier_burst_offset;
|
||||||
if (pio_can_add_program (pio, &nec_carrier_burst_program)) {
|
if (pio_can_add_program(pio, &nec_carrier_burst_program)) {
|
||||||
carrier_burst_offset = pio_add_program(pio, &nec_carrier_burst_program);
|
carrier_burst_offset = pio_add_program(pio, &nec_carrier_burst_program);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// claim an unused state machine on this PIO
|
// claim an unused state machine on this PIO
|
||||||
//
|
|
||||||
int carrier_burst_sm = pio_claim_unused_sm(pio, true);
|
int carrier_burst_sm = pio_claim_unused_sm(pio, true);
|
||||||
if (carrier_burst_sm == -1) {
|
if (carrier_burst_sm == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure and enable the state machine
|
// configure and enable the state machine
|
||||||
//
|
|
||||||
nec_carrier_burst_program_init(pio,
|
nec_carrier_burst_program_init(pio,
|
||||||
carrier_burst_sm,
|
carrier_burst_sm,
|
||||||
carrier_burst_offset,
|
carrier_burst_offset,
|
||||||
@ -59,27 +45,24 @@ int nec_tx_init(PIO pio, uint pin_num) {
|
|||||||
38.222e3); // 38.222 kHz carrier
|
38.222e3); // 38.222 kHz carrier
|
||||||
|
|
||||||
// install the carrier_control program in the PIO shared instruction space
|
// install the carrier_control program in the PIO shared instruction space
|
||||||
//
|
|
||||||
uint carrier_control_offset;
|
uint carrier_control_offset;
|
||||||
if (pio_can_add_program (pio, &nec_carrier_control_program)) {
|
if (pio_can_add_program(pio, &nec_carrier_control_program)) {
|
||||||
carrier_control_offset = pio_add_program(pio, &nec_carrier_control_program);
|
carrier_control_offset = pio_add_program(pio, &nec_carrier_control_program);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// claim an unused state machine on this PIO
|
// claim an unused state machine on this PIO
|
||||||
//
|
|
||||||
int carrier_control_sm = pio_claim_unused_sm(pio, true);
|
int carrier_control_sm = pio_claim_unused_sm(pio, true);
|
||||||
if (carrier_control_sm == -1) {
|
if (carrier_control_sm == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure and enable the state machine
|
// configure and enable the state machine
|
||||||
//
|
|
||||||
nec_carrier_control_program_init(pio,
|
nec_carrier_control_program_init(pio,
|
||||||
carrier_control_sm,
|
carrier_control_sm,
|
||||||
carrier_control_offset,
|
carrier_control_offset,
|
||||||
2 * (1 / 562.5e-6), // 2 ticks per 562.5us carrier burst
|
2 * (1 / 562.5e-6f), // 2 ticks per 562.5us carrier burst
|
||||||
32); // 32 bits per frame
|
32); // 32 bits per frame
|
||||||
|
|
||||||
return carrier_control_sm;
|
return carrier_control_sm;
|
||||||
@ -89,9 +72,7 @@ int nec_tx_init(PIO pio, uint pin_num) {
|
|||||||
// Create a frame in `NEC` format from the provided 8-bit address and data
|
// Create a frame in `NEC` format from the provided 8-bit address and data
|
||||||
//
|
//
|
||||||
// Returns: a 32-bit encoded frame
|
// Returns: a 32-bit encoded frame
|
||||||
//
|
uint32_t nec_encode_frame(uint8_t address, uint8_t data) {
|
||||||
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,
|
// a normal 32-bit frame is encoded as address, inverted address, data, inverse data,
|
||||||
//
|
|
||||||
return address | (address ^ 0xff) << 8 | data << 16 | (data ^ 0xff) << 24;
|
return address | (address ^ 0xff) << 8 | data << 16 | (data ^ 0xff) << 24;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 mjcross
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/pio.h"
|
#include "hardware/pio.h"
|
||||||
|
|
||||||
// public API
|
// public API
|
||||||
//
|
|
||||||
int nec_tx_init(PIO pio, uint pin);
|
int nec_tx_init(PIO pio, uint pin);
|
||||||
uint32_t nec_encode_frame (uint8_t address, uint8_t data);
|
uint32_t nec_encode_frame(uint8_t address, uint8_t data);
|
||||||
|
|||||||
@ -1,3 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 pmarques-dev @ github
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/pio.h"
|
#include "hardware/pio.h"
|
||||||
@ -13,7 +19,7 @@
|
|||||||
// updated. At any point, the main code can query the current count by using
|
// updated. At any point, the main code can query the current count by using
|
||||||
// the quadrature_encoder_*_count functions. The counter is kept in a full
|
// the quadrature_encoder_*_count functions. The counter is kept in a full
|
||||||
// 32 bit register that just wraps around. Two's complement arithmetic means
|
// 32 bit register that just wraps around. Two's complement arithmetic means
|
||||||
// that it can be interpreted as a 32 bit signed or unsigned value and it will
|
// that it can be interpreted as a 32-bit signed or unsigned value, and it will
|
||||||
// work anyway.
|
// work anyway.
|
||||||
//
|
//
|
||||||
// As an example, a two wheel robot being controlled at 100Hz, can use two
|
// As an example, a two wheel robot being controlled at 100Hz, can use two
|
||||||
@ -26,34 +32,30 @@
|
|||||||
// encoder count updated and because of that it supports very high step rates.
|
// encoder count updated and because of that it supports very high step rates.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int new_value, delta, old_value = 0;
|
||||||
|
|
||||||
int main()
|
// Base pin to connect the A phase of the encoder.
|
||||||
{
|
// The B phase must be connected to the next pin
|
||||||
int new_value, delta, old_value = 0;
|
const uint PIN_AB = 10;
|
||||||
|
|
||||||
// Base pin to connect the A phase of the encoder.
|
stdio_init_all();
|
||||||
// The B phase must be connected to the next pin
|
|
||||||
const uint PIN_AB = 10;
|
|
||||||
|
|
||||||
stdio_init_all();
|
PIO pio = pio0;
|
||||||
|
const uint sm = 0;
|
||||||
|
|
||||||
PIO pio = pio0;
|
uint offset = pio_add_program(pio, &quadrature_encoder_program);
|
||||||
const uint sm = 0;
|
quadrature_encoder_program_init(pio, sm, offset, PIN_AB, 0);
|
||||||
|
|
||||||
uint offset = pio_add_program(pio, &quadrature_encoder_program);
|
while (1) {
|
||||||
quadrature_encoder_program_init(pio, sm, offset, PIN_AB, 0);
|
// note: thanks to two's complement arithmetic delta will always
|
||||||
|
// be correct even when new_value wraps around MAXINT / MININT
|
||||||
|
new_value = quadrature_encoder_get_count(pio, sm);
|
||||||
|
delta = new_value - old_value;
|
||||||
|
old_value = new_value;
|
||||||
|
|
||||||
while (1) {
|
printf("position %8d, delta %6d\n", new_value, delta);
|
||||||
// note: thanks to two's complement arithmetic delta will always
|
sleep_ms(100);
|
||||||
// be correct even when new_value wraps around MAXINT / MININT
|
}
|
||||||
new_value = quadrature_encoder_get_count(pio, sm);
|
|
||||||
delta = new_value - old_value;
|
|
||||||
old_value = new_value;
|
|
||||||
|
|
||||||
printf("position %8d, delta %6d\n", new_value, delta);
|
|
||||||
sleep_ms(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
|
;
|
||||||
|
; Copyright (c) 2021 pmarques-dev @ github
|
||||||
|
;
|
||||||
|
; SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
;
|
||||||
|
|
||||||
.program quadrature_encoder
|
.program quadrature_encoder
|
||||||
|
|
||||||
@ -6,7 +11,7 @@
|
|||||||
.origin 0
|
.origin 0
|
||||||
|
|
||||||
|
|
||||||
; the code works by running a loop that contiously shifts the 2 phase pins into
|
; the code works by running a loop that continuously shifts the 2 phase pins into
|
||||||
; ISR and looks at the lower 4 bits to do a computed jump to an instruction that
|
; ISR and looks at the lower 4 bits to do a computed jump to an instruction that
|
||||||
; does the proper "do nothing" | "increment" | "decrement" action for that pin
|
; does the proper "do nothing" | "increment" | "decrement" action for that pin
|
||||||
; state change (or no change)
|
; state change (or no change)
|
||||||
|
|||||||
@ -14,9 +14,12 @@
|
|||||||
|
|
||||||
#define IS_RGBW true
|
#define IS_RGBW true
|
||||||
#define NUM_PIXELS 150
|
#define NUM_PIXELS 150
|
||||||
#ifndef PICO_DEFAULT_WS2812_PIN
|
|
||||||
#warning "no WS2812 default PIN defined for board, please check if pin 2 is okay"
|
#ifdef PICO_DEFAULT_WS2812_PIN
|
||||||
#define PICO_DEFAULT_WS2812_PIN 2
|
#define WS2812_PIN PICO_DEFAULT_WS2812_PIN
|
||||||
|
#else
|
||||||
|
// default to pin 2 if the board doesn't have a default WS2812 pin defined
|
||||||
|
#define WS2812_PIN 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void put_pixel(uint32_t pixel_grb) {
|
static inline void put_pixel(uint32_t pixel_grb) {
|
||||||
@ -81,14 +84,14 @@ const struct {
|
|||||||
int main() {
|
int main() {
|
||||||
//set_sys_clock_48();
|
//set_sys_clock_48();
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
puts("WS2812 Smoke Test");
|
printf("WS2812 Smoke Test, using pin %d", WS2812_PIN);
|
||||||
|
|
||||||
// todo get free sm
|
// todo get free sm
|
||||||
PIO pio = pio0;
|
PIO pio = pio0;
|
||||||
int sm = 0;
|
int sm = 0;
|
||||||
uint offset = pio_add_program(pio, &ws2812_program);
|
uint offset = pio_add_program(pio, &ws2812_program);
|
||||||
|
|
||||||
ws2812_program_init(pio, sm, offset, PICO_DEFAULT_WS2812_PIN, 800000, IS_RGBW);
|
ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, IS_RGBW);
|
||||||
|
|
||||||
int t = 0;
|
int t = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|||||||
Reference in New Issue
Block a user