Refactoring

- Add SPI display
- Add SSD1326 (not fully tested)
- Remove all but one dependecies to HW (#define)
- Cleanup KProjectBuild
- Update .defaults
This commit is contained in:
philippe44
2020-02-09 00:25:50 -08:00
parent f2920675f8
commit cfae996fd3
60 changed files with 1257 additions and 1017 deletions

View File

@@ -2,6 +2,28 @@
# Automatically generated file. DO NOT EDIT.
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
#
# ESP32-A1S defaults (with AC101 codec)
CONFIG_I2S_NUM=0
CONFIG_I2C_LOCKED=y
CONFIG_DISPLAY_CONFIG=""
CONFIG_I2C_CONFIG=""
CONFIG_SPI_CONFIG=""
CONFIG_SET_GPIO=""
CONFIG_ROTARY_ENCODER=""
CONFIG_LED_GREEN_GPIO=-1
CONFIG_LED_RED_GPIO=-1
CONFIG_JACK_GPIO=-1
CONFIG_BAT_CONFIG=""
CONFIG_I2S_BCK_IO=27
CONFIG_I2S_WS_IO=26
CONFIG_I2S_DO_IO=25
CONFIG_I2S_DI_IO=35
CONFIG_SDIF_NUM=0
CONFIG_SPDIF_BCK_IO=27
CONFIG_SPDIF_WS_IO=26
CONFIG_SPDIF_DO_IO=-1
CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"

View File

@@ -2,6 +2,26 @@
# Automatically generated file. DO NOT EDIT.
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
#
CONFIG_DISPLAY_CONFIG=""
CONFIG_I2C_CONFIG=""
CONFIG_SPI_CONFIG=""
CONFIG_SET_GPIO=""
CONFIG_ROTARY_ENCODER=""
CONFIG_LED_GREEN_GPIO=-1
CONFIG_LED_RED_GPIO=-1
CONFIG_JACK_GPIO=-1
CONFIG_BAT_CONFIG=""
CONFIG_I2S_NUM=0
CONFIG_I2S_BCK_IO=33
CONFIG_I2S_WS_IO=25
CONFIG_I2S_DO_IO=32
CONFIG_I2S_DI_IO=-1
CONFIG_SDIF_NUM=0
CONFIG_SPDIF_BCK_IO=33
CONFIG_SPDIF_WS_IO=25
CONFIG_SPDIF_DO_IO=-1
CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"

View File

@@ -2,6 +2,26 @@
# Automatically generated file. DO NOT EDIT.
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
#
CONFIG_DISPLAY_CONFIG=""
CONFIG_I2C_CONFIG=""
CONFIG_SPI_CONFIG=""
CONFIG_SET_GPIO=""
CONFIG_ROTARY_ENCODER=""
CONFIG_LED_GREEN_GPIO=-1
CONFIG_LED_RED_GPIO=-1
CONFIG_JACK_GPIO=-1
CONFIG_BAT_CONFIG=""
CONFIG_I2S_NUM=0
CONFIG_I2S_BCK_IO=33
CONFIG_I2S_WS_IO=25
CONFIG_I2S_DO_IO=32
CONFIG_I2S_DI_IO=-1
CONFIG_SDIF_NUM=0
CONFIG_SPDIF_BCK_IO=33
CONFIG_SPDIF_WS_IO=25
CONFIG_SPDIF_DO_IO=-1
CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"

View File

@@ -2,6 +2,26 @@
# Automatically generated file. DO NOT EDIT.
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
#
CONFIG_DISPLAY_CONFIG=""
CONFIG_I2C_CONFIG=""
CONFIG_SPI_CONFIG=""
CONFIG_SET_GPIO=""
CONFIG_ROTARY_ENCODER=""
CONFIG_LED_GREEN_GPIO=-1
CONFIG_LED_RED_GPIO=-1
CONFIG_JACK_GPIO=-1
CONFIG_BAT_CONFIG=""
CONFIG_I2S_NUM=0
CONFIG_I2S_BCK_IO=33
CONFIG_I2S_WS_IO=25
CONFIG_I2S_DO_IO=32
CONFIG_I2S_DI_IO=-1
CONFIG_SDIF_NUM=0
CONFIG_SPDIF_BCK_IO=33
CONFIG_SPDIF_WS_IO=25
CONFIG_SPDIF_DO_IO=-1
CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"

View File

@@ -2,6 +2,32 @@
# Automatically generated file. DO NOT EDIT.
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
#
# SqueezeAMP defaults
CONFIG_JACK_LOCKED=y
CONFIG_BAT_LOCKED=y
CONFIG_I2C_LOCKED=y
CONFIG_SPDIF_LOCKED=y
CONFIG_DISPLAY_CONFIG=""
CONFIG_I2C_CONFIG=""
CONFIG_SPI_CONFIG=""
CONFIG_SET_GPIO=""
CONFIG_ROTARY_ENCODER=""
CONFIG_LED_GREEN_GPIO=12
CONFIG_LED_RED_GPIO=13
CONFIG_JACK_GPIO=34
CONFIG_JACK_GPIO_LEVEL=0
CONFIG_BAT_CONFIG="channel=7,scale=20.24"
CONFIG_I2S_NUM=0
CONFIG_I2S_BCK_IO=33
CONFIG_I2S_WS_IO=25
CONFIG_I2S_DO_IO=32
CONFIG_I2S_DI_IO=-1
CONFIG_SDIF_NUM=0
CONFIG_SPDIF_BCK_IO=33
CONFIG_SPDIF_WS_IO=25
CONFIG_SPDIF_DO_IO=15
CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"

View File

@@ -2,6 +2,32 @@
# Automatically generated file. DO NOT EDIT.
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
#
# SqueezeAMP defaults
CONFIG_JACK_LOCKED=y
CONFIG_BAT_LOCKED=y
CONFIG_I2C_LOCKED=y
CONFIG_SPDIF_LOCKED=y
CONFIG_DISPLAY_CONFIG=""
CONFIG_I2C_CONFIG=""
CONFIG_SPI_CONFIG=""
CONFIG_SET_GPIO=""
CONFIG_ROTARY_ENCODER=""
CONFIG_LED_GREEN_GPIO=12
CONFIG_LED_RED_GPIO=13
CONFIG_JACK_GPIO=34
CONFIG_JACK_GPIO_LEVEL=0
CONFIG_BAT_CONFIG="channel=7,scale=20.24"
CONFIG_I2S_NUM=0
CONFIG_I2S_BCK_IO=33
CONFIG_I2S_WS_IO=25
CONFIG_I2S_DO_IO=32
CONFIG_I2S_DI_IO=-1
CONFIG_SDIF_NUM=0
CONFIG_SPDIF_BCK_IO=33
CONFIG_SPDIF_WS_IO=25
CONFIG_SPDIF_DO_IO=15
CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"

View File

@@ -2,6 +2,32 @@
# Automatically generated file. DO NOT EDIT.
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
#
# SqueezeAMP defaults
CONFIG_JACK_LOCKED=y
CONFIG_BAT_LOCKED=y
CONFIG_I2C_LOCKED=y
CONFIG_SPDIF_LOCKED=y
CONFIG_DISPLAY_CONFIG=""
CONFIG_I2C_CONFIG=""
CONFIG_SPI_CONFIG=""
CONFIG_SET_GPIO=""
CONFIG_ROTARY_ENCODER=""
CONFIG_LED_GREEN_GPIO=12
CONFIG_LED_RED_GPIO=13
CONFIG_JACK_GPIO=34
CONFIG_JACK_GPIO_LEVEL=0
CONFIG_BAT_CONFIG="channel=7,scale=20.24"
CONFIG_I2S_NUM=0
CONFIG_I2S_BCK_IO=33
CONFIG_I2S_WS_IO=25
CONFIG_I2S_DO_IO=32
CONFIG_I2S_DI_IO=-1
CONFIG_SDIF_NUM=0
CONFIG_SPDIF_BCK_IO=33
CONFIG_SPDIF_WS_IO=25
CONFIG_SPDIF_DO_IO=15
CONFIG_IDF_TARGET_ESP32=y
CONFIG_IDF_TARGET="esp32"

View File

@@ -32,7 +32,7 @@ static const char *TAG = "cmd_i2ctools";
static gpio_num_t i2c_gpio_sda = 19;
static gpio_num_t i2c_gpio_scl = 18;
static uint32_t i2c_frequency = 100000;
#ifdef CONFIG_SQUEEZEAMP
#ifdef I2C_LOCKED
static i2c_port_t i2c_port = I2C_NUM_1;
#else
static i2c_port_t i2c_port = I2C_NUM_0;

View File

@@ -9,7 +9,8 @@
#include <stdio.h>
#include "esp_log.h"
#include "driver/gpio.h"
#include <driver/i2c.h>
#include "driver/i2c.h"
#include "driver/spi_master.h"
#include "config.h"
#include "accessors.h"
#include "globdefs.h"
@@ -59,6 +60,31 @@ const i2c_config_t * config_i2c_get(int * i2c_port) {
return &i2c;
}
/****************************************************************************************
*
*/
const spi_bus_config_t * config_spi_get(spi_host_device_t * spi_host) {
char *nvs_item, *p;
static spi_bus_config_t spi = {
.mosi_io_num = -1,
.sclk_io_num = -1,
.miso_io_num = -1,
.quadwp_io_num = -1,
.quadhd_io_num = -1
};
nvs_item = config_alloc_get(NVS_TYPE_STR, "spi_config");
if (nvs_item) {
if ((p = strcasestr(nvs_item, "data")) != NULL) spi.mosi_io_num = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(nvs_item, "clk")) != NULL) spi.sclk_io_num = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(nvs_item, "d/c")) != NULL) spi_system_dc_gpio = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(nvs_item, "host")) != NULL) spi_system_host = atoi(strchr(p, '=') + 1);
free(nvs_item);
}
if(spi_host) *spi_host = spi_system_host;
return &spi;
}
/****************************************************************************************
*
*/

View File

@@ -10,7 +10,9 @@
#include "esp_system.h"
#include "driver/i2c.h"
#include "driver/spi_master.h"
esp_err_t config_i2c_set(const i2c_config_t * config, int port);
const i2c_config_t * config_i2c_get(int * i2c_port);
void parse_set_GPIO(void (*cb)(int gpio, char *value));
esp_err_t config_i2c_set(const i2c_config_t * config, int port);
const i2c_config_t * config_i2c_get(int * i2c_port);
const spi_bus_config_t * config_spi_get(spi_host_device_t * spi_host);
void parse_set_GPIO(void (*cb)(int gpio, char *value));

View File

@@ -16,6 +16,7 @@
#include "esp_log.h"
#include "driver/adc.h"
#include "battery.h"
#include "config.h"
/*
There is a bug in esp32 which causes a spurious interrupt on gpio 36/39 when
@@ -29,7 +30,8 @@
static const char *TAG = "battery";
static struct {
float sum, avg;
int channel;
float sum, avg, scale;
int count;
TimerHandle_t timer;
} battery;
@@ -37,23 +39,21 @@ static struct {
/****************************************************************************************
*
*/
int battery_value_svc(void) {
int battery_value_svc(void) {
return battery.avg;
}
/****************************************************************************************
*
*/
#ifdef CONFIG_SQUEEZEAMP
#ifdef CONFIG_BAT_CONFIG
static void battery_callback(TimerHandle_t xTimer) {
battery.sum += adc1_get_raw(ADC1_CHANNEL_7) / 4095. * (10+174)/10. * 1.1;
battery.sum += adc1_get_raw(battery.channel) * battery.scale / 4095.0;
if (++battery.count == 30) {
battery.avg = battery.sum / battery.count;
battery.sum = battery.count = 0;
ESP_LOGI(TAG, "Voltage %.2fV", battery.avg);
}
}
#endif
@@ -61,13 +61,30 @@ static void battery_callback(TimerHandle_t xTimer) {
*
*/
void battery_svc_init(void) {
#ifdef CONFIG_SQUEEZEAMP
ESP_LOGI(TAG, "Initializing battery");
#ifdef CONFIG_BAT_CONFIG
char *p;
if ((p = strcasestr(CONFIG_BAT_CONFIG, "channel")) != NULL) battery.channel = atof(strchr(p, '=') + 1);
if ((p = strcasestr(CONFIG_BAT_CONFIG, "scale")) != NULL) battery.scale = atof(strchr(p, '=') + 1);
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_0);
#ifndef BAT_LOCKED
char *nvs_item = config_alloc_get_default(NVS_TYPE_STR, "bat_config", "n", 0);
if (nvs_item) {
if ((p = strcasestr(nvs_item, "channel")) != NULL) battery.channel = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(nvs_item, "scale")) != NULL) battery.scale = atof(strchr(p, '=') + 1);
free(nvs_item);
}
#endif
battery.timer = xTimerCreate("battery", BATTERY_TIMER / portTICK_RATE_MS, pdTRUE, NULL, battery_callback);
xTimerStart(battery.timer, portMAX_DELAY);
if (battery.scale) {
ESP_LOGI(TAG, "Battery measure channel: %u, scale %f", battery.channel, battery.scale);
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(battery.channel, ADC_ATTEN_DB_0);
battery.timer = xTimerCreate("battery", BATTERY_TIMER / portTICK_RATE_MS, pdTRUE, NULL, battery_callback);
xTimerStart(battery.timer, portMAX_DELAY);
} else {
ESP_LOGI(TAG, "No battery");
}
#endif
}

View File

@@ -7,6 +7,6 @@
# please read the SDK documents if you need to do this.
#
COMPONENT_SRCDIRS := . tarablessd1306 tarablessd1306/fonts tarablessd1306/ifaces
COMPONENT_SRCDIRS := . tarablessd13x6 tarablessd13x6/fonts tarablessd13x6/ifaces
COMPONENT_ADD_INCLUDEDIRS := .
COMPONENT_ADD_INCLUDEDIRS += ./tarablessd1306
COMPONENT_ADD_INCLUDEDIRS += ./tarablessd13x6

View File

