void vSoftwareInterruptHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

    /* 'Give' the semaphore to unblock the task. */
    xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);

    /* Clear the software interrupt bit using the interrupt controllers
    Clear Pending register. */
    mainCLEAR_INTERRUPT();

    /* Giving the semaphore may have unblocked a task - if it did and the
    unblocked task has a priority equal to or above the currently executing
    task then xHigherPriorityTaskWoken will have been set to pdTRUE and
    portEND_SWITCHING_ISR() will force a context switch to the newly unblocked
    higher priority task.

    NOTE: The syntax for forcing a context switch within an ISR varies between
    FreeRTOS ports.  The portEND_SWITCHING_ISR() macro is provided as part of
    the Cortex M3 port layer for this purpose.  taskYIELD() must never be called
    from an ISR! */
    portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
Example #2
0
__arm void vEMACISR( void )
{
volatile unsigned long ulIntStatus, ulRxStatus;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	ulIntStatus = AT91C_BASE_EMAC->EMAC_ISR;
	ulRxStatus = AT91C_BASE_EMAC->EMAC_RSR;

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

	/* If a task was woken by either a character being received or a character
	being transmitted then we may need to switch to another task. */
	portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

	/* Clear the interrupt. */
	AT91C_BASE_AIC->AIC_EOICR = 0;
}
/*=====================================================================================================*/
void USART3_IRQHandler()
{
	long lHigherPriorityTaskWoken = pdFALSE;

	serial_msg rx_msg;

	if (USART_GetITStatus(USART3, USART_IT_TXE) != RESET) {
		xSemaphoreGiveFromISR(serial_tx_wait_sem, &lHigherPriorityTaskWoken);

		USART_ITConfig(USART3, USART_IT_TXE, DISABLE);

	} else if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
		rx_msg.ch = USART_ReceiveData(USART3);

		if (!xQueueSendToBackFromISR(serial_rx_queue, &rx_msg, &lHigherPriorityTaskWoken))
			portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);

	} else {
		while (1);
	}

	portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
}
void Dummy_IRQHandler(void)
{
	long lHigherPriorityTaskWoken = pdFALSE;

	/* Clear the interrupt if necessary. */
	Dummy_ClearITPendingBit();

	/* This interrupt does nothing more than demonstrate how to synchronise a
	task with an interrupt.  A semaphore is used for this purpose.  Note
	lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions
	that end in "FromISR" can be called from an ISR. */
	xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );

	/* If there was a task that was blocked on the semaphore, and giving the
	semaphore caused the task to unblock, and the unblocked task has a priority
	higher than the current Running state task (the task that this interrupt
	interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
	internally within xSemaphoreGiveFromISR().  Passing pdTRUE into the
	portEND_SWITCHING_ISR() macro will result in a context switch being pended to
	ensure this interrupt returns directly to the unblocked, higher priority,
	task.  Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
	portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
Example #5
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 );
}
Example #6
0
static long prvMACB_ISR_NonNakedBehaviour( void )
{

  // Variable definitions can be made now.
  volatile unsigned long ulIntStatus, ulEventStatus;
  long xHigherPriorityTaskWoken = FALSE;

  // Find the cause of the interrupt.
  ulIntStatus = AVR32_MACB.isr;
  ulEventStatus = AVR32_MACB.rsr;

  if( ( ulIntStatus & AVR32_MACB_IDR_RCOMP_MASK ) || ( ulEventStatus & AVR32_MACB_REC_MASK ) )
  {
    // A frame has been received, signal the IP task so it can process
    // the Rx descriptors.
    portENTER_CRITICAL();
#ifdef FREERTOS_USED
    xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
#else
    DataToRead = TRUE;   
#endif      
    portEXIT_CRITICAL();
    AVR32_MACB.rsr =  AVR32_MACB_REC_MASK;
    AVR32_MACB.rsr;
  }

  if( ulIntStatus & AVR32_MACB_TCOMP_MASK )
  {
    // A frame has been transmitted.  Mark all the buffers used by the
    // frame just transmitted as free again.
    vClearMACBTxBuffer();
    AVR32_MACB.tsr =  AVR32_MACB_TSR_COMP_MASK;
    AVR32_MACB.tsr;
  }

  return ( xHigherPriorityTaskWoken );
}
Example #7
0
/* IRQ handler to handle USART2 interruptss (both transmit and
 * receive interrupts). */
void USART2_IRQHandler()
{
	static signed portBASE_TYPE xHigherPriorityTaskWoken;
	serial_ch_msg rx_msg;

	/* If this interrupt is for a transmit... */
	if (USART_GetITStatus(USART2, USART_IT_TXE) != RESET) {
		/* "give" the serial_tx_wait_sem semaphore to notfiy processes
		 * that the buffer has a spot free for the next byte.
		 */
		xSemaphoreGiveFromISR(serial_tx_wait_sem,
		                      &xHigherPriorityTaskWoken);

		/* Diables the transmit interrupt. */
		USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
		/* If this interrupt is for a receive... */
	} else if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
		/* Receive the byte from the buffer. */
		rx_msg.ch = USART_ReceiveData(USART2);

		/* Queue the received byte. */
		if (!xQueueSendToBackFromISR(serial_rx_queue, &rx_msg,
		                             &xHigherPriorityTaskWoken)) {
			/* If there was an error queueing the received byte,
			 * freeze. */
			while (1);
		}
	} else {
		/* Only transmit and receive interrupts should be enabled.
		 * If this is another type of interrupt, freeze.
		 */
		while (1);
	}

	if (xHigherPriorityTaskWoken)
		taskYIELD();
}
Example #8
0
static void uartadapter_uart_irq(uint32_t id, SerialIrq event)
{
	portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	if(event == RxIrq) {		
		ua_rcv_ch = serial_getc(&ua_sobj);
		ua_uart_recv_buf[ua_pwrite] = ua_rcv_ch;
		ua_pwrite++;	//point to uart data recved
		xSemaphoreGiveFromISR( ua_uart_action_sema, &xHigherPriorityTaskWoken );	//up action semaphore 					
		
		if(ua_pwrite > (UA_UART_RECV_BUFFER_LEN -1)){	//restart from  head if  reach tail
			ua_pwrite = 0;
			ua_overlap = 1;		
		}
		
		if(ua_overlap && (ua_pwrite - 1) >= ua_pread ){
 		       //ua_printf(UA_ERROR, "IRQ missing data %d byte!", ua_pread - ua_pwrite + 1);
 		       irq_miss_cnt ++;
			ua_pread = ua_pwrite;		//if pwrite overhead pread ,pread is always flow rwrite 					
		}
		ua_tick_last_update =  xTaskGetTickCountFromISR();	// update tick everytime recved data
		irq_rx_cnt ++;
	}
}
void vT5InterruptHandler( void )
{
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

    /* This function is the handler for the peripheral timer interrupt.
    The interrupt is initially signalled in a separate assembly file
    which switches to the system stack and then calls this function.
    It gives a semaphore which signals the prvISRBlockTask */

    /* Give the semaphore.  If giving the semaphore causes the task to leave the
    Blocked state, and the priority of the task is higher than the priority of
    the interrupted task, then xHigherPriorityTaskWoken will be set to pdTRUE
    inside the xSemaphoreGiveFromISR() function.  xHigherPriorityTaskWoken is
    later passed into portEND_SWITCHING_ISR(), where a context switch is
    requested if it is pdTRUE.  The context switch ensures the interrupt returns
    directly to the unblocked task. */
    xSemaphoreGiveFromISR( xBlockSemaphore, &xHigherPriorityTaskWoken );

    /* Clear the interrupt */
    IFS0CLR = _IFS0_T5IF_MASK;

    /* See comment above the call to xSemaphoreGiveFromISR(). */
    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
Example #10
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();
	}
}
Example #11
0
// Signals a semaphore (from ISR)
int sys_sem_signal_isr(sys_sem_t *sem)
{
    BaseType_t woken = pdFALSE;
    xSemaphoreGiveFromISR(*sem, &woken);
    return woken == pdTRUE;
}
Example #12
0
__interrupt
#endif
static void usb_general_interrupt(void)

#endif
{
#ifdef FREERTOS_USED
  portBASE_TYPE task_woken = pdFALSE;
#endif
#if USB_HOST_FEATURE == true && USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
  U8 i;
#endif

// ---------- DEVICE/HOST events management ------------------------------------
#if USB_DEVICE_FEATURE == true && USB_HOST_FEATURE == true
  // ID pin change detection
  if (Is_usb_id_transition() && Is_usb_id_interrupt_enabled())
  {
    g_usb_mode = (Is_usb_id_device()) ? USB_MODE_DEVICE : USB_MODE_HOST;
    Usb_ack_id_transition();
    if (g_usb_mode != g_old_usb_mode) // Basic debounce
    {
      // Previously in device mode, check if disconnection was detected
      if (g_old_usb_mode == USB_MODE_DEVICE)
      {
        if (usb_connected)
        {
          // Device mode disconnection actions
          usb_connected = false;
          usb_configuration_nb = 0;
          Usb_vbus_off_action();
        }
      }
      // Previously in host mode, check if disconnection was detected
      else if (Is_host_attached())
      {
        // Host mode disconnection actions
        device_state = DEVICE_UNATTACHED;
        Host_device_disconnection_action();
      }

      //LOG_STR(log_pin_id_changed);
      if (Is_usb_id_device() == USB_MODE_DEVICE) { LOG_STR(log_pin_id_changed_to_device); }
		else { LOG_STR(log_pin_id_changed_to_host); }
	  
	  Usb_send_event((Is_usb_device()) ? EVT_USB_DEVICE_FUNCTION :
                                         EVT_USB_HOST_FUNCTION);
      Usb_id_transition_action();

	  // Easier to recover from ID signal de-bounce and ID pin transitions by shutting down the USB and resetting state machine to re-init
#if ID_PIN_CHANGE_SHUTDOWN_USB == ENABLE
      Usb_disable();
      Usb_disable_otg_pad();

extern void UsbResetStateMachine(void);
	  UsbResetStateMachine();

    #ifdef FREERTOS_USED
      // Release the semaphore in order to start a new device/host task
      taskENTER_CRITICAL();
      xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
      taskEXIT_CRITICAL();
	#endif
#endif

#if ID_PIN_CHANGE_GENERATE_RESET == ENABLE
      Reset_CPU();
#endif
    }
  }
#endif  // End DEVICE/HOST FEATURE MODE

// ---------- DEVICE events management -----------------------------------------
#if USB_DEVICE_FEATURE == true
  #if USB_HOST_FEATURE == true
  // If both device and host features are enabled, check if device mode is engaged
  // (accessing the USB registers of a non-engaged mode, even with load operations,
  // may corrupt USB FIFO data).
  if (Is_usb_device())
  #endif
  {
    // VBus state detection
    if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled())
    {
      Usb_ack_vbus_transition();
      if (Is_usb_vbus_high())
      {
        usb_start_device();
        Usb_send_event(EVT_USB_POWERED);
        Usb_vbus_on_action();
      }
      else
      {
        Usb_unfreeze_clock();
        Usb_detach();
        usb_connected = false;
        usb_configuration_nb = 0;
        Usb_send_event(EVT_USB_UNPOWERED);
        Usb_vbus_off_action();
  #ifdef FREERTOS_USED
        // Release the semaphore in order to start a new device/host task
        taskENTER_CRITICAL();
        xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
        taskEXIT_CRITICAL();
  #endif
      }
    }
    // Device Start-of-Frame received
    if (Is_usb_sof() && Is_usb_sof_interrupt_enabled())
    {
      Usb_ack_sof();
      Usb_sof_action();
    }
    // Device Suspend event (no more USB activity detected)
    if (Is_usb_suspend() && Is_usb_suspend_interrupt_enabled())
    {
      Usb_ack_suspend();
      Usb_enable_wake_up_interrupt();
      (void)Is_usb_wake_up_interrupt_enabled();
      Usb_freeze_clock();
      Usb_send_event(EVT_USB_SUSPEND);
      Usb_suspend_action();
    }
    // Wake-up event (USB activity detected): Used to resume
    if (Is_usb_wake_up() && Is_usb_wake_up_interrupt_enabled())
    {
      Usb_unfreeze_clock();
      (void)Is_usb_clock_frozen();
      Usb_ack_wake_up();
      Usb_disable_wake_up_interrupt();
      Usb_wake_up_action();
      Usb_send_event(EVT_USB_WAKE_UP);
    }
    // Resume state bus detection
    if (Is_usb_resume() && Is_usb_resume_interrupt_enabled())
    {
      Usb_disable_wake_up_interrupt();
      Usb_ack_resume();
      Usb_disable_resume_interrupt();
      Usb_resume_action();
      Usb_send_event(EVT_USB_RESUME);
    }
    // USB bus reset detection
    if (Is_usb_reset() && Is_usb_reset_interrupt_enabled())
    {
      Usb_ack_reset();
      usb_init_device();
      Usb_reset_action();
      Usb_send_event(EVT_USB_RESET);
    }
  }
#endif  // End DEVICE FEATURE MODE

// ---------- HOST events management -------------------------------------------
#if USB_HOST_FEATURE == true
  #if USB_DEVICE_FEATURE == true
  // If both device and host features are enabled, check if host mode is engaged
  // (accessing the USB registers of a non-engaged mode, even with load operations,
  // may corrupt USB FIFO data).
  else
  #endif
  {
    // The device has been disconnected
    if (Is_host_device_disconnection() && Is_host_device_disconnection_interrupt_enabled())
    {
      host_disable_all_pipes();
      Host_ack_device_disconnection();
  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
      reset_it_pipe_str();
  #endif
      device_state = DEVICE_UNATTACHED;
      LOG_STR(log_device_disconnected);
      Usb_send_event(EVT_HOST_DISCONNECTION);
      Host_device_disconnection_action();
  #ifdef FREERTOS_USED
      // Release the semaphore in order to start a new device/host task
      taskENTER_CRITICAL();
      xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
      taskEXIT_CRITICAL();
  #endif
    }
    // Device connection
    if (Is_host_device_connection() && Is_host_device_connection_interrupt_enabled())
    {
      Host_ack_device_connection();
      host_disable_all_pipes();
      Host_device_connection_action();
    }
    // Host Start-of-Frame has been sent
    if (Is_host_sof() && Is_host_sof_interrupt_enabled())
    {
      Host_ack_sof();
      Usb_send_event(EVT_HOST_SOF);
#if (USB_HIGH_SPEED_SUPPORT==true)
      if( Is_usb_full_speed_mode() )
      {
         private_sof_counter++;
      }else{
         private_sof_counter_HS++;
         if( 0 == (private_sof_counter_HS%8) )
         {
            private_sof_counter++;
         }
      }
#else
      private_sof_counter++;
#endif
      // Delay time-out management for interrupt transfer mode in host mode
  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE && TIMEOUT_DELAY_ENABLE == ENABLE
      if (private_sof_counter >= 250) // Count 250 ms (SOF @ 1 ms)
      {
        private_sof_counter = 0;
        for (i = 0; i < MAX_PEP_NB; i++)
        {
          if (it_pipe_str[i].enable &&
              ++it_pipe_str[i].timeout > TIMEOUT_DELAY && Host_get_pipe_type(i) != TYPE_INTERRUPT)
          {
            it_pipe_str[i].enable = false;
            it_pipe_str[i].status = PIPE_DELAY_TIMEOUT;
            Host_reset_pipe(i);
            if (!is_any_interrupt_pipe_active() && !g_sav_int_sof_enable) // If no more transfer is armed
            {
              Host_disable_sof_interrupt();
            }
            it_pipe_str[i].handler(PIPE_DELAY_TIMEOUT, it_pipe_str[i].nb_byte_processed);
          }
        }
      }
  #endif
      Host_sof_action();
    }
    // Host Wake-up has been received
    if (Is_host_hwup() && Is_host_hwup_interrupt_enabled())
    {
      // CAUTION: HWUP can be cleared only when USB clock is active (not frozen)!
      //! @todo Implement this on the silicon version
      //Pll_start_auto();               // First Restart the PLL for USB operation
      //Wait_pll_ready();               // Make sure PLL is locked
      Usb_unfreeze_clock();           // Enable clock on USB interface
      (void)Is_usb_clock_frozen();    // Make sure USB interface clock is enabled
      Host_disable_hwup_interrupt();  // Wake-up interrupt should be disabled as host is now awoken!
      Host_ack_hwup();                // Clear HWUP interrupt flag
      Usb_send_event(EVT_HOST_HWUP);  // Send software event
      Host_hwup_action();             // Map custom action
    }
  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
    // Host pipe interrupts
    while ((i = Host_get_interrupt_pipe_number()) < MAX_PEP_NB) usb_pipe_interrupt(i);
  #endif
  }
#endif  // End HOST FEATURE MODE

#ifdef FREERTOS_USED
  return task_woken;
#endif
}
Example #13
0
ISR(usb_general_interrupt, AVR32_USBB_IRQ_GROUP, USB_INT_LEVEL)

#endif
{
#ifdef FREERTOS_USED
  portBASE_TYPE task_woken = pdFALSE;
#endif
  uint8_t i;
  /* avoid Cppcheck Warning */
  UNUSED(i);

// ---------- DEVICE/HOST events management ------------------------------------
#if USB_DEVICE_FEATURE == true && USB_HOST_FEATURE == true
  // ID pin change detection
  if (Is_usb_id_transition() && Is_usb_id_interrupt_enabled())
  {
    g_usb_mode = (Is_usb_id_device()) ? USB_MODE_DEVICE : USB_MODE_HOST;
    Usb_ack_id_transition();
    if (g_usb_mode != g_old_usb_mode) // Basic debounce
    {
      // Previously in device mode, check if disconnection was detected
      if (g_old_usb_mode == USB_MODE_DEVICE)
      {
        if (usb_connected)
        {
          // Device mode diconnection actions
          usb_connected = false;
          usb_configuration_nb = 0;
          Usb_vbus_off_action();
        }
      }
      // Previously in host mode, check if disconnection was detected
      else if (Is_host_attached())
      {
        // Host mode diconnection actions
        device_state = DEVICE_UNATTACHED;
        Host_device_disconnection_action();
      }
      LOG_STR(log_pin_id_changed);
      Usb_send_event((Is_usb_device()) ? EVT_USB_DEVICE_FUNCTION :
                                         EVT_USB_HOST_FUNCTION);
      Usb_id_transition_action();
      //! @todo ID pin hot state change!!!
      // Preliminary management: HARDWARE RESET!!!
  #if ID_PIN_CHANGE_GENERATE_RESET == ENABLE
      // Hot ID transition generates CPU reset
      Usb_disable();
      Usb_disable_otg_pad();
    #ifdef FREERTOS_USED
      // Release the semaphore in order to start a new device/host task
      taskENTER_CRITICAL();
      xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
      taskEXIT_CRITICAL();
    #else
#if defined(CPU_RESET_CALLBACK)
      CPU_RESET_CALLBACK();
#endif
      Reset_CPU();
    #endif
  #endif
      g_old_usb_mode = g_usb_mode;  // Store current USB mode, for mode change detection
    }
  }
#endif  // End DEVICE/HOST FEATURE MODE

// ---------- DEVICE events management -----------------------------------------
#if USB_DEVICE_FEATURE == true
  #if USB_HOST_FEATURE == true
  // If both device and host features are enabled, check if device mode is engaged
  // (accessing the USB registers of a non-engaged mode, even with load operations,
  // may corrupt USB FIFO data).
  if (Is_usb_device())
  #endif
  {
    // VBus state detection
    if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled())
    {
      Usb_ack_vbus_transition();
      if (Is_usb_vbus_high())
      {
        usb_start_device();
        Usb_send_event(EVT_USB_POWERED);
        Usb_vbus_on_action();
      }
      else
      {
        Usb_unfreeze_clock();
        Usb_detach();
        usb_connected = false;
        usb_configuration_nb = 0;
        Usb_send_event(EVT_USB_UNPOWERED);
        Usb_vbus_off_action();
  #ifdef FREERTOS_USED
        // Release the semaphore in order to start a new device/host task
        taskENTER_CRITICAL();
        xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
        taskEXIT_CRITICAL();
  #endif
      }
    }
    // Device Start-of-Frame received
    if (Is_usb_sof() && Is_usb_sof_interrupt_enabled())
    {
      Usb_ack_sof();
      Usb_sof_action();
    }
    // Device Suspend event (no more USB activity detected)
    if (Is_usb_suspend() && Is_usb_suspend_interrupt_enabled())
    {
      Usb_ack_suspend();
      Usb_enable_wake_up_interrupt();
      (void)Is_usb_wake_up_interrupt_enabled();
      Usb_freeze_clock();
      Usb_send_event(EVT_USB_SUSPEND);
      Usb_suspend_action();
    }
    // Wake-up event (USB activity detected): Used to resume
    if (Is_usb_wake_up() && Is_usb_wake_up_interrupt_enabled())
    {
      Usb_unfreeze_clock();
      (void)Is_usb_clock_frozen();
      Usb_ack_wake_up();
      Usb_disable_wake_up_interrupt();
      Usb_wake_up_action();
      Usb_send_event(EVT_USB_WAKE_UP);
    }
    // Resume state bus detection
    if (Is_usb_resume() && Is_usb_resume_interrupt_enabled())
    {
      Usb_disable_wake_up_interrupt();
      Usb_ack_resume();
      Usb_disable_resume_interrupt();
      Usb_resume_action();
      Usb_send_event(EVT_USB_RESUME);
    }
    // USB bus reset detection
    if (Is_usb_reset() && Is_usb_reset_interrupt_enabled())
    {
      Usb_ack_reset();
      usb_init_device();
      Usb_reset_action();
      Usb_send_event(EVT_USB_RESET);
    }
  }
#endif  // End DEVICE FEATURE MODE

