blob: 855f4ba1ae085f19527c4dbf924fecbf6d82c83d [file] [log] [blame]
/******************************************************************************
*
* Copyright 2013 Altera Corporation. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 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 <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "alt_16550_uart.h"
#include "uart0_support.h"
static ALT_16550_HANDLE_t g_uart0_handle;
ALT_STATUS_CODE uart0_init(void) {
ALT_STATUS_CODE status;
status = alt_16550_init(ALT_16550_DEVICE_SOCFPGA_UART0, 0, 0, &g_uart0_handle);
status += alt_16550_line_config_set(&g_uart0_handle, ALT_16550_DATABITS_8, ALT_16550_PARITY_DISABLE, ALT_16550_STOPBITS_1);
status += alt_16550_baudrate_set(&g_uart0_handle, ALT_16550_BAUDRATE_115200);
status += alt_16550_fifo_enable(&g_uart0_handle);
status += alt_16550_enable(&g_uart0_handle);
return status;
}
ALT_STATUS_CODE uart0_uninit(void) {
ALT_STATUS_CODE status = 0;
status += alt_16550_disable(&g_uart0_handle);
status += alt_16550_fifo_disable(&g_uart0_handle);
status += alt_16550_uninit(&g_uart0_handle);
return status;
}
ALT_STATUS_CODE uart0_print(const char *in_str) {
ALT_STATUS_CODE status = ALT_E_SUCCESS;
int i;
int len = strlen(in_str);
uint32_t size_tx;
if (status == ALT_E_SUCCESS) {
status = alt_16550_fifo_size_get_tx(&g_uart0_handle, &size_tx);
}
for (i = 0; i < 1000; ++i)
{
if (status != ALT_E_SUCCESS) {
break;
}
if (len == 0) {
break;
}
// Wait for the THRE line status
int j = 1000000;
while (--j) {
uint32_t line_status = 0;
status = alt_16550_line_status_get(&g_uart0_handle, &line_status);
if (status != ALT_E_SUCCESS) {
break;
}
if (line_status & (ALT_16550_LINE_STATUS_THRE | ALT_16550_LINE_STATUS_TEMT)) {
break;
}
}
if (j == 0) {
status = ALT_E_TMO;
}
uint32_t level_tx;
if (status == ALT_E_SUCCESS) {
status = alt_16550_fifo_level_get_tx(&g_uart0_handle, &level_tx);
}
if (status == ALT_E_SUCCESS) {
uint32_t size_write = MIN(len, size_tx - level_tx);
status = alt_16550_fifo_write(&g_uart0_handle, in_str, size_write);
if (status == ALT_E_SUCCESS) {
len -= size_write;
in_str += size_write;
}
}
}
return status;
}
int uart0_printf(const char *fmt, ...) {
ALT_STATUS_CODE status = ALT_E_SUCCESS;
int len = 0;
char buffer[1024];
va_list vl;
va_start(vl, fmt);
len = vsnprintf(buffer, sizeof(buffer), fmt, vl);
va_end(vl);
if(len >= sizeof(buffer)) {
buffer[sizeof(buffer) - 1] = '\0';
status = uart0_print(buffer);
if( status != ALT_E_SUCCESS)
return status;
status = uart0_print("\r\nERROR: uart0_printf_buffer overflow...\r\n");
if( status != ALT_E_SUCCESS)
return status;
} else {
status = uart0_print(buffer);
if( status != ALT_E_SUCCESS)
return status;
}
return len;
}
int uart0_getc(void) {
ALT_STATUS_CODE status = ALT_E_SUCCESS;
int ret_val = EOF;
uint32_t level;
status = alt_16550_fifo_level_get_rx(&g_uart0_handle, &level);
if(status != ALT_E_SUCCESS)
return ret_val;
if(level > 0) {
char buffer;
status = alt_16550_fifo_read(&g_uart0_handle, &buffer, 1);
if(status != ALT_E_SUCCESS)
return ret_val;
else
return buffer;
}
return ret_val;
}
/* md5sum:3086bef986334caa60e4e70a63fba834 2013-09-28 20:48:16 */