Skip to content

Commit

Permalink
NeoPixel support added
Browse files Browse the repository at this point in the history
  • Loading branch information
MrYsLab committed Mar 13, 2021
1 parent 44a1f6e commit a9c0e9c
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 22 deletions.
18 changes: 17 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,24 @@ pico_sdk_init()
add_executable(Telemetrix4RpiPico
Telemetrix4RpiPico.c
)

pico_generate_pio_header(Telemetrix4RpiPico ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)
pico_enable_stdio_usb(Telemetrix4RpiPico 1)
pico_add_extra_outputs(Telemetrix4RpiPico)
target_link_libraries(Telemetrix4RpiPico pico_stdlib hardware_pwm
pico_unique_id hardware_watchdog hardware_adc hardware_i2c)
pico_unique_id hardware_watchdog hardware_adc hardware_i2c
hardware_pio)

add_executable(pio_Telemetrix4RpiPico)
# generate the header file into the source tree as it is included in the RP2040 datasheet
pico_generate_pio_header(pio_Telemetrix4RpiPico ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio OUTPUT_DIR ${CMAKE_CURRENT_LIST_DIR}/generated)

target_sources(pio_Telemetrix4RpiPico PRIVATE Telemetrix4RpiPico.c)
pico_add_extra_outputs(pio_Telemetrix4RpiPico)

add_custom_target(pio_Telemetrix4RpiPico_datasheet DEPENDS ${CMAKE_CURRENT_LIST_DIR}/generated/Telemetrix4RpiPico.py)
add_custom_command(OUTPUT ${CMAKE_CURRENT_LIST_DIR}/generated/Telemetrix4RpiPico.py
DEPENDS ws2812.pio
COMMAND Pioasm -o python ws2812.pio ./generated/Telemetrix4RpiPico
)
add_dependencies(pio_Telemetrix4RpiPico pio_Telemetrix4RpiPico_datasheet)
124 changes: 104 additions & 20 deletions Telemetrix4RpiPico.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,7 @@

#pragma clang diagnostic push
#pragma ide diagnostic ignored "EndlessLoop"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "pico/unique_id.h"
#include "hardware/watchdog.h"
#include "hardware/adc.h"
#include "hardware/i2c.h"

#include "include/Telemetrix4RpiPico.h"

/*******************************************************************
Expand All @@ -49,6 +41,30 @@ analog_pin_descriptor the_analog_pins[MAX_ANALOG_PINS_SUPPORTED];
// buffer to hold incoming command data
uint8_t command_buffer[MAX_COMMAND_LENGTH];

// neopixel support
PIO pio = pio0;
uint sm = 0;

// neopixel storage for up to 150 pixel string
// Each entry contains an RGG array.

uint8_t pixel_buffer[MAXIMUM_NUM_NEOPIXELS][3];

uint actual_number_of_pixels;

static inline void put_pixel(uint32_t pixel_grb) {
pio_sm_put_blocking(pio0, 0, pixel_grb << 8u);

}

static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
return
((uint32_t) (r) << 8) |
((uint32_t) (g) << 16) |
(uint32_t) (b);
}



/******************* REPORT BUFFERS *******************/
// NOTE First value in the array is the number of reporting
Expand All @@ -69,7 +85,7 @@ int i2c_report_message[64];

// get_pico_unique_id report buffer
int unique_id_report_report_message[] = {9, REPORT_PICO_UNIQUE_ID,
0, 0, 0, 0, 0, 0, 0, 0 };
0, 0, 0, 0, 0, 0, 0, 0};
// digital input report buffer
int digital_input_report_message[] = {3, DIGITAL_REPORT, 0, 0};

Expand Down Expand Up @@ -107,6 +123,11 @@ command_descriptor command_table[] =
{&enable_all_reports},
{&reset_data},
{&reset_board},
{&init_neo_pixels},
{&show_neo_pixels},
{&set_neo_pixel},
{&clear_all_neo_pixels},
{&fill_neo_pixels}
};

