Пример #1
0
static void PIOS_USB_HID_SendReport(struct pios_usb_hid_dev * usb_hid_dev)
{
	uint16_t bytes_to_tx;

	if (!usb_hid_dev->tx_out_cb) {
		return;
	}

	bool need_yield = false;
#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
	bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
					       &usb_hid_dev->tx_packet_buffer[1],
					       sizeof(usb_hid_dev->tx_packet_buffer)-1,
					       NULL,
					       &need_yield);
#else
	bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context,
					       &usb_hid_dev->tx_packet_buffer[2],
					       sizeof(usb_hid_dev->tx_packet_buffer)-2,
					       NULL,
					       &need_yield);
#endif
	if (bytes_to_tx == 0) {
		return;
	}

	/* Always set type as report ID */
	usb_hid_dev->tx_packet_buffer[0] = 1;

#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
	UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer,
			GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep),
			bytes_to_tx + 1);
#else
	usb_hid_dev->tx_packet_buffer[1] = bytes_to_tx;
	UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer,
			GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep),
			bytes_to_tx + 2);
#endif
	/* Is this correct?  Why do we always send the whole buffer? */
	SetEPTxCount(usb_hid_dev->cfg->data_tx_ep, sizeof(usb_hid_dev->tx_packet_buffer));
	SetEPTxValid(usb_hid_dev->cfg->data_tx_ep);

#if defined(PIOS_INCLUDE_FREERTOS)
	if (need_yield) {
		vPortYieldFromISR();
	}
#endif	/* PIOS_INCLUDE_FREERTOS */
}
Пример #2
0
/**
 * RxThread
 */
void PIOS_UDP_RxThread(void * udp_dev_n)
{

	/* needed because of FreeRTOS.posix scheduling */
	sigset_t set;
	sigfillset(&set);
	sigprocmask(SIG_BLOCK, &set, NULL);

	pios_udp_dev * udp_dev = (pios_udp_dev*) udp_dev_n;

   /**
	* com devices never get closed except by application "reboot"
	* we also never give up our mutex except for waiting
	*/
   while(1) {

		/**
		 * receive 
		 */
		int received;
		udp_dev->clientLength=sizeof(udp_dev->client);
		if ((received = recvfrom(udp_dev->socket,
				&udp_dev->rx_buffer,
				PIOS_UDP_RX_BUFFER_SIZE,
				0,
				(struct sockaddr *) &udp_dev->client,
				(socklen_t*)&udp_dev->clientLength)) >= 0)
		{

			/* copy received data to buffer if possible */
			/* we do NOT buffer data locally. If the com buffer can't receive, data is discarded! */
			/* (thats what the USART driver does too!) */
			bool rx_need_yield = false;
			if (udp_dev->rx_in_cb) {
			  (void) (udp_dev->rx_in_cb)(udp_dev->rx_in_context, udp_dev->rx_buffer, received, NULL, &rx_need_yield);
			}

#if defined(PIOS_INCLUDE_FREERTOS)
			if (rx_need_yield) {
				vPortYieldFromISR();
			}
#endif	/* PIOS_INCLUDE_FREERTOS */

		}


	}
}
Пример #3
0
static void PIOS_USART_generic_irq_handler(uint32_t usart_id)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid);
	
	/* Force read of dr after sr to make sure to clear error flags */
	volatile uint16_t sr = usart_dev->cfg->regs->SR;
	volatile uint8_t dr = usart_dev->cfg->regs->DR;
	
	/* Check if RXNE flag is set */
	bool rx_need_yield = false;
	if (sr & USART_SR_RXNE) {
		uint8_t byte = dr;
		if (usart_dev->rx_in_cb) {
			(void) (usart_dev->rx_in_cb)(usart_dev->rx_in_context, &byte, 1, NULL, &rx_need_yield);
		}
	}
	
	/* Check if TXE flag is set */
	bool tx_need_yield = false;
	if (sr & USART_SR_TXE) {
		if (usart_dev->tx_out_cb) {
			uint8_t b;
			uint16_t bytes_to_send;
			
			bytes_to_send = (usart_dev->tx_out_cb)(usart_dev->tx_out_context, &b, 1, NULL, &tx_need_yield);
			
			if (bytes_to_send > 0) {
				/* Send the byte we've been given */
				usart_dev->cfg->regs->DR = b;
			} else {
				/* No bytes to send, disable TXE interrupt */
				USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
			}
		} else {
			/* No bytes to send, disable TXE interrupt */
			USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, DISABLE);
		}
	}
	
