Beispiel #1
0
/** ISR to handle the reloading of the data endpoint with the next sample. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
{
	uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();

	/* Check if the sample reload timer period has elapsed, and that the USB bus is ready for a new sample */
	if (Audio_Device_IsReadyForNextSample(&Microphone_Audio_Interface))
	{
		int16_t AudioSample;

		#if defined(USE_TEST_TONE)
			static uint8_t SquareWaveSampleCount;
			static int16_t CurrentWaveValue;
			
			/* In test tone mode, generate a square wave at 1/256 of the sample rate */
			if (SquareWaveSampleCount++ == 0xFF)
			  CurrentWaveValue ^= 0x8000;
			
			/* Only generate audio if the board button is being pressed */
			AudioSample = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? CurrentWaveValue : 0;
		#else
			/* Audio sample is ADC value scaled to fit the entire range */
			AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());

			#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)
			/* Microphone is biased to half rail voltage, subtract the bias from the sample value */
			AudioSample -= (SAMPLE_MAX_RANGE / 2);
			#endif
		#endif
		
		Audio_Device_WriteSample16(&Microphone_Audio_Interface, AudioSample);
	}

	Endpoint_SelectEndpoint(PrevEndpoint);
}
Beispiel #2
0
void sendControlMessage(uint8_t* data, uint8_t length) {
    uint8_t previousEndpoint = Endpoint_GetCurrentEndpoint();
    Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

    Endpoint_ClearSETUP();
    Endpoint_Write_Control_Stream_LE(data, length);
    Endpoint_ClearOUT();

    Endpoint_SelectEndpoint(previousEndpoint);
}
Beispiel #3
0
ISR(USB_COM_vect, ISR_BLOCK)
{
	uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint();

	USB_USBTask();

	USB_INT_Clear(USB_INT_ENDPOINT_SETUP);
	
	Endpoint_SelectEndpoint(PrevSelectedEndpoint);
}
Beispiel #4
0
/*
 * Stall all endpoints and set a flag indicating any current transfers
 * should be aborted. IO loops will see this flag in TimerWorker().
 */
void
SetAbortState()
{
    uint8_t origEndpoint = Endpoint_GetCurrentEndpoint();

    doDeviceReset = true;
    Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT);
    Endpoint_StallTransaction();
    Endpoint_SelectEndpoint(XUM_BULK_IN_ENDPOINT);
    Endpoint_StallTransaction();

    Endpoint_SelectEndpoint(origEndpoint);
}
Beispiel #5
0
ISR(USB_COM_vect, ISR_BLOCK)
{
	uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint();

	USB_INT_Disable(USB_INT_RXSTPI);
	sei();
	USB_USBTask();
	USB_INT_Enable(USB_INT_RXSTPI);

	USB_INT_Clear(USB_INT_RXSTPI);
	
	Endpoint_SelectEndpoint(PrevSelectedEndpoint);
}
Beispiel #6
0
static void USB_DeviceTask(void)
{
	if (USB_DeviceState != DEVICE_STATE_Unattached)
	{
		uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();
	
		Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

		if (Endpoint_IsSETUPReceived())
		  USB_Device_ProcessControlRequest();
		
		Endpoint_SelectEndpoint(PrevEndpoint);
	}
}
ISR(USB_COM_vect, ISR_BLOCK)
{
	uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint();

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
	USB_INT_Disable(USB_INT_RXSTPI);

	GlobalInterruptEnable();

	USB_Device_ProcessControlRequest();

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
	USB_INT_Enable(USB_INT_RXSTPI);
	Endpoint_SelectEndpoint(PrevSelectedEndpoint);
}
Beispiel #8
0
ISR(USB_COM_vect, ISR_BLOCK)
{
	uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); 

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
	USB_INT_Disable(USB_INT_RXSTPI);

	NONATOMIC_BLOCK(NONATOMIC_FORCEOFF)
	{
		USB_Device_ProcessControlRequest();
	}

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
	USB_INT_Enable(USB_INT_RXSTPI);
	Endpoint_SelectEndpoint(PrevSelectedEndpoint);
}
Beispiel #9
0
void readFromHost(UsbDevice* usbDevice, bool (*callback)(uint8_t*)) {
    uint8_t previousEndpoint = Endpoint_GetCurrentEndpoint();
    Endpoint_SelectEndpoint(OUT_ENDPOINT_NUMBER);

    while(Endpoint_IsOUTReceived()) {
        for(int i = 0; i < usbDevice->outEndpointSize; i++) {
            if(!QUEUE_PUSH(uint8_t, &usbDevice->receiveQueue,
                        Endpoint_Read_8())) {
                debug("Dropped write from host -- queue is full");
            }
        }
        processQueue(&usbDevice->receiveQueue, callback);
        Endpoint_ClearOUT();
    }
    Endpoint_SelectEndpoint(previousEndpoint);
}
Beispiel #10
0
/*
 * The Linux and OSX call the configuration changed entry each time
 * a transaction is started (e.g., multiple runs of cbmctrl status).
 * We need to reset the endpoints before reconfiguring them, otherwise
 * we get a hang the second time through.
 *
 * We keep the original endpoint selected after returning.
 */
