* Sends Biphase (Manchester) coded data MSB first * This function concatenates two marks to one longer mark, * thus avoiding the programmatically pause between the generation of two separate marks. * Send an additional start bit if specified * 0 -> mark+space * 1 -> space+mark * The output always ends with a space / inactive level * @param aData uint32 holding the bits to be sen
| 1176 | * @param aSendStartBit if true sends an additional start bit with value 1 as MSB, if false no start bit is sent and data may start with 0 or 1. |
| 1177 | */ |
| 1178 | void IRsend::sendBiphaseData(uint16_t aBiphaseTimeUnit, uint32_t aData, uint_fast8_t aNumberOfBits, bool aSendStartBit) { |
| 1179 | |
| 1180 | TRACE_PRINT(F("0x")); |
| 1181 | TRACE_PRINT(aData, HEX); |
| 1182 | TRACE_PRINT('S'); |
| 1183 | |
| 1184 | // Data - Biphase code MSB first |
| 1185 | |
| 1186 | uint8_t tBitsToSend = aNumberOfBits; // total number of bits to send including start bit if specified |
| 1187 | if (aSendStartBit) { |
| 1188 | tBitsToSend++; // +1 for additional start bit |
| 1189 | } |
| 1190 | uint32_t tMask = 1UL << (tBitsToSend - 1); // Mask is now set to the the MSB of data or the virtual start bit before the MSB of data |
| 1191 | |
| 1192 | bool tLastBitWasOne; |
| 1193 | bool tNextBitIsOne; |
| 1194 | if (aSendStartBit) { |
| 1195 | // prepare for start with sending the start bit, which is 1 |
| 1196 | tNextBitIsOne = true; // Start bit is a 1, value is copied to tCurrentBitIsOne |
| 1197 | tLastBitWasOne = false; // Force to send the mark if tNextBitIsOne is 0 (which it is not the case here). Does not increase code size :-). |
| 1198 | } else { |
| 1199 | // prepare to send only the data which may start with a 0 or 1 (e.g. after a defined pause or header when no additional start bit is needed) |
| 1200 | tNextBitIsOne = ((aData & tMask) != 0) ? 1 : 0; // Value is copied to tCurrentBitIsOne |
| 1201 | tLastBitWasOne = false; // Force to send the mark if tNextBitIsOne is 0 |
| 1202 | } |
| 1203 | |
| 1204 | // now send all bits |
| 1205 | for (uint_fast8_t i = tBitsToSend; i > 0; i--) { |
| 1206 | bool tCurrentBitIsOne = tNextBitIsOne; |
| 1207 | tMask >>= 1; |
| 1208 | tNextBitIsOne = ((aData & tMask) != 0) || (i == 1); // true for last bit to avoid extension of mark |
| 1209 | if (tCurrentBitIsOne) { |
| 1210 | TRACE_PRINT('1'); |
| 1211 | space(aBiphaseTimeUnit); |
| 1212 | if (tNextBitIsOne) { |
| 1213 | mark(aBiphaseTimeUnit); // if next bit is 1 send a single mark |
| 1214 | } else { |
| 1215 | // if next bit is 0, extend the current mark in order to generate a continuous signal without short breaks |
| 1216 | mark(2 * aBiphaseTimeUnit); |
| 1217 | } |
| 1218 | tLastBitWasOne = true; |
| 1219 | |
| 1220 | } else { |
| 1221 | TRACE_PRINT('0'); |
| 1222 | if (!tLastBitWasOne) { |
| 1223 | mark(aBiphaseTimeUnit); // if last bit was 0 send a single mark |
| 1224 | } |
| 1225 | space(aBiphaseTimeUnit); |
| 1226 | tLastBitWasOne = false; |
| 1227 | } |
| 1228 | } |
| 1229 | TRACE_PRINTLN(); |
| 1230 | } |
| 1231 | |
| 1232 | /** |
| 1233 | * Sends an IR mark for the specified number of microseconds. |
nothing calls this directly
no outgoing calls
no test coverage detected