Commit 6a39e935 authored by Federico Vaga's avatar Federico Vaga

svec-demo: use librt for demo application

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent f2aa4688
......@@ -9,6 +9,7 @@
#ifndef __DEMO_COMMON_H
#define __DEMO_COMMON_H
#include <wrnc-common.h>
/* HMQ slots used for input */
#define DEMO_HMQ_IN 0
......@@ -16,20 +17,46 @@
/* HMQ slots used for output */
#define DEMO_HMQ_OUT 0
/* Variable index - used only by demo-librt */
enum rt_variable_index {
DEMO_VAR_LEMO_STA = 0,
DEMO_VAR_LEMO_DIR,
DEMO_VAR_LEMO_SET,
DEMO_VAR_LEMO_CLR,
DEMO_VAR_LED_STA,
DEMO_VAR_LED_SET,
DEMO_VAR_LED_CLR,
__DEMO_VAR_MAX,
};
enum rt_structure_index {
DEMO_STRUCT_TEST = 0,
__DEMO_STRUCT_MAX,
};
/* Command and log message IDs */
#define DEMO_ID_LED_SET 0x0001
#define DEMO_ID_LEMO_SET 0x0002
#define DEMO_ID_LEMO_DIR_SET 0x0003
#define DEMO_ID_STATE_GET 0x0004
#define DEMO_ID_ACK 0x0100
#define DEMO_ID_STATE_GET_REP 0x0200
#define PIN_LEMO_COUNT 4
#define PIN_LEMO_MASK (0x0000000F)
#define PIN_LED_COUNT 8
#define PIN_LED_OFFSET 8
#define PIN_LED_MASK (0xFFFFFF00)
enum rt_action_recv_demo {
DEMO_ID_LED_SET = __RT_ACTION_RECV_STANDARD_NUMBER,
DEMO_ID_LEMO_SET,
DEMO_ID_LEMO_DIR_SET,
DEMO_ID_STATE_GET,
DEMO_ID_RUN_AUTO,
DEMO_ID_STATE_GET_REP,
};
/* For the time being all fields must be 32bit because of HW limits */
#define DEMO_STRUCT_MAX_ARRAY 5
struct demo_structure {
uint32_t field1;
uint32_t field2;
uint32_t array[DEMO_STRUCT_MAX_ARRAY];
};
#define PIN_LEMO_COUNT 4
#define PIN_LEMO_MASK (0x0000000F)
#define PIN_LED_COUNT 8
#define PIN_LED_OFFSET 8
#define PIN_LED_MASK (0x0000FFFF)
#define PIN_LED_RED(ledno) (8 + (ledno * 2))
#define PIN_LED_GREEN(ledno) (9 + (ledno * 2))
......
......@@ -15,7 +15,7 @@ LDLIBS += -L. -ldemo
modules all: $(LIB)
%: %.c $(LIB)
%: %.c $(LIB) $(LIBRT)
$(CC) $(CFLAGS) $(LDFLAGS) $*.c $(LDLIBS) -o $@
$(LIB): $(LOBJ)
......
......@@ -16,6 +16,7 @@
const char *demo_errors[] = {
"Received an invalid answer from white-rabbit-node-code CPU",
"Real-Time application does not acknowledge",
};
......@@ -148,56 +149,23 @@ struct wrnc_dev *demo_get_wrnc_dev(struct demo_node *dev)
return (struct wrnc_dev *)demo->wrnc;
}
int demo_lemo_dir_set(struct demo_node *dev, uint32_t value)
{
struct demo_desc *demo = (struct demo_desc *)dev;
struct wrnc_msg msg;
struct wrnc_hmq *hmq;
int err;
/* Build the message */
msg.datalen = 3;
msg.data[0] = DEMO_ID_LEMO_DIR_SET;
msg.data[1] = 0;
msg.data[2] = value & PIN_LEMO_MASK;
hmq = wrnc_hmq_open(demo->wrnc, DEMO_HMQ_IN, WRNC_HMQ_INCOMING);
if (!hmq)
return -1;
uint32_t fields[] = {DEMO_VAR_LEMO_DIR, value};
/* Send synchronous message */
err = wrnc_hmq_send_and_receive_sync(hmq, DEMO_HMQ_OUT, &msg, 1000);
wrnc_hmq_close(hmq);
return err;
return wrnc_rt_variable_set(demo->wrnc, DEMO_HMQ_IN, DEMO_HMQ_OUT,
fields, sizeof(fields) / 4 / 2, 1);
}
int demo_lemo_set(struct demo_node *dev, uint32_t value)
{
struct demo_desc *demo = (struct demo_desc *)dev;
struct wrnc_msg msg;
struct wrnc_hmq *hmq;
int err;
uint32_t fields[] = {DEMO_VAR_LEMO_SET, value,
DEMO_VAR_LEMO_CLR, ~value};
/* Build the message */
msg.datalen = 3;
msg.data[0] = DEMO_ID_LEMO_SET;
msg.data[1] = 0;
msg.data[2] = value & PIN_LEMO_MASK;
hmq = wrnc_hmq_open(demo->wrnc, DEMO_HMQ_IN, WRNC_HMQ_INCOMING);
if (!hmq)
return -1;
/* Send synchronous message */
err = wrnc_hmq_send_and_receive_sync(hmq, DEMO_HMQ_OUT, &msg, 1000);
wrnc_hmq_close(hmq);
return err;
return wrnc_rt_variable_set(demo->wrnc, DEMO_HMQ_IN, DEMO_HMQ_OUT,
fields, sizeof(fields) / 4 / 2, 0);
}
......@@ -233,65 +201,71 @@ static uint32_t demo_apply_color(uint32_t value, enum demo_color color)
int demo_led_set(struct demo_node *dev, uint32_t value, enum demo_color color)
{
struct demo_desc *demo = (struct demo_desc *)dev;
struct wrnc_msg msg;
struct wrnc_hmq *hmq;
int err;
/* Build the message */
msg.datalen = 3;
msg.data[0] = DEMO_ID_LED_SET;
msg.data[1] = 0;
msg.data[2] = demo_apply_color(value, color);
hmq = wrnc_hmq_open(demo->wrnc, DEMO_HMQ_IN, WRNC_HMQ_INCOMING);
if (!hmq)
return -1;
uint32_t real_value = demo_apply_color(value, color);
uint32_t fields[] = {DEMO_VAR_LED_SET, real_value,
DEMO_VAR_LED_CLR, ~real_value};
/* Send asynchronous message, we do not wait for answers */
err = wrnc_hmq_send(hmq, &msg);
wrnc_hmq_close(hmq);
return err;
return wrnc_rt_variable_set(demo->wrnc, DEMO_HMQ_IN, DEMO_HMQ_OUT,
fields, sizeof(fields) / 4 / 2, 0);
}
#define DEMO_STATUS_N_VARIABLES 3
/**
* It gets the status of the DEMO program
*/
int demo_status_get(struct demo_node *dev, struct demo_status *status)
{
struct demo_desc *demo = (struct demo_desc *)dev;
struct wrnc_hmq *hmq;
struct wrnc_msg msg;
uint32_t fields[] = {DEMO_VAR_LEMO_STA, 0,
DEMO_VAR_LED_STA, 0,
DEMO_VAR_LEMO_DIR, 0};
int err;
/* Build the message */
msg.datalen = 2;
msg.data[0] = DEMO_ID_STATE_GET;
msg.data[1] = 0;
hmq = wrnc_hmq_open(demo->wrnc, DEMO_HMQ_IN, WRNC_HMQ_INCOMING);
if (!hmq)
return -1;
err = wrnc_rt_variable_get(demo->wrnc, DEMO_HMQ_IN, DEMO_HMQ_OUT,
fields, DEMO_STATUS_N_VARIABLES);
if (err)
return err;
/* Send synchronous message. The answer will overwrite our message */
err = wrnc_hmq_send_and_receive_sync(hmq, DEMO_HMQ_OUT, &msg, 1000);
status->lemo = fields[1];
status->led = fields[3];
status->lemo_dir = fields[5];
wrnc_hmq_close(hmq);
return 0;
}
int demo_run_autodemo(struct demo_node *dev, uint32_t run){ return 0; }
/* Check if it is the answer that we are expecting */
if (msg.data[0] != DEMO_ID_STATE_GET_REP) {
return -1;
}
int demo_version(struct demo_node *dev, struct wrnc_rt_version *version)
{
struct demo_desc *demo = (struct demo_desc *)dev;
/* unpack data */
status->led = msg.data[2];
status->lemo = msg.data[3];
status->lemo_dir = msg.data[4];
return wrnc_rt_version_get(demo->wrnc, version,
DEMO_HMQ_IN, DEMO_HMQ_OUT);
}
/* Of course you can use memcpy() to unpack, but this is a demo so,
this way is more explicit */
int demo_test_struct_get(struct demo_node *dev, struct demo_structure *test)
{
struct demo_desc *demo = (struct demo_desc *)dev;
struct wrnc_structure_tlv tlv = {
.index = DEMO_STRUCT_TEST,
.size = sizeof(struct demo_structure),
.structure = test,
};
return wrnc_rt_structure_get(demo->wrnc, DEMO_HMQ_IN, DEMO_HMQ_OUT,
&tlv, 1);
}
return err;
int demo_test_struct_set(struct demo_node *dev, struct demo_structure *test)
{
struct demo_desc *demo = (struct demo_desc *)dev;
struct wrnc_structure_tlv tlv = {
.index = DEMO_STRUCT_TEST,
.size = sizeof(struct demo_structure),
.structure = test,
};
return wrnc_rt_structure_set(demo->wrnc, DEMO_HMQ_IN, DEMO_HMQ_OUT,
&tlv, 1, 0);
}
......@@ -16,10 +16,12 @@ struct demo_status {
uint32_t led;
uint32_t lemo;
uint32_t lemo_dir;
uint32_t autodemo;
};
enum demo_error_list {
EDEMO_INVALID_ANSWER_ACK = 3200,
EDEMO_ANSWER_NACK,
__EDEMO_MAX_ERROR_NUMBER,
};
......@@ -42,4 +44,10 @@ extern int demo_led_set(struct demo_node *dev, uint32_t value,
extern int demo_lemo_set(struct demo_node *dev, uint32_t value);
extern int demo_lemo_dir_set(struct demo_node *dev, uint32_t value);
extern int demo_status_get(struct demo_node *dev, struct demo_status *status);
extern int demo_run_autodemo(struct demo_node *dev, uint32_t run);
extern int demo_version(struct demo_node *dev, struct wrnc_rt_version *version);
extern int demo_test_struct_set(struct demo_node *dev,
struct demo_structure *test);
extern int demo_test_struct_get(struct demo_node *dev,
struct demo_structure *test);
#endif
OBJS = autodemo.o
OBJS = autodemo.o ../common/demo-smem-code.o
OUTPUT = autodemo
WRNC = ../../../../
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=0xd330d330
EXTRA_CFLAGS += -DRT_APPLICATION_ID=0x1236
include $(WRNC)/applications/common/rt/Makefile
......@@ -10,6 +10,7 @@
#include <string.h>
#include "rt.h"
#include <demo-common-rt.h>
#define GPIO_CODR 0x0
#define GPIO_SODR 0x4
......@@ -20,9 +21,6 @@
#define PIN_LEMO_L3 3
#define PIN_LEMO_L4 2
#define PIN_LED_RED(ledno) (8+(ledno*2))
#define PIN_LED_GREEN(ledno) (9+(ledno*2))
void gpio_set_dir(int pin, int out)
{
uint32_t ddr = dp_readl(GPIO_DDR);
......@@ -46,25 +44,21 @@ int gpio_get_state(int pin)
return dp_readl(GPIO_PSR) & (1 << pin) ? 1 : 0;
}
main()
void autodemo()
{
int state, on = 1;
uint32_t i, j = 0;
/* Print something on the debug interface */
pp_printf("Hello, world!\n");
pp_printf("Running autodemo\n");
gpio_set_dir(PIN_LEMO_L1, 0); // Lemo L1 = input
gpio_set_dir(PIN_LEMO_L2, 1); // Lemo L2 = output
gpio_set_dir(PIN_LEMO_L3, 1); // Lemo L3 = output
gpio_set_dir(PIN_LEMO_L4, 1); // Lemo L4 = output
pp_printf("GPIO direction 0x%x\n", dp_readl(GPIO_DDR));
/* Just in case set led to OUTPUT and turn them on 1 red 1 green */
for (i = 0; i < 8; ++i) {
gpio_set_state(PIN_LED_RED(i), 0);
gpio_set_state(PIN_LED_GREEN(i), 0);
}
/* Clear all GPIOs (LEDs and LEMOs) */
dp_writel(~0, GPIO_CODR);
for (i = 0;; i++) {
/* Lemo 2 follows Lemo 1 */
......@@ -98,6 +92,33 @@ main()
dp_readl(GPIO_DDR),
dp_readl(GPIO_PSR));
}
/* Check if someone else (HOST or other RT application) want
to stop this execution */
if (!autodemo_run) {
pp_printf("Stopping autodemo\n");
break;
}
}
/* Clear all GPIOs (LEDs and LEMOs) */
dp_writel(~0, GPIO_CODR);
/* Set all GPIO as output */
dp_writel(~0, GPIO_DDR);
}
int main()
{
/* By default allow this program to run */
smem_atomic_or(&autodemo_run, 1);
while (1) {
/* Wait that someone (HOST or other RT application) allows
this program to run */
if (!autodemo_run)
continue;
autodemo();
}
}
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2015 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __DEMO_COMMON_RT_H__
#define __DEMO_COMMON_RT_H__
#include <rt-smem.h>
#include <demo-common.h>
extern volatile int autodemo_run;
#endif
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include "rt.h"
#include "demo-common-rt.h"
SMEM volatile int autodemo_run;
......@@ -3,5 +3,13 @@ OUTPUT = rt-demo
WRNC = ../../../../
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -D__MAX_ACTION_RECV=0
EXTRA_CFLAGS += -D__MAX_ACTION_SEND=0
EXTRA_CFLAGS += -DRTPERFORMANCE
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=0xd330d330
EXTRA_CFLAGS += -DRT_APPLICATION_ID=0xdeadbeef
EXTRA_CFLAGS += -DLIBRT_DEBUG -DLIBRT_ERROR
RT_USE_LIBRT := 1
include $(WRNC)/applications/common/rt/Makefile
OBJS = rt-demo.o
OUTPUT = rt-demo
PATH_COMMON = ../../../common/
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -D__MAX_ACTION_RECV=0
EXTRA_CFLAGS += -D__MAX_ACTION_SEND=0
EXTRA_CFLAGS += -DRTPERFORMANCE
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=0xd330d330
EXTRA_CFLAGS += -DRT_APPLICATION_ID=0x1234
EXTRA_CFLAGS += -DLIBRT_DEBUG
RT_USE_LIBRT := 1
include $(PATH_COMMON)/rt/Makefile
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include <rt.h>
#include <demo-common-rt.h>
#include <librt.h>
#define GPIO_CODR 0x0 /* Clear Data Register */
#define GPIO_SODR 0x4 /* Set Data Register */
#define GPIO_DDR 0x8 /* Direction Data Register */
#define GPIO_PSR 0xC /* Status Register */
static uint32_t out_seq = 0;
struct rt_variable demo_variables[] = {
[DEMO_VAR_LEMO_STA] = {
.addr = CPU_DP_BASE + GPIO_PSR,
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[DEMO_VAR_LEMO_DIR] = {
.addr = CPU_DP_BASE + GPIO_DDR,
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[DEMO_VAR_LEMO_SET] = {
.addr = CPU_DP_BASE + GPIO_SODR,
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[DEMO_VAR_LEMO_CLR] = {
.addr = CPU_DP_BASE + GPIO_CODR,
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[DEMO_VAR_LED_STA] = {
.addr = CPU_DP_BASE + GPIO_PSR,
.mask = PIN_LED_MASK,
.offset = 0,
},
[DEMO_VAR_LED_SET] = {
.addr = CPU_DP_BASE + GPIO_SODR,
.mask = PIN_LED_MASK,
.offset = 0,
},
[DEMO_VAR_LED_CLR] = {
.addr = CPU_DP_BASE + GPIO_CODR,
.mask = PIN_LED_MASK,
.offset = 0,
},
};
/**
* It sends messages over the debug interface
*/
static void demo_debug_interface(void)
{
pp_printf("Hello world.\n");
pp_printf("We are messages over the debug interface.\n");
pp_printf("Print here your messages.\n");
}
/**
* Well, the main :)
*/
int main()
{
demo_debug_interface();
rt_variable_export(demo_variables, __DEMO_VAR_MAX);
/* Register all the action that the RT application can take */
rt_mq_action_recv_register(RT_ACTION_RECV_PING, DEMO_HMQ_OUT,
rt_recv_ping);
rt_mq_action_recv_register(RT_ACTION_RECV_DATA_SET, DEMO_HMQ_OUT,
rt_setter);
rt_mq_action_recv_register(RT_ACTION_RECV_DATA_GET, DEMO_HMQ_OUT,
rt_getter);
while (1) {
/* Handle all messages incoming from slot DEMO_HMQ_IN
as actions */
rt_mq_action_dispatch(DEMO_HMQ_IN, 0);
}
return 0;
}
......@@ -9,130 +9,75 @@
#include <string.h>
#include <rt.h>
#include <demo-common.h>
#include <demo-common-rt.h>
#include <librt.h>
#define GPIO_CODR 0x0 /* Clear Data Register */
#define GPIO_SODR 0x4 /* Set Data Register */
#define GPIO_DDR 0x8 /* Direction Data Register */
#define GPIO_PSR 0xC /* Status Register */
void rt_get_time(uint32_t *seconds, uint32_t *cycles)
{
*seconds = lr_readl(WRN_CPU_LR_REG_TAI_SEC);
*cycles = lr_readl(WRN_CPU_LR_REG_TAI_CYCLES);
}
static uint32_t out_seq = 0;
/**
* Set LEDs value
*/
static void demo_led_set(uint32_t val)
{
val = (val << PIN_LED_OFFSET) & PIN_LED_MASK;
dp_writel(val, GPIO_SODR);
dp_writel((~val), GPIO_CODR);
}
/**
* Get the current LED status
*/
static uint32_t demo_led_get(void)
{
dp_readl(GPIO_PSR) & PIN_LED_MASK;
}
/**
* Set LEMOs value
*/
static void demo_lemo_set(uint32_t val)
{
dp_writel((val & PIN_LEMO_MASK),
GPIO_SODR);
dp_writel(((~val) & PIN_LEMO_MASK),
GPIO_CODR);
}
/**
* Get current LEMO status
*/
static uint32_t demo_lemo_get(void)
{
return dp_readl(GPIO_PSR) & PIN_LEMO_MASK;
}
/**
* Set direction for all LEMOs.
*/
static void demo_lemo_dir_set(uint32_t output)
{
dp_writel(output & PIN_LEMO_MASK, GPIO_DDR);
}
/**
* Get current LEMO's direction
*/
static uint32_t demo_lemo_dir_get(void)
{
return dp_readl(GPIO_DDR) & PIN_LEMO_MASK;
}
/**
* It sends the register status to the host.
*/
static void demo_status_send(uint32_t seq)
{
struct wrnc_msg out_buf;
out_buf = hmq_msg_claim_out (DEMO_HMQ_OUT, 128);
out_buf.data[0] = DEMO_ID_STATE_GET_REP;
out_buf.data[1] = seq;
out_buf.data[2] = demo_led_get();
out_buf.data[3] = demo_lemo_get();
out_buf.data[4] = demo_lemo_dir_get();
out_buf.datalen = 5;
/* Send the message */
hmq_msg_send (&out_buf);
}
/**
* Send the status to inform that the program is alive. The use of this
* function shows that we can autonomously send messages to the host
* whenever we want.
*/
static inline void demo_alive(void)
{
//pp_printf("Send Status.\n");
demo_status_send(out_seq);
out_seq++;
}
/**
* Sends an acknowledgement reply
*/
static inline void demo_hmq_ack(uint32_t seq)
{
struct wrnc_msg out_buf;
out_buf = hmq_msg_claim_out(DEMO_HMQ_OUT, 128);
/* For the time being there is not a standard for the acknowledge
message ID. The only constraint now is the fact that the sequence
number must be equal to the incoming sequence number */
out_buf.data[0] = DEMO_ID_ACK;
out_buf.data[1] = seq;
out_buf.datalen = 2;
/* Send the message */
hmq_msg_send(&out_buf);
}
static struct demo_structure demo_struct;
struct rt_structure demo_structures[] = {
[DEMO_STRUCT_TEST] = {
.struct_ptr = &demo_struct,
.len = sizeof(struct demo_structure),
}
};
struct rt_variable demo_variables[] = {
[DEMO_VAR_LEMO_STA] = {
.addr = CPU_DP_BASE + GPIO_PSR,
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[DEMO_VAR_LEMO_DIR] = {
.addr = CPU_DP_BASE + GPIO_DDR,
.mask = PIN_LEMO_MASK,
.offset = 0,
},
[DEMO_VAR_LEMO_SET] = {
.addr = CPU_DP_BASE + GPIO_SODR,
.mask = PIN_LEMO_MASK,
.offset = 0,
.flags = RT_VARIABLE_FLAG_WO,
},
[DEMO_VAR_LEMO_CLR] = {
.addr = CPU_DP_BASE + GPIO_CODR,
.mask = PIN_LEMO_MASK,
.offset = 0,
.flags = RT_VARIABLE_FLAG_WO,
},
[DEMO_VAR_LED_STA] = {
.addr = CPU_DP_BASE + GPIO_PSR,
.mask = PIN_LED_MASK,
.offset = PIN_LED_OFFSET,
},
[DEMO_VAR_LED_SET] = {
.addr = CPU_DP_BASE + GPIO_SODR,
.mask = PIN_LED_MASK,
.offset = PIN_LED_OFFSET,
.flags = RT_VARIABLE_FLAG_WO,
},
[DEMO_VAR_LED_CLR] = {
.addr = CPU_DP_BASE + GPIO_CODR,
.mask = PIN_LED_MASK,
.offset = PIN_LED_OFFSET,
.flags = RT_VARIABLE_FLAG_WO,
},
};
static action_t *demo_actions[] = {
[RT_ACTION_RECV_PING] = rt_recv_ping,
[RT_ACTION_RECV_VERSION] = rt_version_getter,
[RT_ACTION_RECV_FIELD_SET] = rt_variable_setter,
[RT_ACTION_RECV_FIELD_GET] = rt_variable_getter,
[RT_ACTION_RECV_STRUCT_SET] = rt_structure_setter,
[RT_ACTION_RECV_STRUCT_GET] = rt_structure_getter,
};
/**
* It sends messages over the debug interface
......@@ -145,121 +90,23 @@ static void demo_debug_interface(void)
}
/**
* It handles the incoming messages from an input HMQ.
* This show you a way to handle incoming messages from the host.
*
* Here we handle both synchronous and asynchronous messages.
*/
static void demo_handle_hmq_in(void)
{
#ifdef RTPERFORMANCE
uint32_t sec, cyc, sec_n, cyc_n;
#endif
struct wrnc_msg in_buf;
uint32_t id, seq, p, val;
/* HMQ control slot empty? */
p = mq_poll();
if (!(p & ( 1<< DEMO_HMQ_IN)))
return;
/* We have something in the input HMQ */
/* Get the message from the HMQ by claiming it */
in_buf = hmq_msg_claim_in(DEMO_HMQ_IN, 8);
/* Extract the ID and sequence number from the header */
id = in_buf.data[0];
seq = in_buf.data[1];
pp_printf("Received message ID 0x%x SEQ 0x%x DATA[0] 0x%x.\n",
id, seq, in_buf.data[2]);
/* According to the ID perform different actions */
#ifdef RTPERFORMANCE
rt_get_time(&sec, &cyc);
#endif
switch (id) {
/* Set LEDs */
case DEMO_ID_LED_SET:
/* Extract the LEDs status to set from the message */
val = in_buf.data[2];
/* Set the new LEDs status */
demo_led_set(val);
/* This is *not* a synchronous message, so it does not need
any acknowledge message. There are not particular reasons
against synchronous message, this is just an example */
break;
/* Set LEMOs */
case DEMO_ID_LEMO_SET:
/* Extract from the messag the LEMOs status to sete */
val = in_buf.data[2];
/* Set the new LEDs status */
demo_lemo_set(val);
/* This is a synchronous message, so send an acknowledge message
by using the same sequence number. There are not particulr reasons
to be synchronous message, this is just an example */
demo_hmq_ack(seq);
break;
/* Set LEMOs Direction */
case DEMO_ID_LEMO_DIR_SET:
/* Extract from the message the LEMO directions to set */
val = in_buf.data[2];
/* Set the new LEDs status */
demo_lemo_dir_set(val);
/* This is a synchronous message, so send an acknowledge message
by using the same sequence number. There are not particulr reasons
to be synchronous message, this is just an example */
demo_hmq_ack(seq);
break;
/* Get state */
case DEMO_ID_STATE_GET:
/* This is a synchronous message. The user asks for data so we
must answer synchrounously */
demo_status_send(seq);
break;
/* Other actions/cases here */
/* Unknown actions */
default:
pp_printf("Unknown ID %d.\n", id);
break;
}
#ifdef RTPERFORMANCE
rt_get_time(&sec_n, &cyc_n);
pp_printf("Action ID: %d | SEQ: | %d TIME: %dns\n",
id, seq, (cyc_n - cyc) * 8);
#endif
/* Drop the message once handled */
mq_discard(0, DEMO_HMQ_IN);
}
/**
* Well, the main :)
*/
int main()
{
int i = 0;
demo_debug_interface();
while (1) {
++i;
demo_handle_hmq_in();
/* Export a set of variables */
rt_variable_export(demo_variables, __DEMO_VAR_MAX);
rt_structure_export(demo_structures, __DEMO_STRUCT_MAX);
rt_action_export(demo_actions, 128); /* FIXME replace 128 with correct number */
/* Once in a while send an alive message */
if (i % 500000 == 0)
demo_alive();
while (1) {
/* Handle all messages incoming from slot DEMO_HMQ_IN
as actions */
rt_mq_action_dispatch(DEMO_HMQ_IN, 0);
}
return 0;
......
demo
\ No newline at end of file
demo
demo-librt
\ No newline at end of file
......@@ -8,7 +8,9 @@ DESTDIR ?= /usr/local
WRNC ?= ../../../
CFLAGS += -Wall -ggdb -I. -I../include -I$(WRNC)/include -I$(WRNC)/lib -I../lib
LDLIBS += -L../lib -ldemo -L$(WRNC)/lib -lwrnc
CFLAGS += $(EXTRACFLAGS)
LDLIBS-WRNC := -L$(WRNC)/lib -lwrnc
LDLIBS += -L../lib -ldemo $(LDLIBS-WRNC)
PROGS := demo
......@@ -18,10 +20,8 @@ install:
install -d $(DESTDIR)/bin
install -D $(PROGS) $(DESTDIR)/bin
%: %.c ../lib/libwrtd.a wrtd-inout-common.o
demo: demo.c
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
wrtd-inout-common.o: wrtd-inout-common.c
$(CC) -c $(CFLAGS) $^ -o $@
# make nothing for modules_install, but avoid errors
modules_install:
......
......@@ -18,13 +18,16 @@
static void help()
{
fprintf(stderr,
"demo -D 0x<hex-number> -L 0x<hex-number> -l 0x<hex-number> -c <char> -s\n");
"demo -D 0x<hex-number> -L 0x<hex-number> -l 0x<hex-number> -c <char> -a <char> -s\n");
fprintf(stderr, "-D device id\n");
fprintf(stderr, "-l value to write into the LED register\n");
fprintf(stderr, "-L value to write into the LEMO register\n");
fprintf(stderr, "-d value to write into the LEMO direction register\n");
fprintf(stderr, "-s it reports the content of LED and LEMO registers\n");
fprintf(stderr, "-c set led color (g: green, r: red, o: orange)\n");
fprintf(stderr, "-a set autodemo status (r: run, s: stop)\n");
fprintf(stderr, "-v show version\n");
fprintf(stderr, "-t send random value to the structure and read them back\n");
fprintf(stderr, "\n");
exit(1);
}
......@@ -35,6 +38,26 @@ static void demo_print_status(struct demo_status *status)
fprintf(stdout, "\tled\t0x%x\n", status->led);
fprintf(stdout, "\tlemo\t0x%x\n", status->lemo);
fprintf(stdout, "\t\tdirection\t0x%x\n", status->lemo_dir);
fprintf(stdout, "\tautodemo\t%s\n", status->autodemo ? "run" : "stop");
}
static void demo_print_version(struct wrnc_rt_version *version)
{
fprintf(stdout, "Version:\n");
fprintf(stdout, "\tFPGA: 0x%x\n", version->fpga_id);
fprintf(stdout, "\tRT: 0x%x\n", version->rt_id);
fprintf(stdout, "\tRT Version: 0x%x\n", version->rt_version);
fprintf(stdout, "\tGit Version: 0x%x\n", version->git_version);
}
static void demo_print_structure(struct demo_structure *test)
{
int i;
fprintf(stdout, "\tfield1: 0x%x\n", test->field1);
fprintf(stdout, "\tfield2: 0x%x\n", test->field2);
for (i = 0; i < DEMO_STRUCT_MAX_ARRAY; i++)
fprintf(stdout, "\tarray[%d]: 0x%x\n", i, test->array[i]);
}
int main(int argc, char *argv[])
......@@ -42,12 +65,14 @@ int main(int argc, char *argv[])
struct demo_node *demo;
struct demo_status status;
uint32_t dev_id = 0;
int led = -1, lemo = -1, lemo_dir = -1;
char c, c_color;
int err = 0, show_status = 0;
int led = -1, lemo = -1, lemo_dir = -1, i;
char c, c_color = 0, autodemo = 0;
int err = 0, show_status = 0, show_version = 0, structure = 0;
enum demo_color color = DEMO_RED;
struct wrnc_rt_version version;
struct demo_structure test, test_rb;
while ((c = getopt (argc, argv, "hD:l:L:d:c:s")) != -1) {
while ((c = getopt (argc, argv, "hD:l:L:d:c:sa:vt")) != -1) {
switch (c) {
case 'h':
case '?':
......@@ -82,6 +107,15 @@ int main(int argc, char *argv[])
case 's':
show_status = 1;
break;
case 'a':
sscanf(optarg, "%c", &autodemo);
break;
case 'v':
show_version = 1;
break;
case 't':
structure = 1;
break;
}
}
......@@ -104,6 +138,11 @@ int main(int argc, char *argv[])
exit(1);
}
/* Set autodemo status */
if (autodemo != 0)
demo_run_autodemo(demo, autodemo == 'r' ? 1 : 0);
if (lemo_dir >= 0) {
/* Set LEMO direction */
err = demo_lemo_dir_set(demo, lemo_dir);
......@@ -135,6 +174,48 @@ int main(int argc, char *argv[])
demo_print_status(&status);
}
if (show_version) {
err = demo_version(demo, &version);
if (err)
fprintf(stderr, "Cannot get version: %s\n",
demo_strerror(errno));
else
demo_print_version(&version);
}
if (structure) {
/* Generate random numbers (cannot use getrandom(2) because
of old system)*/
test.field1 = random();
test.field2 = random();
for (i = 0; i < DEMO_STRUCT_MAX_ARRAY; i++)
test.array[i] = random();
fprintf(stdout, "Generated structure:\n");
demo_print_structure(&test);
err = demo_test_struct_set(demo, &test);
if (err) {
fprintf(stderr, "Cannot set structure: %s\n",
demo_strerror(errno));
} else {
err = demo_test_struct_get(demo, &test_rb);
if (err) {
fprintf(stderr, "Cannot get structure: %s\n",
demo_strerror(errno));
} else {
if (memcmp(&test, &test_rb, sizeof(struct demo_structure))) {
fprintf(stderr, "Got wrong structure: %s\n",
demo_strerror(errno));
demo_print_structure(&test_rb);
} else {
fprintf(stderr,
"Structure correctly read back\n");
}
}
}
}
demo_close(demo);
exit(0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment