?? gx_cat1025.c
字號(hào):
#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
int gx_cat1025_read(alt_fd* fd, char* ptr, int len)
{
int count;
gx_cat1025_dev* dev = (gx_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;
}
int gx_cat1025_write (alt_fd* fd, const char* ptr, int len)
{
int block;
int count;
gx_cat1025_dev* dev = (gx_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);
}
int gx_cat1025_lseek(alt_fd* fd, int ptr, int dir)
{
int err = -1;
gx_cat1025_dev* dev = (gx_cat1025_dev*) fd->dev;
if(ptr > dev->capacity)
{
dev->byte_addr = ptr;
err = 1;
}
return err;
}
void gx_cat1025_init(int base, gx_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);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -