OpenCores
URL https://opencores.org/ocsvn/s6soc/s6soc/trunk

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [sw/] [host/] [deppbus.cpp] - Rev 31

Go to most recent revision | Compare with Previous | Blame | View Log

////////////////////////////////////////////////////////////////////////////////
//
// Filename: 	deppbus.cpp
//
// Project:	CMod S6 System on a Chip, ZipCPU demonstration project
//
// Purpose:	This is a *very* simple Depp to Wishbone driver conversion.
//		Look in devbus.cpp for a description of how to use the driver.
//
//	The driver is simple: there are 9 registers of interest to run this
//	driver.  The first four registers, 0-3, are address registers, MSB
//	first.  Place your 32-bit address into these registers.  The next four
//	registers, 4-7, are data registers.  If writing data, place the data
//	to write into these registers.  The last register, 16, is a strobe
//	register.  Write a 1 to read, and a 3 to write, to this register.  A
// 	bus transaction will then take place.  Once completed, registers 4-7
//	will contain the resulting data.
//
//	That's the internal workings of this driver.  The above description is
//	accomplished in the readio() and writeio() routines.
//
//	This is *not* a fully featured DEVBUS class--it does not support
//	pipelined reads or writes.  It does not support compression.  It does,
//	however, support reading and writing a simple 32-bit wishbone bus.
//	That is good enough, of itself, for now.
//
// Creator:	Dan Gisselquist, Ph.D.
//		Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License:	GPL, v3, as defined and found on www.gnu.org,
//		http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
#include <stdlib.h>
#include <stdio.h>
#include "dpcdecl.h"
#include "dmgr.h"
#include "depp.h"
#include "deppbus.h"
 
DEPPBUS::DEPPBUS(char *szSel) {
	if (!DmgrOpen(&m_dev, szSel)) {
		fprintf(stderr, "Open failed!\n");
		exit(EXIT_FAILURE);
	}
 
	if (!DeppEnable(m_dev)) {
		fprintf(stderr, "Could not enable DEPP interface\n");
		exit(EXIT_FAILURE);
	}
 
	m_int = false, m_err = false;
}
 
DEPPBUS::~DEPPBUS(void) {
	if (m_dev)
		DmgrClose(m_dev);
	m_dev = 0;
}
 
void DEPPBUS::kill(void) { close(); }
void DEPPBUS::close(void) { DmgrClose(m_dev); m_dev = 0; }
 
void	DEPPBUS::depperr(void) {
	ERC	erc = DmgrGetLastError();
	if (erc != ercNoErc) {
		char	scode[cchErcMax], msg[cchErcMsgMax];
		DmgrSzFromErc(erc,scode,msg);
		fprintf(stderr, "ErrCode   : %s\n", scode);
		fprintf(stderr, "ErrMessage: %s\n", msg);
		close();
		exit(EXIT_FAILURE);
	}
}
 
void DEPPBUS::writeio(const BUSW a, const BUSW v) {
	bool	good = true;
 
	// Set the address for our data
	good = good && DeppPutReg(m_dev, 0, (a>>24)&0x0ff, false);
	good = good && DeppPutReg(m_dev, 1, (a>>16)&0x0ff, false);
	good = good && DeppPutReg(m_dev, 2, (a>> 8)&0x0ff, false);
	good = good && DeppPutReg(m_dev, 3,  a     &0x0ff, false);
	if (!good) {
		fprintf(stderr, "BUS CYCLE FAILED\n");
		depperr(); close();
		exit(EXIT_FAILURE);
	}
 
	// Set the data to be transmitted
	good = good && DeppPutReg(m_dev, 4, (v>>24)&0x0ff, false);
	good = good && DeppPutReg(m_dev, 5, (v>>16)&0x0ff, false);
	good = good && DeppPutReg(m_dev, 6, (v>> 8)&0x0ff, false);
	good = good && DeppPutReg(m_dev, 7,  v     &0x0ff, false);
	if (!good) {
		fprintf(stderr, "BUS CYCLE FAILED\n");
		depperr(); close();
		exit(EXIT_FAILURE);
	}
 
	// Perform the operation
	good = good && DeppPutReg(m_dev,16,  0x3, false);
	if (!good) {
		fprintf(stderr, "BUS CYCLE FAILED\n");
		depperr(); close();
		exit(EXIT_FAILURE);
	}
 
	// Now, let's check for any bus errors and/or interrupts
	BYTE	retn;
	good = good && DeppGetReg(m_dev,16, &retn, false);
	m_err = m_err | (retn&1);
	m_int = m_int | (retn&2);
 
	if (!good) {
		fprintf(stderr, "BUS CYCLE FAILED\n");
		depperr(); close();
		exit(EXIT_FAILURE);
	}
 
	if (m_err)
		throw BUSERR(a);
}
 
