Example #1
0
void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
	xemacpsif_s *xemacpsif;
	BaseType_t xNextHead = xErrorHead;

	xemacpsif = (xemacpsif_s *)(arg);

	if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )
	{
		if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )
			xNextHead = 0;
		if( xNextHead != xErrorTail )
		{

			xErrorList[ xErrorHead ].arg = arg;
			xErrorList[ xErrorHead ].Direction = Direction;
			xErrorList[ xErrorHead ].ErrorWord = ErrorWord;

			xErrorHead = xNextHead;

			xemacpsif = (xemacpsif_s *)(arg);
			xemacpsif->isr_events |= EMACPS_ERR_EVENT;
		}

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

	}

	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Example #2
0
/*
 * 	UART Rx handler for GPS UART
 *
 * 	On getting first '$' character, puts the subsequent character into a buffer.
 * 	When CR-LF termination is recieved, signals the gps task of the new sentence.
 *
 *  Note: This is called from within the UART RX ISR
 */
static void gps_uart_rx_handler(UART_Type *base, uart_handle_t *handle, status_t status, void *userData)
{
	static uint32_t buf_n;
	static uint8_t prev_ch;
	uint8_t ch;
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;


	/*  The buffer pointer was incremented in UART ISR */
	handle->rxData--;
	/* Get received byte */
	ch = *(handle->rxData);
	/* Reset Rx size (decremented in UART ISR), otherwise UART driver will disable Rx interrupt! */
	handle->rxDataSize = 1;

	if ('$' == ch) {
		buf_n = 0;
	}
	else {
		if (buf_n < sizeof(gps_rx_sentence)) {
			gps_rx_sentence[buf_n++] = ch;
			if (('\n' == ch) && (prev_ch == '\r')) {
				gps_rx_len = buf_n;
				vTaskNotifyGiveFromISR(xGpsTaskHandle, &xHigherPriorityTaskWoken);
			}
		}
	}

	prev_ch = ch;

	/* Request context switch if vTaskNotifyGiveFromISR() caused a higher priority task ready */
	portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
Example #3
0
void vUART_Handler( void )
{
uint8_t ucChar;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
uint_fast8_t xInterruptStatus;

	xInterruptStatus = MAP_UART_getEnabledInterruptStatus( EUSCI_A0_MODULE );

	if( ( xInterruptStatus & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG ) != 0x00 )
	{
		/* Obtain the character. */
		ucChar = MAP_UART_receiveData( EUSCI_A0_MODULE );

		/* Send the character to the queue.  Note the comments at the top of this
		file with regards to the inefficiency of this method for anything other than
		very low bandwidth communications.

		If writing to the queue unblocks a task, and the unblocked task	has a
		priority above the currently running task (the task that this interrupt
		interrupted), then xHigherPriorityTaskWoken will be set	to pdTRUE inside the
		xQueueSendFromISR() function.  xHigherPriorityTaskWoken is then passed to
		portYIELD_FROM_ISR() at	the end of this interrupt handler to request a
		context switch so the interrupt returns directly to the (higher priority)
		unblocked task. */
		xQueueSendFromISR( xRxQueue, &ucChar, &xHigherPriorityTaskWoken );
	}

	if( ( xInterruptStatus & EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG ) != 0x00 )
	{
		/* Are there more characters to transmit? */
		pcStringStart++;
		if( ( uint32_t ) pcStringStart < ( uint32_t ) pcStringEnd )
		{
			/* This is probably quite a heavy wait function just for writing to
			the Tx register.  An optimised design would probably replace this
			with a simple register write. */
			pxUARTA0->rTXBUF.r = ( uint_fast8_t ) *pcStringStart;
		}
		else
		{
			/* No more characters to send.  Disable the interrupt and notify the
			task, if the task is waiting. */
			MAP_UART_disableInterrupt( EUSCI_A0_MODULE, EUSCI_A_UART_TRANSMIT_INTERRUPT );
			if( xTransmittingTask != NULL )
			{
				vTaskNotifyGiveFromISR( xTransmittingTask, &xHigherPriorityTaskWoken );
				xTransmittingTask = NULL;
			}
		}
	}


	/* portYIELD_FROM_ISR() will request a context switch if executing this
	interrupt handler caused a task to leave the blocked state, and the task
	that left the blocked state has a higher priority than the currently running
	task (the task this interrupt interrupted).  See the comment above the calls
	to xSemaphoreGiveFromISR() and xQueueSendFromISR() within this function. */
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Example #4
0
static void IRQ8_isr (void) {
    BaseType_t xHigherPriorityTaskWoken;

    xHigherPriorityTaskWoken = pdFALSE;

    vTaskNotifyGiveFromISR( xEmergenciaTaskHandle, &xHigherPriorityTaskWoken );

    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Example #5
0
static void prvRxCallback( uint32_t ulStatus )
{
	if( ( ( ulStatus & GMAC_RSR_REC ) != 0 ) && ( xEMACTaskHandle != NULL ) )
	{
		/* let the prvEMACHandlerTask know that there was an RX event. */
		ulISREvents |= EMAC_IF_RX_EVENT;
		/* Only an RX interrupt can wakeup prvEMACHandlerTask. */
		vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
	}
}
Example #6
0
static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer )
{
	if( ( xTxBufferQueue != NULL ) && ( xEMACTaskHandle != NULL ) )
	{
		/* let the prvEMACHandlerTask know that there was an RX event. */
		ulISREvents |= EMAC_IF_TX_EVENT;

		vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
		xQueueSendFromISR( xTxBufferQueue, &puc_buffer, ( BaseType_t * ) &xGMACSwitchRequired );
		tx_release_count[ 2 ]++;
	}
}
Example #7
0
static void prvGMACRxCallback( uint32_t ulStatus )
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    configASSERT( xMACEventHandlingTask );

    /* Unblock the deferred interrupt handler task if the event was an Rx. */
    if( ( ulStatus & GMAC_RSR_REC ) != 0 )
    {
        vTaskNotifyGiveFromISR( xMACEventHandlingTask, &xHigherPriorityTaskWoken );
    }

    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
Example #8
0
void emacps_recv_handler(void *arg)
{
	xemacpsif_s *xemacpsif;
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;

	xemacpsif = (xemacpsif_s *)(arg);
	xemacpsif->isr_events |= EMACPS_RX_EVENT;

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

	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
Example #9
0
/***********************************************************************************************************************
* Function Name: r_scifa2_callback_transmitend
* Description  : This function is a callback function when SCIFA2 finishes transmission.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void r_scifa2_callback_transmitend(void)
{
    /* Start user code. Do not edit comment generated here */
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    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 */
}
Example #10
0
static void prvTxHandler( void *pvUnused, unsigned portBASE_TYPE uxUnused )
{
BaseType_t xHigherPriorityTaskWoken = NULL;

	( void ) pvUnused;
	( void ) uxUnused;

	/* Notify the sending that that the Tx has completed. */
	if( xUARTSendingTask != NULL )
	{
		vTaskNotifyGiveFromISR( xUARTSendingTask, &xHigherPriorityTaskWoken );
		xUARTSendingTask = NULL;
	}

	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
void xNotifyTaskFromISR( void )
{
static BaseType_t xCallCount = 0, xAPIToUse = 0;
const BaseType_t xCallInterval = pdMS_TO_TICKS( 50 );
uint32_t ulPreviousValue;
const uint32_t ulUnexpectedValue = 0xff;

	/* The task performs some tests before starting the timer that gives the
	notification from this interrupt.  If the timer has not been created yet
	then the initial tests have not yet completed and the notification should
	not be sent. */
	if( xTimer != NULL )
	{
		xCallCount++;

		if( xCallCount >= xCallInterval )
		{
			/* It is time to 'give' the notification again. */
			xCallCount = 0;

			/* Test using both vTaskNotifyGiveFromISR(), xTaskNotifyFromISR()
			and xTaskNotifyAndQueryFromISR(). */
			switch( xAPIToUse )
			{
				case 0:	vTaskNotifyGiveFromISR( xTaskToNotify, NULL );
						xAPIToUse++;
						break;

				case 1:	xTaskNotifyFromISR( xTaskToNotify, 0, eIncrement, NULL );
						xAPIToUse++;
						break;

				case 2: ulPreviousValue = ulUnexpectedValue;
						xTaskNotifyAndQueryFromISR( xTaskToNotify, 0, eIncrement, &ulPreviousValue, NULL );
						configASSERT( ulPreviousValue != ulUnexpectedValue );
						xAPIToUse = 0;
						break;

				default:/* Should never get here!. */
						break;
			}

			ulTimerNotificationsSent++;
		}
	}
}
Example #12
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 );
}
Example #13
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 );
}
Example #14
0
void os_threadIsrNotify(os_threadHandle_t handle)
{
    bool hasWoken = false;
    vTaskNotifyGiveFromISR(handle->threadHandle, (BaseType_t *)&hasWoken);
    portYIELD_FROM_ISR(hasWoken);
}
Example #15
0
File: i2c.c Project: qermit/afcipm
/*! @brief I2C common interrupt service routine
 *
 * I2STAT register is handled inside this function, a state-machine-like implementation for I2C interface.
 *    
 * When a full message is trasmitted or received, the task whose handle is written to #i2c_cfg is notified, unblocking it. It also happens when an error occurs.
 * @warning Slave Transmitter mode states are not implemented in this driver and are just ignored.
 */
