Debug print implementation.
Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
#include "dbg_print.h"
#include <gclk.h>
#include <sercom.h>
#include <status_codes.h>
#include <string.h>
#include <system.h>
#include <usart.h>
#include <FreeRTOS.h>
#include <semphr.h>
#include <task.h>
Functions | |
static void | _dbg_interrupt_handler (uint8_t dummy) |
SERCOM UART interrupt handler. More... | |
enum status_code | dbg_init (void) |
Initialize and enable debug UART. More... | |
void | dbg_print_char (const char out_char) |
Print a single character. More... | |
void | dbg_print_hexint (uint32_t out_int) |
Print an integer as hex digits. More... | |
void | dbg_print_str (const char *out_str) |
Print a zero-terminated string. More... | |
void | dbg_sprint_hexint (char *out_str, uint32_t out_int) |
Write an integer as hex digits (ASCII) into string. More... | |
Access lock/unlock | |
static void | _dbg_wait_for_lock (void) |
Wait indefinitely to lock access. More... | |
static void | _dbg_unlock (void) |
Unlock access. More... | |
UART start/stop | |
static void | _dbg_start_uart (void) |
Start UART by enabling DRE interrupt. More... | |
static void | _dbg_stop_uart (void) |
Stop UART by disabling DRE interrupt. More... | |
Internal buffer helpers | |
static dbg_buffer_space_t | _dbg_get_free_buffer_space (void) |
Get current space in print buffer. More... | |
static void | _dbg_write_str_to_buffer (const char *str, dbg_buffer_space_t length) |
Write string to the print buffer. More... | |
static dbg_buffer_space_t | _dbg_request_free_space (dbg_buffer_space_t length) |
Issue request for free buffer space. More... | |
static void | _dbg_wait_for_requested_space (void) |
Wait for requested space to free up. More... | |
static void | _dbg_putstr (const char *str, size_t length) |
Put a string into the print buffer. More... | |
Variables | |
Internal data | |
static SercomUsart *const | sercom_uart = &(CONF_DBG_PRINT_SERCOM->USART) |
Pointer to SERCOM USART instance to use. More... | |
static uint8_t | dbg_buffer [DBG_BUFFER_SIZE] |
Circular print buffer. More... | |
static dbg_buffer_space_t | buffer_head |
Print buffer head (write index) More... | |
static dbg_buffer_space_t | buffer_tail |
Print buffer tail (read index) More... | |
static dbg_buffer_space_t | requested_space |
Variable for buffer space requests. More... | |
static xSemaphoreHandle | dbg_is_free |
Mutex to prevent concurrent writes to print buffer. More... | |
static xSemaphoreHandle | requested_space_is_free |
Semaphore to signal buffer has requested space. More... | |
Convenience macros | |
#define | DBG_BUFFER_SIZE (CONF_DBG_PRINT_BUFFER_SIZE) |
Size of print buffer (must be power of 2) More... | |
#define | DBG_BUFFER_SPACE (DBG_BUFFER_SIZE - 1) |
Maximum number of simultaneously queued bytes in print buffer. More... | |
#define | DBG_BUFFER_MASK (DBG_BUFFER_SIZE - 1) |
Bitmask for print buffer head and tail. More... | |
#define | TRANSLATE_NIBBLE_TO_ASCII(nibble_var) (nibble_var) += ((nibble_var) < 0x0a) ? '0' : ('A' - 0x0a) |
Translate nibble (4-bit) value to ASCII symbol. More... | |
typedef uint8_t | dbg_buffer_space_t |
Type for buffer space and indexes. More... | |
#define DBG_BUFFER_MASK (DBG_BUFFER_SIZE - 1) |
Bitmask for print buffer head and tail.
Referenced by _dbg_get_free_buffer_space(), _dbg_interrupt_handler(), and _dbg_write_str_to_buffer().
#define DBG_BUFFER_SIZE (CONF_DBG_PRINT_BUFFER_SIZE) |
Size of print buffer (must be power of 2)
#define DBG_BUFFER_SPACE (DBG_BUFFER_SIZE - 1) |
Maximum number of simultaneously queued bytes in print buffer.
Referenced by _dbg_get_free_buffer_space(), and _dbg_request_free_space().
#define TRANSLATE_NIBBLE_TO_ASCII | ( | nibble_var | ) | (nibble_var) += ((nibble_var) < 0x0a) ? '0' : ('A' - 0x0a) |
Translate nibble (4-bit) value to ASCII symbol.
Referenced by dbg_sprint_hexint().
typedef uint8_t dbg_buffer_space_t |
Type for buffer space and indexes.
|
inlinestatic |
Get current space in print buffer.
References buffer_head, buffer_tail, DBG_BUFFER_MASK, and DBG_BUFFER_SPACE.
Referenced by _dbg_putstr().
|
static |
SERCOM UART interrupt handler.
This interrupt handler will transmit bytes from the internal print buffer until the tail (read-index) catches up with the head (write-index), at which point it will disable itself since the entire buffer will have been transmitted.
If a print function has requested more space in the buffer, this interrupt handler will also track the number of bytes that have been transmitted and give the mutex when the request has been fulfilled.
dummy | Not used. (SERCOM number passed from master interrupt handler.) |
References buffer_head, buffer_tail, data, dbg_buffer, DBG_BUFFER_MASK, NULL, requested_space, requested_space_is_free, sercom_uart, and xSemaphoreGiveFromISR.
Referenced by dbg_init().
|
inlinestatic |
Put a string into the print buffer.
This function puts a string into the print buffer, taking care to not exceed the buffer's free space. If the buffer becomes full, this function will start the UART and wait for enough space to free up until the entire string has been put into buffer.
[in] | str | Pointer to string to put into the print buffer. |
[out] | length | Length of the string to put into the print buffer. |
References _dbg_get_free_buffer_space(), _dbg_request_free_space(), _dbg_start_uart(), _dbg_stop_uart(), _dbg_wait_for_requested_space(), _dbg_write_str_to_buffer(), and min.
Referenced by dbg_print_char(), dbg_print_hexint(), and dbg_print_str().
|
inlinestatic |
Issue request for free buffer space.
This function will issue a request for _dbg_interrupt_handler() to notify when either the specified number or all (DBG_BUFFER_SPACE) bytes have been freed in a full buffer, depending on which is smaller. The number of bytes that were actually requested is returned by this function.
[in] | length | Desired number of bytes to free up. |
DBG_BUFFER_SPACE | if length was greater than what buffer can contain. |
length | if desired length is less than DBG_BUFFER_SPACE. |
References DBG_BUFFER_SPACE, length, min, and requested_space.
Referenced by _dbg_putstr().
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
Unlock access.
References dbg_is_free, and xSemaphoreGive.
Referenced by dbg_print_char(), dbg_print_hexint(), and dbg_print_str().
|
inlinestatic |
Wait indefinitely to lock access.
This function will try to take the dbg_is_free mutex, and will wait an indefinite amount of time for it.
References dbg_is_free, and xSemaphoreTake.
Referenced by dbg_print_char(), dbg_print_hexint(), and dbg_print_str().
|
inlinestatic |
Wait for requested space to free up.
This function will wait indefinitely for _dbg_interrupt_handler() to free up the number of bytes requested earlier using _dbg_request_free_space() in the print buffer.
References requested_space_is_free, and xSemaphoreTake.
Referenced by _dbg_putstr().
|
inlinestatic |
Write string to the print buffer.
This is a helper function for copying a string into the print buffer, using circular buffer indexing.
[in] | str | Pointer to string to write into buffer. [in] length Number of string bytes to write. |
References Assert, buffer_head, dbg_buffer, and DBG_BUFFER_MASK.
Referenced by _dbg_putstr().
|
static |
Print buffer head (write index)
Referenced by _dbg_get_free_buffer_space(), _dbg_interrupt_handler(), and _dbg_write_str_to_buffer().
|
static |
Print buffer tail (read index)
Referenced by _dbg_get_free_buffer_space(), and _dbg_interrupt_handler().
|
static |
Circular print buffer.
Referenced by _dbg_interrupt_handler(), and _dbg_write_str_to_buffer().
|
static |
Mutex to prevent concurrent writes to print buffer.
Referenced by _dbg_unlock(), _dbg_wait_for_lock(), and dbg_init().
|
static |
Variable for buffer space requests.
Referenced by _dbg_interrupt_handler(), and _dbg_request_free_space().
|
static |
Semaphore to signal buffer has requested space.
Referenced by _dbg_interrupt_handler(), _dbg_wait_for_requested_space(), and dbg_init().
|
static |
Pointer to SERCOM USART instance to use.
Referenced by _dbg_interrupt_handler(), _dbg_start_uart(), _dbg_stop_uart(), and dbg_init().