ir_transmit.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #include <string.h>
  2. #include "freertos/FreeRTOS.h"
  3. #include "freertos/task.h"
  4. #include "freertos/queue.h"
  5. #include "esp_log.h"
  6. #include "driver/rmt.h"
  7. #include "toshiba_ir.h"
  8. #include "ir_transmit.h"
  9. #include "config.h"
  10. #ifdef IR_TRANSMIT
  11. extern uint8_t bitReverse(uint8_t b);
  12. // RMT values
  13. #define RMT_TX_CHANNEL RMT_CHANNEL_0
  14. #define RMT_TX_GPIO GPIO_NUM_26
  15. // channel clock period = 1 uS
  16. #define RMT_CLK_DIV 80
  17. // Variable that holds the IR protocol transmission. 1 start bit, 8*8+19*8 data bits and one stop bit
  18. #define STATIC_PRE_BYTES 8
  19. #define DYN_DATA_BYTES 19
  20. #define TOT_DATA_BYTES (STATIC_PRE_BYTES+DYN_DATA_BYTES)
  21. #define RMT_BITS (1+(STATIC_PRE_BYTES*8)+1+1+(DYN_DATA_BYTES*8)+1+1) // 221 bits in total
  22. rmt_item32_t toshiba_rmt[RMT_BITS];
  23. uint8_t irTxData[TOT_DATA_BYTES];
  24. QueueHandle_t toshibaTxQueue = NULL;
  25. void copyDataToRmtArray( const uint8_t rmtStartBit, const uint8_t* data, const uint8_t noOfBytes, const bool reverseByte) {
  26. for(uint8_t b=0;b<noOfBytes*8;b++) {
  27. uint8_t byteNo = b / 8;
  28. uint8_t byte = (reverseByte) ? bitReverse(data[byteNo]) : data[byteNo];
  29. uint8_t shiftBits = b % 8;
  30. uint8_t bit_data = (1u << (7-shiftBits)) & byte;
  31. uint32_t space = bit_data ? kPanasonicAcOneSpace : kPanasonicAcZeroSpace;
  32. toshiba_rmt[b+rmtStartBit].val = ((kPanasonicAcBitMark+5) << 0) | (1 << 15) | (space << 16);
  33. }
  34. }
  35. void correctIrTxDataChecksum() {
  36. irTxData[TOT_DATA_BYTES-1] = 0xFA;
  37. for( uint8_t b=0+STATIC_PRE_BYTES ; b<(TOT_DATA_BYTES-1) ; b++ ) {
  38. irTxData[TOT_DATA_BYTES-1] += irTxData[b];
  39. }
  40. }
  41. void toshibaTxTask(void *pvParameter)
  42. {
  43. ESP_LOGI("IR_TRANSMIT", "toshibaTxTask() starting.");
  44. uint8_t data[8];
  45. while( true ) {
  46. if( xQueueReceive( toshibaTxQueue, data, 100 ) == pdTRUE ) {
  47. ESP_LOGI("IR_TRANSMIT","Received a TX from MQTT");
  48. uint8_t irPair = 1;
  49. for(uint8_t b=0;b<kPanasonicNumberOfBits;b++) {
  50. uint8_t byteNo = b / 8;
  51. uint8_t shiftBits = b % 8;
  52. uint8_t bit_data = (1u << (7-shiftBits)) & data[byteNo];
  53. uint32_t space = bit_data ? kPanasonicAcOneSpace : kPanasonicAcZeroSpace;
  54. toshiba_rmt[irPair].val = (kPanasonicAcBitMark << 0) | (1 << 15) | (space << 16); // Header of IR Transmit
  55. irPair++;
  56. }
  57. ESP_ERROR_CHECK(rmt_write_items(RMT_TX_CHANNEL, &(toshiba_rmt[0]), 1+72+1, true));
  58. }
  59. }
  60. }
  61. void initIrTransmit() {
  62. const esp_err_t uninstRetVal = rmt_driver_uninstall(RMT_TX_CHANNEL);
  63. ESP_LOGI("IR_TRANSMIT","Uninst: %u", uninstRetVal);
  64. rmt_config_t rmt_tx;
  65. memset(&rmt_tx,0,sizeof(rmt_config_t));
  66. rmt_tx.rmt_mode = RMT_MODE_TX;
  67. rmt_tx.channel = RMT_TX_CHANNEL;
  68. rmt_tx.gpio_num = GPIO_IR_TX_DATA;
  69. rmt_tx.mem_block_num = 1;
  70. rmt_tx.clk_div = RMT_CLK_DIV;
  71. rmt_tx.tx_config.loop_en = false;
  72. rmt_tx.tx_config.carrier_duty_percent = 30;
  73. rmt_tx.tx_config.carrier_freq_hz = 38000;
  74. rmt_tx.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH;
  75. rmt_tx.tx_config.carrier_en = true;
  76. rmt_tx.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
  77. rmt_tx.tx_config.idle_output_en = true;
  78. rmt_tx.flags = 0;
  79. ESP_LOGI("IR_TRANSMIT","Install driver....");
  80. ESP_ERROR_CHECK( rmt_config(&rmt_tx) );
  81. const esp_err_t retVal = rmt_driver_install(rmt_tx.channel, 0, 0);
  82. if( retVal != ESP_OK ) {
  83. ESP_LOGE("IR_TRANSMIT","Error on driver install %u",retVal);
  84. return;
  85. }
  86. //ESP_ERROR_CHECK( rmt_driver_install(rmt_tx.channel, 0, 0) );
  87. // Init the ir default Panasonic IR data field
  88. /**
  89. * The IR is divided into 2 parts
  90. * 0 Start
  91. * 1 64 fixed bits
  92. * 65 A gap
  93. * 66 Start (again)
  94. * 67 152 bits with data
  95. * 219 Stop
  96. * 220 End-marker (Not sent)
  97. *
  98. */
  99. toshiba_rmt[0].val = (kPanasonicAcHdrMark << 0) | (1 << 15) | (kPanasonicAcHdrSpace << 16);
  100. toshiba_rmt[65].val = (kPanasonicAcBitMark << 0) | (1 << 15) | (kPanasonicAcUsualGap << 16);
  101. toshiba_rmt[66].val = (kPanasonicAcHdrMark << 0) | (1 << 15) | (kPanasonicAcHdrSpace << 16);
  102. toshiba_rmt[219].val = (kPanasonicAcBitMark << 0) | (1 << 15) | (kPanasonicAcZeroSpace << 16);
  103. toshiba_rmt[220].val = (1 << 16); // RMT End marker
  104. // Setup the fixed 64 bits: 0x4004072000000060 (Sent like this)
  105. //const uint8_t fixedData[STATIC_PRE_BYTES]={0x40,0x04,0x07,0x20,0x0,0x00,0x0,0x60}; // Non-reversed
  106. const uint8_t fixedData[STATIC_PRE_BYTES]={0x02,0x20,0xE0,0x04,0x00,0x00,0x00,0x06}; // Reversed
  107. memcpy(&irTxData[0],(void *)&fixedData[0],STATIC_PRE_BYTES); // Copy the fixed data
  108. // Setup the the real 152 data bits
  109. const uint8_t confData[DYN_DATA_BYTES]={0x02,0x20,0xE0,0x04,0x00,0x49,0x31,0x86, // 0x86 is correct
  110. 0xA3,0x06,0x00,0x0E,0xE0,0x00,0x00,0x89,
  111. 0x00,0x00,0x20 };
  112. memcpy(&irTxData[0+STATIC_PRE_BYTES],(void *)&confData[0],DYN_DATA_BYTES);
  113. correctIrTxDataChecksum();
  114. copyDataToRmtArray(1,&irTxData[0],STATIC_PRE_BYTES,true);
  115. copyDataToRmtArray(67,&irTxData[8],DYN_DATA_BYTES,true);
  116. toshibaTxQueue = xQueueCreate( 5, IR_TX_QUEUE_DATA_SIZE );
  117. //xTaskCreatePinnedToCore(toshibaTxTask, "toshibaTxTask", 1024*10, NULL, 2, NULL,0);
  118. ESP_LOGI("IR_TRANSMIT","Init done.");
  119. ESP_ERROR_CHECK(rmt_write_items(RMT_TX_CHANNEL, &(toshiba_rmt[0]), RMT_BITS, true));
  120. }
  121. #endif