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

📄 i2c0.c

📁 Rabbit 32Bit RTOS源代码
💻 C
字号:
/*********************************************************************
*                   Copyright (c) 2011-2012,李士伟
*                     All rights reserved.
*文 件 名:i2c0.c
*描    述:I2C0驱动源文件
*当前版本:V1.00
*作    者:李士伟
*创建日期:2012.01.28
**********************************************************************/

/*
    未完成!!!
*/
#include <drivers\lpc2103\target.h>
#include <drivers\lpc2103\i2c0.h>
#include <drivers\lpc2103\pinsel.h>
#include <drivers\lpc2103\vic.h>
#include <kernel\asm.h>
#include <kernel\flag.h>
#include <kernel\sched.h>
#include <kernel\kd.h>
#include <kernel\kds.h>

#define  STA  0x20  /* 起始标志 */
#define  STO  0x10  /* 停止标志 */
#define  SI   0x80  /* 中断标志 */
#define  AA   0x04  /* 应答信号 */

static    OS_TCB      *I2C0UsingTCB;  /* 正在使用I2C0的任务 */
static    OS_TCB      *I2C0WaitQ;     /* 等待I2C0服务队列   */
static    INT8U        I2C0TagAddr;   /* 当前处理的数据包目标地址 */
static    INT32U       I2C0DataSize;  /* 当前处理的数据包大小     */
static    INT8U       *I2C0DataPtr;   /* 当前处理的数据缓冲区指针 */
static    INT32U       I2C0Offset;    /* 当前处理的数据指针偏移量 */

/*********************************************************************
*函 数 名:I2C0_ISR
*描    述:I2C0中断服务例程
*输入参数:无
*输出参数:无
*返 回 值:无
*注    意:
**********************************************************************/
void I2C0_ISR(void)
{
    INT8U state = 0;  /* 状态标志 */
    state = I2C0STAT;
    switch (state)
    {

        case 0x08:
        {
            I2C0DAT    = I2C0TagAddr;
            I2C0CONCLR = SI;
            break;
        }
        case 0x10:
        {
            
            break;
        }
        case 0x38:
        {
            
            break;
        }

        /* 主发送模式状态 */
        case 0x18:
        {
            if (I2C0Offset == I2C0DataSize)  /* 数据包已发送完 */
            {
                I2C0CONCLR = SI;
                I2C0CONSET = STO;  /* 发送停止信号,释放总线 */
                OS_EnterRunQ(I2C0UsingTCB);
                if (I2C0WaitQ != NULL)
                {
                    OS_EnterRunQ(I2C0WaitQ);
                }
                return ;
            }
            I2C0DAT = I2C0DataPtr[I2C0Offset++];
            I2C0CONCLR = SI;  /* 清除中断标志 */
            break;
        }
        case 0x20:
        {
            
            break;
        }
        case 0x28:
        {
            
            break;
        }
        case 0x30:
        {
            
            break;
        }

        /* 主接收模式状态 */
        case 0x40:
        {
            
            break;
        }
        case 0x48:
        {
            
            break;
        }
        case 0x50:
        {
            if (I2C0Offset == I2C0DataSize)
            {
                I2C0CONCLR  = AA;  /* 发送非应答信号 */
                I2C0CONSET  = STO;  /* 发送停止信号,释放总线 */
                I2C0CONCLR  = SI;
                OS_EnterRunQ(I2C0UsingTCB);
                if (I2C0WaitQ != NULL)
                {
                    OS_EnterRunQ(I2C0WaitQ);
                }
                return ;
            }
            I2C0DataPtr[I2C0Offset++] = I2C0DAT;
            I2C0CONSET  = AA;  /* 发送应答信号 */
            I2C0CONCLR  = SI;
            break;
        }
        case 0x58:
        {
            break;
        }
        default:
        {
            break;
        }
    }
}

/*********************************************************************
*函 数 名:I2C0_SendDataPack
*描    述:I2C0发送一个数据包
*输入参数:pack: 数据包指针
*输出参数:无
*返 回 值:无
*注    意:
**********************************************************************/
void I2C0_SendDataPack(I2C_DATA_PACK *pack)
{
    OS_ENTER_CRITICAL();
    for ( ; ; )
    {
        if (I2C0UsingTCB != NULL)  /* 有任务正在访问I2C */
        {
            OS_EnterWaitQTail(&I2C0WaitQ, OSTCBCur);
            OS_Sched();
            continue ;
        }

        break;
    }

    /* 设置数据包信息 */
    I2C0TagAddr   = (pack->TagAddr) & 0xFE;
    I2C0DataSize  = pack->DataSize;
    I2C0DataPtr   = pack->DataPtr;
    I2C0Offset    = 0;

    OS_EnterWaitQTail(&(I2C0UsingTCB), OSTCBCur);
    I2C0CONSET = STA;  /* 发送一个起始标志引发中断 */
    OS_EXIT_CRITICAL();
    OS_Sched();

}

/*********************************************************************
*函 数 名:I2C0_ReceDataPack
*描    述:I2C0接收一个数据包
*输入参数:pack: 数据包指针
*输出参数:无
*返 回 值:无
*注    意:
**********************************************************************/
void I2C0_ReceDataPack(I2C_DATA_PACK *pack)
{
    OS_ENTER_CRITICAL();
    for ( ; ; )
    {
        if (I2C0UsingTCB != NULL)  /* 有任务正在访问I2C */
        {
            OS_EnterWaitQTail(&I2C0WaitQ, OSTCBCur);
            OS_Sched();
            continue ;
        }

        break;
    }

    /* 设置数据包信息 */
    I2C0TagAddr   = (pack->TagAddr) & 0xFF;
    I2C0DataSize  = pack->DataSize;
    I2C0DataPtr   = pack->DataPtr;
    I2C0Offset    = 0;

    OS_EnterWaitQTail(&(I2C0UsingTCB), OSTCBCur);
    I2C0CONSET = STA;  /* 发送一个起始标志引发中断 */
    OS_EXIT_CRITICAL();
    OS_Sched();
}

/*********************************************************************
*函 数 名:I2C0_Init
*描    述:I2C0初始化
*输入参数:Fscl:串行时钟频率(Hz)
*输出参数:无
*返 回 值:0,初始化成功; 1,初始化失败
*注    意:
**********************************************************************/
INT32U I2C0_Init(INT32U Fscl)
{

    if (PIN_Configure(PIN_SDA0))
    {
        if (PIN_Configure(PIN_SCL0) == 0)
        {
            PIN_Release(PIN_SDA0);
            return 0;
        }
    }

    I2C0WaitQ    = NULL;
    I2C0UsingTCB = NULL;
    I2C0DataSize = 0;
    I2C0DataPtr  = NULL;
    I2C0Offset   = NULL;
    I2C0TagAddr  = 0;

    I2C0CONCLR = 0x7C;  /* 先禁止I2C */

    /* 设置串行时钟频率 */
    I2C0SCLH = Fpclk / (Fscl + 1) / 2;
    I2C0SCLL = Fpclk / (Fscl) / 2;

    /* 注册中断处理服务例程 */
    VIC_RegisterIRQ(I2C0_Handler, I2C0_INTR_NUM, I2C0_INTR_PRIO);
    I2C0CONSET = 0x40;  /* 主机模式,启动I2C */
    return 1;
}

⌨️ 快捷键说明

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