Exemplo n.º 1
0
void vSerialClose( xComPortHandle xPort )
{
	uint8_t ucByte;

	/* The parameter is not used. */
	( void ) xPort;

	/* Turn off the interrupts.  We may also want to delete the queues and/or
	re-install the original ISR. */

	vPortFree (serialWorkBuffer);
	vQueueDelete(xRxedChars);
	vQueueDelete(xCharsForTx);

	portENTER_CRITICAL();
	{
		vInterruptOff();
		ucByte = UCSR0B;
		ucByte &= ~(_BV(RXCIE0));
		UCSR0B = ucByte;
	}
	portEXIT_CRITICAL();
}
Exemplo n.º 2
0
/* setup a timer so the Restart timer function can be used */
void SetupOneSecondTimer(tTimerId TimerId,
                         unsigned int Timeout,
                         unsigned char RepeatCount,
                         unsigned char Qindex,
                         eMessageType CallbackMsgType,
                         unsigned char MsgOptions)
{
  if (OneSecondTimers[TimerId].Allocated == 0 || TimerId < 0)
  {
    PrintString("Timer not Allocated\r\n");
    return;
  }
  
  portENTER_CRITICAL();
    
  OneSecondTimers[TimerId].RepeatCount = RepeatCount;
  OneSecondTimers[TimerId].Timeout = Timeout;
  OneSecondTimers[TimerId].Qindex = Qindex;
  OneSecondTimers[TimerId].CallbackMsgType = CallbackMsgType;
  OneSecondTimers[TimerId].CallbackMsgOptions = MsgOptions;
    
  portEXIT_CRITICAL();
}
Exemplo n.º 3
0
/*
*********************************************************************************************************
*                                                UartReadByte()
*
* Description : Receive a single byte.
*
* Argument(s) : number of UART.
*
* Return(s)   : The received byte.
*
* Caller(s)   : Application.
*
* Note(s)     : 
*********************************************************************************************************
*/
void ValidatorPulseProcessing (u32 call_period) {

	static u32 puls_with_cnt = 0;

    if (!GPIO_ReadInputDataBit(VALIDATOR_PULS_IN)) {

    	puls_with_cnt += call_period;
    }

    else if (puls_with_cnt > 0) {

    	if ((puls_with_cnt > ValidatorNV9.PeriodCntMin) && (puls_with_cnt < ValidatorNV9.PeriodCntMax)) {

//    		ValidatorNV9.SynchroFlag   = SET;
    		portENTER_CRITICAL();
    		ValidatorNV9.MoneyQuantity++;
    		portEXIT_CRITICAL();
//    		ValidatorNV9.SynchroFlag   = RESET;
    	}

    	puls_with_cnt = 0;
    }
}
Exemplo n.º 4
0
Arquivo: port.c Projeto: Eclo/FreeRTOS
/* The preemptive scheduler is defined as "naked" as the full context is saved
on entry as part of the context switch. */
__attribute__((__naked__)) static void vTick( void )
{
	/* Save the context of the interrupted task. */
	portSAVE_CONTEXT_OS_INT();

	#if( configTICK_USE_TC==1 )
		/* Clear the interrupt flag. */
		prvClearTcInt();
	#else
		/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
		clock cycles from now. */
		prvScheduleNextTick();
	#endif

	/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
	calls in a critical section . */
	portENTER_CRITICAL();
		xTaskIncrementTick();
	portEXIT_CRITICAL();

	/* Restore the context of the "elected task". */
	portRESTORE_CONTEXT_OS_INT();
}
Exemplo n.º 5
0
//
//  Set clock to new values.
//
static void rtcWrite (struct tm *newTime)
{
  rtcWake ();
  portENTER_CRITICAL ();

  RTC_CCR &= ~RTC_CCR_CLKEN;
  RTC_CCR |=  RTC_CCR_CTCRST;

  RTC_SEC   = newTime->tm_sec;
  RTC_MIN   = newTime->tm_min;
  RTC_HOUR  = newTime->tm_hour;
  RTC_DOM   = newTime->tm_mday;
  RTC_MONTH = newTime->tm_mon + 1;
  RTC_YEAR  = newTime->tm_year + 1900;
  RTC_DOW   = newTime->tm_wday;
  RTC_DOY   = newTime->tm_yday + 1;

  RTC_CCR &= ~RTC_CCR_CTCRST;
  RTC_CCR |=  RTC_CCR_CLKEN;

  portEXIT_CRITICAL ();
  rtcSleep ();
}
Exemplo n.º 6
0
static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters )
{
    uint16_t usData, usExpectedValue = ( uint16_t ) 0;
    BaseType_t xError = pdFALSE;

    for( ;; ) {
        /* Loop until the queue is empty. */
        while( uxQueueMessagesWaiting( *( ( QueueHandle_t * ) pvParameters ) ) ) {
            if( xQueueReceive( *( ( QueueHandle_t * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS ) {
                if( usData != usExpectedValue ) {
                    /* This is not what we expected to receive so an error has
                    occurred. */
                    xError = pdTRUE;

                    /* Catch-up to the value we received so our next expected
                    value should again be correct. */
                    usExpectedValue = usData;
                } else {
                    if( xError == pdFALSE ) {
                        /* Only increment the check variable if no errors have
                        occurred. */
                        portENTER_CRITICAL();
                        xPollingConsumerCount++;
                        portEXIT_CRITICAL();
                    }
                }

                /* Next time round we would expect the number to be one higher. */
                usExpectedValue++;
            }
        }

        /* Now the queue is empty we block, allowing the producer to place more
        items in the queue. */
        vTaskDelay( pollqCONSUMER_DELAY );
    }
} /*lint !e818 Function prototype must conform to API. */
Exemplo n.º 7
0
/*-----------------------------------------------------------*/
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
	/* Initialise the hardware. */
	portENTER_CRITICAL();
	{
		/* Create the queues used by the com test task. */
		xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof(signed char) );
		xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof(signed char) );

		if( xRxedChars == 0 )
		{
			queueFail = pdTRUE;
		}

		if( xCharsForTx == 0 )
		{
			queueFail = pdTRUE;
		}

		/* Initialize UART asynchronous mode */
		BGR0 = configCLKP1_CLOCK_HZ / ulWantedBaud;

		SCR0 = 0x17;	/* 8N1 */
		SMR0 = 0x0d;	/* enable SOT3, Reset, normal mode */
		SSR0 = 0x02;	/* LSB first, enable receive interrupts */

		PIER08_IE2 = 1; /* enable input */
		DDR08_D2 = 0;	/* switch P08_2 to input */
		DDR08_D3 = 1;	/* switch P08_3 to output */
	}
	portEXIT_CRITICAL();

	/* Unlike other ports, this serial code does not allow for more than one
	com port.  We therefore don't return a pointer to a port structure and can
	instead just return NULL. */
	return NULL;
}
Exemplo n.º 8
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 );
}
Exemplo n.º 9
0
static portTASK_FUNCTION( vPolledQueueProducer, pvParameters )
{
unsigned short usValue = ( unsigned short ) 0;
signed portBASE_TYPE xError = pdFALSE, xLoop;

	for( ;; )
	{		
		for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ )
		{
			/* Send an incrementing number on the queue without blocking. */
			if( xQueueSend( *( ( xQueueHandle * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS )
			{
				/* We should never find the queue full so if we get here there
				has been an error. */
				xError = pdTRUE;
			}
			else
			{
				if( xError == pdFALSE )
				{
					/* If an error has ever been recorded we stop incrementing the
					check variable. */
					portENTER_CRITICAL();
						xPollingProducerCount++;
					portEXIT_CRITICAL();
				}

				/* Update the value we are going to post next time around. */
				usValue++;
			}
		}

		/* Wait before we start posting again to ensure the consumer runs and
		empties the queue. */
		vTaskDelay( pollqPRODUCER_DELAY );
	}
}  /*lint !e818 Function prototype must conform to API. */
Exemplo n.º 10
0
void esp_task_wdt_delete() {
    TaskHandle_t handle=xTaskGetCurrentTaskHandle();
    wdt_task_t *wdttask=wdt_task_list;
    portENTER_CRITICAL(&taskwdt_spinlock);

    //Wdt task list can't be empty
    if (!wdt_task_list) {
        ESP_LOGE(TAG, "task_wdt_delete: No tasks in list?");
        portEXIT_CRITICAL(&taskwdt_spinlock);
        return;
    }
    if (handle==wdt_task_list) {
        //Current task is first on list.
        wdt_task_list=wdt_task_list->next;
        free(wdttask);
    } else {
        //Find current task in list
        if (wdt_task_list->task_handle==handle) {
            //Task is the very first one.
            wdt_task_t *freeme=wdt_task_list;
            wdt_task_list=wdt_task_list->next;
            free(freeme);
            portEXIT_CRITICAL(&taskwdt_spinlock);
            return;
        }
        while (wdttask->next!=NULL && wdttask->next->task_handle!=handle) wdttask=wdttask->next;
        if (!wdttask->next) {
            ESP_LOGE(TAG, "task_wdt_delete: Task never called task_wdt_feed!");
            portEXIT_CRITICAL(&taskwdt_spinlock);
            return;
        }
        wdt_task_t *freeme=wdttask->next;
        wdttask->next=wdttask->next->next;
        free(freeme);
    }
    portEXIT_CRITICAL(&taskwdt_spinlock);
}
Exemplo n.º 11
0
/*
 * See the serial2.h header file.
 */
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
    xComPortHandle xReturn = serHANDLE;

    /* Create the queues used to hold Rx and Tx characters. */
    xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
    xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) );

    /* If the queues were created correctly then setup the serial port
    hardware. */
    if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) {
        PMC_EnablePeripheral( AT91C_ID_US0 );
        portENTER_CRITICAL();
        {
            USART_Configure( serCOM0, ( AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE ), ulWantedBaud, configCPU_CLOCK_HZ );

            /* Enable Rx and Tx. */
            USART_SetTransmitterEnabled( serCOM0, pdTRUE );
            USART_SetReceiverEnabled( serCOM0, pdTRUE );

            /* Enable the Rx interrupts.  The Tx interrupts are not enabled
            until there are characters to be transmitted. */
            serCOM0->US_IER = AT91C_US_RXRDY;

            /* Enable the interrupts in the AIC. */
            AIC_ConfigureIT( AT91C_ID_US0, AT91C_AIC_PRIOR_LOWEST, ( void (*)( void ) ) vSerialISR );
            AIC_EnableIT( AT91C_ID_US0 );
        }
        portEXIT_CRITICAL();
    } else {
        xReturn = ( xComPortHandle ) 0;
    }

    /* This demo file only supports a single port but we have to return
    something to comply with the standard demo header file. */
    return xReturn;
}
Exemplo n.º 12
0
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime )
{
portBASE_TYPE xReturn = pdTRUE;

	portENTER_CRITICAL();
	{
		/* If the UART FIFO is full we can block posting the new data on the
		Tx queue. */
		if( XUartLite_mIsTransmitFull( XPAR_RS232_UART_BASEADDR ) )
		{
			if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
			{
				xReturn = pdFAIL;
			}
		}
		/* Otherwise, if there is data already in the queue we should add the
		new data to the back of the queue to ensure the sequencing is 
		maintained. */
		else if( uxQueueMessagesWaiting( xCharsForTx ) )
		{
			if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
			{
				xReturn = pdFAIL;
			}			
		}
		/* If the UART FIFO is not full and there is no data already in the
		queue we can write directly to the FIFO without disrupting the 
		sequence. */
		else
		{
			XIo_Out32( XPAR_RS232_UART_BASEADDR + XUL_TX_FIFO_OFFSET, cOutChar );
		}
	}
	portEXIT_CRITICAL();

	return xReturn;
}
Exemplo n.º 13
0
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
unsigned long ulBaudRateCounter;
unsigned char ucByte;

	portENTER_CRITICAL();
	{
		/* Create the queues used by the com test task. */
		xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
		xCharsForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );

		/* Calculate the baud rate register value from the equation in the
		data sheet. */
		ulBaudRateCounter = ( configCPU_CLOCK_HZ / ( serBAUD_DIV_CONSTANT * ulWantedBaud ) ) - ( unsigned long ) 1;

		/* Set the baud rate. */	
		ucByte = ( unsigned char ) ( ulBaudRateCounter & ( unsigned long ) 0xff );	
		outb( UBRRL, ucByte );

		ulBaudRateCounter >>= ( unsigned long ) 8;
		ucByte = ( unsigned char ) ( ulBaudRateCounter & ( unsigned long ) 0xff );	
		outb( UBRRH, ucByte );

		/* Enable the Rx interrupt.  The Tx interrupt will get enabled
		later. Also enable the Rx and Tx. */
		outb( UCSRB, serRX_INT_ENABLE | serRX_ENABLE | serTX_ENABLE );

		/* Set the data bits to 8. */
		outb( UCSRC, serUCSRC_SELECT | serEIGHT_DATA_BITS );
	}
	portEXIT_CRITICAL();
	
	/* Unlike other ports, this serial code does not allow for more than one
	com port.  We therefore don't return a pointer to a port structure and can
	instead just return NULL. */
	return NULL;
}
Exemplo n.º 14
0
void vParTestToggleLED( unsigned portBASE_TYPE uxLED )
{
    portENTER_CRITICAL();
    {
        switch( uxLED )
        {
        case 0:
            PTHD_PTHD3 = !PTHD_PTHD3;
            break;
        case 1:
            PTED_PTED5 = !PTED_PTED5;
            break;
        case 2:
            PTGD_PTGD5 = !PTGD_PTGD5;
            break;
        case 3:
            PTED_PTED3 = !!PTED_PTED3;
            break;
        default : /* There are no other LEDs. */
            break;
        }
    }
    portEXIT_CRITICAL();
}
Exemplo n.º 15
0
/**
 * \brief Creates and returns a new semaphore.
 *
 * \param count Initial state of the semaphore.
 *
 * \return ERR_OK for OK, other value indicates error.
 */
