Commit 60a7226e authored by Pavel Pisa's avatar Pavel Pisa

driver: extend user-space test program to find PCI base and allow periodic messages Tx.

Signed-off-by: Pavel Pisa's avatarPavel Pisa <pisa@cmp.felk.cvut.cz>
parent ecae59bf
......@@ -34,28 +34,201 @@
#include "userspace_utils.h"
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
/*
/sys/devices/pci0000:00/0000:00:1c.4/0000:05:00.0
*/
typedef struct find_dir_chain {
char *dir_name;
DIR *dir;
struct find_dir_chain *parent;
} find_dir_chain_t;
int pci_find_dev(char **dev_dir, const char *dir_name, unsigned vid, unsigned pid, int inst)
{
unsigned vid_act, pid_act;
find_dir_chain_t *dir_stack = NULL;
find_dir_chain_t *dir_act = NULL;
char *entry_name = NULL;
FILE *f;
struct dirent *entry;
int level = 0;
int sz1, sz2 = 0;
char level0_prefix[] = "pci";
int clean_rest = 0;
*dev_dir = NULL;
while(1) {
if (dir_act != NULL) {
while (((entry = readdir(dir_act->dir)) == NULL) || (clean_rest)) {
closedir(dir_act->dir);
free(dir_act->dir_name);
dir_stack = dir_act->parent;
free(dir_act);
dir_act = dir_stack;
level--;
if (dir_stack == NULL)
break;
}
if (dir_act == NULL)
break;
if (entry->d_type != DT_DIR)
continue;
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
dir_name = dir_stack->dir_name;
entry_name = entry->d_name;
if ((level <= 1) && strncmp(entry_name, level0_prefix, strlen(level0_prefix)))
continue;
}
dir_act = (find_dir_chain_t *)malloc(sizeof(find_dir_chain_t));
if (dir_act == NULL)
err(1, "malloc failed");
dir_act->parent = dir_stack;
sz1 = strlen(dir_name);
if (entry_name != NULL)
sz2 = strlen(entry_name);
dir_act->dir_name = (char *)malloc(sz1 + sz2 + 2);
if (dir_act->dir_name == NULL)
err(1, "malloc failed");
memcpy(dir_act->dir_name, dir_name, sz1);
if (entry_name != NULL) {
dir_act->dir_name[sz1] = '/';
memcpy(dir_act->dir_name + sz1 + 1, entry_name, sz2);
dir_act->dir_name[sz1 + 1 + sz2] = 0;
} else {
dir_act->dir_name[sz1] = 0;
}
/*printf("level %d, name = %s\n", level, dir_act->dir_name);*/
dir_stack = dir_act;
dir_act->dir = opendir(dir_act->dir_name);
if (dir_act->dir == NULL)
err(1, "opendir failed");
level++;
if (level <= 2)
continue;
{
int sz1 = strlen(dir_act->dir_name);
char vid_fname[sz1 + strlen("/vendor") + 1];
char pid_fname[sz1 + strlen("/device") + 1];
memcpy(vid_fname, dir_act->dir_name, sz1);
memcpy(pid_fname, dir_act->dir_name, sz1);
strcpy(vid_fname + sz1, "/vendor");
strcpy(pid_fname + sz1, "/device");
f = fopen(vid_fname, "r");
if (f == NULL)
continue;
vid_act = -1;
fscanf(f, "%i", &vid_act);
fclose(f);
f = fopen(pid_fname, "r");
if (f == NULL)
continue;
pid_act = -1;
fscanf(f, "%i", &pid_act);
fclose(f);
}
if (vid != vid_act)
continue;
if (pid != pid_act)
continue;
if (inst-- > 0)
continue;
*dev_dir = strdup(dir_act->dir_name);
clean_rest = 1;
}
return clean_rest;
}
uintptr_t pci_find_bar(unsigned vid, unsigned pid, int inst, int barnr)
{
FILE *f;
char *dev_dir;
int sz1;
unsigned long long bar1_base;
if (!pci_find_dev(&dev_dir, "/sys/devices", vid, pid, inst)) {
return 0;
}
printf("found %s\n", dev_dir);
sz1 = strlen(dev_dir);
{
char buff[200];
char resource_fname[sz1 + strlen("/resource") + 1];
memcpy(resource_fname, dev_dir, sz1);
strcpy(resource_fname + sz1, "/resource");
f = fopen(resource_fname, "r");
if (f == NULL)
return 0;
while (barnr-- > 0)
fgets(buff, sizeof(buff) - 1, f);
fscanf(f, "%lli", &bar1_base);
fclose(f);
}
return bar1_base;
}
int main(int argc, char *argv[])
{
uint32_t addr_base;
uintptr_t addr_base = 0;
unsigned ifc = 0;
bool do_transmit = false;
int loop_cycle = 0;
int gap = 1000;
int bitrate = 1000000;
bool do_periodic_transmit = false;
bool loopback_mode = false;
//bool do_showhelp = false;
static uintptr_t addrs[] = {0x43C30000, 0x43C70000};
int c;
char *e;
const char *progname = argv[0];
while ((c = getopt(argc, argv, "i:th")) != -1) {
while ((c = getopt(argc, argv, "i:a:g:b:ltThp")) != -1) {
switch (c) {
case 'i':
ifc = strtoul(optarg, &e, 0);
if (*e != '\0')
err(1, "-i expects a number");
break;
case 'a':
addr_base = strtoul(optarg, &e, 0);
if (*e != '\0')
err(1, "-a expects a number");
break;
case 'g':
gap = strtoul(optarg, &e, 0);
if (*e != '\0')
err(1, "-g expects a number");
break;
case 'b':
bitrate = strtoul(optarg, &e, 0);
if (*e != '\0')
err(1, "-b expects a number");
break;
case 'l': loopback_mode = true; break;
case 't': do_transmit = true; break;
case 'T': do_periodic_transmit = true; break;
case 'p':
addrs[0] = pci_find_bar(0x1172, 0xcafd, 0, 1);
if (!addrs[0])
err(1, "-p PCI device not found");
addrs[1] = addrs[0] + 0x4000;
break;
case 'h':
printf("Usage: %s [-i ifc] [-t]\n\n"
printf("Usage: %s [-i ifc] [-a address] [-l] [-t] [-T]\n\n"
" -t: Transmit\n",
progname
);
......@@ -63,12 +236,12 @@ int main(int argc, char *argv[])
}
}
static const uint32_t addrs[] = {0x43C30000, 0x43C70000};
if (ifc >= 2) {
std::cerr << "Err: ifc number must be 0 or 1.\n";
exit(1);
}
addr_base = addrs[ifc];
if (addr_base == 0)
addr_base = addrs[ifc];
struct ctucanfd_priv *priv = ctucanfd_init(addr_base);
int res;
......@@ -105,7 +278,7 @@ int main(int argc, char *argv[])
nd.can.clock.freq = 100000000;
struct can_bittiming nom_timing = {
.bitrate = 1000000,
.bitrate = bitrate,
};
res = can_get_bittiming(&nd, &nom_timing,
&ctu_can_fd_bit_timing_max,
......@@ -133,9 +306,18 @@ int main(int argc, char *argv[])
//ctu_can_fd_abort_tx(priv);
//ctu_can_fd_txt_set_abort(priv, CTU_CAN_FD_TXT_BUFFER_1);
//ctu_can_fd_txt_set_empty(priv, CTU_CAN_FD_TXT_BUFFER_1);
if (loopback_mode) {
struct can_ctrlmode mode = {0, 0};
mode.mask = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_PRESUME_ACK;
mode.flags = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_PRESUME_ACK;
ctu_can_fd_set_mode(priv, &mode);
}
ctu_can_fd_enable(priv, true);
usleep(10000);
printf("MODE=0x%02x\n", priv->read_reg(priv, CTU_CAN_FD_MODE));
if (do_transmit) {
struct canfd_frame txf;
......@@ -176,7 +358,7 @@ int main(int argc, char *argv[])
printf(" 0x%08x\n", data);
}
*/
if (nrxf || rxsz) {
while (nrxf || rxsz) {
struct canfd_frame cf;
u64 ts;
ctu_can_fd_read_rx_frame(priv, &cf, &ts);
......@@ -184,9 +366,29 @@ int main(int argc, char *argv[])
for (int i=0; i<cf.len; ++i)
printf(" %02x", cf.data[i]);
printf("\n");
rxsz = 0;
nrxf = ctu_can_fd_get_rx_frame_count(priv);
}
if (do_periodic_transmit && (loop_cycle & 1)) {
struct canfd_frame txf;
txf.can_id = 0x1FF;
txf.flags = 0;
//u8 d[] = {0xde, 0xad, 0xbe, 0xef};
//u8 d[] = {0xDE, 0xAD, 0xBE, 0xEF};
u8 d[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xEE};
memcpy(txf.data, d, sizeof(d));
txf.len = sizeof(d);
res = ctu_can_fd_insert_frame(priv, &txf, 0, CTU_CAN_FD_TXT_BUFFER_1, false);
if (!res)
printf("TX failed\n");
ctu_can_fd_txt_set_rdy(priv, CTU_CAN_FD_TXT_BUFFER_1);
}
usleep(1000000);
usleep(1000 * gap);
loop_cycle++;
}
return 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