Commit 8e0370f1 authored by Wesley W. Terpstra's avatar Wesley W. Terpstra

w1: add etherbone tool to format sdbfs

parent 089f44f2
......@@ -4,3 +4,4 @@ genrammif
wrpc-uart-sw
wrpc-w1-read
wrpc-w1-write
eb-w1-write
EB ?= no
CFLAGS = -Wall -ggdb -DEXTERNAL_W1 -I../include
LDFLAGS = -lutil
ALL = genraminit genramvhd genrammif wrpc-uart-sw
ALL += wrpc-w1-read wrpc-w1-write
ifneq ($(EB),no)
ALL += eb-w1-write
endif
AS = as
LD = ld
CC = gcc
......@@ -24,5 +30,8 @@ wrpc-w1-read: wrpc-w1-read.c ../dev/w1.c ../dev/w1-eeprom.c ../dev/w1-hw.c
wrpc-w1-write: wrpc-w1-write.c ../dev/w1.c ../dev/w1-eeprom.c ../dev/w1-hw.c
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
eb-w1-write: eb-w1-write.c ../dev/w1.c ../dev/w1-eeprom.c eb-w1.c
$(CC) $(CFLAGS) -I $(EB) $^ $(LDFLAGS) -o $@ -L $(EB) -letherbone
clean:
rm -f $(ALL) *.o *~
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2013 CERN (www.cern.ch)
* Author: Wesley W. Terpstra <w.terpstra@gsi.de>
* Author: Alessandro Rubini <rubini@gnudd.com>
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <etherbone.h>
#include <w1.h>
#define W1_VENDOR 0xce42 /* CERN */
#define W1_DEVICE 0x779c5443 /* WR-Periph-1Wire */
char *prgname;
int verbose;
eb_address_t BASE_ONEWIRE;
eb_device_t device;
extern struct w1_bus wrpc_w1_bus;
static int write_w1(int w1base, int w1len)
{
struct w1_dev *d;
uint8_t buf[w1len];
int i;
w1_scan_bus(&wrpc_w1_bus);
if (verbose) { /* code borrowed from dev/w1.c -- "w1" shell command */
for (i = 0; i < W1_MAX_DEVICES; i++) {
d = wrpc_w1_bus.devs + i;
if (d->rom)
fprintf(stderr, "device %i: %08x%08x\n", i,
(int)(d->rom >> 32), (int)d->rom);
}
}
if (verbose) {
fprintf(stderr, "Writing device offset %i (0x%x), len %i\n",
w1base, w1base, w1len);
}
if (isatty(fileno(stdin)))
fprintf(stderr, "Reading from stdin, please type the data\n");
i = fread(buf, 1, w1len, stdin);
if (i != w1len) {
fprintf(stderr, "%s: read error (%i, expeted %i)\n", prgname,
i, w1len);
return 1;
}
i = w1_write_eeprom_bus(&wrpc_w1_bus, w1base, buf, w1len);
if (i != w1len) {
fprintf(stderr, "Tried to write %i bytes, retval %i\n",
w1len, i);
return 1;
}
return 0;
}
/*
* What follows is mostly generic, should be librarized in a way
*/
static int help(void)
{
fprintf(stderr, "%s: Use: \"%s [-v] <device> <addr> <len>\n",
prgname, prgname);
return 1;
}
static void die(const char *reason, eb_status_t status)
{
fprintf(stderr, "%s: %s: %s\n", prgname, reason, eb_status(status));
exit(1);
}
int main(int argc, char **argv)
{
int c;
eb_status_t status;
eb_socket_t socket;
struct sdb_device sdb;
prgname = argv[0];
while ((c = getopt(argc, argv, "v")) != -1) {
switch(c) {
case 'v':
verbose++;
break;
default:
exit(help());
}
}
if (optind != argc - 3)
exit(help());
if ((status = eb_socket_open(EB_ABI_CODE, 0, EB_DATAX|EB_ADDRX, &socket)) != EB_OK)
die("eb_socket_open", status);
if ((status = eb_device_open(socket, argv[optind], EB_DATAX|EB_ADDRX, 3, &device)) != EB_OK)
die(argv[optind], status);
/* Find the W1 device */
c = 1;
if ((status = eb_sdb_find_by_identity(device, W1_VENDOR, W1_DEVICE, &sdb, &c)) != EB_OK)
die("eb_sdb_find_by_identity", status);
if (c != 1) {
fprintf(stderr, "Found %d 1wire controllers on that device\n", c);
exit(1);
}
BASE_ONEWIRE = sdb.sdb_component.addr_first;
return write_w1(atoi(argv[optind + 1]), atoi(argv[optind + 2]));
}
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2013 CERN (www.cern.ch)
* Author: Wesley W. Terpstra <w.terpstra@gsi.de>
* Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include <etherbone.h>
#include <w1.h>
#include <hw/sockit_owm_regs.h>
extern eb_address_t BASE_ONEWIRE;
extern eb_device_t device;
static inline uint32_t __wait_cycle(eb_device_t device)
{
eb_data_t data;
do {
eb_device_read(device, BASE_ONEWIRE, EB_DATA32|EB_BIG_ENDIAN, &data, 0, 0);
} while (data & SOCKIT_OWM_CTL_CYC_MSK);
return data;
}
static int w1_reset(struct w1_bus *bus)
{
int portnum = bus->detail;
uint32_t reg;
eb_data_t data = (portnum << SOCKIT_OWM_CTL_SEL_OFST)
| (SOCKIT_OWM_CTL_CYC_MSK)
| (SOCKIT_OWM_CTL_RST_MSK);
eb_device_write(device, BASE_ONEWIRE, EB_DATA32|EB_BIG_ENDIAN, data, 0, 0);
reg = __wait_cycle(device);
/* return presence-detect pulse (1 if true) */
return (reg & SOCKIT_OWM_CTL_DAT_MSK) ? 0 : 1;
}
static int w1_read_bit(struct w1_bus *bus)
{
int portnum = bus->detail;
uint32_t reg;
eb_data_t data = (portnum << SOCKIT_OWM_CTL_SEL_OFST)
| (SOCKIT_OWM_CTL_CYC_MSK)
| (SOCKIT_OWM_CTL_DAT_MSK);
eb_device_write(device, BASE_ONEWIRE, EB_DATA32|EB_BIG_ENDIAN, data, 0, 0);
reg = __wait_cycle(device);
return (reg & SOCKIT_OWM_CTL_DAT_MSK) ? 1 : 0;
}
static void w1_write_bit(struct w1_bus *bus, int bit)
{
int portnum = bus->detail;
eb_data_t data = (portnum << SOCKIT_OWM_CTL_SEL_OFST)
| (SOCKIT_OWM_CTL_CYC_MSK)
| (bit ? SOCKIT_OWM_CTL_DAT_MSK : 0);
eb_device_write(device, BASE_ONEWIRE, EB_DATA32|EB_BIG_ENDIAN, data, 0, 0);
__wait_cycle(device);
}
struct w1_ops wrpc_w1_ops = {
.reset = w1_reset,
.read_bit = w1_read_bit,
.write_bit = w1_write_bit,
};
struct w1_bus wrpc_w1_bus;
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