diff --git a/.gitmodules b/.gitmodules index 1891415..e85b5ef 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "libs/pico-sdk"] path = libs/pico-sdk url = https://github.com/raspberrypi/pico-sdk.git +[submodule "libs/pico-extra"] + path = libs/pico-extra + url = https://github.com/raspberrypi/pico-extras.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 570ca8d..c712c83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,11 @@ cmake_minimum_required(VERSION 3.13) +set(PICO_EXTRAS_PATH ${CMAKE_CURRENT_LIST_DIR}/libs/pico-extra) + # initialize the SDK based on PICO_SDK_PATH # note: this must happen before project() include(libs/pico-sdk/pico_sdk_init.cmake) +include(pico_extras_import.cmake) project(stofzuiger CXX C ASM) @@ -14,10 +17,10 @@ pico_sdk_init() add_executable(stofzuiger src/main.c) -# pico_generate_pio_header(stofzuiger ${CMAKE_CURRENT_LIST_DIR}/src/ws2812.pio) -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_pio) +target_link_libraries(stofzuiger + pico_stdlib + hardware_sleep +) pico_enable_stdio_uart(stofzuiger 0) pico_enable_stdio_usb(stofzuiger 1) diff --git a/libs/pico-extra b/libs/pico-extra new file mode 160000 index 0000000..f05d4f7 --- /dev/null +++ b/libs/pico-extra @@ -0,0 +1 @@ +Subproject commit f05d4f7371802440cadd36744789a26944d950ac diff --git a/pico_extras_import.cmake b/pico_extras_import.cmake new file mode 100644 index 0000000..ce714ff --- /dev/null +++ b/pico_extras_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_extras_import.cmake + +# This can be dropped into an external project to help locate pico-extras +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_EXTRAS_PATH} AND (NOT PICO_EXTRAS_PATH)) + set(PICO_EXTRAS_PATH $ENV{PICO_EXTRAS_PATH}) + message("Using PICO_EXTRAS_PATH from environment ('${PICO_EXTRAS_PATH}')") +endif () + +if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT)) + set(PICO_EXTRAS_FETCH_FROM_GIT $ENV{PICO_EXTRAS_FETCH_FROM_GIT}) + message("Using PICO_EXTRAS_FETCH_FROM_GIT from environment ('${PICO_EXTRAS_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT_PATH)) + set(PICO_EXTRAS_FETCH_FROM_GIT_PATH $ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH}) + message("Using PICO_EXTRAS_FETCH_FROM_GIT_PATH from environment ('${PICO_EXTRAS_FETCH_FROM_GIT_PATH}')") +endif () + +if (NOT PICO_EXTRAS_PATH) + if (PICO_EXTRAS_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_EXTRAS_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_extras + GIT_REPOSITORY https://github.com/raspberrypi/pico-extras + GIT_TAG master + ) + if (NOT pico_extras) + message("Downloading PICO EXTRAS") + FetchContent_Populate(pico_extras) + set(PICO_EXTRAS_PATH ${pico_extras_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + if (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../pico-extras") + set(PICO_EXTRAS_PATH ${PICO_SDK_PATH}/../pico-extras) + message("Defaulting PICO_EXTRAS_PATH as sibling of PICO_SDK_PATH: ${PICO_EXTRAS_PATH}") + else() + message(FATAL_ERROR + "PICO EXTRAS location was not specified. Please set PICO_EXTRAS_PATH or set PICO_EXTRAS_FETCH_FROM_GIT to on to fetch from git." + ) + endif() + endif () +endif () + +set(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" CACHE PATH "Path to the PICO EXTRAS") +set(PICO_EXTRAS_FETCH_FROM_GIT "${PICO_EXTRAS_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO EXTRAS from git if not otherwise locatable") +set(PICO_EXTRAS_FETCH_FROM_GIT_PATH "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download EXTRAS") + +get_filename_component(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_EXTRAS_PATH}) + message(FATAL_ERROR "Directory '${PICO_EXTRAS_PATH}' not found") +endif () + +set(PICO_EXTRAS_PATH ${PICO_EXTRAS_PATH} CACHE PATH "Path to the PICO EXTRAS" FORCE) + +add_subdirectory(${PICO_EXTRAS_PATH} pico_extras) diff --git a/src/generated/.gitignore b/src/generated/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/src/generated/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/src/main.c b/src/main.c index bb695ba..0f8ec5d 100644 --- a/src/main.c +++ b/src/main.c @@ -4,47 +4,99 @@ #include #include -#include #include -#include "generated/ws2812.pio.h" +#include #define IS_RGBW false #define NUM_PIXELS 1 #define WS2812_PIN 16 -static inline void put_pixel(PIO pio, uint sm, uint32_t pixel_grb) { - pio_sm_put_blocking(pio, sm, pixel_grb << 8u); -} +#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_MOTOR_PWM 8 -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); +typedef enum { + STATE_OFF, + STATE_HIGE, + STATE_LOW +} mainState_t; +mainState_t mainState; + +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; + + + } } int main() { //set_sys_clock_48(); stdio_init_all(); - printf("WS2812 test %d\n", WS2812_PIN); - // todo get free sm - PIO pio; - uint sm; - uint offset; + mainState = STATE_OFF; - // This will find a free pio and state machine for our program and load it for us - // We use pio_claim_free_sm_and_add_program_for_gpio_range (for_gpio_range variant) - // so we will get a PIO instance suitable for addressing gpios >= 32 if needed and supported by the hardware - bool success = pio_claim_free_sm_and_add_program_for_gpio_range(&ws2812_program, &pio, &sm, &offset, WS2812_PIN, 1, false); - if (success == false) + // init gpio outputs + gpio_init(PIN_LED_MODE_RED); + gpio_set_dir(PIN_LED_MODE_RED, GPIO_OUT); + gpio_put(PIN_LED_MODE_RED, 0); + gpio_init(PIN_LED_MODE_GREEN); + gpio_set_dir(PIN_LED_MODE_GREEN, GPIO_OUT); + gpio_put(PIN_LED_MODE_GREEN, 0); + gpio_init(PIN_LED_BATT1); + gpio_set_dir(PIN_LED_BATT1, GPIO_OUT); + gpio_put(PIN_LED_BATT1, 0); + gpio_init(PIN_LED_BATT2); + gpio_set_dir(PIN_LED_BATT2, GPIO_OUT); + gpio_put(PIN_LED_BATT2, 0); + gpio_init(PIN_LED_BATT3); + gpio_set_dir(PIN_LED_BATT3, GPIO_OUT); + gpio_put(PIN_LED_BATT3, 0); + gpio_set_dir(PIN_MOTOR_IO1, GPIO_OUT); + gpio_put(PIN_MOTOR_IO1, 0); + gpio_set_dir(PIN_MOTOR_IO2, GPIO_OUT); + gpio_put(PIN_MOTOR_IO2, 0); + // init gpio inputs + gpio_init(PIN_BTN); + gpio_set_dir(PIN_BTN, GPIO_IN); + + while (true) { - printf("Faild to claim PIO or SM"); - return -1; + mainState = STATE_OFF; + update_state(STATE_OFF); + sleep_goto_dormant_until_edge_high(PIN_BTN); + mainState = STATE_HIGE; + while (mainState != STATE_OFF) + { + switch (mainState) { + case STATE_HIGE: + mainState = STATE_LOW; + break; + case STATE_LOW: + mainState = STATE_OFF; + break; + } + update_state(mainState); + } } - ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, false); - - put_pixel(pio, sm, urgb_u32(50, 50, 50)); - - // This will free resources and unload our program - pio_remove_program_and_unclaim_sm(&ws2812_program, pio, sm, offset); - return 0; } \ No newline at end of file diff --git a/src/ws2812.pio b/src/ws2812.pio deleted file mode 100644 index a294f37..0000000 --- a/src/ws2812.pio +++ /dev/null @@ -1,53 +0,0 @@ -; -; 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); -} -%}