#define RESPONSE_DATA_LEN   8           // Length of expected data (1-8 bytes)
#define MY_RESPONDER_ID     0x15        // The ID this responder will respond to

//
// Globals
//
volatile uint32_t level0Count = 0;
volatile uint32_t vectorOffset = 0;
volatile uint8_t lastRxID = 0;
volatile bool frameReceived = false;

uint16_t rxData[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

//
// Function Prototypes
//
__interrupt void level0ISR(void)
{
    uint32_t base = LINA_BASE;

    level0Count++;

    // Read the interrupt vector offset
    vectorOffset = LIN_getInterruptLine0Offset(base);

    // ============================================================
    //  ONLY handle RX data interrupt
    // ============================================================
    if (vectorOffset == LIN_VECT_RX)
    {
        // Read the received data
        LIN_getData(base, rxData);

        // Set flag to indicate frame received
        frameReceived = true;
    }

    // Clear interrupt status - ONLY RX
    LIN_clearInterruptStatus(base, LIN_INT_RX);
    LIN_clearGlobalInterruptStatus(base, LIN_INTERRUPT_LINE0);

    // Acknowledge this interrupt (PIE group 6)
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6);
}


void LIN_Slave_HW_Init(void)
{
    uint32_t base;
    base = LINA_BASE;
    GPIO_setPinConfig(DEVICE_GPIO_CFG_LINTXA);   // LINA_TX
    GPIO_setPinConfig(DEVICE_GPIO_CFG_LINRXA);   // LINA_RX

    // Register interrupt handler
    //
    Interrupt_register(INT_LINA_0, &level0ISR);
    Interrupt_enable(INT_LINA_0);

    // Check the arguments.
    //
    ASSERT(LIN_isBaseValid(LINA_BASE));

    EALLOW;
    // Reset LIN module
    // Release from hard reset
    LIN_disableModule(base);
    LIN_enableModule(base);
    // Enter Software Reset State
    LIN_enterSoftwareReset(base);
    // Enable LIN Mode
    LIN_disableSCIMode(base);
    // Set LIN mode to Commander
    LIN_setLINMode(base, LIN_MODE_LIN_RESPONDER);

    // Enable Fixed baud rate mode
    LIN_disableAutomaticBaudrate(base);

    // Use the set frame length and not ID4/ID5 bits for length control
    LIN_setCommMode(base, LIN_COMM_LIN_USELENGTHVAL);
    // Setup to continue operating on emulation suspend
    LIN_setDebugSuspendMode(base, LIN_DEBUG_COMPLETE);
    // Use Enhanced Checksum
    LIN_setChecksumType(base, LIN_CHECKSUM_ENHANCED);

    // Message filtering uses responder task ID byte
    LIN_setMessageFiltering(base, LIN_MSG_FILTER_IDRESPONDER);
    // Disable Internal loopback for external communication
    LIN_disableIntLoopback(base);

    // Enable multi-buffer mode
    LIN_disableMultibufferMode(base);
    LIN_disableParity(base);

    LIN_setBaudRatePrescaler(base, 124U, 50U);
    LIN_setMaximumBaudRate(base, 120000000U, 20000U);

    // Set response field to 8 byte
    LIN_setFrameLength(base, 8U);

    LIN_setSyncFields(base, 5U, 3U);

    // Set Mask ID so TX/RX match will always happen
    LIN_setTxMask(base, 0xFFU);
    LIN_setRxMask(base, 0xFFU);

    // Disable IODFT testing and external loopback mode
    LIN_disableExtLoopback(base);

    // Finally exit SW reset and enter LIN ready state
    LIN_exitSoftwareReset(base);
    EDIS;
    LIN_enableGlobalInterrupt(LINA_BASE, LIN_INTERRUPT_LINE0);
    LIN_clearGlobalInterruptStatus(LINA_BASE, LIN_INTERRUPT_LINE0);
    LIN_enableInterrupt(LINA_BASE, LIN_INT_ID);

    

    
}
static void test_lin()
{
    uint32_t i, dataIndex;
    uint16_t txID, error;
    LIN_Slave_HW_Init();

    while(1)
    {
        if (frameReceived)
        {
            // Process received data in rxData[]
            // For example: copy, validate, or forward the data

            frameReceived = false;  // Clear flag for next frame
        }

        // Yield to other tasks
        asm(" NOP");
    }
}

void main(void)
{
    // Initialize device clock and peripherals
    Device_init();                  // call the function in device.c

    // Disable pin locks and enable internal pullups.
    Device_initGPIO();              // call the function in device.c

    DINT;
    // Initializes PIE and clears PIE registers. Disables CPU interrupts.
    Interrupt_initModule();         // call the function in driverlib.lib

    // Initializes the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    Interrupt_initVectorTable();    // call the function in driverlib.lib

    EINT;
    ERTM;
    test_lin();
}
