Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

Set delay time between two functions

Posted by yeerang on December 11, 2014

Hi.

I want to call the function i2cmastertransaction() in the task, and there are i2csend() and i2creceive() in the i2cmastertransaction() function. Those i2csend() and i2creceive() functions operates with Queue.

I would like to set some delay time between i2csend() and i2creceive(), but it seems that delay_us() and vTaskDelay were not effective.

Could you advise how to set the delay time in the task? Thank you in advance.


Set delay time between two functions

Posted by heinbali01 on December 11, 2014

Hi Yeerang,

Functions like delay_us() are implemented as counted loops, using the CPU intensively.

vTaskDelay() has a lower resolution (of 1 clock tick) but it does make the task sleep.

Your i2C_receive() already blocks while waiting for data in xQueueReceive(), why would you want to have an extra delay?

Regards.


Set delay time between two functions

Posted by yeerang on December 11, 2014

Because if i2c_receive() request the response too fast, there will be the value which means 'the response is not ready'. Could I set the delay time using the vTaskDelay()?


Set delay time between two functions

Posted by heinbali01 on December 11, 2014

You can always use:

~~~~~ void vTaskDelay( const TickType_t xTicksToDelay ) ~~~~~

to introduce some delay.

Your i2c_receive() calls xQueueReceive() and if it is called too quickly, you say there is a value which means 'the response is not ready'.

Shouldn't it just wait once more until the real response comes in?


Set delay time between two functions

Posted by yeerang on December 12, 2014

I don't get what you mentioned in the last line.

I alreaday tried to use vTaskDelay as below: >i2cmastertransaction(){ i2csend(); vTaskDelay(); i2creceive(); }

And it was not working as what I wanted.


Set delay time between two functions

Posted by rtel on December 12, 2014
i2c_master_transaction(){
i2c_send();
vTaskDelay();
i2c_receive();

It is a bit of a crude device in this case. Ideally you would want to be using DMA or at least interrupt and let the hardware do it for you (assuming you are using an I2C peripheral, and not just bit-banging the protocol through an IO port. If not then the next best is to make no assumptions about timing, but instead query the hardware to see the system state (i.e. read the registers).

Regards.


Set delay time between two functions

Posted by heinbali01 on December 12, 2014

In my experience, writing a perfect interrupt-driven TWI (I2C) device driver is very complex. Using DMA will make it more efficient but also more complex. Within each interrupt you'll have to ask your self: where am I in the process? what has been done? What must be done now?

Also, very important is error handling. It is possible that some TWI device gets into a state where the bus becomes totally unusable. In that case there are two ways to solve it: either a total power reset, or a bus-reset.

In case you'll encounter a blocked bus in which SDA is constantly low, here's a way to do a bus-reset:

~~~~~

void setdatadir( int direction ); void setdataval( int value );

int get_data( void ); /* read the SDA pin */

void setclockdir( int direction ); void setclockval( int value );

void us_delay( int useconds );

void twigpioreset (int aDoLock) { int bitNr; /* * In case a part is keeping SDA constantly low by * pulling it down, a bus reset is needed: * 1. Clock up to 9 cycles while SDA in high-impedance * 2. Look for SDA high in each cycle while SCL is high * 3. Create a start condition as SDA is high. */

/* First define SDA/SCL temporarily as normal GPIO's */

set_clock( 1 );
set_data( 1 );
set_clock_dir( _OUTPUT );
set_data_dir( _INPUT );
{
    // CLOCK  11110011 11001010 10101010 10101010
    unsigned clock_pattern = 0xF3CAAAAA;
    // DATA   11100001 10011111 11111111 11111111
    unsigned data_pattern  = 0xE19FFFFF;
    // READ   00000000 00001111 11111111 11111111
    unsigned read_pattern  = 0x000FFFFF;

    for (bitNr = 0; bitNr < 32; bitNr++) {
        /* Clock out any data a slave might have */
        set_clock_val( clock_pattern & 1 );

        if (read_pattern & 1)
        {
            set_data_dir( _INPUT );
        }
        else
        {
            set_data_dir( _OUTPUT );
            set_data_val( data_pattern & 1 );
        }
        us_delay( 20 ); /* Minimal 20 uS delay */

        if( ( read_pattern & 1 ) &&
            ( clock_pattern & 1 ) &&
            ( get_data( ) != 0 ) )
        {
            /* A device has released the SDA.
             * This should happen between 1 and 9 bits.
             */
            break;
        }
        clock_pattern >>= 1;
        data_pattern  >>= 1;
        read_pattern  >>= 1;
    }
}
/* Give SDA/SCL pins back to the TWI peripheral */

} ~~~~~

How much data do you exchange with your I2C devices and how often?

If you're polling some chip occasionally, like once a second, you could also consider leaving-out the interrupts and DMA and just send, poll, receive.

Regards, Hein


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists