Update some more standard demos for use on 64-bit architectures.

Update the Xilinx Ultrascale+ Cortex-A53 (64-bit) and Cortex-R5 (32-bit) demos to use version 2016.1 of the SDK.
This commit is contained in:
Richard Barry 2016-05-06 12:40:27 +00:00
parent 0cb71ee9ce
commit 324127837c
269 changed files with 193989 additions and 181 deletions

View file

@ -69,7 +69,7 @@
</matcher>
</filter>
<filter>
<id>1461847438191</id>
<id>1462537732456</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -78,7 +78,7 @@
</matcher>
</filter>
<filter>
<id>1461847438201</id>
<id>1462537732456</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -87,7 +87,7 @@
</matcher>
</filter>
<filter>
<id>1461847438221</id>
<id>1462537732466</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -96,7 +96,7 @@
</matcher>
</filter>
<filter>
<id>1461847438241</id>
<id>1462537732466</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -105,7 +105,7 @@
</matcher>
</filter>
<filter>
<id>1461847438251</id>
<id>1462537732476</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -114,7 +114,7 @@
</matcher>
</filter>
<filter>
<id>1461847438251</id>
<id>1462537732486</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -123,7 +123,7 @@
</matcher>
</filter>
<filter>
<id>1461847438261</id>
<id>1462537732486</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -132,7 +132,7 @@
</matcher>
</filter>
<filter>
<id>1461847438261</id>
<id>1462537732496</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -141,7 +141,7 @@
</matcher>
</filter>
<filter>
<id>1461847438271</id>
<id>1462537732506</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -150,7 +150,7 @@
</matcher>
</filter>
<filter>
<id>1461847438281</id>
<id>1462537732506</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -159,7 +159,7 @@
</matcher>
</filter>
<filter>
<id>1461847438301</id>
<id>1462537732516</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
@ -167,6 +167,42 @@
<arguments>1.0-name-matches-false-false-IntSemTest.c</arguments>
</matcher>
</filter>
<filter>
<id>1462537732516</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-StaticAllocation.c</arguments>
</matcher>
</filter>
<filter>
<id>1462537732526</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-AbortDelay.c</arguments>
</matcher>
</filter>
<filter>
<id>1462537732536</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-QueueOverwrite.c</arguments>
</matcher>
</filter>
<filter>
<id>1462537732546</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-TimerDemo.c</arguments>
</matcher>
</filter>
<filter>
<id>1461847264041</id>
<name>src/FreeRTOS_Source/portable/GCC</name>

View file

@ -75,7 +75,7 @@
* implements the simply blinky style version.
*
* NOTE 2: This file only contains the source code that is specific to the
* basic demo. Generic functions, such FreeRTOS hook functions, and functions
* simple demo. Generic functions, such FreeRTOS hook functions, and functions
* required to configure the hardware are defined in main.c.
******************************************************************************
*
@ -94,14 +94,14 @@
* in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
* blocks on attempts to read data from the queue that was created within
* main_blinky(). When data is received, the task checks the value of the
* data, and if the value equals the expected 100, toggles an LED. The 'block
* time' parameter passed to the queue receive function specifies that the
* task should be held in the Blocked state indefinitely to wait for data to
* be available on the queue. The queue receive task will only leave the
* Blocked state when the queue send task writes to the queue. As the queue
* send task writes to the queue every 200 milliseconds, the queue receive
* task leaves the Blocked state every 200 milliseconds, and therefore toggles
* the LED every 200 milliseconds.
* data, and if the value equals the expected 100, outputs a message to the
* UART. The 'block time' parameter passed to the queue receive function
* specifies that the task should be held in the Blocked state indefinitely to
* wait for data to be available on the queue. The queue receive task will only
* leave the Blocked state when the queue send task writes to the queue. As the
* queue send task writes to the queue every 200 milliseconds, the queue receive
* task leaves the Blocked state every 200 milliseconds, and therefore outputs
* a message every 200 milliseconds.
*/
/* Kernel includes. */
@ -109,8 +109,8 @@
#include "task.h"
#include "semphr.h"
/* Standard demo includes. */
#include "partest.h"
/* Xilinx includes. */
#include "xil_printf.h"
/* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -125,9 +125,6 @@ will remove items as they are added, meaning the send task should always find
the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* The LED toggled by the Rx task. */
#define mainTASK_LED ( 0 )
/*-----------------------------------------------------------*/
/*
@ -221,7 +218,7 @@ const uint32_t ulExpectedValue = 100UL;
it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == ulExpectedValue )
{
vParTestToggleLED( mainTASK_LED );
xil_printf( "100 received\r\n" );
ulReceivedValue = 0U;
}
}

View file

@ -132,6 +132,10 @@
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_QUEUE_SETS 1
/* This demo creates RTOS objects using both static and dynamic allocation. */
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1 /* Defaults to 1 anyway. */
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
@ -153,6 +157,8 @@ to exclude the API function. */
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetHandle 1
/* This demo makes use of one or more example stats formatting functions. These
format the raw data provided by the uxTaskGetSystemState() function in to human
@ -176,8 +182,8 @@ command interpreter running. */
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
void vAssertCalled( const char * pcFile, unsigned long ulLine );
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ );
void vMainAssertCalled( const char *pcFileName, uint32_t ulLineNumber );
#define configASSERT( x ) if( ( x ) == 0 ) { vMainAssertCalled( __FILE__, __LINE__ ); }
/* If configTASK_RETURN_ADDRESS is not defined then a task that attempts to
return from its implementing function will end up in a "task exit error"

View file

@ -101,16 +101,10 @@
* frequently. A register containing an unexpected value is indicative of an
* error in the context switching mechanism.
*
* "Check" task - The check task period is initially set to three seconds. The
* task checks that all the standard demo tasks, and the register check tasks,
* are not only still executing, but are executing without reporting any errors.
* If the check task discovers that a task has either stalled, or reported an
* error, then it changes its own execution period from the initial three
* seconds, to just 200ms. The check task also toggles an LED each time it is
* called. This provides a visual indication of the system status: If the LED
* toggles every five seconds, then no issues have been discovered. If the LED
* toggles every 200ms, then an issue has been discovered with at least one
* task.
* "Check" task - The check task period is set to five seconds. Each time it
* executes it checks all the standard demo tasks, and the register check tasks,
* are not only still executing, but are executing without reporting any errors,
* then outputs the system status to the UART.
*/
/* Standard includes. */
@ -130,11 +124,17 @@
#include "countsem.h"
#include "GenQTest.h"
#include "recmutex.h"
#include "partest.h"
#include "IntQueue.h"
#include "EventGroupsDemo.h"
#include "TaskNotify.h"
#include "IntSemTest.h"
#include "StaticAllocation.h"
#include "AbortDelay.h"
#include "QueueOverwrite.h"
#include "TimerDemo.h"
/* Xilinx includes. */
#include "xil_printf.h"
/* Priorities for the demo application tasks. */
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + ( UBaseType_t ) 1 )
@ -144,23 +144,14 @@
#define mainUART_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * ( UBaseType_t ) 3 )
#define mainCOM_TEST_TASK_PRIORITY ( tskIDLE_PRIORITY + ( UBaseType_t ) 2 )
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - ( UBaseType_t ) 1 )
/* The LED used by the check task. */
#define mainCHECK_LED ( 0 )
#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY )
/* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( ( TickType_t ) 0 )
/* The period of the check task, in ms, provided no errors have been reported by
any of the standard demo tasks. ms are converted to the equivalent in ticks
using the pdMS_TO_TICKS() macro constant. */
/* The period of the check task, in ms. */
#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( ( TickType_t ) 5000 )
/* The period of the check task, in ms, if an error has been reported in one of
the standard demo tasks. ms are converted to the equivalent in ticks using the
pdMS_TO_TICKS() macro. */
#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( ( TickType_t ) ( 200 ) )
/* Parameters that are passed into the register check tasks solely for the
purpose of ensuring parameters are passed into tasks correctly. */
#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
@ -207,6 +198,13 @@ extern void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriori
*/
static void prvPseudoRandomiser( void *pvParameters );
/*
* The full demo uses the tick hook function to include test code in the tick
* interrupt. vFullDemoTickHook() is called by vApplicationTickHook(), which
* is defined in main.c.
*/
void vFullDemoTickHook( void );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
@ -233,6 +231,10 @@ void main_full( void )
vStartEventGroupTasks();
vStartTaskNotifyTask();
vStartInterruptSemaphoreTasks();
vStartStaticallyAllocatedTasks();
vCreateAbortDelayTasks();
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
/* Create the register check tasks, as described at the top of this file */
xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL );
@ -266,6 +268,7 @@ TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
TickType_t xLastExecutionTime;
static uint64_t ullLastRegTest1Value = 0, ullLastRegTest2Value = 0;
uint64_t ullErrorFound = pdFALSE;
const char *pcStatusString = "Pass";
/* Just to stop compiler warnings. */
( void ) pvParameters;
@ -275,11 +278,8 @@ uint64_t ullErrorFound = pdFALSE;
xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration.
If an error is detected then the delay period is decreased from
mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the
effect of increasing the rate at which the onboard LED toggles, and in so
doing gives visual feedback of the system status. */
operating without error. The system status is written to the UART on each
iteration. */
for( ;; )
{
/* Delay until it is time to execute again. */
@ -290,85 +290,111 @@ uint64_t ullErrorFound = pdFALSE;
if( xAreIntQueueTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 0ULL;
pcStatusString = "Error: IntQ";
}
if( xAreMathsTaskStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 1ULL;
pcStatusString = "Error: Math";
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 2ULL;
pcStatusString = "Error: Dynamic";
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 4ULL;
pcStatusString = "Error: Block Time";
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 5ULL;
pcStatusString = "Error: Generic Queue";
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 6ULL;
pcStatusString = "Error: Recursive Mutex";
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 8ULL;
pcStatusString = "Error: Semaphore";
}
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 10ULL;
pcStatusString = "Error: Counting Semaphore";
}
if( xAreEventGroupTasksStillRunning() != pdPASS )
{
ullErrorFound |= 1ULL << 12ULL;
pcStatusString = "Error: Event Group";
}
if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 13ULL;
pcStatusString = "Error: Task Notifications";
}
if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 14ULL;
pcStatusString = "Error: Interrupt Semaphore";
}
if( xAreStaticAllocationTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 15ULL;
pcStatusString = "Error: Static Allocation";
}
if( xAreAbortDelayTestTasksStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 16ULL;
pcStatusString = "Error: Abort Delay";
}
if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
{
ullErrorFound |= 1ULL << 17ULL;
pcStatusString = "Error: Queue Overwrite";
}
if( xAreTimerDemoTasksStillRunning( xDelayPeriod ) != pdTRUE )
{
ullErrorFound |= 1ULL << 18ULL;
pcStatusString = "Error: Timer Demo";
}
/* Check that the register test 1 task is still running. */
if( ullLastRegTest1Value == ullRegTest1LoopCounter )
{
ullErrorFound |= 1ULL << 15ULL;
ullErrorFound |= 1ULL << 17ULL;
pcStatusString = "Error: Reg Test 1";
}
ullLastRegTest1Value = ullRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
if( ullLastRegTest2Value == ullRegTest2LoopCounter )
{
ullErrorFound |= 1ULL << 16ULL;
ullErrorFound |= 1ULL << 18ULL;
pcStatusString = "Error: Reg Test 2";
}
ullLastRegTest2Value = ullRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then
everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED );
if( ullErrorFound != pdFALSE )
{
/* An error has been detected in one of the tasks - flash the LED
at a higher frequency to give visible feedback that something has
gone wrong (it might just be that the loop back connector required
by the comtest tasks has not been fitted). */
xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
}
/* Output the system status string. */
xil_printf( "%s, status code = %lu, tick count = %lu\r\n", pcStatusString, ullErrorFound, xTaskGetTickCount() );
configASSERT( ullErrorFound == pdFALSE );
}
@ -451,9 +477,26 @@ volatile uint64_t ullNextRand = ( uint64_t ) &pvParameters, ullValue;
}
}
}
/*-----------------------------------------------------------*/
void vFullDemoTickHook( void )
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo();
/* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing();
/* Call the ISR component of the interrupt semaphore test. */
vInterruptSemaphorePeriodicTest();
/* Call the code that 'gives' a task notification from an ISR. */
xNotifyTaskFromISR();
}

View file

@ -68,29 +68,14 @@
*/
/******************************************************************************
* This project provides two demo applications. A simple blinky style project,
* and a more comprehensive test and demo application. The
* mainSELECTED_APPLICATION setting (defined in this file) is used to select
* between the two. The simply blinky demo is implemented and described in
* main_blinky.c. The more comprehensive test and demo application is
* implemented and described in main_full.c.
*
* This file implements the code that is not demo specific, including the
* hardware setup and FreeRTOS hook functions.
*
* !!! IMPORTANT NOTE !!!
* Some GCC libraries can make use of the floating point registers. To avoid
* this causing corruption it is necessary to avoid their use. For this reason
* main.c contains very basic C implementations of the standard C library
* functions memset(), memcpy() and memcmp(), which are are used by FreeRTOS
* itself. Defining these functions in the project prevents the linker pulling
* them in from the library. Any other standard C library functions that are
* used by the application must likewise be defined in C.
*
* ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON
* THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO
* APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!
* NOTE 1: This project provides two demo applications. A simple blinky
* style project, and a more comprehensive test and demo application. The
* mainSELECTED_APPLICATION setting in main.c is used to select between the two.
* See the notes on using mainSELECTED_APPLICATION where it is defined below.
*
* NOTE 2: This file only contains the source code that is not specific to
* either the simply blinky or full demos - this includes initialisation code
* and callback functions.
*/
/* Standard includes. */
@ -99,14 +84,6 @@
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* Standard demo includes. */
#include "partest.h"
#include "QueueOverwrite.h"
#include "EventGroupsDemo.h"
#include "TaskNotify.h"
#include "IntSemTest.h"
/* Xilinx includes. */
#include "platform.h"
@ -122,7 +99,7 @@
* When mainSELECTED_APPLICATION is set to 1 the comprehensive test and demo
* application will be run.
*/
#define mainSELECTED_APPLICATION 0
#define mainSELECTED_APPLICATION 1
/*-----------------------------------------------------------*/
@ -249,49 +226,68 @@ volatile size_t xFreeHeapSpace;
}
/*-----------------------------------------------------------*/
void vAssertCalled( const char * pcFile, unsigned long ulLine )
{
volatile unsigned long ul = 0;
( void ) pcFile;
( void ) ulLine;
taskENTER_CRITICAL();
{
#if( configUSE_TRACE_FACILITY == 1 )
{
vTraceStop();
}
#endif
/* Set ul to a non-zero value using the debugger to step out of this
function. */
while( ul == 0 )
{
portNOP();
}
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
#if( mainSELECTED_APPLICATION == 1 )
{
/* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing();
/* Use task notifications from an interrupt. */
xNotifyTaskFromISR();
/* Use mutexes from interrupts. */
vInterruptSemaphorePeriodicTest();
/* Only the comprehensive demo actually uses the tick hook. */
extern void vFullDemoTickHook( void );
vFullDemoTickHook();
}
#endif
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
{
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
/*-----------------------------------------------------------*/
void *memcpy( void *pvDest, const void *pvSource, size_t xBytes )
{
/* The compiler used during development seems to err unless these volatiles are
@ -350,3 +346,10 @@ volatile size_t x;
}
/*-----------------------------------------------------------*/
void vMainAssertCalled( const char *pcFileName, uint32_t ulLineNumber )
{
xil_printf( "ASSERT! Line %lu of file %s\r\n", ulLineNumber, pcFileName );
taskENTER_CRITICAL();
for( ;; );
}

View file

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="xilinx.gnu.arm.r5.exe.debug.1241551157">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.arm.r5.exe.debug.1241551157" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.r5" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="xilinx.gnu.arm.r5.exe.debug.1241551157" name="Debug" parent="xilinx.gnu.arm.r5.exe.debug">
<folderInfo id="xilinx.gnu.arm.r5.exe.debug.1241551157." name="/" resourcePath="">
<toolChain id="xilinx.gnu.arm.r5.exe.debug.toolchain.1042376297" name="Xilinx ARM R5 GNU Toolchain" superClass="xilinx.gnu.arm.r5.exe.debug.toolchain">
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.r5" id="xilinx.arm.r5.target.gnu.base.debug.1336822890" isAbstract="false" name="Debug Platform" superClass="xilinx.arm.r5.target.gnu.base.debug"/>
<builder buildPath="${workspace_loc:/RTOSDemo_R5}/Debug" enableAutoBuild="true" id="xilinx.gnu.arm.r5.toolchain.builder.debug.1384283750" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GNU make" superClass="xilinx.gnu.arm.r5.toolchain.builder.debug"/>
<tool id="xilinx.gnu.arm.r5.c.toolchain.assembler.debug.1816601105" name="ARM R5 gcc assembler" superClass="xilinx.gnu.arm.r5.c.toolchain.assembler.debug">
<inputType id="xilinx.gnu.assembler.input.2022098472" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.arm.r5.c.toolchain.compiler.debug.1722107426" name="ARM R5 gcc compiler" superClass="xilinx.gnu.arm.r5.c.toolchain.compiler.debug">
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.457563110" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.828113383" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.1785685421" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../RTOSDemo_R5_bsp/psu_cortexr5_0/include"/>
</option>
<option id="xilinx.gnu.compiler.misc.other.429526610" name="Other flags" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-r5 -mfloat-abi=softfp -mfpu=vfpv3-d16" valueType="string"/>
<option id="xilinx.gnu.compiler.symbols.defined.1843794081" name="Defined symbols (-D)" superClass="xilinx.gnu.compiler.symbols.defined" valueType="definedSymbols">
<listOptionValue builtIn="false" value="ARMR5"/>
</option>
<option id="xilinx.gnu.compiler.dircategory.includes.628747742" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/FreeRTOS_Source/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/Full_Demo/Standard_Demo_Tasks/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/FreeRTOS_Source/portable/GCC/ARM_CR5}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
</option>
<inputType id="xilinx.gnu.arm.r5.c.compiler.input.1749560996" name="C source files" superClass="xilinx.gnu.arm.r5.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.arm.r5.cxx.toolchain.compiler.debug.631567756" name="ARM R5 g++ compiler" superClass="xilinx.gnu.arm.r5.cxx.toolchain.compiler.debug">
<option defaultValue="gnu.c.optimization.level.none" id="xilinx.gnu.compiler.option.optimization.level.1718615883" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.643076825" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.1812105725" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../RTOSDemo_R5_bsp/psu_cortexr5_0/include"/>
</option>
</tool>
<tool id="xilinx.gnu.arm.r5.toolchain.archiver.2042791418" name="ARM R5 archiver" superClass="xilinx.gnu.arm.r5.toolchain.archiver"/>
<tool id="xilinx.gnu.arm.r5.c.toolchain.linker.debug.962112697" name="ARM R5 gcc linker" superClass="xilinx.gnu.arm.r5.c.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.309957105" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../RTOSDemo_R5_bsp/psu_cortexr5_0/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.2103334605" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.696848656" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<inputType id="xilinx.gnu.linker.input.334317886" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.1375931662" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.arm.r5.cxx.toolchain.linker.debug.386806219" name="ARM R5 g++ linker" superClass="xilinx.gnu.arm.r5.cxx.toolchain.linker.debug">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1980480402" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../RTOSDemo_R5_bsp/psu_cortexr5_0/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.425610555" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.715406244" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
</tool>
<tool id="xilinx.gnu.arm.r5.size.debug.302419757" name="ARM R5 Print Size" superClass="xilinx.gnu.arm.r5.size.debug"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="xilinx.gnu.arm.r5.exe.release.294032396">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="xilinx.gnu.arm.r5.exe.release.294032396" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="com.xilinx.sdk.managedbuilder.XELF.arm.r5" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="xilinx.gnu.arm.r5.exe.release.294032396" name="Release" parent="xilinx.gnu.arm.r5.exe.release">
<folderInfo id="xilinx.gnu.arm.r5.exe.release.294032396." name="/" resourcePath="">
<toolChain id="xilinx.gnu.arm.r5.exe.release.toolchain.1807883988" name="Xilinx ARM R5 GNU Toolchain" superClass="xilinx.gnu.arm.r5.exe.release.toolchain">
<targetPlatform binaryParser="com.xilinx.sdk.managedbuilder.XELF.arm.r5" id="xilinx.arm.r5.target.gnu.base.release.1838146222" isAbstract="false" name="Release Platform" superClass="xilinx.arm.r5.target.gnu.base.release"/>
<builder buildPath="${workspace_loc:/RTOSDemo_R5}/Release" enableAutoBuild="true" id="xilinx.gnu.arm.r5.toolchain.builder.release.626017572" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GNU make" superClass="xilinx.gnu.arm.r5.toolchain.builder.release"/>
<tool id="xilinx.gnu.arm.r5.c.toolchain.assembler.release.1444622364" name="ARM R5 gcc assembler" superClass="xilinx.gnu.arm.r5.c.toolchain.assembler.release">
<inputType id="xilinx.gnu.assembler.input.333813616" superClass="xilinx.gnu.assembler.input"/>
</tool>
<tool id="xilinx.gnu.arm.r5.c.toolchain.compiler.release.145867101" name="ARM R5 gcc compiler" superClass="xilinx.gnu.arm.r5.c.toolchain.compiler.release">
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.1799283593" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.1807644221" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.2004323892" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../RTOSDemo_R5_bsp/psu_cortexr5_0/include"/>
</option>
<option id="xilinx.gnu.compiler.misc.other.1802391552" name="Other flags" superClass="xilinx.gnu.compiler.misc.other" value="-c -fmessage-length=0 -MT&quot;$@&quot; -mcpu=cortex-r5" valueType="string"/>
<option id="xilinx.gnu.compiler.symbols.defined.86836251" name="Defined symbols (-D)" superClass="xilinx.gnu.compiler.symbols.defined" valueType="definedSymbols">
<listOptionValue builtIn="false" value="ARMR5"/>
</option>
<inputType id="xilinx.gnu.arm.r5.c.compiler.input.620665990" name="C source files" superClass="xilinx.gnu.arm.r5.c.compiler.input"/>
</tool>
<tool id="xilinx.gnu.arm.r5.cxx.toolchain.compiler.release.1970439978" name="ARM R5 g++ compiler" superClass="xilinx.gnu.arm.r5.cxx.toolchain.compiler.release">
<option defaultValue="gnu.c.optimization.level.more" id="xilinx.gnu.compiler.option.optimization.level.337099439" name="Optimization Level" superClass="xilinx.gnu.compiler.option.optimization.level" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.option.debugging.level.643245109" name="Debug Level" superClass="xilinx.gnu.compiler.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<option id="xilinx.gnu.compiler.inferred.swplatform.includes.1682712538" name="Software Platform Include Path" superClass="xilinx.gnu.compiler.inferred.swplatform.includes" valueType="includePath">
<listOptionValue builtIn="false" value="../../RTOSDemo_R5_bsp/psu_cortexr5_0/include"/>
</option>
</tool>
<tool id="xilinx.gnu.arm.r5.toolchain.archiver.1574303768" name="ARM R5 archiver" superClass="xilinx.gnu.arm.r5.toolchain.archiver"/>
<tool id="xilinx.gnu.arm.r5.c.toolchain.linker.release.78655317" name="ARM R5 gcc linker" superClass="xilinx.gnu.arm.r5.c.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1238734123" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../RTOSDemo_R5_bsp/psu_cortexr5_0/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.1245259618" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.576734697" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
<inputType id="xilinx.gnu.linker.input.1254152405" superClass="xilinx.gnu.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
<inputType id="xilinx.gnu.linker.input.lscript.2106805075" name="Linker Script" superClass="xilinx.gnu.linker.input.lscript"/>
</tool>
<tool id="xilinx.gnu.arm.r5.cxx.toolchain.linker.release.1227052324" name="ARM R5 g++ linker" superClass="xilinx.gnu.arm.r5.cxx.toolchain.linker.release">
<option id="xilinx.gnu.linker.inferred.swplatform.lpath.1961345723" name="Software Platform Library Path" superClass="xilinx.gnu.linker.inferred.swplatform.lpath" valueType="libPaths">
<listOptionValue builtIn="false" value="../../RTOSDemo_R5_bsp/psu_cortexr5_0/lib"/>
</option>
<option id="xilinx.gnu.linker.inferred.swplatform.flags.663213761" name="Software Platform Inferred Flags" superClass="xilinx.gnu.linker.inferred.swplatform.flags" valueType="libs">
<listOptionValue builtIn="false" value="-Wl,--start-group,-lxil,-lgcc,-lc,--end-group"/>
</option>
<option id="xilinx.gnu.c.linker.option.lscript.1628022225" name="Linker Script" superClass="xilinx.gnu.c.linker.option.lscript" value="../src/lscript.ld" valueType="string"/>
</tool>
<tool id="xilinx.gnu.arm.r5.size.release.1587097937" name="ARM R5 Print Size" superClass="xilinx.gnu.arm.r5.size.release"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="RTOSDemo_R5.xilinx.gnu.arm.r5.exe.1685244581" name="Xilinx ARM R5 Executable" projectType="xilinx.gnu.arm.r5.exe"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.r5.exe.debug.1241551157;xilinx.gnu.arm.r5.exe.debug.1241551157.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMR5GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.r5.exe.release.294032396;xilinx.gnu.arm.r5.exe.release.294032396.;xilinx.gnu.arm.r5.c.toolchain.compiler.release.145867101;xilinx.gnu.arm.r5.c.compiler.input.620665990">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMR5GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.r5.exe.release.294032396;xilinx.gnu.arm.r5.exe.release.294032396.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMR5GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="xilinx.gnu.arm.r5.exe.debug.1241551157;xilinx.gnu.arm.r5.exe.debug.1241551157.;xilinx.gnu.arm.r5.c.toolchain.compiler.debug.1722107426;xilinx.gnu.arm.r5.c.compiler.input.1749560996">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.xilinx.managedbuilder.ui.ARMR5GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="refreshScope"/>
</cproject>

View file

@ -0,0 +1,267 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RTOSDemo_R5</name>
<comment>Created by SDK v2016.1. RTOSDemo_R5_bsp - psu_cortexr5_0</comment>
<projects>
<project>RTOSDemo_R5_bsp</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>src/FreeRTOS_Source</name>
<type>2</type>
<locationURI>FREERTOS_ROOT/FreeRTOS/Source</locationURI>
</link>
<link>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>2</type>
<locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal</locationURI>
</link>
<link>
<name>src/Full_Demo/Standard_Demo_Tasks/include</name>
<type>2</type>
<locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/include</locationURI>
</link>
</linkedResources>
<filteredResources>
<filter>
<id>1462455164616</id>
<name>src/FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-event_groups.c</arguments>
</matcher>
</filter>
<filter>
<id>1462455164616</id>
<name>src/FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-list.c</arguments>
</matcher>
</filter>
<filter>
<id>1462455164726</id>
<name>src/FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-queue.c</arguments>
</matcher>
</filter>
<filter>
<id>1462455164766</id>
<name>src/FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-tasks.c</arguments>
</matcher>
</filter>
<filter>
<id>1462455164786</id>
<name>src/FreeRTOS_Source</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-timers.c</arguments>
</matcher>
</filter>
<filter>
<id>1462455201203</id>
<name>src/FreeRTOS_Source/portable</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-MemMang</arguments>
</matcher>
</filter>
<filter>
<id>1462455201293</id>
<name>src/FreeRTOS_Source/portable</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-GCC</arguments>
</matcher>
</filter>
<filter>
<id>1462461825645</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-AbortDelay.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825653</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-blocktim.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825660</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-countsem.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825677</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-dynamic.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825687</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-EventGroupsDemo.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825706</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-flop.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825718</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-GenQTest.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825723</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-IntQueue.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825728</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-IntSemTest.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825733</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-recmutex.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825757</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-semtest.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825757</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-StaticAllocation.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825757</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-TaskNotify.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825767</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-TimerDemo.c</arguments>
</matcher>
</filter>
<filter>
<id>1462461825787</id>
<name>src/Full_Demo/Standard_Demo_Tasks</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-QueueOverwrite.c</arguments>
</matcher>
</filter>
<filter>
<id>1462455232956</id>
<name>src/FreeRTOS_Source/portable/GCC</name>
<type>9</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-ARM_CR5</arguments>
</matcher>
</filter>
<filter>
<id>1462455929868</id>
<name>src/FreeRTOS_Source/portable/MemMang</name>
<type>5</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-heap_4.c</arguments>
</matcher>
</filter>
</filteredResources>
<variableList>
<variable>
<name>FREERTOS_ROOT</name>
<value>$%7BPARENT-4-PROJECT_LOC%7D</value>
</variable>
</variableList>
</projectDescription>

View file

@ -0,0 +1,227 @@
/*
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
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. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/******************************************************************************
* NOTE 1: This project provides two demo applications. A simple blinky
* style project, and a more comprehensive test and demo application. The
* mainSELECTED_APPLICATION setting in main.c is used to select between the
* two. See the notes on using mainSELECTED_APPLICATION in main.c. This file
* implements the simply blinky style version.
*
* NOTE 2: This file only contains the source code that is specific to the
* simple demo. Generic functions, such FreeRTOS hook functions, and functions
* required to configure the hardware are defined in main.c.
******************************************************************************
*
* main_blinky() creates one queue, and two tasks. It then starts the
* scheduler.
*
* The Queue Send Task:
* The queue send task is implemented by the prvQueueSendTask() function in
* this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
* block for 200 milliseconds, before sending the value 100 to the queue that
* was created within main_blinky(). Once the value is sent, the task loops
* back around to block for another 200 milliseconds...and so on.
*
* The Queue Receive Task:
* The queue receive task is implemented by the prvQueueReceiveTask() function
* in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
* blocks on attempts to read data from the queue that was created within
* main_blinky(). When data is received, the task checks the value of the
* data, and if the value equals the expected 100, outputs a message to the
* UART. The 'block time' parameter passed to the queue receive function
* specifies that the task should be held in the Blocked state indefinitely to
* wait for data to be available on the queue. The queue receive task will only
* leave the Blocked state when the queue send task writes to the queue. As the
* queue send task writes to the queue every 200 milliseconds, the queue receive
* task leaves the Blocked state every 200 milliseconds, and therefore outputs
* a message every 200 milliseconds.
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* Xilinx includes. */
#include "xil_printf.h"
/* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 200 )
/* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find
the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
/*-----------------------------------------------------------*/
/* The queue used by both tasks. */
static QueueHandle_t xQueue = NULL;
/*-----------------------------------------------------------*/
void main_blinky( void )
{
/* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
NULL, /* The parameter passed to the task - not used in this case. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */
vTaskStartScheduler();
}
/* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */
for( ;; );
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
{
TickType_t xNextWakeTime;
const uint32_t ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
{
/* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
{
uint32_t ulReceivedValue;
const uint32_t ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
for( ;; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but is
it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == ulExpectedValue )
{
xil_printf( "100 received\r\n" );
ulReceivedValue = 0U;
}
}
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,222 @@
/*
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
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. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "xparameters.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
/*
* The FreeRTOS Cortex-A port implements a full interrupt nesting model.
*
* Interrupts that are assigned a priority at or below
* configMAX_API_CALL_INTERRUPT_PRIORITY (which counter-intuitively in the ARM
* generic interrupt controller [GIC] means a priority that has a numerical
* value above configMAX_API_CALL_INTERRUPT_PRIORITY) can call FreeRTOS safe API
* functions and will nest.
*
* Interrupts that are assigned a priority above
* configMAX_API_CALL_INTERRUPT_PRIORITY (which in the GIC means a numerical
* value below configMAX_API_CALL_INTERRUPT_PRIORITY) cannot call any FreeRTOS
* API functions, will nest, and will not be masked by FreeRTOS critical
* sections (although it is necessary for interrupts to be globally disabled
* extremely briefly as the interrupt mask is updated in the GIC).
*
* FreeRTOS functions that can be called from an interrupt are those that end in
* "FromISR". FreeRTOS maintains a separate interrupt safe API to enable
* interrupt entry to be shorter, faster, simpler and smaller.
*
* For the purpose of setting configMAX_API_CALL_INTERRUPT_PRIORITY 255
* represents the lowest priority.
*/
#define configMAX_API_CALL_INTERRUPT_PRIORITY 18
#define configCPU_CLOCK_HZ 100000000UL
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configUSE_TICKLESS_IDLE 0
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configPERIPHERAL_CLOCK_HZ ( 33333000UL )
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configMAX_PRIORITIES ( 7 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 200 )
#define configTOTAL_HEAP_SIZE ( 50 * 1024 )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
/* This demo creates RTOS objects using both static and dynamic allocation. */
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1 /* Defaults to 1 anyway. */
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 5
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetHandle 1
/* This demo makes use of one or more example stats formatting functions. These
format the raw data provided by the uxTaskGetSystemState() function in to human
readable ASCII form. See the notes in the implementation of vTaskList() within
FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Run time stats are not generated. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS and
portGET_RUN_TIME_COUNTER_VALUE must be defined if configGENERATE_RUN_TIME_STATS
is set to 1. */
#define configGENERATE_RUN_TIME_STATS 0
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
#define portGET_RUN_TIME_COUNTER_VALUE()
/* The size of the global output buffer that is available for use when there
are multiple command interpreters running at once (for example, one on a UART
and one on TCP/IP). This is done to prevent an output buffer being defined by
each implementation - which would waste RAM. In this case, there is only one
command interpreter running. */
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2096
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
void vMainAssertCalled( const char *pcFileName, uint32_t ulLineNumber );
#define configASSERT( x ) if( ( x ) == 0 ) { vMainAssertCalled( __FILE__, __LINE__ ); }
/* If configTASK_RETURN_ADDRESS is not defined then a task that attempts to
return from its implementing function will end up in a "task exit error"
function - which contains a call to configASSERT(). However this can give GCC
some problems when it tries to unwind the stack, as the exit error function has
nothing to return to. To avoid this define configTASK_RETURN_ADDRESS to 0. */
#define configTASK_RETURN_ADDRESS NULL
/****** Hardware specific settings. *******************************************/
/*
* The application must provide a function that configures a peripheral to
* create the FreeRTOS tick interrupt, then define configSETUP_TICK_INTERRUPT()
* in FreeRTOSConfig.h to call the function. This file contains a function
* that is suitable for use on the Zynq MPU. FreeRTOS_Tick_Handler() must
* be installed as the peripheral's interrupt handler.
*/
void vConfigureTickInterrupt( void );
#define configSETUP_TICK_INTERRUPT() vConfigureTickInterrupt()
void vClearTickInterrupt( void );
#define configCLEAR_TICK_INTERRUPT() vClearTickInterrupt()
/* The following constant describe the hardware, and are correct for the
Zynq MPU. */
#define configINTERRUPT_CONTROLLER_BASE_ADDRESS ( XPAR_SCUGIC_0_DIST_BASEADDR )
#define configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ( 0x1000 )
#define configUNIQUE_INTERRUPT_PRIORITIES 32
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,103 @@
/******************************************************************************
*
* Copyright (C) 2014 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file asm_vectors.s
*
* This file contains the initial vector table for the Cortex R5 processor
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------- -------- ---------------------------------------------------
* 5.00 pkp 02/10/14 Initial version
* </pre>
*
* @note
*
* None.
*
******************************************************************************/
.org 0
.text
.globl _boot
.globl _freertos_vector_table
.globl FreeRTOS_FIQInterrupt
.globl FreeRTOS_DataAbortHandler
.globl FreeRTOS_PrefetchAbortHandler
.globl vPortInstallFreeRTOSVectorTable
.globl IRQHandler
.globl prof_pc
.extern FreeRTOS_IRQ_Handler
.extern FreeRTOS_SWI_Handler
.section .freertos_vectors
_freertos_vector_table:
ldr pc,=_boot
ldr pc,=FreeRTOS_Undefined
LDR pc, _swi
ldr pc,=FreeRTOS_PrefetchAbortHandler
ldr pc,=FreeRTOS_DataAbortHandler
NOP /* Placeholder for address exception vector*/
LDR pc, _irq
ldr pc,=FreeRTOS_FIQHandler
_irq: .word FreeRTOS_IRQ_Handler
_swi: .word FreeRTOS_SWI_Handler
.text
FreeRTOS_FIQHandler: /* FIQ vector handler */
stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code */
FreeRTOS_FIQLoop:
bl FIQInterrupt /* FIQ vector */
ldmia sp!,{r0-r3,r12,lr} /* state restore from compiled code */
subs pc, lr, #4 /* adjust return */
FreeRTOS_Undefined: /* Undefined handler */
b FreeRTOS_Undefined
FreeRTOS_DataAbortHandler: /* Data Abort handler */
b FreeRTOS_DataAbortHandler
FreeRTOS_PrefetchAbortHandler: /* Prefetch Abort handler */
b FreeRTOS_PrefetchAbortHandler
.end

View file

@ -0,0 +1,177 @@
/*
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
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. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "Task.h"
/* Xilinx includes. */
#include "xscugic.h"
#include "xttcps.h"
/* Settings to generate the tick from channel 0 of TTC 0. */
#define tickTTC_ID XPAR_PSU_TTC_0_DEVICE_ID
#define tickINTERRUPT_ID XPAR_XTTCPS_0_INTR
/* The timer used to generate the tick interrupt. */
static XTtcPs xTimerInstance;
/*
* The application must provide a function that configures a peripheral to
* create the FreeRTOS tick interrupt, then define configSETUP_TICK_INTERRUPT()
* in FreeRTOSConfig.h to call the function. This file contains a function
* that is suitable for use on the Zynq SoC.
*/
void vConfigureTickInterrupt( void )
{
XTtcPs_Config *pxTimerConfig;
BaseType_t xStatus;
XScuGic_Config *pxGICConfig;
static XScuGic xInterruptController; /* Interrupt controller instance */
uint16_t usInterval;
uint8_t ucPrescale = 0;
const uint8_t ucRisingEdge = 3;
/* This function is called with the IRQ interrupt disabled, and the IRQ
interrupt should be left disabled. It is enabled automatically when the
scheduler is started. */
/* Ensure XScuGic_CfgInitialize() has been called. In this demo it has
already been called from prvSetupHardware() in main(). */
pxGICConfig = XScuGic_LookupConfig( XPAR_SCUGIC_SINGLE_DEVICE_ID );
xStatus = XScuGic_CfgInitialize( &xInterruptController, pxGICConfig, pxGICConfig->CpuBaseAddress );
configASSERT( xStatus == XST_SUCCESS );
( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */
/* The interrupt priority must be the lowest possible. */
XScuGic_SetPriorityTriggerType( &xInterruptController, tickINTERRUPT_ID, portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT, ucRisingEdge );
/* Install the FreeRTOS tick handler. */
xStatus = XScuGic_Connect( &xInterruptController, tickINTERRUPT_ID, (Xil_ExceptionHandler) FreeRTOS_Tick_Handler, NULL );
configASSERT( xStatus == XST_SUCCESS );
( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */
/* Initialise the Triple Timer Counter (TTC) that is going to be used to
generate the tick interrupt. */
pxTimerConfig = XTtcPs_LookupConfig( tickTTC_ID );
xStatus = XTtcPs_CfgInitialize( &xTimerInstance, pxTimerConfig, pxTimerConfig->BaseAddress );
configASSERT( xStatus == XST_SUCCESS );
( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */
/* Configure the interval to be the require tick rate. */
XTtcPs_CalcIntervalFromFreq( &xTimerInstance, configTICK_RATE_HZ, &usInterval, &ucPrescale );
XTtcPs_SetInterval( &xTimerInstance, usInterval );
XTtcPs_SetPrescaler( &xTimerInstance, ucPrescale );
/* Interval mode used. */
XTtcPs_SetOptions( &xTimerInstance, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE );
/* Start the timer. */
XTtcPs_Start( &xTimerInstance );
/* Enable the interrupt in the interrupt controller. */
XScuGic_Enable( &xInterruptController, tickINTERRUPT_ID );
/* Enable the interrupt in the timer itself. */
XTtcPs_EnableInterrupts( &xTimerInstance, XTTCPS_IXR_INTERVAL_MASK );
}
/*-----------------------------------------------------------*/
void vClearTickInterrupt( void )
{
volatile uint32_t ulStatus;
ulStatus = XTtcPs_GetInterruptStatus( &xTimerInstance );
( void ) ulStatus;
}
/*-----------------------------------------------------------*/
void vApplicationIRQHandler( uint32_t ulICCIAR )
{
extern const XScuGic_Config XScuGic_ConfigTable[];
static const XScuGic_VectorTableEntry *pxVectorTable = XScuGic_ConfigTable[ XPAR_SCUGIC_SINGLE_DEVICE_ID ].HandlerTable;
uint32_t ulInterruptID;
const XScuGic_VectorTableEntry *pxVectorEntry;
/* Re-enable interrupts. */
__asm ( "cpsie i" );
/* The ID of the interrupt is obtained by bitwise anding the ICCIAR value
with 0x3FF. */
ulInterruptID = ulICCIAR & 0x3FFUL;
if( ulInterruptID < XSCUGIC_MAX_NUM_INTR_INPUTS )
{
/* Call the function installed in the array of installed handler
functions. */
pxVectorEntry = &( pxVectorTable[ ulInterruptID ] );
pxVectorEntry->Handler( pxVectorEntry->CallBackRef );
}
}

View file

@ -0,0 +1,266 @@
/*
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
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. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/*
* This file initialises three timers as follows:
*
* Timer 0 and Timer 1 provide the interrupts that are used with the IntQ
* standard demo tasks, which test interrupt nesting and using queues from
* interrupts. Both these interrupts operate below the maximum syscall
* interrupt priority.
*
* Timer 2 is a much higher frequency timer that tests the nesting of interrupts
* that execute above the maximum syscall interrupt priority.
*
* All the timers can nest with the tick interrupt - creating a maximum
* interrupt nesting depth of 4.
*
* For convenience, the high frequency timer is also used to provide the time
* base for the run time stats.
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Demo includes. */
#include "IntQueueTimer.h"
#include "IntQueue.h"
/* Xilinx includes. */
#include "xttcps.h"
#include "xscugic.h"
/* The frequencies at which the first two timers expire are slightly offset to
ensure they don't remain synchronised. The frequency of the interrupt that
operates above the max syscall interrupt priority is 10 times faster so really
hammers the interrupt entry and exit code. */
#define tmrTIMERS_USED 3
#define tmrTIMER_0_FREQUENCY ( 2000UL )
#define tmrTIMER_1_FREQUENCY ( 2001UL )
#define tmrTIMER_2_FREQUENCY ( 20000UL )
/*-----------------------------------------------------------*/
/*
* The single interrupt service routines that is used to service all three
* timers.
*/
static void prvTimerHandler( void *CallBackRef );
/*-----------------------------------------------------------*/
/* Hardware constants. */
static const BaseType_t xDeviceIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_2_DEVICE_ID, XPAR_XTTCPS_3_DEVICE_ID, XPAR_XTTCPS_4_DEVICE_ID };
static const BaseType_t xInterruptIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_2_INTR, XPAR_XTTCPS_3_INTR, XPAR_XTTCPS_4_INTR };
/* Timer configuration settings. */
typedef struct
{
uint32_t OutputHz; /* Output frequency. */
uint16_t Interval; /* Interval value. */
uint8_t Prescaler; /* Prescaler value. */
uint16_t Options; /* Option settings. */
} TmrCntrSetup;
static TmrCntrSetup xTimerSettings[ tmrTIMERS_USED ] =
{
{ tmrTIMER_0_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE },
{ tmrTIMER_1_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE },
{ tmrTIMER_2_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE }
};
/* Lower priority number means higher logical priority, so
configMAX_API_CALL_INTERRUPT_PRIORITY - 1 is above the maximum system call
interrupt priority. */
static const UBaseType_t uxInterruptPriorities[ tmrTIMERS_USED ] =
{
configMAX_API_CALL_INTERRUPT_PRIORITY + 1,
configMAX_API_CALL_INTERRUPT_PRIORITY,
configMAX_API_CALL_INTERRUPT_PRIORITY - 1
};
static XTtcPs xTimerInstances[ tmrTIMERS_USED ];
/* Used to provide a means of ensuring the intended interrupt nesting depth is
actually being reached. */
extern uint32_t ulPortInterruptNesting;
static uint32_t ulMaxRecordedNesting = 0;
/* Used to ensure the high frequency timer is running at the expected
frequency. */
static volatile uint32_t ulHighFrequencyTimerCounts = 0;
/*-----------------------------------------------------------*/
void vInitialiseTimerForIntQueueTest( void )
{
BaseType_t xStatus;
TmrCntrSetup *pxTimerSettings;
extern XScuGic xInterruptController;
BaseType_t xTimer;
XTtcPs *pxTimerInstance;
XTtcPs_Config *pxTimerConfiguration;
const uint8_t ucRisingEdge = 3;
for( xTimer = 0; xTimer < tmrTIMERS_USED; xTimer++ )
{
/* Look up the timer's configuration. */
pxTimerInstance = &( xTimerInstances[ xTimer ] );
pxTimerConfiguration = XTtcPs_LookupConfig( xDeviceIDs[ xTimer ] );
configASSERT( pxTimerConfiguration );
pxTimerSettings = &( xTimerSettings[ xTimer ] );
/* Initialise the device. */
xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress );
if( xStatus != XST_SUCCESS )
{
/* Not sure how to do this before XTtcPs_CfgInitialize is called
as pxTimerInstance is set within XTtcPs_CfgInitialize(). */
XTtcPs_Stop( pxTimerInstance );
xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress );
configASSERT( xStatus == XST_SUCCESS );
}
/* Set the options. */
XTtcPs_SetOptions( pxTimerInstance, pxTimerSettings->Options );
/* The timer frequency is preset in the pxTimerSettings structure.
Derive the values for the other structure members. */
XTtcPs_CalcIntervalFromFreq( pxTimerInstance, pxTimerSettings->OutputHz, &( pxTimerSettings->Interval ), &( pxTimerSettings->Prescaler ) );
/* Set the interval and prescale. */
XTtcPs_SetInterval( pxTimerInstance, pxTimerSettings->Interval );
XTtcPs_SetPrescaler( pxTimerInstance, pxTimerSettings->Prescaler );
/* The priority must be the lowest possible. */
XScuGic_SetPriorityTriggerType( &xInterruptController, xInterruptIDs[ xTimer ], uxInterruptPriorities[ xTimer ] << portPRIORITY_SHIFT, ucRisingEdge );
/* Connect to the interrupt controller. */
xStatus = XScuGic_Connect( &xInterruptController, xInterruptIDs[ xTimer ], ( Xil_InterruptHandler ) prvTimerHandler, ( void * ) pxTimerInstance );
configASSERT( xStatus == XST_SUCCESS);
/* Enable the interrupt in the GIC. */
XScuGic_Enable( &xInterruptController, xInterruptIDs[ xTimer ] );
/* Enable the interrupts in the timer. */
XTtcPs_EnableInterrupts( pxTimerInstance, XTTCPS_IXR_INTERVAL_MASK );
/* Start the timer. */
XTtcPs_Start( pxTimerInstance );
}
}
/*-----------------------------------------------------------*/
static void prvTimerHandler( void *pvCallBackRef )
{
uint32_t ulInterruptStatus;
XTtcPs *pxTimer = ( XTtcPs * ) pvCallBackRef;
BaseType_t xYieldRequired;
/* Read the interrupt status, then write it back to clear the interrupt. */
ulInterruptStatus = XTtcPs_GetInterruptStatus( pxTimer );
XTtcPs_ClearInterruptStatus( pxTimer, ulInterruptStatus );
/* Only one interrupt event type is expected. */
configASSERT( ( XTTCPS_IXR_INTERVAL_MASK & ulInterruptStatus ) != 0 );
/* Check the device ID to know which IntQueue demo to call. */
if( pxTimer->Config.DeviceId == xDeviceIDs[ 0 ] )
{
xYieldRequired = xFirstTimerHandler();
}
else if( pxTimer->Config.DeviceId == xDeviceIDs[ 1 ] )
{
xYieldRequired = xSecondTimerHandler();
}
else
{
/* Used to check the timer is running at the expected frequency. */
ulHighFrequencyTimerCounts++;
/* Latch the highest interrupt nesting count detected. */
if( ulPortInterruptNesting > ulMaxRecordedNesting )
{
ulMaxRecordedNesting = ulPortInterruptNesting;
}
xYieldRequired = pdFALSE;
}
/* If xYieldRequired is not pdFALSE then calling either xFirstTimerHandler()
or xSecondTimerHandler() resulted in a task leaving the blocked state and
the task that left the blocked state had a priority higher than the currently
running task (the task this interrupt interrupted) - so a context switch
should be performed so the interrupt returns directly to the higher priority
task. xYieldRequired is tested inside the following macro. */
portYIELD_FROM_ISR( xYieldRequired );
}

View file

@ -67,39 +67,12 @@
1 tab == 4 spaces!
*/
/*-----------------------------------------------------------
* Simple IO routines to control the LEDs.
* This file is called ParTest.c for historic reasons. Originally it stood for
* PARallel port TEST.
*-----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Demo includes. */
#include "partest.h"
/* Don't have any real LEDs yet! */
volatile uint64_t ullLEDToggles = 0;
/*-----------------------------------------------------------*/
void vParTestInitialise( void )
{
}
/*-----------------------------------------------------------*/
void vParTestSetLED( UBaseType_t uxLED, BaseType_t xValue )
{
}
/*-----------------------------------------------------------*/
void vParTestToggleLED( unsigned portBASE_TYPE uxLED )
{
ullLEDToggles++;
}
#ifndef INT_QUEUE_TIMER_H
#define INT_QUEUE_TIMER_H
void vInitialiseTimerForIntQueueTest( void );
portBASE_TYPE xTimer0Handler( void );
portBASE_TYPE xTimer1Handler( void );
#endif

View file

@ -0,0 +1,502 @@
/*
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
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. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/******************************************************************************
* NOTE 1: This project provides two demo applications. A simple blinky
* style project, and a more comprehensive test and demo application. The
* mainSELECTED_APPLICATION setting in main.c is used to select between the two.
* See the notes on using mainSELECTED_APPLICATION in main.c. This file
* implements the comprehensive version.
*
* NOTE 2: This file only contains the source code that is specific to the
* full demo. Generic functions, such FreeRTOS hook functions, and functions
* required to configure the hardware, are defined in main.c.
*
* NOTE 3: The full demo includes a test that checks the floating point context
* is maintained correctly across task switches. The standard GCC libraries can
* use floating point registers and made this test fail (unless the tasks that
* use the library are given a floating point context as described on the
* documentation page for this demo).
*
******************************************************************************
*
* main_full() creates all the demo application tasks and software timers, then
* starts the scheduler. The web documentation provides more details of the
* standard demo application tasks, which provide no particular functionality,
* but do provide a good example of how to use the FreeRTOS API.
*
* In addition to the standard demo tasks, the following tasks and tests are
* defined and/or created within this file:
*
* "Reg test" tasks - These fill both the core and floating point registers with
* known values, then check that each register maintains its expected value for
* the lifetime of the task. Each task uses a different set of values. The reg
* test tasks execute with a very low priority, so get preempted very
* frequently. A register containing an unexpected value is indicative of an
* error in the context switching mechanism.
*
* "Check" task - The check task period is set to five seconds. Each time it
* executes it checks all the standard demo tasks, and the register check tasks,
* are not only still executing, but are executing without reporting any errors,
* then outputs the system status to the UART.
*/
/* Standard includes. */
#include <stdio.h>
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
/* Standard demo application includes. */
#include "flop.h"
#include "semtest.h"
#include "dynamic.h"
#include "blocktim.h"
#include "countsem.h"
#include "GenQTest.h"
#include "recmutex.h"
#include "IntQueue.h"
#include "EventGroupsDemo.h"
#include "TaskNotify.h"
#include "IntSemTest.h"
#include "StaticAllocation.h"
#include "AbortDelay.h"
#include "QueueOverwrite.h"
#include "TimerDemo.h"
/* Xilinx includes. */
#include "xil_printf.h"
/* Priorities for the demo application tasks. */
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + ( UBaseType_t ) 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + ( UBaseType_t ) 2 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + ( UBaseType_t ) 3 )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainUART_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * ( UBaseType_t ) 3 )
#define mainCOM_TEST_TASK_PRIORITY ( tskIDLE_PRIORITY + ( UBaseType_t ) 2 )
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - ( UBaseType_t ) 1 )
#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY )
/* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( ( TickType_t ) 0 )
/* The period of the check task, in ms. */
#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( ( TickType_t ) 5000 )
/* Parameters that are passed into the register check tasks solely for the
purpose of ensuring parameters are passed into tasks correctly. */
#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 )
/* The base period used by the timer test tasks. */
#define mainTIMER_TEST_PERIOD ( 50 )
/*-----------------------------------------------------------*/
/*
* The check task, as described at the top of this file.
*/
static void prvCheckTask( void *pvParameters );
/*
* Register check tasks, and the tasks used to write over and check the contents
* of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file, but the
* entry points are kept in the C file for the convenience of checking the task
* parameter.
*/
static void prvRegTestTaskEntry1( void *pvParameters );
extern void vRegTest1Implementation( void );
static void prvRegTestTaskEntry2( void *pvParameters );
extern void vRegTest2Implementation( void );
/*
* Register commands that can be used with FreeRTOS+CLI. The commands are
* defined in CLI-Commands.c and File-Related-CLI-Command.c respectively.
*/
extern void vRegisterSampleCLICommands( void );
/*
* The task that manages the FreeRTOS+CLI input and output.
*/
extern void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority );
/*
* A high priority task that does nothing other than execute at a pseudo random
* time to ensure the other test tasks don't just execute in a repeating
* pattern.
*/
static void prvPseudoRandomiser( void *pvParameters );
/*
* The full demo uses the tick hook function to include test code in the tick
* interrupt. vFullDemoTickHook() is called by vApplicationTickHook(), which
* is defined in main.c.
*/
void vFullDemoTickHook( void );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check task. If the variables keep incrementing,
then the register check tasks have not discovered any errors. If a variable
stops incrementing, then an error has been found. */
volatile uint32_t ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
void main_full( void )
{
/* Start all the other standard demo/test tasks. They have no particular
functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */
vStartInterruptQueueTasks();
vStartDynamicPriorityTasks();
vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartMathTasks( mainFLOP_TASK_PRIORITY );
vStartEventGroupTasks();
vStartTaskNotifyTask();
vStartInterruptSemaphoreTasks();
vStartStaticallyAllocatedTasks();
vCreateAbortDelayTasks();
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
/* Create the register check tasks, as described at the top of this file */
xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL );
xTaskCreate( prvRegTestTaskEntry2, "Reg2", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
/* Create the task that just adds a little random behaviour. */
xTaskCreate( prvPseudoRandomiser, "Rnd", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
/* Create the task that performs the 'check' functionality, as described at
the top of this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */
for( ;; );
}
/*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters )
{
TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
TickType_t xLastExecutionTime;
static uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
uint32_t ulErrorFound = pdFALSE;
const char *pcStatusString = "Pass";
/* Just to stop compiler warnings. */
( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The system status is written to the UART on each
iteration. */
for( ;; )
{
/* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );
/* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */
if( xAreIntQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 0UL;
pcStatusString = "Error: IntQ";
}
if( xAreMathsTaskStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 1UL;
pcStatusString = "Error: Math";
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 2UL;
pcStatusString = "Error: Dynamic";
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 4UL;
pcStatusString = "Error: Block Time";
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 5UL;
pcStatusString = "Error: Generic Queue";
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 6UL;
pcStatusString = "Error: Recursive Mutex";
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 8UL;
pcStatusString = "Error: Semaphore";
}
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 10UL;
pcStatusString = "Error: Counting Semaphore";
}
if( xAreEventGroupTasksStillRunning() != pdPASS )
{
ulErrorFound |= 1UL << 12UL;
pcStatusString = "Error: Event Group";
}
if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 13UL;
pcStatusString = "Error: Task Notifications";
}
if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 14UL;
pcStatusString = "Error: Interrupt Semaphore";
}
if( xAreStaticAllocationTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 15UL;
pcStatusString = "Error: Static Allocation";
}
if( xAreAbortDelayTestTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 16UL;
pcStatusString = "Error: Abort Delay";
}
if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 17UL;
pcStatusString = "Error: Queue Overwrite";
}
if( xAreTimerDemoTasksStillRunning( xDelayPeriod ) != pdTRUE )
{
ulErrorFound |= 1UL << 18UL;
pcStatusString = "Error: Timer Demo";
}
/* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{
ulErrorFound |= 1UL << 19UL;
pcStatusString = "Error: Reg Test 1";
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound |= 1UL << 20UL;
pcStatusString = "Error: Reg Test 2";
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Output the system status string. */
xil_printf( "%s, status code = %lu, tick count = %lu\r\n", pcStatusString, ulErrorFound, xTaskGetTickCount() );
configASSERT( ulErrorFound == pdFALSE );
}
}
/*-----------------------------------------------------------*/
static void prvRegTestTaskEntry1( void *pvParameters )
{
/* Although the regtest task is written in assembler, its entry point is
written in C for convenience of checking the task parameter is being passed
in correctly. */
if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
{
/* The reg test task also tests the floating point registers. Tasks
that use the floating point unit must call vPortTaskUsesFPU() before
any floating point instructions are executed. */
vPortTaskUsesFPU();
/* Start the part of the test that is written in assembler. */
vRegTest1Implementation();
}
/* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
static void prvRegTestTaskEntry2( void *pvParameters )
{
/* Although the regtest task is written in assembler, its entry point is
written in C for convenience of checking the task parameter is being passed
in correctly. */
if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
{
/* The reg test task also tests the floating point registers. Tasks
that use the floating point unit must call vPortTaskUsesFPU() before
any floating point instructions are executed. */
vPortTaskUsesFPU();
/* Start the part of the test that is written in assembler. */
vRegTest2Implementation();
}
/* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
static void prvPseudoRandomiser( void *pvParameters )
{
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL, ulMinDelay = pdMS_TO_TICKS( 95 );
volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue;
/* This task does nothing other than ensure there is a little bit of
disruption in the scheduling pattern of the other tasks. Normally this is
done by generating interrupts at pseudo random times. */
for( ;; )
{
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
ulValue = ( ulNextRand >> 16UL ) & 0xffUL;
if( ulValue < ulMinDelay )
{
ulValue = ulMinDelay;
}
vTaskDelay( ulValue );
while( ulValue > 0 )
{
__asm volatile( "NOP" );
__asm volatile( "NOP" );
__asm volatile( "NOP" );
__asm volatile( "NOP" );
ulValue--;
}
}
}
/*-----------------------------------------------------------*/
void vFullDemoTickHook( void )
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo();
/* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing();
/* Call the ISR component of the interrupt semaphore test. */
vInterruptSemaphorePeriodicTest();
/* Call the code that 'gives' a task notification from an ISR. */
xNotifyTaskFromISR();
}

View file

@ -0,0 +1,462 @@
/*
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* 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 itcan be
viewed here: http://www.freertos.org/a00114.html and also obtained by
writing to Real Time Engineers Ltd., 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, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new
fully thread aware and reentrant UDP/IP stack.
http://www.OpenRTOS.com - 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.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
*/
.global vRegTest1Implementation
.global vRegTest2Implementation
.extern ulRegTest1LoopCounter
.extern ulRegTest2LoopCounter
.text
.arm
/* This function is explained in the comments at the top of main-full.c. */
.type vRegTest1Implementation, %function
vRegTest1Implementation:
/* Fill each general purpose register with a known value. */
mov r0, #0xFF
mov r1, #0x11
mov r2, #0x22
mov r3, #0x33
mov r4, #0x44
mov r5, #0x55
mov r6, #0x66
mov r7, #0x77
mov r8, #0x88
mov r9, #0x99
mov r10, #0xAA
mov r11, #0xBB
mov r12, #0xCC
mov r14, #0xEE
/* Fill each FPU register with a known value. */
vmov d0, r0, r1
vmov d1, r2, r3
vmov d2, r4, r5
vmov d3, r6, r7
vmov d4, r8, r9
vmov d5, r10, r11
vmov d6, r0, r1
vmov d7, r2, r3
vmov d8, r4, r5
vmov d9, r6, r7
vmov d10, r8, r9
vmov d11, r10, r11
vmov d12, r0, r1
vmov d13, r2, r3
vmov d14, r4, r5
vmov d15, r6, r7
/* Loop, checking each iteration that each register still contains the
expected value. */
reg1_loop:
/* Yield to increase test coverage */
svc 0
/* Check all the VFP registers still contain the values set above.
First save registers that are clobbered by the test. */
push { r0-r1 }
vmov r0, r1, d0
cmp r0, #0xFF
bne reg1_error_loopf
cmp r1, #0x11
bne reg1_error_loopf
vmov r0, r1, d1
cmp r0, #0x22
bne reg1_error_loopf
cmp r1, #0x33
bne reg1_error_loopf
vmov r0, r1, d2
cmp r0, #0x44
bne reg1_error_loopf
cmp r1, #0x55
bne reg1_error_loopf
vmov r0, r1, d3
cmp r0, #0x66
bne reg1_error_loopf
cmp r1, #0x77
bne reg1_error_loopf
vmov r0, r1, d4
cmp r0, #0x88
bne reg1_error_loopf
cmp r1, #0x99
bne reg1_error_loopf
vmov r0, r1, d5
cmp r0, #0xAA
bne reg1_error_loopf
cmp r1, #0xBB
bne reg1_error_loopf
vmov r0, r1, d6
cmp r0, #0xFF
bne reg1_error_loopf
cmp r1, #0x11
bne reg1_error_loopf
vmov r0, r1, d7
cmp r0, #0x22
bne reg1_error_loopf
cmp r1, #0x33
bne reg1_error_loopf
vmov r0, r1, d8
cmp r0, #0x44
bne reg1_error_loopf
cmp r1, #0x55
bne reg1_error_loopf
vmov r0, r1, d9
cmp r0, #0x66
bne reg1_error_loopf
cmp r1, #0x77
bne reg1_error_loopf
vmov r0, r1, d10
cmp r0, #0x88
bne reg1_error_loopf
cmp r1, #0x99
bne reg1_error_loopf
vmov r0, r1, d11
cmp r0, #0xAA
bne reg1_error_loopf
cmp r1, #0xBB
bne reg1_error_loopf
vmov r0, r1, d12
cmp r0, #0xFF
bne reg1_error_loopf
cmp r1, #0x11
bne reg1_error_loopf
vmov r0, r1, d13
cmp r0, #0x22
bne reg1_error_loopf
cmp r1, #0x33
bne reg1_error_loopf
vmov r0, r1, d14
cmp r0, #0x44
bne reg1_error_loopf
cmp r1, #0x55
bne reg1_error_loopf
vmov r0, r1, d15
cmp r0, #0x66
bne reg1_error_loopf
cmp r1, #0x77
bne reg1_error_loopf
/* Restore the registers that were clobbered by the test. */
pop {r0-r1}
/* VFP register test passed. Jump to the core register test. */
b reg1_loopf_pass
reg1_error_loopf:
/* If this line is hit then a VFP register value was found to be
incorrect. */
b reg1_error_loopf
reg1_loopf_pass:
/* Test each general purpose register to check that it still contains the
expected known value, jumping to reg1_error_loop if any register contains
an unexpected value. */
cmp r0, #0xFF
bne reg1_error_loop
cmp r1, #0x11
bne reg1_error_loop
cmp r2, #0x22
bne reg1_error_loop
cmp r3, #0x33
bne reg1_error_loop
cmp r4, #0x44
bne reg1_error_loop
cmp r5, #0x55
bne reg1_error_loop
cmp r6, #0x66
bne reg1_error_loop
cmp r7, #0x77
bne reg1_error_loop
cmp r8, #0x88
bne reg1_error_loop
cmp r9, #0x99
bne reg1_error_loop
cmp r10, #0xAA
bne reg1_error_loop
cmp r11, #0xBB
bne reg1_error_loop
cmp r12, #0xCC
bne reg1_error_loop
cmp r14, #0xEE
bne reg1_error_loop
/* Everything passed, increment the loop counter. */
push { r0-r1 }
ldr r0, =ulRegTest1LoopCounter
ldr r1, [r0]
adds r1, r1, #1
str r1, [r0]
pop { r0-r1 }
/* Start again. */
b reg1_loop
reg1_error_loop:
/* If this line is hit then there was an error in a core register value.
The loop ensures the loop counter stops incrementing. */
b reg1_error_loop
nop
/*-----------------------------------------------------------*/
.type vRegTest2Implementation, %function
vRegTest2Implementation:
/* Put a known value in each register. */
mov r0, #0xFF000000
mov r1, #0x11000000
mov r2, #0x22000000
mov r3, #0x33000000
mov r4, #0x44000000
mov r5, #0x55000000
mov r6, #0x66000000
mov r7, #0x77000000
mov r8, #0x88000000
mov r9, #0x99000000
mov r10, #0xAA000000
mov r11, #0xBB000000
mov r12, #0xCC000000
mov r14, #0xEE000000
/* Likewise the floating point registers */
vmov d0, r0, r1
vmov d1, r2, r3
vmov d2, r4, r5
vmov d3, r6, r7
vmov d4, r8, r9
vmov d5, r10, r11
vmov d6, r0, r1
vmov d7, r2, r3
vmov d8, r4, r5
vmov d9, r6, r7
vmov d10, r8, r9
vmov d11, r10, r11
vmov d12, r0, r1
vmov d13, r2, r3
vmov d14, r4, r5
vmov d15, r6, r7
/* Loop, checking each iteration that each register still contains the
expected value. */
reg2_loop:
/* Check all the VFP registers still contain the values set above.
First save registers that are clobbered by the test. */
push { r0-r1 }
vmov r0, r1, d0
cmp r0, #0xFF000000
bne reg2_error_loopf
cmp r1, #0x11000000
bne reg2_error_loopf
vmov r0, r1, d1
cmp r0, #0x22000000
bne reg2_error_loopf
cmp r1, #0x33000000
bne reg2_error_loopf
vmov r0, r1, d2
cmp r0, #0x44000000
bne reg2_error_loopf
cmp r1, #0x55000000
bne reg2_error_loopf
vmov r0, r1, d3
cmp r0, #0x66000000
bne reg2_error_loopf
cmp r1, #0x77000000
bne reg2_error_loopf
vmov r0, r1, d4
cmp r0, #0x88000000
bne reg2_error_loopf
cmp r1, #0x99000000
bne reg2_error_loopf
vmov r0, r1, d5
cmp r0, #0xAA000000
bne reg2_error_loopf
cmp r1, #0xBB000000
bne reg2_error_loopf
vmov r0, r1, d6
cmp r0, #0xFF000000
bne reg2_error_loopf
cmp r1, #0x11000000
bne reg2_error_loopf
vmov r0, r1, d7
cmp r0, #0x22000000
bne reg2_error_loopf
cmp r1, #0x33000000
bne reg2_error_loopf
vmov r0, r1, d8
cmp r0, #0x44000000
bne reg2_error_loopf
cmp r1, #0x55000000
bne reg2_error_loopf
vmov r0, r1, d9
cmp r0, #0x66000000
bne reg2_error_loopf
cmp r1, #0x77000000
bne reg2_error_loopf
vmov r0, r1, d10
cmp r0, #0x88000000
bne reg2_error_loopf
cmp r1, #0x99000000
bne reg2_error_loopf
vmov r0, r1, d11
cmp r0, #0xAA000000
bne reg2_error_loopf
cmp r1, #0xBB000000
bne reg2_error_loopf
vmov r0, r1, d12
cmp r0, #0xFF000000
bne reg2_error_loopf
cmp r1, #0x11000000
bne reg2_error_loopf
vmov r0, r1, d13
cmp r0, #0x22000000
bne reg2_error_loopf
cmp r1, #0x33000000
bne reg2_error_loopf
vmov r0, r1, d14
cmp r0, #0x44000000
bne reg2_error_loopf
cmp r1, #0x55000000
bne reg2_error_loopf
vmov r0, r1, d15
cmp r0, #0x66000000
bne reg2_error_loopf
cmp r1, #0x77000000
bne reg2_error_loopf
/* Restore the registers that were clobbered by the test. */
pop {r0-r1}
/* VFP register test passed. Jump to the core register test. */
b reg2_loopf_pass
reg2_error_loopf:
/* If this line is hit then a VFP register value was found to be
incorrect. */
b reg2_error_loopf
reg2_loopf_pass:
cmp r0, #0xFF000000
bne reg2_error_loop
cmp r1, #0x11000000
bne reg2_error_loop
cmp r2, #0x22000000
bne reg2_error_loop
cmp r3, #0x33000000
bne reg2_error_loop
cmp r4, #0x44000000
bne reg2_error_loop
cmp r5, #0x55000000
bne reg2_error_loop
cmp r6, #0x66000000
bne reg2_error_loop
cmp r7, #0x77000000
bne reg2_error_loop
cmp r8, #0x88000000
bne reg2_error_loop
cmp r9, #0x99000000
bne reg2_error_loop
cmp r10, #0xAA000000
bne reg2_error_loop
cmp r11, #0xBB000000
bne reg2_error_loop
cmp r12, #0xCC000000
bne reg2_error_loop
cmp r14, #0xEE000000
bne reg2_error_loop
/* Everything passed, increment the loop counter. */
push { r0-r1 }
ldr r0, =ulRegTest2LoopCounter
ldr r1, [r0]
adds r1, r1, #1
str r1, [r0]
pop { r0-r1 }
/* Start again. */
b reg2_loop
reg2_error_loop:
/* If this line is hit then there was an error in a core register value.
The loop ensures the loop counter stops incrementing. */
b reg2_error_loop
nop
.end

View file

@ -0,0 +1,310 @@
/*******************************************************************/
/* */
/* This file is automatically generated by linker script generator.*/
/* */
/* Version: */
/* */
/* Copyright (c) 2010 Xilinx, Inc. All rights reserved. */
/* */
/* Description : ARM-v7 Linker Script */
/* */
/*******************************************************************/
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x2000;
_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024;
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
/* Define Memories in the system */
MEMORY
{
psu_bbram_0_S_AXI_BASEADDR : ORIGIN = 0xFFCD0000, LENGTH = 0x10000
psu_ocm_S_AXI_BASEADDR : ORIGIN = 0xFF960000, LENGTH = 0x10000
psu_ocm_ram_0_S_AXI_BASEADDR : ORIGIN = 0xFFFC0000, LENGTH = 0x30000
psu_ocm_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0x10000
psu_pmu_ram_S_AXI_BASEADDR : ORIGIN = 0xFFDC0000, LENGTH = 0x20000
psu_qspi_linear_0_S_AXI_BASEADDR : ORIGIN = 0xC0000000, LENGTH = 0x20000000
psu_r5_0_atcm_S_AXI_BASEADDR : ORIGIN = 0xFFE00000, LENGTH = 0x10000
psu_r5_0_atcm_lockstep_S_AXI_BASEADDR : ORIGIN = 0xFFE10000, LENGTH = 0x10000
psu_r5_0_btcm_S_AXI_BASEADDR : ORIGIN = 0xFFE20000, LENGTH = 0x10000
psu_r5_0_btcm_lockstep_S_AXI_BASEADDR : ORIGIN = 0xFFE30000, LENGTH = 0x10000
psu_r5_1_atcm_S_AXI_BASEADDR : ORIGIN = 0xFFE90000, LENGTH = 0x10000
psu_r5_1_btcm_S_AXI_BASEADDR : ORIGIN = 0xFFEB0000, LENGTH = 0x10000
psu_r5_ddr_0_S_AXI_BASEADDR : ORIGIN = 0x100000, LENGTH = 0x7FF00000
psu_r5_tcm_ram_0_S_AXI_BASEADDR : ORIGIN = 0x100, LENGTH = 0x1FF01
}
/* Specify the default entry point to the program */
ENTRY(_boot)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
.vectors 0x0 : {
KEEP (*(.freertos_vectors))
KEEP (*(.vectors))
}
.text : {
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > psu_r5_ddr_0_S_AXI_BASEADDR
.init : {
KEEP (*(.init))
} > psu_r5_ddr_0_S_AXI_BASEADDR
.fini : {
KEEP (*(.fini))
} > psu_r5_ddr_0_S_AXI_BASEADDR
.interp : {
KEEP (*(.interp))
} > psu_r5_ddr_0_S_AXI_BASEADDR
.note-ABI-tag : {
KEEP (*(.note-ABI-tag))
} > psu_r5_ddr_0_S_AXI_BASEADDR
.rodata : {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.rodata1 : {
__rodata1_start = .;
*(.rodata1)
*(.rodata1.*)
__rodata1_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.sdata2 : {
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
__sdata2_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.sbss2 : {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.data : {
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.jcr)
*(.got)
*(.got.plt)
__data_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.data1 : {
__data1_start = .;
*(.data1)
*(.data1.*)
__data1_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.got : {
*(.got)
} > psu_r5_ddr_0_S_AXI_BASEADDR
.ctors : {
__CTOR_LIST__ = .;
___CTORS_LIST___ = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
___CTORS_END___ = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.dtors : {
__DTOR_LIST__ = .;
___DTORS_LIST___ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
___DTORS_END___ = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.fixup : {
__fixup_start = .;
*(.fixup)
__fixup_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.eh_frame : {
*(.eh_frame)
} > psu_r5_ddr_0_S_AXI_BASEADDR
.eh_framehdr : {
__eh_framehdr_start = .;
*(.eh_framehdr)
__eh_framehdr_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.gcc_except_table : {
*(.gcc_except_table)
} > psu_r5_ddr_0_S_AXI_BASEADDR
.mmu_tbl (ALIGN(16384)) : {
__mmu_tbl_start = .;
*(.mmu_tbl)
__mmu_tbl_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidix.*.*)
__exidx_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.preinit_array : {
__preinit_array_start = .;
KEEP (*(SORT(.preinit_array.*)))
KEEP (*(.preinit_array))
__preinit_array_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.init_array : {
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.fini_array : {
__fini_array_start = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.ARM.attributes : {
__ARM.attributes_start = .;
*(.ARM.attributes)
__ARM.attributes_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.sdata : {
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.sbss (NOLOAD) : {
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
__sbss_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.tdata : {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.tbss : {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.bss (NOLOAD) : {
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
/* Generate Stack and Heap definitions */
.heap (NOLOAD) : {
. = ALIGN(16);
_heap = .;
HeapBase = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
HeapLimit = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
.stack (NOLOAD) : {
. = ALIGN(16);
_stack_end = .;
. += _STACK_SIZE;
_stack = .;
__stack = _stack;
. = ALIGN(16);
_irq_stack_end = .;
. += _IRQ_STACK_SIZE;
__irq_stack = .;
_supervisor_stack_end = .;
. += _SUPERVISOR_STACK_SIZE;
. = ALIGN(16);
__supervisor_stack = .;
_abort_stack_end = .;
. += _ABORT_STACK_SIZE;
. = ALIGN(16);
__abort_stack = .;
_fiq_stack_end = .;
. += _FIQ_STACK_SIZE;
. = ALIGN(16);
__fiq_stack = .;
_undef_stack_end = .;
. += _UNDEF_STACK_SIZE;
. = ALIGN(16);
__undef_stack = .;
} > psu_r5_ddr_0_S_AXI_BASEADDR
_end = .;
}

View file

@ -0,0 +1,314 @@
/*
FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
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. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/******************************************************************************
* NOTE 1: This project provides two demo applications. A simple blinky
* style project, and a more comprehensive test and demo application. The
* mainSELECTED_APPLICATION setting in main.c is used to select between the two.
* See the notes on using mainSELECTED_APPLICATION where it is defined below.
*
* NOTE 2: This file only contains the source code that is not specific to
* either the simply blinky or full demos - this includes initialisation code
* and callback functions.
*/
/* Standard includes. */
#include <stdio.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
/* Xilinx includes. */
#include "platform.h"
#include "xparameters.h"
#include "xscugic.h"
#include "xil_printf.h"
/* mainSELECTED_APPLICATION is used to select between two demo applications,
* as described at the top of this file.
*
* When mainSELECTED_APPLICATION is set to 0 the simple blinky example will
* be run.
*
* When mainSELECTED_APPLICATION is set to 1 the comprehensive test and demo
* application will be run.
*/
#define mainSELECTED_APPLICATION 0
/*-----------------------------------------------------------*/
/*
* Configure the hardware as necessary to run this demo.
*/
static void prvSetupHardware( void );
/*
* See the comments at the top of this file and above the
* mainSELECTED_APPLICATION definition.
*/
#if ( mainSELECTED_APPLICATION == 0 )
extern void main_blinky( void );
#elif ( mainSELECTED_APPLICATION == 1 )
extern void main_full( void );
#else
#error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition.
#endif
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
/* The interrupt controller is initialised in this file, and made available to
other modules. */
XScuGic xInterruptController;
/*-----------------------------------------------------------*/
int main( void )
{
/* Configure the hardware ready to run the demo. */
prvSetupHardware();
/* The mainSELECTED_APPLICATION setting is described at the top
of this file. */
#if( mainSELECTED_APPLICATION == 0 )
{
main_blinky();
}
#elif( mainSELECTED_APPLICATION == 1 )
{
main_full();
}
#endif
/* Don't expect to reach here. */
return 0;
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
BaseType_t xStatus;
XScuGic_Config *pxGICConfig;
/* Ensure no interrupts execute while the scheduler is in an inconsistent
state. Interrupts are automatically enabled when the scheduler is
started. */
portDISABLE_INTERRUPTS();
init_platform();
/* Obtain the configuration of the GIC. */
pxGICConfig = XScuGic_LookupConfig( XPAR_SCUGIC_SINGLE_DEVICE_ID );
/* Sanity check the FreeRTOSConfig.h settings are correct for the
hardware. */
configASSERT( pxGICConfig );
configASSERT( pxGICConfig->CpuBaseAddress == ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) );
configASSERT( pxGICConfig->DistBaseAddress == configINTERRUPT_CONTROLLER_BASE_ADDRESS );
/* Install a default handler for each GIC interrupt. */
xStatus = XScuGic_CfgInitialize( &xInterruptController, pxGICConfig, pxGICConfig->CpuBaseAddress );
configASSERT( xStatus == XST_SUCCESS );
( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */
/* Ensure the FPU is accessible by enabling access to CP 10 and 11. */
__asm volatile( "MRC p15, 0, r0, c1, c0, 2 \n" \
"ORR r0, r0, #(0xF << 20) \n" \
"MCR p15, 0, r0, c1, c0, 2 \n" \
"ISB " );
/* Ensure the FPU is enabled. */
__asm volatile( "VMRS r0, FPEXC \n" \
"ORR r1, r0, #(1<<30) \n" \
"VMSR FPEXC, r1 \n" \
::: "r0", "r1" );
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace;
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
#if( mainSELECTED_APPLICATION == 1 )
{
/* Only the comprehensive demo actually uses the tick hook. */
extern void vFullDemoTickHook( void );
vFullDemoTickHook();
}
#endif
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
{
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
/*-----------------------------------------------------------*/
void vMainAssertCalled( const char *pcFileName, uint32_t ulLineNumber )
{
xil_printf( "ASSERT! Line %lu of file %s\r\n", ulLineNumber, pcFileName );
taskENTER_CRITICAL();
for( ;; );
}

View file

@ -0,0 +1,105 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#include "xparameters.h"
#include "xil_cache.h"
#include "platform_config.h"
/*
* Uncomment one of the following two lines, depending on the target,
* if ps7/psu init source files are added in the source directory for
* compiling example outside of SDK.
*/
/*#include "ps7_init.h"*/
/*#include "psu_init.h"*/
#ifdef STDOUT_IS_16550
#include "xuartns550_l.h"
#define UART_BAUD 9600
#endif
void
enable_caches()
{
#ifdef __PPC__
Xil_ICacheEnableRegion(CACHEABLE_REGION_MASK);
Xil_DCacheEnableRegion(CACHEABLE_REGION_MASK);
#elif __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_ICACHE
Xil_ICacheEnable();
#endif
#ifdef XPAR_MICROBLAZE_USE_DCACHE
Xil_DCacheEnable();
#endif
#endif
}
void
disable_caches()
{
Xil_DCacheDisable();
Xil_ICacheDisable();
}
void
init_uart()
{
#ifdef STDOUT_IS_16550
XUartNs550_SetBaud(STDOUT_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, UART_BAUD);
XUartNs550_SetLineControlReg(STDOUT_BASEADDR, XUN_LCR_8_DATA_BITS);
#endif
/* Bootrom/BSP configures PS7/PSU UART to 115200 bps */
}
void
init_platform()
{
/*
* If you want to run this example outside of SDK,
* uncomment one of the following two lines and also #include "ps7_init.h"
* or #include "ps7_init.h" at the top, depending on the target.
* Make sure that the ps7/psu_init.c and ps7/psu_init.h files are included
* along with this example source files for compilation.
*/
/* ps7_init();*/
/* psu_init();*/
enable_caches();
init_uart();
}
void
cleanup_platform()
{
disable_caches();
}

View file

@ -0,0 +1,41 @@
/******************************************************************************
*
* Copyright (C) 2008 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#ifndef __PLATFORM_H_
#define __PLATFORM_H_
#include "platform_config.h"
void init_platform();
void cleanup_platform();
#endif

View file

@ -0,0 +1,6 @@
#ifndef __PLATFORM_CONFIG_H_
#define __PLATFORM_CONFIG_H_
#define STDOUT_IS_PSU_UART
#define UART_DEVICE_ID 0
#endif

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="org.eclipse.cdt.core.default.config.750804140">
<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="org.eclipse.cdt.core.default.config.750804140" moduleId="org.eclipse.cdt.core.settings" name="Configuration">
<externalSettings/>
<extensions/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RTOSDemo_R5_bsp</name>
<comment>Created by SDK v2016.1</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.make.core.makeBuilder</name>
<arguments>
<dictionary>
<key>org.eclipse.cdt.core.errorOutputParser</key>
<value>org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.MakeErrorParser;</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.arguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.command</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.target.auto</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.target.clean</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.build.target.inc</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.environment</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.xilinx.sdk.sw.SwProjectNature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.make.core.makeNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,4 @@
THIRPARTY=false
HW_PROJECT_REFERENCE=ZynqMP_ZCU102_hw_platform
PROCESSOR=psu_cortexr5_0
MSS_FILE=system.mss

View file

@ -0,0 +1,31 @@
# Makefile generated by Xilinx.
PROCESSOR = psu_cortexr5_0
LIBRARIES = ${PROCESSOR}/lib/libxil.a
BSP_MAKEFILES := $(wildcard $(PROCESSOR)/libsrc/*/src/Makefile)
SUBDIRS := $(patsubst %/Makefile, %, $(BSP_MAKEFILES))
ifneq (,$(findstring win,$(RDI_PLATFORM)))
SHELL = CMD
endif
all: libs
@echo 'Finished building libraries'
include: $(addsuffix /make.include,$(SUBDIRS))
libs: $(addsuffix /make.libs,$(SUBDIRS))
$(PROCESSOR)/lib/libxil.a: $(PROCESSOR)/lib/libxil_init.a
cp -f $< $@
%/make.include: $(if $(wildcard $(PROCESSOR)/lib/libxil_init.a),$(PROCESSOR)/lib/libxil.a,)
@echo "Running Make include in $(subst /make.include,,$@)"
$(MAKE) -C $(subst /make.include,,$@) -s include "SHELL=$(SHELL)" "COMPILER=armr5-none-eabi-gcc" "ARCHIVER=armr5-none-eabi-ar" "COMPILER_FLAGS= -O2 -c -mcpu=cortex-r5" "EXTRA_COMPILER_FLAGS=-g -DARMR5 -mfpu=vfpv3-d16"
%/make.libs: include
@echo "Running Make libs in $(subst /make.libs,,$@)"
$(MAKE) -C $(subst /make.libs,,$@) -s libs "SHELL=$(SHELL)" "COMPILER=armr5-none-eabi-gcc" "ARCHIVER=armr5-none-eabi-ar" "COMPILER_FLAGS= -O2 -c -mcpu=cortex-r5" "EXTRA_COMPILER_FLAGS=-g -DARMR5 -mfpu=vfpv3-d16"
clean:
rm -f ${PROCESSOR}/lib/libxil.a

View file

@ -0,0 +1,27 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
INCLUDEFILES=*.h
LIBSOURCES=*.c
OUTS = *.o
libs:
echo "Compiling axipmon"
$(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES)
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS}
make clean
include:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OUTS}

View file

@ -0,0 +1,938 @@
/******************************************************************************
*
* Copyright (C) 2007 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xaxipmon.h
* @addtogroup axipmon_v6_3
* @{
* @details
*
* The XAxiPmon driver supports the Xilinx AXI Performance Monitor device.
*
* The AXI Performance Monitor device provides following features:
*
* Configurable number of Metric Counters and Incrementers
* Computes performance metrics for Agents connected to
* monitor slots (Up to 8 slots)
*
* The following Metrics can be computed:
*
* Metrics computed for an AXI4 MM agent:
* Write Request Count: Total number of write requests by/to the agent.
* Read Request Count: Total number of read requests given by/to the
* agent.
* Read Latency: It is defined as the time from the start of read address
* transaction to the beginning of the read data service.
* Write Latency: It is defined as the period needed a master completes
* write data transaction, i.e. from write address
* transaction to write response from slave.
* Write Byte Count: Total number of bytes written by/to the agent.
* This metric is helpful when calculating the
* throughput of the system.
* Read Byte Count: Total number of bytes read from/by the agent.
* Average Write Latency: Average write latency seen by the agent.
* It can be derived from total write latency
* and the write request count.
* Average Read Latency: Average read latency seen by the agent. It can be
* derived from total read latency and the read
* request count.
* Master Write Idle Cycle Count: Number of idle cycles caused by the
* masters during write transactions to
* the slave.
* Slave Write Idle Cycle Count: Number of idle cycles caused by this slave
* during write transactions to the slave.
* Master Read Idle Cycle Count: Number of idle cycles caused by the
* master during read transactions to the
* slave.
* Slave Read Idle Cycle Count: Number of idle cycles caused by this slave
* during read transactions to the slave.
*
* Metrics computed for an AXI4-Stream agent:
*
* Transfer Cycle Count: Total number of writes by/to the agent.
* Data Byte Count: Total number of data bytes written by/to the agent.
* This metric helps in calculating the throughput
* of the system.
* Position Byte Count: Total number of position bytes transferred.
* Null Byte Count: Total number of null bytes transferred.
* Packet Count: Total number of packets transferred.
*
* There are three modes : Advanced, Profile and Trace.
* - Advanced mode has 10 Mertic Counters, Sampled Metric Counters, Incrementors
* and Sampled Incrementors.
* - Profile mode has only 47 Metric Counters and Sampled Metric Counters.
* - Trace mode has no Counters.
* User should refer to the hardware device specification for detailed
* information about the device.
*
* This header file contains the prototypes of driver functions that can
* be used to access the AXI Performance Monitor device.
*
*
* <b> Initialization and Configuration </b>
*
* The device driver enables higher layer software (e.g., an application) to
* communicate to the AXI Performance Monitor device.
*
* XAxiPmon_CfgInitialize() API is used to initialize the AXI Performance Monitor
* device. The user needs to first call the XAxiPmon_LookupConfig() API which
* returns the Configuration structure pointer which is passed as a parameter to
* the XAxiPmon_CfgInitialize() API.
*
*
* <b>Interrupts</b>
*
* The AXI Performance Monitor does not support Interrupts
*
*
* <b> Virtual Memory </b>
*
* This driver supports Virtual Memory. The RTOS is responsible for calculating
* the correct device base address in Virtual Memory space.
*
*
* <b> Threads </b>
*
* This driver is not thread safe. Any needs for threads or thread mutual
* exclusion must be satisfied by the layer above this driver.
*
* <b> Asserts </b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on argument
* values. Asserts can be turned off on a system-wide basis by defining, at
* compile time, the NDEBUG identifier. By default, asserts are turned on and it
* is recommended that users leave asserts on during development.
*
*
* <b> Building the driver </b>
*
* The XAxiPmon driver is composed of several source files. This allows the user
* to build and link only those parts of the driver that are necessary.
*
* <b> Limitations of the driver </b>
*
*
* <br><br>
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------------
* 1.00a bss 02/27/12 First release
* 2.00a bss 06/23/12 Updated to support v2_00a version of IP.
* 3.00a bss 09/03/12 To support v2_01_a version of IP:
* Deleted XAxiPmon_SetAgent, XAxiPmon_GetAgent APIs and
* added XAPM_FLAG_EVENT, XAPM_FLAG_EVNTSTAR,
* XAPM_FLAG_EVNTSTOP.
* Deleted XAxiPmon_SetAgent, XAxiPmon_GetAgent APIs and
* modified XAxiPmon_SetMetrics, XAxiPmon_GetMetrics APIs
* in xaxipmon.c
* Deleted XAPM_AGENT_OFFSET Macro in xaxipmon_hw.h
* 3.01a bss 10/25/12 To support new version of IP:
* Added XAPM_MCXLOGEN_OFFSET macros in xaxipmon_hw.h.
* Added XAxiPmon_SetMetricCounterCutOff,
* XAxiPmon_GetMetricCounterCutOff,
* XAxiPmon_EnableExternalTrigger and
* XAxiPmon_DisableExternalTrigger APIs in xaxipmon.c
* Modified XAxiPmon_SetMetrics and XAxiPmon_GetMetrics
* (CR #683746) in xaxipmon.c
* Added XAxiPmon_EnableEventLog,
* XAxiPmon_DisableMetricsCounter,
* XAxiPmon_EnableMetricsCounter APIs in xaxipmon.c to
* replace macros in this file.
* Added XAPM_FLAG_XXX macros.
* Added XAxiPmon_StartCounters and XAxiPmon_StopCounters
* APIs (CR #683799).
* Added XAxiPmon_StartEventLog and XAxiPmon_StopEventLog
* APIs (CR #683801).
* Added XAxiPmon_GetMetricName API (CR #683803).
* Deleted XAxiPmon_SetAgent, XAxiPmon_GetAgent
* declarations (CR #677337)
* 4.00a bss 01/17/13 To support new version of IP:
* Added XAPM_METRIC_SET_12 to XAPM_METRIC_SET_15 macros.
* Added XAxiPmon_SetLogEnableRanges,
* XAxiPmon_GetLogEnableRanges,
* XAxiPmon_EnableMetricCounterTrigger,
* XAxiPmon_DisableMetricCounterTrigger,
* XAxiPmon_EnableEventLogTrigger,
* XAxiPmon_DisableEventLogTrigger,
* XAxiPmon_SetWriteLatencyId,
* XAxiPmon_SetReadLatencyId,
* XAxiPmon_GetWriteLatencyId,
* XAxiPmon_GetReadLatencyId APIs and removed
* XAxiPmon_SetMetricCounterCutOff,
* XAxiPmon_GetMetricCounterCutOff,
* XAxiPmon_EnableExternalTrigger and
* XAxiPmon_DisableExternalTrigger APIs in xaxipmon.c
* Added XAPM_LATENCYID_OFFSET,
* XAPM_CR_EVTLOG_EXTTRIGGER_MASK,
* XAPM_LATENCYID_RID_MASK and XAPM_LATENCYID_WID_MASK in
* xaxipmon_hw.h
* 5.00a bss 08/26/13 To support new version of IP:
* XAxiPmon_SampleMetrics Macro.
* Modified XAxiPmon_CfgInitialize, Assert functions
* Added XAxiPmon_GetMetricCounter,
* XAxiPmon_SetSampleInterval, XAxiPmon_GetSampleInterval,
* XAxiPmon_SetWrLatencyStart, XAxiPmon_SetWrLatencyEnd,
* XAxiPmon_SetRdLatencyStart, XAxiPmon_SetRdLatencyEnd,
* XAxiPmon_GetWrLatencyStart, XAxiPmon_GetWrLatencyEnd,
* XAxiPmon_GetRdLatencyStart, XAxiPmon_GetRdLatencyEnd,
* XAxiPmon_SetWriteIdMask, XAxiPmon_SetReadIdMask,
* XAxiPmon_GetWriteIdMask and XAxiPmon_GetReadIdMask APIs
* Renamed :
* XAxiPmon_SetWriteLatencyId to
* XAxiPmon_SetWriteId, XAxiPmon_SetReadLatencyId to
* XAxiPmon_SetReadId, XAxiPmon_GetWriteLatencyId to
* XAxiPmon_GetWriteId and XAxiPmon_SetReadLatencyId to
* XAxiPmon_GetReadId. in xaxipmon.c
* Added Macros XAPM_MC10_OFFSET to XAPM_MC47_OFFSET,
* XAPM_SMC10_OFFSET to XAPM_SMC47_OFFSET,
* XAPM_IDMASK_OFFSET, XAPM_CR_IDFILTER_ENABLE_MASK,
* XAPM_CR_WRLATENCY_START_MASK,
* XAPM_CR_WRLATENCY_END_MASK,
* XAPM_CR_RDLATENCY_START_MASK,
* XAPM_CR_RDLATENCY_END_MASK and
* XAPM_MAX_COUNTERS_PROFILE.
* Renamed:
* XAPM_LATENCYID_OFFSET to XAPM_ID_OFFSET,
* XAPM_LATENCYID_RID_MASK to XAPM_ID_RID_MASK,
* XAPM_LATENCYID_WID_MASK to XAPM_ID_WID_MASK.
* in xaxipmon_hw.h.
* Modified driver tcl to generate new parameters
* ScaleFactor, ModeProfile, ModeTrace and ModeAdvanced
* in Config structure.
* 6.0 adk 19/12/13 Updated as per the New Tcl API's
* 6.1 adk 16/04/14 Updated the driver tcl for the newly added parameters in
* The Axi pmon IP.
* 6.2 bss 04/21/14 Updated XAxiPmon_CfgInitialize in xaxipmon.c to Reset
* counters and FIFOs based on Modes(CR#782671). And if
* both profile and trace modes are present set mode as
* Advanced.
* 6.2 bss 03/02/15 To support Zynq MP APM:
* Added Is32BitFiltering in XAxiPmon_Config structure.
* Updated XAxiPmon_SetWriteId, XAxiPmon_SetReadId,
* XAxiPmon_GetWriteId, XAxiPmon_GetReadId
* XAxiPmon_SetWriteIdMask, XAxiPmon_SetReadIdMask
* XAxiPmon_GetWriteIdMask, XAxiPmon_GetReadIdMask
* functions in xaxipmon.c.
* Added XAPM_RID_OFFSET and XAPM_RIDMASK_OFFSET in
* xaxipmon_hw.h
*
* 6.3 kvn 07/02/15 Modified code according to MISRA-C:2012 guidelines.
* 6.4 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
* Changed the prototype of XAxiPmon_CfgInitialize API.
* </pre>
*
*****************************************************************************/
#ifndef XAXIPMON_H /* Prevent circular inclusions */
#define XAXIPMON_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xaxipmon_hw.h"
/************************** Constant Definitions ****************************/
/**
* @name Macro for Maximum number of Counters
*
* @{
*/
#define XAPM_MAX_COUNTERS 10U /**< Maximum number of Counters */
#define XAPM_MAX_COUNTERS_PROFILE 48U /**< Maximum number of Counters */
/*@}*/
/**
* @name Indices for Metric Counters and Sampled Metric Coounters used with
* XAxiPmon_GetMetricCounter and XAxiPmon_GetSampledMetricCounter APIs
* @{
*/
#define XAPM_METRIC_COUNTER_0 0U /**< Metric Counter 0 Register Index */
#define XAPM_METRIC_COUNTER_1 1U /**< Metric Counter 1 Register Index */
#define XAPM_METRIC_COUNTER_2 2U /**< Metric Counter 2 Register Index */
#define XAPM_METRIC_COUNTER_3 3U /**< Metric Counter 3 Register Index */
#define XAPM_METRIC_COUNTER_4 4U /**< Metric Counter 4 Register Index */
#define XAPM_METRIC_COUNTER_5 5U /**< Metric Counter 5 Register Index */
#define XAPM_METRIC_COUNTER_6 6U /**< Metric Counter 6 Register Index */
#define XAPM_METRIC_COUNTER_7 7U /**< Metric Counter 7 Register Index */
#define XAPM_METRIC_COUNTER_8 8U /**< Metric Counter 8 Register Index */
#define XAPM_METRIC_COUNTER_9 9U /**< Metric Counter 9 Register Index */
/*@}*/
/**
* @name Indices for Incrementers and Sampled Incrementers used with
* XAxiPmon_GetIncrementer and XAxiPmon_GetSampledIncrementer APIs
* @{
*/
#define XAPM_INCREMENTER_0 0U /**< Metric Counter 0 Register Index */
#define XAPM_INCREMENTER_1 1U /**< Metric Counter 0 Register Index */
#define XAPM_INCREMENTER_2 2U /**< Metric Counter 0 Register Index */
#define XAPM_INCREMENTER_3 3U /**< Metric Counter 0 Register Index */
#define XAPM_INCREMENTER_4 4U /**< Metric Counter 0 Register Index */
#define XAPM_INCREMENTER_5 5U /**< Metric Counter 0 Register Index */
#define XAPM_INCREMENTER_6 6U /**< Metric Counter 0 Register Index */
#define XAPM_INCREMENTER_7 7U /**< Metric Counter 0 Register Index */
#define XAPM_INCREMENTER_8 8U /**< Metric Counter 0 Register Index */
#define XAPM_INCREMENTER_9 9U /**< Metric Counter 0 Register Index */
/*@}*/
/**
* @name Macros for Metric Selector Settings
* @{
*/
#define XAPM_METRIC_SET_0 0U /**< Write Transaction Count */
#define XAPM_METRIC_SET_1 1U /**< Read Transaction Count */
#define XAPM_METRIC_SET_2 2U /**< Write Byte Count */
#define XAPM_METRIC_SET_3 3U /**< Read Byte Count */
#define XAPM_METRIC_SET_4 4U /**< Write Beat Count */
#define XAPM_METRIC_SET_5 5U /**< Total Read Latency */
#define XAPM_METRIC_SET_6 6U /**< Total Write Latency */
#define XAPM_METRIC_SET_7 7U /**< Slv_Wr_Idle_Cnt */
#define XAPM_METRIC_SET_8 8U /**< Mst_Rd_Idle_Cnt */
#define XAPM_METRIC_SET_9 9U /**< Num_BValids */
#define XAPM_METRIC_SET_10 10U /**< Num_WLasts */
#define XAPM_METRIC_SET_11 11U /**< Num_RLasts */
#define XAPM_METRIC_SET_12 12U /**< Minimum Write Latency */
#define XAPM_METRIC_SET_13 13U /**< Maximum Write Latency */
#define XAPM_METRIC_SET_14 14U /**< Minimum Read Latency */
#define XAPM_METRIC_SET_15 15U /**< Maximum Read Latency */
#define XAPM_METRIC_SET_16 16U /**< Transfer Cycle Count */
#define XAPM_METRIC_SET_17 17U /**< Packet Count */
#define XAPM_METRIC_SET_18 18U /**< Data Byte Count */
#define XAPM_METRIC_SET_19 19U /**< Position Byte Count */
#define XAPM_METRIC_SET_20 20U /**< Null Byte Count */
#define XAPM_METRIC_SET_21 21U /**< Slv_Idle_Cnt */
#define XAPM_METRIC_SET_22 22U /**< Mst_Idle_Cnt */
#define XAPM_METRIC_SET_30 30U /**< External event count */
/*@}*/
/**
* @name Macros for Maximum number of Agents
* @{
*/
#define XAPM_MAX_AGENTS 8U /**< Maximum number of Agents */
/*@}*/
/**
* @name Macros for Flags in Flag Enable Control Register
* @{
*/
#define XAPM_FLAG_WRADDR 0x00000001 /**< Write Address Flag */
#define XAPM_FLAG_FIRSTWR 0x00000002 /**< First Write Flag */
#define XAPM_FLAG_LASTWR 0x00000004 /**< Last Write Flag */
#define XAPM_FLAG_RESPONSE 0x00000008 /**< Response Flag */
#define XAPM_FLAG_RDADDR 0x00000010 /**< Read Address Flag */
#define XAPM_FLAG_FIRSTRD 0x00000020 /**< First Read Flag */
#define XAPM_FLAG_LASTRD 0x00000040 /**< Last Read Flag */
#define XAPM_FLAG_SWDATA 0x00010000 /**< Software-written Data Flag */
#define XAPM_FLAG_EVENT 0x00020000 /**< Last Read Flag */
#define XAPM_FLAG_EVNTSTOP 0x00040000 /**< Last Read Flag */
#define XAPM_FLAG_EVNTSTART 0x00080000 /**< Last Read Flag */
#define XAPM_FLAG_GCCOVF 0x00100000 /**< Global Clock Counter Overflow
* Flag */
#define XAPM_FLAG_SCLAPSE 0x00200000 /**< Sample Counter Lapse Flag */
#define XAPM_FLAG_MC0 0x00400000U /**< Metric Counter 0 Flag */
#define XAPM_FLAG_MC1 0x00800000U /**< Metric Counter 1 Flag */
#define XAPM_FLAG_MC2 0x01000000U /**< Metric Counter 2 Flag */
#define XAPM_FLAG_MC3 0x02000000U /**< Metric Counter 3 Flag */
#define XAPM_FLAG_MC4 0x04000000U /**< Metric Counter 4 Flag */
#define XAPM_FLAG_MC5 0x08000000U /**< Metric Counter 5 Flag */
#define XAPM_FLAG_MC6 0x10000000U /**< Metric Counter 6 Flag */
#define XAPM_FLAG_MC7 0x20000000U /**< Metric Counter 7 Flag */
#define XAPM_FLAG_MC8 0x40000000U /**< Metric Counter 8 Flag */
#define XAPM_FLAG_MC9 0x80000000U /**< Metric Counter 9 Flag */
/*@}*/
/**
* @name Macros for Read/Write Latency Start and End points
* @{
*/
#define XAPM_LATENCY_ADDR_ISSUE 0U /**< Address Issue as start
point for Latency calculation*/
#define XAPM_LATENCY_ADDR_ACCEPT 1U /**< Address Acceptance as start
point for Latency calculation*/
#define XAPM_LATENCY_LASTRD 0U /**< Last Read as end point for
Latency calculation */
#define XAPM_LATENCY_LASTWR 0U /**< Last Write as end point for
Latency calculation */
#define XAPM_LATENCY_FIRSTRD 1U /**< First Read as end point for
Latency calculation */
#define XAPM_LATENCY_FIRSTWR 1U /**< First Write as end point for
Latency calculation */
/*@}*/
/**
* @name Macros for Modes of APM
* @{
*/
#define XAPM_MODE_TRACE 2U /**< APM in Trace mode */
#define XAPM_MODE_PROFILE 1U /**< APM in Profile mode */
#define XAPM_MODE_ADVANCED 0U /**< APM in Advanced mode */
/*@}*/
/**************************** Type Definitions *******************************/
/**
* This typedef contains configuration information for the AXI Performance
* Monitor device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
UINTPTR BaseAddress; /**< Device base address */
s32 GlobalClkCounterWidth; /**< Global Clock Counter Width */
s32 MetricSampleCounterWidth ; /**< Metric Sample Counters Width */
u8 IsEventCount; /**< Event Count Enabled 1 - enabled
0 - not enabled */
u8 NumberofSlots; /**< Number of Monitor Slots */
u8 NumberofCounters; /**< Number of Counters */
u8 HaveSampledCounters; /**< Have Sampled Counters 1 - present
0 - Not present */
u8 IsEventLog; /**< Event Logging Enabled 1 - enabled
0 - Not enabled */
u32 FifoDepth; /**< Event Log FIFO Depth */
u32 FifoWidth; /**< Event Log FIFO Width */
u32 TidWidth; /**< Streaming Interface TID Width */
u8 ScaleFactor; /**< Event Count Scaling factor */
u8 ModeAdvanced; /**< Advanced Mode */
u8 ModeProfile; /**< Profile Mode */
u8 ModeTrace; /**< Trace Mode */
u8 Is32BitFiltering; /**< 32 bit filtering enabled */
} XAxiPmon_Config;
/**
* The driver's instance data. The user is required to allocate a variable
* of this type for every AXI Performance Monitor device in system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XAxiPmon_Config Config; /**< XAxiPmon_Config of current device */
u32 IsReady; /**< Device is initialized and ready */
u8 Mode; /**< APM Mode */
} XAxiPmon;
/***************** Macros (Inline Functions) Definitions ********************/
/****************************************************************************/
/**
*
* This routine enables the Global Interrupt.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None.
*
* @note C-Style signature:
* void XAxiPmon_IntrGlobalEnable(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_IntrGlobalEnable(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, \
XAPM_GIE_OFFSET, 1)
/****************************************************************************/
/**
*
* This routine disables the Global Interrupt.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None.
*
* @note C-Style signature:
* void XAxiPmon_IntrGlobalDisable(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_IntrGlobalDisable(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, \
XAPM_GIE_OFFSET, 0)
/****************************************************************************/
/**
*
* This routine enables interrupt(s). Use the XAPM_IXR_* constants defined in
* xaxipmon_hw.h to create the bit-mask to enable interrupts.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
* @param Mask is the mask to enable. Bit positions of 1 will be enabled.
* Bit positions of 0 will keep the previous setting. This mask is
* formed by OR'ing XAPM_IXR__* bits defined in xaxipmon_hw.h.
*
* @return None.
*
* @note C-Style signature:
* void XAxiPmon_IntrEnable(XAxiPmon *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XAxiPmon_IntrEnable(InstancePtr, Mask) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_IE_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_IE_OFFSET) | (Mask));
/****************************************************************************/
/**
*
* This routine disable interrupt(s). Use the XAPM_IXR_* constants defined in
* xaxipmon_hw.h to create the bit-mask to disable interrupts.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
* @param Mask is the mask to disable. Bit positions of 1 will be
* disabled. Bit positions of 0 will keep the previous setting.
* This mask is formed by OR'ing XAPM_IXR_* bits defined in
* xaxipmon_hw.h.
*
* @return None.
*
* @note C-Style signature:
* void XAxiPmon_IntrEnable(XAxiPmon *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XAxiPmon_IntrDisable(InstancePtr, Mask) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_IE_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_IE_OFFSET) | (Mask));
/****************************************************************************/
/**
*
* This routine clears the specified interrupt(s).
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
* @param Mask is the mask to clear. Bit positions of 1 will be cleared.
* This mask is formed by OR'ing XAPM_IXR_* bits defined in
* xaxipmon_hw.h.
*
* @return None.
*
* @note C-Style signature:
* void XAxiPmon_IntrClear(XAxiPmon *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XAxiPmon_IntrClear(InstancePtr, Mask) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_IS_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_IS_OFFSET) | (Mask));
/****************************************************************************/
/**
*
* This routine returns the Interrupt Status Register.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return Interrupt Status Register contents
*
* @note C-Style signature:
* void XAxiPmon_IntrClear(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_IntrGetStatus(InstancePtr) \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_IS_OFFSET);
/****************************************************************************/
/**
*
* This function enables the Global Clock Counter.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_EnableGlobalClkCounter(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_EnableGlobalClkCounter(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_CTL_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_CTL_OFFSET) | XAPM_CR_GCC_ENABLE_MASK);
/****************************************************************************/
/**
*
* This function disbles the Global Clock Counter.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_DisableGlobalClkCounter(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_DisableGlobalClkCounter(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_CTL_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_CTL_OFFSET) & ~(XAPM_CR_GCC_ENABLE_MASK));
/****************************************************************************/
/**
*
* This function enables the specified flag in Flag Control Register.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
* @param Flag is one of the XAPM_FLAG_* masks defined in xaxipmon.h
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_EnableFlag(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_EnableFlag(InstancePtr, Flag) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_FEC_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_FEC_OFFSET) | (Flag));
/****************************************************************************/
/**
*
* This function disables the specified flag in Flag Control Register.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
* @param Flag is one of the XAPM_FLAG_* masks defined in xaxipmon.h*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_DisableFlag(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_DisableFlag(InstancePtr, Flag) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_FEC_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_FEC_OFFSET) & ~(Flag));
/****************************************************************************/
/**
*
* This function loads the sample interval register value into the sample
* interval counter.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_LoadSampleIntervalCounter(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_LoadSampleIntervalCounter(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_SICR_OFFSET, \
XAPM_SICR_LOAD_MASK);
/****************************************************************************/
/**
*
* This enables the down count of the sample interval counter.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_EnableSampleIntervalCounter(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_EnableSampleIntervalCounter(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_SICR_OFFSET,\
XAPM_SICR_ENABLE_MASK);
/****************************************************************************/
/**
*
* This disables the down count of the sample interval counter.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_DisableSampleIntervalCounter(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_DisableSampleIntervalCounter(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_SICR_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_SICR_OFFSET) & ~(XAPM_SICR_ENABLE_MASK));
/****************************************************************************/
/**
*
* This enables Reset of Metric Counters when Sample Interval Counter lapses.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_EnableMetricCounterReset(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_EnableMetricCounterReset(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_SICR_OFFSET,\
XAPM_SICR_MCNTR_RST_MASK);
/****************************************************************************/
/**
*
* This disables the down count of the sample interval counter.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_DisableMetricCounterReset(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_DisableMetricCounterReset(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_SICR_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_SICR_OFFSET) & ~(XAPM_SICR_MCNTR_RST_MASK));
/****************************************************************************/
/**
*
* This function enables the ID Filter Masking.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_EnableIDFilter(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_EnableIDFilter(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_CTL_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_CTL_OFFSET) | XAPM_CR_IDFILTER_ENABLE_MASK);
/****************************************************************************/
/**
*
* This function disbles the ID Filter masking.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return None
*
* @note C-Style signature:
* void XAxiPmon_DisableIDFilter(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_DisableIDFilter(InstancePtr) \
XAxiPmon_WriteReg((InstancePtr)->Config.BaseAddress, XAPM_CTL_OFFSET, \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, \
XAPM_CTL_OFFSET) & ~(XAPM_CR_IDFILTER_ENABLE_MASK));
/****************************************************************************/
/**
*
* This function samples Metric Counters to Sampled Metric Counters by
* reading Sample Register and also returns interval. i.e. the number of
* clocks in between previous read to the current read of sample register.
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return Interval. i.e. the number of clocks in between previous
* read to the current read of sample register.
*
* @note C-Style signature:
* u32 XAxiPmon_SampleMetrics(XAxiPmon *InstancePtr)
*
*****************************************************************************/
#define XAxiPmon_SampleMetrics(InstancePtr) \
XAxiPmon_ReadReg((InstancePtr)->Config.BaseAddress, XAPM_SR_OFFSET);
/************************** Function Prototypes *****************************/
/**
* Functions in xaxipmon_sinit.c
*/
XAxiPmon_Config *XAxiPmon_LookupConfig(u16 DeviceId);
/**
* Functions in xaxipmon.c
*/
s32 XAxiPmon_CfgInitialize(XAxiPmon *InstancePtr,
XAxiPmon_Config *ConfigPtr, UINTPTR EffectiveAddr);
s32 XAxiPmon_ResetMetricCounter(XAxiPmon *InstancePtr);
void XAxiPmon_ResetGlobalClkCounter(XAxiPmon *InstancePtr);
s32 XAxiPmon_ResetFifo(XAxiPmon *InstancePtr);
void XAxiPmon_SetIncrementerRange(XAxiPmon *InstancePtr, u8 IncrementerNum,
u16 RangeUpper, u16 RangeLower);
void XAxiPmon_GetIncrementerRange(XAxiPmon *InstancePtr, u8 IncrementerNum,
u16 *RangeUpper, u16 *RangeLower);
void XAxiPmon_SetSampleInterval(XAxiPmon *InstancePtr, u32 SampleInterval);
void XAxiPmon_GetSampleInterval(XAxiPmon *InstancePtr, u32 *SampleInterval);
s32 XAxiPmon_SetMetrics(XAxiPmon *InstancePtr, u8 Slot, u8 Metrics,
u8 CounterNum);
s32 XAxiPmon_GetMetrics(XAxiPmon *InstancePtr, u8 CounterNum, u8 *Metrics,
u8 *Slot);
void XAxiPmon_GetGlobalClkCounter(XAxiPmon *InstancePtr,u32 *CntHighValue,
u32 *CntLowValue);
u32 XAxiPmon_GetMetricCounter(XAxiPmon *InstancePtr, u32 CounterNum);
u32 XAxiPmon_GetSampledMetricCounter(XAxiPmon *InstancePtr, u32 CounterNum);
u32 XAxiPmon_GetIncrementer(XAxiPmon *InstancePtr, u32 IncrementerNum);
u32 XAxiPmon_GetSampledIncrementer(XAxiPmon *InstancePtr, u32 IncrementerNum);
void XAxiPmon_SetSwDataReg(XAxiPmon *InstancePtr, u32 SwData);
u32 XAxiPmon_GetSwDataReg(XAxiPmon *InstancePtr);
s32 XAxiPmon_StartEventLog(XAxiPmon *InstancePtr, u32 FlagEnables);
s32 XAxiPmon_StopEventLog(XAxiPmon *InstancePtr);
s32 XAxiPmon_StartCounters(XAxiPmon *InstancePtr, u32 SampleInterval);
s32 XAxiPmon_StopCounters(XAxiPmon *InstancePtr);
void XAxiPmon_EnableMetricsCounter(XAxiPmon *InstancePtr);
void XAxiPmon_DisableMetricsCounter(XAxiPmon *InstancePtr);
void XAxiPmon_SetLogEnableRanges(XAxiPmon *InstancePtr, u32 CounterNum,
u16 RangeUpper, u16 RangeLower);
void XAxiPmon_GetLogEnableRanges(XAxiPmon *InstancePtr, u32 CounterNum,
u16 *RangeUpper, u16 *RangeLower);
void XAxiPmon_EnableEventLog(XAxiPmon *InstancePtr);
void XAxiPmon_EnableMetricCounterTrigger(XAxiPmon *InstancePtr);
void XAxiPmon_DisableMetricCounterTrigger(XAxiPmon *InstancePtr);
void XAxiPmon_EnableEventLogTrigger(XAxiPmon *InstancePtr);
void XAxiPmon_DisableEventLogTrigger(XAxiPmon *InstancePtr);
const char * XAxiPmon_GetMetricName(u8 Metrics);
void XAxiPmon_SetWriteId(XAxiPmon *InstancePtr, u32 WriteId);
void XAxiPmon_SetReadId(XAxiPmon *InstancePtr, u32 ReadId);
u32 XAxiPmon_GetWriteId(XAxiPmon *InstancePtr);
u32 XAxiPmon_GetReadId(XAxiPmon *InstancePtr);
void XAxiPmon_SetWrLatencyStart(XAxiPmon *InstancePtr, u8 Param);
void XAxiPmon_SetWrLatencyEnd(XAxiPmon *InstancePtr, u8 Param);
void XAxiPmon_SetRdLatencyStart(XAxiPmon *InstancePtr, u8 Param);
void XAxiPmon_SetRdLatencyEnd(XAxiPmon *InstancePtr, u8 Param);
u8 XAxiPmon_GetWrLatencyStart(XAxiPmon *InstancePtr);
u8 XAxiPmon_GetWrLatencyEnd(XAxiPmon *InstancePtr);
u8 XAxiPmon_GetRdLatencyStart(XAxiPmon *InstancePtr);
u8 XAxiPmon_GetRdLatencyEnd(XAxiPmon *InstancePtr);
void XAxiPmon_SetWriteIdMask(XAxiPmon *InstancePtr, u32 WrMask);
void XAxiPmon_SetReadIdMask(XAxiPmon *InstancePtr, u32 RdMask);
u32 XAxiPmon_GetWriteIdMask(XAxiPmon *InstancePtr);
u32 XAxiPmon_GetReadIdMask(XAxiPmon *InstancePtr);
/**
* Functions in xaxipmon_selftest.c
*/
s32 XAxiPmon_SelfTest(XAxiPmon *InstancePtr);
#ifdef __cplusplus
}
#endif
#endif /* End of protection macro. */
/** @} */

View file

@ -0,0 +1,127 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the Software), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in
*all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
*(a) running on a Xilinx device, or
*(b) that interact with a Xilinx device through a bus or interconnect.
*
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the Xilinx shall not be used
*in advertising or otherwise to promote the sale, use or other dealings in
*this Software without prior written authorization from Xilinx.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xaxipmon.h"
/*
* The configuration table for devices
*/
XAxiPmon_Config XAxiPmon_ConfigTable[] =
{
{
XPAR_PSU_APM_0_DEVICE_ID,
XPAR_PSU_APM_0_BASEADDR,
XPAR_PSU_APM_0_GLOBAL_COUNT_WIDTH,
XPAR_PSU_APM_0_METRICS_SAMPLE_COUNT_WIDTH,
XPAR_PSU_APM_0_ENABLE_EVENT_COUNT,
XPAR_PSU_APM_0_NUM_MONITOR_SLOTS,
XPAR_PSU_APM_0_NUM_OF_COUNTERS,
XPAR_PSU_APM_0_HAVE_SAMPLED_METRIC_CNT,
XPAR_PSU_APM_0_ENABLE_EVENT_LOG,
XPAR_PSU_APM_0_FIFO_AXIS_DEPTH,
XPAR_PSU_APM_0_FIFO_AXIS_TDATA_WIDTH,
XPAR_PSU_APM_0_FIFO_AXIS_TID_WIDTH,
XPAR_PSU_APM_0_METRIC_COUNT_SCALE,
XPAR_PSU_APM_0_ENABLE_ADVANCED,
XPAR_PSU_APM_0_ENABLE_PROFILE,
XPAR_PSU_APM_0_ENABLE_TRACE,
XPAR_PSU_APM_0_ENABLE_32BIT_FILTER_ID
},
{
XPAR_PSU_APM_1_DEVICE_ID,
XPAR_PSU_APM_1_BASEADDR,
XPAR_PSU_APM_1_GLOBAL_COUNT_WIDTH,
XPAR_PSU_APM_1_METRICS_SAMPLE_COUNT_WIDTH,
XPAR_PSU_APM_1_ENABLE_EVENT_COUNT,
XPAR_PSU_APM_1_NUM_MONITOR_SLOTS,
XPAR_PSU_APM_1_NUM_OF_COUNTERS,
XPAR_PSU_APM_1_HAVE_SAMPLED_METRIC_CNT,
XPAR_PSU_APM_1_ENABLE_EVENT_LOG,
XPAR_PSU_APM_1_FIFO_AXIS_DEPTH,
XPAR_PSU_APM_1_FIFO_AXIS_TDATA_WIDTH,
XPAR_PSU_APM_1_FIFO_AXIS_TID_WIDTH,
XPAR_PSU_APM_1_METRIC_COUNT_SCALE,
XPAR_PSU_APM_1_ENABLE_ADVANCED,
XPAR_PSU_APM_1_ENABLE_PROFILE,
XPAR_PSU_APM_1_ENABLE_TRACE,
XPAR_PSU_APM_1_ENABLE_32BIT_FILTER_ID
},
{
XPAR_PSU_APM_2_DEVICE_ID,
XPAR_PSU_APM_2_BASEADDR,
XPAR_PSU_APM_2_GLOBAL_COUNT_WIDTH,
XPAR_PSU_APM_2_METRICS_SAMPLE_COUNT_WIDTH,
XPAR_PSU_APM_2_ENABLE_EVENT_COUNT,
XPAR_PSU_APM_2_NUM_MONITOR_SLOTS,
XPAR_PSU_APM_2_NUM_OF_COUNTERS,
XPAR_PSU_APM_2_HAVE_SAMPLED_METRIC_CNT,
XPAR_PSU_APM_2_ENABLE_EVENT_LOG,
XPAR_PSU_APM_2_FIFO_AXIS_DEPTH,
XPAR_PSU_APM_2_FIFO_AXIS_TDATA_WIDTH,
XPAR_PSU_APM_2_FIFO_AXIS_TID_WIDTH,
XPAR_PSU_APM_2_METRIC_COUNT_SCALE,
XPAR_PSU_APM_2_ENABLE_ADVANCED,
XPAR_PSU_APM_2_ENABLE_PROFILE,
XPAR_PSU_APM_2_ENABLE_TRACE,
XPAR_PSU_APM_2_ENABLE_32BIT_FILTER_ID
},
{
XPAR_PSU_APM_5_DEVICE_ID,
XPAR_PSU_APM_5_BASEADDR,
XPAR_PSU_APM_5_GLOBAL_COUNT_WIDTH,
XPAR_PSU_APM_5_METRICS_SAMPLE_COUNT_WIDTH,
XPAR_PSU_APM_5_ENABLE_EVENT_COUNT,
XPAR_PSU_APM_5_NUM_MONITOR_SLOTS,
XPAR_PSU_APM_5_NUM_OF_COUNTERS,
XPAR_PSU_APM_5_HAVE_SAMPLED_METRIC_CNT,
XPAR_PSU_APM_5_ENABLE_EVENT_LOG,
XPAR_PSU_APM_5_FIFO_AXIS_DEPTH,
XPAR_PSU_APM_5_FIFO_AXIS_TDATA_WIDTH,
XPAR_PSU_APM_5_FIFO_AXIS_TID_WIDTH,
XPAR_PSU_APM_5_METRIC_COUNT_SCALE,
XPAR_PSU_APM_5_ENABLE_ADVANCED,
XPAR_PSU_APM_5_ENABLE_PROFILE,
XPAR_PSU_APM_5_ENABLE_TRACE,
XPAR_PSU_APM_5_ENABLE_32BIT_FILTER_ID
}
};

View file

@ -0,0 +1,571 @@
/******************************************************************************
*
* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xaxipmon_hw.h
* @addtogroup axipmon_v6_3
* @{
*
* This header file contains identifiers and basic driver functions (or
* macros) that can be used to access the AXI Performance Monitor.
*
* Refer to the device specification for more information about this driver.
*
* @note None.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------------
* 1.00a bss 02/27/12 First release
* 2.00a bss 06/23/12 Updated to support v2_00a version of IP.
* 3.00a bss 09/03/12 Deleted XAPM_AGENT_OFFSET Macro to support
* v2_01a version of IP.
* 3.01a bss 10/25/12 To support new version of IP:
* Added XAPM_MCXLOGEN_OFFSET and
* XAPM_CR_EXTERNAL_TRIGGER_MASK macros.
* 4.00a bss 01/17/13 To support new version of IP:
* Added XAPM_LATENCYID_OFFSET,
* XAPM_CR_EVTLOG_EXTTRIGGER_MASK,
* XAPM_LATENCYID_RID_MASK and XAPM_LATENCYID_WID_MASK
* 5.00a bss 08/26/13 To support new version of IP:
* Added Macros XAPM_MC10_OFFSET to XAPM_MC47_OFFSET,
* XAPM_SMC10_OFFSET to XAPM_SMC47_OFFSET.
* Added macro XAPM_IDMASK_OFFSET, XAPM_SR_OFFSET.
* Added XAPM_CR_IDFILTER_ENABLE_MASK,
* XAPM_CR_WRLATENCY_START_MASK,
* XAPM_CR_WRLATENCY_END_MASK,
* XAPM_CR_RDLATENCY_START_MASK,
* XAPM_CR_RDLATENCY_END_MASK, XAPM_MASKID_RID_MASK
* and XAPM_MASKID_WID_MASK macros.
* Renamed:
* XAPM_LATENCYID_OFFSET to XAPM_ID_OFFSET,
* XAPM_LATENCYID_RID_MASK to XAPM_ID_RID_MASK,
* XAPM_LATENCYID_WID_MASK to XAPM_ID_WID_MASK.
*
* 6.2 bss 03/02/15 Added XAPM_RID_OFFSET and XAPM_RIDMASK_OFFSET to support
* Zynq MP APM.
*
* 6.3 kvn 07/02/15 Modified code according to MISRA-C:2012 guidelines.
* </pre>
*
*****************************************************************************/
#ifndef XAXIPMON_HW_H /* Prevent circular inclusions */
#define XAXIPMON_HW_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions ****************************/
/**@name Register offsets of AXIMONITOR in the Device Config
*
* The following constants provide access to each of the registers of the
* AXI PERFORMANCE MONITOR device.
* @{
*/
#define XAPM_GCC_HIGH_OFFSET 0x00000000U /**< Global Clock Counter
32 to 63 bits */
#define XAPM_GCC_LOW_OFFSET 0x00000004U /**< Global Clock Counter Lower
0-31 bits */
#define XAPM_SI_HIGH_OFFSET 0x00000020U /**< Sample Interval MSB */
#define XAPM_SI_LOW_OFFSET 0x00000024U /**< Sample Interval LSB */
#define XAPM_SICR_OFFSET 0x00000028U /**< Sample Interval Control
Register */
#define XAPM_SR_OFFSET 0x0000002CU /**< Sample Register */
#define XAPM_GIE_OFFSET 0x00000030U /**< Global Interrupt Enable
Register */
#define XAPM_IE_OFFSET 0x00000034U /**< Interrupt Enable Register */
#define XAPM_IS_OFFSET 0x00000038U /**< Interrupt Status Register */
#define XAPM_MSR0_OFFSET 0x00000044U /**< Metric Selector 0 Register */
#define XAPM_MSR1_OFFSET 0x00000048U /**< Metric Selector 1 Register */
#define XAPM_MSR2_OFFSET 0x0000004CU /**< Metric Selector 2 Register */
#define XAPM_MC0_OFFSET 0x00000100U /**< Metric Counter 0 Register */
#define XAPM_INC0_OFFSET 0x00000104U /**< Incrementer 0 Register */
#define XAPM_RANGE0_OFFSET 0x00000108U /**< Range 0 Register */
#define XAPM_MC0LOGEN_OFFSET 0x0000010CU /**< Metric Counter 0
Log Enable Register */
#define XAPM_MC1_OFFSET 0x00000110U /**< Metric Counter 1 Register */
#define XAPM_INC1_OFFSET 0x00000114U /**< Incrementer 1 Register */
#define XAPM_RANGE1_OFFSET 0x00000118U /**< Range 1 Register */
#define XAPM_MC1LOGEN_OFFSET 0x0000011CU /**< Metric Counter 1
Log Enable Register */
#define XAPM_MC2_OFFSET 0x00000120U /**< Metric Counter 2 Register */
#define XAPM_INC2_OFFSET 0x00000124U /**< Incrementer 2 Register */
#define XAPM_RANGE2_OFFSET 0x00000128U /**< Range 2 Register */
#define XAPM_MC2LOGEN_OFFSET 0x0000012CU /**< Metric Counter 2
Log Enable Register */
#define XAPM_MC3_OFFSET 0x00000130U /**< Metric Counter 3 Register */
#define XAPM_INC3_OFFSET 0x00000134U /**< Incrementer 3 Register */
#define XAPM_RANGE3_OFFSET 0x00000138U /**< Range 3 Register */
#define XAPM_MC3LOGEN_OFFSET 0x0000013CU /**< Metric Counter 3
Log Enable Register */
#define XAPM_MC4_OFFSET 0x00000140U /**< Metric Counter 4 Register */
#define XAPM_INC4_OFFSET 0x00000144U /**< Incrementer 4 Register */
#define XAPM_RANGE4_OFFSET 0x00000148U /**< Range 4 Register */
#define XAPM_MC4LOGEN_OFFSET 0x0000014CU /**< Metric Counter 4
Log Enable Register */
#define XAPM_MC5_OFFSET 0x00000150U /**< Metric Counter 5
Register */
#define XAPM_INC5_OFFSET 0x00000154U /**< Incrementer 5 Register */
#define XAPM_RANGE5_OFFSET 0x00000158U /**< Range 5 Register */
#define XAPM_MC5LOGEN_OFFSET 0x0000015CU /**< Metric Counter 5
Log Enable Register */
#define XAPM_MC6_OFFSET 0x00000160U /**< Metric Counter 6
Register */
#define XAPM_INC6_OFFSET 0x00000164U /**< Incrementer 6 Register */
#define XAPM_RANGE6_OFFSET 0x00000168U /**< Range 6 Register */
#define XAPM_MC6LOGEN_OFFSET 0x0000016CU /**< Metric Counter 6
Log Enable Register */
#define XAPM_MC7_OFFSET 0x00000170U /**< Metric Counter 7
Register */
#define XAPM_INC7_OFFSET 0x00000174U /**< Incrementer 7 Register */
#define XAPM_RANGE7_OFFSET 0x00000178U /**< Range 7 Register */
#define XAPM_MC7LOGEN_OFFSET 0x0000017CU /**< Metric Counter 7
Log Enable Register */
#define XAPM_MC8_OFFSET 0x00000180U /**< Metric Counter 8
Register */
#define XAPM_INC8_OFFSET 0x00000184U /**< Incrementer 8 Register */
#define XAPM_RANGE8_OFFSET 0x00000188U /**< Range 8 Register */
#define XAPM_MC8LOGEN_OFFSET 0x0000018CU /**< Metric Counter 8
Log Enable Register */
#define XAPM_MC9_OFFSET 0x00000190U /**< Metric Counter 9
Register */
#define XAPM_INC9_OFFSET 0x00000194U /**< Incrementer 9 Register */
#define XAPM_RANGE9_OFFSET 0x00000198U /**< Range 9 Register */
#define XAPM_MC9LOGEN_OFFSET 0x0000019CU /**< Metric Counter 9
Log Enable Register */
#define XAPM_SMC0_OFFSET 0x00000200U /**< Sampled Metric Counter
0 Register */
#define XAPM_SINC0_OFFSET 0x00000204U /**< Sampled Incrementer
0 Register */
#define XAPM_SMC1_OFFSET 0x00000210U /**< Sampled Metric Counter
1 Register */
#define XAPM_SINC1_OFFSET 0x00000214U /**< Sampled Incrementer
1 Register */
#define XAPM_SMC2_OFFSET 0x00000220U /**< Sampled Metric Counter
2 Register */
#define XAPM_SINC2_OFFSET 0x00000224U /**< Sampled Incrementer
2 Register */
#define XAPM_SMC3_OFFSET 0x00000230U /**< Sampled Metric Counter
3 Register */
#define XAPM_SINC3_OFFSET 0x00000234U /**< Sampled Incrementer
3 Register */
#define XAPM_SMC4_OFFSET 0x00000240U /**< Sampled Metric Counter
4 Register */
#define XAPM_SINC4_OFFSET 0x00000244U /**< Sampled Incrementer
4 Register */
#define XAPM_SMC5_OFFSET 0x00000250U /**< Sampled Metric Counter
5 Register */
#define XAPM_SINC5_OFFSET 0x00000254U /**< Sampled Incrementer
5 Register */
#define XAPM_SMC6_OFFSET 0x00000260U /**< Sampled Metric Counter
6 Register */
#define XAPM_SINC6_OFFSET 0x00000264U /**< Sampled Incrementer
6 Register */
#define XAPM_SMC7_OFFSET 0x00000270U /**< Sampled Metric Counter
7 Register */
#define XAPM_SINC7_OFFSET 0x00000274U /**< Sampled Incrementer
7 Register */
#define XAPM_SMC8_OFFSET 0x00000280U /**< Sampled Metric Counter
8 Register */
#define XAPM_SINC8_OFFSET 0x00000284U /**< Sampled Incrementer
8 Register */
#define XAPM_SMC9_OFFSET 0x00000290U /**< Sampled Metric Counter
9 Register */
#define XAPM_SINC9_OFFSET 0x00000294U /**< Sampled Incrementer
9 Register */
#define XAPM_MC10_OFFSET 0x000001A0U /**< Metric Counter 10
Register */
#define XAPM_MC11_OFFSET 0x000001B0U /**< Metric Counter 11
Register */
#define XAPM_MC12_OFFSET 0x00000500U /**< Metric Counter 12
Register */
#define XAPM_MC13_OFFSET 0x00000510U /**< Metric Counter 13
Register */
#define XAPM_MC14_OFFSET 0x00000520U /**< Metric Counter 14
Register */
#define XAPM_MC15_OFFSET 0x00000530U /**< Metric Counter 15
Register */
#define XAPM_MC16_OFFSET 0x00000540U /**< Metric Counter 16
Register */
#define XAPM_MC17_OFFSET 0x00000550U /**< Metric Counter 17
Register */
#define XAPM_MC18_OFFSET 0x00000560U /**< Metric Counter 18
Register */
#define XAPM_MC19_OFFSET 0x00000570U /**< Metric Counter 19
Register */
#define XAPM_MC20_OFFSET 0x00000580U /**< Metric Counter 20
Register */
#define XAPM_MC21_OFFSET 0x00000590U /**< Metric Counter 21
Register */
#define XAPM_MC22_OFFSET 0x000005A0U /**< Metric Counter 22
Register */
#define XAPM_MC23_OFFSET 0x000005B0U /**< Metric Counter 23
Register */
#define XAPM_MC24_OFFSET 0x00000700U /**< Metric Counter 24
Register */
#define XAPM_MC25_OFFSET 0x00000710U /**< Metric Counter 25
Register */
#define XAPM_MC26_OFFSET 0x00000720U /**< Metric Counter 26
Register */
#define XAPM_MC27_OFFSET 0x00000730U /**< Metric Counter 27
Register */
#define XAPM_MC28_OFFSET 0x00000740U /**< Metric Counter 28
Register */
#define XAPM_MC29_OFFSET 0x00000750U /**< Metric Counter 29
Register */
#define XAPM_MC30_OFFSET 0x00000760U /**< Metric Counter 30
Register */
#define XAPM_MC31_OFFSET 0x00000770U /**< Metric Counter 31
Register */
#define XAPM_MC32_OFFSET 0x00000780U /**< Metric Counter 32
Register */
#define XAPM_MC33_OFFSET 0x00000790U /**< Metric Counter 33
Register */
#define XAPM_MC34_OFFSET 0x000007A0U /**< Metric Counter 34
Register */
#define XAPM_MC35_OFFSET 0x000007B0U /**< Metric Counter 35
Register */
#define XAPM_MC36_OFFSET 0x00000900U /**< Metric Counter 36
Register */
#define XAPM_MC37_OFFSET 0x00000910U /**< Metric Counter 37
Register */
#define XAPM_MC38_OFFSET 0x00000920U /**< Metric Counter 38
Register */
#define XAPM_MC39_OFFSET 0x00000930U /**< Metric Counter 39
Register */
#define XAPM_MC40_OFFSET 0x00000940U /**< Metric Counter 40
Register */
#define XAPM_MC41_OFFSET 0x00000950U /**< Metric Counter 41
Register */
#define XAPM_MC42_OFFSET 0x00000960U /**< Metric Counter 42
Register */
#define XAPM_MC43_OFFSET 0x00000970U /**< Metric Counter 43
Register */
#define XAPM_MC44_OFFSET 0x00000980U /**< Metric Counter 44
Register */
#define XAPM_MC45_OFFSET 0x00000990U /**< Metric Counter 45
Register */
#define XAPM_MC46_OFFSET 0x000009A0U /**< Metric Counter 46
Register */
#define XAPM_MC47_OFFSET 0x000009B0U /**< Metric Counter 47
Register */
#define XAPM_SMC10_OFFSET 0x000002A0U /**< Sampled Metric Counter
10 Register */
#define XAPM_SMC11_OFFSET 0x000002B0U /**< Sampled Metric Counter
11 Register */
#define XAPM_SMC12_OFFSET 0x00000600U /**< Sampled Metric Counter
12 Register */
#define XAPM_SMC13_OFFSET 0x00000610U /**< Sampled Metric Counter
13 Register */
#define XAPM_SMC14_OFFSET 0x00000620U /**< Sampled Metric Counter
14 Register */
#define XAPM_SMC15_OFFSET 0x00000630U /**< Sampled Metric Counter
15 Register */
#define XAPM_SMC16_OFFSET 0x00000640U /**< Sampled Metric Counter
16 Register */
#define XAPM_SMC17_OFFSET 0x00000650U /**< Sampled Metric Counter
17 Register */
#define XAPM_SMC18_OFFSET 0x00000660U /**< Sampled Metric Counter
18 Register */
#define XAPM_SMC19_OFFSET 0x00000670U /**< Sampled Metric Counter
19 Register */
#define XAPM_SMC20_OFFSET 0x00000680U /**< Sampled Metric Counter
20 Register */
#define XAPM_SMC21_OFFSET 0x00000690U /**< Sampled Metric Counter
21 Register */
#define XAPM_SMC22_OFFSET 0x000006A0U /**< Sampled Metric Counter
22 Register */
#define XAPM_SMC23_OFFSET 0x000006B0U /**< Sampled Metric Counter
23 Register */
#define XAPM_SMC24_OFFSET 0x00000800U /**< Sampled Metric Counter
24 Register */
#define XAPM_SMC25_OFFSET 0x00000810U /**< Sampled Metric Counter
25 Register */
#define XAPM_SMC26_OFFSET 0x00000820U /**< Sampled Metric Counter
26 Register */
#define XAPM_SMC27_OFFSET 0x00000830U /**< Sampled Metric Counter
27 Register */
#define XAPM_SMC28_OFFSET 0x00000840U /**< Sampled Metric Counter
28 Register */
#define XAPM_SMC29_OFFSET 0x00000850U /**< Sampled Metric Counter
29 Register */
#define XAPM_SMC30_OFFSET 0x00000860U /**< Sampled Metric Counter
30 Register */
#define XAPM_SMC31_OFFSET 0x00000870U /**< Sampled Metric Counter
31 Register */
#define XAPM_SMC32_OFFSET 0x00000880U /**< Sampled Metric Counter
32 Register */
#define XAPM_SMC33_OFFSET 0x00000890U /**< Sampled Metric Counter
33 Register */
#define XAPM_SMC34_OFFSET 0x000008A0U /**< Sampled Metric Counter
34 Register */
#define XAPM_SMC35_OFFSET 0x000008B0U /**< Sampled Metric Counter
35 Register */
#define XAPM_SMC36_OFFSET 0x00000A00U /**< Sampled Metric Counter
36 Register */
#define XAPM_SMC37_OFFSET 0x00000A10U /**< Sampled Metric Counter
37 Register */
#define XAPM_SMC38_OFFSET 0x00000A20U /**< Sampled Metric Counter
38 Register */
#define XAPM_SMC39_OFFSET 0x00000A30U /**< Sampled Metric Counter
39 Register */
#define XAPM_SMC40_OFFSET 0x00000A40U /**< Sampled Metric Counter
40 Register */
#define XAPM_SMC41_OFFSET 0x00000A50U /**< Sampled Metric Counter
41 Register */
#define XAPM_SMC42_OFFSET 0x00000A60U /**< Sampled Metric Counter
42 Register */
#define XAPM_SMC43_OFFSET 0x00000A70U /**< Sampled Metric Counter
43 Register */
#define XAPM_SMC44_OFFSET 0x00000A80U /**< Sampled Metric Counter
44 Register */
#define XAPM_SMC45_OFFSET 0x00000A90U /**< Sampled Metric Counter
45 Register */
#define XAPM_SMC46_OFFSET 0x00000AA0U /**< Sampled Metric Counter
46 Register */
#define XAPM_SMC47_OFFSET 0x00000AB0U /**< Sampled Metric Counter
47 Register */
#define XAPM_CTL_OFFSET 0x00000300U /**< Control Register */
#define XAPM_ID_OFFSET 0x00000304U /**< Latency ID Register */
#define XAPM_IDMASK_OFFSET 0x00000308U /**< ID Mask Register */
#define XAPM_RID_OFFSET 0x0000030CU /**< Latency Write ID Register */
#define XAPM_RIDMASK_OFFSET 0x00000310U /**< Read ID Mask Register */
#define XAPM_FEC_OFFSET 0x00000400U /**< Flag Enable
Control Register */
#define XAPM_SWD_OFFSET 0x00000404U /**< Software-written
Data Register */
/* @} */
/**
* @name AXI Monitor Sample Interval Control Register mask(s)
* @{
*/
#define XAPM_SICR_MCNTR_RST_MASK 0x00000100U /**< Enable the Metric
Counter Reset */
#define XAPM_SICR_LOAD_MASK 0x00000002U /**< Load the Sample Interval
* Register Value into the
* counter */
#define XAPM_SICR_ENABLE_MASK 0x00000001U /**< Enable the downcounter */
/*@}*/
/** @name Interrupt Status/Enable Register Bit Definitions and Masks
* @{
*/
#define XAPM_IXR_MC9_OVERFLOW_MASK 0x00001000U /**< Metric Counter 9
* Overflow> */
#define XAPM_IXR_MC8_OVERFLOW_MASK 0x00000800U /**< Metric Counter 8
* Overflow> */
#define XAPM_IXR_MC7_OVERFLOW_MASK 0x00000400U /**< Metric Counter 7
* Overflow> */
#define XAPM_IXR_MC6_OVERFLOW_MASK 0x00000200U /**< Metric Counter 6
* Overflow> */
#define XAPM_IXR_MC5_OVERFLOW_MASK 0x00000100U /**< Metric Counter 5
* Overflow> */
#define XAPM_IXR_MC4_OVERFLOW_MASK 0x00000080U /**< Metric Counter 4
* Overflow> */
#define XAPM_IXR_MC3_OVERFLOW_MASK 0x00000040U /**< Metric Counter 3
* Overflow> */
#define XAPM_IXR_MC2_OVERFLOW_MASK 0x00000020U /**< Metric Counter 2
* Overflow> */
#define XAPM_IXR_MC1_OVERFLOW_MASK 0x00000010U /**< Metric Counter 1
* Overflow> */
#define XAPM_IXR_MC0_OVERFLOW_MASK 0x00000008U /**< Metric Counter 0
* Overflow> */
#define XAPM_IXR_FIFO_FULL_MASK 0x00000004U /**< Event Log FIFO
* full> */
#define XAPM_IXR_SIC_OVERFLOW_MASK 0x00000002U /**< Sample Interval
* Counter Overflow> */
#define XAPM_IXR_GCC_OVERFLOW_MASK 0x00000001U /**< Global Clock Counter
* Overflow> */
#define XAPM_IXR_ALL_MASK (XAPM_IXR_SIC_OVERFLOW_MASK | \
XAPM_IXR_GCC_OVERFLOW_MASK | \
XAPM_IXR_FIFO_FULL_MASK | \
XAPM_IXR_MC0_OVERFLOW_MASK | \
XAPM_IXR_MC1_OVERFLOW_MASK | \
XAPM_IXR_MC2_OVERFLOW_MASK | \
XAPM_IXR_MC3_OVERFLOW_MASK | \
XAPM_IXR_MC4_OVERFLOW_MASK | \
XAPM_IXR_MC5_OVERFLOW_MASK | \
XAPM_IXR_MC6_OVERFLOW_MASK | \
XAPM_IXR_MC7_OVERFLOW_MASK | \
XAPM_IXR_MC8_OVERFLOW_MASK | \
XAPM_IXR_MC9_OVERFLOW_MASK)
/* @} */
/**
* @name AXI Monitor Control Register mask(s)
* @{
*/
#define XAPM_CR_FIFO_RESET_MASK 0x02000000U
/**< FIFO Reset */
#define XAPM_CR_GCC_RESET_MASK 0x00020000U
/**< Global Clk
Counter Reset */
#define XAPM_CR_GCC_ENABLE_MASK 0x00010000U
/**< Global Clk
Counter Enable */
#define XAPM_CR_EVTLOG_EXTTRIGGER_MASK 0x00000200U
/**< Enable External trigger
to start event Log */
#define XAPM_CR_EVENTLOG_ENABLE_MASK 0x00000100U
/**< Event Log Enable */
#define XAPM_CR_RDLATENCY_END_MASK 0x00000080U
/**< Write Latency
End point */
#define XAPM_CR_RDLATENCY_START_MASK 0x00000040U
/**< Read Latency
Start point */
#define XAPM_CR_WRLATENCY_END_MASK 0x00000020U
/**< Write Latency
End point */
#define XAPM_CR_WRLATENCY_START_MASK 0x00000010U
/**< Write Latency
Start point */
#define XAPM_CR_IDFILTER_ENABLE_MASK 0x00000008U
/**< ID Filter Enable */
#define XAPM_CR_MCNTR_EXTTRIGGER_MASK 0x00000004U
/**< Enable External
trigger to start
Metric Counters */
#define XAPM_CR_MCNTR_RESET_MASK 0x00000002U
/**< Metrics Counter
Reset */
#define XAPM_CR_MCNTR_ENABLE_MASK 0x00000001U
/**< Metrics Counter
Enable */
/*@}*/
/**
* @name AXI Monitor ID Register mask(s)
* @{
*/
#define XAPM_ID_RID_MASK 0xFFFF0000U /**< Read ID */
#define XAPM_ID_WID_MASK 0x0000FFFFU /**< Write ID */
/*@}*/
/**
* @name AXI Monitor ID Mask Register mask(s)
* @{
*/
#define XAPM_MASKID_RID_MASK 0xFFFF0000U /**< Read ID Mask */
#define XAPM_MASKID_WID_MASK 0x0000FFFFU /**< Write ID Mask*/
/*@}*/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
*
* Read a register of the AXI Performance Monitor device. This macro provides
* register access to all registers using the register offsets defined above.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset is the offset of the register to read.
*
* @return The contents of the register.
*
* @note C-style Signature:
* u32 XAxiPmon_ReadReg(u32 BaseAddress, u32 RegOffset);
*
******************************************************************************/
#define XAxiPmon_ReadReg(BaseAddress, RegOffset) \
(Xil_In32((BaseAddress) + (RegOffset)))
/*****************************************************************************/
/**
*
* Write a register of the AXI Performance Monitor device. This macro provides
* register access to all registers using the register offsets defined above.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset is the offset of the register to write.
* @param Data is the value to write to the register.
*
* @return None.
*
* @note C-style Signature:
* void XAxiPmon_WriteReg(u32 BaseAddress,
* u32 RegOffset,u32 Data)
*
******************************************************************************/
#define XAxiPmon_WriteReg(BaseAddress, RegOffset, Data) \
(Xil_Out32((BaseAddress) + (RegOffset), (Data)))
/************************** Function Prototypes ******************************/
#ifdef __cplusplus
}
#endif
#endif /* End of protection macro. */
/** @} */

View file

@ -0,0 +1,152 @@
/******************************************************************************
*
* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xaxipmon_selftest.c
* @addtogroup axipmon_v6_3
* @{
*
* This file contains a diagnostic self test function for the XAxiPmon driver.
* The self test function does a simple read/write test of the Alarm Threshold
* Register.
*
* See XAxiPmon.h for more information.
*
* @note None.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------------
* 1.00a bss 02/24/12 First release
* 2.00a bss 06/23/12 Updated to support v2_00a version of IP.
* 6.3 kvn 07/02/15 Modified code according to MISRA-C:2012 guidelines.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xaxipmon.h"
/************************** Constant Definitions ****************************/
/*
* The following constant defines the test value to be written
* to the Range Registers of Incrementers
*/
#define XAPM_TEST_RANGEUPPER_VALUE 16U /**< Test Value for Upper Range */
#define XAPM_TEST_RANGELOWER_VALUE 8U /**< Test Value for Lower Range */
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
/*****************************************************************************/
/**
*
* Run a self-test on the driver/device. The test
* - Resets the device,
* - Writes a value into the Range Registers of Incrementer 0 and reads
* it back for comparison.
* - Resets the device again.
*
*
* @param InstancePtr is a pointer to the XAxiPmon instance.
*
* @return
* - XST_SUCCESS if the value read from the Range Register of
* Incrementer 0 is the same as the value written.
* - XST_FAILURE Otherwise
*
* @note This is a destructive test in that resets of the device are
* performed. Refer to the device specification for the
* device status after the reset operation.
*
******************************************************************************/
s32 XAxiPmon_SelfTest(XAxiPmon *InstancePtr)
{
s32 Status;
u16 RangeUpper = 0U;
u16 RangeLower = 0U;
/*
* Assert the argument
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Reset the device to get it back to its default state
*/
(void)XAxiPmon_ResetMetricCounter(InstancePtr);
XAxiPmon_ResetGlobalClkCounter(InstancePtr);
/*
* Write a value into the Incrementer register and
* read it back, and do the comparison
*/
XAxiPmon_SetIncrementerRange(InstancePtr, XAPM_INCREMENTER_0,
XAPM_TEST_RANGEUPPER_VALUE,
XAPM_TEST_RANGELOWER_VALUE);
XAxiPmon_GetIncrementerRange(InstancePtr, XAPM_INCREMENTER_0,
&RangeUpper, &RangeLower);
if ((RangeUpper == XAPM_TEST_RANGEUPPER_VALUE) &&
(RangeLower == XAPM_TEST_RANGELOWER_VALUE)) {
Status = XST_SUCCESS;
} else {
Status = XST_FAILURE;
}
/*
* Reset the device again to its default state.
*/
(void)XAxiPmon_ResetMetricCounter(InstancePtr);
XAxiPmon_ResetGlobalClkCounter(InstancePtr);
/*
* Return the test result.
*/
return Status;
}
/** @} */

View file

@ -0,0 +1,104 @@
/******************************************************************************
*
* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xaxipmon_sinit.c
* @addtogroup axipmon_v6_3
* @{
*
* This file contains the implementation of the XAxiPmon driver's static
* initialization functionality.
*
* @note None.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------------
* 1.00a bss 02/27/12 First release
* 2.00a bss 06/23/12 Updated to support v2_00a version of IP.
* 6.3 kvn 07/02/15 Modified code according to MISRA-C:2012 guidelines.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xaxipmon.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
extern XAxiPmon_Config XAxiPmon_ConfigTable[];
/*****************************************************************************/
/**
*
* This function looks up the device configuration based on the unique device ID.
* The table XAxiPmon_ConfigTable contains the configuration info for each device
* in the system.
*
* @param DeviceId contains the ID of the device for which the
* device configuration pointer is to be returned.
*
* @return
* - A pointer to the configuration found.
* - NULL if the specified device ID was not found.
*
* @note None.
*
******************************************************************************/
XAxiPmon_Config *XAxiPmon_LookupConfig(u16 DeviceId)
{
XAxiPmon_Config *CfgPtr = NULL;
u32 Index;
for (Index=0U; Index < (u32)XPAR_XAXIPMON_NUM_INSTANCES; Index++) {
if (XAxiPmon_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XAxiPmon_ConfigTable[Index];
break;
}
}
return (XAxiPmon_Config *)CfgPtr;
}
/** @} */

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner xcanps_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling canps"
xcanps_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: xcanps_includes
xcanps_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

View file

@ -0,0 +1,575 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcanps.h
* @addtogroup canps_v3_0
* @{
* @details
*
* The Xilinx CAN driver component. This component supports the Xilinx
* CAN Controller.
*
* The CAN Controller supports the following features:
* - Confirms to the ISO 11898-1, CAN 2.0A and CAN 2.0B standards.
* - Supports both Standard (11 bit Identifier) and Extended (29 bit
* Identifier) frames.
* - Supports Bit Rates up to 1 Mbps.
* - Transmit message object FIFO with a user configurable depth of
* up to 64 message objects.
* - Transmit prioritization through one TX High Priority Buffer.
* - Receive message object FIFO with a user configurable depth of
* up to 64 message objects.
* - Watermark interrupts for Rx FIFO with configurable Watermark.
* - Acceptance filtering with 4 acceptance filters.
* - Sleep mode with automatic wake up.
* - Loop Back mode for diagnostic applications.
* - Snoop mode for diagnostic applications.
* - Maskable Error and Status Interrupts.
* - Readable Error Counters.
* - External PHY chip required.
* - Receive Timestamp.
*
* The device driver supports all the features listed above, if applicable.
*
* <b>Driver Description</b>
*
* The device driver enables higher layer software (e.g., an application) to
* communicate to the CAN. The driver handles transmission and reception of
* CAN frames, as well as configuration of the controller. The driver is simply a
* pass-through mechanism between a protocol stack and the CAN. A single device
* driver can support multiple CANs.
*
* Since the driver is a simple pass-through mechanism between a protocol stack
* and the CAN, no assembly or disassembly of CAN frames is done at the
* driver-level. This assumes that the protocol stack passes a correctly
* formatted CAN frame to the driver for transmission, and that the driver
* does not validate the contents of an incoming frame
*
* <b>Operation Modes</b>
*
* The CAN controller supports the following modes of operation:
* - <b>Configuration Mode</b>: In this mode the CAN timing parameters and
* Baud Rate Pre-scalar parameters can be changed. In this mode the CAN
* controller loses synchronization with the CAN bus and drives a
* constant recessive bit on the bus line. The Error Counter Register are
* reset. The CAN controller does not receive or transmit any messages
* even if there are pending transmit requests from the TX FIFO or the TX
* High Priority Buffer. The Storage FIFOs and the CAN configuration
* registers are still accessible.
* - <b>Normal Mode</b>:In Normal Mode the CAN controller participates in bus
* communication, by transmitting and receiving messages.
* - <b>Sleep Mode</b>: In Sleep Mode the CAN Controller does not transmit any
* messages. However, if any other node transmits a message, then the CAN
* Controller receives the transmitted message and exits from Sleep Mode.
* If there are new transmission requests from either the TX FIFO or the
* TX High Priority Buffer when the CAN Controller is in Sleep Mode, these
* requests are not serviced, and the CAN Controller continues to remain
* in Sleep Mode. Interrupts are generated when the CAN controller enters
* Sleep mode or Wakes up from Sleep mode.
* - <b>Loop Back Mode</b>: In Loop Back mode, the CAN controller transmits a
* recessive bit stream on to the CAN Bus. Any message that is transmitted
* is looped back to the <EFBFBD>Rx<EFBFBD> line and acknowledged. The CAN controller
* thus receives any message that it transmits. It does not participate in
* normal bus communication and does not receive any messages that are
* transmitted by other CAN nodes. This mode is used for diagnostic
* purposes.
* - <b>Snoop Mode</b>: In Snoop mode, the CAN controller transmits a
* recessive bit stream on to the CAN Bus and does not participate
* in normal bus communication but receives messages that are transmitted
* by other CAN nodes. This mode is used for diagnostic purposes.
*
*
* <b>Buffer Alignment</b>
*
* It is important to note that frame buffers passed to the driver must be
* 32-bit aligned.
*
* <b>Receive Address Filtering</b>
*
* The device can be set to accept frames whose Identifiers match any of the
* 4 filters set in the Acceptance Filter Mask/ID registers.
*
* The incoming Identifier is masked with the bits in the Acceptance Filter Mask
* Register. This value is compared with the result of masking the bits in the
* Acceptance Filter ID Register with the Acceptance Filter Mask Register. If
* both these values are equal, the message will be stored in the RX FIFO.
*
* Acceptance Filtering is performed by each of the defined acceptance filters.
* If the incoming identifier passes through any acceptance filter then the
* frame is stored in the RX FIFO.
*
* If the Accpetance Filters are not set up then all the received messages are
* stroed in the RX FIFO.
*
* <b>PHY Communication</b>
*
* This driver does not provide any mechanism for directly programming PHY.
*
* <b>Interrupts</b>
*
* The driver has no dependencies on the interrupt controller. The driver
* provides an interrupt handler. User of this driver needs to provide
* callback functions. An interrupt handler example is available with
* the driver.
*
* <b>Threads</b>
*
* This driver is not thread safe. Any needs for threads or thread mutual
* exclusion must be satisfied by the layer above this driver.
*
* <b>Device Reset</b>
*
* Bus Off interrupt that can occur in the device requires a device reset.
* The user is responsible for resetting the device and re-configuring it
* based on its needs (the driver does not save the current configuration).
* When integrating into an RTOS, these reset and re-configure obligations are
* taken care of by the OS adapter software if it exists for that RTOS.
*
* <b>Device Configuration</b>
*
* The device can be configured in various ways during the FPGA implementation
* process. Configuration parameters are stored in the xcanps_g.c files.
* A table is defined where each entry contains configuration information
* for a CAN device. This information includes such things as the base address
* of the memory-mapped device.
*
* <b>Asserts</b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on argument
* values. Asserts can be turned off on a system-wide basis by defining, at
* compile time, the NDEBUG identifier. By default, asserts are turned on and it
* is recommended that users leave asserts on during development.
*
* <b>Building the driver</b>
*
* The XCanPs driver is composed of several source files. This allows the user
* to build and link only those parts of the driver that are necessary.
* <br><br>
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00a xd/sv 01/12/10 First release
* 1.01a bss 12/27/11 Added the APIs XCanPs_SetTxIntrWatermark and
* XCanPs_GetTxIntrWatermark.
* Updated the Register/bit definitions
* Changed XCANPS_RXFWIR_RXFLL_MASK to XCANPS_WIR_FW_MASK
* Changed XCANPS_RXWIR_OFFSET to XCANPS_WIR_OFFSET
* Added XCANPS_IXR_TXFEMP_MASK for Tx Fifo Empty
* Changed XCANPS_IXR_RXFLL_MASK to
* XCANPS_IXR_RXFWMFLL_MASK
* Changed
* XCANPS_TXBUF_ID_OFFSET to XCANPS_TXHPB_ID_OFFSET
* XCANPS_TXBUF_DLC_OFFSET to XCANPS_TXHPB_DLC_OFFSET
* XCANPS_TXBUF_DW1_OFFSET to XCANPS_TXHPB_DW1_OFFSET
* XCANPS_TXBUF_DW2_OFFSET to XCANPS_TXHPB_DW2_OFFSET
* 2.1 adk 23/08/14 Fixed CR:798792 Peripheral test for CANPS IP in
* SDK claims a 40kbps baud rate but it's not.
* 3.0 adk 09/12/14 Added support for Zynq Ultrascale Mp.Also code
* modified for MISRA-C:2012 compliance.
* 3.1 adk 10/11/15 Fixed CR#911958 Add support for Tx Watermark example.
* Data mismatch while sending data less than 8 bytes.
* 3.1 nsk 12/21/15 Updated XCanPs_IntrHandler in xcanps_intr.c to handle
* error interrupts correctly. CR#925615
* </pre>
*
******************************************************************************/
#ifndef XCANPS_H /* prevent circular inclusions */
#define XCANPS_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xstatus.h"
#include "xcanps_hw.h"
#include "xil_types.h"
/************************** Constant Definitions *****************************/
/** @name CAN operation modes
* @{
*/
#define XCANPS_MODE_CONFIG 0x00000001U /**< Configuration mode */
#define XCANPS_MODE_NORMAL 0x00000002U /**< Normal mode */
#define XCANPS_MODE_LOOPBACK 0x00000004U /**< Loop Back mode */
#define XCANPS_MODE_SLEEP 0x00000008U /**< Sleep mode */
#define XCANPS_MODE_SNOOP 0x00000010U /**< Snoop mode */
/* @} */
/** @name Callback identifiers used as parameters to XCanPs_SetHandler()
* @{
*/
#define XCANPS_HANDLER_SEND 1U /**< Handler type for frame sending interrupt */
#define XCANPS_HANDLER_RECV 2U /**< Handler type for frame reception interrupt*/
#define XCANPS_HANDLER_ERROR 3U /**< Handler type for error interrupt */
#define XCANPS_HANDLER_EVENT 4U /**< Handler type for all other interrupts */
/* @} */
/**************************** Type Definitions *******************************/
/**
* This typedef contains configuration information for a device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddr; /**< Register base address */
} XCanPs_Config;
/******************************************************************************/
/**
* Callback type for frame sending and reception interrupts.
*
* @param CallBackRef is a callback reference passed in by the upper layer
* when setting the callback functions, and passed back to the
* upper layer when the callback is invoked.
*******************************************************************************/
typedef void (*XCanPs_SendRecvHandler) (void *CallBackRef);
/******************************************************************************/
/**
* Callback type for error interrupt.
*
* @param CallBackRef is a callback reference passed in by the upper layer
* when setting the callback functions, and passed back to the
* upper layer when the callback is invoked.
* @param ErrorMask is a bit mask indicating the cause of the error. Its
* value equals 'OR'ing one or more XCANPS_ESR_* values defined in
* xcanps_hw.h
*******************************************************************************/
typedef void (*XCanPs_ErrorHandler) (void *CallBackRef, u32 ErrorMask);
/******************************************************************************/
/**
* Callback type for all kinds of interrupts except sending frame interrupt,
* receiving frame interrupt, and error interrupt.
*
* @param CallBackRef is a callback reference passed in by the upper layer
* when setting the callback functions, and passed back to the
* upper layer when the callback is invoked.
* @param Mask is a bit mask indicating the pending interrupts. Its value
* equals 'OR'ing one or more XCANPS_IXR_* defined in xcanps_hw.h
*******************************************************************************/
typedef void (*XCanPs_EventHandler) (void *CallBackRef, u32 Mask);
/**
* The XCanPs driver instance data. The user is required to allocate a
* variable of this type for every CAN device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XCanPs_Config CanConfig; /**< Device configuration */
u32 IsReady; /**< Device is initialized and ready */
/**
* Callback and callback reference for TXOK interrupt.
*/
XCanPs_SendRecvHandler SendHandler;
void *SendRef;
/**
* Callback and callback reference for RXOK/RXNEMP/RXFLL interrupts.
*/
XCanPs_SendRecvHandler RecvHandler;
void *RecvRef;
/**
* Callback and callback reference for ERROR interrupt.
*/
XCanPs_ErrorHandler ErrorHandler;
void *ErrorRef;
/**
* Callback and callback reference for RXOFLW/RXUFLW/TXBFLL/TXFLL/
* Wakeup/Sleep/Bus off/ARBLST interrupts.
*/
XCanPs_EventHandler EventHandler;
void *EventRef;
} XCanPs;
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/**
*
* This macro checks if the transmission is complete.
*
* @param InstancePtr is a pointer to the XCanPs instance.
*
* @return
* - TRUE if the transmission is done.
* - FALSE if the transmission is not done.
*
* @note C-Style signature:
* int XCanPs_IsTxDone(XCanPs *InstancePtr)
*
*******************************************************************************/
#define XCanPs_IsTxDone(InstancePtr) \
(((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \
XCANPS_ISR_OFFSET) & XCANPS_IXR_TXOK_MASK) != (u32)0) ? TRUE : FALSE)
/****************************************************************************/
/**
*
* This macro checks if the transmission FIFO is full.
*
* @param InstancePtr is a pointer to the XCanPs instance.
*
* @return
* - TRUE if TX FIFO is full.
* - FALSE if the TX FIFO is NOT full.
*
* @note C-Style signature:
* int XCanPs_IsTxFifoFull(XCanPs *InstancePtr)
*
*****************************************************************************/
#define XCanPs_IsTxFifoFull(InstancePtr) \
(((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \
XCANPS_SR_OFFSET) & XCANPS_SR_TXFLL_MASK) != (u32)0) ? TRUE : FALSE)
/****************************************************************************/
/**
*
* This macro checks if the Transmission High Priority Buffer is full.
*
* @param InstancePtr is a pointer to the XCanPs instance.
*
* @return
* - TRUE if the TX High Priority Buffer is full.
* - FALSE if the TX High Priority Buffer is NOT full.
*
* @note C-Style signature:
* int XCanPs_IsHighPriorityBufFull(XCanPs *InstancePtr)
*
*****************************************************************************/
#define XCanPs_IsHighPriorityBufFull(InstancePtr) \
(((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \
XCANPS_SR_OFFSET) & XCANPS_SR_TXBFLL_MASK) != (u32)0) ? TRUE : FALSE)
/****************************************************************************/
/**
*
* This macro checks if the receive FIFO is empty.
*
* @param InstancePtr is a pointer to the XCanPs instance.
*
* @return
* - TRUE if RX FIFO is empty.
* - FALSE if the RX FIFO is NOT empty.
*
* @note C-Style signature:
* int XCanPs_IsRxEmpty(XCanPs *InstancePtr)
*
*****************************************************************************/
#define XCanPs_IsRxEmpty(InstancePtr) \
(((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \
XCANPS_ISR_OFFSET) & XCANPS_IXR_RXNEMP_MASK) != (u32)0) ? FALSE : TRUE)
/****************************************************************************/
/**
*
* This macro checks if the CAN device is ready for the driver to change
* Acceptance Filter Identifier Registers (AFIR) and Acceptance Filter Mask
* Registers (AFMR).
*
* AFIR and AFMR for a filter are changeable only after the filter is disabled
* and this routine returns FALSE. The filter can be disabled using the
* XCanPs_AcceptFilterDisable function.
*
* Use the XCanPs_Accept_* functions for configuring the acceptance filters.
*
* @param InstancePtr is a pointer to the XCanPs instance.
*
* @return
* - TRUE if the device is busy and NOT ready to accept writes to
* AFIR and AFMR.
* - FALSE if the device is ready to accept writes to AFIR and
* AFMR.
*
* @note C-Style signature:
* int XCanPs_IsAcceptFilterBusy(XCanPs *InstancePtr)
*
*****************************************************************************/
#define XCanPs_IsAcceptFilterBusy(InstancePtr) \
(((XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr), \
XCANPS_SR_OFFSET) & XCANPS_SR_ACFBSY_MASK) != (u32)0) ? TRUE : FALSE)
/****************************************************************************/
/**
*
* This macro calculates CAN message identifier value given identifier field
* values.
*
* @param StandardId contains Standard Message ID value.
* @param SubRemoteTransReq contains Substitute Remote Transmission
* Request value.
* @param IdExtension contains Identifier Extension value.
* @param ExtendedId contains Extended Message ID value.
* @param RemoteTransReq contains Remote Transmission Request value.
*
* @return Message Identifier value.
*
* @note C-Style signature:
* u32 XCanPs_CreateIdValue(u32 StandardId,
* u32 SubRemoteTransReq,
* u32 IdExtension, u32 ExtendedId,
* u32 RemoteTransReq)
*
* Read the CAN specification for meaning of each parameter.
*
*****************************************************************************/
#define XCanPs_CreateIdValue(StandardId, SubRemoteTransReq, IdExtension, \
ExtendedId, RemoteTransReq) \
((((StandardId) << XCANPS_IDR_ID1_SHIFT) & XCANPS_IDR_ID1_MASK) | \
(((SubRemoteTransReq) << XCANPS_IDR_SRR_SHIFT) & XCANPS_IDR_SRR_MASK)|\
(((IdExtension) << XCANPS_IDR_IDE_SHIFT) & XCANPS_IDR_IDE_MASK) | \
(((ExtendedId) << XCANPS_IDR_ID2_SHIFT) & XCANPS_IDR_ID2_MASK) | \
((RemoteTransReq) & XCANPS_IDR_RTR_MASK))
/****************************************************************************/
/**
*
* This macro calculates value for Data Length Code register given Data
* Length Code value.
*
* @param DataLengCode indicates Data Length Code value.
*
* @return Value that can be assigned to Data Length Code register.
*
* @note C-Style signature:
* u32 XCanPs_CreateDlcValue(u32 DataLengCode)
*
* Read the CAN specification for meaning of Data Length Code.
*
*****************************************************************************/
#define XCanPs_CreateDlcValue(DataLengCode) \
(((DataLengCode) << XCANPS_DLCR_DLC_SHIFT) & XCANPS_DLCR_DLC_MASK)
/****************************************************************************/
/**
*
* This macro clears the timestamp in the Timestamp Control Register.
*
* @param InstancePtr is a pointer to the XCanPs instance.
*
* @return None.
*
* @note C-Style signature:
* void XCanPs_ClearTimestamp(XCanPs *InstancePtr)
*
*****************************************************************************/
#define XCanPs_ClearTimestamp(InstancePtr) \
XCanPs_WriteReg((InstancePtr)->CanConfig.BaseAddr, \
XCANPS_TCR_OFFSET, XCANPS_TCR_CTS_MASK)
/************************** Function Prototypes ******************************/
/*
* Functions in xcanps.c
*/
s32 XCanPs_CfgInitialize(XCanPs *InstancePtr, XCanPs_Config *ConfigPtr,
u32 EffectiveAddr);
void XCanPs_Reset(XCanPs *InstancePtr);
u8 XCanPs_GetMode(XCanPs *InstancePtr);
void XCanPs_EnterMode(XCanPs *InstancePtr, u8 OperationMode);
u32 XCanPs_GetStatus(XCanPs *InstancePtr);
void XCanPs_GetBusErrorCounter(XCanPs *InstancePtr, u8 *RxErrorCount,
u8 *TxErrorCount);
u32 XCanPs_GetBusErrorStatus(XCanPs *InstancePtr);
void XCanPs_ClearBusErrorStatus(XCanPs *InstancePtr, u32 Mask);
s32 XCanPs_Send(XCanPs *InstancePtr, u32 *FramePtr);
s32 XCanPs_Recv(XCanPs *InstancePtr, u32 *FramePtr);
s32 XCanPs_SendHighPriority(XCanPs *InstancePtr, u32 *FramePtr);
void XCanPs_AcceptFilterEnable(XCanPs *InstancePtr, u32 FilterIndexes);
void XCanPs_AcceptFilterDisable(XCanPs *InstancePtr, u32 FilterIndexes);
u32 XCanPs_AcceptFilterGetEnabled(XCanPs *InstancePtr);
s32 XCanPs_AcceptFilterSet(XCanPs *InstancePtr, u32 FilterIndex,
u32 MaskValue, u32 IdValue);
void XCanPs_AcceptFilterGet(XCanPs *InstancePtr, u32 FilterIndex,
u32 *MaskValue, u32 *IdValue);
s32 XCanPs_SetBaudRatePrescaler(XCanPs *InstancePtr, u8 Prescaler);
u8 XCanPs_GetBaudRatePrescaler(XCanPs *InstancePtr);
s32 XCanPs_SetBitTiming(XCanPs *InstancePtr, u8 SyncJumpWidth,
u8 TimeSegment2, u8 TimeSegment1);
void XCanPs_GetBitTiming(XCanPs *InstancePtr, u8 *SyncJumpWidth,
u8 *TimeSegment2, u8 *TimeSegment1);
s32 XCanPs_SetRxIntrWatermark(XCanPs *InstancePtr, u8 Threshold);
u8 XCanPs_GetRxIntrWatermark(XCanPs *InstancePtr);
s32 XCanPs_SetTxIntrWatermark(XCanPs *InstancePtr, u8 Threshold);
u8 XCanPs_GetTxIntrWatermark(XCanPs *InstancePtr);
/*
* Diagnostic functions in xcanps_selftest.c
*/
s32 XCanPs_SelfTest(XCanPs *InstancePtr);
/*
* Functions in xcanps_intr.c
*/
void XCanPs_IntrEnable(XCanPs *InstancePtr, u32 Mask);
void XCanPs_IntrDisable(XCanPs *InstancePtr, u32 Mask);
u32 XCanPs_IntrGetEnabled(XCanPs *InstancePtr);
u32 XCanPs_IntrGetStatus(XCanPs *InstancePtr);
void XCanPs_IntrClear(XCanPs *InstancePtr, u32 Mask);
void XCanPs_IntrHandler(void *InstancePtr);
s32 XCanPs_SetHandler(XCanPs *InstancePtr, u32 HandlerType,
void *CallBackFunc, void *CallBackRef);
/*
* Functions in xcanps_sinit.c
*/
XCanPs_Config *XCanPs_LookupConfig(u16 DeviceId);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,55 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the Software), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in
*all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
*(a) running on a Xilinx device, or
*(b) that interact with a Xilinx device through a bus or interconnect.
*
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the Xilinx shall not be used
*in advertising or otherwise to promote the sale, use or other dealings in
*this Software without prior written authorization from Xilinx.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xcanps.h"
/*
* The configuration table for devices
*/
XCanPs_Config XCanPs_ConfigTable[] =
{
{
XPAR_PSU_CAN_1_DEVICE_ID,
XPAR_PSU_CAN_1_BASEADDR
}
};

View file

@ -0,0 +1,93 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcanps_hw.c
* @addtogroup canps_v3_0
* @{
*
* This file contains the implementation of the canps interface reset sequence
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.02a adk 08/08/13 First release
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xcanps_hw.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/**
*
* This function resets the CAN device. Calling this function resets the device
* immediately, and any pending transmission or reception is terminated at once.
* Both Object Layer and Transfer Layer are reset. This function does not reset
* the Physical Layer. All registers are reset to the default values, and no
* previous status will be restored. TX FIFO, RX FIFO and TX High Priority
* Buffer are also reset.
*
* The CAN device will be in Configuration Mode immediately after this function
* returns.
*
* @param BaseAddr is the baseaddress of the interface.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCanPs_ResetHw(u32 BaseAddr)
{
XCanPs_WriteReg(BaseAddr, XCANPS_SRR_OFFSET, \
XCANPS_SRR_SRST_MASK);
}
/** @} */

View file

@ -0,0 +1,369 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcanps_hw.h
* @addtogroup canps_v3_0
* @{
*
* This header file contains the identifiers and basic driver functions (or
* macros) that can be used to access the device. Other driver functions
* are defined in xcanps.h.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00a xd/sv 01/12/10 First release
* 1.01a sbs 12/27/11 Updated the Register/bit definitions
* Changed XCANPS_RXFWIR_RXFLL_MASK to XCANPS_WIR_FW_MASK
* Changed XCANPS_RXWIR_OFFSET to XCANPS_WIR_OFFSET
* Added XCANPS_IXR_TXFEMP_MASK for Tx Fifo Empty
* Changed XCANPS_IXR_RXFLL_MASK to
* XCANPS_IXR_RXFWMFLL_MASK
* Changed
* XCANPS_TXBUF_ID_OFFSET to XCANPS_TXHPB_ID_OFFSET
* XCANPS_TXBUF_DLC_OFFSET to XCANPS_TXHPB_DLC_OFFSET
* XCANPS_TXBUF_DW1_OFFSET to XCANPS_TXHPB_DW1_OFFSET
* XCANPS_TXBUF_DW2_OFFSET to XCANPS_TXHPB_DW2_OFFSET
* 1.02a adk 08/08/13 Updated for inclding the function prototype
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* </pre>
*
******************************************************************************/
#ifndef XCANPS_HW_H /* prevent circular inclusions */
#define XCANPS_HW_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/** @name Register offsets for the CAN. Each register is 32 bits.
* @{
*/
#define XCANPS_SRR_OFFSET 0x00000000U /**< Software Reset Register */
#define XCANPS_MSR_OFFSET 0x00000004U /**< Mode Select Register */
#define XCANPS_BRPR_OFFSET 0x00000008U /**< Baud Rate Prescaler */
#define XCANPS_BTR_OFFSET 0x0000000CU /**< Bit Timing Register */
#define XCANPS_ECR_OFFSET 0x00000010U /**< Error Counter Register */
#define XCANPS_ESR_OFFSET 0x00000014U /**< Error Status Register */
#define XCANPS_SR_OFFSET 0x00000018U /**< Status Register */
#define XCANPS_ISR_OFFSET 0x0000001CU /**< Interrupt Status Register */
#define XCANPS_IER_OFFSET 0x00000020U /**< Interrupt Enable Register */
#define XCANPS_ICR_OFFSET 0x00000024U /**< Interrupt Clear Register */
#define XCANPS_TCR_OFFSET 0x00000028U /**< Timestamp Control Register */
#define XCANPS_WIR_OFFSET 0x0000002CU /**< Watermark Interrupt Reg */
#define XCANPS_TXFIFO_ID_OFFSET 0x00000030U /**< TX FIFO ID */
#define XCANPS_TXFIFO_DLC_OFFSET 0x00000034U /**< TX FIFO DLC */
#define XCANPS_TXFIFO_DW1_OFFSET 0x00000038U /**< TX FIFO Data Word 1 */
#define XCANPS_TXFIFO_DW2_OFFSET 0x0000003CU /**< TX FIFO Data Word 2 */
#define XCANPS_TXHPB_ID_OFFSET 0x00000040U /**< TX High Priority Buffer ID */
#define XCANPS_TXHPB_DLC_OFFSET 0x00000044U /**< TX High Priority Buffer DLC */
#define XCANPS_TXHPB_DW1_OFFSET 0x00000048U /**< TX High Priority Buf Data 1 */
#define XCANPS_TXHPB_DW2_OFFSET 0x0000004CU /**< TX High Priority Buf Data Word 2 */
#define XCANPS_RXFIFO_ID_OFFSET 0x00000050U /**< RX FIFO ID */
#define XCANPS_RXFIFO_DLC_OFFSET 0x00000054U /**< RX FIFO DLC */
#define XCANPS_RXFIFO_DW1_OFFSET 0x00000058U /**< RX FIFO Data Word 1 */
#define XCANPS_RXFIFO_DW2_OFFSET 0x0000005CU /**< RX FIFO Data Word 2 */
#define XCANPS_AFR_OFFSET 0x00000060U /**< Acceptance Filter Register */
#define XCANPS_AFMR1_OFFSET 0x00000064U /**< Acceptance Filter Mask 1 */
#define XCANPS_AFIR1_OFFSET 0x00000068U /**< Acceptance Filter ID 1 */
#define XCANPS_AFMR2_OFFSET 0x0000006CU /**< Acceptance Filter Mask 2 */
#define XCANPS_AFIR2_OFFSET 0x00000070U /**< Acceptance Filter ID 2 */
#define XCANPS_AFMR3_OFFSET 0x00000074U /**< Acceptance Filter Mask 3 */
#define XCANPS_AFIR3_OFFSET 0x00000078U /**< Acceptance Filter ID 3 */
#define XCANPS_AFMR4_OFFSET 0x0000007CU /**< Acceptance Filter Mask 4 */
#define XCANPS_AFIR4_OFFSET 0x00000080U /**< Acceptance Filter ID 4 */
/* @} */
/** @name Software Reset Register (SRR) Bit Definitions and Masks
* @{
*/
#define XCANPS_SRR_CEN_MASK 0x00000002U /**< Can Enable */
#define XCANPS_SRR_SRST_MASK 0x00000001U /**< Reset */
/* @} */
/** @name Mode Select Register (MSR) Bit Definitions and Masks
* @{
*/
#define XCANPS_MSR_SNOOP_MASK 0x00000004U /**< Snoop Mode Select */
#define XCANPS_MSR_LBACK_MASK 0x00000002U /**< Loop Back Mode Select */
#define XCANPS_MSR_SLEEP_MASK 0x00000001U /**< Sleep Mode Select */
/* @} */
/** @name Baud Rate Prescaler register (BRPR) Bit Definitions and Masks
* @{
*/
#define XCANPS_BRPR_BRP_MASK 0x000000FFU /**< Baud Rate Prescaler */
/* @} */
/** @name Bit Timing Register (BTR) Bit Definitions and Masks
* @{
*/
#define XCANPS_BTR_SJW_MASK 0x00000180U /**< Synchronization Jump Width */
#define XCANPS_BTR_SJW_SHIFT 7U
#define XCANPS_BTR_TS2_MASK 0x00000070U /**< Time Segment 2 */
#define XCANPS_BTR_TS2_SHIFT 4U
#define XCANPS_BTR_TS1_MASK 0x0000000FU /**< Time Segment 1 */
/* @} */
/** @name Error Counter Register (ECR) Bit Definitions and Masks
* @{
*/
#define XCANPS_ECR_REC_MASK 0x0000FF00U /**< Receive Error Counter */
#define XCANPS_ECR_REC_SHIFT 8U
#define XCANPS_ECR_TEC_MASK 0x000000FFU /**< Transmit Error Counter */
/* @} */
/** @name Error Status Register (ESR) Bit Definitions and Masks
* @{
*/
#define XCANPS_ESR_ACKER_MASK 0x00000010U /**< ACK Error */
#define XCANPS_ESR_BERR_MASK 0x00000008U /**< Bit Error */
#define XCANPS_ESR_STER_MASK 0x00000004U /**< Stuff Error */
#define XCANPS_ESR_FMER_MASK 0x00000002U /**< Form Error */
#define XCANPS_ESR_CRCER_MASK 0x00000001U /**< CRC Error */
/* @} */
/** @name Status Register (SR) Bit Definitions and Masks
* @{
*/
#define XCANPS_SR_SNOOP_MASK 0x00001000U /**< Snoop Mask */
#define XCANPS_SR_ACFBSY_MASK 0x00000800U /**< Acceptance Filter busy */
#define XCANPS_SR_TXFLL_MASK 0x00000400U /**< TX FIFO is full */
#define XCANPS_SR_TXBFLL_MASK 0x00000200U /**< TX High Priority Buffer full */
#define XCANPS_SR_ESTAT_MASK 0x00000180U /**< Error Status */
#define XCANPS_SR_ESTAT_SHIFT 7U
#define XCANPS_SR_ERRWRN_MASK 0x00000040U /**< Error Warning */
#define XCANPS_SR_BBSY_MASK 0x00000020U /**< Bus Busy */
#define XCANPS_SR_BIDLE_MASK 0x00000010U /**< Bus Idle */
#define XCANPS_SR_NORMAL_MASK 0x00000008U /**< Normal Mode */
#define XCANPS_SR_SLEEP_MASK 0x00000004U /**< Sleep Mode */
#define XCANPS_SR_LBACK_MASK 0x00000002U /**< Loop Back Mode */
#define XCANPS_SR_CONFIG_MASK 0x00000001U /**< Configuration Mode */
/* @} */
/** @name Interrupt Status/Enable/Clear Register Bit Definitions and Masks
* @{
*/
#define XCANPS_IXR_TXFEMP_MASK 0x00004000U /**< Tx Fifo Empty Interrupt */
#define XCANPS_IXR_TXFWMEMP_MASK 0x00002000U /**< Tx Fifo Watermark Empty */
#define XCANPS_IXR_RXFWMFLL_MASK 0x00001000U /**< Rx FIFO Watermark Full */
#define XCANPS_IXR_WKUP_MASK 0x00000800U /**< Wake up Interrupt */
#define XCANPS_IXR_SLP_MASK 0x00000400U /**< Sleep Interrupt */
#define XCANPS_IXR_BSOFF_MASK 0x00000200U /**< Bus Off Interrupt */
#define XCANPS_IXR_ERROR_MASK 0x00000100U /**< Error Interrupt */
#define XCANPS_IXR_RXNEMP_MASK 0x00000080U /**< RX FIFO Not Empty Interrupt */
#define XCANPS_IXR_RXOFLW_MASK 0x00000040U /**< RX FIFO Overflow Interrupt */
#define XCANPS_IXR_RXUFLW_MASK 0x00000020U /**< RX FIFO Underflow Interrupt */
#define XCANPS_IXR_RXOK_MASK 0x00000010U /**< New Message Received Intr */
#define XCANPS_IXR_TXBFLL_MASK 0x00000008U /**< TX High Priority Buf Full */
#define XCANPS_IXR_TXFLL_MASK 0x00000004U /**< TX FIFO Full Interrupt */
#define XCANPS_IXR_TXOK_MASK 0x00000002U /**< TX Successful Interrupt */
#define XCANPS_IXR_ARBLST_MASK 0x00000001U /**< Arbitration Lost Interrupt */
#define XCANPS_IXR_ALL ((u32)XCANPS_IXR_RXFWMFLL_MASK | \
(u32)XCANPS_IXR_WKUP_MASK | \
(u32)XCANPS_IXR_SLP_MASK | \
(u32)XCANPS_IXR_BSOFF_MASK | \
(u32)XCANPS_IXR_ERROR_MASK | \
(u32)XCANPS_IXR_RXNEMP_MASK | \
(u32)XCANPS_IXR_RXOFLW_MASK | \
(u32)XCANPS_IXR_RXUFLW_MASK | \
(u32)XCANPS_IXR_RXOK_MASK | \
(u32)XCANPS_IXR_TXBFLL_MASK | \
(u32)XCANPS_IXR_TXFLL_MASK | \
(u32)XCANPS_IXR_TXOK_MASK | \
(u32)XCANPS_IXR_ARBLST_MASK)
/* @} */
/** @name CAN Timestamp Control Register (TCR) Bit Definitions and Masks
* @{
*/
#define XCANPS_TCR_CTS_MASK 0x00000001U /**< Clear Timestamp counter mask */
/* @} */
/** @name CAN Watermark Register (WIR) Bit Definitions and Masks
* @{
*/
#define XCANPS_WIR_FW_MASK 0x0000003FU /**< Rx Full Threshold mask */
#define XCANPS_WIR_EW_MASK 0x00003F00U /**< Tx Empty Threshold mask */
#define XCANPS_WIR_EW_SHIFT 0x00000008U /**< Tx Empty Threshold shift */
/* @} */
/** @name CAN Frame Identifier (TX High Priority Buffer/TX/RX/Acceptance Filter
Mask/Acceptance Filter ID)
* @{
*/
#define XCANPS_IDR_ID1_MASK 0xFFE00000U /**< Standard Messg Identifier */
#define XCANPS_IDR_ID1_SHIFT 21U
#define XCANPS_IDR_SRR_MASK 0x00100000U /**< Substitute Remote TX Req */
#define XCANPS_IDR_SRR_SHIFT 20U
#define XCANPS_IDR_IDE_MASK 0x00080000U /**< Identifier Extension */
#define XCANPS_IDR_IDE_SHIFT 19U
#define XCANPS_IDR_ID2_MASK 0x0007FFFEU /**< Extended Message Ident */
#define XCANPS_IDR_ID2_SHIFT 1U
#define XCANPS_IDR_RTR_MASK 0x00000001U /**< Remote TX Request */
/* @} */
/** @name CAN Frame Data Length Code (TX High Priority Buffer/TX/RX)
* @{
*/
#define XCANPS_DLCR_DLC_MASK 0xF0000000U /**< Data Length Code */
#define XCANPS_DLCR_DLC_SHIFT 28U
#define XCANPS_DLCR_TIMESTAMP_MASK 0x0000FFFFU /**< Timestamp Mask (Rx only) */
/* @} */
/** @name CAN Frame Data Word 1 (TX High Priority Buffer/TX/RX)
* @{
*/
#define XCANPS_DW1R_DB0_MASK 0xFF000000U /**< Data Byte 0 */
#define XCANPS_DW1R_DB0_SHIFT 24U
#define XCANPS_DW1R_DB1_MASK 0x00FF0000U /**< Data Byte 1 */
#define XCANPS_DW1R_DB1_SHIFT 16U
#define XCANPS_DW1R_DB2_MASK 0x0000FF00U /**< Data Byte 2 */
#define XCANPS_DW1R_DB2_SHIFT 8U
#define XCANPS_DW1R_DB3_MASK 0x000000FFU /**< Data Byte 3 */
/* @} */
/** @name CAN Frame Data Word 2 (TX High Priority Buffer/TX/RX)
* @{
*/
#define XCANPS_DW2R_DB4_MASK 0xFF000000U /**< Data Byte 4 */
#define XCANPS_DW2R_DB4_SHIFT 24U
#define XCANPS_DW2R_DB5_MASK 0x00FF0000U /**< Data Byte 5 */
#define XCANPS_DW2R_DB5_SHIFT 16U
#define XCANPS_DW2R_DB6_MASK 0x0000FF00U /**< Data Byte 6 */
#define XCANPS_DW2R_DB6_SHIFT 8U
#define XCANPS_DW2R_DB7_MASK 0x000000FFU /**< Data Byte 7 */
/* @} */
/** @name Acceptance Filter Register (AFR) Bit Definitions and Masks
* @{
*/
#define XCANPS_AFR_UAF4_MASK 0x00000008U /**< Use Acceptance Filter No.4 */
#define XCANPS_AFR_UAF3_MASK 0x00000004U /**< Use Acceptance Filter No.3 */
#define XCANPS_AFR_UAF2_MASK 0x00000002U /**< Use Acceptance Filter No.2 */
#define XCANPS_AFR_UAF1_MASK 0x00000001U /**< Use Acceptance Filter No.1 */
#define XCANPS_AFR_UAF_ALL_MASK ((u32)XCANPS_AFR_UAF4_MASK | \
(u32)XCANPS_AFR_UAF3_MASK | \
(u32)XCANPS_AFR_UAF2_MASK | \
(u32)XCANPS_AFR_UAF1_MASK)
/* @} */
/** @name CAN frame length constants
* @{
*/
#define XCANPS_MAX_FRAME_SIZE sizeof(u32)*16U /**< Maximum CAN frame length in bytes */
/* @} */
/* For backwards compatibilty */
#define XCANPS_TXBUF_ID_OFFSET XCANPS_TXHPB_ID_OFFSET
#define XCANPS_TXBUF_DLC_OFFSET XCANPS_TXHPB_DLC_OFFSET
#define XCANPS_TXBUF_DW1_OFFSET XCANPS_TXHPB_DW1_OFFSET
#define XCANPS_TXBUF_DW2_OFFSET XCANPS_TXHPB_DW2_OFFSET
#define XCANPS_RXFWIR_RXFLL_MASK XCANPS_WIR_FW_MASK
#define XCANPS_RXWIR_OFFSET XCANPS_WIR_OFFSET
#define XCANPS_IXR_RXFLL_MASK XCANPS_IXR_RXFWMFLL_MASK
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/**
*
* This macro reads the given register.
*
* @param BaseAddr is the base address of the device.
* @param RegOffset is the register offset to be read.
*
* @return The 32-bit value of the register
*
* @note None.
*
*****************************************************************************/
#define XCanPs_ReadReg(BaseAddr, RegOffset) \
Xil_In32((BaseAddr) + (u32)(RegOffset))
/****************************************************************************/
/**
*
* This macro writes the given register.
*
* @param BaseAddr is the base address of the device.
* @param RegOffset is the register offset to be written.
* @param Data is the 32-bit value to write to the register.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
#define XCanPs_WriteReg(BaseAddr, RegOffset, Data) \
Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data))
/************************** Function Prototypes ******************************/
/*
* Perform reset operation to the CanPs interface
*/
void XCanPs_ResetHw(u32 BaseAddr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,421 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcanps_intr.c
* @addtogroup canps_v3_0
* @{
*
* This file contains functions related to CAN interrupt handling.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00a xd/sv 01/12/10 First release
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.1 nsk 12/21/15 Updated XCanPs_IntrHandler to handle error
* interrupts correctly. CR#925615
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xcanps.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
/****************************************************************************/
/**
*
* This routine enables interrupt(s). Use the XCANPS_IXR_* constants defined in
* xcanps_hw.h to create the bit-mask to enable interrupts.
*
* @param InstancePtr is a pointer to the XCanPs instance.
* @param Mask is the mask to enable. Bit positions of 1 will be enabled.
* Bit positions of 0 will keep the previous setting. This mask is
* formed by OR'ing XCANPS_IXR_* bits defined in xcanps_hw.h.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XCanPs_IntrEnable(XCanPs *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Write to the IER to enable the specified interrupts.
*/
IntrValue = XCanPs_IntrGetEnabled(InstancePtr);
IntrValue |= Mask;
XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
XCANPS_IER_OFFSET, IntrValue);
}
/****************************************************************************/
/**
*
* This routine disables interrupt(s). Use the XCANPS_IXR_* constants defined in
* xcanps_hw.h to create the bit-mask to disable interrupt(s).
*
* @param InstancePtr is a pointer to the XCanPs instance.
* @param Mask is the mask to disable. Bit positions of 1 will be
* disabled. Bit positions of 0 will keep the previous setting.
* This mask is formed by OR'ing XCANPS_IXR_* bits defined in
* xcanps_hw.h.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XCanPs_IntrDisable(XCanPs *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Write to the IER to disable the specified interrupts.
*/
IntrValue = XCanPs_IntrGetEnabled(InstancePtr);
IntrValue &= ~Mask;
XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr,
XCANPS_IER_OFFSET, IntrValue);
}
/****************************************************************************/
/**
*
* This routine returns enabled interrupt(s). Use the XCANPS_IXR_* constants
* defined in xcanps_hw.h to interpret the returned value.
*
* @param InstancePtr is a pointer to the XCanPs instance.
*
* @return Enabled interrupt(s) in a 32-bit format.
*
* @note None.
*
*****************************************************************************/
u32 XCanPs_IntrGetEnabled(XCanPs *InstancePtr)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
XCANPS_IER_OFFSET);
}
/****************************************************************************/
/**
*
* This routine returns interrupt status read from Interrupt Status Register.
* Use the XCANPS_IXR_* constants defined in xcanps_hw.h to interpret the
* returned value.
*
* @param InstancePtr is a pointer to the XCanPs instance.
*
* @return The value stored in Interrupt Status Register.
*
* @note None.
*
*****************************************************************************/
u32 XCanPs_IntrGetStatus(XCanPs *InstancePtr)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
return XCanPs_ReadReg(InstancePtr->CanConfig.BaseAddr,
XCANPS_ISR_OFFSET);
}
/****************************************************************************/
/**
*
* This function clears interrupt(s). Every bit set in Interrupt Status
* Register indicates that a specific type of interrupt is occurring, and this
* function clears one or more interrupts by writing a bit mask to Interrupt
* Clear Register.
*
* @param InstancePtr is a pointer to the XCanPs instance.
* @param Mask is the mask to clear. Bit positions of 1 will be cleared.
* Bit positions of 0 will not change the previous interrupt
* status. This mask is formed by OR'ing XCANPS_IXR_* bits defined
* in xcanps_hw.h.
*
* @note None.
*
*****************************************************************************/
void XCanPs_IntrClear(XCanPs *InstancePtr, u32 Mask)
{
u32 IntrValue;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Clear the currently pending interrupts.
*/
IntrValue = XCanPs_IntrGetStatus(InstancePtr);
IntrValue &= Mask;
XCanPs_WriteReg(InstancePtr->CanConfig.BaseAddr, XCANPS_ICR_OFFSET,
IntrValue);
}
/*****************************************************************************/
/**
*
* This routine is the interrupt handler for the CAN driver.
*
* This handler reads the interrupt status from the ISR, determines the source of
* the interrupts, calls according callbacks, and finally clears the interrupts.
*
* Application beyond this driver is responsible for providing callbacks to
* handle interrupts and installing the callbacks using XCanPs_SetHandler()
* during initialization phase. An example delivered with this driver
* demonstrates how this could be done.
*
* @param InstancePtr is a pointer to the XCanPs instance that just
* interrupted.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCanPs_IntrHandler(void *InstancePtr)
{
u32 PendingIntr;
u32 EventIntr;
u32 ErrorStatus;
XCanPs *CanPtr = (XCanPs *) ((void *)InstancePtr);
Xil_AssertVoid(CanPtr != NULL);
Xil_AssertVoid(CanPtr->IsReady == XIL_COMPONENT_IS_READY);
PendingIntr = XCanPs_IntrGetStatus(CanPtr);
PendingIntr &= XCanPs_IntrGetEnabled(CanPtr);
/*
* Clear all pending interrupts.
* Rising Edge interrupt
*/
XCanPs_IntrClear(CanPtr, PendingIntr);
/*
* An error interrupt is occurring.
*/
if (((PendingIntr & XCANPS_IXR_ERROR_MASK) != (u32)0) &&
(CanPtr->ErrorHandler != NULL)) {
ErrorStatus = XCanPs_GetBusErrorStatus(CanPtr);
CanPtr->ErrorHandler(CanPtr->ErrorRef,ErrorStatus);
/*
* Clear Error Status Register.
*/
XCanPs_ClearBusErrorStatus(CanPtr,ErrorStatus);
}
/*
* Check if any following event interrupt is pending:
* - RX FIFO Overflow
* - RX FIFO Underflow
* - TX High Priority Buffer full
* - TX FIFO Full
* - Wake up from sleep mode
* - Enter sleep mode
* - Enter Bus off status
* - Arbitration is lost
*
* If so, call event callback provided by upper level.
*/
EventIntr = PendingIntr & ((u32)XCANPS_IXR_RXOFLW_MASK |
(u32)XCANPS_IXR_RXUFLW_MASK |
(u32)XCANPS_IXR_TXBFLL_MASK |
(u32)XCANPS_IXR_TXFLL_MASK |
(u32)XCANPS_IXR_WKUP_MASK |
(u32)XCANPS_IXR_SLP_MASK |
(u32)XCANPS_IXR_BSOFF_MASK |
(u32)XCANPS_IXR_ARBLST_MASK);
if ((EventIntr != (u32)0) && (CanPtr->EventHandler != NULL)) {
CanPtr->EventHandler(CanPtr->EventRef, EventIntr);
if ((EventIntr & XCANPS_IXR_BSOFF_MASK) != (u32)0) {
/*
* Event callback should reset whole device if "Enter
* Bus Off Status" interrupt occurred. All pending
* interrupts are cleared and no further checking and
* handling of other interrupts is needed any more.
*/
return;
} else {
/*This else was made for misra-c compliance*/
;
}
}
if (((PendingIntr & (XCANPS_IXR_RXFWMFLL_MASK |
XCANPS_IXR_RXNEMP_MASK)) != (u32)0) &&
(CanPtr->RecvHandler != NULL)) {
/*
* This case happens when
* A number of frames depending on the Rx FIFO Watermark
* threshold are received.
* And also when frame was received and is sitting in RX FIFO.
*
* XCANPS_IXR_RXOK_MASK is not used because the bit is set
* just once even if there are multiple frames sitting
* in the RX FIFO.
*
* XCANPS_IXR_RXNEMP_MASK is used because the bit can be
* set again and again automatically as long as there is
* at least one frame in RX FIFO.
*/
CanPtr->RecvHandler(CanPtr->RecvRef);
}
/*
* A frame was transmitted successfully.
*/
if (((PendingIntr & (XCANPS_IXR_TXOK_MASK | XCANPS_IXR_TXFWMEMP_MASK)) != (u32)0) &&
(CanPtr->SendHandler != NULL)) {
CanPtr->SendHandler(CanPtr->SendRef);
}
}
/*****************************************************************************/
/**
*
* This routine installs an asynchronous callback function for the given
* HandlerType:
*
* <pre>
* HandlerType Callback Function Type
* ----------------------- ------------------------
* XCANPS_HANDLER_SEND XCanPs_SendRecvHandler
* XCANPS_HANDLER_RECV XCanPs_SendRecvHandler
* XCANPS_HANDLER_ERROR XCanPs_ErrorHandler
* XCANPS_HANDLER_EVENT XCanPs_EventHandler
*
* HandlerType Invoked by this driver when:
* -------------------------------------------------------------------------
* XCANPS_HANDLER_SEND A frame transmitted by a call to
* XCanPs_Send() has been sent successfully.
*
* XCANPS_HANDLER_RECV A frame(s) has been received and is sitting in
* the RX FIFO.
*
* XCANPS_HANDLER_ERROR An error interrupt is occurring.
*
* XCANPS_HANDLER_EVENT Any other kind of interrupt is occurring.
* </pre>
*
* @param InstancePtr is a pointer to the XCanPs instance.
* @param HandlerType specifies which handler is to be attached.
* @param CallBackFunc is the address of the callback function.
* @param CallBackRef is a user data item that will be passed to the
* callback function when it is invoked.
*
* @return
* - XST_SUCCESS when handler is installed.
* - XST_INVALID_PARAM when HandlerType is invalid.
*
* @note
* Invoking this function for a handler that already has been installed replaces
* it with the new handler.
*
******************************************************************************/
s32 XCanPs_SetHandler(XCanPs *InstancePtr, u32 HandlerType,
void *CallBackFunc, void *CallBackRef)
{
s32 Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
switch (HandlerType) {
case XCANPS_HANDLER_SEND:
InstancePtr->SendHandler =
(XCanPs_SendRecvHandler) CallBackFunc;
InstancePtr->SendRef = CallBackRef;
Status = XST_SUCCESS;
break;
case XCANPS_HANDLER_RECV:
InstancePtr->RecvHandler =
(XCanPs_SendRecvHandler) CallBackFunc;
InstancePtr->RecvRef = CallBackRef;
Status = XST_SUCCESS;
break;
case XCANPS_HANDLER_ERROR:
InstancePtr->ErrorHandler =
(XCanPs_ErrorHandler) CallBackFunc;
InstancePtr->ErrorRef = CallBackRef;
Status = XST_SUCCESS;
break;
case XCANPS_HANDLER_EVENT:
InstancePtr->EventHandler =
(XCanPs_EventHandler) CallBackFunc;
InstancePtr->EventRef = CallBackRef;
Status = XST_SUCCESS;
break;
default:
Status = XST_INVALID_PARAM;
break;
}
return Status;
}
/** @} */

View file

@ -0,0 +1,234 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcanps_selftest.c
* @addtogroup canps_v3_0
* @{
*
* This file contains a diagnostic self-test function for the XCanPs driver.
*
* Read xcanps.h file for more information.
*
* @note
* The Baud Rate Prescaler Register (BRPR) and Bit Timing Register(BTR)
* are setup such that CAN baud rate equals 40Kbps, given the CAN clock
* equal to 24MHz. These need to be changed based on the desired baudrate
* and CAN clock frequency.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00a xd/sv 01/12/10 First release
* 2.1 adk 23/08/14 Fixed CR:798792 Peripheral test for CANPS IP in
* SDK claims a 40kbps baud rate but it's not.
* 3.00 kvn 02/13/15 Modified code for MISRA_C:2012 compliance.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xstatus.h"
#include "xcanps.h"
/************************** Constant Definitions ****************************/
#define XCANPS_MAX_FRAME_SIZE_IN_WORDS ((XCANPS_MAX_FRAME_SIZE) / (sizeof(u32)))
#define FRAME_DATA_LENGTH 8U /* Frame Data field length */
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/*
* Buffers to hold frames to send and receive. These are declared as global so
* that they are not on the stack.
*/
static u32 TxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS];
static u32 RxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS];
/************************** Function Prototypes *****************************/
/*****************************************************************************/
/**
*
* This function runs a self-test on the CAN driver/device. The test resets
* the device, sets up the Loop Back mode, sends a standard frame, receives the
* frame, verifies the contents, and resets the device again.
*
* Note that this is a destructive test in that resets of the device are
* performed. Refer the device specification for the device status after
* the reset operation.
*
*
* @param InstancePtr is a pointer to the XCanPs instance.
*
* @return
* - XST_SUCCESS if the self-test passed. i.e., the frame
* received via the internal loop back has the same contents as
* the frame sent.
* - XST_FAILURE Otherwise.
*
* @note
*
* If the CAN device does not work properly, this function may enter an
* infinite loop and will never return to the caller.
* <br><br>
* If XST_FAILURE is returned, the device is not reset so that the caller could
* have a chance to check reason(s) causing the failure.
*
******************************************************************************/
s32 XCanPs_SelfTest(XCanPs *InstancePtr)
{
u8 *FramePtr;
s32 Status;
u32 Index;
u8 GetModeResult;
u32 RxEmptyResult;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
XCanPs_Reset(InstancePtr);
/*
* The device should enter Configuration Mode immediately after
* reset above is finished. Now check the mode and return error code if
* it is not Configuration Mode.
*/
if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
Status = XST_FAILURE;
return Status;
}
/*
* Setup Baud Rate Prescaler Register (BRPR) and Bit Timing Register
* (BTR) such that CAN baud rate equals 40Kbps, given the CAN clock
* equal to 24MHz. For more information see the CAN 2.0A, CAN 2.0B,
* ISO 11898-1 specifications.
*/
(void)XCanPs_SetBaudRatePrescaler(InstancePtr, (u8)29U);
(void)XCanPs_SetBitTiming(InstancePtr, (u8)3U, (u8)2U, (u8)15U);
/*
* Enter the loop back mode.
*/
XCanPs_EnterMode(InstancePtr, XCANPS_MODE_LOOPBACK);
GetModeResult = XCanPs_GetMode(InstancePtr);
while (GetModeResult != ((u8)XCANPS_MODE_LOOPBACK)) {
GetModeResult = XCanPs_GetMode(InstancePtr);
}
/*
* Create a frame to send with known values so we can verify them
* on receive.
*/
TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)2000U, (u32)0U, (u32)0U, (u32)0U, (u32)0U);
TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)8U);
FramePtr = (u8 *)((void *)(&TxFrame[2]));
for (Index = 0U; Index < 8U; Index++) {
if(*FramePtr != 0U) {
*FramePtr = (u8)Index;
*FramePtr++;
}
}
/*
* Send the frame.
*/
Status = XCanPs_Send(InstancePtr, TxFrame);
if (Status != (s32)XST_SUCCESS) {
Status = XST_FAILURE;
return Status;
}
/*
* Wait until the frame arrives RX FIFO via internal loop back.
*/
RxEmptyResult = XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr),
XCANPS_ISR_OFFSET) & XCANPS_IXR_RXNEMP_MASK;
while (RxEmptyResult == (u32)0U) {
RxEmptyResult = XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr),
XCANPS_ISR_OFFSET) & XCANPS_IXR_RXNEMP_MASK;
}
/*
* Receive the frame.
*/
Status = XCanPs_Recv(InstancePtr, RxFrame);
if (Status != (s32)XST_SUCCESS) {
Status = XST_FAILURE;
return Status;
}
/*
* Verify Identifier and Data Length Code.
*/
if (RxFrame[0] !=
(u32)XCanPs_CreateIdValue((u32)2000U, (u32)0U, (u32)0U, (u32)0U, (u32)0U)) {
Status = XST_FAILURE;
return Status;
}
if ((RxFrame[1] & ~XCANPS_DLCR_TIMESTAMP_MASK) != TxFrame[1]) {
Status = XST_FAILURE;
return Status;
}
for (Index = 2U; Index < (XCANPS_MAX_FRAME_SIZE_IN_WORDS); Index++) {
if (RxFrame[Index] != TxFrame[Index]) {
Status = XST_FAILURE;
return Status;
}
}
/*
* Reset device again before returning to the caller.
*/
XCanPs_Reset(InstancePtr);
Status = XST_SUCCESS;
return Status;
}
/** @} */

View file

@ -0,0 +1,103 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcanps_sinit.c
* @addtogroup canps_v3_0
* @{
*
* This file contains the implementation of the XCanPs driver's static
* initialization functionality.
*
* @note None.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00a xd/sv 01/12/10 First release
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xcanps.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
extern XCanPs_Config XCanPs_ConfigTable[XPAR_XCANPS_NUM_INSTANCES];
/*****************************************************************************/
/**
*
* This function looks for the device configuration based on the unique device
* ID. The table XCanPs_ConfigTable[] contains the configuration information for
* each device in the system.
*
* @param DeviceId is the unique device ID of the device being looked up.
*
* @return A pointer to the configuration table entry corresponding to the
* given device ID, or NULL if no match is found.
*
* @note None.
*
******************************************************************************/
XCanPs_Config *XCanPs_LookupConfig(u16 DeviceId)
{
XCanPs_Config *CfgPtr = NULL;
u32 Index;
for (Index = 0U; Index < (u32)XPAR_XCANPS_NUM_INSTANCES; Index++) {
if (XCanPs_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XCanPs_ConfigTable[Index];
break;
}
}
return (XCanPs_Config *)CfgPtr;
}
/** @} */

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner coresightps_dcc_comp_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling coresightps_dcc"
coresightps_dcc_comp_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: coresightps_dcc_includes
coresightps_dcc_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

View file

@ -0,0 +1,181 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcoresightpsdcc.c
* @addtogroup coresightps_dcc_v1_1
* @{
*
* Functions in this file are the minimum required functions for the
* XCoreSightPs driver.
*
* @note None.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00 kvn 02/14/15 First release
* 1.1 kvn 06/12/15 Add support for Zynq Ultrascale+ MP.
* kvn 08/18/15 Modified Makefile according to compiler changes.
* 1.2 kvn 10/09/15 Add support for IAR Compiler.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <xil_types.h>
#include <xpseudo_asm.h>
#ifdef __ICCARM__
#define INLINE
#else
#define INLINE __inline
#endif
/* DCC Status Bits */
#define XCORESIGHTPS_DCC_STATUS_RX (1 << 30)
#define XCORESIGHTPS_DCC_STATUS_TX (1 << 29)
static INLINE u32 XCoresightPs_DccGetStatus(void);
/****************************************************************************/
/**
*
* This functions sends a single byte using the DCC. It is blocking in that it
* waits for the transmitter to become non-full before it writes the byte to
* the transmit register.
*
* @param BaseAddress is a dummy parameter to match the function proto
* of functions for other stdio devices.
* @param Data is the byte of data to send
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCoresightPs_DccSendByte(u32 BaseAddress, u8 Data)
{
(void) BaseAddress;
while (XCoresightPs_DccGetStatus() & XCORESIGHTPS_DCC_STATUS_TX)
dsb();
#ifdef __aarch64__
asm volatile ("msr dbgdtrtx_el0, %0" : : "r" (Data));
#elif defined (__GNUC__) || defined (__ICCARM__)
asm volatile("mcr p14, 0, %0, c0, c5, 0"
: : "r" (Data));
#else
{
volatile register u32 Reg __asm("cp14:0:c0:c5:0");
Reg = Data;
}
#endif
isb();
}
/****************************************************************************/
/**
*
* This functions receives a single byte using the DCC. It is blocking in that
* it waits for the receiver to become non-empty before it reads from the
* receive register.
*
* @param BaseAddress is a dummy parameter to match the function proto
* of functions for other stdio devices.
*
* @return The byte of data received.
*
* @note None.
*
******************************************************************************/
u8 XCoresightPs_DccRecvByte(u32 BaseAddress)
{
u8 Data;
(void) BaseAddress;
while (!(XCoresightPs_DccGetStatus() & XCORESIGHTPS_DCC_STATUS_RX))
dsb();
#ifdef __aarch64__
asm volatile ("mrs %0, dbgdtrrx_el0" : "=r" (Data));
#elif defined (__GNUC__) || defined (__ICCARM__)
asm volatile("mrc p14, 0, %0, c0, c5, 0"
: "=r" (Data));
#else
{
volatile register u32 Reg __asm("cp14:0:c0:c5:0");
Data = Reg;
}
#endif
isb();
return Data;
}
/****************************************************************************/
/**INLINE
*
* This functions read the status register of the DCC.
*
* @param BaseAddress is the base address of the device
*
* @return The contents of the Status Register.
*
* @note None.
*
******************************************************************************/
static INLINE u32 XCoresightPs_DccGetStatus(void)
{
u32 Status;
#ifdef __aarch64__
asm volatile ("mrs %0, mdccsr_el0" : "=r" (Status));
#elif defined (__GNUC__) || defined (__ICCARM__)
asm volatile("mrc p14, 0, %0, c0, c1, 0"
: "=r" (Status) : : "cc");
#else
{
volatile register u32 Reg __asm("cp14:0:c0:c1:0");
Status = Reg;
}
#endif
return Status;
}
/** @} */

View file

@ -0,0 +1,70 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcoresightpsdcc.h
* @addtogroup coresightps_dcc_v1_1
* @{
* @details
*
* CoreSight driver component.
*
* The coresight is a part of debug communication channel (DCC) group. Jtag UART
* for ARM uses DCC. Each ARM core has its own DCC, so one need to select an
* ARM target in XSDB console before running the jtag terminal command. Using the
* coresight driver component, the output stream can be directed to a log file.
*
* @note None.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00 kvn 02/14/15 First release
* 1.1 kvn 06/12/15 Add support for Zynq Ultrascale+ MP.
* kvn 08/18/15 Modified Makefile according to compiler changes.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <xil_types.h>
void XCoresightPs_DccSendByte(u32 BaseAddress, u8 Data);
u8 XCoresightPs_DccRecvByte(u32 BaseAddress);
/** @} */

View file

@ -0,0 +1,22 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES=*.c
INCLUDEFILES=*.h
libs:
echo "Compiling cpu_cortexr5"
.PHONY: include
include:
${CP} $(INCLUDEFILES) $(INCLUDEDIR)

View file

@ -0,0 +1,43 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcpu_cortexr5.h
* @addtogroup cpu_cortexr5_v1_1
* @{
* @details
*
* dummy file
*
******************************************************************************/
/** @} */

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner csudma_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling csudma"
csudma_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: csudma_includes
csudma_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

View file

@ -0,0 +1,767 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcsudma.c
* @addtogroup csudma_v1_0
* @{
*
* This file contains the implementation of the interface functions for CSU_DMA
* driver. Refer to the header file xcsudma.h for more detailed information.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- ---------------------------------------------------
* 1.0 vnsld 22/10/14 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xcsudma.h"
/************************** Function Prototypes ******************************/
/************************** Function Definitions *****************************/
/*****************************************************************************/
/**
*
* This function initializes an CSU_DMA core. This function must be called
* prior to using an CSU_DMA core. Initialization of an CSU_DMA includes setting
* up the instance data and ensuring the hardware is in a quiescent state.
*
* @param InstancePtr is a pointer to the XCsuDma instance.
* @param CfgPtr is a reference to a structure containing information
* about a specific XCsuDma instance.
* @param EffectiveAddr is the device base address in the virtual memory
* address space. The caller is responsible for keeping the
* address mapping from EffectiveAddr to the device physical
* base address unchanged once this function is invoked.
* Unexpected errors may occur if the address mapping changes
* after this function is called. If address translation is not
* used, pass in the physical address instead.
*
* @return
* - XST_SUCCESS if initialization was successful.
*
* @note None.
*
******************************************************************************/
s32 XCsuDma_CfgInitialize(XCsuDma *InstancePtr, XCsuDma_Config *CfgPtr,
u32 EffectiveAddr)
{
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(CfgPtr != NULL);
Xil_AssertNonvoid(EffectiveAddr != ((u32)0x0));
/* Setup the instance */
(void)memcpy((void *)&(InstancePtr->Config), (const void *)CfgPtr,
sizeof(XCsuDma_Config));
InstancePtr->Config.BaseAddress = EffectiveAddr;
XCsuDma_Reset();
InstancePtr->IsReady = (u32)(XIL_COMPONENT_IS_READY);
return (XST_SUCCESS);
}
/*****************************************************************************/
/**
*
* This function sets the starting address and amount(size) of the data to be
* transfered from/to the memory through the AXI interface.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
* @param Addr is a 64 bit variable which holds the starting address of
* data which needs to write into the memory(DST) (or read from
* the memory(SRC)).
* @param Size is a 32 bit variable which represents the number of 4 byte
* words needs to be transfered from starting address.
* @param EnDataLast is to trigger an end of message. It will enable or
* disable data_inp_last signal to stream interface when current
* command is completed. It is applicable only to source channel
* and neglected for destination channel.
* - 1 - Asserts data_inp_last signal.
* - 0 - data_inp_last will not be asserted.
*
* @return None.
*
* @note Data_inp_last signal is asserted simultaneously with the
* data_inp_valid signal associated with the final 32-bit word
* transfer.
*
******************************************************************************/
void XCsuDma_Transfer(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
UINTPTR Addr, u32 Size, u8 EnDataLast)
{
/* Verify arguments */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(((Addr) & (u64)(XCSUDMA_ADDR_LSB_MASK)) == (u64)0x00);
Xil_AssertVoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
Xil_AssertVoid(Size <= (u32)(XCSUDMA_SIZE_MAX));
Xil_AssertVoid(InstancePtr->IsReady == (u32)(XIL_COMPONENT_IS_READY));
/* Flushing cache memory */
if (Channel == (XCSUDMA_SRC_CHANNEL)) {
Xil_DCacheFlushRange(Addr, Size << (u32)(XCSUDMA_SIZE_SHIFT));
}
/* Invalidating cache memory */
else {
Xil_DCacheInvalidateRange(Addr, Size <<
(u32)(XCSUDMA_SIZE_SHIFT));
}
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_ADDR_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
((u32)(Addr) & (u32)(XCSUDMA_ADDR_MASK)));
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_ADDR_MSB_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
(((u64)Addr >> (u32)(XCSUDMA_MSB_ADDR_SHIFT)) &
(u32)(XCSUDMA_MSB_ADDR_MASK)));
if (EnDataLast == (u8)(XCSUDMA_LAST_WORD_MASK)) {
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_SIZE_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
((Size << (u32)(XCSUDMA_SIZE_SHIFT)) |
(u32)(XCSUDMA_LAST_WORD_MASK)));
}
else {
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_SIZE_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
(Size << (u32)(XCSUDMA_SIZE_SHIFT)));
}
}
/*****************************************************************************/
/**
*
* This function returns the current address location of the memory, from where
* it has to read the data(SRC) or the location where it has to write the data
* (DST) based on the channel selection.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
*
* @return Address is a 64 bit variable which holds the current address.
* - From this location data has to be read(SRC)
* - At this location data has to be written(DST)
*
* @note None.
*
******************************************************************************/
u64 XCsuDma_GetAddr(XCsuDma *InstancePtr, XCsuDma_Channel Channel)
{
u64 FullAddr;
/* Verify arguments */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
FullAddr = XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_ADDR_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))));
FullAddr |= (u64)((u64)XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_ADDR_MSB_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF)))) <<
(u64)(XCSUDMA_MSB_ADDR_SHIFT));
return FullAddr;
}
/*****************************************************************************/
/**
*
* This function returns the size of the data yet to be transfered from memory
* to CSU_DMA or CSU_DMA to memory based on the channel selection.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
*
* @return Size is amount of data yet to be transfered.
*
* @note None.
*
******************************************************************************/
u32 XCsuDma_GetSize(XCsuDma *InstancePtr, XCsuDma_Channel Channel)
{
u32 Size;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
Size = XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_SIZE_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF)))) >>
(u32)(XCSUDMA_SIZE_SHIFT);
return Size;
}
/*****************************************************************************/
/**
*
* This function pause the Channel data tranfer to/from memory or to/from stream
* based on pause type.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
* @param Type is type of the pause to be enabled.
* - XCSUDMA_PAUSE_MEMORY(0) - Pause memory
* - SRC Stops issuing of new read commands to memory.
* - DST Stops issuing of new write commands to memory.
* - XCSUDMA_PAUSE_STREAM(1) - Pause stream
* - SRC Stops transfer of data from FIFO to Stream.
* - DST Stops transfer of data from stream to FIFO.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCsuDma_Pause(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_PauseType Type)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid((Type == (XCSUDMA_PAUSE_MEMORY)) ||
(Type == (XCSUDMA_PAUSE_STREAM)));
Xil_AssertVoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
Xil_AssertVoid(InstancePtr->IsReady == (u32)(XIL_COMPONENT_IS_READY));
/* Pause Memory Read/Write/Stream operations */
if (Type == (XCSUDMA_PAUSE_MEMORY)) {
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
(XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF)))) |
(u32)(XCSUDMA_CTRL_PAUSE_MEM_MASK)));
}
if (Type == (XCSUDMA_PAUSE_STREAM)) {
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
(XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
(Channel * (u32)XCSUDMA_OFFSET_DIFF))) |
(u32)(XCSUDMA_CTRL_PAUSE_STRM_MASK)));
}
}
/*****************************************************************************/
/**
*
* This functions checks whether Channel's memory or stream is paused or not
* based on the given pause type.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
* @param Type is type of the pause which needs to be checked.
* - XCSUDMA_PAUSE_MEMORY(0) - Pause memory
* - SRC Stops issuing of new read commands to memory.
* - DST Stops issuing of new write commands to memory.
* - XCSUDMA_PAUSE_STREAM(1) - Pause stream
* - SRC Stops transfer of data from FIFO to Stream.
* - DST Stops transfer of data from stream to FIFO.
*
* @return Returns the pause status.
* - TRUE if it is in paused state.
* - FALSE if it is not in pause state.
*
* @note None.
*
******************************************************************************/
s32 XCsuDma_IsPaused(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_PauseType Type)
{
u32 Data;
s32 PauseState;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
Xil_AssertNonvoid((Type == (XCSUDMA_PAUSE_MEMORY)) ||
(Type == (XCSUDMA_PAUSE_STREAM)));
Data = XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))));
/* To know Pause condition of Memory Read/Write/Stream operations */
if (Type == (XCSUDMA_PAUSE_MEMORY)) {
if ((Data & (u32)(XCSUDMA_CTRL_PAUSE_MEM_MASK)) ==
(u32)0x00) {
PauseState = (s32)(FALSE);
}
else {
PauseState = (s32)(TRUE);
}
}
else {
if ((Data & (u32)(XCSUDMA_CTRL_PAUSE_STRM_MASK)) ==
(u32)0x00) {
PauseState = (s32)(FALSE);
}
else {
PauseState = (s32)(TRUE);
}
}
return (s32)PauseState;
}
/*****************************************************************************/
/**
*
* This function resumes the channel if it is in paused state and continues
* where it has left or no effect if it is not in paused state, based on the
* type of pause.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
* @param Type is type of the pause to be Resume if it is in pause
* state.
* - XCSUDMA_PAUSE_MEMORY(0) - Pause memory
* - SRC Stops issuing of new read commands to memory.
* - DST Stops issuing of new write commands to memory.
* - XCSUDMA_PAUSE_STREAM(1) - Pause stream
* - SRC Stops transfer of data from FIFO to Stream.
* - DST Stops transfer of data from stream to FIFO.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCsuDma_Resume(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_PauseType Type)
{
u32 Data;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid((Type == (XCSUDMA_PAUSE_MEMORY)) ||
(Type == (XCSUDMA_PAUSE_STREAM)));
Xil_AssertVoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
Xil_AssertVoid(InstancePtr->IsReady == (u32)(XIL_COMPONENT_IS_READY));
Data = XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))));
if (Type == (XCSUDMA_PAUSE_MEMORY)) {
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
(Data &
(~(XCSUDMA_CTRL_PAUSE_MEM_MASK))));
}
if (Type == (XCSUDMA_PAUSE_STREAM)) {
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
(((u32)Channel) * (u32)(XCSUDMA_OFFSET_DIFF))),
( Data &
(~(XCSUDMA_CTRL_PAUSE_STRM_MASK))));
}
}
/*****************************************************************************/
/**
*
* This function returns the sum of all the data read from AXI memory. It is
* valid only one we use CSU_DMA source channel.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
*
* @return Returns the sum of all the data read from memory.
*
* @note Before start of the transfer need to clear this register to get
* correct sum otherwise it adds to previous value which results
* to wrong output.
* Valid only for source channel
*
******************************************************************************/
u32 XCsuDma_GetCheckSum(XCsuDma *InstancePtr)
{
u32 ChkSum;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady ==
(u32)(XIL_COMPONENT_IS_READY));
ChkSum = XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
(u32)(XCSUDMA_CRC_OFFSET));
return ChkSum;
}
/*****************************************************************************/
/**
*
* This function clears the check sum of the data read from AXI memory. It is
* valid only for CSU_DMA source channel.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
*
* @return Returns the sum of all the data read from memory.
*
* @note Before start of the transfer need to clear this register to get
* correct sum otherwise it adds to previous value which results
* to wrong output.
*
******************************************************************************/
void XCsuDma_ClearCheckSum(XCsuDma *InstancePtr)
{
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
(u32)(XCSUDMA_CRC_OFFSET), (u32)(XCSUDMA_CRC_RESET_MASK));
}
/*****************************************************************************/
/**
* This function cofigures all the values of CSU_DMA's Channels with the values
* of updated XCsuDma_Configure structure.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
* @param ConfigurValues is a pointer to the structure XCsuDma_Configure
* whose values are used to configure CSU_DMA core.
* - SssFifoThesh When the DST FIFO level >= this value,
* the SSS interface signal, "data_out_fifo_level_hit" will be
* asserted. This mechanism can be used by the SSS to flow
* control data that is being looped back from the SRC DMA.
* - Range is (0x10 to 0x7A) threshold is 17 to 123
* entries.
* - It is valid only for DST CSU_DMA IP.
* - ApbErr When accessed to invalid APB the resulting
* pslerr will be
* - 0 - 1'b0
* - 1 - 1'b1
* - EndianType Type of endianness
* - 0 doesn't change order
* - 1 will flip the order.
* - AxiBurstType....Type of the burst
* - 0 will issue INCR type burst
* - 1 will issue FIXED type burst
* - TimeoutValue Time out value for timers
* - 0x000 to 0xFFE are valid inputs
* - 0xFFF clears both timers
* - FifoThresh......Programmed watermark value
* - Range is 0x00 to 0x80 (0 to 128 entries).
* - Acache Sets the AXI CACHE bits on the AXI Write/Read
* channel.
* - Cacheable ARCACHE[1] for SRC Channel and AWCACHE[1]
* for DST channel are always 1, we need to configure
* remaining 3 signal support
* (Bufferable, Read allocate and Write allocate).
* Valid inputs are:
* - 0x000 - Cacheable, but do not allocate
* - 0x001 - Cacheable and bufferable, but do not allocate
* - 0x010 - Cacheable write-through, allocate on reads
* only
* - 0x011 - Cacheable write-back, allocate on reads only
* - 0x100 - Cacheable write-through, allocate on writes
* only
* - 0x101 - Cacheable write-back, allocate on writes only
* - 0x110 - Cacheable write-through, allocate on both
* reads and writes
* - 0x111 - Cacheable write-back, allocate on both reads
* and writes
* - RouteBit To select route
* - 0 : Command will be routed normally
* - 1 : Command will be routed to APU's cache controller
* - TimeoutEn To enable or disable time out counters
* - 0 : The 2 Timeout counters are disabled
* - 1 : The 2 Timeout counters are enabled
* - TimeoutPre Set the prescaler value for the timeout in
* clk (~2.5ns) cycles
* - Range is 0x000(Prescaler enables timer every cycles)
* to 0xFFF(Prescaler enables timer every 4096 cycles)
* - MaxOutCmds Controls the maximumum number of outstanding
* AXI read commands issued.
* - Range is 0x0(Up to 1 Outstanding Read command
* allowed) to 0x8 (Up to 9 Outstanding Read
* command allowed)
*
* @return None.
*
* @note To use timers timeout value Timeout enable field should be
* enabled.
*
******************************************************************************/
void XCsuDma_SetConfig(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_Configure *ConfigurValues)
{
u32 Data;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)(XIL_COMPONENT_IS_READY));
Xil_AssertVoid(ConfigurValues != NULL);
Xil_AssertVoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
Xil_AssertVoid(XCsuDma_IsBusy(InstancePtr, Channel) != (s32)(TRUE));
Data = (((ConfigurValues->EndianType <<
(u32)(XCSUDMA_CTRL_ENDIAN_SHIFT)) &
(u32)(XCSUDMA_CTRL_ENDIAN_MASK)) |
((ConfigurValues->ApbErr <<
(u32)(XCSUDMA_CTRL_APB_ERR_SHIFT)) &
(u32)(XCSUDMA_CTRL_APB_ERR_MASK)) |
((ConfigurValues->AxiBurstType <<
(u32)(XCSUDMA_CTRL_BURST_SHIFT)) &
(u32)(XCSUDMA_CTRL_BURST_MASK)) |
((ConfigurValues->TimeoutValue <<
(u32)(XCSUDMA_CTRL_TIMEOUT_SHIFT)) &
(u32)(XCSUDMA_CTRL_TIMEOUT_MASK)) |
((ConfigurValues->FifoThresh <<
(u32)(XCSUDMA_CTRL_FIFO_THRESH_SHIFT)) &
(u32)(XCSUDMA_CTRL_FIFO_THRESH_MASK)));
if(Channel == XCSUDMA_DST_CHANNEL) {
Data = Data | (u32)((ConfigurValues->SssFifoThesh <<
(u32)(XCSUDMA_CTRL_SSS_FIFOTHRESH_SHIFT)) &
(u32)(XCSUDMA_CTRL_SSS_FIFOTHRESH_MASK));
}
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))), Data);
Data = (XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL2_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF)))) &
(u32)(XCSUDMA_CTRL2_RESERVED_MASK));
Data |= (((ConfigurValues->Acache <<
(u32)(XCSUDMA_CTRL2_ACACHE_SHIFT)) &
(u32)(XCSUDMA_CTRL2_ACACHE_MASK)) |
((ConfigurValues->RouteBit <<
(u32)(XCSUDMA_CTRL2_ROUTE_SHIFT)) &
(u32)(XCSUDMA_CTRL2_ROUTE_MASK)) |
((ConfigurValues->TimeoutEn <<
(u32)(XCSUDMA_CTRL2_TIMEOUT_EN_SHIFT)) &
(u32)(XCSUDMA_CTRL2_TIMEOUT_EN_MASK)) |
((ConfigurValues->TimeoutPre <<
(u32)(XCSUDMA_CTRL2_TIMEOUT_PRE_SHIFT)) &
(u32)(XCSUDMA_CTRL2_TIMEOUT_PRE_MASK)) |
((ConfigurValues->MaxOutCmds) &
(u32)(XCSUDMA_CTRL2_MAXCMDS_MASK)));
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL2_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))), Data);
}
/*****************************************************************************/
/**
*
* This function updates XCsuDma_Configure structure members with the cofigured
* values of CSU_DMA's Channel.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
* @param ConfigurValues is a pointer to the structure XCsuDma_Configure
* whose members are updated with configurations of CSU_DMA core.
* - SssFifoThesh When the DST FIFO level >= this value,
* the SSS interface signal, "data_out_fifo_level_hit" will be
* asserted. This mechanism can be used by the SSS to flow
* control data that is being looped back from the SRC DMA.
* - Range is (0x10 to 0x7A) threshold is 17 to 123
* entries.
* - It is valid only for DST CSU_DMA IP.
* - ApbErr When accessed to invalid APB the resulting
* pslerr will be
* - 0 - 1'b0
* - 1 - 1'b1
* - EndianType Type of endianness
* - 0 doesn't change order
* - 1 will flip the order.
* - AxiBurstType....Type of the burst
* - 0 will issue INCR type burst
* - 1 will issue FIXED type burst
* - TimeoutValue Time out value for timers
* - 0x000 to 0xFFE are valid inputs
* - 0xFFF clears both timers
* - FifoThresh......Programmed watermark value
* - Range is 0x00 to 0x80 (0 to 128 entries).
* - Acache Sets the AXI CACHE bits on the AXI Write/Read
* channel.
* - Cacheable ARCACHE[1] for SRC Channel and AWCACHE[1]
* for DST channel are always 1, we need to configure
* remaining 3 signal support
* (Bufferable, Read allocate and Write allocate).
* Valid inputs are:
* - 0x000 - Cacheable, but do not allocate
* - 0x001 - Cacheable and bufferable, but do not allocate
* - 0x010 - Cacheable write-through, allocate on reads
* only
* - 0x011 - Cacheable write-back, allocate on reads only
* - 0x100 - Cacheable write-through, allocate on writes
* only
* - 0x101 - Cacheable write-back, allocate on writes only
* - 0x110 - Cacheable write-through, allocate on both
* reads and writes
* - 0x111 - Cacheable write-back, allocate on both reads
* and writes
* - RouteBit To select route
* - 0 : Command will be routed based normally
* - 1 : Command will be routed to APU's cache controller
* - TimeoutEn To enable or disable time out counters
* - 0 : The 2 Timeout counters are disabled
* - 1 : The 2 Timeout counters are enabled
* - TimeoutPre Set the prescaler value for the timeout in
* clk (~2.5ns) cycles
* - Range is 0x000(Prescaler enables timer every cycles)
* to 0xFFF(Prescaler enables timer every 4096 cycles)
* - MaxOutCmds Controls the maximumum number of outstanding
* AXI read commands issued.
* - Range is 0x0(Up to 1 Outstanding Read command
* allowed) to 0x8 (Up to 9 Outstanding Read command
* allowed)
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCsuDma_GetConfig(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_Configure *ConfigurValues)
{
u32 Data;
/* Verify arguments. */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(ConfigurValues != NULL);
Xil_AssertVoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
Data = XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))));
if (Channel == (XCSUDMA_DST_CHANNEL)) {
ConfigurValues->SssFifoThesh =
(u8)((Data &
(u32)(XCSUDMA_CTRL_SSS_FIFOTHRESH_MASK)) >>
(u32)(XCSUDMA_CTRL_SSS_FIFOTHRESH_SHIFT));
}
ConfigurValues->ApbErr =
(u8)((Data & (u32)(XCSUDMA_CTRL_APB_ERR_MASK)) >>
(u32)(XCSUDMA_CTRL_APB_ERR_SHIFT));
ConfigurValues->EndianType =
(u8)((Data & (u32)(XCSUDMA_CTRL_ENDIAN_MASK)) >>
(u32)(XCSUDMA_CTRL_ENDIAN_SHIFT));
ConfigurValues->AxiBurstType =
(u8)((Data & (u32)(XCSUDMA_CTRL_BURST_MASK)) >>
(u32)(XCSUDMA_CTRL_BURST_SHIFT));
ConfigurValues->TimeoutValue =
((Data & (u32)(XCSUDMA_CTRL_TIMEOUT_MASK)) >>
(u32)(XCSUDMA_CTRL_TIMEOUT_SHIFT));
ConfigurValues->FifoThresh =
(u8)((Data & (u32)(XCSUDMA_CTRL_FIFO_THRESH_MASK)) >>
(u32)(XCSUDMA_CTRL_FIFO_THRESH_SHIFT));
Data = XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_CTRL2_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))));
ConfigurValues->Acache =
(u8)((Data & (u32)(XCSUDMA_CTRL2_ACACHE_MASK)) >>
(u32)(XCSUDMA_CTRL2_ACACHE_SHIFT));
ConfigurValues->RouteBit =
(u8)((Data & (u32)(XCSUDMA_CTRL2_ROUTE_MASK)) >>
(u32)(XCSUDMA_CTRL2_ROUTE_SHIFT));
ConfigurValues->TimeoutEn =
(u8)((Data & (u32)(XCSUDMA_CTRL2_TIMEOUT_EN_MASK)) >>
(u32)(XCSUDMA_CTRL2_TIMEOUT_EN_SHIFT));
ConfigurValues->TimeoutPre =
(u16)((Data & (u32)(XCSUDMA_CTRL2_TIMEOUT_PRE_MASK)) >>
(u32)(XCSUDMA_CTRL2_TIMEOUT_PRE_SHIFT));
ConfigurValues->MaxOutCmds =
(u8)((Data & (u32)(XCSUDMA_CTRL2_MAXCMDS_MASK)));
}
/** @} */

View file

@ -0,0 +1,418 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* The CSU_DMA is present inside CSU (Configuration Security Unit) module which
* is located within the Low-Power Subsystem (LPS) internal to the PS.
* CSU_DMA allows the CSU to move data efficiently between the memory (32 bit
* AXI interface) and the CSU stream peripherals (SHA, AES and PCAP) via Secure
* Stream Switch (SSS).
*
* The CSU_DMA is a 2 channel simple DMA, allowing separate control of the SRC
* (read) channel and DST (write) channel. The DMA is effectively able to
* transfer data:
* - From PS-side to the SSS-side (SRC DMA only)
* - From SSS-side to the PS-side (DST DMA only)
* - Simultaneous PS-side to SSS_side and SSS-side to the PS-side
*
* <b>Initialization & Configuration</b>
*
* The device driver enables higher layer software (e.g., an application) to
* communicate to the CSU_DMA core.
*
* XCsuDma_CfgInitialize() API is used to initialize the CSU_DMA core.
* The user needs to first call the XCsuDma_LookupConfig() API which returns
* the Configuration structure pointer which is passed as a parameter to the
* XCsuDma_CfgInitialize() API.
*
* <b> Interrupts </b>
* This driver will not support handling of interrupts user should write handler
* to handle the interrupts.
*
* <b> Virtual Memory </b>
*
* This driver supports Virtual Memory. The RTOS is responsible for calculating
* the correct device base address in Virtual Memory space.
*
* <b> Threads </b>
*
* This driver is not thread safe. Any needs for threads or thread mutual
* exclusion must be satisfied by the layer above this driver.
*
* <b> Asserts </b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on argument
* values. Asserts can be turned off on a system-wide basis by defining, at
* compile time, the NDEBUG identifier. By default, asserts are turned on and it
* is recommended that users leave asserts on during development.
*
* <b> Building the driver </b>
*
* The XCsuDma driver is composed of several source files. This allows the user
* to build and link only those parts of the driver that are necessary.
*
* @file xcsudma.h
* @addtogroup csudma_v1_0
* @{
* @details
*
* This header file contains identifiers and register-level driver functions (or
* macros), range macros, structure typedefs that can be used to access the
* Xilinx CSU_DMA core instance.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- -----------------------------------------------------
* 1.0 vnsld 22/10/14 First release
* </pre>
*
******************************************************************************/
#ifndef XCSUDMA_H_
#define XCSUDMA_H_ /**< Prevent circular inclusions
* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xcsudma_hw.h"
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xil_cache.h"
/************************** Constant Definitions *****************************/
/** @name CSU_DMA Channels
* @{
*/
typedef enum {
XCSUDMA_SRC_CHANNEL = 0U, /**< Source Channel of CSU_DMA */
XCSUDMA_DST_CHANNEL /**< Destination Channel of CSU_DMA */
}XCsuDma_Channel;
/*@}*/
/** @name CSU_DMA pause types
* @{
*/
typedef enum {
XCSUDMA_PAUSE_MEMORY, /**< Pauses memory data transfer
* to/from CSU_DMA */
XCSUDMA_PAUSE_STREAM, /**< Pauses stream data transfer
* to/from CSU_DMA */
}XCsuDma_PauseType;
/*@}*/
/** @name Ranges of Size
* @{
*/
#define XCSUDMA_SIZE_MAX 0x07FFFFFF /**< Maximum allowed no of words */
/*@}*/
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
*
* This function resets the CSU_DMA core.
*
* @param None.
*
* @return None.
*
* @note None.
* C-style signature:
* void XCsuDma_Reset()
*
******************************************************************************/
#define XCsuDma_Reset() \
Xil_Out32(((u32)(XCSU_BASEADDRESS) + (u32)(XCSU_DMA_RESET_OFFSET)), \
(u32)(XCSUDMA_RESET_SET_MASK)); \
Xil_Out32(((u32)(XCSU_BASEADDRESS) + (u32)(XCSU_DMA_RESET_OFFSET)), \
(u32)(XCSUDMA_RESET_UNSET_MASK));
/*****************************************************************************/
/**
* This function will be in busy while loop until the data transfer is
* completed.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
*
* @return None.
*
* @note This function should be called after XCsuDma_Transfer in polled
* mode to wait until the data gets transfered completely.
* C-style signature:
* void XCsuDma_WaitForDone(XCsuDma *InstancePtr,
* XCsuDma_Channel Channel)
*
******************************************************************************/
#define XCsuDma_WaitForDone(InstancePtr,Channel) \
while((XCsuDma_ReadReg(((InstancePtr)->Config.BaseAddress), \
((u32)(XCSUDMA_I_STS_OFFSET) + \
((u32)(Channel) * (u32)(XCSUDMA_OFFSET_DIFF)))) & \
(u32)(XCSUDMA_IXR_DONE_MASK)) != (XCSUDMA_IXR_DONE_MASK))
/*****************************************************************************/
/**
*
* This function returns the number of completed SRC/DST DMA transfers that
* have not been acknowledged by software based on the channel selection.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
*
* @return Count is number of completed DMA transfers but not acknowledged
* (Range is 0 to 7).
* - 000 - All finished transfers have been acknowledged.
* - Count - Count number of finished transfers are still
* outstanding.
*
* @note None.
* C-style signature:
* u8 XCsuDma_GetDoneCount(XCsuDma *InstancePtr,
* XCsuDma_Channel Channel)
*
******************************************************************************/
#define XCsuDma_GetDoneCount(InstancePtr, Channel) \
((XCsuDma_ReadReg(((InstancePtr)->Config.BaseAddress), \
((u32)(XCSUDMA_STS_OFFSET) + \
((u32)(Channel) * (u32)(XCSUDMA_OFFSET_DIFF)))) & \
(u32)(XCSUDMA_STS_DONE_CNT_MASK)) >> \
(u32)(XCSUDMA_STS_DONE_CNT_SHIFT))
/*****************************************************************************/
/**
*
* This function returns the current SRC/DST FIFO level in 32 bit words of the
* selected channel
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
*
* @return FIFO level. (Range is 0 to 128)
* - 0 Indicates empty
* - Any number 1 to 128 indicates the number of entries in FIFO.
*
* @note None.
* C-style signature:
* u8 XCsuDma_GetFIFOLevel(XCsuDma *InstancePtr,
* XCsuDma_Channel Channel)
*
******************************************************************************/
#define XCsuDma_GetFIFOLevel(InstancePtr, Channel) \
((XCsuDma_ReadReg(((InstancePtr)->Config.BaseAddress), \
((u32)(XCSUDMA_STS_OFFSET) + \
((u32)(Channel) * (u32)(XCSUDMA_OFFSET_DIFF)))) & \
(u32)(XCSUDMA_STS_FIFO_LEVEL_MASK)) >> \
(u32)(XCSUDMA_STS_FIFO_LEVEL_SHIFT))
/*****************************************************************************/
/**
*
* This function returns the current number of read(src)/write(dst) outstanding
* commands based on the type of channel selected.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
*
* @return Count of outstanding commands. (Range is 0 to 9).
*
* @note None.
* C-style signature:
* u8 XCsuDma_GetWROutstandCount(XCsuDma *InstancePtr,
* XCsuDma_Channel Channel)
*
******************************************************************************/
#define XCsuDma_GetWROutstandCount(InstancePtr, Channel) \
((XCsuDma_ReadReg(((InstancePtr)->Config.BaseAddress), \
((u32)(XCSUDMA_STS_OFFSET) + \
((u32)(Channel) * (u32)(XCSUDMA_OFFSET_DIFF)))) & \
(u32)(XCUSDMA_STS_OUTSTDG_MASK)) >> \
(u32)(XCUSDMA_STS_OUTSTDG_SHIFT))
/*****************************************************************************/
/**
*
* This function returns the status of Channel either it is busy or not.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
*
* @return Returns the current status of the core.
* - TRUE represents core is currently busy.
* - FALSE represents core is not involved in any transfers.
*
* @note None.
* C-style signature:
* s32 XCsuDma_IsBusy(XCsuDma *InstancePtr, XCsuDma_Channel Channel)
*
******************************************************************************/
#define XCsuDma_IsBusy(InstancePtr, Channel) \
((XCsuDma_ReadReg(((InstancePtr)->Config.BaseAddress), \
((u32)(XCSUDMA_STS_OFFSET) + \
((u32)(Channel) * (u32)(XCSUDMA_OFFSET_DIFF)))) & \
(u32)(XCSUDMA_STS_BUSY_MASK)) == (XCSUDMA_STS_BUSY_MASK)) ? \
(TRUE) : (FALSE)
/**************************** Type Definitions *******************************/
/**
* This typedef contains configuration information for a CSU_DMA core.
* Each CSU_DMA core should have a configuration structure associated.
*/
typedef struct {
u16 DeviceId; /**< DeviceId is the unique ID of the
* device */
u32 BaseAddress; /**< BaseAddress is the physical base address
* of the device's registers */
} XCsuDma_Config;
/******************************************************************************/
/**
*
* The XCsuDma driver instance data structure. A pointer to an instance data
* structure is passed around by functions to refer to a specific driver
* instance.
*/
typedef struct {
XCsuDma_Config Config; /**< Hardware configuration */
u32 IsReady; /**< Device and the driver instance
* are initialized */
}XCsuDma;
/******************************************************************************/
/**
* This typedef contains all the configuration feilds which needs to be set
* before the start of the data transfer. All these feilds of CSU_DMA can be
* configured by using XCsuDma_SetConfig API.
*/
typedef struct {
u8 SssFifoThesh; /**< SSS FIFO threshold value */
u8 ApbErr; /**< ABP invalid access error */
u8 EndianType; /**< Type of endianess */
u8 AxiBurstType; /**< Type of AXI bus */
u32 TimeoutValue; /**< Time out value */
u8 FifoThresh; /**< FIFO threshold value */
u8 Acache; /**< AXI CACHE selection */
u8 RouteBit; /**< Selection of Route */
u8 TimeoutEn; /**< Enable of time out counters */
u16 TimeoutPre; /**< Pre scaler value */
u8 MaxOutCmds; /**< Maximum number of outstanding
* commands */
}XCsuDma_Configure;
/*****************************************************************************/
/************************** Function Prototypes ******************************/
XCsuDma_Config *XCsuDma_LookupConfig(u16 DeviceId);
s32 XCsuDma_CfgInitialize(XCsuDma *InstancePtr, XCsuDma_Config *CfgPtr,
u32 EffectiveAddr);
void XCsuDma_Transfer(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
UINTPTR Addr, u32 Size, u8 EnDataLast);
void XCsuDma_LoopBackTransfer(XCsuDma *InstancePtr, u64 SrcAddr, u64 DstAddr,
u32 Size);
u64 XCsuDma_GetAddr(XCsuDma *InstancePtr, XCsuDma_Channel Channel);
u32 XCsuDma_GetSize(XCsuDma *InstancePtr, XCsuDma_Channel Channel);
void XCsuDma_Pause(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_PauseType Type);
s32 XCsuDma_IsPaused(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_PauseType Type);
void XCsuDma_Resume(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_PauseType Type);
u32 XCsuDma_GetCheckSum(XCsuDma *InstancePtr);
void XCsuDma_ClearCheckSum(XCsuDma *InstancePtr);
void XCsuDma_SetConfig(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_Configure *ConfigurValues);
void XCsuDma_GetConfig(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
XCsuDma_Configure *ConfigurValues);
void XCsuDma_ClearDoneCount(XCsuDma *InstancePtr, XCsuDma_Channel Channel);
void XCsuDma_SetSafetyCheck(XCsuDma *InstancePtr, u32 Value);
u32 XCsuDma_GetSafetyCheck(XCsuDma *InstancePtr);
/* Interrupt related APIs */
u32 XCsuDma_IntrGetStatus(XCsuDma *InstancePtr, XCsuDma_Channel Channel);
void XCsuDma_IntrClear(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
u32 Mask);
void XCsuDma_EnableIntr(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
u32 Mask);
void XCsuDma_DisableIntr(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
u32 Mask);
u32 XCsuDma_GetIntrMask(XCsuDma *InstancePtr, XCsuDma_Channel Channel);
s32 XCsuDma_SelfTest(XCsuDma *InstancePtr);
/******************************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* End of protection macro */
/** @} */

View file

@ -0,0 +1,55 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the Software), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in
*all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
*(a) running on a Xilinx device, or
*(b) that interact with a Xilinx device through a bus or interconnect.
*
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the Xilinx shall not be used
*in advertising or otherwise to promote the sale, use or other dealings in
*this Software without prior written authorization from Xilinx.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xcsudma.h"
/*
* The configuration table for devices
*/
XCsuDma_Config XCsuDma_ConfigTable[] =
{
{
XPAR_PSU_CSUDMA_DEVICE_ID,
XPAR_PSU_CSUDMA_BASEADDR
}
};

View file

@ -0,0 +1,311 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcsudma_hw.h
* @addtogroup csudma_v1_0
* @{
*
* This header file contains identifiers and register-level driver functions (or
* macros) that can be used to access the Xilinx CSU_DMA core.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- ------------------------------------------------------
* 1.0 vnsld 22/10/14 First release
* </pre>
*
******************************************************************************/
#ifndef XCSUDMA_HW_H_
#define XCSUDMA_HW_H_ /**< Prevent circular inclusions
* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/** @name Registers offsets
* @{
*/
#define XCSUDMA_ADDR_OFFSET 0x000 /**< Address Register Offset */
#define XCSUDMA_SIZE_OFFSET 0x004 /**< Size Register Offset */
#define XCSUDMA_STS_OFFSET 0x008 /**< Status Register Offset */
#define XCSUDMA_CTRL_OFFSET 0x00C /**< Control Register Offset */
#define XCSUDMA_CRC_OFFSET 0x010 /**< CheckSum Register Offset */
#define XCSUDMA_I_STS_OFFSET 0x014 /**< Interrupt Status Register
* Offset */
#define XCSUDMA_I_EN_OFFSET 0x018 /**< Interrupt Enable Register
* Offset */
#define XCSUDMA_I_DIS_OFFSET 0x01C /**< Interrupt Disable Register
* Offset */
#define XCSUDMA_I_MASK_OFFSET 0x020 /**< Interrupt Mask Register Offset */
#define XCSUDMA_CTRL2_OFFSET 0x024 /**< Interrupt Control Register 2
* Offset */
#define XCSUDMA_ADDR_MSB_OFFSET 0x028 /**< Address's MSB Register Offset */
#define XCSUDMA_SAFETY_CHK_OFFSET 0xFF8 /**< Safety Check Field Offset */
#define XCSUDMA_FUTURE_ECO_OFFSET 0xFFC /**< Future potential ECO Offset */
/*@}*/
/** @name CSU Base address and CSU_DMA reset offset
* @{
*/
#define XCSU_BASEADDRESS 0xFFCA0000
/**< CSU Base Address */
#define XCSU_DMA_RESET_OFFSET 0x0000000CU /**< CSU_DMA Reset offset */
/*@}*/
/** @name CSU_DMA Reset register bit masks
* @{
*/
#define XCSUDMA_RESET_SET_MASK 0x00000001U /**< Reset set mask */
#define XCSUDMA_RESET_UNSET_MASK 0x00000000U /**< Reset unset mask*/
/*@}*/
/** @name Offset difference for Source and destination
* @{
*/
#define XCSUDMA_OFFSET_DIFF 0x00000800U /**< Offset difference for
* source and
* destination channels */
/*@}*/
/** @name Address register bit masks
* @{
*/
#define XCSUDMA_ADDR_MASK 0xFFFFFFFCU /**< Address mask */
#define XCSUDMA_ADDR_LSB_MASK 0x00000003U /**< Address alignment check
* mask */
/*@}*/
/** @name Size register bit masks and shifts
* @{
*/
#define XCSUDMA_SIZE_MASK 0x1FFFFFFCU /**< Mask for size */
#define XCSUDMA_LAST_WORD_MASK 0x00000001U /**< Last word check bit mask*/
#define XCSUDMA_SIZE_SHIFT 2U /**< Shift for size */
/*@}*/
/** @name Status register bit masks and shifts
* @{
*/
#define XCSUDMA_STS_DONE_CNT_MASK 0x0000E000U /**< Count done mask */
#define XCSUDMA_STS_FIFO_LEVEL_MASK 0x00001FE0U /**< FIFO level mask */
#define XCUSDMA_STS_OUTSTDG_MASK 0x0000001EU /**< No.of outstanding
* read/write
* commands mask */
#define XCSUDMA_STS_BUSY_MASK 0x00000001U /**< Busy mask */
#define XCSUDMA_STS_DONE_CNT_SHIFT 13U /**< Shift for Count
* done */
#define XCSUDMA_STS_FIFO_LEVEL_SHIFT 5U /**< Shift for FIFO
* level */
#define XCUSDMA_STS_OUTSTDG_SHIFT 1U /**< Shift for No.of
* outstanding
* read/write
* commands */
/*@}*/
/** @name Control register bit masks and shifts
* @{
*/
#define XCSUDMA_CTRL_SSS_FIFOTHRESH_MASK 0xFE000000U /**< SSS FIFO threshold
* value mask */
#define XCSUDMA_CTRL_APB_ERR_MASK 0x01000000U /**< APB register
* access error
* mask */
#define XCSUDMA_CTRL_ENDIAN_MASK 0x00800000U /**< Endianess mask */
#define XCSUDMA_CTRL_BURST_MASK 0x00400000U /**< AXI burst type
* mask */
#define XCSUDMA_CTRL_TIMEOUT_MASK 0x003FFC00U /**< Time out value
* mask */
#define XCSUDMA_CTRL_FIFO_THRESH_MASK 0x000003FCU /**< FIFO threshold
* mask */
#define XCSUDMA_CTRL_PAUSE_MEM_MASK 0x00000001U /**< Memory pause
* mask */
#define XCSUDMA_CTRL_PAUSE_STRM_MASK 0x00000002U /**< Stream pause
* mask */
#define XCSUDMA_CTRL_SSS_FIFOTHRESH_SHIFT 25U /**< SSS FIFO threshold
* shift */
#define XCSUDMA_CTRL_APB_ERR_SHIFT 24U /**< APB error shift */
#define XCSUDMA_CTRL_ENDIAN_SHIFT 23U /**< Endianess shift */
#define XCSUDMA_CTRL_BURST_SHIFT 22U /**< AXI burst type
* shift */
#define XCSUDMA_CTRL_TIMEOUT_SHIFT 10U /**< Time out value
* shift */
#define XCSUDMA_CTRL_FIFO_THRESH_SHIFT 2U /**< FIFO thresh
* shift */
/*@}*/
/** @name CheckSum register bit masks
* @{
*/
#define XCSUDMA_CRC_RESET_MASK 0x00000000U /**< Mask to reset
* value of
* check sum */
/*@}*/
/** @name Interrupt Enable/Disable/Mask/Status registers bit masks
* @{
*/
#define XCSUDMA_IXR_FIFO_OVERFLOW_MASK 0x00000001U /**< FIFO overflow
* mask, it is valid
* only to Destination
* Channel */
#define XCSUDMA_IXR_INVALID_APB_MASK 0x00000040U /**< Invalid APB access
* mask */
#define XCSUDMA_IXR_FIFO_THRESHHIT_MASK 0x00000020U /**< FIFO threshold hit
* indicator mask */
#define XCSUDMA_IXR_TIMEOUT_MEM_MASK 0x00000010U /**< Time out counter
* expired to access
* memory mask */
#define XCSUDMA_IXR_TIMEOUT_STRM_MASK 0x00000008U /**< Time out counter
* expired to access
* stream mask */
#define XCSUDMA_IXR_AXI_WRERR_MASK 0x00000004U /**< AXI Read/Write
* error mask */
#define XCSUDMA_IXR_DONE_MASK 0x00000002U /**< Done mask */
#define XCSUDMA_IXR_MEM_DONE_MASK 0x00000001U /**< Memory done
* mask, it is valid
* only for source
* channel*/
#define XCSUDMA_IXR_SRC_MASK 0x0000007FU
/**< ((XCSUDMA_IXR_INVALID_APB_MASK)|
(XCSUDMA_IXR_FIFO_THRESHHIT_MASK) |
(XCSUDMA_IXR_TIMEOUT_MEM_MASK) |
(XCSUDMA_IXR_TIMEOUT_STRM_MASK) |
(XCSUDMA_IXR_AXI_WRERR_MASK) |
(XCSUDMA_IXR_DONE_MASK) |
(XCSUDMA_IXR_MEM_DONE_MASK)) */
/**< All interrupt mask
* for source */
#define XCSUDMA_IXR_DST_MASK 0x000000FEU
/**< ((XCSUDMA_IXR_FIFO_OVERFLOW_MASK) |
(XCSUDMA_IXR_INVALID_APB_MASK) |
(XCSUDMA_IXR_FIFO_THRESHHIT_MASK) |
(XCSUDMA_IXR_TIMEOUT_MEM_MASK) |
(XCSUDMA_IXR_TIMEOUT_STRM_MASK) |
(XCSUDMA_IXR_AXI_WRERR_MASK) |
(XCSUDMA_IXR_DONE_MASK)) */
/**< All interrupt mask
* for destination */
/*@}*/
/** @name Control register 2 bit masks and shifts
* @{
*/
#define XCSUDMA_CTRL2_RESERVED_MASK 0x083F0000U /**< Reserved bits
* mask */
#define XCSUDMA_CTRL2_ACACHE_MASK 0X07000000U /**< AXI CACHE mask */
#define XCSUDMA_CTRL2_ROUTE_MASK 0x00800000U /**< Route mask */
#define XCSUDMA_CTRL2_TIMEOUT_EN_MASK 0x00400000U /**< Time out counters
* enable mask */
#define XCSUDMA_CTRL2_TIMEOUT_PRE_MASK 0x0000FFF0U /**< Time out pre
* mask */
#define XCSUDMA_CTRL2_MAXCMDS_MASK 0x0000000FU /**< Maximum commands
* mask */
#define XCSUDMA_CTRL2_RESET_MASK 0x0000FFF8U /**< Reset mask */
#define XCSUDMA_CTRL2_ACACHE_SHIFT 24U /**< Shift for
* AXI R/W CACHE */
#define XCSUDMA_CTRL2_ROUTE_SHIFT 23U /**< Shift for route */
#define XCSUDMA_CTRL2_TIMEOUT_EN_SHIFT 22U /**< Shift for Timeout
* enable feild */
#define XCSUDMA_CTRL2_TIMEOUT_PRE_SHIFT 4U /**< Shift for Timeout
* pre feild */
/*@}*/
/** @name MSB Address register bit masks and shifts
* @{
*/
#define XCSUDMA_MSB_ADDR_MASK 0x0001FFFFU /**< MSB bits of address
* mask */
#define XCSUDMA_MSB_ADDR_SHIFT 32U /**< Shift for MSB bits of
* address */
/*@}*/
/***************** Macros (Inline Functions) Definitions *********************/
#define XCsuDma_In32 Xil_In32 /**< Input operation */
#define XCsuDma_Out32 Xil_Out32 /**< Output operation */
/*****************************************************************************/
/**
*
* This macro reads the given register.
*
* @param BaseAddress is the Xilinx base address of the CSU_DMA core.
* @param RegOffset is the register offset of the register.
*
* @return The 32-bit value of the register.
*
* @note C-style signature:
* u32 XCsuDma_ReadReg(u32 BaseAddress, u32 RegOffset)
*
******************************************************************************/
#define XCsuDma_ReadReg(BaseAddress, RegOffset) \
XCsuDma_In32((BaseAddress) + (u32)(RegOffset))
/*****************************************************************************/
/**
*
* This macro writes the value into the given register.
*
* @param BaseAddress is the Xilinx base address of the CSU_DMA core.
* @param RegOffset is the register offset of the register.
* @param Data is the 32-bit value to write to the register.
*
* @return None.
*
* @note C-style signature:
* void XCsuDma_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
*
******************************************************************************/
#define XCsuDma_WriteReg(BaseAddress, RegOffset, Data) \
XCsuDma_Out32((BaseAddress) + (u32)(RegOffset), (u32)(Data))
#ifdef __cplusplus
}
#endif
#endif /* End of protection macro */
/** @} */

View file

@ -0,0 +1,274 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcsudma_intr.c
* @addtogroup csudma_v1_0
* @{
*
* This file contains interrupt related functions of Xilinx CSU_DMA core.
* Please see xcsudma.h for more details of the driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- ---------------------------------------------------
* 1.0 vnsld 22/10/14 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xcsudma.h"
/************************** Function Prototypes ******************************/
/************************** Function Definitions *****************************/
/*****************************************************************************/
/**
*
* This function returns interrupt status read from Interrupt Status Register.
* Use the XCSUDMA_IXR_*_MASK constants defined in xcsudma_hw.h to interpret the
* returned value.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
*
* @return The pending interrupts of the CSU_DMA. Use th following masks
* to interpret the returned value.
* XCSUDMA_IXR_SRC_MASK - For Source channel
* XCSUDMA_IXR_DST_MASK - For Destination channel
*
* @note None.
*
******************************************************************************/
u32 XCsuDma_IntrGetStatus(XCsuDma *InstancePtr, XCsuDma_Channel Channel)
{
u32 Data;
/* Verify arguments */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
Data = XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
(u32)(XCSUDMA_I_STS_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF)));
return Data;
}
/*****************************************************************************/
/**
*
* This function clears interrupt(s). Every bit set in Interrupt Status
* Register indicates that a specific type of interrupt is occurring, and this
* function clears one or more interrupts by writing a bit mask to Interrupt
* Clear Register.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
* @param Mask is the mask to clear. Bit positions of 1 will be cleared.
* Bit positions of 0 will not change the previous interrupt
* status. This mask is formed by OR'ing XCSUDMA_IXR_* bits
* defined in xcsudma_hw.h.
*
* @note None.
*
******************************************************************************/
void XCsuDma_IntrClear(XCsuDma *InstancePtr, XCsuDma_Channel Channel, u32 Mask)
{
/* Verify arguments */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
if (Channel == (XCSUDMA_SRC_CHANNEL)) {
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
(u32)(XCSUDMA_I_STS_OFFSET),
(Mask & (u32)(XCSUDMA_IXR_SRC_MASK)));
}
else {
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_I_STS_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))),
(Mask & (u32)(XCSUDMA_IXR_DST_MASK)));
}
}
/*****************************************************************************/
/**
*
* This function enables the interrupt(s). Use the XCSUDMA_IXR_*_MASK constants
* defined in xcsudma_hw.h to create the bit-mask to enable interrupts.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
* @param Mask contains interrupts to be enabled.
* - Bit positions of 1 will be enabled.
* This mask is formed by OR'ing XCSUDMA_IXR_*_MASK bits defined
* in xcsudma_hw.h.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCsuDma_EnableIntr(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
u32 Mask)
{
u32 Data;
/* Verify arguments */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
if (Channel == (XCSUDMA_SRC_CHANNEL)) {
Data = Mask & (u32)(XCSUDMA_IXR_SRC_MASK);
}
else {
Data = Mask & (u32)(XCSUDMA_IXR_DST_MASK);
}
/*
* Write the mask to the IER Register
*/
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_I_EN_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))), Data);
}
/*****************************************************************************/
/**
*
* This function disables the interrupt(s). Use the XCSUDMA_IXR_*_MASK constants
* defined in xcsudma_hw.h to create the bit-mask to disable interrupts.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
* @param Mask contains interrupts to be disabled.
* - Bit positions of 1 will be disabled.
* This mask is formed by OR'ing XCSUDMA_IXR_*_MASK bits defined
* in xcsudma_hw.h.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XCsuDma_DisableIntr(XCsuDma *InstancePtr, XCsuDma_Channel Channel,
u32 Mask)
{
u32 Data;
/* Verify arguments */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
if (Channel == XCSUDMA_SRC_CHANNEL) {
Data = (Mask) & (u32)(XCSUDMA_IXR_SRC_MASK);
}
else {
Data = (Mask) & (u32)(XCSUDMA_IXR_DST_MASK);
}
/*
* Write the mask to the IDR Register
*/
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_I_DIS_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF))), Data);
}
/*****************************************************************************/
/**
*
* This function returns the interrupt mask to know which interrupts are
* enabled and which of them were disaled.
*
* @param InstancePtr is a pointer to XCsuDma instance to be worked on.
* @param Channel represents the type of channel either it is Source or
* Destination.
* Source channel - XCSUDMA_SRC_CHANNEL
* Destination Channel - XCSUDMA_DST_CHANNEL
*
* @return The current interrupt mask. The mask indicates which interrupts
* are enabled/disabled.
* 0 bit represents .....corresponding interrupt is enabled.
* 1 bit represents .....Corresponding interrupt is disabled.
* To interpret returned mask use
* XCSUDMA_IXR_SRC_MASK........For source channel
* XCSUDMA_IXR_DST_MASK........For destination channel
*
* @note None.
*
******************************************************************************/
u32 XCsuDma_GetIntrMask(XCsuDma *InstancePtr, XCsuDma_Channel Channel)
{
/* Verify arguments */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid((Channel == (XCSUDMA_SRC_CHANNEL)) ||
(Channel == (XCSUDMA_DST_CHANNEL)));
/*
* Read the Interrupt Mask register
*/
return (XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
((u32)(XCSUDMA_I_MASK_OFFSET) +
((u32)Channel * (u32)(XCSUDMA_OFFSET_DIFF)))));
}
/** @} */

View file

@ -0,0 +1,125 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcsudma_selftest.c
* @addtogroup csudma_v1_0
* @{
*
* This file contains a diagnostic self-test function for the CSU_DMA driver.
* Refer to the header file xcsudma.h for more detailed information.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- ---------------------------------------------------
* 1.0 vnsld 22/10/14 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xcsudma.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
/************************** Function Definitions *****************************/
/*****************************************************************************/
/**
*
* This function runs a self-test on the driver and hardware device. Performs
* reset of both source and destination channels and checks if reset is working
* properly or not.
*
* @param InstancePtr is a pointer to the XCsuDma instance.
*
* @return
* - XST_SUCCESS if the self-test passed.
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
s32 XCsuDma_SelfTest(XCsuDma *InstancePtr)
{
u32 Data;
s32 Status;
/* Verify arguments. */
Xil_AssertNonvoid(InstancePtr != NULL);
Data = XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
(u32)(XCSUDMA_CTRL_OFFSET));
/* Changing Endianess of Source channel */
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
(u32)(XCSUDMA_CTRL_OFFSET),
((Data) | (u32)(XCSUDMA_CTRL_ENDIAN_MASK)));
if ((XCsuDma_ReadReg(InstancePtr->Config.BaseAddress,
(u32)(XCSUDMA_CTRL_OFFSET)) &
(u32)(XCSUDMA_CTRL_ENDIAN_MASK)) ==
(XCSUDMA_CTRL_ENDIAN_MASK)) {
Status = (s32)(XST_SUCCESS);
}
else {
Status = (s32)(XST_FAILURE);
}
/* Changes made are being reverted back */
XCsuDma_WriteReg(InstancePtr->Config.BaseAddress,
(u32)(XCSUDMA_CTRL_OFFSET), Data);
return Status;
}
/** @} */

View file

@ -0,0 +1,107 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcsudma_sinit.c
* @addtogroup csudma_v1_0
* @{
*
* This file contains static initialization methods for Xilinx CSU_DMA core.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- ---------------------------------------------------
* 1.0 vnsld 22/10/14 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xcsudma.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/************************** Function Definitions *****************************/
/*****************************************************************************/
/**
*
* XCsuDma_LookupConfig returns a reference to an XCsuDma_Config structure
* based on the unique device id, <i>DeviceId</i>. The return value will refer
* to an entry in the device configuration table defined in the xcsudma_g.c
* file.
*
* @param DeviceId is the unique device ID of the device for the lookup
* operation.
*
* @return CfgPtr is a reference to a config record in the configuration
* table (in xcsudma_g.c) corresponding to <i>DeviceId</i>, or
* NULL if no match is found.
*
* @note None.
******************************************************************************/
XCsuDma_Config *XCsuDma_LookupConfig(u16 DeviceId)
{
extern XCsuDma_Config XCsuDma_ConfigTable[XPAR_XCSUDMA_NUM_INSTANCES];
XCsuDma_Config *CfgPtr = NULL;
u32 Index;
/* Checks all the instances */
for (Index = (u32)0x0; Index < (u32)(XPAR_XCSUDMA_NUM_INSTANCES);
Index++) {
if (XCsuDma_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XCsuDma_ConfigTable[Index];
break;
}
}
return (XCsuDma_Config *)CfgPtr;
}
/** @} */

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner xemacps_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling emacps"
xemacps_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: xemacps_includes
xemacps_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

View file

@ -0,0 +1,489 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemacps.c
* @addtogroup emacps_v3_1
* @{
*
* The XEmacPs driver. Functions in this file are the minimum required functions
* for this driver. See xemacps.h for a detailed description of the driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wsy 01/10/10 First release
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp GEM specification and
* 64-bit changes.
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.0 hk 02/20/15 Added support for jumbo frames. Increase AHB burst.
* Disable extended mode. Perform all 64 bit changes under
* check for arch64.
* 3.1 hk 08/10/15 Update upper 32 bit tx and rx queue ptr registers
*
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xemacps.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
void XEmacPs_StubHandler(void); /* Default handler routine */
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
* Initialize a specific XEmacPs instance/driver. The initialization entails:
* - Initialize fields of the XEmacPs instance structure
* - Reset hardware and apply default options
* - Configure the DMA channels
*
* The PHY is setup independently from the device. Use the MII or whatever other
* interface may be present for setup.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @param CfgPtr is the device configuration structure containing required
* hardware build data.
* @param EffectiveAddress is the base address of the device. If address
* translation is not utilized, this parameter can be passed in using
* CfgPtr->Config.BaseAddress to specify the physical base address.
*
* @return
* - XST_SUCCESS if initialization was successful
*
******************************************************************************/
LONG XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config * CfgPtr,
UINTPTR EffectiveAddress)
{
/* Verify arguments */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(CfgPtr != NULL);
/* Set device base address and ID */
InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
InstancePtr->Config.BaseAddress = EffectiveAddress;
/* Set callbacks to an initial stub routine */
InstancePtr->SendHandler = ((XEmacPs_Handler)((void*)XEmacPs_StubHandler));
InstancePtr->RecvHandler = ((XEmacPs_Handler)(void*)XEmacPs_StubHandler);
InstancePtr->ErrorHandler = ((XEmacPs_ErrHandler)(void*)XEmacPs_StubHandler);
/* Reset the hardware and set default options */
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
XEmacPs_Reset(InstancePtr);
return (LONG)(XST_SUCCESS);
}
/*****************************************************************************/
/**
* Start the Ethernet controller as follows:
* - Enable transmitter if XTE_TRANSMIT_ENABLE_OPTION is set
* - Enable receiver if XTE_RECEIVER_ENABLE_OPTION is set
* - Start the SG DMA send and receive channels and enable the device
* interrupt
*
* @param InstancePtr is a pointer to the instance to be worked on.
*
* @return N/A
*
* @note
* Hardware is configured with scatter-gather DMA, the driver expects to start
* the scatter-gather channels and expects that the user has previously set up
* the buffer descriptor lists.
*
* This function makes use of internal resources that are shared between the
* Start, Stop, and Set/ClearOptions functions. So if one task might be setting
* device options while another is trying to start the device, the user is
* required to provide protection of this shared data (typically using a
* semaphore).
*
* This function must not be preempted by an interrupt that may service the
* device.
*
******************************************************************************/
void XEmacPs_Start(XEmacPs *InstancePtr)
{
u32 Reg;
/* Assert bad arguments and conditions */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
/* Start DMA */
/* When starting the DMA channels, both transmit and receive sides
* need an initialized BD list.
*/
if (InstancePtr->Version == 2) {
Xil_AssertVoid(InstancePtr->RxBdRing.BaseBdAddr != 0);
Xil_AssertVoid(InstancePtr->TxBdRing.BaseBdAddr != 0);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_RXQBASE_OFFSET,
InstancePtr->RxBdRing.BaseBdAddr);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_TXQBASE_OFFSET,
InstancePtr->TxBdRing.BaseBdAddr);
}
/* clear any existed int status */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
XEMACPS_IXR_ALL_MASK);
/* Enable transmitter if not already enabled */
if ((InstancePtr->Options & (u32)XEMACPS_TRANSMITTER_ENABLE_OPTION)!=0x00000000U) {
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
if ((!(Reg & XEMACPS_NWCTRL_TXEN_MASK))==TRUE) {
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET,
Reg | (u32)XEMACPS_NWCTRL_TXEN_MASK);
}
}
/* Enable receiver if not already enabled */
if ((InstancePtr->Options & XEMACPS_RECEIVER_ENABLE_OPTION) != 0x00000000U) {
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
if ((!(Reg & XEMACPS_NWCTRL_RXEN_MASK))==TRUE) {
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET,
Reg | (u32)XEMACPS_NWCTRL_RXEN_MASK);
}
}
/* Enable TX and RX interrupts */
XEmacPs_IntEnable(InstancePtr, (XEMACPS_IXR_TX_ERR_MASK |
XEMACPS_IXR_RX_ERR_MASK | (u32)XEMACPS_IXR_FRAMERX_MASK |
(u32)XEMACPS_IXR_TXCOMPL_MASK));
/* Enable TX Q1 Interrupts */
if (InstancePtr->Version > 2)
XEmacPs_IntQ1Enable(InstancePtr, XEMACPS_INTQ1_IXR_ALL_MASK);
/* Mark as started */
InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
return;
}
/*****************************************************************************/
/**
* Gracefully stop the Ethernet MAC as follows:
* - Disable all interrupts from this device
* - Stop DMA channels
* - Disable the tansmitter and receiver
*
* Device options currently in effect are not changed.
*
* This function will disable all interrupts. Default interrupts settings that
* had been enabled will be restored when XEmacPs_Start() is called.
*
* @param InstancePtr is a pointer to the instance to be worked on.
*
* @note
* This function makes use of internal resources that are shared between the
* Start, Stop, SetOptions, and ClearOptions functions. So if one task might be
* setting device options while another is trying to start the device, the user
* is required to provide protection of this shared data (typically using a
* semaphore).
*
* Stopping the DMA channels causes this function to block until the DMA
* operation is complete.
*
******************************************************************************/
void XEmacPs_Stop(XEmacPs *InstancePtr)
{
u32 Reg;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
/* Disable all interrupts */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
XEMACPS_IXR_ALL_MASK);
/* Disable the receiver & transmitter */
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
Reg &= (u32)(~XEMACPS_NWCTRL_RXEN_MASK);
Reg &= (u32)(~XEMACPS_NWCTRL_TXEN_MASK);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET, Reg);
/* Mark as stopped */
InstancePtr->IsStarted = 0U;
}
/*****************************************************************************/
/**
* Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
* transmitter, and the receiver.
*
* Steps to reset
* - Stops transmit and receive channels
* - Stops DMA
* - Configure transmit and receive buffer size to default
* - Clear transmit and receive status register and counters
* - Clear all interrupt sources
* - Clear phy (if there is any previously detected) address
* - Clear MAC addresses (1-4) as well as Type IDs and hash value
*
* All options are placed in their default state. Any frames in the
* descriptor lists will remain in the lists. The side effect of doing
* this is that after a reset and following a restart of the device, frames
* were in the list before the reset may be transmitted or received.
*
* The upper layer software is responsible for re-configuring (if necessary)
* and restarting the MAC after the reset. Note also that driver statistics
* are not cleared on reset. It is up to the upper layer software to clear the
* statistics if needed.
*
* When a reset is required, the driver notifies the upper layer software of
* this need through the ErrorHandler callback and specific status codes.
* The upper layer software is responsible for calling this Reset function
* and then re-configuring the device.
*
* @param InstancePtr is a pointer to the instance to be worked on.
*
******************************************************************************/
void XEmacPs_Reset(XEmacPs *InstancePtr)
{
u32 Reg;
u8 i;
s8 EmacPs_zero_MAC[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
/* Stop the device and reset hardware */
XEmacPs_Stop(InstancePtr);
InstancePtr->Options = XEMACPS_DEFAULT_OPTIONS;
InstancePtr->Version = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, 0xFC);
InstancePtr->Version = (InstancePtr->Version >> 16) & 0xFFF;
InstancePtr->MaxMtuSize = XEMACPS_MTU;
InstancePtr->MaxFrameSize = XEMACPS_MTU + XEMACPS_HDR_SIZE +
XEMACPS_TRL_SIZE;
InstancePtr->MaxVlanFrameSize = InstancePtr->MaxFrameSize +
XEMACPS_HDR_VLAN_SIZE;
InstancePtr->RxBufMask = XEMACPS_RXBUF_LEN_MASK;
/* Setup hardware with default values */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET,
(XEMACPS_NWCTRL_STATCLR_MASK |
XEMACPS_NWCTRL_MDEN_MASK) &
(u32)(~XEMACPS_NWCTRL_LOOPEN_MASK));
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCFG_OFFSET);
Reg &= XEMACPS_NWCFG_MDCCLKDIV_MASK;
Reg = Reg | (u32)XEMACPS_NWCFG_100_MASK |
(u32)XEMACPS_NWCFG_FDEN_MASK |
(u32)XEMACPS_NWCFG_UCASTHASHEN_MASK;
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCFG_OFFSET, Reg);
if (InstancePtr->Version > 2) {
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET,
(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET) |
XEMACPS_NWCFG_DWIDTH_64_MASK));
}
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_DMACR_OFFSET,
(((((u32)XEMACPS_RX_BUF_SIZE / (u32)XEMACPS_RX_BUF_UNIT) +
(((((u32)XEMACPS_RX_BUF_SIZE %
(u32)XEMACPS_RX_BUF_UNIT))!=(u32)0) ? 1U : 0U)) <<
(u32)(XEMACPS_DMACR_RXBUF_SHIFT)) &
(u32)(XEMACPS_DMACR_RXBUF_MASK)) |
(u32)XEMACPS_DMACR_RXSIZE_MASK |
(u32)XEMACPS_DMACR_TXSIZE_MASK);
/* Single bursts */
/* FIXME: Why Single bursts? */
if (InstancePtr->Version > 2) {
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_DMACR_OFFSET) |
#ifdef __aarch64__
(u32)XEMACPS_DMACR_ADDR_WIDTH_64 |
#endif
(u32)XEMACPS_DMACR_INCR16_AHB_BURST));
}
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_TXSR_OFFSET, 0x0U);
XEmacPs_SetQueuePtr(InstancePtr, 0, 0x00U, (u16)XEMACPS_SEND);
if (InstancePtr->Version > 2)
XEmacPs_SetQueuePtr(InstancePtr, 0, 0x01U, (u16)XEMACPS_SEND);
XEmacPs_SetQueuePtr(InstancePtr, 0, 0x00U, (u16)XEMACPS_RECV);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_RXSR_OFFSET, 0x0U);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
XEMACPS_IXR_ALL_MASK);
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_ISR_OFFSET);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
Reg);
XEmacPs_ClearHash(InstancePtr);
for (i = 1U; i < 5U; i++) {
(void)XEmacPs_SetMacAddress(InstancePtr, EmacPs_zero_MAC, i);
(void)XEmacPs_SetTypeIdCheck(InstancePtr, 0x00000000U, i);
}
/* clear all counters */
for (i = 0U; i < (u8)((XEMACPS_LAST_OFFSET - XEMACPS_OCTTXL_OFFSET) / 4U);
i++) {
(void)XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_OCTTXL_OFFSET + (u32)(((u32)i) * ((u32)4)));
}
/* Disable the receiver */
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
Reg &= (u32)(~XEMACPS_NWCTRL_RXEN_MASK);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET, Reg);
/* Sync default options with hardware but leave receiver and
* transmitter disabled. They get enabled with XEmacPs_Start() if
* XEMACPS_TRANSMITTER_ENABLE_OPTION and
* XEMACPS_RECEIVER_ENABLE_OPTION are set.
*/
(void)XEmacPs_SetOptions(InstancePtr, InstancePtr->Options &
~((u32)XEMACPS_TRANSMITTER_ENABLE_OPTION |
(u32)XEMACPS_RECEIVER_ENABLE_OPTION));
(void)XEmacPs_ClearOptions(InstancePtr, ~InstancePtr->Options);
}
/******************************************************************************/
/**
* This is a stub for the asynchronous callbacks. The stub is here in case the
* upper layer forgot to set the handler(s). On initialization, all handlers are
* set to this callback. It is considered an error for this handler to be
* invoked.
*
******************************************************************************/
void XEmacPs_StubHandler(void)
{
Xil_AssertVoidAlways();
}
/*****************************************************************************/
/**
* This function sets the start address of the transmit/receive buffer queue.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @QPtr Address of the Queue to be written
* @QueueNum Buffer Queue Index
* @Direction Transmit/Recive
*
* @note
* The buffer queue addresses has to be set before starting the transfer, so
* this function has to be called in prior to XEmacPs_Start()
*
******************************************************************************/
void XEmacPs_SetQueuePtr(XEmacPs *InstancePtr, UINTPTR QPtr, u8 QueueNum,
u16 Direction)
{
/* Assert bad arguments and conditions */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
/* If already started, then there is nothing to do */
if (InstancePtr->IsStarted == (u32)XIL_COMPONENT_IS_STARTED) {
return;
}
if (QueueNum == 0x00U) {
if (Direction == XEMACPS_SEND) {
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_TXQBASE_OFFSET,
(QPtr & ULONG64_LO_MASK));
} else {
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_RXQBASE_OFFSET,
(QPtr & ULONG64_LO_MASK));
}
}
else {
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_TXQ1BASE_OFFSET,
(QPtr & ULONG64_LO_MASK));
}
#ifdef __aarch64__
if (Direction == XEMACPS_SEND) {
/* Set the MSB of TX Queue start address */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_MSBBUF_TXQBASE_OFFSET,
(u32)((QPtr & ULONG64_HI_MASK) >> 32U));
} else {
/* Set the MSB of RX Queue start address */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_MSBBUF_RXQBASE_OFFSET,
(u32)((QPtr & ULONG64_HI_MASK) >> 32U));
}
#endif
}
/** @} */

View file

@ -0,0 +1,792 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2016 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xemacps.h
* @addtogroup emacps_v3_1
* @{
* @details
*
* The Xilinx Embedded Processor Block Ethernet driver.
*
* For a full description of XEMACPS features, please see the hardware spec.
* This driver supports the following features:
* - Memory mapped access to host interface registers
* - Statistics counter registers for RMON/MIB
* - API for interrupt driven frame transfers for hardware configured DMA
* - Virtual memory support
* - Unicast, broadcast, and multicast receive address filtering
* - Full and half duplex operation
* - Automatic PAD & FCS insertion and stripping
* - Flow control
* - Support up to four 48bit addresses
* - Address checking for four specific 48bit addresses
* - VLAN frame support
* - Pause frame support
* - Large frame support up to 1536 bytes
* - Checksum offload
*
* <b>Driver Description</b>
*
* The device driver enables higher layer software (e.g., an application) to
* communicate to the XEmacPs. The driver handles transmission and reception
* of Ethernet frames, as well as configuration and control. No pre or post
* processing of frame data is performed. The driver does not validate the
* contents of an incoming frame in addition to what has already occurred in
* hardware.
* A single device driver can support multiple devices even when those devices
* have significantly different configurations.
*
* <b>Initialization & Configuration</b>
*
* The XEmacPs_Config structure is used by the driver to configure itself.
* This configuration structure is typically created by the tool-chain based
* on hardware build properties.
*
* The driver instance can be initialized in
*
* - XEmacPs_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddress): Uses a
* configuration structure provided by the caller. If running in a system
* with address translation, the provided virtual memory base address
* replaces the physical address present in the configuration structure.
*
* The device supports DMA only as current development plan. No FIFO mode is
* supported. The driver expects to start the DMA channels and expects that
* the user has set up the buffer descriptor lists.
*
* <b>Interrupts and Asynchronous Callbacks</b>
*
* The driver has no dependencies on the interrupt controller. When an
* interrupt occurs, the handler will perform a small amount of
* housekeeping work, determine the source of the interrupt, and call the
* appropriate callback function. All callbacks are registered by the user
* level application.
*
* <b>Virtual Memory</b>
*
* All virtual to physical memory mappings must occur prior to accessing the
* driver API.
*
* For DMA transactions, user buffers supplied to the driver must be in terms
* of their physical address.
*
* <b>DMA</b>
*
* The DMA engine uses buffer descriptors (BDs) to describe Ethernet frames.
* These BDs are typically chained together into a list the hardware follows
* when transferring data in and out of the packet buffers. Each BD describes
* a memory region containing either a full or partial Ethernet packet.
*
* Interrupt coalescing is not suppoted from this built-in DMA engine.
*
* This API requires the user to understand how the DMA operates. The
* following paragraphs provide some explanation, but the user is encouraged
* to read documentation in xemacps_bdring.h as well as study example code
* that accompanies this driver.
*
* The API is designed to get BDs to and from the DMA engine in the most
* efficient means possible. The first step is to establish a memory region
* to contain all BDs for a specific channel. This is done with
* XEmacPs_BdRingCreate(). This function sets up a BD ring that hardware will
* follow as BDs are processed. The ring will consist of a user defined number
* of BDs which will all be partially initialized. For example on the transmit
* channel, the driver will initialize all BDs' so that they are configured
* for transmit. The more fields that can be permanently setup at
* initialization, then the fewer accesses will be needed to each BD while
* the DMA engine is in operation resulting in better throughput and CPU
* utilization. The best case initialization would require the user to set
* only a frame buffer address and length prior to submitting the BD to the
* engine.
*
* BDs move through the engine with the help of functions
* XEmacPs_BdRingAlloc(), XEmacPs_BdRingToHw(), XEmacPs_BdRingFromHw(),
* and XEmacPs_BdRingFree().
* All these functions handle BDs that are in place. That is, there are no
* copies of BDs kept anywhere and any BD the user interacts with is an actual
* BD from the same ring hardware accesses.
*
* BDs in the ring go through a series of states as follows:
* 1. Idle. The driver controls BDs in this state.
* 2. The user has data to transfer. XEmacPs_BdRingAlloc() is called to
* reserve BD(s). Once allocated, the user may setup the BD(s) with
* frame buffer address, length, and other attributes. The user controls
* BDs in this state.
* 3. The user submits BDs to the DMA engine with XEmacPs_BdRingToHw. BDs
* in this state are either waiting to be processed by hardware, are in
* process, or have been processed. The DMA engine controls BDs in this
* state.
* 4. Processed BDs are retrieved with XEmacEpv_BdRingFromHw() by the
* user. Once retrieved, the user can examine each BD for the outcome of
* the DMA transfer. The user controls BDs in this state. After examining
* the BDs the user calls XEmacPs_BdRingFree() which places the BDs back
* into state 1.
*
* Each of the four BD accessor functions operate on a set of BDs. A set is
* defined as a segment of the BD ring consisting of one or more BDs. The user
* views the set as a pointer to the first BD along with the number of BDs for
* that set. The set can be navigated by using macros XEmacPs_BdNext(). The
* user must exercise extreme caution when changing BDs in a set as there is
* nothing to prevent doing a mBdNext past the end of the set and modifying a
* BD out of bounds.
*
* XEmacPs_BdRingAlloc() + XEmacPs_BdRingToHw(), as well as
* XEmacPs_BdRingFromHw() + XEmacPs_BdRingFree() are designed to be used in
* tandem. The same BD set retrieved with BdRingAlloc should be the same one
* provided to hardware with BdRingToHw. Same goes with BdRingFromHw and
* BdRIngFree.
*
* <b>Alignment & Data Cache Restrictions</b>
*
* Due to the design of the hardware, all RX buffers, BDs need to be 4-byte
* aligned. Please reference xemacps_bd.h for cache related macros.
*
* DMA Tx:
*
* - If frame buffers exist in cached memory, then they must be flushed
* prior to committing them to hardware.
*
* DMA Rx:
*
* - If frame buffers exist in cached memory, then the cache must be
* invalidated for the memory region containing the frame prior to data
* access
*
* Both cache invalidate/flush are taken care of in driver code.
*
* <b>Buffer Copying</b>
*
* The driver is designed for a zero-copy buffer scheme. That is, the driver
* will not copy buffers. This avoids potential throughput bottlenecks within
* the driver. If byte copying is required, then the transfer will take longer
* to complete.
*
* <b>Checksum Offloading</b>
*
* The Embedded Processor Block Ethernet can be configured to perform IP, TCP
* and UDP checksum offloading in both receive and transmit directions.
*
* IP packets contain a 16-bit checksum field, which is the 16-bit 1s
* complement of the 1s complement sum of all 16-bit words in the header.
* TCP and UDP packets contain a 16-bit checksum field, which is the 16-bit
* 1s complement of the 1s complement sum of all 16-bit words in the header,
* the data and a conceptual pseudo header.
*
* To calculate these checksums in software requires each byte of the packet
* to be read. For TCP and UDP this can use a large amount of processing power.
* Offloading the checksum calculation to hardware can result in significant
* performance improvements.
*
* The transmit checksum offload is only available to use DMA in packet buffer
* mode. This is because the complete frame to be transmitted must be read
* into the packet buffer memory before the checksum can be calculated and
* written to the header at the beginning of the frame.
*
* For IP, TCP or UDP receive checksum offload to be useful, the operating
* system containing the protocol stack must be aware that this offload is
* available so that it can make use of the fact that the hardware has verified
* the checksum.
*
* When receive checksum offloading is enabled in the hardware, the IP header
* checksum is checked, where the packet meets the following criteria:
*
* 1. If present, the VLAN header must be four octets long and the CFI bit
* must not be set.
* 2. Encapsulation must be RFC 894 Ethernet Type Encoding or RFC 1042 SNAP
* encoding.
* 3. IP v4 packet.
* 4. IP header is of a valid length.
* 5. Good IP header checksum.
* 6. No IP fragmentation.
* 7. TCP or UDP packet.
*
* When an IP, TCP or UDP frame is received, the receive buffer descriptor
* gives an indication if the hardware was able to verify the checksums.
* There is also an indication if the frame had SNAP encapsulation. These
* indication bits will replace the type ID match indication bits when the
* receive checksum offload is enabled.
*
* If any of the checksums are verified incorrect by the hardware, the packet
* is discarded and the appropriate statistics counter incremented.
*
* <b>PHY Interfaces</b>
*
* RGMII 1.3 is the only interface supported.
*
* <b>Asserts</b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on
* parameters. Asserts can be turned off on a system-wide basis by defining,
* at compile time, the NDEBUG identifier. By default, asserts are turned on
* and it is recommended that users leave asserts on during development. For
* deployment use -DNDEBUG compiler switch to remove assert code.
*
* @note
*
* Xilinx drivers are typically composed of two parts, one is the driver
* and the other is the adapter. The driver is independent of OS and processor
* and is intended to be highly portable. The adapter is OS-specific and
* facilitates communication between the driver and an OS.
* This driver is intended to be RTOS and processor independent. Any needs for
* dynamic memory management, threads or thread mutual exclusion, or cache
* control must be satisfied bythe layer above this driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wsy 01/10/10 First release
* 1.00a asa 11/21/11 The function XEmacPs_BdRingFromHwTx in file
* xemacps_bdring.c is modified. Earlier it was checking for
* "BdLimit"(passed argument) number of BDs for finding out
* which BDs are successfully processed. Now one more check
* is added. It looks for BDs till the current BD pointer
* reaches HwTail. By doing this processing time is saved.
* 1.00a asa 01/24/12 The function XEmacPs_BdRingFromHwTx in file
* xemacps_bdring.c is modified. Now start of packet is
* searched for returning the number of BDs processed.
* 1.02a asa 11/05/12 Added a new API for deleting an entry from the HASH
* registers. Added a new API to set the bust length.
* Added some new hash-defines.
* 1.03a asa 01/23/12 Fix for CR #692702 which updates error handling for
* Rx errors. Under heavy Rx traffic, there will be a large
* number of errors related to receive buffer not available.
* Because of a HW bug (SI #692601), under such heavy errors,
* the Rx data path can become unresponsive. To reduce the
* probabilities for hitting this HW bug, the SW writes to
* bit 18 to flush a packet from Rx DPRAM immediately. The
* changes for it are done in the function
* XEmacPs_IntrHandler.
* 1.05a asa 09/23/13 Cache operations on BDs are not required and hence
* removed. It is expected that all BDs are allocated in
* from uncached area.
* 1.06a asa 11/02/13 Changed the value for XEMACPS_RXBUF_LEN_MASK from 0x3fff
* to 0x1fff. This fixes the CR#744902.
* Made changes in example file xemacps_example.h to fix compilation
* issues with iarcc compiler.
* 2.0 adk 10/12/13 Updated as per the New Tcl API's
* 2.1 adk 11/08/14 Fixed the CR#811288. Changes are made in the driver tcl file.
* 2.1 bss 09/08/14 Modified driver tcl to fix CR#820349 to export phy
* address in xparameters.h when GMII to RGMII converter
* is present in hw.
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp GEM specification and 64-bit
* changes.
* 2.2 adk 29/10/14 Fixed CR#827686 when PCS/PMA core is configured with
* 1000BASE-X mode export proper values to the xparameters.h
* file. Changes are made in the driver tcl file.
* 3.0 adk 08/1/15 Don't include gem in peripheral test when gem is
* configured with PCS/PMA Core. Changes are made in the
* test app tcl(CR:827686).
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.0 hk 03/18/15 Added support for jumbo frames. Increase AHB burst.
* Disable extended mode. Perform all 64 bit changes under
* check for arch64.
* Remove "used bit set" from TX error interrupt masks.
* 3.1 hk 07/27/15 Do not call error handler with '0' error code when
* there is no error. CR# 869403
* 08/10/15 Update upper 32 bit tx and rx queue ptr registers.
* 3.2 hk 02/22/16 Added SGMII support for Zynq Ultrascale+ MPSoC.
* </pre>
*
****************************************************************************/
#ifndef XEMACPS_H /* prevent circular inclusions */
#define XEMACPS_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xemacps_hw.h"
#include "xemacps_bd.h"
#include "xemacps_bdring.h"
/************************** Constant Definitions ****************************/
/*
* Device information
*/
#define XEMACPS_DEVICE_NAME "xemacps"
#define XEMACPS_DEVICE_DESC "Xilinx PS 10/100/1000 MAC"
/** @name Configuration options
*
* Device configuration options. See the XEmacPs_SetOptions(),
* XEmacPs_ClearOptions() and XEmacPs_GetOptions() for information on how to
* use options.
*
* The default state of the options are noted and are what the device and
* driver will be set to after calling XEmacPs_Reset() or
* XEmacPs_Initialize().
*
* @{
*/
#define XEMACPS_PROMISC_OPTION 0x00000001U
/**< Accept all incoming packets.
* This option defaults to disabled (cleared) */
#define XEMACPS_FRAME1536_OPTION 0x00000002U
/**< Frame larger than 1516 support for Tx & Rx.
* This option defaults to disabled (cleared) */
#define XEMACPS_VLAN_OPTION 0x00000004U
/**< VLAN Rx & Tx frame support.
* This option defaults to disabled (cleared) */
#define XEMACPS_FLOW_CONTROL_OPTION 0x00000010U
/**< Enable recognition of flow control frames on Rx
* This option defaults to enabled (set) */
#define XEMACPS_FCS_STRIP_OPTION 0x00000020U
/**< Strip FCS and PAD from incoming frames. Note: PAD from VLAN frames is not
* stripped.
* This option defaults to enabled (set) */
#define XEMACPS_FCS_INSERT_OPTION 0x00000040U
/**< Generate FCS field and add PAD automatically for outgoing frames.
* This option defaults to disabled (cleared) */
#define XEMACPS_LENTYPE_ERR_OPTION 0x00000080U
/**< Enable Length/Type error checking for incoming frames. When this option is
* set, the MAC will filter frames that have a mismatched type/length field
* and if XEMACPS_REPORT_RXERR_OPTION is set, the user is notified when these
* types of frames are encountered. When this option is cleared, the MAC will
* allow these types of frames to be received.
*
* This option defaults to disabled (cleared) */
#define XEMACPS_TRANSMITTER_ENABLE_OPTION 0x00000100U
/**< Enable the transmitter.
* This option defaults to enabled (set) */
#define XEMACPS_RECEIVER_ENABLE_OPTION 0x00000200U
/**< Enable the receiver
* This option defaults to enabled (set) */
#define XEMACPS_BROADCAST_OPTION 0x00000400U
/**< Allow reception of the broadcast address
* This option defaults to enabled (set) */
#define XEMACPS_MULTICAST_OPTION 0x00000800U
/**< Allows reception of multicast addresses programmed into hash
* This option defaults to disabled (clear) */
#define XEMACPS_RX_CHKSUM_ENABLE_OPTION 0x00001000U
/**< Enable the RX checksum offload
* This option defaults to enabled (set) */
#define XEMACPS_TX_CHKSUM_ENABLE_OPTION 0x00002000U
/**< Enable the TX checksum offload
* This option defaults to enabled (set) */
#define XEMACPS_JUMBO_ENABLE_OPTION 0x00004000U
#define XEMACPS_SGMII_ENABLE_OPTION 0x00008000U
#define XEMACPS_DEFAULT_OPTIONS \
((u32)XEMACPS_FLOW_CONTROL_OPTION | \
(u32)XEMACPS_FCS_INSERT_OPTION | \
(u32)XEMACPS_FCS_STRIP_OPTION | \
(u32)XEMACPS_BROADCAST_OPTION | \
(u32)XEMACPS_LENTYPE_ERR_OPTION | \
(u32)XEMACPS_TRANSMITTER_ENABLE_OPTION | \
(u32)XEMACPS_RECEIVER_ENABLE_OPTION | \
(u32)XEMACPS_RX_CHKSUM_ENABLE_OPTION | \
(u32)XEMACPS_TX_CHKSUM_ENABLE_OPTION)
/**< Default options set when device is initialized or reset */
/*@}*/
/** @name Callback identifiers
*
* These constants are used as parameters to XEmacPs_SetHandler()
* @{
*/
#define XEMACPS_HANDLER_DMASEND 1U
#define XEMACPS_HANDLER_DMARECV 2U
#define XEMACPS_HANDLER_ERROR 3U
/*@}*/
/* Constants to determine the configuration of the hardware device. They are
* used to allow the driver to verify it can operate with the hardware.
*/
#define XEMACPS_MDIO_DIV_DFT MDC_DIV_32 /**< Default MDIO clock divisor */
/* The next few constants help upper layers determine the size of memory
* pools used for Ethernet buffers and descriptor lists.
*/
#define XEMACPS_MAC_ADDR_SIZE 6U /* size of Ethernet header */
#define XEMACPS_MTU 1500U /* max MTU size of Ethernet frame */
#define XEMACPS_MTU_JUMBO 10240U /* max MTU size of jumbo frame */
#define XEMACPS_HDR_SIZE 14U /* size of Ethernet header */
#define XEMACPS_HDR_VLAN_SIZE 18U /* size of Ethernet header with VLAN */
#define XEMACPS_TRL_SIZE 4U /* size of Ethernet trailer (FCS) */
#define XEMACPS_MAX_FRAME_SIZE (XEMACPS_MTU + XEMACPS_HDR_SIZE + \
XEMACPS_TRL_SIZE)
#define XEMACPS_MAX_VLAN_FRAME_SIZE (XEMACPS_MTU + XEMACPS_HDR_SIZE + \
XEMACPS_HDR_VLAN_SIZE + XEMACPS_TRL_SIZE)
#define XEMACPS_MAX_VLAN_FRAME_SIZE_JUMBO (XEMACPS_MTU_JUMBO + XEMACPS_HDR_SIZE + \
XEMACPS_HDR_VLAN_SIZE + XEMACPS_TRL_SIZE)
/* DMACR Bust length hash defines */
#define XEMACPS_SINGLE_BURST 0x00000001
#define XEMACPS_4BYTE_BURST 0x00000004
#define XEMACPS_8BYTE_BURST 0x00000008
#define XEMACPS_16BYTE_BURST 0x00000010
/**************************** Type Definitions ******************************/
/** @name Typedefs for callback functions
*
* These callbacks are invoked in interrupt context.
* @{
*/
/**
* Callback invoked when frame(s) have been sent or received in interrupt
* driven DMA mode. To set the send callback, invoke XEmacPs_SetHandler().
*
* @param CallBackRef is user data assigned when the callback was set.
*
* @note
* See xemacps_hw.h for bitmasks definitions and the device hardware spec for
* further information on their meaning.
*
*/
typedef void (*XEmacPs_Handler) (void *CallBackRef);
/**
* Callback when an asynchronous error occurs. To set this callback, invoke
* XEmacPs_SetHandler() with XEMACPS_HANDLER_ERROR in the HandlerType
* paramter.
*
* @param CallBackRef is user data assigned when the callback was set.
* @param Direction defines either receive or transmit error(s) has occurred.
* @param ErrorWord definition varies with Direction
*
*/
typedef void (*XEmacPs_ErrHandler) (void *CallBackRef, u8 Direction,
u32 ErrorWord);
/*@}*/
/**
* This typedef contains configuration information for a device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
UINTPTR BaseAddress;/**< Physical base address of IPIF registers */
} XEmacPs_Config;
/**
* The XEmacPs driver instance data. The user is required to allocate a
* structure of this type for every XEmacPs device in the system. A pointer
* to a structure of this type is then passed to the driver API functions.
*/
typedef struct XEmacPs_Instance {
XEmacPs_Config Config; /* Hardware configuration */
u32 IsStarted; /* Device is currently started */
u32 IsReady; /* Device is initialized and ready */
u32 Options; /* Current options word */
XEmacPs_BdRing TxBdRing; /* Transmit BD ring */
XEmacPs_BdRing RxBdRing; /* Receive BD ring */
XEmacPs_Handler SendHandler;
XEmacPs_Handler RecvHandler;
void *SendRef;
void *RecvRef;
XEmacPs_ErrHandler ErrorHandler;
void *ErrorRef;
u32 Version;
u32 RxBufMask;
u32 MaxMtuSize;
u32 MaxFrameSize;
u32 MaxVlanFrameSize;
} XEmacPs;
/***************** Macros (Inline Functions) Definitions ********************/
/****************************************************************************/
/**
* Retrieve the Tx ring object. This object can be used in the various Ring
* API functions.
*
* @param InstancePtr is the DMA channel to operate on.
*
* @return TxBdRing attribute
*
* @note
* C-style signature:
* XEmacPs_BdRing XEmacPs_GetTxRing(XEmacPs *InstancePtr)
*
*****************************************************************************/
#define XEmacPs_GetTxRing(InstancePtr) ((InstancePtr)->TxBdRing)
/****************************************************************************/
/**
* Retrieve the Rx ring object. This object can be used in the various Ring
* API functions.
*
* @param InstancePtr is the DMA channel to operate on.
*
* @return RxBdRing attribute
*
* @note
* C-style signature:
* XEmacPs_BdRing XEmacPs_GetRxRing(XEmacPs *InstancePtr)
*
*****************************************************************************/
#define XEmacPs_GetRxRing(InstancePtr) ((InstancePtr)->RxBdRing)
/****************************************************************************/
/**
*
* Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
* each bit set to 1 in <i>Mask</i>, will be enabled.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @param Mask contains a bit mask of interrupts to enable. The mask can
* be formed using a set of bitwise or'd values.
*
* @note
* The state of the transmitter and receiver are not modified by this function.
* C-style signature
* void XEmacPs_IntEnable(XEmacPs *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XEmacPs_IntEnable(InstancePtr, Mask) \
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
XEMACPS_IER_OFFSET, \
((Mask) & XEMACPS_IXR_ALL_MASK));
/****************************************************************************/
/**
*
* Disable interrupts specified in <i>Mask</i>. The corresponding interrupt for
* each bit set to 1 in <i>Mask</i>, will be enabled.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @param Mask contains a bit mask of interrupts to disable. The mask can
* be formed using a set of bitwise or'd values.
*
* @note
* The state of the transmitter and receiver are not modified by this function.
* C-style signature
* void XEmacPs_IntDisable(XEmacPs *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XEmacPs_IntDisable(InstancePtr, Mask) \
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
XEMACPS_IDR_OFFSET, \
((Mask) & XEMACPS_IXR_ALL_MASK));
/****************************************************************************/
/**
*
* Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
* each bit set to 1 in <i>Mask</i>, will be enabled.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @param Mask contains a bit mask of interrupts to enable. The mask can
* be formed using a set of bitwise or'd values.
*
* @note
* The state of the transmitter and receiver are not modified by this function.
* C-style signature
* void XEmacPs_IntQ1Enable(XEmacPs *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XEmacPs_IntQ1Enable(InstancePtr, Mask) \
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
XEMACPS_INTQ1_IER_OFFSET, \
((Mask) & XEMACPS_INTQ1_IXR_ALL_MASK));
/****************************************************************************/
/**
*
* Disable interrupts specified in <i>Mask</i>. The corresponding interrupt for
* each bit set to 1 in <i>Mask</i>, will be enabled.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @param Mask contains a bit mask of interrupts to disable. The mask can
* be formed using a set of bitwise or'd values.
*
* @note
* The state of the transmitter and receiver are not modified by this function.
* C-style signature
* void XEmacPs_IntDisable(XEmacPs *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XEmacPs_IntQ1Disable(InstancePtr, Mask) \
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
XEMACPS_INTQ1_IDR_OFFSET, \
((Mask) & XEMACPS_INTQ1_IXR_ALL_MASK));
/****************************************************************************/
/**
*
* This macro triggers trasmit circuit to send data currently in TX buffer(s).
*
* @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
*
* @return
*
* @note
*
* Signature: void XEmacPs_Transmit(XEmacPs *InstancePtr)
*
*****************************************************************************/
#define XEmacPs_Transmit(InstancePtr) \
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
XEMACPS_NWCTRL_OFFSET, \
(XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
XEMACPS_NWCTRL_OFFSET) | XEMACPS_NWCTRL_STARTTX_MASK))
/****************************************************************************/
/**
*
* This macro determines if the device is configured with checksum offloading
* on the receive channel
*
* @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
*
* @return
*
* Boolean TRUE if the device is configured with checksum offloading, or
* FALSE otherwise.
*
* @note
*
* Signature: u32 XEmacPs_IsRxCsum(XEmacPs *InstancePtr)
*
*****************************************************************************/
#define XEmacPs_IsRxCsum(InstancePtr) \
((XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
XEMACPS_NWCFG_OFFSET) & XEMACPS_NWCFG_RXCHKSUMEN_MASK) != 0U \
? TRUE : FALSE)
/****************************************************************************/
/**
*
* This macro determines if the device is configured with checksum offloading
* on the transmit channel
*
* @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
*
* @return
*
* Boolean TRUE if the device is configured with checksum offloading, or
* FALSE otherwise.
*
* @note
*
* Signature: u32 XEmacPs_IsTxCsum(XEmacPs *InstancePtr)
*
*****************************************************************************/
#define XEmacPs_IsTxCsum(InstancePtr) \
((XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
XEMACPS_DMACR_OFFSET) & XEMACPS_DMACR_TCPCKSUM_MASK) != 0U \
? TRUE : FALSE)
/************************** Function Prototypes *****************************/
/*
* Initialization functions in xemacps.c
*/
LONG XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config *CfgPtr,
UINTPTR EffectiveAddress);
void XEmacPs_Start(XEmacPs *InstancePtr);
void XEmacPs_Stop(XEmacPs *InstancePtr);
void XEmacPs_Reset(XEmacPs *InstancePtr);
void XEmacPs_SetQueuePtr(XEmacPs *InstancePtr, UINTPTR QPtr, u8 QueueNum,
u16 Direction);
/*
* Lookup configuration in xemacps_sinit.c
*/
XEmacPs_Config *XEmacPs_LookupConfig(u16 DeviceId);
/*
* Interrupt-related functions in xemacps_intr.c
* DMA only and FIFO is not supported. This DMA does not support coalescing.
*/
LONG XEmacPs_SetHandler(XEmacPs *InstancePtr, u32 HandlerType,
void *FuncPointer, void *CallBackRef);
void XEmacPs_IntrHandler(void *XEmacPsPtr);
/*
* MAC configuration/control functions in XEmacPs_control.c
*/
LONG XEmacPs_SetOptions(XEmacPs *InstancePtr, u32 Options);
LONG XEmacPs_ClearOptions(XEmacPs *InstancePtr, u32 Options);
u32 XEmacPs_GetOptions(XEmacPs *InstancePtr);
LONG XEmacPs_SetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index);
LONG XEmacPs_DeleteHash(XEmacPs *InstancePtr, void *AddressPtr);
void XEmacPs_GetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index);
LONG XEmacPs_SetHash(XEmacPs *InstancePtr, void *AddressPtr);
void XEmacPs_ClearHash(XEmacPs *InstancePtr);
void XEmacPs_GetHash(XEmacPs *InstancePtr, void *AddressPtr);
void XEmacPs_SetMdioDivisor(XEmacPs *InstancePtr,
XEmacPs_MdcDiv Divisor);
void XEmacPs_SetOperatingSpeed(XEmacPs *InstancePtr, u16 Speed);
u16 XEmacPs_GetOperatingSpeed(XEmacPs *InstancePtr);
LONG XEmacPs_PhyRead(XEmacPs *InstancePtr, u32 PhyAddress,
u32 RegisterNum, u16 *PhyDataPtr);
LONG XEmacPs_PhyWrite(XEmacPs *InstancePtr, u32 PhyAddress,
u32 RegisterNum, u16 PhyData);
LONG XEmacPs_SetTypeIdCheck(XEmacPs *InstancePtr, u32 Id_Check, u8 Index);
LONG XEmacPs_SendPausePacket(XEmacPs *InstancePtr);
void XEmacPs_DMABLengthUpdate(XEmacPs *InstancePtr, s32 BLength);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,804 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemacps_bd.h
* @addtogroup emacps_v3_1
* @{
*
* This header provides operations to manage buffer descriptors in support
* of scatter-gather DMA.
*
* The API exported by this header defines abstracted macros that allow the
* user to read/write specific BD fields.
*
* <b>Buffer Descriptors</b>
*
* A buffer descriptor (BD) defines a DMA transaction. The macros defined by
* this header file allow access to most fields within a BD to tailor a DMA
* transaction according to user and hardware requirements. See the hardware
* IP DMA spec for more information on BD fields and how they affect transfers.
*
* The XEmacPs_Bd structure defines a BD. The organization of this structure
* is driven mainly by the hardware for use in scatter-gather DMA transfers.
*
* <b>Performance</b>
*
* Limiting I/O to BDs can improve overall performance of the DMA channel.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wsy 01/10/10 First release
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale MP GEM specification
* and 64-bit changes.
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.0 hk 02/20/15 Added support for jumbo frames.
* Disable extended mode. Perform all 64 bit changes under
* check for arch64.
* 3.2 hk 11/18/15 Change BD typedef and number of words.
*
* </pre>
*
* ***************************************************************************
*/
#ifndef XEMACPS_BD_H /* prevent circular inclusions */
#define XEMACPS_BD_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include <string.h>
#include "xil_types.h"
#include "xil_assert.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
#ifdef __aarch64__
/* Minimum BD alignment */
#define XEMACPS_DMABD_MINIMUM_ALIGNMENT 64U
#define XEMACPS_BD_NUM_WORDS 4U
#else
/* Minimum BD alignment */
#define XEMACPS_DMABD_MINIMUM_ALIGNMENT 4U
#define XEMACPS_BD_NUM_WORDS 2U
#endif
/**
* The XEmacPs_Bd is the type for buffer descriptors (BDs).
*/
typedef u32 XEmacPs_Bd[XEMACPS_BD_NUM_WORDS];
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
* Zero out BD fields
*
* @param BdPtr is the BD pointer to operate on
*
* @return Nothing
*
* @note
* C-style signature:
* void XEmacPs_BdClear(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdClear(BdPtr) \
memset((BdPtr), 0, sizeof(XEmacPs_Bd))
/****************************************************************************/
/**
*
* Read the given Buffer Descriptor word.
*
* @param BaseAddress is the base address of the BD to read
* @param Offset is the word offset to be read
*
* @return The 32-bit value of the field
*
* @note
* C-style signature:
* u32 XEmacPs_BdRead(UINTPTR BaseAddress, UINTPTR Offset)
*
*****************************************************************************/
#define XEmacPs_BdRead(BaseAddress, Offset) \
(*(u32 *)((UINTPTR)((void*)(BaseAddress)) + (u32)(Offset)))
/****************************************************************************/
/**
*
* Write the given Buffer Descriptor word.
*
* @param BaseAddress is the base address of the BD to write
* @param Offset is the word offset to be written
* @param Data is the 32-bit value to write to the field
*
* @return None.
*
* @note
* C-style signature:
* void XEmacPs_BdWrite(UINTPTR BaseAddress, UINTPTR Offset, UINTPTR Data)
*
*****************************************************************************/
#define XEmacPs_BdWrite(BaseAddress, Offset, Data) \
(*(u32 *)((UINTPTR)(void*)(BaseAddress) + (u32)(Offset)) = (u32)(Data))
/*****************************************************************************/
/**
* Set the BD's Address field (word 0).
*
* @param BdPtr is the BD pointer to operate on
* @param Addr is the value to write to BD's status field.
*
* @note :
*
* C-style signature:
* void XEmacPs_BdSetAddressTx(XEmacPs_Bd* BdPtr, UINTPTR Addr)
*
*****************************************************************************/
#ifdef __aarch64__
#define XEmacPs_BdSetAddressTx(BdPtr, Addr) \
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
(u32)((Addr) & ULONG64_LO_MASK)); \
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_HI_OFFSET, \
(u32)(((Addr) & ULONG64_HI_MASK) >> 32U));
#else
#define XEmacPs_BdSetAddressTx(BdPtr, Addr) \
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, (u32)(Addr))
#endif
/*****************************************************************************/
/**
* Set the BD's Address field (word 0).
*
* @param BdPtr is the BD pointer to operate on
* @param Addr is the value to write to BD's status field.
*
* @note : Due to some bits are mixed within recevie BD's address field,
* read-modify-write is performed.
*
* C-style signature:
* void XEmacPs_BdSetAddressRx(XEmacPs_Bd* BdPtr, UINTPTR Addr)
*
*****************************************************************************/
#ifdef __aarch64__
#define XEmacPs_BdSetAddressRx(BdPtr, Addr) \
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
~XEMACPS_RXBUF_ADD_MASK) | ((u32)((Addr) & ULONG64_LO_MASK)))); \
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_HI_OFFSET, \
(u32)(((Addr) & ULONG64_HI_MASK) >> 32U));
#else
#define XEmacPs_BdSetAddressRx(BdPtr, Addr) \
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
~XEMACPS_RXBUF_ADD_MASK) | (UINTPTR)(Addr)))
#endif
/*****************************************************************************/
/**
* Set the BD's Status field (word 1).
*
* @param BdPtr is the BD pointer to operate on
* @param Data is the value to write to BD's status field.
*
* @note
* C-style signature:
* void XEmacPs_BdSetStatus(XEmacPs_Bd* BdPtr, UINTPTR Data)
*
*****************************************************************************/
#define XEmacPs_BdSetStatus(BdPtr, Data) \
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | (Data))
/*****************************************************************************/
/**
* Retrieve the BD's Packet DMA transfer status word (word 1).
*
* @param BdPtr is the BD pointer to operate on
*
* @return Status word
*
* @note
* C-style signature:
* u32 XEmacPs_BdGetStatus(XEmacPs_Bd* BdPtr)
*
* Due to the BD bit layout differences in transmit and receive. User's
* caution is required.
*****************************************************************************/
#define XEmacPs_BdGetStatus(BdPtr) \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET)
/*****************************************************************************/
/**
* Get the address (bits 0..31) of the BD's buffer address (word 0)
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdGetBufAddr(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#ifdef __aarch64__
#define XEmacPs_BdGetBufAddr(BdPtr) \
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) | \
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_HI_OFFSET)) << 32U)
#else
#define XEmacPs_BdGetBufAddr(BdPtr) \
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET))
#endif
/*****************************************************************************/
/**
* Set transfer length in bytes for the given BD. The length must be set each
* time a BD is submitted to hardware.
*
* @param BdPtr is the BD pointer to operate on
* @param LenBytes is the number of bytes to transfer.
*
* @note
* C-style signature:
* void XEmacPs_BdSetLength(XEmacPs_Bd* BdPtr, u32 LenBytes)
*
*****************************************************************************/
#define XEmacPs_BdSetLength(BdPtr, LenBytes) \
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
~XEMACPS_TXBUF_LEN_MASK) | (LenBytes)))
/*****************************************************************************/
/**
* Set transfer length in bytes for the given BD. The length must be set each
* time a BD is submitted to hardware.
*
* @param BdPtr is the BD pointer to operate on
* @param LenBytes is the number of bytes to transfer.
*
* @note
* C-style signature:
* void XEmacPs_BdSetLength(XEmacPs_Bd* BdPtr, u32 LenBytes)
*
*****************************************************************************/
#define XEmacPs_BdSetLength(BdPtr, LenBytes) \
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
~XEMACPS_TXBUF_LEN_MASK) | (LenBytes)))
/*****************************************************************************/
/**
* Retrieve the BD length field.
*
* For Tx channels, the returned value is the same as that written with
* XEmacPs_BdSetLength().
*
* For Rx channels, the returned value is the size of the received packet.
*
* @param BdPtr is the BD pointer to operate on
*
* @return Length field processed by hardware or set by
* XEmacPs_BdSetLength().
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdGetLength(XEmacPs_Bd* BdPtr)
* XEAMCPS_RXBUF_LEN_MASK is same as XEMACPS_TXBUF_LEN_MASK.
*
*****************************************************************************/
#define XEmacPs_BdGetLength(BdPtr) \
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_LEN_MASK)
/*****************************************************************************/
/**
* Retrieve the RX frame size.
*
* The returned value is the size of the received packet.
* This API supports jumbo frame sizes if enabled.
*
* @param BdPtr is the BD pointer to operate on
*
* @return Length field processed by hardware or set by
* XEmacPs_BdSetLength().
*
* @note
* C-style signature:
* UINTPTR XEmacPs_GetRxFrameSize(XEmacPs* InstancePtr, XEmacPs_Bd* BdPtr)
* RxBufMask is dependent on whether jumbo is enabled or not.
*
*****************************************************************************/
#define XEmacPs_GetRxFrameSize(InstancePtr, BdPtr) \
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
(InstancePtr)->RxBufMask)
/*****************************************************************************/
/**
* Test whether the given BD has been marked as the last BD of a packet.
*
* @param BdPtr is the BD pointer to operate on
*
* @return TRUE if BD represents the "Last" BD of a packet, FALSE otherwise
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsLast(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsLast(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_EOF_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Tell the DMA engine that the given transmit BD marks the end of the current
* packet to be processed.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* void XEmacPs_BdSetLast(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdSetLast(BdPtr) \
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
XEMACPS_TXBUF_LAST_MASK))
/*****************************************************************************/
/**
* Tell the DMA engine that the current packet does not end with the given
* BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* void XEmacPs_BdClearLast(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdClearLast(BdPtr) \
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
~XEMACPS_TXBUF_LAST_MASK))
/*****************************************************************************/
/**
* Set this bit to mark the last descriptor in the receive buffer descriptor
* list.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* void XEmacPs_BdSetRxWrap(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
/*#define XEmacPs_BdSetRxWrap(BdPtr) \
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) | \
XEMACPS_RXBUF_WRAP_MASK))
*/
/*****************************************************************************/
/**
* Determine the wrap bit of the receive BD which indicates end of the
* BD list.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* u8 XEmacPs_BdIsRxWrap(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxWrap(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
XEMACPS_RXBUF_WRAP_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Sets this bit to mark the last descriptor in the transmit buffer
* descriptor list.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* void XEmacPs_BdSetTxWrap(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
/*#define XEmacPs_BdSetTxWrap(BdPtr) \
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
XEMACPS_TXBUF_WRAP_MASK))
*/
/*****************************************************************************/
/**
* Determine the wrap bit of the transmit BD which indicates end of the
* BD list.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* u8 XEmacPs_BdGetTxWrap(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsTxWrap(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_TXBUF_WRAP_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/*
* Must clear this bit to enable the MAC to write data to the receive
* buffer. Hardware sets this bit once it has successfully written a frame to
* memory. Once set, software has to clear the bit before the buffer can be
* used again. This macro clear the new bit of the receive BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* void XEmacPs_BdClearRxNew(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdClearRxNew(BdPtr) \
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
~XEMACPS_RXBUF_NEW_MASK))
/*****************************************************************************/
/**
* Determine the new bit of the receive BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsRxNew(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxNew(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
XEMACPS_RXBUF_NEW_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Software sets this bit to disable the buffer to be read by the hardware.
* Hardware sets this bit for the first buffer of a frame once it has been
* successfully transmitted. This macro sets this bit of transmit BD to avoid
* confusion.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* void XEmacPs_BdSetTxUsed(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdSetTxUsed(BdPtr) \
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
XEMACPS_TXBUF_USED_MASK))
/*****************************************************************************/
/**
* Software clears this bit to enable the buffer to be read by the hardware.
* Hardware sets this bit for the first buffer of a frame once it has been
* successfully transmitted. This macro clears this bit of transmit BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* void XEmacPs_BdClearTxUsed(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdClearTxUsed(BdPtr) \
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
~XEMACPS_TXBUF_USED_MASK))
/*****************************************************************************/
/**
* Determine the used bit of the transmit BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsTxUsed(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsTxUsed(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_TXBUF_USED_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine if a frame fails to be transmitted due to too many retries.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsTxRetry(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsTxRetry(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_TXBUF_RETRY_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine if a frame fails to be transmitted due to data can not be
* feteched in time or buffers are exhausted.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsTxUrun(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsTxUrun(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_TXBUF_URUN_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine if a frame fails to be transmitted due to buffer is exhausted
* mid-frame.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsTxExh(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsTxExh(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_TXBUF_EXH_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Sets this bit, no CRC will be appended to the current frame. This control
* bit must be set for the first buffer in a frame and will be ignored for
* the subsequent buffers of a frame.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* This bit must be clear when using the transmit checksum generation offload,
* otherwise checksum generation and substitution will not occur.
*
* C-style signature:
* UINTPTR XEmacPs_BdSetTxNoCRC(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdSetTxNoCRC(BdPtr) \
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
XEMACPS_TXBUF_NOCRC_MASK))
/*****************************************************************************/
/**
* Clear this bit, CRC will be appended to the current frame. This control
* bit must be set for the first buffer in a frame and will be ignored for
* the subsequent buffers of a frame.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* This bit must be clear when using the transmit checksum generation offload,
* otherwise checksum generation and substitution will not occur.
*
* C-style signature:
* UINTPTR XEmacPs_BdClearTxNoCRC(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdClearTxNoCRC(BdPtr) \
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
~XEMACPS_TXBUF_NOCRC_MASK))
/*****************************************************************************/
/**
* Determine the broadcast bit of the receive BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsRxBcast(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxBcast(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_BCAST_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine the multicast hash bit of the receive BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsRxMultiHash(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxMultiHash(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_MULTIHASH_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine the unicast hash bit of the receive BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsRxUniHash(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxUniHash(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_UNIHASH_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine if the received frame is a VLAN Tagged frame.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsRxVlan(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxVlan(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_VLAN_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine if the received frame has Type ID of 8100h and null VLAN
* identifier(Priority tag).
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsRxPri(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxPri(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_PRI_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine if the received frame's Concatenation Format Indicator (CFI) of
* the frames VLANTCI field was set.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdIsRxCFI(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxCFI(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_CFI_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine the End Of Frame (EOF) bit of the receive BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdGetRxEOF(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxEOF(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_EOF_MASK)!=0U ? TRUE : FALSE)
/*****************************************************************************/
/**
* Determine the Start Of Frame (SOF) bit of the receive BD.
*
* @param BdPtr is the BD pointer to operate on
*
* @note
* C-style signature:
* UINTPTR XEmacPs_BdGetRxSOF(XEmacPs_Bd* BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdIsRxSOF(BdPtr) \
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
XEMACPS_RXBUF_SOF_MASK)!=0U ? TRUE : FALSE)
/************************** Function Prototypes ******************************/
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,238 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemacps_bdring.h
* @addtogroup emacps_v3_1
* @{
*
* The Xiline EmacPs Buffer Descriptor ring driver. This is part of EmacPs
* DMA functionalities.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wsy 01/10/10 First release
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp architecture.
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
*
* </pre>
*
******************************************************************************/
#ifndef XEMACPS_BDRING_H /* prevent curcular inclusions */
#define XEMACPS_BDRING_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/**************************** Type Definitions *******************************/
/** This is an internal structure used to maintain the DMA list */
typedef struct {
UINTPTR PhysBaseAddr;/**< Physical address of 1st BD in list */
UINTPTR BaseBdAddr; /**< Virtual address of 1st BD in list */
UINTPTR HighBdAddr; /**< Virtual address of last BD in the list */
u32 Length; /**< Total size of ring in bytes */
u32 RunState; /**< Flag to indicate DMA is started */
u32 Separation; /**< Number of bytes between the starting address
of adjacent BDs */
XEmacPs_Bd *FreeHead;
/**< First BD in the free group */
XEmacPs_Bd *PreHead;/**< First BD in the pre-work group */
XEmacPs_Bd *HwHead; /**< First BD in the work group */
XEmacPs_Bd *HwTail; /**< Last BD in the work group */
XEmacPs_Bd *PostHead;
/**< First BD in the post-work group */
XEmacPs_Bd *BdaRestart;
/**< BDA to load when channel is started */
u32 HwCnt; /**< Number of BDs in work group */
u32 PreCnt; /**< Number of BDs in pre-work group */
u32 FreeCnt; /**< Number of allocatable BDs in the free group */
u32 PostCnt; /**< Number of BDs in post-work group */
u32 AllCnt; /**< Total Number of BDs for channel */
} XEmacPs_BdRing;
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
* Use this macro at initialization time to determine how many BDs will fit
* in a BD list within the given memory constraints.
*
* The results of this macro can be provided to XEmacPs_BdRingCreate().
*
* @param Alignment specifies what byte alignment the BDs must fall on and
* must be a power of 2 to get an accurate calculation (32, 64, 128,...)
* @param Bytes is the number of bytes to be used to store BDs.
*
* @return Number of BDs that can fit in the given memory area
*
* @note
* C-style signature:
* u32 XEmacPs_BdRingCntCalc(u32 Alignment, u32 Bytes)
*
******************************************************************************/
#define XEmacPs_BdRingCntCalc(Alignment, Bytes) \
(u32)((Bytes) / (sizeof(XEmacPs_Bd)))
/*****************************************************************************/
/**
* Use this macro at initialization time to determine how many bytes of memory
* is required to contain a given number of BDs at a given alignment.
*
* @param Alignment specifies what byte alignment the BDs must fall on. This
* parameter must be a power of 2 to get an accurate calculation (32, 64,
* 128,...)
* @param NumBd is the number of BDs to calculate memory size requirements for
*
* @return The number of bytes of memory required to create a BD list with the
* given memory constraints.
*
* @note
* C-style signature:
* u32 XEmacPs_BdRingMemCalc(u32 Alignment, u32 NumBd)
*
******************************************************************************/
#define XEmacPs_BdRingMemCalc(Alignment, NumBd) \
(u32)(sizeof(XEmacPs_Bd) * (NumBd))
/****************************************************************************/
/**
* Return the total number of BDs allocated by this channel with
* XEmacPs_BdRingCreate().
*
* @param RingPtr is the DMA channel to operate on.
*
* @return The total number of BDs allocated for this channel.
*
* @note
* C-style signature:
* u32 XEmacPs_BdRingGetCnt(XEmacPs_BdRing* RingPtr)
*
*****************************************************************************/
#define XEmacPs_BdRingGetCnt(RingPtr) ((RingPtr)->AllCnt)
/****************************************************************************/
/**
* Return the number of BDs allocatable with XEmacPs_BdRingAlloc() for pre-
* processing.
*
* @param RingPtr is the DMA channel to operate on.
*
* @return The number of BDs currently allocatable.
*
* @note
* C-style signature:
* u32 XEmacPs_BdRingGetFreeCnt(XEmacPs_BdRing* RingPtr)
*
*****************************************************************************/
#define XEmacPs_BdRingGetFreeCnt(RingPtr) ((RingPtr)->FreeCnt)
/****************************************************************************/
/**
* Return the next BD from BdPtr in a list.
*
* @param RingPtr is the DMA channel to operate on.
* @param BdPtr is the BD to operate on.
*
* @return The next BD in the list relative to the BdPtr parameter.
*
* @note
* C-style signature:
* XEmacPs_Bd *XEmacPs_BdRingNext(XEmacPs_BdRing* RingPtr,
* XEmacPs_Bd *BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdRingNext(RingPtr, BdPtr) \
(((UINTPTR)((void *)(BdPtr)) >= (RingPtr)->HighBdAddr) ? \
(XEmacPs_Bd*)((void*)(RingPtr)->BaseBdAddr) : \
(XEmacPs_Bd*)((UINTPTR)((void *)(BdPtr)) + (RingPtr)->Separation))
/****************************************************************************/
/**
* Return the previous BD from BdPtr in the list.
*
* @param RingPtr is the DMA channel to operate on.
* @param BdPtr is the BD to operate on
*
* @return The previous BD in the list relative to the BdPtr parameter.
*
* @note
* C-style signature:
* XEmacPs_Bd *XEmacPs_BdRingPrev(XEmacPs_BdRing* RingPtr,
* XEmacPs_Bd *BdPtr)
*
*****************************************************************************/
#define XEmacPs_BdRingPrev(RingPtr, BdPtr) \
(((UINTPTR)(BdPtr) <= (RingPtr)->BaseBdAddr) ? \
(XEmacPs_Bd*)(RingPtr)->HighBdAddr : \
(XEmacPs_Bd*)((UINTPTR)(BdPtr) - (RingPtr)->Separation))
/************************** Function Prototypes ******************************/
/*
* Scatter gather DMA related functions in xemacps_bdring.c
*/
LONG XEmacPs_BdRingCreate(XEmacPs_BdRing * RingPtr, UINTPTR PhysAddr,
UINTPTR VirtAddr, u32 Alignment, u32 BdCount);
LONG XEmacPs_BdRingClone(XEmacPs_BdRing * RingPtr, XEmacPs_Bd * SrcBdPtr,
u8 Direction);
LONG XEmacPs_BdRingAlloc(XEmacPs_BdRing * RingPtr, u32 NumBd,
XEmacPs_Bd ** BdSetPtr);
LONG XEmacPs_BdRingUnAlloc(XEmacPs_BdRing * RingPtr, u32 NumBd,
XEmacPs_Bd * BdSetPtr);
LONG XEmacPs_BdRingToHw(XEmacPs_BdRing * RingPtr, u32 NumBd,
XEmacPs_Bd * BdSetPtr);
LONG XEmacPs_BdRingFree(XEmacPs_BdRing * RingPtr, u32 NumBd,
XEmacPs_Bd * BdSetPtr);
u32 XEmacPs_BdRingFromHwTx(XEmacPs_BdRing * RingPtr, u32 BdLimit,
XEmacPs_Bd ** BdSetPtr);
u32 XEmacPs_BdRingFromHwRx(XEmacPs_BdRing * RingPtr, u32 BdLimit,
XEmacPs_Bd ** BdSetPtr);
LONG XEmacPs_BdRingCheck(XEmacPs_BdRing * RingPtr, u8 Direction);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macros */
/** @} */

View file

@ -0,0 +1,55 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the Software), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in
*all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
*(a) running on a Xilinx device, or
*(b) that interact with a Xilinx device through a bus or interconnect.
*
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the Xilinx shall not be used
*in advertising or otherwise to promote the sale, use or other dealings in
*this Software without prior written authorization from Xilinx.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xemacps.h"
/*
* The configuration table for devices
*/
XEmacPs_Config XEmacPs_ConfigTable[] =
{
{
XPAR_PSU_ETHERNET_3_DEVICE_ID,
XPAR_PSU_ETHERNET_3_BASEADDR
}
};

View file

@ -0,0 +1,123 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemacps_hw.c
* @addtogroup emacps_v3_1
* @{
*
* This file contains the implementation of the ethernet interface reset sequence
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.05a kpc 28/06/13 First release
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xemacps_hw.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/**
* This function perform the reset sequence to the given emacps interface by
* configuring the appropriate control bits in the emacps specifc registers.
* the emacps reset squence involves the following steps
* Disable all the interuupts
* Clear the status registers
* Disable Rx and Tx engines
* Update the Tx and Rx descriptor queue registers with reset values
* Update the other relevant control registers with reset value
*
* @param BaseAddress of the interface
*
* @return N/A
*
* @note
* This function will not modify the slcr registers that are relavant for
* emacps controller
******************************************************************************/
void XEmacPs_ResetHw(u32 BaseAddr)
{
u32 RegVal;
/* Disable the interrupts */
XEmacPs_WriteReg(BaseAddr,XEMACPS_IDR_OFFSET,0x0U);
/* Stop transmission,disable loopback and Stop tx and Rx engines */
RegVal = XEmacPs_ReadReg(BaseAddr,XEMACPS_NWCTRL_OFFSET);
RegVal &= ~((u32)XEMACPS_NWCTRL_TXEN_MASK|
(u32)XEMACPS_NWCTRL_RXEN_MASK|
(u32)XEMACPS_NWCTRL_HALTTX_MASK|
(u32)XEMACPS_NWCTRL_LOOPEN_MASK);
/* Clear the statistic registers, flush the packets in DPRAM*/
RegVal |= (XEMACPS_NWCTRL_STATCLR_MASK|
XEMACPS_NWCTRL_FLUSH_DPRAM_MASK);
XEmacPs_WriteReg(BaseAddr,XEMACPS_NWCTRL_OFFSET,RegVal);
/* Clear the interrupt status */
XEmacPs_WriteReg(BaseAddr,XEMACPS_ISR_OFFSET,XEMACPS_IXR_ALL_MASK);
/* Clear the tx status */
XEmacPs_WriteReg(BaseAddr,XEMACPS_TXSR_OFFSET,(XEMACPS_TXSR_ERROR_MASK|
(u32)XEMACPS_TXSR_TXCOMPL_MASK|
(u32)XEMACPS_TXSR_TXGO_MASK));
/* Clear the rx status */
XEmacPs_WriteReg(BaseAddr,XEMACPS_RXSR_OFFSET,
XEMACPS_RXSR_FRAMERX_MASK);
/* Clear the tx base address */
XEmacPs_WriteReg(BaseAddr,XEMACPS_TXQBASE_OFFSET,0x0U);
/* Clear the rx base address */
XEmacPs_WriteReg(BaseAddr,XEMACPS_RXQBASE_OFFSET,0x0U);
/* Update the network config register with reset value */
XEmacPs_WriteReg(BaseAddr,XEMACPS_NWCFG_OFFSET,XEMACPS_NWCFG_RESET_MASK);
/* Update the hash address registers with reset value */
XEmacPs_WriteReg(BaseAddr,XEMACPS_HASHL_OFFSET,0x0U);
XEmacPs_WriteReg(BaseAddr,XEMACPS_HASHH_OFFSET,0x0U);
}
/** @} */

View file

@ -0,0 +1,656 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2016 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemacps_hw.h
* @addtogroup emacps_v3_1
* @{
*
* This header file contains identifiers and low-level driver functions (or
* macros) that can be used to access the PS Ethernet MAC (XEmacPs) device.
* High-level driver functions are defined in xemacps.h.
*
* @note
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wsy 01/10/10 First release.
* 1.02a asa 11/05/12 Added hash defines for DMACR burst length configuration.
* 1.05a kpc 28/06/13 Added XEmacPs_ResetHw function prototype
* 1.06a asa 11/02/13 Changed the value for XEMACPS_RXBUF_LEN_MASK from 0x3fff
* to 0x1fff. This fixes the CR#744902.
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp GEM specification.
* 3.0 kvn 12/16/14 Changed name of XEMACPS_NWCFG_LENGTHERRDSCRD_MASK to
* XEMACPS_NWCFG_LENERRDSCRD_MASK as it exceeds 31 characters.
* 3.0 kpc 1/23/15 Corrected the extended descriptor macro values.
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.0 hk 03/18/15 Added support for jumbo frames.
* Remove "used bit set" from TX error interrupt masks.
* 3.1 hk 08/10/15 Update upper 32 bit tx and rx queue ptr register offsets.
* 3.2 hk 02/22/16 Added SGMII support for Zynq Ultrascale+ MPSoC.
* </pre>
*
******************************************************************************/
#ifndef XEMACPS_HW_H /* prevent circular inclusions */
#define XEMACPS_HW_H /* by using protection macros */
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
#ifdef __cplusplus
extern "C" {
#endif
/************************** Constant Definitions *****************************/
#define XEMACPS_MAX_MAC_ADDR 4U /**< Maxmum number of mac address
supported */
#define XEMACPS_MAX_TYPE_ID 4U /**< Maxmum number of type id supported */
#ifdef __aarch64__
#define XEMACPS_BD_ALIGNMENT 64U /**< Minimum buffer descriptor alignment
on the local bus */
#else
#define XEMACPS_BD_ALIGNMENT 4U /**< Minimum buffer descriptor alignment
on the local bus */
#endif
#define XEMACPS_RX_BUF_ALIGNMENT 4U /**< Minimum buffer alignment when using
options that impose alignment
restrictions on the buffer data on
the local bus */
/** @name Direction identifiers
*
* These are used by several functions and callbacks that need
* to specify whether an operation specifies a send or receive channel.
* @{
*/
#define XEMACPS_SEND 1U /**< send direction */
#define XEMACPS_RECV 2U /**< receive direction */
/*@}*/
/** @name MDC clock division
* currently supporting 8, 16, 32, 48, 64, 96, 128, 224.
* @{
*/
typedef enum { MDC_DIV_8 = 0U, MDC_DIV_16, MDC_DIV_32, MDC_DIV_48,
MDC_DIV_64, MDC_DIV_96, MDC_DIV_128, MDC_DIV_224
} XEmacPs_MdcDiv;
/*@}*/
#define XEMACPS_RX_BUF_SIZE 1536U /**< Specify the receive buffer size in
bytes, 64, 128, ... 10240 */
#define XEMACPS_RX_BUF_SIZE_JUMBO 10240U
#define XEMACPS_RX_BUF_UNIT 64U /**< Number of receive buffer bytes as a
unit, this is HW setup */
#define XEMACPS_MAX_RXBD 128U /**< Size of RX buffer descriptor queues */
#define XEMACPS_MAX_TXBD 128U /**< Size of TX buffer descriptor queues */
#define XEMACPS_MAX_HASH_BITS 64U /**< Maximum value for hash bits. 2**6 */
/* Register offset definitions. Unless otherwise noted, register access is
* 32 bit. Names are self explained here.
*/
#define XEMACPS_NWCTRL_OFFSET 0x00000000U /**< Network Control reg */
#define XEMACPS_NWCFG_OFFSET 0x00000004U /**< Network Config reg */
#define XEMACPS_NWSR_OFFSET 0x00000008U /**< Network Status reg */
#define XEMACPS_DMACR_OFFSET 0x00000010U /**< DMA Control reg */
#define XEMACPS_TXSR_OFFSET 0x00000014U /**< TX Status reg */
#define XEMACPS_RXQBASE_OFFSET 0x00000018U /**< RX Q Base address reg */
#define XEMACPS_TXQBASE_OFFSET 0x0000001CU /**< TX Q Base address reg */
#define XEMACPS_RXSR_OFFSET 0x00000020U /**< RX Status reg */
#define XEMACPS_ISR_OFFSET 0x00000024U /**< Interrupt Status reg */
#define XEMACPS_IER_OFFSET 0x00000028U /**< Interrupt Enable reg */
#define XEMACPS_IDR_OFFSET 0x0000002CU /**< Interrupt Disable reg */
#define XEMACPS_IMR_OFFSET 0x00000030U /**< Interrupt Mask reg */
#define XEMACPS_PHYMNTNC_OFFSET 0x00000034U /**< Phy Maintaince reg */
#define XEMACPS_RXPAUSE_OFFSET 0x00000038U /**< RX Pause Time reg */
#define XEMACPS_TXPAUSE_OFFSET 0x0000003CU /**< TX Pause Time reg */
#define XEMACPS_JUMBOMAXLEN_OFFSET 0x00000048U /**< Jumbo max length reg */
#define XEMACPS_HASHL_OFFSET 0x00000080U /**< Hash Low address reg */
#define XEMACPS_HASHH_OFFSET 0x00000084U /**< Hash High address reg */
#define XEMACPS_LADDR1L_OFFSET 0x00000088U /**< Specific1 addr low reg */
#define XEMACPS_LADDR1H_OFFSET 0x0000008CU /**< Specific1 addr high reg */
#define XEMACPS_LADDR2L_OFFSET 0x00000090U /**< Specific2 addr low reg */
#define XEMACPS_LADDR2H_OFFSET 0x00000094U /**< Specific2 addr high reg */
#define XEMACPS_LADDR3L_OFFSET 0x00000098U /**< Specific3 addr low reg */
#define XEMACPS_LADDR3H_OFFSET 0x0000009CU /**< Specific3 addr high reg */
#define XEMACPS_LADDR4L_OFFSET 0x000000A0U /**< Specific4 addr low reg */
#define XEMACPS_LADDR4H_OFFSET 0x000000A4U /**< Specific4 addr high reg */
#define XEMACPS_MATCH1_OFFSET 0x000000A8U /**< Type ID1 Match reg */
#define XEMACPS_MATCH2_OFFSET 0x000000ACU /**< Type ID2 Match reg */
#define XEMACPS_MATCH3_OFFSET 0x000000B0U /**< Type ID3 Match reg */
#define XEMACPS_MATCH4_OFFSET 0x000000B4U /**< Type ID4 Match reg */
#define XEMACPS_STRETCH_OFFSET 0x000000BCU /**< IPG Stretch reg */
#define XEMACPS_OCTTXL_OFFSET 0x00000100U /**< Octects transmitted Low
reg */
#define XEMACPS_OCTTXH_OFFSET 0x00000104U /**< Octects transmitted High
reg */
#define XEMACPS_TXCNT_OFFSET 0x00000108U /**< Error-free Frmaes
transmitted counter */
#define XEMACPS_TXBCCNT_OFFSET 0x0000010CU /**< Error-free Broadcast
Frames counter*/
#define XEMACPS_TXMCCNT_OFFSET 0x00000110U /**< Error-free Multicast
Frame counter */
#define XEMACPS_TXPAUSECNT_OFFSET 0x00000114U /**< Pause Frames Transmitted
Counter */
#define XEMACPS_TX64CNT_OFFSET 0x00000118U /**< Error-free 64 byte Frames
Transmitted counter */
#define XEMACPS_TX65CNT_OFFSET 0x0000011CU /**< Error-free 65-127 byte
Frames Transmitted
counter */
#define XEMACPS_TX128CNT_OFFSET 0x00000120U /**< Error-free 128-255 byte
Frames Transmitted
counter*/
#define XEMACPS_TX256CNT_OFFSET 0x00000124U /**< Error-free 256-511 byte
Frames transmitted
counter */
#define XEMACPS_TX512CNT_OFFSET 0x00000128U /**< Error-free 512-1023 byte
Frames transmitted
counter */
#define XEMACPS_TX1024CNT_OFFSET 0x0000012CU /**< Error-free 1024-1518 byte
Frames transmitted
counter */
#define XEMACPS_TX1519CNT_OFFSET 0x00000130U /**< Error-free larger than
1519 byte Frames
transmitted counter */
#define XEMACPS_TXURUNCNT_OFFSET 0x00000134U /**< TX under run error
counter */
#define XEMACPS_SNGLCOLLCNT_OFFSET 0x00000138U /**< Single Collision Frame
Counter */
#define XEMACPS_MULTICOLLCNT_OFFSET 0x0000013CU /**< Multiple Collision Frame
Counter */
#define XEMACPS_EXCESSCOLLCNT_OFFSET 0x00000140U /**< Excessive Collision Frame
Counter */
#define XEMACPS_LATECOLLCNT_OFFSET 0x00000144U /**< Late Collision Frame
Counter */
#define XEMACPS_TXDEFERCNT_OFFSET 0x00000148U /**< Deferred Transmission
Frame Counter */
#define XEMACPS_TXCSENSECNT_OFFSET 0x0000014CU /**< Transmit Carrier Sense
Error Counter */
#define XEMACPS_OCTRXL_OFFSET 0x00000150U /**< Octects Received register
Low */
#define XEMACPS_OCTRXH_OFFSET 0x00000154U /**< Octects Received register
High */
#define XEMACPS_RXCNT_OFFSET 0x00000158U /**< Error-free Frames
Received Counter */
#define XEMACPS_RXBROADCNT_OFFSET 0x0000015CU /**< Error-free Broadcast
Frames Received Counter */
#define XEMACPS_RXMULTICNT_OFFSET 0x00000160U /**< Error-free Multicast
Frames Received Counter */
#define XEMACPS_RXPAUSECNT_OFFSET 0x00000164U /**< Pause Frames
Received Counter */
#define XEMACPS_RX64CNT_OFFSET 0x00000168U /**< Error-free 64 byte Frames
Received Counter */
#define XEMACPS_RX65CNT_OFFSET 0x0000016CU /**< Error-free 65-127 byte
Frames Received Counter */
#define XEMACPS_RX128CNT_OFFSET 0x00000170U /**< Error-free 128-255 byte
Frames Received Counter */
#define XEMACPS_RX256CNT_OFFSET 0x00000174U /**< Error-free 256-512 byte
Frames Received Counter */
#define XEMACPS_RX512CNT_OFFSET 0x00000178U /**< Error-free 512-1023 byte
Frames Received Counter */
#define XEMACPS_RX1024CNT_OFFSET 0x0000017CU /**< Error-free 1024-1518 byte
Frames Received Counter */
#define XEMACPS_RX1519CNT_OFFSET 0x00000180U /**< Error-free 1519-max byte
Frames Received Counter */
#define XEMACPS_RXUNDRCNT_OFFSET 0x00000184U /**< Undersize Frames Received
Counter */
#define XEMACPS_RXOVRCNT_OFFSET 0x00000188U /**< Oversize Frames Received
Counter */
#define XEMACPS_RXJABCNT_OFFSET 0x0000018CU /**< Jabbers Received
Counter */
#define XEMACPS_RXFCSCNT_OFFSET 0x00000190U /**< Frame Check Sequence
Error Counter */
#define XEMACPS_RXLENGTHCNT_OFFSET 0x00000194U /**< Length Field Error
Counter */
#define XEMACPS_RXSYMBCNT_OFFSET 0x00000198U /**< Symbol Error Counter */
#define XEMACPS_RXALIGNCNT_OFFSET 0x0000019CU /**< Alignment Error Counter */
#define XEMACPS_RXRESERRCNT_OFFSET 0x000001A0U /**< Receive Resource Error
Counter */
#define XEMACPS_RXORCNT_OFFSET 0x000001A4U /**< Receive Overrun Counter */
#define XEMACPS_RXIPCCNT_OFFSET 0x000001A8U /**< IP header Checksum Error
Counter */
#define XEMACPS_RXTCPCCNT_OFFSET 0x000001ACU /**< TCP Checksum Error
Counter */
#define XEMACPS_RXUDPCCNT_OFFSET 0x000001B0U /**< UDP Checksum Error
Counter */
#define XEMACPS_LAST_OFFSET 0x000001B4U /**< Last statistic counter
offset, for clearing */
#define XEMACPS_1588_SEC_OFFSET 0x000001D0U /**< 1588 second counter */
#define XEMACPS_1588_NANOSEC_OFFSET 0x000001D4U /**< 1588 nanosecond counter */
#define XEMACPS_1588_ADJ_OFFSET 0x000001D8U /**< 1588 nanosecond
adjustment counter */
#define XEMACPS_1588_INC_OFFSET 0x000001DCU /**< 1588 nanosecond
increment counter */
#define XEMACPS_PTP_TXSEC_OFFSET 0x000001E0U /**< 1588 PTP transmit second
counter */
#define XEMACPS_PTP_TXNANOSEC_OFFSET 0x000001E4U /**< 1588 PTP transmit
nanosecond counter */
#define XEMACPS_PTP_RXSEC_OFFSET 0x000001E8U /**< 1588 PTP receive second
counter */
#define XEMACPS_PTP_RXNANOSEC_OFFSET 0x000001ECU /**< 1588 PTP receive
nanosecond counter */
#define XEMACPS_PTPP_TXSEC_OFFSET 0x000001F0U /**< 1588 PTP peer transmit
second counter */
#define XEMACPS_PTPP_TXNANOSEC_OFFSET 0x000001F4U /**< 1588 PTP peer transmit
nanosecond counter */
#define XEMACPS_PTPP_RXSEC_OFFSET 0x000001F8U /**< 1588 PTP peer receive
second counter */
#define XEMACPS_PTPP_RXNANOSEC_OFFSET 0x000001FCU /**< 1588 PTP peer receive
nanosecond counter */
#define XEMACPS_INTQ1_STS_OFFSET 0x00000400U /**< Interrupt Q1 Status
reg */
#define XEMACPS_TXQ1BASE_OFFSET 0x00000440U /**< TX Q1 Base address
reg */
#define XEMACPS_RXQ1BASE_OFFSET 0x00000480U /**< RX Q1 Base address
reg */
#define XEMACPS_MSBBUF_TXQBASE_OFFSET 0x000004C8U /**< MSB Buffer TX Q Base
reg */
#define XEMACPS_MSBBUF_RXQBASE_OFFSET 0x000004D4U /**< MSB Buffer RX Q Base
reg */
#define XEMACPS_INTQ1_IER_OFFSET 0x00000600U /**< Interrupt Q1 Enable
reg */
#define XEMACPS_INTQ1_IDR_OFFSET 0x00000620U /**< Interrupt Q1 Disable
reg */
#define XEMACPS_INTQ1_IMR_OFFSET 0x00000640U /**< Interrupt Q1 Mask
reg */
/* Define some bit positions for registers. */
/** @name network control register bit definitions
* @{
*/
#define XEMACPS_NWCTRL_FLUSH_DPRAM_MASK 0x00040000U /**< Flush a packet from
Rx SRAM */
#define XEMACPS_NWCTRL_ZEROPAUSETX_MASK 0x00000800U /**< Transmit zero quantum
pause frame */
#define XEMACPS_NWCTRL_PAUSETX_MASK 0x00000800U /**< Transmit pause frame */
#define XEMACPS_NWCTRL_HALTTX_MASK 0x00000400U /**< Halt transmission
after current frame */
#define XEMACPS_NWCTRL_STARTTX_MASK 0x00000200U /**< Start tx (tx_go) */
#define XEMACPS_NWCTRL_STATWEN_MASK 0x00000080U /**< Enable writing to
stat counters */
#define XEMACPS_NWCTRL_STATINC_MASK 0x00000040U /**< Increment statistic
registers */
#define XEMACPS_NWCTRL_STATCLR_MASK 0x00000020U /**< Clear statistic
registers */
#define XEMACPS_NWCTRL_MDEN_MASK 0x00000010U /**< Enable MDIO port */
#define XEMACPS_NWCTRL_TXEN_MASK 0x00000008U /**< Enable transmit */
#define XEMACPS_NWCTRL_RXEN_MASK 0x00000004U /**< Enable receive */
#define XEMACPS_NWCTRL_LOOPEN_MASK 0x00000002U /**< local loopback */
/*@}*/
/** @name network configuration register bit definitions
* @{
*/
#define XEMACPS_NWCFG_BADPREAMBEN_MASK 0x20000000U /**< disable rejection of
non-standard preamble */
#define XEMACPS_NWCFG_IPDSTRETCH_MASK 0x10000000U /**< enable transmit IPG */
#define XEMACPS_NWCFG_SGMIIEN_MASK 0x08000000U /**< SGMII Enable */
#define XEMACPS_NWCFG_FCSIGNORE_MASK 0x04000000U /**< disable rejection of
FCS error */
#define XEMACPS_NWCFG_HDRXEN_MASK 0x02000000U /**< RX half duplex */
#define XEMACPS_NWCFG_RXCHKSUMEN_MASK 0x01000000U /**< enable RX checksum
offload */
#define XEMACPS_NWCFG_PAUSECOPYDI_MASK 0x00800000U /**< Do not copy pause
Frames to memory */
#define XEMACPS_NWCFG_DWIDTH_64_MASK 0x00200000U /**< 64 bit Data bus width */
#define XEMACPS_NWCFG_MDC_SHIFT_MASK 18U /**< shift bits for MDC */
#define XEMACPS_NWCFG_MDCCLKDIV_MASK 0x001C0000U /**< MDC Mask PCLK divisor */
#define XEMACPS_NWCFG_FCSREM_MASK 0x00020000U /**< Discard FCS from
received frames */
#define XEMACPS_NWCFG_LENERRDSCRD_MASK 0x00010000U
/**< RX length error discard */
#define XEMACPS_NWCFG_RXOFFS_MASK 0x0000C000U /**< RX buffer offset */
#define XEMACPS_NWCFG_PAUSEEN_MASK 0x00002000U /**< Enable pause RX */
#define XEMACPS_NWCFG_RETRYTESTEN_MASK 0x00001000U /**< Retry test */
#define XEMACPS_NWCFG_XTADDMACHEN_MASK 0x00000200U
/**< External address match enable */
#define XEMACPS_NWCFG_PCSSEL_MASK 0x00000800U /**< PCS Select */
#define XEMACPS_NWCFG_1000_MASK 0x00000400U /**< 1000 Mbps */
#define XEMACPS_NWCFG_1536RXEN_MASK 0x00000100U /**< Enable 1536 byte
frames reception */
#define XEMACPS_NWCFG_UCASTHASHEN_MASK 0x00000080U /**< Receive unicast hash
frames */
#define XEMACPS_NWCFG_MCASTHASHEN_MASK 0x00000040U /**< Receive multicast hash
frames */
#define XEMACPS_NWCFG_BCASTDI_MASK 0x00000020U /**< Do not receive
broadcast frames */
#define XEMACPS_NWCFG_COPYALLEN_MASK 0x00000010U /**< Copy all frames */
#define XEMACPS_NWCFG_JUMBO_MASK 0x00000008U /**< Jumbo frames */
#define XEMACPS_NWCFG_NVLANDISC_MASK 0x00000004U /**< Receive only VLAN
frames */
#define XEMACPS_NWCFG_FDEN_MASK 0x00000002U/**< full duplex */
#define XEMACPS_NWCFG_100_MASK 0x00000001U /**< 100 Mbps */
#define XEMACPS_NWCFG_RESET_MASK 0x00080000U/**< reset value */
/*@}*/
/** @name network status register bit definitaions
* @{
*/
#define XEMACPS_NWSR_MDIOIDLE_MASK 0x00000004U /**< PHY management idle */
#define XEMACPS_NWSR_MDIO_MASK 0x00000002U /**< Status of mdio_in */
/*@}*/
/** @name MAC address register word 1 mask
* @{
*/
#define XEMACPS_LADDR_MACH_MASK 0x0000FFFFU /**< Address bits[47:32]
bit[31:0] are in BOTTOM */
/*@}*/
/** @name DMA control register bit definitions
* @{
*/
#define XEMACPS_DMACR_ADDR_WIDTH_64 0x40000000U /**< 64 bit address bus */
#define XEMACPS_DMACR_TXEXTEND_MASK 0x20000000U /**< Tx Extended desc mode */
#define XEMACPS_DMACR_RXEXTEND_MASK 0x10000000U /**< Rx Extended desc mode */
#define XEMACPS_DMACR_RXBUF_MASK 0x00FF0000U /**< Mask bit for RX buffer
size */
#define XEMACPS_DMACR_RXBUF_SHIFT 16U /**< Shift bit for RX buffer
size */
#define XEMACPS_DMACR_TCPCKSUM_MASK 0x00000800U /**< enable/disable TX
checksum offload */
#define XEMACPS_DMACR_TXSIZE_MASK 0x00000400U /**< TX buffer memory size */
#define XEMACPS_DMACR_RXSIZE_MASK 0x00000300U /**< RX buffer memory size */
#define XEMACPS_DMACR_ENDIAN_MASK 0x00000080U /**< endian configuration */
#define XEMACPS_DMACR_BLENGTH_MASK 0x0000001FU /**< buffer burst length */
#define XEMACPS_DMACR_SINGLE_AHB_BURST 0x00000001U /**< single AHB bursts */
#define XEMACPS_DMACR_INCR4_AHB_BURST 0x00000004U /**< 4 bytes AHB bursts */
#define XEMACPS_DMACR_INCR8_AHB_BURST 0x00000008U /**< 8 bytes AHB bursts */
#define XEMACPS_DMACR_INCR16_AHB_BURST 0x00000010U /**< 16 bytes AHB bursts */
/*@}*/
/** @name transmit status register bit definitions
* @{
*/
#define XEMACPS_TXSR_HRESPNOK_MASK 0x00000100U /**< Transmit hresp not OK */
#define XEMACPS_TXSR_URUN_MASK 0x00000040U /**< Transmit underrun */
#define XEMACPS_TXSR_TXCOMPL_MASK 0x00000020U /**< Transmit completed OK */
#define XEMACPS_TXSR_BUFEXH_MASK 0x00000010U /**< Transmit buffs exhausted
mid frame */
#define XEMACPS_TXSR_TXGO_MASK 0x00000008U /**< Status of go flag */
#define XEMACPS_TXSR_RXOVR_MASK 0x00000004U /**< Retry limit exceeded */
#define XEMACPS_TXSR_FRAMERX_MASK 0x00000002U /**< Collision tx frame */
#define XEMACPS_TXSR_USEDREAD_MASK 0x00000001U /**< TX buffer used bit set */
#define XEMACPS_TXSR_ERROR_MASK ((u32)XEMACPS_TXSR_HRESPNOK_MASK | \
(u32)XEMACPS_TXSR_URUN_MASK | \
(u32)XEMACPS_TXSR_BUFEXH_MASK | \
(u32)XEMACPS_TXSR_RXOVR_MASK | \
(u32)XEMACPS_TXSR_FRAMERX_MASK | \
(u32)XEMACPS_TXSR_USEDREAD_MASK)
/*@}*/
/**
* @name receive status register bit definitions
* @{
*/
#define XEMACPS_RXSR_HRESPNOK_MASK 0x00000008U /**< Receive hresp not OK */
#define XEMACPS_RXSR_RXOVR_MASK 0x00000004U /**< Receive overrun */
#define XEMACPS_RXSR_FRAMERX_MASK 0x00000002U /**< Frame received OK */
#define XEMACPS_RXSR_BUFFNA_MASK 0x00000001U /**< RX buffer used bit set */
#define XEMACPS_RXSR_ERROR_MASK ((u32)XEMACPS_RXSR_HRESPNOK_MASK | \
(u32)XEMACPS_RXSR_RXOVR_MASK | \
(u32)XEMACPS_RXSR_BUFFNA_MASK)
/*@}*/
/**
* @name Interrupt Q1 status register bit definitions
* @{
*/
#define XEMACPS_INTQ1SR_TXCOMPL_MASK 0x00000080U /**< Transmit completed OK */
#define XEMACPS_INTQ1SR_TXERR_MASK 0x00000040U /**< Transmit AMBA Error */
#define XEMACPS_INTQ1_IXR_ALL_MASK ((u32)XEMACPS_INTQ1SR_TXCOMPL_MASK | \
(u32)XEMACPS_INTQ1SR_TXERR_MASK)
/*@}*/
/**
* @name interrupts bit definitions
* Bits definitions are same in XEMACPS_ISR_OFFSET,
* XEMACPS_IER_OFFSET, XEMACPS_IDR_OFFSET, and XEMACPS_IMR_OFFSET
* @{
*/
#define XEMACPS_IXR_PTPPSTX_MASK 0x02000000U /**< PTP Psync transmitted */
#define XEMACPS_IXR_PTPPDRTX_MASK 0x01000000U /**< PTP Pdelay_req
transmitted */
#define XEMACPS_IXR_PTPSTX_MASK 0x00800000U /**< PTP Sync transmitted */
#define XEMACPS_IXR_PTPDRTX_MASK 0x00400000U /**< PTP Delay_req transmitted
*/
#define XEMACPS_IXR_PTPPSRX_MASK 0x00200000U /**< PTP Psync received */
#define XEMACPS_IXR_PTPPDRRX_MASK 0x00100000U /**< PTP Pdelay_req received */
#define XEMACPS_IXR_PTPSRX_MASK 0x00080000U /**< PTP Sync received */
#define XEMACPS_IXR_PTPDRRX_MASK 0x00040000U /**< PTP Delay_req received */
#define XEMACPS_IXR_PAUSETX_MASK 0x00004000U /**< Pause frame transmitted */
#define XEMACPS_IXR_PAUSEZERO_MASK 0x00002000U /**< Pause time has reached
zero */
#define XEMACPS_IXR_PAUSENZERO_MASK 0x00001000U /**< Pause frame received */
#define XEMACPS_IXR_HRESPNOK_MASK 0x00000800U /**< hresp not ok */
#define XEMACPS_IXR_RXOVR_MASK 0x00000400U /**< Receive overrun occurred */
#define XEMACPS_IXR_TXCOMPL_MASK 0x00000080U /**< Frame transmitted ok */
#define XEMACPS_IXR_TXEXH_MASK 0x00000040U /**< Transmit err occurred or
no buffers*/
#define XEMACPS_IXR_RETRY_MASK 0x00000020U /**< Retry limit exceeded */
#define XEMACPS_IXR_URUN_MASK 0x00000010U /**< Transmit underrun */
#define XEMACPS_IXR_TXUSED_MASK 0x00000008U /**< Tx buffer used bit read */
#define XEMACPS_IXR_RXUSED_MASK 0x00000004U /**< Rx buffer used bit read */
#define XEMACPS_IXR_FRAMERX_MASK 0x00000002U /**< Frame received ok */
#define XEMACPS_IXR_MGMNT_MASK 0x00000001U /**< PHY management complete */
#define XEMACPS_IXR_ALL_MASK 0x00007FFFU /**< Everything! */
#define XEMACPS_IXR_TX_ERR_MASK ((u32)XEMACPS_IXR_TXEXH_MASK | \
(u32)XEMACPS_IXR_RETRY_MASK | \
(u32)XEMACPS_IXR_URUN_MASK)
#define XEMACPS_IXR_RX_ERR_MASK ((u32)XEMACPS_IXR_HRESPNOK_MASK | \
(u32)XEMACPS_IXR_RXUSED_MASK | \
(u32)XEMACPS_IXR_RXOVR_MASK)
/*@}*/
/** @name PHY Maintenance bit definitions
* @{
*/
#define XEMACPS_PHYMNTNC_OP_MASK 0x40020000U /**< operation mask bits */
#define XEMACPS_PHYMNTNC_OP_R_MASK 0x20000000U /**< read operation */
#define XEMACPS_PHYMNTNC_OP_W_MASK 0x10000000U /**< write operation */
#define XEMACPS_PHYMNTNC_ADDR_MASK 0x0F800000U /**< Address bits */
#define XEMACPS_PHYMNTNC_REG_MASK 0x007C0000U /**< register bits */
#define XEMACPS_PHYMNTNC_DATA_MASK 0x00000FFFU /**< data bits */
#define XEMACPS_PHYMNTNC_PHAD_SHFT_MSK 23U /**< Shift bits for PHYAD */
#define XEMACPS_PHYMNTNC_PREG_SHFT_MSK 18U /**< Shift bits for PHREG */
/*@}*/
/* Transmit buffer descriptor status words offset
* @{
*/
#define XEMACPS_BD_ADDR_OFFSET 0x00000000U /**< word 0/addr of BDs */
#define XEMACPS_BD_STAT_OFFSET 0x00000004U /**< word 1/status of BDs */
#define XEMACPS_BD_ADDR_HI_OFFSET 0x00000008U /**< word 2/addr of BDs */
/*
* @}
*/
/* Transmit buffer descriptor status words bit positions.
* Transmit buffer descriptor consists of two 32-bit registers,
* the first - word0 contains a 32-bit address pointing to the location of
* the transmit data.
* The following register - word1, consists of various information to control
* the XEmacPs transmit process. After transmit, this is updated with status
* information, whether the frame was transmitted OK or why it had failed.
* @{
*/
#define XEMACPS_TXBUF_USED_MASK 0x80000000U /**< Used bit. */
#define XEMACPS_TXBUF_WRAP_MASK 0x40000000U /**< Wrap bit, last descriptor */
#define XEMACPS_TXBUF_RETRY_MASK 0x20000000U /**< Retry limit exceeded */
#define XEMACPS_TXBUF_URUN_MASK 0x10000000U /**< Transmit underrun occurred */
#define XEMACPS_TXBUF_EXH_MASK 0x08000000U /**< Buffers exhausted */
#define XEMACPS_TXBUF_TCP_MASK 0x04000000U /**< Late collision. */
#define XEMACPS_TXBUF_NOCRC_MASK 0x00010000U /**< No CRC */
#define XEMACPS_TXBUF_LAST_MASK 0x00008000U /**< Last buffer */
#define XEMACPS_TXBUF_LEN_MASK 0x00003FFFU /**< Mask for length field */
/*
* @}
*/
/* Receive buffer descriptor status words bit positions.
* Receive buffer descriptor consists of two 32-bit registers,
* the first - word0 contains a 32-bit word aligned address pointing to the
* address of the buffer. The lower two bits make up the wrap bit indicating
* the last descriptor and the ownership bit to indicate it has been used by
* the XEmacPs.
* The following register - word1, contains status information regarding why
* the frame was received (the filter match condition) as well as other
* useful info.
* @{
*/
#define XEMACPS_RXBUF_BCAST_MASK 0x80000000U /**< Broadcast frame */
#define XEMACPS_RXBUF_MULTIHASH_MASK 0x40000000U /**< Multicast hashed frame */
#define XEMACPS_RXBUF_UNIHASH_MASK 0x20000000U /**< Unicast hashed frame */
#define XEMACPS_RXBUF_EXH_MASK 0x08000000U /**< buffer exhausted */
#define XEMACPS_RXBUF_AMATCH_MASK 0x06000000U /**< Specific address
matched */
#define XEMACPS_RXBUF_IDFOUND_MASK 0x01000000U /**< Type ID matched */
#define XEMACPS_RXBUF_IDMATCH_MASK 0x00C00000U /**< ID matched mask */
#define XEMACPS_RXBUF_VLAN_MASK 0x00200000U /**< VLAN tagged */
#define XEMACPS_RXBUF_PRI_MASK 0x00100000U /**< Priority tagged */
#define XEMACPS_RXBUF_VPRI_MASK 0x000E0000U /**< Vlan priority */
#define XEMACPS_RXBUF_CFI_MASK 0x00010000U /**< CFI frame */
#define XEMACPS_RXBUF_EOF_MASK 0x00008000U /**< End of frame. */
#define XEMACPS_RXBUF_SOF_MASK 0x00004000U /**< Start of frame. */
#define XEMACPS_RXBUF_LEN_MASK 0x00001FFFU /**< Mask for length field */
#define XEMACPS_RXBUF_LEN_JUMBO_MASK 0x00003FFFU /**< Mask for jumbo length */
#define XEMACPS_RXBUF_WRAP_MASK 0x00000002U /**< Wrap bit, last BD */
#define XEMACPS_RXBUF_NEW_MASK 0x00000001U /**< Used bit.. */
#define XEMACPS_RXBUF_ADD_MASK 0xFFFFFFFCU /**< Mask for address */
/*
* @}
*/
/*
* Define appropriate I/O access method to memory mapped I/O or other
* interface if necessary.
*/
#define XEmacPs_In32 Xil_In32
#define XEmacPs_Out32 Xil_Out32
/****************************************************************************/
/**
*
* Read the given register.
*
* @param BaseAddress is the base address of the device
* @param RegOffset is the register offset to be read
*
* @return The 32-bit value of the register
*
* @note
* C-style signature:
* u32 XEmacPs_ReadReg(u32 BaseAddress, u32 RegOffset)
*
*****************************************************************************/
#define XEmacPs_ReadReg(BaseAddress, RegOffset) \
XEmacPs_In32((BaseAddress) + (u32)(RegOffset))
/****************************************************************************/
/**
*
* Write the given register.
*
* @param BaseAddress is the base address of the device
* @param RegOffset is the register offset to be written
* @param Data is the 32-bit value to write to the register
*
* @return None.
*
* @note
* C-style signature:
* void XEmacPs_WriteReg(u32 BaseAddress, u32 RegOffset,
* u32 Data)
*
*****************************************************************************/
#define XEmacPs_WriteReg(BaseAddress, RegOffset, Data) \
XEmacPs_Out32((BaseAddress) + (u32)(RegOffset), (u32)(Data))
/************************** Function Prototypes *****************************/
/*
* Perform reset operation to the emacps interface
*/
void XEmacPs_ResetHw(u32 BaseAddr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,268 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemacps_intr.c
* @addtogroup emacps_v3_1
* @{
*
* Functions in this file implement general purpose interrupt processing related
* functionality. See xemacps.h for a detailed description of the driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wsy 01/10/10 First release
* 1.03a asa 01/24/13 Fix for CR #692702 which updates error handling for
* Rx errors. Under heavy Rx traffic, there will be a large
* number of errors related to receive buffer not available.
* Because of a HW bug (SI #692601), under such heavy errors,
* the Rx data path can become unresponsive. To reduce the
* probabilities for hitting this HW bug, the SW writes to
* bit 18 to flush a packet from Rx DPRAM immediately. The
* changes for it are done in the function
* XEmacPs_IntrHandler.
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp GEM specification
* and 64-bit changes.
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.1 hk 07/27/15 Do not call error handler with '0' error code when
* there is no error. CR# 869403
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xemacps.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
* Install an asynchronious handler function for the given HandlerType:
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @param HandlerType indicates what interrupt handler type is.
* XEMACPS_HANDLER_DMASEND, XEMACPS_HANDLER_DMARECV and
* XEMACPS_HANDLER_ERROR.
* @param FuncPointer is the pointer to the callback function
* @param CallBackRef is the upper layer callback reference passed back when
* when the callback function is invoked.
*
* @return
*
* None.
*
* @note
* There is no assert on the CallBackRef since the driver doesn't know what
* it is.
*
*****************************************************************************/
LONG XEmacPs_SetHandler(XEmacPs *InstancePtr, u32 HandlerType,
void *FuncPointer, void *CallBackRef)
{
LONG Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(FuncPointer != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
switch (HandlerType) {
case XEMACPS_HANDLER_DMASEND:
Status = (LONG)(XST_SUCCESS);
InstancePtr->SendHandler = ((XEmacPs_Handler)(void *)FuncPointer);
InstancePtr->SendRef = CallBackRef;
break;
case XEMACPS_HANDLER_DMARECV:
Status = (LONG)(XST_SUCCESS);
InstancePtr->RecvHandler = ((XEmacPs_Handler)(void *)FuncPointer);
InstancePtr->RecvRef = CallBackRef;
break;
case XEMACPS_HANDLER_ERROR:
Status = (LONG)(XST_SUCCESS);
InstancePtr->ErrorHandler = ((XEmacPs_ErrHandler)(void *)FuncPointer);
InstancePtr->ErrorRef = CallBackRef;
break;
default:
Status = (LONG)(XST_INVALID_PARAM);
break;
}
return Status;
}
/*****************************************************************************/
/**
* Master interrupt handler for EMAC driver. This routine will query the
* status of the device, bump statistics, and invoke user callbacks.
*
* This routine must be connected to an interrupt controller using OS/BSP
* specific methods.
*
* @param XEmacPsPtr is a pointer to the XEMACPS instance that has caused the
* interrupt.
*
******************************************************************************/
void XEmacPs_IntrHandler(void *XEmacPsPtr)
{
u32 RegISR;
u32 RegSR;
u32 RegCtrl;
u32 RegQ1ISR = 0U;
XEmacPs *InstancePtr = (XEmacPs *) XEmacPsPtr;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
/* This ISR will try to handle as many interrupts as it can in a single
* call. However, in most of the places where the user's error handler
* is called, this ISR exits because it is expected that the user will
* reset the device in nearly all instances.
*/
RegISR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_ISR_OFFSET);
/* Read Transmit Q1 ISR */
if (InstancePtr->Version > 2)
RegQ1ISR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_INTQ1_STS_OFFSET);
/* Clear the interrupt status register */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
RegISR);
/* Receive complete interrupt */
if ((RegISR & XEMACPS_IXR_FRAMERX_MASK) != 0x00000000U) {
/* Clear RX status register RX complete indication but preserve
* error bits if there is any */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_RXSR_OFFSET,
((u32)XEMACPS_RXSR_FRAMERX_MASK |
(u32)XEMACPS_RXSR_BUFFNA_MASK));
InstancePtr->RecvHandler(InstancePtr->RecvRef);
}
/* Transmit Q1 complete interrupt */
if ((InstancePtr->Version > 2) &&
((RegQ1ISR & XEMACPS_INTQ1SR_TXCOMPL_MASK) != 0x00000000U)) {
/* Clear TX status register TX complete indication but preserve
* error bits if there is any */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_INTQ1_STS_OFFSET,
XEMACPS_INTQ1SR_TXCOMPL_MASK);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_TXSR_OFFSET,
((u32)XEMACPS_TXSR_TXCOMPL_MASK |
(u32)XEMACPS_TXSR_USEDREAD_MASK));
InstancePtr->SendHandler(InstancePtr->SendRef);
}
/* Transmit complete interrupt */
if ((RegISR & XEMACPS_IXR_TXCOMPL_MASK) != 0x00000000U) {
/* Clear TX status register TX complete indication but preserve
* error bits if there is any */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_TXSR_OFFSET,
((u32)XEMACPS_TXSR_TXCOMPL_MASK |
(u32)XEMACPS_TXSR_USEDREAD_MASK));
InstancePtr->SendHandler(InstancePtr->SendRef);
}
/* Receive error conditions interrupt */
if ((RegISR & XEMACPS_IXR_RX_ERR_MASK) != 0x00000000U) {
/* Clear RX status register */
RegSR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_RXSR_OFFSET);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_RXSR_OFFSET, RegSR);
/* Fix for CR # 692702. Write to bit 18 of net_ctrl
* register to flush a packet out of Rx SRAM upon
* an error for receive buffer not available. */
if ((RegISR & XEMACPS_IXR_RXUSED_MASK) != 0x00000000U) {
RegCtrl =
XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
RegCtrl |= (u32)XEMACPS_NWCTRL_FLUSH_DPRAM_MASK;
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET, RegCtrl);
}
if(RegSR != 0) {
InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
XEMACPS_RECV, RegSR);
}
}
/* When XEMACPS_IXR_TXCOMPL_MASK is flaged, XEMACPS_IXR_TXUSED_MASK
* will be asserted the same time.
* Have to distinguish this bit to handle the real error condition.
*/
/* Transmit Q1 error conditions interrupt */
if ((InstancePtr->Version > 2) &&
((RegQ1ISR & XEMACPS_INTQ1SR_TXERR_MASK) != 0x00000000U) &&
((RegQ1ISR & XEMACPS_INTQ1SR_TXCOMPL_MASK) != 0x00000000U)) {
/* Clear Interrupt Q1 status register */
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_INTQ1_STS_OFFSET, RegQ1ISR);
InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XEMACPS_SEND,
RegQ1ISR);
}
/* Transmit error conditions interrupt */
if (((RegISR & XEMACPS_IXR_TX_ERR_MASK) != 0x00000000U) &&
(!(RegISR & XEMACPS_IXR_TXCOMPL_MASK) != 0x00000000U)) {
/* Clear TX status register */
RegSR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
XEMACPS_TXSR_OFFSET);
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
XEMACPS_TXSR_OFFSET, RegSR);
InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XEMACPS_SEND,
RegSR);
}
}
/** @} */

View file

@ -0,0 +1,97 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemacps_sinit.c
* @addtogroup emacps_v3_1
* @{
*
* This file contains lookup method by device ID when success, it returns
* pointer to config table to be used to initialize the device.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wsy 01/10/10 New
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xemacps.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/*************************** Variable Definitions *****************************/
extern XEmacPs_Config XEmacPs_ConfigTable[XPAR_XEMACPS_NUM_INSTANCES];
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/**
* Lookup the device configuration based on the unique device ID. The table
* contains the configuration info for each device in the system.
*
* @param DeviceId is the unique device ID of the device being looked up.
*
* @return
* A pointer to the configuration table entry corresponding to the given
* device ID, or NULL if no match is found.
*
******************************************************************************/
XEmacPs_Config *XEmacPs_LookupConfig(u16 DeviceId)
{
XEmacPs_Config *CfgPtr = NULL;
u32 i;
for (i = 0U; i < (u32)XPAR_XEMACPS_NUM_INSTANCES; i++) {
if (XEmacPs_ConfigTable[i].DeviceId == DeviceId) {
CfgPtr = &XEmacPs_ConfigTable[i];
break;
}
}
return (XEmacPs_Config *)(CfgPtr);
}
/** @} */

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner xgpiops_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling gpiops"
xgpiops_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: xgpiops_includes
xgpiops_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

View file

@ -0,0 +1,628 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xgpiops.c
* @addtogroup gpiops_v3_1
* @{
*
* The XGpioPs driver. Functions in this file are the minimum required functions
* for this driver. See xgpiops.h for a detailed description of the driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sv 01/15/10 First Release
* 1.01a sv 04/15/12 Removed the APIs XGpioPs_SetMode, XGpioPs_SetModePin
* XGpioPs_GetMode, XGpioPs_GetModePin as they are not
* relevant to Zynq device. The interrupts are disabled
* for output pins on all banks during initialization.
* 2.1 hk 04/29/14 Use Input data register DATA_RO for read. CR# 771667.
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.1 kvn 04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xgpiops.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
extern void StubHandler(void *CallBackRef, u32 Bank, u32 Status);
/*****************************************************************************/
/*
*
* This function initializes a XGpioPs instance/driver.
* All members of the XGpioPs instance structure are initialized and
* StubHandlers are assigned to the Bank Status Handlers.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param ConfigPtr points to the XGpioPs device configuration structure.
* @param EffectiveAddr is the device base address in the virtual memory
* address space. If the address translation is not used then the
* physical address should be passed.
* Unexpected errors may occur if the address mapping is changed
* after this function is invoked.
*
* @return XST_SUCCESS always.
*
* @note None.
*
******************************************************************************/
s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, XGpioPs_Config *ConfigPtr,
u32 EffectiveAddr)
{
s32 Status = XST_SUCCESS;
u8 i;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(ConfigPtr != NULL);
Xil_AssertNonvoid(EffectiveAddr != (u32)0);
/*
* Set some default values for instance data, don't indicate the device
* is ready to use until everything has been initialized successfully.
*/
InstancePtr->IsReady = 0U;
InstancePtr->GpioConfig.BaseAddr = EffectiveAddr;
InstancePtr->GpioConfig.DeviceId = ConfigPtr->DeviceId;
InstancePtr->Handler = StubHandler;
InstancePtr->Platform = XGetPlatform_Info();
/* Initialize the Bank data based on platform */
if (InstancePtr->Platform == XPLAT_ZYNQ_ULTRA_MP) {
/*
* Max pins in the ZynqMP GPIO device
* 0 - 25, Bank 0
* 26 - 51, Bank 1
* 52 - 77, Bank 2
* 78 - 109, Bank 3
* 110 - 141, Bank 4
* 142 - 173, Bank 5
*/
InstancePtr->MaxPinNum = (u32)174;
InstancePtr->MaxBanks = (u8)6;
} else {
/*
* Max pins in the GPIO device
* 0 - 31, Bank 0
* 32 - 53, Bank 1
* 54 - 85, Bank 2
* 86 - 117, Bank 3
*/
InstancePtr->MaxPinNum = (u32)118;
InstancePtr->MaxBanks = (u8)4;
}
/*
* By default, interrupts are not masked in GPIO. Disable
* interrupts for all pins in all the 4 banks.
*/
for (i=0;i<InstancePtr->MaxBanks;i++) {
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(i) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU);
}
/* Indicate the component is now ready to use. */
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
return Status;
}
/****************************************************************************/
/**
*
* Read the Data register of the specified GPIO bank.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
*
* @return Current value of the Data register.
*
* @note This function is used for reading the state of all the GPIO pins
* of specified bank.
*
*****************************************************************************/
u32 XGpioPs_Read(XGpioPs *InstancePtr, u8 Bank)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks);
return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_DATA_BANK_OFFSET) +
XGPIOPS_DATA_RO_OFFSET);
}
/****************************************************************************/
/**
*
* Read Data from the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number for which the data has to be read.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
* See xgpiops.h for the mapping of the pin numbers in the banks.
*
* @return Current value of the Pin (0 or 1).
*
* @note This function is used for reading the state of the specified
* GPIO pin.
*
*****************************************************************************/
u32 XGpioPs_ReadPin(XGpioPs *InstancePtr, u32 Pin)
{
u8 Bank;
u8 PinNumber;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
return (XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_DATA_BANK_OFFSET) +
XGPIOPS_DATA_RO_OFFSET) >> (u32)PinNumber) & (u32)1;
}
/****************************************************************************/
/**
*
* Write to the Data register of the specified GPIO bank.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param Data is the value to be written to the Data register.
*
* @return None.
*
* @note This function is used for writing to all the GPIO pins of
* the bank. The previous state of the pins is not maintained.
*
*****************************************************************************/
void XGpioPs_Write(XGpioPs *InstancePtr, u8 Bank, u32 Data)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_DATA_BANK_OFFSET) +
XGPIOPS_DATA_OFFSET, Data);
}
/****************************************************************************/
/**
*
* Write data to the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number to which the Data is to be written.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
* @param Data is the data to be written to the specified pin (0 or 1).
*
* @return None.
*
* @note This function does a masked write to the specified pin of
* the specified GPIO bank. The previous state of other pins
* is maintained.
*
*****************************************************************************/
void XGpioPs_WritePin(XGpioPs *InstancePtr, u32 Pin, u32 Data)
{
u32 RegOffset;
u32 Value;
u8 Bank;
u8 PinNumber;
u32 DataVar = Data;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
if (PinNumber > 15U) {
/* There are only 16 data bits in bit maskable register. */
PinNumber -= (u8)16;
RegOffset = XGPIOPS_DATA_MSW_OFFSET;
} else {
RegOffset = XGPIOPS_DATA_LSW_OFFSET;
}
/*
* Get the 32 bit value to be written to the Mask/Data register where
* the upper 16 bits is the mask and lower 16 bits is the data.
*/
DataVar &= (u32)0x01;
Value = ~((u32)1 << (PinNumber + 16U)) & ((DataVar << PinNumber) | 0xFFFF0000U);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_DATA_MASK_OFFSET) +
RegOffset, Value);
}
/****************************************************************************/
/**
*
* Set the Direction of the pins of the specified GPIO Bank.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param Direction is the 32 bit mask of the Pin direction to be set for
* all the pins in the Bank. Bits with 0 are set to Input mode,
* bits with 1 are set to Output Mode.
*
* @return None.
*
* @note This function is used for setting the direction of all the pins
* in the specified bank. The previous state of the pins is
* not maintained.
*
*****************************************************************************/
void XGpioPs_SetDirection(XGpioPs *InstancePtr, u8 Bank, u32 Direction)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_DIRM_OFFSET, Direction);
}
/****************************************************************************/
/**
*
* Set the Direction of the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number to which the Data is to be written.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
* @param Direction is the direction to be set for the specified pin.
* Valid values are 0 for Input Direction, 1 for Output Direction.
*
* @return None.
*
*****************************************************************************/
void XGpioPs_SetDirectionPin(XGpioPs *InstancePtr, u32 Pin, u32 Direction)
{
u8 Bank;
u8 PinNumber;
u32 DirModeReg;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Pin < InstancePtr->MaxPinNum);
Xil_AssertVoid(Direction <= (u32)1);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
DirModeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_DIRM_OFFSET);
if (Direction!=(u32)0) { /* Output Direction */
DirModeReg |= ((u32)1 << (u32)PinNumber);
} else { /* Input Direction */
DirModeReg &= ~ ((u32)1 << (u32)PinNumber);
}
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_DIRM_OFFSET, DirModeReg);
}
/****************************************************************************/
/**
*
* Get the Direction of the pins of the specified GPIO Bank.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
*
* return Returns a 32 bit mask of the Direction register. Bits with 0 are
* in Input mode, bits with 1 are in Output Mode.
*
* @note None.
*
*****************************************************************************/
u32 XGpioPs_GetDirection(XGpioPs *InstancePtr, u8 Bank)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks);
return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_DIRM_OFFSET);
}
/****************************************************************************/
/**
*
* Get the Direction of the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number for which the Direction is to be
* retrieved.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
*
* @return Direction of the specified pin.
* - 0 for Input Direction
* - 1 for Output Direction
*
* @note None.
*
*****************************************************************************/
u32 XGpioPs_GetDirectionPin(XGpioPs *InstancePtr, u32 Pin)
{
u8 Bank;
u8 PinNumber;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
return (XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_DIRM_OFFSET) >> (u32)PinNumber) & (u32)1;
}
/****************************************************************************/
/**
*
* Set the Output Enable of the pins of the specified GPIO Bank.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param OpEnable is the 32 bit mask of the Output Enables to be set for
* all the pins in the Bank. The Output Enable of bits with 0 are
* disabled, the Output Enable of bits with 1 are enabled.
*
* @return None.
*
* @note This function is used for setting the Output Enables of all the
* pins in the specified bank. The previous state of the Output
* Enables is not maintained.
*
*****************************************************************************/
void XGpioPs_SetOutputEnable(XGpioPs *InstancePtr, u8 Bank, u32 OpEnable)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_OUTEN_OFFSET, OpEnable);
}
/****************************************************************************/
/**
*
* Set the Output Enable of the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number to which the Data is to be written.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
* @param OpEnable specifies whether the Output Enable for the specified
* pin should be enabled.
* Valid values are 0 for Disabling Output Enable,
* 1 for Enabling Output Enable.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_SetOutputEnablePin(XGpioPs *InstancePtr, u32 Pin, u32 OpEnable)
{
u8 Bank;
u8 PinNumber;
u32 OpEnableReg;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Pin < InstancePtr->MaxPinNum);
Xil_AssertVoid(OpEnable <= (u32)1);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
OpEnableReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_OUTEN_OFFSET);
if (OpEnable != (u32)0) { /* Enable Output Enable */
OpEnableReg |= ((u32)1 << (u32)PinNumber);
} else { /* Disable Output Enable */
OpEnableReg &= ~ ((u32)1 << (u32)PinNumber);
}
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_OUTEN_OFFSET, OpEnableReg);
}
/****************************************************************************/
/**
*
* Get the Output Enable status of the pins of the specified GPIO Bank.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
*
* return Returns a a 32 bit mask of the Output Enable register.
* Bits with 0 are in Disabled state, bits with 1 are in
* Enabled State.
*
* @note None.
*
*****************************************************************************/
u32 XGpioPs_GetOutputEnable(XGpioPs *InstancePtr, u8 Bank)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks);
return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_OUTEN_OFFSET);
}
/****************************************************************************/
/**
*
* Get the Output Enable status of the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number for which the Output Enable status is to
* be retrieved.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
*
* @return Output Enable of the specified pin.
* - 0 if Output Enable is disabled for this pin
* - 1 if Output Enable is enabled for this pin
*
* @note None.
*
*****************************************************************************/
u32 XGpioPs_GetOutputEnablePin(XGpioPs *InstancePtr, u32 Pin)
{
u8 Bank;
u8 PinNumber;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
return (XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_OUTEN_OFFSET) >> (u32)PinNumber) & (u32)1;
}
/****************************************************************************/
/*
*
* Get the Bank number and the Pin number in the Bank, for the given PinNumber
* in the GPIO device.
*
* @param PinNumber is the Pin number in the GPIO device.
* @param BankNumber returns the Bank in which this GPIO pin is present.
* Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
* @param PinNumberInBank returns the Pin Number within the Bank.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_GetBankPin(u8 PinNumber, u8 *BankNumber, u8 *PinNumberInBank)
{
u32 XGpioPsPinTable[6] = {0};
u32 Platform = XGetPlatform_Info();
if (Platform == XPLAT_ZYNQ_ULTRA_MP) {
/*
* This structure defines the mapping of the pin numbers to the banks when
* the driver APIs are used for working on the individual pins.
*/
XGpioPsPinTable[0] = (u32)25; /* 0 - 25, Bank 0 */
XGpioPsPinTable[1] = (u32)51; /* 26 - 51, Bank 1 */
XGpioPsPinTable[2] = (u32)77; /* 52 - 77, Bank 2 */
XGpioPsPinTable[3] = (u32)109; /* 78 - 109, Bank 3 */
XGpioPsPinTable[4] = (u32)141; /* 110 - 141, Bank 4 */
XGpioPsPinTable[5] = (u32)173; /* 142 - 173 Bank 5 */
*BankNumber = 0U;
while (*BankNumber < 6U) {
if (PinNumber <= XGpioPsPinTable[*BankNumber]) {
break;
}
(*BankNumber)++;
}
} else {
XGpioPsPinTable[0] = (u32)31; /* 0 - 31, Bank 0 */
XGpioPsPinTable[1] = (u32)53; /* 32 - 53, Bank 1 */
XGpioPsPinTable[2] = (u32)85; /* 54 - 85, Bank 2 */
XGpioPsPinTable[3] = (u32)117; /* 86 - 117 Bank 3 */
*BankNumber = 0U;
while (*BankNumber < 4U) {
if (PinNumber <= XGpioPsPinTable[*BankNumber]) {
break;
}
(*BankNumber)++;
}
}
if (*BankNumber == (u8)0) {
*PinNumberInBank = PinNumber;
} else {
*PinNumberInBank = (u8)((u32)PinNumber %
(XGpioPsPinTable[*BankNumber - (u8)1] + (u32)1));
}
}
/** @} */

View file

@ -0,0 +1,268 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xgpiops.h
* @addtogroup gpiops_v3_1
* @{
* @details
*
* The Xilinx PS GPIO driver. This driver supports the Xilinx PS GPIO
* Controller.
*
* The GPIO Controller supports the following features:
* - 4 banks
* - Masked writes (There are no masked reads)
* - Bypass mode
* - Configurable Interrupts (Level/Edge)
*
* This driver is intended to be RTOS and processor independent. Any needs for
* dynamic memory management, threads or thread mutual exclusion, virtual
* memory, or cache control must be satisfied by the layer above this driver.
* This driver supports all the features listed above, if applicable.
*
* <b>Driver Description</b>
*
* The device driver enables higher layer software (e.g., an application) to
* communicate to the GPIO.
*
* <b>Interrupts</b>
*
* The driver provides interrupt management functions and an interrupt handler.
* Users of this driver need to provide callback functions. An interrupt handler
* example is available with the driver.
*
* <b>Threads</b>
*
* This driver is not thread safe. Any needs for threads or thread mutual
* exclusion must be satisfied by the layer above this driver.
*
* <b>Asserts</b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on argument
* values. Asserts can be turned off on a system-wide basis by defining, at
* compile time, the NDEBUG identifier. By default, asserts are turned on and it
* is recommended that users leave asserts on during development.
*
* <b>Building the driver</b>
*
* The XGpioPs driver is composed of several source files. This allows the user
* to build and link only those parts of the driver that are necessary.
* <br><br>
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sv 01/15/10 First Release
* 1.01a sv 04/15/12 Removed the APIs XGpioPs_SetMode, XGpioPs_SetModePin
* XGpioPs_GetMode, XGpioPs_GetModePin as they are not
* relevant to Zynq device.The interrupts are disabled
* for output pins on all banks during initialization.
* 1.02a hk 08/22/13 Added low level reset API
* 2.1 hk 04/29/14 Use Input data register DATA_RO for read. CR# 771667.
* 2.2 sk 10/13/14 Used Pin number in Bank instead of pin number
* passed to APIs. CR# 822636
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.1 kvn 04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
*
* </pre>
*
******************************************************************************/
#ifndef XGPIOPS_H /* prevent circular inclusions */
#define XGPIOPS_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xstatus.h"
#include "xgpiops_hw.h"
#include "xplatform_info.h"
/************************** Constant Definitions *****************************/
/** @name Interrupt types
* @{
* The following constants define the interrupt types that can be set for each
* GPIO pin.
*/
#define XGPIOPS_IRQ_TYPE_EDGE_RISING 0x00U /**< Interrupt on Rising edge */
#define XGPIOPS_IRQ_TYPE_EDGE_FALLING 0x01U /**< Interrupt Falling edge */
#define XGPIOPS_IRQ_TYPE_EDGE_BOTH 0x02U /**< Interrupt on both edges */
#define XGPIOPS_IRQ_TYPE_LEVEL_HIGH 0x03U /**< Interrupt on high level */
#define XGPIOPS_IRQ_TYPE_LEVEL_LOW 0x04U /**< Interrupt on low level */
/*@}*/
#define XGPIOPS_BANK_MAX_PINS (u32)32 /**< Max pins in a GPIO bank */
#define XGPIOPS_BANK0 0x00U /**< GPIO Bank 0 */
#define XGPIOPS_BANK1 0x01U /**< GPIO Bank 1 */
#define XGPIOPS_BANK2 0x02U /**< GPIO Bank 2 */
#define XGPIOPS_BANK3 0x03U /**< GPIO Bank 3 */
#ifdef XPAR_PSU_GPIO_0_BASEADDR
#define XGPIOPS_BANK4 0x04U /**< GPIO Bank 4 */
#define XGPIOPS_BANK5 0x05U /**< GPIO Bank 5 */
#endif
#define XGPIOPS_MAX_BANKS_ZYNQMP 0x06U /**< Max banks in a
* Zynq Ultrascale+ MP GPIO device
*/
#define XGPIOPS_MAX_BANKS 0x04U /**< Max banks in a Zynq GPIO device */
#define XGPIOPS_DEVICE_MAX_PIN_NUM_ZYNQMP (u32)174 /**< Max pins in the
* Zynq Ultrascale+ MP GPIO device
* 0 - 25, Bank 0
* 26 - 51, Bank 1
* 52 - 77, Bank 2
* 78 - 109, Bank 3
* 110 - 141, Bank 4
* 142 - 173, Bank 5
*/
#define XGPIOPS_DEVICE_MAX_PIN_NUM (u32)118 /**< Max pins in the Zynq GPIO device
* 0 - 31, Bank 0
* 32 - 53, Bank 1
* 54 - 85, Bank 2
* 86 - 117, Bank 3
*/
/**************************** Type Definitions *******************************/
/****************************************************************************/
/**
* This handler data type allows the user to define a callback function to
* handle the interrupts for the GPIO device. The application using this
* driver is expected to define a handler of this type, to support interrupt
* driven mode. The handler executes in an interrupt context such that minimal
* processing should be performed.
*
* @param CallBackRef is a callback reference passed in by the upper layer
* when setting the callback functions for a GPIO bank. It is
* passed back to the upper layer when the callback is invoked. Its
* type is not important to the driver component, so it is a void
* pointer.
* @param Bank is the bank for which the interrupt status has changed.
* @param Status is the Interrupt status of the GPIO bank.
*
*****************************************************************************/
typedef void (*XGpioPs_Handler) (void *CallBackRef, u32 Bank, u32 Status);
/**
* This typedef contains configuration information for a device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddr; /**< Register base address */
} XGpioPs_Config;
/**
* The XGpioPs driver instance data. The user is required to allocate a
* variable of this type for the GPIO device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XGpioPs_Config GpioConfig; /**< Device configuration */
u32 IsReady; /**< Device is initialized and ready */
XGpioPs_Handler Handler; /**< Status handlers for all banks */
void *CallBackRef; /**< Callback ref for bank handlers */
u32 Platform; /**< Platform data */
u32 MaxPinNum; /**< Max pins in the GPIO device */
u8 MaxBanks; /**< Max banks in a GPIO device */
} XGpioPs;
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/* Functions in xgpiops.c */
s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, XGpioPs_Config *ConfigPtr,
u32 EffectiveAddr);
/* Bank APIs in xgpiops.c */
u32 XGpioPs_Read(XGpioPs *InstancePtr, u8 Bank);
void XGpioPs_Write(XGpioPs *InstancePtr, u8 Bank, u32 Data);
void XGpioPs_SetDirection(XGpioPs *InstancePtr, u8 Bank, u32 Direction);
u32 XGpioPs_GetDirection(XGpioPs *InstancePtr, u8 Bank);
void XGpioPs_SetOutputEnable(XGpioPs *InstancePtr, u8 Bank, u32 OpEnable);
u32 XGpioPs_GetOutputEnable(XGpioPs *InstancePtr, u8 Bank);
void XGpioPs_GetBankPin(u8 PinNumber, u8 *BankNumber, u8 *PinNumberInBank);
/* Pin APIs in xgpiops.c */
u32 XGpioPs_ReadPin(XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_WritePin(XGpioPs *InstancePtr, u32 Pin, u32 Data);
void XGpioPs_SetDirectionPin(XGpioPs *InstancePtr, u32 Pin, u32 Direction);
u32 XGpioPs_GetDirectionPin(XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_SetOutputEnablePin(XGpioPs *InstancePtr, u32 Pin, u32 OpEnable);
u32 XGpioPs_GetOutputEnablePin(XGpioPs *InstancePtr, u32 Pin);
/* Diagnostic functions in xgpiops_selftest.c */
s32 XGpioPs_SelfTest(XGpioPs *InstancePtr);
/* Functions in xgpiops_intr.c */
/* Bank APIs in xgpiops_intr.c */
void XGpioPs_IntrEnable(XGpioPs *InstancePtr, u8 Bank, u32 Mask);
void XGpioPs_IntrDisable(XGpioPs *InstancePtr, u8 Bank, u32 Mask);
u32 XGpioPs_IntrGetEnabled(XGpioPs *InstancePtr, u8 Bank);
u32 XGpioPs_IntrGetStatus(XGpioPs *InstancePtr, u8 Bank);
void XGpioPs_IntrClear(XGpioPs *InstancePtr, u8 Bank, u32 Mask);
void XGpioPs_SetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 IntrType,
u32 IntrPolarity, u32 IntrOnAny);
void XGpioPs_GetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 *IntrType,
u32 *IntrPolarity, u32 *IntrOnAny);
void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef,
XGpioPs_Handler FuncPointer);
void XGpioPs_IntrHandler(XGpioPs *InstancePtr);
/* Pin APIs in xgpiops_intr.c */
void XGpioPs_SetIntrTypePin(XGpioPs *InstancePtr, u32 Pin, u8 IrqType);
u8 XGpioPs_GetIntrTypePin(XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_IntrEnablePin(XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_IntrDisablePin(XGpioPs *InstancePtr, u32 Pin);
u32 XGpioPs_IntrGetEnabledPin(XGpioPs *InstancePtr, u32 Pin);
u32 XGpioPs_IntrGetStatusPin(XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_IntrClearPin(XGpioPs *InstancePtr, u32 Pin);
/* Functions in xgpiops_sinit.c */
XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,55 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the Software), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in
*all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
*(a) running on a Xilinx device, or
*(b) that interact with a Xilinx device through a bus or interconnect.
*
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the Xilinx shall not be used
*in advertising or otherwise to promote the sale, use or other dealings in
*this Software without prior written authorization from Xilinx.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xgpiops.h"
/*
* The configuration table for devices
*/
XGpioPs_Config XGpioPs_ConfigTable[] =
{
{
XPAR_PSU_GPIO_0_DEVICE_ID,
XPAR_PSU_GPIO_0_BASEADDR
}
};

View file

@ -0,0 +1,169 @@
/******************************************************************************
*
* Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xgpiops_hw.c
* @addtogroup gpiops_v3_1
* @{
*
* This file contains low level GPIO functions.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.02a hk 08/22/13 First Release
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.1 kvn 04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xgpiops_hw.h"
#include "xgpiops.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/*
*
* This function resets the GPIO module by writing reset values to
* all registers
*
* @param Base address of GPIO module
*
* @return None
*
* @note None.
*
******************************************************************************/
void XGpioPs_ResetHw(u32 BaseAddress)
{
u32 BankCount;
u32 Platform,MaxBanks;
Platform = XGetPlatform_Info();
if (Platform == XPLAT_ZYNQ_ULTRA_MP) {
MaxBanks = (u32)6;
} else {
MaxBanks = (u32)4;
}
/* Write reset values to all mask data registers */
for(BankCount = 2U; BankCount < (u32)MaxBanks; BankCount++) {
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_DATA_MASK_OFFSET) +
XGPIOPS_DATA_LSW_OFFSET), 0x0U);
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_DATA_MASK_OFFSET) +
XGPIOPS_DATA_MSW_OFFSET), 0x0U);
}
/* Write reset values to all output data registers */
for(BankCount = 2U; BankCount < (u32)MaxBanks; BankCount++) {
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_DATA_BANK_OFFSET) +
XGPIOPS_DATA_OFFSET), 0x0U);
}
/* Reset all registers of all GPIO banks */
for(BankCount = 0U; BankCount < (u32)MaxBanks; BankCount++) {
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_DIRM_OFFSET), 0x0U);
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_OUTEN_OFFSET), 0x0U);
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTMASK_OFFSET), 0x0U);
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTEN_OFFSET), 0x0U);
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTDIS_OFFSET), 0x0U);
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTSTS_OFFSET), 0x0U);
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTPOL_OFFSET), 0x0U);
XGpioPs_WriteReg(BaseAddress,
((BankCount * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTANY_OFFSET), 0x0U);
}
/* Bank 0 Int type */
XGpioPs_WriteReg(BaseAddress, XGPIOPS_INTTYPE_OFFSET,
XGPIOPS_INTTYPE_BANK0_RESET);
/* Bank 1 Int type */
XGpioPs_WriteReg(BaseAddress,
((u32)XGPIOPS_REG_MASK_OFFSET + (u32)XGPIOPS_INTTYPE_OFFSET),
XGPIOPS_INTTYPE_BANK1_RESET);
/* Bank 2 Int type */
XGpioPs_WriteReg(BaseAddress,
(((u32)2 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET),
XGPIOPS_INTTYPE_BANK2_RESET);
/* Bank 3 Int type */
XGpioPs_WriteReg(BaseAddress,
(((u32)3 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET),
XGPIOPS_INTTYPE_BANK3_RESET);
if (Platform == XPLAT_ZYNQ_ULTRA_MP) {
/* Bank 4 Int type */
XGpioPs_WriteReg(BaseAddress,
(((u32)4 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET),
XGPIOPS_INTTYPE_BANK4_RESET);
/* Bank 5 Int type */
XGpioPs_WriteReg(BaseAddress,
(((u32)5 * XGPIOPS_REG_MASK_OFFSET) + XGPIOPS_INTTYPE_OFFSET),
XGPIOPS_INTTYPE_BANK5_RESET);
}
}
/** @} */

View file

@ -0,0 +1,164 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xgpiops_hw.h
* @addtogroup gpiops_v3_1
* @{
*
* This header file contains the identifiers and basic driver functions (or
* macros) that can be used to access the device. Other driver functions
* are defined in xgpiops.h.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------
* 1.00a sv 01/15/10 First Release
* 1.02a hk 08/22/13 Added low level reset API function prototype and
* related constant definitions
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.1 kvn 04/13/15 Corrected reset values of banks.
* </pre>
*
******************************************************************************/
#ifndef XGPIOPS_HW_H /* prevent circular inclusions */
#define XGPIOPS_HW_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/** @name Register offsets for the GPIO. Each register is 32 bits.
* @{
*/
#define XGPIOPS_DATA_LSW_OFFSET 0x00000000U /* Mask and Data Register LSW, WO */
#define XGPIOPS_DATA_MSW_OFFSET 0x00000004U /* Mask and Data Register MSW, WO */
#define XGPIOPS_DATA_OFFSET 0x00000040U /* Data Register, RW */
#define XGPIOPS_DATA_RO_OFFSET 0x00000060U /* Data Register - Input, RO */
#define XGPIOPS_DIRM_OFFSET 0x00000204U /* Direction Mode Register, RW */
#define XGPIOPS_OUTEN_OFFSET 0x00000208U /* Output Enable Register, RW */
#define XGPIOPS_INTMASK_OFFSET 0x0000020CU /* Interrupt Mask Register, RO */
#define XGPIOPS_INTEN_OFFSET 0x00000210U /* Interrupt Enable Register, WO */
#define XGPIOPS_INTDIS_OFFSET 0x00000214U /* Interrupt Disable Register, WO*/
#define XGPIOPS_INTSTS_OFFSET 0x00000218U /* Interrupt Status Register, RO */
#define XGPIOPS_INTTYPE_OFFSET 0x0000021CU /* Interrupt Type Register, RW */
#define XGPIOPS_INTPOL_OFFSET 0x00000220U /* Interrupt Polarity Register, RW */
#define XGPIOPS_INTANY_OFFSET 0x00000224U /* Interrupt On Any Register, RW */
/* @} */
/** @name Register offsets for each Bank.
* @{
*/
#define XGPIOPS_DATA_MASK_OFFSET 0x00000008U /* Data/Mask Registers offset */
#define XGPIOPS_DATA_BANK_OFFSET 0x00000004U /* Data Registers offset */
#define XGPIOPS_REG_MASK_OFFSET 0x00000040U /* Registers offset */
/* @} */
/* For backwards compatibility */
#define XGPIOPS_BYPM_MASK_OFFSET (u32)0x40
/** @name Interrupt type reset values for each bank
* @{
*/
#ifdef XPAR_PSU_GPIO_0_BASEADDR
#define XGPIOPS_INTTYPE_BANK0_RESET 0x03FFFFFFU /* Resets specific to Zynq Ultrascale+ MP */
#define XGPIOPS_INTTYPE_BANK1_RESET 0x03FFFFFFU
#define XGPIOPS_INTTYPE_BANK2_RESET 0x03FFFFFFU
#else
#define XGPIOPS_INTTYPE_BANK0_RESET 0xFFFFFFFFU /* Resets specific to Zynq */
#define XGPIOPS_INTTYPE_BANK1_RESET 0x003FFFFFU
#define XGPIOPS_INTTYPE_BANK2_RESET 0xFFFFFFFFU
#endif
#define XGPIOPS_INTTYPE_BANK3_RESET 0xFFFFFFFFU /* Reset common to both platforms */
#define XGPIOPS_INTTYPE_BANK4_RESET 0xFFFFFFFFU /* Resets specific to Zynq Ultrascale+ MP */
#define XGPIOPS_INTTYPE_BANK5_RESET 0xFFFFFFFFU
/* @} */
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/**
*
* This macro reads the given register.
*
* @param BaseAddr is the base address of the device.
* @param RegOffset is the register offset to be read.
*
* @return The 32-bit value of the register
*
* @note None.
*
*****************************************************************************/
#define XGpioPs_ReadReg(BaseAddr, RegOffset) \
Xil_In32((BaseAddr) + (u32)(RegOffset))
/****************************************************************************/
/**
*
* This macro writes to the given register.
*
* @param BaseAddr is the base address of the device.
* @param RegOffset is the offset of the register to be written.
* @param Data is the 32-bit value to write to the register.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
#define XGpioPs_WriteReg(BaseAddr, RegOffset, Data) \
Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data))
/************************** Function Prototypes ******************************/
void XGpioPs_ResetHw(u32 BaseAddress);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XGPIOPS_HW_H */
/** @} */

View file

@ -0,0 +1,731 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xgpiops_intr.c
* @addtogroup gpiops_v3_1
* @{
*
* This file contains functions related to GPIO interrupt handling.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sv 01/18/10 First Release
* 2.2 sk 10/13/14 Used Pin number in Bank instead of pin number
* passed to API's. CR# 822636
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.1 kvn 04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xgpiops.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
void StubHandler(void *CallBackRef, u32 Bank, u32 Status);
/****************************************************************************/
/**
*
* This function enables the interrupts for the specified pins in the specified
* bank.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param Mask is the bit mask of the pins for which interrupts are to
* be enabled. Bit positions of 1 will be enabled. Bit positions
* of 0 will keep the previous setting.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_IntrEnable(XGpioPs *InstancePtr, u8 Bank, u32 Mask)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTEN_OFFSET, Mask);
}
/****************************************************************************/
/**
*
* This function enables the interrupt for the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number for which the interrupt is to be enabled.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_IntrEnablePin(XGpioPs *InstancePtr, u32 Pin)
{
u8 Bank;
u8 PinNumber;
u32 IntrReg = 0U;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
IntrReg = ((u32)1 << (u32)PinNumber);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTEN_OFFSET, IntrReg);
}
/****************************************************************************/
/**
*
* This function disables the interrupts for the specified pins in the specified
* bank.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param Mask is the bit mask of the pins for which interrupts are
* to be disabled. Bit positions of 1 will be disabled. Bit
* positions of 0 will keep the previous setting.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_IntrDisable(XGpioPs *InstancePtr, u8 Bank, u32 Mask)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTDIS_OFFSET, Mask);
}
/****************************************************************************/
/**
*
* This function disables the interrupts for the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number for which the interrupt is to be disabled.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_IntrDisablePin(XGpioPs *InstancePtr, u32 Pin)
{
u8 Bank;
u8 PinNumber;
u32 IntrReg = 0U;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
IntrReg = ((u32)1 << (u32)PinNumber);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTDIS_OFFSET, IntrReg);
}
/****************************************************************************/
/**
*
* This function returns the interrupt enable status for a bank.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
*
* @return Enabled interrupt(s) in a 32-bit format. Bit positions with 1
* indicate that the interrupt for that pin is enabled, bit
* positions with 0 indicate that the interrupt for that pin is
* disabled.
*
* @note None.
*
*****************************************************************************/
u32 XGpioPs_IntrGetEnabled(XGpioPs *InstancePtr, u8 Bank)
{
u32 IntrMask;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks);
IntrMask = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTMASK_OFFSET);
return (~IntrMask);
}
/****************************************************************************/
/**
*
* This function returns whether interrupts are enabled for the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number for which the interrupt enable status
* is to be known.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
*
* @return
* - TRUE if the interrupt is enabled.
* - FALSE if the interrupt is disabled.
*
* @note None.
*
*****************************************************************************/
u32 XGpioPs_IntrGetEnabledPin(XGpioPs *InstancePtr, u32 Pin)
{
u8 Bank;
u8 PinNumber;
u32 IntrReg;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTMASK_OFFSET);
return (((IntrReg & ((u32)1 << PinNumber)) != (u32)0)? FALSE : TRUE);
}
/****************************************************************************/
/**
*
* This function returns interrupt status read from Interrupt Status Register.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
*
* @return The value read from Interrupt Status Register.
*
* @note None.
*
*****************************************************************************/
u32 XGpioPs_IntrGetStatus(XGpioPs *InstancePtr, u8 Bank)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Bank < InstancePtr->MaxBanks);
return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTSTS_OFFSET);
}
/****************************************************************************/
/**
*
* This function returns interrupt enable status of the specified pin.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number for which the interrupt enable status
* is to be known.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
*
* @return
* - TRUE if the interrupt has occurred.
* - FALSE if the interrupt has not occurred.
*
* @note None.
*
*****************************************************************************/
u32 XGpioPs_IntrGetStatusPin(XGpioPs *InstancePtr, u32 Pin)
{
u8 Bank;
u8 PinNumber;
u32 IntrReg;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTSTS_OFFSET);
return (((IntrReg & ((u32)1 << PinNumber)) != (u32)0)? TRUE : FALSE);
}
/****************************************************************************/
/**
*
* This function clears pending interrupt(s) with the provided mask. This
* function should be called after the software has serviced the interrupts
* that are pending.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param Mask is the mask of the interrupts to be cleared. Bit positions
* of 1 will be cleared. Bit positions of 0 will not change the
* previous interrupt status.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_IntrClear(XGpioPs *InstancePtr, u8 Bank, u32 Mask)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
/* Clear the currently pending interrupts. */
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTSTS_OFFSET, Mask);
}
/****************************************************************************/
/**
*
* This function clears the specified pending interrupt. This function should be
* called after the software has serviced the interrupts that are pending.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param Pin is the pin number for which the interrupt status is to be
* cleared. Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_IntrClearPin(XGpioPs *InstancePtr, u32 Pin)
{
u8 Bank;
u8 PinNumber;
u32 IntrReg;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
/* Clear the specified pending interrupts. */
IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTSTS_OFFSET);
IntrReg &= ((u32)1 << PinNumber);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTSTS_OFFSET, IntrReg);
}
/****************************************************************************/
/**
*
* This function is used for setting the Interrupt Type, Interrupt Polarity and
* Interrupt On Any for the specified GPIO Bank pins.
*
* @param InstancePtr is a pointer to an XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param IntrType is the 32 bit mask of the interrupt type.
* 0 means Level Sensitive and 1 means Edge Sensitive.
* @param IntrPolarity is the 32 bit mask of the interrupt polarity.
* 0 means Active Low or Falling Edge and 1 means Active High or
* Rising Edge.
* @param IntrOnAny is the 32 bit mask of the interrupt trigger for
* edge triggered interrupts. 0 means trigger on single edge using
* the configured interrupt polarity and 1 means trigger on both
* edges.
*
* @return None.
*
* @note This function is used for setting the interrupt related
* properties of all the pins in the specified bank. The previous
* state of the pins is not maintained.
* To change the Interrupt properties of a single GPIO pin, use the
* function XGpioPs_SetPinIntrType().
*
*****************************************************************************/
void XGpioPs_SetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 IntrType,
u32 IntrPolarity, u32 IntrOnAny)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTTYPE_OFFSET, IntrType);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTPOL_OFFSET, IntrPolarity);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTANY_OFFSET, IntrOnAny);
}
/****************************************************************************/
/**
*
* This function is used for getting the Interrupt Type, Interrupt Polarity and
* Interrupt On Any for the specified GPIO Bank pins.
*
* @param InstancePtr is a pointer to an XGpioPs instance.
* @param Bank is the bank number of the GPIO to operate on.
* Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param IntrType returns the 32 bit mask of the interrupt type.
* 0 means Level Sensitive and 1 means Edge Sensitive.
* @param IntrPolarity returns the 32 bit mask of the interrupt
* polarity. 0 means Active Low or Falling Edge and 1 means
* Active High or Rising Edge.
* @param IntrOnAny returns the 32 bit mask of the interrupt trigger for
* edge triggered interrupts. 0 means trigger on single edge using
* the configured interrupt polarity and 1 means trigger on both
* edges.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_GetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 *IntrType,
u32 *IntrPolarity, u32 *IntrOnAny)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
*IntrType = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTTYPE_OFFSET);
*IntrPolarity = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTPOL_OFFSET);
*IntrOnAny = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTANY_OFFSET);
}
/****************************************************************************/
/**
*
* This function is used for setting the IRQ Type of a single GPIO pin.
*
* @param InstancePtr is a pointer to an XGpioPs instance.
* @param Pin is the pin number whose IRQ type is to be set.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
* @param IrqType is the IRQ type for GPIO Pin. Use XGPIOPS_IRQ_TYPE_*
* defined in xgpiops.h to specify the IRQ type.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void XGpioPs_SetIntrTypePin(XGpioPs *InstancePtr, u32 Pin, u8 IrqType)
{
u32 IntrTypeReg;
u32 IntrPolReg;
u32 IntrOnAnyReg;
u8 Bank;
u8 PinNumber;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertVoid(Pin < InstancePtr->MaxPinNum);
Xil_AssertVoid(IrqType <= XGPIOPS_IRQ_TYPE_LEVEL_LOW);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
IntrTypeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTTYPE_OFFSET);
IntrPolReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTPOL_OFFSET);
IntrOnAnyReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTANY_OFFSET);
switch (IrqType) {
case XGPIOPS_IRQ_TYPE_EDGE_RISING:
IntrTypeReg |= ((u32)1 << (u32)PinNumber);
IntrPolReg |= ((u32)1 << (u32)PinNumber);
IntrOnAnyReg &= ~((u32)1 << (u32)PinNumber);
break;
case XGPIOPS_IRQ_TYPE_EDGE_FALLING:
IntrTypeReg |= ((u32)1 << (u32)PinNumber);
IntrPolReg &= ~((u32)1 << (u32)PinNumber);
IntrOnAnyReg &= ~((u32)1 << (u32)PinNumber);
break;
case XGPIOPS_IRQ_TYPE_EDGE_BOTH:
IntrTypeReg |= ((u32)1 << (u32)PinNumber);
IntrOnAnyReg |= ((u32)1 << (u32)PinNumber);
break;
case XGPIOPS_IRQ_TYPE_LEVEL_HIGH:
IntrTypeReg &= ~((u32)1 << (u32)PinNumber);
IntrPolReg |= ((u32)1 << (u32)PinNumber);
break;
case XGPIOPS_IRQ_TYPE_LEVEL_LOW:
IntrTypeReg &= ~((u32)1 << (u32)PinNumber);
IntrPolReg &= ~((u32)1 << (u32)PinNumber);
break;
default:
/**< Default statement is added for MISRA C compliance. */
break;
}
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTTYPE_OFFSET, IntrTypeReg);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTPOL_OFFSET, IntrPolReg);
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTANY_OFFSET, IntrOnAnyReg);
}
/****************************************************************************/
/**
*
* This function returns the IRQ Type of a given GPIO pin.
*
* @param InstancePtr is a pointer to an XGpioPs instance.
* @param Pin is the pin number whose IRQ type is to be obtained.
* Valid values are 0-117 in Zynq and 0-173 in Zynq Ultrascale+ MP.
*
* @return None.
*
* @note Use XGPIOPS_IRQ_TYPE_* defined in xgpiops.h for the IRQ type
* returned by this function.
*
*****************************************************************************/
u8 XGpioPs_GetIntrTypePin(XGpioPs *InstancePtr, u32 Pin)
{
u32 IntrType;
u32 IntrPol;
u32 IntrOnAny;
u8 Bank;
u8 PinNumber;
u8 IrqType;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Pin < InstancePtr->MaxPinNum);
/* Get the Bank number and Pin number within the bank. */
XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
IntrType = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTTYPE_OFFSET) & ((u32)1 << PinNumber);
if (IntrType == ((u32)1 << PinNumber)) {
IntrOnAny = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTANY_OFFSET) & ((u32)1 << PinNumber);
IntrPol = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTPOL_OFFSET) & ((u32)1 << PinNumber);
if (IntrOnAny == ((u32)1 << PinNumber)) {
IrqType = XGPIOPS_IRQ_TYPE_EDGE_BOTH;
} else if (IntrPol == ((u32)1 << PinNumber)) {
IrqType = XGPIOPS_IRQ_TYPE_EDGE_RISING;
} else {
IrqType = XGPIOPS_IRQ_TYPE_EDGE_FALLING;
}
} else {
IntrPol = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTPOL_OFFSET) & ((u32)1 << PinNumber);
if (IntrPol == ((u32)1 << PinNumber)) {
IrqType = XGPIOPS_IRQ_TYPE_LEVEL_HIGH;
} else {
IrqType = XGPIOPS_IRQ_TYPE_LEVEL_LOW;
}
}
return IrqType;
}
/*****************************************************************************/
/**
*
* This function sets the status callback function. The callback function is
* called by the XGpioPs_IntrHandler when an interrupt occurs.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param CallBackRef is the upper layer callback reference passed back
* when the callback function is invoked.
* @param FuncPtr is the pointer to the callback function.
*
*
* @return None.
*
* @note The handler is called within interrupt context, so it should do
* its work quickly and queue potentially time-consuming work to a
* task-level thread.
*
******************************************************************************/
void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef,
XGpioPs_Handler FuncPointer)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FuncPointer != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
InstancePtr->Handler = FuncPointer;
InstancePtr->CallBackRef = CallBackRef;
}
/*****************************************************************************/
/**
*
* This function is the interrupt handler for GPIO interrupts.It checks the
* interrupt status registers of all the banks to determine the actual bank in
* which an interrupt has been triggered. It then calls the upper layer callback
* handler set by the function XGpioPs_SetBankHandler(). The callback is called
* when an interrupt
*
* @param InstancePtr is a pointer to the XGpioPs instance.
*
* @return None.
*
* @note This function does not save and restore the processor context
* such that the user must provide this processing.
*
******************************************************************************/
void XGpioPs_IntrHandler(XGpioPs *InstancePtr)
{
u8 Bank;
u32 IntrStatus;
u32 IntrEnabled;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
for (Bank = 0U; Bank < InstancePtr->MaxBanks; Bank++) {
IntrStatus = XGpioPs_IntrGetStatus(InstancePtr, Bank);
if (IntrStatus != (u32)0) {
IntrEnabled = XGpioPs_IntrGetEnabled(InstancePtr,
Bank);
XGpioPs_IntrClear((XGpioPs *)InstancePtr, Bank,
(IntrStatus & IntrEnabled));
InstancePtr->Handler(InstancePtr->
CallBackRef, Bank,
(IntrStatus & IntrEnabled));
}
}
}
/*****************************************************************************/
/**
*
* This is a stub for the status callback. The stub is here in case the upper
* layers do not set the handler.
*
* @param CallBackRef is a pointer to the upper layer callback reference
* @param Bank is the GPIO Bank in which an interrupt occurred.
* @param Status is the Interrupt status of the GPIO bank.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void StubHandler(void *CallBackRef, u32 Bank, u32 Status)
{
(void*) CallBackRef;
(void) Bank;
(void) Status;
Xil_AssertVoidAlways();
}
/** @} */

View file

@ -0,0 +1,133 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xgpiops_selftest.c
* @addtogroup gpiops_v3_1
* @{
*
* This file contains a diagnostic self-test function for the XGpioPs driver.
*
* Read xgpiops.h file for more information.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sv 01/18/10 First Release
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xstatus.h"
#include "xgpiops.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
/*****************************************************************************/
/**
*
* This function runs a self-test on the GPIO driver/device. This function
* does a register read/write test on some of the Interrupt Registers.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
*
* @return
* - XST_SUCCESS if the self-test passed.
* - XST_FAILURE otherwise.
*
*
******************************************************************************/
s32 XGpioPs_SelfTest(XGpioPs *InstancePtr)
{
s32 Status = XST_SUCCESS;
u32 IntrEnabled;
u32 CurrentIntrType = 0U;
u32 CurrentIntrPolarity = 0U;
u32 CurrentIntrOnAny = 0U;
u32 IntrType = 0U;
u32 IntrPolarity = 0U;
u32 IntrOnAny = 0U;
u32 IntrTestValue = 0x22U;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/* Disable the Interrupts for Bank 0 . */
IntrEnabled = XGpioPs_IntrGetEnabled(InstancePtr, XGPIOPS_BANK0);
XGpioPs_IntrDisable(InstancePtr, XGPIOPS_BANK0, IntrEnabled);
/*
* Get the Current Interrupt properties for Bank 0.
* Set them to a known value, read it back and compare.
*/
XGpioPs_GetIntrType(InstancePtr, XGPIOPS_BANK0, &CurrentIntrType,
&CurrentIntrPolarity, &CurrentIntrOnAny);
XGpioPs_SetIntrType(InstancePtr, XGPIOPS_BANK0, IntrTestValue,
IntrTestValue, IntrTestValue);
XGpioPs_GetIntrType(InstancePtr, XGPIOPS_BANK0, &IntrType,
&IntrPolarity, &IntrOnAny);
if ((IntrType != IntrTestValue) && (IntrPolarity != IntrTestValue) &&
(IntrOnAny != IntrTestValue)) {
Status = XST_FAILURE;
}
/*
* Restore the contents of all the interrupt registers modified in this
* test.
*/
XGpioPs_SetIntrType(InstancePtr, XGPIOPS_BANK0, CurrentIntrType,
CurrentIntrPolarity, CurrentIntrOnAny);
XGpioPs_IntrEnable(InstancePtr, XGPIOPS_BANK0, IntrEnabled);
return Status;
}
/** @} */

View file

@ -0,0 +1,101 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xgpiops_sinit.c
* @addtogroup gpiops_v3_1
* @{
*
* This file contains the implementation of the XGpioPs driver's static
* initialization functionality.
*
* @note None.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sv 01/15/10 First Release
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xgpiops.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
extern XGpioPs_Config XGpioPs_ConfigTable[XPAR_XGPIOPS_NUM_INSTANCES];
/*****************************************************************************/
/**
*
* This function looks for the device configuration based on the unique device
* ID. The table XGpioPs_ConfigTable[] contains the configuration information
* for each device in the system.
*
* @param DeviceId is the unique device ID of the device being looked up.
*
* @return A pointer to the configuration table entry corresponding to the
* given device ID, or NULL if no match is found.
*
* @note None.
*
******************************************************************************/
XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId)
{
XGpioPs_Config *CfgPtr = NULL;
u32 Index;
for (Index = 0U; Index < (u32)XPAR_XGPIOPS_NUM_INSTANCES; Index++) {
if (XGpioPs_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XGpioPs_ConfigTable[Index];
break;
}
}
return (XGpioPs_Config *)CfgPtr;
}
/** @} */

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner xiicps_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling iicps"
xiicps_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: xiicps_includes
xiicps_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

View file

@ -0,0 +1,332 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiicps.c
* @addtogroup iicps_v3_0
* @{
*
* Contains implementation of required functions for the XIicPs driver.
* See xiicps.h for detailed description of the device and driver.
*
* <pre> MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------------
* 1.00a drg/jz 01/30/10 First release
* 1.00a sdm 09/21/11 Updated the InstancePtr->Options in the
* XIicPs_CfgInitialize by calling XIicPs_GetOptions.
* 2.1 hk 04/25/14 Explicitly reset CR and clear FIFO in Abort function
* and state the same in the comments. CR# 784254.
* Fix for CR# 761060 - provision for repeated start.
* 2.3 sk 10/07/14 Repeated start feature removed.
* 3.0 sk 11/03/14 Modified TimeOut Register value to 0xFF
* in XIicPs_Reset.
* 12/06/14 Implemented Repeated start feature.
* 01/31/15 Modified the code according to MISRAC 2012 Compliant.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiicps.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static void StubHandler(void *CallBackRef, u32 StatusEvent);
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Initializes a specific XIicPs instance such that the driver is ready to use.
*
* The state of the device after initialization is:
* - Device is disabled
* - Slave mode
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param ConfigPtr is a reference to a structure containing information
* about a specific IIC device. This function initializes an
* InstancePtr object for a specific device specified by the
* contents of Config.
* @param EffectiveAddr is the device base address in the virtual memory
* address space. The caller is responsible for keeping the address
* mapping from EffectiveAddr to the device physical base address
* unchanged once this function is invoked. Unexpected errors may
* occur if the address mapping changes after this function is
* called. If address translation is not used, use
* ConfigPtr->BaseAddress for this parameter, passing the physical
* address instead.
*
* @return The return value is XST_SUCCESS if successful.
*
* @note None.
*
******************************************************************************/
s32 XIicPs_CfgInitialize(XIicPs *InstancePtr, XIicPs_Config *ConfigPtr,
u32 EffectiveAddr)
{
/*
* Assert validates the input arguments.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(ConfigPtr != NULL);
/*
* Set some default values.
*/
InstancePtr->Config.DeviceId = ConfigPtr->DeviceId;
InstancePtr->Config.BaseAddress = EffectiveAddr;
InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz;
InstancePtr->StatusHandler = StubHandler;
InstancePtr->CallBackRef = NULL;
InstancePtr->IsReady = (u32)XIL_COMPONENT_IS_READY;
/*
* Reset the IIC device to get it into its initial state. It is expected
* that device configuration will take place after this initialization
* is done, but before the device is started.
*/
XIicPs_Reset(InstancePtr);
/*
* Keep a copy of what options this instance has.
*/
InstancePtr->Options = XIicPs_GetOptions(InstancePtr);
/* Initialize repeated start flag to 0 */
InstancePtr->IsRepeatedStart = 0;
return (s32)XST_SUCCESS;
}
/*****************************************************************************/
/**
* Check whether the I2C bus is busy
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return
* - TRUE if the bus is busy.
* - FALSE if the bus is not busy.
*
* @note None.
*
******************************************************************************/
s32 XIicPs_BusIsBusy(XIicPs *InstancePtr)
{
u32 StatusReg;
s32 Status;
StatusReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_SR_OFFSET);
if ((StatusReg & XIICPS_SR_BA_MASK) != 0x0U) {
Status = (s32)TRUE;
}else {
Status = (s32)FALSE;
}
return Status;
}
/*****************************************************************************/
/**
*
* This is a stub for the status callback. The stub is here in case the upper
* layers forget to set the handler.
*
* @param CallBackRef is a pointer to the upper layer callback reference.
* @param StatusEvent is the event that just occurred.
* @param ByteCount is the number of bytes transferred up until the event
* occurred.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void StubHandler(void *CallBackRef, u32 StatusEvent)
{
(void) ((void *)CallBackRef);
(void) StatusEvent;
Xil_AssertVoidAlways();
}
/*****************************************************************************/
/**
*
* Aborts a transfer in progress by resetting the FIFOs. The byte counts are
* cleared.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XIicPs_Abort(XIicPs *InstancePtr)
{
u32 IntrMaskReg;
u32 IntrStatusReg;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
/*
* Enter a critical section, so disable the interrupts while we clear
* the FIFO and the status register.
*/
IntrMaskReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_IMR_OFFSET);
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
XIICPS_IDR_OFFSET, XIICPS_IXR_ALL_INTR_MASK);
/*
* Reset the settings in config register and clear the FIFOs.
*/
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_CR_OFFSET,
XIICPS_CR_RESET_VALUE | XIICPS_CR_CLR_FIFO_MASK);
/*
* Read, then write the interrupt status to make sure there are no
* pending interrupts.
*/
IntrStatusReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_ISR_OFFSET);
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
XIICPS_ISR_OFFSET, IntrStatusReg);
/*
* Restore the interrupt state.
*/
IntrMaskReg = XIICPS_IXR_ALL_INTR_MASK & (~IntrMaskReg);
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
XIICPS_IER_OFFSET, IntrMaskReg);
}
/*****************************************************************************/
/**
*
* Resets the IIC device. Reset must only be called after the driver has been
* initialized. The configuration of the device after reset is the same as its
* configuration after initialization. Any data transfer that is in progress is
* aborted.
*
* The upper layer software is responsible for re-configuring (if necessary)
* and reenabling interrupts for the IIC device after the reset.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XIicPs_Reset(XIicPs *InstancePtr)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
/*
* Abort any transfer that is in progress.
*/
XIicPs_Abort(InstancePtr);
/*
* Reset any values so the software state matches the hardware device.
*/
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_CR_OFFSET,
XIICPS_CR_RESET_VALUE);
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
XIICPS_TIME_OUT_OFFSET, XIICPS_TO_RESET_VALUE);
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_IDR_OFFSET,
XIICPS_IXR_ALL_INTR_MASK);
}
/*****************************************************************************/
/**
* Put more data into the transmit FIFO, number of bytes is ether expected
* number of bytes for this transfer or available space in FIFO, which ever
* is less.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return Number of bytes left for this instance.
*
* @note This is function is shared by master and slave.
*
******************************************************************************/
s32 TransmitFifoFill(XIicPs *InstancePtr)
{
u8 AvailBytes;
s32 LoopCnt;
s32 NumBytesToSend;
/*
* Determine number of bytes to write to FIFO.
*/
AvailBytes = (u8)XIICPS_FIFO_DEPTH -
(u8)XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_TRANS_SIZE_OFFSET);
if (InstancePtr->SendByteCount > (s32)AvailBytes) {
NumBytesToSend = (s32)AvailBytes;
} else {
NumBytesToSend = InstancePtr->SendByteCount;
}
/*
* Fill FIFO with amount determined above.
*/
for (LoopCnt = 0; LoopCnt < NumBytesToSend; LoopCnt++) {
XIicPs_SendByte(InstancePtr);
}
return InstancePtr->SendByteCount;
}
/** @} */

View file

@ -0,0 +1,420 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiicps.h
* @addtogroup iicps_v3_0
* @{
* @details
*
* This is an implementation of IIC driver in the PS block. The device can
* be either a master or a slave on the IIC bus. This implementation supports
* both interrupt mode transfer and polled mode transfer. Only 7-bit address
* is used in the driver, although the hardware also supports 10-bit address.
*
* IIC is a 2-wire serial interface. The master controls the clock, so it can
* regulate when it wants to send or receive data. The slave is under control of
* the master, it must respond quickly since it has no control of the clock and
* must send/receive data as fast or as slow as the master does.
*
* The higher level software must implement a higher layer protocol to inform
* the slave what to send to the master.
*
* <b>Initialization & Configuration</b>
*
* The XIicPs_Config structure is used by the driver to configure itself. This
* configuration structure is typically created by the tool-chain based on HW
* build properties.
*
* To support multiple runtime loading and initialization strategies employed by
* various operating systems, the driver instance can be initialized in the
* following way:
*
* - XIicPs_LookupConfig(DeviceId) - Use the device identifier to find
* the static configuration structure defined in xiicps_g.c. This is
* setup by the tools. For some operating systems the config structure
* will be initialized by the software and this call is not needed.
*
* - XIicPs_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a
* configuration structure provided by the caller. If running in a
* system with address translation, the provided virtual memory base
* address replaces the physical address in the configuration
* structure.
*
* <b>Multiple Masters</b>
*
* More than one master can exist, bus arbitration is defined in the IIC
* standard. Lost of arbitration causes arbitration loss interrupt on the device.
*
* <b>Multiple Slaves</b>
*
* Multiple slaves are supported by selecting them with unique addresses. It is
* up to the system designer to be sure all devices on the IIC bus have
* unique addresses.
*
* <b>Addressing</b>
*
* The IIC hardware can use 7 or 10 bit addresses. The driver provides the
* ability to control which address size is sent in messages as a master to a
* slave device.
*
* <b>FIFO Size </b>
* The hardware FIFO is 32 bytes deep. The user must know the limitations of
* other IIC devices on the bus. Some are only able to receive a limited number
* of bytes in a single transfer.
*
* <b>Data Rates</b>
*
* The data rate is set by values in the control register. The formula for
* determining the correct register values is:
* Fscl = Fpclk/(22 x (divisor_a+1) x (divisor_b+1))
*
* When the device is configured as a slave, the slck setting controls the
* sample rate and so must be set to be at least as fast as the fastest scl
* expected to be seen in the system.
*
* <b>Polled Mode Operation</b>
*
* This driver supports polled mode transfers.
*
* <b>Interrupts</b>
*
* The user must connect the interrupt handler of the driver,
* XIicPs_InterruptHandler to an interrupt system such that it will be called
* when an interrupt occurs. This function does not save and restore the
* processor context such that the user must provide this processing.
*
* The driver handles the following interrupts:
* - Transfer complete
* - More Data
* - Transfer not Acknowledged
* - Transfer Time out
* - Monitored slave ready - master mode only
* - Receive Overflow
* - Transmit FIFO overflow
* - Receive FIFO underflow
* - Arbitration lost
*
* <b>Bus Busy</b>
*
* Bus busy is checked before the setup of a master mode device, to avoid
* unnecessary arbitration loss interrupt.
*
* <b>RTOS Independence</b>
*
* This driver is intended to be RTOS and processor independent. It works with
* physical addresses only. Any needs for dynamic memory management, threads or
* thread mutual exclusion, virtual memory, or cache control must be satisfied by
* the layer above this driver.
*
*<b>Repeated Start</b>
*
* The I2C controller does not indicate completion of a receive transfer if HOLD
* bit is set. Due to this errata, repeated start cannot be used if a receive
* transfer is followed by any other transfer.
*
* <pre> MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- -----------------------------------------------
* 1.00a drg/jz 01/30/08 First release
* 1.00a sdm 09/21/11 Fixed an issue in the XIicPs_SetOptions and
* XIicPs_ClearOptions where the InstancePtr->Options
* was not updated correctly.
* Updated the InstancePtr->Options in the
* XIicPs_CfgInitialize by calling XIicPs_GetOptions.
* Updated the XIicPs_SetupMaster to not check for
* Bus Busy condition when the Hold Bit is set.
* Removed some unused variables.
* 1.01a sg 03/30/12 Fixed an issue in XIicPs_MasterSendPolled where a
* check for transfer completion is added, which indicates
* the completion of current transfer.
* 1.02a sg 08/29/12 Updated the logic to arrive at the best divisors
* to achieve I2C clock with minimum error for
* CR #674195
* 1.03a hk 05/04/13 Initialized BestDivA and BestDivB to 0.
* This is fix for CR#704398 to remove warning.
* 2.0 hk 03/07/14 Added check for error status in the while loop that
* checks for completion.
* (XIicPs_MasterSendPolled function). CR# 762244, 764875.
* Limited frequency set when 100KHz or 400KHz is
* selected. This is a hardware limitation. CR#779290.
* 2.1 hk 04/24/14 Fix for CR# 789821 to handle >14 byte transfers.
* Explicitly reset CR and clear FIFO in Abort function
* and state the same in the comments. CR# 784254.
* Fix for CR# 761060 - provision for repeated start.
* 2.2 hk 08/23/14 Slave monitor mode changes - clear FIFO, enable
* read mode and clear transfer size register.
* Disable NACK to avoid interrupts on each retry.
* 2.3 sk 10/07/14 Repeated start feature deleted.
* 3.0 sk 11/03/14 Modified TimeOut Register value to 0xFF
* in XIicPs_Reset.
* 12/06/14 Implemented Repeated start feature.
* 01/31/15 Modified the code according to MISRAC 2012 Compliant.
* 02/18/15 Implemented larger data transfer using repeated start
* in Zynq UltraScale MP.
*
* </pre>
*
******************************************************************************/
#ifndef XIICPS_H /* prevent circular inclusions */
#define XIICPS_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xiicps_hw.h"
#include "xplatform_info.h"
/************************** Constant Definitions *****************************/
/** @name Configuration options
*
* The following options may be specified or retrieved for the device and
* enable/disable additional features of the IIC. Each of the options
* are bit fields, so more than one may be specified.
*
* @{
*/
#define XIICPS_7_BIT_ADDR_OPTION 0x01U /**< 7-bit address mode */
#define XIICPS_10_BIT_ADDR_OPTION 0x02U /**< 10-bit address mode */
#define XIICPS_SLAVE_MON_OPTION 0x04U /**< Slave monitor mode */
#define XIICPS_REP_START_OPTION 0x08U /**< Repeated Start */
/*@}*/
/** @name Callback events
*
* These constants specify the handler events that are passed to an application
* event handler from the driver. These constants are bit masks such that
* more than one event can be passed to the handler.
*
* @{
*/
#define XIICPS_EVENT_COMPLETE_SEND 0x0001U /**< Transmit Complete Event*/
#define XIICPS_EVENT_COMPLETE_RECV 0x0002U /**< Receive Complete Event*/
#define XIICPS_EVENT_TIME_OUT 0x0004U /**< Transfer timed out */
#define XIICPS_EVENT_ERROR 0x0008U /**< Receive error */
#define XIICPS_EVENT_ARB_LOST 0x0010U /**< Arbitration lost */
#define XIICPS_EVENT_NACK 0x0020U /**< NACK Received */
#define XIICPS_EVENT_SLAVE_RDY 0x0040U /**< Slave ready */
#define XIICPS_EVENT_RX_OVR 0x0080U /**< RX overflow */
#define XIICPS_EVENT_TX_OVR 0x0100U /**< TX overflow */
#define XIICPS_EVENT_RX_UNF 0x0200U /**< RX underflow */
/*@}*/
/** @name Role constants
*
* These constants are used to pass into the device setup routines to
* set up the device according to transfer direction.
*/
#define SENDING_ROLE 1 /**< Transfer direction is sending */
#define RECVING_ROLE 0 /**< Transfer direction is receiving */
/* Maximum transfer size */
#define XIICPS_MAX_TRANSFER_SIZE (u32)(255U - 3U)
/**************************** Type Definitions *******************************/
/**
* The handler data type allows the user to define a callback function to
* respond to interrupt events in the system. This function is executed
* in interrupt context, so amount of processing should be minimized.
*
* @param CallBackRef is the callback reference passed in by the upper
* layer when setting the callback functions, and passed back to
* the upper layer when the callback is invoked. Its type is
* not important to the driver, so it is a void pointer.
* @param StatusEvent indicates one or more status events that occurred.
*/
typedef void (*XIicPs_IntrHandler) (void *CallBackRef, u32 StatusEvent);
/**
* This typedef contains configuration information for the device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddress; /**< Base address of the device */
u32 InputClockHz; /**< Input clock frequency */
} XIicPs_Config;
/**
* The XIicPs driver instance data. The user is required to allocate a
* variable of this type for each IIC device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XIicPs_Config Config; /* Configuration structure */
u32 IsReady; /* Device is initialized and ready */
u32 Options; /* Options set in the device */
u8 *SendBufferPtr; /* Pointer to send buffer */
u8 *RecvBufferPtr; /* Pointer to recv buffer */
s32 SendByteCount; /* Number of bytes still expected to send */
s32 RecvByteCount; /* Number of bytes still expected to receive */
s32 CurrByteCount; /* No. of bytes expected in current transfer */
s32 UpdateTxSize; /* If tx size register has to be updated */
s32 IsSend; /* Whether master is sending or receiving */
s32 IsRepeatedStart; /* Indicates if user set repeated start */
XIicPs_IntrHandler StatusHandler; /* Event handler function */
void *CallBackRef; /* Callback reference for event handler */
} XIicPs;
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/*
*
* Place one byte into the transmit FIFO.
*
* @param InstancePtr is the instance of IIC
*
* @return None.
*
* @note C-Style signature:
* void XIicPs_SendByte(XIicPs *InstancePtr)
*
*****************************************************************************/
#define XIicPs_SendByte(InstancePtr) \
{ \
u8 Data; \
Data = *((InstancePtr)->SendBufferPtr); \
XIicPs_Out32((InstancePtr)->Config.BaseAddress \
+ (u32)(XIICPS_DATA_OFFSET), \
(u32)(Data)); \
(InstancePtr)->SendBufferPtr += 1; \
(InstancePtr)->SendByteCount -= 1;\
}
/****************************************************************************/
/*
*
* Receive one byte from FIFO.
*
* @param InstancePtr is the instance of IIC
*
* @return None.
*
* @note C-Style signature:
* u8 XIicPs_RecvByte(XIicPs *InstancePtr)
*
*****************************************************************************/
#define XIicPs_RecvByte(InstancePtr) \
{ \
u8 *Data, Value; \
Value = (u8)(XIicPs_In32((InstancePtr)->Config.BaseAddress \
+ (u32)XIICPS_DATA_OFFSET)); \
Data = &Value; \
*(InstancePtr)->RecvBufferPtr = *Data; \
(InstancePtr)->RecvBufferPtr += 1; \
(InstancePtr)->RecvByteCount --; \
}
/************************** Function Prototypes ******************************/
/*
* Function for configuration lookup, in xiicps_sinit.c
*/
XIicPs_Config *XIicPs_LookupConfig(u16 DeviceId);
/*
* Functions for general setup, in xiicps.c
*/
s32 XIicPs_CfgInitialize(XIicPs *InstancePtr, XIicPs_Config * ConfigPtr,
u32 EffectiveAddr);
void XIicPs_Abort(XIicPs *InstancePtr);
void XIicPs_Reset(XIicPs *InstancePtr);
s32 XIicPs_BusIsBusy(XIicPs *InstancePtr);
s32 TransmitFifoFill(XIicPs *InstancePtr);
/*
* Functions for interrupts, in xiicps_intr.c
*/
void XIicPs_SetStatusHandler(XIicPs *InstancePtr, void *CallBackRef,
XIicPs_IntrHandler FunctionPtr);
/*
* Functions for device as master, in xiicps_master.c
*/
void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
u16 SlaveAddr);
void XIicPs_MasterRecv(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
u16 SlaveAddr);
s32 XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
u16 SlaveAddr);
s32 XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
u16 SlaveAddr);
void XIicPs_EnableSlaveMonitor(XIicPs *InstancePtr, u16 SlaveAddr);
void XIicPs_DisableSlaveMonitor(XIicPs *InstancePtr);
void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr);
/*
* Functions for device as slave, in xiicps_slave.c
*/
void XIicPs_SetupSlave(XIicPs *InstancePtr, u16 SlaveAddr);
void XIicPs_SlaveSend(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount);
void XIicPs_SlaveRecv(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount);
s32 XIicPs_SlaveSendPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount);
s32 XIicPs_SlaveRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount);
void XIicPs_SlaveInterruptHandler(XIicPs *InstancePtr);
/*
* Functions for selftest, in xiicps_selftest.c
*/
s32 XIicPs_SelfTest(XIicPs *InstancePtr);
/*
* Functions for setting and getting data rate, in xiicps_options.c
*/
s32 XIicPs_SetOptions(XIicPs *InstancePtr, u32 Options);
s32 XIicPs_ClearOptions(XIicPs *InstancePtr, u32 Options);
u32 XIicPs_GetOptions(XIicPs *InstancePtr);
s32 XIicPs_SetSClk(XIicPs *InstancePtr, u32 FsclHz);
u32 XIicPs_GetSClk(XIicPs *InstancePtr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,61 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the Software), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in
*all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
*(a) running on a Xilinx device, or
*(b) that interact with a Xilinx device through a bus or interconnect.
*
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the Xilinx shall not be used
*in advertising or otherwise to promote the sale, use or other dealings in
*this Software without prior written authorization from Xilinx.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xiicps.h"
/*
* The configuration table for devices
*/
XIicPs_Config XIicPs_ConfigTable[] =
{
{
XPAR_PSU_I2C_0_DEVICE_ID,
XPAR_PSU_I2C_0_BASEADDR,
XPAR_PSU_I2C_0_I2C_CLK_FREQ_HZ
},
{
XPAR_PSU_I2C_1_DEVICE_ID,
XPAR_PSU_I2C_1_BASEADDR,
XPAR_PSU_I2C_1_I2C_CLK_FREQ_HZ
}
};

View file

@ -0,0 +1,111 @@
/******************************************************************************
*
* Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiicps_hw.c
* @addtogroup iicps_v3_0
* @{
*
* Contains implementation of required functions for providing the reset sequence
* to the i2c interface
*
* <pre> MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------------
* 1.04a kpc 11/07/13 First release
* 3.0 sk 11/03/14 Modified TimeOut Register value to 0xFF
* 01/31/15 Modified the code according to MISRAC 2012 Compliant.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiicps_hw.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
* This function perform the reset sequence to the given I2c interface by
* configuring the appropriate control bits in the I2c specifc registers
* the i2cps reset squence involves the following steps
* Disable all the interuupts
* Clear the status
* Clear FIFO's and disable hold bit
* Clear the line status
* Update relevant config registers with reset values
*
* @param BaseAddress of the interface
*
* @return N/A
*
* @note
* This function will not modify the slcr registers that are relavant for
* I2c controller
******************************************************************************/
void XIicPs_ResetHw(u32 BaseAddress)
{
u32 RegVal;
/* Disable all the interrupts */
XIicPs_WriteReg(BaseAddress, XIICPS_IDR_OFFSET, XIICPS_IXR_ALL_INTR_MASK);
/* Clear the interrupt status */
RegVal = XIicPs_ReadReg(BaseAddress,XIICPS_ISR_OFFSET);
XIicPs_WriteReg(BaseAddress, XIICPS_ISR_OFFSET, RegVal);
/* Clear the hold bit,master enable bit and ack bit */
RegVal = XIicPs_ReadReg(BaseAddress,XIICPS_CR_OFFSET);
RegVal &= ~(XIICPS_CR_HOLD_MASK|XIICPS_CR_MS_MASK|XIICPS_CR_ACKEN_MASK);
/* Clear the fifos */
RegVal |= XIICPS_CR_CLR_FIFO_MASK;
XIicPs_WriteReg(BaseAddress, XIICPS_CR_OFFSET, RegVal);
/* Clear the timeout register */
XIicPs_WriteReg(BaseAddress, XIICPS_TIME_OUT_OFFSET, XIICPS_TO_RESET_VALUE);
/* Clear the transfer size register */
XIicPs_WriteReg(BaseAddress, XIICPS_TRANS_SIZE_OFFSET, 0x0U);
/* Clear the status register */
RegVal = XIicPs_ReadReg(BaseAddress,XIICPS_SR_OFFSET);
XIicPs_WriteReg(BaseAddress, XIICPS_SR_OFFSET, RegVal);
/* Update the configuraqtion register with reset value */
XIicPs_WriteReg(BaseAddress, XIICPS_CR_OFFSET, 0x0U);
}
/** @} */

View file

@ -0,0 +1,383 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiicps_hw.h
* @addtogroup iicps_v3_0
* @{
*
* This header file contains the hardware definition for an IIC device.
* It includes register definitions and interface functions to read/write
* the registers.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- -----------------------------------------------
* 1.00a drg/jz 01/30/10 First release
* 1.04a kpc 11/07/13 Added function prototype.
* 3.0 sk 11/03/14 Modified the TimeOut Register value to 0xFF
* 01/31/15 Modified the code according to MISRAC 2012 Compliant.
* </pre>
*
******************************************************************************/
#ifndef XIICPS_HW_H /* prevent circular inclusions */
#define XIICPS_HW_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/** @name Register Map
*
* Register offsets for the IIC.
* @{
*/
#define XIICPS_CR_OFFSET 0x00U /**< 32-bit Control */
#define XIICPS_SR_OFFSET 0x04U /**< Status */
#define XIICPS_ADDR_OFFSET 0x08U /**< IIC Address */
#define XIICPS_DATA_OFFSET 0x0CU /**< IIC FIFO Data */
#define XIICPS_ISR_OFFSET 0x10U /**< Interrupt Status */
#define XIICPS_TRANS_SIZE_OFFSET 0x14U /**< Transfer Size */
#define XIICPS_SLV_PAUSE_OFFSET 0x18U /**< Slave monitor pause */
#define XIICPS_TIME_OUT_OFFSET 0x1CU /**< Time Out */
#define XIICPS_IMR_OFFSET 0x20U /**< Interrupt Enabled Mask */
#define XIICPS_IER_OFFSET 0x24U /**< Interrupt Enable */
#define XIICPS_IDR_OFFSET 0x28U /**< Interrupt Disable */
/* @} */
/** @name Control Register
*
* This register contains various control bits that
* affects the operation of the IIC controller. Read/Write.
* @{
*/
#define XIICPS_CR_DIV_A_MASK 0x0000C000U /**< Clock Divisor A */
#define XIICPS_CR_DIV_A_SHIFT 14U /**< Clock Divisor A shift */
#define XIICPS_DIV_A_MAX 4U /**< Maximum value of Divisor A */
#define XIICPS_CR_DIV_B_MASK 0x00003F00U /**< Clock Divisor B */
#define XIICPS_CR_DIV_B_SHIFT 8U /**< Clock Divisor B shift */
#define XIICPS_CR_CLR_FIFO_MASK 0x00000040U /**< Clear FIFO, auto clears*/
#define XIICPS_CR_SLVMON_MASK 0x00000020U /**< Slave monitor mode */
#define XIICPS_CR_HOLD_MASK 0x00000010U /**< Hold bus 1=Hold scl,
0=terminate transfer */
#define XIICPS_CR_ACKEN_MASK 0x00000008U /**< Enable TX of ACK when
Master receiver*/
#define XIICPS_CR_NEA_MASK 0x00000004U /**< Addressing Mode 1=7 bit,
0=10 bit */
#define XIICPS_CR_MS_MASK 0x00000002U /**< Master mode bit 1=Master,
0=Slave */
#define XIICPS_CR_RD_WR_MASK 0x00000001U /**< Read or Write Master
transfer 0=Transmitter,
1=Receiver*/
#define XIICPS_CR_RESET_VALUE 0U /**< Reset value of the Control
register */
/* @} */
/** @name IIC Status Register
*
* This register is used to indicate status of the IIC controller. Read only
* @{
*/
#define XIICPS_SR_BA_MASK 0x00000100U /**< Bus Active Mask */
#define XIICPS_SR_RXOVF_MASK 0x00000080U /**< Receiver Overflow Mask */
#define XIICPS_SR_TXDV_MASK 0x00000040U /**< Transmit Data Valid Mask */
#define XIICPS_SR_RXDV_MASK 0x00000020U /**< Receiver Data Valid Mask */
#define XIICPS_SR_RXRW_MASK 0x00000008U /**< Receive read/write Mask */
/* @} */
/** @name IIC Address Register
*
* Normal addressing mode uses add[6:0]. Extended addressing mode uses add[9:0].
* A write access to this register always initiates a transfer if the IIC is in
* master mode. Read/Write
* @{
*/
#define XIICPS_ADDR_MASK 0x000003FF /**< IIC Address Mask */
/* @} */
/** @name IIC Data Register
*
* When written to, the data register sets data to transmit. When read from, the
* data register reads the last received byte of data. Read/Write
* @{
*/
#define XIICPS_DATA_MASK 0x000000FF /**< IIC Data Mask */
/* @} */
/** @name IIC Interrupt Registers
*
* <b>IIC Interrupt Status Register</b>
*
* This register holds the interrupt status flags for the IIC controller. Some
* of the flags are level triggered
* - i.e. are set as long as the interrupt condition exists. Other flags are
* edge triggered, which means they are set one the interrupt condition occurs
* then remain set until they are cleared by software.
* The interrupts are cleared by writing a one to the interrupt bit position
* in the Interrupt Status Register. Read/Write.
*
* <b>IIC Interrupt Enable Register</b>
*
* This register is used to enable interrupt sources for the IIC controller.
* Writing a '1' to a bit in this register clears the corresponding bit in the
* IIC Interrupt Mask register. Write only.
*
* <b>IIC Interrupt Disable Register </b>
*
* This register is used to disable interrupt sources for the IIC controller.
* Writing a '1' to a bit in this register sets the corresponding bit in the
* IIC Interrupt Mask register. Write only.
*
* <b>IIC Interrupt Mask Register</b>
*
* This register shows the enabled/disabled status of each IIC controller
* interrupt source. A bit set to 1 will ignore the corresponding interrupt in
* the status register. A bit set to 0 means the interrupt is enabled.
* All mask bits are set and all interrupts are disabled after reset. Read only.
*
* All four registers have the same bit definitions. They are only defined once
* for each of the Interrupt Enable Register, Interrupt Disable Register,
* Interrupt Mask Register, and Interrupt Status Register
* @{
*/
#define XIICPS_IXR_ARB_LOST_MASK 0x00000200U /**< Arbitration Lost Interrupt
mask */
#define XIICPS_IXR_RX_UNF_MASK 0x00000080U /**< FIFO Recieve Underflow
Interrupt mask */
#define XIICPS_IXR_TX_OVR_MASK 0x00000040U /**< Transmit Overflow
Interrupt mask */
#define XIICPS_IXR_RX_OVR_MASK 0x00000020U /**< Receive Overflow Interrupt
mask */
#define XIICPS_IXR_SLV_RDY_MASK 0x00000010U /**< Monitored Slave Ready
Interrupt mask */
#define XIICPS_IXR_TO_MASK 0x00000008U /**< Transfer Time Out
Interrupt mask */
#define XIICPS_IXR_NACK_MASK 0x00000004U /**< NACK Interrupt mask */
#define XIICPS_IXR_DATA_MASK 0x00000002U /**< Data Interrupt mask */
#define XIICPS_IXR_COMP_MASK 0x00000001U /**< Transfer Complete
Interrupt mask */
#define XIICPS_IXR_DEFAULT_MASK 0x000002FFU /**< Default ISR Mask */
#define XIICPS_IXR_ALL_INTR_MASK 0x000002FFU /**< All ISR Mask */
/* @} */
/** @name IIC Transfer Size Register
*
* The register's meaning varies according to the operating mode as follows:
* - Master transmitter mode: number of data bytes still not transmitted minus
* one
* - Master receiver mode: number of data bytes that are still expected to be
* received
* - Slave transmitter mode: number of bytes remaining in the FIFO after the
* master terminates the transfer
* - Slave receiver mode: number of valid data bytes in the FIFO
*
* This register is cleared if CLR_FIFO bit in the control register is set.
* Read/Write
* @{
*/
#define XIICPS_TRANS_SIZE_MASK 0x0000003F /**< IIC Transfer Size Mask */
#define XIICPS_FIFO_DEPTH 16 /**< Number of bytes in the FIFO */
#define XIICPS_DATA_INTR_DEPTH 14 /**< Number of bytes at DATA intr */
/* @} */
/** @name IIC Slave Monitor Pause Register
*
* This register is associated with the slave monitor mode of the I2C interface.
* It is meaningful only when the module is in master mode and bit SLVMON in the
* control register is set.
*
* This register defines the pause interval between consecutive attempts to
* address the slave once a write to an I2C address register is done by the
* host. It represents the number of sclk cycles minus one between two attempts.
*
* The reset value of the register is 0, which results in the master repeatedly
* trying to access the slave immediately after unsuccessful attempt.
* Read/Write
* @{
*/
#define XIICPS_SLV_PAUSE_MASK 0x0000000F /**< Slave monitor pause mask */
/* @} */
/** @name IIC Time Out Register
*
* The value of time out register represents the time out interval in number of
* sclk cycles minus one.
*
* When the accessed slave holds the sclk line low for longer than the time out
* period, thus prohibiting the I2C interface in master mode to complete the
* current transfer, an interrupt is generated and TO interrupt flag is set.
*
* The reset value of the register is 0x1f.
* Read/Write
* @{
*/
#define XIICPS_TIME_OUT_MASK 0x000000FFU /**< IIC Time Out mask */
#define XIICPS_TO_RESET_VALUE 0x000000FFU /**< IIC Time Out reset value */
/* @} */
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define XIicPs_In32 Xil_In32
#define XIicPs_Out32 Xil_Out32
/****************************************************************************/
/**
* Read an IIC register.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset contains the offset from the 1st register of the
* device to select the specific register.
*
* @return The value read from the register.
*
* @note C-Style signature:
* u32 XIicPs_ReadReg(u32 BaseAddress. int RegOffset)
*
******************************************************************************/
#define XIicPs_ReadReg(BaseAddress, RegOffset) \
XIicPs_In32((BaseAddress) + (u32)(RegOffset))
/***************************************************************************/
/**
* Write an IIC register.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset contains the offset from the 1st register of the
* device to select the specific register.
* @param RegisterValue is the value to be written to the register.
*
* @return None.
*
* @note C-Style signature:
* void XIicPs_WriteReg(u32 BaseAddress, int RegOffset, u32 RegisterValue)
*
******************************************************************************/
#define XIicPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \
XIicPs_Out32((BaseAddress) + (u32)(RegOffset), (u32)(RegisterValue))
/***************************************************************************/
/**
* Read the interrupt enable register.
*
* @param BaseAddress contains the base address of the device.
*
* @return Current bit mask that represents currently enabled interrupts.
*
* @note C-Style signature:
* u32 XIicPs_ReadIER(u32 BaseAddress)
*
******************************************************************************/
#define XIicPs_ReadIER(BaseAddress) \
XIicPs_ReadReg((BaseAddress), XIICPS_IER_OFFSET)
/***************************************************************************/
/**
* Write to the interrupt enable register.
*
* @param BaseAddress contains the base address of the device.
*
* @param IntrMask is the interrupts to be enabled.
*
* @return None.
*
* @note C-Style signature:
* void XIicPs_EnabledInterrupts(u32 BaseAddress, u32 IntrMask)
*
******************************************************************************/
#define XIicPs_EnableInterrupts(BaseAddress, IntrMask) \
XIicPs_WriteReg((BaseAddress), XIICPS_IER_OFFSET, (IntrMask))
/***************************************************************************/
/**
* Disable all interrupts.
*
* @param BaseAddress contains the base address of the device.
*
* @return None.
*
* @note C-Style signature:
* void XIicPs_DisableAllInterrupts(u32 BaseAddress)
*
******************************************************************************/
#define XIicPs_DisableAllInterrupts(BaseAddress) \
XIicPs_WriteReg((BaseAddress), XIICPS_IDR_OFFSET, \
XIICPS_IXR_ALL_INTR_MASK)
/***************************************************************************/
/**
* Disable selected interrupts.
*
* @param BaseAddress contains the base address of the device.
*
* @param IntrMask is the interrupts to be disabled.
*
* @return None.
*
* @note C-Style signature:
* void XIicPs_DisableInterrupts(u32 BaseAddress, u32 IntrMask)
*
******************************************************************************/
#define XIicPs_DisableInterrupts(BaseAddress, IntrMask) \
XIicPs_WriteReg((BaseAddress), XIICPS_IDR_OFFSET, \
(IntrMask))
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
/*
* Perform reset operation to the I2c interface
*/
void XIicPs_ResetHw(u32 BaseAddress);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */

View file

@ -0,0 +1,101 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiicps_intr.c
* @addtogroup iicps_v3_0
* @{
*
* Contains functions of the XIicPs driver for interrupt-driven transfers.
* See xiicps.h for a detailed description of the device and driver.
*
* <pre> MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- -----------------------------------------------
* 1.00a drg/jz 01/30/10 First release
* 3.00 sk 01/31/15 Modified the code according to MISRAC 2012 Compliant.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiicps.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************* Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* This function sets the status callback function, the status handler, which the
* driver calls when it encounters conditions that should be reported to the
* higher layer software. The handler executes in an interrupt context, so
* the amount of processing should be minimized
*
* Refer to the xiicps.h file for a list of the Callback events. The events are
* defined to start with XIICPS_EVENT_*.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param CallBackRef is the upper layer callback reference passed back
* when the callback function is invoked.
* @param FunctionPtr is the pointer to the callback function.
*
* @return None.
*
* @note
*
* The handler is called within interrupt context, so it should finish its
* work quickly.
*
******************************************************************************/
void XIicPs_SetStatusHandler(XIicPs *InstancePtr, void *CallBackRef,
XIicPs_IntrHandler FunctionPtr)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(FunctionPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
InstancePtr->StatusHandler = FunctionPtr;
InstancePtr->CallBackRef = CallBackRef;
}
/** @} */

View file

@ -0,0 +1,987 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiicps_master.c
* @addtogroup iicps_v3_0
* @{
*
* Handles master mode transfers.
*
* <pre> MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- ---------------------------------------------
* 1.00a jz 01/30/10 First release
* 1.00a sdm 09/21/11 Updated the XIicPs_SetupMaster to not check for
* Bus Busy condition when the Hold Bit is set.
* 1.01a sg 03/30/12 Fixed an issue in XIicPs_MasterSendPolled where a
* check for transfer completion is added, which indicates
* the completion of current transfer.
* 2.0 hk 03/07/14 Added check for error status in the while loop that
* checks for completion. CR# 762244, 764875.
* 2.1 hk 04/24/14 Fix for CR# 789821 to handle >14 byte transfers.
* Fix for CR# 761060 - provision for repeated start.
* 2.2 hk 08/23/14 Slave monitor mode changes - clear FIFO, enable
* read mode and clear transfer size register.
* Disable NACK to avoid interrupts on each retry.
* 2.3 sk 10/06/14 Fill transmit fifo before address register when sending.
* Replaced XIICPS_DATA_INTR_DEPTH with XIICPS_FIFO_DEPTH.
* Repeated start feature removed.
* 3.0 sk 12/06/14 Implemented Repeated start feature.
* 01/31/15 Modified the code according to MISRAC 2012 Compliant.
* 02/18/15 Implemented larger data transfer using repeated start
* in Zynq UltraScale MP.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiicps.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
s32 TransmitFifoFill(XIicPs *InstancePtr);
static s32 XIicPs_SetupMaster(XIicPs *InstancePtr, s32 Role);
static void MasterSendData(XIicPs *InstancePtr);
/************************* Variable Definitions *****************************/
/*****************************************************************************/
/**
* This function initiates an interrupt-driven send in master mode.
*
* It tries to send the first FIFO-full of data, then lets the interrupt
* handler to handle the rest of the data if there is any.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param MsgPtr is the pointer to the send buffer.
* @param ByteCount is the number of bytes to be sent.
* @param SlaveAddr is the address of the slave we are sending to.
*
* @return None.
*
* @note This send routine is for interrupt-driven transfer only.
*
****************************************************************************/
void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
u16 SlaveAddr)
{
u32 BaseAddr;
/*
* Assert validates the input arguments.
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(MsgPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
BaseAddr = InstancePtr->Config.BaseAddress;
InstancePtr->SendBufferPtr = MsgPtr;
InstancePtr->SendByteCount = ByteCount;
InstancePtr->RecvBufferPtr = NULL;
InstancePtr->IsSend = 1;
/*
* Set repeated start if sending more than FIFO of data.
*/
if (((InstancePtr->IsRepeatedStart) != 0)||
((ByteCount > XIICPS_FIFO_DEPTH) != 0U)) {
XIicPs_WriteReg(BaseAddr, (u32)XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
(u32)XIICPS_CR_HOLD_MASK);
}
/*
* Setup as a master sending role.
*/
(void)XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
(void)TransmitFifoFill(InstancePtr);
XIicPs_EnableInterrupts(BaseAddr,
(u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_COMP_MASK |
(u32)XIICPS_IXR_ARB_LOST_MASK);
/*
* Do the address transfer to notify the slave.
*/
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
}
/*****************************************************************************/
/**
* This function initiates an interrupt-driven receive in master mode.
*
* It sets the transfer size register so the slave can send data to us.
* The rest of the work is managed by interrupt handler.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param MsgPtr is the pointer to the receive buffer.
* @param ByteCount is the number of bytes to be received.
* @param SlaveAddr is the address of the slave we are receiving from.
*
* @return None.
*
* @note This receive routine is for interrupt-driven transfer only.
*
****************************************************************************/
void XIicPs_MasterRecv(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount,
u16 SlaveAddr)
{
u32 BaseAddr;
/*
* Assert validates the input arguments.
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(MsgPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
BaseAddr = InstancePtr->Config.BaseAddress;
InstancePtr->RecvBufferPtr = MsgPtr;
InstancePtr->RecvByteCount = ByteCount;
InstancePtr->CurrByteCount = ByteCount;
InstancePtr->SendBufferPtr = NULL;
InstancePtr->IsSend = 0;
InstancePtr->UpdateTxSize = 0;
if ((ByteCount > XIICPS_FIFO_DEPTH) ||
((InstancePtr->IsRepeatedStart) !=0))
{
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
(u32)XIICPS_CR_HOLD_MASK);
}
/*
* Initialize for a master receiving role.
*/
(void)XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
/*
* Setup the transfer size register so the slave knows how much
* to send to us.
*/
if (ByteCount > XIICPS_MAX_TRANSFER_SIZE) {
XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
XIICPS_MAX_TRANSFER_SIZE);
InstancePtr->CurrByteCount = (s32)XIICPS_MAX_TRANSFER_SIZE;
InstancePtr->UpdateTxSize = 1;
}else {
XIicPs_WriteReg(BaseAddr, (u32)(XIICPS_TRANS_SIZE_OFFSET),
(u32)ByteCount);
}
XIicPs_EnableInterrupts(BaseAddr,
(u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_DATA_MASK |
(u32)XIICPS_IXR_RX_OVR_MASK | (u32)XIICPS_IXR_COMP_MASK |
(u32)XIICPS_IXR_ARB_LOST_MASK);
/*
* Do the address transfer to signal the slave.
*/
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
}
/*****************************************************************************/
/**
* This function initiates a polled mode send in master mode.
*
* It sends data to the FIFO and waits for the slave to pick them up.
* If slave fails to remove data from FIFO, the send fails with
* time out.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param MsgPtr is the pointer to the send buffer.
* @param ByteCount is the number of bytes to be sent.
* @param SlaveAddr is the address of the slave we are sending to.
*
* @return
* - XST_SUCCESS if everything went well.
* - XST_FAILURE if timed out.
*
* @note This send routine is for polled mode transfer only.
*
****************************************************************************/
s32 XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr,
s32 ByteCount, u16 SlaveAddr)
{
u32 IntrStatusReg;
u32 StatusReg;
u32 BaseAddr;
u32 Intrs;
u32 Value;
s32 Status;
/*
* Assert validates the input arguments.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(MsgPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
BaseAddr = InstancePtr->Config.BaseAddress;
InstancePtr->SendBufferPtr = MsgPtr;
InstancePtr->SendByteCount = ByteCount;
if (((InstancePtr->IsRepeatedStart) != 0) ||
((ByteCount > XIICPS_FIFO_DEPTH) != 0U)) {
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
(u32)XIICPS_CR_HOLD_MASK);
}
(void)XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);
/*
* Intrs keeps all the error-related interrupts.
*/
Intrs = (u32)XIICPS_IXR_ARB_LOST_MASK | (u32)XIICPS_IXR_TX_OVR_MASK |
(u32)XIICPS_IXR_NACK_MASK;
/*
* Clear the interrupt status register before use it to monitor.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
/*
* Transmit first FIFO full of data.
*/
(void)TransmitFifoFill(InstancePtr);
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
/*
* Continue sending as long as there is more data and
* there are no errors.
*/
Value = ((InstancePtr->SendByteCount > (s32)0) &&
((IntrStatusReg & Intrs) == (u32)0U));
while (Value != (u32)0x00U) {
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
/*
* Wait until transmit FIFO is empty.
*/
if ((StatusReg & XIICPS_SR_TXDV_MASK) != 0U) {
IntrStatusReg = XIicPs_ReadReg(BaseAddr,
XIICPS_ISR_OFFSET);
Value = ((InstancePtr->SendByteCount > (s32)0) &&
((IntrStatusReg & Intrs) == (u32)0U));
continue;
}
/*
* Send more data out through transmit FIFO.
*/
(void)TransmitFifoFill(InstancePtr);
Value = ((InstancePtr->SendByteCount > (s32)0) &&
((IntrStatusReg & Intrs) == (u32)0U));
}
/*
* Check for completion of transfer.
*/
while ((IntrStatusReg & XIICPS_IXR_COMP_MASK) != XIICPS_IXR_COMP_MASK){
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
/*
* If there is an error, tell the caller.
*/
if ((IntrStatusReg & Intrs) != 0U) {
return (s32)XST_FAILURE;
}
}
if ((!(InstancePtr->IsRepeatedStart)) != 0) {
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
(~XIICPS_CR_HOLD_MASK));
}
return (s32)XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function initiates a polled mode receive in master mode.
*
* It repeatedly sets the transfer size register so the slave can
* send data to us. It polls the data register for data to come in.
* If slave fails to send us data, it fails with time out.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param MsgPtr is the pointer to the receive buffer.
* @param ByteCount is the number of bytes to be received.
* @param SlaveAddr is the address of the slave we are receiving from.
*
* @return
* - XST_SUCCESS if everything went well.
* - XST_FAILURE if timed out.
*
* @note This receive routine is for polled mode transfer only.
*
****************************************************************************/
s32 XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr,
s32 ByteCount, u16 SlaveAddr)
{
u32 IntrStatusReg;
u32 Intrs;
u32 StatusReg;
u32 BaseAddr;
s32 BytesToRecv;
s32 BytesToRead;
s32 TransSize;
s32 Tmp = 0;
u32 Status_Rcv;
u32 Status;
s32 Result;
s32 IsHold = 0;
s32 UpdateTxSize = 0;
s32 ByteCountVar = ByteCount;
u32 Platform;
/*
* Assert validates the input arguments.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(MsgPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
BaseAddr = InstancePtr->Config.BaseAddress;
InstancePtr->RecvBufferPtr = MsgPtr;
InstancePtr->RecvByteCount = ByteCountVar;
Platform = XGetPlatform_Info();
if((ByteCountVar > XIICPS_FIFO_DEPTH) ||
((InstancePtr->IsRepeatedStart) !=0))
{
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |
(u32)XIICPS_CR_HOLD_MASK);
IsHold = 1;
}
(void)XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
/*
* Clear the interrupt status register before use it to monitor.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
/*
* Set up the transfer size register so the slave knows how much
* to send to us.
*/
if (ByteCountVar > XIICPS_MAX_TRANSFER_SIZE) {
XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
XIICPS_MAX_TRANSFER_SIZE);
ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE;
UpdateTxSize = 1;
}else {
XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
ByteCountVar);
}
/*
* Intrs keeps all the error-related interrupts.
*/
Intrs = (u32)XIICPS_IXR_ARB_LOST_MASK | (u32)XIICPS_IXR_RX_OVR_MASK |
(u32)XIICPS_IXR_RX_UNF_MASK | (u32)XIICPS_IXR_NACK_MASK;
/*
* Poll the interrupt status register to find the errors.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
while ((InstancePtr->RecvByteCount > 0) &&
((IntrStatusReg & Intrs) == 0U)) {
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
while ((StatusReg & XIICPS_SR_RXDV_MASK) != 0U) {
if (((InstancePtr->RecvByteCount <
XIICPS_DATA_INTR_DEPTH) != 0U) && (IsHold != 0) &&
((!InstancePtr->IsRepeatedStart) != 0) &&
(UpdateTxSize == 0)) {
IsHold = 0;
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr,
XIICPS_CR_OFFSET) &
(~XIICPS_CR_HOLD_MASK));
}
XIicPs_RecvByte(InstancePtr);
ByteCountVar --;
if (Platform == XPLAT_ZYNQ) {
if ((UpdateTxSize != 0) &&
((ByteCountVar == (XIICPS_FIFO_DEPTH + 1)) != 0U)) {
break;
}
}
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
}
if (Platform == XPLAT_ZYNQ) {
if ((UpdateTxSize != 0) &&
((ByteCountVar == (XIICPS_FIFO_DEPTH + 1)) != 0U)) {
/* wait while fifo is full */
while (XIicPs_ReadReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET) !=
(u32)(ByteCountVar - XIICPS_FIFO_DEPTH)) { ;
}
if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
XIICPS_MAX_TRANSFER_SIZE) {
XIicPs_WriteReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET,
XIICPS_MAX_TRANSFER_SIZE);
ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE +
XIICPS_FIFO_DEPTH;
} else {
XIicPs_WriteReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET,
InstancePtr->RecvByteCount -
XIICPS_FIFO_DEPTH);
UpdateTxSize = 0;
ByteCountVar = InstancePtr->RecvByteCount;
}
}
} else {
if ((InstancePtr->RecvByteCount > 0) && (ByteCountVar == 0)) {
/*
* Clear the interrupt status register before use it to
* monitor.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
if ((InstancePtr->RecvByteCount) >
XIICPS_MAX_TRANSFER_SIZE) {
XIicPs_WriteReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET,
XIICPS_MAX_TRANSFER_SIZE);
ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE;
} else {
XIicPs_WriteReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET,
InstancePtr->RecvByteCount);
UpdateTxSize = 0;
ByteCountVar = InstancePtr->RecvByteCount;
}
}
}
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
}
if ((!(InstancePtr->IsRepeatedStart)) != 0) {
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) &
(~XIICPS_CR_HOLD_MASK));
}
if ((IntrStatusReg & Intrs) != 0x0U) {
Result = (s32)XST_FAILURE;
}
else {
Result = (s32)XST_SUCCESS;
}
return Result;
}
/*****************************************************************************/
/**
* This function enables the slave monitor mode.
*
* It enables slave monitor in the control register and enables
* slave ready interrupt. It then does an address transfer to slave.
* Interrupt handler will signal the caller if slave responds to
* the address transfer.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param SlaveAddr is the address of the slave we want to contact.
*
* @return None.
*
* @note None.
*
****************************************************************************/
void XIicPs_EnableSlaveMonitor(XIicPs *InstancePtr, u16 SlaveAddr)
{
u32 BaseAddr;
u32 ConfigReg;
Xil_AssertVoid(InstancePtr != NULL);
BaseAddr = InstancePtr->Config.BaseAddress;
/* Clear transfer size register */
XIicPs_WriteReg(BaseAddr, (u32)XIICPS_TRANS_SIZE_OFFSET, 0x0U);
/*
* Enable slave monitor mode in control register.
*/
ConfigReg = XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET);
ConfigReg |= (u32)XIICPS_CR_MS_MASK | (u32)XIICPS_CR_NEA_MASK |
(u32)XIICPS_CR_CLR_FIFO_MASK | (u32)XIICPS_CR_SLVMON_MASK;
ConfigReg &= (u32)(~XIICPS_CR_RD_WR_MASK);
XIicPs_WriteReg(BaseAddr, (u32)XIICPS_CR_OFFSET, ConfigReg);
/*
* Set up interrupt flag for slave monitor interrupt.
* Dont enable NACK.
*/
XIicPs_EnableInterrupts(BaseAddr, (u32)XIICPS_IXR_SLV_RDY_MASK);
/*
* Initialize the slave monitor register.
*/
XIicPs_WriteReg(BaseAddr, (u32)XIICPS_SLV_PAUSE_OFFSET, 0xFU);
/*
* Set the slave address to start the slave address transmission.
*/
XIicPs_WriteReg(BaseAddr, (u32)XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
return;
}
/*****************************************************************************/
/**
* This function disables slave monitor mode.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return None.
*
* @note None.
*
****************************************************************************/
void XIicPs_DisableSlaveMonitor(XIicPs *InstancePtr)
{
u32 BaseAddr;
Xil_AssertVoid(InstancePtr != NULL);
BaseAddr = InstancePtr->Config.BaseAddress;
/*
* Clear slave monitor control bit.
*/
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET)
& (~XIICPS_CR_SLVMON_MASK));
/*
* Clear interrupt flag for slave monitor interrupt.
*/
XIicPs_DisableInterrupts(BaseAddr, XIICPS_IXR_SLV_RDY_MASK);
return;
}
/*****************************************************************************/
/**
* The interrupt handler for the master mode. It does the protocol handling for
* the interrupt-driven transfers.
*
* Completion events and errors are signaled to upper layer for proper handling.
*
* <pre>
* The interrupts that are handled are:
* - DATA
* This case is handled only for master receive data.
* The master has to request for more data (if there is more data to
* receive) and read the data from the FIFO .
*
* - COMP
* If the Master is transmitting data and there is more data to be
* sent then the data is written to the FIFO. If there is no more data to
* be transmitted then a completion event is signalled to the upper layer
* by calling the callback handler.
*
* If the Master is receiving data then the data is read from the FIFO and
* the Master has to request for more data (if there is more data to
* receive). If all the data has been received then a completion event
* is signalled to the upper layer by calling the callback handler.
* It is an error if the amount of received data is more than expected.
*
* - NAK and SLAVE_RDY
* This is signalled to the upper layer by calling the callback handler.
*
* - All Other interrupts
* These interrupts are marked as error. This is signalled to the upper
* layer by calling the callback handler.
*
* </pre>
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return None.
*
* @note None.
*
****************************************************************************/
void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr)
{
u32 IntrStatusReg;
u32 StatusEvent = 0U;
u32 BaseAddr;
u16 SlaveAddr;
s32 ByteCnt;
s32 IsHold;
u32 Platform;
/*
* Assert validates the input arguments.
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
BaseAddr = InstancePtr->Config.BaseAddress;
Platform = XGetPlatform_Info();
/*
* Read the Interrupt status register.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr,
(u32)XIICPS_ISR_OFFSET);
/*
* Write the status back to clear the interrupts so no events are
* missed while processing this interrupt.
*/
XIicPs_WriteReg(BaseAddr, (u32)XIICPS_ISR_OFFSET, IntrStatusReg);
/*
* Use the Mask register AND with the Interrupt Status register so
* disabled interrupts are not processed.
*/
IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, (u32)XIICPS_IMR_OFFSET));
ByteCnt = InstancePtr->CurrByteCount;
IsHold = 0;
if ((XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) & (u32)XIICPS_CR_HOLD_MASK) != 0U) {
IsHold = 1;
}
/*
* Send
*/
if (((InstancePtr->IsSend) != 0) &&
((u32)0U != (IntrStatusReg & (u32)XIICPS_IXR_COMP_MASK))) {
if (InstancePtr->SendByteCount > 0) {
MasterSendData(InstancePtr);
} else {
StatusEvent |= XIICPS_EVENT_COMPLETE_SEND;
}
}
/*
* Receive
*/
if (((!(InstancePtr->IsSend))!= 0) &&
((0 != (IntrStatusReg & (u32)XIICPS_IXR_DATA_MASK)) ||
(0 != (IntrStatusReg & (u32)XIICPS_IXR_COMP_MASK)))){
while ((XIicPs_ReadReg(BaseAddr, (u32)XIICPS_SR_OFFSET) &
XIICPS_SR_RXDV_MASK) != 0U) {
if (((InstancePtr->RecvByteCount <
XIICPS_DATA_INTR_DEPTH)!= 0U) && (IsHold != 0) &&
((!InstancePtr->IsRepeatedStart)!= 0) &&
(InstancePtr->UpdateTxSize == 0)) {
IsHold = 0;
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr,
XIICPS_CR_OFFSET) &
(~XIICPS_CR_HOLD_MASK));
}
XIicPs_RecvByte(InstancePtr);
ByteCnt--;
if (Platform == XPLAT_ZYNQ) {
if ((InstancePtr->UpdateTxSize != 0) &&
((ByteCnt == (XIICPS_FIFO_DEPTH + 1)) != 0U)) {
break;
}
}
}
if (Platform == XPLAT_ZYNQ) {
if ((InstancePtr->UpdateTxSize != 0) &&
((ByteCnt == (XIICPS_FIFO_DEPTH + 1))!= 0U)) {
/* wait while fifo is full */
while (XIicPs_ReadReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET) !=
(u32)(ByteCnt - XIICPS_FIFO_DEPTH)) {
}
if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) >
XIICPS_MAX_TRANSFER_SIZE) {
XIicPs_WriteReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET,
XIICPS_MAX_TRANSFER_SIZE);
ByteCnt = (s32)XIICPS_MAX_TRANSFER_SIZE +
XIICPS_FIFO_DEPTH;
} else {
XIicPs_WriteReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET,
InstancePtr->RecvByteCount -
XIICPS_FIFO_DEPTH);
InstancePtr->UpdateTxSize = 0;
ByteCnt = InstancePtr->RecvByteCount;
}
}
} else {
if ((InstancePtr->RecvByteCount > 0) && (ByteCnt == 0)) {
/*
* Clear the interrupt status register before use it to
* monitor.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
SlaveAddr = XIicPs_ReadReg(BaseAddr, (u32)XIICPS_ADDR_OFFSET);
XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
if ((InstancePtr->RecvByteCount) >
XIICPS_MAX_TRANSFER_SIZE) {
XIicPs_WriteReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET,
XIICPS_MAX_TRANSFER_SIZE);
ByteCnt = (s32)XIICPS_MAX_TRANSFER_SIZE;
} else {
XIicPs_WriteReg(BaseAddr,
XIICPS_TRANS_SIZE_OFFSET,
InstancePtr->RecvByteCount);
InstancePtr->UpdateTxSize = 0;
ByteCnt = InstancePtr->RecvByteCount;
}
XIicPs_EnableInterrupts(BaseAddr,
(u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_DATA_MASK |
(u32)XIICPS_IXR_RX_OVR_MASK | (u32)XIICPS_IXR_COMP_MASK |
(u32)XIICPS_IXR_ARB_LOST_MASK);
}
}
InstancePtr->CurrByteCount = ByteCnt;
}
if (((!(InstancePtr->IsSend)) != 0) &&
(0U != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) {
/*
* If all done, tell the application.
*/
if (InstancePtr->RecvByteCount == 0){
if ((!(InstancePtr->IsRepeatedStart)) != 0) {
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr,
XIICPS_CR_OFFSET) &
(~XIICPS_CR_HOLD_MASK));
}
StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
}
}
/*
* Slave ready interrupt, it is only meaningful for master mode.
*/
if (0U != (IntrStatusReg & XIICPS_IXR_SLV_RDY_MASK)) {
StatusEvent |= XIICPS_EVENT_SLAVE_RDY;
}
if (0U != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) {
if ((!(InstancePtr->IsRepeatedStart)) != 0 ) {
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr,
XIICPS_CR_OFFSET) &
(~XIICPS_CR_HOLD_MASK));
}
StatusEvent |= XIICPS_EVENT_NACK;
}
/*
* Arbitration lost interrupt
*/
if (0U != (IntrStatusReg & XIICPS_IXR_ARB_LOST_MASK)) {
StatusEvent |= XIICPS_EVENT_ARB_LOST;
}
/*
* All other interrupts are treated as error.
*/
if (0U != (IntrStatusReg & (XIICPS_IXR_NACK_MASK |
XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_TX_OVR_MASK |
XIICPS_IXR_RX_OVR_MASK))) {
if ((!(InstancePtr->IsRepeatedStart)) != 0) {
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
XIicPs_ReadReg(BaseAddr,
XIICPS_CR_OFFSET) &
(~XIICPS_CR_HOLD_MASK));
}
StatusEvent |= XIICPS_EVENT_ERROR;
}
/*
* Signal application if there are any events.
*/
if (StatusEvent != 0U) {
InstancePtr->StatusHandler(InstancePtr->CallBackRef,
StatusEvent);
}
}
/*****************************************************************************/
/*
* This function prepares a device to transfers as a master.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @param Role specifies whether the device is sending or receiving.
*
* @return
* - XST_SUCCESS if everything went well.
* - XST_FAILURE if bus is busy.
*
* @note Interrupts are always disabled, device which needs to use
* interrupts needs to setup interrupts after this call.
*
****************************************************************************/
static s32 XIicPs_SetupMaster(XIicPs *InstancePtr, s32 Role)
{
u32 ControlReg;
u32 BaseAddr;
u32 EnabledIntr = 0x0U;
Xil_AssertNonvoid(InstancePtr != NULL);
BaseAddr = InstancePtr->Config.BaseAddress;
ControlReg = XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET);
/*
* Only check if bus is busy when repeated start option is not set.
*/
if ((ControlReg & XIICPS_CR_HOLD_MASK) == 0U) {
if (XIicPs_BusIsBusy(InstancePtr) == (s32)1) {
return (s32)XST_FAILURE;
}
}
/*
* Set up master, AckEn, nea and also clear fifo.
*/
ControlReg |= (u32)XIICPS_CR_ACKEN_MASK | (u32)XIICPS_CR_CLR_FIFO_MASK |
(u32)XIICPS_CR_NEA_MASK | (u32)XIICPS_CR_MS_MASK;
if (Role == RECVING_ROLE) {
ControlReg |= (u32)XIICPS_CR_RD_WR_MASK;
EnabledIntr = (u32)XIICPS_IXR_DATA_MASK |(u32)XIICPS_IXR_RX_OVR_MASK;
}else {
ControlReg &= (u32)(~XIICPS_CR_RD_WR_MASK);
}
EnabledIntr |= (u32)XIICPS_IXR_COMP_MASK | (u32)XIICPS_IXR_ARB_LOST_MASK;
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, ControlReg);
XIicPs_DisableAllInterrupts(BaseAddr);
return (s32)XST_SUCCESS;
}
/*****************************************************************************/
/*
* This function handles continuation of sending data. It is invoked
* from interrupt handler.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return None.
*
* @note None.
*
****************************************************************************/
static void MasterSendData(XIicPs *InstancePtr)
{
(void)TransmitFifoFill(InstancePtr);
/*
* Clear hold bit if done, so stop can be sent out.
*/
if (InstancePtr->SendByteCount == 0) {
/*
* If user has enabled repeated start as an option,
* do not disable it.
*/
if ((!(InstancePtr->IsRepeatedStart)) != 0) {
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
(u32)XIICPS_CR_OFFSET,
XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
(u32)XIICPS_CR_OFFSET) & (u32)(~ XIICPS_CR_HOLD_MASK));
}
}
return;
}
/** @} */

View file

@ -0,0 +1,496 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiicps_options.c
* @addtogroup iicps_v3_0
* @{
*
* Contains functions for the configuration of the XIccPs driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- -----------------------------------------------
* 1.00a drg/jz 01/30/10 First release
* 1.02a sg 08/29/12 Updated the logic to arrive at the best divisors
* to achieve I2C clock with minimum error.
* This is a fix for CR #674195
* 1.03a hk 05/04/13 Initialized BestDivA and BestDivB to 0.
* This is fix for CR#704398 to remove warning.
* 2.0 hk 03/07/14 Limited frequency set when 100KHz or 400KHz is
* selected. This is a hardware limitation. CR#779290.
* 2.1 hk 04/24/14 Fix for CR# 761060 - provision for repeated start.
* 2.3 sk 10/07/14 Repeated start feature removed.
* 3.0 sk 12/06/14 Implemented Repeated start feature.
* 01/31/15 Modified the code according to MISRAC 2012 Compliant.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiicps.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*
* Create the table of options which are processed to get/set the device
* options. These options are table driven to allow easy maintenance and
* expansion of the options.
*/
typedef struct {
u32 Option;
u32 Mask;
} OptionsMap;
static OptionsMap OptionsTable[] = {
{XIICPS_7_BIT_ADDR_OPTION, XIICPS_CR_NEA_MASK},
{XIICPS_10_BIT_ADDR_OPTION, XIICPS_CR_NEA_MASK},
{XIICPS_SLAVE_MON_OPTION, XIICPS_CR_SLVMON_MASK},
{XIICPS_REP_START_OPTION, XIICPS_CR_HOLD_MASK},
};
#define XIICPS_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionsMap))
/*****************************************************************************/
/**
*
* This function sets the options for the IIC device driver. The options control
* how the device behaves relative to the IIC bus. The device must be idle
* rather than busy transferring data before setting these device options.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param Options contains the specified options to be set. This is a bit
* mask where a 1 means to turn the option on. One or more bit
* values may be contained in the mask. See the bit definitions
* named XIICPS_*_OPTION in xiicps.h.
*
* @return
* - XST_SUCCESS if options are successfully set.
* - XST_DEVICE_IS_STARTED if the device is currently transferring
* data. The transfer must complete or be aborted before setting
* options.
*
* @note None.
*
******************************************************************************/
s32 XIicPs_SetOptions(XIicPs *InstancePtr, u32 Options)
{
u32 ControlReg;
u32 Index;
u32 OptionsVar = Options;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_CR_OFFSET);
/*
* If repeated start option is requested, set the flag.
* The hold bit in CR will be written by driver when the next transfer
* is initiated.
*/
if ((OptionsVar & XIICPS_REP_START_OPTION) != 0U ) {
InstancePtr->IsRepeatedStart = 1;
OptionsVar = OptionsVar & (~XIICPS_REP_START_OPTION);
}
/*
* Loop through the options table, turning the option on.
*/
for (Index = 0U; Index < XIICPS_NUM_OPTIONS; Index++) {
if ((OptionsVar & OptionsTable[Index].Option) != (u32)0x0U) {
/*
* 10-bit option is specially treated, because it is
* using the 7-bit option, so turning it on means
* turning 7-bit option off.
*/
if ((OptionsTable[Index].Option &
XIICPS_10_BIT_ADDR_OPTION) != (u32)0x0U) {
/* Turn 7-bit off */
ControlReg &= ~OptionsTable[Index].Mask;
} else {
/* Turn 7-bit on */
ControlReg |= OptionsTable[Index].Mask;
}
}
}
/*
* Now write to the control register. Leave it to the upper layers
* to restart the device.
*/
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_CR_OFFSET,
ControlReg);
/*
* Keep a copy of what options this instance has.
*/
InstancePtr->Options = XIicPs_GetOptions(InstancePtr);
return (s32)XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function clears the options for the IIC device driver. The options
* control how the device behaves relative to the IIC bus. The device must be
* idle rather than busy transferring data before setting these device options.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param Options contains the specified options to be cleared. This is a
* bit mask where a 1 means to turn the option off. One or more bit
* values may be contained in the mask. See the bit definitions
* named XIICPS_*_OPTION in xiicps.h.
*
* @return
* - XST_SUCCESS if options are successfully set.
* - XST_DEVICE_IS_STARTED if the device is currently transferring
* data. The transfer must complete or be aborted before setting
* options.
*
* @note None
*
******************************************************************************/
s32 XIicPs_ClearOptions(XIicPs *InstancePtr, u32 Options)
{
u32 ControlReg;
u32 Index;
u32 OptionsVar = Options;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_CR_OFFSET);
/*
* If repeated start option is cleared, set the flag.
* The hold bit in CR will be cleared by driver when the
* following transfer ends.
*/
if ((OptionsVar & XIICPS_REP_START_OPTION) != (u32)0x0U ) {
InstancePtr->IsRepeatedStart = 0;
OptionsVar = OptionsVar & (~XIICPS_REP_START_OPTION);
}
/*
* Loop through the options table and clear the specified options.
*/
for (Index = 0U; Index < XIICPS_NUM_OPTIONS; Index++) {
if ((OptionsVar & OptionsTable[Index].Option) != (u32)0x0U) {
/*
* 10-bit option is specially treated, because it is
* using the 7-bit option, so clearing it means turning
* 7-bit option on.
*/
if ((OptionsTable[Index].Option &
XIICPS_10_BIT_ADDR_OPTION) != (u32)0x0U) {
/* Turn 7-bit on */
ControlReg |= OptionsTable[Index].Mask;
} else {
/* Turn 7-bit off */
ControlReg &= ~OptionsTable[Index].Mask;
}
}
}
/*
* Now write the control register. Leave it to the upper layers
* to restart the device.
*/
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, XIICPS_CR_OFFSET,
ControlReg);
/*
* Keep a copy of what options this instance has.
*/
InstancePtr->Options = XIicPs_GetOptions(InstancePtr);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function gets the options for the IIC device. The options control how
* the device behaves relative to the IIC bus.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return 32 bit mask of the options, where a 1 means the option is on,
* and a 0 means to the option is off. One or more bit values may
* be contained in the mask. See the bit definitions named
* XIICPS_*_OPTION in the file xiicps.h.
*
* @note None.
*
******************************************************************************/
u32 XIicPs_GetOptions(XIicPs *InstancePtr)
{
u32 OptionsFlag = 0U;
u32 ControlReg;
u32 Index;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
/*
* Read control register to find which options are currently set.
*/
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_CR_OFFSET);
/*
* Loop through the options table to determine which options are set.
*/
for (Index = 0U; Index < XIICPS_NUM_OPTIONS; Index++) {
if ((ControlReg & OptionsTable[Index].Mask) != (u32)0x0U) {
OptionsFlag |= OptionsTable[Index].Option;
}
if ((ControlReg & XIICPS_CR_NEA_MASK) == (u32)0x0U) {
OptionsFlag |= XIICPS_10_BIT_ADDR_OPTION;
}
}
if (InstancePtr->IsRepeatedStart != 0 ) {
OptionsFlag |= XIICPS_REP_START_OPTION;
}
return OptionsFlag;
}
/*****************************************************************************/
/**
*
* This function sets the serial clock rate for the IIC device. The device
* must be idle rather than busy transferring data before setting these device
* options.
*
* The data rate is set by values in the control register. The formula for
* determining the correct register values is:
* Fscl = Fpclk/(22 x (divisor_a+1) x (divisor_b+1))
* See the hardware data sheet for a full explanation of setting the serial
* clock rate.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param FsclHz is the clock frequency in Hz. The two most common clock
* rates are 100KHz and 400KHz.
*
* @return
* - XST_SUCCESS if options are successfully set.
* - XST_DEVICE_IS_STARTED if the device is currently transferring
* data. The transfer must complete or be aborted before setting
* options.
* - XST_FAILURE if the Fscl frequency can not be set.
*
* @note The clock can not be faster than the input clock divide by 22.
*
******************************************************************************/
s32 XIicPs_SetSClk(XIicPs *InstancePtr, u32 FsclHz)
{
u32 Div_a;
u32 Div_b;
u32 ActualFscl;
u32 Temp;
u32 TempLimit;
u32 LastError;
u32 BestError;
u32 CurrentError;
u32 ControlReg;
u32 CalcDivA;
u32 CalcDivB;
u32 BestDivA = 0;
u32 BestDivB = 0;
u32 FsclHzVar = FsclHz;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(FsclHzVar > 0U);
if (0U != XIicPs_In32((InstancePtr->Config.BaseAddress) +
XIICPS_TRANS_SIZE_OFFSET)) {
return (s32)XST_DEVICE_IS_STARTED;
}
/*
* Assume Div_a is 0 and calculate (divisor_a+1) x (divisor_b+1).
*/
Temp = (InstancePtr->Config.InputClockHz) / ((u32)22U * FsclHzVar);
/*
* If the answer is negative or 0, the Fscl input is out of range.
*/
if ((u32)(0U) == Temp) {
return (s32)XST_FAILURE;
}
/*
* If frequency 400KHz is selected, 384.6KHz should be set.
* If frequency 100KHz is selected, 90KHz should be set.
* This is due to a hardware limitation.
*/
if(FsclHzVar > 384600U) {
FsclHzVar = 384600U;
}
if((FsclHzVar <= 100000U) && (FsclHzVar > 90000U)) {
FsclHzVar = 90000U;
}
/*
* TempLimit helps in iterating over the consecutive value of Temp to
* find the closest clock rate achievable with divisors.
* Iterate over the next value only if fractional part is involved.
*/
TempLimit = (((InstancePtr->Config.InputClockHz) %
((u32)22 * FsclHzVar)) != (u32)0x0U) ?
Temp + (u32)1U : Temp;
BestError = FsclHzVar;
BestDivA = 0U;
BestDivB = 0U;
for ( ; Temp <= TempLimit ; Temp++)
{
LastError = FsclHzVar;
CalcDivA = 0U;
CalcDivB = 0U;
for (Div_b = 0U; Div_b < 64U; Div_b++) {
Div_a = Temp / (Div_b + 1U);
if (Div_a != 0U){
Div_a = Div_a - (u32)1U;
}
if (Div_a > 3U){
continue;
}
ActualFscl = (InstancePtr->Config.InputClockHz) /
(22U * (Div_a + 1U) * (Div_b + 1U));
if (ActualFscl > FsclHzVar){
CurrentError = (ActualFscl - FsclHzVar);}
else{
CurrentError = (FsclHzVar - ActualFscl);}
if (LastError > CurrentError) {
CalcDivA = Div_a;
CalcDivB = Div_b;
LastError = CurrentError;
}
}
/*
* Used to capture the best divisors.
*/
if (LastError < BestError) {
BestError = LastError;
BestDivA = CalcDivA;
BestDivB = CalcDivB;
}
}
/*
* Read the control register and mask the Divisors.
*/
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
(u32)XIICPS_CR_OFFSET);
ControlReg &= ~((u32)XIICPS_CR_DIV_A_MASK | (u32)XIICPS_CR_DIV_B_MASK);
ControlReg |= (BestDivA << XIICPS_CR_DIV_A_SHIFT) |
(BestDivB << XIICPS_CR_DIV_B_SHIFT);
XIicPs_WriteReg(InstancePtr->Config.BaseAddress, (u32)XIICPS_CR_OFFSET,
ControlReg);
return (s32)XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function gets the serial clock rate for the IIC device. The device
* must be idle rather than busy transferring data before setting these device
* options.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return The value of the IIC clock to the nearest Hz based on the
* control register settings. The actual value may not be exact to
* to integer math rounding errors.
*
* @note None.
*
******************************************************************************/
u32 XIicPs_GetSClk(XIicPs *InstancePtr)
{
u32 ControlReg;
u32 ActualFscl;
u32 Div_a;
u32 Div_b;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
ControlReg = XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_CR_OFFSET);
Div_a = (ControlReg & XIICPS_CR_DIV_A_MASK) >> XIICPS_CR_DIV_A_SHIFT;
Div_b = (ControlReg & XIICPS_CR_DIV_B_MASK) >> XIICPS_CR_DIV_B_SHIFT;
ActualFscl = (InstancePtr->Config.InputClockHz) /
(22U * (Div_a + 1U) * (Div_b + 1U));
return ActualFscl;
}
/** @} */

View file

@ -0,0 +1,132 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiicps_selftest.c
* @addtogroup iicps_v3_0
* @{
*
* This component contains the implementation of selftest functions for the
* XIicPs driver component.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- ---------------------------------------------
* 1.00a drg/jz 01/30/10 First release
* 1.00a sdm 09/22/11 Removed unused code
* 3.0 sk 11/03/14 Removed TimeOut Register value check
* 01/31/15 Modified the code according to MISRAC 2012 Compliant.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiicps.h"
/************************** Constant Definitions *****************************/
#define REG_TEST_VALUE 0x00000005U
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Runs a self-test on the driver/device. The self-test is destructive in that
* a reset of the device is performed in order to check the reset values of
* the registers and to get the device into a known state.
*
* Upon successful return from the self-test, the device is reset.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return
* - XST_SUCCESS if successful.
* - XST_REGISTER_ERROR indicates a register did not read or write
* correctly
*
* @note None.
*
******************************************************************************/
s32 XIicPs_SelfTest(XIicPs *InstancePtr)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
/*
* All the IIC registers should be in their default state right now.
*/
if ((XIICPS_CR_RESET_VALUE !=
XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_CR_OFFSET)) ||
(XIICPS_IXR_ALL_INTR_MASK !=
XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_IMR_OFFSET))) {
return (s32)XST_FAILURE;
}
XIicPs_Reset(InstancePtr);
/*
* Write, Read then write a register
*/
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
XIICPS_SLV_PAUSE_OFFSET, REG_TEST_VALUE);
if (REG_TEST_VALUE != XIicPs_ReadReg(InstancePtr->Config.BaseAddress,
XIICPS_SLV_PAUSE_OFFSET)) {
return (s32)XST_FAILURE;
}
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
XIICPS_SLV_PAUSE_OFFSET, 0U);
XIicPs_Reset(InstancePtr);
return (s32)XST_SUCCESS;
}
/** @} */

View file

@ -0,0 +1,102 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xiicps_sinit.c
* @addtogroup iicps_v3_0
* @{
*
* The implementation of the XIicPs component's static initialization
* functionality.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------------
* 1.00a drg/jz 01/30/10 First release
* 3.00 sk 01/31/15 Modified the code according to MISRAC 2012 Compliant.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xstatus.h"
#include "xparameters.h"
#include "xiicps.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
extern XIicPs_Config XIicPs_ConfigTable[XPAR_XIICPS_NUM_INSTANCES];
/*****************************************************************************/
/**
*
* Looks up the device configuration based on the unique device ID. A table
* contains the configuration info for each device in the system.
*
* @param DeviceId contains the ID of the device to look up the
* configuration for.
*
* @return A pointer to the configuration found or NULL if the specified
* device ID was not found. See xiicps.h for the definition of
* XIicPs_Config.
*
* @note None.
*
******************************************************************************/
XIicPs_Config *XIicPs_LookupConfig(u16 DeviceId)
{
XIicPs_Config *CfgPtr = NULL;
s32 Index;
for (Index = 0; Index < XPAR_XIICPS_NUM_INSTANCES; Index++) {
if (XIicPs_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XIicPs_ConfigTable[Index];
break;
}
}
return (XIicPs_Config *)CfgPtr;
}
/** @} */

View file

@ -0,0 +1,590 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xiicps_slave.c
* @addtogroup iicps_v3_0
* @{
*
* Handles slave transfers
*
* <pre> MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -- -------- ---------------------------------------------
* 1.00a jz 01/30/10 First release
* 1.04a kpc 08/30/13 Avoid buffer overwrite in SlaveRecvData function
* 3.00 sk 01/31/15 Modified the code according to MISRAC 2012 Compliant.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xiicps.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
extern s32 TransmitFifoFill(XIicPs *InstancePtr);
static s32 SlaveRecvData(XIicPs *InstancePtr);
/************************* Variable Definitions *****************************/
/*****************************************************************************/
/**
* This function sets up the device to be a slave.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param SlaveAddr is the address of the slave we are receiving from.
*
* @return None.
*
* @note
* Interrupt is always enabled no matter the tranfer is interrupt-
* driven or polled mode. Whether device will be interrupted or not
* depends on whether the device is connected to an interrupt
* controller and interrupt for the device is enabled.
*
****************************************************************************/
void XIicPs_SetupSlave(XIicPs *InstancePtr, u16 SlaveAddr)
{
u32 ControlReg;
u32 BaseAddr;
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr);
BaseAddr = InstancePtr->Config.BaseAddress;
ControlReg = XIicPs_In32(BaseAddr + XIICPS_CR_OFFSET);
/*
* Set up master, AckEn, nea and also clear fifo.
*/
ControlReg |= (u32)XIICPS_CR_ACKEN_MASK | (u32)XIICPS_CR_CLR_FIFO_MASK;
ControlReg |= (u32)XIICPS_CR_NEA_MASK;
ControlReg &= (u32)(~XIICPS_CR_MS_MASK);
XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,
ControlReg);
XIicPs_DisableAllInterrupts(BaseAddr);
XIicPs_WriteReg(InstancePtr->Config.BaseAddress,
XIICPS_ADDR_OFFSET, (u32)SlaveAddr);
return;
}
/*****************************************************************************/
/**
* This function setup a slave interrupt-driven send. It set the repeated
* start for the device is the tranfer size is larger than FIFO depth.
* Data processing for the send is initiated by the interrupt handler.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param MsgPtr is the pointer to the send buffer.
* @param ByteCount is the number of bytes to be sent.
*
* @return None.
*
* @note This send routine is for interrupt-driven transfer only.
*
****************************************************************************/
void XIicPs_SlaveSend(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount)
{
u32 BaseAddr;
/*
* Assert validates the input arguments
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(MsgPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
BaseAddr = InstancePtr->Config.BaseAddress;
InstancePtr->SendBufferPtr = MsgPtr;
InstancePtr->SendByteCount = ByteCount;
InstancePtr->RecvBufferPtr = NULL;
XIicPs_EnableInterrupts(BaseAddr,
(u32)XIICPS_IXR_DATA_MASK | (u32)XIICPS_IXR_COMP_MASK |
(u32)XIICPS_IXR_TO_MASK | (u32)XIICPS_IXR_NACK_MASK |
(u32)XIICPS_IXR_TX_OVR_MASK);
}
/*****************************************************************************/
/**
* This function setup a slave interrupt-driven receive.
* Data processing for the receive is handled by the interrupt handler.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param MsgPtr is the pointer to the receive buffer.
* @param ByteCount is the number of bytes to be received.
*
* @return None.
*
* @note This routine is for interrupt-driven transfer only.
*
****************************************************************************/
void XIicPs_SlaveRecv(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount)
{
/*
* Assert validates the input arguments.
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(MsgPtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
InstancePtr->RecvBufferPtr = MsgPtr;
InstancePtr->RecvByteCount = ByteCount;
InstancePtr->SendBufferPtr = NULL;
XIicPs_EnableInterrupts(InstancePtr->Config.BaseAddress,
(u32)XIICPS_IXR_DATA_MASK | (u32)XIICPS_IXR_COMP_MASK |
(u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_TO_MASK |
(u32)XIICPS_IXR_RX_OVR_MASK | (u32)XIICPS_IXR_RX_UNF_MASK);
}
/*****************************************************************************/
/**
* This function sends a buffer in polled mode as a slave.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param MsgPtr is the pointer to the send buffer.
* @param ByteCount is the number of bytes to be sent.
*
* @return
* - XST_SUCCESS if everything went well.
* - XST_FAILURE if master sends us data or master terminates the
* transfer before all data has sent out.
*
* @note This send routine is for polled mode transfer only.
*
****************************************************************************/
s32 XIicPs_SlaveSendPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount)
{
u32 IntrStatusReg;
u32 StatusReg;
u32 BaseAddr;
s32 Tmp;
s32 BytesToSend;
s32 Error = 0;
s32 Status = (s32)XST_SUCCESS;
u32 Value;
/*
* Assert validates the input arguments.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(MsgPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
BaseAddr = InstancePtr->Config.BaseAddress;
InstancePtr->SendBufferPtr = MsgPtr;
InstancePtr->SendByteCount = ByteCount;
/*
* Use RXRW bit in status register to wait master to start a read.
*/
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
while (((StatusReg & XIICPS_SR_RXRW_MASK) == 0U) &&
((!Error) != 0)) {
/*
* If master tries to send us data, it is an error.
*/
if ((StatusReg & XIICPS_SR_RXDV_MASK) != 0x0U) {
Error = 1;
}
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
}
if (Error != 0) {
Status = (s32)XST_FAILURE;
} else {
/*
* Clear the interrupt status register.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
/*
* Send data as long as there is more data to send and
* there are no errors.
*/
Value = (InstancePtr->SendByteCount > (s32)0) &&
((!Error) != 0);
while (Value != (u32)0x00U) {
/*
* Find out how many can be sent.
*/
BytesToSend = InstancePtr->SendByteCount;
if (BytesToSend > (s32)(XIICPS_FIFO_DEPTH)) {
BytesToSend = (s32)(XIICPS_FIFO_DEPTH);
}
for(Tmp = 0; Tmp < BytesToSend; Tmp ++) {
XIicPs_SendByte(InstancePtr);
}
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
/*
* Wait for master to read the data out of fifo.
*/
while (((StatusReg & XIICPS_SR_TXDV_MASK) != (u32)0x00U) &&
((!Error) != 0)) {
/*
* If master terminates the transfer before all data is
* sent, it is an error.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr,
XIICPS_ISR_OFFSET);
if ((IntrStatusReg & XIICPS_IXR_NACK_MASK) != 0x0U) {
Error = 1;
}
/* Clear ISR.
*/
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET,
IntrStatusReg);
StatusReg = XIicPs_ReadReg(BaseAddr,
XIICPS_SR_OFFSET);
}
Value = (InstancePtr->SendByteCount > (s32)0U) &&
((!Error) != 0);
}
}
if (Error != 0) {
Status = (s32)XST_FAILURE;
}
return Status;
}
/*****************************************************************************/
/**
* This function receives a buffer in polled mode as a slave.
*
* @param InstancePtr is a pointer to the XIicPs instance.
* @param MsgPtr is the pointer to the receive buffer.
* @param ByteCount is the number of bytes to be received.
*
* @return
* - XST_SUCCESS if everything went well.
* - XST_FAILURE if timed out.
*
* @note This receive routine is for polled mode transfer only.
*
****************************************************************************/
s32 XIicPs_SlaveRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount)
{
u32 IntrStatusReg;
u32 StatusReg;
u32 BaseAddr;
s32 Count;
/*
* Assert validates the input arguments.
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(MsgPtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
BaseAddr = InstancePtr->Config.BaseAddress;
InstancePtr->RecvBufferPtr = MsgPtr;
InstancePtr->RecvByteCount = ByteCount;
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
/*
* Clear the interrupt status register.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
/*
* Clear the status register.
*/
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
XIicPs_WriteReg(BaseAddr, XIICPS_SR_OFFSET, StatusReg);
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
Count = InstancePtr->RecvByteCount;
while (Count > (s32)0) {
/* Wait for master to put data */
while ((StatusReg & XIICPS_SR_RXDV_MASK) == 0U) {
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
/*
* If master terminates the transfer before we get all
* the data or the master tries to read from us,
* it is an error.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr,
XIICPS_ISR_OFFSET);
if (((IntrStatusReg & (XIICPS_IXR_DATA_MASK |
XIICPS_IXR_COMP_MASK))!=0x0U) &&
((StatusReg & XIICPS_SR_RXDV_MASK) == 0U) &&
((InstancePtr->RecvByteCount > 0) != 0x0U)) {
return (s32)XST_FAILURE;
}
/*
* Clear the interrupt status register.
*/
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET,
IntrStatusReg);
}
/*
* Read all data from FIFO.
*/
while (((StatusReg & XIICPS_SR_RXDV_MASK)!=0x0U) &&
((InstancePtr->RecvByteCount > 0) != 0x0U)){
XIicPs_RecvByte(InstancePtr);
StatusReg = XIicPs_ReadReg(BaseAddr,
XIICPS_SR_OFFSET);
}
Count = InstancePtr->RecvByteCount;
}
return (s32)XST_SUCCESS;
}
/*****************************************************************************/
/**
* The interrupt handler for slave mode. It does the protocol handling for
* the interrupt-driven transfers.
*
* Completion events and errors are signaled to upper layer for proper
* handling.
*
* <pre>
*
* The interrupts that are handled are:
* - DATA
* If the instance is sending, it means that the master wants to read more
* data from us. Send more data, and check whether we are done with this
* send.
*
* If the instance is receiving, it means that the master has writen
* more data to us. Receive more data, and check whether we are done with
* with this receive.
*
* - COMP
* This marks that stop sequence has been sent from the master, transfer
* is about to terminate. However, for receiving, the master may have
* written us some data, so receive that first.
*
* It is an error if the amount of transfered data is less than expected.
*
* - NAK
* This marks that master does not want our data. It is for send only.
*
* - Other interrupts
* These interrupts are marked as error.
*
* </pre>
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return None.
*
* @note None.
*
****************************************************************************/
void XIicPs_SlaveInterruptHandler(XIicPs *InstancePtr)
{
u32 IntrStatusReg;
u32 IsSend = 0U;
u32 StatusEvent = 0U;
s32 LeftOver;
u32 BaseAddr;
/*
* Assert validates the input arguments.
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
BaseAddr = InstancePtr->Config.BaseAddress;
/*
* Read the Interrupt status register.
*/
IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
/*
* Write the status back to clear the interrupts so no events are missed
* while processing this interrupt.
*/
XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
/*
* Use the Mask register AND with the Interrupt Status register so
* disabled interrupts are not processed.
*/
IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, XIICPS_IMR_OFFSET));
/*
* Determine whether the device is sending.
*/
if (InstancePtr->RecvBufferPtr == NULL) {
IsSend = 1U;
}
/* Data interrupt
*
* This means master wants to do more data transfers.
* Also check for completion of transfer, signal upper layer if done.
*/
if ((u32)0U != (IntrStatusReg & XIICPS_IXR_DATA_MASK)) {
if (IsSend != 0x0U) {
LeftOver = TransmitFifoFill(InstancePtr);
/*
* We may finish send here
*/
if (LeftOver == 0) {
StatusEvent |=
XIICPS_EVENT_COMPLETE_SEND;
}
} else {
LeftOver = SlaveRecvData(InstancePtr);
/* We may finish the receive here */
if (LeftOver == 0) {
StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
}
}
}
/*
* Complete interrupt.
*
* In slave mode, it means the master has done with this transfer, so
* we signal the application using completion event.
*/
if (0U != (IntrStatusReg & XIICPS_IXR_COMP_MASK)) {
if (IsSend != 0x0U) {
if (InstancePtr->SendByteCount > 0) {
StatusEvent |= XIICPS_EVENT_ERROR;
}else {
StatusEvent |= XIICPS_EVENT_COMPLETE_SEND;
}
} else {
LeftOver = SlaveRecvData(InstancePtr);
if (LeftOver > 0) {
StatusEvent |= XIICPS_EVENT_ERROR;
} else {
StatusEvent |= XIICPS_EVENT_COMPLETE_RECV;
}
}
}
/*
* Nack interrupt, pass this information to application.
*/
if (0U != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) {
StatusEvent |= XIICPS_EVENT_NACK;
}
/*
* All other interrupts are treated as error.
*/
if (0U != (IntrStatusReg & (XIICPS_IXR_TO_MASK |
XIICPS_IXR_RX_UNF_MASK |
XIICPS_IXR_TX_OVR_MASK |
XIICPS_IXR_RX_OVR_MASK))){
StatusEvent |= XIICPS_EVENT_ERROR;
}
/*
* Signal application if there are any events.
*/
if (0U != StatusEvent) {
InstancePtr->StatusHandler(InstancePtr->CallBackRef,
StatusEvent);
}
}
/*****************************************************************************/
/*
*
* This function handles continuation of receiving data. It is invoked
* from interrupt handler.
*
* @param InstancePtr is a pointer to the XIicPs instance.
*
* @return Number of bytes still expected by the instance.
*
* @note None.
*
****************************************************************************/
static s32 SlaveRecvData(XIicPs *InstancePtr)
{
u32 StatusReg;
u32 BaseAddr;
BaseAddr = InstancePtr->Config.BaseAddress;
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
while (((StatusReg & XIICPS_SR_RXDV_MASK)!=0x0U) &&
((InstancePtr->RecvByteCount > 0) != 0x0U)) {
XIicPs_RecvByte(InstancePtr);
StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
}
return InstancePtr->RecvByteCount;
}
/** @} */

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner xipipsu_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling ipipsu"
xipipsu_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: xipipsu_includes
xipipsu_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

View file

@ -0,0 +1,352 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xipipsu.c
* @addtogroup ipipsu_v1_0
* @{
*
* This file contains the implementation of the interface functions for XIpiPsu
* driver. Refer to the header file xipipsu.h for more detailed information.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- ----------------------------------------------
* 1.00 mjr 03/15/15 First Release
* 2.0 mjr 01/22/16 Fixed response buffer address
* calculation. CR# 932582.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xipipsu.h"
#include "xipipsu_hw.h"
/****************************************************************************/
/**
* Initialize the Instance pointer based on a given Config Pointer
*
* @param InstancePtr is a pointer to the instance to be worked on
* @param CfgPtr is the device configuration structure containing required
* hardware build data
* @param EffectiveAddress is the base address of the device. If address
* translation is not utilized, this parameter can be passed in using
* CfgPtr->Config.BaseAddress to specify the physical base address.
* @return XST_SUCCESS if initialization was successful
* XST_FAILURE in case of failure
*
*/
XStatus XIpiPsu_CfgInitialize(XIpiPsu *InstancePtr, XIpiPsu_Config * CfgPtr,
UINTPTR EffectiveAddress)
{
u32 Index;
/* Verify arguments */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(CfgPtr != NULL);
/* Set device base address and ID */
InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
InstancePtr->Config.BaseAddress = EffectiveAddress;
InstancePtr->Config.BitMask = CfgPtr->BitMask;
InstancePtr->Config.IntId = CfgPtr->IntId;
InstancePtr->Config.TargetCount = CfgPtr->TargetCount;
for (Index = 0; Index < CfgPtr->TargetCount; Index++) {
InstancePtr->Config.TargetList[Index].Mask =
CfgPtr->TargetList[Index].Mask;
InstancePtr->Config.TargetList[Index].BufferIndex =
CfgPtr->TargetList[Index].BufferIndex;
}
/* Mark the component as Ready */
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
return (XST_SUCCESS);
}
/**
* @brief Reset the given IPI register set.
* This function can be called to disable the IPIs from all
* the sources and clear any pending IPIs in status register
*
* @param InstancePtr is the pointer to current IPI instance
*
*/
void XIpiPsu_Reset(XIpiPsu *InstancePtr)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/**************Disable***************/
XIpiPsu_WriteReg(InstancePtr->Config.BaseAddress, XIPIPSU_IDR_OFFSET,
XIPIPSU_ALL_MASK);
/**************Clear***************/
XIpiPsu_WriteReg(InstancePtr->Config.BaseAddress, XIPIPSU_ISR_OFFSET,
XIPIPSU_ALL_MASK);
}
/**
* @brief Trigger an IPI to a Destination CPU
*
* @param InstancePtr is the pointer to current IPI instance
* @param DestCpuMask is the Mask of the CPU to which IPI is to be triggered
*
*
* @return XST_SUCCESS if successful
* XST_FAILURE if an error occurred
*/
XStatus XIpiPsu_TriggerIpi(XIpiPsu *InstancePtr, u32 DestCpuMask)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/* Trigger an IPI to the Target */
XIpiPsu_WriteReg(InstancePtr->Config.BaseAddress, XIPIPSU_TRIG_OFFSET,
DestCpuMask);
return XST_SUCCESS;
}
/**
* @brief Poll for an acknowledgement using Observation Register
*
* @param InstancePtr is the pointer to current IPI instance
* @param DestCpuMask is the Mask of the destination CPU from which ACK is expected
* @param TimeOutCount is the Count after which the routines returns failure
*
* @return XST_SUCCESS if successful
* XST_FAILURE if a timeout occurred
*/
XStatus XIpiPsu_PollForAck(XIpiPsu *InstancePtr, u32 DestCpuMask,
u32 TimeOutCount)
{
u32 Flag, PollCount;
XStatus Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
PollCount = 0;
/* Poll the OBS register until the corresponding DestCpu bit is cleared */
do {
Flag = (XIpiPsu_ReadReg(InstancePtr->Config.BaseAddress,
XIPIPSU_OBS_OFFSET)) & (DestCpuMask);
PollCount++;
/* Check if the IPI was Acknowledged by the Target or we Timed Out*/
} while ((0x00000000U != Flag) && (PollCount < TimeOutCount));
if (PollCount >= TimeOutCount) {
Status = XST_FAILURE;
} else {
Status = XST_SUCCESS;
}
return Status;
}
/**
* @brief Get the Buffer Index for a CPU specified by Mask
*
* @param InstancePtr is the pointer to current IPI instance
* @param CpuMask is the Mask of the CPU form which Index is required
*
* @return Buffer Index value if CPU Mask is valid
* XIPIPSU_MAX_BUFF_INDEX+1 if not valid
*
* @note Static function used only by XIpiPsu_GetBufferAddress
*
*/
static u32 XIpiPsu_GetBufferIndex(XIpiPsu *InstancePtr, u32 CpuMask)
{
u32 BufferIndex;
u32 Index;
/* Init Index with an invalid value */
BufferIndex = XIPIPSU_MAX_BUFF_INDEX + 1;
/*Search for CPU in the List */
for (Index = 0; Index < InstancePtr->Config.TargetCount; Index++) {
/*If we find the CPU , then set the Index and break the loop*/
if (InstancePtr->Config.TargetList[Index].Mask == CpuMask) {
BufferIndex = InstancePtr->Config.TargetList[Index].BufferIndex;
break;
}
}
/* Return the Index */
return BufferIndex;
}
/**
* @brief Get the Buffer Address for a given pair of CPUs
*
* @param InstancePtr is the pointer to current IPI instance
* @param SrcCpuMask is the Mask for Source CPU
* @param DestCpuMask is the Mask for Destination CPU
* @param BufferType is either XIPIPSU_BUF_TYPE_MSG or XIPIPSU_BUF_TYPE_RESP
*
* @return Valid Buffer Address if no error
* NULL if an error occurred in calculating Address
*
*/
static u32* XIpiPsu_GetBufferAddress(XIpiPsu *InstancePtr, u32 SrcCpuMask,
u32 DestCpuMask, u32 BufferType)
{
#ifdef __aarch64__
u64 BufferAddr;
#else
u32 BufferAddr;
#endif
u32 SrcIndex;
u32 DestIndex;
/* Get the buffer indices */
SrcIndex = XIpiPsu_GetBufferIndex(InstancePtr, SrcCpuMask);
DestIndex = XIpiPsu_GetBufferIndex(InstancePtr, DestCpuMask);
/* If we got an invalid buffer index, then return NULL pointer, else valid address */
if ((SrcIndex > XIPIPSU_MAX_BUFF_INDEX)
|| (DestIndex > XIPIPSU_MAX_BUFF_INDEX)) {
BufferAddr = 0U;
} else {
if (XIPIPSU_BUF_TYPE_MSG == BufferType) {
BufferAddr = XIPIPSU_MSG_RAM_BASE
+ (SrcIndex * XIPIPSU_BUFFER_OFFSET_GROUP)
+ (DestIndex * XIPIPSU_BUFFER_OFFSET_TARGET);
} else if (XIPIPSU_BUF_TYPE_RESP == BufferType) {
BufferAddr = XIPIPSU_MSG_RAM_BASE
+ (DestIndex * XIPIPSU_BUFFER_OFFSET_GROUP)
+ (SrcIndex * XIPIPSU_BUFFER_OFFSET_TARGET)
+ (XIPIPSU_BUFFER_OFFSET_RESPONSE);
} else {
BufferAddr = 0U;
}
}
return (u32 *) BufferAddr;
}
/**
* @brief Read an Incoming Message from a Source
*
* @param InstancePtr is the pointer to current IPI instance
* @param SrcCpuMask is the Device Mask for the CPU which has sent the message
* @param MsgPtr is the pointer to Buffer to which the read message needs to be stored
* @param MsgLength is the length of the buffer/message
* @param BufType is the type of buffer (XIPIPSU_BUF_TYPE_MSG or XIPIPSU_BUF_TYPE_RESP)
*
* @return XST_SUCCESS if successful
* XST_FAILURE if an error occurred
*/
XStatus XIpiPsu_ReadMessage(XIpiPsu *InstancePtr, u32 TargetMask, u32 *MsgPtr,
u32 MsgLength, u8 BufferType)
{
u32 *BufferPtr;
u32 Index;
u32 Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(MsgPtr != NULL);
Xil_AssertNonvoid(MsgLength <= XIPIPSU_MAX_MSG_LEN);
BufferPtr = XIpiPsu_GetBufferAddress(InstancePtr, TargetMask,
InstancePtr->Config.BitMask, BufferType);
if (BufferPtr != NULL) {
/* Copy the IPI Buffer contents into Users's Buffer*/
for (Index = 0; Index < MsgLength; Index++) {
MsgPtr[Index] = BufferPtr[Index];
}
Status = XST_SUCCESS;
} else {
Status = XST_FAILURE;
}
return Status;
}
/**
* @brief Send a Message to Destination
*
* @param InstancePtr is the pointer to current IPI instance
* @param DestCpuMask is the Device Mask for the destination CPU
* @param MsgPtr is the pointer to Buffer which contains the message to be sent
* @param MsgLength is the length of the buffer/message
* @param BufType is the type of buffer (XIPIPSU_BUF_TYPE_MSG or XIPIPSU_BUF_TYPE_RESP)
*
* @return XST_SUCCESS if successful
* XST_FAILURE if an error occurred
*/
XStatus XIpiPsu_WriteMessage(XIpiPsu *InstancePtr, u32 TargetMask, u32 *MsgPtr,
u32 MsgLength, u8 BufferType)
{
u32 *BufferPtr;
u32 Index;
u32 Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(MsgPtr != NULL);
Xil_AssertNonvoid(MsgLength <= XIPIPSU_MAX_MSG_LEN);
BufferPtr = XIpiPsu_GetBufferAddress(InstancePtr,
InstancePtr->Config.BitMask, TargetMask, BufferType);
if (BufferPtr != NULL) {
/* Copy the Message to IPI Buffer */
for (Index = 0; Index < MsgLength; Index++) {
BufferPtr[Index] = MsgPtr[Index];
}
Status = XST_SUCCESS;
} else {
Status = XST_FAILURE;
}
return Status;
}
/** @} */

View file

@ -0,0 +1,281 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xipipsu.h
* @addtogroup ipipsu_v1_0
* @{
* @details
*
* This is the header file for implementation of IPIPSU driver.
* Inter Processor Interrupt (IPI) is used for communication between
* different processors on ZynqMP SoC. Each IPI register set has Trigger, Status
* and Observation registers for communication between processors. Each IPI path
* has a 32 byte buffer associated with it and these buffers are located in the
* XPPU RAM. This driver supports the following operations:
*
* - Trigger IPIs to CPUs on the SoC
* - Write and Read Message buffers
* - Read the status of Observation Register to get status of Triggered IPI
* - Enable/Disable IPIs from selected Masters
* - Read the Status register to get the source of an incoming IPI
*
* <b>Initialization</b>
* The config data for the driver is loaded and is based on the HW build. The
* XIpiPsu_Config data structure contains all the data related to the
* IPI driver instance and also teh available Target CPUs.
*
* <b>Sending an IPI</b>
* The following steps can be followed to send an IPI:
* - Write the Message into Message Buffer using XIpiPsu_WriteMessage()
* - Trigger IPI using XIpiPsu_TriggerIpi()
* - Wait for Ack using XIpiPsu_PollForAck()
* - Read response using XIpiPsu_ReadMessage()
*
* @note XIpiPsu_GetObsStatus() before sending an IPI to ensure that the
* previous IPI was serviced by the target
*
* <b>Receiving an IPI</b>
* To receive an IPI, the following sequence can be followed:
* - Register an interrupt handler for the IPIs interrupt ID
* - Enable the required sources using XIpiPsu_InterruptEnable()
* - In the interrupt handler, Check for source using XIpiPsu_GetInterruptStatus
* - Read the message form source using XIpiPsu_ReadMessage()
* - Write the response using XIpiPsu_WriteMessage()
* - Ack the IPI using XIpiPsu_ClearInterruptStatus()
*
* @note XIpiPsu_Reset can be used at startup to clear the status and
* disable all sources
*
*/
/*****************************************************************************/
#ifndef XIPIPSU_H_
#define XIPIPSU_H_
/***************************** Include Files *********************************/
#include "xil_io.h"
#include "xstatus.h"
#include "xipipsu_hw.h"
/************************** Constant Definitions *****************************/
#define XIPIPSU_BUF_TYPE_MSG (0x00000001U)
#define XIPIPSU_BUF_TYPE_RESP (0x00000002U)
#define XIPIPSU_MAX_MSG_LEN XIPIPSU_MSG_BUF_SIZE
/**************************** Type Definitions *******************************/
/**
* Data structure used to refer IPI Targets
*/
typedef struct {
u32 Mask; /**< Bit Mask for the target */
u32 BufferIndex; /**< Buffer Index used for calculating buffer address */
} XIpiPsu_Target;
/**
* This typedef contains configuration information for the device.
*/
typedef struct {
u32 DeviceId; /**< Unique ID of device */
u32 BaseAddress; /**< Base address of the device */
u32 BitMask; /**< BitMask to be used to identify this CPU */
u32 BufferIndex; /**< Index of the IPI Message Buffer */
u32 IntId; /**< Interrupt ID on GIC **/
u32 TargetCount; /**< Number of available IPI Targets */
XIpiPsu_Target TargetList[XIPIPSU_MAX_TARGETS] ; /** < List of IPI Targets */
} XIpiPsu_Config;
/**
* The XIpiPsu driver instance data. The user is required to allocate a
* variable of this type for each IPI device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XIpiPsu_Config Config; /**< Configuration structure */
u32 IsReady; /**< Device is initialized and ready */
u32 Options; /**< Options set in the device */
} XIpiPsu;
/***************** Macros (Inline Functions) Definitions *********************/
/**
*
* Read the register specified by the base address and offset
*
* @param BaseAddress is the base address of the IPI instance
* @param RegOffset is the offset of the register relative to base
*
* @return Value of the specified register
* @note
* C-style signature
* u32 XIpiPsu_ReadReg(u32 BaseAddress, u32 RegOffset)
*
*****************************************************************************/
#define XIpiPsu_ReadReg(BaseAddress, RegOffset) \
Xil_In32((BaseAddress) + (RegOffset))
/****************************************************************************/
/**
*
* Write a value into a register specified by base address and offset
*
* @param BaseAddress is the base address of the IPI instance
* @param RegOffset is the offset of the register relative to base
* @param Data is a 32-bit value that is to be written into the specified register
*
* @note
* C-style signature
* void XIpiPsu_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
*
*****************************************************************************/
#define XIpiPsu_WriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32(((BaseAddress) + (RegOffset)), (Data))
/****************************************************************************/
/**
*
* Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
* each bit set to 1 in <i>Mask</i>, will be enabled.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @param Mask contains a bit mask of interrupts to enable. The mask can
* be formed using a set of bitwise or'd values of individual CPU masks
*
* @note
* C-style signature
* void XIpiPsu_InterruptEnable(XIpiPsu *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XIpiPsu_InterruptEnable(InstancePtr, Mask) \
XIpiPsu_WriteReg((InstancePtr)->Config.BaseAddress, \
XIPIPSU_IER_OFFSET, \
((Mask) & XIPIPSU_ALL_MASK));
/****************************************************************************/
/**
*
* Disable interrupts specified in <i>Mask</i>. The corresponding interrupt for
* each bit set to 1 in <i>Mask</i>, will be disabled.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @param Mask contains a bit mask of interrupts to disable. The mask can
* be formed using a set of bitwise or'd values of individual CPU masks
*
* @note
* C-style signature
* void XIpiPsu_InterruptDisable(XIpiPsu *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XIpiPsu_InterruptDisable(InstancePtr, Mask) \
XIpiPsu_WriteReg((InstancePtr)->Config.BaseAddress, \
XIPIPSU_IDR_OFFSET, \
((Mask) & XIPIPSU_ALL_MASK));
/****************************************************************************/
/**
*
* Get the <i>STATUS REGISTER</i> of the current IPI instance.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @return Returns the Interrupt Status register(ISR) contents
* @note User needs to parse this 32-bit value to check the source CPU
* C-style signature
* u32 XIpiPsu_GetInterruptStatus(XIpiPsu *InstancePtr)
*
*****************************************************************************/
#define XIpiPsu_GetInterruptStatus(InstancePtr) \
XIpiPsu_ReadReg((InstancePtr)->Config.BaseAddress, \
XIPIPSU_ISR_OFFSET)
/****************************************************************************/
/**
*
* Clear the <i>STATUS REGISTER</i> of the current IPI instance.
* The corresponding interrupt status for
* each bit set to 1 in <i>Mask</i>, will be cleared
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @param Mask corresponding to the source CPU*
*
* @note This function should be used after handling the IPI.
* Clearing the status will automatically clear the corresponding bit in
* OBSERVATION register of Source CPU
* C-style signature
* void XIpiPsu_ClearInterruptStatus(XIpiPsu *InstancePtr, u32 Mask)
*
*****************************************************************************/
#define XIpiPsu_ClearInterruptStatus(InstancePtr, Mask) \
XIpiPsu_WriteReg((InstancePtr)->Config.BaseAddress, \
XIPIPSU_ISR_OFFSET, \
((Mask) & XIPIPSU_ALL_MASK));
/****************************************************************************/
/**
*
* Get the <i>OBSERVATION REGISTER</i> of the current IPI instance.
*
* @param InstancePtr is a pointer to the instance to be worked on.
* @return Returns the Observation register(OBS) contents
* @note User needs to parse this 32-bit value to check the status of
* individual CPUs
* C-style signature
* u32 XIpiPsu_GetObsStatus(XIpiPsu *InstancePtr)
*
*****************************************************************************/
#define XIpiPsu_GetObsStatus(InstancePtr) \
XIpiPsu_ReadReg((InstancePtr)->Config.BaseAddress, \
XIPIPSU_OBS_OFFSET)
/****************************************************************************/
/************************** Function Prototypes *****************************/
/* Static lookup function implemented in xipipsu_sinit.c */
XIpiPsu_Config *XIpiPsu_LookupConfig(u32 DeviceId);
/* Interface Functions implemented in xipipsu.c */
XStatus XIpiPsu_CfgInitialize(XIpiPsu *InstancePtr, XIpiPsu_Config * CfgPtr,
UINTPTR EffectiveAddress);
void XIpiPsu_Reset(XIpiPsu *InstancePtr);
XStatus XIpiPsu_TriggerIpi(XIpiPsu *InstancePtr, u32 DestCpuMask);
XStatus XIpiPsu_PollForAck(XIpiPsu *InstancePtr, u32 DestCpuMask,
u32 TimeOutCount);
XStatus XIpiPsu_ReadMessage(XIpiPsu *InstancePtr, u32 SrcCpuMask, u32 *MsgPtr,
u32 MsgLength, u8 BufType);
XStatus XIpiPsu_WriteMessage(XIpiPsu *InstancePtr, u32 DestCpuMask, u32 *MsgPtr,
u32 MsgLength, u8 BufType);
#endif /* XIPIPSU_H_ */
/** @} */

View file

@ -0,0 +1,161 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the Software), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in
*all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
*(a) running on a Xilinx device, or
*(b) that interact with a Xilinx device through a bus or interconnect.
*
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the Xilinx shall not be used
*in advertising or otherwise to promote the sale, use or other dealings in
*this Software without prior written authorization from Xilinx.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xipipsu.h"
/*
* The configuration table for devices
*/
XIpiPsu_Config XIpiPsu_ConfigTable[] =
{
{
XPAR_PSU_IPI_1_DEVICE_ID,
XPAR_PSU_IPI_1_BASE_ADDRESS,
XPAR_PSU_IPI_1_BIT_MASK,
XPAR_PSU_IPI_1_BUFFER_INDEX,
XPAR_PSU_IPI_1_INT_ID,
XPAR_XIPIPSU_NUM_TARGETS,
{
{
XPAR_PSU_IPI_0_BIT_MASK,
XPAR_PSU_IPI_0_BUFFER_INDEX
},
{
XPAR_PSU_IPI_1_BIT_MASK,
XPAR_PSU_IPI_1_BUFFER_INDEX
},
{
XPAR_PSU_IPI_2_BIT_MASK,
XPAR_PSU_IPI_2_BUFFER_INDEX
},
{
XPAR_PSU_IPI_3_BIT_MASK,
XPAR_PSU_IPI_3_BUFFER_INDEX
},
{
XPAR_PSU_IPI_4_BIT_MASK,
XPAR_PSU_IPI_4_BUFFER_INDEX
},
{
XPAR_PSU_IPI_5_BIT_MASK,
XPAR_PSU_IPI_5_BUFFER_INDEX
},
{
XPAR_PSU_IPI_6_BIT_MASK,
XPAR_PSU_IPI_6_BUFFER_INDEX
},
{
XPAR_PSU_IPI_7_BIT_MASK,
XPAR_PSU_IPI_7_BUFFER_INDEX
},
{
XPAR_PSU_IPI_8_BIT_MASK,
XPAR_PSU_IPI_8_BUFFER_INDEX
},
{
XPAR_PSU_IPI_9_BIT_MASK,
XPAR_PSU_IPI_9_BUFFER_INDEX
},
{
XPAR_PSU_IPI_10_BIT_MASK,
XPAR_PSU_IPI_10_BUFFER_INDEX
}
}
},
{
XPAR_PSU_IPI_2_DEVICE_ID,
XPAR_PSU_IPI_2_BASE_ADDRESS,
XPAR_PSU_IPI_2_BIT_MASK,
XPAR_PSU_IPI_2_BUFFER_INDEX,
XPAR_PSU_IPI_2_INT_ID,
XPAR_XIPIPSU_NUM_TARGETS,
{
{
XPAR_PSU_IPI_0_BIT_MASK,
XPAR_PSU_IPI_0_BUFFER_INDEX
},
{
XPAR_PSU_IPI_1_BIT_MASK,
XPAR_PSU_IPI_1_BUFFER_INDEX
},
{
XPAR_PSU_IPI_2_BIT_MASK,
XPAR_PSU_IPI_2_BUFFER_INDEX
},
{
XPAR_PSU_IPI_3_BIT_MASK,
XPAR_PSU_IPI_3_BUFFER_INDEX
},
{
XPAR_PSU_IPI_4_BIT_MASK,
XPAR_PSU_IPI_4_BUFFER_INDEX
},
{
XPAR_PSU_IPI_5_BIT_MASK,
XPAR_PSU_IPI_5_BUFFER_INDEX
},
{
XPAR_PSU_IPI_6_BIT_MASK,
XPAR_PSU_IPI_6_BUFFER_INDEX
},
{
XPAR_PSU_IPI_7_BIT_MASK,
XPAR_PSU_IPI_7_BUFFER_INDEX
},
{
XPAR_PSU_IPI_8_BIT_MASK,
XPAR_PSU_IPI_8_BUFFER_INDEX
},
{
XPAR_PSU_IPI_9_BIT_MASK,
XPAR_PSU_IPI_9_BUFFER_INDEX
},
{
XPAR_PSU_IPI_10_BIT_MASK,
XPAR_PSU_IPI_10_BUFFER_INDEX
}
}
}
};

View file

@ -0,0 +1,79 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/**
*
* @file xipipsu_hw.h
* @addtogroup ipipsu_v1_0
* @{
*
* This file contains macro definitions for low level HW related params
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- -----------------------------------------------.
* 1.0 mjr 03/15/15 First release
*
* </pre>
*
******************************************************************************/
#ifndef XIPIPSU_HW_H_ /* prevent circular inclusions */
#define XIPIPSU_HW_H_ /* by using protection macros */
/************************** Constant Definitions *****************************/
/* Message RAM related params */
#define XIPIPSU_MSG_RAM_BASE 0xFF990000U
#define XIPIPSU_MSG_BUF_SIZE 8U /* Size in Words */
#define XIPIPSU_MAX_BUFF_INDEX 7
/* EIGHT pairs of TWO buffers(msg+resp) of THIRTY TWO bytes each */
#define XIPIPSU_BUFFER_OFFSET_GROUP (8U * 2U * 32U)
#define XIPIPSU_BUFFER_OFFSET_TARGET (32U * 2U)
#define XIPIPSU_BUFFER_OFFSET_RESPONSE (32U)
/* Max Number of IPI slots on the device */
#define XIPIPSU_MAX_TARGETS 11
/* Register Offsets for each member of IPI Register Set */
#define XIPIPSU_TRIG_OFFSET 0x00U
#define XIPIPSU_OBS_OFFSET 0x04U
#define XIPIPSU_ISR_OFFSET 0x10U
#define XIPIPSU_IMR_OFFSET 0x14U
#define XIPIPSU_IER_OFFSET 0x18U
#define XIPIPSU_IDR_OFFSET 0x1CU
/* MASK of all valid IPI bits in above registers */
#define XIPIPSU_ALL_MASK 0x0F0F0301U
#endif /* XIPIPSU_HW_H_ */
/** @} */

View file

@ -0,0 +1,90 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/**
*
* @file xipipsu_sinit.c
* @addtogroup ipipsu_v1_0
* @{
*
* The implementation of the XIpiPsu component's static initialization
* functionality.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- -----------------------------------------------
* 1.0 mjr 03/15/15 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xparameters.h"
#include "xipipsu.h"
/************************** Variable Definitions *****************************/
extern XIpiPsu_Config XIpiPsu_ConfigTable[];
/*****************************************************************************/
/**
*
* Looks up the device configuration based on the unique device ID. A table
* contains the configuration info for each device in the system.
*
* @param DeviceId contains the ID of the device to look up the
* configuration for.
*
* @return A pointer to the configuration found or NULL if the specified
* device ID was not found. See xipipsu.h for the definition of
* XIpiPsu_Config.
*
* @note None.
*
******************************************************************************/
XIpiPsu_Config *XIpiPsu_LookupConfig(u32 DeviceId)
{
XIpiPsu_Config *CfgPtr = NULL;
int Index;
for (Index = 0; Index < XPAR_XIPIPSU_NUM_INSTANCES; Index++) {
if (XIpiPsu_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XIpiPsu_ConfigTable[Index];
break;
}
}
return CfgPtr;
}
/** @} */

View file

@ -0,0 +1,40 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner xqspipsu_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling qspipsu"
xqspipsu_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: xqspipsu_includes
xqspipsu_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

View file

@ -0,0 +1,272 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xqspipsu.h
* @addtogroup qspipsu_v1_0
* @{
* @details
*
* This is the header file for the implementation of QSPIPSU driver.
* Generic QSPI interface allows for communication to any QSPI slave device.
* GQSPI contains a GENFIFO into which the bus transfers required are to be
* pushed with appropriate configuration. The controller provides TX and RX
* FIFO's and a DMA to be used for RX transfers. The controller executes each
* GENFIFO entry noting the configuration and places data on the bus as required
*
* The different options in GENFIFO are as follows:
* IMM_DATA : Can be one byte of data to be transmitted, number of clocks or
* number of bytes in transfer.
* DATA_XFER : Indicates that data/clocks need to be transmitted or received.
* EXPONENT : e when 2^e bytes are involved in transfer.
* SPI_MODE : SPI/Dual SPI/Quad SPI
* CS : Lower or Upper CS or Both
* Bus : Lower or Upper Bus or Both
* TX : When selected, controller transmits data in IMM or fetches number of
* bytes mentioned form TX FIFO. If not selected, dummies are pumped.
* RX : When selected, controller receives and fills the RX FIFO/allows RX DMA
* of requested number of bytes. If not selected, RX data is discarded.
* Stripe : Byte stripe over lower and upper bus or not.
* Poll : Polls response to match for to a set value (used along with POLL_CFG
* registers) and then proceeds to next GENFIFO entry.
* This feature is not currently used in the driver.
*
* GENFIFO has manual and auto start options.
* All DMA requests need a 4-byte aligned destination address buffer and
* size of transfer should also be a multiple of 4.
* This driver supports DMA RX and IO RX.
*
* Initialization:
* This driver uses the GQSPI controller with RX DMA. It supports both
* interrupt and polled transfers. Manual start of GENFIFO is used.
* XQspiPsu_CfgInitialize() initializes the instance variables.
* Additional setting can be done using SetOptions/ClearOptions functions
* and SelectSlave function.
*
* Transfer:
* Polled or Interrupt transfers can be done. The transfer function needs the
* message(s) to be transmitted in the form of an array of type XQspiPsu_Msg.
* This is supposed to contain the byte count and any TX/RX buffers as required.
* Flags can be used indicate further information such as whether the message
* should be striped. The transfer functions form and write GENFIFO entries,
* check the status of the transfer and report back to the application
* when done.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- -----------------------------------------------.
* 1.0 hk 08/21/14 First release
* sk 03/13/15 Added IO mode support.
* hk 03/18/15 Switch to I/O mode before clearing RX FIFO.
* Clear and disbale DMA interrupts/status in abort.
* Use DMA DONE bit instead of BUSY as recommended.
* sk 04/24/15 Modified the code according to MISRAC-2012.
* sk 06/17/15 Removed NULL checks for Rx/Tx buffers. As
* writing/reading from 0x0 location is permitted.
*
* </pre>
*
******************************************************************************/
#ifndef XQSPIPSU_H_ /* prevent circular inclusions */
#define XQSPIPSU_H_ /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xstatus.h"
#include "xqspipsu_hw.h"
#include "xil_cache.h"
/**************************** Type Definitions *******************************/
/**
* The handler data type allows the user to define a callback function to
* handle the asynchronous processing for the QSPIPSU device. The application
* using this driver is expected to define a handler of this type to support
* interrupt driven mode. The handler executes in an interrupt context, so
* only minimal processing should be performed.
*
* @param CallBackRef is the callback reference passed in by the upper
* layer when setting the callback functions, and passed back to
* the upper layer when the callback is invoked. Its type is
* not important to the driver, so it is a void pointer.
* @param StatusEvent holds one or more status events that have occurred.
* See the XQspiPsu_SetStatusHandler() for details on the status
* events that can be passed in the callback.
* @param ByteCount indicates how many bytes of data were successfully
* transferred. This may be less than the number of bytes
* requested if the status event indicates an error.
*/
typedef void (*XQspiPsu_StatusHandler) (void *CallBackRef, u32 StatusEvent,
u32 ByteCount);
/**
* This typedef contains configuration information for a flash message.
*/
typedef struct {
u8 *TxBfrPtr;
u8 *RxBfrPtr;
u32 ByteCount;
u32 BusWidth;
u32 Flags;
} XQspiPsu_Msg;
/**
* This typedef contains configuration information for the device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddress; /**< Base address of the device */
u32 InputClockHz; /**< Input clock frequency */
u8 ConnectionMode; /**< Single, Stacked and Parallel mode */
u8 BusWidth; /**< Bus width available on board */
} XQspiPsu_Config;
/**
* The XQspiPsu driver instance data. The user is required to allocate a
* variable of this type for every QSPIPSU device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XQspiPsu_Config Config; /**< Configuration structure */
u32 IsReady; /**< Device is initialized and ready */
u8 *SendBufferPtr; /**< Buffer to send (state) */
u8 *RecvBufferPtr; /**< Buffer to receive (state) */
u8 *GenFifoBufferPtr; /**< Gen FIFO entries */
s32 TxBytes; /**< Number of bytes to transfer (state) */
s32 RxBytes; /**< Number of bytes left to transfer(state) */
s32 GenFifoEntries; /**< Number of Gen FIFO entries remaining */
u32 IsBusy; /**< A transfer is in progress (state) */
u32 ReadMode; /**< DMA or IO mode */
u32 GenFifoCS;
u32 GenFifoBus;
s32 NumMsg;
s32 MsgCnt;
s32 IsUnaligned;
u8 IsManualstart;
XQspiPsu_Msg *Msg;
XQspiPsu_StatusHandler StatusHandler;
void *StatusRef; /**< Callback reference for status handler */
} XQspiPsu;
/***************** Macros (Inline Functions) Definitions *********************/
#define XQSPIPSU_READMODE_DMA 0x0U
#define XQSPIPSU_READMODE_IO 0x1U
#define XQSPIPSU_SELECT_FLASH_CS_LOWER 0x1U
#define XQSPIPSU_SELECT_FLASH_CS_UPPER 0x2U
#define XQSPIPSU_SELECT_FLASH_CS_BOTH 0x3U
#define XQSPIPSU_SELECT_FLASH_BUS_LOWER 0x1U
#define XQSPIPSU_SELECT_FLASH_BUS_UPPER 0x2U
#define XQSPIPSU_SELECT_FLASH_BUS_BOTH 0x3U
#define XQSPIPSU_SELECT_MODE_SPI 0x1U
#define XQSPIPSU_SELECT_MODE_DUALSPI 0x2U
#define XQSPIPSU_SELECT_MODE_QUADSPI 0x4U
#define XQSPIPSU_GENFIFO_CS_SETUP 0x05U
#define XQSPIPSU_GENFIFO_CS_HOLD 0x04U
#define XQSPIPSU_CLK_ACTIVE_LOW_OPTION 0x2U
#define XQSPIPSU_CLK_PHASE_1_OPTION 0x4U
#define XQSPIPSU_MANUAL_START_OPTION 0x8U
#define XQSPIPSU_GENFIFO_EXP_START 0x100U
#define XQSPIPSU_DMA_BYTES_MAX 0x10000000U
#define XQSPIPSU_CLK_PRESCALE_2 0x00U
#define XQSPIPSU_CLK_PRESCALE_4 0x01U
#define XQSPIPSU_CLK_PRESCALE_8 0x02U
#define XQSPIPSU_CLK_PRESCALE_16 0x03U
#define XQSPIPSU_CLK_PRESCALE_32 0x04U
#define XQSPIPSU_CLK_PRESCALE_64 0x05U
#define XQSPIPSU_CLK_PRESCALE_128 0x06U
#define XQSPIPSU_CLK_PRESCALE_256 0x07U
#define XQSPIPSU_CR_PRESC_MAXIMUM 7U
#define XQSPIPSU_CONNECTION_MODE_SINGLE 0U
#define XQSPIPSU_CONNECTION_MODE_STACKED 1U
#define XQSPIPSU_CONNECTION_MODE_PARALLEL 2U
/* Add more flags as required */
#define XQSPIPSU_MSG_FLAG_STRIPE 0x1U
#define XQSPIPSU_MSG_FLAG_RX 0x2U
#define XQSPIPSU_MSG_FLAG_TX 0x4U
#define XQspiPsu_Select(InstancePtr) XQspiPsu_Out32(((InstancePtr)->Config.BaseAddress) + XQSPIPSU_SEL_OFFSET, XQSPIPSU_SEL_MASK)
#define XQspiPsu_Enable(InstancePtr) XQspiPsu_Out32(((InstancePtr)->Config.BaseAddress) + XQSPIPSU_EN_OFFSET, XQSPIPSU_EN_MASK)
#define XQspiPsu_Disable(InstancePtr) XQspiPsu_Out32(((InstancePtr)->Config.BaseAddress) + XQSPIPSU_EN_OFFSET, 0x0U)
/************************** Function Prototypes ******************************/
/* Initialization and reset */
XQspiPsu_Config *XQspiPsu_LookupConfig(u16 DeviceId);
s32 XQspiPsu_CfgInitialize(XQspiPsu *InstancePtr, XQspiPsu_Config *ConfigPtr,
u32 EffectiveAddr);
void XQspiPsu_Reset(XQspiPsu *InstancePtr);
void XQspiPsu_Abort(XQspiPsu *InstancePtr);
/* Transfer functions and handlers */
s32 XQspiPsu_PolledTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
u32 NumMsg);
s32 XQspiPsu_InterruptTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
u32 NumMsg);
s32 XQspiPsu_InterruptHandler(XQspiPsu *InstancePtr);
void XQspiPsu_SetStatusHandler(XQspiPsu *InstancePtr, void *CallBackRef,
XQspiPsu_StatusHandler FuncPointer);
/* Configuration functions */
s32 XQspiPsu_SetClkPrescaler(XQspiPsu *InstancePtr, u8 Prescaler);
void XQspiPsu_SelectFlash(XQspiPsu *InstancePtr, u8 FlashCS, u8 FlashBus);
s32 XQspiPsu_SetOptions(XQspiPsu *InstancePtr, u32 Options);
s32 XQspiPsu_ClearOptions(XQspiPsu *InstancePtr, u32 Options);
u32 XQspiPsu_GetOptions(XQspiPsu *InstancePtr);
s32 XQspiPsu_SetReadMode(XQspiPsu *InstancePtr, u32 Mode);
#ifdef __cplusplus
}
#endif
#endif /* XQSPIPSU_H_ */
/** @} */

View file

@ -0,0 +1,58 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version:
* DO NOT EDIT.
*
* Copyright (C) 2010-2016 Xilinx, Inc. All Rights Reserved.*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the Software), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in
*all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
*(a) running on a Xilinx device, or
*(b) that interact with a Xilinx device through a bus or interconnect.
*
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the Xilinx shall not be used
*in advertising or otherwise to promote the sale, use or other dealings in
*this Software without prior written authorization from Xilinx.
*
*
* Description: Driver configuration
*
*******************************************************************/
#include "xparameters.h"
#include "xqspipsu.h"
/*
* The configuration table for devices
*/
XQspiPsu_Config XQspiPsu_ConfigTable[] =
{
{
XPAR_PSU_QSPI_0_DEVICE_ID,
XPAR_PSU_QSPI_0_BASEADDR,
XPAR_PSU_QSPI_0_QSPI_CLK_FREQ_HZ,
XPAR_PSU_QSPI_0_QSPI_MODE,
XPAR_PSU_QSPI_0_QSPI_BUS_WIDTH
}
};

View file

@ -0,0 +1,841 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xqspipsu_hw.h
* @addtogroup qspipsu_v1_0
* @{
*
* This file contains low level access funcitons using the base address
* directly without an instance.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- -----------------------------------------------.
* 1.0 hk 08/21/14 First release
* hk 03/18/15 Add DMA status register masks required.
* sk 04/24/15 Modified the code according to MISRAC-2012.
*
* </pre>
*
******************************************************************************/
#ifndef _XQSPIPSU_HW_H_ /* prevent circular inclusions */
#define _XQSPIPSU_HW_H_ /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**
* QSPI Base Address
*/
#define XQSPIPS_BASEADDR 0XFF0F0000U
/**
* GQSPI Base Address
*/
#define XQSPIPSU_BASEADDR 0xFF0F0100U
#define XQSPIPSU_OFFSET 0x100U
/**
* Register: XQSPIPS_EN_REG
*/
#define XQSPIPS_EN_REG ( ( XQSPIPS_BASEADDR ) + 0X00000014U )
#define XQSPIPS_EN_SHIFT 0
#define XQSPIPS_EN_WIDTH 1
#define XQSPIPS_EN_MASK 0X00000001U
/**
* Register: XQSPIPSU_CFG
*/
#define XQSPIPSU_CFG_OFFSET 0X00000000U
#define XQSPIPSU_CFG_MODE_EN_SHIFT 30
#define XQSPIPSU_CFG_MODE_EN_WIDTH 2
#define XQSPIPSU_CFG_MODE_EN_MASK 0XC0000000U
#define XQSPIPSU_CFG_MODE_EN_DMA_MASK 0X80000000U
#define XQSPIPSU_CFG_GEN_FIFO_START_MODE_SHIFT 29
#define XQSPIPSU_CFG_GEN_FIFO_START_MODE_WIDTH 1
#define XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK 0X20000000U
#define XQSPIPSU_CFG_START_GEN_FIFO_SHIFT 28
#define XQSPIPSU_CFG_START_GEN_FIFO_WIDTH 1
#define XQSPIPSU_CFG_START_GEN_FIFO_MASK 0X10000000U
#define XQSPIPSU_CFG_ENDIAN_SHIFT 26
#define XQSPIPSU_CFG_ENDIAN_WIDTH 1
#define XQSPIPSU_CFG_ENDIAN_MASK 0X04000000U
#define XQSPIPSU_CFG_EN_POLL_TO_SHIFT 20
#define XQSPIPSU_CFG_EN_POLL_TO_WIDTH 1
#define XQSPIPSU_CFG_EN_POLL_TO_MASK 0X00100000U
#define XQSPIPSU_CFG_WP_HOLD_SHIFT 19
#define XQSPIPSU_CFG_WP_HOLD_WIDTH 1
#define XQSPIPSU_CFG_WP_HOLD_MASK 0X00080000U
#define XQSPIPSU_CFG_BAUD_RATE_DIV_SHIFT 3
#define XQSPIPSU_CFG_BAUD_RATE_DIV_WIDTH 3
#define XQSPIPSU_CFG_BAUD_RATE_DIV_MASK 0X00000038U
#define XQSPIPSU_CFG_CLK_PHA_SHIFT 2
#define XQSPIPSU_CFG_CLK_PHA_WIDTH 1
#define XQSPIPSU_CFG_CLK_PHA_MASK 0X00000004U
#define XQSPIPSU_CFG_CLK_POL_SHIFT 1
#define XQSPIPSU_CFG_CLK_POL_WIDTH 1
#define XQSPIPSU_CFG_CLK_POL_MASK 0X00000002U
/**
* Register: XQSPIPSU_ISR
*/
#define XQSPIPSU_ISR_OFFSET 0X00000004U
#define XQSPIPSU_ISR_RXEMPTY_SHIFT 11
#define XQSPIPSU_ISR_RXEMPTY_WIDTH 1
#define XQSPIPSU_ISR_RXEMPTY_MASK 0X00000800U
#define XQSPIPSU_ISR_GENFIFOFULL_SHIFT 10
#define XQSPIPSU_ISR_GENFIFOFULL_WIDTH 1
#define XQSPIPSU_ISR_GENFIFOFULL_MASK 0X00000400U
#define XQSPIPSU_ISR_GENFIFONOT_FULL_SHIFT 9
#define XQSPIPSU_ISR_GENFIFONOT_FULL_WIDTH 1
#define XQSPIPSU_ISR_GENFIFONOT_FULL_MASK 0X00000200U
#define XQSPIPSU_ISR_TXEMPTY_SHIFT 8
#define XQSPIPSU_ISR_TXEMPTY_WIDTH 1
#define XQSPIPSU_ISR_TXEMPTY_MASK 0X00000100U
#define XQSPIPSU_ISR_GENFIFOEMPTY_SHIFT 7
#define XQSPIPSU_ISR_GENFIFOEMPTY_WIDTH 1
#define XQSPIPSU_ISR_GENFIFOEMPTY_MASK 0X00000080U
#define XQSPIPSU_ISR_RXFULL_SHIFT 5
#define XQSPIPSU_ISR_RXFULL_WIDTH 1
#define XQSPIPSU_ISR_RXFULL_MASK 0X00000020U
#define XQSPIPSU_ISR_RXNEMPTY_SHIFT 4
#define XQSPIPSU_ISR_RXNEMPTY_WIDTH 1
#define XQSPIPSU_ISR_RXNEMPTY_MASK 0X00000010U
#define XQSPIPSU_ISR_TXFULL_SHIFT 3
#define XQSPIPSU_ISR_TXFULL_WIDTH 1
#define XQSPIPSU_ISR_TXFULL_MASK 0X00000008U
#define XQSPIPSU_ISR_TXNOT_FULL_SHIFT 2
#define XQSPIPSU_ISR_TXNOT_FULL_WIDTH 1
#define XQSPIPSU_ISR_TXNOT_FULL_MASK 0X00000004U
#define XQSPIPSU_ISR_POLL_TIME_EXPIRE_SHIFT 1
#define XQSPIPSU_ISR_POLL_TIME_EXPIRE_WIDTH 1
#define XQSPIPSU_ISR_POLL_TIME_EXPIRE_MASK 0X00000002U
#define XQSPIPSU_ISR_WR_TO_CLR_MASK 0X00000002U
/**
* Register: XQSPIPSU_IER
*/
#define XQSPIPSU_IER_OFFSET 0X00000008U
#define XQSPIPSU_IER_RXEMPTY_SHIFT 11
#define XQSPIPSU_IER_RXEMPTY_WIDTH 1
#define XQSPIPSU_IER_RXEMPTY_MASK 0X00000800U
#define XQSPIPSU_IER_GENFIFOFULL_SHIFT 10
#define XQSPIPSU_IER_GENFIFOFULL_WIDTH 1
#define XQSPIPSU_IER_GENFIFOFULL_MASK 0X00000400U
#define XQSPIPSU_IER_GENFIFONOT_FULL_SHIFT 9
#define XQSPIPSU_IER_GENFIFONOT_FULL_WIDTH 1
#define XQSPIPSU_IER_GENFIFONOT_FULL_MASK 0X00000200U
#define XQSPIPSU_IER_TXEMPTY_SHIFT 8
#define XQSPIPSU_IER_TXEMPTY_WIDTH 1
#define XQSPIPSU_IER_TXEMPTY_MASK 0X00000100U
#define XQSPIPSU_IER_GENFIFOEMPTY_SHIFT 7
#define XQSPIPSU_IER_GENFIFOEMPTY_WIDTH 1
#define XQSPIPSU_IER_GENFIFOEMPTY_MASK 0X00000080U
#define XQSPIPSU_IER_RXFULL_SHIFT 5
#define XQSPIPSU_IER_RXFULL_WIDTH 1
#define XQSPIPSU_IER_RXFULL_MASK 0X00000020U
#define XQSPIPSU_IER_RXNEMPTY_SHIFT 4
#define XQSPIPSU_IER_RXNEMPTY_WIDTH 1
#define XQSPIPSU_IER_RXNEMPTY_MASK 0X00000010U
#define XQSPIPSU_IER_TXFULL_SHIFT 3
#define XQSPIPSU_IER_TXFULL_WIDTH 1
#define XQSPIPSU_IER_TXFULL_MASK 0X00000008U
#define XQSPIPSU_IER_TXNOT_FULL_SHIFT 2
#define XQSPIPSU_IER_TXNOT_FULL_WIDTH 1
#define XQSPIPSU_IER_TXNOT_FULL_MASK 0X00000004U
#define XQSPIPSU_IER_POLL_TIME_EXPIRE_SHIFT 1
#define XQSPIPSU_IER_POLL_TIME_EXPIRE_WIDTH 1
#define XQSPIPSU_IER_POLL_TIME_EXPIRE_MASK 0X00000002U
/**
* Register: XQSPIPSU_IDR
*/
#define XQSPIPSU_IDR_OFFSET 0X0000000CU
#define XQSPIPSU_IDR_RXEMPTY_SHIFT 11
#define XQSPIPSU_IDR_RXEMPTY_WIDTH 1
#define XQSPIPSU_IDR_RXEMPTY_MASK 0X00000800U
#define XQSPIPSU_IDR_GENFIFOFULL_SHIFT 10
#define XQSPIPSU_IDR_GENFIFOFULL_WIDTH 1
#define XQSPIPSU_IDR_GENFIFOFULL_MASK 0X00000400U
#define XQSPIPSU_IDR_GENFIFONOT_FULL_SHIFT 9
#define XQSPIPSU_IDR_GENFIFONOT_FULL_WIDTH 1
#define XQSPIPSU_IDR_GENFIFONOT_FULL_MASK 0X00000200U
#define XQSPIPSU_IDR_TXEMPTY_SHIFT 8
#define XQSPIPSU_IDR_TXEMPTY_WIDTH 1
#define XQSPIPSU_IDR_TXEMPTY_MASK 0X00000100U
#define XQSPIPSU_IDR_GENFIFOEMPTY_SHIFT 7
#define XQSPIPSU_IDR_GENFIFOEMPTY_WIDTH 1
#define XQSPIPSU_IDR_GENFIFOEMPTY_MASK 0X00000080U
#define XQSPIPSU_IDR_RXFULL_SHIFT 5
#define XQSPIPSU_IDR_RXFULL_WIDTH 1
#define XQSPIPSU_IDR_RXFULL_MASK 0X00000020U
#define XQSPIPSU_IDR_RXNEMPTY_SHIFT 4
#define XQSPIPSU_IDR_RXNEMPTY_WIDTH 1
#define XQSPIPSU_IDR_RXNEMPTY_MASK 0X00000010U
#define XQSPIPSU_IDR_TXFULL_SHIFT 3
#define XQSPIPSU_IDR_TXFULL_WIDTH 1
#define XQSPIPSU_IDR_TXFULL_MASK 0X00000008U
#define XQSPIPSU_IDR_TXNOT_FULL_SHIFT 2
#define XQSPIPSU_IDR_TXNOT_FULL_WIDTH 1
#define XQSPIPSU_IDR_TXNOT_FULL_MASK 0X00000004U
#define XQSPIPSU_IDR_POLL_TIME_EXPIRE_SHIFT 1
#define XQSPIPSU_IDR_POLL_TIME_EXPIRE_WIDTH 1
#define XQSPIPSU_IDR_POLL_TIME_EXPIRE_MASK 0X00000002U
#define XQSPIPSU_IDR_ALL_MASK 0X0FBEU
/**
* Register: XQSPIPSU_IMR
*/
#define XQSPIPSU_IMR_OFFSET 0X00000010U
#define XQSPIPSU_IMR_RXEMPTY_SHIFT 11
#define XQSPIPSU_IMR_RXEMPTY_WIDTH 1
#define XQSPIPSU_IMR_RXEMPTY_MASK 0X00000800U
#define XQSPIPSU_IMR_GENFIFOFULL_SHIFT 10
#define XQSPIPSU_IMR_GENFIFOFULL_WIDTH 1
#define XQSPIPSU_IMR_GENFIFOFULL_MASK 0X00000400U
#define XQSPIPSU_IMR_GENFIFONOT_FULL_SHIFT 9
#define XQSPIPSU_IMR_GENFIFONOT_FULL_WIDTH 1
#define XQSPIPSU_IMR_GENFIFONOT_FULL_MASK 0X00000200U
#define XQSPIPSU_IMR_TXEMPTY_SHIFT 8
#define XQSPIPSU_IMR_TXEMPTY_WIDTH 1
#define XQSPIPSU_IMR_TXEMPTY_MASK 0X00000100U
#define XQSPIPSU_IMR_GENFIFOEMPTY_SHIFT 7
#define XQSPIPSU_IMR_GENFIFOEMPTY_WIDTH 1
#define XQSPIPSU_IMR_GENFIFOEMPTY_MASK 0X00000080U
#define XQSPIPSU_IMR_RXFULL_SHIFT 5
#define XQSPIPSU_IMR_RXFULL_WIDTH 1
#define XQSPIPSU_IMR_RXFULL_MASK 0X00000020U
#define XQSPIPSU_IMR_RXNEMPTY_SHIFT 4
#define XQSPIPSU_IMR_RXNEMPTY_WIDTH 1
#define XQSPIPSU_IMR_RXNEMPTY_MASK 0X00000010U
#define XQSPIPSU_IMR_TXFULL_SHIFT 3
#define XQSPIPSU_IMR_TXFULL_WIDTH 1
#define XQSPIPSU_IMR_TXFULL_MASK 0X00000008U
#define XQSPIPSU_IMR_TXNOT_FULL_SHIFT 2
#define XQSPIPSU_IMR_TXNOT_FULL_WIDTH 1
#define XQSPIPSU_IMR_TXNOT_FULL_MASK 0X00000004U
#define XQSPIPSU_IMR_POLL_TIME_EXPIRE_SHIFT 1
#define XQSPIPSU_IMR_POLL_TIME_EXPIRE_WIDTH 1
#define XQSPIPSU_IMR_POLL_TIME_EXPIRE_MASK 0X00000002U
/**
* Register: XQSPIPSU_EN_REG
*/
#define XQSPIPSU_EN_OFFSET 0X00000014U
#define XQSPIPSU_EN_SHIFT 0
#define XQSPIPSU_EN_WIDTH 1
#define XQSPIPSU_EN_MASK 0X00000001U
/**
* Register: XQSPIPSU_TXD
*/
#define XQSPIPSU_TXD_OFFSET 0X0000001CU
#define XQSPIPSU_TXD_SHIFT 0
#define XQSPIPSU_TXD_WIDTH 32
#define XQSPIPSU_TXD_MASK 0XFFFFFFFFU
#define XQSPIPSU_TXD_DEPTH 64
/**
* Register: XQSPIPSU_RXD
*/
#define XQSPIPSU_RXD_OFFSET 0X00000020U
#define XQSPIPSU_RXD_SHIFT 0
#define XQSPIPSU_RXD_WIDTH 32
#define XQSPIPSU_RXD_MASK 0XFFFFFFFFU
/**
* Register: XQSPIPSU_TX_THRESHOLD
*/
#define XQSPIPSU_TX_THRESHOLD_OFFSET 0X00000028U
#define XQSPIPSU_TX_FIFO_THRESHOLD_SHIFT 0
#define XQSPIPSU_TX_FIFO_THRESHOLD_WIDTH 6
#define XQSPIPSU_TX_FIFO_THRESHOLD_MASK 0X0000003FU
#define XQSPIPSU_TX_FIFO_THRESHOLD_RESET_VAL 0X01U
/**
* Register: XQSPIPSU_RX_THRESHOLD
*/
#define XQSPIPSU_RX_THRESHOLD_OFFSET 0X0000002CU
#define XQSPIPSU_RX_FIFO_THRESHOLD_SHIFT 0
#define XQSPIPSU_RX_FIFO_THRESHOLD_WIDTH 6
#define XQSPIPSU_RX_FIFO_THRESHOLD_MASK 0X0000003FU
#define XQSPIPSU_RX_FIFO_THRESHOLD_RESET_VAL 0X01U
#define XQSPIPSU_RXFIFO_THRESHOLD_OPT 32U
/**
* Register: XQSPIPSU_GPIO
*/
#define XQSPIPSU_GPIO_OFFSET 0X00000030U
#define XQSPIPSU_GPIO_WP_N_SHIFT 0
#define XQSPIPSU_GPIO_WP_N_WIDTH 1
#define XQSPIPSU_GPIO_WP_N_MASK 0X00000001U
/**
* Register: XQSPIPSU_LPBK_DLY_ADJ
*/
#define XQSPIPSU_LPBK_DLY_ADJ_OFFSET 0X00000038U
#define XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_SHIFT 5
#define XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_WIDTH 1
#define XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_MASK 0X00000020U
#define XQSPIPSU_LPBK_DLY_ADJ_DLY1_SHIFT 3
#define XQSPIPSU_LPBK_DLY_ADJ_DLY1_WIDTH 2
#define XQSPIPSU_LPBK_DLY_ADJ_DLY1_MASK 0X00000018U
#define XQSPIPSU_LPBK_DLY_ADJ_DLY0_SHIFT 0
#define XQSPIPSU_LPBK_DLY_ADJ_DLY0_WIDTH 3
#define XQSPIPSU_LPBK_DLY_ADJ_DLY0_MASK 0X00000007U
/**
* Register: XQSPIPSU_GEN_FIFO
*/
#define XQSPIPSU_GEN_FIFO_OFFSET 0X00000040U
#define XQSPIPSU_GEN_FIFO_DATA_SHIFT 0
#define XQSPIPSU_GEN_FIFO_DATA_WIDTH 20
#define XQSPIPSU_GEN_FIFO_DATA_MASK 0X000FFFFFU
/**
* Register: XQSPIPSU_SEL
*/
#define XQSPIPSU_SEL_OFFSET 0X00000044U
#define XQSPIPSU_SEL_SHIFT 0
#define XQSPIPSU_SEL_WIDTH 1
#define XQSPIPSU_SEL_MASK 0X00000001U
/**
* Register: XQSPIPSU_FIFO_CTRL
*/
#define XQSPIPSU_FIFO_CTRL_OFFSET 0X0000004CU
#define XQSPIPSU_FIFO_CTRL_RST_RX_FIFO_SHIFT 2
#define XQSPIPSU_FIFO_CTRL_RST_RX_FIFO_WIDTH 1
#define XQSPIPSU_FIFO_CTRL_RST_RX_FIFO_MASK 0X00000004U
#define XQSPIPSU_FIFO_CTRL_RST_TX_FIFO_SHIFT 1
#define XQSPIPSU_FIFO_CTRL_RST_TX_FIFO_WIDTH 1
#define XQSPIPSU_FIFO_CTRL_RST_TX_FIFO_MASK 0X00000002U
#define XQSPIPSU_FIFO_CTRL_RST_GEN_FIFO_SHIFT 0
#define XQSPIPSU_FIFO_CTRL_RST_GEN_FIFO_WIDTH 1
#define XQSPIPSU_FIFO_CTRL_RST_GEN_FIFO_MASK 0X00000001U
/**
* Register: XQSPIPSU_GF_THRESHOLD
*/
#define XQSPIPSU_GF_THRESHOLD_OFFSET 0X00000050U
#define XQSPIPSU_GEN_FIFO_THRESHOLD_SHIFT 0
#define XQSPIPSU_GEN_FIFO_THRESHOLD_WIDTH 5
#define XQSPIPSU_GEN_FIFO_THRESHOLD_MASK 0X0000001F
#define XQSPIPSU_GEN_FIFO_THRESHOLD_RESET_VAL 0X10U
/**
* Register: XQSPIPSU_POLL_CFG
*/
#define XQSPIPSU_POLL_CFG_OFFSET 0X00000054U
#define XQSPIPSU_POLL_CFG_EN_MASK_UPPER_SHIFT 31
#define XQSPIPSU_POLL_CFG_EN_MASK_UPPER_WIDTH 1
#define XQSPIPSU_POLL_CFG_EN_MASK_UPPER_MASK 0X80000000U
#define XQSPIPSU_POLL_CFG_EN_MASK_LOWER_SHIFT 30
#define XQSPIPSU_POLL_CFG_EN_MASK_LOWER_WIDTH 1
#define XQSPIPSU_POLL_CFG_EN_MASK_LOWER_MASK 0X40000000U
#define XQSPIPSU_POLL_CFG_MASK_EN_SHIFT 8
#define XQSPIPSU_POLL_CFG_MASK_EN_WIDTH 8
#define XQSPIPSU_POLL_CFG_MASK_EN_MASK 0X0000FF00U
#define XQSPIPSU_POLL_CFG_DATA_VALUE_SHIFT 0
#define XQSPIPSU_POLL_CFG_DATA_VALUE_WIDTH 8
#define XQSPIPSU_POLL_CFG_DATA_VALUE_MASK 0X000000FFU
/**
* Register: XQSPIPSU_P_TIMEOUT
*/
#define XQSPIPSU_P_TO_OFFSET 0X00000058U
#define XQSPIPSU_P_TO_VALUE_SHIFT 0
#define XQSPIPSU_P_TO_VALUE_WIDTH 32
#define XQSPIPSU_P_TO_VALUE_MASK 0XFFFFFFFFU
/**
* Register: XQSPIPSU_XFER_STS
*/
#define XQSPIPSU_XFER_STS_OFFSET 0X0000005CU
#define XQSPIPSU_XFER_STS_PEND_BYTES_SHIFT 0
#define XQSPIPSU_XFER_STS_PEND_BYTES_WIDTH 32
#define XQSPIPSU_XFER_STS_PEND_BYTES_MASK 0XFFFFFFFFU
/**
* Register: XQSPIPSU_GF_SNAPSHOT
*/
#define XQSPIPSU_GF_SNAPSHOT_OFFSET 0X00000060U
#define XQSPIPSU_GF_SNAPSHOT_SHIFT 0
#define XQSPIPSU_GF_SNAPSHOT_WIDTH 20
#define XQSPIPSU_GF_SNAPSHOT_MASK 0X000FFFFFU
/**
* Register: XQSPIPSU_RX_COPY
*/
#define XQSPIPSU_RX_COPY_OFFSET 0X00000064U
#define XQSPIPSU_RX_COPY_UPPER_SHIFT 8
#define XQSPIPSU_RX_COPY_UPPER_WIDTH 8
#define XQSPIPSU_RX_COPY_UPPER_MASK 0X0000FF00U
#define XQSPIPSU_RX_COPY_LOWER_SHIFT 0
#define XQSPIPSU_RX_COPY_LOWER_WIDTH 8
#define XQSPIPSU_RX_COPY_LOWER_MASK 0X000000FFU
/**
* Register: XQSPIPSU_MOD_ID
*/
#define XQSPIPSU_MOD_ID_OFFSET 0X000000FCU
#define XQSPIPSU_MOD_ID_SHIFT 0
#define XQSPIPSU_MOD_ID_WIDTH 32
#define XQSPIPSU_MOD_ID_MASK 0XFFFFFFFFU
/**
* Register: XQSPIPSU_QSPIDMA_DST_ADDR
*/
#define XQSPIPSU_QSPIDMA_DST_ADDR_OFFSET 0X00000700U
#define XQSPIPSU_QSPIDMA_DST_ADDR_SHIFT 2
#define XQSPIPSU_QSPIDMA_DST_ADDR_WIDTH 30
#define XQSPIPSU_QSPIDMA_DST_ADDR_MASK 0XFFFFFFFCU
/**
* Register: XQSPIPSU_QSPIDMA_DST_SIZE
*/
#define XQSPIPSU_QSPIDMA_DST_SIZE_OFFSET 0X00000704U
#define XQSPIPSU_QSPIDMA_DST_SIZE_SHIFT 2
#define XQSPIPSU_QSPIDMA_DST_SIZE_WIDTH 27
#define XQSPIPSU_QSPIDMA_DST_SIZE_MASK 0X1FFFFFFCU
/**
* Register: XQSPIPSU_QSPIDMA_DST_STS
*/
#define XQSPIPSU_QSPIDMA_DST_STS_OFFSET 0X00000708U
#define XQSPIPSU_QSPIDMA_DST_STS_DONE_CNT_SHIFT 13
#define XQSPIPSU_QSPIDMA_DST_STS_DONE_CNT_WIDTH 3
#define XQSPIPSU_QSPIDMA_DST_STS_DONE_CNT_MASK 0X0000E000U
#define XQSPIPSU_QSPIDMA_DST_STS_DST_FIFO_LEVEL_SHIFT 5
#define XQSPIPSU_QSPIDMA_DST_STS_DST_FIFO_LEVEL_WIDTH 8
#define XQSPIPSU_QSPIDMA_DST_STS_DST_FIFO_LEVEL_MASK 0X00001FE0U
#define XQSPIPSU_QSPIDMA_DST_STS_WR_OUTSTANDING_SHIFT 1
#define XQSPIPSU_QSPIDMA_DST_STS_WR_OUTSTANDING_WIDTH 4
#define XQSPIPSU_QSPIDMA_DST_STS_WR_OUTSTANDING_MASK 0X0000001EU
#define XQSPIPSU_QSPIDMA_DST_STS_BUSY_SHIFT 0
#define XQSPIPSU_QSPIDMA_DST_STS_BUSY_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_STS_BUSY_MASK 0X00000001U
#define XQSPIPSU_QSPIDMA_DST_STS_WTC 0xE000U
/**
* Register: XQSPIPSU_QSPIDMA_DST_CTRL
*/
#define XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET 0X0000070CU
#define XQSPIPSU_QSPIDMA_DST_CTRL_FIFO_LVL_HIT_THRESHOLD_SHIFT 25
#define XQSPIPSU_QSPIDMA_DST_CTRL_FIFO_LVL_HIT_THRESHOLD_WIDTH 7
#define XQSPIPSU_QSPIDMA_DST_CTRL_FIFO_LVL_HIT_THRESHOLD_MASK 0XFE000000U
#define XQSPIPSU_QSPIDMA_DST_CTRL_APB_ERR_RESP_SHIFT 24
#define XQSPIPSU_QSPIDMA_DST_CTRL_APB_ERR_RESP_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_CTRL_APB_ERR_RESP_MASK 0X01000000U
#define XQSPIPSU_QSPIDMA_DST_CTRL_ENDIAN_SHIFT 23
#define XQSPIPSU_QSPIDMA_DST_CTRL_ENDIAN_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_CTRL_ENDIAN_MASK 0X00800000U
#define XQSPIPSU_QSPIDMA_DST_CTRL_AXI_BRST_TYPE_SHIFT 22
#define XQSPIPSU_QSPIDMA_DST_CTRL_AXI_BRST_TYPE_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_CTRL_AXI_BRST_TYPE_MASK 0X00400000U
#define XQSPIPSU_QSPIDMA_DST_CTRL_TO_VAL_SHIFT 10
#define XQSPIPSU_QSPIDMA_DST_CTRL_TO_VAL_WIDTH 12
#define XQSPIPSU_QSPIDMA_DST_CTRL_TO_VAL_MASK 0X003FFC00U
#define XQSPIPSU_QSPIDMA_DST_CTRL_FIFO_THRESHOLD_SHIFT 2
#define XQSPIPSU_QSPIDMA_DST_CTRL_FIFO_THRESHOLD_WIDTH 8
#define XQSPIPSU_QSPIDMA_DST_CTRL_FIFO_THRESHOLD_MASK 0X000003FCU
#define XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_STRM_SHIFT 1
#define XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_STRM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_STRM_MASK 0X00000002U
#define XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_MEM_SHIFT 0
#define XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_MEM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_MEM_MASK 0X00000001U
#define XQSPIPSU_QSPIDMA_DST_CTRL_RESET_VAL 0x403FFA00U
/**
* Register: XQSPIPSU_QSPIDMA_DST_I_STS
*/
#define XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET 0X00000714U
#define XQSPIPSU_QSPIDMA_DST_I_STS_FIFO_OF_SHIFT 7
#define XQSPIPSU_QSPIDMA_DST_I_STS_FIFO_OF_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_STS_FIFO_OF_MASK 0X00000080U
#define XQSPIPSU_QSPIDMA_DST_I_STS_INVALID_APB_SHIFT 6
#define XQSPIPSU_QSPIDMA_DST_I_STS_INVALID_APB_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_STS_INVALID_APB_MASK 0X00000040U
#define XQSPIPSU_QSPIDMA_DST_I_STS_THRESHOLD_HIT_SHIFT 5
#define XQSPIPSU_QSPIDMA_DST_I_STS_THRESHOLD_HIT_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_STS_THRESHOLD_HIT_MASK 0X00000020U
#define XQSPIPSU_QSPIDMA_DST_I_STS_TO_MEM_SHIFT 4
#define XQSPIPSU_QSPIDMA_DST_I_STS_TO_MEM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_STS_TO_MEM_MASK 0X00000010U
#define XQSPIPSU_QSPIDMA_DST_I_STS_TO_STRM_SHIFT 3
#define XQSPIPSU_QSPIDMA_DST_I_STS_TO_STRM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_STS_TO_STRM_MASK 0X00000008U
#define XQSPIPSU_QSPIDMA_DST_I_STS_AXI_BRESP_ERR_SHIFT 2
#define XQSPIPSU_QSPIDMA_DST_I_STS_AXI_BRESP_ERR_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_STS_AXI_BRESP_ERR_MASK 0X00000004U
#define XQSPIPSU_QSPIDMA_DST_I_STS_DONE_SHIFT 1
#define XQSPIPSU_QSPIDMA_DST_I_STS_DONE_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK 0X00000002U
#define XQSPIPSU_QSPIDMA_DST_INTR_ERR_MASK 0X000000FCU
#define XQSPIPSU_QSPIDMA_DST_INTR_ALL_MASK 0X000000FEU
/**
* Register: XQSPIPSU_QSPIDMA_DST_I_EN
*/
#define XQSPIPSU_QSPIDMA_DST_I_EN_OFFSET 0X00000718U
#define XQSPIPSU_QSPIDMA_DST_I_EN_FIFO_OF_SHIFT 7
#define XQSPIPSU_QSPIDMA_DST_I_EN_FIFO_OF_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_EN_FIFO_OF_MASK 0X00000080U
#define XQSPIPSU_QSPIDMA_DST_I_EN_INVALID_APB_SHIFT 6
#define XQSPIPSU_QSPIDMA_DST_I_EN_INVALID_APB_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_EN_INVALID_APB_MASK 0X00000040U
#define XQSPIPSU_QSPIDMA_DST_I_EN_THRESHOLD_HIT_SHIFT 5
#define XQSPIPSU_QSPIDMA_DST_I_EN_THRESHOLD_HIT_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_EN_THRESHOLD_HIT_MASK 0X00000020U
#define XQSPIPSU_QSPIDMA_DST_I_EN_TO_MEM_SHIFT 4
#define XQSPIPSU_QSPIDMA_DST_I_EN_TO_MEM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_EN_TO_MEM_MASK 0X00000010U
#define XQSPIPSU_QSPIDMA_DST_I_EN_TO_STRM_SHIFT 3
#define XQSPIPSU_QSPIDMA_DST_I_EN_TO_STRM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_EN_TO_STRM_MASK 0X00000008U
#define XQSPIPSU_QSPIDMA_DST_I_EN_AXI_BRESP_ERR_SHIFT 2
#define XQSPIPSU_QSPIDMA_DST_I_EN_AXI_BRESP_ERR_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_EN_AXI_BRESP_ERR_MASK 0X00000004U
#define XQSPIPSU_QSPIDMA_DST_I_EN_DONE_SHIFT 1
#define XQSPIPSU_QSPIDMA_DST_I_EN_DONE_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_EN_DONE_MASK 0X00000002U
/**
* Register: XQSPIPSU_QSPIDMA_DST_I_DIS
*/
#define XQSPIPSU_QSPIDMA_DST_I_DIS_OFFSET 0X0000071CU
#define XQSPIPSU_QSPIDMA_DST_I_DIS_FIFO_OF_SHIFT 7
#define XQSPIPSU_QSPIDMA_DST_I_DIS_FIFO_OF_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_DIS_FIFO_OF_MASK 0X00000080U
#define XQSPIPSU_QSPIDMA_DST_I_DIS_INVALID_APB_SHIFT 6
#define XQSPIPSU_QSPIDMA_DST_I_DIS_INVALID_APB_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_DIS_INVALID_APB_MASK 0X00000040U
#define XQSPIPSU_QSPIDMA_DST_I_DIS_THRESHOLD_HIT_SHIFT 5
#define XQSPIPSU_QSPIDMA_DST_I_DIS_THRESHOLD_HIT_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_DIS_THRESHOLD_HIT_MASK 0X00000020U
#define XQSPIPSU_QSPIDMA_DST_I_DIS_TO_MEM_SHIFT 4
#define XQSPIPSU_QSPIDMA_DST_I_DIS_TO_MEM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_DIS_TO_MEM_MASK 0X00000010U
#define XQSPIPSU_QSPIDMA_DST_I_DIS_TO_STRM_SHIFT 3
#define XQSPIPSU_QSPIDMA_DST_I_DIS_TO_STRM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_DIS_TO_STRM_MASK 0X00000008U
#define XQSPIPSU_QSPIDMA_DST_I_DIS_AXI_BRESP_ERR_SHIFT 2
#define XQSPIPSU_QSPIDMA_DST_I_DIS_AXI_BRESP_ERR_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_DIS_AXI_BRESP_ERR_MASK 0X00000004U
#define XQSPIPSU_QSPIDMA_DST_I_DIS_DONE_SHIFT 1
#define XQSPIPSU_QSPIDMA_DST_I_DIS_DONE_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_I_DIS_DONE_MASK 0X00000002U
/**
* Register: XQSPIPSU_QSPIDMA_DST_IMR
*/
#define XQSPIPSU_QSPIDMA_DST_IMR_OFFSET 0X00000720U
#define XQSPIPSU_QSPIDMA_DST_IMR_FIFO_OF_SHIFT 7
#define XQSPIPSU_QSPIDMA_DST_IMR_FIFO_OF_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_IMR_FIFO_OF_MASK 0X00000080U
#define XQSPIPSU_QSPIDMA_DST_IMR_INVALID_APB_SHIFT 6
#define XQSPIPSU_QSPIDMA_DST_IMR_INVALID_APB_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_IMR_INVALID_APB_MASK 0X00000040U
#define XQSPIPSU_QSPIDMA_DST_IMR_THRESHOLD_HIT_SHIFT 5
#define XQSPIPSU_QSPIDMA_DST_IMR_THRESHOLD_HIT_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_IMR_THRESHOLD_HIT_MASK 0X00000020U
#define XQSPIPSU_QSPIDMA_DST_IMR_TO_MEM_SHIFT 4
#define XQSPIPSU_QSPIDMA_DST_IMR_TO_MEM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_IMR_TO_MEM_MASK 0X00000010U
#define XQSPIPSU_QSPIDMA_DST_IMR_TO_STRM_SHIFT 3
#define XQSPIPSU_QSPIDMA_DST_IMR_TO_STRM_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_IMR_TO_STRM_MASK 0X00000008U
#define XQSPIPSU_QSPIDMA_DST_IMR_AXI_BRESP_ERR_SHIFT 2
#define XQSPIPSU_QSPIDMA_DST_IMR_AXI_BRESP_ERR_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_IMR_AXI_BRESP_ERR_MASK 0X00000004U
#define XQSPIPSU_QSPIDMA_DST_IMR_DONE_SHIFT 1
#define XQSPIPSU_QSPIDMA_DST_IMR_DONE_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_IMR_DONE_MASK 0X00000002U
/**
* Register: XQSPIPSU_QSPIDMA_DST_CTRL2
*/
#define XQSPIPSU_QSPIDMA_DST_CTRL2_OFFSET 0X00000724U
#define XQSPIPSU_QSPIDMA_DST_CTRL2_RAM_EMASA_SHIFT 27
#define XQSPIPSU_QSPIDMA_DST_CTRL2_RAM_EMASA_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_CTRL2_RAM_EMASA_MASK 0X08000000U
#define XQSPIPSU_QSPIDMA_DST_CTRL2_AWCACHE_SHIFT 24
#define XQSPIPSU_QSPIDMA_DST_CTRL2_AWCACHE_WIDTH 3
#define XQSPIPSU_QSPIDMA_DST_CTRL2_AWCACHE_MASK 0X07000000U
#define XQSPIPSU_QSPIDMA_DST_CTRL2_TO_EN_SHIFT 22
#define XQSPIPSU_QSPIDMA_DST_CTRL2_TO_EN_WIDTH 1
#define XQSPIPSU_QSPIDMA_DST_CTRL2_TO_EN_MASK 0X00400000U
#define XQSPIPSU_QSPIDMA_DST_CTRL2_RAM_EMAB_SHIFT 19
#define XQSPIPSU_QSPIDMA_DST_CTRL2_RAM_EMAB_WIDTH 3
#define XQSPIPSU_QSPIDMA_DST_CTRL2_RAM_EMAB_MASK 0X00380000U
#define XQSPIPSU_QSPIDMA_DST_CTRL2_RAM_EMAA_SHIFT 16
#define XQSPIPSU_QSPIDMA_DST_CTRL2_RAM_EMAA_WIDTH 3
#define XQSPIPSU_QSPIDMA_DST_CTRL2_RAM_EMAA_MASK 0X00070000U
#define XQSPIPSU_QSPIDMA_DST_CTRL2_TO_PRE_SHIFT 4
#define XQSPIPSU_QSPIDMA_DST_CTRL2_TO_PRE_WIDTH 12
#define XQSPIPSU_QSPIDMA_DST_CTRL2_TO_PRE_MASK 0X0000FFF0U
#define XQSPIPSU_QSPIDMA_DST_CTRL2_MAX_OUTS_CMDS_SHIFT 0
#define XQSPIPSU_QSPIDMA_DST_CTRL2_MAX_OUTS_CMDS_WIDTH 4
#define XQSPIPSU_QSPIDMA_DST_CTRL2_MAX_OUTS_CMDS_MASK 0X0000000FU
/**
* Register: XQSPIPSU_QSPIDMA_DST_ADDR_MSB
*/
#define XQSPIPSU_QSPIDMA_DST_ADDR_MSB_OFFSET 0X00000728U
#define XQSPIPSU_QSPIDMA_DST_ADDR_MSB_SHIFT 0
#define XQSPIPSU_QSPIDMA_DST_ADDR_MSB_WIDTH 12
#define XQSPIPSU_QSPIDMA_DST_ADDR_MSB_MASK 0X00000FFFU
/**
* Register: XQSPIPSU_QSPIDMA_FUTURE_ECO
*/
#define XQSPIPSU_QSPIDMA_FUTURE_ECO_OFFSET 0X00000EFCU
#define XQSPIPSU_QSPIDMA_FUTURE_ECO_VAL_SHIFT 0
#define XQSPIPSU_QSPIDMA_FUTURE_ECO_VAL_WIDTH 32
#define XQSPIPSU_QSPIDMA_FUTURE_ECO_VAL_MASK 0XFFFFFFFFU
/*
* Generic FIFO masks
*/
#define XQSPIPSU_GENFIFO_IMM_DATA_MASK 0xFFU
#define XQSPIPSU_GENFIFO_DATA_XFER 0x100U
#define XQSPIPSU_GENFIFO_EXP 0x200U
#define XQSPIPSU_GENFIFO_MODE_SPI 0x400U
#define XQSPIPSU_GENFIFO_MODE_DUALSPI 0x800U
#define XQSPIPSU_GENFIFO_MODE_QUADSPI 0xC00U
#define XQSPIPSU_GENFIFO_MODE_MASK 0xC00U /* And with ~MASK first */
#define XQSPIPSU_GENFIFO_CS_LOWER 0x1000U
#define XQSPIPSU_GENFIFO_CS_UPPER 0x2000U
#define XQSPIPSU_GENFIFO_BUS_LOWER 0x4000U
#define XQSPIPSU_GENFIFO_BUS_UPPER 0x8000U
#define XQSPIPSU_GENFIFO_BUS_BOTH 0xC000U /* inverse is no bus */
#define XQSPIPSU_GENFIFO_BUS_MASK 0xC000U /* And with ~MASK first */
#define XQSPIPSU_GENFIFO_TX 0x10000U /* inverse is zero pump */
#define XQSPIPSU_GENFIFO_RX 0x20000U /* inverse is RX discard */
#define XQSPIPSU_GENFIFO_STRIPE 0x40000U
#define XQSPIPSU_GENFIFO_POLL 0x80000U
/***************** Macros (Inline Functions) Definitions *********************/
#define XQspiPsu_In32 Xil_In32
#define XQspiPsu_Out32 Xil_Out32
/****************************************************************************/
/**
* Read a register.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset contains the offset from the 1st register of the
* device to the target register.
*
* @return The value read from the register.
*
* @note C-Style signature:
* u32 XQspiPsu_ReadReg(u32 BaseAddress. s32 RegOffset)
*
******************************************************************************/
#define XQspiPsu_ReadReg(BaseAddress, RegOffset) XQspiPsu_In32((BaseAddress) + (RegOffset))
/***************************************************************************/
/**
* Write to a register.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset contains the offset from the 1st register of the
* device to target register.
* @param RegisterValue is the value to be written to the register.
*
* @return None.
*
* @note C-Style signature:
* void XQspiPsu_WriteReg(u32 BaseAddress, s32 RegOffset,
* u32 RegisterValue)
*
******************************************************************************/
#define XQspiPsu_WriteReg(BaseAddress, RegOffset, RegisterValue) XQspiPsu_Out32((BaseAddress) + (RegOffset), (RegisterValue))
#ifdef __cplusplus
}
#endif
#endif /* _XQSPIPSU_H_ */
/** @} */

View file

@ -0,0 +1,449 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xqspipsu_options.c
* @addtogroup qspipsu_v1_0
* @{
*
* This file implements funcitons to configure the QSPIPSU component,
* specifically some optional settings, clock and flash related information.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- -----------------------------------------------
* 1.0 hk 08/21/14 First release
* sk 03/13/15 Added IO mode support.
* sk 04/24/15 Modified the code according to MISRAC-2012.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xqspipsu.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*
* Create the table of options which are processed to get/set the device
* options. These options are table driven to allow easy maintenance and
* expansion of the options.
*/
typedef struct {
u32 Option;
u32 Mask;
} OptionsMap;
static OptionsMap OptionsTable[] = {
{XQSPIPSU_CLK_ACTIVE_LOW_OPTION, XQSPIPSU_CFG_CLK_POL_MASK},
{XQSPIPSU_CLK_PHASE_1_OPTION, XQSPIPSU_CFG_CLK_PHA_MASK},
{XQSPIPSU_MANUAL_START_OPTION, XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK},
};
#define XQSPIPSU_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionsMap))
/*****************************************************************************/
/**
*
* This function sets the options for the QSPIPSU device driver.The options
* control how the device behaves relative to the QSPIPSU bus. The device must be
* idle rather than busy transferring data before setting these device options.
*
* @param InstancePtr is a pointer to the XQspiPsu instance.
* @param Options contains the specified options to be set. This is a bit
* mask where a 1 indicates the option should be turned ON and
* a 0 indicates no action. One or more bit values may be
* contained in the mask. See the bit definitions named
* XQSPIPSU_*_OPTIONS in the file xqspipsu.h.
*
* @return
* - XST_SUCCESS if options are successfully set.
* - XST_DEVICE_BUSY if the device is currently transferring data.
* The transfer must complete or be aborted before setting options.
*
* @note
* This function is not thread-safe.
*
******************************************************************************/
s32 XQspiPsu_SetOptions(XQspiPsu *InstancePtr, u32 Options)
{
u32 ConfigReg;
u32 Index;
u32 QspiPsuOptions;
s32 Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Do not allow to modify the Control Register while a transfer is in
* progress. Not thread-safe.
*/
if (InstancePtr->IsBusy == TRUE) {
Status = (s32)XST_DEVICE_BUSY;
} else {
ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
XQSPIPSU_CFG_OFFSET);
/*
* Loop through the options table, turning the option on
* depending on whether the bit is set in the incoming options flag.
*/
for (Index = 0U; Index < XQSPIPSU_NUM_OPTIONS; Index++) {
if ((Options & OptionsTable[Index].Option) != FALSE) {
/* Turn it on */
ConfigReg |= OptionsTable[Index].Mask;
}
}
/*
* Now write the control register. Leave it to the upper layers
* to restart the device.
*/
XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
ConfigReg);
if ((Options & XQSPIPSU_MANUAL_START_OPTION) != FALSE) {
InstancePtr->IsManualstart = TRUE;
}
Status = XST_SUCCESS;
}
return Status;
}
/*****************************************************************************/
/**
*
* This function resets the options for the QSPIPSU device driver.The options
* control how the device behaves relative to the QSPIPSU bus. The device must be
* idle rather than busy transferring data before setting these device options.
*
* @param InstancePtr is a pointer to the XQspiPsu instance.
* @param Options contains the specified options to be set. This is a bit
* mask where a 1 indicates the option should be turned OFF and
* a 0 indicates no action. One or more bit values may be
* contained in the mask. See the bit definitions named
* XQSPIPSU_*_OPTIONS in the file xqspipsu.h.
*
* @return
* - XST_SUCCESS if options are successfully set.
* - XST_DEVICE_BUSY if the device is currently transferring data.
* The transfer must complete or be aborted before setting options.
*
* @note
* This function is not thread-safe.
*
******************************************************************************/
s32 XQspiPsu_ClearOptions(XQspiPsu *InstancePtr, u32 Options)
{
u32 ConfigReg;
u32 Index;
u32 QspiPsuOptions;
s32 Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Do not allow to modify the Control Register while a transfer is in
* progress. Not thread-safe.
*/
if (InstancePtr->IsBusy == TRUE) {
Status = (s32)XST_DEVICE_BUSY;
} else {
ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
XQSPIPSU_CFG_OFFSET);
/*
* Loop through the options table, turning the option on
* depending on whether the bit is set in the incoming options flag.
*/
for (Index = 0U; Index < XQSPIPSU_NUM_OPTIONS; Index++) {
if ((Options & OptionsTable[Index].Option) != FALSE) {
/* Turn it off */
ConfigReg &= ~OptionsTable[Index].Mask;
}
}
/*
* Now write the control register. Leave it to the upper layers
* to restart the device.
*/
XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
ConfigReg);
if ((Options & XQSPIPSU_MANUAL_START_OPTION) != FALSE) {
InstancePtr->IsManualstart = FALSE;
}
Status = XST_SUCCESS;
}
return Status;
}
/*****************************************************************************/
/**
*
* This function gets the options for the QSPIPSU device. The options control how
* the device behaves relative to the QSPIPSU bus.
*
* @param InstancePtr is a pointer to the XQspiPsu instance.
*
* @return
*
* Options contains the specified options currently set. This is a bit value
* where a 1 means the option is on, and a 0 means the option is off.
* See the bit definitions named XQSPIPSU_*_OPTIONS in file xqspipsu.h.
*
* @note None.
*
******************************************************************************/
u32 XQspiPsu_GetOptions(XQspiPsu *InstancePtr)
{
u32 OptionsFlag = 0;
u32 ConfigReg;
u32 Index;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Get the current options from QSPIPSU configuration register.
*/
ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
XQSPIPSU_CFG_OFFSET);
/* Loop through the options table to grab options */
for (Index = 0U; Index < XQSPIPSU_NUM_OPTIONS; Index++) {
if ((ConfigReg & OptionsTable[Index].Mask) != FALSE) {
OptionsFlag |= OptionsTable[Index].Option;
}
}
return OptionsFlag;
}
/*****************************************************************************/
/**
*
* Configures the clock according to the prescaler passed.
*
*
* @param InstancePtr is a pointer to the XQspiPsu instance.
* @param Prescaler - clock prescaler to be set.
*
* @return
* - XST_SUCCESS if successful.
* - XST_DEVICE_IS_STARTED if the device is already started.
* It must be stopped to re-initialize.
*
* @note None.
*
******************************************************************************/
s32 XQspiPsu_SetClkPrescaler(XQspiPsu *InstancePtr, u8 Prescaler)
{
u32 ConfigReg;
s32 Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Prescaler <= XQSPIPSU_CR_PRESC_MAXIMUM);
/*
* Do not allow the slave select to change while a transfer is in
* progress. Not thread-safe.
*/
if (InstancePtr->IsBusy == TRUE) {
Status = (s32)XST_DEVICE_BUSY;
} else {
/*
* Read the configuration register, mask out the relevant bits, and set
* them with the shifted value passed into the function. Write the
* results back to the configuration register.
*/
ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
XQSPIPSU_CFG_OFFSET);
ConfigReg &= (u32)(~XQSPIPSU_CFG_BAUD_RATE_DIV_MASK);
ConfigReg |= (u32) ((u32)Prescaler & (u32)XQSPIPSU_CR_PRESC_MAXIMUM) <<
XQSPIPSU_CFG_BAUD_RATE_DIV_SHIFT;
XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
XQSPIPSU_CFG_OFFSET, ConfigReg);
Status = XST_SUCCESS;
}
return Status;
}
/*****************************************************************************/
/**
*
* This funciton should be used to tell the QSPIPSU driver the HW flash
* configuration being used. This API should be called atleast once in the
* application. If desired, it can be called multiple times when switching
* between communicating to different flahs devices/using different configs.
*
* @param InstancePtr is a pointer to the XQspiPsu instance.
* @param FlashCS - Flash Chip Select.
* @param FlashBus - Flash Bus (Upper, Lower or Both).
*
* @return
* - XST_SUCCESS if successful.
* - XST_DEVICE_IS_STARTED if the device is already started.
* It must be stopped to re-initialize.
*
* @note If this funciton is not called atleast once in the application,
* the driver assumes there is a single flash connected to the
* lower bus and CS line.
*
******************************************************************************/
void XQspiPsu_SelectFlash(XQspiPsu *InstancePtr, u8 FlashCS, u8 FlashBus)
{
Xil_AssertVoid(InstancePtr != NULL);
/*
* Bus and CS lines selected here will be updated in the instance and
* used for subsequent GENFIFO entries during transfer.
*/
/* Choose slave select line */
switch (FlashCS) {
case XQSPIPSU_SELECT_FLASH_CS_BOTH:
InstancePtr->GenFifoCS = (u32)XQSPIPSU_GENFIFO_CS_LOWER |
(u32)XQSPIPSU_GENFIFO_CS_UPPER;
break;
case XQSPIPSU_SELECT_FLASH_CS_UPPER:
InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_UPPER;
break;
case XQSPIPSU_SELECT_FLASH_CS_LOWER:
InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER;
break;
default:
InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER;
break;
}
/* Choose bus */
switch (FlashBus) {
case XQSPIPSU_SELECT_FLASH_BUS_BOTH:
InstancePtr->GenFifoBus = (u32)XQSPIPSU_GENFIFO_BUS_LOWER |
(u32)XQSPIPSU_GENFIFO_BUS_UPPER;
break;
case XQSPIPSU_SELECT_FLASH_BUS_UPPER:
InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_UPPER;
break;
case XQSPIPSU_SELECT_FLASH_BUS_LOWER:
InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER;
break;
default:
InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER;
break;
}
}
/*****************************************************************************/
/**
*
* This function sets the Read mode for the QSPIPSU device driver.The device
* must be idle rather than busy transferring data before setting Read mode
* options.
*
* @param InstancePtr is a pointer to the XQspiPsu instance.
* @param Mode contains the specified Mode to be set. See the
* bit definitions named XQSPIPSU_READMODE_* in the file xqspipsu.h.
*
* @return
* - XST_SUCCESS if options are successfully set.
* - XST_DEVICE_BUSY if the device is currently transferring data.
* The transfer must complete or be aborted before setting Mode.
*
* @note
* This function is not thread-safe.
*
******************************************************************************/
s32 XQspiPsu_SetReadMode(XQspiPsu *InstancePtr, u32 Mode)
{
u32 ConfigReg;
s32 Status;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Do not allow to modify the Control Register while a transfer is in
* progress. Not thread-safe.
*/
if (InstancePtr->IsBusy == TRUE) {
Status = (s32)XST_DEVICE_BUSY;
} else {
InstancePtr->ReadMode = Mode;
ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
XQSPIPSU_CFG_OFFSET);
if (Mode == XQSPIPSU_READMODE_DMA) {
ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK;
} else {
ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
}
XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
ConfigReg);
Status = XST_SUCCESS;
}
return Status;
}
/** @} */

View file

@ -0,0 +1,100 @@
/******************************************************************************
*
* Copyright (C) 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xqspipsu_sinit.c
* @addtogroup qspipsu_v1_0
* @{
*
* The implementation of the XQspiPsu component's static initialization
* functionality.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- -----------------------------------------------
* 1.0 hk 08/21/14 First release
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xstatus.h"
#include "xqspipsu.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
extern XQspiPsu_Config XQspiPsu_ConfigTable[XPAR_XQSPIPSU_NUM_INSTANCES];
/*****************************************************************************/
/**
*
* Looks up the device configuration based on the unique device ID. A table
* contains the configuration info for each device in the system.
*
* @param DeviceId contains the ID of the device to look up the
* configuration for.
*
* @return
*
* A pointer to the configuration found or NULL if the specified device ID was
* not found. See xqspipsu.h for the definition of XQspiPsu_Config.
*
* @note None.
*
******************************************************************************/
XQspiPsu_Config *XQspiPsu_LookupConfig(u16 DeviceId)
{
XQspiPsu_Config *CfgPtr = NULL;
s32 Index;
for (Index = 0; Index < XPAR_XQSPIPSU_NUM_INSTANCES; Index++) {
if (XQspiPsu_ConfigTable[Index].DeviceId == DeviceId) {
CfgPtr = &XQspiPsu_ConfigTable[Index];
break;
}
}
return (XQspiPsu_Config *)CfgPtr;
}
/** @} */

Some files were not shown because too many files have changed in this diff Show more