void
USB_ResetConfig()
{
    static uint8_t endpoints[] = {
        XUM_BULK_IN_ENDPOINT, XUM_BULK_OUT_ENDPOINT, 0,
    };
    uint8_t lastEndpoint, *endp;

    lastEndpoint = Endpoint_GetCurrentEndpoint();

    for (endp = endpoints; *endp != 0; endp++) {
        Endpoint_SelectEndpoint(*endp);
        Endpoint_ResetFIFO(*endp);
        Endpoint_ResetDataToggle();
        if (Endpoint_IsStalled())
            Endpoint_ClearStall();
    }

    Endpoint_SelectEndpoint(lastEndpoint);
}
void USBSerial::flush()
{
	uint8_t prevEndpoint = Endpoint_GetCurrentEndpoint();
	
	Endpoint_SelectEndpoint(CDC_TX_EPADDR);
	bool IsFull = !Endpoint_IsReadWriteAllowed();
	Endpoint_ClearIN();
	
	/* Send an empty packet to ensure that the host does not buffer data sent to it */
	if (IsFull) {
		while (!Endpoint_IsINReady() && USB_DeviceState == DEVICE_STATE_Configured) {
			USB_USBTask();
		}
		Endpoint_ClearIN();
	}
	//Endpoint_WaitUntilReady();
	while (!Endpoint_IsINReady() && USB_DeviceState == DEVICE_STATE_Configured) {
		USB_USBTask();
	}
	
	Endpoint_SelectEndpoint(prevEndpoint);
}
Beispiel #12
0
/* Private: Flush any queued data out to the USB host. */
static void sendToHost(UsbDevice* usbDevice) {
    if(!usbDevice->configured) {
        return;
    }

    uint8_t previousEndpoint = Endpoint_GetCurrentEndpoint();
    Endpoint_SelectEndpoint(IN_ENDPOINT_NUMBER);
    if(!Endpoint_IsINReady() || QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue)) {
        return;
    }

    // get bytes from transmit FIFO into intermediate buffer
    int byteCount = 0;
    while(!QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue)
            && byteCount < USB_SEND_BUFFER_SIZE) {
        usbDevice->sendBuffer[byteCount++] = QUEUE_POP(uint8_t, &usbDevice->sendQueue);
    }

    if(byteCount > 0) {
        Endpoint_Write_Stream_LE(usbDevice->sendBuffer, byteCount, NULL);
    }
    Endpoint_ClearIN();
    Endpoint_SelectEndpoint(previousEndpoint);
}
Beispiel #13
0
static bool
USB_BulkWorker()
{
    uint8_t cmdBuf[XUM_CMDBUF_SIZE], statusBuf[XUM_STATUSBUF_SIZE];
    int8_t status;

    /*
     * If we are not connected to the host or a command has not yet
     * been sent, no more processing is required.
     */
    if (USB_DeviceState != DEVICE_STATE_Configured)
        return false;
    Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT);
    if (!Endpoint_IsReadWriteAllowed())
        return false;

#ifdef DEBUG
    // Dump the status of both endpoints before getting the command
    Endpoint_SelectEndpoint(XUM_BULK_IN_ENDPOINT);
    DEBUGF(DBG_INFO, "bsti %x %x %x %x %x %x %x %x\n",
        Endpoint_GetCurrentEndpoint(),
        Endpoint_BytesInEndpoint(), Endpoint_IsEnabled(),
        Endpoint_IsReadWriteAllowed(), Endpoint_IsConfigured(),
        Endpoint_IsINReady(), Endpoint_IsOUTReceived(), Endpoint_IsStalled());
    Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT);
    DEBUGF(DBG_INFO, "bsto %x %x %x %x %x %x %x %x\n",
        Endpoint_GetCurrentEndpoint(),
        Endpoint_BytesInEndpoint(), Endpoint_IsEnabled(),
        Endpoint_IsReadWriteAllowed(), Endpoint_IsConfigured(),
        Endpoint_IsINReady(), Endpoint_IsOUTReceived(), Endpoint_IsStalled());
