?? zlg_cat1025.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 + -