summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-06-15 05:08:56 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2011-06-15 05:08:56 (GMT)
commitcb080a847eacc10c98b7d745820bf8280a36bc41 (patch)
tree7d0ce238c1f4356529f15e029ce4179ae4510ace
parentf7599be1a21ad99e7e0dea46dc80845e2a3298f2 (diff)
parent827df9a88a1a7c9950e680157235570515c2bd7d (diff)
downloadabc8000-old-cb080a847eacc10c98b7d745820bf8280a36bc41.zip
abc8000-old-cb080a847eacc10c98b7d745820bf8280a36bc41.tar.gz
abc8000-old-cb080a847eacc10c98b7d745820bf8280a36bc41.tar.bz2
abc8000-old-cb080a847eacc10c98b7d745820bf8280a36bc41.tar.xz
Merge branch 'enc28j60'
-rw-r--r--data/sysrom/include/ioreg.h10
-rw-r--r--de1/de1.v69
-rw-r--r--enc28j60.v183
3 files changed, 251 insertions, 11 deletions
diff --git a/data/sysrom/include/ioreg.h b/data/sysrom/include/ioreg.h
index 35e5cf0..135927b 100644
--- a/data/sysrom/include/ioreg.h
+++ b/data/sysrom/include/ioreg.h
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2010 H. Peter Anvin - All Rights Reserved
+ * Copyright 2010-2011 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -128,6 +128,14 @@ static __inline__ void writel(uint32_t __val, volatile uint32_t *__ptr)
#define IO_KBD_STATUS IO_BYTE(0xfff50002)
/*
+ * ENC28J60 Ethernet controller
+ */
+#define IO_ETH_NOSTART IO_BYTE(0xfff60000)
+#define IO_ETH_MIDDLE IO_BYTE(0xfff60002)
+#define IO_ETH_END IO_BYTE(0xfff60004)
+#define IO_ETH_END_SLOW IO_BYTE(0xfff60006)
+
+/*
* 68901 Multi-Function Peripheral
*/
#define IO_MFP_GPDR IO_BYTE(0xfffe0001)
diff --git a/de1/de1.v b/de1/de1.v
index ce83c73..26bd626 100644
--- a/de1/de1.v
+++ b/de1/de1.v
@@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
//
-// Copyright 2003-2010 H. Peter Anvin - All Rights Reserved
+// Copyright 2003-2011 H. Peter Anvin - All Rights Reserved
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -534,14 +534,62 @@ module abc8000_de1 (
);
// ------------------------------------------------------------------------
+ // ENC28J60 SPI Ethernet interface (using GPIO1)
+ // ------------------------------------------------------------------------
+
+ wire [15:0] eth_cpu_di;
+ wire eth_wait_n;
+ wire eth_wol_n;
+ wire eth_irq_n;
+ wire eth_rst_n = rst_n;
+ wire eth_cs_n, eth_mosi, eth_sck, eth_miso;
+
+ enc28j60 eth_enc28j60 (
+ .rst_n ( rst_n ),
+ .clk ( sys_clk ),
+
+ .eth_cs_n ( eth_cs_n ),
+ .eth_mosi ( eth_mosi ),
+ .eth_sck ( eth_sck ),
+ .eth_miso ( eth_miso ),
+
+ .cpu_do ( cpu_do[15:8] ),
+ .cpu_di ( eth_cpu_di[15:8] ),
+ .msel ( msel_dev[6] & ~cpu_be_n[1] ),
+ .cpu_a ( cpu_a[2:1] ),
+ .cpu_r_wn ( cpu_r_wn ),
+ .cpu_wait_n ( eth_wait_n )
+ );
+
+ assign eth_cpu_di[7:0] = 8'hff; // Byte-sized device only
+
+ // The ENC28J60 module is attached to GPIO1 signals 26-33, corresponding
+ // to pins 29-38 (including power). This is dictated by VCC33 and GND
+ // on pins 29-30 corresponding to the MOD-ENC28J60 pins 1-2.
+
+ assign gpio_1[26] = 1'bz; // Optional connection to LEDA
+ assign gpio_1[27] = 1'bz;
+ assign eth_wol_n = gpio_1[27];
+ assign gpio_1[28] = 1'bz;
+ assign eth_irq_n = gpio_1[28];
+ assign gpio_1[29] = eth_rst_n;
+ assign gpio_1[30] = 1'bz;
+ assign eth_miso = gpio_1[30];
+ assign gpio_1[31] = eth_mosi;
+ assign gpio_1[32] = eth_sck;
+ assign gpio_1[33] = eth_cs_n;
+
+ // ------------------------------------------------------------------------
// Stubbed out external devices
// ------------------------------------------------------------------------
assign ledr = sw_d;
// GPIOs
- assign gpio_0 = 36'hz_zzzz_zzzz;
- assign gpio_1 = 36'hz_zzzz_zzzz;
+ assign gpio_0 = 36'hz_zzzz_zzzz;
+ assign gpio_1[25:0] = 26'hzzz_zzzz;
+ assign gpio_1[35:34] = 2'bzz;
+
// ------------------------------------------------------------------------
// Display unit
@@ -627,12 +675,13 @@ module abc8000_de1 (
assign cpu_di = fl_cpu_di & serial_cpu_di &
sdram_cpu_di & video_cpu_di & audio_cpu_di &
- sysctl_cpu_di & sdcard_cpu_di &
+ sysctl_cpu_di & sdcard_cpu_di & eth_cpu_di &
kbd_cpu_di & mfp_cpu_di;
assign cpu_dtack_n = (cpu_as_n |
- ~( sdram_wait_n & audio_wait_n & sdcard_wait_n
- & ~(msel_dev[14] | msel_dev[15])))
+ ~( sdram_wait_n & audio_wait_n & sdcard_wait_n &
+ eth_wait_n &
+ ~(msel_dev[14] | msel_dev[15])))
& mfp_dtack_n;
// MFP assigned to IPL 4, nothing else in use
@@ -663,15 +712,15 @@ module mfp_clk_gen
);
reg [13:0] ctr;
- reg final;
+ reg final_ctr;
- assign mfp_clk = final;
+ assign mfp_clk = final_ctr;
always @(negedge rst_n or posedge sys_clk)
if (~rst_n)
begin
ctr <= 14'd0;
- final <= 1'b0;
+ final_ctr <= 1'b0;
end
else
begin
@@ -682,7 +731,7 @@ module mfp_clk_gen
else
begin
ctr <= ctr - (14'd15625 - 14'd3072);
- final <= ~final;
+ final_ctr <= ~final_ctr;
end
end // else: !if(~rst_n)
endmodule // mfp_clk
diff --git a/enc28j60.v b/enc28j60.v
new file mode 100644
index 0000000..a89cdc9
--- /dev/null
+++ b/enc28j60.v
@@ -0,0 +1,183 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2011 H. Peter Anvin - All Rights Reserved
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom
+// the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall
+// be included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// -----------------------------------------------------------------------
+
+//
+// enc28j60.v
+//
+// Driver for the Microchip ENC28J60 SPI Ethernet controller
+//
+
+module enc28j60 (
+ input rst_n, // Global reset
+ input clk, // CPU clk (25 MHz)
+
+ output eth_cs_n, // SPI CS#
+ output eth_mosi, // SPI MOSI (SI)
+ output eth_sck, // SPI SCLK
+ input eth_miso, // SPI MISO (SO)
+
+ input [7:0] cpu_do, // CPU data out (CPU->controller)
+ output [7:0] cpu_di, // CPU data in (controller->CPU)
+ input msel, // Select
+ input [1:0] cpu_a, // Address bits
+ input cpu_r_wn, // R/W#
+ output cpu_wait_n
+ );
+
+ // ------------------------------------------------------------------------
+ //
+ // ENC28J60 supports up to 20 MHz on the SPI bus, but we run it at
+ // CPU clk / 2 (12.5 MHz). However, all fixed timings are such that
+ // running this module up to 40 MHz for a 20 MHz output should work.
+ //
+ // The CPU interface is a byte-oriented peripheral.
+ // The actual connection to the 68000 bus shifts the addresses left
+ // by one.
+ //
+ // 00 - read input shift register (ignored on write)
+ // 01 - start bus transaction, leave CS# asserted
+ // 10 - start bus transaction, then deassert CS# (1 cycle hold)
+ // 11 - start bus transaction, then deassert CS# (9 cycles hold)
+ // ------------------------------------------------------------------------
+
+ reg [7:0] spi_shr_out;
+ reg [7:0] spi_shr_in;
+ reg [3:0] spi_ctr; // Bit or cycle counter
+
+ reg spi_cs_n;
+ reg spi_clk;
+
+ reg spi_active;
+ reg spi_cmd_ok;
+ reg [1:0] spi_finish;
+
+ assign eth_cs_n = spi_cs_n;
+ assign eth_sck = spi_clk;
+ assign eth_mosi = spi_shr_out[7];
+
+ assign cpu_wait_n = ~(msel & ~spi_cmd_ok);
+
+ reg [1:0] spi_state;
+ parameter st_idle = 2'b00;
+ parameter st_data = 2'b01;
+ parameter st_cshold0 = 2'b10;
+ parameter st_cshold1 = 2'b11;
+
+ always @(negedge rst_n or posedge clk)
+ if (~rst_n)
+ begin
+ spi_state <= st_idle;
+ spi_cs_n <= 1'b1;
+ spi_clk <= 1'b0;
+ spi_shr_out <= 8'hff;
+ spi_shr_in <= 8'hxx;
+ spi_ctr <= 4'd0;
+ spi_finish <= 1'bx;
+ spi_cmd_ok <= 1'b0;
+ end
+ else
+ begin
+ spi_cmd_ok <= spi_cmd_ok & msel;
+
+ case (spi_state)
+ st_idle:
+ begin
+ spi_cmd_ok <= 1'b1;
+
+ if (msel & |cpu_a)
+ begin
+ spi_cs_n <= 1'b0;
+ spi_state <= st_data;
+ spi_shr_out <= cpu_r_wn ? 8'hff : cpu_do;
+ spi_ctr <= 4'd7;
+ spi_finish <= cpu_a;
+ end
+ end // case: spi_idle
+
+ st_data:
+ begin
+ spi_cs_n <= 1'b0;
+ spi_clk <= ~spi_clk;
+
+ if (spi_clk)
+ begin
+ spi_shr_out <= { spi_shr_out[6:0], 1'b1 };
+ spi_ctr <= spi_ctr - 1'b1;
+
+ if (~|spi_ctr)
+ begin
+ if (spi_finish[1])
+ begin
+ spi_ctr <= { spi_finish[0], 3'b000 };
+ spi_state <= st_cshold0;
+ end
+ else if (msel & |cpu_a)
+ begin
+ spi_shr_out <= cpu_r_wn ? 8'hff : cpu_do;
+ spi_ctr <= 4'd7;
+ spi_finish <= cpu_a;
+ spi_cmd_ok <= 1'b1;
+ end
+ else
+ begin
+ spi_state <= st_idle;
+ spi_cmd_ok <= 1'b1;
+ end
+ end // if (~|spi_ctr)
+ end // if (spi_clk)
+ else
+ begin
+ spi_shr_in <= { spi_shr_in[6:0], eth_miso };
+ end // else: !if(spi_clk)
+ end // case: spi_data
+
+ st_cshold0:
+ begin
+ spi_ctr <= spi_ctr - 1'b1;
+
+ if (~|spi_ctr)
+ begin
+ spi_cs_n <= 1'b1;
+ spi_state <= st_cshold1;
+ end
+ end
+
+ st_cshold1:
+ begin
+ spi_state <= st_idle;
+ spi_cmd_ok <= 1'b1;
+ end
+
+ endcase
+ end // else: !if(~rst_n)
+
+ //
+ // Output data
+ //
+ assign cpu_di = (msel & cpu_r_wn) ? spi_shr_in : 8'hff;
+
+endmodule // enc28j60