// usb_shell.c // BCD -- Ben Hutton, Chris Leary, Devrin Talen // 100-column width #include "usb_shell.h" /***********/ /* GLOBALS */ /***********/ uint8_t rx_buf[RX_BUF_SIZE]; uint8_t rx_buf_len = 0; uint8_t tx_buf[TX_BUF_SIZE]; uint8_t tx_buf_len = 0; uint8_t exec_cmd_flag = 0; // a string that will make backspaces actually look like backspaces in a terminal connection const uint8_t backspace_str[] = "\b \b"; /**************/ /* INTERRUPTS */ /**************/ ISR(USART_RXC_vect) // Code executed when USART receives a byte. { uint8_t received_char; // Fetch the recieved byte value. received_char = UDR; switch (received_char) { case '\b': rx_buf[rx_buf_len] = '\0'; /* Need rx_buf_len to be non-zero before decrement to prevent unsigned integer * underflow. */ if (rx_buf_len) { rx_buf_len--; // Need the following cast to avoid the warning. usart_putstr((uint8_t *)backspace_str); } break; case '\r': case '\n': UDR = received_char; rx_buf[rx_buf_len] = '\0'; exec_cmd_flag = 1; break; default: UDR = received_char; //sprintf(rx_buf, "0x%x ", received_char); //usart_putstr(rx_buf); rx_buf[rx_buf_len++] = received_char; // Prevent buffer overflows. if (rx_buf_len >= RX_BUF_SIZE) rx_buf_len = 0; break; } } /************************/ /* FUNCTION DEFINITIONS */ /************************/ void usart_putchar(uint8_t char_to_put) /* * Waits for transmit flag to become clear, then sends a single byte. */ { loop_until_bit_is_set(UCSRA, UDRE); UDR = char_to_put; } void usart_putstr(char *str_to_put) /* * Transmits the given string over USART. */ { uint8_t iter; uint8_t char_to_put; for (iter = 0; (char_to_put = str_to_put[iter]); iter++) { usart_putchar(char_to_put); } } void initialize_usart() { // Enable usart for transmit and receive. UCSRB |= (1 << RXEN) | (1 << TXEN); // 8-bit chars (uint8_t) UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // load lower 8-bits of the baud rate value into the low byte of the UBRR register UBRRL = BAUD_PRESCALE; // load upper 8-bits of the baud rate value into the high byte of the UBRR register UBRRH = (BAUD_PRESCALE >> 8); // enable 'recieve complete' interrupt (USART_RXC) UCSRB |= (1 << RXCIE); // Enable interrupts globally sei(); }