/* * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD * All rights reserved. * * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use * exclusively with CVA's microcontroller products. This file can be freely * distributed within development tools that are supporting such microcontroller * products. * * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. */ /******************************************************************************* * the includes ******************************************************************************/ #include #include #include "uds_service2F.h" /******************************************************************************* * the defines ******************************************************************************/ /******************************************************************************* * the typedefs ******************************************************************************/ /*! \brief The Uds IO control type */ typedef enum _UdsIoCtrlType_ { UDS_IOCTRL_RETURN_TO_ECU = 0x00, UDS_IOCTRL_RETSET_TO_DEFAULT = 0x01, UDS_IOCTRL_FREEZE_CURRENT_STATE = 0x02, UDS_IOCTRL_SHORT_ADJUSTMENT = 0x03 } UdsIoCtrlType; /*! \brief The Uds IO control struct */ typedef struct _Uds_IoCtrl_ { uint16_t did; uint8_t securityLevel; uint8_t *pData; uint8_t dataLen; uint8_t defaultValue; uint8_t step; bool enable; void (*IoCtrl_Init)(void); void (*IoCtrl_Stop)(void); } Uds_IoCtrl; /*! \brief The IoControl-by-ID definition of UDS */ typedef struct _Uds_IoCtrlBuf_ { uint8_t backlightLevel[2]; uint8_t buzzer[2]; } Uds_IoCtrlBuf; /******************************************************************************* * the constants ******************************************************************************/ static void IoCtrl_InitBackLight(void); static void IoCtrl_StopBacklight(void); static void IoCtrl_InitBuzzer(void); static void IoCtrl_StopBuzzer(void); /******************************************************************************* * the globals ******************************************************************************/ Uds_IoCtrlBuf udsIoCtrlBuffer; Uds_IoCtrl udsIoCtrlTable[] = { {0xF092, UDS_SA_NONE, udsIoCtrlBuffer.backlightLevel, 2, 0, 0, 0, &IoCtrl_InitBackLight, &IoCtrl_StopBacklight}, {0xF020, UDS_SA_NONE, udsIoCtrlBuffer.buzzer, 2, 0, 0, 0, &IoCtrl_InitBuzzer, &IoCtrl_StopBuzzer }, }; /******************************************************************************* * the functions ******************************************************************************/ static void IoCtrl_InitBackLight(void) { /* user add back light control code */ } static void IoCtrl_StopBacklight(void) { /* user add back light stop code */ } static void IoCtrl_InitBuzzer(void) { /* user add buzzer control code */ } static void IoCtrl_StopBuzzer(void) { /* user add buzzer stop code */ } void UdsService2F_InputOutputCtrlById(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen) { uint16_t ioCtrlId = 0; uint8_t ioCtrlParam = 0; uint8_t ioCtrlIndex = 0; uint8_t ioCtrlNum = sizeof(udsIoCtrlTable) / sizeof(udsIoCtrlTable[0]); uint8_t rspBuffer[UDS_RSP_LEN_MAX] = {0}; if(msgLen < obj->seviceTable[obj->curServiceIdx].minLen) { Uds_NegativeResponse(obj, 0x2F, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); return; } if(obj->session == UDS_SESSION_DEFAULT) { Uds_NegativeResponse(obj, 0x2F, NRC_CONDITIONS_NOT_CORRECT); return; } ioCtrlId = ((uint16_t)msgBuf[1] << 8) + msgBuf[2]; ioCtrlParam = msgBuf[3]; for(ioCtrlIndex = 0; ioCtrlIndex < ioCtrlNum; ioCtrlIndex++) { if(udsIoCtrlTable[ioCtrlIndex].did == ioCtrlId) { if((udsIoCtrlTable[ioCtrlIndex].securityLevel != UDS_SA_NONE) && (udsIoCtrlTable[ioCtrlIndex].securityLevel != obj->securityLevel)) { Uds_NegativeResponse(obj, 0x2F, NRC_SECURITY_ACCESS_DENIED); return; } break; } } if(ioCtrlIndex >= ioCtrlNum) { Uds_NegativeResponse(obj, 0x2F, NRC_REQUEST_OUT_OF_RANGE); return; } rspBuffer[0] = UDS_GET_POSITIVE_RSP(0x2F); rspBuffer[1] = msgBuf[1]; rspBuffer[2] = msgBuf[2]; rspBuffer[3] = msgBuf[3]; switch(ioCtrlParam) { case UDS_IOCTRL_RETURN_TO_ECU: /* add user code */ udsIoCtrlTable[ioCtrlIndex].enable = false; if(udsIoCtrlTable[ioCtrlIndex].IoCtrl_Stop != NULL) { udsIoCtrlTable[ioCtrlIndex].IoCtrl_Stop(); Uds_PositiveResponse(obj, rspBuffer, 4); } break; case UDS_IOCTRL_SHORT_ADJUSTMENT: /* add user code */ if(msgLen < (udsIoCtrlTable[ioCtrlIndex].dataLen + 4)) { Uds_NegativeResponse(obj, 0x2F, NRC_CONDITIONS_NOT_CORRECT); return; } udsIoCtrlTable[ioCtrlIndex].enable = true; memcpy(udsIoCtrlTable[ioCtrlIndex].pData, &msgBuf[4], udsIoCtrlTable[ioCtrlIndex].dataLen); if(udsIoCtrlTable[ioCtrlIndex].IoCtrl_Init != NULL) { udsIoCtrlTable[ioCtrlIndex].IoCtrl_Init(); Uds_PositiveResponse(obj, rspBuffer, 4); } break; default: Uds_NegativeResponse(obj, 0x2F, NRC_REQUEST_OUT_OF_RANGE); break; } }