This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

HALCOGEN: SCI difference in versions 04.02.00

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 */

  • Hi Daw,

    The HALCoGen doesn't support SCI multibuffer mode. The attached 2 files are created for different devices which have different frequency of VCLK. The difference between those 2 files is the workaround in ISR (TX) to use the multibuffer mode.
  • *The HALC0Gen doesn't support SCI multibuffer mode.

    Yes. I know that and I see this in GUI of HALC0Gen. (I ask, if it is wanted or the setup will be more advanced in future?)

    *The attached 2 files are created for different devices which have different frequency of VCLK

    I believe that both of them have this multi buffer functionality in SCI and the clock speed really doesn't matter in this context. The main point was find way to work in buffered mode.

    *The difference between those 2 files is the workaround in ISR (TX) to use the multibuffer mode.

    Yes, exactly! This is the reason why this "part of code" I expected in HALC0Gen code template for SCI (OK for not supporting this in GUI, but better library code). So I found it in standalone example by (by Dave Livingston) Thx  :-(

    Thanks

    D.