init commit
This commit is contained in:
4
main/CMakeLists.txt
Normal file
4
main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
set(COMPONENT_SRCS main.c ssd1306.c ssd1306_i2c.c ssd1306_spi.c)
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
register_component()
|
||||
265
main/Kconfig.projbuild
Normal file
265
main/Kconfig.projbuild
Normal file
@ -0,0 +1,265 @@
|
||||
menu "Ethernet Configuration"
|
||||
choice ETH_USE_ETHERNET
|
||||
prompt "Ethernet Type"
|
||||
default ETH_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32
|
||||
default ETH_USE_DM9051 if !IDF_TARGET_ESP32
|
||||
help
|
||||
Select which kind of Ethernet will be used in the example.
|
||||
|
||||
config ETH_USE_INTERNAL_ETHERNET
|
||||
depends on IDF_TARGET_ESP32
|
||||
select ETH_USE_ESP32_EMAC
|
||||
bool "Internal EMAC"
|
||||
help
|
||||
Select internal Ethernet MAC controller.
|
||||
|
||||
config ETH_USE_DM9051
|
||||
bool "DM9051 Module"
|
||||
select ETH_USE_SPI_ETHERNET
|
||||
select ETH_SPI_ETHERNET_DM9051
|
||||
help
|
||||
Select external SPI-Ethernet module (DM9051).
|
||||
|
||||
endchoice
|
||||
|
||||
if ETH_USE_INTERNAL_ETHERNET
|
||||
choice ETH_ETH_PHY_MODEL
|
||||
prompt "Ethernet PHY Device"
|
||||
default ETH_ETH_PHY_IP101
|
||||
help
|
||||
Select the Ethernet PHY device to use in the example.
|
||||
|
||||
config ETH_ETH_PHY_IP101
|
||||
bool "IP101"
|
||||
help
|
||||
IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver.
|
||||
Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it.
|
||||
|
||||
config ETH_ETH_PHY_RTL8201
|
||||
bool "RTL8201/SR8201"
|
||||
help
|
||||
RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
|
||||
Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
|
||||
|
||||
config ETH_ETH_PHY_LAN8720
|
||||
bool "LAN8720"
|
||||
help
|
||||
LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
|
||||
Goto https://www.microchip.com/LAN8720A for more information about it.
|
||||
|
||||
config ETH_ETH_PHY_DP83848
|
||||
bool "DP83848"
|
||||
help
|
||||
DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver.
|
||||
Goto http://www.ti.com/product/DP83848J for more information about it.
|
||||
endchoice
|
||||
|
||||
config ETH_ETH_MDC_GPIO
|
||||
int "SMI MDC GPIO number"
|
||||
default 23
|
||||
help
|
||||
Set the GPIO number used by SMI MDC.
|
||||
|
||||
config ETH_ETH_MDIO_GPIO
|
||||
int "SMI MDIO GPIO number"
|
||||
default 18
|
||||
help
|
||||
Set the GPIO number used by SMI MDIO.
|
||||
endif
|
||||
|
||||
if ETH_USE_DM9051
|
||||
config ETH_DM9051_SPI_HOST
|
||||
int "SPI Host Number"
|
||||
range 0 2
|
||||
default 1
|
||||
help
|
||||
Set the SPI host used to communicate with the SPI Ethernet Controller.
|
||||
|
||||
config ETH_DM9051_SCLK_GPIO
|
||||
int "SPI SCLK GPIO number"
|
||||
range 0 33
|
||||
default 19
|
||||
help
|
||||
Set the GPIO number used by SPI SCLK.
|
||||
|
||||
config ETH_DM9051_MOSI_GPIO
|
||||
int "SPI MOSI GPIO number"
|
||||
range 0 33
|
||||
default 23
|
||||
help
|
||||
Set the GPIO number used by SPI MOSI.
|
||||
|
||||
config ETH_DM9051_MISO_GPIO
|
||||
int "SPI MISO GPIO number"
|
||||
range 0 33
|
||||
default 25
|
||||
help
|
||||
Set the GPIO number used by SPI MISO.
|
||||
|
||||
config ETH_DM9051_CS_GPIO
|
||||
int "SPI CS GPIO number"
|
||||
range 0 33
|
||||
default 22
|
||||
help
|
||||
Set the GPIO number used by SPI CS.
|
||||
|
||||
config ETH_DM9051_SPI_CLOCK_MHZ
|
||||
int "SPI clock speed (MHz)"
|
||||
range 5 80
|
||||
default 20
|
||||
help
|
||||
Set the clock speed (MHz) of SPI interface.
|
||||
|
||||
config ETH_DM9051_INT_GPIO
|
||||
int "Interrupt GPIO number"
|
||||
default 4
|
||||
help
|
||||
Set the GPIO number used by DM9051 interrupt.
|
||||
endif
|
||||
|
||||
config ETH_ETH_PHY_RST_GPIO
|
||||
int "PHY Reset GPIO number"
|
||||
default 5
|
||||
help
|
||||
Set the GPIO number used to reset PHY chip.
|
||||
Set to -1 to disable PHY chip hardware reset.
|
||||
|
||||
config ETH_ETH_PHY_ADDR
|
||||
int "PHY Address"
|
||||
range 0 31 if ETH_USE_INTERNAL_ETHERNET
|
||||
range 1 1 if !ETH_USE_INTERNAL_ETHERNET
|
||||
default 1
|
||||
help
|
||||
Set PHY address according your board schematic.
|
||||
endmenu
|
||||
|
||||
menu "SSD1306 Configuration"
|
||||
|
||||
choice INTERFACE
|
||||
prompt "Interface"
|
||||
default I2C_INTERFACE
|
||||
help
|
||||
Select Interface.
|
||||
config I2C_INTERFACE
|
||||
bool "I2C Interface"
|
||||
help
|
||||
I2C Interface.
|
||||
config SPI_INTERFACE
|
||||
bool "SPI Interface"
|
||||
help
|
||||
SPI Interface.
|
||||
endchoice
|
||||
|
||||
choice PANEL
|
||||
prompt "Panel Type"
|
||||
default SSD1306_128x64
|
||||
help
|
||||
Select Panel Type.
|
||||
config SSD1306_128x32
|
||||
bool "128x32 Panel"
|
||||
help
|
||||
Panel is 128x32.
|
||||
config SSD1306_128x64
|
||||
bool "128x64 Panel"
|
||||
help
|
||||
Panel is 128x64.
|
||||
endchoice
|
||||
|
||||
config OFFSETX
|
||||
int "GRAM X OFFSET"
|
||||
range 0 99
|
||||
default 0
|
||||
help
|
||||
When your TFT have offset(X), set it.
|
||||
|
||||
config FLIP
|
||||
bool "Flip upside down"
|
||||
default false
|
||||
help
|
||||
Flip upside down.
|
||||
|
||||
config SCL_GPIO
|
||||
depends on I2C_INTERFACE
|
||||
int "SCL GPIO number"
|
||||
range 0 46
|
||||
default 22 if IDF_TARGET_ESP32
|
||||
default 12 if IDF_TARGET_ESP32S2
|
||||
default 9 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to I2C SCL.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config SDA_GPIO
|
||||
depends on I2C_INTERFACE
|
||||
int "SDA GPIO number"
|
||||
range 0 46
|
||||
default 21 if IDF_TARGET_ESP32
|
||||
default 11 if IDF_TARGET_ESP32S2
|
||||
default 10 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to I2C SDA.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to I2C.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config RESET_GPIO
|
||||
int "RESET GPIO number"
|
||||
range -1 46
|
||||
default -1
|
||||
help
|
||||
GPIO number (IOxx) to RESET.
|
||||
When it is -1, RESET isn't performed.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to Reset.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config MOSI_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "MOSI GPIO number"
|
||||
range 0 46
|
||||
default 23 if IDF_TARGET_ESP32
|
||||
default 35 if IDF_TARGET_ESP32S2
|
||||
default 0 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to SPI MOSI.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config SCLK_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "SCLK GPIO number"
|
||||
range 0 46
|
||||
default 18 if IDF_TARGET_ESP32
|
||||
default 36 if IDF_TARGET_ESP32S2
|
||||
default 1 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to SPI SCLK.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC.
|
||||
On the ESP32, GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
On the ESP32-S2, GPIO 46 is input-only so cannot be used as outputs.
|
||||
|
||||
config CS_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "CS GPIO number"
|
||||
range 0 34
|
||||
default 5 if IDF_TARGET_ESP32
|
||||
default 34 if IDF_TARGET_ESP32S2
|
||||
default 10 if IDF_TARGET_ESP32C3
|
||||
help
|
||||
GPIO number (IOxx) to SPI CS.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to CS.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
config DC_GPIO
|
||||
depends on SPI_INTERFACE
|
||||
int "DC GPIO number"
|
||||
range 0 34
|
||||
default 2
|
||||
help
|
||||
GPIO number (IOxx) to SPI DC.
|
||||
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to DC.
|
||||
GPIOs 35-39 are input-only so cannot be used as outputs.
|
||||
|
||||
|
||||
endmenu
|
||||
|
||||
4
main/component.mk
Normal file
4
main/component.mk
Normal file
@ -0,0 +1,4 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
174
main/font8x8_basic.h
Normal file
174
main/font8x8_basic.h
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* font8x8_basic.h
|
||||
*
|
||||
* Created on: 2017/05/03
|
||||
* Author: yanbe
|
||||
*/
|
||||
|
||||
#ifndef MAIN_FONT8X8_BASIC_H_
|
||||
#define MAIN_FONT8X8_BASIC_H_
|
||||
|
||||
/*
|
||||
Constant: font8x8_basic_tr
|
||||
Contains an 90 digree transposed 8x8 font map for unicode points
|
||||
U+0000 - U+007F (basic latin)
|
||||
|
||||
To make it easy to use with SSD1306's GDDRAM mapping and API,
|
||||
this constant is an 90 degree transposed.
|
||||
The original version written by Marcel Sondaar is availble at:
|
||||
https://github.com/dhepper/font8x8/blob/master/font8x8_basic.h
|
||||
|
||||
Conversion is done via following procedure:
|
||||
|
||||
for (int code = 0; code < 128; code++) {
|
||||
uint8_t trans[8];
|
||||
for (int w = 0; w < 8; w++) {
|
||||
trans[w] = 0x00;
|
||||
for (int b = 0; b < 8; b++) {
|
||||
trans[w] |= ((font8x8_basic[code][b] & (1 << w)) >> w) << b;
|
||||
}
|
||||
}
|
||||
|
||||
for (int w = 0; w < 8; w++) {
|
||||
if (w == 0) { printf(" { "); }
|
||||
printf("0x%.2X", trans[w]);
|
||||
if (w < 7) { printf(", "); }
|
||||
if (w == 7) { printf(" }, // U+00%.2X (%c)\n", code, code); }
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static uint8_t font8x8_basic_tr[128][8] = {
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0000 (nul)
|
||||
{ 0x00, 0x04, 0x02, 0xFF, 0x02, 0x04, 0x00, 0x00 }, // U+0001 (Up Allow)
|
||||
{ 0x00, 0x20, 0x40, 0xFF, 0x40, 0x20, 0x00, 0x00 }, // U+0002 (Down Allow)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0003
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0004
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0005
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0006
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0007
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0008
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0009
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000A
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000B
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000C
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000D
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000E
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000F
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0010
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0011
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0012
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0013
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0014
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0015
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0016
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0017
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0018
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0019
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001A
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001B
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001C
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001D
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001E
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001F
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0020 (space)
|
||||
{ 0x00, 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00 }, // U+0021 (!)
|
||||
{ 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00 }, // U+0022 (")
|
||||
{ 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 }, // U+0023 (#)
|
||||
{ 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00 }, // U+0024 ($)
|
||||
{ 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 }, // U+0025 (%)
|
||||
{ 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 }, // U+0026 (&)
|
||||
{ 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0027 (')
|
||||
{ 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00 }, // U+0028 (()
|
||||
{ 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00 }, // U+0029 ())
|
||||
{ 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 }, // U+002A (*)
|
||||
{ 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00 }, // U+002B (+)
|
||||
{ 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00 }, // U+002C (,)
|
||||
{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 }, // U+002D (-)
|
||||
{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }, // U+002E (.)
|
||||
{ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 }, // U+002F (/)
|
||||
{ 0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00 }, // U+0030 (0)
|
||||
{ 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 }, // U+0031 (1)
|
||||
{ 0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00 }, // U+0032 (2)
|
||||
{ 0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 }, // U+0033 (3)
|
||||
{ 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 }, // U+0034 (4)
|
||||
{ 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00 }, // U+0035 (5)
|
||||
{ 0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00 }, // U+0036 (6)
|
||||
{ 0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00 }, // U+0037 (7)
|
||||
{ 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 }, // U+0038 (8)
|
||||
{ 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00 }, // U+0039 (9)
|
||||
{ 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }, // U+003A (:)
|
||||
{ 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00 }, // U+003B (;)
|
||||
{ 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00 }, // U+003C (<)
|
||||
{ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00 }, // U+003D (=)
|
||||
{ 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 }, // U+003E (>)
|
||||
{ 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00 }, // U+003F (?)
|
||||
{ 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 }, // U+0040 (@)
|
||||
{ 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 }, // U+0041 (A)
|
||||
{ 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 }, // U+0042 (B)
|
||||
{ 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 }, // U+0043 (C)
|
||||
{ 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 }, // U+0044 (D)
|
||||
{ 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 }, // U+0045 (E)
|
||||
{ 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 }, // U+0046 (F)
|
||||
{ 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 }, // U+0047 (G)
|
||||
{ 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 }, // U+0048 (H)
|
||||
{ 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00 }, // U+0049 (I)
|
||||
{ 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 }, // U+004A (J)
|
||||
{ 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 }, // U+004B (K)
|
||||
{ 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 }, // U+004C (L)
|
||||
{ 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 }, // U+004D (M)
|
||||
{ 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 }, // U+004E (N)
|
||||
{ 0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00 }, // U+004F (O)
|
||||
{ 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 }, // U+0050 (P)
|
||||
{ 0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00 }, // U+0051 (Q)
|
||||
{ 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 }, // U+0052 (R)
|
||||
{ 0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00 }, // U+0053 (S)
|
||||
{ 0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00 }, // U+0054 (T)
|
||||
{ 0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00 }, // U+0055 (U)
|
||||
{ 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00 }, // U+0056 (V)
|
||||
{ 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00 }, // U+0057 (W)
|
||||
{ 0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00 }, // U+0058 (X)
|
||||
{ 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00 }, // U+0059 (Y)
|
||||
{ 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 }, // U+005A (Z)
|
||||
{ 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00 }, // U+005B ([)
|
||||
{ 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 }, // U+005C (\)
|
||||
{ 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00 }, // U+005D (])
|
||||
{ 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 }, // U+005E (^)
|
||||
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, // U+005F (_)
|
||||
{ 0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00 }, // U+0060 (`)
|
||||
{ 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 }, // U+0061 (a)
|
||||
{ 0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00 }, // U+0062 (b)
|
||||
{ 0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00 }, // U+0063 (c)
|
||||
{ 0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00 }, // U+0064 (d)
|
||||
{ 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00 }, // U+0065 (e)
|
||||
{ 0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00 }, // U+0066 (f)
|
||||
{ 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 }, // U+0067 (g)
|
||||
{ 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 }, // U+0068 (h)
|
||||
{ 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00 }, // U+0069 (i)
|
||||
{ 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00 }, // U+006A (j)
|
||||
{ 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 }, // U+006B (k)
|
||||
{ 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00 }, // U+006C (l)
|
||||
{ 0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00 }, // U+006D (m)
|
||||
{ 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00 }, // U+006E (n)
|
||||
{ 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00 }, // U+006F (o)
|
||||
{ 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 }, // U+0070 (p)
|
||||
{ 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 }, // U+0071 (q)
|
||||
{ 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00 }, // U+0072 (r)
|
||||
{ 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00 }, // U+0073 (s)
|
||||
{ 0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00 }, // U+0074 (t)
|
||||
{ 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 }, // U+0075 (u)
|
||||
{ 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00 }, // U+0076 (v)
|
||||
{ 0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00 }, // U+0077 (w)
|
||||
{ 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 }, // U+0078 (x)
|
||||
{ 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00 }, // U+0079 (y)
|
||||
{ 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00 }, // U+007A (z)
|
||||
{ 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00 }, // U+007B ({)
|
||||
{ 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00 }, // U+007C (|)
|
||||
{ 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00 }, // U+007D (})
|
||||
{ 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 }, // U+007E (~)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // U+007F
|
||||
};
|
||||
|
||||
#endif /* MAIN_FONT8X8_BASIC_H_ */
|
||||
|
||||
|
||||
381
main/main.c
Normal file
381
main/main.c
Normal file
@ -0,0 +1,381 @@
|
||||
/* Ethernet Basic Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_eth.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "driver/gpio.h"
|
||||
#include <driver/adc.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "ssd1306.h"
|
||||
#include "font8x8_basic.h"
|
||||
|
||||
static const char *TAG = "eth_tester";
|
||||
|
||||
#define IP_FSTRING "%3d.%3d.%3d.%3d"
|
||||
|
||||
#define SIGNAL_SHUTDOWN 1
|
||||
|
||||
#define LINE_STATUS_MAIN 0
|
||||
|
||||
#define LINE_ID_ADDR 2
|
||||
#define LINE_IP_SNM 3
|
||||
#define LINE_IP_GW 4
|
||||
|
||||
#define LINE_STATUS_FLAGS1 5
|
||||
#define LINE_STATUS_FLAGS2 6
|
||||
#define LINE_STATUS_FLAGS3 7
|
||||
|
||||
SSD1306_t display;
|
||||
uint8_t mac_addr[6] = {0};
|
||||
eth_event_t eth_state = ETHERNET_EVENT_STOP;
|
||||
esp_ip4_addr_t ip_addr;
|
||||
esp_ip4_addr_t ip_snm;
|
||||
esp_ip4_addr_t ip_gw;
|
||||
esp_netif_t *eth_netif;
|
||||
|
||||
bool dns_resolv = false;
|
||||
|
||||
bool blink_mod = false;
|
||||
|
||||
static uint8_t get_byte(uint32_t addr, int n)
|
||||
{
|
||||
return (addr >> (8 * n)) & 0xFF;
|
||||
}
|
||||
|
||||
#define IP4ZCHK(ipaddr) (esp_ip4_addr1_16(ipaddr) | esp_ip4_addr2_16(ipaddr) | esp_ip4_addr3_16(ipaddr) | esp_ip4_addr4_16(ipaddr))
|
||||
|
||||
static bool check_dns()
|
||||
{
|
||||
esp_netif_dns_info_t dns_info;
|
||||
ESP_ERROR_CHECK(esp_netif_get_dns_info(eth_netif, ESP_NETIF_DNS_MAIN, &dns_info));
|
||||
// ESP_LOGI(TAG, IP_FSTRING, IP2STR(&dns_info.ip.u_addr.ip4));
|
||||
// ESP_LOGI(TAG, "%d", IP4ZCHK(&dns_info.ip.u_addr.ip4));
|
||||
|
||||
if (IP4ZCHK(&dns_info.ip.u_addr.ip4) != 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void refresh_display()
|
||||
{
|
||||
char buf[64];
|
||||
int buflen;
|
||||
|
||||
switch (eth_state) {
|
||||
case ETHERNET_EVENT_CONNECTED:
|
||||
buflen = sprintf(buf, "%-16s", "LINK UP");
|
||||
// ssd1306_clear_line(&display, LINE_STATUS_MAIN, false);
|
||||
ssd1306_display_text(&display, LINE_STATUS_MAIN, buf, buflen, false, 0);
|
||||
// buflen = sprintf(buf, "MAC:%02X%02X%02X%02X%02X%02X",
|
||||
// mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
// ssd1306_clear_line(&display, 1, false);
|
||||
// ssd1306_display_text(&display, 1, buf, buflen, false, 0);
|
||||
break;
|
||||
case ETHERNET_EVENT_DISCONNECTED:
|
||||
buflen = sprintf(buf, "%-16s", "LINK DOWN");
|
||||
// ssd1306_clear_screen(&display, false);
|
||||
ssd1306_display_text(&display, LINE_STATUS_MAIN, buf, buflen, false, 0);
|
||||
ssd1306_clear_line(&display, LINE_ID_ADDR, false);
|
||||
ssd1306_clear_line(&display, LINE_IP_SNM, false);
|
||||
ssd1306_clear_line(&display, LINE_IP_GW, false);
|
||||
break;
|
||||
case ETHERNET_EVENT_START:
|
||||
buflen = sprintf(buf, "%-16s", "ETH RDY");
|
||||
// ssd1306_clear_screen(&display, false);
|
||||
ssd1306_display_text(&display, LINE_STATUS_MAIN, buf, buflen, false, 0);
|
||||
break;
|
||||
case ETHERNET_EVENT_STOP:
|
||||
buflen = sprintf(buf, "%-16s", "ETH DOWN");
|
||||
// ssd1306_clear_screen(&display, false);
|
||||
ssd1306_display_text(&display, LINE_STATUS_MAIN, buf, buflen, false, 0);
|
||||
ssd1306_clear_line(&display, LINE_ID_ADDR, false);
|
||||
ssd1306_clear_line(&display, LINE_IP_SNM, false);
|
||||
ssd1306_clear_line(&display, LINE_IP_GW, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ((eth_state == ETHERNET_EVENT_CONNECTED) & (ip_addr.addr != 0)){
|
||||
// ssd1306_clear_line(&display, 2, false);
|
||||
// ssd1306_display_text(&display, 2, "IP", 2, false, 0);
|
||||
|
||||
|
||||
buflen = sprintf(buf, IP_FSTRING, IP2STR(&ip_addr));
|
||||
//ssd1306_clear_line(&display, 3, false);
|
||||
ssd1306_display_text(&display, LINE_ID_ADDR, "I", 3, true, 0);
|
||||
ssd1306_display_text(&display, LINE_ID_ADDR, buf, buflen, false, 1);
|
||||
|
||||
|
||||
buflen = sprintf(buf, IP_FSTRING, IP2STR(&ip_snm));
|
||||
//ssd1306_clear_line(&display, 4, false);
|
||||
ssd1306_display_text(&display, LINE_IP_SNM, "S", 1, true, 0);
|
||||
ssd1306_display_text(&display, LINE_IP_SNM, buf, buflen, false, 1);
|
||||
|
||||
|
||||
buflen = sprintf(buf, IP_FSTRING, IP2STR(&ip_gw));
|
||||
//ssd1306_clear_line(&display, 5, false);
|
||||
ssd1306_display_text(&display, LINE_IP_GW, "G", 1, true, 0);
|
||||
ssd1306_display_text(&display, LINE_IP_GW, buf, buflen, false, 1);
|
||||
}
|
||||
|
||||
bool poe = (adc1_get_raw(ADC1_CHANNEL_3) > 2048); //arbitrary value, battery power is ~800
|
||||
bool eth = (eth_state == ETHERNET_EVENT_CONNECTED);
|
||||
bool addr = (ip_addr.addr != 0) & eth;
|
||||
bool dns = ((check_dns()) && addr && blink_mod) || dns_resolv;
|
||||
|
||||
ssd1306_display_text(&display, LINE_STATUS_FLAGS3, "POE", 3, poe, 13);
|
||||
ssd1306_display_text(&display, LINE_STATUS_FLAGS3, "LNK", 3, eth, 9);
|
||||
ssd1306_display_text(&display, LINE_STATUS_FLAGS3, "DHCP", 4, addr, 4);
|
||||
ssd1306_display_text(&display, LINE_STATUS_FLAGS3, "DNS", 3, dns, 0);
|
||||
}
|
||||
|
||||
/** Event handler for Ethernet events */
|
||||
static void eth_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
/* we can get the ethernet driver handle from event data */
|
||||
esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;
|
||||
|
||||
eth_state = event_id;
|
||||
|
||||
switch (event_id) {
|
||||
case ETHERNET_EVENT_CONNECTED:
|
||||
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
|
||||
ESP_LOGI(TAG, "Ethernet Link Up");
|
||||
ESP_LOGI(TAG, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
break;
|
||||
case ETHERNET_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "Link Down");
|
||||
break;
|
||||
case ETHERNET_EVENT_START:
|
||||
ESP_LOGI(TAG, "Ethernet Started");
|
||||
break;
|
||||
case ETHERNET_EVENT_STOP:
|
||||
ESP_LOGI(TAG, "Ethernet Stopped");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
refresh_display();
|
||||
}
|
||||
|
||||
/** Event handler for IP_EVENT_ETH_GOT_IP */
|
||||
static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
||||
const esp_netif_ip_info_t *ip_info = &event->ip_info;
|
||||
|
||||
ESP_LOGI(TAG, "Ethernet Got IP Address");
|
||||
ESP_LOGI(TAG, "~~~~~~~~~~~");
|
||||
ESP_LOGI(TAG, "ETHIP:" IPSTR, IP2STR(&ip_info->ip));
|
||||
ESP_LOGI(TAG, "ETHMASK:" IPSTR, IP2STR(&ip_info->netmask));
|
||||
ESP_LOGI(TAG, "ETHGW:" IPSTR, IP2STR(&ip_info->gw));
|
||||
ESP_LOGI(TAG, "~~~~~~~~~~~");
|
||||
|
||||
ip_addr = ip_info->ip;
|
||||
ip_snm = ip_info->netmask;
|
||||
ip_gw = ip_info->gw;
|
||||
|
||||
refresh_display();
|
||||
}
|
||||
|
||||
static xQueueHandle signal_queue = NULL;
|
||||
|
||||
static void IRAM_ATTR isr_shutdown(void* arg)
|
||||
{
|
||||
uint32_t sig = SIGNAL_SHUTDOWN;
|
||||
xQueueSendFromISR(signal_queue, &sig, NULL);
|
||||
}
|
||||
|
||||
static void task_signals(void* arg)
|
||||
{
|
||||
uint32_t sig;
|
||||
|
||||
for(;;) {
|
||||
if(xQueueReceive(signal_queue, &sig, portMAX_DELAY)) {
|
||||
if (sig == SIGNAL_SHUTDOWN) {
|
||||
ESP_LOGI(TAG, "Got shutdown trigger, going to sleep...");
|
||||
ssd1306_clear_screen(&display, false);
|
||||
esp_sleep_enable_ext0_wakeup(34, 0);
|
||||
esp_deep_sleep_start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define PIN_PHY_POWER 12
|
||||
void app_main(void)
|
||||
{
|
||||
// ###############################################################
|
||||
// # Display Configuration #
|
||||
// ###############################################################
|
||||
|
||||
|
||||
SSD1306_t dev;
|
||||
|
||||
#if CONFIG_I2C_INTERFACE
|
||||
ESP_LOGI(TAG, "INTERFACE is i2c");
|
||||
ESP_LOGI(TAG, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
|
||||
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
|
||||
#endif // CONFIG_I2C_INTERFACE
|
||||
|
||||
#if CONFIG_SPI_INTERFACE
|
||||
ESP_LOGI(TAG, "INTERFACE is SPI");
|
||||
ESP_LOGI(TAG, "CONFIG_MOSI_GPIO=%d",CONFIG_MOSI_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_SCLK_GPIO=%d",CONFIG_SCLK_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_CS_GPIO=%d",CONFIG_CS_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_DC_GPIO=%d",CONFIG_DC_GPIO);
|
||||
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
|
||||
spi_master_init(&dev, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
|
||||
#endif // CONFIG_SPI_INTERFACE
|
||||
|
||||
#if CONFIG_FLIP
|
||||
dev._flip = true;
|
||||
ESP_LOGW(TAG, "Flip upside down");
|
||||
#endif
|
||||
|
||||
#if CONFIG_SSD1306_128x64
|
||||
ESP_LOGI(TAG, "Panel is 128x64");
|
||||
ssd1306_init(&dev, 128, 64);
|
||||
#endif // CONFIG_SSD1306_128x64
|
||||
#if CONFIG_SSD1306_128x32
|
||||
ESP_LOGI(TAG, "Panel is 128x32");
|
||||
ssd1306_init(&dev, 128, 32);
|
||||
#endif // CONFIG_SSD1306_128x32
|
||||
|
||||
ssd1306_clear_screen(&dev, false);
|
||||
ssd1306_contrast(&dev, 0xff);
|
||||
|
||||
display = dev;
|
||||
|
||||
|
||||
// ###############################################################
|
||||
// # Ethernet Configuration #
|
||||
// ###############################################################
|
||||
|
||||
// Initialize TCP/IP network interface (should be called only once in application)
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
// Create default event loop that running in background
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
|
||||
eth_netif = esp_netif_new(&cfg);
|
||||
// Set default handlers to process TCP/IP stuffs
|
||||
ESP_ERROR_CHECK(esp_eth_set_default_handlers(eth_netif));
|
||||
// Register user defined event handers
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||
phy_config.phy_addr = CONFIG_ETH_ETH_PHY_ADDR;
|
||||
phy_config.reset_gpio_num = CONFIG_ETH_ETH_PHY_RST_GPIO;
|
||||
gpio_pad_select_gpio(PIN_PHY_POWER);
|
||||
gpio_set_direction(PIN_PHY_POWER,GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(PIN_PHY_POWER, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
#if CONFIG_ETH_USE_INTERNAL_ETHERNET
|
||||
mac_config.smi_mdc_gpio_num = CONFIG_ETH_ETH_MDC_GPIO;
|
||||
mac_config.smi_mdio_gpio_num = CONFIG_ETH_ETH_MDIO_GPIO;
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
|
||||
#if CONFIG_ETH_ETH_PHY_IP101
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
|
||||
#elif CONFIG_ETH_ETH_PHY_RTL8201
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
|
||||
#elif CONFIG_ETH_ETH_PHY_LAN8720
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config);
|
||||
#elif CONFIG_ETH_ETH_PHY_DP83848
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
|
||||
#endif
|
||||
#elif CONFIG_ETH_USE_DM9051
|
||||
gpio_install_isr_service(0);
|
||||
spi_device_handle_t spi_handle = NULL;
|
||||
spi_bus_config_t buscfg = {
|
||||
.miso_io_num = CONFIG_ETH_DM9051_MISO_GPIO,
|
||||
.mosi_io_num = CONFIG_ETH_DM9051_MOSI_GPIO,
|
||||
.sclk_io_num = CONFIG_ETH_DM9051_SCLK_GPIO,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_ETH_DM9051_SPI_HOST, &buscfg, 1));
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.command_bits = 1,
|
||||
.address_bits = 7,
|
||||
.mode = 0,
|
||||
.clock_speed_hz = CONFIG_ETH_DM9051_SPI_CLOCK_MHZ * 1000 * 1000,
|
||||
.spics_io_num = CONFIG_ETH_DM9051_CS_GPIO,
|
||||
.queue_size = 20
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_ETH_DM9051_SPI_HOST, &devcfg, &spi_handle));
|
||||
/* dm9051 ethernet driver is based on spi driver */
|
||||
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
|
||||
dm9051_config.int_gpio_num = CONFIG_ETH_DM9051_INT_GPIO;
|
||||
esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
|
||||
esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config);
|
||||
#endif
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
|
||||
esp_eth_handle_t eth_handle = NULL;
|
||||
ESP_ERROR_CHECK(esp_eth_driver_install(&config, ð_handle));
|
||||
/* attach Ethernet driver to TCP/IP stack */
|
||||
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
|
||||
/* start Ethernet driver state machine */
|
||||
ESP_ERROR_CHECK(esp_eth_start(eth_handle));
|
||||
|
||||
// ###############################################################
|
||||
// # Misc Configuration #
|
||||
// ###############################################################
|
||||
|
||||
// setup power in measurement (for PoE detection)
|
||||
adc1_config_width(ADC_WIDTH_12Bit);
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_11);
|
||||
|
||||
// gpio setup
|
||||
//zero-initialize the config structure.
|
||||
gpio_config_t io_conf = {};
|
||||
|
||||
//interrupt of rising edge
|
||||
io_conf.intr_type = GPIO_INTR_POSEDGE;
|
||||
//bit mask of the pins, here 34
|
||||
io_conf.pin_bit_mask = 1ULL<<34;
|
||||
//set as input mode
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
|
||||
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
||||
ESP_ERROR_CHECK(gpio_set_intr_type(34, GPIO_INTR_POSEDGE));
|
||||
|
||||
// interrut for shutdown/deep sleep
|
||||
ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LOWMED));
|
||||
ESP_ERROR_CHECK(gpio_isr_handler_add(34, isr_shutdown, NULL));
|
||||
|
||||
// signal task, to catch shutdown signal
|
||||
signal_queue = xQueueCreate(10, sizeof(uint32_t));
|
||||
//start signal task
|
||||
xTaskCreate(task_signals, "signals", 2048, NULL, 10, NULL);
|
||||
|
||||
|
||||
while (1) {
|
||||
blink_mod = !blink_mod;
|
||||
refresh_display();
|
||||
vTaskDelay(350 / portTICK_RATE_MS);
|
||||
}
|
||||
}
|
||||
229
main/ssd1306.c
Normal file
229
main/ssd1306.c
Normal file
@ -0,0 +1,229 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "ssd1306.h"
|
||||
#include "font8x8_basic.h"
|
||||
|
||||
#define TAG "SSD1306"
|
||||
|
||||
void ssd1306_init(SSD1306_t * dev, int width, int height)
|
||||
{
|
||||
if (dev->_address == SPIAddress) {
|
||||
spi_init(dev, width, height);
|
||||
} else {
|
||||
i2c_init(dev, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void ssd1306_display_text(SSD1306_t * dev, int page, char * text, int text_len, bool invert, int skip)
|
||||
{
|
||||
if (page >= dev->_pages) return;
|
||||
int _text_len = text_len;
|
||||
if (_text_len > 16) _text_len = 16;
|
||||
|
||||
uint8_t seg = 8*skip;
|
||||
uint8_t image[8];
|
||||
for (uint8_t i = 0; i < _text_len; i++) {
|
||||
memcpy(image, font8x8_basic_tr[(uint8_t)text[i]], 8);
|
||||
if (invert) ssd1306_invert(image, 8);
|
||||
if (dev->_flip) ssd1306_flip(image, 8);
|
||||
if (dev->_address == SPIAddress) {
|
||||
spi_display_image(dev, page, seg, image, 8);
|
||||
} else {
|
||||
i2c_display_image(dev, page, seg, image, 8);
|
||||
}
|
||||
seg = seg + 8;
|
||||
}
|
||||
}
|
||||
|
||||
void ssd1306_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width)
|
||||
{
|
||||
if (dev->_address == SPIAddress) {
|
||||
spi_display_image(dev, page, seg, images, width);
|
||||
} else {
|
||||
i2c_display_image(dev, page, seg, images, width);
|
||||
}
|
||||
}
|
||||
|
||||
void ssd1306_clear_screen(SSD1306_t * dev, bool invert)
|
||||
{
|
||||
char space[16];
|
||||
memset(space, 0x20, sizeof(space));
|
||||
for (int page = 0; page < dev->_pages; page++) {
|
||||
ssd1306_display_text(dev, page, space, sizeof(space), invert, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ssd1306_clear_line(SSD1306_t * dev, int page, bool invert)
|
||||
{
|
||||
char space[16];
|
||||
memset(space, 0x20, sizeof(space));
|
||||
ssd1306_display_text(dev, page, space, sizeof(space), invert, 0);
|
||||
}
|
||||
|
||||
void ssd1306_contrast(SSD1306_t * dev, int contrast)
|
||||
{
|
||||
if (dev->_address == SPIAddress) {
|
||||
spi_contrast(dev, contrast);
|
||||
} else {
|
||||
i2c_contrast(dev, contrast);
|
||||
}
|
||||
}
|
||||
|
||||
void ssd1306_software_scroll(SSD1306_t * dev, int start, int end)
|
||||
{
|
||||
ESP_LOGD(TAG, "software_scroll start=%d end=%d _pages=%d", start, end, dev->_pages);
|
||||
if (start < 0 || end < 0) {
|
||||
dev->_scEnable = false;
|
||||
} else if (start >= dev->_pages || end >= dev->_pages) {
|
||||
dev->_scEnable = false;
|
||||
} else {
|
||||
dev->_scEnable = true;
|
||||
dev->_scStart = start;
|
||||
dev->_scEnd = end;
|
||||
dev->_scDirection = 1;
|
||||
if (start > end ) dev->_scDirection = -1;
|
||||
for (int i=0;i<dev->_pages;i++) {
|
||||
dev->_page[i]._valid = false;
|
||||
dev->_page[i]._segLen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ssd1306_scroll_text(SSD1306_t * dev, char * text, int text_len, bool invert)
|
||||
{
|
||||
ESP_LOGD(TAG, "dev->_scEnable=%d", dev->_scEnable);
|
||||
if (dev->_scEnable == false) return;
|
||||
|
||||
void (*func)(SSD1306_t * dev, int page, int seg, uint8_t * images, int width);
|
||||
if (dev->_address == SPIAddress) {
|
||||
func = spi_display_image;
|
||||
} else {
|
||||
func = i2c_display_image;
|
||||
}
|
||||
|
||||
int srcIndex = dev->_scEnd - dev->_scDirection;
|
||||
while(1) {
|
||||
int dstIndex = srcIndex + dev->_scDirection;
|
||||
ESP_LOGD(TAG, "srcIndex=%d dstIndex=%d", srcIndex,dstIndex);
|
||||
dev->_page[dstIndex]._valid = dev->_page[srcIndex]._valid;
|
||||
dev->_page[dstIndex]._segLen = dev->_page[srcIndex]._segLen;
|
||||
for(int seg = 0; seg < dev->_width; seg++) {
|
||||
dev->_page[dstIndex]._segs[seg] = dev->_page[srcIndex]._segs[seg];
|
||||
}
|
||||
ESP_LOGD(TAG, "_valid=%d", dev->_page[dstIndex]._valid);
|
||||
if (dev->_page[dstIndex]._valid) (*func)(dev, dstIndex, 0, dev->_page[dstIndex]._segs, dev->_page[srcIndex]._segLen);
|
||||
if (srcIndex == dev->_scStart) break;
|
||||
srcIndex = srcIndex - dev->_scDirection;
|
||||
}
|
||||
|
||||
int _text_len = text_len;
|
||||
if (_text_len > 16) _text_len = 16;
|
||||
|
||||
uint8_t seg = 0;
|
||||
uint8_t image[8];
|
||||
for (uint8_t i = 0; i < _text_len; i++) {
|
||||
memcpy(image, font8x8_basic_tr[(uint8_t)text[i]], 8);
|
||||
if (invert) ssd1306_invert(image, 8);
|
||||
if (dev->_flip) ssd1306_flip(image, 8);
|
||||
(*func)(dev, srcIndex, seg, image, 8);
|
||||
for(int j=0;j<8;j++) dev->_page[srcIndex]._segs[seg+j] = image[j];
|
||||
seg = seg + 8;
|
||||
}
|
||||
dev->_page[srcIndex]._valid = true;
|
||||
dev->_page[srcIndex]._segLen = seg;
|
||||
}
|
||||
|
||||
void ssd1306_scroll_clear(SSD1306_t * dev)
|
||||
{
|
||||
ESP_LOGD(TAG, "dev->_scEnable=%d", dev->_scEnable);
|
||||
if (dev->_scEnable == false) return;
|
||||
|
||||
int srcIndex = dev->_scEnd - dev->_scDirection;
|
||||
while(1) {
|
||||
int dstIndex = srcIndex + dev->_scDirection;
|
||||
ESP_LOGD(TAG, "srcIndex=%d dstIndex=%d", srcIndex,dstIndex);
|
||||
ssd1306_clear_line(dev, dstIndex, false);
|
||||
dev->_page[dstIndex]._valid = false;
|
||||
if (dstIndex == dev->_scStart) break;
|
||||
srcIndex = srcIndex - dev->_scDirection;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ssd1306_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll)
|
||||
{
|
||||
if (dev->_address == SPIAddress) {
|
||||
spi_hardware_scroll(dev, scroll);
|
||||
} else {
|
||||
i2c_hardware_scroll(dev, scroll);
|
||||
}
|
||||
}
|
||||
|
||||
void ssd1306_invert(uint8_t *buf, size_t blen)
|
||||
{
|
||||
uint8_t wk;
|
||||
for(int i=0; i<blen; i++){
|
||||
wk = buf[i];
|
||||
buf[i] = ~wk;
|
||||
}
|
||||
}
|
||||
|
||||
// Flip upside down
|
||||
void ssd1306_flip(uint8_t *buf, size_t blen)
|
||||
{
|
||||
for(int i=0; i<blen; i++){
|
||||
buf[i] = ssd1306_rotate(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Rotate 8-bit data
|
||||
// 0x12-->0x48
|
||||
uint8_t ssd1306_rotate(uint8_t ch1) {
|
||||
uint8_t ch2 = 0;
|
||||
for (int j=0;j<8;j++) {
|
||||
ch2 = (ch2 << 1) + (ch1 & 0x01);
|
||||
ch1 = ch1 >> 1;
|
||||
}
|
||||
return ch2;
|
||||
}
|
||||
|
||||
|
||||
void ssd1306_fadeout(SSD1306_t * dev)
|
||||
{
|
||||
void (*func)(SSD1306_t * dev, int page, int seg, uint8_t * images, int width);
|
||||
if (dev->_address == SPIAddress) {
|
||||
func = spi_display_image;
|
||||
} else {
|
||||
func = i2c_display_image;
|
||||
}
|
||||
|
||||
uint8_t image[1];
|
||||
for(int page=0; page<dev->_pages; page++) {
|
||||
image[0] = 0xFF;
|
||||
for(int line=0; line<8; line++) {
|
||||
if (dev->_flip) {
|
||||
image[0] = image[0] >> 1;
|
||||
} else {
|
||||
image[0] = image[0] << 1;
|
||||
}
|
||||
for(int seg=0; seg<128; seg++) {
|
||||
(*func)(dev, page, seg, image, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ssd1306_dump(SSD1306_t dev)
|
||||
{
|
||||
printf("_address=%x\n",dev._address);
|
||||
printf("_width=%x\n",dev._width);
|
||||
printf("_height=%x\n",dev._height);
|
||||
printf("_pages=%x\n",dev._pages);
|
||||
}
|
||||
|
||||
135
main/ssd1306.h
Normal file
135
main/ssd1306.h
Normal file
@ -0,0 +1,135 @@
|
||||
#ifndef MAIN_SSD1306_H_
|
||||
#define MAIN_SSD1306_H_
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
// Following definitions are borrowed from
|
||||
// http://robotcantalk.blogspot.com/2015/03/interfacing-arduino-with-ssd1306-driven.html
|
||||
|
||||
/* Control byte for i2c
|
||||
Co : bit 8 : Continuation Bit
|
||||
* 1 = no-continuation (only one byte to follow)
|
||||
* 0 = the controller should expect a stream of bytes.
|
||||
D/C# : bit 7 : Data/Command Select bit
|
||||
* 1 = the next byte or byte stream will be Data.
|
||||
* 0 = a Command byte or byte stream will be coming up next.
|
||||
Bits 6-0 will be all zeros.
|
||||
Usage:
|
||||
0x80 : Single Command byte
|
||||
0x00 : Command Stream
|
||||
0xC0 : Single Data byte
|
||||
0x40 : Data Stream
|
||||
*/
|
||||
#define OLED_CONTROL_BYTE_CMD_SINGLE 0x80
|
||||
#define OLED_CONTROL_BYTE_CMD_STREAM 0x00
|
||||
#define OLED_CONTROL_BYTE_DATA_SINGLE 0xC0
|
||||
#define OLED_CONTROL_BYTE_DATA_STREAM 0x40
|
||||
|
||||
// Fundamental commands (pg.28)
|
||||
#define OLED_CMD_SET_CONTRAST 0x81 // follow with 0x7F
|
||||
#define OLED_CMD_DISPLAY_RAM 0xA4
|
||||
#define OLED_CMD_DISPLAY_ALLON 0xA5
|
||||
#define OLED_CMD_DISPLAY_NORMAL 0xA6
|
||||
#define OLED_CMD_DISPLAY_INVERTED 0xA7
|
||||
#define OLED_CMD_DISPLAY_OFF 0xAE
|
||||
#define OLED_CMD_DISPLAY_ON 0xAF
|
||||
|
||||
// Addressing Command Table (pg.30)
|
||||
#define OLED_CMD_SET_MEMORY_ADDR_MODE 0x20
|
||||
#define OLED_CMD_SET_HORI_ADDR_MODE 0x00 // Horizontal Addressing Mode
|
||||
#define OLED_CMD_SET_VERT_ADDR_MODE 0x01 // Vertical Addressing Mode
|
||||
#define OLED_CMD_SET_PAGE_ADDR_MODE 0x02 // Page Addressing Mode
|
||||
#define OLED_CMD_SET_COLUMN_RANGE 0x21 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x7F = COL127
|
||||
#define OLED_CMD_SET_PAGE_RANGE 0x22 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x07 = PAGE7
|
||||
|
||||
// Hardware Config (pg.31)
|
||||
#define OLED_CMD_SET_DISPLAY_START_LINE 0x40
|
||||
#define OLED_CMD_SET_SEGMENT_REMAP_0 0xA0
|
||||
#define OLED_CMD_SET_SEGMENT_REMAP_1 0xA1
|
||||
#define OLED_CMD_SET_MUX_RATIO 0xA8 // follow with 0x3F = 64 MUX
|
||||
#define OLED_CMD_SET_COM_SCAN_MODE 0xC8
|
||||
#define OLED_CMD_SET_DISPLAY_OFFSET 0xD3 // follow with 0x00
|
||||
#define OLED_CMD_SET_COM_PIN_MAP 0xDA // follow with 0x12
|
||||
#define OLED_CMD_NOP 0xE3 // NOP
|
||||
|
||||
// Timing and Driving Scheme (pg.32)
|
||||
#define OLED_CMD_SET_DISPLAY_CLK_DIV 0xD5 // follow with 0x80
|
||||
#define OLED_CMD_SET_PRECHARGE 0xD9 // follow with 0xF1
|
||||
#define OLED_CMD_SET_VCOMH_DESELCT 0xDB // follow with 0x30
|
||||
|
||||
// Charge Pump (pg.62)
|
||||
#define OLED_CMD_SET_CHARGE_PUMP 0x8D // follow with 0x14
|
||||
|
||||
// Scrolling Command
|
||||
#define OLED_CMD_HORIZONTAL_RIGHT 0x26
|
||||
#define OLED_CMD_HORIZONTAL_LEFT 0x27
|
||||
#define OLED_CMD_CONTINUOUS_SCROLL 0x29
|
||||
#define OLED_CMD_DEACTIVE_SCROLL 0x2E
|
||||
#define OLED_CMD_ACTIVE_SCROLL 0x2F
|
||||
#define OLED_CMD_VERTICAL 0xA3
|
||||
|
||||
#define I2CAddress 0x3C
|
||||
#define SPIAddress 0xFF
|
||||
|
||||
typedef enum {
|
||||
SCROLL_RIGHT = 1,
|
||||
SCROLL_LEFT = 2,
|
||||
SCROLL_DOWN = 3,
|
||||
SCROLL_UP = 4,
|
||||
SCROLL_STOP = 5
|
||||
} ssd1306_scroll_type_t;
|
||||
|
||||
typedef struct {
|
||||
bool _valid;
|
||||
int _segLen; // 0-128
|
||||
uint8_t _segs[128];
|
||||
} PAGE_t;
|
||||
|
||||
typedef struct {
|
||||
int _address;
|
||||
int _width;
|
||||
int _height;
|
||||
int _pages;
|
||||
int _dc;
|
||||
spi_device_handle_t _SPIHandle;
|
||||
bool _scEnable;
|
||||
int _scStart;
|
||||
int _scEnd;
|
||||
int _scDirection;
|
||||
PAGE_t _page[8];
|
||||
bool _flip;
|
||||
} SSD1306_t;
|
||||
|
||||
void ssd1306_init(SSD1306_t * dev, int width, int height);
|
||||
void ssd1306_display_text(SSD1306_t * dev, int page, char * text, int text_len, bool invert, int skip);
|
||||
void ssd1306_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width);
|
||||
void ssd1306_clear_screen(SSD1306_t * dev, bool invert);
|
||||
void ssd1306_clear_line(SSD1306_t * dev, int page, bool invert);
|
||||
void ssd1306_contrast(SSD1306_t * dev, int contrast);
|
||||
void ssd1306_software_scroll(SSD1306_t * dev, int start, int end);
|
||||
void ssd1306_scroll_text(SSD1306_t * dev, char * text, int text_len, bool invert);
|
||||
void ssd1306_scroll_clear(SSD1306_t * dev);
|
||||
void ssd1306_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll);
|
||||
void ssd1306_invert(uint8_t *buf, size_t blen);
|
||||
void ssd1306_flip(uint8_t *buf, size_t blen);
|
||||
uint8_t ssd1306_rotate(uint8_t ch1);
|
||||
void ssd1306_fadeout(SSD1306_t * dev);
|
||||
void ssd1306_dump(SSD1306_t dev);
|
||||
|
||||
void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset);
|
||||
void i2c_init(SSD1306_t * dev, int width, int height);
|
||||
void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width);
|
||||
void i2c_contrast(SSD1306_t * dev, int contrast);
|
||||
void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll);
|
||||
|
||||
void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET);
|
||||
bool spi_master_write_byte(spi_device_handle_t SPIHandle, const uint8_t* Data, size_t DataLength );
|
||||
bool spi_master_write_command(SSD1306_t * dev, uint8_t Command );
|
||||
bool spi_master_write_data(SSD1306_t * dev, const uint8_t* Data, size_t DataLength );
|
||||
void spi_init(SSD1306_t * dev, int width, int height);
|
||||
void spi_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width);
|
||||
void spi_contrast(SSD1306_t * dev, int contrast);
|
||||
void spi_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll);
|
||||
|
||||
#endif /* MAIN_SSD1306_H_ */
|
||||
|
||||
242
main/ssd1306_i2c.c
Normal file
242
main/ssd1306_i2c.c
Normal file
@ -0,0 +1,242 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "ssd1306.h"
|
||||
|
||||
#define tag "SSD1306"
|
||||
|
||||
void i2c_master_init(SSD1306_t * dev, int16_t sda, int16_t scl, int16_t reset)
|
||||
{
|
||||
i2c_config_t i2c_config = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_io_num = sda,
|
||||
.scl_io_num = scl,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 1000000
|
||||
};
|
||||
i2c_param_config(I2C_NUM_0, &i2c_config);
|
||||
i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
|
||||
|
||||
if (reset >= 0) {
|
||||
//gpio_pad_select_gpio(reset);
|
||||
gpio_reset_pin(reset);
|
||||
gpio_set_direction(reset, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(reset, 0);
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(reset, 1);
|
||||
}
|
||||
dev->_address = I2CAddress;
|
||||
dev->_flip = false;
|
||||
}
|
||||
|
||||
void i2c_init(SSD1306_t * dev, int width, int height) {
|
||||
dev->_width = width;
|
||||
dev->_height = height;
|
||||
dev->_pages = 8;
|
||||
if (dev->_height == 32) dev->_pages = 4;
|
||||
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_OFF, true); // AE
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_MUX_RATIO, true); // A8
|
||||
if (dev->_height == 64) i2c_master_write_byte(cmd, 0x3F, true);
|
||||
if (dev->_height == 32) i2c_master_write_byte(cmd, 0x1F, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_OFFSET, true); // D3
|
||||
i2c_master_write_byte(cmd, 0x00, true);
|
||||
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true); // 40
|
||||
//i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP, true); // A1
|
||||
if (dev->_flip) {
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP_0, true); // A0
|
||||
} else {
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP_1, true); // A1
|
||||
}
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE, true); // C8
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_DISPLAY_CLK_DIV, true); // D5
|
||||
i2c_master_write_byte(cmd, 0x80, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_COM_PIN_MAP, true); // DA
|
||||
if (dev->_height == 64) i2c_master_write_byte(cmd, 0x12, true);
|
||||
if (dev->_height == 32) i2c_master_write_byte(cmd, 0x02, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true); // 81
|
||||
i2c_master_write_byte(cmd, 0xFF, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_RAM, true); // A4
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_VCOMH_DESELCT, true); // DB
|
||||
i2c_master_write_byte(cmd, 0x40, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_MEMORY_ADDR_MODE, true); // 20
|
||||
//i2c_master_write_byte(cmd, OLED_CMD_SET_HORI_ADDR_MODE, true); // 00
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_PAGE_ADDR_MODE, true); // 02
|
||||
// Set Lower Column Start Address for Page Addressing Mode
|
||||
i2c_master_write_byte(cmd, 0x00, true);
|
||||
// Set Higher Column Start Address for Page Addressing Mode
|
||||
i2c_master_write_byte(cmd, 0x10, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP, true); // 8D
|
||||
i2c_master_write_byte(cmd, 0x14, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_DEACTIVE_SCROLL, true); // 2E
|
||||
i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_NORMAL, true); // A6
|
||||
i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true); // AF
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
|
||||
esp_err_t espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
||||
if (espRc == ESP_OK) {
|
||||
ESP_LOGI(tag, "OLED configured successfully");
|
||||
} else {
|
||||
ESP_LOGE(tag, "OLED configuration failed. code: 0x%.2X", espRc);
|
||||
}
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
|
||||
void i2c_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width) {
|
||||
i2c_cmd_handle_t cmd;
|
||||
|
||||
if (page >= dev->_pages) return;
|
||||
if (seg >= dev->_width) return;
|
||||
|
||||
int _seg = seg + CONFIG_OFFSETX;
|
||||
uint8_t columLow = _seg & 0x0F;
|
||||
uint8_t columHigh = (_seg >> 4) & 0x0F;
|
||||
|
||||
int _page = page;
|
||||
if (dev->_flip) {
|
||||
_page = (dev->_pages - page) - 1;
|
||||
}
|
||||
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true);
|
||||
|
||||
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
||||
// Set Lower Column Start Address for Page Addressing Mode
|
||||
i2c_master_write_byte(cmd, (0x00 + columLow), true);
|
||||
// Set Higher Column Start Address for Page Addressing Mode
|
||||
i2c_master_write_byte(cmd, (0x10 + columHigh), true);
|
||||
// Set Page Start Address for Page Addressing Mode
|
||||
i2c_master_write_byte(cmd, 0xB0 | _page, true);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true);
|
||||
|
||||
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true);
|
||||
i2c_master_write(cmd, images, width, true);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
void i2c_contrast(SSD1306_t * dev, int contrast) {
|
||||
i2c_cmd_handle_t cmd;
|
||||
int _contrast = contrast;
|
||||
if (contrast < 0x0) _contrast = 0;
|
||||
if (contrast > 0xFF) _contrast = 0xFF;
|
||||
|
||||
cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true); // 81
|
||||
i2c_master_write_byte(cmd, _contrast, true);
|
||||
i2c_master_stop(cmd);
|
||||
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
|
||||
void i2c_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll) {
|
||||
esp_err_t espRc;
|
||||
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
|
||||
i2c_master_write_byte(cmd, (dev->_address << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
||||
|
||||
if (scroll == SCROLL_RIGHT) {
|
||||
i2c_master_write_byte(cmd, OLED_CMD_HORIZONTAL_RIGHT, true); // 26
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Dummy byte
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Define start page address
|
||||
i2c_master_write_byte(cmd, 0x07, true); // Frame frequency
|
||||
i2c_master_write_byte(cmd, 0x07, true); // Define end page address
|
||||
i2c_master_write_byte(cmd, 0x00, true); //
|
||||
i2c_master_write_byte(cmd, 0xFF, true); //
|
||||
i2c_master_write_byte(cmd, OLED_CMD_ACTIVE_SCROLL, true); // 2F
|
||||
}
|
||||
|
||||
if (scroll == SCROLL_LEFT) {
|
||||
i2c_master_write_byte(cmd, OLED_CMD_HORIZONTAL_LEFT, true); // 27
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Dummy byte
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Define start page address
|
||||
i2c_master_write_byte(cmd, 0x07, true); // Frame frequency
|
||||
i2c_master_write_byte(cmd, 0x07, true); // Define end page address
|
||||
i2c_master_write_byte(cmd, 0x00, true); //
|
||||
i2c_master_write_byte(cmd, 0xFF, true); //
|
||||
i2c_master_write_byte(cmd, OLED_CMD_ACTIVE_SCROLL, true); // 2F
|
||||
}
|
||||
|
||||
if (scroll == SCROLL_DOWN) {
|
||||
i2c_master_write_byte(cmd, OLED_CMD_CONTINUOUS_SCROLL, true); // 29
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Dummy byte
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Define start page address
|
||||
i2c_master_write_byte(cmd, 0x07, true); // Frame frequency
|
||||
//i2c_master_write_byte(cmd, 0x01, true); // Define end page address
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Define end page address
|
||||
i2c_master_write_byte(cmd, 0x3F, true); // Vertical scrolling offset
|
||||
|
||||
i2c_master_write_byte(cmd, OLED_CMD_VERTICAL, true); // A3
|
||||
i2c_master_write_byte(cmd, 0x00, true);
|
||||
if (dev->_height == 64)
|
||||
//i2c_master_write_byte(cmd, 0x7F, true);
|
||||
i2c_master_write_byte(cmd, 0x40, true);
|
||||
if (dev->_height == 32)
|
||||
i2c_master_write_byte(cmd, 0x20, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_ACTIVE_SCROLL, true); // 2F
|
||||
}
|
||||
|
||||
if (scroll == SCROLL_UP) {
|
||||
i2c_master_write_byte(cmd, OLED_CMD_CONTINUOUS_SCROLL, true); // 29
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Dummy byte
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Define start page address
|
||||
i2c_master_write_byte(cmd, 0x07, true); // Frame frequency
|
||||
//i2c_master_write_byte(cmd, 0x01, true); // Define end page address
|
||||
i2c_master_write_byte(cmd, 0x00, true); // Define end page address
|
||||
i2c_master_write_byte(cmd, 0x01, true); // Vertical scrolling offset
|
||||
|
||||
i2c_master_write_byte(cmd, OLED_CMD_VERTICAL, true); // A3
|
||||
i2c_master_write_byte(cmd, 0x00, true);
|
||||
if (dev->_height == 64)
|
||||
//i2c_master_write_byte(cmd, 0x7F, true);
|
||||
i2c_master_write_byte(cmd, 0x40, true);
|
||||
if (dev->_height == 32)
|
||||
i2c_master_write_byte(cmd, 0x20, true);
|
||||
i2c_master_write_byte(cmd, OLED_CMD_ACTIVE_SCROLL, true); // 2F
|
||||
}
|
||||
|
||||
if (scroll == SCROLL_STOP) {
|
||||
i2c_master_write_byte(cmd, OLED_CMD_DEACTIVE_SCROLL, true); // 2E
|
||||
}
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
||||
if (espRc == ESP_OK) {
|
||||
ESP_LOGD(tag, "Scroll command succeeded");
|
||||
} else {
|
||||
ESP_LOGE(tag, "Scroll command failed. code: 0x%.2X", espRc);
|
||||
}
|
||||
|
||||
i2c_cmd_link_delete(cmd);
|
||||
}
|
||||
|
||||
253
main/ssd1306_spi.c
Normal file
253
main/ssd1306_spi.c
Normal file
@ -0,0 +1,253 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "ssd1306.h"
|
||||
|
||||
#define TAG "SSD1306"
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define LCD_HOST HSPI_HOST
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
#define LCD_HOST SPI2_HOST
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32C3
|
||||
#define LCD_HOST SPI2_HOST
|
||||
#endif
|
||||
|
||||
static const int SPI_Command_Mode = 0;
|
||||
static const int SPI_Data_Mode = 1;
|
||||
static const int SPI_Frequency = 1000000;
|
||||
|
||||
void spi_master_init(SSD1306_t * dev, int16_t GPIO_MOSI, int16_t GPIO_SCLK, int16_t GPIO_CS, int16_t GPIO_DC, int16_t GPIO_RESET)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
//gpio_pad_select_gpio( GPIO_CS );
|
||||
gpio_reset_pin( GPIO_CS );
|
||||
gpio_set_direction( GPIO_CS, GPIO_MODE_OUTPUT );
|
||||
gpio_set_level( GPIO_CS, 0 );
|
||||
|
||||
//gpio_pad_select_gpio( GPIO_DC );
|
||||
gpio_reset_pin( GPIO_DC );
|
||||
gpio_set_direction( GPIO_DC, GPIO_MODE_OUTPUT );
|
||||
gpio_set_level( GPIO_DC, 0 );
|
||||
|
||||
if ( GPIO_RESET >= 0 ) {
|
||||
//gpio_pad_select_gpio( GPIO_RESET );
|
||||
gpio_reset_pin( GPIO_RESET );
|
||||
gpio_set_direction( GPIO_RESET, GPIO_MODE_OUTPUT );
|
||||
gpio_set_level( GPIO_RESET, 0 );
|
||||
vTaskDelay( pdMS_TO_TICKS( 100 ) );
|
||||
gpio_set_level( GPIO_RESET, 1 );
|
||||
}
|
||||
|
||||
spi_bus_config_t spi_bus_config = {
|
||||
.mosi_io_num = GPIO_MOSI,
|
||||
.miso_io_num = -1,
|
||||
.sclk_io_num = GPIO_SCLK,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = 0,
|
||||
.flags = 0
|
||||
};
|
||||
|
||||
ret = spi_bus_initialize( LCD_HOST, &spi_bus_config, SPI_DMA_CH_AUTO );
|
||||
ESP_LOGI(TAG, "spi_bus_initialize=%d",ret);
|
||||
assert(ret==ESP_OK);
|
||||
|
||||
spi_device_interface_config_t devcfg;
|
||||
memset( &devcfg, 0, sizeof( spi_device_interface_config_t ) );
|
||||
devcfg.clock_speed_hz = SPI_Frequency;
|
||||
devcfg.spics_io_num = GPIO_CS;
|
||||
devcfg.queue_size = 1;
|
||||
|
||||
spi_device_handle_t handle;
|
||||
ret = spi_bus_add_device( LCD_HOST, &devcfg, &handle);
|
||||
ESP_LOGI(TAG, "spi_bus_add_device=%d",ret);
|
||||
assert(ret==ESP_OK);
|
||||
dev->_dc = GPIO_DC;
|
||||
dev->_SPIHandle = handle;
|
||||
dev->_address = SPIAddress;
|
||||
dev->_flip = false;
|
||||
}
|
||||
|
||||
|
||||
bool spi_master_write_byte(spi_device_handle_t SPIHandle, const uint8_t* Data, size_t DataLength )
|
||||
{
|
||||
spi_transaction_t SPITransaction;
|
||||
|
||||
if ( DataLength > 0 ) {
|
||||
memset( &SPITransaction, 0, sizeof( spi_transaction_t ) );
|
||||
SPITransaction.length = DataLength * 8;
|
||||
SPITransaction.tx_buffer = Data;
|
||||
spi_device_transmit( SPIHandle, &SPITransaction );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spi_master_write_command(SSD1306_t * dev, uint8_t Command )
|
||||
{
|
||||
static uint8_t CommandByte = 0;
|
||||
CommandByte = Command;
|
||||
gpio_set_level( dev->_dc, SPI_Command_Mode );
|
||||
return spi_master_write_byte( dev->_SPIHandle, &CommandByte, 1 );
|
||||
}
|
||||
|
||||
bool spi_master_write_data(SSD1306_t * dev, const uint8_t* Data, size_t DataLength )
|
||||
{
|
||||
gpio_set_level( dev->_dc, SPI_Data_Mode );
|
||||
return spi_master_write_byte( dev->_SPIHandle, Data, DataLength );
|
||||
}
|
||||
|
||||
|
||||
void spi_init(SSD1306_t * dev, int width, int height)
|
||||
{
|
||||
dev->_width = width;
|
||||
dev->_height = height;
|
||||
dev->_pages = 8;
|
||||
if (dev->_height == 32) dev->_pages = 4;
|
||||
|
||||
spi_master_write_command(dev, OLED_CMD_DISPLAY_OFF); // AE
|
||||
spi_master_write_command(dev, OLED_CMD_SET_MUX_RATIO); // A8
|
||||
if (dev->_height == 64) spi_master_write_command(dev, 0x3F);
|
||||
if (dev->_height == 32) spi_master_write_command(dev, 0x1F);
|
||||
spi_master_write_command(dev, OLED_CMD_SET_DISPLAY_OFFSET); // D3
|
||||
spi_master_write_command(dev, 0x00);
|
||||
spi_master_write_command(dev, OLED_CONTROL_BYTE_DATA_STREAM); // 40
|
||||
if (dev->_flip) {
|
||||
spi_master_write_command(dev, OLED_CMD_SET_SEGMENT_REMAP_0); // A0
|
||||
} else {
|
||||
spi_master_write_command(dev, OLED_CMD_SET_SEGMENT_REMAP_1); // A1
|
||||
}
|
||||
//spi_master_write_command(dev, OLED_CMD_SET_SEGMENT_REMAP); // A1
|
||||
spi_master_write_command(dev, OLED_CMD_SET_COM_SCAN_MODE); // C8
|
||||
spi_master_write_command(dev, OLED_CMD_SET_DISPLAY_CLK_DIV); // D5
|
||||
spi_master_write_command(dev, 0x80);
|
||||
spi_master_write_command(dev, OLED_CMD_SET_COM_PIN_MAP); // DA
|
||||
if (dev->_height == 64) spi_master_write_command(dev, 0x12);
|
||||
if (dev->_height == 32) spi_master_write_command(dev, 0x02);
|
||||
spi_master_write_command(dev, OLED_CMD_SET_CONTRAST); // 81
|
||||
spi_master_write_command(dev, 0xFF);
|
||||
spi_master_write_command(dev, OLED_CMD_DISPLAY_RAM); // A4
|
||||
spi_master_write_command(dev, OLED_CMD_SET_VCOMH_DESELCT); // DB
|
||||
spi_master_write_command(dev, 0x40);
|
||||
spi_master_write_command(dev, OLED_CMD_SET_MEMORY_ADDR_MODE); // 20
|
||||
//spi_master_write_command(dev, OLED_CMD_SET_HORI_ADDR_MODE); // 00
|
||||
spi_master_write_command(dev, OLED_CMD_SET_PAGE_ADDR_MODE); // 02
|
||||
// Set Lower Column Start Address for Page Addressing Mode
|
||||
spi_master_write_command(dev, 0x00);
|
||||
// Set Higher Column Start Address for Page Addressing Mode
|
||||
spi_master_write_command(dev, 0x10);
|
||||
spi_master_write_command(dev, OLED_CMD_SET_CHARGE_PUMP); // 8D
|
||||
spi_master_write_command(dev, 0x14);
|
||||
spi_master_write_command(dev, OLED_CMD_DEACTIVE_SCROLL); // 2E
|
||||
spi_master_write_command(dev, OLED_CMD_DISPLAY_NORMAL); // A6
|
||||
spi_master_write_command(dev, OLED_CMD_DISPLAY_ON); // AF
|
||||
}
|
||||
|
||||
|
||||
void spi_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width)
|
||||
{
|
||||
if (page >= dev->_pages) return;
|
||||
if (seg >= dev->_width) return;
|
||||
|
||||
int _seg = seg + CONFIG_OFFSETX;
|
||||
uint8_t columLow = _seg & 0x0F;
|
||||
uint8_t columHigh = (_seg >> 4) & 0x0F;
|
||||
|
||||
int _page = page;
|
||||
if (dev->_flip) {
|
||||
_page = (dev->_pages - page) - 1;
|
||||
}
|
||||
|
||||
// Set Lower Column Start Address for Page Addressing Mode
|
||||
spi_master_write_command(dev, (0x00 + columLow));
|
||||
// Set Higher Column Start Address for Page Addressing Mode
|
||||
spi_master_write_command(dev, (0x10 + columHigh));
|
||||
// Set Page Start Address for Page Addressing Mode
|
||||
spi_master_write_command(dev, 0xB0 | _page);
|
||||
|
||||
spi_master_write_data(dev, images, width);
|
||||
|
||||
}
|
||||
|
||||
void spi_contrast(SSD1306_t * dev, int contrast) {
|
||||
int _contrast = contrast;
|
||||
if (contrast < 0x0) _contrast = 0;
|
||||
if (contrast > 0xFF) _contrast = 0xFF;
|
||||
|
||||
spi_master_write_command(dev, OLED_CMD_SET_CONTRAST); // 81
|
||||
spi_master_write_command(dev, _contrast);
|
||||
}
|
||||
|
||||
void spi_hardware_scroll(SSD1306_t * dev, ssd1306_scroll_type_t scroll)
|
||||
{
|
||||
|
||||
if (scroll == SCROLL_RIGHT) {
|
||||
spi_master_write_command(dev, OLED_CMD_HORIZONTAL_RIGHT); // 26
|
||||
spi_master_write_command(dev, 0x00); // Dummy byte
|
||||
spi_master_write_command(dev, 0x00); // Define start page address
|
||||
spi_master_write_command(dev, 0x07); // Frame frequency
|
||||
spi_master_write_command(dev, 0x07); // Define end page address
|
||||
spi_master_write_command(dev, 0x00); //
|
||||
spi_master_write_command(dev, 0xFF); //
|
||||
spi_master_write_command(dev, OLED_CMD_ACTIVE_SCROLL); // 2F
|
||||
}
|
||||
|
||||
if (scroll == SCROLL_LEFT) {
|
||||
spi_master_write_command(dev, OLED_CMD_HORIZONTAL_LEFT); // 27
|
||||
spi_master_write_command(dev, 0x00); // Dummy byte
|
||||
spi_master_write_command(dev, 0x00); // Define start page address
|
||||
spi_master_write_command(dev, 0x07); // Frame frequency
|
||||
spi_master_write_command(dev, 0x07); // Define end page address
|
||||
spi_master_write_command(dev, 0x00); //
|
||||
spi_master_write_command(dev, 0xFF); //
|
||||
spi_master_write_command(dev, OLED_CMD_ACTIVE_SCROLL); // 2F
|
||||
}
|
||||
|
||||
if (scroll == SCROLL_DOWN) {
|
||||
spi_master_write_command(dev, OLED_CMD_CONTINUOUS_SCROLL); // 29
|
||||
spi_master_write_command(dev, 0x00); // Dummy byte
|
||||
spi_master_write_command(dev, 0x00); // Define start page address
|
||||
spi_master_write_command(dev, 0x07); // Frame frequency
|
||||
//spi_master_write_command(dev, 0x01); // Define end page address
|
||||
spi_master_write_command(dev, 0x00); // Define end page address
|
||||
spi_master_write_command(dev, 0x3F); // Vertical scrolling offset
|
||||
|
||||
spi_master_write_command(dev, OLED_CMD_VERTICAL); // A3
|
||||
spi_master_write_command(dev, 0x00);
|
||||
if (dev->_height == 64)
|
||||
spi_master_write_command(dev, 0x40);
|
||||
if (dev->_height == 32)
|
||||
spi_master_write_command(dev, 0x20);
|
||||
spi_master_write_command(dev, OLED_CMD_ACTIVE_SCROLL); // 2F
|
||||
}
|
||||
|
||||
if (scroll == SCROLL_UP) {
|
||||
spi_master_write_command(dev, OLED_CMD_CONTINUOUS_SCROLL); // 29
|
||||
spi_master_write_command(dev, 0x00); // Dummy byte
|
||||
spi_master_write_command(dev, 0x00); // Define start page address
|
||||
spi_master_write_command(dev, 0x07); // Frame frequency
|
||||
//spi_master_write_command(dev, 0x01); // Define end page address
|
||||
spi_master_write_command(dev, 0x00); // Define end page address
|
||||
spi_master_write_command(dev, 0x01); // Vertical scrolling offset
|
||||
|
||||
spi_master_write_command(dev, OLED_CMD_VERTICAL); // A3
|
||||
spi_master_write_command(dev, 0x00);
|
||||
if (dev->_height == 64)
|
||||
spi_master_write_command(dev, 0x40);
|
||||
if (dev->_height == 32)
|
||||
spi_master_write_command(dev, 0x20);
|
||||
spi_master_write_command(dev, OLED_CMD_ACTIVE_SCROLL); // 2F
|
||||
}
|
||||
|
||||
if (scroll == SCROLL_STOP) {
|
||||
spi_master_write_command(dev, OLED_CMD_DEACTIVE_SCROLL); // 2E
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user