<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>TWIM easydma write write fails</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/53735/twim-easydma-write-write-fails</link><description>Hi, 
 I&amp;#39; m trying to create a TMIM easydma sequence to same an ADC. The sequence involves a write, and timer delay and a read. 
 Given what I&amp;#39;m trying to achieve, I think I need to perform a write, without stopping the transaction. 
 I&amp;#39;m having problems</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 10 Mar 2020 12:14:16 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/53735/twim-easydma-write-write-fails" /><item><title>RE: TWIM easydma write write fails</title><link>https://devzone.nordicsemi.com/thread/239094?ContentTypeID=1</link><pubDate>Tue, 10 Mar 2020 12:14:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3ede9b87-9049-4547-8a95-bc19d0ce658b</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;The TX and RX buffer is setup on&amp;nbsp;nrf_drv_twi_xfer().&lt;/p&gt;
&lt;p&gt;Best regards,&lt;br /&gt;Kenneth&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TWIM easydma write write fails</title><link>https://devzone.nordicsemi.com/thread/239090?ContentTypeID=1</link><pubDate>Tue, 10 Mar 2020 12:02:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7dca90f1-cbb8-4f66-9668-92c27dcb4269</guid><dc:creator>jawadk</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I was not able to fined where you&amp;nbsp;set the TX buffer before the transfer.&lt;/p&gt;
&lt;p&gt;I need to trigger by PPI a TWI transfer only .&lt;/p&gt;
&lt;p&gt;Best Regards&lt;/p&gt;
&lt;p&gt;Jawad&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TWIM easydma write write fails</title><link>https://devzone.nordicsemi.com/thread/217712?ContentTypeID=1</link><pubDate>Thu, 31 Oct 2019 09:25:14 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c8b1d4d9-d7b3-4495-a95e-c92b00781750</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;A long time ago I made an example which I think can be used as a reference.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
 *
 * The information contained herein is property of Nordic Semiconductor ASA.
 * Terms and conditions of usage are described in detail in NORDIC
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 *
 * Licensees are granted free, non-transferable use of the information. NO
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 * the file.
 *
 */

/**
 * @file
 * @brief File with example code presenting usage of drivers for TWI in master mode with EasyDMA
 *
 * @sa twi_master_with_mma7660_slave_example
 */

#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;ctype.h&amp;gt;
#include &amp;quot;config.h&amp;quot;
#include &amp;quot;app_uart.h&amp;quot;
#include &amp;quot;nrf_drv_twi_mod.h&amp;quot;
#include &amp;quot;nrf_gpio.h&amp;quot;
#include &amp;quot;app_error.h&amp;quot;
#include &amp;quot;nrf.h&amp;quot;
#include &amp;quot;bsp.h&amp;quot;
#include &amp;quot;app_util_platform.h&amp;quot;
#include &amp;quot;mma7660.h&amp;quot;
#include &amp;quot;nrf_delay.h&amp;quot;
#include &amp;quot;nrf_drv_twi_mod.h&amp;quot;
#include &amp;quot;nrf_drv_ppi.h&amp;quot;

#define SENSOR_POLL_RATE SAMPLES_PER_SEC_4

static const nrf_drv_twi_t m_twi_master = NRF_DRV_TWI_INSTANCE(0);
static uint8_t m_rxbuf[3] = {0, 0, 0};
static uint8_t m_txbuf[1] = {0};

// How frequently the RTC should read the accel.
uint32_t rtc_init(mma7660_mode_t sensor_poll_mode)
{
    NRF_CLOCK-&amp;gt;TASKS_LFCLKSTART = 1;
    while (NRF_CLOCK-&amp;gt;EVENTS_LFCLKSTARTED == 0);
    
    NRF_RTC0-&amp;gt;PRESCALER = 0;
    NRF_RTC0-&amp;gt;EVTENSET = RTC_EVTENSET_COMPARE0_Msk;    
    uint32_t cc0_value;
    switch (sensor_poll_mode)
    {
        case SAMPLES_PER_SEC_120:
            cc0_value = 273 - 1;
            break;
        case SAMPLES_PER_SEC_64:
            cc0_value = 512 - 1;
            break;
        case SAMPLES_PER_SEC_32:
            cc0_value = 1024 - 1;
            break;
        case SAMPLES_PER_SEC_16:
            cc0_value = 2048 - 1;
            break;
        case SAMPLES_PER_SEC_8:
            cc0_value = 4096 - 1;
            break;
        case SAMPLES_PER_SEC_4:
            cc0_value = 8192 - 1;
            break;
        case SAMPLES_PER_SEC_2:
            cc0_value = 16384 - 1;
            break;
        case SAMPLES_PER_SEC_1:
            cc0_value = 32768 - 1;
            break;
        default:
            return NRF_ERROR_INVALID_PARAM;            
    }
    NRF_RTC0-&amp;gt;CC[0] = cc0_value;
    NRF_RTC0-&amp;gt;TASKS_START =1;
    return NRF_SUCCESS;
}