// ---------- HOST events management -------------------------------------------
#if USB_HOST_FEATURE == true
  #if USB_DEVICE_FEATURE == true
  // If both device and host features are enabled, check if host mode is engaged
  // (accessing the USB registers of a non-engaged mode, even with load operations,
  // may corrupt USB FIFO data).
  else
  #endif
  {
    // The device has been disconnected
    if (Is_host_device_disconnection() && Is_host_device_disconnection_interrupt_enabled())
    {
      host_disable_all_pipes();
      Host_ack_device_disconnection();
  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
      reset_it_pipe_str();
  #endif
  #ifdef HOST_VBUS_LOW_TIMEOUT
      cpu_set_timeout(HOST_VBUS_LOW_TIMEOUT, &timer_vbus_low);
      device_state = DEVICE_VBUS_LOW;
  #else
      device_state = DEVICE_UNATTACHED;
  #endif
      LOG_STR(log_device_disconnected);
      Usb_send_event(EVT_HOST_DISCONNECTION);
      Host_device_disconnection_action();
  #ifdef FREERTOS_USED
      // Release the semaphore in order to start a new device/host task
      taskENTER_CRITICAL();
      xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
      taskEXIT_CRITICAL();
  #endif
    }
    // Device connection
    if (Is_host_device_connection() && Is_host_device_connection_interrupt_enabled())
    {
      Host_ack_device_connection();
      host_disable_all_pipes();
      Usb_send_event(EVT_HOST_CONNECTION);
      Host_device_connection_action();
    }
    // Host Start-of-Frame has been sent
    if (Is_host_sof() && Is_host_sof_interrupt_enabled())
    {
      Host_ack_sof();
      Usb_send_event(EVT_HOST_SOF);
      private_sof_counter++;
      // Delay time-out management for interrupt tranfer mode in host mode
  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE && TIMEOUT_DELAY_ENABLE == ENABLE
      if (private_sof_counter >= 250) // Count 250 ms (SOF @ 1 ms)
      {
        private_sof_counter = 0;
        for (i = 0; i < MAX_PEP_NB; i++)
        {
          if (it_pipe_str[i].enable &&
              ++it_pipe_str[i].timeout > TIMEOUT_DELAY && Host_get_pipe_type(i) != TYPE_INTERRUPT)
          {
            it_pipe_str[i].enable = false;
            it_pipe_str[i].status = PIPE_DELAY_TIMEOUT;
            Host_reset_pipe(i);
            if (!is_any_interrupt_pipe_active() && !g_sav_int_sof_enable) // If no more transfer is armed
            {
              Host_disable_sof_interrupt();
            }
            it_pipe_str[i].handler(PIPE_DELAY_TIMEOUT, it_pipe_str[i].nb_byte_processed);
          }
        }
      }
  #endif
      Host_sof_action();
    }
    // Host Wake-up has been received
    if (Is_host_hwup() && Is_host_hwup_interrupt_enabled())
    {
      // CAUTION: HWUP can be cleared only when USB clock is active (not frozen)!
      //! @todo Implement this on the silicon version
      //Pll_start_auto();               // First Restart the PLL for USB operation
      //Wait_pll_ready();               // Make sure PLL is locked
      Usb_unfreeze_clock();           // Enable clock on USB interface
      (void)Is_usb_clock_frozen();    // Make sure USB interface clock is enabled
      Host_disable_hwup_interrupt();  // Wake-up interrupt should be disabled as host is now awoken!
      Host_ack_hwup();                // Clear HWUP interrupt flag
      Usb_send_event(EVT_HOST_HWUP);  // Send software event
      Host_hwup_action();             // Map custom action
    }

    Host_int_action();

    while ((i = Host_get_interrupt_pipe_number()) < MAX_PEP_NB)
    {
      if (Is_host_in_received(i) && Is_host_in_received_interrupt_enabled(i))
      {
        Host_freeze_pipe(i);
        Host_disable_in_received_interrupt(i);
      }
    }

  #if defined(USB_HIGH_SPEED_SUPPORT) && USB_HIGH_SPEED_SUPPORT == true && \
    defined(PIPE_AUDIO_IN)
    // Workaround - freeze the IN audio pipe
    if (Is_host_in_received(PIPE_AUDIO_IN))
    {
      extern void workaround_freeze_iso_in(void);
      workaround_freeze_iso_in();
    }
  #endif // USB_HIGH_SPEED_SUPPORT == true

  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
    // Host pipe interrupts
    while ((i = Host_get_interrupt_pipe_number()) < MAX_PEP_NB) usb_pipe_interrupt(i);
  #endif
  }
#endif  // End HOST FEATURE MODE

#ifdef FREERTOS_USED
  return task_woken;
#endif
}
Example #14
0
	void UART2_IRQHandler(void)
	{
		uint32_t intsrc, tmp, tmp1;
		char c = 0;
		uint32_t bToRecv=256, timeOut=0;
		uint8_t recvData = 0;
		/* Determine the interrupt source */
		intsrc = (LPC_UART2->IIR & 0x03CF);
		tmp = intsrc & UART_IIR_INTID_MASK;

		// Receive Line Status
		if (tmp == UART_IIR_INTID_RLS)
		{
			// Check line status
			tmp1 = ((LPC_UART2->LSR) & UART_LSR_BITMASK);
			// Mask out the Receive Ready and Transmit Holding empty status
			tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \
					| UART_LSR_BI | UART_LSR_RXFE);
			// If any error exist
			if (tmp1)
			{
					while(1);
			}
		}

		// Receive Data Available or Character time-out
		if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI))
		{
			while (bToRecv)
			{
				if (!(LPC_UART2->LSR & UART_LSR_RDR))
				{
					printf("here1\n");
					gBuffer[bRecvInt++] = '\0';
					printf("-->%s\n",gBuffer);
					bRecvInt =0;
					xSemaphoreGiveFromISR(gUartSemaphore,NULL);
					break;
				}
				else
				{
					recvData= LPC_UART2->RBR;
					printf("%c\n",recvData);

					if ((recvData == 0xA) | (recvData == 0xD))
					{
						continue;
					}
					//delay_ms(5);
					printf("%c\n",recvData);
					gBuffer[bRecvInt] = recvData;
					bRecvInt++;
					bToRecv--;
				}
			}

		}

		// Transmit Holding Empty
		if (tmp == UART_IIR_INTID_THRE)
		{
				//UART_IntTransmit();
		}
		//bRecvInt ++;
		//gBuffer[bRecv] = '\0';

	}
Example #15
0
/*------------------------------------------------------------------------------
 * MSS I2C interrupt service routine.
 *------------------------------------------------------------------------------
 * Parameters:
 *
 * 	mss_i2c_instance_t * this_i2c:
 * 		Pointer to the mss_i2c_instance_t data structure holding all data related to
 * 		the	MSS I2C instance that generated the interrupt.
 */
static void mss_i2c_isr
(
    mss_i2c_instance_t * this_i2c
)
{
    volatile uint8_t status;
    uint8_t data;
    uint8_t hold_bus;
    uint8_t clear_irq = 1;
    long lHigherPriorityTaskWoken = pdFALSE;
    configASSERT( ( this_i2c->xI2CCompleteSemaphore ) );

    ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );

    status = this_i2c->hw_reg->STATUS;

    switch( status ) {
        /************** MASTER TRANSMITTER / RECEIVER *******************/

        case ST_START: /* start has been xmt'd */
        case ST_RESTART: /* repeated start has been xmt'd */
            this_i2c->hw_reg_bit->CTRL_STA = 0x0;
            this_i2c->hw_reg->DATA = this_i2c->target_addr;
            this_i2c->hw_reg_bit->DATA_DIR = this_i2c->dir;

            this_i2c->tx_idx = 0;
            this_i2c->rx_idx = 0;
            break;

        case ST_LOST_ARB:
            /* Set start bit.  Let's keep trying!  Don't give up! */
            this_i2c->hw_reg_bit->CTRL_STA = 0x01;
            break;

        /******************* MASTER TRANSMITTER *************************/
        case ST_SLAW_ACK:
            /* call address has been xmt'd with ACK, time to send data byte and increment index. */
            if ( this_i2c->tx_idx < this_i2c->tx_size ) {
                /* load data byte */
                this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
            } else {
                NVIC_DisableIRQ( this_i2c->irqn );
            }
            break;

        case ST_SLAW_NACK:
#if 0
            /* SLA+W has been transmitted; not ACK has been received - let's stop. */
            this_i2c->hw_reg_bit->CTRL_STO = 0x01;
            this_i2c->status = MSS_I2C_FAILED;
#endif
            /* call address has been xmt'd with ACK, time to send data byte and increment index. */
            if ( this_i2c->tx_idx < this_i2c->tx_size ) {
                /* load data byte */
                this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
            } else {
                NVIC_DisableIRQ( this_i2c->irqn );
            }
            break;

        case ST_TX_DATA_ACK:
            /* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */
            if (this_i2c->tx_idx < this_i2c->tx_size) {
                this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
            } else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION ) {
                /* We are finished sending the address offset part of a random read transaction.
                 * It is is time to send a restart in order to change direction. */
                this_i2c->dir = READ_DIR;
                this_i2c->hw_reg_bit->CTRL_STA = 0x01;
            } else { /* done sending. let's stop */
                hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS;
                if ( hold_bus == 0 ) {
                    this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */
                } else {
                    NVIC_DisableIRQ( this_i2c->irqn );
                    clear_irq = 0;
                }
                this_i2c->status = MSS_I2C_SUCCESS;
                xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
            }
            break;

        case ST_TX_DATA_NACK:
#if 0
            /* data byte SENT, ACK to be received
            * In fact, this means we've received a NACK (This may not be
            * obvious, but if we've rec'd an ACK then we would be in state
            * 0x28!) hence, let's send a stop bit
            */
            this_i2c->hw_reg_bit->CTRL_STO = 0x01;
            this_i2c->status = MSS_I2C_FAILED;
#endif
            /* data byte has been xmt'd with ACK, time to send stop bit or repeated start. */
            if (this_i2c->tx_idx < this_i2c->tx_size) {
                this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
            } else if ( this_i2c->transaction == MASTER_RANDOM_READ_TRANSACTION ) {
                /* We are finished sending the address offset part of a random read transaction.
                 * It is is time to send a restart in order to change direction. */
                this_i2c->dir = READ_DIR;
                this_i2c->hw_reg_bit->CTRL_STA = 0x01;
            } else { /* done sending. let's stop */
                hold_bus = this_i2c->options & MSS_I2C_HOLD_BUS;
                if ( hold_bus == 0 ) {
                    this_i2c->hw_reg_bit->CTRL_STO = 0x01; /*xmt stop condition */
                } else {
                    NVIC_DisableIRQ( this_i2c->irqn );
                    clear_irq = 0;
                }
                this_i2c->status = MSS_I2C_SUCCESS;
                xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
            }
            break;

        /********************* MASTER (or slave?) RECEIVER *************************/

        /* STATUS codes 08H, 10H, 38H are all covered in MTX mode */
        case ST_SLAR_ACK: /* SLA+R tx'ed. */
            /* Let's make sure we ACK the first data byte received (set AA bit in CTRL) unless
             * the next byte is the last byte of the read transaction.
             */
            if( this_i2c->rx_size > 1 ) {
                this_i2c->hw_reg_bit->CTRL_AA = 0x01;
            } else {
                this_i2c->hw_reg_bit->CTRL_AA = 0x00;
            }
            break;

        case ST_SLAR_NACK: /* SLA+R tx'ed; let's release the bus (send a stop condition) */
            this_i2c->hw_reg_bit->CTRL_STO = 0x01;
            this_i2c->status = MSS_I2C_FAILED;
            xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
            break;

        case ST_RX_DATA_ACK: /* Data byte received, ACK returned */
            /* First, get the data */
            this_i2c->rx_buffer[this_i2c->rx_idx++] = this_i2c->hw_reg->DATA;

            if( this_i2c->rx_idx >= this_i2c->rx_size - 1) {
                /* If we're at the second last byte, let's set AA to 0 so
                 * we return a NACK at the last byte. */
                this_i2c->hw_reg_bit->CTRL_AA = 0x00;
            }
            break;

        case ST_RX_DATA_NACK: /* Data byte received, NACK returned */
            /* Get the data, then send a stop condition */
            this_i2c->rx_buffer[this_i2c->rx_idx++] = this_i2c->hw_reg->DATA;

            hold_bus = this_i2c->options &  MSS_I2C_HOLD_BUS;
            if ( hold_bus == 0 ) {
                this_i2c->hw_reg_bit->CTRL_STO = 0x01;  /*xmt stop condition */
            } else {
                NVIC_DisableIRQ( this_i2c->irqn );
                clear_irq = 0;
            }

            this_i2c->status = MSS_I2C_SUCCESS;
//			xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
            break;

        /******************** SLAVE RECEIVER **************************/
        case ST_GCA_NACK: /* NACK after, GCA addressing */
        case ST_SLA_NACK: /* Get Data, but also re-enable AA (assert ack) bit for future transmissions */
            if ( this_i2c->rx_buffer != 0 ) {
                this_i2c->rx_buffer[this_i2c->rx_idx] = this_i2c->hw_reg->DATA;
            }
            this_i2c->hw_reg_bit->CTRL_AA = 0x01;
            break;

        case ST_SLAVE_SLAW: /* SLA+W received, ACK returned */
            this_i2c->transaction = WRITE_SLAVE_TRANSACTION;
            this_i2c->rx_idx = 0;
            this_i2c->random_read_addr = 0;
#ifndef INCLUDE_SLA_IN_RX_PAYLOAD
            /* Only break from this case if the slave address must NOT be included at the
             * beginning of the received write data. */
            break;