sys_sem_t sys_sem_new(u8_t count)
{
	sys_sem_t xSemaphore = SYS_SEM_NULL;

	portENTER_CRITICAL();

	vSemaphoreCreateBinary( xSemaphore );
	if (xSemaphore != SYS_SEM_NULL) {
#if SYS_STATS
		lwip_stats.sys.sem.used++;
		if (lwip_stats.sys.sem.used > lwip_stats.sys.sem.max) {
			lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
		}
#endif /* SYS_STATS */
		/* Means we want the sem to be unavailable at init state. */
		if (0 == count) {
			xSemaphoreTake( xSemaphore, 1);
		}
	}

	portEXIT_CRITICAL();

	return xSemaphore;
}
Exemplo n.º 16
0
static void AddUser(unsigned char User,unsigned int CrystalTicks)
{
  portENTER_CRITICAL();
  
  /* minimum value of 1 tick */
  if ( CrystalTicks < 1 )
  {
    CrystalTicks = 1;
  }  
  
  unsigned int CaptureTime = TA0R + CrystalTicks;

  /* clear ifg, add to ccr register, enable interrupt */
  switch (User)
  {
  case 0: TA0CCTL0 = 0; TA0CCR0 = CaptureTime; TA0CCTL0 = CCIE; break;
  case 1: TA0CCTL1 = 0; TA0CCR1 = CaptureTime; TA0CCTL1 = CCIE; break;
  case 2: TA0CCTL2 = 0; TA0CCR2 = CaptureTime; TA0CCTL2 = CCIE; break;
  case 3: TA0CCTL3 = 0; TA0CCR3 = CaptureTime; TA0CCTL3 = CCIE; break;
  case 4: TA0CCTL4 = 0; TA0CCR4 = CaptureTime; TA0CCTL4 = CCIE; break;
  default: break;
    
  }
  
  /* start counting up in continuous mode if not already doing so */
  if ( Timer0Users == 0 )
  {
    TA0CTL |= TASSEL_1 | MC_2 | ID_2; 
  }
  
  /* keep track of users */
  Timer0Users |= (1 << User);
  
  portEXIT_CRITICAL();
  
}
Exemplo n.º 17
0
void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
{
unsigned char ucLED = 1U;

	/* Only attempt to set the LED if it is in range. */
	if( uxLED < partstMAX_LED )
	{
		ucLED <<= ( unsigned char ) uxLED;

		portENTER_CRITICAL();
		{
			if( xValue == pdFALSE )
			{
				ucGPIOState &= ~ucLED;
			}
			else
			{
				ucGPIOState |= ucLED;
			}
			XGpio_DiscreteWrite( &xOutputGPIOInstance, uxGPIOOutputChannel, ucGPIOState );
		}
		portEXIT_CRITICAL();
	}
}
Exemplo n.º 18
0
 void RxThread()
 {
     while (1)
     {
         os_sem_wait(&rxSem);
         portENTER_CRITICAL();
         // we read the packet received to our assembly buffer
         bool result = readEP_NB(rxData, &rxSize);
         portEXIT_CRITICAL();
         if (!result)
         {
             diewith(0x80000CCC);
         }
         for (uint32_t i = 0; i < rxSize; i++)
         {
           /// @todo (balazs.racz) this needs to be replaced with something
           /// that works in the new select based model.
           //os_mq_send(rxQ, rxData + i);
         }
         rxSize = 0;
         // We reactivate the endpoint to receive next characters
         // readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
     }
 }