@@ -27,7 +27,7 @@
#include "display.h"
// here we should include all possible drivers
extern struct display_s SSD1306_display;
extern struct display_s SSD13x6_display;
struct display_s *display = NULL;
@@ -66,8 +66,8 @@ void display_init(char *welcome) {
if (item && *item) {
char * drivername=strstr(item,"driver");
if (!drivername || (drivername && strcasestr(drivername,"SSD1306"))) {
display = &SSD1306_display;
if (!drivername || (drivername && (strcasestr(drivername,"SSD1306") || strcasestr(drivername,"SSD1326")))) {
display = &SSD13x6_display;
if (display->init(item, welcome)) {
init = true;
ESP_LOGI(TAG, "Display initialization successful");
@@ -79,7 +79,7 @@ void display_init(char *welcome) {
ESP_LOGE(TAG,"Unknown display driver name in display config: %s",item);
}
} else {
ESP_LOGW(TAG, "no display");
ESP_LOGI(TAG, "no display");
}
if (init) {

View File

@@ -25,10 +25,10 @@
#include "display.h"
#include "globdefs.h"
#include "ssd1306.h"
#include "ssd1306_draw.h"
#include "ssd1306_font.h"
#include "ssd1306_default_if.h"
#include "ssd13x6.h"
#include "ssd13x6_draw.h"
#include "ssd13x6_font.h"
#include "ssd13x6_default_if.h"
#define I2C_ADDRESS 0x3C
@@ -50,13 +50,13 @@ static void on(bool state);
static void update(void);
// display structure for others to use
struct display_s SSD1306_display = { 0, 0,
struct display_s SSD13x6_display = { 0, 0,
init, clear, set_font, on, brightness,
text, line, stretch, update, draw, draw_cbr, NULL };
// SSD1306 specific function
static struct SSD1306_Device Display;
static SSD1306_AddressMode AddressMode = AddressMode_Invalid;
// SSD13x6 specific function
static struct SSD13x6_Device Display;
static SSD13x6_AddressMode AddressMode = AddressMode_Invalid;
static const unsigned char BitReverseTable256[] =
{
@@ -82,7 +82,7 @@ static const unsigned char BitReverseTable256[] =
static struct {
int y, space;
const struct SSD1306_FontDef *font;
const struct SSD13x6_FontDef *font;
} lines[MAX_LINES];
/****************************************************************************************
@@ -90,32 +90,51 @@ static struct {
*/
static bool init(char *config, char *welcome) {
bool res = false;
int width = -1, height = -1, model = SSD1306;
char *p;
ESP_LOGI(TAG, "Initializing display with config: %s",config);
// no time for smart parsing - this is for tinkerers
if ((p = strcasestr(config, "width")) != NULL) width = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(config, "height")) != NULL) height = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(config, "ssd1326")) != NULL) model = SSD1326;
if (width == -1 || height == -1) {
ESP_LOGW(TAG, "No display configured %s [%d x %d]", config, width, height);
return false;
}
if (strstr(config, "I2C")) {
int width = -1, height = -1, address = I2C_ADDRESS;
char *p;
ESP_LOGI(TAG, "Initializing I2C display with config: %s",config);
// no time for smart parsing - this is for tinkerers
if ((p = strcasestr(config, "width")) != NULL) width = atoi(strchr(p, '=') + 1);
if ((p = strcasestr(config, "height")) != NULL) height = atoi(strchr(p, '=') + 1);
int address = I2C_ADDRESS;
if ((p = strcasestr(config, "address")) != NULL) address = atoi(strchr(p, '=') + 1);
if (width != -1 && height != -1) {
SSD1306_I2CMasterInitDefault( i2c_system_port, -1, -1 ) ;
SSD1306_I2CMasterAttachDisplayDefault( &Display, width, height, address, -1 );
SSD1306_SetHFlip( &Display, strcasestr(config, "HFlip") ? true : false);
SSD1306_SetVFlip( &Display, strcasestr(config, "VFlip") ? true : false);
SSD1306_SetFont( &Display, &Font_droid_sans_fallback_15x17 );
SSD1306_display.width = width;
SSD1306_display.height = height;
text(DISPLAY_FONT_MEDIUM, DISPLAY_CENTERED, DISPLAY_CLEAR | DISPLAY_UPDATE, welcome);
ESP_LOGI(TAG, "Initialized I2C display %dx%d", width, height);
res = true;
} else {
ESP_LOGI(TAG, "Cannot initialized I2C display %s [%dx%d]", config, width, height);
}
SSD13x6_I2CMasterInitDefault( i2c_system_port, -1, -1 ) ;
SSD13x6_I2CMasterAttachDisplayDefault( &Display, model, width, height, address, -1 );
SSD13x6_SetHFlip( &Display, strcasestr(config, "HFlip") ? true : false);
SSD13x6_SetVFlip( &Display, strcasestr(config, "VFlip") ? true : false);
SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_15x17 );
SSD13x6_display.width = width;
SSD13x6_display.height = height;
text(DISPLAY_FONT_MEDIUM, DISPLAY_CENTERED, DISPLAY_CLEAR | DISPLAY_UPDATE, welcome);
ESP_LOGI(TAG, "Display is I2C on port %u", address);
res = true;
} else if (strstr(config, "SPI")) {
int CS_pin = -1;
if ((p = strcasestr(config, "CS")) != NULL) CS_pin = atoi(strchr(p, '=') + 1);
SSD13x6_SPIMasterInitDefault( spi_system_host, spi_system_dc_gpio );
SSD13x6_SPIMasterAttachDisplayDefault( &Display, model, width, height, CS_pin, -1 );
SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_15x17 );
SSD13x6_display.width = width;
SSD13x6_display.height = height;
text(DISPLAY_FONT_MEDIUM, DISPLAY_CENTERED, DISPLAY_CLEAR | DISPLAY_UPDATE, welcome);
ESP_LOGI(TAG, "Display is SPI host %u with CS:%d", spi_system_host, CS_pin);
} else {
ESP_LOGE(TAG, "Non-I2C display not supported. Display config %s", config);
ESP_LOGE(TAG, "Unknown display type");
}
return res;
@@ -125,8 +144,8 @@ static bool init(char *config, char *welcome) {
*
*/
static void clear(void) {
SSD1306_Clear( &Display, SSD_COLOR_BLACK );
SSD1306_Update( &Display );
SSD13x6_Clear( &Display, SSD_COLOR_BLACK );
SSD13x6_Update( &Display );
}
/****************************************************************************************
@@ -186,13 +205,13 @@ static bool line(int num, int x, int attribute, char *text) {
// always horizontal mode for text display
if (AddressMode != AddressMode_Horizontal) {
AddressMode = AddressMode_Horizontal;
SSD1306_SetDisplayAddressMode( &Display, AddressMode );
SSD13x6_SetDisplayAddressMode( &Display, AddressMode );
}
SSD1306_SetFont( &Display, lines[num].font );
if (attribute & DISPLAY_MONOSPACE) SSD1306_FontForceMonospace( &Display, true );
SSD13x6_SetFont( &Display, lines[num].font );
if (attribute & DISPLAY_MONOSPACE) SSD13x6_FontForceMonospace( &Display, true );
width = SSD1306_FontMeasureString( &Display, text );
width = SSD13x6_FontMeasureString( &Display, text );
// adjusting position, erase only EoL for rigth-justified
if (x == DISPLAY_RIGHT) x = Display.Width - width - 1;
@@ -202,15 +221,15 @@ static bool line(int num, int x, int attribute, char *text) {
if (attribute & DISPLAY_CLEAR) {
for (int c = (attribute & DISPLAY_ONLY_EOL) ? x : 0; c < Display.Width; c++)
for (int y = lines[num].y; y < lines[num].y + lines[num].font->Height; y++)
SSD1306_DrawPixelFast( &Display, c, y, SSD_COLOR_BLACK );
SSD13x6_DrawPixelFast( &Display, c, y, SSD_COLOR_BLACK );
}
SSD1306_FontDrawString( &Display, x, lines[num].y, text, SSD_COLOR_WHITE );
SSD13x6_FontDrawString( &Display, x, lines[num].y, text, SSD_COLOR_WHITE );
ESP_LOGD(TAG, "displaying %s line %u (x:%d, attr:%u)", text, num+1, x, attribute);
// update whole display if requested
if (attribute & DISPLAY_UPDATE) SSD1306_Update( &Display );
if (attribute & DISPLAY_UPDATE) SSD13x6_Update( &Display );
return width + x < Display.Width;
}
@@ -225,8 +244,8 @@ static int stretch(int num, char *string, int max) {
num--;
// we might already fit
SSD1306_SetFont( &Display, lines[num].font );
if (SSD1306_FontMeasureString( &Display, string ) <= Display.Width) return 0;
SSD13x6_SetFont( &Display, lines[num].font );
if (SSD13x6_FontMeasureString( &Display, string ) <= Display.Width) return 0;
// add some space for better visual
strncat(string, space, max-len);
@@ -234,10 +253,10 @@ static int stretch(int num, char *string, int max) {
len = strlen(string);
// mark the end of the extended string
boundary = SSD1306_FontMeasureString( &Display, string );
boundary = SSD13x6_FontMeasureString( &Display, string );
// add a full display width
while (len < max && SSD1306_FontMeasureString( &Display, string ) - boundary < Display.Width) {
while (len < max && SSD13x6_FontMeasureString( &Display, string ) - boundary < Display.Width) {
string[len++] = string[extra++];
string[len] = '\0';
}
@@ -254,31 +273,31 @@ static void text(enum display_font_e font, enum display_pos_e pos, int attribute
va_start(args, text);
TextAnchor Anchor = TextAnchor_Center;
if (attribute & DISPLAY_CLEAR) SSD1306_Clear( &Display, SSD_COLOR_BLACK );
if (attribute & DISPLAY_CLEAR) SSD13x6_Clear( &Display, SSD_COLOR_BLACK );
if (!text) return;
switch(font) {
case DISPLAY_FONT_LINE_1:
SSD1306_SetFont( &Display, &Font_line_1 );
SSD13x6_SetFont( &Display, &Font_line_1 );
break;
case DISPLAY_FONT_LINE_2:
SSD1306_SetFont( &Display, &Font_line_2 );
SSD13x6_SetFont( &Display, &Font_line_2 );
break;
case DISPLAY_FONT_SMALL:
SSD1306_SetFont( &Display, &Font_droid_sans_fallback_11x13 );
SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_11x13 );
break;
case DISPLAY_FONT_MEDIUM:
case DISPLAY_FONT_DEFAULT:
default:
SSD1306_SetFont( &Display, &Font_droid_sans_fallback_15x17 );
SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_15x17 );
break;
case DISPLAY_FONT_LARGE:
SSD1306_SetFont( &Display, &Font_droid_sans_fallback_24x28 );
SSD13x6_SetFont( &Display, &Font_droid_sans_fallback_24x28 );
break;
case DISPLAY_FONT_SEGMENT:
if (Display.Height == 32) SSD1306_SetFont( &Display, &Font_Tarable7Seg_16x32 );
else SSD1306_SetFont( &Display, &Font_Tarable7Seg_32x64 );
if (Display.Height == 32) SSD13x6_SetFont( &Display, &Font_Tarable7Seg_16x32 );
else SSD13x6_SetFont( &Display, &Font_Tarable7Seg_32x64 );
break;
}
@@ -298,15 +317,15 @@ static void text(enum display_font_e font, enum display_pos_e pos, int attribute
break;
}
ESP_LOGD(TAG, "SSDD1306 displaying %s at %u with attribute %u", text, Anchor, attribute);
ESP_LOGD(TAG, "SSDD13x6 displaying %s at %u with attribute %u", text, Anchor, attribute);
if (AddressMode != AddressMode_Horizontal) {
AddressMode = AddressMode_Horizontal;
SSD1306_SetDisplayAddressMode( &Display, AddressMode );
SSD13x6_SetDisplayAddressMode( &Display, AddressMode );
}
SSD1306_FontDrawAnchoredString( &Display, Anchor, text, SSD_COLOR_WHITE );
if (attribute & DISPLAY_UPDATE) SSD1306_Update( &Display );
SSD13x6_FontDrawAnchoredString( &Display, Anchor, text, SSD_COLOR_WHITE );
if (attribute & DISPLAY_UPDATE) SSD13x6_Update( &Display );
va_end(args);
}
@@ -319,7 +338,7 @@ static void draw_cbr(u8_t *data, int height) {
// force addressing mode by rows
if (AddressMode != AddressMode_Horizontal) {
AddressMode = AddressMode_Horizontal;
SSD1306_SetDisplayAddressMode( &Display, AddressMode );
SSD13x6_SetDisplayAddressMode( &Display, AddressMode );
}
// try to minimize I2C traffic which is very slow
@@ -341,9 +360,9 @@ static void draw_cbr(u8_t *data, int height) {
// now update the display by "byte rows"
if (first--) {
SSD1306_SetColumnAddress( &Display, first, last );
SSD1306_SetPageAddress( &Display, r, r);
SSD1306_WriteRawData( &Display, Display.Framebuffer + r*Display.Width + first, last - first + 1);
SSD13x6_SetColumnAddress( &Display, first, last );
SSD13x6_SetPageAddress( &Display, r, r);
SSD13x6_WriteRawData( &Display, Display.Framebuffer + r*Display.Width + first, last - first + 1);
}
}
#else
@@ -354,15 +373,15 @@ static void draw_cbr(u8_t *data, int height) {
for (int r = 0; r < height / 8; r++)
Display.Framebuffer[c*Display.Height/8 + r] = BitReverseTable256[data[c*height/8 +r]];
SSD1306_SetPageAddress( &Display, 0, height / 8 - 1);
SSD13x6_SetPageAddress( &Display, 0, height / 8 - 1);
// force addressing mode by columns
if (AddressMode != AddressMode_Vertical) {
AddressMode = AddressMode_Vertical;
SSD1306_SetDisplayAddressMode( &Display, AddressMode );
SSD13x6_SetDisplayAddressMode( &Display, AddressMode );
}
SSD1306_WriteRawData(&Display, Display.Framebuffer, Display.Width * Display.Height/8);
SSD13x6_WriteRawData(&Display, Display.Framebuffer, Display.Width * Display.Height/8);
#endif
}
@@ -386,7 +405,7 @@ static void draw(int x1, int y1, int x2, int y2, bool by_column, u8_t *data) {
if (AddressMode != AddressMode_Vertical) {
AddressMode = AddressMode_Vertical;
SSD1306_SetDisplayAddressMode( &Display, AddressMode );
SSD13x6_SetDisplayAddressMode( &Display, AddressMode );
}
// copy the window and do row/col exchange
@@ -405,32 +424,32 @@ static void draw(int x1, int y1, int x2, int y2, bool by_column, u8_t *data) {
}
}
SSD1306_SetColumnAddress( &Display, x1, x2);
SSD1306_SetPageAddress( &Display, y1/8, y2/8);
SSD1306_WriteRawData( &Display, data, (x2-x1 + 1) * ((y2-y1)/8 + 1));
SSD13x6_SetColumnAddress( &Display, x1, x2);
SSD13x6_SetPageAddress( &Display, y1/8, y2/8);
SSD13x6_WriteRawData( &Display, data, (x2-x1 + 1) * ((y2-y1)/8 + 1));
}
/****************************************************************************************
* Brightness
*/
static void brightness(u8_t level) {
SSD1306_DisplayOn( &Display );
SSD1306_SetContrast( &Display, (uint8_t) level);
SSD13x6_DisplayOn( &Display );
SSD13x6_SetContrast( &Display, (uint8_t) level);
}
/****************************************************************************************
* Display On/Off
*/
static void on(bool state) {
if (state) SSD1306_DisplayOn( &Display );
else SSD1306_DisplayOff( &Display );
if (state) SSD13x6_DisplayOn( &Display );
else SSD13x6_DisplayOff( &Display );
}
/****************************************************************************************
* Update
*/
static void update(void) {
SSD1306_Update( &Display );
SSD13x6_Update( &Display );
}

View File

@@ -21,16 +21,18 @@
#pragma once
#define I2C_SYSTEM_PORT 1
#define SPI_SYSTEM_HOST SPI2_HOST
extern int i2c_system_port;
extern int spi_system_host;
extern int spi_system_dc_gpio;
extern bool gpio36_39_used;
#ifdef CONFIG_SQUEEZEAMP
#define JACK_GPIO 34
#define SPKFAULT_GPIO 2 // this requires a pull-up, so can't be >34
#define LED_GREEN_GPIO 12
#define LED_RED_GPIO 13
#else
#define LED_GREEN_GPIO CONFIG_LED_GREEN_GPIO
#define LED_RED_GPIO CONFIG_LED_RED_GPIO
#define JACK_GPIO CONFIG_JACK_GPIO
#define SPKFAULT_GPIO 2 // this requires a pull-up, so can't be >34
#define ADAC dac_tas57xx
#elif defined(CONFIG_A1S)
#define ADAC dac_a1s
#else
#define ADAC dac_external
#endif

View File

@@ -26,11 +26,7 @@
static const char *TAG = "monitor";
static TimerHandle_t monitor_timer;
#ifdef JACK_GPIO
static int jack_gpio = JACK_GPIO;
#else
static int jack_gpio = -1;
#endif
void (*jack_handler_svc)(bool inserted);
bool jack_inserted_svc(void);
@@ -68,12 +64,14 @@ bool jack_inserted_svc (void) {
/****************************************************************************************
*
*/
#ifdef SPKFAULT_GPIO
static void spkfault_handler_default(void *id, button_event_e event, button_press_e mode, bool long_press) {
ESP_LOGD(TAG, "Speaker status %s", event == BUTTON_PRESSED ? "faulty" : "normal");
if (event == BUTTON_PRESSED) led_on(LED_RED);
else led_off(LED_RED);
if (spkfault_handler_svc) (*spkfault_handler_svc)(event == BUTTON_PRESSED);
}
#endif
/****************************************************************************************
*
@@ -117,16 +115,17 @@ void set_jack_gpio(int gpio, char *value) {
void monitor_svc_init(void) {
ESP_LOGI(TAG, "Initializing monitoring");
// if JACK_GPIO is compiled-time defined set it there
if (jack_gpio != -1) {
#if JACK_GPIO_LEVEL == 1
set_jack_gpio(JACK_GPIO, "jack_h");
#ifdef CONFIG_JACK_GPIO
jack_gpio = CONFIG_JACK_GPIO;
#if CONFIG_JACK_GPIO_LEVEL == 1
set_jack_gpio(CONFIG_JACK_GPIO, "jack_h");
#else
set_jack_gpio(JACK_GPIO, "jack_l");
set_jack_gpio(CONFIG_JACK_GPIO, "jack_l");
#endif
} else {
parse_set_GPIO(set_jack_gpio);
}
#endif
#ifndef CONFIG_JACK_LOCKED
parse_set_GPIO(set_jack_gpio);
#endif
#ifdef SPKFAULT_GPIO
gpio_pad_select_gpio(SPKFAULT_GPIO);

View File

@@ -22,6 +22,8 @@ extern void monitor_svc_init(void);
extern void led_svc_init(void);
int i2c_system_port = I2C_SYSTEM_PORT;
int spi_system_host = SPI_SYSTEM_HOST;
int spi_system_dc_gpio = -1;
static const char *TAG = "services";
@@ -48,22 +50,20 @@ void set_power_gpio(int gpio, char *value) {
*
*/
void services_init(void) {
char *nvs_item;
gpio_install_isr_service(0);
#ifdef CONFIG_SQUEEZEAMP
#ifdef CONFIG_I2C_LOCKED
if (i2c_system_port == 0) {
i2c_system_port = 1;
ESP_LOGE(TAG, "can't use i2c port 0 on SqueezeAMP");
ESP_LOGE(TAG, "Port 0 is reserved for internal DAC use");
}
#endif
// set potential power GPIO
parse_set_GPIO(set_power_gpio);
// shared I2C bus
const i2c_config_t * i2c_config = config_i2c_get(&i2c_system_port);
ESP_LOGI(TAG,"Configuring I2C sda:%d scl:%d port:%u speed:%u", i2c_config->sda_io_num, i2c_config->scl_io_num, i2c_system_port, i2c_config->master.clk_speed);
if (i2c_config->sda_io_num != -1 && i2c_config->scl_io_num != -1) {
@@ -72,11 +72,26 @@ void services_init(void) {
} else {
ESP_LOGW(TAG, "no I2C configured");
}
const spi_bus_config_t * spi_config = config_spi_get((spi_host_device_t*) &spi_system_host);
ESP_LOGI(TAG,"Configuring SPI data:%d clk:%d host:%u d/c:%d", spi_config->mosi_io_num, spi_config->sclk_io_num, spi_system_host, spi_system_dc_gpio);
if (spi_config->mosi_io_num != -1 && spi_config->sclk_io_num != -1) {
spi_bus_initialize( spi_system_host, spi_config, 1 );
if (spi_system_dc_gpio != 1) {
gpio_set_direction( spi_system_dc_gpio, GPIO_MODE_OUTPUT );
gpio_set_level( spi_system_dc_gpio, 0 );
} else {
ESP_LOGW(TAG, "No D/C GPIO set, SPI display will not work");
}
} else {
ESP_LOGW(TAG, "no SPI configured");
}
ESP_LOGD(TAG,"Configuring LEDs");
ESP_LOGD(TAG,"Configuring LEDs green:%d red:%d", CONFIG_LED_GREEN_GPIO, CONFIG_LED_RED_GPIO);
led_svc_init();
led_config(LED_GREEN, LED_GREEN_GPIO, 0);
led_config(LED_RED, LED_RED_GPIO, 0);
led_config(LED_GREEN, CONFIG_LED_GREEN_GPIO, 0);
led_config(LED_RED, CONFIG_LED_RED_GPIO, 0);
battery_svc_init();
monitor_svc_init();

View File

@@ -1,139 +0,0 @@
/**
* Copyright (c) 2017-2018 Tara Keeling
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <driver/spi_master.h>
#include <driver/gpio.h>
#include <freertos/task.h>
#include "ssd1306.h"
#include "ssd1306_default_if.h"
/*
* HACKHACKHACK:
* Conditional compiling in component.mk does not seem to be working.
* This workaround looks ugly, but should work.
*/
#if defined CONFIG_SSD1306_ENABLE_DEFAULT_SPI_INTERFACE
static const spi_host_device_t SPIHost = ( spi_host_device_t ) CONFIG_SSD1306_DEFAULT_SPI_HOST;
static const int SPIFrequency = CONFIG_SSD1306_DEFAULT_SPI_FREQUENCY;
static const int MOSIPin = CONFIG_SSD1306_DEFAULT_SPI_MOSI_PIN;
static const int SCLKPin = CONFIG_SSD1306_DEFAULT_SPI_SCLK_PIN;
static const int DCPin = CONFIG_SSD1306_DEFAULT_SPI_DC_PIN;
static const int SSD1306_SPI_Command_Mode = 0;
static const int SSD1306_SPI_Data_Mode = 1;
static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength );
static bool SPIDefaultWriteCommand( struct SSD1306_Device* DeviceHandle, SSDCmd Command );
static bool SPIDefaultWriteData( struct SSD1306_Device* DeviceHandle, const uint8_t* Data, size_t DataLength );
static bool SPIDefaultReset( struct SSD1306_Device* DeviceHandle );
bool SSD1306_SPIMasterInitDefault( void ) {
spi_bus_config_t BusConfig = {
.sclk_io_num = SCLKPin,
.mosi_io_num = MOSIPin,
.miso_io_num = -1,
.quadwp_io_num = -1,
.quadhd_io_num = -1
};
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( DCPin, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DCPin, 0 ), return false );
ESP_ERROR_CHECK_NONFATAL( spi_bus_initialize( SPIHost, &BusConfig, 1 ), return false );
return true;
}
bool SSD1306_SPIMasterAttachDisplayDefault( struct SSD1306_Device* DeviceHandle, int Width, int Height, int CSForThisDisplay, int RSTForThisDisplay ) {
spi_device_interface_config_t SPIDeviceConfig;
spi_device_handle_t SPIDeviceHandle;
NullCheck( DeviceHandle, return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( CSForThisDisplay, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( CSForThisDisplay, 0 ), return false );
memset( &SPIDeviceConfig, 0, sizeof( spi_device_interface_config_t ) );
SPIDeviceConfig.clock_speed_hz = SPIFrequency;
SPIDeviceConfig.spics_io_num = CSForThisDisplay;
SPIDeviceConfig.queue_size = 1;
if ( RSTForThisDisplay >= 0 ) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTForThisDisplay, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTForThisDisplay, 0 ), return false );
}
ESP_ERROR_CHECK_NONFATAL( spi_bus_add_device( SPIHost, &SPIDeviceConfig, &SPIDeviceHandle ), return false );
return SSD1306_Init_SPI( DeviceHandle,
Width,
Height,
RSTForThisDisplay,
CSForThisDisplay,
SPIDeviceHandle,
SPIDefaultWriteCommand,
SPIDefaultWriteData,
SPIDefaultReset
);
}
static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength ) {
spi_transaction_t SPITransaction;
NullCheck( SPIHandle, return false );
NullCheck( Data, return false );
if ( DataLength > 0 ) {
memset( &SPITransaction, 0, sizeof( spi_transaction_t ) );
SPITransaction.length = DataLength * 8;
SPITransaction.tx_buffer = Data;
gpio_set_level( DCPin, WriteMode );
ESP_ERROR_CHECK_NONFATAL( spi_device_transmit( SPIHandle, &SPITransaction ), return false );
}
return true;
}
static bool SPIDefaultWriteCommand( struct SSD1306_Device* DeviceHandle, SSDCmd Command ) {
static uint8_t CommandByte = 0;
NullCheck( DeviceHandle, return false );
NullCheck( DeviceHandle->SPIHandle, return false );
CommandByte = Command;
return SPIDefaultWriteBytes( DeviceHandle->SPIHandle, SSD1306_SPI_Command_Mode, &CommandByte, 1 );
}
static bool SPIDefaultWriteData( struct SSD1306_Device* DeviceHandle, const uint8_t* Data, size_t DataLength ) {
NullCheck( DeviceHandle, return false );
NullCheck( DeviceHandle->SPIHandle, return false );
return SPIDefaultWriteBytes( DeviceHandle->SPIHandle, SSD1306_SPI_Data_Mode, Data, DataLength );
}
static bool SPIDefaultReset( struct SSD1306_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return false );
if ( DeviceHandle->RSTPin >= 0 ) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DeviceHandle->RSTPin, 0 ), return false );
vTaskDelay( pdMS_TO_TICKS( 100 ) );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DeviceHandle->RSTPin, 1 ), return false );
}
return true;
}
#endif

View File

@@ -1,272 +0,0 @@
/**
* Copyright (c) 2017-2018 Tara Keeling
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <math.h>
#include <esp_heap_caps.h>
#include "ssd1306.h"
#define COM_Disable_LR_Remap 0
#define COM_Enable_LR_Remap BIT( 5 )
#define COM_Pins_Sequential 0
#define COM_Pins_Alternative BIT( 4 )
#define COM_ScanDir_LR 0
#define COM_ScanDir_RL 1
static bool SSD1306_Init( struct SSD1306_Device* DeviceHandle, int Width, int Height );
bool SSD1306_WriteCommand( struct SSD1306_Device* DeviceHandle, SSDCmd SSDCommand ) {
NullCheck( DeviceHandle, return false );
NullCheck( DeviceHandle->WriteCommand, return false );
return ( DeviceHandle->WriteCommand ) ( DeviceHandle, SSDCommand );
}
bool SSD1306_WriteData( struct SSD1306_Device* DeviceHandle, uint8_t* Data, size_t DataLength ) {
NullCheck( DeviceHandle, return false );
NullCheck( DeviceHandle->WriteData, return false );
return ( DeviceHandle->WriteData ) ( DeviceHandle, Data, DataLength );
}
void SSD1306_SetMuxRatio( struct SSD1306_Device* DeviceHandle, uint8_t Ratio ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, 0xA8 );
SSD1306_WriteCommand( DeviceHandle, Ratio );
}
void SSD1306_SetDisplayOffset( struct SSD1306_Device* DeviceHandle, uint8_t Offset ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, 0xD3 );
SSD1306_WriteCommand( DeviceHandle, Offset );
}
void SSD1306_SetDisplayStartLine( struct SSD1306_Device* DeviceHandle, int Line ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle,
SSDCmd_Set_Display_Start_Line + ( uint32_t ) ( Line & 0x1F )
);
}
/*
* This is all a big giant mystery that I have yet to figure out.
* Beware all ye who enter.
*/
static void SetCOMPinConfiguration( struct SSD1306_Device* DeviceHandle, uint32_t RemapCFG, uint32_t PinCFG, int ScanDir ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_COM_Pin_Config );
SSD1306_WriteCommand( DeviceHandle, ( uint8_t ) ( RemapCFG | PinCFG | BIT( 1 ) ) );
SSD1306_WriteCommand( DeviceHandle,
( ScanDir == COM_ScanDir_LR ) ? SSDCmd_Set_Display_VFlip_Off : SSDCmd_Set_Display_VFlip_On
);
}
void SSD1306_SetContrast( struct SSD1306_Device* DeviceHandle, uint8_t Contrast ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_Contrast );
SSD1306_WriteCommand( DeviceHandle, Contrast );
}
void SSD1306_EnableDisplayRAM( struct SSD1306_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_Display_Show_RAM );
}
void SSD1306_DisableDisplayRAM( struct SSD1306_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_Display_Ignore_RAM );
}
void SSD1306_SetInverted( struct SSD1306_Device* DeviceHandle, bool Inverted ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, ( Inverted == true ) ? SSDCmd_Set_Inverted_Display : SSDCmd_Set_Normal_Display );
}
void SSD1306_SetDisplayClocks( struct SSD1306_Device* DeviceHandle, uint32_t DisplayClockDivider, uint32_t OSCFrequency ) {
NullCheck( DeviceHandle, return );
DisplayClockDivider&= 0x0F;
OSCFrequency&= 0x0F;
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_Display_CLK );
SSD1306_WriteCommand( DeviceHandle, ( ( OSCFrequency << 4 ) | DisplayClockDivider ) );
}
/* There is no documentation for this command, but it is required during init. */
static void EnableChargePumpRegulator( struct SSD1306_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Enable_Charge_Pump_Regulator );
SSD1306_WriteCommand( DeviceHandle, 0x14 ); /* MAGIC NUMBER */
}
void SSD1306_DisplayOn( struct SSD1306_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_Display_On );
}
void SSD1306_DisplayOff( struct SSD1306_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_Display_Off );
}
void SSD1306_SetDisplayAddressMode( struct SSD1306_Device* DeviceHandle, SSD1306_AddressMode AddressMode ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_Memory_Addressing_Mode );
SSD1306_WriteCommand( DeviceHandle, AddressMode );
}
void SSD1306_Update( struct SSD1306_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return );
SSD1306_SetColumnAddress( DeviceHandle, 0, DeviceHandle->Width - 1);
SSD1306_SetPageAddress( DeviceHandle, 0, DeviceHandle->Height / 8 - 1);
SSD1306_WriteData( DeviceHandle, DeviceHandle->Framebuffer, DeviceHandle->FramebufferSize );
}
void SSD1306_WriteRawData( struct SSD1306_Device* DeviceHandle, uint8_t* Data, size_t DataLength ) {
NullCheck( DeviceHandle, return );
NullCheck( Data, return );
DataLength = DataLength > DeviceHandle->FramebufferSize ? DeviceHandle->FramebufferSize : DataLength;
if ( DataLength > 0 ) {
SSD1306_WriteData( DeviceHandle, Data, DataLength );
}
}
void SSD1306_SetHFlip( struct SSD1306_Device* DeviceHandle, bool On ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, ( On == true ) ? SSDCmd_Set_Display_HFlip_On : SSDCmd_Set_Display_HFlip_Off );
}
void SSD1306_SetVFlip( struct SSD1306_Device* DeviceHandle, bool On ) {
NullCheck( DeviceHandle, return );
SSD1306_WriteCommand( DeviceHandle, ( On == true ) ? SSDCmd_Set_Display_VFlip_On : SSDCmd_Set_Display_VFlip_Off );
}
void SSD1306_SetColumnAddress( struct SSD1306_Device* DeviceHandle, uint8_t Start, uint8_t End ) {
NullCheck( DeviceHandle, return );
CheckBounds( Start > SSD1306_Max_Col, return );
CheckBounds( End > SSD1306_Max_Col, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_Column_Address );
SSD1306_WriteCommand( DeviceHandle, Start );
SSD1306_WriteCommand( DeviceHandle, End );
}
void SSD1306_SetPageAddress( struct SSD1306_Device* DeviceHandle, uint8_t Start, uint8_t End ) {
NullCheck( DeviceHandle, return );
CheckBounds( Start > SSD1306_Max_Row, return );
CheckBounds( End > SSD1306_Max_Row, return );
SSD1306_WriteCommand( DeviceHandle, SSDCmd_Set_Page_Address );
SSD1306_WriteCommand( DeviceHandle, Start );
SSD1306_WriteCommand( DeviceHandle, End );
}
bool SSD1306_HWReset( struct SSD1306_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return 0 );
if ( DeviceHandle->Reset != NULL ) {
return ( DeviceHandle->Reset ) ( DeviceHandle );
}
/* This should always return true if there is no reset callback as
* no error would have occurred during the non existant reset.
*/
return true;
}
static bool SSD1306_Init( struct SSD1306_Device* DeviceHandle, int Width, int Height ) {
DeviceHandle->Width = Width;
DeviceHandle->Height = Height;
DeviceHandle->FramebufferSize = ( DeviceHandle->Width * Height ) / 8;
// DeviceHandle->Framebuffer = heap_caps_calloc( 1, DeviceHandle->FramebufferSize, MALLOC_CAP_INTERNAL );
DeviceHandle->Framebuffer = calloc( 1, DeviceHandle->FramebufferSize );
NullCheck( DeviceHandle->Framebuffer, return false );
/* For those who have a hardware reset pin on their display */
SSD1306_HWReset( DeviceHandle );
/* Init sequence according to SSD1306.pdf */
SSD1306_SetMuxRatio( DeviceHandle, Height - 1 );
SSD1306_SetDisplayOffset( DeviceHandle, 0x00 );
SSD1306_SetDisplayStartLine( DeviceHandle, 0 );
SSD1306_SetHFlip( DeviceHandle, false );
SSD1306_SetVFlip( DeviceHandle, false );
if ( Height == 64 ) {
SetCOMPinConfiguration( DeviceHandle, COM_Disable_LR_Remap, COM_Pins_Alternative, COM_ScanDir_LR );
} else {
SetCOMPinConfiguration( DeviceHandle, COM_Disable_LR_Remap, COM_Pins_Sequential, COM_ScanDir_LR );
}
SSD1306_SetContrast( DeviceHandle, 0x7F );
SSD1306_DisableDisplayRAM( DeviceHandle );
SSD1306_SetInverted( DeviceHandle, false );
SSD1306_SetDisplayClocks( DeviceHandle, 0, 8 );
EnableChargePumpRegulator( DeviceHandle );
SSD1306_SetDisplayAddressMode( DeviceHandle, AddressMode_Vertical );
SSD1306_SetColumnAddress( DeviceHandle, 0, DeviceHandle->Width - 1 );
SSD1306_SetPageAddress( DeviceHandle, 0, ( DeviceHandle->Height / 8 ) - 1 );
SSD1306_EnableDisplayRAM( DeviceHandle );
SSD1306_DisplayOn( DeviceHandle );
SSD1306_Update( DeviceHandle );
return true;
}
bool SSD1306_Init_I2C( struct SSD1306_Device* DeviceHandle, int Width, int Height, int I2CAddress, int ResetPin, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset ) {
NullCheck( DeviceHandle, return false );
NullCheck( WriteCommand, return false );
NullCheck( WriteData, return false );
memset( DeviceHandle, 0, sizeof( struct SSD1306_Device ) );
DeviceHandle->WriteCommand = WriteCommand;
DeviceHandle->WriteData = WriteData;
DeviceHandle->Reset = Reset;
DeviceHandle->Address = I2CAddress;
DeviceHandle->RSTPin = ResetPin;
return SSD1306_Init( DeviceHandle, Width, Height );
}
bool SSD1306_Init_SPI( struct SSD1306_Device* DeviceHandle, int Width, int Height, int ResetPin, int CSPin, spi_device_handle_t SPIHandle, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset ) {
NullCheck( DeviceHandle, return false );
NullCheck( WriteCommand, return false );
NullCheck( WriteData, return false );
memset( DeviceHandle, 0, sizeof( struct SSD1306_Device ) );
DeviceHandle->WriteCommand = WriteCommand;
DeviceHandle->WriteData = WriteData;
DeviceHandle->Reset = Reset;
DeviceHandle->SPIHandle = SPIHandle;
DeviceHandle->RSTPin = ResetPin;
DeviceHandle->CSPin = CSPin;
return SSD1306_Init( DeviceHandle, Width, Height );
}

View File

@@ -1,117 +0,0 @@
#ifndef _SSD1306_H_
#define _SSD1306_H_
/* For uint(X)_t */
#include <stdint.h>
/* For booooool */
#include <stdbool.h>
#include "sdkconfig.h"
#include "ssd1306_err.h"
#define SSD_ALWAYS_INLINE __attribute__( ( always_inline ) )
#define SSD1306_Max_Col 127
#define SSD1306_Max_Row 7
#if ! defined BIT
#define BIT( n ) ( 1 << n )
#endif
typedef enum {
SSDCmd_Set_Contrast = 0x81,
SSDCmd_Set_Display_Show_RAM = 0xA4,
SSDCmd_Set_Display_Ignore_RAM = 0xA5,
SSDCmd_Set_Normal_Display = 0xA6,
SSDCmd_Set_Inverted_Display = 0xA7,
SSDCmd_Set_Display_Off = 0xAE,
SSDCmd_Set_Display_On = 0xAF,
SSDCmd_Set_Memory_Addressing_Mode = 0x20,
SSDCmd_Set_Mux_Ratio = 0xA8,
SSDCmd_Nop = 0xE3,
SSDCmd_Set_Display_Offset = 0xD3,
SSDCmd_Set_Display_Start_Line = 0x40,
SSDCmd_Set_Display_HFlip_Off = 0xA0,
SSDCmd_Set_Display_HFlip_On = 0xA1,
SSDCmd_Set_Display_VFlip_Off = 0xC0,
SSDCmd_Set_Display_VFlip_On = 0xC8,
SSDCmd_Set_COM_Pin_Config = 0xDA,
SSDCmd_Set_Display_CLK = 0xD5,
SSDCmd_Enable_Charge_Pump_Regulator = 0x8D,
SSDCmd_Set_Column_Address = 0x21,
SSDCmd_Set_Page_Address = 0x22
} SSDCmd;
typedef enum {
AddressMode_Horizontal = 0,
AddressMode_Vertical,
AddressMode_Page,
AddressMode_Invalid
} SSD1306_AddressMode;
struct SSD1306_Device;
/*
* These can optionally return a succeed/fail but are as of yet unused in the driver.
*/
typedef bool ( *WriteCommandProc ) ( struct SSD1306_Device* DeviceHandle, SSDCmd Command );
typedef bool ( *WriteDataProc ) ( struct SSD1306_Device* DeviceHandle, const uint8_t* Data, size_t DataLength );
typedef bool ( *ResetProc ) ( struct SSD1306_Device* DeviceHandle );
struct spi_device_t;
typedef struct spi_device_t* spi_device_handle_t;
struct SSD1306_FontDef;
struct SSD1306_Device {
/* I2C Specific */
int Address;
/* SPI Specific */
spi_device_handle_t SPIHandle;
int RSTPin;
int CSPin;
/* Everything else */
int Width;
int Height;
uint8_t* Framebuffer;
int FramebufferSize;
WriteCommandProc WriteCommand;
WriteDataProc WriteData;
ResetProc Reset;
const struct SSD1306_FontDef* Font;
bool FontForceProportional;
bool FontForceMonospace;
};
void SSD1306_SetMuxRatio( struct SSD1306_Device* DeviceHandle, uint8_t Ratio );
void SSD1306_SetDisplayOffset( struct SSD1306_Device* DeviceHandle, uint8_t Offset );
void SSD1306_SetDisplayStartLines( struct SSD1306_Device* DeviceHandle );
void SSD1306_SetSegmentRemap( struct SSD1306_Device* DeviceHandle, bool Remap );
void SSD1306_SetContrast( struct SSD1306_Device* DeviceHandle, uint8_t Contrast );
void SSD1306_EnableDisplayRAM( struct SSD1306_Device* DeviceHandle );
void SSD1306_DisableDisplayRAM( struct SSD1306_Device* DeviceHandle );
void SSD1306_SetInverted( struct SSD1306_Device* DeviceHandle, bool Inverted );
void SSD1306_SetHFlip( struct SSD1306_Device* DeviceHandle, bool On );
void SSD1306_SetVFlip( struct SSD1306_Device* DeviceHandle, bool On );
void SSD1306_DisplayOn( struct SSD1306_Device* DeviceHandle );
void SSD1306_DisplayOff( struct SSD1306_Device* DeviceHandle );
void SSD1306_SetDisplayAddressMode( struct SSD1306_Device* DeviceHandle, SSD1306_AddressMode AddressMode );
void SSD1306_Update( struct SSD1306_Device* DeviceHandle );
void SSD1306_SetDisplayClocks( struct SSD1306_Device* DeviceHandle, uint32_t DisplayClockDivider, uint32_t OSCFrequency );
void SSD1306_WriteRawData( struct SSD1306_Device* DeviceHandle, uint8_t* Data, size_t DataLength );
void SSD1306_SetColumnAddress( struct SSD1306_Device* DeviceHandle, uint8_t Start, uint8_t End );
void SSD1306_SetPageAddress( struct SSD1306_Device* DeviceHandle, uint8_t Start, uint8_t End );
bool SSD1306_HWReset( struct SSD1306_Device* DeviceHandle );
bool SSD1306_Init_I2C( struct SSD1306_Device* DeviceHandle, int Width, int Height, int I2CAddress, int ResetPin, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset );
bool SSD1306_Init_SPI( struct SSD1306_Device* DeviceHandle, int Width, int Height, int ResetPin, int CSPin, spi_device_handle_t SPIHandle, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset );
#endif

View File

