Initial commit

main
EmaMaker 2023-08-05 10:54:01 +02:00
commit 1d72873f0d
8 changed files with 578 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
build
build.sh
.vscode

52
CMakeLists.txt Normal file
View File

@ -0,0 +1,52 @@
# Generated Cmake Pico project file
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
set(PICO_SDK_PATH "/usr/share/pico-sdk")
set(PICO_BOARD pico CACHE STRING "Board type")
# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)
if (PICO_SDK_VERSION_STRING VERSION_LESS "1.4.0")
message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.4.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
endif()
project(SDA5708 C CXX ASM)
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
# Add executable. Default name is the project name, version 0.1
add_executable(SDA5708 SDA5708.c sda5708.c )
pico_set_program_name(SDA5708 "SDA5708")
pico_set_program_version(SDA5708 "0.1")
pico_enable_stdio_uart(SDA5708 0)
pico_enable_stdio_usb(SDA5708 1)
# Add the standard library to the build
target_link_libraries(SDA5708
pico_stdlib)
# Add the standard include files to the build
target_include_directories(SDA5708 PRIVATE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required
)
# Add any user requested libraries
target_link_libraries(SDA5708
hardware_spi
)
pico_add_extra_outputs(SDA5708)

7
README.md Normal file
View File

@ -0,0 +1,7 @@
The SDA5708 is 8 digit 7x5 led matrix display, the font used by the hardware is defined in software
This is a C library and example to control the display using a Raspberry Pi Pico communicating with the display using SPI.
Hardware reference: [https://www.sbprojects.net/knowledge/footprints/sda5708/index.php](!https://www.sbprojects.net/knowledge/footprints/sda5708/index.php).
You can copy the files `sda5708.h` `sda5708.c` `sda5708_fonts.h` for use in another Pico project

78
SDA5708.c Normal file
View File

@ -0,0 +1,78 @@
#include <stdio.h>
#include "pico/stdlib.h"
#include "sda5708.h"
#include "sda5708_fonts.h"
#define BUF_LEN 27
int main() {
#if !defined(spi_default) || !defined(PICO_DEFAULT_SPI_SCK_PIN) || !defined(PICO_DEFAULT_SPI_TX_PIN) || !defined(PICO_DEFAULT_SPI_RX_PIN) || !defined(PICO_DEFAULT_SPI_CSN_PIN)
#warning spi/spi_master example requires a board with SPI pins
puts("Default SPI pins were not defined");
#else
printf("SPI master example\n");
sda5708_init(spi_default, PICO_DEFAULT_SPI_TX_PIN, PICO_DEFAULT_SPI_SCK_PIN, PICO_DEFAULT_SPI_CSN_PIN);
sda5708_clear(spi_default);
sda5708_set_brightness(spi_default, 3);
sda5708_set_max_current(spi_default, 0);
/*int i = 0, a = 1;
while(1){
sda5708_clear(spi_default);
sda5708_select_digit(spi_default, i);
sda5708_write_character(spi_default, letter_O);
i += a;
if( i >= 7 || i <= 0) a = -a;
sleep_ms(500);
}*/
uint8_t* buf[BUF_LEN] = {
letter_A,
letter_B,
letter_C,
letter_D,
letter_E,
letter_F,
letter_G,
letter_H,
letter_I,
letter_J,
letter_K,
letter_L,
letter_M,
letter_N,
letter_O,
letter_P,
letter_Q,
letter_R,
letter_S,
letter_T,
letter_U,
letter_V,
letter_W,
letter_X,
letter_Y,
letter_Z,
character_empty
};
int off = 0;
while(1){
sda5708_clear(spi_default);
for(int i = 0; i < 8; i++){
sda5708_select_digit(spi_default, i);
sda5708_write_character(spi_default, buf [(off+i) % BUF_LEN]);
}
off = (off+1) % BUF_LEN;
sleep_ms(350);
}
#endif
}

73
pico_sdk_import.cmake Normal file
View File

@ -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})

83
sda5708.c Normal file
View File

