
- Fix some memory access bugs - Add optional support for CUDA FFTs - Compile a shared library, as part of a gnuradio integration project
464 lines
12 KiB
C
464 lines
12 KiB
C
/***************************************************************************//**
|
|
* @file console.c
|
|
* @brief Implementation of Console Driver.
|
|
* @author DBogdan (dragos.bogdan@analog.com)
|
|
********************************************************************************
|
|
* Copyright 2013(c) Analog Devices, Inc.
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* - Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* - Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* - Neither the name of Analog Devices, Inc. nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
* - The use of this software may or may not infringe the patent rights
|
|
* of one or more patent holders. This license does not release you
|
|
* from the requirement that you obtain separate licenses from these
|
|
* patent holders to use this software.
|
|
* - Use of the software either in source or binary form, must be run
|
|
* on or directly connected to an Analog Devices Inc. component.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
/***************************** Include Files **********************************/
|
|
/******************************************************************************/
|
|
#include "stdarg.h"
|
|
#include "stdlib.h"
|
|
#include "stdio.h"
|
|
#include "console.h"
|
|
|
|
/***************************************************************************//**
|
|
* @brief Initializes the UART communication peripheral. If the value of the
|
|
* baud rate is not equal with the ipcore's baud rate the
|
|
* initialization going to FAIL.
|
|
*
|
|
* @param baudRate - Baud rate value.
|
|
* Example: 9600 - 9600 bps.
|
|
*
|
|
* @return status - Result of the initialization procedure.
|
|
* Example: 0 - if initialization was successful;
|
|
* -1 - if initialization was unsuccessful.
|
|
*
|
|
*******************************************************************************/
|
|
char uart_init(unsigned long baudRate)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Writes one character to UART.
|
|
*
|
|
* @param data - Character to write.
|
|
*
|
|
* @return None.
|
|
*******************************************************************************/
|
|
void uart_write_char(char data)
|
|
{
|
|
putchar(data);
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Reads one character from UART.
|
|
*
|
|
* @return received_char - Read character.
|
|
*
|
|
* Note: Blocking function - Waits until get a valid data.
|
|
*******************************************************************************/
|
|
void uart_read_char(char * data)
|
|
{
|
|
*data = getchar();
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Writes one character string to UART.
|
|
*
|
|
* @param data - Character to write.
|
|
*
|
|
* @return None.
|
|
*******************************************************************************/
|
|
void uart_write_string(const char* string)
|
|
{
|
|
while(*string)
|
|
{
|
|
uart_write_char(*string++);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Converts an integer number to a string of ASCII characters string.
|
|
*
|
|
* @param number - Integer number.
|
|
* @param base - Numerical base used to represent the integer number as
|
|
* string.
|
|
*
|
|
* @return Pointer to the string of ASCII characters.
|
|
*******************************************************************************/
|
|
char *int_to_str(long number, char base)
|
|
{
|
|
unsigned long pos_number = 0;
|
|
char neg_sign = 0;
|
|
const char digits[17] = "0123456789ABCDEF";
|
|
static char buffer[17] = " ";
|
|
char* buffer_ptr = &buffer[16];
|
|
|
|
if((number < 0) && (base == 10))
|
|
{
|
|
neg_sign = 1;
|
|
pos_number = -1 * number;
|
|
}
|
|
else
|
|
{
|
|
pos_number = (unsigned long)number;
|
|
}
|
|
do
|
|
{
|
|
*buffer_ptr-- = digits[pos_number % base];
|
|
pos_number /= base;
|
|
}
|
|
while(pos_number != 0);
|
|
if(neg_sign)
|
|
{
|
|
*buffer_ptr-- = '-';
|
|
}
|
|
*buffer_ptr++;
|
|
|
|
return buffer_ptr;
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Prints formatted data to console.
|
|
*
|
|
* @param str - String to be printed.
|
|
*
|
|
* @return None.
|
|
*******************************************************************************/
|
|
void console_print(char* str, ...)
|
|
{
|
|
char* string_ptr;
|
|
char first_param = 0;
|
|
char second_param = 0;
|
|
unsigned long x_mask = 0;
|
|
unsigned long d_mask = 0;
|
|
char ch_number = 0;
|
|
unsigned long multiplier = 1;
|
|
char* str_arg;
|
|
long long_arg;
|
|
double double_arg;
|
|
va_list argp;
|
|
|
|
va_start(argp, str);
|
|
for(string_ptr = str; *string_ptr != '\0'; string_ptr++)
|
|
{
|
|
if(*string_ptr!='%')
|
|
{
|
|
uart_write_char(*string_ptr);
|
|
continue;
|
|
}
|
|
string_ptr++;
|
|
first_param = 0;
|
|
while((*string_ptr >= 0x30) & (*string_ptr <= 0x39))
|
|
{
|
|
first_param *= 10;
|
|
first_param += (*string_ptr - 0x30);
|
|
string_ptr++;
|
|
}
|
|
if(*string_ptr == '.')
|
|
{
|
|
string_ptr++;
|
|
second_param = 0;
|
|
while((*string_ptr >= 0x30) & (*string_ptr <= 0x39))
|
|
{
|
|
second_param *= 10;
|
|
second_param += (*string_ptr - 0x30);
|
|
string_ptr++;
|
|
}
|
|
}
|
|
switch(*string_ptr)
|
|
{
|
|
case 'c':
|
|
long_arg = va_arg(argp, long);
|
|
uart_write_char((char)long_arg);
|
|
break;
|
|
case 's':
|
|
str_arg = va_arg(argp, char*);
|
|
uart_write_string(str_arg);
|
|
break;
|
|
case 'd':
|
|
long_arg = va_arg(argp, long);
|
|
uart_write_string(int_to_str(long_arg, 10));
|
|
break;
|
|
case 'x':
|
|
long_arg = va_arg(argp, long);
|
|
x_mask = 268435456;
|
|
ch_number = 8;
|
|
while(x_mask > long_arg)
|
|
{
|
|
x_mask /= 16;
|
|
ch_number--;
|
|
}
|
|
while(ch_number < first_param)
|
|
{
|
|
uart_write_char('0');
|
|
ch_number++;
|
|
}
|
|
if(long_arg != 0)
|
|
{
|
|
uart_write_string(int_to_str(long_arg, 16));
|
|
}
|
|
break;
|
|
case 'f':
|
|
double_arg = va_arg(argp, double);
|
|
if(second_param == 0)
|
|
{
|
|
second_param = 3;
|
|
}
|
|
ch_number = second_param;
|
|
while(ch_number > 0)
|
|
{
|
|
multiplier *= 10;
|
|
ch_number--;
|
|
}
|
|
double_arg *= multiplier;
|
|
if(double_arg < 0)
|
|
{
|
|
double_arg *= -1;
|
|
uart_write_char('-');
|
|
}
|
|
long_arg = (long)double_arg;
|
|
uart_write_string(int_to_str((long_arg / multiplier), 10));
|
|
uart_write_char('.');
|
|
d_mask = 1000000000;
|
|
ch_number = 10;
|
|
while(d_mask > (long)(long_arg % multiplier))
|
|
{
|
|
d_mask /= 10;
|
|
ch_number--;
|
|
}
|
|
while(ch_number < second_param)
|
|
{
|
|
uart_write_char('0');
|
|
ch_number++;
|
|
}
|
|
if((long_arg % multiplier) != 0)
|
|
{
|
|
uart_write_string(int_to_str((long_arg % multiplier), 10));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
va_end(argp);
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Initializes the serial console.
|
|
*
|
|
* @param baud_rate - Baud rate value.
|
|
* Example: 9600 - 9600 bps.
|
|
*
|
|
* @return status - Result of the initialization procedure.
|
|
* Example: -1 - if initialization was unsuccessful;
|
|
* 0 - if initialization was successful.
|
|
*******************************************************************************/
|
|
char console_init(unsigned long baud_rate)
|
|
{
|
|
return uart_init(baud_rate);
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Reads one command from console.
|
|
*
|
|
* @param command - Read command.
|
|
*
|
|
* @return None.
|
|
*******************************************************************************/
|
|
void console_get_command(char* command)
|
|
{
|
|
char received_char = 0;
|
|
unsigned char char_number = 0;
|
|
|
|
while((received_char != '\n') && (received_char != '\r'))
|
|
{
|
|
uart_read_char(&received_char);
|
|
command[char_number++] = received_char;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Compares two commands and returns the type of the command.
|
|
*
|
|
* @param received_cmd - Received command.
|
|
* @param expected_cmd - Expected command.
|
|
* @param param - Parameters' buffer.
|
|
* @param param_no - Nomber of parameters.
|
|
*
|
|
* @return cmd_type - Type of the command.
|
|
* Example: UNKNOWN_CMD - Commands don't match.
|
|
* DO_CMD - Do command (!).
|
|
* READ_CMD - Read command (?).
|
|
* WRITE_CMD - Write command (=).
|
|
*******************************************************************************/
|
|
int console_check_commands(char* received_cmd,
|
|
const char* expected_cmd,
|
|
double* param,
|
|
char* param_no)
|
|
{
|
|
int cmd_type = 1;
|
|
unsigned char char_index = 0;
|
|
char param_string[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
unsigned char param_index = 0;
|
|
unsigned char index = 0;
|
|
const char digits[17] = "0123456789ABCDEF";
|
|
unsigned char digit_index = 0;
|
|
|
|
while((expected_cmd[char_index] != '!') &&
|
|
(expected_cmd[char_index] != '?') &&
|
|
(expected_cmd[char_index] != '=') &&
|
|
(cmd_type != UNKNOWN_CMD))
|
|
{
|
|
if(expected_cmd[char_index] != received_cmd[char_index])
|
|
{
|
|
cmd_type = UNKNOWN_CMD;
|
|
}
|
|
char_index++;
|
|
}
|
|
if(cmd_type != UNKNOWN_CMD)
|
|
{
|
|
if(expected_cmd[char_index] == '!')
|
|
{
|
|
if(received_cmd[char_index] == '!')
|
|
{
|
|
cmd_type = DO_CMD;
|
|
}
|
|
else
|
|
{
|
|
cmd_type = UNKNOWN_CMD;
|
|
}
|
|
}
|
|
if(expected_cmd[char_index] == '?')
|
|
{
|
|
if(received_cmd[char_index] == '?')
|
|
{
|
|
cmd_type = READ_CMD;
|
|
}
|
|
else
|
|
{
|
|
cmd_type = UNKNOWN_CMD;
|
|
}
|
|
}
|
|
if(expected_cmd[char_index] == '=')
|
|
{
|
|
if(received_cmd[char_index] == '=')
|
|
{
|
|
cmd_type = WRITE_CMD;
|
|
}
|
|
else
|
|
{
|
|
cmd_type = UNKNOWN_CMD;
|
|
}
|
|
}
|
|
if((cmd_type == WRITE_CMD) || (cmd_type == READ_CMD))
|
|
{
|
|
char_index++;
|
|
while((received_cmd[char_index] != '\n') &&
|
|
(received_cmd[char_index] != '\r'))
|
|
{
|
|
if((received_cmd[char_index] == 0x20))
|
|
{
|
|
*param = 0;
|
|
if((param_string[0] == '0') && (param_string[1] == 'x'))
|
|
{
|
|
for(index = 2; index < param_index; index++)
|
|
{
|
|
for(digit_index = 0; digit_index < 16; digit_index++)
|
|
{
|
|
if(param_string[index] == digits[digit_index])
|
|
{
|
|
*param = *param * 16;
|
|
*param = *param + digit_index;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(param_string[0] == '-')
|
|
{
|
|
*param = atof((const char*)(¶m_string[1]));
|
|
*param *= (-1);
|
|
}
|
|
else
|
|
{
|
|
*param = atof((const char*)param_string);
|
|
}
|
|
}
|
|
param++;
|
|
*param_no += 1;
|
|
for(param_index = 0; param_index < 10; param_index++)
|
|
{
|
|
param_string[param_index] = 0;
|
|
}
|
|
param_index = 0;
|
|
char_index++;
|
|
}
|
|
else
|
|
{
|
|
param_string[param_index] = received_cmd[char_index];
|
|
char_index++;
|
|
param_index++;
|
|
}
|
|
}
|
|
if(param_index)
|
|
{
|
|
*param = 0;
|
|
if((param_string[0] == '0') && (param_string[1] == 'x'))
|
|
{
|
|
for(index = 2; index < param_index; index++)
|
|
{
|
|
for(digit_index = 0; digit_index < 16; digit_index++)
|
|
{
|
|
if(param_string[index] == digits[digit_index])
|
|
{
|
|
*param *= 16;
|
|
*param += digit_index;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(param_string[0] == '-')
|
|
{
|
|
*param = atof((const char*)(¶m_string[1]));
|
|
*param *= (-1);
|
|
}
|
|
else
|
|
{
|
|
*param = atof((const char*)param_string);
|
|
}
|
|
}
|
|
*param_no += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return cmd_type;
|
|
}
|