//############################################################################# // idibus_custom.h implementation //############################################################################# #include #include #include "IdiBusSlave.h" #include "idibus_hw.h" #include "USART1.h" #include "SYSTEM.h" #include "IDIBUS_IMPL.h" #include "RSLink.h" #include "MEMORY.h" // ÍÅ ÈÑÏÎËÜÇÓÉÒÅ ÎÁÙÈÅ ÏÅÐÅÌÅÍÍÛÅ ÄËß ÑÂßÇÈ ÊÎÌÏîÍÅÍÒΠÌÅÆÄÓ ÑÎÁÎÉ ÏÎÆÀË+ÉÑÒÀ //============================================================================= // IMPLEMENTATION SECTION //============================================================================= /* * Define your specific logic for slave module * Required: * Init * Shutdown * And any other custom functions for your needs */ //Make prototypes for channel handlers static void IDIBUS_XXX_NAME_ChannelHandler(idibus_channel_t* CH, idibus_farg_t* farg); //Enumerate channels and assign functions to them static idibus_channel_t IDIBUS_XXX_NAME_Channels[IDIBUS_XXX_NAME_CH_NUM] = { { .ChNum = 0, .CH_Func = IDIBUS_XXX_NAME_ChannelHandler, }, { .ChNum = 1, .CH_Func = IDIBUS_XXX_NAME_ChannelHandler, }, { .ChNum = 2, .CH_Func = IDIBUS_XXX_NAME_ChannelHandler, }, { .ChNum = 3, .CH_Func = IDIBUS_XXX_NAME_ChannelHandler, }, }; //List all devices and their channels static idibus_device_t IDIBUS_Devices[XXX_NAME_DEVICES_NUMBER] = { {IDIBUS_XXX_NAME_Channels, IDIBUS_XXX_NAME_CH_NUM}, }; //Common module configuration //Change on your own risk; static idibus_slave_module_t IDIBUS_MODULE = { .Devices = IDIBUS_Devices, .DevicesCount = XXX_NAME_DEVICES_NUMBER, .STATUS.STATE.B0S.StError = 0, .STATUS.STATE.B0S.StState = IDISTATUS_B0S_ST_STATE_StOperate, .STATUS.STATE.B0S.AesSupported = 0, .STATUS.STATE.B0S.AesInstalled = 0, .STATUS.STATE.B0S.SendAlarmL0 = 0, .STATUS.STATE.B0S.SendAlarmL1 = 0, .STATUS.STATE.B1S.ModuleType = IDISTATUS_B1S_MODULE_TYPE_Slave, .STATUS.STATE.B1S.BridgeConnected = 0, .STATUS.STATE.B1S.SelfInit = 1, .STATUS.STATE.B1S.TimeoutLed = 1, .STATUS.STATE.B1S.NoMMESTimeout = 0, .STATUS.STATE.B1S.CatchAlarmL0 = 0, .STATUS.STATE.B1S.CatchAlarmL1 = 0, }; #define IDIBUS_READ_VAR(farg, DATA){\ if (farg->InpDataLength != 0)\ {\ IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT);\ }\ else\ {\ uint8_t ResponseData[sizeof(DATA)] = {0};\ memcpy(ResponseData, &DATA, sizeof(DATA));\ IDIBUS_ResponseProtectedWrite(farg, ResponseData, sizeof(ResponseData), IDIER_NOPE);\ }\ } #define IDIBUS_WRITE_VAR(farg, DATA){\ if (farg->InpDataLength == sizeof(DATA))\ {\ memcpy(&DATA, farg->InpData, sizeof(DATA));\ IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIER_NOPE);\ }\ else\ {\ IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT);\ }\ } //----------------------------------------------------------------------------- // Channel Handler // This sequence is for a single channel CH->ChNum //----------------------------------------------------------------------------- //memcpy(to, from, num); static void IDIBUS_XXX_NAME_ChannelHandler(idibus_channel_t* CH, idibus_farg_t* farg) { //Check for msg and operations if (IDIBUS_CnannelStaticFunc(CH, farg) != 0) { return; } //Catch channel error if (CH->ChNum >= IDIBUS_XXX_NAME_CH_NUM) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERDEV_INVALID_CHN_NUM); return; } /* * After all checks proccess the command * This sequence is for a single channel CH->ChNum * Use farg->ComFunc to define command * Use farg->InpData and farg->InpDataLength to read recieved data * Two types of command is used READ and WRITE * For ecxlusive actions write your own handler */ switch (farg->ComFunc) { case (XXX_NAME_STATUS_CMD): { IDIBUS_READ_VAR(farg, XXX_NAME_channels_data[CH->ChNum].status); break; } case (XXX_NAME_GET_CMD): { IDIBUS_READ_VAR(farg, XXX_NAME_channels_data[CH->ChNum].ch_data); break; } case (XXX_NAME_SET_CMD): { IDIBUS_WRITE_VAR(farg, XXX_NAME_channels_data[CH->ChNum].ch_data); break; } default: { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_UNSUPPORTED_FUNC_NUM); break; } } } //----------------------------------------------------------------------------- // Custom Initialization //----------------------------------------------------------------------------- static void IDIBUS_Init() //Idibus only init! { for (uint8_t dev = 0; dev < XXX_NAME_DEVICES_NUMBER; dev ++) { for (uint8_t I = 0; I < IDIBUS_MODULE.Devices[dev].ChannelsCount; I++) { IDIBUS_MODULE.Devices[dev].Channels[I].ChNum = I; IDIBUS_MODULE.Devices[dev].Channels[I].LONG_OP.Type = 0; IDIBUS_MODULE.Devices[dev].Channels[I].LONG_OP.State = IDILONGOP_STATE_COMPLETE_NO_ERR; IDIBUS_MODULE.Devices[dev].Channels[I].BcastAddr = IDIBUS_GROUP_0_ADDR; } } } //----------------------------------------------------------------------------- // IdiBus Initialization //----------------------------------------------------------------------------- void IdiBusSlaveInit() { // Idibus dedicated hardware init System_InitSysTick(); System_SystickTimerStart(); USART1_Init(); RSLink_StatusLedInit(); wdt_reset(); //Rslink hardware registration rslink_func_pack_t rslink_hw = { .dips_init = RSLink_DipsInit, .disp_read_addr = RSLink_AddrDecode, .disp_read_speed = RSLink_SpeedDecode, .status_led_init = RSLink_StatusLedInit, .status_led_off = RSLink_StatusLedSetOff, .status_led_on = RSLink_StatusLedSetOn, }; //Register hardware and configuration RSLink_register_hw_functions(rslink_hw); IDIBUS_Init(); //Executes on c_Init //IdiBus_register_init(); //Executes on c_Shutdown //IdiBus_register_shutdown(); wdt_reset(); //Do a complete init of IdiBus RSLlink_pass_module(&IDIBUS_MODULE); IdiBus_pass_module(&IDIBUS_MODULE); #ifdef _LONG_ADDR_SPACE_ IdiBus_ModuleInit(&USART1_INTERFACE, (uint_farptr_t)(locationInApp*2)); #else IdiBus_ModuleInit(&USART1_INTERFACE, (uint8_t*)(locationInApp*2)); #endif RSLink_Init(&USART1_INTERFACE, &USART1_IDIBUS); wdt_reset(); }