⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* I2C bus common (driver-independent) primitives implementation. * * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia * Author: Victor V. Vengerov <vvv@oktet.ru> * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * * http://www.rtems.com/license/LICENSE. * * @(#) $Id: i2c.c,v 1.1.4.1 2003/09/04 18:44:30 joel Exp $ */#include <bsp.h>#include <i2c.h>/* i2c_transfer_sema_done_func -- *     This function called from I2C driver layer to signal that I2C *     transfer is finished. This function resumes of task execution which *     has invoked blocking I2C primitive. * * PARAMETERS: *     arg - done function argument; it is RTEMS semaphore ID. */static voidi2c_transfer_sema_done_func(rtems_unsigned32 arg){    rtems_id sema = (rtems_id)arg;    rtems_semaphore_release(sema);}/* i2c_transfer_poll_done_func -- *     This function called from I2C driver layer to signal that I2C *     transfer is finished. This function set the flag polled by waiting *     function. * * PARAMETERS: *     arg - done function argument; address of poll_done_flag */static voidi2c_transfer_poll_done_func(rtems_unsigned32 arg){    rtems_boolean *poll_done_flag = (rtems_boolean *)arg;    *poll_done_flag = 1;}/* i2c_transfer_wait_sema -- *     Initiate I2C bus transfer and block on temporary created semaphore *     until this transfer will be finished. * * PARAMETERS: *     bus - I2C bus number *     msg - pointer to transfer messages array *     nmsg - number of messages in transfer * * RETURNS: *     RTEMS_SUCCESSFUL, if tranfer finished successfully, *     or RTEMS status code if semaphore operations has failed. */static i2c_message_statusi2c_transfer_wait_sema(i2c_bus_number bus, i2c_message *msg, int nmsg){    rtems_status_code sc;    rtems_id sema;    sc = rtems_semaphore_create(        rtems_build_name('I', '2', 'C', 'S'),        0,        RTEMS_COUNTING_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY |         RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,        0,        &sema    );    if (sc != RTEMS_SUCCESSFUL)        return I2C_RESOURCE_NOT_AVAILABLE;    sc = i2c_transfer(bus, nmsg, msg, i2c_transfer_sema_done_func, sema);    if (sc != RTEMS_SUCCESSFUL)    {        rtems_semaphore_delete(sema);        return sc;    }    rtems_semaphore_obtain(sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);    sc = rtems_semaphore_delete(sema);    return sc;}/* i2c_transfer_wait_poll -- *     Initiate I2C bus transfer and wait by poll transaction done flag until *     this transfer will be finished. * * PARAMETERS: *     bus - I2C bus number *     msg - pointer to transfer messages array *     nmsg - number of messages in transfer * * RETURNS: *     RTEMS_SUCCESSFUL */static rtems_status_codei2c_transfer_wait_poll(i2c_bus_number bus, i2c_message *msg, int nmsg){    volatile rtems_boolean poll_done_flag;    rtems_status_code sc;    poll_done_flag = 0;    sc = i2c_transfer(bus, nmsg, msg, i2c_transfer_poll_done_func,                       (rtems_unsigned32)&poll_done_flag);    if (sc != RTEMS_SUCCESSFUL)        return sc;    while (poll_done_flag == 0)    {        i2c_poll(bus);    }    return RTEMS_SUCCESSFUL;}/* i2c_transfer_wait -- *     Initiate I2C bus transfer and block until this transfer will be *     finished. This function wait the semaphore if system in *     SYSTEM_STATE_UP state, or poll done flag in other states. * * PARAMETERS: *     bus - I2C bus number *     msg - pointer to transfer messages array *     nmsg - number of messages in transfer * * RETURNS: *     I2C_SUCCESSFUL, if tranfer finished successfully,  *     I2C_RESOURCE_NOT_AVAILABLE, if semaphore operations has failed, *     value of status field of first error-finished message in transfer, *     if something wrong. */i2c_message_statusi2c_transfer_wait(i2c_bus_number bus, i2c_message *msg, int nmsg){    rtems_status_code sc;    int i;    if (_System_state_Is_up(_System_state_Get()))    {        sc = i2c_transfer_wait_sema(bus, msg, nmsg);    }    else    {        sc = i2c_transfer_wait_poll(bus, msg, nmsg);    }        if (sc != RTEMS_SUCCESSFUL)        return I2C_RESOURCE_NOT_AVAILABLE;        for (i = 0; i < nmsg; i++)    {        if (msg[i].status != I2C_SUCCESSFUL)        {            return msg[i].status;        }    }    return I2C_SUCCESSFUL;}/* i2c_write -- *     Send single message over specified I2C bus to addressed device and *     wait while transfer is finished. * * PARAMETERS: *     bus  - I2C bus number *     addr - address of I2C device *     buf  - data to be sent to device *     size - data buffer size * * RETURNS: *     transfer status */i2c_message_statusi2c_write(i2c_bus_number bus, i2c_address addr, void *buf, int size){    i2c_message msg;    msg.addr = addr;    msg.flags = I2C_MSG_WR;    if (addr > 0xff)        msg.flags |= I2C_MSG_ADDR_10;    msg.status = 0;    msg.len = size;    msg.buf = buf;    return i2c_transfer_wait(bus, &msg, 1);}/* i2c_wrbyte -- *     Send single one-byte long message over specified I2C bus to *     addressed device and wait while transfer is finished. * * PARAMETERS: *     bus  - I2C bus number *     addr - address of I2C device *     cmd  - byte message to be sent to device * * RETURNS: *     transfer status */i2c_message_statusi2c_wrbyte(i2c_bus_number bus, i2c_address addr, rtems_unsigned8 cmd){    i2c_message msg;    rtems_unsigned8 data = cmd;    msg.addr = addr;    msg.flags = I2C_MSG_WR;    if (addr > 0xff)        msg.flags |= I2C_MSG_ADDR_10;    msg.status = 0;    msg.len = sizeof(data);    msg.buf = &data;    return i2c_transfer_wait(bus, &msg, 1);}/* i2c_read -- *     receive single message over specified I2C bus from addressed device. *     This call will wait while transfer is finished. * * PARAMETERS: *     bus  - I2C bus number *     addr - address of I2C device *     buf  - buffer for received message *     size - receive buffer size * * RETURNS: *     transfer status */i2c_message_statusi2c_read(i2c_bus_number bus, i2c_address addr, void *buf, int size){    i2c_message msg;    msg.addr = addr;    msg.flags = 0;    if (addr > 0xff)        msg.flags |= I2C_MSG_ADDR_10;    msg.status = 0;    msg.len = size;    msg.buf = buf;    return i2c_transfer_wait(bus, &msg, 1);}/* i2c_wrrd -- *     Send message over I2C bus to specified device and receive message *     from the same device during single transfer. * * PARAMETERS: *     bus   - I2C bus number *     addr  - address of I2C device *     bufw  - data to be sent to device *     sizew - send data buffer size *     bufr  - buffer for received message *     sizer - receive buffer size * * RETURNS: *     transfer status */i2c_message_statusi2c_wrrd(i2c_bus_number bus, i2c_address addr, void *bufw, int sizew,         void *bufr, int sizer){    i2c_message msg[2];    msg[0].addr = addr;    msg[0].flags = I2C_MSG_WR | I2C_MSG_ERRSKIP;    if (addr > 0xff)        msg[0].flags |= I2C_MSG_ADDR_10;    msg[0].status = 0;    msg[0].len = sizew;    msg[0].buf = bufw;        msg[1].addr = addr;    msg[1].flags = 0;    if (addr > 0xff)        msg[1].flags |= I2C_MSG_ADDR_10;    msg[1].status = 0;    msg[1].len = sizer;    msg[1].buf = bufr;    return i2c_transfer_wait(bus, msg, 2);}/* i2c_wbrd -- *     Send one-byte message over I2C bus to specified device and receive *     message from the same device during single transfer. * * PARAMETERS: *     bus   - I2C bus number *     addr  - address of I2C device *     cmd   - one-byte message to be sent over I2C bus *     bufr  - buffer for received message *     sizer - receive buffer size * * RETURNS: *     transfer status */i2c_message_statusi2c_wbrd(i2c_bus_number bus, i2c_address addr, rtems_unsigned8 cmd,         void *bufr, int sizer){    i2c_message msg[2];    rtems_unsigned8 bufw = cmd;    msg[0].addr = addr;    msg[0].flags = I2C_MSG_WR | I2C_MSG_ERRSKIP;    if (addr > 0xff)        msg[0].flags |= I2C_MSG_ADDR_10;    msg[0].status = 0;    msg[0].len = sizeof(bufw);    msg[0].buf = &bufw;        msg[1].addr = addr;    msg[1].flags = I2C_MSG_ERRSKIP;    if (addr > 0xff)        msg[1].flags |= I2C_MSG_ADDR_10;    msg[1].status = 0;    msg[1].len = sizer;    msg[1].buf = bufr;    return i2c_transfer_wait(bus, msg, 2);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -