SPI: change the different soc's spi defintion location and fix the bug that wrong dummy cycle under quad spi mode

This commit is contained in:
gaoxu 2022-09-15 16:03:54 +08:00
parent 6075806400
commit 8095142796
9 changed files with 405 additions and 145 deletions

View File

@ -19,10 +19,12 @@
#include "driver/periph_ctrl.h"
#include "essl_internal.h"
#include "essl_spi.h"
#include "essl_spi/esp32s2_defs.h"
#define ESSL_SPI_CHECK(cond, warn, ret) do{if(!(cond)){ESP_LOGE(TAG, warn); return ret;}} while(0)
#include "hal/spi_types.h"
#include "hal/spi_ll.h"
/**
* Initialise device function list of SPI by this macro.
*/
@ -58,51 +60,54 @@ typedef struct {
} master_in;
} essl_spi_context_t;
static uint16_t get_hd_command(uint16_t cmd_i, uint32_t flags)
static uint16_t get_hd_command(spi_command_t cmd_t, uint32_t flags)
{
//have no prefixes
if (cmd_i == CMD_HD_EN_QPI_REG) return cmd_i;
//doesn't support 4-line commands
if(flags & SPI_TRANS_MODE_QIO && flags & SPI_TRANS_MODE_DIOQIO_ADDR &&
(cmd_i == CMD_HD_WR_END_REG || cmd_i == CMD_HD_INT0_REG ||
cmd_i == CMD_HD_INT1_REG || cmd_i == CMD_HD_INT2_REG)) {
//the transaction will be sent in corresponding 1/2/4 bit mode, without address and data.
//the CMD will have no 0xA- prefix
return cmd_i;
}
spi_line_mode_t line_mode = {
.cmd_lines = 1,
};
if (flags & SPI_TRANS_MODE_DIO) {
line_mode.data_lines = 2;
if (flags & SPI_TRANS_MODE_DIOQIO_ADDR) {
return cmd_i | CMD_HD_DIO_MODE;
line_mode.addr_lines = 2;
} else {
return cmd_i | CMD_HD_DOUT_MODE;
line_mode.addr_lines = 1;
}
} else if (flags & SPI_TRANS_MODE_QIO) {
line_mode.data_lines = 4;
if (flags & SPI_TRANS_MODE_DIOQIO_ADDR) {
return cmd_i | CMD_HD_QIO_MODE;
line_mode.addr_lines = 4;
} else {
return cmd_i | CMD_HD_QOUT_MODE;
line_mode.addr_lines = 1;
}
} else {
line_mode.data_lines = 1;
line_mode.addr_lines = 1;
}
return cmd_i | CMD_HD_ONEBIT_MODE;
return spi_ll_get_slave_hd_command(cmd_t, line_mode);
}
static int get_hd_dummy_bits(uint32_t flags)
{
//dummy is always 4 cycles when dual or quad mode is enabled. Otherwise 8 cycles in normal mode.
if (flags & (SPI_TRANS_MODE_DIO | SPI_TRANS_MODE_QIO)) {
return 4;
spi_line_mode_t line_mode = {};
if (flags & SPI_TRANS_MODE_DIO) {
line_mode.data_lines = 2;
} else if (flags & SPI_TRANS_MODE_QIO) {
line_mode.data_lines = 4;
} else {
return 8;
line_mode.data_lines = 1;
}
return spi_ll_get_slave_hd_dummy_bits(line_mode);
}
esp_err_t essl_spi_rdbuf(spi_device_handle_t spi, uint8_t *out_data, int addr, int len, uint32_t flags)
{
spi_transaction_ext_t t = {
.base = {
.cmd = get_hd_command(CMD_HD_RDBUF_REG, flags),
.cmd = get_hd_command(SPI_CMD_HD_RDBUF, flags),
.addr = addr % 72,
.rxlength = len * 8,
.rx_buffer = out_data,
@ -118,7 +123,7 @@ esp_err_t essl_spi_rdbuf_polling(spi_device_handle_t spi, uint8_t *out_data, int
{
spi_transaction_ext_t t = {
.base = {
.cmd = get_hd_command(CMD_HD_RDBUF_REG, flags),
.cmd = get_hd_command(SPI_CMD_HD_RDBUF, flags),
.addr = addr % 72,
.rxlength = len * 8,
.rx_buffer = out_data,
@ -134,7 +139,7 @@ esp_err_t essl_spi_wrbuf(spi_device_handle_t spi, const uint8_t *data, int addr,
{
spi_transaction_ext_t t = {
.base = {
.cmd = get_hd_command(CMD_HD_WRBUF_REG, flags),
.cmd = get_hd_command(SPI_CMD_HD_WRBUF, flags),
.addr = addr % 72,
.length = len * 8,
.tx_buffer = data,
@ -149,7 +154,7 @@ esp_err_t essl_spi_wrbuf_polling(spi_device_handle_t spi, const uint8_t *data, i
{
spi_transaction_ext_t t = {
.base = {
.cmd = get_hd_command(CMD_HD_WRBUF_REG, flags),
.cmd = get_hd_command(SPI_CMD_HD_WRBUF, flags),
.addr = addr % 72,
.length = len * 8,
.tx_buffer = data,
@ -164,7 +169,7 @@ esp_err_t essl_spi_rddma_seg(spi_device_handle_t spi, uint8_t *out_data, int seg
{
spi_transaction_ext_t t = {
.base = {
.cmd = get_hd_command(CMD_HD_RDDMA_REG, flags),
.cmd = get_hd_command(SPI_CMD_HD_RDDMA, flags),
.rxlength = seg_len * 8,
.rx_buffer = out_data,
.flags = flags | SPI_TRANS_VARIABLE_DUMMY,
@ -177,7 +182,7 @@ esp_err_t essl_spi_rddma_seg(spi_device_handle_t spi, uint8_t *out_data, int seg
esp_err_t essl_spi_rddma_done(spi_device_handle_t spi, uint32_t flags)
{
spi_transaction_t end_t = {
.cmd = get_hd_command(CMD_HD_INT0_REG, flags),
.cmd = get_hd_command(SPI_CMD_HD_INT0, flags),
.flags = flags,
};
return spi_device_transmit(spi, &end_t);
@ -208,7 +213,7 @@ esp_err_t essl_spi_wrdma_seg(spi_device_handle_t spi, const uint8_t *data, int s
{
spi_transaction_ext_t t = {
.base = {
.cmd = get_hd_command(CMD_HD_WRDMA_REG, flags),
.cmd = get_hd_command(SPI_CMD_HD_WRDMA, flags),
.length = seg_len * 8,
.tx_buffer = data,
.flags = flags | SPI_TRANS_VARIABLE_DUMMY,
@ -221,7 +226,7 @@ esp_err_t essl_spi_wrdma_seg(spi_device_handle_t spi, const uint8_t *data, int s
esp_err_t essl_spi_wrdma_done(spi_device_handle_t spi, uint32_t flags)
{
spi_transaction_t end_t = {
.cmd = get_hd_command(CMD_HD_WR_END_REG, flags),
.cmd = get_hd_command(SPI_CMD_HD_WR_END, flags),
.flags = flags,
};
return spi_device_transmit(spi, &end_t);
@ -250,7 +255,7 @@ esp_err_t essl_spi_wrdma(spi_device_handle_t spi, const uint8_t *data, int len,
esp_err_t essl_spi_int(spi_device_handle_t spi, int int_n, uint32_t flags)
{
spi_transaction_t end_t = {
.cmd = get_hd_command(CMD_HD_INT0_REG + int_n, flags),
.cmd = get_hd_command(SPI_CMD_HD_INT0 + int_n, flags),
.flags = flags,
};
return spi_device_transmit(spi, &end_t);

View File

@ -1,38 +0,0 @@
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
// NOTE: From the view of master
#define CMD_HD_WRBUF_REG 0x01
#define CMD_HD_RDBUF_REG 0x02
#define CMD_HD_WRDMA_REG 0x03
#define CMD_HD_RDDMA_REG 0x04
#define CMD_HD_ONEBIT_MODE 0x00
#define CMD_HD_DOUT_MODE 0x10
#define CMD_HD_QOUT_MODE 0x20
#define CMD_HD_DIO_MODE 0x50
#define CMD_HD_QIO_MODE 0xA0
#define CMD_HD_SEG_END_REG 0x05
#define CMD_HD_EN_QPI_REG 0x06
#define CMD_HD_WR_END_REG 0x07
#define CMD_HD_INT0_REG 0x08
#define CMD_HD_INT1_REG 0x09
#define CMD_HD_INT2_REG 0x0A
#define CMD_HD_EX_QPI_REG 0xDD
#define SPI_SLAVE_HD_BUFFER_SIZE 64

View File

@ -1,38 +0,0 @@
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
// NOTE: From the view of master
#define CMD_HD_WRBUF_REG 0x01
#define CMD_HD_RDBUF_REG 0x02
#define CMD_HD_WRDMA_REG 0x03
#define CMD_HD_RDDMA_REG 0x04
#define CMD_HD_ONEBIT_MODE 0x00
#define CMD_HD_DOUT_MODE 0x10
#define CMD_HD_QOUT_MODE 0x20
#define CMD_HD_DIO_MODE 0x50
#define CMD_HD_QIO_MODE 0xA0
#define CMD_HD_SEG_END_REG 0x05
#define CMD_HD_EN_QPI_REG 0x06
#define CMD_HD_WR_END_REG 0x07
#define CMD_HD_INT0_REG 0x08
#define CMD_HD_INT1_REG 0x09
#define CMD_HD_INT2_REG 0x0A
#define CMD_HD_EX_QPI_REG 0xDD
#define SPI_SLAVE_HD_BUFFER_SIZE 72

View File

@ -1,38 +0,0 @@
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
// NOTE: From the view of master
#define CMD_HD_WRBUF_REG 0x01
#define CMD_HD_RDBUF_REG 0x02
#define CMD_HD_WRDMA_REG 0x03
#define CMD_HD_RDDMA_REG 0x04
#define CMD_HD_ONEBIT_MODE 0x00
#define CMD_HD_DOUT_MODE 0x10
#define CMD_HD_QOUT_MODE 0x20
#define CMD_HD_DIO_MODE 0x50
#define CMD_HD_QIO_MODE 0xA0
#define CMD_HD_SEG_END_REG 0x05
#define CMD_HD_EN_QPI_REG 0x06
#define CMD_HD_WR_END_REG 0x07
#define CMD_HD_INT0_REG 0x08
#define CMD_HD_INT1_REG 0x09
#define CMD_HD_INT2_REG 0x0A
#define CMD_HD_EX_QPI_REG 0xDD
#define SPI_SLAVE_HD_BUFFER_SIZE 64

View File

@ -30,6 +30,7 @@
#include <esp_types.h>
#include "hal/hal_defs.h"
#include <stdlib.h> //for abs()
#include "hal/spi_types.h"
#ifdef __cplusplus
extern "C" {
@ -1069,6 +1070,29 @@ static inline void spi_dma_ll_enable_out_auto_wrback(spi_dma_dev_t *dma_out, uin
//does not configure it in ESP32
}
/**
* Get the spi communication command
*
* @param cmd_t Base command value
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline uint16_t spi_ll_get_slave_hd_command(spi_command_t cmd_t, spi_line_mode_t line_mode)
{
//This is not supported in esp32
return 0;
}
/**
* Get the dummy bits
*
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline int spi_ll_get_slave_hd_dummy_bits(spi_line_mode_t line_mode)
{
//This is not supported in esp32
return 0;
}
#undef SPI_LL_RST_MASK
#undef SPI_LL_UNUSED_INT_MASK

View File

@ -22,6 +22,7 @@
#include "soc/spi_struct.h"
#include "esp32c3/rom/lldesc.h"
#include "esp_attr.h"
#include "hal/spi_types.h"
#ifdef __cplusplus
extern "C" {
@ -76,6 +77,21 @@ typedef enum {
} spi_ll_trans_len_cond_t;
FLAG_ATTR(spi_ll_trans_len_cond_t)
// SPI base command in esp32c3
typedef enum {
/* Slave HD Only */
SPI_LL_BASE_CMD_HD_WRBUF = 0x01,
SPI_LL_BASE_CMD_HD_RDBUF = 0x02,
SPI_LL_BASE_CMD_HD_WRDMA = 0x03,
SPI_LL_BASE_CMD_HD_RDDMA = 0x04,
SPI_LL_BASE_CMD_HD_SEG_END = 0x05,
SPI_LL_BASE_CMD_HD_EN_QPI = 0x06,
SPI_LL_BASE_CMD_HD_WR_END = 0x07,
SPI_LL_BASE_CMD_HD_INT0 = 0x08,
SPI_LL_BASE_CMD_HD_INT1 = 0x09,
SPI_LL_BASE_CMD_HD_INT2 = 0x0A,
} spi_ll_base_command_t;
/*------------------------------------------------------------------------------
* Control
*----------------------------------------------------------------------------*/
@ -1079,6 +1095,93 @@ static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t* hw)
#undef SPI_LL_RST_MASK
#undef SPI_LL_UNUSED_INT_MASK
/**
* Get the base spi command in esp32c3
*
* @param cmd_t Command value
*/
static inline uint8_t spi_ll_get_slave_hd_base_command(spi_command_t cmd_t)
{
uint8_t cmd_base = 0x00;
switch (cmd_t)
{
case SPI_CMD_HD_WRBUF:
cmd_base = SPI_LL_BASE_CMD_HD_WRBUF;
break;
case SPI_CMD_HD_RDBUF:
cmd_base = SPI_LL_BASE_CMD_HD_RDBUF;
break;
case SPI_CMD_HD_WRDMA:
cmd_base = SPI_LL_BASE_CMD_HD_WRDMA;
break;
case SPI_CMD_HD_RDDMA:
cmd_base = SPI_LL_BASE_CMD_HD_RDDMA;
break;
case SPI_CMD_HD_SEG_END:
cmd_base = SPI_LL_BASE_CMD_HD_SEG_END;
break;
case SPI_CMD_HD_EN_QPI:
cmd_base = SPI_LL_BASE_CMD_HD_EN_QPI;
break;
case SPI_CMD_HD_WR_END:
cmd_base = SPI_LL_BASE_CMD_HD_WR_END;
break;
case SPI_CMD_HD_INT0:
cmd_base = SPI_LL_BASE_CMD_HD_INT0;
break;
case SPI_CMD_HD_INT1:
cmd_base = SPI_LL_BASE_CMD_HD_INT1;
break;
case SPI_CMD_HD_INT2:
cmd_base = SPI_LL_BASE_CMD_HD_INT2;
break;
default:
abort();
}
return cmd_base;
}
/**
* Get the spi communication command
*
* @param cmd_t Base command value
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline uint16_t spi_ll_get_slave_hd_command(spi_command_t cmd_t, spi_line_mode_t line_mode)
{
uint8_t cmd_base = spi_ll_get_slave_hd_base_command(cmd_t);
uint8_t cmd_mod = 0x00; //CMD:1-bit, ADDR:1-bit, DATA:1-bit
if (line_mode.data_lines == 2) {
if (line_mode.addr_lines == 2) {
cmd_mod = 0x50; //CMD:1-bit, ADDR:2-bit, DATA:2-bit
} else {
cmd_mod = 0x10; //CMD:1-bit, ADDR:1-bit, DATA:2-bit
}
} else if (line_mode.data_lines == 4) {
if (line_mode.addr_lines == 4) {
cmd_mod = 0xA0; //CMD:1-bit, ADDR:4-bit, DATA:4-bit
} else {
cmd_mod = 0x20; //CMD:1-bit, ADDR:1-bit, DATA:4-bit
}
}
if (cmd_base == SPI_LL_BASE_CMD_HD_SEG_END || cmd_base == SPI_LL_BASE_CMD_HD_EN_QPI) {
cmd_mod = 0x00;
}
return cmd_base | cmd_mod;
}
/**
* Get the dummy bits
*
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline int spi_ll_get_slave_hd_dummy_bits(spi_line_mode_t line_mode)
{
return 8;
}
#ifdef __cplusplus
}
#endif

View File

@ -30,6 +30,7 @@
#include "soc/spi_struct.h"
#include "esp32s2/rom/lldesc.h"
#include "esp_attr.h"
#include "hal/spi_types.h"
#ifdef __cplusplus
extern "C" {
@ -93,6 +94,21 @@ typedef enum {
} spi_ll_trans_len_cond_t;
FLAG_ATTR(spi_ll_trans_len_cond_t)
// SPI base command in esp32s2
typedef enum {
/* Slave HD Only */
SPI_LL_BASE_CMD_HD_WRBUF = 0x01,
SPI_LL_BASE_CMD_HD_RDBUF = 0x02,
SPI_LL_BASE_CMD_HD_WRDMA = 0x03,
SPI_LL_BASE_CMD_HD_RDDMA = 0x04,
SPI_LL_BASE_CMD_HD_SEG_END = 0x05,
SPI_LL_BASE_CMD_HD_EN_QPI = 0x06,
SPI_LL_BASE_CMD_HD_WR_END = 0x07,
SPI_LL_BASE_CMD_HD_INT0 = 0x08,
SPI_LL_BASE_CMD_HD_INT1 = 0x09,
SPI_LL_BASE_CMD_HD_INT2 = 0x0A,
} spi_ll_base_command_t;
/*------------------------------------------------------------------------------
* Control
*----------------------------------------------------------------------------*/
@ -1262,6 +1278,103 @@ static inline bool spi_ll_tx_get_empty_err(spi_dev_t *hw)
#undef SPI_LL_RST_MASK
#undef SPI_LL_UNUSED_INT_MASK
/**
* Get the base spi command in esp32s2
*
* @param cmd_t Command value
*/
static inline uint8_t spi_ll_get_slave_hd_base_command(spi_command_t cmd_t)
{
uint8_t cmd_base = 0x00;
switch (cmd_t)
{
case SPI_CMD_HD_WRBUF:
cmd_base = SPI_LL_BASE_CMD_HD_WRBUF;
break;
case SPI_CMD_HD_RDBUF:
cmd_base = SPI_LL_BASE_CMD_HD_RDBUF;
break;
case SPI_CMD_HD_WRDMA:
cmd_base = SPI_LL_BASE_CMD_HD_WRDMA;
break;
case SPI_CMD_HD_RDDMA:
cmd_base = SPI_LL_BASE_CMD_HD_RDDMA;
break;
case SPI_CMD_HD_SEG_END:
cmd_base = SPI_LL_BASE_CMD_HD_SEG_END;
break;
case SPI_CMD_HD_EN_QPI:
cmd_base = SPI_LL_BASE_CMD_HD_EN_QPI;
break;
case SPI_CMD_HD_WR_END:
cmd_base = SPI_LL_BASE_CMD_HD_WR_END;
break;
case SPI_CMD_HD_INT0:
cmd_base = SPI_LL_BASE_CMD_HD_INT0;
break;
case SPI_CMD_HD_INT1:
cmd_base = SPI_LL_BASE_CMD_HD_INT1;
break;
case SPI_CMD_HD_INT2:
cmd_base = SPI_LL_BASE_CMD_HD_INT2;
break;
default:
abort();
}
return cmd_base;
}
/**
* Get the spi communication command
*
* @param cmd_t Base command value
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline uint16_t spi_ll_get_slave_hd_command(spi_command_t cmd_t, spi_line_mode_t line_mode)
{
uint8_t cmd_base = spi_ll_get_slave_hd_base_command(cmd_t);
uint8_t cmd_mod = 0x00; //CMD:1-bit, ADDR:1-bit, DATA:1-bit
if (line_mode.data_lines == 2) {
if (line_mode.addr_lines == 2) {
cmd_mod = 0x50; //CMD:1-bit, ADDR:2-bit, DATA:2-bit
} else {
cmd_mod = 0x10; //CMD:1-bit, ADDR:1-bit, DATA:2-bit
}
} else if (line_mode.data_lines == 4) {
if (line_mode.addr_lines == 4) {
cmd_mod = 0xA0; //CMD:1-bit, ADDR:4-bit, DATA:4-bit
} else {
cmd_mod = 0x20; //CMD:1-bit, ADDR:1-bit, DATA:4-bit
}
}
if (cmd_base == SPI_LL_BASE_CMD_HD_SEG_END || cmd_base == SPI_LL_BASE_CMD_HD_EN_QPI) {
cmd_mod = 0x00;
}
return cmd_base | cmd_mod;
}
/**
* Get the dummy bits
*
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline int spi_ll_get_slave_hd_dummy_bits(spi_line_mode_t line_mode)
{
uint8_t dummy_bits = 0;
if (line_mode.data_lines == 2) {
dummy_bits = 4;
} else if (line_mode.data_lines == 4) {
dummy_bits = 4;
} else {
dummy_bits = 8;
}
return dummy_bits;
}
#ifdef __cplusplus
}
#endif

View File

@ -21,6 +21,7 @@
#include "soc/spi_periph.h"
#include "esp32s3/rom/lldesc.h"
#include "esp_attr.h"
#include "hal/spi_types.h"
#ifdef __cplusplus
extern "C" {
@ -75,6 +76,21 @@ typedef enum {
} spi_ll_trans_len_cond_t;
FLAG_ATTR(spi_ll_trans_len_cond_t)
// SPI base command in esp32s3
typedef enum {
/* Slave HD Only */
SPI_LL_BASE_CMD_HD_WRBUF = 0x01,
SPI_LL_BASE_CMD_HD_RDBUF = 0x02,
SPI_LL_BASE_CMD_HD_WRDMA = 0x03,
SPI_LL_BASE_CMD_HD_RDDMA = 0x04,
SPI_LL_BASE_CMD_HD_SEG_END = 0x05,
SPI_LL_BASE_CMD_HD_EN_QPI = 0x06,
SPI_LL_BASE_CMD_HD_WR_END = 0x07,
SPI_LL_BASE_CMD_HD_INT0 = 0x08,
SPI_LL_BASE_CMD_HD_INT1 = 0x09,
SPI_LL_BASE_CMD_HD_INT2 = 0x0A,
} spi_ll_base_command_t;
/*------------------------------------------------------------------------------
* Control
*----------------------------------------------------------------------------*/
@ -1087,6 +1103,93 @@ static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t* hw)
#undef SPI_LL_RST_MASK
#undef SPI_LL_UNUSED_INT_MASK
/**
* Get the base spi command in esp32s3
*
* @param cmd_t Command value
*/
static inline uint8_t spi_ll_get_slave_hd_base_command(spi_command_t cmd_t)
{
uint8_t cmd_base = 0x00;
switch (cmd_t)
{
case SPI_CMD_HD_WRBUF:
cmd_base = SPI_LL_BASE_CMD_HD_WRBUF;
break;
case SPI_CMD_HD_RDBUF:
cmd_base = SPI_LL_BASE_CMD_HD_RDBUF;
break;
case SPI_CMD_HD_WRDMA:
cmd_base = SPI_LL_BASE_CMD_HD_WRDMA;
break;
case SPI_CMD_HD_RDDMA:
cmd_base = SPI_LL_BASE_CMD_HD_RDDMA;
break;
case SPI_CMD_HD_SEG_END:
cmd_base = SPI_LL_BASE_CMD_HD_SEG_END;
break;
case SPI_CMD_HD_EN_QPI:
cmd_base = SPI_LL_BASE_CMD_HD_EN_QPI;
break;
case SPI_CMD_HD_WR_END:
cmd_base = SPI_LL_BASE_CMD_HD_WR_END;
break;
case SPI_CMD_HD_INT0:
cmd_base = SPI_LL_BASE_CMD_HD_INT0;
break;
case SPI_CMD_HD_INT1:
cmd_base = SPI_LL_BASE_CMD_HD_INT1;
break;
case SPI_CMD_HD_INT2:
cmd_base = SPI_LL_BASE_CMD_HD_INT2;
break;
default:
abort();
}
return cmd_base;
}
/**
* Get the spi communication command
*
* @param cmd_t Base command value
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline uint16_t spi_ll_get_slave_hd_command(spi_command_t cmd_t, spi_line_mode_t line_mode)
{
uint8_t cmd_base = spi_ll_get_slave_hd_base_command(cmd_t);
uint8_t cmd_mod = 0x00; //CMD:1-bit, ADDR:1-bit, DATA:1-bit
if (line_mode.data_lines == 2) {
if (line_mode.addr_lines == 2) {
cmd_mod = 0x50; //CMD:1-bit, ADDR:2-bit, DATA:2-bit
} else {
cmd_mod = 0x10; //CMD:1-bit, ADDR:1-bit, DATA:2-bit
}
} else if (line_mode.data_lines == 4) {
if (line_mode.addr_lines == 4) {
cmd_mod = 0xA0; //CMD:1-bit, ADDR:4-bit, DATA:4-bit
} else {
cmd_mod = 0x20; //CMD:1-bit, ADDR:1-bit, DATA:4-bit
}
}
if (cmd_base == SPI_LL_BASE_CMD_HD_SEG_END || cmd_base == SPI_LL_BASE_CMD_HD_EN_QPI) {
cmd_mod = 0x00;
}
return cmd_base | cmd_mod;
}
/**
* Get the dummy bits
*
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline int spi_ll_get_slave_hd_dummy_bits(spi_line_mode_t line_mode)
{
return 8;
}
#ifdef __cplusplus
}
#endif

View File

@ -46,6 +46,32 @@ typedef enum {
FLAG_ATTR(spi_event_t)
/**
* @brief Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
typedef struct {
uint8_t cmd_lines; ///< The line width of command phase, e.g. 2-line-cmd-phase.
uint8_t addr_lines; ///< The line width of address phase, e.g. 1-line-addr-phase.
uint8_t data_lines; ///< The line width of data phase, e.g. 4-line-data-phase.
} spi_line_mode_t;
/**
* @brief SPI command.
*/
typedef enum {
/* Slave HD Only */
SPI_CMD_HD_WRBUF = BIT(0),
SPI_CMD_HD_RDBUF = BIT(1),
SPI_CMD_HD_WRDMA = BIT(2),
SPI_CMD_HD_RDDMA = BIT(3),
SPI_CMD_HD_SEG_END = BIT(4),
SPI_CMD_HD_EN_QPI = BIT(5),
SPI_CMD_HD_WR_END = BIT(6),
SPI_CMD_HD_INT0 = BIT(7),
SPI_CMD_HD_INT1 = BIT(8),
SPI_CMD_HD_INT2 = BIT(9),
} spi_command_t;
/** @cond */ //Doxy command to hide preprocessor definitions from docs */
//alias for different chips, deprecated for the chips after esp32s2