Commit 0facccb6 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

add HWIU support to libswitchhw

parent f7088f3d
/*
Register definitions for slave core: WR Switch Hardware Info Unit
* File : hwiu-regs.h
* Author : auto-generated by wbgen2 from wrsw_hwiu.wb
* Created : Wed Jun 5 10:49:31 2013
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrsw_hwiu.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WRSW_HWIU_WB
#define __WBGEN2_REGDEFS_WRSW_HWIU_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Control Register */
/* definitions for field: Address of the register in reg: Control Register */
#define HWIU_CR_ADR_MASK WBGEN2_GEN_MASK(0, 16)
#define HWIU_CR_ADR_SHIFT 0
#define HWIU_CR_ADR_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define HWIU_CR_ADR_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: Read error in reg: Control Register */
#define HWIU_CR_RD_ERR WBGEN2_GEN_MASK(30, 1)
/* definitions for field: Read register value in reg: Control Register */
#define HWIU_CR_RD_EN WBGEN2_GEN_MASK(31, 1)
/* definitions for register: Value of the requested register */
PACKED struct HWIU_WB {
/* [0x0]: REG Control Register */
uint32_t CR;
/* [0x4]: REG Value of the requested register */
uint32_t REG_VAL;
};
#endif
-- -*- Mode: LUA; tab-width: 2 -*-
-- White-Rabbit Hardware Debugging Unit
-- author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
--
-- Use wbgen2 to generate code, documentation and more.
-- wbgen2 is available at:
-- http://www.ohwr.org/projects/wishbone-gen
--
peripheral {
name = "WR Switch Hardware Info Unit";
description = "The module provides basic info about the gateware version. It can be also used for reading registers inside WR Switch Gateware after connecting them to optional dbg input.";
hdl_entity = "hwiu_wishbone_slave";
prefix = "hwiu";
reg {
name = "Control Register";
prefix = "CR";
field {
name = "Address of the register";
description = "Which register (among those connected to HWDU) will be read";
prefix = "ADR";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Read error";
description = "read 1: read error, provided address is out of range \
read 0: read done successfully";
prefix = "RD_ERR";
type = BIT;
align = 30;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Read register value";
description = "write 1: read the content \
write 0: no effect \
read 1: reading in progress \
read 0: reading done, register value available";
prefix = "RD_EN";
type = BIT;
align = 31;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
name = "Value of the requested register";
description = "The value of the register under ADR from the Control Register";
prefix = "REG_VAL";
field {
name = "register value";
size = 32;
type = SLV;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
};
......@@ -15,6 +15,9 @@
/* Simple PWM module */
#define FPGA_BASE_SPWM 0x57000
/* HW Info Unit */
#define FPGA_BASE_HWIU 0x57800
#define FPGA_BASE_ADDR _fpga_base_virt
......
#ifndef __HWIU_H__
#define __HWIU_H__
#define HWIU_INFO_START 0
#define HWIU_INFO_WORDS_START 1
#define HWIU_RD_TIMEOUT 30
#define HWIU_INFO_WORDS 4
#define HWIU_STRUCT_VERSION 1
struct gw_info {
uint8_t ver_minor, ver_major;
uint8_t nwords;
uint8_t struct_ver;
uint8_t build_no, build_year, build_month, build_day;
uint32_t switch_hdl_hash;
uint32_t general_cores_hash;
uint32_t wr_cores_hash;
} __attribute__((packed));
int shw_hwiu_gwver(struct gw_info *info);
#endif
......@@ -2,7 +2,7 @@ CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
CFLAGS = -I. -O2 -I../include -DDEBUG -g
OBJS = trace.o init.o fpga_io.o util.o pps_gen.o i2c.o shw_io.o i2c_bitbang.o i2c_fpga_reg.o pio.o libshw_i2c.o i2c_sfp.o fan.o i2c_io.o
OBJS = trace.o init.o fpga_io.o util.o pps_gen.o i2c.o shw_io.o i2c_bitbang.o i2c_fpga_reg.o pio.o libshw_i2c.o i2c_sfp.o fan.o i2c_io.o hwiu.o
SCAN_OBJS = i2cscan.o
LIB = libswitchhw.a
......
#include <stdio.h>
#include <inttypes.h>
#include <stddef.h>
#include <fpga_io.h>
#include <regs/hwiu-regs.h>
#include <hwiu.h>
#define hwiu_write(reg, val) \
_fpga_writel(FPGA_BASE_HWIU + offsetof(struct HWIU_WB, reg), val)
#define hwiu_read(reg) \
_fpga_readl(FPGA_BASE_HWIU + offsetof(struct HWIU_WB, reg))
int hwiu_read_word(uint32_t adr, uint32_t *data)
{
uint32_t temp;
int timeout = 0;
temp = HWIU_CR_RD_EN | HWIU_CR_ADR_W(adr);
hwiu_write(CR, temp);
do {
temp = hwiu_read(CR);
++timeout;
} while( temp & HWIU_CR_RD_EN && timeout < HWIU_RD_TIMEOUT );
if( timeout == HWIU_RD_TIMEOUT || temp & HWIU_CR_RD_ERR )
return -1;
*data = hwiu_read(REG_VAL);
return 0;
}
int shw_hwiu_gwver(struct gw_info *info)
{
uint32_t data[HWIU_INFO_WORDS+1];
struct gw_info *s_data;
int i;
//read first word of info struct
if( hwiu_read_word(HWIU_INFO_START, data) < 0 )
return -1;
s_data = (struct gw_info *)data;
*info = *s_data;
if( info->nwords != HWIU_INFO_WORDS ) {
printf("nwords: sw=%u, hw=%u, ver=%u, data=%x\n", info->nwords, HWIU_INFO_WORDS, info->struct_ver, data[0]);
return -1;
}
//now read info words
for(i=0; i<info->nwords; ++i) {
if( hwiu_read_word(HWIU_INFO_WORDS_START+i, data+i+1) < 0 )
return -1;
}
*info = *( (struct gw_info*) data);
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