- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
}
Link Copied

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page