/* * OLED_SSD1327.c * * The MIT License. * Created on: 16.07.2020 * Author: Mateusz Salamon * www.msalamon.pl * mateusz@msalamon.pl */ #include "main.h" #include "OLED_SSD1327.h" #include "string.h" #ifdef SSD1327_I2C_CONTROL I2C_HandleTypeDef *ssd1337_i2c; #endif #ifdef SSD1327_SPI_CONTROL SPI_HandleTypeDef *ssd1337_spi; #endif #define SSD1327_BUFFERSIZE (SSD1327_LCDHEIGHT * SSD1327_LCDWIDTH / 2) static uint8_t buffer[SSD1327_BUFFERSIZE]; void SSD1327_Command(uint8_t com) { #ifdef SSD1327_I2C_CONTROL // I2C HAL_I2C_Mem_Write(ssd1337_i2c, SSD1327_I2C_ADDRESS, 0x00, 1, &com, sizeof(com), 100); #endif #ifdef SSD1327_SPI_CONTROL //SPI HAL_GPIO_WritePin(SSD1327_DC_GPIO_Port, SSD1327_DC_Pin, GPIO_PIN_RESET); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_RESET); #endif HAL_SPI_Transmit(ssd1337_spi, &com, 1, 10); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_SET); #endif #endif } void SSD1327_Data(uint8_t dat) { #ifdef SSD1327_I2C_CONTROL // I2C HAL_I2C_Mem_Write(ssd1337_i2c, SSD1327_I2C_ADDRESS, 0x40, 1, &dat, sizeof(dat), 100); #endif #ifdef SSD1327_SPI_CONTROL // SPI HAL_GPIO_WritePin(SSD1327_DC_GPIO_Port, SSD1327_DC_Pin, GPIO_PIN_SET); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_RESET); #endif HAL_SPI_Transmit(ssd1337_spi, &dat, 1, 10); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_SET); #endif #endif } #if defined(SSD1327_SPI_CONTROL) || defined(SSD1327_RESET_USE) void SSD1327_Reset(void) { HAL_GPIO_WritePin(SSD1327_RESET_GPIO_Port, SSD1327_RESET_Pin, GPIO_PIN_RESET); HAL_Delay(5); HAL_GPIO_WritePin(SSD1327_RESET_GPIO_Port, SSD1327_RESET_Pin, GPIO_PIN_SET); } #endif // // Configuration functions // void SSD1327_InvertColors(uint8_t Invert) { SSD1327_Command(Invert ? SSD1327_INVERTDISPLAY : SSD1327_NORMALDISPLAY); } void SSD1327_RotateDisplay(uint8_t Rotate) { if(Rotate > 1) Rotate = 1; SSD1327_Command(0xA0 | (0x01 & Rotate)); // Set Segment Re-Map Default // 0xA0 (0x00) => column Address 0 mapped to 127 // 0xA1 (0x01) => Column Address 127 mapped to 0 SSD1327_Command(0xC0 | (0x08 & (Rotate<<3))); // Set COM Output Scan Direction // 0xC0 (0x00) => normal mode (RESET) Scan from COM0 to COM[N-1];Where N is the Multiplex ratio. // 0xC8 (0xC8) => remapped mode. Scan from COM[N-1] to COM0;;Where N is the Multiplex ratio. } void SSD1327_DisplayON(uint8_t On) { SSD1327_Command(On ? SSD1327_DISPLAYON : SSD1327_DISPLAYOFF); } void SSD1327_SetContrast(uint8_t Contrast) { SSD1327_Command(SSD1327_SETCONTRASTCURRENT); // Set Contrast Control SSD1327_Command(Contrast); } #if GRAPHIC_ACCELERATION_COMMANDS == 1 // // Graphic Acceleration Command // void SSD1327_StartScrollRight(uint8_t StartPage, uint8_t EndPage, uint8_t Speed) { SSD1327_Command(SSD1327_RIGHT_HORIZONTAL_SCROLL); SSD1327_Command(0x00); SSD1327_Command(StartPage); SSD1327_Command(Speed); SSD1327_Command(EndPage); SSD1327_Command(SSD1327_ACTIVATE_SCROLL); } void SSD1327_StartScrollLeft(uint8_t StartPage, uint8_t EndPage, uint8_t Speed) { SSD1327_Command(SSD1327_LEFT_HORIZONTAL_SCROLL); SSD1327_Command(0x00); SSD1327_Command(StartPage); SSD1327_Command(Speed); SSD1327_Command(EndPage); SSD1327_Command(SSD1327_ACTIVATE_SCROLL); } void SSD1327_StopScroll(void) { SSD1327_Command(SSD1327_DEACTIVATE_SCROLL); } #endif // // Initialization // void SSD1327_Init(void) { SSD1327_Command(SSD1327_DISPLAYOFF); // Display Off SSD1327_Command(SSD1327_SETMULTIPLEX); SSD1327_Command(0x7F); SSD1327_Command(SSD1327_SETDISPLAYSTARTLINE); SSD1327_Command(0x00); SSD1327_Command(SSD1327_SETDISPLAYOFFSET); SSD1327_Command(0x0); SSD1327_Command(SSD1327_SEGREMAP); SSD1327_Command(0x51); SSD1327_SetContrast(0x7F); SSD1327_Command(SSD1327_SETPHASELENGTH); SSD1327_Command(0x22); SSD1327_Command(SSD1327_SETFRONTCLOCKDIVIDER_OSCILLATORFREQUENCY); SSD1327_Command(0x50); SSD1327_Command(SSD1327_SELECTDEFAULTLINEARGRAYSCALETABLE); SSD1327_Command(SSD1327_SETPRECHARGEVOLTAGE); SSD1327_Command(0x10); SSD1327_Command(SSD1327_SETSETVCOMVOLTAGE); SSD1327_Command(0x05); SSD1327_Command(SSD1327_SETSECONDPRECHARGEPERTIOD); SSD1327_Command(0x0a); SSD1327_Command(SSD1327_FUNCTIONSELECTIONB); SSD1327_Command(0x62); SSD1327_Command(SSD1327_SETCOLUMNADDRESS); SSD1327_Command(0x00); SSD1327_Command(0x3F); SSD1327_Command(SSD1327_SETROWADDRESS); SSD1327_Command(0x00); SSD1327_Command(0x7F); SSD1327_Command(SSD1327_NORMALDISPLAY); // Set Normal Display SSD1327_Command(SSD1327_DISPLAYALLON_RESUME); // Entire Display ON #if GRAPHIC_ACCELERATION_COMMANDS == 1 SSD1327_StopScroll(); #endif SSD1327_DisplayON(1); } #ifdef SSD1327_I2C_CONTROL void SSD1327_I2cInit(I2C_HandleTypeDef *i2c) { ssd1337_i2c = i2c; SSD1327_Init(); } #endif #ifdef SSD1327_SPI_CONTROL void SSD1327_SpiInit(SPI_HandleTypeDef *spi) { ssd1337_spi = spi; #if defined(SSD1327_RESET_USE) SSD1327_Reset(); #endif SSD1327_Init(); } #endif // // Draw pixel in the buffer // void SSD1327_DrawPixel(int16_t x, int16_t y, uint8_t Color) { if ((x < 0) || (x >= SSD1327_LCDWIDTH) || (y < 0) || (y >= SSD1327_LCDHEIGHT)) return; uint8_t SelectedCell = buffer[x/2 + y*(SSD1327_LCDWIDTH/2)]; if(x % 2) { SelectedCell &= ~(0x0F); SelectedCell |= (0x0F & Color); } else { SelectedCell &= ~(0xF0); SelectedCell |= (0xF0 & (Color<<4)); } buffer[x/2 + y*(SSD1327_LCDWIDTH/2)] = SelectedCell; } // // Clear the buffer // void SSD1327_Clear(uint8_t Color) { if(Color > WHITE) Color = WHITE; memset(buffer, (Color << 4 | Color), SSD1327_BUFFERSIZE); } // // Send buffer to OLDE GCRAM // void SSD1327_Display(void) { SSD1327_Command(SSD1327_SETCOLUMNADDRESS); SSD1327_Command(0x00); SSD1327_Command(0x3F); SSD1327_Command(SSD1327_SETROWADDRESS); SSD1327_Command(0x00); //SSD1327_Command(0x5F); SSD1327_Command(0x7F); #ifdef SSD1327_I2C_CONTROL #ifdef SSD1327_I2C_DMA_ENABLE if(ssd1337_i2c->hdmatx->State == HAL_DMA_STATE_READY) { HAL_I2C_Mem_Write_DMA(ssd1337_i2c, SSD1327_I2C_ADDRESS, 0x40, 1, (uint8_t*)&buffer, SSD1327_BUFFERSIZE); } #else HAL_I2C_Mem_Write(ssd1337_i2c, SSD1327_I2C_ADDRESS, 0x40, 1, (uint8_t*)&buffer, SSD1327_BUFFERSIZE, 1000); #endif #endif #ifdef SSD1327_SPI_CONTROL #ifdef SSD1327_SPI_DMA_ENABLE HAL_GPIO_WritePin(SSD1327_DC_GPIO_Port, SSD1327_DC_Pin, GPIO_PIN_SET); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_RESET); #endif if(ssd1337_spi->hdmatx->State == HAL_DMA_STATE_READY) { HAL_SPI_Transmit_DMA(ssd1337_spi, (uint8_t*)&buffer, SSD1327_BUFFERSIZE); } #else HAL_GPIO_WritePin(SSD1327_DC_GPIO_Port, SSD1327_DC_Pin, GPIO_PIN_SET); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_RESET); #endif HAL_SPI_Transmit(ssd1337_spi, (uint8_t*)&buffer, SSD1327_BUFFERSIZE, 100); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_SET); #endif #endif #endif } // // Display Bitmap directly on screen // void SSD1327_Bitmap(uint8_t *bitmap) { SSD1327_Command(0x22); SSD1327_Command(0x00); SSD1327_Command(0x07); #ifdef SSD1327_I2C_CONTROL #ifdef SSD1327_I2C_DMA_ENABLE if(ssd1337_i2c->hdmatx->State == HAL_DMA_STATE_READY) { HAL_I2C_Mem_Write_DMA(ssd1337_i2c, SSD1327_I2C_ADDRESS, 0x40, 1, bitmap, (SSD1327_LCDHEIGHT * SSD1327_LCDWIDTH / 8)); } #else HAL_I2C_Mem_Write(ssd1337_i2c, SSD1327_I2C_ADDRESS, 0x40, 1, bitmap, (SSD1327_LCDHEIGHT * SSD1327_LCDWIDTH / 8), 100); #endif #endif #ifdef SSD1327_SPI_CONTROL #ifdef SSD1327_SPI_DMA_ENABLE HAL_GPIO_WritePin(SSD1327_DC_GPIO_Port, SSD1327_DC_Pin, GPIO_PIN_SET); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_RESET); #endif if(ssd1337_spi->hdmatx->State == HAL_DMA_STATE_READY) { HAL_SPI_Transmit_DMA(ssd1337_spi, bitmap, (SSD1327_LCDHEIGHT * SSD1327_LCDWIDTH / 8)); } #else HAL_GPIO_WritePin(SSD1327_DC_GPIO_Port, SSD1327_DC_Pin, GPIO_PIN_SET); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_RESET); #endif HAL_SPI_Transmit(ssd1337_spi, bitmap, (SSD1327_LCDHEIGHT * SSD1327_LCDWIDTH / 8), 100); #ifndef SPI_CS_HARDWARE_CONTROL HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_SET); #endif #endif #endif } #if defined(SSD1327_SPI_CONTROL) && !defined(SSD1327_SPI_DMA_ENABLE) && !defined(SPI_CS_HARDWARE_CONTROL) void SSD1327_DmaEndCallback(SPI_HandleTypeDef *hspi) { if(hspi == ssd1337_spi) { HAL_GPIO_WritePin(SSD1327_CS_GPIO_Port, SSD1327_CS_Pin, GPIO_PIN_SET); } } #endif