Initial commit: TC264 smart car project with IPS200 menu system
- IPS200 display menu with real-time status and parameter settings - Camera image processing and line tracking - IMU attitude solution and PID control - WiFi SPI oscilloscope data transmission
This commit is contained in:
commit
843447835d
660 files changed
+443632
No files matched your search
@@ -0,0 +1,641 @@
|
||||
/**
|
||||
* \file IfxAsclin_Asc.c
|
||||
* \brief ASCLIN ASC details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxAsclin_Asc.h"
|
||||
#include "string.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint8 IfxAsclin_Asc_blockingRead(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
Ifx_SizeT count = 1;
|
||||
uint8 data;
|
||||
|
||||
while (IfxAsclin_Asc_read(asclin, &data, &count, TIME_INFINITE) != TRUE)
|
||||
{}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxAsclin_Asc_blockingWrite(IfxAsclin_Asc *asclin, uint8 data)
|
||||
{
|
||||
Ifx_SizeT count = 1;
|
||||
|
||||
return IfxAsclin_Asc_write(asclin, &data, &count, TIME_INFINITE);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxAsclin_Asc_canReadCount(IfxAsclin_Asc *asclin, Ifx_SizeT count, Ifx_TickTime timeout)
|
||||
{
|
||||
return Ifx_Fifo_canReadCount(asclin->rx, count, timeout);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxAsclin_Asc_canWriteCount(IfxAsclin_Asc *asclin, Ifx_SizeT count, Ifx_TickTime timeout)
|
||||
{
|
||||
return Ifx_Fifo_canWriteCount(asclin->tx, count, timeout);
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Asc_clearRx(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
IfxAsclin_flushRxFifo(asclin->asclin);
|
||||
Ifx_Fifo_clear(asclin->rx);
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Asc_clearTx(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
Ifx_Fifo_clear(asclin->tx);
|
||||
IfxAsclin_flushTxFifo(asclin->asclin);
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Asc_disableModule(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler*/
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(psw); /* clearing the endinit protection */
|
||||
IfxAsclin_setDisableModuleRequest(asclinSFR); /* disabling the module */
|
||||
IfxScuWdt_setCpuEndinit(psw); /* setting the endinit protection back on */
|
||||
}
|
||||
|
||||
|
||||
boolean IfxAsclin_Asc_flushTx(IfxAsclin_Asc *asclin, Ifx_TickTime timeout)
|
||||
{
|
||||
Ifx_TickTime deadline = getDeadLine(timeout);
|
||||
boolean result;
|
||||
|
||||
/* Flush the software FIFO */
|
||||
result = Ifx_Fifo_flush(asclin->tx, timeout);
|
||||
|
||||
if (result)
|
||||
{
|
||||
/* Flush the hardware FIFO (wait until all bytes have been transmitted) */
|
||||
do
|
||||
{
|
||||
result = IfxAsclin_getTxFifoFillLevel(asclin->asclin) == 0;
|
||||
} while (!result && !isDeadLine(deadline));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
sint32 IfxAsclin_Asc_getReadCount(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
return Ifx_Fifo_readCount(asclin->rx);
|
||||
}
|
||||
|
||||
|
||||
IfxStdIf_DPipe_ReadEvent IfxAsclin_Asc_getReadEvent(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
return &asclin->rx->eventWriter;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxAsclin_Asc_getSendCount(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
return asclin->sendCount;
|
||||
}
|
||||
|
||||
|
||||
Ifx_TickTime IfxAsclin_Asc_getTxTimeStamp(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
return asclin->txTimestamp;
|
||||
}
|
||||
|
||||
|
||||
sint32 IfxAsclin_Asc_getWriteCount(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
return Ifx_Fifo_writeCount(asclin->tx);
|
||||
}
|
||||
|
||||
|
||||
IfxStdIf_DPipe_WriteEvent IfxAsclin_Asc_getWriteEvent(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
return &asclin->tx->eventWriter;
|
||||
}
|
||||
|
||||
|
||||
IfxAsclin_Status IfxAsclin_Asc_initModule(IfxAsclin_Asc *asclin, const IfxAsclin_Asc_Config *config)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = config->asclin; /* pointer to ASCLIN registers*/
|
||||
IfxAsclin_Status status = IfxAsclin_Status_noError;
|
||||
|
||||
asclin->asclin = asclinSFR; /* adding register pointer to module handler*/
|
||||
|
||||
IfxAsclin_enableModule(asclinSFR); /* enabling the module*/
|
||||
IfxAsclin_setClockSource(asclinSFR, IfxAsclin_ClockSource_noClock); /* disabling the clock*/
|
||||
IfxAsclin_setFrameMode(asclinSFR, IfxAsclin_FrameMode_initialise); /* setting the module in Initialise mode*/
|
||||
IfxAsclin_setPrescaler(asclinSFR, config->baudrate.prescaler); /* sets the prescaler */
|
||||
IfxAsclin_setClockSource(asclinSFR, config->clockSource); /* temporary set the clock source for baudrate configuration*/
|
||||
status = (IfxAsclin_Status)IfxAsclin_setBitTiming(asclinSFR, /* setting the baudrate bit fields to generate the required baudrate*/
|
||||
config->baudrate.baudrate,
|
||||
config->baudrate.oversampling,
|
||||
config->bitTiming.samplePointPosition,
|
||||
config->bitTiming.medianFilter);
|
||||
IfxAsclin_setClockSource(asclinSFR, IfxAsclin_ClockSource_noClock); /* disabling the clock again*/
|
||||
|
||||
IfxAsclin_enableLoopBackMode(asclinSFR, config->loopBack); /* selecting the loopback mode */
|
||||
IfxAsclin_enableParity(asclinSFR, config->frame.parityBit); /* setting parity enable */
|
||||
IfxAsclin_setParityType(asclinSFR, config->frame.parityType); /* setting parity type (odd/even)*/
|
||||
IfxAsclin_setStopBit(asclinSFR, config->frame.stopBit); /* setting the stop bit */
|
||||
IfxAsclin_setShiftDirection(asclinSFR, config->frame.shiftDir); /* setting the shift direction */
|
||||
IfxAsclin_setDataLength(asclinSFR, config->frame.dataLength); /* setting the data length */
|
||||
IfxAsclin_setTxFifoInletWidth(asclinSFR, config->fifo.inWidth); /* setting Tx FIFO inlet width */
|
||||
IfxAsclin_setRxFifoOutletWidth(asclinSFR, config->fifo.outWidth); /* setting Rx FIFO outlet width */
|
||||
IfxAsclin_setIdleDelay(asclinSFR, config->frame.idleDelay); /* setting idle delay */
|
||||
IfxAsclin_setTxFifoInterruptLevel(asclinSFR, config->fifo.txFifoInterruptLevel); /* setting Tx FIFO level at which a Tx interrupt will be triggered*/
|
||||
IfxAsclin_setRxFifoInterruptLevel(asclinSFR, config->fifo.rxFifoInterruptLevel); /* setting Rx FIFO interrupt level at which a Rx interrupt will be triggered*/
|
||||
IfxAsclin_setFrameMode(asclinSFR, config->frame.frameMode); /* selecting the frame mode*/
|
||||
|
||||
/* Pin mapping */
|
||||
const IfxAsclin_Asc_Pins *pins = config->pins;
|
||||
|
||||
if (pins != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_Cts_In *cts = pins->cts;
|
||||
|
||||
if (cts != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_initCtsPin(cts, pins->ctsMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxAsclin_Rx_In *rx = pins->rx;
|
||||
|
||||
if (rx != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_initRxPin(rx, pins->rxMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxAsclin_Rts_Out *rts = pins->rts;
|
||||
|
||||
if (rts != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_initRtsPin(rts, pins->rtsMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxAsclin_Tx_Out *tx = pins->tx;
|
||||
|
||||
if (tx != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_initTxPin(tx, pins->txMode, pins->pinDriver);
|
||||
}
|
||||
}
|
||||
|
||||
IfxAsclin_setClockSource(asclinSFR, config->clockSource); /* select the clock source*/
|
||||
|
||||
IfxAsclin_disableAllFlags(asclinSFR); /* disable all flags */
|
||||
IfxAsclin_clearAllFlags(asclinSFR); /* clear all flags */
|
||||
|
||||
/* HW error flags */
|
||||
asclin->errorFlags.ALL = 0;
|
||||
|
||||
if (config->errorFlags.flags.parityError)
|
||||
{
|
||||
IfxAsclin_enableParityErrorFlag(asclinSFR, TRUE);
|
||||
}
|
||||
|
||||
if (config->errorFlags.flags.frameError)
|
||||
{
|
||||
IfxAsclin_enableFrameErrorFlag(asclinSFR, TRUE);
|
||||
}
|
||||
|
||||
if (config->errorFlags.flags.rxFifoOverflow)
|
||||
{
|
||||
IfxAsclin_enableRxFifoOverflowFlag(asclinSFR, TRUE);
|
||||
}
|
||||
|
||||
if (config->errorFlags.flags.rxFifoUnderflow)
|
||||
{
|
||||
IfxAsclin_enableRxFifoUnderflowFlag(asclinSFR, TRUE);
|
||||
}
|
||||
|
||||
if (config->errorFlags.flags.txFifoOverflow)
|
||||
{
|
||||
IfxAsclin_enableTxFifoOverflowFlag(asclinSFR, TRUE);
|
||||
}
|
||||
|
||||
/* transmission flags */
|
||||
asclin->rxSwFifoOverflow = FALSE;
|
||||
asclin->txInProgress = FALSE;
|
||||
|
||||
/* Buffer mode */
|
||||
Ifx_SizeT elementSize;
|
||||
asclin->dataBufferMode = config->dataBufferMode;
|
||||
asclin->txTimestamp = 0;
|
||||
asclin->sendCount = 0;
|
||||
|
||||
switch (asclin->dataBufferMode)
|
||||
{
|
||||
case Ifx_DataBufferMode_normal:
|
||||
elementSize = 1;
|
||||
break;
|
||||
case Ifx_DataBufferMode_timeStampSingle:
|
||||
elementSize = sizeof(Ifx_DataBufferMode_TimeStampSingle);
|
||||
break;
|
||||
default:
|
||||
elementSize = 0;
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* SW Fifos */
|
||||
if (config->txBuffer != NULL_PTR)
|
||||
{
|
||||
asclin->tx = Ifx_Fifo_init(config->txBuffer, config->txBufferSize, elementSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
asclin->tx = Ifx_Fifo_create(config->txBufferSize, elementSize);
|
||||
}
|
||||
|
||||
if (config->rxBuffer != NULL_PTR)
|
||||
{
|
||||
asclin->rx = Ifx_Fifo_init(config->rxBuffer, config->rxBufferSize, elementSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
asclin->rx = Ifx_Fifo_create(config->rxBufferSize, elementSize);
|
||||
}
|
||||
|
||||
/* initialising the interrupts */
|
||||
IfxSrc_Tos tos = config->interrupt.typeOfService;
|
||||
|
||||
if ((config->interrupt.rxPriority > 0) || (tos == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxAsclin_getSrcPointerRx(asclinSFR);
|
||||
IfxSrc_init(src, tos, config->interrupt.rxPriority);
|
||||
IfxAsclin_enableRxFifoFillLevelFlag(asclinSFR, TRUE);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.txPriority > 0) || (tos == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxAsclin_getSrcPointerTx(asclinSFR);
|
||||
IfxSrc_init(src, tos, config->interrupt.txPriority);
|
||||
IfxAsclin_enableTxFifoFillLevelFlag(asclinSFR, TRUE);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt.erPriority > 0) /*These interrupts are not serviced by dma*/
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxAsclin_getSrcPointerEr(asclinSFR);
|
||||
IfxSrc_init(src, tos, config->interrupt.erPriority);
|
||||
IfxAsclin_enableParityErrorFlag(asclinSFR, TRUE);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
/* enable transfers */
|
||||
IfxAsclin_enableRxFifoInlet(asclinSFR, TRUE); // enabling Rx FIFO for recieving
|
||||
IfxAsclin_enableTxFifoOutlet(asclinSFR, TRUE); // enabling Tx FIFO for transmitting
|
||||
|
||||
IfxAsclin_flushRxFifo(asclinSFR); // flushing Rx FIFO
|
||||
IfxAsclin_flushTxFifo(asclinSFR); // flushing Tx FIFO
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Asc_initModuleConfig(IfxAsclin_Asc_Config *config, Ifx_ASCLIN *asclin)
|
||||
{
|
||||
config->asclin = asclin;
|
||||
|
||||
/* loop back disabled */
|
||||
config->loopBack = FALSE; /* no loop back*/
|
||||
|
||||
/* Default values for baudrate */
|
||||
config->clockSource = IfxAsclin_ClockSource_kernelClock; /* kernel clock, fclc*/
|
||||
config->baudrate.prescaler = 1; /* default prescaler*/
|
||||
config->baudrate.baudrate = 115200; /* default baudrate (the fractional dividier setup will be calculated in initModule*/
|
||||
config->baudrate.oversampling = IfxAsclin_OversamplingFactor_4; /* default oversampling factor*/
|
||||
|
||||
/* Default Values for Bit Timings */
|
||||
config->bitTiming.medianFilter = IfxAsclin_SamplesPerBit_one; /* one sample per bit*/
|
||||
config->bitTiming.samplePointPosition = IfxAsclin_SamplePointPosition_3; /* sample point position at 3*/
|
||||
/* Default Values for Frame Control */
|
||||
config->frame.idleDelay = IfxAsclin_IdleDelay_0; /* no idle delay*/
|
||||
config->frame.stopBit = IfxAsclin_StopBit_1; /* one stop bit*/
|
||||
config->frame.frameMode = IfxAsclin_FrameMode_asc; /* ASC mode*/
|
||||
config->frame.shiftDir = IfxAsclin_ShiftDirection_lsbFirst; /* shift diection LSB first*/
|
||||
config->frame.parityBit = FALSE; /* disable parity*/
|
||||
config->frame.parityType = IfxAsclin_ParityType_even; /* even parity (if parity enabled)*/
|
||||
config->frame.dataLength = IfxAsclin_DataLength_8; /* number of bits per transfer 8*/
|
||||
|
||||
/* Default Values for Fifo Control */
|
||||
config->fifo.inWidth = IfxAsclin_TxFifoInletWidth_1; /* 8-bit wide write*/
|
||||
config->fifo.outWidth = IfxAsclin_RxFifoOutletWidth_1; /* 8-bit wide read*/
|
||||
config->fifo.txFifoInterruptLevel = IfxAsclin_TxFifoInterruptLevel_0; /* txFifoInterruptLevel = 0. optimised to write upto 16 bytes at a time */
|
||||
config->fifo.rxFifoInterruptLevel = IfxAsclin_RxFifoInterruptLevel_1;
|
||||
config->fifo.buffMode = IfxAsclin_ReceiveBufferMode_rxFifo; /* RxFIFO*/
|
||||
|
||||
/* Default Values for Interrupt Config */
|
||||
config->interrupt.rxPriority = 0; /* receive interrupt priority 0*/
|
||||
config->interrupt.txPriority = 0; /* transmit interrupt priority 0*/
|
||||
config->interrupt.erPriority = 0; /* error interrupt priority 0*/
|
||||
config->interrupt.typeOfService = IfxSrc_Tos_cpu0; /* type of service CPU0*/
|
||||
|
||||
/* Enable error flags */
|
||||
config->errorFlags.ALL = ~0; /* all error flags enabled*/
|
||||
|
||||
/* init pointers */
|
||||
config->pins = NULL_PTR; /* pins to null pointer*/
|
||||
config->rxBuffer = NULL_PTR; /* Rx Fifo buffer*/
|
||||
config->txBuffer = NULL_PTR; /* Tx Fifo buffer*/
|
||||
|
||||
config->txBufferSize = 0; /* Rx Fifo buffer size*/
|
||||
config->rxBufferSize = 0; /* Rx Fifo buffer size*/
|
||||
|
||||
config->dataBufferMode = Ifx_DataBufferMode_normal;
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Asc_initiateTransmission(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
if (asclin->txInProgress == FALSE) /* Send first byte: send init */
|
||||
{
|
||||
if (Ifx_Fifo_isEmpty(asclin->tx) == FALSE)
|
||||
{
|
||||
uint8 data;
|
||||
asclin->txInProgress = TRUE;
|
||||
|
||||
switch (asclin->dataBufferMode)
|
||||
{
|
||||
case Ifx_DataBufferMode_normal:
|
||||
{
|
||||
Ifx_Fifo_read(asclin->tx, &data, 1, TIME_NULL);
|
||||
}
|
||||
break;
|
||||
case Ifx_DataBufferMode_timeStampSingle:
|
||||
{
|
||||
Ifx_DataBufferMode_TimeStampSingle packedData;
|
||||
Ifx_Fifo_read(asclin->tx, &packedData, sizeof(packedData), TIME_NULL);
|
||||
data = packedData.data;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
IfxAsclin_write8(asclin->asclin, &data, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Asc_isrError(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler*/
|
||||
|
||||
/* store all the flags in the variable */
|
||||
if (IfxAsclin_getParityErrorFlagStatus(asclinSFR))
|
||||
{
|
||||
IfxAsclin_clearParityErrorFlag(asclinSFR);
|
||||
asclin->errorFlags.flags.parityError = 1;
|
||||
}
|
||||
|
||||
if (IfxAsclin_getFrameErrorFlagStatus(asclinSFR))
|
||||
{
|
||||
IfxAsclin_clearFrameErrorFlag(asclinSFR);
|
||||
asclin->errorFlags.flags.frameError = 1;
|
||||
}
|
||||
|
||||
if (IfxAsclin_getRxFifoOverflowFlagStatus(asclinSFR))
|
||||
{
|
||||
IfxAsclin_clearRxFifoOverflowFlag(asclinSFR);
|
||||
asclin->errorFlags.flags.rxFifoOverflow = 1;
|
||||
}
|
||||
|
||||
if (IfxAsclin_getRxFifoUnderflowFlagStatus(asclinSFR))
|
||||
{
|
||||
IfxAsclin_clearRxFifoUnderflowFlag(asclinSFR);
|
||||
asclin->errorFlags.flags.rxFifoUnderflow = 1;
|
||||
}
|
||||
|
||||
if (IfxAsclin_getTxFifoOverflowFlagStatus(asclinSFR))
|
||||
{
|
||||
IfxAsclin_clearTxFifoOverflowFlag(asclinSFR);
|
||||
asclin->errorFlags.flags.txFifoOverflow = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Asc_isrReceive(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
uint8 ascData[16]; /*FIFO size is 16 bytes*/
|
||||
|
||||
switch (asclin->dataBufferMode)
|
||||
{
|
||||
case Ifx_DataBufferMode_normal:
|
||||
{
|
||||
uint8 count;
|
||||
count = IfxAsclin_getRxFifoFillLevel(asclin->asclin);
|
||||
IfxAsclin_read8(asclin->asclin, &ascData[0], count);
|
||||
|
||||
if (Ifx_Fifo_write(asclin->rx, &ascData[0], count, TIME_NULL) != 0)
|
||||
{
|
||||
/* Receive buffer is full, data is discard */
|
||||
asclin->rxSwFifoOverflow = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Ifx_DataBufferMode_timeStampSingle:
|
||||
{
|
||||
Ifx_DataBufferMode_TimeStampSingle packedData;
|
||||
|
||||
while (IfxAsclin_getRxFifoFillLevel(asclin->asclin) > 0)
|
||||
{
|
||||
packedData.timestamp = now();
|
||||
IfxAsclin_read8(asclin->asclin, &ascData[0], 1);
|
||||
packedData.data = ascData[0];
|
||||
|
||||
if (Ifx_Fifo_write(asclin->rx, &packedData, sizeof(packedData), TIME_NULL) != 0)
|
||||
{
|
||||
/* Receive buffer is full, data is discard */
|
||||
asclin->rxSwFifoOverflow = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Asc_isrTransmit(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
asclin->txTimestamp = now();
|
||||
asclin->sendCount++;
|
||||
|
||||
if (Ifx_Fifo_isEmpty(asclin->tx) == FALSE)
|
||||
{
|
||||
switch (asclin->dataBufferMode)
|
||||
{
|
||||
case Ifx_DataBufferMode_normal:
|
||||
{
|
||||
uint8 ascData[16];
|
||||
uint16 count = 0, i_count = 0;
|
||||
volatile uint8 hw_tx_fill_level = 0;
|
||||
|
||||
count = Ifx_Fifo_readCount(asclin->tx); /*SW FIFO fill level*/
|
||||
|
||||
hw_tx_fill_level = IfxAsclin_getTxFifoFillLevel(asclin->asclin);
|
||||
|
||||
i_count = (16 - hw_tx_fill_level);
|
||||
|
||||
if (i_count > count)
|
||||
{
|
||||
i_count = count;
|
||||
}
|
||||
|
||||
Ifx_Fifo_read(asclin->tx, &ascData[0], i_count, TIME_NULL);
|
||||
IfxAsclin_write8(asclin->asclin, &ascData[0], i_count);
|
||||
}
|
||||
break;
|
||||
|
||||
case Ifx_DataBufferMode_timeStampSingle:
|
||||
{
|
||||
Ifx_DataBufferMode_TimeStampSingle packedData;
|
||||
uint8 ascData;
|
||||
|
||||
Ifx_Fifo_read(asclin->tx, &packedData, sizeof(packedData), TIME_NULL);
|
||||
|
||||
ascData = packedData.data;
|
||||
IfxAsclin_write8(asclin->asclin, &ascData, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Transmit buffer is empty */
|
||||
asclin->txInProgress = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean IfxAsclin_Asc_read(IfxAsclin_Asc *asclin, void *data, Ifx_SizeT *count, Ifx_TickTime timeout)
|
||||
{
|
||||
Ifx_SizeT left = Ifx_Fifo_read(asclin->rx, data, *count, timeout);
|
||||
|
||||
*count -= left;
|
||||
|
||||
return left == 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Asc_resetSendCount(IfxAsclin_Asc *asclin)
|
||||
{
|
||||
asclin->sendCount = 0;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxAsclin_Asc_stdIfDPipeInit(IfxStdIf_DPipe *stdif, IfxAsclin_Asc *asclin)
|
||||
{
|
||||
/* Ensure the stdif is reset to zeros */
|
||||
memset(stdif, 0, sizeof(IfxStdIf_DPipe));
|
||||
|
||||
/* Set the API link */
|
||||
stdif->driver = asclin;
|
||||
stdif->write = (IfxStdIf_DPipe_Write) & IfxAsclin_Asc_write;
|
||||
stdif->read = (IfxStdIf_DPipe_Read) & IfxAsclin_Asc_read;
|
||||
stdif->getReadCount = (IfxStdIf_DPipe_GetReadCount) & IfxAsclin_Asc_getReadCount;
|
||||
stdif->getReadEvent = (IfxStdIf_DPipe_GetReadEvent) & IfxAsclin_Asc_getReadEvent;
|
||||
stdif->getWriteCount = (IfxStdIf_DPipe_GetWriteCount) & IfxAsclin_Asc_getWriteCount;
|
||||
stdif->getWriteEvent = (IfxStdIf_DPipe_GetWriteEvent) & IfxAsclin_Asc_getWriteEvent;
|
||||
stdif->canReadCount = (IfxStdIf_DPipe_CanReadCount) & IfxAsclin_Asc_canReadCount;
|
||||
stdif->canWriteCount = (IfxStdIf_DPipe_CanWriteCount) & IfxAsclin_Asc_canWriteCount;
|
||||
stdif->flushTx = (IfxStdIf_DPipe_FlushTx) & IfxAsclin_Asc_flushTx;
|
||||
stdif->clearTx = (IfxStdIf_DPipe_ClearTx) & IfxAsclin_Asc_clearTx;
|
||||
stdif->clearRx = (IfxStdIf_DPipe_ClearRx) & IfxAsclin_Asc_clearRx;
|
||||
stdif->onReceive = (IfxStdIf_DPipe_OnReceive) & IfxAsclin_Asc_isrReceive;
|
||||
stdif->onTransmit = (IfxStdIf_DPipe_OnTransmit) & IfxAsclin_Asc_isrTransmit;
|
||||
stdif->onError = (IfxStdIf_DPipe_OnError) & IfxAsclin_Asc_isrError;
|
||||
stdif->getSendCount = (IfxStdIf_DPipe_GetSendCount) & IfxAsclin_Asc_getSendCount;
|
||||
stdif->getTxTimeStamp = (IfxStdIf_DPipe_GetTxTimeStamp) & IfxAsclin_Asc_getTxTimeStamp;
|
||||
stdif->resetSendCount = (IfxStdIf_DPipe_ResetSendCount) & IfxAsclin_Asc_resetSendCount;
|
||||
stdif->txDisabled = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxAsclin_Asc_write(IfxAsclin_Asc *asclin, const void *data, Ifx_SizeT *count, Ifx_TickTime timeout)
|
||||
{
|
||||
Ifx_SizeT left;
|
||||
boolean result = TRUE;
|
||||
boolean tx_status = asclin->txInProgress;
|
||||
uint16 tx_fifo_size = (uint16)asclin->tx->size;
|
||||
|
||||
if (*count != 0)
|
||||
{
|
||||
if ((!tx_status) && (*count > tx_fifo_size)) /*Transmission not initialised and data size is greater than S/W FIFO*/
|
||||
{
|
||||
Ifx_Fifo_write(asclin->tx, data, tx_fifo_size, timeout); /*Fill upto the S/W FIFO size and initiate transmission*/
|
||||
IfxAsclin_Asc_initiateTransmission(asclin);
|
||||
|
||||
left = Ifx_Fifo_write(asclin->tx, (((const uint8 *)data) + tx_fifo_size), (*count) - tx_fifo_size, timeout);
|
||||
IfxAsclin_Asc_initiateTransmission(asclin); /*Will initiate transmission only if txInProgress is False, otherwise interrupts will continue to push data to H/W FIFO*/
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
left = Ifx_Fifo_write(asclin->tx, data, *count, timeout);
|
||||
IfxAsclin_Asc_initiateTransmission(asclin);
|
||||
}
|
||||
|
||||
*count -= left;
|
||||
result = left == 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,615 @@
|
||||
/**
|
||||
* \file IfxAsclin_Asc.h
|
||||
* \brief ASCLIN ASC details
|
||||
* \ingroup IfxLld_Asclin
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Asclin_Asc_Usage How to use the ASCLIN ASC Interface driver?
|
||||
* \ingroup IfxLld_Asclin
|
||||
*
|
||||
* The ASC interface driver provides a default ASCLIN configuration for asynchronous serial communication in 8bit mode, and a set of data transfer routines.
|
||||
*
|
||||
* Data transfers are buffered by the hardware based FIFOs, and in addition by software based FIFOs with a configurable size. Incoming and outgoing data is transfered in background from/to the ASCLIN peripheral by interrupt service handlers, which are part of this driver as well. This allows a nonblocking communication without stalling the thread(s) from where data is sent and received.
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
* \section IfxLld_Asclin_Asc_Preparation Preparation
|
||||
* \subsection IfxLld_Asclin_Asc_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
* \code
|
||||
* #include <Asclin/Asc/IfxAsclin_Asc.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Asc_Variables Variables
|
||||
*
|
||||
* Declare the ASC handle and the FIFOs as global variables in your C code:
|
||||
*
|
||||
* \code
|
||||
* // used globally
|
||||
* static IfxAsclin_Asc asc;
|
||||
*
|
||||
* #define ASC_TX_BUFFER_SIZE 64
|
||||
* static uint8 ascTxBuffer[ASC_TX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];
|
||||
*
|
||||
* #define ASC_RX_BUFFER_SIZE 64
|
||||
* static uint8 ascRxBuffer[ASC_RX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];
|
||||
* \endcode
|
||||
*
|
||||
* As you can see above, the transfer buffers allocate not only memory for the data itself, but also for FIFO runtime variables. 8 bytes have to be added to ensure a proper circular buffer handling independent from the address to which the buffers have been located.
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Asc_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priorities for the Interrrupt handlers. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define IFX_INTPRIO_ASCLIN0_TX 1
|
||||
* #define IFX_INTPRIO_ASCLIN0_RX 2
|
||||
* #define IFX_INTPRIO_ASCLIN0_ER 3
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routines to your C code. They have to call the ASC interrupt handlers by passing the asc handle:
|
||||
* \code
|
||||
* IFX_INTERRUPT(asclin0TxISR, 0, IFX_INTPRIO_ASCLIN0_TX)
|
||||
* {
|
||||
* IfxAsclin_Asc_isrTransmit(&asc);
|
||||
* }
|
||||
*
|
||||
* IFX_INTERRUPT(asclin0RxISR, 0, IFX_INTPRIO_ASCLIN0_RX)
|
||||
* {
|
||||
* IfxAsclin_Asc_isrReceive(&asc);
|
||||
* }
|
||||
*
|
||||
* IFX_INTERRUPT(asclin0ErISR, 0, IFX_INTPRIO_ASCLIN0_ER)
|
||||
* {
|
||||
* IfxAsclin_Asc_isrError(&asc);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handlers in your initialisation function:
|
||||
* \code
|
||||
* // install interrupt handlers
|
||||
* IfxCpu_Irq_installInterruptHandler(&asclin0TxISR, IFX_INTPRIO_ASCLIN0_TX);
|
||||
* IfxCpu_Irq_installInterruptHandler(&asclin0RxISR, IFX_INTPRIO_ASCLIN0_RX);
|
||||
* IfxCpu_Irq_installInterruptHandler(&asclin0ErISR, IFX_INTPRIO_ASCLIN0_ER);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Asc_Init Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function. Here an example:
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxAsclin_Asc_Config ascConfig;
|
||||
* IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN0);
|
||||
*
|
||||
* // set the desired baudrate
|
||||
* ascConfig.baudrate.prescaler = 1;
|
||||
* ascConfig.baudrate.baudrate = 1000000; // FDR values will be calculated in initModule
|
||||
*
|
||||
* // ISR priorities and interrupt target
|
||||
* ascConfig.interrupt.txPriority = IFX_INTPRIO_ASCLIN0_TX;
|
||||
* ascConfig.interrupt.rxPriority = IFX_INTPRIO_ASCLIN0_RX;
|
||||
* ascConfig.interrupt.erPriority = IFX_INTPRIO_ASCLIN0_ER;
|
||||
* ascConfig.interrupt.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());
|
||||
*
|
||||
* // FIFO configuration
|
||||
* ascConfig.txBuffer = &ascTxBuffer;
|
||||
* ascConfig.txBufferSize = ASC_TX_BUFFER_SIZE;
|
||||
*
|
||||
* ascConfig.rxBuffer = &ascRxBuffer;
|
||||
* ascConfig.rxBufferSize = ASC_RX_BUFFER_SIZE;
|
||||
*
|
||||
* // pin configuration
|
||||
* const IfxAsclin_Asc_Pins pins = {
|
||||
* NULL, IfxPort_InputMode_pullUp, // CTS pin not used
|
||||
* &IfxAsclin0_RXA_P14_1_IN, IfxPort_InputMode_pullUp, // Rx pin
|
||||
* NULL, IfxPort_OutputMode_pushPull, // RTS pin not used
|
||||
* &IfxAsclin0_TX_P14_0_OUT, IfxPort_OutputMode_pushPull, // Tx pin
|
||||
* IfxPort_PadDriver_cmosAutomotiveSpeed1
|
||||
* };
|
||||
* ascConfig.pins = &pins;
|
||||
*
|
||||
* // initialize module
|
||||
* //IfxAsclin_Asc asc; // defined globally
|
||||
* IfxAsclin_Asc_initModule(&asc, &ascConfig);
|
||||
* \endcode
|
||||
*
|
||||
* The ASC is ready for use now!
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Asclin_Asc_DataTransfers Data Transfers
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Asc_DataSimple Simple Transfers
|
||||
*
|
||||
* The ASC driver provides simple to use transfer functions, which are blocking.
|
||||
*
|
||||
* This means: you can send as much data as you want without taking care for the fill state of the FIFO. If the FIFO is full, the blocking function will wait until the next byte has been transfered to ASCLIN before putting the new byte into the FIFO:
|
||||
* \code
|
||||
* // send 3 bytes
|
||||
* IfxAsclin_Asc_blockingWrite(&asc, 0x01);
|
||||
* IfxAsclin_Asc_blockingWrite(&asc, 0x02);
|
||||
* IfxAsclin_Asc_blockingWrite(&asc, 0x03);
|
||||
* \endcode
|
||||
*
|
||||
* A simple to use receive function is available as well. If no data is in the receive FIFO, it will wait until the next byte has been received:
|
||||
* \code
|
||||
* // receive a byte
|
||||
* uint8 data = IfxAsclin_Asc_blockingRead(&asc);
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Asc_DataStream Streamed Transfers
|
||||
*
|
||||
* Streamed transfers are handled faster by the ASC driver and therefore they are recommended whenever a large bulk of data should be sent. Here an example:
|
||||
* \code
|
||||
* uint8 txData[9] = { 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x65, 0x6f, 0x6e, 0x0a };
|
||||
* {
|
||||
* Ifx_SizeT count = 9;
|
||||
* IfxAsclin_Asc_write(&asc, txData, &count, TIME_INFINITE);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* Data can be received the following way:
|
||||
* \code
|
||||
* uint8 rxData[5];
|
||||
*
|
||||
* {
|
||||
* // wait until 5 bytes have been received
|
||||
* Ifx_SizeT count = 5;
|
||||
* IfxAsclin_Asc_read(&asc, rxData, &count, TIME_INFINITE);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Or alternatively with:
|
||||
* \code
|
||||
* uint8 rxData[5];
|
||||
*
|
||||
* {
|
||||
* // how many bytes have been received?
|
||||
* Ifx_SizeT count = IfxAsclin_Asc_getReadCount(&asc);
|
||||
*
|
||||
* // limit to our buffer size
|
||||
* count = count < 5 ? count : 5;
|
||||
*
|
||||
* // transfer received data into buffer
|
||||
* IfxAsclin_Asc_read(&asc, rxData, &count, TIME_INFINITE);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Asclin_Asc ASC
|
||||
* \ingroup IfxLld_Asclin
|
||||
* \defgroup IfxLld_Asclin_Asc_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Asclin_Asc
|
||||
* \defgroup IfxLld_Asclin_Asc_InterruptFunctions Interrupt Functions
|
||||
* \ingroup IfxLld_Asclin_Asc
|
||||
* \defgroup IfxLld_Asclin_Asc_SimpleCom Simple Communication
|
||||
* \ingroup IfxLld_Asclin_Asc
|
||||
* \defgroup IfxLld_Asclin_Asc_StreamCom Stream based Communication (STDIO)
|
||||
* \ingroup IfxLld_Asclin_Asc
|
||||
* \defgroup IfxLld_Asclin_Asc_ModuleFunctions Module Functions
|
||||
* \ingroup IfxLld_Asclin_Asc
|
||||
*/
|
||||
|
||||
#ifndef IFXASCLIN_ASC_H
|
||||
#define IFXASCLIN_ASC_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Asclin/Std/IfxAsclin.h"
|
||||
#include "_Lib/DataHandling/Ifx_Fifo.h"
|
||||
#include "SysSe/Bsp/Bsp.h"
|
||||
#include "StdIf/IfxStdIf_DPipe.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Structure for Error Flags
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8 parityError : 1; /**< \brief parity error */
|
||||
uint8 frameError : 1; /**< \brief transmit complete/pending error */
|
||||
uint8 rxFifoOverflow : 1; /**< \brief receive FIFO overflow error */
|
||||
uint8 rxFifoUnderflow : 1; /**< \brief receive FIFO underflow error */
|
||||
uint8 txFifoOverflow : 1; /**< \brief transmit FIFO overflow error */
|
||||
} IfxAsclin_Asc_ErrorFlags;
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Asc_DataStructures
|
||||
* \{ */
|
||||
/** \brief Structure for baudrate
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
float32 baudrate; /**< \brief value of the required baudrate */
|
||||
uint16 prescaler; /**< \brief BITCON.PRESCALER, the division ratio of the predevider */
|
||||
IfxAsclin_OversamplingFactor oversampling; /**< \brief BITCON.OVERSAMPLING, division ratio of the baudrate post devider */
|
||||
} IfxAsclin_Asc_BaudRate;
|
||||
|
||||
/** \brief Structure for bit timings
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_SamplesPerBit medianFilter; /**< \brief BITCON.SM, number of samples per bit (1 or 3), sample mode/median filter */
|
||||
IfxAsclin_SamplePointPosition samplePointPosition; /**< \brief BITCON.SAMPLEPOINT, sample point position */
|
||||
} IfxAsclin_Asc_BitTimingControl;
|
||||
|
||||
/** \brief Structure for FIFO control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_TxFifoInletWidth inWidth; /**< \brief TXFIFOCON.INW, transmit FIFO inlet width */
|
||||
IfxAsclin_RxFifoOutletWidth outWidth; /**< \brief RXFIFOCON.OTW, receive FIFO oulet width */
|
||||
IfxAsclin_TxFifoInterruptLevel txFifoInterruptLevel; /**< \brief TXFIFOCON.INTLEVEL, Tx FIFO interrupt level */
|
||||
IfxAsclin_RxFifoInterruptLevel rxFifoInterruptLevel; /**< \brief RXFIFOCON.INTLEVEL, Rx FIFO interrupt level */
|
||||
IfxAsclin_ReceiveBufferMode buffMode; /**< \brief RXFIFOCON.BUFF, receive buffer mode (Rx FIFO or Rx buffer) */
|
||||
} IfxAsclin_Asc_FifoControl;
|
||||
|
||||
/** \brief Structure for frame control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_IdleDelay idleDelay; /**< \brief FRAMECON.IDLE, idle delay */
|
||||
IfxAsclin_StopBit stopBit; /**< \brief FRAMECON.STOP, number of stop bits */
|
||||
IfxAsclin_FrameMode frameMode; /**< \brief FRAMECON.MODE, mode of operation of the module */
|
||||
IfxAsclin_ShiftDirection shiftDir; /**< \brief FRAMECON.MSB, shift direction */
|
||||
IfxAsclin_ParityType parityType; /**< \brief FRAMECON.ODD, parity type (even or odd) */
|
||||
IfxAsclin_DataLength dataLength; /**< \brief DATCON.DATALENGTH, data length, number of bits per transfer */
|
||||
boolean parityBit; /**< \brief FRAMECON.PEN, parity enable */
|
||||
} IfxAsclin_Asc_FrameControl;
|
||||
|
||||
/** \brief Structure for interrupt configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 txPriority; /**< \brief transmit interrupt priority */
|
||||
uint16 rxPriority; /**< \brief receive interrupt priority */
|
||||
uint16 erPriority; /**< \brief error interrupt priority */
|
||||
IfxSrc_Tos typeOfService; /**< \brief type of interrupt service */
|
||||
} IfxAsclin_Asc_InterruptConfig;
|
||||
|
||||
/** \brief Structure for ASC pin configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IFX_CONST IfxAsclin_Cts_In *cts; /**< \brief ASC clear to send (CTS) pin */
|
||||
IfxPort_InputMode ctsMode; /**< \brief Cts pin as input */
|
||||
IFX_CONST IfxAsclin_Rx_In *rx; /**< \brief ASC Rx pin */
|
||||
IfxPort_InputMode rxMode; /**< \brief Rx pin as input */
|
||||
IFX_CONST IfxAsclin_Rts_Out *rts; /**< \brief ASC (request to send) RTS pin */
|
||||
IfxPort_OutputMode rtsMode; /**< \brief Rts as output */
|
||||
IFX_CONST IfxAsclin_Tx_Out *tx; /**< \brief ASC Tx pin */
|
||||
IfxPort_OutputMode txMode; /**< \brief Tx as output */
|
||||
IfxPort_PadDriver pinDriver; /**< \brief pad driver */
|
||||
} IfxAsclin_Asc_Pins;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \brief This union contains the error flags. In addition it allows to write and read to/from all flags as once via the ALL member.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
uint8 ALL;
|
||||
IfxAsclin_Asc_ErrorFlags flags;
|
||||
} IfxAsclin_Asc_ErrorFlagsUnion;
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Asc_DataStructures
|
||||
* \{ */
|
||||
/** \brief Module Handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_ASCLIN *asclin; /**< \brief pointer to ASCLIN registers */
|
||||
Ifx_Fifo *tx; /**< \brief Transmit FIFO buffer */
|
||||
Ifx_Fifo *rx; /**< \brief Receive FIFO buffer */
|
||||
volatile boolean txInProgress; /**< \brief Ongoing transfer. Will be set by IfxAsclin_Asc_initiateTransmission, and cleared by IfxAsclin_Asc_isrTransmit */
|
||||
volatile boolean rxSwFifoOverflow; /**< \brief Will be set by IfxAsclin_Asc_isrReceive if the SW Fifo overflowed */
|
||||
IfxAsclin_Asc_ErrorFlagsUnion errorFlags; /**< \brief error reported by ASCLIN during runtime (written by IfxAsclin_Asc_isrError) */
|
||||
Ifx_DataBufferMode dataBufferMode; /**< \brief Rx buffer mode */
|
||||
volatile uint32 sendCount; /**< \brief Number of byte that are send out, this value is reset with the function Asc_If_resetSendCount() */
|
||||
volatile Ifx_TickTime txTimestamp; /**< \brief Time stamp of the latest send byte */
|
||||
} IfxAsclin_Asc;
|
||||
|
||||
/** \brief Configuration structure of the module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_ASCLIN *asclin; /**< \brief pointer to ASCLIN registers */
|
||||
IfxAsclin_Asc_BaudRate baudrate; /**< \brief structure for baudrate */
|
||||
IfxAsclin_Asc_BitTimingControl bitTiming; /**< \brief structure for bit timings */
|
||||
IfxAsclin_Asc_FrameControl frame; /**< \brief structure for frame control */
|
||||
IfxAsclin_Asc_FifoControl fifo; /**< \brief structure for FIFO control */
|
||||
IfxAsclin_Asc_InterruptConfig interrupt; /**< \brief structure for interrupt configuration */
|
||||
IFX_CONST IfxAsclin_Asc_Pins *pins; /**< \brief structure for ASC pins */
|
||||
IfxAsclin_ClockSource clockSource; /**< \brief CSR.CLKSEL, clock source selection */
|
||||
IfxAsclin_Asc_ErrorFlagsUnion errorFlags; /**< \brief structure for error flags */
|
||||
Ifx_SizeT txBufferSize; /**< \brief Size of the tx buffer */
|
||||
void *txBuffer; /**< \brief The buffer parameter must point on a free memory location where the buffer object will be Initialised.
|
||||
*
|
||||
* The Size of this area must be at least equals to "txBufferSize + sizeof(Ifx_Fifo) + 8". Not tacking this in account may result in unpredictable behavior.
|
||||
*
|
||||
* If set to NULL_PTR, the buffer will be allocated dynamically according to txBufferSize */
|
||||
Ifx_SizeT rxBufferSize; /**< \brief Size of the rx buffer */
|
||||
void *rxBuffer; /**< \brief The buffer parameter must point on a free memory location where the buffer object will be Initialised.
|
||||
*
|
||||
* The Size of this area must be at least equals to "rxBufferSize + sizeof(Ifx_Fifo) + 8". Not tacking this in account may result in unpredictable behavior.
|
||||
*
|
||||
* If set to NULL, the buffer will be allocated dynamically according to rxBufferSize */
|
||||
boolean loopBack; /**< \brief IOCR.LB, loop back mode selection, 0 for disable, 1 for enable */
|
||||
Ifx_DataBufferMode dataBufferMode; /**< \brief Rx buffer mode */
|
||||
} IfxAsclin_Asc_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Asc_InterruptFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief ISR error routine.
|
||||
* \see IfxSdtIf_DPipe_OnError
|
||||
*
|
||||
* Currently it only stores error flags in the handle (asclin->errorFlags) whenever an error happened.
|
||||
* The user software could react on these flags, e.g. it could re-initialize the module.
|
||||
* \param asclin module handler
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Asc_isrError(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief ISR receive routine
|
||||
* \see IfxSdtIf_DPipe_OnReceive
|
||||
* \param asclin module handler
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Asc_isrReceive(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief ISR transmit routine
|
||||
* \see IfxSdtIf_DPipe_OnTransmit
|
||||
* \param asclin module handler
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Asc_isrTransmit(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Asc_SimpleCom
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Reads data from the Rx FIFO
|
||||
* \param asclin module handle
|
||||
* \return number of received data words
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Asc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN uint8 IfxAsclin_Asc_blockingRead(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief Writes data into the Tx FIFO
|
||||
* \param asclin module handle
|
||||
* \param data the data byte which should be sent
|
||||
* \return Returns TRUE if data could be written
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Asc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Asc_blockingWrite(IfxAsclin_Asc *asclin, uint8 data);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Asc_StreamCom
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_CanReadCount
|
||||
* \param asclin module handle
|
||||
* \param count Count of data which should be checked (in bytes)
|
||||
* \param timeout in system timer ticks
|
||||
* \return Returns TRUE if at least count bytes are available for read in the rx buffer, if not the Event is armed to be set when the buffer count is bigger or equal to the requested count.
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Asc_canReadCount(IfxAsclin_Asc *asclin, Ifx_SizeT count, Ifx_TickTime timeout);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_CanWriteCount
|
||||
* \param asclin module handle
|
||||
* \param count Count of data which should be checked (in bytes)
|
||||
* \param timeout in system timer ticks
|
||||
* \return Returns TRUE if at least count bytes can be written to the tx buffer, if not the Event is armed to be set when the buffer free count is bigger or equal to the requested count
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Asc_canWriteCount(IfxAsclin_Asc *asclin, Ifx_SizeT count, Ifx_TickTime timeout);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_ClearRx
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Asc_clearRx(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_ClearTx
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Asc_clearTx(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_FlushTx
|
||||
* \param asclin module handle
|
||||
* \param timeout in system timer ticks
|
||||
* \return Returns TRUE if the FIFO is empty
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Asc_flushTx(IfxAsclin_Asc *asclin, Ifx_TickTime timeout);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_GetReadCount
|
||||
* \param asclin module handle
|
||||
* \return The number of bytes in the rx buffer
|
||||
*/
|
||||
IFX_EXTERN sint32 IfxAsclin_Asc_getReadCount(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief \see IIfxStdIf_DPipe_GetReadEvent
|
||||
* \param asclin module handle
|
||||
* \return Read event object
|
||||
*/
|
||||
IFX_EXTERN IfxStdIf_DPipe_ReadEvent IfxAsclin_Asc_getReadEvent(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_GetSendCount
|
||||
* \param asclin module handle
|
||||
* \return number of bytes send
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxAsclin_Asc_getSendCount(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_GetTxTimeStamp
|
||||
* \param asclin module handle
|
||||
* \return Time in ticks
|
||||
*/
|
||||
IFX_EXTERN Ifx_TickTime IfxAsclin_Asc_getTxTimeStamp(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_GetWriteCount
|
||||
* \param asclin module handle
|
||||
* \return The number of free bytes in the tx buffer
|
||||
*/
|
||||
IFX_EXTERN sint32 IfxAsclin_Asc_getWriteCount(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief \see IIfxStdIf_DPipe_GetWriteEvent
|
||||
* \param asclin module handle
|
||||
* \return Write event object
|
||||
*/
|
||||
IFX_EXTERN IfxStdIf_DPipe_WriteEvent IfxAsclin_Asc_getWriteEvent(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_Read
|
||||
* \param asclin module handle
|
||||
* \param data Pointer to the start of data
|
||||
* \param count Pointer to the count of data (in bytes).
|
||||
* \param timeout in system timer ticks
|
||||
* \return Returns TRUE if all items could be read\n
|
||||
* Returns FALSE if not all the items could be read
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Asc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Asc_read(IfxAsclin_Asc *asclin, void *data, Ifx_SizeT *count, Ifx_TickTime timeout);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_ResetSendCount
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Asc_resetSendCount(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief \see IfxStdIf_DPipe_Write
|
||||
* \param asclin module handle
|
||||
* \param data Pointer to the start of data
|
||||
* \param count Pointer to the count of data (in bytes).
|
||||
* \param timeout in system timer ticks
|
||||
* \return Returns TRUE if all items could be written\n
|
||||
* Returns FALSE if not all the items could be written
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Asc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Asc_write(IfxAsclin_Asc *asclin, const void *data, Ifx_SizeT *count, Ifx_TickTime timeout);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Asc_ModuleFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Disables the module
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Asc_disableModule(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief Initialises the module
|
||||
* \param asclin module handle
|
||||
* \param config predefined configuration structure of the module
|
||||
* \return Status
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Asc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN IfxAsclin_Status IfxAsclin_Asc_initModule(IfxAsclin_Asc *asclin, const IfxAsclin_Asc_Config *config);
|
||||
|
||||
/** \brief Fills the config structure with default values
|
||||
* \param config configuration structure of the module
|
||||
* \param asclin pointer to ASCLIN registers
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Asc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Asc_initModuleConfig(IfxAsclin_Asc_Config *config, Ifx_ASCLIN *asclin);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initiate the data transmission
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Asc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Asc_initiateTransmission(IfxAsclin_Asc *asclin);
|
||||
|
||||
/** \brief Initialize the standard interface to the device driver
|
||||
* \param stdif standard interface object, will be initialized by the function
|
||||
* \param asclin device driver object used by the standard interface. must be initialised separately
|
||||
* \return TRUE on success, else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Asc_stdIfDPipeInit(IfxStdIf_DPipe *stdif, IfxAsclin_Asc *asclin);
|
||||
|
||||
#endif /* IFXASCLIN_ASC_H */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,858 @@
|
||||
/**
|
||||
* \file IfxAsclin_Lin.h
|
||||
* \brief ASCLIN LIN details
|
||||
* \ingroup IfxLld_Asclin
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Asclin_Lin_Usage How to use the ASCLIN LIN Interface driver?
|
||||
* \ingroup IfxLld_Asclin
|
||||
*
|
||||
* The LIN interface driver provides a default ASCLIN configuration for asynchronous serial communication in 8bit mode, and a set of data transfer routines.
|
||||
* It supports all four elementary LIN transactions in polling mode.
|
||||
* TxH - Transmission of Header
|
||||
* TxR - Transmission of Response
|
||||
* RxH - Reception of Header
|
||||
* RxR - Reception of Response
|
||||
*
|
||||
* The driver also provides a LIN Master to be configured in Interrupt mode. In interrupt mode, following Lin frame transactions are provided.
|
||||
* 1.Transmit Header only.
|
||||
* 2.Transmit both Header and Response.
|
||||
* 3.Transmit Header and Receive Response.
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
* \section IfxLld_Asclin_Lin_Preparation Preparation
|
||||
* \subsection IfxLld_Asclin_Lin_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
* \code
|
||||
* #include <Asclin/Lin/IfxAsclin_Lin.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Lin_Variables Variables
|
||||
*
|
||||
* Declare the LIN handle as global variable in your C code:
|
||||
*
|
||||
* \code
|
||||
* // used globally
|
||||
* static IfxAsclin_Lin linMaster;
|
||||
* static IfxAsclin_Lin linSlave;
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Lin_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* Define priorities for the Interrrupt handlers.
|
||||
* \code
|
||||
*
|
||||
* #define IFX_INTPRIO_ASCLIN1_RX 4 // Define the LIN1 receive interrupt priority.
|
||||
* #define IFX_INTPRIO_ASCLIN1_TX 8 // Define the LIN1 transmit interrupt priority.
|
||||
* #define IFX_INTPRIO_ASCLIN1_EX 12 // Define the LIN1 error interrupt priority.
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routines to your C code. They have to call the LIN interrupt handlers by passing the lin handle:
|
||||
* \code
|
||||
* IFX_INTERRUPT(ISR_Lin1_rx, 0, IFX_INTPRIO_ASCLIN1_RX);
|
||||
* IFX_INTERRUPT(ISR_Lin1_tx, 0, IFX_INTPRIO_ASCLIN1_TX);
|
||||
* IFX_INTERRUPT(ISR_Lin1_ex, 0, IFX_INTPRIO_ASCLIN1_EX);
|
||||
*
|
||||
* void ISR_Lin1_rx(void)
|
||||
* {
|
||||
* IfxAsclin_Lin_isrReceive(&linMaster);
|
||||
* }
|
||||
* void ISR_Lin1_tx(void)
|
||||
* {
|
||||
* IfxAsclin_Lin_isrTransmit(&linMaster);
|
||||
* }
|
||||
* void ISR_Lin1_ex(void)
|
||||
* {
|
||||
* IfxAsclin_Lin_isrError(&linMaster);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Lin_Init Module Initialisation
|
||||
*
|
||||
* The module can be initialised as either Master or Slave. Here an example:
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Lin_Init_Master Module Initialisation as Master
|
||||
*
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxAsclin_Lin_Config linMasterConfig;
|
||||
* IfxAsclin_Lin_initModuleConfig(&linMasterConfig, &MODULE_ASCLIN1);
|
||||
*
|
||||
* // set the lin mode of operation
|
||||
* linMasterConfig.linMode = IfxAsclin_LinMode_master;
|
||||
*
|
||||
* // set the desired baudrate
|
||||
* linMasterConfig.btc.prescaler = 4;
|
||||
* linMasterConfig.brg.baudrate = 19200; // FDR values will be calculated in initModule
|
||||
*
|
||||
* // pin configuration
|
||||
* const IfxAsclin_Lin_Pins pins = {
|
||||
* &IfxAsclin1_RXB_P15_5_IN, IfxPort_InputMode_pullUp, // Rx pin
|
||||
* &IfxAsclin1_TX_P15_4_OUT, IfxPort_OutputMode_pushPull, // Tx pin
|
||||
* IfxPort_PadDriver_cmosAutomotiveSpeed1
|
||||
* };
|
||||
* linMasterConfig.pins = &pins;
|
||||
*
|
||||
* //Lin Master Interrupt Config. Only needed for interrupt mode.
|
||||
* linConfig.isInterruptMode = TRUE;
|
||||
* linConfig.interrupt.rxPriority = ISR_PRIORITY(INTERRUPT_LIN1_RX);
|
||||
* linConfig.interrupt.txPriority = ISR_PRIORITY(INTERRUPT_LIN1_TX);
|
||||
* linConfig.interrupt.exPriority = ISR_PRIORITY(INTERRUPT_LIN1_EX);
|
||||
*
|
||||
* //Optionally, if any interrupt has to be enabled during initialisation it can be done as follows.
|
||||
* //Otherwise the driver will enable required interrupts during run time.
|
||||
*
|
||||
* linConfig.interrupt.enabledInterrupt.exCollisionDetectionError = TRUE; //This is optional example.
|
||||
*
|
||||
* linConfig.lin.csi = FALSE;//checksum injection not written into RxFIFO
|
||||
*
|
||||
* // initialize module
|
||||
* IfxAsclin_Lin_initModule(&linMaster, &linMasterConfig);
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Lin_Init_Slave Module Initialisation as Slave
|
||||
*
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxAsclin_Lin_Config linSlaveConfig;
|
||||
* IfxAsclin_Lin_initModuleConfig(&linSlaveConfig, &MODULE_ASCLIN1);
|
||||
*
|
||||
* // set the lin mode of operation
|
||||
* linSlaveConfig.linMode = IfxAsclin_LinMode_slave;
|
||||
*
|
||||
* // set the desired baudrate
|
||||
* linSlaveConfig.btc.prescaler = 4;
|
||||
* linSlaveConfig.brg.baudrate = 19200; // FDR values will be calculated in initModule
|
||||
*
|
||||
* // choose the auto baudrate detection configuration
|
||||
* linSlaveConfig.brd.abd = FALSE;
|
||||
* linSlaveConfig.brd.lowerLimit = 0x4;
|
||||
* linSlaveConfig.brd.upperLimit = 0xF0;
|
||||
*
|
||||
* // pin configuration
|
||||
* const IfxAsclin_Lin_Pins pins = {
|
||||
* &IfxAsclin1_RXB_P15_5_IN, IfxPort_InputMode_pullUp, // Rx pin
|
||||
* &IfxAsclin1_TX_P15_4_OUT, IfxPort_OutputMode_pushPull, // Tx pin
|
||||
* IfxPort_PadDriver_cmosAutomotiveSpeed1
|
||||
* };
|
||||
* linSlaveConfig.pins = &pins;
|
||||
*
|
||||
*
|
||||
*
|
||||
* // initialize module
|
||||
* //IfxAsclin_Lin linSlave; // defined globally
|
||||
* IfxAsclin_Lin_initModule(&linSlave, &linSlaveConfig);
|
||||
* \endcode
|
||||
*
|
||||
* The LIN is ready for use now!
|
||||
*
|
||||
* \section IfxLld_Asclin_Lin_DataTransfers Data Transfers
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Lin_DataMaster Master Transfers
|
||||
*
|
||||
* The LIN driver provides all three master elementary transfers.
|
||||
*
|
||||
* This means: you can send a header and based on the id byte, after transmission of header
|
||||
* you can send or receive response and also can ignore the header based on the id:
|
||||
* \code
|
||||
* // set the id bytes
|
||||
* uint8 txId = 0x80; // for sending respose after header
|
||||
* uint8 rxId = 0xC1; // for receiving respose after header
|
||||
*
|
||||
* // prepare transmit bytes incase of sending response
|
||||
* uint8 txData[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
*
|
||||
* // prepare receive buffer incase of receiving response
|
||||
* uint8 rxData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
*
|
||||
* uint32 size = 8;
|
||||
*
|
||||
* //Polling mode APIs
|
||||
* //send response case
|
||||
* IfxAsclin_Lin_sendHeader(&linMaster, &txId);
|
||||
*
|
||||
* if (lin.acknowledgmentFlags.txHeaderEnd == 1) // if the header is been transmitted succesfully
|
||||
* {
|
||||
* IfxAsclin_Lin_sendResponse(&linMaster, txData, size);
|
||||
* }
|
||||
*
|
||||
* //receive response case
|
||||
* IfxAsclin_Lin_sendHeader(&linMaster, &rxId);
|
||||
*
|
||||
* if (lin.acknowledgmentFlags.txHeaderEnd == 1) // if the header is been transmitted succesfully
|
||||
* {
|
||||
* IfxAsclin_Lin_receiveResponse(&linMaster, rxData, size);
|
||||
* }
|
||||
*
|
||||
* //Interrupt mode APIs
|
||||
* IfxAsclin_Lin_PduType pdu;
|
||||
* pdu.pid = 0x42;
|
||||
* pdu.checksumMode = IfxAsclin_Checksum_enhanced;
|
||||
* pdu.dataLength = 8;
|
||||
* pdu.direction = IfxAsclin_Lin_Direction_TransmitHeaderAndResponse; //Transmits both Header and Response
|
||||
* pdu.dataPtr = &txData[0];
|
||||
* IfxAsclin_Lin_sendFrame(&linMaster,&pdu);
|
||||
* //Here Poll for linMaster.acknowledgmentFlags.txResponseEnd to detect end of transmission of frame.
|
||||
*
|
||||
* pdu.pid = 0xC4;
|
||||
* pdu.direction = IfxAsclin_Lin_Direction_TransmitHeaderAndReceiveResponse; //Transmits Header and expects slave to respond
|
||||
* IfxAsclin_Lin_sendFrame(&linMaster,&pdu);
|
||||
* //Here Poll for linMaster.acknowledgmentFlags.rxResponseEnd
|
||||
* //linMaster.linFrameData.rxResponseData[8] will have received response data if slave replies.
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Lin_DataSlave Slave Transfers
|
||||
*
|
||||
* Same as master the LIN driver provides all three slave elemnatry tranfers.
|
||||
*
|
||||
* This means: you can receive a header and based on the id byte received,
|
||||
* you can send or receive response and can also ignore the header based on the id:
|
||||
* \code
|
||||
* uint8 id; // for storing received id byte
|
||||
*
|
||||
* // prepare transmit bytes incase of sending response
|
||||
* uint8 txData[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
*
|
||||
* // prepare receive buffer incase of receiving response
|
||||
* uint8 rxData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
*
|
||||
* uint32 size = 8;
|
||||
*
|
||||
* // receive header
|
||||
* IfxAsclin_Lin_receiveHeader(&linSlave, &id);
|
||||
*
|
||||
* // if data is requsted by master
|
||||
* if(id == txId)
|
||||
* {
|
||||
* IfxAsclin_Lin_sendResponse(&linSlave, txData, size); // send response
|
||||
* }
|
||||
*
|
||||
* // if header is follwed by response
|
||||
* else if(id == rxId)
|
||||
* {
|
||||
* IfxAsclin_Lin_receiveResponse(&linSlave, rxData, size); // receive response
|
||||
* }
|
||||
*
|
||||
* // if header is not for this slave
|
||||
* else
|
||||
* {
|
||||
* IfxAsclin_Lin_ignoreHeader(&linSlave);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Asclin_Lin LIN
|
||||
* \ingroup IfxLld_Asclin
|
||||
* \defgroup IfxLld_Asclin_Lin_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Asclin_Lin
|
||||
* \defgroup IfxLld_Asclin_Lin_ElementaryTransactions Elementary Transactions
|
||||
* \ingroup IfxLld_Asclin_Lin
|
||||
* \defgroup IfxLld_Asclin_Lin_ModuleFunctions Module Functions
|
||||
* \ingroup IfxLld_Asclin_Lin
|
||||
* \defgroup IfxLld_Asclin_Lin_errorHandlingFunctions Error Handling Functions
|
||||
* \ingroup IfxLld_Asclin_Lin
|
||||
* \defgroup IfxLld_Asclin_Lin_InterruptFunctions Interrupt Functions
|
||||
* \ingroup IfxLld_Asclin_Lin
|
||||
* \defgroup IfxLld_Asclin_Lin_Enumerations Enumerations
|
||||
* \ingroup IfxLld_Asclin_Lin
|
||||
*/
|
||||
|
||||
#ifndef IFXASCLIN_LIN_H
|
||||
#define IFXASCLIN_LIN_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Asclin/Std/IfxAsclin.h"
|
||||
#include "_Utilities/Ifx_Assert.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------------Macros-----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#define IFXASCLIN_LIN_SEND_RESPONSE (0x80)
|
||||
|
||||
#define IFXASCLIN_LIN_RECEIVE_RESPONSE (0xC1)
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Lin_Enumerations
|
||||
* \{ */
|
||||
/** \brief Defines the type of Lin Master Frame.
|
||||
* (Transmit Header only) or
|
||||
* (Transmit Header and Response) or
|
||||
* (Transmit Header and Receive Response).
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxAsclin_Lin_Direction_TransmitHeader = 0, /**< \brief Transmit Header */
|
||||
IfxAsclin_Lin_Direction_TransmitHeaderAndResponse = 1, /**< \brief Transmit both Header and Response */
|
||||
IfxAsclin_Lin_Direction_TransmitHeaderAndReceiveResponse = 2 /**< \brief Transmit Header and Receive Response */
|
||||
} IfxAsclin_Lin_Direction;
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Lin_DataStructures
|
||||
* \{ */
|
||||
/** \brief Structure to store interrupts which are enabled during initialisation.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 rxReceivedHeader : 1; /**< \brief Received Header */
|
||||
uint16 rxReceivedResponse : 1; /**< \brief Received Response */
|
||||
uint16 txTransmittedHeader : 1; /**< \brief Transmitted Header */
|
||||
uint16 txTransmittedResponse : 1; /**< \brief Transmitted Response */
|
||||
uint16 exBreakDetected : 1; /**< \brief Break Detected */
|
||||
uint16 exTransmissionCompleted : 1; /**< \brief Transmission Completed */
|
||||
uint16 exHeaderTimeout : 1; /**< \brief Header Timeout */
|
||||
uint16 exResponseTimeout : 1; /**< \brief Response Timeout */
|
||||
uint16 exLinParityError : 1; /**< \brief Lin Parity Error */
|
||||
uint16 exLinAutobaudDetectionError : 1; /**< \brief Lin Autobaud Detection Error */
|
||||
uint16 exLinChecksumError : 1; /**< \brief Lin Checksum Error */
|
||||
uint16 exFramingError : 1; /**< \brief Framing Error */
|
||||
uint16 exCollisionDetectionError : 1; /**< \brief Collision Detection Error */
|
||||
uint16 exReceiveFIFOOverflow : 1; /**< \brief Receive FIFO Overflow */
|
||||
uint16 exTransmitFIFOOverflow : 1; /**< \brief Transmit FIFO Overflow */
|
||||
} IfxAsclin_Lin_EnabledInterrupts;
|
||||
|
||||
/** \brief Structure for Lin Frame Control flags
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 txSendHeaderOnly : 1; /**< \brief Flag indicating that only Header is transmitted */
|
||||
uint16 txSendResponse : 1; /**< \brief Flag to indicate Response is transmitted */
|
||||
uint16 txHeaderInProgress : 1; /**< \brief Flag to indicate Header transmission is initiated and is in progress */
|
||||
uint16 txResponseInProgress : 1; /**< \brief Flag to indicate Response transmission is initiated and is in progress */
|
||||
uint16 rxHeaderInProgress : 1; /**< \brief Flag to indicate Header reception is initiated and is in progress */
|
||||
uint16 rxResponseInProgress : 1; /**< \brief Flag to indicate Response reception is initiated and is in progress */
|
||||
uint16 txHeaderErrorOccurred : 1; /**< \brief Flag to indicate error occurred during transmission of Header */
|
||||
uint16 txResponseErrorOccurred : 1; /**< \brief Flag to indicate error occurred during transmission of Response */
|
||||
uint16 rxHeaderErrorOccurred : 1; /**< \brief Flag to indicate error occurred during reception of Header */
|
||||
uint16 rxResponseErrorOccurred : 1; /**< \brief Flag to indicate error occurred during reception of Response */
|
||||
} IfxAsclin_Lin_FrameControlFlags;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Lin_DataStructures
|
||||
* \{ */
|
||||
/** \brief Structure for Acknowledgement Flags
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8 txHeaderEnd : 1; /**< \brief transmit header end */
|
||||
uint8 txResponseEnd : 1; /**< \brief transmit response end */
|
||||
uint8 rxHeaderEnd : 1; /**< \brief receive header end */
|
||||
uint8 rxResponseEnd : 1; /**< \brief receive response end */
|
||||
uint8 txCompleted : 1; /**< \brief transmission completed */
|
||||
} IfxAsclin_Lin_AcknowledgementFlags;
|
||||
|
||||
/** \brief Structure for Baudrate Detection
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean abd; /**< \brief LINCON.ABD, autobaud detection enable */
|
||||
uint8 lowerLimit; /**< \brief BRD.LOWERLIMIT, auto baudrate detection lowerlimit */
|
||||
uint8 upperLimit; /**< \brief BRD.UPPERLIMIT, auto baudrate detection upperlimit */
|
||||
uint8 measured; /**< \brief BRD.MEASURED, measured time interval between the
|
||||
* first and the fifth falling edge of the sync byte */
|
||||
} IfxAsclin_Lin_BaudrateDetection;
|
||||
|
||||
/** \brief Structure for Baudrate Generation
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
float32 baudrate; /**< \brief value of the required baudrate */
|
||||
uint16 numerator; /**< \brief BRG.NUMERATOR, defines the numerator of fractional divider */
|
||||
uint16 denominator; /**< \brief BRG.DENOMINATOR, defines the denominator of fractional divider */
|
||||
} IfxAsclin_Lin_BaudrateGeneration;
|
||||
|
||||
/** \brief Structure for Bit Sampling
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8 filterDepth; /**< \brief IOCR.DEPTH, digital glitch filter depth */
|
||||
IfxAsclin_SamplesPerBit medianFilter; /**< \brief BITCON.SM, no. of samples per bit 1 or 3 */
|
||||
IfxAsclin_SamplePointPosition samplePointPosition; /**< \brief BITCON.SAMPLEPOINT, sample point position */
|
||||
} IfxAsclin_Lin_BitSamplingControl;
|
||||
|
||||
/** \brief Structure for Bit Timing
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 prescaler; /**< \brief BITCON.PRESCALER, predivider to generate the baud rate */
|
||||
IfxAsclin_OversamplingFactor oversampling; /**< \brief BITCON.OVERSAMPLING, postdivider, used for oversampling */
|
||||
} IfxAsclin_Lin_BitTimingControl;
|
||||
|
||||
/** \brief Structure for Data Control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_DataLength dataLength; /**< \brief DATCON.DATALENGTH, data length, number of bits per transfer */
|
||||
IfxAsclin_HeaderResponseSelect headerOnly; /**< \brief DATCON.HO, Lin frame with header and response or header only */
|
||||
IfxAsclin_LinResponseTimeoutMode responseTimeoutMode; /**< \brief DATCON.RM, response mode (response or frame timeout threshold) */
|
||||
IfxAsclin_Checksum checksum; /**< \brief DATCON.CSM, checksum mode (classic or enhanced) */
|
||||
uint16 responseTimeout; /**< \brief DATCON.RESPONSE, timeout limit */
|
||||
} IfxAsclin_Lin_DataControl;
|
||||
|
||||
/** \brief Structure for Error Flags
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8 frameError : 1; /**< \brief frame error */
|
||||
uint8 headerTimeout : 1; /**< \brief header timeout */
|
||||
uint8 responseTimeout : 1; /**< \brief response timeout */
|
||||
uint8 breakDetected : 1; /**< \brief break detected */
|
||||
uint8 linParityError : 1; /**< \brief lin parity error */
|
||||
uint8 linAutobaudDetectionError : 1; /**< \brief lin autobaud detection error */
|
||||
uint8 linChecksumError : 1; /**< \brief lin checksum error */
|
||||
uint8 collisionDetectionError : 1; /**< \brief collision detection error */
|
||||
uint8 rxFifoOverflow : 1; /**< \brief receive FIFO overflow error */
|
||||
uint8 txFifoOverflow : 1; /**< \brief transmit FIFO overflow error */
|
||||
} IfxAsclin_Lin_ErrorFlags;
|
||||
|
||||
/** \brief Structure for FIFO Control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_ReceiveBufferMode buffMode; /**< \brief RXFIFOCON.BUF, receive buffer mode (RXFIFO or RXBuffer) */
|
||||
IfxAsclin_TxFifoInletWidth inWidth; /**< \brief TXFIFOCON.INW, transmit FIFO inlet width */
|
||||
IfxAsclin_RxFifoOutletWidth outWidth; /**< \brief RXFIFOCON.OTW, receive FIFO oulet width */
|
||||
} IfxAsclin_Lin_FifoControl;
|
||||
|
||||
/** \brief Structure for Frame Control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_IdleDelay idleDelay; /**< \brief FRAMECON.IDLE, idle delay */
|
||||
IfxAsclin_LeadDelay leadDelay; /**< \brief FRAMECON.LEAD, lead delay */
|
||||
IfxAsclin_StopBit stopBit; /**< \brief FRAMECON.STOP, number of stop bits */
|
||||
IfxAsclin_ParityType parityType; /**< \brief FRAMECON.ODD, parity type (even or odd) */
|
||||
IfxAsclin_ShiftDirection shiftDir; /**< \brief FRAMECON.MSB, shift direction */
|
||||
boolean parityEnable; /**< \brief FRAMECON.PEN, parity enable */
|
||||
boolean collisionDetectionEnable; /**< \brief FRAMECON.CEN, collision detection enable */
|
||||
} IfxAsclin_Lin_FrameControl;
|
||||
|
||||
/** \brief Structure for Frame Data and Control flags
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8 rxResponseData[8]; /**< \brief Array to store received response data */
|
||||
uint8 headerID; /**< \brief header ID */
|
||||
uint8 txResponseLength; /**< \brief Length of transmitted response */
|
||||
uint8 rxResponseLength; /**< \brief Length of received response */
|
||||
IfxAsclin_Lin_FrameControlFlags flags; /**< \brief LIN frame control flags */
|
||||
} IfxAsclin_Lin_FrameDataControl;
|
||||
|
||||
/** \brief Structure for LIN Interrupt Configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 txPriority; /**< \brief transmit interrupt priority */
|
||||
uint16 rxPriority; /**< \brief receive interrupt priority */
|
||||
uint16 exPriority; /**< \brief error interrupt priority */
|
||||
IfxSrc_Tos typeOfService; /**< \brief type of interrupt service */
|
||||
IfxAsclin_Lin_EnabledInterrupts enabledInterrupt; /**< \brief Interrupts which have to be enabled during initialisation as configured by application. Does not reflect current status of FLAGSENABLE register. */
|
||||
} IfxAsclin_Lin_InterruptConfig;
|
||||
|
||||
/** \brief Structure for lin Control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean csEnable; /**< \brief LINCON.CSEN, hardware checksum generation and checking */
|
||||
IfxAsclin_ChecksumInjection csi; /**< \brief LINCON.CSI, checksum injection (not written or written) into RxFIFO */
|
||||
uint8 breakLength; /**< \brief LINBTIMER.BREAK, break pulse generation and detection length */
|
||||
uint8 headerTimeout; /**< \brief LINHTIMER.HEADER, header timeout threshold value */
|
||||
} IfxAsclin_Lin_LinControl;
|
||||
|
||||
/** \brief Structure for LIN pin configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IFX_CONST IfxAsclin_Rx_In *rx; /**< \brief LIN Rx pin */
|
||||
IfxPort_InputMode rxMode; /**< \brief rx pin as input */
|
||||
IFX_CONST IfxAsclin_Tx_Out *tx; /**< \brief LIN Tx pin */
|
||||
IfxPort_OutputMode txMode; /**< \brief tx as output */
|
||||
IfxPort_PadDriver pinDriver; /**< \brief pad driver */
|
||||
} IfxAsclin_Lin_Pins;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Lin_DataStructures
|
||||
* \{ */
|
||||
typedef struct
|
||||
{
|
||||
Ifx_ASCLIN *asclin; /**< \brief pointer to ASCLIN registers */
|
||||
IfxAsclin_Lin_FrameDataControl linFrameData; /**< \brief Structure for Lin Frame Data and Control */
|
||||
IfxAsclin_LinMode linMode; /**< \brief LINCON.MS, lin mode of operation (master or slave) */
|
||||
IfxAsclin_Lin_AcknowledgementFlags acknowledgmentFlags; /**< \brief structure for acknowledgement flags */
|
||||
IfxAsclin_Lin_ErrorFlags errorFlagsStatus; /**< \brief structure for error flags status */
|
||||
boolean receiveIdEnable; /**< \brief setting to receive Id in Rx Fifo after sending it */
|
||||
boolean isInterruptMode; /**< \brief Value to indicate if APIs work in Polling mode or Interrupt mode */
|
||||
} IfxAsclin_Lin;
|
||||
|
||||
/** \brief Configuration structure of the module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_ASCLIN *asclin; /**< \brief pointer to ASCLIN registers */
|
||||
IfxAsclin_FrameMode frameMode; /**< \brief FRAMECON.MODE, mode of operation of the module (ASC, SPI, LIN) */
|
||||
IfxAsclin_LinMode linMode; /**< \brief LINCON.MS, lin mode of operation (master or slave) */
|
||||
IfxAsclin_Lin_BaudrateGeneration brg; /**< \brief structure for baudrate generation */
|
||||
IfxAsclin_Lin_BaudrateDetection brd; /**< \brief structure for baudrate detection */
|
||||
IfxAsclin_Lin_BitTimingControl btc; /**< \brief structure for bit timings */
|
||||
IfxAsclin_Lin_BitSamplingControl bsc; /**< \brief structure for bit sampling */
|
||||
IfxAsclin_Lin_FrameControl frame; /**< \brief structure for frame control */
|
||||
IfxAsclin_Lin_FifoControl fifo; /**< \brief structure for FIFO control */
|
||||
IfxAsclin_Lin_DataControl data; /**< \brief structure for data control */
|
||||
IfxAsclin_Lin_LinControl lin; /**< \brief structure for lin control */
|
||||
IFX_CONST IfxAsclin_Lin_Pins *pins; /**< \brief structure for LIN pins */
|
||||
IfxAsclin_ClockSource clockSource; /**< \brief CSR.CLKSEL, clock source selection */
|
||||
IfxAsclin_RxInputSelect alti; /**< \brief IOCR.ALTI, Rx input (alternate input) pin selection */
|
||||
IfxAsclin_Lin_InterruptConfig interrupt; /**< \brief structure for lin interrupt configuration */
|
||||
boolean isInterruptMode; /**< \brief flag to indicate Interrupt Mode (TRUE) or Polling Mode (FALSE) */
|
||||
boolean receiveIdEnable; /**< \brief setting to receive Id in Rx Fifo after sending it */
|
||||
} IfxAsclin_Lin_Config;
|
||||
|
||||
/** \brief Structure to hold Lin Pdu data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8 pid; /**< \brief PID of LIN Header */
|
||||
uint8 dataLength; /**< \brief Length of LIN Response */
|
||||
uint8 *dataPtr; /**< \brief Pointer for LIN Response data */
|
||||
IfxAsclin_Lin_Direction direction; /**< \brief Direction Control (Tx Header only, Tx both Header and Response, Tx Header and Rx Response) */
|
||||
IfxAsclin_Checksum checksumMode; /**< \brief LIN Checksum Mode */
|
||||
} IfxAsclin_Lin_PduType;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Lin_ElementaryTransactions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Prepares the module to receive the header
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxAsclin_Lin_prepareHeaderReception(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief Prepares the module to Receive the response
|
||||
* \param asclin module handle
|
||||
* \param length count of data (in bytes).
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxAsclin_Lin_prepareResponseReception(IfxAsclin_Lin *asclin, uint32 length);
|
||||
|
||||
/** \brief Reads the header
|
||||
* \param asclin module handle
|
||||
* \param id the id byte which should be received
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxAsclin_Lin_readHeader(IfxAsclin_Lin *asclin, uint8 *id);
|
||||
|
||||
/** \brief Reads the response
|
||||
* \param asclin module handle
|
||||
* \param data Pointer to the start of data which should be received
|
||||
* \param length count of data (in bytes).
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxAsclin_Lin_readResponse(IfxAsclin_Lin *asclin, uint8 *data, uint32 length);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Ignores the latest header
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_ignoreHeader(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief Receives the header
|
||||
* \param asclin module handle
|
||||
* \param id the id byte which should be received
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_receiveHeader(IfxAsclin_Lin *asclin, uint8 *id);
|
||||
|
||||
/** \brief Receives the response
|
||||
* \param asclin module handle
|
||||
* \param data Pointer to the start of data which should be received
|
||||
* \param length count of data (in bytes).
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_receiveResponse(IfxAsclin_Lin *asclin, uint8 *data, uint32 length);
|
||||
|
||||
/** \brief Sends the header
|
||||
* \param asclin module handle
|
||||
* \param id the id byte which should be sent
|
||||
* \return None
|
||||
*
|
||||
* A coding example of send header in polling mode can be found in \ref IfxLld_Asclin_Lin_Usage. For interrupt mode, this fuction is internally used by IfxAsclin_Lin_sendFrame API and the the polling part is bypassed.
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_sendHeader(IfxAsclin_Lin *asclin, uint8 *id);
|
||||
|
||||
/** \brief sends the response
|
||||
* \param asclin module handle
|
||||
* \param data Pointer to the start of data which should be sent
|
||||
* \param length count of data (in bytes).
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_sendResponse(IfxAsclin_Lin *asclin, uint8 *data, uint32 length);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Lin_ModuleFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Disables the module
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_disableModule(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief Initialises the module
|
||||
* \param asclin module handle
|
||||
* \param config predefined configuration structure of the module
|
||||
* \return Status
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN IfxAsclin_Status IfxAsclin_Lin_initModule(IfxAsclin_Lin *asclin, const IfxAsclin_Lin_Config *config);
|
||||
|
||||
/** \brief Fills the config structure with default values
|
||||
* \param config predefined configuration structure of the module
|
||||
* \param asclin pointer to ASCLIN registers
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Lin_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_initModuleConfig(IfxAsclin_Lin_Config *config, Ifx_ASCLIN *asclin);
|
||||
|
||||
/** \brief This API must be used in interrupt mode. It can be used to
|
||||
* 1.Send Header
|
||||
* 2.Send both Header and Response
|
||||
* 3.Send Header and Receive Response
|
||||
* \param asclin asclin module handle
|
||||
* \param pduptr lin pdu configuration
|
||||
* \return None
|
||||
*
|
||||
* A coding example of sendFrame in interrupt mode can be found in \ref IfxLld_Asclin_Lin_Usage.
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_sendFrame(IfxAsclin_Lin *asclin, IfxAsclin_Lin_PduType *pduptr);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Lin_errorHandlingFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief checks for acknowledgement and error flags for received header
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_checkForReceivedHeaderFlags(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief checks for acknowledgement and error flags for received response
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_checkForReceivedResponseFlags(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief checks for acknowledgement and error flags for transmitted header
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_checkForTransmittedHeaderFlags(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief checks for acknowledgement and error flags for transmitted response
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_checkForTransmittedResponseFlags(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief clears the flags status structures
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_clearFlagsStatus(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief waits until receive header end acknowledgemnet or an error has been detected
|
||||
* \param asclin module handle
|
||||
* \return Result, TRUE: if error, FALSE: is no error
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Lin_waitForReceivedHeader(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief waits until receive response end acknowledgemnet or an error has been detected
|
||||
* \param asclin module handle
|
||||
* \return Result, TRUE: if error, FALSE: is no error
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Lin_waitForReceivedResponse(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief waits until transmit header end acknowledgemnet or an error has been detected
|
||||
* \param asclin module handle
|
||||
* \return Result, TRUE: if error, FALSE: is no error
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Lin_waitForTransmittedHeader(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief waits until transmit response end acknowledgemnet or an error has been detected
|
||||
* \param asclin module handle
|
||||
* \return Result, TRUE: if error, FALSE: is no error
|
||||
*/
|
||||
IFX_EXTERN boolean IfxAsclin_Lin_waitForTransmittedResponse(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Lin_InterruptFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief ISR error routine.
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_isrError(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief ISR receive routine.
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_isrReceive(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \brief ISR transmit routine.
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Lin_isrTransmit(IfxAsclin_Lin *asclin);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxAsclin_Lin_prepareHeaderReception(IfxAsclin_Lin *asclin)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler*/
|
||||
IfxAsclin_clearAllFlags(asclinSFR); /* clearing all flags*/
|
||||
IfxAsclin_flushRxFifo(asclinSFR); /* flushing Rx FIFO*/
|
||||
IfxAsclin_enableTxFifoOutlet(asclinSFR, FALSE); /* enabling Tx FIFO for transmitting*/
|
||||
IfxAsclin_enableRxFifoInlet(asclinSFR, TRUE); /* enabling Rx FIFO for receiving*/
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxAsclin_Lin_prepareResponseReception(IfxAsclin_Lin *asclin, uint32 length)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler*/
|
||||
IfxAsclin_setDataLength(asclinSFR, (IfxAsclin_DataLength)(length - 1)); /* set number of bytes to be received*/
|
||||
IfxAsclin_clearAllFlags(asclinSFR); /* clear all flags */
|
||||
IfxAsclin_flushRxFifo(asclinSFR); /* flushing Rx FIFO */
|
||||
IfxAsclin_enableTxFifoOutlet(asclinSFR, FALSE); /* enable Tx FIFO for transmitting */
|
||||
IfxAsclin_enableRxFifoInlet(asclinSFR, TRUE); /* enable Rx FIFO for receiving */
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxAsclin_Lin_readHeader(IfxAsclin_Lin *asclin, uint8 *id)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler*/
|
||||
IfxAsclin_read8(asclinSFR, id, 1U); /*reading the ID byte*/
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxAsclin_Lin_readResponse(IfxAsclin_Lin *asclin, uint8 *data, uint32 length)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler*/
|
||||
IfxAsclin_read8(asclinSFR, data, length); /* read the data bytes; */
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXASCLIN_LIN_H */
|
||||
@@ -0,0 +1,472 @@
|
||||
/**
|
||||
* \file IfxAsclin_Spi.c
|
||||
* \brief ASCLIN SPI details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxAsclin_Spi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* \param asclin module handle
|
||||
* \return status of the on going job
|
||||
*/
|
||||
IFX_STATIC IfxAsclin_Spi_Status IfxAsclin_Spi_lock(IfxAsclin_Spi *asclin);
|
||||
|
||||
/**
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxAsclin_Spi_unlock(IfxAsclin_Spi *asclin);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxAsclin_Spi_disableModule(IfxAsclin_Spi *asclin)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler */
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(psw); /* clearing the endinit protection*/
|
||||
IfxAsclin_setDisableModuleRequest(asclinSFR); /* disabling the module */
|
||||
IfxScuWdt_setCpuEndinit(psw); /* setting the endinit protection back on */
|
||||
}
|
||||
|
||||
|
||||
IfxAsclin_Spi_Status IfxAsclin_Spi_exchange(IfxAsclin_Spi *asclin, void *src, void *dest, uint32 count)
|
||||
{
|
||||
IfxAsclin_Spi_Status status = IfxAsclin_Spi_lock(asclin); /* lock the driver until the communication is done */
|
||||
|
||||
if (status == IfxAsclin_Spi_Status_ok)
|
||||
{
|
||||
asclin->transferInProgress = 1; /* setting transfer in progress status */
|
||||
asclin->txJob.data = src; /* data to be transmitted */
|
||||
asclin->txJob.pending = count; /* count of Tx data */
|
||||
asclin->rxJob.data = dest; /* empty buffer to receive data */
|
||||
asclin->rxJob.pending = count; /* count of Rx data */
|
||||
|
||||
IfxAsclin_Spi_write(asclin); /* write data into Tx fifo */
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
IfxAsclin_Spi_Status IfxAsclin_Spi_getStatus(IfxAsclin_Spi *asclin)
|
||||
{
|
||||
IfxAsclin_Spi_Status status = IfxAsclin_Spi_Status_ok;
|
||||
|
||||
if ((asclin->transferInProgress != 0) || (asclin->sending != 0))
|
||||
{
|
||||
status = IfxAsclin_Spi_Status_busy;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
IfxAsclin_Status IfxAsclin_Spi_initModule(IfxAsclin_Spi *asclin, const IfxAsclin_Spi_Config *config)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = config->asclin; /* pointer to ASCLIN registers */
|
||||
IfxAsclin_Status status = IfxAsclin_Status_noError;
|
||||
|
||||
asclin->asclin = asclinSFR; /* adding register pointer to module handler*/
|
||||
IfxAsclin_enableModule(asclinSFR); /* enabling the module */
|
||||
|
||||
/* mode initialisation */
|
||||
IfxAsclin_setClockSource(asclinSFR, IfxAsclin_ClockSource_noClock); /* disabling the clock */
|
||||
IfxAsclin_setFrameMode(asclinSFR, IfxAsclin_FrameMode_initialise); /* setting the module in Initialise mode */
|
||||
IfxAsclin_setClockSource(asclinSFR, config->clockSource); /* setting the clock source */
|
||||
|
||||
/* spi mode initialisation */
|
||||
IfxAsclin_setClockSource(asclinSFR, IfxAsclin_ClockSource_noClock); /* disabling the clock */
|
||||
IfxAsclin_setFrameMode(asclinSFR, config->frameMode); /* setting the module in Spi mode */
|
||||
IfxAsclin_setPrescaler(asclinSFR, config->baudrate.prescaler); /* setting the prescaler*/
|
||||
IfxAsclin_setClockSource(asclinSFR, config->clockSource); /* setting the clock source */
|
||||
|
||||
IfxAsclin_SamplePointPosition samplePointPosition = (IfxAsclin_SamplePointPosition)((config->baudrate.oversampling + 1) / 2); /* sample point position at half of oversampling factor */
|
||||
|
||||
/* baudrate generation */
|
||||
status = (IfxAsclin_Status)IfxAsclin_setBitTiming(asclinSFR, config->baudrate.baudrate,
|
||||
config->baudrate.oversampling,
|
||||
samplePointPosition,
|
||||
config->bitSampling.medianFilter); /* setting the baudrate bit fields to generate the required baudrate */
|
||||
|
||||
IfxAsclin_setClockSource(asclinSFR, IfxAsclin_ClockSource_noClock); /* disabling the clock again */
|
||||
|
||||
/* input output control initialisation */
|
||||
IfxAsclin_setRxInput(asclinSFR, config->inputOutput.alti); /* selecting the Rx(alternate) input pin */
|
||||
IfxAsclin_setClockPolarity(asclinSFR, config->inputOutput.cpol); /* setting the clock polarity */
|
||||
IfxAsclin_setSlavePolarity(asclinSFR, config->inputOutput.spol); /* setting the slave polarity */
|
||||
IfxAsclin_enableLoopBackMode(asclinSFR, config->inputOutput.loopBack); /* selecting loopbak (enable/disable) */
|
||||
|
||||
/* frame control initialisation */
|
||||
IfxAsclin_setIdleDelay(asclinSFR, config->frame.idleDelay); /* setting idle delay */
|
||||
IfxAsclin_setLeadDelay(asclinSFR, config->frame.leadDelay); /* setting lead delay */
|
||||
IfxAsclin_setStopBit(asclinSFR, config->frame.stopBit); /* setting the stop bit (trail delay) */
|
||||
IfxAsclin_setShiftDirection(asclinSFR, config->frame.shiftDir); /* setting the shift direction */
|
||||
|
||||
/* data control initialisation */
|
||||
IfxAsclin_setDataLength(asclinSFR, config->dataLength); /* setting the number of bytes to be transfered */
|
||||
|
||||
/* fifo control initialisation */
|
||||
/* set the FIFO widths based on the supplied datalength */
|
||||
if (config->dataLength <= 8)
|
||||
{
|
||||
IfxAsclin_setTxFifoInletWidth(asclinSFR, IfxAsclin_TxFifoInletWidth_1); /* setting Tx FIFO inlet width to 1 byte */
|
||||
IfxAsclin_setRxFifoOutletWidth(asclinSFR, IfxAsclin_RxFifoOutletWidth_1); /* setting Rx FIFO outlet width to 1 byte */
|
||||
asclin->dataWidth = 1; /* echo the data width to module handle*/
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
IfxAsclin_setTxFifoInletWidth(asclinSFR, IfxAsclin_TxFifoInletWidth_2); /* setting Tx FIFO inlet width to 2 bytes */
|
||||
IfxAsclin_setRxFifoOutletWidth(asclinSFR, IfxAsclin_RxFifoOutletWidth_2); /* setting Rx FIFO outlet width to 2 bytes */
|
||||
asclin->dataWidth = 2; /* echo the data width to module handle*/
|
||||
}
|
||||
|
||||
IfxAsclin_setRxBufferMode(asclinSFR, config->fifo.buffMode); /* setting Rx FIFO mode */
|
||||
IfxAsclin_setTxFifoInterruptLevel(asclinSFR, config->fifo.txFifoInterruptLevel); /* setting Tx FIFO level at which a Tx interrupt will be triggered */
|
||||
IfxAsclin_setRxFifoInterruptLevel(asclinSFR, config->fifo.rxFifoInterruptLevel); /* setting Rx FIFO interrupt level at which a Rx interrupt will be triggered */
|
||||
IfxAsclin_flushRxFifo(asclinSFR); /* flushing Rx FIFO */
|
||||
IfxAsclin_flushTxFifo(asclinSFR); /* flushing Tx FIFO */
|
||||
|
||||
IfxAsclin_disableAllFlags(asclinSFR); /* disable all flags */
|
||||
IfxAsclin_clearAllFlags(asclinSFR); /* clear all flags */
|
||||
|
||||
/* initialising the interrupts */
|
||||
IfxSrc_Tos tos = config->interrupt.typeOfService;
|
||||
|
||||
if ((config->interrupt.rxPriority > 0) || (tos == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxAsclin_getSrcPointerRx(asclinSFR);
|
||||
IfxSrc_init(src, tos, config->interrupt.rxPriority);
|
||||
IfxAsclin_enableRxFifoFillLevelFlag(asclinSFR, TRUE);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.txPriority > 0) || (tos == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxAsclin_getSrcPointerTx(asclinSFR);
|
||||
IfxSrc_init(src, tos, config->interrupt.txPriority);
|
||||
IfxAsclin_enableTxFifoFillLevelFlag(asclinSFR, TRUE);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt.erPriority > 0) /*These interrupts are not serviced by dma*/
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxAsclin_getSrcPointerEr(asclinSFR);
|
||||
IfxSrc_init(src, tos, config->interrupt.erPriority);
|
||||
IfxAsclin_enableFrameErrorFlag(asclinSFR, TRUE);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
/* Pin mapping */
|
||||
const IfxAsclin_Spi_Pins *pins = config->pins;
|
||||
|
||||
if (pins != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_Sclk_Out *sclk = pins->sclk;
|
||||
|
||||
if (sclk != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_initSclkPin(sclk, pins->sclkMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxAsclin_Rx_In *rx = pins->rx;
|
||||
|
||||
if (rx != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_initRxPin(rx, pins->rxMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxAsclin_Tx_Out *tx = pins->tx;
|
||||
|
||||
if (tx != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_initTxPin(tx, pins->txMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxAsclin_Slso_Out *slso = pins->slso;
|
||||
|
||||
if (slso != NULL_PTR)
|
||||
{
|
||||
IfxAsclin_initSlsoPin(slso, pins->slsoMode, pins->pinDriver);
|
||||
}
|
||||
}
|
||||
|
||||
IfxAsclin_enableParity(asclinSFR, FALSE); /* no parity */
|
||||
|
||||
IfxAsclin_setClockSource(asclinSFR, config->clockSource); /* setting the clock source*/
|
||||
|
||||
asclin->sending = 0;
|
||||
IfxAsclin_enableTxFifoOutlet(asclinSFR, TRUE); /* disabling Rx FIFO for recieving */
|
||||
IfxAsclin_enableRxFifoInlet(asclinSFR, TRUE); /* disabling Tx FIFO for transmitting */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Spi_initModuleConfig(IfxAsclin_Spi_Config *config, Ifx_ASCLIN *asclin)
|
||||
{
|
||||
const IfxAsclin_Spi_Config defaultConfig = {
|
||||
.asclin = NULL_PTR, /* will be initialized below */
|
||||
|
||||
.frameMode = IfxAsclin_FrameMode_spi, /* SPI mode */
|
||||
.clockSource = IfxAsclin_ClockSource_kernelClock, /* kernel clock, fclc*/
|
||||
|
||||
/* Default values for input output control */
|
||||
.inputOutput = {
|
||||
.alti = IfxAsclin_RxInputSelect_0, /* alternate input 0; */
|
||||
.cpol = IfxAsclin_ClockPolarity_idleLow, /* CPOL active low */
|
||||
.spol = IfxAsclin_SlavePolarity_idlehigh, /* SPOL active high */
|
||||
.loopBack = FALSE, /* no loop back */
|
||||
},
|
||||
|
||||
/* Default values for baudrate */
|
||||
.baudrate = {
|
||||
.baudrate = 100000.0, /* default baudrate (the fractional dividier setup will be calculated in initModule) */
|
||||
.prescaler = 2, /* default prescaler */
|
||||
.oversampling = IfxAsclin_OversamplingFactor_8, /* default oversampling factor */
|
||||
},
|
||||
|
||||
/* Default Values for Bit sampling */
|
||||
.bitSampling = {
|
||||
.medianFilter = IfxAsclin_SamplesPerBit_one, /* one sample per bit */
|
||||
},
|
||||
|
||||
/* Default Values for Frame Control */
|
||||
.frame = {
|
||||
.idleDelay = IfxAsclin_IdleDelay_0, /* no idle delay */
|
||||
.leadDelay = IfxAsclin_LeadDelay_1, /* one lead bit */
|
||||
.stopBit = IfxAsclin_StopBit_1, /* one stop bit (trail delay) */
|
||||
.shiftDir = IfxAsclin_ShiftDirection_lsbFirst, /* shift direction LSB first */
|
||||
},
|
||||
|
||||
/* Default Values for Data Control*/
|
||||
.dataLength = IfxAsclin_DataLength_8, /* number of bits per transfer 8*/
|
||||
|
||||
/* Default Values for fifo Control */
|
||||
.fifo = {
|
||||
.outWidth = IfxAsclin_RxFifoOutletWidth_1, /* 8-bit wide read */
|
||||
.inWidth = IfxAsclin_TxFifoInletWidth_1, /*8-bit wide write */
|
||||
.buffMode = IfxAsclin_ReceiveBufferMode_rxFifo, /* RxFIFO */
|
||||
.txFifoInterruptLevel = IfxAsclin_TxFifoInterruptLevel_15, /* Tx FIFO interrupt level */
|
||||
.rxFifoInterruptLevel = IfxAsclin_RxFifoInterruptLevel_1, /* Rx FIFO interrupt level */
|
||||
},
|
||||
|
||||
/* Default Values for Interrupt Config */
|
||||
.interrupt = {
|
||||
.rxPriority = 0, /* receive interrupt priority 0 */
|
||||
.txPriority = 0, /* transmit interrupt priority 0 */
|
||||
.erPriority = 0, /* error interrupt priority 0 */
|
||||
.typeOfService = IfxSrc_Tos_cpu0, /* type of service CPU0 */
|
||||
},
|
||||
|
||||
.pins = NULL_PTR, /* pins to null pointer */
|
||||
};
|
||||
|
||||
/* Default Configuration */
|
||||
*config = defaultConfig;
|
||||
/* take over module pointer */
|
||||
config->asclin = asclin;
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Spi_isrError(IfxAsclin_Spi *asclin)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler */
|
||||
|
||||
/* store all the flags in the variable */
|
||||
if (IfxAsclin_getFrameErrorFlagStatus(asclinSFR))
|
||||
{
|
||||
IfxAsclin_clearFrameErrorFlag(asclinSFR);
|
||||
asclin->errorFlags.frameError = 1;
|
||||
}
|
||||
|
||||
if (IfxAsclin_getRxFifoOverflowFlagStatus(asclinSFR))
|
||||
{
|
||||
IfxAsclin_clearRxFifoOverflowFlag(asclinSFR);
|
||||
asclin->errorFlags.rxFifoOverflow = 1;
|
||||
}
|
||||
|
||||
if (IfxAsclin_getRxFifoUnderflowFlagStatus(asclinSFR))
|
||||
{
|
||||
IfxAsclin_clearRxFifoUnderflowFlag(asclinSFR);
|
||||
asclin->errorFlags.rxFifoUnderflow = 1;
|
||||
}
|
||||
|
||||
if (IfxAsclin_getTxFifoOverflowFlagStatus(asclinSFR))
|
||||
{
|
||||
IfxAsclin_clearTxFifoOverflowFlag(asclinSFR);
|
||||
asclin->errorFlags.txFifoOverflow = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Spi_isrReceive(IfxAsclin_Spi *asclin)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler*/
|
||||
IfxAsclin_clearRxFifoFillLevelFlag(asclinSFR); /* clear the interrupt flag */
|
||||
IfxAsclin_Spi_read(asclin); /* read the remaining data */
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Spi_isrTransmit(IfxAsclin_Spi *asclin)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler */
|
||||
IfxAsclin_clearTxFifoFillLevelFlag(asclinSFR); /* clear the interrupt flag */
|
||||
IfxAsclin_Spi_write(asclin); /* write the remaining data */
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC IfxAsclin_Spi_Status IfxAsclin_Spi_lock(IfxAsclin_Spi *asclin)
|
||||
{
|
||||
sint32 sending = __swap((void *)&asclin->sending, 1UL);
|
||||
return (sending == 0) ? IfxAsclin_Spi_Status_ok : IfxAsclin_Spi_Status_busy;
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Spi_read(IfxAsclin_Spi *asclin)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler */
|
||||
IfxAsclin_Spi_Job *job = &asclin->rxJob; /* getting the rxJob structure from module handler */
|
||||
|
||||
uint32 count = (uint32)IfxAsclin_getRxFifoFillLevel(asclinSFR); /* get the readable count of Rx fifo */
|
||||
count = __min(job->pending, count); /* check for the end of the data */
|
||||
|
||||
if (job->data == NULL_PTR) /* incase of no data to be received (only transmit case) */
|
||||
{
|
||||
uint32 i;
|
||||
job->pending = job->pending - count; /* discount the current reading count from job pending */
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
IfxAsclin_readRxData(asclinSFR); /* do dummy reads */
|
||||
}
|
||||
}
|
||||
else if (job->pending > 0)
|
||||
{
|
||||
job->pending = job->pending - count; /* discount the current reading count from job pending */
|
||||
|
||||
/* read data up to the count based on the out width */
|
||||
switch (asclin->dataWidth)
|
||||
{
|
||||
case 1: /* in case of 8 bit wide */
|
||||
IfxAsclin_read8(asclinSFR, job->data, count); /* reading from Rx FIFO */
|
||||
job->data = &(((uint8 *)job->data)[count]); /* pointing to the remaining data */
|
||||
break;
|
||||
|
||||
case 2: /* in case of 16 bit wide*/
|
||||
IfxAsclin_read16(asclinSFR, job->data, count); /* reading from Rx FIFO */
|
||||
job->data = &(((uint16 *)job->data)[count]); /* pointing to the remaining data */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (job->pending == 0)
|
||||
{
|
||||
asclin->transferInProgress = 0; /* clearing the transfer in progress status */
|
||||
IfxAsclin_Spi_unlock(asclin); /* unlock the driver */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxAsclin_Spi_unlock(IfxAsclin_Spi *asclin)
|
||||
{
|
||||
asclin->sending = 0UL;
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_Spi_write(IfxAsclin_Spi *asclin)
|
||||
{
|
||||
Ifx_ASCLIN *asclinSFR = asclin->asclin; /* getting the pointer to ASCLIN registers from module handler */
|
||||
IfxAsclin_Spi_Job *job = &asclin->txJob; /* getting the txJob structure from module handler */
|
||||
|
||||
if (job->pending)
|
||||
{
|
||||
boolean interruptState = IfxCpu_disableInterrupts();
|
||||
|
||||
uint32 count = (uint32)(16 - IfxAsclin_getTxFifoFillLevel(asclinSFR)); /* getting the fillable count of the Tx Fifo */
|
||||
count = __min(job->pending, count); /* checking for the end of the data */
|
||||
|
||||
if (job->data == NULL_PTR) /* incase of no data to be transmitted (only receive case) */
|
||||
{
|
||||
uint32 i;
|
||||
job->pending = job->pending - count; /* discount the current filling count from job pending */
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
IfxAsclin_writeTxData(asclinSFR, ~0); /* write all 1's */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
job->pending = job->pending - count; /* discount the current filling count from job pending */
|
||||
|
||||
/* write data up to the count based on the in width */
|
||||
switch (asclin->dataWidth)
|
||||
{
|
||||
case 1: /* in case of 8 bit wide */
|
||||
IfxAsclin_write8(asclinSFR, job->data, count); /* writing to Tx FIFO */
|
||||
job->data = &(((uint8 *)job->data)[count]); /* pointing to the remaining data */
|
||||
break;
|
||||
|
||||
case 2: /* in case of 16 bit wide*/
|
||||
IfxAsclin_write16(asclinSFR, job->data, count); /* writing to Tx FIFO */
|
||||
job->data = &(((uint16 *)job->data)[count]); /* pointing to the remaining data */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IfxCpu_restoreInterrupts(interruptState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
/**
|
||||
* \file IfxAsclin_Spi.h
|
||||
* \brief ASCLIN SPI details
|
||||
* \ingroup IfxLld_Asclin
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Asclin_Spi_Usage How to use the ASCLIN SPI Interface driver?
|
||||
* \ingroup IfxLld_Asclin
|
||||
*
|
||||
* The SPI interface driver provides a default ASCLIN configuration for synchronous serial communication in 8 and 16 bit mode, and a set of data transfer routines.
|
||||
*
|
||||
* Data transfers are buffered by the hardware based FIFOs. Incoming and outgoing data is transfered in background from/to the ASCLIN peripheral by interrupt service handlers, which are part of this driver as well. This allows a nonblocking communication without stalling the thread(s) from where data is sent and received.
|
||||
*
|
||||
* The SPI interface driver works only as Master
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
* \section IfxLld_Asclin_Spi_Preparation Preparation
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Spi_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
*
|
||||
* \code
|
||||
* #include <Asclin/Spi/IfxAsclin_Spi.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Spi_Variables Variables
|
||||
*
|
||||
* Declare the Spi handle as global variable in your C code:
|
||||
*
|
||||
* \code
|
||||
* // used globally
|
||||
* static IfxAsclin_Spi spi;
|
||||
* \endcode
|
||||
*
|
||||
* In addition, declare global transmit and receive buffers for the data transfers:
|
||||
*
|
||||
* \code
|
||||
* #define SPI_BUFFER_SIZE 8
|
||||
* uint8 spiTxBuffer[SPI_BUFFER_SIZE];
|
||||
* uint8 spiRxBuffer[SPI_BUFFER_SIZE];
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Spi_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priorities for the Interrrupt handlers. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
*
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define IFX_INTPRIO_ASCLIN1_TX 1
|
||||
* #define IFX_INTPRIO_ASCLIN1_RX 2
|
||||
* #define IFX_INTPRIO_ASCLIN1_ER 3
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routines to your C code. They have to call the SPI interrupt handlers by passing the spi handle:
|
||||
*
|
||||
* \code
|
||||
* IFX_INTERRUPT(asclin1TxISR, 0, IFX_INTPRIO_ASCLIN1_TX)
|
||||
* {
|
||||
* IfxAsclin_Spi_isrTransmit(&spi);
|
||||
* }
|
||||
*
|
||||
* IFX_INTERRUPT(asclin1RxISR, 0, IFX_INTPRIO_ASCLIN1_RX)
|
||||
* {
|
||||
* IfxAsclin_Spi_isrReceive(&spi);
|
||||
* }
|
||||
*
|
||||
* IFX_INTERRUPT(asclin1ErISR, 0, IFX_INTPRIO_ASCLIN1_ER)
|
||||
* {
|
||||
* IfxAsclin_Spi_isrError(&spi);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handlers in your initialisation function:
|
||||
*
|
||||
* \code
|
||||
* // install interrupt handlers
|
||||
* IfxCpu_Irq_installInterruptHandler(&asclin1TxISR, IFX_INTPRIO_ASCLIN1_TX);
|
||||
* IfxCpu_Irq_installInterruptHandler(&asclin1RxISR, IFX_INTPRIO_ASCLIN1_RX);
|
||||
* IfxCpu_Irq_installInterruptHandler(&asclin1ErISR, IFX_INTPRIO_ASCLIN1_ER);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Asclin_Spi_Init Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function. Here an example:
|
||||
*
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxAsclin_Spi_Config spiConfig;
|
||||
* IfxAsclin_Spi_initModuleConfig(&spiConfig, &MODULE_ASCLIN1);
|
||||
*
|
||||
* // set the desired baudrate
|
||||
* spiConfig.baudrate.prescaler = 1;
|
||||
* spiConfig.baudrate.baudrate = 1000000; // FDR values will be calculated in initModule
|
||||
*
|
||||
* // ISR priorities and interrupt target
|
||||
* spiConfig.interrupt.txPriority = IFX_INTPRIO_ASCLIN1_TX; // see also \ref IfxLld_Asclin
|
||||
* spiConfig.interrupt.rxPriority = IFX_INTPRIO_ASCLIN1_RX; // see also \ref IfxLld_Asclin
|
||||
* spiConfig.interrupt.erPriority = IFX_INTPRIO_ASCLIN1_ER; // see also \ref IfxLld_Asclin
|
||||
* spiConfig.interrupt.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());
|
||||
*
|
||||
* // pin configuration
|
||||
* const IfxAsclin_Spi_Pins pins = {
|
||||
* &IfxAsclin1_SCLK_P15_0_OUT, IfxPort_OutputMode_pushPull, // Clock out pin
|
||||
* &IfxAsclin1_RXA_P15_1_IN, IfxPort_InputMode_pullUp, // Rx pin
|
||||
* &IfxAsclin1_TX_P15_4_OUT, IfxPort_OutputMode_pushPull, // Tx pin
|
||||
* &IfxAsclin1_SLSO_P20_8_OUT, IfxPort_OutputMode_pushPull, // Slave select pin
|
||||
* IfxPort_PadDriver_cmosAutomotiveSpeed1
|
||||
* };
|
||||
* spiConfig.pins = &pins;
|
||||
*
|
||||
* // initialize module
|
||||
* //IfxAsclin_Spi spi; // defined globally
|
||||
* IfxAsclin_Spi_initModule(&spi, &spiConfig);
|
||||
* \endcode
|
||||
*
|
||||
* The SPI is ready for use now!
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Asclin_Spi_DataTransfers Data Transfers
|
||||
*
|
||||
* In following examples we assume, that following buffers are declared globally:
|
||||
*
|
||||
* \code
|
||||
* // load the data buffers
|
||||
* int i;
|
||||
* for (i = 0; i < SPI_BUFFER_SIZE; i++)
|
||||
* {
|
||||
* spiTxBuffer[i] = i + 1;
|
||||
* spiRxBuffer[i] = 0;
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Sending and Receiving a data stream:
|
||||
*
|
||||
* \code
|
||||
* // wait until transfer of previous data stream is finished
|
||||
* while( IfxAsclin_Spi_getStatus(&spi) == IfxAsclin_Spi_Status_busy );
|
||||
*
|
||||
* // send/receive new stream
|
||||
* IfxAsclin_Spi_exchange(&spi, spiTxBuffer, spiRxBuffer, 8);
|
||||
* \endcode
|
||||
*
|
||||
* Send only, discard received data:
|
||||
*
|
||||
* \code
|
||||
* // wait until transfer of previous data stream is finished
|
||||
* while( IfxAsclin_Spi_getStatus(&spi) == IfxAsclin_Spi_Status_busy );
|
||||
*
|
||||
* // send new stream
|
||||
* IfxAsclin_Spi_exchange(&spi, spiTxBuffer, NULL_PTR, 8);
|
||||
* \endcode
|
||||
*
|
||||
* Receive only, send all 1's
|
||||
*
|
||||
* \code
|
||||
* // wait until transfer of previous data stream is finished
|
||||
* while( IfxAsclin_Spi_getStatus(&spi) == IfxAsclin_Spi_Status_busy );
|
||||
*
|
||||
* // receive new stream
|
||||
* IfxAsclin_Spi_exchange(&spi, NULL_PTR, spiRxBuffer, 8);
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Asclin_Spi SPI
|
||||
* \ingroup IfxLld_Asclin
|
||||
* \defgroup IfxLld_Asclin_Spi_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Asclin_Spi
|
||||
* \defgroup IfxLld_Asclin_Spi_ModuleFunctions Module Functions
|
||||
* \ingroup IfxLld_Asclin_Spi
|
||||
* \defgroup IfxLld_Asclin_Spi_InterruptFunctions Interrupt Functions
|
||||
* \ingroup IfxLld_Asclin_Spi
|
||||
* \defgroup IfxLld_Asclin_Spi_CommunicationFunctions Communication Functions
|
||||
* \ingroup IfxLld_Asclin_Spi
|
||||
*/
|
||||
|
||||
#ifndef IFXASCLIN_SPI_H
|
||||
#define IFXASCLIN_SPI_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Asclin/Std/IfxAsclin.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------------Enumerations---------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Enumeration for job status
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxAsclin_Spi_Status_ok = 0,
|
||||
IfxAsclin_Spi_Status_busy = 1,
|
||||
IfxAsclin_Spi_Status_unknown = 2
|
||||
} IfxAsclin_Spi_Status;
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Spi_DataStructures
|
||||
* \{ */
|
||||
/** \brief Structure for Baudrate Generation
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
float32 baudrate; /**< \brief value of the required baudrate */
|
||||
uint16 prescaler; /**< \brief BITCON.PRESCALER, predivider to generate the baud rate */
|
||||
IfxAsclin_OversamplingFactor oversampling; /**< \brief BITCON.OVERSAMPLING, postdivider, used for oversampling */
|
||||
} IfxAsclin_Spi_Baudrate;
|
||||
|
||||
/** \brief Structure for Bit Sampling
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_SamplesPerBit medianFilter; /**< \brief BITCON.SM, no. of samples per bit 1 or 3 */
|
||||
} IfxAsclin_Spi_BitSamplingControl;
|
||||
|
||||
/** \brief Structure for Error Flags
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8 frameError : 1; /**< \brief frame error */
|
||||
uint8 rxFifoOverflow : 1; /**< \brief receive FIFO overflow error */
|
||||
uint8 rxFifoUnderflow : 1; /**< \brief receive FIFO underflow error */
|
||||
uint8 txFifoOverflow : 1; /**< \brief transmit FIFO overflow error */
|
||||
} IfxAsclin_Spi_ErrorFlags;
|
||||
|
||||
/** \brief Structure for FIFO Control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_TxFifoInletWidth inWidth; /**< \brief TXFIFOCON.INW, transmit FIFO inlet width */
|
||||
IfxAsclin_TxFifoInterruptLevel txFifoInterruptLevel; /**< \brief TXFIFOCON.INTLEVEL, Tx FIFO interrupt level */
|
||||
IfxAsclin_RxFifoOutletWidth outWidth; /**< \brief RXFIFOCON.OTW, receive FIFO oulet width */
|
||||
IfxAsclin_RxFifoInterruptLevel rxFifoInterruptLevel; /**< \brief RXFIFOCON.INTLEVEL, Rx FIFO interrupt level */
|
||||
IfxAsclin_ReceiveBufferMode buffMode; /**< \brief RXFIFOCON.BUF, receive buffer mode (RXFIFO or RXBuffer) */
|
||||
} IfxAsclin_Spi_FifoControl;
|
||||
|
||||
/** \brief Structure for Frame Control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_IdleDelay idleDelay; /**< \brief FRAMECON.IDLE, idle delay */
|
||||
IfxAsclin_StopBit stopBit; /**< \brief FRAMECON.STOP, number of stop bits */
|
||||
IfxAsclin_LeadDelay leadDelay; /**< \brief FRAMECON.LEAD, lead delay */
|
||||
IfxAsclin_ShiftDirection shiftDir; /**< \brief FRAMECON.MSB, shift direction */
|
||||
} IfxAsclin_Spi_FrameControl;
|
||||
|
||||
/** \brief Structure for input output control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxAsclin_RxInputSelect alti; /**< \brief IOCR.ALTI, Rx input (alternate input) pin selection */
|
||||
IfxAsclin_ClockPolarity cpol; /**< \brief IOCR.CPOL clock polarity selection */
|
||||
IfxAsclin_SlavePolarity spol; /**< \brief IOCR.SPOL slave polarity selection */
|
||||
boolean loopBack; /**< \brief IOCR.LB, loop back mode selection, 0 for disable, 1 for enable */
|
||||
} IfxAsclin_Spi_InputOutputControl;
|
||||
|
||||
/** \brief Structure for interrupt configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 txPriority; /**< \brief transmit interrupt priority */
|
||||
uint16 rxPriority; /**< \brief receive interrupt priority */
|
||||
uint16 erPriority; /**< \brief error interrupt priority */
|
||||
IfxSrc_Tos typeOfService; /**< \brief type of interrupt service */
|
||||
} IfxAsclin_Spi_InterruptConfig;
|
||||
|
||||
/** \brief Structure for data transfer jobs
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void *data; /**< \brief pointer to user data */
|
||||
uint32 pending; /**< \brief job remaining (count of the data) */
|
||||
} IfxAsclin_Spi_Job;
|
||||
|
||||
/** \brief Structure for SPI pin configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IFX_CONST IfxAsclin_Sclk_Out *sclk; /**< \brief SPI clock select pin */
|
||||
IfxPort_OutputMode sclkMode; /**< \brief sclk as output */
|
||||
IFX_CONST IfxAsclin_Rx_In *rx; /**< \brief SPI Rx pin */
|
||||
IfxPort_InputMode rxMode; /**< \brief rx pin as input */
|
||||
IFX_CONST IfxAsclin_Tx_Out *tx; /**< \brief SPI Tx pin */
|
||||
IfxPort_OutputMode txMode; /**< \brief tx as output */
|
||||
IFX_CONST IfxAsclin_Slso_Out *slso; /**< \brief SPI slave select pin */
|
||||
IfxPort_OutputMode slsoMode; /**< \brief slso as output */
|
||||
IfxPort_PadDriver pinDriver; /**< \brief pad driver */
|
||||
} IfxAsclin_Spi_Pins;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Spi_DataStructures
|
||||
* \{ */
|
||||
/** \brief Module handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_ASCLIN *asclin; /**< \brief pointer to ASCLIN registers */
|
||||
IfxAsclin_Spi_Job txJob; /**< \brief structure for Tx job */
|
||||
IfxAsclin_Spi_Job rxJob; /**< \brief structure for Rx job */
|
||||
uint32 sending; /**< \brief sending in progress status */
|
||||
IfxAsclin_Spi_ErrorFlags errorFlags; /**< \brief structure for error flags status */
|
||||
uint8 dataWidth; /**< \brief width of the data in bytes */
|
||||
boolean transferInProgress; /**< \brief status of the transfer In progress */
|
||||
} IfxAsclin_Spi;
|
||||
|
||||
/** \brief Configuration structure of the module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_ASCLIN *asclin; /**< \brief pointer to ASCLIN registers */
|
||||
IfxAsclin_FrameMode frameMode; /**< \brief FRAMECON.MODE, mode of operation of the module (ASC, SPI, LIN) */
|
||||
IfxAsclin_Spi_InputOutputControl inputOutput; /**< \brief structure for input output control */
|
||||
IfxAsclin_Spi_Baudrate baudrate; /**< \brief structure for baudrate */
|
||||
IfxAsclin_Spi_BitSamplingControl bitSampling; /**< \brief structure for bit sampling */
|
||||
IfxAsclin_Spi_FrameControl frame; /**< \brief structure for frame control */
|
||||
IfxAsclin_DataLength dataLength; /**< \brief DATCON.DATALENGTH, data length, number of bits per transfer */
|
||||
IfxAsclin_Spi_FifoControl fifo; /**< \brief structure for FIFO control */
|
||||
IfxAsclin_Spi_InterruptConfig interrupt; /**< \brief structure for interrupt configuration */
|
||||
IFX_CONST IfxAsclin_Spi_Pins *pins; /**< \brief structure for SPI pins */
|
||||
IfxAsclin_ClockSource clockSource; /**< \brief CSR.CLKSEL, clock source selection */
|
||||
} IfxAsclin_Spi_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Spi_ModuleFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Disables the module
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Spi_disableModule(IfxAsclin_Spi *asclin);
|
||||
|
||||
/** \brief Initialises the module
|
||||
* \param asclin module handle
|
||||
* \param config predefined configuration structure of the module
|
||||
* \return Status
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Spi_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN IfxAsclin_Status IfxAsclin_Spi_initModule(IfxAsclin_Spi *asclin, const IfxAsclin_Spi_Config *config);
|
||||
|
||||
/** \brief Fills the configuration structure with default values
|
||||
* \param config predefined configuration structure of the module
|
||||
* \param asclin pointer to ASCLIN registers
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Spi_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Spi_initModuleConfig(IfxAsclin_Spi_Config *config, Ifx_ASCLIN *asclin);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Spi_InterruptFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief ISR error routine.
|
||||
*
|
||||
* Currently it only stores error flags in the handle (asclin->errorFlags) whenever an error happens.
|
||||
* The user software could react on these flags, e.g. re-initialising the module.
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Spi_isrError(IfxAsclin_Spi *asclin);
|
||||
|
||||
/** \brief ISR receive routine
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Spi_isrReceive(IfxAsclin_Spi *asclin);
|
||||
|
||||
/** \brief ISR transmit routine
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Spi_isrTransmit(IfxAsclin_Spi *asclin);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Asclin_Spi_CommunicationFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief starts the data exchange
|
||||
* \param asclin module handle
|
||||
* \param src pointer to transmit data buffer
|
||||
* \param dest pointer to receive data buffer
|
||||
* \param count count of the data
|
||||
* \return status
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Asclin_Spi_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN IfxAsclin_Spi_Status IfxAsclin_Spi_exchange(IfxAsclin_Spi *asclin, void *src, void *dest, uint32 count);
|
||||
|
||||
/** \brief Reads data from the Rx FIFO based on the outlet width
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Spi_read(IfxAsclin_Spi *asclin);
|
||||
|
||||
/** \brief Writes data into the Tx FIFO based on the inlet width
|
||||
* \param asclin module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxAsclin_Spi_write(IfxAsclin_Spi *asclin);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* \param asclin module handle
|
||||
* \return status of the on going job
|
||||
*/
|
||||
IFX_EXTERN IfxAsclin_Spi_Status IfxAsclin_Spi_getStatus(IfxAsclin_Spi *asclin);
|
||||
|
||||
#endif /* IFXASCLIN_SPI_H */
|
||||
@@ -0,0 +1,417 @@
|
||||
/**
|
||||
* \file IfxAsclin.c
|
||||
* \brief ASCLIN basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxAsclin.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxAsclin_disableModule(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(psw); /* clears the endinit protection*/
|
||||
IfxAsclin_setDisableModuleRequest(asclin); /* disables the module*/
|
||||
IfxScuWdt_setCpuEndinit(psw); /* sets the endinit protection back on*/
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_enableAscErrorFlags(Ifx_ASCLIN *asclin, boolean parEnable, boolean rfoEnable)
|
||||
{
|
||||
IfxAsclin_enableParityErrorFlag(asclin, parEnable); /* enables parity error*/
|
||||
IfxAsclin_enableRxFifoOverflowFlag(asclin, rfoEnable); /* enables Rx fifo Overflow error*/
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_enableModule(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(psw); /* clears the endinit protection*/
|
||||
IfxAsclin_setEnableModuleRequest(asclin); /* enables the module*/
|
||||
IfxScuWdt_setCpuEndinit(psw); /* sets the endinit protection back on*/
|
||||
}
|
||||
|
||||
|
||||
Ifx_ASCLIN *IfxAsclin_getAddress(IfxAsclin_Index asclin)
|
||||
{
|
||||
Ifx_ASCLIN *module;
|
||||
|
||||
if (asclin < IFXASCLIN_NUM_MODULES)
|
||||
{
|
||||
module = (Ifx_ASCLIN *)IfxAsclin_cfg_indexMap[asclin].module;
|
||||
}
|
||||
else
|
||||
{
|
||||
module = NULL_PTR;
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxAsclin_getFaFrequency(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
float32 frequency;
|
||||
IfxAsclin_ClockSource clockSource = (IfxAsclin_ClockSource)IfxAsclin_getClockSource(asclin); /* gets the current clock source*/
|
||||
|
||||
switch (clockSource)
|
||||
{
|
||||
case IfxAsclin_ClockSource_noClock: /* gets the respective frequency*/
|
||||
frequency = 0.0;
|
||||
break;
|
||||
case IfxAsclin_ClockSource_kernelClock:
|
||||
frequency = IfxScuCcu_getSpbFrequency();
|
||||
break;
|
||||
case IfxAsclin_ClockSource_oscillatorClock:
|
||||
frequency = IfxScuCcu_getOsc0Frequency();
|
||||
break;
|
||||
case IfxAsclin_ClockSource_flexRayClock:
|
||||
frequency = IfxScuCcu_getPllErayFrequency();
|
||||
break;
|
||||
case IfxAsclin_ClockSource_ascFastClock:
|
||||
frequency = IfxScuCcu_getBaud2Frequency();
|
||||
break;
|
||||
case IfxAsclin_ClockSource_ascSlowClock:
|
||||
frequency = IfxScuCcu_getBaud1Frequency();
|
||||
break;
|
||||
default:
|
||||
frequency = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
||||
IfxAsclin_Index IfxAsclin_getIndex(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
uint32 index;
|
||||
IfxAsclin_Index result;
|
||||
|
||||
result = IfxAsclin_Index_none;
|
||||
|
||||
for (index = 0; index < IFXASCLIN_NUM_MODULES; index++)
|
||||
{
|
||||
if (IfxAsclin_cfg_indexMap[index].module == asclin)
|
||||
{
|
||||
result = (IfxAsclin_Index)IfxAsclin_cfg_indexMap[index].index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxAsclin_getOvsFrequency(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
return (IfxAsclin_getPdFrequency(asclin) * asclin->BRG.B.NUMERATOR) / asclin->BRG.B.DENOMINATOR;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxAsclin_getPdFrequency(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
return IfxAsclin_getFaFrequency(asclin) / (asclin->BITCON.B.PRESCALER + 1);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxAsclin_getShiftFrequency(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
return IfxAsclin_getOvsFrequency(asclin) / asclin->BITCON.B.OVERSAMPLING;
|
||||
}
|
||||
|
||||
|
||||
volatile Ifx_SRC_SRCR *IfxAsclin_getSrcPointerEr(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
return (volatile Ifx_SRC_SRCR *)(&MODULE_SRC.ASCLIN.ASCLIN[IfxAsclin_getIndex(asclin)].ERR);
|
||||
}
|
||||
|
||||
|
||||
volatile Ifx_SRC_SRCR *IfxAsclin_getSrcPointerRx(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
return (volatile Ifx_SRC_SRCR *)(&MODULE_SRC.ASCLIN.ASCLIN[IfxAsclin_getIndex(asclin)].RX);
|
||||
}
|
||||
|
||||
|
||||
volatile Ifx_SRC_SRCR *IfxAsclin_getSrcPointerTx(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
return (volatile Ifx_SRC_SRCR *)(&MODULE_SRC.ASCLIN.ASCLIN[IfxAsclin_getIndex(asclin)].TX);
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxAsclin_read16(Ifx_ASCLIN *asclin, uint16 *data, uint32 count)
|
||||
{
|
||||
volatile Ifx_ASCLIN_RXDATA *rxData = (volatile Ifx_ASCLIN_RXDATA *)&asclin->RXDATA.U;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
*data++ = (uint16)rxData->U;
|
||||
count--;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxAsclin_read32(Ifx_ASCLIN *asclin, uint32 *data, uint32 count)
|
||||
{
|
||||
volatile Ifx_ASCLIN_RXDATA *rxData = (volatile Ifx_ASCLIN_RXDATA *)&asclin->RXDATA.U;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
*data++ = rxData->U;
|
||||
count--;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxAsclin_read8(Ifx_ASCLIN *asclin, uint8 *data, uint32 count)
|
||||
{
|
||||
volatile Ifx_ASCLIN_RXDATA *rxData = (volatile Ifx_ASCLIN_RXDATA *)&asclin->RXDATA.U;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
*data++ = (uint8)rxData->U;
|
||||
count--;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_resetModule(Ifx_ASCLIN *asclin)
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
|
||||
asclin->KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
|
||||
asclin->KRST1.B.RST = 1;
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
|
||||
while (0 == asclin->KRST0.B.RSTSTAT) /* Wait until reset is executed */
|
||||
{}
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
asclin->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
|
||||
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_setBaudrateBitFields(Ifx_ASCLIN *asclin, uint16 prescaler, uint16 numerator, uint16 denominator, IfxAsclin_OversamplingFactor oversampling)
|
||||
{
|
||||
IfxAsclin_ClockSource clockSource = (IfxAsclin_ClockSource)IfxAsclin_getClockSource(asclin); /* gets the current clock source */
|
||||
IfxAsclin_setClockSource(asclin, IfxAsclin_ClockSource_noClock); /* turns off the clock for settings */
|
||||
IfxAsclin_setPrescaler(asclin, prescaler); /* sets the prescaler*/
|
||||
IfxAsclin_setNumerator(asclin, numerator); /* sets the numerator*/
|
||||
IfxAsclin_setDenominator(asclin, denominator); /* sets the denominator*/
|
||||
IfxAsclin_setOversampling(asclin, oversampling); /* sets the oversampling*/
|
||||
IfxAsclin_setClockSource(asclin, clockSource); /* sets the clock source back on*/
|
||||
}
|
||||
|
||||
|
||||
boolean IfxAsclin_setBitTiming(Ifx_ASCLIN *asclin, float32 baudrate, IfxAsclin_OversamplingFactor oversampling, IfxAsclin_SamplePointPosition samplepoint, IfxAsclin_SamplesPerBit medianFilter)
|
||||
{
|
||||
IfxAsclin_ClockSource source = (IfxAsclin_ClockSource)IfxAsclin_getClockSource(asclin);
|
||||
float32 fOvs;
|
||||
uint32 d = 0, n, dBest = 1, nBest = 1;
|
||||
float32 f;
|
||||
|
||||
/* Set the PD frequency */
|
||||
float32 fpd = IfxAsclin_getPdFrequency(asclin);
|
||||
oversampling = (IfxAsclin_OversamplingFactor)__maxu((oversampling + 1), 4);
|
||||
samplepoint = (IfxAsclin_SamplePointPosition)__maxu(samplepoint, 1);
|
||||
fOvs = baudrate * oversampling;
|
||||
float32 relError = fOvs;
|
||||
float32 limit = 0.001 * fOvs; // save the error limit
|
||||
|
||||
boolean terminated = FALSE;
|
||||
float32 newRelError; //modified by Hassan
|
||||
uint32 adder_facL, adder_facH, adder_facL_min, count; //modified by Hassan
|
||||
|
||||
d = (uint32)(fpd / fOvs);
|
||||
n = 1;
|
||||
|
||||
if (d >> 12)
|
||||
{
|
||||
if (((uint32)(fpd / (baudrate * 16))) >> 12)
|
||||
{
|
||||
/* Increase the value of the prescalar to generate the required baudrate */
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_WARNING, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increase the value of the oversampling to generate the required baudrate */
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_WARNING, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
dBest = d;
|
||||
nBest = n;
|
||||
adder_facL_min = 0;
|
||||
f = (fpd * n) / d;
|
||||
relError = __absf(fOvs - f);
|
||||
|
||||
if (relError <= limit)
|
||||
{
|
||||
terminated = TRUE;
|
||||
}
|
||||
|
||||
for (n = 2; ((!terminated) && ((n * d) <= 0xFFF)); n++)
|
||||
{
|
||||
if (n == 2)
|
||||
{
|
||||
adder_facL = 1;
|
||||
adder_facH = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
adder_facL = (adder_facL_min * n) / nBest;
|
||||
adder_facH = adder_facL + 1;
|
||||
}
|
||||
|
||||
for (count = adder_facL; count <= adder_facH; count++)
|
||||
{
|
||||
f = (fpd * n) / (n * d + count);
|
||||
newRelError = __absf(fOvs - f);
|
||||
|
||||
if (relError > (newRelError))
|
||||
{
|
||||
relError = newRelError;
|
||||
nBest = n;
|
||||
dBest = (n * d + count);
|
||||
adder_facL_min = count;
|
||||
}
|
||||
}
|
||||
|
||||
if (relError <= limit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IfxAsclin_setClockSource(asclin, IfxAsclin_ClockSource_noClock);
|
||||
asclin->BRG.B.DENOMINATOR = dBest;
|
||||
asclin->BRG.B.NUMERATOR = nBest;
|
||||
|
||||
/* Set the SHIFT frequency */
|
||||
asclin->BITCON.B.OVERSAMPLING = oversampling - 1;
|
||||
|
||||
/* Set the sampling point */
|
||||
asclin->BITCON.B.SAMPLEPOINT = samplepoint;
|
||||
|
||||
/* Set the median filter */
|
||||
asclin->BITCON.B.SM = medianFilter ? 1 : 0;
|
||||
|
||||
IfxAsclin_setClockSource(asclin, source);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxAsclin_setClockSource(Ifx_ASCLIN *asclin, IfxAsclin_ClockSource clockSource)
|
||||
{
|
||||
asclin->CSR.B.CLKSEL = clockSource; /* selects the given clock source*/
|
||||
|
||||
/* Waits TW or polls for CSR.CON to change */
|
||||
if (clockSource == IfxAsclin_ClockSource_noClock)
|
||||
{
|
||||
while (IfxAsclin_getClockStatus(asclin) != 0U)
|
||||
{}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (IfxAsclin_getClockStatus(asclin) != 1U)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxAsclin_write16(Ifx_ASCLIN *asclin, uint16 *data, uint32 count)
|
||||
{
|
||||
volatile Ifx_ASCLIN_TXDATA *txData = (volatile Ifx_ASCLIN_TXDATA *)&asclin->TXDATA.U;
|
||||
|
||||
while ((count > 0))
|
||||
{
|
||||
txData->U = *data++;
|
||||
count--;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxAsclin_write32(Ifx_ASCLIN *asclin, uint32 *data, uint32 count)
|
||||
{
|
||||
volatile Ifx_ASCLIN_TXDATA *txData = (volatile Ifx_ASCLIN_TXDATA *)&asclin->TXDATA.U;
|
||||
|
||||
while ((count > 0))
|
||||
{
|
||||
txData->U = *data++;
|
||||
count--;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxAsclin_write8(Ifx_ASCLIN *asclin,const uint8 *data, uint32 count)
|
||||
{
|
||||
volatile Ifx_ASCLIN_TXDATA *txData = (volatile Ifx_ASCLIN_TXDATA *)&asclin->TXDATA.U;
|
||||
|
||||
while ((count > 0))
|
||||
{
|
||||
txData->U = *data++;
|
||||
count--;
|
||||
while(asclin->TXFIFOCON.B.FILL > 0);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
* \file IfxCcu6_Icu.c
|
||||
* \brief CCU6 ICU details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxCcu6_Icu.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint32 IfxCcu6_Icu_getTimeStamp(IfxCcu6_Icu_Channel *channel)
|
||||
{
|
||||
uint32 timeStamp = 0;
|
||||
|
||||
timeStamp = IfxCcu6_getCaptureShadowRegisterValue(channel->ccu6, channel->channelId);
|
||||
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Icu_initChannel(IfxCcu6_Icu_Channel *channel, const IfxCcu6_Icu_ChannelConfig *channelConfig)
|
||||
{
|
||||
channel->ccu6 = channelConfig->ccu6;
|
||||
|
||||
/* -- capture input initialisation -- */
|
||||
|
||||
const IfxCcu6_Icu_Pins *pins = channelConfig->pins;
|
||||
|
||||
if (pins != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_Cc60in_In *cc60In = pins->cc60In;
|
||||
|
||||
if (cc60In != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc60InPinWithPadLevel(cc60In, pins->cc6xInputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cc61in_In *cc61In = pins->cc61In;
|
||||
|
||||
if (cc61In != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc61InPinWithPadLevel(cc61In, pins->cc6xInputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cc62in_In *cc62In = pins->cc62In;
|
||||
|
||||
if (cc62In != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc62InPinWithPadLevel(cc62In, pins->cc6xInputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
if (channelConfig->multiInputCaptureEnabled)
|
||||
{
|
||||
IfxCcu6_Ccpos0_In *ccpos0 = pins->ccpos0;
|
||||
|
||||
if (ccpos0 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCcpos0PinWithPadLevel(ccpos0, pins->ccposxInputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Ccpos1_In *ccpos1 = pins->ccpos1;
|
||||
|
||||
if (ccpos1 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCcpos1PinWithPadLevel(ccpos1, pins->ccposxInputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Ccpos2_In *ccpos2 = pins->ccpos2;
|
||||
|
||||
if (ccpos2 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCcpos2PinWithPadLevel(ccpos2, pins->ccposxInputMode, pins->pinDriver);
|
||||
}
|
||||
}
|
||||
|
||||
IfxCcu6_T12hr_In *t12hr = pins->t12hr;
|
||||
|
||||
if (t12hr != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initT12hrPinWithPadLevel(t12hr, pins->t1xhrInputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_T13hr_In *t13hr = pins->t13hr;
|
||||
|
||||
if (t13hr != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initT13hrPinWithPadLevel(t13hr, pins->t1xhrInputMode, pins->pinDriver);
|
||||
}
|
||||
}
|
||||
|
||||
/* -- interrupt initialisation -- */
|
||||
|
||||
if (channelConfig->interrupt1.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(channelConfig->ccu6, channelConfig->interrupt1.source);
|
||||
IfxCcu6_routeInterruptNode(channelConfig->ccu6, channelConfig->interrupt1.source, channelConfig->interrupt1.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(channelConfig->ccu6, channelConfig->interrupt1.serviceRequest);
|
||||
IfxSrc_init(src, channelConfig->interrupt1.typeOfService, channelConfig->interrupt1.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (channelConfig->interrupt2.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(channelConfig->ccu6, channelConfig->interrupt2.source);
|
||||
IfxCcu6_routeInterruptNode(channelConfig->ccu6, channelConfig->interrupt2.source, channelConfig->interrupt2.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(channelConfig->ccu6, channelConfig->interrupt2.serviceRequest);
|
||||
IfxSrc_init(src, channelConfig->interrupt2.typeOfService, channelConfig->interrupt2.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (channelConfig->interrupt3.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(channelConfig->ccu6, channelConfig->interrupt3.source);
|
||||
IfxCcu6_routeInterruptNode(channelConfig->ccu6, channelConfig->interrupt3.source, channelConfig->interrupt3.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(channelConfig->ccu6, channelConfig->interrupt3.serviceRequest);
|
||||
IfxSrc_init(src, channelConfig->interrupt3.typeOfService, channelConfig->interrupt3.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (channelConfig->interrupt4.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(channelConfig->ccu6, channelConfig->interrupt4.source);
|
||||
IfxCcu6_routeInterruptNode(channelConfig->ccu6, channelConfig->interrupt4.source, channelConfig->interrupt4.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(channelConfig->ccu6, channelConfig->interrupt4.serviceRequest);
|
||||
IfxSrc_init(src, channelConfig->interrupt4.typeOfService, channelConfig->interrupt4.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
channel->trigger = channelConfig->trigger;
|
||||
channel->channelId = channelConfig->channelId;
|
||||
channel->channelMode = channelConfig->channelMode;
|
||||
|
||||
#if IFX_CFG_USE_STANDARD_INTERFACE
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (uint32)icu == ((uint32)&icu->base));
|
||||
icu->base.functions.startCapture = (Icu_StartCapture) & IfxCcu6_Icu_startCapture;
|
||||
icu->base.functions.stopCapture = (Icu_StopCapture) & IfxCcu6_Icu_stopCapture;
|
||||
icu->base.functions.getTimeStamp = (Icu_GetTimeStamp) & IfxCcu6_Icu_getTimeStamp;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Icu_initChannelConfig(IfxCcu6_Icu_ChannelConfig *channelConfig, Ifx_CCU6 *ccu6)
|
||||
{
|
||||
channelConfig->ccu6 = ccu6;
|
||||
|
||||
channelConfig->channelId = IfxCcu6_T12Channel_0; // default channel 0
|
||||
channelConfig->channelMode = IfxCcu6_T12ChannelMode_doubleRegisterCaptureRising; // default CC6xIN rising edge
|
||||
|
||||
channelConfig->interrupt1.source = IfxCcu6_InterruptSource_cc60RisingEdge;
|
||||
channelConfig->interrupt1.serviceRequest = IfxCcu6_ServiceRequest_0;
|
||||
channelConfig->interrupt1.priority = 0; // interrupt priority 0
|
||||
channelConfig->interrupt1.typeOfService = IfxSrc_Tos_cpu0; // type of service CPU0
|
||||
|
||||
channelConfig->interrupt2.source = IfxCcu6_InterruptSource_cc60FallingEdge;
|
||||
channelConfig->interrupt2.serviceRequest = IfxCcu6_ServiceRequest_1;
|
||||
channelConfig->interrupt2.priority = 0; // interrupt priority 0
|
||||
channelConfig->interrupt2.typeOfService = IfxSrc_Tos_cpu0; // type of service CPU0
|
||||
|
||||
channelConfig->interrupt3.source = IfxCcu6_InterruptSource_cc61RisingEdge;
|
||||
channelConfig->interrupt3.serviceRequest = IfxCcu6_ServiceRequest_2;
|
||||
channelConfig->interrupt3.priority = 0; // interrupt priority 0
|
||||
channelConfig->interrupt3.typeOfService = IfxSrc_Tos_cpu0; // type of service CPU0
|
||||
|
||||
channelConfig->interrupt4.source = IfxCcu6_InterruptSource_trap;
|
||||
channelConfig->interrupt4.serviceRequest = IfxCcu6_ServiceRequest_3;
|
||||
channelConfig->interrupt4.priority = 0; // interrupt priority 0
|
||||
channelConfig->interrupt4.typeOfService = IfxSrc_Tos_cpu0; // type of service CPU0
|
||||
|
||||
channelConfig->trigger.extInputTrigger = channelConfig->timer.trigger.t12ExtInputTrigger;
|
||||
channelConfig->trigger.extInputTriggerMode = channelConfig->timer.trigger.extInputTriggerMode;
|
||||
|
||||
channelConfig->pins = NULL_PTR;
|
||||
|
||||
channelConfig->multiInputCaptureEnabled = FALSE;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Icu_initModule(IfxCcu6_Icu *icu, const IfxCcu6_Icu_Config *config)
|
||||
{
|
||||
Ifx_CCU6 *ccu6SFR = config->ccu6; // pointer to CCU6 registers
|
||||
icu->ccu6 = ccu6SFR; // adding register pointer to module handler
|
||||
|
||||
/* -- hardware module initialisation -- */
|
||||
|
||||
// enable module if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_isModuleEnabled(ccu6SFR) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableModule(ccu6SFR);
|
||||
}
|
||||
|
||||
/* -- timer initialisation -- */
|
||||
|
||||
// enable Timer12 if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_getTimerAvailabilityStatus(ccu6SFR, IfxCcu6_TimerId_t12) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableTimer(ccu6SFR, IfxCcu6_TimerId_t12);
|
||||
}
|
||||
|
||||
// clock initialization //
|
||||
|
||||
Ifx_TimerValue period = config->period;
|
||||
|
||||
if (config->clock.extClockEnabled) // if external source is selected as reference
|
||||
{
|
||||
// input signal selection
|
||||
if (config->clock.extClockInput != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setT12InputSignal(config->ccu6, config->clock.extClockInput);
|
||||
}
|
||||
|
||||
// counting input mode selection
|
||||
IfxCcu6_setCountingInputMode(ccu6SFR, IfxCcu6_TimerId_t12, config->clock.countingInputMode);
|
||||
|
||||
// countining mode selection
|
||||
IfxCcu6_setT12CountMode(ccu6SFR, config->countMode);
|
||||
|
||||
// period selection for center aligned mode
|
||||
if (config->countMode == IfxCcu6_T12CountMode_centerAligned)
|
||||
{
|
||||
period = (period / 2) - 1;
|
||||
}
|
||||
|
||||
// period setting
|
||||
IfxCcu6_setT12PeriodValue(ccu6SFR, (uint16)period);
|
||||
|
||||
// frequency is meaningless here : set to 0
|
||||
icu->captureFrequency = 0;
|
||||
}
|
||||
else // if internal clock is selected as reference
|
||||
{
|
||||
// in case of in sync with T13, T12 runs at same frequency as T13
|
||||
icu->captureFrequency = IfxCcu6_setT12Frequency(ccu6SFR, config->frequency, period, config->countMode);
|
||||
}
|
||||
|
||||
// counter initialisation //
|
||||
|
||||
IfxCcu6_setT12CounterValue(ccu6SFR, config->counterValue);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Icu_initModuleConfig(IfxCcu6_Icu_Config *config, Ifx_CCU6 *ccu6)
|
||||
{
|
||||
config->ccu6 = ccu6;
|
||||
|
||||
config->frequency = 400000;
|
||||
config->period = 0xFFFE; /* max(uint16) - 1 */
|
||||
|
||||
config->clock.extClockEnabled = FALSE;
|
||||
config->clock.extClockInput = NULL_PTR;
|
||||
config->clock.countingInputMode = IfxCcu6_CountingInputMode_internal;
|
||||
|
||||
config->countMode = IfxCcu6_T12CountMode_edgeAligned;
|
||||
config->counterValue = 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Icu_startCapture(IfxCcu6_Icu_Channel *channel)
|
||||
{
|
||||
if (IfxCcu6_getTimerRunStatus(channel->ccu6, IfxCcu6_TimerId_t12) != IfxCcu6_TimerRunStatus_running)
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(channel->ccu6, TRUE, FALSE);
|
||||
|
||||
// start the timer
|
||||
if (channel->trigger.extInputTrigger != NULL_PTR)
|
||||
{
|
||||
// external input setting
|
||||
IfxCcu6_setExternalRunMode(channel->ccu6, IfxCcu6_TimerId_t12, channel->trigger.extInputTriggerMode);
|
||||
IfxCcu6_setT12InputSignal(channel->ccu6, channel->trigger.extInputTrigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
// internal start
|
||||
IfxCcu6_startTimer(channel->ccu6, TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// enable capture mode
|
||||
IfxCcu6_setT12ChannelMode(channel->ccu6, channel->channelId, channel->channelMode);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Icu_stopCapture(IfxCcu6_Icu_Channel *channel)
|
||||
{
|
||||
// disable shadow transfer
|
||||
IfxCcu6_disableShadowTransfer(channel->ccu6, TRUE, FALSE);
|
||||
|
||||
// disable capture mode
|
||||
IfxCcu6_setT12ChannelMode(channel->ccu6, channel->channelId, IfxCcu6_T12ChannelMode_off);
|
||||
|
||||
// remove the external input
|
||||
IfxCcu6_setExternalRunMode(channel->ccu6, IfxCcu6_TimerId_t12, IfxCcu6_ExternalTriggerMode_disable);
|
||||
|
||||
// stop the timer
|
||||
IfxCcu6_stopTimer(channel->ccu6, TRUE, FALSE);
|
||||
}
|
||||
@@ -0,0 +1,442 @@
|
||||
/**
|
||||
* \file IfxCcu6_Icu.h
|
||||
* \brief CCU6 ICU details
|
||||
* \ingroup IfxLld_Ccu6
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_Icu_Usage How to use the CCU6 ICU Interface driver?
|
||||
* \ingroup IfxLld_Ccu6_Icu
|
||||
*
|
||||
* The ICU interface driver provides a default CCU6 configuration for capturing the input from the selected channel
|
||||
*
|
||||
* User can select the various configuration options that hardware allows
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Ccu6_Icu_Preparation Preparation
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_Icu_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
*
|
||||
* \code
|
||||
* #include <Ccu6/Icu/IfxCcu6_Icu.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_Icu_Variables Variables
|
||||
*
|
||||
* Declare the ICU handle and channel handle as global variables in your C code:
|
||||
*
|
||||
* \code
|
||||
* // used globally
|
||||
* static IfxCcu6_Icu icu;
|
||||
* static IfxCcu6_IcuChannel icuChannel;
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_Icu_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priority for the Interrrupt handler. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
*
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define IFX_INTPRIO_CCU6 1
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routine to your C code.
|
||||
*
|
||||
* \code
|
||||
* IFX_INTERRUPT(ccu60ISR_Icu, 0, IFX_INTPRIO_CCU6)
|
||||
* {
|
||||
* //user code
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handlers in your initialisation function:
|
||||
*
|
||||
* \code
|
||||
* // install interrupt handlers
|
||||
* IfxCpu_Irq_installInterruptHandler(&ccu60ISR_Icu, IFX_INTPRIO_CCU6);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_Icu_Init Module Initialisation
|
||||
*
|
||||
* The module can be initialised in two ways, as a stand alone driver or in conjunction with Timer driver
|
||||
* The module initialisation can be done in the same function. Here an example:
|
||||
*
|
||||
* \code
|
||||
* // ---- when not using inconjunction with Timer driver ---- //
|
||||
* // create configuration
|
||||
* IfxCcu6_Icu_Config icuConfig;
|
||||
* IfxCcu6_Icu_initModuleConfig(&icuConfig, &MODULE_CCU60);
|
||||
*
|
||||
* // configure the frequency of the timer in case of internal start
|
||||
* icuConfig.frequency = 400000;
|
||||
*
|
||||
* // configure the period of the timer
|
||||
* icuConfig.period = 100;
|
||||
*
|
||||
* // configure the clock for internal mode
|
||||
* icuConfig.clock.extClockEnabled = FALSE;
|
||||
* icuConfig.clock.extClockInput = NULL_PTR;
|
||||
* icuConfig.clock.countingInputMode = IfxCcu6_CountingInputMode_internal;
|
||||
*
|
||||
* // configure count operation
|
||||
* icuConfig.countMode = IfxCcu6_T12CountMode_edgeAligned;
|
||||
* icuConfig.counterValue = 0;
|
||||
*
|
||||
* // initialize the module
|
||||
* IfxCcu6_Icu_initModule(&icu, &icuConfig);
|
||||
* // -------------------------------------------------------- //
|
||||
*
|
||||
* // ---- when not using inconjunction with Timer driver ---- //
|
||||
* // after initialising the timer
|
||||
* IfxCcu6_Timer timer;
|
||||
* IfxCcu6_TimerConfig timerConfig;
|
||||
* IfxCcu6_Timer_initModule(&timer, &timerConfig); // e.g. Timer 12 is specified previously in timerConfig.
|
||||
* // -------------------------------------------------------- //
|
||||
*
|
||||
* // create Icu channel config
|
||||
* IfxCcu6_Icu_channelConfig icuChannelConfig;
|
||||
* IfxCcu6_Icu_initChannelConfig(&icuChannelConfig, &MODULE_CCU60);
|
||||
*
|
||||
* // ---- when using inconjunction with Timer driver ---- //
|
||||
* icuChannelConfig.timer = (Timer*)&timer;
|
||||
* // ---------------------------------------------------- //
|
||||
*
|
||||
* // configure the channel
|
||||
* icuChannelConfig.channelNumber = IfxCcu6_T12Channel_0;
|
||||
* icuChannelConfig.channelMode = IfxCcu6_T12ChannelMode_doubleRegisterCaptureRising;
|
||||
*
|
||||
* // configure the interrupts
|
||||
* icuChannelConfig.interrupt1.interruptSource = IfxCcu6_InterruptSource_cc60RisingEdge;
|
||||
* icuChannelConfig.interrupt1.serviceRequest = IfxCcu6_ServiceRequest_2;
|
||||
* icuChannelConfig.interrupt1.priority = IFX_INTRPRIO_CCU6;
|
||||
* icuChannelConfig.interrupt1.typeOfService = IfxSrc_Tos_cpu0;
|
||||
*
|
||||
* // ---- when not using inconjunction with Timer driver ---- //
|
||||
* // configure input and output triggers
|
||||
* icuChannelConfig.trigger.extInputTrigger = IfxCcu60_T12HRB_P00_7_IN;
|
||||
* icuChannelConfig.trigger.extInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge;
|
||||
* // -------------------------------------------------------- //
|
||||
*
|
||||
* // pin configuration, in case of multi input capture mode select the respective CC6xIn and CCPOSxIn pins of the selected channel
|
||||
* const IfxCcu6_Icu_Pins pins = {
|
||||
* IfxCcu60_CC60INA_P02_0_IN, // CC60In pin
|
||||
* NULL, // CC61In pin not used
|
||||
* NULL, // CC62In pin not used
|
||||
* NULL, // CCPOS0In pin not used
|
||||
* NULL, // CCPOS1In pin not used
|
||||
* NULL, // CCPOS2In pin not used
|
||||
* IfxPort_InputMode_pullUp,
|
||||
* IfxPort_InputMode_pullUp
|
||||
* };
|
||||
* IcuConfig.pins = &pins;
|
||||
*
|
||||
* // configure multi input capture mode
|
||||
* icuChannelConfig->multiInputCaptureEnabled = FALSE;
|
||||
*
|
||||
* // initialize the channel
|
||||
* IfxCcu6_Icu_initChannel(&icuChannel, &icuChannelConfig);
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* The Icu is ready for use now!
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Ccu6_Icu_Control Control
|
||||
*
|
||||
*
|
||||
* The ICU driver provides simple to use Capture Control functions
|
||||
*
|
||||
* This means: you can start and stop the capture process, and you can also get a time stamp at any point of time during the capture process
|
||||
*
|
||||
* Start Capture
|
||||
*
|
||||
* \code
|
||||
* IfxCcu6_Icu_startCapture(&icuChannel);
|
||||
* \endcode
|
||||
*
|
||||
* Stop Capture
|
||||
*
|
||||
* \code
|
||||
* IfxCcu6_Icu_stopCapture(&icuChannel);
|
||||
* \endcode
|
||||
*
|
||||
* Get time stamp at any point of time during the capture process
|
||||
* (can also be used in ISR)
|
||||
*
|
||||
* \code
|
||||
* // assumed to be declared globally
|
||||
* // uint32 timeStamp[100] = 0;
|
||||
*
|
||||
* // store the time stamp in an array
|
||||
* timeStamp[i] = IfxCcu6_Icu_getTimeStamp(&icuChannel);
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_Icu ICU Interface driver
|
||||
* \ingroup IfxLld_Ccu6
|
||||
* \defgroup IfxLld_Ccu6_Icu_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Ccu6_Icu
|
||||
* \defgroup IfxLld_Ccu6_Icu_Module_Initialize_Functions Module Initialize Functions
|
||||
* \ingroup IfxLld_Ccu6_Icu
|
||||
* \defgroup IfxLld_Ccu6_Icu_Capture_Control_Functions Capture Control Functions
|
||||
* \ingroup IfxLld_Ccu6_Icu
|
||||
* \defgroup IfxLld_Ccu6_Icu_Channel_Initialize_Functions Channel Initialize Functions
|
||||
* \ingroup IfxLld_Ccu6_Icu
|
||||
*/
|
||||
|
||||
#ifndef IFXCCU6_ICU_H
|
||||
#define IFXCCU6_ICU_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Ccu6/Std/IfxCcu6.h"
|
||||
#include "If/Ccu6If/Icu.h"
|
||||
#include "Ccu6/Timer/IfxCcu6_Timer.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_Icu_DataStructures
|
||||
* \{ */
|
||||
/** \brief Structure for clock configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean extClockEnabled; /**< \brief external clock enable / disable selection */
|
||||
IfxCcu6_T12hr_In *extClockInput; /**< \brief External input signal selection for timer 12 */
|
||||
IfxCcu6_CountingInputMode countingInputMode; /**< \brief Input event leading to a counting action of the timer T12 */
|
||||
} IfxCcu6_Icu_Clock;
|
||||
|
||||
/** \brief Structure for interrupt configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_InterruptSource source; /**< \brief Interrupt source selection */
|
||||
IfxCcu6_ServiceRequest serviceRequest; /**< \brief Selection of service request outputs */
|
||||
uint16 priority; /**< \brief Interrupt priority */
|
||||
IfxSrc_Tos typeOfService; /**< \brief type of interrupt service */
|
||||
} IfxCcu6_Icu_InterruptConfig;
|
||||
|
||||
/** \brief Structure for capture input pins
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IFX_CONST IfxCcu6_Cc60in_In *cc60In; /**< \brief CC60 input signal */
|
||||
IFX_CONST IfxCcu6_Cc61in_In *cc61In; /**< \brief CC61 input signal */
|
||||
IFX_CONST IfxCcu6_Cc62in_In *cc62In; /**< \brief CC62 input signal */
|
||||
IFX_CONST IfxCcu6_Ccpos0_In *ccpos0; /**< \brief CCPOS0 input signal */
|
||||
IFX_CONST IfxCcu6_Ccpos1_In *ccpos1; /**< \brief CCPOS2 input signal */
|
||||
IFX_CONST IfxCcu6_Ccpos2_In *ccpos2; /**< \brief CCPOS2 input signal */
|
||||
IfxPort_InputMode cc6xInputMode; /**< \brief The CC6x pin input mode which should be configured */
|
||||
IfxPort_InputMode ccposxInputMode; /**< \brief The CCPOSx pin input mode which should be configured */
|
||||
IFX_CONST IfxCcu6_T12hr_In *t12hr; /**< \brief T12HR input signal */
|
||||
IFX_CONST IfxCcu6_T13hr_In *t13hr; /**< \brief T13HR input signal */
|
||||
IfxPort_InputMode t1xhrInputMode; /**< \brief The T1xHR pin input mode which should be configured */
|
||||
IfxPort_PadDriver pinDriver; /**< \brief Pad Driver */
|
||||
} IfxCcu6_Icu_Pins;
|
||||
|
||||
/** \brief Configuration structure for external triggers
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_T12hr_In *extInputTrigger; /**< \brief External input signal selection for timer */
|
||||
IfxCcu6_ExternalTriggerMode extInputTriggerMode; /**< \brief Event of signal T12HR that can set the run bit T12R by HW */
|
||||
} IfxCcu6_Icu_TriggerConfig;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_Icu_DataStructures
|
||||
* \{ */
|
||||
/** \brief Module handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
float32 captureFrequency; /**< \brief Configured CCU6 capture frequency ( set to 0 for external counting mode) */
|
||||
} IfxCcu6_Icu;
|
||||
|
||||
/** \brief Channel handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Icu base; /**< \brief Base ICU object */
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
IfxCcu6_Icu_TriggerConfig trigger; /**< \brief Structure for trigger configuration */
|
||||
IfxCcu6_T12Channel channelId; /**< \brief Capture compare channel of the Timer12 */
|
||||
IfxCcu6_T12ChannelMode channelMode; /**< \brief The operating mode for the T12 channel */
|
||||
} IfxCcu6_Icu_Channel;
|
||||
|
||||
/** \brief Configuration structure of the channel
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Icu_Config base; /**< \brief Base configuration */
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
IfxCcu6_T12Channel channelId; /**< \brief Capture compare channel of the Timer12 */
|
||||
IfxCcu6_T12ChannelMode channelMode; /**< \brief The operating mode for the T12 channel */
|
||||
IfxCcu6_Icu_InterruptConfig interrupt1; /**< \brief Structure for first interrupt configuration */
|
||||
IfxCcu6_Icu_InterruptConfig interrupt2; /**< \brief Structure for second interrupt configuration */
|
||||
IfxCcu6_Icu_InterruptConfig interrupt3; /**< \brief Structure for third interrupt configuration */
|
||||
IfxCcu6_Icu_InterruptConfig interrupt4; /**< \brief Structure for fourth interrupt configuration */
|
||||
IfxCcu6_Icu_TriggerConfig trigger; /**< \brief Structure for trigger configuration */
|
||||
IfxCcu6_Icu_Pins *pins; /**< \brief Structure for capture input pins */
|
||||
boolean multiInputCaptureEnabled; /**< \brief Choice of multi input capture */
|
||||
IfxCcu6_Timer timer; /**< \brief Timer handle */
|
||||
} IfxCcu6_Icu_ChannelConfig;
|
||||
|
||||
/** \brief Configuration structure of the module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
float32 frequency; /**< \brief Specify expected PWM frequency in Hertz */
|
||||
Ifx_TimerValue period; /**< \brief PWM period in ticks */
|
||||
IfxCcu6_Icu_Clock clock; /**< \brief Structure for clock configuration */
|
||||
IfxCcu6_T12CountMode countMode; /**< \brief Operating mode of Timer 12 */
|
||||
uint16 counterValue; /**< \brief 16-bit counter value of Timer12 */
|
||||
} IfxCcu6_Icu_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_Icu_Module_Initialize_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialises the module with default configuration
|
||||
* \param icu Module handle
|
||||
* \param config Configuration structure of the module
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Icu_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Icu_initModule(IfxCcu6_Icu *icu, const IfxCcu6_Icu_Config *config);
|
||||
|
||||
/** \brief Fills the config structure with default values
|
||||
* \param config Configuration structure of the module
|
||||
* \param ccu6 Pointer to the base of CCU6 registers
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Icu_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Icu_initModuleConfig(IfxCcu6_Icu_Config *config, Ifx_CCU6 *ccu6);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_Icu_Capture_Control_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the cuurent value stored in the Compare Shadow register (current time stamp)
|
||||
* \param channel Channel handle
|
||||
* \return timeStamp (cuurent CC6xSR register value)
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Icu_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxCcu6_Icu_getTimeStamp(IfxCcu6_Icu_Channel *channel);
|
||||
|
||||
/** \brief Starts the input capture
|
||||
* \param channel Channel handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Icu_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Icu_startCapture(IfxCcu6_Icu_Channel *channel);
|
||||
|
||||
/** \brief Stops the input capture
|
||||
* \param channel Channel handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Icu_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Icu_stopCapture(IfxCcu6_Icu_Channel *channel);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_Icu_Channel_Initialize_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialises the channel
|
||||
* \param channel Channel handle
|
||||
* \param channelConfig Configuration structure of the channel
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Icu_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Icu_initChannel(IfxCcu6_Icu_Channel *channel, const IfxCcu6_Icu_ChannelConfig *channelConfig);
|
||||
|
||||
/** \brief Fills the channel config structure with default values
|
||||
* \param channelConfig Configuration structure of the channel
|
||||
* \param ccu6 Pointer to the base of CCU6 registers
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Icu_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Icu_initChannelConfig(IfxCcu6_Icu_ChannelConfig *channelConfig, Ifx_CCU6 *ccu6);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXCCU6_ICU_H */
|
||||
@@ -0,0 +1,528 @@
|
||||
/**
|
||||
* \file IfxCcu6_PwmBc.c
|
||||
* \brief CCU6 PWMBC details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxCcu6_PwmBc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint32 IfxCcu6_PwmBc_getMotorSpeed(IfxCcu6_PwmBc *pwmBc)
|
||||
{
|
||||
uint32 currentTime, previousTime;
|
||||
float32 speed;
|
||||
|
||||
currentTime = IfxCcu6_getCaptureRegisterValue(pwmBc->ccu6, IfxCcu6_T12Channel_0);
|
||||
previousTime = IfxCcu6_getCaptureShadowRegisterValue(pwmBc->ccu6, IfxCcu6_T12Channel_0);
|
||||
|
||||
// TODO -- FIX IT --
|
||||
speed = (currentTime - previousTime) * (6 / (pwmBc->base.t13Frequency));
|
||||
speed = speed * 60 * 100000; //convertion to RPM (minutes),
|
||||
return speed;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_PwmBc_initModule(IfxCcu6_PwmBc *pwmBc, const IfxCcu6_PwmBc_Config *config)
|
||||
{
|
||||
Ifx_CCU6 *ccu6SFR = config->ccu6; // pointer to CCU6 registers
|
||||
pwmBc->ccu6 = ccu6SFR; // adding register pointer to module handler
|
||||
|
||||
/* -- hardware module initialisation -- */
|
||||
|
||||
// enable module if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_isModuleEnabled(ccu6SFR) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableModule(ccu6SFR);
|
||||
}
|
||||
|
||||
/* -- Timer13 initialisation -- */
|
||||
|
||||
// enable Timer13 if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_getTimerAvailabilityStatus(ccu6SFR, IfxCcu6_TimerId_t13) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableTimer(ccu6SFR, IfxCcu6_TimerId_t13);
|
||||
}
|
||||
|
||||
// clock initialisation //
|
||||
pwmBc->base.t13Frequency = IfxCcu6_setT13Frequency(ccu6SFR, config->base.t13Frequency, config->base.t13Period);
|
||||
|
||||
// duty cycle initialisation //
|
||||
|
||||
IfxCcu6_setT13CounterValue(ccu6SFR, config->timer13.counterValue);
|
||||
|
||||
IfxCcu6_setT13CompareValue(ccu6SFR, config->timer13.compareValue);
|
||||
|
||||
// if Timer 13 start is in sync with Timer 12 //
|
||||
|
||||
if (config->trigger.t13InSyncWithT12)
|
||||
{
|
||||
IfxCcu6_setT13TriggerEventMode(ccu6SFR, config->timer13.t12SyncEvent);
|
||||
IfxCcu6_setT13TriggerEventDirection(ccu6SFR, config->timer13.t12SyncDirection);
|
||||
}
|
||||
|
||||
/* -- Timer12 initialisation -- */
|
||||
|
||||
// enable Timer12 if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_getTimerAvailabilityStatus(ccu6SFR, IfxCcu6_TimerId_t12) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableTimer(ccu6SFR, IfxCcu6_TimerId_t12);
|
||||
}
|
||||
|
||||
// clock initialisation //
|
||||
|
||||
IfxCcu6_setT12Frequency(ccu6SFR, config->base.t12Frequency, config->base.t12Period, config->timer12.countMode);
|
||||
|
||||
// duty cycle initialisation //
|
||||
|
||||
IfxCcu6_setT12CounterValue(ccu6SFR, config->timer12.counterValue);
|
||||
|
||||
// hall effect noise filter initialisation
|
||||
if (config->base.noiseFilter)
|
||||
{
|
||||
IfxCcu6_setDeadTimeValue(ccu6SFR, (uint8)config->base.noiseFilter);
|
||||
IfxCcu6_enableDeadTime(ccu6SFR, IfxCcu6_T12Channel_0);
|
||||
IfxCcu6_disableDelayBypass(ccu6SFR);
|
||||
}
|
||||
|
||||
// channel initialisation for hall sensor mode ( for Brush Less DC motor)
|
||||
IfxCcu6_setT12ChannelMode(ccu6SFR, IfxCcu6_T12Channel_0, IfxCcu6_T12ChannelMode_hallSensor);
|
||||
IfxCcu6_setT12ChannelMode(ccu6SFR, IfxCcu6_T12Channel_1, IfxCcu6_T12ChannelMode_hallSensor);
|
||||
IfxCcu6_setT12ChannelMode(ccu6SFR, IfxCcu6_T12Channel_2, IfxCcu6_T12ChannelMode_hallSensor);
|
||||
|
||||
// phase delay initialisation
|
||||
IfxCcu6_setT12CompareValue(ccu6SFR, IfxCcu6_T12Channel_1, (uint16)config->base.phaseDelay);
|
||||
|
||||
// multichannel control / output pattern control initialisation
|
||||
IfxCcu6_setMultiChannelSwitchingMode(ccu6SFR, config->multiChannelControl.switchingSelect);
|
||||
IfxCcu6_setMultiChannelSwitchingSync(ccu6SFR, config->multiChannelControl.switchingSync);
|
||||
|
||||
/* -- output path initialisation -- */
|
||||
|
||||
//enable Timer13 modulation output path for all T12 channel outs//
|
||||
|
||||
IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t13, IfxCcu6_ChannelOut_cc0);
|
||||
IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t13, IfxCcu6_ChannelOut_cc1);
|
||||
IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t13, IfxCcu6_ChannelOut_cc2);
|
||||
|
||||
if (config->pins->cout63 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t13, IfxCcu6_ChannelOut_cout3);
|
||||
}
|
||||
|
||||
// output passive logic configuration //
|
||||
//TODO check correct polarity:
|
||||
|
||||
IfxCcu6_setOutputPassiveState(ccu6SFR, IfxCcu6_ChannelOut_cc0, config->base.activeState);
|
||||
IfxCcu6_setOutputPassiveState(ccu6SFR, IfxCcu6_ChannelOut_cc1, config->base.activeState);
|
||||
IfxCcu6_setOutputPassiveState(ccu6SFR, IfxCcu6_ChannelOut_cc2, config->base.activeState);
|
||||
|
||||
if (config->pins->cout63 != NULL_PTR)
|
||||
|
||||
{
|
||||
IfxCcu6_setOutputPassiveState(ccu6SFR, IfxCcu6_ChannelOut_cout3, config->base.activeState);
|
||||
}
|
||||
|
||||
/* -- Pin mapping -- */
|
||||
|
||||
const IfxCcu6_PwmBc_Pins *pins = config->pins;
|
||||
|
||||
if (pins != NULL_PTR)
|
||||
{
|
||||
// modulation output pins
|
||||
|
||||
IfxCcu6_Cc60_Out *cc60Out = pins->cc60Out;
|
||||
|
||||
if (cc60Out != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc60OutPin(cc60Out, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cc61_Out *cc61Out = pins->cc61Out;
|
||||
|
||||
if (cc61Out != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc61OutPin(cc61Out, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cc62_Out *cc62Out = pins->cc62Out;
|
||||
|
||||
if (cc62Out != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc62OutPin(cc62Out, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cout60_Out *cout60 = pins->cout60;
|
||||
|
||||
if (cout60 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout60Pin(cout60, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cout61_Out *cout61 = pins->cout61;
|
||||
|
||||
if (cout61 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout61Pin(cout61, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cout62_Out *cout62 = pins->cout62;
|
||||
|
||||
if (cout62 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout62Pin(cout62, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cout63_Out *cout63 = pins->cout63;
|
||||
|
||||
if (cout63 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout63Pin(cout63, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
// hall sensor input pins
|
||||
|
||||
IfxCcu6_Ccpos0_In *ccpos0 = pins->ccpos0;
|
||||
|
||||
if (ccpos0 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCcpos0Pin(ccpos0, pins->inputMode);
|
||||
}
|
||||
|
||||
IfxCcu6_Ccpos1_In *ccpos1 = pins->ccpos1;
|
||||
|
||||
if (ccpos1 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCcpos1Pin(ccpos1, pins->inputMode);
|
||||
}
|
||||
|
||||
IfxCcu6_Ccpos2_In *ccpos2 = pins->ccpos2;
|
||||
|
||||
if (ccpos2 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCcpos2Pin(ccpos2, pins->inputMode);
|
||||
}
|
||||
|
||||
IfxCcu6_T12hr_In *t12hr = pins->t12hr;
|
||||
|
||||
if (t12hr != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initT12hrPin(t12hr, pins->t1xhrInputMode);
|
||||
}
|
||||
|
||||
IfxCcu6_T13hr_In *t13hr = pins->t13hr;
|
||||
|
||||
if (t13hr != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initT13hrPin(t13hr, pins->t1xhrInputMode);
|
||||
}
|
||||
}
|
||||
|
||||
/* -- hall pattern configuration (when to start the hall pattern evaluation) -- */
|
||||
|
||||
IfxCcu6_setHallSensorTriggerMode(ccu6SFR, config->hallSyncEvent);
|
||||
|
||||
/* -- interrupt initialisation -- */
|
||||
|
||||
if (config->interrupt1.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt1.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt1.source, config->interrupt1.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt1.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt1.typeOfService, config->interrupt1.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt2.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt2.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt2.source, config->interrupt2.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt2.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt2.typeOfService, config->interrupt2.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt3.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt3.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt3.source, config->interrupt3.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt3.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt3.typeOfService, config->interrupt3.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt4.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt4.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt4.source, config->interrupt4.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt4.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt4.typeOfService, config->interrupt4.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
/* -- output trigger initialisation --*/
|
||||
|
||||
if (config->trigger.outputTriggerEnabled)
|
||||
{
|
||||
IfxCcu6_connectTrigger(ccu6SFR, config->trigger.outputLine, config->trigger.outputTrigger);
|
||||
}
|
||||
|
||||
pwmBc->trigger = config->trigger;
|
||||
pwmBc->hallPatternIndex = 0;
|
||||
|
||||
#if IFX_CFG_USE_STANDARD_INTERFACE
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (uint32)pwmBc == ((uint32)&pwmBc->base));
|
||||
pwmBc->base.functions.start = (PwmBc_Start) & IfxCcu6_PwmBc_start;
|
||||
pwmBc->base.functions.stop = (PwmBc_Stop) & IfxCcu6_PwmBc_stop;
|
||||
pwmBc->base.functions.updateHallPattern = (PwmBc_UpdateHallPattern) & IfxCcu6_PwmBc_updateHallPattern;
|
||||
pwmBc->base.functions.getMotorSpeed = (PwmBc_GetMotorSpeed) & IfxCcu6_PwmBc_getMotorSpeed;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_PwmBc_initModuleConfig(IfxCcu6_PwmBc_Config *config, Ifx_CCU6 *ccu6)
|
||||
{
|
||||
const IfxCcu6_PwmBc_Config defaultConfig = {
|
||||
.base = {
|
||||
.t12Frequency = 400000,
|
||||
.t12Period = 100,
|
||||
.t13Frequency = 400000,
|
||||
.t13Period = 100,
|
||||
.phaseDelay = 20,
|
||||
.noiseFilter = 10,
|
||||
.activeState = Ifx_ActiveState_high,
|
||||
},
|
||||
|
||||
.ccu6 = NULL_PTR, // will be initialized below
|
||||
|
||||
.timer12 = {
|
||||
.countMode = IfxCcu6_T12CountMode_edgeAligned,
|
||||
.counterValue = 0,
|
||||
},
|
||||
|
||||
.timer13 = {
|
||||
.counterValue = 0,
|
||||
.compareValue = 0,
|
||||
.t12SyncEvent = IfxCcu6_T13TriggerEvent_noAction,
|
||||
.t12SyncDirection = IfxCcu6_T13TriggerDirection_noAction,
|
||||
},
|
||||
|
||||
.hallSyncEvent = IfxCcu6_HallSensorTriggerMode_t13PM,
|
||||
|
||||
.hallPatternIndex = 0,
|
||||
|
||||
.multiChannelControl = {
|
||||
.switchingSelect = IfxCcu6_MultiChannelSwitchingSelect_t12Channel1CompareMatch,
|
||||
.switchingSync = IfxCcu6_MultiChannelSwitchingSync_t13ZeroMatch,
|
||||
},
|
||||
|
||||
.pins = NULL_PTR,
|
||||
|
||||
.interrupt1 = {
|
||||
.source = IfxCcu6_InterruptSource_t12PeriodMatch,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_0,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.interrupt2 = {
|
||||
.source = IfxCcu6_InterruptSource_t13PeriodMatch,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_1,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.interrupt3 = {
|
||||
.source = IfxCcu6_InterruptSource_t12OneMatch,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_2,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.interrupt4 = {
|
||||
.source = IfxCcu6_InterruptSource_trap,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_3,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.trigger = {
|
||||
.t12ExtInputTrigger = NULL_PTR,
|
||||
.t12ExtInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge,
|
||||
.t13ExtInputTrigger = NULL_PTR,
|
||||
.t13ExtInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge,
|
||||
.t13InSyncWithT12 = FALSE,
|
||||
|
||||
.outputTriggerEnabled = TRUE,
|
||||
.outputLine = IfxCcu6_TrigOut_0,
|
||||
.outputTrigger = IfxCcu6_TrigSel_cout63,
|
||||
},
|
||||
};
|
||||
|
||||
/* Default Configuration */
|
||||
*config = defaultConfig;
|
||||
|
||||
/* take over module pointer */
|
||||
config->ccu6 = ccu6;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_PwmBc_start(IfxCcu6_PwmBc *pwmBc)
|
||||
{
|
||||
// enable shadow transfers
|
||||
IfxCcu6_enableShadowTransfer(pwmBc->ccu6, TRUE, TRUE);
|
||||
|
||||
// internal start
|
||||
if ((pwmBc->trigger.t13ExtInputTrigger == NULL_PTR) && (pwmBc->trigger.t12ExtInputTrigger == NULL_PTR))
|
||||
{
|
||||
// if T13 start is in sync with T12 start the T12
|
||||
if (pwmBc->trigger.t13InSyncWithT12)
|
||||
{
|
||||
IfxCcu6_startTimer(pwmBc->ccu6, TRUE, FALSE);
|
||||
}
|
||||
else // start both timers
|
||||
{
|
||||
IfxCcu6_startTimer(pwmBc->ccu6, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// external start
|
||||
else
|
||||
{
|
||||
// if T13 start is not in sync with T12
|
||||
if (!(pwmBc->trigger.t13InSyncWithT12))
|
||||
{
|
||||
// T13 external start if selected
|
||||
if (pwmBc->trigger.t13ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setExternalRunMode(pwmBc->ccu6, IfxCcu6_TimerId_t13, pwmBc->trigger.t13ExtInputTriggerMode);
|
||||
IfxCcu6_setT13InputSignal(pwmBc->ccu6, pwmBc->trigger.t13ExtInputTrigger);
|
||||
}
|
||||
else // internal start of T13 alone
|
||||
{
|
||||
IfxCcu6_startTimer(pwmBc->ccu6, FALSE, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
// T12 external start if selected
|
||||
if (pwmBc->trigger.t12ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setExternalRunMode(pwmBc->ccu6, IfxCcu6_TimerId_t12, pwmBc->trigger.t12ExtInputTriggerMode);
|
||||
IfxCcu6_setT12InputSignal(pwmBc->ccu6, pwmBc->trigger.t12ExtInputTrigger);
|
||||
}
|
||||
else // internal start of T12 alone
|
||||
{
|
||||
IfxCcu6_startTimer(pwmBc->ccu6, TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_PwmBc_stop(IfxCcu6_PwmBc *pwmBc)
|
||||
{
|
||||
IfxCcu6_disableShadowTransfer(pwmBc->ccu6, TRUE, TRUE);
|
||||
|
||||
// if T13 start is in sync with T12, remove sync trigger
|
||||
if (pwmBc->trigger.t13InSyncWithT12)
|
||||
{
|
||||
IfxCcu6_setT13TriggerEventMode(pwmBc->ccu6, IfxCcu6_T13TriggerEvent_noAction);
|
||||
IfxCcu6_setT13TriggerEventDirection(pwmBc->ccu6, IfxCcu6_T13TriggerDirection_noAction);
|
||||
}
|
||||
|
||||
// remove external triggers if any
|
||||
if ((pwmBc->trigger.t13ExtInputTrigger != NULL_PTR) || (pwmBc->trigger.t12ExtInputTrigger != NULL_PTR))
|
||||
{
|
||||
if (pwmBc->trigger.t13ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setExternalRunMode(pwmBc->ccu6, IfxCcu6_TimerId_t13, IfxCcu6_ExternalTriggerMode_disable);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxCcu6_setExternalRunMode(pwmBc->ccu6, IfxCcu6_TimerId_t12, IfxCcu6_ExternalTriggerMode_disable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
// stop both timers
|
||||
IfxCcu6_stopTimer(pwmBc->ccu6, TRUE, TRUE);
|
||||
|
||||
//disable Timer13 modulation output path for all T12 channel outs//
|
||||
|
||||
IfxCcu6_disableModulationOutput(pwmBc->ccu6, IfxCcu6_TimerId_t13, IfxCcu6_ChannelOut_cc0);
|
||||
IfxCcu6_disableModulationOutput(pwmBc->ccu6, IfxCcu6_TimerId_t13, IfxCcu6_ChannelOut_cc1);
|
||||
IfxCcu6_disableModulationOutput(pwmBc->ccu6, IfxCcu6_TimerId_t13, IfxCcu6_ChannelOut_cc2);
|
||||
IfxCcu6_disableModulationOutput(pwmBc->ccu6, IfxCcu6_TimerId_t13, IfxCcu6_ChannelOut_cout3);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_PwmBc_updateHallPattern(IfxCcu6_PwmBc *pwmBc, uint8 controlTable[6][3])
|
||||
{
|
||||
uint8 index = pwmBc->hallPatternIndex;
|
||||
|
||||
IfxCcu6_updateHallPattern(pwmBc->ccu6, controlTable[index][0], controlTable[index][1], controlTable[index][2]);
|
||||
|
||||
index++;
|
||||
|
||||
if (index >= 6)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
pwmBc->hallPatternIndex = index;
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
/**
|
||||
* \file IfxCcu6_PwmBc.h
|
||||
* \brief CCU6 PWMBC details
|
||||
* \ingroup IfxLld_Ccu6
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_PwmBc_Usage How to use the CCU6 PWMBC Interface driver?
|
||||
* \ingroup IfxLld_Ccu6_PwmBc
|
||||
*
|
||||
* The PWMBC interface driver provides a default CCU6 configuration specifically for running a Brush Less DC Motor using hall sensor inputs, by utilising both the timers
|
||||
*
|
||||
* After evaluating the hall input pattern at every T13 period match, new out pattern is given to the module after the phase delay at the T13 zero match
|
||||
*
|
||||
* User has to prepare the control table for the respective motor he/she is using,
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Ccu6_PwmBc_Preparation Preparation
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_PwmBc_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
* \code
|
||||
* #include <Ccu6/PwmBc/IfxCcu6_PwmBc.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_PwmBc_Variables Variables
|
||||
*
|
||||
* Declare the PWMBC handle and the motor control table as global variables in your C code:
|
||||
*
|
||||
* \code
|
||||
* // used globally
|
||||
* static IfxCcu6_PwmBc pwmBc;
|
||||
* // prepare the control table
|
||||
* uint8 controlTable[6][3] = {{1, 5, 17} ,
|
||||
* {2, 3, 36} ,
|
||||
* {3, 1, 6} ,
|
||||
* {4, 6, 18} ,
|
||||
* {5, 4, 24} ,
|
||||
* {6, 2, 9}};
|
||||
* // to store value of the speed
|
||||
* uint32 speed = 0;
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_PwmBc_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priority for the Interrrupt handler. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define IFX_INTPRIO_CCU6 1
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routine to your C code.
|
||||
* \code
|
||||
* IFX_INTERRUPT(ccu60ISR_PwmBc, 0, IFX_INTPRIO_CCU6)
|
||||
* {
|
||||
* //user code
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handlers in your initialisation function:
|
||||
* \code
|
||||
* // install interrupt handlers
|
||||
* IfxCpu_Irq_installInterruptHandler(&ccu60ISR_PwmBc, IFX_INTPRIO_CCU6);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_PwmBc_Init Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function. Here an example:
|
||||
*
|
||||
* \code
|
||||
* // create configuration
|
||||
* IfxCcu6_PwmBc_Config pwmBcConfig;
|
||||
* IfxCcu6_PwmBc_initModuleConfig(&pwmBcConfig, &MODULE_CCU60);
|
||||
*
|
||||
* // configure the frequencies of both the timers
|
||||
* pwmBcConfig.base.t12Frequency = 400000;
|
||||
* pwmBcConfig.base.t13Frequency = 400000;
|
||||
*
|
||||
* // configure the periods of both the timers
|
||||
* pwmBcConfig.base.t12Period = 100;
|
||||
* pwmBcConfig.base.t13Period = 100;
|
||||
*
|
||||
* // configure the phase delay and noise filter for hall input
|
||||
* pwmBcConfig.base.phaseDelay = 20;
|
||||
* pwmBcConfig.base.noiseFilter = 10;
|
||||
*
|
||||
* // select the active state of the output
|
||||
* pwmBcConfig.base.activeState = Ifx_ActiveState_high;
|
||||
*
|
||||
* // configure timer12
|
||||
* pwmBcConfig.timer12.countMode = IfxCcu6_T12CountMode_edgeAligned;
|
||||
* pwmBcConfig.timer12.counterValue = 0;
|
||||
*
|
||||
* // configure timer13
|
||||
* pwmBcConfig.timer13.counterValue = 0;
|
||||
* pwmBcConfig.timer13.compareValue = 100;
|
||||
* // configure the syncronisation, in case of sync start with T12
|
||||
* pwmBcConfig.timer13.t12SyncEvent = IfxCcu6_T13TriggerEvent_onCC60RCompare;
|
||||
* pwmBcConfig.timer13.t12SyncDirection = IfxCcu6_T13TriggerDirection_onT12CountingUp;
|
||||
*
|
||||
* // configure hall sync event that starts the hall input pattern evaluation
|
||||
* pwmBcConfig.hallSyncEvent = IfxCcu6_HallSensorTriggerMode_t13PM,
|
||||
*
|
||||
* // configure multi channel control
|
||||
* pwmBcConfig.multiChannelControl.switchingSelect = IfxCcu6_MultiChannelSwitchingSelect_t12Channel1CompareMatch,
|
||||
* pwmBcConfig.multiChannelControl.switchingSync = IfxCcu6_MultiChannelSwitchingSync_t13ZeroMatch,
|
||||
*
|
||||
* // pin configuration
|
||||
* const IfxCcu6_PwmBc_Pins pins = {
|
||||
* IfxCcu60_CC60_P02_0_OUT, // CC60Out pin
|
||||
* IfxCcu60_CC61_P02_2_OUT, // CC61Out pin
|
||||
* IfxCcu60_CC62_P02_4_OUT, // CC62Out pin
|
||||
* IfxCcu60_COUT60_P02_1_OUT, // COUT60 pin
|
||||
* IfxCcu60_COUT60_P02_3_OUT, // COUT61 pin
|
||||
* IfxCcu60_COUT60_P02_5_OUT, // COUT62 pin
|
||||
* NULL, // COUT63 pin not used
|
||||
*
|
||||
* IfxCcu60_COUT60_P02_6_OUT // CCPOS0In pin
|
||||
* IfxCcu60_COUT60_P02_7_OUT // CCPOS1In pin
|
||||
* IfxCcu60_COUT60_P02_8_OUT // CCPOS2In pin
|
||||
*
|
||||
* IfxPort_OutputMode_pushPull,
|
||||
* IfxPort_PadDriver_cmosAutomotiveSpeed1,
|
||||
* IfxPort_InputMode_pullUp
|
||||
* };
|
||||
* pwmBcConfig.pins = &pins;
|
||||
*
|
||||
* // configure the interrupts
|
||||
* pwmBcConfig.interrupt1.interruptSource = IfxCcu6_InterruptSource_cc61FallingEdge;
|
||||
* pwmBcConfig.interrupt1.serviceRequest = IfxCcu6_ServiceRequest_2;
|
||||
* pwmBcConfig.interrupt1.priority = IFX_INTRPRIO_CCU6;
|
||||
* pwmBcConfig.interrupt1.typeOfService = IfxSrc_Tos_cpu0;
|
||||
*
|
||||
* // configure input and output triggers
|
||||
* pwmBcConfig.trigger.t12ExtInputTrigger = NULL_PTR;
|
||||
* pwmBcConfig.trigger.t12ExtInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge;
|
||||
* pwmBcConfig.trigger.t13ExtInputTrigger = NULL_PTR;
|
||||
* pwmBcConfig.trigger.t13ExtInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge;
|
||||
* pwmBcConfig.trigger.t13InSyncWithT12 = FALSE;
|
||||
*
|
||||
* pwmBcConfig.trigger.outputTriggerEnabled = TRUE;
|
||||
* pwmBcConfig.trigger.outputLine = IfxCcu6_TrigOut_0;
|
||||
* pwmBcConfig.trigger.outputTrigger = IfxCcu6_TrigSel_cout63;
|
||||
*
|
||||
*
|
||||
* // initialize the module
|
||||
* IfxCcu6_PwmBc_initModule(&pwmBc, &pwmBcConfig);
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* The PwmBc is ready for use now!
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Ccu6_PwmBc_ModulationControl Modulation Control
|
||||
*
|
||||
*
|
||||
* The PWMBC driver provides simple to use Motor Control functions
|
||||
*
|
||||
* This means: you can start, stop, the BLDC motor once the module is initialised with the appropriate configuration
|
||||
* You can optionally get the speed of the motor at any point of time
|
||||
*
|
||||
* Start the motor
|
||||
*
|
||||
* \code
|
||||
* IfxCcu6_PwmBc_start(&pwmBc);
|
||||
* \endcode
|
||||
*
|
||||
* Stop the motor
|
||||
*
|
||||
* \code
|
||||
* IfxCcu6_PwmBc_stop(&pwmBc);
|
||||
* \endcode
|
||||
*
|
||||
* Update the output pattern
|
||||
*
|
||||
* \code
|
||||
* // prepare the control table
|
||||
* // assumed to be declared globally
|
||||
* uint8 controlTable[6][3] = {{1, 5, 17} ,
|
||||
* {2, 3, 36} ,
|
||||
* {3, 1, 6} ,
|
||||
* {4, 6, 18} ,
|
||||
* {5, 4, 24} ,
|
||||
* {6, 2, 9}};
|
||||
*
|
||||
* // update the output pattern
|
||||
* IfxCcu6_PwmBc_updateHallPattern(&pwmBc, controlTable[6][3]);
|
||||
* \endcode
|
||||
*
|
||||
* Get the current motor speed
|
||||
* (can also be called in ISR)
|
||||
*
|
||||
* \code
|
||||
* // assumed to be declared globally
|
||||
* uint32 speed = 0;
|
||||
*
|
||||
* // get the current motor speed
|
||||
* speed = IfxCcu6_PwmBc_getMotorSpeed(&pwmBc);
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_PwmBc PWMBC Interface driver
|
||||
* \ingroup IfxLld_Ccu6
|
||||
* \defgroup IfxLld_Ccu6_PwmBc_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Ccu6_PwmBc
|
||||
* \defgroup IfxLld_Ccu6_PwmBc_Module_Initialize_Functions Module Initialize Functions
|
||||
* \ingroup IfxLld_Ccu6_PwmBc
|
||||
* \defgroup IfxLld_Ccu6_PwmBc_Modulation_Control_Functions Modulation Control Functions
|
||||
* \ingroup IfxLld_Ccu6_PwmBc
|
||||
* \defgroup IfxLld_Ccu6_PwmBc_Hall_Pattern_Functions Hall Pattern Functions
|
||||
* \ingroup IfxLld_Ccu6_PwmBc
|
||||
*/
|
||||
|
||||
#ifndef IFXCCU6_PWMBC_H
|
||||
#define IFXCCU6_PWMBC_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Ccu6/Std/IfxCcu6.h"
|
||||
#include "If/Ccu6If/PwmHl.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmBc_DataStructures
|
||||
* \{ */
|
||||
/** \brief Structure for interrupt configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_InterruptSource source; /**< \brief Interrupt source selection */
|
||||
IfxCcu6_ServiceRequest serviceRequest; /**< \brief Selection of service request outputs */
|
||||
uint16 priority; /**< \brief Interrupt priority */
|
||||
IfxSrc_Tos typeOfService; /**< \brief type of interrupt service */
|
||||
} IfxCcu6_PwmBc_InterruptConfig;
|
||||
|
||||
/** \brief Structure for multichannel mode control
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_MultiChannelSwitchingSelect switchingSelect; /**< \brief Trigger request source (next multi-channel event) for the shadow transfer MCM_ST from MCMPS to MCMP */
|
||||
IfxCcu6_MultiChannelSwitchingSync switchingSync; /**< \brief Synchronization selection for the shadow transfer event MCM_ST */
|
||||
} IfxCcu6_PwmBc_MultiChannelControl;
|
||||
|
||||
/** \brief Structure for CCU6 output pin configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IFX_CONST IfxCcu6_Cc60_Out *cc60Out; /**< \brief CC60 compare output CC0 */
|
||||
IFX_CONST IfxCcu6_Cc61_Out *cc61Out; /**< \brief CC61 compare output CC1 */
|
||||
IFX_CONST IfxCcu6_Cc62_Out *cc62Out; /**< \brief CC62 compare output CC2 */
|
||||
IFX_CONST IfxCcu6_Cout60_Out *cout60; /**< \brief CC60 compare output COUT0 */
|
||||
IFX_CONST IfxCcu6_Cout61_Out *cout61; /**< \brief CC61 compare output COUT1 */
|
||||
IFX_CONST IfxCcu6_Cout62_Out *cout62; /**< \brief CC62 compare output COUT2 */
|
||||
IFX_CONST IfxCcu6_Cout63_Out *cout63; /**< \brief CC63 compare output COUT3 */
|
||||
IFX_CONST IfxCcu6_Ccpos0_In *ccpos0; /**< \brief CCPOS0 input signal */
|
||||
IFX_CONST IfxCcu6_Ccpos1_In *ccpos1; /**< \brief CCPOS2 input signal */
|
||||
IFX_CONST IfxCcu6_Ccpos2_In *ccpos2; /**< \brief CCPOS2 input signal */
|
||||
IfxPort_OutputMode outputMode; /**< \brief The pin output mode which should be configured */
|
||||
IfxPort_PadDriver pinDriver; /**< \brief pad driver */
|
||||
IfxPort_InputMode inputMode; /**< \brief The CCPOSx pin input mode which should be configured */
|
||||
IFX_CONST IfxCcu6_T12hr_In *t12hr; /**< \brief T12HR input signal */
|
||||
IFX_CONST IfxCcu6_T13hr_In *t13hr; /**< \brief T13HR input signal */
|
||||
IfxPort_InputMode t1xhrInputMode; /**< \brief The T1xHR pin input mode which should be configured */
|
||||
} IfxCcu6_PwmBc_Pins;
|
||||
|
||||
/** \brief Structure for Timer 12
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_T12CountMode countMode; /**< \brief Operating mode of Timer 12 */
|
||||
uint16 counterValue; /**< \brief 16-bit counter value of Timer12 */
|
||||
} IfxCcu6_PwmBc_Timer12;
|
||||
|
||||
/** \brief Structure for Timer 13
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 counterValue; /**< \brief 16-bit counter value of Timer13 */
|
||||
uint16 compareValue; /**< \brief 16-bit comapre value of Timer12 */
|
||||
IfxCcu6_T13TriggerEvent t12SyncEvent; /**< \brief T12 sync trigger event to start T13 */
|
||||
IfxCcu6_T13TriggerDirection t12SyncDirection; /**< \brief Additional information to control trigger event selection */
|
||||
} IfxCcu6_PwmBc_Timer13;
|
||||
|
||||
/** \brief Configuration structure for external triggers
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_T12hr_In *t12ExtInputTrigger; /**< \brief External input signal selection for timer 12 */
|
||||
IfxCcu6_ExternalTriggerMode t12ExtInputTriggerMode; /**< \brief Event of signal T12HR that can set the run bit T12R by HW */
|
||||
IfxCcu6_T13hr_In *t13ExtInputTrigger; /**< \brief External input signal selection for timer 13 */
|
||||
IfxCcu6_ExternalTriggerMode t13ExtInputTriggerMode; /**< \brief Event of signal T13HR that can set the run bit T13R by HW */
|
||||
boolean t13InSyncWithT12; /**< \brief Selection of Timer 13 start in sync with T12 */
|
||||
boolean outputTriggerEnabled; /**< \brief Output trigger connection to VADC enable / disable choice */
|
||||
IfxCcu6_TrigOut outputLine; /**< \brief Trigger out selection */
|
||||
IfxCcu6_TrigSel outputTrigger; /**< \brief Trigger selection */
|
||||
} IfxCcu6_PwmBc_TriggerConfig;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmBc_DataStructures
|
||||
* \{ */
|
||||
/** \brief Module handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
PwmHl base; /**< \brief Base PWMHL object */
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
IfxCcu6_PwmBc_TriggerConfig trigger; /**< \brief Structure for trigger configuration */
|
||||
uint8 hallPatternIndex; /**< \brief Hall pattern index of motor control table */
|
||||
} IfxCcu6_PwmBc;
|
||||
|
||||
/** \brief Configuration structure of the module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
PwmHl_Config base; /**< \brief Base configuration */
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
IfxCcu6_PwmBc_Timer12 timer12; /**< \brief Structure for Timer 12 */
|
||||
IfxCcu6_PwmBc_Timer13 timer13; /**< \brief Structure for Timer 13 */
|
||||
uint8 hallPatternIndex; /**< \brief Hall pattern index of motor control table */
|
||||
IfxCcu6_HallSensorTriggerMode hallSyncEvent; /**< \brief Hall pattern evaluation trigger selection (HSYNC) */
|
||||
IfxCcu6_PwmBc_MultiChannelControl multiChannelControl; /**< \brief Structure for multichannel mode control */
|
||||
IfxCcu6_PwmBc_Pins *pins; /**< \brief Structure for CCU6 output pin configuration */
|
||||
IfxCcu6_PwmBc_InterruptConfig interrupt1; /**< \brief Structure for first interrupt configuration */
|
||||
IfxCcu6_PwmBc_InterruptConfig interrupt2; /**< \brief Structure for second interrupt configuration */
|
||||
IfxCcu6_PwmBc_InterruptConfig interrupt3; /**< \brief Structure for third interrupt configuration */
|
||||
IfxCcu6_PwmBc_InterruptConfig interrupt4; /**< \brief Structure for fourth interrupt configuration */
|
||||
IfxCcu6_PwmBc_TriggerConfig trigger; /**< \brief Structure for trigger configuration */
|
||||
} IfxCcu6_PwmBc_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmBc_Module_Initialize_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialises the module with default configuration
|
||||
* \param pwmBc Module handle
|
||||
* \param config Configuration structure of the module
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_PwmBc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_PwmBc_initModule(IfxCcu6_PwmBc *pwmBc, const IfxCcu6_PwmBc_Config *config);
|
||||
|
||||
/** \brief Fills the config structure with default values
|
||||
* \param config Configuration structure of the module
|
||||
* \param ccu6 Pointer to the base of CCU6 registers
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_PwmBc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_PwmBc_initModuleConfig(IfxCcu6_PwmBc_Config *config, Ifx_CCU6 *ccu6);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmBc_Modulation_Control_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Starts the Hall sensored based PWM
|
||||
* \param pwmBc Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_PwmBc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_PwmBc_start(IfxCcu6_PwmBc *pwmBc);
|
||||
|
||||
/** \brief Stops the Hall sensored based PWM
|
||||
* \param pwmBc Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_PwmBc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_PwmBc_stop(IfxCcu6_PwmBc *pwmBc);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmBc_Hall_Pattern_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief returns the current motor speed
|
||||
* \param pwmBc Module handle
|
||||
* \return speed
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_PwmBc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxCcu6_PwmBc_getMotorSpeed(IfxCcu6_PwmBc *pwmBc);
|
||||
|
||||
/** \brief Updates the Hall pattern
|
||||
* \param pwmBc Module handle
|
||||
* \param controlTable Motor Control table
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_PwmBc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_PwmBc_updateHallPattern(IfxCcu6_PwmBc * pwmBc, uint8 controlTable[6][3]);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXCCU6_PWMBC_H */
|
||||
@@ -0,0 +1,520 @@
|
||||
/**
|
||||
* \file IfxCcu6_PwmHl.c
|
||||
* \brief CCU6 PWMHL details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxCcu6_PwmHl.h"
|
||||
#include "_Utilities/Ifx_Assert.h"
|
||||
#include "stddef.h"
|
||||
#include "string.h"
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmHl_StdIf_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Turn-off the complementary PWM generation mode.
|
||||
*
|
||||
* \note The changes are not applied until Timer->applyUpdate() is called.
|
||||
* \note This function will set the ON time to ZERO, overriding previous call to
|
||||
* IfxCcu6_PwmHl_setOnTime().
|
||||
* \note This function will disable PWM in all channels, overriding previous call to
|
||||
* IfxCcu6_PwmHl_setupChannels().
|
||||
* \param driver CCU6 PWM driver
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCcu6_PwmHl_disable(IfxCcu6_PwmHl *driver);
|
||||
|
||||
/** \brief Turn-on the complementary PWM generation mode.
|
||||
*
|
||||
* \note The changes are not applied until Timer->applyUpdate() is called.
|
||||
* \note This function will disable PWM in all channels, overriding previous call to
|
||||
* IfxCcu6_PwmHl_setupChannels().
|
||||
* \param driver CCU6 PWM driver
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCcu6_PwmHl_enable(IfxCcu6_PwmHl *driver);
|
||||
|
||||
/** \brief Sets up the output pins
|
||||
* \param module Pointer to register base
|
||||
* \param config CCU6 : PWM HL configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCcu6_PwmHl_setOutputPins(Ifx_CCU6 *module, const IfxCcu6_PwmHl_Config *config);
|
||||
|
||||
/** \brief Updates the x output duty cycle in center aligned and center aligned inverted modes
|
||||
* \param driver CCU6 PWM driver
|
||||
* \param tOn T on
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCcu6_PwmHl_updateCenterAligned(IfxCcu6_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
/** \brief Updates the x output duty cycle in edge aligned modes (left and right aligned)
|
||||
* \param driver CCU6 PWM driver
|
||||
* \param tOn T on
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCcu6_PwmHl_updateEdgeAligned(IfxCcu6_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
/** \brief Set the outputs to inactive
|
||||
* \param driver CCU6 PWM driver
|
||||
* \param tOn T on
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCcu6_PwmHl_updateOff(IfxCcu6_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*------------------------Private Variables/Constants-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_STATIC IFX_CONST IfxCcu6_PwmHl_Mode IfxCcu6_PwmHl_modes[Ifx_Pwm_Mode_off + 1] = {
|
||||
{Ifx_Pwm_Mode_centerAligned, FALSE, &IfxCcu6_PwmHl_updateCenterAligned},
|
||||
{Ifx_Pwm_Mode_centerAlignedInverted, TRUE, &IfxCcu6_PwmHl_updateCenterAligned},
|
||||
{Ifx_Pwm_Mode_leftAligned, FALSE, &IfxCcu6_PwmHl_updateEdgeAligned },
|
||||
{Ifx_Pwm_Mode_rightAligned, TRUE, &IfxCcu6_PwmHl_updateEdgeAligned },
|
||||
{Ifx_Pwm_Mode_off, FALSE, &IfxCcu6_PwmHl_updateOff }
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_STATIC void IfxCcu6_PwmHl_disable(IfxCcu6_PwmHl *driver)
|
||||
{
|
||||
IfxCcu6_TimerWithTrigger *timer = driver->timer;
|
||||
Ifx_CCU6 *module = timer->ccu6;
|
||||
Ifx_CCU6_CMPSTAT cmpstat;
|
||||
|
||||
Ifx_TimerValue tOn[3] = {0, 0, 0};
|
||||
IfxCcu6_PwmHl_setOnTime(driver, tOn);
|
||||
|
||||
/** - All TOP and BOTTOM channel (COUTx) states equals CC6xST */
|
||||
cmpstat.U = 0;
|
||||
//cmpstat.B.T13IM = 0;
|
||||
//cmpstat.B.COUT63PS = 0;
|
||||
//cmpstat.B.CC60PS = 0;
|
||||
//cmpstat.B.CC61PS = 0;
|
||||
//cmpstat.B.CC62PS = 0;
|
||||
//cmpstat.B.COUT60PS = 0;
|
||||
//cmpstat.B.COUT61PS = 0;
|
||||
//cmpstat.B.COUT62PS = 0;
|
||||
module->CMPSTAT.U = cmpstat.U;
|
||||
|
||||
{
|
||||
/* set all into stuck-states */
|
||||
//boolean active[6] = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE};
|
||||
boolean active[6] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
|
||||
boolean stuckState[6] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
|
||||
IfxCcu6_PwmHl_setupChannels(driver, active, stuckState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCcu6_PwmHl_enable(IfxCcu6_PwmHl *driver)
|
||||
{
|
||||
IfxCcu6_TimerWithTrigger *timer = (IfxCcu6_TimerWithTrigger *)driver->timer;
|
||||
Ifx_CCU6 *module = timer->ccu6;
|
||||
/** - All TOP and BOTTOM channel (COUTx) states equals CC6xST */
|
||||
Ifx_CCU6_CMPSTAT cmpstat;
|
||||
cmpstat.U = 0;
|
||||
//cmpstat.B.T13IM = 0;
|
||||
//cmpstat.B.COUT63PS = 0;
|
||||
//cmpstat.B.CC60PS = 0;
|
||||
//cmpstat.B.CC61PS = 0;
|
||||
//cmpstat.B.CC62PS = 0;
|
||||
cmpstat.B.COUT60PS = 1;
|
||||
cmpstat.B.COUT61PS = 1;
|
||||
cmpstat.B.COUT62PS = 1;
|
||||
|
||||
module->CMPSTAT.U = cmpstat.U;
|
||||
{
|
||||
/* set all into non stuck-states */
|
||||
boolean active[6] = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE};
|
||||
boolean stuckState[6] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
|
||||
IfxCcu6_PwmHl_setupChannels(driver, active, stuckState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float32 IfxCcu6_PwmHl_getDeadtime(IfxCcu6_PwmHl *driver)
|
||||
{
|
||||
return IfxStdIf_Timer_tickToS(driver->timer->base.clockFreq, driver->base.deadtime);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxCcu6_PwmHl_getMinPulse(IfxCcu6_PwmHl *driver)
|
||||
{
|
||||
return IfxStdIf_Timer_tickToS(driver->timer->base.clockFreq, driver->base.minPulse - driver->base.deadtime);
|
||||
}
|
||||
|
||||
|
||||
Ifx_Pwm_Mode IfxCcu6_PwmHl_getMode(IfxCcu6_PwmHl *driver)
|
||||
{
|
||||
return driver->base.mode;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_PwmHl_init(IfxCcu6_PwmHl *driver, const IfxCcu6_PwmHl_Config *config)
|
||||
{
|
||||
boolean result = TRUE;
|
||||
|
||||
IfxCcu6_TimerWithTrigger *timer = config->timer;
|
||||
Ifx_CCU6 *module = timer->ccu6;
|
||||
|
||||
driver->base.mode = Ifx_Pwm_Mode_init;
|
||||
driver->timer = timer;
|
||||
driver->base.setMode = 0;
|
||||
driver->base.inverted = FALSE;
|
||||
driver->base.ccxActiveState = config->base.ccxActiveState;
|
||||
driver->base.coutxActiveState = config->base.coutxActiveState;
|
||||
|
||||
driver->base.channelCount = __minu(config->base.channelCount, IFXCCU6_PWMHL_MAX_CHANNELS);
|
||||
|
||||
IfxCcu6_PwmHl_setDeadtime(driver, config->base.deadtime);
|
||||
IfxCcu6_PwmHl_setMinPulse(driver, config->base.minPulse);
|
||||
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->base.channelCount == IFXCCU6_PWMHL_MAX_CHANNELS);
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->timer->base.countDir == IfxStdIf_Timer_CountDir_upAndDown);
|
||||
|
||||
unsigned int passiveState;
|
||||
Ifx_CCU6_PSLR pslr;
|
||||
Ifx_CCU6_MODCTR modctr;
|
||||
Ifx_CCU6_MCMOUTS mcmouts;
|
||||
Ifx_CCU6_MCMCTR mcmctr;
|
||||
|
||||
/** - All T12 channels (0,1,2) are set in compare mode */
|
||||
|
||||
IfxCcu6_setT12ChannelMode(module, IfxCcu6_T12Channel_0, IfxCcu6_T12ChannelMode_compareMode);
|
||||
IfxCcu6_setT12ChannelMode(module, IfxCcu6_T12Channel_1, IfxCcu6_T12ChannelMode_compareMode);
|
||||
IfxCcu6_setT12ChannelMode(module, IfxCcu6_T12Channel_2, IfxCcu6_T12ChannelMode_compareMode);
|
||||
|
||||
/** - Enable T12 modulation mode */
|
||||
modctr.U = module->MODCTR.U;
|
||||
modctr.B.MCMEN = 1;
|
||||
modctr.B.T12MODEN = 0x3FU;
|
||||
module->MODCTR.U = modctr.U;
|
||||
|
||||
IfxCcu6_setMultiChannelSwitchingMode(module, IfxCcu6_MultiChannelSwitchingSelect_t12PeriodMatch);
|
||||
|
||||
IfxCcu6_setMultiChannelSwitchingSync(module, IfxCcu6_MultiChannelSwitchingSync_t12ZeroMatch);
|
||||
|
||||
mcmctr.U = module->MCMCTR.U;
|
||||
mcmctr.B.STE12D = FALSE;
|
||||
mcmctr.B.STE12U = FALSE;
|
||||
mcmctr.B.STE13U = FALSE;
|
||||
module->MCMCTR.U = mcmctr.U;
|
||||
|
||||
IfxCcu6_enableDeadTime(module, IfxCcu6_T12Channel_0);
|
||||
IfxCcu6_enableDeadTime(module, IfxCcu6_T12Channel_1);
|
||||
IfxCcu6_enableDeadTime(module, IfxCcu6_T12Channel_2);
|
||||
|
||||
/* Configure the passive state */
|
||||
pslr.B.PSL = 0;
|
||||
passiveState = (config->base.ccxActiveState == Ifx_ActiveState_high) ? 0 : 1;
|
||||
pslr.B.PSL |= (passiveState << 0);
|
||||
pslr.B.PSL |= (passiveState << 2);
|
||||
pslr.B.PSL |= (passiveState << 4);
|
||||
|
||||
passiveState = (config->base.coutxActiveState == Ifx_ActiveState_high) ? 0 : 1;
|
||||
pslr.B.PSL |= (passiveState << 1);
|
||||
pslr.B.PSL |= (passiveState << 3);
|
||||
pslr.B.PSL |= (passiveState << 5);
|
||||
|
||||
module->PSLR.B.PSL = pslr.B.PSL;
|
||||
|
||||
IfxCcu6_PwmHl_setMode(driver, Ifx_Pwm_Mode_off);
|
||||
|
||||
Ifx_TimerValue tOn[IFXCCU6_PWMHL_MAX_CHANNELS] = {0};
|
||||
IfxCcu6_PwmHl_updateOff(driver, tOn); /* tOn do not need defined values */
|
||||
|
||||
mcmouts.U = module->MCMOUTS.U;
|
||||
mcmouts.B.MCMPS = 0x3F;
|
||||
mcmouts.B.STRMCM = 1;
|
||||
module->MCMOUTS.U = mcmouts.U;
|
||||
|
||||
IfxCcu6_PwmHl_setOutputPins(module, config);
|
||||
|
||||
//config->base.emergencyEnabled;
|
||||
|
||||
/* Transfer the shadow registers */
|
||||
IfxCcu6_TimerWithTrigger_applyUpdate(driver->timer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_PwmHl_initConfig(IfxCcu6_PwmHl_Config *config)
|
||||
{
|
||||
IfxStdIf_PwmHl_initConfig(&config->base);
|
||||
config->timer = NULL_PTR;
|
||||
config->cc0 = NULL_PTR;
|
||||
config->cc1 = NULL_PTR;
|
||||
config->cc2 = NULL_PTR;
|
||||
config->cout0 = NULL_PTR;
|
||||
config->cout1 = NULL_PTR;
|
||||
config->cout2 = NULL_PTR;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_PwmHl_setDeadtime(IfxCcu6_PwmHl *driver, float32 deadtime)
|
||||
{
|
||||
Ifx_TimerValue value = IfxStdIf_Timer_sToTick(driver->timer->base.clockFreq, deadtime);
|
||||
|
||||
driver->base.deadtime = __minu(__minu(value, driver->timer->base.period / 2), 255);
|
||||
|
||||
IfxCcu6_setDeadTimeValue(driver->timer->ccu6, (uint8)driver->base.deadtime);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_PwmHl_setMinPulse(IfxCcu6_PwmHl *driver, float32 minPulse)
|
||||
{
|
||||
Ifx_TimerValue value = IfxStdIf_Timer_sToTick(driver->timer->base.clockFreq, minPulse);
|
||||
|
||||
driver->base.minPulse = value + driver->base.deadtime;
|
||||
driver->base.maxPulse = driver->timer->base.period - driver->base.minPulse;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_PwmHl_setMode(IfxCcu6_PwmHl *driver, Ifx_Pwm_Mode mode)
|
||||
{
|
||||
boolean result = TRUE;
|
||||
IfxCcu6_PwmHl_Base *base = &driver->base;
|
||||
|
||||
if (base->mode != mode)
|
||||
{
|
||||
if ((mode > Ifx_Pwm_Mode_off) || (IfxCcu6_PwmHl_modes[mode].update == NULL_PTR))
|
||||
{
|
||||
mode = Ifx_Pwm_Mode_off;
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mode == IfxCcu6_PwmHl_modes[mode].mode);
|
||||
|
||||
base->mode = mode;
|
||||
driver->update = IfxCcu6_PwmHl_modes[mode].update;
|
||||
|
||||
if (base->mode == Ifx_Pwm_Mode_off)
|
||||
{
|
||||
IfxCcu6_PwmHl_disable(driver);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxCcu6_PwmHl_enable(driver);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_PwmHl_setOnTime(IfxCcu6_PwmHl *driver, Ifx_TimerValue *tOn)
|
||||
{
|
||||
// Period = 12
|
||||
// Ton = 2
|
||||
// Center-aligned (the CCx equals CC6xST):
|
||||
// T12PR = (Period/2)-1
|
||||
// T12 = 0 1 2 3 4 5 6 5 4 3 2 1 0 1 2 3
|
||||
// CC6xR = (Period - Ton) / 2 = 5
|
||||
// CC6xST = 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
|
||||
// Right-aligned (the CCx equals CC6xST):
|
||||
// T12PR = (Period-1)
|
||||
// T12 = 0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3
|
||||
// CC6xR = (Period - Ton) = 10
|
||||
// CC6xST = 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
|
||||
// Left-aligned (the CCx equals ~CC6xST):
|
||||
// T12PR = (Period-1)
|
||||
// T12 = 0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3
|
||||
// CC6xR = Ton = 2
|
||||
// CC6xST = 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0
|
||||
IfxCcu6_TimerWithTrigger *timer = (IfxCcu6_TimerWithTrigger *)driver->timer;
|
||||
Ifx_CCU6 *module = timer->ccu6;
|
||||
int i;
|
||||
int channels = driver->base.channelCount;
|
||||
Ifx_TimerValue period = driver->timer->base.period;
|
||||
|
||||
for (i = 0; i < channels; i++)
|
||||
{
|
||||
Ifx_TimerValue cmp;
|
||||
Ifx_TimerValue tOnX = tOn[i];
|
||||
|
||||
if (tOnX < driver->base.minPulse)
|
||||
{
|
||||
tOnX = 0;
|
||||
}
|
||||
else if (tOnX > driver->base.maxPulse)
|
||||
{
|
||||
tOnX = period;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
cmp = (period - tOnX);
|
||||
cmp = cmp >> ((driver->base.mode == Ifx_Pwm_Mode_centerAligned) ? 1 : 0);
|
||||
IfxCcu6_setT12CompareValue(module, (IfxCcu6_T12Channel)i, (uint16)cmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCcu6_PwmHl_setOutputPins(Ifx_CCU6 *module, const IfxCcu6_PwmHl_Config *config)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(module->CLC.U != (uint32)0)
|
||||
|
||||
if (config->cc0 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc60OutPin(config->cc0, config->base.outputMode, config->base.outputDriver);
|
||||
}
|
||||
|
||||
if (config->cc1 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc61OutPin(config->cc1, config->base.outputMode, config->base.outputDriver);
|
||||
}
|
||||
|
||||
if (config->cc2 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc62OutPin(config->cc2, config->base.outputMode, config->base.outputDriver);
|
||||
}
|
||||
|
||||
if (config->cout0 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout60Pin(config->cout0, config->base.outputMode, config->base.outputDriver);
|
||||
}
|
||||
|
||||
if (config->cout1 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout61Pin(config->cout1, config->base.outputMode, config->base.outputDriver);
|
||||
}
|
||||
|
||||
if (config->cout2 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout62Pin(config->cout2, config->base.outputMode, config->base.outputDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_PwmHl_setupChannels(IfxCcu6_PwmHl *driver, boolean *activeCh, boolean *stuckSt)
|
||||
{
|
||||
IfxCcu6_TimerWithTrigger *timer = driver->timer;
|
||||
Ifx_CCU6 *module = timer->ccu6;
|
||||
{
|
||||
uint8 pattern;
|
||||
|
||||
pattern = 0;
|
||||
pattern |= ((activeCh[0] != FALSE) ? 1 : 0) << 0;
|
||||
pattern |= ((activeCh[1] != FALSE) ? 1 : 0) << 1;
|
||||
pattern |= ((activeCh[2] != FALSE) ? 1 : 0) << 2;
|
||||
pattern |= ((activeCh[3] != FALSE) ? 1 : 0) << 3;
|
||||
pattern |= ((activeCh[4] != FALSE) ? 1 : 0) << 4;
|
||||
pattern |= ((activeCh[5] != FALSE) ? 1 : 0) << 5;
|
||||
|
||||
IfxCcu6_setMultiChannelPwmPattern(module, pattern);
|
||||
}
|
||||
{
|
||||
Ifx_CCU6_PSLR pslr;
|
||||
pslr.U = module->PSLR.U;
|
||||
pslr.B.PSL = 0;
|
||||
|
||||
// top:
|
||||
pslr.B.PSL |= ((activeCh[0] == FALSE) ? ((stuckSt[0] == FALSE) ? 0 : 1) : 0) << 0;
|
||||
pslr.B.PSL |= ((activeCh[2] == FALSE) ? ((stuckSt[2] == FALSE) ? 0 : 1) : 0) << 2;
|
||||
pslr.B.PSL |= ((activeCh[4] == FALSE) ? ((stuckSt[4] == FALSE) ? 0 : 1) : 0) << 4;
|
||||
|
||||
// bottom:
|
||||
pslr.B.PSL |= ((activeCh[1] == FALSE) ? ((stuckSt[1] == FALSE) ? 0 : 1) : 0) << 1;
|
||||
pslr.B.PSL |= ((activeCh[3] == FALSE) ? ((stuckSt[3] == FALSE) ? 0 : 1) : 0) << 3;
|
||||
pslr.B.PSL |= ((activeCh[5] == FALSE) ? ((stuckSt[5] == FALSE) ? 0 : 1) : 0) << 5;
|
||||
module->PSLR.U = pslr.U;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_PwmHl_stdIfPwmHlInit(IfxStdIf_PwmHl *stdif, IfxCcu6_PwmHl *driver)
|
||||
{
|
||||
/* Ensure the stdif is reset to zeros */
|
||||
memset(stdif, 0, sizeof(IfxStdIf_PwmHl));
|
||||
|
||||
/* *INDENT-OFF* Note: this file was indented manually by the author. */
|
||||
/* Set the API link */
|
||||
stdif->driver = driver;
|
||||
stdif->setDeadtime = (IfxStdIf_PwmHl_SetDeadtime )&IfxCcu6_PwmHl_setDeadtime;
|
||||
stdif->getDeadtime = (IfxStdIf_PwmHl_GetDeadtime )&IfxCcu6_PwmHl_getDeadtime;
|
||||
stdif->setMinPulse = (IfxStdIf_PwmHl_SetMinPulse )&IfxCcu6_PwmHl_setMinPulse;
|
||||
stdif->getMinPulse = (IfxStdIf_PwmHl_GetMinPulse )&IfxCcu6_PwmHl_getMinPulse;
|
||||
stdif->getMode = (IfxStdIf_PwmHl_GetMode )&IfxCcu6_PwmHl_getMode;
|
||||
stdif->setMode = (IfxStdIf_PwmHl_SetMode )&IfxCcu6_PwmHl_setMode;
|
||||
stdif->setOnTime = (IfxStdIf_PwmHl_SetOnTime )&IfxCcu6_PwmHl_setOnTime;
|
||||
stdif->setupChannels = (IfxStdIf_PwmHl_SetupChannels)&IfxCcu6_PwmHl_setupChannels;
|
||||
IfxCcu6_TimerWithTrigger_stdIfTimerInit(&stdif->timer, driver->timer);
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCcu6_PwmHl_updateCenterAligned(IfxCcu6_PwmHl *driver, Ifx_TimerValue *tOn)
|
||||
{
|
||||
IfxCcu6_PwmHl_setOnTime(driver, tOn);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCcu6_PwmHl_updateEdgeAligned(IfxCcu6_PwmHl *driver, Ifx_TimerValue *tOn)
|
||||
{
|
||||
IfxCcu6_PwmHl_setOnTime(driver, tOn);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCcu6_PwmHl_updateOff(IfxCcu6_PwmHl *driver, Ifx_TimerValue *tOn)
|
||||
{
|
||||
/* Nothing to do */
|
||||
IFX_UNUSED_PARAMETER(driver)
|
||||
IFX_UNUSED_PARAMETER(tOn)
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* \file IfxCcu6_PwmHl.h
|
||||
* \brief CCU6 PWMHL details
|
||||
* \ingroup IfxLld_Ccu6
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_PwmHl_Usage How to use the CCU6 PWM Driver
|
||||
* \ingroup IfxLld_Ccu6_PwmHl
|
||||
*
|
||||
* This driver implements the PWM functionalities as defined by \ref library_srvsw_stdif_pwmhl.
|
||||
* The user is free to use either the driver specific APIs below or to used the \ref library_srvsw_stdif_pwmhl "standard interface APIs".
|
||||
*
|
||||
* \section Specific Specific implementation
|
||||
* \todo add documentation
|
||||
*
|
||||
* For a detailed configuration of the microcontroller, see \ref IfxCcu6_PwmHl_init().
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_PwmHl PWM Interface Driver
|
||||
* \ingroup IfxLld_Ccu6
|
||||
* \defgroup IfxLld_Ccu6_PwmHl_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Ccu6_PwmHl
|
||||
* \defgroup IfxLld_Ccu6_PwmHl_PwmHl_Functions PwmHl Functions
|
||||
* \ingroup IfxLld_Ccu6_PwmHl
|
||||
* \defgroup IfxLld_Ccu6_PwmHl_StdIf_Functions StdIf Functions
|
||||
* \ingroup IfxLld_Ccu6_PwmHl
|
||||
*/
|
||||
|
||||
#ifndef IFXCCU6_PWMHL_H
|
||||
#define IFXCCU6_PWMHL_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "StdIf/IfxStdIf_PwmHl.h"
|
||||
#include "Ccu6/TimerWithTrigger/IfxCcu6_TimerWithTrigger.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------------Macros-----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Maximal number of channels handled by the driver. One channel has a top and bottom pwm output
|
||||
*/
|
||||
#define IFXCCU6_PWMHL_MAX_CHANNELS (3)
|
||||
|
||||
/******************************************************************************/
|
||||
/*------------------------------Type Definitions------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct IfxCcu6_PwmHl_s IfxCcu6_PwmHl;
|
||||
|
||||
typedef void (*IfxCcu6_PwmHl_Update)(IfxCcu6_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmHl_DataStructures
|
||||
* \{ */
|
||||
/** \brief Multi-channels PWM object definition (channels only)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_TimerValue deadtime; /**< \brief Dead time between the top and bottom channel in ticks */
|
||||
Ifx_TimerValue minPulse; /**< \brief minimum pulse that is output, shorter pulse time will be output as 0% duty cycle */
|
||||
Ifx_TimerValue maxPulse; /**< \brief internal parameter */
|
||||
Ifx_Pwm_Mode mode; /**< \brief actual PWM mode */
|
||||
sint8 setMode; /**< \brief A non zero flag indicates that the PWM mode is being modified */
|
||||
Ifx_ActiveState ccxActiveState; /**< \brief Top PWM active state */
|
||||
Ifx_ActiveState coutxActiveState; /**< \brief Bottom PWM active state */
|
||||
boolean inverted; /**< \brief Flag indicating the center aligned inverted mode (TRUE) */
|
||||
uint8 channelCount; /**< \brief Number of PWM channels, one channel is made of a top and bottom channel */
|
||||
} IfxCcu6_PwmHl_Base;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmHl_DataStructures
|
||||
* \{ */
|
||||
/** \brief CCU6: PWM HL configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxStdIf_PwmHl_Config base; /**< \brief PWM HL standard interface configuration */
|
||||
IfxCcu6_TimerWithTrigger *timer; /**< \brief Pointer to the linked timer object */
|
||||
IfxCcu6_Cc60_Out *cc0; /**< \brief CC0 channel used */
|
||||
IfxCcu6_Cc61_Out *cc1; /**< \brief CC1 channel used */
|
||||
IfxCcu6_Cc62_Out *cc2; /**< \brief CC2 channel used */
|
||||
IfxCcu6_Cout60_Out *cout0; /**< \brief COUT0 channel used */
|
||||
IfxCcu6_Cout61_Out *cout1; /**< \brief COUT1 channel used */
|
||||
IfxCcu6_Cout62_Out *cout2; /**< \brief COUT2 channel used */
|
||||
} IfxCcu6_PwmHl_Config;
|
||||
|
||||
/** \brief Structure for PWM configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_Pwm_Mode mode; /**< \brief pwm mode */
|
||||
boolean inverted; /**< \brief Inverted configuration for the selected mode */
|
||||
IfxCcu6_PwmHl_Update update; /**< \brief update call back function for the selected mode */
|
||||
} IfxCcu6_PwmHl_Mode;
|
||||
|
||||
/** \brief CCU6 PWM driver
|
||||
*/
|
||||
struct IfxCcu6_PwmHl_s
|
||||
{
|
||||
IfxCcu6_PwmHl_Base base; /**< \brief Multi-channels PWM object definition (channels only) */
|
||||
IfxCcu6_TimerWithTrigger *timer; /**< \brief Pointer to the linked timer object */
|
||||
IfxCcu6_PwmHl_Update update; /**< \brief Update function for actual selected mode */
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmHl_PwmHl_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initializes the timer object
|
||||
* \note To ensure that the channels counter are reset by the timer and do not overflow, leading to random signal on the output, the timer must be started before the call to this function.
|
||||
* Initialise the CCU6 module for PWM generation of high- and low switches usage, e.g.
|
||||
* - electric motor drive
|
||||
* - half-bridge switches
|
||||
*
|
||||
* It is assumed that the whole CCU6 module is only used for purposes mentioned at the
|
||||
* IfxCcu6_PwmHl API. No part of CCU6 module is used for other purpose.
|
||||
*
|
||||
* The timer used should configure the T12 as PWM base timer and T13 as trigger.
|
||||
* \param driver CCU6 PWM driver
|
||||
* \param config CCU6 : PWM HL configuration
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_PwmHl_init(IfxCcu6_PwmHl *driver, const IfxCcu6_PwmHl_Config *config);
|
||||
|
||||
/** \brief Initialize the configuration structure to default
|
||||
* \param config Channel configuration. This parameter is Initialised by the function
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_PwmHl_initConfig(IfxCcu6_PwmHl_Config *config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_PwmHl_StdIf_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Inverts the active state
|
||||
* \param activeState Active state
|
||||
* \return State
|
||||
*/
|
||||
IFX_INLINE Ifx_ActiveState IfxCcu6_PwmHl_invertActiveState(Ifx_ActiveState activeState);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the dead time
|
||||
* \param driver CCU6 PWM driver
|
||||
* \return Dead Time
|
||||
*
|
||||
* \see IfxStdIf_PwmHl_GetDeadtime
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN float32 IfxCcu6_PwmHl_getDeadtime(IfxCcu6_PwmHl *driver);
|
||||
|
||||
/** \brief Returns the minimum pulse
|
||||
* \param driver CCU6 PWM driver
|
||||
* \return Min Pulse
|
||||
*
|
||||
* \see IfxStdIf_PwmHl_GetMinPulse
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN float32 IfxCcu6_PwmHl_getMinPulse(IfxCcu6_PwmHl *driver);
|
||||
|
||||
/** \brief Returns Pwm mode
|
||||
* \param driver CCU6 PWM driver
|
||||
* \return Pwm mode
|
||||
*
|
||||
* \see IfxStdIf_PwmHl_GetMode
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN Ifx_Pwm_Mode IfxCcu6_PwmHl_getMode(IfxCcu6_PwmHl *driver);
|
||||
|
||||
/** \brief Sets the dead time
|
||||
* \note The changes are not applied until Timer->applyUpdate() is called.
|
||||
* \param driver CCU6 PWM driver
|
||||
* \param deadtime Dead time value
|
||||
* \return TRUE on success else FALSE
|
||||
*
|
||||
* \see IfxStdIf_PwmHl_SetDeadtime
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_PwmHl_setDeadtime(IfxCcu6_PwmHl *driver, float32 deadtime);
|
||||
|
||||
/** \brief Sets the minimum pulse
|
||||
* \param driver CCU6 PWM driver
|
||||
* \param minPulse Minimum pulse
|
||||
* \return TRUE on success else FALSE
|
||||
*
|
||||
* \see IfxStdIf_PwmHl_SetMinPulse
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_PwmHl_setMinPulse(IfxCcu6_PwmHl *driver, float32 minPulse);
|
||||
|
||||
/** \brief Sets the PWM mode, the mode is only applied after setOnTime() + applyUpdate()
|
||||
* \param driver CCU6 PWM driver
|
||||
* \param mode Pwm mode
|
||||
* \return TRUE on success else FALSE
|
||||
*
|
||||
* \see IfxStdIf_PwmHl_SetMode
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_PwmHl_setMode(IfxCcu6_PwmHl *driver, Ifx_Pwm_Mode mode);
|
||||
|
||||
/** \brief Sets the ON time
|
||||
* Assign the ON time to the TOP channels.
|
||||
* The ON time of the BOTTOM channels are complementary.
|
||||
*
|
||||
* \note The changes are not applied until Timer->applyUpdate() is called.
|
||||
* \param driver CCU6 PWM driver
|
||||
* \param tOn ON time
|
||||
* \return None
|
||||
*
|
||||
* \see IfxStdIf_PwmHl_SetOnTime
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_PwmHl_setOnTime(IfxCcu6_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
/** \brief Set channels which are generating PWM or in "stuck-at" state.
|
||||
*
|
||||
* \note The values for the parameters are arranged as follows:
|
||||
* index = 0 --> phase 0 top
|
||||
* index = 1 --> phase 0 bottom
|
||||
* index = 2 --> phase 1 top
|
||||
* index = 3 --> phase 1 bottom
|
||||
* index = 4 --> phase 2 top
|
||||
* index = 5 --> phase 2 bottom
|
||||
* \param driver CCU6 PWM driver
|
||||
* \param activeCh Pointer to boolean array containing values for PWM channels.
|
||||
* If FALSE, the channel will be in stuck-at state, else the channel will generate PWM.
|
||||
* \param stuckSt Pointer to boolean array containing values for active channels.
|
||||
* If FALSE, the stuck-at state is passive level, else the stuck-at state is active level.
|
||||
* \return None
|
||||
*
|
||||
* \see IfxStdIf_PwmHl_SetupChannels
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_PwmHl_setupChannels(IfxCcu6_PwmHl *driver, boolean *activeCh, boolean *stuckSt);
|
||||
|
||||
/** \brief Initialises the statndard interface Pwm
|
||||
* \param stdif Standard interface object, will be initialized by the function
|
||||
* \param driver Interface driver to be used by the standard interface. must be initialised separately
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_PwmHl_stdIfPwmHlInit(IfxStdIf_PwmHl *stdif, IfxCcu6_PwmHl *driver);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE Ifx_ActiveState IfxCcu6_PwmHl_invertActiveState(Ifx_ActiveState activeState)
|
||||
{
|
||||
return activeState == Ifx_ActiveState_low ? Ifx_ActiveState_high : Ifx_ActiveState_low;
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXCCU6_PWMHL_H */
|
||||
@@ -0,0 +1,519 @@
|
||||
/**
|
||||
* \file IfxCcu6.c
|
||||
* \brief CCU6 basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxCcu6.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxCcu6_connectTrigger(Ifx_CCU6 *ccu6, IfxCcu6_TrigOut outputLine, IfxCcu6_TrigSel selectedTrigger)
|
||||
{
|
||||
unsigned mosel = ccu6->MOSEL.U;
|
||||
uint16 shift = (uint16)outputLine;
|
||||
uint16 data = 2 * selectedTrigger;
|
||||
|
||||
if (ccu6 == &MODULE_CCU61)
|
||||
{
|
||||
data = data + 1;
|
||||
}
|
||||
|
||||
mosel = ccu6->MOSEL.U;
|
||||
__ldmst_c(&mosel, (0x7U << shift), (data << shift));
|
||||
ccu6->MOSEL.U = mosel;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_disableModulationOutput(Ifx_CCU6 *ccu6, IfxCcu6_TimerId timer, IfxCcu6_ChannelOut channelOut)
|
||||
{
|
||||
uint32 shift, mask;
|
||||
|
||||
if (timer != IfxCcu6_TimerId_t13)
|
||||
{
|
||||
if (channelOut != IfxCcu6_ChannelOut_cout3)
|
||||
{
|
||||
shift = channelOut;
|
||||
mask = (1 << shift);
|
||||
ccu6->MODCTR.U = ccu6->MODCTR.U & ~(mask);
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (channelOut != IfxCcu6_ChannelOut_cout3)
|
||||
{
|
||||
shift = channelOut + 8;
|
||||
mask = (1 << shift);
|
||||
ccu6->MODCTR.U = ccu6->MODCTR.U & ~(mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
ccu6->MODCTR.B.ECT13O = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_disableModule(Ifx_CCU6 *ccu6)
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
ccu6->CLC.U = 0x00000001;
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
|
||||
/* Wait until module is disabled */
|
||||
while (IfxCcu6_isModuleEnabled(ccu6) == TRUE)
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_enableModulationOutput(Ifx_CCU6 *ccu6, IfxCcu6_TimerId timer, IfxCcu6_ChannelOut channelOut)
|
||||
{
|
||||
uint32 shift, mask;
|
||||
|
||||
if (timer != IfxCcu6_TimerId_t13)
|
||||
{
|
||||
if (channelOut != IfxCcu6_ChannelOut_cout3)
|
||||
{
|
||||
shift = channelOut;
|
||||
mask = (1 << shift);
|
||||
ccu6->MODCTR.U = ccu6->MODCTR.U | (mask);
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (channelOut != IfxCcu6_ChannelOut_cout3)
|
||||
{
|
||||
shift = channelOut + 8;
|
||||
mask = (1 << shift);
|
||||
ccu6->MODCTR.U = ccu6->MODCTR.U | (mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
ccu6->MODCTR.B.ECT13O = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_enableModule(Ifx_CCU6 *ccu6)
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
ccu6->CLC.B.DISR = 0U; /* Enable module */
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
|
||||
/* Wait until module is enabled */
|
||||
while (IfxCcu6_isModuleEnabled(ccu6) == FALSE)
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
Ifx_CCU6 *IfxCcu6_getAddress(IfxCcu6_Index ccu6)
|
||||
{
|
||||
Ifx_CCU6 *module;
|
||||
|
||||
if (ccu6 < IFXCCU6_NUM_MODULES)
|
||||
{
|
||||
module = (Ifx_CCU6 *)IfxCcu6_cfg_indexMap[ccu6].module;
|
||||
}
|
||||
else
|
||||
{
|
||||
module = NULL_PTR;
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxCcu6_getCaptureRegisterValue(Ifx_CCU6 *ccu6, IfxCcu6_T12Channel channel)
|
||||
{
|
||||
uint32 value = 0;
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case IfxCcu6_T12Channel_0:
|
||||
value = ccu6->CC60R.U;
|
||||
break;
|
||||
case IfxCcu6_T12Channel_1:
|
||||
value = ccu6->CC61R.U;
|
||||
break;
|
||||
case IfxCcu6_T12Channel_2:
|
||||
value = ccu6->CC62R.U;
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxCcu6_getCaptureShadowRegisterValue(Ifx_CCU6 *ccu6, IfxCcu6_T12Channel channel)
|
||||
{
|
||||
uint32 value = 0;
|
||||
|
||||
switch (channel)
|
||||
{
|
||||
case IfxCcu6_T12Channel_0:
|
||||
value = ccu6->CC60SR.U;
|
||||
break;
|
||||
case IfxCcu6_T12Channel_1:
|
||||
value = ccu6->CC61SR.U;
|
||||
break;
|
||||
case IfxCcu6_T12Channel_2:
|
||||
value = ccu6->CC62SR.U;
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
IfxCcu6_Index IfxCcu6_getIndex(Ifx_CCU6 *ccu6)
|
||||
{
|
||||
uint32 index;
|
||||
IfxCcu6_Index result;
|
||||
|
||||
result = IfxCcu6_Index_none;
|
||||
|
||||
for (index = 0; index < IFXCCU6_NUM_MODULES; index++)
|
||||
{
|
||||
if (IfxCcu6_cfg_indexMap[index].module == ccu6)
|
||||
{
|
||||
result = (IfxCcu6_Index)IfxCcu6_cfg_indexMap[index].index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
volatile Ifx_SRC_SRCR *IfxCcu6_getSrcAddress(Ifx_CCU6 *ccu6, IfxCcu6_ServiceRequest serviceRequest)
|
||||
{
|
||||
sint32 moduleIdx = IfxCcu6_getIndex(ccu6);
|
||||
volatile Ifx_SRC_SRCR *srcr;
|
||||
|
||||
srcr = &(MODULE_SRC.CCU6.CCU6[moduleIdx].SR0);
|
||||
return &(srcr[serviceRequest]);
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxCcu6_readTimer(Ifx_CCU6 *ccu6, IfxCcu6_TimerId timer)
|
||||
{
|
||||
uint32 result = 0;
|
||||
|
||||
if (timer != IfxCcu6_TimerId_t13)
|
||||
{
|
||||
result = ccu6->T12.U;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ccu6->T13.U;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_resetModule(Ifx_CCU6 *ccu6)
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
ccu6->KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
|
||||
ccu6->KRST1.B.RST = 1;
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
|
||||
while (0 == ccu6->KRST0.B.RSTSTAT) /* Wait until reset is executed */
|
||||
|
||||
{}
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
ccu6->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_routeInterruptNode(Ifx_CCU6 *ccu6, IfxCcu6_InterruptSource source, IfxCcu6_ServiceRequest serviceRequest)
|
||||
{
|
||||
if ((source == IfxCcu6_InterruptSource_cc60RisingEdge) || (source == IfxCcu6_InterruptSource_cc60FallingEdge))
|
||||
{
|
||||
ccu6->INP.B.INPCC60 = serviceRequest;
|
||||
}
|
||||
else if ((source == IfxCcu6_InterruptSource_cc61RisingEdge) || (source == IfxCcu6_InterruptSource_cc61FallingEdge))
|
||||
{
|
||||
ccu6->INP.B.INPCC61 = serviceRequest;
|
||||
}
|
||||
else if ((source == IfxCcu6_InterruptSource_cc62RisingEdge) || (source == IfxCcu6_InterruptSource_cc62FallingEdge))
|
||||
{
|
||||
ccu6->INP.B.INPCC62 = serviceRequest;
|
||||
}
|
||||
else if ((source == IfxCcu6_InterruptSource_correctHallEvent))
|
||||
{
|
||||
ccu6->INP.B.INPCHE = serviceRequest;
|
||||
}
|
||||
else if ((source == IfxCcu6_InterruptSource_trap) || (source == IfxCcu6_InterruptSource_wrongHallEvent))
|
||||
{
|
||||
ccu6->INP.B.INPERR = serviceRequest;
|
||||
}
|
||||
else if ((source == IfxCcu6_InterruptSource_t12OneMatch) || (source == IfxCcu6_InterruptSource_t12PeriodMatch))
|
||||
{
|
||||
ccu6->INP.B.INPT12 = serviceRequest;
|
||||
}
|
||||
else if ((source == IfxCcu6_InterruptSource_t13CompareMatch) || (source == IfxCcu6_InterruptSource_t13PeriodMatch))
|
||||
{
|
||||
ccu6->INP.B.INPT13 = serviceRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
__debug();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_setOutputPassiveLevel(Ifx_CCU6 *ccu6, IfxCcu6_ChannelOut channelOut, boolean state)
|
||||
{
|
||||
if (channelOut != IfxCcu6_ChannelOut_cout3)
|
||||
{
|
||||
uint32 shift = channelOut;
|
||||
uint32 mask = (1 << shift);
|
||||
ccu6->PSLR.U = (ccu6->PSLR.U & ~mask) | ((uint32)state << shift);
|
||||
}
|
||||
else
|
||||
{
|
||||
ccu6->PSLR.B.PSL63 = state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_setT12CaptureCompareState(Ifx_CCU6 *ccu6, IfxCcu6_T12Channel channel, IfxCcu6_CaptureCompareState state)
|
||||
{
|
||||
uint32 mask = (0x0101U << channel);
|
||||
uint32 mode;
|
||||
|
||||
if (state == IfxCcu6_CaptureCompareState_set)
|
||||
{
|
||||
mode = 0x0001U;
|
||||
ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << channel);
|
||||
}
|
||||
|
||||
if (state == IfxCcu6_CaptureCompareState_clear)
|
||||
{
|
||||
mode = 0x0100U;
|
||||
ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << channel);
|
||||
}
|
||||
|
||||
if (state == IfxCcu6_CaptureCompareState_toggle)
|
||||
{
|
||||
mode = 0x0101U;
|
||||
ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_setT12CompareValue(Ifx_CCU6 *ccu6, IfxCcu6_T12Channel channel, uint16 value)
|
||||
{
|
||||
switch (channel)
|
||||
{
|
||||
case IfxCcu6_T12Channel_0:
|
||||
ccu6->CC60SR.B.CCS = value;
|
||||
break;
|
||||
case IfxCcu6_T12Channel_1:
|
||||
ccu6->CC61SR.B.CCS = value;
|
||||
break;
|
||||
case IfxCcu6_T12Channel_2:
|
||||
ccu6->CC62SR.B.CCS = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float32 IfxCcu6_setT12Frequency(Ifx_CCU6 *ccu6, float32 frequency, Ifx_TimerValue period, IfxCcu6_T12CountMode countMode)
|
||||
{
|
||||
uint16 prescaler;
|
||||
float32 freqCC6 = IfxScuCcu_getSpbFrequency();
|
||||
uint16 divFactor = freqCC6 / frequency;
|
||||
|
||||
for (prescaler = 0; prescaler < 16; prescaler++)
|
||||
{
|
||||
divFactor = divFactor / 2;
|
||||
|
||||
if (divFactor == (uint8)0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (prescaler < 16)
|
||||
{
|
||||
uint16 periodVal;
|
||||
boolean additionalPrescaler;
|
||||
IfxCcu6_TimerInputClock clockInput;
|
||||
|
||||
periodVal = (uint16)((countMode != IfxCcu6_T12CountMode_edgeAligned) ? ((period / 2) - 1) : (period - 1));
|
||||
IfxCcu6_setT12PeriodValue(ccu6, periodVal);
|
||||
IfxCcu6_enableShadowTransfer(ccu6, TRUE, FALSE);
|
||||
|
||||
clockInput = (IfxCcu6_TimerInputClock)(prescaler & 0x7U);
|
||||
IfxCcu6_setInputClockFrequency(ccu6, IfxCcu6_TimerId_t12, clockInput);
|
||||
|
||||
additionalPrescaler = ((prescaler & 0x8U) != 0);
|
||||
|
||||
if (additionalPrescaler)
|
||||
{
|
||||
IfxCcu6_enableAdditionalPrescaler(ccu6, IfxCcu6_TimerId_t12);
|
||||
}
|
||||
|
||||
IfxCcu6_setT12CountMode(ccu6, countMode);
|
||||
|
||||
frequency = freqCC6 / (0x1u << prescaler); // Frequency = FREQ_CCU6 / (2 ^ prescaler)
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = 0;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_setT12InputSignal(Ifx_CCU6 *ccu6, IfxCcu6_T12hr_In *extInput)
|
||||
{
|
||||
ccu6->PISEL2.B.T12EXT = extInput->select >= Ifx_RxSel_e;
|
||||
ccu6->PISEL0.B.IST12HR = extInput->select;
|
||||
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, extInput->module == ccu6);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_setT13CaptureCompareState(Ifx_CCU6 *ccu6, IfxCcu6_CaptureCompareState state)
|
||||
{
|
||||
uint32 shift = 6;
|
||||
uint32 mask = (0x0101U << shift);
|
||||
uint32 mode;
|
||||
|
||||
if (state == IfxCcu6_CaptureCompareState_set)
|
||||
{
|
||||
mode = 0x0001U;
|
||||
ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << shift);
|
||||
}
|
||||
|
||||
if (state == IfxCcu6_CaptureCompareState_clear)
|
||||
{
|
||||
mode = 0x0100U;
|
||||
ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << shift);
|
||||
}
|
||||
|
||||
if (state == IfxCcu6_CaptureCompareState_toggle)
|
||||
{
|
||||
mode = 0x0101U;
|
||||
ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << shift);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float32 IfxCcu6_setT13Frequency(Ifx_CCU6 *ccu6, float32 frequency, Ifx_TimerValue period)
|
||||
{
|
||||
uint16 prescaler;
|
||||
float32 freqCC6 = IfxScuCcu_getSpbFrequency();
|
||||
uint16 divFactor = freqCC6 / frequency;
|
||||
|
||||
for (prescaler = 0; prescaler < 16; prescaler++)
|
||||
{
|
||||
divFactor = divFactor / 2;
|
||||
|
||||
if (divFactor == (uint8)0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (prescaler < 16)
|
||||
{
|
||||
uint16 periodVal;
|
||||
boolean additionalPrescaler;
|
||||
IfxCcu6_TimerInputClock clockInput;
|
||||
|
||||
periodVal = (uint16)(period - 1);
|
||||
IfxCcu6_setT13PeriodValue(ccu6, periodVal);
|
||||
IfxCcu6_enableShadowTransfer(ccu6, FALSE, TRUE);
|
||||
|
||||
clockInput = (IfxCcu6_TimerInputClock)(prescaler & 0x7U);
|
||||
IfxCcu6_setInputClockFrequency(ccu6, IfxCcu6_TimerId_t13, clockInput);
|
||||
|
||||
additionalPrescaler = ((prescaler & 0x8U) != 0);
|
||||
|
||||
if (additionalPrescaler)
|
||||
{
|
||||
IfxCcu6_enableAdditionalPrescaler(ccu6, IfxCcu6_TimerId_t13);
|
||||
}
|
||||
|
||||
frequency = freqCC6 / (0x1u << prescaler); // Frequency = FREQ_CCU6 / (2 ^ prescaler)
|
||||
}
|
||||
else
|
||||
{
|
||||
/** \retval IfxCcu6_Stat_wrongPwmFreq if the T12 prescaler can't fulfill the
|
||||
* required frequency */
|
||||
frequency = 0;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_setT13InputSignal(Ifx_CCU6 *ccu6, IfxCcu6_T13hr_In *extInput)
|
||||
{
|
||||
ccu6->PISEL2.B.T13EXT = extInput->select >= Ifx_RxSel_e;
|
||||
ccu6->PISEL2.B.IST13HR = extInput->select;
|
||||
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, extInput->module == ccu6);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,550 @@
|
||||
/**
|
||||
* \file IfxCcu6_TPwm.c
|
||||
* \brief CCU6 TPWM details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxCcu6_TPwm.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxCcu6_TPwm_initModule(IfxCcu6_TPwm *tPwm, const IfxCcu6_TPwm_Config *config)
|
||||
{
|
||||
Ifx_CCU6 *ccu6SFR = config->ccu6; // pointer to CCU6 registers
|
||||
tPwm->ccu6 = ccu6SFR; // adding register pointer to module handler
|
||||
|
||||
/* -- hardware module initialisation -- */
|
||||
|
||||
// enable module if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_isModuleEnabled(ccu6SFR) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableModule(ccu6SFR);
|
||||
}
|
||||
|
||||
/* -- timer initialisation -- */
|
||||
|
||||
// Timer 13 initialisation //
|
||||
|
||||
if (config->timer == IfxCcu6_TimerId_t13)
|
||||
{
|
||||
// enable Timer13 if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_getTimerAvailabilityStatus(ccu6SFR, IfxCcu6_TimerId_t13) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableTimer(ccu6SFR, IfxCcu6_TimerId_t13);
|
||||
}
|
||||
|
||||
// clock initialisation //
|
||||
|
||||
if (config->clock.t13ExtClockEnabled) // if external source is selected as reference
|
||||
{
|
||||
// input signal selection
|
||||
if (config->clock.t13ExtClockInput != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setT13InputSignal(config->ccu6, config->clock.t13ExtClockInput);
|
||||
}
|
||||
|
||||
// counting input mode selection
|
||||
IfxCcu6_setCountingInputMode(ccu6SFR, IfxCcu6_TimerId_t13, config->clock.t13countingInputMode);
|
||||
|
||||
// period setting
|
||||
IfxCcu6_setT13PeriodValue(ccu6SFR, (uint16)config->base.period);
|
||||
}
|
||||
else // if internal clock is selected as reference
|
||||
{
|
||||
IfxCcu6_setT13Frequency(ccu6SFR, config->base.frequency, config->base.period);
|
||||
}
|
||||
|
||||
// duty cycle initialisation //
|
||||
|
||||
IfxCcu6_setT13CounterValue(ccu6SFR, config->timer13.counterValue);
|
||||
|
||||
IfxCcu6_setT13CompareValue(ccu6SFR, config->timer13.compareValue);
|
||||
|
||||
// if Timer 13 start is in sync with Timer 12 //
|
||||
if (config->trigger.t13InSyncWithT12)
|
||||
{
|
||||
IfxCcu6_setT13TriggerEventMode(ccu6SFR, config->timer13.t12SyncEvent);
|
||||
IfxCcu6_setT13TriggerEventDirection(ccu6SFR, config->timer13.t12SyncDirection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
// Timer 12 initialisation //
|
||||
|
||||
if ((config->timer == IfxCcu6_TimerId_t12) || (config->trigger.t13InSyncWithT12))
|
||||
{
|
||||
Ifx_TimerValue period = config->base.period;
|
||||
Ifx_TimerValue compareValue = config->timer12.compareValue;
|
||||
|
||||
// enable Timer12 if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_getTimerAvailabilityStatus(ccu6SFR, IfxCcu6_TimerId_t12) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableTimer(ccu6SFR, IfxCcu6_TimerId_t12);
|
||||
}
|
||||
|
||||
// if Timer 13 start is in sync with Timer 12 //
|
||||
if ((config->trigger.t13InSyncWithT12) && (config->base.waitingTime != 0))
|
||||
{
|
||||
// if in sync with T12 period match
|
||||
if (config->timer13.t12SyncEvent == IfxCcu6_T13TriggerEvent_onT12Period)
|
||||
{
|
||||
period = config->base.waitingTime; // waiting time as period
|
||||
}
|
||||
else if (config->timer13.t12SyncEvent != IfxCcu6_T13TriggerEvent_noAction)
|
||||
{
|
||||
compareValue = config->base.waitingTime; // waiting time as compare value
|
||||
period = config->base.activeCount;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// configuration error
|
||||
}
|
||||
|
||||
// clock initialisation //
|
||||
|
||||
if (config->clock.t12ExtClockEnabled) // if external source is selected as reference
|
||||
{
|
||||
// input signal selection
|
||||
if (config->clock.t12ExtClockInput != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setT12InputSignal(config->ccu6, config->clock.t12ExtClockInput);
|
||||
}
|
||||
|
||||
// counting input mode selection
|
||||
IfxCcu6_setCountingInputMode(ccu6SFR, IfxCcu6_TimerId_t12, config->clock.t12countingInputMode);
|
||||
|
||||
// countining mode selection
|
||||
IfxCcu6_setT12CountMode(ccu6SFR, config->timer12.countMode);
|
||||
|
||||
// period selection for center aligned mode
|
||||
if (config->timer12.countMode == IfxCcu6_T12CountMode_centerAligned)
|
||||
{
|
||||
period = (period / 2) - 1;
|
||||
}
|
||||
|
||||
// period setting
|
||||
IfxCcu6_setT12PeriodValue(ccu6SFR, (uint16)period);
|
||||
}
|
||||
else // if internal clock is selected as reference
|
||||
{
|
||||
// in case of in sync with T13 T12 runs at same frequency as T13
|
||||
IfxCcu6_setT12Frequency(ccu6SFR, config->base.frequency, period, config->timer12.countMode);
|
||||
}
|
||||
|
||||
// duty cycle initialisation //
|
||||
|
||||
IfxCcu6_setT12CounterValue(ccu6SFR, config->timer12.counterValue);
|
||||
|
||||
IfxCcu6_setT12ChannelMode(ccu6SFR, config->timer12.channelId, config->timer12.channelMode);
|
||||
|
||||
IfxCcu6_setT12CompareValue(ccu6SFR, config->timer12.channelId, (uint16)compareValue);
|
||||
|
||||
// dead time injection if selected
|
||||
if (config->timer12.deadTimeValue)
|
||||
{
|
||||
IfxCcu6_setDeadTimeValue(ccu6SFR, config->timer12.deadTimeValue);
|
||||
IfxCcu6_enableDeadTime(ccu6SFR, config->timer12.channelId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
/* -- output path initialisation -- */
|
||||
|
||||
//enable modulation output path //
|
||||
IfxCcu6_enableModulationOutput(ccu6SFR, config->timer, config->channelOut);
|
||||
|
||||
// output passive logic configuration //
|
||||
//TODO check correct polarity:
|
||||
IfxCcu6_setOutputPassiveState(ccu6SFR, config->channelOut, config->base.activeState);
|
||||
|
||||
/* -- Pin mapping -- */
|
||||
|
||||
const IfxCcu6_TPwm_Pins *pins = config->pins;
|
||||
|
||||
if (pins != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_Cc60_Out *cc60Out = pins->cc60Out;
|
||||
|
||||
if (cc60Out != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc60OutPin(cc60Out, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cc61_Out *cc61Out = pins->cc61Out;
|
||||
|
||||
if (cc61Out != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc61OutPin(cc61Out, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cc62_Out *cc62Out = pins->cc62Out;
|
||||
|
||||
if (cc62Out != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCc62OutPin(cc62Out, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cout60_Out *cout60 = pins->cout60;
|
||||
|
||||
if (cout60 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout60Pin(cout60, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cout61_Out *cout61 = pins->cout61;
|
||||
|
||||
if (cout61 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout61Pin(cout61, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cout62_Out *cout62 = pins->cout62;
|
||||
|
||||
if (cout62 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout62Pin(cout62, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_Cout63_Out *cout63 = pins->cout63;
|
||||
|
||||
if (cout63 != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initCout63Pin(cout63, pins->outputMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
IfxCcu6_T12hr_In *t12hr = pins->t12hr;
|
||||
|
||||
if (t12hr != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initT12hrPin(t12hr, pins->t1xhrInputMode);
|
||||
}
|
||||
|
||||
IfxCcu6_T13hr_In *t13hr = pins->t13hr;
|
||||
|
||||
if (t13hr != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initT13hrPin(t13hr, pins->t1xhrInputMode);
|
||||
}
|
||||
}
|
||||
|
||||
/* -- interrupt initialisation -- */
|
||||
|
||||
if (config->interrupt1.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt1.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt1.source, config->interrupt1.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt1.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt1.typeOfService, config->interrupt1.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt2.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt2.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt2.source, config->interrupt2.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt2.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt2.typeOfService, config->interrupt2.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt3.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt3.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt3.source, config->interrupt3.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt3.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt3.typeOfService, config->interrupt3.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt4.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt4.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt4.source, config->interrupt4.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt4.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt4.typeOfService, config->interrupt4.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
/* -- output trigger initialisation --*/
|
||||
|
||||
if (config->trigger.outputTriggerEnabled)
|
||||
{
|
||||
IfxCcu6_connectTrigger(ccu6SFR, config->trigger.outputLine, config->trigger.outputTrigger);
|
||||
}
|
||||
|
||||
tPwm->timer = config->timer;
|
||||
tPwm->channelOut = config->channelOut;
|
||||
tPwm->trigger = config->trigger;
|
||||
|
||||
#if IFX_CFG_USE_STANDARD_INTERFACE
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (uint32)tPwm == ((uint32)&tPwm->base));
|
||||
tPwm->base.functions.start = (TPwm_Start) & IfxCcu6_TPwm_start;
|
||||
tPwm->base.functions.pause = (TPwm_Pause) & IfxCcu6_TPwm_pause;
|
||||
tPwm->base.functions.resume = (TPwm_Resume) & IfxCcu6_TPwm_resume;
|
||||
tPwm->base.functions.stop = (TPwm_Stop) & IfxCcu6_TPwm_stop;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TPwm_initModuleConfig(IfxCcu6_TPwm_Config *config, Ifx_CCU6 *ccu6)
|
||||
{
|
||||
const IfxCcu6_TPwm_Config defaultConfig = {
|
||||
.base = {
|
||||
.frequency = 400000,
|
||||
.waitingTime = 20,
|
||||
.activeCount = 0,
|
||||
.period = 100,
|
||||
.activeState = Ifx_ActiveState_high,
|
||||
},
|
||||
|
||||
.ccu6 = NULL_PTR, // will be initialized below
|
||||
|
||||
.timer = IfxCcu6_TimerId_t13,
|
||||
|
||||
.clock = {
|
||||
.t12ExtClockEnabled = FALSE,
|
||||
.t12ExtClockInput = NULL_PTR,
|
||||
.t12countingInputMode = IfxCcu6_CountingInputMode_internal,
|
||||
|
||||
.t13ExtClockEnabled = FALSE,
|
||||
.t13ExtClockInput = NULL_PTR,
|
||||
.t13countingInputMode = IfxCcu6_CountingInputMode_internal,
|
||||
},
|
||||
|
||||
.timer12 = {
|
||||
.channelId = IfxCcu6_T12Channel_0,
|
||||
.channelMode = IfxCcu6_T12ChannelMode_compareMode,
|
||||
.countMode = IfxCcu6_T12CountMode_edgeAligned,
|
||||
.counterValue = 0,
|
||||
.deadTimeValue = 0,
|
||||
.compareValue = 0,
|
||||
},
|
||||
|
||||
.timer13 = {
|
||||
.counterValue = 0,
|
||||
.compareValue = 0,
|
||||
.t12SyncEvent = IfxCcu6_T13TriggerEvent_onCC60RCompare,
|
||||
.t12SyncDirection = IfxCcu6_T13TriggerDirection_onT12CountingUp,
|
||||
},
|
||||
|
||||
.channelOut = IfxCcu6_ChannelOut_cout3,
|
||||
|
||||
.pins = NULL_PTR,
|
||||
|
||||
.interrupt1 = {
|
||||
.source = IfxCcu6_InterruptSource_t12PeriodMatch,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_0,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.interrupt2 = {
|
||||
.source = IfxCcu6_InterruptSource_t13PeriodMatch,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_1,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.interrupt3 = {
|
||||
.source = IfxCcu6_InterruptSource_t12OneMatch,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_2,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.interrupt4 = {
|
||||
.source = IfxCcu6_InterruptSource_trap,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_3,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.trigger = {
|
||||
.t12ExtInputTrigger = NULL_PTR,
|
||||
.t13ExtInputTrigger = NULL_PTR,
|
||||
.extInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge,
|
||||
.t13InSyncWithT12 = TRUE,
|
||||
|
||||
.outputTriggerEnabled = TRUE,
|
||||
.outputLine = IfxCcu6_TrigOut_0,
|
||||
.outputTrigger = IfxCcu6_TrigSel_cout63,
|
||||
},
|
||||
};
|
||||
|
||||
/* Default Configuration */
|
||||
*config = defaultConfig;
|
||||
|
||||
/* take over module pointer */
|
||||
config->ccu6 = ccu6;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TPwm_pause(IfxCcu6_TPwm *tPwm)
|
||||
{
|
||||
IfxCcu6_disableModulationOutput(tPwm->ccu6, tPwm->timer, tPwm->channelOut);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TPwm_resume(IfxCcu6_TPwm *tPwm)
|
||||
{
|
||||
IfxCcu6_enableModulationOutput(tPwm->ccu6, tPwm->timer, tPwm->channelOut);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TPwm_start(IfxCcu6_TPwm *tPwm)
|
||||
{
|
||||
// Timer 13 modulation //
|
||||
|
||||
if (tPwm->timer == IfxCcu6_TimerId_t13)
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(tPwm->ccu6, FALSE, TRUE);
|
||||
|
||||
// start Timer 13 when not in sync with Timer 12
|
||||
if (!(tPwm->trigger.t13InSyncWithT12))
|
||||
{
|
||||
if (tPwm->trigger.t13ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
// external start
|
||||
IfxCcu6_setExternalRunMode(tPwm->ccu6, IfxCcu6_TimerId_t13, tPwm->trigger.extInputTriggerMode);
|
||||
IfxCcu6_setT13InputSignal(tPwm->ccu6, tPwm->trigger.t13ExtInputTrigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
// internal start
|
||||
IfxCcu6_startTimer(tPwm->ccu6, FALSE, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
// Timer 12 alone for modulation or when in sync with Timer 13 //
|
||||
|
||||
if ((tPwm->timer == IfxCcu6_TimerId_t12) || (tPwm->trigger.t13InSyncWithT12))
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(tPwm->ccu6, TRUE, FALSE);
|
||||
|
||||
//start Timer 12
|
||||
if (tPwm->trigger.t12ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
// external start
|
||||
IfxCcu6_setExternalRunMode(tPwm->ccu6, IfxCcu6_TimerId_t12, tPwm->trigger.extInputTriggerMode);
|
||||
IfxCcu6_setT12InputSignal(tPwm->ccu6, tPwm->trigger.t12ExtInputTrigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
// internal start
|
||||
IfxCcu6_startTimer(tPwm->ccu6, TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TPwm_stop(IfxCcu6_TPwm *tPwm)
|
||||
{
|
||||
// Timer 13 modulation //
|
||||
|
||||
if ((tPwm->timer == IfxCcu6_TimerId_t13) || (tPwm->trigger.t13InSyncWithT12))
|
||||
{
|
||||
// disable shadow transfer
|
||||
IfxCcu6_disableShadowTransfer(tPwm->ccu6, FALSE, TRUE);
|
||||
|
||||
// remove external input trigger if any
|
||||
if (tPwm->trigger.t13ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setExternalRunMode(tPwm->ccu6, IfxCcu6_TimerId_t13, IfxCcu6_ExternalTriggerMode_disable);
|
||||
}
|
||||
|
||||
// remove the sync with Timer 12
|
||||
if (tPwm->trigger.t13InSyncWithT12)
|
||||
{
|
||||
IfxCcu6_setT13TriggerEventMode(tPwm->ccu6, IfxCcu6_T13TriggerEvent_noAction);
|
||||
IfxCcu6_setT13TriggerEventDirection(tPwm->ccu6, IfxCcu6_T13TriggerDirection_noAction);
|
||||
}
|
||||
|
||||
// stop Timer 13
|
||||
IfxCcu6_stopTimer(tPwm->ccu6, FALSE, TRUE);
|
||||
}
|
||||
|
||||
// Timer 12 modulation //
|
||||
|
||||
else
|
||||
{
|
||||
// disable shadow transfer
|
||||
IfxCcu6_disableShadowTransfer(tPwm->ccu6, TRUE, FALSE);
|
||||
|
||||
// remove external input trigger if any
|
||||
if (tPwm->trigger.t12ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setExternalRunMode(tPwm->ccu6, IfxCcu6_TimerId_t12, IfxCcu6_ExternalTriggerMode_disable);
|
||||
}
|
||||
|
||||
// stop Timer 12
|
||||
IfxCcu6_stopTimer(tPwm->ccu6, TRUE, FALSE);
|
||||
}
|
||||
|
||||
// disable the modulation
|
||||
IfxCcu6_disableModulationOutput(tPwm->ccu6, tPwm->timer, tPwm->channelOut);
|
||||
}
|
||||
@@ -0,0 +1,417 @@
|
||||
/**
|
||||
* \file IfxCcu6_TPwm.h
|
||||
* \brief CCU6 TPWM details
|
||||
* \ingroup IfxLld_Ccu6
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_TPwm_Usage How to use the CCU6 TPWM Interface driver?
|
||||
* \ingroup IfxLld_Ccu6_TPwm
|
||||
*
|
||||
* The TPWM interface driver provides a default CCU6 configuration for PWM modulation output through the selected timer block.
|
||||
*
|
||||
* User can select the various configuration options that hardware allows
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Ccu6_TPwm_Preparation Preparation
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_TPwm_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
* \code
|
||||
* #include <Ccu6/TPwm/IfxCcu6_TPwm.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_TPwm_Variables Variables
|
||||
*
|
||||
* Declare the TPWM handle as global variable in your C code:
|
||||
*
|
||||
* \code
|
||||
* // used globally
|
||||
* static IfxCcu6_TPwm tPwm;
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_TPwm_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priority for the Interrrupt handler. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define IFX_INTPRIO_CCU6 1
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routine to your C code.
|
||||
* \code
|
||||
* IFX_INTERRUPT(ccu60ISR_TPwm, 0, IFX_INTPRIO_CCU6)
|
||||
* {
|
||||
* //user code
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handlers in your initialisation function:
|
||||
* \code
|
||||
* // install interrupt handlers
|
||||
* IfxCpu_Irq_installInterruptHandler(&ccu60ISR_TPwm, IFX_INTPRIO_CCU6);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_TPwm_Init Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function. Here an example:
|
||||
* \code
|
||||
* // create configuration
|
||||
* IfxCcu6_TPwm_Config tPwmConfig;
|
||||
* IfxCcu6_TPwm_initModuleConfig(&tPwmConfig, &MODULE_CCU60);
|
||||
*
|
||||
* // configure the frequency of the timer in case of internal start
|
||||
* // this frequency will be set for the timer block selected later
|
||||
* tPwmConfig.base.frequency = 400000;
|
||||
*
|
||||
* // configure the period of the timer
|
||||
* tPwmConfig.base.period = 100;
|
||||
*
|
||||
* // configure the waiting time in case of delayed T13 start in sync with T12
|
||||
* tPwmConfig.base.waitingTime = 20;
|
||||
*
|
||||
* // select the active state of the output
|
||||
* tPwmConfig.base.activeState = Ifx_ActiveState_high;
|
||||
*
|
||||
* // select the timer through which PWM is to be generated
|
||||
* tPwmConfig.timer = IfxCcu6_TimerId_t13;
|
||||
*
|
||||
* // configure the clock for internal mode
|
||||
* tPwmConfig.clock.t13ExtClockEnabled = FALSE;
|
||||
* tPwmConfig.clock.t13ExtClockInput = NULL_PTR;
|
||||
* tPwmConfig.clock.t13countingInputMode = IfxCcu6_CountingInputMode_internal;
|
||||
*
|
||||
* // configure the selcted timer block
|
||||
* tPwmConfig.timer13.counterValue = 0;
|
||||
* tPwmConfig.timer13.compareValue = 100;
|
||||
* // configure the syncronisation, in case of sync start with T12
|
||||
* tPwmConfig.timer13.t12SyncEvent = IfxCcu6_T13TriggerEvent_onCC60RCompare;
|
||||
* tPwmConfig.timer13.t12SyncDirection = IfxCcu6_T13TriggerDirection_onT12CountingUp;
|
||||
*
|
||||
* //select the channel out for modulation
|
||||
* tPwmConfig.channelOut = IfxCcu6_ChannelOut_cout3;
|
||||
*
|
||||
* // pin configuration
|
||||
* const IfxCcu6_TPwm_Pins pins = {
|
||||
* NULL, // CC60Out pin not used
|
||||
* NULL, // CC61Out pin not used
|
||||
* NULL, // CC62Out pin not used
|
||||
* NULL, // COUT60 pin not used
|
||||
* NULL, // COUT61 pin not used
|
||||
* NULL, // COUT62 pin not used
|
||||
* IfxCcu60_COUT63_P00_0_OUT, // COUT63 pin
|
||||
* IfxPort_OutputMode_pushPull,
|
||||
* IfxPort_PadDriver_cmosAutomotiveSpeed1
|
||||
* };
|
||||
* tPwmConfig.pins = &pins;
|
||||
*
|
||||
* // configure the interrupts
|
||||
* tPwmConfig.interrupt1.interruptSource = IfxCcu6_InterruptSource_t13CompareMatch;
|
||||
* tPwmConfig.interrupt1.serviceRequest = IfxCcu6_ServiceRequest_2;
|
||||
* tPwmConfig.interrupt1.priority = IFX_INTPRIO_CCU6;
|
||||
* tPwmConfig.interrupt1.typeOfService = IfxSrc_Tos_cpu0;
|
||||
*
|
||||
* // configure input and output triggers
|
||||
* tPwmConfig.trigger.t12ExtInputTrigger = IfxCcu60_T12HRB_P00_7_IN;
|
||||
* tPwmConfig.trigger.t13ExtInputTrigger = NULL_PTR;
|
||||
* tPwmConfig.trigger.extInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge;
|
||||
* tPwmConfig.trigger.t13InSyncWithT12 = TRUE;
|
||||
*
|
||||
* tPwmConfig.trigger.outputTriggerEnabled = TRUE;
|
||||
* tPwmConfig.trigger.outputLine = IfxCcu6_TrigOut_0;
|
||||
* tPwmConfig.trigger.outputTrigger = IfxCcu6_TrigSel_cout63;
|
||||
*
|
||||
*
|
||||
* // initialize the module
|
||||
* IfxCcu6_TPwm_initModule(&tPwm, &tPwmConfig);
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* The TPWM is ready for use now!
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Ccu6_TPwm_ModulationControl Modulation Control
|
||||
*
|
||||
*
|
||||
* The TPWM driver provides simple to use Modulation Control functions
|
||||
*
|
||||
* This means: you can start, stop, pause and resume the modulation once the module is initialised with the appropriate configuration
|
||||
*
|
||||
* Start the modulation
|
||||
* \code
|
||||
* IfxCcu6_TPwm_start(&tPwm);
|
||||
* \endcode
|
||||
*
|
||||
* Stop the modulation
|
||||
* \code
|
||||
* IfxCcu6_TPwm_stop(&tPwm);
|
||||
* \endcode
|
||||
*
|
||||
* Pause the modulation
|
||||
* \code
|
||||
* IfxCcu6_TPwm_pause(&tPwm);
|
||||
* \endcode
|
||||
*
|
||||
* Resume the modulation
|
||||
* \code
|
||||
* IfxCcu6_TPwm_resume(&tPwm);
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_TPwm TPWM Interface driver
|
||||
* \ingroup IfxLld_Ccu6
|
||||
* \defgroup IfxLld_Ccu6_TPwm_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Ccu6_TPwm
|
||||
* \defgroup IfxLld_Ccu6_TPwm_Module_Initialize_Functions Module Initialize Functions
|
||||
* \ingroup IfxLld_Ccu6_TPwm
|
||||
* \defgroup IfxLld_Ccu6_TPwm_Modultion_Control_Functions Modultion Control Functions
|
||||
* \ingroup IfxLld_Ccu6_TPwm
|
||||
*/
|
||||
|
||||
#ifndef IFXCCU6_TPWM_H
|
||||
#define IFXCCU6_TPWM_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Ccu6/Std/IfxCcu6.h"
|
||||
#include "If/Ccu6If/TPwm.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_TPwm_DataStructures
|
||||
* \{ */
|
||||
/** \brief Structure for clock configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean t12ExtClockEnabled; /**< \brief Timer 12 external clock enable / disable selection */
|
||||
IfxCcu6_T12hr_In *t12ExtClockInput; /**< \brief External input signal selection for timer 12 */
|
||||
IfxCcu6_CountingInputMode t12countingInputMode; /**< \brief Input event leading to a counting action of the timer T12 */
|
||||
boolean t13ExtClockEnabled; /**< \brief Timer 13 external clock enable / disable selection */
|
||||
IfxCcu6_T13hr_In *t13ExtClockInput; /**< \brief External input signal selection for timer 13 */
|
||||
IfxCcu6_CountingInputMode t13countingInputMode; /**< \brief Input event leading to a counting action of the timer T13 */
|
||||
} IfxCcu6_TPwm_Clock;
|
||||
|
||||
/** \brief Structure for interrupt configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_InterruptSource source; /**< \brief Interrupt source selection */
|
||||
IfxCcu6_ServiceRequest serviceRequest; /**< \brief Selection of service request outputs */
|
||||
uint16 priority; /**< \brief Interrupt priority */
|
||||
IfxSrc_Tos typeOfService; /**< \brief type of interrupt service */
|
||||
} IfxCcu6_TPwm_InterruptConfig;
|
||||
|
||||
/** \brief Structure for CCU6 output pin configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IFX_CONST IfxCcu6_Cc60_Out *cc60Out; /**< \brief CC60 compare output CC0 */
|
||||
IFX_CONST IfxCcu6_Cc61_Out *cc61Out; /**< \brief CC61 compare output CC1 */
|
||||
IFX_CONST IfxCcu6_Cc62_Out *cc62Out; /**< \brief CC62 compare output CC2 */
|
||||
IFX_CONST IfxCcu6_Cout60_Out *cout60; /**< \brief CC60 compare output COUT0 */
|
||||
IFX_CONST IfxCcu6_Cout61_Out *cout61; /**< \brief CC61 compare output COUT1 */
|
||||
IFX_CONST IfxCcu6_Cout62_Out *cout62; /**< \brief CC62 compare output COUT2 */
|
||||
IFX_CONST IfxCcu6_Cout63_Out *cout63; /**< \brief CC63 compare output COUT3 */
|
||||
IfxPort_OutputMode outputMode; /**< \brief The pin output mode which should be configured */
|
||||
IfxPort_PadDriver pinDriver; /**< \brief pad driver */
|
||||
IFX_CONST IfxCcu6_T12hr_In *t12hr; /**< \brief T12HR input signal */
|
||||
IFX_CONST IfxCcu6_T13hr_In *t13hr; /**< \brief T13HR input signal */
|
||||
IfxPort_InputMode t1xhrInputMode; /**< \brief The T1xHR pin input mode which should be configured */
|
||||
} IfxCcu6_TPwm_Pins;
|
||||
|
||||
/** \brief Structure for Timer 12
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_TimerInputClock clockInput; /**< \brief Input clock selection (prescaler) */
|
||||
IfxCcu6_T12Channel channelId; /**< \brief Capture compare channel of the Timer12 */
|
||||
IfxCcu6_T12ChannelMode channelMode; /**< \brief The operating mode for the T12 channel */
|
||||
IfxCcu6_T12CountMode countMode; /**< \brief Operating mode of Timer 12 */
|
||||
uint16 counterValue; /**< \brief 16-bit counter value of Timer12 */
|
||||
uint8 deadTimeValue; /**< \brief Value of the dead time to be induced */
|
||||
uint16 compareValue; /**< \brief 16-bit comapre value of Timer12 */
|
||||
} IfxCcu6_TPwm_Timer12;
|
||||
|
||||
/** \brief Structure for Timer 13
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_TimerInputClock clockInput; /**< \brief Input clock selection (prescaler) */
|
||||
uint16 counterValue; /**< \brief 16-bit counter value of Timer13 */
|
||||
uint16 compareValue; /**< \brief 16-bit comapre value of Timer12 */
|
||||
IfxCcu6_T13TriggerEvent t12SyncEvent; /**< \brief T12 sync trigger event to start T13 */
|
||||
IfxCcu6_T13TriggerDirection t12SyncDirection; /**< \brief Additional information to control trigger event selection */
|
||||
} IfxCcu6_TPwm_Timer13;
|
||||
|
||||
/** \brief Configuration structure for external triggers
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_T12hr_In *t12ExtInputTrigger; /**< \brief External trigger input signal selection to start the timer 12 */
|
||||
IfxCcu6_T13hr_In *t13ExtInputTrigger; /**< \brief External trigger input signal selection to start the timer 13 */
|
||||
IfxCcu6_ExternalTriggerMode extInputTriggerMode; /**< \brief Event of signal T1xHR that can set the run bit T1xR by HW */
|
||||
boolean t13InSyncWithT12; /**< \brief Selection of Timer 13 start in sync with T12 */
|
||||
boolean outputTriggerEnabled; /**< \brief Output trigger connection to VADC enable / disable choice */
|
||||
IfxCcu6_TrigOut outputLine; /**< \brief Trigger out selection */
|
||||
IfxCcu6_TrigSel outputTrigger; /**< \brief Output Trigger selection */
|
||||
} IfxCcu6_TPwm_TriggerConfig;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_TPwm_DataStructures
|
||||
* \{ */
|
||||
/** \brief Module handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
TPwm base; /**< \brief Base TPWM object */
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
IfxCcu6_TimerId timer; /**< \brief Timer number (T12 / T13) */
|
||||
IfxCcu6_ChannelOut channelOut; /**< \brief Capture compare output pin selection */
|
||||
IfxCcu6_TPwm_TriggerConfig trigger; /**< \brief Structure for trigger configuration */
|
||||
} IfxCcu6_TPwm;
|
||||
|
||||
/** \brief Configuration structure of the module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
TPwm_Config base; /**< \brief Base configuration */
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
IfxCcu6_TimerId timer; /**< \brief Timer number (T12 / T13) */
|
||||
IfxCcu6_TPwm_Clock clock; /**< \brief Structure for clock configuration */
|
||||
IfxCcu6_TPwm_Timer12 timer12; /**< \brief Structure for Timer 12 */
|
||||
IfxCcu6_TPwm_Timer13 timer13; /**< \brief Structure for Timer 13 */
|
||||
IfxCcu6_ChannelOut channelOut; /**< \brief Capture compare output pin selection */
|
||||
IfxCcu6_TPwm_Pins *pins; /**< \brief Structure for CCU6 output pin configuration */
|
||||
IfxCcu6_TPwm_InterruptConfig interrupt1; /**< \brief Structure for first interrupt configuration */
|
||||
IfxCcu6_TPwm_InterruptConfig interrupt2; /**< \brief Structure for second interrupt configuration */
|
||||
IfxCcu6_TPwm_InterruptConfig interrupt3; /**< \brief Structure for third interrupt configuration */
|
||||
IfxCcu6_TPwm_InterruptConfig interrupt4; /**< \brief Structure for fourth interrupt configuration */
|
||||
IfxCcu6_TPwm_TriggerConfig trigger; /**< \brief Structure for trigger configuration */
|
||||
} IfxCcu6_TPwm_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_TPwm_Module_Initialize_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Fills the config structure with default values
|
||||
* \param config Configuration structure of the module
|
||||
* \param ccu6 Pointer to the base of CCU6 registers
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_TPwm_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TPwm_initModuleConfig(IfxCcu6_TPwm_Config *config, Ifx_CCU6 *ccu6);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_TPwm_Modultion_Control_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialises the module with default configuration
|
||||
* \param tPwm Module handle
|
||||
* \param config Configuration structure of the module
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_TPwm_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TPwm_initModule(IfxCcu6_TPwm *tPwm, const IfxCcu6_TPwm_Config *config);
|
||||
|
||||
/** \brief Pauses the triggered PWM
|
||||
* \param tPwm Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_TPwm_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TPwm_pause(IfxCcu6_TPwm *tPwm);
|
||||
|
||||
/** \brief Resumes the triggered PWM
|
||||
* \param tPwm Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_TPwm_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TPwm_resume(IfxCcu6_TPwm *tPwm);
|
||||
|
||||
/** \brief Starts the triggered PWM
|
||||
* \param tPwm Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_TPwm_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TPwm_start(IfxCcu6_TPwm *tPwm);
|
||||
|
||||
/** \brief Stops the triggered PWM
|
||||
* \param tPwm Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_TPwm_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TPwm_stop(IfxCcu6_TPwm *tPwm);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXCCU6_TPWM_H */
|
||||
@@ -0,0 +1,544 @@
|
||||
/**
|
||||
* \file IfxCcu6_Timer.c
|
||||
* \brief CCU6 TIMER details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxCcu6_Timer.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxCcu6_Timer_countOneStep(IfxCcu6_Timer *timer)
|
||||
{
|
||||
if (timer->timer == IfxCcu6_TimerId_t13)
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(timer->ccu6, FALSE, TRUE);
|
||||
|
||||
// enable manual counting mode
|
||||
IfxCcu6_setCountingInputMode(timer->ccu6, IfxCcu6_TimerId_t13, IfxCcu6_CountingInputMode_manual);
|
||||
IfxCcu6_enableCountEvent(timer->ccu6, FALSE, TRUE);
|
||||
}
|
||||
else if (timer->timer == IfxCcu6_TimerId_t12)
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(timer->ccu6, TRUE, FALSE);
|
||||
|
||||
// enable manual counting mode
|
||||
IfxCcu6_setCountingInputMode(timer->ccu6, IfxCcu6_TimerId_t12, IfxCcu6_CountingInputMode_manual);
|
||||
IfxCcu6_enableCountEvent(timer->ccu6, TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Timer_initModule(IfxCcu6_Timer *timer, const IfxCcu6_Timer_Config *config)
|
||||
{
|
||||
Ifx_CCU6 *ccu6SFR = config->ccu6; // pointer to CCU6 registers
|
||||
timer->ccu6 = ccu6SFR; // adding register pointer to module handler
|
||||
|
||||
/* -- hardware module initialisation -- */
|
||||
|
||||
// enable module if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_isModuleEnabled(ccu6SFR) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableModule(ccu6SFR);
|
||||
}
|
||||
|
||||
/* -- timer initialisation -- */
|
||||
|
||||
// Timer 13 initialisation //
|
||||
|
||||
if ((config->timer == IfxCcu6_TimerId_t13) || (config->synchronousOperation))
|
||||
{
|
||||
// enable Timer13 if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_getTimerAvailabilityStatus(ccu6SFR, IfxCcu6_TimerId_t13) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableTimer(ccu6SFR, IfxCcu6_TimerId_t13);
|
||||
}
|
||||
|
||||
// clock initialisation //
|
||||
|
||||
if (config->clock.t13ExtClockEnabled) // if external source is selected as reference
|
||||
{
|
||||
// input signal selection
|
||||
if (config->clock.t13ExtClockInput != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setT13InputSignal(config->ccu6, config->clock.t13ExtClockInput);
|
||||
}
|
||||
|
||||
// counting input mode selection
|
||||
IfxCcu6_setCountingInputMode(ccu6SFR, IfxCcu6_TimerId_t13, config->clock.t13countingInputMode);
|
||||
|
||||
// period setting
|
||||
IfxCcu6_setT13PeriodValue(ccu6SFR, (uint16)config->base.t13Period);
|
||||
}
|
||||
else // if internal clock is selected as reference
|
||||
{
|
||||
IfxCcu6_setT13Frequency(ccu6SFR, config->base.t13Frequency, config->base.t13Period);
|
||||
}
|
||||
|
||||
// counter initialisation //
|
||||
|
||||
IfxCcu6_setT13CounterValue(ccu6SFR, config->timer13.counterValue);
|
||||
|
||||
// if Timer 13 start is in sync with Timer 12 //
|
||||
if ((config->trigger.t13InSyncWithT12) && (!(config->synchronousOperation)))
|
||||
{
|
||||
IfxCcu6_setT13TriggerEventMode(ccu6SFR, config->timer13.t12SyncEvent);
|
||||
IfxCcu6_setT13TriggerEventDirection(ccu6SFR, config->timer13.t12SyncDirection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
// Timer 12 initialisation //
|
||||
|
||||
if ((config->timer == IfxCcu6_TimerId_t12) || (config->trigger.t13InSyncWithT12) || (config->synchronousOperation))
|
||||
{
|
||||
Ifx_TimerValue period = config->base.t12Period;
|
||||
|
||||
// enable Timer12 if it hasn't been enabled by any other interface //
|
||||
if (IfxCcu6_getTimerAvailabilityStatus(ccu6SFR, IfxCcu6_TimerId_t12) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableTimer(ccu6SFR, IfxCcu6_TimerId_t12);
|
||||
}
|
||||
|
||||
// if Timer 13 start is in sync with Timer 12 //
|
||||
if ((config->trigger.t13InSyncWithT12) && (!(config->synchronousOperation)) && (config->base.waitingTime != 0))
|
||||
{
|
||||
// if in sync with T12 period match (only period match is allowed in this interface because T12 is only in counter mode)
|
||||
if (config->timer13.t12SyncEvent == IfxCcu6_T13TriggerEvent_onT12Period)
|
||||
{
|
||||
period = config->base.waitingTime; // waiting time as period
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// configuration error
|
||||
}
|
||||
|
||||
// clock initialisation //
|
||||
|
||||
if (config->clock.t12ExtClockEnabled) // if external source is selected as reference
|
||||
{
|
||||
// input signal selection
|
||||
if (config->clock.t12ExtClockInput != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setT12InputSignal(config->ccu6, config->clock.t12ExtClockInput);
|
||||
}
|
||||
|
||||
// counting input mode selection
|
||||
IfxCcu6_setCountingInputMode(ccu6SFR, IfxCcu6_TimerId_t12, config->clock.t12countingInputMode);
|
||||
|
||||
// countining mode selection
|
||||
IfxCcu6_setT12CountMode(ccu6SFR, config->timer12.countMode);
|
||||
|
||||
// period selection for center aligned mode
|
||||
if (config->timer12.countMode == IfxCcu6_T12CountMode_centerAligned)
|
||||
{
|
||||
period = (period / 2) - 1;
|
||||
}
|
||||
|
||||
// period setting
|
||||
IfxCcu6_setT12PeriodValue(ccu6SFR, (uint16)period);
|
||||
}
|
||||
else // if internal clock is selected as reference
|
||||
{
|
||||
// in case of in sync with T13, T12 runs at same frequency as T13
|
||||
IfxCcu6_setT12Frequency(ccu6SFR, config->base.t12Frequency, period, config->timer12.countMode);
|
||||
}
|
||||
|
||||
// counter initialisation //
|
||||
|
||||
IfxCcu6_setT12CounterValue(ccu6SFR, config->timer12.counterValue);
|
||||
}
|
||||
|
||||
/* -- Pin mapping -- */
|
||||
|
||||
const IfxCcu6_Timer_Pins *pins = config->pins;
|
||||
|
||||
if (pins != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_T12hr_In *t12hr = pins->t12hr;
|
||||
|
||||
if (t12hr != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initT12hrPin(t12hr, pins->t1xhrInputMode);
|
||||
}
|
||||
|
||||
IfxCcu6_T13hr_In *t13hr = pins->t13hr;
|
||||
|
||||
if (t13hr != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_initT13hrPin(t13hr, pins->t1xhrInputMode);
|
||||
}
|
||||
}
|
||||
|
||||
/* -- interrupt initialisation -- */
|
||||
|
||||
if (config->interrupt1.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt1.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt1.source, config->interrupt1.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt1.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt1.typeOfService, config->interrupt1.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt2.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt2.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt2.source, config->interrupt2.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt2.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt2.typeOfService, config->interrupt2.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt3.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt3.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt3.source, config->interrupt3.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt3.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt3.typeOfService, config->interrupt3.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->interrupt4.priority > 0)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(config->ccu6, config->interrupt4.source);
|
||||
IfxCcu6_routeInterruptNode(config->ccu6, config->interrupt4.source, config->interrupt4.serviceRequest);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt4.serviceRequest);
|
||||
IfxSrc_init(src, config->interrupt4.typeOfService, config->interrupt4.priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
timer->timer = config->timer;
|
||||
timer->trigger = config->trigger;
|
||||
|
||||
#if IFX_CFG_USE_STANDARD_INTERFACE
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (uint32)timer == ((uint32)&timer->base));
|
||||
timer->base.functions.start = (Timer_Start) & IfxCcu6_Timer_start;
|
||||
timer->base.functions.stop = (Timer_Stop) & IfxCcu6_Timer_stop;
|
||||
timer->base.functions.synchronousStart = (Timer_SynchronousStart) & IfxCcu6_Timer_synchronousStart;
|
||||
timer->base.functions.synchronousStop = (Timer_SynchronousStop) & IfxCcu6_Timer_synchronousStop;
|
||||
timer->base.functions.countOneStep = (Timer_CountOneStep) & IfxCcu6_Timer_countOneStep;
|
||||
timer->base.functions.startSingleShotMode = (Timer_StartSingleShotMode) & IfxCcu6_Timer_startSingleShotMode;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Timer_initModuleConfig(IfxCcu6_Timer_Config *config, Ifx_CCU6 *ccu6)
|
||||
{
|
||||
const IfxCcu6_Timer_Config defaultConfig = {
|
||||
.base = {
|
||||
.t12Frequency = 400000,
|
||||
.t12Period = 100,
|
||||
.t13Frequency = 400000,
|
||||
.t13Period = 100,
|
||||
.waitingTime = 20,
|
||||
.activeCount = 0,
|
||||
},
|
||||
|
||||
.ccu6 = NULL_PTR, // will be initialized below
|
||||
|
||||
.timer = IfxCcu6_TimerId_t13,
|
||||
.synchronousOperation = FALSE,
|
||||
|
||||
.pins = NULL_PTR,
|
||||
|
||||
.clock = {
|
||||
.t12ExtClockEnabled = FALSE,
|
||||
.t12ExtClockInput = NULL_PTR,
|
||||
.t12countingInputMode = IfxCcu6_CountingInputMode_internal,
|
||||
|
||||
.t13ExtClockEnabled = FALSE,
|
||||
.t13ExtClockInput = NULL_PTR,
|
||||
.t13countingInputMode = IfxCcu6_CountingInputMode_internal,
|
||||
},
|
||||
|
||||
.timer12 = {
|
||||
.countMode = IfxCcu6_T12CountMode_edgeAligned,
|
||||
.counterValue = 0,
|
||||
},
|
||||
|
||||
.timer13 = {
|
||||
.counterValue = 0,
|
||||
.t12SyncEvent = IfxCcu6_T13TriggerEvent_onCC60RCompare,
|
||||
.t12SyncDirection = IfxCcu6_T13TriggerDirection_onT12CountingUp,
|
||||
},
|
||||
|
||||
.interrupt1 = {
|
||||
.source = IfxCcu6_InterruptSource_t12PeriodMatch,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_0,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.interrupt2 = {
|
||||
.source = IfxCcu6_InterruptSource_t13PeriodMatch,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_1,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.interrupt3 = {
|
||||
.source = IfxCcu6_InterruptSource_t12OneMatch,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_2,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.interrupt4 = {
|
||||
.source = IfxCcu6_InterruptSource_trap,
|
||||
.serviceRequest = IfxCcu6_ServiceRequest_3,
|
||||
.priority = 0, // interrupt priority 0
|
||||
.typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
|
||||
},
|
||||
|
||||
.trigger = {
|
||||
.t12ExtInputTrigger = NULL_PTR,
|
||||
.t13ExtInputTrigger = NULL_PTR,
|
||||
.extInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge,
|
||||
.t13InSyncWithT12 = TRUE,
|
||||
},
|
||||
};
|
||||
|
||||
/* Default Configuration */
|
||||
*config = defaultConfig;
|
||||
|
||||
/* take over module pointer */
|
||||
config->ccu6 = ccu6;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Timer_start(IfxCcu6_Timer *timer)
|
||||
{
|
||||
// Timer 13 start //
|
||||
|
||||
if (timer->timer == IfxCcu6_TimerId_t13)
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(timer->ccu6, FALSE, TRUE);
|
||||
|
||||
// start Timer 13 when not in sync with timer12
|
||||
if (!(timer->trigger.t13InSyncWithT12))
|
||||
{
|
||||
if (timer->trigger.t13ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
// external start
|
||||
IfxCcu6_setExternalRunMode(timer->ccu6, IfxCcu6_TimerId_t13, timer->trigger.extInputTriggerMode);
|
||||
IfxCcu6_setT13InputSignal(timer->ccu6, timer->trigger.t13ExtInputTrigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
// internal start
|
||||
IfxCcu6_startTimer(timer->ccu6, FALSE, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
// Timer 12 start alone or when in sync with Timer 13 //
|
||||
|
||||
if ((timer->timer == IfxCcu6_TimerId_t12) || (timer->trigger.t13InSyncWithT12))
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(timer->ccu6, TRUE, FALSE);
|
||||
|
||||
//start Timer 12
|
||||
if (timer->trigger.t12ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
// external start
|
||||
IfxCcu6_setExternalRunMode(timer->ccu6, IfxCcu6_TimerId_t12, timer->trigger.extInputTriggerMode);
|
||||
IfxCcu6_setT12InputSignal(timer->ccu6, timer->trigger.t12ExtInputTrigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
// internal start
|
||||
IfxCcu6_startTimer(timer->ccu6, TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Timer_startSingleShotMode(IfxCcu6_Timer *timer)
|
||||
{
|
||||
// Timer 13 start //
|
||||
|
||||
if (timer->timer == IfxCcu6_TimerId_t13)
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(timer->ccu6, FALSE, TRUE);
|
||||
|
||||
//enable single shot mode
|
||||
IfxCcu6_enableSingleShotMode(timer->ccu6, IfxCcu6_TimerId_t13);
|
||||
|
||||
// start Timer 13 when not in sync with timer12
|
||||
if (!(timer->trigger.t13InSyncWithT12))
|
||||
{
|
||||
if (timer->trigger.t13ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
// external start
|
||||
IfxCcu6_setExternalRunMode(timer->ccu6, IfxCcu6_TimerId_t13, timer->trigger.extInputTriggerMode);
|
||||
IfxCcu6_setT13InputSignal(timer->ccu6, timer->trigger.t13ExtInputTrigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
// internal start
|
||||
IfxCcu6_startTimer(timer->ccu6, FALSE, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
// Timer 12 start alone or when in sync with Timer 13 //
|
||||
|
||||
if ((timer->timer == IfxCcu6_TimerId_t12) || (timer->trigger.t13InSyncWithT12))
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(timer->ccu6, TRUE, FALSE);
|
||||
|
||||
//enable single shot mode
|
||||
IfxCcu6_enableSingleShotMode(timer->ccu6, IfxCcu6_TimerId_t12);
|
||||
|
||||
if (timer->trigger.t12ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
// external start
|
||||
IfxCcu6_setExternalRunMode(timer->ccu6, IfxCcu6_TimerId_t12, timer->trigger.extInputTriggerMode);
|
||||
IfxCcu6_setT12InputSignal(timer->ccu6, timer->trigger.t12ExtInputTrigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
// internal start
|
||||
IfxCcu6_startTimer(timer->ccu6, TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Timer_stop(IfxCcu6_Timer *timer)
|
||||
{
|
||||
// Timer 13 stop //
|
||||
|
||||
if ((timer->timer == IfxCcu6_TimerId_t13) || (timer->trigger.t13InSyncWithT12))
|
||||
{
|
||||
// disable shadow transfer
|
||||
IfxCcu6_disableShadowTransfer(timer->ccu6, FALSE, TRUE);
|
||||
|
||||
// remove external input trigger if any
|
||||
if (timer->trigger.t13ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setExternalRunMode(timer->ccu6, IfxCcu6_TimerId_t13, IfxCcu6_ExternalTriggerMode_disable);
|
||||
}
|
||||
|
||||
// remove the sync with Timer 12
|
||||
if (timer->trigger.t13InSyncWithT12)
|
||||
{
|
||||
IfxCcu6_setT13TriggerEventMode(timer->ccu6, IfxCcu6_T13TriggerEvent_noAction);
|
||||
IfxCcu6_setT13TriggerEventDirection(timer->ccu6, IfxCcu6_T13TriggerDirection_noAction);
|
||||
}
|
||||
|
||||
// stop Timer 13
|
||||
IfxCcu6_stopTimer(timer->ccu6, FALSE, TRUE);
|
||||
}
|
||||
|
||||
// Timer 12 stop //
|
||||
|
||||
else
|
||||
{
|
||||
// disable shadow transfer
|
||||
IfxCcu6_disableShadowTransfer(timer->ccu6, TRUE, FALSE);
|
||||
|
||||
// remove external input trigger if any
|
||||
if (timer->trigger.t12ExtInputTrigger != NULL_PTR)
|
||||
{
|
||||
IfxCcu6_setExternalRunMode(timer->ccu6, IfxCcu6_TimerId_t12, IfxCcu6_ExternalTriggerMode_disable);
|
||||
}
|
||||
|
||||
// stop Timer 12
|
||||
IfxCcu6_stopTimer(timer->ccu6, TRUE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Timer_synchronousStart(IfxCcu6_Timer *timer)
|
||||
{
|
||||
// enable shadow transfer
|
||||
IfxCcu6_enableShadowTransfer(timer->ccu6, TRUE, TRUE);
|
||||
|
||||
// only internal synchronous start is possible
|
||||
IfxCcu6_startTimer(timer->ccu6, TRUE, TRUE);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_Timer_synchronousStop(IfxCcu6_Timer *timer)
|
||||
{
|
||||
// disable shadow transfer
|
||||
IfxCcu6_disableShadowTransfer(timer->ccu6, TRUE, TRUE);
|
||||
|
||||
// only internal synchronous stop is possible
|
||||
IfxCcu6_stopTimer(timer->ccu6, TRUE, TRUE);
|
||||
}
|
||||
@@ -0,0 +1,417 @@
|
||||
/**
|
||||
* \file IfxCcu6_Timer.h
|
||||
* \brief CCU6 TIMER details
|
||||
* \ingroup IfxLld_Ccu6
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_Timer_Usage How to use the CCU6 TIMER Interface driver?
|
||||
* \ingroup IfxLld_Ccu6_Timer
|
||||
*
|
||||
* The TIMER interface driver provides a default CCU6 configuration for runnung the selected timer block.
|
||||
*
|
||||
* User can select the various configuration options that hardware allows
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Ccu6_Timer_Preparation Preparation
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_Timer_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
*
|
||||
* \code
|
||||
* #include <Ccu6/Timer/IfxCcu6_Timer.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_Timer_Variables Variables
|
||||
*
|
||||
* Declare the TIMER handle as global variable in your C code:
|
||||
*
|
||||
* \code
|
||||
* // used globally
|
||||
* static IfxCcu6_Timer timer;
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_Timer_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priority for the Interrrupt handler. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
*
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define IFX_INTPRIO_CCU6 1
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routine to your C code.
|
||||
*
|
||||
* \code
|
||||
* IFX_INTERRUPT(ccu60ISR_Timer, 0, IFX_INTPRIO_CCU6)
|
||||
* {
|
||||
* //user code
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handlers in your initialisation function:
|
||||
*
|
||||
* \code
|
||||
* // install interrupt handlers
|
||||
* IfxCpu_Irq_installInterruptHandler(&ccu60ISR_Timer, IFX_INTPRIO_CCU6);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Ccu6_Timer_Init Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function. Here an example:
|
||||
*
|
||||
* \code
|
||||
* // create configuration
|
||||
* IfxCcu6_Timer_Config timerConfig;
|
||||
* IfxCcu6_Timer_initModuleConfig(&timerConfig, &MODULE_CCU60);
|
||||
*
|
||||
* // configure the frequency of the timer in case of internal start
|
||||
* // this frequency will be set for the timer block selected later
|
||||
* timerConfig.base.frequency = 400000;
|
||||
*
|
||||
* // configure the period of the timer
|
||||
* timerConfig.base.period = 100;
|
||||
*
|
||||
* // configure the waiting time in case of delayed T13 start in sync with T12
|
||||
* timerConfig.base.waitingTime = 0;
|
||||
*
|
||||
* // select the timer that needs to be started
|
||||
* timerConfig.timer = IfxCcu6_TimerId_t12;
|
||||
*
|
||||
* // select the synchronous operation if both timers need to be start at the same time
|
||||
* // previous selection of timer block can be ignored in this mode
|
||||
* timerConfig.synchronousOperation = TRUE;
|
||||
*
|
||||
* // configure the clock for internal mode
|
||||
* timerConfig.clock.t12ExtClockEnabled = FALSE;
|
||||
* timerConfig.clock.t12ExtClockInput = NULL_PTR;
|
||||
* timerConfig.clock.t12countingInputMode = IfxCcu6_CountingInputMode_internal;
|
||||
*
|
||||
* // configure the selcted timer block
|
||||
* timerConfig.timer12.countMode = IfxCcu6_T12CountMode_edgeAligned;
|
||||
* timerConfig.timer12.counterValue = 0;
|
||||
*
|
||||
* // configure the interrupts
|
||||
* timerConfig.interrupt1.interruptSource = IfxCcu6_InterruptSource_t12PeriodMatch;
|
||||
* timerConfig.interrupt1.serviceRequest = IfxCcu6_ServiceRequest_2;
|
||||
* timerConfig.interrupt1.priority = IFX_INTRPRIO_CCU6;
|
||||
* timerConfig.interrupt1.typeOfService = IfxSrc_Tos_cpu0;
|
||||
*
|
||||
* // configure input and output triggers
|
||||
* timerConfig.trigger.t12ExtInputTrigger = IfxCcu60_T12HRB_P00_7_IN;
|
||||
* timerConfig.trigger.t13ExtInputTrigger = NULL_PTR;
|
||||
* timerConfig.trigger.extInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge;
|
||||
* timerConfig.trigger.t13InSyncWithT12 = FALSE;
|
||||
*
|
||||
* // initialize the module
|
||||
* IfxCcu6_Timer_initModule(&timer, &timerConfig);
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* The Timer is ready for use now!
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Ccu6_Timer_Control Control
|
||||
*
|
||||
*
|
||||
* The TIMER driver provides simple to use timer Control functions
|
||||
*
|
||||
* This means: In addition to start and stop a single timer, you can start and stop both the timer blocks at the same time
|
||||
* you can also run the timer in single shot mode and finally you an manually make the timer count each step
|
||||
*
|
||||
* Start the timer
|
||||
*
|
||||
* \code
|
||||
* IfxCcu6_Timer_start(&timer);
|
||||
* \endcode
|
||||
*
|
||||
* Stop the timer
|
||||
*
|
||||
* \code
|
||||
* IfxCcu6_Timer_stop(&timer);
|
||||
* \endcode
|
||||
*
|
||||
* Start both the timers synchronously, when the synchronousOperation mode is selected in the configuration
|
||||
*
|
||||
* \code
|
||||
* IfxCcu6_Timer_synchronousStart(&timer);
|
||||
* \endcode
|
||||
*
|
||||
* Stop both the timers synchronously, when the synchronousOperation mode is selected in the configuration
|
||||
*
|
||||
* \code
|
||||
* IfxCcu6_Timer_synchronousStop(&timer);
|
||||
* \endcode
|
||||
*
|
||||
* Start the selected timer in single shot mode
|
||||
*
|
||||
* \code
|
||||
* IfxCcu6_Timer_startSingleShotMode(&timer);
|
||||
* \endcode
|
||||
*
|
||||
* Make the timer count each step manually
|
||||
*
|
||||
* \code
|
||||
* uint8 i;
|
||||
* for (i=0; i<50; i++)
|
||||
* {
|
||||
* IfxCcu6_Timer_countOneStep(&timer);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_Timer TIMER Interface driver
|
||||
* \ingroup IfxLld_Ccu6
|
||||
* \defgroup IfxLld_Ccu6_Timer_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Ccu6_Timer
|
||||
* \defgroup IfxLld_Ccu6_Timer_Module_Initialize_Functions Module Initialize Functions
|
||||
* \ingroup IfxLld_Ccu6_Timer
|
||||
* \defgroup IfxLld_Ccu6_Timer_Timer_Control_Functions Timer Control Functions
|
||||
* \ingroup IfxLld_Ccu6_Timer
|
||||
*/
|
||||
|
||||
#ifndef IFXCCU6_TIMER_H
|
||||
#define IFXCCU6_TIMER_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Ccu6/Std/IfxCcu6.h"
|
||||
#include "If/Ccu6If/Timer.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_Timer_DataStructures
|
||||
* \{ */
|
||||
/** \brief Structure for clock configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean t12ExtClockEnabled; /**< \brief Timer 12 external clock enable / disable selection */
|
||||
IfxCcu6_T12hr_In *t12ExtClockInput; /**< \brief External input signal selection for timer 12 */
|
||||
IfxCcu6_CountingInputMode t12countingInputMode; /**< \brief Input event leading to a counting action of the timer T12 */
|
||||
boolean t13ExtClockEnabled; /**< \brief Timer 13 external clock enable / disable selection */
|
||||
IfxCcu6_T13hr_In *t13ExtClockInput; /**< \brief External input signal selection for timer 13 */
|
||||
IfxCcu6_CountingInputMode t13countingInputMode; /**< \brief Input event leading to a counting action of the timer T13 */
|
||||
} IfxCcu6_Timer_Clock;
|
||||
|
||||
/** \brief Structure for interrupt configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_InterruptSource source; /**< \brief Interrupt source selection */
|
||||
IfxCcu6_ServiceRequest serviceRequest; /**< \brief Selection of service request outputs */
|
||||
uint16 priority; /**< \brief Interrupt priority */
|
||||
IfxSrc_Tos typeOfService; /**< \brief type of interrupt service */
|
||||
} IfxCcu6_Timer_InterruptConfig;
|
||||
|
||||
/** \brief Structure for Timer 12
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_T12CountMode countMode; /**< \brief Operating mode of Timer 12 */
|
||||
uint16 counterValue; /**< \brief 16-bit counter value of Timer12 */
|
||||
} IfxCcu6_Timer_Timer12;
|
||||
|
||||
/** \brief Structure for Timer 13
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 counterValue; /**< \brief 16-bit counter value of Timer13 */
|
||||
IfxCcu6_T13TriggerEvent t12SyncEvent; /**< \brief T12 sync trigger event to start T13 */
|
||||
IfxCcu6_T13TriggerDirection t12SyncDirection; /**< \brief Additional information to control trigger event selection */
|
||||
} IfxCcu6_Timer_Timer13;
|
||||
|
||||
/** \brief Configuration structure for external triggers
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_T12hr_In *t12ExtInputTrigger; /**< \brief External input signal selection for timer 12 */
|
||||
IfxCcu6_T13hr_In *t13ExtInputTrigger; /**< \brief External input signal selection for timer 13 */
|
||||
IfxCcu6_ExternalTriggerMode extInputTriggerMode; /**< \brief Event of signal T1xHR that can set the run bit T1xR by HW */
|
||||
boolean t13InSyncWithT12; /**< \brief Selection of Timer 13 start in sync with T12 */
|
||||
} IfxCcu6_Timer_TriggerConfig;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \brief Structure for CCU6 output pin configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IFX_CONST IfxCcu6_T12hr_In *t12hr; /**< \brief T12HR input signal */
|
||||
IFX_CONST IfxCcu6_T13hr_In *t13hr; /**< \brief T13HR input signal */
|
||||
IfxPort_InputMode t1xhrInputMode; /**< \brief The T1xHR pin input mode which should be configured */
|
||||
} IfxCcu6_Timer_Pins;
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_Timer_DataStructures
|
||||
* \{ */
|
||||
/** \brief Module handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Timer base; /**< \brief Base Timer object */
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
IfxCcu6_TimerId timer; /**< \brief Timer number (T12 / T13) */
|
||||
IfxCcu6_Timer_TriggerConfig trigger; /**< \brief Structure for trigger configuration */
|
||||
} IfxCcu6_Timer;
|
||||
|
||||
/** \brief Configuration structure of the module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Timer_Config base; /**< \brief Base configuration */
|
||||
Ifx_CCU6 *ccu6; /**< \brief Pointer to the base of CCU6 registers */
|
||||
IfxCcu6_TimerId timer; /**< \brief Timer number (T12 / T13) */
|
||||
boolean synchronousOperation; /**< \brief Synchronous operation selection (starting / stopping both the timers at the same time) */
|
||||
IfxCcu6_Timer_Clock clock; /**< \brief Structure for clock configuration */
|
||||
IfxCcu6_Timer_Timer12 timer12; /**< \brief Structure for Timer 12 */
|
||||
IfxCcu6_Timer_Timer13 timer13; /**< \brief Structure for Timer 13 */
|
||||
IfxCcu6_Timer_InterruptConfig interrupt1; /**< \brief Structure for first interrupt configuration */
|
||||
IfxCcu6_Timer_InterruptConfig interrupt2; /**< \brief Structure for second interrupt configuration */
|
||||
IfxCcu6_Timer_InterruptConfig interrupt3; /**< \brief Structure for third interrupt configuration */
|
||||
IfxCcu6_Timer_InterruptConfig interrupt4; /**< \brief Structure for fourth interrupt configuration */
|
||||
IfxCcu6_Timer_TriggerConfig trigger; /**< \brief Structure for trigger configuration */
|
||||
IfxCcu6_Timer_Pins *pins; /**< \brief Structure for CCU6 output pin configuration */
|
||||
} IfxCcu6_Timer_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_Timer_Module_Initialize_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialises the module with default configuration
|
||||
* \param timer Module handle
|
||||
* \param config Configuration structure of the module
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Timer_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Timer_initModule(IfxCcu6_Timer *timer, const IfxCcu6_Timer_Config *config);
|
||||
|
||||
/** \brief Fills the config structure with default values
|
||||
* \param config Configuration structure of the module
|
||||
* \param ccu6 Pointer to the base of CCU6 registers
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Timer_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Timer_initModuleConfig(IfxCcu6_Timer_Config *config, Ifx_CCU6 *ccu6);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_Timer_Timer_Control_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Counts the timer one step
|
||||
* \param timer Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Timer_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Timer_countOneStep(IfxCcu6_Timer *timer);
|
||||
|
||||
/** \brief Starts the timer
|
||||
* \param timer Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Timer_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Timer_start(IfxCcu6_Timer *timer);
|
||||
|
||||
/** \brief Starts the single shot mode of the timer
|
||||
* \param timer Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Timer_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Timer_startSingleShotMode(IfxCcu6_Timer *timer);
|
||||
|
||||
/** \brief Stops the timer
|
||||
* \param timer Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Timer_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Timer_stop(IfxCcu6_Timer *timer);
|
||||
|
||||
/** \brief Starts both the timers together
|
||||
* \param timer Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Timer_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Timer_synchronousStart(IfxCcu6_Timer *timer);
|
||||
|
||||
/** \brief Starts both the timers together
|
||||
* \param timer Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Ccu6_Timer_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_Timer_synchronousStop(IfxCcu6_Timer *timer);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXCCU6_TIMER_H */
|
||||
+379
@@ -0,0 +1,379 @@
|
||||
/**
|
||||
* \file IfxCcu6_TimerWithTrigger.c
|
||||
* \brief CCU6 TIMERWITHTRIGGER details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxCcu6_TimerWithTrigger.h"
|
||||
#include "_Utilities/Ifx_Assert.h"
|
||||
#include "stddef.h"
|
||||
#include "string.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
boolean IfxCcu6_TimerWithTrigger_acknowledgeTimerIrq(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
boolean event;
|
||||
event = IfxCcu6_isT12OneNotification(driver->ccu6);
|
||||
|
||||
if (event)
|
||||
{
|
||||
IfxCcu6_clearT12OneNotification(driver->ccu6);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_TimerWithTrigger_acknowledgeTriggerIrq(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
boolean event;
|
||||
event = IfxCcu6_isT13CompareNotification(driver->ccu6);
|
||||
|
||||
if (event)
|
||||
{
|
||||
IfxCcu6_clearT13CompareNotification(driver->ccu6);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TimerWithTrigger_applyUpdate(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
IfxCcu6_enableShadowTransfer(driver->ccu6, TRUE, TRUE);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TimerWithTrigger_disableUpdate(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(driver)
|
||||
}
|
||||
|
||||
|
||||
float32 IfxCcu6_TimerWithTrigger_getFrequency(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
return 1.0 / IfxStdIf_Timer_tickToS(driver->base.clockFreq, driver->base.period);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxCcu6_TimerWithTrigger_getInputFrequency(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
return driver->base.clockFreq;
|
||||
}
|
||||
|
||||
|
||||
Ifx_TimerValue IfxCcu6_TimerWithTrigger_getPeriod(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
return driver->base.period;
|
||||
}
|
||||
|
||||
|
||||
volatile uint32 *IfxCcu6_TimerWithTrigger_getPointer(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
return IfxCcu6_getT12TimerPointer(driver->ccu6);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxCcu6_TimerWithTrigger_getResolution(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
return 1.0 / driver->base.clockFreq;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_TimerWithTrigger_init(IfxCcu6_TimerWithTrigger *driver, IfxCcu6_TimerWithTrigger_Config *config)
|
||||
{
|
||||
boolean result = TRUE;
|
||||
IfxCcu6_TimerWithTrigger_Base *base = &driver->base;
|
||||
Ifx_CCU6 *module;
|
||||
|
||||
driver->ccu6 = config->ccu6;
|
||||
module = driver->ccu6;
|
||||
|
||||
base->triggerEnabled = config->base.trigger.enabled;
|
||||
|
||||
/** - Enable/initialise the CCU6 if it has not been enabled. See IfxCcu6_isModuleEnabled() */
|
||||
if (IfxCcu6_isModuleEnabled(module) == FALSE)
|
||||
{
|
||||
IfxCcu6_enableModule(module);
|
||||
}
|
||||
|
||||
/* Initialize the timer part */
|
||||
IfxCcu6_setT12CountMode(module, (config->base.countDir == IfxStdIf_Timer_CountDir_upAndDown) ? IfxCcu6_T12CountMode_centerAligned : IfxCcu6_T12CountMode_edgeAligned);
|
||||
|
||||
driver->base.countDir = config->base.countDir;
|
||||
|
||||
uint16 prescaler;
|
||||
float32 freqT12 = 0, periodT12;
|
||||
float32 freqCC6 = (float32)IfxScuCcu_getSpbFrequency();
|
||||
|
||||
for (prescaler = 0; prescaler < 16; prescaler++)
|
||||
{
|
||||
freqT12 = freqCC6 / (1U << prescaler);
|
||||
periodT12 = freqT12 / config->base.frequency;
|
||||
|
||||
if ((periodT12 <= 16386.0) && (periodT12 > config->base.minResolution))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (prescaler < 16)
|
||||
{
|
||||
Ifx_CCU6_TCTR0 tctr0;
|
||||
tctr0.U = module->TCTR0.U;
|
||||
tctr0.B.T12CLK = (prescaler & 0x7U);
|
||||
tctr0.B.T12PRE = ((prescaler & 0x8U) != 0);
|
||||
module->TCTR0.U = tctr0.U;
|
||||
}
|
||||
else
|
||||
{
|
||||
/** \retval IfxCcu6_Stat_wrongPwmFreq if the T12 prescaler can't fulfill the
|
||||
* required frequency */
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
IfxCcu6_TimerWithTrigger_updateInputFrequency(driver);
|
||||
|
||||
if ((config->base.minResolution > 0) && ((1.0 / base->clockFreq) > config->base.minResolution))
|
||||
{
|
||||
result = FALSE;
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, FALSE);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
IfxCcu6_TimerWithTrigger_setFrequency(driver, config->base.frequency);
|
||||
/* Initialize the trigger part */
|
||||
|
||||
/** - The T13 is used to generate additional PWM for internal trigger purpose (e.g.
|
||||
* ADC) or external trigger purpose (e.g. sensor synchronisation). */
|
||||
|
||||
if (base->triggerEnabled)
|
||||
{
|
||||
Ifx_CCU6_TCTR0 tctr0 = module->TCTR0;
|
||||
module->TCTR0.B.T13CLK = tctr0.B.T12CLK;
|
||||
module->TCTR0.B.T13PRE = tctr0.B.T12PRE;
|
||||
IfxCcu6_setT13PeriodValue(module, (uint16)(base->period - 1));
|
||||
|
||||
module->MODCTR.B.T13MODEN = 0;
|
||||
IfxCcu6_enableModulationOutput(module, IfxCcu6_TimerId_t13, IfxCcu6_ChannelOut_cout3);
|
||||
|
||||
IfxCcu6_setOutputPassiveLevel(module, IfxCcu6_ChannelOut_cout3, config->base.trigger.risingEdgeAtPeriod);
|
||||
|
||||
IfxCcu6_setSingleShotModeEnable(module, FALSE, TRUE);
|
||||
|
||||
IfxCcu6_setT13TriggerEventMode(module, IfxCcu6_T13TriggerEvent_onT12Zero);
|
||||
IfxCcu6_setT13TriggerEventDirection(module, IfxCcu6_T13TriggerDirection_onT12CountingUp);
|
||||
|
||||
if (config->base.trigger.outputEnabled)
|
||||
{
|
||||
if (config->triggerOut != NULL_PTR)
|
||||
{
|
||||
/*Initialize the port */
|
||||
IfxCcu6_initCout63Pin(config->triggerOut, config->base.trigger.outputMode, config->base.trigger.outputDriver);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
IfxCcu6_TimerWithTrigger_setTrigger(driver, config->base.trigger.triggerPoint);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
/* Interrupt configuration */
|
||||
{
|
||||
boolean timerHasIrq = config->base.isrPriority > 0;
|
||||
boolean triggerHasIrq = (config->base.trigger.isrPriority > 0) && base->triggerEnabled;
|
||||
|
||||
if (timerHasIrq || triggerHasIrq)
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
|
||||
IfxCcu6_clearInterruptStatusFlag(module, IfxCcu6_InterruptSource_t12PeriodMatch);
|
||||
IfxCcu6_clearInterruptStatusFlag(module, IfxCcu6_InterruptSource_t12OneMatch);
|
||||
IfxCcu6_clearInterruptStatusFlag(module, IfxCcu6_InterruptSource_t13CompareMatch);
|
||||
|
||||
if (timerHasIrq)
|
||||
{
|
||||
if (config->base.countDir == IfxStdIf_Timer_CountDir_upAndDown)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(module, IfxCcu6_InterruptSource_t12OneMatch); /* full period */
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxCcu6_enableInterrupt(module, IfxCcu6_InterruptSource_t12PeriodMatch); /* half-period*/
|
||||
}
|
||||
|
||||
module->INP.B.INPT12 = config->serviceReqNrPeriod;
|
||||
src = IfxCcu6_getSrcAddress(module, config->serviceReqNrPeriod);
|
||||
IfxSrc_init(src, config->base.isrProvider, config->base.isrPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (triggerHasIrq)
|
||||
{
|
||||
IfxCcu6_enableInterrupt(module, IfxCcu6_InterruptSource_t13CompareMatch); /* trigger event */
|
||||
module->INP.B.INPT13 = config->serviceReqNrTrigger;
|
||||
|
||||
src = IfxCcu6_getSrcAddress(module, config->serviceReqNrTrigger);
|
||||
IfxSrc_init(src, config->base.trigger.isrProvider, config->base.trigger.isrPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer the shadow registers */
|
||||
IfxCcu6_TimerWithTrigger_applyUpdate(driver);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TimerWithTrigger_initConfig(IfxCcu6_TimerWithTrigger_Config *config, Ifx_CCU6 *ccu6)
|
||||
{
|
||||
IfxStdIf_Timer_initConfig(&config->base);
|
||||
config->ccu6 = ccu6;
|
||||
config->serviceReqNrPeriod = IfxCcu6_ServiceRequest_0;
|
||||
config->serviceReqNrTrigger = IfxCcu6_ServiceRequest_1;
|
||||
config->triggerOut = NULL_PTR;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TimerWithTrigger_run(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
IfxCcu6_startTimer(driver->ccu6, TRUE, FALSE);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_TimerWithTrigger_setFrequency(IfxCcu6_TimerWithTrigger *driver, float32 frequency)
|
||||
{
|
||||
Ifx_TimerValue period = IfxStdIf_Timer_sToTick(driver->base.clockFreq, 1.0 / frequency);
|
||||
|
||||
return IfxCcu6_TimerWithTrigger_setPeriod(driver, period);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_TimerWithTrigger_setPeriod(IfxCcu6_TimerWithTrigger *driver, Ifx_TimerValue period)
|
||||
{
|
||||
driver->base.period = period;
|
||||
IfxCcu6_setT12PeriodValue(driver->ccu6, (uint16)((driver->ccu6->TCTR0.B.CTM == 1) ?
|
||||
((period / 2) - 1) : (period - 1)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TimerWithTrigger_setSingleMode(IfxCcu6_TimerWithTrigger *driver, boolean enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
IfxCcu6_enableSingleShotMode(driver->ccu6, IfxCcu6_TimerId_t12);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxCcu6_disableSingleShotMode(driver->ccu6, IfxCcu6_TimerId_t12);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TimerWithTrigger_setTrigger(IfxCcu6_TimerWithTrigger *driver, Ifx_TimerValue triggerPoint)
|
||||
{
|
||||
driver->ccu6->CC63SR.U = triggerPoint;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCcu6_TimerWithTrigger_stdIfTimerInit(IfxStdIf_Timer *stdif, IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
/* Ensure the stdif is reset to zeros */
|
||||
memset(stdif, 0, sizeof(IfxStdIf_Timer));
|
||||
|
||||
/* *INDENT-OFF* Note: this file was indented manually by the author. */
|
||||
/* Set the API link */
|
||||
stdif->driver = driver;
|
||||
stdif->getFrequency =(IfxStdIf_Timer_GetFrequency )&IfxCcu6_TimerWithTrigger_getFrequency;
|
||||
stdif->getPeriod =(IfxStdIf_Timer_GetPeriod )&IfxCcu6_TimerWithTrigger_getPeriod;
|
||||
stdif->getResolution =(IfxStdIf_Timer_GetResolution )&IfxCcu6_TimerWithTrigger_getResolution;
|
||||
stdif->setFrequency =(IfxStdIf_Timer_SetFrequency )&IfxCcu6_TimerWithTrigger_setFrequency;
|
||||
stdif->updateInputFrequency =(IfxStdIf_Timer_UpdateInputFrequency)&IfxCcu6_TimerWithTrigger_updateInputFrequency;
|
||||
stdif->applyUpdate =(IfxStdIf_Timer_ApplyUpdate )&IfxCcu6_TimerWithTrigger_applyUpdate;
|
||||
stdif->disableUpdate =(IfxStdIf_Timer_DisableUpdate )&IfxCcu6_TimerWithTrigger_disableUpdate;
|
||||
stdif->getInputFrequency =(IfxStdIf_Timer_GetInputFrequency )&IfxCcu6_TimerWithTrigger_getInputFrequency;
|
||||
stdif->run =(IfxStdIf_Timer_Run )&IfxCcu6_TimerWithTrigger_run;
|
||||
stdif->setPeriod =(IfxStdIf_Timer_SetPeriod )&IfxCcu6_TimerWithTrigger_setPeriod;
|
||||
stdif->setSingleMode =(IfxStdIf_Timer_SetSingleMode )&IfxCcu6_TimerWithTrigger_setSingleMode;
|
||||
stdif->setTrigger =(IfxStdIf_Timer_SetTrigger )&IfxCcu6_TimerWithTrigger_setTrigger;
|
||||
stdif->stop =(IfxStdIf_Timer_Stop )&IfxCcu6_TimerWithTrigger_stop;
|
||||
stdif->ackTimerIrq =(IfxStdIf_Timer_AckTimerIrq )&IfxCcu6_TimerWithTrigger_acknowledgeTimerIrq;
|
||||
stdif->ackTriggerIrq =(IfxStdIf_Timer_AckTriggerIrq )&IfxCcu6_TimerWithTrigger_acknowledgeTriggerIrq;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TimerWithTrigger_stop(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
IfxCcu6_stopTimer(driver->ccu6, TRUE, TRUE);
|
||||
}
|
||||
|
||||
|
||||
void IfxCcu6_TimerWithTrigger_updateInputFrequency(IfxCcu6_TimerWithTrigger *driver)
|
||||
{
|
||||
uint16 prescaler;
|
||||
prescaler = driver->ccu6->TCTR0.B.T12CLK;
|
||||
|
||||
driver->base.clockFreq = IfxScuCcu_getSpbFrequency() / (1U << prescaler);
|
||||
}
|
||||
+299
@@ -0,0 +1,299 @@
|
||||
/**
|
||||
* \file IfxCcu6_TimerWithTrigger.h
|
||||
* \brief CCU6 TIMERWITHTRIGGER details
|
||||
* \ingroup IfxLld_Ccu6
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_TimerWithTrigger_Usage How to use the CCU6 TimerWithTrigger Interface driver?
|
||||
* \ingroup IfxLld_Ccu6_TimerWithTrigger
|
||||
* This driver implements the timer functionalities as defined by \ref library_srvsw_stdif_timer.
|
||||
* The user is free to use either the driver specific APIs below or to used the \ref library_srvsw_stdif_timer "standard interface APIs".
|
||||
*
|
||||
* \defgroup IfxLld_Ccu6_TimerWithTrigger TimerWithTrigger Interface driver
|
||||
* \ingroup IfxLld_Ccu6
|
||||
* \defgroup IfxLld_Ccu6_TimerWithTrigger_Data_Structures Data Structures
|
||||
* \ingroup IfxLld_Ccu6_TimerWithTrigger
|
||||
* \defgroup IfxLld_Ccu6_TimerWithTrigger_Timer_StdIf_Functions Timer StdIf Functions
|
||||
* \ingroup IfxLld_Ccu6_TimerWithTrigger
|
||||
* \defgroup IfxLld_Ccu6_TimerWithTrigger_Timer_Functions Timer Functions
|
||||
* \ingroup IfxLld_Ccu6_TimerWithTrigger
|
||||
*/
|
||||
|
||||
#ifndef IFXCCU6_TIMERWITHTRIGGER_H
|
||||
#define IFXCCU6_TIMERWITHTRIGGER_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_PinMap/IfxCcu6_PinMap.h"
|
||||
#include "Ccu6/Std/IfxCcu6.h"
|
||||
#include "StdIf/IfxStdIf_Timer.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_TimerWithTrigger_Data_Structures
|
||||
* \{ */
|
||||
/** \brief Structure for the timer base
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_TimerValue period; /**< \brief Timer period in ticks (cached value) */
|
||||
boolean triggerEnabled; /**< \brief If TRUE, the trigger functionality is Initialised */
|
||||
float32 clockFreq; /**< \brief Timer input clock frequency (cached value) */
|
||||
IfxStdIf_Timer_CountDir countDir; /**< \brief Timer counting mode */
|
||||
} IfxCcu6_TimerWithTrigger_Base;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \brief CCU6 Timer interface
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCcu6_TimerWithTrigger_Base base; /**< \brief Timer base structure */
|
||||
Ifx_CCU6 *ccu6; /**< \brief CCU6 module used for the timer functionality */
|
||||
} IfxCcu6_TimerWithTrigger;
|
||||
|
||||
/** \brief Configuration structure for T12 and T13 Timer
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxStdIf_Timer_Config base; /**< \brief Standard interface timer configuration */
|
||||
Ifx_CCU6 *ccu6; /**< \brief CCU6 module used for the timer functionality */
|
||||
IfxCcu6_Cout63_Out *triggerOut;
|
||||
IfxCcu6_ServiceRequest serviceReqNrPeriod; /**< \brief Service request used for the period */
|
||||
IfxCcu6_ServiceRequest serviceReqNrTrigger; /**< \brief Service request used for the Trigger */
|
||||
} IfxCcu6_TimerWithTrigger_Config;
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_TimerWithTrigger_Timer_StdIf_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the timer event
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return Timer event
|
||||
*
|
||||
* \see IfxStdIf_Timer_AckTimerIrq
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_TimerWithTrigger_acknowledgeTimerIrq(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Returns the trigger event
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return Timer event
|
||||
*
|
||||
* \see IfxStdIf_Timer_AckTriggerIrq
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_TimerWithTrigger_acknowledgeTriggerIrq(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Enable the transfer of the shadow registers
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return None
|
||||
*
|
||||
* \see IfxStdIf_Timer_ApplyUpdate
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TimerWithTrigger_applyUpdate(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Disables the upadte\n
|
||||
* This function is has an empty body as the updated is disabled automatically after the shadow transfer
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return None
|
||||
*
|
||||
* \see IfxStdIf_Timer_DisableUpdate
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TimerWithTrigger_disableUpdate(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Returns the frequency
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return Frequency
|
||||
*
|
||||
* \see IfxStdIf_Timer_GetFrequency
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN float32 IfxCcu6_TimerWithTrigger_getFrequency(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Returns the Input frequncy
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return Frequency
|
||||
*
|
||||
* \see IfxStdIf_Timer_GetInputFrequency
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN float32 IfxCcu6_TimerWithTrigger_getInputFrequency(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Returns the period of the timer
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return Period
|
||||
*
|
||||
* \see IfxStdIf_Timer_GetPeriod
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN Ifx_TimerValue IfxCcu6_TimerWithTrigger_getPeriod(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Returns the resolution
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return Resolution
|
||||
*
|
||||
* \see IfxStdIf_Timer_GetResolution
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN float32 IfxCcu6_TimerWithTrigger_getResolution(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Runs the timer
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return None
|
||||
*
|
||||
* \see IfxStdIf_Timer_Run
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TimerWithTrigger_run(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Sets the frequency
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \param frequency Frequency
|
||||
* \return TRUE on success else FALSE
|
||||
*
|
||||
* \see IfxStdIf_Timer_SetFrequency
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_TimerWithTrigger_setFrequency(IfxCcu6_TimerWithTrigger *driver, float32 frequency);
|
||||
|
||||
/** \brief Sets the period for the timer
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \param period Period value
|
||||
* \return TRUE on success else FALSE
|
||||
*
|
||||
* \see IfxStdIf_Timer_SetPeriod
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_TimerWithTrigger_setPeriod(IfxCcu6_TimerWithTrigger *driver, Ifx_TimerValue period);
|
||||
|
||||
/** \brief Sets the single shot mode of the timer
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \param enabled If TRUE, sets the single shot mode
|
||||
* \return None
|
||||
*
|
||||
* \see IfxStdIf_Timer_SetSingleMode
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TimerWithTrigger_setSingleMode(IfxCcu6_TimerWithTrigger *driver, boolean enabled);
|
||||
|
||||
/** \brief Sets the trigger
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \param triggerPoint Trigger point value
|
||||
* \return None
|
||||
*
|
||||
* \see IfxStdIf_Timer_SetTrigger
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TimerWithTrigger_setTrigger(IfxCcu6_TimerWithTrigger *driver, Ifx_TimerValue triggerPoint);
|
||||
|
||||
/** \brief Initializes the standard interface timer
|
||||
* \param stdif Standard interface object, will be initialized by the function
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_TimerWithTrigger_stdIfTimerInit(IfxStdIf_Timer *stdif, IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Stops the timer
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return None
|
||||
*
|
||||
* \see IfxStdIf_Timer_Stop
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TimerWithTrigger_stop(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Updates the input frequency
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return None
|
||||
*
|
||||
* \see IfxStdIf_Timer_UpdateInputFrequency
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TimerWithTrigger_updateInputFrequency(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Ccu6_TimerWithTrigger_Timer_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the pointer to timer channel
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \return Pointer
|
||||
*
|
||||
* \see IfxStdIf_Timer_DisableUpdate
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN volatile uint32 *IfxCcu6_TimerWithTrigger_getPointer(IfxCcu6_TimerWithTrigger *driver);
|
||||
|
||||
/** \brief Initialises the timer object\n
|
||||
* T12 is configured as timer, T13 is optionally configured as trigger\n
|
||||
* T12CLK, T12PRE and T12PR are chosen to achieve maximum PWM resolution\n
|
||||
* Note: To achieve maximum PWM resolution, the requested T12 frequency should be the\n
|
||||
* lowest PWM frequency.\n
|
||||
* \param driver CCU6 Timer interface Handle
|
||||
* \param config Configuration structure for Timer
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCcu6_TimerWithTrigger_init(IfxCcu6_TimerWithTrigger *driver, IfxCcu6_TimerWithTrigger_Config *config);
|
||||
|
||||
/** \brief Initializes the configuration structure to default
|
||||
* \param config Configuration structure for Timer
|
||||
* \param ccu6 Pointer to CCU6 module
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxCcu6_TimerWithTrigger_initConfig(IfxCcu6_TimerWithTrigger_Config *config, Ifx_CCU6 *ccu6);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXCCU6_TIMERWITHTRIGGER_H */
|
||||
@@ -0,0 +1,848 @@
|
||||
/**
|
||||
* \file IfxCif_Cam.c
|
||||
* \brief CIF CAM details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxCif_Cam.h"
|
||||
#include "Src/Std/IfxSrc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Macros------------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#define IFXCIF_CAM_ALIGN(size, align) ((((size) / (align)) * (align)) + ((((size) % (align)) != 0) ? (align) : 0))
|
||||
|
||||
#define IFXCIF_CAM_MEM_ALIGN(size) IFXCIF_CAM_ALIGN(size, IFXCIF_CAM_MEM_ALIGN_SIZE)
|
||||
|
||||
/** \addtogroup IfxLld_Cif_Cam_camEnumerations
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* \param cam cam handle
|
||||
*/
|
||||
IFX_STATIC IfxCif_Cam_Status IfxCif_Cam_initMemSize(IfxCif_Cam *cam, const IfxCif_Cam_Config *config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Cif_Cam_camFunctions
|
||||
* \{ */
|
||||
/******************************************************************************/
|
||||
/*------------------------Inline Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
*/
|
||||
IFX_INLINE uint32 IfxCif_Cam_calcMem(uint32 bytes, float32 frames);
|
||||
|
||||
/**
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxCif_Cam_initPictInfo(IfxCif_Cam_PictureInfo *m, const IfxCif_Cam_MemConfig *mcfg);
|
||||
|
||||
/** \brief initializes GPIO Ports for image capturing
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxCif_Cam_initPortPins(IfxPort_InputMode inputMode, IfxPort_PadDriver padDriver);
|
||||
|
||||
/**
|
||||
*/
|
||||
IFX_INLINE boolean IfxCif_Cam_isEmulationExtensionAvailable(void);
|
||||
|
||||
/**
|
||||
* \param cam cam handle
|
||||
*/
|
||||
IFX_INLINE uint32 IfxCif_Cam_yuvMemSize(const IfxCif_Cam *cam);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief OVT OV10630 sensor Camera SensorcConfig subroutine , Config file is preloaded to pflash
|
||||
*/
|
||||
IFX_STATIC IfxCif_Cam_Status IfxCif_Cam_initCamera(const IfxCif_Cam_Config *config);
|
||||
|
||||
/** \brief Initialises the CIF for image capturing
|
||||
* \param cam cam handel
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCif_Cam_initCif(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config);
|
||||
|
||||
/**
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCif_Cam_initCifDownscaler(const IfxCif_Cam_Downscaling *ds);
|
||||
|
||||
/**
|
||||
* \param cam cam handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCif_Cam_initCifExtraPath(const IfxCif_Cam *cam, IfxCif_ExtraPath ep, const IfxCif_Cam_Config *config);
|
||||
|
||||
/**
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCif_Cam_initCifIspUnit(const IfxCif_Cam_Config *config);
|
||||
|
||||
/**
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCif_Cam_initCifJpegEncoder(const IfxCif_Cam_Config *config);
|
||||
|
||||
/**
|
||||
* \param cam cam handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCif_Cam_initCifMemInterface(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config);
|
||||
|
||||
/** \brief Enables CIF and EMEM and initialises all memory to 0
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxCif_Cam_initEmem(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE uint32 IfxCif_Cam_calcMem(uint32 bytes, float32 frames)
|
||||
{
|
||||
float32 fbytes = (float32)bytes * frames;
|
||||
uint32 ubytes = (uint32)__roundf(fbytes);
|
||||
|
||||
return Ifx_AlignOn32(ubytes);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxCif_Cam_initPictInfo(IfxCif_Cam_PictureInfo *m, const IfxCif_Cam_MemConfig *mcfg)
|
||||
{
|
||||
m->hSize = mcfg->hSize;
|
||||
m->vSize = mcfg->vSize;
|
||||
m->hOffset = mcfg->hOffset;
|
||||
m->vOffset = mcfg->vOffset;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxCif_Cam_initPortPins(IfxPort_InputMode inputMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
/* Setup the P00.0..9, P02.0..8 pad drivers */
|
||||
IfxPort_setGroupPadDriver(&MODULE_P02, 0, 0x01FFU, padDriver);
|
||||
IfxPort_setGroupPadDriver(&MODULE_P00, 0, 0x03FFU, padDriver);
|
||||
|
||||
/* CIF Data Lines */
|
||||
/* P02.0 .. 8 as input for CIFD0..D8 */
|
||||
/* P00.0 .. 6 as input for CIFD9..D15 */
|
||||
IfxPort_setGroupModeInput(&MODULE_P02, 0, 0x01FFU, inputMode);
|
||||
IfxPort_setGroupModeInput(&MODULE_P00, 0, 0x007FU, inputMode);
|
||||
|
||||
/* CIF synchronisation lines */
|
||||
IfxPort_setPinModeInput(&MODULE_P00, 8, inputMode); /* CIFVSNC */
|
||||
IfxPort_setPinModeInput(&MODULE_P00, 9, inputMode); /* CIFHSNC */
|
||||
IfxPort_setPinModeInput(&MODULE_P00, 7, inputMode); /* CIFCLK */
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxCif_Cam_isEmulationExtensionAvailable(void)
|
||||
{
|
||||
return (MODULE_SCU.CHIPID.B.EEA != 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint32 IfxCif_Cam_yuvMemSize(const IfxCif_Cam *cam)
|
||||
{
|
||||
return cam->memAreas.y.size + cam->memAreas.cb.size + cam->memAreas.cr.size;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxCif_Cam_clearAllFlags(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
MODULE_CIF.JPE.STATUS_ICR.U = 0xFFFFFFFFUL;
|
||||
MODULE_CIF.MI.ICR.U = 0xFFFFFFFFUL;
|
||||
MODULE_CIF.ISP.ICR.U = 0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
|
||||
void IfxCif_Cam_disableJpegEncoder(const IfxCif_Cam *cam)
|
||||
{
|
||||
IfxCif_setMiFeatureEnableState(IfxCif_MiDataPaths_JpegData, IfxCif_State_Disabled);
|
||||
IfxCif_setDataPathSelectorForMainPath(IfxCif_DataPathSelectorForMainPath_DataToMemoryInterfaceUncompressed);
|
||||
|
||||
if (cam->ispMode == IfxCif_Cam_IspMode_raw)
|
||||
{
|
||||
IfxCif_setMiFeatureEnableState(IfxCif_MiDataPaths_RawData, IfxCif_State_Enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxCif_setMiFeatureEnableState(IfxCif_MiDataPaths_MainPictureData, IfxCif_State_Enabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxCif_Cam_enableJpegEncoder(const IfxCif_Cam *cam)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(cam);
|
||||
IfxCif_setMiFeatureEnableState(IfxCif_MiDataPaths_RawData, IfxCif_State_Disabled);
|
||||
IfxCif_setMiFeatureEnableState(IfxCif_MiDataPaths_MainPictureData, IfxCif_State_Disabled);
|
||||
IfxCif_setDataPathSelectorForMainPath(IfxCif_DataPathSelectorForMainPath_DataToJpegEncoder);
|
||||
IfxCif_setMiFeatureEnableState(IfxCif_MiDataPaths_JpegData, IfxCif_State_Enabled);
|
||||
}
|
||||
|
||||
|
||||
IFX_CONST IfxCif_Cam_PictureInfo *IfxCif_Cam_getExtraPathPictureInfo(const IfxCif_Cam *cam, IfxCif_ExtraPath z)
|
||||
{
|
||||
const IfxCif_Cam_PictureInfo *m = NULL_PTR;
|
||||
|
||||
if (z <= IfxCif_ExtraPath_5)
|
||||
{
|
||||
m = &(cam->memAreas.ep[z].image);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCif_Cam_getLastJpegEncodingInfo(IfxCif_Cam *cam, Ifx_AddressValue *address, sint32 *size)
|
||||
{
|
||||
boolean result = FALSE;
|
||||
|
||||
if (IfxCif_Cam_isJpegEncodingComplete(cam))
|
||||
{
|
||||
/* event for sending JPEG encoded image */
|
||||
IfxCif_Cam_clearJpegEncodingCompleteFlag(cam);
|
||||
Ifx_AddressValue nextAddress = IfxCif_Cam_getNextJpegFrameAddress(cam);
|
||||
|
||||
if (((IfxCif_Cam_JfifHeader *)nextAddress)->app0 == 0xE0FF)
|
||||
{
|
||||
/* correct JPEG header was detected. */
|
||||
*address = IfxCif_Cam_getLastFrameAddress(cam);
|
||||
*size = IfxCif_Cam_getJpegEncodedSize(cam);
|
||||
result = TRUE;
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
IfxCif_Cam_Status IfxCif_Cam_init(IfxCif_Cam *cam, const IfxCif_Cam_Config *config, boolean initCam)
|
||||
{
|
||||
/* Try allocating image areas for EMEM */
|
||||
IfxCif_Cam_Status result = IfxCif_Cam_initMemSize(cam, config);
|
||||
|
||||
/* Check if EMEM is available */
|
||||
if (IfxCif_Cam_isEmulationExtensionAvailable() == FALSE)
|
||||
{
|
||||
result = IfxCif_Cam_Status_notAvailable;
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxCif_Cam_initEmem();
|
||||
}
|
||||
|
||||
/* Initialse camera if needed */
|
||||
if ((result == IfxCif_Cam_Status_ok) && (initCam != FALSE))
|
||||
{
|
||||
result = IfxCif_Cam_initCamera(config);
|
||||
}
|
||||
|
||||
/* Finally, initialise the CIF */
|
||||
if (result == IfxCif_Cam_Status_ok)
|
||||
{
|
||||
if (IfxCif_getModuleState() == IfxCif_State_Enabled)
|
||||
{
|
||||
IfxCif_setKernelResetRequestState(IfxCif_State_Enabled);
|
||||
}
|
||||
|
||||
IfxCif_Cam_initPortPins(IfxPort_InputMode_noPullDevice, IfxPort_PadDriver_ttlSpeed1);
|
||||
IfxCif_Cam_initCif(cam, config);
|
||||
}
|
||||
|
||||
cam->configResult = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC IfxCif_Cam_Status IfxCif_Cam_initCamera(const IfxCif_Cam_Config *config)
|
||||
{
|
||||
IfxCif_Cam_Status result = IfxCif_Cam_Status_ok;
|
||||
IfxI2c_I2c i2c;
|
||||
IfxI2c_I2c_Device i2cDev;
|
||||
|
||||
{ /* Initialise I2C module as master */
|
||||
IfxI2c_I2c_Config i2cConfig;
|
||||
IfxI2c_I2c_initConfig(&i2cConfig, &MODULE_I2C0);
|
||||
|
||||
const IfxI2c_Pins pins = {
|
||||
&IfxI2c0_SCL_P15_4_INOUT,
|
||||
&IfxI2c0_SDA_P15_5_INOUT,
|
||||
IfxPort_PadDriver_ttlSpeed1
|
||||
};
|
||||
|
||||
i2cConfig.pins = &pins;
|
||||
i2cConfig.baudrate = 400000; /* 400 kHz */
|
||||
IfxI2c_I2c_initModule(&i2c, &i2cConfig);
|
||||
|
||||
IfxI2c_I2c_deviceConfig i2cDeviceConfig;
|
||||
IfxI2c_I2c_initDeviceConfig(&i2cDeviceConfig, &i2c); /* Device config for Bus of i2c handle */
|
||||
|
||||
/* device address is obtained from the setup data table */
|
||||
i2cDeviceConfig.deviceAddress = (0xFFU & config->setupDataTable[0]);
|
||||
IfxI2c_I2c_initDevice(&i2cDev, &i2cDeviceConfig);
|
||||
}
|
||||
|
||||
/* Send camera configuration array */
|
||||
{
|
||||
uint32 count;
|
||||
|
||||
for (count = 0; count < config->setupDataCount && result == IfxCif_Cam_Status_ok; count++)
|
||||
{
|
||||
uint32 nakCnt = 0; /* counts the NAKs */
|
||||
|
||||
while (IfxI2c_I2c_write(&i2cDev, ((uint8 *)&(config->setupDataTable[count])) + 1, 3) == IfxI2c_I2c_Status_nak)
|
||||
{
|
||||
nakCnt++;
|
||||
|
||||
if (nakCnt >= IFXCIF_MAX_I2CNAK) /* ~400 - 500 us */
|
||||
{
|
||||
result = IfxCif_Cam_Status_cameraCommError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCif_Cam_initCif(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config)
|
||||
{
|
||||
const IfxCif_Cam_Common *common = config->common;
|
||||
|
||||
IfxCif_setModuleStateRequest(IfxCif_State_Enabled);
|
||||
IfxCif_setSoftwareResetMode(IfxCif_Submodules_AllModules, IfxCif_State_Enabled);
|
||||
|
||||
//IfxCif_setInternalClockMode(IfxCif_Submodules_Debug, IfxCif_State_Enabled);
|
||||
//IfxCif_setInternalClockMode(IfxCif_Submodules_SecurityWatchdog, IfxCif_State_Enabled);
|
||||
|
||||
IfxCif_Cam_initCifDownscaler(config->downscaling);
|
||||
IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_1, config);
|
||||
IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_2, config);
|
||||
IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_3, config);
|
||||
IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_4, config);
|
||||
IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_5, config);
|
||||
|
||||
IfxCif_Cam_initCifMemInterface(cam, config);
|
||||
IfxCif_Cam_initCifIspUnit(config);
|
||||
|
||||
if (common->jpegEnabled)
|
||||
{
|
||||
IfxCif_Cam_enableJpegEncoder(cam);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxCif_Cam_disableJpegEncoder(cam);
|
||||
}
|
||||
|
||||
if (common->jpegTables != NULL_PTR)
|
||||
{
|
||||
IfxCif_Cam_initCifJpegEncoder(config);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCif_Cam_initCifDownscaler(const IfxCif_Cam_Downscaling *ds)
|
||||
{
|
||||
if (ds != NULL_PTR)
|
||||
{
|
||||
IfxCif_setInternalClockMode(IfxCif_Submodules_LinearDownscaler,
|
||||
ds->enabled ? IfxCif_State_Enabled : IfxCif_State_Disabled);
|
||||
IfxCif_setLinearDownscalerScalingFactors(ds->hFactor, ds->vFactor);
|
||||
IfxCif_setLinearDownscalerScalingModes(ds->hMode, ds->vMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCif_Cam_initCifExtraPath(const IfxCif_Cam *cam, IfxCif_ExtraPath ep, const IfxCif_Cam_Config *config)
|
||||
{
|
||||
const IfxCif_Cam_Common *common = config->common;
|
||||
const IfxCif_Cam_MemConfig *mcfg = &(common->extraPaths[ep]);
|
||||
|
||||
/* configuration of extra path is requested when each {hSize, vSize, memFactor} is positive. */
|
||||
|
||||
if ((mcfg->hSize > 0) && (mcfg->vSize > 0) && (mcfg->memFactor > 0))
|
||||
{
|
||||
if ((mcfg->vSize + mcfg->vOffset) > common->ispIn.vSize)
|
||||
{
|
||||
/* invalid setting, the vSize and vOffset is outside the ISP acquisition */
|
||||
IFXCIF_DEBUG;
|
||||
}
|
||||
|
||||
IfxCif_setInternalClockMode(IfxCif_Submodules_ExtraPaths, IfxCif_State_Enabled);
|
||||
IfxCif_setEpFeatureEnableState(ep, IfxCif_EpFeatures_PictureDataPath, IfxCif_State_Enabled);
|
||||
IfxCif_setEpFeatureEnableState(ep, IfxCif_EpFeatures_InitBaseAddress, IfxCif_State_Enabled);
|
||||
IfxCif_setEpFeatureEnableState(ep, IfxCif_EpFeatures_InitOffsetCounter, IfxCif_State_Enabled);
|
||||
|
||||
if (config->ispMode == IfxCif_Cam_IspMode_raw)
|
||||
{
|
||||
IfxCif_setEpWriteFormat(ep, (config->ispRawBpp <= 8) ? IfxCif_EpWriteFormat_Raw8Bit : IfxCif_EpWriteFormat_RawGreater);
|
||||
IfxCif_setEpFeatureEnableState(ep, IfxCif_EpFeatures_ByteSwap, mcfg->byteSwap ? IfxCif_State_Enabled : IfxCif_State_Disabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxCif_setEpWriteFormat(ep, IfxCif_EpWriteFormat_YCbCr);
|
||||
}
|
||||
|
||||
if ((mcfg->hSize + mcfg->hOffset) > common->ispIn.hSize)
|
||||
{
|
||||
/* invalid setting, the hSize and hOffset is outside the ISP acquisition */
|
||||
IFXCIF_DEBUG;
|
||||
}
|
||||
|
||||
IfxCif_setEpCroppingEnableState(ep, IfxCif_State_Enabled);
|
||||
IfxCif_setEpCroppingPictureSizes(ep, mcfg->hSize, mcfg->vSize);
|
||||
IfxCif_setEpCroppingOffsetsOutputWindow(ep, mcfg->hOffset, mcfg->vOffset);
|
||||
IfxCif_setEpBaseInitAddress(ep, IfxCif_Cam_getBbbAddress(cam, cam->memAreas.ep[ep].start));
|
||||
IfxCif_setEpInitSize(ep, cam->memAreas.ep[ep].size);
|
||||
IfxCif_epForceConfigurationUpdate(ep);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCif_Cam_initCifIspUnit(const IfxCif_Cam_Config *config)
|
||||
{
|
||||
const IfxCif_Cam_Common *common = config->common;
|
||||
|
||||
IfxCif_setInternalClockMode(IfxCif_Submodules_ImageSignalProcessing, IfxCif_State_Enabled);
|
||||
|
||||
IfxCif_setYCSplitterChannelMode(IfxCif_YCSplitterChannelMode_MainPathAndRawMode);
|
||||
IfxCif_setNumberOfAcquisitionFrames(1);
|
||||
|
||||
if (config->ispRawBpp == 8)
|
||||
{
|
||||
IfxCif_setIspInputSelectionAppendState(IfxCif_State_Enabled);
|
||||
IfxCif_setIspInputInterface(IfxCif_IspInputInterface_8BitExternalInterfaceAppendMsb);
|
||||
}
|
||||
else if (config->ispRawBpp == 10)
|
||||
{
|
||||
IfxCif_setIspInputSelectionAppendState(IfxCif_State_Enabled);
|
||||
IfxCif_setIspInputInterface(IfxCif_IspInputInterface_10BitExternalInterfaceAppendMsb);
|
||||
}
|
||||
else if (config->ispRawBpp == 12)
|
||||
{
|
||||
IfxCif_setIspInputSelectionAppendState(IfxCif_State_Enabled);
|
||||
IfxCif_setIspInputInterface(IfxCif_IspInputInterface_12BitExternalInterfaceAppendMsb);
|
||||
}
|
||||
else if (config->ispRawBpp == 14)
|
||||
{
|
||||
IfxCif_setIspInputSelectionAppendState(IfxCif_State_Enabled);
|
||||
IfxCif_setIspInputInterface(IfxCif_IspInputInterface_14BitExternalInterfaceAppendMsb);
|
||||
}
|
||||
else if (config->ispRawBpp == 16)
|
||||
{
|
||||
IfxCif_setIspInputSelectionAppendState(IfxCif_State_Disabled);
|
||||
IfxCif_setIspInputInterface(IfxCif_IspInputInterface_16BitExternalInterface);
|
||||
}
|
||||
else
|
||||
{
|
||||
IFXCIF_DEBUG;
|
||||
}
|
||||
|
||||
IfxCif_setIspHSyncPolarity(config->hSyncPolarity);
|
||||
IfxCif_setIspVSyncPolarity(config->vSyncPolarity);
|
||||
IfxCif_setIspSamplingEdge(config->samplingEdge);
|
||||
|
||||
if (config->ispMode == IfxCif_Cam_IspMode_raw)
|
||||
{
|
||||
IfxCif_setIspMode(IfxCif_IspMode_RawPicture);
|
||||
IfxCif_setIspFieldInvertState(IfxCif_State_Disabled);
|
||||
IfxCif_setIspAcquisitionSizes(common->ispIn.hSize, common->ispIn.vSize);
|
||||
|
||||
/* the followings are ignored, but set to default */
|
||||
IfxCif_setIspCcirSequence(IfxCif_IspCcirSequence_YCbYCr);
|
||||
IfxCif_setIspColorSpaceMatrixCrominanceClippingRange(IfxCif_IspColorSpaceMatrixCrominanceClippingRange_0To255);
|
||||
IfxCif_setIspColorSpaceMatrixLuminanceClippingRange(IfxCif_IspColorSpaceMatrixLuminanceClippingRange_0To255);
|
||||
}
|
||||
else if ((config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
|
||||
|| (config->ispMode == IfxCif_Cam_IspMode_yuvPlanar))
|
||||
{
|
||||
IfxCif_setIspMode(IfxCif_IspMode_ItuRBT601);
|
||||
IfxCif_setIspFieldInvertState(IfxCif_State_Enabled);
|
||||
IfxCif_setIspAcquisitionSizes(common->ispIn.hSize * 2, common->ispIn.vSize);
|
||||
|
||||
IfxCif_setIspCcirSequence(IfxCif_IspCcirSequence_YCbYCr);
|
||||
IfxCif_setIspColorSpaceMatrixCrominanceClippingRange(IfxCif_IspColorSpaceMatrixCrominanceClippingRange_0To255);
|
||||
IfxCif_setIspColorSpaceMatrixLuminanceClippingRange(IfxCif_IspColorSpaceMatrixLuminanceClippingRange_0To255);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* undefined */
|
||||
IFXCIF_DEBUG;
|
||||
}
|
||||
|
||||
IfxCif_setIspAcquisitionOffsets(common->ispIn.hOffset, common->ispIn.vOffset);
|
||||
IfxCif_setIspPictureSizes(common->ispIn.hSize, common->ispIn.vSize);
|
||||
IfxCif_setIspOutputWindowOffsets(common->ispIn.hOffset, common->ispIn.vOffset);
|
||||
|
||||
IfxCif_setIspisEnableState(IfxCif_State_Enabled);
|
||||
IfxCif_setIspisPictureSizes(common->mainPath.hSize, common->mainPath.vSize);
|
||||
IfxCif_setIspisOutputWindowOffsets((IfxCif_ImageTiers)common->mainPath.hOffset, common->mainPath.vOffset);
|
||||
|
||||
IfxCif_generateIspImmediateConfigUpdateSignal();
|
||||
|
||||
IfxCif_setIspInterruptEnableState(IfxCif_IspInterruptSources_FrameCompletelyPutOut, IfxCif_State_Enabled);
|
||||
//IfxCif_setIspInterruptEnableState(IfxCif_IspInterruptSources_IspTurnedOff, IfxCif_State_Enabled);
|
||||
|
||||
if (common->ispInterrupt.priority > 0)
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *srcr = &SRC_CIFISP;
|
||||
IfxSrc_init(srcr, (IfxSrc_Tos)common->ispInterrupt.provider, (Ifx_Priority)common->ispInterrupt.priority);
|
||||
IfxSrc_enable(srcr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCif_Cam_initCifJpegEncoder(const IfxCif_Cam_Config *config)
|
||||
{
|
||||
const IfxCif_Cam_JpegTables *jpeTables = config->common->jpegTables;
|
||||
|
||||
IfxCif_setInternalClockMode(IfxCif_Submodules_JpegEncoder, IfxCif_State_Enabled);
|
||||
|
||||
/* Select encoding table */
|
||||
IfxCif_setJpeQTableSelector(IfxCif_JpeQTableSelectorComponents_Y, IfxCif_JpeQTableSelector_Table0);
|
||||
IfxCif_setJpeQTableSelector(IfxCif_JpeQTableSelectorComponents_U, IfxCif_JpeQTableSelector_Table1);
|
||||
IfxCif_setJpeQTableSelector(IfxCif_JpeQTableSelectorComponents_V, IfxCif_JpeQTableSelector_Table1);
|
||||
|
||||
/* Programming encoding table */
|
||||
IfxCif_programJpeTable(IfxCif_JpeTableId_QTable0, jpeTables->y.q.entry, jpeTables->y.q.length);
|
||||
IfxCif_programJpeTable(IfxCif_JpeTableId_QTable1, jpeTables->uv.q.entry, jpeTables->uv.q.length);
|
||||
IfxCif_programJpeTable(IfxCif_JpeTableId_VlcDcTable0, jpeTables->y.dc.entry, jpeTables->y.dc.length);
|
||||
IfxCif_programJpeTable(IfxCif_JpeTableId_VlcDcTable1, jpeTables->uv.dc.entry, jpeTables->uv.dc.length);
|
||||
IfxCif_programJpeTable(IfxCif_JpeTableId_VlcAcTable0, jpeTables->y.ac.entry, jpeTables->y.ac.length);
|
||||
IfxCif_programJpeTable(IfxCif_JpeTableId_VlcAcTable1, jpeTables->uv.ac.entry, jpeTables->uv.ac.length);
|
||||
|
||||
/* JPEG Codec Image Size */
|
||||
const IfxCif_Cam_MemConfig *mcfg = &(config->common->mainPath);
|
||||
|
||||
if (config->ispMode == IfxCif_Cam_IspMode_raw)
|
||||
{
|
||||
IfxCif_setJpegCodecImageSizes(mcfg->hSize, mcfg->vSize);
|
||||
}
|
||||
else if (config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
|
||||
{
|
||||
IfxCif_setJpegCodecImageSizes(mcfg->hSize, mcfg->vSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
IFXCIF_DEBUG;
|
||||
}
|
||||
|
||||
/* JPE Header Mode Definition Register */
|
||||
IfxCif_setJpeHeaderMode(IfxCif_JpeHeaderMode_JfifHeader);
|
||||
|
||||
/* JPE Status Interrupt Mask Register */
|
||||
IfxCif_setJpeInterruptEnableState(IfxCif_JpeInterruptSources_EncodingComplete, IfxCif_State_Enabled);
|
||||
//IfxCif_setJpeInterruptEnableState(IfxCif_JpeInterruptSources_HeaderGenerationComplete, IfxCif_State_Enabled);
|
||||
|
||||
/* JPE Command To Start Stream Header Generation Register */
|
||||
IfxCif_jpeGenerateHeader();
|
||||
|
||||
/* JPE Start Command To Start JFIF Stream Encoding Register */
|
||||
IfxCif_startJpegJfifStreamEncoder();
|
||||
IfxCif_setJpegJfifStreamEncoderContinuousMode
|
||||
(IfxCif_JpegJfifStreamEncoderContinuousMode_GenerateHeaderAndStartAutomatically);
|
||||
|
||||
/* JPE Automatic Configuration Update Register */
|
||||
IfxCif_initJpegEncoder();
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCif_Cam_initCifMemInterface(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config)
|
||||
{
|
||||
IfxCif_setInternalClockMode(IfxCif_Submodules_MemoryInterface, IfxCif_State_Enabled);
|
||||
|
||||
if (config->ispMode == IfxCif_Cam_IspMode_raw)
|
||||
{
|
||||
IfxCif_setMiFeatureEnableState(IfxCif_MiDataPaths_RawData, IfxCif_State_Enabled);
|
||||
IfxCif_setMiLuminanceBurstLength(IfxCif_MiBurstLength_8BeatBursts);
|
||||
|
||||
if (config->ispRawBpp > 8)
|
||||
{
|
||||
IfxCif_setMiMainPictureWriteFormat(IfxCif_MiMainPictureWriteFormat_InterleavedOrDataGreater8Bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxCif_setMiMainPictureWriteFormat(IfxCif_MiMainPictureWriteFormat_PlanarOrData8Bit);
|
||||
}
|
||||
}
|
||||
else if (config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
|
||||
{
|
||||
IfxCif_setMiFeatureEnableState(IfxCif_MiDataPaths_MainPictureData, IfxCif_State_Enabled);
|
||||
IfxCif_setMiLuminanceBurstLength(IfxCif_MiBurstLength_8BeatBursts);
|
||||
IfxCif_setMiMainPictureWriteFormat(IfxCif_MiMainPictureWriteFormat_InterleavedOrDataGreater8Bit); /* interleaved mode */
|
||||
}
|
||||
else
|
||||
{
|
||||
IFXCIF_DEBUG;
|
||||
}
|
||||
|
||||
IfxCif_setMiBaseAddressInitializationEnableState(IfxCif_State_Enabled);
|
||||
IfxCif_setMiMainPictureComponentBaseInitAddress(IfxCif_MiMainPicturePathComponents_Y, IfxCif_Cam_getBbbAddress(cam, cam->memAreas.y.start));
|
||||
IfxCif_setMiMainPictureComponentInitSize(IfxCif_MiMainPicturePathComponents_Y, cam->memAreas.y.size);
|
||||
IfxCif_generateMiImmediateConfigUpdateSignal();
|
||||
|
||||
IfxCif_setMiInterruptEnableState(IfxCif_MiInterruptSources_MainPictureFrameEnd, IfxCif_State_Enabled);
|
||||
//IfxCif_setMiInterruptEnableState(IfxCif_MiInterruptSources_FillMainPictureY, IfxCif_State_Enabled);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxCif_Cam_initEmem(void)
|
||||
{
|
||||
IfxEmem_setClockEnableState(IfxEmem_State_enabled);
|
||||
__nop();
|
||||
|
||||
if (IfxEmem_LockedState_locked == IfxEmem_getLockedState())
|
||||
{
|
||||
/* apply unlock sequence */
|
||||
IfxEmem_setUnlockStandbyLockFlag(0x1);
|
||||
IfxEmem_setUnlockStandbyLockFlag(0x3);
|
||||
IfxEmem_setUnlockStandbyLockFlag(0x7);
|
||||
/* wait one cycle for unlock */
|
||||
__nop();
|
||||
}
|
||||
|
||||
IfxEmem_setTileConfigMode(IfxEmem_TileConfigMode_calibMode, IfxEmem_TileNumber_0);
|
||||
|
||||
#if IFXCIF_CAM_INITIALIZE_EMEM
|
||||
{
|
||||
uint64 *pmem;
|
||||
uint32 i;
|
||||
|
||||
/* initialize the whole EMEM with 0 */
|
||||
pmem = (uint64 *)IFXEMEM_START_ADDR_CPU;
|
||||
|
||||
for (i = 0; (uint64)i < (IFXEMEM_SIZE / 8); i += 1)
|
||||
{
|
||||
*(pmem++) = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC IfxCif_Cam_Status IfxCif_Cam_initMemSize(IfxCif_Cam *cam, const IfxCif_Cam_Config *config)
|
||||
{
|
||||
IfxCif_Cam_Status result = IfxCif_Cam_Status_ok;
|
||||
IfxCif_Cam_MemAreas *m = &cam->memAreas;
|
||||
const IfxCif_Cam_Common *common = config->common;
|
||||
const IfxCif_Cam_MemConfig *mcfg = &(common->mainPath);
|
||||
|
||||
cam->nextFreeAddress = 0x00000000;
|
||||
cam->availMemSize = 0x00100000;
|
||||
cam->cif = &MODULE_CIF;
|
||||
cam->emem = &MODULE_EMEM;
|
||||
cam->configResult = IfxCif_Cam_Status_ok;
|
||||
cam->totalMemSize = 0;
|
||||
cam->ispMode = config->ispMode;
|
||||
cam->jfif = NULL_PTR;
|
||||
|
||||
memset(m, 0, sizeof(IfxCif_Cam_MemAreas));
|
||||
|
||||
uint32 numPixels = mcfg->hSize * mcfg->vSize;
|
||||
|
||||
/* Calculate MainPath memory usage information ------------------------------------ */
|
||||
if (config->ispMode == IfxCif_Cam_IspMode_raw)
|
||||
{
|
||||
cam->ispBpp = (config->ispRawBpp > 8) ? 2 : 1;
|
||||
m->y.size = IfxCif_Cam_calcMem(numPixels * cam->ispBpp, mcfg->memFactor) + IFXCIF_CAM_MEM_GAPSIZE;
|
||||
IfxCif_Cam_initPictInfo(&m->y.image, mcfg);
|
||||
m->cb.size = 0 + IFXCIF_CAM_MEM_GAPSIZE;
|
||||
m->cr.size = 0 + IFXCIF_CAM_MEM_GAPSIZE;
|
||||
}
|
||||
else if (config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
|
||||
{
|
||||
cam->ispBpp = 2;
|
||||
m->y.size = IfxCif_Cam_calcMem(numPixels * cam->ispBpp, mcfg->memFactor) + IFXCIF_CAM_MEM_GAPSIZE;
|
||||
IfxCif_Cam_initPictInfo(&m->y.image, mcfg);
|
||||
m->cb.size = 0;
|
||||
m->cr.size = m->cb.size;
|
||||
}
|
||||
else if (config->ispMode == IfxCif_Cam_IspMode_yuvPlanar)
|
||||
{
|
||||
IFXCIF_DEBUG; /* not tested! */
|
||||
cam->ispBpp = 2;
|
||||
m->y.size = IfxCif_Cam_calcMem(numPixels, mcfg->memFactor) + IFXCIF_CAM_MEM_GAPSIZE;
|
||||
IfxCif_Cam_initPictInfo(&m->y.image, mcfg);
|
||||
m->cb.size = m->y.size / 2;
|
||||
m->cr.size = m->cb.size;
|
||||
}
|
||||
|
||||
m->y.start = (Ifx_AddressValue)IFXEMEM_START_ADDR_CPU_CACHED;
|
||||
|
||||
if (common->jpegEnabled != 0)
|
||||
{
|
||||
cam->memAreas.y.size = Ifx_AlignOn32(cam->memAreas.y.size / 8);
|
||||
}
|
||||
|
||||
m->cb.start = (Ifx_AddressValue)((uint32)m->y.start + m->y.size);
|
||||
m->cr.start = (Ifx_AddressValue)((uint32)m->cb.start + m->cb.size);
|
||||
|
||||
cam->totalMemSize = IFXCIF_CAM_MEM_ALIGN(IfxCif_Cam_yuvMemSize(cam));
|
||||
|
||||
IfxCif_ExtraPath z = IfxCif_ExtraPath_1;
|
||||
Ifx_AddressValue nextStart = (Ifx_AddressValue)(IFXEMEM_START_ADDR_CPU_CACHED + cam->totalMemSize);
|
||||
|
||||
/* Calculate ExtraPath 1 memory usage information --------------------------------- */
|
||||
IfxCif_Cam_MemInfo *mep = &(m->ep[z]);
|
||||
mcfg = &common->extraPaths[z];
|
||||
mep->start = nextStart;
|
||||
mep->size = IfxCif_Cam_calcMem(cam->ispBpp * (mcfg->vSize * mcfg->hSize), mcfg->memFactor);
|
||||
IfxCif_Cam_initPictInfo(&mep->image, mcfg);
|
||||
|
||||
if (config->downscaling != NULL_PTR)
|
||||
{
|
||||
const IfxCif_Cam_Downscaling *downscaling = config->downscaling;
|
||||
|
||||
if (downscaling->enabled)
|
||||
{
|
||||
/* NOTE: preliminary version (using 2x or 4x downscaling only) */
|
||||
/* It should be possible to compute the size from the given parameters */
|
||||
if ((downscaling->sizeFactor != 4) && (downscaling->sizeFactor != 2))
|
||||
{
|
||||
IFXCIF_DEBUG;
|
||||
}
|
||||
|
||||
mep->size /= (downscaling->sizeFactor * downscaling->sizeFactor);
|
||||
|
||||
if (downscaling->hMode != IfxCif_LinearDownscalerScalingMode_Disabled)
|
||||
{
|
||||
mep->image.hSize /= downscaling->sizeFactor;
|
||||
}
|
||||
|
||||
if (downscaling->vMode != IfxCif_LinearDownscalerScalingMode_Disabled)
|
||||
{
|
||||
mep->image.vSize /= downscaling->sizeFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cam->totalMemSize = cam->totalMemSize + IFXCIF_CAM_MEM_ALIGN(mep->size);
|
||||
nextStart = (Ifx_AddressValue)(IFXEMEM_START_ADDR_CPU_CACHED + cam->totalMemSize);
|
||||
|
||||
/* Calculate ExtraPath 2..5 memory usage information ------------------------------ */
|
||||
for (z = IfxCif_ExtraPath_2; z <= IfxCif_ExtraPath_5; z++)
|
||||
{
|
||||
mep = &(m->ep[z]);
|
||||
mcfg = &common->extraPaths[z];
|
||||
mep->start = nextStart;
|
||||
mep->size = IfxCif_Cam_calcMem(cam->ispBpp * (mcfg->vSize * mcfg->hSize), mcfg->memFactor);
|
||||
IfxCif_Cam_initPictInfo(&mep->image, mcfg);
|
||||
cam->totalMemSize = cam->totalMemSize + IFXCIF_CAM_MEM_ALIGN(mep->size);
|
||||
nextStart = (Ifx_AddressValue)(IFXEMEM_START_ADDR_CPU_CACHED + cam->totalMemSize);
|
||||
}
|
||||
|
||||
/* Total memory usage ------------------------------------------------------------- */
|
||||
if (cam->totalMemSize <= cam->availMemSize)
|
||||
{
|
||||
/* if enough memory available..... */
|
||||
cam->availMemSize -= cam->totalMemSize;
|
||||
|
||||
if (cam->nextFreeAddress == 0)
|
||||
{
|
||||
cam->nextFreeAddress = (Ifx_AddressValue)IFXEMEM_START_ADDR_CPU_CACHED;
|
||||
}
|
||||
|
||||
cam->nextFreeAddress = (Ifx_AddressValue)((uint32)cam->nextFreeAddress + cam->totalMemSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
IFXCIF_DEBUG;
|
||||
result = IfxCif_Cam_Status_notEnoughMemory;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxCif_Cam_restartCapture(const IfxCif_Cam *cam, uint8 frames)
|
||||
{
|
||||
(void)cam;
|
||||
IfxCif_setNumberOfAcquisitionFrames(frames);
|
||||
IfxCif_setIspOutputState(IfxCif_State_Enabled);
|
||||
IfxCif_generateIspFrameSynchronousConfigUpdateSignal();
|
||||
}
|
||||
|
||||
|
||||
void IfxCif_Cam_startCapture(const IfxCif_Cam *cam, uint8 frames)
|
||||
{
|
||||
(void)cam;
|
||||
IfxCif_setMiOffsetCounterInitializationEnableState(IfxCif_State_Enabled);
|
||||
IfxCif_generateMiImmediateConfigUpdateSignal();
|
||||
IfxCif_setNumberOfAcquisitionFrames(frames);
|
||||
IfxCif_setIspInputFormatterState(IfxCif_State_Enabled);
|
||||
IfxCif_setIspOutputState(IfxCif_State_Enabled);
|
||||
IfxCif_generateIspImmediateConfigUpdateSignal();
|
||||
}
|
||||
|
||||
|
||||
void IfxCif_Cam_stopCapture(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
IfxCif_setIspOutputState(IfxCif_State_Disabled);
|
||||
IfxCif_generateIspImmediateConfigUpdateSignal();
|
||||
}
|
||||
@@ -0,0 +1,624 @@
|
||||
/**
|
||||
* \file IfxCif_Cam.h
|
||||
* \brief CIF CAM details
|
||||
* \ingroup IfxLld_Cif
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Cif_Cam CAM
|
||||
* \ingroup IfxLld_Cif
|
||||
* \defgroup IfxLld_Cif_Cam_camEnumerations Camera Enumerations
|
||||
* \ingroup IfxLld_Cif_Cam
|
||||
* \defgroup IfxLld_Cif_Cam_camFunctions Camera Functions
|
||||
* \ingroup IfxLld_Cif_Cam
|
||||
* \defgroup IfxLld_Cif_Cam_camStructures Camera Structures
|
||||
* \ingroup IfxLld_Cif_Cam
|
||||
*/
|
||||
|
||||
#ifndef IFXCIF_CAM_H
|
||||
#define IFXCIF_CAM_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Cif/Std/IfxCif.h"
|
||||
#include "_PinMap/IfxCif_PinMap.h"
|
||||
#include "Emem/Std/IfxEmem.h"
|
||||
#include "I2c/I2c/IfxI2c_I2c.h"
|
||||
#include "string.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------------Macros-----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#define IFXCIF_CAM_MEM_ALIGN_SIZE (64)
|
||||
|
||||
#define IFXCIF_CAM_MEM_GAPSIZE 0x0
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Cif_Cam_camEnumerations
|
||||
* \{ */
|
||||
/** \brief CIF ISP mode
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCif_Cam_IspMode_undefined = -1, /**< \brief undefined */
|
||||
IfxCif_Cam_IspMode_raw = 0, /**< \brief raw */
|
||||
IfxCif_Cam_IspMode_yuvInterleaved = 1, /**< \brief yuv interleaved */
|
||||
IfxCif_Cam_IspMode_yuvPlanar = 2 /**< \brief yuv planar */
|
||||
} IfxCif_Cam_IspMode;
|
||||
|
||||
/** \brief Driver acquisition state
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCif_Cam_State_stopped = 0, /**< \brief stopped */
|
||||
IfxCif_Cam_State_running = 1 /**< \brief running */
|
||||
} IfxCif_Cam_State;
|
||||
|
||||
/** \brief Driver status
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCif_Cam_Status_ok = 0, /**< \brief ok */
|
||||
IfxCif_Cam_Status_notEnoughMemory = 1, /**< \brief not enough Memory */
|
||||
IfxCif_Cam_Status_cameraCommError = 2, /**< \brief camera comm Error */
|
||||
IfxCif_Cam_Status_notAvailable = 3 /**< \brief not available */
|
||||
} IfxCif_Cam_Status;
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Cif_Cam_camStructures
|
||||
* \{ */
|
||||
typedef struct
|
||||
{
|
||||
uint8 length; /**< \brief length */
|
||||
IFX_CONST uint8 *entry; /**< \brief entry */
|
||||
} IfxCif_Cam_TableInfo;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Cif_Cam_camStructures
|
||||
* \{ */
|
||||
/** \brief Single component JPEG tables
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCif_Cam_TableInfo q; /**< \brief q */
|
||||
IfxCif_Cam_TableInfo dc; /**< \brief dc */
|
||||
IfxCif_Cam_TableInfo ac; /**< \brief ac */
|
||||
} IfxCif_Cam_JpegTable;
|
||||
|
||||
/** \brief Picture info
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 hSize; /**< \brief horizontal (number of pixel) */
|
||||
uint16 vSize; /**< \brief vertical (number of lines) */
|
||||
uint16 hOffset; /**< \brief horizontal offset */
|
||||
uint16 vOffset; /**< \brief vertical offset */
|
||||
} IfxCif_Cam_PictureInfo;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Cif_Cam_camStructures
|
||||
* \{ */
|
||||
/** \brief JPEG tables for all components
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCif_Cam_JpegTable y; /**< \brief y */
|
||||
IfxCif_Cam_JpegTable uv; /**< \brief uv */
|
||||
} IfxCif_Cam_JpegTables;
|
||||
|
||||
/** \brief Single path memory interface configuration (used in initialisation/configuration)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
float32 memFactor; /**< \brief multiples of frame count for memory allocation */
|
||||
uint16 hSize; /**< \brief horizontal (number of pixel) */
|
||||
uint16 vSize; /**< \brief vertical (number of lines) */
|
||||
uint16 hOffset; /**< \brief horizontal offset */
|
||||
uint16 vOffset; /**< \brief vertical offset */
|
||||
boolean byteSwap; /**< \brief byte swapping */
|
||||
} IfxCif_Cam_MemConfig;
|
||||
|
||||
/** \brief Single path memory interface information (used in Runtime)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_AddressValue start; /**< \brief start address */
|
||||
uint32 size; /**< \brief size in bytes */
|
||||
IfxCif_Cam_PictureInfo image; /**< \brief image */
|
||||
} IfxCif_Cam_MemInfo;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Cif_Cam_camStructures
|
||||
* \{ */
|
||||
/** \brief Common configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCif_Cam_PictureInfo ispIn; /**< \brief ispIn */
|
||||
IfxCif_Cam_MemConfig mainPath; /**< \brief main path */
|
||||
IfxCif_Cam_MemConfig extraPaths[IFXCIF_EXTRA_PATHS]; /**< \brief extra paths */
|
||||
IfxCif_InputInterface inputInterface; /**< \brief input interface */
|
||||
Ifx_IsrSetting ispInterrupt; /**< \brief isp interrupt */
|
||||
boolean debugPathEnabled; /**< \brief debug path enabled */
|
||||
boolean watchdogEnabled; /**< \brief watchdog enabled */
|
||||
IFX_CONST IfxCif_Cam_JpegTables *jpegTables; /**< \brief jpeg tables */
|
||||
boolean jpegEnabled; /**< \brief jpeg enabled */
|
||||
} IfxCif_Cam_Common;
|
||||
|
||||
/** \brief Downscaler configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean enabled; /**< \brief enable */
|
||||
IfxCif_LinearDownscalerScalingMode hMode; /**< \brief hMode */
|
||||
IfxCif_LinearDownscalerScalingMode vMode; /**< \brief vMode */
|
||||
uint8 hFactor; /**< \brief horizontal factor to program into IfxCif_setLinearDownscalerScalingFactors() */
|
||||
uint8 vFactor; /**< \brief vertical factor to program into IfxCif_setLinearDownscalerScalingFactors() */
|
||||
uint8 sizeFactor; /**< \brief memory size factor, e.g. half in both H and V usually gives factor of 4 */
|
||||
} IfxCif_Cam_Downscaling;
|
||||
|
||||
/** \brief JPEG JFIF header structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 unknown; /**< \brief unknown */
|
||||
uint16 app0; /**< \brief app0 */
|
||||
uint16 length; /**< \brief length */
|
||||
uint8 ident[5]; /**< \brief ident */
|
||||
uint16 version; /**< \brief version */
|
||||
uint8 density; /**< \brief density */
|
||||
uint16 densityX; /**< \brief densityX */
|
||||
uint16 densityY; /**< \brief densityY */
|
||||
uint8 thumbX; /**< \brief thumbX */
|
||||
uint8 thumbY; /**< \brief thumbY */
|
||||
uint8 thumbData[20]; /**< \brief thumbData */
|
||||
} IfxCif_Cam_JfifHeader;
|
||||
|
||||
/** \brief All paths memory partitioning
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCif_Cam_MemInfo y; /**< \brief y */
|
||||
IfxCif_Cam_MemInfo cb; /**< \brief cb */
|
||||
IfxCif_Cam_MemInfo cr; /**< \brief cr */
|
||||
IfxCif_Cam_MemInfo ep[IFXCIF_EXTRA_PATHS]; /**< \brief ep */
|
||||
} IfxCif_Cam_MemAreas;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Cif_Cam_camStructures
|
||||
* \{ */
|
||||
/** \brief Structure which is used as handle for the CIF-CAM functions.
|
||||
* This stores cached variables useful for run-time operations.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxCif_Cam_MemAreas memAreas; /**< \brief memory area definition */
|
||||
uint32 totalMemSize; /**< \brief total occupied memory area (in bytes) */
|
||||
Ifx_AddressValue nextFreeAddress; /**< \brief next free storage address */
|
||||
uint32 availMemSize; /**< \brief total available RAM space left (in bytes) */
|
||||
Ifx_CIF *cif; /**< \brief pointer to base address of CIF module SFRs */
|
||||
Ifx_EMEM *emem; /**< \brief pointer to base address of EMEM module SFRs */
|
||||
IfxCif_Cam_JfifHeader *jfif; /**< \brief pointer to the last acquired JPEG header */
|
||||
IfxCif_Cam_Status configResult; /**< \brief status of last configuration (or initialisation) */
|
||||
IfxCif_Cam_IspMode ispMode; /**< \brief actual ISP mode */
|
||||
boolean ispBpp; /**< \brief byte per pixel */
|
||||
} IfxCif_Cam;
|
||||
|
||||
/** \brief Camera specific configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IFX_CONST IfxCif_Cam_Common *common; /**< \brief pointer to common configuration */
|
||||
IfxCif_Cam_IspMode ispMode; /**< \brief ISP mode */
|
||||
uint16 ispRawBpp; /**< \brief bytes per pixel of the input stream */
|
||||
IfxCif_IspSyncPolarity hSyncPolarity; /**< \brief polarity of HSYNC signal */
|
||||
IfxCif_IspSyncPolarity vSyncPolarity; /**< \brief polarity of VSYNC signal */
|
||||
IfxCif_IspSamplingEdge samplingEdge; /**< \brief sampling edge */
|
||||
uint16 setupDataCount; /**< \brief number of camera-specific configuration data (in DWORDS) */
|
||||
IFX_CONST uint32 *setupDataTable; /**< \brief pointer to the first entry of camera-specific configuration data */
|
||||
IFX_CONST IfxCif_Cam_Downscaling *downscaling; /**< \brief downscaling settings for ExtraPath 1 */
|
||||
} IfxCif_Cam_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Cif_Cam_camFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Clear the frame reception flag
|
||||
* \param cam cam handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxCif_Cam_clearFrameReceptionFlag(const IfxCif_Cam *cam);
|
||||
|
||||
/** \brief Clear the JPEG encoder completed flag
|
||||
* \param cam cam handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxCif_Cam_clearJpegEncodingCompleteFlag(const IfxCif_Cam *cam);
|
||||
|
||||
/** \brief Convert the CPU address into BBB address
|
||||
* \param cam cam handle
|
||||
* \param cpuAddress Address value
|
||||
*/
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getBbbAddress(const IfxCif_Cam *cam, Ifx_AddressValue cpuAddress);
|
||||
|
||||
/** \brief Returns the size (in bytes) of one last acquired extra-path image data
|
||||
* \param cam cam handle
|
||||
* \param z Extra path
|
||||
*/
|
||||
IFX_INLINE uint32 IfxCif_Cam_getExtraFrameSize(const IfxCif_Cam *cam, IfxCif_ExtraPath z);
|
||||
|
||||
/**
|
||||
* \param cam cam handle
|
||||
* \param z Extra path
|
||||
*/
|
||||
IFX_INLINE IFX_CONST IfxCif_Cam_MemInfo *IfxCif_Cam_getExtraPathMemInfo(const IfxCif_Cam *cam, IfxCif_ExtraPath z);
|
||||
|
||||
/** \brief Returns the size (in bytes) of last acquired main-path image data
|
||||
* \param cam cam handle
|
||||
*/
|
||||
IFX_INLINE uint32 IfxCif_Cam_getFrameSize(const IfxCif_Cam *cam);
|
||||
|
||||
/** \brief Returns the size (in bytes) of last encoded main-path image data
|
||||
* \param cam cam handle
|
||||
*/
|
||||
IFX_INLINE uint32 IfxCif_Cam_getJpegEncodedSize(const IfxCif_Cam *cam);
|
||||
|
||||
/** \brief Returns the address location of last acquired extra-path image frame data
|
||||
* \param cam cam handle
|
||||
* \param z Extra path
|
||||
*/
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getLastExtraAddress(const IfxCif_Cam *cam, IfxCif_ExtraPath z);
|
||||
|
||||
/**
|
||||
* \param cam cam handle
|
||||
* \param z Extra path
|
||||
* \param address Address Value
|
||||
* \param size const IfxCif_Cam_MemInfo *m;
|
||||
* *size = IfxCif_Cam_getExtraFrameSize(cam, z);
|
||||
* *address = IfxCif_Cam_getLastExtraAddress(cam, z);
|
||||
* m = IfxCif_Cam_getExtraPathMemInfo(cam, z);
|
||||
* return m;
|
||||
*/
|
||||
IFX_INLINE IFX_CONST IfxCif_Cam_MemInfo *IfxCif_Cam_getLastExtraCaptureInfo(const IfxCif_Cam *cam, IfxCif_ExtraPath z, Ifx_AddressValue *address, uint32 *size);
|
||||
|
||||
/** \brief Returns the address location of last acquired main-path image frame data
|
||||
* \param cam cam handle
|
||||
* \return address location of last acquired main-path image frame data
|
||||
*/
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getLastFrameAddress(const IfxCif_Cam *cam);
|
||||
|
||||
/**
|
||||
* \param cam cam handle
|
||||
* \param address Address value
|
||||
* \param size Size
|
||||
*/
|
||||
IFX_INLINE IFX_CONST IfxCif_Cam_MemInfo *IfxCif_Cam_getLastFrameCaptureInfo(const IfxCif_Cam *cam, Ifx_AddressValue *address, uint32 *size);
|
||||
|
||||
/** \brief Returns the address location of next acquired main-path image frame data
|
||||
* \param cam cam handle
|
||||
*/
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getNextFrameAddress(const IfxCif_Cam *cam);
|
||||
|
||||
/** \brief Returns the address location of next acquired JPEG image frame data
|
||||
* \param cam cam handle
|
||||
*/
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getNextJpegFrameAddress(IfxCif_Cam *cam);
|
||||
|
||||
/** \brief Increment the address related to memory interface of for main-path. The address is wrapped around at the boundary of the allocated RAM size
|
||||
* \param cam cam handle
|
||||
* \param address Address value
|
||||
*/
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_incrementAddress(const IfxCif_Cam *cam, Ifx_AddressValue address);
|
||||
|
||||
/** \brief Returns TRUE if JPEG encoding is completed
|
||||
* \param cam cam handle
|
||||
* \return TRUE if one frame reception is completed
|
||||
*/
|
||||
IFX_INLINE boolean IfxCif_Cam_isFrameReceptionComplete(const IfxCif_Cam *cam);
|
||||
|
||||
/** \brief
|
||||
* \param cam cam handle
|
||||
* \return TRUE if JPEG encoding is completed
|
||||
*/
|
||||
IFX_INLINE boolean IfxCif_Cam_isJpegEncodingComplete(const IfxCif_Cam *cam);
|
||||
|
||||
/**
|
||||
* \param cam cam handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxCif_Cam_skipPicture(const IfxCif_Cam *cam);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Clear all CIF module notification flags
|
||||
* \param cam cam handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxCif_Cam_clearAllFlags(const IfxCif_Cam *cam);
|
||||
|
||||
/** \brief Disable the JPEG encoder and route the acquisition path accordingly to the 'original' configuration, i.e. RAW or main path.
|
||||
* \param cam cam handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxCif_Cam_disableJpegEncoder(const IfxCif_Cam *cam);
|
||||
|
||||
/** \brief Enable the JPEG encoder and route the acquisition path accordingly
|
||||
* \param cam cam handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxCif_Cam_enableJpegEncoder(const IfxCif_Cam *cam);
|
||||
|
||||
/** \brief Returns pointer to the variable storing picture info of an extra-path
|
||||
* \param cam cam handle
|
||||
* \param z Extra Path
|
||||
* \return pointer to the variable storing picture info of an extra-path
|
||||
*/
|
||||
IFX_EXTERN IFX_CONST IfxCif_Cam_PictureInfo *IfxCif_Cam_getExtraPathPictureInfo(const IfxCif_Cam *cam, IfxCif_ExtraPath z);
|
||||
|
||||
/** \brief Returns pointer to the memory structure storing last JPEG encoding process
|
||||
* \param cam cam handle
|
||||
* \param address EMEM address which stores the JPEG frame
|
||||
* \param size size of JPEG frame
|
||||
* \return TRUE if there was new frame encoded, else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxCif_Cam_getLastJpegEncodingInfo(IfxCif_Cam *cam, Ifx_AddressValue *address, sint32 *size);
|
||||
|
||||
/** \brief Initialise the CIF, EMEM, PORT, I2C and the camera itself
|
||||
* \param cam cam handel
|
||||
* \param config configurations structure
|
||||
* \param initCam if TRUE camera will be reconfigured, else camera will not be reconfigured.
|
||||
*/
|
||||
IFX_EXTERN IfxCif_Cam_Status IfxCif_Cam_init(IfxCif_Cam *cam, const IfxCif_Cam_Config *config, boolean initCam);
|
||||
|
||||
/** \brief Restart capture by enabling the ISP output
|
||||
* \param cam cam handle
|
||||
* \param frames Number of acquisitions. Set to zero for continuous acquisition
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxCif_Cam_restartCapture(const IfxCif_Cam *cam, uint8 frames);
|
||||
|
||||
/** \brief Start capture by enabling the ISP output and initialising the MI counter
|
||||
* \param cam cam handle
|
||||
* \param frames Number of acquisitions. Set to zero for continuous acquisition
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxCif_Cam_startCapture(const IfxCif_Cam *cam, uint8 frames);
|
||||
|
||||
/** \brief Stop capture by disabling the ISP output
|
||||
* \param cam cam handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxCif_Cam_stopCapture(const IfxCif_Cam *cam);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxCif_Cam_clearFrameReceptionFlag(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
MODULE_CIF.ISP.ICR.U = (IFX_CIF_ISP_ICR_ICR_FRAME_MSK << IFX_CIF_ISP_ICR_ICR_FRAME_OFF);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxCif_Cam_clearJpegEncodingCompleteFlag(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
MODULE_CIF.JPE.STATUS_ICR.U = (IFX_CIF_JPE_STATUS_ICR_ENCODE_DONE_MSK << IFX_CIF_JPE_STATUS_ICR_ENCODE_DONE_OFF);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getBbbAddress(const IfxCif_Cam *cam, Ifx_AddressValue cpuAddress)
|
||||
{
|
||||
(void)cam;
|
||||
|
||||
return (Ifx_AddressValue)(((uint32)cpuAddress & 0x00FFFFFFU) + IFXEMEM_START_ADDR_BBB);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint32 IfxCif_Cam_getExtraFrameSize(const IfxCif_Cam *cam, IfxCif_ExtraPath z)
|
||||
{
|
||||
sint32 size = 0;
|
||||
|
||||
if (z <= IfxCif_ExtraPath_5)
|
||||
{
|
||||
size = cam->memAreas.ep[z].image.hSize * cam->memAreas.ep[z].image.vSize;
|
||||
|
||||
if ((cam->ispMode != IfxCif_Cam_IspMode_raw) || (cam->ispBpp > 1))
|
||||
{
|
||||
size = size * 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IFXCIF_DEBUG;
|
||||
}
|
||||
|
||||
return (uint32)size;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE IFX_CONST IfxCif_Cam_MemInfo *IfxCif_Cam_getExtraPathMemInfo(const IfxCif_Cam *cam, IfxCif_ExtraPath z)
|
||||
{
|
||||
return &(cam->memAreas.ep[z]);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint32 IfxCif_Cam_getFrameSize(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
sint32 size = MODULE_CIF.MI.MP_Y_OFFS_CNT_SHD.U - MODULE_CIF.MI.MP_Y_OFFS_CNT_START.U;
|
||||
|
||||
if (size <= 0)
|
||||
{
|
||||
size += MODULE_CIF.MI.MP_Y_SIZE_INIT.U;
|
||||
}
|
||||
|
||||
return (uint32)size;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint32 IfxCif_Cam_getJpegEncodedSize(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
|
||||
/* 0x240 is size of JFIF header. */
|
||||
return 0x240 + IfxCif_Cam_getFrameSize(cam);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getLastExtraAddress(const IfxCif_Cam *cam, IfxCif_ExtraPath z)
|
||||
{
|
||||
Ifx_AddressValue address = 0;
|
||||
|
||||
if (z <= IfxCif_ExtraPath_5)
|
||||
{
|
||||
address = (Ifx_AddressValue)((uint32)cam->memAreas.ep[z].start + MODULE_CIF.MIEP.CH_1S[z].OFFS_CNT_START.U);
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE IFX_CONST IfxCif_Cam_MemInfo *IfxCif_Cam_getLastExtraCaptureInfo(const IfxCif_Cam *cam, IfxCif_ExtraPath z, Ifx_AddressValue *address, uint32 *size)
|
||||
{
|
||||
const IfxCif_Cam_MemInfo *m;
|
||||
*size = IfxCif_Cam_getExtraFrameSize(cam, z);
|
||||
*address = IfxCif_Cam_getLastExtraAddress(cam, z);
|
||||
m = IfxCif_Cam_getExtraPathMemInfo(cam, z);
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getLastFrameAddress(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
|
||||
return (Ifx_AddressValue)(IFXEMEM_START_ADDR_CPU_CACHED + MODULE_CIF.MI.MP_Y_OFFS_CNT_START.U);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE IFX_CONST IfxCif_Cam_MemInfo *IfxCif_Cam_getLastFrameCaptureInfo(const IfxCif_Cam *cam, Ifx_AddressValue *address, uint32 *size)
|
||||
{
|
||||
const IfxCif_Cam_MemInfo *m;
|
||||
*size = IfxCif_Cam_getFrameSize(cam);
|
||||
*address = IfxCif_Cam_getLastFrameAddress(cam);
|
||||
m = &(cam->memAreas.y);
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getNextFrameAddress(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
|
||||
return (Ifx_AddressValue)(IFXEMEM_START_ADDR_CPU_CACHED + MODULE_CIF.MI.MP_Y_OFFS_CNT_SHD.U);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_getNextJpegFrameAddress(IfxCif_Cam *cam)
|
||||
{
|
||||
Ifx_AddressValue address = IfxCif_Cam_getNextFrameAddress(cam);
|
||||
cam->jfif = (IfxCif_Cam_JfifHeader *)address; /* note: no cast to (void *) to satisfy C++ compilers */
|
||||
return address;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE Ifx_AddressValue IfxCif_Cam_incrementAddress(const IfxCif_Cam *cam, Ifx_AddressValue address)
|
||||
{
|
||||
address = (Ifx_AddressValue)((uint32)address + 4U);
|
||||
|
||||
if ((uint32)address >= (IFXEMEM_START_ADDR_CPU_CACHED + cam->memAreas.y.size))
|
||||
{ /* back to base */
|
||||
address = (Ifx_AddressValue)IFXEMEM_START_ADDR_CPU_CACHED;
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxCif_Cam_isFrameReceptionComplete(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
|
||||
return MODULE_CIF.ISP.RIS.B.RIS_FRAME != 0;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxCif_Cam_isJpegEncodingComplete(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
|
||||
return MODULE_CIF.JPE.STATUS_RIS.B.ENCODE_DONE != 0;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxCif_Cam_skipPicture(const IfxCif_Cam *cam)
|
||||
{
|
||||
(void)cam;
|
||||
IfxCif_setMiOffsetCounterInitializationEnableState(IfxCif_State_Disabled);
|
||||
IfxCif_miSkipPicture();
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXCIF_CAM_H */
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
* \file IfxCpu_Cstart.h
|
||||
* \brief This file contains the Core startup sequence.
|
||||
*
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_CStart Core Startup Functions
|
||||
* \ingroup IfxLld_Cpu
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_CStart_StartupSequence Startup Sequence
|
||||
* \ingroup IfxLld_Cpu_CStart
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_CStart_ConfigEnableCache How to enable cache during startup?
|
||||
* \ingroup IfxLld_Cpu_CStart
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_CStart_ConfigEnableCores How to enable CPUs during startup?
|
||||
* \ingroup IfxLld_Cpu_CStart
|
||||
*/
|
||||
#ifndef IFXCPU_CSTART_H_
|
||||
#define IFXCPU_CSTART_H_
|
||||
|
||||
/******************************************************************************/
|
||||
/* Includes */
|
||||
/******************************************************************************/
|
||||
#include "Ifx_Cfg.h"
|
||||
#ifndef IFX_CFG_USE_COMPILER_DEFAULT_LINKER
|
||||
#include "Cpu/Std/Ifx_Types.h"
|
||||
#include "Tricore/Compilers/Compilers.h"
|
||||
#include "Cpu/Std/IfxCpu_Intrinsics.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* Macros */
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Configuration for pre initialization hook function.
|
||||
*
|
||||
*/
|
||||
#ifndef IFX_CFG_CPU_CSTART_PRE_C_INIT_HOOK
|
||||
# define IFX_CFG_CPU_CSTART_PRE_C_INIT_HOOK(cpu) /**< Hook function is empty if not configured*/
|
||||
#endif
|
||||
/******************************************************************************/
|
||||
/* Exported prototypes */
|
||||
/******************************************************************************/
|
||||
void _Core1_start(void);
|
||||
void _Core2_start(void);
|
||||
|
||||
/*Documentation */
|
||||
|
||||
/** \addtogroup IfxLld_Cpu_CStart_StartupSequence
|
||||
* \{
|
||||
*
|
||||
* The startup driver is responsible for initializing the basic features of microcontroller
|
||||
* to bring it up to the user functions. In framework these functions are called as "CoreX_main".
|
||||
*
|
||||
* In TC27X controllers, CPU0 is master controller which is booted from reset.
|
||||
* IfxCpu_CStart driver provides following functionalities and they are listed in the order of
|
||||
* their execution.
|
||||
*
|
||||
* \section IfxLld_Cpu_CStart_StartupSequence Core Startup Sequence
|
||||
* 1) Execute pre-initialization hook, which is user configurable. \ref IfxLld_Cpu_CStart_ConfigStartupPreInitHook\n
|
||||
* 2) Setup user stack pointer for the CPU core\n
|
||||
* 3) Set program/data cache bypass to configuration defined settings. Refer \ref IfxLld_Cpu_CStart_ConfigEnableCache.\n
|
||||
* 4) Set base address for trap vector and interrupt vector for the CPU core\n
|
||||
* 5) Set interrupt stack pointer\n
|
||||
* 6) Initialize the base pointers for the small data area registers for CPU core\n
|
||||
* 7) Initialize the CSA for CPU core\n
|
||||
* 8) Do the C initialization to initialize the global variables etc.\n
|
||||
* 9) Initialize the clock system to configuration defined settings. \ref Ifx_Scu_Ccu_ConfigClock\n
|
||||
* 10) Start remaining cores if they configuration setting request them to be enabled. \ref IfxLld_Cpu_CStart_ConfigEnableCores\n
|
||||
* 11) Call user function "CoreX_main"\n
|
||||
*
|
||||
* \note All the above functionalities are executed by "master core" in this case CPU0. Remaining cores will execute
|
||||
* only subset of the above functions, i.e. steps 8) 9) and 10) are not executed by remaining CPU core startups.
|
||||
*
|
||||
* \section IfxLld_Cpu_CStart_ConfigStartupPreInitHook Using Startup pre-initialization hook
|
||||
*
|
||||
* If the application/ demo example need some activity other than above defined functionalities, user can configure
|
||||
* the function which is called before any other initialization is executed. Example of such activity is testing the CSA and STACK.
|
||||
*
|
||||
* Following are the steps to be done to configure user defined activity which is needed before startup sequence.
|
||||
*
|
||||
* \subsection IfxLld_Cpu_CStart_ConfigStartupPreInitHookStep1 Step1: Define a hook function
|
||||
*
|
||||
* This definition shall be as user defined code (Generally in DemoApps folder).\n
|
||||
* Considerations:\n
|
||||
* 1. Format: IFX_INLINE void \<pre init function name\>(cpu)
|
||||
* \note Define such a routine with the consideration, that there shall be no function call within this.
|
||||
*
|
||||
* 2. Use the information available as parameter cpu
|
||||
*
|
||||
* Example code in a user defined file eg. Ifx_preInitHook.h, placed under folder/subfolder: 0_AppSw/Tricore/DemoApp:
|
||||
* \code
|
||||
* // file: Ifx_preInitHook.h
|
||||
* //Example function for pre initialization Hook for startup functions.
|
||||
*
|
||||
* IFX_INLINE mySysPreInitHook(uint32 cpu)
|
||||
* {
|
||||
* switch (cpu)
|
||||
* {
|
||||
* case 0:
|
||||
* {
|
||||
* //user code for cpu0: Function calls NOT allowed.
|
||||
* break;
|
||||
* }
|
||||
* case 1:
|
||||
* {
|
||||
* //user code for cpu1: Function calls NOT allowed.
|
||||
* break;
|
||||
* }
|
||||
* case 2:
|
||||
* {
|
||||
* //user code for cpu2: Function calls NOT allowed.
|
||||
* break;
|
||||
* }
|
||||
* case default:
|
||||
* {
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Cpu_CStart_ConfigStartupPreInitHookStep2 Step2: Configure the pre initialization function for startup sequence call
|
||||
* Create a file for configuring the hook. For example, Ifx_Cfg_CStart.h at ../0_Src/0_AppSw/Config/Tricore (or in DemoApp folder)
|
||||
* \note This configuration, overload the macro IFX_CFG_CPU_CSTART_PRE_C_INIT_HOOK(cpu), which is already defined in IfxCpu_CStart.h.
|
||||
* !!IMPORTANT!! Don't modify this at IfxCpu_CStart.h, because this is library file.
|
||||
*
|
||||
* \code
|
||||
* //file: Ifx_Cfg_CStart.h
|
||||
*
|
||||
* #include "Ifx_preInitHook.h" //Assuming this is the file name as in above example
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_PRE_C_INIT_HOOK(cpu) mySysPreInitHook(cpu) //This is INLINE function.
|
||||
*
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Cpu_CStart_ConfigEnableCache
|
||||
* \{
|
||||
*
|
||||
* In Tricore Cpu the cache enable/ disable are handled by the feature called cache bypass.
|
||||
* Cache is enabled if the Bypass is disabled.
|
||||
*
|
||||
* Startup sequence of each CPU execute the function to do the cache settings. \ref Ifx_Cpu_StartupSequence
|
||||
* The configuration parameters IFX_CFG_CPU_CSTART_ENABLE_TRICOREx_PCACHE and
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICOREx_DCACHE control this function.
|
||||
*
|
||||
* To modify the default configuration, these macros are to be defined in Ifx_Cfg.h (usually located under ../0_Src/0_AppSw/Config/Common/Ifx_Cfg.h)
|
||||
* \note This kind of definitions overload the macros, which are already defined in IfxCpu_CStart*.c.
|
||||
* !!IMPORTANT!! Don't modify these in IfxCpu_CStart*.c, because theseare library files.
|
||||
*
|
||||
* Details of configuration parameters:\n
|
||||
*
|
||||
* \paragraph IfxLld_Cpu_CStart_ConfigEnableCachePgmParamters program cache configuration parameters
|
||||
*
|
||||
* Enable/Disable program cache of Tricore CPU0 with parameter:\n
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_PCACHE\n
|
||||
*
|
||||
* Enable/Disable program cache of Tricore CPU1 with parameter:\n
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_PCACHE\n
|
||||
*
|
||||
* Enable/Disable program cache of Tricore CPU2 with parameter:\n
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICORE2_PCACHE\n
|
||||
*
|
||||
* Enable/Disable data cache of Tricore CPU0 with parameter:\n
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_DCACHE\n
|
||||
*
|
||||
* Enable/Disable data cache of Tricore CPU1 with parameter:\n
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_DCACHE\n
|
||||
*
|
||||
* Enable/Disable data cache of Tricore CPU2 with parameter:\n
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICORE2_DCACHE\n
|
||||
*
|
||||
* Following example shows, how to enable program cache of all available cores and disable data cache of all
|
||||
* the available cores.
|
||||
* \code
|
||||
* //file: Ifx_Cfg.h
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_PCACHE (1) //Program cache for Cpu0 is enabled
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_DCACHE (1) //Data cache for Cpu0 is enabled
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_PCACHE (1) //Program cache for Cpu1 is enabled
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_DCACHE (1) //Data cache for Cpu1 is enabled
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_ENABLE_TRICORE2_PCACHE (1) //Program cache for Cpu2 is enabled
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_ENABLE_TRICORE2_DCACHE (1) //Data cache for Cpu2 is enabled
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* To control the the caches during runtime, refer for the details of APIs: \ref Ifx_Cpu_Cache
|
||||
*
|
||||
*/
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Cpu_CStart_ConfigEnableCores
|
||||
* \{
|
||||
*
|
||||
* Startup sequence of CPU0 execute the function to initialize the remaining available CPUs.
|
||||
* \ref IfxLld_Cpu_CStart_StartupSequence.
|
||||
* Startup sequence enables all the available CPUs.
|
||||
*
|
||||
* The configuration parameters IFX_CFG_CPU_CSTART_ENABLE_TRICOREx control this function.
|
||||
* To modify the default configuration, these macros are to be defined. Create a file to define these macros,
|
||||
* for example, Ifx_Cfg_CStart.h at ../0_Src/0_AppSw/Config/Tricore (or in DemoApp folder).
|
||||
* \note This kind of definitions, overload the macros, which are already defined in IfxCpu_CStart.h.
|
||||
* !!IMPORTANT!! Don't modify these at IfxCpu_CStart.h, because this is library file.
|
||||
*
|
||||
* Details of configuration parameters:\n
|
||||
*
|
||||
* \paragraph IfxLld_Cpu_CStart_ConfigEnableCoresParamters CPU enable/disable configuration parameters
|
||||
*
|
||||
* Enable/Disable of Tricore CPU0 with parameter:\n
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICORE0\n
|
||||
*
|
||||
* Enable/Disable of Tricore CPU1 with parameter:\n
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICORE1\n
|
||||
*
|
||||
* Enable/Disable of Tricore CPU2 with parameter:\n
|
||||
* IFX_CFG_CPU_CSTART_ENABLE_TRICORE2\n
|
||||
*
|
||||
* Following example shows, how to enable all available cores.
|
||||
* \code
|
||||
* //file: Ifx_Cfg_CStart.h
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_ENABLE_TRICORE0 (1) //Cpu0 is enabled
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_ENABLE_TRICORE1 (1) //Cpu1 is enabled
|
||||
*
|
||||
* #define IFX_CFG_CPU_CSTART_ENABLE_TRICORE2 (1) //Cpu2 is enabled
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /*#ifndef IFX_CFG_USE_COMPILER_DEFAULT_LINKER */
|
||||
#endif /* IFXCPU_CSTART_H_ */
|
||||
@@ -0,0 +1,314 @@
|
||||
/**
|
||||
* \file IfxCpu_Cstart0.c
|
||||
* \brief This file contains the Core startup sequence for Cpu0.
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
/*******************************************************************************
|
||||
** Includes **
|
||||
*******************************************************************************/
|
||||
#include "Ifx_Cfg.h"
|
||||
#ifndef IFX_CFG_USE_COMPILER_DEFAULT_LINKER
|
||||
#include "Scu/Std/IfxScuWdt.h"
|
||||
#include "Scu/Std/IfxScuCcu.h"
|
||||
#include "Cpu/Std/IfxCpu.h"
|
||||
#include "Cpu/CStart/IfxCpu_CStart.h"
|
||||
#include "IfxScu_reg.h"
|
||||
#include "IfxCpu_reg.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* Macros */
|
||||
/******************************************************************************/
|
||||
/** \brief Configuration for CpuX enable.
|
||||
*
|
||||
*/
|
||||
#ifndef IFX_CFG_CPU_CSTART_ENABLE_TRICORE0
|
||||
# define IFX_CFG_CPU_CSTART_ENABLE_TRICORE0 (1) /**< Cpu0 enabled by default*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_CSTART_ENABLE_TRICORE1
|
||||
# define IFX_CFG_CPU_CSTART_ENABLE_TRICORE1 (1) /**< Cpu1 enabled by default*/
|
||||
#endif
|
||||
|
||||
/** \brief Configuration for cache enable.
|
||||
*
|
||||
*/
|
||||
#ifndef IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_PCACHE
|
||||
# define IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_PCACHE (1) /**< Program Cache enabled by default*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_DCACHE
|
||||
# define IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_DCACHE (1) /**< Data Cache enabled by default*/
|
||||
#endif
|
||||
|
||||
#ifndef IFXCPU_CSTART_CCU_INIT_HOOK
|
||||
#define IFXCPU_CSTART_CCU_INIT_HOOK() (void)IfxScuCcu_init(&IfxScuCcu_defaultClockConfig); /*The status returned by Ccu init is ignored */
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
** Imported Function Declarations **
|
||||
*******************************************************************************/
|
||||
IFXCOMPILER_COMMON_LINKER_SYMBOLS()
|
||||
IFXCOMPILER_CORE_LINKER_SYMBOLS(0)
|
||||
|
||||
IFX_EXTERN void core0_main(void); // @suppress("Unused function declaration")
|
||||
#if defined(__TASKING__)
|
||||
__asm("\t .extern core0_main");
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
** Private Constant Definitions **
|
||||
*******************************************************************************/
|
||||
#define IFXCSTART0_PSW_DEFAULT (0x00000980u)
|
||||
#define IFXCSTART0_PCX_O_S_DEFAULT (0xfff00000u)
|
||||
|
||||
/*********************************************************************************
|
||||
* _start() - startup code
|
||||
*********************************************************************************/
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma GCC optimize ("-O2")
|
||||
#endif
|
||||
|
||||
void _Core0_start(void)
|
||||
{
|
||||
uint32 pcxi;
|
||||
uint16 cpuWdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[0]);
|
||||
|
||||
|
||||
|
||||
IFX_CFG_CPU_CSTART_PRE_C_INIT_HOOK(0); /*Test Stack, CSA and Cache */
|
||||
|
||||
/* Load user stack pointer */
|
||||
__setareg(sp, __USTACK(0));
|
||||
__dsync();
|
||||
|
||||
/* Set the PSW to its reset value in case of a warm start,clear PSW.IS */
|
||||
__mtcr(CPU_PSW, IFXCSTART0_PSW_DEFAULT);
|
||||
|
||||
/* Set the PCXS and PCXO to its reset value in case of a warm start */
|
||||
pcxi = __mfcr(CPU_PCXI);
|
||||
pcxi &= IFXCSTART0_PCX_O_S_DEFAULT; /*0xfff00000; */
|
||||
__mtcr(CPU_PCXI, pcxi);
|
||||
|
||||
/*enable/disable program cache depending on the configuration */
|
||||
IfxCpu_setProgramCache(IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_PCACHE);
|
||||
|
||||
/*enable/disable data cache depending on the configuration */
|
||||
IfxCpu_setDataCache(IFX_CFG_CPU_CSTART_ENABLE_TRICORE0_DCACHE);
|
||||
|
||||
/* Clear the ENDINIT bit in the WDT_CON0 register, inline funtion */
|
||||
IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[0], cpuWdtPassword);
|
||||
|
||||
/* Load Base Address of Trap Vector Table. */
|
||||
__mtcr(CPU_BTV, (uint32)__TRAPTAB(0));
|
||||
|
||||
/* Load Base Address of Interrupt Vector Table. we will do this later in the program */
|
||||
__mtcr(CPU_BIV, (uint32)__INTTAB(0));
|
||||
|
||||
/* Load interupt stack pointer. */
|
||||
__mtcr(CPU_ISP, (uint32)__ISTACK(0));
|
||||
|
||||
IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[0], cpuWdtPassword);
|
||||
|
||||
/* initialize SDA base pointers */
|
||||
__setareg(a0, __SDATA1(0));
|
||||
__setareg(a1, __SDATA2(0));
|
||||
|
||||
/* These to be un commented if A8 and A9 are required to be initialized */
|
||||
__setareg(a8, __SDATA3(0));
|
||||
__setareg(a9, __SDATA4(0));
|
||||
/* Setup the context save area linked list. */
|
||||
|
||||
IfxCpu_initCSA((uint32 *)__CSA(0), (uint32 *)__CSA_END(0)); /*Initialize the context save area for CPU0 */
|
||||
{
|
||||
/*CPU and safety watchdogs are enabled by default, C initialization functions are not servicing the watchdogs */
|
||||
uint16 safetyWdtPassword = IfxScuWdt_getSafetyWatchdogPassword();
|
||||
IfxScuWdt_disableCpuWatchdog(cpuWdtPassword);
|
||||
IfxScuWdt_disableSafetyWatchdog(safetyWdtPassword);
|
||||
|
||||
Ifx_C_Init(); /*Initialization of C runtime variables */
|
||||
// IfxScuWdt_enableCpuWatchdog(cpuWdtPassword);
|
||||
// IfxScuWdt_enableSafetyWatchdog(safetyWdtPassword);
|
||||
}
|
||||
|
||||
uint16 password;
|
||||
password = IfxScuWdt_getSafetyWatchdogPassword();
|
||||
IfxScuWdt_clearSafetyEndinitInline(password);
|
||||
MODULE_SCU.RSTCON.U = 0;
|
||||
|
||||
/*Initialize the clock system */
|
||||
IFXCPU_CSTART_CCU_INIT_HOOK();
|
||||
|
||||
/*Start remaining cores */
|
||||
#if (IFX_CFG_CPU_CSTART_ENABLE_TRICORE1 != 0)
|
||||
(void)IfxCpu_startCore(&MODULE_CPU1, (uint32)&_Core1_start); /*The status returned by function call is ignored */
|
||||
#endif
|
||||
|
||||
#if (IFX_CFG_CPU_CSTART_ENABLE_TRICORE0 == 0)
|
||||
IfxScuWdt_disableCpuWatchdog(cpuWdtPassword);
|
||||
/*halt the CPU 0 if it is not needed to be enabled */
|
||||
IfxCpu_setCoreMode(&MODULE_CPU0, IfxCpu_CoreMode_idle);
|
||||
#endif
|
||||
|
||||
/*Call main function of Cpu0 */
|
||||
__non_return_call(core0_main);
|
||||
}
|
||||
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma GCC reset_options
|
||||
#endif
|
||||
/******************************************************************************
|
||||
* reset vector address, user section to inform linker to locate the code at 0x8000 0020
|
||||
*****************************************************************************/
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#pragma section ".start" x
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma protect on
|
||||
#pragma section code "start"
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section CODE ".start" X
|
||||
#endif
|
||||
|
||||
void _START(void)
|
||||
{
|
||||
__non_return_call(_Core0_start);
|
||||
}
|
||||
|
||||
|
||||
/* reset the sections defined above, to normal region */
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma protect restore
|
||||
#pragma section code restore
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section CODE
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
** Boot Mode Headers **
|
||||
*******************************************************************************/
|
||||
/*Boot Mode Header 0 sections to inform linker to locate them at 0x8000 0000 */
|
||||
#ifndef IFX_CFG_CPUCSTART_BMHD_NOT_NEEDED
|
||||
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#pragma section ".bmhd_0" a
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma protect on
|
||||
#pragma section farrom "bmhd_0"
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section CONST ".bmhd_0" R
|
||||
#endif
|
||||
/** \brief Boot Mode Header 0
|
||||
* Boot mode header at memory location 0c8000 0000.
|
||||
*/
|
||||
const uint32 BootModeHeader_0[] = {
|
||||
0x00000000u, /* STADBM first user code at 0x8000 0020h */
|
||||
0xb3590070u, /* BMI = 0070h BMHDID = B359h */
|
||||
0x00000000u, /* ChkStart */
|
||||
0x00000000u, /* ChkEnd */
|
||||
0x00000000u, /* CRCrange */
|
||||
0x00000000u, /* !CRCrange */
|
||||
0x791eb864u, /* CRChead */
|
||||
0x86e1479bu /* !CRChead */
|
||||
};
|
||||
|
||||
/*reset the sections defined above */
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma protect restore
|
||||
#pragma section farrom restore
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section CONST
|
||||
#endif
|
||||
|
||||
#ifndef IFX_CFG_CPUCSTART_BMI01_NOT_NEEDED
|
||||
/*Boot Mode Header 1 sections to inform linker to locate them at 0x8002 0000 */
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#pragma section ".bmhd_1" a
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma protect on
|
||||
#pragma section farrom "bmhd_1"
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section CONST ".bmhd_1" R
|
||||
#endif
|
||||
|
||||
/** \brief Boot Mode Header 1
|
||||
* Boot mode header at memory location 0c8002 0000.
|
||||
*/
|
||||
const uint32 BootModeHeader_1[] = {
|
||||
0x00000000u, /* STADBM first user code at 0x8000 0020h */
|
||||
0xB3590070u, /* BMI = 0070h BMHDID = B359h */
|
||||
0x00000000u, /* ChkStart */
|
||||
0x00000000u, /* ChkEnd */
|
||||
0x00000000u, /* CRCrange */
|
||||
0x00000000u, /* !CRCrange */
|
||||
0x791eb864u, /* CRChead */
|
||||
0x86e1479bu /* !CRChead */
|
||||
};
|
||||
|
||||
/*reset the sections defined above */
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma protect restore
|
||||
#pragma section farrom restore
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section CONST
|
||||
#endif
|
||||
#endif /*IFX_CFG_CPUCSTART_BMI01_NOT_NEEDED*/
|
||||
|
||||
#endif /*IFX_CFG_CPUCSTART_BMHD_NOT_NEEDED*/
|
||||
|
||||
#endif /*#ifndef IFX_CFG_USE_COMPILER_DEFAULT_LINKER */
|
||||
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* \file IfxCpu_Cstart1.c
|
||||
* \brief This file contains the Core startup sequence for Cpu1.
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
/*******************************************************************************
|
||||
** Includes **
|
||||
*******************************************************************************/
|
||||
#include "Ifx_Cfg.h"
|
||||
#ifndef IFX_CFG_USE_COMPILER_DEFAULT_LINKER
|
||||
#include "Scu/Std/IfxScuWdt.h"
|
||||
#include "Cpu/Std/IfxCpu.h"
|
||||
#include "Cpu/CStart/IfxCpu_CStart.h"
|
||||
#include "IfxScu_reg.h"
|
||||
#include "IfxCpu_reg.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* Macros */
|
||||
/******************************************************************************/
|
||||
/** \brief Configuration for cache enable.
|
||||
*
|
||||
*/
|
||||
#ifndef IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_PCACHE
|
||||
# define IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_PCACHE (1) /**< Program Cache enabled by default*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_DCACHE
|
||||
# define IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_DCACHE (1) /**< Data Cache enabled by default*/
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
** Imported Function Declarations **
|
||||
*******************************************************************************/
|
||||
IFXCOMPILER_COMMON_LINKER_SYMBOLS()
|
||||
IFXCOMPILER_CORE_LINKER_SYMBOLS(1)
|
||||
|
||||
IFX_EXTERN void core1_main(void); // @suppress("Unused function declaration")
|
||||
#if defined(__TASKING__)
|
||||
__asm("\t .extern core1_main");
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
** Private Constant Definitions **
|
||||
*******************************************************************************/
|
||||
#define IFXCSTART1_PSW_DEFAULT (0x00000980u)
|
||||
#define IFXCSTART1_PCX_O_S_DEFAULT (0xfff00000u)
|
||||
|
||||
/*********************************************************************************
|
||||
* - startup code
|
||||
*********************************************************************************/
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma GCC optimize ("-O2")
|
||||
#endif
|
||||
|
||||
void _Core1_start(void)
|
||||
{
|
||||
uint32 pcxi;
|
||||
uint16 wdtPassword = IfxScuWdt_getCpuWatchdogPasswordInline(&MODULE_SCU.WDTCPU[1]);
|
||||
|
||||
IFX_CFG_CPU_CSTART_PRE_C_INIT_HOOK(1); /*Test Stack, CSA and Cache */
|
||||
|
||||
/* Load user stack pointer */
|
||||
__setareg(sp, __USTACK(1));
|
||||
__dsync();
|
||||
|
||||
/* Set the PSW to its reset value in case of a warm start,clear PSW.IS */
|
||||
__mtcr(CPU_PSW, IFXCSTART1_PSW_DEFAULT); /* 0x00000980 */
|
||||
|
||||
/* Set the PCXS and PCXO to its reset value in case of a warm start */
|
||||
pcxi = __mfcr(CPU_PCXI);
|
||||
pcxi &= IFXCSTART1_PCX_O_S_DEFAULT; /*0xfff00000; */
|
||||
__mtcr(CPU_PCXI, pcxi);
|
||||
|
||||
/*enable program cache */
|
||||
IfxCpu_setProgramCache(IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_PCACHE);
|
||||
|
||||
/*enable data cache */
|
||||
IfxCpu_setDataCache(IFX_CFG_CPU_CSTART_ENABLE_TRICORE1_DCACHE);
|
||||
|
||||
/* Clear the ENDINIT bit in the WDT_CON0 register, inline funtion */
|
||||
IfxScuWdt_clearCpuEndinitInline(&MODULE_SCU.WDTCPU[1], wdtPassword);
|
||||
|
||||
/* Load Base Address of Trap Vector Table. */
|
||||
__mtcr(CPU_BTV, (uint32)__TRAPTAB(1));
|
||||
|
||||
/* Load Base Address of Interrupt Vector Table. we will do this later in the program */
|
||||
__mtcr(CPU_BIV, (uint32)__INTTAB(1));
|
||||
|
||||
/* Load interupt stack pointer. */
|
||||
__mtcr(CPU_ISP, (uint32)__ISTACK(1));
|
||||
|
||||
IfxScuWdt_setCpuEndinitInline(&MODULE_SCU.WDTCPU[1], wdtPassword);
|
||||
|
||||
/* initialize SDA base pointers */
|
||||
__setareg(a0, __SDATA1(1));
|
||||
__setareg(a1, __SDATA2(1));
|
||||
|
||||
/* These to be un commented if A8 and A9 are required to be initialised */
|
||||
__setareg(a8, __SDATA3(1));
|
||||
__setareg(a9, __SDATA4(1));
|
||||
|
||||
IfxCpu_initCSA((uint32 *)__CSA(1), (uint32 *)__CSA_END(1));
|
||||
|
||||
/*Call main function of Cpu0 */
|
||||
__non_return_call(core1_main);
|
||||
}
|
||||
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma GCC reset_options
|
||||
#endif
|
||||
#endif /*#ifndef IFX_CFG_USE_COMPILER_DEFAULT_LINKER */
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* \file IfxCpu_Irq.c
|
||||
* \brief This file contains the APIs for Interrupt related functions.
|
||||
*
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
** Includes **
|
||||
*******************************************************************************/
|
||||
#include "Cpu/Irq/IfxCpu_Irq.h"
|
||||
#include "Tricore/Compilers/Compilers.h"
|
||||
#include "Cpu/Std/IfxCpu_Intrinsics.h"
|
||||
#include "IfxCpu_reg.h"
|
||||
|
||||
/*******************************************************************************
|
||||
** Private macros **
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
** Global variables/constants **
|
||||
*******************************************************************************/
|
||||
#if defined(IFX_USE_SW_MANAGED_INT)
|
||||
|
||||
typedef void (*Ifx_Isr)(void);
|
||||
|
||||
static Ifx_Isr IfxCpu_Irq_swIntVector[256];
|
||||
|
||||
#endif /*defined(IFX_USE_SW_MANAGED_INT) */
|
||||
|
||||
/*******************************************************************************
|
||||
** Global Function definitions **
|
||||
*******************************************************************************/
|
||||
#if defined(IFX_USE_SW_MANAGED_INT)
|
||||
|
||||
/** \brief API to install the interrupt service routine for Software Managed Interrupts.
|
||||
*
|
||||
*/
|
||||
void IfxCpu_Irq_installInterruptHandler(void *isrFuncPointer, uint32 serviceReqPrioNumber)
|
||||
{
|
||||
IfxCpu_Irq_swIntVector[serviceReqPrioNumber] = (Ifx_Isr)isrFuncPointer;
|
||||
}
|
||||
|
||||
|
||||
/** SW managed Interrupt vector table
|
||||
*
|
||||
* This is vector table with single entry for Software Managed Interrupts.
|
||||
* This function need to be located at boundary 0xXFE0 where (X=1,3,5 and so on). For the software managed
|
||||
* interrupts to work correctly, the BIV must be set to address of this function.
|
||||
*
|
||||
*/
|
||||
IFX_INTERRUPT_INTERNAL(IfxCpu_Irq_intVecTable, 0, 255)
|
||||
{
|
||||
Ifx_CPU_ICR icr;
|
||||
|
||||
icr.U = __mfcr(CPU_ICR); /*Fetch the ICR value */
|
||||
|
||||
/*Call the ISR */
|
||||
IfxCpu_Irq_swIntVector[icr.B.CCPN]();
|
||||
}
|
||||
|
||||
#endif /*defined(IFX_USE_SW_MANAGED_INT) */
|
||||
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
* \file IfxCpu_Irq.h
|
||||
* \brief This file contains the APIs for Interrupt related functions.
|
||||
*
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_Irq Interrupt Functions
|
||||
* \ingroup IfxLld_Cpu
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_Irq_Usage How to define Interrupts?
|
||||
* \ingroup IfxLld_Cpu_Irq
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_Irq_Functions Functions
|
||||
* \ingroup IfxLld_Cpu_Irq
|
||||
*
|
||||
*/
|
||||
#ifndef IFXCPU_IRQ_H_
|
||||
#define IFXCPU_IRQ_H_
|
||||
|
||||
/*******************************************************************************
|
||||
** Includes **
|
||||
*******************************************************************************/
|
||||
#include "Ifx_Cfg.h"
|
||||
#include "Cpu/Std/Ifx_Types.h"
|
||||
#include "Cpu/Std/IfxCpu.h"
|
||||
#include "Src/Std/IfxSrc.h"
|
||||
/*******************************************************************************
|
||||
** Type definitions **
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
** Global Exported variables/constants **
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
** Global Exported macros/inlines/function ptototypes **
|
||||
*******************************************************************************/
|
||||
|
||||
#if defined(IFX_USE_SW_MANAGED_INT)
|
||||
/** \addtogroup IfxLld_Cpu_Irq_Functions
|
||||
* \{ */
|
||||
/** \brief API for Interrupt handler install for SW Managed interrupts.
|
||||
* This API installs the isr to SW interrupt vector.
|
||||
* This must be used only when IFX_USE_SW_MANAGED_INT is defined in Ifx_Cfg.h
|
||||
*
|
||||
* \param isrFuncPointer pointer to ISR function.
|
||||
* \param serviceReqPrioNumber ISR priority.
|
||||
*/
|
||||
|
||||
IFX_EXTERN void IfxCpu_Irq_installInterruptHandler(void *isrFuncPointer, uint32 serviceReqPrioNumber);
|
||||
|
||||
IFX_INLINE void interruptHandlerInstall(uint32 srpn, uint32 addr)
|
||||
{
|
||||
IfxCpu_Irq_installInterruptHandler((void *)addr, srpn);
|
||||
}
|
||||
|
||||
|
||||
/** \} */
|
||||
#endif /*defined(IFX_USE_SW_MANAGED_INT) */
|
||||
|
||||
/** \addtogroup IfxLld_Cpu_Irq_Functions
|
||||
* \{ */
|
||||
/** \brief API to get type of service of the caller CPU.
|
||||
* \param coreId core id of the core
|
||||
* \return type of service for the corresponding CPU.
|
||||
*/
|
||||
IFX_INLINE IfxSrc_Tos IfxCpu_Irq_getTos(IfxCpu_ResourceCpu coreId)
|
||||
{
|
||||
return (IfxSrc_Tos)coreId;
|
||||
}
|
||||
|
||||
|
||||
/** \} */
|
||||
|
||||
/*Documentation */
|
||||
/** \addtogroup IfxLld_Cpu_Irq_Usage
|
||||
* \{
|
||||
*
|
||||
* This page describes how to use interrupts with application framework.\n
|
||||
*
|
||||
* \section IfxLld_Cpu_Irq_Terminology Interrupts Terminology:
|
||||
* \subsection IfxLld_Cpu_Irq_HWManaged Hardware Managed Interrupt Mechanism.
|
||||
* Hardware managed interrupts have static interrupt vector which are defined for each priority separately.
|
||||
* These vectors have jump instruction to the interrupt handler.
|
||||
*
|
||||
* Advantages:\n
|
||||
* This mechanism has less interrupt latency time.
|
||||
*
|
||||
* \subsection IfxLld_Cpu_Irq_SWManaged Software Managed Interrupt Mechanism.
|
||||
* Software managed interrupts have single interrupt vector statically defined at vector position 255.
|
||||
* This address is assigned to BIV during startup.\n
|
||||
* For Tricore, this vector position is important, because whenever an interrupt occurs, with whichever priority,
|
||||
* the execution control jumps to this vector position. The code at this vector position will:\n
|
||||
* 1) fetch the priority of the targetted interrupt.\n
|
||||
* 2) fetch the interrupt handler defined for this priority (this is done by Interrupt handler installation. Refer
|
||||
* \ref IfxLld_Cpu_Irq_Step4\n
|
||||
* 3) Then call the handler as notmal function call.
|
||||
*
|
||||
* Advantages:\n
|
||||
* This kind of mechanism is useful when project wants to change the handler for an interrupt during runtime.
|
||||
*
|
||||
* Disadvantages:\n
|
||||
* This mechanism has more interrupt latency time.
|
||||
*
|
||||
* of the interrupt and in tand jumps to the function
|
||||
*
|
||||
* \section IfxLld_Cpu_Irq_Steps Steps to use Interrupt Mechanism.
|
||||
* Dependency: Ifx_Compilers, Ifx_Cpu, Ifx_Src, IfxCpu_Irq\n
|
||||
* Following are the steps to use interrupt mechanism.
|
||||
*
|
||||
* \section IfxLld_Cpu_Irq_Step1 Step1: Define Interrupt priorities.
|
||||
* Define priorities of all interrupts with names corresponding to their functionality. It is recommended to define
|
||||
* such priority definitions in single header file, because it is easy to detect if ISR priorities are conflicting.
|
||||
* In Tricore architecture, two Isrs can't have same priority at same point of time.
|
||||
* \note These defines shall be defined without brackets surrounding priority number. (eg. #define PRIO (10) is not allowed)
|
||||
*
|
||||
* In a user defined file eg. Ifx_IntPrioDef.h, placed in folder: 0_AppSw/Tricore/DemoApp:
|
||||
* \code
|
||||
* //file: Ifx_IntPrioDef.h.
|
||||
* #define IFX_INTPRIO_FUNCT1 1
|
||||
* #define IFX_INTPRIO_FUNCT2 2
|
||||
* #define IFX_INTPRIO_FUNCT3 5
|
||||
* #define IFX_INTPRIO_STM0 8
|
||||
* #define IFX_INTPRIO_ADC_FUNC1 10
|
||||
* //etc.
|
||||
* \endcode
|
||||
*
|
||||
* \note !! IMPORTANT !!\n As explained above, the definition with closing bracket around priority number as,
|
||||
* #define IFX_INTPRIO_FUNCT1 (1) will cause compilation error. Because linker sections which are constructed
|
||||
* using such information will also get these brackets included. Which look like ".intvec_tc0_(1)" instead of the
|
||||
* expected ".intvec_tc0_1"\n
|
||||
* Linker sections' definitions are predefined statically in .lsl file,
|
||||
* for all 255 interrupts, with the format ".intvec_tc<vector number>_<interrupt priority>".
|
||||
*
|
||||
* \section IfxLld_Cpu_Irq_Step2 Step2: Define Type of interrupt mechanism.
|
||||
* \subsection IfxLld_Cpu_Irq_HWManaged_Usage To use Hardware Managed Interrupt Mechanism.
|
||||
* Refer \ref IfxLld_Cpu_Irq_HWManaged
|
||||
* If project is designed for hardware managed interrupts, this feature is enabled at the file Ifx_Cfg.h, at path:
|
||||
* 0_Src/0_AppSw/Config/Common/, as shown below. IFX_USE_SW_MANAGED_INT definition must be undefined (i.e. the
|
||||
* statement "#define IFX_USE_SW_MANAGED_INT" shall be commented as below).
|
||||
*
|
||||
* \code
|
||||
* //file: Ifx_Cfg.h
|
||||
*
|
||||
* //#define IFX_USE_SW_MANAGED_INT
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Cpu_Irq_SWManaged_Usage To use Software Managed Interrupt Mechanism.
|
||||
* Refer \ref IfxLld_Cpu_Irq_SWManaged
|
||||
* If project is designed for software managed interrupts, this feature is enabled at the file Ifx_Cfg.h, at path:
|
||||
* 0_Src/0_AppSw/Config/Common/, as shown below.
|
||||
* IFX_USE_SW_MANAGED_INT definition must be defined.
|
||||
*
|
||||
* \code
|
||||
* //file: Ifx_Cfg.h
|
||||
*
|
||||
* #define IFX_USE_SW_MANAGED_INT
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* Software managed interrupts must also install the "Interrupt Handlers" Refer \ref IfxLld_Cpu_Irq_Step4
|
||||
*
|
||||
* \section IfxLld_Cpu_Irq_Step3 Step3: How to define an Interrupt Service routine?
|
||||
* Interrupt service routines or interrupt handlers are defined in driver specific files or application specific
|
||||
* files.
|
||||
*
|
||||
* \code
|
||||
* //file usercode1.c
|
||||
* #include "Compilers.h" // to get the compiler abstracted macros for interrupt definition
|
||||
* #include "Ifx_IntPrioDef.h" // to get the priority numbers
|
||||
*
|
||||
* //define an ISR with name Isr_Stm0 with priority defined by IFX_INTPRIO_STM0
|
||||
* IFX_INTERRUPT (Isr_Stm0, 0, IFX_INTPRIO_STM0)
|
||||
* {
|
||||
* //Isr code here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \code
|
||||
* //file usercode2.c
|
||||
* #include "Compilers.h" // to get the compiler abstracted macros for interrupt definition
|
||||
* #include "Ifx_IntPrioDef.h" // to get the priority numbers
|
||||
*
|
||||
* //define an ISR with name Isr_Adc_fun1 with priority defined by IFX_INTPRIO_ADC_FUNC1
|
||||
* IFX_INTERRUPT (Isr_Adc_fun1, 0, IFX_INTPRIO_ADC_FUNC1)
|
||||
* {
|
||||
* //Isr code here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \section IfxLld_Cpu_Irq_Step4 Step4: How to install Interrupt Service routine/handler?
|
||||
* This step is not required for HW managed interrupts.\n
|
||||
* Interrupt service routines or interrupt handlers are installed in driver specific files or application specific
|
||||
* files
|
||||
*
|
||||
* \code
|
||||
* //file usermain.c
|
||||
* #include "IfxCpu_Irq.h"
|
||||
* #include "Ifx_IntPrioDef.h" // to get the priority numbers
|
||||
*
|
||||
* void userfunction_init(void)
|
||||
* {
|
||||
* //code for user function init
|
||||
* // :
|
||||
* // :
|
||||
* IfxCpu_Irq_installInterruptHandler (Isr_Stm0, IFX_INTPRIO_STM0);
|
||||
* IfxCpu_Irq_installInterruptHandler (Isr_Adc_fun1, IFX_INTPRIO_ADC_FUNC1);
|
||||
*
|
||||
* // :
|
||||
* }
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \section IfxLld_Cpu_Irq_Step5 Step5: Managing the Service Request Node.
|
||||
* For the interrupt to get activated, interrupt triggers are needed. These triggers are activated by peripheral modules
|
||||
* and corresponding service request node must be\n
|
||||
* 1) Configured with correct priority number\n
|
||||
* 2) The request node must be enabled\n
|
||||
* Refer to \ref IfxLld_Src_Usage
|
||||
*/
|
||||
|
||||
/** \} */
|
||||
#endif /* IFXCPU_IRQ_H_ */
|
||||
@@ -0,0 +1,362 @@
|
||||
/**
|
||||
* \file IfxCpu.c
|
||||
* \brief CPU basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxCpu.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
boolean IfxCpu_acquireMutex(IfxCpu_mutexLock *lock)
|
||||
{
|
||||
boolean retVal;
|
||||
volatile uint32 spinLockVal;
|
||||
|
||||
retVal = FALSE;
|
||||
|
||||
spinLockVal = 1UL;
|
||||
spinLockVal =
|
||||
(uint32)__cmpAndSwap(((unsigned int *)lock), spinLockVal, 0);
|
||||
|
||||
/* Check if the SpinLock WAS set before the attempt to acquire spinlock */
|
||||
if (spinLockVal == 0)
|
||||
{
|
||||
retVal = TRUE;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
IfxCpu_CoreMode IfxCpu_getCoreMode(Ifx_CPU *cpu)
|
||||
{
|
||||
IfxCpu_CoreMode cpuMode;
|
||||
Ifx_CPU_DBGSR dbgsr;
|
||||
IfxCpu_ResourceCpu index = IfxCpu_getIndex(cpu);
|
||||
|
||||
cpuMode = IfxCpu_CoreMode_unknown;
|
||||
|
||||
/*get the DBGSR.HALT status */
|
||||
/*Check if the request is done for same cpu as the host for this call */
|
||||
if (IfxCpu_getCoreIndex() != index)
|
||||
{ /*status request is for other cpu than the host */
|
||||
dbgsr = cpu->DBGSR;
|
||||
}
|
||||
else
|
||||
{ /*status request is for same cpu as the host */
|
||||
dbgsr.U = __mfcr(CPU_DBGSR);
|
||||
}
|
||||
|
||||
/*Check if the requested CPU is in DBG HALT mode */
|
||||
if (dbgsr.B.HALT == (uint32)IfxCpu_DBGST_HALT_halt)
|
||||
{ /*CPU is in DBG HALT mode */
|
||||
cpuMode = IfxCpu_CoreMode_halt;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dbgsr.B.HALT == (uint32)IfxCpu_DBGST_HALT_run)
|
||||
{ /*CPU is in DBG RUNNING mode now check PMCSR status */
|
||||
volatile Ifx_SCU_PMCSR *pmcsr_val;
|
||||
|
||||
pmcsr_val = &MODULE_SCU.PMCSR[index];
|
||||
|
||||
if (pmcsr_val->B.PMST == (uint32)IfxCpu_PMCSR_PMST_normalMode)
|
||||
{ /*Cpu is in normal run mode */
|
||||
cpuMode = IfxCpu_CoreMode_run;
|
||||
}
|
||||
else
|
||||
{ /*Cpu is not in run mode */
|
||||
if (pmcsr_val->B.PMST == (uint32)IfxCpu_PMCSR_PMST_idleMode)
|
||||
{ /*Cpu is in idle mode */
|
||||
cpuMode = IfxCpu_CoreMode_idle;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuMode = IfxCpu_CoreMode_unknown;
|
||||
}
|
||||
}
|
||||
|
||||
return cpuMode;
|
||||
}
|
||||
|
||||
|
||||
IfxCpu_ResourceCpu IfxCpu_getIndex(Ifx_CPU *cpu)
|
||||
{
|
||||
IfxCpu_ResourceCpu result;
|
||||
uint32 index;
|
||||
result = IfxCpu_ResourceCpu_none;
|
||||
|
||||
for (index = 0; index < IFXCPU_NUM_MODULES; index++)
|
||||
{
|
||||
if (IfxCpu_cfg_indexMap[index].module == cpu)
|
||||
{
|
||||
result = (IfxCpu_ResourceCpu)IfxCpu_cfg_indexMap[index].index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxCpu_getRandomValue(uint32 *seed)
|
||||
{
|
||||
/*************************************************************************
|
||||
* the choice of a and m is important for a long period of the LCG
|
||||
* with a = 279470273 and
|
||||
* m = 4294967291
|
||||
* a maximum period of 2^32-5 is given
|
||||
* values for a:
|
||||
* 0x5EB0A82F = 1588635695
|
||||
* 0x48E7211F = 1223106847
|
||||
* 0x10a860c1 = 279470273
|
||||
***************************************************************************/
|
||||
uint32 x = *seed;
|
||||
|
||||
/* a seed of 0 is not allowed, and therefore will be changed to a valid value */
|
||||
if (x == 0)
|
||||
{
|
||||
x = 42;
|
||||
}
|
||||
|
||||
uint32 a = 0x10a860c1; // 279470273
|
||||
uint32 m = 0xfffffffb; // 4294967291
|
||||
uint32 result;
|
||||
|
||||
//__asm(a,m,x,tmp1,tmp2 );
|
||||
//EhEl = a * x;
|
||||
//result = e14 % m;
|
||||
// %0 result
|
||||
// %1 a
|
||||
// %2 x
|
||||
// %3 m
|
||||
result = IfxCpu_getRandomVal(a, x, m);
|
||||
|
||||
*seed = result; // to simplify seed passing
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxCpu_getRandomValueWithinRange(uint32 *seed, uint32 min, uint32 max)
|
||||
{
|
||||
uint32 new_value = IfxCpu_getRandomValue(seed);
|
||||
|
||||
/* swap min/max if required */
|
||||
if (min > max)
|
||||
{
|
||||
unsigned swap = max;
|
||||
max = min;
|
||||
min = swap;
|
||||
}
|
||||
|
||||
/* special case */
|
||||
if ((min == 0) && (max == 0xffffffff))
|
||||
{
|
||||
return new_value;
|
||||
}
|
||||
|
||||
/* return value within range */
|
||||
return (new_value % (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_releaseMutex(IfxCpu_mutexLock *lock)
|
||||
{
|
||||
/*Reset the SpinLock*/
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_resetSpinLock(IfxCpu_spinLock *lock)
|
||||
{
|
||||
/*Reset the SpinLock*/
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCpu_setCoreMode(Ifx_CPU *cpu, IfxCpu_CoreMode mode)
|
||||
{
|
||||
uint8 reqslp;
|
||||
boolean retValue;
|
||||
IfxCpu_ResourceCpu index = IfxCpu_getIndex(cpu);
|
||||
|
||||
/*Modes such as HALT, SLEEP and STBY are not handled at CPU level */
|
||||
retValue = ((mode == IfxCpu_CoreMode_halt) || (mode == IfxCpu_CoreMode_sleep)
|
||||
|| (mode == IfxCpu_CoreMode_stby)) ? FALSE : TRUE;
|
||||
|
||||
reqslp = (mode == IfxCpu_CoreMode_idle) ? IfxScu_PMCSR_REQSLP_Idle : IfxScu_PMCSR_REQSLP_Run;
|
||||
|
||||
if (retValue == TRUE)
|
||||
{
|
||||
/*Check if the same core is requesting to change the core run mode */
|
||||
if (IfxCpu_getCoreIndex() != index)
|
||||
{ /*Request is for the other core */
|
||||
/*To access PMCSR of other CPUs handle the safety EndInit protection */
|
||||
uint16 safetyWdtPw = IfxScuWdt_getSafetyWatchdogPassword();
|
||||
IfxScuWdt_clearSafetyEndinit(safetyWdtPw);
|
||||
MODULE_SCU.PMCSR[(uint32)IfxCpu_getIndex(cpu)].B.REQSLP = reqslp;
|
||||
IfxScuWdt_setSafetyEndinit(safetyWdtPw);
|
||||
|
||||
cpu->DBGSR.B.HALT = 2; /*reset the HALT bit, if it is already done it is no harm in writing again */
|
||||
}
|
||||
else
|
||||
{ /*Request is for self, this request normally only for halt, otherwise the core is already running anyway! */
|
||||
/*To access PMCSR of self handle the cpu EndInit protection */
|
||||
uint16 cpuWdtPw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(cpuWdtPw);
|
||||
MODULE_SCU.PMCSR[(uint32)index].B.REQSLP = reqslp;
|
||||
IfxScuWdt_setCpuEndinit(cpuWdtPw);
|
||||
}
|
||||
}
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCpu_setProgramCounter(Ifx_CPU *cpu, uint32 programCounter)
|
||||
{
|
||||
boolean retVal = TRUE;
|
||||
|
||||
if (cpu == IfxCpu_getAddress(IfxCpu_getCoreIndex()))
|
||||
{
|
||||
retVal = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->PC.B.PC = programCounter >> 1;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCpu_setSpinLock(IfxCpu_spinLock *lock, uint32 timeoutCount)
|
||||
{
|
||||
boolean retVal;
|
||||
volatile uint32 spinLockVal;
|
||||
|
||||
retVal = FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
spinLockVal = 1UL;
|
||||
spinLockVal =
|
||||
(uint32)__cmpAndSwap(((unsigned int *)lock), spinLockVal, 0);
|
||||
|
||||
/* Check if the SpinLock WAS set before the attempt to acquire spinlock */
|
||||
if (spinLockVal == 0)
|
||||
{
|
||||
retVal = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeoutCount--;
|
||||
}
|
||||
} while ((retVal == FALSE) && (timeoutCount > 0));
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCpu_startCore(Ifx_CPU *cpu, uint32 programCounter)
|
||||
{
|
||||
boolean retVal = TRUE;
|
||||
|
||||
/* Set the PC for Core 1 */
|
||||
retVal &= IfxCpu_setProgramCounter(cpu, programCounter);
|
||||
/* Get the mode for Core 1 and set it to RUNNING */
|
||||
|
||||
/* Core not running already */
|
||||
if (IfxCpu_getCoreMode(cpu) == IfxCpu_CoreMode_halt)
|
||||
{
|
||||
retVal &= IfxCpu_setCoreMode(cpu, IfxCpu_CoreMode_run);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxCpu_waitEvent(IfxCpu_syncEvent *event, uint32 timeoutMilliSec)
|
||||
{
|
||||
volatile uint32 *sync = (volatile uint32 *)IFXCPU_GLB_ADDR_DSPR(__mfcr(CPU_CORE_ID), event);
|
||||
|
||||
boolean errorcnt = 0U;
|
||||
/* Divide with 1000, gives the count value equivalent to milliseconds */
|
||||
uint32 stmCount = (uint32)((IfxScuCcu_getStmFrequency() / 1000) * timeoutMilliSec);
|
||||
uint32 stmCountBegin = STM0_TIM0.U;
|
||||
|
||||
while ((*sync & IFXCPU_CFG_ALLCORE_DONE) != IFXCPU_CFG_ALLCORE_DONE)
|
||||
{
|
||||
__nop();
|
||||
|
||||
if ((uint32)(STM0_TIM0.U - stmCountBegin) >= stmCount)
|
||||
{
|
||||
errorcnt = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* There is no need to check overflow of the STM timer.
|
||||
* When counter after overflow subtracted with counter before overflow,
|
||||
* the subtraction result will be as expected, as long as both are unsigned 32 bits
|
||||
* eg: stmCountBegin= 0xFFFFFFFE (before overflow)
|
||||
* stmCountNow = 0x00000002 (before overflow)
|
||||
* diff= stmCountNow - stmCountBegin = 4 as expected.*/
|
||||
}
|
||||
|
||||
return errorcnt;
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_emitEvent(IfxCpu_syncEvent *event)
|
||||
{
|
||||
Ifx__imaskldmst(event, 1, __mfcr(CPU_CORE_ID), 1);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* \file IfxCpu_Intrinsics.h
|
||||
* \ingroup IfxLld_Cpu_Intrinsics Intrinsics
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_Intrinsics Intrinsics
|
||||
* \ingroup IfxLld_Cpu_Std
|
||||
*
|
||||
*/
|
||||
#ifndef IFXCPU_INTRINSICS_H
|
||||
#define IFXCPU_INTRINSICS_H
|
||||
/******************************************************************************/
|
||||
#include "Ifx_Types.h"
|
||||
|
||||
#if defined(__DCC__)
|
||||
#include "IfxCpu_IntrinsicsDcc.h"
|
||||
|
||||
#elif defined(__HIGHTEC__)
|
||||
#include "IfxCpu_IntrinsicsGnuc.h"
|
||||
|
||||
#elif defined(__TASKING__)
|
||||
#include "IfxCpu_IntrinsicsTasking.h"
|
||||
|
||||
#elif defined(__ghs__)
|
||||
#include "IfxCpu_IntrinsicsGhs.h"
|
||||
|
||||
#else
|
||||
#error Compiler unsupported
|
||||
#endif
|
||||
|
||||
#define IFX_ALIGN_8 (1) // Align on 8 bit Boundary
|
||||
#define IFX_ALIGN_16 (2) // Align on 16 bit Boundary
|
||||
#define IFX_ALIGN_32 (4) // Align on 32 bit Boundary
|
||||
#define IFX_ALIGN_64 (8) // Align on 64 bit Boundary
|
||||
#define IFX_ALIGN_128 (16) // Align on 128 bit Boundary
|
||||
#define IFX_ALIGN_256 (32) // Align on 256 bit Boundary
|
||||
|
||||
#define Ifx_AlignOn256(Size) ((((Size) + (IFX_ALIGN_256 - 1)) & (~(IFX_ALIGN_256 - 1))))
|
||||
#define Ifx_AlignOn128(Size) ((((Size) + (IFX_ALIGN_128 - 1)) & (~(IFX_ALIGN_128 - 1))))
|
||||
#define Ifx_AlignOn64(Size) ((((Size) + (IFX_ALIGN_64 - 1)) & (~(IFX_ALIGN_64 - 1))))
|
||||
#define Ifx_AlignOn32(Size) ((((Size) + (IFX_ALIGN_32 - 1)) & (~(IFX_ALIGN_32 - 1))))
|
||||
#define Ifx_AlignOn16(Size) ((((Size) + (IFX_ALIGN_16 - 1)) & (~(IFX_ALIGN_16 - 1))))
|
||||
#define Ifx_AlignOn8(Size) ((((Size) + (IFX_ALIGN_8 - 1)) & (~(IFX_ALIGN_8 - 1))))
|
||||
|
||||
#define Ifx_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
//______________________________________________________________________________
|
||||
|
||||
/** Convert context pointer to address pointer
|
||||
* \param[in] cx context pointer
|
||||
* \return address pointer
|
||||
*/
|
||||
IFX_INLINE void *__cx_to_addr(uint32 cx)
|
||||
{
|
||||
uint32 seg_nr = __extru(cx, 16, 4);
|
||||
return (void *)__insert(seg_nr << 28, cx, 6, 16);
|
||||
}
|
||||
|
||||
|
||||
/** Convert address pointer to context pointer
|
||||
* \param[in] addr address pointer
|
||||
* \return context pointer
|
||||
*/
|
||||
IFX_INLINE uint32 __addr_to_cx(void *addr)
|
||||
{
|
||||
uint32 seg_nr, seg_idx;
|
||||
seg_nr = __extru((int)addr, 28, 4) << 16;
|
||||
seg_idx = __extru((int)addr, 6, 16);
|
||||
return seg_nr | seg_idx;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
IFX_INLINE void __ldmst_c(volatile void *address, unsigned mask, unsigned value)
|
||||
{
|
||||
*(volatile uint32 *)address = (*(volatile uint32 *)address & ~(mask)) | (mask & value);
|
||||
}
|
||||
|
||||
|
||||
/** 32bit load operation
|
||||
*/
|
||||
IFX_INLINE uint32 __ld32(void *addr)
|
||||
{
|
||||
return *(volatile uint32 *)addr;
|
||||
}
|
||||
|
||||
|
||||
/** 32bit store operation
|
||||
*/
|
||||
IFX_INLINE void __st32(void *addr, uint32 value)
|
||||
{
|
||||
*(volatile uint32 *)addr = value;
|
||||
}
|
||||
|
||||
|
||||
/** 64bit load operation
|
||||
*/
|
||||
IFX_INLINE uint64 __ld64(void *addr)
|
||||
{
|
||||
return *(volatile uint64 *)addr;
|
||||
}
|
||||
|
||||
|
||||
/** 64bit store operation
|
||||
*/
|
||||
IFX_INLINE void __st64(void *addr, uint64 value)
|
||||
{
|
||||
*(volatile uint64 *)addr = value;
|
||||
}
|
||||
|
||||
|
||||
/** 64bit load operation which returns the lower and upper 32bit word
|
||||
*/
|
||||
IFX_INLINE void __ld64_lu(void *addr, uint32 *valueLower, uint32 *valueUpper)
|
||||
{
|
||||
register uint64 value;
|
||||
value = __ld64(addr);
|
||||
*valueLower = (uint32)value;
|
||||
*valueUpper = (uint32)(value >> 32);
|
||||
}
|
||||
|
||||
|
||||
/** 64bit store operation which stores a lower and upper 32bit word
|
||||
*/
|
||||
IFX_INLINE void __st64_lu(void *addr, uint32 valueLower, uint32 valueUpper)
|
||||
{
|
||||
register uint64 value = ((uint64)valueUpper << 32) | valueLower;
|
||||
__st64(addr, value);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
#endif /* IFXCPU_INTRINSICS_H */
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,639 @@
|
||||
/**
|
||||
* \file IfxCpu_IntrinsicsTasking.h
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_Intrinsics_Tasking Intrinsics for TASKING compiler
|
||||
* \ingroup IfxLld_Cpu_Intrinsics
|
||||
*
|
||||
*/
|
||||
#ifndef IFXCPU_INTRINSICSTASKING_H
|
||||
#define IFXCPU_INTRINSICSTASKING_H
|
||||
/******************************************************************************/
|
||||
#include "Ifx_Types.h"
|
||||
/******************************************************************************/
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
#ifndef __cplusplus
|
||||
/** Function call without return
|
||||
*/
|
||||
#define Ifx__non_return_call(fun) __asm("\tji %0"::"a"(fun))
|
||||
|
||||
/** Jump and link
|
||||
*/
|
||||
IFX_INLINE void Ifx__jump_and_link(void (*fun)(void))
|
||||
{
|
||||
__asm("jli %0"::"a"(fun));
|
||||
}
|
||||
|
||||
IFX_INLINE void Ifx__moveToDataParam0(unsigned int var)
|
||||
{
|
||||
__asm("mov d4, %0"::"d"(var));
|
||||
}
|
||||
|
||||
IFX_INLINE void Ifx__moveToAddrParam0(const void *var)
|
||||
{
|
||||
__asm("mov.aa a4, %0"::"a"(var));
|
||||
}
|
||||
|
||||
IFX_INLINE unsigned int Ifx__getDataParamRet(void)
|
||||
{
|
||||
unsigned int var;
|
||||
__asm(" mov\t %0, d2":"=d"(var));
|
||||
return var;
|
||||
}
|
||||
|
||||
IFX_INLINE void Ifx__moveToDataParamRet(unsigned int var)
|
||||
{
|
||||
__asm("mov d2, %0"::"d"(var));
|
||||
}
|
||||
|
||||
IFX_INLINE void Ifx__jumpToFunction(const void *fun)
|
||||
{
|
||||
Ifx__non_return_call(fun);
|
||||
}
|
||||
|
||||
IFX_INLINE void Ifx__jumpToFunctionWithLink(const void *fun)
|
||||
{
|
||||
Ifx__jump_and_link((void (*)(void))fun);
|
||||
}
|
||||
|
||||
IFX_INLINE void Ifx__jumpBackToLink(void)
|
||||
{
|
||||
__asm("ji a11");
|
||||
}
|
||||
#endif
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_any_type Cross type arithmetic operation
|
||||
*
|
||||
* Macro compatible with float, fix point, signed integer and unsigned integer
|
||||
*
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
#define Ifx__minX(X,Y) ( ((X) < (Y)) ? (X) : (Y) )
|
||||
#define Ifx__maxX(X,Y) ( ((X) > (Y)) ? (X) : (Y) )
|
||||
#define Ifx__saturateX(X,Min,Max) ( Ifx__minX(Ifx__maxX(X, Min), Max) )
|
||||
#define Ifx__checkrangeX(X,Min,Max) (((X) >= (Min)) && ((X) <= (Max)))
|
||||
/** \} */
|
||||
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_singed_integer Signed integer operation
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
#define Ifx__saturate(X,Min,Max) ( __min(__max(X, Min), Max) )
|
||||
/** \} */
|
||||
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_unsinged_integer Unsigned integer operation
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
#define Ifx__saturateu(X,Min,Max) ( __minu(__maxu(X, Min), Max) )
|
||||
/** \} */
|
||||
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_float Floating point operation
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
#define Ifx__checkrange(X,Min,Max) (((X) >= (Min)) && ((X) <= (Max)))
|
||||
|
||||
#define Ifx__sqrf(X) ((X) * (X))
|
||||
#define Ifx__sqrtf(X) sqrtf(X)
|
||||
|
||||
#define Ifx__roundf(X) ((((X) - (int)(X)) > 0.5) ? (1 + (int)(X)) : ((int)(X)))
|
||||
#define Ifx__absf(X) ( ((X) < 0.0) ? -(X) : (X) )
|
||||
#define Ifx__minf(X,Y) ( ((X) < (Y)) ? (X) : (Y) )
|
||||
#define Ifx__maxf(X,Y) ( ((X) > (Y)) ? (X) : (Y) )
|
||||
#define Ifx__saturatef(X,Min,Max) ( Ifx__minf(_Ifx_maxf(X, Min), Max) )
|
||||
#define Ifx__checkrangef(X,Min,Max) (((X) >= (Min)) && ((X) <= (Max)))
|
||||
|
||||
#define Ifx__abs_stdreal(X) ( ((X) > 0.0) ? (X) : -(X) )
|
||||
#define Ifx__min_stdreal(X,Y) ( ((X) < (Y)) ? (X) : (Y) )
|
||||
#define Ifx__max_stdreal(X,Y) ( ((X) > (Y)) ? (X) : (Y) )
|
||||
#define Ifx__saturate_stdreal(X,Min,Max) ( Ifx__min_stdreal(Ifx__max_stdreal(X, Min), Max) )
|
||||
|
||||
#define Ifx__neqf(X,Y) ( ((X) > (Y)) || ((X) < (Y)) ) /**< X != Y */
|
||||
#define Ifx__leqf(X,Y) ( !((X) > (Y)) ) /**< X <= Y */
|
||||
#define Ifx__geqf(X,Y) ( !((X) < (Y)) ) /**< X >= Y */
|
||||
/** \} */
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_fractional Fractional Arithmetic Support
|
||||
The next table provides an overview of intrinsic functions to convert fractional values. Note that the
|
||||
TASKING VX-toolset C compiler for TriCore fully supports the fractional type so normally you should not
|
||||
need these intrinsic functions (except for __mulfractlong). For compatibility reasons the TASKING C
|
||||
compiler does support these functions.
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
#define Ifx__fract_to_float(value) ((float)(value))
|
||||
|
||||
#define Ifx__mulfractlong __mulfractlong
|
||||
|
||||
#define Ifx__mulfractfract(fractvalue1,fractvalue2) ((fractvalue1)*(fractvalue2))
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_insert Insert / Extract Bit-fields and Bits
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
|
||||
#define Ifx__extru(a, p, w) __extru(a,p,w)
|
||||
|
||||
#define Ifx__extr(a, p, w) __extr(a,p,w)
|
||||
|
||||
#define Ifx__imaskldmst(a, v, b, p) __imaskldmst((int*)a, v, b, p)
|
||||
|
||||
#define Ifx__insert(a,b,p,w) __insert(a,b,p,w)
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_interrupt_handling Interrupt Handling
|
||||
The next table provides an overview of the intrinsic functions to read or set interrupt handling.
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
#define Ifx__disable_and_save __disable_and_save
|
||||
|
||||
#define Ifx__restore __restore
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_miscellaneous Miscellaneous Intrinsic Functions
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_packed Packed Data Type Support
|
||||
The next table provides an overview of the intrinsic functions for initialization of packed data type.
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifndef __cplusplus
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_register Register Handling
|
||||
The next table provides an overview of the intrinsic functions that you can use to access control registers.
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
#define Ifx__mtcr_no_isync(reg, val) \
|
||||
__asm("mtcr %0,%1"::"i"(reg),"d"(val));
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_saturation Saturation Arithmetic Support
|
||||
These intrinsics support saturation arithmetic
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
|
||||
#define Ifx__adds(a,b) ((__sat int)(a)+(__sat int)(b))
|
||||
|
||||
#define Ifx__addsu(a,b) ((__sat unsigned int)(a)+(__sat unsigned int)(b))
|
||||
|
||||
#define Ifx__subs(a,b) ((__sat int)(a)-(__sat int)(b))
|
||||
|
||||
#define Ifx__subsu(a,b) ((__sat unsigned int )(a)-(__sat unsigned int )(b))
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \defgroup IfxLld_Cpu_Intrinsics_Tasking_single_assembly Insert Single Assembly Instruction
|
||||
The next table provides an overview of the intrinsic functions that you can use to insert a single assembly
|
||||
instruction.You can also use inline assembly but these intrinsics provide a shorthand for frequently used
|
||||
assembly instructions.
|
||||
* \ingroup IfxLld_Cpu_Intrinsics_Tasking
|
||||
* \{
|
||||
*/
|
||||
|
||||
IFX_INLINE void Ifx__nops(void* cnt)
|
||||
{
|
||||
__asm("nop16 \n\t"
|
||||
"loop %0,*-2"
|
||||
::"a"(((char*)cnt) - 1));
|
||||
}
|
||||
|
||||
#define Ifx__NOP(n) __asm(".DUP " #n "\n\tnop16\n\t.ENDM\n")
|
||||
|
||||
/** Insert a memory barrier
|
||||
*/
|
||||
#define Ifx__mem_barrier __asm("":::"memory");
|
||||
|
||||
#if CPU_NO_LDMST
|
||||
IFX_INLINE void Ifx__ldmstC(volatile void *addr, uint32 mask, uint32 data)
|
||||
{
|
||||
*(volatile uint32 *)addr = (*(volatile uint32 *)addr & ~mask) | (mask & data);
|
||||
}
|
||||
|
||||
#define Ifx__ldmst(a,b,c) Ifx__ldmstC(a,b,c)
|
||||
#else
|
||||
|
||||
IFX_INLINE void Ifx__ldmstAsm(volatile void *addr, uint32 mask, uint32 data)
|
||||
{
|
||||
__asm("\tmov d3, %1 \n"
|
||||
"\tmov d2, %2 \n"
|
||||
"\tldmst [%0],e2"
|
||||
::"a"(addr), "d"(mask), "d"(data):"d2", "d3");
|
||||
|
||||
}
|
||||
|
||||
/** Convert float to fract
|
||||
*/
|
||||
IFX_INLINE fract Ifx__float_to_fract(float a)
|
||||
{
|
||||
fract res;
|
||||
__asm("ftoq31 %0,%1,%2":"=d"(res):"d"(a), "d"(0):"memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
#define Ifx__fract_to_sfract __round16
|
||||
|
||||
/** Convert float to sfract
|
||||
*/
|
||||
IFX_INLINE sfract Ifx__float_to_sfract(float a)
|
||||
{
|
||||
fract tmp = Ifx__float_to_fract(a);
|
||||
return Ifx__fract_to_sfract(tmp);
|
||||
}
|
||||
|
||||
#define Ifx__ldmst(addr, mask, data) Ifx__ldmstAsm(addr, mask, data)
|
||||
#endif
|
||||
|
||||
IFX_INLINE void Ifx__stopPerfCounters(void)
|
||||
{ //__mtcr (CPU_CCTRL, 0);
|
||||
__asm(
|
||||
" mov d0,#0\n"
|
||||
" mtcr #0xFC00,d0\n"
|
||||
" isync\n"
|
||||
:::"d0");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* FIXME use inline instead of #define */
|
||||
/* FIXME is it really required to have #define __setareg(areg,val) ___setareg(areg,val) or can __setareg() implemented directly */
|
||||
#define Ifx___setareg(areg,val) \
|
||||
{ __asm (" movh.a\t "#areg",#@his("#val")\n lea\t "#areg",["#areg"]@los("#val")"); }
|
||||
#define Ifx__setareg(areg,val) Ifx___setareg(areg,val)
|
||||
|
||||
/** \brief This function is a implementation of a binary semaphore using compare and swap instruction
|
||||
* \param address address of resource.
|
||||
* \param value This variable is updated with status of address
|
||||
* \param condition if the value of address matches with the value of condition, then swap of value & address occurs.
|
||||
*
|
||||
*/
|
||||
#define Ifx__cmpAndSwap(address,value,condition) \
|
||||
__cmpswapw((address), ((unsigned long)value), (condition) )
|
||||
|
||||
/** \brief Convert a fixpoint value to float32
|
||||
*
|
||||
* This function converts a value from a fixpoint format to a float32 format.
|
||||
*
|
||||
*
|
||||
* \param value value to be converted.
|
||||
* \param shift position of the fix point. Range = [-256, 255] => (Qx.y format where x = shift+1).
|
||||
*
|
||||
* \return Returns the converted value in the float32 format.
|
||||
*
|
||||
*/
|
||||
IFX_INLINE float32 Ifx__fixpoint_to_float32(fract value, sint32 shift)
|
||||
{
|
||||
float32 result;
|
||||
|
||||
__asm(
|
||||
" q31tof\t%0, %1, %2 \n"
|
||||
: "=d" (result)
|
||||
: "d" (value), "d" (shift));
|
||||
return result;
|
||||
}
|
||||
|
||||
IFX_INLINE void* Ifx__getA11(void)
|
||||
{
|
||||
unsigned int *res;
|
||||
__asm("mov.aa %0, a11": "=a" (res) : :"a11");
|
||||
return res;
|
||||
}
|
||||
|
||||
IFX_INLINE void Ifx__setStackPointer(void *stackAddr)
|
||||
{
|
||||
__asm("mov.aa a10, %0": : "a" (stackAddr) :"a10");
|
||||
}
|
||||
|
||||
IFX_INLINE uint32 IfxCpu_calculateCrc32(uint32 *startaddress, uint8 length)
|
||||
{
|
||||
uint32 returnvalue;
|
||||
__asm("MOV d0, #0x0"); /* set seed value to 0 */
|
||||
for (;length > 0; length--)
|
||||
{
|
||||
/*calculate the CRC over all data */
|
||||
__asm("MOV d1,%0" : : "d" (*startaddress));
|
||||
__asm("CRC32 d0,d0,d1");
|
||||
startaddress++;
|
||||
}
|
||||
__asm("MOV %0,d0" : "=d" (returnvalue)); /* return result of CRC*/
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
IFX_INLINE uint32 IfxCpu_getRandomVal(uint32 a, uint32 x, uint32 m)
|
||||
{
|
||||
uint32 result;
|
||||
__asm(" mul.u e14,%1,%2 ; d15 = Eh; d14 = El \n"
|
||||
" mov d12,d14 ; e12 = El \n"
|
||||
" mov d13,#0 ; \n"
|
||||
" madd.u e14,e12,d15,#5 ; e14 = El + 5 * d15 \n"
|
||||
" 1: jge.u d14,%3,2n ; \n"
|
||||
" jz d15,3n ; \n"
|
||||
" 2: subx d14,d14,%3 ; e12=e12-m \n"
|
||||
" subc d15,d15,d13 ; d13=d13-0 \n"
|
||||
" loopu 1p ; \n"
|
||||
" 3: mov %0,d14 ; \n"
|
||||
: "=d"(result) : "d"(a), "d"(x), "d"(m) : "e14","e12");
|
||||
return result;
|
||||
}
|
||||
|
||||
IFX_INLINE sint32 Ifx__popcnt(sint32 a)
|
||||
{
|
||||
sint32 res;
|
||||
__asm("popcnt %0,%1":"=d"(res):"d"(a));
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Macros for backward compatibility of the intrinsics*/
|
||||
/******************************************************************************/
|
||||
#ifndef IFX_CFG_DISABLE_DEFAULT_INTRINSICS
|
||||
#ifndef __non_return_call
|
||||
#define __non_return_call Ifx__non_return_call
|
||||
#endif
|
||||
|
||||
#ifndef __jump_and_link
|
||||
#define __jump_and_link Ifx__jump_and_link
|
||||
#endif
|
||||
|
||||
#ifndef __moveToDataParam0
|
||||
#define __moveToDataParam0 Ifx__moveToDataParam0
|
||||
#endif
|
||||
|
||||
#ifndef __moveToAddrParam0
|
||||
#define __moveToAddrParam0 Ifx__moveToAddrParam0
|
||||
#endif
|
||||
|
||||
#ifndef __getDataParamRet
|
||||
#define __getDataParamRet Ifx__getDataParamRet
|
||||
#endif
|
||||
|
||||
#ifndef __moveToDataParamRet
|
||||
#define __moveToDataParamRet Ifx__moveToDataParamRet
|
||||
#endif
|
||||
|
||||
#ifndef __jumpToFunction
|
||||
#define __jumpToFunction Ifx__jumpToFunction
|
||||
#endif
|
||||
|
||||
#ifndef __jumpToFunctionWithLink
|
||||
#define __jumpToFunctionWithLink Ifx__jumpToFunctionWithLink
|
||||
#endif
|
||||
|
||||
#ifndef __jumpBackToLink
|
||||
#define __jumpBackToLink Ifx__jumpBackToLink
|
||||
#endif
|
||||
|
||||
#ifndef __minX
|
||||
#define __minX Ifx__minX
|
||||
#endif
|
||||
|
||||
#ifndef __maxX
|
||||
#define __maxX Ifx__maxX
|
||||
#endif
|
||||
|
||||
#ifndef __saturateX
|
||||
#define __saturateX Ifx__saturateX
|
||||
#endif
|
||||
|
||||
#ifndef __checkrangeX
|
||||
#define __checkrangeX Ifx__checkrangeX
|
||||
#endif
|
||||
|
||||
#ifndef __saturate
|
||||
#define __saturate Ifx__saturate
|
||||
#endif
|
||||
|
||||
#ifndef __saturateu
|
||||
#define __saturateu Ifx__saturateu
|
||||
#endif
|
||||
|
||||
#ifndef __checkrange
|
||||
#define __checkrange Ifx__checkrange
|
||||
#endif
|
||||
|
||||
#ifndef __sqrtf
|
||||
#define __sqrtf Ifx__sqrtf
|
||||
#endif
|
||||
|
||||
#ifndef __sqrf
|
||||
#define __sqrf Ifx__sqrf
|
||||
#endif
|
||||
|
||||
#ifndef __roundf
|
||||
#define __roundf Ifx__roundf
|
||||
#endif
|
||||
|
||||
#ifndef __absf
|
||||
#define __absf Ifx__absf
|
||||
#endif
|
||||
|
||||
#ifndef __maxf
|
||||
#define __maxf Ifx__maxf
|
||||
#endif
|
||||
|
||||
#ifndef __saturatef
|
||||
#define __saturatef Ifx__saturatef
|
||||
#endif
|
||||
|
||||
#ifndef __minf
|
||||
#define __minf Ifx__minf
|
||||
#endif
|
||||
|
||||
#ifndef __checkrangef
|
||||
#define __checkrangef Ifx__checkrangef
|
||||
#endif
|
||||
|
||||
#ifndef __abs_stdreal
|
||||
#define __abs_stdreal Ifx__abs_stdreal
|
||||
#endif
|
||||
|
||||
#ifndef __saturate_stdreal
|
||||
#define __saturate_stdreal Ifx__saturate_stdreal
|
||||
#endif
|
||||
|
||||
#ifndef __min_stdreal
|
||||
#define __min_stdreal Ifx__min_stdreal
|
||||
#endif
|
||||
|
||||
#ifndef __max_stdreal
|
||||
#define __max_stdreal Ifx__max_stdreal
|
||||
#endif
|
||||
|
||||
#ifndef __neqf
|
||||
#define __neqf Ifx__neqf
|
||||
#endif
|
||||
|
||||
#ifndef __leqf
|
||||
#define __leqf Ifx__leqf
|
||||
#endif
|
||||
|
||||
#ifndef __geqf
|
||||
#define __geqf Ifx__geqf
|
||||
#endif
|
||||
|
||||
#ifndef __fract_to_float
|
||||
#define __fract_to_float Ifx__fract_to_float
|
||||
#endif
|
||||
|
||||
#ifndef __mulfractlong
|
||||
#define __mulfractlong Ifx__mulfractlong
|
||||
#endif
|
||||
|
||||
#ifndef __mulfractfract
|
||||
#define __mulfractfract Ifx__mulfractfract
|
||||
#endif
|
||||
|
||||
#ifndef __disable_and_save
|
||||
#define __disable_and_save Ifx__disable_and_save
|
||||
#endif
|
||||
|
||||
#ifndef __restore
|
||||
#define __restore Ifx__restore
|
||||
#endif
|
||||
|
||||
#ifndef __mtcr_no_isync
|
||||
#define __mtcr_no_isync Ifx__mtcr_no_isync
|
||||
#endif
|
||||
|
||||
#ifndef __adds
|
||||
#define __adds Ifx__adds
|
||||
#endif
|
||||
|
||||
#ifndef __addsu
|
||||
#define __addsu Ifx__addsu
|
||||
#endif
|
||||
|
||||
#ifndef __subs
|
||||
#define __subs Ifx__subs
|
||||
#endif
|
||||
|
||||
#ifndef __subsu
|
||||
#define __subsu Ifx__subsu
|
||||
#endif
|
||||
|
||||
#ifndef __nops
|
||||
#define __nops Ifx__nops
|
||||
#endif
|
||||
|
||||
#if ((!defined(NOP)) && (!defined(IFX_CFG_DISABLE_DEFAULT_INTRINSICS)))
|
||||
#define NOP Ifx__NOP
|
||||
#endif
|
||||
|
||||
#ifndef __mem_barrier
|
||||
#define __mem_barrier Ifx__mem_barrier
|
||||
#endif
|
||||
|
||||
#ifndef __ldmst
|
||||
#define __ldmst Ifx__ldmst
|
||||
#endif
|
||||
|
||||
#ifndef __ldmstC
|
||||
#define __ldmstC Ifx__ldmstC
|
||||
#endif
|
||||
|
||||
#ifndef __float_to_sfract
|
||||
#define __float_to_sfract Ifx__float_to_sfract
|
||||
#endif
|
||||
|
||||
#ifndef __float_to_fract
|
||||
#define __float_to_fract Ifx__float_to_fract
|
||||
#endif
|
||||
|
||||
#ifndef __fract_to_sfract
|
||||
#define __fract_to_sfract Ifx__fract_to_sfract
|
||||
#endif
|
||||
|
||||
#ifndef __ldmstAsm
|
||||
#define __ldmstAsm Ifx__ldmstAsm
|
||||
#endif
|
||||
|
||||
#ifndef __stopPerfCounters
|
||||
#define __stopPerfCounters Ifx__stopPerfCounters
|
||||
#endif
|
||||
|
||||
#ifndef __setareg
|
||||
#define __setareg Ifx__setareg
|
||||
#endif
|
||||
|
||||
#ifndef ___setareg
|
||||
#define ___setareg Ifx___setareg
|
||||
#endif
|
||||
|
||||
#ifndef __cmpAndSwap
|
||||
#define __cmpAndSwap Ifx__cmpAndSwap
|
||||
#endif
|
||||
|
||||
#ifndef __fixpoint_to_float32
|
||||
#define __fixpoint_to_float32 Ifx__fixpoint_to_float32
|
||||
#endif
|
||||
|
||||
#ifndef __getA11
|
||||
#define __getA11 Ifx__getA11
|
||||
#endif
|
||||
|
||||
#ifndef __setStackPointer
|
||||
#define __setStackPointer Ifx__setStackPointer
|
||||
#endif
|
||||
|
||||
#ifndef __popcnt
|
||||
#define __popcnt Ifx__popcnt
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/******************************************************************************/
|
||||
/* *INDENT-ON* */
|
||||
/******************************************************************************/
|
||||
#endif /* IFXCPU_INTRINSICSTASKING_H */
|
||||
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* \file Ifx_Types.h
|
||||
* \brief This files defines all types used by the IFX HAL and libraries
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IFX_TYPES_H
|
||||
#define IFX_TYPES_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
#include "Tricore/Compilers/Compilers.h" /* mapping compiler specific keywords */
|
||||
#include "Platform_Types.h"
|
||||
|
||||
/*******************************************************************************
|
||||
** Global Data Types **
|
||||
** (Types not defined by AUTOSAR) **
|
||||
*******************************************************************************/
|
||||
typedef const char *pchar; /**< \brief const char pointer */
|
||||
typedef void *pvoid; /**< \brief void pointer */
|
||||
typedef volatile void *vvoid; /**< \brief volatile void pointer */
|
||||
typedef void (*voidfuncvoid) (void); /**< \brief void pointer which takes void argument */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float32 real; /**< \brief Real part */
|
||||
float32 imag; /**< \brief Imaginary part */
|
||||
} cfloat32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sint32 real; /**< \brief Real part */
|
||||
sint32 imag; /**< \brief Imaginary part */
|
||||
} csint32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sint16 real; /**< \brief Real part */
|
||||
sint16 imag; /**< \brief Imaginary part */
|
||||
} csint16;
|
||||
|
||||
typedef sint64 Ifx_TickTime; /**< \brief Time in ticks */
|
||||
#define TIME_INFINITE ((Ifx_TickTime)0x7FFFFFFFFFFFFFFFLL)
|
||||
#define TIME_NULL ((Ifx_TickTime)0x0000000000000000LL)
|
||||
|
||||
#define IFX_ONES (0xFFFFFFFFFFFFFFFFU)
|
||||
#define IFX_ZEROS (0x0000000000000000U)
|
||||
|
||||
|
||||
#if CFG_LONG_SIZE_T
|
||||
#define IFX_SIZET_MAX (0x7FFFFFFFL)
|
||||
typedef sint32 Ifx_SizeT; /**< \brief Type used for data stream size */
|
||||
#else
|
||||
#define IFX_SIZET_MAX (0x7FFF)
|
||||
typedef sint16 Ifx_SizeT; /**< \brief Type used for data stream size */
|
||||
#endif
|
||||
|
||||
/** \brief Circular buffer definition. */
|
||||
typedef struct
|
||||
{
|
||||
void *base; /**< \brief buffer base address */
|
||||
uint16 index; /**< \brief buffer current index */
|
||||
uint16 length; /**< \brief buffer length*/
|
||||
} Ifx_CircularBuffer;
|
||||
|
||||
typedef uint16 Ifx_Priority; /**< \brief Used in interrupt service priorities */
|
||||
typedef uint32 Ifx_TimerValue; /**< \brief Used in timer values */
|
||||
typedef sint32 Ifx_SignedTimerVal; /**< \brief Used in signed timer values */
|
||||
|
||||
typedef pvoid Ifx_AddressValue; /**< \brief Used in address values */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16 priority;
|
||||
uint16 provider;
|
||||
} Ifx_IsrSetting;
|
||||
|
||||
/** \brief Signal active state definition. */
|
||||
typedef enum
|
||||
{
|
||||
Ifx_ActiveState_low = 0, /**< \brief The signal is low active */
|
||||
Ifx_ActiveState_high = 1 /**< \brief The signal is high active */
|
||||
} Ifx_ActiveState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Ifx_ParityMode_even = 0,
|
||||
Ifx_ParityMode_odd = 1
|
||||
} Ifx_ParityMode;
|
||||
|
||||
/** \brief input multiplexer definition used in PinMaps
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
Ifx_RxSel_a,
|
||||
Ifx_RxSel_b,
|
||||
Ifx_RxSel_c,
|
||||
Ifx_RxSel_d,
|
||||
Ifx_RxSel_e,
|
||||
Ifx_RxSel_f,
|
||||
Ifx_RxSel_g,
|
||||
Ifx_RxSel_h
|
||||
} Ifx_RxSel;
|
||||
|
||||
/** \brief Module address and index map */
|
||||
typedef struct
|
||||
{
|
||||
volatile void *module; /**< \brief Module address */
|
||||
sint32 index; /**< \brief Module index */
|
||||
} IfxModule_IndexMap;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Ifx_TickTime timestamp;
|
||||
uint8 data;
|
||||
}Ifx_DataBufferMode_TimeStampSingle;
|
||||
|
||||
/*
|
||||
* typedef struct
|
||||
* {
|
||||
* Ifx_TickTime timestamp;
|
||||
* uint8 count[1]; // Number of valid data
|
||||
* uint8 data[7];
|
||||
* }Ifx_DataBufferMode_TimeStampBurst;
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Ifx_DataBufferMode_normal = 0, /**< \brief normal mode, each received byte is moved to the rx fifo */
|
||||
Ifx_DataBufferMode_timeStampSingle, /**< \brief Single byte type stamp mode. The rx fifo is filled in with Ifx_DataBufferMode_TimeStampSingle items. */
|
||||
// Ifx_DataBufferMode_timeStameBurst /**< \brief Burst byte type stamp mode. The rx fifo is filled in with Ifx_DataBufferMode_TimeStampBurst items. */
|
||||
}Ifx_DataBufferMode;
|
||||
|
||||
/**
|
||||
* Defines the PWM modes
|
||||
*
|
||||
* The 1st member shall start with value 0, and the next members value shall be the previous member +1
|
||||
* pwmMode_off shall be the member with the higher index
|
||||
* \note enum order and values should not be modified, except Ifx_Pwm_Mode_init and Ifx_Pwm_Mode_count
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
Ifx_Pwm_Mode_centerAligned = 0, /**< \brief Center aligned mode */
|
||||
Ifx_Pwm_Mode_centerAlignedInverted = 1, /**< \brief Center aligned inverted aligned mode */
|
||||
Ifx_Pwm_Mode_leftAligned = 2, /**< \brief Left aligned mode. The PWM period starts with a rising edge */
|
||||
Ifx_Pwm_Mode_rightAligned = 3, /**< \brief Right aligned mode. The PWM period starts with a falling edge*/
|
||||
Ifx_Pwm_Mode_off = 4, /**< \brief All switch open */
|
||||
Ifx_Pwm_Mode_init = 5, /**< \brief Initialisation mode, do not use at run time */
|
||||
Ifx_Pwm_Mode_count /**< \brief Number of defined modes */
|
||||
} Ifx_Pwm_Mode;
|
||||
|
||||
#ifdef __DCC__
|
||||
#include "Ifx_TypesDcc.h"
|
||||
|
||||
#elif defined(__TASKING__)
|
||||
#include "Ifx_TypesTasking.h"
|
||||
|
||||
#elif defined(__HIGHTEC__)
|
||||
#include "Ifx_TypesGnuc.h"
|
||||
|
||||
#elif defined(__ghs__)
|
||||
#include "Ifx_TypesGhs.h"
|
||||
|
||||
#elif defined(__MSVC__)
|
||||
#include "Ifx_TypesMsvc.h"
|
||||
#else
|
||||
#error Unsupported compiler.
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fract real; /**< \brief Real part */
|
||||
fract imag; /**< \brief Imaginary part */
|
||||
} cfract;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sfract real; /**< \brief Real part */
|
||||
sfract imag; /**< \brief Imaginary part */
|
||||
} csfract;
|
||||
|
||||
#define IFX_PI (3.1415926535897932384626433832795f)
|
||||
#define IFX_TWO_OVER_PI (2.0 / IFX_PI)
|
||||
#define IFX_ONE_OVER_SQRT_THREE (0.57735026918962576450914878050196f)
|
||||
#define IFX_SQRT_TWO (1.4142135623730950488016887242097f)
|
||||
#define IFX_SQRT_THREE (1.7320508075688772935274463415059f)
|
||||
#define IFX_UNUSED_PARAMETER(x) if(x){} /**< \brief Added to handle warning resulting from cases where one/multiple function argument(s) is/are not used(but function signature maintained for legacy purposes). Another use case being usage of intrinsics wherein the compiler ignores it and copy pastes the statements using intrinsics directly to the object file and hence usage of arguments isn't visible to it.(eg: __mfcr() etc) */
|
||||
|
||||
#endif /* IFX_TYPES_H */
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* \file Ifx_TypesDcc.h
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
#ifndef IFX_TYPESDDC_H_
|
||||
#define IFX_TYPESDDC_H_
|
||||
/******************************************************************************/
|
||||
#define FRACT_MAX 0x7fffffff
|
||||
|
||||
typedef long fract;
|
||||
typedef short sfract;
|
||||
typedef long long laccum;
|
||||
typedef long __packb; //MSMRK should be struct of four chars
|
||||
typedef unsigned long __upackb; //MSMRK should be struct of four unsigned chars
|
||||
typedef long __packhw; //MSMRK should be struct of two shorts
|
||||
typedef unsigned long __upackhw; //MSMRK should be struct of two unsigned shorts
|
||||
|
||||
typedef unsigned long long circ_t;
|
||||
|
||||
/******************************************************************************/
|
||||
#endif /* IFX_TYPESDDC_H_ */
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* \file Ifx_TypesGhs.h
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
#ifndef IFX_TYPESGHS_H_
|
||||
#define IFX_TYPESGHS_H_
|
||||
/******************************************************************************/
|
||||
#define FRACT_MAX 0x7fffffff
|
||||
|
||||
#define __interrupt(intno)
|
||||
|
||||
typedef long fract;
|
||||
typedef short sfract;
|
||||
typedef long long laccum;
|
||||
typedef long __packb; //MSMRK should be struct of four chars
|
||||
typedef unsigned long __upackb; //MSMRK should be struct of four unsigned chars
|
||||
typedef long __packhw; //MSMRK should be struct of two shorts
|
||||
typedef unsigned long __upackhw; //MSMRK should be struct of two unsigned shorts
|
||||
/******************************************************************************/
|
||||
|
||||
#endif /* IFX_TYPESGHS_H_ */
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* \file Ifx_TypesGnuc.h
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
#ifndef IFX_TYPESGNUC_H_
|
||||
#define IFX_TYPESGNUC_H_
|
||||
/******************************************************************************/
|
||||
#define FRACT_MAX 0x7fffffff
|
||||
|
||||
#include <machine/cint.h>
|
||||
#define __interrupt(intno)
|
||||
|
||||
typedef long fract;
|
||||
typedef short sfract;
|
||||
typedef long long laccum;
|
||||
typedef long __packb; //MSMRK should be struct of four chars
|
||||
typedef unsigned long __upackb; //MSMRK should be struct of four unsigned chars
|
||||
typedef long __packhw; //MSMRK should be struct of two shorts
|
||||
typedef unsigned long __upackhw; //MSMRK should be struct of two unsigned shorts
|
||||
/******************************************************************************/
|
||||
|
||||
#endif /* IFX_TYPESGNUC_H_ */
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* \file Ifx_TypesTasking.h
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
#ifndef IFX_TYPESTASKING_H_
|
||||
#define IFX_TYPESTASKING_H_
|
||||
/******************************************************************************/
|
||||
#define fract __fract // see http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf
|
||||
#define sfract __sfract // see http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf
|
||||
#define laccum __laccum
|
||||
#define __asm__ __asm
|
||||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#endif /* IFX_TYPESTASKING_H_ */
|
||||
@@ -0,0 +1,187 @@
|
||||
/*******************************************************************************
|
||||
** **
|
||||
** Copyright (C) Infineon Technologies (2018) **
|
||||
** **
|
||||
** All rights reserved. **
|
||||
** **
|
||||
** This document contains proprietary information belonging to Infineon **
|
||||
** Technologies. Passing on and copying of this document, and communication **
|
||||
** of its contents is not permitted without prior written authorization. **
|
||||
** **
|
||||
********************************************************************************
|
||||
** **
|
||||
** FILENAME : Platform_Types.h **
|
||||
** **
|
||||
** VERSION : 2.0.0 **
|
||||
** **
|
||||
** DATE : 2017-03-26 **
|
||||
** **
|
||||
** VARIANT : NA **
|
||||
** **
|
||||
** PLATFORM : Infineon AURIX2G **
|
||||
** **
|
||||
** AUTHOR : DL-AUTOSAR-Engineering **
|
||||
** **
|
||||
** VENDOR : Infineon Technologies **
|
||||
** **
|
||||
** TRACEABILITY : [cover parentID={523013F2-B3A6-4ac7-8ADD-5A4284CE656E}] **
|
||||
** **
|
||||
** DESCRIPTION : Autosar Standard type definitions for the platform **
|
||||
** **
|
||||
** [/cover] **
|
||||
** **
|
||||
** SPECIFICATION(S) : AUTOSAR_SWS_PlatformTypes.pdf, AUTOSAR Release 4.2.2 **
|
||||
** **
|
||||
** MAY BE CHANGED BY USER : no **
|
||||
** **
|
||||
*******************************************************************************/
|
||||
#ifndef PLATFORM_TYPES_H
|
||||
#define PLATFORM_TYPES_H
|
||||
|
||||
/******************************************************************************
|
||||
** Includes **
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
** Global Macro Definitions **
|
||||
******************************************************************************/
|
||||
#define PLATFORM_VENDOR_ID (17u)
|
||||
#define PLATFORM_AR_RELEASE_MAJOR_VERSION (4u)
|
||||
#define PLATFORM_AR_RELEASE_MINOR_VERSION (2u)
|
||||
#define PLATFORM_AR_RELEASE_REVISION_VERSION (2u)
|
||||
#define PLATFORM_SW_MAJOR_VERSION (1u)
|
||||
#define PLATFORM_SW_MINOR_VERSION (0u)
|
||||
#define PLATFORM_SW_PATCH_VERSION (0u)
|
||||
|
||||
/* [cover parentID={5294D975-045A-4d91-9A1A-B1765FAB4653}] */
|
||||
/* CPU register width type definition */
|
||||
#define CPU_TYPE_8 (8u)
|
||||
#define CPU_TYPE_16 (16u)
|
||||
#define CPU_TYPE_32 (32u)
|
||||
/* Register width of CPU*/
|
||||
#define CPU_TYPE CPU_TYPE_32 /* 32 bit */
|
||||
/* [/cover] */
|
||||
|
||||
|
||||
/* [cover parentID={FBA2FA55-430B-4dfb-82B1-C791F0878F9B}] */
|
||||
/* Bit order type definition*/
|
||||
#define MSB_FIRST (0u) /* Big Endian bit ordering */
|
||||
#define LSB_FIRST (1u) /* Little Endian bit ordering */
|
||||
/* Bit order of Register level*/
|
||||
#define CPU_BIT_ORDER LSB_FIRST /* Little Endian */
|
||||
/* [/cover] */
|
||||
|
||||
|
||||
/* [cover parentID={0E2E6A28-264A-4d32-96EE-5F5C93286311}] */
|
||||
/* Byte order type definition*/
|
||||
#define HIGH_BYTE_FIRST (0u) /* Big Endian byte ordering */
|
||||
#define LOW_BYTE_FIRST (1u) /* Little Endian byte ordering */
|
||||
/* Byte order on Memory level*/
|
||||
#define CPU_BYTE_ORDER LOW_BYTE_FIRST /* Little Endian */
|
||||
/* [/cover] */
|
||||
|
||||
|
||||
/* TRUE, FALSE symbol for Boolean types*/
|
||||
/* [cover parentID={FF7F9840-8904-4b7d-83A7-988524B795DE}] */
|
||||
#ifndef TRUE
|
||||
#define TRUE (1u)
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE (0u)
|
||||
#endif
|
||||
/* [/cover] */
|
||||
/******************************************************************************
|
||||
** Global Type Definitions **
|
||||
******************************************************************************/
|
||||
/* AUTOSAR integer data types*/
|
||||
|
||||
/* unsigned char with a bit length that is the shortest one natively supported
|
||||
by the platform.*/
|
||||
/* [cover parentID={F7B51F71-6687-4e05-8408-7F5AAC55C638}] boolean [/cover]*/
|
||||
typedef unsigned char boolean; /* for use with TRUE/FALSE */
|
||||
|
||||
/* 8bit unsigned : 0 .. 255 [0X00 .. 0XFF]*/
|
||||
/* [cover parentID={4269E5AB-7F28-4803-8D60-7B4EC91CB087}] uint8 [/cover] */
|
||||
typedef unsigned char uint8;
|
||||
|
||||
/* 16bit unsigned: 0..65535 [0x0000..0xFFFF]*/
|
||||
/* [cover parentID={66E964CA-35D5-4013-BB61-1E824636D713}] uint16 [/cover] */
|
||||
typedef unsigned short uint16;
|
||||
|
||||
/* 32bit unsigned: 0..4294967295 [0x00000000..0xFFFFFFFF]*/
|
||||
/* [cover parentID={DA33B7A0-7CD3-45e7-9C9A-6D63FB8BA3DC}] uint32 [/cover] */
|
||||
typedef unsigned long uint32;
|
||||
|
||||
/* 64bit unsigned
|
||||
* 0..18446744073709551615 [0x0000000000000000..0xFFFFFFFFFFFFFFFF]*/
|
||||
/* [cover parentID={3409E2A3-BF2D-44a5-9B00-A72300848166}] uint64 */
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
/* 8bit signed, 7 bit + 1 bit sign -128..+127 [0x80..0x7F]*/
|
||||
/* [cover parentID={94E0756B-993D-4cae-9499-416CDFD6FEAF}] sint8[/cover]*/
|
||||
typedef signed char sint8;
|
||||
|
||||
/* 16bit signed, 15 bit + 1 bit sign -32768..+32767 [0x8000..0x7FFF]*/
|
||||
/* [cover parentID={B3482DFF-8DFF-41bd-95E0-0406E2451CB0}] sint16 [/cover]*/
|
||||
typedef short sint16;
|
||||
|
||||
/* 32bit signed, 31 bit + 1 bit sign
|
||||
-2147483648..+2147483647 [0x80000000..0x7FFFFFFF]*/
|
||||
/* [cover parentID={B027B471-A1A2-456c-A015-35F4A34A88EF}] sint32 [/cover]*/
|
||||
typedef long sint32;
|
||||
/*
|
||||
* 64bit signed, 63 bit + 1 bit sign
|
||||
* -9223372036854775808..9223372036854775807
|
||||
* [0x8000000000000000..0x7FFFFFFFFFFFFFFF]
|
||||
*/
|
||||
/* [cover parentID={3CF3471C-EB1A-450c-B78F-4B96D226A1F5}] sint64 [/cover]*/
|
||||
typedef long long sint64;
|
||||
|
||||
/* At least 8 bit*/
|
||||
/* [cover parentID={F8719785-0A16-486e-AB85-0A2859402037}] uint8_least[/cover]*/
|
||||
typedef unsigned long uint8_least;
|
||||
|
||||
/* At least 16 bit*/
|
||||
/* [cover parentID={BEAD868D-0EC1-44f0-AFEE-B57401CC9E65}]uint16_least[/cover]*/
|
||||
typedef unsigned long uint16_least;
|
||||
|
||||
/* least 32 bit*/
|
||||
/* [cover parentID={9B9CC46A-0F61-4d25-8001-679CF210C135}]uint32_least[/cover]*/
|
||||
typedef unsigned long uint32_least;
|
||||
|
||||
/* At least 7 bit + 1 bit sign*/
|
||||
/* [cover parentID={5C0DE046-8407-4708-8D26-41B96731D89D}]sint8_least[/cover]*/
|
||||
typedef signed long sint8_least;
|
||||
|
||||
/* At least 15 bit + 1 bit sign*/
|
||||
/* [cover parentID={0A83DB6E-ECD8-42f0-B97C-057F9FBFEB6E}]sint16_least[/cover]*/
|
||||
typedef signed long sint16_least;
|
||||
|
||||
/* At least 31 bit + 1 bit sign*/
|
||||
/* [cover parentID={A65F0248-A0A7-4ab7-BAFA-A5428F4E8A96}]sint32_least[/cover]*/
|
||||
typedef signed long sint32_least;
|
||||
|
||||
/* IEEE754-2008 single precision
|
||||
* -3.4028235e+38..+3.4028235e+38*/
|
||||
/* [cover parentID={BBC4F70E-DA81-4d37-BCA4-628A89B29517}] float32 [/cover]*/
|
||||
typedef float float32; /* IEEE754-2008 single precision */
|
||||
|
||||
/* IEEE754-2008 double precision
|
||||
* -1.7976931348623157e+308..+1.7976931348623157e+308*/
|
||||
/* [cover parentID={0D62172C-9309-493a-8028-06A7299D7906}] float64 [/cover]*/
|
||||
typedef double float64; /* IEEE754-2008 double precision */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Global Constant Declarations **
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
** Global Variable Declarations **
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
** Global Function Declarations **
|
||||
******************************************************************************/
|
||||
|
||||
#endif /* PLATFORM_TYPES_H */
|
||||
@@ -0,0 +1,494 @@
|
||||
/**
|
||||
* \file IfxCpu_Trap.c
|
||||
* \brief This file contains the APIs for Trap related functions.
|
||||
*
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
** Includes **
|
||||
*******************************************************************************/
|
||||
#include "IfxCpu_Trap.h"
|
||||
#include "Cpu/Std/IfxCpu.h"
|
||||
#include "Cpu/Std/IfxCpu_Intrinsics.h"
|
||||
#include "IfxCpu_reg.h"
|
||||
#include "Ifx_Cfg.h"
|
||||
#include "zf_common_debug.h"
|
||||
#ifdef IFX_CFG_EXTEND_TRAP_HOOKS
|
||||
#include "Ifx_Cfg_Trap.h"
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* Macros */
|
||||
/******************************************************************************/
|
||||
/** \brief Configuration for CpuX enable.
|
||||
*
|
||||
*/
|
||||
#ifndef IFX_CFG_CPU_TRAP_TSR_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_TSR_HOOK(trapWatch) /**< By default macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_SYSCALL_CPU0_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_SYSCALL_CPU0_HOOK(trapWatch) ((void)trapWatch) /**< By default macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_SYSCALL_CPU1_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_SYSCALL_CPU1_HOOK(trapWatch) ((void)trapWatch) /**< By default macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_SYSCALL_CPU2_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_SYSCALL_CPU2_HOOK(trapWatch) ((void)trapWatch) /**< By default macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_SYSCALL_CPU3_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_SYSCALL_CPU3_HOOK(trapWatch) ((void)trapWatch) /**< By default macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_SYSCALL_CPU4_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_SYSCALL_CPU4_HOOK(trapWatch) ((void)trapWatch) /**< By default macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_SYSCALL_CPU5_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_SYSCALL_CPU5_HOOK(trapWatch) ((void)trapWatch) /**< By default macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_NMI_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_NMI_HOOK(trapWatch) ((void)trapWatch) /**< By default NMI macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_MME_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_MME_HOOK(trapWatch) ((void)trapWatch) /**< By default memory Management Error macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_IPE_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_IPE_HOOK(trapWatch) ((void)trapWatch) /**< By default internal Protection Error macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_IE_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_IE_HOOK(trapWatch) ((void)trapWatch) /**< By default instruction Error macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_CME_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_CME_HOOK(trapWatch) ((void)trapWatch) /**< By default context Management Error macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_BE_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_BE_HOOK(trapWatch) ((void)trapWatch) /**< By default bus Error macro is empty*/
|
||||
#endif
|
||||
#ifndef IFX_CFG_CPU_TRAP_ASSERT_HOOK
|
||||
# define IFX_CFG_CPU_TRAP_ASSERT_HOOK(trapWatch) ((void)trapWatch) /**< By default assertion is empty*/
|
||||
#endif
|
||||
|
||||
#ifndef IFX_CFG_CPU_TRAP_DEBUG
|
||||
#define IFX_CFG_CPU_TRAP_DEBUG __debug()
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
** variables **
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
** Function definitions **
|
||||
*******************************************************************************/
|
||||
IFX_INLINE IfxCpu_Trap IfxCpu_Trap_extractTrapInfo(uint8 trapClass, uint32 tin)
|
||||
{
|
||||
IfxCpu_Trap trapInfo;
|
||||
trapInfo.tAddr = (unsigned int)__getA11();
|
||||
trapInfo.tClass = trapClass;
|
||||
trapInfo.tId = tin;
|
||||
trapInfo.tCpu = IfxCpu_getCoreId();
|
||||
return trapInfo;
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_Trap_memoryManagementError(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_memoryManagement, tin);
|
||||
IFX_CFG_CPU_TRAP_MME_HOOK(trapWatch);
|
||||
|
||||
// 如果单片机卡死在这里,则说明出现了内存管理报错,报错原因需自行排查
|
||||
|
||||
IFX_CFG_CPU_TRAP_DEBUG;
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_Trap_internalProtectionError(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_internalProtection, tin);
|
||||
IFX_CFG_CPU_TRAP_IPE_HOOK(trapWatch);
|
||||
|
||||
// 如果单片机卡死在这里,则说明单片机访问到了空的内存位置,也就是常说的访问越界
|
||||
|
||||
IFX_CFG_CPU_TRAP_DEBUG;
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_Trap_instructionError(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_instructionErrors, tin);
|
||||
IFX_CFG_CPU_TRAP_IE_HOOK(trapWatch);
|
||||
|
||||
// 如果单片机卡死在这里,则说明执行了错误的指令,具体原因通过debug查找
|
||||
|
||||
IFX_CFG_CPU_TRAP_DEBUG;
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_Trap_contextManagementError(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_contextManagement, tin);
|
||||
IFX_CFG_CPU_TRAP_CME_HOOK(trapWatch);
|
||||
|
||||
// 单片机调度管理错误,一般不会触发此类报错,如若触发则自行debug查找问题
|
||||
|
||||
IFX_CFG_CPU_TRAP_DEBUG;
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_Trap_busError(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_bus, tin);
|
||||
IFX_CFG_CPU_TRAP_BE_HOOK(trapWatch);
|
||||
|
||||
// 如果单片机卡死在了这里 可能是使用了未初始化的外设资源
|
||||
// 举个例子,没调用pwm_init初始化函数,然后直接调用pwm_set_duty来赋值输出
|
||||
// 也可能是访问内存失败导致 如果访问失败请仔细检查使用指针访问数据的地方
|
||||
|
||||
IFX_CFG_CPU_TRAP_DEBUG;
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_Trap_assertion(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_assertion, tin);
|
||||
IFX_CFG_CPU_TRAP_ASSERT_HOOK(trapWatch);
|
||||
|
||||
// 如果单片机卡死在这里,则说明触发了英飞凌的断言,通过调试来查看具体触发断言的位置并修正
|
||||
|
||||
IFX_CFG_CPU_TRAP_DEBUG;
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
|
||||
|
||||
void IfxCpu_Trap_systemCall_Cpu0(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_systemCall, tin);
|
||||
IFX_CFG_CPU_TRAP_SYSCALL_CPU0_HOOK(trapWatch);
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 2
|
||||
void IfxCpu_Trap_systemCall_Cpu1(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_systemCall, tin);
|
||||
IFX_CFG_CPU_TRAP_SYSCALL_CPU1_HOOK(trapWatch);
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 3
|
||||
void IfxCpu_Trap_systemCall_Cpu2(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_systemCall, tin);
|
||||
IFX_CFG_CPU_TRAP_SYSCALL_CPU2_HOOK(trapWatch);
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 4
|
||||
void IfxCpu_Trap_systemCall_Cpu3(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_systemCall, tin);
|
||||
IFX_CFG_CPU_TRAP_SYSCALL_CPU3_HOOK(trapWatch);
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 5
|
||||
void IfxCpu_Trap_systemCall_Cpu4(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_systemCall, tin);
|
||||
IFX_CFG_CPU_TRAP_SYSCALL_CPU4_HOOK(trapWatch);
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 6
|
||||
void IfxCpu_Trap_systemCall_Cpu5(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_systemCall, tin);
|
||||
IFX_CFG_CPU_TRAP_SYSCALL_CPU5_HOOK(trapWatch);
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
#endif
|
||||
|
||||
void IfxCpu_Trap_nonMaskableInterrupt(uint32 tin)
|
||||
{
|
||||
volatile IfxCpu_Trap trapWatch;
|
||||
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_nonMaskableInterrupt, tin);
|
||||
IFX_CFG_CPU_TRAP_NMI_HOOK(trapWatch);
|
||||
__asm("rslcx"); /* Restore lower context before returning. lower context was stored in the trap vector */
|
||||
__asm("rfe");
|
||||
}
|
||||
|
||||
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#pragma section ".traptab_cpu0" awx
|
||||
#pragma GCC optimize ("O2")
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section
|
||||
#pragma section CODE ".traptab_cpu0" X
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma protect on
|
||||
#pragma section code "traptab_cpu0"
|
||||
#endif
|
||||
#if defined(__ghs__)
|
||||
#pragma ghs section
|
||||
#pragma ghs section text=".traptab_cpu0"
|
||||
#endif
|
||||
void IfxCpu_Trap_vectorTable0(void)
|
||||
{
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_memoryManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_internalProtectionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_instructionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_contextManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_busError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_assertion);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_systemCall_Cpu0);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_nonMaskableInterrupt);
|
||||
}
|
||||
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 2
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#pragma section ".traptab_cpu1" awx
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section
|
||||
#pragma section CODE ".traptab_cpu1" X
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma section code "traptab_cpu1"
|
||||
#endif
|
||||
#if defined(__ghs__)
|
||||
#pragma ghs section
|
||||
#pragma ghs section text=".traptab_cpu1"
|
||||
#endif
|
||||
void IfxCpu_Trap_vectorTable1(void)
|
||||
{
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_memoryManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_internalProtectionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_instructionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_contextManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_busError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_assertion);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_systemCall_Cpu1);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_nonMaskableInterrupt);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 3
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#pragma section ".traptab_cpu2" awx
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section
|
||||
#pragma section CODE ".traptab_cpu2" X
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma section code "traptab_cpu2"
|
||||
#endif
|
||||
#if defined(__ghs__)
|
||||
#pragma ghs section
|
||||
#pragma ghs section text=".traptab_cpu2"
|
||||
#endif
|
||||
|
||||
void IfxCpu_Trap_vectorTable2(void)
|
||||
{
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_memoryManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_internalProtectionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_instructionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_contextManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_busError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_assertion);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_systemCall_Cpu2);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_nonMaskableInterrupt);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 4
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#pragma section ".traptab_cpu3" awx
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section
|
||||
#pragma section CODE ".traptab_cpu3" X
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma section code "traptab_cpu3"
|
||||
#endif
|
||||
#if defined(__ghs__)
|
||||
#pragma ghs section
|
||||
#pragma ghs section text=".traptab_cpu3"
|
||||
#endif
|
||||
|
||||
|
||||
void IfxCpu_Trap_vectorTable3(void)
|
||||
{
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_memoryManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_internalProtectionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_instructionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_contextManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_busError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_assertion);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_systemCall_Cpu3);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_nonMaskableInterrupt);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 5
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#pragma section ".traptab_cpu4" awx
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section
|
||||
#pragma section CODE ".traptab_cpu4" X
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma section code "traptab_cpu4"
|
||||
#endif
|
||||
#if defined(__ghs__)
|
||||
#pragma ghs section
|
||||
#pragma ghs section text=".traptab_cpu4"
|
||||
#endif
|
||||
|
||||
void IfxCpu_Trap_vectorTable4(void)
|
||||
{
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_memoryManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_internalProtectionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_instructionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_contextManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_busError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_assertion);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_systemCall_Cpu4);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_nonMaskableInterrupt);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if IFXCPU_NUM_MODULES >= 6
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#pragma section ".traptab_cpu5" awx
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section
|
||||
#pragma section CODE ".traptab_cpu5" X
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma section code "traptab_cpu5"
|
||||
#endif
|
||||
#if defined(__ghs__)
|
||||
#pragma ghs section
|
||||
#pragma ghs section text=".traptab_cpu5"
|
||||
#endif
|
||||
|
||||
void IfxCpu_Trap_vectorTable5(void)
|
||||
{
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_memoryManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_internalProtectionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_instructionError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_contextManagementError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_busError);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_assertion);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_systemCall_Cpu5);
|
||||
IfxCpu_Tsr_CallTSR(IfxCpu_Trap_nonMaskableInterrupt);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__HIGHTEC__)
|
||||
#pragma section
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma section
|
||||
#endif
|
||||
#if defined(__DCC__)
|
||||
#pragma interrupt IfxInterruptEx
|
||||
#endif
|
||||
#if defined(__TASKING__)
|
||||
#pragma endprotect
|
||||
#endif
|
||||
#if defined(__ghs__)
|
||||
#pragma ghs section
|
||||
#endif
|
||||
@@ -0,0 +1,436 @@
|
||||
/**
|
||||
* \file IfxCpu_Trap.c
|
||||
* \brief This file contains the APIs for Trap related functions.
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2012 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_Trap Trap Functions
|
||||
* \ingroup IfxLld_Cpu
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_Trap_Hooks Trap Function Hooks
|
||||
* \ingroup IfxLld_Cpu_Trap
|
||||
*
|
||||
* \defgroup IfxLld_Cpu_Trap_Usage How to use the Trap Function Hooks?
|
||||
* \ingroup IfxLld_Cpu_Trap
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IFXCPU_TRAPS_H_
|
||||
#define IFXCPU_TRAPS_H_
|
||||
|
||||
/*******************************************************************************
|
||||
** Includes **
|
||||
*******************************************************************************/
|
||||
#include "Cpu/Std/Ifx_Types.h"
|
||||
#include "Cpu/Std/IfxCpu_Intrinsics.h"
|
||||
#include "Ifx_Cfg.h"
|
||||
|
||||
/*******************************************************************************
|
||||
** Type definitions **
|
||||
*******************************************************************************/
|
||||
/** \addtogroup IfxLld_Cpu_Trap_Hooks
|
||||
* \{ */
|
||||
|
||||
/** \brief Enum for available Trap classes.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCpu_Trap_Class_memoryManagement = 0U,
|
||||
IfxCpu_Trap_Class_internalProtection = 1U,
|
||||
IfxCpu_Trap_Class_instructionErrors = 2U,
|
||||
IfxCpu_Trap_Class_contextManagement = 3U,
|
||||
IfxCpu_Trap_Class_bus = 4U,
|
||||
IfxCpu_Trap_Class_assertion = 5U,
|
||||
IfxCpu_Trap_Class_systemCall = 6U,
|
||||
IfxCpu_Trap_Class_nonMaskableInterrupt = 7U
|
||||
} IfxCpu_Trap_Class;
|
||||
|
||||
/** \brief Enum for available Identification numbers under Memory Management Trap.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCpu_Trap_MemoryManagement_Id_virtualAddressFill = 0U,
|
||||
IfxCpu_Trap_MemoryManagement_Id_virtualAddressProtection = 1U,
|
||||
} IfxCpu_Trap_MemoryManagement_Id;
|
||||
|
||||
/** \brief Enum for available Identification numbers under Internal Protection Trap.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCpu_Trap_InternalProtection_Id_privilegeViolation = 1U,
|
||||
IfxCpu_Trap_InternalProtection_Id_memoryProtectionRead = 2U,
|
||||
IfxCpu_Trap_InternalProtection_Id_memoryProtectionWrite = 3U,
|
||||
IfxCpu_Trap_InternalProtection_Id_memoryProtectionExecute = 4U,
|
||||
IfxCpu_Trap_InternalProtection_Id_memoryProtectionPeripheralAccess = 5U,
|
||||
IfxCpu_Trap_InternalProtection_Id_memoryProtectionNullAddress = 6U,
|
||||
IfxCpu_Trap_InternalProtection_Id_globalRegisterWriteProtection = 7U,
|
||||
} IfxCpu_Trap_InternalProtection_Id;
|
||||
|
||||
/** \brief Enum for available Identification numbers under Instruction Errors Trap.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCpu_Trap_InstructionErrors_Id_illegalOpcode = 1U,
|
||||
IfxCpu_Trap_InstructionErrors_Id_unimplementedOpcode = 2U,
|
||||
IfxCpu_Trap_InstructionErrors_Id_invalidOperand = 3U,
|
||||
IfxCpu_Trap_InstructionErrors_Id_dataAddressAlignment = 4U,
|
||||
IfxCpu_Trap_InstructionErrors_Id_invalidMemoryAddress = 5U,
|
||||
} IfxCpu_Trap_InstructionErrors_Id;
|
||||
|
||||
/** \brief Enum for available Identification numbers under Context Management Trap.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCpu_Trap_ContextManagement_Id_freeContextListDepletion = 1U,
|
||||
IfxCpu_Trap_ContextManagement_Id_callDepthOverflow = 2U,
|
||||
IfxCpu_Trap_ContextManagement_Id_callDepthUnderflow = 3U,
|
||||
IfxCpu_Trap_ContextManagement_Id_freeContextListUnderflow = 4U,
|
||||
IfxCpu_Trap_ContextManagement_Id_callStackUnderflow = 5U,
|
||||
IfxCpu_Trap_ContextManagement_Id_contextType = 6U,
|
||||
IfxCpu_Trap_ContextManagement_Id_nestingError = 7U,
|
||||
} IfxCpu_Trap_ContextManagement_Id;
|
||||
|
||||
/** \brief Enum for available Identification numbers under Bus Trap.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCpu_Trap_Bus_Id_programFetchSynchronousError = 1U,
|
||||
IfxCpu_Trap_Bus_Id_dataAccessSynchronousError = 2U,
|
||||
IfxCpu_Trap_Bus_Id_dataAccessAsynchronousError = 3U,
|
||||
IfxCpu_Trap_Bus_Id_CoprocessorTrapAsynchronousError = 4U,
|
||||
IfxCpu_Trap_Bus_Id_programMemoryIntegrityError = 5U,
|
||||
IfxCpu_Trap_Bus_Id_dataMemoryIntegrityError = 6U,
|
||||
IfxCpu_Trap_Bus_Id_temporalAsynchronousError = 7U,
|
||||
} IfxCpu_Trap_Bus_Id;
|
||||
|
||||
/** \brief Enum for available Identification numbers under Assertion Trap.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxCpu_Trap_Assertion_Id_arithmeticOverflow = 1U,
|
||||
IfxCpu_Trap_Assertion_Id_stickyArithmeticOverflow = 2U,
|
||||
} IfxCpu_Trap_Assertion_Id;
|
||||
|
||||
/** \brief Type for Identification numbers under SystemCall Trap.
|
||||
*
|
||||
*/
|
||||
typedef sint32 IfxCpu_Trap_SystemCall_Id;
|
||||
|
||||
/** \brief Type for Identification number for Non Maskable Interrupt Trap.
|
||||
*
|
||||
*/
|
||||
typedef sint32 IfxCpu_Trap_NonMaskableInterrupt_Id;
|
||||
|
||||
/** \brief Union to abstract Identification numbers under Traps.
|
||||
*
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
IfxCpu_Trap_MemoryManagement_Id memoryManagement;
|
||||
IfxCpu_Trap_InternalProtection_Id internalProtection;
|
||||
IfxCpu_Trap_InstructionErrors_Id instructionErrors;
|
||||
IfxCpu_Trap_ContextManagement_Id contextManagement;
|
||||
IfxCpu_Trap_Bus_Id bus;
|
||||
IfxCpu_Trap_Assertion_Id assertion;
|
||||
IfxCpu_Trap_SystemCall_Id systemCall;
|
||||
IfxCpu_Trap_NonMaskableInterrupt_Id nonMaskableInterrupt;
|
||||
} IfxCpu_Trap_Id;
|
||||
|
||||
/** \brief Structure to contain the trap information.
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int tAddr;
|
||||
unsigned int tId : 8;
|
||||
unsigned int tClass : 8;
|
||||
unsigned int tCpu : 3;
|
||||
} IfxCpu_Trap;
|
||||
|
||||
/*******************************************************************************
|
||||
** Global Exported variables/constants **
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
** Global Exported macros/inlines/function ptototypes **
|
||||
*******************************************************************************/
|
||||
/** \brief Macro to define the trap vector table.
|
||||
* This macro is provided to define the trap vector table in the frameowrk. User shall not use
|
||||
* this macro.
|
||||
* Refer to the documentation to extend the trap with hook functions. \ref IfxLld_Cpu_Trap_Usage
|
||||
*/
|
||||
#if defined(__HIGHTEC__)
|
||||
#define __ALIGN_TRAP_TAB__ __asm(" .align 5");
|
||||
#define IfxCpu_Tsr_CallTSR(serviceRoutine) \
|
||||
{ \
|
||||
__ALIGN_TRAP_TAB__; \
|
||||
__asm("svlcx\n"); \
|
||||
__asm("mov\t %d4, %d15"); \
|
||||
__asm("ji\t %0" : : "a" (serviceRoutine)); \
|
||||
__asm("rfe"); \
|
||||
}
|
||||
#elif defined(__ghs__)
|
||||
#define __ALIGN_TRAP_TAB__ __asm(" .align 32");
|
||||
#define IfxCpu_Tsr_CallTSR(serviceRoutine) \
|
||||
{ \
|
||||
__ALIGN_TRAP_TAB__; \
|
||||
__asm("svlcx\n"); \
|
||||
__asm("mov\t d4, d15"); \
|
||||
__asm("ji\t %0" : : "a" (serviceRoutine)); \
|
||||
__asm("rfe"); \
|
||||
}
|
||||
#elif defined(__DCC__)
|
||||
#define IfxCpu_Tsr_CallTSR(serviceRoutine) \
|
||||
{ \
|
||||
__ALIGN_TRAP_TAB__; \
|
||||
__asm("\n#$$bp\n"); \
|
||||
__asm("svlcx\n"); \
|
||||
__asm(" movh.a\t %a15,"#serviceRoutine "@ha\n"); \
|
||||
__asm(" lea\t %a15,[%a15]"#serviceRoutine "@l\n"); \
|
||||
__asm(" mov\t %d4,%d15\n"); \
|
||||
__asm(" ji\t %a15\n"); \
|
||||
__asm(" rfe"); \
|
||||
__asm("#$$ep"); \
|
||||
}
|
||||
#define __ALIGN_TRAP_TAB__ __asm(" .align 5");
|
||||
#elif defined(__TASKING__)
|
||||
#define IfxCpu_Tsr_CallTSR(serviceRoutine) \
|
||||
{ \
|
||||
__ALIGN_TRAP_TAB__; \
|
||||
__asm("svlcx\n\tmov\td4,d15\n\tji\t%0\n" : : "a" (serviceRoutine) : "d4", "d15"); \
|
||||
}
|
||||
#define __ALIGN_TRAP_TAB__ __asm(" .align 32");
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
|
||||
/*Documentation */
|
||||
/** \addtogroup IfxLld_Cpu_Trap_Usage
|
||||
* \{
|
||||
*
|
||||
* This page describes how to use the trap function hooks with application framework.\n
|
||||
* Framework has built in Trap Service Routines, which has minimal set of debug information.
|
||||
* The execution of trap service is as below,\n
|
||||
* 1) When a trap occurs, a variable "trapInfo" is updated with the information:\n
|
||||
* a. Which CPU caused this trap,\n
|
||||
* b. What is the trap address, trap class and\n
|
||||
* c. What is the trap identification number\n
|
||||
* 2) Call to a configurable hook function, passing structure trapInfo as parameter.\n
|
||||
* 3) Then debug instruction executed.\n
|
||||
* 4) Returning from the trap. (This instruction is not reached if debugger is connected because of
|
||||
* "debug" instruction before)\n
|
||||
* For normal cases during development, where user works with debugger, user can watch the structure variable
|
||||
* "trapInfo" in the debugger.
|
||||
*
|
||||
* In case, user wants to make use of the information of trap for further processing,\n
|
||||
* extend the traps, using the hook functions provided.
|
||||
*
|
||||
* \section IfxLld_Cpu_Trap_Hooks Extending the traps with hook functions.
|
||||
*
|
||||
* If the trap extensions are to be extended, it is very important to enable this feature. By default this
|
||||
* feature is disabled.
|
||||
*
|
||||
* \subsection IfxLld_Cpu_Trap_Hooks_EnableExtn How to enable the trap extension feature?
|
||||
* To extend the trap hook functions user must enable this feature by defining the macro
|
||||
* "IFX_CFG_EXTEND_TRAP_HOOKS" in Ifx_Cfg.h, as shown below.
|
||||
* \code
|
||||
* //file: Ifx_Cfg.h
|
||||
*
|
||||
* #define IFX_CFG_EXTEND_TRAP_HOOKS
|
||||
*
|
||||
* \endcode
|
||||
* Now the compiler will accept the further configurations to extend the hooks.\n
|
||||
* Ifx_Cfg_Trap.h file shall be used to extend the traps. This provides two kind of hook functions.
|
||||
* ie. Hook for error traps and hooks (per CPU available) for system calls.
|
||||
*
|
||||
* \subsection IfxLld_Cpu_Trap_ErrorHooks Extending the "Error traps" with hook function.
|
||||
* Error trap occurs as a result of an error event such as an instruction error, memory-management error
|
||||
* or an illegal access.\n
|
||||
* To extend the error traps, following steps are to be followed:\n
|
||||
* \subsubsection IfxLld_Cpu_Trap_ErrorHooksStep1 Step1: Define a routine to substitute the hook for error traps.
|
||||
* This definition shall be as user defined code (Generally in DemoApps folder).\n
|
||||
* Considerations:\n
|
||||
* 1. Format: IFX_INLINE void \<trap extension name\>(IfxCpu_Trap trapInfo)
|
||||
* \note Define such a routine with the consideration that the trap extension hook is not a function. In case
|
||||
* of context management error, this extension itself will not call any other function.
|
||||
*
|
||||
* 2. Use the information trapInfo, which is available as parameter passed to this hook and process further.
|
||||
* Example code in a user defined file eg. Ifx_TrapExtension.h,
|
||||
* \code
|
||||
* //Example "inlined" function for trap Extension Hook.
|
||||
* IFX_INLINE myTrapExtensionHook(IfxCpu_Trap trapInfo)
|
||||
* {
|
||||
* switch (trapInfo.tClass)
|
||||
* {
|
||||
* case IfxCpu_Trap_Class_memoryManagement:
|
||||
* {
|
||||
* //user code: Function calls allowed.
|
||||
* break;
|
||||
* }
|
||||
* case IfxCpu_Trap_Class_internalProtection:
|
||||
* {
|
||||
* //user code: Function calls allowed.
|
||||
* break;
|
||||
* }
|
||||
* case IfxCpu_Trap_Class_instructionErrors:
|
||||
* {
|
||||
* //user code: Function calls allowed.
|
||||
* break;
|
||||
* }
|
||||
* case IfxCpu_Trap_Class_contextManagement:
|
||||
* {
|
||||
* //user code: Function calls NOT allowed.
|
||||
* break;
|
||||
* }
|
||||
* case IfxCpu_Trap_Class_bus:
|
||||
* {
|
||||
* //user code: Function calls allowed.
|
||||
* break;
|
||||
* }
|
||||
* case IfxCpu_Trap_Class_assertion:
|
||||
* {
|
||||
* //user code: Function calls allowed.
|
||||
* break;
|
||||
* }
|
||||
* case IfxCpu_Trap_Class_nonMaskableInterrupt:
|
||||
* {
|
||||
* //user code: Function calls allowed.
|
||||
* break;
|
||||
* }
|
||||
* case default:
|
||||
* {
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
* \note The error trap functions execute the debug instruction immediately after returning from extension hooks.
|
||||
*
|
||||
* \subsubsection IfxLld_Cpu_Trap_ErrorHooksStep2 Step2: Configure error trap hook extension function.
|
||||
* Configure error trap hook extension function as defined above to the macro as below:
|
||||
* \note Configuration of hook extension is available in Ifx_Cfg_Trap.h
|
||||
*
|
||||
* \code
|
||||
* //file: Ifx_Cfg_Trap.h
|
||||
*
|
||||
* #include "Ifx_TrapExtension.h" //Assuming this is the file name as in above example
|
||||
*
|
||||
* #define IFX_CFG_CPU_TRAP_TSR_HOOK(trapInfo) myTrapExtensionHook(trapInfo) //This is INLINE function.
|
||||
*
|
||||
* \endcode
|
||||
* \note The exten hooks are effective only if the feature is enabled.
|
||||
*
|
||||
* \subsection IfxLld_Cpu_Trap_SysCallHooks Extending the cpu specific "system call" hook functions.
|
||||
* Tricore architecture provides the system call trap which is executed by software trigger. The instruction "syscall"
|
||||
* triggers this trap. Please refer Tricore architecture manual for more details.\n
|
||||
* IfxCpu_trap driver provide hook function for each CPU separately. To extend System Call trap following steps
|
||||
* are to be followed:\n
|
||||
* \subsubsection IfxLld_Cpu_Trap_SysCallHooksStep1 Step1: Define routine/s to substitute the hook/s for System Call trap.
|
||||
* This definition shall be as user defined code (Generally in DemoApps folder).\n
|
||||
* Considerations:\n
|
||||
* 1. Format: void \<syscall function name\>(IfxCpu_Trap trapInfo)
|
||||
* It is allowed to define this trap extension as function definition, because this trap is not triggered due to any error.
|
||||
* Depending on the application requirement, define single or per CPU instance of the extension.
|
||||
*
|
||||
* 2. Use the information trapInfo which is available as parameter passed to this hook and process further. The parameter
|
||||
* passed, with syscall instruction, will be trap identification number (refer to Tricore architecture manual for more details).
|
||||
* \note To hook extension, information about trap identification number is available through parameter "trapInfo".
|
||||
*
|
||||
* Example code in a user defined file eg. Ifx_TrapExtension.h,
|
||||
* \code
|
||||
* //Example function for System Call Extension Hook.
|
||||
* IFX_INLINE mySysCallExtensionHook(IfxCpu_Trap trapInfo)
|
||||
* {
|
||||
* switch (trapInfo.tId)
|
||||
* {
|
||||
* case 0:
|
||||
* {
|
||||
* //user code: Function calls allowed.
|
||||
* break;
|
||||
* }
|
||||
* case 1:
|
||||
* {
|
||||
* //user code: Function calls allowed.
|
||||
* break;
|
||||
* }
|
||||
* // and so on..
|
||||
* case default:
|
||||
* {
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \subsubsection IfxLld_Cpu_Trap_SysCallHooksStep2 Step2: Configure the extension function.\n
|
||||
* Configure the hook extension function defined above, to the macro as below:
|
||||
* \note Configuration of hook extension is available in Ifx_Cfg_Trap.h
|
||||
* \code
|
||||
* //file: Ifx_Cfg_Trap.h
|
||||
*
|
||||
* #include "Ifx_TrapExtension.h" //Assuming this is the file name as in above example
|
||||
*
|
||||
* #define IFXCPU_TRAP_CFG_SYSCALL_CPU0_HOOK(trapInfo) mySysCallExtensionHook(trapInfo)
|
||||
*
|
||||
* #define IFXCPU_TRAP_CFG_SYSCALL_CPU1_HOOK(trapInfo) // Not used in this example
|
||||
*
|
||||
* #define IFXCPU_TRAP_CFG_SYSCALL_CPU2_HOOK(trapInfo) // Not used in this example
|
||||
*
|
||||
* #define IFXCPU_TRAP_CFG_SYSCALL_CPU3_HOOK(trapInfo) // Not used in this example
|
||||
*
|
||||
* #define IFXCPU_TRAP_CFG_SYSCALL_CPU4_HOOK(trapInfo) // Not used in this example
|
||||
*
|
||||
* #define IFXCPU_TRAP_CFG_SYSCALL_CPU5_HOOK(trapInfo) // Not used in this example
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \note The exten hooks are effective only if this feature is enabled.
|
||||
*
|
||||
*/
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXCPU_TRAPS_H_ */
|
||||
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* \file IfxDma_Dma.c
|
||||
* \brief DMA DMA details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxDma_Dma.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief local function to copy a transaction set into DMA channel SFRs or memory location (for linked lists)
|
||||
* \param channel Specifies the pointer to DMA channel registers
|
||||
* \param config pointer to the DMA default channel configuration structure
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxDma_Dma_configureTransactionSet(Ifx_DMA_CH *channel, const IfxDma_Dma_ChannelConfig *config);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_STATIC void IfxDma_Dma_configureTransactionSet(Ifx_DMA_CH *channel, const IfxDma_Dma_ChannelConfig *config)
|
||||
{
|
||||
/* shadow address shall be 32-Byte Aligned */
|
||||
{
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, ((config->shadowAddress & 0x1F) == 0U));
|
||||
}
|
||||
|
||||
{
|
||||
Ifx_DMA_CH_CHCFGR chcfgr;
|
||||
chcfgr.U = 0;
|
||||
chcfgr.B.TREL = config->transferCount;
|
||||
chcfgr.B.BLKM = config->blockMode;
|
||||
chcfgr.B.RROAT = config->requestMode;
|
||||
chcfgr.B.CHMODE = config->operationMode;
|
||||
chcfgr.B.CHDW = config->moveSize;
|
||||
chcfgr.B.PRSEL = config->requestSource;
|
||||
chcfgr.B.PATSEL = config->pattern;
|
||||
|
||||
channel->CHCFGR.U = chcfgr.U;
|
||||
}
|
||||
|
||||
{
|
||||
Ifx_DMA_CH_ADICR adicr;
|
||||
adicr.U = 0;
|
||||
adicr.B.SMF = config->sourceAddressIncrementStep;
|
||||
adicr.B.INCS = config->sourceAddressIncrementDirection;
|
||||
adicr.B.CBLS = config->sourceAddressCircularRange;
|
||||
adicr.B.SCBE = config->sourceCircularBufferEnabled;
|
||||
adicr.B.DMF = config->destinationAddressIncrementStep;
|
||||
adicr.B.INCD = config->destinationAddressIncrementDirection;
|
||||
adicr.B.CBLD = config->destinationAddressCircularRange;
|
||||
adicr.B.DCBE = config->destinationCircularBufferEnabled;
|
||||
adicr.B.SHCT = config->shadowControl;
|
||||
adicr.B.STAMP = config->timestampEnabled;
|
||||
adicr.B.WRPSE = config->wrapSourceInterruptEnabled;
|
||||
adicr.B.WRPDE = config->wrapDestinationInterruptEnabled;
|
||||
adicr.B.INTCT = (config->channelInterruptEnabled ? 2 : 0) | (config->channelInterruptControl ? 1 : 0);
|
||||
adicr.B.IRDV = config->interruptRaiseThreshold;
|
||||
adicr.B.ETRL = config->transactionRequestLostInterruptEnabled;
|
||||
//enter also the circular buffer enable bits
|
||||
|
||||
channel->ADICR.U = adicr.U;
|
||||
}
|
||||
channel->SADR.U = config->sourceAddress;
|
||||
channel->DADR.U = config->destinationAddress;
|
||||
channel->SDCRCR.U = config->sourceDestinationAddressCrc;
|
||||
channel->RDCRCR.U = config->readDataCrc;
|
||||
|
||||
// write not allowed if SHCT=1 or SHCT=2
|
||||
if ((config->shadowControl != IfxDma_ChannelShadow_none) &&
|
||||
(config->shadowControl != IfxDma_ChannelShadow_src) &&
|
||||
(config->shadowControl != IfxDma_ChannelShadow_dst))
|
||||
{
|
||||
channel->SHADR.U = config->shadowAddress;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxDma_Dma_createModuleHandle(IfxDma_Dma *dmaHandle, Ifx_DMA *dma)
|
||||
{
|
||||
dmaHandle->dma = dma;
|
||||
}
|
||||
|
||||
|
||||
void IfxDma_Dma_deInitChannel(IfxDma_Dma *dma, IfxDma_ChannelId channel)
|
||||
{
|
||||
if (IfxDma_isChannelTransactionEnabled(dma->dma, channel))
|
||||
{
|
||||
IfxDma_disableChannelTransaction(dma->dma, channel);
|
||||
}
|
||||
|
||||
IfxDma_resetChannel(dma->dma, channel);
|
||||
|
||||
while (!(IfxDma_isChannelReset(dma->dma, channel)))
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
void IfxDma_Dma_initChannel(IfxDma_Dma_Channel *channel, const IfxDma_Dma_ChannelConfig *config)
|
||||
{
|
||||
Ifx_DMA *dma = config->module->dma;
|
||||
|
||||
channel->dma = dma;
|
||||
channel->channelId = config->channelId;
|
||||
channel->channel = &dma->CH[config->channelId];
|
||||
|
||||
IfxDma_Dma_configureTransactionSet(channel->channel, config);
|
||||
|
||||
{
|
||||
Ifx_DMA_TSR tsr;
|
||||
tsr.U = 0;
|
||||
|
||||
if (config->hardwareRequestEnabled)
|
||||
{
|
||||
tsr.B.ECH = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tsr.B.DCH = 1;
|
||||
}
|
||||
|
||||
dma->TSR[channel->channelId].U = tsr.U;
|
||||
}
|
||||
|
||||
if (config->channelInterruptPriority > 0)
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxDma_getSrcPointer(channel->dma, channel->channelId);
|
||||
IfxSrc_init(src, config->channelInterruptTypeOfService, config->channelInterruptPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxDma_Dma_initChannelConfig(IfxDma_Dma_ChannelConfig *config, IfxDma_Dma *dma)
|
||||
{
|
||||
const IfxDma_Dma_ChannelConfig defaultConfig = {
|
||||
.module = NULL_PTR,
|
||||
.channelId = IfxDma_ChannelId_0,
|
||||
.sourceAddress = 0,
|
||||
.destinationAddress = 0,
|
||||
.shadowAddress = 0,
|
||||
.readDataCrc = 0,
|
||||
.sourceDestinationAddressCrc = 0,
|
||||
.transferCount = 0,
|
||||
.blockMode = IfxDma_ChannelMove_1,
|
||||
.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest,
|
||||
.operationMode = IfxDma_ChannelOperationMode_single,
|
||||
.moveSize = IfxDma_ChannelMoveSize_8bit,
|
||||
.pattern = IfxDma_ChannelPattern_0_disable,
|
||||
.requestSource = IfxDma_ChannelRequestSource_peripheral,
|
||||
.busPriority = IfxDma_ChannelBusPriority_medium,
|
||||
.hardwareRequestEnabled = FALSE,
|
||||
.sourceAddressIncrementStep = IfxDma_ChannelIncrementStep_1,
|
||||
.sourceAddressIncrementDirection = IfxDma_ChannelIncrementDirection_positive,
|
||||
.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_32768,
|
||||
.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1,
|
||||
.destinationAddressIncrementDirection = IfxDma_ChannelIncrementDirection_positive,
|
||||
.destinationAddressCircularRange = IfxDma_ChannelIncrementCircular_32768,
|
||||
.shadowControl = IfxDma_ChannelShadow_none,
|
||||
.sourceCircularBufferEnabled = FALSE,
|
||||
.destinationCircularBufferEnabled = FALSE,
|
||||
.timestampEnabled = FALSE,
|
||||
.wrapSourceInterruptEnabled = FALSE,
|
||||
.wrapDestinationInterruptEnabled = FALSE,
|
||||
.channelInterruptEnabled = FALSE,
|
||||
.channelInterruptControl = IfxDma_ChannelInterruptControl_thresholdLimitMatch,
|
||||
.interruptRaiseThreshold = 0,
|
||||
.transactionRequestLostInterruptEnabled = FALSE,
|
||||
.channelInterruptPriority = 0,
|
||||
.channelInterruptTypeOfService = IfxSrc_Tos_cpu0
|
||||
};
|
||||
|
||||
/* Default Configuration */
|
||||
*config = defaultConfig;
|
||||
|
||||
/* take over module pointer */
|
||||
config->module = dma;
|
||||
}
|
||||
|
||||
|
||||
void IfxDma_Dma_initLinkedListEntry(void *ptrToAddress, const IfxDma_Dma_ChannelConfig *config)
|
||||
{
|
||||
IfxDma_Dma_configureTransactionSet((Ifx_DMA_CH *)ptrToAddress, config);
|
||||
}
|
||||
|
||||
|
||||
void IfxDma_Dma_initModule(IfxDma_Dma *dma, const IfxDma_Dma_Config *config)
|
||||
{
|
||||
dma->dma = config->dma;
|
||||
}
|
||||
|
||||
|
||||
void IfxDma_Dma_initModuleConfig(IfxDma_Dma_Config *config, Ifx_DMA *dma)
|
||||
{
|
||||
config->dma = dma;
|
||||
}
|
||||
@@ -0,0 +1,774 @@
|
||||
/**
|
||||
* \file IfxDma_Dma.h
|
||||
* \brief DMA DMA details
|
||||
* \ingroup IfxLld_Dma
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Dma_Dma_Usage How to use the DMA Interface driver?
|
||||
* \ingroup IfxLld_Dma
|
||||
*
|
||||
* The DMA interface driver provides a default configuration for data moves without intervention of the CPU or other on chip devices.
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework for different use cases.
|
||||
*
|
||||
* \section IfxLld_Dma_Dma_Preparation Preparation
|
||||
* \subsection IfxLld_Dma_Dma_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
*
|
||||
* \code
|
||||
* #include <Dma/Dma/IfxDma_Dma.h>
|
||||
* #include <Vadc/Adc/IfxVadc_Adc.h>
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Dma_Dma_Module Module initialisation
|
||||
*
|
||||
* Declare the dma handle as a global variable:
|
||||
*
|
||||
* \code
|
||||
* // DMA handle
|
||||
* IfxDma_Dma dma;
|
||||
* \endcode
|
||||
*
|
||||
* Initialize the DMA with following code:
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxDma_Dma_Config dmaConfig;
|
||||
* IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);
|
||||
*
|
||||
* // initialize module
|
||||
* // IfxDma_Dma dma; // declared globally
|
||||
* IfxDma_Dma_initModule(&dma, &dmaConfig);
|
||||
* \endcode
|
||||
*
|
||||
* This only has to be done once in the application.
|
||||
*
|
||||
* The "IfxDma_Dma dma" handle should either be declared as a global variable (as shown in this example),
|
||||
* or it can be created locally if desired:
|
||||
*
|
||||
* \code
|
||||
* IfxDma_Dma dma;
|
||||
* IfxDma_Dma_createModuleHandle(&dma, &MODULE_DMA);
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Dma_Dma_Simple Memory-to-Memory Transfers
|
||||
*
|
||||
* A large amount of data should be copied between SRI based memories, e.g. from Flash into the DSPR
|
||||
* of the current CPU. It's recommended to use 256 bit moves for this purpose for best performance.
|
||||
*
|
||||
* This requires, that source and target locations are 256 bit (32 byte) aligned. With the GCC compiler
|
||||
* this can be achieved by adding __attribute__ ((aligned(64))) to the arrays:
|
||||
*
|
||||
* \code
|
||||
* #define MEMORY_TRANSFER_NUM_WORDS 1024
|
||||
* uint32 __attribute__ ((aligned(64))) memoryDestination[MEMORY_TRANSFER_NUM_WORDS];
|
||||
* \endcode
|
||||
*
|
||||
* Channel configuration and handling for the data move:
|
||||
* \code
|
||||
* // construct the channel configuration
|
||||
* IfxDma_Dma_ChannelConfig chnCfg;
|
||||
* IfxDma_Dma_initChannelConfig(&chnCfg, &dma);
|
||||
*
|
||||
* // select DMA channel which should be used
|
||||
* chnCfg.channelId = IfxDma_ChannelId_0;
|
||||
*
|
||||
* // source and destination address
|
||||
* chnCfg.sourceAddress = (uint32)0x80000000; // somewhere in flash section, here: start of PFlash (only for demo)
|
||||
* chnCfg.destinationAddress = (uint32)memoryDestination;
|
||||
*
|
||||
* // move size, transfer count and request/operation mode
|
||||
* chnCfg.moveSize = IfxDma_ChannelMoveSize_256bit;
|
||||
* chnCfg.transferCount = (4 * MEMORY_TRANSFER_NUM_WORDS) / 32; // e.g. 1024 words require 128 * 256 bit moves
|
||||
* chnCfg.requestMode = IfxDma_ChannelRequestMode_completeTransactionPerRequest;
|
||||
* chnCfg.operationMode = IfxDma_ChannelOperationMode_continuous;
|
||||
*
|
||||
* // transfer configuration into DMA channel registers
|
||||
* IfxDma_Dma_Channel chn;
|
||||
* IfxDma_Dma_initChannel(&chn, &chnCfg);
|
||||
*
|
||||
* // start transfer and wait until it's finished
|
||||
* IfxDma_Dma_startChannelTransaction(&chn);
|
||||
* while( IfxDma_Dma_isChannelTransactionPending(&chn) == TRUE );
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Dma_Dma_Peripheral Peripheral-to-Memory Transfers
|
||||
*
|
||||
* The content of 8 ADC result registers should be transfered to a memory location in DSPR whenever
|
||||
* an VADC autoscan has been finished. After the DMA transaction, an interrupt should be triggered
|
||||
* so that the CPU can process the conversion results.
|
||||
*
|
||||
* We use following global variables:
|
||||
* \code
|
||||
* // buffer for autoscanned conversion result values
|
||||
* #define NUM_SCANNED_CHANNELS 8
|
||||
* static uint16 vadcResultBuffer[NUM_SCANNED_CHANNELS];
|
||||
*
|
||||
* // VADC handle
|
||||
* IfxVadc_Adc vadc;
|
||||
*
|
||||
* // VADC group handle
|
||||
* static IfxVadc_Adc_Group adcGroup;
|
||||
*
|
||||
* // DMA channel handle
|
||||
* static IfxDma_Dma_Channel dmaChn;
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* Create an interrupt handler for the DMA channel request:
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define IFX_INTPRIO_DMA_CH0 1
|
||||
*
|
||||
* IFX_INTERRUPT(dmaCh0ISR, 0, IFX_INTPRIO_DMA_CH0)
|
||||
* {
|
||||
* // ...
|
||||
* // do something with the conversion results in vadcResultBuffer[]
|
||||
* // ...
|
||||
*
|
||||
* // re-init DMA channel destination address
|
||||
* IfxDma_Dma_setChannelDestinationAddress(&dmaChn, ADDR_CPU_DSPR(IfxCpu_getCoreId(), &vadcResultBuffer[0]));
|
||||
*
|
||||
* // start new transaction
|
||||
* IfxDma_Dma_setChannelTransferCount(&dmaChn, NUM_SCANNED_CHANNELS);
|
||||
*
|
||||
* {
|
||||
* uint32 channels = 0xff; // all 8 channels
|
||||
* uint32 mask = 0xff; // modify the selection of all channels
|
||||
*
|
||||
* // configure autoscan (single shot, not continuous scan)
|
||||
* IfxVadc_Adc_setScan(&adcGroup, channels, mask);
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* ADC configuration:
|
||||
* \code
|
||||
* // create configuration
|
||||
* IfxVadc_Adc_Config adcConfig;
|
||||
* IfxVadc_Adc_initModuleConfig(&adcConfig, &MODULE_VADC);
|
||||
*
|
||||
* adcConfig.startupCalibration = TRUE;
|
||||
*
|
||||
* // initialize module
|
||||
* // IfxVadc_Adc vadc; // declared globally
|
||||
* IfxVadc_Adc_initModule(&vadc, &adcConfig);
|
||||
*
|
||||
* // create group config
|
||||
* IfxVadc_Adc_GroupConfig adcGroupConfig;
|
||||
* IfxVadc_Adc_initGroupConfig(&adcGroupConfig, &vadc);
|
||||
*
|
||||
* // initialize the group
|
||||
* //IfxVadc_Adc_Group adcGroup; // defined globally
|
||||
* adcGroupConfig.groupId = IfxVadc_GroupId_0;
|
||||
* adcGroupConfig.master = adcGroupConfig.groupId;
|
||||
*
|
||||
* // enable all arbiter request sources
|
||||
* adcGroupConfig.arbiter.requestSlotQueueEnabled = TRUE; // enable Queue mode
|
||||
* adcGroupConfig.arbiter.requestSlotScanEnabled = TRUE; // enable Scan mode
|
||||
* adcGroupConfig.arbiter.requestSlotBackgroundScanEnabled = TRUE; // enable Background scan
|
||||
*
|
||||
* // enable all gates in "always" mode (no edge detection)
|
||||
* adcGroupConfig.queueRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;
|
||||
* adcGroupConfig.scanRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;
|
||||
* adcGroupConfig.backgroundScanRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;
|
||||
*
|
||||
* IfxVadc_Adc_initGroup(&adcGroup, &adcGroupConfig);
|
||||
*
|
||||
* {
|
||||
* // create channel config
|
||||
* IfxVadc_Adc_ChannelConfig adcChannelConfig;
|
||||
* IfxVadc_Adc_initChannelConfig(&adcChannelConfig, &adcGroup);
|
||||
*
|
||||
* // initialize the channels
|
||||
* for(int i=0; i<NUM_SCANNED_CHANNELS; ++i) {
|
||||
* adcChannelConfig.channelId = (IfxVadc_ChannelId)i;
|
||||
* adcChannelConfig.resultRegister = IfxVadc_ChannelResult_0;
|
||||
*
|
||||
* // initialize the channel
|
||||
* IfxVadc_Adc_Channel adcChannel;
|
||||
* IfxVadc_Adc_initChannel(&adcChannel, &adcChannelConfig);
|
||||
*
|
||||
* IfxVadc_Adc_configureWaitForReadMode(&adcChannel, TRUE);
|
||||
* }
|
||||
* }
|
||||
* adcGroup.group->RCR[0].B.SRGEN = 1; // interrupt when new result is available
|
||||
*
|
||||
* // send service request to DMA Channel 0
|
||||
* IfxSrc_init((Ifx_SRC_SRCR*)&MODULE_SRC.VADC.G[0], IfxSrc_Tos_dma, 0);
|
||||
* IfxSrc_enable((Ifx_SRC_SRCR*)&MODULE_SRC.VADC.G[0]);
|
||||
* \endcode
|
||||
*
|
||||
* And finally the DMA channel configuration
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxDma_Dma_Config dmaConfig;
|
||||
* IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);
|
||||
*
|
||||
* // initialize module
|
||||
* IfxDma_Dma dma;
|
||||
* IfxDma_Dma_initModule(&dma, &dmaConfig);
|
||||
*
|
||||
* {
|
||||
* // construct the channel configuration
|
||||
* IfxDma_Dma_ChannelConfig chnCfg;
|
||||
* IfxDma_Dma_initChannelConfig(&chnCfg, &dma);
|
||||
*
|
||||
* // select DMA channel which should be used
|
||||
* chnCfg.channelId = IfxDma_ChannelId_0;
|
||||
* chnCfg.hardwareRequestEnabled = TRUE; // will be triggered from VADC service request
|
||||
*
|
||||
* // interrupt configuration
|
||||
* chnCfg.channelInterruptEnabled = TRUE; // service request from DMA after all words have been transfered
|
||||
* chnCfg.channelInterruptPriority = IFX_INTPRIO_DMA_CH0;
|
||||
* chnCfg.channelInterruptTypeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());
|
||||
*
|
||||
* // source and destination address
|
||||
* chnCfg.sourceAddress = (uint32)&adcGroup.group->RES[0]; // first result register
|
||||
* chnCfg.sourceCircularBufferEnabled = TRUE;
|
||||
* chnCfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_1; // keep this address
|
||||
*
|
||||
* chnCfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &vadcResultBuffer[0]); // move into result buffer
|
||||
* chnCfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; // increment once (=2 bytes) with each write
|
||||
*
|
||||
* // move size, transfer count and request/operation mode
|
||||
* chnCfg.moveSize = IfxDma_ChannelMoveSize_16bit;
|
||||
* chnCfg.transferCount = NUM_SCANNED_CHANNELS; // for the scanned channels
|
||||
* chnCfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest;
|
||||
* chnCfg.operationMode = IfxDma_ChannelOperationMode_continuous; // hw request enable remains set after transaction
|
||||
*
|
||||
*
|
||||
* // transfer configuration into DMA channel registers
|
||||
* // IfxDma_Dma_Channel dmaChn; // declared globally
|
||||
* IfxDma_Dma_initChannel(&dmaChn, &chnCfg);
|
||||
*
|
||||
* // configure IRQ handler which will be called after all result registers have been transfered
|
||||
* IfxCpu_Irq_installInterruptHandler(&dmaCh0ISR, IFX_INTPRIO_DMA_CH0);
|
||||
*
|
||||
* // enable CPU interrupts
|
||||
* IfxCpu_enableInterrupts();
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* In order to start the initial channel conversions, use:
|
||||
* \code
|
||||
* {
|
||||
* uint32 channels = 0xff; // all 8 channels
|
||||
* uint32 mask = 0xff; // modify the selection of all channels
|
||||
*
|
||||
* // configure and start autoscan (single shot, not continuous mode)
|
||||
* IfxVadc_Adc_setScan(&adcGroup, channels, mask);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* DMA will transfer the results to DSPR during the autoscan (whenever a new result is availale), and
|
||||
* invoke the dmaCh0ISR function once all channels have been converted.
|
||||
*
|
||||
* The ISR will re-configure the DMA channel and re-start the autoscan.
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Dma_Dma_LinkedList Linked Lists
|
||||
*
|
||||
* Linked lists allow to initiate multiple DMA transactions from independent transaction sets which are
|
||||
* typically stored in a DSPR memory location, and fetched and executed from the DMA channel without
|
||||
* further CPU interaction.
|
||||
*
|
||||
* Following example demonstrates, how 5 different transactions can be initiated from a single request.
|
||||
* We copy the data of 5 CAN message objects to a DSPR location.
|
||||
*
|
||||
* Includes and global variables:
|
||||
* \code
|
||||
* #include <Dma/Dma/IfxDma_Dma.h>
|
||||
* #include <Scu/Std/IfxScuWdt.h>
|
||||
* #include <IfxCan_reg.h>
|
||||
*
|
||||
* // DMA channel handle
|
||||
* IfxDma_Dma_Channel chn;
|
||||
*
|
||||
* // Linked List storage
|
||||
* // IMPORTANT: it has to be aligned to an 256bit address, otherwise DMA can't read it
|
||||
* #define NUM_LINKED_LIST_ITEMS 5
|
||||
* IFX_ALIGN(256) Ifx_DMA_CH linkedList[NUM_LINKED_LIST_ITEMS] ;
|
||||
*
|
||||
* // transfer these values to various CAN_MODATA[LH] registers via linked lists
|
||||
* #define NUM_TRANSFERED_WORDS 2
|
||||
* uint32 sourceBuffer[NUM_LINKED_LIST_ITEMS][NUM_TRANSFERED_WORDS];
|
||||
*
|
||||
* const uint32 destinationAddresses[NUM_LINKED_LIST_ITEMS] = {
|
||||
* (uint32)&CAN_MODATAL0,
|
||||
* (uint32)&CAN_MODATAL1,
|
||||
* (uint32)&CAN_MODATAL2,
|
||||
* (uint32)&CAN_MODATAL3,
|
||||
* (uint32)&CAN_MODATAL4,
|
||||
* };
|
||||
* \endcode
|
||||
*
|
||||
* Following code to prepare CAN for this demo:
|
||||
* \code
|
||||
* // enable CAN (no Ifx LLD available yet)
|
||||
* {
|
||||
* uint32 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
* IfxScuWdt_clearCpuEndinit(passwd);
|
||||
*
|
||||
* CAN_CLC.U = 0x0100;
|
||||
* if( CAN_CLC.U ); // synch access
|
||||
*
|
||||
* // select f_clc as kernel clock
|
||||
* CAN_MCR.B.CLKSEL = 1;
|
||||
*
|
||||
* // configure fractional divider
|
||||
* CAN_FDR.U = 0x43ff;
|
||||
*
|
||||
* // wait until RAM has been initialized
|
||||
* while( CAN_PANCTR.B.BUSY );
|
||||
*
|
||||
* IfxScuWdt_setCpuEndinit(passwd);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* Build a linked list
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxDma_Dma_Config dmaConfig;
|
||||
* IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);
|
||||
*
|
||||
* // initialize module
|
||||
* IfxDma_Dma dma;
|
||||
* IfxDma_Dma_initModule(&dma, &dmaConfig);
|
||||
*
|
||||
* // initial channel configuration
|
||||
* IfxDma_Dma_ChannelConfig cfg;
|
||||
* IfxDma_Dma_initChannelConfig(&cfg, &dma);
|
||||
*
|
||||
* // following settings are used by all transactions
|
||||
* cfg.transferCount = NUM_TRANSFERED_WORDS;
|
||||
* cfg.requestMode = IfxDma_ChannelRequestMode_completeTransactionPerRequest;
|
||||
* cfg.moveSize = IfxDma_ChannelMoveSize_32bit;
|
||||
* cfg.shadowControl = IfxDma_ChannelShadow_linkedList;
|
||||
*
|
||||
* // generate linked list items
|
||||
* for(int i=0; i<NUM_LINKED_LIST_ITEMS; ++i) {
|
||||
* cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &sourceBuffer[i]);
|
||||
* cfg.destinationAddress = destinationAddresses[i];
|
||||
*
|
||||
* // address to next transaction set
|
||||
* cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (uint32)&linkedList[(i + 1) % NUM_LINKED_LIST_ITEMS]);
|
||||
*
|
||||
* // transfer first transaction set into DMA channel
|
||||
* if( i == 0 ) {
|
||||
* IfxDma_Dma_initChannel(&chn, &cfg);
|
||||
* }
|
||||
*
|
||||
* // transfer into linked list storage
|
||||
* IfxDma_Dma_initLinkedListEntry((void *)&linkedList[i], &cfg);
|
||||
*
|
||||
* if( i == 0 ) {
|
||||
* // - trigger channel interrupt once the first transaction set has been loaded (again) into DMA channel
|
||||
* linkedList[i].CHCSR.B.SIT = 1;
|
||||
* } else {
|
||||
* // - activate SCH (transaction request) for each entry, except for the first one (linked list terminated here)
|
||||
* linkedList[i].CHCSR.B.SCH = 1;
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* The transfer can be started via software with:
|
||||
* \code
|
||||
* // clear service request flag
|
||||
* (IfxDma_Dma_getSrcPointer(&chn))->B.CLRR = 1;
|
||||
*
|
||||
* // start linked list transaction
|
||||
* IfxDma_Dma_startChannelTransaction(&chn);
|
||||
*
|
||||
* // wait for service request which is triggered at the end of linked list transfers
|
||||
* while( !(IfxDma_Dma_getSrcPointer(&chn))->B.SRR );
|
||||
* \endcode
|
||||
*
|
||||
* In order to synchronize with the end of linked list operations, it's recommended to poll the service request flag (triggered via linkedList[NUM_LINKED_LIST_ITEMS-1].CHCSR.B.SIT after the last word has been transfered), and not the transaction count as shown before, because a linked list will initiate multiple transactions.
|
||||
*
|
||||
* \defgroup IfxLld_Dma_Dma DMA
|
||||
* \ingroup IfxLld_Dma
|
||||
* \defgroup IfxLld_Dma_Dma_Data_Structures Data Structures
|
||||
* \ingroup IfxLld_Dma_Dma
|
||||
* \defgroup IfxLld_Dma_Dma_Module_Initialize Module Initialization
|
||||
* \ingroup IfxLld_Dma_Dma
|
||||
* \defgroup IfxLld_Dma_Dma_Channel_Initialize Channel Initialization
|
||||
* \ingroup IfxLld_Dma_Dma
|
||||
* \defgroup IfxLld_Dma_Dma_Linked_List Linked Lists
|
||||
* \ingroup IfxLld_Dma_Dma
|
||||
* \defgroup IfxLld_Dma_Dma_Channel_Transaction_Initiate Channel Transactions
|
||||
* \ingroup IfxLld_Dma_Dma
|
||||
*/
|
||||
|
||||
#ifndef IFXDMA_DMA_H
|
||||
#define IFXDMA_DMA_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxDma_cfg.h"
|
||||
#include "Dma/Std/IfxDma.h"
|
||||
#include "Cpu/Std/IfxCpu.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Dma_Dma_Data_Structures
|
||||
* \{ */
|
||||
/** \brief DMA base address data structure (Module handle)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_DMA *dma; /**< \brief Specifies the pointer to the DMA registers */
|
||||
} IfxDma_Dma;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dma_Dma_Data_Structures
|
||||
* \{ */
|
||||
/** \brief Channel handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_DMA *dma; /**< \brief Specifies the pointer to the DMA registers */
|
||||
IfxDma_ChannelId channelId; /**< \brief Specifies the DMA channel */
|
||||
Ifx_DMA_CH *channel; /**< \brief Specifies the pointer to DMA channel registers */
|
||||
} IfxDma_Dma_Channel;
|
||||
|
||||
/** \brief Configuration data structure of the channel
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxDma_Dma *module; /**< \brief Specifies pointer to the IfxDma_Dma module handle */
|
||||
IfxDma_ChannelId channelId; /**< \brief Specifies the channel being used */
|
||||
uint32 sourceAddress; /**< \brief Source address for the DMA channel */
|
||||
uint32 destinationAddress; /**< \brief Destination address for the DMA channel */
|
||||
uint32 shadowAddress; /**< \brief Initial content of shadow address for the DMA channel */
|
||||
uint32 readDataCrc; /**< \brief Checksum for read data of the channel */
|
||||
uint32 sourceDestinationAddressCrc; /**< \brief Checksum for source and destination address of channel */
|
||||
uint16 transferCount; /**< \brief Number of transfers in a transaction */
|
||||
IfxDma_ChannelMove blockMode; /**< \brief Number of moves in a transfer */
|
||||
IfxDma_ChannelRequestMode requestMode; /**< \brief A service request initiates a single transfer, or the complete transaction */
|
||||
IfxDma_ChannelOperationMode operationMode; /**< \brief keep enable/disable the hardware channel request after a transaction */
|
||||
IfxDma_ChannelMoveSize moveSize; /**< \brief Read/write data size */
|
||||
IfxDma_ChannelPattern pattern; /**< \brief Pattern selection operation modes */
|
||||
IfxDma_ChannelRequestSource requestSource; /**< \brief Request of channel transfer through hardware or daisy chain. channel transfer complete interrupt of previous channel will trigger the next channel request */
|
||||
IfxDma_ChannelBusPriority busPriority; /**< \brief Bus priority selection */
|
||||
boolean hardwareRequestEnabled; /**< \brief Enabling channel transaction via hardware request */
|
||||
IfxDma_ChannelIncrementStep sourceAddressIncrementStep; /**< \brief Describes the address offset with which the source address should be modified after each move */
|
||||
IfxDma_ChannelIncrementDirection sourceAddressIncrementDirection; /**< \brief Decides whether the source address offset after each move should be added or decremented from the exisiting address */
|
||||
IfxDma_ChannelIncrementCircular sourceAddressCircularRange; /**< \brief Determines which part of the source address remains unchanged and therby not updated after each move */
|
||||
IfxDma_ChannelIncrementStep destinationAddressIncrementStep; /**< \brief Describes the address offset with which the destination address should be modified after each move */
|
||||
IfxDma_ChannelIncrementDirection destinationAddressIncrementDirection; /**< \brief Decides whether the destination address offset after each move should be added or decremented from the exisiting address */
|
||||
IfxDma_ChannelIncrementCircular destinationAddressCircularRange; /**< \brief Determines which part of the destination address remains unchanged and therby not updated after each move */
|
||||
IfxDma_ChannelShadow shadowControl; /**< \brief selects the shadow transfer mode */
|
||||
boolean sourceCircularBufferEnabled; /**< \brief Enables/Disables the source circular buffering */
|
||||
boolean destinationCircularBufferEnabled; /**< \brief Enables/Disables the destination circular buffering */
|
||||
boolean timestampEnabled; /**< \brief Enables/Disables the appendage of the time stamp after end of the last DMA move in a transaction */
|
||||
boolean wrapSourceInterruptEnabled; /**< \brief An interrupt should be triggered whenever source address is wrapped */
|
||||
boolean wrapDestinationInterruptEnabled; /**< \brief An interrupt should be triggered whenever destination address is wrapped */
|
||||
boolean channelInterruptEnabled; /**< \brief The channel transfer interrupt should be triggered. See also channelInterruptControl */
|
||||
IfxDma_ChannelInterruptControl channelInterruptControl; /**< \brief The channel transfer interrupt can either be triggered depending on the interruptRaiseThreshold, or each time the transaction count is decremented */
|
||||
uint8 interruptRaiseThreshold; /**< \brief The value of the transferCount at which the interrupt should be raised */
|
||||
boolean transactionRequestLostInterruptEnabled; /**< \brief Enables/Disables the channel transaction request lost interrupt */
|
||||
Ifx_Priority channelInterruptPriority; /**< \brief Priority of the channel interrupt trigger */
|
||||
IfxSrc_Tos channelInterruptTypeOfService; /**< \brief Interrupt service provider */
|
||||
} IfxDma_Dma_ChannelConfig;
|
||||
|
||||
/** \brief Configuration data structure of the Module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_DMA *dma; /**< \brief Specifies the pointer to the DMA registers */
|
||||
} IfxDma_Dma_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dma_Dma_Module_Initialize
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief initializes a DMA module handle based on the current configuration.
|
||||
* Can be used in code where it's ensure that the DMA module is already initialized, and a DMA handle isn't globally available.
|
||||
* \param dmaHandle pointer to the DMA module handle
|
||||
* \param dma pointer to the DMA registers
|
||||
* \return None
|
||||
*
|
||||
* \code
|
||||
* IfxDma_Dma dma;
|
||||
* IfxDma_Dma_createModuleHandle(&dma, &MODULE_DMA);
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDma_Dma_createModuleHandle(IfxDma_Dma *dmaHandle, Ifx_DMA *dma);
|
||||
|
||||
/** \brief de-initialize the DMA channel
|
||||
* \param dma pointer to the DMA module handle
|
||||
* \param channel the DMA channel ID
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDma_Dma_deInitChannel(IfxDma_Dma *dma, IfxDma_ChannelId channel);
|
||||
|
||||
/** \brief Initialize the DMA module
|
||||
* \param dma pointer to the DMA module handle
|
||||
* \param config Pointer to configuration structure of the DMA module
|
||||
* \return None
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_Simple
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDma_Dma_initModule(IfxDma_Dma *dma, const IfxDma_Dma_Config *config);
|
||||
|
||||
/** \brief initialize the DMA module configuration
|
||||
* \param config Pointer to configuration structure of the DMA module
|
||||
* \param dma pointer to the DMA registers
|
||||
* \return None
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_Simple
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDma_Dma_initModuleConfig(IfxDma_Dma_Config *config, Ifx_DMA *dma);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dma_Dma_Channel_Initialize
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief initialize the DMA channel
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \param config pointer to the DMA default channel configuration structure
|
||||
* \return None
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_Simple
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDma_Dma_initChannel(IfxDma_Dma_Channel *channel, const IfxDma_Dma_ChannelConfig *config);
|
||||
|
||||
/** \brief initialize the DMA module channel configuration
|
||||
* \param config pointer to the DMA default channel configuration structure
|
||||
* \param dma pointer to the DMA module handle
|
||||
* \return None
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_Simple
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDma_Dma_initChannelConfig(IfxDma_Dma_ChannelConfig *config, IfxDma_Dma *dma);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dma_Dma_Linked_List
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the SRC pointer for given DMA channel
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \return SRC pointer for given DMA channel
|
||||
*/
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxDma_Dma_getSrcPointer(IfxDma_Dma_Channel *channel);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief linked list functionality within the DMA module
|
||||
* \param ptrToAddress pointer to the memory location where the linked list entry should be stored
|
||||
* \param config pointer to the DMA default channel configuration structure
|
||||
* \return None
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_LinkedList
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDma_Dma_initLinkedListEntry(void *ptrToAddress, const IfxDma_Dma_ChannelConfig *config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dma_Dma_Channel_Transaction_Initiate
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Clear a channel transfer interrupt flag
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDma_Dma_clearChannelInterrupt(IfxDma_Dma_Channel *channel);
|
||||
|
||||
/** \brief Return and clear a channel transfer interrupt flag
|
||||
* The flag is automatically cleared with the call to this function
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \return TRUE if the interrupt flag is set
|
||||
* FALSE if the interrupt flag is not set
|
||||
*/
|
||||
IFX_INLINE boolean IfxDma_Dma_getAndClearChannelInterrupt(IfxDma_Dma_Channel *channel);
|
||||
|
||||
/** \brief Return a channel transfer interrupt flag
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \return TRUE if the interrupt flag is set
|
||||
* FALSE if the interrupt flag is not set
|
||||
*/
|
||||
IFX_INLINE boolean IfxDma_Dma_getChannelInterrupt(IfxDma_Dma_Channel *channel);
|
||||
|
||||
/** \brief Poll for an ongoing transaction
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \return TRUE if a transaction request for the given channel is pending
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_Simple
|
||||
*
|
||||
*/
|
||||
IFX_INLINE boolean IfxDma_Dma_isChannelTransactionPending(IfxDma_Dma_Channel *channel);
|
||||
|
||||
/** \brief Re-initialize the destination address after a transaction
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \param address is the Initial address of the destination pointer
|
||||
* \return None
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_Simple
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxDma_Dma_setChannelDestinationAddress(IfxDma_Dma_Channel *channel, uint32 address);
|
||||
|
||||
/** \brief Re-initialize the source address after a transaction
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \param address is the Initial address of the source pointer
|
||||
* \return None
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_Simple
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxDma_Dma_setChannelSourceAddress(IfxDma_Dma_Channel *channel, uint32 address);
|
||||
|
||||
/** \brief Re-initialize the transfer count after a transaction
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \param transferCount value holds the DMA transfers within a transaction (1..16383; 0 handled like 1 transaction)
|
||||
* \return None
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_Simple
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxDma_Dma_setChannelTransferCount(IfxDma_Dma_Channel *channel, uint32 transferCount);
|
||||
|
||||
/** \brief initiate the DMA move transaction
|
||||
* \param channel pointer to the DMA base address and channel ID
|
||||
* \return None
|
||||
*
|
||||
* See \ref IfxLld_Dma_Dma_Simple
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxDma_Dma_startChannelTransaction(IfxDma_Dma_Channel *channel);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxDma_Dma_clearChannelInterrupt(IfxDma_Dma_Channel *channel)
|
||||
{
|
||||
IfxDma_clearChannelInterrupt(channel->dma, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxDma_Dma_getAndClearChannelInterrupt(IfxDma_Dma_Channel *channel)
|
||||
{
|
||||
return IfxDma_getAndClearChannelInterrupt(channel->dma, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxDma_Dma_getChannelInterrupt(IfxDma_Dma_Channel *channel)
|
||||
{
|
||||
return IfxDma_getChannelInterrupt(channel->dma, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxDma_Dma_getSrcPointer(IfxDma_Dma_Channel *channel)
|
||||
{
|
||||
return IfxDma_getSrcPointer(channel->dma, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxDma_Dma_isChannelTransactionPending(IfxDma_Dma_Channel *channel)
|
||||
{
|
||||
return IfxDma_isChannelTransactionPending(channel->dma, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDma_Dma_setChannelDestinationAddress(IfxDma_Dma_Channel *channel, uint32 address)
|
||||
{
|
||||
IfxDma_setChannelDestinationAddress(channel->dma, channel->channelId, (void *)address);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDma_Dma_setChannelSourceAddress(IfxDma_Dma_Channel *channel, uint32 address)
|
||||
{
|
||||
IfxDma_setChannelSourceAddress(channel->dma, channel->channelId, (void *)address);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDma_Dma_setChannelTransferCount(IfxDma_Dma_Channel *channel, uint32 transferCount)
|
||||
{
|
||||
IfxDma_setChannelTransferCount(channel->dma, channel->channelId, transferCount);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDma_Dma_startChannelTransaction(IfxDma_Dma_Channel *channel)
|
||||
{
|
||||
IfxDma_startChannelTransaction(channel->dma, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXDMA_DMA_H */
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* \file IfxDma.c
|
||||
* \brief DMA basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxDma.h"
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,493 @@
|
||||
/**
|
||||
* \file IfxDsadc_Dsadc.c
|
||||
* \brief DSADC DSADC details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxDsadc_Dsadc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief calculate division factor
|
||||
* \param sourceFreq Source frequency
|
||||
* \param targetFreq Target frequency
|
||||
* \return division factor
|
||||
*/
|
||||
IFX_STATIC sint32 IfxDsadc_Dsadc_calcDIVx(float32 sourceFreq, float32 *targetFreq);
|
||||
|
||||
/** \brief Initialises the auxilary filter
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \param config pointer to the DSADC fir auxilary filter configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initAuxFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_AuxFilterConfig *config);
|
||||
|
||||
/** \brief Initialises the comb filter
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \param config pointer to the DSADC comb filter configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initCombFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_CombFilterConfig *config);
|
||||
|
||||
/** \brief Initialises the demodulator
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \param config pointer to the DSADC demodulator configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initDemodulator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_DemodulatorConfig *config);
|
||||
|
||||
/** \brief Initialises the fir filter
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \param config pointer to the DSADC fir filter configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initFirFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_FirFilterConfig *config);
|
||||
|
||||
/** \brief Initialises the integrator
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \param config pointer to the DSADC fir integrator configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initIntegrator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_IntegratorConfig *config);
|
||||
|
||||
/** \brief Initialises the modulator
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \param config pointer to the DSADC modulator configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initModulator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_ModulatorConfig *config);
|
||||
|
||||
/** \brief Initialises the rectifier
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \param config pointer to the DSADC fir rectifier configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initRectifier(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_RectifierConfig *config);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_STATIC sint32 IfxDsadc_Dsadc_calcDIVx(float32 sourceFreq, float32 *targetFreq)
|
||||
{
|
||||
float32 bestError = 10e6;
|
||||
sint32 bestDiv = 2, i;
|
||||
|
||||
for (i = 2; i <= 32; i += 2)
|
||||
{
|
||||
float32 freq = sourceFreq / i;
|
||||
float32 error = __absf(freq - *targetFreq);
|
||||
|
||||
if (__leqf(error, bestError))
|
||||
{
|
||||
bestError = error;
|
||||
bestDiv = i;
|
||||
|
||||
if (!__neqf(error, 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*targetFreq = sourceFreq / bestDiv;
|
||||
|
||||
return (bestDiv / 2) - 1;
|
||||
}
|
||||
|
||||
|
||||
sint16 IfxDsadc_Dsadc_getAuxResult(IfxDsadc_Dsadc_Channel *channel)
|
||||
{
|
||||
return IfxDsadc_getAuxResult(channel->module, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initAuxFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_AuxFilterConfig *config)
|
||||
{
|
||||
Ifx_DSADC_CH_FCFGA fcfga;
|
||||
|
||||
fcfga.U = 0;
|
||||
|
||||
fcfga.B.CFADF = config->decimationFactor - 1;
|
||||
fcfga.B.CFAC = config->combFilterType;
|
||||
|
||||
fcfga.B.SRGA = config->serviceRequest;
|
||||
fcfga.B.ESEL = config->eventSelect;
|
||||
fcfga.B.EGT = config->eventGate;
|
||||
|
||||
fcfga.B.AFSC = config->combFilterShift;
|
||||
|
||||
(channel->channel)->FCFGA = fcfga;
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Dsadc_initCarrierGen(IfxDsadc_Dsadc *dsadc, const IfxDsadc_Dsadc_CarrierGenConfig *config)
|
||||
{
|
||||
Ifx_DSADC_CGCFG cgcfg;
|
||||
|
||||
cgcfg.U = 0;
|
||||
|
||||
float32 sourceFreq = IfxDsadc_getModulatorInputClockFreq(dsadc->dsadc);
|
||||
float32 targetFreq = config->frequency;
|
||||
cgcfg.B.DIVCG = IfxDsadc_Dsadc_calcDIVx(sourceFreq / (32 * 32), &targetFreq);
|
||||
cgcfg.B.SIGPOL = (config->inverted == FALSE) ? 0 : 1;
|
||||
cgcfg.B.BREV = (config->bitReversed == FALSE) ? 0 : 1;
|
||||
cgcfg.B.CGMOD = config->carrierWaveformMode;
|
||||
|
||||
dsadc->dsadc->CGCFG = cgcfg;
|
||||
|
||||
const IfxDsadc_Cgpwm_Out *pinPos = config->pinPos;
|
||||
|
||||
if (pinPos != NULL_PTR)
|
||||
{ /* Initialise positive carrier pin */
|
||||
IfxDsadc_initCgPwmPin(pinPos, config->pinMode, config->pinDriver);
|
||||
}
|
||||
|
||||
const IfxDsadc_Cgpwm_Out *pinNeg = config->pinNeg;
|
||||
|
||||
if (pinNeg != NULL_PTR)
|
||||
{ /* Initialise negative carrier pin */
|
||||
IfxDsadc_initCgPwmPin(pinNeg, config->pinMode, config->pinDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Dsadc_initChannel(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_ChannelConfig *config)
|
||||
{
|
||||
Ifx_DSADC *dsadc = config->module;
|
||||
|
||||
channel->channelId = config->channelId;
|
||||
channel->module = dsadc;
|
||||
channel->channel = (Ifx_DSADC_CH *)&dsadc->CH[config->channelId];
|
||||
|
||||
IfxDsadc_Dsadc_initModulator(channel, &config->modulator);
|
||||
IfxDsadc_Dsadc_initDemodulator(channel, &config->demodulator);
|
||||
IfxDsadc_Dsadc_initCombFilter(channel, &config->combFilter);
|
||||
IfxDsadc_Dsadc_initFirFilter(channel, &config->firFilter);
|
||||
IfxDsadc_Dsadc_initIntegrator(channel, &config->integrator);
|
||||
IfxDsadc_Dsadc_initAuxFilter(channel, &config->auxFilter);
|
||||
IfxDsadc_Dsadc_initRectifier(channel, &config->rectifier);
|
||||
|
||||
const IfxDsadc_Dsadc_ChannelPins *pins = config->channelPins;
|
||||
|
||||
if (pins != NULL_PTR)
|
||||
{
|
||||
const IfxDsadc_Dsn_In *dsn = pins->dsn;
|
||||
|
||||
if (dsn != NULL_PTR)
|
||||
{
|
||||
IfxDsadc_initDsnPin(dsn, pins->dsnMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
const IfxDsadc_Dsp_In *dsp = pins->dsp;
|
||||
|
||||
if (dsp != NULL_PTR)
|
||||
{
|
||||
IfxDsadc_initDspPin(dsp, pins->dspMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
const IfxDsadc_Cin_In *cin = pins->cin;
|
||||
|
||||
if (cin != NULL_PTR)
|
||||
{
|
||||
IfxDsadc_initCinPin(cin, pins->cinMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
const IfxDsadc_Din_In *din = pins->din;
|
||||
|
||||
if (din != NULL_PTR)
|
||||
{
|
||||
IfxDsadc_initDinPin(din, pins->dinMode, pins->pinDriver);
|
||||
}
|
||||
|
||||
const IfxDsadc_Itr_In *itr = pins->itr;
|
||||
|
||||
if (itr != NULL_PTR)
|
||||
{
|
||||
IfxDsadc_initItrPin(itr, pins->itrMode, pins->pinDriver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Dsadc_initChannelConfig(IfxDsadc_Dsadc_ChannelConfig *config, IfxDsadc_Dsadc *dsadc)
|
||||
{
|
||||
const IfxDsadc_Dsadc_ChannelConfig IfxDsadc_Dsadc_defaultChannelConfig = {
|
||||
.modulator = {
|
||||
.positiveInput = IfxDsadc_InputConfig_inputPin,
|
||||
.negativeInput = IfxDsadc_InputConfig_referenceGround,
|
||||
.inputGain = IfxDsadc_InputGain_factor1,
|
||||
.inputPin = IfxDsadc_InputPin_a,
|
||||
.modulatorClockFreq = 10.0e6,
|
||||
.commonModeVoltage = IfxDsadc_CommonModeVoltage_c,
|
||||
},
|
||||
.demodulator = {
|
||||
.inputDataSource = IfxDsadc_InputDataSource_onChipStandAlone,
|
||||
.triggerInput = IfxDsadc_TriggerInput_a,
|
||||
.integrationTrigger = IfxDsadc_IntegratorTrigger_bypassed,
|
||||
.timestampTrigger = IfxDsadc_TimestampTrigger_noTrigger,
|
||||
.sampleClockSource = IfxDsadc_SampleClockSource_internal,
|
||||
.sampleStrobe = IfxDsadc_SampleStrobe_sampleOnRisingEdge,
|
||||
},
|
||||
.combFilter = {
|
||||
.bypassed = FALSE,
|
||||
.combFilterType = IfxDsadc_MainCombFilterType_comb3,
|
||||
.combFilterShift = IfxDsadc_MainCombFilterShift_noShift,
|
||||
.serviceRequest = IfxDsadc_MainServiceRequest_everyNewResult,
|
||||
.decimationFactor = 50,
|
||||
.startValue = 0,
|
||||
},
|
||||
.firFilter = {
|
||||
.fir0Enabled = FALSE,
|
||||
.fir1Enabled = FALSE,
|
||||
.offsetCompensation = FALSE,
|
||||
.dataShift = IfxDsadc_FirDataShift_noShift,
|
||||
.internalShift = IfxDsadc_FirInternalShift_noShift,
|
||||
},
|
||||
.integrator = {
|
||||
.windowSize = IfxDsadc_IntegrationWindowSize_internalControl,
|
||||
.discardCount = 0,
|
||||
.integrationCount = 20,
|
||||
.integrationCycles = 1,
|
||||
},
|
||||
.auxFilter = {
|
||||
.bypassed = TRUE,
|
||||
.combFilterType = IfxDsadc_AuxCombFilterType_comb1,
|
||||
.combFilterShift = IfxDsadc_AuxCombFilterShift_noShift,
|
||||
.serviceRequest = IfxDsadc_AuxServiceRequest_never,
|
||||
.eventSelect = IfxDsadc_AuxEvent_everyNewResult,
|
||||
.eventGate = IfxDsadc_AuxGate_definedByESEL,
|
||||
.decimationFactor = 4,
|
||||
},
|
||||
.rectifier = {
|
||||
.enabled = FALSE,
|
||||
.signSource = IfxDsadc_RectifierSignSource_onChipGenerator,
|
||||
.signDelay = 0,
|
||||
.signPeriod = 0,
|
||||
},
|
||||
|
||||
.channelPins = NULL_PTR
|
||||
};
|
||||
|
||||
*config = IfxDsadc_Dsadc_defaultChannelConfig;
|
||||
config->channelId = IfxDsadc_ChannelId_0;
|
||||
|
||||
if (dsadc != NULL_PTR)
|
||||
{
|
||||
config->module = dsadc->dsadc;
|
||||
}
|
||||
else
|
||||
{
|
||||
config->module = NULL_PTR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initCombFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_CombFilterConfig *config)
|
||||
{
|
||||
Ifx_DSADC_CH_FCFGC fcfgc;
|
||||
|
||||
fcfgc.U = 0;
|
||||
|
||||
fcfgc.B.CFMDF = config->decimationFactor - 1;
|
||||
fcfgc.B.CFMC = config->combFilterType;
|
||||
fcfgc.B.CFEN = (config->bypassed == FALSE) ? 1 : 0;
|
||||
|
||||
fcfgc.B.MFSC = config->combFilterShift;
|
||||
|
||||
fcfgc.B.SRGM = config->serviceRequest;
|
||||
fcfgc.B.CFMSV = config->startValue - 1;
|
||||
|
||||
(channel->channel)->FCFGC = fcfgc;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initDemodulator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_DemodulatorConfig *config)
|
||||
{
|
||||
Ifx_DSADC_CH_DICFG dicfg;
|
||||
|
||||
dicfg.U = 0;
|
||||
|
||||
dicfg.B.DSRC = config->inputDataSource;
|
||||
dicfg.B.DSWC = 1; // enable write access for this bitfield
|
||||
|
||||
dicfg.B.ITRMODE = config->integrationTrigger;
|
||||
dicfg.B.TSTRMODE = config->timestampTrigger;
|
||||
dicfg.B.TRSEL = config->triggerInput;
|
||||
dicfg.B.TRWC = 1; // enable write access for these bitfields
|
||||
|
||||
dicfg.B.CSRC = config->sampleClockSource;
|
||||
dicfg.B.STROBE = config->sampleStrobe;
|
||||
dicfg.B.SCWC = 1; // enable write access for these bitfields
|
||||
|
||||
(channel->channel)->DICFG = dicfg;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initFirFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_FirFilterConfig *config)
|
||||
{
|
||||
Ifx_DSADC_CH_FCFGM fcfgm;
|
||||
|
||||
fcfgm.U = 0;
|
||||
|
||||
fcfgm.B.FIR0EN = (config->fir0Enabled != FALSE) ? 1 : 0;
|
||||
fcfgm.B.FIR1EN = (config->fir1Enabled != FALSE) ? 1 : 0;
|
||||
fcfgm.B.OCEN = (config->offsetCompensation != FALSE) ? 1 : 0;
|
||||
fcfgm.B.DSH = config->dataShift;
|
||||
fcfgm.B.FSH = config->internalShift;
|
||||
|
||||
(channel->channel)->FCFGM = fcfgm;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initIntegrator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_IntegratorConfig *config)
|
||||
{
|
||||
Ifx_DSADC_CH_IWCTR iwctr;
|
||||
|
||||
iwctr.U = 0;
|
||||
|
||||
iwctr.B.REPVAL = config->integrationCycles - 1;
|
||||
iwctr.B.NVALDIS = config->discardCount;
|
||||
iwctr.B.IWS = config->windowSize;
|
||||
iwctr.B.NVALINT = config->integrationCount - 1;
|
||||
|
||||
(channel->channel)->IWCTR = iwctr;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initModulator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_ModulatorConfig *config)
|
||||
{
|
||||
Ifx_DSADC_CH_MODCFG modcfg;
|
||||
|
||||
modcfg.U = 0;
|
||||
|
||||
modcfg.B.INCFGP = config->positiveInput;
|
||||
modcfg.B.INCFGN = config->negativeInput;
|
||||
modcfg.B.GAINSEL = config->inputGain;
|
||||
modcfg.B.INSEL = config->inputPin;
|
||||
modcfg.B.INCWC = 1; // enable write access for these bitfields
|
||||
|
||||
float32 targetFreq = config->modulatorClockFreq;
|
||||
float32 sourceFreq = IfxDsadc_getModulatorInputClockFreq(channel->module);
|
||||
modcfg.B.DIVM = IfxDsadc_Dsadc_calcDIVx(sourceFreq, &targetFreq);
|
||||
modcfg.B.DWC = 1; // enable write access for this bitfield
|
||||
|
||||
modcfg.B.CMVS = config->commonModeVoltage;
|
||||
modcfg.B.GCEN = 0; // normal operation (calibration mode disabled)
|
||||
modcfg.B.MWC = 1; // enable write access for these bitfields
|
||||
|
||||
(channel->channel)->MODCFG = modcfg;
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Dsadc_initModule(IfxDsadc_Dsadc *dsadc, const IfxDsadc_Dsadc_Config *config)
|
||||
{
|
||||
Ifx_DSADC *dsadcSFR = config->dsadc;
|
||||
|
||||
dsadc->dsadc = dsadcSFR;
|
||||
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
dsadcSFR->CLC.U = 0x00000000;
|
||||
|
||||
if (dsadcSFR->CLC.U)
|
||||
{} // sync access
|
||||
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
|
||||
{
|
||||
Ifx_DSADC_GLOBCFG globcfg;
|
||||
globcfg.U = dsadcSFR->GLOBCFG.U;
|
||||
|
||||
globcfg.B.MCSEL = config->modulatorClockSelect;
|
||||
globcfg.B.LOSUP = config->lowPowerSupply;
|
||||
globcfg.B.PSWC = 1;
|
||||
|
||||
dsadcSFR->GLOBCFG.U = globcfg.U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Dsadc_initModuleConfig(IfxDsadc_Dsadc_Config *config, Ifx_DSADC *dsadc)
|
||||
{
|
||||
const IfxDsadc_Dsadc_Config IfxDsadc_Dsadc_defaultConfig = {
|
||||
.modulatorClockSelect = IfxDsadc_ModulatorClock_fDSD,
|
||||
.lowPowerSupply = IfxDsadc_LowPowerSupply_5V
|
||||
};
|
||||
|
||||
*config = IfxDsadc_Dsadc_defaultConfig;
|
||||
config->dsadc = dsadc;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxDsadc_Dsadc_initRectifier(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_RectifierConfig *config)
|
||||
{
|
||||
Ifx_DSADC_CH_RECTCFG rect;
|
||||
|
||||
rect.U = 0;
|
||||
rect.B.RFEN = config->enabled;
|
||||
rect.B.SSRC = config->signSource;
|
||||
(channel->channel)->RECTCFG = rect;
|
||||
(channel->channel)->CGSYNC.B.SDPOS = config->signDelay;
|
||||
(channel->channel)->CGSYNC.B.SDNEG = config->signDelay + (config->signPeriod / 2);
|
||||
(channel->channel)->IWCTR.B.NVALDIS = config->signDelay + 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Dsadc_initCarrierGenConfig(IfxDsadc_Dsadc_CarrierGenConfig *config)
|
||||
{
|
||||
config->bitReversed = FALSE;
|
||||
config->carrierWaveformMode = IfxDsadc_CarrierWaveformMode_sine;
|
||||
config->frequency = 10000;
|
||||
config->inverted = FALSE;
|
||||
config->pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1;
|
||||
config->pinMode = IfxPort_OutputMode_pushPull;
|
||||
config->pinNeg = NULL_PTR;
|
||||
config->pinPos = NULL_PTR;
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
/**
|
||||
* \file IfxDsadc_Dsadc.h
|
||||
* \brief DSADC DSADC details
|
||||
* \ingroup IfxLld_Dsadc
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Dsadc_Dsadc_Usage How to use the DSADC Interface driver?
|
||||
* \ingroup IfxLld_Dsadc
|
||||
*
|
||||
* The DSADC interface driver provides a default DSADC configuration for converting analog data streams inputs from external modulators via digital input channels, into digital values by using the on-chip demodulator channels.
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
* \section IfxLld_Dsadc_Dsadc_Preparation Preparation
|
||||
* \subsection IfxLld_Dsadc_Dsadc_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
* \code
|
||||
* #include <Dsadc/Dsadc/IfxDsadc_Dsadc.h>
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Dsadc_Dsadc_Variables Variables
|
||||
*
|
||||
* Declare the DSADC channel handle and available channels as global variables in your C code:
|
||||
*
|
||||
* \code
|
||||
* static IfxDsadc_Dsadc dsadc;
|
||||
* IfxDsadc_Dsadc_Channel dsadcChannel[IFXDSADC_NUM_CHANNELS];
|
||||
*
|
||||
* #if defined(DERIVATIVE_TC22x) || defined(DERIVATIVE_TC23x) || defined(DERIVATIVE_TC24x)
|
||||
* uint8 dsadcChannelAvailable[IFXDSADC_NUM_CHANNELS] = { 1, 0, 0, 1 };
|
||||
*
|
||||
* #elif defined(DERIVATIVE_TC27x) || defined(DERIVATIVE_TC27xB) || defined(DERIVATIVE_TC27xC) || defined(DERIVATIVE_TC27xD)
|
||||
* uint8 dsadcChannelAvailable[IFXDSADC_NUM_CHANNELS] = { 1, 1, 1, 1, 1, 1 };
|
||||
*
|
||||
* #elif defined(DERIVATIVE_TC26x) || defined(DERIVATIVE_TC26xB)
|
||||
* uint8 dsadcChannelAvailable[IFXDSADC_NUM_CHANNELS] = { 1, 0, 1, 1 };
|
||||
*
|
||||
* #elif defined(DERIVATIVE_TC29x) || defined(DERIVATIVE_TC29xB)
|
||||
* uint8 dsadcChannelAvailable[IFXDSADC_NUM_CHANNELS] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
*
|
||||
* #else
|
||||
* # error "Testcase not prepared for this derivative!"
|
||||
* #endif
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Dsadc_Dsadc_Init Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function. Here an example:
|
||||
* \code
|
||||
*
|
||||
* // create module config
|
||||
* IfxDsadc_Dsadc_Config dsadcConfig;
|
||||
* IfxDsadc_Dsadc_initModuleConfig(&dsadcConfig, &MODULE_DSADC);
|
||||
*
|
||||
* // initialize module
|
||||
*
|
||||
* IfxDsadc_Dsadc_initModule(&dsadc, &dsadcConfig);
|
||||
*
|
||||
* // create channel config
|
||||
* IfxDsadc_Dsadc_ChannelConfig dsadcChannelConfig;
|
||||
* IfxDsadc_Dsadc_initChannelConfig(&dsadcChannelConfig, &dsadc);
|
||||
*
|
||||
* // modify default configuration
|
||||
* dsadcChannelConfig.modulator.positiveInput = IfxDsadc_InputConfig_inputPin;
|
||||
* dsadcChannelConfig.modulator.negativeInput = IfxDsadc_InputConfig_inputPin;
|
||||
* dsadcChannelConfig.modulator.inputGain = IfxDsadc_InputGain_factor1;
|
||||
* dsadcChannelConfig.modulator.inputPin = IfxDsadc_InputPin_a;
|
||||
* dsadcChannelConfig.modulator.modulatorClockFreq = 10.0e6;
|
||||
* dsadcChannelConfig.modulator.commonModeVoltage = IfxDsadc_CommonModeVoltage_c;
|
||||
*
|
||||
* dsadcChannelConfig.combFilter.bypassed = FALSE;
|
||||
* dsadcChannelConfig.combFilter.combFilterType = IfxDsadc_MainCombFilterType_comb3;
|
||||
* dsadcChannelConfig.combFilter.combFilterShift = IfxDsadc_MainCombFilterShift_noShift;
|
||||
* dsadcChannelConfig.combFilter.serviceRequest = IfxDsadc_MainServiceRequest_everyNewResult;
|
||||
* dsadcChannelConfig.combFilter.decimationFactor = 32;
|
||||
* dsadcChannelConfig.combFilter.startValue = 32;
|
||||
*
|
||||
* dsadcChannelConfig.firFilter.fir0Enabled = TRUE;
|
||||
* dsadcChannelConfig.firFilter.fir1Enabled = TRUE;
|
||||
* dsadcChannelConfig.firFilter.offsetCompensation = FALSE;
|
||||
* dsadcChannelConfig.firFilter.dataShift = IfxDsadc_FirDataShift_shiftBy2;
|
||||
* dsadcChannelConfig.firFilter.internalShift = IfxDsadc_FirInternalShift_shiftBy1;
|
||||
*
|
||||
*
|
||||
* // initialize channels
|
||||
* for(int chn=0; chn<IFXDSADC_NUM_CHANNELS; ++chn) {
|
||||
* if( dsadcChannelAvailable[chn] ) {
|
||||
* dsadcChannelConfig.channelId = (IfxDsadc_ChannelId)chn;
|
||||
*
|
||||
* IfxDsadc_Dsadc_initChannel(&dsadcChannel[chn], &dsadcChannelConfig);
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* The DSADC is ready for use now!
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Dsadc_Dsadc_Conversions Conversions
|
||||
*
|
||||
* The DSADC driver provides simple to use Conversion function,
|
||||
*
|
||||
* \code
|
||||
* // start conversions
|
||||
* IfxDsadc_Dsadc_startScan(&dsadc, 0x3f, 0x3f);
|
||||
*
|
||||
* // results are now available in IFXDSADC(ds).CH[x].RESM.B.RESULT (x=0..5)
|
||||
* \endcode
|
||||
*
|
||||
* The converted data can be collected using the following function
|
||||
*
|
||||
* \code
|
||||
* // declared globally
|
||||
* // sint16 result[];
|
||||
* for(int chn=0; chn<IFXDSADC_NUM_CHANNELS; ++chn) {
|
||||
* if( dsadcChannelAvailable[chn] ) {
|
||||
* result = IfxDsadc_Dsadc_getMainResult(&dsadcChannel[chn]));
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Dsadc_Dsadc DSADC
|
||||
* \ingroup IfxLld_Dsadc
|
||||
* \defgroup IfxLld_Dsadc_Dsadc_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Dsadc_Dsadc
|
||||
* \defgroup IfxLld_Dsadc_Dsadc_Module Module Functions
|
||||
* \ingroup IfxLld_Dsadc_Dsadc
|
||||
* \defgroup IfxLld_Dsadc_Dsadc_Channel Channel Functions
|
||||
* \ingroup IfxLld_Dsadc_Dsadc
|
||||
* \defgroup IfxLld_Dsadc_Dsadc_Operative Operative Functions
|
||||
* \ingroup IfxLld_Dsadc_Dsadc
|
||||
* \defgroup IfxLld_Dsadc_Dsadc_Results Result Functions
|
||||
* \ingroup IfxLld_Dsadc_Dsadc
|
||||
* \defgroup IfxLld_Dsadc_Dsadc_Interrupt Interrupt Functions
|
||||
* \ingroup IfxLld_Dsadc_Dsadc
|
||||
*/
|
||||
|
||||
#ifndef IFXDSADC_DSADC_H
|
||||
#define IFXDSADC_DSADC_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Dsadc/Std/IfxDsadc.h"
|
||||
#include "Scu/Std/IfxScuWdt.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Dsadc_DataStructures
|
||||
* \{ */
|
||||
/** \brief Auxiliary comb filter configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean bypassed;
|
||||
IfxDsadc_AuxCombFilterType combFilterType; /**< \brief Comb Filter (auxiliary) configuration/type */
|
||||
IfxDsadc_AuxCombFilterShift combFilterShift; /**< \brief Comb Filter (auxiliary) shift control */
|
||||
IfxDsadc_AuxServiceRequest serviceRequest; /**< \brief Service request generation (auxiliary) */
|
||||
IfxDsadc_AuxEvent eventSelect; /**< \brief Service request generation (auxiliary) */
|
||||
IfxDsadc_AuxGate eventGate; /**< \brief Service request generation (auxiliary) */
|
||||
uint8 decimationFactor; /**< \brief CIC Filter (Auxiliary) decimation factor (4 .. 32) */
|
||||
} IfxDsadc_Dsadc_AuxFilterConfig;
|
||||
|
||||
/** \brief Channel Pins Configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IFX_CONST IfxDsadc_Cin_In *cin; /**< \brief the CIN Pin which should be configured */
|
||||
IfxPort_InputMode cinMode; /**< \brief the CIN pin input mode which should be configured */
|
||||
IFX_CONST IfxDsadc_Din_In *din; /**< \brief the DIN Pin which should be configured */
|
||||
IfxPort_InputMode dinMode; /**< \brief the DIN pin input mode which should be configured */
|
||||
IFX_CONST IfxDsadc_Itr_In *itr; /**< \brief the ITR Pin which should be configured */
|
||||
IfxPort_InputMode itrMode; /**< \brief the ITR pin input mode which should be configured */
|
||||
IFX_CONST IfxDsadc_Dsn_In *dsn; /**< \brief the DSN Pin which should be configured */
|
||||
IfxPort_InputMode dsnMode; /**< \brief the DSN pin output mode which should be configured */
|
||||
IFX_CONST IfxDsadc_Dsp_In *dsp; /**< \brief the DSP Pin which should be configured */
|
||||
IfxPort_InputMode dspMode; /**< \brief the DSP pin output mode which should be configured */
|
||||
IfxPort_PadDriver pinDriver; /**< \brief Pin Driver Configuration */
|
||||
} IfxDsadc_Dsadc_ChannelPins;
|
||||
|
||||
/** \brief Comb filter configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean bypassed; /**< \brief CIC Filter enable/bypass selection */
|
||||
IfxDsadc_MainCombFilterType combFilterType; /**< \brief Comb Filter (Main Chain) configuration/type */
|
||||
IfxDsadc_MainCombFilterShift combFilterShift; /**< \brief Comb Filter (Main Chain) shift control */
|
||||
IfxDsadc_MainServiceRequest serviceRequest; /**< \brief Service request generation (main chain) */
|
||||
uint16 decimationFactor; /**< \brief 4 .. 256 */
|
||||
uint16 startValue; /**< \brief 4 .. decimationFactor */
|
||||
} IfxDsadc_Dsadc_CombFilterConfig;
|
||||
|
||||
/** \brief Demodulator configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxDsadc_InputDataSource inputDataSource; /**< \brief Demodulator input data source selection */
|
||||
IfxDsadc_TriggerInput triggerInput; /**< \brief Trigger selection */
|
||||
IfxDsadc_IntegratorTrigger integrationTrigger; /**< \brief Integrator trigger mode selection */
|
||||
IfxDsadc_TimestampTrigger timestampTrigger; /**< \brief Timestamp trigger mode selection */
|
||||
IfxDsadc_SampleClockSource sampleClockSource; /**< \brief Demodulator sample clock source selection */
|
||||
IfxDsadc_SampleStrobe sampleStrobe; /**< \brief Demodulator data strobe generation mode selection */
|
||||
} IfxDsadc_Dsadc_DemodulatorConfig;
|
||||
|
||||
/** \brief FIR filters configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean fir0Enabled; /**< \brief FIR filter 0 enable/disable selection */
|
||||
boolean fir1Enabled; /**< \brief FIR filter 0 enable/disable selection */
|
||||
boolean offsetCompensation; /**< \brief Offset Compensation Filter enable/disable selection */
|
||||
IfxDsadc_FirDataShift dataShift; /**< \brief FIR data shift control selection */
|
||||
IfxDsadc_FirInternalShift internalShift; /**< \brief FIR shift control selction */
|
||||
} IfxDsadc_Dsadc_FirFilterConfig;
|
||||
|
||||
/** \brief Integrator configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxDsadc_IntegrationWindowSize windowSize; /**< \brief Integrator window size */
|
||||
uint16 discardCount; /**< \brief Number of discarded values to after active trigger: 1 .. 64 */
|
||||
uint16 integrationCount; /**< \brief Number of integrated values after discard step: 1 .. 64 */
|
||||
uint16 integrationCycles; /**< \brief Number of integration cycles: 1 .. 16. Used only when \ref IfxDsadc_IntegrationWindowSize_internalControl */
|
||||
} IfxDsadc_Dsadc_IntegratorConfig;
|
||||
|
||||
/** \brief Modulator configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxDsadc_InputConfig positiveInput; /**< \brief Modulator configuration of positive input line */
|
||||
IfxDsadc_InputConfig negativeInput; /**< \brief Modulator configuration of negative input line */
|
||||
IfxDsadc_InputGain inputGain; /**< \brief Modulator gain select of analog input path */
|
||||
IfxDsadc_InputPin inputPin; /**< \brief Modulator input pin selection */
|
||||
float32 modulatorClockFreq; /**< \brief Modulator clock frequency */
|
||||
IfxDsadc_CommonModeVoltage commonModeVoltage; /**< \brief Modulator common mode voltage selection */
|
||||
} IfxDsadc_Dsadc_ModulatorConfig;
|
||||
|
||||
/** \brief Rectifier configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean enabled; /**< \brief Rectification enable/disable selection */
|
||||
IfxDsadc_RectifierSignSource signSource; /**< \brief Rectifier sign source */
|
||||
uint8 signDelay; /**< \brief Sign delay value */
|
||||
uint8 signPeriod; /**< \brief Sign period */
|
||||
} IfxDsadc_Dsadc_RectifierConfig;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Dsadc_DataStructures
|
||||
* \{ */
|
||||
/** \brief DSADC handle data structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_DSADC *dsadc; /**< \brief Specifies the pointer to the DSADC module registers */
|
||||
} IfxDsadc_Dsadc;
|
||||
|
||||
/** \brief Carrier generation configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxDsadc_CarrierWaveformMode carrierWaveformMode; /**< \brief Carrier generation mode */
|
||||
boolean inverted; /**< \brief Signal polarity (Normal / Inverted) selection */
|
||||
boolean bitReversed; /**< \brief Bit-Reverse PWM Generation (Normal / Bit reverse mode) selection */
|
||||
float32 frequency; /**< \brief Expected excitation frequency in Hz. */
|
||||
IFX_CONST IfxDsadc_Cgpwm_Out *pinPos; /**< \brief Positive-carrier pin configuration */
|
||||
IFX_CONST IfxDsadc_Cgpwm_Out *pinNeg; /**< \brief Negative-carrier pin configuration */
|
||||
IfxPort_OutputMode pinMode; /**< \brief Carrier pins output mode */
|
||||
IfxPort_PadDriver pinDriver; /**< \brief Carrier pins pad driver */
|
||||
} IfxDsadc_Dsadc_CarrierGenConfig;
|
||||
|
||||
/** \brief Channel handle structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_DSADC *module; /**< \brief Specifies the pointer to the DSADC module registers */
|
||||
Ifx_DSADC_CH *channel; /**< \brief Specifies the pointer to the DSADC channel registers */
|
||||
IfxDsadc_ChannelId channelId; /**< \brief Channel Id */
|
||||
} IfxDsadc_Dsadc_Channel;
|
||||
|
||||
/** \brief Single channel configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_DSADC *module; /**< \brief Specifies the pointer to the DSADC module registers */
|
||||
IfxDsadc_ChannelId channelId; /**< \brief Channel Id */
|
||||
IfxDsadc_Dsadc_ModulatorConfig modulator; /**< \brief Modulator configuration structure */
|
||||
IfxDsadc_Dsadc_DemodulatorConfig demodulator; /**< \brief Demodulator configuration structure */
|
||||
IfxDsadc_Dsadc_CombFilterConfig combFilter; /**< \brief Comb filter configuration structure */
|
||||
IfxDsadc_Dsadc_FirFilterConfig firFilter; /**< \brief FIR filters configuration structure */
|
||||
IfxDsadc_Dsadc_IntegratorConfig integrator; /**< \brief Integrator configuration structure */
|
||||
IfxDsadc_Dsadc_AuxFilterConfig auxFilter; /**< \brief Auxiliary comb filter configuration structure */
|
||||
IfxDsadc_Dsadc_RectifierConfig rectifier; /**< \brief Rectifier configuration structure */
|
||||
IFX_CONST IfxDsadc_Dsadc_ChannelPins *channelPins; /**< \brief Channel Pins Configuration structure */
|
||||
} IfxDsadc_Dsadc_ChannelConfig;
|
||||
|
||||
/** \brief Clock configuration data structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_DSADC *dsadc; /**< \brief Specifies the pointer to the DSADC module registers */
|
||||
IfxDsadc_ModulatorClock modulatorClockSelect; /**< \brief Modulator clock selection */
|
||||
IfxDsadc_LowPowerSupply lowPowerSupply; /**< \brief Low power supply voltage selection */
|
||||
} IfxDsadc_Dsadc_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Dsadc_Module
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialise the DSADC carrier generator
|
||||
* \param dsadc pointer to the DSADC handle (it will be initialized by this function)
|
||||
* \param config pointer to the DSADC carrier configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Dsadc_initCarrierGen(IfxDsadc_Dsadc *dsadc, const IfxDsadc_Dsadc_CarrierGenConfig *config);
|
||||
|
||||
/** \brief Initialise the DSADC with the supplied configuration
|
||||
* \param dsadc pointer to the DSADC handle (it will be initialized by this function)
|
||||
* \param config pointer to the DSADC module configuration
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Dsadc_Dsadc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Dsadc_initModule(IfxDsadc_Dsadc *dsadc, const IfxDsadc_Dsadc_Config *config);
|
||||
|
||||
/** \brief Initialise the config struct with default DSADC configuration
|
||||
* \param config pointer to the DSADC module configuration
|
||||
* \param dsadc base address of the DSADC register space
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Dsadc_Dsadc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Dsadc_initModuleConfig(IfxDsadc_Dsadc_Config *config, Ifx_DSADC *dsadc);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Dsadc_Channel
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialise a DSADC channel with the supplied configuration
|
||||
* \param channel pointer to the DSADC channel handle (it will be initialized by this function)
|
||||
* \param config pointer to the DSADC Channel configuration
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Dsadc_Dsadc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Dsadc_initChannel(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_ChannelConfig *config);
|
||||
|
||||
/** \brief Initialise the config struct with default DSADC channel configuration
|
||||
* \param config pointer to the DSADC Channel configuration (it will be initialized by this function)
|
||||
* \param dsadc pointer to the DSADC handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Dsadc_Dsadc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Dsadc_initChannelConfig(IfxDsadc_Dsadc_ChannelConfig *config, IfxDsadc_Dsadc *dsadc);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Dsadc_Operative
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Enables the conversion of multiple channels
|
||||
* \param dsadc Pointer to the DSADC handle
|
||||
* \param modulatorMask the modulator which should be running (bitwise selection)
|
||||
* \param channelMask the channels which should be scanned (bitwise selection)
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Dsadc_Dsadc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_Dsadc_startScan(IfxDsadc_Dsadc *dsadc, uint32 modulatorMask, uint32 channelMask);
|
||||
|
||||
/** \brief Disables the conversion of multiple channels
|
||||
* \param dsadc Pointer to the DSADC handle
|
||||
* \param modulatorMask the modulator which should be running (bitwise selection)
|
||||
* \return None
|
||||
*
|
||||
* \code
|
||||
* // disable the modulators of all 6 DSADC channels
|
||||
* IfxDsadc_Dsadc_stopScan(&dsadc, 0x3f);
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_Dsadc_stopScan(IfxDsadc_Dsadc *dsadc, uint32 modulatorMask);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Dsadc_Results
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Get result from the main chain
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \return result from the main chain
|
||||
*/
|
||||
IFX_INLINE sint16 IfxDsadc_Dsadc_getMainResult(IfxDsadc_Dsadc_Channel *channel);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Get result from the auxilary chain
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \return result from the auxiliary chain
|
||||
*/
|
||||
IFX_EXTERN sint16 IfxDsadc_Dsadc_getAuxResult(IfxDsadc_Dsadc_Channel *channel);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Dsadc_Interrupt
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Get the interrupt source register for a Aux event
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \return Address/pointer to the interrupt source register
|
||||
*/
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxDsadc_Dsadc_getAuxSrc(IfxDsadc_Dsadc_Channel *channel);
|
||||
|
||||
/** \brief Get the interrupt source register for a Main event
|
||||
* \param channel Pointer to the DSADC channel handle
|
||||
* \return Address/pointer to the interrupt source register
|
||||
*/
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxDsadc_Dsadc_getMainSrc(IfxDsadc_Dsadc_Channel *channel);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* \param config Pointer to DSADC Carrier Configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Dsadc_initCarrierGenConfig(IfxDsadc_Dsadc_CarrierGenConfig *config);
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxDsadc_Dsadc_getAuxSrc(IfxDsadc_Dsadc_Channel *channel)
|
||||
{
|
||||
return IfxDsadc_getAuxSrc(channel->module, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE sint16 IfxDsadc_Dsadc_getMainResult(IfxDsadc_Dsadc_Channel *channel)
|
||||
{
|
||||
return IfxDsadc_getMainResult(channel->module, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxDsadc_Dsadc_getMainSrc(IfxDsadc_Dsadc_Channel *channel)
|
||||
{
|
||||
return IfxDsadc_getMainSrc(channel->module, channel->channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_Dsadc_startScan(IfxDsadc_Dsadc *dsadc, uint32 modulatorMask, uint32 channelMask)
|
||||
{
|
||||
IfxDsadc_startScan(dsadc->dsadc, modulatorMask, channelMask);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_Dsadc_stopScan(IfxDsadc_Dsadc *dsadc, uint32 modulatorMask)
|
||||
{
|
||||
IfxDsadc_stopScan(dsadc->dsadc, modulatorMask);
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXDSADC_DSADC_H */
|
||||
@@ -0,0 +1,572 @@
|
||||
/**
|
||||
* \file IfxDsadc_Rdc.c
|
||||
* \brief DSADC RDC details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxDsadc_Rdc.h"
|
||||
#include "string.h"
|
||||
#include "Gtm/Trig/IfxGtm_Trig.h"
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Rdc_func_config
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* \param gtm Pointer to GTM module registers
|
||||
* \param tim TIM Number
|
||||
* \param timCh TIM Channel Number
|
||||
* \param risingEdge Signal level control
|
||||
*/
|
||||
IFX_STATIC Ifx_GTM_TIM_CH *IfxDsadc_Rdc_initGtmTim(Ifx_GTM *gtm, IfxGtm_Tim tim, IfxGtm_Tim_Ch timCh, boolean risingEdge);
|
||||
|
||||
/** \brief Initialise the DSADC hardware channels
|
||||
* \param driver Driver handle
|
||||
* \param config DSADC RDC configuration structure
|
||||
*/
|
||||
IFX_STATIC boolean IfxDsadc_Rdc_initHwChannels(IfxDsadc_Rdc *driver, const IfxDsadc_Rdc_Config *config);
|
||||
|
||||
/** \brief Initialise the GTM timestamp hardware resources
|
||||
* \param driver Driver handle
|
||||
* \param config DSADC RDC configuration structure
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxDsadc_Rdc_initHwTimestamp(IfxDsadc_Rdc *driver, const IfxDsadc_Rdc_Config *config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Rdc_func_utility
|
||||
* \{ */
|
||||
/******************************************************************************/
|
||||
/*------------------------Inline Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Updating RDC timestamps
|
||||
* \param driver Driver handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_Rdc_updateTimestamp(IfxDsadc_Rdc *driver);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Group Dalay calculation
|
||||
* \param driver Driver handle
|
||||
*/
|
||||
IFX_STATIC float32 IfxDsadc_Rdc_calculateGroupDelay(IfxDsadc_Rdc *driver);
|
||||
|
||||
/**
|
||||
* \param config DSADC RDC configuration structure
|
||||
*/
|
||||
IFX_STATIC float32 IfxDsadc_Rdc_calculateTimestampPeriod(const IfxDsadc_Rdc_Config *config);
|
||||
|
||||
/** \brief Return the update period.
|
||||
* \param driver Driver handle
|
||||
* \return Return the update period in [seconds], i.e. the period of new result (and interrupt)
|
||||
*/
|
||||
IFX_STATIC float32 IfxDsadc_Rdc_getUpdatePeriod(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Rdc_variable
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*------------------------Private Variables/Constants-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief GTM TIM Configuration settings
|
||||
*/
|
||||
IFX_STATIC IFX_CONST Ifx_GTM_TIM_CH_CTRL_Bits IfxDsadc_Rdc_GtmTimCfg = {
|
||||
.TIM_EN = 1,
|
||||
.TIM_MODE = IfxGtm_Tim_Mode_inputEvent,
|
||||
.GPR0_SEL = IfxGtm_Tim_GprSel_tbuTs0,
|
||||
.GPR1_SEL = IfxGtm_Tim_GprSel_tbuTs0,
|
||||
.CNTS_SEL = IfxGtm_Tim_CntsSel_cntReg,
|
||||
/*.EGPR0_SEL= 0, //not available in A-step */
|
||||
.DSL = 0, /* 0 = falling or low */
|
||||
.ISL = 0, /* 1 = both edges, ignore DSL */
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxDsadc_Rdc_updateTimestamp(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
IfxDsadc_Rdc_Ts *timestamp = &driver->timestamp;
|
||||
IfxDsadc_Rdc_Hw *hwHandle = &driver->hardware;
|
||||
|
||||
uint32 tsPwm = hwHandle->pwmTimCh->GPR0.B.GPR0;
|
||||
uint32 clockTicks = (tsPwm - timestamp->rdc) % timestamp->maxTicks;
|
||||
# if IFXDSADC_RDC_CFG_DEBUG
|
||||
timestamp->inTicks = clockTicks;
|
||||
timestamp->pwm = tsPwm;
|
||||
# endif
|
||||
timestamp->inSeconds = timestamp->clockPeriod * (float32)clockTicks;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_STATIC float32 IfxDsadc_Rdc_calculateGroupDelay(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
Ifx_DSADC *dsadc = driver->hardware.inputSin.module;
|
||||
return IfxDsadc_getMainGroupDelay(dsadc, driver->hardware.inputSin.channelId);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC float32 IfxDsadc_Rdc_calculateTimestampPeriod(const IfxDsadc_Rdc_Config *config)
|
||||
{
|
||||
Ifx_GTM *gtm = config->hardware.gtmTimestamp.gtm;
|
||||
return 1.0F / IfxGtm_Tbu_getClockFrequency(gtm, IfxGtm_Tbu_Ts_0);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxDsadc_Rdc_getAbsolutePosition(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getAbsolutePosition(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
IfxStdIf_Pos_Dir IfxDsadc_Rdc_getDirection(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getDirection(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
sint32 IfxDsadc_Rdc_getOffset(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getOffset(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxDsadc_Rdc_getPosition(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getPosition(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxDsadc_Rdc_getRefreshPeriod(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getRefreshPeriod(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
sint32 IfxDsadc_Rdc_getResolution(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getResolution(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
IfxStdIf_Pos_SensorType IfxDsadc_Rdc_getSensorType(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return IfxStdIf_Pos_SensorType_resolver;
|
||||
}
|
||||
|
||||
|
||||
sint32 IfxDsadc_Rdc_getTurn(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getTurn(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC float32 IfxDsadc_Rdc_getUpdatePeriod(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
IfxDsadc_Rdc_Hw *hwHandle = &(driver->hardware);
|
||||
return 1.0F / IfxDsadc_getIntegratorOutFreq(hwHandle->inputSin.module, hwHandle->inputSin.channelId);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxDsadc_Rdc_init(IfxDsadc_Rdc *driver, const IfxDsadc_Rdc_Config *config)
|
||||
{
|
||||
boolean result = TRUE;
|
||||
/* Initialise the DSADC hardware channels */
|
||||
result &= IfxDsadc_Rdc_initHwChannels(driver, config);
|
||||
|
||||
/* Initialise the GTM timestamp hardware resources */
|
||||
IfxDsadc_Rdc_initHwTimestamp(driver, config);
|
||||
|
||||
/* Initialise the software resources */
|
||||
{
|
||||
driver->updatePeriod = IfxDsadc_Rdc_getUpdatePeriod(driver);
|
||||
driver->groupDelay = IfxDsadc_Rdc_calculateGroupDelay(driver);
|
||||
driver->timestamp.enabled = TRUE;
|
||||
driver->timestamp.clockPeriod = IfxDsadc_Rdc_calculateTimestampPeriod(config);
|
||||
driver->timestamp.maxTicks = (uint32)(driver->updatePeriod / driver->timestamp.clockPeriod);
|
||||
}
|
||||
|
||||
/* Initialise angle-tracking observer */
|
||||
{
|
||||
Ifx_AngleTrkF32_Config atoConfig;
|
||||
Ifx_AngleTrkF32_initConfig(&atoConfig, &(driver->sinIn), &(driver->cosIn));
|
||||
|
||||
atoConfig.offset = config->offset;
|
||||
atoConfig.speedLpfFc = config->speedLpfFc;
|
||||
atoConfig.reversed = config->reversed;
|
||||
atoConfig.errorThreshold = config->errorThreshold;
|
||||
atoConfig.sqrAmplMax = config->sqrAmplMax;
|
||||
atoConfig.sqrAmplMin = config->sqrAmplMin;
|
||||
atoConfig.periodPerRotation = config->periodPerRotation;
|
||||
|
||||
atoConfig.kp = config->kp;
|
||||
atoConfig.ki = config->ki;
|
||||
atoConfig.kd = config->kd;
|
||||
atoConfig.resolution = config->resolution;
|
||||
|
||||
#if IFXDSADC_RDC_CFG_PRE_OBSERVER_CORRECTION
|
||||
Ifx_AngleTrkF32_init(&(driver->angleTrk), &atoConfig, config->userTs);
|
||||
#else
|
||||
Ifx_AngleTrkF32_init(&(driver->angleTrk), &atoConfig, driver->updatePeriod);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Optional calibration init */
|
||||
{}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Rdc_initConfig(IfxDsadc_Rdc_Config *config)
|
||||
{
|
||||
config->kp = 0; /* Force to used default from Ifx_AngleTrkF32 */
|
||||
config->ki = 0;
|
||||
config->kd = 0;
|
||||
config->speedLpfFc = 100;
|
||||
config->errorThreshold = 5.0f / 180 * IFX_PI;
|
||||
config->userTs = 0;
|
||||
config->sqrAmplMax = (sint32)((1.01f * 1.01f) * 2048);
|
||||
config->sqrAmplMin = (sint32)((0.99f * 0.99f) * 2048);
|
||||
config->periodPerRotation = 1;
|
||||
config->reversed = FALSE;
|
||||
config->resolution = (1UL << 12); /** \brief 12-bit default resolution */
|
||||
config->offset = 0;
|
||||
IfxDsadc_Dsadc_initCarrierGenConfig(&config->hardware.carrierGen);
|
||||
config->hardware.gtmTimestamp.gtm = &MODULE_GTM;
|
||||
config->hardware.gtmTimestamp.pwmTim = NULL_PTR;
|
||||
config->hardware.gtmTimestamp.rdcTim = IfxGtm_Tim_0;
|
||||
config->hardware.gtmTimestamp.rdcTimChannel = IfxGtm_Tim_Ch_0;
|
||||
config->hardware.gtmTimestamp.rdcTimMuxValue = 0;
|
||||
IfxDsadc_Dsadc_initChannelConfig(&config->hardware.inputConfig, NULL_PTR);
|
||||
config->hardware.inputCos = IfxDsadc_ChannelId_0;
|
||||
|
||||
config->hardware.inputSin = IfxDsadc_ChannelId_2;
|
||||
|
||||
config->hardware.outputClock = NULL_PTR;
|
||||
config->hardware.servReqPriority = 0;
|
||||
config->hardware.servReqProvider = IfxSrc_Tos_cpu0;
|
||||
config->hardware.startScan = FALSE;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC Ifx_GTM_TIM_CH *IfxDsadc_Rdc_initGtmTim(Ifx_GTM *gtm, IfxGtm_Tim tim, IfxGtm_Tim_Ch timCh, boolean risingEdge)
|
||||
{
|
||||
Ifx_GTM_TIM_CH *pTimCh = IfxGtm_Tim_getChannel(>m->TIM[tim], timCh);
|
||||
Ifx_GTM_TIM_CH_CTRL ctrl;
|
||||
ctrl.B = IfxDsadc_Rdc_GtmTimCfg;
|
||||
ctrl.B.DSL = (risingEdge != FALSE) ? 1 : 0;
|
||||
pTimCh->CTRL.U = ctrl.U;
|
||||
return pTimCh;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC boolean IfxDsadc_Rdc_initHwChannels(IfxDsadc_Rdc *driver, const IfxDsadc_Rdc_Config *config)
|
||||
{
|
||||
// #if IFXDSADC_HW_INIT
|
||||
IfxDsadc_Rdc_Hw *hwHandle = &(driver->hardware);
|
||||
const IfxDsadc_Rdc_ConfigHw *configHw = &config->hardware;
|
||||
Ifx_DSADC *module = configHw->inputConfig.module;
|
||||
boolean result = (module != NULL_PTR) ? TRUE : FALSE;
|
||||
|
||||
if (result != FALSE)
|
||||
{
|
||||
/* Initialise input channels */
|
||||
{
|
||||
IfxDsadc_Dsadc_ChannelConfig channelConfig = configHw->inputConfig;
|
||||
channelConfig.channelId = configHw->inputCos;
|
||||
IfxDsadc_Dsadc_initChannel(&hwHandle->inputCos, &channelConfig);
|
||||
|
||||
channelConfig.channelId = configHw->inputSin;
|
||||
IfxDsadc_Dsadc_initChannel(&hwHandle->inputSin, &channelConfig);
|
||||
|
||||
if (configHw->servReqPriority != 0)
|
||||
{
|
||||
IfxDsadc_ChannelId ch = channelConfig.channelId;
|
||||
|
||||
volatile Ifx_SRC_SRCR *srcr;
|
||||
|
||||
if (ch == 0)
|
||||
{
|
||||
srcr = &MODULE_SRC.DSADC.DSADC0.SRM;
|
||||
}
|
||||
|
||||
else if (ch == 2)
|
||||
{
|
||||
srcr = &MODULE_SRC.DSADC.DSADC2.SRM;
|
||||
}
|
||||
|
||||
else if (ch == 3)
|
||||
{
|
||||
srcr = &MODULE_SRC.DSADC.DSADC3.SRM;
|
||||
}
|
||||
|
||||
IfxSrc_init(srcr, configHw->servReqProvider, configHw->servReqPriority);
|
||||
IfxSrc_enable(srcr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialise carrier generator, if necessary */
|
||||
if ((configHw->carrierGen.pinNeg != NULL_PTR) || (configHw->carrierGen.pinPos != NULL_PTR))
|
||||
{
|
||||
IfxDsadc_Dsadc_initCarrierGen(config->dsadc, &configHw->carrierGen);
|
||||
}
|
||||
|
||||
/* Start conversion, if necessary */
|
||||
if (configHw->startScan != FALSE)
|
||||
{
|
||||
IfxDsadc_Rdc_startConversion(driver);
|
||||
}
|
||||
|
||||
/* Initialise modulator clock output, if necessary */
|
||||
if (configHw->outputClock != NULL_PTR)
|
||||
{
|
||||
const IfxPort_Pin *clkPin = &(configHw->outputClock->pin);
|
||||
IfxPort_setPinModeOutput(clkPin->port, clkPin->pinIndex, configHw->carrierGen.pinMode, configHw->outputClock->select);
|
||||
IfxPort_setPinPadDriver(clkPin->port, clkPin->pinIndex, IfxPort_PadDriver_cmosAutomotiveSpeed1);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxDsadc_Rdc_initHwTimestamp(IfxDsadc_Rdc *driver, const IfxDsadc_Rdc_Config *config)
|
||||
{
|
||||
IfxDsadc_Rdc_Hw *hwHandle = &(driver->hardware);
|
||||
const IfxDsadc_Rdc_ConfigHw *configHw = &config->hardware;
|
||||
const IfxDsadc_Rdc_GtmTimestamp *tsConfig = &(configHw->gtmTimestamp);
|
||||
Ifx_GTM *gtm = tsConfig->gtm;
|
||||
|
||||
/** - Initialize TIM channel which is triggered by application's PWM */
|
||||
{
|
||||
boolean risingEdge = (configHw->inputConfig.demodulator.timestampTrigger == IfxDsadc_TimestampTrigger_risingEdge);
|
||||
hwHandle->pwmTimCh = IfxDsadc_Rdc_initGtmTim(gtm, tsConfig->pwmTim->tim, tsConfig->pwmTim->channel, risingEdge);
|
||||
|
||||
/* connect into TIM timer input: */
|
||||
IfxGtm_PinMap_setTimTin(tsConfig->pwmTim, IfxPort_InputMode_undefined);
|
||||
}
|
||||
/** - Initialize TIM channel which is triggered by DSADC sample event */
|
||||
{
|
||||
hwHandle->rdcTimCh = IfxDsadc_Rdc_initGtmTim(gtm, tsConfig->rdcTim, tsConfig->rdcTimChannel, TRUE);
|
||||
|
||||
/** - Connect DSADC trigger to TIM mux */
|
||||
IfxGtm_Trig_fromDsadc(gtm, configHw->inputSin, tsConfig->rdcTim, tsConfig->rdcTimChannel);
|
||||
|
||||
/** - Connect into TIM input */
|
||||
uint32 shift = tsConfig->rdcTimChannel * 4;
|
||||
__ldmst_c(&(gtm->INOUTSEL.TIM[tsConfig->rdcTim].INSEL.U), (0xFU << shift), (tsConfig->rdcTimMuxValue << shift));
|
||||
}
|
||||
IfxGtm_Tbu_enableChannel(gtm, IfxGtm_Tbu_Ts_0);
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Rdc_onEventA(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
driver->timestamp.rdc = driver->hardware.rdcTimCh->GPR0.B.GPR0;
|
||||
|
||||
Ifx_DSADC *dsadc = driver->hardware.inputSin.module;
|
||||
driver->sinIn = IfxDsadc_getMainResult(dsadc, driver->hardware.inputSin.channelId);
|
||||
driver->cosIn = IfxDsadc_getMainResult(dsadc, driver->hardware.inputCos.channelId);
|
||||
/*
|
||||
*/
|
||||
|
||||
#if IFXDSADC_RDC_CFG_PRE_OBSERVER_CORRECTION == 0
|
||||
{
|
||||
sint16 sinIn = driver->sinIn;
|
||||
sint16 cosIn = driver->cosIn;
|
||||
|
||||
/* tracking observer (note: atan2 lookup function is available inside) */
|
||||
Ifx_AngleTrkF32_step(&(driver->angleTrk), sinIn, cosIn, 0);
|
||||
Ifx_AngleTrkF32_updateStatus(&(driver->angleTrk), sinIn, cosIn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Rdc_reset(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
Ifx_AngleTrkF32_reset(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Rdc_resetFaults(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
Ifx_AngleTrkF32_resetFaults(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Rdc_setOffset(IfxDsadc_Rdc *driver, sint32 offset)
|
||||
{
|
||||
Ifx_AngleTrkF32_setOffset(&driver->angleTrk, offset);
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Rdc_setRefreshPeriod(IfxDsadc_Rdc *driver, float32 updatePeriod)
|
||||
{
|
||||
Ifx_AngleTrkF32_setRefreshPeriod(&driver->angleTrk, updatePeriod);
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Rdc_startConversion(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
Ifx_DSADC *module = driver->hardware.inputSin.module;
|
||||
uint32 mask =
|
||||
(1U << driver->hardware.inputCos.channelId) |
|
||||
(1U << driver->hardware.inputSin.channelId);
|
||||
IfxDsadc_startScan(module, mask, mask);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxDsadc_Rdc_stdIfPosInit(IfxStdIf_Pos *stdif, IfxDsadc_Rdc *driver)
|
||||
{
|
||||
/* Ensure the stdif is reset to zeros */
|
||||
memset(stdif, 0, sizeof(IfxStdIf_Pos));
|
||||
|
||||
/* Set the driver */
|
||||
stdif->driver = driver;
|
||||
|
||||
/* *INDENT-OFF* Note: this file was indented manually by the author. */
|
||||
/* Set the API link */
|
||||
stdif->onZeroIrq =(IfxStdIf_Pos_OnZeroIrq )NULL_PTR;
|
||||
stdif->getAbsolutePosition=(IfxStdIf_Pos_GetAbsolutePosition )&IfxDsadc_Rdc_getAbsolutePosition;
|
||||
stdif->getDirection =(IfxStdIf_Pos_GetDirection )&IfxDsadc_Rdc_getDirection;
|
||||
stdif->getFault =(IfxStdIf_Pos_GetFault )&IfxDsadc_Rdc_getFault;
|
||||
stdif->getOffset =(IfxStdIf_Pos_GetOffset )&IfxDsadc_Rdc_getOffset;
|
||||
stdif->getPeriodPerRotation =(IfxStdIf_Pos_GetPeriodPerRotation )&IfxDsadc_Rdc_getPeriodPerRotation;
|
||||
stdif->getPosition =(IfxStdIf_Pos_GetPosition )&IfxDsadc_Rdc_getPosition;
|
||||
stdif->getRawPosition =(IfxStdIf_Pos_GetRawPosition )&IfxDsadc_Rdc_getRawPosition;
|
||||
stdif->getRefreshPeriod =(IfxStdIf_Pos_GetRefreshPeriod )&IfxDsadc_Rdc_getRefreshPeriod;
|
||||
stdif->getResolution =(IfxStdIf_Pos_GetResolution )&IfxDsadc_Rdc_getResolution;
|
||||
stdif->getSensorType =(IfxStdIf_Pos_GetSensorType )&IfxDsadc_Rdc_getSensorType;
|
||||
stdif->reset =(IfxStdIf_Pos_Reset )&IfxDsadc_Rdc_reset;
|
||||
stdif->resetFaults =(IfxStdIf_Pos_ResetFaults )&IfxDsadc_Rdc_resetFaults;
|
||||
stdif->getSpeed =(IfxStdIf_Pos_GetSpeed )&IfxDsadc_Rdc_getSpeed;
|
||||
stdif->update =(IfxStdIf_Pos_Update )&IfxDsadc_Rdc_update;
|
||||
stdif->setPosition =(IfxStdIf_Pos_SetPosition )NULL_PTR;
|
||||
stdif->setRawPosition =(IfxStdIf_Pos_SetRawPosition )NULL_PTR;
|
||||
stdif->setSpeed =(IfxStdIf_Pos_SetSpeed )NULL_PTR;
|
||||
stdif->setOffset =(IfxStdIf_Pos_SetOffset )&IfxDsadc_Rdc_setOffset;
|
||||
stdif->setRefreshPeriod =(IfxStdIf_Pos_SetRefreshPeriod )&IfxDsadc_Rdc_setRefreshPeriod;
|
||||
stdif->getTurn =(IfxStdIf_Pos_GetTurn )&IfxDsadc_Rdc_getTurn;
|
||||
stdif->onEventA =(IfxStdIf_Pos_OnEventA )&IfxDsadc_Rdc_onEventA;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_Rdc_update(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
float32 groupDelayAngle;
|
||||
float32 timeStampAngle;
|
||||
float32 angleOut;
|
||||
float32 speedEst;
|
||||
float32 angleCorrection;
|
||||
|
||||
/* previous estimated speed */
|
||||
speedEst = Ifx_AngleTrkF32_getLoopSpeed(&(driver->angleTrk));
|
||||
|
||||
/* angular component due to group delay */
|
||||
groupDelayAngle = driver->groupDelay * speedEst;
|
||||
|
||||
/* angular component due to time-stamp, if time-stamping is enabled */
|
||||
if (driver->timestamp.enabled != FALSE)
|
||||
{
|
||||
IfxDsadc_Rdc_updateTimestamp(driver);
|
||||
timeStampAngle = IfxDsadc_Rdc_getTimestamp(driver) * speedEst;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeStampAngle = 0;
|
||||
}
|
||||
|
||||
/* angle correction value */
|
||||
angleCorrection = groupDelayAngle + timeStampAngle;
|
||||
|
||||
#if IFXDSADC_RDC_CFG_PRE_OBSERVER_CORRECTION != 0
|
||||
/*
|
||||
* driver->sinIn = (sint16)driver->hardware.inputSin.channel->TSTMP.B.RESULT;
|
||||
* driver->cosIn = (sint16)driver->hardware.inputCos.channel->TSTMP.B.RESULT;
|
||||
*/
|
||||
|
||||
{
|
||||
sint16 sinIn = driver->sinIn;
|
||||
sint16 cosIn = driver->cosIn;
|
||||
|
||||
/* tracking observer (note: atan2 lookup function is available inside) */
|
||||
Ifx_AngleTrkF32_step(&(driver->angleTrk), sinIn, cosIn, angleCorrection);
|
||||
Ifx_AngleTrkF32_updateStatus(&(driver->angleTrk), sinIn, cosIn);
|
||||
}
|
||||
angleOut = driver->angleTrk.angleEst;
|
||||
#else
|
||||
angleOut = driver->angleTrk.angleEst + angleCorrection;
|
||||
#endif
|
||||
|
||||
/* final output estimation */
|
||||
{
|
||||
Ifx_AngleTrkF32_PosIf *base = &(driver->angleTrk).base;
|
||||
IfxStdIf_Pos_RawAngle newPosition = (IfxStdIf_Pos_RawAngle)(angleOut * (base->resolution / 2) / IFX_PI);
|
||||
newPosition = (newPosition + base->offset) & (base->resolution - 1);
|
||||
base->rawPosition = newPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,634 @@
|
||||
/**
|
||||
* \file IfxDsadc_Rdc.h
|
||||
* \brief DSADC RDC details
|
||||
* \ingroup IfxLld_Dsadc
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* Please refer to page \ref page_dsadc_rdc for more details.
|
||||
* This module uses the following modules:
|
||||
* - \ref IfxLld_Dsadc
|
||||
* - \ref library_srvsw_sysse_math_f32_angletrk
|
||||
*
|
||||
*
|
||||
*
|
||||
* Example usage:
|
||||
* Initialisation shall be done by using IfxDsadc_Rdc_init().
|
||||
* \code
|
||||
* IfxDsadc_Rdc rdcHandle;
|
||||
* IfxDsadc_Rdc_Config rdcConfig;
|
||||
*
|
||||
* IfxDsadc_Rdc_initConfig(&rdcConfig);
|
||||
* rdcConfig.hardware.inputConfig.module = &MODULE_DSADC;
|
||||
* IfxDsadc_Rdc_init(&rdcHandle, &rdcConfig);
|
||||
* IfxDsadc_Rdc_startConversion(&rdcHandle);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* After successful initialisation, one DSADC channel may generate interrupt request to CPU.
|
||||
* Function IfxDsadc_Rdc_onEventA() shall be called in the interrupt service routine.
|
||||
*
|
||||
* The function IfxDsadc_Rdc_update() shall be called in the user application's task
|
||||
* or interrupt context for updating the final outputs (position and speed),
|
||||
* (e.g. running inside motor PWM interrupt context)
|
||||
* \name Getting result functions
|
||||
*
|
||||
* \code
|
||||
* { // within context of user's application interrupt or task
|
||||
* extern IfxDsadc_Rdc rdcHandle;
|
||||
*
|
||||
* IfxDsadc_Rdc_update(&rdcHandle); // final update
|
||||
*
|
||||
* IfxStdIf_Pos_RawAngle position = IfxDsadc_Rdc_getRawPosition(&rdcHandle);
|
||||
* StdReal speedRad_s = IfxDsadc_Rdc_getSpeed(&rdcHandle);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Alternatively, the application may use \ref library_srvsw_stdif_posif for accessing the actual results.
|
||||
*
|
||||
* \code
|
||||
* { // within context of user's application interrupt or task
|
||||
* extern IfxDsadc_Rdc rdcHandle;
|
||||
* Ifx_AngleTrkF32_PosIf* posIf = (Ifx_AngleTrkF32_PosIf*)&rdcHandle; // cast is safe because it's located in the same address
|
||||
*
|
||||
* PosIf_update(posIf); // final update, alias of IfxDsadc_Rdc_update()
|
||||
*
|
||||
* elAngle = PosIf_getElAngle(posIf);
|
||||
* elSpeed = PosIf_getElSpeed(posIf);
|
||||
* faultOccurred = PosIf_isFault(posIf);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \note the IfxDsadc_Rdc_update() is implementing the PosIf_update(). Therefore,
|
||||
* only one of them shall be used.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* \page page_dsadc_rdc Resolver-to-digital Converter with DSADC
|
||||
*
|
||||
* \tableofcontents
|
||||
*
|
||||
* One of the popular rotor positioning sensor used by electric motor drive is resolver.
|
||||
* A resolver device modulates carrier signal R1-R2 by the SINE and COSINE function of actual
|
||||
* angle and feeds it back into the controller unit (S1-S3, S2-S6).
|
||||
*
|
||||
* AURIX family provides support for resolver-to-digital converter (RDC) by providing the
|
||||
* following functionalities:
|
||||
* - Carrier generation (DSADC hardware)
|
||||
* - Signal acquisition and carrier cancellation (DSADC hardware)
|
||||
* - Timestamp acquisition (GTM TIM hardware)
|
||||
*
|
||||
* Additionally, the following functionalities are provided by software:
|
||||
* - Angle tracking observer function
|
||||
* - Fault detection
|
||||
*
|
||||
* This page contains concept documentation of the driver software (\ref IfxLld_Dsadc_rdc "DSADC RDC"),
|
||||
* especially implemented in files: IfxDsadc_Rdc.h and IfxDsadc_Rdc.c
|
||||
*
|
||||
* \section sec_dsadc_rdc_cgen Carrier generation
|
||||
*
|
||||
* DSADC hardware supports the generation of resolver excitation carrier by providing PWM
|
||||
* pin outputs which can be simply filtered by low-pass filter circuit to obtain a pair of
|
||||
* differential signal.
|
||||
*
|
||||
* Common configuration of the positive and negative signals are:
|
||||
* - carrier signal frequency
|
||||
* - bit-reversed PWM (optional, but recommended)
|
||||
* - waveform mode: square, triangle, or sinusoidal
|
||||
*
|
||||
* Those configuration are set by IfxDsadc_initCarrierGen() function which is called in the
|
||||
* context of IfxDsadc_Rdc_init() function. Therefore, user only needs to call
|
||||
* IfxDsadc_Rdc_init().
|
||||
*
|
||||
* For each pin output (positive and negative), a low-pass filter and amplifier circuitry
|
||||
* is required to drive a resolver device. Example of such circuitry can be seen in the
|
||||
* figure below.
|
||||
*
|
||||
* TODO: add picture
|
||||
*
|
||||
* \section sec_dsadc_rdc_acq Signal acquisition and carrier cancellation
|
||||
*
|
||||
* Two differential signals are generated from a resolver device (Sin+, Sin-, Cos+, Cos- or
|
||||
* some write also as S1-S3, S2-S6). These signals basically can be connected directly into
|
||||
* the two channels of DSADC, where each DSADC channel has P and N inputs.
|
||||
*
|
||||
* Single DSADC channel and carrier cancelation configuration is done by function
|
||||
* IfxDsadc_initChannel() which is called in the context of IfxDsadc_Rdc_init() function.
|
||||
* Therefore, user only needs to call IfxDsadc_Rdc_init().
|
||||
*
|
||||
* Common configuration items for each DSADC channel are:
|
||||
* - modulator frequency (default: 10MHz)
|
||||
* - CIC filter type (default: COMB3)
|
||||
* - CIC decimation factor (default: 32)
|
||||
* - FIR0 and FIR1 blocks (default: disabled)
|
||||
*
|
||||
* Common configuration items of the carrier cancelation in each DSADC channel are:
|
||||
* - offset compensation block (default: enabled)
|
||||
* - integration count (default: 32)
|
||||
*
|
||||
* With above default values (modulator frequency 10MHz, CIC decimation factor = 32, both FIRs
|
||||
* disabled and integration count = 32), the output sample rate is:
|
||||
* 10MHz / (32 * 32) = ~9.7kHz
|
||||
*
|
||||
* In each acquired sample, interrupt service is requested by the first DSADC channel
|
||||
* initialised by IfxDsadc_Rdc_init(). User's application shall provide an interrupt service
|
||||
* routine (ISR) to handle this request. In the ISR, or an OS task which is synchronised to
|
||||
* the event, user shall call IfxDsadc_Rdc_onEventA() function in order to update all
|
||||
* necessary driver data related to this event.
|
||||
*
|
||||
* \section sec_dsadc_rdc_tstmp Timestamp acquisition
|
||||
*
|
||||
* Typically, user's application run at different sampling rate than DSADC output sampling
|
||||
* rate. For example, motor control PWM interrupt occurs with 10 kHz sampling whereas the
|
||||
* DSADC interrupt runs with ~9.7 kHz. This condition creates situation where the sampled
|
||||
* resolver position is already aged with a few timer ticks, but can be significant to the
|
||||
* motor control algorithm.
|
||||
*
|
||||
* Therefore, timestamp which indicates the elapsed time since last DSADC channel sampling
|
||||
* is required for compensating or computing the missing rotor position. In addition, this
|
||||
* timestamp is also used for compensating the group delay which is inherent property of
|
||||
* DSADC.
|
||||
*
|
||||
* The implementation of timestamp acquisition uses following hardware resources:
|
||||
* - one timebase unit or global timer (free-running), i.e. GTM TBU
|
||||
* - first timer capture unit, to capture the time at the DSADC sample output event, i.e.
|
||||
* using GTM TIM channel
|
||||
* - second timer capture unit, to capture the time at the application sample point (e.g.
|
||||
* PWM event), i.e. using GTM TIM channel.
|
||||
*
|
||||
* Those resources are initialised by IfxDsadc_Rdc_initHwTimestamp() function which is called
|
||||
* in the context of IfxDsadc_Rdc_init() function. Therefore, user **doesn't need** to call
|
||||
* IfxDsadc_Rdc_initHwTimestamp() separately.
|
||||
*
|
||||
* The user shall call IfxDsadc_Rdc_update() function in order to execute:
|
||||
* - timestamp and group delay compensation
|
||||
* - angle tracking observer
|
||||
* - fault-detection
|
||||
*
|
||||
* \section sec_dsadc_rdc_ato Angle tracking observer
|
||||
*
|
||||
* Output samples acquired by DSADC channel and carrier cancelation are the envelope of SINE
|
||||
* and COSINE resolver signals. In principle, ATAN2 function can be used to calculate the
|
||||
* rotor position (angle), but in this driver a \ref library_srvsw_sysse_math_f32_angletrk "Ifx_AngleTrkF32" module is used.
|
||||
*
|
||||
* When user's application calls function IfxDsadc_Rdc_update(), function Ifx_AngleTrkF32_step()
|
||||
* is also called which contains implementation of:
|
||||
* - ATAN2,
|
||||
* - 3rd order angle tracking observer
|
||||
*
|
||||
* The following figure shows the idea:
|
||||
*
|
||||
* TODO: add picture
|
||||
*
|
||||
* ATAN2 function computes the initial angle for the observer. Additional phase is computed
|
||||
* from the timestamp and group delay to compensate 'missing' rotor position (angle).
|
||||
* The combined initial angle and phase are used as reference for the first integrator for
|
||||
* estimating acceleration. The second integrator estimates speed. The final integrator
|
||||
* estimates the output angle.
|
||||
*
|
||||
* The output angle is normally more 'smooth' in steady-state than the angle from ATAN2
|
||||
* function, albeit some settling time and overshoot which occur during transient. The dynamic
|
||||
* performance depends on the gain constants set in the integrators. By default, the constants
|
||||
* are calculated using formula from proceeding's paper
|
||||
* [Design of advanced resolver-to-digital converters](http://www.univ-nantes.fr/servlet/com.univ.collaboratif.utils.LectureFichiergw?CODE_FICHIER=1307605985775&ID_FICHE=1329),
|
||||
* by Auger, et.al, in Electrimacs 2011, CergyPontoise (France), 6-8 june 2011.
|
||||
*
|
||||
* \subsection sec_dsadc_rdc_groupDelay Group delay estimation
|
||||
*
|
||||
* It is shown in previous figure that group delay is required to estimate the actual position
|
||||
* based on the angular speed and measured position.
|
||||
*
|
||||
* The group delay of itself is estimated to be the sum of group delay of components of the
|
||||
* DSADC channel used for acquisition such as CIC filter, FIR0, FIR1, and Integrator blocks.
|
||||
*
|
||||
* The following formulas are used to estimate the group delays:
|
||||
*
|
||||
* <table>
|
||||
* <tr><td>CIC group delay: \f$ \tau_{CIC} = \frac{N.k}{2.F_{mod}} \f$</td></tr>
|
||||
* <tr><td>FIR0 group delay: \f$ \tau_{FIR0} = \frac{7}{2.F_{FIR0_{in}}} \f$</td></tr>
|
||||
* <tr><td>FIR1 group delay: \f$ \tau_{FIR1} = \frac{27}{2.F_{FIR1_{in}}} \f$</td></tr>
|
||||
* <tr><td>Integrator group delay: \f$ \tau_{INT} = \frac{N_{INT}-1}{2.F_{INT_{in}}} \f$</td></tr>
|
||||
* </table>
|
||||
*
|
||||
* The function IfxDsadc_getMainGroupDelay() implements those formulas, invoked by
|
||||
* IfxDsadc_Rdc_update().
|
||||
*
|
||||
* \section sec_dsadc_rdc_fault Fault detection
|
||||
*
|
||||
* When application calls function IfxDsadc_Rdc_update(), fault detection
|
||||
* implemented in \ref library_srvsw_sysse_math_f32_angletrk "Ifx_AngleTrkF32" module is also executed.
|
||||
* The fault-detection is based on simple trigonometry equation:
|
||||
*
|
||||
* \f$ \sin^2(\phi) + \cos^2(\phi) = 1 \f$
|
||||
*
|
||||
* With some tolerance, whenever the amplitude of one of SINE or COSINE signal is outside
|
||||
* the allowed band, then fault flag is set. "SignalLoss" flag is set when the amplitude is
|
||||
* below lower boundary. "SignalDegradation" flag is set when the amplitude is higher than
|
||||
* upper boundary.
|
||||
*
|
||||
* In addition, the flag "TrackingLoss" is set when the internal error value of the angle
|
||||
* tracking observer is above a threshold.
|
||||
*
|
||||
* Functions IfxDsadc_Rdc_getFault() can be used to
|
||||
* check the error flags.
|
||||
*
|
||||
* Configuration of the fault-detection (tolerance) boundary values and threshold are done
|
||||
* by user's call to IfxDsadc_Rdc_init().
|
||||
*
|
||||
* \defgroup IfxLld_Dsadc_Rdc RDC
|
||||
* \ingroup IfxLld_Dsadc
|
||||
* \defgroup IfxLld_Dsadc_Rdc_variable Variables
|
||||
* \ingroup IfxLld_Dsadc_Rdc
|
||||
* \defgroup IfxLld_Dsadc_Rdc_func_config Configuration Functions
|
||||
* \ingroup IfxLld_Dsadc_Rdc
|
||||
* \defgroup IfxLld_Dsadc_Rdc_library_srvsw_sysse_virtualDevice_positionSensor_StdIf_Functions StdIf Functions
|
||||
* \ingroup IfxLld_Dsadc_Rdc
|
||||
* \defgroup IfxLld_Dsadc_Rdc_structures Structures
|
||||
* \ingroup IfxLld_Dsadc_Rdc
|
||||
* \defgroup IfxLld_Dsadc_Rdc_func_utility Utility Functions
|
||||
* \ingroup IfxLld_Dsadc_Rdc
|
||||
*/
|
||||
|
||||
#ifndef IFXDSADC_RDC_H
|
||||
#define IFXDSADC_RDC_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "SysSe/Math/Ifx_AngleTrkF32.h"
|
||||
#include "Dsadc/Dsadc/IfxDsadc_Dsadc.h"
|
||||
#include "Gtm/Std/IfxGtm_Tim.h"
|
||||
#include "_PinMap/IfxGtm_PinMap.h"
|
||||
#include "Ifx_Cfg.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------------Macros-----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef IFXDSADC_RDC_CFG_PRE_OBSERVER_CORRECTION
|
||||
#define IFXDSADC_RDC_CFG_PRE_OBSERVER_CORRECTION (1)
|
||||
#endif
|
||||
|
||||
#ifndef IFXDSADC_RDC_CFG_DEBUG
|
||||
#define IFXDSADC_RDC_CFG_DEBUG (0)
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Rdc_structures
|
||||
* \{ */
|
||||
/** \brief DSADC timestamp helper using GTM
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_GTM *gtm; /**< \brief Pointer to GTM SFRs */
|
||||
IfxGtm_Tim rdcTim;
|
||||
IfxGtm_Tim_Ch rdcTimChannel; /**< \brief TIM channel triggered by DSADC channel */
|
||||
uint32 rdcTimMuxValue; /**< \brief Mux value used */
|
||||
IfxGtm_Tim_TinMap *pwmTim; /**< \brief TIM channel triggered by PWM trigger */
|
||||
} IfxDsadc_Rdc_GtmTimestamp;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Rdc_structures
|
||||
* \{ */
|
||||
/** \brief RDC hardware configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxDsadc_Dsadc_ChannelConfig inputConfig; /**< \brief Default channel configuration for both SIN and COS input. */
|
||||
IfxDsadc_ChannelId inputSin; /**< \brief Channel ID of DSADC used for SIN input. This will override value given in the inputConfig */
|
||||
IfxDsadc_ChannelId inputCos; /**< \brief Channel ID of DSADC used for COS input. This will override value given in the inputConfig */
|
||||
Ifx_Priority servReqPriority; /**< \brief Interrupt priority. NOTE: Only used by inputSin and will override value given in the inputConfig */
|
||||
IfxSrc_Tos servReqProvider; /**< \brief Service provider. NOTE: Only used by inputSin and will override value given in the inputConfig */
|
||||
boolean startScan; /**< \brief Specifies whether the conversion will be started as soon as the IfxDsadc_Rdc_initHw() is called */
|
||||
IfxDsadc_Dsadc_CarrierGenConfig carrierGen; /**< \brief Pointer to the carrier signal generation configuration.
|
||||
* \note If NULL_PTR, it is assumed that the carrier generation has been pre-configured */
|
||||
IfxDsadc_Cout_Out *outputClock; /**< \brief if not NULL_PTR, modulator clock output pin from inputSin channel will be configured */
|
||||
IfxDsadc_Rdc_GtmTimestamp gtmTimestamp; /**< \brief Timestamp helper using GTM */
|
||||
} IfxDsadc_Rdc_ConfigHw;
|
||||
|
||||
/** \brief DSADC RDC hardware object structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxDsadc_Dsadc_Channel inputSin; /**< \brief Handle to SIN input channel */
|
||||
IfxDsadc_Dsadc_Channel inputCos; /**< \brief Handle to COS input channel */
|
||||
Ifx_GTM_TIM_CH *pwmTimCh; /**< \brief TIM channel for PWM timestamp */
|
||||
Ifx_GTM_TIM_CH *rdcTimCh; /**< \brief TIM channel for DSADC timestamp */
|
||||
} IfxDsadc_Rdc_Hw;
|
||||
|
||||
/** \brief
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean enabled;
|
||||
float32 inSeconds;
|
||||
uint32 rdc; /**< \brief Absolute time of DSADC result */
|
||||
uint32 pwm; /**< \brief Absolute time of user's PWM trigger. Used only if IFXDSADC_RDC_CFG_DEBUG is set */
|
||||
sint32 inTicks; /**< \brief Time-stamp of last result (in ticks). Used only if IFXDSADC_RDC_CFG_DEBUG is set */
|
||||
uint32 maxTicks; /**< \brief Maximum time-stamp value (in ticks of absolute time clock) */
|
||||
float32 clockPeriod; /**< \brief Period of absolute time clock (in second) */
|
||||
} IfxDsadc_Rdc_Ts;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Rdc_structures
|
||||
* \{ */
|
||||
/** \brief DSADC RDC data structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_AngleTrkF32 angleTrk;
|
||||
sint16 sinIn;
|
||||
sint16 cosIn;
|
||||
float32 updatePeriod;
|
||||
float32 groupDelay;
|
||||
IfxDsadc_Rdc_Hw hardware;
|
||||
IfxDsadc_Rdc_Ts timestamp;
|
||||
} IfxDsadc_Rdc;
|
||||
|
||||
/** \brief DSADC RDC configuration structure
|
||||
* Note: if ALL kp, ki, kd are zero, then the init function will use default value.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
float32 kp; /**< \brief Observer proportional gain */
|
||||
float32 ki; /**< \brief Observer integral gain */
|
||||
float32 kd; /**< \brief Observer differential gain */
|
||||
float32 speedLpfFc; /**< \brief Cut-off frequency of speed low-pass filter (in Hertz). */
|
||||
float32 errorThreshold; /**< \brief Threshold of error value in the tracking loop (in radian) */
|
||||
float32 userTs; /**< \brief Sampling period of the application */
|
||||
sint32 sqrAmplMax; /**< \brief Maximum value for square of signal amplitudes */
|
||||
sint32 sqrAmplMin; /**< \brief Minimum value for square of signal amplitudes */
|
||||
uint16 periodPerRotation; /**< \brief Number of electrical periods per mechanical rotation */
|
||||
boolean reversed; /**< \brief TRUE: reversed direction, FALSE: straight direction */
|
||||
sint32 resolution; /**< \brief Sensor resolution */
|
||||
IfxStdIf_Pos_RawAngle offset; /**< \brief Offset in ticks. [0 .. (\ref IfxDsadc_Rdc_Config.resolution - 1)] */
|
||||
IfxDsadc_Rdc_ConfigHw hardware; /**< \brief Pointer to hardware config. */
|
||||
IfxDsadc_Dsadc *dsadc; /**< \brief Pointer to the DSADC driver */
|
||||
} IfxDsadc_Rdc_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Rdc_func_config
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialise the DSADC RDC driver by initialising:
|
||||
* - Two DSADC hardware channel resources
|
||||
* - Carrier generation hardware resources
|
||||
* - Time-stamp hardware resources
|
||||
* - Driver's run-time data (RAM): tracking observer, fault-detection, interface layer etc.
|
||||
* \param driver Driver's handle, i.e. pointer to \ref IfxDsadc_Rdc RAM location
|
||||
* \param config Config Pointer to the driver's configuration
|
||||
* \return TRUE in case of success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxDsadc_Rdc_init(IfxDsadc_Rdc *driver, const IfxDsadc_Rdc_Config *config);
|
||||
|
||||
/** \brief
|
||||
* \param config DSADC RDC configuration structure
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Rdc_initConfig(IfxDsadc_Rdc_Config *config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Rdc_library_srvsw_sysse_virtualDevice_positionSensor_StdIf_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetFault
|
||||
* \param driver Driver handle
|
||||
* \return Fault
|
||||
*/
|
||||
IFX_INLINE IfxStdIf_Pos_Status IfxDsadc_Rdc_getFault(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetPeriodPerRotation
|
||||
* \param driver Driver handle
|
||||
* \return Period per rotation
|
||||
*/
|
||||
IFX_INLINE uint16 IfxDsadc_Rdc_getPeriodPerRotation(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetRawPosition
|
||||
* \param driver Driver handle
|
||||
* \return Position in ticks
|
||||
*/
|
||||
IFX_INLINE IfxStdIf_Pos_RawAngle IfxDsadc_Rdc_getRawPosition(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetSpeed
|
||||
* \param driver Driver handle
|
||||
* \return speed
|
||||
*/
|
||||
IFX_INLINE float32 IfxDsadc_Rdc_getSpeed(IfxDsadc_Rdc *driver);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief see IfxStdIf_Pos_GetAbsolutePosition
|
||||
* \param driver Driver handle
|
||||
* \return Absolute position
|
||||
*/
|
||||
IFX_EXTERN float32 IfxDsadc_Rdc_getAbsolutePosition(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetDirection
|
||||
* \param driver Driver handle
|
||||
* \return Direction
|
||||
*/
|
||||
IFX_EXTERN IfxStdIf_Pos_Dir IfxDsadc_Rdc_getDirection(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetOffset
|
||||
* \param driver Driver handle
|
||||
* \return Offset address
|
||||
*/
|
||||
IFX_EXTERN sint32 IfxDsadc_Rdc_getOffset(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetPosition
|
||||
* \param driver Driver handle
|
||||
* \return Position
|
||||
*/
|
||||
IFX_EXTERN float32 IfxDsadc_Rdc_getPosition(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetRefreshPeriod
|
||||
* \param driver driver handle
|
||||
* \return Update period
|
||||
*/
|
||||
IFX_EXTERN float32 IfxDsadc_Rdc_getRefreshPeriod(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetResolution
|
||||
* \param driver Driver handle
|
||||
* \return Resolution
|
||||
*/
|
||||
IFX_EXTERN sint32 IfxDsadc_Rdc_getResolution(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetSensorType
|
||||
* \param driver driver handle
|
||||
* \return Sensor type
|
||||
*/
|
||||
IFX_EXTERN IfxStdIf_Pos_SensorType IfxDsadc_Rdc_getSensorType(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetTurn
|
||||
* \param driver Driver handle
|
||||
* \return Returns the number of turns
|
||||
*/
|
||||
IFX_EXTERN sint32 IfxDsadc_Rdc_getTurn(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_OnEventA
|
||||
* The API handles the event A which corresponds to the DSADC interrupt event.
|
||||
* \param driver Driver's handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Rdc_onEventA(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_Reset
|
||||
* \param driver Driver handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Rdc_reset(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_ResetFaults
|
||||
* \param driver Driver handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Rdc_resetFaults(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_SetOffset
|
||||
* \param driver Driver handle
|
||||
* \param offset Offset
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Rdc_setOffset(IfxDsadc_Rdc *driver, sint32 offset);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_SetRefreshPeriod
|
||||
* \param driver Driver handle
|
||||
* \param updatePeriod Update period
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Rdc_setRefreshPeriod(IfxDsadc_Rdc *driver, float32 updatePeriod);
|
||||
|
||||
/** \brief Initializes the standard interface "Pos"
|
||||
* \param stdif Standard interface position object
|
||||
* \param driver Virtual position sensor
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxDsadc_Rdc_stdIfPosInit(IfxStdIf_Pos *stdif, IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_Update
|
||||
* This function is to be executed at user's application interrupt or task, e.g. motor control
|
||||
* \param driver Driver's handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Rdc_update(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Rdc_func_utility
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Return timestamp in seconds
|
||||
* \param driver Driver handle
|
||||
* \return timestamp in seconds.
|
||||
*/
|
||||
IFX_INLINE float32 IfxDsadc_Rdc_getTimestamp(IfxDsadc_Rdc *driver);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Synchronously start of both DSADC H/W channels
|
||||
* \param driver Driver's handle, i.e. pointer to \ref IfxDsadc_Rdc RAM location
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_Rdc_startConversion(IfxDsadc_Rdc *driver);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE IfxStdIf_Pos_Status IfxDsadc_Rdc_getFault(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getFault(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint16 IfxDsadc_Rdc_getPeriodPerRotation(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getPeriodPerRotation(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE IfxStdIf_Pos_RawAngle IfxDsadc_Rdc_getRawPosition(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getRawPosition(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE float32 IfxDsadc_Rdc_getSpeed(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return Ifx_AngleTrkF32_getSpeed(&driver->angleTrk);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE float32 IfxDsadc_Rdc_getTimestamp(IfxDsadc_Rdc *driver)
|
||||
{
|
||||
return driver->timestamp.inSeconds;
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXDSADC_RDC_H */
|
||||
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* \file IfxDsadc.c
|
||||
* \brief DSADC basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxDsadc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
volatile Ifx_SRC_SRCR *IfxDsadc_getAuxSrc(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel)
|
||||
{
|
||||
return (volatile Ifx_SRC_SRCR *)((uint32)&(MODULE_SRC.DSADC.DSADC0.SRA) + 8 * channel);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxDsadc_getIntegratorOutFreq(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel)
|
||||
{
|
||||
float32 frequency = IfxDsadc_getMainCombOutFreq(dsadc, channel);
|
||||
|
||||
frequency = frequency / ((float32)1.0 + dsadc->CH[channel].IWCTR.B.NVALINT);
|
||||
Ifx_DSADC_CH_FCFGM fcfgm = dsadc->CH[channel].FCFGM;
|
||||
|
||||
if (fcfgm.B.FIR0EN != 0)
|
||||
{
|
||||
frequency = frequency / 2;
|
||||
}
|
||||
|
||||
if (fcfgm.B.FIR1EN != 0)
|
||||
{
|
||||
frequency = frequency / 2;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxDsadc_getMainCombOutFreq(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel)
|
||||
{
|
||||
float32 frequency = IfxDsadc_getModulatorClockFreq(dsadc, channel);
|
||||
|
||||
return frequency / ((float32)1.0 + dsadc->CH[channel].FCFGC.B.CFMDF);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxDsadc_getMainGroupDelay(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel)
|
||||
{
|
||||
Ifx_DSADC_CH_FCFGC fcfgc = dsadc->CH[channel].FCFGC;
|
||||
Ifx_DSADC_CH_FCFGM fcfgm = dsadc->CH[channel].FCFGM;
|
||||
Ifx_DSADC_CH_DICFG dicfg = dsadc->CH[channel].DICFG;
|
||||
Ifx_DSADC_CH_IWCTR iwctr = dsadc->CH[channel].IWCTR;
|
||||
float32 tsMod = 1.0 / IfxDsadc_getModulatorClockFreq(dsadc, channel);
|
||||
float32 tsCic = tsMod * (1 + fcfgc.B.CFMDF);
|
||||
float32 tsFir0 = tsCic * (1 + fcfgm.B.FIR0EN);
|
||||
float32 tsFir1 = tsFir0 * (1 + fcfgm.B.FIR1EN);
|
||||
|
||||
float32 gdDsA = (7 + 1) * tsMod;
|
||||
float32 cicN = (1 + fcfgc.B.CFMDF);
|
||||
float32 cick = (1 + fcfgc.B.CFMC);
|
||||
float32 gdCic = tsMod * ((cick < 4) ? (0.5 * cick * (cicN - 1.0)) : ((2.0 * cicN) - 1.0));
|
||||
float32 gdFir0 = (fcfgm.B.FIR0EN != 0) ? ((3.5 + (3.0 / cicN)) * tsCic) : 0.0;
|
||||
float32 gdFir1;
|
||||
|
||||
if (fcfgm.B.FIR0EN)
|
||||
{
|
||||
gdFir1 = (fcfgm.B.FIR1EN != 0) ? (0.5 * (28.0 + (5.0 / cicN)) * tsFir0) : 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdFir1 = (fcfgm.B.FIR1EN != 0) ? ((28.0 + (5.0 / cicN)) * tsFir0) : 0.0;
|
||||
}
|
||||
|
||||
float32 gdInt = (dicfg.B.ITRMODE == IfxDsadc_IntegratorTrigger_bypassed) ? 0 : ((iwctr.B.NVALINT) * tsFir1);
|
||||
|
||||
return gdDsA + gdCic + gdFir0 + gdFir1 + gdInt;
|
||||
}
|
||||
|
||||
|
||||
volatile Ifx_SRC_SRCR *IfxDsadc_getMainSrc(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel)
|
||||
{
|
||||
return (volatile Ifx_SRC_SRCR *)((uint32)&(MODULE_SRC.DSADC.DSADC0.SRM) + 8 * channel);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxDsadc_getModulatorClockFreq(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel)
|
||||
{
|
||||
float32 sourceFreq = IfxDsadc_getModulatorInputClockFreq(dsadc);
|
||||
|
||||
return sourceFreq / ((dsadc->CH[channel].MODCFG.B.DIVM + 1) * 2);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxDsadc_getModulatorInputClockFreq(Ifx_DSADC *dsadc)
|
||||
{
|
||||
float32 result;
|
||||
|
||||
switch (dsadc->GLOBCFG.B.MCSEL)
|
||||
{
|
||||
case IfxDsadc_ModulatorClock_fOSC0:
|
||||
result = IfxScuCcu_getOsc0Frequency();
|
||||
break;
|
||||
case IfxDsadc_ModulatorClock_fERAY:
|
||||
result = IfxScuCcu_getPllErayFrequency();
|
||||
break;
|
||||
case IfxDsadc_ModulatorClock_fDSD:
|
||||
result = IfxScuCcu_getSpbFrequency();
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxDsadc_resetModule(Ifx_DSADC *dsadc)
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
dsadc->KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
|
||||
dsadc->KRST1.B.RST = 1;
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
|
||||
while (0 == dsadc->KRST0.B.RSTSTAT) /* Wait until reset is executed */
|
||||
|
||||
{}
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
dsadc->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
}
|
||||
@@ -0,0 +1,760 @@
|
||||
/**
|
||||
* \file IfxDsadc.h
|
||||
* \brief DSADC basic functionality
|
||||
* \ingroup IfxLld_Dsadc
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Dsadc_Std_Enum Enumerations
|
||||
* \ingroup IfxLld_Dsadc_Std
|
||||
* \defgroup IfxLld_Dsadc_Std_Operative Operative Functions
|
||||
* \ingroup IfxLld_Dsadc_Std
|
||||
* \defgroup IfxLld_Dsadc_Std_Support Support Functions
|
||||
* \ingroup IfxLld_Dsadc_Std
|
||||
* \defgroup IfxLld_Dsadc_Std_Interrupt Interrupt Functions
|
||||
* \ingroup IfxLld_Dsadc_Std
|
||||
* \defgroup IfxLld_Dsadc_Std_IO IO Pin Configuration Functions
|
||||
* \ingroup IfxLld_Dsadc_Std
|
||||
*/
|
||||
|
||||
#ifndef IFXDSADC_H
|
||||
#define IFXDSADC_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxDsadc_cfg.h"
|
||||
#include "Src/Std/IfxSrc.h"
|
||||
#include "Scu/Std/IfxScuCcu.h"
|
||||
#include "_PinMap/IfxDsadc_PinMap.h"
|
||||
#include "IfxDsadc_reg.h"
|
||||
#include "Cpu/Std/IfxCpu_Intrinsics.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Std_Enum
|
||||
* \{ */
|
||||
/** \brief Comb Filter (auxiliary) shift control\n
|
||||
* Definition in Ifx_DSADC.FCFGA.B.AFSC
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_AuxCombFilterShift_noShift = 0, /**< \brief no shift, use full range */
|
||||
IfxDsadc_AuxCombFilterShift_shiftBy1 = 1, /**< \brief Shift by 1 */
|
||||
IfxDsadc_AuxCombFilterShift_shiftBy2 = 2, /**< \brief Shift by 2 */
|
||||
IfxDsadc_AuxCombFilterShift_shiftBy3 = 3 /**< \brief Shift by 3 */
|
||||
} IfxDsadc_AuxCombFilterShift;
|
||||
|
||||
/** \brief Comb Filter (auxiliary) configuration/type\n
|
||||
* Definition in Ifx_DSADC.FCFGA.B.CFAC
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_AuxCombFilterType_comb1 = 0, /**< \brief CIC1 */
|
||||
IfxDsadc_AuxCombFilterType_comb2 = 1, /**< \brief CIC2 */
|
||||
IfxDsadc_AuxCombFilterType_comb3 = 2, /**< \brief CIC3 */
|
||||
IfxDsadc_AuxCombFilterType_combF = 3 /**< \brief CICF */
|
||||
} IfxDsadc_AuxCombFilterType;
|
||||
|
||||
/** \brief Service request generation (auxiliary)\n
|
||||
* Definition in Ifx_DSADC.FCFGA.B.ESEL
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_AuxEvent_everyNewResult = 0, /**< \brief Always, for each new result value */
|
||||
IfxDsadc_AuxEvent_insideBoundary = 1, /**< \brief If result is inside the boundary band */
|
||||
IfxDsadc_AuxEvent_outsideBoundary = 2 /**< \brief If result is outside the boundary band */
|
||||
} IfxDsadc_AuxEvent;
|
||||
|
||||
/** \brief Service request generation (auxiliary)\n
|
||||
* Definition in Ifx_DSADC.FCFGA.B.EGT
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_AuxGate_definedByESEL = 0, /**< \brief Separate: generate events according to ESEL */
|
||||
IfxDsadc_AuxGate_coupledToIntegrator = 1 /**< \brief Coupled: generate events only when the integrator is enabled and after the discard phase defined by bitfield NVALDIS */
|
||||
} IfxDsadc_AuxGate;
|
||||
|
||||
/** \brief Service request generation (auxiliary)\n
|
||||
* Definition in Ifx_DSADC.FCFGA.B.SRGA
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_AuxServiceRequest_never = 0, /**< \brief Never, service requests disabled */
|
||||
IfxDsadc_AuxServiceRequest_auxFilter = 1, /**< \brief Auxiliary filter: As selected by bitfield ESEL (\ref IfxDsadc_AuxEvent) */
|
||||
IfxDsadc_AuxServiceRequest_altSource = 2 /**< \brief Alternate source: Capturing of a sign delay value to register CGSYNCx (x = 0 - 5) */
|
||||
} IfxDsadc_AuxServiceRequest;
|
||||
|
||||
/** \brief Carrier generation mode\n
|
||||
* Definition in Ifx_DSADC.CGCFG.B.CGMOD
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_CarrierWaveformMode_stopped = 0, /**< \brief Carrier Generator stopped */
|
||||
IfxDsadc_CarrierWaveformMode_square = 1, /**< \brief Carrier Generator generates square wave */
|
||||
IfxDsadc_CarrierWaveformMode_triangle = 2, /**< \brief Carrier Generator generates triangle wave */
|
||||
IfxDsadc_CarrierWaveformMode_sine = 3 /**< \brief Carrier Generator generates sine wave */
|
||||
} IfxDsadc_CarrierWaveformMode;
|
||||
|
||||
/** \brief Specifies the channel Index
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_ChannelId_0 = 0, /**< \brief Specifies the channel Index 0 */
|
||||
IfxDsadc_ChannelId_2 = 2, /**< \brief Specifies the channel Index 2 */
|
||||
IfxDsadc_ChannelId_3 = 3 /**< \brief Specifies the channel Index 3 */
|
||||
} IfxDsadc_ChannelId;
|
||||
|
||||
/** \brief Modulator common mode voltage selection\n
|
||||
* Definition in Ifx_DSADC.MODCFGx.B.CMVS
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_CommonModeVoltage_a = 0, /**< \brief VCM = VAREF / 3.03 (1.65 V for VAREF = 5.0 V), recommended for VDDM = 3.3 V1.65V */
|
||||
IfxDsadc_CommonModeVoltage_b = 1, /**< \brief VCM = VAREF / 2.27 (2.2 V for VAREF = 5.0 V), recommended for low distortion of AC-coupled signals */
|
||||
IfxDsadc_CommonModeVoltage_c = 2 /**< \brief VCM = VAREF / 2.0 (2.5 V for VAREF = 5.0 V), recommended for DC-coupled signals */
|
||||
} IfxDsadc_CommonModeVoltage;
|
||||
|
||||
/** \brief FIR data shift control\n
|
||||
* Selects the displacement caused by the data shifter at the FIR filter output\n
|
||||
* Definition in Ifx_DSADC.FCFGM.B.DSH
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_FirDataShift_noShift = 0, /**< \brief no shift, use full range */
|
||||
IfxDsadc_FirDataShift_shiftBy1 = 1, /**< \brief Shift by 1 */
|
||||
IfxDsadc_FirDataShift_shiftBy2 = 2, /**< \brief Shift by 2 */
|
||||
IfxDsadc_FirDataShift_shiftBy3 = 3 /**< \brief Shift by 3 */
|
||||
} IfxDsadc_FirDataShift;
|
||||
|
||||
/** \brief FIR shift control\n
|
||||
* Selects the displacement caused by the data shifter inbetween the FIR filter blocks.\n
|
||||
* Definition in Ifx_DSADC.FCFGM.B.FSH
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_FirInternalShift_noShift = 0, /**< \brief no shift, use full range */
|
||||
IfxDsadc_FirInternalShift_shiftBy1 = 1 /**< \brief Shift by 1 */
|
||||
} IfxDsadc_FirInternalShift;
|
||||
|
||||
/** \brief Modulator configuration of positive/negative input line\n
|
||||
* Definition in Ifx_DSADC.MODCFGx.B.INCFGP and Ifx_DSADC.MODCFGx.B.INCFGN
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_InputConfig_inputPin = 0, /**< \brief Modulator input connected to external pin */
|
||||
IfxDsadc_InputConfig_supplyVoltage = 1, /**< \brief Modulator input connected to supply voltage V_ddm */
|
||||
IfxDsadc_InputConfig_commonModeVoltage = 2, /**< \brief Modulator input connected to common mode voltage V_cm */
|
||||
IfxDsadc_InputConfig_referenceGround = 3 /**< \brief Modulator input connected to reference ground V_ref */
|
||||
} IfxDsadc_InputConfig;
|
||||
|
||||
/** \brief Demodulator input data source selection\n
|
||||
* Definition in Ifx_DSADC.DICFG.B.DSRC
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_InputDataSource_onChipStandAlone = 0, /**< \brief On-chip modulator, standalone (3rd order) */
|
||||
IfxDsadc_InputDataSource_onChipCombined = 1, /**< \brief On-chip modulator, yield (2nd order) */
|
||||
IfxDsadc_InputDataSource_directInputA = 2, /**< \brief External, from input A, direct */
|
||||
IfxDsadc_InputDataSource_invertedInputA = 3, /**< \brief External, from input A, inverted */
|
||||
IfxDsadc_InputDataSource_directInputB = 4, /**< \brief External, from input B, direct */
|
||||
IfxDsadc_InputDataSource_invertedInputB = 5 /**< \brief External, from input B, inverted */
|
||||
} IfxDsadc_InputDataSource;
|
||||
|
||||
/** \brief Modulator gain select of analog input path\n
|
||||
* Definition in Ifx_DSADC.MODCFGx.B.GAINSEL
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_InputGain_factor1 = 0, /**< \brief Input gain factor: 1 */
|
||||
IfxDsadc_InputGain_factor2 = 1, /**< \brief Input gain factor: 2 */
|
||||
IfxDsadc_InputGain_factor4 = 2, /**< \brief Input gain factor: 4 */
|
||||
IfxDsadc_InputGain_factor8 = 3, /**< \brief Input gain factor: 8 */
|
||||
IfxDsadc_InputGain_factor16 = 4 /**< \brief Input gain factor: 16 */
|
||||
} IfxDsadc_InputGain;
|
||||
|
||||
/** \brief Modulator input pin selection\n
|
||||
* Definition in Ifx_DSADC.MODCFGx.B.INMUX
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_InputPin_a = 0, /**< \brief Pin A connected to modulator input */
|
||||
IfxDsadc_InputPin_b = 1, /**< \brief Pin B connected to modulator input */
|
||||
IfxDsadc_InputPin_c = 2, /**< \brief Pin C connected to modulator input */
|
||||
IfxDsadc_InputPin_d = 3 /**< \brief Pin D connected to modulator input */
|
||||
} IfxDsadc_InputPin;
|
||||
|
||||
/** \brief Integrator window size\n
|
||||
* Definition in Ifx_DSADC.IWCTR.B.IWS
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_IntegrationWindowSize_internalControl = 0, /**< \brief Internal control: stop integrator after REPVAL+1 integration cycles */
|
||||
IfxDsadc_IntegrationWindowSize_externalControl = 1 /**< \brief External control: stop integrator when bit INTEN becomes 0 */
|
||||
} IfxDsadc_IntegrationWindowSize;
|
||||
|
||||
/** \brief Integrator trigger mode\n
|
||||
* NOTE: switch-first to bypassed before using other mode\n
|
||||
* Definition in Ifx_DSADC.DICFG.B.ITRMODE
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_IntegratorTrigger_bypassed = 0, /**< \brief No integration trigger, integrator bypassed */
|
||||
IfxDsadc_IntegratorTrigger_fallingEdge = 1, /**< \brief Trigger event upon a falling edge */
|
||||
IfxDsadc_IntegratorTrigger_risingEdge = 2, /**< \brief Trigger event upon a rising edge */
|
||||
IfxDsadc_IntegratorTrigger_alwaysActive = 3 /**< \brief No trigger, integrator active all the time */
|
||||
} IfxDsadc_IntegratorTrigger;
|
||||
|
||||
/** \brief Low power supply voltage select\n
|
||||
* Definition in Ifx_DSADC.GLOBCFG.B.LOSUP
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_LowPowerSupply_5V = 0, /**< \brief Supply Voltage for Analog Circuitry set to 5V */
|
||||
IfxDsadc_LowPowerSupply_3_3V = 1 /**< \brief Supply Voltage for Analog Circuitry set to 3.3V */
|
||||
} IfxDsadc_LowPowerSupply;
|
||||
|
||||
/** \brief Comb Filter (Main Chain) shift control\n
|
||||
* Definition in Ifx_DSADC.FCFGC.B.MFSC
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_MainCombFilterShift_noShift = 0, /**< \brief no shift, use full range */
|
||||
IfxDsadc_MainCombFilterShift_shiftBy1 = 1, /**< \brief Shift by 1 */
|
||||
IfxDsadc_MainCombFilterShift_shiftBy2 = 2, /**< \brief Shift by 2 */
|
||||
IfxDsadc_MainCombFilterShift_shiftBy3 = 3 /**< \brief Shift by 3 */
|
||||
} IfxDsadc_MainCombFilterShift;
|
||||
|
||||
/** \brief Comb Filter (Main Chain) configuration/type\n
|
||||
* Definition in Ifx_DSADC.FCFGC.B.CFMC
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_MainCombFilterType_comb1 = 0, /**< \brief CIC1 */
|
||||
IfxDsadc_MainCombFilterType_comb2 = 1, /**< \brief CIC2 */
|
||||
IfxDsadc_MainCombFilterType_comb3 = 2, /**< \brief CIC3 */
|
||||
IfxDsadc_MainCombFilterType_combF = 3 /**< \brief CICF */
|
||||
} IfxDsadc_MainCombFilterType;
|
||||
|
||||
/** \brief Service request generation (main chain)\n
|
||||
* Definition in Ifx_DSADC.FCFGC.B.SRGM
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_MainServiceRequest_never = 0, /**< \brief Never, service requests disabled */
|
||||
IfxDsadc_MainServiceRequest_highGateSignal = 1, /**< \brief While gate (selected trigger signal) is high */
|
||||
IfxDsadc_MainServiceRequest_lowGateSignal = 2, /**< \brief While gate (selected trigger signal) is low */
|
||||
IfxDsadc_MainServiceRequest_everyNewResult = 3 /**< \brief Always, for each new result value */
|
||||
} IfxDsadc_MainServiceRequest;
|
||||
|
||||
/** \brief Modulator clock select\n
|
||||
* Definition in Ifx_DSADC.GLOBCFG.B.MCSEL
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_ModulatorClock_off = 0, /**< \brief Internal clock off, no source selected */
|
||||
IfxDsadc_ModulatorClock_fDSD = 1, /**< \brief f_dsd clock selected */
|
||||
IfxDsadc_ModulatorClock_fERAY = 2, /**< \brief f_eray clock selected */
|
||||
IfxDsadc_ModulatorClock_fOSC0 = 3 /**< \brief f_osc0 clock selected */
|
||||
} IfxDsadc_ModulatorClock;
|
||||
|
||||
/** \brief Modulator divider factor for modulator clock\n
|
||||
* Definition in Ifx_DSADC.MODCFGx.B.DIVM
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_ModulatorClockDivider_div2 = 0, /**< \brief f_mod = f_clk / 2 */
|
||||
IfxDsadc_ModulatorClockDivider_div4, /**< \brief f_mod = f_clk / 4 */
|
||||
IfxDsadc_ModulatorClockDivider_div6, /**< \brief f_mod = f_clk / 6 */
|
||||
IfxDsadc_ModulatorClockDivider_div8, /**< \brief f_mod = f_clk / 8 */
|
||||
IfxDsadc_ModulatorClockDivider_div10, /**< \brief f_mod = f_clk / 10 */
|
||||
IfxDsadc_ModulatorClockDivider_div12, /**< \brief f_mod = f_clk / 12 */
|
||||
IfxDsadc_ModulatorClockDivider_div14, /**< \brief f_mod = f_clk / 14 */
|
||||
IfxDsadc_ModulatorClockDivider_div16, /**< \brief f_mod = f_clk / 16 */
|
||||
IfxDsadc_ModulatorClockDivider_div18, /**< \brief f_mod = f_clk / 18 */
|
||||
IfxDsadc_ModulatorClockDivider_div20, /**< \brief f_mod = f_clk / 20 */
|
||||
IfxDsadc_ModulatorClockDivider_div22, /**< \brief f_mod = f_clk / 22 */
|
||||
IfxDsadc_ModulatorClockDivider_div24, /**< \brief f_mod = f_clk / 24 */
|
||||
IfxDsadc_ModulatorClockDivider_div26, /**< \brief f_mod = f_clk / 26 */
|
||||
IfxDsadc_ModulatorClockDivider_div28, /**< \brief f_mod = f_clk / 28 */
|
||||
IfxDsadc_ModulatorClockDivider_div30, /**< \brief f_mod = f_clk / 30 */
|
||||
IfxDsadc_ModulatorClockDivider_div32 /**< \brief f_mod = f_clk / 32 */
|
||||
} IfxDsadc_ModulatorClockDivider;
|
||||
|
||||
/** \brief Rectifier sign source\n
|
||||
* Selects the sign signal that is to be delayed.\n
|
||||
* Definition in Ifx_DSADC.RECT.B.SSRC
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_RectifierSignSource_onChipGenerator = 0, /**< \brief On-chip carrier generator */
|
||||
IfxDsadc_RectifierSignSource_nextChannel = 1, /**< \brief Sign of result of next channel */
|
||||
IfxDsadc_RectifierSignSource_externalA = 2, /**< \brief External sign signal A */
|
||||
IfxDsadc_RectifierSignSource_externalB = 3 /**< \brief External sign signal B */
|
||||
} IfxDsadc_RectifierSignSource;
|
||||
|
||||
/** \brief Demodulator sample clock source select\n
|
||||
* Definition in Ifx_DSADC.DICFG.B.CSRC
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_SampleClockSource_internal = 0, /**< \brief Internal clock */
|
||||
IfxDsadc_SampleClockSource_inputA = 1, /**< \brief External clock, from Input A */
|
||||
IfxDsadc_SampleClockSource_inputB = 2, /**< \brief External clock, from Input B */
|
||||
IfxDsadc_SampleClockSource_inputC = 3 /**< \brief External clock, from Input C */
|
||||
} IfxDsadc_SampleClockSource;
|
||||
|
||||
/** \brief Demodulator data strobe generation mode\n
|
||||
* Definition in Ifx_DSADC.DICFG.B.STROBE
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_SampleStrobe_noDataStrobe = 0, /**< \brief No data strobe */
|
||||
IfxDsadc_SampleStrobe_sampleOnRisingEdge = 1, /**< \brief Direct clock, a sample trigger is generated at each rising clock edge */
|
||||
IfxDsadc_SampleStrobe_sampleOnFallingEdge = 2, /**< \brief Direct clock, a sample trigger is generated at each falling clock edge */
|
||||
IfxDsadc_SampleStrobe_sampleOnBothEdges = 3, /**< \brief Double data, a sample trigger is generated at each rising and falling clock edge */
|
||||
IfxDsadc_SampleStrobe_reserved = 4, /**< \brief don't use */
|
||||
IfxDsadc_SampleStrobe_sampleOnTwoRisingEdges = 5, /**< \brief Double clock, a sample trigger is generated at every 2nd rising clock edge */
|
||||
IfxDsadc_SampleStrobe_sampleOnTwoFallingEdges = 6 /**< \brief Double clock, a sample trigger is generated at every 2nd falling clock edge */
|
||||
} IfxDsadc_SampleStrobe;
|
||||
|
||||
/** \brief Enable/disable the sensitivity of the module to sleep signal\n
|
||||
* Definition in Ifx_DSADC.CLC.B.EDIS
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_SleepMode_enable = 0, /**< \brief enables sleep mode */
|
||||
IfxDsadc_SleepMode_disable = 1 /**< \brief disables sleep mode */
|
||||
} IfxDsadc_SleepMode;
|
||||
|
||||
/** \brief Timestamp trigger mode\n
|
||||
* Definition in Ifx_DSADC.DICFG.B.TSTRMODE
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_TimestampTrigger_noTrigger = 0, /**< \brief No timestamp trigger */
|
||||
IfxDsadc_TimestampTrigger_fallingEdge = 1, /**< \brief Trigger event upon a falling edge */
|
||||
IfxDsadc_TimestampTrigger_risingEdge = 2, /**< \brief Trigger event upon a rising edge */
|
||||
IfxDsadc_TimestampTrigger_eachEdge = 3 /**< \brief Trigger event upon each edge */
|
||||
} IfxDsadc_TimestampTrigger;
|
||||
|
||||
/** \brief Trigger select\n
|
||||
* Definition in Ifx_DSADC.DICFG.B.TRSEL
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxDsadc_TriggerInput_a = 0, /**< \brief dsadc trig 0 */
|
||||
IfxDsadc_TriggerInput_b = 1, /**< \brief dsadc trig 1 */
|
||||
IfxDsadc_TriggerInput_c = 2, /**< \brief vadc trig 0 */
|
||||
IfxDsadc_TriggerInput_d = 3, /**< \brief vadc trig 1 */
|
||||
IfxDsadc_TriggerInput_e = 4, /**< \brief external pin e */
|
||||
IfxDsadc_TriggerInput_f = 5, /**< \brief external pin f */
|
||||
IfxDsadc_TriggerInput_g = 6,
|
||||
IfxDsadc_TriggerInput_h = 7
|
||||
} IfxDsadc_TriggerInput;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Std_Operative
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Sets the sensitivity of the module to sleep signal
|
||||
* \param dsadc pointer to DSADC registers
|
||||
* \param mode mode selection (enable/disable)
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_setSleepMode(Ifx_DSADC *dsadc, IfxDsadc_SleepMode mode);
|
||||
|
||||
/** \brief Enables the conversion of multiple channels
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param modulatorMask the modulator which should be running (bitwise selection)
|
||||
* \param channelMask the channels which should be scanned (bitwise selection)
|
||||
* \return None
|
||||
*
|
||||
* \code
|
||||
* // enable the conversion of all 6 DSADC channels
|
||||
* IfxDsadc_startScan(&MODULE_DSADC, 0x3FU, 0x3FU);
|
||||
* // results are now available in IFXDSADC(ds).CH[x].RESM.B.RESULT (x=0..5)
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_startScan(Ifx_DSADC *dsadc, uint32 modulatorMask, uint32 channelMask);
|
||||
|
||||
/** \brief Disables the conversion of multiple channels
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param modulatorMask the modulator which should be disabled (bitwise selection)
|
||||
* \return None
|
||||
*
|
||||
* \code
|
||||
* // disable the modulators of all 6 DSADC channels
|
||||
* IfxDsadc_stopScan(&MODULE_DSADC, 0x3FU);
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_stopScan(Ifx_DSADC *dsadc, uint32 modulatorMask);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief resets the DSADC kernel
|
||||
* \param dsadc pointer to DSADC registers
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxDsadc_resetModule(Ifx_DSADC *dsadc);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Std_Support
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Get result from the auxiliary chain
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param channel Channel Id
|
||||
* \return result from the auxiliary chain
|
||||
*/
|
||||
IFX_INLINE sint16 IfxDsadc_getAuxResult(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel);
|
||||
|
||||
/** \brief Get the main comb decimation factor
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param channel Channel Id
|
||||
* \return the main comb decimation factor
|
||||
*/
|
||||
IFX_INLINE uint16 IfxDsadc_getMainCombDecimation(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel);
|
||||
|
||||
/** \brief Get result from the main chain
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param channel Channel Id
|
||||
* \return result from the main chain
|
||||
*/
|
||||
IFX_INLINE sint16 IfxDsadc_getMainResult(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel);
|
||||
|
||||
/** \brief Return TRUE if DSADC module is enabled
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \return TRUE if DSADC module is enabled
|
||||
*/
|
||||
IFX_INLINE boolean IfxDsadc_isModuleEnabled(Ifx_DSADC *dsadc);
|
||||
|
||||
/** \brief Set the carrier waveform mode
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param waveformMode the waveform mode
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_setCarrierMode(Ifx_DSADC *dsadc, IfxDsadc_CarrierWaveformMode waveformMode);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Get the sample frequency of the integrator output in Hz
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param channel Channel Id
|
||||
* \return frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxDsadc_getIntegratorOutFreq(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel);
|
||||
|
||||
/** \brief Get the sample frequency of the main COMB filter output in Hz
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param channel Channel Id
|
||||
* \return frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxDsadc_getMainCombOutFreq(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel);
|
||||
|
||||
/** \brief Estimate the group delay of main-chain filters in seconds
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param channel Channel Id
|
||||
* \return delay in seconds
|
||||
*/
|
||||
IFX_EXTERN float32 IfxDsadc_getMainGroupDelay(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel);
|
||||
|
||||
/** \brief Get the modulator clock frequency in Hz
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param channel Channel Id
|
||||
* \return frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxDsadc_getModulatorClockFreq(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel);
|
||||
|
||||
/** \brief Get the input frequency of DSADC in Hz
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \return frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxDsadc_getModulatorInputClockFreq(Ifx_DSADC *dsadc);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Std_Interrupt
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Address/pointer to the interrupt source register
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param channel Channel Id
|
||||
* \return Address/pointer to the interrupt source register
|
||||
*/
|
||||
IFX_EXTERN volatile Ifx_SRC_SRCR *IfxDsadc_getAuxSrc(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel);
|
||||
|
||||
/** \brief Get the interrupt source register for a Main event
|
||||
* \param dsadc Pointer to the DSADC register space
|
||||
* \param channel Channel Id
|
||||
* \return Address/pointer to the interrupt source register
|
||||
*/
|
||||
IFX_EXTERN volatile Ifx_SRC_SRCR *IfxDsadc_getMainSrc(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dsadc_Std_IO
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initializes a CGPWM output
|
||||
* \param cgPwm the CGPWM Pin which should be configured
|
||||
* \param pinMode the pin output mode which should be configured
|
||||
* \param padDriver the pad driver mode which should be configured
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_initCgPwmPin(const IfxDsadc_Cgpwm_Out *cgPwm, IfxPort_OutputMode pinMode, IfxPort_PadDriver padDriver);
|
||||
|
||||
/** \brief Initializes a CIN input
|
||||
* \param cIn the CIN Pin which should be configured
|
||||
* \param cInMode the pin input mode which should be configured
|
||||
* \param padDriver Pad Driver Configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_initCinPin(const IfxDsadc_Cin_In *cIn, IfxPort_InputMode cInMode, IfxPort_PadDriver padDriver);
|
||||
|
||||
/** \brief Initializes a COUT output
|
||||
* \param cout the COUT Pin which should be configured
|
||||
* \param pinMode the pin output mode which should be configured
|
||||
* \param padDriver the pad driver mode which should be configured
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_initCoutPin(const IfxDsadc_Cout_Out *cout, IfxPort_OutputMode pinMode, IfxPort_PadDriver padDriver);
|
||||
|
||||
/** \brief Initializes a DIN input
|
||||
* \param dIn the DIN Pin which should be configured
|
||||
* \param dInMode the pin input mode which should be configured
|
||||
* \param padDriver Pad Driver Configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_initDinPin(const IfxDsadc_Din_In *dIn, IfxPort_InputMode dInMode, IfxPort_PadDriver padDriver);
|
||||
|
||||
/** \brief Initializes a DS input
|
||||
* \param dsn the DSN Pin which should be configured
|
||||
* \param pinMode the pin input mode which should be configured
|
||||
* \param padDriver Pad Driver Configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_initDsnPin(const IfxDsadc_Dsn_In *dsn, IfxPort_InputMode pinMode, IfxPort_PadDriver padDriver);
|
||||
|
||||
/** \brief Initializes a DS input
|
||||
* \param dsp the DSP Pin which should be configured
|
||||
* \param pinMode the pin input mode which should be configured
|
||||
* \param padDriver Pad Driver Configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_initDspPin(const IfxDsadc_Dsp_In *dsp, IfxPort_InputMode pinMode, IfxPort_PadDriver padDriver);
|
||||
|
||||
/** \brief Initializes a ITR input
|
||||
* \param itr the ITR Pin which should be configured
|
||||
* \param itrMode the pin input mode which should be configured
|
||||
* \param padDriver Pad Driver Configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_initItrPin(const IfxDsadc_Itr_In *itr, IfxPort_InputMode itrMode, IfxPort_PadDriver padDriver);
|
||||
|
||||
/** \brief Initializes a SG input
|
||||
* \param sg the SG Pin which should be configured
|
||||
* \param pinMode the pin input mode which should be configured
|
||||
* \param padDriver Pad Driver Configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDsadc_initSgPin(const IfxDsadc_Sg_In *sg, IfxPort_InputMode pinMode, IfxPort_PadDriver padDriver);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE sint16 IfxDsadc_getAuxResult(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel)
|
||||
{
|
||||
return (sint16)(dsadc->CH[channel].RESA.B.RESULT);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint16 IfxDsadc_getMainCombDecimation(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel)
|
||||
{
|
||||
return (uint16)(1U + dsadc->CH[channel].FCFGC.B.CFMDF);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE sint16 IfxDsadc_getMainResult(Ifx_DSADC *dsadc, IfxDsadc_ChannelId channel)
|
||||
{
|
||||
return (sint16)(dsadc->CH[channel].RESM.B.RESULT);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_initCgPwmPin(const IfxDsadc_Cgpwm_Out *cgPwm, IfxPort_OutputMode pinMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
IfxPort_setPinModeOutput(cgPwm->pin.port, cgPwm->pin.pinIndex, pinMode, cgPwm->select);
|
||||
IfxPort_setPinPadDriver(cgPwm->pin.port, cgPwm->pin.pinIndex, padDriver);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_initCinPin(const IfxDsadc_Cin_In *cIn, IfxPort_InputMode cInMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
if (cIn->pin.port != NULL_PTR)
|
||||
{
|
||||
IfxPort_setPinModeInput(cIn->pin.port, cIn->pin.pinIndex, cInMode);
|
||||
IfxPort_setPinPadDriver(cIn->pin.port, cIn->pin.pinIndex, padDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_initCoutPin(const IfxDsadc_Cout_Out *cout, IfxPort_OutputMode pinMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
if (cout->pin.port != NULL_PTR)
|
||||
{
|
||||
IfxPort_setPinModeOutput(cout->pin.port, cout->pin.pinIndex, pinMode, cout->select);
|
||||
IfxPort_setPinPadDriver(cout->pin.port, cout->pin.pinIndex, padDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_initDinPin(const IfxDsadc_Din_In *dIn, IfxPort_InputMode dInMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
if (dIn->pin.port != NULL_PTR)
|
||||
{
|
||||
IfxPort_setPinModeInput(dIn->pin.port, dIn->pin.pinIndex, dInMode);
|
||||
IfxPort_setPinPadDriver(dIn->pin.port, dIn->pin.pinIndex, padDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_initDsnPin(const IfxDsadc_Dsn_In *dsn, IfxPort_InputMode pinMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
if (dsn->pin.port != NULL_PTR)
|
||||
{
|
||||
IfxPort_setPinModeInput(dsn->pin.port, dsn->pin.pinIndex, pinMode);
|
||||
IfxPort_setPinPadDriver(dsn->pin.port, dsn->pin.pinIndex, padDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_initDspPin(const IfxDsadc_Dsp_In *dsp, IfxPort_InputMode pinMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
if (dsp->pin.port != NULL_PTR)
|
||||
{
|
||||
IfxPort_setPinModeInput(dsp->pin.port, dsp->pin.pinIndex, pinMode);
|
||||
IfxPort_setPinPadDriver(dsp->pin.port, dsp->pin.pinIndex, padDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_initItrPin(const IfxDsadc_Itr_In *itr, IfxPort_InputMode itrMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
if (itr->pin.port != NULL_PTR)
|
||||
{
|
||||
IfxPort_setPinModeInput(itr->pin.port, itr->pin.pinIndex, itrMode);
|
||||
IfxPort_setPinPadDriver(itr->pin.port, itr->pin.pinIndex, padDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_initSgPin(const IfxDsadc_Sg_In *sg, IfxPort_InputMode pinMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
if (sg->pin.port != NULL_PTR)
|
||||
{
|
||||
IfxPort_setPinModeInput(sg->pin.port, sg->pin.pinIndex, pinMode);
|
||||
IfxPort_setPinPadDriver(sg->pin.port, sg->pin.pinIndex, padDriver);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxDsadc_isModuleEnabled(Ifx_DSADC *dsadc)
|
||||
{
|
||||
return dsadc->CLC.B.DISS == 0;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_setCarrierMode(Ifx_DSADC *dsadc, IfxDsadc_CarrierWaveformMode waveformMode)
|
||||
{
|
||||
dsadc->CGCFG.B.CGMOD = waveformMode;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_setSleepMode(Ifx_DSADC *dsadc, IfxDsadc_SleepMode mode)
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
dsadc->CLC.B.EDIS = mode;
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_startScan(Ifx_DSADC *dsadc, uint32 modulatorMask, uint32 channelMask)
|
||||
{
|
||||
dsadc->GLOBRC.U = dsadc->GLOBRC.U | ((modulatorMask << 16) | (channelMask));
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDsadc_stopScan(Ifx_DSADC *dsadc, uint32 modulatorMask)
|
||||
{
|
||||
dsadc->GLOBRC.U &= ~(modulatorMask << 16);
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXDSADC_H */
|
||||
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* \file IfxDts_Dts.c
|
||||
* \brief DTS DTS details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxDts_Dts.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint16 IfxDts_Dts_convertFromCelsius(float32 temperatureValue)
|
||||
{
|
||||
sint32 dtsValue = (sint32)(temperatureValue + 285.5) / 0.467;
|
||||
|
||||
if (dtsValue < 0)
|
||||
{
|
||||
dtsValue = 0;
|
||||
}
|
||||
else if (dtsValue > 1023)
|
||||
{
|
||||
dtsValue = 1023;
|
||||
}
|
||||
|
||||
return (uint16)dtsValue;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxDts_Dts_convertToCelsius(uint16 dtsValue)
|
||||
{
|
||||
return ((float32)dtsValue * 0.467) - 285.5;
|
||||
}
|
||||
|
||||
|
||||
void IfxDts_Dts_initModule(const IfxDts_Dts_Config *config)
|
||||
{
|
||||
IfxDts_enableSensor();
|
||||
|
||||
/* wait for two measurements before enabling the limits */
|
||||
{
|
||||
int i;
|
||||
|
||||
/* disable limits */
|
||||
MODULE_SCU.DTSLIM.B.LOWER = 0;
|
||||
MODULE_SCU.DTSLIM.B.UPPER = 1023;
|
||||
|
||||
/* wait until DTS is ready */
|
||||
while (!IfxDts_isReady())
|
||||
{}
|
||||
|
||||
/* two dummy measurements */
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
IfxDts_Dts_startSensor();
|
||||
|
||||
while (IfxDts_Dts_isBusy())
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
/* change to the requested limits */
|
||||
MODULE_SCU.DTSLIM.B.LOWER = IfxDts_Dts_convertFromCelsius(config->lowerTemperatureLimit);
|
||||
MODULE_SCU.DTSLIM.B.UPPER = IfxDts_Dts_convertFromCelsius(config->upperTemperatureLimit);
|
||||
|
||||
/* lock configuration? */
|
||||
if (config->enableSecureLock == TRUE)
|
||||
{
|
||||
IfxDts_disableSensorControl();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* do Nothing */
|
||||
}
|
||||
|
||||
/* enable DTS IRQ */
|
||||
if (config->isrPriority > 0)
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxDts_getSrcPointer();
|
||||
IfxSrc_init(src, config->isrTypeOfService, config->isrPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxDts_Dts_initModuleConfig(IfxDts_Dts_Config *config)
|
||||
{
|
||||
config->sensorControlDisabled = FALSE;
|
||||
config->lowerTemperatureLimit = -40.0; // Celsius
|
||||
config->upperTemperatureLimit = 170.0; // Celsius
|
||||
|
||||
config->isrTypeOfService = IfxSrc_Tos_cpu0;
|
||||
config->isrPriority = 0;
|
||||
|
||||
config->enableSecureLock = FALSE;
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/**
|
||||
* \file IfxDts_Dts.h
|
||||
* \brief DTS DTS details
|
||||
* \ingroup IfxLld_Dts
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Dts_Dts_Usage How to use the DTS Interface driver?
|
||||
* \ingroup IfxLld_Dts
|
||||
*
|
||||
* DTS gives the die-temperature result which will decoded to standard temperature value. Minimum first two temperature results are to be ignored to get reliable temperature.
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
* \section IfxLld_Dts_Dts_Preparation Preparation
|
||||
* \subsection IfxLld_Dts_Dts_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
*
|
||||
* \code
|
||||
* #include <Dts/Dts/IfxDts_Dts.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Dts_Dts_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priorities for the Interrrupt handler. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define IFX_INTPRIO_DTS 1
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routine to your C code which should do the error flag handling:
|
||||
* \code
|
||||
* IFX_INTERRUPT(dtsISR, 0, IFX_INTPRIO_DTS)
|
||||
* {
|
||||
* // DTS finished temperature measurement
|
||||
*
|
||||
* uint16 temperatureValue = IfxDts_Dts_getTemperatureValue();
|
||||
* // here we could do something with the value...
|
||||
* // and the DTS can be restarted
|
||||
* IfxDts_Dts_startSensor();
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handler in your initialisation function:
|
||||
* \code
|
||||
* // install interrupt handler
|
||||
* IfxCpu_Irq_installInterruptHandler(&dtsISR, IFX_INTPRIO_DTS);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Dts_Dts_Module DTS Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function:
|
||||
* \code
|
||||
* // Get the default configuration
|
||||
* IfxDts_Dts_Config dtsConfig;
|
||||
* IfxDts_Dts_initModuleConfig(&dtsConfig);
|
||||
*
|
||||
* // Adapt the default configuration if required
|
||||
* dtsConfig.isrPriority = IFX_INTPRIO_DTS;
|
||||
* dtsConfig.isrTypeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());
|
||||
* dtsConfig.lowerTemperatureLimit = -35; // SMU alarm if temperature value is below this Celsius value
|
||||
* dtsConfig.upperTemperatureLimit = 150; // SMU alarm if temperature value is above this Celsius value
|
||||
*
|
||||
* // Module initialisation
|
||||
* IfxDts_Dts_initModule(&dtsConfig);
|
||||
* \endcode
|
||||
* Now, DTS is initialised for starting temperature measurements:
|
||||
* \code
|
||||
* IfxDts_Dts_startSensor();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Dts_Dts_IrqBased IRQ based measurements
|
||||
*
|
||||
* Whenever the interrupt handler is called, a new measurment result is available and could be processed further (e.g. for statistical analysis).
|
||||
*
|
||||
* \code
|
||||
* IFX_INTERRUPT(dtsISR, 0, IFX_INTPRIO_DTS)
|
||||
* {
|
||||
* // DTS finished temperature measurement
|
||||
*
|
||||
* uint16 temperatureValue = IfxDts_Dts_getTemperatureValue();
|
||||
* // here we could do something with the value...
|
||||
* // and the DTS can be restarted
|
||||
* IfxDts_Dts_startSensor();
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Dts_Dts_NonIrqBased Measurements without IRQs
|
||||
*
|
||||
* If no interrupt routine should be used, a new measurement result can be requested the following way:
|
||||
*
|
||||
* \code
|
||||
* // start Sensor
|
||||
* IfxDts_Dts_startSensor();
|
||||
*
|
||||
* // wait until a new result is available
|
||||
* while( IfxDts_Dts_isBusy() );
|
||||
* uint16 temperatureValue = IfxDts_Dts_getTemperatureValue();
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* Alternatively (and this is the normal usage), the DTS could be periodically started from a timer routine, e.g. each mS. The conversion itself takes 100 uS maximum.
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Dts_Dts_Converted Temperature conversion
|
||||
*
|
||||
* Following function returns the actual temperature in Celsius:
|
||||
*
|
||||
* \code
|
||||
* float32 temperature = IfxDts_Dts_getTemperatureCelsius();
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Dts_Dts DTS
|
||||
* \ingroup IfxLld_Dts
|
||||
* \defgroup IfxLld_Dts_Dts_Structures Data Structures
|
||||
* \ingroup IfxLld_Dts_Dts
|
||||
* \defgroup IfxLld_Dts_Dts_Module Module Initialisation functions
|
||||
* \ingroup IfxLld_Dts_Dts
|
||||
* \defgroup IfxLld_Dts_Dts_Sensor Sensor Functions
|
||||
* \ingroup IfxLld_Dts_Dts
|
||||
* \defgroup IfxLld_Dts_Dts_Conversion Conversion Functions
|
||||
* \ingroup IfxLld_Dts_Dts
|
||||
*/
|
||||
|
||||
#ifndef IFXDTS_DTS_H
|
||||
#define IFXDTS_DTS_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Dts/Std/IfxDts.h"
|
||||
#include "Cpu/Std/IfxCpu.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Dts_Dts_Structures
|
||||
* \{ */
|
||||
/** \brief DTS module configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean sensorControlDisabled; /**< \brief MODULE_SCU.DTSCON.SCLK, specifies the control register lock except MODULE_SCU.DTSCON.START. */
|
||||
float32 lowerTemperatureLimit; /**< \brief Specifies the lower temperature limit compared against die temperature in Celsius
|
||||
*
|
||||
* A SMU will be triggered if the measurement result is below this limit */
|
||||
float32 upperTemperatureLimit; /**< \brief Specifies the upper temperature limit compared against die temperature in Celsius.
|
||||
*
|
||||
* A SMU will be triggered if the measurement result is above this limit */
|
||||
uint16 isrPriority; /**< \brief interrupt priority */
|
||||
IfxSrc_Tos isrTypeOfService; /**< \brief type of interrupt service */
|
||||
boolean enableSecureLock; /**< \brief MODULE_SCU.DTSCON.SLCK,MODULE_SCU.DTSLIM.SLCK, Specifies the Security Lock for Configuration and Limitation register. */
|
||||
} IfxDts_Dts_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dts_Dts_Module
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialise the DTS with supplied configuration.
|
||||
* \param config pointer to module configuration structure
|
||||
* \return None
|
||||
*
|
||||
* Usage Example : \ref IfxLld_Dts_Dts_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDts_Dts_initModule(const IfxDts_Dts_Config *config);
|
||||
|
||||
/** \brief Intialises the module configuration buffer with default configuration.
|
||||
* \param config pointer to module configuration structure
|
||||
* \return None
|
||||
*
|
||||
* Usage Example : \ref IfxLld_Dts_Dts_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxDts_Dts_initModuleConfig(IfxDts_Dts_Config *config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dts_Dts_Sensor
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the converted temperature in Celsius
|
||||
* \return The temperature based on the DTS temperature value
|
||||
*
|
||||
* Usage Example : \ref IfxLld_Dts_Dts_Usage
|
||||
*
|
||||
*/
|
||||
IFX_INLINE float32 IfxDts_Dts_getTemperatureCelsius(void);
|
||||
|
||||
/** \brief Returns the unconverted temperature measurement result
|
||||
* \return current sensor measured result.
|
||||
*
|
||||
* Usage Example : \ref IfxLld_Dts_Dts_Usage
|
||||
*
|
||||
*/
|
||||
IFX_INLINE uint16 IfxDts_Dts_getTemperatureValue(void);
|
||||
|
||||
/** \brief Returns the current BUSY status of the Sensor
|
||||
* \return TRUE if Sensor is busy in measuring temperature otherwise FALSE
|
||||
*
|
||||
* Usage Example : \ref IfxLld_Dts_Dts_Usage
|
||||
*
|
||||
*/
|
||||
IFX_INLINE boolean IfxDts_Dts_isBusy(void);
|
||||
|
||||
/** \brief Starts the next temperature measurement.
|
||||
* \return None
|
||||
*
|
||||
* Usage Example : \ref IfxLld_Dts_Dts_Usage
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxDts_Dts_startSensor(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dts_Dts_Conversion
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Converts a temperature value in Celsius to DTS value
|
||||
* \param temperatureValue the temperature in Celsius
|
||||
* \return the appr. DTS value
|
||||
*/
|
||||
IFX_EXTERN uint16 IfxDts_Dts_convertFromCelsius(float32 temperatureValue);
|
||||
|
||||
/** \brief Converts the measurement value returned from DTS to Celsius
|
||||
* \param dtsValue measurement value returned from DTS
|
||||
* \return temperature in Celsius
|
||||
*/
|
||||
IFX_EXTERN float32 IfxDts_Dts_convertToCelsius(uint16 dtsValue);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE float32 IfxDts_Dts_getTemperatureCelsius(void)
|
||||
{
|
||||
return IfxDts_Dts_convertToCelsius(IfxDts_getTemperatureValue());
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint16 IfxDts_Dts_getTemperatureValue(void)
|
||||
{
|
||||
return (uint16)IfxDts_getTemperatureValue();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxDts_Dts_isBusy(void)
|
||||
{
|
||||
return IfxDts_isBusy();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDts_Dts_startSensor(void)
|
||||
{
|
||||
/* start sensor */
|
||||
IfxDts_startSensor();
|
||||
|
||||
/* one dummy read to a SCU register which ensures that the BUSY flag is synchronized
|
||||
* into the status register before IfxDts_Dts_isBusy() is called */
|
||||
if (IfxDts_isBusy())
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXDTS_DTS_H */
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* \file IfxDts.c
|
||||
* \brief DTS basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxDts.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
boolean IfxDts_isReady(void)
|
||||
{
|
||||
return MODULE_SCU.DTSSTAT.B.RDY == 1 ? TRUE : FALSE;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* \file IfxDts.h
|
||||
* \brief DTS basic functionality
|
||||
* \ingroup IfxLld_Dts
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Dts_Std_Control Control functions
|
||||
* \ingroup IfxLld_Dts_Std
|
||||
* \defgroup IfxLld_Dts_Std_Status Status functions
|
||||
* \ingroup IfxLld_Dts_Std
|
||||
*/
|
||||
|
||||
#ifndef IFXDTS_H
|
||||
#define IFXDTS_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxDts_cfg.h"
|
||||
#include "IfxScu_reg.h"
|
||||
#include "IfxScu_bf.h"
|
||||
#include "Cpu/Std/IfxCpu_Intrinsics.h"
|
||||
#include "Src/Std/IfxSrc.h"
|
||||
/** \addtogroup IfxLld_Dts_Std_Control
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Disable the writing of register bits except START bit.
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDts_disableSensorControl(void);
|
||||
|
||||
/** \brief Enables the DTS sensor
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDts_enableSensor(void);
|
||||
|
||||
/** \brief Starts the next temperature measurement.
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxDts_startSensor(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Dts_Std_Status
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Gets the Interrupt request source.
|
||||
* \return Address of interrupt request source
|
||||
*/
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxDts_getSrcPointer(void);
|
||||
|
||||
/** \brief Read the temperature measurement result
|
||||
* \return Temperature measurement result
|
||||
*/
|
||||
IFX_INLINE uint16 IfxDts_getTemperatureValue(void);
|
||||
|
||||
/** \brief Returns the current BUSY status of the Sensor
|
||||
* \return TRUE if Sensor is busy in measuring temperature otherwise FALSE
|
||||
*/
|
||||
IFX_INLINE boolean IfxDts_isBusy(void);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the current READY status of the Sensor.
|
||||
* \return TRUE if Sensor is ready for measuring temperature otherwise FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxDts_isReady(void);
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxDts_disableSensorControl(void)
|
||||
{
|
||||
MODULE_SCU.DTSCON.B.SLCK = 1;
|
||||
MODULE_SCU.DTSLIM.B.SLCK = 1;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDts_enableSensor(void)
|
||||
{
|
||||
MODULE_SCU.DTSCON.B.PWD = 0;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxDts_getSrcPointer(void)
|
||||
{
|
||||
return &SRC_SCUDTS;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint16 IfxDts_getTemperatureValue(void)
|
||||
{
|
||||
return (uint16)MODULE_SCU.DTSSTAT.B.RESULT;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxDts_isBusy(void)
|
||||
{
|
||||
return MODULE_SCU.DTSSTAT.B.BUSY == 1 ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxDts_startSensor(void)
|
||||
{
|
||||
MODULE_SCU.DTSCON.B.START = 1;
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXDTS_H */
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* \file IfxEmem.c
|
||||
* \brief EMEM basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxEmem.h"
|
||||
#include "Cpu/Std/IfxCpu_Intrinsics.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IfxEmem_LockedState IfxEmem_getLockedState(void)
|
||||
{
|
||||
return (IfxEmem_LockedState)MODULE_EMEM.SBRCTR.B.STBLOCK;
|
||||
}
|
||||
|
||||
|
||||
void IfxEmem_setClockEnableState(const IfxEmem_State state)
|
||||
{
|
||||
/* bit is inverted */
|
||||
if (IfxEmem_State_enabled == state)
|
||||
{
|
||||
MODULE_EMEM.CLC.B.DISR = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
MODULE_EMEM.CLC.B.DISR = 1;
|
||||
}
|
||||
|
||||
/* wait one cycle for module to be enabled */
|
||||
__nop();
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* \file IfxEmem.h
|
||||
* \brief EMEM basic functionality
|
||||
* \ingroup IfxLld_Emem
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Emem_Std_Enumerations Enumerations
|
||||
* \ingroup IfxLld_Emem_Std
|
||||
* \defgroup IfxLld_Emem_Std_Module Module Functions
|
||||
* \ingroup IfxLld_Emem_Std
|
||||
*/
|
||||
|
||||
#ifndef IFXEMEM_H
|
||||
#define IFXEMEM_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxEmem_cfg.h"
|
||||
#include "Scu/Std/IfxScuWdt.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Emem_Std_Enumerations
|
||||
* \{ */
|
||||
/** \brief EMEM lock state defined in MODULE_EMEM.SBRCTR.B.STBLOCK.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxEmem_LockedState_locked = 0, /**< \brief EMEM locked state. */
|
||||
IfxEmem_LockedState_unlocked = 1 /**< \brief EMEM unlocked state. */
|
||||
} IfxEmem_LockedState;
|
||||
|
||||
/** \brief EMEM module clock enabled or disabled state defined in MODULE_EMEM.CLC.B.DISR.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxEmem_State_disabled = 0, /**< \brief EMEM module clock disabled state. */
|
||||
IfxEmem_State_enabled = 1 /**< \brief EMEM module clock enabled state. */
|
||||
} IfxEmem_State;
|
||||
|
||||
/** \brief EMEM tile configuration mode defined in MODULE_EMEM.TILECONFIG.B.Tx( x = 0,1,..).
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxEmem_TileConfigMode_calibMode = 0 /**< \brief EMEM tile mode to calibration memory. */
|
||||
} IfxEmem_TileConfigMode;
|
||||
|
||||
/** \brief Tile Number
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxEmem_TileNumber_0 = 0, /**< \brief Tile Number0 */
|
||||
IfxEmem_TileNumber_1, /**< \brief Tile Number1 */
|
||||
IfxEmem_TileNumber_2, /**< \brief Tile Number2 */
|
||||
IfxEmem_TileNumber_3, /**< \brief Tile Number3 */
|
||||
IfxEmem_TileNumber_4, /**< \brief Tile Number4 */
|
||||
IfxEmem_TileNumber_5, /**< \brief Tile Number5 */
|
||||
IfxEmem_TileNumber_6, /**< \brief Tile Number6 */
|
||||
IfxEmem_TileNumber_7, /**< \brief Tile Number7 */
|
||||
IfxEmem_TileNumber_8, /**< \brief Tile Number8 */
|
||||
IfxEmem_TileNumber_9, /**< \brief Tile Number9 */
|
||||
IfxEmem_TileNumber_10, /**< \brief Tile Number10 */
|
||||
IfxEmem_TileNumber_11, /**< \brief Tile Number11 */
|
||||
IfxEmem_TileNumber_12, /**< \brief Tile Number12 */
|
||||
IfxEmem_TileNumber_13, /**< \brief Tile Number13 */
|
||||
IfxEmem_TileNumber_14, /**< \brief Tile Number14 */
|
||||
IfxEmem_TileNumber_15 /**< \brief Tile Number15 */
|
||||
} IfxEmem_TileNumber;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Emem_Std_Module
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the status of module enabled or disabled
|
||||
* \return Status (TRUE / FALSE)
|
||||
*/
|
||||
IFX_INLINE boolean IfxEmem_isModuleEnabled(void);
|
||||
|
||||
/** \brief Sets all EMEM tiles to calibration memory mode.
|
||||
* \param mode EMEM tile configuration mode.
|
||||
* \param tile tile number
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxEmem_setTileConfigMode(const IfxEmem_TileConfigMode mode, IfxEmem_TileNumber tile);
|
||||
|
||||
/** \brief Sets Unlock standby lock flag.
|
||||
* \param flag Unlock standby lock flag value.
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxEmem_setUnlockStandbyLockFlag(const uint8 flag);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Gets the EMEM stand RAM lock state.
|
||||
* \return EMEM stand RAM lock state.
|
||||
*/
|
||||
IFX_EXTERN IfxEmem_LockedState IfxEmem_getLockedState(void);
|
||||
|
||||
/** \brief Sets state of the EMEM module clock.
|
||||
* Note: Do not use this API for enabling and disabling EMEM without handling Endinit protection in application.
|
||||
* for complete enable and disable of EMEM with endint protection handling, please use the following APIs
|
||||
* /ref IfxEmem_enableModule
|
||||
* /ref IfxEmem_disableModule
|
||||
* \param state EMEM module clock enabled or disabled state.
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxEmem_setClockEnableState(const IfxEmem_State state);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE boolean IfxEmem_isModuleEnabled(void)
|
||||
{
|
||||
return (MODULE_EMEM.CLC.B.DISS == 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxEmem_setTileConfigMode(const IfxEmem_TileConfigMode mode, IfxEmem_TileNumber tile)
|
||||
{
|
||||
uint32 shift = tile * 2;
|
||||
uint32 mask = ~(0x3 << shift);
|
||||
uint32 value = (uint32)mode << shift;
|
||||
MODULE_EMEM.TILECONFIG.U = (MODULE_EMEM.TILESTATE.U & mask) | value;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxEmem_setUnlockStandbyLockFlag(const uint8 flag)
|
||||
{
|
||||
if (8 > flag)
|
||||
{
|
||||
MODULE_EMEM.SBRCTR.B.STBULK = flag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXEMEM_H */
|
||||
@@ -0,0 +1,609 @@
|
||||
/**
|
||||
* \file IfxEray_Eray.c
|
||||
* \brief ERAY ERAY details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxEray_Eray.h"
|
||||
#include "Mtu/Std/IfxMtu.h"
|
||||
|
||||
/** \addtogroup IfxLld_Eray_Eray_Node
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Inialises the communication controller.
|
||||
* \param eray pointer to ERAY Module handle.
|
||||
* \param config pointer to communication controller config structure.
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxEray_Eray_Node_initCommunicationController(IfxEray_Eray *eray, const IfxEray_Eray_ControllerConfig *config);
|
||||
|
||||
/** \brief Initialises the Global Timing Unit.
|
||||
* \param eray pointer to ERAY Module handle.
|
||||
* \param config global timing unit Configuration structure.
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxEray_Eray_Node_initGTU(IfxEray_Eray *eray, const IfxEray_Eray_GTUConfig *config);
|
||||
|
||||
/** \brief Inialises the message RAM.
|
||||
* \param eray pointer to ERAY Module handle.
|
||||
* \param config pointer to message RAM config structure.
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxEray_Eray_Node_initMessageRAM(IfxEray_Eray *eray, const IfxEray_Eray_MessageRAMConfig *config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxEray_Eray_Node_init(IfxEray_Eray *eray, const IfxEray_Eray_NodeConfig *config)
|
||||
{
|
||||
Ifx_ERAY *eraySFR = eray->eray;
|
||||
// clear all the flags
|
||||
IfxEray_clearAllFlags(eraySFR);
|
||||
|
||||
// set Communication Controller to config state
|
||||
if (IfxEray_getPocState(eraySFR) != IfxEray_PocState_config)
|
||||
{
|
||||
IfxEray_changePocState(eraySFR, IfxEray_PocCommand_freeze);
|
||||
IfxEray_waitForPocState(eraySFR, IfxEray_PocState_halt);
|
||||
IfxEray_changePocState(eraySFR, IfxEray_PocCommand_config);
|
||||
IfxEray_waitForPocState(eraySFR, IfxEray_PocState_defaultConfig);
|
||||
IfxEray_changePocState(eraySFR, IfxEray_PocCommand_config);
|
||||
IfxEray_waitForPocState(eraySFR, IfxEray_PocState_config);
|
||||
}
|
||||
|
||||
// enable interrupt lines
|
||||
IfxEray_enableInterruptLines(eraySFR);
|
||||
IfxEray_setAutoDelayBuffers(eraySFR);
|
||||
//configure message RAM ( slots and slot buffers )
|
||||
IfxEray_Eray_Node_initMessageRAM(eray, &config->messageRAMConfig);
|
||||
//configure communication controller for clock corrections
|
||||
IfxEray_Eray_Node_initCommunicationController(eray, &config->controllerConfig);
|
||||
// initialise the Node pins.
|
||||
const IfxEray_Eray_Pins *pins = config->pins;
|
||||
|
||||
if (pins != NULL_PTR)
|
||||
{
|
||||
const IfxEray_Eray_NodeA *nodeAPins = pins->nodeAPins;
|
||||
|
||||
if (nodeAPins != NULL_PTR)
|
||||
{
|
||||
const IfxEray_Rxd_In *rx = nodeAPins->rxIn;
|
||||
|
||||
if (rx != NULL_PTR)
|
||||
{
|
||||
IfxEray_initRxPinWithPadLevel(rx, nodeAPins->rxInMode, nodeAPins->pinDriver);
|
||||
}
|
||||
|
||||
const IfxEray_Txd_Out *tx = nodeAPins->txOut;
|
||||
|
||||
if (tx != NULL_PTR)
|
||||
{
|
||||
IfxEray_initTxPin(tx, nodeAPins->txOutMode, nodeAPins->pinDriver);
|
||||
}
|
||||
|
||||
const IfxEray_Txen_Out *txEn = nodeAPins->txEnOut;
|
||||
|
||||
if (txEn != NULL_PTR)
|
||||
{
|
||||
IfxEray_initTxEnPin(txEn, nodeAPins->txEnOutMode, nodeAPins->pinDriver);
|
||||
}
|
||||
}
|
||||
|
||||
const IfxEray_Eray_NodeB *nodeBPins = pins->nodeBPins;
|
||||
|
||||
if (nodeBPins != NULL_PTR)
|
||||
{
|
||||
const IfxEray_Rxd_In *rx = nodeBPins->rxIn;
|
||||
|
||||
if (rx != NULL_PTR)
|
||||
{
|
||||
IfxEray_initRxPinWithPadLevel(rx, nodeBPins->rxInMode, nodeBPins->pinDriver);
|
||||
}
|
||||
|
||||
const IfxEray_Txd_Out *tx = nodeBPins->txOut;
|
||||
|
||||
if (tx != NULL_PTR)
|
||||
{
|
||||
IfxEray_initTxPin(tx, nodeBPins->txOutMode, nodeBPins->pinDriver);
|
||||
}
|
||||
|
||||
const IfxEray_Txen_Out *txEn = nodeBPins->txEnOut;
|
||||
|
||||
if (txEn != NULL_PTR)
|
||||
{
|
||||
IfxEray_initTxEnPin(txEn, nodeBPins->txEnOutMode, nodeBPins->pinDriver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set the Communication Controller to ready state
|
||||
IfxEray_setPocReady(eraySFR);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxEray_Eray_Node_initCommunicationController(IfxEray_Eray *eray, const IfxEray_Eray_ControllerConfig *config)
|
||||
{
|
||||
Ifx_ERAY *eraySFR = eray->eray;
|
||||
//SUCC1
|
||||
IfxEray_setTransmittedFrames(eraySFR, config->succ1Config.startupFrameTransmitted, config->succ1Config.syncFrameTransmitted);
|
||||
IfxEray_setMaxColdStartAttempts(eraySFR, config->succ1Config.maxColdStartAttempts);
|
||||
IfxEray_setActiveCyclePairs(eraySFR, config->succ1Config.numberOfCyclePairsForActive);
|
||||
IfxEray_setWakeupPatternChannel(eraySFR, config->succ1Config.wakeupPatternChannel);
|
||||
IfxEray_setTransmissionSlotMode(eraySFR, config->succ1Config.transmissionSlotMode);
|
||||
IfxEray_setClockSynchErrorHalt(eraySFR, config->succ1Config.clockSyncErrorHalt);
|
||||
IfxEray_setSymbolChannels(eraySFR, config->succ1Config.channelASymbolTransmitted, config->succ1Config.channelBSymbolTransmitted);
|
||||
IfxEray_setNodeChannels(eraySFR, config->succ1Config.channelAConnectedNode, config->succ1Config.channelBConnectedNode);
|
||||
//SUCC2
|
||||
IfxEray_setListenTimeOuts(eraySFR, config->succ2Config.listenTimeOut, config->succ2Config.listenTimeOutNoise);
|
||||
//SUCC3
|
||||
IfxEray_setClockCorrectionCycles(eraySFR, config->succ3Config.clockCorrectionCyclesPassive, config->succ3Config.clockCorrectionCyclesHalt);
|
||||
//NEMC
|
||||
IfxEray_setNetworkVectorLength(eraySFR, config->networkVectorLength);
|
||||
//PRTC1, PRTC2
|
||||
IfxEray_setTransmissionStartTime(eraySFR, (uint8)config->prtc1Control.transmissionStartTime);
|
||||
IfxEray_setCollisionAvoidanceDuration(eraySFR, config->prtc1Control.collisionAvoidanceDuration);
|
||||
IfxEray_setStrobePosition(eraySFR, config->prtc1Control.strobePosition);
|
||||
IfxEray_setBaudrate(eraySFR, config->prtc1Control.baudrate);
|
||||
IfxEray_setReceiveWakeupTimes(eraySFR, config->prtc1Control.receiveWakeupTestDuration, config->prtc2Control.receiveWakeupIdleTime, config->prtc2Control.receiveWakeupLowTime
|
||||
);
|
||||
IfxEray_setTransmitWakeupTimes(eraySFR, config->prtc1Control.transmitWakeupRepetitions, config->prtc2Control.transmitWakeupIdleTime, config->prtc2Control.transmitWakeupLowTime);
|
||||
//MHDC
|
||||
IfxEray_setMessageHandlerConfigurations(eraySFR, config->staticFramepayload, config->latestTransmissionStart);
|
||||
// GTU
|
||||
IfxEray_Eray_Node_initGTU(eray, &config->gtuConfig);
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_Eray_Node_initConfig(IfxEray_Eray_NodeConfig *config)
|
||||
{
|
||||
// Default node configurations buffer
|
||||
const IfxEray_Eray_NodeConfig nodeConfig = {
|
||||
.messageRAMConfig = {
|
||||
.firstDynamicBuffer = 0,
|
||||
.numberOfMessageBuffers = 0,
|
||||
.fifoBufferStartIndex = 0x80,
|
||||
.fifoDepth = 30,
|
||||
.frameIdFilter = 0x7FD,
|
||||
.receiveChannel = IfxEray_ReceiveChannel_a,
|
||||
.rejectedFrameId = 2,
|
||||
.filteredCycleNumber = 0,
|
||||
.staticFifoDisabled = FALSE,
|
||||
.fifoNullFramesRejected = FALSE,
|
||||
.bufferReconfigEnabled = TRUE,
|
||||
.fifoConfigured = FALSE
|
||||
},
|
||||
|
||||
.controllerConfig = {
|
||||
.networkVectorLength = 0x2,
|
||||
.staticFramepayload = 0x4,
|
||||
.latestTransmissionStart = 0x3F,
|
||||
|
||||
.prtc1Control = {
|
||||
.transmissionStartTime = 0xA,
|
||||
.collisionAvoidanceDuration = 0x61,
|
||||
.strobePosition = IfxEray_StrobePosition_5,
|
||||
.baudrate = IfxEray_Baudrate_10,
|
||||
.receiveWakeupTestDuration = 0x8C,
|
||||
.transmitWakeupRepetitions = 0x2
|
||||
},
|
||||
|
||||
.prtc2Control = {
|
||||
.receiveWakeupIdleTime = 0x2D,
|
||||
.receiveWakeupLowTime = 0x12,
|
||||
.transmitWakeupIdleTime = 0x2D,
|
||||
.transmitWakeupLowTime = 0x12
|
||||
},
|
||||
|
||||
.succ1Config = {
|
||||
.channelAConnectedNode = TRUE,
|
||||
.channelBConnectedNode = TRUE,
|
||||
.channelASymbolTransmitted = FALSE,
|
||||
.channelBSymbolTransmitted = FALSE,
|
||||
.clockSyncErrorHalt = TRUE,
|
||||
.transmissionSlotMode = IfxEray_TransmissionSlotMode_single,
|
||||
.wakeupPatternChannel = IfxEray_WakeupChannel_a,
|
||||
.numberOfCyclePairsForActive = 0x7,
|
||||
.maxColdStartAttempts = 0x1F,
|
||||
.syncFrameTransmitted = TRUE,
|
||||
.startupFrameTransmitted = TRUE
|
||||
},
|
||||
|
||||
.succ2Config = {
|
||||
.listenTimeOut = 0x13972,
|
||||
.listenTimeOutNoise = IfxEray_ListenTimeOutNoise_16
|
||||
},
|
||||
|
||||
.succ3Config = {
|
||||
.clockCorrectionCyclesPassive = 0x1,
|
||||
.clockCorrectionCyclesHalt = 0x1
|
||||
},
|
||||
|
||||
.gtuConfig = {
|
||||
.gtu01Config.microticksPerCycle = 0x9C40,
|
||||
|
||||
.gtu02Config = {
|
||||
.macroticksPerCycle = 0x3E8,
|
||||
.maxSyncFrames = 0x4
|
||||
},
|
||||
|
||||
.gtu03Config = {
|
||||
.channelAMicrotickInitialOffset = 0x19,
|
||||
.channelBMicrotickInitialOffset = 0x19,
|
||||
.channelAMacrotickInitialOffset = 0xA,
|
||||
.channelBMacrotickInitialOffset = 0x2
|
||||
},
|
||||
|
||||
.gtu04Config = {
|
||||
.networkStartIdleTime = 0x38E,
|
||||
.correctionOffset = 0x394
|
||||
},
|
||||
|
||||
.gtu05Config = {
|
||||
.channelAReceptionDelay = 0x4,
|
||||
.channelBReceptionDelay = 0x4,
|
||||
.clusterDrift = 1,
|
||||
.decodingCorrection = 0x34
|
||||
},
|
||||
|
||||
.gtu06Config = {
|
||||
.acceptedStartupDeviation = 0x81,
|
||||
.maxDriftOffset = 0xD2
|
||||
},
|
||||
|
||||
.gtu07Config = {
|
||||
.staticSlotLength = 0x32,
|
||||
.staticSlotsCount = 0xC
|
||||
},
|
||||
|
||||
.gtu08Config = {
|
||||
.dynamicSlotLength = 4,
|
||||
.dynamicSlotCount = 0x4B,
|
||||
},
|
||||
|
||||
.gtu09Config = {
|
||||
.idleDynamicSlots = IfxEray_IdleDynamicSlots_1,
|
||||
.staticActionPoint = 8,
|
||||
.dynamicActionPoint = 3
|
||||
},
|
||||
|
||||
.gtu10Config = {
|
||||
.maxOffsetCorrection = 0x32,
|
||||
.maxRateCorrection = 0xD2
|
||||
},
|
||||
|
||||
.gtu11Config = {
|
||||
.externalOffsetCorrection = IfxEray_ExternalOffsetCorrection_0,
|
||||
.externalRateCorrection = IfxEray_ExternalRateCorrection_0,
|
||||
.externalOffset = IfxEray_ExternalOffset_noCorrection,
|
||||
.externalRate = IfxEray_ExternalRate_noCorrection
|
||||
},
|
||||
},
|
||||
},
|
||||
.pins = NULL_PTR
|
||||
};
|
||||
|
||||
*config = nodeConfig;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxEray_Eray_Node_initGTU(IfxEray_Eray *eray, const IfxEray_Eray_GTUConfig *config)
|
||||
{
|
||||
Ifx_ERAY *eraySFR = eray->eray;
|
||||
|
||||
IfxEray_setCycleDurationMicroticks(eraySFR, config->gtu01Config.microticksPerCycle);
|
||||
IfxEray_setCycleDurationMacroticks(eraySFR, config->gtu02Config.macroticksPerCycle);
|
||||
IfxEray_setMaxSynchFrames(eraySFR, (IfxEray_MaxSynchFrames)config->gtu02Config.maxSyncFrames);
|
||||
IfxEray_setChannelAInitialOffsets(eraySFR, config->gtu03Config.channelAMicrotickInitialOffset, config->gtu03Config.channelAMacrotickInitialOffset);
|
||||
IfxEray_setChannelBInitialOffsets(eraySFR, config->gtu03Config.channelBMicrotickInitialOffset, config->gtu03Config.channelBMacrotickInitialOffset);
|
||||
IfxEray_setNetworkStartIdleTime(eraySFR, config->gtu04Config.networkStartIdleTime);
|
||||
IfxEray_setOffsetCorrection(eraySFR, config->gtu04Config.correctionOffset);
|
||||
IfxEray_setChannelsReceiveDelay(eraySFR, config->gtu05Config.channelAReceptionDelay, config->gtu05Config.channelBReceptionDelay);
|
||||
IfxEray_setDecodingCorrectionValue(eraySFR, config->gtu05Config.decodingCorrection);
|
||||
IfxEray_setClusterDriftValues(eraySFR, config->gtu05Config.clusterDrift, config->gtu06Config.maxDriftOffset);
|
||||
IfxEray_setClusterStartupDeviation(eraySFR, config->gtu06Config.acceptedStartupDeviation);
|
||||
IfxEray_setStaticSlots(eraySFR, config->gtu07Config.staticSlotLength, config->gtu07Config.staticSlotsCount);
|
||||
IfxEray_setDynamicSlots(eraySFR, config->gtu08Config.dynamicSlotLength, config->gtu08Config.dynamicSlotCount, config->gtu09Config.idleDynamicSlots);
|
||||
IfxEray_setSlotActionPoints(eraySFR, config->gtu09Config.staticActionPoint, config->gtu09Config.dynamicActionPoint);
|
||||
IfxEray_setMaxCorrectionValues(eraySFR, config->gtu10Config.maxOffsetCorrection, config->gtu10Config.maxRateCorrection);
|
||||
IfxEray_setExternalCorrectionControl(eraySFR, config->gtu11Config.externalOffset, config->gtu11Config.externalRate);
|
||||
IfxEray_setExternalCorrectionValues(eraySFR, config->gtu11Config.externalOffsetCorrection, config->gtu11Config.externalRateCorrection);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxEray_Eray_Node_initMessageRAM(IfxEray_Eray *eray, const IfxEray_Eray_MessageRAMConfig *config)
|
||||
{
|
||||
Ifx_ERAY *eraySFR = eray->eray;
|
||||
uint32 bufferCount;
|
||||
//group of Message Buffers exclusively for the static segment configured
|
||||
IfxEray_setFirstDynamicBuffer(eraySFR, config->firstDynamicBuffer);
|
||||
/* Last Configured Buffer
|
||||
* 01H..7FH: Number of Message Buffers is LCB + 1
|
||||
* 80H..FFH: No Message Buffer configured
|
||||
*/
|
||||
IfxEray_setMessageBufferCount(eraySFR, config->numberOfMessageBuffers);
|
||||
|
||||
// receive FIFO buffers configuration
|
||||
if (config->fifoConfigured == TRUE)
|
||||
{
|
||||
IfxEray_setFifoBufferStartIndex(eraySFR, (uint8)config->fifoBufferStartIndex);
|
||||
IfxEray_setFifoMessageBufferConfigurations(eraySFR, config->receiveChannel, config->staticFifoDisabled, config->fifoDepth);
|
||||
IfxEray_setFifoFilterConfigurations(eraySFR, config->rejectedFrameId, config->filteredCycleNumber, config->fifoNullFramesRejected, config->frameIdFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIFO is not supported. No message buffers assigned to the FIFO, if FFB >= 128
|
||||
IfxEray_setFifoBufferStartIndex(eraySFR, (uint8)config->fifoBufferStartIndex);
|
||||
}
|
||||
|
||||
if (config->bufferReconfigEnabled == TRUE)
|
||||
{
|
||||
//buffers reconfigured
|
||||
IfxEray_setBufferReconfigSecure(eraySFR, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//buffer reconfiguration locked
|
||||
IfxEray_setBufferReconfigSecure(eraySFR, 2);
|
||||
}
|
||||
|
||||
for (bufferCount = 0; bufferCount < config->numberOfMessageBuffers; bufferCount++)
|
||||
{
|
||||
IfxEray_setSlot(eraySFR, config->header[bufferCount], config->data[bufferCount], config->slotControl[bufferCount]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_Eray_initModule(IfxEray_Eray *eray, const IfxEray_Eray_Config *config)
|
||||
{
|
||||
eray->eray = config->module;
|
||||
Ifx_ERAY *eraySFR = config->module;
|
||||
// Enable MTU clock
|
||||
{
|
||||
uint16 password = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(password);
|
||||
IfxMtu_enableModule();
|
||||
IfxScuWdt_setCpuEndinit(password);
|
||||
}
|
||||
// clear RAMS
|
||||
{
|
||||
uint16 password = IfxScuWdt_getSafetyWatchdogPassword();
|
||||
IfxScuWdt_clearSafetyEndinit(password);
|
||||
IfxMtu_clearSram(IfxMtu_MbistSel_erayObf);
|
||||
IfxMtu_clearSram(IfxMtu_MbistSel_erayIbfTbf);
|
||||
IfxMtu_clearSram(IfxMtu_MbistSel_erayMbf);
|
||||
|
||||
IfxScuWdt_setSafetyEndinit(password);
|
||||
}
|
||||
|
||||
{
|
||||
IfxEray_enableModule(eraySFR);
|
||||
}
|
||||
|
||||
/** NOTE: If not DMA, the interrupt service provider is assigned to the CPU ID where
|
||||
* this function is called from */
|
||||
{
|
||||
if ((config->interrupt.int0Priority != 0) || (config->interrupt.int0IsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getInterruptLine0SrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.int0IsrProvider, config->interrupt.int0Priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.int1Priority != 0) || (config->interrupt.int1IsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getInterruptLine1SrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.int1IsrProvider, config->interrupt.int1Priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.tint0Priority != 0) || (config->interrupt.tint0IsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getTimerInterrupt0SrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.tint0IsrProvider, config->interrupt.tint0Priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.tint1Priority != 0) || (config->interrupt.tint1IsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getTimerInterrupt1SrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.tint1IsrProvider, config->interrupt.tint1Priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.mbsc0Priority != 0) || (config->interrupt.mbsc0IsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getMessageBufferStatus0SrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.mbsc0IsrProvider, config->interrupt.mbsc0Priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.mbsc1Priority != 0) || (config->interrupt.mbsc1IsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getMessageBufferStatus1SrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.mbsc1IsrProvider, config->interrupt.mbsc1Priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.ibusyPriority != 0) || (config->interrupt.ibusyIsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getInputBufferBusySrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.ibusyIsrProvider, config->interrupt.ibusyPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.obusyPriority != 0) || (config->interrupt.obusyIsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getOutputBufferBusySrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.obusyIsrProvider, config->interrupt.obusyPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.ndat0Priority != 0) || (config->interrupt.ndat0IsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getNewDataInterrupt0SrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.ndat0IsrProvider, config->interrupt.ndat0Priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if ((config->interrupt.ndat1Priority != 0) || (config->interrupt.ndat1IsrProvider == IfxSrc_Tos_dma))
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src = IfxEray_getNewDataInterrupt1SrcPtr(eraySFR);
|
||||
IfxSrc_init(src, config->interrupt.ndat1IsrProvider, config->interrupt.ndat1Priority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_Eray_initModuleConfig(IfxEray_Eray_Config *config, Ifx_ERAY *eray)
|
||||
{
|
||||
config->module = eray;
|
||||
config->interrupt.int0IsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.int1IsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.tint0IsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.tint1IsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.ndat0IsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.ndat1IsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.mbsc0IsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.mbsc1IsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.ibusyIsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.obusyIsrProvider = IfxSrc_Tos_cpu0;
|
||||
|
||||
config->interrupt.int0Priority = 0;
|
||||
config->interrupt.int1Priority = 0;
|
||||
config->interrupt.tint0Priority = 0;
|
||||
config->interrupt.tint1Priority = 0;
|
||||
config->interrupt.ndat0Priority = 0;
|
||||
config->interrupt.ndat1Priority = 0;
|
||||
config->interrupt.mbsc0Priority = 0;
|
||||
config->interrupt.mbsc1Priority = 0;
|
||||
config->interrupt.ibusyPriority = 0;
|
||||
config->interrupt.obusyPriority = 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_Eray_receiveFifoFrame(IfxEray_Eray *eray, IfxEray_Eray_ReceiveControl *config)
|
||||
{
|
||||
Ifx_ERAY *eraySFR = eray->eray;
|
||||
|
||||
Ifx_ERAY_FSR fifoStatus = IfxEray_getFifoStatus(eraySFR);
|
||||
|
||||
// Check if FIFO is not empty
|
||||
if (fifoStatus.B.RFNE == 1)
|
||||
{
|
||||
if (fifoStatus.B.RFO == 1)
|
||||
{
|
||||
//FIX ME: FIFO overrun error
|
||||
}
|
||||
else
|
||||
{
|
||||
while (IfxEray_getOutputBufferBusyShadowStatus(eraySFR) == TRUE)
|
||||
{}
|
||||
|
||||
IfxEray_receiveHeader(eraySFR, config->headerReceived);
|
||||
IfxEray_receiveData(eraySFR, config->dataReceived);
|
||||
//Transfer the first message buffer ID of FIFO
|
||||
IfxEray_setRxBufferNumber(eraySFR, IfxEray_getFifoIndex(eraySFR));
|
||||
IfxEray_setReceiveRequest(eraySFR, config->receiveRequested);
|
||||
|
||||
while (IfxEray_getOutputBufferBusyShadowStatus(eraySFR))
|
||||
{}
|
||||
|
||||
if (config->swapRequested && (IfxEray_getOutputBuffer(eraySFR) != config->bufferIndex))
|
||||
{
|
||||
IfxEray_setViewData(eraySFR, config->swapRequested);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_Eray_receiveFrame(IfxEray_Eray *eray, IfxEray_Eray_ReceiveControl *config)
|
||||
{
|
||||
Ifx_ERAY *eraySFR = eray->eray;
|
||||
|
||||
while (IfxEray_getOutputBufferBusyShadowStatus(eraySFR) == TRUE)
|
||||
{}
|
||||
|
||||
IfxEray_receiveHeader(eraySFR, config->headerReceived);
|
||||
IfxEray_receiveData(eraySFR, config->dataReceived);
|
||||
IfxEray_setRxBufferNumber(eraySFR, config->bufferIndex);
|
||||
IfxEray_setReceiveRequest(eraySFR, config->receiveRequested);
|
||||
|
||||
while (IfxEray_getOutputBufferBusyShadowStatus(eraySFR) == TRUE)
|
||||
{}
|
||||
|
||||
if (config->swapRequested && (IfxEray_getOutputBuffer(eraySFR) != config->bufferIndex))
|
||||
{
|
||||
IfxEray_setViewData(eraySFR, config->swapRequested);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_Eray_transmitFrame(IfxEray_Eray *eray, IfxEray_Eray_TransmitControl *transmitControl)
|
||||
{
|
||||
Ifx_ERAY *eraySFR = eray->eray;
|
||||
|
||||
while (IfxEray_getInputBufferBusyHostStatus(eraySFR) == TRUE)
|
||||
{}
|
||||
|
||||
IfxEray_sendHeader(eraySFR, transmitControl->headerTransfered);
|
||||
IfxEray_sendData(eraySFR, transmitControl->dataTransfered);
|
||||
IfxEray_setTransmitRequest(eraySFR, transmitControl->transferRequested);
|
||||
IfxEray_setTxBufferNumber(eraySFR, transmitControl->bufferIndex);
|
||||
|
||||
while (IfxEray_getInputBufferBusyShadowStatus(eraySFR) == TRUE)
|
||||
{}
|
||||
|
||||
while (IfxEray_getInputBufferBusyHostStatus(eraySFR) == TRUE)
|
||||
{}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,363 @@
|
||||
/**
|
||||
* \file IfxEray.c
|
||||
* \brief ERAY basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxEray.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint16 IfxEray_calcHeaderCrc(uint8 payloadLength, uint16 frameId, boolean startupFrameIndicator, boolean syncFrameIndicator)
|
||||
{
|
||||
uint32 headerValue = ((syncFrameIndicator & 0x1) << 19) | ((startupFrameIndicator & 0x1) << 18) | ((frameId & 0x7FF) << 7) | (payloadLength &
|
||||
0x7F);
|
||||
|
||||
uint32 crcInit = 0x1A;
|
||||
uint32 length = 20;
|
||||
uint32 crcNext;
|
||||
uint32 crcPoly = 0x385;
|
||||
uint32 crcRegX = crcInit;
|
||||
uint32 headerTemp, regTemp;
|
||||
|
||||
headerValue <<= 11;
|
||||
crcRegX <<= 21;
|
||||
crcPoly <<= 21;
|
||||
|
||||
while (length)
|
||||
{
|
||||
headerValue <<= 1;
|
||||
headerTemp = headerValue & 0x80000000;
|
||||
regTemp = crcRegX & 0x80000000;
|
||||
|
||||
if (headerTemp ^ regTemp) // Step 1
|
||||
{
|
||||
crcNext = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
crcNext = 0;
|
||||
}
|
||||
|
||||
crcRegX <<= 1; // Step 2
|
||||
|
||||
if (crcNext)
|
||||
{
|
||||
crcRegX ^= crcPoly; // Step 3
|
||||
}
|
||||
|
||||
length--;
|
||||
}
|
||||
|
||||
crcRegX >>= 21;
|
||||
|
||||
return (uint16)crcRegX;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxEray_changePocState(Ifx_ERAY *eray, IfxEray_PocCommand pocCommand)
|
||||
{
|
||||
boolean result;
|
||||
|
||||
// wait if Communication controller is busy
|
||||
while (eray->SUCC1.B.PBSY == 1)
|
||||
{}
|
||||
|
||||
eray->SUCC1.B.CMD = pocCommand;
|
||||
|
||||
// if command not accepted, return FALSE
|
||||
if (eray->SUCC1.B.CMD == 0)
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_clearAllFlags(Ifx_ERAY *eray)
|
||||
{
|
||||
eray->EIR.U = 0xFFFFFFFFU; /* Clear Error Int. */
|
||||
eray->SIR.U = 0xFFFFFFFFU; /* Clear Status Int. */
|
||||
eray->EIER.U = 0xFFFFFFFFU; /* Disable all Error Int. */
|
||||
eray->SIER.U = 0xFFFFFFFFU; /* Disable all Status Int. */
|
||||
eray->MHDS.U = 0x7F7F7FFFU; /* Clear Error Int. */
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_enableInterruptLines(Ifx_ERAY *eray)
|
||||
{
|
||||
eray->ILE.U = 0x00000003U; //enable both the interrupt lines
|
||||
eray->EILS.U = 0x00000000U; // all interrupt lines to INT0SRC
|
||||
eray->SILS.U = 0x00000800U; // TOBC interrupt line to INT1SRC
|
||||
eray->SIES.U = 0x0303FFFFU; // all status interrupts are enabled
|
||||
eray->EIES.U = 0x07070FFFU; // all error interrupts are enabled
|
||||
eray->NDIC1.U = 0x00000000U; // all interrupt lines to NADT0SRC
|
||||
eray->NDIC2.U = 0x00000000U; // all interrupt lines to NADT0SRC
|
||||
eray->NDIC3.U = 0x00000000U; // all interrupt lines to NADT0SRC
|
||||
eray->NDIC4.U = 0x00000000U; // all interrupt lines to NADT0SRC
|
||||
eray->MSIC1.U = 0x00000000U; // all interrupt lines to MBSC0SRC
|
||||
eray->MSIC2.U = 0x00000000U; // all interrupt lines to MBSC0SRC
|
||||
eray->MSIC3.U = 0x00000000U; // all interrupt lines to MBSC0SRC
|
||||
eray->MSIC4.U = 0x00000000U; // all interrupt lines to MBSC0SRC
|
||||
}
|
||||
|
||||
|
||||
Ifx_ERAY *IfxEray_getAddress(IfxEray_Index eray)
|
||||
{
|
||||
Ifx_ERAY *module;
|
||||
|
||||
if (eray < IFXERAY_NUM_MODULES)
|
||||
{
|
||||
module = (Ifx_ERAY *)IfxEray_cfg_indexMap[eray].module;
|
||||
}
|
||||
else
|
||||
{
|
||||
module = NULL_PTR;
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
IfxEray_Index IfxEray_getIndex(Ifx_ERAY *eray)
|
||||
{
|
||||
uint32 index;
|
||||
IfxEray_Index result;
|
||||
|
||||
result = IfxEray_Index_none;
|
||||
|
||||
for (index = 0; index < IFXERAY_NUM_MODULES; index++)
|
||||
{
|
||||
if (IfxEray_cfg_indexMap[index].module == eray)
|
||||
{
|
||||
result = (IfxEray_Index)IfxEray_cfg_indexMap[index].index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_readData(Ifx_ERAY *eray, uint32 *data, uint8 payloadLength)
|
||||
{
|
||||
if (data != NULL_PTR)
|
||||
{
|
||||
uint16 length = (payloadLength + 1) / 2;
|
||||
uint8 index;
|
||||
|
||||
for (index = 0; index < length; index++)
|
||||
{
|
||||
*data++ = eray->RDDS_1S[index].U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_readFrame(Ifx_ERAY *eray, IfxEray_ReceivedHeader *header, uint32 *data, Ifx_SizeT maxPayloadLength)
|
||||
{
|
||||
{
|
||||
Ifx_ERAY_RDHS1 rdhs1;
|
||||
rdhs1.U = eray->RDHS1.U;
|
||||
Ifx_ERAY_RDHS2 rdhs2;
|
||||
rdhs2.U = eray->RDHS2.U;
|
||||
Ifx_ERAY_RDHS3 rdhs3;
|
||||
rdhs3.U = eray->RDHS3.U;
|
||||
|
||||
header->frameId = rdhs1.B.FID;
|
||||
header->payloadLength = rdhs2.B.PLR;
|
||||
header->headerCrc = rdhs2.B.CRC;
|
||||
header->payloadPreambleIndicator = rdhs3.B.PPI;
|
||||
header->nullFrameIndicator = rdhs3.B.NFI;
|
||||
header->syncFrame = rdhs3.B.SYN;
|
||||
header->startupFrame = rdhs3.B.SFI;
|
||||
header->cycleNumber = rdhs3.B.RCC;
|
||||
}
|
||||
|
||||
IfxEray_readData(eray, data, (header->payloadLength > maxPayloadLength) ? maxPayloadLength : header->payloadLength);
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_resetModule(Ifx_ERAY *eray)
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
eray->KRST1.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
|
||||
eray->KRST0.B.RST = 1;
|
||||
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
|
||||
while (eray->KRST0.B.RSTSTAT == 0)
|
||||
{
|
||||
/* Wait until reset is executed */
|
||||
}
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
eray->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_setMessageBufferInterruptDestination(Ifx_ERAY *eray, uint8 messageBuffer, uint8 messageBufferDestination)
|
||||
{
|
||||
uint8 ix = messageBuffer / 32;
|
||||
uint32 mask = 1 << (messageBuffer % 32);
|
||||
Ifx_ERAY_MSIC1 *msicSFR = (Ifx_ERAY_MSIC1 *)((uint32)&eray->MSIC1 + 4 * ix);
|
||||
|
||||
if (messageBufferDestination == FALSE)
|
||||
{
|
||||
msicSFR->U &= ~mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
msicSFR->U |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_setNewDataInterruptDestination(Ifx_ERAY *eray, uint8 ndat, uint8 ndatDestination)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(ndat);
|
||||
uint8 ix = ndatDestination / 32;
|
||||
uint32 mask = 1 << (ndatDestination % 32);
|
||||
Ifx_ERAY_NDIC1 *ndicSFR = (Ifx_ERAY_NDIC1 *)((uint32)&eray->NDIC1 + 4 * ix);
|
||||
|
||||
if (ndatDestination == FALSE)
|
||||
{
|
||||
ndicSFR->U &= ~mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
ndicSFR->U |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_setPocReady(Ifx_ERAY *eray)
|
||||
{
|
||||
// wait CC is busy
|
||||
while (eray->SUCC1.B.PBSY == 1)
|
||||
{}
|
||||
|
||||
// Ready unlock sequence
|
||||
eray->LCK.B.CLK = 0xCE;
|
||||
eray->LCK.B.CLK = 0x31;
|
||||
eray->SUCC1.B.CMD = IfxEray_PocCommand_ready;
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_setSlot(Ifx_ERAY *eray, const IfxEray_Header *header, const uint32 *data, const IfxEray_SlotConfig *slotConfig)
|
||||
{
|
||||
// wait if Host is busy with another transfer
|
||||
while (IfxEray_getInputBufferBusyHostStatus(eray) == TRUE)
|
||||
{}
|
||||
|
||||
if (header != NULL_PTR)
|
||||
{
|
||||
{
|
||||
Ifx_ERAY_WRHS1 wrhs1;
|
||||
wrhs1.U = 0;
|
||||
wrhs1.B.FID = header->frameId;
|
||||
wrhs1.B.CYC = header->cycleCode;
|
||||
wrhs1.B.CHA = header->channelAFiltered;
|
||||
wrhs1.B.CHB = header->channelBFiltered;
|
||||
wrhs1.B.CFG = header->bufferDirection;
|
||||
wrhs1.B.PPIT = header->transmitPayloadIndicatior;
|
||||
wrhs1.B.TXM = header->transmissionMode;
|
||||
wrhs1.B.MBI = header->bufferServiceEnabled;
|
||||
eray->WRHS1.U = wrhs1.U;
|
||||
}
|
||||
{
|
||||
Ifx_ERAY_WRHS2 wrhs2;
|
||||
wrhs2.U = 0;
|
||||
|
||||
if (header->bufferDirection == IfxEray_BufferDirection_transmit)
|
||||
{
|
||||
wrhs2.B.CRC = IfxEray_calcHeaderCrc(header->payloadLength, header->frameId, header->startupFrameIndicator, header->syncFrameIndicator);
|
||||
}
|
||||
|
||||
wrhs2.B.PLC = header->payloadLength;
|
||||
eray->WRHS2.U = wrhs2.U;
|
||||
}
|
||||
|
||||
eray->WRHS3.U = header->dataPointer;
|
||||
}
|
||||
|
||||
IfxEray_writeData(eray, data, header->payloadLength);
|
||||
|
||||
eray->IBCM.B.LHSH = slotConfig->headerTransfered;
|
||||
eray->IBCM.B.LDSH = slotConfig->dataTransfered;
|
||||
eray->IBCM.B.STXRH = slotConfig->transferRequested;
|
||||
eray->IBCR.B.IBRH = slotConfig->bufferIndex;
|
||||
|
||||
// wait if Shadow is busy with another transfer
|
||||
while (IfxEray_getInputBufferBusyShadowStatus(eray) == TRUE)
|
||||
{}
|
||||
|
||||
while (IfxEray_getInputBufferBusyHostStatus(eray) == TRUE)
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
void IfxEray_writeData(Ifx_ERAY *eray, const uint32 *data, uint8 payloadLength)
|
||||
{
|
||||
if (data != NULL_PTR)
|
||||
{
|
||||
uint16 length = (payloadLength + 1) / 2;
|
||||
uint8 index;
|
||||
|
||||
for (index = 0; index < length; index++)
|
||||
{
|
||||
eray->WRDS_1S[index].U = *data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* \file IfxEth_Phy_Pef7071.c
|
||||
* \brief ETH PHY_PEF7071 details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxEth_Phy_Pef7071.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Macros------------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_CTRL 0x00
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_STAT 0x01
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_PHYID1 0x02
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_PHYID2 0x03
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_AN_ADV 0x04
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_AN_LPA 0x05
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_AN_EXP 0x06
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_AN_NPTX 0x07
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_AN_NPRX 0x08
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_GCTRL 0x09
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_GSTAT 0x0A
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_RES11 0x0B
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_RES12 0x0C
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_MMDCTRL 0x0D
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_MMDDATA 0x0E
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_XSTAT 0x0F
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_PHYPERF 0x10
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_PHYSTAT1 0x11
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_PHYSTAT2 0x12
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_PHYCTL1 0x13
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_PHYCTL2 0x14
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_ERRCNT 0x15
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_EECTRL 0x16
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_MIICTRL 0x17
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_MIISTAT 0x18
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_IMASK 0x19
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_ISTAT 0x1A
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_LED 0x1B
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_TPGCTRL 0x1C
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_TPGDATA 0x1D
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_FWV 0x1E
|
||||
|
||||
#define IFXETH_PHY_PEF7071_MDIO_RES1F 0x1F
|
||||
|
||||
#define IFXETH_PHY_PEF7071_WAIT_GMII_READY() while (ETH_GMII_ADDRESS.B.GB) {}
|
||||
|
||||
/** \brief Access type for indirectly accessing Address Type of MMD register in PHY
|
||||
*/
|
||||
#define IFXETH_PHY_PEF7071_MDIO_MMDCTRL_ACCESSTYPE_ADDR 0x00
|
||||
|
||||
/** \brief Access type for indirectly accessing Data Type of MMD register in PHY
|
||||
*/
|
||||
#define IFXETH_PHY_PEF7071_MDIO_MMDCTRL_ACCESSTYPE_DATA 0x4000
|
||||
|
||||
/** \brief Access type for indirectly accessing Data Type with post increment of MMD register in PHY
|
||||
*/
|
||||
#define IFXETH_PHY_PEF7071_MDIO_MMDCTRL_ACCESSTYPE_DATA_PI 0x8000
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Exported Variables/Constants-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint32 IfxEth_Phy_Pef7071_iPhyInitDone = 0;
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint32 IfxEth_Phy_Pef7071_init(void)
|
||||
{
|
||||
IFXETH_PHY_PEF7071_WAIT_GMII_READY();
|
||||
|
||||
/* // read once all PHY registers
|
||||
* int i;
|
||||
* for(i = 0; i < 31; i++)
|
||||
* {
|
||||
* uint32 value;
|
||||
* read_mdio_reg(0, i, &value);
|
||||
* } */
|
||||
|
||||
// reset PHY
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(0, IFXETH_PHY_PEF7071_MDIO_CTRL, 0x8000); // reset
|
||||
uint32 value;
|
||||
|
||||
do
|
||||
{
|
||||
IfxEth_Phy_Pef7071_read_mdio_reg(0, IFXETH_PHY_PEF7071_MDIO_CTRL, &value);
|
||||
} while (value & 0x8000); // wait for reset to finish
|
||||
|
||||
// setup PHY
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(0, IFXETH_PHY_PEF7071_MDIO_MIICTRL, 0xF702); // skew adaptation is needed, RMII mode (10/100MBit)
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(0, IFXETH_PHY_PEF7071_MDIO_GCTRL, 0x0000); // advertise no 1000BASE-T (full/half duplex)
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(0, IFXETH_PHY_PEF7071_MDIO_AN_ADV, 0x0101); // advertise 100BASE-TX full duplex only
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(0, IFXETH_PHY_PEF7071_MDIO_CTRL, 0x1200); // enable auto-negotiation, restart auto-negotiation
|
||||
|
||||
// we set our loop mode (RJ45) in side the PHY (PHYCTL1 register) if we will have a loop
|
||||
// if (CONFIG_ETH._loop)
|
||||
// write_mdio_reg (0, 0x13, (0x4 << 13) | 0x1);
|
||||
|
||||
// done
|
||||
IfxEth_Phy_Pef7071_iPhyInitDone = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxEth_Phy_Pef7071_link(void)
|
||||
{
|
||||
boolean linkEstablished = FALSE;
|
||||
|
||||
if (IfxEth_Phy_Pef7071_iPhyInitDone)
|
||||
{
|
||||
uint32 value;
|
||||
IfxEth_Phy_Pef7071_read_mdio_reg(0, IFXETH_PHY_PEF7071_MDIO_STAT, &value);
|
||||
linkEstablished = ((value & (1 << 2)) != 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
return linkEstablished;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_Phy_Pef7071_read_mdio_reg(uint32 layeraddr, uint32 regaddr, uint32 *pdata)
|
||||
{
|
||||
// 5bit Physical Layer Adddress, 5bit GMII Regnr, 4bit csrclock divider, Read, Busy
|
||||
ETH_GMII_ADDRESS.U = (layeraddr << 11) | (regaddr << 6) | (0 << 2) | (0 << 1) | (1 << 0);
|
||||
|
||||
IFXETH_PHY_PEF7071_WAIT_GMII_READY();
|
||||
|
||||
// get data
|
||||
*pdata = ETH_GMII_DATA.U;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_Phy_Pef7071_write_mdio_reg(uint32 layeraddr, uint32 regaddr, uint32 data)
|
||||
{
|
||||
// put data
|
||||
ETH_GMII_DATA.U = data;
|
||||
|
||||
// 5bit Physical Layer Adddress, 5bit GMII Regnr, 4bit csrclock divider, Write, Busy
|
||||
ETH_GMII_ADDRESS.U = (layeraddr << 11) | (regaddr << 6) | (0 << 2) | (1 << 1) | (1 << 0);
|
||||
|
||||
IFXETH_PHY_PEF7071_WAIT_GMII_READY();
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_Phy_Pef7071_write_mmd_indirect(uint32 layeraddr, uint32 devaddr, uint32 regaddr, uint32 data)
|
||||
{
|
||||
/* Select access type as ADDR for MMD access and select the Device address */
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(layeraddr, IFXETH_PHY_PEF7071_MDIO_MMDCTRL, IFXETH_PHY_PEF7071_MDIO_MMDCTRL_ACCESSTYPE_ADDR | devaddr);
|
||||
/* Select PHY register for write operation */
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(layeraddr, IFXETH_PHY_PEF7071_MDIO_MMDDATA, regaddr);
|
||||
/* select the DATA operation and device address */
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(layeraddr, IFXETH_PHY_PEF7071_MDIO_MMDCTRL, IFXETH_PHY_PEF7071_MDIO_MMDCTRL_ACCESSTYPE_DATA | devaddr);
|
||||
/* Write the data */
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(layeraddr, IFXETH_PHY_PEF7071_MDIO_MMDDATA, data);
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_Phy_Pef7071_read_mmd_indirect(uint32 layeraddr, uint32 devaddr, uint32 regaddr, uint32 data)
|
||||
{
|
||||
/* Select access type as ADDR for MMD access and select the Device address */
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(layeraddr, IFXETH_PHY_PEF7071_MDIO_MMDCTRL, IFXETH_PHY_PEF7071_MDIO_MMDCTRL_ACCESSTYPE_ADDR | devaddr);
|
||||
/* Select PHY register for read operation */
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(layeraddr, IFXETH_PHY_PEF7071_MDIO_MMDDATA, regaddr);
|
||||
/* select the DATA operation and device address */
|
||||
IfxEth_Phy_Pef7071_write_mdio_reg(layeraddr, IFXETH_PHY_PEF7071_MDIO_MMDCTRL, IFXETH_PHY_PEF7071_MDIO_MMDCTRL_ACCESSTYPE_DATA | devaddr);
|
||||
/* Read the data */
|
||||
IfxEth_Phy_Pef7071_read_mdio_reg(layeraddr, IFXETH_PHY_PEF7071_MDIO_MMDDATA, &data);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* \file IfxEth_Phy_Pef7071.h
|
||||
* \brief ETH PHY_PEF7071 details
|
||||
* \ingroup IfxLld_Eth
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Eth_Phy_Pef7071 PHY_PEF7071
|
||||
* \ingroup IfxLld_Eth
|
||||
* \defgroup IfxLld_Eth_Phy_Pef7071_Functions Functions
|
||||
* \ingroup IfxLld_Eth_Phy_Pef7071
|
||||
*/
|
||||
|
||||
#ifndef IFXETH_PHY_PEF7071_H
|
||||
#define IFXETH_PHY_PEF7071_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Eth/Std/IfxEth.h"
|
||||
/** \addtogroup IfxLld_Eth_Phy_Pef7071_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* \return Status
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxEth_Phy_Pef7071_init(void);
|
||||
|
||||
/**
|
||||
* \return Link status
|
||||
*/
|
||||
IFX_EXTERN boolean IfxEth_Phy_Pef7071_link(void);
|
||||
|
||||
/**
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxEth_Phy_Pef7071_read_mdio_reg(uint32 layeraddr, uint32 regaddr, uint32 *pdata);
|
||||
|
||||
/**
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxEth_Phy_Pef7071_write_mdio_reg(uint32 layeraddr, uint32 regaddr, uint32 data);
|
||||
|
||||
/** \brief Write the data into the MMD register of PHY
|
||||
* \param layeraddr physical layer address
|
||||
* \param devaddr Device address in PHY
|
||||
* \param regaddr Register address in PHY
|
||||
* \param data Data to be written
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxEth_Phy_Pef7071_write_mmd_indirect(uint32 layeraddr, uint32 devaddr, uint32 regaddr, uint32 data);
|
||||
|
||||
/** \brief Read data from MMD register of PHY
|
||||
* \param layeraddr physical layer address
|
||||
* \param devaddr Device address in PHY
|
||||
* \param regaddr Register address in PHY
|
||||
* \param data Data from PHY register
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxEth_Phy_Pef7071_read_mmd_indirect(uint32 layeraddr, uint32 devaddr, uint32 regaddr, uint32 data);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------Global Exported Variables/Constants----------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_EXTERN uint32 IfxEth_Phy_Pef7071_iPhyInitDone;
|
||||
|
||||
#endif /* IFXETH_PHY_PEF7071_H */
|
||||
@@ -0,0 +1,953 @@
|
||||
/**
|
||||
* \file IfxEth.c
|
||||
* \brief ETH basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxEth.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Exported Variables/Constants-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint8 IfxEth_rxBuffer[IFXETH_MAX_RX_BUFFERS][IFXETH_RTX_BUFFER_SIZE];
|
||||
|
||||
IfxEth_RxDescrList IfxEth_rxDescr;
|
||||
|
||||
uint8 IfxEth_txBuffer[IFXETH_MAX_TX_BUFFERS][IFXETH_RTX_BUFFER_SIZE];
|
||||
|
||||
IfxEth_TxDescrList IfxEth_txDescr;
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxEth_disableModule(void)
|
||||
{
|
||||
uint16 l_TempVar = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(l_TempVar);
|
||||
ETH_CLC.B.DISR = 1;
|
||||
IfxScuWdt_setCpuEndinit(l_TempVar);
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_enableModule(void)
|
||||
{
|
||||
{
|
||||
uint16 l_TempVar = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(l_TempVar);
|
||||
ETH_CLC.U = 0;
|
||||
IfxScuWdt_setCpuEndinit(l_TempVar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_freeReceiveBuffer(IfxEth *eth)
|
||||
{
|
||||
IfxEth_RxDescr *descr = IfxEth_getActualRxDescriptor(eth);
|
||||
IfxEth_RxDescr_release(descr);
|
||||
IfxEth_shuffleRxDescriptor(eth);
|
||||
}
|
||||
|
||||
|
||||
void *IfxEth_getReceiveBuffer(IfxEth *eth)
|
||||
{
|
||||
void *result = 0;
|
||||
IfxEth_RxDescr *descr;
|
||||
|
||||
if (IfxEth_isRxDataAvailable(eth))
|
||||
{
|
||||
eth->rxCount++;
|
||||
descr = IfxEth_getActualRxDescriptor(eth);
|
||||
result = (void *)(descr->RDES2.U);
|
||||
}
|
||||
|
||||
IfxEth_wakeupReceiver(eth);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void *IfxEth_getTransmitBuffer(IfxEth *eth)
|
||||
{
|
||||
void *buffer = NULL_PTR;
|
||||
IfxEth_TxDescr *descr = IfxEth_getActualTxDescriptor(eth);
|
||||
|
||||
// check descriptor / buffer is free.
|
||||
if (descr->TDES0.A.OWN == 0)
|
||||
{
|
||||
buffer = ((void *)descr->TDES2.U);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_init(IfxEth *eth, const IfxEth_Config *config)
|
||||
{
|
||||
eth->ethSfr = config->ethSfr;
|
||||
|
||||
#ifndef _WIN32
|
||||
IfxEth_enableModule();
|
||||
|
||||
if (config->phyInterfaceMode == IfxEth_PhyInterfaceMode_rmii)
|
||||
{
|
||||
if (config->rmiiPins != NULL_PTR)
|
||||
{
|
||||
IfxEth_setupRmiiOutputPins(eth, config->rmiiPins);
|
||||
IfxEth_setupRmiiInputPins(eth, config->rmiiPins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config->miiPins != NULL_PTR)
|
||||
{
|
||||
IfxEth_setupMiiOutputPins(eth, config->miiPins);
|
||||
IfxEth_setupMiiInputPins(eth, config->miiPins);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
IfxEth_resetModule();
|
||||
|
||||
/* select the Phy Interface Mode */
|
||||
IfxEth_setPhyInterfaceMode(eth, config->phyInterfaceMode);
|
||||
IfxEth_applySoftwareReset(eth);
|
||||
|
||||
/* wait until reset is finished or timeout. */
|
||||
{
|
||||
uint32 timeout = 0;
|
||||
|
||||
while ((IfxEth_isSoftwareResetDone(eth) == 0) && (timeout < IFXETH_MAX_TIMEOUT_VALUE))
|
||||
{
|
||||
timeout++;
|
||||
}
|
||||
}
|
||||
|
||||
/* configure bus mode */
|
||||
{
|
||||
Ifx_ETH_BUS_MODE busMode;
|
||||
busMode.U = ETH_BUS_MODE.U;
|
||||
busMode.B.DSL = 0; /* descriptor skip length in ring mode */
|
||||
busMode.B.ATDS = 0; /* alternate descriptor size: 0 => 4 DWORDS, 1 => 8 DWORDS */
|
||||
busMode.B.DA = 0; /* 0 = weighted round-robin, 1 = fixed priority */
|
||||
|
||||
ETH_BUS_MODE.U = busMode.U;
|
||||
}
|
||||
|
||||
/* configure ETH MAC */
|
||||
{
|
||||
Ifx_ETH_MAC_CONFIGURATION ethMacCfg;
|
||||
ethMacCfg.U = ETH_MAC_CONFIGURATION.U;
|
||||
|
||||
ethMacCfg.B.PRELEN = 0; /* 7 bytes preamble */
|
||||
// ethMacCfg.B.RE = 0; /* disable receiver */
|
||||
// ethMacCfg.B.TE = 0; /* disable transmitter */
|
||||
ethMacCfg.B.DC = 0; /* Deferral Check */
|
||||
// ethMacCfg.B.BL = 0; /* Backoff Limit */
|
||||
ethMacCfg.B.ACS = 1; /* Automatic Pad/CRC stripping--less than 1536 bytes */
|
||||
// ethMacCfg.B.DR = 0; /* Disable Retry */
|
||||
ethMacCfg.B.IPC = 0; /* checksum offload */
|
||||
ethMacCfg.B.DM = 1; /* Duplex Mode: 0=Half Duplex, 1=Full duplex */
|
||||
ethMacCfg.B.LM = 0; /* Loopback Mode */
|
||||
// ethMacCfg.B.DO = 0; /* Disable Receive Own */
|
||||
ethMacCfg.B.FES = 1; /* Speed 0->10mbps 1->100mbps */
|
||||
ethMacCfg.B.PS = 1; /* port select 10/100mbps */
|
||||
ethMacCfg.B.IFG = 0; /* Inter Frame Gap - gap between frames = 96 bit times */
|
||||
ethMacCfg.B.JE = 0; /* Jumbo Frame Enable - no jumbo frames */
|
||||
ethMacCfg.B.JD = 0; /* Jabber Disable - cut of transmission after 2,048 data bytes. */
|
||||
ethMacCfg.B.WD = 0; /* Watchdog Disable - cut off frame after 2,048 bytes. */
|
||||
ethMacCfg.B.CST = 1; /* CRC stripping - last four bytes are stripped and dropped to application. */
|
||||
ethMacCfg.B.TWOKPE = 0; /* 2K Packets Enable - with JE=0 - all received frames of size > 1,518bytes are Giant frames.*/
|
||||
|
||||
ETH_MAC_CONFIGURATION.U = ethMacCfg.U;
|
||||
}
|
||||
|
||||
IfxEth_setMacAddress(eth, config->macAddress);
|
||||
|
||||
/* setup MMC */
|
||||
ETH_MMC_CONTROL.B.CNTFREEZ = 1; /* disable MMC counters - counters reset */
|
||||
|
||||
/* setup GMAC */
|
||||
ETH_STATUS.U = 0x0001e7ff; /* reset all interrupt flag(s) */
|
||||
ETH_MAC_FRAME_FILTER.U = 0x00000010; /* Hash Unicast */
|
||||
|
||||
ETH_INTERRUPT_ENABLE.U = 0x00010041; /* enable tx & rx interrupts */
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
if (config->isrPriority)
|
||||
{
|
||||
IfxSrc_init(&SRC_ETH, config->isrProvider, config->isrPriority);
|
||||
IfxSrc_enable(&SRC_ETH);
|
||||
}
|
||||
|
||||
if (config->phyInit != NULL_PTR)
|
||||
{
|
||||
config->phyInit(); /* init PHY (100Mbit, full duplex with RMII) */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
eth->config = *config;
|
||||
eth->error = 0;
|
||||
eth->status.U = 0;
|
||||
eth->rxCount = 0;
|
||||
eth->txCount = 0;
|
||||
|
||||
IfxEth_stopTransmitter(eth);
|
||||
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, sizeof(IfxEth_TxDescr) == (IFXETH_DESCR_SIZE * sizeof(uint32)));
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, sizeof(IfxEth_RxDescr) == (IFXETH_DESCR_SIZE * sizeof(uint32)));
|
||||
|
||||
eth->rxDescr = config->rxDescr;
|
||||
eth->txDescr = config->txDescr;
|
||||
|
||||
eth->descriptorMode = config->descriptorMode;
|
||||
|
||||
if (config->descriptorMode == IfxEth_DescriptorMode_chain)
|
||||
{
|
||||
IfxEth_initReceiveDescriptors(eth);
|
||||
IfxEth_initTransmitDescriptors(eth);
|
||||
}
|
||||
else if (config->descriptorMode == IfxEth_DescriptorMode_ring)
|
||||
{
|
||||
IfxEth_initReceiveDescriptorsRingMode(eth, &config->ringModeBuffersConfig.rxConfig);
|
||||
IfxEth_initTransmitDescriptorsRingMode(eth, &config->ringModeBuffersConfig.txConfig);
|
||||
}
|
||||
else
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_initConfig(IfxEth_Config *config, Ifx_ETH *ethSfr)
|
||||
{
|
||||
const IfxEth_Config defaultConfig = {
|
||||
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55}, /* MAC address */
|
||||
NULL_PTR,
|
||||
NULL_PTR,
|
||||
IfxEth_PhyInterfaceMode_rmii, /* PHY Interfac mode RMII */
|
||||
NULL_PTR, /* Pointer to the RMII pin config */
|
||||
NULL_PTR, /* Pointer to the MII pin config */
|
||||
(Ifx_Priority)0, /* Interrupt serivce priority */
|
||||
IfxSrc_Tos_cpu0, /* Interrupt serivce provider */
|
||||
NULL_PTR, /* Pointer to register base */
|
||||
&IfxEth_rxDescr, /* pointer to RX descriptor RAM */
|
||||
&IfxEth_txDescr, /* pointer to TX descriptor RAM */
|
||||
IfxEth_DescriptorMode_chain, /* chain mode descreptors */
|
||||
{
|
||||
{
|
||||
IfxEth_RingModeBufferUsed_buffer1,
|
||||
0x0,
|
||||
0x0,
|
||||
IFXETH_RTX_BUFFER_SIZE,
|
||||
0,
|
||||
},
|
||||
{
|
||||
IfxEth_RingModeBufferUsed_buffer1,
|
||||
0x0,
|
||||
0x0,
|
||||
IFXETH_RTX_BUFFER_SIZE,
|
||||
0,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
*config = defaultConfig;
|
||||
config->ethSfr = ethSfr;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_initReceiveDescriptors(IfxEth *eth)
|
||||
{
|
||||
/* Use enhanced descriptors, because ETH is generally configured to precision time protocol. */
|
||||
int i;
|
||||
IfxEth_RxDescr *descr = IfxEth_getBaseRxDescriptor(eth);
|
||||
|
||||
eth->pRxDescr = descr;
|
||||
|
||||
/* init descriptor chained mode */
|
||||
for (i = 0; i < IFXETH_MAX_RX_BUFFERS; i++)
|
||||
{
|
||||
descr->RDES0.U = 0;
|
||||
descr->RDES0.A.OWN = 1U;
|
||||
|
||||
descr->RDES1.U = 0;
|
||||
descr->RDES1.A.RCH = 1U;
|
||||
descr->RDES1.A.RBS1 = (IFXETH_RTX_BUFFER_SIZE);
|
||||
|
||||
#ifndef IFXETH_RX_BUFFER_BY_USER
|
||||
IfxEth_RxDescr_setBuffer(descr, &(IfxEth_rxBuffer[i][0]));
|
||||
#endif
|
||||
|
||||
/* with RCH set, link to next descriptor address */
|
||||
descr->RDES3.U = (uint32)&(descr[1]);
|
||||
descr = &descr[1];
|
||||
}
|
||||
|
||||
/* correction for last descriptor */
|
||||
{
|
||||
descr = &descr[-1];
|
||||
|
||||
/* indicate end of ring */
|
||||
descr->RDES1.A.RER = 1U;
|
||||
|
||||
/* with RCH set, link to first descriptor address */
|
||||
eth->pRxDescr = IfxEth_getBaseRxDescriptor(eth);
|
||||
descr->RDES3.U = (uint32)eth->pRxDescr;
|
||||
}
|
||||
|
||||
eth->rxCount = 0;
|
||||
|
||||
/* write descriptor list base address */
|
||||
IfxEth_setReceiveDescriptorAddress(&MODULE_ETH, IfxEth_getBaseRxDescriptor(eth));
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_initReceiveDescriptorsRingMode(IfxEth *eth, const IfxEth_RingModeRxBuffersConfig *config)
|
||||
{
|
||||
/* Use enhanced descriptors, because ETH is generally configured to precision time protocol. */
|
||||
int i;
|
||||
uint32 buffer1StartAddress = 0;
|
||||
uint32 buffer2StartAddress = 0;
|
||||
|
||||
IfxEth_RxDescr *descr = IfxEth_getBaseRxDescriptor(eth);
|
||||
|
||||
eth->pRxDescr = descr;
|
||||
|
||||
/* init descriptors in ring mode */
|
||||
|
||||
for (i = 0; i < IFXETH_MAX_RX_BUFFERS; i++)
|
||||
{
|
||||
descr->RDES0.U = 0;
|
||||
descr->RDES0.A.OWN = 1U;
|
||||
|
||||
descr->RDES1.U = 0;
|
||||
|
||||
if ((config->rxBufferUsed == IfxEth_RingModeBufferUsed_buffer1) || (config->rxBufferUsed == IfxEth_RingModeBufferUsed_bothBuffers))
|
||||
{
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (config->rxBuffer1Size) % 4 == 0);
|
||||
buffer1StartAddress = (uint32)(config->rxBuffer1StartAddress + (config->rxBuffer1Size * i));
|
||||
IfxEth_setReceiveBuffer1RingMode(eth, descr, buffer1StartAddress, config->rxBuffer1Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxEth_setReceiveBuffer1RingMode(eth, descr, 0x0, 0);
|
||||
}
|
||||
|
||||
if ((config->rxBufferUsed == IfxEth_RingModeBufferUsed_buffer2) || (config->rxBufferUsed == IfxEth_RingModeBufferUsed_bothBuffers))
|
||||
{
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (config->rxBuffer2Size) % 4 == 0);
|
||||
buffer2StartAddress = (uint32)(config->rxBuffer2StartAddress + (config->rxBuffer2Size * i));
|
||||
IfxEth_setReceiveBuffer2RingMode(eth, descr, buffer2StartAddress, config->rxBuffer2Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxEth_setReceiveBuffer2RingMode(eth, descr, 0x0, 0);
|
||||
}
|
||||
|
||||
descr = &descr[1];
|
||||
}
|
||||
|
||||
/* correction for last descriptor */
|
||||
{
|
||||
descr = &descr[-1];
|
||||
|
||||
/* indicate end of ring */
|
||||
descr->RDES1.A.RER = 1U;
|
||||
|
||||
eth->pRxDescr = IfxEth_getBaseRxDescriptor(eth);
|
||||
}
|
||||
|
||||
eth->rxCount = 0;
|
||||
|
||||
/* write descriptor list base address */
|
||||
IfxEth_setReceiveDescriptorAddress(&MODULE_ETH, IfxEth_getBaseRxDescriptor(eth));
|
||||
|
||||
eth->rxBufferUsed = config->rxBufferUsed;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_initTransmitDescriptors(IfxEth *eth)
|
||||
{
|
||||
int i;
|
||||
IfxEth_TxDescr *descr = IfxEth_getBaseTxDescriptor(eth);
|
||||
|
||||
eth->pTxDescr = descr;
|
||||
|
||||
/* Initialize chained descriptor mode */
|
||||
for (i = 0; i < IFXETH_MAX_TX_BUFFERS; i++)
|
||||
{
|
||||
descr->TDES0.U = 0;
|
||||
descr->TDES0.A.IC = 1U;
|
||||
descr->TDES0.A.FS = 1U;
|
||||
descr->TDES0.A.LS = 1U;
|
||||
descr->TDES0.A.TCH = 1U;
|
||||
|
||||
#ifndef IFXETH_TX_BUFFER_BY_USER
|
||||
IfxEth_TxDescr_setBuffer(descr, &(IfxEth_txBuffer[i][0]));
|
||||
#endif
|
||||
|
||||
/* with TCH set, TDES3 points to next descriptor */
|
||||
descr->TDES3.U = (uint32)&descr[1];
|
||||
descr = &descr[1];
|
||||
}
|
||||
|
||||
/* correction for last descriptor */
|
||||
{
|
||||
descr = &descr[-1];
|
||||
|
||||
/* indicate end of ring */
|
||||
descr->TDES0.A.TER = 1U;
|
||||
|
||||
/* with TCH set, TDES3 points to the first descriptor */
|
||||
eth->pTxDescr = IfxEth_getBaseTxDescriptor(eth);
|
||||
descr->TDES3.U = (uint32)eth->pTxDescr;
|
||||
}
|
||||
|
||||
eth->txCount = 0;
|
||||
|
||||
/* write descriptor list base address */
|
||||
IfxEth_setTransmitDescriptorAddress(&MODULE_ETH, IfxEth_getBaseTxDescriptor(eth));
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_initTransmitDescriptorsRingMode(IfxEth *eth, const IfxEth_RingModeTxBuffersConfig *config)
|
||||
{
|
||||
int i;
|
||||
uint32 buffer1StartAddress = 0;
|
||||
uint32 buffer2StartAddress = 0;
|
||||
|
||||
IfxEth_TxDescr *descr = IfxEth_getBaseTxDescriptor(eth);
|
||||
|
||||
eth->pTxDescr = descr;
|
||||
|
||||
/* Initialize descriptors in ring mode */
|
||||
for (i = 0; i < IFXETH_MAX_TX_BUFFERS; i++)
|
||||
{
|
||||
descr->TDES0.U = 0;
|
||||
descr->TDES0.A.IC = 1U;
|
||||
descr->TDES0.A.FS = 1U;
|
||||
descr->TDES0.A.LS = 1U;
|
||||
|
||||
if ((config->txBufferUsed == IfxEth_RingModeBufferUsed_buffer1) || (config->txBufferUsed == IfxEth_RingModeBufferUsed_bothBuffers))
|
||||
{
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (config->txBuffer1Size) % 4 == 0);
|
||||
|
||||
buffer1StartAddress = (uint32)(config->txBuffer1StartAddress + (config->txBuffer1Size * i));
|
||||
IfxEth_setTransmitBuffer1RingMode(eth, descr, buffer1StartAddress, config->txBuffer1Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxEth_setTransmitBuffer1RingMode(eth, descr, 0x0, 0);
|
||||
}
|
||||
|
||||
if ((config->txBufferUsed == IfxEth_RingModeBufferUsed_buffer2) || (config->txBufferUsed == IfxEth_RingModeBufferUsed_bothBuffers))
|
||||
{
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (config->txBuffer2Size) % 4 == 0);
|
||||
|
||||
buffer2StartAddress = (uint32)(config->txBuffer2StartAddress + (config->txBuffer2Size * i));
|
||||
IfxEth_setTransmitBuffer2RingMode(eth, descr, buffer2StartAddress, config->txBuffer2Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxEth_setTransmitBuffer2RingMode(eth, descr, 0x0, 0);
|
||||
}
|
||||
|
||||
descr = &descr[1];
|
||||
}
|
||||
|
||||
/* correction for last descriptor */
|
||||
{
|
||||
descr = &descr[-1];
|
||||
|
||||
/* indicate end of ring */
|
||||
descr->TDES0.A.TER = 1U;
|
||||
|
||||
eth->pTxDescr = IfxEth_getBaseTxDescriptor(eth);
|
||||
}
|
||||
|
||||
eth->txCount = 0;
|
||||
|
||||
/* write descriptor list base address */
|
||||
IfxEth_setTransmitDescriptorAddress(&MODULE_ETH, IfxEth_getBaseTxDescriptor(eth));
|
||||
|
||||
eth->txBufferUsed = config->txBufferUsed;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_readMacAddress(IfxEth *eth, uint8 *macAddress)
|
||||
{
|
||||
(void)eth;
|
||||
*((uint32 *)macAddress) = ETH_MAC_ADDRESS_G00_LOW.U;
|
||||
*((uint16 *)(&macAddress[4])) = (uint16)(ETH_MAC_ADDRESS_G00_HIGH.U & 0xFFFFU);
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_resetModule(void)
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
|
||||
ETH_KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
|
||||
ETH_KRST1.B.RST = 1;
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
|
||||
while (0 == ETH_KRST0.B.RSTSTAT) /* Wait until reset is executed */
|
||||
{}
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
ETH_KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
|
||||
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_sendTransmitBuffer(IfxEth *eth, uint16 len)
|
||||
{
|
||||
IfxEth_TxDescr *descr = IfxEth_getActualTxDescriptor(eth);
|
||||
|
||||
descr->TDES1.U = len; /* with TCH set, TBS1 is used for buffer size */
|
||||
descr->TDES0.A.OWN = 1U; /* release to DMA */
|
||||
|
||||
IfxEth_wakeupTransmitter(eth);
|
||||
IfxEth_shuffleTxDescriptor(eth);
|
||||
|
||||
eth->txCount++;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_sendTransmitBuffersRingMode(IfxEth *eth, uint16 buffer1Length, uint16 buffer2Length)
|
||||
{
|
||||
IfxEth_TxDescr *descr = IfxEth_getActualTxDescriptor(eth);
|
||||
|
||||
if ((eth->txBufferUsed == IfxEth_RingModeBufferUsed_buffer1) || (eth->txBufferUsed == IfxEth_RingModeBufferUsed_bothBuffers))
|
||||
{
|
||||
descr->TDES1.A.TBS1 = buffer1Length;
|
||||
}
|
||||
|
||||
if ((eth->txBufferUsed == IfxEth_RingModeBufferUsed_buffer2) || (eth->txBufferUsed == IfxEth_RingModeBufferUsed_bothBuffers))
|
||||
{
|
||||
descr->TDES1.A.TBS2 = buffer2Length;
|
||||
}
|
||||
|
||||
descr->TDES0.A.OWN = 1U; /* release to DMA */
|
||||
|
||||
IfxEth_wakeupTransmitter(eth);
|
||||
IfxEth_shuffleTxDescriptor(eth);
|
||||
|
||||
eth->txCount++;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_setAndSendTransmitBuffer(IfxEth *eth, void *buffer, uint16 len)
|
||||
{
|
||||
IfxEth_TxDescr_setBuffer(IfxEth_getActualTxDescriptor(eth), buffer);
|
||||
IfxEth_sendTransmitBuffer(eth, len);
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_setMacAddress(IfxEth *eth, const uint8 *macAddress)
|
||||
{
|
||||
(void)eth;
|
||||
ETH_MAC_ADDRESS_G00_HIGH.U = 0
|
||||
| ((uint32)macAddress[4] << 0U)
|
||||
| ((uint32)macAddress[5] << 8U)
|
||||
| 0x80000000U;
|
||||
|
||||
ETH_MAC_ADDRESS_G00_LOW.U = 0
|
||||
| ((uint32)macAddress[0] << 0U)
|
||||
| ((uint32)macAddress[1] << 8U)
|
||||
| ((uint32)macAddress[2] << 16U)
|
||||
| ((uint32)macAddress[3] << 24U)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_setupChecksumEngine(IfxEth *eth, IfxEth_ChecksumMode mode)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (mode != IfxEth_ChecksumMode_bypass)
|
||||
{
|
||||
ETH_OPERATION_MODE.B.TSF = 1U;
|
||||
ETH_OPERATION_MODE.B.DT = 0U; /* 0 = drop TCP/IP frame with checksum error */
|
||||
ETH_MAC_CONFIGURATION.B.IPC = 1U; /* 1 = enable received IP frame checksum engine */
|
||||
|
||||
IfxEth_TxDescr *descr = IfxEth_getBaseTxDescriptor(eth);
|
||||
|
||||
for (i = 0; i < IFXETH_MAX_TX_BUFFERS; i++)
|
||||
{
|
||||
descr->TDES0.A.CIC = mode;
|
||||
descr = IfxEth_TxDescr_getNext(descr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_setupMiiInputPins(IfxEth *eth, const IfxEth_MiiPins *miiPins)
|
||||
{
|
||||
(void)eth;
|
||||
|
||||
IfxPort_InputMode mode = IfxPort_InputMode_noPullDevice;
|
||||
IfxPort_PadDriver speedGrade = IfxPort_PadDriver_cmosAutomotiveSpeed1;
|
||||
|
||||
if (miiPins->crs != NULL_PTR)
|
||||
{
|
||||
IfxEth_Crs_In *crs = miiPins->crs;
|
||||
ETH_GPCTL.B.ALTI2 = crs->select;
|
||||
IfxPort_setPinModeInput(crs->pin.port, crs->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(crs->pin.port, crs->pin.pinIndex, speedGrade);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MII lite mode */
|
||||
ETH_GPCTL.B.ALTI2 = Ifx_RxSel_d;
|
||||
}
|
||||
|
||||
if (miiPins->col != NULL_PTR)
|
||||
{
|
||||
IfxEth_Col_In *col = miiPins->col;
|
||||
ETH_GPCTL.B.ALTI3 = col->select;
|
||||
IfxPort_setPinModeInput(col->pin.port, col->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(col->pin.port, col->pin.pinIndex, speedGrade);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MII lite mode */
|
||||
ETH_GPCTL.B.ALTI3 = Ifx_RxSel_d;
|
||||
}
|
||||
|
||||
IfxEth_Txclk_In *txClk = miiPins->txClk;
|
||||
ETH_GPCTL.B.ALTI10 = txClk->select;
|
||||
IfxPort_setPinModeInput(txClk->pin.port, txClk->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(txClk->pin.port, txClk->pin.pinIndex, speedGrade);
|
||||
|
||||
IfxEth_Rxclk_In *rxClk = miiPins->rxClk;
|
||||
ETH_GPCTL.B.ALTI1 = rxClk->select;
|
||||
IfxPort_setPinModeInput(rxClk->pin.port, rxClk->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(rxClk->pin.port, rxClk->pin.pinIndex, speedGrade);
|
||||
|
||||
IfxEth_Rxdv_In *rxDv = miiPins->rxDv;
|
||||
ETH_GPCTL.B.ALTI4 = rxDv->select;
|
||||
IfxPort_setPinModeInput(rxDv->pin.port, rxDv->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(rxDv->pin.port, rxDv->pin.pinIndex, speedGrade);
|
||||
|
||||
if (miiPins->rxEr != NULL_PTR)
|
||||
{
|
||||
IfxEth_Rxer_In *rxEr = miiPins->rxEr;
|
||||
ETH_GPCTL.B.ALTI5 = rxEr->select;
|
||||
IfxPort_setPinModeInput(rxEr->pin.port, rxEr->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(rxEr->pin.port, rxEr->pin.pinIndex, speedGrade);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MII lite mode */
|
||||
ETH_GPCTL.B.ALTI5 = Ifx_RxSel_d;
|
||||
}
|
||||
|
||||
IfxEth_Rxd_In *rxd0 = miiPins->rxd0;
|
||||
ETH_GPCTL.B.ALTI6 = rxd0->select;
|
||||
IfxPort_setPinModeInput(rxd0->pin.port, rxd0->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(rxd0->pin.port, rxd0->pin.pinIndex, speedGrade);
|
||||
|
||||
IfxEth_Rxd_In *rxd1 = miiPins->rxd1;
|
||||
ETH_GPCTL.B.ALTI7 = rxd1->select;
|
||||
IfxPort_setPinModeInput(rxd1->pin.port, rxd1->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(rxd1->pin.port, rxd1->pin.pinIndex, speedGrade);
|
||||
|
||||
IfxEth_Rxd_In *rxd2 = miiPins->rxd2;
|
||||
ETH_GPCTL.B.ALTI8 = rxd2->select;
|
||||
IfxPort_setPinModeInput(rxd2->pin.port, rxd2->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(rxd2->pin.port, rxd2->pin.pinIndex, speedGrade);
|
||||
|
||||
IfxEth_Rxd_In *rxd3 = miiPins->rxd3;
|
||||
ETH_GPCTL.B.ALTI9 = rxd3->select;
|
||||
IfxPort_setPinModeInput(rxd3->pin.port, rxd3->pin.pinIndex, mode);
|
||||
IfxPort_setPinPadDriver(rxd3->pin.port, rxd3->pin.pinIndex, speedGrade);
|
||||
|
||||
IfxEth_Mdio_InOut *mdio = miiPins->mdio;
|
||||
ETH_GPCTL.B.ALTI0 = mdio->inSelect;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_setupMiiOutputPins(IfxEth *eth, const IfxEth_MiiPins *miiPins)
|
||||
{
|
||||
(void)eth;
|
||||
IfxPort_OutputMode mode = IfxPort_OutputMode_pushPull;
|
||||
IfxPort_PadDriver speedGrade = IfxPort_PadDriver_cmosAutomotiveSpeed1;
|
||||
|
||||
IfxEth_Txen_Out *txEn = miiPins->txEn;
|
||||
IfxPort_setPinPadDriver(txEn->pin.port, txEn->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinModeOutput(txEn->pin.port, txEn->pin.pinIndex, mode, txEn->select);
|
||||
|
||||
if (miiPins->txEr != NULL_PTR)
|
||||
{
|
||||
IfxEth_Txer_Out *txEr = miiPins->txEr;
|
||||
IfxPort_setPinPadDriver(txEr->pin.port, txEr->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinModeOutput(txEr->pin.port, txEr->pin.pinIndex, mode, txEr->select);
|
||||
}
|
||||
|
||||
IfxEth_Txd_Out *txd0 = miiPins->txd0;
|
||||
IfxPort_setPinPadDriver(txd0->pin.port, txd0->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinModeOutput(txd0->pin.port, txd0->pin.pinIndex, mode, txd0->select);
|
||||
|
||||
IfxEth_Txd_Out *txd1 = miiPins->txd1;
|
||||
IfxPort_setPinPadDriver(txd1->pin.port, txd1->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinModeOutput(txd1->pin.port, txd1->pin.pinIndex, mode, txd1->select);
|
||||
|
||||
IfxEth_Txd_Out *txd2 = miiPins->txd2;
|
||||
IfxPort_setPinPadDriver(txd2->pin.port, txd2->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinModeOutput(txd2->pin.port, txd2->pin.pinIndex, mode, txd2->select);
|
||||
|
||||
IfxEth_Txd_Out *txd3 = miiPins->txd3;
|
||||
IfxPort_setPinPadDriver(txd3->pin.port, txd3->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinModeOutput(txd3->pin.port, txd3->pin.pinIndex, mode, txd3->select);
|
||||
|
||||
IfxEth_Mdc_Out *mdc = miiPins->mdc;
|
||||
IfxPort_setPinPadDriver(mdc->pin.port, mdc->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinModeOutput(mdc->pin.port, mdc->pin.pinIndex, mode, mdc->select);
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_setupRmiiInputPins(IfxEth *eth, const IfxEth_RmiiPins *rmiiPins)
|
||||
{
|
||||
(void)eth;
|
||||
|
||||
ETH_GPCTL.B.ALTI0 = rmiiPins->mdio->inSelect;
|
||||
ETH_GPCTL.B.ALTI1 = rmiiPins->refClk->select;
|
||||
ETH_GPCTL.B.ALTI4 = rmiiPins->crsDiv->select;
|
||||
ETH_GPCTL.B.ALTI6 = rmiiPins->rxd0->select;
|
||||
ETH_GPCTL.B.ALTI7 = rmiiPins->rxd1->select;
|
||||
|
||||
{
|
||||
IfxPort_InputMode mode = IfxPort_InputMode_noPullDevice;
|
||||
IfxPort_PadDriver speedGrade = IfxPort_PadDriver_cmosAutomotiveSpeed1;
|
||||
|
||||
IfxEth_Crsdv_In *crsDiv = rmiiPins->crsDiv;
|
||||
IfxEth_Refclk_In *refClk = rmiiPins->refClk;
|
||||
IfxEth_Rxd_In *rxd0 = rmiiPins->rxd0;
|
||||
IfxEth_Rxd_In *rxd1 = rmiiPins->rxd1;
|
||||
|
||||
IfxPort_setPinModeInput(crsDiv->pin.port, crsDiv->pin.pinIndex, mode);
|
||||
IfxPort_setPinModeInput(refClk->pin.port, refClk->pin.pinIndex, mode);
|
||||
IfxPort_setPinModeInput(rxd0->pin.port, rxd0->pin.pinIndex, mode);
|
||||
IfxPort_setPinModeInput(rxd1->pin.port, rxd1->pin.pinIndex, mode);
|
||||
|
||||
IfxPort_setPinPadDriver(crsDiv->pin.port, crsDiv->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinPadDriver(refClk->pin.port, refClk->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinPadDriver(rxd0->pin.port, rxd0->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinPadDriver(rxd1->pin.port, rxd1->pin.pinIndex, speedGrade);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_setupRmiiOutputPins(IfxEth *eth, const IfxEth_RmiiPins *rmiiPins)
|
||||
{
|
||||
IfxPort_OutputMode mode = IfxPort_OutputMode_pushPull;
|
||||
IfxPort_PadDriver speedGrade = IfxPort_PadDriver_cmosAutomotiveSpeed1;
|
||||
|
||||
IfxEth_Mdc_Out *mdc = rmiiPins->mdc;
|
||||
IfxEth_Mdio_InOut *mdio = rmiiPins->mdio;
|
||||
IfxEth_Txen_Out *txen = rmiiPins->txEn;
|
||||
IfxEth_Txd_Out *txd0 = rmiiPins->txd0;
|
||||
IfxEth_Txd_Out *txd1 = rmiiPins->txd1;
|
||||
|
||||
(void)eth;
|
||||
|
||||
#if 0
|
||||
IfxPort_setPinPadDriver(mdc->pin.port, mdc->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinPadDriver(mdio->pin.port, mdio->pin.pinIndex, speedGrade);
|
||||
#endif
|
||||
IfxPort_setPinPadDriver(txen->pin.port, txen->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinPadDriver(txd0->pin.port, txd0->pin.pinIndex, speedGrade);
|
||||
IfxPort_setPinPadDriver(txd1->pin.port, txd1->pin.pinIndex, speedGrade);
|
||||
|
||||
IfxPort_setPinModeOutput(mdc->pin.port, mdc->pin.pinIndex, mode, mdc->select);
|
||||
IfxPort_setPinModeOutput(txen->pin.port, txen->pin.pinIndex, mode, txen->select);
|
||||
IfxPort_setPinModeOutput(txd0->pin.port, txd0->pin.pinIndex, mode, txd0->select);
|
||||
IfxPort_setPinModeOutput(txd1->pin.port, txd1->pin.pinIndex, mode, txd1->select);
|
||||
|
||||
// For MDIO, when P21.1 is used it should be configured as output
|
||||
if ((mdio->pin.port == (&MODULE_P21)) && (mdio->pin.pinIndex == 1))
|
||||
{
|
||||
IfxPort_setPinModeOutput(mdio->pin.port, mdio->pin.pinIndex, mode, mdio->outSelect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_shuffleRxDescriptor(IfxEth *eth)
|
||||
{
|
||||
if (eth->descriptorMode == IfxEth_DescriptorMode_chain)
|
||||
{
|
||||
eth->pRxDescr = IfxEth_RxDescr_getNext(eth->pRxDescr);
|
||||
}
|
||||
else if ((eth->descriptorMode == IfxEth_DescriptorMode_ring) && (eth->pRxDescr->RDES1.A.RER != 1))
|
||||
{
|
||||
eth->pRxDescr = ð->pRxDescr[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
eth->pRxDescr = IfxEth_getBaseRxDescriptor(eth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_shuffleTxDescriptor(IfxEth *eth)
|
||||
{
|
||||
if (eth->descriptorMode == IfxEth_DescriptorMode_chain)
|
||||
{
|
||||
eth->pTxDescr = IfxEth_TxDescr_getNext(eth->pTxDescr);
|
||||
}
|
||||
else if ((eth->descriptorMode == IfxEth_DescriptorMode_ring) && (eth->pTxDescr->TDES0.A.TER != 1))
|
||||
{
|
||||
eth->pTxDescr = ð->pTxDescr[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
eth->pTxDescr = IfxEth_getBaseTxDescriptor(eth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_startReceiver(IfxEth *eth)
|
||||
{
|
||||
(void)eth;
|
||||
|
||||
// enable receiver and RX DMA
|
||||
ETH_OPERATION_MODE.B.SR = 1;
|
||||
ETH_MAC_CONFIGURATION.B.RE = 1;
|
||||
ETH_RECEIVE_POLL_DEMAND.U = 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_startTransmitter(IfxEth *eth)
|
||||
{
|
||||
(void)eth;
|
||||
|
||||
ETH_MAC_CONFIGURATION.B.TE = 1;
|
||||
ETH_OPERATION_MODE.B.ST = 1;
|
||||
ETH_TRANSMIT_POLL_DEMAND.U = 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_stopReceiver(IfxEth *eth)
|
||||
{
|
||||
(void)eth;
|
||||
|
||||
ETH_OPERATION_MODE.B.SR = 0;
|
||||
ETH_MAC_CONFIGURATION.B.RE = 0;
|
||||
ETH_RECEIVE_POLL_DEMAND.U = 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_stopTransmitter(IfxEth *eth)
|
||||
{
|
||||
(void)eth;
|
||||
|
||||
ETH_TRANSMIT_POLL_DEMAND.U = 0;
|
||||
ETH_OPERATION_MODE.B.ST = 0;
|
||||
ETH_MAC_CONFIGURATION.B.TE = 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_wakeupReceiver(IfxEth *eth)
|
||||
{
|
||||
eth->status.U = ETH_STATUS.U;
|
||||
|
||||
// check if receiver suspended
|
||||
if (eth->status.U & (4U << IFX_ETH_STATUS_RS_OFF))
|
||||
{
|
||||
if (eth->status.B.RU)
|
||||
{
|
||||
ETH_STATUS.U = (IFX_ETH_STATUS_RU_MSK << IFX_ETH_STATUS_RU_OFF);
|
||||
}
|
||||
|
||||
IfxEth_startReceiver(eth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_wakeupTransmitter(IfxEth *eth)
|
||||
{
|
||||
eth->status.U = ETH_STATUS.U;
|
||||
|
||||
// check if suspended
|
||||
if (eth->status.U & 0x00600000)
|
||||
{
|
||||
if (eth->status.B.TU)
|
||||
{
|
||||
// clear transmit unavailable and underflow flags
|
||||
ETH_STATUS.U = (IFX_ETH_STATUS_TU_MSK << IFX_ETH_STATUS_TU_OFF) |
|
||||
(IFX_ETH_STATUS_UNF_MSK << IFX_ETH_STATUS_UNF_OFF);
|
||||
}
|
||||
|
||||
IfxEth_startTransmitter(eth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxEth_writeHeader(IfxEth *eth, uint8 *txBuffer, uint8 *destinationAddress, uint8 *sourceAddress, uint32 packetSize)
|
||||
{
|
||||
(void)eth;
|
||||
uint32 i;
|
||||
|
||||
/* Destination Address */
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
*txBuffer++ = *destinationAddress++;
|
||||
}
|
||||
|
||||
/* Source Address */
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
*txBuffer++ = *sourceAddress++;
|
||||
}
|
||||
|
||||
/* packet size */
|
||||
*txBuffer++ = (uint8)(packetSize / 256);
|
||||
*txBuffer = (uint8)(packetSize % 256);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
* \file IfxFce_Crc.c
|
||||
* \brief FCE CRC details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxFce_Crc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint16 IfxFce_Crc_calculateCrc16(IfxFce_Crc_Crc *fce, const uint16 *crcData, uint32 crcDataLength, uint16 crcStartValue)
|
||||
{
|
||||
Ifx_FCE *fceSFR = fce->fce;
|
||||
uint32 inputDataCounter;
|
||||
uint16 crcResultValue;
|
||||
uint16 *dataPtr = (uint16 *)crcData;
|
||||
|
||||
fceSFR->IN2.CHECK.U = 0xFACECAFE;
|
||||
fceSFR->IN2.LENGTH.U = 0xFACECAFE;
|
||||
fceSFR->IN2.CHECK.U = (uint16)fce->expectedCrc;
|
||||
fceSFR->IN2.LENGTH.U = crcDataLength;
|
||||
|
||||
/*Configure CRC register*/
|
||||
fceSFR->IN2.CRC.U = crcStartValue;
|
||||
{
|
||||
/*Code for CRC-16 calculaion with 0x1021 polynomial*/
|
||||
for (inputDataCounter = 0; inputDataCounter < crcDataLength; inputDataCounter++)
|
||||
{
|
||||
fceSFR->IN2.IR.U = *(dataPtr++);
|
||||
}
|
||||
}
|
||||
|
||||
crcResultValue = (uint16)fceSFR->IN2.RES.U;
|
||||
|
||||
return crcResultValue;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxFce_Crc_calculateCrc32(IfxFce_Crc_Crc *fce, const uint32 *crcData, uint32 crcDataLength, uint32 crcStartValue)
|
||||
{
|
||||
Ifx_FCE *fceSFR = fce->fce;
|
||||
uint32 inputDataCounter;
|
||||
uint32 crcResultValue;
|
||||
uint32 *dataPtr = (uint32 *)crcData;
|
||||
volatile uint32 *inPtr;
|
||||
|
||||
/*Crc-32 calculaion with 0x04C11DB7 polynomial*/
|
||||
if (fce->crc32Kernel == IfxFce_Crc32Kernel_0)
|
||||
{
|
||||
fceSFR->IN0.CHECK.U = 0xFACECAFE;
|
||||
fceSFR->IN0.LENGTH.U = 0xFACECAFE;
|
||||
fceSFR->IN0.CHECK.U = fce->expectedCrc;
|
||||
fceSFR->IN0.LENGTH.U = crcDataLength;
|
||||
fceSFR->IN0.CRC.U = crcStartValue;
|
||||
|
||||
inPtr = (volatile uint32 *)&fceSFR->IN0.IR.U;
|
||||
}
|
||||
else
|
||||
{
|
||||
fceSFR->IN1.CHECK.U = 0xFACECAFE;
|
||||
fceSFR->IN1.LENGTH.U = 0xFACECAFE;
|
||||
fceSFR->IN1.CHECK.U = fce->expectedCrc;
|
||||
fceSFR->IN1.LENGTH.U = crcDataLength;
|
||||
fceSFR->IN1.CRC.U = crcStartValue;
|
||||
|
||||
inPtr = (volatile uint32 *)&fceSFR->IN1.IR.U;
|
||||
}
|
||||
|
||||
{
|
||||
for (inputDataCounter = 0; inputDataCounter < crcDataLength; inputDataCounter++)
|
||||
{
|
||||
*inPtr = *(dataPtr++);
|
||||
}
|
||||
}
|
||||
|
||||
if (fce->crc32Kernel == IfxFce_Crc32Kernel_0)
|
||||
{
|
||||
crcResultValue = fceSFR->IN0.RES.U;
|
||||
}
|
||||
else
|
||||
{
|
||||
crcResultValue = fceSFR->IN1.RES.U;
|
||||
}
|
||||
|
||||
return crcResultValue;
|
||||
}
|
||||
|
||||
|
||||
uint8 IfxFce_Crc_calculateCrc8(IfxFce_Crc_Crc *fce, const uint8 *crcData, uint32 crcDataLength, uint8 crcStartValue)
|
||||
{
|
||||
Ifx_FCE *fceSFR = fce->fce;
|
||||
uint32 inputDataCounter;
|
||||
uint8 crcResultValue;
|
||||
uint8 *dataPtr = (uint8 *)crcData;
|
||||
|
||||
fceSFR->IN3.CHECK.U = 0xFACECAFE;
|
||||
fceSFR->IN3.LENGTH.U = 0xFACECAFE;
|
||||
fceSFR->IN3.CHECK.U = (uint8)fce->expectedCrc;
|
||||
fceSFR->IN3.LENGTH.U = crcDataLength;
|
||||
|
||||
/*Configure CRC register*/
|
||||
fceSFR->IN3.CRC.U = crcStartValue;
|
||||
|
||||
/*Code for CRC-8 calculaion for 0x1D polynomials*/
|
||||
{
|
||||
/* input in INIT register */
|
||||
for (inputDataCounter = 0; inputDataCounter < crcDataLength; ++inputDataCounter)
|
||||
{
|
||||
fceSFR->IN3.IR.U = *(dataPtr++);
|
||||
}
|
||||
}
|
||||
crcResultValue = (uint8)fceSFR->IN3.RES.U;
|
||||
|
||||
return crcResultValue;
|
||||
}
|
||||
|
||||
|
||||
void IfxFce_Crc_clearErrorFlags(IfxFce_Crc_Crc *fce)
|
||||
{
|
||||
if (fce->crcMode == IfxFce_CrcMode_8)
|
||||
{
|
||||
IfxFce_clearCrc8ErrorFlags(fce->fce);
|
||||
}
|
||||
else if (fce->crcMode == IfxFce_CrcMode_16)
|
||||
{
|
||||
IfxFce_clearCrc16ErrorFlags(fce->fce);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxFce_clearCrc32ErrorFlags(fce->fce, fce->crc32Kernel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxFce_Crc_deInitModule(IfxFce_Crc_Crc *fce)
|
||||
{
|
||||
IfxFce_resetModule(fce->fce);
|
||||
}
|
||||
|
||||
|
||||
Ifx_FCE_STS IfxFce_Crc_getInterruptStatus(IfxFce_Crc_Crc *fce)
|
||||
{
|
||||
if (fce->crcMode == IfxFce_CrcMode_8)
|
||||
{
|
||||
return IfxFce_getCrc8InterruptStatus(fce->fce);
|
||||
}
|
||||
else if (fce->crcMode == IfxFce_CrcMode_16)
|
||||
{
|
||||
return IfxFce_getCrc16InterruptStatus(fce->fce);
|
||||
}
|
||||
else
|
||||
{
|
||||
return IfxFce_getCrc32InterruptStatus(fce->fce, fce->crc32Kernel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxFce_Crc_initCrc(IfxFce_Crc_Crc *fceCrc, const IfxFce_Crc_CrcConfig *crcConfig)
|
||||
{
|
||||
fceCrc->fce = crcConfig->fce;
|
||||
Ifx_FCE *fceSFR = crcConfig->fce;
|
||||
|
||||
fceCrc->crcMode = crcConfig->crcMode;
|
||||
fceCrc->expectedCrc = crcConfig->expectedCrc;
|
||||
|
||||
uint16 password = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(password);
|
||||
|
||||
Ifx_FCE_CFG tempCFG;
|
||||
tempCFG.U = 0;
|
||||
tempCFG.B.CMI = crcConfig->enabledInterrupts.crcMismatch;
|
||||
tempCFG.B.CEI = crcConfig->enabledInterrupts.configError;
|
||||
tempCFG.B.LEI = crcConfig->enabledInterrupts.lengthError;
|
||||
tempCFG.B.BEI = crcConfig->enabledInterrupts.busError;
|
||||
tempCFG.B.CCE = crcConfig->crcCheckCompared;
|
||||
tempCFG.B.ALR = crcConfig->automaticLengthReload;
|
||||
tempCFG.B.REFIN = crcConfig->dataByteReflectionEnabled;
|
||||
tempCFG.B.REFOUT = crcConfig->crc32BitReflectionEnabled;
|
||||
tempCFG.B.XSEL = crcConfig->crcResultInverted;
|
||||
|
||||
if (crcConfig->crcMode == IfxFce_CrcMode_8)
|
||||
{
|
||||
fceSFR->IN3.CFG.U = tempCFG.U;
|
||||
}
|
||||
else if (crcConfig->crcMode == IfxFce_CrcMode_16)
|
||||
{
|
||||
fceSFR->IN2.CFG.U = tempCFG.U;
|
||||
}
|
||||
else
|
||||
{
|
||||
fceCrc->crc32Kernel = crcConfig->crc32Kernel;
|
||||
|
||||
if (crcConfig->crc32Kernel == IfxFce_Crc32Kernel_0)
|
||||
{
|
||||
fceSFR->IN0.CFG.U = tempCFG.U;
|
||||
}
|
||||
else
|
||||
{
|
||||
fceSFR->IN1.CFG.U = tempCFG.U;
|
||||
}
|
||||
}
|
||||
|
||||
IfxScuWdt_setCpuEndinit(password);
|
||||
}
|
||||
|
||||
|
||||
void IfxFce_Crc_initCrcConfig(IfxFce_Crc_CrcConfig *crcConfig, IfxFce_Crc *fce)
|
||||
{
|
||||
crcConfig->fce = fce->fce;
|
||||
crcConfig->crcMode = IfxFce_CrcMode_32;
|
||||
crcConfig->crcCheckCompared = TRUE;
|
||||
crcConfig->automaticLengthReload = FALSE;
|
||||
crcConfig->dataByteReflectionEnabled = TRUE;
|
||||
crcConfig->crc32BitReflectionEnabled = TRUE;
|
||||
crcConfig->crcResultInverted = TRUE;
|
||||
crcConfig->enabledInterrupts.crcMismatch = FALSE; // enable if CRC is already known
|
||||
crcConfig->enabledInterrupts.configError = TRUE;
|
||||
crcConfig->enabledInterrupts.lengthError = TRUE;
|
||||
crcConfig->enabledInterrupts.busError = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxFce_Crc_initModule(IfxFce_Crc *fce, const IfxFce_Crc_Config *config)
|
||||
{
|
||||
fce->fce = config->fce;
|
||||
Ifx_FCE *fceSFR = config->fce;
|
||||
|
||||
IfxFce_enableModule(fceSFR);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src = IfxFce_getSrcPointer(fceSFR);
|
||||
IfxSrc_init(src, config->isrTypeOfService, config->isrPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
|
||||
void IfxFce_Crc_initModuleConfig(IfxFce_Crc_Config *config, Ifx_FCE *fce)
|
||||
{
|
||||
config->fce = fce;
|
||||
config->isrPriority = 0;
|
||||
config->isrTypeOfService = IfxSrc_Tos_cpu0;
|
||||
}
|
||||
@@ -0,0 +1,565 @@
|
||||
/**
|
||||
* \file IfxFce_Crc.h
|
||||
* \brief FCE CRC details
|
||||
* \ingroup IfxLld_Fce
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Fce_Crc_Usage How to use the FCE CRC Interface driver?
|
||||
* \ingroup IfxLld_Fce
|
||||
*
|
||||
*
|
||||
*
|
||||
* FCE gives CRC-x(x= 8,16,32) message signatures. Kernel 3 is used for CRC-8,Kernel 2 is used for CRC-16,Kernel 0 1nd Kernel 1 is used for CRC-32.
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
* \section IfxLld_Fce_Fce_Preparation Preparation
|
||||
* \subsection IfxLld_Fce_Fce_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
*
|
||||
* \code
|
||||
* #include <Fce/Crc/IfxFce_Crc.h>
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Fce_Crc_Variables Variables
|
||||
*
|
||||
* Declare the FCE and CRC handles as global variable in your C code:
|
||||
* \code
|
||||
* // used globally
|
||||
* static IfxFce_Crc fce;
|
||||
* static IfxFce_Crc_Crc fceCrc32_0;
|
||||
* static IfxFce_Crc_Crc fceCrc32_1;
|
||||
* static IfxFce_Crc_Crc fceCrc16;
|
||||
* static IfxFce_Crc_Crc fceCrc8;
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Fce_Crc_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priorities for the Interrrupt handler. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define IFX_INTPRIO_FCE 1
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routine to your C code which should do the error flag handling:
|
||||
* \code
|
||||
* IFX_INTERRUPT(fceISR, 0, IFX_INTPRIO_FCE)
|
||||
* {
|
||||
* {
|
||||
* Ifx_FCE_STS interruptStatus = IfxFce_Crc_getInterruptStatus(&fceCrc32_0);
|
||||
* if (interruptStatus.U )
|
||||
* {
|
||||
* if ( interruptStatus.B.CMF == 1)
|
||||
* {
|
||||
* // CRC Mismatch Error...!
|
||||
* }
|
||||
* if( interruptStatus.B.CEF == 1)
|
||||
* {
|
||||
* // Configuration Error...!
|
||||
* }
|
||||
* if ( interruptStatus.B.LEF == 1)
|
||||
* {
|
||||
* // Length Error...!
|
||||
* }
|
||||
* if ( interruptStatus.B.BEF == 1)
|
||||
* {
|
||||
* // Bus Error...!
|
||||
* }
|
||||
* }
|
||||
* IfxFce_Crc_clearErrorFlags(&fceCrc32_0);
|
||||
* }
|
||||
*
|
||||
* {
|
||||
* Ifx_FCE_STS interruptStatus = IfxFce_Crc_getInterruptStatus(&fceCrc32_1);
|
||||
* if (interruptStatus.U )
|
||||
* {
|
||||
* if ( interruptStatus.B.CMF == 1)
|
||||
* {
|
||||
* // CRC Mismatch Error...!
|
||||
* }
|
||||
* if( interruptStatus.B.CEF == 1)
|
||||
* {
|
||||
* // Configuration Error...!
|
||||
* }
|
||||
* if ( interruptStatus.B.LEF == 1)
|
||||
* {
|
||||
* // Length Error...!
|
||||
* }
|
||||
* if ( interruptStatus.B.BEF == 1)
|
||||
* {
|
||||
* // Bus Error...!
|
||||
* }
|
||||
* }
|
||||
* IfxFce_Crc_clearErrorFlags(&fceCrc32_1);
|
||||
* }
|
||||
*
|
||||
* {
|
||||
* Ifx_FCE_STS interruptStatus = IfxFce_Crc_getInterruptStatus(&fceCrc16);
|
||||
* if (interruptStatus.U )
|
||||
* {
|
||||
* if ( interruptStatus.B.CMF == 1)
|
||||
* {
|
||||
* // CRC Mismatch Error...!
|
||||
* }
|
||||
* if( interruptStatus.B.CEF == 1)
|
||||
* {
|
||||
* // Configuration Error...!
|
||||
* }
|
||||
* if ( interruptStatus.B.LEF == 1)
|
||||
* {
|
||||
* // Length Error...!
|
||||
* }
|
||||
* if ( interruptStatus.B.BEF == 1)
|
||||
* {
|
||||
* // Bus Error...!
|
||||
* }
|
||||
* }
|
||||
* IfxFce_Crc_clearErrorFlags(&fceCrc16);
|
||||
* }
|
||||
*
|
||||
* {
|
||||
* Ifx_FCE_STS interruptStatus = IfxFce_Crc_getInterruptStatus(&fceCrc8);
|
||||
* if (interruptStatus.U )
|
||||
* {
|
||||
* if ( interruptStatus.B.CMF == 1)
|
||||
* {
|
||||
* // CRC Mismatch Error...!
|
||||
* }
|
||||
* if( interruptStatus.B.CEF == 1)
|
||||
* {
|
||||
* // Configuration Error...!
|
||||
* }
|
||||
* if ( interruptStatus.B.LEF == 1)
|
||||
* {
|
||||
* // Length Error...!
|
||||
* }
|
||||
* if ( interruptStatus.B.BEF == 1)
|
||||
* {
|
||||
* // Bus Error...!
|
||||
* }
|
||||
* }
|
||||
* IfxFce_Crc_clearErrorFlags(&fceCrc8);
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handler in your initialisation function:
|
||||
* \code
|
||||
* // install interrupt handler
|
||||
* IfxCpu_Irq_installInterruptHandler(fceISR, IFX_INTPRIO_FCE);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Fce_Fce_InitCrc Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function. Here an example for all CRC kernels:
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxFce_Crc_Config fceConfig;
|
||||
* IfxFce_Crc_initModuleConfig(&fceConfig, &MODULE_FCE0);
|
||||
*
|
||||
* // ISR priorities and interrupt target
|
||||
* fceConfig.isrPriority = IFX_INTPRIO_FCE;
|
||||
* fceConfig.isrTypeOfService = IfxCpu_Irq_getTos( IfxCpu_getCoreIndex());
|
||||
*
|
||||
* // initialize module
|
||||
* //IfxFce_Crc fce; // defined globally
|
||||
* IfxFce_Crc_initModule(&fce, &fceConfig);
|
||||
*
|
||||
* // initialize CRC kernels
|
||||
* IfxFce_Crc_CrcConfig crcConfig;
|
||||
* IfxFce_Crc_initCrcConfig(&crcConfig, &fce);
|
||||
*
|
||||
* //IfxFce_Crc_Crc fceCrc32_0; // defined globally
|
||||
* IfxFce_Crc_initCrc(&fceCrc32_0, &crcConfig);
|
||||
* //IfxFce_Crc_Crc fceCrc32_1; // defined globally
|
||||
* crcConfig.crc32Kernel = IfxFce_Crc32Kernel_1;
|
||||
*
|
||||
*
|
||||
* IfxFce_Crc_initCrc(&fceCrc32_1, &crcConfig);
|
||||
* crcConfig.crc32Kernel = IfxFce_Crc32Kernel_0;
|
||||
*
|
||||
* //IfxFce_Crc_Crc fceCrc16; // defined globally
|
||||
* crcConfig.crcMode = IfxFce_CrcMode_16;
|
||||
* IfxFce_Crc_initCrc(&fceCrc16, &crcConfig);
|
||||
*
|
||||
* //IfxFce_Crc_Crc fceCrc8; // defined globally
|
||||
* crcConfig.crcMode = IfxFce_CrcMode_8;
|
||||
* crcConfig.useDma = TRUE; // Enable Dma transfer
|
||||
* crcConfig.fceChannelId = IfxDma_ChannelId_0;
|
||||
* IfxFce_Crc_initCrc(&fceCrc8, &crcConfig);
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* \subsection IfxLld_Fce_Fce_ErrorIRQ Error Interrupt on CRC mismatch
|
||||
*
|
||||
* By default, all error interrupts aside from the CRC mismatch interrupt (CMF) are enabled.
|
||||
*
|
||||
* In order to use the CMF interrupt as well, the appr. error flag has to be enabled during configuration:
|
||||
* \code
|
||||
* // initialize CRC kernel with CRC check enabled
|
||||
* IfxFce_Crc_CrcConfig crcConfig;
|
||||
* IfxFce_Crc_initCrcConfig(&crcConfig, &fce);
|
||||
* crcConfig.enabledInterrupts.crcMismatch = TRUE;
|
||||
* IfxFce_Crc_initCrc(&fceCrc32_0, &crcConfig);
|
||||
* \endcode
|
||||
*
|
||||
* And the expected CRC value has to be written into the expectedCrc field of the handle before the CRC calculation is started.
|
||||
*
|
||||
* \code
|
||||
* {
|
||||
* // Expected CRC:
|
||||
* fceCrc32_0.expectedCrc = 0xd95def75;
|
||||
*
|
||||
* // do calculation
|
||||
* uint32 fceCrc = IfxFce_Crc_calculateCrc32(&fceCrc32_0, checkData, CHECK_DATA_SIZE, 0x00000000);
|
||||
*
|
||||
* // we can expect, that an error interrupt has been triggered if the CRC over checkData didn't match.
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Fce_Fce_calculateCrc CRC Calculation
|
||||
*
|
||||
* Now, all 4 FCE kernels are configured and can be used to calculate CRC values.
|
||||
*
|
||||
* In following examples, CRC is calculated over following array:
|
||||
* \code
|
||||
* #define CHECK_DATA_SIZE 25 // declare this portion globally
|
||||
* // if Dma is enabled, align memory to 32 byte
|
||||
* uint32 checkData[CHECK_DATA_SIZE] = {
|
||||
* 0xbe9957bb,
|
||||
* 0x1c706c1e,
|
||||
* 0x14c3db3f,
|
||||
* 0x7fb17a93,
|
||||
* 0xb0d9d5a7,
|
||||
* 0x768093e0,
|
||||
* 0x88b206a0,
|
||||
* 0xc51299e4,
|
||||
* 0xe8a97d48,
|
||||
* 0x89367f27,
|
||||
* 0x70095984,
|
||||
* 0xec030f75,
|
||||
* 0xdc22f8d4,
|
||||
* 0xd951407b,
|
||||
* 0x34ae18c6,
|
||||
* 0x4d47ba7d,
|
||||
* 0x0e2e4622,
|
||||
* 0x4a2e90d3,
|
||||
* 0xdaec3752,
|
||||
* 0xcd3ed11c,
|
||||
* 0x36b416b7,
|
||||
* 0x8ea28658,
|
||||
* 0xdd37eee3,
|
||||
* 0x23928b62,
|
||||
* 0x84eb4b22,
|
||||
* };
|
||||
* \endcode
|
||||
*
|
||||
* Function calls:
|
||||
* \code
|
||||
* // Common usage:
|
||||
* {
|
||||
* uint32 fceCrc = IfxFce_Crc_calculateCrc32(&fceCrc32_0, checkData, CHECK_DATA_SIZE, 0x00000000);
|
||||
*
|
||||
* // -> CRC32 will be 0xd95def75
|
||||
* }
|
||||
*
|
||||
* // Piecewise CRC calculation over two (more more) memory blocks.
|
||||
* // Please note that the initial value requires a bytewise reflection, and an inversion whenever it's passed for the next calculation:
|
||||
* {
|
||||
* uint32 fceCrc;
|
||||
*
|
||||
* fceCrc = IfxFce_Crc_calculateCrc32(&fceCrc32_1, (uint32 *)&checkData[0], CHECK_DATA_SIZE-10, 0x00000000);
|
||||
* fceCrc = IfxFce_Crc_calculateCrc32(&fceCrc32_1, (uint32 *)&checkData[CHECK_DATA_SIZE-10], 10, ~IfxFce_reflectCrc32(fceCrc, 32));
|
||||
*
|
||||
* // -> CRC32 will be 0xd95def75 (as well)
|
||||
* }
|
||||
*
|
||||
* // using the CRC16 kernel
|
||||
* {
|
||||
* uint32 fceCrc;
|
||||
*
|
||||
* fceCrc = IfxFce_Crc_calculateCrc16(&fceCrc16, (uint16 *)checkData, CHECK_DATA_SIZE*2, 0x00000000);
|
||||
*
|
||||
* // -> CRC16 will be 0xda6f
|
||||
* }
|
||||
*
|
||||
* // using the CRC8 kernel
|
||||
* {
|
||||
* uint32 fceCrc;
|
||||
*
|
||||
* fceCrc = IfxFce_Crc_calculateCrc8(&fceCrc8, (uint8 *)checkData, CHECK_DATA_SIZE*4, 0x00000000);
|
||||
*
|
||||
* // -> CRC8 will be 0x61
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* /
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Fce_Crc CRC
|
||||
* \ingroup IfxLld_Fce
|
||||
* \defgroup IfxLld_Fce_Crc_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Fce_Crc
|
||||
* \defgroup IfxLld_Fce_Crc_Module Module Initialise Functions
|
||||
* \ingroup IfxLld_Fce_Crc
|
||||
* \defgroup IfxLld_Fce_Crc_Operative CRC Operation Functions
|
||||
* \ingroup IfxLld_Fce_Crc
|
||||
* \defgroup IfxLld_Fce_Crc_Interrupt Interrupt Status Function
|
||||
* \ingroup IfxLld_Fce_Crc
|
||||
*/
|
||||
|
||||
#ifndef IFXFCE_CRC_H
|
||||
#define IFXFCE_CRC_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "Fce/Std/IfxFce.h"
|
||||
#include "Cpu/Irq/IfxCpu_Irq.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Fce_Crc_DataStructures
|
||||
* \{ */
|
||||
/** \brief Specifies the interrupt enable structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean crcMismatch; /**< \brief Specifies enabel/disable of CRC mismatch interrupt */
|
||||
boolean configError; /**< \brief Specifies enabel/disable of configuration error interrupt */
|
||||
boolean lengthError; /**< \brief Specifies enabel/disable of length error interrupt */
|
||||
boolean busError; /**< \brief Specifies enabel/disable of bus error interrupt */
|
||||
} IfxFce_Crc_EnabledInterrupts;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fce_Crc_DataStructures
|
||||
* \{ */
|
||||
/** \brief FCE Module Handle;
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_FCE *fce; /**< \brief Pointer to FCE registers */
|
||||
} IfxFce_Crc;
|
||||
|
||||
/** \brief Configuration structure of the module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_FCE *fce; /**< \brief Pointer to FCE registers */
|
||||
uint16 isrPriority; /**< \brief interrupt priority */
|
||||
IfxSrc_Tos isrTypeOfService; /**< \brief type of interrupt service */
|
||||
} IfxFce_Crc_Config;
|
||||
|
||||
/** \brief Specifies the pointer to FCE module handler
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_FCE *fce; /**< \brief Specifies pointer to FCE module registers */
|
||||
IfxFce_CrcMode crcMode; /**< \brief Specifies the CRC mode */
|
||||
uint32 expectedCrc; /**< \brief Specifies the expected CRC to be compared with resulted. */
|
||||
IfxFce_Crc32Kernel crc32Kernel; /**< \brief Specifies the kernel used for CRC-32 */
|
||||
} IfxFce_Crc_Crc;
|
||||
|
||||
/** \brief Specifies the module configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_FCE *fce; /**< \brief Specifies pointer to FCE module registers */
|
||||
boolean crcCheckCompared; /**< \brief Specifies whether CRC check comparision is enabled or not */
|
||||
boolean automaticLengthReload; /**< \brief Specifies the enable/disable of automatic length reload */
|
||||
boolean dataByteReflectionEnabled; /**< \brief Specifies enable/disable of input data byte wise reflection */
|
||||
boolean crc32BitReflectionEnabled; /**< \brief Specifies enable/disable of CRC 32-bit wise reflection */
|
||||
uint32 expectedCrc; /**< \brief Specifies the expected CRC to be compared with resulted. */
|
||||
IfxFce_CrcMode crcMode; /**< \brief Specifies the CRC mode */
|
||||
boolean crcResultInverted; /**< \brief Specifies the XOR valueto get the final CRC */
|
||||
IfxFce_Crc32Kernel crc32Kernel; /**< \brief Specifies the kernel used for CRC-32 */
|
||||
IfxFce_Crc_EnabledInterrupts enabledInterrupts; /**< \brief Specifies the interrupt enable structure */
|
||||
} IfxFce_Crc_CrcConfig;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fce_Crc_Module
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Deinitialises the FCE module
|
||||
* \param fce Specifies the pointer to FCE module handler
|
||||
* \return None
|
||||
*
|
||||
* Reset the module
|
||||
*
|
||||
* \code
|
||||
* IfxFce_Crc fce;
|
||||
* //Deinitialise the module
|
||||
* IfxFce_Crc_deInitModule(&fce);
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFce_Crc_deInitModule(IfxFce_Crc_Crc *fce);
|
||||
|
||||
/** \brief Initialise the FCE module for CRC computation according to CRC mode
|
||||
* \param fceCrc Specifies the pointer to CRC handle
|
||||
* \param crcConfig Specifies the FCE CRC configuration structure
|
||||
* \return None
|
||||
*
|
||||
* Usage Example: see \ref IfxLld_Fce_Crc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFce_Crc_initCrc(IfxFce_Crc_Crc *fceCrc, const IfxFce_Crc_CrcConfig *crcConfig);
|
||||
|
||||
/** \brief Initialises the default CRC configuration buffer
|
||||
* \param crcConfig Specifies the FCE CRC configuration structure
|
||||
* \param fce Pointer to the FCE module handle
|
||||
* \return None
|
||||
*
|
||||
* Usage Example: see \ref IfxLld_Fce_Crc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFce_Crc_initCrcConfig(IfxFce_Crc_CrcConfig *crcConfig, IfxFce_Crc *fce);
|
||||
|
||||
/** \brief Usage Example: see \ref IfxLld_Fce_Crc_Usage
|
||||
* \param fce module handle
|
||||
* \param config predefined configuration structure of the module
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFce_Crc_initModule(IfxFce_Crc *fce, const IfxFce_Crc_Config *config);
|
||||
|
||||
/** \brief Fills the config structure with default values
|
||||
* \param config configuration structure of the module
|
||||
* \param fce pointer to FCE registers
|
||||
* \return None
|
||||
*
|
||||
* Usage Example: see \ref IfxLld_Fce_Crc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFce_Crc_initModuleConfig(IfxFce_Crc_Config *config, Ifx_FCE *fce);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fce_Crc_Operative
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Calculate the XORed 16-bit CRC value and returns it. It takes the precomputed XORed and reversed.
|
||||
* \param fce Specifies the pointer to FCE module handler
|
||||
* \param crcData Length of the input data block
|
||||
* \param crcDataLength Length of the input data block
|
||||
* \param crcStartValue start value for CRC calculation
|
||||
* \return Final CRC after XORed with XOR value.
|
||||
*
|
||||
* Usage Example: see \ref IfxLld_Fce_Crc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN uint16 IfxFce_Crc_calculateCrc16(IfxFce_Crc_Crc *fce, const uint16 *crcData, uint32 crcDataLength, uint16 crcStartValue);
|
||||
|
||||
/** \brief Calculate the XORed 32-bit CRC value and returns it. It takes the precomputed XORed and reversed.
|
||||
* \param fce Specifies the pointer to FCE module handler
|
||||
* \param crcData pointer to the input data block
|
||||
* \param crcDataLength Length of the input data block
|
||||
* \param crcStartValue start value for CRC calculation
|
||||
* \return Final CRC after XORed with XOR value.
|
||||
*
|
||||
* Usage Example: see \ref IfxLld_Fce_Crc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxFce_Crc_calculateCrc32(IfxFce_Crc_Crc *fce, const uint32 *crcData, uint32 crcDataLength, uint32 crcStartValue);
|
||||
|
||||
/** \brief Calculate the XORed 8-bit CRC value and returns it. It takes the precomputed XORed and reversed.
|
||||
* \param fce Specifies the pointer to FCE module handler
|
||||
* \param crcData Length of the input data block
|
||||
* \param crcDataLength Length of the input data block
|
||||
* \param crcStartValue start value for CRC calculation
|
||||
* \return Final CRC after XORed with XOR value.
|
||||
*
|
||||
* Usage Example: see \ref IfxLld_Fce_Crc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN uint8 IfxFce_Crc_calculateCrc8(IfxFce_Crc_Crc *fce, const uint8 *crcData, uint32 crcDataLength, uint8 crcStartValue);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fce_Crc_Interrupt
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Clears the error flags
|
||||
* \param fce Specifies the pointer to FCE module handler
|
||||
* \return None
|
||||
*
|
||||
* Usage Example: see \ref IfxLld_Fce_Crc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFce_Crc_clearErrorFlags(IfxFce_Crc_Crc *fce);
|
||||
|
||||
/** \brief Gets the current CRC interrupt status.
|
||||
* \param fce Specifies the pointer to FCE module handler
|
||||
* \return Current interrupt status
|
||||
*
|
||||
* Usage Example: see \ref IfxLld_Fce_Crc_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN Ifx_FCE_STS IfxFce_Crc_getInterruptStatus(IfxFce_Crc_Crc *fce);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXFCE_CRC_H */
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* \file IfxFce.c
|
||||
* \brief FCE basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxFce.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
Ifx_FCE_STS IfxFce_getCrc16InterruptStatus(Ifx_FCE *fce)
|
||||
{
|
||||
Ifx_FCE_STS interruptStatus;
|
||||
interruptStatus.U = fce->IN2.STS.U;
|
||||
return interruptStatus;
|
||||
}
|
||||
|
||||
|
||||
Ifx_FCE_STS IfxFce_getCrc32InterruptStatus(Ifx_FCE *fce, IfxFce_Crc32Kernel crc32Kernel)
|
||||
{
|
||||
Ifx_FCE_STS interruptStatus;
|
||||
|
||||
if (crc32Kernel == IfxFce_Crc32Kernel_0)
|
||||
{
|
||||
interruptStatus.U = fce->IN0.STS.U;
|
||||
}
|
||||
else
|
||||
{
|
||||
interruptStatus.U = fce->IN1.STS.U;
|
||||
}
|
||||
|
||||
return interruptStatus;
|
||||
}
|
||||
|
||||
|
||||
Ifx_FCE_STS IfxFce_getCrc8InterruptStatus(Ifx_FCE *fce)
|
||||
{
|
||||
Ifx_FCE_STS interruptStatus;
|
||||
interruptStatus.U = fce->IN3.STS.U;
|
||||
return interruptStatus;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxFce_reflectCrc32(uint32 crcStartValue, uint8 crcLength)
|
||||
{
|
||||
uint32 ReversedData = 0x0U;
|
||||
uint8 inputDataCounter;
|
||||
|
||||
for (inputDataCounter = 0; inputDataCounter < crcLength; ++inputDataCounter)
|
||||
{
|
||||
if (crcStartValue & 0x01)
|
||||
{
|
||||
ReversedData |= (uint32)((uint32)1 << ((crcLength - 1) - inputDataCounter));
|
||||
}
|
||||
|
||||
crcStartValue = (uint32)((uint32)crcStartValue >> (uint32)1);
|
||||
}
|
||||
|
||||
return ReversedData;
|
||||
}
|
||||
|
||||
|
||||
void IfxFce_resetModule(Ifx_FCE *fce)
|
||||
{
|
||||
uint16 password = IfxScuWdt_getCpuWatchdogPassword();
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(password);
|
||||
fce->KRST1.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
|
||||
fce->KRST0.B.RST = 1;
|
||||
IfxScuWdt_setCpuEndinit(password);
|
||||
|
||||
while (0 == fce->KRST0.B.RSTSTAT) /* Wait until reset is executed */
|
||||
|
||||
{}
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(password);
|
||||
fce->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
|
||||
IfxScuWdt_setCpuEndinit(password);
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* \file IfxFce.h
|
||||
* \brief FCE basic functionality
|
||||
* \ingroup IfxLld_Fce
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Fce_Std_Enum Enumerations
|
||||
* \ingroup IfxLld_Fce_Std
|
||||
* \defgroup IfxLld_Fce_Std_Module Module Functions
|
||||
* \ingroup IfxLld_Fce_Std
|
||||
* \defgroup IfxLld_Fce_Std_Support Support Function
|
||||
* \ingroup IfxLld_Fce_Std
|
||||
* \defgroup IfxLld_Fce_Std_InterruptStatus Interrupt Status Functions
|
||||
* \ingroup IfxLld_Fce_Std
|
||||
*/
|
||||
|
||||
#ifndef IFXFCE_H
|
||||
#define IFXFCE_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxFce_cfg.h"
|
||||
#include "Cpu/Std/IfxCpu_Intrinsics.h"
|
||||
#include "Scu/Std/IfxScuWdt.h"
|
||||
#include "IfxFce_reg.h"
|
||||
#include "Src/Std/IfxSrc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Fce_Std_Enum
|
||||
* \{ */
|
||||
/** \brief Ifx_FCE_INx(x= 0,1), Specifies the kernel used for CRC-32
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxFce_Crc32Kernel_0 = 0, /**< \brief Specifies the kernel0 used for CRC-32 */
|
||||
IfxFce_Crc32Kernel_1 /**< \brief Specifies the kernel1 used for CRC-32 */
|
||||
} IfxFce_Crc32Kernel;
|
||||
|
||||
/** \brief Specifies the CRC mode
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxFce_CrcMode_8 = 0, /**< \brief Specifies the 8-bit CRC mode */
|
||||
IfxFce_CrcMode_16 = 1, /**< \brief Specifies the 16-bit CRC mode */
|
||||
IfxFce_CrcMode_32 = 2 /**< \brief Specifies the 32-bit CRC mode */
|
||||
} IfxFce_CrcMode;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fce_Std_Module
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Disable the control of FCE module
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFce_disableModule(Ifx_FCE *fce);
|
||||
|
||||
/** \brief Enable the control of FCE module
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFce_enableModule(Ifx_FCE *fce);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Reset the module by clearing the kernel
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFce_resetModule(Ifx_FCE *fce);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fce_Std_Support
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Reflects the CRC data and returns it
|
||||
* \param crcStartValue start value for reflection
|
||||
* \param crcLength length of reflected value
|
||||
* \return Reflected CRC data
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxFce_reflectCrc32(uint32 crcStartValue, uint8 crcLength);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fce_Std_InterruptStatus
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Clears the CRC-16 error flags
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFce_clearCrc16ErrorFlags(Ifx_FCE *fce);
|
||||
|
||||
/** \brief Clears the CRC-32 error flags
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
* \param crc32Kernel Specifies the kernel used for CRC-32
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFce_clearCrc32ErrorFlags(Ifx_FCE *fce, IfxFce_Crc32Kernel crc32Kernel);
|
||||
|
||||
/** \brief Clears the CRC-8 error flags
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFce_clearCrc8ErrorFlags(Ifx_FCE *fce);
|
||||
|
||||
/** \brief Returns the SRC pointer for FCE
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
*/
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxFce_getSrcPointer(Ifx_FCE *fce);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Gets the CRC-16 interrupt status
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
* \return Current CRC-16 interrupt status
|
||||
*/
|
||||
IFX_EXTERN Ifx_FCE_STS IfxFce_getCrc16InterruptStatus(Ifx_FCE *fce);
|
||||
|
||||
/** \brief Gets the CRC-32 interrupt status
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
* \param crc32Kernel Specifies the kernel used for CRC-32
|
||||
* \return Current CRC-32 interrupt status
|
||||
*/
|
||||
IFX_EXTERN Ifx_FCE_STS IfxFce_getCrc32InterruptStatus(Ifx_FCE *fce, IfxFce_Crc32Kernel crc32Kernel);
|
||||
|
||||
/** \brief Gets the CRC-8 interrupt status
|
||||
* \param fce Specifies pointer to FCE module registers
|
||||
* \return Current CRC-8 interrupt status
|
||||
*/
|
||||
IFX_EXTERN Ifx_FCE_STS IfxFce_getCrc8InterruptStatus(Ifx_FCE *fce);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxFce_clearCrc16ErrorFlags(Ifx_FCE *fce)
|
||||
{
|
||||
fce->IN2.STS.U = 0x0000000fU;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFce_clearCrc32ErrorFlags(Ifx_FCE *fce, IfxFce_Crc32Kernel crc32Kernel)
|
||||
{
|
||||
if (crc32Kernel == IfxFce_Crc32Kernel_0)
|
||||
{
|
||||
fce->IN0.STS.U = 0x0000000fU;
|
||||
}
|
||||
else
|
||||
{
|
||||
fce->IN1.STS.U = 0x0000000fU;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFce_clearCrc8ErrorFlags(Ifx_FCE *fce)
|
||||
{
|
||||
fce->IN3.STS.U = 0x0000000fU;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFce_disableModule(Ifx_FCE *fce)
|
||||
{
|
||||
uint16 password = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(password);
|
||||
fce->CLC.B.DISR = 1;
|
||||
IfxScuWdt_setCpuEndinit(password);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFce_enableModule(Ifx_FCE *fce)
|
||||
{
|
||||
uint16 password = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(password);
|
||||
fce->CLC.B.DISR = 0;
|
||||
IfxScuWdt_setCpuEndinit(password);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxFce_getSrcPointer(Ifx_FCE *fce)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(fce);
|
||||
return &SRC_FCE;
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXFCE_H */
|
||||
@@ -0,0 +1,744 @@
|
||||
/**
|
||||
* \file IfxFft_Fft.c
|
||||
* \brief FFT FFT details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxFft_Fft.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Macros------------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#define IFXFFT_FFT_DATA_TRANSFER (*((volatile uint64 *)IFXFFT_DATA_SPACE))
|
||||
|
||||
#define IFXFFT_FFT_WINDOW_TRANSFER (*((volatile uint64 *)IFXFFT_WINDOW_SPACE))
|
||||
|
||||
#define IFXFFT_FFT_DMADISCARDCHANNELID_OPT (IFXFFT_FFT_DMA_CHANNEL_BASE + 2)
|
||||
|
||||
#define IFXFFT_FFT_DMAOUTPUTCHANNELID_OPT (IFXFFT_FFT_DMA_CHANNEL_BASE + 1)
|
||||
|
||||
#define IFXFFT_FFT_DMAINPUTCHANNELID_OPT (IFXFFT_FFT_DMA_CHANNEL_BASE)
|
||||
|
||||
#define IFXFFT_FFT_DMADISCARDCHANNELID (dmaDiscard->channelId)
|
||||
|
||||
#define IFXFFT_FFT_DMAOUTPUTCHANNELID (dmaOutput->channelId)
|
||||
|
||||
#define IFXFFT_FFT_DMAINPUTCHANNELID (dmaInput->channelId)
|
||||
|
||||
#define IFXFFT_FFT_MOVE_BTR4 1
|
||||
|
||||
#define IFXFFT_FFT_MOVE_SIZE IfxDma_ChannelMoveSize_256bit
|
||||
|
||||
#define IFXFFT_FFT_MOVE_DIV 4
|
||||
|
||||
#define IFXFFT_FFT_ISALIGNED(address) ((Ifx_AlignOn256((uint32)address) == (uint32)address))
|
||||
|
||||
/** \addtogroup IfxLld_Fft_Fft_ModuleFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Configures the CSR register
|
||||
* \param config Configuration structure for the FFT job
|
||||
* \return Desired value to write into the Ifx_FFT.CSR register
|
||||
*/
|
||||
IFX_STATIC uint32 IfxFft_Fft_calcCSR(const IfxFft_Fft_JobConfig *config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fft_Fft_TransformFuntions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Unloads output data from the FFT engine
|
||||
* \param job FFT job handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxFft_Fft_unloadOutput(IfxFft_Fft_Job *job);
|
||||
|
||||
/** \brief Loads input data into the FFT engine
|
||||
* \param job FFT job handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxFft_Fft_loadInput(IfxFft_Fft_Job *job);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Calculates the input counters and output counters
|
||||
* \param job job FFT job
|
||||
* \param jobConfig jobConfig Pointer to the job configuration
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxFft_Fft_calcCounters(IfxFft_Fft_Job *job, const IfxFft_Fft_JobConfig *jobConfig);
|
||||
|
||||
/******************************************************************************/
|
||||
/*------------------------Private Variables/Constants-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_STATIC uint64 IfxFft_Fft_dummy256[IFXFFT_FFT_MOVE_DIV];
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_STATIC uint32 IfxFft_Fft_calcCSR(const IfxFft_Fft_JobConfig *config)
|
||||
{
|
||||
uint32 csr =
|
||||
(config->fftLength << IFX_FFT_CSR_LENGTH_OFF) |
|
||||
(config->inputFormat << IFX_FFT_CSR_IN_FMT_OFF) |
|
||||
(config->outputFormat << IFX_FFT_CSR_OUT_FMT_OFF) |
|
||||
(config->operation << IFX_FFT_CSR_IFFT_OFF) |
|
||||
((config->useWindowFunction ? 0U : 1U) << IFX_FFT_CSR_WIN_BYP_OFF);
|
||||
return csr;
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_cloneAndLinkJobs(IfxFft_Fft_Job *originalJob, IfxFft_Fft_Job *newJob)
|
||||
{
|
||||
*newJob = *originalJob;
|
||||
originalJob->nextJob = newJob;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxFft_Fft_unloadOutput(IfxFft_Fft_Job *job)
|
||||
{
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
#if IFXFFT_FFT_HW_EXEC
|
||||
volatile Ifx_SRC_SRCR *srcr;
|
||||
sint16 discardCount;
|
||||
|
||||
#if !IFXFFT_FFT_OPTIMIZED
|
||||
IfxDma_Dma_Channel *dmaOutput = &(job->fft->outputDmaChannel);
|
||||
IfxDma_Dma_Channel *dmaDiscard = &(job->fft->discardDmaChannel);
|
||||
Ifx_DMA *dmaSFR = dmaOutput->dma;
|
||||
#else
|
||||
Ifx_DMA *dmaSFR = (&MODULE_DMA);
|
||||
#endif
|
||||
#if IFXFFT_FFT_OPTIMIZED
|
||||
IfxDma_setChannelDestinationAddress(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID_OPT, job->outputPtr);
|
||||
IfxDma_setChannelTransferCount(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID_OPT, job->count64.output);
|
||||
#else
|
||||
IfxDma_setChannelDestinationAddress(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID, job->outputPtr);
|
||||
IfxDma_setChannelTransferCount(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID, job->count64.output);
|
||||
#endif
|
||||
discardCount = (job->count64.result - job->count64.output);
|
||||
|
||||
if (discardCount > 0)
|
||||
{
|
||||
#if IFXFFT_FFT_OPTIMIZED
|
||||
IfxDma_setChannelDestinationAddress(dmaSFR, IFXFFT_FFT_DMADISCARDCHANNELID_OPT, IfxFft_Fft_dummy256);
|
||||
IfxDma_setChannelTransferCount(dmaSFR, IFXFFT_FFT_DMADISCARDCHANNELID_OPT, discardCount);
|
||||
#else
|
||||
IfxDma_setChannelDestinationAddress(dmaSFR, IFXFFT_FFT_DMADISCARDCHANNELID, IfxFft_Fft_dummy256);
|
||||
IfxDma_setChannelTransferCount(dmaSFR, IFXFFT_FFT_DMADISCARDCHANNELID, discardCount);
|
||||
#endif
|
||||
|
||||
#if IFXFFT_FFT_OPTIMIZED
|
||||
srcr = IfxDma_getSrcPointer(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID_OPT);
|
||||
#else
|
||||
srcr = IfxDma_getSrcPointer(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID);
|
||||
#endif
|
||||
srcr->B = job->fft->srcrOutDis;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if IFXFFT_FFT_OPTIMIZED
|
||||
srcr = IfxDma_getSrcPointer(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID_OPT);
|
||||
#else
|
||||
srcr = IfxDma_getSrcPointer(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID);
|
||||
#endif
|
||||
srcr->B = job->fft->srcrOutEnd;
|
||||
}
|
||||
|
||||
#if IFXFFT_FFT_OPTIMIZED
|
||||
IfxDma_startChannelTransaction(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID_OPT);
|
||||
#else
|
||||
IfxDma_startChannelTransaction(dmaSFR, IFXFFT_FFT_DMAOUTPUTCHANNELID);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
sint16 i;
|
||||
uint64 *output64;
|
||||
|
||||
output64 = job->outputPtr;
|
||||
|
||||
for (i = 0; i < job->count64.output; i++)
|
||||
{
|
||||
*(output64++) = IFXFFT_FFT_DATA_TRANSFER;
|
||||
}
|
||||
|
||||
for ( ; i < job->count64.result; i++)
|
||||
{
|
||||
volatile uint64 dummy64 = IFXFFT_FFT_DATA_TRANSFER;
|
||||
|
||||
if (dummy64) // avoid warning message (unused variable)
|
||||
{}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_initJob(IfxFft_Fft_Job *job, const IfxFft_Fft_JobConfig *jobConfig)
|
||||
{
|
||||
// take over FFT handle
|
||||
job->fft = jobConfig->fft;
|
||||
job->nextJob = NULL_PTR;
|
||||
|
||||
// engine control
|
||||
job->csr.U = IfxFft_Fft_calcCSR(jobConfig);
|
||||
job->inputPtr = jobConfig->inputPtr;
|
||||
job->outputPtr = jobConfig->outputPtr;
|
||||
|
||||
// move counters
|
||||
IfxFft_Fft_calcCounters(job, jobConfig);
|
||||
|
||||
// config check
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (IfxFft_getLengthFromCode(jobConfig->fftLength)) <= IFXFFT_MAX_LENGTH);
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, jobConfig->inputLength > 0);
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, jobConfig->outputLength > 0);
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (IfxFft_getLengthFromCode(jobConfig->fftLength)) == jobConfig->inputLength);
|
||||
#else
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (IfxFft_getLengthFromCode(jobConfig->fftLength)) >= jobConfig->inputLength);
|
||||
#endif
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (IfxFft_getLengthFromCode(jobConfig->fftLength)) >= jobConfig->outputLength);
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, IFXFFT_FFT_ISALIGNED(jobConfig->outputLength));
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, IFXFFT_FFT_ISALIGNED(job->inputPtr));
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, IFXFFT_FFT_ISALIGNED(job->outputPtr));
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_initJobConfig(IfxFft_Fft_JobConfig *config, IfxFft_Fft *fft)
|
||||
{
|
||||
config->fft = fft;
|
||||
config->inputLength = 256;
|
||||
config->outputLength = 256;
|
||||
config->fftLength = IfxFft_Length_256;
|
||||
config->inputFormat = IfxFft_Input_realSInt32;
|
||||
config->outputFormat = IfxFft_Output_complexSInt32;
|
||||
config->operation = IfxFft_Operation_fft;
|
||||
config->useWindowFunction = FALSE;
|
||||
config->inputPtr = NULL_PTR;
|
||||
config->outputPtr = NULL_PTR;
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_initModule(IfxFft_Fft *fft, const IfxFft_Fft_Config *config)
|
||||
{
|
||||
#if !IFXFFT_FFT_OPTIMIZED
|
||||
Ifx_FFT *fftSFR = config->fft;
|
||||
Ifx_LMU *lmuSFR = config->lmu;
|
||||
|
||||
fft->fft = fftSFR;
|
||||
fft->lmu = lmuSFR;
|
||||
#else
|
||||
Ifx_FFT *fftSFR = (&MODULE_FFT);
|
||||
Ifx_LMU *lmuSFR = (&MODULE_LMU);
|
||||
#endif
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
|
||||
fft->inputIdx = 0;
|
||||
fft->job[0] = 0;
|
||||
fft->job[1] = 0;
|
||||
#endif
|
||||
|
||||
if (IfxFft_isModuleEnabled(fftSFR) == FALSE)
|
||||
{
|
||||
IfxFft_enableModule(fftSFR, lmuSFR);
|
||||
}
|
||||
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->outputPriority > 0);
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->inputPriority > 0);
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->intraPriority > 0);
|
||||
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->inputDmaChannelId != IfxDma_ChannelId_none);
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->outputDmaChannelId != IfxDma_ChannelId_none);
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->discardDmaChannelId != IfxDma_ChannelId_none);
|
||||
|
||||
IfxFft_Fft_initDma(fft, config);
|
||||
#else
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->typeOfService != IfxSrc_Tos_dma);
|
||||
|
||||
if (config->outputPriority > 0)
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *srcr;
|
||||
// FFT DONE as ISR output
|
||||
srcr = IfxFft_getSrcPointerDone(fftSFR);
|
||||
IfxSrc_init(srcr, config->typeOfService, config->outputPriority);
|
||||
IfxSrc_enable(srcr);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_initModuleConfig(IfxFft_Fft_Config *config, Ifx_FFT *fft, Ifx_LMU *lmu)
|
||||
{
|
||||
#if !IFXFFT_FFT_OPTIMIZED
|
||||
config->fft = fft;
|
||||
config->lmu = lmu;
|
||||
#endif
|
||||
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
#if IFXFFT_FFT_OPTIMIZED
|
||||
config->inputDmaChannelId = IFXFFT_FFT_DMA_CHANNEL_BASE;
|
||||
config->outputDmaChannelId = IFXFFT_FFT_DMA_CHANNEL_BASE + 1;
|
||||
config->discardDmaChannelId = IFXFFT_FFT_DMA_CHANNEL_BASE + 2;
|
||||
#else
|
||||
config->fft = fft;
|
||||
config->lmu = lmu;
|
||||
config->inputDmaChannelId = IfxDma_ChannelId_none;
|
||||
config->outputDmaChannelId = IfxDma_ChannelId_none;
|
||||
config->discardDmaChannelId = IfxDma_ChannelId_none;
|
||||
#endif
|
||||
#endif
|
||||
config->inputPriority = 0;
|
||||
config->outputPriority = 0;
|
||||
config->typeOfService = IfxSrc_Tos_cpu0;
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_initWindow(IfxFft_Fft *fft, const uint64 *windowData)
|
||||
{
|
||||
int i;
|
||||
const uint64 *ptr = windowData;
|
||||
|
||||
#if !IFXFFT_FFT_OPTIMIZED
|
||||
/*IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, MODULE_LMU.MEMCON.B.FFTPFT == 0);*/
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, !IfxFft_isEngineBusy(fft->fft));
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, IfxFft_isReadyForStart(fft->fft));
|
||||
#else
|
||||
/*IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, MODULE_LMU.MEMCON.B.FFTPFT == 0);*/
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, !IfxFft_isEngineBusy(&MODULE_FFT));
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, IfxFft_isReadyForStart(&MODULE_FFT));
|
||||
#endif
|
||||
|
||||
uint64 *wmem = (uint64 *)IFXFFT_WINDOW_SPACE;
|
||||
|
||||
for (i = 0; i < (IFXFFT_MAX_WINDOW_LENGTH / (sizeof(uint64) / sizeof(uint16))); i++)
|
||||
{
|
||||
*(wmem++) = *(ptr++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_isrInput(IfxFft_Fft *fft)
|
||||
{
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
|
||||
#if IFXFFT_FFT_PIPELINED
|
||||
IfxFft_Fft_Job *inputJob = fft->job[0];
|
||||
|
||||
if (fft->inputIdx == 0)
|
||||
{
|
||||
if (inputJob != NULL_PTR)
|
||||
{
|
||||
IfxFft_Fft_startJob(inputJob);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fft->flags & IFXFFT_FFT_FLAG_DONE)
|
||||
{
|
||||
fft->flags = 0;
|
||||
IfxFft_Fft_unloadOutput(fft->job[1]);
|
||||
fft->job[1] = fft->job[1]->nextJob;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fft->inputIdx > fft->intraIdx)
|
||||
{
|
||||
fft->flags = IFXFFT_FFT_FLAG_INPUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fft->inputIdx == IFXFFT_FFT_NUM_JOBS)
|
||||
{
|
||||
__debug();
|
||||
}
|
||||
|
||||
fft->inputIdx++;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_isrOutput(IfxFft_Fft *fft)
|
||||
{
|
||||
#if IFXFFT_FFT_PIPELINED
|
||||
IfxFft_Fft_Job *outputJob = fft->job[1];
|
||||
|
||||
if (outputJob != NULL_PTR)
|
||||
{
|
||||
if (outputJob->nextJob != NULL_PTR)
|
||||
{
|
||||
IfxFft_Fft_Job *inputJob = fft->job[0];
|
||||
|
||||
if (inputJob != NULL_PTR)
|
||||
{
|
||||
IfxFft_Fft_startJob(inputJob);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fft->flags & IFXFFT_FFT_FLAG_DONE)
|
||||
{
|
||||
fft->flags = 0;
|
||||
IfxFft_Fft_unloadOutput(outputJob);
|
||||
fft->job[1] = outputJob->nextJob;
|
||||
}
|
||||
else
|
||||
{
|
||||
fft->flags = IFXFFT_FFT_FLAG_INPUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fft->flags & IFXFFT_FFT_FLAG_DONE)
|
||||
{
|
||||
fft->flags = 0;
|
||||
IfxFft_Fft_unloadOutput(outputJob);
|
||||
fft->job[1] = outputJob->nextJob;
|
||||
}
|
||||
else
|
||||
{
|
||||
fft->flags = IFXFFT_FFT_FLAG_INPUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
IfxFft_Fft_Job *outputJob = fft->job[0];
|
||||
|
||||
#if !IFXFFT_FFT_DMA_SUPPORT
|
||||
IfxFft_Fft_unloadOutput(outputJob);
|
||||
#endif
|
||||
|
||||
if (outputJob->nextJob != NULL_PTR)
|
||||
{
|
||||
boolean result = IfxFft_Fft_startJob(outputJob->nextJob);
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
fft->job[0] = NULL_PTR;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxFft_Fft_loadInput(IfxFft_Fft_Job *job)
|
||||
{
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
|
||||
#if !IFXFFT_FFT_OPTIMIZED
|
||||
IfxDma_Dma_Channel *dmaInput = &job->fft->inputDmaChannel;
|
||||
Ifx_DMA *dmaSFR = dmaInput->dma;
|
||||
#else
|
||||
Ifx_DMA *dmaSFR = (&MODULE_DMA);
|
||||
#endif
|
||||
#if IFXFFT_FFT_HW_EXEC
|
||||
#if IFXFFT_FFT_OPTIMIZED
|
||||
IfxDma_setChannelSourceAddress(dmaSFR, IFXFFT_FFT_DMAINPUTCHANNELID_OPT, job->inputPtr);
|
||||
IfxDma_setChannelTransferCount(dmaSFR, IFXFFT_FFT_DMAINPUTCHANNELID_OPT, job->count64.input);
|
||||
IfxDma_startChannelTransaction(dmaSFR, IFXFFT_FFT_DMAINPUTCHANNELID_OPT);
|
||||
#else
|
||||
IfxDma_setChannelSourceAddress(dmaSFR, IFXFFT_FFT_DMAINPUTCHANNELID, job->inputPtr);
|
||||
IfxDma_setChannelTransferCount(dmaSFR, IFXFFT_FFT_DMAINPUTCHANNELID, job->count64.input);
|
||||
IfxDma_startChannelTransaction(dmaSFR, IFXFFT_FFT_DMAINPUTCHANNELID);
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
sint16 i;
|
||||
const uint64 *input64 = job->inputPtr;
|
||||
|
||||
for (i = 0; i < job->count64.input; i++)
|
||||
{
|
||||
IFXFFT_FFT_DATA_TRANSFER = *(input64++);
|
||||
}
|
||||
|
||||
for ( ; i < job->count64.expect; i++)
|
||||
{
|
||||
IFXFFT_FFT_DATA_TRANSFER = (uint64)0ULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_modifyDataPointers(IfxFft_Fft_Job *job, const void *inputPtr, void *outputPtr)
|
||||
{
|
||||
job->inputPtr = inputPtr;
|
||||
job->outputPtr = outputPtr;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxFft_Fft_startJob(IfxFft_Fft_Job *job)
|
||||
{
|
||||
IfxFft_Fft *fft = job->fft;
|
||||
#if !IFXFFT_FFT_OPTIMIZED
|
||||
Ifx_FFT *fftSFR = fft->fft;
|
||||
#else
|
||||
Ifx_FFT *fftSFR = (&MODULE_FFT);
|
||||
#endif
|
||||
boolean result = IfxFft_isReadyForStart(fftSFR);
|
||||
|
||||
if (result != FALSE)
|
||||
{
|
||||
IfxFft_Fft_triggerEngine(fftSFR, job->csr.U);
|
||||
#if IFXFFT_FFT_PIPELINED
|
||||
|
||||
if (fft->job[1] == NULL_PTR)
|
||||
{
|
||||
fft->inputIdx = 0;
|
||||
fft->intraIdx = 0;
|
||||
fft->job[1] = job;
|
||||
fft->flags = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
IfxFft_Fft_loadInput(job);
|
||||
|
||||
#if IFXFFT_FFT_PIPELINED
|
||||
fft->job[0] = job->nextJob;
|
||||
#else
|
||||
fft->job[0] = job;
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxFft_Fft_calcCounters(IfxFft_Fft_Job *job, const IfxFft_Fft_JobConfig *jobConfig)
|
||||
{
|
||||
uint16 shift;
|
||||
|
||||
/* input counters */
|
||||
if (jobConfig->inputFormat == IfxFft_Input_complexSInt32)
|
||||
{
|
||||
shift = 0;
|
||||
}
|
||||
else if (jobConfig->inputFormat == IfxFft_Input_realSInt16)
|
||||
{
|
||||
shift = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = 1;
|
||||
}
|
||||
|
||||
uint16 fftLength = IfxFft_getLengthFromCode(jobConfig->fftLength);
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
job->count64.input = (jobConfig->inputLength >> shift) / IFXFFT_FFT_MOVE_DIV;
|
||||
job->count64.expect = (fftLength >> shift) / IFXFFT_FFT_MOVE_DIV;
|
||||
#else
|
||||
job->count64.input = jobConfig->inputLength >> shift;
|
||||
job->count64.expect = fftLength >> shift;
|
||||
#endif
|
||||
/* output counters */
|
||||
shift = (jobConfig->outputFormat == IfxFft_Output_complexSInt32) ? 0 : 1;
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
job->count64.result = (fftLength >> shift) / IFXFFT_FFT_MOVE_DIV;
|
||||
job->count64.output = (jobConfig->outputLength >> shift) / IFXFFT_FFT_MOVE_DIV;
|
||||
#else
|
||||
job->count64.result = fftLength >> shift;
|
||||
job->count64.output = jobConfig->outputLength >> shift;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_isrIntra(IfxFft_Fft *fft)
|
||||
{
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
|
||||
# if IFXFFT_FFT_PIPELINED
|
||||
|
||||
if (fft->intraIdx == 0)
|
||||
{
|
||||
fft->flags = 0;
|
||||
IfxFft_Fft_unloadOutput(fft->job[1]);
|
||||
fft->job[1] = fft->job[1]->nextJob;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fft->flags & IFXFFT_FFT_FLAG_INPUT)
|
||||
{
|
||||
fft->flags = 0;
|
||||
IfxFft_Fft_unloadOutput(fft->job[1]);
|
||||
fft->job[1] = fft->job[1]->nextJob;
|
||||
}
|
||||
else
|
||||
{
|
||||
fft->flags = IFXFFT_FFT_FLAG_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
fft->intraIdx++;
|
||||
# else
|
||||
IfxFft_Fft_unloadOutput(fft->job[0]);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void IfxFft_Fft_initDma(IfxFft_Fft *fft, const IfxFft_Fft_Config *config)
|
||||
{
|
||||
#if IFXFFT_FFT_DMA_SUPPORT
|
||||
#if !IFXFFT_FFT_OPTIMIZED
|
||||
Ifx_DMA *dmaSFR = &MODULE_DMA;
|
||||
Ifx_FFT *fftSFR = config->fft;
|
||||
IfxDma_Dma_Channel *inputDmaChannel = &fft->inputDmaChannel;
|
||||
IfxDma_Dma_Channel *discardDmaChannel = &fft->discardDmaChannel;
|
||||
IfxDma_Dma_Channel *outputDmaChannel = &fft->outputDmaChannel;
|
||||
#else
|
||||
Ifx_FFT *fftSFR = (&MODULE_FFT);
|
||||
Ifx_DMA *dmaSFR = (&MODULE_DMA);
|
||||
IfxDma_Dma_Channel dmaChannel;
|
||||
IfxDma_Dma_Channel *inputDmaChannel = &dmaChannel;
|
||||
IfxDma_Dma_Channel *discardDmaChannel = &dmaChannel;
|
||||
IfxDma_Dma_Channel *outputDmaChannel = &dmaChannel;
|
||||
#endif
|
||||
|
||||
IfxDma_Dma dma;
|
||||
IfxDma_Dma_createModuleHandle(&dma, dmaSFR);
|
||||
|
||||
IfxDma_Dma_ChannelConfig dmaCfg;
|
||||
IfxDma_Dma_initChannelConfig(&dmaCfg, &dma);
|
||||
|
||||
dmaCfg.requestMode = IfxDma_ChannelRequestMode_completeTransactionPerRequest;
|
||||
dmaCfg.operationMode = IfxDma_ChannelOperationMode_continuous;
|
||||
dmaCfg.moveSize = IFXFFT_FFT_MOVE_SIZE;
|
||||
dmaCfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none;
|
||||
dmaCfg.destinationAddressCircularRange = IfxDma_ChannelIncrementCircular_none;
|
||||
|
||||
{
|
||||
/* output channel */
|
||||
dmaCfg.channelId = config->outputDmaChannelId;
|
||||
dmaCfg.hardwareRequestEnabled = FALSE; // will be triggered via software
|
||||
dmaCfg.channelInterruptEnabled = TRUE; // trigger interrupt after transaction
|
||||
|
||||
// source address is fixed; use circular mode to stay at this address for each move
|
||||
dmaCfg.sourceAddress = IFXFFT_DATA_SPACE;
|
||||
dmaCfg.sourceCircularBufferEnabled = TRUE;
|
||||
|
||||
// destination address and transfer count will be configured during runtime
|
||||
dmaCfg.destinationAddress = 0;
|
||||
dmaCfg.destinationCircularBufferEnabled = FALSE;
|
||||
dmaCfg.transferCount = 0;
|
||||
|
||||
IfxDma_Dma_initChannel(outputDmaChannel, &dmaCfg);
|
||||
}
|
||||
{
|
||||
/* discard channel, reuse most configuration of output channel */
|
||||
dmaCfg.channelId = config->discardDmaChannelId;
|
||||
dmaCfg.hardwareRequestEnabled = TRUE; // will be triggered via output DMA channel
|
||||
IfxDma_Dma_initChannel(discardDmaChannel, &dmaCfg);
|
||||
}
|
||||
{
|
||||
/* input channel */
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->inputDmaChannelId != config->outputDmaChannelId);
|
||||
dmaCfg.channelId = config->inputDmaChannelId;
|
||||
dmaCfg.hardwareRequestEnabled = FALSE; // will be triggered via software
|
||||
#if IFXFFT_FFT_PIPELINED
|
||||
dmaCfg.channelInterruptEnabled = TRUE; // trigger interrupt after transaction
|
||||
#else
|
||||
dmaCfg.channelInterruptEnabled = FALSE; // no interrupt at end of transaction
|
||||
#endif
|
||||
// source address and transfer count will be configured during runtime
|
||||
dmaCfg.sourceAddress = 0;
|
||||
dmaCfg.sourceCircularBufferEnabled = FALSE;
|
||||
dmaCfg.transferCount = 0;
|
||||
|
||||
// destination address is fixed; use circular mode to stay at this address for each move
|
||||
dmaCfg.destinationAddress = IFXFFT_DATA_SPACE;
|
||||
dmaCfg.destinationCircularBufferEnabled = TRUE;
|
||||
|
||||
IfxDma_Dma_initChannel(inputDmaChannel, &dmaCfg);
|
||||
}
|
||||
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *srcr;
|
||||
#if IFXFFT_FFT_PIPELINED
|
||||
//Route DMA input SRC to CPU as ISR input
|
||||
srcr = IfxDma_getSrcPointer(dmaSFR, config->inputDmaChannelId);
|
||||
IfxSrc_init(srcr, config->typeOfService, config->inputPriority);
|
||||
IfxSrc_enable(srcr);
|
||||
#endif
|
||||
//Route FFT DONE SRC to CPU as ISR midjob
|
||||
srcr = IfxFft_getSrcPointerDone(fftSFR);
|
||||
IfxSrc_init(srcr, config->typeOfService, config->intraPriority);
|
||||
IfxSrc_enable(srcr);
|
||||
|
||||
//Route output DMA request to discard DMA
|
||||
srcr = IfxDma_getSrcPointer(dmaSFR, config->outputDmaChannelId);
|
||||
IfxSrc_init(srcr, IfxSrc_Tos_dma, (Ifx_Priority)config->discardDmaChannelId);
|
||||
IfxSrc_enable(srcr);
|
||||
fft->srcrOutDis = srcr->B;
|
||||
|
||||
//Route DMA discard interrupt to CPU as ISR output
|
||||
srcr = IfxDma_getSrcPointer(dmaSFR, config->discardDmaChannelId);
|
||||
IfxSrc_init(srcr, config->typeOfService, config->outputPriority);
|
||||
IfxSrc_enable(srcr);
|
||||
fft->srcrOutEnd = srcr->B;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
/**
|
||||
* \file IfxFft_Fft.h
|
||||
* \brief FFT FFT details
|
||||
* \ingroup IfxLld_Fft
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Fft_Fft_Usage How to use the FFT driver?
|
||||
* \ingroup IfxLld_Fft
|
||||
*
|
||||
* The FFT interface driver provides a default FFT configuration for calculating forward and inverse FFTs of lengths 8 to 1024 (powers of 2 only) of real or complex input operands.
|
||||
*
|
||||
* In the following sections it will be described, how to integrate the driver into the application framework.
|
||||
*
|
||||
* \section IfxLld_Fft_Fft_Preparation Preparation
|
||||
* \subsection IfxLld_Fft_Fft_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
*
|
||||
* \code
|
||||
* #include <Fft/Fft/IfxFft_Fft.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Fft_Fft_Variables Variables
|
||||
*
|
||||
* Declare the FFT handle, FFT job handle and the input output locations as global variables in your C code:
|
||||
*
|
||||
* \code
|
||||
* // FFT window length
|
||||
* #define FFT_LENGTH 512
|
||||
*
|
||||
* // source waveform (must be 256bit aligned!)
|
||||
* __attribute__ ((aligned(256))) sint32 fftIn[FFT_LENGTH] = {
|
||||
* #include "sinewave.inc"
|
||||
* };
|
||||
*
|
||||
* // FFT result (must be 256bit aligned!)
|
||||
* __attribute__ ((aligned(256))) sint32 fftOut[FFT_LENGTH*2];
|
||||
*
|
||||
* // used globally
|
||||
* IfxFft_Fft fft;
|
||||
* IfxFft_Fft_Job fftJob;
|
||||
*
|
||||
* volatile uint32 fftInterruptCounter;
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Fft_Fft_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priorities for the Interrrupt handlers. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define ISR_PRIORITY_FFT_OUTPUT 1
|
||||
* #define ISR_PRIORITY_FFT_INPUT 2
|
||||
* #define ISR_PRIORITY_FFT_INTRA 3
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routines to your C code. They have to call the FFT interrupt handlers by passing the fftJob handle:
|
||||
* \code
|
||||
* IFX_INTERRUPT(ISR_Fft_intra, 0, ISR_PRIORITY_FFT_INTRA)
|
||||
* {
|
||||
* IfxFft_Fft_isrIntra(&fft);
|
||||
* }
|
||||
*
|
||||
* IFX_INTERRUPT(ISR_Fft_input, 0, ISR_PRIORITY_FFT_INPUT)
|
||||
* {
|
||||
* IfxFft_Fft_isrInput(&fft);
|
||||
* }
|
||||
*
|
||||
* IFX_INTERRUPT(ISR_Fft_output, 0, ISR_PRIORITY_FFT_output)
|
||||
* {
|
||||
* ++fftInterruptCounter;
|
||||
*
|
||||
* IfxFft_Fft_isrOutput(&fft);
|
||||
*
|
||||
* // do the next transform:
|
||||
* while (IfxFft_Fft_startJob(&fftJob) == FALSE) {}
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handlers in your initialisation function:
|
||||
* \code
|
||||
* // install interrupt handlers
|
||||
* IfxCpu_Irq_installInterruptHandler(&ISR_Fft_input, ISR_PRIORITY_FFT_INPUT);
|
||||
* IfxCpu_Irq_installInterruptHandler(&ISR_Fft_output, ISR_PRIORITY_FFT_OUTPUT);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Fft_Fft_InitModule Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function. Here an example:
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxFft_Fft_Config fftConfig;
|
||||
* IfxFft_Fft_initModuleConfig(&fftConfig, &MODULE_FFT, &MODULE_LMU);
|
||||
*
|
||||
* // configure interrupts
|
||||
* fftConfig.inputPriority = ISR_PRIORITY_FFT_INPUT;
|
||||
* fftConfig.intraPriority = ISR_PRIORITY_FFT_INTRA;
|
||||
* fftConfig.outputPriority = ISR_PRIORITY_FFT_OUTPUT;
|
||||
* fftConfig.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());
|
||||
*
|
||||
* // use DMA channels for input/output transfers
|
||||
* fftConfig.inputDmaChannelId = IfxDma_ChannelId_4;
|
||||
* fftConfig.outputDmaChannelId = IfxDma_ChannelId_5;
|
||||
* fftConfig.discardDmaChannelId = IfxDma_ChannelId_6;
|
||||
*
|
||||
* // initialize module
|
||||
* // IfxFft_Fft fft; // defined globally
|
||||
* IfxFft_Fft_initModule(&fft, &fftConfig);
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Fft_Fft_InitJob Job Initialisation
|
||||
*
|
||||
* The FFT job initialisation can also be done in the same function. Here an example:
|
||||
* \code
|
||||
* // create FFT job config
|
||||
* IfxFft_Fft_JobConfig fftJobConfig;
|
||||
* IfxFft_Fft_initJobConfig(&fftJobConfig, &fft);
|
||||
*
|
||||
* // customize job
|
||||
* fftJobConfig.fftLength = IfxFft_Length_512;
|
||||
*
|
||||
* fftJobConfig.inputFormat = IfxFft_Input_realSInt32;
|
||||
* fftJobConfig.inputPtr = (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (uint32)fftIn);
|
||||
* fftJobConfig.inputLength = FFT_LENGTH;
|
||||
*
|
||||
* fftJobConfig.outputFormat = IfxFft_Output_complexSInt32;
|
||||
* fftJobConfig.outputPtr = (void *)IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (uint32)fftOut);
|
||||
* fftJobConfig.outputLength = FFT_LENGTH;
|
||||
*
|
||||
* // initialize FFT job
|
||||
* // IfxFft_Fft_Job fftJob; // defined globally
|
||||
* IfxFft_Fft_initJob(&fftJob, &fftJobConfig);
|
||||
* \endcode
|
||||
*
|
||||
* The FFT is ready for use now!
|
||||
*
|
||||
*
|
||||
* \section IfxLld_Fft_Fft_TransformFunctions Transform Functions
|
||||
*
|
||||
* The FFT driver provides simple function to perform the transforms.
|
||||
*
|
||||
* This means: you only have to start the FFT job with pre configured job handle and the transform will be done automatically by the FFT engine and an interrupt will be raised, indicating the end of treansform(DONE).
|
||||
*
|
||||
* \code
|
||||
* // start job until return TRUE.
|
||||
* while (IfxFft_Fft_startJob(&fftJob) == FALSE) {}
|
||||
*
|
||||
* // wait for 3 interrupts
|
||||
* while( fftInterruptCounter < 3 );
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Fft_Fft FFT
|
||||
* \ingroup IfxLld_Fft
|
||||
* \defgroup IfxLld_Fft_Fft_DataStructures Data Structures
|
||||
* \ingroup IfxLld_Fft_Fft
|
||||
* \defgroup IfxLld_Fft_Fft_ModuleFunctions Module Functions
|
||||
* \ingroup IfxLld_Fft_Fft
|
||||
* \defgroup IfxLld_Fft_Fft_InterruptFunctions Interrupt Functions
|
||||
* \ingroup IfxLld_Fft_Fft
|
||||
* \defgroup IfxLld_Fft_Fft_TransformFuntions Transform Funtions
|
||||
* \ingroup IfxLld_Fft_Fft
|
||||
*/
|
||||
|
||||
#ifndef IFXFFT_FFT_H
|
||||
#define IFXFFT_FFT_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Utilities/Ifx_Assert.h"
|
||||
#include "IfxFft_bf.h"
|
||||
#include "Fft/Std/IfxFft.h"
|
||||
#include "Dma/Dma/IfxDma_Dma.h"
|
||||
#include "Scu/Std/IfxScuWdt.h"
|
||||
#include "Cpu/Std/IfxCpu.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------------Macros-----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#define IFXFFT_FFT_FLAG_INPUT (1)
|
||||
|
||||
#define IFXFFT_FFT_FLAG_DONE (2)
|
||||
|
||||
#define IFXFFT_FFT_HW_EXEC (1)
|
||||
|
||||
/******************************************************************************/
|
||||
/*------------------------------Type Definitions------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct IfxFft_Fft_Job_s IfxFft_Fft_Job;
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Fft_Fft_DataStructures
|
||||
* \{ */
|
||||
/** \brief Module handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_FFT *fft; /**< \brief Pointer to FFT registers. Used when (IFXFFT_FFT_OPTIMIZED == 0) */
|
||||
Ifx_LMU *lmu; /**< \brief Pointer to LMU registers.Used when (IFXFFT_FFT_OPTIMIZED == 0) */
|
||||
IfxDma_Dma_Channel inputDmaChannel; /**< \brief Input DMA channel. Used when (IFXFFT_FFT_DMA_SUPPORT != 0) && (IFXFFT_FFT_OPTIMIZED == 0) */
|
||||
IfxDma_Dma_Channel outputDmaChannel; /**< \brief Output DMA channel.Used when (IFXFFT_FFT_DMA_SUPPORT != 0) && (IFXFFT_FFT_OPTIMIZED == 0) */
|
||||
IfxDma_Dma_Channel discardDmaChannel; /**< \brief Discard DMA channel. Used when (IFXFFT_FFT_DMA_SUPPORT != 0) && (IFXFFT_FFT_OPTIMIZED == 0) */
|
||||
uint32 flags; /**< \brief Driver flags. Used when (IFXFFT_FFT_DMA_SUPPORT != 0) */
|
||||
uint32 inputIdx; /**< \brief Input interrupt index. Used when (IFXFFT_FFT_DMA_SUPPORT != 0) */
|
||||
uint32 intraIdx; /**< \brief Intra interrupt index. Used when (IFXFFT_FFT_DMA_SUPPORT != 0) */
|
||||
Ifx_SRC_SRCR_Bits srcrOutDis; /**< \brief Cache of discard DMA channel. Used when (IFXFFT_FFT_DMA_SUPPORT != 0) */
|
||||
Ifx_SRC_SRCR_Bits srcrOutEnd; /**< \brief Cache of end of output DMA channel. Used when (IFXFFT_FFT_DMA_SUPPORT != 0) */
|
||||
IfxFft_Fft_Job *job[2]; /**< \brief FFT job handle */
|
||||
} IfxFft_Fft;
|
||||
|
||||
/** \brief Structure for counters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16 input; /**< \brief Input count */
|
||||
uint16 expect; /**< \brief Padding */
|
||||
uint16 output; /**< \brief Output count */
|
||||
uint16 result; /**< \brief Discard */
|
||||
} IfxFft_Fft_Count64;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fft_Fft_DataStructures
|
||||
* \{ */
|
||||
/** \brief Configuration structure of the module
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_FFT *fft; /**< \brief Pointer to FFT registers.Used when (IFXFFT_FFT_OPTIMIZED == 0) */
|
||||
Ifx_LMU *lmu; /**< \brief Pointer to LMU registers.Used when (IFXFFT_FFT_OPTIMIZED == 0) */
|
||||
Ifx_Priority inputPriority; /**< \brief "input loading finished" interrupt priority */
|
||||
Ifx_Priority intraPriority; /**< \brief "intra transfer" interrupt priority */
|
||||
Ifx_Priority outputPriority; /**< \brief "output unloading finished" interrupt priority */
|
||||
IfxSrc_Tos typeOfService; /**< \brief Type of interrupt service */
|
||||
IfxDma_ChannelId inputDmaChannelId; /**< \brief Input DMA channel.Used when (IFXFFT_FFT_DMA_SUPPORT != 0) */
|
||||
IfxDma_ChannelId outputDmaChannelId; /**< \brief Output DMA channel.Used when (IFXFFT_FFT_DMA_SUPPORT != 0) */
|
||||
IfxDma_ChannelId discardDmaChannelId; /**< \brief DMA channel for discarding unused samples. Used when (IFXFFT_FFT_DMA_SUPPORT != 0) */
|
||||
} IfxFft_Fft_Config;
|
||||
|
||||
/** \brief Configuration structure for the FFT job
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxFft_Fft *fft; /**< \brief Pointer To FFT.Used when (IFXFFT_FFT_OPTIMIZED == 0) */
|
||||
uint16 inputLength; /**< \brief Length of the input */
|
||||
uint16 outputLength; /**< \brief Length of the output */
|
||||
IfxFft_Length fftLength; /**< \brief Length of the transform */
|
||||
IfxFft_Input inputFormat; /**< \brief Input format */
|
||||
IfxFft_Output outputFormat; /**< \brief Output format */
|
||||
IfxFft_Operation operation; /**< \brief Operation (FFT / IFFT) */
|
||||
boolean useWindowFunction; /**< \brief Selection to use window function */
|
||||
IFX_CONST void *inputPtr; /**< \brief Pointer to input data */
|
||||
void *outputPtr; /**< \brief Pointer to output data */
|
||||
} IfxFft_Fft_JobConfig;
|
||||
|
||||
/** \brief FFT job handle
|
||||
*/
|
||||
struct IfxFft_Fft_Job_s
|
||||
{
|
||||
IfxFft_Fft *fft; /**< \brief Pointer to FFT registers. Used when (IFXFFT_FFT_OPTIMIZED == 0) */
|
||||
Ifx_FFT_CSR csr; /**< \brief FFT.CSR register duplicate */
|
||||
IFX_CONST void *inputPtr; /**< \brief Input pointer */
|
||||
void *outputPtr; /**< \brief Output pointer */
|
||||
IfxFft_Fft_Count64 count64; /**< \brief Counters */
|
||||
IfxFft_Fft_Job *nextJob; /**< \brief Pointer to the next job */
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fft_Fft_ModuleFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialises the module
|
||||
* \param fft Module handle
|
||||
* \param config Configuration structure of the module
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Fft_Fft_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_initModule(IfxFft_Fft *fft, const IfxFft_Fft_Config *config);
|
||||
|
||||
/** \brief Fills the config structure with default values
|
||||
* \param config Configuration structure of the module
|
||||
* \param fft Pointer to FFT registers
|
||||
* \param lmu Pointer to LMU registers
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Fft_Fft_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_initModuleConfig(IfxFft_Fft_Config *config, Ifx_FFT *fft, Ifx_LMU *lmu);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fft_Fft_InterruptFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief ISR input routine
|
||||
* \param fft Module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_isrInput(IfxFft_Fft *fft);
|
||||
|
||||
/** \brief ISR output routine
|
||||
* \param fft Module handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_isrOutput(IfxFft_Fft *fft);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fft_Fft_TransformFuntions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Clones and links the jobs
|
||||
* \param originalJob Current (original)FFT job handle
|
||||
* \param newJob Modified (new) FFT job handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_cloneAndLinkJobs(IfxFft_Fft_Job *originalJob, IfxFft_Fft_Job *newJob);
|
||||
|
||||
/** \brief Initialises the FFT job
|
||||
* \param job FFT job handle
|
||||
* \param jobConfig Configuration structure for the FFT job
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Fft_Fft_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_initJob(IfxFft_Fft_Job *job, const IfxFft_Fft_JobConfig *jobConfig);
|
||||
|
||||
/** \brief Fills the job configuration structure with default values
|
||||
* \param config Configuration structure for the FFT job
|
||||
* \param fft Module handle
|
||||
* \return None
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Fft_Fft_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_initJobConfig(IfxFft_Fft_JobConfig *config, IfxFft_Fft *fft);
|
||||
|
||||
/** \brief Initialises the window transfer
|
||||
* \param fft Module handle
|
||||
* \param windowData Window data
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_initWindow(IfxFft_Fft *fft, const uint64 *windowData);
|
||||
|
||||
/** \brief Updates the input and output pointers in the FFT job handle
|
||||
* \param job FFT job handle
|
||||
* \param inputPtr Input pointer
|
||||
* \param outputPtr Output pointer
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_modifyDataPointers(IfxFft_Fft_Job *job, const void *inputPtr, void *outputPtr);
|
||||
|
||||
/** \brief Starts the FFT job
|
||||
* \param job FFT job handle
|
||||
* \return Module's ready for start (RFS) status (true / false)
|
||||
*
|
||||
* A coding example can be found in \ref IfxLld_Fft_Fft_Usage
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxFft_Fft_startJob(IfxFft_Fft_Job *job);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFft_Fft_triggerEngine(Ifx_FFT *fft, uint32 csr);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_isrIntra(IfxFft_Fft *fft);
|
||||
|
||||
/** \brief Initialization of DMA
|
||||
* \param fft fft Module handle
|
||||
* \param config pointing to config strucuture of fft
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFft_Fft_initDma(IfxFft_Fft *fft, const IfxFft_Fft_Config *config);
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxFft_Fft_triggerEngine(Ifx_FFT *fft, uint32 csr)
|
||||
{
|
||||
#if IFXFFT_FFT_HW_EXEC
|
||||
fft->CSR.U = csr | (IFX_FFT_CSR_START_MSK << IFX_FFT_CSR_START_OFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXFFT_FFT_H */
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* \file IfxFft.c
|
||||
* \brief FFT basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2016 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxFft.h"
|
||||
@@ -0,0 +1,346 @@
|
||||
/**
|
||||
* \file IfxFft.h
|
||||
* \brief FFT basic functionality
|
||||
* \ingroup IfxLld_Fft
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2017 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Fft_Std_Enumerations Enumerations
|
||||
* \ingroup IfxLld_Fft_Std
|
||||
* \defgroup IfxLld_Fft_Std_UtilityFunctions Utility Functions
|
||||
* \ingroup IfxLld_Fft_Std
|
||||
*/
|
||||
|
||||
#ifndef IFXFFT_H
|
||||
#define IFXFFT_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxFft_cfg.h"
|
||||
#include "Cpu/Std/IfxCpu_Intrinsics.h"
|
||||
#include "Src/Std/IfxSrc.h"
|
||||
#include "IfxFft_reg.h"
|
||||
#include "IfxLmu_reg.h"
|
||||
#include "Scu/Std/IfxScuWdt.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Fft_Std_Enumerations
|
||||
* \{ */
|
||||
/** \brief Input format
|
||||
* Definition in Ifx_FFT.CSR.B.IN.FMT
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxFft_Input_complexSInt32 = 0, /**< \brief 1 complex 32-bit data per 64-bit word */
|
||||
IfxFft_Input_realSInt32 = 1, /**< \brief 2 real 32-bit data per 64-bit word */
|
||||
IfxFft_Input_complexSInt16 = 2, /**< \brief 2 complex 16-bit data per 64-bit word */
|
||||
IfxFft_Input_realSInt16 = 3 /**< \brief 4 real 16-bit data per 64-bit word */
|
||||
} IfxFft_Input;
|
||||
|
||||
/** \brief Length of transform. Log base 2 of the required transform size.
|
||||
* Length must be between 3 (transform of 8) and 11 (transform of 2048).
|
||||
* Definition in Ifx_FFT.CSR.B.LENGTH
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxFft_Length_8 = 3, /**< \brief transform of 8 */
|
||||
IfxFft_Length_16 = 4, /**< \brief transform of 16 */
|
||||
IfxFft_Length_32 = 5, /**< \brief transform of 32 */
|
||||
IfxFft_Length_64 = 6, /**< \brief transform of 64 */
|
||||
IfxFft_Length_128 = 7, /**< \brief transform of 128 */
|
||||
IfxFft_Length_256 = 8, /**< \brief transform of 256 */
|
||||
IfxFft_Length_512 = 9, /**< \brief transform of 512 */
|
||||
IfxFft_Length_1024 = 10 /**< \brief transform of 1024 */
|
||||
} IfxFft_Length;
|
||||
|
||||
/** \brief Operation (FFT / IFFT)
|
||||
* Definition in Ifx_FFT.CSR.B.IFFT
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxFft_Operation_fft = 0, /**< \brief perform FFT */
|
||||
IfxFft_Operation_ifft = 1 /**< \brief perform IFFT */
|
||||
} IfxFft_Operation;
|
||||
|
||||
/** \brief Output format
|
||||
* Definition in Ifx_FFT.CSR.B.OUT.FMT
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxFft_Output_complexSInt32 = 0, /**< \brief 1 complex 32-bit data per 64-bit word */
|
||||
IfxFft_Output_complexSInt16 = 1 /**< \brief 2 complex 16-bit data per 64-bit word */
|
||||
} IfxFft_Output;
|
||||
|
||||
/** \brief OCDS Suspend Control (OCDS.SUS)
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxFft_SuspendMode_none = 0, /**< \brief No suspend */
|
||||
IfxFft_SuspendMode_hard = 1, /**< \brief Hard Suspend */
|
||||
IfxFft_SuspendMode_soft = 2 /**< \brief Soft Suspend */
|
||||
} IfxFft_SuspendMode;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Fft_Std_UtilityFunctions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Disables the FFT module and also the LMU interface
|
||||
* \param fft pointer to FFT registers
|
||||
* \param lmu pointer to LMU registers
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFft_disableModule(Ifx_FFT *fft, Ifx_LMU *lmu);
|
||||
|
||||
/** \brief Enables the FFT module and also the LMU interface
|
||||
* \param fft pointer to FFT registers
|
||||
* \param lmu pointer to LMU registers
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFft_enableModule(Ifx_FFT *fft, Ifx_LMU *lmu);
|
||||
|
||||
/** \brief Returns the input format
|
||||
* \param fft pointer to FFT registers
|
||||
* \return Input format
|
||||
*/
|
||||
IFX_INLINE IfxFft_Input IfxFft_getInputFormat(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Returns the length of the transform (length code, 3 to 10)
|
||||
* \param fft pointer to FFT registers
|
||||
* \return Length of the transform (length code)
|
||||
*/
|
||||
IFX_INLINE IfxFft_Length IfxFft_getLength(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Converts the given input length into the transform length code, to write into Ifx_FFT.CSR.B.LENGTH
|
||||
* \param length Input length of the transform
|
||||
* \return Length of the transform (code, 3 to 10)
|
||||
*/
|
||||
IFX_INLINE IfxFft_Length IfxFft_getLengthCode(uint16 length);
|
||||
|
||||
/** \brief Retruns the actual length of the transform from the length code
|
||||
* \param length Length of transform
|
||||
* \return Actual length of the transform
|
||||
*/
|
||||
IFX_INLINE uint16 IfxFft_getLengthFromCode(IfxFft_Length length);
|
||||
|
||||
/** \brief Returns the output format
|
||||
* \param fft pointer to FFT registers
|
||||
* \return Output format
|
||||
*/
|
||||
IFX_INLINE IfxFft_Output IfxFft_getOutputFormat(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Returns the status of FFT DONE request
|
||||
* \param fft pointer to FFT registers
|
||||
* \return Status of FFT DONE request
|
||||
*/
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxFft_getSrcPointerDone(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Returns the status of FFT RFS request
|
||||
* \param fft pointer to FFT registers
|
||||
* \return Status of FFT RFS request
|
||||
*/
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxFft_getSrcPointerRfs(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Returns the actual length of the transform
|
||||
* \param fft pointer to FFT registers
|
||||
* \return Actual length of the transform ()
|
||||
*/
|
||||
IFX_INLINE uint16 IfxFft_getTransformLength(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Returns the status of whether the FFT Engine is Idle or has at least one transform in operation.
|
||||
* \param fft pointer to FFT registers
|
||||
* \return (true / false)
|
||||
*/
|
||||
IFX_INLINE boolean IfxFft_isEngineBusy(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Returns the status of whether the module is enabled or not
|
||||
* \param fft pointer to FFT registers
|
||||
* \return (true / false)
|
||||
*/
|
||||
IFX_INLINE boolean IfxFft_isModuleEnabled(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Returns the module's suspend state.
|
||||
* TRUE :if module is suspended.
|
||||
* FALSE:if module is not yet suspended.
|
||||
* \param fft Pointer to FFT module registers
|
||||
* \return Suspend status (TRUE / FALSE)
|
||||
*/
|
||||
IFX_INLINE boolean IfxFft_isModuleSuspended(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Returns the status of whether the module can accept a START operation or not
|
||||
* \param fft Pointer to FFT registers
|
||||
* \return (true / false)
|
||||
*/
|
||||
IFX_INLINE boolean IfxFft_isReadyForStart(Ifx_FFT *fft);
|
||||
|
||||
/** \brief Configure the Module to Hard/Soft suspend mode.
|
||||
* Note: The api works only when the OCDS is enabled and in Supervisor Mode. When OCDS is disabled the OCS suspend control is ineffective.
|
||||
* \param fft Pointer to FFT module registers
|
||||
* \param mode Module suspend mode
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFft_setSuspendMode(Ifx_FFT *fft, IfxFft_SuspendMode mode);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxFft_disableModule(Ifx_FFT *fft, Ifx_LMU *lmu)
|
||||
{
|
||||
uint16 password = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(password);
|
||||
// FFT clock disable
|
||||
fft->CLC.B.DISR = 1;
|
||||
IfxScuWdt_setCpuEndinit(password);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFft_enableModule(Ifx_FFT *fft, Ifx_LMU *lmu)
|
||||
{
|
||||
uint16 password = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(password);
|
||||
// FFT clock enable
|
||||
fft->CLC.U = 0x0;
|
||||
IfxScuWdt_setCpuEndinit(password);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE IfxFft_Input IfxFft_getInputFormat(Ifx_FFT *fft)
|
||||
{
|
||||
return (IfxFft_Input)fft->CSR.B.IN_FMT;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE IfxFft_Length IfxFft_getLength(Ifx_FFT *fft)
|
||||
{
|
||||
return (IfxFft_Length)fft->CSR.B.LENGTH;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE IfxFft_Length IfxFft_getLengthCode(uint16 length)
|
||||
{
|
||||
return (IfxFft_Length)(31 - __clz((uint32)length));
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint16 IfxFft_getLengthFromCode(IfxFft_Length length)
|
||||
{
|
||||
return 1 << (uint32)length;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE IfxFft_Output IfxFft_getOutputFormat(Ifx_FFT *fft)
|
||||
{
|
||||
return (IfxFft_Output)fft->CSR.B.OUT_FMT;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxFft_getSrcPointerDone(Ifx_FFT *fft)
|
||||
{
|
||||
// only a single FFT available, therefore no check for the fft pointer required
|
||||
return &MODULE_SRC.FFT.FFT[0].DONE;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE volatile Ifx_SRC_SRCR *IfxFft_getSrcPointerRfs(Ifx_FFT *fft)
|
||||
{
|
||||
// only a single FFT available, therefore no check for the fft pointer required
|
||||
return &MODULE_SRC.FFT.FFT[0].RFS;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint16 IfxFft_getTransformLength(Ifx_FFT *fft)
|
||||
{
|
||||
return 1U << fft->CSR.B.LENGTH;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxFft_isEngineBusy(Ifx_FFT *fft)
|
||||
{
|
||||
return fft->CSR.B.BUSY != 0;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxFft_isModuleEnabled(Ifx_FFT *fft)
|
||||
{
|
||||
return fft->CLC.B.DISS == 0;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxFft_isModuleSuspended(Ifx_FFT *fft)
|
||||
{
|
||||
Ifx_FFT_OCS ocs;
|
||||
|
||||
// read the status
|
||||
ocs.U = fft->OCS.U;
|
||||
|
||||
// return the status
|
||||
return ocs.B.SUSSTA;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxFft_isReadyForStart(Ifx_FFT *fft)
|
||||
{
|
||||
return fft->CSR.B.RFS != 0;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFft_setSuspendMode(Ifx_FFT *fft, IfxFft_SuspendMode mode)
|
||||
{
|
||||
Ifx_FFT_OCS ocs;
|
||||
|
||||
// remove protection and configure the suspend mode.
|
||||
ocs.B.SUS_P = 1;
|
||||
ocs.B.SUS = mode;
|
||||
fft->OCS.U = ocs.U;
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXFFT_H */
|
||||
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* \file IfxFlash.c
|
||||
* \brief FLASH basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxFlash.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxFlash_clearCorrectableErrorTracking(IfxFlash_PortId portId)
|
||||
{
|
||||
MODULE_FLASH0.CBAB[portId].CFG.B.CLR = 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxFlash_clearUncorrectableErrorTracking(IfxFlash_PortId portId)
|
||||
{
|
||||
MODULE_FLASH0.UBAB[portId].CFG.B.CLR = 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxFlash_disableCorrectableErrorTracking(IfxFlash_PortId portId, boolean disable)
|
||||
{
|
||||
MODULE_FLASH0.CBAB[portId].CFG.B.DIS = disable;
|
||||
}
|
||||
|
||||
|
||||
void IfxFlash_disableUncorrectableErrorTracking(IfxFlash_PortId portId, boolean disable)
|
||||
{
|
||||
MODULE_FLASH0.UBAB[portId].CFG.B.DIS = disable;
|
||||
}
|
||||
|
||||
|
||||
void IfxFlash_disableWriteProtection(uint32 flash, IfxFlash_UcbType ucb, uint32 *password)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(flash);
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0x553c);
|
||||
uint32 i;
|
||||
|
||||
*addr1 = ucb;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
*addr1 = password[i];
|
||||
}
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxFlash_getTrackedCorrectableErrors(IfxFlash_PortId portId, IfxFlash_ErrorTracking_Address *trackedFlashAdresses)
|
||||
{
|
||||
uint32 numErrors = 0;
|
||||
uint32 fillingLevel = MODULE_FLASH0.CBAB[portId].STAT.U;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0;
|
||||
i < IFXFLASH_ERROR_TRACKING_MAX_CORRECTABLE_ERRORS &&
|
||||
(fillingLevel & (1 << i)) != 0;
|
||||
++i)
|
||||
{
|
||||
Ifx_FLASH_CBAB_TOP top;
|
||||
top.U = MODULE_FLASH0.CBAB[portId].TOP.U;
|
||||
|
||||
if (top.B.VLD)
|
||||
{
|
||||
trackedFlashAdresses[numErrors].address = 0xa0000000 | (top.B.ADDR << 5);
|
||||
trackedFlashAdresses[numErrors].errorType = (IfxFlash_ErrorTracking)top.B.ERR;
|
||||
++numErrors;
|
||||
}
|
||||
|
||||
// clear entry
|
||||
MODULE_FLASH0.CBAB[portId].TOP.U = (((uint32)1) << 31);
|
||||
}
|
||||
|
||||
return numErrors;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxFlash_getTrackedUncorrectableErrors(IfxFlash_PortId portId, IfxFlash_ErrorTracking_Address *trackedFlashAdresses)
|
||||
{
|
||||
uint32 numErrors = 0;
|
||||
uint32 fillingLevel = MODULE_FLASH0.UBAB[portId].STAT.U;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0;
|
||||
i < IFXFLASH_ERROR_TRACKING_MAX_UNCORRECTABLE_ERRORS &&
|
||||
(fillingLevel & (1 << i)) != 0;
|
||||
++i)
|
||||
{
|
||||
Ifx_FLASH_UBAB_TOP top;
|
||||
top.U = MODULE_FLASH0.UBAB[portId].TOP.U;
|
||||
|
||||
if (top.B.VLD)
|
||||
{
|
||||
trackedFlashAdresses[numErrors].address = 0xa0000000 | (top.B.ADDR << 5);
|
||||
trackedFlashAdresses[numErrors].errorType = (IfxFlash_ErrorTracking)top.B.ERR;
|
||||
++numErrors;
|
||||
}
|
||||
|
||||
// clear entry
|
||||
MODULE_FLASH0.UBAB[portId].TOP.U = (((uint32)1) << 31);
|
||||
}
|
||||
|
||||
return numErrors;
|
||||
}
|
||||
|
||||
|
||||
void IfxFlash_selectCorrectableErrorTracking(IfxFlash_PortId portId, IfxFlash_ErrorTracking errorTracking)
|
||||
{
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR,
|
||||
errorTracking == IfxFlash_ErrorTracking_none ||
|
||||
errorTracking == IfxFlash_ErrorTracking_correctedSingleBitError ||
|
||||
errorTracking == IfxFlash_ErrorTracking_correctedDoubleBitError ||
|
||||
errorTracking == IfxFlash_ErrorTracking_correctedSingleOrDoubleBitError);
|
||||
|
||||
MODULE_FLASH0.CBAB[portId].CFG.B.SEL = errorTracking;
|
||||
}
|
||||
|
||||
|
||||
void IfxFlash_selectUncorrectableErrorTracking(IfxFlash_PortId portId, IfxFlash_ErrorTracking errorTracking)
|
||||
{
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR,
|
||||
errorTracking == IfxFlash_ErrorTracking_none ||
|
||||
errorTracking == IfxFlash_ErrorTracking_uncorrectableMultiBitError);
|
||||
|
||||
MODULE_FLASH0.UBAB[portId].CFG.B.SEL = errorTracking;
|
||||
}
|
||||
@@ -0,0 +1,790 @@
|
||||
/**
|
||||
* \file IfxFlash.h
|
||||
* \brief FLASH basic functionality
|
||||
* \ingroup IfxLld_Flash
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Flash_Std_Enumerations Enumerations
|
||||
* \ingroup IfxLld_Flash_Std
|
||||
* \defgroup IfxLld_Flash_Std_CommandSequence CommandSequence Functions
|
||||
* \ingroup IfxLld_Flash_Std
|
||||
* \defgroup IfxLld_Flash_Std_ErrorTracking Error Tracking Functions
|
||||
* \ingroup IfxLld_Flash_Std
|
||||
*/
|
||||
|
||||
#ifndef IFXFLAS_H
|
||||
#define IFXFLAS_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxFlash_cfg.h"
|
||||
#include "_Utilities/Ifx_Assert.h"
|
||||
#include "IfxFlash_reg.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Flash_Std_Enumerations
|
||||
* \{ */
|
||||
/** \brief enumeration for Flash Error tracking
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxFlash_ErrorTracking_none = 0, /**< \brief Error tracking disabled */
|
||||
IfxFlash_ErrorTracking_correctedSingleBitError = 1, /**< \brief corrected single bit errors */
|
||||
IfxFlash_ErrorTracking_correctedDoubleBitError = 2, /**< \brief Corrected double-bit errors */
|
||||
IfxFlash_ErrorTracking_correctedSingleOrDoubleBitError = 3, /**< \brief Corrected single-bit and double-bit errors */
|
||||
IfxFlash_ErrorTracking_uncorrectableMultiBitError = 4 /**< \brief Detected uncorrectable errors */
|
||||
} IfxFlash_ErrorTracking;
|
||||
|
||||
/** \brief Corrected/UnCorrected Bits Address Buffer Port Id
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxFlash_PortId_PortId_0 = 0, /**< \brief Port Id 0 */
|
||||
IfxFlash_PortId_PortId_1 = 1 /**< \brief Port Id 1 */
|
||||
} IfxFlash_PortId;
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Flash_Std_Enumerations
|
||||
* \{ */
|
||||
/** \brief Error tracking address structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32 address; /**< \brief Flash address for error tracking */
|
||||
IfxFlash_ErrorTracking errorType; /**< \brief Error type */
|
||||
} IfxFlash_ErrorTracking_Address;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Flash_Std_CommandSequence
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Performs the "Clear Status" sequence. Operation and error flags are cleared.
|
||||
* \param flash selects the flash (PMU) module
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_clearStatus(uint32 flash);
|
||||
|
||||
/** \brief Performs the sequence for entering program page mode
|
||||
* \param pageAddr pageAddr specifies the page being written - the command sequence will be varied accordingly
|
||||
* \return 0 on success, != 0 if invalid or not available page is selected
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* unsigned int pageAddr = IFXFLASH_DFLASH_START + page*IFXFLASH_DFLASH_PAGE_LENGTH;
|
||||
*
|
||||
* // enter page mode
|
||||
* IfxFlash_enterPageMode(pageAddr);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE uint8 IfxFlash_enterPageMode(uint32 pageAddr);
|
||||
|
||||
/** \brief Performs the erase sequence for n sectors in program or data flash
|
||||
* \param sectorAddr sector address
|
||||
* \param numSector the no.of sectors to be erased
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // erase the first and second data flash
|
||||
* IfxFlash_eraseMultiplePhysicalSectors(IFXFLASH_DFLASH_START,2);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_eraseMultiplePhysicalSectors(uint32 sectorAddr, uint32 numSector);
|
||||
|
||||
/** \brief Performs the erase sequence for n sectors in program or data flash
|
||||
* \param sectorAddr sector address
|
||||
* \param numSector the no.of sectors to be erased
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // erase logical sectors of program flash
|
||||
* IfxFlash_eraseMultipleSectors(pFlashTableLog[sector].start,2);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_eraseMultipleSectors(uint32 sectorAddr, uint32 numSector);
|
||||
|
||||
/** \brief Performs the erase sequence for a physical sector in program or data flash
|
||||
* \param sectorAddr sector address
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // erase the first data flash
|
||||
* IfxFlash_erasePhysicalSector(IFXFLASH_DFLASH_START);
|
||||
*
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_erasePhysicalSector(uint32 sectorAddr);
|
||||
|
||||
/** \brief Performs the erase sequence for a sector in program or data flash.
|
||||
* \param sectorAddr sector address
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
*
|
||||
* // erase all sectors of program flash
|
||||
* for(sector=0; sector<IFXFLASH_PFLASH_NO_OF_LOG_SECTORS; ++sector) {
|
||||
* // get address from predefined table
|
||||
* unsigned int sector_addr = pFlashTableLog[sector].start;
|
||||
* // erase sector
|
||||
* IfxFlash_eraseSector(sector_addr);
|
||||
* }
|
||||
*
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_eraseSector(uint32 sectorAddr);
|
||||
|
||||
/** \brief Performs the "Erase Verify" sequence for multiple sectors
|
||||
* \param sectorAddr sector address which should be verified
|
||||
* \param numSector no.of sectors to be operated on
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_eraseVerifyMultipleSectors(uint32 sectorAddr, uint32 numSector);
|
||||
|
||||
/** \brief Performs the "Erase Verify" sequence
|
||||
* \param sectorAddr sector address which should be verified
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_eraseVerifySector(uint32 sectorAddr);
|
||||
|
||||
/** \brief performs a load page sequence with a single 64bit access
|
||||
* \param pageAddr pageAddr start address of page which should be programmed
|
||||
* \param wordL Lower Address word
|
||||
* \param wordU Upper address word
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // load 64bit into assembly buffer of program flash
|
||||
* IfxFlash_loadPage(IFXFLASH_PFLASH_START, 0x55555555, 0xaaaaaaaa);
|
||||
*
|
||||
* // load 64bit into assembly buffer of data flash
|
||||
* IfxFlash_loadPage(0XAF000000, 0x55555555, 0xaaaaaaaa);
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_loadPage(uint32 pageAddr, uint32 wordL, uint32 wordU);
|
||||
|
||||
/** \brief performs a load page sequence with two 32bit accesses
|
||||
* \param pageAddr pageAddr start address of page which should be programmed
|
||||
* \param wordL Lower Address word
|
||||
* \param wordU Upper Address word
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // load 2*32bit into assembly buffer of program flash
|
||||
* IfxFlash_loadPage2X32(IFXFLASH_PFLASH_START, 0x55555555, 0xaaaaaaaa);
|
||||
*
|
||||
* // load 2*32bit into assembly buffer of data flash
|
||||
* IfxFlash_loadPage2X32(0XAF000000, 0x55555555, 0xaaaaaaaa);
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_loadPage2X32(uint32 pageAddr, uint32 wordL, uint32 wordU);
|
||||
|
||||
/** \brief reset to read mode
|
||||
* \param flash flash selects the flash (PMU) module
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // reset to read mode
|
||||
* IfxFlash_resetToRead(0);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_resetToRead(uint32 flash);
|
||||
|
||||
/** \brief Performs the "Resume Protection" sequence
|
||||
* \param flash selects the flash (PMU) module
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_resumeProtection(uint32 flash);
|
||||
|
||||
/** \brief Performs the "Suspend Resume" sequence for multiple sectors
|
||||
* \param sectorAddr sector address
|
||||
* \param numSector the no.of sectors to be operated on
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_suspendResumeMultipleSectors(uint32 sectorAddr, uint32 numSector);
|
||||
|
||||
/** \brief Performs the "Suspend Resume" sequence
|
||||
* \param sectorAddr sector address which should be resumed
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_suspendResumeSector(uint32 sectorAddr);
|
||||
|
||||
/** \brief Polls the selected status flag in flash status register until it turns to 0
|
||||
* \param flash selects the flash (PMU) module
|
||||
* \param flashType selects the flash type
|
||||
* \return 0 on success, != 0 if invalid or not available page is selected
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // wait until data flash 0 is unbusy
|
||||
* IfxFlash_waitUnbusy(0, IfxFlash_FlashType_D0);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE uint8 IfxFlash_waitUnbusy(uint32 flash, IfxFlash_FlashType flashType);
|
||||
|
||||
/** \brief Performs the "Write Burst" sequence, similar to write page but performs a burst transfer instead of page.Make sure the appropriate amount of data is loaded using load page command
|
||||
* \param pageAddr start address of page which should be programmed
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // program the second page of the first sector of the Program Flash
|
||||
* IfxFlash_writeBurst(0xa0000100);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_writeBurst(uint32 pageAddr);
|
||||
|
||||
/** \brief Performs the "Write Page" sequence
|
||||
* \param pageAddr start address of page which should be programmed
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // program the second page of the first sector of the Program Flash
|
||||
* IfxFlash_writePage(0xa0000100);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_writePage(uint32 pageAddr);
|
||||
|
||||
/** \brief Performs the "Write Page Once" sequence, similar to write page but performs a program verify after writing.
|
||||
* \param pageAddr start address of page which should be programmed
|
||||
* \return None
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
*
|
||||
* // program the second page of the first sector of the Program Flash
|
||||
* IfxFlash_writePageOnce(0xa0000100);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_INLINE void IfxFlash_writePageOnce(uint32 pageAddr);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief The password protection of the selected UCB (if this UCB offers this feature) is temporarily disabled. The command fails by setting PROER when any of the supplied PWs does not match. In this case until the next application reset all further calls of "Disable Protection" fail with PROER independent of the supplied password.
|
||||
* \param flash selects the flash (PMU) module
|
||||
* \param ucb selects the user configuration block (0 for UCB0, 1 for UCB1, 5 for UCB_HSMC)
|
||||
* \param password password pointer to an array of 8 words
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFlash_disableWriteProtection(uint32 flash, IfxFlash_UcbType ucb, uint32 *password);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Flash_Std_ErrorTracking
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Clear the Correctable errors in Corrected Bits Address Buffer Configuration Port x (CBABCFGx) register
|
||||
* \param portId Corrected Bits Address Buffer Port Id
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFlash_clearCorrectableErrorTracking(IfxFlash_PortId portId);
|
||||
|
||||
/** \brief Select the uncorrectable errors in UnCorrectable Bits Address Buffer Configuration Port x (UBABCFGx) register
|
||||
* \param portId UnCorrected Bits Address Buffer Port Id
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFlash_clearUncorrectableErrorTracking(IfxFlash_PortId portId);
|
||||
|
||||
/** \brief Disable the Correctable errors in Corrected Bits Address Buffer Configuration Port x (CBABCFGx) register
|
||||
* \param portId Corrected Bits Address Buffer Port Id
|
||||
* \param disable Disable/enable the error tracking
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFlash_disableCorrectableErrorTracking(IfxFlash_PortId portId, boolean disable);
|
||||
|
||||
/** \brief Clear the uncorrectable errors in UnCorrectable Bits Address Buffer Configuration Port x (UBABCFGx) register
|
||||
* \param portId UnCorrected Bits Address Buffer Port Id
|
||||
* \param disable Disable/enable the error tracking
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxFlash_disableUncorrectableErrorTracking(IfxFlash_PortId portId, boolean disable);
|
||||
|
||||
/** \brief Returns the tracked correctable error addresses, error types and number of errors which are stored in the CBAB registers.
|
||||
* \param portId Corrected Bits Address Buffer Port Id
|
||||
* \param trackedFlashAdresses tracked flash addresses for correctable errors
|
||||
* \return numErrors
|
||||
*
|
||||
* Example usage to print out tracked errors :
|
||||
*
|
||||
* \code
|
||||
* {
|
||||
* IfxFlash_ErrorTracking_Address trackedAddresses[IFX_FLASH_ERROR_TRACKING_MAX_CORRECTABLE_ERRORS];
|
||||
* IfxFlash_portId portId = 0;
|
||||
* uint8 numTrackedAddresses = IfxFlash_getTrackedCorrectableErrors(portId, trackedAddresses);
|
||||
*
|
||||
* for(int i=0; i<numTrackedAddresses; ++i) {
|
||||
* printf("%d: A:0x%04x Error Type:%d \n",
|
||||
* i,
|
||||
* trackedAddresses[i].address,
|
||||
* trackedAddresses[i].errorType);
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxFlash_getTrackedCorrectableErrors(IfxFlash_PortId portId, IfxFlash_ErrorTracking_Address *trackedFlashAdresses);
|
||||
|
||||
/** \brief Returns the tracked uncorrectable error addresses, error types and number of errors which are stored in the UBAB registers.
|
||||
* \param portId UnCorrected Bits Address Buffer Port Id
|
||||
* \param trackedFlashAdresses tracked flash addresses for uncorrectable errors
|
||||
* \return numErrors
|
||||
*
|
||||
* Example usage to print out tracked errors :
|
||||
*
|
||||
* \code
|
||||
* {
|
||||
* IfxFlash_ErrorTracking_Address trackedAddresses[IFX_FLASH_ERROR_TRACKING_MAX_UNCORRECTABLE_ERRORS];
|
||||
* IfxFlash_portId portId = 0;
|
||||
* uint8 numTrackedAddresses = IfxFlash_getTrackedUnCorrectableErrors(portId, trackedAddresses);
|
||||
*
|
||||
* for(int i=0; i<numTrackedAddresses; ++i) {
|
||||
* printf("%d: A:0x%04x Error Type:%d \n",
|
||||
* i,
|
||||
* trackedAddresses[i].address,
|
||||
* trackedAddresses[i].errorType);
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxFlash_getTrackedUncorrectableErrors(IfxFlash_PortId portId, IfxFlash_ErrorTracking_Address *trackedFlashAdresses);
|
||||
|
||||
/** \brief Enables error tracking for correctable flash errors
|
||||
* \param portId Corrected Bits Address Buffer Port Id
|
||||
* \param errorTracking Error Tracking to be selected
|
||||
* \return None
|
||||
*
|
||||
* Usage example: how to enable error tracking for two flash ports:
|
||||
* \code
|
||||
* // enable error tracking
|
||||
* {
|
||||
* uint16 password = IfxScuWdt_getCpuWatchdogPassword();
|
||||
* IfxScuWdt_clearCpuEndinit(password);
|
||||
*
|
||||
* // PFlash0
|
||||
* IfxFlash_selectCorrectableErrorTracking(IfxFlash_PortId_PortId_0, IfxFlash_ErrorTracking_correctedSingleOrDoubleBitError);
|
||||
* IfxFlash_selectUncorrectableErrorTracking(IfxFlash_PortId_PortId_0, IfxFlash_ErrorTracking_uncorrectableMultiBitError);
|
||||
*
|
||||
* // PFlash1
|
||||
* IfxFlash_selectCorrectableErrorTracking(IfxFlash_PortId_PortId_1, IfxFlash_ErrorTracking_correctedSingleOrDoubleBitError);
|
||||
* IfxFlash_selectUncorrectableErrorTracking(IfxFlash_PortId_PortId_1, IfxFlash_ErrorTracking_uncorrectableMultiBitError);
|
||||
*
|
||||
* IfxScuWdt_setCpuEndinit(password);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFlash_selectCorrectableErrorTracking(IfxFlash_PortId portId, IfxFlash_ErrorTracking errorTracking);
|
||||
|
||||
/** \brief Enables error tracking for uncorrectable flash errors
|
||||
* \param portId UnCorrected Bits Address Buffer Port Id
|
||||
* \param errorTracking Error Tracking to be selected
|
||||
* \return None
|
||||
*
|
||||
* Usage example: see \ref IfxFlash_selectCorrectableErrorTracking
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxFlash_selectUncorrectableErrorTracking(IfxFlash_PortId portId, IfxFlash_ErrorTracking errorTracking);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief This function will wait till all the flash banks are out of busy state
|
||||
* \return Return 0 on success.Success means none of the flash banks are in busy state.
|
||||
*/
|
||||
IFX_INLINE boolean IfxFlash_waitUnbusyAll(void);
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxFlash_clearStatus(uint32 flash)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(flash);
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0x5554);
|
||||
|
||||
*addr1 = 0xFA;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint8 IfxFlash_enterPageMode(uint32 pageAddr)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0x5554);
|
||||
|
||||
if ((pageAddr & 0xff000000) == 0xa0000000) // program flash
|
||||
{
|
||||
*addr1 = 0x50;
|
||||
return 0;
|
||||
}
|
||||
else if ((pageAddr & 0xff000000) == 0xaf000000) // data flash
|
||||
{
|
||||
*addr1 = 0x5D;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__dsync();
|
||||
return 1; // invalid flash address
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_eraseMultiplePhysicalSectors(uint32 sectorAddr, uint32 numSector)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = sectorAddr;
|
||||
*addr2 = numSector;
|
||||
*addr3 = 0x80;
|
||||
*addr4 = 0x5a;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_eraseMultipleSectors(uint32 sectorAddr, uint32 numSector)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = sectorAddr;
|
||||
*addr2 = numSector;
|
||||
*addr3 = 0x80;
|
||||
*addr4 = 0x50;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_erasePhysicalSector(uint32 sectorAddr)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = sectorAddr;
|
||||
*addr2 = 1;
|
||||
*addr3 = 0x80;
|
||||
*addr4 = 0x5a;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_eraseSector(uint32 sectorAddr)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = sectorAddr;
|
||||
*addr2 = 1;
|
||||
*addr3 = 0x80;
|
||||
*addr4 = 0x50;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_eraseVerifyMultipleSectors(uint32 sectorAddr, uint32 numSector)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = sectorAddr;
|
||||
*addr2 = numSector;
|
||||
*addr3 = 0x80;
|
||||
*addr4 = 0x5F;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_eraseVerifySector(uint32 sectorAddr)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = sectorAddr;
|
||||
*addr2 = 1;
|
||||
*addr3 = 0x80;
|
||||
*addr4 = 0x5F;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_loadPage(uint32 pageAddr, uint32 wordL, uint32 wordU)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(pageAddr);
|
||||
uint64 *addr1 = (uint64 *)(IFXFLASH_CMD_BASE_ADDRESS | 0x55f0);
|
||||
|
||||
__st64_lu(addr1, wordL, wordU);
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_loadPage2X32(uint32 pageAddr, uint32 wordL, uint32 wordU)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(pageAddr);
|
||||
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0x55f0);
|
||||
|
||||
*addr1 = wordL;
|
||||
addr1++;
|
||||
*addr1 = wordU;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_resetToRead(uint32 flash)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(flash);
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0x5554);
|
||||
*addr1 = 0xf0;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_resumeProtection(uint32 flash)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(flash);
|
||||
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0x5554);
|
||||
|
||||
*addr1 = 0xF5;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_suspendResumeMultipleSectors(uint32 sectorAddr, uint32 numSector)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = sectorAddr;
|
||||
*addr2 = numSector;
|
||||
*addr3 = 0x70;
|
||||
*addr4 = 0xCC;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_suspendResumeSector(uint32 sectorAddr)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = sectorAddr;
|
||||
*addr2 = 1;
|
||||
*addr3 = 0x70;
|
||||
*addr4 = 0xCC;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE uint8 IfxFlash_waitUnbusy(uint32 flash, IfxFlash_FlashType flashType)
|
||||
{
|
||||
if (flash == 0)
|
||||
{
|
||||
while (FLASH0_FSR.U & (1 << flashType))
|
||||
{}
|
||||
}
|
||||
|
||||
#if IFXFLASH_NUM_FLASH_MODULES > 1
|
||||
else if (flash == 1)
|
||||
{
|
||||
while (FLASH1_FSR.U & (1 << flashType))
|
||||
{}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
return 1; // invalid flash selected
|
||||
}
|
||||
__dsync();
|
||||
return 0; // finished
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_writeBurst(uint32 pageAddr)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = pageAddr;
|
||||
*addr2 = 0x00;
|
||||
*addr3 = 0xa0;
|
||||
*addr4 = 0x7a;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_writePage(uint32 pageAddr)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = pageAddr;
|
||||
*addr2 = 0x00;
|
||||
*addr3 = 0xa0;
|
||||
*addr4 = 0xaa;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxFlash_writePageOnce(uint32 pageAddr)
|
||||
{
|
||||
volatile uint32 *addr1 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa50);
|
||||
volatile uint32 *addr2 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaa58);
|
||||
volatile uint32 *addr3 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
volatile uint32 *addr4 = (volatile uint32 *)(IFXFLASH_CMD_BASE_ADDRESS | 0xaaa8);
|
||||
|
||||
*addr1 = pageAddr;
|
||||
*addr2 = 0x00;
|
||||
*addr3 = 0xa0;
|
||||
*addr4 = 0x9a;
|
||||
|
||||
__dsync();
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxFlash_waitUnbusyAll(void)
|
||||
{
|
||||
while (FLASH0_FSR.U & 0x1EU)
|
||||
{}
|
||||
|
||||
__dsync();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXFLAS_H */
|
||||
@@ -0,0 +1,565 @@
|
||||
/**
|
||||
* \file IfxGpt12_IncrEnc.c
|
||||
* \brief GPT12 INCRENC details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGpt12_IncrEnc.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Update internal data when incremental mode is using T2.\n
|
||||
* This function shall be periodically called
|
||||
* \param driver driver handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGpt12_IncrEnc_updateFromT2(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief Update internal data when incremental mode is using T3.\n
|
||||
* This function shall be periodically called
|
||||
* \param driver driver handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGpt12_IncrEnc_updateFromT3(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief Updates the speed
|
||||
* \param driver driver handle
|
||||
* \param newPosition new position
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGpt12_IncrEnc_updateSpeedFromT2(IfxGpt12_IncrEnc *driver, sint32 newPosition);
|
||||
|
||||
/** \brief Updates the speed
|
||||
* \param driver driver handle
|
||||
* \param newPosition new position
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGpt12_IncrEnc_updateSpeedFromT3(IfxGpt12_IncrEnc *driver, sint32 newPosition);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
float32 IfxGpt12_IncrEnc_getAbsolutePosition(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return ((float32)driver->turn + (float32)driver->rawPosition / (float32)driver->resolution) * 2.0 * IFX_PI;
|
||||
}
|
||||
|
||||
|
||||
IfxStdIf_Pos_Dir IfxGpt12_IncrEnc_getDirection(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return driver->direction;
|
||||
}
|
||||
|
||||
|
||||
IfxStdIf_Pos_Status IfxGpt12_IncrEnc_getFault(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return driver->status;
|
||||
}
|
||||
|
||||
|
||||
sint32 IfxGpt12_IncrEnc_getOffset(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return driver->offset;
|
||||
}
|
||||
|
||||
|
||||
uint16 IfxGpt12_IncrEnc_getPeriodPerRotation(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(driver)
|
||||
return 1; /* Period per rotation is 1*/
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGpt12_IncrEnc_getPosition(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return (float32)driver->rawPosition * driver->positionConst;
|
||||
}
|
||||
|
||||
|
||||
sint32 IfxGpt12_IncrEnc_getRawPosition(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return driver->rawPosition;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGpt12_IncrEnc_getRefreshPeriod(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return driver->updatePeriod;
|
||||
}
|
||||
|
||||
|
||||
sint32 IfxGpt12_IncrEnc_getResolution(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return driver->resolution;
|
||||
}
|
||||
|
||||
|
||||
IfxStdIf_Pos_SensorType IfxGpt12_IncrEnc_getSensorType(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(driver)
|
||||
return IfxStdIf_Pos_SensorType_encoder;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGpt12_IncrEnc_getSpeed(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return driver->speed;
|
||||
}
|
||||
|
||||
|
||||
sint32 IfxGpt12_IncrEnc_getTurn(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
return driver->turn;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGpt12_IncrEnc_init(IfxGpt12_IncrEnc *driver, const IfxGpt12_IncrEnc_Config *config)
|
||||
{
|
||||
boolean status = TRUE;
|
||||
Ifx_GPT12 *gpt12 = config->module;
|
||||
|
||||
driver->module = gpt12;
|
||||
|
||||
driver->offset = config->base.offset;
|
||||
driver->resolution = config->base.resolution * config->base.resolutionFactor;
|
||||
driver->positionConst = 1.0 / (float32)driver->resolution * 2.0 * IFX_PI;
|
||||
driver->speedModeThreshold = config->base.speedModeThreshold;
|
||||
IfxGpt12_IncrEnc_setRefreshPeriod(driver, config->base.updatePeriod);
|
||||
|
||||
driver->status.status = 0;
|
||||
driver->status.B.notSynchronised = 1;
|
||||
driver->minSpeed = config->base.minSpeed;
|
||||
driver->maxSpeed = config->base.maxSpeed;
|
||||
|
||||
driver->rawPosition = 0;
|
||||
driver->speed = 0;
|
||||
driver->direction = IfxStdIf_Pos_Dir_unknown;
|
||||
driver->turn = 0;
|
||||
|
||||
if (config->pinA->timer == 3)
|
||||
{
|
||||
/* T3 Configuration */
|
||||
IfxGpt12_T3_setMode(gpt12, IfxGpt12_Mode_incrementalInterfaceEdgeDetection);
|
||||
|
||||
switch (config->base.resolutionFactor)
|
||||
{
|
||||
case IfxStdIf_Pos_ResolutionFactor_twoFold:
|
||||
IfxGpt12_T3_setIncrementalInterfaceInputMode(gpt12, IfxGpt12_IncrementalInterfaceInputMode_bothEdgesTxIN);
|
||||
break;
|
||||
case IfxStdIf_Pos_ResolutionFactor_fourFold:
|
||||
IfxGpt12_T3_setIncrementalInterfaceInputMode(gpt12, IfxGpt12_IncrementalInterfaceInputMode_bothEdgesTxINOrTxEUD);
|
||||
break;
|
||||
default:
|
||||
status = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
IfxGpt12_T3_setDirectionSource(gpt12, IfxGpt12_TimerDirectionSource_external);
|
||||
IfxGpt12_T3_setTimerDirection(gpt12, config->base.reversed ? IfxGpt12_TimerDirection_up : IfxGpt12_TimerDirection_down);
|
||||
IfxGpt12_T3_enableOutput(gpt12, FALSE);
|
||||
IfxGpt12_T3_run(gpt12, IfxGpt12_TimerRun_start);
|
||||
|
||||
if (config->pinZ != NULL_PTR)
|
||||
{ /* Only configure T4 if zero signal is available. Zero has to be on T4IN */
|
||||
/* T4 Configuration */
|
||||
IfxGpt12_T4_setMode(gpt12, IfxGpt12_Mode_capture);
|
||||
IfxGpt12_T4_setCaptureInputMode(gpt12, IfxGpt12_CaptureInputMode_risingEdgeTxIN);
|
||||
IfxGpt12_T4_enableClearTimerT2(gpt12, FALSE);
|
||||
IfxGpt12_T4_enableClearTimerT3(gpt12, TRUE);
|
||||
IfxGpt12_T4_setInterruptEnable(gpt12, config->zeroIsrPriority != 0);
|
||||
IfxGpt12_T4_setRemoteControl(gpt12, IfxGpt12_TimerRemoteControl_off);
|
||||
IfxGpt12_T4_run(gpt12, IfxGpt12_TimerRun_stop);
|
||||
|
||||
if (config->zeroIsrPriority)
|
||||
{
|
||||
/* setup interrupt */
|
||||
volatile Ifx_SRC_SRCR *src = IfxGpt12_T4_getSrc(gpt12);
|
||||
IfxSrc_init(src, config->zeroIsrProvider, config->zeroIsrPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
}
|
||||
|
||||
/* T5 Configuration */
|
||||
IfxGpt12_T5_setMode(gpt12, IfxGpt12_Mode_timer);
|
||||
IfxGpt12_T5_setTimerPrescaler(gpt12, IfxGpt12_TimerInputPrescaler_4);
|
||||
IfxGpt12_T5_setCaptureTrigger(gpt12, IfxGpt12_CaptureTrigger_t3inOrT3EUD);
|
||||
IfxGpt12_T5_setCaptureTriggerMode(gpt12, IfxGpt12_CaptureTriggerMode_risingEdge);
|
||||
IfxGpt12_T5_enableClearTimer(gpt12, TRUE);
|
||||
IfxGpt12_T5_setCaptureTriggerEnable(gpt12, TRUE);
|
||||
IfxGpt12_T5_setRemoteControl(gpt12, IfxGpt12_TimerRemoteControl_off);
|
||||
IfxGpt12_T5_setDirectionSource(gpt12, IfxGpt12_TimerDirectionSource_internal);
|
||||
IfxGpt12_T5_setTimerDirection(gpt12, IfxGpt12_TimerDirection_up);
|
||||
IfxGpt12_T5_run(gpt12, IfxGpt12_TimerRun_start);
|
||||
|
||||
driver->update = (IfxGpt12_IncrEnc_Update) & IfxGpt12_IncrEnc_updateFromT3;
|
||||
}
|
||||
else if (config->pinA->timer == 2)
|
||||
{
|
||||
/* T2 Configuration */
|
||||
IfxGpt12_T2_setMode(gpt12, IfxGpt12_Mode_incrementalInterfaceEdgeDetection);
|
||||
|
||||
switch (config->base.resolutionFactor)
|
||||
{
|
||||
case IfxStdIf_Pos_ResolutionFactor_twoFold:
|
||||
IfxGpt12_T2_setIncrementalInterfaceInputMode(gpt12, IfxGpt12_IncrementalInterfaceInputMode_bothEdgesTxIN);
|
||||
break;
|
||||
case IfxStdIf_Pos_ResolutionFactor_fourFold:
|
||||
IfxGpt12_T2_setIncrementalInterfaceInputMode(gpt12, IfxGpt12_IncrementalInterfaceInputMode_bothEdgesTxINOrTxEUD);
|
||||
break;
|
||||
default:
|
||||
status = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
IfxGpt12_T2_setDirectionSource(gpt12, IfxGpt12_TimerDirectionSource_external);
|
||||
IfxGpt12_T2_setTimerDirection(gpt12, config->base.reversed ? IfxGpt12_TimerDirection_up : IfxGpt12_TimerDirection_down);
|
||||
IfxGpt12_T2_run(gpt12, IfxGpt12_TimerRun_start);
|
||||
|
||||
if (config->pinZ != NULL_PTR)
|
||||
{ /* Only configure T4 if zero signal is available. Zero has to be on T4EUD */
|
||||
/* T4 Configuration */
|
||||
IfxGpt12_T4_setMode(gpt12, IfxGpt12_Mode_capture);
|
||||
IfxGpt12_T4_setCaptureInputMode(gpt12, IfxGpt12_CaptureInputMode_none);
|
||||
IfxGpt12_T4_enableClearTimerT2(gpt12, TRUE);
|
||||
IfxGpt12_T4_enableClearTimerT3(gpt12, FALSE);
|
||||
IfxGpt12_T4_setInterruptEnable(gpt12, FALSE);
|
||||
IfxGpt12_T4_setRemoteControl(gpt12, IfxGpt12_TimerRemoteControl_off);
|
||||
IfxGpt12_T4_run(gpt12, IfxGpt12_TimerRun_stop);
|
||||
}
|
||||
|
||||
driver->update = (IfxGpt12_IncrEnc_Update) & IfxGpt12_IncrEnc_updateFromT2;
|
||||
}
|
||||
|
||||
if (config->initPins == TRUE)
|
||||
{
|
||||
IfxGpt12_initTxInPinWithPadLevel(config->pinA, config->pinMode, config->pinDriver);
|
||||
IfxGpt12_initTxEudInPinWithPadLevel(config->pinB, config->pinMode, config->pinDriver);
|
||||
|
||||
if (config->pinZ != NULL_PTR)
|
||||
{
|
||||
IfxGpt12_initTxInPinWithPadLevel(config->pinZ, config->pinMode, config->pinDriver);
|
||||
}
|
||||
}
|
||||
|
||||
driver->speedConstTimeDiff =
|
||||
(2.0 * IFX_PI) / (config->base.resolution * 2) * IfxGpt12_T5_getFrequency(gpt12);
|
||||
|
||||
driver->speedFilterEnabled = config->base.speedFilterEnabled;
|
||||
|
||||
if (config->base.speedFilterEnabled)
|
||||
{
|
||||
Ifx_LowPassPt1F32_Config lpfConfig;
|
||||
lpfConfig.gain = 1.0;
|
||||
lpfConfig.cutOffFrequency = config->base.speedFilerCutOffFrequency;
|
||||
lpfConfig.samplingTime = config->base.updatePeriod;
|
||||
Ifx_LowPassPt1F32_init(&driver->speedLpf, &lpfConfig);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_IncrEnc_initConfig(IfxGpt12_IncrEnc_Config *config, Ifx_GPT12 *gpt12)
|
||||
{
|
||||
IfxStdIf_Pos_initConfig(&config->base);
|
||||
config->base.resolutionFactor = IfxStdIf_Pos_ResolutionFactor_twoFold;
|
||||
config->base.minSpeed = 1.0 / 60.0 * (2 * IFX_PI); // 1 rpm
|
||||
config->base.maxSpeed = 20000.0 / 60.0 * (2 * IFX_PI); // 20000 rpm
|
||||
config->base.speedFilterEnabled = TRUE;
|
||||
config->base.speedFilerCutOffFrequency = config->base.maxSpeed / 2 * IFX_PI * 10;
|
||||
|
||||
config->pinA = NULL_PTR;
|
||||
config->pinB = NULL_PTR;
|
||||
config->pinZ = NULL_PTR;
|
||||
config->pinMode = IfxPort_InputMode_noPullDevice;
|
||||
config->module = gpt12;
|
||||
config->zeroIsrPriority = 0;
|
||||
config->zeroIsrProvider = IfxSrc_Tos_cpu0;
|
||||
config->pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1;
|
||||
|
||||
config->initPins = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_IncrEnc_onZeroIrq(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
if (driver->status.B.notSynchronised)
|
||||
{
|
||||
driver->status.B.notSynchronised = 0;
|
||||
}
|
||||
|
||||
if (driver->direction == IfxStdIf_Pos_Dir_forward)
|
||||
{
|
||||
driver->turn++;
|
||||
}
|
||||
else
|
||||
{
|
||||
driver->turn--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_IncrEnc_reset(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
driver->rawPosition = 0;
|
||||
driver->turn = 0;
|
||||
driver->speed = 0;
|
||||
driver->status.status = 0;
|
||||
driver->status.B.notSynchronised = 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_IncrEnc_resetFaults(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
IfxStdIf_Pos_Status status;
|
||||
status.status = 0;
|
||||
status.B.notSynchronised = driver->status.B.notSynchronised;
|
||||
driver->status.status = status.status;
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_IncrEnc_setOffset(IfxGpt12_IncrEnc *driver, sint32 offset)
|
||||
{
|
||||
driver->offset = offset;
|
||||
driver->status.B.notSynchronised = 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_IncrEnc_setRefreshPeriod(IfxGpt12_IncrEnc *driver, float32 updatePeriod)
|
||||
{
|
||||
driver->updatePeriod = updatePeriod;
|
||||
driver->speedConstPulseCount = (2.0 * IFX_PI) / driver->resolution / updatePeriod;
|
||||
driver->speedModeThresholdTick = driver->speedModeThreshold * driver->resolution * updatePeriod / (2.0 * IFX_PI);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGpt12_IncrEnc_stdIfPosInit(IfxStdIf_Pos *stdif, IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
/* Ensure the stdif is reset to zeros */
|
||||
memset(stdif, 0, sizeof(IfxStdIf_Pos));
|
||||
|
||||
/* Set the driver */
|
||||
stdif->driver = driver;
|
||||
|
||||
/* *INDENT-OFF* Note: this file was indented manually by the author. */
|
||||
/* Set the API link */
|
||||
stdif->onZeroIrq =(IfxStdIf_Pos_OnZeroIrq )&IfxGpt12_IncrEnc_onZeroIrq;
|
||||
stdif->getAbsolutePosition=(IfxStdIf_Pos_GetAbsolutePosition )&IfxGpt12_IncrEnc_getAbsolutePosition;
|
||||
stdif->getDirection =(IfxStdIf_Pos_GetDirection )&IfxGpt12_IncrEnc_getDirection;
|
||||
stdif->getFault =(IfxStdIf_Pos_GetFault )&IfxGpt12_IncrEnc_getFault;
|
||||
stdif->getOffset =(IfxStdIf_Pos_GetOffset )&IfxGpt12_IncrEnc_getOffset;
|
||||
stdif->getPeriodPerRotation =(IfxStdIf_Pos_GetPeriodPerRotation )&IfxGpt12_IncrEnc_getPeriodPerRotation;
|
||||
stdif->getPosition =(IfxStdIf_Pos_GetPosition )&IfxGpt12_IncrEnc_getPosition;
|
||||
stdif->getRawPosition =(IfxStdIf_Pos_GetRawPosition )&IfxGpt12_IncrEnc_getRawPosition;
|
||||
stdif->getRefreshPeriod =(IfxStdIf_Pos_GetRefreshPeriod )&IfxGpt12_IncrEnc_getRefreshPeriod;
|
||||
stdif->getResolution =(IfxStdIf_Pos_GetResolution )&IfxGpt12_IncrEnc_getResolution;
|
||||
stdif->getSensorType =(IfxStdIf_Pos_GetSensorType )&IfxGpt12_IncrEnc_getSensorType;
|
||||
stdif->reset =(IfxStdIf_Pos_Reset )&IfxGpt12_IncrEnc_reset;
|
||||
stdif->resetFaults =(IfxStdIf_Pos_ResetFaults )&IfxGpt12_IncrEnc_resetFaults;
|
||||
stdif->getSpeed =(IfxStdIf_Pos_GetSpeed )&IfxGpt12_IncrEnc_getSpeed;
|
||||
stdif->update =(IfxStdIf_Pos_Update )&IfxGpt12_IncrEnc_update;
|
||||
stdif->setOffset =(IfxStdIf_Pos_SetOffset )&IfxGpt12_IncrEnc_setOffset;
|
||||
stdif->setRefreshPeriod =(IfxStdIf_Pos_SetRefreshPeriod )&IfxGpt12_IncrEnc_setRefreshPeriod;
|
||||
stdif->getTurn =(IfxStdIf_Pos_GetTurn )&IfxGpt12_IncrEnc_getTurn;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_IncrEnc_update(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
driver->update(driver);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGpt12_IncrEnc_updateFromT2(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
Ifx_GPT12 *gpt12 = driver->module;
|
||||
sint32 newPosition;
|
||||
driver->direction = gpt12->T2CON.B.T2RDIR ? IfxStdIf_Pos_Dir_backward : IfxStdIf_Pos_Dir_forward;
|
||||
|
||||
newPosition = gpt12->T2.U;
|
||||
|
||||
newPosition = (newPosition + driver->offset);
|
||||
|
||||
if (newPosition >= driver->resolution)
|
||||
{
|
||||
newPosition %= driver->resolution;
|
||||
}
|
||||
else if (newPosition < 0)
|
||||
{
|
||||
newPosition = (newPosition + driver->resolution);
|
||||
}
|
||||
|
||||
IfxGpt12_IncrEnc_updateSpeedFromT2(driver, newPosition);
|
||||
driver->rawPosition = newPosition;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGpt12_IncrEnc_updateFromT3(IfxGpt12_IncrEnc *driver)
|
||||
{
|
||||
Ifx_GPT12 *gpt12 = driver->module;
|
||||
sint32 newPosition;
|
||||
driver->direction = gpt12->T3CON.B.T3RDIR ? IfxStdIf_Pos_Dir_backward : IfxStdIf_Pos_Dir_forward;
|
||||
|
||||
newPosition = gpt12->T3.U;
|
||||
|
||||
newPosition = (newPosition + driver->offset);
|
||||
|
||||
if (newPosition >= driver->resolution)
|
||||
{
|
||||
newPosition %= driver->resolution;
|
||||
}
|
||||
else if (newPosition < 0)
|
||||
{
|
||||
newPosition = (newPosition + driver->resolution);
|
||||
}
|
||||
|
||||
IfxGpt12_IncrEnc_updateSpeedFromT3(driver, newPosition);
|
||||
driver->rawPosition = newPosition;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGpt12_IncrEnc_updateSpeedFromT2(IfxGpt12_IncrEnc *driver, sint32 newPosition)
|
||||
{
|
||||
float32 speed;
|
||||
sint32 diff;
|
||||
|
||||
if (driver->direction == IfxStdIf_Pos_Dir_forward)
|
||||
{
|
||||
diff = newPosition - driver->rawPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
diff = driver->rawPosition - newPosition;
|
||||
}
|
||||
|
||||
if (diff < 0)
|
||||
{
|
||||
diff += driver->resolution;
|
||||
}
|
||||
|
||||
speed = diff * driver->speedConstPulseCount;
|
||||
|
||||
speed = driver->direction == IfxStdIf_Pos_Dir_forward ? speed : -speed;
|
||||
|
||||
if (driver->speedFilterEnabled)
|
||||
{
|
||||
driver->speed = Ifx_LowPassPt1F32_do(&driver->speedLpf, speed);
|
||||
}
|
||||
else
|
||||
{
|
||||
driver->speed = speed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGpt12_IncrEnc_updateSpeedFromT3(IfxGpt12_IncrEnc *driver, sint32 newPosition)
|
||||
{
|
||||
float32 speed;
|
||||
sint32 diff;
|
||||
|
||||
if (driver->direction == IfxStdIf_Pos_Dir_forward)
|
||||
{
|
||||
diff = newPosition - driver->rawPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
diff = driver->rawPosition - newPosition;
|
||||
}
|
||||
|
||||
if (diff < 0)
|
||||
{
|
||||
diff += driver->resolution;
|
||||
}
|
||||
|
||||
if (diff > driver->speedModeThresholdTick)
|
||||
{ /* Use pulse count mode ( Fast speed ) */
|
||||
speed = diff * driver->speedConstPulseCount;
|
||||
}
|
||||
else
|
||||
{ /* Use time diff mode (slow speed), only if T3 is used as core */
|
||||
Ifx_GPT12 *gpt12 = driver->module;
|
||||
volatile Ifx_SRC_SRCR *srcT5 = IfxGpt12_T5_getSrc(gpt12);
|
||||
|
||||
if (srcT5->B.SRR != 1)
|
||||
{ // NO overflow of T5
|
||||
volatile Ifx_SRC_SRCR *srcCap = IfxGpt12_getCaptureSrc(gpt12);
|
||||
|
||||
// Check if a new value is captured
|
||||
if (srcCap->B.SRR != 0)
|
||||
{
|
||||
// Delete Capture Request Bit
|
||||
srcCap->B.CLRR = 1;
|
||||
speed = driver->speedConstTimeDiff / gpt12->CAPREL.B.CAPREL;
|
||||
}
|
||||
else
|
||||
{
|
||||
speed = driver->speed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // T5 overflow detected
|
||||
// Delete Overflow Request bit
|
||||
srcT5->B.CLRR = 1;
|
||||
speed = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
speed = driver->direction == IfxStdIf_Pos_Dir_forward ? speed : -speed;
|
||||
|
||||
if (driver->speedFilterEnabled)
|
||||
{
|
||||
driver->speed = Ifx_LowPassPt1F32_do(&driver->speedLpf, speed);
|
||||
}
|
||||
else
|
||||
{
|
||||
driver->speed = speed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
/**
|
||||
* \file IfxGpt12_IncrEnc.h
|
||||
* \brief GPT12 INCRENC details
|
||||
* \ingroup IfxLld_Gpt12
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Gpt12_IncrEnc INCRENC
|
||||
* \ingroup IfxLld_Gpt12
|
||||
*
|
||||
* \defgroup IfxLld_Gpt12_IncrEnc_Usage How to use the GPT12 Incremental Encoder Driver
|
||||
* \ingroup IfxLld_Gpt12_IncrEnc
|
||||
*
|
||||
* The IncrEnc interface can be used in one of the following configurations T3 as core or T2 as core
|
||||
*
|
||||
* Setup with T3 as core
|
||||
* - T3 as incremental mode
|
||||
* - Multiplication factor:
|
||||
* - twoFold: use both edges of TxIn
|
||||
* - fourFold: use both edges of TxIn and TxEUD
|
||||
* - Reverse of direction supported by GPT12
|
||||
* - T3 value diff is used for speed calculation at high speed (speed > speedModeThreshold)
|
||||
* - T4 used for zero signal detection if pinZ is not NULL
|
||||
* - interrupt is generated to support turn calculation if zeroIsrPriority != 0
|
||||
* - T4 clears T3 on zero signal event on TxIn input
|
||||
* - T5 used for low speed calculation (speed < speedModeThreshold)
|
||||
* - Rising edge of TxIn or TxEUD captures the T5 timer in CAPREL
|
||||
*
|
||||
* Setup with T2 as core
|
||||
* - T2 as incremental mode
|
||||
* - Multiplication factor:
|
||||
* - twoFold: sample on both edges of TxIn
|
||||
* - fourFold: sample on both edges of TxIn and TxEUD
|
||||
* - Reverse of direction supported by GPT12
|
||||
* - T2 value diff is used for speed calculation at high speed
|
||||
* - T4 used for zero signal detection if pinZeroTxEUD is not NULL
|
||||
* - T4 clears T2 on zero signal event on TxEUD input
|
||||
*
|
||||
* \section IfxLld_Gpt12_IncrEnc_Preparation Preparation
|
||||
* \subsection IfxLld_Gpt12_IncrEnc_Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
* \code
|
||||
* #include <Gpt12/Gpt/IfxGpt12_IncrEnc.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Gpt12_IncrEnc_Variables Variables
|
||||
*
|
||||
* \code
|
||||
* // used globally
|
||||
* static IfxGpt12_IncrEnc gpt12;
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Gpt12_Gpt_Interrupt Interrupt Handler Installation
|
||||
*
|
||||
* See also \ref IfxLld_Cpu_Irq_Usage
|
||||
*
|
||||
* Define priorities for the Interrrupt handlers. This is normally done in the Ifx_IntPrioDef.h file:
|
||||
* \code
|
||||
* // priorities are normally defined in Ifx_IntPrioDef.h
|
||||
* #define ISR_PRIORITY_INCRENC_ZERO 6
|
||||
* \endcode
|
||||
*
|
||||
* Add the interrupt service routines to your C code. They have to call the GPT12 interrupt handlers by passing the gpt12 handle:
|
||||
* \code
|
||||
* IFX_INTERRUPT(ISR_IncrIncZero, 0, ISR_PRIORITY_INCRENC_ZERO)
|
||||
* {
|
||||
* IfxGpt12_IncrEnc_onZeroIrq(&gpt12);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Finally install the interrupt handlers in your initialisation function:
|
||||
* \code
|
||||
* // install interrupt handlers
|
||||
* IfxCpu_Irq_installInterruptHandler(&ISR_IncrIncZero, ISR_PRIORITY_INCRENC_ZERO);
|
||||
* IfxCpu_enableInterrupts();
|
||||
* \endcode
|
||||
*
|
||||
* \subsection IfxLld_Gpt12_Gpt_Init Module Initialisation
|
||||
*
|
||||
* The module initialisation can be done in the same function. Here an example:
|
||||
* \code
|
||||
* // Initialize global clocks
|
||||
* IfxGpt12_enableModule(&MODULE_GPT120);
|
||||
* IfxGpt12_setGpt1BlockPrescaler(&MODULE_GPT120, IfxGpt12_Gpt1BlockPrescaler_8);
|
||||
* IfxGpt12_setGpt2BlockPrescaler(&MODULE_GPT120, IfxGpt12_Gpt2BlockPrescaler_4);
|
||||
*
|
||||
* // create module config
|
||||
* IfxGpt12_IncrEnc_Config gpt12Config;
|
||||
* IfxGpt12_IncrEnc_initConfig(&gpt12Config , &MODULE_GPT120);
|
||||
*
|
||||
* // implementation with T3 as core
|
||||
* gpt12Config.base.offset = 0;
|
||||
* gpt12Config.base.reversed = FALSE;
|
||||
* gpt12Config.base.resolution = 2048;
|
||||
* gpt12Config.base.periodPerRotation = 1;
|
||||
* gpt12Config.base.resolutionFactor = IfxStdIf_Pos_ResolutionFactor_fourFold;
|
||||
* gpt12Config.base.updatePeriod = 100e-6;
|
||||
* gpt12Config.base.speedModeThreshold = 200;
|
||||
* gpt12Config.base.minSpeed = 10;
|
||||
* gpt12Config.base.maxSpeed = 500;
|
||||
* gpt12Config.zeroIsrPriority = ISR_PRIORITY(INTERRUPT_INCRINC_ZERO);
|
||||
* gpt12Config.zeroIsrProvider = ISR_PROVIDER(INTERRUPT_INCRINC_ZERO);
|
||||
* gpt12Config.pinA = &IfxGpt120_T3INA_P02_6_IN;
|
||||
* gpt12Config.pinB = &IfxGpt120_T3EUDA_P02_7_IN;
|
||||
* gpt12Config.pinZ = &IfxGpt120_T4INA_P02_8_IN;
|
||||
* gpt12Config.pinMode = IfxPort_InputMode_noPullDevice;
|
||||
*
|
||||
* gpt12Config.base.speedFilterEnabled = TRUE;
|
||||
* gpt12Config.base.speedFilerCutOffFrequency = config.base.maxSpeed / 2 * IFX_PI * 2;
|
||||
*
|
||||
*
|
||||
* // initialize module
|
||||
* //IfxGpt12_IncrEnc gpt12; // defined globally
|
||||
* IfxGpt12_IncrEnc_init(&gpt12, &gpt12Config);
|
||||
* \endcode
|
||||
*
|
||||
* \section IfxLld_Gpt12_IncrEnc_Update Update
|
||||
*
|
||||
* speed, position and direction of the incremental encoder can be collected by the following
|
||||
*
|
||||
* \code
|
||||
* float32 speed, rawPosition;
|
||||
* IfxStdIf_Pos_Dir direction;
|
||||
*
|
||||
* Ifx_TickTime tickRefresh = gpt12.updatePeriod * TimeConst_1s;
|
||||
*
|
||||
* Ifx_TickTime refreshDeadLine = now();
|
||||
*
|
||||
* if (isDeadLine(refreshDeadLine))
|
||||
* {
|
||||
* refreshDeadLine = addTTime(refreshDeadLine, tickRefresh);
|
||||
* IfxGpt12_IncrEnc_update(&gpt12);
|
||||
*
|
||||
* speed = IfxGpt12_IncrEnc_getSpeed(&gpt12);
|
||||
* rawPosition = IfxGpt12_IncrEnc_getRawPosition(&gpt12);
|
||||
* direction = IfxGpt12_IncrEnc_getDirection(&gpt12);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Gpt12_IncrEnc INCRENC
|
||||
* \ingroup IfxLld_Gpt12
|
||||
* \defgroup IfxLld_Gpt12_IncrEnc_Datastructures Data structures
|
||||
* \ingroup IfxLld_Gpt12_IncrEnc
|
||||
* \defgroup IfxLld_Gpt12_IncrEnc_Functions Functions
|
||||
* \ingroup IfxLld_Gpt12_IncrEnc
|
||||
* \defgroup IfxLld_Gpt12_IncrEnc_StdIf_Functions StdIf Functions
|
||||
* \ingroup IfxLld_Gpt12_IncrEnc
|
||||
*/
|
||||
|
||||
#ifndef IFXGPT12_INCRENC_H
|
||||
#define IFXGPT12_INCRENC_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "StdIf/IfxStdIf_Pos.h"
|
||||
#include "SysSe/Math/Ifx_LowPassPt1F32.h"
|
||||
#include "Gpt12/Std/IfxGpt12.h"
|
||||
#include "string.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*------------------------------Type Definitions------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
typedef IfxStdIf_Pos_Update IfxGpt12_IncrEnc_Update;
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Gpt12_IncrEnc_Datastructures
|
||||
* \{ */
|
||||
/** \brief Incremental encoder object
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
sint32 rawPosition; /**< \brief raw position in ticks. \note: the value already contains the offset */
|
||||
float32 speed; /**< \brief mechanical speed in rad/s */
|
||||
sint32 turn; /**< \brief number of mechanical turns */
|
||||
IfxStdIf_Pos_Dir direction; /**< \brief rotation direction */
|
||||
IfxStdIf_Pos_Status status; /**< \brief error code (0 = no error) */
|
||||
sint32 offset; /**< \brief raw position offset */
|
||||
sint32 resolution; /**< \brief resolution of this position sensor interface */
|
||||
float32 updatePeriod; /**< \brief update period in seconds */
|
||||
float32 speedConstPulseCount; /**< \brief constant for calculating mechanical speed (in rad/s) from raw speed in pulse count mode */
|
||||
float32 speedConstTimeDiff; /**< \brief constant for calculating mechanical speed (in rad/s) from raw speed in time diff mode */
|
||||
float32 positionConst; /**< \brief constant for calculating mechanical position (in rad) from raw position */
|
||||
float32 speedModeThreshold; /**< \brief treshold used for speed calculation using pulse count mode or time diff mode in rad/s */
|
||||
sint32 speedModeThresholdTick; /**< \brief treshold used for speed calculation using pulse count mode or time diff mode in ticks */
|
||||
Ifx_GPT12 *module; /**< \brief Pointer to the GPT12 module */
|
||||
float32 minSpeed; /**< \brief Absolute minimal allowed speed. below speed is recognized as 0rad/s */
|
||||
float32 maxSpeed; /**< \brief Absolute maximal allowed speed. Above speed is recognized as error */
|
||||
Ifx_LowPassPt1F32 speedLpf; /**< \brief Low pass filter object */
|
||||
IfxGpt12_IncrEnc_Update update; /**< \brief Update call back API */
|
||||
boolean speedFilterEnabled; /**< \brief Enable / disable the speed low pass filter */
|
||||
} IfxGpt12_IncrEnc;
|
||||
|
||||
/** \brief Configuration structure for GPT12
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxStdIf_Pos_Config base; /**< \brief Configuration data of \ref library_srvsw_stdif_posif */
|
||||
Ifx_GPT12 *module; /**< \brief Pointer to module base address */
|
||||
IfxGpt12_TxIn_In *pinA; /**< \brief Encoder A signal. Should be connecting to T2 or T3 TxIN. See \ref IfxLld_Gpt12_pinmap "GPT12 pin map data" */
|
||||
IfxGpt12_TxEud_In *pinB; /**< \brief Encoder B signal. Should be connecting to T2 or T3 TxEUD. See \ref IfxLld_Gpt12_pinmap "GPT12 pin map data" */
|
||||
IfxGpt12_TxIn_In *pinZ; /**< \brief Encoder Z signal. Should be connecting to T4 TxIn for use with T3 and TxEUD (Ignore compiler type conflict warning) for use with T4. See \ref IfxLld_Gpt12_pinmap "GPT12 pin map data" */
|
||||
IfxPort_InputMode pinMode; /**< \brief Pin mode for A, B and Z inputs */
|
||||
Ifx_Priority zeroIsrPriority; /**< \brief Interrupt isrPriority of the zero interrupt, if 0 the interrupt is disable */
|
||||
IfxSrc_Tos zeroIsrProvider; /**< \brief Interrupt service provider for the zero interrupt */
|
||||
IfxPort_PadDriver pinDriver; /**< \brief Pad Driver */
|
||||
boolean initPins; /**< \brief TRUE: Initialize pins in driver
|
||||
* FALSE: Don't initialize pins. User handles separately. */
|
||||
} IfxGpt12_IncrEnc_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gpt12_IncrEnc_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialises the Incremental interface
|
||||
* \param driver incremental encoder interface Handle
|
||||
* \param config Configuration structure for incremental encoder
|
||||
* \return TRUE on success else FALSE
|
||||
*
|
||||
* \code
|
||||
* // create module config
|
||||
* IfxGpt12_IncrEnc_Config gptConfig;
|
||||
* IfxGpt12_IncrEnc_initConfig(&gptConfig , &MODULE_GPT120);
|
||||
*
|
||||
* // initialize module
|
||||
* //IfxGpt12_IncrEnc gpt12; // defined globally
|
||||
*
|
||||
* IfxGpt12_IncrEnc_init(&gpt12, &gptConfig);
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGpt12_IncrEnc_init(IfxGpt12_IncrEnc *driver, const IfxGpt12_IncrEnc_Config *config);
|
||||
|
||||
/** \brief Initializes the configuration structure to default
|
||||
* \param config Configuration structure for incremental encoder
|
||||
* \param gpt12 pointer to module base address
|
||||
* \return None
|
||||
*
|
||||
* see \ref IfxGpt12_IncrEnc_init
|
||||
*
|
||||
*/
|
||||
IFX_EXTERN void IfxGpt12_IncrEnc_initConfig(IfxGpt12_IncrEnc_Config *config, Ifx_GPT12 *gpt12);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gpt12_IncrEnc_StdIf_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetAbsolutePosition
|
||||
* \param driver driver handle
|
||||
* \return absolute position
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGpt12_IncrEnc_getAbsolutePosition(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetDirection
|
||||
* \param driver driver handle
|
||||
* \return direction
|
||||
*/
|
||||
IFX_EXTERN IfxStdIf_Pos_Dir IfxGpt12_IncrEnc_getDirection(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetFault
|
||||
* \param driver driver handle
|
||||
* \return Fault
|
||||
*/
|
||||
IFX_EXTERN IfxStdIf_Pos_Status IfxGpt12_IncrEnc_getFault(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetOffset
|
||||
* \param driver driver handle
|
||||
* \return offset address
|
||||
*/
|
||||
IFX_EXTERN sint32 IfxGpt12_IncrEnc_getOffset(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetPeriodPerRotation
|
||||
* \param driver driver handle
|
||||
* \return Period per rotation
|
||||
*/
|
||||
IFX_EXTERN uint16 IfxGpt12_IncrEnc_getPeriodPerRotation(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetPosition
|
||||
* \param driver driver handle
|
||||
* \return position
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGpt12_IncrEnc_getPosition(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetRawPosition
|
||||
* \param driver driver handle
|
||||
* \return position in ticks
|
||||
*/
|
||||
IFX_EXTERN sint32 IfxGpt12_IncrEnc_getRawPosition(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetRefreshPeriod
|
||||
* \param driver driver handle
|
||||
* \return update period
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGpt12_IncrEnc_getRefreshPeriod(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetResolution
|
||||
* \param driver driver handle
|
||||
* \return resolution
|
||||
*/
|
||||
IFX_EXTERN sint32 IfxGpt12_IncrEnc_getResolution(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetSensorType
|
||||
* \param driver driver handle
|
||||
* \return sensor type
|
||||
*/
|
||||
IFX_EXTERN IfxStdIf_Pos_SensorType IfxGpt12_IncrEnc_getSensorType(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetSpeed
|
||||
* \param driver driver handle
|
||||
* \return speed
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGpt12_IncrEnc_getSpeed(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_GetTurn
|
||||
* \param driver driver handle
|
||||
* \return the number of turns
|
||||
*/
|
||||
IFX_EXTERN sint32 IfxGpt12_IncrEnc_getTurn(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_OnZeroIrq
|
||||
* \param driver driver handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGpt12_IncrEnc_onZeroIrq(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_Reset
|
||||
* \param driver driver handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGpt12_IncrEnc_reset(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_ResetFaults
|
||||
* \param driver driver handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGpt12_IncrEnc_resetFaults(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_SetOffset
|
||||
* \param driver driver handle
|
||||
* \param offset offset address
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGpt12_IncrEnc_setOffset(IfxGpt12_IncrEnc *driver, sint32 offset);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_SetRefreshPeriod
|
||||
* \param driver driver handle
|
||||
* \param updatePeriod update period
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGpt12_IncrEnc_setRefreshPeriod(IfxGpt12_IncrEnc *driver, float32 updatePeriod);
|
||||
|
||||
/** \brief \see IfxStdIf_Pos_Update
|
||||
* \param driver driver handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGpt12_IncrEnc_update(IfxGpt12_IncrEnc *driver);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initializes the standard interface "Pos"
|
||||
* \param stdif Standard interface position object
|
||||
* \param driver incremental encoder interface Handle
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGpt12_IncrEnc_stdIfPosInit(IfxStdIf_Pos *stdif, IfxGpt12_IncrEnc *driver);
|
||||
|
||||
#endif /* IFXGPT12_INCRENC_H */
|
||||
@@ -0,0 +1,404 @@
|
||||
/**
|
||||
* \file IfxGpt12.c
|
||||
* \brief GPT12 basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGpt12.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
float32 IfxGpt12_T2_getFrequency(Ifx_GPT12 *gpt12)
|
||||
{
|
||||
float32 freq = IfxGpt12_getModuleFrequency(gpt12);
|
||||
|
||||
IfxGpt12_Mode mode;
|
||||
IfxGpt12_TimerInputPrescaler prescaler;
|
||||
|
||||
IfxGpt12_Gpt1BlockPrescaler bps1 = (IfxGpt12_Gpt1BlockPrescaler)gpt12->T3CON.B.BPS1;
|
||||
|
||||
switch (bps1)
|
||||
{
|
||||
case IfxGpt12_Gpt1BlockPrescaler_4:
|
||||
freq = freq / 4;
|
||||
break;
|
||||
case IfxGpt12_Gpt1BlockPrescaler_8:
|
||||
freq = freq / 8;
|
||||
break;
|
||||
case IfxGpt12_Gpt1BlockPrescaler_16:
|
||||
freq = freq / 16;
|
||||
break;
|
||||
default: /* case IfxGpt12_Gpt1BlockPrescaler_32: */
|
||||
freq = freq / 32;
|
||||
break;
|
||||
}
|
||||
|
||||
mode = IfxGpt12_T2_getMode(gpt12);
|
||||
prescaler = (IfxGpt12_TimerInputPrescaler)gpt12->T2CON.B.T2I;
|
||||
|
||||
if ((mode == IfxGpt12_Mode_timer) || (mode == IfxGpt12_Mode_highGatedTimer) || (mode == IfxGpt12_Mode_lowGatedTimer))
|
||||
{
|
||||
freq = freq / (1 << prescaler);
|
||||
}
|
||||
else
|
||||
{
|
||||
freq = freq / 2;
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGpt12_T3_getFrequency(Ifx_GPT12 *gpt12)
|
||||
{
|
||||
float32 freq = IfxGpt12_getModuleFrequency(gpt12);
|
||||
|
||||
IfxGpt12_Mode mode;
|
||||
IfxGpt12_TimerInputPrescaler prescaler;
|
||||
|
||||
IfxGpt12_Gpt1BlockPrescaler bps1 = (IfxGpt12_Gpt1BlockPrescaler)gpt12->T3CON.B.BPS1;
|
||||
|
||||
switch (bps1)
|
||||
{
|
||||
case IfxGpt12_Gpt1BlockPrescaler_4:
|
||||
freq = freq / 4;
|
||||
break;
|
||||
case IfxGpt12_Gpt1BlockPrescaler_8:
|
||||
freq = freq / 8;
|
||||
break;
|
||||
case IfxGpt12_Gpt1BlockPrescaler_16:
|
||||
freq = freq / 16;
|
||||
break;
|
||||
default: /* case IfxGpt12_Gpt1BlockPrescaler_32: */
|
||||
freq = freq / 32;
|
||||
break;
|
||||
}
|
||||
|
||||
mode = (IfxGpt12_Mode)gpt12->T3CON.B.T3M;
|
||||
prescaler = (IfxGpt12_TimerInputPrescaler)gpt12->T3CON.B.T3I;
|
||||
|
||||
if ((mode == IfxGpt12_Mode_timer) || (mode == IfxGpt12_Mode_highGatedTimer) || (mode == IfxGpt12_Mode_lowGatedTimer))
|
||||
{
|
||||
freq = freq / (1 << prescaler);
|
||||
}
|
||||
else
|
||||
{
|
||||
freq = freq / 2;
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGpt12_T4_getFrequency(Ifx_GPT12 *gpt12)
|
||||
{
|
||||
float32 freq = IfxGpt12_getModuleFrequency(gpt12);
|
||||
|
||||
IfxGpt12_Mode mode;
|
||||
IfxGpt12_TimerInputPrescaler prescaler;
|
||||
|
||||
IfxGpt12_Gpt1BlockPrescaler bps1 = (IfxGpt12_Gpt1BlockPrescaler)gpt12->T3CON.B.BPS1;
|
||||
|
||||
switch (bps1)
|
||||
{
|
||||
case IfxGpt12_Gpt1BlockPrescaler_4:
|
||||
freq = freq / 4;
|
||||
break;
|
||||
case IfxGpt12_Gpt1BlockPrescaler_8:
|
||||
freq = freq / 8;
|
||||
break;
|
||||
case IfxGpt12_Gpt1BlockPrescaler_16:
|
||||
freq = freq / 16;
|
||||
break;
|
||||
default: /* case IfxGpt12_Gpt1BlockPrescaler_32: */
|
||||
freq = freq / 32;
|
||||
break;
|
||||
}
|
||||
|
||||
mode = (IfxGpt12_Mode)gpt12->T4CON.B.T4M;
|
||||
prescaler = (IfxGpt12_TimerInputPrescaler)gpt12->T4CON.B.T4I;
|
||||
|
||||
if ((mode == IfxGpt12_Mode_timer) || (mode == IfxGpt12_Mode_highGatedTimer) || (mode == IfxGpt12_Mode_lowGatedTimer))
|
||||
{
|
||||
freq = freq / (1 << prescaler);
|
||||
}
|
||||
else
|
||||
{
|
||||
freq = freq / 2;
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGpt12_T5_getFrequency(Ifx_GPT12 *gpt12)
|
||||
{
|
||||
float32 freq = IfxGpt12_getModuleFrequency(gpt12);
|
||||
|
||||
IfxGpt12_Mode mode;
|
||||
IfxGpt12_TimerInputPrescaler prescaler;
|
||||
|
||||
IfxGpt12_Gpt2BlockPrescaler bps2 = (IfxGpt12_Gpt2BlockPrescaler)gpt12->T6CON.B.BPS2;
|
||||
|
||||
switch (bps2)
|
||||
{
|
||||
case IfxGpt12_Gpt2BlockPrescaler_2:
|
||||
freq = freq / 2;
|
||||
break;
|
||||
case IfxGpt12_Gpt2BlockPrescaler_4:
|
||||
freq = freq / 4;
|
||||
break;
|
||||
case IfxGpt12_Gpt2BlockPrescaler_8:
|
||||
freq = freq / 8;
|
||||
break;
|
||||
default: /* case IfxGpt12_Gpt2BlockPrescaler_16: */
|
||||
freq = freq / 16;
|
||||
break;
|
||||
}
|
||||
|
||||
mode = (IfxGpt12_Mode)gpt12->T5CON.B.T5M;
|
||||
prescaler = (IfxGpt12_TimerInputPrescaler)gpt12->T5CON.B.T5I;
|
||||
|
||||
if ((mode == IfxGpt12_Mode_timer) || (mode == IfxGpt12_Mode_highGatedTimer) || (mode == IfxGpt12_Mode_lowGatedTimer))
|
||||
{
|
||||
freq = freq / (1 << prescaler);
|
||||
}
|
||||
else
|
||||
{
|
||||
freq = freq / 2;
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGpt12_T6_getFrequency(Ifx_GPT12 *gpt12)
|
||||
{
|
||||
float32 freq = IfxGpt12_getModuleFrequency(gpt12);
|
||||
|
||||
IfxGpt12_Mode mode;
|
||||
IfxGpt12_TimerInputPrescaler prescaler;
|
||||
|
||||
IfxGpt12_Gpt2BlockPrescaler bps2 = (IfxGpt12_Gpt2BlockPrescaler)gpt12->T6CON.B.BPS2;
|
||||
|
||||
switch (bps2)
|
||||
{
|
||||
case IfxGpt12_Gpt2BlockPrescaler_2:
|
||||
freq = freq / 2;
|
||||
break;
|
||||
case IfxGpt12_Gpt2BlockPrescaler_4:
|
||||
freq = freq / 4;
|
||||
break;
|
||||
case IfxGpt12_Gpt2BlockPrescaler_8:
|
||||
freq = freq / 8;
|
||||
break;
|
||||
default: /* case IfxGpt12_Gpt2BlockPrescaler_16: */
|
||||
freq = freq / 16;
|
||||
break;
|
||||
}
|
||||
|
||||
mode = (IfxGpt12_Mode)gpt12->T6CON.B.T6M;
|
||||
prescaler = (IfxGpt12_TimerInputPrescaler)gpt12->T6CON.B.T6I;
|
||||
|
||||
if ((mode == IfxGpt12_Mode_timer) || (mode == IfxGpt12_Mode_highGatedTimer) || (mode == IfxGpt12_Mode_lowGatedTimer))
|
||||
{
|
||||
freq = freq / (1 << prescaler);
|
||||
}
|
||||
else
|
||||
{
|
||||
freq = freq / 2;
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_disableModule(Ifx_GPT12 *gpt12)
|
||||
{
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(psw);
|
||||
gpt12->CLC.B.DISR = 1;
|
||||
IfxScuWdt_setCpuEndinit(psw);
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_enableModule(Ifx_GPT12 *gpt12)
|
||||
{
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(psw);
|
||||
gpt12->CLC.B.DISR = 0;
|
||||
IfxScuWdt_setCpuEndinit(psw);
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_initTxEudInPin(const IfxGpt12_TxEud_In *txEudIn, IfxPort_InputMode inputMode)
|
||||
{
|
||||
IfxPort_setPinModeInput(txEudIn->pin.port, txEudIn->pin.pinIndex, inputMode);
|
||||
|
||||
switch (txEudIn->timer)
|
||||
{
|
||||
case 2:
|
||||
IfxGpt12_T2_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
case 3:
|
||||
IfxGpt12_T3_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
case 4:
|
||||
IfxGpt12_T4_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
case 5:
|
||||
IfxGpt12_T5_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
case 6:
|
||||
IfxGpt12_T6_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_initTxEudInPinWithPadLevel(const IfxGpt12_TxEud_In *txEudIn, IfxPort_InputMode inputMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
IfxPort_setPinModeInput(txEudIn->pin.port, txEudIn->pin.pinIndex, inputMode);
|
||||
IfxPort_setPinPadDriver(txEudIn->pin.port, txEudIn->pin.pinIndex, padDriver);
|
||||
|
||||
switch (txEudIn->timer)
|
||||
{
|
||||
case 2:
|
||||
IfxGpt12_T2_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
case 3:
|
||||
IfxGpt12_T3_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
case 4:
|
||||
IfxGpt12_T4_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
case 5:
|
||||
IfxGpt12_T5_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
case 6:
|
||||
IfxGpt12_T6_setEudInput(txEudIn->module, (IfxGpt12_EudInput)txEudIn->select);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_initTxInPin(const IfxGpt12_TxIn_In *txIn, IfxPort_InputMode inputMode)
|
||||
{
|
||||
IfxPort_setPinModeInput(txIn->pin.port, txIn->pin.pinIndex, inputMode);
|
||||
|
||||
switch (txIn->timer)
|
||||
{
|
||||
case 2:
|
||||
IfxGpt12_T2_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
case 3:
|
||||
IfxGpt12_T3_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
case 4:
|
||||
IfxGpt12_T4_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
case 5:
|
||||
IfxGpt12_T5_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
case 6:
|
||||
IfxGpt12_T6_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_initTxInPinWithPadLevel(const IfxGpt12_TxIn_In *txIn, IfxPort_InputMode inputMode, IfxPort_PadDriver padDriver)
|
||||
{
|
||||
IfxPort_setPinModeInput(txIn->pin.port, txIn->pin.pinIndex, inputMode);
|
||||
IfxPort_setPinPadDriver(txIn->pin.port, txIn->pin.pinIndex, padDriver);
|
||||
|
||||
switch (txIn->timer)
|
||||
{
|
||||
case 2:
|
||||
IfxGpt12_T2_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
case 3:
|
||||
IfxGpt12_T3_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
case 4:
|
||||
IfxGpt12_T4_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
case 5:
|
||||
IfxGpt12_T5_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
case 6:
|
||||
IfxGpt12_T6_setInput(txIn->module, (IfxGpt12_Input)txIn->select);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGpt12_resetModule(Ifx_GPT12 *gpt12)
|
||||
{
|
||||
uint16 passwd = IfxScuWdt_getCpuWatchdogPassword();
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
gpt12->KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
|
||||
gpt12->KRST1.B.RST = 1;
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
|
||||
while (0 == gpt12->KRST0.B.RSTSTAT) /* Wait until reset is executed */
|
||||
|
||||
{}
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(passwd);
|
||||
gpt12->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
|
||||
IfxScuWdt_setCpuEndinit(passwd);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* \file IfxGtm_Atom_Pwm.c
|
||||
* \brief GTM PWM details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGtm_Atom_Pwm.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
boolean IfxGtm_Atom_Pwm_init(IfxGtm_Atom_Pwm_Driver *driver, const IfxGtm_Atom_Pwm_Config *config)
|
||||
{
|
||||
boolean result = TRUE;
|
||||
|
||||
driver->gtm = config->gtm;
|
||||
driver->atomIndex = config->atom;
|
||||
|
||||
Ifx_GTM_ATOM *atomSFR = &config->gtm->ATOM[config->atom];
|
||||
driver->atom = atomSFR;
|
||||
driver->atomChannel = config->atomChannel;
|
||||
Ifx_GTM_ATOM_AGC *agc = &atomSFR->AGC;
|
||||
driver->agc = agc;
|
||||
|
||||
/* Initialize the timer part */
|
||||
if (config->synchronousUpdateEnabled == 1)
|
||||
{
|
||||
IfxGtm_Atom_Agc_enableChannelUpdate(agc, config->atomChannel, TRUE);
|
||||
}
|
||||
|
||||
IfxGtm_Atom_Agc_setChannelForceUpdate(agc, config->atomChannel, TRUE, TRUE);
|
||||
|
||||
IfxGtm_Atom_Ch_setSignalLevel(atomSFR, config->atomChannel, config->signalLevel);
|
||||
|
||||
IfxGtm_Atom_Ch_setMode(atomSFR, config->atomChannel, config->mode);
|
||||
|
||||
if (config->pin.outputPin != NULL_PTR)
|
||||
{
|
||||
IfxGtm_PinMap_setAtomTout(config->pin.outputPin, config->pin.outputMode, config->pin.padDriver);
|
||||
}
|
||||
|
||||
// enable and initialise interrupts if chosen
|
||||
if ((config->interrupt.ccu0Enabled == 1) || (config->interrupt.ccu1Enabled == 1))
|
||||
{
|
||||
IfxGtm_Atom_Ch_setNotification(atomSFR, config->atomChannel, config->interrupt.mode, config->interrupt.ccu0Enabled, config->interrupt.ccu1Enabled);
|
||||
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
src = IfxGtm_Atom_Ch_getSrcPointer(config->gtm, config->atom, config->atomChannel);
|
||||
IfxSrc_init(src, config->interrupt.isrProvider, config->interrupt.isrPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (config->synchronousUpdateEnabled == 1)
|
||||
{
|
||||
IfxGtm_Atom_Ch_setCompareZeroShadow(atomSFR, config->atomChannel, config->period);
|
||||
IfxGtm_Atom_Ch_setCompareOneShadow(atomSFR, config->atomChannel, config->dutyCycle);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxGtm_Atom_Ch_setCompareZero(atomSFR, config->atomChannel, config->period);
|
||||
IfxGtm_Atom_Ch_setCompareOne(atomSFR, config->atomChannel, config->dutyCycle);
|
||||
}
|
||||
|
||||
IfxGtm_Atom_Agc_enableChannel(agc, config->atomChannel, TRUE, FALSE);
|
||||
IfxGtm_Atom_Agc_enableChannelOutput(agc, config->atomChannel, TRUE, FALSE);
|
||||
|
||||
if (config->immediateStartEnabled == TRUE)
|
||||
{
|
||||
IfxGtm_Atom_Agc_trigger(driver->agc);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Pwm_initConfig(IfxGtm_Atom_Pwm_Config *config, Ifx_GTM *gtm)
|
||||
{
|
||||
config->gtm = gtm;
|
||||
config->atom = IfxGtm_Atom_0;
|
||||
config->atomChannel = IfxGtm_Atom_Ch_0;
|
||||
config->period = 20;
|
||||
config->dutyCycle = 10;
|
||||
config->signalLevel = Ifx_ActiveState_high;
|
||||
config->mode = IfxGtm_Atom_Mode_outputPwm;
|
||||
config->oneShotModeEnabled = FALSE;
|
||||
config->synchronousUpdateEnabled = FALSE;
|
||||
config->immediateStartEnabled = TRUE;
|
||||
config->interrupt.ccu0Enabled = FALSE;
|
||||
config->interrupt.ccu1Enabled = FALSE;
|
||||
config->interrupt.mode = IfxGtm_IrqMode_pulseNotify;
|
||||
config->interrupt.isrProvider = IfxSrc_Tos_cpu0;
|
||||
config->interrupt.isrPriority = 0;
|
||||
config->pin.outputPin = NULL_PTR;
|
||||
config->pin.outputMode = IfxPort_OutputMode_pushPull;
|
||||
config->pin.padDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Pwm_start(IfxGtm_Atom_Pwm_Driver *driver, boolean immediate)
|
||||
{
|
||||
/* Enable channel if not enabled already */
|
||||
IfxGtm_Atom_Agc_enableChannel(driver->agc, driver->atomChannel, TRUE, immediate);
|
||||
IfxGtm_Atom_Agc_enableChannelOutput(driver->agc, driver->atomChannel, TRUE, immediate);
|
||||
|
||||
/* Trigger the start now */
|
||||
IfxGtm_Atom_Agc_trigger(driver->agc);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Pwm_stop(IfxGtm_Atom_Pwm_Driver *driver, boolean immediate)
|
||||
{
|
||||
/* Disable channels */
|
||||
IfxGtm_Atom_Agc_enableChannel(driver->agc, driver->atomChannel, FALSE, immediate);
|
||||
IfxGtm_Atom_Agc_enableChannelOutput(driver->agc, driver->atomChannel, FALSE, immediate);
|
||||
|
||||
/* Trigger the stop now */
|
||||
IfxGtm_Atom_Agc_trigger(driver->agc);
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* \file IfxGtm_Atom_Pwm.h
|
||||
* \brief GTM PWM details
|
||||
* \ingroup IfxLld_Gtm
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Atom_Pwm_Usage How to use the GTM ATOM PWM Driver
|
||||
* \ingroup IfxLld_Gtm_Atom_Pwm
|
||||
*
|
||||
* This interface allows to generate simple PWM signal on a ATOM out put and can generate interrupts if enabled.
|
||||
* this output can also be routed to port pin if required.
|
||||
*
|
||||
* \section Preparation Preparation
|
||||
* \subsection Include Include Files
|
||||
*
|
||||
* Include following header file into your C code:
|
||||
* \code
|
||||
* #include <Gtm/Atom/Pwm/IfxGtm_Atom_Pwm.h>
|
||||
* \endcode
|
||||
*
|
||||
* \subsection Variables Variables
|
||||
* define global variables if necessary
|
||||
*
|
||||
* \code
|
||||
* Ifx_GTM *gtm = &MODULE_GTM;
|
||||
* #define ATOM0_CH0_PRIO 20
|
||||
* \endcode
|
||||
*
|
||||
* \subsection Interrupts Interrupts
|
||||
* define Interrupts if needed
|
||||
*
|
||||
* \code
|
||||
* IFX_INTERRUPT(ATOM0Ch0_ISR, 0, ATOM0_CH0_PRIO)
|
||||
* {}
|
||||
* \endcode
|
||||
*
|
||||
* \subsection Initialization Initialization
|
||||
*
|
||||
* \code
|
||||
* // install interrupt handlers
|
||||
* IfxCpu_Irq_installInterruptHandler (ATOM0Ch0_ISR, ATOM0_CH0_PRIO);
|
||||
*
|
||||
* // enable GTM clock
|
||||
* {
|
||||
* float32 frequency = IfxGtm_Cmu_getModuleFrequency(gtm);
|
||||
* // Enables the GTM
|
||||
* IfxGtm_enable(gtm);
|
||||
* // Set the global clock frequency to the max
|
||||
* IfxGtm_Cmu_setGclkFrequency(gtm, frequency);
|
||||
* // Set the CMU CLK0
|
||||
* IfxGtm_Cmu_setClkFrequency(gtm, IfxGtm_Cmu_Clk_0, frequency);
|
||||
* // FXCLK: used by TOM and CLK0: used by ATOM
|
||||
* IfxGtm_Cmu_enableClocks(gtm, IFXGTM_CMU_CLKEN_FXCLK | IFXGTM_CMU_CLKEN_CLK0);
|
||||
* }
|
||||
*
|
||||
* // initialise ATOM
|
||||
* IfxGtm_Atom_Pwm_Config atomConfig; \\configuration structure
|
||||
* IfxGtm_Atom_Pwm_Driver atomHandle; \\ handle
|
||||
*
|
||||
* IfxGtm_Atom_Pwm_initConfig(&atomConfig, gtm);
|
||||
*
|
||||
* atomConfig.tomChannel = IfxGtm_Tom_Ch_0;
|
||||
* atomConfig.period = 20;
|
||||
* atomConfig.dutyCycle = 10;
|
||||
* atomConfig.interrupt.ccu0Enabled = TRUE;
|
||||
* atomConfig.interrupt.isrPriority = ATOM0_CH0_PRIO;
|
||||
* atomConfig.pin.outputPin = &IfxGtm_ATOM0_0_TOUT0_P02_0_OUT;
|
||||
*
|
||||
* IfxGtm_Atom_Pwm_init(&atomHandle, &atomConfig);
|
||||
* \endcode
|
||||
*
|
||||
* ATOM will be now generating a PWM signal on the selected port pin while generating selected interrupt according to above configured period and duty cycle.
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Atom_Pwm ATOM PWM Interface Driver
|
||||
* \ingroup IfxLld_Gtm_Atom
|
||||
* \defgroup IfxLld_Gtm_Atom_Pwm_DataStructures ATOM PWM DataStructures
|
||||
* \ingroup IfxLld_Gtm_Atom_Pwm
|
||||
* \defgroup IfxLld_Gtm_Atom_Pwm_Pwm_Functions Pwm Functions
|
||||
* \ingroup IfxLld_Gtm_Atom_Pwm
|
||||
*/
|
||||
|
||||
#ifndef IFXGTM_ATOM_PWM_H
|
||||
#define IFXGTM_ATOM_PWM_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_PinMap/IfxGtm_PinMap.h"
|
||||
#include "Gtm/Std/IfxGtm_Atom.h"
|
||||
#include "Gtm/Std/IfxGtm_Cmu.h"
|
||||
#include "Cpu/Std/IfxCpu.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_Pwm_DataStructures
|
||||
* \{ */
|
||||
/** \brief configuration structure for interrupts
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
boolean ccu0Enabled; /**< \brief Enable/Disable choice for CCU0 trigger interrupt */
|
||||
boolean ccu1Enabled; /**< \brief Enable/Disable choice for CCU1 trigger interrupt */
|
||||
IfxGtm_IrqMode mode; /**< \brief IRQ mode of interrupt */
|
||||
IfxSrc_Tos isrProvider; /**< \brief Type of Service for Ccu0/1 interrupt */
|
||||
Ifx_Priority isrPriority; /**< \brief Priority for Ccu0/1 interrupt */
|
||||
} IfxGtm_Atom_Pwm_Interrupt;
|
||||
|
||||
/** \brief configuration structure for output pin
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxGtm_Atom_ToutMap *outputPin; /**< \brief output pin */
|
||||
IfxPort_OutputMode outputMode; /**< \brief Output mode */
|
||||
IfxPort_PadDriver padDriver; /**< \brief Pad driver */
|
||||
} IfxGtm_Atom_Pwm_pin;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_Pwm_DataStructures
|
||||
* \{ */
|
||||
/** \brief Configuration structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_GTM *gtm; /**< \brief Pointer to GTM module */
|
||||
IfxGtm_Atom atom; /**< \brief Index of the ATOM object used */
|
||||
IfxGtm_Atom_Ch atomChannel; /**< \brief ATOM channel used for the timer */
|
||||
IfxGtm_Atom_Mode mode; /**< \brief Atom mode of operation */
|
||||
uint32 period; /**< \brief Period */
|
||||
uint32 dutyCycle; /**< \brief Duty Cycle */
|
||||
Ifx_ActiveState signalLevel; /**< \brief Signal Level */
|
||||
boolean oneShotModeEnabled; /**< \brief Enable/Disable the one shot mode */
|
||||
boolean synchronousUpdateEnabled; /**< \brief Synchronous or Asynchronous update */
|
||||
boolean immediateStartEnabled; /**< \brief enable immediate start after init */
|
||||
IfxGtm_Atom_Pwm_Interrupt interrupt; /**< \brief configuration structure for interrupt */
|
||||
IfxGtm_Atom_Pwm_pin pin; /**< \brief configuration structure for output pin */
|
||||
} IfxGtm_Atom_Pwm_Config;
|
||||
|
||||
/** \brief Driver Handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_GTM *gtm; /**< \brief Pointer to GTM module */
|
||||
IfxGtm_Atom atomIndex; /**< \brief Index of the ATOM object used */
|
||||
IfxGtm_Atom_Ch atomChannel; /**< \brief ATOM channel used for the timer */
|
||||
Ifx_GTM_ATOM *atom; /**< \brief Pointer to the ATOM object */
|
||||
Ifx_GTM_ATOM_AGC *agc; /**< \brief Pointer to the AGC object */
|
||||
IfxGtm_Atom_Mode mode; /**< \brief Atom mode of operation */
|
||||
} IfxGtm_Atom_Pwm_Driver;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_Pwm_Pwm_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initialises the Timer object
|
||||
* \param driver ATOM Handle
|
||||
* \param config Configuration structure for ATOM
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Pwm_init(IfxGtm_Atom_Pwm_Driver *driver, const IfxGtm_Atom_Pwm_Config *config);
|
||||
|
||||
/** \brief Initializes the configuration structure to default
|
||||
* \param config This parameter is Initialised by the function
|
||||
* \param gtm Pointer to GTM module
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Pwm_initConfig(IfxGtm_Atom_Pwm_Config *config, Ifx_GTM *gtm);
|
||||
|
||||
/** \brief Starts the PWM generation from the configured channel.
|
||||
* \param driver handle for the PWM device.
|
||||
* \param immediate immediate start or not.
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Pwm_start(IfxGtm_Atom_Pwm_Driver *driver, boolean immediate);
|
||||
|
||||
/** \brief Stops the PWM generation from the configured channel
|
||||
* \param driver handle for the PWM device
|
||||
* \param immediate immediate start or not.
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Pwm_stop(IfxGtm_Atom_Pwm_Driver *driver, boolean immediate);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXGTM_ATOM_PWM_H */
|
||||
@@ -0,0 +1,746 @@
|
||||
/**
|
||||
* \file IfxGtm_Atom_PwmHl.c
|
||||
* \brief GTM PWMHL details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGtm_Atom_PwmHl.h"
|
||||
#include "_Utilities/Ifx_Assert.h"
|
||||
#include "stddef.h"
|
||||
#include "string.h"
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_PwmHl_PwmHl_StdIf_Functions
|
||||
* \{ */
|
||||
/******************************************************************************/
|
||||
/*------------------------Inline Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Inverts the active state
|
||||
* \param activeState Active state
|
||||
* \return State
|
||||
*/
|
||||
IFX_INLINE Ifx_ActiveState IfxGtm_Atom_PwmHl_invertActiveState(Ifx_ActiveState activeState);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------Private Function Prototypes--------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Sets switched to OFF
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn ON time
|
||||
* \param shift Shift value in ticks
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateAndShiftOff(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn, Ifx_TimerValue *shift);
|
||||
|
||||
/** \brief Updates the x output duty cycle in center aligned and center aligned inverted modes
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn T on
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateCenterAligned(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
/** \brief Updates the x output duty cycle in edge aligned modes (left and right aligned)
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn T on
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateEdgeAligned(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
/** \brief Set the outputs to inactive
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn T on
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateOff(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
/** \brief Update Pulse
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn ON times. Phase 0 top, phase 1 top, ... phase 0 bottom, phase 1 botteom, ...
|
||||
* \param offset Offset value in ticks. Phase 0 top, phase 1 top, ... phase 0 bottom, phase 1 botteom, ...
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updatePulse(IfxGtm_Atom_PwmHl *driver, float32 *tOn, float32 *offset);
|
||||
|
||||
/** \brief Set Pulse to OFF
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn ON times. Phase 0 top, phase 1 top, ... phase 0 bottom, phase 1 botteom, ...
|
||||
* \param offset Offset value in ticks. Phase 0 top, phase 1 top, ... phase 0 bottom, phase 1 botteom, ...
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updatePulseOff(IfxGtm_Atom_PwmHl *driver, float32 *tOn, float32 *offset);
|
||||
|
||||
/** \brief Update Shift Center Aligned
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn ON time
|
||||
* \param shift Shift value in ticks
|
||||
* \return None
|
||||
*/
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateShiftCenterAligned(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn, Ifx_TimerValue *shift);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*------------------------Private Variables/Constants-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_STATIC IFX_CONST IfxGtm_Atom_PwmHl_Mode IfxGtm_Atom_PwmHl_modes[Ifx_Pwm_Mode_off + 1] = {
|
||||
{Ifx_Pwm_Mode_centerAligned, FALSE, &IfxGtm_Atom_PwmHl_updateCenterAligned, &IfxGtm_Atom_PwmHl_updateShiftCenterAligned, &IfxGtm_Atom_PwmHl_updatePulse },
|
||||
{Ifx_Pwm_Mode_centerAlignedInverted, TRUE, &IfxGtm_Atom_PwmHl_updateCenterAligned, &IfxGtm_Atom_PwmHl_updateShiftCenterAligned, &IfxGtm_Atom_PwmHl_updatePulse },
|
||||
{Ifx_Pwm_Mode_leftAligned, FALSE, &IfxGtm_Atom_PwmHl_updateEdgeAligned, &IfxGtm_Atom_PwmHl_updateAndShiftOff, &IfxGtm_Atom_PwmHl_updatePulse },
|
||||
{Ifx_Pwm_Mode_rightAligned, TRUE, &IfxGtm_Atom_PwmHl_updateEdgeAligned, &IfxGtm_Atom_PwmHl_updateAndShiftOff, &IfxGtm_Atom_PwmHl_updatePulse },
|
||||
{Ifx_Pwm_Mode_off, FALSE, &IfxGtm_Atom_PwmHl_updateOff, &IfxGtm_Atom_PwmHl_updateAndShiftOff, &IfxGtm_Atom_PwmHl_updatePulseOff},
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE Ifx_ActiveState IfxGtm_Atom_PwmHl_invertActiveState(Ifx_ActiveState activeState)
|
||||
{
|
||||
return activeState == Ifx_ActiveState_low ? Ifx_ActiveState_high : Ifx_ActiveState_low;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
float32 IfxGtm_Atom_PwmHl_getDeadtime(IfxGtm_Atom_PwmHl *driver)
|
||||
{
|
||||
return IfxStdIf_Timer_tickToS(driver->timer->base.clockFreq, driver->base.deadtime);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Atom_PwmHl_getMinPulse(IfxGtm_Atom_PwmHl *driver)
|
||||
{
|
||||
return IfxStdIf_Timer_tickToS(driver->timer->base.clockFreq, driver->base.minPulse - driver->base.deadtime);
|
||||
}
|
||||
|
||||
|
||||
Ifx_Pwm_Mode IfxGtm_Atom_PwmHl_getMode(IfxGtm_Atom_PwmHl *driver)
|
||||
{
|
||||
return driver->base.mode;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_PwmHl_init(IfxGtm_Atom_PwmHl *driver, const IfxGtm_Atom_PwmHl_Config *config)
|
||||
{
|
||||
boolean result = TRUE;
|
||||
uint16 channelMask;
|
||||
uint16 channelsMask = 0;
|
||||
uint32 channelIndex;
|
||||
|
||||
IfxGtm_Atom_Timer *timer = config->timer;
|
||||
|
||||
driver->base.mode = Ifx_Pwm_Mode_init;
|
||||
driver->timer = timer;
|
||||
driver->base.setMode = 0;
|
||||
driver->base.inverted = FALSE;
|
||||
driver->base.ccxActiveState = config->base.ccxActiveState;
|
||||
driver->base.coutxActiveState = config->base.coutxActiveState;
|
||||
driver->base.channelCount = config->base.channelCount;
|
||||
|
||||
IfxGtm_Atom_PwmHl_setDeadtime(driver, config->base.deadtime);
|
||||
IfxGtm_Atom_PwmHl_setMinPulse(driver, config->base.minPulse);
|
||||
|
||||
driver->atom = &(timer->gtm->ATOM[config->atom]);
|
||||
/* Only one AGC */
|
||||
driver->agc = (Ifx_GTM_ATOM_AGC *)&driver->atom->AGC.GLB_CTRL;
|
||||
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->base.channelCount <= IFXGTM_ATOM_PWMHL_MAX_NUM_CHANNELS);
|
||||
|
||||
IfxGtm_Cmu_Clk clock = IfxGtm_Atom_Ch_getClockSource(timer->atom, timer->timerChannel);
|
||||
|
||||
for (channelIndex = 0; channelIndex < config->base.channelCount; channelIndex++)
|
||||
{
|
||||
IfxGtm_Atom_Ch channel;
|
||||
/* CCX */
|
||||
channel = config->ccx[channelIndex]->channel;
|
||||
driver->ccx[channelIndex] = channel;
|
||||
channelMask = 1 << channel;
|
||||
channelsMask |= channelMask;
|
||||
|
||||
/* Initialize the timer part */
|
||||
IfxGtm_Atom_Ch_configurePwmMode(driver->atom, channel, clock,
|
||||
driver->base.inverted ? config->base.ccxActiveState :
|
||||
IfxGtm_Atom_PwmHl_invertActiveState(config->base.ccxActiveState),
|
||||
IfxGtm_Atom_Ch_ResetEvent_onTrigger, IfxGtm_Atom_Ch_OutputTrigger_forward);
|
||||
|
||||
/* Initialize the port */
|
||||
if (config->initPins == TRUE)
|
||||
{
|
||||
IfxGtm_PinMap_setAtomTout(config->ccx[channelIndex],
|
||||
config->base.outputMode, config->base.outputDriver);
|
||||
}
|
||||
|
||||
/* COUTX */
|
||||
channel = config->coutx[channelIndex]->channel;
|
||||
driver->coutx[channelIndex] = channel;
|
||||
channelMask = 1 << channel;
|
||||
channelsMask |= channelMask;
|
||||
|
||||
/* Initialize the timer part */
|
||||
IfxGtm_Atom_Ch_configurePwmMode(driver->atom, channel, clock,
|
||||
driver->base.inverted ?
|
||||
IfxGtm_Atom_PwmHl_invertActiveState(config->base.coutxActiveState)
|
||||
: config->base.coutxActiveState,
|
||||
IfxGtm_Atom_Ch_ResetEvent_onTrigger, IfxGtm_Atom_Ch_OutputTrigger_forward);
|
||||
|
||||
/* Initialize the port */
|
||||
if (config->initPins == TRUE)
|
||||
{
|
||||
IfxGtm_PinMap_setAtomTout(config->coutx[channelIndex],
|
||||
config->base.outputMode, config->base.outputDriver);
|
||||
}
|
||||
}
|
||||
|
||||
IfxGtm_Atom_Agc_enableChannelsOutput(driver->agc, channelsMask, 0, TRUE);
|
||||
IfxGtm_Atom_Agc_enableChannels(driver->agc, channelsMask, 0, TRUE);
|
||||
|
||||
IfxGtm_Atom_PwmHl_setMode(driver, Ifx_Pwm_Mode_off);
|
||||
|
||||
Ifx_TimerValue tOn[IFXGTM_ATOM_PWMHL_MAX_NUM_CHANNELS] = {0};
|
||||
IfxGtm_Atom_PwmHl_updateOff(driver, tOn); /* tOn do not need defined values */
|
||||
|
||||
/* Transfer the shadow registers */
|
||||
IfxGtm_Atom_Agc_setChannelsForceUpdate(driver->agc, channelsMask, 0, 0, 0);
|
||||
IfxGtm_Atom_Agc_trigger(driver->agc);
|
||||
IfxGtm_Atom_Agc_setChannelsForceUpdate(driver->agc, 0, channelsMask, 0, 0);
|
||||
|
||||
/* Enable timer to update the channels */
|
||||
|
||||
for (channelIndex = 0; channelIndex < driver->base.channelCount; channelIndex++)
|
||||
{
|
||||
IfxGtm_Atom_Timer_addToChannelMask(timer, driver->ccx[channelIndex]);
|
||||
IfxGtm_Atom_Timer_addToChannelMask(timer, driver->coutx[channelIndex]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_PwmHl_initConfig(IfxGtm_Atom_PwmHl_Config *config)
|
||||
{
|
||||
IfxStdIf_PwmHl_initConfig(&config->base);
|
||||
config->timer = NULL_PTR;
|
||||
config->atom = IfxGtm_Atom_0;
|
||||
config->ccx = NULL_PTR;
|
||||
config->coutx = NULL_PTR;
|
||||
config->initPins = TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_PwmHl_setDeadtime(IfxGtm_Atom_PwmHl *driver, float32 deadtime)
|
||||
{
|
||||
Ifx_TimerValue value = IfxStdIf_Timer_sToTick(driver->timer->base.clockFreq, deadtime);
|
||||
driver->base.deadtime = value;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_PwmHl_setMinPulse(IfxGtm_Atom_PwmHl *driver, float32 minPulse)
|
||||
{
|
||||
Ifx_TimerValue value = IfxStdIf_Timer_sToTick(driver->timer->base.clockFreq, minPulse);
|
||||
|
||||
driver->base.minPulse = value + driver->base.deadtime;
|
||||
driver->base.maxPulse = driver->timer->base.period - driver->base.minPulse;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_PwmHl_setMode(IfxGtm_Atom_PwmHl *driver, Ifx_Pwm_Mode mode)
|
||||
{
|
||||
boolean result = TRUE;
|
||||
IfxGtm_Atom_PwmHl_Base *base = &driver->base;
|
||||
|
||||
if (base->mode != mode)
|
||||
{
|
||||
if ((mode > Ifx_Pwm_Mode_off) || (IfxGtm_Atom_PwmHl_modes[mode].update == NULL_PTR))
|
||||
{
|
||||
mode = Ifx_Pwm_Mode_off;
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mode == IfxGtm_Atom_PwmHl_modes[mode].mode);
|
||||
|
||||
base->mode = mode;
|
||||
driver->update = IfxGtm_Atom_PwmHl_modes[mode].update;
|
||||
driver->updateAndShift = IfxGtm_Atom_PwmHl_modes[mode].updateAndShift;
|
||||
driver->updatePulse = IfxGtm_Atom_PwmHl_modes[mode].updatePulse;
|
||||
|
||||
if (base->mode != Ifx_Pwm_Mode_off)
|
||||
{
|
||||
base->inverted = IfxGtm_Atom_PwmHl_modes[mode].inverted;
|
||||
}
|
||||
else
|
||||
{ /* Keep previous inverted for off mode */
|
||||
}
|
||||
|
||||
if (base->inverted)
|
||||
{
|
||||
driver->ccxTemp = driver->coutx;
|
||||
driver->coutxTemp = driver->ccx;
|
||||
}
|
||||
else
|
||||
{
|
||||
driver->ccxTemp = driver->ccx;
|
||||
driver->coutxTemp = driver->coutx;
|
||||
}
|
||||
|
||||
{ /* Workaround to enable the signal inversion required for center aligned inverted
|
||||
* and right aligned modes */
|
||||
/** \note Changing signal level may produce short circuit at the power stage,
|
||||
* in which case the inverter must be disable during this action.*/
|
||||
|
||||
/* Ifx_Pwm_Mode_centerAligned and Ifx_Pwm_Mode_LeftAligned use inverted=FALSE */
|
||||
/* Ifx_Pwm_Mode_centerAlignedInverted and Ifx_Pwm_Mode_RightAligned use inverted=TRUE */
|
||||
uint32 channelIndex;
|
||||
|
||||
for (channelIndex = 0; channelIndex < driver->base.channelCount; channelIndex++)
|
||||
{
|
||||
IfxGtm_Atom_Ch channel;
|
||||
|
||||
channel = driver->ccx[channelIndex];
|
||||
IfxGtm_Atom_Ch_setSignalLevel(driver->atom, channel, base->inverted
|
||||
? base->ccxActiveState
|
||||
: IfxGtm_Atom_PwmHl_invertActiveState(driver->base.ccxActiveState));
|
||||
|
||||
channel = driver->coutx[channelIndex];
|
||||
IfxGtm_Atom_Ch_setSignalLevel(driver->atom, channel, base->inverted
|
||||
? IfxGtm_Atom_PwmHl_invertActiveState(driver->base.coutxActiveState)
|
||||
: base->coutxActiveState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_PwmHl_setOnTime(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn)
|
||||
{
|
||||
driver->update(driver, tOn);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_PwmHl_setOnTimeAndShift(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn, Ifx_TimerValue *shift)
|
||||
{
|
||||
driver->updateAndShift(driver, tOn, shift);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_PwmHl_setPulse(IfxGtm_Atom_PwmHl *driver, float32 *tOn, float32 *offset)
|
||||
{
|
||||
driver->updatePulse(driver, tOn, offset);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_PwmHl_setupChannels(IfxGtm_Atom_PwmHl *driver, boolean *activeCh, boolean *stuckSt)
|
||||
{
|
||||
/* Dummy Function for StdIf Compile*/
|
||||
IFX_UNUSED_PARAMETER(driver)
|
||||
IFX_UNUSED_PARAMETER(activeCh)
|
||||
IFX_UNUSED_PARAMETER(stuckSt)
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_PwmHl_stdIfPwmHlInit(IfxStdIf_PwmHl *stdif, IfxGtm_Atom_PwmHl *driver)
|
||||
{
|
||||
/* Ensure the stdif is reset to zeros */
|
||||
memset(stdif, 0, sizeof(IfxStdIf_PwmHl));
|
||||
|
||||
/* *INDENT-OFF* Note: this file was indented manually by the author. */
|
||||
/* Set the API link */
|
||||
stdif->driver = driver;
|
||||
stdif->setDeadtime = (IfxStdIf_PwmHl_SetDeadtime )&IfxGtm_Atom_PwmHl_setDeadtime;
|
||||
stdif->getDeadtime = (IfxStdIf_PwmHl_GetDeadtime )&IfxGtm_Atom_PwmHl_getDeadtime;
|
||||
stdif->setMinPulse = (IfxStdIf_PwmHl_SetMinPulse )&IfxGtm_Atom_PwmHl_setMinPulse;
|
||||
stdif->getMinPulse = (IfxStdIf_PwmHl_GetMinPulse )&IfxGtm_Atom_PwmHl_getMinPulse;
|
||||
stdif->getMode = (IfxStdIf_PwmHl_GetMode )&IfxGtm_Atom_PwmHl_getMode;
|
||||
stdif->setMode = (IfxStdIf_PwmHl_SetMode )&IfxGtm_Atom_PwmHl_setMode;
|
||||
stdif->setOnTime = (IfxStdIf_PwmHl_SetOnTime )&IfxGtm_Atom_PwmHl_setOnTime;
|
||||
stdif->setOnTimeAndShift = (IfxStdIf_PwmHl_SetOnTimeAndShift)&IfxGtm_Atom_PwmHl_setOnTimeAndShift;
|
||||
stdif->setPulse = (IfxStdIf_PwmHl_SetPulse )&IfxGtm_Atom_PwmHl_setPulse;
|
||||
stdif->setupChannels = (IfxStdIf_PwmHl_SetupChannels )&IfxGtm_Atom_PwmHl_setupChannels;
|
||||
IfxGtm_Atom_Timer_stdIfTimerInit(&stdif->timer, driver->timer);
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateAndShiftOff(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn, Ifx_TimerValue *shift)
|
||||
{
|
||||
IfxGtm_Atom_PwmHl_updateOff(driver, NULL_PTR);
|
||||
IFX_UNUSED_PARAMETER(tOn)
|
||||
IFX_UNUSED_PARAMETER(shift)
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateCenterAligned(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn)
|
||||
{
|
||||
uint8 channelIndex;
|
||||
Ifx_TimerValue period;
|
||||
Ifx_TimerValue deadtime = driver->base.deadtime;
|
||||
|
||||
period = driver->timer->base.period;
|
||||
|
||||
for (channelIndex = 0; channelIndex < driver->base.channelCount; channelIndex++)
|
||||
{
|
||||
Ifx_TimerValue x; /* x=period*dutyCycle, x=OnTime+deadTime */
|
||||
Ifx_TimerValue cm0, cm1;
|
||||
x = tOn[channelIndex];
|
||||
|
||||
if (driver->base.inverted != FALSE)
|
||||
{
|
||||
x = period - x;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
if ((x < driver->base.minPulse) || (x <= deadtime))
|
||||
{ /* For deadtime condition: avoid leading edge of top channel to occur after the trailing edge */
|
||||
x = 0;
|
||||
}
|
||||
else if (x > driver->base.maxPulse)
|
||||
{
|
||||
x = period;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
/* Special handling due to GTM issue */
|
||||
if (x == period)
|
||||
{ /* 100% duty cycle */
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex],
|
||||
period + 1 /* No compare event */,
|
||||
2 /* 1st compare event (issue: expected to be 1)*/ + deadtime);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex],
|
||||
period + 2 /* No compare event, issues has been seen with +1 */,
|
||||
2 /* 1st compare event (issue: expected to be 1)*/);
|
||||
}
|
||||
else if (x == 0)
|
||||
{
|
||||
cm0 = 1;
|
||||
cm1 = period + 2;
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex], cm0, cm1);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex], cm0 + deadtime, cm1);
|
||||
}
|
||||
else
|
||||
{ /* x% duty cycle */
|
||||
cm1 = (period - x) / 2; // CM1
|
||||
cm0 = (period + x) / 2; // CM0
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex], cm0, cm1 + deadtime);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex], cm0 + deadtime, cm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateEdgeAligned(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn)
|
||||
{
|
||||
uint8 channelIndex;
|
||||
Ifx_TimerValue period;
|
||||
Ifx_TimerValue deadtime = driver->base.deadtime;
|
||||
|
||||
period = driver->timer->base.period;
|
||||
|
||||
for (channelIndex = 0; channelIndex < driver->base.channelCount; channelIndex++)
|
||||
{
|
||||
Ifx_TimerValue x; /* x=period*dutyCycle, x=OnTime+deadTime */
|
||||
Ifx_TimerValue cm0, cm1;
|
||||
x = tOn[channelIndex];
|
||||
|
||||
if (driver->base.inverted != FALSE)
|
||||
{
|
||||
x = period - x;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
if ((x < driver->base.minPulse) || (x <= deadtime))
|
||||
{ /* For deadtime condition: avoid leading edge of top channel to occur after the trailing edge */
|
||||
x = 0;
|
||||
}
|
||||
else if (x > driver->base.maxPulse)
|
||||
{
|
||||
x = period;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
/* Special handling due to GTM issue */
|
||||
if (x == period)
|
||||
{ /* 100% duty cycle */
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex],
|
||||
period + 1 /* No compare event */,
|
||||
2 /* 1st compare event (issue: expected to be 1)*/ + deadtime);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex],
|
||||
period + 2 /* No compare event, issues has been seen with +1 */,
|
||||
2 /* 1st compare event (issue: expected to be 1)*/);
|
||||
}
|
||||
else if (x == 0)
|
||||
{
|
||||
cm0 = 1;
|
||||
cm1 = period + 2;
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex], cm0, cm1);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex], cm0 + deadtime, cm1);
|
||||
}
|
||||
else
|
||||
{ /* x% duty cycle */
|
||||
cm1 = 2; // CM1, set to 2 due to a GTM issue. should be 1 according to spec
|
||||
cm0 = x; // CM0, set to x+2 due to a GTM issue. should be x+1 according to spec
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex], cm0, cm1 + deadtime);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex], cm0 + deadtime, cm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateOff(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(tOn)
|
||||
uint8 channelIndex;
|
||||
Ifx_TimerValue period;
|
||||
period = driver->timer->base.period;
|
||||
|
||||
for (channelIndex = 0; channelIndex < driver->base.channelCount; channelIndex++)
|
||||
{
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex],
|
||||
2 /* 1 will keep the previous level*/, period + 2);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex], period + 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updatePulse(IfxGtm_Atom_PwmHl *driver, float32 *tOn, float32 *offset)
|
||||
{
|
||||
uint8 channelIndex;
|
||||
Ifx_TimerValue period;
|
||||
|
||||
period = driver->timer->base.period;
|
||||
|
||||
/* Top channels */
|
||||
for (channelIndex = 0; channelIndex < driver->base.channelCount; channelIndex++)
|
||||
{
|
||||
Ifx_TimerValue x; /* x=period*dutyCycle, x=OnTime+deadTime */
|
||||
Ifx_TimerValue o;
|
||||
Ifx_TimerValue cm0, cm1;
|
||||
|
||||
x = IfxStdIf_Timer_sToTick(driver->timer->base.clockFreq, tOn[channelIndex]);
|
||||
o = IfxStdIf_Timer_sToTick(driver->timer->base.clockFreq, offset[channelIndex]);
|
||||
|
||||
if (driver->base.inverted != FALSE)
|
||||
{
|
||||
x = period - x;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
if ((x < driver->base.minPulse) || (o > period))
|
||||
{
|
||||
x = 0;
|
||||
}
|
||||
else if ((x > driver->base.maxPulse) || (o + x > period))
|
||||
{
|
||||
x = period;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
/* Special handling due to GTM issue */
|
||||
if (x == period)
|
||||
{ /* 100% duty cycle */
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex],
|
||||
period + 1 /* No compare event */,
|
||||
2 /* 1st compare event (issue: expected to be 1)*/);
|
||||
}
|
||||
else if (x == 0)
|
||||
{
|
||||
cm0 = 1;
|
||||
cm1 = period + 2;
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex], cm0, cm1);
|
||||
}
|
||||
else
|
||||
{ /* x% duty cycle */
|
||||
cm1 = 2 + o; // CM1, set to 2 due to a GTM issue. should be 1 according to spec
|
||||
cm0 = o + x; // CM0, set to x+2 due to a GTM issue. should be x+1 according to spec
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex], cm0, cm1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Bottom channels */
|
||||
for (channelIndex = 0; channelIndex < driver->base.channelCount; channelIndex++)
|
||||
{
|
||||
Ifx_TimerValue x; /* x=period*dutyCycle, x=OnTime+deadTime */
|
||||
Ifx_TimerValue o;
|
||||
Ifx_TimerValue cm0, cm1;
|
||||
|
||||
x = IfxStdIf_Timer_sToTick(driver->timer->base.clockFreq, tOn[channelIndex + driver->base.channelCount]);
|
||||
o = IfxStdIf_Timer_sToTick(driver->timer->base.clockFreq, offset[channelIndex + driver->base.channelCount]);
|
||||
|
||||
if (driver->base.inverted != FALSE)
|
||||
{
|
||||
x = period - x;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
if (x < driver->base.minPulse)
|
||||
{
|
||||
x = 0;
|
||||
}
|
||||
else if (x > driver->base.maxPulse)
|
||||
{
|
||||
x = period;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
/* Special handling due to GTM issue */
|
||||
if (x == period)
|
||||
{ /* 100% duty cycle */
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex],
|
||||
period + 2 /* No compare event, issues has been seen with +1 */,
|
||||
2 /* 1st compare event (issue: expected to be 1)*/);
|
||||
}
|
||||
else if (x == 0)
|
||||
{
|
||||
cm0 = 1;
|
||||
cm1 = period + 2;
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex], cm0, cm1);
|
||||
}
|
||||
else
|
||||
{ /* x% duty cycle */
|
||||
cm1 = 2 + o; // CM1, set to 2 due to a GTM issue. should be 1 according to spec
|
||||
cm0 = o + x; // CM0, set to x+2 due to a GTM issue. should be x+1 according to spec
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex], cm0, cm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updatePulseOff(IfxGtm_Atom_PwmHl *driver, float32 *tOn, float32 *offset)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(tOn)
|
||||
IFX_UNUSED_PARAMETER(offset)
|
||||
|
||||
IfxGtm_Atom_PwmHl_updateOff(driver, NULL_PTR);
|
||||
}
|
||||
|
||||
|
||||
IFX_STATIC void IfxGtm_Atom_PwmHl_updateShiftCenterAligned(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn, Ifx_TimerValue *shift)
|
||||
{
|
||||
uint8 channelIndex;
|
||||
Ifx_TimerValue period;
|
||||
Ifx_TimerValue deadtime = driver->base.deadtime;
|
||||
|
||||
period = driver->timer->base.period;
|
||||
|
||||
for (channelIndex = 0; channelIndex < driver->base.channelCount; channelIndex++)
|
||||
{
|
||||
Ifx_TimerValue x; /* x=period*dutyCycle, x=OnTime+deadTime */
|
||||
Ifx_TimerValue s; /* Shift value */
|
||||
Ifx_TimerValue cm0, cm1;
|
||||
x = tOn[channelIndex];
|
||||
|
||||
if (driver->base.inverted != FALSE)
|
||||
{
|
||||
x = period - x;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
if ((x < driver->base.minPulse) || (x <= deadtime))
|
||||
{ /* For deadtime condition: avoid leading edge of top channel to occur after the trailing edge */
|
||||
x = 0;
|
||||
}
|
||||
else if (x > driver->base.maxPulse)
|
||||
{
|
||||
x = period;
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
/* Special handling due to GTM issue */
|
||||
if (x == period)
|
||||
{ /* 100% duty cycle */
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex],
|
||||
period + 1 /* No compare event */,
|
||||
2 /* 1st compare event (issue: expected to be 1)*/ + deadtime);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex],
|
||||
period + 2 /* No compare event, issues has been seen with +1 */,
|
||||
2 /* 1st compare event (issue: expected to be 1)*/);
|
||||
}
|
||||
else if (x == 0)
|
||||
{
|
||||
cm0 = 1;
|
||||
cm1 = period + 2;
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex], cm0, cm1);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex], cm0 + deadtime, cm1);
|
||||
}
|
||||
else
|
||||
{ /* x% duty cycle */
|
||||
s = shift[channelIndex];
|
||||
|
||||
if (s > 0)
|
||||
{
|
||||
s = __minX(s, (period - x) / 2 - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
s = __maxX(s, (x - period) / 2 + 1);
|
||||
}
|
||||
|
||||
cm1 = s + (period - x) / 2; // CM1
|
||||
cm0 = s + (period + x) / 2; // CM0
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->ccxTemp[channelIndex], cm0, cm1 + deadtime);
|
||||
IfxGtm_Atom_Ch_setCompareShadow(driver->atom, driver->coutxTemp[channelIndex], cm0 + deadtime, cm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* \file IfxGtm_Atom_PwmHl.h
|
||||
* \brief GTM PWMHL details
|
||||
* \ingroup IfxLld_Gtm
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Atom_PwmHl_Usage How to use the GTM ATOM PWM Driver
|
||||
* \ingroup IfxLld_Gtm_Atom_PwmHl
|
||||
*
|
||||
* This driver implements the PWM functionalities as defined by \ref library_srvsw_stdif_pwmhl.
|
||||
* The user is free to use either the driver specific APIs below or to used the \ref library_srvsw_stdif_pwmhl "standard interface APIs".
|
||||
*
|
||||
* \section Specific Specific implementation
|
||||
* Implementation is similar to \ref IfxLld_Gtm_Tom_PwmHl
|
||||
*
|
||||
* \todo add documentation
|
||||
*
|
||||
* For a detailed configuration of the microcontroller, see \ref IfxGtm_Atom_PwmHl_init().
|
||||
*
|
||||
* \section Example Usage example
|
||||
* Initialisation is done by, e.g:
|
||||
* \code
|
||||
* IfxGtm_Atom_PwmHl_Config driverConfig;
|
||||
* IfxGtm_Atom_PwmHl driverData;
|
||||
* IfxStdIf_PwmHl pwmhl;
|
||||
* IfxGtm_Atom_PwmHl_initConfig(&driverConfig, &MODULE_GTM);
|
||||
* IfxGtm_Atom_PwmHl_init(&driverData, &driverConfig);
|
||||
* IfxGtm_Atom_PwmHl_stdIfPwmHlInit(pwmhl, &driverData);
|
||||
* \endcode
|
||||
*
|
||||
* During run-time, \ref library_srvsw_stdif_pwmhl "the interface functions" shall be used, e.g.:
|
||||
* \code
|
||||
* IfxStdIf_Timer* timer = IfxStdIf_PwmHl_getTimer(pwmhl);
|
||||
* Ifx_TimerValue onTime[3]; // assume configured for three HL channels
|
||||
*
|
||||
* onTime[0] = 10;
|
||||
* onTime[1] = 20;
|
||||
* onTime[2] = 30;
|
||||
*
|
||||
* IfxStdIf_Timer_disableUpdate(timer);
|
||||
* IfxStdIf_Timer_setPeriod(timer, period);
|
||||
* IfxStdIf_PwmHl_setOnTime(pwmhl, onTime);
|
||||
* IfxStdIf_Timer_applyUpdate(timer);
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Atom_PwmHl ATOM PWM HL Interface Driver
|
||||
* \ingroup IfxLld_Gtm_Atom
|
||||
* \defgroup IfxLld_Gtm_Atom_PwmHl_Data_Structures Data Structures
|
||||
* \ingroup IfxLld_Gtm_Atom_PwmHl
|
||||
* \defgroup IfxLld_Gtm_Atom_PwmHl_Functions PwmHl Functions
|
||||
* \ingroup IfxLld_Gtm_Atom_PwmHl
|
||||
* \defgroup IfxLld_Gtm_Atom_PwmHl_PwmHl_StdIf_Functions PwmHl StdIf Functions
|
||||
* \ingroup IfxLld_Gtm_Atom_PwmHl
|
||||
*/
|
||||
|
||||
#ifndef IFXGTM_ATOM_PWMHL_H
|
||||
#define IFXGTM_ATOM_PWMHL_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "StdIf/IfxStdIf_PwmHl.h"
|
||||
#include "Gtm/Atom/Timer/IfxGtm_Atom_Timer.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------------Macros-----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Maximal number of channels handled by the driver. One channel has a top and bottom pwm output
|
||||
*/
|
||||
#define IFXGTM_ATOM_PWMHL_MAX_NUM_CHANNELS (8)
|
||||
|
||||
/******************************************************************************/
|
||||
/*------------------------------Type Definitions------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct IfxGtm_Atom_PwmHl_s IfxGtm_Atom_PwmHl;
|
||||
|
||||
typedef void (*IfxGtm_Atom_PwmHl_Update)(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
typedef void (*IfxGtm_Atom_PwmHl_UpdateShift)(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn, Ifx_TimerValue *shift);
|
||||
|
||||
typedef void (*IfxGtm_Atom_PwmHl_UpdatePulse)(IfxGtm_Atom_PwmHl *driver, float32 *tOn, float32 *offset);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_PwmHl_Data_Structures
|
||||
* \{ */
|
||||
/** \brief Multi-channels PWM object definition (channels only)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_TimerValue deadtime; /**< \brief Dead time between the top and bottom channel in ticks */
|
||||
Ifx_TimerValue minPulse; /**< \brief minimum pulse that is output, shorter pulse time will be output as 0% duty cycle */
|
||||
Ifx_TimerValue maxPulse; /**< \brief internal parameter */
|
||||
Ifx_Pwm_Mode mode; /**< \brief actual PWM mode */
|
||||
sint8 setMode; /**< \brief A non zero flag indicates that the PWM mode is being modified */
|
||||
Ifx_ActiveState ccxActiveState; /**< \brief Top PWM active state */
|
||||
Ifx_ActiveState coutxActiveState; /**< \brief Bottom PWM active state */
|
||||
boolean inverted; /**< \brief Flag indicating the center aligned inverted mode (TRUE) */
|
||||
uint8 channelCount; /**< \brief Number of PWM channels, one channel is made of a top and bottom channel */
|
||||
} IfxGtm_Atom_PwmHl_Base;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_PwmHl_Data_Structures
|
||||
* \{ */
|
||||
/** \brief GTM ATOM: PWM HL configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxStdIf_PwmHl_Config base; /**< \brief PWM HL standard interface configuration */
|
||||
IfxGtm_Atom_Timer *timer; /**< \brief Pointer to the linked timer object */
|
||||
IfxGtm_Atom atom; /**< \brief ATOM unit used */
|
||||
IFX_CONST IfxGtm_Atom_ToutMapP *ccx; /**< \brief Pointer to an array of size pwmHl.channels.channelCount containing the channels used. Channels must be adjacent channels */
|
||||
IFX_CONST IfxGtm_Atom_ToutMapP *coutx; /**< \brief Pointer to an array of size pwmHl.channels.channelCount containing the channels used. Channels must be adjacent channels */
|
||||
boolean initPins; /**< \brief TRUE: Initialize pins in driver
|
||||
* FALSE: Don't initialize pins in driver. User handles separately. */
|
||||
} IfxGtm_Atom_PwmHl_Config;
|
||||
|
||||
/** \brief Structure for PWM configuration
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_Pwm_Mode mode; /**< \brief Pwm Mode */
|
||||
boolean inverted; /**< \brief Inverted configuration for the selected mode */
|
||||
IfxGtm_Atom_PwmHl_Update update; /**< \brief update call back function for the selected mode */
|
||||
IfxGtm_Atom_PwmHl_UpdateShift updateAndShift; /**< \brief update shift call back function for the selected mode */
|
||||
IfxGtm_Atom_PwmHl_UpdatePulse updatePulse; /**< \brief update pulse call back function for the selected mode */
|
||||
} IfxGtm_Atom_PwmHl_Mode;
|
||||
|
||||
/** \brief GTM ATOM PWM driver
|
||||
*/
|
||||
struct IfxGtm_Atom_PwmHl_s
|
||||
{
|
||||
IfxGtm_Atom_PwmHl_Base base; /**< \brief Multi-channels PWM object definition (channels only) */
|
||||
IfxGtm_Atom_Timer *timer; /**< \brief Pointer to the linked timer object */
|
||||
IfxGtm_Atom_PwmHl_Update update; /**< \brief Update function for actual selected mode */
|
||||
IfxGtm_Atom_PwmHl_UpdateShift updateAndShift; /**< \brief Update shift function for actual selected mode */
|
||||
IfxGtm_Atom_PwmHl_UpdatePulse updatePulse; /**< \brief Update pulse function for actual selected mode */
|
||||
Ifx_GTM_ATOM *atom; /**< \brief ATOM unit used */
|
||||
Ifx_GTM_ATOM_AGC *agc; /**< \brief AGC unit used */
|
||||
IfxGtm_Atom_Ch ccx[IFXGTM_ATOM_PWMHL_MAX_NUM_CHANNELS]; /**< \brief ATOM channels used for the CCCX outputs */
|
||||
IfxGtm_Atom_Ch coutx[IFXGTM_ATOM_PWMHL_MAX_NUM_CHANNELS]; /**< \brief ATOM channels used for the OUTX outputs */
|
||||
IfxGtm_Atom_Ch *ccxTemp; /**< \brief cached value */
|
||||
IfxGtm_Atom_Ch *coutxTemp; /**< \brief cached value */
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_PwmHl_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Initializes the timer object
|
||||
* note To ensure that the channels counter are reset by the timer and do not overflow, leading to random signal on the output, the timer must be started before the call to this function.
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param config GTM ATOM: PWM HL configuration
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_PwmHl_init(IfxGtm_Atom_PwmHl *driver, const IfxGtm_Atom_PwmHl_Config *config);
|
||||
|
||||
/** \brief Initialize the configuration structure to default
|
||||
* \param config Channel configuration. This parameter is Initialised by the function
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_PwmHl_initConfig(IfxGtm_Atom_PwmHl_Config *config);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_PwmHl_PwmHl_StdIf_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the dead time
|
||||
* \see IfxStdIf_PwmHl_GetDeadtime
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \return Dead Time
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Atom_PwmHl_getDeadtime(IfxGtm_Atom_PwmHl *driver);
|
||||
|
||||
/** \brief Returns the minimum pulse
|
||||
* \see IfxStdIf_PwmHl_GetMinPulse
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \return Min Pulse
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Atom_PwmHl_getMinPulse(IfxGtm_Atom_PwmHl *driver);
|
||||
|
||||
/** \brief Returns Pwm mode
|
||||
* \see IfxStdIf_PwmHl_GetMode
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \return Pwm mode
|
||||
*/
|
||||
IFX_EXTERN Ifx_Pwm_Mode IfxGtm_Atom_PwmHl_getMode(IfxGtm_Atom_PwmHl *driver);
|
||||
|
||||
/** \brief Sets the dead time
|
||||
* \see IfxStdIf_PwmHl_SetDeadtime
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param deadtime Dead time value
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_PwmHl_setDeadtime(IfxGtm_Atom_PwmHl *driver, float32 deadtime);
|
||||
|
||||
/** \brief Sets the minimum pulse
|
||||
* \see IfxStdIf_PwmHl_SetMinPulse
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param minPulse Minimum pulse
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_PwmHl_setMinPulse(IfxGtm_Atom_PwmHl *driver, float32 minPulse);
|
||||
|
||||
/** \brief Sets the PWM mode, the mode is only applied after setOnTime() + applyUpdate()
|
||||
* \see IfxStdIf_PwmHl_SetMode
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param mode Pwm mode
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_PwmHl_setMode(IfxGtm_Atom_PwmHl *driver, Ifx_Pwm_Mode mode);
|
||||
|
||||
/** \brief Sets the ON time
|
||||
* \see IfxStdIf_PwmHl_SetOnTime
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn ON time
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_PwmHl_setOnTime(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn);
|
||||
|
||||
/** \brief Sets the ON time and Shift
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn ON time
|
||||
* \param shift Shift value in ticks
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_PwmHl_setOnTimeAndShift(IfxGtm_Atom_PwmHl *driver, Ifx_TimerValue *tOn, Ifx_TimerValue *shift);
|
||||
|
||||
/** \brief Sets the ON time and offset, all switched are independent
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param tOn ON times. Phase 0 top, phase 1 top, ... phase 0 bottom, phase 1 botteom, ...
|
||||
* \param offset Offset value in ticks. Phase 0 top, phase 1 top, ... phase 0 bottom, phase 1 botteom, ...
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_PwmHl_setPulse(IfxGtm_Atom_PwmHl *driver, float32 *tOn, float32 *offset);
|
||||
|
||||
/** \brief Set up channels
|
||||
* \see IfxStdIf_PwmHl_SetupChannels
|
||||
* \param driver GTM ATOM PWM driver
|
||||
* \param activeCh Active channel
|
||||
* \param stuckSt Stuck state
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_PwmHl_setupChannels(IfxGtm_Atom_PwmHl *driver, boolean *activeCh, boolean *stuckSt);
|
||||
|
||||
/** \brief Initialises the statndard interface Pwm
|
||||
* \param stdif Standard interface object, will be initialized by the function
|
||||
* \param driver Interface driver to be used by the standard interface. must be initialised separately
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_PwmHl_stdIfPwmHlInit(IfxStdIf_PwmHl *stdif, IfxGtm_Atom_PwmHl *driver);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXGTM_ATOM_PWMHL_H */
|
||||
@@ -0,0 +1,393 @@
|
||||
/**
|
||||
* \file IfxGtm_Atom_Timer.c
|
||||
* \brief GTM TIMER details
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGtm_Atom_Timer.h"
|
||||
#include "_Utilities/Ifx_Assert.h"
|
||||
#include "IfxGtm_bf.h"
|
||||
#include "stddef.h"
|
||||
#include "string.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
boolean IfxGtm_Atom_Timer_acknowledgeTimerIrq(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
boolean event;
|
||||
event = IfxGtm_Atom_Ch_isZeroNotification(driver->atom, driver->timerChannel);
|
||||
|
||||
if (event)
|
||||
{
|
||||
IfxGtm_Atom_Ch_clearZeroNotification(driver->atom, driver->timerChannel);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_Timer_acknowledgeTriggerIrq(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
boolean event;
|
||||
event = IfxGtm_Atom_Ch_isOneNotification(driver->atom, driver->triggerChannel);
|
||||
|
||||
if (event)
|
||||
{
|
||||
IfxGtm_Atom_Ch_clearOneNotification(driver->atom, driver->triggerChannel);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Timer_addToChannelMask(IfxGtm_Atom_Timer *driver, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
driver->channelsMask |= 1 << channel;
|
||||
driver->agcDisableUpdate = IfxGtm_Atom_Agc_buildFeature(0, driver->channelsMask, IFX_GTM_ATOM_AGC_GLB_CTRL_UPEN_CTRL0_OFF);
|
||||
driver->agcApplyUpdate = IfxGtm_Atom_Agc_buildFeature(driver->channelsMask, 0, IFX_GTM_ATOM_AGC_GLB_CTRL_UPEN_CTRL0_OFF);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Timer_applyUpdate(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
IfxGtm_Atom_Agc_setChannelsUpdate(driver->agc, driver->agcApplyUpdate);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Timer_disableUpdate(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
IfxGtm_Atom_Agc_setChannelsUpdate(driver->agc, driver->agcDisableUpdate);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Atom_Timer_getFrequency(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
return 1.0 / IfxStdIf_Timer_tickToS(driver->base.clockFreq, driver->base.period);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Atom_Timer_getInputFrequency(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
return driver->base.clockFreq;
|
||||
}
|
||||
|
||||
|
||||
Ifx_TimerValue IfxGtm_Atom_Timer_getOffset(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
return driver->offset;
|
||||
}
|
||||
|
||||
|
||||
Ifx_TimerValue IfxGtm_Atom_Timer_getPeriod(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
return driver->base.period;
|
||||
}
|
||||
|
||||
|
||||
volatile uint32 *IfxGtm_Atom_Timer_getPointer(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
return IfxGtm_Atom_Ch_getTimerPointer(driver->atom, driver->timerChannel);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Atom_Timer_getResolution(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
return 1.0 / driver->base.clockFreq;
|
||||
}
|
||||
|
||||
|
||||
Ifx_TimerValue IfxGtm_Atom_Timer_getTrigger(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
return IfxGtm_Atom_Ch_getCompareOne(driver->atom, driver->triggerChannel) - 1;
|
||||
}
|
||||
|
||||
|
||||
volatile uint32 *IfxGtm_Atom_Timer_getTriggerPointer(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
return IfxGtm_Atom_Ch_getCompareOnePointer(driver->atom, driver->triggerChannel);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_Timer_init(IfxGtm_Atom_Timer *driver, const IfxGtm_Atom_Timer_Config *config)
|
||||
{
|
||||
boolean result = TRUE;
|
||||
IfxGtm_Atom_Timer_Base *base = &driver->base;
|
||||
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, config->base.countDir == IfxStdIf_Timer_CountDir_up); /* only this mode is supported */
|
||||
|
||||
driver->gtm = config->gtm;
|
||||
driver->atomIndex = config->atom;
|
||||
driver->atom = &config->gtm->ATOM[config->atom];
|
||||
driver->timerChannel = config->timerChannel;
|
||||
|
||||
base->triggerEnabled = config->base.trigger.enabled;
|
||||
|
||||
if (base->triggerEnabled)
|
||||
{
|
||||
if (config->triggerOut != NULL_PTR)
|
||||
{
|
||||
driver->triggerChannel = config->triggerOut->channel;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = FALSE;
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, result); /* triggerOut is required */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
driver->triggerChannel = driver->timerChannel; // Set to timer channel to disable its use
|
||||
}
|
||||
|
||||
driver->agc = (Ifx_GTM_ATOM_AGC *)&driver->atom->AGC.GLB_CTRL;
|
||||
|
||||
driver->channelsMask = 0;
|
||||
driver->agcApplyUpdate = 0;
|
||||
driver->agcDisableUpdate = 0;
|
||||
|
||||
/* Initialize the timer part */
|
||||
IfxGtm_Atom_Ch_configurePwmMode(driver->atom, driver->timerChannel, config->clock,
|
||||
(Ifx_ActiveState)config->base.trigger.risingEdgeAtPeriod, IfxGtm_Atom_Ch_ResetEvent_onCm0,
|
||||
IfxGtm_Atom_Ch_OutputTrigger_generate);
|
||||
|
||||
IfxGtm_Atom_Timer_updateInputFrequency(driver);
|
||||
|
||||
if ((config->base.minResolution > 0) && ((1.0 / base->clockFreq) > config->base.minResolution))
|
||||
{
|
||||
result = FALSE;
|
||||
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, FALSE);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
IfxGtm_Atom_Timer_setFrequency(driver, config->base.frequency);
|
||||
driver->offset = IfxStdIf_Timer_sToTick(driver->base.clockFreq, 1.0 / config->base.frequency * config->base.startOffset);
|
||||
|
||||
IfxGtm_Atom_Ch_setCounterValue(driver->atom, driver->timerChannel, driver->offset);
|
||||
|
||||
/* Initialize the trigger part */
|
||||
IfxGtm_Atom_Timer_addToChannelMask(driver, driver->timerChannel);
|
||||
|
||||
if (base->triggerEnabled)
|
||||
{
|
||||
IfxGtm_Atom_Ch triggerChannel = driver->triggerChannel;
|
||||
uint16 triggerChannelMask = 1 << triggerChannel;
|
||||
|
||||
IfxGtm_Atom_Ch_setSignalLevel(driver->atom, triggerChannel, config->base.trigger.risingEdgeAtPeriod ? Ifx_ActiveState_high : Ifx_ActiveState_low);
|
||||
|
||||
IfxGtm_Atom_Ch_setCounterValue(driver->atom, triggerChannel, driver->offset);
|
||||
|
||||
if (triggerChannel != driver->timerChannel)
|
||||
{
|
||||
IfxGtm_Atom_Ch_configurePwmMode(driver->atom, triggerChannel, config->clock,
|
||||
(Ifx_ActiveState)config->base.trigger.risingEdgeAtPeriod, IfxGtm_Atom_Ch_ResetEvent_onTrigger,
|
||||
IfxGtm_Atom_Ch_OutputTrigger_forward);
|
||||
IfxGtm_Atom_Agc_enableChannels(driver->agc, triggerChannelMask, 0, FALSE);
|
||||
IfxGtm_Atom_Timer_addToChannelMask(driver, driver->triggerChannel);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
/* Signal must go out of the GTM even if the port outpout is not enabled */
|
||||
IfxGtm_Atom_Agc_enableChannelsOutput(driver->agc, triggerChannelMask, 0, FALSE);
|
||||
|
||||
if ((config->base.trigger.outputEnabled) && (config->initPins == TRUE))
|
||||
{
|
||||
/* Initialize the port */
|
||||
IfxGtm_PinMap_setAtomTout(config->triggerOut, config->base.trigger.outputMode, config->base.trigger.outputDriver);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
IfxGtm_Atom_Timer_setTrigger(driver, config->base.trigger.triggerPoint);
|
||||
}
|
||||
else
|
||||
{}
|
||||
|
||||
/* Interrupt configuration */
|
||||
{
|
||||
volatile Ifx_SRC_SRCR *src;
|
||||
boolean timerHasIrq = config->base.isrPriority > 0;
|
||||
boolean triggerHasIrq = (config->base.trigger.isrPriority > 0) && base->triggerEnabled;
|
||||
|
||||
if (driver->triggerChannel == driver->timerChannel)
|
||||
{
|
||||
IfxGtm_Atom_Ch_setNotification(driver->atom, driver->timerChannel, timerHasIrq ? config->irqModeTimer : config->irqModeTrigger, timerHasIrq, triggerHasIrq);
|
||||
src = IfxGtm_Atom_Ch_getSrcPointer(driver->gtm, config->atom, driver->timerChannel);
|
||||
IfxSrc_init(src, timerHasIrq ? config->base.isrProvider : config->base.trigger.isrProvider, timerHasIrq ? config->base.isrPriority : config->base.trigger.isrPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
else
|
||||
{
|
||||
IfxGtm_IrqMode irqMode = IfxGtm_IrqMode_pulseNotify;
|
||||
|
||||
if (timerHasIrq)
|
||||
{
|
||||
IfxGtm_Atom_Ch_setNotification(driver->atom, driver->timerChannel, irqMode, TRUE, FALSE);
|
||||
src = IfxGtm_Atom_Ch_getSrcPointer(driver->gtm, config->atom, driver->timerChannel);
|
||||
IfxSrc_init(src, config->base.isrProvider, config->base.isrPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
|
||||
if (triggerHasIrq)
|
||||
{
|
||||
IfxGtm_Atom_Ch_setNotification(driver->atom, driver->triggerChannel, irqMode, FALSE, TRUE);
|
||||
src = IfxGtm_Atom_Ch_getSrcPointer(driver->gtm, config->atom, driver->triggerChannel);
|
||||
IfxSrc_init(src, config->base.trigger.isrProvider, config->base.trigger.isrPriority);
|
||||
IfxSrc_enable(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer the shadow registers */
|
||||
IfxGtm_Atom_Agc_setChannelsForceUpdate(driver->agc, driver->channelsMask, 0, 0, 0);
|
||||
IfxGtm_Atom_Agc_trigger(driver->agc);
|
||||
IfxGtm_Atom_Agc_setChannelsForceUpdate(driver->agc, 0, driver->channelsMask, 0, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Timer_initConfig(IfxGtm_Atom_Timer_Config *config, Ifx_GTM *gtm)
|
||||
{
|
||||
IfxStdIf_Timer_initConfig(&config->base);
|
||||
config->gtm = gtm;
|
||||
config->atom = IfxGtm_Atom_0;
|
||||
config->timerChannel = IfxGtm_Atom_Ch_0;
|
||||
config->triggerOut = NULL_PTR;
|
||||
config->clock = IfxGtm_Cmu_Clk_0;
|
||||
config->base.countDir = IfxStdIf_Timer_CountDir_up;
|
||||
config->irqModeTimer = IfxGtm_IrqMode_level;
|
||||
config->irqModeTrigger = IfxGtm_IrqMode_level;
|
||||
config->initPins = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Timer_run(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
IfxGtm_Atom_Agc_enableChannels(driver->agc, driver->channelsMask, 0, TRUE);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_Timer_setFrequency(IfxGtm_Atom_Timer *driver, float32 frequency)
|
||||
{
|
||||
Ifx_TimerValue period = IfxStdIf_Timer_sToTick(driver->base.clockFreq, 1.0 / frequency);
|
||||
|
||||
return IfxGtm_Atom_Timer_setPeriod(driver, period);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_Timer_setPeriod(IfxGtm_Atom_Timer *driver, Ifx_TimerValue period)
|
||||
{
|
||||
driver->base.period = period;
|
||||
IfxGtm_Atom_Ch_setCompareZeroShadow(driver->atom, driver->timerChannel, period);
|
||||
|
||||
if (driver->triggerChannel != driver->timerChannel)
|
||||
{
|
||||
IfxGtm_Atom_Ch_setCompareZeroShadow(driver->atom, driver->triggerChannel, period);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Timer_setSingleMode(IfxGtm_Atom_Timer *driver, boolean enabled)
|
||||
{
|
||||
IfxGtm_Atom_Ch_setOneShotMode(driver->atom, driver->timerChannel, enabled);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Timer_setTrigger(IfxGtm_Atom_Timer *driver, Ifx_TimerValue triggerPoint)
|
||||
{
|
||||
IfxGtm_Atom_Ch_setCompareOneShadow(driver->atom, driver->triggerChannel, triggerPoint + 1);
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_Timer_stdIfTimerInit(IfxStdIf_Timer *stdif, IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
/* Ensure the stdif is reset to zeros */
|
||||
memset(stdif, 0, sizeof(IfxStdIf_Timer));
|
||||
|
||||
/* *INDENT-OFF* Note: this file was indented manually by the author. */
|
||||
/* Set the API link */
|
||||
stdif->driver = driver;
|
||||
stdif->getFrequency =(IfxStdIf_Timer_GetFrequency )&IfxGtm_Atom_Timer_getFrequency;
|
||||
stdif->getPeriod =(IfxStdIf_Timer_GetPeriod )&IfxGtm_Atom_Timer_getPeriod;
|
||||
stdif->getResolution =(IfxStdIf_Timer_GetResolution )&IfxGtm_Atom_Timer_getResolution;
|
||||
stdif->getTrigger =(IfxStdIf_Timer_GetTrigger )&IfxGtm_Atom_Timer_getTrigger;
|
||||
stdif->setFrequency =(IfxStdIf_Timer_SetFrequency )&IfxGtm_Atom_Timer_setFrequency;
|
||||
stdif->updateInputFrequency =(IfxStdIf_Timer_UpdateInputFrequency)&IfxGtm_Atom_Timer_updateInputFrequency;
|
||||
stdif->applyUpdate =(IfxStdIf_Timer_ApplyUpdate )&IfxGtm_Atom_Timer_applyUpdate;
|
||||
stdif->disableUpdate =(IfxStdIf_Timer_DisableUpdate )&IfxGtm_Atom_Timer_disableUpdate;
|
||||
stdif->getInputFrequency =(IfxStdIf_Timer_GetInputFrequency )&IfxGtm_Atom_Timer_getInputFrequency;
|
||||
stdif->run =(IfxStdIf_Timer_Run )&IfxGtm_Atom_Timer_run;
|
||||
stdif->setPeriod =(IfxStdIf_Timer_SetPeriod )&IfxGtm_Atom_Timer_setPeriod;
|
||||
stdif->setSingleMode =(IfxStdIf_Timer_SetSingleMode )&IfxGtm_Atom_Timer_setSingleMode;
|
||||
stdif->setTrigger =(IfxStdIf_Timer_SetTrigger )&IfxGtm_Atom_Timer_setTrigger;
|
||||
stdif->stop =(IfxStdIf_Timer_Stop )&IfxGtm_Atom_Timer_stop;
|
||||
stdif->ackTimerIrq =(IfxStdIf_Timer_AckTimerIrq )&IfxGtm_Atom_Timer_acknowledgeTimerIrq;
|
||||
stdif->ackTriggerIrq =(IfxStdIf_Timer_AckTriggerIrq )&IfxGtm_Atom_Timer_acknowledgeTriggerIrq;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Timer_stop(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
IfxGtm_Atom_Agc_enableChannels(driver->agc, 0, driver->channelsMask, TRUE);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Timer_updateInputFrequency(IfxGtm_Atom_Timer *driver)
|
||||
{
|
||||
driver->base.clockFreq = IfxGtm_Atom_Ch_getClockFrequency(driver->gtm, driver->atom, driver->timerChannel);
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
/**
|
||||
* \file IfxGtm_Atom_Timer.h
|
||||
* \brief GTM TIMER details
|
||||
* \ingroup IfxLld_Gtm
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Atom_Timer_Usage How to use the GTM ATOM Timer Driver
|
||||
* \ingroup IfxLld_Gtm_Atom_Timer
|
||||
*
|
||||
* This driver implements the timer functionalities as defined by \ref library_srvsw_stdif_timer.
|
||||
* The user is free to use either the driver specific APIs below or to used the \ref library_srvsw_stdif_timer "standard interface APIs".
|
||||
*
|
||||
* \section Specific Specific implementation
|
||||
* Implementation is similar to \ref IfxLld_Gtm_Tom_Timer.
|
||||
*
|
||||
* \todo Add documentation
|
||||
*
|
||||
* For a detailed configuration of the microcontroller, see \ref IfxGtm_Atom_Timer_init().
|
||||
*
|
||||
* \section Example Usage example
|
||||
* Initialisation:
|
||||
* \code
|
||||
* IfxGtm_Atom_Timer_Config driverConfig;
|
||||
* IfxGtm_Atom_Timer driverData;
|
||||
* IfxStdIf_Timer timer;
|
||||
* IfxGtm_Atom_Timer_initConfig(&driverConfig, &MODULE_GTM);
|
||||
* IfxGtm_Atom_Timer_init (&driverData, &driverConfig);
|
||||
* boolean IfxGtm_Atom_Timer_stdIfTimerInit(&timer, &driverData);
|
||||
* \endcode
|
||||
*
|
||||
* During run-time, \ref library_srvsw_stdif_timer "the interface functions" should be used:
|
||||
* \code
|
||||
* IfxStdIf_Timer_run(timer);
|
||||
* IfxStdIf_Timer_disableUpdate(timer);
|
||||
* IfxStdIf_Timer_setPeriod(timer, period);
|
||||
* IfxStdIf_Timer_applyUpdate(timer);
|
||||
* \endcode
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Atom_Timer ATOM Timer Interface Driver
|
||||
* \ingroup IfxLld_Gtm_Atom
|
||||
* \defgroup IfxLld_Gtm_Atom_Timer_Timer_StdIf_Functions Timer StdIf Functions
|
||||
* \ingroup IfxLld_Gtm_Atom_Timer
|
||||
* \defgroup IfxLld_Gtm_Atom_Timer_Timer_Functions Timer Functions
|
||||
* \ingroup IfxLld_Gtm_Atom_Timer
|
||||
* \defgroup IfxLld_Gtm_Atom_Timer_Data_Structures Data Structures
|
||||
* \ingroup IfxLld_Gtm_Atom_Timer
|
||||
*/
|
||||
|
||||
#ifndef IFXGTM_ATOM_TIMER_H
|
||||
#define IFXGTM_ATOM_TIMER_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_PinMap/IfxGtm_PinMap.h"
|
||||
#include "Gtm/Std/IfxGtm_Atom.h"
|
||||
#include "Gtm/Std/IfxGtm_Cmu.h"
|
||||
#include "StdIf/IfxStdIf_Timer.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-----------------------------Data Structures--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_Timer_Data_Structures
|
||||
* \{ */
|
||||
/** \brief Structure for the timer base
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Ifx_TimerValue period; /**< \brief Timer period in ticks (cached value) */
|
||||
boolean triggerEnabled; /**< \brief If TRUE, the trigger functionality is Initialised */
|
||||
float32 clockFreq; /**< \brief Timer input clock frequency (cached value) */
|
||||
IfxStdIf_Timer_CountDir countDir; /**< \brief Timer counting mode */
|
||||
} IfxGtm_Atom_Timer_Base;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_Timer_Data_Structures
|
||||
* \{ */
|
||||
/** \brief TOM Timer interface
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxGtm_Atom_Timer_Base base; /**< \brief Timer base structure */
|
||||
Ifx_GTM *gtm; /**< \brief GTM module used for the timer functionality */
|
||||
Ifx_GTM_ATOM *atom; /**< \brief ATOM used for the timer functionality */
|
||||
Ifx_GTM_ATOM_AGC *agc; /**< \brief Pointer to the AGC object */
|
||||
IfxGtm_Atom atomIndex; /**< \brief Enum for ATOM objects */
|
||||
IfxGtm_Atom_Ch timerChannel; /**< \brief ATOM channel used for the timer */
|
||||
IfxGtm_Atom_Ch triggerChannel; /**< \brief ATOM channel used for the trigger, if identical to the timerChannel, the trigger interrupt is having the same interrupt level as the timer interrupt */
|
||||
uint16 channelsMask; /**< \brief Mask for channels to be modified together */
|
||||
Ifx_TimerValue offset; /**< \brief Timer initial offset in ticks */
|
||||
uint32 agcDisableUpdate; /**< \brief AGC value for disable update */
|
||||
uint32 agcApplyUpdate; /**< \brief AGC value for apply update */
|
||||
} IfxGtm_Atom_Timer;
|
||||
|
||||
/** \brief Configuration structure for TOM Timer
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IfxStdIf_Timer_Config base; /**< \brief Standard interface timer configuration */
|
||||
Ifx_GTM *gtm; /**< \brief GTM used for the timer functionality */
|
||||
IfxGtm_Atom atom; /**< \brief ATOM used for the timer functionality */
|
||||
IfxGtm_Atom_Ch timerChannel; /**< \brief ATOM channel used for the timer */
|
||||
IfxGtm_Atom_ToutMap *triggerOut; /**< \brief ATOM channel used for the trigger output, can be identical to the timer channe */
|
||||
IfxGtm_Cmu_Clk clock; /**< \brief Timer input clock */
|
||||
IfxGtm_IrqMode irqModeTimer; /**< \brief Interrupt mode for the timer */
|
||||
IfxGtm_IrqMode irqModeTrigger; /**< \brief Interrupt mode for the trigger */
|
||||
boolean initPins; /**< \brief TRUE: Initialize pins in driver
|
||||
* FALSE: Don't initialize pins in driver : user handles separately */
|
||||
} IfxGtm_Atom_Timer_Config;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_Timer_Timer_StdIf_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the timer event
|
||||
* \see IfxStdIf_Timer_AckTimerIrq
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Timer event
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Timer_acknowledgeTimerIrq(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Returns the trigger event
|
||||
* \see IfxStdIf_Timer_AckTriggerIrq
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Trigger event
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Timer_acknowledgeTriggerIrq(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Add a channel to the channel mask
|
||||
* Channels present in the mask are started, stopped, updated at the same time as the timer:
|
||||
* IfxGtm_Atom_Timer_applyUpdate, IfxGtm_Atom_Timer_disableUpdate, IfxGtm_Atom_Timer_stop, IfxGtm_Atom_Timer_run
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \param channel Channel to ba added to the mask
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Timer_addToChannelMask(IfxGtm_Atom_Timer *driver, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Enables the transfer of the shadow registers
|
||||
* \see IfxStdIf_Timer_ApplyUpdate
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Timer_applyUpdate(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Disables the upadte
|
||||
* \see IfxStdIf_Timer_DisableUpdate
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Timer_disableUpdate(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Returns the frequency
|
||||
* \see IfxStdIf_Timer_GetFrequency
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Frequency
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Atom_Timer_getFrequency(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Returns the Input frequncy
|
||||
* \see IfxStdIf_Timer_GetInputFrequency
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Frequency
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Atom_Timer_getInputFrequency(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Returns the period of the timer
|
||||
* \see IfxStdIf_Timer_GetPeriod
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Period
|
||||
*/
|
||||
IFX_EXTERN Ifx_TimerValue IfxGtm_Atom_Timer_getPeriod(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Returns the resolution
|
||||
* \see IfxStdIf_Timer_GetResolution
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Resolution
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Atom_Timer_getResolution(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Returns the trigger point
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Trigger point
|
||||
*/
|
||||
IFX_EXTERN Ifx_TimerValue IfxGtm_Atom_Timer_getTrigger(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Runs the timer
|
||||
* \see IfxStdIf_Timer_Run
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Timer_run(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Sets the frequency
|
||||
* \see IfxStdIf_Timer_SetFrequency
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \param frequency Frequency
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Timer_setFrequency(IfxGtm_Atom_Timer *driver, float32 frequency);
|
||||
|
||||
/** \brief Sets the period for the timer
|
||||
* \see IfxStdIf_Timer_SetPeriod
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \param period Period value
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Timer_setPeriod(IfxGtm_Atom_Timer *driver, Ifx_TimerValue period);
|
||||
|
||||
/** \brief Sets the single shot mode of the timer
|
||||
* \see IfxStdIf_Timer_SetSingleMode
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \param enabled If TRUE, sets the single shot mode
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Timer_setSingleMode(IfxGtm_Atom_Timer *driver, boolean enabled);
|
||||
|
||||
/** \brief Sets the trigger
|
||||
* \see IfxStdIf_Timer_SetTrigger
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \param triggerPoint Trigger point value
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Timer_setTrigger(IfxGtm_Atom_Timer *driver, Ifx_TimerValue triggerPoint);
|
||||
|
||||
/** \brief Initializes the standard interface timer
|
||||
* \param stdif Standard interface object, will be initialized by the function
|
||||
* \param driver Interface driver to be used by the standard interface. must be initialised separately
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Timer_stdIfTimerInit(IfxStdIf_Timer *stdif, IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Stops the timer
|
||||
* \see IfxStdIf_Timer_Stop
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Timer_stop(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Updates the input frequency
|
||||
* \see IfxStdIf_Timer_UpdateInputFrequency
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Timer_updateInputFrequency(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Atom_Timer_Timer_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the initial timer offset in ticks
|
||||
* \see IfxStdIf_Timer_GetOffset
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Returns the initial timer offset in ticks
|
||||
*/
|
||||
IFX_EXTERN Ifx_TimerValue IfxGtm_Atom_Timer_getOffset(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Returns the pointer to timer channel
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Pointer
|
||||
*/
|
||||
IFX_EXTERN volatile uint32 *IfxGtm_Atom_Timer_getPointer(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Returns the pointer to trigger channel
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \return Pointer
|
||||
*/
|
||||
IFX_EXTERN volatile uint32 *IfxGtm_Atom_Timer_getTriggerPointer(IfxGtm_Atom_Timer *driver);
|
||||
|
||||
/** \brief Initialises the timer object
|
||||
* \param driver ATOM Timer interface Handle
|
||||
* \param config Configuration structure for ATOM Timer
|
||||
* \return TRUE on success else FALSE
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Timer_init(IfxGtm_Atom_Timer *driver, const IfxGtm_Atom_Timer_Config *config);
|
||||
|
||||
/** \brief Initializes the configuration structure to default
|
||||
* \param config Configuration structure for ATOM Timer
|
||||
* \param gtm Pointer to GTM module
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Timer_initConfig(IfxGtm_Atom_Timer_Config *config, Ifx_GTM *gtm);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXGTM_ATOM_TIMER_H */
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* \file IfxGtm.c
|
||||
* \brief GTM basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGtm.h"
|
||||
#include "Scu/Std/IfxScuWdt.h"
|
||||
#include "Scu/Std/IfxScuCcu.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxGtm_disable(Ifx_GTM *gtm)
|
||||
{
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(psw);
|
||||
gtm->CLC.B.DISR = 1;
|
||||
IfxScuWdt_setCpuEndinit(psw);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_enable(Ifx_GTM *gtm)
|
||||
{
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
|
||||
IfxScuWdt_clearCpuEndinit(psw);
|
||||
gtm->CLC.B.DISR = 0;
|
||||
IfxScuWdt_setCpuEndinit(psw);
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_getSysClkFrequency(void)
|
||||
{
|
||||
return IfxScuCcu_getGtmFrequency();
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* \file IfxGtm.h
|
||||
* \brief GTM basic functionality
|
||||
* \ingroup IfxLld_Gtm
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Std_Basic_Functions Basic Functions
|
||||
* \ingroup IfxLld_Gtm_Std
|
||||
* \defgroup IfxLld_Gtm_Std_Enumerations Enumerations
|
||||
* \ingroup IfxLld_Gtm_Std
|
||||
*/
|
||||
|
||||
#ifndef IFXGTM_H
|
||||
#define IFXGTM_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxGtm_cfg.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Std_Enumerations
|
||||
* \{ */
|
||||
/** \brief Enum for GTM interrupt modes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_IrqMode_level = 0,
|
||||
IfxGtm_IrqMode_pulse = 1,
|
||||
IfxGtm_IrqMode_pulseNotify = 2,
|
||||
IfxGtm_IrqMode_singlePulse = 3
|
||||
} IfxGtm_IrqMode;
|
||||
|
||||
/** \brief OCDS Suspend Control (OCDS.SUS)
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_SuspendMode_none = 0, /**< \brief No suspend */
|
||||
IfxGtm_SuspendMode_hard = 1, /**< \brief Hard Suspend */
|
||||
IfxGtm_SuspendMode_soft = 2 /**< \brief Soft Suspend */
|
||||
} IfxGtm_SuspendMode;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Std_Basic_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returs the status of module enabled or disabled
|
||||
* \param gtm Pointer to GTM module
|
||||
* \return status: TRUE/FALSE
|
||||
*/
|
||||
IFX_INLINE boolean IfxGtm_isEnabled(Ifx_GTM *gtm);
|
||||
|
||||
/** \brief Returns the module's suspend state.
|
||||
* TRUE :if module is suspended.
|
||||
* FALSE:if module is not yet suspended.
|
||||
* \param gtm Pointer to GTM module registers
|
||||
* \return Suspend status (TRUE / FALSE)
|
||||
*/
|
||||
IFX_INLINE boolean IfxGtm_isModuleSuspended(Ifx_GTM *gtm);
|
||||
|
||||
/** \brief Configure the Module to Hard/Soft suspend mode.
|
||||
* Note: The api works only when the OCDS is enabled and in Supervisor Mode. When OCDS is disabled the OCS suspend control is ineffective.
|
||||
* \param gtm Pointer to GTM module registers
|
||||
* \param mode Module suspend mode
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxGtm_setSuspendMode(Ifx_GTM *gtm, IfxGtm_SuspendMode mode);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Disables the module
|
||||
* \param gtm Pointer to GTM module
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_disable(Ifx_GTM *gtm);
|
||||
|
||||
/** \brief Enables the module
|
||||
* \param gtm Pointer to GTM module
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_enable(Ifx_GTM *gtm);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief returns the GTM SYSCLK frequency.
|
||||
* Refer to the Clock distribution for details on GTM SYS CLK.
|
||||
* \return sysFreq
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_getSysClkFrequency(void);
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE boolean IfxGtm_isEnabled(Ifx_GTM *gtm)
|
||||
{
|
||||
return gtm->CLC.B.DISS == 0;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxGtm_isModuleSuspended(Ifx_GTM *gtm)
|
||||
{
|
||||
Ifx_GTM_OCS ocs;
|
||||
|
||||
// read the status
|
||||
ocs.U = gtm->OCS.U;
|
||||
|
||||
// return the status
|
||||
return ocs.B.SUSSTA;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxGtm_setSuspendMode(Ifx_GTM *gtm, IfxGtm_SuspendMode mode)
|
||||
{
|
||||
Ifx_GTM_OCS ocs;
|
||||
|
||||
// remove protection and configure the suspend mode.
|
||||
ocs.B.SUS_P = 1;
|
||||
ocs.B.SUS = mode;
|
||||
|
||||
gtm->OCS.U = ocs.U;
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXGTM_H */
|
||||
@@ -0,0 +1,567 @@
|
||||
/**
|
||||
* \file IfxGtm_Atom.c
|
||||
* \brief GTM basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGtm_Atom.h"
|
||||
#include "IfxGtm_bf.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Macros------------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Number of channels per ATOM AGC
|
||||
*/
|
||||
#define IFXGTM_ATOM_NUM_AGC_CHANNELS (8)
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
uint32 IfxGtm_Atom_Agc_buildFeature(uint16 enableMask, uint16 disableMask, uint8 bitfieldOffset)
|
||||
{
|
||||
uint8 i;
|
||||
uint32 reg = 0;
|
||||
uint32 mask = enableMask | (disableMask << 16);
|
||||
|
||||
for (i = 0; i < IFXGTM_ATOM_NUM_AGC_CHANNELS; i++)
|
||||
{
|
||||
/* Bitfield length is 2 bits */
|
||||
uint8 shift = (i * 2) + bitfieldOffset;
|
||||
|
||||
if (mask & 0x1)
|
||||
{
|
||||
reg |= IfxGtm_FeatureControl_enable << shift;
|
||||
}
|
||||
|
||||
if (mask & 0x10000)
|
||||
{
|
||||
reg |= IfxGtm_FeatureControl_disable << shift;
|
||||
}
|
||||
|
||||
mask = mask >> 1;
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxGtm_Atom_Agc_buildFeatureForChannel(IfxGtm_Atom_Ch channel, boolean enabled, uint8 bitfieldOffset)
|
||||
{
|
||||
uint32 reg = 0;
|
||||
|
||||
/* Bitfield length is 2 bits */
|
||||
uint8 shift = (((uint8)channel % 8) * 2) + bitfieldOffset;
|
||||
|
||||
if (enabled == 1)
|
||||
{
|
||||
reg = IfxGtm_FeatureControl_enable << shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg = IfxGtm_FeatureControl_disable << shift;
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_enableChannel(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Atom_Ch channel, boolean enabled, boolean immediate)
|
||||
{
|
||||
uint32 value;
|
||||
|
||||
value = IfxGtm_Atom_Agc_buildFeatureForChannel(channel, enabled, IFX_GTM_ATOM_AGC_ENDIS_CTRL_ENDIS_CTRL0_OFF);
|
||||
|
||||
if (immediate)
|
||||
{
|
||||
agc->ENDIS_CTRL.U = value;
|
||||
agc->ENDIS_STAT.U = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
agc->ENDIS_CTRL.U = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_enableChannelOutput(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Atom_Ch channel, boolean enabled, boolean immediate)
|
||||
{
|
||||
uint32 value;
|
||||
|
||||
value = IfxGtm_Atom_Agc_buildFeatureForChannel(channel, enabled, IFX_GTM_ATOM_AGC_OUTEN_CTRL_OUTEN_CTRL0_OFF);
|
||||
|
||||
if (immediate)
|
||||
{
|
||||
agc->OUTEN_CTRL.U = value;
|
||||
agc->OUTEN_STAT.U = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
agc->OUTEN_CTRL.U = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_enableChannelUpdate(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Atom_Ch channel, boolean enabled)
|
||||
{
|
||||
agc->GLB_CTRL.U = IfxGtm_Atom_Agc_buildFeatureForChannel(channel, enabled, IFX_GTM_ATOM_AGC_GLB_CTRL_UPEN_CTRL0_OFF);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_enableChannels(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask, boolean immediate)
|
||||
{
|
||||
uint32 value;
|
||||
|
||||
value = IfxGtm_Atom_Agc_buildFeature(enableMask, disableMask, IFX_GTM_ATOM_AGC_ENDIS_CTRL_ENDIS_CTRL0_OFF);
|
||||
|
||||
if (immediate)
|
||||
{
|
||||
agc->ENDIS_CTRL.U = value;
|
||||
agc->ENDIS_STAT.U = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
agc->ENDIS_CTRL.U = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_enableChannelsOutput(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask, boolean immediate)
|
||||
{
|
||||
uint32 value;
|
||||
|
||||
value = IfxGtm_Atom_Agc_buildFeature(enableMask, disableMask, IFX_GTM_ATOM_AGC_OUTEN_CTRL_OUTEN_CTRL0_OFF);
|
||||
|
||||
if (immediate)
|
||||
{
|
||||
agc->OUTEN_CTRL.U = value;
|
||||
agc->OUTEN_STAT.U = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
agc->OUTEN_CTRL.U = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_enableChannelsTrigger(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask)
|
||||
{
|
||||
agc->INT_TRIG.U = IfxGtm_Atom_Agc_buildFeature(enableMask, disableMask, IFX_GTM_ATOM_AGC_INT_TRIG_INT_TRIG0_OFF);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_enableChannelsUpdate(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask)
|
||||
{
|
||||
agc->GLB_CTRL.U = IfxGtm_Atom_Agc_buildFeature(enableMask, disableMask, IFX_GTM_ATOM_AGC_GLB_CTRL_UPEN_CTRL0_OFF);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_enableTimeTrigger(Ifx_GTM_ATOM_AGC *agc, boolean enabled)
|
||||
{
|
||||
agc->ACT_TB.B.TB_TRIG = enabled ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_resetChannels(Ifx_GTM_ATOM_AGC *agc, uint32 resetMask)
|
||||
{
|
||||
uint8 i;
|
||||
uint32 reg = 0;
|
||||
|
||||
for (i = 0; i < IFXGTM_ATOM_NUM_AGC_CHANNELS; i++)
|
||||
{
|
||||
if (resetMask & 0x1)
|
||||
{
|
||||
reg |= 1 << i;
|
||||
}
|
||||
|
||||
resetMask = resetMask >> 1;
|
||||
}
|
||||
|
||||
agc->GLB_CTRL.U = reg << IFX_GTM_ATOM_AGC_GLB_CTRL_RST_CH0_OFF;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_setChannelForceUpdate(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Atom_Ch channel, boolean enabled, boolean resetEnabled)
|
||||
{
|
||||
uint32 regEnable, regReset;
|
||||
|
||||
regEnable = IfxGtm_Atom_Agc_buildFeatureForChannel(channel, enabled, IFX_GTM_ATOM_AGC_FUPD_CTRL_FUPD_CTRL0_OFF);
|
||||
regReset = IfxGtm_Atom_Agc_buildFeatureForChannel(channel, resetEnabled, IFX_GTM_ATOM_AGC_FUPD_CTRL_RSTCN0_CH0_OFF);
|
||||
|
||||
agc->FUPD_CTRL.U = regEnable | (regReset << 16);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_setChannelsForceUpdate(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask, uint16 resetEnableMask, uint16 resetDisableMask)
|
||||
{
|
||||
uint32 regEnable, regReset;
|
||||
|
||||
regEnable = IfxGtm_Atom_Agc_buildFeature(enableMask, disableMask, IFX_GTM_ATOM_AGC_FUPD_CTRL_FUPD_CTRL0_OFF);
|
||||
regReset = IfxGtm_Atom_Agc_buildFeature(resetEnableMask, resetDisableMask, IFX_GTM_ATOM_AGC_FUPD_CTRL_RSTCN0_CH0_OFF);
|
||||
agc->FUPD_CTRL.U = regEnable | regReset;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_setTimeTrigger(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Tbu_Ts base, uint32 value)
|
||||
{
|
||||
Ifx_GTM_ATOM_AGC_ACT_TB act_tb;
|
||||
|
||||
act_tb.U = agc->ACT_TB.U;
|
||||
act_tb.B.TBU_SEL = base;
|
||||
act_tb.B.ACT_TB = value;
|
||||
agc->ACT_TB.U = act_tb.U;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Agc_trigger(Ifx_GTM_ATOM_AGC *agc)
|
||||
{
|
||||
agc->GLB_CTRL.U = 1 << IFX_GTM_ATOM_AGC_GLB_CTRL_HOST_TRIG_OFF;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_clearOneNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->IRQ_NOTIFY.B.CCU1TC = 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_clearZeroNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->IRQ_NOTIFY.B.CCU0TC = 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_configurePwmMode(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Cmu_Clk clock, Ifx_ActiveState activeState, IfxGtm_Atom_Ch_ResetEvent resetEvent, IfxGtm_Atom_Ch_OutputTrigger trigger)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
Ifx_GTM_ATOM_CH_CTRL ctrl;
|
||||
|
||||
ctrl.U = 0;
|
||||
ctrl.B.MODE = IfxGtm_Atom_Mode_outputPwm;
|
||||
|
||||
ctrl.B.CLK_SRC = clock;
|
||||
|
||||
ctrl.B.RST_CCU0 = resetEvent;
|
||||
ctrl.B.SL = (activeState == Ifx_ActiveState_high ? 1 : 0);
|
||||
ctrl.B.TRIGOUT = trigger;
|
||||
|
||||
atomCh->CTRL.U = ctrl.U;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Atom_Ch_getClockFrequency(Ifx_GTM *gtm, Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
IfxGtm_Cmu_Clk clock;
|
||||
|
||||
clock = IfxGtm_Atom_Ch_getClockSource(atom, channel);
|
||||
|
||||
return IfxGtm_Cmu_getClkFrequency(gtm, clock, TRUE);
|
||||
}
|
||||
|
||||
|
||||
IfxGtm_Cmu_Clk IfxGtm_Atom_Ch_getClockSource(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
IfxGtm_Cmu_Clk clock;
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
clock = (IfxGtm_Cmu_Clk)atomCh->CTRL.B.CLK_SRC;
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxGtm_Atom_Ch_getCompareOne(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
return atomCh->CM1.U;
|
||||
}
|
||||
|
||||
|
||||
volatile uint32 *IfxGtm_Atom_Ch_getCompareOnePointer(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
return (volatile uint32 *)&atomCh->CM1;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxGtm_Atom_Ch_getCompareZero(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
return atomCh->CM0.U;
|
||||
}
|
||||
|
||||
|
||||
volatile uint32 *IfxGtm_Atom_Ch_getCompareZeroPointer(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
return (volatile uint32 *)&atomCh->CM0;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_Ch_getOutputLevel(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
boolean result;
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
result = atomCh->STAT.B.OL == 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
volatile Ifx_SRC_SRCR *IfxGtm_Atom_Ch_getSrcPointer(Ifx_GTM *gtm, IfxGtm_Atom atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(gtm)
|
||||
return &MODULE_SRC.GTM.GTM[0].ATOM[atom][channel / 2];
|
||||
}
|
||||
|
||||
|
||||
volatile uint32 *IfxGtm_Atom_Ch_getTimerPointer(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
return (volatile uint32 *)((uint32)&(atom->CH0.CN0.U) + channel * (offsetof(Ifx_GTM_ATOM, CH1) - offsetof(Ifx_GTM_ATOM, CH0)));
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_Ch_isOneNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
boolean result;
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
result = atomCh->IRQ_NOTIFY.B.CCU1TC != 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Atom_Ch_isZeroNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
boolean result;
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
result = atomCh->IRQ_NOTIFY.B.CCU0TC != 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_raiseInterruptOne(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->IRQ_FORCINT.B.TRG_CCU1TC = 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_raiseInterruptZero(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->IRQ_FORCINT.B.TRG_CCU0TC = 1;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setClockSource(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Cmu_Clk clock)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CTRL.B.CLK_SRC = clock;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setCompare(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 compareZero, uint32 compareOne)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CM0.U = compareZero; // TK: replaced .B access to optimize runtime
|
||||
atomCh->CM1.U = compareOne;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setCompareOne(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 compareOne)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CM1.U = compareOne; // TK: replaced .B access to optimize runtime
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setCompareOneShadow(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 shadowOne)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->SR1.U = shadowOne; // TK: replaced .B access to optimize runtime
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setCompareZero(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 compareZero)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CM0.U = compareZero; // TK: replaced .B access to optimize runtime
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setCompareZeroShadow(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 shadowZero)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->SR0.U = shadowZero; // TK: replaced .B access to optimize runtime
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setCounterValue(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 value)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CN0.U = value; // TK: replaced .B access to optimize runtime
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setMode(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_Mode mode)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CTRL.B.MODE = mode;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_IrqMode mode, boolean interruptOnCompareZero, boolean interruptOnCompareOne)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
Ifx_GTM_ATOM_CH_IRQ_EN en;
|
||||
en.U = atomCh->IRQ_EN.U;
|
||||
|
||||
/* Disable all interrupts of the interrupt set to change mode */
|
||||
atomCh->IRQ_EN.U = IFX_ZEROS;
|
||||
atomCh->IRQ_MODE.B.IRQ_MODE = mode;
|
||||
atomCh->IRQ_EN.U = en.U; /* Set the values back */
|
||||
|
||||
en.B.CCU0TC_IRQ_EN = interruptOnCompareZero ? 1 : 0;
|
||||
en.B.CCU1TC_IRQ_EN = interruptOnCompareOne ? 1 : 0;
|
||||
atomCh->IRQ_EN.U = en.U;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setOneShotMode(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, boolean enabled)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CTRL.B.OSM = enabled ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setResetSource(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_Ch_ResetEvent event)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CTRL.B.RST_CCU0 = event;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setSignalLevel(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, Ifx_ActiveState activeState)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CTRL.B.SL = activeState == Ifx_ActiveState_high ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setTriggerOutput(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_Ch_OutputTrigger trigger)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CTRL.B.TRIGOUT = trigger;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setAruInput(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, boolean enabled)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->CTRL.B.ARU_EN = enabled;
|
||||
}
|
||||
|
||||
|
||||
uint32 IfxGtm_Atom_Ch_getCounterValue(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
return atomCh->CN0.U;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setSomcControl(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_SomcControl control)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->SOMC.B.ACB42 = control;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setSomcSignalLevelControl(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_SomcSignalLevelControl ctrl)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->SOMC.B.ACB10 = ctrl;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setAruReadAddress0(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 address)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
atomCh->RDADDR.B.RDADDR0 = address;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Atom_Ch_setAruReadAddress1(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 address)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
atomCh->RDADDR.B.RDADDR1 = address;
|
||||
}
|
||||
@@ -0,0 +1,609 @@
|
||||
/**
|
||||
* \file IfxGtm_Atom.h
|
||||
* \brief GTM basic functionality
|
||||
* \ingroup IfxLld_Gtm
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Std_Atom Atom Basic Functionality
|
||||
* \ingroup IfxLld_Gtm_Std
|
||||
* \defgroup IfxLld_Gtm_Std_Atom_Enumerations ATOM Enumerations
|
||||
* \ingroup IfxLld_Gtm_Std_Atom
|
||||
* \defgroup IfxLld_Gtm_Std_Atom_Channel_Functions ATOM Channel Functions
|
||||
* \ingroup IfxLld_Gtm_Std_Atom
|
||||
* \defgroup IfxLld_Gtm_Std_Atom_AGC_Functions ATOM AGC Functions
|
||||
* \ingroup IfxLld_Gtm_Std_Atom
|
||||
*/
|
||||
|
||||
#ifndef IFXGTM_ATOM_H
|
||||
#define IFXGTM_ATOM_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxGtm_cfg.h"
|
||||
#include "IfxGtm.h"
|
||||
#include "IfxGtm_Tbu.h"
|
||||
#include "Src/Std/IfxSrc.h"
|
||||
#include "IfxGtm_Cmu.h"
|
||||
#include "stddef.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Std_Atom_Enumerations
|
||||
* \{ */
|
||||
/** \brief Reset source for channel counter CN0
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Atom_Ch_OutputTrigger_forward = 0, /**< \brief Forward the trigger from the previous channel */
|
||||
IfxGtm_Atom_Ch_OutputTrigger_generate = 1 /**< \brief Generate the trigger from the current channel */
|
||||
} IfxGtm_Atom_Ch_OutputTrigger;
|
||||
|
||||
/** \brief Reset event for channel counter CN0
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Atom_Ch_ResetEvent_onCm0 = 0,
|
||||
IfxGtm_Atom_Ch_ResetEvent_onTrigger = 1
|
||||
} IfxGtm_Atom_Ch_ResetEvent;
|
||||
|
||||
/** \brief Enum for ATOM mode
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Atom_Mode_outputImmediate,
|
||||
IfxGtm_Atom_Mode_outputCompare,
|
||||
IfxGtm_Atom_Mode_outputPwm,
|
||||
IfxGtm_Atom_Mode_outputSerial
|
||||
} IfxGtm_Atom_Mode;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \brief Enable/disable of Aru Input to ATOM channel
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Atom_AruInput_disabled = 0, /**< \brief ARU input disabled */
|
||||
IfxGtm_Atom_AruInput_enabled = 1 /**< \brief ARU input enabled */
|
||||
} IfxGtm_Atom_AruInput;
|
||||
|
||||
/** \brief Match Compare control modes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Atom_SomcControl_compareBoth = 0, /**< \brief compare CCU0 and CCU1 in parallel */
|
||||
IfxGtm_Atom_SomcControl_compareBoth1 = 1, /**< \brief compare CCU0 and CCU1 in parallel */
|
||||
IfxGtm_Atom_SomcControl_ccu0Ts0 = 2, /**< \brief compare CCU0 against TS0 */
|
||||
IfxGtm_Atom_SomcControl_ccu1Ts12 = 3, /**< \brief compare only CCU1 against TS1 or TS2 */
|
||||
IfxGtm_Atom_SomcControl_ccu0ccu1Ts0 = 4, /**< \brief compare CCU0 then CCU1, use TS0 */
|
||||
IfxGtm_Atom_SomcControl_ccu0ccu1Ts12 = 5, /**< \brief compare CCU0 then CCU1. Use TS1 or TS2 */
|
||||
IfxGtm_Atom_SomcControl_ccu0Ts0ccu1Ts12 = 6, /**< \brief compare CCU0 with TS0 then CCU1 with TS1 or TS2 */
|
||||
IfxGtm_Atom_SomcControl_cancelCompare = 7 /**< \brief Cancel pending compare events */
|
||||
} IfxGtm_Atom_SomcControl;
|
||||
|
||||
/** \brief SOMC signal level Control
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Atom_SomcSignalLevelControl_noChange = 0, /**< \brief no signal level change at output */
|
||||
IfxGtm_Atom_SomcSignalLevelControl_sl0out1 = 1, /**< \brief SL= 0 -> Out=1; SL=1->Out=0 */
|
||||
IfxGtm_Atom_SomcSignalLevelControl_sl0out0 = 2, /**< \brief SL=0->Out=0; SL=1->Out=1 */
|
||||
IfxGtm_Atom_SomcSignalLevelControl_toggle = 3 /**< \brief toggle the output signal level */
|
||||
} IfxGtm_Atom_SomcSignalLevelControl;
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Std_Atom_Channel_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the base addredd of selected Atom channel
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return Pointer to channel base address
|
||||
*/
|
||||
IFX_INLINE Ifx_GTM_ATOM_CH *IfxGtm_Atom_Ch_getChannelPointer(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Sets the compare 0 and 1 shadow values
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param shadowZero Compare zero shadow value
|
||||
* \param shadowOne Compare one shadow value
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxGtm_Atom_Ch_setCompareShadow(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 shadowZero, uint32 shadowOne);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Clears the channel One notification
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_clearOneNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Clears the channel Zero notification
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_clearZeroNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param clock Clock source
|
||||
* \param activeState Active State
|
||||
* \param resetEvent Channel reset event
|
||||
* \param trigger Channel trigger output mode
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_configurePwmMode(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Cmu_Clk clock, Ifx_ActiveState activeState, IfxGtm_Atom_Ch_ResetEvent resetEvent, IfxGtm_Atom_Ch_OutputTrigger trigger);
|
||||
|
||||
/** \brief Returns the ATOM channel input clock frequency in Hz
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return ATOM channel input clock frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Atom_Ch_getClockFrequency(Ifx_GTM *gtm, Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Returns the channel clock source
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return The clock source
|
||||
*/
|
||||
IFX_EXTERN IfxGtm_Cmu_Clk IfxGtm_Atom_Ch_getClockSource(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Returns the compare one value
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return compare one value
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxGtm_Atom_Ch_getCompareOne(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Returns the compare one pointer
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return compare one pointer
|
||||
*/
|
||||
IFX_EXTERN volatile uint32 *IfxGtm_Atom_Ch_getCompareOnePointer(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Returns the compare zero value
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return compare zero value
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxGtm_Atom_Ch_getCompareZero(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Returns the compare zero pointer
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return compare zero pointer
|
||||
*/
|
||||
IFX_EXTERN volatile uint32 *IfxGtm_Atom_Ch_getCompareZeroPointer(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Gets the ATOM output level
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return TRUE the output is high, FALSE the output is low
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Ch_getOutputLevel(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Returns a pointer to the ATOM channel SRC
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param atom Specifies the atom object
|
||||
* \param channel Channel index
|
||||
* \return Pointer to the TOM channel SRC
|
||||
*/
|
||||
IFX_EXTERN volatile Ifx_SRC_SRCR *IfxGtm_Atom_Ch_getSrcPointer(Ifx_GTM *gtm, IfxGtm_Atom atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Returns the Timer pointer
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return Timer pointer
|
||||
*/
|
||||
IFX_EXTERN volatile uint32 *IfxGtm_Atom_Ch_getTimerPointer(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Returns the status of channel One notification
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return Status of channel One notification
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Ch_isOneNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Returns the status of channel Zero notification
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return Status of channel Zero notification
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Atom_Ch_isZeroNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Raises the interrupt for Compare 1
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_raiseInterruptOne(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Raises the interrupt for Compare 0
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_raiseInterruptZero(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \brief Sets the channel clock source
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param clock Channel clock source
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setClockSource(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Cmu_Clk clock);
|
||||
|
||||
/** \brief Sets the compare 0 and 1 values
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param compareZero Compare zero value
|
||||
* \param compareOne Compare one value
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setCompare(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 compareZero, uint32 compareOne);
|
||||
|
||||
/** \brief Sets the compare 1 value
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param compareOne Compare one value
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setCompareOne(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 compareOne);
|
||||
|
||||
/** \brief Sets the compare 1 shadow value
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param shadowOne Compare one shadow value
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setCompareOneShadow(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 shadowOne);
|
||||
|
||||
/** \brief Sets the compare 0 value
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param compareZero Compare zero value
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setCompareZero(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 compareZero);
|
||||
|
||||
/** \brief Sets the compare 0 shadow value
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param shadowZero Compare zero shadow value
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setCompareZeroShadow(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 shadowZero);
|
||||
|
||||
/** \brief Sets the counter value
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param value Counter value
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setCounterValue(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 value);
|
||||
|
||||
/** \brief set the Atom operating mode
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param mode Atom operating mode
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setMode(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_Mode mode);
|
||||
|
||||
/** \brief Sets the channel notification
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param mode Interrupt mode
|
||||
* \param interruptOnCompareZero If TRUE, an interrupt is generated on compare 0, else no interrupt is generated
|
||||
* \param interruptOnCompareOne If TRUE, an interrupt is generated on compare 1, else no interrupt is generated
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setNotification(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_IrqMode mode, boolean interruptOnCompareZero, boolean interruptOnCompareOne);
|
||||
|
||||
/** \brief Enable/disable the one shot mode
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param enabled If TRUE, the feature is enabled, else disabled
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setOneShotMode(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, boolean enabled);
|
||||
|
||||
/** \brief Sets the channel clock source either from local or from previous channel
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param event Channel reset event
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setResetSource(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_Ch_ResetEvent event);
|
||||
|
||||
/** \brief Sets the signal level
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param activeState Signal level active state. In case the channel is reset, the output is set to not active. The signal is active between 0 and the leading edge (CM1) and inactive between the leading edge and the trailing edge (CM0).
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setSignalLevel(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, Ifx_ActiveState activeState);
|
||||
|
||||
/** \brief Sets the channel trigger output
|
||||
* \param atom Pointer to the ATOM object
|
||||
* \param channel Channel index
|
||||
* \param trigger Channel trigger output mode
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setTriggerOutput(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_Ch_OutputTrigger trigger);
|
||||
|
||||
/** \brief Get the counter value
|
||||
* \param atom pointer to the ATOM instance
|
||||
* \param channel channel index of the ATOM
|
||||
* \return counter value
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxGtm_Atom_Ch_getCounterValue(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel);
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Std_Atom_AGC_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Sets the channels for update (UPEN)
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param value value for the channel enable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxGtm_Atom_Agc_setChannelsUpdate(Ifx_GTM_ATOM_AGC *agc, uint32 value);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Builds the register value for the feature enable/disable
|
||||
* \param enableMask Mask for the channel feature enable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param disableMask Mask for the channel feature disable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param bitfieldOffset Offset of the channel 0 bitfield in the register
|
||||
* \return The register value
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxGtm_Atom_Agc_buildFeature(uint16 enableMask, uint16 disableMask, uint8 bitfieldOffset);
|
||||
|
||||
/** \brief Builds the register value for the feature enable/disable for a single channel
|
||||
* \param channel Channel index
|
||||
* \param enabled Enable/ Disable choise of the feature
|
||||
* \param bitfieldOffset Offset of the channel 0 bitfield in the register
|
||||
* \return The register value
|
||||
*/
|
||||
IFX_EXTERN uint32 IfxGtm_Atom_Agc_buildFeatureForChannel(IfxGtm_Atom_Ch channel, boolean enabled, uint8 bitfieldOffset);
|
||||
|
||||
/** \brief Enable/disable one channel (ENDIS)
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param channel Channel index
|
||||
* \param enabled Enable/ Disable choise of the feature
|
||||
* \param immediate If TRUE, the action is done immediately else, the action is done on AGC trigger (CTRL_TRIG)
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_enableChannel(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Atom_Ch channel, boolean enabled, boolean immediate);
|
||||
|
||||
/** \brief Enable/disable one channel output (OUTEN)
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param channel Channel index
|
||||
* \param enabled Enable/ Disable choise of the feature
|
||||
* \param immediate If TRUE, the action is done immediately else, the action is done on TGC trigger (CTRL_TRIG)
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_enableChannelOutput(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Atom_Ch channel, boolean enabled, boolean immediate);
|
||||
|
||||
/** \brief Enable/disable one channel for update (UPEN)
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param channel Channel index
|
||||
* \param enabled Enable/ Disable choise of the feature
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_enableChannelUpdate(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Atom_Ch channel, boolean enabled);
|
||||
|
||||
/** \brief Enable/disable one or more channels (ENDIS)
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param enableMask Mask for the channel feature enable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param disableMask Mask for the channel feature disable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param immediate If TRUE, the action is done immediately else, the action is done on TGC trigger (CTRL_TRIG)
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_enableChannels(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask, boolean immediate);
|
||||
|
||||
/** \brief Enable/disable one or more channels output (OUTEN)
|
||||
* \param agc Pointer to the TGC object
|
||||
* \param enableMask Mask for the channel feature enable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param disableMask Mask for the channel feature disable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param immediate If TRUE, the action is done immediately else, the action is done on TGC trigger (CTRL_TRIG)
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_enableChannelsOutput(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask, boolean immediate);
|
||||
|
||||
/** \brief Enable/disable the TGC channels trigger
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param enableMask Mask for the channel feature enable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param disableMask Mask for the channel feature disable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_enableChannelsTrigger(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask);
|
||||
|
||||
/** \brief Enable/disable one or more channels for update (UPEN)
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param enableMask Mask for the channel feature enable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param disableMask Mask for the channel feature disable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_enableChannelsUpdate(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask);
|
||||
|
||||
/** \brief Enable/disable the time base trigger
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param enabled If TRUE, the trigger is enabled else disabled
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_enableTimeTrigger(Ifx_GTM_ATOM_AGC *agc, boolean enabled);
|
||||
|
||||
/** \brief Reset one or more channels
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param resetMask Mask for the channel reset (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_resetChannels(Ifx_GTM_ATOM_AGC *agc, uint32 resetMask);
|
||||
|
||||
/** \brief Enable/disable one channel for update (FUPD)
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param channel Channel index
|
||||
* \param enabled Enable/ Disable choise of the feature
|
||||
* \param resetEnabled Enable/ Disable reset choise of the feature
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_setChannelForceUpdate(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Atom_Ch channel, boolean enabled, boolean resetEnabled);
|
||||
|
||||
/** \brief Enable/disable one or more channels for the force update feature (FUPD)
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param enableMask Mask for the channel feature enable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param disableMask Mask for the channel feature disable (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \param resetEnableMask Mask for the enabled channels counter reset on force update (bit 0: Channel 0, bit 1: channel 1, ...) Channel 0, bit 1: channel 1, ...)
|
||||
* \param resetDisableMask Mask for the disabled channels with no counter reset on force update (bit 0: Channel 0, bit 1: channel 1, ...)
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_setChannelsForceUpdate(Ifx_GTM_ATOM_AGC *agc, uint16 enableMask, uint16 disableMask, uint16 resetEnableMask, uint16 resetDisableMask);
|
||||
|
||||
/** \brief Sets the trigger time base and time base value
|
||||
* \param agc Pointer to the AGC object
|
||||
* \param base Time base used for comparison
|
||||
* \param value Compare value that raise the trigger
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_setTimeTrigger(Ifx_GTM_ATOM_AGC *agc, IfxGtm_Tbu_Ts base, uint32 value);
|
||||
|
||||
/** \brief Raise the trigger for the channel enable/disable settings, output enable settings, and force update event (CTRL_TRIG)
|
||||
* \param agc Pointer to the AGC object
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Agc_trigger(Ifx_GTM_ATOM_AGC *agc);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief enable/disable ARU input for the ATOM channel specified.
|
||||
* \param atom pointer to the ATOM instance
|
||||
* \param channel index of ATOM channel
|
||||
* \param enabled ARU enable status
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setAruInput(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, boolean enabled);
|
||||
|
||||
/** \brief sets the SOMC control bits for the specified ATOM channel
|
||||
* \param atom pointer to ATOM instance
|
||||
* \param channel ATOM channel index
|
||||
* \param control SOMC control mode enum
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setSomcControl(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_SomcControl control);
|
||||
|
||||
/** \brief sets the SL control for SOMC mode.
|
||||
* \param atom pointer to the ATOM instance
|
||||
* \param channel index of ATOM channel
|
||||
* \param ctrl SIgnal level control
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setSomcSignalLevelControl(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, IfxGtm_Atom_SomcSignalLevelControl ctrl);
|
||||
|
||||
/** \brief set the ARU read address 0
|
||||
* \param atom pointer to ATOM instance
|
||||
* \param channel ATOM channel index
|
||||
* \param address ARU read address 0
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setAruReadAddress0(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 address);
|
||||
|
||||
/** \brief set the ARU read address 1
|
||||
* \param atom pointer to ATOM instance
|
||||
* \param channel ATOM channel index
|
||||
* \param address ARU read address 1
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Atom_Ch_setAruReadAddress1(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 address);
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE Ifx_GTM_ATOM_CH *IfxGtm_Atom_Ch_getChannelPointer(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel)
|
||||
{
|
||||
return (Ifx_GTM_ATOM_CH *)((uint32)&atom->CH0.RDADDR.U + 0x80 * channel);
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxGtm_Atom_Ch_setCompareShadow(Ifx_GTM_ATOM *atom, IfxGtm_Atom_Ch channel, uint32 shadowZero, uint32 shadowOne)
|
||||
{
|
||||
Ifx_GTM_ATOM_CH *atomCh = IfxGtm_Atom_Ch_getChannelPointer(atom, channel);
|
||||
|
||||
atomCh->SR0.U = shadowZero; // TK: replaced .B access to optimize runtime
|
||||
atomCh->SR1.U = shadowOne;
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE void IfxGtm_Atom_Agc_setChannelsUpdate(Ifx_GTM_ATOM_AGC *agc, uint32 value)
|
||||
{
|
||||
agc->GLB_CTRL.U = value;
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXGTM_ATOM_H */
|
||||
@@ -0,0 +1,424 @@
|
||||
/**
|
||||
* \file IfxGtm_Cmu.c
|
||||
* \brief GTM basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGtm_Cmu.h"
|
||||
#include "IfxGtm_Dpll.h"
|
||||
#include "Scu/Std/IfxScuCcu.h"
|
||||
#include "Scu/Std/IfxScuWdt.h"
|
||||
#include "math.h"
|
||||
#include "IfxGtm_bf.h"
|
||||
#include "IfxGtm.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
void IfxGtm_Cmu_enableClocks(Ifx_GTM *gtm, uint32 clkMask)
|
||||
{
|
||||
gtm->CMU.CLK_EN.U = clkMask;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Cmu_getClkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Clk clkIndex, boolean assumeEnabled)
|
||||
{
|
||||
float32 frequency;
|
||||
|
||||
if ((IfxGtm_Cmu_isClkClockEnabled(gtm, clkIndex) != FALSE) || (assumeEnabled != FALSE))
|
||||
{
|
||||
switch (clkIndex)
|
||||
{
|
||||
case IfxGtm_Cmu_Clk_0:
|
||||
case IfxGtm_Cmu_Clk_1:
|
||||
case IfxGtm_Cmu_Clk_2:
|
||||
case IfxGtm_Cmu_Clk_3:
|
||||
case IfxGtm_Cmu_Clk_4:
|
||||
case IfxGtm_Cmu_Clk_5:
|
||||
frequency = IfxGtm_Cmu_getGclkFrequency(gtm) / (gtm->CMU.CLK0_5[clkIndex].CTRL.B.CLK_CNT + 1);
|
||||
break;
|
||||
case IfxGtm_Cmu_Clk_6:
|
||||
|
||||
if (gtm->CMU.CLK_6.CTRL.B.CLK6_SEL == 0)
|
||||
{
|
||||
frequency = IfxGtm_Cmu_getGclkFrequency(gtm) / (gtm->CMU.CLK_6.CTRL.B.CLK_CNT + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = IfxGtm_Dpll_getSubIncFrequency(gtm, IfxGtm_Dpll_SubInc_2);
|
||||
}
|
||||
|
||||
break;
|
||||
case IfxGtm_Cmu_Clk_7:
|
||||
|
||||
if (gtm->CMU.CLK_7.CTRL.B.CLK7_SEL == 0)
|
||||
{
|
||||
frequency = IfxGtm_Cmu_getGclkFrequency(gtm) / (gtm->CMU.CLK_7.CTRL.B.CLK_CNT + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = IfxGtm_Dpll_getSubIncFrequency(gtm, IfxGtm_Dpll_SubInc_1);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
frequency = 0.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = 0.0;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Cmu_getEclkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Eclk clkIndex, boolean assumeEnabled)
|
||||
{
|
||||
float32 frequency;
|
||||
|
||||
if (IfxGtm_Cmu_isEclkClockEnabled(gtm, clkIndex) || (assumeEnabled != FALSE))
|
||||
{
|
||||
float32 Z = gtm->CMU.ECLK[clkIndex].NUM.B.ECLK_NUM;
|
||||
float32 N = gtm->CMU.ECLK[clkIndex].DEN.B.ECLK_DEN;
|
||||
float32 multiplier = N / Z / 2;
|
||||
frequency = IfxGtm_Cmu_getGclkFrequency(gtm) * multiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = 0.0;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Cmu_getFxClkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Fxclk clkIndex, boolean assumeEnabled)
|
||||
{
|
||||
float32 frequency;
|
||||
uint8 fxSelect;
|
||||
|
||||
if (IfxGtm_Cmu_isFxClockEnabled(gtm) || (assumeEnabled != FALSE))
|
||||
{
|
||||
fxSelect = gtm->CMU.FXCLK.CTRL.B.FXCLK_SEL;
|
||||
|
||||
if (fxSelect == 0)
|
||||
{
|
||||
frequency = IfxGtm_Cmu_getGclkFrequency(gtm);
|
||||
}
|
||||
else if (fxSelect <= 6)
|
||||
{
|
||||
frequency = IfxGtm_Cmu_getClkFrequency(gtm, IfxGtm_Cmu_Clk_5, assumeEnabled);
|
||||
}
|
||||
else if (fxSelect == 7)
|
||||
{
|
||||
frequency = IfxGtm_Cmu_getClkFrequency(gtm, IfxGtm_Cmu_Clk_6, assumeEnabled);
|
||||
}
|
||||
else if (fxSelect == 8)
|
||||
{
|
||||
frequency = IfxGtm_Cmu_getClkFrequency(gtm, IfxGtm_Cmu_Clk_7, assumeEnabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = IfxGtm_Cmu_getGclkFrequency(gtm);
|
||||
}
|
||||
|
||||
switch (clkIndex)
|
||||
{
|
||||
case IfxGtm_Cmu_Fxclk_0:
|
||||
frequency = frequency / 1;
|
||||
break;
|
||||
case IfxGtm_Cmu_Fxclk_1:
|
||||
frequency = frequency / 16;
|
||||
break;
|
||||
case IfxGtm_Cmu_Fxclk_2:
|
||||
frequency = frequency / 256;
|
||||
break;
|
||||
case IfxGtm_Cmu_Fxclk_3:
|
||||
frequency = frequency / 4096;
|
||||
break;
|
||||
case IfxGtm_Cmu_Fxclk_4:
|
||||
frequency = frequency / 65536;
|
||||
break;
|
||||
default:
|
||||
frequency = 0.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = 0.0;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Cmu_getGclkFrequency(Ifx_GTM *gtm)
|
||||
{
|
||||
float32 N = gtm->CMU.GCLK_DEN.B.GCLK_DEN;
|
||||
float32 Z = gtm->CMU.GCLK_NUM.B.GCLK_NUM;
|
||||
float32 multiplier = N / Z;
|
||||
|
||||
return IfxGtm_Cmu_getModuleFrequency(gtm) * multiplier;
|
||||
}
|
||||
|
||||
|
||||
float32 IfxGtm_Cmu_getModuleFrequency(Ifx_GTM *gtm)
|
||||
{
|
||||
return IfxGtm_getSysClkFrequency();
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Cmu_isClkClockEnabled(Ifx_GTM *gtm, IfxGtm_Cmu_Clk clkIndex)
|
||||
{
|
||||
return ((gtm->CMU.CLK_EN.U >> (2 * clkIndex)) & IFX_GTM_CMU_CLK_EN_EN_CLK0_MSK) == 0x3;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Cmu_isEclkClockEnabled(Ifx_GTM *gtm, IfxGtm_Cmu_Eclk clkIndex)
|
||||
{
|
||||
return ((gtm->CMU.CLK_EN.U >> (2 * clkIndex + 16)) & IFX_GTM_CMU_CLK_EN_EN_CLK0_MSK) == 0x3;
|
||||
}
|
||||
|
||||
|
||||
boolean IfxGtm_Cmu_isFxClockEnabled(Ifx_GTM *gtm)
|
||||
{
|
||||
return gtm->CMU.CLK_EN.B.EN_FXCLK == 0x3;
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Cmu_selectClkInput(Ifx_GTM *gtm, IfxGtm_Cmu_Clk clkIndex, boolean useGlobal)
|
||||
{
|
||||
switch (clkIndex)
|
||||
{
|
||||
case IfxGtm_Cmu_Clk_6:
|
||||
gtm->CMU.CLK_6.CTRL.B.CLK6_SEL = useGlobal ? 0 : 1;
|
||||
break;
|
||||
case IfxGtm_Cmu_Clk_7:
|
||||
gtm->CMU.CLK_7.CTRL.B.CLK7_SEL = useGlobal ? 0 : 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Cmu_setClkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Clk clkIndex, float32 frequency)
|
||||
{
|
||||
float32 t = (IfxGtm_Cmu_getGclkFrequency(gtm) / frequency) - 1;
|
||||
uint32 cnt = (uint32)t;
|
||||
|
||||
if ((t - (float32)cnt) > 0.5)
|
||||
{ /* Round to nearest */
|
||||
cnt++;
|
||||
}
|
||||
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(psw);
|
||||
|
||||
switch (clkIndex)
|
||||
{
|
||||
case IfxGtm_Cmu_Clk_0:
|
||||
case IfxGtm_Cmu_Clk_1:
|
||||
case IfxGtm_Cmu_Clk_2:
|
||||
case IfxGtm_Cmu_Clk_3:
|
||||
case IfxGtm_Cmu_Clk_4:
|
||||
case IfxGtm_Cmu_Clk_5:
|
||||
gtm->CMU.CLK0_5[clkIndex].CTRL.B.CLK_CNT = cnt;
|
||||
break;
|
||||
case IfxGtm_Cmu_Clk_6:
|
||||
gtm->CMU.CLK_6.CTRL.B.CLK_CNT = cnt;
|
||||
break;
|
||||
case IfxGtm_Cmu_Clk_7:
|
||||
gtm->CMU.CLK_7.CTRL.B.CLK_CNT = cnt;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
IfxScuWdt_setCpuEndinit(psw);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Cmu_setEclkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Eclk clkIndex, float32 frequency)
|
||||
{
|
||||
float32 f;
|
||||
float32 bestDistance = frequency;
|
||||
float32 fIn = IfxGtm_Cmu_getGclkFrequency(gtm) * 2;
|
||||
uint32 z, n, nBest = 1, zBest = 1;
|
||||
float32 t;
|
||||
|
||||
for (z = 1; z < 0xFFFFFF; z++)
|
||||
{
|
||||
boolean endLoop = FALSE;
|
||||
t = fIn / z;
|
||||
|
||||
for (n = z; n > 0; n--)
|
||||
{
|
||||
float32 distance;
|
||||
f = t * n;
|
||||
distance = fabsf(frequency - f);
|
||||
|
||||
if (distance < bestDistance)
|
||||
{
|
||||
bestDistance = distance;
|
||||
nBest = n;
|
||||
zBest = z;
|
||||
}
|
||||
|
||||
if (bestDistance < 0.1)
|
||||
{
|
||||
endLoop = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (endLoop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(psw);
|
||||
gtm->CMU.ECLK[clkIndex].NUM.B.ECLK_NUM = zBest;
|
||||
gtm->CMU.ECLK[clkIndex].NUM.B.ECLK_NUM = zBest; /* write twice to be sure */
|
||||
gtm->CMU.ECLK[clkIndex].DEN.B.ECLK_DEN = nBest;
|
||||
IfxScuWdt_setCpuEndinit(psw);
|
||||
}
|
||||
|
||||
|
||||
void IfxGtm_Cmu_setGclkFrequency(Ifx_GTM *gtm, float32 frequency)
|
||||
{
|
||||
float32 f;
|
||||
float32 bestDistance = frequency;
|
||||
|
||||
float32 fIn = IfxGtm_Cmu_getModuleFrequency(gtm);
|
||||
uint32 z, n, nBest = 1, zBest = 1;
|
||||
float32 t;
|
||||
|
||||
#if 1
|
||||
|
||||
for (z = 1; z < 0xFFFFFF; z++)
|
||||
{
|
||||
boolean endLoop = FALSE;
|
||||
t = fIn / z;
|
||||
|
||||
for (n = z; n > 0; n--)
|
||||
{
|
||||
float32 distance;
|
||||
f = t * n;
|
||||
distance = fabsf(frequency - f);
|
||||
|
||||
if (distance < bestDistance)
|
||||
{
|
||||
bestDistance = distance;
|
||||
nBest = n;
|
||||
zBest = z;
|
||||
}
|
||||
|
||||
if (bestDistance < 0.1)
|
||||
{
|
||||
endLoop = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (endLoop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for (n = 1; n < 0xFFFFFF; n++)
|
||||
{
|
||||
float32 distance;
|
||||
/* get best z */
|
||||
z = floorf(frequency * n / fIn);
|
||||
t = fIn / n;
|
||||
|
||||
/* lower value */
|
||||
f = t * z;
|
||||
distance = fabsf(frequency - f);
|
||||
|
||||
if (distance < bestDistance)
|
||||
{
|
||||
bestDistance = distance;
|
||||
nBest = n;
|
||||
zBest = z;
|
||||
}
|
||||
|
||||
/* upper value */
|
||||
f = t * (z + 1);
|
||||
distance = fabsf(frequency - f);
|
||||
|
||||
if (distance < bestDistance)
|
||||
{
|
||||
bestDistance = distance;
|
||||
nBest = n;
|
||||
zBest = z;
|
||||
}
|
||||
|
||||
if (bestDistance == 0.0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint16 psw = IfxScuWdt_getCpuWatchdogPassword();
|
||||
IfxScuWdt_clearCpuEndinit(psw);
|
||||
gtm->CMU.GCLK_NUM.B.GCLK_NUM = zBest;
|
||||
gtm->CMU.GCLK_NUM.B.GCLK_NUM = zBest; /* write twice to be sure */
|
||||
gtm->CMU.GCLK_DEN.B.GCLK_DEN = nBest;
|
||||
IfxScuWdt_setCpuEndinit(psw);
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* \file IfxGtm_Cmu.h
|
||||
* \brief GTM basic functionality
|
||||
* \ingroup IfxLld_Gtm
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Std_Cmu Cmu Basic Functionality
|
||||
* \ingroup IfxLld_Gtm_Std
|
||||
* \defgroup IfxLld_Gtm_Std_Cmu_CMUEnumerations CMU Enumerations
|
||||
* \ingroup IfxLld_Gtm_Std_Cmu
|
||||
* \defgroup IfxLld_Gtm_Std_Cmu_CMU_Basic_Functions CMU Basic Functions
|
||||
* \ingroup IfxLld_Gtm_Std_Cmu
|
||||
*/
|
||||
|
||||
#ifndef IFXGTM_CMU_H
|
||||
#define IFXGTM_CMU_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxGtm_cfg.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Std_Cmu_CMUEnumerations
|
||||
* \{ */
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Cmu_Clk_0 = 0,
|
||||
IfxGtm_Cmu_Clk_1,
|
||||
IfxGtm_Cmu_Clk_2,
|
||||
IfxGtm_Cmu_Clk_3,
|
||||
IfxGtm_Cmu_Clk_4,
|
||||
IfxGtm_Cmu_Clk_5,
|
||||
IfxGtm_Cmu_Clk_6,
|
||||
IfxGtm_Cmu_Clk_7
|
||||
} IfxGtm_Cmu_Clk;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Cmu_Eclk_0 = 0,
|
||||
IfxGtm_Cmu_Eclk_1,
|
||||
IfxGtm_Cmu_Eclk_2
|
||||
} IfxGtm_Cmu_Eclk;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Cmu_Fxclk_0 = 0,
|
||||
IfxGtm_Cmu_Fxclk_1,
|
||||
IfxGtm_Cmu_Fxclk_2,
|
||||
IfxGtm_Cmu_Fxclk_3,
|
||||
IfxGtm_Cmu_Fxclk_4
|
||||
} IfxGtm_Cmu_Fxclk;
|
||||
|
||||
/** \brief Tim Filter counter frequency select
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Cmu_Tim_Filter_Clk_0, /**< \brief FLT_CNT counts with CMU_CLK0 */
|
||||
IfxGtm_Cmu_Tim_Filter_Clk_1, /**< \brief FLT_CNT counts with CMU_CLK1 */
|
||||
IfxGtm_Cmu_Tim_Filter_Clk_6, /**< \brief FLT_CNT counts with CMU_CLK6 */
|
||||
IfxGtm_Cmu_Tim_Filter_Clk_7 /**< \brief FLT_CNT counts with CMU_CLK7 */
|
||||
} IfxGtm_Cmu_Tim_Filter_Clk;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Std_Cmu_CMU_Basic_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Enable / Disable the configurable, fixed, and external clocks
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param clkMask Enable / Disable mask.
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Cmu_enableClocks(Ifx_GTM *gtm, uint32 clkMask);
|
||||
|
||||
/** \brief Returns the GTM configurable clock frequency in Hz
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param clkIndex Index of the configurable clock 0=CMU_CLK0, 1=CMU_CLK1, ...
|
||||
* \param assumeEnabled When TRUE, attempt to calculate the frequency as if the clock is enabled.
|
||||
* \return GTM configurable clock frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Cmu_getClkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Clk clkIndex, boolean assumeEnabled);
|
||||
|
||||
/** \brief Returns the GTM external clock frequency in Hz
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param clkIndex Index of the external clock 0=CMU_ECLK0, 1=CMU_ECLK1, ...
|
||||
* \param assumeEnabled When TRUE, attempt to calculate the frequency as if the clock is enabled.
|
||||
* \return GTM external clock frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Cmu_getEclkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Eclk clkIndex, boolean assumeEnabled);
|
||||
|
||||
/** \brief Returns the GTM fixed clock frequency in Hz
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param clkIndex Index of the fixed clock 0=CMU_FXCLK0, 1=CMU_FXCLK1, ...
|
||||
* \param assumeEnabled When TRUE, attempt to calculate the frequency as if the clock is enabled.
|
||||
* \return GTM fixed clock frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Cmu_getFxClkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Fxclk clkIndex, boolean assumeEnabled);
|
||||
|
||||
/** \brief Returns the GTM global clock frequency in Hz
|
||||
* \param gtm Pointer to GTM module
|
||||
* \return GTM global clock frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Cmu_getGclkFrequency(Ifx_GTM *gtm);
|
||||
|
||||
/** \brief returns the CMU module frequency in Hz. This is only for CMU module frequency.
|
||||
* For GTM SYS frequency: IfxGtm_getSysClkFrequency() is to be used.
|
||||
* \param gtm Pointer to GTM module
|
||||
* \return GTM module frequency in Hz
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Cmu_getModuleFrequency(Ifx_GTM *gtm);
|
||||
|
||||
/** \brief Returns the configurable clock enable status
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param clkIndex Index of the configurable clock 0=CMU_CLK0, 1=CMU_CLK1, ...
|
||||
* \return TRUE The clock is enabled, FALSE The clock is disabled
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Cmu_isClkClockEnabled(Ifx_GTM *gtm, IfxGtm_Cmu_Clk clkIndex);
|
||||
|
||||
/** \brief Returns the external clock enable status
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param clkIndex Index of the external clock 0=CMU_ECLK0, 1=CMU_ECLK1, ...
|
||||
* \return TRUE The clock is enabled, FALSE The clock is disabled
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Cmu_isEclkClockEnabled(Ifx_GTM *gtm, IfxGtm_Cmu_Eclk clkIndex);
|
||||
|
||||
/** \brief Returns the fixed clock enable status
|
||||
* \param gtm Pointer to GTM module
|
||||
* \return TRUE The clock is enabled, FALSE The clock is disabled
|
||||
*/
|
||||
IFX_EXTERN boolean IfxGtm_Cmu_isFxClockEnabled(Ifx_GTM *gtm);
|
||||
|
||||
/** \brief Select the clock input for CLK6 and CLK7
|
||||
* note The frequency can only be modified when the corresponding clock is disabled using IfxGtm_Cmu_enableClocks()
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param clkIndex Index of the configurable clock 0=CMU_CLK0, 1=CMU_CLK1, ...
|
||||
* \param useGlobal if TRUE, uses the global clock as an input, else use the SUB_INC input
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Cmu_selectClkInput(Ifx_GTM *gtm, IfxGtm_Cmu_Clk clkIndex, boolean useGlobal);
|
||||
|
||||
/** \brief Set the GTM configurable clock frequency in Hz
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param clkIndex Index of the configurable clock 0=CMU_CLK0, 1=CMU_CLK1, ...
|
||||
* \param frequency Frequency in Hz
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Cmu_setClkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Clk clkIndex, float32 frequency);
|
||||
|
||||
/** \brief Set the GTM external clock frequency in Hz
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param clkIndex Index of the external clock 0=CMU_ECLK0, 1=CMU_ECLK1, ...
|
||||
* \param frequency Frequency in Hz
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Cmu_setEclkFrequency(Ifx_GTM *gtm, IfxGtm_Cmu_Eclk clkIndex, float32 frequency);
|
||||
|
||||
/** \brief Set the GTM global clock frequency in Hz
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param frequency Frequency in Hz
|
||||
* \return None
|
||||
*/
|
||||
IFX_EXTERN void IfxGtm_Cmu_setGclkFrequency(Ifx_GTM *gtm, float32 frequency);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXGTM_CMU_H */
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* \file IfxGtm_Dpll.c
|
||||
* \brief GTM basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGtm_Dpll.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
float32 IfxGtm_Dpll_getSubIncFrequency(Ifx_GTM *gtm, IfxGtm_Dpll_SubInc index)
|
||||
{
|
||||
IFX_UNUSED_PARAMETER(gtm)
|
||||
IFX_UNUSED_PARAMETER(index)
|
||||
return 0.0F;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* \file IfxGtm_Dpll.h
|
||||
* \brief GTM basic functionality
|
||||
* \ingroup IfxLld_Gtm
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2019 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Std_Dpll Dpll Basic Functionality
|
||||
* \ingroup IfxLld_Gtm_Std
|
||||
* \defgroup IfxLld_Gtm_Std_Dpll_Basic_Functions DPLL Basic Functions
|
||||
* \ingroup IfxLld_Gtm_Std_Dpll
|
||||
*/
|
||||
|
||||
#ifndef IFXGTM_DPLL_H
|
||||
#define IFXGTM_DPLL_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxGtm_cfg.h"
|
||||
/** \addtogroup IfxLld_Gtm_Std_Dpll_Basic_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Dummy Function, returns 0.0F
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param index Dpll subincrement index
|
||||
* \return frequency
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Dpll_getSubIncFrequency(Ifx_GTM *gtm, IfxGtm_Dpll_SubInc index);
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* IFXGTM_DPLL_H */
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* \file IfxGtm_Tbu.c
|
||||
* \brief GTM basic functionality
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "IfxGtm_Tbu.h"
|
||||
#include "IfxGtm_Cmu.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Function Implementations---------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
float32 IfxGtm_Tbu_getClockFrequency(Ifx_GTM *gtm, IfxGtm_Tbu_Ts channel)
|
||||
{
|
||||
float32 result = 0.0F;
|
||||
|
||||
if (channel == IfxGtm_Tbu_Ts_0)
|
||||
{
|
||||
result = IfxGtm_Cmu_getClkFrequency(gtm, (IfxGtm_Cmu_Clk)gtm->TBU.CH0_CTRL.B.CH_CLK_SRC, TRUE);
|
||||
}
|
||||
else if (channel == IfxGtm_Tbu_Ts_1)
|
||||
{
|
||||
result = IfxGtm_Cmu_getClkFrequency(gtm, (IfxGtm_Cmu_Clk)gtm->TBU.CH1_CTRL.B.CH_CLK_SRC, TRUE);
|
||||
}
|
||||
else if (channel == IfxGtm_Tbu_Ts_2)
|
||||
{
|
||||
result = IfxGtm_Cmu_getClkFrequency(gtm, (IfxGtm_Cmu_Clk)gtm->TBU.CH2_CTRL.B.CH_CLK_SRC, TRUE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* \file IfxGtm_Tbu.h
|
||||
* \brief GTM basic functionality
|
||||
* \ingroup IfxLld_Gtm
|
||||
*
|
||||
* \version iLLD_1_0_1_11_0
|
||||
* \copyright Copyright (c) 2018 Infineon Technologies AG. All rights reserved.
|
||||
*
|
||||
*
|
||||
* IMPORTANT NOTICE
|
||||
*
|
||||
*
|
||||
* Use of this file is subject to the terms of use agreed between (i) you or
|
||||
* the company in which ordinary course of business you are acting and (ii)
|
||||
* Infineon Technologies AG or its licensees. If and as long as no such
|
||||
* terms of use are agreed, use of this file is subject to following:
|
||||
|
||||
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person or
|
||||
* organization obtaining a copy of the software and accompanying
|
||||
* documentation covered by this license (the "Software") to use, reproduce,
|
||||
* display, distribute, execute, and transmit the Software, and to prepare
|
||||
* derivative works of the Software, and to permit third-parties to whom the
|
||||
* Software is furnished to do so, all subject to the following:
|
||||
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer, must
|
||||
* be included in all copies of the Software, in whole or in part, and all
|
||||
* derivative works of the Software, unless such copies or derivative works are
|
||||
* solely in the form of machine-executable object code generated by a source
|
||||
* language processor.
|
||||
|
||||
* 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*
|
||||
* \defgroup IfxLld_Gtm_Std_Tbu Tbu Basic Functionality
|
||||
* \ingroup IfxLld_Gtm_Std
|
||||
* \defgroup IfxLld_Gtm_Std_Tbu_Enumerations TBU Enumerations
|
||||
* \ingroup IfxLld_Gtm_Std_Tbu
|
||||
* \defgroup IfxLld_Gtm_Std_Tbu_Basic_Functions TBU Basic Functions
|
||||
* \ingroup IfxLld_Gtm_Std_Tbu
|
||||
*/
|
||||
|
||||
#ifndef IFXGTM_TBU_H
|
||||
#define IFXGTM_TBU_H 1
|
||||
|
||||
/******************************************************************************/
|
||||
/*----------------------------------Includes----------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "_Impl/IfxGtm_cfg.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*--------------------------------Enumerations--------------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Std_Tbu_Enumerations
|
||||
* \{ */
|
||||
/** \brief GTM TOM TBU Time stamps
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
IfxGtm_Tbu_Ts_0,
|
||||
IfxGtm_Tbu_Ts_1,
|
||||
IfxGtm_Tbu_Ts_2
|
||||
} IfxGtm_Tbu_Ts;
|
||||
|
||||
/** \} */
|
||||
|
||||
/** \addtogroup IfxLld_Gtm_Std_Tbu_Basic_Functions
|
||||
* \{ */
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Inline Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Enables the channel
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param channel TBU Time stamps
|
||||
* \return None
|
||||
*/
|
||||
IFX_INLINE void IfxGtm_Tbu_enableChannel(Ifx_GTM *gtm, IfxGtm_Tbu_Ts channel);
|
||||
|
||||
/** \brief Function to check if a TBU channel is enabled.
|
||||
* Returns TRUE if the corresponding channel is enabled
|
||||
* Returns FALSE if the corresponding channel is disabled.
|
||||
* \param gtm Pointer to GTM SFR
|
||||
* \param channel Channel of TBU
|
||||
* \return TRUE: channel is enabled
|
||||
*/
|
||||
IFX_INLINE boolean IfxGtm_Tbu_isChannelEnabled(Ifx_GTM *gtm, IfxGtm_Tbu_Ts channel);
|
||||
|
||||
/******************************************************************************/
|
||||
/*-------------------------Global Function Prototypes-------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
/** \brief Returns the clock frequency
|
||||
* \param gtm Pointer to GTM module
|
||||
* \param channel TBU Time stamps
|
||||
* \return frequency
|
||||
*/
|
||||
IFX_EXTERN float32 IfxGtm_Tbu_getClockFrequency(Ifx_GTM *gtm, IfxGtm_Tbu_Ts channel);
|
||||
|
||||
/** \} */
|
||||
|
||||
/******************************************************************************/
|
||||
/*---------------------Inline Function Implementations------------------------*/
|
||||
/******************************************************************************/
|
||||
|
||||
IFX_INLINE void IfxGtm_Tbu_enableChannel(Ifx_GTM *gtm, IfxGtm_Tbu_Ts channel)
|
||||
{
|
||||
uint32 shift = channel * 2;
|
||||
|
||||
__ldmst_c(>m->TBU.CHEN.U, (3U << shift), (IfxGtm_FeatureControl_enable << shift));
|
||||
}
|
||||
|
||||
|
||||
IFX_INLINE boolean IfxGtm_Tbu_isChannelEnabled(Ifx_GTM *gtm, IfxGtm_Tbu_Ts channel)
|
||||
{
|
||||
uint32 shift = channel * 2;
|
||||
uint32 enable_status = (gtm->TBU.CHEN.U & ((uint32)3 << shift)) >> shift;
|
||||
|
||||
return enable_status == (uint32)IfxGtm_FeatureControl_enabled;
|
||||
}
|
||||
|
||||
|
||||
#endif /* IFXGTM_TBU_H */
|
||||
Loaded 100 of 660 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user