add display + some refactoring

This commit is contained in:
philippe44
2020-01-10 12:32:50 -08:00
parent daef63fdea
commit 450943735b
49 changed files with 4434 additions and 58 deletions

View File

@@ -0,0 +1,132 @@
/**
* 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/i2c.h>
#include <driver/gpio.h>
#include "ssd1306.h"
#include "ssd1306_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 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 );
/*
* Initializes the i2c master with the parameters specified
* in the component configuration in sdkconfig.h.
*
* Returns true on successful init of the i2c bus.
*/
bool SSD1306_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
i2c_config_t Config;
memset( &Config, 0, sizeof( i2c_config_t ) );
Config.mode = I2C_MODE_MASTER;
Config.sda_io_num = SDA;
Config.sda_pullup_en = GPIO_PULLUP_ENABLE;
Config.scl_io_num = SCL;
Config.scl_pullup_en = GPIO_PULLUP_ENABLE;
Config.master.clk_speed = I2CDisplaySpeed;
I2CPortNumber = PortNumber;
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 );
return true;
}
/*
* 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 ) {
NullCheck( DisplayHandle, 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,
Width,
Height,
I2CAddress,
RSTPin,
I2CDefaultWriteCommand,
I2CDefaultWriteData,
I2CDefaultReset
);
}
static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength ) {
i2c_cmd_handle_t* CommandHandle = NULL;
static uint8_t ModeByte = 0;
NullCheck( Data, return false );
if ( ( CommandHandle = i2c_cmd_link_create( ) ) != NULL ) {
ModeByte = ( IsCommand == true ) ? SSD1306_I2C_COMMAND_MODE: SSD1306_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_cmd_begin( I2CPortNumber, CommandHandle, pdMS_TO_TICKS( 1000 ) ), return false );
i2c_cmd_link_delete( CommandHandle );
}
return true;
}
static bool I2CDefaultWriteCommand( struct SSD1306_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 ) {
NullCheck( Display, return false );
NullCheck( Data, return false );
return I2CDefaultWriteBytes( Display->Address, false, Data, DataLength );
}
static bool I2CDefaultReset( struct SSD1306_Device* Display ) {
NullCheck( Display, return false );
if ( Display->RSTPin >= 0 ) {
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( Display->RSTPin, 0 ), return true );
vTaskDelay( pdMS_TO_TICKS( 100 ) );
ESP_ERROR_CHECK_NONFATAL( gpio_set_level( Display->RSTPin, 1 ), return true );
}
return true;
}

View File

@@ -0,0 +1,139 @@
/**
* 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