Ein Roboter mit bürstenlosem Antrieb, differenzial und NRF24L01 Funk. Großflächig gebaut um ein großes Solarpanel aufzunehmen. https://gitlab.informatik.hs-fulda.de/fdai5253/roboter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
4.9 KiB

  1. #include "PCD8544_SPI.h"
  2. #include <SPI.h>
  3. PCD8544_SPI::PCD8544_SPI()
  4. {
  5. }
  6. void PCD8544_SPI::begin(bool invert)
  7. {
  8. this->begin(invert, 0xB0, 0x04, 0x15);
  9. }
  10. void PCD8544_SPI::begin(bool invert, uint8_t vop, uint8_t tempCoef, uint8_t bias)
  11. {
  12. PCD8544_PORT |= (PIN_DC | PIN_RESET | PIN_CE);
  13. PCD8544_DDR |= (PIN_DC | PIN_RESET | PIN_CE);
  14. SPI.begin();
  15. // LCD init section:
  16. uint8_t invertSetting = invert ? 0x0D : 0x0C;
  17. // Must reset LCD first!
  18. PCD8544_PORT &= ~PIN_RESET;
  19. PCD8544_PORT |= PIN_RESET;
  20. this->writeLcd(PCD8544_COMMAND, 0x21); //Tell LCD that extended commands follow
  21. this->writeLcd(PCD8544_COMMAND, vop); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark
  22. this->writeLcd(PCD8544_COMMAND, tempCoef); //Set Temp coefficent
  23. this->writeLcd(PCD8544_COMMAND, bias); //LCD bias mode 1:48: Try 0x13 or 0x14. Mine works best with 1:65/1:65
  24. this->writeLcd(PCD8544_COMMAND, 0x20); //We must send 0x20 before modifying the display control mode
  25. this->writeLcd(PCD8544_COMMAND, invertSetting); //Set display control, normal mode. 0x0D for inverse
  26. this->clear();
  27. }
  28. size_t PCD8544_SPI::write(uint8_t data)
  29. {
  30. // Non-ASCII characters are not supported.
  31. if (data < 0x20 || data > 0x7F) return 0;
  32. uint8_t buf[6];
  33. memcpy_P(buf, ASCII[data - 0x20], 5);
  34. buf[5] = 0x00;
  35. this->writeLcd(PCD8544_DATA, buf, 6);
  36. this->advanceXY(6);
  37. return 1;
  38. }
  39. void PCD8544_SPI::clear()
  40. {
  41. for (uint16_t i = 0; i < BUF_LEN; i++)
  42. this->writeLcd(PCD8544_DATA, 0x00);
  43. //PCD8544_PORT = (PCD8544_PORT & ~PINS_CE_DC) | PCD8544_DATA;
  44. //for (uint16_t i = BUF_LEN; i > 0; i--) SPI.transfer(0x00);
  45. //PCD8544_PORT |= PIN_CE;
  46. this->gotoXY(0, 0);
  47. }
  48. uint8_t PCD8544_SPI::gotoXY(uint8_t x, uint8_t y)
  49. {
  50. if (x >= PCD8544_X_PIXELS || y >= PCD8544_ROWS) return PCD8544_ERROR;
  51. //PCD8544_PORT = (PCD8544_PORT & ~PINS_CE_DC) | PCD8544_COMMAND;
  52. //SPI.transfer(0x80 | x);
  53. //SPI.transfer(0x40 | y);
  54. //PCD8544_PORT |= PIN_CE;
  55. this->writeLcd(PCD8544_COMMAND, 0x80 | x); // Column.
  56. this->writeLcd(PCD8544_COMMAND, 0x40 | y); // Row.
  57. this->m_Column = x;
  58. this->m_Line = y;
  59. return PCD8544_SUCCESS;
  60. }
  61. uint8_t PCD8544_SPI::writeBitmap(const uint8_t *bitmap, uint8_t x, uint8_t y, uint8_t width, uint8_t height)
  62. {
  63. //if (x >= PCD8544_X_PIXELS || y >= PCD8544_ROWS) return;
  64. ////height = (this->m_Line + height > PCD8544_Y_PIXELS / 8) ? ((PCD8544_Y_PIXELS / 8) - this->m_Line) : height;
  65. ////width = (this->m_Column + width > PCD8544_X_PIXELS) ? (PCD8544_X_PIXELS - this->m_Column) : width;
  66. //this->gotoXY(x, y);
  67. //for (uint8_t y = 0; y < height; y++)
  68. //{
  69. // for (uint8_t x = 0; x < width; x++)
  70. // this->writeLcd(PCD8544_DATA, bitmap[x + (y * width)]);
  71. // this->gotoXY(this->m_Column, this->m_Line + 1);
  72. //}
  73. //this->advanceXY(width);
  74. if (this->gotoXY(x, y) == PCD8544_ERROR) return PCD8544_ERROR;
  75. const uint8_t *maxY = bitmap + height * width;
  76. for (const uint8_t *y = bitmap; y < maxY; y += width)
  77. {
  78. //for (uint8_t x = 0; x < width; x++, y++)
  79. // this->writeLcd(PCD8544_DATA, *y);
  80. this->writeLcd(PCD8544_DATA, y , width);
  81. this->gotoXY(this->m_Column, this->m_Line + 1);
  82. }
  83. this->advanceXY(width);
  84. }
  85. //void PCD8544_SPI::init(void)
  86. //{
  87. // // Must reset LCD first!
  88. // PCD8544_PORT &= ~PIN_RESET;
  89. // PCD8544_PORT |= PIN_RESET;
  90. //
  91. // this->writeLcd(PCD8544_COMMAND, 0x21); //Tell LCD that extended commands follow
  92. // this->writeLcd(PCD8544_COMMAND, 0xB0); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark
  93. // this->writeLcd(PCD8544_COMMAND, 0x04); //Set Temp coefficent
  94. // this->writeLcd(PCD8544_COMMAND, 0x12); //LCD bias mode 1:48: Try 0x13 or 0x14. Mine works best with 1:65/1:65
  95. //
  96. // this->writeLcd(PCD8544_COMMAND, 0x20); //We must send 0x20 before modifying the display control mode
  97. // this->writeLcd(PCD8544_COMMAND, 0x0C); //Set display control, normal mode. 0x0D for inverse
  98. //}
  99. void PCD8544_SPI::advanceXY(uint8_t columns)
  100. {
  101. this->m_Column += columns;
  102. if (this->m_Column >= PCD8544_X_PIXELS)
  103. {
  104. this->m_Column %= PCD8544_X_PIXELS;
  105. this->m_Line++;
  106. this->m_Line %= PCD8544_ROWS;
  107. }
  108. }
  109. void PCD8544_SPI::writeLcd(uint8_t dataOrCommand, const uint8_t *data, uint16_t count)
  110. {
  111. PCD8544_PORT = (PCD8544_PORT & ~PINS_CE_DC) | dataOrCommand;
  112. //for (uint16_t i = 0; i < count; i++)
  113. // SPI.transfer(data[i]);
  114. for (uint16_t i = count; i > 0; i--)
  115. SPI.transfer(data[count-i]);
  116. PCD8544_PORT |= PIN_CE;
  117. }
  118. void PCD8544_SPI::writeLcd(uint8_t dataOrCommand, uint8_t data)
  119. {
  120. PCD8544_PORT = (PCD8544_PORT & ~PINS_CE_DC) | dataOrCommand;
  121. SPI.transfer(data);
  122. PCD8544_PORT |= PIN_CE;
  123. }
  124. // Valid values are 0x00 - 0x7F.
  125. void PCD8544_SPI::contrast(uint8_t cnt)
  126. {
  127. this->writeLcd(PCD8544_COMMAND, 0x21); //Tell LCD that extended commands follow
  128. this->writeLcd(PCD8544_COMMAND, 0X80 | cnt); //Set LCD Vop (Contrast)
  129. }