// Enable PPI channels to connect the RTC Compare0 event to trigger TWI transfer without CPU interaction.
uint32_t ppi_init(uint32_t * p_twim_master_start_task)
{
    uint32_t err_code;
    nrf_ppi_channel_t ppi_channel, ppi_channel2;

    err_code = nrf_drv_ppi_channel_alloc(&amp;amp;ppi_channel);
    if (err_code != NRF_SUCCESS)
        return err_code;
    // Create a PPI channel from RTC Compare0 event to start TWI transfer task
    err_code = nrf_drv_ppi_channel_assign(ppi_channel, (uint32_t)&amp;amp;NRF_RTC0-&amp;gt;EVENTS_COMPARE[0], (uint32_t)*p_twim_master_start_task);
    if (err_code != NRF_SUCCESS)
        return err_code;    

    err_code = nrf_drv_ppi_channel_enable(ppi_channel);
    if (err_code != NRF_SUCCESS)
        return err_code;    

    err_code = nrf_drv_ppi_channel_alloc(&amp;amp;ppi_channel2);
    if (err_code != NRF_SUCCESS)
        return err_code;
    // Create a PPI channel from Compare0 event to clear RTC timer (repeated until stopped)
    err_code = nrf_drv_ppi_channel_assign(ppi_channel2, (uint32_t)&amp;amp;NRF_RTC0-&amp;gt;EVENTS_COMPARE[0], (uint32_t)&amp;amp;NRF_RTC0-&amp;gt;TASKS_CLEAR);
    if (err_code != NRF_SUCCESS)
        return err_code;    

    err_code = nrf_drv_ppi_channel_enable(ppi_channel2);
    
    return err_code;
}

// Callback  executed after every twi transfer (in this case just outputs the data over the UART)
void twi_cb_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
    // Pack the raw data into a more representable format and cast to int8_t (or with 0xE0, see MMA7660 data output values)
    if(m_rxbuf[0] &amp;gt; 31) m_rxbuf[0] = m_rxbuf[0] | 0xE0;        
    if(m_rxbuf[1] &amp;gt; 31) m_rxbuf[1] = m_rxbuf[1] | 0xE0;        
    if(m_rxbuf[2] &amp;gt; 31) m_rxbuf[2] = m_rxbuf[2] | 0xE0;        
    
    printf(&amp;quot;%4i %4i %4i \n\r&amp;quot;, (int8_t)m_rxbuf[0], (int8_t)m_rxbuf[1], (int8_t)m_rxbuf[2]);
}

// Init the TWI module; speed, pins, and callback &amp;#39;twi_cb_handler()&amp;#39;
static ret_code_t twi_master_init(void)
{
    ret_code_t ret;
    const nrf_drv_twi_config_t config =
    {
       .scl                = 27,
       .sda                = 26,
       .frequency          = NRF_TWI_FREQ_400K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH
    };

    do
    {
        ret = nrf_drv_twi_init(&amp;amp;m_twi_master, &amp;amp;config, twi_cb_handler, NULL);
        if(NRF_SUCCESS != ret)
        {
            break;
        }
        nrf_drv_twi_enable(&amp;amp;m_twi_master);
    }while(0);
    return ret;
}

// UART error handler.
static void uart_error_handle(app_uart_evt_t * p_event)
{
    if (p_event-&amp;gt;evt_type == APP_UART_COMMUNICATION_ERROR)
    {
        APP_ERROR_HANDLER(p_event-&amp;gt;data.error_communication);
    }
    else if (p_event-&amp;gt;evt_type == APP_UART_FIFO_ERROR)
    {
        APP_ERROR_HANDLER(p_event-&amp;gt;data.error_code);
    }
}

// UART used to output debug and accel. data in &amp;#39;twi_cb_handler()&amp;#39;
uint32_t uart_init(void)
{
    uint32_t err_code;
    const app_uart_comm_params_t comm_params =
    {
        RX_PIN_NUMBER,
        TX_PIN_NUMBER,
        RTS_PIN_NUMBER,
        CTS_PIN_NUMBER,
        APP_UART_FLOW_CONTROL_ENABLED,
        false,
        UART_BAUDRATE_BAUDRATE_Baud460800
    };

    APP_UART_FIFO_INIT(&amp;amp;comm_params,
                       4,
                       32,
                       uart_error_handle,
                       APP_IRQ_PRIORITY_LOW,
                       err_code);
    return err_code;
}

// Setup parameters (buffers, type of transfer, and flags) for the next twi transfer by calling &amp;#39;nrf_drv_twi_xfer()&amp;#39;
// Useful information: &amp;#39;nrf_drv_twi_rx()&amp;#39; and &amp;#39;nrf_drv_twi_tx()&amp;#39; wraps around this function (refer to those also for example on how to setup &amp;#39;nrf_drv_twi_xfer()&amp;#39;)
uint32_t twim_sync_xfer_setup(uint32_t * p_twim_master_start_task)
{
    nrf_drv_twi_xfer_desc_t p_xfer_desc;
    uint32_t err_code;    
    
    p_xfer_desc.address = MMA7660_DEFAULT_ADDRESS;
    p_xfer_desc.type = NRF_DRV_TWI_XFER_TXRX;
    p_xfer_desc.primary_length = 1;
    p_xfer_desc.secondary_length = 3;
    p_xfer_desc.p_primary_buf = m_txbuf;
    p_xfer_desc.p_secondary_buf = m_rxbuf;
    
    uint32_t flags = NRF_DRV_TWI_FLAG_HOLD_XFER | NRF_DRV_TWI_FLAG_REPEATED_XFER;

    do 
    {
        err_code = nrf_drv_twi_xfer(&amp;amp;m_twi_master, &amp;amp;p_xfer_desc, flags);
        
        // If success, read out task required to start the twi transfer, will be used to setup the correct PPI channel to trigger the twi transfer.
        if(err_code == NRF_SUCCESS)
        {
            * p_twim_master_start_task = nrf_drv_twi_start_task_get(&amp;amp;m_twi_master, NRF_DRV_TWI_XFER_TXRX); 
        }
    } while (err_code == NRF_ERROR_BUSY);   
    
    return err_code;
}

/**
 *  The begin of the journey
 */
int main(void)
{    
	uint32_t twim_master_start_task;
	
    // For debugging purposes only, writes accel. data to UART in twi callback &amp;#39;twi_cb_handler()&amp;#39;
    APP_ERROR_CHECK(uart_init());  

    // Init. twi module, need to provide a callback &amp;#39;twi_cb_handler()&amp;#39;, else each call to twi driver will be blocking
    APP_ERROR_CHECK(twi_master_init());        
    
    // Write some init. twi data to the accel. to enable it, create new data every &amp;#39;SENSOR_POLL_RATE&amp;#39;
    APP_ERROR_CHECK(mma7660_init(&amp;amp;m_twi_master, SENSOR_POLL_RATE));    

    // Setup repeated twi transfer (e.g. provide tx and rx buffers and type of twi transfer), each twi transfer can now be triggered by &amp;#39;twim_master_start_task&amp;#39;
    APP_ERROR_CHECK(twim_sync_xfer_setup(&amp;amp;twim_master_start_task));    
    
    // Enable ppi channel from RTC compare0 event to start twi transfer &amp;#39;twim_master_start_task&amp;#39;
    // Useful information: Could have used a pin interrupt from the accel. to trigger twi transfer, but the mbed module doesn&amp;#39;t expose the interrupt data ready pin, so use RTC instead
    APP_ERROR_CHECK(ppi_init(&amp;amp;twim_master_start_task));
    
    // Start RTC, RTC ompare0 event will execute twi transfer on every &amp;#39;SENSOR_POLL_RATE&amp;#39;
    APP_ERROR_CHECK(rtc_init(SENSOR_POLL_RATE));
    
    // No more CPU activity needed, go to sleep, CPU only interrupted when data is ready in buffer in twi callback &amp;#39;twi_cb_handler()&amp;#39;.
    // RTC Compare0 event wil ensure data is read at specific intervals by triggering twi transfer through PPI, while CPU can process the data at it&amp;#39;s own pace.
    SCB-&amp;gt;SCR |= SCB_SCR_SEVONPEND_Msk;    
    while(1)
    {
        __sev();
        __wfe();
        __wfe();
    }        
}

