Exemplo n.º 1
0
static void vSerialISR( XUartLite *pxUART )
{
unsigned portLONG ulISRStatus;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, lDidSomething;
portCHAR cChar;

	/* Just to remove compiler warning. */
	( void ) pxUART;

	do
	{
		lDidSomething = pdFALSE;

		ulISRStatus = XIo_In32( XPAR_RS232_UART_BASEADDR + XUL_STATUS_REG_OFFSET );

		if( ( ulISRStatus & XUL_SR_RX_FIFO_VALID_DATA ) != 0 )
		{
			/* A character is available - place it in the queue of received
			characters.  This might wake a task that was blocked waiting for 
			data. */
			cChar = ( portCHAR ) XIo_In32( XPAR_RS232_UART_BASEADDR + XUL_RX_FIFO_OFFSET );
			xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
			lDidSomething = pdTRUE;
		}
		
		if( ( ulISRStatus & XUL_SR_TX_FIFO_EMPTY ) != 0 )
		{
			/* There is space in the FIFO - if there are any characters queue for
			transmission they can be sent to the UART now.  This might unblock a
			task that was waiting for space to become available on the Tx queue. */
			if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
			{
				XIo_Out32( XPAR_RS232_UART_BASEADDR + XUL_TX_FIFO_OFFSET, cChar );
				lDidSomething = pdTRUE;
			}			
		}
	} while( lDidSomething == pdTRUE );

	/* If we woke any tasks we may require a context switch. */
	if( xHigherPriorityTaskWoken )
	{
		portYIELD_FROM_ISR();
	}
}
Exemplo n.º 2
0
static void prvTimerHandler( void *pvCallBackRef )
{
uint32_t ulInterruptStatus;
XTtcPs *pxTimer = ( XTtcPs * ) pvCallBackRef;
BaseType_t xYieldRequired;

	/* Read the interrupt status, then write it back to clear the interrupt. */
	ulInterruptStatus = XTtcPs_GetInterruptStatus( pxTimer );
	XTtcPs_ClearInterruptStatus( pxTimer, ulInterruptStatus );

	/* Only one interrupt event type is expected. */
	configASSERT( ( XTTCPS_IXR_INTERVAL_MASK & ulInterruptStatus ) != 0 );

	/* Check the device ID to know which IntQueue demo to call. */
	if( pxTimer->Config.DeviceId == xDeviceIDs[ 0 ] )
	{
		xYieldRequired = xFirstTimerHandler();
	}
	else if( pxTimer->Config.DeviceId == xDeviceIDs[ 1 ] )
	{
		xYieldRequired = xSecondTimerHandler();
	}
	else
	{
		/* Used to check the timer is running at the expected frequency. */
		ulHighFrequencyTimerCounts++;

		/* Latch the highest interrupt nesting count detected. */
		if( ulPortInterruptNesting > ulMaxRecordedNesting )
		{
			ulMaxRecordedNesting = ulPortInterruptNesting;
		}

		xYieldRequired = pdFALSE;
	}

	/* If xYieldRequired is not pdFALSE then calling either xFirstTimerHandler()
	or xSecondTimerHandler() resulted in a task leaving the blocked state and
	the task that left the blocked state had a priority higher than the currently
	running task (the task this interrupt interrupted) - so a context switch
	should be performed so the interrupt returns directly to the higher priority
	task.  xYieldRequired is tested inside the following macro. */
	portYIELD_FROM_ISR( xYieldRequired );
}
Exemplo n.º 3
0
__interrupt void vSCIInterruptHandler( void )
{
/* xHigherPriorityTaskWoken must be initialised to pdFALSE. */
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
char cChar;
portBASE_TYPE xVectorValue = serialSCI_INTVEC0_REG;

	switch( xVectorValue )
	{
		case 11:
			/* Receive buffer full interrupt, send received char to queue */
			cChar = serialSCI_RD_REG;
			xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
			break;

		case 12:
			/* Transmit buffer empty interrupt received */
			/* Are there any more characters to transmit? */
			if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
			{
				/* A character was retrieved from the queue so can be sent to
				the TD now. */
				serialSCI_TD_REG = cChar;
			}
			else
			{
				/* no more bytes, clear the TX interrupt */
				serialSCI_CLRINT_REG = serialSCI_TX_INT;
			}
			break;

		default:
			/* unused interrupt, clear flags */
			serialSCI_FLR_REG = 0x07000003;
	}

	/* If calling xQueueSendFromISR() above caused a task to leave the blocked
	state, and the task that left the blocked state has a priority above the
	task that this interrupt interrupted, then xHighPriorityTaskWoken will have
	been set to pdTRUE.  If xHigherPriorityTaskWoken equals true then calling
	portYIELD_FROM_ISR() will result in this interrupt returning directly to the
	unblocked task. */
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Exemplo n.º 4
0
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_SemaphorePost
 * Description   : This function is used to wake up one task that wating on the
 * semaphore. If no task is waiting, increase the semaphore. The function returns
 * osaStatus_Success if the semaphre is post successfully, otherwise returns
 * osaStatus_Error.
 *
 *END**************************************************************************/
osaStatus_t OSA_SemaphorePost(osaSemaphoreId_t semId)
{
#if osNumberOfSemaphores
  osaStatus_t status = osaStatus_Error;
  if(semId)
  {
    semaphore_t sem = (semaphore_t)semId;
    
    if (__get_IPSR())
    {
      portBASE_TYPE taskToWake = pdFALSE;
      
      if (pdTRUE==xSemaphoreGiveFromISR(sem, &taskToWake))
      {
        if (pdTRUE == taskToWake)
        {
          portYIELD_FROM_ISR(taskToWake);
        }
        status = osaStatus_Success;
      }
      else
      {
        status = osaStatus_Error;
      }
    }
    else
    {
      if (pdTRUE == xSemaphoreGive(sem))
      {
        status = osaStatus_Success; /* sync object given */
      }
      else
      {
        status = osaStatus_Error;
      }
    }    
  }
  return status;
#else
  (void)semId;
  return osaStatus_Error;
#endif  
}
Exemplo n.º 5
0
/**
* @brief  Resume execution of a suspended thread.
* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
* @retval  status code that indicates the execution status of the function.
*/
osStatus osThreadResume (osThreadId thread_id)
{
#if (INCLUDE_vTaskSuspend == 1)  
  if(inHandlerMode())
  {
    if (xTaskResumeFromISR(thread_id) == pdTRUE)
    {
      portYIELD_FROM_ISR(pdTRUE);
    }
  }
  else
  {
    vTaskResume(thread_id);
  }
  return osOK;
#else
  return osErrorResource;
#endif
}
/***********************************************************************************************************************
* Function Name: r_sci1_callback_transmitend
* Description  : This function is a callback function when SCI1 finishes transmission.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void r_sci1_callback_transmitend(void)
{
    /* Start user code. Do not edit comment generated here */
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    /* The sci1_txdone flag is used by the auto generated API only. */
    sci1_txdone = TRUE;

    if( xSendingTask != NULL )
    {
        /* A task is waiting for the end of the Tx, unblock it now.
        http://www.freertos.org/vTaskNotifyGiveFromISR.html */
        vTaskNotifyGiveFromISR( xSendingTask, &xHigherPriorityTaskWoken );
        xSendingTask = NULL;

        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    }
    /* End user code. Do not edit comment generated here */
}
/** Lock a mutex
 * @param mutex the mutex to lock */
void sys_mutex_lock( sys_mutex_t *pxMutex )
{
BaseType_t xGotSemaphore;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;

	if( xInsideISR == 0 )
	{
		while( xSemaphoreTake( *pxMutex, portMAX_DELAY ) != pdPASS );
	}
	else
	{
		xGotSemaphore = xSemaphoreTakeFromISR( *pxMutex, &xHigherPriorityTaskWoken );
		configASSERT( xGotSemaphore );
		portYIELD_FROM_ISR( xHigherPriorityTaskWoken );

		/* Prevent compiler warnings if configASSERT() is not defined. */
		( void ) xGotSemaphore;
	}
}
Exemplo n.º 8
0
__interrupt static void prvSelectButtonInterrupt(void)
{
    /* Define the message sent to the LCD task from this interrupt. */
    static const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt" };
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

    /* This is the interrupt handler for the joystick select button input.
    The button has been pushed, write a message to the LCD via the LCD task. */
    xQueueSendFromISR( xLCDQueue, &xMessage, &xHigherPriorityTaskWoken );

    P2IFG = 0;

    /* If writing to xLCDQueue caused a task to unblock, and the unblocked task
    has a priority equal to or above the task that this interrupt interrupted,
    then lHigherPriorityTaskWoken will have been set to pdTRUE internally within
    xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this
    interrupt returns directly to the higher priority unblocked task. */
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Exemplo n.º 9
0
/*
 * UART RX interrupt service routine.
 */
__interrupt void UART0_RxISR( void )
{
volatile signed char	cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	/* Get the character from the UART and post it on the queue of Rxed 
	characters. */
	cChar = RDR0;

	xQueueSendFromISR( xRxedChars, ( const void *const ) &cChar, &xHigherPriorityTaskWoken );

	if( xHigherPriorityTaskWoken )
	{
		/*If the post causes a task to wake force a context switch 
		as the woken task may have a higher priority than the task we have 
		interrupted. */
		portYIELD_FROM_ISR();
	}
}
Exemplo n.º 10
0
static __interrupt void prvUSCI_A1_ISR( void )
{
signed char cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	while( ( UCA1IFG & UCRXIFG ) != 0 )
	{
		/* Get the character from the UART and post it on the queue of Rxed
		characters. */
		cChar = UCA1RXBUF;
		xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
	}
	
	/* If there is a Tx interrupt pending and the tx interrupts are enabled. */
	if( ( UCA1IFG & UCTXIFG ) != 0 )
	{
		/* The previous character has been transmitted.  See if there are any
		further characters waiting transmission. */
		if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
		{
			/* There was another character queued - transmit it now. */
			UCA1TXBUF = cChar;
		}
		else
		{
			/* There were no other characters to transmit - disable the Tx
			interrupt. */
			UCA1IE &= ~UCTXIE;
		}
	}

	__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
	
	/* If writing to a queue caused a task to unblock, and the unblocked task
	has a priority equal to or above the task that this interrupt interrupted,
	then lHigherPriorityTaskWoken will have been set to pdTRUE internally within
	xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this
	interrupt returns directly to the higher priority unblocked task.
	
	THIS MUST BE THE LAST THING DONE IN THE ISR. */	
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Exemplo n.º 11
0
void emacps_send_handler(void *arg)
{
xemacpsif_s   *xemacpsif;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;

	xemacpsif = (xemacpsif_s *)(arg);

	/* In this port for FreeRTOS+TCP, the EMAC interrupts will only set a bit in 
	"isr_events". The task in NetworkInterface will wake-up and do the necessary work.
	*/
	xemacpsif->isr_events |= EMACPS_TX_EVENT;
	xemacpsif->txBusy = pdFALSE;

	if( xEMACTaskHandle != NULL )
	{
		vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
	}

	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Exemplo n.º 12
0
/* Handles interrupts generated by pressing the USER button. */
void EXTI0_IRQHandler(void)
{
static const TickType_t xIncrement = 200UL / portTICK_PERIOD_MS;

	/* If xSendBlockTime is already portMAX_DELAY then the Tx task was blocked
	indefinitely, and this interrupt is bringing the MCU out of STOP low power
	mode. */
	if( xSendBlockTime == portMAX_DELAY )
	{
		portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

		/* Unblock the Tx task. */
		xSemaphoreGiveFromISR( xTxSemaphore, &xHigherPriorityTaskWoken );

		/* Start over with the 'short' block time as described at the top of
		this file. */
		xSendBlockTime = xMinBlockTime;

		/* Request a yield if calling xSemaphoreGiveFromISR() caused a task to
		leave the Blocked state (which it will have done) and the task that left
		the Blocked state has a priority higher than the currently running task
		(which it will have). */
		portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
	}
	else
	{
		/* Increase the block time used by the Tx task, as described at the top
		of this file. */
		xSendBlockTime += xIncrement;

		/* If the block time has gone over the configured maximum then set it to
		an infinite block time to allow the MCU to go into its STOP low power
		mode. */
		if( xSendBlockTime > xMaxBlockTime )
		{
			xSendBlockTime = portMAX_DELAY;
		}
	}

	EXTI_ClearITPendingBit( EXTI_Line0 );
}
Exemplo n.º 13
0
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MsgQPut
 * Description   : This function is used to put a message to a message queue.
* Return         : osaStatus_Success if the message is put successfully, otherwise return osaStatus_Error.
 *
 *END**************************************************************************/
osaStatus_t OSA_MsgQPut(osaMsgQId_t msgQId, void* pMessage)
{
#if osNumberOfMessageQs  
  msg_queue_handler_t handler;
  osaStatus_t osaStatus;
  if(msgQId == NULL)
  {
    return osaStatus_Error;
  }
  handler = (msg_queue_handler_t)msgQId;
  {
    if (__get_IPSR())
    {
      portBASE_TYPE taskToWake = pdFALSE;
      
      if (pdTRUE == xQueueSendToBackFromISR(handler, pMessage, &taskToWake))
      {
        if (pdTRUE == taskToWake)
        {
          portYIELD_FROM_ISR(taskToWake);
        }
        osaStatus = osaStatus_Success;
      }
      else
      {
        osaStatus =  osaStatus_Error;
      }
      
    }
    else
    {
      osaStatus = (xQueueSendToBack(handler, pMessage, 0)== pdPASS)?(osaStatus_Success):(osaStatus_Error);
    }
  }
  return osaStatus;
#else
  (void)msgQId;
  (void)pMessage;
  return osaStatus_Error;
#endif  
}
Exemplo n.º 14
0
static void example_timer_isr(void *arg)
{
    example_event_data_t *tim_arg = (example_event_data_t *)arg;

    if (tim_arg->thnd != NULL) {
        if (tim_arg->count++ < 10) {
            BaseType_t xHigherPriorityTaskWoken = pdFALSE;
            SYSVIEW_EXAMPLE_SEND_EVENT_START();
            if (xTaskNotifyFromISR(tim_arg->thnd, tim_arg->count, eSetValueWithOverwrite, &xHigherPriorityTaskWoken) != pdPASS) {
                ESP_EARLY_LOGE(TAG, "Failed to notify task %p", tim_arg->thnd);
            } else {
                SYSVIEW_EXAMPLE_SEND_EVENT_END(tim_arg->count);
                if (xHigherPriorityTaskWoken == pdTRUE) {
                    portYIELD_FROM_ISR();
                }
            }
        }
    }
    // re-start timer
    example_timer_rearm(tim_arg->group, tim_arg->timer);
}
Exemplo n.º 15
0
/*
 * When the WIZnet device asserts an interrupt we send an (empty) message to
 * the TCP task.  This wakes the task so the interrupt can be processed.  The
 * source of the interrupt has to be ascertained by the TCP task as this 
 * requires an I2C transaction which cannot be performed from this ISR.
 * Note this code predates the introduction of semaphores, a semaphore should
 * be used in place of the empty queue message.
 */
void vEINT0_ISR_Handler( void )
{
extern xQueueHandle xTCPISRQueue;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	/* Just wake the TCP task so it knows an ISR has occurred. */
	xQueueSendFromISR( xTCPISRQueue, ( void * ) &lDummyVariable, &xHigherPriorityTaskWoken );	

	/* We cannot carry on processing interrupts until the TCP task has 
	processed this one - so for now interrupts are disabled.  The TCP task will
	re-enable it. */
	VICIntEnClear |= tcpEINT0_VIC_CHANNEL_BIT;

	/* Clear the interrupt bit. */	
	VICVectAddr = tcpCLEAR_VIC_INTERRUPT;

	if( xHigherPriorityTaskWoken )
	{
		portYIELD_FROM_ISR();
	}
}
Exemplo n.º 16
0
/// Set the specified Signal Flags of an active thread.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \param[in]     signals       specifies the signal flags of the thread that should be set.
/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
int32_t osSignalSet (osThreadId thread_id, int32_t signals)
{
    EventGroupHandle_t event_handle;
    portBASE_TYPE taskWoken = pdFALSE;
    portBASE_TYPE xResult;
    EventBits_t uxBits_ret=0x80000000;
#ifdef CHECK_VALUE_OF_EVENT_GROUP    
    EventBits_t uxBits;
#endif    

    if (signals & (0xFFFFFFFF << osFeature_Signals)) {
        return 0x80000000;
    }

    event_handle = find_signal_by_thread(thread_id);
    if (event_handle) {
        if (inHandlerMode()) {
            uxBits_ret = xEventGroupGetBitsFromISR(event_handle);
            xResult = xEventGroupSetBitsFromISR(
                            event_handle,    /* The event group being updated. */
                            signals,         /* The bits being set. */
                            &taskWoken );
            if( xResult != pdFAIL )
            {
                portYIELD_FROM_ISR(taskWoken);
            }
        }
        else {
            uxBits_ret = xEventGroupGetBits(event_handle);
#ifdef CHECK_VALUE_OF_EVENT_GROUP                
            uxBits = 
#endif              
                      xEventGroupSetBits(
                           event_handle,    /* The event group being updated. */
                           signals );/* The bits being set. */
        }
    }

    return uxBits_ret;
}
Exemplo n.º 17
0
void TC0_Handler( void )
{
static uint32_t ulISRCount = 0;

	/* Clear the interrupt. */
	if( tc_get_status( TC0, 0 ) != 0 )
	{
		/* As noted in the comments above, manually pend the TC1 interrupt from
		the TC0 interrupt handler.  This is not done on each occurrence of the
		TC0 interrupt though, to make sure interrupts don't nest in every single
		case. */
		ulISRCount++;
		if( ( ulISRCount & 0x07 ) != 0x07 )
		{
			/* Pend an interrupt that will nest with this interrupt. */
			NVIC_SetPendingIRQ( TC1_IRQn );
		}

		/* Call the IntQ test function for this channel. */
		portYIELD_FROM_ISR( xFirstTimerHandler() );
	}
}
Exemplo n.º 18
0
static void ssp_irq_handler( LPC_SSP_T * ssp_id )
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    Chip_SSP_DATA_SETUP_T * xf_setup;
    uint8_t ssp_cfg_index;

    if ((ssp_id == LPC_SSP0) && (active_SSP0 != 0xFF)) {
        ssp_cfg_index = active_SSP0;
    } else if (ssp_id == LPC_SSP1) {
        /* The only component in SPI1 is the Flash memory */
        ssp_cfg_index = FLASH_SPI;
    }

    xf_setup = &ssp_cfg[ssp_cfg_index].xf_setup;

    /* Disable SSP interrupts */
    Chip_SSP_Int_Disable(ssp_id);

    if (ssp_cfg[ssp_cfg_index].frame_size <= 8) {
        Chip_SSP_Int_RWFrames8Bits(ssp_id, xf_setup);
    }
    else {
        Chip_SSP_Int_RWFrames16Bits(ssp_id, xf_setup);
    }

    if ((xf_setup->rx_cnt != xf_setup->length) || (xf_setup->tx_cnt != xf_setup->length)) {
        /* Enable ssp interrupts, we're going to read/write more data */
        Chip_SSP_Int_Enable(ssp_id);
    }
    else {
        /* Transfer is completed, notify the caller task */
        vTaskNotifyGiveFromISR(ssp_cfg[ssp_cfg_index].caller_task, &xHigherPriorityTaskWoken);
	/* Deassert SSEL pin */
	ssp_ssel_control(ssp_cfg_index, DEASSERT);
    }

    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Exemplo n.º 19
0
static void uartIsrHdl(void *arg)
{
    char c;
    char buf[50];
    char *item;
    int r;
    size_t len;
    BaseType_t xHigherPriorityTaskWoken;
    SET_PERI_REG_MASK(UART_INT_CLR_REG(0), UART_RXFIFO_FULL_INT_CLR);
    while (READ_PERI_REG(UART_STATUS_REG(0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
        c = READ_PERI_REG(UART_FIFO_REG(0));
        if (c == 'r') {
            ets_printf("ISR r");
            xRingbufferPrintInfo(rb);
            item = xRingbufferReceiveFromISR(rb, &len);
            if (item == NULL) {
                ets_printf("ISR recv fail!\n");
            } else if (len == 0) {
                ets_printf("ISR recv NULL!\n");
                vRingbufferReturnItemFromISR(rb, item, &xHigherPriorityTaskWoken);
            } else {
                ets_printf("ISR recv '%s' (%d bytes, %p)\n", buf, len, buf);
                vRingbufferReturnItemFromISR(rb, item, &xHigherPriorityTaskWoken);
            }
        } else {
            sprintf(buf, "UART: %c", c);
            ets_printf("ISR w");
            xRingbufferPrintInfo(rb);
            r = xRingbufferSendFromISR(rb, buf, strlen(buf) + 1, &xHigherPriorityTaskWoken);
            if (!r) {
                ets_printf("ISR send fail\n");
            }
        }
    }
    if (xHigherPriorityTaskWoken) {
        portYIELD_FROM_ISR();
    }
}
Exemplo n.º 20
0
/*
 * The EMAC ISR.  Handles both Tx and Rx complete interrupts.
 */
void vEMACISR_Handler( void )
{
volatile unsigned long ulIntStatus, ulEventStatus;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
extern void vClearEMACTxBuffer( void );

	/* Find the cause of the interrupt. */
	ulIntStatus = AT91C_BASE_EMAC->EMAC_ISR;
	ulEventStatus = AT91C_BASE_EMAC->EMAC_RSR;

	if( ( ulIntStatus & AT91C_EMAC_RCOMP ) || ( ulEventStatus & AT91C_EMAC_REC ) )
	{
		/* A frame has been received, signal the lwIP task so it can process
		the Rx descriptors. */
		xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
		AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_REC;
	}

	if( ulIntStatus & AT91C_EMAC_TCOMP )
	{
		/* A frame has been transmitted.  Mark all the buffers used by the
		frame just transmitted as free again. */
		vClearEMACTxBuffer();
		AT91C_BASE_EMAC->EMAC_TSR = AT91C_EMAC_COMP;
	}

	/* Clear the interrupt. */
	AT91C_BASE_AIC->AIC_EOICR = 0;

	/* If a task was woken by either a frame being received then we may need to 
	switch to another task.  If the unblocked task was of higher priority then
	the interrupted task it will then execute immediately that the ISR
	completes. */
	if( xHigherPriorityTaskWoken )
	{
		portYIELD_FROM_ISR();
	}
}
Exemplo n.º 21
0
/* Tx interrupt handler.  This is called from the asm file wrapper. */
void vUARTTxISRHandler( void )
{
char cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	/* Are there any more characters queue to transmit? */
	if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
	{
		/* Send the next character. */
		UD0TX = cChar;
	}
	else
	{
		/* The UART is no longer active. */
		ulTxInProgress = pdFALSE;
	}
	
	/* If reading a character from the Rx queue caused a task to unblock, and
	the unblocked task has a priority higher than the currently running task,
	then xHigherPriorityTaskWoken will have been set to true and a context
	switch should occur now. */
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Exemplo n.º 22
0
static void prvRxInterruptHandler( int iArg )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
unsigned char ucRx;

	/* Just to remove compiler warnings about unused parameters. */
	( void ) iArg;

	/* Grab the character as early as possible. */
	ucRx = ( unsigned char ) ASC0_RBUF.reg;

	/* ACK. */
	ASC0_RSRC.reg |= 0x4000UL;

	/* Frame available in RBUF. */
	if( pdPASS != xQueueSendFromISR( xSerialReceiveQueue, &ucRx, &xHigherPriorityTaskWoken ) )
	{
		/* Error handling code can go here. */
	}

	/* Finally end ISR and switch Task if necessary. */
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Exemplo n.º 23
0
static void i2cISR()
{
	portSAVE_CONTEXT();		// Save context of existing task

	long higherPriorityTaskWaiting = 0;
	i2cStateMachineStatus status = i2cStateMachine();

	/* For READ, do not release I2C Lock, instead give the i2cReadCompleteSignal
	 * so that the read() routine can read the data first, and then release the lock.
	 * For WRITE, release the i2c Lock so next task can access I2C
	 */
	if(status == readComplete)
		xSemaphoreGiveFromISR(i2cReadCompleteSignal, &higherPriorityTaskWaiting);
	else if(status == writeComplete)
		xSemaphoreGiveFromISR(i2cLock, &higherPriorityTaskWaiting);
	
	if(higherPriorityTaskWaiting) {
		portYIELD_FROM_ISR();
	}
	VICVectAddr = 0;

	portRESTORE_CONTEXT();	// Restore context to possibly a task waiting for I2C Read or I2C Mutex
}
Exemplo n.º 24
0
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_EventSet
 * Description   : Set one or more event flags of an event object.
 * Return        : osaStatus_Success if set successfully, osaStatus_Error if failed.
 *
 *END**************************************************************************/
osaStatus_t OSA_EventSet(osaEventId_t eventId, osaEventFlags_t flagsToSet)
{
#if osNumberOfEvents    
  osEventStruct_t* pEventStruct; 
  portBASE_TYPE taskToWake = pdFALSE;
  if(osObjectIsAllocated(&osEventInfo, eventId) == FALSE)
  {
    return osaStatus_Error;
  }
  pEventStruct = (osEventStruct_t*)eventId;  
  if(pEventStruct->event.eventHandler == NULL)
  {
    return osaStatus_Error;
  }
  if (__get_IPSR())
  {
    if (pdPASS != xEventGroupSetBitsFromISR(pEventStruct->event.eventHandler, (event_flags_t)flagsToSet, &taskToWake))
    {
      panic(0,(uint32_t)OSA_EventSet,0,0);
      return osaStatus_Error;
    }
    if (pdTRUE == taskToWake)
    {
      portYIELD_FROM_ISR(taskToWake);
    }
  }
  else
  {
    xEventGroupSetBits(pEventStruct->event.eventHandler, (event_flags_t)flagsToSet);
  }
  return osaStatus_Success;
#else
  (void)eventId;
  (void)flagsToSet;  
  return osaStatus_Error;
#endif  
}
Exemplo n.º 25
0
Arquivo: usart.c Projeto: tsugli/stm32
//===============================================================================================
__inline void AT91F_US_INTERRUPT(AT91PS_USART COM,xQueueHandle *pxQueue,ErrorHandle *pxError)
{
    unsigned int status;
    unsigned int size;
    portBASE_TYPE  xTaskWokenByPost = pdFALSE;
    /* What caused the interrupt? */
    status = COM->US_CSR &= COM->US_IMR;
    if (status & (AT91C_US_RXBUFF | AT91C_US_FRAME | AT91C_US_PARE |AT91C_US_OVRE))
    {
        AT91F_US_DisableIt(COM, (status & (AT91C_US_RXBUFF | AT91C_US_FRAME | AT91C_US_PARE |AT91C_US_OVRE)));
    } else  {
        if ((status & AT91C_US_TIMEOUT ))
        {
            AT91F_US_DisableIt(COM, AT91C_US_TIMEOUT | AT91C_US_RXBUFF );
            AT91F_US_DisableRx(COM);
            size = (unsigned int)COM->US_RCR;
            xQueueSendFromISR( *pxQueue, &size, &xTaskWokenByPost );
        }
    }
    if (status & AT91C_US_ENDTX)
    {   // Data transmitted
        AT91F_US_DisableIt(COM, AT91C_US_ENDTX );
        AT91F_US_DisableTx(COM);
        AT91F_US_EnableIt(COM, AT91C_US_TXEMPTY );
    }
    if (status & AT91C_US_TXEMPTY)
    {
        size = (unsigned int)COM->US_TCR;
        xQueueSendFromISR( *pxQueue, &size, &xTaskWokenByPost );
        AT91F_US_DisableIt(COM, AT91C_US_TXEMPTY );
    }
    if( xTaskWokenByPost)
    {
        portYIELD_FROM_ISR();
    }
    AT91C_BASE_AIC->AIC_EOICR = 0;
}
Exemplo n.º 26
0
void vEMAC_ISR_Handler( void )
{
unsigned long ul = EDMAC.EESR.LONG;
long lHigherPriorityTaskWoken = pdFALSE;
extern xQueueHandle xEMACEventQueue;
const unsigned long ulRxEvent = uipETHERNET_RX_EVENT;

	/* Has a Tx end occurred? */
	if( ul & emacTX_END_INTERRUPT )
	{
		/* Only return the buffer to the pool once both Txes have completed. */
		prvReturnBuffer( ( void * ) xTxDescriptors[ 0 ].buf_p );
		EDMAC.EESR.LONG = emacTX_END_INTERRUPT;
	}

	/* Has an Rx end occurred? */
	if( ul & emacRX_END_INTERRUPT )
	{
		/* Make sure the Ethernet task is not blocked waiting for a packet. */
		xQueueSendFromISR( xEMACEventQueue, &ulRxEvent, &lHigherPriorityTaskWoken );
		portYIELD_FROM_ISR( lHigherPriorityTaskWoken );
		EDMAC.EESR.LONG = emacRX_END_INTERRUPT;
	}
}
Exemplo n.º 27
0
static void prvTxHandler( void )
{
signed char cChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	/* The interrupt was caused by the transmit fifo having space for at least one
	character. Are there any more characters to transmit? */
	if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
	{
		/* A character was retrieved from the queue so can be sent to the uart now. */
		uart1->tx_data = cChar;
	}
	else
	{
		/* Queue empty, nothing to send so turn off the Tx interrupt. */
		uart1->tx_mask = 0;
	}

	/* If an event caused a task to unblock then we call "Yield from ISR" to
	ensure that the unblocked task is the task that executes when the interrupt
	completes if the unblocked task has a priority higher than the interrupted
	task. */
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Exemplo n.º 28
0
Arquivo: i2c.c Projeto: cocobot/mcual
static void mcual_i2c_stop(mcual_i2c_id_t id, int success)
{
  I2C_TypeDef * reg = mcual_i2c_get_register(id);

  reg->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITERREN);
  I2C1->SR1 = 0;
  I2C1->SR2 = 0;

  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  BaseType_t xResult = pdFALSE;
  if(success)
  {
    xResult =  xEventGroupSetBitsFromISR(transfer_done[id], 1 << MCUAL_I2C_SUCCESS, &xHigherPriorityTaskWoken);
  }
  else
  {
    xResult = xEventGroupSetBitsFromISR(transfer_done[id], 1 << MCUAL_I2C_FAIL, &xHigherPriorityTaskWoken);
  }

  if(xResult != pdFAIL)
  {
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
  }
}
Exemplo n.º 29
0
/* Handler for the SW2 button push interrupt. */
__interrupt void vExternalInt8Handler( void )
{
short sHigherPriorityTaskWoken = pdFALSE;

	/* Reset the interrupt. */
	EIRR1_ER8 = 0;

	/* Check the semaphore has been created before attempting to use it. */
	if( xSemaphores[ configLEFT_DISPLAY ] != NULL )
	{
		/* Send a message via the semaphore to the dice task that controls the
		left side display.  This will unblock the task if it is blocked waiting
		for a button push. */
		xSemaphoreGiveFromISR( xSemaphores[ configLEFT_DISPLAY ], &sHigherPriorityTaskWoken );
	}

	/* If sending the semaphore unblocked a task, and the unblocked task has a
	priority that is higher than the currently running task, then force a context
	switch. */
	if( sHigherPriorityTaskWoken != pdFALSE )
	{
		portYIELD_FROM_ISR();
	}
}
Exemplo n.º 30
0
/* The ISR is executed when the user button is pushed. */
static void prvButtonInputInterruptHandler( void *pvUnused )
{
long lHigherPriorityTaskWoken = pdFALSE;

	/* The button was pushed, so ensure the LED is on before resetting the
	LED timer.  The LED timer will turn the LED off if the button is not
	pushed within 5000ms. */
	ucGPIOState |= mainTIMER_CONTROLLED_LED;
	XGpio_DiscreteWrite( &xOutputGPIOInstance, ulGPIOOutputChannel, ucGPIOState );

	/* Ensure only the ISR safe reset API function is used, as this is executed
	in an interrupt context. */
	xTimerResetFromISR( xLEDTimer, &lHigherPriorityTaskWoken );

	/* Clear the interrupt before leaving. */
	XGpio_InterruptClear( &xInputGPIOInstance, ulGPIOInputChannel );

	/* If calling xTimerResetFromISR() caused a task (in this case the timer
	service/daemon task) to unblock, and the unblocked task has a priority
	higher than or equal to the task that was interrupted, then
	lHigherPriorityTaskWoken will now be set to pdTRUE, and calling
	portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
	portYIELD_FROM_ISR( lHigherPriorityTaskWoken );
}