Complete first release candidate for the SAM4S-EK demo.
parent
c8c7c80116
commit
02c347d45d
Binary file not shown.
@ -0,0 +1,304 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong? *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest information,
|
||||||
|
license and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This version of comtest. c is for use on systems that have limited stack
|
||||||
|
* space and no display facilities. The complete version can be found in
|
||||||
|
* the Demo/Common/Full directory.
|
||||||
|
*
|
||||||
|
* Creates two tasks that operate on an interrupt driven serial port. A
|
||||||
|
* loopback connector should be used so that everything that is transmitted is
|
||||||
|
* also received. The serial port does not use any flow control. On a
|
||||||
|
* standard 9way 'D' connector pins two and three should be connected together.
|
||||||
|
*
|
||||||
|
* The first task posts a sequence of characters to the Tx queue, toggling an
|
||||||
|
* LED on each successful post. At the end of the sequence it sleeps for a
|
||||||
|
* pseudo-random period before resending the same sequence.
|
||||||
|
*
|
||||||
|
* The UART Tx end interrupt is enabled whenever data is available in the Tx
|
||||||
|
* queue. The Tx end ISR removes a single character from the Tx queue and
|
||||||
|
* passes it to the UART for transmission.
|
||||||
|
*
|
||||||
|
* The second task blocks on the Rx queue waiting for a character to become
|
||||||
|
* available. When the UART Rx end interrupt receives a character it places
|
||||||
|
* it in the Rx queue, waking the second task. The second task checks that the
|
||||||
|
* characters removed from the Rx queue form the same sequence as those posted
|
||||||
|
* to the Tx queue, and toggles an LED for each correct character.
|
||||||
|
*
|
||||||
|
* The receiving task is spawned with a higher priority than the transmitting
|
||||||
|
* task. The receiver will therefore wake every time a character is
|
||||||
|
* transmitted so neither the Tx or Rx queue should ever hold more than a few
|
||||||
|
* characters.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "demo_serial.h"
|
||||||
|
#include "comtest2.h"
|
||||||
|
#include "partest.h"
|
||||||
|
|
||||||
|
#define comSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
#define comTX_LED_OFFSET ( 0 )
|
||||||
|
#define comRX_LED_OFFSET ( 1 )
|
||||||
|
#define comTOTAL_PERMISSIBLE_ERRORS ( 2 )
|
||||||
|
|
||||||
|
/* The Tx task will transmit the sequence of characters at a pseudo random
|
||||||
|
interval. This is the maximum and minimum block time between sends. */
|
||||||
|
#define comTX_MAX_BLOCK_TIME ( ( portTickType ) 0x96 )
|
||||||
|
#define comTX_MIN_BLOCK_TIME ( ( portTickType ) 0x32 )
|
||||||
|
#define comOFFSET_TIME ( ( portTickType ) 3 )
|
||||||
|
|
||||||
|
/* We should find that each character can be queued for Tx immediately and we
|
||||||
|
don't have to block to send. */
|
||||||
|
#define comNO_BLOCK ( ( portTickType ) 0 )
|
||||||
|
|
||||||
|
/* The Rx task will block on the Rx queue for a long period. */
|
||||||
|
#define comRX_BLOCK_TIME ( ( portTickType ) 0xffff )
|
||||||
|
|
||||||
|
/* The sequence transmitted is from comFIRST_BYTE to and including comLAST_BYTE. */
|
||||||
|
#define comFIRST_BYTE ( 'A' )
|
||||||
|
#define comLAST_BYTE ( 'X' )
|
||||||
|
|
||||||
|
#define comBUFFER_LEN ( ( unsigned portBASE_TYPE ) ( comLAST_BYTE - comFIRST_BYTE ) + ( unsigned portBASE_TYPE ) 1 )
|
||||||
|
#define comINITIAL_RX_COUNT_VALUE ( 0 )
|
||||||
|
|
||||||
|
/* Handle to the com port used by both tasks. */
|
||||||
|
static xComPortHandle xPort = NULL;
|
||||||
|
|
||||||
|
/* The transmit task as described at the top of the file. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vComTxTask, pvParameters );
|
||||||
|
|
||||||
|
/* The receive task as described at the top of the file. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vComRxTask, pvParameters );
|
||||||
|
|
||||||
|
/* The LED that should be toggled by the Rx and Tx tasks. The Rx task will
|
||||||
|
toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task will toggle LED
|
||||||
|
( uxBaseLED + comTX_LED_OFFSET ). */
|
||||||
|
static unsigned portBASE_TYPE uxBaseLED = 0;
|
||||||
|
|
||||||
|
/* Check variable used to ensure no error have occurred. The Rx task will
|
||||||
|
increment this variable after every successfully received sequence. If at any
|
||||||
|
time the sequence is incorrect the the variable will stop being incremented. */
|
||||||
|
static volatile unsigned portBASE_TYPE uxRxLoops = comINITIAL_RX_COUNT_VALUE;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vAltStartComTestTasks( unsigned portBASE_TYPE uxPriority, unsigned long ulBaudRate, unsigned portBASE_TYPE uxLED )
|
||||||
|
{
|
||||||
|
/* Initialise the com port then spawn the Rx and Tx tasks. */
|
||||||
|
uxBaseLED = uxLED;
|
||||||
|
xSerialPortInitMinimal( ulBaudRate, comBUFFER_LEN );
|
||||||
|
|
||||||
|
/* The Tx task is spawned with a lower priority than the Rx task. */
|
||||||
|
xTaskCreate( vComTxTask, ( signed char * ) "COMTx", comSTACK_SIZE, NULL, uxPriority - 1, ( xTaskHandle * ) NULL );
|
||||||
|
xTaskCreate( vComRxTask, ( signed char * ) "COMRx", comSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vComTxTask, pvParameters )
|
||||||
|
{
|
||||||
|
signed char cByteToSend;
|
||||||
|
portTickType xTimeToWait;
|
||||||
|
|
||||||
|
/* Just to stop compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Simply transmit a sequence of characters from comFIRST_BYTE to
|
||||||
|
comLAST_BYTE. */
|
||||||
|
for( cByteToSend = comFIRST_BYTE; cByteToSend <= comLAST_BYTE; cByteToSend++ )
|
||||||
|
{
|
||||||
|
if( xSerialPutChar( xPort, cByteToSend, comNO_BLOCK ) == pdPASS )
|
||||||
|
{
|
||||||
|
vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn the LED off while we are not doing anything. */
|
||||||
|
vParTestSetLED( uxBaseLED + comTX_LED_OFFSET, pdFALSE );
|
||||||
|
|
||||||
|
/* We have posted all the characters in the string - wait before
|
||||||
|
re-sending. Wait a pseudo-random time as this will provide a better
|
||||||
|
test. */
|
||||||
|
xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME;
|
||||||
|
|
||||||
|
/* Make sure we don't wait too long... */
|
||||||
|
xTimeToWait %= comTX_MAX_BLOCK_TIME;
|
||||||
|
|
||||||
|
/* ...but we do want to wait. */
|
||||||
|
if( xTimeToWait < comTX_MIN_BLOCK_TIME )
|
||||||
|
{
|
||||||
|
xTimeToWait = comTX_MIN_BLOCK_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay( xTimeToWait );
|
||||||
|
}
|
||||||
|
} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vComRxTask, pvParameters )
|
||||||
|
{
|
||||||
|
signed char cExpectedByte, cByteRxed;
|
||||||
|
portBASE_TYPE xResyncRequired = pdFALSE, xErrorOccurred = pdFALSE;
|
||||||
|
|
||||||
|
/* Just to stop compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* We expect to receive the characters from comFIRST_BYTE to
|
||||||
|
comLAST_BYTE in an incrementing order. Loop to receive each byte. */
|
||||||
|
for( cExpectedByte = comFIRST_BYTE; cExpectedByte <= comLAST_BYTE; cExpectedByte++ )
|
||||||
|
{
|
||||||
|
/* Block on the queue that contains received bytes until a byte is
|
||||||
|
available. */
|
||||||
|
if( xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ) )
|
||||||
|
{
|
||||||
|
/* Was this the byte we were expecting? If so, toggle the LED,
|
||||||
|
otherwise we are out on sync and should break out of the loop
|
||||||
|
until the expected character sequence is about to restart. */
|
||||||
|
if( cByteRxed == cExpectedByte )
|
||||||
|
{
|
||||||
|
vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xResyncRequired = pdTRUE;
|
||||||
|
break; /*lint !e960 Non-switch break allowed. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn the LED off while we are not doing anything. */
|
||||||
|
vParTestSetLED( uxBaseLED + comRX_LED_OFFSET, pdFALSE );
|
||||||
|
|
||||||
|
/* Did we break out of the loop because the characters were received in
|
||||||
|
an unexpected order? If so wait here until the character sequence is
|
||||||
|
about to restart. */
|
||||||
|
if( xResyncRequired == pdTRUE )
|
||||||
|
{
|
||||||
|
while( cByteRxed != comLAST_BYTE )
|
||||||
|
{
|
||||||
|
/* Block until the next char is available. */
|
||||||
|
xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note that an error occurred which caused us to have to resync.
|
||||||
|
We use this to stop incrementing the loop counter so
|
||||||
|
sAreComTestTasksStillRunning() will return false - indicating an
|
||||||
|
error. */
|
||||||
|
xErrorOccurred++;
|
||||||
|
|
||||||
|
/* We have now resynced with the Tx task and can continue. */
|
||||||
|
xResyncRequired = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( xErrorOccurred < comTOTAL_PERMISSIBLE_ERRORS )
|
||||||
|
{
|
||||||
|
/* Increment the count of successful loops. As error
|
||||||
|
occurring (i.e. an unexpected character being received) will
|
||||||
|
prevent this counter being incremented for the rest of the
|
||||||
|
execution. Don't worry about mutual exclusion on this
|
||||||
|
variable - it doesn't really matter as we just want it
|
||||||
|
to change. */
|
||||||
|
uxRxLoops++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xAreComTestTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xReturn;
|
||||||
|
|
||||||
|
/* If the count of successful reception loops has not changed than at
|
||||||
|
some time an error occurred (i.e. a character was received out of sequence)
|
||||||
|
and we will return false. */
|
||||||
|
if( uxRxLoops == comINITIAL_RX_COUNT_VALUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the count of successful Rx loops. When this function is called
|
||||||
|
again we expect this to have been incremented. */
|
||||||
|
uxRxLoops = comINITIAL_RX_COUNT_VALUE;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong? *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest information,
|
||||||
|
license and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repeatedly toggles one or more LEDs using software timers - one timer per
|
||||||
|
* LED.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "partest.h"
|
||||||
|
#include "flash_timer.h"
|
||||||
|
|
||||||
|
/* The toggle rates are all a multple of ledFLASH_RATE_BASE. */
|
||||||
|
#define ledFLASH_RATE_BASE ( ( ( portTickType ) 333 ) / portTICK_RATE_MS )
|
||||||
|
|
||||||
|
/* A block time of zero simple means "don't block". */
|
||||||
|
#define ledDONT_BLOCK ( ( portTickType ) 0 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The callback function used by each LED flashing timer. All the timers use
|
||||||
|
* this function, and the timer ID is used within the function to determine
|
||||||
|
* which timer has actually expired.
|
||||||
|
*/
|
||||||
|
static void prvLEDTimerCallback( xTimerHandle xTimer );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartLEDFlashTimers( unsigned portBASE_TYPE uxNumberOfLEDs )
|
||||||
|
{
|
||||||
|
unsigned portBASE_TYPE uxLEDTimer;
|
||||||
|
xTimerHandle xTimer;
|
||||||
|
|
||||||
|
/* Create and start the requested number of timers. */
|
||||||
|
for( uxLEDTimer = 0; uxLEDTimer < uxNumberOfLEDs; ++uxLEDTimer )
|
||||||
|
{
|
||||||
|
/* Create the timer. */
|
||||||
|
xTimer = xTimerCreate( ( const signed char * const ) "Flasher",/* A text name, purely to help debugging. */
|
||||||
|
ledFLASH_RATE_BASE * ( uxLEDTimer + 1 ), /* The timer period, which is a multiple of ledFLASH_RATE_BASE. */
|
||||||
|
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
|
||||||
|
( void * ) uxLEDTimer, /* The ID is used to identify the timer within the timer callback function, as each timer uses the same callback. */
|
||||||
|
prvLEDTimerCallback /* Each timer uses the same callback. */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* If the timer was created successfully, attempt to start it. If the
|
||||||
|
scheduler has not yet been started then the timer command queue must
|
||||||
|
be long enough to hold each command sent to it until such time that the
|
||||||
|
scheduler is started. The timer command queue length is set by
|
||||||
|
configTIMER_QUEUE_LENGTH in FreeRTOSConfig.h. */
|
||||||
|
if( xTimer != NULL )
|
||||||
|
{
|
||||||
|
xTimerStart( xTimer, ledDONT_BLOCK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvLEDTimerCallback( xTimerHandle xTimer )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xTimerID;
|
||||||
|
|
||||||
|
/* The timer ID is used to identify the timer that has actually expired as
|
||||||
|
each timer uses the same callback. The ID is then also used as the number
|
||||||
|
of the LED that is to be toggled. */
|
||||||
|
xTimerID = ( portBASE_TYPE ) pvTimerGetTimerID( xTimer );
|
||||||
|
vParTestToggleLED( xTimerID );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong? *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest information,
|
||||||
|
license and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMTEST_H
|
||||||
|
#define COMTEST_H
|
||||||
|
|
||||||
|
void vAltStartComTestTasks( unsigned portBASE_TYPE uxPriority, unsigned long ulBaudRate, unsigned portBASE_TYPE uxLED );
|
||||||
|
portBASE_TYPE xAreComTestTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong? *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest information,
|
||||||
|
license and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SERIAL_COMMS_H
|
||||||
|
#define SERIAL_COMMS_H
|
||||||
|
|
||||||
|
typedef void * xComPortHandle;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
serCOM1,
|
||||||
|
serCOM2,
|
||||||
|
serCOM3,
|
||||||
|
serCOM4,
|
||||||
|
serCOM5,
|
||||||
|
serCOM6,
|
||||||
|
serCOM7,
|
||||||
|
serCOM8
|
||||||
|
} eCOMPort;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
serNO_PARITY,
|
||||||
|
serODD_PARITY,
|
||||||
|
serEVEN_PARITY,
|
||||||
|
serMARK_PARITY,
|
||||||
|
serSPACE_PARITY
|
||||||
|
} eParity;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
serSTOP_1,
|
||||||
|
serSTOP_2
|
||||||
|
} eStopBits;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
serBITS_5,
|
||||||
|
serBITS_6,
|
||||||
|
serBITS_7,
|
||||||
|
serBITS_8
|
||||||
|
} eDataBits;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ser50,
|
||||||
|
ser75,
|
||||||
|
ser110,
|
||||||
|
ser134,
|
||||||
|
ser150,
|
||||||
|
ser200,
|
||||||
|
ser300,
|
||||||
|
ser600,
|
||||||
|
ser1200,
|
||||||
|
ser1800,
|
||||||
|
ser2400,
|
||||||
|
ser4800,
|
||||||
|
ser9600,
|
||||||
|
ser19200,
|
||||||
|
ser38400,
|
||||||
|
ser57600,
|
||||||
|
ser115200
|
||||||
|
} eBaud;
|
||||||
|
|
||||||
|
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength );
|
||||||
|
xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength );
|
||||||
|
void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength );
|
||||||
|
signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime );
|
||||||
|
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime );
|
||||||
|
portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort );
|
||||||
|
void vSerialClose( xComPortHandle xPort );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong? *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest information,
|
||||||
|
license and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLASH_TIMER_H
|
||||||
|
#define FLASH_TIMER_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates the LED flashing timers. xNumberOfLEDs specifies how many timers to
|
||||||
|
* create, with each timer toggling a different LED. The first LED to be
|
||||||
|
* toggled is LED 0, with subsequent LEDs following on in numerical order. Each
|
||||||
|
* timer uses the exact same callback function, with the timer ID being used
|
||||||
|
* within the callback function to determine which timer has actually expired
|
||||||
|
* (and therefore which LED to toggle).
|
||||||
|
*/
|
||||||
|
void vStartLEDFlashTimers( unsigned portBASE_TYPE uxNumberOfLEDs );
|
||||||
|
|
||||||
|
#endif /* FLASH_TIMER_H */
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong? *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest information,
|
||||||
|
license and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PARTEST_H
|
||||||
|
#define PARTEST_H
|
||||||
|
|
||||||
|
#define partstDEFAULT_PORT_ADDRESS ( ( unsigned short ) 0x378 )
|
||||||
|
|
||||||
|
void vParTestInitialise( void );
|
||||||
|
void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue );
|
||||||
|
void vParTestToggleLED( unsigned portBASE_TYPE uxLED );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,172 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Generic clock management
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef CLK_GENCLK_H_INCLUDED
|
||||||
|
#define CLK_GENCLK_H_INCLUDED
|
||||||
|
|
||||||
|
#include "parts.h"
|
||||||
|
|
||||||
|
#if SAM3S
|
||||||
|
# include "sam3s/genclk.h"
|
||||||
|
#elif SAM3U
|
||||||
|
# include "sam3u/genclk.h"
|
||||||
|
#elif SAM3N
|
||||||
|
# include "sam3n/genclk.h"
|
||||||
|
#elif SAM3XA
|
||||||
|
# include "sam3x/genclk.h"
|
||||||
|
#elif SAM4S
|
||||||
|
# include "sam4s/genclk.h"
|
||||||
|
#elif (UC3A0 || UC3A1)
|
||||||
|
# include "uc3a0_a1/genclk.h"
|
||||||
|
#elif UC3A3
|
||||||
|
# include "uc3a3_a4/genclk.h"
|
||||||
|
#elif UC3B
|
||||||
|
# include "uc3b0_b1/genclk.h"
|
||||||
|
#elif UC3C
|
||||||
|
# include "uc3c/genclk.h"
|
||||||
|
#elif UC3D
|
||||||
|
# include "uc3d/genclk.h"
|
||||||
|
#elif UC3L
|
||||||
|
# include "uc3l/genclk.h"
|
||||||
|
#else
|
||||||
|
# error Unsupported chip type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup clk_group
|
||||||
|
* \defgroup genclk_group Generic Clock Management
|
||||||
|
*
|
||||||
|
* Generic clocks are configurable clocks which run outside the system
|
||||||
|
* clock domain. They are often connected to peripherals which have an
|
||||||
|
* asynchronous component running independently of the bus clock, e.g.
|
||||||
|
* USB controllers, low-power timers and RTCs, etc.
|
||||||
|
*
|
||||||
|
* Note that not all platforms have support for generic clocks; on such
|
||||||
|
* platforms, this API will not be available.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def GENCLK_DIV_MAX
|
||||||
|
* \brief Maximum divider supported by the generic clock implementation
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \enum genclk_source
|
||||||
|
* \brief Generic clock source ID
|
||||||
|
*
|
||||||
|
* Each generic clock may be generated from a different clock source.
|
||||||
|
* These are the available alternatives provided by the chip.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \name Generic clock configuration
|
||||||
|
//@{
|
||||||
|
/**
|
||||||
|
* \struct genclk_config
|
||||||
|
* \brief Hardware representation of a set of generic clock parameters
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void genclk_config_defaults(struct genclk_config *cfg,
|
||||||
|
* unsigned int id)
|
||||||
|
* \brief Initialize \a cfg to the default configuration for the clock
|
||||||
|
* identified by \a id.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id)
|
||||||
|
* \brief Read the currently active configuration of the clock
|
||||||
|
* identified by \a id into \a cfg.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void genclk_config_write(const struct genclk_config *cfg,
|
||||||
|
* unsigned int id)
|
||||||
|
* \brief Activate the configuration \a cfg on the clock identified by
|
||||||
|
* \a id.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void genclk_config_set_source(struct genclk_config *cfg,
|
||||||
|
* enum genclk_source src)
|
||||||
|
* \brief Select a new source clock \a src in configuration \a cfg.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void genclk_config_set_divider(struct genclk_config *cfg,
|
||||||
|
* unsigned int divider)
|
||||||
|
* \brief Set a new \a divider in configuration \a cfg.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void genclk_enable_source(enum genclk_source src)
|
||||||
|
* \brief Enable the source clock \a src used by a generic clock.
|
||||||
|
*/
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name Enabling and disabling Generic Clocks
|
||||||
|
//@{
|
||||||
|
/**
|
||||||
|
* \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id)
|
||||||
|
* \brief Activate the configuration \a cfg on the clock identified by
|
||||||
|
* \a id and enable it.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void genclk_disable(unsigned int id)
|
||||||
|
* \brief Disable the generic clock identified by \a id.
|
||||||
|
*/
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Enable the configuration defined by \a src and \a divider
|
||||||
|
* for the generic clock identified by \a id.
|
||||||
|
*
|
||||||
|
* \param id The ID of the generic clock.
|
||||||
|
* \param src The source clock of the generic clock.
|
||||||
|
* \param divider The divider used to generate the generic clock.
|
||||||
|
*/
|
||||||
|
static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider)
|
||||||
|
{
|
||||||
|
struct genclk_config gcfg;
|
||||||
|
|
||||||
|
genclk_config_defaults(&gcfg, id);
|
||||||
|
genclk_enable_source(src);
|
||||||
|
genclk_config_set_source(&gcfg, src);
|
||||||
|
genclk_config_set_divider(&gcfg, divider);
|
||||||
|
genclk_enable(&gcfg, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
#endif /* CLK_GENCLK_H_INCLUDED */
|
@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Oscillator management
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OSC_H_INCLUDED
|
||||||
|
#define OSC_H_INCLUDED
|
||||||
|
|
||||||
|
#include "parts.h"
|
||||||
|
#include "conf_clock.h"
|
||||||
|
|
||||||
|
#if SAM3S
|
||||||
|
# include "sam3s/osc.h"
|
||||||
|
#elif SAM3XA
|
||||||
|
# include "sam3x/osc.h"
|
||||||
|
#elif SAM3U
|
||||||
|
# include "sam3u/osc.h"
|
||||||
|
#elif SAM3N
|
||||||
|
# include "sam3n/osc.h"
|
||||||
|
#elif SAM4S
|
||||||
|
# include "sam4s/osc.h"
|
||||||
|
#elif (UC3A0 || UC3A1)
|
||||||
|
# include "uc3a0_a1/osc.h"
|
||||||
|
#elif UC3A3
|
||||||
|
# include "uc3a3_a4/osc.h"
|
||||||
|
#elif UC3B
|
||||||
|
# include "uc3b0_b1/osc.h"
|
||||||
|
#elif UC3C
|
||||||
|
# include "uc3c/osc.h"
|
||||||
|
#elif UC3D
|
||||||
|
# include "uc3d/osc.h"
|
||||||
|
#elif UC3L
|
||||||
|
# include "uc3l/osc.h"
|
||||||
|
#elif XMEGA
|
||||||
|
# include "xmega/osc.h"
|
||||||
|
#else
|
||||||
|
# error Unsupported chip type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup clk_group
|
||||||
|
* \defgroup osc_group Oscillator Management
|
||||||
|
*
|
||||||
|
* This group contains functions and definitions related to configuring
|
||||||
|
* and enabling/disabling on-chip oscillators. Internal RC-oscillators,
|
||||||
|
* external crystal oscillators and external clock generators are
|
||||||
|
* supported by this module. What all of these have in common is that
|
||||||
|
* they swing at a fixed, nominal frequency which is normally not
|
||||||
|
* adjustable.
|
||||||
|
*
|
||||||
|
* \par Example: Enabling an oscillator
|
||||||
|
*
|
||||||
|
* The following example demonstrates how to enable the external
|
||||||
|
* oscillator on XMEGA A and wait for it to be ready to use. The
|
||||||
|
* oscillator identifiers are platform-specific, so while the same
|
||||||
|
* procedure is used on all platforms, the parameter to osc_enable()
|
||||||
|
* will be different from device to device.
|
||||||
|
* \code
|
||||||
|
osc_enable(OSC_ID_XOSC);
|
||||||
|
osc_wait_ready(OSC_ID_XOSC); \endcode
|
||||||
|
*
|
||||||
|
* \section osc_group_board Board-specific Definitions
|
||||||
|
* If external oscillators are used, the board code must provide the
|
||||||
|
* following definitions for each of those:
|
||||||
|
* - \b BOARD_<osc name>_HZ: The nominal frequency of the oscillator.
|
||||||
|
* - \b BOARD_<osc name>_STARTUP_US: The startup time of the
|
||||||
|
* oscillator in microseconds.
|
||||||
|
* - \b BOARD_<osc name>_TYPE: The type of oscillator connected, i.e.
|
||||||
|
* whether it's a crystal or external clock, and sometimes what kind
|
||||||
|
* of crystal it is. The meaning of this value is platform-specific.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \name Oscillator Management
|
||||||
|
//@{
|
||||||
|
/**
|
||||||
|
* \fn void osc_enable(uint8_t id)
|
||||||
|
* \brief Enable oscillator \a id
|
||||||
|
*
|
||||||
|
* The startup time and mode value is automatically determined based on
|
||||||
|
* definitions in the board code.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void osc_disable(uint8_t id)
|
||||||
|
* \brief Disable oscillator \a id
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn osc_is_ready(uint8_t id)
|
||||||
|
* \brief Determine whether oscillator \a id is ready.
|
||||||
|
* \retval true Oscillator \a id is running and ready to use as a clock
|
||||||
|
* source.
|
||||||
|
* \retval false Oscillator \a id is not running.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn uint32_t osc_get_rate(uint8_t id)
|
||||||
|
* \brief Return the frequency of oscillator \a id in Hz
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Wait until the oscillator identified by \a id is ready
|
||||||
|
*
|
||||||
|
* This function will busy-wait for the oscillator identified by \a id
|
||||||
|
* to become stable and ready to use as a clock source.
|
||||||
|
*
|
||||||
|
* \param id A number identifying the oscillator to wait for.
|
||||||
|
*/
|
||||||
|
static inline void osc_wait_ready(uint8_t id)
|
||||||
|
{
|
||||||
|
while (!osc_is_ready(id)) {
|
||||||
|
/* Do nothing */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
#endif /* OSC_H_INCLUDED */
|
@ -0,0 +1,314 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief PLL management
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef CLK_PLL_H_INCLUDED
|
||||||
|
#define CLK_PLL_H_INCLUDED
|
||||||
|
|
||||||
|
#include "parts.h"
|
||||||
|
#include "conf_clock.h"
|
||||||
|
|
||||||
|
#if SAM3S
|
||||||
|
# include "sam3s/pll.h"
|
||||||
|
#elif SAM3XA
|
||||||
|
# include "sam3x/pll.h"
|
||||||
|
#elif SAM3U
|
||||||
|
# include "sam3u/pll.h"
|
||||||
|
#elif SAM3N
|
||||||
|
# include "sam3n/pll.h"
|
||||||
|
#elif SAM4S
|
||||||
|
# include "sam4s/pll.h"
|
||||||
|
#elif (UC3A0 || UC3A1)
|
||||||
|
# include "uc3a0_a1/pll.h"
|
||||||
|
#elif UC3A3
|
||||||
|
# include "uc3a3_a4/pll.h"
|
||||||
|
#elif UC3B
|
||||||
|
# include "uc3b0_b1/pll.h"
|
||||||
|
#elif UC3C
|
||||||
|
# include "uc3c/pll.h"
|
||||||
|
#elif UC3D
|
||||||
|
# include "uc3d/pll.h"
|
||||||
|
#elif (UC3L0128 || UC3L0256 || UC3L3_L4)
|
||||||
|
# include "uc3l/pll.h"
|
||||||
|
#elif XMEGA
|
||||||
|
# include "xmega/pll.h"
|
||||||
|
#else
|
||||||
|
# error Unsupported chip type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup clk_group
|
||||||
|
* \defgroup pll_group PLL Management
|
||||||
|
*
|
||||||
|
* This group contains functions and definitions related to configuring
|
||||||
|
* and enabling/disabling on-chip PLLs. A PLL will take an input signal
|
||||||
|
* (the \em source), optionally divide the frequency by a configurable
|
||||||
|
* \em divider, and then multiply the frequency by a configurable \em
|
||||||
|
* multiplier.
|
||||||
|
*
|
||||||
|
* Some devices don't support input dividers; specifying any other
|
||||||
|
* divisor than 1 on these devices will result in an assertion failure.
|
||||||
|
* Other devices may have various restrictions to the frequency range of
|
||||||
|
* the input and output signals.
|
||||||
|
*
|
||||||
|
* \par Example: Setting up PLL0 with default parameters
|
||||||
|
*
|
||||||
|
* The following example shows how to configure and enable PLL0 using
|
||||||
|
* the default parameters specified using the configuration symbols
|
||||||
|
* listed above.
|
||||||
|
* \code
|
||||||
|
pll_enable_config_defaults(0); \endcode
|
||||||
|
*
|
||||||
|
* To configure, enable PLL0 using the default parameters and to disable
|
||||||
|
* a specific feature like Wide Bandwidth Mode (a UC3A3-specific
|
||||||
|
* PLL option.), you can use this initialization process.
|
||||||
|
* \code
|
||||||
|
struct pll_config pllcfg;
|
||||||
|
if (pll_is_locked(pll_id)) {
|
||||||
|
return; // Pll already running
|
||||||
|
}
|
||||||
|
pll_enable_source(CONFIG_PLL0_SOURCE);
|
||||||
|
pll_config_defaults(&pllcfg, 0);
|
||||||
|
pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE);
|
||||||
|
pll_enable(&pllcfg, 0);
|
||||||
|
pll_wait_for_lock(0); \endcode
|
||||||
|
*
|
||||||
|
* When the last function call returns, PLL0 is ready to be used as the
|
||||||
|
* main system clock source.
|
||||||
|
*
|
||||||
|
* \section pll_group_config Configuration Symbols
|
||||||
|
*
|
||||||
|
* Each PLL has a set of default parameters determined by the following
|
||||||
|
* configuration symbols in the application's configuration file:
|
||||||
|
* - \b CONFIG_PLLn_SOURCE: The default clock source connected to the
|
||||||
|
* input of PLL \a n. Must be one of the values defined by the
|
||||||
|
* #pll_source enum.
|
||||||
|
* - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL
|
||||||
|
* \a n.
|
||||||
|
* - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n.
|
||||||
|
*
|
||||||
|
* These configuration symbols determine the result of calling
|
||||||
|
* pll_config_defaults() and pll_get_default_rate().
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \name Chip-specific PLL characteristics
|
||||||
|
//@{
|
||||||
|
/**
|
||||||
|
* \def PLL_MAX_STARTUP_CYCLES
|
||||||
|
* \brief Maximum PLL startup time in number of slow clock cycles
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \def NR_PLLS
|
||||||
|
* \brief Number of on-chip PLLs
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def PLL_MIN_HZ
|
||||||
|
* \brief Minimum frequency that the PLL can generate
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \def PLL_MAX_HZ
|
||||||
|
* \brief Maximum frequency that the PLL can generate
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \def PLL_NR_OPTIONS
|
||||||
|
* \brief Number of PLL option bits
|
||||||
|
*/
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \enum pll_source
|
||||||
|
* \brief PLL clock source
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \name PLL configuration
|
||||||
|
//@{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \struct pll_config
|
||||||
|
* \brief Hardware-specific representation of PLL configuration.
|
||||||
|
*
|
||||||
|
* This structure contains one or more device-specific values
|
||||||
|
* representing the current PLL configuration. The contents of this
|
||||||
|
* structure is typically different from platform to platform, and the
|
||||||
|
* user should not access any fields except through the PLL
|
||||||
|
* configuration API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn void pll_config_init(struct pll_config *cfg,
|
||||||
|
* enum pll_source src, unsigned int div, unsigned int mul)
|
||||||
|
* \brief Initialize PLL configuration from standard parameters.
|
||||||
|
*
|
||||||
|
* \note This function may be defined inline because it is assumed to be
|
||||||
|
* called very few times, and usually with constant parameters. Inlining
|
||||||
|
* it will in such cases reduce the code size significantly.
|
||||||
|
*
|
||||||
|
* \param cfg The PLL configuration to be initialized.
|
||||||
|
* \param src The oscillator to be used as input to the PLL.
|
||||||
|
* \param div PLL input divider.
|
||||||
|
* \param mul PLL loop divider (i.e. multiplier).
|
||||||
|
*
|
||||||
|
* \return A configuration which will make the PLL run at
|
||||||
|
* (\a mul / \a div) times the frequency of \a src
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \def pll_config_defaults(cfg, pll_id)
|
||||||
|
* \brief Initialize PLL configuration using default parameters.
|
||||||
|
*
|
||||||
|
* After this function returns, \a cfg will contain a configuration
|
||||||
|
* which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV)
|
||||||
|
* times the frequency of CONFIG_PLLx_SOURCE.
|
||||||
|
*
|
||||||
|
* \param cfg The PLL configuration to be initialized.
|
||||||
|
* \param pll_id Use defaults for this PLL.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \def pll_get_default_rate(pll_id)
|
||||||
|
* \brief Get the default rate in Hz of \a pll_id
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void pll_config_set_option(struct pll_config *cfg,
|
||||||
|
* unsigned int option)
|
||||||
|
* \brief Set the PLL option bit \a option in the configuration \a cfg.
|
||||||
|
*
|
||||||
|
* \param cfg The PLL configuration to be changed.
|
||||||
|
* \param option The PLL option bit to be set.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void pll_config_clear_option(struct pll_config *cfg,
|
||||||
|
* unsigned int option)
|
||||||
|
* \brief Clear the PLL option bit \a option in the configuration \a cfg.
|
||||||
|
*
|
||||||
|
* \param cfg The PLL configuration to be changed.
|
||||||
|
* \param option The PLL option bit to be cleared.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id)
|
||||||
|
* \brief Read the currently active configuration of \a pll_id.
|
||||||
|
*
|
||||||
|
* \param cfg The configuration object into which to store the currently
|
||||||
|
* active configuration.
|
||||||
|
* \param pll_id The ID of the PLL to be accessed.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void pll_config_write(const struct pll_config *cfg,
|
||||||
|
* unsigned int pll_id)
|
||||||
|
* \brief Activate the configuration \a cfg on \a pll_id
|
||||||
|
*
|
||||||
|
* \param cfg The configuration object representing the PLL
|
||||||
|
* configuration to be activated.
|
||||||
|
* \param pll_id The ID of the PLL to be updated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name Interaction with the PLL hardware
|
||||||
|
//@{
|
||||||
|
/**
|
||||||
|
* \fn void pll_enable(const struct pll_config *cfg,
|
||||||
|
* unsigned int pll_id)
|
||||||
|
* \brief Activate the configuration \a cfg and enable PLL \a pll_id.
|
||||||
|
*
|
||||||
|
* \param cfg The PLL configuration to be activated.
|
||||||
|
* \param pll_id The ID of the PLL to be enabled.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void pll_disable(unsigned int pll_id)
|
||||||
|
* \brief Disable the PLL identified by \a pll_id.
|
||||||
|
*
|
||||||
|
* After this function is called, the PLL identified by \a pll_id will
|
||||||
|
* be disabled. The PLL configuration stored in hardware may be affected
|
||||||
|
* by this, so if the caller needs to restore the same configuration
|
||||||
|
* later, it should either do a pll_config_read() before disabling the
|
||||||
|
* PLL, or remember the last configuration written to the PLL.
|
||||||
|
*
|
||||||
|
* \param pll_id The ID of the PLL to be disabled.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn bool pll_is_locked(unsigned int pll_id)
|
||||||
|
* \brief Determine whether the PLL is locked or not.
|
||||||
|
*
|
||||||
|
* \param pll_id The ID of the PLL to check.
|
||||||
|
*
|
||||||
|
* \retval true The PLL is locked and ready to use as a clock source
|
||||||
|
* \retval false The PLL is not yet locked, or has not been enabled.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void pll_enable_source(enum pll_source src)
|
||||||
|
* \brief Enable the source of the pll.
|
||||||
|
* The source is enabled, if the source is not already running.
|
||||||
|
*
|
||||||
|
* \param src The ID of the PLL source to enable.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \fn void pll_enable_config_defaults(unsigned int pll_id)
|
||||||
|
* \brief Enable the pll with the default configuration.
|
||||||
|
* PLL is enabled, if the PLL is not already locked.
|
||||||
|
*
|
||||||
|
* \param pll_id The ID of the PLL to enable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Wait for PLL \a pll_id to become locked
|
||||||
|
*
|
||||||
|
* \todo Use a timeout to avoid waiting forever and hanging the system
|
||||||
|
*
|
||||||
|
* \param pll_id The ID of the PLL to wait for.
|
||||||
|
*
|
||||||
|
* \retval STATUS_OK The PLL is now locked.
|
||||||
|
* \retval ERR_TIMEOUT Timed out waiting for PLL to become locked.
|
||||||
|
*/
|
||||||
|
static inline int pll_wait_for_lock(unsigned int pll_id)
|
||||||
|
{
|
||||||
|
Assert(pll_id < NR_PLLS);
|
||||||
|
|
||||||
|
while (!pll_is_locked(pll_id)) {
|
||||||
|
/* Do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
#endif /* CLK_PLL_H_INCLUDED */
|
@ -0,0 +1,264 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Chip-specific generic clock management.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHIP_GENCLK_H_INCLUDED
|
||||||
|
#define CHIP_GENCLK_H_INCLUDED
|
||||||
|
|
||||||
|
#include <osc.h>
|
||||||
|
#include <pll.h>
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \weakgroup genclk_group
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \name Programmable Clock Identifiers (PCK)
|
||||||
|
//@{
|
||||||
|
#define GENCLK_PCK_0 0 //!< PCK0 ID
|
||||||
|
#define GENCLK_PCK_1 1 //!< PCK1 ID
|
||||||
|
#define GENCLK_PCK_2 2 //!< PCK2 ID
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name Programmable Clock Sources (PCK)
|
||||||
|
//@{
|
||||||
|
|
||||||
|
enum genclk_source {
|
||||||
|
GENCLK_PCK_SRC_SLCK_RC = 0, //!< Internal 32kHz RC oscillator as PCK source clock
|
||||||
|
GENCLK_PCK_SRC_SLCK_XTAL = 1, //!< External 32kHz crystal oscillator as PCK source clock
|
||||||
|
GENCLK_PCK_SRC_SLCK_BYPASS = 2, //!< External 32kHz bypass oscillator as PCK source clock
|
||||||
|
GENCLK_PCK_SRC_MAINCK_4M_RC = 3, //!< Internal 4MHz RC oscillator as PCK source clock
|
||||||
|
GENCLK_PCK_SRC_MAINCK_8M_RC = 4, //!< Internal 8MHz RC oscillator as PCK source clock
|
||||||
|
GENCLK_PCK_SRC_MAINCK_12M_RC = 5, //!< Internal 12MHz RC oscillator as PCK source clock
|
||||||
|
GENCLK_PCK_SRC_MAINCK_XTAL = 6, //!< External crystal oscillator as PCK source clock
|
||||||
|
GENCLK_PCK_SRC_MAINCK_BYPASS = 7, //!< External bypass oscillator as PCK source clock
|
||||||
|
GENCLK_PCK_SRC_PLLACK = 8, //!< Use PLLACK as PCK source clock
|
||||||
|
GENCLK_PCK_SRC_PLLBCK = 9, //!< Use PLLBCK as PCK source clock
|
||||||
|
};
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name Programmable Clock Prescalers (PCK)
|
||||||
|
//@{
|
||||||
|
|
||||||
|
enum genclk_divider {
|
||||||
|
GENCLK_PCK_PRES_1 = PMC_PCK_PRES_CLK_1, //!< Set PCK clock prescaler to 1
|
||||||
|
GENCLK_PCK_PRES_2 = PMC_PCK_PRES_CLK_2, //!< Set PCK clock prescaler to 2
|
||||||
|
GENCLK_PCK_PRES_4 = PMC_PCK_PRES_CLK_4, //!< Set PCK clock prescaler to 4
|
||||||
|
GENCLK_PCK_PRES_8 = PMC_PCK_PRES_CLK_8, //!< Set PCK clock prescaler to 8
|
||||||
|
GENCLK_PCK_PRES_16 = PMC_PCK_PRES_CLK_16, //!< Set PCK clock prescaler to 16
|
||||||
|
GENCLK_PCK_PRES_32 = PMC_PCK_PRES_CLK_32, //!< Set PCK clock prescaler to 32
|
||||||
|
GENCLK_PCK_PRES_64 = PMC_PCK_PRES_CLK_64, //!< Set PCK clock prescaler to 64
|
||||||
|
};
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
struct genclk_config {
|
||||||
|
uint32_t ctrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void genclk_config_defaults(struct genclk_config *p_cfg,
|
||||||
|
uint32_t ul_id)
|
||||||
|
{
|
||||||
|
ul_id = ul_id;
|
||||||
|
p_cfg->ctrl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void genclk_config_read(struct genclk_config *p_cfg,
|
||||||
|
uint32_t ul_id)
|
||||||
|
{
|
||||||
|
p_cfg->ctrl = PMC->PMC_PCK[ul_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void genclk_config_write(const struct genclk_config *p_cfg,
|
||||||
|
uint32_t ul_id)
|
||||||
|
{
|
||||||
|
PMC->PMC_PCK[ul_id] = p_cfg->ctrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \name Programmable Clock Source and Prescaler configuration
|
||||||
|
//@{
|
||||||
|
|
||||||
|
static inline void genclk_config_set_source(struct genclk_config *p_cfg,
|
||||||
|
enum genclk_source e_src)
|
||||||
|
{
|
||||||
|
p_cfg->ctrl &= (~PMC_PCK_CSS_Msk);
|
||||||
|
|
||||||
|
switch (e_src) {
|
||||||
|
case GENCLK_PCK_SRC_SLCK_RC:
|
||||||
|
case GENCLK_PCK_SRC_SLCK_XTAL:
|
||||||
|
case GENCLK_PCK_SRC_SLCK_BYPASS:
|
||||||
|
p_cfg->ctrl |= (PMC_MCKR_CSS_SLOW_CLK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_4M_RC:
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_8M_RC:
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_12M_RC:
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_XTAL:
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_BYPASS:
|
||||||
|
p_cfg->ctrl |= (PMC_MCKR_CSS_MAIN_CLK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_PLLACK:
|
||||||
|
p_cfg->ctrl |= (PMC_MCKR_CSS_PLLA_CLK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_PLLBCK:
|
||||||
|
p_cfg->ctrl |= (PMC_MCKR_CSS_PLLB_CLK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void genclk_config_set_divider(struct genclk_config *p_cfg,
|
||||||
|
enum genclk_divider e_divider)
|
||||||
|
{
|
||||||
|
p_cfg->ctrl &= ~PMC_PCK_PRES_Msk;
|
||||||
|
p_cfg->ctrl |= e_divider;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
static inline void genclk_enable(const struct genclk_config *p_cfg, uint32_t ul_id)
|
||||||
|
{
|
||||||
|
PMC->PMC_PCK[ul_id] = p_cfg->ctrl;
|
||||||
|
pmc_enable_pck(ul_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void genclk_disable(uint32_t ul_id)
|
||||||
|
{
|
||||||
|
pmc_disable_pck(ul_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void genclk_enable_source(enum genclk_source e_src)
|
||||||
|
{
|
||||||
|
switch (e_src) {
|
||||||
|
case GENCLK_PCK_SRC_SLCK_RC:
|
||||||
|
if (!osc_is_ready(OSC_SLCK_32K_RC)) {
|
||||||
|
osc_enable(OSC_SLCK_32K_RC);
|
||||||
|
osc_wait_ready(OSC_SLCK_32K_RC);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_SLCK_XTAL:
|
||||||
|
if (!osc_is_ready(OSC_SLCK_32K_XTAL)) {
|
||||||
|
osc_enable(OSC_SLCK_32K_XTAL);
|
||||||
|
osc_wait_ready(OSC_SLCK_32K_XTAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_SLCK_BYPASS:
|
||||||
|
if (!osc_is_ready(OSC_SLCK_32K_BYPASS)) {
|
||||||
|
osc_enable(OSC_SLCK_32K_BYPASS);
|
||||||
|
osc_wait_ready(OSC_SLCK_32K_BYPASS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_4M_RC:
|
||||||
|
if (!osc_is_ready(OSC_MAINCK_4M_RC)) {
|
||||||
|
osc_enable(OSC_MAINCK_4M_RC);
|
||||||
|
osc_wait_ready(OSC_MAINCK_4M_RC);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_8M_RC:
|
||||||
|
if (!osc_is_ready(OSC_MAINCK_8M_RC)) {
|
||||||
|
osc_enable(OSC_MAINCK_8M_RC);
|
||||||
|
osc_wait_ready(OSC_MAINCK_8M_RC);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_12M_RC:
|
||||||
|
if (!osc_is_ready(OSC_MAINCK_12M_RC)) {
|
||||||
|
osc_enable(OSC_MAINCK_12M_RC);
|
||||||
|
osc_wait_ready(OSC_MAINCK_12M_RC);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_XTAL:
|
||||||
|
if (!osc_is_ready(OSC_MAINCK_XTAL)) {
|
||||||
|
osc_enable(OSC_MAINCK_XTAL);
|
||||||
|
osc_wait_ready(OSC_MAINCK_XTAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GENCLK_PCK_SRC_MAINCK_BYPASS:
|
||||||
|
if (!osc_is_ready(OSC_MAINCK_BYPASS)) {
|
||||||
|
osc_enable(OSC_MAINCK_BYPASS);
|
||||||
|
osc_wait_ready(OSC_MAINCK_BYPASS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PLL0_SOURCE
|
||||||
|
case GENCLK_PCK_SRC_PLLACK:
|
||||||
|
pll_enable_config_defaults(0);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PLL1_SOURCE
|
||||||
|
case GENCLK_PCK_SRC_PLLBCK:
|
||||||
|
pll_enable_config_defaults(1);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
Assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
#endif /* CHIP_GENCLK_H_INCLUDED */
|
@ -0,0 +1,217 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Chip-specific oscillator management functions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHIP_OSC_H_INCLUDED
|
||||||
|
#define CHIP_OSC_H_INCLUDED
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "pmc.h"
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \weakgroup osc_group
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \name Oscillator identifiers
|
||||||
|
//@{
|
||||||
|
#define OSC_SLCK_32K_RC 0 //!< Internal 32kHz RC oscillator.
|
||||||
|
#define OSC_SLCK_32K_XTAL 1 //!< External 32kHz crystal oscillator.
|
||||||
|
#define OSC_SLCK_32K_BYPASS 2 //!< External 32kHz bypass oscillator.
|
||||||
|
#define OSC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator.
|
||||||
|
#define OSC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator.
|
||||||
|
#define OSC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator.
|
||||||
|
#define OSC_MAINCK_XTAL 6 //!< External crystal oscillator.
|
||||||
|
#define OSC_MAINCK_BYPASS 7 //!< External bypass oscillator.
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name Oscillator clock speed in hertz
|
||||||
|
//@{
|
||||||
|
#define OSC_SLCK_32K_RC_HZ CHIP_FREQ_SLCK_RC //!< Internal 32kHz RC oscillator.
|
||||||
|
#define OSC_SLCK_32K_XTAL_HZ BOARD_FREQ_SLCK_XTAL //!< External 32kHz crystal oscillator.
|
||||||
|
#define OSC_SLCK_32K_BYPASS_HZ BOARD_FREQ_SLCK_BYPASS //!< External 32kHz bypass oscillator.
|
||||||
|
#define OSC_MAINCK_4M_RC_HZ CHIP_FREQ_MAINCK_RC_4MHZ //!< Internal 4MHz RC oscillator.
|
||||||
|
#define OSC_MAINCK_8M_RC_HZ CHIP_FREQ_MAINCK_RC_8MHZ //!< Internal 8MHz RC oscillator.
|
||||||
|
#define OSC_MAINCK_12M_RC_HZ CHIP_FREQ_MAINCK_RC_12MHZ //!< Internal 12MHz RC oscillator.
|
||||||
|
#define OSC_MAINCK_XTAL_HZ BOARD_FREQ_MAINCK_XTAL //!< External crystal oscillator.
|
||||||
|
#define OSC_MAINCK_BYPASS_HZ BOARD_FREQ_MAINCK_BYPASS //!< External bypass oscillator.
|
||||||
|
//@}
|
||||||
|
|
||||||
|
static inline void osc_enable(uint32_t ul_id)
|
||||||
|
{
|
||||||
|
switch (ul_id) {
|
||||||
|
case OSC_SLCK_32K_RC:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OSC_SLCK_32K_XTAL:
|
||||||
|
pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OSC_SLCK_32K_BYPASS:
|
||||||
|
pmc_switch_sclk_to_32kxtal(PMC_OSC_BYPASS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case OSC_MAINCK_4M_RC:
|
||||||
|
pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OSC_MAINCK_8M_RC:
|
||||||
|
pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OSC_MAINCK_12M_RC:
|
||||||
|
pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case OSC_MAINCK_XTAL:
|
||||||
|
pmc_switch_mainck_to_xtal(PMC_OSC_XTAL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OSC_MAINCK_BYPASS:
|
||||||
|
pmc_switch_mainck_to_xtal(PMC_OSC_BYPASS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void osc_disable(uint32_t ul_id)
|
||||||
|
{
|
||||||
|
switch (ul_id) {
|
||||||
|
case OSC_SLCK_32K_RC:
|
||||||
|
case OSC_SLCK_32K_XTAL:
|
||||||
|
case OSC_SLCK_32K_BYPASS:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OSC_MAINCK_4M_RC:
|
||||||
|
case OSC_MAINCK_8M_RC:
|
||||||
|
case OSC_MAINCK_12M_RC:
|
||||||
|
pmc_osc_disable_fastrc();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OSC_MAINCK_XTAL:
|
||||||
|
pmc_osc_disable_xtal(PMC_OSC_XTAL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OSC_MAINCK_BYPASS:
|
||||||
|
pmc_osc_disable_xtal(PMC_OSC_BYPASS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool osc_is_ready(uint32_t ul_id)
|
||||||
|
{
|
||||||
|
switch (ul_id) {
|
||||||
|
case OSC_SLCK_32K_RC:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case OSC_SLCK_32K_XTAL:
|
||||||
|
case OSC_SLCK_32K_BYPASS:
|
||||||
|
return pmc_osc_is_ready_32kxtal();
|
||||||
|
|
||||||
|
case OSC_MAINCK_4M_RC:
|
||||||
|
case OSC_MAINCK_8M_RC:
|
||||||
|
case OSC_MAINCK_12M_RC:
|
||||||
|
case OSC_MAINCK_XTAL:
|
||||||
|
case OSC_MAINCK_BYPASS:
|
||||||
|
return pmc_osc_is_ready_mainck();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t osc_get_rate(uint32_t ul_id)
|
||||||
|
{
|
||||||
|
switch (ul_id) {
|
||||||
|
case OSC_SLCK_32K_RC:
|
||||||
|
return OSC_SLCK_32K_RC_HZ;
|
||||||
|
|
||||||
|
#ifdef BOARD_FREQ_SLCK_XTAL
|
||||||
|
case OSC_SLCK_32K_XTAL:
|
||||||
|
return BOARD_FREQ_SLCK_XTAL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOARD_FREQ_SLCK_BYPASS
|
||||||
|
case OSC_SLCK_32K_BYPASS:
|
||||||
|
return BOARD_FREQ_SLCK_BYPASS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case OSC_MAINCK_4M_RC:
|
||||||
|
return OSC_MAINCK_4M_RC_HZ;
|
||||||
|
|
||||||
|
case OSC_MAINCK_8M_RC:
|
||||||
|
return OSC_MAINCK_8M_RC_HZ;
|
||||||
|
|
||||||
|
case OSC_MAINCK_12M_RC:
|
||||||
|
return OSC_MAINCK_12M_RC_HZ;
|
||||||
|
|
||||||
|
#ifdef BOARD_FREQ_MAINCK_XTAL
|
||||||
|
case OSC_MAINCK_XTAL:
|
||||||
|
return BOARD_FREQ_MAINCK_XTAL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOARD_FREQ_MAINCK_BYPASS
|
||||||
|
case OSC_MAINCK_BYPASS:
|
||||||
|
return BOARD_FREQ_MAINCK_BYPASS;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
#endif /* CHIP_OSC_H_INCLUDED */
|
@ -0,0 +1,241 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Chip-specific PLL definitions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHIP_PLL_H_INCLUDED
|
||||||
|
#define CHIP_PLL_H_INCLUDED
|
||||||
|
|
||||||
|
#include <osc.h>
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \weakgroup pll_group
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PLL_OUTPUT_MIN_HZ 80000000
|
||||||
|
#define PLL_OUTPUT_MAX_HZ 240000000
|
||||||
|
|
||||||
|
#define PLL_INPUT_MIN_HZ 3000000
|
||||||
|
#define PLL_INPUT_MAX_HZ 32000000
|
||||||
|
|
||||||
|
#define NR_PLLS 2
|
||||||
|
#define PLLA_ID 0
|
||||||
|
#define PLLB_ID 1
|
||||||
|
|
||||||
|
#define PLL_COUNT 0x3fU
|
||||||
|
|
||||||
|
enum pll_source {
|
||||||
|
PLL_SRC_MAINCK_4M_RC = OSC_MAINCK_4M_RC, //!< Internal 4MHz RC oscillator.
|
||||||
|
PLL_SRC_MAINCK_8M_RC = OSC_MAINCK_8M_RC, //!< Internal 8MHz RC oscillator.
|
||||||
|
PLL_SRC_MAINCK_12M_RC = OSC_MAINCK_12M_RC, //!< Internal 12MHz RC oscillator.
|
||||||
|
PLL_SRC_MAINCK_XTAL = OSC_MAINCK_XTAL, //!< External crystal oscillator.
|
||||||
|
PLL_SRC_MAINCK_BYPASS = OSC_MAINCK_BYPASS, //!< External bypass oscillator.
|
||||||
|
PLL_NR_SOURCES, //!< Number of PLL sources.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pll_config {
|
||||||
|
uint32_t ctrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define pll_get_default_rate(pll_id) \
|
||||||
|
((osc_get_rate(CONFIG_PLL##pll_id##_SOURCE) \
|
||||||
|
* CONFIG_PLL##pll_id##_MUL) \
|
||||||
|
/ CONFIG_PLL##pll_id##_DIV)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \note The SAM3S PLL hardware interprets mul as mul+1. For readability the hardware mul+1
|
||||||
|
* is hidden in this implementation. Use mul as mul effective value.
|
||||||
|
*/
|
||||||
|
static inline void pll_config_init(struct pll_config *p_cfg,
|
||||||
|
enum pll_source e_src, uint32_t ul_div, uint32_t ul_mul)
|
||||||
|
{
|
||||||
|
uint32_t vco_hz;
|
||||||
|
|
||||||
|
Assert(e_src < PLL_NR_SOURCES);
|
||||||
|
|
||||||
|
/* Calculate internal VCO frequency */
|
||||||
|
vco_hz = osc_get_rate(e_src) / ul_div;
|
||||||
|
Assert(vco_hz >= PLL_INPUT_MIN_HZ);
|
||||||
|
Assert(vco_hz <= PLL_INPUT_MAX_HZ);
|
||||||
|
|
||||||
|
vco_hz *= ul_mul;
|
||||||
|
Assert(vco_hz >= PLL_OUTPUT_MIN_HZ);
|
||||||
|
Assert(vco_hz <= PLL_OUTPUT_MAX_HZ);
|
||||||
|
|
||||||
|
/* PMC hardware will automatically make it mul+1 */
|
||||||
|
p_cfg->ctrl = CKGR_PLLAR_MULA(ul_mul - 1) | CKGR_PLLAR_DIVA(ul_div) | CKGR_PLLAR_PLLACOUNT(PLL_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pll_config_defaults(cfg, pll_id) \
|
||||||
|
pll_config_init(cfg, \
|
||||||
|
CONFIG_PLL##pll_id##_SOURCE, \
|
||||||
|
CONFIG_PLL##pll_id##_DIV, \
|
||||||
|
CONFIG_PLL##pll_id##_MUL)
|
||||||
|
|
||||||
|
static inline void pll_config_read(struct pll_config *p_cfg, uint32_t ul_pll_id)
|
||||||
|
{
|
||||||
|
Assert(ul_pll_id < NR_PLLS);
|
||||||
|
|
||||||
|
if (ul_pll_id == PLLA_ID)
|
||||||
|
p_cfg->ctrl = PMC->CKGR_PLLAR;
|
||||||
|
else
|
||||||
|
p_cfg->ctrl = PMC->CKGR_PLLBR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pll_config_write(const struct pll_config *p_cfg, uint32_t ul_pll_id)
|
||||||
|
{
|
||||||
|
Assert(ul_pll_id < NR_PLLS);
|
||||||
|
|
||||||
|
if (ul_pll_id == PLLA_ID) {
|
||||||
|
pmc_disable_pllack(); // Always stop PLL first!
|
||||||
|
PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl;
|
||||||
|
} else {
|
||||||
|
pmc_disable_pllbck();
|
||||||
|
PMC->CKGR_PLLBR = p_cfg->ctrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pll_enable(const struct pll_config *p_cfg, uint32_t ul_pll_id)
|
||||||
|
{
|
||||||
|
Assert(ul_pll_id < NR_PLLS);
|
||||||
|
|
||||||
|
if (ul_pll_id == PLLA_ID) {
|
||||||
|
pmc_disable_pllack(); // Always stop PLL first!
|
||||||
|
PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl;
|
||||||
|
} else {
|
||||||
|
pmc_disable_pllbck();
|
||||||
|
PMC->CKGR_PLLBR = p_cfg->ctrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \note This will only disable the selected PLL, not the underlying oscillator (mainck).
|
||||||
|
*/
|
||||||
|
static inline void pll_disable(uint32_t ul_pll_id)
|
||||||
|
{
|
||||||
|
Assert(ul_pll_id < NR_PLLS);
|
||||||
|
|
||||||
|
if (ul_pll_id == PLLA_ID)
|
||||||
|
pmc_disable_pllack();
|
||||||
|
else
|
||||||
|
pmc_disable_pllbck();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t pll_is_locked(uint32_t ul_pll_id)
|
||||||
|
{
|
||||||
|
Assert(ul_pll_id < NR_PLLS);
|
||||||
|
|
||||||
|
if (ul_pll_id == PLLA_ID)
|
||||||
|
return pmc_is_locked_pllack();
|
||||||
|
else
|
||||||
|
return pmc_is_locked_pllbck();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pll_enable_source(enum pll_source e_src)
|
||||||
|
{
|
||||||
|
switch (e_src) {
|
||||||
|
case PLL_SRC_MAINCK_4M_RC:
|
||||||
|
case PLL_SRC_MAINCK_8M_RC:
|
||||||
|
case PLL_SRC_MAINCK_12M_RC:
|
||||||
|
case PLL_SRC_MAINCK_XTAL:
|
||||||
|
case PLL_SRC_MAINCK_BYPASS:
|
||||||
|
osc_enable(e_src);
|
||||||
|
osc_wait_ready(e_src);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pll_enable_config_defaults(unsigned int ul_pll_id)
|
||||||
|
{
|
||||||
|
struct pll_config pllcfg;
|
||||||
|
|
||||||
|
if (pll_is_locked(ul_pll_id)) {
|
||||||
|
return; // Pll already running
|
||||||
|
}
|
||||||
|
switch (ul_pll_id) {
|
||||||
|
#ifdef CONFIG_PLL0_SOURCE
|
||||||
|
case 0:
|
||||||
|
pll_enable_source(CONFIG_PLL0_SOURCE);
|
||||||
|
pll_config_init(&pllcfg,
|
||||||
|
CONFIG_PLL0_SOURCE,
|
||||||
|
CONFIG_PLL0_DIV,
|
||||||
|
CONFIG_PLL0_MUL);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_PLL1_SOURCE
|
||||||
|
case 1:
|
||||||
|
pll_enable_source(CONFIG_PLL1_SOURCE);
|
||||||
|
pll_config_init(&pllcfg,
|
||||||
|
CONFIG_PLL1_SOURCE,
|
||||||
|
CONFIG_PLL1_DIV,
|
||||||
|
CONFIG_PLL1_MUL);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
Assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pll_enable(&pllcfg, ul_pll_id);
|
||||||
|
while (!pll_is_locked(ul_pll_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
#endif /* CHIP_PLL_H_INCLUDED */
|
@ -0,0 +1,265 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Chip-specific system clock management functions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sysclk.h>
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \weakgroup sysclk_group
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
|
||||||
|
/**
|
||||||
|
* \brief boolean signaling that the sysclk_init is done.
|
||||||
|
*/
|
||||||
|
uint32_t sysclk_initialized = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set system clock prescaler configuration
|
||||||
|
*
|
||||||
|
* This function will change the system clock prescaler configuration to
|
||||||
|
* match the parameters.
|
||||||
|
*
|
||||||
|
* \note The parameters to this function are device-specific.
|
||||||
|
*
|
||||||
|
* \param cpu_shift The CPU clock will be divided by \f$2^{mck\_pres}\f$
|
||||||
|
*/
|
||||||
|
void sysclk_set_prescalers(uint32_t ul_pres)
|
||||||
|
{
|
||||||
|
pmc_mck_set_prescaler(ul_pres);
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Change the source of the main system clock.
|
||||||
|
*
|
||||||
|
* \param src The new system clock source. Must be one of the constants
|
||||||
|
* from the <em>System Clock Sources</em> section.
|
||||||
|
*/
|
||||||
|
void sysclk_set_source(uint32_t ul_src)
|
||||||
|
{
|
||||||
|
switch (ul_src) {
|
||||||
|
case SYSCLK_SRC_SLCK_RC:
|
||||||
|
case SYSCLK_SRC_SLCK_XTAL:
|
||||||
|
case SYSCLK_SRC_SLCK_BYPASS:
|
||||||
|
pmc_mck_set_source(PMC_MCKR_CSS_SLOW_CLK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_4M_RC:
|
||||||
|
case SYSCLK_SRC_MAINCK_8M_RC:
|
||||||
|
case SYSCLK_SRC_MAINCK_12M_RC:
|
||||||
|
case SYSCLK_SRC_MAINCK_XTAL:
|
||||||
|
case SYSCLK_SRC_MAINCK_BYPASS:
|
||||||
|
pmc_mck_set_source(PMC_MCKR_CSS_MAIN_CLK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_PLLACK:
|
||||||
|
pmc_mck_set_source(PMC_MCKR_CSS_PLLA_CLK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_PLLBCK:
|
||||||
|
pmc_mck_set_source(PMC_MCKR_CSS_PLLB_CLK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* \brief Enable USB clock.
|
||||||
|
*
|
||||||
|
* \note The SAM3S UDP hardware interprets div as div+1. For readability the hardware div+1
|
||||||
|
* is hidden in this implementation. Use div as div effective value.
|
||||||
|
*
|
||||||
|
* \param pll_id Source of the USB clock.
|
||||||
|
* \param div Actual clock diviser. Must be superior to 0.
|
||||||
|
*/
|
||||||
|
void sysclk_enable_usb(void)
|
||||||
|
{
|
||||||
|
Assert(CONFIG_USBCLK_DIV > 0);
|
||||||
|
|
||||||
|
switch (CONFIG_USBCLK_SOURCE) {
|
||||||
|
#ifdef CONFIG_PLL0_SOURCE
|
||||||
|
case USBCLK_SRC_PLL0: {
|
||||||
|
struct pll_config pllcfg;
|
||||||
|
|
||||||
|
pll_enable_source(CONFIG_PLL0_SOURCE);
|
||||||
|
pll_config_defaults(&pllcfg, 0);
|
||||||
|
pll_enable(&pllcfg, 0);
|
||||||
|
pll_wait_for_lock(0);
|
||||||
|
pmc_switch_udpck_to_pllack(CONFIG_USBCLK_DIV - 1);
|
||||||
|
pmc_enable_udpck();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PLL1_SOURCE
|
||||||
|
case USBCLK_SRC_PLL1: {
|
||||||
|
struct pll_config pllcfg;
|
||||||
|
|
||||||
|
pll_enable_source(CONFIG_PLL1_SOURCE);
|
||||||
|
pll_config_defaults(&pllcfg, 1);
|
||||||
|
pll_enable(&pllcfg, 1);
|
||||||
|
pll_wait_for_lock(1);
|
||||||
|
pmc_switch_udpck_to_pllbck(CONFIG_USBCLK_DIV - 1);
|
||||||
|
pmc_enable_udpck();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Disable the USB clock.
|
||||||
|
*
|
||||||
|
* \note This implementation does not switch off the PLL, it just turns off the USB clock.
|
||||||
|
*/
|
||||||
|
void sysclk_disable_usb(void)
|
||||||
|
{
|
||||||
|
pmc_disable_udpck();
|
||||||
|
}
|
||||||
|
#endif // CONFIG_USBCLK_SOURCE
|
||||||
|
|
||||||
|
void sysclk_init(void)
|
||||||
|
{
|
||||||
|
struct pll_config pllcfg;
|
||||||
|
|
||||||
|
/* Set a flash wait state depending on the new cpu frequency */
|
||||||
|
system_init_flash(sysclk_get_cpu_hz());
|
||||||
|
|
||||||
|
/* Config system clock setting */
|
||||||
|
switch (CONFIG_SYSCLK_SOURCE) {
|
||||||
|
case SYSCLK_SRC_SLCK_RC:
|
||||||
|
osc_enable(OSC_SLCK_32K_RC);
|
||||||
|
osc_wait_ready(OSC_SLCK_32K_RC);
|
||||||
|
pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_SLCK_XTAL:
|
||||||
|
osc_enable(OSC_SLCK_32K_XTAL);
|
||||||
|
osc_wait_ready(OSC_SLCK_32K_XTAL);
|
||||||
|
pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_SLCK_BYPASS:
|
||||||
|
osc_enable(OSC_SLCK_32K_BYPASS);
|
||||||
|
osc_wait_ready(OSC_SLCK_32K_BYPASS);
|
||||||
|
pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_4M_RC:
|
||||||
|
/* Already running from SYSCLK_SRC_MAINCK_4M_RC */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_8M_RC:
|
||||||
|
osc_enable(OSC_MAINCK_8M_RC);
|
||||||
|
osc_wait_ready(OSC_MAINCK_8M_RC);
|
||||||
|
pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_12M_RC:
|
||||||
|
osc_enable(OSC_MAINCK_12M_RC);
|
||||||
|
osc_wait_ready(OSC_MAINCK_12M_RC);
|
||||||
|
pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_XTAL:
|
||||||
|
osc_enable(OSC_MAINCK_XTAL);
|
||||||
|
osc_wait_ready(OSC_MAINCK_XTAL);
|
||||||
|
pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_BYPASS:
|
||||||
|
osc_enable(OSC_MAINCK_BYPASS);
|
||||||
|
osc_wait_ready(OSC_MAINCK_BYPASS);
|
||||||
|
pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PLL0_SOURCE
|
||||||
|
case SYSCLK_SRC_PLLACK:
|
||||||
|
pll_enable_source(CONFIG_PLL0_SOURCE);
|
||||||
|
pll_config_defaults(&pllcfg, 0);
|
||||||
|
pll_enable(&pllcfg, 0);
|
||||||
|
pll_wait_for_lock(0);
|
||||||
|
pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PLL1_SOURCE
|
||||||
|
case SYSCLK_SRC_PLLBCK:
|
||||||
|
pll_enable_source(CONFIG_PLL1_SOURCE);
|
||||||
|
pll_config_defaults(&pllcfg, 1);
|
||||||
|
pll_enable(&pllcfg, 1);
|
||||||
|
pll_wait_for_lock(1);
|
||||||
|
pmc_switch_mck_to_pllbck(CONFIG_SYSCLK_PRES);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the SystemFrequency variable */
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
|
||||||
|
#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
|
||||||
|
/* Signal that the internal frequencies are setup */
|
||||||
|
sysclk_initialized = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
@ -0,0 +1,442 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Chip-specific system clock management functions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHIP_SYSCLK_H_INCLUDED
|
||||||
|
#define CHIP_SYSCLK_H_INCLUDED
|
||||||
|
|
||||||
|
#include <osc.h>
|
||||||
|
#include <pll.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \page sysclk_quickstart Quick Start Guide for the System Clock Management service (SAM4S)
|
||||||
|
*
|
||||||
|
* This is the quick start guide for the \ref sysclk_group "System Clock Management"
|
||||||
|
* service, with step-by-step instructions on how to configure and use the service for
|
||||||
|
* specific use cases.
|
||||||
|
*
|
||||||
|
* \section sysclk_quickstart_usecases System Clock Management use cases
|
||||||
|
* - \ref sysclk_quickstart_basic
|
||||||
|
* - \ref sysclk_quickstart_use_case_2
|
||||||
|
*
|
||||||
|
* \section sysclk_quickstart_basic Basic usage of the System Clock Management service
|
||||||
|
* This section will present a basic use case for the System Clock Management service.
|
||||||
|
* This use case will configure the main system clock to 120MHz, using an internal PLL
|
||||||
|
* module to multiply the frequency of a crystal attached to the microcontroller.
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_1_prereq Prerequisites
|
||||||
|
* - None
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code
|
||||||
|
* Add to the application initialization code:
|
||||||
|
* \code
|
||||||
|
* sysclk_init();
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow
|
||||||
|
* -# Configure the system clocks according to the settings in conf_clock.h:
|
||||||
|
* \code sysclk_init(); \endcode
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_1_example_code Example code
|
||||||
|
* Add or uncomment the following in your conf_clock.h header file, commenting out all other
|
||||||
|
* definitions of the same symbol(s):
|
||||||
|
* \code
|
||||||
|
* #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK
|
||||||
|
*
|
||||||
|
* // Fpll0 = (Fclk * PLL_mul) / PLL_div
|
||||||
|
* #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL
|
||||||
|
* #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL)
|
||||||
|
* #define CONFIG_PLL0_DIV 1
|
||||||
|
*
|
||||||
|
* // Fbus = Fsys / BUS_div
|
||||||
|
* #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_1_example_workflow Workflow
|
||||||
|
* -# Configure the main system clock to use the output of the PLL module as its source:
|
||||||
|
* \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode
|
||||||
|
* -# Configure the PLL module to use the fast external fast crystal oscillator as its source:
|
||||||
|
* \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode
|
||||||
|
* -# Configure the PLL module to multiply the external fast crystal oscillator frequency up to 120MHz:
|
||||||
|
* \code
|
||||||
|
* #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL)
|
||||||
|
* #define CONFIG_PLL0_DIV 1
|
||||||
|
* \endcode
|
||||||
|
* \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the board \c conf_board.h configuration
|
||||||
|
* file as the frequency of the fast crystal attached to the microcontroller.
|
||||||
|
* -# Configure the main clock to run at the full 120MHz, disable scaling of the main system clock speed:
|
||||||
|
* \code
|
||||||
|
* #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
|
||||||
|
* \endcode
|
||||||
|
* \note Some dividers are powers of two, while others are integer division factors. Refer to the
|
||||||
|
* formulas in the conf_clock.h template commented above each division define.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (SAM4S)
|
||||||
|
*
|
||||||
|
* \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management
|
||||||
|
* This section will present a more advanced use case for the System Clock Management service.
|
||||||
|
* This use case will configure the main system clock to 120MHz, using an internal PLL
|
||||||
|
* module to multiply the frequency of a crystal attached to the microcontroller. The USB clock
|
||||||
|
* will be configured via a seperate PLL module.
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_2_prereq Prerequisites
|
||||||
|
* - None
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code
|
||||||
|
* Add to the application initialization code:
|
||||||
|
* \code
|
||||||
|
* sysclk_init();
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow
|
||||||
|
* -# Configure the system clocks according to the settings in conf_clock.h:
|
||||||
|
* \code sysclk_init(); \endcode
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_2_example_code Example code
|
||||||
|
* Add or uncomment the following in your conf_clock.h header file, commenting out all other
|
||||||
|
* definitions of the same symbol(s):
|
||||||
|
* \code
|
||||||
|
* #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK
|
||||||
|
*
|
||||||
|
* // Fpll0 = (Fclk * PLL_mul) / PLL_div
|
||||||
|
* #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL
|
||||||
|
* #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL)
|
||||||
|
* #define CONFIG_PLL0_DIV 1
|
||||||
|
*
|
||||||
|
* // Fbus = Fsys / BUS_div
|
||||||
|
* #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
|
||||||
|
*
|
||||||
|
* // Fusb = Fsys / USB_div
|
||||||
|
* #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1
|
||||||
|
* #define CONFIG_USBCLK_DIV 1
|
||||||
|
*
|
||||||
|
* // Fpll1 = (Fclk * PLL_mul) / PLL_div
|
||||||
|
* #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL
|
||||||
|
* #define CONFIG_PLL1_MUL (48000000UL / BOARD_FREQ_MAINCK_XTAL)
|
||||||
|
* #define CONFIG_PLL1_DIV 1
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection sysclk_quickstart_use_case_2_example_workflow Workflow
|
||||||
|
* -# Configure the main system clock to use the output of the PLL0 module as its source:
|
||||||
|
* \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode
|
||||||
|
* -# Configure the PLL0 module to use the fast external fast crystal oscillator as its source:
|
||||||
|
* \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode
|
||||||
|
* -# Configure the PLL0 module to multiply the external fast crystal oscillator frequency up to 120MHz:
|
||||||
|
* \code
|
||||||
|
* #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL)
|
||||||
|
* #define CONFIG_PLL0_DIV 1
|
||||||
|
* \endcode
|
||||||
|
* \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the board \c conf_board.h configuration
|
||||||
|
* file as the frequency of the fast crystal attached to the microcontroller.
|
||||||
|
* -# Configure the main clock to run at the full 120MHz, disable scaling of the main system clock speed:
|
||||||
|
* \code
|
||||||
|
* #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
|
||||||
|
* \endcode
|
||||||
|
* \note Some dividers are powers of two, while others are integer division factors. Refer to the
|
||||||
|
* formulas in the conf_clock.h template commented above each division define.
|
||||||
|
* -# Configure the USB module clock to use the output of the PLL1 module as its source:
|
||||||
|
* \code #define CONFIG_SYSCLK_SOURCE USBCLK_SRC_PLL1 \endcode
|
||||||
|
* -# Configure the PLL1 module to use the fast external fast crystal oscillator as its source:
|
||||||
|
* \code #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL \endcode
|
||||||
|
* -# Configure the PLL1 module to multiply the external fast crystal oscillator frequency up to 48MHz:
|
||||||
|
* \code
|
||||||
|
* #define CONFIG_PLL1_MUL (48000000UL / BOARD_FREQ_MAINCK_XTAL)
|
||||||
|
* #define CONFIG_PLL1_DIV 1
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \weakgroup sysclk_group
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \name Configuration Symbols
|
||||||
|
//@{
|
||||||
|
/**
|
||||||
|
* \def CONFIG_SYSCLK_SOURCE
|
||||||
|
* \brief Initial/static main system clock source
|
||||||
|
*
|
||||||
|
* The main system clock will be configured to use this clock during
|
||||||
|
* initialization.
|
||||||
|
*/
|
||||||
|
#ifndef CONFIG_SYSCLK_SOURCE
|
||||||
|
# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* \def CONFIG_SYSCLK_PRES
|
||||||
|
* \brief Initial CPU clock divider (mck)
|
||||||
|
*
|
||||||
|
* The MCK will run at
|
||||||
|
* \f[
|
||||||
|
* f_{MCK} = \frac{f_{sys}}{\mathrm{CONFIG\_SYSCLK\_PRES}}\,\mbox{Hz}
|
||||||
|
* \f]
|
||||||
|
* after initialization.
|
||||||
|
*/
|
||||||
|
#ifndef CONFIG_SYSCLK_PRES
|
||||||
|
# define CONFIG_SYSCLK_PRES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name Master Clock Sources (MCK)
|
||||||
|
//@{
|
||||||
|
#define SYSCLK_SRC_SLCK_RC 0 //!< Internal 32kHz RC oscillator as master source clock
|
||||||
|
#define SYSCLK_SRC_SLCK_XTAL 1 //!< External 32kHz crystal oscillator as master source clock
|
||||||
|
#define SYSCLK_SRC_SLCK_BYPASS 2 //!< External 32kHz bypass oscillator as master source clock
|
||||||
|
#define SYSCLK_SRC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator as master source clock
|
||||||
|
#define SYSCLK_SRC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator as master source clock
|
||||||
|
#define SYSCLK_SRC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator as master source clock
|
||||||
|
#define SYSCLK_SRC_MAINCK_XTAL 6 //!< External crystal oscillator as master source clock
|
||||||
|
#define SYSCLK_SRC_MAINCK_BYPASS 7 //!< External bypass oscillator as master source clock
|
||||||
|
#define SYSCLK_SRC_PLLACK 8 //!< Use PLLACK as master source clock
|
||||||
|
#define SYSCLK_SRC_PLLBCK 9 //!< Use PLLBCK as master source clock
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name Master Clock Prescalers (MCK)
|
||||||
|
//@{
|
||||||
|
#define SYSCLK_PRES_1 PMC_MCKR_PRES_CLK_1 //!< Set master clock prescaler to 1
|
||||||
|
#define SYSCLK_PRES_2 PMC_MCKR_PRES_CLK_2 //!< Set master clock prescaler to 2
|
||||||
|
#define SYSCLK_PRES_4 PMC_MCKR_PRES_CLK_4 //!< Set master clock prescaler to 4
|
||||||
|
#define SYSCLK_PRES_8 PMC_MCKR_PRES_CLK_8 //!< Set master clock prescaler to 8
|
||||||
|
#define SYSCLK_PRES_16 PMC_MCKR_PRES_CLK_16 //!< Set master clock prescaler to 16
|
||||||
|
#define SYSCLK_PRES_32 PMC_MCKR_PRES_CLK_32 //!< Set master clock prescaler to 32
|
||||||
|
#define SYSCLK_PRES_64 PMC_MCKR_PRES_CLK_64 //!< Set master clock prescaler to 64
|
||||||
|
#define SYSCLK_PRES_3 PMC_MCKR_PRES_CLK_3 //!< Set master clock prescaler to 3
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name USB Clock Sources
|
||||||
|
//@{
|
||||||
|
#define USBCLK_SRC_PLL0 0 //!< Use PLLA
|
||||||
|
#define USBCLK_SRC_PLL1 1 //!< Use PLLB
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def CONFIG_USBCLK_SOURCE
|
||||||
|
* \brief Configuration symbol for the USB generic clock source
|
||||||
|
*
|
||||||
|
* Sets the clock source to use for the USB. The source must also be properly
|
||||||
|
* configured.
|
||||||
|
*
|
||||||
|
* Define this to one of the \c USBCLK_SRC_xxx settings. Leave it undefined if
|
||||||
|
* USB is not required.
|
||||||
|
*/
|
||||||
|
#ifdef __DOXYGEN__
|
||||||
|
# define CONFIG_USBCLK_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \def CONFIG_USBCLK_DIV
|
||||||
|
* \brief Configuration symbol for the USB generic clock divider setting
|
||||||
|
*
|
||||||
|
* Sets the clock division for the USB generic clock. If a USB clock source is
|
||||||
|
* selected with CONFIG_USBCLK_SOURCE, this configuration symbol must also be
|
||||||
|
* defined.
|
||||||
|
*/
|
||||||
|
#ifdef __DOXYGEN__
|
||||||
|
# define CONFIG_USBCLK_DIV
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Querying the system clock
|
||||||
|
*
|
||||||
|
* The following functions may be used to query the current frequency of
|
||||||
|
* the system clock and the CPU and bus clocks derived from it.
|
||||||
|
* sysclk_get_main_hz() and sysclk_get_cpu_hz() can be assumed to be
|
||||||
|
* available on all platforms, although some platforms may define
|
||||||
|
* additional accessors for various chip-internal bus clocks. These are
|
||||||
|
* usually not intended to be queried directly by generic code.
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the current rate in Hz of the main system clock
|
||||||
|
*
|
||||||
|
* \todo This function assumes that the main clock source never changes
|
||||||
|
* once it's been set up, and that PLL0 always runs at the compile-time
|
||||||
|
* configured default rate. While this is probably the most common
|
||||||
|
* configuration, which we want to support as a special case for
|
||||||
|
* performance reasons, we will at some point need to support more
|
||||||
|
* dynamic setups as well.
|
||||||
|
*/
|
||||||
|
#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
|
||||||
|
extern uint32_t sysclk_initialized;
|
||||||
|
#endif
|
||||||
|
static inline uint32_t sysclk_get_main_hz(void)
|
||||||
|
{
|
||||||
|
#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
|
||||||
|
if (!sysclk_initialized ) {
|
||||||
|
return OSC_MAINCK_4M_RC_HZ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Config system clock setting */
|
||||||
|
switch (CONFIG_SYSCLK_SOURCE) {
|
||||||
|
case SYSCLK_SRC_SLCK_RC:
|
||||||
|
return OSC_SLCK_32K_RC_HZ;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_SLCK_XTAL:
|
||||||
|
return OSC_SLCK_32K_XTAL_HZ;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_SLCK_BYPASS:
|
||||||
|
return OSC_SLCK_32K_BYPASS_HZ;
|
||||||
|
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_4M_RC:
|
||||||
|
return OSC_MAINCK_4M_RC_HZ;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_8M_RC:
|
||||||
|
return OSC_MAINCK_8M_RC_HZ;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_12M_RC:
|
||||||
|
return OSC_MAINCK_12M_RC_HZ;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_XTAL:
|
||||||
|
return OSC_MAINCK_XTAL_HZ;
|
||||||
|
|
||||||
|
case SYSCLK_SRC_MAINCK_BYPASS:
|
||||||
|
return OSC_MAINCK_BYPASS_HZ;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PLL0_SOURCE
|
||||||
|
case SYSCLK_SRC_PLLACK:
|
||||||
|
return pll_get_default_rate(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PLL1_SOURCE
|
||||||
|
case SYSCLK_SRC_PLLBCK:
|
||||||
|
return pll_get_default_rate(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* unhandled_case(CONFIG_SYSCLK_SOURCE); */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the current rate in Hz of the CPU clock
|
||||||
|
*
|
||||||
|
* \todo This function assumes that the CPU always runs at the system
|
||||||
|
* clock frequency. We want to support at least two more scenarios:
|
||||||
|
* Fixed CPU/bus clock dividers (config symbols) and dynamic CPU/bus
|
||||||
|
* clock dividers (which may change at run time). Ditto for all the bus
|
||||||
|
* clocks.
|
||||||
|
*
|
||||||
|
* \return Frequency of the CPU clock, in Hz.
|
||||||
|
*/
|
||||||
|
static inline uint32_t sysclk_get_cpu_hz(void)
|
||||||
|
{
|
||||||
|
/* CONFIG_SYSCLK_PRES is the register value for setting the expected */
|
||||||
|
/* prescaler, not an immediat value. */
|
||||||
|
return sysclk_get_main_hz() / ((CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the current rate in Hz of the peripheral clocks.
|
||||||
|
*
|
||||||
|
* \return Frequency of the peripheral clocks, in Hz.
|
||||||
|
*/
|
||||||
|
static inline uint32_t sysclk_get_peripheral_hz(void)
|
||||||
|
{
|
||||||
|
/* CONFIG_SYSCLK_PRES is the register value for setting the expected */
|
||||||
|
/* prescaler, not an immediat value. */
|
||||||
|
return sysclk_get_main_hz() / ((CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name Enabling and disabling synchronous clocks
|
||||||
|
//@{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Enable a peripheral's clock.
|
||||||
|
*
|
||||||
|
* \param ul_id Id (number) of the peripheral clock.
|
||||||
|
*/
|
||||||
|
static inline void sysclk_enable_peripheral_clock(uint32_t ul_id)
|
||||||
|
{
|
||||||
|
pmc_enable_periph_clk(ul_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Disable a peripheral's clock.
|
||||||
|
*
|
||||||
|
* \param ul_id Id (number) of the peripheral clock.
|
||||||
|
*/
|
||||||
|
static inline void sysclk_disable_peripheral_clock(uint32_t ul_id)
|
||||||
|
{
|
||||||
|
pmc_disable_periph_clk(ul_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! \name System Clock Source and Prescaler configuration
|
||||||
|
//@{
|
||||||
|
|
||||||
|
extern void sysclk_set_prescalers(uint32_t ul_pres);
|
||||||
|
extern void sysclk_set_source(uint32_t ul_src);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
extern void sysclk_enable_usb(void);
|
||||||
|
extern void sysclk_disable_usb(void);
|
||||||
|
|
||||||
|
extern void sysclk_init(void);
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
#endif /* CHIP_SYSCLK_H_INCLUDED */
|
@ -0,0 +1,165 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief System clock management
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef SYSCLK_H_INCLUDED
|
||||||
|
#define SYSCLK_H_INCLUDED
|
||||||
|
|
||||||
|
#include "parts.h"
|
||||||
|
#include "conf_clock.h"
|
||||||
|
|
||||||
|
#if SAM3S
|
||||||
|
# include "sam3s/sysclk.h"
|
||||||
|
#elif SAM3U
|
||||||
|
# include "sam3u/sysclk.h"
|
||||||
|
#elif SAM3N
|
||||||
|
# include "sam3n/sysclk.h"
|
||||||
|
#elif SAM3XA
|
||||||
|
# include "sam3x/sysclk.h"
|
||||||
|
#elif SAM4S
|
||||||
|
# include "sam4s/sysclk.h"
|
||||||
|
#elif (UC3A0 || UC3A1)
|
||||||
|
# include "uc3a0_a1/sysclk.h"
|
||||||
|
#elif UC3A3
|
||||||
|
# include "uc3a3_a4/sysclk.h"
|
||||||
|
#elif UC3B
|
||||||
|
# include "uc3b0_b1/sysclk.h"
|
||||||
|
#elif UC3C
|
||||||
|
# include "uc3c/sysclk.h"
|
||||||
|
#elif UC3D
|
||||||
|
# include "uc3d/sysclk.h"
|
||||||
|
#elif UC3L
|
||||||
|
# include "uc3l/sysclk.h"
|
||||||
|
#elif XMEGA
|
||||||
|
# include "xmega/sysclk.h"
|
||||||
|
#else
|
||||||
|
# error Unsupported chip type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \defgroup clk_group Clock Management
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup clk_group
|
||||||
|
* \defgroup sysclk_group System Clock Management
|
||||||
|
*
|
||||||
|
* See \ref sysclk_quickstart.
|
||||||
|
*
|
||||||
|
* The <em>sysclk</em> API covers the <em>system clock</em> and all
|
||||||
|
* clocks derived from it. The system clock is a chip-internal clock on
|
||||||
|
* which all <em>synchronous clocks</em>, i.e. CPU and bus/peripheral
|
||||||
|
* clocks, are based. The system clock is typically generated from one
|
||||||
|
* of a variety of sources, which may include crystal and RC oscillators
|
||||||
|
* as well as PLLs. The clocks derived from the system clock are
|
||||||
|
* sometimes also known as <em>synchronous clocks</em>, since they
|
||||||
|
* always run synchronously with respect to each other, as opposed to
|
||||||
|
* <em>generic clocks</em> which may run from different oscillators or
|
||||||
|
* PLLs.
|
||||||
|
*
|
||||||
|
* Most applications should simply call sysclk_init() to initialize
|
||||||
|
* everything related to the system clock and its source (oscillator,
|
||||||
|
* PLL or DFLL), and leave it at that. More advanced applications, and
|
||||||
|
* platform-specific drivers, may require additional services from the
|
||||||
|
* clock system, some of which may be platform-specific.
|
||||||
|
*
|
||||||
|
* \section sysclk_group_platform Platform Dependencies
|
||||||
|
*
|
||||||
|
* The sysclk API is partially chip- or platform-specific. While all
|
||||||
|
* platforms provide mostly the same functionality, there are some
|
||||||
|
* variations around how different bus types and clock tree structures
|
||||||
|
* are handled.
|
||||||
|
*
|
||||||
|
* The following functions are available on all platforms with the same
|
||||||
|
* parameters and functionality. These functions may be called freely by
|
||||||
|
* portable applications, drivers and services:
|
||||||
|
* - sysclk_init()
|
||||||
|
* - sysclk_set_source()
|
||||||
|
* - sysclk_get_main_hz()
|
||||||
|
* - sysclk_get_cpu_hz()
|
||||||
|
* - sysclk_get_peripheral_bus_hz()
|
||||||
|
*
|
||||||
|
* The following functions are available on all platforms, but there may
|
||||||
|
* be variations in the function signature (i.e. parameters) and
|
||||||
|
* behaviour. These functions are typically called by platform-specific
|
||||||
|
* parts of drivers, and applications that aren't intended to be
|
||||||
|
* portable:
|
||||||
|
* - sysclk_enable_peripheral_clock()
|
||||||
|
* - sysclk_disable_peripheral_clock()
|
||||||
|
* - sysclk_enable_module()
|
||||||
|
* - sysclk_disable_module()
|
||||||
|
* - sysclk_module_is_enabled()
|
||||||
|
* - sysclk_set_prescalers()
|
||||||
|
*
|
||||||
|
* All other functions should be considered platform-specific.
|
||||||
|
* Enabling/disabling clocks to specific peripherals as well as
|
||||||
|
* determining the speed of these clocks should be done by calling
|
||||||
|
* functions provided by the driver for that peripheral.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \name System Clock Initialization
|
||||||
|
//@{
|
||||||
|
/**
|
||||||
|
* \fn void sysclk_init(void)
|
||||||
|
* \brief Initialize the synchronous clock system.
|
||||||
|
*
|
||||||
|
* This function will initialize the system clock and its source. This
|
||||||
|
* includes:
|
||||||
|
* - Mask all synchronous clocks except for any clocks which are
|
||||||
|
* essential for normal operation (for example internal memory
|
||||||
|
* clocks).
|
||||||
|
* - Set up the system clock prescalers as specified by the
|
||||||
|
* application's configuration file.
|
||||||
|
* - Enable the clock source specified by the application's
|
||||||
|
* configuration file (oscillator or PLL) and wait for it to become
|
||||||
|
* stable.
|
||||||
|
* - Set the main system clock source to the clock specified by the
|
||||||
|
* application's configuration file.
|
||||||
|
*
|
||||||
|
* Since all non-essential peripheral clocks are initially disabled, it
|
||||||
|
* is the responsibility of the peripheral driver to re-enable any
|
||||||
|
* clocks that are needed for normal operation.
|
||||||
|
*/
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
#endif /* SYSCLK_H_INCLUDED */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,437 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Power Management Controller (PMC) driver for SAM.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PMC_H_INCLUDED
|
||||||
|
#define PMC_H_INCLUDED
|
||||||
|
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/** Bit mask for peripheral clocks (PCER0) */
|
||||||
|
#define PMC_MASK_STATUS0 (0xFFFFFFFC)
|
||||||
|
|
||||||
|
/** Bit mask for peripheral clocks (PCER1) */
|
||||||
|
#define PMC_MASK_STATUS1 (0xFFFFFFFF)
|
||||||
|
|
||||||
|
/** Loop counter timeout value */
|
||||||
|
#define PMC_TIMEOUT (2048)
|
||||||
|
|
||||||
|
/** Key to unlock CKGR_MOR register */
|
||||||
|
#define PMC_CKGR_MOR_KEY_VALUE CKGR_MOR_KEY(0x37)
|
||||||
|
|
||||||
|
/** Key used to write SUPC registers */
|
||||||
|
#define SUPC_KEY_VALUE ((uint32_t) 0xA5)
|
||||||
|
|
||||||
|
/** PMC xtal statup time */
|
||||||
|
#define PMC_XTAL_STARTUP_TIME (0x3F)
|
||||||
|
|
||||||
|
/** Mask to access fast startup input */
|
||||||
|
#define PMC_FAST_STARTUP_Msk (0xFFFFu)
|
||||||
|
|
||||||
|
/** PMC_WPMR Write Protect KEY, unlock it */
|
||||||
|
#define PMC_WPMR_WPKEY_VALUE PMC_WPMR_WPKEY((uint32_t) 0x504D43)
|
||||||
|
|
||||||
|
/** Using external oscillator */
|
||||||
|
#define PMC_OSC_XTAL 0
|
||||||
|
|
||||||
|
/** Oscillator in bypass mode */
|
||||||
|
#define PMC_OSC_BYPASS 1
|
||||||
|
|
||||||
|
#define PMC_PCK_0 0 /* PCK0 ID */
|
||||||
|
#define PMC_PCK_1 1 /* PCK1 ID */
|
||||||
|
#define PMC_PCK_2 2 /* PCK2 ID */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Master clock (MCK) Source and Prescaler configuration
|
||||||
|
*
|
||||||
|
* The following functions may be used to select the clock source and
|
||||||
|
* prescaler for the master clock.
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
void pmc_mck_set_prescaler(uint32_t ul_pres);
|
||||||
|
void pmc_mck_set_source(uint32_t ul_source);
|
||||||
|
uint32_t pmc_switch_mck_to_sclk(uint32_t ul_pres);
|
||||||
|
uint32_t pmc_switch_mck_to_mainck(uint32_t ul_pres);
|
||||||
|
uint32_t pmc_switch_mck_to_pllack(uint32_t ul_pres);
|
||||||
|
#if (SAM3S || SAM4S)
|
||||||
|
uint32_t pmc_switch_mck_to_pllbck(uint32_t ul_pres);
|
||||||
|
#endif
|
||||||
|
#if (SAM3XA || SAM3U)
|
||||||
|
uint32_t pmc_switch_mck_to_upllck(uint32_t ul_pres);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Slow clock (SLCK) oscillator and configuration
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass);
|
||||||
|
uint32_t pmc_osc_is_ready_32kxtal(void);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Main Clock (MAINCK) oscillator and configuration
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
void pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf);
|
||||||
|
void pmc_osc_enable_fastrc(uint32_t ul_rc);
|
||||||
|
void pmc_osc_disable_fastrc(void);
|
||||||
|
void pmc_switch_mainck_to_xtal(uint32_t ul_bypass);
|
||||||
|
void pmc_osc_disable_xtal(uint32_t ul_bypass);
|
||||||
|
uint32_t pmc_osc_is_ready_mainck(void);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name PLL oscillator and configuration
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva);
|
||||||
|
void pmc_disable_pllack(void);
|
||||||
|
uint32_t pmc_is_locked_pllack(void);
|
||||||
|
|
||||||
|
#if (SAM3S || SAM4S)
|
||||||
|
void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb);
|
||||||
|
void pmc_disable_pllbck(void);
|
||||||
|
uint32_t pmc_is_locked_pllbck(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SAM3XA || SAM3U)
|
||||||
|
void pmc_enable_upll_clock(void);
|
||||||
|
void pmc_disable_upll_clock(void);
|
||||||
|
uint32_t pmc_is_locked_upll(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Peripherals clock configuration
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
uint32_t pmc_enable_periph_clk(uint32_t ul_id);
|
||||||
|
uint32_t pmc_disable_periph_clk(uint32_t ul_id);
|
||||||
|
void pmc_enable_all_periph_clk(void);
|
||||||
|
void pmc_disable_all_periph_clk(void);
|
||||||
|
uint32_t pmc_is_periph_clk_enabled(uint32_t ul_id);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Programmable clock Source and Prescaler configuration
|
||||||
|
*
|
||||||
|
* The following functions may be used to select the clock source and
|
||||||
|
* prescaler for the specified programmable clock.
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
void pmc_pck_set_prescaler(uint32_t ul_id, uint32_t ul_pres);
|
||||||
|
void pmc_pck_set_source(uint32_t ul_id, uint32_t ul_source);
|
||||||
|
uint32_t pmc_switch_pck_to_sclk(uint32_t ul_id, uint32_t ul_pres);
|
||||||
|
uint32_t pmc_switch_pck_to_mainck(uint32_t ul_id, uint32_t ul_pres);
|
||||||
|
uint32_t pmc_switch_pck_to_pllack(uint32_t ul_id, uint32_t ul_pres);
|
||||||
|
#if (SAM3S || SAM4S)
|
||||||
|
uint32_t pmc_switch_pck_to_pllbck(uint32_t ul_id, uint32_t ul_pres);
|
||||||
|
#endif
|
||||||
|
#if (SAM3XA || SAM3U)
|
||||||
|
uint32_t pmc_switch_pck_to_upllck(uint32_t ul_id, uint32_t ul_pres);
|
||||||
|
#endif
|
||||||
|
void pmc_enable_pck(uint32_t ul_id);
|
||||||
|
void pmc_disable_pck(uint32_t ul_id);
|
||||||
|
void pmc_enable_all_pck(void);
|
||||||
|
void pmc_disable_all_pck(void);
|
||||||
|
uint32_t pmc_is_pck_enabled(uint32_t ul_id);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name USB clock configuration
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
#if (SAM3S || SAM3XA || SAM4S)
|
||||||
|
void pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv);
|
||||||
|
#endif
|
||||||
|
#if (SAM3S || SAM4S)
|
||||||
|
void pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv);
|
||||||
|
#endif
|
||||||
|
#if (SAM3XA)
|
||||||
|
void pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv);
|
||||||
|
#endif
|
||||||
|
#if (SAM3S || SAM3XA || SAM4S)
|
||||||
|
void pmc_enable_udpck(void);
|
||||||
|
void pmc_disable_udpck(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Interrupt and status management
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
void pmc_enable_interrupt(uint32_t ul_sources);
|
||||||
|
void pmc_disable_interrupt(uint32_t ul_sources);
|
||||||
|
uint32_t pmc_get_interrupt_mask(void);
|
||||||
|
uint32_t pmc_get_status(void);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Power management
|
||||||
|
*
|
||||||
|
* The following functions are used to configure sleep mode and additionnal
|
||||||
|
* wake up inputs.
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
void pmc_set_fast_startup_input(uint32_t ul_inputs);
|
||||||
|
void pmc_clr_fast_startup_input(uint32_t ul_inputs);
|
||||||
|
void pmc_enable_sleepmode(uint8_t uc_type);
|
||||||
|
void pmc_enable_waitmode(void);
|
||||||
|
void pmc_enable_backupmode(void);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Write protection
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
void pmc_set_writeprotect(uint32_t ul_enable);
|
||||||
|
uint32_t pmc_get_writeprotect_status(void);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \page sam_pmc_quickstart Quick start guide for the SAM PMC module
|
||||||
|
*
|
||||||
|
* This is the quick start guide for the \ref pmc_group "PMC module", with
|
||||||
|
* step-by-step instructions on how to configure and use the driver in a
|
||||||
|
* selection of use cases.
|
||||||
|
*
|
||||||
|
* The use cases contain several code fragments. The code fragments in the
|
||||||
|
* steps for setup can be copied into a custom initialization function, while
|
||||||
|
* the steps for usage can be copied into, e.g., the main application function.
|
||||||
|
*
|
||||||
|
* \section pmc_use_cases PMC use cases
|
||||||
|
* - \ref pmc_basic_use_case Basic use case - Switch Main Clock sources
|
||||||
|
* - \ref pmc_use_case_2 Advanced use case - Configure Programmable Clocks
|
||||||
|
*
|
||||||
|
* \section pmc_basic_use_case Basic use case - Switch Main Clock sources
|
||||||
|
* In this use case, the PMC module is configured for a variety of system clock
|
||||||
|
* sources and speeds. A LED is used to visually indicate the current clock
|
||||||
|
* speed as the source is switched.
|
||||||
|
*
|
||||||
|
* \section pmc_basic_use_case_setup Setup
|
||||||
|
*
|
||||||
|
* \subsection pmc_basic_use_case_setup_prereq Prerequisites
|
||||||
|
* -# \ref gpio_group "General Purpose I/O Management (gpio)"
|
||||||
|
*
|
||||||
|
* \subsection pmc_basic_use_case_setup_code Code
|
||||||
|
* The following function needs to be added to the user application, to flash a
|
||||||
|
* board LED a variable number of times at a rate given in CPU ticks.
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* #define FLASH_TICK_COUNT 0x00012345
|
||||||
|
*
|
||||||
|
* void flash_led(uint32_t tick_count, uint8_t flash_count)
|
||||||
|
* {
|
||||||
|
* SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
|
||||||
|
* SysTick->LOAD = tick_count;
|
||||||
|
*
|
||||||
|
* while (flash_count--)
|
||||||
|
* {
|
||||||
|
* gpio_toggle_pin(LED0_GPIO);
|
||||||
|
* while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
|
||||||
|
* gpio_toggle_pin(LED0_GPIO);
|
||||||
|
* while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \section pmc_basic_use_case_usage Use case
|
||||||
|
*
|
||||||
|
* \subsection pmc_basic_use_case_usage_code Example code
|
||||||
|
* Add to application C-file:
|
||||||
|
* \code
|
||||||
|
* for (;;)
|
||||||
|
* {
|
||||||
|
* pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz);
|
||||||
|
* flash_led(FLASH_TICK_COUNT, 5);
|
||||||
|
* pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz);
|
||||||
|
* flash_led(FLASH_TICK_COUNT, 5);
|
||||||
|
* pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz);
|
||||||
|
* flash_led(FLASH_TICK_COUNT, 5);
|
||||||
|
* pmc_switch_mainck_to_xtal(0);
|
||||||
|
* flash_led(FLASH_TICK_COUNT, 5);
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection pmc_basic_use_case_usage_flow Workflow
|
||||||
|
* -# Wrap the code in an infinite loop:
|
||||||
|
* \code
|
||||||
|
* for (;;)
|
||||||
|
* \endcode
|
||||||
|
* -# Switch the Master CPU frequency to the internal 12MHz RC oscillator, flash
|
||||||
|
* a LED on the board several times:
|
||||||
|
* \code
|
||||||
|
* pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz);
|
||||||
|
* flash_led(FLASH_TICK_COUNT, 5);
|
||||||
|
* \endcode
|
||||||
|
* -# Switch the Master CPU frequency to the internal 8MHz RC oscillator, flash
|
||||||
|
* a LED on the board several times:
|
||||||
|
* \code
|
||||||
|
* pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz);
|
||||||
|
* flash_led(FLASH_TICK_COUNT, 5);
|
||||||
|
* \endcode
|
||||||
|
* -# Switch the Master CPU frequency to the internal 4MHz RC oscillator, flash
|
||||||
|
* a LED on the board several times:
|
||||||
|
* \code
|
||||||
|
* pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz);
|
||||||
|
* flash_led(FLASH_TICK_COUNT, 5);
|
||||||
|
* \endcode
|
||||||
|
* -# Switch the Master CPU frequency to the external crystal oscillator, flash
|
||||||
|
* a LED on the board several times:
|
||||||
|
* \code
|
||||||
|
* pmc_switch_mainck_to_xtal(0);
|
||||||
|
* flash_led(FLASH_TICK_COUNT, 5);
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \page pmc_use_case_2 Use case #2 - Configure Programmable Clocks
|
||||||
|
* In this use case, the PMC module is configured to start the Slow Clock from
|
||||||
|
* an attached 32KHz crystal, and start one of the Programmable Clock modules
|
||||||
|
* sourced from the Slow Clock divided down with a prescale factor of 64.
|
||||||
|
*
|
||||||
|
* \section pmc_use_case_2_setup Setup
|
||||||
|
*
|
||||||
|
* \subsection pmc_use_case_2_setup_prereq Prerequisites
|
||||||
|
* -# \ref pio_group "Parallel Input/Output Controller (pio)"
|
||||||
|
*
|
||||||
|
* \subsection pmc_use_case_2_setup_code Code
|
||||||
|
* The following code must be added to the user application:
|
||||||
|
* \code
|
||||||
|
* pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17);
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection pmc_use_case_2_setup_code_workflow Workflow
|
||||||
|
* -# Configure the PCK1 pin to output on a specific port pin (in this case,
|
||||||
|
* PIOA pin 17) of the microcontroller.
|
||||||
|
* \code
|
||||||
|
* pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17);
|
||||||
|
* \endcode
|
||||||
|
* \note The peripheral selection and pin will vary according to your selected
|
||||||
|
* SAM device model. Refer to the "Peripheral Signal Multiplexing on I/O
|
||||||
|
* Lines" of your device's datasheet.
|
||||||
|
*
|
||||||
|
* \section pmc_use_case_2_usage Use case
|
||||||
|
* The generated PCK1 clock output can be viewed on an oscilloscope attached to
|
||||||
|
* the correct pin of the microcontroller.
|
||||||
|
*
|
||||||
|
* \subsection pmc_use_case_2_usage_code Example code
|
||||||
|
* Add to application C-file:
|
||||||
|
* \code
|
||||||
|
* pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL);
|
||||||
|
* pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64);
|
||||||
|
* pmc_enable_pck(PMC_PCK_1);
|
||||||
|
*
|
||||||
|
* for (;;)
|
||||||
|
* {
|
||||||
|
* // Do Nothing
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection pmc_use_case_2_usage_flow Workflow
|
||||||
|
* -# Switch the Slow Clock source input to an external 32KHz crystal:
|
||||||
|
* \code
|
||||||
|
* pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL);
|
||||||
|
* \endcode
|
||||||
|
* -# Switch the Programmable Clock module PCK1 source clock to the Slow Clock,
|
||||||
|
* with a prescaler of 64:
|
||||||
|
* \code
|
||||||
|
* pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64);
|
||||||
|
* \endcode
|
||||||
|
* -# Enable Programmable Clock module PCK1:
|
||||||
|
* \code
|
||||||
|
* pmc_enable_pck(PMC_PCK_1);
|
||||||
|
* \endcode
|
||||||
|
* -# Enter an infinite loop:
|
||||||
|
* \code
|
||||||
|
* for (;;)
|
||||||
|
* {
|
||||||
|
* // Do Nothing
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* PMC_H_INCLUDED */
|
@ -0,0 +1,217 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Sleep mode access
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SLEEP_H
|
||||||
|
#define SLEEP_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <compiler.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \defgroup sleep_group Power Manager (PM)
|
||||||
|
*
|
||||||
|
* This is a stub on the SAM Power Manager Control (PMC) for the sleepmgr service.
|
||||||
|
*
|
||||||
|
* \note To minimize the code overhead, these functions do not feature
|
||||||
|
* interrupt-protected access since they are likely to be called inside
|
||||||
|
* interrupt handlers or in applications where such protection is not
|
||||||
|
* necessary. If such protection is needed, it must be ensured by the calling
|
||||||
|
* code.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* \brief Sets the MCU in the specified sleep mode
|
||||||
|
* \param sleep_mode Sleep mode to set.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S) // SAM3 and SAM4 series
|
||||||
|
# include "pmc.h"
|
||||||
|
|
||||||
|
# define SAM_PM_SMODE_ACTIVE 0
|
||||||
|
# define SAM_PM_SMODE_SLEEP_WFE 1
|
||||||
|
# define SAM_PM_SMODE_SLEEP_WFI 2
|
||||||
|
# define SAM_PM_SMODE_WAIT 3
|
||||||
|
# define SAM_PM_SMODE_BACKUP 4
|
||||||
|
|
||||||
|
/* (SCR) Sleep deep bit */
|
||||||
|
#define SCR_SLEEPDEEP (0x1 << 2)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save clock settings and shutdown PLLs
|
||||||
|
*/
|
||||||
|
static inline void pmc_save_clock_settings(
|
||||||
|
uint32_t *p_osc_setting,
|
||||||
|
uint32_t *p_pll0_setting,
|
||||||
|
uint32_t *p_pll1_setting,
|
||||||
|
uint32_t *p_mck_setting)
|
||||||
|
{
|
||||||
|
if (p_osc_setting) {
|
||||||
|
*p_osc_setting = PMC->CKGR_MOR;
|
||||||
|
}
|
||||||
|
if (p_pll0_setting) {
|
||||||
|
*p_pll0_setting = PMC->CKGR_PLLAR;
|
||||||
|
}
|
||||||
|
if (p_pll1_setting) {
|
||||||
|
#if SAM3S||SAM4S
|
||||||
|
*p_pll1_setting = PMC->CKGR_PLLBR;
|
||||||
|
#elif SAM3U||SAM3XA
|
||||||
|
*p_pll1_setting = PMC->CKGR_UCKR;
|
||||||
|
#else
|
||||||
|
*p_pll1_setting = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (p_mck_setting) {
|
||||||
|
*p_mck_setting = PMC->PMC_MCKR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch MCK to Main clock (internal or external 12MHz) for fast wakeup
|
||||||
|
// If MAIN_CLK is already the source, just skip
|
||||||
|
if ((PMC->PMC_MCKR & PMC_MCKR_CSS_Msk) == PMC_MCKR_CSS_MAIN_CLK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If we have to enable the MAIN_CLK
|
||||||
|
if ((PMC->PMC_SR & PMC_SR_MOSCXTS) == 0) {
|
||||||
|
// Intend to use internal RC as source of MAIN_CLK
|
||||||
|
pmc_osc_enable_fastrc(CKGR_MOR_MOSCRCF_12_MHz);
|
||||||
|
pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz);
|
||||||
|
}
|
||||||
|
pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore clock settings
|
||||||
|
*/
|
||||||
|
static inline void pmc_restore_clock_setting(
|
||||||
|
uint32_t osc_setting,
|
||||||
|
uint32_t pll0_setting,
|
||||||
|
uint32_t pll1_setting,
|
||||||
|
uint32_t mck_setting)
|
||||||
|
{
|
||||||
|
uint32_t mckr;
|
||||||
|
if ((pll0_setting & CKGR_PLLAR_MULA_Msk) &&
|
||||||
|
pll0_setting != PMC->CKGR_PLLAR) {
|
||||||
|
PMC->CKGR_PLLAR = 0;
|
||||||
|
PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | pll0_setting;
|
||||||
|
while (!(PMC->PMC_SR & PMC_SR_LOCKA));
|
||||||
|
}
|
||||||
|
#if SAM3S||SAM4S
|
||||||
|
if ((pll1_setting & CKGR_PLLBR_MULB_Msk) &&
|
||||||
|
pll1_setting != PMC->CKGR_PLLBR) {
|
||||||
|
PMC->CKGR_PLLBR = 0;
|
||||||
|
PMC->CKGR_PLLBR = pll1_setting ;
|
||||||
|
while (!(PMC->PMC_SR & PMC_SR_LOCKB));
|
||||||
|
}
|
||||||
|
#elif SAM3U||SAM3XA
|
||||||
|
if ((pll1_setting & CKGR_UCKR_UPLLEN) &&
|
||||||
|
pll1_setting != PMC->CKGR_UCKR) {
|
||||||
|
PMC->CKGR_UCKR = 0;
|
||||||
|
PMC->CKGR_UCKR = pll1_setting;
|
||||||
|
while (!(PMC->PMC_SR & PMC_SR_LOCKU));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Switch to faster clock */
|
||||||
|
mckr = PMC->PMC_MCKR;
|
||||||
|
// Set PRES
|
||||||
|
PMC->PMC_MCKR = (mckr & ~PMC_MCKR_PRES_Msk)
|
||||||
|
| (mck_setting & PMC_MCKR_PRES_Msk);
|
||||||
|
while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
|
||||||
|
// Set CSS and others
|
||||||
|
PMC->PMC_MCKR = mck_setting;
|
||||||
|
while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
|
||||||
|
/* Shutdown fastrc */
|
||||||
|
if (0 == (osc_setting & CKGR_MOR_MOSCRCEN)) {
|
||||||
|
pmc_osc_disable_fastrc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pmc_sleep(int sleep_mode)
|
||||||
|
{
|
||||||
|
switch (sleep_mode) {
|
||||||
|
case SAM_PM_SMODE_SLEEP_WFI:
|
||||||
|
case SAM_PM_SMODE_SLEEP_WFE:
|
||||||
|
PMC->PMC_FSMR &= (uint32_t)~PMC_FSMR_LPM;
|
||||||
|
SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP;
|
||||||
|
cpu_irq_enable();
|
||||||
|
if (sleep_mode == SAM_PM_SMODE_SLEEP_WFI)
|
||||||
|
__WFI();
|
||||||
|
else
|
||||||
|
__WFE();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SAM_PM_SMODE_WAIT: {
|
||||||
|
uint32_t mor, pllr0, pllr1, mckr;
|
||||||
|
pmc_save_clock_settings(&mor, &pllr0, &pllr1, &mckr);
|
||||||
|
|
||||||
|
PMC->PMC_FSMR |= PMC_FSMR_LPM;
|
||||||
|
SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP ;
|
||||||
|
cpu_irq_enable();
|
||||||
|
__WFE();
|
||||||
|
|
||||||
|
cpu_irq_disable();
|
||||||
|
pmc_restore_clock_setting(mor, pllr0, pllr1, mckr);
|
||||||
|
cpu_irq_enable();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SAM_PM_SMODE_BACKUP:
|
||||||
|
SCB->SCR |= SCR_SLEEPDEEP ;
|
||||||
|
cpu_irq_enable();
|
||||||
|
__WFE() ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SLEEP_H */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,633 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief Universal Synchronous Asynchronous Receiver Transmitter (USART) driver for SAM.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef USART_H_INCLUDED
|
||||||
|
#define USART_H_INCLUDED
|
||||||
|
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \defgroup usart_group Universal Synchronous Asynchronous Receiver Transmitter (USART)
|
||||||
|
*
|
||||||
|
* See \ref sam_usart_quickstart.
|
||||||
|
*
|
||||||
|
* This is a low-level driver implementation for the SAM Universal
|
||||||
|
* Synchronous/Asynchronous Receiver/Transmitter.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/** Clock phase. */
|
||||||
|
#define SPI_CPHA (1 << 0)
|
||||||
|
|
||||||
|
/** Clock polarity. */
|
||||||
|
#define SPI_CPOL (1 << 1)
|
||||||
|
|
||||||
|
/** SPI mode definition. */
|
||||||
|
#define SPI_MODE_0 (SPI_CPHA)
|
||||||
|
#define SPI_MODE_1 0
|
||||||
|
#define SPI_MODE_2 (SPI_CPOL | SPI_CPHA)
|
||||||
|
#define SPI_MODE_3 (SPI_CPOL)
|
||||||
|
|
||||||
|
//! Input parameters when initializing RS232 and similar modes.
|
||||||
|
typedef struct {
|
||||||
|
//! Set baud rate of the USART (unused in slave modes).
|
||||||
|
uint32_t baudrate;
|
||||||
|
|
||||||
|
//! Number of bits, which should be one of the following: US_MR_CHRL_5_BIT,
|
||||||
|
//! US_MR_CHRL_6_BIT, US_MR_CHRL_7_BIT, US_MR_CHRL_8_BIT or US_MR_MODE9.
|
||||||
|
uint32_t char_length;
|
||||||
|
|
||||||
|
//! Parity type, which should be one of the following: US_MR_PAR_EVEN, US_MR_PAR_ODD,
|
||||||
|
//! US_MR_PAR_SPACE, US_MR_PAR_MARK, US_MR_PAR_NO or US_MR_PAR_MULTIDROP.
|
||||||
|
uint32_t parity_type;
|
||||||
|
|
||||||
|
//! Number of stop bits between two characters: US_MR_NBSTOP_1_BIT,
|
||||||
|
//! US_MR_NBSTOP_1_5_BIT, US_MR_NBSTOP_2_BIT.
|
||||||
|
//! \note US_MR_NBSTOP_1_5_BIT is supported in asynchronous modes only.
|
||||||
|
uint32_t stop_bits;
|
||||||
|
|
||||||
|
//! Run the channel in test mode, which should be one of following: US_MR_CHMODE_NORMAL,
|
||||||
|
//! US_MR_CHMODE_AUTOMATIC, US_MR_CHMODE_LOCAL_LOOPBACK, US_MR_CHMODE_REMOTE_LOOPBACK
|
||||||
|
uint32_t channel_mode;
|
||||||
|
|
||||||
|
//! Filter of IrDA mode, useless in other modes.
|
||||||
|
uint32_t irda_filter;
|
||||||
|
} sam_usart_opt_t;
|
||||||
|
|
||||||
|
//! Input parameters when initializing ISO7816 mode.
|
||||||
|
typedef struct {
|
||||||
|
//! Set the frequency of the ISO7816 clock.
|
||||||
|
uint32_t iso7816_hz;
|
||||||
|
|
||||||
|
//! The number of ISO7816 clock ticks in every bit period (1 to 2047, 0 = disable clock).
|
||||||
|
//! Baudrate rate = iso7816_hz / fidi_ratio
|
||||||
|
uint32_t fidi_ratio;
|
||||||
|
|
||||||
|
//! How to calculate the parity bit: US_MR_PAR_EVEN for normal mode or
|
||||||
|
//! US_MR_PAR_ODD for inverse mode.
|
||||||
|
uint32_t parity_type;
|
||||||
|
|
||||||
|
//! Inhibit Non Acknowledge:
|
||||||
|
//! - 0: the NACK is generated;
|
||||||
|
//! - 1: the NACK is not generated.
|
||||||
|
//!
|
||||||
|
//! \note This bit will be used only in ISO7816 mode, protocol T = 0 receiver.
|
||||||
|
uint32_t inhibit_nack;
|
||||||
|
|
||||||
|
//! Disable successive NACKs.
|
||||||
|
//! - 0: NACK is sent on the ISO line as soon as a parity error occurs in the received character.
|
||||||
|
//! Successive parity errors are counted up to the value in the max_iterations field.
|
||||||
|
//! These parity errors generate a NACK on the ISO line. As soon as this value is reached,
|
||||||
|
//! No additional NACK is sent on the ISO line. The ITERATION flag is asserted.
|
||||||
|
uint32_t dis_suc_nack;
|
||||||
|
|
||||||
|
//! Max number of repetitions (0 to 7).
|
||||||
|
uint32_t max_iterations;
|
||||||
|
|
||||||
|
//! Bit order in transmitted characters:
|
||||||
|
//! - 0: LSB first;
|
||||||
|
//! - 1: MSB first.
|
||||||
|
uint32_t bit_order;
|
||||||
|
|
||||||
|
//! Which protocol is used:
|
||||||
|
//! - 0: T = 0;
|
||||||
|
//! - 1: T = 1.
|
||||||
|
uint32_t protocol_type;
|
||||||
|
} usart_iso7816_opt_t;
|
||||||
|
|
||||||
|
//! Input parameters when initializing SPI mode.
|
||||||
|
typedef struct {
|
||||||
|
//! Set the frequency of the SPI clock (unused in slave mode).
|
||||||
|
uint32_t baudrate;
|
||||||
|
|
||||||
|
//! Number of bits, which should be one of the following: US_MR_CHRL_5_BIT,
|
||||||
|
//! US_MR_CHRL_6_BIT, US_MR_CHRL_7_BIT, US_MR_CHRL_8_BIT or US_MR_MODE9.
|
||||||
|
uint32_t char_length;
|
||||||
|
|
||||||
|
//! Which SPI mode to use, which should be one of the following:
|
||||||
|
//! SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3.
|
||||||
|
uint32_t spi_mode;
|
||||||
|
|
||||||
|
//! Run the channel in test mode, which should be one of following: US_MR_CHMODE_NORMAL,
|
||||||
|
//! US_MR_CHMODE_AUTOMATIC, US_MR_CHMODE_LOCAL_LOOPBACK, US_MR_CHMODE_REMOTE_LOOPBACK
|
||||||
|
uint32_t channel_mode;
|
||||||
|
} usart_spi_opt_t;
|
||||||
|
|
||||||
|
void usart_reset(Usart *p_usart);
|
||||||
|
uint32_t usart_init_rs232(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
uint32_t usart_init_hw_handshaking(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
#if (SAM3S || SAM4S || SAM3U)
|
||||||
|
uint32_t usart_init_modem(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
#endif
|
||||||
|
uint32_t usart_init_sync_master(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
uint32_t usart_init_sync_slave(Usart *p_usart, const sam_usart_opt_t *p_usart_opt);
|
||||||
|
uint32_t usart_init_rs485(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
uint32_t usart_init_irda(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
uint32_t usart_init_iso7816(Usart *p_usart, const usart_iso7816_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
uint32_t usart_init_spi_master(Usart *p_usart, const usart_spi_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
uint32_t usart_init_spi_slave(Usart *p_usart, const usart_spi_opt_t *p_usart_opt);
|
||||||
|
#if SAM3XA
|
||||||
|
uint32_t usart_init_lin_master(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
uint32_t usart_init_lin_slave(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck);
|
||||||
|
void usart_lin_abort_tx(Usart *p_usart);
|
||||||
|
void usart_lin_send_wakeup_signal(Usart *p_usart);
|
||||||
|
void usart_lin_set_node_action(Usart *p_usart, uint8_t uc_action);
|
||||||
|
void usart_lin_disable_parity(Usart *p_usart);
|
||||||
|
void usart_lin_enable_parity(Usart *p_usart);
|
||||||
|
void usart_lin_disable_checksum(Usart *p_usart);
|
||||||
|
void usart_lin_enable_checksum(Usart *p_usart);
|
||||||
|
void usart_lin_set_checksum_type(Usart *p_usart, uint8_t uc_type);
|
||||||
|
void usart_lin_set_data_len_mode(Usart *p_usart, uint8_t uc_mode);
|
||||||
|
void usart_lin_disable_frame_slot(Usart *p_usart);
|
||||||
|
void usart_lin_enable_frame_slot(Usart *p_usart);
|
||||||
|
void usart_lin_set_wakeup_signal_type(Usart *p_usart, uint8_t uc_type);
|
||||||
|
void usart_lin_set_response_data_len(Usart *p_usart, uint8_t uc_len);
|
||||||
|
void usart_lin_disable_pdc_mode(Usart *p_usart);
|
||||||
|
void usart_lin_enable_pdc_mode(Usart *p_usart);
|
||||||
|
void usart_lin_set_tx_identifier(Usart *p_usart, uint8_t uc_id);
|
||||||
|
uint8_t usart_lin_read_identifier(Usart *p_usart);
|
||||||
|
#endif
|
||||||
|
void usart_enable_tx(Usart *p_usart);
|
||||||
|
void usart_disable_tx(Usart *p_usart);
|
||||||
|
void usart_reset_tx(Usart *p_usart);
|
||||||
|
void usart_set_tx_timeguard(Usart *p_usart, uint32_t timeguard);
|
||||||
|
void usart_enable_rx(Usart *p_usart);
|
||||||
|
void usart_disable_rx(Usart *p_usart);
|
||||||
|
void usart_reset_rx(Usart *p_usart);
|
||||||
|
void usart_set_rx_timeout(Usart *p_usart, uint32_t timeout);
|
||||||
|
void usart_enable_interrupt(Usart *p_usart,uint32_t ul_sources);
|
||||||
|
void usart_disable_interrupt(Usart *p_usart,uint32_t ul_sources);
|
||||||
|
uint32_t usart_get_interrupt_mask(Usart *p_usart);
|
||||||
|
uint32_t usart_get_status(Usart *p_usart);
|
||||||
|
void usart_reset_status(Usart *p_usart);
|
||||||
|
void usart_start_tx_break(Usart *p_usart);
|
||||||
|
void usart_stop_tx_break(Usart *p_usart);
|
||||||
|
void usart_start_rx_timeout(Usart *p_usart);
|
||||||
|
uint32_t usart_send_address(Usart *p_usart, uint32_t ul_addr);
|
||||||
|
void usart_reset_iterations(Usart *p_usart);
|
||||||
|
void usart_reset_nack(Usart *p_usart);
|
||||||
|
void usart_restart_rx_timeout(Usart *p_usart);
|
||||||
|
#if (SAM3S || SAM4S || SAM3U)
|
||||||
|
void usart_drive_DTR_pin_low(Usart *p_usart);
|
||||||
|
void usart_drive_DTR_pin_high(Usart *p_usart);
|
||||||
|
#endif
|
||||||
|
void usart_drive_RTS_pin_low(Usart *p_usart);
|
||||||
|
void usart_drive_RTS_pin_high(Usart *p_usart);
|
||||||
|
void usart_spi_force_chip_select(Usart *p_usart);
|
||||||
|
void usart_spi_release_chip_select(Usart *p_usart);
|
||||||
|
uint32_t usart_is_tx_ready(Usart *p_usart);
|
||||||
|
uint32_t usart_is_tx_empty(Usart *p_usart);
|
||||||
|
uint32_t usart_is_rx_ready(Usart *p_usart);
|
||||||
|
uint32_t usart_is_rx_buf_end(Usart *p_usart);
|
||||||
|
uint32_t usart_is_tx_buf_end(Usart *p_usart);
|
||||||
|
uint32_t usart_is_rx_buf_full(Usart *p_usart);
|
||||||
|
uint32_t usart_is_tx_buf_empty(Usart *p_usart);
|
||||||
|
uint32_t usart_write(Usart *p_usart, uint32_t c);
|
||||||
|
uint32_t usart_putchar(Usart *p_usart, uint32_t c);
|
||||||
|
void usart_write_line(Usart *p_usart, const char *string);
|
||||||
|
uint32_t usart_read(Usart *p_usart, uint32_t *c);
|
||||||
|
uint32_t usart_getchar(Usart *p_usart, uint32_t *c);
|
||||||
|
#if (SAM3XA || SAM3U)
|
||||||
|
uint32_t * usart_get_tx_access(Usart *p_usart);
|
||||||
|
uint32_t * usart_get_rx_access(Usart *p_usart);
|
||||||
|
#endif
|
||||||
|
Pdc *usart_get_pdc_base(Usart *p_usart);
|
||||||
|
void usart_enable_writeprotect(Usart *p_usart);
|
||||||
|
void usart_disable_writeprotect(Usart *p_usart);
|
||||||
|
uint32_t usart_get_writeprotect_status(Usart *p_usart);
|
||||||
|
uint8_t usart_get_error_number(Usart *p_usart);
|
||||||
|
#if (SAM3S || SAM4S || SAM3U || SAM3XA)
|
||||||
|
void usart_man_set_tx_pre_len(Usart *p_usart, uint8_t uc_len);
|
||||||
|
void usart_man_set_tx_pre_pattern(Usart *p_usart, uint8_t uc_pattern);
|
||||||
|
void usart_man_set_tx_polarity(Usart *p_usart, uint8_t uc_polarity);
|
||||||
|
void usart_man_set_rx_pre_len(Usart *p_usart, uint8_t uc_len);
|
||||||
|
void usart_man_set_rx_pre_pattern(Usart *p_usart, uint8_t uc_pattern);
|
||||||
|
void usart_man_set_rx_polarity(Usart *p_usart, uint8_t uc_polarity);
|
||||||
|
void usart_man_enable_drift_compensation(Usart *p_usart);
|
||||||
|
void usart_man_disable_drift_compensation(Usart *p_usart);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// @cond 0
|
||||||
|
/**INDENT-OFF**/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**INDENT-ON**/
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \page sam_usart_quickstart Quick start guide for the SAM USART module
|
||||||
|
*
|
||||||
|
* This is the quick start guide for the \ref usart_group "USART module", with
|
||||||
|
* step-by-step instructions on how to configure and use the driver in a
|
||||||
|
* selection of use cases.
|
||||||
|
*
|
||||||
|
* The use cases contain several code fragments. The code fragments in the
|
||||||
|
* steps for setup can be copied into a custom initialization function, while
|
||||||
|
* the steps for usage can be copied into, e.g., the main application function.
|
||||||
|
*
|
||||||
|
* \note Some SAM devices contain both USART and UART modules, with the latter
|
||||||
|
* being a subset in functionality of the former but physically seperate
|
||||||
|
* peripherals. UART modules are compatible with the USART driver, but
|
||||||
|
* only for the functions and modes suported by the base UART driver.
|
||||||
|
*
|
||||||
|
* \section usart_basic_use_case Basic use case
|
||||||
|
* \section usart_use_cases USART use cases
|
||||||
|
* - \ref usart_basic_use_case
|
||||||
|
* - \subpage usart_use_case_1
|
||||||
|
* - \subpage usart_use_case_2
|
||||||
|
*
|
||||||
|
* \section usart_basic_use_case Basic use case - transmit a character
|
||||||
|
* In this use case, the USART module is configured for:
|
||||||
|
* - Using USART0
|
||||||
|
* - Baudrate: 9600
|
||||||
|
* - Character length: 8 bit
|
||||||
|
* - Parity mode: Disabled
|
||||||
|
* - Stop bit: None
|
||||||
|
* - RS232 mode
|
||||||
|
*
|
||||||
|
* \section usart_basic_use_case_setup Setup steps
|
||||||
|
*
|
||||||
|
* \subsection usart_basic_use_case_setup_prereq Prerequisites
|
||||||
|
* -# \ref sysclk_group "System Clock Management (sysclock)"
|
||||||
|
* -# \ref pio_group "Parallel Input/Output Controller (pio)"
|
||||||
|
* -# \ref pmc_group "Power Management Controller (pmc)"
|
||||||
|
*
|
||||||
|
* \subsection usart_basic_use_case_setup_code Example code
|
||||||
|
* The following configuration must be added to the project (typically to a
|
||||||
|
* conf_usart.h file, but it can also be added to your main application file.)
|
||||||
|
* \code
|
||||||
|
* #define USART_SERIAL USART0
|
||||||
|
* #define USART_SERIAL_ID ID_USART0
|
||||||
|
* #define USART_SERIAL_PIO PINS_USART_PIO
|
||||||
|
* #define USART_SERIAL_TYPE PINS_USART_TYPE
|
||||||
|
* #define USART_SERIAL_PINS PINS_USART_PINS
|
||||||
|
* #define USART_SERIAL_MASK PINS_USART_MASK
|
||||||
|
* #define USART_SERIAL_BAUDRATE 9600
|
||||||
|
* #define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT
|
||||||
|
* #define USART_SERIAL_PARITY US_MR_PAR_NO
|
||||||
|
* #define USART_SERIAL_STOP_BIT US_MR_NBSTOP_1_BIT
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* Add to application initialization:
|
||||||
|
* \code
|
||||||
|
* sysclk_init();
|
||||||
|
*
|
||||||
|
* pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE,
|
||||||
|
* USART_SERIAL_MASK, USART_SERIAL_ATTR);
|
||||||
|
*
|
||||||
|
* const sam_usart_opt_t usart_console_settings = {
|
||||||
|
* USART_SERIAL_BAUDRATE,
|
||||||
|
* USART_SERIAL_CHAR_LENGTH,
|
||||||
|
* USART_SERIAL_PARITY,
|
||||||
|
* USART_SERIAL_STOP_BIT,
|
||||||
|
* US_MR_CHMODE_NORMAL
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* pmc_enable_periph_clk(USART_SERIAL_ID);
|
||||||
|
*
|
||||||
|
* usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz());
|
||||||
|
* usart_enable_tx(USART_SERIAL);
|
||||||
|
* usart_enable_rx(USART_SERIAL);
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection usart_basic_use_case_setup_flow Workflow
|
||||||
|
* -# Initialize system clock:
|
||||||
|
* \code
|
||||||
|
* sysclk_init();
|
||||||
|
* \endcode
|
||||||
|
* -# Configure the USART Tx and Rx pins as Outputs and Inputs respectively:
|
||||||
|
* \code
|
||||||
|
* pio_configure(PINS_UART_PIO, PINS_UART_TYPE, PINS_UART_MASK,
|
||||||
|
* PINS_UART_ATTR);
|
||||||
|
* \endcode
|
||||||
|
* -# Create USART options struct:
|
||||||
|
* \code
|
||||||
|
* const sam_usart_opt_t usart_console_settings = {
|
||||||
|
* USART_SERIAL_BAUDRATE,
|
||||||
|
* USART_SERIAL_CHAR_LENGTH,
|
||||||
|
* USART_SERIAL_PARITY,
|
||||||
|
* USART_SERIAL_STOP_BIT,
|
||||||
|
* US_MR_CHMODE_NORMAL
|
||||||
|
* };
|
||||||
|
* \endcode
|
||||||
|
* -# Enable the clock to the USART module:
|
||||||
|
* \code
|
||||||
|
* pmc_enable_periph_clk(USART_SERIAL_ID);
|
||||||
|
* \endcode
|
||||||
|
* -# Initialize the USART module in RS232 mode:
|
||||||
|
* \code
|
||||||
|
* usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz());
|
||||||
|
* \endcode
|
||||||
|
* -# Enable the Rx and Tx modes of the USART module:
|
||||||
|
* \code
|
||||||
|
* usart_enable_tx(USART_SERIAL);
|
||||||
|
* usart_enable_rx(USART_SERIAL);
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \section usart_basic_use_case_usage Usage steps
|
||||||
|
*
|
||||||
|
* \subsection usart_basic_use_case_usage_code Example code
|
||||||
|
* Add to application C-file:
|
||||||
|
* \code
|
||||||
|
* usart_putchar(USART_SERIAL, 'a');
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection usart_basic_use_case_usage_flow Workflow
|
||||||
|
* -# Send an 'a' character via USART
|
||||||
|
* \code usart_putchar(USART_SERIAL, 'a'); \endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \page usart_use_case_1 USART receive character and echo back
|
||||||
|
*
|
||||||
|
* In this use case, the USART module is configured for:
|
||||||
|
* - Using USART0
|
||||||
|
* - Baudrate: 9600
|
||||||
|
* - Character length: 8 bit
|
||||||
|
* - Parity mode: Disabled
|
||||||
|
* - Stop bit: None
|
||||||
|
* - RS232 mode
|
||||||
|
*
|
||||||
|
* The use case waits for a received character on the configured USART and
|
||||||
|
* echoes the character back to the same USART.
|
||||||
|
*
|
||||||
|
* \section usart_use_case_1_setup Setup steps
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_1_setup_prereq Prerequisites
|
||||||
|
* -# \ref sysclk_group "System Clock Management (sysclock)"
|
||||||
|
* -# \ref pio_group "Parallel Input/Output Controller (pio)"
|
||||||
|
* -# \ref pmc_group "Power Management Controller (pmc)"
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_1_setup_code Example code
|
||||||
|
* The following configuration must be added to the project (typically to a
|
||||||
|
* conf_usart.h file, but it can also be added to your main application file.):
|
||||||
|
* \code
|
||||||
|
* #define USART_SERIAL USART0
|
||||||
|
* #define USART_SERIAL_ID ID_USART0
|
||||||
|
* #define USART_SERIAL_PIO PINS_USART_PIO
|
||||||
|
* #define USART_SERIAL_TYPE PINS_USART_TYPE
|
||||||
|
* #define USART_SERIAL_PINS PINS_USART_PINS
|
||||||
|
* #define USART_SERIAL_MASK PINS_USART_MASK
|
||||||
|
* #define USART_SERIAL_BAUDRATE 9600
|
||||||
|
* #define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT
|
||||||
|
* #define USART_SERIAL_PARITY US_MR_PAR_NO
|
||||||
|
* #define USART_SERIAL_STOP_BIT US_MR_NBSTOP_1_BIT
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* A variable for the received byte must be added:
|
||||||
|
* \code
|
||||||
|
* uint32_t received_byte;
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* Add to application initialization:
|
||||||
|
* \code
|
||||||
|
* sysclk_init();
|
||||||
|
*
|
||||||
|
* pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE,
|
||||||
|
* USART_SERIAL_MASK, USART_SERIAL_ATTR);
|
||||||
|
*
|
||||||
|
* const sam_usart_opt_t usart_console_settings = {
|
||||||
|
* USART_SERIAL_BAUDRATE,
|
||||||
|
* USART_SERIAL_CHAR_LENGTH,
|
||||||
|
* USART_SERIAL_PARITY,
|
||||||
|
* USART_SERIAL_STOP_BIT,
|
||||||
|
* US_MR_CHMODE_NORMAL
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* pmc_enable_periph_clk(USART_SERIAL_ID);
|
||||||
|
*
|
||||||
|
* usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz());
|
||||||
|
* usart_enable_tx(USART_SERIAL);
|
||||||
|
* usart_enable_rx(USART_SERIAL);
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_1_setup_flow Workflow
|
||||||
|
* -# Initialize system clock:
|
||||||
|
* \code
|
||||||
|
* sysclk_init();
|
||||||
|
* \endcode
|
||||||
|
* -# Configure the USART Tx and Rx pins as Outputs and Inputs respectively:
|
||||||
|
* \code
|
||||||
|
* pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE,
|
||||||
|
* USART_SERIAL_MASK, USART_SERIAL_ATTR);
|
||||||
|
* \endcode
|
||||||
|
* -# Create USART options struct:
|
||||||
|
* \code
|
||||||
|
* const sam_usart_opt_t usart_console_settings = {
|
||||||
|
* USART_SERIAL_BAUDRATE,
|
||||||
|
* USART_SERIAL_CHAR_LENGTH,
|
||||||
|
* USART_SERIAL_PARITY,
|
||||||
|
* USART_SERIAL_STOP_BIT,
|
||||||
|
* US_MR_CHMODE_NORMAL
|
||||||
|
* };
|
||||||
|
* \endcode
|
||||||
|
* -# Enable the clock to the USART module:
|
||||||
|
* \code pmc_enable_periph_clk(USART_SERIAL_ID); \endcode
|
||||||
|
* -# Initialize the USART module in RS232 mode:
|
||||||
|
* \code usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz()); \endcode
|
||||||
|
* -# Enable the Rx and Tx modes of the USART module:
|
||||||
|
* \code
|
||||||
|
* usart_enable_tx(USART_SERIAL);
|
||||||
|
* usart_enable_rx(USART_SERIAL);
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \section usart_use_case_1_usage Usage steps
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_1_usage_code Example code
|
||||||
|
* Add to, e.g., main loop in application C-file:
|
||||||
|
* \code
|
||||||
|
* received_byte = usart_getchar(USART_SERIAL);
|
||||||
|
* usart_putchar(USART_SERIAL, received_byte);
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_1_usage_flow Workflow
|
||||||
|
* -# Wait for reception of a character:
|
||||||
|
* \code usart_getchar(USART_SERIAL, &received_byte); \endcode
|
||||||
|
* -# Echo the character back:
|
||||||
|
* \code usart_putchar(USART_SERIAL, received_byte); \endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \page usart_use_case_2 USART receive character and echo back via interrupts
|
||||||
|
*
|
||||||
|
* In this use case, the USART module is configured for:
|
||||||
|
* - Using USART0
|
||||||
|
* - Baudrate: 9600
|
||||||
|
* - Character length: 8 bit
|
||||||
|
* - Parity mode: Disabled
|
||||||
|
* - Stop bit: None
|
||||||
|
* - RS232 mode
|
||||||
|
*
|
||||||
|
* The use case waits for a received character on the configured USART and
|
||||||
|
* echoes the character back to the same USART. The character reception is
|
||||||
|
* performed via an interrupt handler, rather than the polling method used
|
||||||
|
* in \ref usart_use_case_1.
|
||||||
|
*
|
||||||
|
* \section usart_use_case_2_setup Setup steps
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_2_setup_prereq Prerequisites
|
||||||
|
* -# \ref sysclk_group "System Clock Management (sysclock)"
|
||||||
|
* -# \ref pio_group "Parallel Input/Output Controller (pio)"
|
||||||
|
* -# \ref pmc_group "Power Management Controller (pmc)"
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_2_setup_code Example code
|
||||||
|
* The following configuration must be added to the project (typically to a
|
||||||
|
* conf_usart.h file, but it can also be added to your main application file.):
|
||||||
|
* \code
|
||||||
|
* #define USART_SERIAL USART0
|
||||||
|
* #define USART_SERIAL_ID ID_USART0
|
||||||
|
* #define USART_SERIAL_ISR_HANDLER USART0_Handler
|
||||||
|
* #define USART_SERIAL_PIO PINS_USART_PIO
|
||||||
|
* #define USART_SERIAL_TYPE PINS_USART_TYPE
|
||||||
|
* #define USART_SERIAL_PINS PINS_USART_PINS
|
||||||
|
* #define USART_SERIAL_MASK PINS_USART_MASK
|
||||||
|
* #define USART_SERIAL_BAUDRATE 9600
|
||||||
|
* #define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT
|
||||||
|
* #define USART_SERIAL_PARITY US_MR_PAR_NO
|
||||||
|
* #define USART_SERIAL_STOP_BIT US_MR_NBSTOP_1_BIT
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* A variable for the received byte must be added:
|
||||||
|
* \code
|
||||||
|
* uint32_t received_byte;
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* Add to application initialization:
|
||||||
|
* \code
|
||||||
|
* sysclk_init();
|
||||||
|
*
|
||||||
|
* pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE,
|
||||||
|
* USART_SERIAL_MASK, USART_SERIAL_ATTR);
|
||||||
|
*
|
||||||
|
* const sam_usart_opt_t usart_console_settings = {
|
||||||
|
* USART_SERIAL_BAUDRATE,
|
||||||
|
* USART_SERIAL_CHAR_LENGTH,
|
||||||
|
* USART_SERIAL_PARITY,
|
||||||
|
* USART_SERIAL_STOP_BIT,
|
||||||
|
* US_MR_CHMODE_NORMAL
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* pmc_enable_periph_clk(USART_SERIAL_ID);
|
||||||
|
*
|
||||||
|
* usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz());
|
||||||
|
* usart_enable_tx(USART_SERIAL);
|
||||||
|
* usart_enable_rx(USART_SERIAL);
|
||||||
|
*
|
||||||
|
* usart_enable_interrupt(USART_SERIAL, US_IER_RXRDY);
|
||||||
|
* NVIC_EnableIRQ(USART_SERIAL_IRQ);
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_2_setup_flow Workflow
|
||||||
|
* -# Initialize system clock:
|
||||||
|
* \code
|
||||||
|
* sysclk_init();
|
||||||
|
* \endcode
|
||||||
|
* -# Configure the USART Tx and Rx pins as Outputs and Inputs respectively:
|
||||||
|
* \code
|
||||||
|
* pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE,
|
||||||
|
* USART_SERIAL_MASK, USART_SERIAL_ATTR);
|
||||||
|
* \endcode
|
||||||
|
* -# Create USART options struct:
|
||||||
|
* \code
|
||||||
|
* const sam_usart_opt_t usart_console_settings = {
|
||||||
|
* USART_SERIAL_BAUDRATE,
|
||||||
|
* USART_SERIAL_CHAR_LENGTH,
|
||||||
|
* USART_SERIAL_PARITY,
|
||||||
|
* USART_SERIAL_STOP_BIT,
|
||||||
|
* US_MR_CHMODE_NORMAL
|
||||||
|
* };
|
||||||
|
* \endcode
|
||||||
|
* -# Enable the clock to the USART module:
|
||||||
|
* \code pmc_enable_periph_clk(USART_SERIAL_ID); \endcode
|
||||||
|
* -# Initialize the USART module in RS232 mode:
|
||||||
|
* \code usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz()); \endcode
|
||||||
|
* -# Enable the Rx and Tx modes of the USART module:
|
||||||
|
* \code
|
||||||
|
* usart_enable_tx(USART_SERIAL);
|
||||||
|
* usart_enable_rx(USART_SERIAL);
|
||||||
|
* \endcode
|
||||||
|
* -# Enable the USART character reception interrupt, and general interrupts for the USART module.
|
||||||
|
* \code
|
||||||
|
* usart_enable_interrupt(USART_SERIAL, US_IER_RXRDY);
|
||||||
|
* NVIC_EnableIRQ(USART_SERIAL_IRQ);
|
||||||
|
* \endcode
|
||||||
|
* \section usart_use_case_2_usage Usage steps
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_2_usage_code Example code
|
||||||
|
* Add to your main application C-file the USART interrupt handler:
|
||||||
|
* \code
|
||||||
|
* void USART_SERIAL_ISR_HANDLER(void)
|
||||||
|
* {
|
||||||
|
* uint32_t dw_status = usart_get_status(USART_SERIAL);
|
||||||
|
*
|
||||||
|
* if (dw_status & US_CSR_RXRDY) {
|
||||||
|
* uint32_t received_byte;
|
||||||
|
*
|
||||||
|
* usart_read(USART_SERIAL, &received_byte);
|
||||||
|
* usart_write(USART_SERIAL, received_byte);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* \subsection usart_use_case_2_usage_flow Workflow
|
||||||
|
* -# When the USART ISR fires, retrieve the USART module interrupt flags:
|
||||||
|
* \code uint32_t dw_status = usart_get_status(USART_SERIAL); \endcode
|
||||||
|
* -# Check if the USART Receive Character interrupt has fired:
|
||||||
|
* \code if (dw_status & US_CSR_RXRDY) \endcode
|
||||||
|
* -# If a character has been received, fetch it into a temporary variable:
|
||||||
|
* \code usart_read(USART_SERIAL, &received_byte); \endcode
|
||||||
|
* -# Echo the character back:
|
||||||
|
* \code usart_write(USART_SERIAL, received_byte); \endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* USART_H_INCLUDED */
|
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief SAM4S clock configuration.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* \asf_license_start
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 4. This software may only be redistributed and used in connection with an
|
||||||
|
* Atmel microcontroller product.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* \asf_license_stop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONF_CLOCK_H_INCLUDED
|
||||||
|
#define CONF_CLOCK_H_INCLUDED
|
||||||
|
|
||||||
|
// ===== System Clock (MCK) Source Options
|
||||||
|
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_RC
|
||||||
|
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_XTAL
|
||||||
|
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_BYPASS
|
||||||
|
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC
|
||||||
|
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_8M_RC
|
||||||
|
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_12M_RC
|
||||||
|
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_XTAL
|
||||||
|
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_BYPASS
|
||||||
|
#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK
|
||||||
|
//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLBCK
|
||||||
|
|
||||||
|
// ===== System Clock (MCK) Prescaler Options (Fmck = Fsys / (SYSCLK_PRES))
|
||||||
|
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
|
||||||
|
#define CONFIG_SYSCLK_PRES SYSCLK_PRES_2
|
||||||
|
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_4
|
||||||
|
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_8
|
||||||
|
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_16
|
||||||
|
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_32
|
||||||
|
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_64
|
||||||
|
//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_3
|
||||||
|
|
||||||
|
// ===== PLL0 (A) Options (Fpll = (Fclk * PLL_mul) / PLL_div)
|
||||||
|
// Use mul and div effective values here.
|
||||||
|
#define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL
|
||||||
|
#define CONFIG_PLL0_MUL 20
|
||||||
|
#define CONFIG_PLL0_DIV 1
|
||||||
|
|
||||||
|
// ===== PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div)
|
||||||
|
// Use mul and div effective values here.
|
||||||
|
//#define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL
|
||||||
|
//#define CONFIG_PLL1_MUL 16
|
||||||
|
//#define CONFIG_PLL1_DIV 2
|
||||||
|
|
||||||
|
// ===== USB Clock Source Options (Fusb = FpllX / USB_div)
|
||||||
|
// Use div effective value here.
|
||||||
|
//#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0
|
||||||
|
//#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1
|
||||||
|
//#define CONFIG_USBCLK_DIV 2
|
||||||
|
|
||||||
|
// ===== Target frequency (System clock)
|
||||||
|
// - XTAL frequency: 12MHz
|
||||||
|
// - System clock source: PLLA
|
||||||
|
// - System clock prescaler: 2 (divided by 2)
|
||||||
|
// - PLLA source: XTAL
|
||||||
|
// - PLLA output: XTAL * 20 / 1
|
||||||
|
// - System clock: 12 * 20 / 1 / 2 = 120MHz
|
||||||
|
// ===== Target frequency (USB Clock)
|
||||||
|
// - USB clock source: PLLB
|
||||||
|
// - USB clock devider: 2 (devided by 2)
|
||||||
|
// - PLLB output: XTAL * 16 / 2
|
||||||
|
// - USB clock: 12 * 16 / 2 / 2 = 48MHz
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CONF_CLOCK_H_INCLUDED */
|
@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong? *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest information,
|
||||||
|
license and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR USART1.
|
||||||
|
|
||||||
|
***Note*** This example uses queues to send each character into an interrupt
|
||||||
|
service routine and out of an interrupt service routine individually. This
|
||||||
|
is done to demonstrate queues being used in an interrupt, and to deliberately
|
||||||
|
load the system to test the FreeRTOS port. It is *NOT* meant to be an
|
||||||
|
example of an efficient implementation. An efficient implementation should
|
||||||
|
use FIFO's or DMA if available, and only use FreeRTOS API functions when
|
||||||
|
enough has been received to warrant a task being unblocked to process the
|
||||||
|
data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
#include "comtest2.h"
|
||||||
|
|
||||||
|
/* Library includes. */
|
||||||
|
#include "asf.h"
|
||||||
|
|
||||||
|
/* Demo application includes. */
|
||||||
|
#include "demo_serial.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Misc defines. */
|
||||||
|
#define serINVALID_QUEUE ( ( xQueueHandle ) 0 )
|
||||||
|
#define serNO_BLOCK ( ( portTickType ) 0 )
|
||||||
|
#define serPMC_USART_ID ( BOARD_ID_USART )
|
||||||
|
|
||||||
|
/* The USART supported by this file. */
|
||||||
|
#define serUSART_PORT ( USART1 )
|
||||||
|
#define serUSART_IRQ ( USART1_IRQn )
|
||||||
|
|
||||||
|
/* Every bit in the interrupt mask. */
|
||||||
|
#define serMASK_ALL_INTERRUPTS ( 0xffffffffUL )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The queue used to hold received characters. */
|
||||||
|
static xQueueHandle xRxedChars;
|
||||||
|
static xQueueHandle xCharsForTx;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See the serial.h header file.
|
||||||
|
*/
|
||||||
|
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
|
||||||
|
{
|
||||||
|
uint32_t ulChar;
|
||||||
|
xComPortHandle xReturn;
|
||||||
|
const sam_usart_opt_t xUSARTSettings =
|
||||||
|
{
|
||||||
|
ulWantedBaud,
|
||||||
|
US_MR_CHRL_8_BIT,
|
||||||
|
US_MR_PAR_NO,
|
||||||
|
US_MR_NBSTOP_1_BIT,
|
||||||
|
US_MR_CHMODE_NORMAL,
|
||||||
|
0 /* Only used in IrDA mode. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create the queues used to hold Rx/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 ) )
|
||||||
|
{
|
||||||
|
/* Enable the peripheral clock in the PMC. */
|
||||||
|
pmc_enable_periph_clk( serPMC_USART_ID );
|
||||||
|
|
||||||
|
/* Configure USART in serial mode. */
|
||||||
|
usart_init_rs232( serUSART_PORT, &xUSARTSettings, sysclk_get_cpu_hz() );
|
||||||
|
|
||||||
|
/* Disable all the interrupts. */
|
||||||
|
usart_disable_interrupt( serUSART_PORT, serMASK_ALL_INTERRUPTS );
|
||||||
|
|
||||||
|
/* Enable the receiver and transmitter. */
|
||||||
|
usart_enable_tx( serUSART_PORT );
|
||||||
|
usart_enable_rx( serUSART_PORT );
|
||||||
|
|
||||||
|
/* Clear any characters before enabling interrupt. */
|
||||||
|
usart_getchar( serUSART_PORT, &ulChar );
|
||||||
|
|
||||||
|
/* Enable Rx end interrupt. */
|
||||||
|
usart_enable_interrupt( serUSART_PORT, US_IER_RXRDY );
|
||||||
|
|
||||||
|
/* Configure and enable interrupt of USART. */
|
||||||
|
NVIC_SetPriority( serUSART_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
NVIC_EnableIRQ( serUSART_IRQ );
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime )
|
||||||
|
{
|
||||||
|
/* The port handle is not required as this driver only supports one port. */
|
||||||
|
( void ) pxPort;
|
||||||
|
|
||||||
|
/* Get the next character from the buffer. Return false if no characters
|
||||||
|
are available, or arrive before xBlockTime expires. */
|
||||||
|
if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
|
||||||
|
{
|
||||||
|
return pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength )
|
||||||
|
{
|
||||||
|
signed char *pxNext;
|
||||||
|
|
||||||
|
/* A couple of parameters that this port does not use. */
|
||||||
|
( void ) usStringLength;
|
||||||
|
( void ) pxPort;
|
||||||
|
|
||||||
|
/* NOTE: This implementation does not handle the queue being full as no
|
||||||
|
block time is used! */
|
||||||
|
|
||||||
|
/* The port handle is not required as this driver only supports USART1. */
|
||||||
|
( void ) pxPort;
|
||||||
|
|
||||||
|
/* Send each character in the string, one at a time. */
|
||||||
|
pxNext = ( signed char * ) pcString;
|
||||||
|
while( *pxNext )
|
||||||
|
{
|
||||||
|
xSerialPutChar( pxPort, *pxNext, serNO_BLOCK );
|
||||||
|
pxNext++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime )
|
||||||
|
{
|
||||||
|
signed portBASE_TYPE xReturn;
|
||||||
|
|
||||||
|
/* This simple example only supports one port. */
|
||||||
|
( void ) pxPort;
|
||||||
|
|
||||||
|
if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS )
|
||||||
|
{
|
||||||
|
xReturn = pdPASS;
|
||||||
|
usart_enable_interrupt( serUSART_PORT, US_IER_TXRDY );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vSerialClose( xComPortHandle xPort )
|
||||||
|
{
|
||||||
|
/* Not supported as not required by the demo application. */
|
||||||
|
( void ) xPort;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void USART1_Handler( void )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
uint8_t ucChar;
|
||||||
|
uint32_t ulChar;
|
||||||
|
uint32_t ulUSARTStatus, ulUSARTMask;
|
||||||
|
|
||||||
|
ulUSARTStatus = usart_get_status( serUSART_PORT );
|
||||||
|
ulUSARTMask = usart_get_interrupt_mask( serUSART_PORT );
|
||||||
|
ulUSARTStatus &= ulUSARTMask;
|
||||||
|
|
||||||
|
if( ( ulUSARTStatus & US_CSR_TXRDY ) != 0UL )
|
||||||
|
{
|
||||||
|
/* The interrupt was caused by the TX register becoming empty. Are
|
||||||
|
there any more characters to transmit? */
|
||||||
|
if( xQueueReceiveFromISR( xCharsForTx, &ucChar, &xHigherPriorityTaskWoken ) == pdTRUE )
|
||||||
|
{
|
||||||
|
/* A character was retrieved from the queue so can be sent to the
|
||||||
|
USART now. */
|
||||||
|
usart_putchar( serUSART_PORT, ( uint32_t ) ucChar );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usart_disable_interrupt( serUSART_PORT, US_IER_TXRDY );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( ulUSARTStatus & US_CSR_RXRDY ) != 0UL )
|
||||||
|
{
|
||||||
|
/* A character has been received on the USART, send it to the Rx
|
||||||
|
handler task. */
|
||||||
|
usart_getchar( serUSART_PORT, &ulChar );
|
||||||
|
ucChar = ( uint8_t ) ( ulChar & 0xffUL );
|
||||||
|
xQueueSendFromISR( xRxedChars, &ucChar, &xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If sending or receiving from a queue has 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 xHigherPriorityTaskWoken
|
||||||
|
will have automatically been set to pdTRUE within the queue send or receive
|
||||||
|
function. portEND_SWITCHING_ISR() will then ensure that this ISR returns
|
||||||
|
directly to the higher priority unblocked task. */
|
||||||
|
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue