Nios® II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
12452 Discussions

Communication between HPS UART and external device Cyclone V

Altera_Forum
Honored Contributor II
1,260 Views

I am using the HPS UART to communicate with the Ergometer. I have used the API's from the SOC kit folder (altera/14.1/embedded/ip/altera/hps/altera_hps/hwlib/src/hwmgr) but when i run my code in Linux on the SOC kit, it gives me a segmentation error although all the UART Register addresses are well assigned. Am i using the correct APIs? I have attached my code. Below is my code. Thanks!!

 

 

 

 

#include <stdio.h>

#include <stdint.h>

#include <stdlib.h>

#include <stddef.h>

#include <string.h> // string function definitions

#include <unistd.h> // UNIX standard function definitions

#include <fcntl.h> // File control definitions

#include <errno.h> // Error number definitions

#include <termios.h> // POSIX terminal control definitions

#include <stdbool.h>

#include <sys/types.h>

#include "ergo.h"

#include "alt_clock_manager.h"

#include "hwlib.h"

#include "alt_clock_group.h"

#include "alt_hwlibs_ver.h"

#include "alt_16550_uart.h"

#include "uart.h"

#include "socal/alt_clkmgr.h"

#include "socal/alt_rstmgr.h"

#include "socal/alt_uart.h"

#include "socal/hps.h"

#include "socal/socal.h"

 

 

 

/* commands to control the ergo bike */

#define ERGO_CMD_GET_ADDRESS 0x11

#define ERGO_CMD_RUN_DATA 0x40

#define ERGO_CMD_SET_WATT 0x51

#define UART_MAX_DATA 20

#define enable_init TRUE

 

 

/*Global Variables*/

ergo_run_data_t ergo_run_data;

u_int8_t ergo_adr_int;

 

 

/* External Functions that are called in the main function*/

static ALT_STATUS_CODE alt_16550_reset_helper(ALT_16550_HANDLE_t * handle, bool enable_init);

static inline uint32_t alt_read_word_helper(const void * addr);

static ALT_STATUS_CODE alt_16550_write_divisor_helper(ALT_16550_HANDLE_t * handle,uint32_t divisor);

ALT_STATUS_CODE alt_clk_clock_enable(ALT_CLK_t ALT_CLK_L4_SP);

ALT_STATUS_CODE alt_clk_is_enabled(ALT_CLK_t ALT_CLK_L4_SP);

ALT_STATUS_CODE alt_clk_freq_get(ALT_CLK_t ALT_CLK_L4_SP,alt_freq_t* freq);

ALT_STATUS_CODE alt_16550_fifo_write(ALT_16550_HANDLE_t * handle,const char * buffer,size_t count);

void ergo_get_address(ALT_16550_HANDLE_t * handle);

void ergo_get_run_data(void);

void ergo_set_watt(u_int8_t ergo_adr_int, u_int8_t watt);

void ergo_reset(ALT_16550_HANDLE_t * handle,u_int8_t ergo_adr_int);

void ergo_break(void);

 

 

/*function to enable the SOCFPGA UART Clock*/

ALT_STATUS_CODE alt_clk_clock_enable(ALT_CLK_t ALT_CLK_L4_SP)

{

 

 

if (alt_clk_clock_enable(ALT_CLK_L4_SP) != ALT_E_ERROR)

{

 

return ALT_E_SUCCESS; // The operation was successfull

}

else

{

return ALT_E_ERROR; // The operation was not successfull

}

 

}

 

/*Function to check whether the SOCFPGA Clock is enabled*/

ALT_STATUS_CODE alt_clk_is_enabled(ALT_CLK_t ALT_CLK_L4_SP)

{

ALT_16550_HANDLE_t * handle;

handle->clock_freq = 0;

 

if (alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE)

{

return ALT_E_BAD_CLK;

}

else

{

ALT_STATUS_CODE status;

status = alt_clk_freq_get(ALT_CLK_L4_SP, &handle->clock_freq);

}

}

 

//function to get the clock frequency

ALT_STATUS_CODE alt_clk_freq_get(ALT_CLK_t ALT_CLK_L4_SP,alt_freq_t* freq)

{

 

ALT_16550_HANDLE_t * handle;

handle->clock_freq = 0;

 

ALT_STATUS_CODE status;

status = alt_clk_freq_get(ALT_CLK_L4_SP, &handle->clock_freq);

 

if (status != ALT_E_SUCCESS)

{

return status;

}

 

}

 