#endif
        case ST_GCA_ACK: /* DATA received; ACK sent after GCA */
        case ST_RDATA: /* DATA received; must clear DATA register */
            if (this_i2c->rx_idx >= this_i2c->rx_size - 2) {
                this_i2c->hw_reg_bit->CTRL_AA = 0x00;   /* send a NACK when done (next reception) */
            }
            data = this_i2c->hw_reg->DATA;
            this_i2c->rx_buffer[this_i2c->rx_idx++] = data;
            this_i2c->random_read_addr = (this_i2c->random_read_addr << 8) + data;

            break;

        case ST_RSTOP:
            /* STOP or repeated START occured. */
            /* We cannot be sure if the transaction has actually completed as
             * this hardware state reports that either a STOP or repeated START
             * condition has occured. We assume that this is a repeated START
             * if the transaction was a write from the master to this point.*/
            if ( this_i2c->transaction == WRITE_SLAVE_TRANSACTION ) {
                if ( this_i2c->rx_idx == this_i2c->slave_mem_offset_length ) {
                    this_i2c->transaction = RANDOM_READ_SLAVE_TRANSACTION;
                    this_i2c->tx_idx = this_i2c->random_read_addr;
                } else {
                    /* Call the slave's write transaction handler if it exists. */
                    if ( this_i2c->slave_write_handler != 0 ) {
                        mss_i2c_slave_handler_ret_t h_ret;
                        h_ret = this_i2c->slave_write_handler( this_i2c->rx_buffer, (uint16_t)this_i2c->rx_idx );
                        if ( MSS_I2C_REENABLE_SLAVE_RX == h_ret ) {
                            this_i2c->hw_reg_bit->CTRL_AA = 0x01;
                        } else {
                            this_i2c->hw_reg_bit->CTRL_AA = 0x00;
                        }
                    }
                }
            }
            /* Mark any previous master write transaction as complete. */
            this_i2c->status = MSS_I2C_SUCCESS;
//			xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );
            break;

        case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */
        case ST_SLV_LA: /* Arbitr. lost (SLA rec'd) */
        case ST_GCA: /* General call address received, ACK returned */
        case ST_GCA_LA: /* Arbitr. lost (GCA rec'd) */
            /* do nothing */
            break;

        /****************** SLAVE TRANSMITTER **************************/
        case ST_SLAVE_SLAR_ACK: /* SLA+R received, ACK returned */
        case ST_SLARW_LA: /* Arbitration lost, and: */
        case ST_RACK: /* Data tx'ed, ACK received */
            if ( status == ST_SLAVE_SLAR_ACK ) {
                this_i2c->transaction = READ_SLAVE_TRANSACTION;
                this_i2c->random_read_addr = 0;
            }
            /* Load the data, and determine if it is the last one */
            this_i2c->hw_reg->DATA = this_i2c->tx_buffer[this_i2c->tx_idx++];
            if (this_i2c->tx_idx >= this_i2c->tx_size - 1) { /* last byte? */
                this_i2c->hw_reg_bit->CTRL_AA = 0x00;
                /* Next read transaction will result in slave's transmit buffer
                 * being sent from the first byte. */
                this_i2c->tx_idx = 0;
            }
            break;

        case ST_SLAVE_RNACK:	/* Data byte has been transmitted; not-ACK has been received. */
            /* We assume that the transaction will be stopped by the master.
             * Reset tx_idx so that a subsequent read will result in the slave's
             * transmit buffer being sent from the first byte. */
            this_i2c->tx_idx = 0;
            break;

        case ST_FINAL: /* Last Data byte tx'ed, ACK recieved */
        default:
            /* do nothing */
            break;
    }

    if ( clear_irq ) {
        /* clear interrupt. */
        this_i2c->hw_reg_bit->CTRL_SI = 0x00;
    }

    /* Read the status register to ensure the last I2C registers write took place
     * in a system built around a bus making use of posted writes. */
    status = this_i2c->hw_reg->STATUS;

    portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
Example #16
0
void USART3_IRQHandler(void)
{
    volatile u32 tem_reg;
    volatile u16 u16BufferUsedLen = 0;
    BaseType_t xHigherPriorityTaskWoken, xResult;

    // xHigherPriorityTaskWoken must be initialised to pdFALSE.
    xHigherPriorityTaskWoken = pdFALSE;
    
    // error happen
    if(USART_GetITStatus(USART3, USART_IT_PE) != RESET)
    {
        USART_ClearITPendingBit(USART3, USART_IT_PE);
        xSerialRxParityFlag = DMA_UART_PACKET_PARITY_ERR;
    }
    
    // uart idle interrupt
    if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)
    {
        USART_ClearITPendingBit(USART3, USART_IT_IDLE);
        DMA_ClearFlag(DMA1_FLAG_GL3);//clear all interrupt flags     
        DMA_Cmd(DMA1_Channel3, DISABLE); //close DMA incase receive data while handling
        
        xResult = xSemaphoreTakeFromISR( xSerialRxHandleLock, &xHigherPriorityTaskWoken);
        if( pdTRUE == xResult)
        {
            if (uart3_rx_dma_buf.IdleBufferIndex) //buf1 busy, buf2 idle
            {
                u16BufferUsedLen = uart3_rx_dma_buf.nBuff1MaxLength - DMA_GetCurrDataCounter(DMA1_Channel3); 
                if (u16BufferUsedLen > 0)
                {
                    uart3_rx_dma_buf.nBuff1Offset = u16BufferUsedLen;
                    DMA1_Channel3->CMAR = (uint32_t)uart3_rx_dma_buf.pPingPongBuff2;
                    DMA1_Channel3->CNDTR = uart3_rx_dma_buf.nBuff2MaxLength;
                    uart3_rx_dma_buf.IdleBufferIndex = 0;
                }
            }
            else
            {
                u16BufferUsedLen = uart3_rx_dma_buf.nBuff2MaxLength - DMA_GetCurrDataCounter(DMA1_Channel3); 
                if (u16BufferUsedLen > 0)
                {
                    uart3_rx_dma_buf.nBuff2Offset = u16BufferUsedLen;
                    DMA1_Channel3->CMAR = (uint32_t)uart3_rx_dma_buf.pPingPongBuff1;
                    DMA1_Channel3->CNDTR = uart3_rx_dma_buf.nBuff1MaxLength;
                    uart3_rx_dma_buf.IdleBufferIndex = 1;
                }
            }
            xResult = xSemaphoreGiveFromISR( xSerialRxHandleLock ,&xHigherPriorityTaskWoken);

            if (u16BufferUsedLen > 0)
            {
                //boardcast message to handle
                xResult = xEventGroupSetBitsFromISR(
                                xUart3RxEventGroup,	// The event group being updated.
                                UART_DMA_RX_INCOMPLETE_EVENT_BIT,// The bits being set.
                                &xHigherPriorityTaskWoken );
            } //End if u16BufferUsedLen > 0
        }// End if pdTRUE == xSemaphoreTakeFromISR
        DMA_Cmd(DMA1_Channel3, ENABLE);                 //open DMA after handled
        
        //clear Idle flag by read SR and DR
        tem_reg = USART3->SR;
        tem_reg = USART3->DR;
        tem_reg = tem_reg; // slove warning 
    }// End if USART_IT_IDLE
    
    if(USART_GetITStatus(USART3, USART_IT_FE | USART_IT_NE) != RESET)
    {
        USART_ClearITPendingBit(USART3, USART_IT_FE | USART_IT_NE);
    }

    if( xResult == pdPASS )
    {
        // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
        // switch should be requested.  The macro used is port specific and 
        // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - 
        // refer to the documentation page for the port being used.
        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    }
}
Example #17
0
void UART_IRQHandler(void){
	uint8_t IIRValue, LSRValue;
	uint8_t temp = temp;
	static signed portBASE_TYPE xHigherPriorityTaskWoken;

	IIRValue = LPC_UART->IIR;

	IIRValue >>= 1; /* skip pending bit in IIR */
	IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
	if (IIRValue == IIR_RLS) /* Receive Line Status */
	{
		LSRValue = LPC_UART->LSR;
		/* Receive Line Status */
		if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI)) {
			/* There are errors or break interrupt */
			/* Read LSR will clear the interrupt */
			temp = LPC_UART->RBR; /* temp read on RX to clear
			 interrupt, then bail out */
			return;
		}
		if (LSRValue & LSR_RDR) /* Receive Data Ready */
		{
			/* If no error on RLS, normal ready, save into the data buffer. */
			/* Note: read RBR will clear the interrupt */
			temp = LPC_UART->RBR;
		}
	}
	else if (IIRValue == IIR_RDA) /* Receive Data Available */
	{
		/* Receive Data Available */
		temp = LPC_UART->RBR;

		if (InCount == 0)
		{
			if (temp == 0xAA)
			{
				InSum = 0xAA;
				InCount++;
			}
		}
		else if (InCount == 1)
		{
			if (temp == 0x55)
			{
				InCount++;
				InSum += 0x55;
			}
			else if(temp != 0xAA)
			{
				InCount = 0;
			}
		}
		else if (InCount == 2)
		{
			InTempLength = temp;
			if(InTempLength > MAX_PAYLOAD_LENGTH+4)
				InCount = 0;
			else
			{
				InCount++;
				InSum += temp;
			}
		}
		else if(InCount == 3)
		{
			InCount++;
			InSum += temp;
		}
		else if(InCount < MAX_PAYLOAD_LENGTH+4)
		{
			InputPayload[InBuff][InCount-4] = temp;
			InCount++;
			InSum += temp;

			if (InCount >= InTempLength)
			{
				if (InSum == 0)
				{
					InBuff = (InBuff+1) & 0x3;
					InLength = InTempLength - 4;
					NewInData = 1;
					xHigherPriorityTaskWoken = pdFALSE;
					if(xSerialSemaphore != 0)
						xSemaphoreGiveFromISR(xSerialSemaphore,&xHigherPriorityTaskWoken);
				}
				InCount = 0;
				InTempLength = 0;
			}
		}
		else
		{
			InCount = 0;
		}
	}
	else if (IIRValue == IIR_CTI) /* Character timeout indicator */
	{
		/* Character Time-out indicator */
	}
	else if (IIRValue == IIR_THRE) /* THRE, transmit holding register empty */
	{
		/* THRE interrupt */
		if (OutCount < OutLength) {
			LPC_UART->THR = OutputBuff[OutCount];
			OutCount++;
		}
		else
		{
			OutCount = 0;
			OutLength = 0;
			OutBusy = 0;
		}
	}
	return;
}
Example #18
0
static void enable_usart1(void)
{
	/* RCC Initialization */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

	/* GPIO Initialization */
	GPIO_InitTypeDef GPIO_InitStruct = {
		.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10,
		.GPIO_Mode = GPIO_Mode_AF,
		.GPIO_OType = GPIO_OType_PP,
		.GPIO_PuPd = GPIO_PuPd_UP,
		.GPIO_Speed = GPIO_Speed_50MHz
	};

	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	/* USART3 Initialization */
	USART_InitTypeDef USART_InitStruct = {
		.USART_BaudRate = 57600,
		.USART_WordLength = USART_WordLength_8b,
		.USART_StopBits = USART_StopBits_1,
		.USART_Parity = USART_Parity_No,
		.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
		.USART_Mode = USART_Mode_Rx | USART_Mode_Tx
	};

	USART_Init(USART1, &USART_InitStruct);
	USART_Cmd(USART1, ENABLE);
}

static void enable_usart2(void)
{
	/* RCC Initialization */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

	/* GPIO Initialization */
	GPIO_InitTypeDef GPIO_InitStruct = {
		.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6,
		.GPIO_Mode = GPIO_Mode_AF,
		.GPIO_OType = GPIO_OType_PP,
		.GPIO_PuPd = GPIO_PuPd_UP,
		.GPIO_Speed = GPIO_Speed_50MHz
	};

	GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);
	GPIO_Init(GPIOD, &GPIO_InitStruct);

	/* USART2 Initialization */
	USART_InitTypeDef USART_InitStruct = {
		.USART_BaudRate = 9600,
		.USART_WordLength = USART_WordLength_8b,
		.USART_StopBits = USART_StopBits_1,
		.USART_Parity = USART_Parity_No,
		.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
		.USART_Mode = USART_Mode_Rx | USART_Mode_Tx
	};

	USART_Init(USART2, &USART_InitStruct);
	USART_Cmd(USART2, ENABLE);

	/* DMA Initialization */
	DMA_DeInit(DMA1_Stream6);
	while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE);
}