#if defined(PIOS_INCLUDE_FREERTOS)
	if (rx_need_yield || tx_need_yield) {
		vPortYieldFromISR();
	}
#endif	/* PIOS_INCLUDE_FREERTOS */
}
Пример #4
0
void ADCIntHandler(){

	ADCIntClear(ADC0_BASE, 0); // Limpia el flag de interrupcion del ADC
	uint32_t potenciometros[3];
	BaseType_t xHigherPriorityTaskWoken;
	xHigherPriorityTaskWoken = pdFALSE;
	// leemos los datos del secuenciador
	 ADCSequenceDataGet(ADC0_BASE, 0, potenciometros);

	 //Enviamos el dato a la tarea
	 xQueueSendFromISR( potQueue,potenciometros,&xHigherPriorityTaskWoken);
	 if(xHigherPriorityTaskWoken == pdTRUE){
		 vPortYieldFromISR();
	 }

}
static osa_status_t OSA_MessageQueuePutFromISR(msg_queue_handler_t handler, void* pMessage)
{
    portBASE_TYPE taskToWake = pdFALSE;

    if (pdTRUE == xQueueSendToBackFromISR(handler, pMessage, &taskToWake))
    {
        if (pdTRUE == taskToWake)
        {
            vPortYieldFromISR();
        }
        return kStatus_OSA_Success;
    }
    else
    {
        return kStatus_OSA_Error;
    }
}
static osa_status_t OSA_SemaphorePostFromISR(semaphore_t *pSem)
{
    portBASE_TYPE taskToWake = pdFALSE;

    if (pdTRUE==xSemaphoreGiveFromISR(*pSem, &taskToWake))
    {
        if (pdTRUE == taskToWake)
        {
            vPortYieldFromISR();
        }
        return kStatus_OSA_Success;
    }
    else
    {
        return kStatus_OSA_Error;
    }
}
Пример #7
0
static Void callback_ToHost(VirtQueue_Handle vq)
{
	UInt16 avail;
	int    i;
	Bool   doSwitch[portNUM_PROCESSORS];
	unsigned portBASE_TYPE curCpu =  portGetCurrentCPU();
	
	taskENTER_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock);

	if(listLIST_IS_EMPTY(&availBufList) != pdFALSE){
		taskEXIT_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock);
		return;
	}

	if((avail = GET_AVAIL_COUNT(vq)) == 0){
		taskEXIT_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock);
		return;
	}

	memset(doSwitch, FALSE, sizeof(doSwitch));

	do{
		signed portBASE_TYPE ret;

		/* Because this function is not an application code,             */
		/* there is not the problem with using xTaskRemoveFromEventList. */
		ret = xTaskRemoveFromEventList(&availBufList, pdFALSE);
		if(ret >= 0){
			doSwitch[ret] = TRUE;
		}			
	}
	while(--avail > 0);

	taskEXIT_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock);

	for(i = 0; i < portNUM_PROCESSORS; i++){
		if(doSwitch[i]){
			if(i == (int)curCpu){
				vPortYieldFromISR();
			}
			else{
				portINTERRUPT_CORE(i);
			}
		}
	}
}
Пример #8
0
static Void callback_FromHost(VirtQueue_Handle vq)
{
    Int16            token;
    MessageQCopy_Msg msg;
    Bool             usedBufAdded = FALSE;
    Int              len;
	portBASE_TYPE    switchCpu;
	Bool             doSwitch[portNUM_PROCESSORS];
	int              i;

	memset(doSwitch, FALSE, sizeof(doSwitch));

	taskENTER_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock);

	/* Process all available buffers: */
	while((token = VirtQueue_getAvailBuf(vq, (Void **)&msg, &len)) >= 0){
		if(!MessageQCopy_SendToTask(token, msg, &switchCpu)){
			VirtQueue_addUsedBuf(vq, token, RP_MSG_BUF_SIZE);
			usedBufAdded = TRUE;
		}
		else if(switchCpu >= 0){
			doSwitch[switchCpu] = TRUE;
		}
	}

	if(usedBufAdded){
		/* Tell host we've processed the buffers: */
		VirtQueue_kick(vq);
	}

	taskEXIT_CRITICAL_NOT_RECURSIVE_FROM_ISR(&virtQueLock);

	for(i = 0; i < portNUM_PROCESSORS; i++){
		unsigned portBASE_TYPE curCpu = portGetCurrentCPU();

		if(doSwitch[i]){
			if(i == (Int)curCpu){
				vPortYieldFromISR();
			}
			else{
				portINTERRUPT_CORE(i);
			}
		}
	}
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_EventSet
 * Description   : Set one or more event flags of an event object.
 * Return kStatus_OSA_Success if set successfully, kStatus_OSA_Error if failed.
 *
 *END**************************************************************************/
