//***************************************************************************** // (C) Automotive Lighting China // // Automotive Lighting Reutlingen GmbH owns all the rights to this work. // This work shall not be copied, reproduced, used, modified, transferred // or its information shall not be disclosed without the prior written // authorization of Automotive Lighting China. //***************************************************************************** // ---------------------------------------------------------------------------- /// \file CddTps929240.c /// /// \author f24301c [mailto:walker.lv@marelli.com] /// /// \date 06.21.2024 /// /// \brief CddTps929240 RTE interface /// original from MES-Engineering, re-constructed by me. /// // ---------------------------------------------------------------------------- /****************************************************************************** ** Includes ** ******************************************************************************/ #include #include "CddTps929240.h" #include "../Api/CddTps929240_api.h" #include "../Cfg/CddTps929x_PBcfg.h" #include "../Cfg/CddTps929x_Lcfg.h" #include "../Cfg/CddTps929x_Protocol_PBcfg.h" #include "../Common/Tps929xType.h" #include "Protocol_Flexwire.h" #include "CddTps929240_PwmOut.h" #include "CddTps929240_Diag.h" #include #include #include #include "Rte_ctadCddTps929.h" /******************************************************************************* ** Private Macro Definitions ** *******************************************************************************/ /******************************************************************************* ** Private Variable Declarations ** *******************************************************************************/ /******************************************************************************* ** Public Variable Declarations ** *******************************************************************************/ #if (TPS929240_SUPPORT_EEPROM_PROGRAMING == STD_ON) uint8 Tps929_EepMode = TPS929_EEPMODE; #endif /******************************************************************************* ** Private Function Declarations ** *******************************************************************************/ STATIC_AL void CddTps929240_MemoryInit(void); STATIC_AL void CddTps929240_UpdateDeviceState(const Device_Tps929x_t* device, uint8 primitive, uint8* buff, uint8 buffLen); /******************************************************************************* ** Public Function Declarations ** *******************************************************************************/ //----------------------------------------------------------------------------- /// \brief Tps929x device instance memory initialization /// /// \descr internal API. initial memory of Tps929x /// /// \param none /// /// \return none //----------------------------------------------------------------------------- STATIC_AL void CddTps929240_MemoryInit(void) { for (uint16 idx = 0; idx < device_Tps929240_number; idx++) { const Device_Tps929x_t* aDevice = &device_Tps929240_Instances[idx]; // skip .configuration, it is hard coded initialization, check CddTps929x_PBcfg // skip .shadow, it is hard coded initialization, check CddTps929x_PBcfg //memset(aDevice->shadow, 0, sizeof(DeviceShadow_Tps929x_t)); aDevice->state[idx].commErrorCounter = 0; aDevice->state[idx].crcErrorCounter = 0; aDevice->state[idx].deviceState = DeviceState_Uninitial; // using ROM table to initial device's primitive response descriptor memcpy(aDevice->primitiveResp->primitiveRespDesc, primRespDescInitTable_Tps929240, primDescInitTable_Tps929240_number * sizeof(PrimitiveResponseBufDesc_t)); } } //----------------------------------------------------------------------------- /// \brief RTE Cdd initial runnable /// /// \descr internal API. do the general BUS state clear up when a /// transaction done /// /// \param none /// /// \return none //----------------------------------------------------------------------------- void Rte_riCddTps929Init(void) { CddTps929240_MemoryInit(); } void CddTps929240_DrvInit(void* pData) { (void)pData; CddTps929240_PwmOutInit(); CddTps929240_UnlockInit(); CddTps929240_EnCh(NULL_PTR); // read register: FLEXWIRE0 //FlexWire_Ser2(0, 1, FLEXWIRE0, FALSE, Prim_Tps929x_READ_REGISTER, NULL_PTR, 0); } //----------------------------------------------------------------------------- /// \brief period CddTps929 runnable /// /// \descr execute schedule /// /// \param none /// /// \return none //----------------------------------------------------------------------------- void Rte_rpCddTps929x5ms(void) { static uint32 ticks = 0; ticks++; #if ( TPS929240_SUPPORT_EEPROM_PROGRAMING == STD_ON) if (Tps929_EepMode == TPS929_NORMAL) { #endif /* End of TPS929240_SUPPORT_EEPROM_PROGRAMING */ for (uint8 tableIdx = 0u; tableIdx < scheduleTable_number; tableIdx++) { UUE_ScheduleTask_t* task = (UUE_ScheduleTask_t*)&Tps929240_ScheduleTable[tableIdx]; if (ticks >= task->offset) { // pass start delay if ((task->entry) && ((ticks - task->offset) % task->period) == 0) // multiple of period { if (task->period == 0) { if (task->offset == ticks) { task->entry(NULL_PTR); // non-period task } } else { task->entry(NULL_PTR); // currently no data to pass to task entry } } } } #if ( TPS929240_SUPPORT_EEPROM_PROGRAMING == STD_ON) } else { #ifdef TPS929EEP_ALL_ADDR if (Tps929_EepDevNum < TPS929_EEP_DEV_NUM) { CddTps929240_EepUpdata(Tps929_EepDev[Tps929_EepDevNum].UartCh, Tps929_EepDev[Tps929_EepDevNum].DevAddr, &Tps929_EepMode); CddTps929240_Transmit(Tps929_EepDev[Tps929_EepDevNum].UartCh, UART_CYCLE); if (Tps929_EepMode == TPS929_NORMAL) { Tps929_EepMode = TPS929_EEPMODE; Tps929_EepDevNum++; /* Program the next device */ } } else { Tps929_EepMode = TPS929_NORMAL; } #else CddTps929240_EepUpdata(TPS929_EEP_UARTCH, TPS929_EEP_ADDR, &Tps929_EepMode); CddTps929240_Transmit(TPS929_EEP_UARTCH, UART_CYCLE); #endif /* End of TPS929EEP_ALL_ADDR */ } #endif /* End of TPS929240_SUPPORT_EEPROM_PROGRAMING */ } //----------------------------------------------------------------------------- /// \brief handle primitive response /// /// \descr executed every 5ms. process response, shadows, PWM, pwm_en, crc, error... /// /// \param pData: not used, reserved for future /// /// \return none //----------------------------------------------------------------------------- void CddTps929240_ProcessResponse(void* pData) { (void)pData; // in theory, there would be device_Tps929240_number * Prim_Tps929x_NUMBER response // to be process, especially for crc calculation. we may not be able to process all // response in only cycle uint8 deviceIdx = 0; for (deviceIdx = 0; deviceIdx < device_Tps929240_number; deviceIdx++) { const Device_Tps929x_t* device = &device_Tps929240_Instances[deviceIdx]; // respDesc is array PrimitiveResponseBufDesc_t* respDesc = device->primitiveResp->primitiveRespDesc; for (uint8 primitiveIdx = 0; primitiveIdx < Prim_Tps929x_NUMBER; primitiveIdx++) { if (respDesc[primitiveIdx].dirtyFlag) { // response updated //step 1. check LL error if (respDesc->transactionErr != TransactionError_NoError) { // accumulate transaction error to device error if (device->state->commErrorCounter < UTIL_MAX_OF_TYPE(uint16)) { // all LL error consider as communication error device->state->commErrorCounter++; } else { // keep error counter max } } else { uint8* respBuff = TPS929X_GET_PRIMITIVE_RESPBUF(device_Tps929240_Instances[deviceIdx].primitiveResp, primitiveIdx); uint8 respBuffLen = TPS929X_GET_PRIMITIVE_RESPBUFLEN(device_Tps929240_Instances[deviceIdx].primitiveResp, primitiveIdx); device->state->commErrorCounter = 0; // NOTENOTE: one succeeded transaction reset LL error // step 2, check crc if ((respBuff[respBuffLen - 1] & TPS929240_CRCMASK) != ((FlexWire_Tps929240_CRC(respBuff, respBuffLen - 1) & TPS929240_CRCMASK))) { // crc failure if (device->state->crcErrorCounter < UTIL_MAX_OF_TYPE(uint16)) { device->state->crcErrorCounter++; } else { // keep crc error counter max } } else { // crc check passed if (device->state->crcErrorCounter > 0) device->state->crcErrorCounter--; // step 3, process response buffer CddTps929240_UpdateDeviceState(device, primitiveIdx, respBuff, respBuffLen - 1); // skip crc byte } } respDesc[primitiveIdx].dirtyFlag = 0; // clear flag } else { // nothing to do } } } } //----------------------------------------------------------------------------- /// \brief process response data of one primitive /// /// \descr update slave device information base on response buff /// /// \param device: slave device object /// primitive: which primitive is being process /// buff: primitive response buff, not include crc from slave /// buffLen: buff length /// /// \return none //----------------------------------------------------------------------------- STATIC_AL void CddTps929240_UpdateDeviceState(const Device_Tps929x_t* device, uint8 primitive, uint8* buff, uint8 buffLen) { UUE_ASSERT(buffLen == primRespDescInitTable_Tps929240[primitive].respSize - 1); switch (primitive) { case Prim_Tps929x_WRITE_PWM: // clear shadow plausible bit only UTIL_CLEAR_BIT(device->shadow->plausibleMask, TPS929_SHADOWN_PLAUSIBLE_PWM_OFFSET); break; case Prim_Tps929x_WRITE_OUTEN: // clear shadow plausible bit only UTIL_CLEAR_BIT(device->shadow->plausibleMask, TPS929_SHADOWN_PLAUSIBLE_EN_OFFSET); break; case Prim_Tps929x_READ_FLAG: UUE_ASSERT(sizeof(device->shadow->reg_flags) == buffLen); memcpy(&device->shadow->reg_flags, buff, buffLen); UTIL_CLEAR_BIT(device->shadow->plausibleMask, TPS929_SHADOWN_PLAUSIBLE_FLAGS_OFFSET); break; case Prim_Tps929x_CLEAR_FLAG: break; case Prim_Tps929x_WRITE_CTRLGATE_0: break; case Prim_Tps929x_WRITE_CTRLGATE_1: break; case Prim_Tps929x_WRITE_CTRLGATE_2: break; case Prim_Tps929x_WRITE_CTRLGATE_3: break; case Prim_Tps929x_WRITE_LOCK: break; case Prim_Tps929x_READ_REGISTER: break; case Prim_Tps929x_WRITE_REGISTER: break; default: UUE_ASSERT(0); break; } }