default_if_i2c.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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/i2c.h>
  12. #include <driver/gpio.h>
  13. #include "ssd1306.h"
  14. #include "ssd1306_default_if.h"
  15. static const int I2CDisplaySpeed = CONFIG_DISPLAY_I2C_SPEED;
  16. static int I2CPortNumber;
  17. static const int SSD1306_I2C_COMMAND_MODE = 0x80;
  18. static const int SSD1306_I2C_DATA_MODE = 0x40;
  19. static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength );
  20. static bool I2CDefaultWriteCommand( struct SSD1306_Device* Display, SSDCmd Command );
  21. static bool I2CDefaultWriteData( struct SSD1306_Device* Display, const uint8_t* Data, size_t DataLength );
  22. static bool I2CDefaultReset( struct SSD1306_Device* Display );
  23. /*
  24. * Initializes the i2c master with the parameters specified
  25. * in the component configuration in sdkconfig.h.
  26. *
  27. * Returns true on successful init of the i2c bus.
  28. */
  29. bool SSD1306_I2CMasterInitDefault( int PortNumber, int SDA, int SCL ) {
  30. I2CPortNumber = PortNumber;
  31. if (SDA != -1 && SCL != -1) {
  32. i2c_config_t Config = { 0 };
  33. Config.mode = I2C_MODE_MASTER;
  34. Config.sda_io_num = SDA;
  35. Config.sda_pullup_en = GPIO_PULLUP_ENABLE;
  36. Config.scl_io_num = SCL;
  37. Config.scl_pullup_en = GPIO_PULLUP_ENABLE;
  38. Config.master.clk_speed = I2CDisplaySpeed;
  39. ESP_ERROR_CHECK_NONFATAL( i2c_param_config( I2CPortNumber, &Config ), return false );
  40. ESP_ERROR_CHECK_NONFATAL( i2c_driver_install( I2CPortNumber, Config.mode, 0, 0, 0 ), return false );
  41. }
  42. return true;
  43. }
  44. /*
  45. * Attaches a display to the I2C bus using default communication functions.
  46. *
  47. * Params:
  48. * DisplayHandle: Pointer to your SSD1306_Device object
  49. * Width: Width of display
  50. * Height: Height of display
  51. * I2CAddress: Address of your display
  52. * RSTPin: Optional GPIO pin to use for hardware reset, if none pass -1 for this parameter.
  53. *
  54. * Returns true on successful init of display.
  55. */
  56. bool SSD1306_I2CMasterAttachDisplayDefault( struct SSD1306_Device* DisplayHandle, int Width, int Height, int I2CAddress, int RSTPin ) {
  57. NullCheck( DisplayHandle, return false );
  58. if ( RSTPin >= 0 ) {
  59. ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTPin, GPIO_MODE_OUTPUT ), return false );
  60. ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTPin, 1 ), return false );
  61. }
  62. return SSD1306_Init_I2C( DisplayHandle,
  63. Width,
  64. Height,
  65. I2CAddress,
  66. RSTPin,
  67. I2CDefaultWriteCommand,
  68. I2CDefaultWriteData,
  69. I2CDefaultReset
  70. );
  71. }
  72. static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength ) {
  73. i2c_cmd_handle_t* CommandHandle = NULL;
  74. static uint8_t ModeByte = 0;
  75. NullCheck( Data, return false );
  76. if ( ( CommandHandle = i2c_cmd_link_create( ) ) != NULL ) {
  77. ModeByte = ( IsCommand == true ) ? SSD1306_I2C_COMMAND_MODE: SSD1306_I2C_DATA_MODE;
  78. ESP_ERROR_CHECK_NONFATAL( i2c_master_start( CommandHandle ), return false );
  79. ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ( Address << 1 ) | I2C_MASTER_WRITE, true ), return false );
  80. ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ModeByte, true ), return false );
  81. ESP_ERROR_CHECK_NONFATAL( i2c_master_write( CommandHandle, ( uint8_t* ) Data, DataLength, true ), return false );
  82. ESP_ERROR_CHECK_NONFATAL( i2c_master_stop( CommandHandle ), return false );
  83. ESP_ERROR_CHECK_NONFATAL( i2c_master_cmd_begin( I2CPortNumber, CommandHandle, pdMS_TO_TICKS( 1000 ) ), return false );
  84. i2c_cmd_link_delete( CommandHandle );
  85. }
  86. return true;
  87. }
  88. static bool I2CDefaultWriteCommand( struct SSD1306_Device* Display, SSDCmd Command ) {
  89. uint8_t CommandByte = ( uint8_t ) Command;
  90. NullCheck( Display, return false );
  91. return I2CDefaultWriteBytes( Display->Address, true, ( const uint8_t* ) &CommandByte, 1 );
  92. }
  93. static bool I2CDefaultWriteData( struct SSD1306_Device* Display, const uint8_t* Data, size_t DataLength ) {
  94. NullCheck( Display, return false );
  95. NullCheck( Data, return false );
  96. return I2CDefaultWriteBytes( Display->Address, false, Data, DataLength );
  97. }
  98. static bool I2CDefaultReset( struct SSD1306_Device* Display ) {
  99. NullCheck( Display, return false );
  100. if ( Display->RSTPin >= 0 ) {
  101. ESP_ERROR_CHECK_NONFATAL( gpio_set_level( Display->RSTPin, 0 ), return true );
  102. vTaskDelay( pdMS_TO_TICKS( 100 ) );
  103. ESP_ERROR_CHECK_NONFATAL( gpio_set_level( Display->RSTPin, 1 ), return true );
  104. }
  105. return true;
  106. }