generated from LailaTheElf/rp2040_c
v1.0.0
This commit is contained in:
parent
ef76d8e35f
commit
9959e0bd01
@ -16,14 +16,17 @@ set(PICO_CXX_ENABLE_RTTI 1)
|
||||
pico_sdk_init()
|
||||
|
||||
add_executable(stofzuiger src/main.c)
|
||||
pico_generate_pio_header(stofzuiger ${CMAKE_CURRENT_LIST_DIR}/src/ws2812.pio OUTPUT_DIR ${CMAKE_CURRENT_LIST_DIR}/src/generated)
|
||||
|
||||
target_link_libraries(stofzuiger
|
||||
pico_stdlib
|
||||
hardware_sleep
|
||||
hardware_pio
|
||||
hardware_pwm
|
||||
)
|
||||
|
||||
pico_enable_stdio_uart(stofzuiger 0)
|
||||
pico_enable_stdio_usb(stofzuiger 1)
|
||||
pico_enable_stdio_usb(stofzuiger 0)
|
||||
|
||||
# create map/bin/hex/uf2 file in addition to ELF.
|
||||
pico_add_extra_outputs(stofzuiger)
|
||||
|
||||
66
src/generated/ws2812.pio.h
Normal file
66
src/generated/ws2812.pio.h
Normal file
@ -0,0 +1,66 @@
|
||||
// -------------------------------------------------- //
|
||||
// This file is autogenerated by pioasm; do not edit! //
|
||||
// -------------------------------------------------- //
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
#include "hardware/pio.h"
|
||||
#endif
|
||||
|
||||
// ------ //
|
||||
// ws2812 //
|
||||
// ------ //
|
||||
|
||||
#define ws2812_wrap_target 0
|
||||
#define ws2812_wrap 3
|
||||
#define ws2812_pio_version 0
|
||||
|
||||
#define ws2812_T1 3
|
||||
#define ws2812_T2 3
|
||||
#define ws2812_T3 4
|
||||
|
||||
static const uint16_t ws2812_program_instructions[] = {
|
||||
// .wrap_target
|
||||
0x6321, // 0: out x, 1 side 0 [3]
|
||||
0x1223, // 1: jmp !x, 3 side 1 [2]
|
||||
0x1200, // 2: jmp 0 side 1 [2]
|
||||
0xa242, // 3: nop side 0 [2]
|
||||
// .wrap
|
||||
};
|
||||
|
||||
#if !PICO_NO_HARDWARE
|
||||
static const struct pio_program ws2812_program = {
|
||||
.instructions = ws2812_program_instructions,
|
||||
.length = 4,
|
||||
.origin = -1,
|
||||
.pio_version = ws2812_pio_version,
|
||||
#if PICO_PIO_VERSION > 0
|
||||
.used_gpio_ranges = 0x0
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline pio_sm_config ws2812_program_get_default_config(uint offset) {
|
||||
pio_sm_config c = pio_get_default_sm_config();
|
||||
sm_config_set_wrap(&c, offset + ws2812_wrap_target, offset + ws2812_wrap);
|
||||
sm_config_set_sideset(&c, 1, false, false);
|
||||
return c;
|
||||
}
|
||||
|
||||
#include "hardware/clocks.h"
|
||||
static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) {
|
||||
pio_gpio_init(pio, pin);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
|
||||
pio_sm_config c = ws2812_program_get_default_config(offset);
|
||||
sm_config_set_sideset_pins(&c, pin);
|
||||
sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
|
||||
int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3;
|
||||
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
|
||||
sm_config_set_clkdiv(&c, div);
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
120
src/main.c
120
src/main.c
@ -1,25 +1,28 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <pico/stdlib.h>
|
||||
#include <hardware/pio.h>
|
||||
#include <hardware/clocks.h>
|
||||
#include <hardware/pwm.h>
|
||||
#include <pico/sleep.h>
|
||||
|
||||
#include "generated/ws2812.pio.h"
|
||||
|
||||
#define IS_RGBW false
|
||||
#define NUM_PIXELS 1
|
||||
#define WS2812_PIN 16
|
||||
|
||||
#define PIN_LED_MODE_RED 0
|
||||
#define PIN_LED_MODE_GREEN 1
|
||||
#define PIN_LED_BATT1 2
|
||||
#define PIN_LED_BATT2 3
|
||||
#define PIN_LED_BATT3 4
|
||||
#define PIN_BTN 5
|
||||
#define PIN_MOTOR_IO1 6
|
||||
#define PIN_MOTOR_IO2 7
|
||||
#define PIN_LED_MODE_GREEN 3
|
||||
#define PIN_LED_MODE_RED 4
|
||||
#define PIN_LED_BATT1 5
|
||||
#define PIN_LED_BATT2 6
|
||||
#define PIN_LED_BATT3 7
|
||||
#define PIN_BTN 2
|
||||
#define PIN_MOTOR_PWM 8
|
||||
#define PIN_MOTOR_IO1 9
|
||||
#define PIN_MOTOR_IO2 10
|
||||
|
||||
typedef enum {
|
||||
STATE_OFF,
|
||||
@ -27,33 +30,22 @@ typedef enum {
|
||||
STATE_LOW
|
||||
} mainState_t;
|
||||
mainState_t mainState;
|
||||
bool btn_pressed = false;
|
||||
|
||||
void update_state(mainState_t state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case STATE_OFF:
|
||||
gpio_put(PIN_MOTOR_IO1, 0);
|
||||
gpio_put(PIN_MOTOR_IO2, 0);
|
||||
break;
|
||||
case STATE_HIGE:
|
||||
gpio_put(PIN_MOTOR_IO1, 1);
|
||||
gpio_put(PIN_MOTOR_IO2, 0);
|
||||
break;
|
||||
case STATE_LOW:
|
||||
gpio_put(PIN_MOTOR_IO1, 0);
|
||||
gpio_put(PIN_MOTOR_IO2, 1);
|
||||
break;
|
||||
static inline void put_pixel(PIO pio, uint sm, uint32_t pixel_grb) {
|
||||
pio_sm_put_blocking(pio, sm, pixel_grb << 8u);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return ((uint32_t) (r) << 16) | ((uint32_t) (g) << 8) | (uint32_t) (b);
|
||||
}
|
||||
|
||||
int main() {
|
||||
//set_sys_clock_48();
|
||||
stdio_init_all();
|
||||
// stdio_init_all();
|
||||
|
||||
mainState = STATE_OFF;
|
||||
uint pwm_out;
|
||||
|
||||
// init gpio outputs
|
||||
gpio_init(PIN_LED_MODE_RED);
|
||||
@ -71,31 +63,89 @@ int main() {
|
||||
gpio_init(PIN_LED_BATT3);
|
||||
gpio_set_dir(PIN_LED_BATT3, GPIO_OUT);
|
||||
gpio_put(PIN_LED_BATT3, 0);
|
||||
gpio_init(PIN_MOTOR_IO1);
|
||||
gpio_set_dir(PIN_MOTOR_IO1, GPIO_OUT);
|
||||
gpio_put(PIN_MOTOR_IO1, 0);
|
||||
gpio_init(PIN_MOTOR_IO2);
|
||||
gpio_set_dir(PIN_MOTOR_IO2, GPIO_OUT);
|
||||
gpio_put(PIN_MOTOR_IO2, 0);
|
||||
// gpio_init(PIN_MOTOR_PWM);
|
||||
gpio_set_function(PIN_MOTOR_PWM, GPIO_FUNC_PWM);
|
||||
pwm_out = pwm_gpio_to_slice_num(PIN_MOTOR_PWM);
|
||||
pwm_config config = pwm_get_default_config();
|
||||
// set to about 25 kHz
|
||||
pwm_config_set_clkdiv(&config, 255.f);
|
||||
pwm_config_set_wrap(&config, 19);
|
||||
pwm_init(pwm_out, &config, true);
|
||||
pwm_set_gpio_level(PIN_MOTOR_PWM, 0);
|
||||
// init gpio inputs
|
||||
gpio_init(PIN_BTN);
|
||||
gpio_set_dir(PIN_BTN, GPIO_IN);
|
||||
gpio_set_pulls(PIN_BTN, false, true);
|
||||
// gpio_set_irq_enabled_with_callback(PIN_BTN, GPIO_IRQ_EDGE_FALL, true, &switch_state);
|
||||
|
||||
// todo get free sm
|
||||
PIO pio;
|
||||
uint sm;
|
||||
uint offset;
|
||||
pio_claim_free_sm_and_add_program_for_gpio_range(&ws2812_program, &pio, &sm, &offset, WS2812_PIN, 1, false);
|
||||
ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, false);
|
||||
put_pixel(pio, sm, urgb_u32(0, 0, 0));
|
||||
// pio_remove_program_and_unclaim_sm(&ws2812_program, pio, sm, offset);
|
||||
|
||||
mainState = STATE_OFF;
|
||||
|
||||
uint8_t counter = 0;
|
||||
bool last_state = true;
|
||||
while (true)
|
||||
{
|
||||
mainState = STATE_OFF;
|
||||
update_state(STATE_OFF);
|
||||
sleep_goto_dormant_until_edge_high(PIN_BTN);
|
||||
mainState = STATE_HIGE;
|
||||
while (mainState != STATE_OFF)
|
||||
{
|
||||
// sleep_run_from_xosc();
|
||||
// sleep_goto_dormant_until_pin(PIN_BTN, true, false); // falling edge
|
||||
// sleep_goto_sleep_for(100, &switch_state); // debounce
|
||||
// sleep_power_up();
|
||||
|
||||
bool new_state;
|
||||
while ((new_state = gpio_get(PIN_BTN)) == last_state) {
|
||||
tight_loop_contents();
|
||||
}
|
||||
sleep_ms(100);
|
||||
last_state = new_state;
|
||||
if (new_state) {
|
||||
switch (mainState) {
|
||||
case STATE_OFF:
|
||||
mainState = STATE_HIGE;
|
||||
gpio_put(PIN_MOTOR_IO1, 0);
|
||||
gpio_put(PIN_MOTOR_IO2, 1);
|
||||
|
||||
gpio_put(PIN_LED_MODE_RED, 1);
|
||||
gpio_put(PIN_LED_MODE_GREEN, 0);
|
||||
pwm_set_gpio_level(PIN_MOTOR_PWM, 19);
|
||||
|
||||
put_pixel(pio, sm, urgb_u32(50, 0, 0));
|
||||
break;
|
||||
case STATE_HIGE:
|
||||
mainState = STATE_LOW;
|
||||
gpio_put(PIN_MOTOR_IO1, 0);
|
||||
gpio_put(PIN_MOTOR_IO2, 1);
|
||||
|
||||
gpio_put(PIN_LED_MODE_RED, 0);
|
||||
gpio_put(PIN_LED_MODE_GREEN, 1);
|
||||
pwm_set_gpio_level(PIN_MOTOR_PWM, 12);
|
||||
|
||||
put_pixel(pio, sm, urgb_u32(0, 50, 0));
|
||||
break;
|
||||
case STATE_LOW:
|
||||
mainState = STATE_OFF;
|
||||
gpio_put(PIN_MOTOR_IO1, 0);
|
||||
gpio_put(PIN_MOTOR_IO2, 0);
|
||||
|
||||
gpio_put(PIN_LED_MODE_RED, 0);
|
||||
gpio_put(PIN_LED_MODE_GREEN, 0);
|
||||
pwm_set_gpio_level(PIN_MOTOR_PWM, 0);
|
||||
|
||||
put_pixel(pio, sm, urgb_u32(0, 0, 50));
|
||||
break;
|
||||
}
|
||||
update_state(mainState);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
53
src/ws2812.pio
Normal file
53
src/ws2812.pio
Normal file
@ -0,0 +1,53 @@
|
||||
;
|
||||
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
;
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;
|
||||
.pio_version 0 // only requires PIO version 0
|
||||
|
||||
.program ws2812
|
||||
.side_set 1
|
||||
|
||||
; The following constants are selected for broad compatibility with WS2812,
|
||||
; WS2812B, and SK6812 LEDs. Other constants may support higher bandwidths for
|
||||
; specific LEDs, such as (7,10,8) for WS2812B LEDs.
|
||||
|
||||
.define public T1 3
|
||||
.define public T2 3
|
||||
.define public T3 4
|
||||
|
||||
.lang_opt python sideset_init = pico.PIO.OUT_HIGH
|
||||
.lang_opt python out_init = pico.PIO.OUT_HIGH
|
||||
.lang_opt python out_shiftdir = 1
|
||||
|
||||
.wrap_target
|
||||
bitloop:
|
||||
out x, 1 side 0 [T3 - 1] ; Side-set still takes place when instruction stalls
|
||||
jmp !x do_zero side 1 [T1 - 1] ; Branch on the bit we shifted out. Positive pulse
|
||||
do_one:
|
||||
jmp bitloop side 1 [T2 - 1] ; Continue driving high, for a long pulse
|
||||
do_zero:
|
||||
nop side 0 [T2 - 1] ; Or drive low, for a short pulse
|
||||
.wrap
|
||||
|
||||
% c-sdk {
|
||||
#include "hardware/clocks.h"
|
||||
|
||||
static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) {
|
||||
|
||||
pio_gpio_init(pio, pin);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
|
||||
|
||||
pio_sm_config c = ws2812_program_get_default_config(offset);
|
||||
sm_config_set_sideset_pins(&c, pin);
|
||||
sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
|
||||
|
||||
int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3;
|
||||
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
|
||||
sm_config_set_clkdiv(&c, div);
|
||||
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
%}
|
||||
Loading…
x
Reference in New Issue
Block a user