Exemplo n.º 19
0
/*******************************************************************************
 * FUNCTION: vLogStackWatermark
 *
 * PARAMETERS:
 * ~ szTaskName     - Task name.
 * ~ usWatermark    - Value for watermark.
 *
 * RETURN:
 * ~ void
 *
 * DESCRIPTIONS:
 * Log the RTOS low stack error.
 *
 *******************************************************************************/
void vLogStackWatermark(const char* szTaskName, unsigned short usWatermark)
{
    // Convert the watermark to string.
    char szWatermark[6];
    prv_vUShortToString(usWatermark, szWatermark);



    // Open the log file.
    xSemaphoreTake(xSdCardMutex, portMAX_DELAY);
    portENTER_CRITICAL();
    FSFILE *pxLogFile = FSfopen(pucLogFilePath, "a");


    // Write the message.
    const char szTxt1[] = "[Stack Error] ";
    FSfwrite(szTxt1, 1, sizeof(szTxt1) - 1, pxLogFile);
    FSfwrite(szTaskName, 1, strlen(szTaskName), pxLogFile);

    const char szTxt2[] = "    Watermark: ";
    FSfwrite(szTxt2, 1, sizeof(szTxt2) - 1, pxLogFile);
    FSfwrite(szWatermark, 1, strlen(szWatermark), pxLogFile);
    
    const char szTxt3[] = "    Firmware: ";
    FSfwrite(szTxt3, 1, sizeof(szTxt3) - 1, pxLogFile);
    FSfwrite(szFirmwareVersion, 1, strlen(szFirmwareVersion), pxLogFile);
    
    const char szCrLf[] = "\r\n";
    FSfwrite(szCrLf, 1, sizeof(szCrLf) - 1, pxLogFile);


    // Close the log file.
    FSfclose(pxLogFile);
    portEXIT_CRITICAL();
    xSemaphoreGive(xSdCardMutex);
}
Exemplo n.º 20
0
signed portBASE_TYPE xMutexGive( xMutexHandle pxMutex, portBASE_TYPE Release )
{
    portENTER_CRITICAL( );
    if ( pxMutex->pxOwner != xTaskGetCurrentTaskHandle( ) )
    {
        portEXIT_CRITICAL( );
        return pdFALSE;
    }

    if ( Release )
        pxMutex->uxCount = 0;
    else
    {
        if ( --pxMutex->uxCount != 0 )
        {
            portEXIT_CRITICAL( );
            return pdFALSE;
        }
    }

    if( !listLIST_IS_EMPTY( &pxMutex->xTasksWaitingToTake ) )
    {
        pxMutex->pxOwner = (xTaskHandle) listGET_OWNER_OF_HEAD_ENTRY( ( &pxMutex->xTasksWaitingToTake ) );
        pxMutex->uxCount = 1;

        if( xTaskRemoveFromEventList( &pxMutex->xTasksWaitingToTake ) == pdTRUE )
            taskYIELD( );
    }
    else
    {
        pxMutex->pxOwner = NULL;
    }

    portEXIT_CRITICAL( );
    return pdTRUE;
}
Exemplo n.º 21
0
/////////////////////////////////////////////////////////////////////////////
// This task is running endless in background
/////////////////////////////////////////////////////////////////////////////
void APP_Background(void)
{
  // clear LCD screen
  MIOS32_LCD_Clear();

  // endless loop: print status information on LCD
  while( 1 ) {
    // new message requested?
    // TODO: add FreeRTOS specific queue handling!
    u8 new_msg = PRINT_MSG_NONE;
    portENTER_CRITICAL(); // port specific FreeRTOS function to disable tasks (nested)
    if( print_msg ) {
      new_msg = print_msg;
      print_msg = PRINT_MSG_NONE; // clear request
    }
    portEXIT_CRITICAL(); // port specific FreeRTOS function to enable tasks (nested)

    switch( new_msg ) {
      case PRINT_MSG_INIT:
        MIOS32_LCD_CursorSet(0, 0);
        MIOS32_LCD_PrintString("see README.txt   ");
        MIOS32_LCD_CursorSet(0, 1);
        MIOS32_LCD_PrintString("for details     ");
	break;

      case PRINT_MSG_STATUS:
      {
        MIOS32_LCD_CursorSet(0, 0);

	// request status screen again (will stop once a new screen is requested by another task)
	print_msg = PRINT_MSG_STATUS;
      }
      break;
    }
  }
}
Exemplo n.º 22
0
/*
 * Controller task as described above.
 */
