--- /dev/null
+from migen.fhdl.structure import *
+from migen.bus import csr
+from migen.bank import description, csrgen
+from migen.bank.description import *
+
+class Spi2Csr :
+ def __init__(self, a_width, d_width, max_burst = 8):
+ self.a_width = a_width
+ self.d_width = d_width
+ self.max_burst = 8
+ # Csr interface
+ self.csr = csr.Interface(self.a_width, self.d_width)
+ # Spi interface
+ self.spi_clk = Signal()
+ self.spi_cs_n = Signal(reset=1)
+ self.spi_mosi = Signal()
+ self.spi_miso = Signal()
+ self.spi_int_n = Signal(reset=1)
+
+ def get_fragment(self):
+ comb = []
+ sync = []
+
+ # Resychronisation
+ spi_clk_d1 = Signal()
+ spi_clk_d2 = Signal()
+ spi_clk_d3 = Signal()
+
+ sync += [
+ spi_clk_d1.eq(self.spi_clk),
+ spi_clk_d2.eq(spi_clk_d1),
+ spi_clk_d3.eq(spi_clk_d2)
+ ]
+
+ spi_cs_n_d1 = Signal()
+ spi_cs_n_d2 = Signal()
+ spi_cs_n_d3 = Signal()
+
+ sync += [
+ spi_cs_n_d1.eq(self.spi_cs_n),
+ spi_cs_n_d2.eq(spi_cs_n_d1),
+ spi_cs_n_d3.eq(spi_cs_n_d2)
+ ]
+
+ spi_mosi_d1 = Signal()
+ spi_mosi_d2 = Signal()
+ spi_mosi_d3 = Signal()
+
+ sync += [
+ spi_mosi_d1.eq(self.spi_mosi),
+ spi_mosi_d2.eq(spi_mosi_d1),
+ spi_mosi_d3.eq(spi_mosi_d2)
+ ]
+
+ # Decode
+ spi_clk_rising = Signal()
+ spi_clk_falling = Signal()
+ spi_cs_n_active = Signal()
+ spi_mosi_dat = Signal()
+
+ comb += [
+ spi_clk_rising.eq(spi_clk_d2 & ~spi_clk_d3),
+ spi_clk_falling.eq(~spi_clk_d2 & spi_clk_d3),
+ spi_cs_n_active.eq(~spi_cs_n_d3),
+ spi_mosi_dat.eq(spi_mosi_d3)
+ ]
+
+ #
+ # Spi --> Csr
+ #
+ spi_cnt = Signal(bits_for(self.a_width+self.max_burst*self.d_width))
+ spi_addr = Signal(self.a_width)
+ spi_w_dat = Signal(self.d_width)
+ spi_r_dat = Signal(self.d_width)
+ spi_we = Signal()
+ spi_re = Signal()
+ spi_we_re_done = Signal(reset = 1)
+ spi_miso_dat = Signal()
+
+ # Re/We Signals Decoding
+ first_b = Signal()
+ last_b = Signal()
+
+ comb +=[
+ first_b.eq(spi_cnt[0:bits_for(self.d_width)-1] == 0),
+ last_b.eq(spi_cnt[0:bits_for(self.d_width)-1] == 2**(bits_for(self.d_width)-1)-1)
+ ]
+ sync +=[
+ If((spi_cnt >= (self.a_width + self.d_width)) & first_b,
+ spi_we.eq(spi_addr[self.a_width-1] & ~spi_we_re_done),
+ spi_re.eq(~spi_addr[self.a_width-1] & ~spi_we_re_done),
+ spi_we_re_done.eq(1)
+ ).Elif((spi_cnt >= self.a_width) & first_b,
+ spi_re.eq(~spi_addr[self.a_width-1] & ~spi_we_re_done),
+ spi_we_re_done.eq(1)
+ ).Else(
+ spi_we.eq(0),
+ spi_re.eq(0),
+ spi_we_re_done.eq(0)
+ )
+ ]
+
+ # Spi Addr / Data Decoding
+ sync +=[
+ If(~spi_cs_n_active,
+ spi_cnt.eq(0),
+ ).Elif(spi_clk_rising,
+ # addr
+ If(spi_cnt < self.a_width,
+ spi_addr.eq(Cat(spi_mosi_dat,spi_addr[:self.a_width-1]))
+ ).Elif((spi_cnt >= (self.a_width+self.d_width)) & last_b,
+ spi_addr.eq(spi_addr+1)
+ ).Elif((spi_cnt >= self.a_width) & last_b & (spi_addr[self.a_width-1] == 0),
+ spi_addr.eq(spi_addr+1)
+ ),
+ # dat
+ If(spi_cnt >= self.a_width,
+ spi_w_dat.eq(Cat(spi_mosi_dat,spi_w_dat[:self.d_width-1]))
+ ),
+
+ # spi_cnt
+ spi_cnt.eq(spi_cnt+1)
+ )
+ ]
+
+ #
+ # Csr --> Spi
+ #
+ spi_r_dat_shift = Signal(self.d_width)
+ sync +=[
+ If(spi_re,
+ spi_r_dat_shift.eq(spi_r_dat)
+ ),
+
+ If(~spi_cs_n_active,
+ spi_miso_dat.eq(0)
+ ).Elif(spi_clk_falling,
+ spi_miso_dat.eq(spi_r_dat_shift[self.d_width-1]),
+ spi_r_dat_shift.eq(Cat(0,spi_r_dat_shift[:self.d_width-1]))
+ )
+ ]
+
+
+ #
+ # Csr Interface
+ #
+ comb += [
+ self.csr.adr.eq(spi_addr),
+ self.csr.dat_w.eq(spi_w_dat),
+ self.csr.we.eq(spi_we)
+ ]
+
+ #
+ # Spi Interface
+ #
+ comb += [
+ spi_r_dat.eq(self.csr.dat_r),
+ self.spi_miso.eq(spi_miso_dat)
+ ]
+ return Fragment(comb=comb,sync=sync)
\ No newline at end of file
--- /dev/null
+/*
+ * spiFpga
+ * Copyright (C) 2012 by Florent Kermarrec <florent@enjoy-digital.fr>
+ * Copyright (C) 2011 by James Bowman <jamesb@excamera.com>
+ *
+ */
+
+#include "WProgram.h"
+#include <avr/pgmspace.h>
+#include <SPI.h>
+#include <spiFpga.h>
+
+SFClass SF;
+
+void SFClass::begin()
+{
+ pinMode(SS_PIN, OUTPUT);
+ SPI.begin();
+ SPI.setClockDivider(SPI_CLOCK_DIV2);
+ SPI.setBitOrder(MSBFIRST);
+ SPI.setDataMode(SPI_MODE0);
+ SPSR = (1 << SPI2X);
+ digitalWrite(SS_PIN, HIGH);
+}
+
+void SFClass::end() {
+}
+
+void SFClass::__start(unsigned int addr)
+{
+ digitalWrite(SS_PIN, LOW);
+ SPI.transfer(highByte(addr));
+ SPI.transfer(lowByte(addr));
+}
+
+void SFClass::__wstart(unsigned int addr)
+{
+ __start(0x8000|addr);
+}
+
+void SFClass::__end()
+{
+ digitalWrite(SS_PIN, HIGH);
+}
+
+char SFClass::rd(unsigned int addr)
+{
+ __start(addr);
+ char r = SPI.transfer(0);
+ __end();
+ return r;
+}
+
+void SFClass::wr(unsigned int addr, char v)
+{
+ __wstart(addr);
+ SPI.transfer(v);
+ __end();
+}
\ No newline at end of file
--- /dev/null
+/*
+ * spiFpga
+ * Copyright (C) 2012 by Florent Kermarrec <florent@enjoy-digital.fr>
+ * Copyright (C) 2011 by James Bowman <jamesb@excamera.com>
+ *
+ */
+
+#ifndef _SF_H_INCLUDED
+#define _SF_H_INCLUDED
+
+#ifndef SS_PIN
+#define SS_PIN 10
+#endif
+
+class SFClass {
+public:
+ static void begin();
+ static void end();
+ static void __start(unsigned int addr);
+ static void __wstart(unsigned int addr);
+ static void __end(void);
+ static char rd(unsigned int addr);
+ static void wr(unsigned int addr, char v);
+};
+
+extern SFClass SF;
+
+#endif
--- /dev/null
+/*
+ Uart2Spi
+ Copyright 2012 - Florent Kermarrec - florent@enjoy-digital.fr
+
+ Protocol:
+ -Write : 0x01 + 16b Addr + 8b Data
+ -Read : 0x02 + 16b Addr + 8b Don't Care
+
+ Todo:
+ Support Spi Burst Mode
+
+ */
+#include <SPI.h>
+#include <spiFpga.h>
+
+void setup() {
+ SF.begin();
+ SPI.setClockDivider(8);
+ Serial.begin(115200);
+}
+
+int cmd = 0;
+
+void loop()
+{
+ if (Serial.available() == 4)
+ {
+ cmd = Serial.read();
+ //Write Cmd
+ if (cmd == 0x01)
+ {
+ char addrMsb = Serial.read();
+ char addrLsb = Serial.read();
+ char data = Serial.read();
+ SF.wr(addrMsb<<8|addrLsb, data);
+ }
+ //Read Cmd
+ if (cmd == 0x02)
+ {
+ char addrMsb = Serial.read();
+ char addrLsb = Serial.read();
+ Serial.read();
+ char data;
+ data = SF.rd(addrMsb<<8|addrLsb);
+ Serial.print(data);
+ }
+ else {
+ Serial.flush();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+import string
+import time
+import serial
+from struct import *
+from migen.fhdl.structure import *
+
+def write_b(uart, data):
+ uart.write(pack('B',data))
+
+class Uart2Spi:
+ def __init__(self, port, baudrate, debug = False):
+ self.port = port
+ self.baudrate = baudrate
+ self.debug = debug
+ self.uart = serial.Serial(port, baudrate, timeout=0.25)
+
+ def read(self, addr):
+ write_b(self.uart, 0x02)
+ write_b(self.uart, (addr>>8)&0xFF)
+ write_b(self.uart, (addr&0xFF))
+ write_b(self.uart, 0x00)
+ read = self.uart.read()
+ if self.debug:
+ print("RD @ %04X" %addr)
+ return int(read[0])
+
+ def read_n(self, addr, n, endianess = "LE"):
+ r = 0
+ words = int(2**bits_for(n-1)/8)
+ for i in range(words):
+ if endianess == "BE":
+ r += self.read(addr+i)<<(8*i)
+ elif endianess == "LE":
+ r += self.read(addr+words-1-i)<<(8*i)
+ if self.debug:
+ print("RD @ %04X" %addr)
+ return r
+
+
+ def write(self, addr, data):
+ write_b(self.uart, 0x01)
+ write_b(self.uart, (addr>>8)&0xFF)
+ write_b(self.uart, (addr&0xFF))
+ write_b(self.uart, data)
+ if self.debug:
+ print("WR %02X @ %04X" %(data, addr))
+
+ def write_n(self, addr, data, n, endianess = "LE"):
+ words = int(2**bits_for(n-1)/8)
+ for i in range(words):
+ if endianess == "BE":
+ self.write(addr+i, (data>>(8*i)) & 0xFF)
+ elif endianess == "LE":
+ self.write(addr+words-1-i, (data>>(8*i)) & 0xFF)
+ if self.debug:
+ print("WR %08X @ %04X" %(data, addr))
+
+def main():
+ csr = Uart2Spi(1,115200)
+ for i in range(100):
+ csr.write(0x0000,i)
+ print(csr.read(0x0000))
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.bus import csr
-from migen.bank import description, csrgen
-from migen.bank.description import *
-
-class Spi2Csr :
- def __init__(self, a_width, d_width, max_burst = 8):
- self.a_width = a_width
- self.d_width = d_width
- self.max_burst = 8
- # Csr interface
- self.csr = csr.Interface(self.a_width, self.d_width)
- # Spi interface
- self.spi_clk = Signal()
- self.spi_cs_n = Signal(reset=1)
- self.spi_mosi = Signal()
- self.spi_miso = Signal()
- self.spi_int_n = Signal(reset=1)
-
- def get_fragment(self):
- comb = []
- sync = []
-
- # Resychronisation
- spi_clk_d1 = Signal()
- spi_clk_d2 = Signal()
- spi_clk_d3 = Signal()
-
- sync += [
- spi_clk_d1.eq(self.spi_clk),
- spi_clk_d2.eq(spi_clk_d1),
- spi_clk_d3.eq(spi_clk_d2)
- ]
-
- spi_cs_n_d1 = Signal()
- spi_cs_n_d2 = Signal()
- spi_cs_n_d3 = Signal()
-
- sync += [
- spi_cs_n_d1.eq(self.spi_cs_n),
- spi_cs_n_d2.eq(spi_cs_n_d1),
- spi_cs_n_d3.eq(spi_cs_n_d2)
- ]
-
- spi_mosi_d1 = Signal()
- spi_mosi_d2 = Signal()
- spi_mosi_d3 = Signal()
-
- sync += [
- spi_mosi_d1.eq(self.spi_mosi),
- spi_mosi_d2.eq(spi_mosi_d1),
- spi_mosi_d3.eq(spi_mosi_d2)
- ]
-
- # Decode
- spi_clk_rising = Signal()
- spi_clk_falling = Signal()
- spi_cs_n_active = Signal()
- spi_mosi_dat = Signal()
-
- comb += [
- spi_clk_rising.eq(spi_clk_d2 & ~spi_clk_d3),
- spi_clk_falling.eq(~spi_clk_d2 & spi_clk_d3),
- spi_cs_n_active.eq(~spi_cs_n_d3),
- spi_mosi_dat.eq(spi_mosi_d3)
- ]
-
- #
- # Spi --> Csr
- #
- spi_cnt = Signal(bits_for(self.a_width+self.max_burst*self.d_width))
- spi_addr = Signal(self.a_width)
- spi_w_dat = Signal(self.d_width)
- spi_r_dat = Signal(self.d_width)
- spi_we = Signal()
- spi_re = Signal()
- spi_we_re_done = Signal(reset = 1)
- spi_miso_dat = Signal()
-
- # Re/We Signals Decoding
- first_b = Signal()
- last_b = Signal()
-
- comb +=[
- first_b.eq(spi_cnt[0:bits_for(self.d_width)-1] == 0),
- last_b.eq(spi_cnt[0:bits_for(self.d_width)-1] == 2**(bits_for(self.d_width)-1)-1)
- ]
- sync +=[
- If((spi_cnt >= (self.a_width + self.d_width)) & first_b,
- spi_we.eq(spi_addr[self.a_width-1] & ~spi_we_re_done),
- spi_re.eq(~spi_addr[self.a_width-1] & ~spi_we_re_done),
- spi_we_re_done.eq(1)
- ).Elif((spi_cnt >= self.a_width) & first_b,
- spi_re.eq(~spi_addr[self.a_width-1] & ~spi_we_re_done),
- spi_we_re_done.eq(1)
- ).Else(
- spi_we.eq(0),
- spi_re.eq(0),
- spi_we_re_done.eq(0)
- )
- ]
-
- # Spi Addr / Data Decoding
- sync +=[
- If(~spi_cs_n_active,
- spi_cnt.eq(0),
- ).Elif(spi_clk_rising,
- # addr
- If(spi_cnt < self.a_width,
- spi_addr.eq(Cat(spi_mosi_dat,spi_addr[:self.a_width-1]))
- ).Elif((spi_cnt >= (self.a_width+self.d_width)) & last_b,
- spi_addr.eq(spi_addr+1)
- ).Elif((spi_cnt >= self.a_width) & last_b & (spi_addr[self.a_width-1] == 0),
- spi_addr.eq(spi_addr+1)
- ),
- # dat
- If(spi_cnt >= self.a_width,
- spi_w_dat.eq(Cat(spi_mosi_dat,spi_w_dat[:self.d_width-1]))
- ),
-
- # spi_cnt
- spi_cnt.eq(spi_cnt+1)
- )
- ]
-
- #
- # Csr --> Spi
- #
- spi_r_dat_shift = Signal(self.d_width)
- sync +=[
- If(spi_re,
- spi_r_dat_shift.eq(spi_r_dat)
- ),
-
- If(~spi_cs_n_active,
- spi_miso_dat.eq(0)
- ).Elif(spi_clk_falling,
- spi_miso_dat.eq(spi_r_dat_shift[self.d_width-1]),
- spi_r_dat_shift.eq(Cat(0,spi_r_dat_shift[:self.d_width-1]))
- )
- ]
-
-
- #
- # Csr Interface
- #
- comb += [
- self.csr.adr.eq(spi_addr),
- self.csr.dat_w.eq(spi_w_dat),
- self.csr.we.eq(spi_we)
- ]
-
- #
- # Spi Interface
- #
- comb += [
- spi_r_dat.eq(self.csr.dat_r),
- self.spi_miso.eq(spi_miso_dat)
- ]
- return Fragment(comb=comb,sync=sync)
\ No newline at end of file
+++ /dev/null
-/*
- * spiFpga
- * Copyright (C) 2012 by Florent Kermarrec <florent@enjoy-digital.fr>
- * Copyright (C) 2011 by James Bowman <jamesb@excamera.com>
- *
- */
-
-#include "WProgram.h"
-#include <avr/pgmspace.h>
-#include <SPI.h>
-#include <spiFpga.h>
-
-SFClass SF;
-
-void SFClass::begin()
-{
- pinMode(SS_PIN, OUTPUT);
- SPI.begin();
- SPI.setClockDivider(SPI_CLOCK_DIV2);
- SPI.setBitOrder(MSBFIRST);
- SPI.setDataMode(SPI_MODE0);
- SPSR = (1 << SPI2X);
- digitalWrite(SS_PIN, HIGH);
-}
-
-void SFClass::end() {
-}
-
-void SFClass::__start(unsigned int addr)
-{
- digitalWrite(SS_PIN, LOW);
- SPI.transfer(highByte(addr));
- SPI.transfer(lowByte(addr));
-}
-
-void SFClass::__wstart(unsigned int addr)
-{
- __start(0x8000|addr);
-}
-
-void SFClass::__end()
-{
- digitalWrite(SS_PIN, HIGH);
-}
-
-char SFClass::rd(unsigned int addr)
-{
- __start(addr);
- char r = SPI.transfer(0);
- __end();
- return r;
-}
-
-void SFClass::wr(unsigned int addr, char v)
-{
- __wstart(addr);
- SPI.transfer(v);
- __end();
-}
\ No newline at end of file
+++ /dev/null
-/*
- * spiFpga
- * Copyright (C) 2012 by Florent Kermarrec <florent@enjoy-digital.fr>
- * Copyright (C) 2011 by James Bowman <jamesb@excamera.com>
- *
- */
-
-#ifndef _SF_H_INCLUDED
-#define _SF_H_INCLUDED
-
-#ifndef SS_PIN
-#define SS_PIN 10
-#endif
-
-class SFClass {
-public:
- static void begin();
- static void end();
- static void __start(unsigned int addr);
- static void __wstart(unsigned int addr);
- static void __end(void);
- static char rd(unsigned int addr);
- static void wr(unsigned int addr, char v);
-};
-
-extern SFClass SF;
-
-#endif
+++ /dev/null
-/*
- Uart2Spi
- Copyright 2012 - Florent Kermarrec - florent@enjoy-digital.fr
-
- Protocol:
- -Write : 0x01 + 16b Addr + 8b Data
- -Read : 0x02 + 16b Addr + 8b Don't Care
-
- Todo:
- Support Spi Burst Mode
-
- */
-#include <SPI.h>
-#include <spiFpga.h>
-
-void setup() {
- SF.begin();
- SPI.setClockDivider(8);
- Serial.begin(115200);
-}
-
-int cmd = 0;
-
-void loop()
-{
- if (Serial.available() == 4)
- {
- cmd = Serial.read();
- //Write Cmd
- if (cmd == 0x01)
- {
- char addrMsb = Serial.read();
- char addrLsb = Serial.read();
- char data = Serial.read();
- SF.wr(addrMsb<<8|addrLsb, data);
- }
- //Read Cmd
- if (cmd == 0x02)
- {
- char addrMsb = Serial.read();
- char addrLsb = Serial.read();
- Serial.read();
- char data;
- data = SF.rd(addrMsb<<8|addrLsb);
- Serial.print(data);
- }
- else {
- Serial.flush();
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-import string
-import time
-import serial
-from struct import *
-from migen.fhdl.structure import *
-
-def write_b(uart, data):
- uart.write(pack('B',data))
-
-class Uart2Spi:
- def __init__(self, port, baudrate, debug = False):
- self.port = port
- self.baudrate = baudrate
- self.debug = debug
- self.uart = serial.Serial(port, baudrate, timeout=0.25)
-
- def read(self, addr):
- write_b(self.uart, 0x02)
- write_b(self.uart, (addr>>8)&0xFF)
- write_b(self.uart, (addr&0xFF))
- write_b(self.uart, 0x00)
- read = self.uart.read()
- if self.debug:
- print("RD @ %04X" %addr)
- return int(read[0])
-
- def read_n(self, addr, n, endianess = "LE"):
- r = 0
- words = int(2**bits_for(n-1)/8)
- for i in range(words):
- if endianess == "BE":
- r += self.read(addr+i)<<(8*i)
- elif endianess == "LE":
- r += self.read(addr+words-1-i)<<(8*i)
- if self.debug:
- print("RD @ %04X" %addr)
- return r
-
-
- def write(self, addr, data):
- write_b(self.uart, 0x01)
- write_b(self.uart, (addr>>8)&0xFF)
- write_b(self.uart, (addr&0xFF))
- write_b(self.uart, data)
- if self.debug:
- print("WR %02X @ %04X" %(data, addr))
-
- def write_n(self, addr, data, n, endianess = "LE"):
- words = int(2**bits_for(n-1)/8)
- for i in range(words):
- if endianess == "BE":
- self.write(addr+i, (data>>(8*i)) & 0xFF)
- elif endianess == "LE":
- self.write(addr+words-1-i, (data>>(8*i)) & 0xFF)
- if self.debug:
- print("WR %08X @ %04X" %(data, addr))
-
-def main():
- csr = Uart2Spi(1,115200)
- for i in range(100):
- csr.write(0x0000,i)
- print(csr.read(0x0000))
-
-if __name__ == '__main__':
- main()
\ No newline at end of file