/** @} */ /* End of group twi_master_with_mma7660_slave_example */

&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TWIM easydma write write fails</title><link>https://devzone.nordicsemi.com/thread/217610?ContentTypeID=1</link><pubDate>Wed, 30 Oct 2019 17:40:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:469cbb5a-d38c-48dd-b53e-c77c3568a9a3</guid><dc:creator>Paul</dc:creator><description>&lt;p&gt;Hi Kenneth,&lt;/p&gt;
&lt;p&gt;Thanks for your reply!&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When you say the twi driver, do you refer to the current or legacy?&lt;/p&gt;
&lt;p&gt;The code above which works uses the legacy form of the twi driver, however its either&lt;/p&gt;
&lt;p&gt;blocking or interrupt based. I&amp;#39;ve looked at the source and it all seems to map down to&lt;/p&gt;
&lt;p&gt;the same NRFX easydma based driver.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If I make the calls in form:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt; uint8_t tx_buf[1] = {0x88};&lt;br /&gt; nrfx_twim_xfer_desc_t xfer = NRFX_TWIM_XFER_DESC_TX(addr, (uint8_t*)tx_buf, sizeof(tx_buf));&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;uint32_t err_code = nrfx_twim_xfer(&amp;amp;(twi_instance_00.u.twim), &amp;amp;xfer, 0);&lt;/p&gt;
&lt;p&gt;APP_ERROR_CHECK(err_code);&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Which replicates whats in nrf_drv_twi_tx&amp;nbsp;&amp;nbsp;, its work, and successfully writes.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;However my understanding is that this code is blocking the same as&amp;nbsp;nrf_drv_twi_tx&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If however I try to make defer execution and suitable for initiation via PPI:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;uint32_t flags = NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER |&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NRFX_TWIM_FLAG_TX_NO_STOP |&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NRF_DRV_TWI_FLAG_HOLD_XFER;&lt;br /&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;uint32_t err_code = nrfx_twim_xfer(&amp;amp;(twi_instance_00.u.twim), &amp;amp;xfer, flags);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;then the&amp;nbsp;nrfx_twim_xfer call never completes?!?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Any ideas?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;BR, Paul&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TWIM easydma write write fails</title><link>https://devzone.nordicsemi.com/thread/217373?ContentTypeID=1</link><pubDate>Tue, 29 Oct 2019 15:17:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:221af81d-2cf8-4bcc-be2b-6f9afb06d0d1</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;Why not use the TWI driver?&lt;/p&gt;
&lt;p&gt;Kenneth&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TWIM easydma write write fails</title><link>https://devzone.nordicsemi.com/thread/217148?ContentTypeID=1</link><pubDate>Mon, 28 Oct 2019 14:40:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:352ce14c-52dd-4c6f-96be-c5b66b545f56</guid><dc:creator>Paul</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Additionally would like to add main:&lt;/p&gt;
&lt;p&gt;int main(void)&lt;br /&gt;{&lt;br /&gt; ret_code_t err_code;&lt;br /&gt; log_init();&lt;br /&gt; NRF_LOG_INFO(&amp;quot;Start fwtest\r\n&amp;quot;);&lt;br /&gt; NRF_LOG_FLUSH();&lt;/p&gt;
&lt;p&gt;NRF_TWIM0-&amp;gt;PSEL.SCL = PIN_SCL;&lt;br /&gt; NRF_TWIM0-&amp;gt;PSEL.SDA = PIN_SDA;&lt;/p&gt;
&lt;p&gt;NRF_TWIM0-&amp;gt;ADDRESS = DEVICE_ADDRESS;&lt;br /&gt; NRF_TWIM0-&amp;gt;FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K400 &amp;lt;&amp;lt; TWIM_FREQUENCY_FREQUENCY_Pos;&lt;br /&gt; NRF_TWIM0-&amp;gt;SHORTS = 0;&lt;/p&gt;
&lt;p&gt;NRF_TWIM0-&amp;gt;ENABLE = TWIM_ENABLE_ENABLE_Enabled &amp;lt;&amp;lt; TWIM_ENABLE_ENABLE_Pos;&lt;/p&gt;
&lt;p&gt;simple_test();&lt;br /&gt; //simple_mixed_test();&lt;/p&gt;
&lt;p&gt;while (1)&lt;br /&gt; {&lt;br /&gt; __WFE();&lt;br /&gt; }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>