/*
 * FreeRTOS Kernel V10.3.0
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://www.FreeRTOS.org
 * http://aws.amazon.com/freertos
 *
 * 1 tab == 4 spaces!
 */

/* ****************************************************************************
 * When configCREATE_LOW_POWER_DEMO is set to 1 in FreeRTOSConfig.h main() will
 * call main_low_power(), which is defined in this file.  main_low_power()
 * demonstrates FreeRTOS tick suppression being used to allow the MCU to be
 * placed into both the low power deep sleep mode and the low power software
 * standby mode.  When configCREATE_LOW_POWER_DEMO is set to 0 main will
 * instead call main_full(), which is a more comprehensive RTOS demonstration.
 * ****************************************************************************
 *
 * This application demonstrates the FreeRTOS tickless idle mode (tick
 * suppression).  See http://www.freertos.org/low-power-tickless-rtos.html
 * The demo is configured to execute on the Renesas RX100 RSK.
 *
 *  Functionality:
 *
 *  + Two tasks are created, an Rx task and a Tx task.
 *
 *  + The Rx task repeatedly blocks on a queue to wait for data.  The Rx task
 *    toggles LED 0 each time is receives a value from the queue.
 *
 *  + The Tx task repeatedly enters the Blocked state for an amount of time
 *    that is set by the position of the potentiometer.  On exiting the blocked
 *    state the Tx task sends a value through the queue to the Rx task (causing
 *    the Rx task to exit the blocked state and toggle LED 0).
 *
 *    If the value read from the potentiometer is less than or equal to
 *    mainSOFTWARE_STANDBY_DELAY then the Tx task blocks for the equivalent
 *    number of milliseconds.  For example, if the sampled analog value is
 *    2000, then the Tx task blocks for 2000ms.  Blocking for a finite period
 *    allows the kernel to stop the tick interrupt and place the RX100 into
 *    deep sleep mode.
 *
 *    If the value read form the potentiometer is greater than
 *    mainSOFTWARE_STANDBY_DELAY then the Tx task blocks on a semaphore with
 *    an infinite timeout.  Blocking with an infinite timeout allows the kernel
 *    to stop the tick interrupt and place the RX100 into software standby
 *    mode.  Pressing a button will generate an interrupt that causes the RX100
 *    to exit software standby mode.  The interrupt service routine 'gives' the
 *    semaphore to unblock the Tx task.
 *
 *
 *  Using the Demo and Observed Behaviour:
 *
 *  1) Turn the potentiometer completely counter clockwise.
 *
 *  2) Program the RX100 with the application, then disconnect the programming/
 *   debugging hardware to ensure power readings are not effected by any
 *   connected interfaces.
 *
 *  3) Start the application running.  LED 0 will toggle quickly because the
 *   potentiometer is turned to its lowest value.  LED 1 will be illuminated
 *   when the RX100 is not in a power saving mode, but will appear to be off
 *   because most execution time is spent in a sleep mode.  Led 2 will be
 *   illuminated when the RX100 is in deep sleep mode, and will appear to be
 *   always on, again because most execution time is spent in deep sleep mode.
 *   The LEDs are turned on and off by the application defined pre and post
 *   sleep macros (see the definitions of configPRE_SLEEP_PROCESSING() and
 *   configPOST_SLEEP_PROCESSING() in FreeRTOSConfig.h).
 *
 *  4) Slowly turn the potentiometer in the clockwise direction.  This will
 *   increase the value read from the potentiometer, which will increase the
 *   time the Tx task spends in the Blocked state, which will therefore
 *   decrease the frequency at which the Tx task sends data to the queue (and
 *   the rate at which LED 0 is toggled).
 *
 *  5) Keep turning the potentiometer in the clockwise direction.  Eventually
 *   the value read from the potentiometer will go above
 *   mainSOFTWARE_STANDBY_DELAY, causing the Tx task to block on the semaphore
 *   with an infinite timeout.  LED 0 will stop toggling because the Tx task is
 *   no longer sending to the queue.  LED 1 and LED 2 will both be off because
 *   the RX100 is neither running or in deep sleep mode (it is in software
 *   standby mode).
 *
 *  6) Turn the potentiometer counter clockwise again to ensure its value goes
 *   back below mainSOFTWARE_STANDBY_DELAY.
 *
 *  7) Press any of the three buttons to generate an interrupt.  The interrupt
 *   will take the RX100 out of software standby mode, and the interrupt
 *   service routine will unblock the Tx task by 'giving' the semaphore.  LED 0
 *   will then start to toggle again.
 *
 */


/* Hardware specific includes. */
#include "platform.h"
#include "r_switches_if.h"

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/* Common demo includes. */
#include "partest.h"