osa_status_t OSA_EventSet(event_t *pEvent, event_flags_t flagsToSet)
{
    assert(pEvent);
    portBASE_TYPE taskToWake = pdFALSE;

    if (__get_IPSR())
    {
        xEventGroupSetBitsFromISR(pEvent->eventHandler, flagsToSet, &taskToWake);
        if (pdTRUE == taskToWake)
        {
            vPortYieldFromISR();
        }
    }
    else
    {
        xEventGroupSetBits(pEvent->eventHandler, flagsToSet);
    }
    return kStatus_OSA_Success;
}
Пример #10
0
void EXTI0_IRQHandler(void)
{
	long taskWoken = 0;
	if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
		bool isRisingEdge = digitalRead(GPIO_PA0);
		//digitalWrite(GPIO_PD11, isRisingEdge);

		if (isRisingEdge) {
			lastMicros = micros();
		} else {
			ultrasound_duration =  micros() - lastMicros;

			if (ultrasound_duration > MAX_ULTRASOUND_DURATION_US)
				ultrasound_duration = MAX_ULTRASOUND_DURATION_US;
			xSemaphoreGiveFromISR(sensorReadSignal, &taskWoken);
		}

		EXTI_ClearITPendingBit(EXTI_Line0);
	}
	if (taskWoken)
		vPortYieldFromISR();
}
Пример #11
0
/**
 * Take data from the PIOS_COM buffer and transfer it to the currently inactive DMA
 * circular buffer
 */
static void PIOS_OVERO_WriteData(struct pios_overo_dev *overo_dev)
{
    // TODO: How do we protect against the DMA buffer swapping midway through adding data
    // to this buffer.  If we were writing at the beginning it could cause a weird race.
    if (overo_dev->tx_out_cb) {
        int32_t max_bytes = PACKET_SIZE - overo_dev->writing_offset;

        if (max_bytes > 0) {
            uint16_t bytes_added;
            bool tx_need_yield = false;
            uint8_t *writing_pointer = &overo_dev->tx_buffer[overo_dev->writing_buffer][overo_dev->writing_offset];

            bytes_added = (overo_dev->tx_out_cb)(overo_dev->tx_out_context, writing_pointer, max_bytes, NULL, &tx_need_yield);

#if defined(OVERO_USES_BLOCKING_WRITE)
            if (tx_need_yield) {
                vPortYieldFromISR();
            }
#endif
            overo_dev->writing_offset += bytes_added;
        }
    }
}
Пример #12
0
void EINT3_IRQHandler(void)
{
	static signed portBASE_TYPE xHigherPriorityTaskWoken;
	xHigherPriorityTaskWoken = pdFALSE;

	if(LPC_GPIOINT->IO0IntStatF & (1<<4))
	{
		contarTicks = 0;
	} else
	if (LPC_GPIOINT->IO0IntStatR & (1<<4)) {
		contarTicks = contarTicks / portTICK_RATE_MS;
		xQueueSendFromISR(cola,  &contarTicks, &xHigherPriorityTaskWoken);
		contarTicks = -1;
	}
	LPC_GPIOINT->IO0IntClr = 1<<4;

	// Si la tarea asociada tiene mayor prioridad que la que
	//se esta ejecutando
   if(xHigherPriorityTaskWoken == pdTRUE)
	   // se realiza un cambio de contexto manualmente
	   //(no se pasa por el scheduler).
	   vPortYieldFromISR ();
}
Пример #13
0
/**
 * EP1 OUT Callback Routine
 */
