hal_i2c.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 498 行 · 第 1/2 页

C
498
字号
/**************************************************************************/
/*                                                                        */
/*     Copyright (C) 2006 Oki Electric Industry Co., LTD.                 */
/*                                                                        */
/*     System Name  :  ML675050 series                                    */
/*     Module Name  :  ML675050 i2c sample program                        */
/*     File   Name  :  hal_i2c.c                                          */
/*     Revision     :  01.00                                              */
/*     Date         :  2006/1/27 initial version                          */
/*                                                                        */
/**************************************************************************/
#if defined(__arm)
#include "ml675050.h"
#elif defined(_WIN32)
#include "ml675050sim.h"
#else
#error COMPILER ERROR
#endif

#include "ML675050.h"
#include "common.h"
#include "hal_common.h"
#include "hal_i2c.h"
#include "hal_interrupt.h"


/***********************************/
/*    type definition              */
/***********************************/
#define I2CBC_400Kbps40MHz  (0x000d)    /* 400kbps, 40Mhz */
#define I2CBC_400Kbps33MHz  (0x000b)    /* 400kbps, 33Mhz */
#define I2CBC_400Kbps25MHz  (0x0008)    /* 400kbps, 25Mhz */
#define I2CBC_400Kbps20MHz  (0x0007)    /* 400kbps, 20Mhz */
#define I2CBC_100Kbps40MHz  (0x0032)    /* 100kbps, 40Mhz */
#define I2CBC_100Kbps33MHz  (0x002a)    /* 100kbps, 33Mhz */
#define I2CBC_100Kbps25MHz  (0x0020)    /* 100kbps, 25Mhz */
#define I2CBC_100Kbps20MHz  (0x0019)    /* 100kbps, 20Mhz */

/***********************************/
/*     Static functions prototype  */
/***********************************/
static int16_t i2c_Mas_Get_TxD_result(void);
static int16_t i2c_Slv_Get_RxD_result(void);
static int16_t i2c_Slv_Get_TxD_result(void);
static void i2c_Mas_tramsmit_stop_condition(void);
static void i2c_Slv_tramsmit_complete(void);

static void _i2c0_handler(void);
static void _i2c1_handler(void);

/* global variables */
struct ml675050_i2cParam i2c_hal_status;

/******************************/
/*     Public defines         */
/******************************/
FP i2c0_handler = _i2c0_handler;
FP i2c1_handler = _i2c1_handler;

/*****************************************************************************/
/*                                                                           */
/*  Function Name   : int16_t HalI2c_i2cInit( struct ml675050_i2cParam *param )*/
/*  Input           : Transmission parameter                                 */
/*  Output          : HAL_OK(1)                                              */
/*                  : HAL_PARAM_ERROR(-2)                                    */
/*                                                                           */
/*  Note : Initialize I2C.                                                   */
/*        Master                                                             */
/*         channel: ch0                                                      */
/*         trans speed : Fast-mode(400kHz)                                   */
/*         trans speed counter: 400Kbps 40MHz                                */
/*        Slave                                                              */
/*         channel: ch1                                                      */
/*         trans speed : Fast-mode(400kHz)                                   */
/*         trans speed counter: 400Kbps 40MHz                                */
/*                                                                           */
/*****************************************************************************/
int16_t HalI2c_i2cInit( struct ml675050_i2cParam *param )
{
    int16_t rtnVal = HAL_OK;

    /* get i2c trans Info */
    i2c_hal_status.channel = param->channel;
    i2c_hal_status.trans_mode = param->trans_mode;
    i2c_hal_status.trans_speed = param->trans_speed;
    i2c_hal_status.slave_addr = param->slave_addr;
    
    OkiCLib_set32bit(CLKCNT, CLKCNT_PLLSEL);                /* Enable PLL for CPU_CLK */
    
    if(i2c_hal_status.trans_mode == MASTER_MODE){
        OkiCLib_set16bit(I2CCTL0, I2CCTL0_I2CMEN);           /* Enable I2C module */
        OkiCLib_write16(I2CBC0, I2CBC_400Kbps25MHz);         /* setting transmit speed counter */
        OkiCLib_set16bit(I2CCTL0, FARST_MODE);               /* Fast-mode(400kHz) */
    }else{
        OkiCLib_set16bit(I2CCTL1, I2CCTL1_I2CMEN);           /* Enable I2C module */
        OkiCLib_write16(I2CSADR1, i2c_hal_status.slave_addr);    /* setting slave address */
        OkiCLib_write16(I2CBC1, I2CBC_400Kbps25MHz);         /* setting transmit speed counter */
        OkiCLib_set16bit(I2CCTL1, FARST_MODE);               /* Fast-mode(400kHz) */
        OkiCLib_set16bit(I2CCTL1, I2CCTL1_I2CAASIE);         /* MAAS interrupt enable */
    }

    return rtnVal;
}

