diff --git a/src/ssd1306.c b/lib/ssd1306/ssd1306.c copy from src/ssd1306.c copy to lib/ssd1306/ssd1306.c --- a/src/ssd1306.c +++ b/lib/ssd1306/ssd1306.c @@ -5,7 +5,7 @@ SPI_HandleTypeDef hspi1; - +// SPI handle accessor SPI_HandleTypeDef* spi_get() { return &hspi1; @@ -33,80 +33,79 @@ static void WriteData(unsigned char data // Initialize OLED void ssd1306_init(void) { - __SPI3_CLK_ENABLE(); - __GPIOA_CLK_ENABLE(); - __GPIOB_CLK_ENABLE(); - GPIO_InitTypeDef GPIO_InitStruct; + __SPI3_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + GPIO_InitTypeDef GPIO_InitStruct; - /*Configure GPIO pins : OLED_CS_Pin OLED_RESET_Pin OLED_DC_Pin */ - GPIO_InitStruct.Pin = OLED_CS_Pin|OLED_RESET_Pin|OLED_DC_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(OLED_DC_GPIO_Port, &GPIO_InitStruct); + /*Configure GPIO pins : OLED_CS_Pin OLED_RESET_Pin OLED_DC_Pin */ + GPIO_InitStruct.Pin = OLED_CS_Pin|OLED_RESET_Pin|OLED_DC_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(OLED_DC_GPIO_Port, &GPIO_InitStruct); // Set up MOSI/MISO/SCK - GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // Set up SPI port for OLED - hspi1.Instance = SPI3; - hspi1.Init.Mode = SPI_MODE_MASTER; - hspi1.Init.Direction = SPI_DIRECTION_2LINES; - hspi1.Init.DataSize = SPI_DATASIZE_8BIT; - hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; - hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; - hspi1.Init.NSS = SPI_NSS_SOFT; - hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; - hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; - hspi1.Init.TIMode = SPI_TIMODE_DISABLED; - hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; - hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLED; - HAL_SPI_Init(&hspi1); - + hspi1.Instance = SPI3; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLED; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; + hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLED; + HAL_SPI_Init(&hspi1); - /* Generate a reset */ - SSD_Reset_Low(); - uint32_t i; - for(i=5000; i>1; i--) - SSD_Reset_High(); + // Generate a reset + SSD_Reset_Low(); + uint32_t i; + for(i=5000; i>1; i--) + SSD_Reset_High(); - WriteCommand(0xAE); - WriteCommand(0xD5); - WriteCommand(0x80); - WriteCommand(0xA8); - WriteCommand(0x1F); - WriteCommand(0xD3); - WriteCommand(0x00); - WriteCommand(0x40 | 0x00); // line #0 - WriteCommand(0x8D); - WriteCommand(0x14); //10 or 14 if not externalvcc - WriteCommand(0x20); - WriteCommand(0x00); -// WriteCommand(0xA0 | 0x1); // segremap (normal) - WriteCommand(0xA0); // segremap (flip) -// WriteCommand(0xC8); // comscandec (normal) - WriteCommand(0xC0); // comscandec (flip) - WriteCommand(0xDA); // setcompins - WriteCommand(0x02); - WriteCommand(0x81); // contrast - WriteCommand(0x0F); // contrast value. 8f is a good one. - WriteCommand(0xD9); - WriteCommand(0xF1); //22 or F1 if not externalvcc - WriteCommand(0xDB); - WriteCommand(0x40); - WriteCommand(0xA4); // dispalyallon_resume - WriteCommand(0xA6); // normaldisplay + WriteCommand(0xAE); + WriteCommand(0xD5); + WriteCommand(0x80); + WriteCommand(0xA8); + WriteCommand(0x1F); + WriteCommand(0xD3); + WriteCommand(0x00); + WriteCommand(0x40 | 0x00); // line #0 + WriteCommand(0x8D); + WriteCommand(0x14); //10 or 14 if not externalvcc + WriteCommand(0x20); + WriteCommand(0x00); + // WriteCommand(0xA0 | 0x1); // segremap (normal) + WriteCommand(0xA0); // segremap (flip) + // WriteCommand(0xC8); // comscandec (normal) + WriteCommand(0xC0); // comscandec (flip) + WriteCommand(0xDA); // setcompins + WriteCommand(0x02); + WriteCommand(0x81); // contrast + WriteCommand(0x0F); // contrast value. 8f is a good one. + WriteCommand(0xD9); + WriteCommand(0xF1); //22 or F1 if not externalvcc + WriteCommand(0xDB); + WriteCommand(0x40); + WriteCommand(0xA4); // dispalyallon_resume + WriteCommand(0xA6); // normaldisplay - WriteCommand(0xAF); // display on + WriteCommand(0xAF); // display on } @@ -209,31 +208,39 @@ static const char fontData[][5] = {0x00,0x00,0x7F,0x00,0x00}, // ( 92) | - 0x007C Vertical Line {0x00,0x41,0x36,0x08,0x00}, // ( 93) } - 0x007D Right Curly Bracket {0x02,0x01,0x02,0x04,0x02}, // ( 94) ~ - 0x007E Tilde - {0x08,0x14,0x2A,0x14,0x22}, // ( 95) << - 0x00AB Left-Pointing Double Angle Quotation Mark + {0x08,0x14,0x2A,0x14,0x22}, // ( 95) << - 0x00AB Left-Pointing Double Angle Quotation Mark {0x00,0x02,0x05,0x02,0x00}, // ( 96) - 0x00B0 Degree Sign -// {0x44,0x44,0x5F,0x44,0x44}, // ( 97) +- - 0x00B1 Plus-Minus Sign -// {0x7E,0x20,0x20,0x10,0x3E}, // ( 98) u - 0x00B5 Micro Sign -// {0x22,0x14,0x2A,0x14,0x08}, // ( 99) >> - 0x00BB Right-Pointing Double Angle Quotation Mark -// {0x30,0x48,0x45,0x40,0x20}, // (100) ? - 0x00BF Inverted Question Mark -// {0x22,0x14,0x08,0x14,0x22}, // (101) x - 0x00D7 Multiplcation Sign -// {0x08,0x08,0x2A,0x08,0x08}, // (102) + - 0x00F7 Division Sign -// {0x18,0x14,0x08,0x14,0x0C}, // (103) - 0x221E Infinity -// {0x44,0x4A,0x4A,0x51,0x51}, // (104) < - 0x2264 Less-Than or Equal to -// {0x51,0x51,0x4A,0x4A,0x44}, // (105) > - 0x2265 Greater-Than or Equal to -// {0x54,0x14,0x64,0x08,0x70}, // (106) .: - RF Symbol -// {0x70,0x7C,0x72,0x7C,0x70}, // (107) ^ - Lock symbol -// {0x70,0x5C,0x52,0x54,0x70}, // (108) / - Unlock symbol -// {0x0C,0x1E,0x3C,0x1E,0x0C}, // (109) <3 - Heart Symbol -// {0x18,0x22,0xFF,0x12,0x0C}, // (110) U - USB Symbol + {0x44,0x44,0x5F,0x44,0x44}, // ( 97) +- - 0x00B1 Plus-Minus Sign + {0x7E,0x20,0x20,0x10,0x3E}, // ( 98) u - 0x00B5 Micro Sign + {0x22,0x14,0x2A,0x14,0x08}, // ( 99) >> - 0x00BB Right-Pointing Double Angle Quotation Mark + {0x30,0x48,0x45,0x40,0x20}, // (100) ? - 0x00BF Inverted Question Mark + {0x22,0x14,0x08,0x14,0x22}, // (101) x - 0x00D7 Multiplication Sign + {0x08,0x08,0x2A,0x08,0x08}, // (102) + - 0x00F7 Division Sign + {0x18,0x14,0x08,0x14,0x0C}, // (103) - 0x221E Infinity + {0x44,0x4A,0x4A,0x51,0x51}, // (104) < - 0x2264 Less-Than or Equal to + {0x51,0x51,0x4A,0x4A,0x44}, // (105) > - 0x2265 Greater-Than or Equal to + {0x54,0x14,0x64,0x08,0x70}, // (106) .: - RF Symbol + {0x70,0x7C,0x72,0x7C,0x70}, // (107) ^ - Lock symbol + {0x70,0x5C,0x52,0x54,0x70}, // (108) / - Unlock symbol + {0x0C,0x1E,0x3C,0x1E,0x0C}, // (109) <3 - Heart Symbol + {0x18,0x22,0xFF,0x12,0x0C}, // (110) U - USB Symbol + {0x22,0x5d,0x22,0x00,0x00}, // (111) ez updown + {0x14,0x3e,0x14,0x00,0x00}, // (112) ez updown short }; +/* +*/ + +// Set start page static void setStartPage(unsigned char d) { WriteCommand(0xB0|d); // Set Page Start Address for Page Addressing Mode // Default => 0xB0 (0x00) } -/* Below are functions used to configure the OLED */ + + +// Set start column static void setStartColumn(unsigned char d) { WriteCommand(0x00+d%16); // Set Lower Column Start Address for Page Addressing Mode @@ -242,6 +249,7 @@ static void setStartColumn(unsigned char } +// Therm logo const uint8_t row[4][32] = { {0x00,0x00,0x01,0x03,0x07,0x0F,0x1E,0x3C,0x3C,0x7C,0x7C,0x7C,0xFC,0xFF,0xFF,0xFC,0xFC,0xFC,0xFC,0xFF,0x7F,0x7F,0x7F,0x3C,0x3C,0x1C,0x0C,0x06,0x03,0x01,0x00,0x00}, @@ -254,6 +262,8 @@ const uint8_t row[4][32] = { }; + +// Clear the screen void ssd1306_clearscreen() { uint8_t i = 0; @@ -270,6 +280,8 @@ void ssd1306_clearscreen() WriteData(0x00); } + +// Draw the therm logo on the left side of the OLED void ssd1306_drawlogo() { uint8_t i = 0; @@ -307,10 +319,11 @@ void ssd1306_drawlogo() WriteData(0x00); } -/* Print a single character from font.cpp */ -void ssd1306_drawchar(char ascii, unsigned char row, unsigned char xPos) + +// Print a single character +void ssd1306_drawchar(unsigned char ascii, unsigned char row, unsigned char xPos) { - const char *srcPointer = (char*)-1; + const unsigned char *srcPointer = (char*)-1; srcPointer = &fontData[(ascii-32)][0]; @@ -325,7 +338,9 @@ void ssd1306_drawchar(char ascii, unsign WriteData(0x00); } -void ssd1306_drawcharbig(char ascii, unsigned char row, unsigned char xPos) + +// Print a single large character +void ssd1306_drawcharbig(unsigned char ascii, unsigned char row, unsigned char xPos) { const char *srcPointer = (char*)-1; @@ -387,11 +402,13 @@ void ssd1306_drawcharbig(char ascii, uns } -void ssd1306_drawstring(const char *dataPtr, unsigned char row, unsigned char xPos) + +// Print a string to the display +void ssd1306_drawstring(const unsigned char *dataPtr, unsigned char row, unsigned char xPos) { - char *srcPointer; + unsigned char *srcPointer; - srcPointer = (char*)dataPtr; + srcPointer = (unsigned char*)dataPtr; ssd1306_drawchar(' ',row,xPos); // NBSP must be written first before the string start while(1) @@ -404,7 +421,8 @@ void ssd1306_drawstring(const char *data } -void ssd1306_drawstringbig(const char *dataPtr, unsigned char row, unsigned char xPos) +// Print a string to the display, big font +void ssd1306_drawstringbig(const unsigned char *dataPtr, unsigned char row, unsigned char xPos) { char *srcPointer;