/***************************************************************************
Expand Down Expand Up @@ -204,7 +225,7 @@ void set_pin_mode() {
// save the differential value
the_analog_pins[pin].differential =
(int) ((command_buffer[SET_PIN_MODE_ANALOG_DIFF_HIGH] << 8) +
command_buffer[SET_PIN_MODE_ANALOG_DIFF_LOW]);
command_buffer[SET_PIN_MODE_ANALOG_DIFF_LOW]);
break;
default:
break;
Expand Down Expand Up @@ -276,7 +297,6 @@ void modify_reporting() {
* Retrieve the current firmware version
*/
void get_firmware_version() {
send_debug_info(1,sizeof(firmware_report_message) / sizeof(int));
serial_write(firmware_report_message,
sizeof(firmware_report_message) / sizeof(int));
}
Expand Down Expand Up @@ -355,7 +375,7 @@ void i2c_read() {
// 6... = bytes read

// length of i2c report packet
int num_of_bytes_to_send = I2C_READ_START_OF_DATA + command_buffer[I2C_READ_LENGTH] ;
int num_of_bytes_to_send = I2C_READ_START_OF_DATA + command_buffer[I2C_READ_LENGTH];

// We have a separate buffer ot store the data read from the device
// and combine that data back into the i2c report buffer.
Expand All @@ -381,7 +401,7 @@ void i2c_read() {
(uint8_t) command_buffer[I2C_DEVICE_ADDRESS],
(const uint8_t *) &command_buffer[I2C_READ_REGISTER], 1,
(bool) command_buffer[I2C_READ_NO_STOP_FLAG]);
if (i2c_sdk_call_return_value == PICO_ERROR_GENERIC){
if (i2c_sdk_call_return_value == PICO_ERROR_GENERIC) {
return;
}
}
Expand All @@ -408,7 +428,7 @@ void i2c_read() {
}
// length of the packet
i2c_report_message[I2C_PACKET_LENGTH] = (uint8_t) (i2c_sdk_call_return_value +
I2C_READ_DATA_BASE_BYTES);
I2C_READ_DATA_BASE_BYTES);

i2c_report_message[I2C_REPORT_ID] = I2C_READ_REPORT;

Expand Down Expand Up @@ -440,9 +460,9 @@ void i2c_write() {
}

int i2c_sdk_call_return_value = i2c_write_blocking(i2c, (uint8_t) command_buffer[I2C_DEVICE_ADDRESS],
&(command_buffer[I2C_WRITE_BYTES_TO_WRITE]),
command_buffer[I2C_WRITE_NUMBER_OF_BYTES],
(bool) command_buffer[I2C_WRITE_NO_STOP_FLAG]);
&(command_buffer[I2C_WRITE_BYTES_TO_WRITE]),
command_buffer[I2C_WRITE_NUMBER_OF_BYTES],
(bool) command_buffer[I2C_WRITE_NO_STOP_FLAG]);

if (i2c_sdk_call_return_value == PICO_ERROR_GENERIC) {
i2c_report_message[I2C_PACKET_LENGTH] = I2C_ERROR_REPORT_LENGTH; // length of the packet
Expand All @@ -455,6 +475,69 @@ void i2c_write() {
}
}

void init_neo_pixels() {
// initialize the pico support a NeoPixel string
uint offset = pio_add_program(pio, &Telemetrix4RpiPico_program);
ws2812_init(pio, sm, offset, command_buffer[NP_PIN_NUMBER], 800000,
false);

actual_number_of_pixels = command_buffer[NP_NUMBER_OF_PIXELS];

// set the pixels to the fill color
for (int i = 0; i < actual_number_of_pixels; i++) {
pixel_buffer[i][RED] = command_buffer[NP_RED_FILL];
pixel_buffer[i][GREEN] = command_buffer[NP_GREEN_FILL];
pixel_buffer[i][BLUE] = command_buffer[NP_BLUE_FILL];
}
show_neo_pixels();
sleep_ms(1);

}

void set_neo_pixel(){
// set a single neopixel in the pixel buffer
pixel_buffer[command_buffer[NP_PIXEL_NUMBER]][RED] = command_buffer[NP_SET_RED];
pixel_buffer[command_buffer[NP_PIXEL_NUMBER]][GREEN] = command_buffer[NP_SET_GREEN];
pixel_buffer[command_buffer[NP_PIXEL_NUMBER]][BLUE] = command_buffer[NP_SET_BLUE];
if(command_buffer[NP_SET_AUTO_SHOW]) {
show_neo_pixels();
}
}

void show_neo_pixels() {
// show the neopixels in the buffer
for(int i=0; i < actual_number_of_pixels; i++) {
put_pixel(urgb_u32(pixel_buffer[i][RED],
pixel_buffer[i][GREEN],
pixel_buffer[i][BLUE]));
}
}

void clear_all_neo_pixels(){
// set all the neopixels in the buffer to all zeroes
for(int i=0; i < actual_number_of_pixels; i++) {
pixel_buffer[i][RED] = 0;
pixel_buffer[i][GREEN] = 0;
pixel_buffer[i][BLUE] = 0;
}
if(command_buffer[NP_CLEAR_AUTO_SHOW]) {
show_neo_pixels();
}
}

