SPI Engine: create inverted CS mode (#1301)
SPI Engine: create inverted CS mode Add a CS Invert Mask instruction for selecting the polarity of the Chip Select pins. Signed-off-by: Laez Barbosa <laez.barbosa@analog.com>main
parent
b8418e7e92
commit
e757859b56
|
@ -4,7 +4,7 @@ SPI Engine Instruction Set Specification
|
|||
================================================================================
|
||||
|
||||
The SPI Engine instruction set is a simple 16-bit instruction set of which
|
||||
12-bit is currently allocated (bits 15,14,11,10 are always 0).
|
||||
13-bits are currently allocated (bits 15,11,10 are always 0).
|
||||
|
||||
Instructions
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -48,7 +48,10 @@ accepted/becomes available.
|
|||
- Length
|
||||
- n + 1 number of words that will be transferred.
|
||||
|
||||
Chip-select Instruction
|
||||
|
||||
.. _spi_engine cs-instruction:
|
||||
|
||||
Chip-Select Instruction
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
== == == == == == = = = = = = = = = =
|
||||
|
@ -60,6 +63,13 @@ Chip-select Instruction
|
|||
The chip-select instruction updates the value chip-select output signal of the
|
||||
SPI Engine execution module.
|
||||
|
||||
The physical outputs on each pin may be inverted relative to the command
|
||||
according to the mask set by :ref:`spi_engine cs-invert-mask-instruction`. The
|
||||
Invert Mask acts only on the output registers of the Chip-Select pins. Thus, if
|
||||
the last 8 bits of the Chip-Select instruction are 0xFE, only CS[0] will be
|
||||
active regardless of polarity. The polarity inversion process (if needed) is
|
||||
transparent to the programmer.
|
||||
|
||||
Before and after the update is performed the execution module is paused for the
|
||||
specified delay. The length of the delay depends on the module clock frequency,
|
||||
the setting of the prescaler register and the parameter :math:`t` of the
|
||||
|
@ -98,7 +108,7 @@ Configuration Write Instruction
|
|||
== == == == == == = = = = = = = = = =
|
||||
|
||||
The configuration writes instruction updates a
|
||||
:ref:`spi_engine configutarion-registers`
|
||||
:ref:`spi_engine configuration-registers`
|
||||
of the SPI Engine execution module with a new value.
|
||||
|
||||
.. list-table::
|
||||
|
@ -174,7 +184,51 @@ is the minimum, needed by the internal logic.
|
|||
- Time
|
||||
- The amount of time to wait.
|
||||
|
||||
.. _spi_engine configutarion-registers:
|
||||
.. _spi_engine cs-invert-mask-instruction:
|
||||
|
||||
CS Invert Mask Instruction
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
== == == == == == = = = = = = = = = =
|
||||
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||
== == == == == == = = = = = = = = = =
|
||||
0 1 0 0 r r r r m m m m m m m m
|
||||
== == == == == == = = = = = = = = = =
|
||||
|
||||
The CS Invert Mask Instructions allows the user to select on a per-pin basis
|
||||
whether the Chip Select will be active-low (default) or active-high (inverted).
|
||||
Note that the Chip-Select instructions should remain the same because the value
|
||||
of CS is inverted at the output register, and additional logic (e.g. reset
|
||||
counters) occurs when the CS active state is asserted.
|
||||
|
||||
Since the physical values on the pins are inverted at the output, the current
|
||||
Invert Mask does not affect the use of the :ref:`spi_engine cs-instruction`. As
|
||||
an example, a Chip-Select Instruction with the 's' field equal to 0xFE will
|
||||
always result in only CS[0] being active. For an Invert Mask of 0xFF, this would
|
||||
result on only CS[0] being high. For an Invert Mask of 0x00, this would result
|
||||
on only CS[0] being low. For an Invert Mask of 0x01, this would result on all CS
|
||||
pins being high, but only CS[0] is active in this case (since it's the only one
|
||||
currently treated as active-high).
|
||||
|
||||
This was introduced in
|
||||
version 1.02.00 of the core.
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 15 75
|
||||
:header-rows: 1
|
||||
|
||||
* - Bits
|
||||
- Name
|
||||
- Description
|
||||
* - r
|
||||
- reserved
|
||||
- Reserved for future use. Must always be set to 0.
|
||||
* - m
|
||||
- Mask
|
||||
- Mask for selecting inverted CS channels. For the bits set to 1, the
|
||||
corresponding channel will be inverted at the output.
|
||||
|
||||
.. _spi_engine configuration-registers:
|
||||
|
||||
Configuration Registers
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
|
@ -9,23 +9,23 @@ ENDTITLE
|
|||
REG
|
||||
0x00
|
||||
VERSION
|
||||
Version of the peripheral. Follows semantic versioning. Current version 1.00.71.
|
||||
Version of the peripheral. Follows semantic versioning. Current version 1.02.00.
|
||||
ENDREG
|
||||
|
||||
FIELD
|
||||
[31:16] 0x01
|
||||
[31:16] 0x00000001
|
||||
VERSION_MAJOR
|
||||
RO
|
||||
ENDFIELD
|
||||
|
||||
FIELD
|
||||
[15:8] 0x01
|
||||
[15:8] 0x00000002
|
||||
VERSION_MINOR
|
||||
RO
|
||||
ENDFIELD
|
||||
|
||||
FIELD
|
||||
[7:0] 0x71
|
||||
[7:0] 0x00000000
|
||||
VERSION_PATCH
|
||||
RO
|
||||
ENDFIELD
|
||||
|
|
|
@ -133,7 +133,7 @@ module axi_spi_engine #(
|
|||
input [7:0] offload_sync_data
|
||||
);
|
||||
|
||||
localparam PCORE_VERSION = 'h010171;
|
||||
localparam PCORE_VERSION = 'h010200;
|
||||
localparam S_AXI = 0;
|
||||
localparam UP_FIFO = 1;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2015-2023 Analog Devices, Inc. All rights reserved.
|
||||
// Copyright (C) 2015-2024 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
|
@ -76,10 +76,11 @@ module spi_engine_execution #(
|
|||
output reg three_wire
|
||||
);
|
||||
|
||||
localparam CMD_TRANSFER = 2'b00;
|
||||
localparam CMD_CHIPSELECT = 2'b01;
|
||||
localparam CMD_WRITE = 2'b10;
|
||||
localparam CMD_MISC = 2'b11;
|
||||
localparam CMD_TRANSFER = 3'b000;
|
||||
localparam CMD_CHIPSELECT = 3'b001;
|
||||
localparam CMD_WRITE = 3'b010;
|
||||
localparam CMD_MISC = 3'b011;
|
||||
localparam CMD_CS_INV = 3'b100;
|
||||
|
||||
localparam MISC_SYNC = 1'b0;
|
||||
localparam MISC_SLEEP = 1'b1;
|
||||
|
@ -134,6 +135,8 @@ module spi_engine_execution #(
|
|||
reg cpol = DEFAULT_SPI_CFG[1];
|
||||
reg [7:0] clk_div = DEFAULT_CLK_DIV;
|
||||
|
||||
reg [NUM_OF_CS-1:0] cs_inv_mask_reg = 'h0;
|
||||
|
||||
reg sdo_enabled = 1'b0;
|
||||
reg sdi_enabled = 1'b0;
|
||||
|
||||
|
@ -141,12 +144,12 @@ module spi_engine_execution #(
|
|||
|
||||
reg [SDI_DELAY+1:0] trigger_rx_d = {(SDI_DELAY+2){1'b0}};
|
||||
|
||||
wire [1:0] inst = cmd[13:12];
|
||||
wire [1:0] inst_d1 = cmd_d1[13:12];
|
||||
wire [2:0] inst = cmd[14:12];
|
||||
wire [2:0] inst_d1 = cmd_d1[14:12];
|
||||
|
||||
wire exec_cmd = cmd_ready && cmd_valid;
|
||||
wire exec_transfer_cmd = exec_cmd && inst == CMD_TRANSFER;
|
||||
|
||||
wire exec_cs_inv_cmd = exec_cmd && inst == CMD_CS_INV;
|
||||
wire exec_write_cmd = exec_cmd && inst == CMD_WRITE;
|
||||
wire exec_chipselect_cmd = exec_cmd && inst == CMD_CHIPSELECT;
|
||||
wire exec_misc_cmd = exec_cmd && inst == CMD_MISC;
|
||||
|
@ -306,11 +309,21 @@ module spi_engine_execution #(
|
|||
end
|
||||
end
|
||||
|
||||
always @(posedge clk ) begin
|
||||
if (resetn == 1'b0) begin
|
||||
cs_inv_mask_reg <= 'h0;
|
||||
end else begin
|
||||
if (exec_cs_inv_cmd == 1'b1) begin
|
||||
cs_inv_mask_reg <= cmd[NUM_OF_CS-1:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
cs <= 'hff;
|
||||
end else if (cs_gen) begin
|
||||
cs <= cmd_d1[NUM_OF_CS-1:0];
|
||||
cs <= cmd_d1[NUM_OF_CS-1:0]^cs_inv_mask_reg[NUM_OF_CS-1:0];
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue