Serialization nrf52: How to send a GPIO interrupt from connectivity chip before sending the event to the application chip?

I am trying to understand how to implement Serialization mode on nrf52. 

Rather than having an observer on the application chip, I want the application chip to get alerted of a BLE event via a GPIO interrupt. Keeping the serialization example code for the connectivity chip in mind (PCA10040 s132), which will be the best spot to set this interrupt (set a GPIO pin physically connected to the application chip) in the code?

Also, how to make sure that the incoming BLE events are not lost until the application chip calls the sd_ble_evt_get() function after receiving the interrupt.

Thank you

Parents Reply Children
  • Hello Kenneth! 

    Thank you for the response. I apologize - I forgot to mention that I intend to use the UART RAW communication between the application and connectivity chip. I went through the documentation for that and the example code but couldn't find the code snippet where an interrupt is being sent to the application chip from the connectivity chip. 

    The following is function called to send the packet out and inform the upper transport layer that the packet has been transmitted. 

    uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
    {
        if (p_buffer == NULL)
        {
            return NRF_ERROR_NULL;
        }
        else if (num_of_bytes == 0)
        {
            return NRF_ERROR_INVALID_PARAM;
        }
    
        bool busy;
    
        CRITICAL_REGION_ENTER();
        busy = m_tx_in_progress;
        m_tx_in_progress = true;
        CRITICAL_REGION_EXIT();
    
        if (busy)
        {
            return NRF_ERROR_BUSY;
        }
    
        (void)uint16_encode(num_of_bytes, m_tx_header_buf);
        mp_tx_buffer = p_buffer;
        m_bytes_to_transmit = num_of_bytes;
        APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, m_tx_header_buf,
            SER_PHY_HEADER_SIZE));
    
        return NRF_SUCCESS;
    }
    

    The following two snippets are the UART driver code to actually transmit the packet out:

    __STATIC_INLINE
    ret_code_t nrf_drv_uart_tx(nrf_drv_uart_t const * p_instance,
                               uint8_t const *        p_data,
                               uint8_t                length)
    {
        uint32_t result = 0;
        if (NRF_DRV_UART_USE_UARTE)
        {
            result = nrfx_uarte_tx(&p_instance->uarte,
                                   p_data,
                                   length);
        }
        else if (NRF_DRV_UART_USE_UART)
        {
            result = nrfx_uart_tx(&p_instance->uart,
                                  p_data,
                                  length);
        }
        return result;
    }

    nrfx_err_t nrfx_uart_tx(nrfx_uart_t const * p_instance,
                            uint8_t const *     p_data,
                            size_t              length)
    {
        uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
        NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
        NRFX_ASSERT(p_data);
        NRFX_ASSERT(length > 0);
    
        nrfx_err_t err_code;
    
        if (nrfx_uart_tx_in_progress(p_instance))
        {
            err_code = NRFX_ERROR_BUSY;
            NRFX_LOG_WARNING("Function: %s, error code: %s.",
                             __func__,
                             NRFX_LOG_ERROR_STRING_GET(err_code));
            return err_code;
        }
        p_cb->tx_buffer_length = length;
        p_cb->p_tx_buffer      = p_data;
        p_cb->tx_counter       = 0;
        p_cb->tx_abort         = false;
    
        NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
        NRFX_LOG_DEBUG("Tx data:");
        NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
                               p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));
    
        err_code = NRFX_SUCCESS;
    
        nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY);
        nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTTX);
    
        tx_byte(p_instance->p_reg, p_cb);
    
        if (p_cb->handler == NULL)
        {
            if (!tx_blocking(p_instance->p_reg, p_cb))
            {
                // The transfer has been aborted.
                err_code = NRFX_ERROR_FORBIDDEN;
            }
            else
            {
                // Wait until the last byte is completely transmitted.
                while (!nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_TXDRDY))
                {}
                nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX);
            }
            p_cb->tx_buffer_length = 0;
        }
    
        NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }

    Nowhere in here do I see an interrupt being set before sending the packet out. (I am imagining this as some GPIO pin being set in order to cause an interrupt on the application chip). I think I am missing that part of the code in the example (ble_connectivity_s132_uart_pca10040). Could you please point that code snippet out to me? 

    I need to set an interrupt pin in order wake up the application chip incase it is in some kind of low power mode. 

  • From the SPI implementation it seems the set/clearing of pin_req is handled in ser_conn_ble_event_handle() and ser_phy_tx_pkt_send(). I suggest to do the same.

    Kenneth

Related