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

📄 zlg_cat1025.c

📁 周立功 SOPC嵌入式系统实验教程配套光盘 I2C驱动
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzhou ZHIYUAN ELECTRONIC CO.,LTD.
**                                      Research centre
**                         http://www.zyinside.com, http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			  zlg_cat1025.c
** Latest modified Date:  2005-11-30
** Latest Version:		  1.0
** Descriptions:		  Implement CAT1025 access routines
**                        
**
**------------------------------------------------------------------------------------------------------
** Created by:			  Jing.Zhang
** Created date:		  2005-11-08
** Version:				  1.0
** Descriptions:		  The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/

#include <fcntl.h>
#define  __GLOBAL_DEF__

#include "sys/alt_dev.h"
#include "sys/alt_irq.h"
#include "sys/ioctl.h"
#include "sys/alt_errno.h"

#include "oc_i2c_master.h"

#define  I2C_SPEED    (400000u)  // 400kbps

/*********************************************************************************************************
** Function name:			zlg_cat1025_read
**
** Descriptions:			zlg_cat1025_read() is called by the system read() function in order to
**                    read a block of data from the CAT1025
**
** input parameters:  len: the maximum length of the data to read                      
**					  ptr: indicates the destination address
**                    fd : the file descriptor for the device to be read from.
**
** Returned value:		the number of bytes actually read
**                    -1 means some error occur.
**
** Used global variables:	None
** Calling modules:			None
**
** NOTE:             This function will block on the devices receive register, until all 
**                   characters have been received. If the maximum length of the data is 
**                   larger than the capacity of CAT1025, Not more than capacity of CAT1025
**                   will be read.
** Created by:				Jing.Zhang
** Created Date:			2005/09/30
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int zlg_cat1025_read(alt_fd* fd, char* ptr, int len)
{
  int count;
  
  zlg_cat1025_dev* dev = (zlg_cat1025_dev*) fd->dev;

  /* The parameters are valid */
  if(len <= 0 || fd == NULL || ptr == NULL)
  {
  	return -1;
  }

  /* The number of data could not be more than the capactity of CAT1025 */
  if(len > dev->capacity)
  {
  	  len = dev->capacity;
  }
  /*
   * When running in a multi threaded environment, obtain the "read_lock"
   * semaphore. This ensures that reading from the device is thread-safe.
   */

  ALT_SEM_PEND (dev->read_lock, 0);
/******** Implement Selective Read or Sequential Read timing *************/
  /* Send Slave address with start signal */
  I2C_SEND_BYTE_WITH_START(dev->base, dev->slave_addr);
  /* Send Byte address */
  I2C_SEND_BYTE(dev->base, dev->byte_addr);
  dev->byte_addr = 0;
  /* Send Slave address with start signal plus Read Command*/
  I2C_SEND_BYTE_WITH_START(dev->base, dev->slave_addr|0x01);
  /* if the length of data equals to 1 carry out byte read operation */
  if(1 == len)
  {
  	  *ptr = I2C_RECV_BYTE_WITH_STOP(dev->base);
  }
  else{
      for(count=0; count<len-1; count++)
      {
         ptr[count] = I2C_RECV_BYTE_WITH_ACK(dev->base);
      }
  }    
  ptr[count] = I2C_RECV_BYTE_WITH_STOP(dev->base);
   /*
   * Now that Read operation is complete, release the read
   * semaphore so that other threads can access the device.
   */

  ALT_SEM_POST (dev->read_lock);
  return len;
}


/*********************************************************************************************************
** Function name:			zlg_cat1025_write
**
** Descriptions:			zlg_cat1025_write() is called by the system write() function in order to
**                    write a block of data to the CAT1025
**
** input parameters:	len: the length of the data to write                      
**						        ptr: indicates the source address
**                    fd : the file descriptor for the device to be read from.
**
** Returned value:		the number of bytes actually written 
**                    -1 means some error occur.
**         
** Used global variables:	None
** Calling modules:			  None
**
** NOTE:             This function will block on the devices transmit register, until all 
**                   characters have been transmitted. This is unless the device is being 
**                   accessed in non-blocking mode. In this case this function will return as 
**                   soon as the device reports that it is not ready to transmit.
** Created by:				Jing.Zhang
** Created Date:			2005/09/30
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int zlg_cat1025_write (alt_fd* fd, const char* ptr, int len)
{
  int block;
  int count;

  zlg_cat1025_dev* dev = (zlg_cat1025_dev*) fd->dev;
  
  /* The parameters are valid */
  if(len <= 0 || fd == NULL || ptr == NULL)
  {
  	return -1;
  }
  block = !(fd->fd_flags & O_NONBLOCK);
  /* The number of data could not be more than a page */
  if(len > dev->page_size)
  {
  	  len = dev->page_size;
  }
  count = len - 1;
  
  /*
   * When running in a multi threaded environment, obtain the "write_lock"
   * semaphore. This ensures that writing to the device is thread-safe.
   */

  ALT_SEM_PEND (dev->write_lock, 0);
