aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-11-01 21:44:09 -0700
committerH. Peter Anvin <hpa@zytor.com>2011-11-01 21:48:34 -0700
commitadac0cd13500f3dfa8ec0c994fafbbb1ac3de790 (patch)
treeec42c72d4c0c4f598a2ee1d9e5daf2b9f58a873f
parentefaa21c2db63985a3a84288d823ba9c3ba8b89b7 (diff)
downloadabc80-adac0cd13500f3dfa8ec0c994fafbbb1ac3de790.tar.gz
abc80-adac0cd13500f3dfa8ec0c994fafbbb1ac3de790.tar.xz
abc80-adac0cd13500f3dfa8ec0c994fafbbb1ac3de790.zip
enc28j60: fix the handling of CS# on read
Fix the handling of CS# on read, so that the last byte read is indeed the one which is read by IN 2. We don't need a long CS# hold after a read, so simply deassert CS# immediately after STATUS#.
-rw-r--r--CHANGES9
-rw-r--r--enc28j60.v34
2 files changed, 24 insertions, 19 deletions
diff --git a/CHANGES b/CHANGES
index 91c7fb1..8707b27 100644
--- a/CHANGES
+++ b/CHANGES
@@ -8,14 +8,15 @@ Changes in release DE1-19:
OUT# (OUT 0) Send a byte to the Ethernet controller, leave CS# low
C1# (OUT 2) Send a byte to the Ethernet controller, pull CS# high
- C2# (OUT 2) Send FF byte to the Ethernet controller, leave CS# low
C3# (OUT 4) Local reset
- INP# (IN 0) Read a byte from the Ethernet controller, leave CS# low
- STATUS# (IN 1) Read a byte from the Ethernet controller, pull CS# high
+ INP# (IN 0) Read latched byte from controller, leave CS# low
+ STATUS# (IN 1) Read latched byte from controller, pull CS# high
+
+ OUT#, C1# and INP# trigger a new SPI transaction.
Note that reads are "delayed" by one cycle, so it is necessary to
- write a dummy byte before doing the first read.
+ issue a dummy IN 0 before doing the first read.
LEDG0 - disk (SD) activity (for real!)
LEDG1 - disk selected (like the old LED 0)
diff --git a/enc28j60.v b/enc28j60.v
index abfe5bd..08e613f 100644
--- a/enc28j60.v
+++ b/enc28j60.v
@@ -65,14 +65,10 @@ module enc28j60 (
// Write commands:
// OUT - send data byte, leave CS# asserted
// C1 - send data byte, deassert CS#
- // C2 - send FF byte, leave CS# asserted
// C3 - reset
// Read commands:
// INP - read input shift register, output FF, leave CS# asserted
- // STATUS - read input shift register, output FF, deassert CS#
- //
- // If CS# is already deasserted, input simply returns the shift
- // register contents.
+ // STATUS - read input shift register, deassert CS#
// ------------------------------------------------------------------------
parameter selectcode = 6'd9;
@@ -94,10 +90,11 @@ module enc28j60 (
assign eth_sck = spi_clk;
assign eth_mosi = spi_shr_out[7];
- wire abc_active =
- selected & (~abc_out_n | ~abc_c1_n | ~abc_c2_n |
- ~abc_inp_n | ~abc_status_n);
-
+ wire abc_start = selected & (~abc_out_n | ~abc_c1_n | ~abc_inp_n );
+ wire abc_endread = selected & ~abc_status_n;
+ wire abc_active = abc_start | abc_endread;
+ wire abc_read = selected & (~abc_inp_n | ~abc_status_n);
+
assign abc_rdy = ~(abc_active & ~spi_cmd_ok);
reg [1:0] spi_state;
@@ -140,13 +137,13 @@ module enc28j60 (
begin
spi_cmd_ok <= 1'b1;
- if (abc_active)
+ if (abc_start)
begin
spi_cs_n <= 1'b0;
spi_state <= st_data;
spi_shr_out <= cpu_to_spi_data;
spi_ctr <= 4'd7;
- spi_finish <= ~abc_c1_n | ~abc_status_n;
+ spi_finish <= ~abc_c1_n;
end
end // case: spi_idle
@@ -167,11 +164,18 @@ module enc28j60 (
spi_ctr <= 4'd8;
spi_state <= st_cshold0;
end
- else if (abc_active)
+ else if (abc_endread)
+ begin
+ // After STATUS# we raise CS# immediately
+ spi_state <= st_cshold1;
+ spi_cs_n <= 1'b1;
+ spi_cmd_ok <= 1'b1;
+ end
+ else if (abc_start)
begin
spi_shr_out <= cpu_to_spi_data;
spi_ctr <= 4'd7;
- spi_finish <= ~abc_c1_n | ~abc_status_n;
+ spi_finish <= ~abc_c1_n;
spi_cmd_ok <= 1'b1;
end
else
@@ -200,6 +204,7 @@ module enc28j60 (
st_cshold1:
begin
+ spi_cs_n <= 1'b1;
spi_state <= st_idle;
spi_cmd_ok <= 1'b1;
end
@@ -210,7 +215,6 @@ module enc28j60 (
//
// Output data
//
- assign abc_di = (selected & (~abc_inp_n | ~abc_status_n))
- ? spi_shr_in : 8'hff;
+ assign abc_di = abc_read ? spi_shr_in : 8'hff;
endmodule // enc28j60