/*****************************************************************************/
/*                                                                           */
/*  Function Name   : int16_t HalI2c_i2cMasTxDataStart(uint8_t *data, uint8_t scl_out) */
/*  Input           : data: Pointer to transmission data                     */
/*                  : scl_out: 0:scl continue, 1:scl stop                    */
/*  Output          : HAL_OK(1)                                              */
/*                  : HAL_PARAM_ERROR(-2)                                    */
/*                                                                           */
/*  Note : Data is transmitted.                                              */
/*                                                                           */
/*****************************************************************************/
int16_t HalI2c_i2cMasTxDataStart(uint8_t *data, uint8_t scl_out)
{
    int16_t rtnVal = HAL_OK;
    int16_t sta;
    uint16_t reg_adr = (uint16_t)*data;

    if (data == NULL) {
        rtnVal = HAL_PARAM_ERROR;
    }

    if(rtnVal == HAL_OK){
        OkiCLib_set16bit(I2CCTL0, I2CCTL0_I2CMTX);                          /* set transmission direction(write) */
        while(((OkiCLib_read16(I2CSR0))&I2CSR0_I2CMBB) == I2CSR0_I2CMBB){   /* Waiting for bus free */
            ;
        }
        OkiCLib_write16(I2CDR0, (uint16_t)(i2c_hal_status.slave_addr|WRITE_FLAG)); /* set serve address & write flag  */
        OkiCLib_set16bit(I2CCTL0, I2CCTL0_I2CMSTA);                         /* tramsmit start condition & data */
        sta = i2c_Mas_Get_TxD_result();
        if(sta == HAL_I2C_ACK){
            OkiCLib_clr16bit(I2CSR0, I2CSR0_I2CMCF);                        /* clear I2CSR_I2CMCF */
            OkiCLib_write16(I2CDR0, (uint8_t)((reg_adr>>8)&0xff));          /* set transmit data(register address(high))  */
            sta = i2c_Mas_Get_TxD_result();
            if(sta == HAL_I2C_ACK){
                OkiCLib_clr16bit(I2CSR0, I2CSR0_I2CMCF);                    /* clear I2CSR_I2CMCF */
                if(scl_out != 0){
                    OkiCLib_set16bit(I2CCTL0, I2CCTL0_I2CCS);               /* STOP SCL OUT */
                }
                OkiCLib_write16(I2CDR0, (uint8_t)(reg_adr&0xff));           /* set transmit data(register address(low))  */
                sta = i2c_Mas_Get_TxD_result();
                if(sta == HAL_I2C_NO_ACK){
                    i2c_Mas_tramsmit_stop_condition();
                    rtnVal = HAL_I2C_DATA_ACK_ERROR;
                }else if(sta == HAL_I2C_NO_FREE_BUS){
                    i2c_Mas_tramsmit_stop_condition();
                    rtnVal = HAL_I2C_BUS_ERROR;
                }
            }else if(sta == HAL_I2C_NO_ACK){
                i2c_Mas_tramsmit_stop_condition();
                rtnVal = HAL_I2C_DATA_ACK_ERROR;
            }else{
                i2c_Mas_tramsmit_stop_condition();
                rtnVal = HAL_I2C_BUS_ERROR;
            }
        }else if(sta == HAL_I2C_NO_ACK){
            i2c_Mas_tramsmit_stop_condition();
            rtnVal = HAL_I2C_ADDR_ACK_ERROR;
        }else{
            i2c_Mas_tramsmit_stop_condition();
            rtnVal = HAL_I2C_BUS_ERROR;
        }
    }
    return rtnVal;
}

