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
LBFFilho 2024-05-08 11:19:37 -03:00 committed by GitHub
parent b8418e7e92
commit e757859b56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 85 additions and 18 deletions

View File

@ -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
--------------------------------------------------------------------------------

View File

@ -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

View File

@ -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;

View File

@ -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