default_if_i2c.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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 "gds.h"
  14. #include "gds_err.h"
  15. #include "gds_private.h"
  16. #include "gds_default_if.h"
  17. #include "messaging.h"
  18. static int I2CPortNumber;
  19. static int I2CWait;
  20. static const int GDS_I2C_COMMAND_MODE = 0x80;
  21. static const int GDS_I2C_DATA_MODE = 0x40;
  22. static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength );
  23. static bool I2CDefaultWriteCommand( struct GDS_Device* Device, uint8_t Command );
  24. static bool I2CDefaultWriteData( struct GDS_Device* Device, const uint8_t* Data, size_t DataLength );
  25. /*
  26. * Initializes the i2c master with the parameters specified
  27. * in the component configuration in sdkconfig.h.
  28. *
  29. * Returns true on successful init of the i2c bus.
  30. */
  31. bool GDS_I2CInit( int PortNumber, int SDA, int SCL, int Speed ) {
  32. I2CPortNumber = PortNumber;
  33. I2CWait = pdMS_TO_TICKS( Speed ? Speed / 4000 : 100 );
  34. if (SDA != -1 && SCL != -1) {
  35. i2c_config_t Config = { 0 };
  36. Config.mode = I2C_MODE_MASTER;
  37. Config.sda_io_num = SDA;
  38. Config.sda_pullup_en = GPIO_PULLUP_ENABLE;
  39. Config.scl_io_num = SCL;
  40. Config.scl_pullup_en = GPIO_PULLUP_ENABLE;
  41. Config.master.clk_speed = Speed ? Speed : 400000;
  42. ESP_ERROR_CHECK_NONFATAL( i2c_param_config( I2CPortNumber, &Config ), return false );
  43. ESP_ERROR_CHECK_NONFATAL( i2c_driver_install( I2CPortNumber, Config.mode, 0, 0, 0 ), return false );
  44. }
  45. return true;
  46. }
  47. /*
  48. * Attaches a display to the I2C bus using default communication functions.
  49. *
  50. * Params:
  51. * Device: Pointer to your GDS_Device object
  52. * Width: Width of display
  53. * Height: Height of display
  54. * I2CAddress: Address of your display
  55. * RSTPin: Optional GPIO pin to use for hardware reset, if none pass -1 for this parameter.
  56. *
  57. * Returns true on successful init of display.
  58. */
  59. bool GDS_I2CAttachDevice( struct GDS_Device* Device, int Width, int Height, int I2CAddress, int RSTPin ) {
  60. NullCheck( Device, return false );
  61. Device->WriteCommand = I2CDefaultWriteCommand;
  62. Device->WriteData = I2CDefaultWriteData;
  63. Device->Address = I2CAddress;
  64. Device->RSTPin = RSTPin;
  65. Device->IF = GDS_IF_I2C;
  66. Device->Width = Width;
  67. Device->Height = Height;
  68. if ( RSTPin >= 0 ) {
  69. ESP_ERROR_CHECK_NONFATAL( gpio_set_direction( RSTPin, GPIO_MODE_OUTPUT ), return false );
  70. ESP_ERROR_CHECK_NONFATAL( gpio_set_level( RSTPin, 1 ), return false );
  71. GDS_Reset( Device );
  72. }
  73. return GDS_Init( Device );
  74. }
  75. static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength ) {
  76. i2c_cmd_handle_t* CommandHandle = NULL;
  77. static uint8_t ModeByte = 0;
  78. static uint32_t failures=0;
  79. if(failures > 1000){
  80. ESP_LOGE("I2C_Display","I2C Write failure");
  81. failures = 1;
  82. return false;
  83. }
  84. NullCheck( Data, return false );
  85. if ( ( CommandHandle = i2c_cmd_link_create( ) ) != NULL ) {
  86. ModeByte = ( IsCommand == true ) ? GDS_I2C_COMMAND_MODE: GDS_I2C_DATA_MODE;
  87. ESP_ERROR_CHECK_NONFATAL( i2c_master_start( CommandHandle ), goto error );
  88. ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ( Address << 1 ) | I2C_MASTER_WRITE, true ), goto error );
  89. ESP_ERROR_CHECK_NONFATAL( i2c_master_write_byte( CommandHandle, ModeByte, true ), goto error );
  90. ESP_ERROR_CHECK_NONFATAL( i2c_master_write( CommandHandle, ( uint8_t* ) Data, DataLength, true ), goto error );
  91. ESP_ERROR_CHECK_NONFATAL( i2c_master_stop( CommandHandle ), goto error );
  92. ESP_ERROR_CHECK_NONFATAL( i2c_master_cmd_begin( I2CPortNumber, CommandHandle, I2CWait ), goto error );
  93. i2c_cmd_link_delete( CommandHandle );
  94. }
  95. return true;
  96. error:
  97. if(++failures == 1){
  98. messaging_post_message(MESSAGING_ERROR,MESSAGING_CLASS_SYSTEM, "Display communication failed.");
  99. }
  100. if (CommandHandle) i2c_cmd_link_delete( CommandHandle );
  101. return false;
  102. }
  103. static bool I2CDefaultWriteCommand( struct GDS_Device* Device, uint8_t Command ) {
  104. uint8_t CommandByte = ( uint8_t ) Command;
  105. NullCheck( Device, return false );
  106. return I2CDefaultWriteBytes( Device->Address, true, ( const uint8_t* ) &CommandByte, 1 );
  107. }
  108. static bool I2CDefaultWriteData( struct GDS_Device* Device, const uint8_t* Data, size_t DataLength ) {
  109. NullCheck( Device, return false );
  110. NullCheck( Data, return false );
  111. return I2CDefaultWriteBytes( Device->Address, false, Data, DataLength );
  112. }