This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Import IR transmitter library on nrf52840 thread sdk

Hi,

I want to make universal AC remote, using nrf52840.

I have decoded IR codes of all AC remotes which have been decoded using IRremoteESP8266 library.

Since AC IR codes are quite long and each AC vendor has their own IR Protocol, how can I send long IR codes on nrf52840?

Parents
  • Hi,

    The best solution would be to use the PWM peripheral, as this can output sequences directly from RAM without any CPU intervention.

    We have implemented IR in our Smart Remote 3 reference design. I would recommend you to have a look at the Infrared transmitter documentation, and download the firmware, to look at how it is implemented in the code.

    Best regards,
    Jørgen

  • How did you implement the acknowledgement handler? This should be passed to drv_ir_init(), see m_ir_tx_drv_ack_handler() in m_ir_tx.c.

  • This m_acknowledgement_handler is passed in "drv_ir_send_symbol" in drv_ir_sirc.c file.

    In m_acknowledge_handler(mp_ir_symbol), ir signal to be transmitted is passed in this m_acknowledge handler.

    But after transmitting the signal once, code is stuck in this handler  and keeps on sending garbage values and my board reboots after sometime because of Watchdog which is enabled in main().

    Please suggest what could be done.

  • m_acknowledge_handler is called in drv_ir_send_symbol, but you need to implement it elsewhere in the application. 

    m_acknowledge_handler is assigned the argument acknowledge_handler in drv_ir_init() in the bottom of drv_ir_sirc.c file. If you do not pass a handler to this function when you call drv_ir_init() from your application, it will jump to a random address (or possibly the NULL pointer), which most likely will cause a HardFault.

  • hi,

    Thank you very much for such quick replies.

    I am writing IR driver for Panasonic AC. It consists of 27 bytes (216 bits) message to be transferred but at receiver end I am receiving 220 bits.

    Following is the driver code..

    #include "ir_drv_lib.h"
    
    #include <string.h>
    #include "nrf_drv_pwm.h"
    #include "ir_config.h"
    #include "app_util_platform.h"
    #include "nrf_log.h"
    #include "nrf_delay.h"
    #include "nrf_gpio.h"
    
    STATIC_ASSERT(NRFX_PWM_ENABLED && NRFX_PWM0_ENABLED);
    
    
    #define PANASONIC_GUARD_ZEROS        1
    #define PANASONIC_AC_BITS            216
    
    #define PANASONIC_TOP_VALUE          27           // 36.7kHz carrier 27usec for 1MHz PWM_CLK 1us
    #define PANASONIC_SYMBOL_REPEATS     15            // repeat each symbol 16 times - 16*27.25 = 436us
    
    #define PANASONIC_MARK_SYMBOL        0x800E        // 14/27 usec - duty 1/2
    #define PANASONIC_SPACE_SYMBOL       0x8000
    
    
    #define PANASONIC_REPETION_MAX       0          // X times with 45 ms period
    #define PANASONIC_REPETION_TIME      498784     // 498ms = 498784us
    #define PANASONIC_REPETION_PERIODS   (PANASONIC_REPETION_TIME / PANASONIC_TOP_VALUE)
    
    
    const uint16_t PANASONIC_START[] =
            {PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL,
             PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL,
             PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL};
    
    const uint16_t PANASONIC_ONE[] =
            {PANASONIC_MARK_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL};
    
    const uint16_t PANASONIC_ZERO[] =
            {PANASONIC_MARK_SYMBOL, PANASONIC_SPACE_SYMBOL};
    
    const uint16_t PANASONIC_SECTION_GAP[] =
            {
              PANASONIC_MARK_SYMBOL,  PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL};
    
    const uint16_t PANASONIC_AC_GAP[] =
            { PANASONIC_MARK_SYMBOL,  PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL};
    
    #define MAX_SEQ_SIZE            ARRAY_SIZE(PANASONIC_START) + \
                                    ((PANASONIC_AC_BITS) * MAX(ARRAY_SIZE(PANASONIC_ZERO), ARRAY_SIZE(PANASONIC_ONE))) + \
                                    ARRAY_SIZE(PANASONIC_SECTION_GAP)+ \
                                    ARRAY_SIZE(PANASONIC_START) + \
                                    (PANASONIC_GUARD_ZEROS * ARRAY_SIZE(PANASONIC_AC_GAP))
    
    static nrf_drv_pwm_t m_pwm = CONFIG_IR_TX_PWM_INSTANCE;
    static uint16_t m_seq_pwm_values[MAX_SEQ_SIZE];
    static nrf_pwm_sequence_t m_seq;
    static drv_ir_callback_t m_acknowledge_handler;
    static const ir_symbol_t *mp_ir_symbol;
    static bool m_pwm_active;
    static bool m_enabled_flag;
    
    void DBG_PIN_PULSE(const unsigned int pio) {
        if (IS_IO_VALID(pio)) {
            nrf_gpio_pin_set(pio);
            nrf_delay_us(1);
            nrf_gpio_pin_clear(pio);
        }
    }
    
    
    static void insert_start_symbol(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_START, sizeof(PANASONIC_START));
        *pp_seq += ARRAY_SIZE(PANASONIC_START);
    }
    
    static void insert_one_symbol(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_ONE, sizeof(PANASONIC_ONE));
        *pp_seq += ARRAY_SIZE(PANASONIC_ONE);
    }
    
    static void insert_zero_symbol(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_ZERO, sizeof(PANASONIC_ZERO));
        *pp_seq += ARRAY_SIZE(PANASONIC_ZERO);
    }
    
    static void insert_ac_section_gap(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_SECTION_GAP, sizeof(PANASONIC_SECTION_GAP));
        *pp_seq += ARRAY_SIZE(PANASONIC_SECTION_GAP);
    }
    
    static void insert_dummy_zero(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_AC_GAP, sizeof(PANASONIC_AC_GAP));
        *pp_seq += ARRAY_SIZE(PANASONIC_AC_GAP);
    }
    
    static uint16_t PANASONIC_symbol_encoder(const ir_symbol_t *p_sirc_symbol) {
        uint16_t *p_seq;
        uint8_t address;
        int i;
    
        p_seq = m_seq_pwm_values;
        insert_start_symbol(&p_seq);
    
        for (int a = 0; a < 8; a++) {
            address = p_sirc_symbol->ir_command[a];
            NRF_LOG_INFO("symbol received: %02x", p_sirc_symbol->ir_command[a]);
            for (i = 0; i < 8; i++) {
                if (address & 0x01) {
                    insert_one_symbol(&p_seq);
                } else {
                    insert_zero_symbol(&p_seq);
                }
                address = address >> 1;
            }
        }
    
        insert_ac_section_gap(&p_seq);
        NRF_LOG_INFO("insert ac section gap");
        NRF_LOG_INFO("insert next header");
        insert_start_symbol(&p_seq);
    
        for (int a = 8; a < (p_sirc_symbol->ir_address); a++) {
            address = p_sirc_symbol->ir_command[a];
            NRF_LOG_INFO("symbol received: %02x", p_sirc_symbol->ir_command[a]);
            for (i = 0; i < 8; i++) {
                if (address & 0x01) {
                    insert_one_symbol(&p_seq);
                } else {
                    insert_zero_symbol(&p_seq);
                }
                address = address >> 1;
            }
        }
    
        for (i = 0; i < PANASONIC_GUARD_ZEROS; i++) {
            insert_dummy_zero(&p_seq);
        }
        NRF_LOG_INFO("Length of message: %d", (uint16_t)(p_seq - m_seq_pwm_values));
    
        return (uint16_t)(p_seq - m_seq_pwm_values);
    }
    
    
    static void pwm_handler(nrf_drv_pwm_evt_type_t event) {
        DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_PWM_INT);
    
        if (((event == NRF_DRV_PWM_EVT_END_SEQ0) || (event == NRF_DRV_PWM_EVT_END_SEQ1)) && (mp_ir_symbol == NULL)) {
            nrf_drv_pwm_stop(&m_pwm, true); // Stop during repetition gap.
            m_acknowledge_handler(NULL);     // Acknowledge end.
            m_pwm_active = false;
    
            DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_EACK);
        }
    
    
        if (event == NRF_DRV_PWM_EVT_FINISHED) {
            if ((mp_ir_symbol == NULL)) {
                // Acknowledge end.
                m_acknowledge_handler(NULL);
    
                DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_EACK);
            }
    
            m_pwm_active = false;
        }
    }
    
    ret_code_t drv_ir_send_symbol(const ir_symbol_t *p_ir_symbol) {
        bool callback_flag = false;
        uint16_t seq_length;
    
        if (m_enabled_flag != true) {
            return NRF_ERROR_INVALID_STATE;
        }
    
        CRITICAL_REGION_ENTER();
        mp_ir_symbol = p_ir_symbol;
        if ((mp_ir_symbol == NULL) && !m_pwm_active) {
            callback_flag = true;
        }
        CRITICAL_REGION_EXIT();
    
        if (callback_flag) {
            // Acknowledge of prematurely ended sequence - it won't be acknowledge by handler.
            m_acknowledge_handler(NULL);
            NRF_LOG_INFO("callback;");
            DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_EACK);
        } else if (mp_ir_symbol) {
            seq_length = PANASONIC_symbol_encoder(mp_ir_symbol);
    
           // NRF_LOG_INFO("Message to be send: %d, %d", mp_ir_symbol->ir_address, mp_ir_symbol->ir_command);
            if (seq_length > 0) {
                m_seq.values.p_common = m_seq_pwm_values;
                m_seq.length = seq_length;
                m_seq.repeats = PANASONIC_SYMBOL_REPEATS;
                m_seq.end_delay = PANASONIC_REPETION_PERIODS - ((PANASONIC_SYMBOL_REPEATS + 1) * seq_length);
            } else {
                return NRF_ERROR_NOT_SUPPORTED;
            }
    
            m_pwm_active = true;
            NRF_LOG_INFO("return from drv_ir_send_symbol 1;");
    
            nrf_drv_pwm_simple_playback(&m_pwm, &m_seq, PANASONIC_REPETION_MAX,
                                        NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0 | NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1);
            NRF_LOG_INFO("return from drv_ir_send_symbol 2 ;");
            m_acknowledge_handler(mp_ir_symbol);
            NRF_LOG_INFO("return from drv_ir_send_symbol 3;");
    
            DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_SACK);
        }
    
        NRF_LOG_INFO("return from drv_ir_send_symbol ;");
        return NRF_SUCCESS;
    }
    
    ret_code_t drv_ir_enable(void) {
        ASSERT(m_enabled_flag == false);
    
        m_enabled_flag = true;
        nrf_pwm_enable(m_pwm.p_registers);
    
        return NRF_SUCCESS;
    }
    
    ret_code_t drv_ir_disable(void) {
        NRF_LOG_INFO("PWM disabled 1 ");
    
        ASSERT(m_enabled_flag == true);
    
        NRF_LOG_INFO("PWM disabled");
        nrf_pwm_disable(m_pwm.p_registers);
        m_enabled_flag = false;
    
        return NRF_SUCCESS;
    }
    
    ret_code_t drv_ir_init(drv_ir_callback_t acknowledge_handler) {
        ret_code_t status;
    
        static const nrf_drv_pwm_config_t config =
                {
                        .output_pins =
                                {
                                        IS_IO_VALID(CONFIG_IO_IR_TX_LED) ? CONFIG_IO_IR_TX_LED : NRF_DRV_PWM_PIN_NOT_USED,
                                        NRF_DRV_PWM_PIN_NOT_USED,
                                        NRF_DRV_PWM_PIN_NOT_USED,
                                        NRF_DRV_PWM_PIN_NOT_USED,
                                },
    
                        .irq_priority   = 7,
                        .base_clock     = NRF_PWM_CLK_1MHz,
                        .count_mode     = NRF_PWM_MODE_UP,
                        .top_value      = PANASONIC_TOP_VALUE,
                        .load_mode      = NRF_PWM_LOAD_COMMON,
                        .step_mode      = NRF_PWM_STEP_AUTO
                };
    
        if (acknowledge_handler == NULL) {
            return NRF_ERROR_INVALID_PARAM;
        }
    
        m_acknowledge_handler = m_acknowledge_handler;
        m_enabled_flag = false;
        m_pwm_active = false;
        mp_ir_symbol = NULL;
    
        status = nrf_drv_pwm_init(&m_pwm, &config, pwm_handler);
        if (status == NRF_SUCCESS) {
            nrf_pwm_disable(m_pwm.p_registers);
        }
    
        return status;
    }
    

    Structure type for data is

    typedef struct
    {
        uint8_t ir_command[27];  /**< panasonic signl to be send */
        uint8_t ir_address;  /**< no of bytes to be sent*/
    } ir_symbol_t;

    Could you please help me identify the issue here.

