OCD Messaging with Handshaking and Blocking

This example will block on each character sent via the OCD messaging system until it is ready to accept a new character. A simple timeout is employed to prevent full lockup of code if the debugger is disconnected. This example runs on an AVR ATtiny817 using the UPDI interface, but a similar mechanism could be used on other AVR MCU architectures supporting OCD messaging.

#include <avr/io.h>
#include <stdbool.h>

#define SYSCFG_OCDM SYSCFG.reserved_0x18
#define SYSCFG_OCDMS SYSCFG.reserved_0x19

bool ocd_print_ready (void)
{
    // Has the last character been collected?
    return !(SYSCFG_OCDMS & (1 << 0));
}

bool ocd_print_char (char msg)
{
    // Simple timeout mechanism
    uint8_t timeout = 0xFF;
    while (timeout-- && !ocd_print_ready())
        ;
    
    // If the debugger fails to collect, continue
    if (!timeout)
        return false;
    
    // Drop off a message
    SYSCFG_OCDM = msg;
    return true;
}

void ocd_print (char* pmsg)
{
    // Send the message
    while (*pmsg) {
        if (!ocd_print_char(*pmsg++))
            return;
    }
}

int main(void)
{
    // Send an OCD message
    ocd_print ("Hello World\n");
    while (1)
        ;
}