Rev 2040 | Rev 2198 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 2040 | Rev 2045 | ||
|---|---|---|---|
| Line 884... | Line 884... | ||
| 884 | /* Use once seq. */ |
884 | /* Use once seq. */ |
| 885 | /* Don't transmit last passive. last passive handled by timer. */ |
885 | /* Don't transmit last passive. last passive handled by timer. */ |
| 886 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1, irTxChannel[channel].proto.modfreq); |
886 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1, irTxChannel[channel].proto.modfreq); |
| 887 | } |
887 | } |
| 888 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
888 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| - | 889 | break; |
|
| 889 | } |
890 | } |
| 890 | 891 | ||
| 891 | case sns_irTransceive_STATE_TRANSMITTING: |
892 | case sns_irTransceive_STATE_TRANSMITTING: |
| 892 | { |
893 | { |
| 893 | if (irTxChannel[channel].sendComplete == TRUE) |
894 | if (irTxChannel[channel].sendComplete == TRUE) |
| Line 898... | Line 899... | ||
| 898 | 899 | ||
| 899 | if (irTxChannel[channel].sendingPronto) |
900 | if (irTxChannel[channel].sendingPronto) |
| 900 | { |
901 | { |
| 901 | /* First repeat, or no repeat sequence defined => use last passive time in once seq. */ |
902 | /* First repeat, or no repeat sequence defined => use last passive time in once seq. */ |
| 902 | if(irTxChannel[channel].repeatCount == 0 || irTxChannel[channel].repSeqLen == 0) |
903 | if(irTxChannel[channel].repeatCount == 0 || irTxChannel[channel].repSeqLen == 0) |
| 903 | { |
904 | { |
| 904 | /* Use last passive time as timeout. */ |
905 | /* Use last passive time as timeout. */ |
| 905 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].onceSeqLen - 1] / 1000; |
906 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].onceSeqLen - 1] / 1000; |
| 906 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
907 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
| 907 | } |
908 | } |
| 908 | /* Second, or later repeat => use last passive time in repeat seq. */ |
909 | /* Second, or later repeat => use last passive time in repeat seq. */ |
| 909 | else |
910 | else |
| 910 | { |
911 | { |
| 911 | /* Use last passive time as timeout. */ |
912 | /* Use last passive time as timeout. */ |
| 912 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] / 1000; |
913 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] / 1000; |
| Line 915... | Line 916... | ||
| 915 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
916 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
| 916 | } |
917 | } |
| 917 | else |
918 | else |
| 918 | { |
919 | { |
| 919 | irTxChannel[channel].state = sns_irTransceive_STATE_START_PAUSE; |
920 | irTxChannel[channel].state = sns_irTransceive_STATE_START_PAUSE; |
| 920 | } |
921 | } |
| 921 | } |
922 | } |
| 922 | break; |
923 | break; |
| 923 | } |
924 | } |
| 924 | 925 | ||
| 925 | case sns_irTransceive_STATE_START_PAUSE: |
926 | case sns_irTransceive_STATE_START_PAUSE: |
| 926 | { |
927 | { |
| Line 965... | Line 966... | ||
| 965 | 966 | ||
| 966 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
967 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 967 | } |
968 | } |
| 968 | break; |
969 | break; |
| 969 | } |
970 | } |
| - | 971 | ||
| 970 | default: |
972 | default: |
| - | 973 | { |
|
| 971 | break; |
974 | break; |
| 972 | } |
975 | } |
| - | 976 | ||
| - | 977 | } |
|
| 973 | #endif |
978 | #endif |
| 974 | 979 | ||
| 975 | } |
980 | } |
| 976 | } |
981 | } |
| 977 | 982 | ||
| 978 | 983 | ||
| 979 | /* Handle incoming CAN data. */ |
984 | /* Handle incoming CAN data. */ |
| 980 | void sns_irTransceive_HandleMessage(StdCan_Msg_t *rxMsg) |
985 | void sns_irTransceive_HandleMessage(StdCan_Msg_t *rxMsg) |
| 981 | { |
986 | { |
| 982 | /* Sanity check. */ |
987 | /* Sanity check. */ |
| 983 | if (StdCan_Ret_class(rxMsg->Header) != CAN_MODULE_CLASS_SNS || |
988 | if (StdCan_Ret_class(rxMsg->Header) != CAN_MODULE_CLASS_SNS || |
| 984 | StdCan_Ret_direction(rxMsg->Header) != DIRECTIONFLAG_TO_OWNER || |
989 | StdCan_Ret_direction(rxMsg->Header) != DIRECTIONFLAG_TO_OWNER || |
| 985 | rxMsg->Header.ModuleType != CAN_MODULE_TYPE_SNS_IRTRANSCEIVE || |
990 | rxMsg->Header.ModuleType != CAN_MODULE_TYPE_SNS_IRTRANSCEIVE || |
| 986 | rxMsg->Header.ModuleId != sns_irTransceive_ID) return; |
991 | rxMsg->Header.ModuleId != sns_irTransceive_ID) return; |
| 987 | 992 | ||
| 988 | switch (rxMsg->Header.Command) |
993 | switch (rxMsg->Header.Command) |
| 989 | { |
994 | { |
| 990 | #if IR_TX_ENABLE==1 |
995 | #if IR_TX_ENABLE==1 |
| 991 | case CAN_MODULE_CMD_PHYSICAL_IR: |
996 | case CAN_MODULE_CMD_PHYSICAL_IR: |
| 992 | { |
997 | { |
| Line 1045... | Line 1050... | ||
| 1045 | uint8_t channel = rxMsg->Data[0] >> 4; |
1050 | uint8_t channel = rxMsg->Data[0] >> 4; |
| 1046 | 1051 | ||
| 1047 | /* Sanity check. */ |
1052 | /* Sanity check. */ |
| 1048 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
1053 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
| 1049 | /* Invalid channel. Generic error code. */ |
1054 | /* Invalid channel. Generic error code. */ |
| 1050 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1055 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1051 | break; |
1056 | break; |
| 1052 | } |
1057 | } |
| 1053 | 1058 | ||
| 1054 | /* Check channel configuration. */ |
1059 | /* Check channel configuration. */ |
| 1055 | if (irTxChannel[channel].state == sns_irTransceive_STATE_DISABLED) { |
1060 | if (irTxChannel[channel].state == sns_irTransceive_STATE_DISABLED) { |
| 1056 | /* Not a TX channel. */ |
1061 | /* Not a TX channel. */ |
| 1057 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1062 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1058 | break; |
1063 | break; |
| 1059 | } |
1064 | } |
| 1060 | 1065 | ||
| 1061 | /* Check if channel is busy. */ |
1066 | /* Check if channel is busy. */ |
| 1062 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) { |
1067 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) { |
| 1063 | /* We're already transmitting on this channel. */ |
1068 | /* We're already transmitting on this channel. */ |
| 1064 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_CHANNELBUSY); |
1069 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_CHANNELBUSY); |
| 1065 | break; |
1070 | break; |
| 1066 | } |
1071 | } |
| 1067 | 1072 | ||
| 1068 | /* Check if format is supported. */ |
1073 | /* Check if format is supported. */ |
| 1069 | if ((((uint16_t)(rxMsg->Data[0] & 0x0F) << 8) | (uint16_t)(rxMsg->Data[1])) != 0) { |
1074 | if ((((uint16_t)(rxMsg->Data[0] & 0x0F) << 8) | (uint16_t)(rxMsg->Data[1])) != 0) { |
| 1070 | /* Invalid pronto format. Generic error code. */ |
1075 | /* Invalid pronto format. Generic error code. */ |
| 1071 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1076 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1072 | break; |
1077 | break; |
| 1073 | } |
1078 | } |
| 1074 | 1079 | ||
| 1075 | /* Check if any other pronto transmission is ongoing (i.e. if the pronto activeChannel is busy). */ |
1080 | /* Check if any other pronto transmission is ongoing (i.e. if the pronto activeChannel is busy). */ |
| 1076 | if (prontoChannelIsAllocated() && irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_IDLE) { |
1081 | if (prontoChannelIsAllocated() && irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_IDLE) { |
| 1077 | /* Pronto data is already being transmitted (or prepared) on another channel. */ |
1082 | /* Pronto data is already being transmitted (or prepared) on another channel. */ |
| 1078 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_ALREADYSENDINGPRONTO); |
1083 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_ALREADYSENDINGPRONTO); |
| 1079 | break; |
1084 | break; |
| Line 1081... | Line 1086... | ||
| 1081 | 1086 | ||
| 1082 | /* Extract received data. */ |
1087 | /* Extract received data. */ |
| 1083 | 1088 | ||
| 1084 | uint32_t divider = (rxMsg->Data[2] << 8) | (rxMsg->Data[3] << 0); |
1089 | uint32_t divider = (rxMsg->Data[2] << 8) | (rxMsg->Data[3] << 0); |
| 1085 | if (divider == 0) { |
1090 | if (divider == 0) { |
| 1086 | /* Invalid wFrqDiv value. Generic error code. */ |
1091 | /* Invalid wFrqDiv value. Generic error code. */ |
| 1087 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1092 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1088 | break; |
1093 | break; |
| 1089 | } |
1094 | } |
| 1090 | uint32_t freqkHz = (sns_irTransceive_BaseFrq / (divider*1000)); |
1095 | uint32_t freqkHz = (sns_irTransceive_BaseFrq / (divider*1000)); |
| 1091 | if (freqkHz == 0) { |
1096 | if (freqkHz == 0) { |
| 1092 | /* Invalid wFrqDiv value. Generic error code. */ |
1097 | /* Invalid wFrqDiv value. Generic error code. */ |
| 1093 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1098 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1094 | break; |
1099 | break; |
| 1095 | } |
1100 | } |
| 1096 | irTxChannel[channel].proto.modfreq = freqkHz; |
1101 | irTxChannel[channel].proto.modfreq = freqkHz; |
| 1097 | 1102 | ||
| 1098 | /* In case other channels are busy sending with other modfreqs, this will be reported by IrTransceiver_Transmit. */ |
1103 | /* In case other channels are busy sending with other modfreqs, this will be reported by IrTransceiver_Transmit. */ |
| 1099 | 1104 | ||
| 1100 | /* Convert lenghts to bytes. */ |
1105 | /* Convert lenghts to bytes. */ |
| 1101 | irTxChannel[channel].onceSeqLen = 2*((((uint16_t)rxMsg->Data[4]) << 8) | (((uint16_t)rxMsg->Data[5]) << 0)); |
1106 | irTxChannel[channel].onceSeqLen = 2*((((uint16_t)rxMsg->Data[4]) << 8) | (((uint16_t)rxMsg->Data[5]) << 0)); |
| 1102 | irTxChannel[channel].repSeqLen = 2*((((uint16_t)rxMsg->Data[6]) << 8) | (((uint16_t)rxMsg->Data[7]) << 0)); |
1107 | irTxChannel[channel].repSeqLen = 2*((((uint16_t)rxMsg->Data[6]) << 8) | (((uint16_t)rxMsg->Data[7]) << 0)); |
| 1103 | 1108 | ||
| 1104 | /* Enter prepering pronto state and clear transmit buffer. */ |
1109 | /* Enter prepering pronto state and clear transmit buffer. */ |
| 1105 | irTxChannel[channel].state = sns_irTransceive_STATE_PREPARING_PRONTO; |
1110 | irTxChannel[channel].state = sns_irTransceive_STATE_PREPARING_PRONTO; |
| 1106 | irTxChannel[channel].txlen = 0; |
1111 | irTxChannel[channel].txlen = 0; |
| 1107 | irTxChannel[channel].expectedSeqNr = 0; |
1112 | irTxChannel[channel].expectedSeqNr = 0; |
| 1108 | prontoAllocatedTxChannel = channel; |
1113 | prontoAllocatedTxChannel = channel; |
| Line 1114... | Line 1119... | ||
| 1114 | 1119 | ||
| 1115 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTOP: |
1120 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTOP: |
| 1116 | { |
1121 | { |
| 1117 | /* Get IR channel. */ |
1122 | /* Get IR channel. */ |
| 1118 | uint8_t channel = rxMsg->Data[0] >> 4; |
1123 | uint8_t channel = rxMsg->Data[0] >> 4; |
| 1119 | 1124 | ||
| 1120 | /* Sanity check. */ |
1125 | /* Sanity check. */ |
| 1121 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
1126 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
| 1122 | /* Invalid channel. */ |
1127 | /* Invalid channel. */ |
| 1123 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1128 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1124 | break; |
1129 | break; |
| 1125 | } |
1130 | } |
| 1126 | 1131 | ||
| 1127 | /* Check channel configuration. */ |
1132 | /* Check channel configuration. */ |
| 1128 | if (irTxChannel[channel].state == sns_irTransceive_STATE_DISABLED) { |
1133 | if (irTxChannel[channel].state == sns_irTransceive_STATE_DISABLED) { |
| 1129 | /* Not a TX channel. */ |
1134 | /* Not a TX channel. */ |
| 1130 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1135 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1131 | break; |
1136 | break; |
| 1132 | } |
1137 | } |
| 1133 | 1138 | ||
| 1134 | irTxChannel[channel].stopSend = TRUE; |
1139 | irTxChannel[channel].stopSend = TRUE; |
| 1135 | 1140 | ||
| 1136 | if (!prontoChannelIsAllocated()) { |
1141 | if (!prontoChannelIsAllocated()) { |
| 1137 | /* Nothing to stop. No pronto TX channel allocated right now. */ |
1142 | /* Nothing to stop. No pronto TX channel allocated right now. */ |
| 1138 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED); |
1143 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED); |
| - | 1144 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
|
| 1139 | break; |
1145 | break; |
| 1140 | } |
1146 | } |
| 1141 | 1147 | ||
| 1142 | /* State check. If we're not currently transmitting anything, the STOPPED reponse will never occur. */ |
1148 | /* State check. If we're not currently transmitting anything, the STOPPED reponse will never occur. */ |
| 1143 | if (prontoChannelIsAllocated() && |
1149 | if (prontoChannelIsAllocated() && |
| Line 1147... | Line 1153... | ||
| 1147 | irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_PAUSING && |
1153 | irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_PAUSING && |
| 1148 | irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_START_PAUSE) |
1154 | irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_START_PAUSE) |
| 1149 | { |
1155 | { |
| 1150 | /* Nothing to stop. Not in TX state. Respond that we're already stopped. */ |
1156 | /* Nothing to stop. Not in TX state. Respond that we're already stopped. */ |
| 1151 | pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED); |
1157 | pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED); |
| - | 1158 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
|
| 1152 | break; |
1159 | break; |
| 1153 | } |
1160 | } |
| 1154 | 1161 | ||
| 1155 | /* Is pronto activeChannel active, but wrong channel specified? */ |
1162 | /* Is pronto activeChannel active, but wrong channel specified? */ |
| 1156 | if (prontoChannelIsAllocated() && prontoAllocatedTxChannel != channel) { |
1163 | if (prontoChannelIsAllocated() && prontoAllocatedTxChannel != channel) { |