Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12599 Discussions

Communication between HPS UART and external device Cyclone V

Altera_Forum
Honored Contributor II
1,687 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