static void enable_usart3(void)
{
	/* RCC Initialization */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

	/* GPIO Initialization */
	GPIO_InitTypeDef GPIO_InitStruct = {
		.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9,
		.GPIO_Mode = GPIO_Mode_AF,
		.GPIO_OType = GPIO_OType_PP,
		.GPIO_PuPd = GPIO_PuPd_UP,
		.GPIO_Speed = GPIO_Speed_50MHz
	};

	GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);
	GPIO_Init(GPIOD, &GPIO_InitStruct);

	/* USART3 Initialization */
	USART_InitTypeDef USART_InitStruct = {
		.USART_BaudRate = 57600,
		.USART_WordLength = USART_WordLength_8b,
		.USART_StopBits = USART_StopBits_1,
		.USART_Parity = USART_Parity_No,
		.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
		.USART_Mode = USART_Mode_Rx | USART_Mode_Tx
	};

	USART_Init(USART3, &USART_InitStruct);
	USART_Cmd(USART3, ENABLE);
	USART_ClearFlag(USART3, USART_FLAG_TC);

	USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

	/* NVIC Initialization */
	NVIC_InitTypeDef NVIC_InitStruct = {
		.NVIC_IRQChannel = USART3_IRQn,
		.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1,
		.NVIC_IRQChannelSubPriority = 0,
		.NVIC_IRQChannelCmd = ENABLE
	};
	NVIC_Init(&NVIC_InitStruct);
}

static void enable_usart4(void)
{
	/* RCC Initialization */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);

	/* GPIO Initialization */
	GPIO_InitTypeDef GPIO_InitStruct = {
		.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11,
		.GPIO_Mode = GPIO_Mode_AF,
		.GPIO_OType = GPIO_OType_PP,
		.GPIO_PuPd = GPIO_PuPd_UP,
		.GPIO_Speed = GPIO_Speed_50MHz
	};

	GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4);
	GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4);
	GPIO_Init(GPIOC, &GPIO_InitStruct);

	/* USART4 Initialization */
	USART_InitTypeDef USART_InitStruct = {
		.USART_BaudRate = 57600,
		.USART_WordLength = USART_WordLength_8b,
		.USART_StopBits = USART_StopBits_1,
		.USART_Parity = USART_Parity_No,
		.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
		.USART_Mode = USART_Mode_Rx | USART_Mode_Tx
	};

	USART_Init(UART4, &USART_InitStruct);
	USART_Cmd(UART4, ENABLE);
}

static void enable_usart5(void)
{
	/* RCC Initialization */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);

	/* GPIO Initialization */
	GPIO_InitTypeDef GPIO_InitStruct = {
		.GPIO_Pin = GPIO_Pin_2,
		.GPIO_Mode = GPIO_Mode_AF,
		.GPIO_OType = GPIO_OType_PP,
		.GPIO_PuPd = GPIO_PuPd_UP,
		.GPIO_Speed = GPIO_Speed_50MHz
	};

	GPIO_Init(GPIOD, &GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;

	GPIO_Init(GPIOC, &GPIO_InitStruct);

	GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
	GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);

	/* USART5 Initialization */
	USART_InitTypeDef USART_InitStruct = {
		.USART_BaudRate = 57600,
		.USART_WordLength = USART_WordLength_8b,
		.USART_StopBits = USART_StopBits_1,
		.USART_Parity = USART_Parity_No,
		.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
		.USART_Mode = USART_Mode_Rx | USART_Mode_Tx
	};

	USART_Init(UART5, &USART_InitStruct);
	USART_Cmd(UART5, ENABLE);
}

static void enable_usart8(void)
{
	/* RCC Initialization */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART8, ENABLE);

	/* GPIO Initialization */
	GPIO_InitTypeDef GPIO_InitStruct = {
		.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1,
		.GPIO_Mode = GPIO_Mode_AF,
		.GPIO_OType = GPIO_OType_PP,
		.GPIO_PuPd = GPIO_PuPd_UP,
		.GPIO_Speed = GPIO_Speed_50MHz
	};

	GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_UART8);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_UART8);
	GPIO_Init(GPIOE, &GPIO_InitStruct);

	/* USART8 Initialization */
	USART_InitTypeDef USART_InitStruct = {
		.USART_BaudRate = 57600,
		.USART_WordLength = USART_WordLength_8b,
		.USART_StopBits = USART_StopBits_1,
		.USART_Parity = USART_Parity_No,
		.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
		.USART_Mode = USART_Mode_Rx | USART_Mode_Tx
	};

	USART_Init(UART8, &USART_InitStruct);
	USART_Cmd(UART8, ENABLE);
	
	/* DMA Initialization */
	DMA_DeInit(DMA1_Stream6);

	while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE);
}

void usart_init()
{
	enable_usart1();
	enable_usart2();
	enable_usart3();
	enable_usart4();
	enable_usart5();
	enable_usart8();
}

void usart2_dma_init()
{

	uint8_t dummy = 0;
	DMA_InitTypeDef DMA_InitStructure = {
	/* Configure DMA Initialization Structure */
		.DMA_BufferSize = (uint32_t)1,
		.DMA_FIFOMode = DMA_FIFOMode_Disable,
		.DMA_FIFOThreshold = DMA_FIFOThreshold_Full,
		.DMA_MemoryBurst = DMA_MemoryBurst_Single,
		.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
		.DMA_MemoryInc = DMA_MemoryInc_Enable,
		.DMA_Mode = DMA_Mode_Normal,
		.DMA_PeripheralBaseAddr = (uint32_t)(&(USART2->DR)),
		.DMA_PeripheralBurst = DMA_PeripheralBurst_Single,
		.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
		.DMA_PeripheralInc = DMA_PeripheralInc_Disable,
		.DMA_Priority = DMA_Priority_Medium,
		/* Configure TX DMA */
		.DMA_Channel = DMA_Channel_4,
		.DMA_DIR = DMA_DIR_MemoryToPeripheral,
		.DMA_Memory0BaseAddr = (uint32_t)&dummy
	};

	DMA_Init(DMA1_Stream6, &DMA_InitStructure);
	DMA_Cmd(DMA1_Stream6, ENABLE);

	USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);

}
void usart2_dma_send(uint8_t *s)
{
	while (DMA_GetFlagStatus(DMA1_Stream6, DMA_FLAG_TCIF6) == RESET);

	DMA_ClearFlag(DMA1_Stream6, DMA_FLAG_TCIF6);

	DMA_InitTypeDef  DMA_InitStructure = {
		/* Configure DMA Initialization Structure */
		.DMA_BufferSize = (uint32_t)strlen((const char *) s),
		.DMA_FIFOMode = DMA_FIFOMode_Disable,
		.DMA_FIFOThreshold = DMA_FIFOThreshold_Full,
		.DMA_MemoryBurst = DMA_MemoryBurst_Single,
		.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
		.DMA_MemoryInc = DMA_MemoryInc_Enable,
		.DMA_Mode = DMA_Mode_Normal,
		.DMA_PeripheralBaseAddr = (uint32_t)(&(USART2->DR)),
		.DMA_PeripheralBurst = DMA_PeripheralBurst_Single,
		.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
		.DMA_PeripheralInc = DMA_PeripheralInc_Disable,
		.DMA_Priority = DMA_Priority_Medium,
		/* Configure TX DMA */
		.DMA_Channel = DMA_Channel_4,
		.DMA_DIR = DMA_DIR_MemoryToPeripheral,
		.DMA_Memory0BaseAddr = (uint32_t)s
	};
	DMA_Init(DMA1_Stream6, &DMA_InitStructure);

	DMA_Cmd(DMA1_Stream6, ENABLE);

	USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);


}

int _write(int fd, char *ptr, int len)
{
	/* Write "len" of char from "ptr" to file id "fd"
	 * Return number of char written.
	 * Need implementing with UART here. */
	int i = 0;
	fd=fd;
	for (i = 0; i < len ; i++) {
		USART_SendData(PRINTF_USART, (uint8_t) *ptr);

		/* Loop until USART2 DR register is empty */
		while (USART_GetFlagStatus(PRINTF_USART, USART_FLAG_TXE) == RESET);

		ptr++;
	}

	return len;
}


xSemaphoreHandle serial_tx_wait_sem = NULL;
xQueueHandle serial_rx_queue = NULL;
xQueueHandle gps_serial_queue = NULL;
void USART3_IRQHandler(void)
{
	long lHigherPriorityTaskWoken = pdFALSE;

	serial_msg rx_msg;

	if (USART_GetITStatus(USART3, USART_IT_TXE) != RESET) {
		xSemaphoreGiveFromISR(serial_tx_wait_sem, &lHigherPriorityTaskWoken);

		USART_ITConfig(USART3, USART_IT_TXE, DISABLE);

	}
	
	if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
		rx_msg.ch = USART_ReceiveData(USART3);

		if (!xQueueSendToBackFromISR(serial_rx_queue, &rx_msg, &lHigherPriorityTaskWoken))
			portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);

	}

	portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
}

char usart3_read(void)
{
	serial_msg msg;

	while (!xQueueReceive(serial_rx_queue, &msg, portMAX_DELAY));

	return msg.ch;
}

void usart3_send(char str)
{
	while (!xSemaphoreTake(serial_tx_wait_sem, portMAX_DELAY));

	USART_SendData(USART3, (uint16_t)str);
	USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
}

void uart8_puts(uint8_t *ptr)
{
	while(*ptr!='\0'){

		USART_SendData(PRINTF_USART, (uint8_t) *ptr);

		/* Loop until USART8 DR register is empty */
		while (USART_GetFlagStatus(PRINTF_USART, USART_FLAG_TXE) == RESET);
		ptr++;
	}

}
Example #19
0
void EXTI2_IRQHandler(void) // nRF24_IRQ_PIN
{
    EXTI_ClearITPendingBit(NRF24L01_IRQ_LINE);
    xSemaphoreGiveFromISR(xNRF_IRQ_Semaphore, NULL);
}
Example #20
0
/*
 * For internal use only.
 * A common SPI interrupt handler that is called for all SPI peripherals.
 */