/* Priorities at which the Rx and Tx tasks are created. */
#define configQUEUE_RECEIVE_TASK_PRIORITY	( tskIDLE_PRIORITY + 1 )
#define	configQUEUE_SEND_TASK_PRIORITY		( tskIDLE_PRIORITY + 2 )

/* The number of items the queue can hold.  This is 1 as the Rx task will
remove items as they are added so the Tx task should always find the queue
empty. */
#define mainQUEUE_LENGTH					( 1 )

/* The LED used to indicate that a value has been received on the queue. */
#define mainQUEUE_LED						( 0 )

/* The LED used to indicate that full power is being used (the MCU is not in
deep sleep or software standby mode). */
#define mainFULL_POWER_LED					( 1 )

/* The LED used to indicate that deep sleep mode is being used. */
#define mainDEEP_SLEEP_LED					( 2 )

/* The Tx task sends to the queue with a frequency that is set by the value
read from the potentiometer until the value goes above that set by the
mainSOFTWARE_STANDBY_DELAY constant - at which time the Tx task instead blocks
indefinitely on a semaphore. */
#define mainSOFTWARE_STANDBY_DELAY			( 3000UL )

/* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK						( 0 )

/* The value that is sent from the Tx task to the Rx task on the queue. */
#define mainQUEUED_VALUE					( 100UL )

/*-----------------------------------------------------------*/

/*
 * The Rx and Tx tasks as described at the top of this file.
 */
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );

/*
 * Reads and returns the value of the ADC connected to the potentiometer built
 * onto the RSK.
 */
static unsigned short prvReadPOT( void );

/*
 * The handler for the interrupt generated when any of the buttons are pressed.
 */
__interrupt void vButtonInterrupt( void );

/*-----------------------------------------------------------*/

/* The queue to pass data from the Tx task to the Rx task. */
static QueueHandle_t xQueue = NULL;

/* The semaphore that is 'given' by interrupts generated from button pushes. */
static SemaphoreHandle_t xSemaphore = NULL;

/*-----------------------------------------------------------*/

void main_low_power( void )
{
	/* Create the queue. */
	xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
	configASSERT( xQueue );

	/* Create the semaphore that is 'given' by an interrupt generated from a
	button push. */
	vSemaphoreCreateBinary( xSemaphore );
	configASSERT( xSemaphore );

	/* Make sure the semaphore starts in the expected state - no button pushes
	have yet occurred.  A block time of zero can be used as it is guaranteed
	that the semaphore will be available because it has just been created. */
	xSemaphoreTake( xSemaphore, mainDONT_BLOCK );

	/* Start the two tasks as described at the top of this file. */
	xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, configQUEUE_RECEIVE_TASK_PRIORITY, NULL );
	xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, configQUEUE_SEND_TASK_PRIORITY, NULL );

	/* The CPU is currently running, not sleeping, so turn on the LED that
	shows the CPU is not in a sleep mode. */
	vParTestSetLED( mainFULL_POWER_LED, pdTRUE );

	/* Start the scheduler running running. */
	vTaskStartScheduler();

	/* If all is well the next line of code will not be reached as the
	scheduler will be running.  If the next line is reached then it is likely
	there was insufficient FreeRTOS heap available for the idle task and/or
	timer task to be created.  See http://www.freertos.org/a00111.html. */
	for( ;; );
}
/*-----------------------------------------------------------*/

static void prvQueueSendTask( void *pvParameters )
{
TickType_t xDelay;
const unsigned long ulValueToSend = mainQUEUED_VALUE;

	/* Remove compiler warning about unused parameter. */
	( void ) pvParameters;

	for( ;; )
	{
		/* The delay period between successive sends to the queue is set by
		the potentiometer reading. */
		xDelay = ( TickType_t ) prvReadPOT();

		/* If the block time is greater than 3000 milliseconds then block
		indefinitely waiting for a button push. */
		if( xDelay > mainSOFTWARE_STANDBY_DELAY )
		{
			/* As this is an indefinite delay the kernel will place the CPU
			into software standby mode the next time the idle task runs. */
			xSemaphoreTake( xSemaphore, portMAX_DELAY );
		}
		else
		{
			/* Convert a time in milliseconds to a time in ticks. */
			xDelay /= portTICK_PERIOD_MS;

			/* Place this task in the blocked state until it is time to run
			again.  As this is not an indefinite sleep the kernel will place
			the CPU into the deep sleep state when the idle task next runs. */
			vTaskDelay( xDelay );
		}

		/* Send to the queue - causing the queue receive task to flash its LED.
		It should not be necessary to block on the queue send because the Rx
		task will have removed the last queued item. */
		xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
	}
}
/*-----------------------------------------------------------*/