@ -0,0 +1,83 @@
#include "sda5708.h"
/* Display has 8 levels of brightness. We encode that as level:
0 (lowest): needs 0b111 (7) to be sent to the display
7 (highest): needs 0b000 (0) to be sent to the display
The order of the bits needs to be reversed
*/
uint8_t brightness_lookup[] = {
0b11100000,
0b01100000,
0b10100000,
0b00100000,
0b11000000,
0b01000000,
0b10000000,
0b00000000
};
// The digits need to be reversed too
uint8_t digit_lookup[] = {
0b00000000,
0b10000000,
0b01000000,
0b11000000,
0b00100000,
0b10100000,
0b01100000,
0b11100000
};
uint8_t BRIGHTNESS_LEVEL = 0b000;
bool PEAK_CURRENT = 0b0;
void sda5708_init(spi_inst_t *spi, int SPI_DATA_PIN, int SPI_CLOCK_PIN, int SPI_LOAD_PIN){
// Enable SPI 0 at 1 MHz and connect to GPIOs
spi_init(spi_default, 1000*1000);
gpio_set_function(SPI_DATA_PIN, GPIO_FUNC_SPI);
gpio_set_function(SPI_CLOCK_PIN, GPIO_FUNC_SPI);
gpio_set_function(SPI_LOAD_PIN, GPIO_FUNC_SPI);
// Make the SPI pins available to picotool
bi_decl(bi_4pins_with_func(PICO_DEFAULT_SPI_RX_PIN, PICO_DEFAULT_SPI_TX_PIN, PICO_DEFAULT_SPI_SCK_PIN, PICO_DEFAULT_SPI_CSN_PIN, GPIO_FUNC_SPI));
}
// Clear the screen
void sda5708_clear(spi_inst_t *spi){
// This whole sharade of bitwise operations is needed because the hardware reads the bits in the
// bytes in reverse order (considers MSB the LSB)
uint8_t out[] ={
BRIGHTNESS_LEVEL | (PEAK_CURRENT << 5) | 0b00000011, //clear
BRIGHTNESS_LEVEL | (PEAK_CURRENT << 5) | 0b00000111 //return to normal
};
spi_write_blocking(spi, out, 2);
}
// The display only has 8 level of brightness [0, 7].
void sda5708_set_brightness(spi_inst_t* spi, uint8_t brightness){
if(brightness > 7) brightness = 7;
BRIGHTNESS_LEVEL = brightness_lookup[brightness];
uint8_t b = BRIGHTNESS_LEVEL | (PEAK_CURRENT << 5) | 0b00000111; //return to normal
spi_write_blocking(spi, &b, 1);
}
void sda5708_set_max_current(spi_inst_t* spi, bool current){
PEAK_CURRENT = current;
}
// The display only has 8 digits
void sda5708_select_digit(spi_inst_t* spi, uint8_t digit){
if(digit > 7) digit = 7;
uint8_t b = digit_lookup[digit] | 0b00000101;
spi_write_blocking(spi, &b, 1);
}
//Writs a character to the select digit
void sda5708_write_character(spi_inst_t* spi, uint8_t* letter){
spi_write_blocking(spi, letter, 7);
}

34
sda5708.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef SDA5708_H
#define SDA5707_H
#include <stdbool.h>
#include "hardware/spi.h"
#include "pico/stdlib.h"
#include "pico/binary_info.h"
/* Hardware reference: https://www.sbprojects.net/knowledge/footprints/sda5708/index.php
The article is actually wrong, has each byte needs to be sent in reverse (MSB in place of LSB)
The display receives commands in SPI, but names the pins differently
SPI_DATA_PIN -> SPI TX (MOSI)
SPI_LOAD_PIN -> SPI CS (Chip Select)
SPI_CLOCK_PIN -> SPI SCLK
Since the display does not send information back, there is no need to setup a RX (MISO) pin
*/
// Init SPI communication with the display
void sda5708_init(spi_inst_t *spi, int SPI_DATA_PIN, int SPI_CLOCK_PIN, int SPI_LOAD_PIN);
// Clear the screen
void sda5708_clear(spi_inst_t *spi);
// The display only has 8 level of brightness [0, 7].
void sda5708_set_brightness(spi_inst_t* spi, uint8_t brightness);
// The display has two modes: max current (0), 12.5% max current(1);
void sda5708_set_max_current(spi_inst_t* spi, bool current);
// The display only has 8 digits
void sda5708_select_digit(spi_inst_t* spi, uint8_t digit);
//Writs a character to the select digit
void sda5708_write_character(spi_inst_t*, uint8_t* letter);
#endif

