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

📄 soft_i2c.c

📁 软件模拟i2c
💻 C
📖 第 1 页 / 共 2 页
字号:
//       while(get_scl_input_level == 0);
       for(int ii = 0; ii < soft_i2c_para.delay * 16; ii++){
          if(get_scl_input_level){
             break;
        }
    }  /* wait for slc is free */    
       soft_i2c_Delay(soft_i2c_para.delay ) ;
     
//       set_scl_outputlevel(1);    //talk->set_scl(TRUE);   
//       set_scl_output;        
//       soft_i2c_Delay(soft_i2c_para.delay << 1);
    }

     set_scl_outputlevel(0);   //talk->set_scl(FALSE);
     set_scl_output;     
     soft_i2c_Delay(soft_i2c_para.delay << 1) ;
    return 0;
}

int soft_i2c_Read_(unsigned char *rw_buff, unsigned rw_bytes, unsigned rw_addr)
{
    unsigned char retry_times = I2C_RETRY_TIME ;
//    unsigned char read_device_addr ;
    INT8U err;
    unsigned int read_bytes ;
    int ret = 0 ;
        
    if (rw_addr + rw_bytes > soft_i2c_para.max_addr) {   	
        return -1;
    }
    
    AVMutexPend(swi2c_mutex, 0, &err); 
    
//    read_device_addr = soft_i2c_para.device_id | ((((rw_addr>>8)&0x7)<<1) & soft_i2c_para.id_mask);

    while(retry_times > 0){
        retry_times--;

        /* write sequence read address to device first */
        soft_i2c_Start() ;
            
        if((rw_addr&0xff) != 0xff) {    
            /* select device, write */
            soft_i2c_Write8Bit(soft_i2c_para.device_id) ;
            if(!soft_i2c_TestAck()){
            	  ret = -1 ;
            	  soft_i2c_Stop();
                continue;
            }
    
            /* send address */
            if (soft_i2c_para.id_mask == 0){
                soft_i2c_Write8Bit((unsigned char)(rw_addr>>8));
                if(!soft_i2c_TestAck()){
                	 ret = -1 ;
                	 soft_i2c_Stop();
                   continue;
                }
            }
    
            soft_i2c_Write8Bit(rw_addr & 0xff);
            if(!soft_i2c_TestAck()){
            	  soft_i2c_Stop();
            	  ret = -1 ;
                continue;
            }
        /* read */
        soft_i2c_ReStart() ;            
        }

        /* select device, read */
        soft_i2c_Write8Bit(soft_i2c_para.device_id | 1) ;
        if(!soft_i2c_TestAck()){
        	  soft_i2c_Stop();
            ret = -1 ;
            continue;
        }

        read_bytes = rw_bytes ;
        while (read_bytes > 1) {
            read_bytes--;
            *rw_buff++ = soft_i2c_Read8Bit();
            soft_i2c_Ack();
        }
        *rw_buff = soft_i2c_Read8Bit();        //read last byte data
        soft_i2c_NoAck();
        soft_i2c_Stop();
        break;
    }

//    soft_i2c_Stop() ;
    AVMutexPost(swi2c_mutex);
    return ret ;
}

int soft_i2c_Write_( unsigned char *rw_buff, unsigned rw_bytes, unsigned rw_addr)
{
    unsigned char retry_times = I2C_RETRY_TIME ;
//    unsigned char write_device_addr ;
    INT8U err;
    int ret = 0 ;
    unsigned int writed_bytes, page_size, write_addr ;
        
    if (rw_addr + rw_bytes > soft_i2c_para.max_addr) {  	
        return -1;
    }
    
    AVMutexPend(swi2c_mutex, 0, &err); 
    
    writed_bytes = 0;
    while((retry_times > 0) && (writed_bytes < rw_bytes)) {
        retry_times--;        
        writed_bytes = 0 ;
        
//        write_device_addr = soft_i2c_para.device_id |((((write_addr>>8)&0x7)<<1) & soft_i2c_para.id_mask);

        while (writed_bytes < rw_bytes) {
            write_addr = rw_addr + writed_bytes;
                       
            soft_i2c_Start() ;
            
            /* write operation, bit[0] = 0 */
            soft_i2c_Write8Bit(soft_i2c_para.device_id);
            if(!soft_i2c_TestAck()){
            	  soft_i2c_Stop();
                ret = -1;
                break;
            }
            
            if((rw_addr&0xff) != 0xff)           
            //weather to send the memory address
            {
                if (soft_i2c_para.id_mask == 0){
                    soft_i2c_Write8Bit((unsigned char)(write_addr>>8));
                    if(!soft_i2c_TestAck()){
                    	soft_i2c_Stop();
                    	 ret = -1;
                        break ;
                    }
                }
                
                soft_i2c_Write8Bit( write_addr & 0xff);
                if(!soft_i2c_TestAck()){
                	 soft_i2c_Stop();
                    ret = -1;
                    break ;
                }
            }
            
            if((rw_addr&0xff) == 0xff) {
                page_size = rw_bytes;
            }
            else if((rw_bytes - writed_bytes) > I2C_PAGE_SIZE) 
              {            
                page_size = I2C_PAGE_SIZE;    //I2C_PAGE_SIZE - (write_addr & I2C_PAGE_MOD) ;
              }
            else
            	{
            	  page_size = rw_bytes - writed_bytes;
            	 }            
            while(page_size > 0){
                page_size--;
                soft_i2c_Write8Bit( rw_buff[writed_bytes]) ;
                writed_bytes++;
                if(!soft_i2c_TestAck()){
                    ret = -1;
                    break ;
                }

//                if (writed_bytes == rw_bytes) {
//                	  ret = 0;
//                    break;
//                }
            }
            
            soft_i2c_Stop() ;
            
            if (writed_bytes == rw_bytes) {
                	  ret = 0;
                }  
                          
            /* max 1ms */ 
            soft_i2c_Delay(soft_i2c_para.delay * 1500) ;
            break;
        } /* paged write */
    }
    AVMutexPost(swi2c_mutex);
    return ret;
}
int soft_i2c_Read_1(unsigned char *rw_buff, unsigned int rw_bytes)
{
       
//    AVMutexPend(swi2c_mutex, 0, &err); 
//   AVMutexPost(swi2c_mutex);

     return 0;
}

