Commit 09379a42 authored by Dimitris Lampridis's avatar Dimitris Lampridis
Browse files

[WR-dev] Added tools to program the LM32 and access the VUART of the WR PTP core

parent e5167d3e
ENV ?= lab
CPU ?= L866
include /acc/src/dsc/co/Make.auto
VME_INC ?= /acc/src/dsc/drivers/coht/vmebridge/include/
CFLAGS += -g -Wall
CFLAGS += -I $(VME_INC)
LDFLAGS += -L /acc/local/$(CPU)/lib
LDLIBS += -lvmebus
all: vfchd-vuart.$(CPU) vfchd-wrc_loader.$(CPU)
%.$(CPU): %.$(CPU).o
install-$(ENV):
dsc_install vme.$(CPU) /acc/dsc/$(ENV)/$(CPU)/bin
clean:
rm -f *.o *.$(CPU) vme.$(CPU)
# These targets are called from ../Makefile, just do nothing
modules install modules_install:
.PHONY: all modules clean install modules_install
/* A simple console for accessing the VFC-HD virtual UART (i.e. for communicating with the WR Core shell
from a Linux terminal. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <libvmebus.h>
#include "wb_uart.h"
volatile void *vme_base_ptr;
uint32_t vuart_base = 0x60500;
/* int addr_fd; */
/* int data_fd; */
/* int lun = -1; */
uint32_t vfchd_read(uint32_t offset)
{
volatile uint32_t *addr = vme_base_ptr + offset;
uint32_t datum = ntohl(addr[0]);
return datum;
}
void vfchd_write(uint32_t datum, uint32_t offset)
{
volatile uint32_t *addr = vme_base_ptr + offset;
addr[0] = htonl(datum);
}
int vfchd_vuart_rx(char *d)
{
int rdr = vfchd_read(vuart_base + UART_REG_HOST_RDR);
if(rdr & UART_HOST_RDR_RDY)
{
*d = UART_HOST_RDR_DATA_R(rdr);
return 1;
} else
return 0;
}
int vfchd_vuart_tx(char d)
{
/* fprintf(stderr, "would send 0x%.2x\n", d); */
while( vfchd_read(vuart_base + UART_REG_SR) & UART_SR_RX_RDY );
vfchd_write(UART_HOST_TDR_DATA_W(d), vuart_base + UART_REG_HOST_TDR);
return 0;
}
static int transfer_byte(int from, int is_control) {
char c;
int ret;
do {
ret = read(from, &c, 1);
} while (ret < 0 && errno == EINTR);
if(ret == 1) {
if(is_control) {
if(c == '\x01') { // C-a
return -1;
}
}
vfchd_vuart_tx(c);
} else {
fprintf(stderr, "\nnothing to read. probably port disconnected.\n");
return -2;
}
return 0;
}
void term_main(int keep_term)
{
struct termios oldkey, newkey; //place for old and new port settings for keyboard teletype
int need_exit = 0;
fprintf(stderr, "[press C-a to exit]\n");
if(!keep_term) {
tcgetattr(STDIN_FILENO,&oldkey);
newkey.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
newkey.c_iflag = IGNPAR;
newkey.c_oflag = 0;
newkey.c_lflag = 0;
newkey.c_cc[VMIN]=1;
newkey.c_cc[VTIME]=0;
tcflush(STDIN_FILENO, TCIFLUSH);
tcsetattr(STDIN_FILENO,TCSANOW,&newkey);
}
while(!need_exit) {
fd_set fds;
int ret;
char rx;
struct timeval tv = {0, 10000};
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
ret = select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
if(ret == -1) {
perror("select");
} else if (ret > 0) {
if(FD_ISSET(STDIN_FILENO, &fds)) {
need_exit = transfer_byte(STDIN_FILENO, 1);
}
}
while((vfchd_vuart_rx(&rx)) == 1)
fprintf(stderr,"%c", rx);
}
if(!keep_term)
tcsetattr(STDIN_FILENO,TCSANOW,&oldkey);
}
int main(int argc, char **argv)
{
struct vme_mapping map;
struct vme_mapping *mapp = &map;
memset(mapp, 0, sizeof(*mapp));
mapp->am = VME_A32_USER_DATA_SCT;
mapp->data_width = VME_D32;
mapp->sizel = 0x80000;
mapp->vme_addrl = 0x4000000;
if ((vme_base_ptr = vme_map(mapp, 1)) == NULL) {
printf("could not map at 0x%08x\n", mapp->vme_addrl);
exit(1);
}
fprintf(stderr, "vme 0x%08x kernel %p user %p\n",
mapp->vme_addrl, mapp->kernel_va, mapp->user_va);
term_main(0);
vme_unmap(mapp, 1);
return 0;
}
/* A simple console for accessing the VFC-HD virtual UART (i.e. for communicating with the WR Core shell
from a Linux terminal. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <libvmebus.h>
volatile void *vme_base_ptr;
uint32_t wrc_mem_base = 0x40000;
uint32_t wrc_sys_base = 0x60400;
void vfchd_wrc_loader (const char *fname) {
volatile uint32_t *wrc_mem_ptr = vme_base_ptr + wrc_mem_base;
volatile uint32_t *wrc_sys_ptr = vme_base_ptr + wrc_sys_base;
FILE *f = fopen(fname, "rb");
if ( f == NULL )
{
fprintf( stderr, "Could not open file\n" );
return;
}
fseek(f, 0, SEEK_END);
long fsize32 = ftell(f) >> 2;
fseek(f, 0, SEEK_SET);
uint32_t datum, readback;
int i = 0;
wrc_sys_ptr[0] = htonl(0x1deadbee);
for (i=0; i < fsize32; i++) {
fread((void *)&datum, 4, 1, f);
wrc_mem_ptr[i] = datum;
readback = wrc_mem_ptr[i];
if ( readback != datum) {
fprintf(stderr, "\nerror writing value 0x%.8x to address 0x%.8x. Read-back value was 0x%.8x\n",
htonl(datum), i, readback);
break;
}
}
fclose(f);
wrc_sys_ptr[0] = htonl(0x0deadbee);
}
int main(int argc, char **argv)
{
struct vme_mapping map;
struct vme_mapping *mapp = &map;
memset(mapp, 0, sizeof(*mapp));
mapp->am = VME_A32_USER_DATA_SCT;
mapp->data_width = VME_D32;
mapp->sizel = 0x80000;
mapp->vme_addrl = 0x4000000;
if ((vme_base_ptr = vme_map(mapp, 1)) == NULL) {
printf("could not map at 0x%08x\n", mapp->vme_addrl);
exit(1);
}
fprintf(stderr, "vme 0x%08x kernel %p user %p\n",
mapp->vme_addrl, mapp->kernel_va, mapp->user_va);
vfchd_wrc_loader(argv[1]);
vme_unmap(mapp, 1);
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