WaveShareOLED1in5.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. * WaveShareOLED1in5.cpp
  3. *
  4. * Created on: Mar 23, 2021
  5. * Author: spinner
  6. */
  7. #include <WaveShareOLED1in5.h>
  8. #include <cstring>
  9. static uint8_t rxPad[WSOLED_MAX_TX] = {};
  10. void oledOnTxComplete() {
  11. WaveShare_OLED1in5::instance.onTxComplete();
  12. }
  13. WaveShare_OLED1in5 WaveShare_OLED1in5::instance = WaveShare_OLED1in5();
  14. void WaveShare_OLED1in5::init(SPI_HandleTypeDef* hspi) {
  15. this->hspi = hspi;
  16. if (txCompleteId == nullptr) {
  17. txCompleteId = osSemaphoreNew(1, 0, nullptr);
  18. }
  19. if (spiLock == nullptr) {
  20. spiLock = osMutexNew(nullptr);
  21. }
  22. }
  23. void WaveShare_OLED1in5::_write(uint8_t byte) {
  24. HAL_SPI_TransmitReceive_DMA(hspi, &byte, rxPad, 1);
  25. waitTxComplete();
  26. }
  27. void WaveShare_OLED1in5::_write(uint8_t const* data, size_t size) {
  28. size_t sent = 0;
  29. size_t slice;
  30. size_t left;
  31. while(sent < size) {
  32. left = (size - sent);
  33. slice = (left > WSOLED_MAX_TX) ? WSOLED_MAX_TX : left;
  34. HAL_SPI_TransmitReceive_DMA(hspi, const_cast<uint8_t*>(data + sent), rxPad, slice);
  35. waitTxComplete();
  36. sent += slice;
  37. }
  38. }
  39. void WaveShare_OLED1in5::waitTxComplete() {
  40. while(osSemaphoreAcquire(txCompleteId, osWaitForever) != osOK);
  41. }
  42. void WaveShare_OLED1in5::onTxComplete() {
  43. osSemaphoreRelease(txCompleteId);
  44. }
  45. void WaveShare_OLED1in5::reset() {
  46. OLED_RST_1;
  47. osDelay(100);
  48. OLED_RST_0;
  49. osDelay(100);
  50. OLED_RST_1;
  51. osDelay(100);
  52. }
  53. void WaveShare_OLED1in5::writeReg(uint8_t const* reg, size_t size) {
  54. if (osMutexAcquire(spiLock, osWaitForever) == osOK) {
  55. OLED_DC_0;
  56. OLED_CS_0;
  57. _write(reg, size);
  58. OLED_CS_1;
  59. osMutexRelease(spiLock);
  60. }
  61. }
  62. void WaveShare_OLED1in5::writeReg(uint8_t reg) {
  63. writeReg(&reg, 1);
  64. }
  65. void WaveShare_OLED1in5::writeData(uint8_t const* data, size_t size) {
  66. if (osMutexAcquire(spiLock, osWaitForever) == osOK) {
  67. OLED_DC_1;
  68. OLED_CS_0;
  69. _write(data, size);
  70. OLED_CS_1;
  71. osMutexRelease(spiLock);
  72. }
  73. }
  74. void WaveShare_OLED1in5::initReg() {
  75. static const uint8_t regSequence [] = {
  76. 0xae, // turn off oled panel
  77. 0x15, // set column address
  78. 0x00, // start column 0
  79. 0x7f, // end column 12
  80. 0x75, // set row address
  81. 0x00, // start row 0
  82. 0x7f, // end row 127
  83. 0x81, // set contrast control
  84. 0xFF,
  85. 0xa0, // gment remap
  86. 0x51, // 51
  87. 0xa1, // start line
  88. 0x00,
  89. 0xa2, // display offset
  90. 0x00,
  91. 0xa4, // Normal display
  92. 0xa8, // set multiplex ratio
  93. 0x7f,
  94. 0xb1, // set phase leghth
  95. 0xf1,
  96. 0xb3, // set dclk
  97. 0x70, // 80Hz:0xc1 90Hz:0xe1 100Hz:0x00 110Hz:0x30 120Hz:0x50 130Hz:0x70 01
  98. 0xab, // Internal regulator
  99. 0x01, // Enabled
  100. 0xb6, // set phase leghth
  101. 0x0f, // 15CLK
  102. 0xbe, // set COM deselect voltage level
  103. 0x08, //
  104. 0xbc, // set PRECHARGE voltage
  105. 0x00,
  106. 0xd5, // Enable second precharge and VSL pin
  107. 0x62,
  108. 0xb8,
  109. 1, 2, 3, 4, 6, 8, 10, 13, 17, 22, 28, 35, 44, 55,
  110. //0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x10, 0x15, 0x19, 0x20, 0x28, 0x32,
  111. 0xfd,
  112. 0x12,
  113. // Set the grayscale
  114. //0xB9,
  115. };
  116. writeReg(regSequence, sizeof(regSequence));
  117. }
  118. void WaveShare_OLED1in5::setGramScanWay(OLED_SCAN_DIR scanDir) {
  119. desc.OLED_Scan_Dir = scanDir;
  120. //Get GRAM and OLED width and height
  121. if(scanDir == L2R_U2D || scanDir == L2R_D2U || scanDir == R2L_U2D || scanDir == R2L_D2U) {
  122. desc.OLED_Dis_Column = OLED_WIDTH;
  123. desc.OLED_Dis_Page = OLED_HEIGHT;
  124. desc.OLED_X_Adjust = OLED_X;
  125. desc.OLED_Y_Adjust = OLED_Y;
  126. } else {
  127. desc.OLED_Dis_Column = OLED_HEIGHT;
  128. desc.OLED_Dis_Page = OLED_WIDTH;
  129. desc.OLED_X_Adjust = OLED_Y;
  130. desc.OLED_Y_Adjust = OLED_X;
  131. }
  132. }
  133. void WaveShare_OLED1in5::displayInit(OLED_SCAN_DIR scanDir) {
  134. //Hardware reset
  135. reset();
  136. //Set the initialization register
  137. initReg();
  138. //Set the display scan and color transfer modes
  139. setGramScanWay(scanDir);
  140. osDelay(200);
  141. //Turn on the OLED display
  142. writeReg(0xAF);
  143. }
  144. void WaveShare_OLED1in5::setCursor(POINT Xpoint, POINT Ypoint) {
  145. if((Xpoint > desc.OLED_Dis_Column) || (Ypoint > desc.OLED_Dis_Page)) {
  146. return;
  147. }
  148. uint8_t sequence[] = {
  149. 0x15, static_cast<uint8_t>(Xpoint), static_cast<uint8_t>(Xpoint),
  150. 0x75, static_cast<uint8_t>(Ypoint), static_cast<uint8_t>(Ypoint),
  151. };
  152. writeReg(sequence, sizeof(sequence));
  153. }
  154. void WaveShare_OLED1in5::setWindow(POINT Xstart, POINT Ystart, POINT Xend, POINT Yend) {
  155. if((Xstart > desc.OLED_Dis_Column) || (Ystart > desc.OLED_Dis_Page) ||
  156. (Xend > desc.OLED_Dis_Column) || (Yend > desc.OLED_Dis_Page))
  157. return;
  158. uint8_t sequence[] = {
  159. 0x15, static_cast<uint8_t>(Xstart), static_cast<uint8_t>(Xend - 1),
  160. 0x75, static_cast<uint8_t>(Ystart), static_cast<uint8_t>(Yend - 1),
  161. };
  162. writeReg(sequence, sizeof(sequence));
  163. }
  164. void WaveShare_OLED1in5::setColor(POINT Xpoint, POINT Ypoint, COLOR Color)
  165. {
  166. if(Xpoint > desc.OLED_Dis_Column || Ypoint > desc.OLED_Dis_Page) {
  167. return;
  168. }
  169. Color &= 0x0F;
  170. //1 byte control two points
  171. if(Xpoint % 2 == 0) {
  172. pixBuf[Xpoint / 2 + Ypoint * 64] = (Color << 4) | (pixBuf[Xpoint / 2 + Ypoint * 64] & 0x0F);
  173. } else {
  174. pixBuf[Xpoint / 2 + Ypoint * 64] = (Color & 0x0F) | (pixBuf[Xpoint / 2 + Ypoint * 64] & 0xf0);
  175. }
  176. }
  177. void WaveShare_OLED1in5::display(Surface4Bit<SCR_PARAMS>* surface) {
  178. memcpy(pixBuf, surface->getSurface(), sizeof(pixBuf));
  179. display();
  180. }
  181. void WaveShare_OLED1in5::display() {
  182. setWindow(0, 0, desc.OLED_Dis_Column, desc.OLED_Dis_Page);
  183. //write data
  184. writeData(pixBuf, sizeof(pixBuf));
  185. }
  186. void WaveShare_OLED1in5::clear(COLOR color) {
  187. color &= 0x0F;
  188. uint8_t c = (color << 4) | color;
  189. memset(pixBuf, c, sizeof(pixBuf));
  190. }