/******** Implement Byte Write or Page Write timing *************/

  /* Send Slave address with start signal */
  I2C_SEND_BYTE_WITH_START(dev->base, dev->slave_addr);
  /* Send Byte address */
  I2C_SEND_BYTE(dev->base, dev->byte_addr);
   dev->byte_addr = 0;
  /* if the length of data equals to 1 carry out byte write operation */
  if(1 == len)
  {
  	  I2C_SEND_BYTE_WITH_STOP(dev->base, *ptr);
  }
  else { /* the length of data is more than 1, carry out page write operation */
      do{
       	   I2C_SEND_BYTE(dev->base, *ptr++);
       	   count--;     
      } while (block && count);
      //Send last byte with stop signal  
    	I2C_SEND_BYTE_WITH_STOP(dev->base, *ptr);
  }
  
   /*
   * Now that Write operation is complete, release the write
   * semaphore so that other threads can access the device.
   */

  ALT_SEM_POST (dev->write_lock);
  if (count)
  {
    ALT_ERRNO = EWOULDBLOCK;
  }
  
  return (len - count);
}


/*********************************************************************************************************
** Function name:			zlg_cat1025_lseek
**
** Descriptions:			Move around within a file
**
** input parameters:	dir: dir is ignored here                      
**						        ptr: indicates the byte address of cat1025
**                    fd : the file descriptor for the device to be read from.
**
** Returned value:		-1 : the address is beyond the capacity
**                    0  : successfully!
**         
** Used global variables:	None
** Calling modules:			  None
**
**
** Created by:				Jing.Zhang
** Created Date:			2005/09/30
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int zlg_cat1025_lseek(alt_fd* fd, int ptr, int dir)
{
  int err = -1;
  zlg_cat1025_dev* dev = (zlg_cat1025_dev*) fd->dev;
  if(ptr > dev->capacity)
  {
     dev->byte_addr = ptr;
     err = 1;
  }
  return err;
  
}

/*********************************************************************************************************
** Function name:			zlg_cat1025_init
**
** Descriptions:			Initialize the I2C Open Core. The frequency of SCL is set as freq
**                    Interrupt will not be enabled now.
**                    zlg_cat1025_init() is called by the auto-generated function 
**                    alt_sys_init() in order to initialise a particular instance of this device  
**
** input parameters:	dev: a pointer to I2C device                      
**						
** Returned value:		None 
**         
** Used global variables:	None
** Calling modules:			  None
**
** Created by:				Jing.Zhang
** Created Date:			2005/09/30
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void zlg_cat1025_init(int base, zlg_cat1025_dev* dev)
{
  
  alt_u32 prescale;
	// Calculate the prescale value
	prescale = dev->cpu_freq/((I2C_SPEED<<2) + I2C_SPEED);
  // Setup prescaler for the freq of SCL with sysclk of ALT_CPU_FREQ
  IOWR_OC_I2C_PRERLO(base, prescale & 0xff);
  IOWR_OC_I2C_PRERHI(base,(prescale & 0xff00)>>8);
  // Enable core and  disable interrupt
  IOWR_OC_I2C_CTR(base, 0x80);
  /* 
   * Initialise the read and write semaphores used to protect
   * access to the device when running in a multi-threaded environment.
   */
  ALT_SEM_CREATE (&dev->read_lock, 1);  
  ALT_SEM_CREATE (&dev->write_lock, 1);
  // register drivers into HAL
  alt_dev_reg(&dev->dev);
   
}

⌨️ 快捷键说明

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