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

📄 aim711_misc.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:
    // Wait till timer counts below threshold
    do {
        HAL_READ_UINT32(KS32C_TCNT1, count);
    } while (count >= ticks);
    // then wait for it to be reloaded
    do {
        HAL_READ_UINT32(KS32C_TCNT1, count);
    } while (count < ticks);

    // Then disable timer 1 again
    tmod &= ~KS32C_TMOD_TE1;
    HAL_WRITE_UINT32(KS32C_TMOD, tmod);
}

// -------------------------------------------------------------------------
//
// To reset the AIM 711, set P3 to low, which is connected to the reset
// logic 
//
void hal_reset(void)
{
    cyg_uint32 value;
    CYG_INTERRUPT_STATE old;

    CYGACC_CALL_IF_DELAY_US(100000);

    // Set P3 to output
    HAL_READ_UINT32(KS32C_IOPMOD, value);
    value |= AIM711_GPIO_RESET;
    HAL_WRITE_UINT32(KS32C_IOPMOD, value);

    // Set P3 to low
    AIM711_GPIO_CLR(AIM711_GPIO_RESET);

    HAL_DISABLE_INTERRUPTS(old);
    while (1)
    ;
}

//----------------------------------------------------------------------
//
// I2C Support
//

#include <string.h>
#include <cyg/hal/drv_api.h>

#ifdef CYGPKG_ERROR
#include <errno.h>
#define I2C_STATUS_SUCCESS      (ENOERR)
#define I2C_STATUS_MUTEX        (-EINTR)
#define I2C_STATUS_BUSY         (-EBUSY)
#define I2C_STATUS_ADDR_NAK     (-1000)
#define I2C_STATUS_DATA_NAK     (-1001)
#else
#define I2C_STATUS_SUCCESS      (0)
#define I2C_STATUS_MUTEX        (-1)
#define I2C_STATUS_BUSY         (-1)
#define I2C_STATUS_ADDR_NAK     (-1)
#define I2C_STATUS_DATA_NAK     (-1)
#endif

static cyg_drv_mutex_t i2c_mutex;

//  Initialize the I2C bus controller.
static void
hal_ks32c_i2c_init(void)
{
    cyg_uint32 prescale = KS32C_I2C_FREQ(100000);

    // reset the bus controller
    HAL_WRITE_UINT32(KS32C_I2CCON, KS32C_I2C_CON_RESET);

    // set the bus frequency
    HAL_WRITE_UINT32(KS32C_I2CPS, prescale);

    cyg_drv_mutex_init(&i2c_mutex);
}

#define RETURN(_x_) \
    CYG_MACRO_START                             \
    diag_printf("%s: line %d error=%d\n",__FUNCTION__,__LINE__,(_x_)); \
    return (_x_); \
    CYG_MACRO_END

//  Transfer the I2C messages.
int
hal_ks32c_i2c_transfer(cyg_uint32 nmsg, hal_ks32c_i2c_msg_t* pmsgs)
{
    cyg_uint32 i2ccon;

    // serialize access to the I2C bus
    if (!cyg_drv_mutex_lock(&i2c_mutex))
    {
        RETURN(I2C_STATUS_MUTEX);
    }

    // is the bus free ?
    do
    {
        HAL_READ_UINT32(KS32C_I2CCON, i2ccon);
    } while (i2ccon & KS32C_I2C_CON_BUSY);

    // transfer the messages
    for (; nmsg > 0; --nmsg, ++pmsgs)
    {
        // generate the start condition
        HAL_WRITE_UINT32(KS32C_I2CCON, KS32C_I2C_CON_START);

        // send the device address
        HAL_WRITE_UINT32(KS32C_I2CBUF, pmsgs->devaddr);
        do
        {
            HAL_READ_UINT32(KS32C_I2CCON, i2ccon);
        } while ((i2ccon & KS32C_I2C_CON_BF) == 0);

        // check if the slave ACK'ed the device address
        if (i2ccon & KS32C_I2C_CON_LRB)
        {
            // generate the stop condition
            HAL_WRITE_UINT32(KS32C_I2CCON, KS32C_I2C_CON_STOP);
            cyg_drv_mutex_unlock(&i2c_mutex);
            RETURN(I2C_STATUS_ADDR_NAK);
        }

        // read the message ?
        if (pmsgs->devaddr & KS32C_I2C_RD)
        {
            cyg_uint8* pbuf = pmsgs->pbuf;
            cyg_uint32 bufsize = pmsgs->bufsize;
            cyg_uint32 i2cbuf;

            // read more than one byte ?
            if (--bufsize > 0)
            {
                // enable ACK
                HAL_WRITE_UINT32(KS32C_I2CCON, KS32C_I2C_CON_ACK);

                while (bufsize-- > 0)
                {
                    do
                    {
                        HAL_READ_UINT32(KS32C_I2CCON, i2ccon);
                    } while ((i2ccon & KS32C_I2C_CON_BF) == 0);

                    // read the data byte
                    HAL_READ_UINT32(KS32C_I2CBUF, i2cbuf);
                    *pbuf++ = i2cbuf;
                }
            }

            // disable ACK
            HAL_WRITE_UINT32(KS32C_I2CCON, 0);
            do
            {
                HAL_READ_UINT32(KS32C_I2CCON, i2ccon);
            } while ((i2ccon & KS32C_I2C_CON_BF) == 0);

            // read the data byte
            HAL_READ_UINT32(KS32C_I2CBUF, i2cbuf);
            *pbuf++ = i2cbuf;
        }

        // write the message
        else
        {
            cyg_uint32 i;

            for (i = 0; i < pmsgs->bufsize; ++i)
            {
                HAL_WRITE_UINT32(KS32C_I2CBUF, pmsgs->pbuf[i]);
                do
                {
                    HAL_READ_UINT32(KS32C_I2CCON, i2ccon);
                } while ((i2ccon & KS32C_I2C_CON_BF) == 0);

                // check if the slave ACK'ed the data byte
                if (i2ccon & KS32C_I2C_CON_LRB)
                {
                    // generate the stop condition
                    HAL_WRITE_UINT32(KS32C_I2CCON, KS32C_I2C_CON_STOP);
                    cyg_drv_mutex_unlock(&i2c_mutex);
                    RETURN(I2C_STATUS_DATA_NAK);
                }
            }
        }

        // generate a restart condition ?
        if (nmsg > 1)
        {
            HAL_WRITE_UINT32(KS32C_I2CCON, KS32C_I2C_CON_RESTART);
        }
    }

    // generate the stop condition
    HAL_WRITE_UINT32(KS32C_I2CCON, KS32C_I2C_CON_STOP);

    cyg_drv_mutex_unlock(&i2c_mutex);
    return I2C_STATUS_SUCCESS;
}

