#include "rpp/rpp.h"
#if rppCONFIG_INCLUDE_SDR == 1
+#include <string.h>
+#if rppCONFIG_DRV == 1
+#include "drv/drv.h"
+#else
+#include <stdio.h>
+#define rpp_sci_putc(x) putchar(x)
+#define rpp_sci_printf(x) printf(x)
+#endif
+
+/// Memory pointer variables ---------------------------------------------------
+static uint32_t memory_size = 0;
+static uint8_t* memory_start = NULL;
+static uint8_t* memory_end = NULL;
+static uint8_t* memory_current = NULL;
+
+
+
+/// Command processor task -----------------------------------------------------
+// SCI log command processor task
+void rpp_sdr_cmdproc(void *p)
+{
+ rpp_sci_printf((const char*)"Log control application:\r\n");
+ rpp_sci_printf((const char*)"================================\r\n");
+ rpp_sci_printf((const char*)"--> ");
+
+ while(TRUE) {
+ }
+}
+
+
+
+/// Show log task --------------------------------------------------------------
+// Semaphore to order the show task to start flushing the log
+static xSemaphoreHandle show_semaphore;
+
+// Flag to check if log show task is flushing the log
+static boolean_t show_flushing = FALSE;
+
+// Show log task
+void rpp_sdr_showtask(void *p)
+{
+ uint8_t* current;
+ uint8_t byte;
+
+ while(TRUE) {
+
+ // Wait semaphore to start
+ xSemaphoreTake(show_semaphore, portMAX_DELAY);
+ current = memory_start;
+
+ // Iterate until the end of the log
+ while(show_flushing && (current != memory_current)) {
+
+ // Print characters in this memory location.
+ // Ignores non-printable characters except \r and \n
+ byte = *current;
+ if((byte == '\r') || (byte == '\n') || isprint(byte)) {
+ rpp_sci_putc(byte);
+ }
+ current++;
+ }
+ }
+}
+
+
+
+/// Public API -----------------------------------------------------------------
+// Flag to check if SDR module is initialized
static boolean_t initialized = FALSE;
+// Initialize SDR module
int8_t rpp_sdr_init()
{
if(initialized) {
}
initialized = TRUE;
- // FIXME: Implement.
- return SUCCESS;
+ // Create log show semaphore
+ vSemaphoreCreateBinary(show_semaphore);
+
+ // Define memory bounds
+ #if rppCONFIG_DRV == 1
+ memory_size = RPP_SDR_ADDR_END - RPP_SDR_ADDR_START + 1;
+ memory_start = (uint8_t*)RPP_SDR_ADDR_START;
+ memory_end = (uint8_t*)RPP_SDR_ADDR_END;
+ #else
+ // Allocate 1MB for test
+ memory_size = 1024*1024;
+ memory_start = (uint8_t*)malloc(memory_size);
+ memory_end = (uint8_t*)((uint32_t)memory_start + memory_size - 1);
+ #endif
+ memory_current = memory_start;
+
+ return SUCCESS;
+}
+
+
+// General flag to check if logging is enabled
+static boolean_t log_enabled = FALSE;
+
+// Task handle for command processor task
+static xTaskHandle cmdproc_handle;
+
+// Task handle for log show task
+static xTaskHandle show_handle;
+
+// Enable/Disable logging
+int8_t rpp_sdr_setup(boolean_t enable)
+{
+ // No change, ignore
+ if(log_enabled == enable) {
+ return FAILURE;
+ }
+
+ // Shut down is requested
+ if(log_enabled && !enable) {
+ // Disable logging
+ log_enabled = FALSE;
+ // Stop show task if running
+ rpp_sdr_show(FALSE);
+ // Delete tasks
+ vTaskDelete(cmdproc_handle);
+ vTaskDelete(show_handle);
+
+ // Startup is requested
+ } else {
+ log_enabled = TRUE;
+ xTaskCreate(rpp_sdr_cmdproc,
+ "rpp_sdr_cmdproc", 512, NULL, 2, &cmdproc_handle);
+ xTaskCreate(rpp_sdr_showtask,
+ "rpp_sdr_showtask", 512, NULL, 2, &show_handle);
+ }
+
+ return SUCCESS;
+}
+
+
+// Store something to the log, if logging is enabled
+int32_t rpp_sdr_printf(const char* format, ...)
+{
+ if(!log_enabled) {
+ return FAILURE;
+ }
+
+ /// Format user string
+ char str[MAX_BUFFER_LEN];
+ int length = -1;
+
+ va_list argList;
+ va_start(argList, format);
+
+ length = vsnprintf(str, sizeof(str), format, argList);
+
+ va_end(argList);
+
+ if(length < 1) {
+ return length;
+ }
+
+
+ /// Format header
+ // uint32_t max value is 4294967295 (10 digits) + [] + ' ' + '\0' = 14
+ char hdr[14];
+ int hdr_length = -1;
+ hdr_length = vsnprintf(hdr, sizeof(hdr), "[%10d] ", xTaskGetTickCount());
+
+ if(hdr_length < 1) {
+ return hdr_length;
+ }
+
+
+ /// Write header
+ uint32_t cnt = 0;
+ int i = 0;
+ while((memory_current != memory_end) && (i < hdr_length)) {
+
+ *memory_current = hdr[i];
+
+ memory_current++;
+ cnt++;
+ i++;
+ }
+
+
+ /// Write user string
+ i = 0;
+ while((memory_current != memory_end) && (i < length)) {
+
+ *memory_current = str[i];
+
+ memory_current++;
+ cnt++;
+ i++;
+ }
+
+ /// Write trailer
+ const static char trailer[2] = {'\r', '\n'};
+ i = 0;
+ while((memory_current != memory_end) && (i < sizeof(trailer))) {
+
+ *memory_current = trailer[i];
+
+ memory_current++;
+ cnt++;
+ i++;
+ }
+
+ return cnt;
+}
+
+
+// Clears log. Will also stop the show task
+int8_t rpp_sdr_clear();
+{
+ if(!log_enabled) {
+ return FAILURE;
+ }
+
+ // Stop log show flushing if running
+ if(show_flushing) {
+ rpp_sdr_show(FALSE);
+ }
+
+ // Reset memory pointer
+ memory_pointer = memory_start;
+
+ return SUCCESS;
+}
+
+
+// Starts/Stops the task that sends the log to the SCI
+int8_t rpp_sdr_show(boolean_t start)
+{
+ if(!log_enabled) {
+ return FAILURE;
+ }
+
+ // No change, ignore
+ if(start == show_flushing) {
+ return FAILURE;
+ }
+
+ // Log flush stop requested
+ if(show_flushing && !start) {
+ show_flushing = FALSE;
+
+ // Log flush start requested
+ } else {
+ show_flushing = TRUE;
+ xSemaphoreGive(show_semaphore);
+ }
+
+ return SUCCESS;
}