Files
TAIXIN/sdk/app/app_iic/app_iic.c

269 lines
7.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "sys_config.h"
#include "basic_include.h"
#include "hal/lcdc.h"
#include "hal/spi.h"
#include "hal/i2c.h"
#include "dev/lcdc/hglcdc.h"
#include "lib/lcd/lcd.h"
#include "lib/multimedia/msi.h"
#include "stream_frame.h"
typedef struct
{
struct list_head list; //iic queue hand
struct i2c_device *i2c; //iic dev
uint32_t len;
uint8_t *table;
uint8_t scl_io;
uint8_t sda_io;
uint8_t id_addr;
uint8_t rw_sta; //0:normal read 1:normal write 2:table write
uint8_t sta; //0:idle 1:data ready
uint8_t devid;
uint8_t *trx_buff; //用户自定义的buff空间
}iic_queue_wq;
volatile struct list_head iic_queue_head;
static struct os_semaphore iicwq_sem = {0,NULL};
void iicwq_sema_init()
{
os_sema_init(&iicwq_sem,0);
}
void iicwq_sema_down(int32 tmo_ms)
{
os_sema_down(&iicwq_sem,tmo_ms);
}
void iicwq_sema_up()
{
os_sema_up(&iicwq_sem);
}
int register_iic_queue(struct i2c_device *i2c,uint8_t scl_io,uint8_t sda_io,uint8_t id_addr){
static uint8_t idnum= 1;
iic_queue_wq *wq;
wq = malloc(sizeof(iic_queue_wq));
wq->scl_io = scl_io;
wq->sda_io = sda_io;
wq->id_addr= id_addr;
wq->sta = 0;
wq->i2c = i2c;
wq->devid = idnum;
wq->trx_buff = NULL;
INIT_LIST_HEAD(&wq->list);
list_add_tail(&wq->list,(struct list_head*)&iic_queue_head);
return idnum++;
}
int unregister_iic_queue(uint8_t devid){
int ret = 0;
struct list_head *dlist;
iic_queue_wq* iicdev;
if(list_empty((struct list_head *)&iic_queue_head) != TRUE){
dlist = (struct list_head *)&iic_queue_head;
do{
dlist = dlist->next;
if(dlist == &iic_queue_head){
return -1;
}else{
iicdev = list_entry((struct list_head *)dlist,iic_queue_wq,list);
if(iicdev->devid == devid){
list_del(&iicdev->list);
free(iicdev);
return 1;
}
}
}while(1);
}else{
ret = -1;
}
return ret;
}
int iic_devid_set_addr(uint8_t devid,uint8_t addr){
int ret = 0;
struct list_head *dlist;
iic_queue_wq* iicdev;
if(list_empty((struct list_head *)&iic_queue_head) != TRUE){
dlist = (struct list_head *)&iic_queue_head;
do{
dlist = dlist->next;
if(dlist == &iic_queue_head){
return -2; //no this device
}else{
iicdev = list_entry((struct list_head *)dlist,iic_queue_wq,list);
if(iicdev->devid == devid){
iicdev->id_addr= addr;
return 1; //this id all ready finish
}
}
}while(1);
}else{
ret = -1;
}
return ret;
}
int wake_up_iic_queue(uint8_t devid,uint8_t *table,uint32_t len,uint8_t rw_sta,uint8_t *trx_buff){
int ret = 0;
struct list_head *dlist;
iic_queue_wq* iicdev;
if(list_empty((struct list_head *)&iic_queue_head) != TRUE){
dlist = (struct list_head *)&iic_queue_head;
do{
dlist = dlist->next;
if(dlist == &iic_queue_head){
return -1;
}else{
iicdev = list_entry((struct list_head *)dlist,iic_queue_wq,list);
if(iicdev->devid == devid){
iicdev->table = table;
iicdev->len = len;
if(iicdev->sta == 1){
return 2; //this id all ready running
}
iicdev->sta = 1;
iicdev->rw_sta= rw_sta;
iicdev->trx_buff = trx_buff;
iicwq_sema_up();
return 1;
}
}
}while(1);
}else{
ret = -1;
}
return ret;
}
int iic_devid_finish(uint8_t devid){
int ret = 0;
struct list_head *dlist;
iic_queue_wq* iicdev;
if(list_empty((struct list_head *)&iic_queue_head) != TRUE){
dlist = (struct list_head *)&iic_queue_head;
do{
dlist = dlist->next;
if(dlist == &iic_queue_head){
return -2; //no this device
}else{
iicdev = list_entry((struct list_head *)dlist,iic_queue_wq,list);
if(iicdev->devid == devid){
if(iicdev->sta == 0){
return 1; //this id all ready finish
}else{
return 0;
}
}
}
}while(1);
}else{
ret = -1;
}
return ret;
}
void iic_run_thread(void *d){
// int32 iic_table_finish;
// int out_time;
scatter_data *table_scatter_data;
struct i2c_device *iic_dev;
struct i2c_device *iic2_dev;
struct list_head *dlist;
iic_queue_wq* iicdev;
iic_dev = (struct i2c_device *)dev_get(HG_I2C1_DEVID);
iic2_dev = (struct i2c_device *)dev_get(HG_I2C2_DEVID);
while(1){
iicwq_sema_down(-1);
if(list_empty((struct list_head *)&iic_queue_head) != TRUE){
dlist =(struct list_head *) &iic_queue_head;
do{
dlist = dlist->next;
if(dlist == &iic_queue_head){
break;
}else{
iicdev = list_entry((struct list_head *)dlist,iic_queue_wq,list);
if(iicdev->sta == 1){
gpio_driver_strength(iicdev->scl_io, GPIO_DS_G3);
gpio_driver_strength(iicdev->sda_io, GPIO_DS_G3);
gpio_set_mode(iicdev->scl_io, GPIO_OPENDRAIN_PULL_UP, GPIO_PULL_LEVEL_4_7K);
gpio_set_mode(iicdev->sda_io, GPIO_OPENDRAIN_PULL_UP, GPIO_PULL_LEVEL_4_7K);
if(iicdev->i2c == iic_dev){
gpio_iomap_inout(iicdev->scl_io, GPIO_IOMAP_IN_SPI1_SCK_IN, GPIO_IOMAP_OUT_SPI1_SCK_OUT);
gpio_iomap_inout(iicdev->sda_io, GPIO_IOMAP_IN_SPI1_IO0_IN, GPIO_IOMAP_OUT_SPI1_IO0_OUT);
}else{
gpio_iomap_inout(iicdev->scl_io, GPIO_IOMAP_IN_SPI2_SCK_IN, GPIO_IOMAP_OUT_SPI2_SCK_OUT);
gpio_iomap_inout(iicdev->sda_io, GPIO_IOMAP_IN_SPI2_IO0_IN, GPIO_IOMAP_OUT_SPI2_IO0_OUT);
}
if(iicdev->id_addr == 0){
i2c_ioctl(iicdev->i2c,IIC_SET_DEVICE_ADDR,iicdev->table[2]);
}
//printf("scl_io:%x sda_io:%x\r\n",iicdev->scl_io,iicdev->sda_io);
if(iicdev->rw_sta == 0){
if (iicdev->trx_buff != NULL) {
//处理DMA地址不对齐的情况使用外部传入的地址空间
i2c_read(iicdev->i2c,(int8*)&iicdev->table[3],iicdev->table[0],(int8*)iicdev->trx_buff,iicdev->table[1]);
} else {
i2c_read(iicdev->i2c,(int8*)&iicdev->table[3],iicdev->table[0],(int8*)&iicdev->table[3+iicdev->table[0]],iicdev->table[1]);
}
}else if(iicdev->rw_sta == 1){
i2c_write(iicdev->i2c, (int8*)&iicdev->table[3],iicdev->table[0], (int8*)&iicdev->table[3+iicdev->table[0]], iicdev->table[1]);
}else if(iicdev->rw_sta == 2){
table_scatter_data = (scatter_data*)iicdev->table;
// out_time = 0x1ff;
// iic_table_finish = 0;
i2c_master_write_table(iicdev->i2c, iicdev->len, iicdev->id_addr, table_scatter_data);
// while((iic_table_finish == 0)&&(out_time != 0)){
// iic_table_finish = i2c_ioctl(iic_dev,IIC_GET_TX_STATUS, 0);
// out_time--;
// os_sleep_ms(1);
// }
}
gpio_set_dir(iicdev->scl_io, GPIO_DIR_INPUT);
gpio_set_dir(iicdev->sda_io, GPIO_DIR_INPUT);
gpio_iomap_input(iicdev->scl_io,GPIO_IOMAP_INPUT);
gpio_iomap_input(iicdev->sda_io,GPIO_IOMAP_INPUT);
iicdev->sta = 0;
}
}
}while(1);
}else{
continue;
}
}
}
void iic_thread_init(){
struct i2c_device *iic_dev;
iic_dev = (struct i2c_device *)dev_get(HG_I2C1_DEVID);
struct i2c_device *iic_dev2;
iic_dev2 = (struct i2c_device *)dev_get(HG_I2C2_DEVID);
i2c_open(iic_dev, IIC_MODE_MASTER, IIC_ADDR_7BIT, 0);
i2c_set_baudrate(iic_dev,250000UL);
i2c_ioctl(iic_dev,IIC_SDA_OUTPUT_DELAY,20);
i2c_ioctl(iic_dev,IIC_FILTERING,20);
i2c_ioctl(iic_dev,IIC_SET_WRITE_TABLE_MODE, 1);
// i2c_open(iic_dev2, IIC_MODE_MASTER, IIC_ADDR_7BIT, 0);
// i2c_set_baudrate(iic_dev2,250000UL);
// i2c_ioctl(iic_dev2,IIC_FILTERING,20);
// i2c_ioctl(iic_dev2,IIC_SET_WRITE_TABLE_MODE, 1);
INIT_LIST_HEAD((struct list_head *)&iic_queue_head);
iicwq_sema_init();
os_task_create("iic_thread", iic_run_thread, NULL, OS_TASK_PRIORITY_HIGH-1, 0, NULL, 1024);
}