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

📄 i2cmgr.c

📁 zilog z80f91单片机的I2C接口函数
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * File       : I2CMgr.c
 * Scope      : 
 *
 * Description:  This contains implementations for I2C manager which handles 
 * the i2c protocol.
 *
 *
 * Copyright 2003 ZiLOG Inc.  ALL RIGHTS RESERVED.
 *
 * This file contains unpublished confidential and proprietary information
 * of ZiLOG, Inc.
 * NO PART OF THIS WORK MAY BE DUPLICATED, STORED, PUBLISHED OR DISCLOSED 
 * IN ANY FORM WITHOUT THE PRIOR WRITTEN CONSENT OF ZiLOG, INC.
 * This is not a license and no use of any kind of this work is authorized
 * in the absence of a written license granted by ZiLOG, Inc. in ZiLOG's 
 * sole discretion 
 */



#ifdef _IAR_CODE

#ifdef _EZ80F91
#include <ioez80f91.h>
#endif

#ifdef _EZ80F92
#include <ioez80f92.h>
#endif

#ifdef _EZ80F93
#include <ioez80f92.h>
#endif

#ifdef _EZ80L92
#include <ioez80l92.h>
#endif

#ifdef _EZ80190
#include <ioez80190.h>
#endif

#else
#include <ez80.h>
#endif

#include <stdio.h>
#include "ZTypes.h"
#include "ZSysgen.h"
#include "ZInterrupt.h"
#include "ZThread.h"
#include "ZSemaphore.h"
#include "i2c.h"

extern UINT8 I2C_TASK_STACK[] ;
extern UINT8 i2cRxBuff[] ;
extern UINT8 i2cTxBuff[] ;
extern UINT I2C_TASK_STACK_SIZE ;
extern UINT8 I2C_TASK_PRIORITY ;
extern I2C_CONFIG_t    i2cConfigParams ;
extern UINT I2C_RX_MAX_BUFF_SIZE ;
extern UINT I2C_TX_MAX_BUFF_SIZE ;
RZK_SEMAPHOREHANDLE_t hSem_I2C;
void I2cInterruptTask(void) ;

INT rxAvail ;

CQ_t rxCQ ;
CQ_t txCQ ;

RZK_THREADHANDLE_t i2cIntThreadHdl ;

void CQ_IN( CQ_t *pCQ, UINT8 ch )
{    
    if( pCQ->rear == pCQ->bufLen - 1 )
    {         
        pCQ->rear = 0 ;
    }
    else
        pCQ->rear++ ;

    pCQ->pBuff[pCQ->rear] = ch ;
    pCQ->avail++ ;
}



UINT8 CQ_OUT(CQ_t *pCQ)
{     
    UINT8 data = 0;   
    
    data = pCQ->pBuff[pCQ->front] ;   
    if ( pCQ->front == pCQ->bufLen - 1 )        
        pCQ->front = 0 ;     
    else         
        pCQ->front++ ;    
    
    pCQ->avail-- ;
    return data ;
}

DDF_STATUS_t I2CPeek()
{
	DDF_STATUS_t avail ;
	UINTRMASK intmask ;

	intmask = RZKDisableInterrupts() ;
	avail = rxCQ.avail ;
	RZKEnableInterrupts(intmask) ;

	return avail ;
}



DDF_STATUS_t I2COpen( RZK_DEVICE_CB_t *pDCB, INT8 *devName, INT8 * devMode )
{
    UINTRMASK intmask;
    
    /**  Opens the I2C bus by initializing the ports and 
    setting up the registers to a known state
    *    Creates interrupt thread 
    *    Configures I2C based on whether it is a master or slave */
    
    if(RZKDEV_OPENED == pDCB->InUse)
        return I2CERR_SUCCESS ;

    i2cConfigParams.mode = *devMode ;
    
   	I2CDev_Init();
    
	hSem_I2C    = RZKCreateSemaphore((RZK_NAME_t*)"hSem_I2C", 1, RECV_ORDER_PRIORITY) ;//KE_SemCreate( 1 );
	if(hSem_I2C == NULL)
		printf("\nI2C Semaphore creation error");

    if(*devMode == I2C_SLAVE)
    {
        i2cIntThreadHdl = RZKCreateThreadEnhanced((RZK_NAME_t*)"I2C", 
            (RZK_PTR_t)I2cInterruptTask, 
            NULL, 
            I2C_TASK_STACK_SIZE,
            I2C_TASK_PRIORITY,1, 
            RZK_THREAD_PREEMPTION|RZK_THREAD_INTERRUPT,0) ;
        if(i2cIntThreadHdl == NULL)
        {
            return I2CERR_KERNELERROR ;
        }

		rxCQ.rear = -1 ;
		rxCQ.front = 0 ;
		txCQ.rear = -1 ;
		txCQ.front = 0 ;
		rxCQ.pBuff = i2cRxBuff ;
		txCQ.pBuff = i2cTxBuff ;
		rxCQ.bufLen = I2C_RX_MAX_BUFF_SIZE ;
		txCQ.bufLen = I2C_TX_MAX_BUFF_SIZE ;
		rxCQ.avail = 0 ;
		txCQ.avail = 0 ;
    }
    
    intmask = RZKDisableInterrupts() ;
    pDCB->InUse = RZKDEV_OPENED ;
    RZKEnableInterrupts(intmask) ;    
    return 		I2CERR_SUCCESS ; 				
    
    
}


DDF_STATUS_t I2CClose( RZK_DEVICE_CB_t * pDCB)
{

UINTRMASK intmask ;
/** Close I2C bus
*   Deletes interrupt thread
    */
    if(RZKDEV_OPENED != pDCB->InUse)
        return I2CERR_INVALID_OPERATION ;
    
    
    RZKDeleteThreadEnhanced(i2cIntThreadHdl) ;
    intmask = RZKDisableInterrupts() ;
    pDCB->InUse &= ~RZKDEV_OPENED ;
    RZKEnableInterrupts(intmask) ;
    
    return I2CERR_SUCCESS ;
}



DDF_STATUS_t I2CWrite( RZK_DEVICE_CB_t * pDCB, INT8 * buf, RZK_DEV_BYTES_t size )
{
    INT stat = 0 ;
    INT32 i ; // INT changed to INT32
    UINT8 slvaddr = i2cConfigParams.currSlaveAddr ; 
	UINT8 useSubAddr = i2cConfigParams.useSubAddr ;
	UINT subAddr = i2cConfigParams.subAddr ;
//    UINTRMASK intmask ;   //Commented during IAR Porting
	UINT16 count ;
    
    /* If master 
    Send the start condition
    Send slave address with write bit
    Send data
    Send STOP condn
    If slave
    write the data to the Tx circular buffer in the I2C
    Actual transmission will happen from the interrupt thd context.
    */
    
    if(RZKDEV_OPENED != pDCB->InUse)
        return I2CERR_INVALID_OPERATION ;
    
    if(I2C_BUS_BUSY == pDCB->InUse)
        return I2CERR_BUSBUSY ;
    else
    {
	RZKAcquireSemaphore(hSem_I2C,INFINITE_SUSPEND);
//        mask = RZKDisablePreemption() ;
        pDCB->InUse |= I2C_BUS_BUSY ;
        
        if(I2C_MASTER == i2cConfigParams.mode)
        {
            stat = I2CDev_SendStart() ;
            if(stat<0)
            {
                pDCB->InUse &= ~I2C_BUS_BUSY ;
    		RZKReleaseSemaphore(hSem_I2C);
//            RZKRestorePreemption(mask) ;
                return stat ;
            }

            slvaddr |= I2CMODE_TRANSMIT ;
            
            stat = I2CDev_TransmitDataByte(slvaddr) ;
                if(stat<0)
                {
                    I2CDev_SendStop() ;
                    pDCB->InUse &= ~I2C_BUS_BUSY ;
			RZKReleaseSemaphore(hSem_I2C);
//                    RZKRestorePreemption(mask) ;
                    return stat ;
                }

                if(useSubAddr == RZK_TRUE)
                {
					switch(i2cConfigParams.addrLen)
					{
					case 3:
		                   	stat = I2CDev_TransmitDataByte(subAddr) ;
							if(stat<0)  	
			                	break ;
							subAddr >>= 8 ;
					case 2:
		                   	stat = I2CDev_TransmitDataByte(subAddr) ;
							if(stat<0)  	
			                	break ;
							subAddr >>= 8 ;
					case 1:
							stat = I2CDev_TransmitDataByte(subAddr) ;
							break ;
					}

				    if(stat<0)  	
	                {
	                    I2CDev_SendStop() ;
	                    pDCB->InUse &= ~I2C_BUS_BUSY ;
				RZKReleaseSemaphore(hSem_I2C);
//	                    RZKRestorePreemption(mask) ;
	                    return stat ;
	                }
                }
                
                for(i=0; i<size; i++)
                {
                    stat = I2CDev_TransmitDataByte(*buf) ;
                        if(stat<0)
                        {
                            I2CDev_SendStop() ;
                            pDCB->InUse &= ~I2C_BUS_BUSY ;
				RZKReleaseSemaphore(hSem_I2C);
//                            RZKRestorePreemption(mask) ;
                            return stat ;
                        }
                        else 
                            buf++ ;
                }
                
                I2CDev_SendStop() ;
				count = COUNT_DELAY ;
				I2C_Delay(count) ;    
           	}
	        else
	        {
    	        for(i=0; i<size; i++)
        	    {
            	    CQ_IN(&txCQ, *buf++) ;
            	}
        	}

        }

   
     pDCB->InUse &= ~I2C_BUS_BUSY ;
		RZKReleaseSemaphore(hSem_I2C);
//     RZKRestorePreemption(mask) ; 
     return size ;
    
}


DDF_STATUS_t I2CRead(RZK_DEVICE_CB_t *	pDCB, INT8 * buf, RZK_DEV_BYTES_t size)
{
    
    INT stat = 0 ;
    INT32 i ;   // INT changed to INT32
    UINT8 slvaddr = i2cConfigParams.currSlaveAddr ; 
	UINT8 useSubAddr = i2cConfigParams.useSubAddr ;
	UINT subAddr = i2cConfigParams.subAddr ;
//    UINTRMASK intmask ;   //Commented during IAR Porting
	UINT16 temp = 0 ;
	UINT16 count ;

⌨️ 快捷键说明

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