int soft_i2c_Write_1(unsigned char *rw_buff, unsigned int rw_bytes)
{
//    AVMutexPend(swi2c_mutex, 0, &err); 
//   AVMutexPost(swi2c_mutex);    

      return 0;
}


avfs_device_driver soft_i2c_init(avfs_device_major_number major, avfs_device_minor_number minor, void *arg)
{
		INT8U err;
    avfs_status_code status;

    status = avfs_io_register_name(
        "/dev/soft_i2c",    //DRIVER_NAME,
        major,
        (avfs_device_minor_number) 0
    );
    swi2c_mutex = AVMutexCreate(&err);  
    return AVFS_SUCCESSFUL;
}

avfs_device_driver soft_i2c_open(avfs_device_major_number major, avfs_device_minor_number minor, void *arg)
{ 
    return AVFS_SUCCESSFUL;
}

avfs_device_driver soft_i2c_close(avfs_device_major_number major, avfs_device_minor_number minor, void *arg)
{
    return AVFS_SUCCESSFUL;
}

avfs_device_driver soft_i2c_read(avfs_device_major_number major, avfs_device_minor_number minor, void *arg)
{   
    avfs_libio_rw_args_t *args = arg;
    unsigned8 *rx_buf = args->buffer;
    unsigned32 rx_cnt = (args->count) & 0xffff;
    unsigned32 rx_addr = ((args->count) >> 16 ) & 0xffff;
    if(soft_i2c_para.i2c_flag)
    	return soft_i2c_Read_1(rx_buf, rx_cnt);
    else    
    return soft_i2c_Read_(rx_buf,rx_cnt,rx_addr);
}

avfs_device_driver soft_i2c_write(avfs_device_major_number major, avfs_device_minor_number minor, void *arg)
{
    avfs_libio_rw_args_t *args = arg;
    unsigned8 *wx_buf = args->buffer;
    unsigned32 wx_cnt = (args->count) & 0xffff;
    unsigned32 wx_addr = ((args->count) >> 16 ) & 0xffff;
    if(soft_i2c_para.i2c_flag)
    	return soft_i2c_Write_1(wx_buf, wx_cnt);
    else	
      return soft_i2c_Write_(wx_buf,wx_cnt,wx_addr);
}

avfs_device_driver soft_i2c_ioctl(avfs_device_major_number major, avfs_device_minor_number minor, void *arg)
{
    avfs_libio_ioctl_args_t *args;
    unsigned command, *buffer;
    int ret = 0;
    args    = arg;
    command = args->command;
    buffer  = args->buffer;
         
    switch(command)	
    {
    	case INIT_I2C_PIN_MUX:
    		soft_i2c_para_t *soft_i2c_cfg;
    		soft_i2c_cfg = (soft_i2c_para_t *)buffer;
		    if(soft_i2c_cfg ->magic == SOFT_I2C_MAGIC)
    		     soft_i2c_para = *soft_i2c_cfg; 
		    else
		    ret = -1;
    		break;     		
    		
    	case	MODIFY_DEVICE_ID:
    		soft_i2c_para.device_id = (unsigned char )buffer;
    		break;

    	case	MODIFY_I2C_FLAG:
    		soft_i2c_para.i2c_flag = (unsigned char )buffer;
    		break;

    	case	MODIFY_I2C_DELAY:
    		soft_i2c_para.delay = (unsigned )buffer;
    		break;
    		    		    		
//    	case I2C_READ_1:
//    		soft_i2c_Read_1(buffer, rw_cnt);
//    		break;
    		
//    	case I2C_WRITE_1:
//    		soft_i2c_Write_1(buffer, rw_cnt);
//    		break;
    		
      default:
      	break;			
    } 
    return ret;    
}

⌨️ 快捷键说明

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