Ejemplo n.º 1
0
/* 主机端的主程序简单示例 */
main() {
	unsigned char xdata data_to_send[200];  /* 缓冲区 */
	unsigned char str_to_print[]="OK, support text print\n";
	unsigned char s;
	mDelaymS( 200 );
	set_usb_mode( 6 );  /* 设置USB主机模式 */
	while ( wait_interrupt()!=USB_INT_CONNECT );  /* 等待USB打印机连接上来 */

/* 如果设备端是CH341转打印口或者是CH37X,那么以下步骤是可选的,如果是其它USB芯片,那么可能需要执行以下步骤 */
#define USB_RESET_FIRST	1  /* USB规范中未要求在USB设备插入后必须复位该设备,但是计算机的WINDOWS总是这样做,所以有些USB设备也要求在插入后必须先复位才能工作 */
#ifdef USB_RESET_FIRST
	set_usb_mode( 7 );  /* 复位USB设备,CH375向USB信号线的D+和D-输出低电平 */
/* 如果单片机对CH375的INT#引脚采用中断方式而不是查询方式,那么应该在复制USB设备期间禁止CH375中断,在USB设备复位完成后清除CH375中断标志再允许中断 */
	mDelaymS( 10 );  /* 复位时间不少于1mS,建议为10mS */
	set_usb_mode( 6 );  /* 结束复位 */
	mDelaymS( 100 );
	while ( wait_interrupt()!=USB_INT_CONNECT );  /* 等待复位之后的设备端再次连接上来 */
#endif

	mDelaymS( 200 );  /* 有些USB设备要等待数百毫秒才能正常工作 */
	if ( init_print()!=USB_INT_SUCCESS ) while(1);  /* 错误 */
	while ( 1 ) {
		s = get_port_status( );
		if ( s!=0xFF ) {
/*			if ( s&0x20 ) printf("No paper!\n");
			if ( (s&0x08) == 0 ) printf("Print ERROR!\n");*/
		}
		send_data( strlen(str_to_print), str_to_print );  /* 输出数据给打印机,与通过并口方式输出一样 */
		send_data( sizeof(data_to_send), data_to_send );  /* 输出的数据必须按照打印机的格式要求或者遵循打印描述语言 */
		/* 可以再次继续发送数据或者接收数据 */
	}
}
Ejemplo n.º 2
0
unsigned char issue_token_X( unsigned char endp_and_pid, unsigned char tog ) {  /* 执行USB事务,适用于CH375A */
/* 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功 */
	CH375_WR_CMD_PORT( CMD_ISSUE_TKN_X );
	CH375_WR_DAT_PORT( tog );  /* 同步标志的位7为主机端点IN的同步触发位, 位6为主机端点OUT的同步触发位, 位5~位0必须为0 */
	CH375_WR_DAT_PORT( endp_and_pid );  /* 高4位目的端点号, 低4位令牌PID */
	return( wait_interrupt() );  /* 等待CH375操作完成 */
}
Ejemplo n.º 3
0
unsigned char set_addr( unsigned char addr ) {  /* 设置设备端的USB地址 */
	unsigned char status;
	CH375_WR_CMD_PORT( CMD_SET_ADDRESS );  /* 设置USB设备端的USB地址 */
	CH375_WR_DAT_PORT( addr );  /* 地址, 从1到127之间的任意值, 常用2到20 */
	status=wait_interrupt();  /* 等待CH375操作完成 */
	if ( status==USB_INT_SUCCESS ) {  /* 操作成功 */
		CH375_WR_CMD_PORT( CMD_SET_USB_ADDR );  /* 设置USB主机端的USB地址 */
		CH375_WR_DAT_PORT( addr );  /* 当目标USB设备的地址成功修改后,应该同步修改主机端的USB地址 */
	}
	mDelaymS( 5 );
	return( status );
}
Ejemplo n.º 4
0
int
lis2dw12_stream_read(struct sensor *sensor,
                   sensor_type_t sensor_type,
                   sensor_data_func_t read_func,
                   void *read_arg,
                   uint32_t time_ms)
{
    struct lis2dw12 *lis2dw12;
    struct sensor_itf *itf;
    int rc;
    os_time_t time_ticks;
    os_time_t stop_ticks = 0;
    struct lis2dw12_private_driver_data *pdd;
    uint8_t fifo_samples;

    /* If the read isn't looking for accel data, don't do anything. */
    if (!(sensor_type & SENSOR_TYPE_ACCELEROMETER)) {
        return SYS_EINVAL;
    }

    lis2dw12 = (struct lis2dw12 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);
    pdd = &lis2dw12->pdd;

    undo_interrupt(&lis2dw12->intr);

    if (pdd->interrupt) {
        return SYS_EBUSY;
    }

    /* enable interrupt */
    pdd->interrupt = &lis2dw12->intr;

    rc = enable_interrupt(sensor, lis2dw12->cfg.stream_read_interrupt);
    if (rc) {
        goto done;
    }

    if (time_ms != 0) {
        rc = os_time_ms_to_ticks(time_ms, &time_ticks);
        if (rc) {
            goto done;
        }
        stop_ticks = os_time_get() + time_ticks;
    }

    for (;;) {
        wait_interrupt(&lis2dw12->intr, pdd->int_num);
        fifo_samples = 1;
        
        while(fifo_samples > 0) {
            rc = lis2dw12_do_read(sensor, read_func, read_arg);
            if (rc) {
                goto done;
            }

            rc = lis2dw12_get_fifo_samples(itf, &fifo_samples);
            if (rc) {
                goto done;
            }
        }
        
        if (time_ms != 0 && OS_TIME_TICK_GT(os_time_get(), stop_ticks)) {
                break;
        }
    }

done:
    /* disable interrupt */
    pdd->interrupt = NULL;
    rc = disable_interrupt(sensor, lis2dw12->cfg.stream_read_interrupt);

    return rc;
}
Ejemplo n.º 5
0
unsigned char set_config( unsigned char cfg ) {  /* 设置设备端的USB配置 */
	tog_send=tog_recv=0;  /* 复位USB数据同步标志 */
	CH375_WR_CMD_PORT( CMD_SET_CONFIG );  /* 设置USB设备端的配置值 */
	CH375_WR_DAT_PORT( cfg );  /* 此值取自USB设备的配置描述符中 */
	return( wait_interrupt() );  /* 等待CH375操作完成 */
}
Ejemplo n.º 6
0
unsigned char get_descr( unsigned char type ) {  /* 从设备端获取描述符 */
	CH375_WR_CMD_PORT( CMD_GET_DESCR );
	CH375_WR_DAT_PORT( type );  /* 描述符类型, 只支持1(设备)或者2(配置) */
	return( wait_interrupt() );  /* 等待CH375操作完成 */
}
Ejemplo n.º 7
0
unsigned char issue_token( unsigned char endp_and_pid ) {  /* 执行USB事务 */
/* 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功 */
	CH375_WR_CMD_PORT( CMD_ISSUE_TOKEN );
	CH375_WR_DAT_PORT( endp_and_pid );  /* 高4位目的端点号, 低4位令牌PID */
	return( wait_interrupt() );  /* 等待CH375操作完成 */
}
Ejemplo n.º 8
0
unsigned char clr_stall( unsigned char endp_addr ) {  /* USB通讯失败后,复位设备端的指定端点到DATA0 */
	CH375_WR_CMD_PORT( CMD_CLR_STALL );
	CH375_WR_DAT_PORT( endp_addr );
	return( wait_interrupt() );
}
Ejemplo n.º 9
0
/*
 * Generic i2c master transfer entrypoint
 */
static int
keywest_xfer(	struct i2c_adapter *adap,
		struct i2c_msg *msgs, 
		int num)
{
	struct keywest_chan* chan = i2c_get_adapdata(adap);
	struct keywest_iface* iface = chan->iface;
	struct i2c_msg *pmsg;
	int i, completed;
	int rc = 0;

	if (iface->state == state_dead)
		return -ENXIO;

	if (pmac_low_i2c_lock(iface->node))
		return -ENXIO;

	/* Set adapter to standard mode */
	iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
	iface->cur_mode |= KW_I2C_MODE_STANDARD;

	completed = 0;
	for (i = 0; rc >= 0 && i < num;) {
		u8 addr;
		
		pmsg = &msgs[i++];
		addr = pmsg->addr;
		if (pmsg->flags & I2C_M_TEN) {
			printk(KERN_ERR "i2c-keywest: 10 bits addr not supported !\n");
			rc = -EINVAL;
			break;
		}
		pr_debug("xfer: chan: %d, doing %s %d bytes to 0x%02x - %d of %d messages\n",
		     chan->chan_no,
		     pmsg->flags & I2C_M_RD ? "read" : "write",
                     pmsg->len, addr, i, num);
    
		/* Setup channel & clear pending irqs */
		write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4));
		write_reg(reg_isr, read_reg(reg_isr));
		write_reg(reg_status, 0);
		
		iface->data = pmsg->buf;
		iface->datalen = pmsg->len;
		iface->state = state_addr;
		iface->result = 0;
		if (pmsg->flags & I2C_M_RD)
			iface->read_write = I2C_SMBUS_READ;
		else
			iface->read_write = I2C_SMBUS_WRITE;

		/* Set up address and r/w bit */
		if (pmsg->flags & I2C_M_REV_DIR_ADDR)
			addr ^= 1;		
		write_reg(reg_addr,
			(addr << 1) |
			((iface->read_write == I2C_SMBUS_READ) ? 0x01 : 0x00));

#ifndef POLLED_MODE
		/* Arm timeout */
		iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
		add_timer(&iface->timeout_timer);
#endif

		/* Start sending address & enable interrupt*/
		write_reg(reg_ier, KW_I2C_IRQ_MASK);
		write_reg(reg_control, KW_I2C_CTL_XADDR);

#ifdef POLLED_MODE
		pr_debug("using polled mode...\n");
		/* State machine, to turn into an interrupt handler */
		while(iface->state != state_idle) {
			u8 isr = wait_interrupt(iface);
			handle_interrupt(iface, isr);
		}
#else /* POLLED_MODE */
		pr_debug("using interrupt mode...\n");
		wait_for_completion(&iface->complete);	
#endif /* POLLED_MODE */	

		rc = iface->result;
		if (rc == 0)
			completed++;
		pr_debug("transfer done, result: %d\n", rc);
	}

	/* Release sem */
	pmac_low_i2c_unlock(iface->node);

	return completed;
}
Ejemplo n.º 10
0
/*
 * SMBUS-type transfer entrypoint
 */
static s32
keywest_smbus_xfer(	struct i2c_adapter*	adap,
			u16			addr,
			unsigned short		flags,
			char			read_write,
			u8			command,
			int			size,
			union i2c_smbus_data*	data)
{
	struct keywest_chan* chan = i2c_get_adapdata(adap);
	struct keywest_iface* iface = chan->iface;
	int len;
	u8* buffer;
	u16 cur_word;
	int rc = 0;

	if (iface->state == state_dead)
		return -ENXIO;
		
	/* Prepare datas & select mode */
	iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
	switch (size) {
        case I2C_SMBUS_QUICK:
	    	len = 0;
	    	buffer = NULL;
	    	iface->cur_mode |= KW_I2C_MODE_STANDARD;
	    	break;
        case I2C_SMBUS_BYTE:
	    	len = 1;
	    	buffer = &data->byte;
	    	iface->cur_mode |= KW_I2C_MODE_STANDARD;
	    	break;
        case I2C_SMBUS_BYTE_DATA:
	    	len = 1;
	    	buffer = &data->byte;
	    	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
	    	break;
        case I2C_SMBUS_WORD_DATA:
	    	len = 2;
	    	cur_word = cpu_to_le16(data->word);
	    	buffer = (u8 *)&cur_word;
	    	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
		break;
        case I2C_SMBUS_BLOCK_DATA:
	    	len = data->block[0];
	    	buffer = &data->block[1];
	    	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
		break;
        default:
	    	return -1;
	}

	/* Turn a standardsub read into a combined mode access */
 	if (read_write == I2C_SMBUS_READ
 	    && (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB) {
 		iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
 		iface->cur_mode |= KW_I2C_MODE_COMBINED;
 	}

	/* Original driver had this limitation */
	if (len > 32)
		len = 32;

	if (pmac_low_i2c_lock(iface->node))
		return -ENXIO;

	pr_debug("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n",
		chan->chan_no, addr, len, read_write == I2C_SMBUS_READ);

	iface->data = buffer;
	iface->datalen = len;
	iface->state = state_addr;
	iface->result = 0;
	iface->read_write = read_write;
	
	/* Setup channel & clear pending irqs */
	write_reg(reg_isr, read_reg(reg_isr));
	write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4));
	write_reg(reg_status, 0);

	/* Set up address and r/w bit */
	write_reg(reg_addr,
		(addr << 1) | ((read_write == I2C_SMBUS_READ) ? 0x01 : 0x00));

	/* Set up the sub address */
	if ((iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB
	    || (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED)
		write_reg(reg_subaddr, command);

#ifndef POLLED_MODE
	/* Arm timeout */
	iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
	add_timer(&iface->timeout_timer);
#endif

	/* Start sending address & enable interrupt*/
	write_reg(reg_control, KW_I2C_CTL_XADDR);
	write_reg(reg_ier, KW_I2C_IRQ_MASK);

#ifdef POLLED_MODE
	pr_debug("using polled mode...\n");
	/* State machine, to turn into an interrupt handler */
	while(iface->state != state_idle) {
		unsigned long flags;

		u8 isr = wait_interrupt(iface);
		spin_lock_irqsave(&iface->lock, flags);
		handle_interrupt(iface, isr);
		spin_unlock_irqrestore(&iface->lock, flags);
	}
#else /* POLLED_MODE */
	pr_debug("using interrupt mode...\n");
	wait_for_completion(&iface->complete);	
#endif /* POLLED_MODE */	

	rc = iface->result;	
	pr_debug("transfer done, result: %d\n", rc);

	if (rc == 0 && size == I2C_SMBUS_WORD_DATA && read_write == I2C_SMBUS_READ)
	    	data->word = le16_to_cpu(cur_word);
	
	/* Release sem */
	pmac_low_i2c_unlock(iface->node);
	
	return rc;
}