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 + -
显示快捷键?