Part Number: HALCOGEN
I am interested in SCI in multi-buffer mode. I tried find answer/example in HALCoGen, newest version. With no luck. Then I find example on this forum (.zip).
By comparison two files (one from .zip demo and 2nd generated by HALCoGen), there is big difference in work around multi-buffer SCI.
So I must ask, why the multi-buffer functionality is missing (in newer versions) and why I find two indentically signed versions of file (origin TI) not identical?
Thank You
/** @file sci.c
* @brief SCI Driver Implementation File
* @date 17.Nov.2014
* @version 04.02.00
*
*/
/*
* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* USER CODE BEGIN (0) */
/* USER CODE END */
#include "sci.h"
#include "lin.h"
#include "sys_vim.h"
/* USER CODE BEGIN (1) */
/* USER CODE END */
/** @struct g_sciTransfer
* @brief Interrupt mode globals
*
*/
static struct g_sciTransfer
{
uint32 mode; /* Used to check for TX interrupt Enable */
uint32 tx_length; /* Transmit data length in number of Bytes */
uint32 rx_length; /* Receive data length in number of Bytes */
uint8 * tx_data; /* Transmit data pointer */
uint8 * rx_data; /* Receive data pointer */
} g_sciTransfer_t;
/** @fn void sciInit(void)
* @brief Initializes the SCI Driver
*
* This function initializes the SCI module.
*/
/* SourceId : SCI_SourceId_001 */
/* DesignId : SCI_DesignId_001 */
/* Requirements : HL_SR230 */
void sciInit(void)
{
/* USER CODE BEGIN (2) */
/* USER CODE END */
/** @b initialize @b SCILIN */
/** - bring SCI out of reset */
scilinREG->GCR0 = 0U;
scilinREG->GCR0 = 1U;
/** - Disable all interrupts */
scilinREG->CLEARINT = 0xFFFFFFFFU;
scilinREG->CLEARINTLVL = 0xFFFFFFFFU;
/** - global control 1 */
scilinREG->GCR1 = (uint32)((uint32)1U << 25U) /* enable transmit */
| (uint32)((uint32)1U << 24U) /* enable receive */
| (uint32)((uint32)1U << 5U) /* internal clock (device has no clock pin) */
| (uint32)((uint32)(2U-1U) << 4U) /* number of stop bits */
| (uint32)((uint32)0U << 3U) /* even parity, otherwise odd */
| (uint32)((uint32)0U << 2U) /* enable parity */
| (uint32)((uint32)1U << 1U); /* asynchronous timing mode */
/** - set baudrate */
scilinREG->BRS = 53U; /* baudrate */
/** - transmission length */
scilinREG->FORMAT = 8U - 1U; /* length */
/** - set SCI pins functional mode */
scilinREG->PIO0 = (uint32)((uint32)1U << 2U) /* tx pin */
| (uint32)((uint32)1U << 1U); /* rx pin */
/** - set SCI pins default output value */
scilinREG->PIO3 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */
/** - set SCI pins output direction */
scilinREG->PIO1 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */
/** - set SCI pins open drain enable */
scilinREG->PIO6 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */
/** - set SCI pins pullup/pulldown enable */
scilinREG->PIO7 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */
/** - set SCI pins pullup/pulldown select */
scilinREG->PIO8 = (uint32)((uint32)1U << 2U) /* tx pin */
| (uint32)((uint32)1U << 1U); /* rx pin */
/** - set interrupt level */
scilinREG->SETINTLVL = (uint32)((uint32)0U << 26U) /* Framing error */
| (uint32)((uint32)0U << 25U) /* Overrun error */
| (uint32)((uint32)0U << 24U) /* Parity error */
| (uint32)((uint32)0U << 9U) /* Receive */
| (uint32)((uint32)0U << 8U) /* Transmit */
| (uint32)((uint32)0U << 1U) /* Wakeup */
| (uint32)((uint32)0U << 0U); /* Break detect */
/** - set interrupt enable */
scilinREG->SETINT = (uint32)((uint32)0U << 26U) /* Framing error */
| (uint32)((uint32)0U << 25U) /* Overrun error */
| (uint32)((uint32)0U << 24U) /* Parity error */
| (uint32)((uint32)0U << 9U) /* Receive */
| (uint32)((uint32)0U << 1U) /* Wakeup */
| (uint32)((uint32)0U); /* Break detect */
/** - initialize global transfer variables */
g_sciTransfer_t.mode = (uint32)0U << 8U;
g_sciTransfer_t.tx_length = 0U;
g_sciTransfer_t.rx_length = 0U;
/** - Finaly start SCILIN */
scilinREG->GCR1 |= 0x80U;
/* USER CODE BEGIN (3) */
/* USER CODE END */
}
/** @fn void sciSetFunctional(sciBASE_t *sci, uint32 port)
* @brief Change functional behavior of pins at runtime.
* @param[in] sci - sci module base address
* @param[in] port - Value to write to PIO0 register
*
* Change the value of the PCPIO0 register at runtime, this allows to
* dynamically change the functionality of the SCI pins between functional
* and GIO mode.
*/
/* SourceId : SCI_SourceId_002 */
/* DesignId : SCI_DesignId_002 */
/* Requirements : HL_SR231 */
void sciSetFunctional(sciBASE_t *sci, uint32 port)
{
/* USER CODE BEGIN (4) */
/* USER CODE END */
sci->PIO0 = port;
/* USER CODE BEGIN (5) */
/* USER CODE END */
}
/** @fn void sciSetBaudrate(sciBASE_t *sci, uint32 baud)
* @brief Change baudrate at runtime.
* @param[in] sci - sci module base address
* @param[in] baud - baudrate in Hz
*
* Change the SCI baudrate at runtime.
*/
/* SourceId : SCI_SourceId_003 */
/* DesignId : SCI_DesignId_003 */
/* Requirements : HL_SR232 */
void sciSetBaudrate(sciBASE_t *sci, uint32 baud)
{
float64 vclk = 100.000 * 1000000.0;
uint32 f = ((sci->GCR1 & 2U) == 2U) ? 16U : 1U;
uint32 temp;
float64 temp2;
/* USER CODE BEGIN (6) */
/* USER CODE END */
/*SAFETYMCUSW 96 S MR:6.1 <APPROVED> "Calculations including int and float cannot be avoided" */
temp = (f*(baud + 1U));
temp2 = ((vclk)/((float64)temp));
sci->BRS = (uint32)((uint32)temp2 & 0x00FFFFFFU);
/* USER CODE BEGIN (7) */
/* USER CODE END */
}
/** @fn uint32 sciIsTxReady(sciBASE_t *sci)
* @brief Check if Tx buffer empty
* @param[in] sci - sci module base address
*
* @return The TX ready flag
*
* Checks to see if the Tx buffer ready flag is set, returns
* 0 is flags not set otherwise will return the Tx flag itself.
*/
/* SourceId : SCI_SourceId_004 */
/* DesignId : SCI_DesignId_004 */
/* Requirements : HL_SR233 */
uint32 sciIsTxReady(sciBASE_t *sci)
{
/* USER CODE BEGIN (8) */
/* USER CODE END */
return sci->FLR & (uint32)SCI_TX_INT;
}
/** @fn void sciSendByte(sciBASE_t *sci, uint8 byte)
* @brief Send Byte
* @param[in] sci - sci module base address
* @param[in] byte - byte to transfer
*
* Sends a single byte in polling mode, will wait in the
* routine until the transmit buffer is empty before sending
* the byte. Use sciIsTxReady to check for Tx buffer empty
* before calling sciSendByte to avoid waiting.
*/
/* SourceId : SCI_SourceId_005 */
/* DesignId : SCI_DesignId_005 */
/* Requirements : HL_SR234 */
void sciSendByte(sciBASE_t *sci, uint8 byte)
{
/* USER CODE BEGIN (9) */
/* USER CODE END */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((sci->FLR & (uint32)SCI_TX_INT) == 0U)
{
} /* Wait */
sci->TD = byte;
/* USER CODE BEGIN (10) */
/* USER CODE END */
}
/** @fn void sciSend(sciBASE_t *sci, uint32 length, uint8 * data)
* @brief Send Data
* @param[in] sci - sci module base address
* @param[in] length - number of data words to transfer
* @param[in] data - pointer to data to send
*
* Send a block of data pointed to by 'data' and 'length' bytes
* long. If interrupts have been enabled the data is sent using
* interrupt mode, otherwise polling mode is used. In interrupt
* mode transmission of the first byte is started and the routine
* returns immediately, sciSend must not be called again until the
* transfer is complete, when the sciNotification callback will
* be called. In polling mode, sciSend will not return until
* the transfer is complete.
*
* @note if data word is less than 8 bits, then the data must be left
* aligned in the data byte.
*/
/* SourceId : SCI_SourceId_006 */
/* DesignId : SCI_DesignId_006 */
/* Requirements : HL_SR235 */
void sciSend(sciBASE_t *sci, uint32 length, uint8 * data)
{
uint8 txdata;
/* USER CODE BEGIN (11) */
/* USER CODE END */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Mode variable is configured in sciEnableNotification()" */
if ((g_sciTransfer_t.mode & (uint32)SCI_TX_INT) != 0U)
{
/* we are in interrupt mode */
g_sciTransfer_t.tx_length = length;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
g_sciTransfer_t.tx_data = data;
/* start transmit by sending first byte */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
txdata = *g_sciTransfer_t.tx_data;
sci->TD = (uint32)(txdata);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_sciTransfer_t.tx_data++;
sci->SETINT = (uint32)SCI_TX_INT;
}
else
{
/* send the data */
while (length > 0U)
{
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((sci->FLR & (uint32)SCI_TX_INT) == 0U)
{
} /* Wait */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
txdata = *data;
sci->TD = (uint32)(txdata);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
data++;
length--;
}
}
/* USER CODE BEGIN (12) */
/* USER CODE END */
}
/** @fn uint32 sciIsRxReady(sciBASE_t *sci)
* @brief Check if Rx buffer full
* @param[in] sci - sci module base address
*
* @return The Rx ready flag
*
* Checks to see if the Rx buffer full flag is set, returns
* 0 is flags not set otherwise will return the Rx flag itself.
*/
/* SourceId : SCI_SourceId_007 */
/* DesignId : SCI_DesignId_007 */
/* Requirements : HL_SR236 */
uint32 sciIsRxReady(sciBASE_t *sci)
{
/* USER CODE BEGIN (13) */
/* USER CODE END */
return sci->FLR & (uint32)SCI_RX_INT;
}
/** @fn uint32 sciIsIdleDetected(sciBASE_t *sci)
* @brief Check if Idle Period is Detected
* @param[in] sci - sci module base address
*
* @return The Idle flag
*
* Checks to see if the SCI Idle flag is set, returns 0 is flags
* not set otherwise will return the Ilde flag itself.
*/
/* SourceId : SCI_SourceId_008 */
/* DesignId : SCI_DesignId_008 */
/* Requirements : HL_SR237 */
uint32 sciIsIdleDetected(sciBASE_t *sci)
{
/* USER CODE BEGIN (14) */
/* USER CODE END */
return sci->FLR & (uint32)SCI_IDLE;
}
/** @fn uint32 sciRxError(sciBASE_t *sci)
* @brief Return Rx Error flags
* @param[in] sci - sci module base address
*
* @return The Rx error flags
*
* Returns the Rx framing, overrun and parity errors flags,
* also clears the error flags before returning.
*/
/* SourceId : SCI_SourceId_009 */
/* DesignId : SCI_DesignId_009 */
/* Requirements : HL_SR238 */
uint32 sciRxError(sciBASE_t *sci)
{
uint32 status = (sci->FLR & ((uint32)SCI_FE_INT | (uint32)SCI_OE_INT |(uint32)SCI_PE_INT));
/* USER CODE BEGIN (15) */
/* USER CODE END */
sci->FLR = ((uint32)SCI_FE_INT | (uint32)SCI_OE_INT | (uint32)SCI_PE_INT);
return status;
}
/** @fn uint32 sciReceiveByte(sciBASE_t *sci)
* @brief Receive Byte
* @param[in] sci - sci module base address
*
* @return Received byte
*
* Receives a single byte in polling mode. If there is
* not a byte in the receive buffer the routine will wait
* until one is received. Use sciIsRxReady to check to
* see if the buffer is full to avoid waiting.
*/
/* SourceId : SCI_SourceId_010 */
/* DesignId : SCI_DesignId_010 */
/* Requirements : HL_SR239 */
uint32 sciReceiveByte(sciBASE_t *sci)
{
/* USER CODE BEGIN (16) */
/* USER CODE END */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((sci->FLR & (uint32)SCI_RX_INT) == 0U)
{
} /* Wait */
return (sci->RD & (uint32)0x000000FFU);
}
/** @fn void sciReceive(sciBASE_t *sci, uint32 length, uint8 * data)
* @brief Receive Data
* @param[in] sci - sci module base address
* @param[in] length - number of data words to transfer
* @param[in] data - pointer to data buffer to receive data
*
* Receive a block of 'length' bytes long and place it into the
* data buffer pointed to by 'data'. If interrupts have been
* enabled the data is received using interrupt mode, otherwise
* polling mode is used. In interrupt mode receive is setup and
* the routine returns immediately, sciReceive must not be called
* again until the transfer is complete, when the sciNotification
* callback will be called. In polling mode, sciReceive will not
* return until the transfer is complete.
*/
/* SourceId : SCI_SourceId_011 */
/* DesignId : SCI_DesignId_011 */
/* Requirements : HL_SR240 */
void sciReceive(sciBASE_t *sci, uint32 length, uint8 * data)
{
/* USER CODE BEGIN (17) */
/* USER CODE END */
if ((sci->SETINT & (uint32)SCI_RX_INT) == (uint32)SCI_RX_INT)
{
/* we are in interrupt mode */
/* clear error flags */
sci->FLR = ((uint32) SCI_FE_INT | (uint32) SCI_OE_INT | (uint32) SCI_PE_INT);
g_sciTransfer_t.rx_length = length;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
g_sciTransfer_t.rx_data = data;
}
else
{
/*SAFETYMCUSW 30 S MR:12.2,12.3 <APPROVED> "Used for data count in Transmit/Receive polling and Interrupt mode" */
while (length > 0U)
{
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((sci->FLR & (uint32)SCI_RX_INT) == 0U)
{
} /* Wait */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
*data = (uint8)(sci->RD & 0x000000FFU);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer operation required." */
data++;
length--;
}
}
/* USER CODE BEGIN (18) */
/* USER CODE END */
}
/** @fn void sciEnableLoopback(sciBASE_t *sci, loopBackType_t Loopbacktype)
* @brief Enable Loopback mode for self test
* @param[in] sci - sci module base address
* @param[in] Loopbacktype - Digital or Analog
*
* This function enables the Loopback mode for self test.
*/
/* SourceId : SCI_SourceId_012 */
/* DesignId : SCI_DesignId_014 */
/* Requirements : HL_SR243 */
void sciEnableLoopback(sciBASE_t *sci, loopBackType_t Loopbacktype)
{
/* USER CODE BEGIN (19) */
/* USER CODE END */
/* Clear Loopback incase enabled already */
sci->IODFTCTRL = 0U;
/* Enable Loopback either in Analog or Digital Mode */
sci->IODFTCTRL = (uint32)0x00000A00U
| (uint32)((uint32)Loopbacktype << 1U);
/* USER CODE BEGIN (20) */
/* USER CODE END */
}
/** @fn void sciDisableLoopback(sciBASE_t *sci)
* @brief Enable Loopback mode for self test
* @param[in] sci - sci module base address
*
* This function disable the Loopback mode.
*/
/* SourceId : SCI_SourceId_013 */
/* DesignId : SCI_DesignId_015 */
/* Requirements : HL_SR244 */
void sciDisableLoopback(sciBASE_t *sci)
{
/* USER CODE BEGIN (21) */
/* USER CODE END */
/* Disable Loopback Mode */
sci->IODFTCTRL = 0x00000500U;
/* USER CODE BEGIN (22) */
/* USER CODE END */
}
/** @fn sciEnableNotification(sciBASE_t *sci, uint32 flags)
* @brief Enable interrupts
* @param[in] sci - sci module base address
* @param[in] flags - Interrupts to be enabled, can be ored value of:
* SCI_FE_INT - framing error,
* SCI_OE_INT - overrun error,
* SCI_PE_INT - parity error,
* SCI_RX_INT - receive buffer ready,
* SCI_TX_INT - transmit buffer ready,
* SCI_WAKE_INT - wakeup,
* SCI_BREAK_INT - break detect
*/
/* SourceId : SCI_SourceId_014 */
/* DesignId : SCI_DesignId_012 */
/* Requirements : HL_SR241 */
void sciEnableNotification(sciBASE_t *sci, uint32 flags)
{
/* USER CODE BEGIN (23) */
/* USER CODE END */
g_sciTransfer_t.mode |= (flags & (uint32)SCI_TX_INT);
sci->SETINT = (flags & (uint32)(~(uint32)(SCI_TX_INT)));
/* USER CODE BEGIN (24) */
/* USER CODE END */
}
/** @fn sciDisableNotification(sciBASE_t *sci, uint32 flags)
* @brief Disable interrupts
* @param[in] sci - sci module base address
* @param[in] flags - Interrupts to be disabled, can be ored value of:
* SCI_FE_INT - framing error,
* SCI_OE_INT - overrun error,
* SCI_PE_INT - parity error,
* SCI_RX_INT - receive buffer ready,
* SCI_TX_INT - transmit buffer ready,
* SCI_WAKE_INT - wakeup,
* SCI_BREAK_INT - break detect
*/
void sciDisableNotification(sciBASE_t *sci, uint32 flags)
{
/* USER CODE BEGIN (25) */
/* USER CODE END */
g_sciTransfer_t.mode &= (uint32)(~(flags & (uint32)SCI_TX_INT));
sci->CLEARINT = (flags & (uint32)(~(uint32)(SCI_TX_INT)));
/* USER CODE BEGIN (26) */
/* USER CODE END */
}
/** @fn void scilinGetConfigValue(sci_config_reg_t *config_reg, config_value_type_t type)
* @brief Get the initial or current values of the SCILIN ( SCI2) configuration registers
*
* @param[in] *config_reg: pointer to the struct to which the initial or current
* value of the configuration registers need to be stored
* @param[in] type: whether initial or current value of the configuration registers need to be stored
* - InitialValue: initial value of the configuration registers will be stored
* in the struct pointed by config_reg
* - CurrentValue: initial value of the configuration registers will be stored
* in the struct pointed by config_reg
*
* This function will copy the initial or current value (depending on the parameter 'type')
* of the configuration registers to the struct pointed by config_reg
*
*/
/* SourceId : SCI_SourceId_016 */
/* DesignId : SCI_DesignId_016 */
/* Requirements : HL_SR247 */
void scilinGetConfigValue(sci_config_reg_t *config_reg, config_value_type_t type)
{
if (type == InitialValue)
{
config_reg->CONFIG_GCR0 = SCILIN_GCR0_CONFIGVALUE;
config_reg->CONFIG_GCR1 = SCILIN_GCR1_CONFIGVALUE;
config_reg->CONFIG_SETINT = SCILIN_SETINT_CONFIGVALUE;
config_reg->CONFIG_SETINTLVL = SCILIN_SETINTLVL_CONFIGVALUE;
config_reg->CONFIG_FORMAT = SCILIN_FORMAT_CONFIGVALUE;
config_reg->CONFIG_BRS = SCILIN_BRS_CONFIGVALUE;
config_reg->CONFIG_PIO0 = SCILIN_PIO0_CONFIGVALUE;
config_reg->CONFIG_PIO1 = SCILIN_PIO1_CONFIGVALUE;
config_reg->CONFIG_PIO6 = SCILIN_PIO6_CONFIGVALUE;
config_reg->CONFIG_PIO7 = SCILIN_PIO7_CONFIGVALUE;
config_reg->CONFIG_PIO8 = SCILIN_PIO8_CONFIGVALUE;
}
else
{
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
config_reg->CONFIG_GCR0 = scilinREG->GCR0;
config_reg->CONFIG_GCR1 = scilinREG->GCR1;
config_reg->CONFIG_SETINT = scilinREG->SETINT;
config_reg->CONFIG_SETINTLVL = scilinREG->SETINTLVL;
config_reg->CONFIG_FORMAT = scilinREG->FORMAT;
config_reg->CONFIG_BRS = scilinREG->BRS;
config_reg->CONFIG_PIO0 = scilinREG->PIO0;
config_reg->CONFIG_PIO1 = scilinREG->PIO1;
config_reg->CONFIG_PIO6 = scilinREG->PIO6;
config_reg->CONFIG_PIO7 = scilinREG->PIO7;
config_reg->CONFIG_PIO8 = scilinREG->PIO8;
}
}
/** @fn void linHighLevelInterrupt(void)
* @brief Level 0 Interrupt for SCILIN
*/
#pragma CODE_STATE(linHighLevelInterrupt, 32)
#pragma INTERRUPT(linHighLevelInterrupt, IRQ)
/* SourceId : SCI_SourceId_021 */
/* DesignId : SCI_DesignId_017 */
/* Requirements : HL_SR245, HL_SR246 */
void linHighLevelInterrupt(void)
{
uint32 vec = scilinREG->INTVECT0;
uint8 byte;
/* USER CODE BEGIN (29) */
/* USER CODE END */
switch (vec)
{
case 1U:
sciNotification(scilinREG, (uint32)SCI_WAKE_INT);
break;
case 3U:
sciNotification(scilinREG, (uint32)SCI_PE_INT);
break;
case 6U:
sciNotification(scilinREG, (uint32)SCI_FE_INT);
break;
case 7U:
sciNotification(scilinREG, (uint32)SCI_BREAK_INT);
break;
case 9U:
sciNotification(scilinREG, (uint32)SCI_OE_INT);
break;
case 11U:
/* receive */
byte = (uint8)(scilinREG->RD & 0x000000FFU);
if (g_sciTransfer_t.rx_length > 0U)
{
*g_sciTransfer_t.rx_data = byte;
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_sciTransfer_t.rx_data++;
g_sciTransfer_t.rx_length--;
if (g_sciTransfer_t.rx_length == 0U)
{
sciNotification(scilinREG, (uint32)SCI_RX_INT);
}
}
break;
case 12U:
/* transmit */
/*SAFETYMCUSW 30 S MR:12.2,12.3 <APPROVED> "Used for data count in Transmit/Receive polling and Interrupt mode" */
--g_sciTransfer_t.tx_length;
if ((g_sciTransfer_t.tx_length) > 0U)
{
/* Check Mode */
if ((scilinREG->GCR1 >> 10U ) & 1U) { // Multi-Buffer Mode Enabled
/* Check Multi Buffer Length */
if (((scilinREG->FORMAT >> 16U ) & 3U) == 0) { // Single Byte/Character
uint8 txdata = *g_sciTransfer_t.tx_data;
#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1)) // write the byte in the correct place
linREG->TDx[3U] = (uint32)(txdata);
#else
linREG->TDx[0U] = (uint32)(txdata);
#endif
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_sciTransfer_t.tx_data++;
} else { // Eight Bytes
if (g_sciTransfer_t.tx_length > 6) {
g_sciTransfer_t.tx_length -= 7; //decrement by the additional 7 other bytes (first byte taken above)
} else {
g_sciTransfer_t.tx_length = 1;
}
#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1)) // write the byte in the correct place
linREG->TDx[3] = (uint32)(*g_sciTransfer_t.tx_data++);
linREG->TDx[2] = (uint32)(*g_sciTransfer_t.tx_data++);
linREG->TDx[1] = (uint32)(*g_sciTransfer_t.tx_data++);
linREG->TDx[0] = (uint32)(*g_sciTransfer_t.tx_data++);
linREG->TDx[7] = (uint32)(*g_sciTransfer_t.tx_data++);
linREG->TDx[6] = (uint32)(*g_sciTransfer_t.tx_data++);
linREG->TDx[5] = (uint32)(*g_sciTransfer_t.tx_data++);
linREG->TDx[4] = (uint32)(*g_sciTransfer_t.tx_data++);
#else
/* First 32bits */
*(uint32 *)(&linREG->TDx[0U]) = *(uint32 *)(&*g_sciTransfer_t.tx_data); // Writes are broken in to 32bits for fastest transfer
// 64bit transfers are not allowed because the distination address is unaligned
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_sciTransfer_t.tx_data += 4;
/* Second 32bits */
*(uint32 *)(&linREG->TDx[4U]) = *(uint32 *)(&*g_sciTransfer_t.tx_data); // Writes are broken in to 32bits for fastest transfer
// 64bit transfers are not allowed because the distination address is unaligned
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_sciTransfer_t.tx_data += 4;
#endif
}
} else { // Single Buffer Mode
uint8 txdata = *g_sciTransfer_t.tx_data;
scilinREG->TD = (uint32)(txdata);
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_sciTransfer_t.tx_data++;
}
}
else
{
scilinREG->CLEARINT = (uint32)SCI_TX_INT;
sciNotification(scilinREG, (uint32)SCI_TX_INT);
}
break;
default:
/* phantom interrupt, clear flags and return */
scilinREG->FLR = ~scilinREG->SETINTLVL & 0x07000303U;
break;
}
/* USER CODE BEGIN (30) */
/* USER CODE END */
}
/* USER CODE BEGIN (31) */
/* USER CODE END */
/** @file sci.c
* @brief SCI Driver Implementation File
* @date 17.Nov.2014
* @version 04.02.00
*
*/
/*
* Copyright (C) 2009-2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* USER CODE BEGIN (0) */
/* USER CODE END */
#include "sci.h"
#include "sys_vim.h"
/* USER CODE BEGIN (1) */
/* USER CODE END */
/** @struct g_sciTransfer
* @brief Interrupt mode globals
*
*/
static struct g_sciTransfer
{
uint32 mode; /* Used to check for TX interrupt Enable */
uint32 tx_length; /* Transmit data length in number of Bytes */
uint32 rx_length; /* Receive data length in number of Bytes */
uint8 * tx_data; /* Transmit data pointer */
uint8 * rx_data; /* Receive data pointer */
} g_sciTransfer_t;
/** @fn void sciInit(void)
* @brief Initializes the SCI Driver
*
* This function initializes the SCI module.
*/
/* SourceId : SCI_SourceId_001 */
/* DesignId : SCI_DesignId_001 */
/* Requirements : HL_SR230 */
void sciInit(void)
{
/* USER CODE BEGIN (2) */
/* USER CODE END */
/** @b initialize @b SCILIN */
/** - bring SCI out of reset */
scilinREG->GCR0 = 0U;
scilinREG->GCR0 = 1U;
/** - Disable all interrupts */
scilinREG->CLEARINT = 0xFFFFFFFFU;
scilinREG->CLEARINTLVL = 0xFFFFFFFFU;
/** - global control 1 */
scilinREG->GCR1 = (uint32)((uint32)1U << 25U) /* enable transmit */
| (uint32)((uint32)1U << 24U) /* enable receive */
| (uint32)((uint32)1U << 5U) /* internal clock (device has no clock pin) */
| (uint32)((uint32)(2U-1U) << 4U) /* number of stop bits */
| (uint32)((uint32)0U << 3U) /* even parity, otherwise odd */
| (uint32)((uint32)0U << 2U) /* enable parity */
| (uint32)((uint32)1U << 1U); /* asynchronous timing mode */
/** - set baudrate */
scilinREG->BRS = 520U; /* baudrate */
/** - transmission length */
scilinREG->FORMAT = 8U - 1U; /* length */
/** - set SCI pins functional mode */
scilinREG->PIO0 = (uint32)((uint32)1U << 2U) /* tx pin */
| (uint32)((uint32)1U << 1U); /* rx pin */
/** - set SCI pins default output value */
scilinREG->PIO3 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */
/** - set SCI pins output direction */
scilinREG->PIO1 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */
/** - set SCI pins open drain enable */
scilinREG->PIO6 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */
/** - set SCI pins pullup/pulldown enable */
scilinREG->PIO7 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */
/** - set SCI pins pullup/pulldown select */
scilinREG->PIO8 = (uint32)((uint32)1U << 2U) /* tx pin */
| (uint32)((uint32)1U << 1U); /* rx pin */
/** - set interrupt level */
scilinREG->SETINTLVL = (uint32)((uint32)0U << 26U) /* Framing error */
| (uint32)((uint32)0U << 25U) /* Overrun error */
| (uint32)((uint32)0U << 24U) /* Parity error */
| (uint32)((uint32)0U << 9U) /* Receive */
| (uint32)((uint32)0U << 8U) /* Transmit */
| (uint32)((uint32)0U << 1U) /* Wakeup */
| (uint32)((uint32)0U << 0U); /* Break detect */
/** - set interrupt enable */
scilinREG->SETINT = (uint32)((uint32)0U << 26U) /* Framing error */
| (uint32)((uint32)0U << 25U) /* Overrun error */
| (uint32)((uint32)0U << 24U) /* Parity error */
| (uint32)((uint32)0U << 9U) /* Receive */
| (uint32)((uint32)0U << 1U) /* Wakeup */
| (uint32)((uint32)0U); /* Break detect */
/** - initialize global transfer variables */
g_sciTransfer_t.mode = (uint32)0U << 8U;
g_sciTransfer_t.tx_length = 0U;
g_sciTransfer_t.rx_length = 0U;
/** - Finaly start SCILIN */
scilinREG->GCR1 |= 0x80U;
/* USER CODE BEGIN (3) */
/* USER CODE END */
}
/** @fn void sciSetFunctional(sciBASE_t *sci, uint32 port)
* @brief Change functional behavior of pins at runtime.
* @param[in] sci - sci module base address
* @param[in] port - Value to write to PIO0 register
*
* Change the value of the PCPIO0 register at runtime, this allows to
* dynamically change the functionality of the SCI pins between functional
* and GIO mode.
*/
/* SourceId : SCI_SourceId_002 */
/* DesignId : SCI_DesignId_002 */
/* Requirements : HL_SR231 */
void sciSetFunctional(sciBASE_t *sci, uint32 port)
{
/* USER CODE BEGIN (4) */
/* USER CODE END */
sci->PIO0 = port;
/* USER CODE BEGIN (5) */
/* USER CODE END */
}
/** @fn void sciSetBaudrate(sciBASE_t *sci, uint32 baud)
* @brief Change baudrate at runtime.
* @param[in] sci - sci module base address
* @param[in] baud - baudrate in Hz
*
* Change the SCI baudrate at runtime.
*/
/* SourceId : SCI_SourceId_003 */
/* DesignId : SCI_DesignId_003 */
/* Requirements : HL_SR232 */
void sciSetBaudrate(sciBASE_t *sci, uint32 baud)
{
float64 vclk = 80.000 * 1000000.0;
uint32 f = ((sci->GCR1 & 2U) == 2U) ? 16U : 1U;
uint32 temp;
float64 temp2;
/* USER CODE BEGIN (6) */
/* USER CODE END */
/*SAFETYMCUSW 96 S MR:6.1 <APPROVED> "Calculations including int and float cannot be avoided" */
temp = (f*(baud + 1U));
temp2 = ((vclk)/((float64)temp));
sci->BRS = (uint32)((uint32)temp2 & 0x00FFFFFFU);
/* USER CODE BEGIN (7) */
/* USER CODE END */
}
/** @fn uint32 sciIsTxReady(sciBASE_t *sci)
* @brief Check if Tx buffer empty
* @param[in] sci - sci module base address
*
* @return The TX ready flag
*
* Checks to see if the Tx buffer ready flag is set, returns
* 0 is flags not set otherwise will return the Tx flag itself.
*/
/* SourceId : SCI_SourceId_004 */
/* DesignId : SCI_DesignId_004 */
/* Requirements : HL_SR233 */
uint32 sciIsTxReady(sciBASE_t *sci)
{
/* USER CODE BEGIN (8) */
/* USER CODE END */
return sci->FLR & (uint32)SCI_TX_INT;
}
/** @fn void sciSendByte(sciBASE_t *sci, uint8 byte)
* @brief Send Byte
* @param[in] sci - sci module base address
* @param[in] byte - byte to transfer
*
* Sends a single byte in polling mode, will wait in the
* routine until the transmit buffer is empty before sending
* the byte. Use sciIsTxReady to check for Tx buffer empty
* before calling sciSendByte to avoid waiting.
*/
/* SourceId : SCI_SourceId_005 */
/* DesignId : SCI_DesignId_005 */
/* Requirements : HL_SR234 */
void sciSendByte(sciBASE_t *sci, uint8 byte)
{
/* USER CODE BEGIN (9) */
/* USER CODE END */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((sci->FLR & (uint32)SCI_TX_INT) == 0U)
{
} /* Wait */
sci->TD = byte;
/* USER CODE BEGIN (10) */
/* USER CODE END */
}
/** @fn void sciSend(sciBASE_t *sci, uint32 length, uint8 * data)
* @brief Send Data
* @param[in] sci - sci module base address
* @param[in] length - number of data words to transfer
* @param[in] data - pointer to data to send
*
* Send a block of data pointed to by 'data' and 'length' bytes
* long. If interrupts have been enabled the data is sent using
* interrupt mode, otherwise polling mode is used. In interrupt
* mode transmission of the first byte is started and the routine
* returns immediately, sciSend must not be called again until the
* transfer is complete, when the sciNotification callback will
* be called. In polling mode, sciSend will not return until
* the transfer is complete.
*
* @note if data word is less than 8 bits, then the data must be left
* aligned in the data byte.
*/
/* SourceId : SCI_SourceId_006 */
/* DesignId : SCI_DesignId_006 */
/* Requirements : HL_SR235 */
void sciSend(sciBASE_t *sci, uint32 length, uint8 * data)
{
uint8 txdata;
/* USER CODE BEGIN (11) */
/* USER CODE END */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Mode variable is configured in sciEnableNotification()" */
if ((g_sciTransfer_t.mode & (uint32)SCI_TX_INT) != 0U)
{
/* we are in interrupt mode */
g_sciTransfer_t.tx_length = length;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
g_sciTransfer_t.tx_data = data;
/* start transmit by sending first byte */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
txdata = *g_sciTransfer_t.tx_data;
sci->TD = (uint32)(txdata);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_sciTransfer_t.tx_data++;
sci->SETINT = (uint32)SCI_TX_INT;
}
else
{
/* send the data */
while (length > 0U)
{
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((sci->FLR & (uint32)SCI_TX_INT) == 0U)
{
} /* Wait */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
txdata = *data;
sci->TD = (uint32)(txdata);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
data++;
length--;
}
}
/* USER CODE BEGIN (12) */
/* USER CODE END */
}
/** @fn uint32 sciIsRxReady(sciBASE_t *sci)
* @brief Check if Rx buffer full
* @param[in] sci - sci module base address
*
* @return The Rx ready flag
*
* Checks to see if the Rx buffer full flag is set, returns
* 0 is flags not set otherwise will return the Rx flag itself.
*/
/* SourceId : SCI_SourceId_007 */
/* DesignId : SCI_DesignId_007 */
/* Requirements : HL_SR236 */
uint32 sciIsRxReady(sciBASE_t *sci)
{
/* USER CODE BEGIN (13) */
/* USER CODE END */
return sci->FLR & (uint32)SCI_RX_INT;
}
/** @fn uint32 sciIsIdleDetected(sciBASE_t *sci)
* @brief Check if Idle Period is Detected
* @param[in] sci - sci module base address
*
* @return The Idle flag
*
* Checks to see if the SCI Idle flag is set, returns 0 is flags
* not set otherwise will return the Ilde flag itself.
*/
/* SourceId : SCI_SourceId_008 */
/* DesignId : SCI_DesignId_008 */
/* Requirements : HL_SR237 */
uint32 sciIsIdleDetected(sciBASE_t *sci)
{
/* USER CODE BEGIN (14) */
/* USER CODE END */
return sci->FLR & (uint32)SCI_IDLE;
}
/** @fn uint32 sciRxError(sciBASE_t *sci)
* @brief Return Rx Error flags
* @param[in] sci - sci module base address
*
* @return The Rx error flags
*
* Returns the Rx framing, overrun and parity errors flags,
* also clears the error flags before returning.
*/
/* SourceId : SCI_SourceId_009 */
/* DesignId : SCI_DesignId_009 */
/* Requirements : HL_SR238 */
uint32 sciRxError(sciBASE_t *sci)
{
uint32 status = (sci->FLR & ((uint32)SCI_FE_INT | (uint32)SCI_OE_INT |(uint32)SCI_PE_INT));
/* USER CODE BEGIN (15) */
/* USER CODE END */
sci->FLR = ((uint32)SCI_FE_INT | (uint32)SCI_OE_INT | (uint32)SCI_PE_INT);
return status;
}
/** @fn uint32 sciReceiveByte(sciBASE_t *sci)
* @brief Receive Byte
* @param[in] sci - sci module base address
*
* @return Received byte
*
* Receives a single byte in polling mode. If there is
* not a byte in the receive buffer the routine will wait
* until one is received. Use sciIsRxReady to check to
* see if the buffer is full to avoid waiting.
*/
/* SourceId : SCI_SourceId_010 */
/* DesignId : SCI_DesignId_010 */
/* Requirements : HL_SR239 */
uint32 sciReceiveByte(sciBASE_t *sci)
{
/* USER CODE BEGIN (16) */
/* USER CODE END */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((sci->FLR & (uint32)SCI_RX_INT) == 0U)
{
} /* Wait */
return (sci->RD & (uint32)0x000000FFU);
}
/** @fn void sciReceive(sciBASE_t *sci, uint32 length, uint8 * data)
* @brief Receive Data
* @param[in] sci - sci module base address
* @param[in] length - number of data words to transfer
* @param[in] data - pointer to data buffer to receive data
*
* Receive a block of 'length' bytes long and place it into the
* data buffer pointed to by 'data'. If interrupts have been
* enabled the data is received using interrupt mode, otherwise
* polling mode is used. In interrupt mode receive is setup and
* the routine returns immediately, sciReceive must not be called
* again until the transfer is complete, when the sciNotification
* callback will be called. In polling mode, sciReceive will not
* return until the transfer is complete.
*/
/* SourceId : SCI_SourceId_011 */
/* DesignId : SCI_DesignId_011 */
/* Requirements : HL_SR240 */
void sciReceive(sciBASE_t *sci, uint32 length, uint8 * data)
{
/* USER CODE BEGIN (17) */
/* USER CODE END */
if ((sci->SETINT & (uint32)SCI_RX_INT) == (uint32)SCI_RX_INT)
{
/* we are in interrupt mode */
/* clear error flags */
sci->FLR = ((uint32) SCI_FE_INT | (uint32) SCI_OE_INT | (uint32) SCI_PE_INT);
g_sciTransfer_t.rx_length = length;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
g_sciTransfer_t.rx_data = data;
}
else
{
/*SAFETYMCUSW 30 S MR:12.2,12.3 <APPROVED> "Used for data count in Transmit/Receive polling and Interrupt mode" */
while (length > 0U)
{
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((sci->FLR & (uint32)SCI_RX_INT) == 0U)
{
} /* Wait */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
*data = (uint8)(sci->RD & 0x000000FFU);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer operation required." */
data++;
length--;
}
}
/* USER CODE BEGIN (18) */
/* USER CODE END */
}
/** @fn void sciEnableLoopback(sciBASE_t *sci, loopBackType_t Loopbacktype)
* @brief Enable Loopback mode for self test
* @param[in] sci - sci module base address
* @param[in] Loopbacktype - Digital or Analog
*
* This function enables the Loopback mode for self test.
*/
/* SourceId : SCI_SourceId_012 */
/* DesignId : SCI_DesignId_014 */
/* Requirements : HL_SR243 */
void sciEnableLoopback(sciBASE_t *sci, loopBackType_t Loopbacktype)
{
/* USER CODE BEGIN (19) */
/* USER CODE END */
/* Clear Loopback incase enabled already */
sci->IODFTCTRL = 0U;
/* Enable Loopback either in Analog or Digital Mode */
sci->IODFTCTRL = (uint32)0x00000A00U
| (uint32)((uint32)Loopbacktype << 1U);
/* USER CODE BEGIN (20) */
/* USER CODE END */
}
/** @fn void sciDisableLoopback(sciBASE_t *sci)
* @brief Enable Loopback mode for self test
* @param[in] sci - sci module base address
*
* This function disable the Loopback mode.
*/
/* SourceId : SCI_SourceId_013 */
/* DesignId : SCI_DesignId_015 */
/* Requirements : HL_SR244 */
void sciDisableLoopback(sciBASE_t *sci)
{
/* USER CODE BEGIN (21) */
/* USER CODE END */
/* Disable Loopback Mode */
sci->IODFTCTRL = 0x00000500U;
/* USER CODE BEGIN (22) */
/* USER CODE END */
}
/** @fn sciEnableNotification(sciBASE_t *sci, uint32 flags)
* @brief Enable interrupts
* @param[in] sci - sci module base address
* @param[in] flags - Interrupts to be enabled, can be ored value of:
* SCI_FE_INT - framing error,
* SCI_OE_INT - overrun error,
* SCI_PE_INT - parity error,
* SCI_RX_INT - receive buffer ready,
* SCI_TX_INT - transmit buffer ready,
* SCI_WAKE_INT - wakeup,
* SCI_BREAK_INT - break detect
*/
/* SourceId : SCI_SourceId_014 */
/* DesignId : SCI_DesignId_012 */
/* Requirements : HL_SR241 */
void sciEnableNotification(sciBASE_t *sci, uint32 flags)
{
/* USER CODE BEGIN (23) */
/* USER CODE END */
g_sciTransfer_t.mode |= (flags & (uint32)SCI_TX_INT);
sci->SETINT = (flags & (uint32)(~(uint32)(SCI_TX_INT)));
/* USER CODE BEGIN (24) */
/* USER CODE END */
}
/** @fn sciDisableNotification(sciBASE_t *sci, uint32 flags)
* @brief Disable interrupts
* @param[in] sci - sci module base address
* @param[in] flags - Interrupts to be disabled, can be ored value of:
* SCI_FE_INT - framing error,
* SCI_OE_INT - overrun error,
* SCI_PE_INT - parity error,
* SCI_RX_INT - receive buffer ready,
* SCI_TX_INT - transmit buffer ready,
* SCI_WAKE_INT - wakeup,
* SCI_BREAK_INT - break detect
*/
void sciDisableNotification(sciBASE_t *sci, uint32 flags)
{
/* USER CODE BEGIN (25) */
/* USER CODE END */
g_sciTransfer_t.mode &= (uint32)(~(flags & (uint32)SCI_TX_INT));
sci->CLEARINT = (flags & (uint32)(~(uint32)(SCI_TX_INT)));
/* USER CODE BEGIN (26) */
/* USER CODE END */
}
/** @fn void scilinGetConfigValue(sci_config_reg_t *config_reg, config_value_type_t type)
* @brief Get the initial or current values of the SCILIN ( SCI2) configuration registers
*
* @param[in] *config_reg: pointer to the struct to which the initial or current
* value of the configuration registers need to be stored
* @param[in] type: whether initial or current value of the configuration registers need to be stored
* - InitialValue: initial value of the configuration registers will be stored
* in the struct pointed by config_reg
* - CurrentValue: initial value of the configuration registers will be stored
* in the struct pointed by config_reg
*
* This function will copy the initial or current value (depending on the parameter 'type')
* of the configuration registers to the struct pointed by config_reg
*
*/
/* SourceId : SCI_SourceId_016 */
/* DesignId : SCI_DesignId_016 */
/* Requirements : HL_SR247 */
void scilinGetConfigValue(sci_config_reg_t *config_reg, config_value_type_t type)
{
if (type == InitialValue)
{
config_reg->CONFIG_GCR0 = SCILIN_GCR0_CONFIGVALUE;
config_reg->CONFIG_GCR1 = SCILIN_GCR1_CONFIGVALUE;
config_reg->CONFIG_SETINT = SCILIN_SETINT_CONFIGVALUE;
config_reg->CONFIG_SETINTLVL = SCILIN_SETINTLVL_CONFIGVALUE;
config_reg->CONFIG_FORMAT = SCILIN_FORMAT_CONFIGVALUE;
config_reg->CONFIG_BRS = SCILIN_BRS_CONFIGVALUE;
config_reg->CONFIG_PIO0 = SCILIN_PIO0_CONFIGVALUE;
config_reg->CONFIG_PIO1 = SCILIN_PIO1_CONFIGVALUE;
config_reg->CONFIG_PIO6 = SCILIN_PIO6_CONFIGVALUE;
config_reg->CONFIG_PIO7 = SCILIN_PIO7_CONFIGVALUE;
config_reg->CONFIG_PIO8 = SCILIN_PIO8_CONFIGVALUE;
}
else
{
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
config_reg->CONFIG_GCR0 = scilinREG->GCR0;
config_reg->CONFIG_GCR1 = scilinREG->GCR1;
config_reg->CONFIG_SETINT = scilinREG->SETINT;
config_reg->CONFIG_SETINTLVL = scilinREG->SETINTLVL;
config_reg->CONFIG_FORMAT = scilinREG->FORMAT;
config_reg->CONFIG_BRS = scilinREG->BRS;
config_reg->CONFIG_PIO0 = scilinREG->PIO0;
config_reg->CONFIG_PIO1 = scilinREG->PIO1;
config_reg->CONFIG_PIO6 = scilinREG->PIO6;
config_reg->CONFIG_PIO7 = scilinREG->PIO7;
config_reg->CONFIG_PIO8 = scilinREG->PIO8;
}
}
/** @fn void linHighLevelInterrupt(void)
* @brief Level 0 Interrupt for SCILIN
*/
#pragma CODE_STATE(linHighLevelInterrupt, 32)
#pragma INTERRUPT(linHighLevelInterrupt, IRQ)
/* SourceId : SCI_SourceId_021 */
/* DesignId : SCI_DesignId_017 */
/* Requirements : HL_SR245, HL_SR246 */
void linHighLevelInterrupt(void)
{
uint32 vec = scilinREG->INTVECT0;
uint8 byte;
/* USER CODE BEGIN (29) */
/* USER CODE END */
switch (vec)
{
case 1U:
sciNotification(scilinREG, (uint32)SCI_WAKE_INT);
break;
case 3U:
sciNotification(scilinREG, (uint32)SCI_PE_INT);
break;
case 6U:
sciNotification(scilinREG, (uint32)SCI_FE_INT);
break;
case 7U:
sciNotification(scilinREG, (uint32)SCI_BREAK_INT);
break;
case 9U:
sciNotification(scilinREG, (uint32)SCI_OE_INT);
break;
case 11U:
/* receive */
byte = (uint8)(scilinREG->RD & 0x000000FFU);
if (g_sciTransfer_t.rx_length > 0U)
{
*g_sciTransfer_t.rx_data = byte;
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_sciTransfer_t.rx_data++;
g_sciTransfer_t.rx_length--;
if (g_sciTransfer_t.rx_length == 0U)
{
sciNotification(scilinREG, (uint32)SCI_RX_INT);
}
}
break;
case 12U:
/* transmit */
/*SAFETYMCUSW 30 S MR:12.2,12.3 <APPROVED> "Used for data count in Transmit/Receive polling and Interrupt mode" */
--g_sciTransfer_t.tx_length;
if ((g_sciTransfer_t.tx_length) > 0U)
{
uint8 txdata = *g_sciTransfer_t.tx_data;
scilinREG->TD = (uint32)(txdata);
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
g_sciTransfer_t.tx_data++;
}
else
{
scilinREG->CLEARINT = SCI_TX_INT;
sciNotification(scilinREG, (uint32)SCI_TX_INT);
}
break;
default:
/* phantom interrupt, clear flags and return */
scilinREG->FLR = ~scilinREG->SETINTLVL & 0x07000303U;
break;
}
/* USER CODE BEGIN (30) */
/* USER CODE END */
}
/* USER CODE BEGIN (31) */
/* USER CODE END */