static void local_spi_handler(const portBASE_TYPE spi_index)
{
	portBASE_TYPE higher_priority_task_woken = pdFALSE;
	uint32_t spi_status;
	Spi *spi_port;

	spi_port = all_spi_definitions[spi_index].peripheral_base_address;

	spi_status = spi_read_status(spi_port);
	spi_status &= spi_read_interrupt_mask(spi_port);

	/* Has the PDC completed a transmission? */
	if ((spi_status & SPI_SR_ENDTX) != 0UL) {
		spi_disable_interrupt(spi_port, SPI_IDR_ENDTX);

		/* If the driver is supporting multi-threading, then return the access
		mutex. */
		if (tx_dma_control[spi_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[spi_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* if the sending task supplied a notification semaphore, then
		 * notify the task that the transmission has completed. */
		if (tx_dma_control[spi_index].transaction_complete_notification_semaphore != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[spi_index].transaction_complete_notification_semaphore,
					&higher_priority_task_woken);
		}
	}

	/* Has the PDC completed a reception? */
	if ((spi_status & SPI_SR_ENDRX) != 0UL) {
		spi_disable_interrupt(spi_port, SPI_IDR_ENDRX);

		/* If the driver is supporting multi-threading, then return the access
		mutex.  NOTE: As a reception is performed by first performing a
		transmission, the SPI receive function uses the tx access semaphore. */
		if (tx_dma_control[spi_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[spi_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* If the receiving task supplied a notification semaphore, then
		notify the task that the transmission has completed. */
		if (rx_dma_control[spi_index].transaction_complete_notification_semaphore != NULL) {
			xSemaphoreGiveFromISR(
					rx_dma_control[spi_index].transaction_complete_notification_semaphore,
					&higher_priority_task_woken);
		}
	}

	if ((spi_status & SR_ERROR_INTERRUPTS) != 0) {
		/* An mode error occurred in either a transmission or reception.  Abort.
		Stop the transmission, disable interrupts used by the peripheral, and
		ensure the peripheral access mutex is made available to tasks.  As this
		peripheral is half duplex, only the Tx peripheral access mutex exits. */
		spi_disable_interrupt(spi_port, SPI_IDR_ENDTX);
		spi_disable_interrupt(spi_port, SPI_IDR_ENDRX);

		if (tx_dma_control[spi_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[spi_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* The SPI port will have been disabled, re-enable it. */
		spi_enable(spi_port);
	}

	/* If giving a semaphore caused a task to unblock, and the unblocked task
	has a priority equal to or higher than the currently running task (the task
	this ISR interrupted), then higher_priority_task_woken will have
	automatically been set to pdTRUE within the semaphore function.
	portEND_SWITCHING_ISR() will then ensure that this ISR returns directly to
	the higher priority unblocked task. */
	portEND_SWITCHING_ISR(higher_priority_task_woken);
}
Example #21
0
/*
 * For internal use only.
 * A common TWI interrupt handler that is called for all TWI peripherals.
 */
static void local_twi_handler(const portBASE_TYPE twi_index)
{
	portBASE_TYPE higher_priority_task_woken = pdFALSE;
	uint32_t twi_status;
	Twi *twi_port;
	bool transfer_timeout = false;

	twi_port = all_twi_definitions[twi_index].peripheral_base_address;

	twi_status = twi_get_interrupt_status(twi_port);
	twi_status &= twi_get_interrupt_mask(twi_port);

	/* Has the PDC completed a transmission? */
	if ((twi_status & TWI_SR_ENDTX) != 0UL) {
		/* Disable PDC */
		pdc_disable_transfer(all_twi_definitions[twi_index].pdc_base_address, PERIPH_PTCR_TXTDIS);
		twi_disable_interrupt(twi_port, TWI_IDR_ENDTX);

		uint8_t status;
		uint32_t timeout_counter = 0;

		/* Wait for TX ready flag */
		while (1) {
			status = twi_port->TWI_SR;
			if (status & TWI_SR_TXRDY) {
				break;
			}
			/* Check timeout condition. */
			if (++timeout_counter >= TWI_TIMEOUT_COUNTER) {
				transfer_timeout = true;
				break;
			}
		}
		/* Complete the transfer - stop and last byte */
		twi_port->TWI_CR = TWI_CR_STOP;
		twi_port->TWI_THR = twis[twi_index].buffer[twis[twi_index].length-1];

		/* Wait for TX complete flag */
		while (1) {
			status = twi_port->TWI_SR;
			if (status & TWI_SR_TXCOMP) {
				break;
			}
			/* Check timeout condition. */
			if (++timeout_counter >= TWI_TIMEOUT_COUNTER) {
				transfer_timeout = true;
				break;
			}
		}
		/* If the driver is supporting multi-threading, then return the access
		mutex. */
		if (tx_dma_control[twi_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[twi_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* if the sending task supplied a notification semaphore, then
		notify the task that the transmission has completed. */
		if (!(timeout_counter >= TWI_TIMEOUT_COUNTER)) {
			if (tx_dma_control[twi_index]. transaction_complete_notification_semaphore != NULL) {
				xSemaphoreGiveFromISR(
						tx_dma_control[twi_index].transaction_complete_notification_semaphore,
						&higher_priority_task_woken);
			}
		}
	}

	/* Has the PDC completed a reception? */
	if ((twi_status & TWI_SR_ENDRX) != 0UL) {
		uint32_t timeout_counter = 0;
		uint32_t status;
		/* Must handle the two last bytes */
		/* Disable PDC */
		pdc_disable_transfer(all_twi_definitions[twi_index].pdc_base_address, PERIPH_PTCR_RXTDIS);

		twi_disable_interrupt(twi_port, TWI_IDR_ENDRX);

		/* Wait for RX ready flag */
		while (1) {
			status = twi_port->TWI_SR;
			if (status & TWI_SR_RXRDY) {
				break;
			}
			/* Check timeout condition. */
			if (++timeout_counter >= TWI_TIMEOUT_COUNTER) {
				break;
			}
		}
		/* Complete the transfer. */
		twi_port->TWI_CR = TWI_CR_STOP;
		/* Read second last data */
		twis[twi_index].buffer[(twis[twi_index].length)-2] = twi_port->TWI_RHR;

		/* Wait for RX ready flag */
		while (1) {
			status = twi_port->TWI_SR;
			if (status & TWI_SR_RXRDY) {
				break;
			}
			/* Check timeout condition. */
			if (++timeout_counter >= TWI_TIMEOUT_COUNTER) {
				break;
			}
		}

		if (!(timeout_counter >= TWI_TIMEOUT_COUNTER)) {
			/* Read last data */
			twis[twi_index].buffer[(twis[twi_index].length)-1] = twi_port->TWI_RHR;
			timeout_counter = 0;
			/* Wait for TX complete flag before releasing semaphore */
			while (1) {
				status = twi_port->TWI_SR;
				if (status & TWI_SR_TXCOMP) {
					break;
				}
				/* Check timeout condition. */
				if (++timeout_counter >= TWI_TIMEOUT_COUNTER) {
					transfer_timeout = true;
					break;
				}
			}
		}

		/* If the driver is supporting multi-threading, then return the access
		mutex.  NOTE: As the peripheral is half duplex there is only one
		access mutex, and the reception uses the tx access muted. */
		if (tx_dma_control[twi_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[twi_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* if the receiving task supplied a notification semaphore, then
		notify the task that the transmission has completed. */
		if  (!(timeout_counter >= TWI_TIMEOUT_COUNTER)) {
			if (rx_dma_control[twi_index].transaction_complete_notification_semaphore != NULL) {
				xSemaphoreGiveFromISR(
						rx_dma_control[twi_index].transaction_complete_notification_semaphore,
						&higher_priority_task_woken);
			}
		}
	}

	if (((twi_status & SR_ERROR_INTERRUPTS) != 0) || (transfer_timeout == true)) {
		/* An error occurred in either a transmission or reception.  Abort.
		Stop the transmission, disable interrupts used by the peripheral, and
		ensure the peripheral access mutex is made available to tasks.  As this
		peripheral is half duplex, only the Tx peripheral access mutex exits.*/

		/* Stop the PDC */
		pdc_disable_transfer(all_twi_definitions[twi_index].pdc_base_address, PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS);

		if (!(twi_status & TWI_SR_NACK)) {
			/* Do not send stop if NACK received. Handled by hardware */
			twi_port->TWI_CR = TWI_CR_STOP;
		}
		twi_disable_interrupt(twi_port, TWI_IDR_ENDTX);
		twi_disable_interrupt(twi_port, TWI_IDR_ENDRX);

		if (tx_dma_control[twi_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[twi_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}
	}

	/* If giving a semaphore caused a task to unblock, and the unblocked task
	has a priority equal to or higher than the currently running task (the task
	this ISR interrupted), then higher_priority_task_woken will have
	automatically been set to pdTRUE within the semaphore function.
	portEND_SWITCHING_ISR() will then ensure that this ISR returns directly to
	the higher priority unblocked task. */
	portEND_SWITCHING_ISR(higher_priority_task_woken);
}
Example #22
0
//Vsync interrupt service routine
void EXTI1_IRQHandler()
{
	portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
	
	static uint16_t Vsync_update = 0;
	
//	vPortEnterCritical();
//	taskENTER_CRITICAL();
	
	if(EXTI_GetITStatus(EXTI_Line1) != RESET) 
	{
		EXTI_ClearITPendingBit(EXTI_Line1);
		
		// Stop the line counter
		TIM_Cmd(LINE_COUNTER_TIMER, DISABLE);

		// Update the number of video lines
		num_video_lines = LINE_COUNTER_TIMER->CNT;

		// check video type
		if (num_video_lines > VIDEO_TYPE_PAL_ROWS) 
		{
			video_type_tmp = VIDEO_TYPE_PAL;
		}

		// if video type has changed set new active values
		if (video_type_act != video_type_tmp) 
		{
			video_type_act = video_type_tmp;
			if (video_type_act == VIDEO_TYPE_NTSC) 
			{
				pios_video_type_boundary_act = &pios_video_type_boundary_ntsc;
				pios_video_type_cfg_act = &pios_video_type_cfg_ntsc;
				//set_bw_levels(black_ntsc, white_ntsc);
			} 
			else 
			{
				pios_video_type_boundary_act = &pios_video_type_boundary_pal;
				pios_video_type_cfg_act = &pios_video_type_cfg_pal;
				//set_bw_levels(black_pal, white_pal);
			}
			PIXEL_TIMER->CCR1 = pios_video_type_cfg_act->dc;
			PIXEL_TIMER->ARR  = pios_video_type_cfg_act->period;
			HSYNC_CAPTURE_TIMER->ARR = pios_video_type_cfg_act->dc * (pios_video_type_cfg_act->graphics_column_start + x_offset);
		}
		if (x_offset != x_offset_new)
		{
			x_offset = x_offset_new;
			HSYNC_CAPTURE_TIMER->ARR = pios_video_type_cfg_act->dc * (pios_video_type_cfg_act->graphics_column_start + x_offset);
		}

		video_type_tmp = VIDEO_TYPE_NTSC;


		// Every VSYNC_REDRAW_CNT field: swap buffers and trigger redraw
		if (++Vsync_update >= VSYNC_REDRAW_CNT) {
			if((LINE_COUNTER_TIMER->DIER & TIM_IT_Update) == (uint16_t)RESET)
			{
				TIM_ITConfig(LINE_COUNTER_TIMER, TIM_IT_Update, ENABLE);
			}
			Vsync_update = 0;
			swap_buffers();
			xSemaphoreGiveFromISR(onScreenDisplaySemaphore, &xHigherPriorityTaskWoken);
		}
		
		// Get ready for the first line
		active_line = 0;

		// Set the number of lines to wait until we start clocking out pixels
		LINE_COUNTER_TIMER->CNT = 0xffff - (pios_video_type_cfg_act->graphics_line_start + y_offset);
		TIM_Cmd(LINE_COUNTER_TIMER, ENABLE);
		

	}
	
	portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
//	vPortExitCritical();
//	taskEXIT_CRITICAL();
}
Example #23
0
/*!
 *  Interrupt routine notifying us a new character is available from the
 *  GPS's uart module.
 *  This function buffers a valid (structure and checksum) RMC sentence. The
 *  used buffer is nmea_buffer_RMC.
 */
void __attribute__((__interrupt__, __shadow__, __auto_psv__)) _U2RXInterrupt(void)
{
	unsigned char c = U2RXREG;
	//uart1_putc(c);
	
 
	if (c == '$')   // Beginnng of new sequence
	{
		state = 1;
		checksum = 0;
	} 
	else if (c == '*')
	{
		if (state == 7)
			state = 98;	
		else if (state == 11)
			state = 90;
	} 
	else if (state == 90)
	{
		checksum -= (hexchar2int(c)*16);
		state = 91;			
	}	
	else if (state == 91)
	{
		nmea_buffer_GGA[nmea_buffer_GGA_counter++] = '\0';
		checksum -= (hexchar2int(c));
		if (checksum == 0)
			gga_sentence_number++;
		state = 92;
#ifndef TEST
		static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; 
		xSemaphoreGiveFromISR( xGpsSemaphore, &xHigherPriorityTaskWoken );
#endif		
	}	
	else if (state == 98)
	{
		checksum -= (hexchar2int(c)*16);
		state = 99;	
	}
	else if (state == 99)
	{
		nmea_buffer_RMC[nmea_buffer_RMC_counter++] = '\0';
		checksum -= (hexchar2int(c));
		if (checksum == 0)
			rmc_sentence_number++;

		state = 100;

// small test programs don't use FreeRTOS so we need a way to avoid 
#ifndef TEST
		static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; 
		xSemaphoreGiveFromISR( xGpsSemaphore, &xHigherPriorityTaskWoken );
#endif
	}
	else 
	{
		checksum ^= c;
		
		switch(state)
		{
			case 1:
				if (c == 'G')
					state = 2;
				break;
			case 2:
				if (c == 'P')
					state = 3;
				break;
			case 3:
				if (c == 'R')
					state = 4;
				else if (c == 'G')
					state = 8;
				break;
			case 4:
				if (c == 'M')
					state = 5;
				break;
			case 5:
				if (c == 'C')
					state = 6;
				break;
			case 6:
				if (c == ',')
				{
					state = 7;
					nmea_buffer_RMC_counter = 0;
				}
				break;
			case 7:
				if (nmea_buffer_RMC_counter < 100)
					nmea_buffer_RMC[nmea_buffer_RMC_counter++] = c;
				break;
			case 8:
				if (c == 'G')
					state = 9;
				break;
			case 9:
				if (c == 'A')
					state = 10;
				break;
			case 10:
				if (c == ',')
					state = 11;
					nmea_buffer_GGA_counter = 0;
				break;
			case 11:
				if (nmea_buffer_GGA_counter < 100)
					nmea_buffer_GGA[nmea_buffer_GGA_counter++] = c;
				break;
			default:
				nmea_buffer_RMC_counter = 0;
				nmea_buffer_GGA_counter = 0;
		}
	}
	_U2RXIF = 0;
}
Example #24
0
/*****************************************************************************
 Prototype    : DMA1_Channel2_IRQHandler
 Description  : uart3 DMA-Tx Handler
 Input        : void  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2015/9/7
    Author       : qiuweibo
    Modification : Created function

*****************************************************************************/
void DMA1_Channel2_IRQHandler(void)
{
    BaseType_t xHigherPriorityTaskWoken, xResult;

    // xHigherPriorityTaskWoken must be initialised to pdFALSE.
    xHigherPriorityTaskWoken = pdFALSE;

    DMA_ClearITPendingBit(DMA1_IT_TC2);
    DMA_Cmd(DMA1_Channel2, DISABLE);    // close DMA
    
    xResult = xSemaphoreTakeFromISR( xSerialTxHandleLock, &xHigherPriorityTaskWoken);
    if( pdTRUE != xResult)
    {
        return;
    }

    //After finish this send mission, need to do: clear status --> check next mission
    if (uart3_tx_dma_buf.IdleBufferIndex)
    {
        // reset buffer1
        uart3_tx_dma_buf.nBuff1Offset = 0;

        // check for buffer2
        if (uart3_tx_dma_buf.nBuff2Offset > 0)
        {
            DMA1_Channel2->CMAR = (uint32_t)uart3_tx_dma_buf.pPingPongBuff2;
            DMA1_Channel2->CNDTR = uart3_tx_dma_buf.nBuff2Offset;
            uart3_tx_dma_buf.IdleBufferIndex = 0;
            DMA_Cmd(DMA1_Channel2, ENABLE); // open DMA
        }
        else
        {
            uart3_tx_dma_buf.IsDMAWroking = 0;
        }
    }
    else
    {
        //reset buffer2
        uart3_tx_dma_buf.nBuff2Offset = 0;
        
        // check for buffer1
        if (uart3_tx_dma_buf.nBuff1Offset > 0)
        {
            DMA1_Channel2->CMAR = (uint32_t)uart3_tx_dma_buf.pPingPongBuff1;
            DMA1_Channel2->CNDTR = uart3_tx_dma_buf.nBuff1Offset;
            uart3_tx_dma_buf.IdleBufferIndex = 1;
            DMA_Cmd(DMA1_Channel2, ENABLE); // open DMA
        }
        else
        {
            uart3_tx_dma_buf.IsDMAWroking = 0;
        }
    }
    
    xResult = xSemaphoreGiveFromISR( xSerialTxHandleLock , &xHigherPriorityTaskWoken);
    if( xResult == pdPASS )
    {
        // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
        // switch should be requested.  The macro used is port specific and 
        // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - 
        // refer to the documentation page for the port being used.
        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    }
}
/*******************************************************************************
 * ISR: UART 2 Interrupt.
 *
 * DESCRIPTIONS:
 * Interrupt vector for UART 2.
 *
 *******************************************************************************/
void __ISR(_UART_2_VECTOR, IPL7AUTO) UART2Interrupt(void)
{
    unsigned char ucReceivedData;

    xSystemState.bBluetoothBusy = 1;


    // Rx interrupt.
    if (INTGetEnable(INT_U2RX) && INTGetFlag(INT_U2RX)) {
        INTClearFlag(INT_U2RX);

        // Read out all data available.
        while (UARTReceivedDataIsAvailable(UART2)) {
            // Read the received data.
            ucReceivedData = UARTGetDataByte(UART2);

            // Make sure there is empty space in the buffer.
            if ((prv_xRx.uiBufferSize - prv_xRx.uiDataCount) > 0) {

                // Copy the data to the buffer.
                prv_xRx.pucBuffer[prv_xRx.uiWritePt] = ucReceivedData;

                // Increase the write pointer and data count.
                prv_vIncPointer(&prv_xRx.uiWritePt, prv_xRx.uiBufferSize);
                prv_xRx.uiDataCount++;

                portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
                xSemaphoreGiveFromISR(xBluetoothRxSemaphore, &xHigherPriorityTaskWoken);
            }
            else {
                xSystemError.bBluetoothError = 1;
            }
        }
    }



    // Tx interrupt.
    if (INTGetEnable(INT_U2TX) && INTGetFlag(INT_U2TX)) {
        // Loop until the Tx buffer is fully filled.
        while (UARTTransmitterIsReady(UART2)) {
            // If there is data to transmit...
            if (prv_xTx.uiDataCount > 0) {
                // Shift in the data to the transmit buffer.
                UARTSendDataByte(UART2, prv_xTx.pucBuffer[prv_xTx.uiReadPt]);

                // Increase the read pointer and decrease the data count.
                prv_vIncPointer(&prv_xTx.uiReadPt, prv_xTx.uiBufferSize);
                prv_xTx.uiDataCount--;
            }

            // Else, disable the transmit interrupt.
            else {
                INTEnable(INT_U2TX, INT_DISABLED);
                break;
            }
        }
    }



    // Error Interrupt.
    if (INTGetEnable(INT_U2E) && INTGetFlag(INT_U2E)) {
        INTClearFlag(INT_U2E);

        // Discard all data available.
        while (UARTReceivedDataIsAvailable(UART2)) {
            // Read the received data.
            ucReceivedData = UARTGetDataByte(UART2);
        }

        // Clear the overrun flag.
        if (UARTGetLineStatus(UART2) & UART_OVERRUN_ERROR) {
            U2STAbits.OERR = 0;
        }

        xSystemError.bBluetoothError = 1;
    }

}
/*
 * For internal use only.
 * A common UART interrupt handler that is called for all UART peripherals.
 */
static void local_uart_handler(const portBASE_TYPE uart_index)
{
	portBASE_TYPE higher_priority_task_woken = pdFALSE;
	uint32_t uart_status;
	freertos_pdc_rx_control_t *rx_buffer_definition;

	uart_status = uart_get_status(
			all_uart_definitions[uart_index].peripheral_base_address);
	uart_status &= uart_get_interrupt_mask(
			all_uart_definitions[uart_index].peripheral_base_address);

	rx_buffer_definition = &(rx_buffer_definitions[uart_index]);

	/* Has the PDC completed a transmission? */
	if ((uart_status & UART_SR_ENDTX) != 0UL) {
		uart_disable_interrupt(
				all_uart_definitions[uart_index].peripheral_base_address,
				UART_IDR_ENDTX);

		/* If the driver is supporting multi-threading, then return the access
		mutex. */
		if (tx_dma_control[uart_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[uart_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}

		/* if the sending task supplied a notification semaphore, then
		notify the task that the transmission has completed. */
		if (tx_dma_control[uart_index].transaction_complete_notification_semaphore != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[uart_index].transaction_complete_notification_semaphore,
					&higher_priority_task_woken);
		}
	}

	if ((uart_status & UART_SR_ENDRX) != 0UL) {
		/* It is possible to initialise the peripheral to only use Tx and not Rx.
		Check that Rx has been initialised. */
		configASSERT(rx_buffer_definition->next_byte_to_read);
		configASSERT(rx_buffer_definition->next_byte_to_read !=
				RX_NOT_USED);

		/* Out of DMA buffer, configure the next buffer.  Start by moving
		the DMA buffer start address up to the end of the previously defined
		buffer. */
		rx_buffer_definition->rx_pdc_parameters.ul_addr +=
				rx_buffer_definition->rx_pdc_parameters.ul_size;

		/* If the end of the buffer has been reached, wrap back to the start. */
		if (rx_buffer_definition->rx_pdc_parameters.ul_addr >=
				rx_buffer_definition->past_rx_buffer_end_address)
		{
			rx_buffer_definition->rx_pdc_parameters.ul_addr =
					rx_buffer_definition->rx_buffer_start_address;
		}

		/* Reset the Rx DMA to receive data into whatever free space remains in
		the Rx buffer. */
		configure_rx_dma(uart_index, data_added);

		if (rx_buffer_definition->rx_event_semaphore != NULL) {
			/* Notify that new data is available. */
			xSemaphoreGiveFromISR(
					rx_buffer_definition->rx_event_semaphore,
					&higher_priority_task_woken);
		}
	}

	/**
	 * Normally the uart_status can't be "0" when the interrupt happened.
	 * It happened only when in PDC mode with TXRDY and RXRDY interrupts since
	 * the flags has been cleared by PDC.
	 * As the TXRDY is never enabled in this service, here we
	 * check the RXRDY interrupt case.
	 */
	if (uart_status == 0UL) {
		/* Character has been placed into the Rx buffer. */
		if (rx_buffer_definition->rx_event_semaphore != NULL) {
			/* Notify that new data is available. */
			xSemaphoreGiveFromISR(
					rx_buffer_definition->rx_event_semaphore,
					&higher_priority_task_woken);
		}
	}

	if ((uart_status & SR_ERROR_INTERRUPTS) != 0) {
		/* An error occurred in either a transmission or reception.  Abort, and
		ensure the peripheral access mutex is made available to tasks. */
		uart_reset_status(
				all_uart_definitions[uart_index].peripheral_base_address);
		if (tx_dma_control[uart_index].peripheral_access_mutex != NULL) {
			xSemaphoreGiveFromISR(
					tx_dma_control[uart_index].peripheral_access_mutex,
					&higher_priority_task_woken);
		}
	}

	/* If giving a semaphore caused a task to unblock, and the unblocked task
	has a priority equal to or higher than the currently running task (the task
	this ISR interrupted), then higher_priority_task_woken will have
	automatically been set to pdTRUE within the semaphore function.
	portEND_SWITCHING_ISR() will then ensure that this ISR returns directly to
	the higher priority unblocked task. */
	portEND_SWITCHING_ISR(higher_priority_task_woken);
}
Example #27
0
void vI2C_ISR_Handler( void )
{
/* Holds the current transmission state. */							
static I2C_STATE eCurrentState = eSentStart;
static long lMessageIndex = -i2cBUFFER_ADDRESS_BYTES; /* There are two address bytes to send prior to the data. */
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
long lBytesLeft;

	/* The action taken for this interrupt depends on our current state. */
	switch( eCurrentState )
	{
		case eSentStart	:	

				/* We sent a start bit, if it was successful we can
				go on to send the slave address. */
				if( ( I2C_I2STAT == i2cSTATUS_START_TXED ) || ( I2C_I2STAT == i2cSTATUS_REP_START_TXED ) )
				{
					/* Send the slave address. */
					I2C_I2DAT = pxCurrentMessage->ucSlaveAddress;

					if( pxCurrentMessage->ucSlaveAddress & i2cREAD )
					{
						/* We are then going to read bytes back from the 
						slave. */
						eCurrentState = eSentAddressForRead;
						
						/* Initialise the buffer index so the first byte goes
						into the first buffer position. */
						lMessageIndex = 0;
					}
					else
					{
						/* We are then going to write some data to the slave. */
						eCurrentState = eSentAddressForWrite;

						/* When writing bytes we first have to send the two
						byte buffer address so lMessageIndex is set negative,
						when it reaches 0 it is time to send the actual data. */
						lMessageIndex = -i2cBUFFER_ADDRESS_BYTES;
					}
				}
				else
				{
					/* Could not send the start bit so give up. */
					i2cEND_TRANSMISSION( pdFAIL );					
				}

				I2C_I2CONCLR = i2cSTA_BIT;				

				break;

		case eSentAddressForWrite :

				/* We sent the address of the slave we are going to write to.
				If this was acknowledged we	can go on to send the data. */
				if( I2C_I2STAT == i2cSTATUS_TX_ADDR_ACKED )
				{
					/* Start the first byte transmitting which is the 
					first byte of the buffer address to which the data will 
					be sent. */
					I2C_I2DAT = pxCurrentMessage->ucBufferAddressHighByte;
					eCurrentState = eSentData;
				}
				else
				{
					/* Address was not acknowledged so give up. */
					i2cEND_TRANSMISSION( pdFAIL );					
				}					
				break;

		case eSentAddressForRead :

				/* We sent the address of the slave we are going to read from.
				If this was acknowledged we can go on to read the data. */
				if( I2C_I2STAT == i2cSTATUS_RX_ADDR_ACKED )
				{
					eCurrentState = eReceiveData;
					if( pxCurrentMessage->lMessageLength > i2cJUST_ONE_BYTE_TO_RX )
					{
						/* Don't ack the last byte of the message. */
						I2C_I2CONSET = i2cAA_BIT;
					}					
				}
				else
				{
					/* Something unexpected happened - give up. */
					i2cEND_TRANSMISSION( pdFAIL );					
				}
				break;

		case eReceiveData :
				
				/* We have just received a byte from the slave. */
				if( ( I2C_I2STAT == i2cSTATUS_DATA_RXED ) || ( I2C_I2STAT == i2cSTATUS_LAST_BYTE_RXED ) )
				{
					/* Buffer the byte just received then increment the index 
					so it points to the next free space. */
					pxCurrentMessage->pucBuffer[ lMessageIndex ] = I2C_I2DAT;
					lMessageIndex++;

					/* How many more bytes are we expecting to receive? */
					lBytesLeft = pxCurrentMessage->lMessageLength - lMessageIndex;
					if( lBytesLeft == ( unsigned long ) 0 )
					{
						/* This was the last byte in the message. */
						i2cEND_TRANSMISSION( pdPASS );

						/* If xMessageCompleteSemaphore is not null then there
						is a task waiting for this message to complete and we
						must 'give' the semaphore so the task is woken.*/
						if( pxCurrentMessage->xMessageCompleteSemaphore )
						{
							xSemaphoreGiveFromISR( pxCurrentMessage->xMessageCompleteSemaphore, &xHigherPriorityTaskWoken );
						}

						/* Are there any other messages to transact? */
						if( xQueueReceiveFromISR( xMessagesForTx, &pxCurrentMessage, &xHigherPriorityTaskWoken ) == pdTRUE )
						{
							/* Start the next message - which was
							retrieved from the queue. */
							I2C_I2CONSET = i2cSTA_BIT;
						}
						else
						{
							/* No more messages were found to be waiting for
							transaction so the bus is free. */
							ulBusFree = ( unsigned long ) pdTRUE;			
						}						
					}
					else
					{
						/* There are more bytes to receive but don't ack the 
						last byte. */
						if( lBytesLeft <= i2cJUST_ONE_BYTE_TO_RX )
						{
							I2C_I2CONCLR = i2cAA_BIT;
						}							 
					}
				}
				else
				{
					/* Something unexpected happened - give up. */
					i2cEND_TRANSMISSION( pdFAIL );					
				}

				break;
				
		case eSentData	:	

				/* We sent a data byte, if successful send the	next byte in 
				the message. */
				if( I2C_I2STAT == i2cSTATUS_DATA_TXED )
				{
					/* Index to the next byte to send. */
					lMessageIndex++;
					if( lMessageIndex < 0 )
					{
						/* lMessage index is still negative so we have so far 
						only sent the first byte of the buffer address.  Send 
						the second byte now, then initialise the buffer index
						to zero so the next byte sent comes from the actual 
						data buffer. */
						I2C_I2DAT = pxCurrentMessage->ucBufferAddressLowByte;
					}
					else if( lMessageIndex < pxCurrentMessage->lMessageLength )
					{
						/* Simply send the next byte in the tx buffer. */
						I2C_I2DAT = pxCurrentMessage->pucBuffer[ lMessageIndex ];										
					}
					else
					{
						/* No more bytes in this message to be send.  Finished 
						sending message - send a stop bit. */
						i2cEND_TRANSMISSION( pdPASS );

						/* If xMessageCompleteSemaphore is not null then there
						is a task waiting for this message to be sent and the
						semaphore must be 'given' to wake the task. */
						if( pxCurrentMessage->xMessageCompleteSemaphore )
						{
							xSemaphoreGiveFromISR( pxCurrentMessage->xMessageCompleteSemaphore, &xHigherPriorityTaskWoken );
						}

						/* Are there any other messages to transact? */
						if( xQueueReceiveFromISR( xMessagesForTx, &pxCurrentMessage, &xHigherPriorityTaskWoken ) == pdTRUE )
						{
							/* Start the next message from the Tx queue. */
							I2C_I2CONSET = i2cSTA_BIT;
						}
						else
						{
							/* No more message were queues for transaction so 
							the bus is free. */
							ulBusFree = ( unsigned long ) pdTRUE;			
						}
					}
				}
				else
				{
					/* Something unexpected happened, give up. */
					i2cEND_TRANSMISSION( pdFAIL );					
				}
				break;

		default	:	
		
				/* Should never get here. */
				eCurrentState = eSentStart;
				break;
	}	

	/* Clear the interrupt. */
	I2C_I2CONCLR = i2cSI_BIT;
	VICVectAddr = i2cCLEAR_VIC_INTERRUPT;

	if( xHigherPriorityTaskWoken )
	{
		portYIELD_FROM_ISR();
	}
}
Example #28
0
void USART1_IRQHandler (void)//следует разработать систему распознавания старого протокола или заменить на выбор вручную
{
 	static portBASE_TYPE xHigherPriorityTaskWoken;
 	  xHigherPriorityTaskWoken = pdFALSE;

//

 	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
   	{

 		USART_ClearITPendingBit(USART1, USART_IT_RXNE);


   		symbol=USART_ReceiveData (USART1);
   //----------------------обрабатываем возможные ошибки длины кадра-------------
   		if(recieve_count>MAX_LENGTH_REC_BUF)	//если посылка слишком длинная
   		{
   			recieve_count=0x0;
   			return;
   		}

		if(recieve_count==0x0)
		{
			if(symbol==':')//признак старого протокола
			{
				proto_type=PROTO_TYPE_OLD;
			}
			else
			{
				if((symbol==0x0) || (symbol==0xD7))//новый протокол
				{
					proto_type=PROTO_TYPE_NEW;
				}
				else//ошибка кадра или не с начала
				{
					return;
				}
			}
		}
switch(proto_type)
{
	case PROTO_TYPE_OLD:
	{
		if(symbol==':')
		{
			recieve_count=0x0;
		}

		tab.tablo_proto_buf[recieve_count]=symbol;
		recieve_count++;

		if(recieve_count>1)
		{
			if(tab.tablo_proto_buf[1]==(recieve_count-2))//кадр принят
			{
				 USART_ITConfig(USART1, USART_IT_RXNE , DISABLE);
				xSemaphoreGiveFromISR( xProtoSemaphore, &xHigherPriorityTaskWoken );

  				 if( xHigherPriorityTaskWoken != pdFALSE )
  				 {
  					portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
  				 }
			}
		}



	}
	break;

	case PROTO_TYPE_NEW:
	{
	//--------------------------начало кадра...проверка до длины кадра--------
   	    if(recieve_count<6)
   		{
   	    		switch(recieve_count)
   				{
   					case  0:   //первый символ 0
   					{
   	 				 	 if(symbol!=0x00)
   						 {
   	 				 		recieve_count=0;

   	 				 	fr_err++;
   							//return;
   						 }
   					}
   					break;

   					case 1:	 //второй символ 0xD7
   					{
   						 if(symbol!=0xD7)
   						 {
   							recieve_count=0;

   							//return;
   						 }
   					}
   					break;

   					case 2:	 //	третий символ 0x29
   					{
   					 	 if(symbol!=0x29)
   						 {
   					 		recieve_count=0;

   							//return;
   						 }
   					}
   					break;

   					case 3:	//если адрес не совпал, то сбросим//NEW
   					{
   						if(symbol!=ADRESS_DEV)//если адрес совпал
   						{
   							recieve_count=0;

   							//return;
   						}
   					}
   					break;

   					default:  //
   					{
   					}
   					break;
   				}

   			RecieveBuf[recieve_count]=symbol;//сохраняем принятый символ в буфер
   			recieve_count++;//счетчик буфера

   			if(recieve_count==6)
   			{
   				frame_len=RecieveBuf[recieve_count-1]; //получим оставшуюся длину
   			}
   		}
   //---------------------------------------------------------
   		else  //отсюда знаем длину кадра и удаляем нули после 0xD7
   		{
   			switch(symbol)//проверим, это 0x0 ,0xD7 или другое
   			{
   				case 0xD7:
   				{
   					CUT_OUT_NULL=1;	//
   					RecieveBuf[recieve_count]=symbol;
   					recieve_count++;

   				}
   				break;

   				case 0x0:
   				{
   					if(!CUT_OUT_NULL)  //если вырезать 0x0 не надо, то не вырезаем
   					{
   						RecieveBuf[recieve_count]=symbol;
   						recieve_count++;
   					}
   					else //иначе в буфер не кладем, сбросим флаг
   					{
   						CUT_OUT_NULL=0;
   					}
   				}
   				break;

   				default:  //другие кладем в буфер
   				{
   					CUT_OUT_NULL=0;
   					RecieveBuf[recieve_count]=symbol;
   					recieve_count++;
   				}
   				break;
   			}

   			if(recieve_count>=frame_len+6)//если приняты  все байты
   			{
   				 USART_ITConfig(USART1, USART_IT_RXNE , DISABLE);
   				  /* 'Дать' семафор для разблокировки задачи. */

   				 xSemaphoreGiveFromISR( xProtoSemaphore, &xHigherPriorityTaskWoken );

   				 if( xHigherPriorityTaskWoken != pdFALSE )
   				 {
   					portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
   				 }
   			}
   		}
	}
}

   	}
   //----------------------------передача----------------------------------------------------------------
   	if(USART_GetITStatus(USART1, USART_IT_TC) != RESET)
   	{

   		USART_ClearITPendingBit(USART1, USART_IT_TC);//очищаем признак прерывания

   		if(transf_count<buf_len)
   		{
   			if(transf_count<3)//передаем заголовок
   			{
   				USART_SendData(USART1,TransferBuf[transf_count]);
   				transf_count++;
   			}
   			else   //тело...   подставляем 0 после 0xD7
   			{
   					if(CUT_OUT_NULL==0)
   					{
   						if(TransferBuf[transf_count]==(uint8_t)0xD7)//проверим, это  ,0xD7 или другое
   						{
   							CUT_OUT_NULL=0x1;
   						}
   						USART_SendData(USART1,TransferBuf[transf_count]);
   						transf_count++;
   					}
   					else
   					{
   						USART_SendData(USART1,(uint8_t)0x0);
   						CUT_OUT_NULL=0;
   					}
   			}
   		}
   		else
   		{
   			transf_count=0;		//обнуляем счетчик
   			recieve_count=0;

   			CUT_OUT_NULL=0;
   			 USART_ITConfig(USART1, USART_IT_RXNE , ENABLE);
   		}

   	}
   	portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

}
/*
 * ISR routines
 */
void ADC_IRQHandler() {
	static signed portBASE_TYPE xHigherPriorityTaskWoken;
	xSemaphoreGiveFromISR(adc_conversion_semaphore, &xHigherPriorityTaskWoken);
}
Example #30
0
static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw)
{
    return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
}