1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
S16BIT _DECL sitalRt_MessageLegality_Enable ( S16BIT swDevice,
U16BIT wOwnAddressOrBroadcast,
U16BIT wMessageDirection,
U16BIT wSubaddress,
U32BIT dwWordCountOrModeCodeMask)
{
/// @pseudocode
/// If any state irrelevancy or illegal input parameter or operation failure is identified:
/// Return error.
if (((S16BIT)0 > swDevice) || ((S16BIT)sitalMaximum_DEVICES <= swDevice))
{
return sitalReturnCode_INVALID_DEVICE_NUMBER;
}
const DeviceStateStructure* dsspDeviceState // A pointer to the state structure of given device.
= &(s_dssaDevices[swDevice]);
if ((sitalMode_RT != dsspDeviceState->wMode) && (sitalMode_RT_AND_MT != dsspDeviceState->wMode))
{
return sitalReturnCode_INVALID_MODE;
}
if ((sitalDeviceState_READY != dsspDeviceState->wCurrentState) && (sitalDeviceState_RUN != dsspDeviceState->wCurrentState))
{
return sitalReturnCode_INVALID_STATE;
}
BOOLEAN bIsLegalParameter; // A flag that says whether an input parameter is legal.
switch (wOwnAddressOrBroadcast)
{
case sitalRtAddressType_BROADCAST:
case sitalRtAddressType_OWN:
case sitalRtAddressType_BOTH:
bIsLegalParameter = TRUE;
break;
default:
bIsLegalParameter = FALSE;
break;
}
if (FALSE == bIsLegalParameter)
{
return sitalReturnCode_INVALID_PARAMETER;
}
switch (wMessageDirection)
{
case sitalMessageDirection_RX:
case sitalMessageDirection_TX:
case sitalMessageDirection_BOTH:
bIsLegalParameter = TRUE;
break;
default:
bIsLegalParameter = FALSE;
break;
}
if (FALSE == bIsLegalParameter)
{
return sitalReturnCode_INVALID_PARAMETER;
}
if ((0U > wSubaddress) || ((rtSubaddress_BORDER <= wSubaddress) && (sitalRtSubaddress_ALL != wSubaddress)))
{
return sitalReturnCode_INVALID_PARAMETER;
}
/// Set loop delimiters for the direction, address type, and subaddress loops.
U16BIT wDirectionLoopBase; // Base value of direction loop.
U16BIT wDirectionLoopBorder; // Border value of direction loop.
if (sitalMessageDirection_BOTH == wMessageDirection)
{
wDirectionLoopBase = 0U;
wDirectionLoopBorder = messageDirection_BORDER;
}
else
{
wDirectionLoopBase = wMessageDirection;
wDirectionLoopBorder = (wMessageDirection + (U16BIT)1U);
}
U16BIT wAddressLoopBase; // Base value of address loop.
U16BIT wAddressLoopBorder; // Border value of address loop.
if (sitalRtAddressType_BOTH == wOwnAddressOrBroadcast)
{
wAddressLoopBase = 0U;
wAddressLoopBorder = rtAddressType_BORDER;
}
else
{
wAddressLoopBase = wOwnAddressOrBroadcast;
wAddressLoopBorder = (wOwnAddressOrBroadcast + (U16BIT)1U);
}
U16BIT wSubaddressLoopBase; // Base value of subaddress loop.
U16BIT wSubaddressLoopBorder; // Border value of subaddress loop.
if (sitalRtSubaddress_ALL == wSubaddress)
{
wSubaddressLoopBase = 0U;
wSubaddressLoopBorder = rtSubaddress_BORDER;
}
else
{
wSubaddressLoopBase = wSubaddress;
wSubaddressLoopBorder = (wSubaddress + (U16BIT)1U);
}
/// Loop over all given combinations of direction, address type, and subaddress:
/// Update each combination's illegalization specifications.
for (S32BIT iDirection=(S32BIT)wDirectionLoopBase; iDirection<(S32BIT)wDirectionLoopBorder; iDirection++)
{
for (S32BIT iAddress=(S32BIT)wAddressLoopBase; iAddress<(S32BIT)wAddressLoopBorder; iAddress++)
{
for (S32BIT iSubaddress=(S32BIT)wSubaddressLoopBase; iSubaddress<(S32BIT)wSubaddressLoopBorder; iSubaddress++)
{
// Find the address of the entry of the target table that corresponds current combination.
U16BIT wTableEntryAddress; // The address of an entry in the target table.
wTableEntryAddress = ((U16BIT)rtAddressMap_COMMAND_ILLEGALIZATION_TABLE | (U16BIT)(iDirection << rtCommandIllegalizationTable_OFFSET_OF_DIRECTION) | (U16BIT)(iAddress << rtCommandIllegalizationTable_OFFSET_OF_ADDRESS_TYPE) | (U16BIT)(iSubaddress << rtCommandIllegalizationTable_OFFSET_OF_SUBADDRESS));
// Calculate the new mask.
U16BIT wMaskLowWord; // The value of the least significant word of the new mask.
U16BIT wMaskHighWord; // The value of the most significant word of the new mask.
U32BIT dwNewMask; // The value of the new illegalization mask.
S16BIT swResult; // Result of operation or function call.
swResult = sitalDevice_AccessMemory (swDevice, sitalDeviceAccessOperation_Read, wTableEntryAddress, sitalDeviceMemorySection_Ram, 1U, &wMaskLowWord);
if (sitalReturnCode_SUCCESS != swResult)
{
return swResult;
}
swResult = sitalDevice_AccessMemory (swDevice, sitalDeviceAccessOperation_Read, (wTableEntryAddress + 1U), sitalDeviceMemorySection_Ram, 1U, &wMaskHighWord);
if (sitalReturnCode_SUCCESS != swResult)
{
return swResult;
}
dwNewMask = wMaskHighWord;
dwNewMask = ((dwNewMask << 16U) | wMaskLowWord);
dwNewMask &= (~dwWordCountOrModeCodeMask);
// Write the new mask in the entry of the target table that corresponds current combination.
wMaskLowWord = (U16BIT)(dwNewMask & 0xFFFFU);
wMaskHighWord = (U16BIT)(dwNewMask >> 16U);
swResult = sitalDevice_AccessMemory (swDevice, sitalDeviceAccessOperation_Write, wTableEntryAddress, sitalDeviceMemorySection_Ram, 1U, &wMaskLowWord);
if (sitalReturnCode_SUCCESS != swResult)
{
return swResult;
}
swResult = sitalDevice_AccessMemory (swDevice, sitalDeviceAccessOperation_Write, (wTableEntryAddress + 1U), sitalDeviceMemorySection_Ram, 1U, &wMaskHighWord);
if (sitalReturnCode_SUCCESS != swResult)
{
return swResult;
}
}
}
}
return sitalReturnCode_SUCCESS;
}
| |