//----------------------------------------------------------------------
//
// EEPROM Support
//

int hal_aim711_eeprom_write(cyg_uint8 *buf, int offset, int len)
{
    cyg_uint8 addr_page[1 + AIM711_EEPROM_PAGESIZE];
    cyg_uint8 const* pbufbyte = (cyg_uint8 const*)buf;
    hal_ks32c_i2c_msg_t msg;
    cyg_uint8 addr;
    cyg_uint32 bufsize;
 
    if (offset > AIM711_EEPROM_SIZE)
        RETURN(-1);

    if (len > (AIM711_EEPROM_SIZE - offset))
        len = (AIM711_EEPROM_SIZE - offset);

    addr = offset;
    bufsize = len;

    msg.devaddr = AIM711_EEPROM_ADDR | KS32C_I2C_WR;
    msg.pbuf = addr_page;

    while (bufsize > 0)
    {
        cyg_uint32 nbytes;
        int status;

        // write at most a page at a time
        nbytes = MIN(bufsize, AIM711_EEPROM_PAGESIZE);

        // don't cross a page boundary
        if (addr%AIM711_EEPROM_PAGESIZE)
        {
            nbytes = MIN(nbytes, AIM711_EEPROM_PAGESIZE - addr%AIM711_EEPROM_PAGESIZE);
        }

        // build the write message
        addr_page[0] = addr;
        memcpy(&addr_page[1], pbufbyte, nbytes);
        msg.bufsize = nbytes + 1;
        addr += nbytes;
        pbufbyte += nbytes;
        bufsize -= nbytes;

        // transfer the message
        status = hal_ks32c_i2c_transfer(1, &msg);
        if (status != I2C_STATUS_SUCCESS)
        {
            RETURN(status);
        }

        // delay 10 msec
        CYGACC_CALL_IF_DELAY_US(10000);
    }

    return len;
}

int hal_aim711_eeprom_read(cyg_uint8 *buf, int offset, int len)
{
    hal_ks32c_i2c_msg_t msgs[2];
    int status;
    cyg_uint8 toffset;
 
    if (offset > AIM711_EEPROM_SIZE)
        RETURN(-1);

    if (len > (AIM711_EEPROM_SIZE - offset))
        len = (AIM711_EEPROM_SIZE - offset);

    toffset = offset;

    // write message to set the address
    msgs[0].devaddr = AIM711_EEPROM_ADDR | KS32C_I2C_WR;
    msgs[0].pbuf = &toffset;
    msgs[0].bufsize = sizeof(toffset);

    // read message
    msgs[1].devaddr = AIM711_EEPROM_ADDR | KS32C_I2C_RD;
    msgs[1].pbuf = buf;
    msgs[1].bufsize = len;

    // transfer the messages
    status = hal_ks32c_i2c_transfer(2, msgs);

    if (status < 0)
        RETURN(status);

    return len;
}

//-----------------------------------------------------------------------------
//

⌨️ 快捷键说明

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