Skip to content
Snippets Groups Projects
Commit 07131f42 authored by Matthieu Cattin's avatar Matthieu Cattin
Browse files

Add exception handling, remove possible infinite loops, add license and comments in spi module.

parent 81bfcae9
No related merge requests found
#!/usr/bin/python
# Copyright CERN, 2011
# Author: Matthieu Cattin (CERN)
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 27/4/2012
# Import standard modules
import sys
import rr
import time
# Import specific modules
import rr
# Class to access the wishbone to SPI master module from OpenCores
# http://opencores.org/project,spi
class SPIDeviceOperationError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return ("SPI Device produced the error: %s" %(msg))
class COpenCoresSPI:
# OpenCores SPI registers description
R_RX = [0x00, 0x04, 0x08, 0x0C]
R_TX = [0x00, 0x04, 0x08, 0x0C]
R_CTRL = 0x10
......@@ -23,10 +42,13 @@ class COpenCoresSPI:
DIV_MASK = (0xFFFF)
SS_SEL = [0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40]
# Static variable
conf = 0x0
# Constant declaration
SS_SEL = [0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40]
WAIT_TIME_OUT = 2
def wr_reg(self, addr, val):
self.bus.iwrite(0, self.base_addr + addr, 4, val)
......@@ -37,12 +59,16 @@ class COpenCoresSPI:
self.bus = bus;
self.base_addr = base_addr;
self.wr_reg(self.R_DIV, (divider & self.DIV_MASK));
# default configuration
# Default configuration:
# ASS = Automatic Slave Select
# TXNEG = MOSI changes on SCLK falling edge
self.conf = self.CTRL_ASS | self.CTRL_TXNEG
def wait_busy(self):
while(self.rd_reg(self.R_CTRL) & self.CTRL_BSY):
pass
init_time=time.time()
while(self.rd_reg(self.R_CTRL) & self.CTRL_BSY):
if (time.time()-init_time) > self.WAIT_TIME_OUT:
raise I2CDeviceOperationError("Wait timeout")
def config(self, ass, rx_neg, tx_neg, lsb, ie):
self.conf = 0
......@@ -58,26 +84,24 @@ class COpenCoresSPI:
self.conf |= self.CTRL_IE
# slave = slave number (0 to 7)
# data = byte data array to send, in case if read fill with dummy data of the right size
# data = byte data array to send,
# in case of read, filled with dummy data of the right size
def transaction(self, slave, data):
txrx = [0x00000000, 0x00000000, 0x00000000, 0x00000000]
for i in range(0,len(data)):
txrx[i/4] += (data[i]<<((i%4)*8))
#print("tx[%d]=%.8X data[%d]=%.2X") %(i/4,txrx[i/4],i,data[i])
#print '[SPI] tx[%d]=%.8X data[%d]=%.2X' % (i/4,txrx[i/4],i,data[i])
for i in range(0, len(txrx)):
self.wr_reg(self.R_TX[i], txrx[i])
#print('data length: 0x%X')%len(data)
#print '[SPI] data length: 0x%X' % len(data)
self.wr_reg(self.R_SS, self.SS_SEL[slave])
self.wr_reg(self.R_CTRL, (self.LGH_MASK & (len(data)<<3)) | self.CTRL_GO | self.conf)
self.wait_busy()
for i in range(0, len(txrx)):
txrx[i] = self.rd_reg(self.R_RX[i])
#print("rx[%d]=%.8X") %(i,txrx[i])
#print '[SPI] rx[%d]=%.8X' % (i,txrx[i])
return txrx
# Usage example
#gennum = rr.Gennum();
#spi = COpenCoresSPI(gennum, 0x80000, 500);
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