void fill_neo_pixels(){
// fill all the neopixels in the buffer with the
// specified rgb values.
for(int i=0; i < actual_number_of_pixels; i++) {
pixel_buffer[i][RED] = command_buffer[NP_FILL_RED];
pixel_buffer[i][GREEN] = command_buffer[NP_FILL_GREEN];
pixel_buffer[i][BLUE] = command_buffer[NP_FILL_BLUE];
}
if(command_buffer[NP_FILL_AUTO_SHOW]) {
show_neo_pixels();
}
}

/******************* FOR FUTURE RELEASES **********************/
void servo_attach() {}

Expand Down Expand Up @@ -595,6 +678,9 @@ int main() {
stdio_init_all();
stdio_set_translate_crlf(&stdio_usb, false);
stdio_flush();
//uint offset = pio_add_program(pio, &Telemetrix4RpiPico_program);
//ws2812_init(pio, sm, offset, 28, 800000,
// false);

//stdio_set_translate_crlf(&stdio_usb, false);
adc_init();
Expand Down Expand Up @@ -635,6 +721,4 @@ int main() {
}




#pragma clang diagnostic pop
Binary file modified cmake-build-release/Telemetrix4RpiPico.uf2
Binary file not shown.
65 changes: 64 additions & 1 deletion include/Telemetrix4RpiPico.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@

#ifndef TELEMETRIX4RPIPICO_TELEMETRIX4RPIPICO_H
#define TELEMETRIX4RPIPICO_TELEMETRIX4RPIPICO_H

#pragma clang diagnostic push
#pragma ide diagnostic ignored "EndlessLoop"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "pico/unique_id.h"
#include "hardware/watchdog.h"
#include "hardware/adc.h"
#include "hardware/i2c.h"
#include "hardware/pio.h"
#include "hardware/clocks.h"
#include "ws2812.pio.h"
/************************** FORWARD REFERENCES ***********************
We define all functions here as extern to provide allow
forward referencing.
Expand Down Expand Up @@ -57,6 +72,16 @@ extern void scan_digital_inputs();

extern void scan_analog_inputs();

extern void init_neo_pixels();

extern void show_neo_pixels();

extern void set_neo_pixel();

extern void clear_all_neo_pixels();

extern void fill_neo_pixels();



/*********************************************************
Expand Down Expand Up @@ -85,6 +110,11 @@ extern void scan_analog_inputs();
#define ENABLE_ALL_REPORTS 16
#define RESET_DATA 17
#define RESET_BOARD 18
#define INITIALIZE_NEO_PIXELS 19
#define SHOW_NEO_PIXELS 20
#define SET_NEO_PIXEL 21
#define CLEAR_ALL_NEO_PIXELS 22
#define FILL_NEO_PIXELS 23

/*****************************************************
* MESSAGE OFFSETS
Expand Down Expand Up @@ -167,7 +197,40 @@ extern void scan_analog_inputs();
#define I2C_ERROR_REPORT_LENGTH 4
#define I2C_ERROR_REPORT_NUM_OF_BYTE_TO_SEND 5

// init neopixels
// command offsets
#define NP_PIN_NUMBER 1
#define NP_NUMBER_OF_PIXELS 2
#define NP_RED_FILL 3
#define NP_GREEN_FILL 4
#define NP_BLUE_FILL 5


// NeoPixel clock frequency
#define NP_FREQUENCY 800000

// Pixel buffer array offsets
#define RED 0
#define GREEN 1
#define BLUE 2

// set_neo_pixel command offsets
#define NP_PIXEL_NUMBER 1
#define NP_SET_RED 2
#define NP_SET_GREEN 3
#define NP_SET_BLUE 4
#define NP_SET_AUTO_SHOW 5

// fill_neo_pixels command offsets
#define NP_FILL_RED 1
#define NP_FILL_GREEN 2
#define NP_FILL_BLUE 3
#define NP_FILL_AUTO_SHOW 4

// clear_all_neo_pixels command offsets
#define NP_CLEAR_AUTO_SHOW 1

#define MAXIMUM_NUM_NEOPIXELS 150

/*********************** REPORTING BUFFER OFFSETS ******************/
// loopback buffer offset for data being looped back
Expand Down Expand Up @@ -229,7 +292,7 @@ extern void scan_analog_inputs();

/* Firmware Version Values */
#define FIRMWARE_MAJOR 0
#define FIRMWARE_MINOR 2
#define FIRMWARE_MINOR 3

// maximum length of a command packet in bytes
#define MAX_COMMAND_LENGTH 30
Expand Down

0 comments on commit a9c0e9c

Please sign in to comment.