📄 i2cdrv8260.c
字号:
/*==============================================================================** MODULE: I2C驱动** FILENAME: i2cDrv8260.c**==============================================================================*//*============================================================================== Includes and Variable Definitions==============================================================================*/#include "vxWorks.h"#include <string.h>#include <stdlib.h>#include <stdio.h>#include "iv.h"#include "intLib.h"#include "netLib.h"#include "semLib.h"#include "logLib.h"#include "../inc/i2cDrv8260.h"#include "../inc/mpc8260cp.h"#include "../inc/mpc8260i2c.h"#include "../inc/mpc8260IOPort.h"#include "../inc/mpc8260int.h"/***********************//* Global Declarations *//***********************/LOCAL UINT8 gI2cMode; /* Operation mode of current device */LOCAL UINT8 *gImmrVal; /* internal memory map base */LOCAL I2cPram *gI2cPram_ptr; /* I2C Parameter RAM pointer */I2cBdrings *gI2cRxTxBD_ptr; /* RxTxBD ring pointer */LOCAL UINT8 *gI2cTxBuf0_ptr; /* Pointer of transmit buffer */LOCAL UINT8 *gI2cTxBuf1_ptr;LOCAL UINT8 *gI2cRxBuf_ptr; /* Pointer of receive buffer */SEM_ID gI2csemSync;/*INT16 rtnvlu;*/LOCAL_BUF gI2cRxTxBuf[NUM_I2C_RXBDS+NUM_I2C_TXBDS];LOCAL UINT8 envlu;/**************************************************************************** Function Name: i2c_init** Description:* init I2C.** Input(s):* local_addr: I2C local addr; oprt_mode: I2C operate mode;** Output(s):* none.** Returns:* NB_DRV_OK or ERR_NUM.**************************************************************************/SYS_STATUS i2c_init(UINT8 local_addr, UINT8 oprt_mode){ /*----------------------------------------------*/ /* input pram check */ /*----------------------------------------------*/ UINT32 a; UINT16 *b; b=(UINT16*)&a; if ((local_addr >= 128) ) { #ifdef I2C_DEBUG printf(" I2C Device address must less than 128\n"); #endif return I2C_ERR_PARM; } if (oprt_mode >= 2) { #ifdef I2C_DEBUG printf("Operation mode must be master(1) or slave(0)\n"); #endif return I2C_ERR_PARM; } /* get immr value */ gImmrVal =(UINT8*)(vxImmrGet()&IMMR_MASK); * M8260_I2C_BASE(gImmrVal) = I2C_PARAM_OFFSET; gI2cMode=oprt_mode; /*----------------------------------------------*/ /* Establish I2C PRAM and I2C Bdrings pointer */ /*----------------------------------------------*/ gI2cPram_ptr = (I2cPram *)(gImmrVal + I2C_PARAM_OFFSET); memset(gI2cPram_ptr, 0, sizeof(I2cPram)); /* Clear I2C Parameter RAM */ gI2cRxTxBD_ptr = (I2cBdrings *)(gImmrVal + I2C_BDS_OFFSET); /* Pointer to BD area of DPRAM */ memset(gI2cRxTxBD_ptr, 0, sizeof(I2cBdrings)); /* Clear I2C BDs */ /*----------------------------------------------*/ /* config io port */ /*----------------------------------------------*/ * M8260_PPARD(gImmrVal)|= 0x00030000; * M8260_PDIRD(gImmrVal) &= ~0x00030000; * M8260_PODRD(gImmrVal) |= 0x00030000; * M8260_PSORD(gImmrVal)|= 0x00030000; /*----------------------------------------------*/ /* config i2c pram and i2c bdrings */ /*----------------------------------------------*/ a=(UINT32)& gI2cRxTxBD_ptr->RxBD[0]; gI2cPram_ptr->rbase = *(b+1); /* point RBASE to first RX BD */ a=(UINT32) & gI2cRxTxBD_ptr->TxBD[0]; gI2cPram_ptr->tbase = *(b+1); gI2cPram_ptr->rfcr = 0x30; gI2cPram_ptr->tfcr = 0x30; gI2cPram_ptr->mrblr = BUFF_MAX_LEN; gI2cRxTxBD_ptr->RxBD[0].bd_length = 0; /* reset */ gI2cRxTxBD_ptr->RxBD[0].bd_addr = gI2cRxTxBuf[0]; /* point RX BD to first RX buffer address */ memset(&gI2cRxTxBuf[0], 0, BUFF_MAX_LEN); gI2cRxTxBD_ptr->RxBD[0].bd_cstatus = I2C_RXBD; /* not ready, last bds, interrupt */ gI2cRxTxBD_ptr->TxBD[0].bd_length = 0; /* reset */ gI2cRxTxBD_ptr->TxBD[0].bd_addr = gI2cRxTxBuf[I2C_TXBD_INDX]; /* point TX BD to last buffer address */ memset(&gI2cRxTxBuf[I2C_TXBD_INDX], 0, BUFF_MAX_LEN); gI2cRxTxBD_ptr->TxBD[0].bd_cstatus = I2C_TXBD; /* not ready, last bds, and interrupt ,last byte,has start bit*/ gI2cRxTxBD_ptr->TxBD[1].bd_length = 0; /* reset */ gI2cRxTxBD_ptr->TxBD[1].bd_addr = gI2cRxTxBuf[I2C_TXBD_INDX+1]; /* point TX BD to last buffer address */ memset(&gI2cRxTxBuf[I2C_TXBD_INDX+1], 0, BUFF_MAX_LEN); gI2cRxTxBD_ptr->TxBD[1].bd_cstatus = I2C_TXBD; /* not ready, last bds, and interrupt ,last byte,has start bit*/ /*----------------------*/ /* Set-up I2C Registers */ /*----------------------*/ * M8260_I2C_I2MOD(gImmrVal) = 0x00; /* Disable I2C before initializing it */ * M8260_I2C_I2ADD(gImmrVal) = (local_addr<<1) & 0xfe; /* Station address */ * M8260_I2C_I2BRG(gImmrVal) = 0x06; /* Generate 90kHz baud rate after predivider BRGCLK/32 */ * M8260_I2C_I2CER(gImmrVal) = 0x17; /* Clear out I2C events */ * M8260_I2C_I2CMR(gImmrVal) = 0x17; /* Enable/Disable interrupts from I2C */ * M8260_I2C_I2COM(gImmrVal) = oprt_mode; /* Set master/slave mode */ * M8260_I2C_I2MOD(gImmrVal) = 0x11; gI2cRxBuf_ptr= gI2cRxTxBD_ptr->RxBD[0].bd_addr; gI2cTxBuf0_ptr=gI2cRxTxBD_ptr->TxBD[0].bd_addr; gI2cTxBuf1_ptr=gI2cRxTxBD_ptr->TxBD[1].bd_addr; /* creat a synchronization signal*/ if((gI2csemSync=semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL) { #ifdef I2C_DEBUG printf("memory cannot be allocated for the synchronizatation semaphore"); #endif return I2C_ERR_SYS; } /*-----------------------------------------------*/ /* Issue Init RX & TX Parameters Command for I2C */ /*-----------------------------------------------*/ /* If the CPCR contains a command that the CP is currently processing */ while ((*M8260_CPCR(gImmrVal) & M8260_CPCR_FLG) != 0); * M8260_CPCR(gImmrVal) = M8260_CPCR_OP(M8260_CPCR_RT_INIT) | M8260_CPCR_SBC(M8260_CPCR_SBC_I2C) | M8260_CPCR_PAGE(M8260_CPCR_PAGE_I2C) | M8260_CPCR_FLG; while ((*M8260_CPCR(gImmrVal) & M8260_CPCR_FLG) != 0); /*--------------------------------------------*/ /* Connect Interrupt Handler to I2C interrupt */ /*--------------------------------------------*/#if 1 if (intConnect(INUM_TO_IVEC(INTR_I2C), (VOIDFUNCPTR)i2cInterruptHandler, NULL) == ERROR) { #ifdef I2C_DEBUG printf("Error : cannot connect I2C interrupt handler"); #endif return I2C_ERR_SYS ; } intEnable(INTR_I2C);#endif return NB_DRV_OK;} /* The end of i2cInit *//**************************************************************************** Function Name: i2cInterruptHandler** Description:* Interrupt handler for I2C.** Input(s):* none.** Output(s):* none.** Returns:* none.****************************************************************************/void i2cInterruptHandler(void){#ifdef I2C_DEBUG logMsg("i2cInterruptHandler has start!\n",0,0,0,0,0,0);#endif envlu = (* M8260_I2C_I2CER(gImmrVal) & 0x17);#ifdef I2C_DEBUG logMsg("envlu =%d\n",envlu ,0,0,0,0,0);#endif if (envlu & 0x10) { * M8260_I2C_I2CER(gImmrVal) = 0x10; /* Clear TXE */ } if (envlu & 0x04) { * M8260_I2C_I2CER(gImmrVal) = 0x04; /* Clear BSY */ } if (envlu & 0x02) { * M8260_I2C_I2CER(gImmrVal) = 0x02; /* Clear TXB*/ } if (envlu & 0x01) { * M8260_I2C_I2CER(gImmrVal) = 0x01; /* Clear RXB*/ } semGive(gI2csemSync); *M8260_SIPNR_L(gImmrVal) = 0x00008000;#ifdef I2C_DEBUG logMsg("i2cInterruptHandler is ended!",0,0,0,0,0,0);#endif}/**************************************************************************** Function Name: i2c_read** Description:* Master I2C controller read date from slave i2c_chip.** Input(s):* trgt_addr:* data_addr:* read_len:* flag:** Output(s):* recv_data_ptr:** Returns:* NB_DRV_OK or ERR_NUM.****************************************************************************/SYS_STATUS i2c_read(UINT8 trgt_addr,UINT8 data_addr,UINT16 read_len,UINT8 flag,UINT8 *recv_data_ptr){ INT8 sgrtn; /* Check input parameters of this function */ if (trgt_addr >= 128) { #ifdef I2C_DEBUG printf("Target device address must less than 128\n"); #endif return I2C_ERR_PARM; } if (read_len > BUFF_MAX_LEN) { #ifdef I2C_DEBUG printf("Read data length must less than 0x100\n"); #endif return I2C_ERR_PARM; } if (flag >= 2) { #ifdef I2C_DEBUG printf("target slave componentn type must be 0 or 1"); #endif return I2C_ERR_PARM; } /* Check device operation mode */ if (gI2cMode != I2C_MODE_MASTER) { #ifdef I2C_DEBUG printf("Current device cannot execute Master Read!\n"); #endif return I2C_ERR_SYS; } /* Check I2C is busy or not now */ if ((0x8000 & (gI2cRxTxBD_ptr->TxBD[0].bd_cstatus)) != 0) { #ifdef I2C_DEBUG printf("I2C is busy now!"); #endif return I2C_ERR_BUSY; } if ((0x8000 & (gI2cRxTxBD_ptr->TxBD[1].bd_cstatus)) != 0) { #ifdef I2C_DEBUG printf("I2C is busy now!"); #endif return I2C_ERR_BUSY; } if ((0x8000 & (gI2cRxTxBD_ptr->RxBD[0].bd_cstatus)) != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -