コード例 #1
0
ファイル: usb_serial.c プロジェクト: BenW0/IMC_Closed_Loop
// read a block of bytes to a buffer
int usb_serial_read(void *buffer, uint32_t size)
{
	uint8_t *p = (uint8_t *)buffer;
	uint32_t qty, count=0;

	while (size) {
		if (!usb_configuration) break;
		if (!rx_packet) {
			rx:
			rx_packet = usb_rx(CDC_RX_ENDPOINT);
			if (!rx_packet) break;
			if (rx_packet->len == 0) {
				usb_free(rx_packet);
				goto rx;
			}
		}
		qty = rx_packet->len - rx_packet->index;
		if (qty > size) qty = size;
		memcpy(p, rx_packet->buf + rx_packet->index, qty);
		p += qty;
		count += qty;
		size -= qty;
		rx_packet->index += qty;
		if (rx_packet->index >= rx_packet->len) {
			usb_free(rx_packet);
			rx_packet = NULL;
		}
	}
	return count;
}
コード例 #2
0
ファイル: fc_usb.cpp プロジェクト: Dewb/fadecandy
void fcBuffers::handleUSB()
{
    /*
     * Look for incoming USB packets, and file them appropriately.
     * Our framebuffer and LUT buffers are arrays of references to USB packets
     * which we hold until a new packet arrives to replace them.
     */

    bool handledAnyPackets = false;

    while (1) {
        usb_packet_t *packet = usb_rx(FC_OUT_ENDPOINT);
        if (!packet) {
            break;
        }
        handledAnyPackets = true;

        unsigned control = packet->buf[0];
        unsigned type = control & TYPE_BITS;
        unsigned final = control & FINAL_BIT;
        unsigned index = control & INDEX_BITS;

        switch (type) {

            case TYPE_FRAMEBUFFER:
                fbNew->store(index, packet);
                if (final) {
                    finalizeFramebuffer();
                }
                break;

            case TYPE_LUT:
                lutNew.store(index, packet);
                if (final) {
                    finalizeLUT();
                }
                break;

            case TYPE_CONFIG:
                flags = packet->buf[1];
                usb_free(packet);
                break;

            default:
                usb_free(packet);
                break;
        }
    }

    if (flags & CFLAG_NO_ACTIVITY_LED) {
        // LED under manual control
        digitalWrite(LED_BUILTIN, flags & CFLAG_LED_CONTROL);
    } else {
        // Use the built-in LED as a USB activity indicator.
        digitalWrite(LED_BUILTIN, handledAnyPackets);
    }
}
コード例 #3
0
ファイル: led_usb.c プロジェクト: ain101/SedecimWS2811
void ledStorePacket(ledPacketBuffer *const pBuffer, usb_packet_t *const packet)
{
	if (pBuffer->pCounter < NUM_BUFFS_PER_FRAME) {
		// Store a packet, holding a reference to it.
		usb_packet_t *prev = pBuffer->packets[pBuffer->pCounter];
		pBuffer->packets[pBuffer->pCounter] = packet;
		usb_free(prev);
		pBuffer->pByteCount += packet->len;
		pBuffer->pCounter++;
	} else {
		// Error; ignore this packet.
		usb_free(packet);
	}
}
コード例 #4
0
ファイル: usb_serial.c プロジェクト: BenW0/IMC_Closed_Loop
// discard any buffered input
void usb_serial_flush_input(void)
{
	usb_packet_t *rx;

	if (!usb_configuration) return;
	if (rx_packet) {
		usb_free(rx_packet);
		rx_packet = NULL;
	}
	while (1) {
		rx = usb_rx(CDC_RX_ENDPOINT);
		if (!rx) break;
		usb_free(rx);
	}
}
コード例 #5
0
ファイル: fc_usb.cpp プロジェクト: JoeCase/fadecandy
bool fcBuffers::handleUSB(usb_packet_t *packet)
{
    unsigned control = packet->buf[0];
    unsigned type = control & TYPE_BITS;
    unsigned final = control & FINAL_BIT;
    unsigned index = control & INDEX_BITS;

    switch (type) {

    case TYPE_FRAMEBUFFER:

        // Framebuffer updates are synchronized; if we're waiting to finalize fbNew,
        // don't accept any new packets until that buffer becomes available.
        if (pendingFinalizeFrame) {
            return false;
        }

        fbNew->store(index, packet);
        if (final) {
            pendingFinalizeFrame = true;
        }
        break;

    case TYPE_LUT:
        // LUT accesses are not synchronized
        lutNew.store(index, packet);

        if (final) {
            // Finalize the LUT on the main thread, it's less async than doing it in the ISR.
            pendingFinalizeLUT = true;
        }
        break;

    case TYPE_CONFIG:
        // Config changes take effect immediately.
        flags = packet->buf[1];
        usb_free(packet);
        break;

    default:
        usb_free(packet);
        break;
    }

    // Handled this packet
    handledAnyPacketsThisFrame = true;
    return true;
}
コード例 #6
0
ファイル: usb_serial.c プロジェクト: Applepi/controller
// get the next character, or -1 if nothing received
int usb_serial_getchar()
{
	unsigned int i;
	int c;

	if ( !rx_packet )
	{
		if ( !usb_configuration )
			return -1;
		rx_packet = usb_rx( CDC_RX_ENDPOINT );
		if ( !rx_packet )
			return -1;
	}
	i = rx_packet->index;
	c = rx_packet->buf[i++];
	if ( i >= rx_packet->len )
	{
		usb_free( rx_packet );
		rx_packet = NULL;
	}
	else
	{
		rx_packet->index = i;
	}
	return c;
}
コード例 #7
0
/*------------------------------------------------------------------------*
 *	usb_pc_free_mem - free DMA memory
 *
 * This function is NULL safe.
 *------------------------------------------------------------------------*/