static void prvQueueReceiveTask( void *pvParameters )
{
unsigned long ulReceivedValue;

	/* Remove compiler warning about unused parameter. */
	( void ) pvParameters;

	for( ;; )
	{
		/* Wait until something arrives in the queue - this will block
		indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
		FreeRTOSConfig.h. */
		xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );

		/*  To get here something must have arrived, but is it the expected
		value?  If it is, toggle the LED. */
		if( ulReceivedValue == mainQUEUED_VALUE )
		{
			vParTestToggleLED( mainQUEUE_LED );
		}
	}
}
/*-----------------------------------------------------------*/

void vPreSleepProcessing( unsigned long ulExpectedIdleTime )
{
	/* Called by the kernel before it places the MCU into a sleep mode because
	configPRE_SLEEP_PROCESSING() is #defined to vPreSleepProcessing().

	NOTE:  Additional actions can be taken here to get the power consumption
	even lower.  For example, the ADC input used by this demo could be turned
	off here, and then back on again in the post sleep processing function.
	For maximum power saving ensure all unused pins are in their lowest power
	state. */

	/* Avoid compiler warnings about the unused parameter. */
	( void ) ulExpectedIdleTime;

	/* Is the MCU about to enter deep sleep mode or software standby mode? */
	if( SYSTEM.SBYCR.BIT.SSBY == 0 )
	{
		/* Turn on the LED that indicates deep sleep mode is being entered. */
		vParTestSetLED( mainDEEP_SLEEP_LED, pdTRUE );
	}
	else
	{
		/* Software standby mode is being used, so no LEDs are illuminated to
		ensure minimum power readings are obtained.  Ensure the Queue LED is
		also off. */
		vParTestSetLED( mainQUEUE_LED, pdFALSE );
	}

	/* Turn off the LED that indicates full power is being used. */
	vParTestSetLED( mainFULL_POWER_LED, pdFALSE );
}
/*-----------------------------------------------------------*/

void vPostSleepProcessing( unsigned long ulExpectedIdleTime )
{
	/* Called by the kernel when the MCU exits a sleep mode because
	configPOST_SLEEP_PROCESSING is #defined to vPostSleepProcessing(). */

	/* Avoid compiler warnings about the unused parameter. */
	( void ) ulExpectedIdleTime;

	/* Turn off the LED that indicates deep sleep mode, and turn on the LED
	that indicates full power is being used. */
	vParTestSetLED( mainDEEP_SLEEP_LED, pdFALSE );
	vParTestSetLED( mainFULL_POWER_LED, pdTRUE );
}
/*-----------------------------------------------------------*/

static unsigned short prvReadPOT( void )
{
unsigned short usADCValue;
const unsigned short usMinADCValue = 128;

	/* Start an ADC scan. */
	S12AD.ADCSR.BIT.ADST = 1;
	while( S12AD.ADCSR.BIT.ADST == 1 )
	{
		/* Just waiting for the ADC scan to complete.  Inefficient
		polling! */
	}

	usADCValue = S12AD.ADDR4;

	/* Don't let the ADC value get too small as the LED behaviour will look
	erratic. */
	if( usADCValue < usMinADCValue )
	{
		usADCValue = usMinADCValue;
	}

	return usADCValue;
}
/*-----------------------------------------------------------*/

#pragma vector = VECT_ICU_IRQ0, VECT_ICU_IRQ1, VECT_ICU_IRQ4
__interrupt void vButtonInterrupt1( void )
{
long lHigherPriorityTaskWoken = pdFALSE;

	/* The semaphore is only created when the build is configured to create the
	low power demo. */
	if( xSemaphore != NULL )
	{
		/* This interrupt will bring the CPU out of deep sleep and software
		standby	modes.  Give the semaphore that was used to place the Tx task
		into an indefinite sleep. */
		if( uxQueueMessagesWaitingFromISR( xSemaphore ) == 0 )
		{
			xSemaphoreGiveFromISR( xSemaphore, &lHigherPriorityTaskWoken );
		}
		else
		{
			/* The semaphore was already available, so the task is not blocked
			on it and there is no point giving it. */
		}

		/* If giving the semaphore caused a task to leave the Blocked state,
		and the task that left the Blocked state has a priority equal to or
		above the priority of the task that this interrupt interrupted, then
		lHigherPriorityTaskWoken will have been set to pdTRUE inside the call
		to xSemaphoreGiveFromISR(), and calling portYIELD_FROM_ISR() will cause
		a context switch to the unblocked task. */
		portYIELD_FROM_ISR( lHigherPriorityTaskWoken );
	}
}

