-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
51 changed files
with
5,290 additions
and
1,961 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
cmake_minimum_required(VERSION 3.24) | ||
set(CMAKE_C_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
if (NOT PICO_SDK_PATH) | ||
set(PICO_SDK_PATH "~/raspberrypi/pico-sdk") | ||
endif () | ||
|
||
if (NOT PICO_EXTRAS_PATH) | ||
set(PICO_EXTRAS_PATH "~/raspberrypi/pico-extras") | ||
endif () | ||
|
||
include(cmake/pico_sdk_import.cmake) | ||
include(cmake/pico_extras_import.cmake) | ||
|
||
project(c_scaffold C CXX) | ||
|
||
set(CMAKE_BUILD_TYPE Release) | ||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-void-pointer-to-int-cast -Wno-int-to-void-pointer-cast -Wno-pointer-sign -Werror=implicit-function-declaration") | ||
|
||
add_executable(${PROJECT_NAME} "src/main.c") | ||
|
||
target_include_directories(${PROJECT_NAME} PRIVATE "src/") | ||
|
||
pico_sdk_init() | ||
add_definitions( | ||
-DSAMPLES_PER_BUFFER=\(256*6\) | ||
-DBUFFER_COUNT=3 | ||
) | ||
|
||
pico_enable_stdio_usb(${PROJECT_NAME} 1) | ||
pico_enable_stdio_uart(${PROJECT_NAME} 1) | ||
|
||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../sprig_hal sprig_hal) | ||
|
||
target_link_libraries(${PROJECT_NAME} PRIVATE | ||
pico_stdlib | ||
pico_multicore | ||
hardware_spi | ||
hardware_timer | ||
hardware_pwm | ||
hardware_adc | ||
sprig_hal | ||
) | ||
|
||
# create map/bin/hex file etc. | ||
pico_add_extra_outputs(${PROJECT_NAME}) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Sprig C Firmware Scaffold |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# This is a copy of <PICO_EXTRAS_PATH>/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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake | ||
|
||
# This can be dropped into an external project to help locate this SDK | ||
# It should be include()ed prior to project() | ||
|
||
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) | ||
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) | ||
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") | ||
endif () | ||
|
||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) | ||
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) | ||
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") | ||
endif () | ||
|
||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) | ||
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) | ||
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") | ||
endif () | ||
|
||
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") | ||
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") | ||
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") | ||
|
||
if (NOT PICO_SDK_PATH) | ||
if (PICO_SDK_FETCH_FROM_GIT) | ||
include(FetchContent) | ||
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) | ||
if (PICO_SDK_FETCH_FROM_GIT_PATH) | ||
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") | ||
endif () | ||
# GIT_SUBMODULES_RECURSE was added in 3.17 | ||
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") | ||
FetchContent_Declare( | ||
pico_sdk | ||
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk | ||
GIT_TAG master | ||
GIT_SUBMODULES_RECURSE FALSE | ||
) | ||
else () | ||
FetchContent_Declare( | ||
pico_sdk | ||
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk | ||
GIT_TAG master | ||
) | ||
endif () | ||
|
||
if (NOT pico_sdk) | ||
message("Downloading Raspberry Pi Pico SDK") | ||
FetchContent_Populate(pico_sdk) | ||
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) | ||
endif () | ||
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) | ||
else () | ||
message(FATAL_ERROR | ||
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." | ||
) | ||
endif () | ||
endif () | ||
|
||
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") | ||
if (NOT EXISTS ${PICO_SDK_PATH}) | ||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") | ||
endif () | ||
|
||
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) | ||
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) | ||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") | ||
endif () | ||
|
||
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) | ||
|
||
include(${PICO_SDK_INIT_CMAKE_FILE}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#ifndef C_SCAFFOLD_AUDIO_H | ||
#define C_SCAFFOLD_AUDIO_H | ||
|
||
#include <math.h> | ||
#include "HAL.h" | ||
|
||
#define SINE_WAVE_TABLE_LEN 2048 | ||
|
||
int16_t sine_wave_table[SINE_WAVE_TABLE_LEN]; | ||
|
||
// precalculate a sine wave and store it in sine_wave_table | ||
void init_sine_wave_table() { | ||
for (int i = 0; i < SINE_WAVE_TABLE_LEN; i++) { | ||
sine_wave_table[i] = 32767 * cosf(i * 2 * (float) (M_PI / SINE_WAVE_TABLE_LEN)); | ||
} | ||
} | ||
|
||
void play_sine_wave(uint32_t step, uint32_t volume) { | ||
// get a free audio buffer from the pool | ||
struct audio_buffer *buffer = get_audio_buffer(false); | ||
if (buffer == NULL) return; // if there aren't free buffers, return early | ||
|
||
uint32_t pos_max = 0x10000 * SINE_WAVE_TABLE_LEN; | ||
uint32_t pos = 0; | ||
|
||
int16_t *samples = (int16_t *) buffer->buffer->bytes; // reference to buffer bytes | ||
for (uint i = 0; i < buffer->max_sample_count; i++) { | ||
// sample the sine wave at position pos, and write to buffer | ||
samples[i] = (volume * sine_wave_table[pos >> 16u]) >> 8u; | ||
|
||
// increment pos; if step is larger, it'll move faster thru the sine wave, and pitch is higher | ||
pos += step; | ||
if (pos >= pos_max) pos -= pos_max; // wrap back around if past end of wave | ||
} | ||
buffer->sample_count = buffer->max_sample_count; | ||
push_audio_buffer(buffer); // push filled buffer into the pool | ||
} | ||
|
||
#endif //C_SCAFFOLD_AUDIO_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#ifndef C_SCAFFOLD_BUTTONS_H | ||
#define C_SCAFFOLD_BUTTONS_H | ||
|
||
/** | ||
* We store a 64-boolean ringbuffer of polled button states for a primitive | ||
* sort of debouncing. The button counts as pressed if more than 5/6th of | ||
* the ringbuffer is true. | ||
* | ||
* (gpio_set_input_hysteresis_enabled was too slow.) | ||
*/ | ||
#include "HAL.h" | ||
#include "pico/util/queue.h" | ||
#include "pico/multicore.h" | ||
|
||
#define HISTORY_LEN (64) | ||
|
||
typedef struct { | ||
uint8_t history[HISTORY_LEN / 8]; | ||
uint8_t last_state; | ||
uint8_t ring_i; | ||
} ButtonState; | ||
|
||
ButtonState button_states[8] = {0}; | ||
|
||
bool button_history_read(ButtonState *bs, int i) { | ||
// We want to store bools compactly so we have to do some bit twiddling. | ||
int q = 1 << (i % 8); | ||
return !!(bs->history[i / 8] & q); | ||
} | ||
|
||
void button_history_write(ButtonState *bs, int i, bool value) { | ||
if (value) | ||
bs->history[i / 8] |= 1 << (i % 8); | ||
else | ||
bs->history[i / 8] &= ~(1 << (i % 8)); | ||
} | ||
|
||
/** | ||
* Poll the buttons and push any keypresses to the main core. | ||
* | ||
* (Should be run in a loop on a non-primary core.) | ||
*/ | ||
void button_poll(void) { | ||
for (;;) { | ||
for (int i = 0; i < 8; i++) { | ||
ButtonState *bs = button_states + i; | ||
|
||
bs->ring_i = (bs->ring_i + 1) % HISTORY_LEN; // Incrememnt ringbuffer index | ||
button_history_write(bs, bs->ring_i, get_button( (Sprig_Button) i)); | ||
|
||
// up is true if more than 5/6 are true | ||
int up = 0; | ||
for (int i = 0; i < HISTORY_LEN; i++) { | ||
up += button_history_read(bs, i); | ||
} | ||
up = up > ((HISTORY_LEN * 5) / 6); // Here we convert to a bool | ||
|
||
if (up != bs->last_state) { | ||
bs->last_state = up; | ||
if (!up) { | ||
// Send the keypress to the main core | ||
multicore_fifo_push_blocking(i); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
Sprig_Button get_button_press() { | ||
if (!multicore_fifo_rvalid()) return Button_None; | ||
return (Sprig_Button) multicore_fifo_pop_blocking(); | ||
} | ||
|
||
void init_button_handler() { | ||
// Start a core to listen for keypresses. | ||
multicore_reset_core1(); | ||
multicore_launch_core1(button_poll); | ||
|
||
/* We get a bunch of fake keypresses at startup, so we need to | ||
* drain them from the FIFO queue. */ | ||
sleep_ms(50); | ||
while (multicore_fifo_rvalid()) multicore_fifo_pop_blocking(); | ||
} | ||
|
||
#endif //C_SCAFFOLD_BUTTONS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#ifndef C_SCAFFOLD_COMMON_H | ||
#define C_SCAFFOLD_COMMON_H | ||
|
||
#define SCREEN_SIZE_X (160) | ||
#define SCREEN_SIZE_Y (128) | ||
|
||
#define TEXT_CHARS_MAX_X (20) | ||
#define TEXT_CHARS_MAX_Y (16) | ||
|
||
#define ARR_LEN(arr) (sizeof(arr) / sizeof(arr[0])) | ||
|
||
uint8_t flip_endianness(uint8_t in) { | ||
in = ((in & 0x0F) << 4) | ((in & 0xF0) >> 4); | ||
in = ((in & 0b00110011) << 2) | ((in & 0b11001100) >> 2); | ||
in = ((in & 0b01010101) << 1) | ((in & 0b10101010) >> 1); | ||
return in; | ||
} | ||
|
||
uint16_t color16(uint8_t r, uint8_t g, uint8_t b) { | ||
// arrange bits in 5-6-5 (BBBBBGGG GGGRRRRR) | ||
uint16_t result = ((b & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (r >> 3); | ||
|
||
// swap bytes to conform to display endianness | ||
return ((result & 0x00FF) << 8) | ((result & 0xFF00) >> 8); | ||
} | ||
|
||
|
||
#endif //C_SCAFFOLD_COMMON_H |
Oops, something went wrong.