Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,15 @@ App|Description
[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.
[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.
[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.
[pwm](pio/pwm)| Pulse width modulation on PIO. Use it to gradually fade the brightness of an LED.
[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.
[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_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.
Expand Down
8 changes: 4 additions & 4 deletions i2c/bmp280_i2c/bmp280_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,14 @@ void bmp280_get_calib_params(struct bmp280_calib_param* params) {
int main() {
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)
#warning i2c / bmp280_i2c example requires a board with I2C pins
puts("Default I2C pins were not defined");
#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");

// I2C is "open drain", pull ups to keep signal high when no data is being sent
Expand Down
6 changes: 3 additions & 3 deletions i2c/mcp9808_i2c/mcp9808_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ float mcp9808_convert_temp(uint8_t upper_byte, uint8_t lower_byte) {
return temperature;
}


#ifdef i2c_default
void mcp9808_set_limits() {

//Set an upper limit of 30°C for the temperature
Expand Down Expand Up @@ -97,7 +97,7 @@ void mcp9808_set_limits() {
buf[2] = crit_temp_lsb;;
i2c_write_blocking(i2c_default, ADDRESS, buf, 3, false);
}

#endif

int main() {

Expand All @@ -117,7 +117,6 @@ int main() {
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
// 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));
#endif

mcp9808_set_limits();

Expand All @@ -144,4 +143,5 @@ int main() {

sleep_ms(1000);
}
#endif
}
2 changes: 2 additions & 0 deletions i2c/mma8451_i2c/mma8451_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,13 @@ float mma8451_convert_accel(uint16_t raw_accel) {
return acceleration;
}

#ifdef i2c_default
void mma8451_set_state(uint8_t state) {
buf[0] = REG_CTRL_REG1;
buf[1] = state; // Set RST bit to 1
i2c_write_blocking(i2c_default, ADDRESS, buf, 2, false);
}
#endif

int main() {
stdio_init_all();
Expand Down
8 changes: 4 additions & 4 deletions i2c/oled_i2c/oled_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,14 +231,14 @@ void render(uint8_t *buf, struct render_area *area) {
int main() {
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)
#warning i2c / oled_i2d example requires a board with I2C pins
puts("Default I2C pins were not defined");
#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");

// I2C is "open drain", pull ups to keep signal high when no data is being
Expand Down
10 changes: 5 additions & 5 deletions i2c/pcf8523_i2c/pcf8523_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
GND (physical pin 38) -> GND on PCF8520 board
*/

#ifdef i2c_default

// By default these devices are on bus address 0x68
static int addr = 0x68;

#ifdef i2c_default

static void pcf8520_reset() {
// 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
Expand Down Expand Up @@ -90,8 +90,6 @@ void pcf8520_set_alarm() {
}
}

#endif

void pcf8520_check_alarm() {
// Check bit 3 of control register 2 for alarm flags
uint8_t status[1];
Expand All @@ -106,6 +104,7 @@ void pcf8520_check_alarm() {
}
}


void pcf8520_convert_time(int conv_time[7], const uint8_t raw_time[7]) {
// Convert raw data into time
conv_time[0] = (10 * (int) ((raw_time[0] & 0x70) >> 4)) + ((int) (raw_time[0] & 0x0F));
Expand All @@ -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[6] = (10 * (int) ((raw_time[6] & 0xF0) >> 4)) + ((int) (raw_time[6] & 0x0F));
}
#endif

int main() {
stdio_init_all();
Expand Down Expand Up @@ -158,7 +158,7 @@ int main() {
// Clear terminal
printf("\e[1;1H\e[2J");
}
#endif
return 0;
}

#endif
6 changes: 6 additions & 0 deletions pio/addition/addition.pio
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;

.program addition

; Pop two 32 bit integers from the TX FIFO, add them together, and push the
Expand Down
6 changes: 6 additions & 0 deletions pio/hub75/hub75.pio
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;

.program hub75_row

; side-set pin 0 is LATCH
Expand Down
32 changes: 13 additions & 19 deletions pio/ir_nec/ir_loopback/ir_loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,37 @@ int main() {
uint rx_gpio = 15; // choose which GPIO pin is connected to the IR detector

// 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 rx_sm = nec_rx_init (pio, rx_gpio); // uses one state machine and 9 instructions
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

if (tx_sm == -1 || rx_sm == -1) {
printf ("could not configure PIO\n");
printf("could not configure PIO\n");
return -1;
}

// transmit and receive frames
//
uint8_t tx_address = 0x00, tx_data = 0x00, rx_address, rx_data;
while (true) {

// create a 32-bit frame and add it to the transmit FIFO
//
uint32_t tx_frame = nec_encode_frame (tx_address, tx_data);
pio_sm_put (pio, tx_sm, tx_frame);
printf ("\nsent: %02x, %02x", tx_address, tx_data);
uint32_t tx_frame = nec_encode_frame(tx_address, tx_data);
pio_sm_put(pio, tx_sm, tx_frame);
printf("\nsent: %02x, %02x", tx_address, tx_data);

// allow time for the frame to be transmitted (optional)
//
sleep_ms (100);
sleep_ms(100);

// display any frames in the receive FIFO
//
while (!pio_sm_is_rx_fifo_empty (pio, rx_sm)) {
uint32_t rx_frame = pio_sm_get (pio, rx_sm);
while (!pio_sm_is_rx_fifo_empty(pio, rx_sm)) {
uint32_t rx_frame = pio_sm_get(pio, rx_sm);

if (nec_decode_frame (rx_frame, &rx_address, &rx_data)) {
printf ("\treceived: %02x, %02x", rx_address, rx_data);
if (nec_decode_frame(rx_frame, &rx_address, &rx_data)) {
printf("\treceived: %02x, %02x", rx_address, rx_data);
} else {
printf ("\treceived: %08x", rx_frame);
printf("\treceived: %08x", rx_frame);
}
}

sleep_ms (900);
sleep_ms(900);
tx_data += 1;
}
}
29 changes: 5 additions & 24 deletions pio/ir_nec/nec_receive_library/nec_receive.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,40 @@
* 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()


// declare the public API functions
//
#include "nec_receive.h"


// import the assembled PIO state machine program
//
#include "nec_receive.pio.h"


// define the public API functions
//

// 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);
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);
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);
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;
Expand All @@ -64,8 +48,7 @@ int nec_rx_init(PIO pio, uint pin_num) {
// 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) {
bool nec_decode_frame(uint32_t frame, uint8_t *p_address, uint8_t *p_data) {

// access the frame data as four 8-bit fields
//
Expand All @@ -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
// 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;

Expand Down
12 changes: 9 additions & 3 deletions pio/ir_nec/nec_receive_library/nec_receive.h
Original file line number Diff line number Diff line change
@@ -1,7 +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);

int nec_rx_init(PIO pio, uint pin);
bool nec_decode_frame(uint32_t sm, uint8_t *p_address, uint8_t *p_data);
Loading