0

I'm trying to format data sent over a USB UART with printf and it's giving me garbage. I can send a simple string and that works but anything I try to format gives junk. Looking through the code I think it has to do with my string not being in program space but I'm not sure.

Here is my main:

void main(void) {
    CPU_PRESCALE(CPU_16MHz);
    init_uart();

    int degree = 0;
    char buffer[50];

    while(1) {
        degree = (degree + 1) % 360;

        send_str(PSTR("\n\nHello!!!\n\n"));
        memset(buffer, 0, 50);
        sprintf_P(buffer, PSTR("%d degrees\n"), degree);
        send_str(buffer);

        _delay_ms(20);
    }
}

The output looks like this:

Hello!!!

����/�������(/����#Q��������

Hello!!!

����/�������(/����#Q��������

The USB UART code I found in a tutorial. The relevant parts look like this:

void send_str(const char *s)
{
    char c;
    while (1) {
        c = pgm_read_byte(s++);
        if (!c) break;
        usb_serial_putchar(c);
    }
}

int8_t usb_serial_putchar(uint8_t c)
{
    uint8_t timeout, intr_state;

    // if we're not online (enumerated and configured), error
    if (!usb_configuration) return -1;
    // interrupts are disabled so these functions can be
    // used from the main program or interrupt context,
    // even both in the same program!
    intr_state = SREG;
    cli();
    UENUM = CDC_TX_ENDPOINT;
    // if we gave up due to timeout before, don't wait again
    if (transmit_previous_timeout) {
        if (!(UEINTX & (1<<RWAL))) {
            SREG = intr_state;
            return -1;
        }
        transmit_previous_timeout = 0;
    }
    // wait for the FIFO to be ready to accept data
    timeout = UDFNUML + TRANSMIT_TIMEOUT;
    while (1) {
        // are we ready to transmit?
        if (UEINTX & (1<<RWAL)) break;
        SREG = intr_state;
        // have we waited too long?  This happens if the user
        // is not running an application that is listening
        if (UDFNUML == timeout) {
            transmit_previous_timeout = 1;
            return -1;
        }
        // has the USB gone offline?
        if (!usb_configuration) return -1;
        // get ready to try checking again
        intr_state = SREG;
        cli();
        UENUM = CDC_TX_ENDPOINT;
    }
    // actually write the byte into the FIFO
    UEDATX = c;
    // if this completed a packet, transmit it now!
    if (!(UEINTX & (1<<RWAL))) UEINTX = 0x3A;
    transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
    SREG = intr_state;
    return 0;
}
CaseyB
  • 24,780
  • 14
  • 77
  • 112

0 Answers0