/*****************************************************************************/
/*                                                                           */
/*  Function Name   : int16_t HalI2c_i2cSlvRxDataStart(uint8_t *data)        */
/*  Input           : Pointer to receive data                                */
/*  Output          : HAL_OK(1)                                              */
/*                  : HAL_PARAM_ERROR(-2)                                    */
/*                                                                           */
/*  Note : It receives the data.                                             */
/*                                                                           */
/*****************************************************************************/
int16_t HalI2c_i2cSlvRxDataStart(uint8_t *data)
{
    int16_t rtnVal = HAL_OK;
    int16_t sta;
    uint16_t reg_adr;
    uint16_t *data_pt = (uint16_t *)data;
    
    if(((OkiCLib_read16(I2CSR1))&I2CSR1_I2CSRW) != I2CSR1_I2CSRW){      /* check transmission direction */
        sta = i2c_Slv_Get_RxD_result();
        if(sta == HAL_I2C_MCF){   /* MCF */
            reg_adr = (uint16_t)((OkiCLib_read16(I2CDR1)<<8)&0xff00);     /* get transmit data  */
            OkiCLib_clr16bit(I2CSR1, I2CSR1_I2CMCF);                    /* clear I2CSR_I2CMCF */
            sta = i2c_Slv_Get_RxD_result();
            if(sta == HAL_I2C_MCF){   /* MCF */
                reg_adr |= (uint16_t)(OkiCLib_read16(I2CDR1)&0x00ff);       /* get transmit data  */
                OkiCLib_clr16bit(I2CSR1, I2CSR1_I2CMCF);                /* clear I2CSR_I2CMCF */
                *data_pt = reg_adr;
                sta = i2c_Slv_Get_RxD_result();
                if(sta == HAL_I2C_STP){   /* STP */
                    i2c_Slv_tramsmit_complete();
                }
            }else{                    /* STP */
                i2c_Slv_tramsmit_complete();
                rtnVal = HAL_I2C_OTHER_ERROR;
            }
        }else{                    /* STP */
            i2c_Slv_tramsmit_complete();
            rtnVal = HAL_I2C_OTHER_ERROR;
        }
    }else{
        i2c_Slv_tramsmit_complete();
        rtnVal = HAL_I2C_DIRECT_ERROR;
    }
    return rtnVal;
}

/*****************************************************************************/
/*                                                                           */
/*  Function Name   : int16_t HalI2c_i2cMasTxDataEnd(uint8_t *data)          */
/*  Input           : Pointer to transmission data                           */
/*  Output          : HAL_OK(1)                                              */
/*                  : HAL_PARAM_ERROR(-2)                                    */
/*                                                                           */
/*  Note : Data is transmitted.                                              */
/*                                                                           */
/*****************************************************************************/
int16_t HalI2c_i2cMasTxDataEnd(uint8_t *data)
{
    int16_t rtnVal = HAL_OK;
    int16_t sta;

    if (data == NULL) {
        rtnVal = HAL_PARAM_ERROR;
    }

    if(rtnVal == HAL_OK){
        OkiCLib_clr16bit(I2CSR0, I2CSR0_I2CMCF);                /* clear I2CSR_I2CMCF */
        OkiCLib_write16(I2CDR0, *data);                         /* set transmit data  */
        sta = i2c_Mas_Get_TxD_result();
        if(sta == HAL_I2C_NO_ACK){
            rtnVal = HAL_I2C_DATA_ACK_ERROR;
        }else if(sta == HAL_I2C_NO_FREE_BUS){
            rtnVal = HAL_I2C_BUS_ERROR;
        }
        i2c_Mas_tramsmit_stop_condition();
    }
    return rtnVal;
}

/*****************************************************************************/

⌨️ 快捷键说明

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