From: Florent Kermarrec Date: Tue, 26 Feb 2013 22:17:34 +0000 (+0100) Subject: move spi2csr to briges/spi2csr X-Git-Tag: 24jan2021_ls180~2575^2~118 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5fc89f0c7167ec65438fbb43b80bb7f6d8a43aa5;p=litex.git move spi2csr to briges/spi2csr --- diff --git a/miscope/bridges/__init__.py b/miscope/bridges/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/miscope/bridges/spi2csr/__init__.py b/miscope/bridges/spi2csr/__init__.py new file mode 100644 index 00000000..f327762c --- /dev/null +++ b/miscope/bridges/spi2csr/__init__.py @@ -0,0 +1,160 @@ +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 diff --git a/miscope/bridges/spi2csr/tools/__init__.py b/miscope/bridges/spi2csr/tools/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/miscope/bridges/spi2csr/tools/arduino/spiFpga.cpp b/miscope/bridges/spi2csr/tools/arduino/spiFpga.cpp new file mode 100644 index 00000000..0787072e --- /dev/null +++ b/miscope/bridges/spi2csr/tools/arduino/spiFpga.cpp @@ -0,0 +1,59 @@ +/* + * spiFpga + * Copyright (C) 2012 by Florent Kermarrec + * Copyright (C) 2011 by James Bowman + * + */ + +#include "WProgram.h" +#include +#include +#include + +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 diff --git a/miscope/bridges/spi2csr/tools/arduino/spiFpga.h b/miscope/bridges/spi2csr/tools/arduino/spiFpga.h new file mode 100644 index 00000000..c28837b2 --- /dev/null +++ b/miscope/bridges/spi2csr/tools/arduino/spiFpga.h @@ -0,0 +1,28 @@ +/* + * spiFpga + * Copyright (C) 2012 by Florent Kermarrec + * Copyright (C) 2011 by James Bowman + * + */ + +#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 diff --git a/miscope/bridges/spi2csr/tools/arduino/uart2Spi.pde b/miscope/bridges/spi2csr/tools/arduino/uart2Spi.pde new file mode 100644 index 00000000..df049bfd --- /dev/null +++ b/miscope/bridges/spi2csr/tools/arduino/uart2Spi.pde @@ -0,0 +1,51 @@ +/* + 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 +#include + +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 diff --git a/miscope/bridges/spi2csr/tools/uart2Spi.py b/miscope/bridges/spi2csr/tools/uart2Spi.py new file mode 100644 index 00000000..9f5568df --- /dev/null +++ b/miscope/bridges/spi2csr/tools/uart2Spi.py @@ -0,0 +1,65 @@ +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 diff --git a/spi2Csr/__init__.py b/spi2Csr/__init__.py deleted file mode 100644 index f327762c..00000000 --- a/spi2Csr/__init__.py +++ /dev/null @@ -1,160 +0,0 @@ -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 diff --git a/spi2Csr/tools/__init__.py b/spi2Csr/tools/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/spi2Csr/tools/arduino/spiFpga.cpp b/spi2Csr/tools/arduino/spiFpga.cpp deleted file mode 100644 index 0787072e..00000000 --- a/spi2Csr/tools/arduino/spiFpga.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * spiFpga - * Copyright (C) 2012 by Florent Kermarrec - * Copyright (C) 2011 by James Bowman - * - */ - -#include "WProgram.h" -#include -#include -#include - -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 diff --git a/spi2Csr/tools/arduino/spiFpga.h b/spi2Csr/tools/arduino/spiFpga.h deleted file mode 100644 index c28837b2..00000000 --- a/spi2Csr/tools/arduino/spiFpga.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * spiFpga - * Copyright (C) 2012 by Florent Kermarrec - * Copyright (C) 2011 by James Bowman - * - */ - -#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 diff --git a/spi2Csr/tools/arduino/uart2Spi.pde b/spi2Csr/tools/arduino/uart2Spi.pde deleted file mode 100644 index df049bfd..00000000 --- a/spi2Csr/tools/arduino/uart2Spi.pde +++ /dev/null @@ -1,51 +0,0 @@ -/* - 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 -#include - -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 diff --git a/spi2Csr/tools/uart2Spi.py b/spi2Csr/tools/uart2Spi.py deleted file mode 100644 index 9f5568df..00000000 --- a/spi2Csr/tools/uart2Spi.py +++ /dev/null @@ -1,65 +0,0 @@ -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