DEVBUS::BUSW DEPPBUS::readio(const DEVBUS::BUSW a) {
	BUSW	v = 0;
	BYTE	retn;
	bool	good = true;
 
	// Set the address for our data
	good = good && DeppPutReg(m_dev, 0, (a>>24)&0x0ff, false);
	good = good && DeppPutReg(m_dev, 1, (a>>16)&0x0ff, false);
	good = good && DeppPutReg(m_dev, 2, (a>> 8)&0x0ff, false);
	good = good && DeppPutReg(m_dev, 3,  a     &0x0ff, false);
 
	if (!good) {
		fprintf(stderr, "BUS CYCLE FAILED\n");
		depperr(); close();
		exit(EXIT_FAILURE);
	}
 
	// Run the bus cycle
	good = good && DeppPutReg(m_dev,16,  0x1, false);
	if (!good) {
		fprintf(stderr, "BUS CYCLE FAILED\n");
		depperr(); close();
		exit(EXIT_FAILURE);
	}
 
	// Check for any bus errors and/or interrupts
	good = good && DeppGetReg(m_dev,16, &retn, false);
	if (!good) {
		fprintf(stderr, "BUS CYCLE FAILED\n");
		depperr(); close();
		exit(EXIT_FAILURE);
	}
 
	m_err = m_err | (retn&1);
	m_int = m_int | (retn&2);
 
	if (m_err)
		throw BUSERR(a);
 
	// Otherwise let's get our result
	good = good && DeppGetReg(m_dev, 4, &retn, false); v = (retn & 0x0ff);
	good = good && DeppGetReg(m_dev, 5, &retn, false); v = (v<<8)|(retn & 0x0ff);
	good = good && DeppGetReg(m_dev, 6, &retn, false); v = (v<<8)|(retn & 0x0ff);
	good = good && DeppGetReg(m_dev, 7, &retn, false); v = (v<<8)|(retn & 0x0ff);
	if (!good) {
		fprintf(stderr, "BUS CYCLE FAILED\n");
		depperr(); close();
		exit(EXIT_FAILURE);
	}
 
	return v;
}
 
void	DEPPBUS::readi(const BUSW a, const int len, BUSW *buf) {
	for(int i=0; i<len; i++)
		buf[i] = readio(a+i);
} void	DEPPBUS::readz(const BUSW a, const int len, BUSW *buf) {
	for(int i=0; i<len; i++)
		buf[i] = readio(a);
}
 
void	DEPPBUS::writei(const BUSW a, const int len, const BUSW *buf) {
	for(int i=0; i<len; i++)
		writeio(a+i, buf[i]);
} void	DEPPBUS::writez(const BUSW a, const int len, const BUSW *buf) {
	for(int i=0; i<len; i++)
		writeio(a, buf[i]);
}
 
bool	DEPPBUS::poll(void) {
	if (m_int)
		return true;
 
	// Check for any bus errors and/or interrupts
	BYTE	retn;
	DeppGetReg(m_dev,16, &retn, false);
	m_err = m_err | (retn&1);
	m_int = m_int | (retn&2);
 
	if (m_int)
		return true;
	return false;
} void	DEPPBUS::usleep(unsigned msec) {
	if (!poll())
		usleep(msec);
} void	DEPPBUS::wait(void) {
	while(!poll())
		usleep(5);
} bool	DEPPBUS::bus_err(void) const {
	return m_err;
} void	DEPPBUS::reset_err(void) {
	m_err = false;
} void	DEPPBUS::clear(void) {
	m_int = false;
	m_err = false;
}
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.