default_if_spi.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * Copyright (c) 2017-2018 Tara Keeling
  3. *
  4. * This software is released under the MIT License.
  5. * https://opensource.org/licenses/MIT
  6. */
  7. #include <stdio.h>
  8. #include <stdint.h>
  9. #include <stdbool.h>
  10. #include <string.h>
  11. #include <driver/spi_master.h>
  12. #include <driver/gpio.h>
  13. #include <freertos/task.h>
  14. #include "ssd1306.h"
  15. #include "ssd1306_default_if.h"
  16. /*
  17. * HACKHACKHACK:
  18. * Conditional compiling in component.mk does not seem to be working.
  19. * This workaround looks ugly, but should work.
  20. */
  21. #if defined CONFIG_SSD1306_ENABLE_DEFAULT_SPI_INTERFACE
  22. static const spi_host_device_t SPIHost = ( spi_host_device_t ) CONFIG_SSD1306_DEFAULT_SPI_HOST;
  23. static const int SPIFrequency = CONFIG_SSD1306_DEFAULT_SPI_FREQUENCY;
  24. static const int MOSIPin = CONFIG_SSD1306_DEFAULT_SPI_MOSI_PIN;
  25. static const int SCLKPin = CONFIG_SSD1306_DEFAULT_SPI_SCLK_PIN;
  26. static const int DCPin = CONFIG_SSD1306_DEFAULT_SPI_DC_PIN;
  27. static const int SSD1306_SPI_Command_Mode = 0;
  28. static const int SSD1306_SPI_Data_Mode = 1;
  29. static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength );
  30. static bool SPIDefaultWriteCommand( struct SSD1306_Device* DeviceHandle, SSDCmd Command );
  31. static bool SPIDefaultWriteData( struct SSD1306_Device* DeviceHandle, const uint8_t* Data, size_t DataLength );
  32. static bool SPIDefaultReset( struct SSD1306_Device* DeviceHandle );
  33. bool SSD1306_SPIMasterInitDefault( void ) {
  34. spi_bus_config_t BusConfig = {
  35. .sclk_io_num = SCLKPin,
  36. .mosi_io_num = MOSIPin,
  37. .miso_io_num = -1,
  38. .quadwp_io_num = -1,
  39. .quadhd_io_num = -1
  40. };
  41. ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( DCPin, GPIO_MODE_OUTPUT ), return false );
  42. ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DCPin, 0 ), return false );
  43. ESP_ERROR_CHECK_NONFATAL( spi_bus_initialize( SPIHost, &BusConfig, 1 ), return false );
  44. return true;
  45. }
  46. bool SSD1306_SPIMasterAttachDisplayDefault( struct SSD1306_Device* DeviceHandle, int Width, int Height, int CSForThisDisplay, int RSTForThisDisplay ) {
  47. spi_device_interface_config_t SPIDeviceConfig;
  48. spi_device_handle_t SPIDeviceHandle;
  49. NullCheck( DeviceHandle, return false );
  50. ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( CSForThisDisplay, GPIO_MODE_OUTPUT ), return false );
  51. ESP_ERROR_CHECK_NONFATAL( gpio_set_level( CSForThisDisplay, 0 ), return false );
  52. memset( &SPIDeviceConfig, 0, sizeof( spi_device_interface_config_t ) );
  53. SPIDeviceConfig.clock_speed_hz = SPIFrequency;
  54. SPIDeviceConfig.spics_io_num = CSForThisDisplay;
  55. SPIDeviceConfig.queue_size = 1;
  56. if ( RSTForThisDisplay >= 0 ) {
  57. ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTForThisDisplay, GPIO_MODE_OUTPUT ), return false );
  58. ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTForThisDisplay, 0 ), return false );
  59. }
  60. ESP_ERROR_CHECK_NONFATAL( spi_bus_add_device( SPIHost, &SPIDeviceConfig, &SPIDeviceHandle ), return false );
  61. return SSD1306_Init_SPI( DeviceHandle,
  62. Width,
  63. Height,
  64. RSTForThisDisplay,
  65. CSForThisDisplay,
  66. SPIDeviceHandle,
  67. SPIDefaultWriteCommand,
  68. SPIDefaultWriteData,
  69. SPIDefaultReset
  70. );
  71. }
  72. static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength ) {
  73. spi_transaction_t SPITransaction;
  74. NullCheck( SPIHandle, return false );
  75. NullCheck( Data, return false );
  76. if ( DataLength > 0 ) {
  77. memset( &SPITransaction, 0, sizeof( spi_transaction_t ) );
  78. SPITransaction.length = DataLength * 8;
  79. SPITransaction.tx_buffer = Data;
  80. gpio_set_level( DCPin, WriteMode );
  81. ESP_ERROR_CHECK_NONFATAL( spi_device_transmit( SPIHandle, &SPITransaction ), return false );
  82. }
  83. return true;
  84. }
  85. static bool SPIDefaultWriteCommand( struct SSD1306_Device* DeviceHandle, SSDCmd Command ) {
  86. static uint8_t CommandByte = 0;
  87. NullCheck( DeviceHandle, return false );
  88. NullCheck( DeviceHandle->SPIHandle, return false );
  89. CommandByte = Command;
  90. return SPIDefaultWriteBytes( DeviceHandle->SPIHandle, SSD1306_SPI_Command_Mode, &CommandByte, 1 );
  91. }
  92. static bool SPIDefaultWriteData( struct SSD1306_Device* DeviceHandle, const uint8_t* Data, size_t DataLength ) {
  93. NullCheck( DeviceHandle, return false );
  94. NullCheck( DeviceHandle->SPIHandle, return false );
  95. return SPIDefaultWriteBytes( DeviceHandle->SPIHandle, SSD1306_SPI_Data_Mode, Data, DataLength );
  96. }
  97. static bool SPIDefaultReset( struct SSD1306_Device* DeviceHandle ) {
  98. NullCheck( DeviceHandle, return false );
  99. if ( DeviceHandle->RSTPin >= 0 ) {
  100. ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DeviceHandle->RSTPin, 0 ), return false );
  101. vTaskDelay( pdMS_TO_TICKS( 100 ) );
  102. ESP_ERROR_CHECK_NONFATAL( gpio_set_level( DeviceHandle->RSTPin, 1 ), return false );
  103. }
  104. return true;
  105. }
  106. #endif