void
usb_pc_free_mem(struct usb_page_cache *pc)
{
	if (pc != NULL && pc->buffer != NULL) {
		usb_free(pc->tag);
		pc->buffer = NULL;
	}
}
コード例 #8
0
static inline void ehci_qtd_free(struct ehci_hcd *ehci, struct ehci_qtd *qtd)
{
	if ((qtd->qtd_dma & (USB_IRAM_BASE_ADDR & 0xFFF00000)) ==
	    (USB_IRAM_BASE_ADDR & 0xFFF00000))
		usb_free(qtd->qtd_dma);
	else
		dma_pool_free(ehci->qtd_pool, qtd, qtd->qtd_dma);
	--g_debug_qtd_allocated;
}
コード例 #9
0
ファイル: usb_serial.c プロジェクト: voidptr/evolight
static void usb_serial_receive(void)
{
	if (!usb_configuration) return;
	if (rx_packet) return;
	while (1) {
		rx_packet = usb_rx(CDC_RX_ENDPOINT);
		if (rx_packet == NULL) return;
		if (rx_packet->len > 0) return;
		usb_free(rx_packet);
		rx_packet = NULL;
	}
}
コード例 #10
0
ファイル: usb_rawhid.c プロジェクト: Quirade/TiltyIMU
int usb_rawhid_recv(void *buffer, uint32_t timeout)
{
	usb_packet_t *rx_packet;
	uint32_t begin = millis();

	while (1) {
		if (!usb_configuration) return -1;
		rx_packet = usb_rx(RAWHID_RX_ENDPOINT);
		if (rx_packet) break;
		if (millis() - begin > timeout || !timeout) return 0;
		yield();
	}
	memcpy(buffer, rx_packet->buf, RAWHID_RX_SIZE);
	usb_free(rx_packet);
	return RAWHID_RX_SIZE;
}
コード例 #11
0
ファイル: usb_serial.c プロジェクト: voidptr/evolight
// get the next character, or -1 if nothing received
int usb_serial_getchar(void)
{
	unsigned int i;
	int c;

	usb_serial_receive();
	if (!rx_packet) return -1;
	i = rx_packet->index;
	c = rx_packet->buf[i++];
	if (i >= rx_packet->len) {
		usb_free(rx_packet);
		rx_packet = NULL;
	} else {
		rx_packet->index = i;
	}
	return c;
}
コード例 #12
0
ファイル: usb_dev.c プロジェクト: downbeat/senseye
// Called from usb_free, but only when usb_rx_memory_needed > 0, indicating
// receive endpoints are starving for memory.  The intention is to give
// endpoints needing receive memory priority over the user's code, which is
// likely calling usb_malloc to obtain memory for transmitting.  When the
// user is creating data very quickly, their consumption could starve reception
// without this prioritization.  The packet buffer (input) is assigned to the
// first endpoint needing memory.
//
void usb_rx_memory(usb_packet_t *packet)
{
	unsigned int i;
	const uint8_t *cfg;

	cfg = usb_endpoint_config_table;
	//serial_print("rx_mem:");
	__disable_irq();
	for (i=1; i < NUM_ENDPOINTS; i++) {
		if (*cfg++ & USB_ENDPT_EPRXEN) {
			if (table[index(i, RX, EVEN)].desc == 0) {
				table[index(i, RX, EVEN)].addr = packet->buf;
				table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
				usb_rx_memory_needed--;
				__enable_irq();
				//serial_phex(i);
				//serial_print(",even\n");
				return;
			}
			if (table[index(i, RX, ODD)].desc == 0) {
				table[index(i, RX, ODD)].addr = packet->buf;
				table[index(i, RX, ODD)].desc = BDT_DESC(64, 1);
				usb_rx_memory_needed--;
				__enable_irq();
				//serial_phex(i);
				//serial_print(",odd\n");
				return;
			}
		}
	}
	__enable_irq();
	// we should never reach this point.  If we get here, it means
	// usb_rx_memory_needed was set greater than zero, but no memory
	// was actually needed.  
	usb_rx_memory_needed = 0;
	usb_free(packet);
	return;
}
コード例 #13
0
static void qh_destroy(struct ehci_qh *qh)
{
	struct ehci_hcd *ehci = qh->ehci;

	/* clean qtds first, and know this is not linked */
	if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) {
		ehci_dbg(ehci, "unused qh not empty!\n");
		BUG();
	}
	if (qh->dummy)
		ehci_qtd_free(ehci, qh->dummy);
	int i;
	for (i = 0; i < IRAM_NTD; i++) {
		if (ehci->usb_address[i] == (qh->hw_info1 & 0x7F))
			ehci->usb_address[i] = 0;
	}

	if ((qh->qh_dma & (USB_IRAM_BASE_ADDR & 0xFFF00000)) ==
	    (USB_IRAM_BASE_ADDR & 0xFFF00000))
		usb_free(qh->qh_dma);
	else
		dma_pool_free(ehci->qh_pool, qh, qh->qh_dma);
	--g_debug_qH_allocated;
}
コード例 #14
0
static int msm72k_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct usb_info *ui;
	int irq;
	int ret;

	INFO("msm72k_probe\n");
	ui = kzalloc(sizeof(struct usb_info), GFP_KERNEL);
	if (!ui)
		return -ENOMEM;

	ui->pdev = pdev;

	if (pdev->dev.platform_data) {
		struct msm_hsusb_platform_data *pdata = pdev->dev.platform_data;
		ui->phy_reset = pdata->phy_reset;
		ui->phy_init_seq = pdata->phy_init_seq;
	}

	irq = platform_get_irq(pdev, 0);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res || (irq < 0))
		return usb_free(ui, -ENODEV);

	ui->addr = ioremap(res->start, 4096);
	if (!ui->addr)
		return usb_free(ui, -ENOMEM);

	ui->buf = dma_alloc_coherent(&pdev->dev, 4096, &ui->dma, GFP_KERNEL);
	if (!ui->buf)
		return usb_free(ui, -ENOMEM);

	ui->pool = dma_pool_create("msm72k_udc", NULL, 32, 32, 0);
	if (!ui->pool)
		return usb_free(ui, -ENOMEM);

	INFO("msm72k_probe() io=%p, irq=%d, dma=%p(%x)\n",
	       ui->addr, irq, ui->buf, ui->dma);

	ui->clk = clk_get(&pdev->dev, "usb_hs_clk");
	if (IS_ERR(ui->clk))
		return usb_free(ui, PTR_ERR(ui->clk));

	ui->pclk = clk_get(&pdev->dev, "usb_hs_pclk");
	if (IS_ERR(ui->pclk))
		return usb_free(ui, PTR_ERR(ui->pclk));

	/* FIXME: dmb cannot be called from interrupt context
	 * for the first time; Need to verify on how it needs
	 * to be fixed
	 */
	dmb();

	ret = request_irq(irq, usb_interrupt, 0, pdev->name, ui);
	if (ret)
		return usb_free(ui, ret);
	enable_irq_wake(irq);
	ui->irq = irq;

	ui->gadget.ops = &msm72k_ops;
	ui->gadget.is_dualspeed = 1;
	device_initialize(&ui->gadget.dev);
	strcpy(ui->gadget.dev.bus_id, "gadget");
	ui->gadget.dev.parent = &pdev->dev;
	ui->gadget.dev.dma_mask = pdev->dev.dma_mask;

	the_usb_info = ui;

	usb_debugfs_init(ui);

	usb_prepare(ui);

	return 0;
}
コード例 #15
0
ファイル: usb_flightsim.cpp プロジェクト: jbliesener/cores
void FlightSimClass::update(void)
{
	uint8_t len, maxlen, type, *p, *end;
	union {
		uint8_t b[4];
		long l;
		float f;
	} data;
	usb_packet_t *rx_packet;
	uint16_t id;

	while (1) {
		if (!usb_configuration) break;
		rx_packet = usb_rx(FLIGHTSIM_RX_ENDPOINT);
		if (!rx_packet) break;
		p = rx_packet->buf;
		end = p + 64;
		maxlen = 64;
		do {
			len = p[0];
			if (len < 2 || len > maxlen) break;
			switch (p[1]) {
			  case 0x02: // write data
				if (len < 10) break;
				id = p[2] | (p[3] << 8);
				type = p[4];
				if (type == 1) {
					FlightSimInteger *item = FlightSimInteger::find(id);
					if (!item) break;
					#ifdef KINETISK
					data.l = *(long *)(p + 6);
					#else
					data.b[0] = p[6];
					data.b[1] = p[7];
					data.b[2] = p[8];
					data.b[3] = p[9];
					#endif
					item->update(data.l);
				} else if (type == 2) {
					FlightSimFloat *item = FlightSimFloat::find(id);
					if (!item) break;
					#ifdef KINETISK
					data.f = *(float *)(p + 6);
					#else
					data.b[0] = p[6];
					data.b[1] = p[7];
					data.b[2] = p[8];
					data.b[3] = p[9];
					#endif
					item->update(data.f);
/// JB
				} else if (type == 3) {
					FlightSimEvent *item = FlightSimEvent::find(id);
					if (!item) break;
					#ifdef KINETISK
					data.l = *(long *)(p + 6);
					#else
					data.b[0] = p[6];
					data.b[1] = p[7];
					data.b[2] = p[8];
					data.b[3] = p[9];
					#endif
					item->update(data.f);
				} else if (type == 4) {
					FlightSimData *item = FlightSimData::find(id);
					if (!item) break;
					item->update(((char*)p)+6,len-6);
/// JB End
				}
				break;
			  case 0x03: // enable/disable
				if (len < 4) break;
				switch (p[2]) {
				  case 1:
					request_id_messages = 1;
					/* no break */
				  case 2:
					enable();
					frameCount++;
					break;
				  case 3:
					disable();
				}
			}
			p += len;
			maxlen -= len;
		} while (p < end);
		usb_free(rx_packet);
	}
	if (enabled && request_id_messages) {
		request_id_messages = 0;
		for (FlightSimCommand *p = FlightSimCommand::first; p; p = p->next) {
			p->identify();
		}
/// JB
		for (FlightSimEvent *p = FlightSimEvent::first; p; p = p->next) {
			p->identify();
		}
		for (FlightSimData *p = FlightSimData::first; p; p=p->next) {
			p->identify();
		}
/// JB End
		for (FlightSimInteger *p = FlightSimInteger::first; p; p = p->next) {
			p->identify();
			// TODO: send any dirty data
		}
		for (FlightSimFloat *p = FlightSimFloat::first; p; p = p->next) {
			p->identify();
			// TODO: send any dirty data
		}
	}
}
コード例 #16
0
static int msm72k_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct usb_info *ui;
	int irq;
	int ret;

	INFO("msm72k_probe\n");
	ui = kzalloc(sizeof(struct usb_info), GFP_KERNEL);
	if (!ui)
		return -ENOMEM;

	spin_lock_init(&ui->lock);
	ui->pdev = pdev;

	if (pdev->dev.platform_data) {
		struct msm_hsusb_platform_data *pdata = pdev->dev.platform_data;
		ui->phy_reset = pdata->phy_reset;
		ui->phy_init_seq = pdata->phy_init_seq;
		ui->usb_connected = pdata->usb_connected;
	}

	irq = platform_get_irq(pdev, 0);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res || (irq < 0))
		return usb_free(ui, -ENODEV);

	ui->addr = ioremap(res->start, 4096);
	if (!ui->addr)
		return usb_free(ui, -ENOMEM);

	ui->buf = dma_alloc_coherent(&pdev->dev, 4096, &ui->dma, GFP_KERNEL);
	if (!ui->buf)
		return usb_free(ui, -ENOMEM);

	ui->pool = dma_pool_create("msm72k_udc", NULL, 32, 32, 0);
	if (!ui->pool)
		return usb_free(ui, -ENOMEM);

	INFO("msm72k_probe() io=%p, irq=%d, dma=%p(%x)\n",
	       ui->addr, irq, ui->buf, ui->dma);

	ui->clk = clk_get(&pdev->dev, "usb_hs_clk");
	if (IS_ERR(ui->clk))
		return usb_free(ui, PTR_ERR(ui->clk));

	ui->pclk = clk_get(&pdev->dev, "usb_hs_pclk");
	if (IS_ERR(ui->pclk))
		return usb_free(ui, PTR_ERR(ui->pclk));

	ui->otgclk = clk_get(&pdev->dev, "usb_otg_clk");
	if (IS_ERR(ui->otgclk))
		ui->otgclk = NULL;

	ui->coreclk = clk_get(&pdev->dev, "usb_hs_core_clk");
	if (IS_ERR(ui->coreclk))
		ui->coreclk = NULL;

	ui->ebi1clk = clk_get(NULL, "ebi1_clk");
	if (IS_ERR(ui->ebi1clk))
		return usb_free(ui, PTR_ERR(ui->ebi1clk));

	/* clear interrupts before requesting irq */
	if (ui->coreclk)
		clk_enable(ui->coreclk);
	clk_enable(ui->clk);
	clk_enable(ui->pclk);
	if (ui->otgclk)
		clk_enable(ui->otgclk);
	writel(0, USB_USBINTR);
	writel(0, USB_OTGSC);
	if (ui->coreclk)
		clk_disable(ui->coreclk);
	if (ui->otgclk)
		clk_disable(ui->otgclk);
	clk_disable(ui->pclk);
	clk_disable(ui->clk);

	ret = request_irq(irq, usb_interrupt, 0, pdev->name, ui);
	if (ret)
		return usb_free(ui, ret);
	enable_irq_wake(irq);
	ui->irq = irq;

	ui->gadget.ops = &msm72k_ops;
	ui->gadget.is_dualspeed = 1;
	device_initialize(&ui->gadget.dev);
	dev_set_name(&ui->gadget.dev, "gadget");
	ui->gadget.dev.parent = &pdev->dev;
	ui->gadget.dev.dma_mask = pdev->dev.dma_mask;

	the_usb_info = ui;

	usb_debugfs_init(ui);

	usb_prepare(ui);

	return 0;
}
コード例 #17
0
ファイル: usb_dev.c プロジェクト: downbeat/senseye
static void usb_setup(void)
{
	const uint8_t *data = NULL;
	uint32_t datalen = 0;
	const usb_descriptor_list_t *list;
	uint32_t size;
	volatile uint8_t *reg;
	uint8_t epconf;
	const uint8_t *cfg;
	int i;

	switch (setup.wRequestAndType) {
	  case 0x0500: // SET_ADDRESS
		break;
	  case 0x0900: // SET_CONFIGURATION
		//serial_print("configure\n");
		usb_configuration = setup.wValue;
		reg = &USB0_ENDPT1;
		cfg = usb_endpoint_config_table;
		// clear all BDT entries, free any allocated memory...
		for (i=4; i < NUM_ENDPOINTS*4; i++) {
			if (table[i].desc & BDT_OWN) {
				usb_free((usb_packet_t *)((uint8_t *)(table[i].addr) - 8));
				table[i].desc = 0;
			}
		}
		usb_rx_memory_needed = 0;
		for (i=1; i < NUM_ENDPOINTS; i++) {
			epconf = *cfg++;
			*reg = epconf;
			reg += 4;
			if (epconf & USB_ENDPT_EPRXEN) {
				usb_packet_t *p;
				p = usb_malloc();
				if (p) {
					table[index(i, RX, EVEN)].addr = p->buf;
					table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
				} else {
					table[index(i, RX, EVEN)].desc = 0;
					usb_rx_memory_needed++;
				}
				p = usb_malloc();
				if (p) {
					table[index(i, RX, ODD)].addr = p->buf;
					table[index(i, RX, ODD)].desc = BDT_DESC(64, 1);
				} else {
					table[index(i, RX, ODD)].desc = 0;
					usb_rx_memory_needed++;
				}
			}
			table[index(i, TX, EVEN)].desc = 0;
			table[index(i, TX, ODD)].desc = 0;
		}
		break;
	  case 0x0880: // GET_CONFIGURATION
		reply_buffer[0] = usb_configuration;
		datalen = 1;
		data = reply_buffer;
		break;
	  case 0x0080: // GET_STATUS (device)
		reply_buffer[0] = 0;
		reply_buffer[1] = 0;
		datalen = 2;
		data = reply_buffer;
		break;
	  case 0x0082: // GET_STATUS (endpoint)
		if (setup.wIndex > NUM_ENDPOINTS) {
			// TODO: do we need to handle IN vs OUT here?
			endpoint0_stall();
			return;
		}
		reply_buffer[0] = 0;
		reply_buffer[1] = 0;
		if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1;
		data = reply_buffer;
		datalen = 2;
		break;
	  case 0x0102: // CLEAR_FEATURE (endpoint)
		i = setup.wIndex & 0x7F;
		if (i > NUM_ENDPOINTS || setup.wValue != 0) {
			// TODO: do we need to handle IN vs OUT here?
			endpoint0_stall();
			return;
		}
		(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02;
		// TODO: do we need to clear the data toggle here?
		break;
	  case 0x0302: // SET_FEATURE (endpoint)
		i = setup.wIndex & 0x7F;
		if (i > NUM_ENDPOINTS || setup.wValue != 0) {
			// TODO: do we need to handle IN vs OUT here?
			endpoint0_stall();
			return;
		}
		(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02;
		// TODO: do we need to clear the data toggle here?
		break;
	  case 0x0680: // GET_DESCRIPTOR
	  case 0x0681:
		//serial_print("desc:");
		//serial_phex16(setup.wValue);
		//serial_print("\n");
		for (list = usb_descriptor_list; 1; list++) {
			if (list->addr == NULL) break;
			//if (setup.wValue == list->wValue && 
			//(setup.wIndex == list->wIndex) || ((setup.wValue >> 8) == 3)) {
			if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) {
				data = list->addr;
				datalen = list->length;
#if 0
				serial_print("Desc found, ");
				serial_phex32((uint32_t)data);
				serial_print(",");
				serial_phex16(datalen);
				serial_print(",");
				serial_phex(data[0]);
				serial_phex(data[1]);
				serial_phex(data[2]);
				serial_phex(data[3]);
				serial_phex(data[4]);
				serial_phex(data[5]);
				serial_print("\n");
#endif
				goto send;
			}
		}
		//serial_print("desc: not found\n");
		endpoint0_stall();
		return;
#if defined(CDC_STATUS_INTERFACE)
	  case 0x2221: // CDC_SET_CONTROL_LINE_STATE
		usb_cdc_line_rtsdtr = setup.wValue;
		//serial_print("set control line state\n");
		break;
	  case 0x2021: // CDC_SET_LINE_CODING
		//serial_print("set coding, waiting...\n");
		return;
#endif

// TODO: this does not work... why?
#if defined(SEREMU_INTERFACE) || defined(KEYBOARD_INTERFACE)
	  case 0x0921: // HID SET_REPORT
		//serial_print(":)\n");
		return;
	  case 0x0A21: // HID SET_IDLE
		break;
	  // case 0xC940:
#endif
	  default:
		endpoint0_stall();
		return;
	}
	send:
	//serial_print("setup send ");
	//serial_phex32(data);
	//serial_print(",");
	//serial_phex16(datalen);
	//serial_print("\n");

	if (datalen > setup.wLength) datalen = setup.wLength;
	size = datalen;
	if (size > EP0_SIZE) size = EP0_SIZE;
	endpoint0_transmit(data, size);
	data += size;
	datalen -= size;
	if (datalen == 0 && size < EP0_SIZE) return;

	size = datalen;
	if (size > EP0_SIZE) size = EP0_SIZE;
	endpoint0_transmit(data, size);
	data += size;
	datalen -= size;
	if (datalen == 0 && size < EP0_SIZE) return;

	ep0_tx_ptr = data;
	ep0_tx_len = datalen;
}
コード例 #18
0
ファイル: usb_dev.c プロジェクト: downbeat/senseye
void usb_isr(void)
{
	uint8_t status, stat, t;

	//serial_print("isr");
	//status = USB0_ISTAT;
	//serial_phex(status);
	//serial_print("\n");
	restart:
	status = USB0_ISTAT;

	if ((status & USB_INTEN_SOFTOKEN /* 04 */ )) {
		if (usb_configuration) {
			t = usb_reboot_timer;
			if (t) {
				usb_reboot_timer = --t;
				if (!t) _reboot_Teensyduino_();
			}
#ifdef CDC_DATA_INTERFACE
			t = usb_cdc_transmit_flush_timer;
			if (t) {
				usb_cdc_transmit_flush_timer = --t;
				if (t == 0) usb_serial_flush_callback();
			}
#endif
#if SEREMU_INTERFACE
			t = usb_seremu_transmit_flush_timer;
			if (t) {
				usb_seremu_transmit_flush_timer = --t;
				if (t == 0) usb_seremu_flush_callback();
			}
#endif
		}
		USB0_ISTAT = USB_INTEN_SOFTOKEN;
	}

	if ((status & USB_ISTAT_TOKDNE /* 08 */ )) {
		uint8_t endpoint;
		stat = USB0_STAT;
		//serial_print("token: ep=");
		//serial_phex(stat >> 4);
		//serial_print(stat & 0x08 ? ",tx" : ",rx");
		//serial_print(stat & 0x04 ? ",odd\n" : ",even\n");
		endpoint = stat >> 4;
		if (endpoint == 0) {
			usb_control(stat);
		} else {
			bdt_t *b = stat2bufferdescriptor(stat);
			usb_packet_t *packet = (usb_packet_t *)((uint8_t *)(b->addr) - 8);
#if 0
			serial_print("ep:");
			serial_phex(endpoint);
			serial_print(", pid:");
			serial_phex(BDT_PID(b->desc));
			serial_print(((uint32_t)b & 8) ? ", odd" : ", even");
			serial_print(", count:");
			serial_phex(b->desc >> 16);
			serial_print("\n");
#endif
			endpoint--;	// endpoint is index to zero-based arrays

			if (stat & 0x08) { // transmit
				usb_free(packet);
				packet = tx_first[endpoint];
				if (packet) {
					//serial_print("tx packet\n");
					tx_first[endpoint] = packet->next;
					b->addr = packet->buf;
					switch (tx_state[endpoint]) {
					  case TX_STATE_BOTH_FREE_EVEN_FIRST:
						tx_state[endpoint] = TX_STATE_ODD_FREE;
						break;
					  case TX_STATE_BOTH_FREE_ODD_FIRST:
						tx_state[endpoint] = TX_STATE_EVEN_FREE;
						break;
					  case TX_STATE_EVEN_FREE:
					  case TX_STATE_ODD_FREE:
					  default:
						tx_state[endpoint] = TX_STATE_NONE_FREE;
						break;
					}
					b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0);
				} else {
					//serial_print("tx no packet\n");
					switch (tx_state[endpoint]) {
					  case TX_STATE_BOTH_FREE_EVEN_FIRST:
					  case TX_STATE_BOTH_FREE_ODD_FIRST:
						break;
					  case TX_STATE_EVEN_FREE:
						tx_state[endpoint] = TX_STATE_BOTH_FREE_EVEN_FIRST;
						break;
					  case TX_STATE_ODD_FREE:
						tx_state[endpoint] = TX_STATE_BOTH_FREE_ODD_FIRST;
						break;
					  default:
						tx_state[endpoint] = ((uint32_t)b & 8) ?
						  TX_STATE_ODD_FREE : TX_STATE_EVEN_FREE;
						break;
					}
				}
			} else { // receive
				packet->len = b->desc >> 16;
				packet->index = 0;
				packet->next = NULL;
				if (rx_first[endpoint] == NULL) {
					//serial_print("rx 1st, epidx=");
					//serial_phex(endpoint);
					//serial_print(", packet=");
					//serial_phex32((uint32_t)packet);
					//serial_print("\n");
					rx_first[endpoint] = packet;
				} else {
					//serial_print("rx Nth, epidx=");
					//serial_phex(endpoint);
					//serial_print(", packet=");
					//serial_phex32((uint32_t)packet);
					//serial_print("\n");
					rx_last[endpoint]->next = packet;
				}
				rx_last[endpoint] = packet;
				// TODO: implement a per-endpoint maximum # of allocated packets
				// so a flood of incoming data on 1 endpoint doesn't starve
				// the others if the user isn't reading it regularly
				packet = usb_malloc();
				if (packet) {
					b->addr = packet->buf;
					b->desc = BDT_DESC(64, ((uint32_t)b & 8) ? DATA1 : DATA0);
				} else {
					//serial_print("starving ");
					//serial_phex(endpoint + 1);
					//serial_print(((uint32_t)b & 8) ? ",odd\n" : ",even\n");
					b->desc = 0;
					usb_rx_memory_needed++;
				}
			}




		}
		USB0_ISTAT = USB_ISTAT_TOKDNE;
		goto restart;
	}
コード例 #19
0
static int msm72k_probe(struct platform_device *pdev)
{
	struct usb_info *ui;
	struct msm_hsusb_gadget_platform_data *pdata;
	struct msm_otg *otg;
	int retval;

	INFO("msm72k_probe\n");
	ui = kzalloc(sizeof(struct usb_info), GFP_KERNEL);
	if (!ui)
		return -ENOMEM;

	ui->pdev = pdev;

	if (pdev->dev.platform_data) {
		pdata = pdev->dev.platform_data;
		ui->phy_reset = pdata->phy_reset;
		ui->phy_init_seq = pdata->phy_init_seq;
		ui->chg_init = pdata->chg_init;
		ui->chg_connected = pdata->chg_connected;
		ui->chg_vbus_draw = pdata->chg_vbus_draw;
		ui->usb_connected = pdata->usb_connected;
	}

	if (ui->chg_init)
		ui->chg_init(1);

	ui->buf = dma_alloc_coherent(&pdev->dev, 4096, &ui->dma, GFP_KERNEL);
	if (!ui->buf)
		return usb_free(ui, -ENOMEM);

	ui->pool = dma_pool_create("msm72k_udc", NULL, 32, 32, 0);
	if (!ui->pool)
		return usb_free(ui, -ENOMEM);


	/* FIXME: dmb cannot be called from interrupt context
	 * for the first time; Need to verify on how it needs
	 * to be fixed
	 */
	dmb();

	ui->xceiv = otg_get_transceiver();
	if (!ui->xceiv)
		return usb_free(ui, -ENODEV);

	otg = to_msm_otg(ui->xceiv);
	ui->addr = otg->regs;

	ui->gadget.ops = &msm72k_ops;
	ui->gadget.is_dualspeed = 1;
	device_initialize(&ui->gadget.dev);
	strcpy(ui->gadget.dev.bus_id, "gadget");
	ui->gadget.dev.parent = &pdev->dev;
	ui->gadget.dev.dma_mask = pdev->dev.dma_mask;

	the_usb_info = ui;

	pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, DRIVER_NAME,
					PM_QOS_DEFAULT_VALUE);
	pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ, DRIVER_NAME,
					PM_QOS_DEFAULT_VALUE);
	usb_debugfs_init(ui);

	usb_prepare(ui);

	retval = otg_set_peripheral(ui->xceiv, &ui->gadget);
	if (retval) {
		pr_err("%s: Cannot bind the transceiver, retval:(%d)\n",
				__func__, retval);
		return usb_free(ui, retval);
	}

	return 0;
}