Issue 310: EQ Answers

Answer 1: UDP packets are subject to the following problems. Packets may be lost. Packets may experience variable delays. Packets may arrive in a different order from the order they were transmitted.

UDP gives the application the ability to detect and deal with these issues without experiencing the overhead and arbitrarily large delays associated with TCP.

Since UDP packets can get lost or arrive out of order, you include a sequence number in the packet so that the receiving side can detect either of these occurrances.

The packets also experience random delays over some range that is generally bounded. Therefore, you use a FIFO buffer (or “elastic store”) on the receive side to hide the packet arrival “jitter”. You try to keep the amount data in this buffer that corresponds to the average packet delay, plus a safety margin. If this FIFO ever “runs dry”, you might need to set the (re-)starting threshold to a higher value. Packets that arrive extremely late are treated the same as lost packets.

Answer 2: Any difference between the transmit and receive sample clocks means that the average amount of data in the receive-side FIFO will start to trend upward or downward over time. If the FIFO depth is increasing, it is necessary to increase the output audio sample rate slightly to match. Similarly, if it is decreasing, it is necessary to decrease the sample rate. These adjustments will cause the long-term average sample rate of the receiver to match that of the transmitter exactly.

Answer 3: You can effectively do both the multiplication and the division one addition and one subtraction at a time, by keeping track of the milliseconds right inside the ISR, rather than (or in addition to) simply counting the raw ticks:

/* microseconds can be a 16-bit integer */

microseconds += microsecondsPerTick;

while (microseconds >= 1000) {

microseconds -= 1000;

++milliseconds;

Answer 4: I2C clock “stretching” refers to the mechanism by which a slave device holds SCL low *after* the master has driven it low, in order to prevent it from going high again before the slave is ready to process the next data bit.

If the master is waiting for more data from, say, a host CPU, it simply won’t drive SCL low in the first place — it’ll simply leave SCL high until the next data transfer can start. There’s no reason for the master to hold SCL low for an extended period of time.

The one exception would be during the arbitration phase of a multi-master setup. In that case, some clock stretching will occur as a result of the various masters not being strictly in-phase as they start their transfers.