HeapCrash / Challenges / RS-485 transmit with DMA

RS-485 transmit with DMA

A Modbus RTU master on half-duplex RS-485 sends frames by DMA and drops the transceiver's driver-enable line when the DMA finishes. Slaves report CRC errors on the last byte, the master sometimes parses its own request as the reply, and two requests sent back to back garble each other.

The code

Embedded C for Cortex-M. It compiles. There are 3 real bugs in it: the kind that pass a bench test and fail in the field.

static uint8_t tx_buf[64];

void rs485_send(const uint8_t *frame, uint16_t len)
{
    memcpy(tx_buf, frame, len);
    gpio_write(DE_PIN, 1);
    DMA1_Channel7->CCR &= ~1u;
    DMA1_Channel7->CMAR = (uint32_t)(uintptr_t)tx_buf;
    DMA1_Channel7->CNDTR = len;
    DMA1_Channel7->CCR |= 1u;
}

void DMA1_Channel7_IRQHandler(void)
{
    DMA1->IFCR = DMA_IFCR_CTCIF7;
    gpio_write(DE_PIN, 0);
    response_timer_start(MODBUS_TIMEOUT_MS);
}

void USART2_IRQHandler(void)
{
    if (USART2->ISR & USART_ISR_RXNE) {
        rx_push((uint8_t)USART2->RDR);
    }
}

What an interviewer expects

The bugs, reference fixes and the follow-up question are in the practice app, after you've tried it.

Companies that test this

Matched on the skills each company's embedded roles emphasise.

Related challenges

Flag the lines, say what breaks, then fix it and build it with clang in your browser.

Find the bugs