struct uart_data_t

{

 

size_t tx_count; /*amount of data to send*/

 

char tx_buffer[UART_MAX_DATA]; /*data to send*/

 

size_t rx_count; /*amount of data to send*/

 

char rx_buffer[UART_MAX_DATA]; /*data received*/

 

 

}uart_data_t;

 

/*==========================UART functions======================*/

 

/*----------------------------- uart_init() -------------------------*/

/**

* Übergabeparameter: -

* Return: -

* Funktion: Initialisiert UART-Schnittstelle

*---------------------------------------------------------------------*/

 

 

int main()

{

/* Open File Descriptor */

int USB = open( "/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK);

 

 

//Error Handling

if ( USB < 0 )

{

printf("Error beim oeffnen");

}

 

 

 

// Configure Port

struct termios tty;

struct termios tty_old;

memset (&tty, 0, sizeof tty);

 

// Error Handling

if ( tcgetattr ( USB, &tty ) != 0 )

{

printf("error beim tcgetattr");

}

 

// Save old tty parameters

tty_old = tty;

 

 

 

ALT_16550_HANDLE_t * handle;

handle->data;

handle->fcr;

handle->clock_freq;

handle->location; //ALT_UART0_ADDR

handle->device;

 

//ALT_16550_DEVICE_SOCFPGA_UART0 = 0; //This option selects UART0 in the SoC FPGA

 

ALT_16550_DEVICE_t device; //

ALT_STATUS_CODE status;

alt_freq_t clock_freq;

void *location;

const void * addr;

bool enable_init;

uint32_t baudrate = ALT_16550_BAUDRATE_9600;

 

uint32_t divisor; //((handle->clock_freq + (8 * baudrate)) / (16 * baudrate));

 

printf("Program start \n");

 

// Enable the UART Clock

alt_clk_clock_enable(ALT_CLK_L4_SP);

 

// Helper function to reset and Initialise the UART (UART 0)

alt_16550_reset_helper(handle, enable_init);

 

// Helper function to carryout the actual register read.

alt_read_word_helper(addr);

 

//Helper function to write the divisor in Hardware

alt_16550_write_divisor_helper(handle,divisor);

 

//Enable the UART (UART 0)

alt_16550_enable(handle);

 

//Enable the FIFO

alt_16550_fifo_enable(handle);

 

//Get the Ergometer address

ergo_get_address(handle);

 

return 0;

}

 

 

/*--------------------------- ergo_get_adr() ------------------------*/

/**

* Übergabeparameter: -

* Return: -

* Funktion: Holen der Ergometer-Adreesse (1 Byte)

*---------------------------------------------------------------------*/

 

void ergo_get_address(ALT_16550_HANDLE_t * handle)

{

struct uart_data_t data;

 

/* build up data frame for address request */

data.tx_count = 1; // amount of data to send

data.tx_buffer[0] = ERGO_CMD_GET_ADDRESS;

data.rx_count = 2; /*amount of data to receive*/

 

/* get address from ergo bike */

alt_16550_fifo_write(handle, &(char) {0x12},1);

alt_16550_fifo_read(handle,data.rx_buffer,2);

 

/* save ergo address if the bike responded */

if(data.rx_buffer[0] == ERGO_CMD_GET_ADDRESS)

{

ergo_adr_int = data.rx_buffer[1];

printf("%d\n",data.rx_buffer[1]);

}

 

/* wait for 50ms */

ergo_break();

 

return;

}

 

/*---------------------------- ergo_reset() -------------------------*/

/**

* Übergabeparameter: u_int8_t ergo_adr_int

* Return: -

* Funktion: Setzt Ergometer zurück

*---------------------------------------------------------------------*/

 

void ergo_reset(ALT_16550_HANDLE_t * handle,u_int8_t ergo_adr_int)

{

alt_16550_fifo_write(handle,&(char) {0x12},1);

alt_16550_fifo_write(handle,&(char) {ergo_adr_int},1);

ergo_break();

return;

}

 

/*---------------------------- ergo_break() -------------------------*/

/**

* Übergabeparameter: -

* Return: -

* Funktion: Wait for about 50 ms

*---------------------------------------------------------------------*/

void ergo_break(void)

{

u_int16_t d1;

u_int8_t d2;

 

//wait for ~50 ms

for(d1=0; d1 < 65535; d1++)

{

for(d2=0; d2 < 64; d2++)

{

}

}

 

return;

}

0 Kudos
0 Replies
Reply