@@ -1,36 +0,0 @@
#ifndef _SSD1306_DEFAULT_IF_H_
#define _SSD1306_DEFAULT_IF_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Initializes the i2c master
*
* Returns true on successful init of the i2c bus.
*/
bool SSD1306_I2CMasterInitDefault( int PortNumber, int SDA, int SCL );
/*
* Attaches a display to the I2C bus using default communication functions.
*
* Params:
* DisplayHandle: Pointer to your SSD1306_Device object
* Width: Width of display
* Height: Height of display
* I2CAddress: Address of your display
* RSTPin: Optional GPIO pin to use for hardware reset, if none pass -1 for this parameter.
*
* Returns true on successful init of display.
*/
bool SSD1306_I2CMasterAttachDisplayDefault( struct SSD1306_Device* DisplayHandle, int Width, int Height, int I2CAddress, int RSTPin );
bool SSD1306_SPIMasterInitDefault( void );
bool SSD1306_SPIMasterAttachDisplayDefault( struct SSD1306_Device* DeviceHandle, int Width, int Height, int CSForThisDisplay, int RSTForThisDisplay );
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,91 +0,0 @@
#ifndef _SSD1306_FONT_H_
#define _SSD1306_FONT_H_
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
struct SSD1306_Device;
/*
* X-GLCD Font format:
*
* First byte of glyph is it's width in pixels.
* Each data byte represents 8 pixels going down from top to bottom.
*
* Example glyph layout for a 16x16 font
* 'a': [Glyph width][Pixel column 0][Pixel column 1] where the number of pixel columns is the font height divided by 8
* 'b': [Glyph width][Pixel column 0][Pixel column 1]...
* 'c': And so on...
*/
struct SSD1306_FontDef {
const uint8_t* FontData;
int Width;
int Height;
int StartChar;
int EndChar;
bool Monospace;
};
typedef enum {
TextAnchor_East = 0,
TextAnchor_West,
TextAnchor_North,
TextAnchor_South,
TextAnchor_NorthEast,
TextAnchor_NorthWest,
TextAnchor_SouthEast,
TextAnchor_SouthWest,
TextAnchor_Center
} TextAnchor;
bool SSD1306_SetFont( struct SSD1306_Device* Display, const struct SSD1306_FontDef* Font );
void SSD1306_FontForceProportional( struct SSD1306_Device* Display, bool Force );
void SSD1306_FontForceMonospace( struct SSD1306_Device* Display, bool Force );
int SSD1306_FontGetWidth( struct SSD1306_Device* Display );
int SSD1306_FontGetHeight( struct SSD1306_Device* Display );
int SSD1306_FontGetMaxCharsPerRow( struct SSD1306_Device* Display );
int SSD1306_FontGetMaxCharsPerColumn( struct SSD1306_Device* Display );
int SSD1306_FontGetCharWidth( struct SSD1306_Device* Display, char Character );
int SSD1306_FontGetCharHeight( struct SSD1306_Device* Display );
int SSD1306_FontMeasureString( struct SSD1306_Device* Display, const char* Text );\
void SSD1306_FontDrawChar( struct SSD1306_Device* Display, char Character, int x, int y, int Color );
void SSD1306_FontDrawString( struct SSD1306_Device* Display, int x, int y, const char* Text, int Color );
void SSD1306_FontDrawAnchoredString( struct SSD1306_Device* Display, TextAnchor Anchor, const char* Text, int Color );
void SSD1306_FontGetAnchoredStringCoords( struct SSD1306_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text );
extern const struct SSD1306_FontDef Font_droid_sans_fallback_11x13;
extern const struct SSD1306_FontDef Font_droid_sans_fallback_15x17;
extern const struct SSD1306_FontDef Font_droid_sans_fallback_24x28;
extern const struct SSD1306_FontDef Font_droid_sans_mono_7x13;
extern const struct SSD1306_FontDef Font_droid_sans_mono_13x24;
extern const struct SSD1306_FontDef Font_droid_sans_mono_16x31;
extern const struct SSD1306_FontDef Font_liberation_mono_9x15;
extern const struct SSD1306_FontDef Font_liberation_mono_13x21;
extern const struct SSD1306_FontDef Font_liberation_mono_17x30;
extern const struct SSD1306_FontDef Font_Tarable7Seg_16x32;
extern const struct SSD1306_FontDef Font_Tarable7Seg_32x64;
extern const struct SSD1306_FontDef Font_line_1;
extern const struct SSD1306_FontDef Font_line_2;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Fallback11x13[ ] = {
0x05, 0x00, 0x10, 0xE4, 0x11, 0x00, 0x0E, 0x00, 0x02, 0xE4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_droid_sans_fallback_11x13 = {
const struct SSD13x6_FontDef Font_droid_sans_fallback_11x13 = {
Droid_Sans_Fallback11x13,
11,
13,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Fallback15x17[ ] = {
0x07, 0xC0, 0x00, 0x01, 0x00, 0x03, 0x01, 0x10, 0x8C, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_droid_sans_fallback_15x17 = {
const struct SSD13x6_FontDef Font_droid_sans_fallback_15x17 = {
Droid_Sans_Fallback15x17,
15,
17,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Fallback24x28[ ] = {
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x0C, 0xE0, 0xF0, 0x03, 0x0C, 0xE0, 0x80, 0x0F, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x7E, 0x00, 0xE0, 0x80, 0x0F, 0x00, 0xE0, 0xF0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_droid_sans_fallback_24x28 = {
const struct SSD13x6_FontDef Font_droid_sans_fallback_24x28 = {
Droid_Sans_Fallback24x28,
24,
28,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Mono13x24[ ] = {
0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x80, 0x07, 0xC0, 0x00, 0x1E, 0xC0, 0x18, 0xF8, 0xC0, 0x18, 0xC0, 0x7F, 0x00, 0x00, 0x1E, 0x00, 0xC0, 0x07, 0x18, 0xF8, 0x00, 0x18, 0x3E, 0x00, 0x80, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_droid_sans_mono_13x24 = {
const struct SSD13x6_FontDef Font_droid_sans_mono_13x24 = {
Droid_Sans_Mono13x24,
13,
24,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Mono16x31[ ] = {
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x00, 0x78, 0x00, 0x60, 0x00, 0xF8, 0x01, 0x60, 0x00, 0xE0, 0x07, 0x60, 0xE0, 0x00, 0x3F, 0x70, 0xE0, 0x00, 0xFC, 0x3C, 0x40, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x40, 0x00, 0xF8, 0x01, 0xE0, 0x00, 0x3F, 0x00, 0xE0, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_droid_sans_mono_16x31 = {
const struct SSD13x6_FontDef Font_droid_sans_mono_16x31 = {
Droid_Sans_Mono16x31,
16,
31,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Droid_Sans_Mono7x13[ ] = {
0x06, 0x00, 0x00, 0x30, 0x10, 0xC4, 0x10, 0x00, 0x0F, 0xC4, 0x01, 0x30, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_droid_sans_mono_7x13 = {
const struct SSD13x6_FontDef Font_droid_sans_mono_7x13 = {
Droid_Sans_Mono7x13,
7,
13,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Liberation_Mono13x21[ ] = {
0x0C, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x03, 0x10, 0x00, 0x0F, 0x10, 0x0C, 0x3C, 0x18, 0x00, 0xE0, 0x0D, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x0C, 0x3C, 0x00, 0x00, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_liberation_mono_13x21 = {
const struct SSD13x6_FontDef Font_liberation_mono_13x21 = {
Liberation_Mono13x21,
13,
21,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Liberation_Mono17x30[] = {
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x30, 0x00, 0x3F, 0x00, 0x30, 0x00, 0xFC, 0x01, 0x30, 0x38, 0xE0, 0x07, 0x38, 0x38, 0x00, 0x3F, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x01, 0x38, 0x00, 0x3F, 0x00, 0x38, 0xE0, 0x07, 0x00, 0x38, 0xFC, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_liberation_mono_17x30 = {
const struct SSD13x6_FontDef Font_liberation_mono_17x30 = {
Liberation_Mono17x30,
17,
30,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Liberation_Mono9x15[ ] = {
0x08, 0x00, 0x00, 0x30, 0x40, 0xC6, 0x41, 0x06, 0x67, 0x00, 0x18, 0x06, 0x07, 0xC6, 0x01, 0x30, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_liberation_mono_9x15 = {
const struct SSD13x6_FontDef Font_liberation_mono_9x15 = {
Liberation_Mono9x15,
9,
15,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -214,7 +214,7 @@ static const uint8_t Square721_BT11x14[] = {
0x06, 0x00, 0x00, 0xE8, 0x03, 0xB0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char è
};
const struct SSD1306_FontDef Font_line_1 = {
const struct SSD13x6_FontDef Font_line_1 = {
Square721_BT11x14,
11,
14,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -237,7 +237,7 @@ static const uint8_t Archivo_Narrow18x24[] = {
0x0A, 0x00, 0x01, 0x00, 0x00, 0x1F, 0xE0, 0x38, 0xFF, 0xE0, 0x38, 0xFC, 0xF7, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x3F, 0x38, 0xF0, 0x0F, 0x38, 0xFF, 0x01, 0x00, 0x1F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char ÿ
};
const struct SSD1306_FontDef Font_line_2 = {
const struct SSD13x6_FontDef Font_line_2 = {
Archivo_Narrow18x24,
18,
24,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -109,7 +109,7 @@ static const uint8_t Tarable7Seg_16x32[ ] = {
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char 
};
const struct SSD1306_FontDef Font_Tarable7Seg_16x32 = {
const struct SSD13x6_FontDef Font_Tarable7Seg_16x32 = {
Tarable7Seg_16x32,
16,
32,

View File

@@ -1,4 +1,4 @@
#include <ssd1306_font.h>
#include <ssd13x6_font.h>
//WARNING: This Font Require X-GLCD Lib.
// You can not use it with MikroE GLCD Lib.
@@ -109,7 +109,7 @@ static const uint8_t Tarable7Seg_32x64[ ] = {
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char 
};
const struct SSD1306_FontDef Font_Tarable7Seg_32x64 = {
const struct SSD13x6_FontDef Font_Tarable7Seg_32x64 = {
Tarable7Seg_32x64,
32,
64,

View File

@@ -11,19 +11,18 @@
#include <string.h>
#include <driver/i2c.h>
#include <driver/gpio.h>
#include "ssd1306.h"
#include "ssd1306_default_if.h"
#include "ssd13x6.h"
#include "ssd13x6_default_if.h"
static const int I2CDisplaySpeed = CONFIG_DISPLAY_I2C_SPEED;
static int I2CPortNumber;
static const int SSD1306_I2C_COMMAND_MODE = 0x80;
static const int SSD1306_I2C_DATA_MODE = 0x40;
static const int SSD13x6_I2C_COMMAND_MODE = 0x80;
static const int SSD13x6_I2C_DATA_MODE = 0x40;
static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength );
static bool I2CDefaultWriteCommand( struct SSD1306_Device* Display, SSDCmd Command );
static bool I2CDefaultWriteData( struct SSD1306_Device* Display, const uint8_t* Data, size_t DataLength );
static bool I2CDefaultReset( struct SSD1306_Device* Display );
static bool I2CDefaultWriteCommand( struct SSD13x6_Device* Display, SSDCmd Command );
static bool I2CDefaultWriteData( struct SSD13x6_Device* Display, const uint8_t* Data, size_t DataLength );
static bool I2CDefaultReset( struct SSD13x6_Device* Display );
/*
* Initializes the i2c master with the parameters specified
@@ -31,7 +30,7 @@ static bool I2CDefaultReset( struct SSD1306_Device* Display );
*
* Returns true on successful init of the i2c bus.
*/
bool SSD1306_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
bool SSD13x6_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
I2CPortNumber = PortNumber;
if (SDA != -1 && SCL != -1) {
@@ -42,7 +41,7 @@ bool SSD1306_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
Config.sda_pullup_en = GPIO_PULLUP_ENABLE;
Config.scl_io_num = SCL;
Config.scl_pullup_en = GPIO_PULLUP_ENABLE;
Config.master.clk_speed = I2CDisplaySpeed;
Config.master.clk_speed = 250000;
ESP_ERROR_CHECK_NONFATAL( i2c_param_config( I2CPortNumber, &Config ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_driver_install( I2CPortNumber, Config.mode, 0, 0, 0 ), return false );
@@ -55,7 +54,7 @@ bool SSD1306_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
* Attaches a display to the I2C bus using default communication functions.
*
* Params:
* DisplayHandle: Pointer to your SSD1306_Device object
* DisplayHandle: Pointer to your SSD13x6_Device object
* Width: Width of display
* Height: Height of display
* I2CAddress: Address of your display
@@ -63,15 +62,17 @@ bool SSD1306_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
*
* Returns true on successful init of display.
*/
bool SSD1306_I2CMasterAttachDisplayDefault( struct SSD1306_Device* DisplayHandle, int Width, int Height, int I2CAddress, int RSTPin ) {
NullCheck( DisplayHandle, return false );
bool SSD13x6_I2CMasterAttachDisplayDefault( struct SSD13x6_Device* DeviceHandle, int Model, int Width, int Height, int I2CAddress, int RSTPin ) {
NullCheck( DeviceHandle, return false );
if ( RSTPin >= 0 ) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTPin, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTPin, 1 ), return false );
}
return SSD1306_Init_I2C( DisplayHandle,
DeviceHandle->Model = Model;
return SSD13x6_Init_I2C( DeviceHandle,
Width,
Height,
I2CAddress,
@@ -89,36 +90,40 @@ static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Da
NullCheck( Data, return false );
if ( ( CommandHandle = i2c_cmd_link_create( ) ) != NULL ) {
ModeByte = ( IsCommand == true ) ? SSD1306_I2C_COMMAND_MODE: SSD1306_I2C_DATA_MODE;
ModeByte = ( IsCommand == true ) ? SSD13x6_I2C_COMMAND_MODE: SSD13x6_I2C_DATA_MODE;
ESP_ERROR_CHECK_NONFATAL( i2c_master_start( CommandHandle ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ( Address << 1 ) | I2C_MASTER_WRITE, true ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ModeByte, true ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_write( CommandHandle, ( uint8_t* ) Data, DataLength, true ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_stop( CommandHandle ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_start( CommandHandle ), goto error );
ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ( Address << 1 ) | I2C_MASTER_WRITE, true ), goto error );
ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ModeByte, true ), goto error );
ESP_ERROR_CHECK_NONFATAL( i2c_master_write( CommandHandle, ( uint8_t* ) Data, DataLength, true ), goto error );
ESP_ERROR_CHECK_NONFATAL( i2c_master_stop( CommandHandle ), goto error );
ESP_ERROR_CHECK_NONFATAL( i2c_master_cmd_begin( I2CPortNumber, CommandHandle, pdMS_TO_TICKS( 1000 ) ), return false );
ESP_ERROR_CHECK_NONFATAL( i2c_master_cmd_begin( I2CPortNumber, CommandHandle, pdMS_TO_TICKS( 1000 ) ), goto error );
i2c_cmd_link_delete( CommandHandle );
}
return true;
error:
if (CommandHandle) i2c_cmd_link_delete( CommandHandle );
return false;
}
static bool I2CDefaultWriteCommand( struct SSD1306_Device* Display, SSDCmd Command ) {
static bool I2CDefaultWriteCommand( struct SSD13x6_Device* Display, SSDCmd Command ) {
uint8_t CommandByte = ( uint8_t ) Command;
NullCheck( Display, return false );
return I2CDefaultWriteBytes( Display->Address, true, ( const uint8_t* ) &CommandByte, 1 );
}
static bool I2CDefaultWriteData( struct SSD1306_Device* Display, const uint8_t* Data, size_t DataLength ) {
static bool I2CDefaultWriteData( struct SSD13x6_Device* Display, const uint8_t* Data, size_t DataLength ) {
NullCheck( Display, return false );
NullCheck( Data, return false );
return I2CDefaultWriteBytes( Display->Address, false, Data, DataLength );
}
static bool I2CDefaultReset( struct SSD1306_Device* Display ) {
static bool I2CDefaultReset( struct SSD13x6_Device* Display ) {
NullCheck( Display, return false );
if ( Display->RSTPin >= 0 ) {

View File

@@ -0,0 +1,122 @@
/**
* Copyright (c) 2017-2018 Tara Keeling
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <driver/spi_master.h>
#include <driver/gpio.h>
#include <freertos/task.h>
#include "ssd13x6.h"
#include "ssd13x6_default_if.h"
static const int SSD13x6_SPI_Command_Mode = 0;
static const int SSD13x6_SPI_Data_Mode = 1;
static spi_host_device_t SPIHost;
static int DCPin;
static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength );
static bool SPIDefaultWriteCommand( struct SSD13x6_Device* DeviceHandle, SSDCmd Command );
static bool SPIDefaultWriteData( struct SSD13x6_Device* DeviceHandle, const uint8_t* Data, size_t DataLength );
static bool SPIDefaultReset( struct SSD13x6_Device* DeviceHandle );
bool SSD13x6_SPIMasterInitDefault( int SPI, int DC ) {
SPIHost = SPI;
DCPin = DC;
return true;
}
bool SSD13x6_SPIMasterAttachDisplayDefault( struct SSD13x6_Device* DeviceHandle, int Model, int Width, int Height, int CSPin, int RSTPin ) {
spi_device_interface_config_t SPIDeviceConfig;
spi_device_handle_t SPIDeviceHandle;
NullCheck( DeviceHandle, return false );
if (CSPin >= 0) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( CSPin, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( CSPin, 0 ), return false );
}
memset( &SPIDeviceConfig, 0, sizeof( spi_device_interface_config_t ) );
SPIDeviceConfig.clock_speed_hz = SPI_MASTER_FREQ_8M;
SPIDeviceConfig.spics_io_num = CSPin;
SPIDeviceConfig.queue_size = 1;
if ( RSTPin >= 0 ) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTPin, GPIO_MODE_OUTPUT ), return false );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTPin, 0 ), return false );
}
ESP_ERROR_CHECK_NONFATAL( spi_bus_add_device( SPIHost, &SPIDeviceConfig, &SPIDeviceHandle ), return false );
DeviceHandle->Model = Model;
return SSD13x6_Init_SPI( DeviceHandle,
Width,
Height,
RSTPin,
CSPin,
SPIDeviceHandle,
SPIDefaultWriteCommand,
SPIDefaultWriteData,
SPIDefaultReset
);
}
static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength ) {
spi_transaction_t SPITransaction;
NullCheck( SPIHandle, return false );
NullCheck( Data, return false );
if ( DataLength > 0 ) {
memset( &SPITransaction, 0, sizeof( spi_transaction_t ) );
SPITransaction.length = DataLength * 8;
SPITransaction.tx_buffer = Data;
gpio_set_level( DCPin, WriteMode );
ESP_ERROR_CHECK_NONFATAL( spi_device_transmit( SPIHandle, &SPITransaction ), return false );
}
return true;
}
static bool SPIDefaultWriteCommand( struct SSD13x6_Device* DeviceHandle, SSDCmd Command ) {
static uint8_t CommandByte = 0;
NullCheck( DeviceHandle, return false );
NullCheck( DeviceHandle->SPIHandle, return false );
CommandByte = Command;
return SPIDefaultWriteBytes( DeviceHandle->SPIHandle, SSD13x6_SPI_Command_Mode, &CommandByte, 1 );
}
static bool SPIDefaultWriteData( struct SSD13x6_Device* DeviceHandle, const uint8_t* Data, size_t DataLength ) {
NullCheck( DeviceHandle, return false );
NullCheck( DeviceHandle->SPIHandle, return false );
return SPIDefaultWriteBytes( DeviceHandle->SPIHandle, SSD13x6_SPI_Data_Mode, Data, DataLength );
}
static bool SPIDefaultReset( struct SSD13x6_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return false );
if ( DeviceHandle->RSTPin >= 0 ) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DeviceHandle->RSTPin, 0 ), return false );
vTaskDelay( pdMS_TO_TICKS( 100 ) );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DeviceHandle->RSTPin, 1 ), return false );
}
return true;
}

View File

@@ -0,0 +1,298 @@
/**
* Copyright (c) 2017-2018 Tara Keeling
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <math.h>
#include <esp_heap_caps.h>
#include "ssd13x6.h"
#define COM_Disable_LR_Remap 0
#define COM_Enable_LR_Remap BIT( 5 )
#define COM_Pins_Sequential 0
#define COM_Pins_Alternative BIT( 4 )
#define COM_ScanDir_LR 0
#define COM_ScanDir_RL 1
// used by both but different
static uint8_t SSDCmd_Set_Display_Start_Line;
static uint8_t SSDCmd_Set_Display_Offset;
static uint8_t SSDCmd_Set_Column_Address;
static uint8_t SSDCmd_Set_Display_CLK;
static uint8_t SSDCmd_Set_Page_Address;
// misc boundaries
static uint8_t SSD13x6_Max_Col;
static const uint8_t SSD13x6_Max_Row = 7;
static bool SSD13x6_Init( struct SSD13x6_Device* DeviceHandle, int Width, int Height );
bool SSD13x6_WriteCommand( struct SSD13x6_Device* DeviceHandle, SSDCmd SSDCommand ) {
NullCheck( DeviceHandle->WriteCommand, return false );
return ( DeviceHandle->WriteCommand ) ( DeviceHandle, SSDCommand );
}
bool SSD13x6_WriteData( struct SSD13x6_Device* DeviceHandle, uint8_t* Data, size_t DataLength ) {
NullCheck( DeviceHandle->WriteData, return false );
return ( DeviceHandle->WriteData ) ( DeviceHandle, Data, DataLength );
}
void SSD13x6_SetMuxRatio( struct SSD13x6_Device* DeviceHandle, uint8_t Ratio ) {
SSD13x6_WriteCommand( DeviceHandle, 0xA8 );
SSD13x6_WriteCommand( DeviceHandle, Ratio );
}
void SSD13x6_SetDisplayOffset( struct SSD13x6_Device* DeviceHandle, uint8_t Offset ) {
SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Display_Offset );
SSD13x6_WriteCommand( DeviceHandle, Offset );
}
void SSD13x6_SetDisplayStartLine( struct SSD13x6_Device* DeviceHandle, int Line ) {
SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Display_Start_Line + ( uint32_t ) ( Line & 0x1F ) );
}
void SSD13x6_SetContrast( struct SSD13x6_Device* DeviceHandle, uint8_t Contrast ) {
SSD13x6_WriteCommand( DeviceHandle, 0x81 );
SSD13x6_WriteCommand( DeviceHandle, Contrast );
}
void SSD13x6_EnableDisplayRAM( struct SSD13x6_Device* DeviceHandle ) {
SSD13x6_WriteCommand( DeviceHandle, 0xA4 );
}
void SSD13x6_DisableDisplayRAM( struct SSD13x6_Device* DeviceHandle ) {
SSD13x6_WriteCommand( DeviceHandle, 0xA5 );
}
void SSD13x6_SetInverted( struct SSD13x6_Device* DeviceHandle, bool Inverted ) {
SSD13x6_WriteCommand( DeviceHandle, Inverted ? 0xA7 : 0xA6 );
}
void SSD13x6_SetDisplayClocks( struct SSD13x6_Device* DeviceHandle, uint32_t DisplayClockDivider, uint32_t OSCFrequency ) {
DisplayClockDivider&= 0x0F;
OSCFrequency&= 0x0F;
SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Display_CLK );
SSD13x6_WriteCommand( DeviceHandle, ( ( OSCFrequency << 4 ) | DisplayClockDivider ) );
}
void SSD13x6_DisplayOn( struct SSD13x6_Device* DeviceHandle ) {
SSD13x6_WriteCommand( DeviceHandle, 0xAF );
}
void SSD13x6_DisplayOff( struct SSD13x6_Device* DeviceHandle ) {
SSD13x6_WriteCommand( DeviceHandle, 0xAE );
}
void SSD132x_ReMap( struct SSD13x6_Device* DeviceHandle ) {
SSD13x6_WriteCommand( DeviceHandle, 0xA0 );
SSD13x6_WriteCommand( DeviceHandle, DeviceHandle->ReMap );
}
void SSD13x6_SetDisplayAddressMode( struct SSD13x6_Device* DeviceHandle, SSD13x6_AddressMode AddressMode ) {
switch (DeviceHandle->Model) {
case SSD1306:
SSD13x6_WriteCommand( DeviceHandle, 0x20 );
SSD13x6_WriteCommand( DeviceHandle, AddressMode );
break;
case SSD1326:
DeviceHandle->ReMap = (AddressMode == AddressMode_Horizontal) ? (DeviceHandle->ReMap & ~0x80) : (DeviceHandle->ReMap | 0x80);
SSD132x_ReMap(DeviceHandle);
break;
}
}
void SSD13x6_Update( struct SSD13x6_Device* DeviceHandle ) {
SSD13x6_SetColumnAddress( DeviceHandle, 0, DeviceHandle->Width - 1);
SSD13x6_SetPageAddress( DeviceHandle, 0, DeviceHandle->Height / 8 - 1);
SSD13x6_WriteData( DeviceHandle, DeviceHandle->Framebuffer, DeviceHandle->FramebufferSize );
}
void SSD13x6_WriteRawData( struct SSD13x6_Device* DeviceHandle, uint8_t* Data, size_t DataLength ) {
NullCheck( Data, return );
DataLength = DataLength > DeviceHandle->FramebufferSize ? DeviceHandle->FramebufferSize : DataLength;
if ( DataLength > 0 ) SSD13x6_WriteData( DeviceHandle, Data, DataLength );
}
void SSD13x6_SetHFlip( struct SSD13x6_Device* DeviceHandle, bool On ) {
switch (DeviceHandle->Model) {
case SSD1306:
SSD13x6_WriteCommand( DeviceHandle, On ? 0xA1 : 0xA0 );
break;
case SSD1326:
DeviceHandle->ReMap = On ? (DeviceHandle->ReMap | 0x01) : (DeviceHandle->ReMap & ~0x01);
SSD132x_ReMap(DeviceHandle);
break;
}
}
void SSD13x6_SetVFlip( struct SSD13x6_Device* DeviceHandle, bool On ) {
switch (DeviceHandle->Model) {
case SSD1306:
SSD13x6_WriteCommand( DeviceHandle, On ? 0xC8 : 0xC0 );
break;
case SSD1326:
DeviceHandle->ReMap = On ? (DeviceHandle->ReMap | 0x05) : (DeviceHandle->ReMap & ~0x05);
SSD132x_ReMap( DeviceHandle );
break;
}
}
void SSD13x6_SetColumnAddress( struct SSD13x6_Device* DeviceHandle, uint8_t Start, uint8_t End ) {
CheckBounds( Start > SSD13x6_Max_Col, return );
CheckBounds( End > SSD13x6_Max_Col, return );
SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Column_Address );
SSD13x6_WriteCommand( DeviceHandle, Start );
SSD13x6_WriteCommand( DeviceHandle, End );
}
void SSD13x6_SetPageAddress( struct SSD13x6_Device* DeviceHandle, uint8_t Start, uint8_t End ) {
NullCheck( DeviceHandle, return );
CheckBounds( Start > SSD13x6_Max_Row, return );
CheckBounds( End > SSD13x6_Max_Row, return );
// in case of SSD1326, this is sub-optimal as it can address by line, not by page
if (DeviceHandle->Model != SSD1306) {
Start *= 8;
End = (End + 1) * 8 - 1;
}
SSD13x6_WriteCommand( DeviceHandle, SSDCmd_Set_Page_Address );
SSD13x6_WriteCommand( DeviceHandle, Start );
SSD13x6_WriteCommand( DeviceHandle, End );
}
bool SSD13x6_HWReset( struct SSD13x6_Device* DeviceHandle ) {
NullCheck( DeviceHandle, return 0 );
if ( DeviceHandle->Reset != NULL ) {
return ( DeviceHandle->Reset ) ( DeviceHandle );
}
/* This should always return true if there is no reset callback as
* no error would have occurred during the non existant reset.
*/
return true;
}
/*
* This is all a big giant mystery that I have yet to figure out.
* Beware all ye who enter.
*/
static void SetCOMPinConfiguration( struct SSD13x6_Device* DeviceHandle, uint32_t RemapCFG, uint32_t PinCFG, int ScanDir ) {
SSD13x6_WriteCommand( DeviceHandle, 0xDA );
SSD13x6_WriteCommand( DeviceHandle, ( uint8_t ) ( RemapCFG | PinCFG | BIT( 1 ) ) );
SSD13x6_WriteCommand( DeviceHandle,
( ScanDir == COM_ScanDir_LR ) ? 0xC0 : 0xC8
);
}
static bool SSD13x6_Init( struct SSD13x6_Device* DeviceHandle, int Width, int Height ) {
DeviceHandle->Width = Width;
DeviceHandle->Height = Height;
DeviceHandle->FramebufferSize = ( DeviceHandle->Width * Height ) / 8;
// DeviceHandle->Framebuffer = heap_caps_calloc( 1, DeviceHandle->FramebufferSize, MALLOC_CAP_INTERNAL );
DeviceHandle->Framebuffer = calloc( 1, DeviceHandle->FramebufferSize );
NullCheck( DeviceHandle->Framebuffer, return false );
SSD13x6_HWReset( DeviceHandle );
if (DeviceHandle->Model == SSD1306) {
SSDCmd_Set_Display_Start_Line = 0x40;
SSDCmd_Set_Display_Offset = 0xD3;
SSDCmd_Set_Column_Address = 0x21,
SSDCmd_Set_Display_CLK = 0xD5;
SSDCmd_Set_Page_Address = 0x22;
SSD13x6_Max_Col = 127;
// charge pump regulator, do direct init
SSD13x6_WriteCommand( DeviceHandle, 0x8D );
SSD13x6_WriteCommand( DeviceHandle, 0x14 ); /* MAGIC NUMBER */
if ( Height == 64 ) {
SetCOMPinConfiguration( DeviceHandle, COM_Disable_LR_Remap, COM_Pins_Alternative, COM_ScanDir_LR );
} else {
SetCOMPinConfiguration( DeviceHandle, COM_Disable_LR_Remap, COM_Pins_Sequential, COM_ScanDir_LR );
}
} else if (DeviceHandle->Model == SSD1326) {
SSDCmd_Set_Display_Start_Line = 0xA1;
SSDCmd_Set_Display_Offset = 0xA2;
SSDCmd_Set_Column_Address = 0x15;
SSDCmd_Set_Display_CLK = 0xB3;
SSDCmd_Set_Page_Address = 0x75; // not really a page but a row
SSD13x6_Max_Col = 255;
// no gray scale
DeviceHandle->ReMap |= 0x10;
SSD132x_ReMap( DeviceHandle );
SSD13x6_SetHFlip( DeviceHandle, false );
SSD13x6_SetVFlip( DeviceHandle, false );
}
SSD13x6_SetMuxRatio( DeviceHandle, Height - 1 );
SSD13x6_SetDisplayOffset( DeviceHandle, 0x00 );
SSD13x6_SetDisplayStartLine( DeviceHandle, 0 );
SSD13x6_SetContrast( DeviceHandle, 0x7F );
SSD13x6_DisableDisplayRAM( DeviceHandle );
SSD13x6_SetInverted( DeviceHandle, false );
SSD13x6_SetDisplayClocks( DeviceHandle, 0, 8 );
SSD13x6_SetDisplayAddressMode( DeviceHandle, AddressMode_Vertical );
SSD13x6_SetColumnAddress( DeviceHandle, 0, DeviceHandle->Width - 1 );
SSD13x6_SetPageAddress( DeviceHandle, 0, ( DeviceHandle->Height / 8 ) - 1 );
SSD13x6_EnableDisplayRAM( DeviceHandle );
SSD13x6_DisplayOn( DeviceHandle );
SSD13x6_Update( DeviceHandle );
return true;
}
bool SSD13x6_Init_I2C( struct SSD13x6_Device* DeviceHandle, int Width, int Height, int I2CAddress, int ResetPin, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset ) {
NullCheck( DeviceHandle, return false );
NullCheck( WriteCommand, return false );
NullCheck( WriteData, return false );
memset( DeviceHandle, 0, sizeof( struct SSD13x6_Device ) );
DeviceHandle->WriteCommand = WriteCommand;
DeviceHandle->WriteData = WriteData;
DeviceHandle->Reset = Reset;
DeviceHandle->Address = I2CAddress;
DeviceHandle->RSTPin = ResetPin;
return SSD13x6_Init( DeviceHandle, Width, Height );
}
bool SSD13x6_Init_SPI( struct SSD13x6_Device* DeviceHandle, int Width, int Height, int ResetPin, int CSPin, spi_device_handle_t SPIHandle, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset ) {
NullCheck( DeviceHandle, return false );
NullCheck( WriteCommand, return false );
NullCheck( WriteData, return false );
memset( DeviceHandle, 0, sizeof( struct SSD13x6_Device ) );
DeviceHandle->WriteCommand = WriteCommand;
DeviceHandle->WriteData = WriteData;
DeviceHandle->Reset = Reset;
DeviceHandle->SPIHandle = SPIHandle;
DeviceHandle->RSTPin = ResetPin;
DeviceHandle->CSPin = CSPin;
return SSD13x6_Init( DeviceHandle, Width, Height );
}

View File

@@ -0,0 +1,94 @@
#ifndef _SSD13X6_H_
#define _SSD13X6_H_
/* For uint(X)_t */
#include <stdint.h>
/* For booooool */
#include <stdbool.h>
#include "sdkconfig.h"
#include "ssd13x6_err.h"
#define SSD_ALWAYS_INLINE __attribute__( ( always_inline ) )
#if ! defined BIT
#define BIT( n ) ( 1 << n )
#endif
typedef uint8_t SSDCmd;
typedef enum {
AddressMode_Horizontal = 0,
AddressMode_Vertical,
AddressMode_Page,
AddressMode_Invalid
} SSD13x6_AddressMode;
struct SSD13x6_Device;
/*
* These can optionally return a succeed/fail but are as of yet unused in the driver.
*/
typedef bool ( *WriteCommandProc ) ( struct SSD13x6_Device* DeviceHandle, SSDCmd Command );
typedef bool ( *WriteDataProc ) ( struct SSD13x6_Device* DeviceHandle, const uint8_t* Data, size_t DataLength );
typedef bool ( *ResetProc ) ( struct SSD13x6_Device* DeviceHandle );
struct spi_device_t;
typedef struct spi_device_t* spi_device_handle_t;
struct SSD13x6_FontDef;
struct SSD13x6_Device {
/* I2C Specific */
int Address;
/* SPI Specific */
spi_device_handle_t SPIHandle;
int RSTPin;
int CSPin;
/* Everything else */
int Width;
int Height;
enum { SSD1306, SSD1326 } Model;
uint8_t ReMap;
uint8_t* Framebuffer;
int FramebufferSize;
WriteCommandProc WriteCommand;
WriteDataProc WriteData;
ResetProc Reset;
const struct SSD13x6_FontDef* Font;
bool FontForceProportional;
bool FontForceMonospace;
};
void SSD13x6_SetMuxRatio( struct SSD13x6_Device* DeviceHandle, uint8_t Ratio );
void SSD13x6_SetDisplayOffset( struct SSD13x6_Device* DeviceHandle, uint8_t Offset );
void SSD13x6_SetDisplayStartLines( struct SSD13x6_Device* DeviceHandle );
void SSD13x6_SetSegmentRemap( struct SSD13x6_Device* DeviceHandle, bool Remap );
void SSD13x6_SetContrast( struct SSD13x6_Device* DeviceHandle, uint8_t Contrast );
void SSD13x6_EnableDisplayRAM( struct SSD13x6_Device* DeviceHandle );
void SSD13x6_DisableDisplayRAM( struct SSD13x6_Device* DeviceHandle );
void SSD13x6_SetInverted( struct SSD13x6_Device* DeviceHandle, bool Inverted );
void SSD13x6_SetHFlip( struct SSD13x6_Device* DeviceHandle, bool On );
void SSD13x6_SetVFlip( struct SSD13x6_Device* DeviceHandle, bool On );
void SSD13x6_DisplayOn( struct SSD13x6_Device* DeviceHandle );
void SSD13x6_DisplayOff( struct SSD13x6_Device* DeviceHandle );
void SSD13x6_SetDisplayAddressMode( struct SSD13x6_Device* DeviceHandle, SSD13x6_AddressMode AddressMode );
void SSD13x6_Update( struct SSD13x6_Device* DeviceHandle );
void SSD13x6_SetDisplayClocks( struct SSD13x6_Device* DeviceHandle, uint32_t DisplayClockDivider, uint32_t OSCFrequency );
void SSD13x6_SetColumnAddress( struct SSD13x6_Device* DeviceHandle, uint8_t Start, uint8_t End );
void SSD13x6_SetPageAddress( struct SSD13x6_Device* DeviceHandle, uint8_t Start, uint8_t End );
bool SSD13x6_HWReset( struct SSD13x6_Device* DeviceHandle );
bool SSD13x6_Init_I2C( struct SSD13x6_Device* DeviceHandle, int Width, int Height, int I2CAddress, int ResetPin, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset );
bool SSD13x6_Init_SPI( struct SSD13x6_Device* DeviceHandle, int Width, int Height, int ResetPin, int CSPin, spi_device_handle_t SPIHandle, WriteCommandProc WriteCommand, WriteDataProc WriteData, ResetProc Reset );
void SSD13x6_WriteRawData( struct SSD13x6_Device* DeviceHandle, uint8_t* Data, size_t DataLength );
#endif

View File

@@ -0,0 +1,18 @@
#ifndef _SSD13x6_DEFAULT_IF_H_
#define _SSD13x6_DEFAULT_IF_H_
#ifdef __cplusplus
extern "C" {
#endif
bool SSD13x6_I2CMasterInitDefault( int PortNumber, int SDA, int SCL );
bool SSD13x6_I2CMasterAttachDisplayDefault( struct SSD13x6_Device* DisplayHandle, int Model, int Width, int Height, int I2CAddress, int RSTPin );
bool SSD13x6_SPIMasterInitDefault( int SPI, int DC);
bool SSD13x6_SPIMasterAttachDisplayDefault( struct SSD13x6_Device* DeviceHandle, int Model, int Width, int Height, int CSPin, int RSTPin );
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -13,10 +13,10 @@
#include <math.h>
#include <esp_attr.h>
#include "ssd1306.h"
#include "ssd1306_draw.h"
#include "ssd13x6.h"
#include "ssd13x6_draw.h"
__attribute__( ( always_inline ) ) static inline bool IsPixelVisible( struct SSD1306_Device* DeviceHandle, int x, int y ) {
__attribute__( ( always_inline ) ) static inline bool IsPixelVisible( struct SSD13x6_Device* DeviceHandle, int x, int y ) {
bool Result = (
( x >= 0 ) &&
( x < DeviceHandle->Width ) &&
@@ -24,7 +24,7 @@ __attribute__( ( always_inline ) ) static inline bool IsPixelVisible( struct SSD
( y < DeviceHandle->Height )
) ? true : false;
#if CONFIG_SSD1306_CLIPDEBUG > 0
#if CONFIG_SSD13x6_CLIPDEBUG > 0
if ( Result == false ) {
ClipDebug( x, y );
}
@@ -40,7 +40,7 @@ __attribute__( ( always_inline ) ) static inline void SwapInt( int* a, int* b )
*a = Temp;
}
inline void IRAM_ATTR SSD1306_DrawPixelFast( struct SSD1306_Device* DeviceHandle, int X, int Y, int Color ) {
inline void IRAM_ATTR SSD13x6_DrawPixelFast( struct SSD13x6_Device* DeviceHandle, int X, int Y, int Color ) {
uint32_t YBit = ( Y & 0x07 );
uint8_t* FBOffset = NULL;
@@ -61,15 +61,15 @@ inline void IRAM_ATTR SSD1306_DrawPixelFast( struct SSD1306_Device* DeviceHandle
}
}
void IRAM_ATTR SSD1306_DrawPixel( struct SSD1306_Device* DeviceHandle, int x, int y, int Color ) {
void IRAM_ATTR SSD13x6_DrawPixel( struct SSD13x6_Device* DeviceHandle, int x, int y, int Color ) {
NullCheck( DeviceHandle, return );
if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
SSD1306_DrawPixelFast( DeviceHandle, x, y, Color );
SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color );
}
}
void IRAM_ATTR SSD1306_DrawHLine( struct SSD1306_Device* DeviceHandle, int x, int y, int Width, int Color ) {
void IRAM_ATTR SSD13x6_DrawHLine( struct SSD13x6_Device* DeviceHandle, int x, int y, int Width, int Color ) {
int XEnd = x + Width;
NullCheck( DeviceHandle, return );
@@ -77,14 +77,14 @@ void IRAM_ATTR SSD1306_DrawHLine( struct SSD1306_Device* DeviceHandle, int x, in
for ( ; x <= XEnd; x++ ) {
if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
SSD1306_DrawPixelFast( DeviceHandle, x, y, Color );
SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color );
} else {
break;
}
}
}
void IRAM_ATTR SSD1306_DrawVLine( struct SSD1306_Device* DeviceHandle, int x, int y, int Height, int Color ) {
void IRAM_ATTR SSD13x6_DrawVLine( struct SSD13x6_Device* DeviceHandle, int x, int y, int Height, int Color ) {
int YEnd = y + Height;
NullCheck( DeviceHandle, return );
@@ -92,14 +92,14 @@ void IRAM_ATTR SSD1306_DrawVLine( struct SSD1306_Device* DeviceHandle, int x, in
for ( ; y <= YEnd; y++ ) {
if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
SSD1306_DrawPixel( DeviceHandle, x, y, Color );
SSD13x6_DrawPixel( DeviceHandle, x, y, Color );
} else {
break;
}
}
}
static inline void IRAM_ATTR DrawWideLine( struct SSD1306_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ) {
static inline void IRAM_ATTR DrawWideLine( struct SSD13x6_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ) {
int dx = ( x1 - x0 );
int dy = ( y1 - y0 );
int Error = 0;
@@ -116,7 +116,7 @@ static inline void IRAM_ATTR DrawWideLine( struct SSD1306_Device* DeviceHandle,
for ( ; x <= x1; x++ ) {
if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
SSD1306_DrawPixelFast( DeviceHandle, x, y, Color );
SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color );
}
if ( Error > 0 ) {
@@ -128,7 +128,7 @@ static inline void IRAM_ATTR DrawWideLine( struct SSD1306_Device* DeviceHandle,
}
}
static inline void IRAM_ATTR DrawTallLine( struct SSD1306_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ) {
static inline void IRAM_ATTR DrawTallLine( struct SSD13x6_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ) {
int dx = ( x1 - x0 );
int dy = ( y1 - y0 );
int Error = 0;
@@ -145,7 +145,7 @@ static inline void IRAM_ATTR DrawTallLine( struct SSD1306_Device* DeviceHandle,
for ( ; y < y1; y++ ) {
if ( IsPixelVisible( DeviceHandle, x, y ) == true ) {
SSD1306_DrawPixelFast( DeviceHandle, x, y, Color );
SSD13x6_DrawPixelFast( DeviceHandle, x, y, Color );
}
if ( Error > 0 ) {
@@ -157,14 +157,14 @@ static inline void IRAM_ATTR DrawTallLine( struct SSD1306_Device* DeviceHandle,
}
}
void IRAM_ATTR SSD1306_DrawLine( struct SSD1306_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ) {
void IRAM_ATTR SSD13x6_DrawLine( struct SSD13x6_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ) {
NullCheck( DeviceHandle, return );
NullCheck( DeviceHandle->Framebuffer, return );
if ( x0 == x1 ) {
SSD1306_DrawVLine( DeviceHandle, x0, y0, ( y1 - y0 ), Color );
SSD13x6_DrawVLine( DeviceHandle, x0, y0, ( y1 - y0 ), Color );
} else if ( y0 == y1 ) {
SSD1306_DrawHLine( DeviceHandle, x0, y0, ( x1 - x0 ), Color );
SSD13x6_DrawHLine( DeviceHandle, x0, y0, ( x1 - x0 ), Color );
} else {
if ( abs( x1 - x0 ) > abs( y1 - y0 ) ) {
/* Wide ( run > rise ) */
@@ -186,7 +186,7 @@ void IRAM_ATTR SSD1306_DrawLine( struct SSD1306_Device* DeviceHandle, int x0, in
}
}
void IRAM_ATTR SSD1306_DrawBox( struct SSD1306_Device* DeviceHandle, int x1, int y1, int x2, int y2, int Color, bool Fill ) {
void IRAM_ATTR SSD13x6_DrawBox( struct SSD13x6_Device* DeviceHandle, int x1, int y1, int x2, int y2, int Color, bool Fill ) {
int Width = ( x2 - x1 );
int Height = ( y2 - y1 );
@@ -195,25 +195,25 @@ void IRAM_ATTR SSD1306_DrawBox( struct SSD1306_Device* DeviceHandle, int x1, int
if ( Fill == false ) {
/* Top side */
SSD1306_DrawHLine( DeviceHandle, x1, y1, Width, Color );
SSD13x6_DrawHLine( DeviceHandle, x1, y1, Width, Color );
/* Bottom side */
SSD1306_DrawHLine( DeviceHandle, x1, y1 + Height, Width, Color );
SSD13x6_DrawHLine( DeviceHandle, x1, y1 + Height, Width, Color );
/* Left side */
SSD1306_DrawVLine( DeviceHandle, x1, y1, Height, Color );
SSD13x6_DrawVLine( DeviceHandle, x1, y1, Height, Color );
/* Right side */
SSD1306_DrawVLine( DeviceHandle, x1 + Width, y1, Height, Color );
SSD13x6_DrawVLine( DeviceHandle, x1 + Width, y1, Height, Color );
} else {
/* Fill the box by drawing horizontal lines */
for ( ; y1 <= y2; y1++ ) {
SSD1306_DrawHLine( DeviceHandle, x1, y1, Width, Color );
SSD13x6_DrawHLine( DeviceHandle, x1, y1, Width, Color );
}
}
}
void SSD1306_Clear( struct SSD1306_Device* DeviceHandle, int Color ) {
void SSD13x6_Clear( struct SSD13x6_Device* DeviceHandle, int Color ) {
NullCheck( DeviceHandle, return );
NullCheck( DeviceHandle->Framebuffer, return );

View File

@@ -1,5 +1,5 @@
#ifndef _SSD1306_DRAW_H_
#define _SSD1306_DRAW_H_
#ifndef _SSD13x6_DRAW_H_
#define _SSD13x6_DRAW_H_
#ifdef __cplusplus
extern "C" {
@@ -7,23 +7,23 @@ extern "C" {
#include "sdkconfig.h"
#define SSD1306_CLIPDEBUG_NONE 0
#define SSD1306_CLIPDEBUG_WARNING 1
#define SSD1306_CLIPDEBUG_ERROR 2
#define SSD13x6_CLIPDEBUG_NONE 0
#define SSD13x6_CLIPDEBUG_WARNING 1
#define SSD13x6_CLIPDEBUG_ERROR 2
#if CONFIG_SSD1306_CLIPDEBUG == SSD1306_CLIPDEBUG_NONE
#if CONFIG_SSD13x6_CLIPDEBUG == SSD13x6_CLIPDEBUG_NONE
/*
* Clip silently with no console output.
*/
#define ClipDebug( x, y )
#elif CONFIG_SSD1306_CLIPDEBUG == SSD1306_CLIPDEBUG_WARNING
#elif CONFIG_SSD13x6_CLIPDEBUG == SSD13x6_CLIPDEBUG_WARNING
/*
* Log clipping to the console as a warning.
*/
#define ClipDebug( x, y ) { \
ESP_LOGW( __FUNCTION__, "Line %d: Pixel at %d, %d CLIPPED", __LINE__, x, y ); \
}
#elif CONFIG_SSD1306_CLIPDEBUG == SSD1306_CLIPDEBUG_ERROR
#elif CONFIG_SSD13x6_CLIPDEBUG == SSD13x6_CLIPDEBUG_ERROR
/*
* Log clipping as an error to the console.
* Also invokes an abort with stack trace.
@@ -38,13 +38,13 @@ extern "C" {
#define SSD_COLOR_WHITE 1
#define SSD_COLOR_XOR 2
void SSD1306_Clear( struct SSD1306_Device* DeviceHandle, int Color );
void SSD1306_DrawPixel( struct SSD1306_Device* DeviceHandle, int X, int Y, int Color );
void SSD1306_DrawPixelFast( struct SSD1306_Device* DeviceHandle, int X, int Y, int Color );
void SSD1306_DrawHLine( struct SSD1306_Device* DeviceHandle, int x, int y, int Width, int Color );
void SSD1306_DrawVLine( struct SSD1306_Device* DeviceHandle, int x, int y, int Height, int Color );
void SSD1306_DrawLine( struct SSD1306_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color );
void SSD1306_DrawBox( struct SSD1306_Device* DeviceHandle, int x1, int y1, int x2, int y2, int Color, bool Fill );
void SSD13x6_Clear( struct SSD13x6_Device* DeviceHandle, int Color );
void SSD13x6_DrawPixel( struct SSD13x6_Device* DeviceHandle, int X, int Y, int Color );
void SSD13x6_DrawPixelFast( struct SSD13x6_Device* DeviceHandle, int X, int Y, int Color );
void SSD13x6_DrawHLine( struct SSD13x6_Device* DeviceHandle, int x, int y, int Width, int Color );
void SSD13x6_DrawVLine( struct SSD13x6_Device* DeviceHandle, int x, int y, int Height, int Color );
void SSD13x6_DrawLine( struct SSD13x6_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color );
void SSD13x6_DrawBox( struct SSD13x6_Device* DeviceHandle, int x1, int y1, int x2, int y2, int Color, bool Fill );
#ifdef __cplusplus
}

View File

@@ -1,15 +1,15 @@
#ifndef _SSD1306_ERR_H_
#define _SSD1306_ERR_H_
#ifndef _SSD13x6_ERR_H_
#define _SSD13x6_ERR_H_
#include <esp_log.h>
#define SSD1306_DoAbort( )
#define SSD13x6_DoAbort( )
#if ! defined NullCheck
#define NullCheck( ptr, retexpr ) { \
if ( ptr == NULL ) { \
ESP_LOGE( __FUNCTION__, "%s == NULL", #ptr ); \
SSD1306_DoAbort( ); \
SSD13x6_DoAbort( ); \
retexpr; \
} \
}
@@ -20,7 +20,7 @@
esp_err_t __err_rc = ( expr ); \
if ( __err_rc != ESP_OK ) { \
ESP_LOGE( __FUNCTION__, "%s != ESP_OK, result: %d", #expr, __err_rc ); \
SSD1306_DoAbort( ); \
SSD13x6_DoAbort( ); \
retexpr; \
} \
}
@@ -30,7 +30,7 @@
#define CheckBounds( expr, retexpr ) { \
if ( expr ) { \
ESP_LOGE( __FUNCTION__, "Line %d: %s", __LINE__, #expr ); \
SSD1306_DoAbort( ); \
SSD13x6_DoAbort( ); \
retexpr; \
} \
}

View File

@@ -9,11 +9,11 @@
#include <string.h>
#include <stdint.h>
#include <math.h>
#include "ssd1306.h"
#include "ssd1306_draw.h"
#include "ssd1306_font.h"
#include "ssd13x6.h"
#include "ssd13x6_draw.h"
#include "ssd13x6_font.h"
static int RoundUpFontHeight( const struct SSD1306_FontDef* Font ) {
static int RoundUpFontHeight( const struct SSD13x6_FontDef* Font ) {
int Height = Font->Height;
if ( ( Height % 8 ) != 0 ) {
@@ -23,11 +23,11 @@ static int RoundUpFontHeight( const struct SSD1306_FontDef* Font ) {
return Height;
}
static const uint8_t* GetCharPtr( const struct SSD1306_FontDef* Font, char Character ) {
static const uint8_t* GetCharPtr( const struct SSD13x6_FontDef* Font, char Character ) {
return &Font->FontData[ ( Character - Font->StartChar ) * ( ( Font->Width * ( RoundUpFontHeight( Font ) / 8 ) ) + 1 ) ];
}
void SSD1306_FontDrawChar( struct SSD1306_Device* DisplayHandle, char Character, int x, int y, int Color ) {
void SSD13x6_FontDrawChar( struct SSD13x6_Device* DisplayHandle, char Character, int x, int y, int Color ) {
const uint8_t* GlyphData = NULL;
int GlyphColumnLen = 0;
int CharStartX = 0;
@@ -52,8 +52,8 @@ void SSD1306_FontDrawChar( struct SSD1306_Device* DisplayHandle, char Character,
GlyphData++;
GlyphColumnLen = RoundUpFontHeight( DisplayHandle->Font ) / 8;
CharWidth = SSD1306_FontGetCharWidth( DisplayHandle, Character );
CharHeight = SSD1306_FontGetHeight( DisplayHandle );
CharWidth = SSD13x6_FontGetCharWidth( DisplayHandle, Character );
CharHeight = SSD13x6_FontGetHeight( DisplayHandle );
CharStartX = x;
CharStartY = y;
@@ -89,7 +89,7 @@ void SSD1306_FontDrawChar( struct SSD1306_Device* DisplayHandle, char Character,
YBit = ( i + OffsetY ) & 0x07;
if ( GlyphData[ YByte ] & BIT( YBit ) ) {
SSD1306_DrawPixel( DisplayHandle, x, y, Color );
SSD13x6_DrawPixel( DisplayHandle, x, y, Color );
}
}
@@ -98,7 +98,7 @@ void SSD1306_FontDrawChar( struct SSD1306_Device* DisplayHandle, char Character,
}
}
bool SSD1306_SetFont( struct SSD1306_Device* Display, const struct SSD1306_FontDef* Font ) {
bool SSD13x6_SetFont( struct SSD13x6_Device* Display, const struct SSD13x6_FontDef* Font ) {
NullCheck( Display, return false );
NullCheck( Font, return false );
@@ -109,35 +109,35 @@ bool SSD1306_SetFont( struct SSD1306_Device* Display, const struct SSD1306_FontD
return true;
}
void SSD1306_FontForceProportional( struct SSD1306_Device* Display, bool Force ) {
void SSD13x6_FontForceProportional( struct SSD13x6_Device* Display, bool Force ) {
NullCheck( Display, return );
NullCheck( Display->Font, return );
Display->FontForceProportional = Force;
}
void SSD1306_FontForceMonospace( struct SSD1306_Device* Display, bool Force ) {
void SSD13x6_FontForceMonospace( struct SSD13x6_Device* Display, bool Force ) {
NullCheck( Display, return );
NullCheck( Display->Font, return );
Display->FontForceMonospace = Force;
}
int SSD1306_FontGetWidth( struct SSD1306_Device* Display ) {
int SSD13x6_FontGetWidth( struct SSD13x6_Device* Display ) {
NullCheck( Display, return 0 );
NullCheck( Display->Font, return 0 );
return Display->Font->Width;
}
int SSD1306_FontGetHeight( struct SSD1306_Device* Display ) {
int SSD13x6_FontGetHeight( struct SSD13x6_Device* Display ) {
NullCheck( Display, return 0 );
NullCheck( Display->Font, return 0 );
return Display->Font->Height;
}
int SSD1306_FontGetCharWidth( struct SSD1306_Device* Display, char Character ) {
int SSD13x6_FontGetCharWidth( struct SSD13x6_Device* Display, char Character ) {
const uint8_t* CharPtr = NULL;
int Width = 0;
@@ -161,28 +161,28 @@ int SSD1306_FontGetCharWidth( struct SSD1306_Device* Display, char Character ) {
return Width;
}
int SSD1306_FontGetMaxCharsPerRow( struct SSD1306_Device* Display ) {
int SSD13x6_FontGetMaxCharsPerRow( struct SSD13x6_Device* Display ) {
NullCheck( Display, return 0 );
NullCheck( Display->Font, return 0 );
return Display->Width / Display->Font->Width;
}
int SSD1306_FontGetMaxCharsPerColumn( struct SSD1306_Device* Display ) {
int SSD13x6_FontGetMaxCharsPerColumn( struct SSD13x6_Device* Display ) {
NullCheck( Display, return 0 );
NullCheck( Display->Font, return 0 );
return Display->Height / Display->Font->Height;
}
int SSD1306_FontGetCharHeight( struct SSD1306_Device* Display ) {
int SSD13x6_FontGetCharHeight( struct SSD13x6_Device* Display ) {
NullCheck( Display, return 0 );
NullCheck( Display->Font, return 0 );
return Display->Font->Height;
}
int SSD1306_FontMeasureString( struct SSD1306_Device* Display, const char* Text ) {
int SSD13x6_FontMeasureString( struct SSD13x6_Device* Display, const char* Text ) {
int Width = 0;
int Len = 0;
@@ -192,14 +192,14 @@ int SSD1306_FontMeasureString( struct SSD1306_Device* Display, const char* Text
for ( Len = strlen( Text ); Len >= 0; Len--, Text++ ) {
if ( *Text >= Display->Font->StartChar && *Text <= Display->Font->EndChar ) {
Width+= SSD1306_FontGetCharWidth( Display, *Text );
Width+= SSD13x6_FontGetCharWidth( Display, *Text );
}
}
return Width;
}
void SSD1306_FontDrawString( struct SSD1306_Device* Display, int x, int y, const char* Text, int Color ) {
void SSD13x6_FontDrawString( struct SSD13x6_Device* Display, int x, int y, const char* Text, int Color ) {
int Len = 0;
int i = 0;
@@ -208,25 +208,25 @@ void SSD1306_FontDrawString( struct SSD1306_Device* Display, int x, int y, const
NullCheck( Text, return );
for ( Len = strlen( Text ), i = 0; i < Len; i++ ) {
SSD1306_FontDrawChar( Display, *Text, x, y, Color );
SSD13x6_FontDrawChar( Display, *Text, x, y, Color );
x+= SSD1306_FontGetCharWidth( Display, *Text );
x+= SSD13x6_FontGetCharWidth( Display, *Text );
Text++;
}
}
void SSD1306_FontDrawAnchoredString( struct SSD1306_Device* Display, TextAnchor Anchor, const char* Text, int Color ) {
void SSD13x6_FontDrawAnchoredString( struct SSD13x6_Device* Display, TextAnchor Anchor, const char* Text, int Color ) {
int x = 0;
int y = 0;
NullCheck( Display, return );
NullCheck( Text, return );
SSD1306_FontGetAnchoredStringCoords( Display, &x, &y, Anchor, Text );
SSD1306_FontDrawString( Display, x, y, Text, Color );
SSD13x6_FontGetAnchoredStringCoords( Display, &x, &y, Anchor, Text );
SSD13x6_FontDrawString( Display, x, y, Text, Color );
}
void SSD1306_FontGetAnchoredStringCoords( struct SSD1306_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text ) {
void SSD13x6_FontGetAnchoredStringCoords( struct SSD13x6_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text ) {
int StringWidth = 0;
int StringHeight = 0;
@@ -235,8 +235,8 @@ void SSD1306_FontGetAnchoredStringCoords( struct SSD1306_Device* Display, int* O
NullCheck( OutY, return );
NullCheck( Text, return );
StringWidth = SSD1306_FontMeasureString( Display, Text );
StringHeight = SSD1306_FontGetCharHeight( Display );
StringWidth = SSD13x6_FontMeasureString( Display, Text );
StringHeight = SSD13x6_FontGetCharHeight( Display );
switch ( Anchor ) {
case TextAnchor_East: {

View File

@@ -0,0 +1,91 @@
#ifndef _SSD13x6_FONT_H_
#define _SSD13x6_FONT_H_
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
struct SSD13x6_Device;
/*
* X-GLCD Font format:
*
* First byte of glyph is it's width in pixels.
* Each data byte represents 8 pixels going down from top to bottom.
*
* Example glyph layout for a 16x16 font
* 'a': [Glyph width][Pixel column 0][Pixel column 1] where the number of pixel columns is the font height divided by 8
* 'b': [Glyph width][Pixel column 0][Pixel column 1]...
* 'c': And so on...
*/
struct SSD13x6_FontDef {
const uint8_t* FontData;
int Width;
int Height;
int StartChar;
int EndChar;
bool Monospace;
};
typedef enum {
TextAnchor_East = 0,
TextAnchor_West,
TextAnchor_North,
TextAnchor_South,
TextAnchor_NorthEast,
TextAnchor_NorthWest,
TextAnchor_SouthEast,
TextAnchor_SouthWest,
TextAnchor_Center
} TextAnchor;
bool SSD13x6_SetFont( struct SSD13x6_Device* Display, const struct SSD13x6_FontDef* Font );
void SSD13x6_FontForceProportional( struct SSD13x6_Device* Display, bool Force );
void SSD13x6_FontForceMonospace( struct SSD13x6_Device* Display, bool Force );
int SSD13x6_FontGetWidth( struct SSD13x6_Device* Display );
int SSD13x6_FontGetHeight( struct SSD13x6_Device* Display );
int SSD13x6_FontGetMaxCharsPerRow( struct SSD13x6_Device* Display );
int SSD13x6_FontGetMaxCharsPerColumn( struct SSD13x6_Device* Display );
int SSD13x6_FontGetCharWidth( struct SSD13x6_Device* Display, char Character );
int SSD13x6_FontGetCharHeight( struct SSD13x6_Device* Display );
int SSD13x6_FontMeasureString( struct SSD13x6_Device* Display, const char* Text );\
void SSD13x6_FontDrawChar( struct SSD13x6_Device* Display, char Character, int x, int y, int Color );
void SSD13x6_FontDrawString( struct SSD13x6_Device* Display, int x, int y, const char* Text, int Color );
void SSD13x6_FontDrawAnchoredString( struct SSD13x6_Device* Display, TextAnchor Anchor, const char* Text, int Color );
void SSD13x6_FontGetAnchoredStringCoords( struct SSD13x6_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text );
extern const struct SSD13x6_FontDef Font_droid_sans_fallback_11x13;
extern const struct SSD13x6_FontDef Font_droid_sans_fallback_15x17;
extern const struct SSD13x6_FontDef Font_droid_sans_fallback_24x28;
extern const struct SSD13x6_FontDef Font_droid_sans_mono_7x13;
extern const struct SSD13x6_FontDef Font_droid_sans_mono_13x24;
extern const struct SSD13x6_FontDef Font_droid_sans_mono_16x31;
extern const struct SSD13x6_FontDef Font_liberation_mono_9x15;
extern const struct SSD13x6_FontDef Font_liberation_mono_13x21;
extern const struct SSD13x6_FontDef Font_liberation_mono_17x30;
extern const struct SSD13x6_FontDef Font_Tarable7Seg_16x32;
extern const struct SSD13x6_FontDef Font_Tarable7Seg_32x64;
extern const struct SSD13x6_FontDef Font_line_1;
extern const struct SSD13x6_FontDef Font_line_2;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -138,8 +138,8 @@ static bool init(int i2c_port_num, int i2s_num, i2s_config_t *i2s_config) {
#endif
// configure I2S pins & install driver
i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = 27, .ws_io_num = 26,
.data_out_num = 25, .data_in_num = 35 //Not used
i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = CONFIG_I2S_BCK_IO, .ws_io_num = CONFIG_I2S_WS_IO,
.data_out_num = CONFIG_I2S_DO_IO, .data_in_num = CONFIG_I2S_DI_IO
};
i2s_driver_install(i2s_num, i2s_config, 0, NULL);
i2s_set_pin(i2s_num, &i2s_pin_config);

View File

@@ -38,9 +38,8 @@ struct adac_s dac_external = { init, deinit, power, speaker, headset, volume };
static char TAG[] = "DAC external";
static bool init(int i2c_port_num, int i2s_num, i2s_config_t *config) {
#if !defined(CONFIG_SQUEEZEAMP) && !defined(CONFIG_A1S)
i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = CONFIG_I2S_BCK_IO, .ws_io_num = CONFIG_I2S_WS_IO,
.data_out_num = CONFIG_I2S_DO_IO, .data_in_num = -1 };
.data_out_num = CONFIG_I2S_DO_IO, .data_in_num = CONFIG_I2S_DI_IO };
char *nvs_item = config_alloc_get(NVS_TYPE_STR, "dac_config");
if (nvs_item) {
@@ -59,13 +58,10 @@ static bool init(int i2c_port_num, int i2s_num, i2s_config_t *config) {
return true;
} else {
ESP_LOGI(TAG, "Cannot initialize I2S for SPDIF bck:%d ws:%d do:%d", i2s_pin_config.bck_io_num,
ESP_LOGI(TAG, "Cannot initialize I2S for DAC bck:%d ws:%d do:%d", i2s_pin_config.bck_io_num,
i2s_pin_config.ws_io_num,
i2s_pin_config.data_out_num);
return false;
}
#else
return true;
#endif
}

View File

@@ -53,6 +53,7 @@ sure that using rate_delay would fix that
#include "monitor.h"
#include "config.h"
#include "accessors.h"
#include "globdefs.h"
#define LOCK mutex_lock(outputbuf->mutex)
#define UNLOCK mutex_unlock(outputbuf->mutex)
@@ -112,16 +113,6 @@ static void *output_thread_i2s_stats(void *arg);
static void spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst, size_t *count);
static void (*jack_handler_chain)(bool inserted);
// force all GPIOs to what we need
#undef CONFIG_I2S_NUM
#define CONFIG_I2S_NUM 0
#ifdef CONFIG_SQUEEZEAMP
#undef CONFIG_SPDIF_DO_IO
#define CONFIG_SPDIF_DO_IO 15
#elif defined CONFIG_A1S
#endif
#define I2C_PORT 0
/****************************************************************************************
@@ -212,13 +203,9 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
if (strcasestr(device, "spdif")) {
spdif = true;
#ifdef CONFIG_SQUEEZEAMP
i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = 33, .ws_io_num = 25,
.data_out_num = CONFIG_SPDIF_DO_IO, .data_in_num = -1 };
#else
i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = CONFIG_SPDIF_BCK_IO, .ws_io_num = CONFIG_SPDIF_WS_IO,
.data_out_num = CONFIG_SPDIF_DO_IO, .data_in_num = -1 };
#ifndef CONFIG_SPDIF_LOCKED
char *nvs_item = config_alloc_get(NVS_TYPE_STR, "spdif_config");
if (nvs_item) {
if ((p = strcasestr(nvs_item, "bck")) != NULL) i2s_pin_config.bck_io_num = atoi(strchr(p, '=') + 1);
@@ -226,13 +213,13 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
if ((p = strcasestr(nvs_item, "do")) != NULL) i2s_pin_config.data_out_num = atoi(strchr(p, '=') + 1);
free(nvs_item);
}
#endif
if (i2s_pin_config.bck_io_num == -1 || i2s_pin_config.ws_io_num == -1 || i2s_pin_config.data_out_num == -1) {
LOG_WARN("Cannot initialize I2S for SPDIF bck:%d ws:%d do:%d", i2s_pin_config.bck_io_num,
i2s_pin_config.ws_io_num,
i2s_pin_config.data_out_num);
}
#endif
i2s_config.sample_rate = output.current_sample_rate * 2;
i2s_config.bits_per_sample = 32;
@@ -249,14 +236,15 @@ void output_init_i2s(log_level level, char *device, unsigned output_buf_size, ch
i2s_set_pin(CONFIG_I2S_NUM, &i2s_pin_config);
LOG_INFO("SPDIF using I2S bck:%u, ws:%u, do:%u", i2s_pin_config.bck_io_num, i2s_pin_config.ws_io_num, i2s_pin_config.data_out_num);
} else {
#ifdef CONFIG_SQUEEZEAMP
#if CONFIG_SPDIF_DO_IO != -1
gpio_pad_select_gpio(CONFIG_SPDIF_DO_IO);
gpio_set_direction(CONFIG_SPDIF_DO_IO, GPIO_MODE_OUTPUT);
gpio_set_level(CONFIG_SPDIF_DO_IO, 0);
adac = &dac_tas57xx;
#elif defined(CONFIG_A1S)
adac = &dac_a1s;
#endif
#endif
// not very pretty ...
adac = &ADAC;
i2s_config.sample_rate = output.current_sample_rate;
i2s_config.bits_per_sample = bytes_per_frame * 8 / 2;
// Counted in frames (but i2s allocates a buffer <= 4092 bytes)

View File

@@ -119,8 +119,8 @@ static bool init(int i2c_port_num, int i2s_num, i2s_config_t *i2s_config) {
i2c_cmd_link_delete(i2c_cmd);
// configure I2S pins & install driver
i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = 33, .ws_io_num = 25,
.data_out_num = 32, .data_in_num = -1 //Not used
i2s_pin_config_t i2s_pin_config = (i2s_pin_config_t) { .bck_io_num = CONFIG_I2S_BCK_IO, .ws_io_num = CONFIG_I2S_WS_IO,
.data_out_num = CONFIG_I2S_DO_IO, .data_in_num = CONFIG_I2S_DI_IO,
};
i2s_driver_install(i2s_num, i2s_config, 0, NULL);
i2s_set_pin(i2s_num, &i2s_pin_config);

View File

@@ -382,6 +382,7 @@
<li>jQuery, The jQuery Foundation. Licensed under the MIT License.</li>
<li>cJSON, &copy; 2009-2017, Dave Gamble and cJSON contributors. Licensed under the MIT License.</li>
<li>esp32-rotary-encoder, &copy; 2011-2019, David Antliff and Ben Buxton. Licensed under the GPL License.</li>
<li>tarablessd1306, &copy; 2017-2018, Tara Keeling. Licensed under the MIT license.</li>
</ul>
</div>
<h2>Show NVS Editor</h2>

View File

@@ -21,99 +21,100 @@ menu "Squeezelite-ESP32"
help
Set logging level info|debug|sdebug
endmenu
menu "Audio CODEC libraries"
config INCLUDE_FLAC
bool "FLAC"
default 1
help
Include FLAC library for flc decoding.
config INCLUDE_FAAD
bool "FAAD"
default 1
help
Include FAAD library for aac decoding.
config INCLUDE_MAD
bool "MAD"
default 1
help
Include mad library for mp3 decoding.
config INCLUDE_VORBIS
bool "VORBIS"
default 1
help
Include vorbis/ogg library for ogg/vorbis decoding.
config INCLUDE_ALAC
bool "ALAC"
default 1
help
Include alac library for alac decoding.
config INCLUDE_OPUS
bool "OPUS"
default 1
help
Include opus library for opus decoding.
endmenu
menu "Audio Output"
config JACK_LOCKED
bool
config BAT_LOCKED
bool
config I2C_LOCKED
bool
config SPDIF_LOCKED
bool
menu "Audio Output"
choice OUTPUT_TYPE
prompt "Output Type"
prompt "Output Type"
default BASIC_I2C_BT
help
Type of hardware platform
config SQUEEZEAMP
bool "SqueezeAMP (TAS575x & Bluetooth)"
bool "SqueezeAMP"
select JACK_LOCKED
select BAT_LOCKED
select I2C_LOCKED
select SPDIF_LOCKED
config A1S
bool "ESP32-A1S module"
select I2C_LOCKED
config BASIC_I2C_BT
bool "Generic I2S & Bluetooth"
endchoice
menu "DAC I2S settings"
depends on BASIC_I2C_BT
config I2S_NUM
visible if !SQUEEZEAMP && !A1S
config I2S_NUM
int "I2S channel (0 or 1). "
default 0
help
I2S dma channel to use.
config I2S_BCK_IO
int "I2S Bit clock GPIO number. "
default 33
default 33 if !A1S
default 27 if A1S
help
I2S Bit Clock gpio pin to use.
config I2S_WS_IO
int "I2S Word Select GPIO number. "
default 25
default 25 if !A1S
default 26 if A1S
help
I2S Word Select gpio pin to use.
config I2S_DO_IO
int "I2S Data I/O GPIO number. "
default 32
int "I2S Data Output GPIO number. "
default 32 if !A1S
default 25 if A1S
help
I2S data I/O gpio pin to use.
I2S data output gpio pin to use.
config I2S_DI_IO
int "I2S Data Input GPIO number. "
default -1 if !A1S
default 35 if A1S
help
I2S data input gpio pin to use (not used mostly, leave it to -1).
endmenu
menu "SPDIF settings"
depends on BASIC_I2C_BT || A1S
config SDIF_NUM
int "SDPIF/I2S channel (0 or 1)"
default 0
visible if !SQUEEZEAMP && !A1S
config SDIF_NUM
int "I2S channel for SDPIF (0 or 1)"
default 0
help
I2S dma channel to use.
config SPDIF_BCK_IO
int "SDPIF/I2S Bit clock GPIO number"
default -1
int "SDPIF Bit clock GPIO number"
default I2S_BCK_IO
help
Must be set even if you don't use SPDIF
Must be set as SPDIF re-uses I2S but only needs DO (recommendation: set it to I2S Bit clock value)
config SPDIF_WS_IO
int "SPDIF/I2S Word Select GPIO number"
default -1
int "SPDIF Word Select GPIO number"
default I2S_WS_IO
help
Must be set even if you don't use SPDIF
Must be set as SPDIF re-uses I2S but only needs DO (recommendation: set it to I2S Word select value)
config SPDIF_DO_IO
int "I2S Data I/O GPIO number"
default -1
help
Must be set even if you don't use SPDIF
int "SPDIF Data I/O GPIO number"
default 15 if SQUEEZEAMP
default I2S_DO_IO if !A1S
default -1 if A1S
help
I2S data output IO use to simulate SPDIF
endmenu
menu "SPDIF settings"
visible if A1S
config SPDIF_DO_IO
int "SPDIF Data I/O GPIO number"
default -1
help
I2S data output IO use to simulate SPDIF
endmenu
menu "A2DP settings"
@@ -179,11 +180,8 @@ menu "Squeezelite-ESP32"
default ""
help
Set parameters for display screen, leave empty for no screen
I2C,width=<size>,height=<size>
SPI,width=<size>,height=<size>,select=<gpio>
config DISPLAY_I2C_SPEED
int "I2C bus speed"
default 250000
I2C,width=<pixels>,height=<pixels>[address=<i2c_address>][,HFlip][,VFlip]
SPI,width=<pixels>,height=<pixels>,cs=<gpio>[,HFlip][,VFlip]
endmenu
menu "Various I/O"
@@ -192,26 +190,64 @@ menu "Squeezelite-ESP32"
default ""
help
Set parameters of shared I2C interface
sda=<gpio>,scl=<gpio>,speed=<num>,port=<0|1>
sda=<gpio>,scl=<gpio>[,speed=<num>][,port=<0|1>]
config SPI_CONFIG
string "SPI system configuration"
default ""
help
Set parameters of shared SPI interface
data=<gpio>,clk=<gpio>[,d/c=<num>][,host=<0|1|2>]
config SET_GPIO
string "Special GPIO configuration"
default ""
help
Set parameters of shared GPIO with special values.
<gpio_1>=Vcc|GND|amp|jack_h|jack_l[,<gpio_n>=Vcc|GND|amp|jack_h|jack_l]
'amp' means a GPIO that is set when playback starts
'jack_h' means the audio_gpio insertion detection (1=inserted, use 'jack_l' when 0=inserted) - see also "Jack Insertion GPIO"
config ROTARY_ENCODER
string "Rotary Encoder configuration"
default ""
help
Set GPIO for rotary encoder (quadrature phase). See README on SqueezeESP32 project's GitHub for more details
A=<gpio>,B=<gpio>[,SW=gpio>[,volume][,longpress]]
endmenu
menu "LED configuration"
visible if !SQUEEZEAMP
config LED_GREEN_GPIO
int "Green led GPIO"
default -1
default -1 if !SQUEEZEAMP
default 12 if SQUEEZEAMP
help
Set to -1 for no LED
config LED_RED_GPIO
int "Red led GPIO"
default -1
default -1 if !SQUEEZEAMP
default 13 if SQUEEZEAMP
help
Set to -1 for no LED
config JACK_GPIO
endmenu
menu "Audio JACK"
visible if !SQUEEZEAMP
config JACK_GPIO
int "Jack insertion GPIO"
default -1
default -1 if !SQUEEZEAMP
default 34 if SQUEEZEAMP
help
GPIO to detect speaker jack insertion. Set to -1 for no detection
GPIO to detect speaker jack insertion. Set to -1 for no detection. This takes precedence over runtime jack GPIO
config JACK_GPIO_LEVEL
depends on JACK_GPIO != -1
int "Level when inserted (0/1)"
default 0
endmenu
menu "Battery measure"
visible if !SQUEEZEAMP
config BAT_CONFIG
string "Set channel and scale"
default "" if !SQUEEZEAMP
default "channel=7,scale=20.24" if SQUEEZEAMP
help
Read a value every 10s on ADC1. Configuration format: channel=0..7,scale=<scale>
endmenu
endmenu

View File

@@ -282,8 +282,8 @@ void register_default_nvs(){
ESP_LOGD(TAG,"Registering default Audio control board type %s, value ","actrls_config");
config_set_default(NVS_TYPE_STR, "actrls_config", "", 0);
ESP_LOGD(TAG,"Registering default Audio control board type %s, value ","rotary_config");
config_set_default(NVS_TYPE_STR, "rotary_config", "", 0);
ESP_LOGD(TAG,"Registering default Audio control board type %s, value %s", "rotary_config", CONFIG_ROTARY_ENCODER);
config_set_default(NVS_TYPE_STR, "rotary_config", CONFIG_ROTARY_ENCODER, 0);
char number_buffer[101] = {};
snprintf(number_buffer,sizeof(number_buffer)-1,"%u",OTA_FLASH_ERASE_BLOCK);
@@ -304,15 +304,27 @@ void register_default_nvs(){
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "enable_airplay", STR(CONFIG_AIRPLAY_SINK));
config_set_default(NVS_TYPE_STR, "enable_airplay", STR(CONFIG_AIRPLAY_SINK), 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "display_config", STR(CONFIG_DISPLAY_CONFIG));
config_set_default(NVS_TYPE_STR, "display_config", STR(CONFIG_DISPLAY_CONFIG), 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "display_config", CONFIG_DISPLAY_CONFIG);
config_set_default(NVS_TYPE_STR, "display_config", CONFIG_DISPLAY_CONFIG, 0);
ESP_LOGD(TAG,"Registering default value for key %s", "i2c_config");
config_set_default(NVS_TYPE_STR, "i2c_config", "", 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "i2c_config", CONFIG_I2C_CONFIG);
config_set_default(NVS_TYPE_STR, "i2c_config", CONFIG_I2C_CONFIG, 0);
ESP_LOGD(TAG,"Registering default value for key %s", "set_GPIO");
config_set_default(NVS_TYPE_STR, "set_GPIO", "", 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "spi_config", CONFIG_SPI_CONFIG);
config_set_default(NVS_TYPE_STR, "spi_config", CONFIG_SPI_CONFIG, 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "set_GPIO", CONFIG_SET_GPIO);
config_set_default(NVS_TYPE_STR, "set_GPIO", CONFIG_SET_GPIO, 0);
ESP_LOGD(TAG,"Registering default value for key %s", "spdif_config");
config_set_default(NVS_TYPE_STR, "spdif_config", "", 0);
ESP_LOGD(TAG,"Registering default value for key %s", "dac_config");
config_set_default(NVS_TYPE_STR, "dac_config", "", 0);
ESP_LOGD(TAG,"Registering default value for key %s, value %s", "bat_config", CONFIG_BAT_CONFIG);
config_set_default(NVS_TYPE_STR, "bat_config", CONFIG_BAT_CONFIG, 0);
ESP_LOGD(TAG,"Registering default value for key %s", "metadata_config");
config_set_default(NVS_TYPE_STR, "metadata_config", "", 0);
@@ -328,12 +340,6 @@ void register_default_nvs(){
ESP_LOGD(TAG,"Registering default value for key %s", "stats");
config_set_default(NVS_TYPE_STR, "stats", "n", 0);
ESP_LOGD(TAG,"Registering default value for key %s", "spdif_config");
config_set_default(NVS_TYPE_STR, "spdif_config", "", 0);
ESP_LOGD(TAG,"Registering default value for key %s", "dac_config");
config_set_default(NVS_TYPE_STR, "dac_config", "", 0);
ESP_LOGD(TAG,"Done setting default values in nvs.");
}