Reply
  • hi,

    Thank you very much for such quick replies.

    I am writing IR driver for Panasonic AC. It consists of 27 bytes (216 bits) message to be transferred but at receiver end I am receiving 220 bits.

    Following is the driver code..

    #include "ir_drv_lib.h"
    
    #include <string.h>
    #include "nrf_drv_pwm.h"
    #include "ir_config.h"
    #include "app_util_platform.h"
    #include "nrf_log.h"
    #include "nrf_delay.h"
    #include "nrf_gpio.h"
    
    STATIC_ASSERT(NRFX_PWM_ENABLED && NRFX_PWM0_ENABLED);
    
    
    #define PANASONIC_GUARD_ZEROS        1
    #define PANASONIC_AC_BITS            216
    
    #define PANASONIC_TOP_VALUE          27           // 36.7kHz carrier 27usec for 1MHz PWM_CLK 1us
    #define PANASONIC_SYMBOL_REPEATS     15            // repeat each symbol 16 times - 16*27.25 = 436us
    
    #define PANASONIC_MARK_SYMBOL        0x800E        // 14/27 usec - duty 1/2
    #define PANASONIC_SPACE_SYMBOL       0x8000
    
    
    #define PANASONIC_REPETION_MAX       0          // X times with 45 ms period
    #define PANASONIC_REPETION_TIME      498784     // 498ms = 498784us
    #define PANASONIC_REPETION_PERIODS   (PANASONIC_REPETION_TIME / PANASONIC_TOP_VALUE)
    
    
    const uint16_t PANASONIC_START[] =
            {PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL,
             PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL, PANASONIC_MARK_SYMBOL,
             PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL};
    
    const uint16_t PANASONIC_ONE[] =
            {PANASONIC_MARK_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL};
    
    const uint16_t PANASONIC_ZERO[] =
            {PANASONIC_MARK_SYMBOL, PANASONIC_SPACE_SYMBOL};
    
    const uint16_t PANASONIC_SECTION_GAP[] =
            {
              PANASONIC_MARK_SYMBOL,  PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL};
    
    const uint16_t PANASONIC_AC_GAP[] =
            { PANASONIC_MARK_SYMBOL,  PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, \
              PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL, PANASONIC_SPACE_SYMBOL};
    
    #define MAX_SEQ_SIZE            ARRAY_SIZE(PANASONIC_START) + \
                                    ((PANASONIC_AC_BITS) * MAX(ARRAY_SIZE(PANASONIC_ZERO), ARRAY_SIZE(PANASONIC_ONE))) + \
                                    ARRAY_SIZE(PANASONIC_SECTION_GAP)+ \
                                    ARRAY_SIZE(PANASONIC_START) + \
                                    (PANASONIC_GUARD_ZEROS * ARRAY_SIZE(PANASONIC_AC_GAP))
    
    static nrf_drv_pwm_t m_pwm = CONFIG_IR_TX_PWM_INSTANCE;
    static uint16_t m_seq_pwm_values[MAX_SEQ_SIZE];
    static nrf_pwm_sequence_t m_seq;
    static drv_ir_callback_t m_acknowledge_handler;
    static const ir_symbol_t *mp_ir_symbol;
    static bool m_pwm_active;
    static bool m_enabled_flag;
    
    void DBG_PIN_PULSE(const unsigned int pio) {
        if (IS_IO_VALID(pio)) {
            nrf_gpio_pin_set(pio);
            nrf_delay_us(1);
            nrf_gpio_pin_clear(pio);
        }
    }
    
    
    static void insert_start_symbol(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_START, sizeof(PANASONIC_START));
        *pp_seq += ARRAY_SIZE(PANASONIC_START);
    }
    
    static void insert_one_symbol(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_ONE, sizeof(PANASONIC_ONE));
        *pp_seq += ARRAY_SIZE(PANASONIC_ONE);
    }
    
    static void insert_zero_symbol(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_ZERO, sizeof(PANASONIC_ZERO));
        *pp_seq += ARRAY_SIZE(PANASONIC_ZERO);
    }
    
    static void insert_ac_section_gap(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_SECTION_GAP, sizeof(PANASONIC_SECTION_GAP));
        *pp_seq += ARRAY_SIZE(PANASONIC_SECTION_GAP);
    }
    
    static void insert_dummy_zero(uint16_t **pp_seq) {
        memcpy(*pp_seq, PANASONIC_AC_GAP, sizeof(PANASONIC_AC_GAP));
        *pp_seq += ARRAY_SIZE(PANASONIC_AC_GAP);
    }
    
    static uint16_t PANASONIC_symbol_encoder(const ir_symbol_t *p_sirc_symbol) {
        uint16_t *p_seq;
        uint8_t address;
        int i;
    
        p_seq = m_seq_pwm_values;
        insert_start_symbol(&p_seq);
    
        for (int a = 0; a < 8; a++) {
            address = p_sirc_symbol->ir_command[a];
            NRF_LOG_INFO("symbol received: %02x", p_sirc_symbol->ir_command[a]);
            for (i = 0; i < 8; i++) {
                if (address & 0x01) {
                    insert_one_symbol(&p_seq);
                } else {
                    insert_zero_symbol(&p_seq);
                }
                address = address >> 1;
            }
        }
    
        insert_ac_section_gap(&p_seq);
        NRF_LOG_INFO("insert ac section gap");
        NRF_LOG_INFO("insert next header");
        insert_start_symbol(&p_seq);
    
        for (int a = 8; a < (p_sirc_symbol->ir_address); a++) {
            address = p_sirc_symbol->ir_command[a];
            NRF_LOG_INFO("symbol received: %02x", p_sirc_symbol->ir_command[a]);
            for (i = 0; i < 8; i++) {
                if (address & 0x01) {
                    insert_one_symbol(&p_seq);
                } else {
                    insert_zero_symbol(&p_seq);
                }
                address = address >> 1;
            }
        }
    
        for (i = 0; i < PANASONIC_GUARD_ZEROS; i++) {
            insert_dummy_zero(&p_seq);
        }
        NRF_LOG_INFO("Length of message: %d", (uint16_t)(p_seq - m_seq_pwm_values));
    
        return (uint16_t)(p_seq - m_seq_pwm_values);
    }
    
    
    static void pwm_handler(nrf_drv_pwm_evt_type_t event) {
        DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_PWM_INT);
    
        if (((event == NRF_DRV_PWM_EVT_END_SEQ0) || (event == NRF_DRV_PWM_EVT_END_SEQ1)) && (mp_ir_symbol == NULL)) {
            nrf_drv_pwm_stop(&m_pwm, true); // Stop during repetition gap.
            m_acknowledge_handler(NULL);     // Acknowledge end.
            m_pwm_active = false;
    
            DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_EACK);
        }
    
    
        if (event == NRF_DRV_PWM_EVT_FINISHED) {
            if ((mp_ir_symbol == NULL)) {
                // Acknowledge end.
                m_acknowledge_handler(NULL);
    
                DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_EACK);
            }
    
            m_pwm_active = false;
        }
    }
    
    ret_code_t drv_ir_send_symbol(const ir_symbol_t *p_ir_symbol) {
        bool callback_flag = false;
        uint16_t seq_length;
    
        if (m_enabled_flag != true) {
            return NRF_ERROR_INVALID_STATE;
        }
    
        CRITICAL_REGION_ENTER();
        mp_ir_symbol = p_ir_symbol;
        if ((mp_ir_symbol == NULL) && !m_pwm_active) {
            callback_flag = true;
        }
        CRITICAL_REGION_EXIT();
    
        if (callback_flag) {
            // Acknowledge of prematurely ended sequence - it won't be acknowledge by handler.
            m_acknowledge_handler(NULL);
            NRF_LOG_INFO("callback;");
            DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_EACK);
        } else if (mp_ir_symbol) {
            seq_length = PANASONIC_symbol_encoder(mp_ir_symbol);
    
           // NRF_LOG_INFO("Message to be send: %d, %d", mp_ir_symbol->ir_address, mp_ir_symbol->ir_command);
            if (seq_length > 0) {
                m_seq.values.p_common = m_seq_pwm_values;
                m_seq.length = seq_length;
                m_seq.repeats = PANASONIC_SYMBOL_REPEATS;
                m_seq.end_delay = PANASONIC_REPETION_PERIODS - ((PANASONIC_SYMBOL_REPEATS + 1) * seq_length);
            } else {
                return NRF_ERROR_NOT_SUPPORTED;
            }
    
            m_pwm_active = true;
            NRF_LOG_INFO("return from drv_ir_send_symbol 1;");
    
            nrf_drv_pwm_simple_playback(&m_pwm, &m_seq, PANASONIC_REPETION_MAX,
                                        NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0 | NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1);
            NRF_LOG_INFO("return from drv_ir_send_symbol 2 ;");
            m_acknowledge_handler(mp_ir_symbol);
            NRF_LOG_INFO("return from drv_ir_send_symbol 3;");
    
            DBG_PIN_PULSE(CONFIG_IO_DBG_IR_TX_SACK);
        }
    
        NRF_LOG_INFO("return from drv_ir_send_symbol ;");
        return NRF_SUCCESS;
    }
    
    ret_code_t drv_ir_enable(void) {
        ASSERT(m_enabled_flag == false);
    
        m_enabled_flag = true;
        nrf_pwm_enable(m_pwm.p_registers);
    
        return NRF_SUCCESS;
    }
    
    ret_code_t drv_ir_disable(void) {
        NRF_LOG_INFO("PWM disabled 1 ");
    
        ASSERT(m_enabled_flag == true);
    
        NRF_LOG_INFO("PWM disabled");
        nrf_pwm_disable(m_pwm.p_registers);
        m_enabled_flag = false;
    
        return NRF_SUCCESS;
    }
    
    ret_code_t drv_ir_init(drv_ir_callback_t acknowledge_handler) {
        ret_code_t status;
    
        static const nrf_drv_pwm_config_t config =
                {
                        .output_pins =
                                {
                                        IS_IO_VALID(CONFIG_IO_IR_TX_LED) ? CONFIG_IO_IR_TX_LED : NRF_DRV_PWM_PIN_NOT_USED,
                                        NRF_DRV_PWM_PIN_NOT_USED,
                                        NRF_DRV_PWM_PIN_NOT_USED,
                                        NRF_DRV_PWM_PIN_NOT_USED,
                                },
    
                        .irq_priority   = 7,
                        .base_clock     = NRF_PWM_CLK_1MHz,
                        .count_mode     = NRF_PWM_MODE_UP,
                        .top_value      = PANASONIC_TOP_VALUE,
                        .load_mode      = NRF_PWM_LOAD_COMMON,
                        .step_mode      = NRF_PWM_STEP_AUTO
                };
    
        if (acknowledge_handler == NULL) {
            return NRF_ERROR_INVALID_PARAM;
        }
    
        m_acknowledge_handler = m_acknowledge_handler;
        m_enabled_flag = false;
        m_pwm_active = false;
        mp_ir_symbol = NULL;
    
        status = nrf_drv_pwm_init(&m_pwm, &config, pwm_handler);
        if (status == NRF_SUCCESS) {
            nrf_pwm_disable(m_pwm.p_registers);
        }
    
        return status;
    }
    

    Structure type for data is

    typedef struct
    {
        uint8_t ir_command[27];  /**< panasonic signl to be send */
        uint8_t ir_address;  /**< no of bytes to be sent*/
    } ir_symbol_t;

    Could you please help me identify the issue here.

Children
No Data
Related