static void PIOS_USB_HID_EP_OUT_Callback(void)
{
	struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)pios_usb_hid_id;

	bool valid = PIOS_USB_HID_validate(usb_hid_dev);
	PIOS_Assert(valid);

	uint32_t DataLength;

	/* Read received data (63 bytes) */
	/* Get the number of received data on the selected Endpoint */
	DataLength = GetEPRxCount(usb_hid_dev->cfg->data_rx_ep);
	if (DataLength > sizeof(usb_hid_dev->rx_packet_buffer)) {
		DataLength = sizeof(usb_hid_dev->rx_packet_buffer);
	}

	/* Use the memory interface function to read from the selected endpoint */
	PMAToUserBufferCopy((uint8_t *) usb_hid_dev->rx_packet_buffer,
			GetEPRxAddr(usb_hid_dev->cfg->data_rx_ep),
			DataLength);

	if (!usb_hid_dev->rx_in_cb) {
		/* No Rx call back registered, disable the receiver */
		SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK);
		return;
	}

	/* The first byte is report ID (not checked), the second byte is the valid data length */
	uint16_t headroom;
	bool need_yield = false;
#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
	(usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
				&usb_hid_dev->rx_packet_buffer[1],
				sizeof(usb_hid_dev->rx_packet_buffer)-1,
				&headroom,
				&need_yield);
#else
	(usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
				&usb_hid_dev->rx_packet_buffer[2],
				usb_hid_dev->rx_packet_buffer[1],
				&headroom,
				&need_yield);
#endif

#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
	uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 1;
#else
	uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 2;
#endif

	if (headroom >= max_payload_length) {

		/* We have room for a maximum length message */
		SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_VALID);
	} else {
		/* Not enough room left for a message, apply backpressure */
		SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK);
	}

#if defined(PIOS_INCLUDE_FREERTOS)
	if (need_yield) {
		vPortYieldFromISR();
	}
#endif	/* PIOS_INCLUDE_FREERTOS */
}
Пример #14
0
/**
 * EP1 OUT Callback Routine
 */
static bool PIOS_USB_HID_EP_OUT_Callback(uint32_t usb_hid_id, uint8_t epnum, uint16_t len)
{
	struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usb_hid_id;

	if (!PIOS_USB_HID_validate(usb_hid_dev)) {
		return false;
	}

	if (len > sizeof(usb_hid_dev->rx_packet_buffer)) {
		len = sizeof(usb_hid_dev->rx_packet_buffer);
	}

	if (!usb_hid_dev->rx_in_cb) {
		/* No Rx call back registered, disable the receiver */
		usb_hid_dev->rx_active = false;
		return false;
	}

	/* The first byte is report ID (not checked), the second byte is the valid data length */
	uint16_t headroom;
	bool need_yield = false;
#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
	(usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
				&usb_hid_dev->rx_packet_buffer[1],
				len-1,
				&headroom,
				&need_yield);
#else
	(usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context,
				&usb_hid_dev->rx_packet_buffer[2],
				usb_hid_dev->rx_packet_buffer[1],
				&headroom,
				&need_yield);
#endif

#ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE
	uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 1;
#else
	uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 2;
#endif

	bool rc;
	if (headroom >= max_payload_length) {
		/* We have room for a maximum length message */
		PIOS_USBHOOK_EndpointRx(usb_hid_dev->cfg->data_rx_ep,
					usb_hid_dev->rx_packet_buffer,
					sizeof(usb_hid_dev->rx_packet_buffer));
		rc = true;
	} else {
		/* Not enough room left for a message, apply backpressure */
		usb_hid_dev->rx_active = false;
		rc = false;
	}

#if defined(PIOS_INCLUDE_FREERTOS)
	if (need_yield) {
		vPortYieldFromISR();
	}
#endif	/* PIOS_INCLUDE_FREERTOS */

	return rc;
}
Пример #15
0
void Task::yieldFromISR()
{
	vPortYieldFromISR();
}