static void vCounterControlTask( void * pvParameters )
{
unsigned long ulLastCounter;
short sLoops;
short sError = pdFALSE;
const char * const pcTaskStartMsg = "Priority manipulation tasks started.\r\n";
const char * const pcTaskFailMsg = "Priority manipulation Task Failed\r\n";

	/* Just to stop warning messages. */
	( void ) pvParameters;

	/* Queue a message for printing to say the task has started. */
	vPrintDisplayMessage( &pcTaskStartMsg );

	for( ;; )
	{
		/* Start with the counter at zero. */
		ulCounter = ( unsigned long ) 0;

		/* First section : */

		/* Check the continuous count task is running. */
		for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
		{
			/* Suspend the continuous count task so we can take a mirror of the
			shared variable without risk of corruption. */
			vTaskSuspend( xContinuousIncrementHandle );
				ulLastCounter = ulCounter;
			vTaskResume( xContinuousIncrementHandle );
			
			/* Now delay to ensure the other task has processor time. */
			vTaskDelay( priSLEEP_TIME );

			/* Check the shared variable again.  This time to ensure mutual 
			exclusion the whole scheduler will be locked.  This is just for
			demo purposes! */
			vTaskSuspendAll();
			{
				if( ulLastCounter == ulCounter )
				{
					/* The shared variable has not changed.  There is a problem
					with the continuous count task so flag an error. */
					sError = pdTRUE;
					xTaskResumeAll();
						vPrintDisplayMessage( &pcTaskFailMsg );
					vTaskSuspendAll();
				}
			}
			xTaskResumeAll();
		}


		/* Second section: */

		/* Suspend the continuous counter task so it stops accessing the shared variable. */
		vTaskSuspend( xContinuousIncrementHandle );

		/* Reset the variable. */
		ulCounter = ( unsigned long ) 0;

		/* Resume the limited count task which has a higher priority than us.
		We should therefore not return from this call until the limited count
		task has suspended itself with a known value in the counter variable. 
		The scheduler suspension is not necessary but is included for test
		purposes. */
		vTaskSuspendAll();
			vTaskResume( xLimitedIncrementHandle );
		xTaskResumeAll();

		/* Does the counter variable have the expected value? */
		if( ulCounter != priMAX_COUNT )
		{
			sError = pdTRUE;
			vPrintDisplayMessage( &pcTaskFailMsg );
		}

		if( sError == pdFALSE )
		{
			/* If no errors have occurred then increment the check variable. */
			portENTER_CRITICAL();
				usCheckVariable++;
			portEXIT_CRITICAL();
		}

		#if configUSE_PREEMPTION == 0
			taskYIELD();
		#endif

		/* Resume the continuous count task and do it all again. */
		vTaskResume( xContinuousIncrementHandle );
	}
}
Exemplo n.º 23
0
static void prvChangePriorityWhenSuspendedTask( void *pvParameters )
{
const char * const pcTaskStartMsg = "Priority change when suspended task started.\r\n";
const char * const pcTaskFailMsg = "Priority change when suspended task failed.\r\n";

	/* Just to stop warning messages. */
	( void ) pvParameters;

	/* Queue a message for printing to say the task has started. */
	vPrintDisplayMessage( &pcTaskStartMsg );	
	
	for( ;; )
	{
		/* Start with the counter at 0 so we know what the counter should be
		when we check it next. */
		ulPrioritySetCounter = ( unsigned long ) 0;

		/* Resume the helper task.  At this time it has a priority lower than
		ours so no context switch should occur. */
		vTaskResume( xChangePriorityWhenSuspendedHandle );

		/* Check to ensure the task just resumed has not executed. */
		portENTER_CRITICAL();
		{
			if( ulPrioritySetCounter != ( unsigned long ) 0 )
			{
				xPriorityRaiseWhenSuspendedError = pdTRUE;
				vPrintDisplayMessage( &pcTaskFailMsg );
			}
		}
		portEXIT_CRITICAL();

		/* Now try raising the priority while the scheduler is suspended. */
		vTaskSuspendAll();
		{
			vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, ( configMAX_PRIORITIES - 1 ) );

			/* Again, even though the helper task has a priority greater than 
			ours, it should not have executed yet because the scheduler is
			suspended. */
			portENTER_CRITICAL();
			{
				if( ulPrioritySetCounter != ( unsigned long ) 0 )
				{
					xPriorityRaiseWhenSuspendedError = pdTRUE;
					vPrintDisplayMessage( &pcTaskFailMsg );
				}
			}
			portEXIT_CRITICAL();
		}
		xTaskResumeAll();
		
		/* Now the scheduler has been resumed the helper task should 
		immediately preempt us and execute.  When it executes it will increment
		the ulPrioritySetCounter exactly once before suspending itself.

		We should now always find the counter set to 1. */
		portENTER_CRITICAL();
		{
			if( ulPrioritySetCounter != ( unsigned long ) 1 )
			{
				xPriorityRaiseWhenSuspendedError = pdTRUE;
				vPrintDisplayMessage( &pcTaskFailMsg );
			}
		}
		portEXIT_CRITICAL();

		/* Delay until we try this again. */		
		vTaskDelay( priSLEEP_TIME * 2 );
		
		/* Set the priority of the helper task back ready for the next 
		execution of this task. */
		vTaskSuspendAll();
			vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, tskIDLE_PRIORITY );				
		xTaskResumeAll();				
	}
}
Exemplo n.º 24
0
/////////////////////////////////////////////////////////////////////////////
// Local encoder callback function
// Should return:
//   1 if value has been changed
//   0 if value hasn't been changed
//  -1 if invalid or unsupported encoder
/////////////////////////////////////////////////////////////////////////////
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
{
  // reset tap tempo if any encoder != GP16 has been pressed
  if( encoder != SEQ_UI_ENCODER_GP16 )
    resetTapTempo();


  switch( encoder ) {
    case SEQ_UI_ENCODER_GP1:
      ui_selected_item = ITEM_MODE;
      break;

    case SEQ_UI_ENCODER_GP2:
      ui_selected_item = ITEM_PRESET;
      break;

    case SEQ_UI_ENCODER_GP3:
      ui_selected_item = ITEM_BPM;
      // special feature: these two encoders increment *10
      incrementer *= 10;
      break;

    case SEQ_UI_ENCODER_GP4:
      ui_selected_item = ITEM_BPM;
      break;

    case SEQ_UI_ENCODER_GP5:
      ui_selected_item = ITEM_RAMP;
      break;

    case SEQ_UI_ENCODER_GP6:
    case SEQ_UI_ENCODER_GP7:
    case SEQ_UI_ENCODER_GP8:
      return -1; // not mapped to encoder

    case SEQ_UI_ENCODER_GP9:
      ui_selected_item = ITEM_MCLK_PORT;
      break;

    case SEQ_UI_ENCODER_GP10:
      ui_selected_item = ITEM_MCLK_IN;
      break;

    case SEQ_UI_ENCODER_GP11:
      ui_selected_item = ITEM_MCLK_OUT;
      break;

    case SEQ_UI_ENCODER_GP12:
    case SEQ_UI_ENCODER_GP13:
      return -1; // not used (yet)

    case SEQ_UI_ENCODER_GP14:
    case SEQ_UI_ENCODER_GP15:
      // external restart request should be atomic
      portENTER_CRITICAL();
      seq_core_state.EXT_RESTART_REQ = 1;
      portEXIT_CRITICAL();
      return 1;

    case SEQ_UI_ENCODER_GP16:
      SEQ_UI_BPM_TapTempo();
      return 1;
  }

  // for GP encoders and Datawheel
  switch( ui_selected_item ) {
    case ITEM_MODE: {
      u8 value = SEQ_BPM_ModeGet();
      if( SEQ_UI_Var8_Inc(&value, 0, 2, incrementer) ) {
	SEQ_BPM_ModeSet(value);
	store_file_required = 1;
	return 1; // value has been changed
      } else
	return 0; // value hasn't been changed
    } break;

    case ITEM_PRESET: {
      return SEQ_UI_Var8_Inc(&seq_core_bpm_preset_num, 0, SEQ_CORE_NUM_BPM_PRESETS-1, incrementer);
    } break;

    case ITEM_BPM: {
      u16 value = (u16)(seq_core_bpm_preset_tempo[seq_core_bpm_preset_num]*10);
      if( SEQ_UI_Var16_Inc(&value, 25, 3000, incrementer) ) { // at 384ppqn, the minimum BPM rate is ca. 2.5
	// set new BPM
      	seq_core_bpm_preset_tempo[seq_core_bpm_preset_num] = (float)value/10.0;
	SEQ_CORE_BPM_Update(seq_core_bpm_preset_tempo[seq_core_bpm_preset_num], seq_core_bpm_preset_ramp[seq_core_bpm_preset_num]);
	store_file_required = 1;
	return 1; // value has been changed
      } else
	return 0; // value hasn't been changed
    } break;

    case ITEM_RAMP: {
      u16 value = (u16)seq_core_bpm_preset_ramp[seq_core_bpm_preset_num];
      if( SEQ_UI_Var16_Inc(&value, 0, 99, incrementer) ) {
	seq_core_bpm_preset_ramp[seq_core_bpm_preset_num] = (float)value;
	store_file_required = 1;
	return 1; // value has been changed
      } else
	return 0; // value hasn't been changed
    } break;

    case ITEM_MCLK_PORT: {
      u8 port_ix = SEQ_MIDI_PORT_ClkIxGet(selected_mclk_port);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_ClkNumGet()-1, incrementer) >= 0 ) {
	selected_mclk_port = SEQ_MIDI_PORT_ClkPortGet(port_ix);
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_MCLK_IN: {
      s32 status = SEQ_MIDI_ROUTER_MIDIClockInGet(selected_mclk_port);
      if( status < 0 )
	return 0; // no change
      u8 enable = status;
      if( SEQ_UI_Var8_Inc(&enable, 0, 1, incrementer) >= 0 ) {
	SEQ_MIDI_ROUTER_MIDIClockInSet(selected_mclk_port, enable);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_MCLK_OUT: {
      s32 status = SEQ_MIDI_ROUTER_MIDIClockOutGet(selected_mclk_port);
      if( status < 0 )
	return 0; // no change
      u8 enable = status;
      if( SEQ_UI_Var8_Inc(&enable, 0, 1, incrementer) >= 0 ) {
	SEQ_MIDI_ROUTER_MIDIClockOutSet(selected_mclk_port, enable);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;
  }

  return -1; // invalid or unsupported encoder
}
Exemplo n.º 25
0
/*
 * See the serial2.h header file.
 */
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
xComPortHandle xReturn;
UART_InitTypeDef xUART1_Init;
GPIO_InitTypeDef GPIO_InitStructure;
	
	/* Create the queues used to hold Rx characters. */
	xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
	
	/* Create the semaphore used to wake a task waiting for space to become
	available in the FIFO. */
	vSemaphoreCreateBinary( xTxFIFOSemaphore );

	/* If the queue/semaphore was created correctly then setup the serial port
	hardware. */
	if( ( xRxedChars != serINVALID_QUEUE ) && ( xTxFIFOSemaphore != serINVALID_QUEUE ) )
	{
		/* Pre take the semaphore so a task will block if it tries to access
		it. */
		xSemaphoreTake( xTxFIFOSemaphore, 0 );
		
		/* Configure the UART. */
		xUART1_Init.UART_WordLength = UART_WordLength_8D;
		xUART1_Init.UART_StopBits = UART_StopBits_1;
		xUART1_Init.UART_Parity = UART_Parity_No;
		xUART1_Init.UART_BaudRate = ulWantedBaud;
		xUART1_Init.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
		xUART1_Init.UART_Mode = UART_Mode_Tx_Rx;
		xUART1_Init.UART_FIFO = UART_FIFO_Enable;

		/* Enable the UART1 Clock */
		SCU_APBPeriphClockConfig( __UART1, ENABLE );
		
		/* Enable the GPIO3 Clock */
		SCU_APBPeriphClockConfig( __GPIO3, ENABLE );
		
		/* Configure UART1_Rx pin GPIO3.2 */
		GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
		GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
		GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
		GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1 ;
		GPIO_Init( GPIO3, &GPIO_InitStructure );
		
		/* Configure UART1_Tx pin GPIO3.3 */
		GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
		GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
		GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
		GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2 ;
		GPIO_Init( GPIO3, &GPIO_InitStructure );
		
		
		portENTER_CRITICAL();
		{		
			/* Configure the UART itself. */
			UART_DeInit( UART1 );		
			UART_Init( UART1, &xUART1_Init );
			UART_ITConfig( UART1, UART_IT_Receive | UART_IT_Transmit, ENABLE );
			UART1->ICR = serCLEAR_ALL_INTERRUPTS;
			UART_LoopBackConfig( UART1, DISABLE );
			UART_IrDACmd( IrDA1, DISABLE );

			/* Configure the VIC for the UART interrupts. */			
			VIC_Config( UART1_ITLine, VIC_IRQ, 9 );
			VIC_ITCmd( UART1_ITLine, ENABLE );

			UART_Cmd( UART1, ENABLE );			
			lTaskWaiting = pdFALSE;
		}
		portEXIT_CRITICAL();
	}
	else
	{
		xReturn = ( xComPortHandle ) 0;
	}

	/* This demo file only supports a single port but we have to return
	something to comply with the standard demo header file. */
	return xReturn;
}
Exemplo n.º 26
0
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
uint32_t *pulUpperCSA = NULL;
uint32_t *pulLowerCSA = NULL;

	/* 16 Address Registers (4 Address registers are global), 16 Data
	Registers, and 3 System Registers.

	There are 3 registers that track the CSAs.
		FCX points to the head of globally free set of CSAs.
		PCX for the task needs to point to Lower->Upper->NULL arrangement.
		LCX points to the last free CSA so that corrective action can be taken.

	Need two CSAs to store the context of a task.
		The upper context contains D8-D15, A10-A15, PSW and PCXI->NULL.
		The lower context contains D0-D7, A2-A7, A11 and PCXI->UpperContext.
		The pxCurrentTCB->pxTopOfStack points to the Lower Context RSLCX matching the initial BISR.
		The Lower Context points to the Upper Context ready for the return from the interrupt handler.

	 The Real stack pointer for the task is stored in the A10 which is restored
	 with the upper context. */

	/* Have to disable interrupts here because the CSAs are going to be
	manipulated. */
	portENTER_CRITICAL();
	{
		/* DSync to ensure that buffering is not a problem. */
		_dsync();

		/* Consume two free CSAs. */
		pulLowerCSA = portCSA_TO_ADDRESS( _mfcr( $FCX ) );
		if( NULL != pulLowerCSA )
		{
			/* The Lower Links to the Upper. */
			pulUpperCSA = portCSA_TO_ADDRESS( pulLowerCSA[ 0 ] );
		}

		/* Check that we have successfully reserved two CSAs. */
		if( ( NULL != pulLowerCSA ) && ( NULL != pulUpperCSA ) )
		{
			/* Remove the two consumed CSAs from the free CSA list. */
			_disable();
			_dsync();
			_mtcr( $FCX, pulUpperCSA[ 0 ] );
			_isync();
			_enable();
		}
		else
		{
			/* Simply trigger a context list depletion trap. */
			_svlcx();
		}
	}
	portEXIT_CRITICAL();

	/* Clear the upper CSA. */
	memset( pulUpperCSA, 0, portNUM_WORDS_IN_CSA * sizeof( uint32_t ) );

	/* Upper Context. */
	pulUpperCSA[ 2 ] = ( uint32_t )pxTopOfStack;		/* A10;	Stack Return aka Stack Pointer */
	pulUpperCSA[ 1 ] = portSYSTEM_PROGRAM_STATUS_WORD;		/* PSW	*/

	/* Clear the lower CSA. */
	memset( pulLowerCSA, 0, portNUM_WORDS_IN_CSA * sizeof( uint32_t ) );

	/* Lower Context. */
	pulLowerCSA[ 8 ] = ( uint32_t ) pvParameters;		/* A4;	Address Type Parameter Register	*/
	pulLowerCSA[ 1 ] = ( uint32_t ) pxCode;			/* A11;	Return Address aka RA */

	/* PCXI pointing to the Upper context. */
	pulLowerCSA[ 0 ] = ( portINITIAL_PCXI_UPPER_CONTEXT_WORD | ( uint32_t ) portADDRESS_TO_CSA( pulUpperCSA ) );

	/* Save the link to the CSA in the top of stack. */
	pxTopOfStack = (uint32_t * ) portADDRESS_TO_CSA( pulLowerCSA );

	/* DSync to ensure that buffering is not a problem. */
	_dsync();

	return pxTopOfStack;
}
Exemplo n.º 27
0
signed portBASE_TYPE uart0Init (unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength)
{
  unsigned portLONG ulDivisor;
  unsigned portLONG ulWantedClock;
  static unsigned portLONG sulWantedBaud = 9600;
  static unsigned portBASE_TYPE suxQueueLength = 64;

  if (!ulWantedBaud)
    ulWantedBaud = sulWantedBaud;

  sulWantedBaud = ulWantedBaud;

  if (!uxQueueLength)
    uxQueueLength = suxQueueLength;

  suxQueueLength = uxQueueLength;

  uart0ISRCreateQueues (uxQueueLength, &xRX0Queue, &xTX0Queue, &plTHREEmpty0);

  if ((xRX0Queue == serINVALID_QUEUE) || (xTX0Queue == serINVALID_QUEUE) || (ulWantedBaud == (unsigned portLONG) 0))
    return 0;

  portENTER_CRITICAL ();

  {
    PCB_PINSEL0 = (PCB_PINSEL0 & ~(PCB_PINSEL0_P00_MASK | PCB_PINSEL0_P01_MASK)) | (PCB_PINSEL0_P00_TXD0 | PCB_PINSEL0_P01_RXD0);

    SCB_PCONP |= SCB_PCONP_PCUART0;

    //
    //  Setup the baud rate:  Calculate the divisor value
    //
    ulWantedClock = ulWantedBaud * serWANTED_CLOCK_SCALING;
    ulDivisor = configCPU_CLOCK_HZ / ulWantedClock;

    //
    //  Set the DLAB bit so we can access the divisor
    //
    UART0_LCR |= UART_LCR_DLAB;

    //
    //  Setup the divisor
    //
    UART0_DLL = (unsigned portCHAR) (ulDivisor & (unsigned portLONG) 0xff);
    ulDivisor >>= 8;
    UART0_DLM = (unsigned portCHAR) (ulDivisor & (unsigned portLONG) 0xff);

    //
    //  Turn on the FIFO's and clear the buffers
    //
    UART0_FCR = UART_FCR_EN | UART_FCR_CLR;

    //
    //  Setup transmission format
    //
    UART0_LCR = UART_LCR_NOPAR | UART_LCR_1STOP | UART_LCR_8BITS;

    //
    //  Setup the VIC for the UART
    //
    VIC_IntSelect &= ~VIC_IntSelect_UART0;
    VIC_VectAddr2 = (portLONG) uart0ISR;
    VIC_VectCntl2 = VIC_VectCntl_ENABLE | VIC_Channel_UART0;
    VIC_IntEnable = VIC_IntEnable_UART0;

    //
    //  Enable UART0 interrupts
    //
    UART0_IER |= UART_IER_EI;
  }

  portEXIT_CRITICAL ();

  return 1;
}
Exemplo n.º 28
0
void vuIP_Task( void *pvParameters )
{
portBASE_TYPE i;
uip_ipaddr_t xIPAddr;
struct timer periodic_timer, arp_timer;
extern void ( vEMAC_ISR_Wrapper )( void );

	/* Create the semaphore used by the ISR to wake this task. */
	vSemaphoreCreateBinary( xEMACSemaphore );
	
	/* Initialise the uIP stack. */
	timer_set( &periodic_timer, configTICK_RATE_HZ / 2 );
	timer_set( &arp_timer, configTICK_RATE_HZ * 10 );
	uip_init();
	uip_ipaddr( xIPAddr, uipIP_ADDR0, uipIP_ADDR1, uipIP_ADDR2, uipIP_ADDR3 );
	uip_sethostaddr( xIPAddr );
	httpd_init();

	/* Initialise the MAC. */
	while( Init_EMAC() != pdPASS )
    {
        vTaskDelay( uipINIT_WAIT );
    }

	portENTER_CRITICAL();
	{
		MAC_INTENABLE = INT_RX_DONE;
        VICIntEnable |= 0x00200000;
        VICVectAddr21 = ( portLONG ) vEMAC_ISR_Wrapper;
		prvSetMACAddress();
	}
	portEXIT_CRITICAL();
	

	for( ;; )
	{
		/* Is there received data ready to be processed? */
		uip_len = uiGetEMACRxData( uip_buf );
		
		if( uip_len > 0 )
		{
			/* Standard uIP loop taken from the uIP manual. */
			if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
			{
				uip_arp_ipin();
				uip_input();

				/* If the above function invocation resulted in data that 
				should be sent out on the network, the global variable 
				uip_len is set to a value > 0. */
				if( uip_len > 0 )
				{
					uip_arp_out();
					prvENET_Send();
				}
			}
			else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
			{
				uip_arp_arpin();

				/* If the above function invocation resulted in data that 
				should be sent out on the network, the global variable 
				uip_len is set to a value > 0. */
				if( uip_len > 0 )
				{
					prvENET_Send();
				}
			}
		}
		else
		{
			if( timer_expired( &periodic_timer ) )
			{
				timer_reset( &periodic_timer );
				for( i = 0; i < UIP_CONNS; i++ )
				{
					uip_periodic( i );
	
					/* If the above function invocation resulted in data that 
					should be sent out on the network, the global variable 
					uip_len is set to a value > 0. */
					if( uip_len > 0 )
					{
						uip_arp_out();
						prvENET_Send();
					}
				}	
	
				/* Call the ARP timer function every 10 seconds. */
				if( timer_expired( &arp_timer ) )
				{
					timer_reset( &arp_timer );
					uip_arp_timer();
				}
			}
			else
			{			
				/* We did not receive a packet, and there was no periodic
				processing to perform.  Block for a fixed period.  If a packet
				is received during this period we will be woken by the ISR
				giving us the Semaphore. */
				xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 );			
			}
		}
	}
}
Exemplo n.º 29
0
	__weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
	{
	uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
	TickType_t xModifiableIdleTime;

		/* Make sure the SysTick reload value does not overflow the counter. */
		if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
		{
			xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
		}

		/* Stop the SysTick momentarily.  The time the SysTick is stopped for
		is accounted for as best it can be, but using the tickless mode will
		inevitably result in some tiny drift of the time maintained by the
		kernel with respect to calendar time. */
		portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;

		/* Calculate the reload value required to wait xExpectedIdleTime
		tick periods.  -1 is used because this code will execute part way
		through one of the tick periods. */
		ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
		if( ulReloadValue > ulStoppedTimerCompensation )
		{
			ulReloadValue -= ulStoppedTimerCompensation;
		}

		/* Enter a critical section but don't use the taskENTER_CRITICAL()
		method as that will mask interrupts that should exit sleep mode. */
		__disable_irq();

		/* If a context switch is pending or a task is waiting for the scheduler
		to be unsuspended then abandon the low power entry. */
		if( eTaskConfirmSleepModeStatus() == eAbortSleep )
		{
			/* Restart from whatever is left in the count register to complete
			this tick period. */
			portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;

			/* Restart SysTick. */
			portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;

			/* Reset the reload register to the value required for normal tick
			periods. */
			portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;

			/* Re-enable interrupts - see comments above __disable_irq() call
			above. */
			__enable_irq();
		}
		else
		{
			/* Set the new reload value. */
			portNVIC_SYSTICK_LOAD_REG = ulReloadValue;

			/* Clear the SysTick count flag and set the count value back to
			zero. */
			portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;

			/* Restart SysTick. */
			portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;

			/* Sleep until something happens.  configPRE_SLEEP_PROCESSING() can
			set its parameter to 0 to indicate that its implementation contains
			its own wait for interrupt or wait for event instruction, and so wfi
			should not be executed again.  However, the original expected idle
			time variable must remain unmodified, so a copy is taken. */
			xModifiableIdleTime = xExpectedIdleTime;
			configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
			if( xModifiableIdleTime > 0 )
			{
				__dsb( portSY_FULL_READ_WRITE );
				__wfi();
				__isb( portSY_FULL_READ_WRITE );
			}
			configPOST_SLEEP_PROCESSING( xExpectedIdleTime );

			/* Stop SysTick.  Again, the time the SysTick is stopped for is
			accounted for as best it can be, but using the tickless mode will
			inevitably result in some tiny drift of the time maintained by the
			kernel with respect to calendar time. */
			ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
			portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );

			/* Re-enable interrupts - see comments above __disable_irq() call
			above. */
			__enable_irq();

			if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
			{
				uint32_t ulCalculatedLoadValue;

				/* The tick interrupt has already executed, and the SysTick
				count reloaded with ulReloadValue.  Reset the
				portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
				period. */
				ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );

				/* Don't allow a tiny value, or values that have somehow
				underflowed because the post sleep hook did something
				that took too long. */
				if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
				{
					ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
				}

				portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;

				/* The tick interrupt handler will already have pended the tick
				processing in the kernel.  As the pending tick will be
				processed as soon as this function exits, the tick value
				maintained by the tick is stepped forward by one less than the
				time spent waiting. */
				ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
			}
			else
			{
				/* Something other than the tick interrupt ended the sleep.
				Work out how long the sleep lasted rounded to complete tick
				periods (not the ulReload value which accounted for part
				ticks). */
				ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;

				/* How many complete tick periods passed while the processor
				was waiting? */
				ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;

				/* The reload value is set to whatever fraction of a single tick
				period remains. */
				portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
			}

			/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
			again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
			value.  The critical section is used to ensure the tick interrupt
			can only execute once in the case that the reload register is near
			zero. */
			portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
			portENTER_CRITICAL();
			{
				portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
				vTaskStepTick( ulCompleteTickPeriods );
				portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
			}
			portEXIT_CRITICAL();
		}
	}