#endif

    // Read in the command from the host now that one is ready.
    if (!USB_ReadBlock(cmdBuf, sizeof(cmdBuf))) {
        board_set_status(STATUS_ERROR);
        return false;
    }

    // Allow commands to leave the extended status untouched
    memset(statusBuf, 0, sizeof(statusBuf));

    /*
     * Decode and process the command.
     * usbHandleBulk() stores its extended result in the output buffer,
     * up to XUM_STATUSBUF_SIZE.
     *
     * Return values:
     *   >0: completed ok, send the return value and extended status
     *    0: completed ok, don't send any status
     *   -1: error, no status
     */
    status = usbHandleBulk(cmdBuf, statusBuf);
    if (status > 0) {
        statusBuf[0] = status;
        USB_WriteBlock(statusBuf, sizeof(statusBuf));
    } else if (status < 0) {
        DEBUGF(DBG_ERROR, "usbblk err\n");
        board_set_status(STATUS_ERROR);
        Endpoint_StallTransaction();
        return false;
    }

    return true;
}
Beispiel #14
0
/** ISR for the general Pipe/Endpoint interrupt vector. This ISR fires when an endpoint's status changes (such as
 *  a packet has been received) on an endpoint with its corresponding ISR enabling bits set. This is used to send
 *  HID packets to the host each time the HID interrupt endpoints polling period elapses, as managed by the USB
 *  controller.
 */
ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
{
	/* Save previously selected endpoint before selecting a new endpoint */
	uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint();

	#if defined(INTERRUPT_CONTROL_ENDPOINT)
	/* Check if the control endpoint has received a request */
	if (Endpoint_HasEndpointInterrupted(ENDPOINT_CONTROLEP))
	{
		/* Clear the endpoint interrupt */
		Endpoint_ClearEndpointInterrupt(ENDPOINT_CONTROLEP);

		/* Process the control request */
		USB_USBTask();

		/* Handshake the endpoint setup interrupt - must be after the call to USB_USBTask() */
		USB_INT_Clear(ENDPOINT_INT_SETUP);
	}
	#endif

	#if defined(INTERRUPT_DATA_ENDPOINT)
	/* Check if Generic IN endpoint has interrupted */
	if (Endpoint_HasEndpointInterrupted(GENERIC_IN_EPNUM))
	{
		/* Select the Generic IN Report Endpoint */
		Endpoint_SelectEndpoint(GENERIC_IN_EPNUM);

		/* Clear the endpoint IN interrupt flag */
		USB_INT_Clear(ENDPOINT_INT_IN);

		/* Clear the Generic IN Report endpoint interrupt and select the endpoint */
		Endpoint_ClearEndpointInterrupt(GENERIC_IN_EPNUM);

		/* Create a temporary buffer to hold the report to send to the host */
		uint8_t GenericData[GENERIC_REPORT_SIZE];
		
		/* Create Generic Report Data */
		CreateGenericHIDReport(GenericData);

		/* Write Generic Report Data */
		Endpoint_Write_Stream_LE(&GenericData, sizeof(GenericData));

		/* Finalize the stream transfer to send the last packet */
		Endpoint_ClearIN();
	}

	/* Check if Generic OUT endpoint has interrupted */
	if (Endpoint_HasEndpointInterrupted(GENERIC_OUT_EPNUM))
	{
		/* Select the Generic OUT Report Endpoint */
		Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM);

		/* Clear the endpoint OUT Interrupt flag */
		USB_INT_Clear(ENDPOINT_INT_OUT);

		/* Clear the Generic OUT Report endpoint interrupt and select the endpoint */
		Endpoint_ClearEndpointInterrupt(GENERIC_OUT_EPNUM);

		/* Create a temporary buffer to hold the read in report from the host */
		uint8_t GenericData[GENERIC_REPORT_SIZE];
		
		/* Read Generic Report Data */
		Endpoint_Read_Stream_LE(&GenericData, sizeof(GenericData));
		
		/* Process Generic Report Data */
		ProcessGenericHIDReport(GenericData);

		/* Finalize the stream transfer to send the last packet */
		Endpoint_ClearOUT();
	}
	#endif

	/* Restore previously selected endpoint */
	Endpoint_SelectEndpoint(PrevSelectedEndpoint);
}