248
sda5708_fonts.h Normal file
View File

@ -0,0 +1,248 @@
#ifndef SDA5708_FONTS_H
#define SDA5708_H
uint8_t letter_A[] = { 0b00100000,
0b01010000,
0b01010000,
0b11111000,
0b10001000,
0b10001000,
0b10001000
};
uint8_t letter_B[] = { 0b01111000,
0b10001000,
0b10001000,
0b01111000,
0b10001000,
0b10001000,
0b01111000
};
uint8_t letter_C[] = { 0b11110000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b11110000
};
uint8_t letter_D[] = { 0b01111000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01111000
};
uint8_t letter_E[] = { 0b11111000,
0b00001000,
0b00001000,
0b11111000,
0b00001000,
0b00001000,
0b11111000
};
uint8_t letter_F[] = { 0b11111000,
0b00001000,
0b00001000,
0b01111000,
0b00001000,
0b00001000,
0b00001000
};
uint8_t letter_G[] = { 0b11110000,
0b00001000,
0b00001000,
0b11001000,
0b10001000,
0b10001000,
0b11110000
};
uint8_t letter_H[] = { 0b10001000,
0b10001000,
0b10001000,
0b11111000,
0b10001000,
0b10001000,
0b10001000
};
uint8_t letter_I[] = { 0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000
};
uint8_t letter_J[] = { 0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b01110000
};
uint8_t letter_K[] = { 0b10001000,
0b01001000,
0b00101000,
0b00011000,
0b00101000,
0b01001000,
0b10001000
};
uint8_t letter_L[] = { 0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b00001000,
0b11111000
};
uint8_t letter_M[] = { 0b10001000,
0b11011000,
0b10101000,
0b10001000,
0b10001000,
0b10001000,
0b10001000
};
uint8_t letter_N[] = { 0b10001000,
0b10011000,
0b10101000,
0b10101000,
0b11001000,
0b10001000,
0b10001000
};
uint8_t letter_O[] = { 0b01110000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01110000
};
uint8_t letter_P[] = { 0b01111000,
0b10001000,
0b10001000,
0b01111000,
0b00001000,
0b00001000,
0b00001000
};
uint8_t letter_Q[] = { 0b01110000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01110000,
0b10000000
};
uint8_t letter_R[] = { 0b01111000,
0b10001000,
0b10001000,
0b01111000,
0b01001000,
0b10001000,
0b10001000
};
uint8_t letter_S[] = { 0b11110000,
0b00001000,
0b00001000,
0b01110000,
0b10000000,
0b10000000,
0b01111000
};
uint8_t letter_T[] = { 0b11111000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000
};
uint8_t letter_U[] = { 0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01110000
};
uint8_t letter_V[] = { 0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01010000,
0b01010000,
0b00100000
};
uint8_t letter_W[] = { 0b10001000,
0b10001000,
0b10001000,
0b10101000,
0b10101000,
0b10101000,
0b01110000
};
uint8_t letter_X[] = { 0b10001000,
0b10001000,
0b01010000,
0b00100000,
0b01010000,
0b10001000,
0b10001000
};
uint8_t letter_Y[] = { 0b10001000,
0b10001000,
0b01010000,
0b00100000,
0b00100000,
0b00100000,
0b00100000
};
uint8_t letter_Z[] = { 0b11111000,
0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b11111000
};
uint8_t character_empty[] = { 0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
#endif