Exemplo n.º 30
0
// 受信
bool clBTLUSB::Rx(PACKET_t &packet) {
    if (m_Rx.Size <= 0) return false;	// クリティカルセクションは時間がかかるため、最初に一度チェックする

    portENTER_CRITICAL();

    unsigned int size = m_Rx.Size;
    if (size <= 0) {		// 二重にチェック
        portEXIT_CRITICAL();
        return false;
    }

    bool result = false;

    // キュー内のインデックスを計算
    unsigned int next = m_Rx.Next;
    unsigned int index = LowerWrap(next - size, RX_QUEUELEVEL);

    //xprintf("rx(idx=%X)\n", index);

    // 最初のパケットを取得
    unsigned int dest, msg, frame;
    const SPACKET_t *spacket = (const SPACKET_t*)m_Rx.Buf[index];
    dest	= spacket->Dest;
    msg		= spacket->Msg;
    frame	= spacket->Frame;
    //xprintf("rx(sp=%08X)\n", spacket);

    if (frame < size) {
        if (frame < RX_MAX_DIVISION) {
            //xprintf("rx(dest=%X)\n", dest);

            // キューの中に一連のパケットが納まっているか
            unsigned int cnt = 0;
            unsigned int total_length = 0;
            signed int start_index = index;
            while(cnt <= frame) {
                spacket = (const SPACKET_t*)m_Rx.Buf[index];
                if (spacket->Dest != dest) break;
                if (spacket->Msg != msg) break;
                if (spacket->Frame != (frame - cnt)) break;

                total_length += spacket->Length;

                cnt++;
                index = IncAndWrap(index, RX_QUEUELEVEL);
            }

            if ((frame < cnt) && (total_length <= MAX_PAYLOADSIZE)) {
                index = start_index;

                // 実際にコピー
                packet.Dest		= dest;
                packet.Msg		= msg;
                packet.Length	= total_length;

                frame++;
                size -= frame;

                char *data = packet.Data;
                do {
                    spacket = (const SPACKET_t*)m_Rx.Buf[index];
                    memcpy(data, spacket->Data, spacket->Length);
                    data += spacket->Length;

                    index = IncAndWrap(index, RX_QUEUELEVEL);
                } while(0 < --frame);

                /*xprintf("rx(%d,%d,%d)[", spacket->Dest, spacket->Msg, spacket->Length);
                put_dump(packet.Data, 0, spacket->Length, DW_CHAR);
                xputs("]\n");*/

                //xprintf("rx(%X,%X)(%d)[%08X]\n", dest, msg, total_length, Adler32(packet.Data, total_length));
                //xprintf("%d rx(%X,%X)(%d)\n", xTaskGetTickCount(), dest, msg, total_length);

                result = true;
            } else {
                // データが異常なので廃棄
                size--;
                xprintf("rx(err1)\n");
            }
        } else {
            // データが異常なので廃棄
            size--;
            xprintf("rx(err2)\n");
        }

        m_Rx.Size = size;

        // データが受信できることを通知
        USB::Data::RxReady();
    } else {
        m_Rx.FrameLacking = true;
        //xprintf("rx(lack)\n");
    }

    portEXIT_CRITICAL();

    return result;
}