void vI2C_ISR( uint8_t i2c_id )
{
    /* Declare local variables */
    portBASE_TYPE xI2CSemaphoreWokeTask;

    /* Initialize variables */
    xI2CSemaphoreWokeTask = pdFALSE;
    uint32_t cclr = I2C_CON_FLAGS;

    /* I2C status handling */
    switch ( I2CSTAT( i2c_id ) ){
    case I2C_STAT_START:
    case I2C_STAT_REPEATED_START:
        i2c_cfg[i2c_id].rx_cnt = 0;
        i2c_cfg[i2c_id].tx_cnt = 0;
        /* Write Slave Address in the I2C bus, if there's nothing
         * to transmit, the last bit (R/W) will be set to 1 */
        I2CDAT_WRITE( i2c_id, ( i2c_cfg[i2c_id].msg.addr << 1 ) | ( i2c_cfg[i2c_id].msg.tx_len == 0 ) );
        break;

    case I2C_STAT_SLA_W_SENT_ACK:
        /* Send first data byte */
        I2CDAT_WRITE( i2c_id, i2c_cfg[i2c_id].msg.tx_data[i2c_cfg[i2c_id].tx_cnt] );
        i2c_cfg[i2c_id].tx_cnt++;
        break;

    case I2C_STAT_SLA_W_SENT_NACK:
        cclr &= ~I2C_STO;
        i2c_cfg[i2c_id].msg.error = i2c_err_SLA_W_SENT_NACK;
        vTaskNotifyGiveFromISR( i2c_cfg[i2c_id].master_task_id, &xI2CSemaphoreWokeTask );
        break;

    case I2C_STAT_DATA_SENT_ACK:
        /* Transmit the remaining bytes */
        if ( i2c_cfg[i2c_id].msg.tx_len != i2c_cfg[i2c_id].tx_cnt ){
            I2CDAT_WRITE( i2c_id, i2c_cfg[i2c_id].msg.tx_data[i2c_cfg[i2c_id].tx_cnt] );
            i2c_cfg[i2c_id].tx_cnt++;
        } else {
            /* If there's no more data to be transmitted,
             * finish the communication and notify the caller task */
            cclr &= ~I2C_STO;
            vTaskNotifyGiveFromISR( i2c_cfg[i2c_id].master_task_id, &xI2CSemaphoreWokeTask );
        }
        break;

    case I2C_STAT_DATA_SENT_NACK:
        cclr &= ~I2C_STO;
        i2c_cfg[i2c_id].msg.error = i2c_err_DATA_SENT_NACK;
        vTaskNotifyGiveFromISR( i2c_cfg[i2c_id].master_task_id, &xI2CSemaphoreWokeTask );

    case I2C_STAT_SLA_R_SENT_ACK:
        /* SLA+R has been transmitted and ACK'd
         * If we want to receive only 1 byte, return NACK on the next byte */
        if ( i2c_cfg[i2c_id].msg.rx_len > 1 ){
             /* If we expect to receive more than 1 byte,
             * return ACK on the next byte */
            cclr &= ~I2C_AA;
        }
        break;

    case I2C_STAT_DATA_RECV_ACK:
        if ( i2c_cfg[i2c_id].rx_cnt < i2cMAX_MSG_LENGTH - 1 ){
            i2c_cfg[i2c_id].msg.rx_data[i2c_cfg[i2c_id].rx_cnt] = I2CDAT_READ( i2c_id );
            i2c_cfg[i2c_id].rx_cnt++;
            if (i2c_cfg[i2c_id].rx_cnt != (i2c_cfg[i2c_id].msg.rx_len) - 1 ){
                cclr &= ~I2C_AA;
            }
        }
        break;

    case I2C_STAT_DATA_RECV_NACK:
        i2c_cfg[i2c_id].msg.rx_data[i2c_cfg[i2c_id].rx_cnt] = I2CDAT_READ( i2c_id );
        i2c_cfg[i2c_id].rx_cnt++;
        cclr &= ~I2C_STO;
        /* There's no more data to be received */
        vTaskNotifyGiveFromISR( i2c_cfg[i2c_id].master_task_id, &xI2CSemaphoreWokeTask );
        break;

    case I2C_STAT_SLA_R_SENT_NACK:
	cclr &= ~I2C_STO;
        /* Notify the error */
        i2c_cfg[i2c_id].msg.error = i2c_err_SLA_R_SENT_NACK;
        vTaskNotifyGiveFromISR( i2c_cfg[i2c_id].master_task_id, &xI2CSemaphoreWokeTask );
        break;

        /* Slave Mode */
    case I2C_STAT_SLA_W_RECV_ACK:
    case I2C_STAT_ARB_LOST_SLA_W_RECV_ACK:
        i2c_cfg[i2c_id].msg.i2c_id = i2c_id;
        i2c_cfg[i2c_id].rx_cnt = 0;
        if ( i2c_cfg[i2c_id].mode == I2C_Mode_IPMB ){
            i2c_cfg[i2c_id].msg.rx_data[i2c_cfg[i2c_id].rx_cnt] = I2CADDR_READ(i2c_id);

            //if (i2c_cfg[i2c_id].rx_cnt > 1) {
        	cclr &= ~I2C_AA;
            //}


            i2c_cfg[i2c_id].rx_cnt++;

        }


        break;

    case I2C_STAT_SLA_DATA_RECV_ACK:
        /* Checks if the buffer is full */
        if ( i2c_cfg[i2c_id].rx_cnt < i2cMAX_MSG_LENGTH ){
            i2c_cfg[i2c_id].msg.rx_data[i2c_cfg[i2c_id].rx_cnt] = I2CDAT_READ( i2c_id );
            i2c_cfg[i2c_id].rx_cnt++;
            cclr &= ~I2C_AA;
        }
        break;

    case I2C_STAT_SLA_DATA_RECV_NACK:
        cclr &= ~I2C_AA;
        i2c_cfg[i2c_id].msg.error = i2c_err_SLA_DATA_RECV_NACK;
        break;

    case I2C_STAT_SLA_STOP_REP_START:
        i2c_cfg[i2c_id].msg.rx_len = i2c_cfg[i2c_id].rx_cnt;
        if (((i2c_cfg[i2c_id].rx_cnt > 0) && (i2c_cfg[i2c_id].mode == I2C_Mode_Local_Master ))) {
        		vTaskNotifyGiveFromISR( i2c_cfg[i2c_id].slave_task_id, &xI2CSemaphoreWokeTask );
    	}
        if (((i2c_cfg[i2c_id].rx_cnt > 1) && (i2c_cfg[i2c_id].mode == I2C_Mode_IPMB ))) {
            vTaskNotifyGiveFromISR( i2c_cfg[i2c_id].slave_task_id, &xI2CSemaphoreWokeTask );
        }

        cclr &= ~I2C_AA;
        break;

    case I2C_STATUS_BUSERR:
	cclr &= ~I2C_STO;
	break;
    default:
        break;
    }

	if (!(cclr & I2C_CON_STO)) {
		//if (slave_active != 0) {
			cclr &= ~I2C_CON_AA;
		//}
		I2CCONSET(i2c_id, cclr ^ I2C_CON_FLAGS);
		I2CCONCLR(i2c_id, cclr);
		asm("nop");
	} else {
		I2CCONSET(i2c_id, cclr ^ I2C_CON_FLAGS);
		I2CCONCLR(i2c_id, cclr);
	}


    if (xI2CSemaphoreWokeTask == pdTRUE) {
        portYIELD_FROM_ISR(pdTRUE);
    }
}