1035 lines
25 KiB
C
1035 lines
25 KiB
C
|
/*
|
||
|
* Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions
|
||
|
* are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the
|
||
|
* distribution.
|
||
|
* 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
|
||
|
* its contributors may be used to endorse or promote products derived
|
||
|
* from this software without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*/
|
||
|
#include "string.h"
|
||
|
#include "cmd_util.h"
|
||
|
#include "cmd_spi.h"
|
||
|
#include "driver/chip/hal_gpio.h"
|
||
|
#include "driver/chip/hal_spi.h"
|
||
|
#include "common/board/board.h"
|
||
|
|
||
|
#if (CONFIG_CHIP_ARCH_VER == 2)
|
||
|
#define CMD_SPI_PORT SPI1
|
||
|
#elif (CONFIG_CHIP_ARCH_VER == 3)
|
||
|
#define CMD_SPI_PORT SPI0
|
||
|
#endif
|
||
|
|
||
|
#define CMD_SPI_DO_OPEN_CLOSE 0
|
||
|
#define CMD_SPI_SLAVE_DELAY_STOP 0
|
||
|
|
||
|
#define CMD_SPI_FIRST_BIT SPI_TCTRL_FBS_MSB
|
||
|
#define CMD_SPI_SCLK_MODE SPI_SCLK_Mode0
|
||
|
//#define CMD_SPI_SCLK (48 * 1000 * 1000)
|
||
|
//#define CMD_SPI_TEST_TRANSFER_DATA_LEN 48
|
||
|
uint32_t testlen;// master and slave must same
|
||
|
|
||
|
#define CMD_SPI_MASTER_BUF_SIZE (1 * 1024)
|
||
|
|
||
|
/*
|
||
|
* spi config
|
||
|
*/
|
||
|
static enum cmd_status cmd_spi_config_exec(char *cmd)
|
||
|
{
|
||
|
int ret;
|
||
|
static const SPI_Global_Config board_spi_param = {
|
||
|
.mclk = BOARD_SPI_MCLK,
|
||
|
.cs_level = BOARD_SPI_CS_LEVEL
|
||
|
};
|
||
|
|
||
|
ret = HAL_SPI_Init(CMD_SPI_PORT, &board_spi_param);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Init failed\n");
|
||
|
return CMD_STATUS_FAIL;
|
||
|
}
|
||
|
|
||
|
return CMD_STATUS_OK;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* spi deconfig
|
||
|
*/
|
||
|
static enum cmd_status cmd_spi_deconfig_exec(char *cmd)
|
||
|
{
|
||
|
HAL_SPI_Deinit(CMD_SPI_PORT);
|
||
|
|
||
|
return CMD_STATUS_OK;
|
||
|
}
|
||
|
|
||
|
/*spi start m=<mode> l=<line> s=<speed>*/
|
||
|
static enum cmd_status cmd_spi_start_exec(char *cmd)
|
||
|
{
|
||
|
int ret;
|
||
|
int cnt;
|
||
|
uint32_t mode, line, speed;
|
||
|
SPI_Config config;
|
||
|
uint8_t dataBuf[16];
|
||
|
|
||
|
cnt = cmd_sscanf(cmd, "m=%u l=%u s=%u", &mode, &line, &speed);
|
||
|
if (cnt != 3) {
|
||
|
CMD_ERR("invalid cnt %u\n", cnt);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (mode < 0 || mode > 3) {
|
||
|
CMD_ERR("invalid line %u\n", mode);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (line < 1 || line > 2) {
|
||
|
CMD_ERR("invalid line %u\n", line);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (speed < 1 || speed > 48) {
|
||
|
CMD_ERR("invalid speed %u\n", speed);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
cmd_memset(&config, 0, sizeof(config));
|
||
|
config.firstBit = SPI_TCTRL_FBS_MSB;
|
||
|
config.mode = SPI_CTRL_MODE_MASTER;
|
||
|
config.opMode = SPI_OPERATION_MODE_DMA;
|
||
|
config.sclk = speed * 1000 * 1000;
|
||
|
config.sclkMode = mode;
|
||
|
|
||
|
ret = HAL_SPI_Open(CMD_SPI_PORT, SPI_TCTRL_SS_SEL_SS0, &config, 10);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Open failed\n");
|
||
|
return CMD_STATUS_FAIL;
|
||
|
}
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 1);
|
||
|
cmd_memcpy(dataBuf, "SPI Test Data", sizeof("SPI Test Data"));
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)dataBuf, 16);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Open failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
if (line == 2)
|
||
|
HAL_SPI_Config(CMD_SPI_PORT, SPI_ATTRIBUTION_IO_MODE, SPI_IO_MODE_DUAL_RX);
|
||
|
else
|
||
|
HAL_SPI_Config(CMD_SPI_PORT, SPI_ATTRIBUTION_IO_MODE, SPI_IO_MODE_NORMAL);
|
||
|
|
||
|
HAL_SPI_Receive(CMD_SPI_PORT, dataBuf, 16);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Receive failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 0);
|
||
|
cmd_print_uint8_array(dataBuf, 16);
|
||
|
|
||
|
close:
|
||
|
HAL_SPI_Close(CMD_SPI_PORT);
|
||
|
return (ret == 0) ? CMD_STATUS_OK : ret;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
static uint8_t *cmd_spi_master_buf = (uint8_t *)0x7E000;
|
||
|
#else
|
||
|
static uint8_t cmd_spi_master_buf[CMD_SPI_MASTER_BUF_SIZE];
|
||
|
#endif
|
||
|
|
||
|
void cmd_spi_init_data(uint8_t *buf, int32_t len)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < len; ++i) {
|
||
|
buf[i] = ((i + 1) & 0xff);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int cmd_spi_verify_data(uint8_t *buf, int32_t len)
|
||
|
{
|
||
|
int i;
|
||
|
#if 0
|
||
|
uint8_t *ptr = buf;
|
||
|
|
||
|
for (i = 0; i < len; ++i) {
|
||
|
if ((i % 16) == 0) {
|
||
|
printf("\n");
|
||
|
}
|
||
|
printf(" %02X", *ptr++);
|
||
|
}
|
||
|
printf("\n");
|
||
|
#endif
|
||
|
for (i = 0; i < len; ++i) {
|
||
|
if (buf[i] != ((i + 1) & 0xff)) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (i >= len) {
|
||
|
CMD_DBG("data correct\n");
|
||
|
return 1;
|
||
|
} else {
|
||
|
CMD_DBG("data wrong, i %d\n", i);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
__nonxip_text
|
||
|
static void cmd_master_irq_cb(uint32_t irq, void *arg)
|
||
|
{
|
||
|
//CMD_DBG("master spi irq %#x\n", irq);
|
||
|
|
||
|
//OS_SemaphoreRelease(&cmd_slave_sem);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
static enum cmd_status cmd_spi_master_init_exec(char *cmd)
|
||
|
{
|
||
|
SPI_Device param;
|
||
|
uint32_t speed;
|
||
|
uint8_t cnt;
|
||
|
uint32_t test_len;
|
||
|
cnt = cmd_sscanf(cmd, "s=%u l=%u", &speed, &test_len);
|
||
|
if (cnt != 2) {
|
||
|
CMD_ERR("invalid cnt %u\n", cnt);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (speed < 1 || speed > 48) {
|
||
|
CMD_ERR("invalid speed %u\n", speed);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (test_len < 1 || test_len > 1024) {
|
||
|
CMD_ERR("invalid speed %u\n", test_len);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
cmd_memset(¶m, 0, sizeof(SPI_Device));
|
||
|
param.port = CMD_SPI_PORT;
|
||
|
param.cs = SPI_TCTRL_SS_SEL_SS0;
|
||
|
param.config.mode = SPI_CTRL_MODE_MASTER;
|
||
|
param.config.opMode = SPI_OPERATION_MODE_DMA;
|
||
|
param.config.firstBit = CMD_SPI_FIRST_BIT;
|
||
|
param.config.sclk = speed * 1000 * 1000;
|
||
|
param.config.sclkMode = CMD_SPI_SCLK_MODE;
|
||
|
|
||
|
testlen = test_len;
|
||
|
CMD_DBG("sclk %d, test len %d\n", param.config.sclk, testlen);
|
||
|
if (HAL_SPI_Open(param.port, param.cs, ¶m.config, 5000) == HAL_OK) {
|
||
|
#if 0
|
||
|
SPI_IrqParam irq_param;
|
||
|
irq_param.irqMask = SPI_INT_TRANSFER_COMPLETE; /* or SPI_INT_TRANSFER_COMPLETE */
|
||
|
irq_param.callback = cmd_master_irq_cb;
|
||
|
irq_param.arg = NULL;
|
||
|
HAL_SPI_Slave_EnableIRQ(param.spi_port, &irq_param);
|
||
|
#endif
|
||
|
return CMD_STATUS_OK;
|
||
|
} else {
|
||
|
return CMD_STATUS_FAIL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_master_deinit_exec(char *cmd)
|
||
|
{
|
||
|
HAL_SPI_Close(CMD_SPI_PORT);
|
||
|
return CMD_STATUS_OK;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_master_send_exec(char *cmd)
|
||
|
{
|
||
|
uint8_t *buf = cmd_spi_master_buf;
|
||
|
int32_t len = testlen;
|
||
|
enum cmd_status ret = CMD_STATUS_OK;
|
||
|
|
||
|
cmd_spi_init_data(buf, len);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_master_init_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 1);
|
||
|
if (HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)buf, len) != HAL_OK) {
|
||
|
ret = CMD_STATUS_FAIL;
|
||
|
}
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 0);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_master_deinit_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_master_send_continue_exec(char *cmd)
|
||
|
{
|
||
|
uint8_t *buf = cmd_spi_master_buf;
|
||
|
int32_t len = testlen;
|
||
|
enum cmd_status ret = CMD_STATUS_OK;
|
||
|
|
||
|
cmd_spi_init_data(buf, len);
|
||
|
while (1) {
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_master_init_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 1);
|
||
|
if (HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)buf, len) != HAL_OK) {
|
||
|
ret = CMD_STATUS_FAIL;
|
||
|
}
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 0);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_master_deinit_exec(NULL);
|
||
|
#endif
|
||
|
OS_MSleep(1); /* wait slave recv first exec */
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_master_recv_exec(char *cmd)
|
||
|
{
|
||
|
uint8_t *buf = cmd_spi_master_buf;
|
||
|
int32_t len = testlen;
|
||
|
enum cmd_status ret = CMD_STATUS_OK;
|
||
|
|
||
|
cmd_memset(buf, 0, len);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_master_init_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 1);
|
||
|
if (HAL_SPI_Receive(CMD_SPI_PORT, (uint8_t *)buf, len) != HAL_OK) {
|
||
|
ret = CMD_STATUS_FAIL;
|
||
|
}
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 0);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_master_deinit_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
cmd_spi_verify_data(buf, len);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_master_recv_continue_exec(char *cmd)
|
||
|
{
|
||
|
uint8_t *buf = cmd_spi_master_buf;
|
||
|
int32_t len = testlen;
|
||
|
enum cmd_status ret = CMD_STATUS_OK;
|
||
|
|
||
|
uint32_t test_timeout = 1000 * 120;
|
||
|
uint32_t timeout = OS_GetTicks() + OS_TicksToMSecs(test_timeout);
|
||
|
uint32_t correct = 0;
|
||
|
uint32_t wrong = 0;
|
||
|
uint32_t sum = 0;
|
||
|
|
||
|
while (OS_TimeBeforeEqual(OS_GetTicks(), timeout)) {
|
||
|
cmd_memset(buf, 0, len);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_master_init_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 1);
|
||
|
if (HAL_SPI_Receive(CMD_SPI_PORT, (uint8_t *)buf, len) != HAL_OK) {
|
||
|
ret = CMD_STATUS_FAIL;
|
||
|
break;
|
||
|
}
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 0);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_master_deinit_exec(NULL);
|
||
|
#endif
|
||
|
sum += 1;
|
||
|
|
||
|
int i;
|
||
|
for (i = 0; i < len; ++i) {
|
||
|
if (buf[i] != ((i + 1) & 0xff)) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (i >= len) {
|
||
|
correct += 1;
|
||
|
} else {
|
||
|
wrong += 1;
|
||
|
}
|
||
|
}
|
||
|
CMD_DBG("master rx sum %u, correct %u, wrong %u, speed %u(KB/s)\n",
|
||
|
sum, correct, wrong, (sum * testlen)/((test_timeout / 1000) * 1000));
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* after cmd_spi_slave_stable_test_exec exec*/
|
||
|
static enum cmd_status cmd_spi_master_stable_test_exec(char *cmd)
|
||
|
{
|
||
|
while (1) {
|
||
|
cmd_spi_master_recv_exec(NULL);
|
||
|
OS_MSleep(500);
|
||
|
cmd_spi_master_send_exec(NULL);
|
||
|
OS_MSleep(500);
|
||
|
}
|
||
|
return CMD_STATUS_OK;
|
||
|
}
|
||
|
|
||
|
static const struct cmd_data g_spi_master_cmds[] = {
|
||
|
{ "init", cmd_spi_master_init_exec },
|
||
|
{ "deinit", cmd_spi_master_deinit_exec },
|
||
|
{ "send", cmd_spi_master_send_exec },
|
||
|
{ "recv", cmd_spi_master_recv_exec },
|
||
|
{ "send_continue", cmd_spi_master_send_continue_exec },
|
||
|
{ "recv_continue", cmd_spi_master_recv_continue_exec },
|
||
|
{ "stable_test", cmd_spi_master_stable_test_exec },
|
||
|
};
|
||
|
|
||
|
static enum cmd_status cmd_spi_master_exec(char *cmd)
|
||
|
{
|
||
|
return cmd_exec(cmd, g_spi_master_cmds, cmd_nitems(g_spi_master_cmds));
|
||
|
}
|
||
|
|
||
|
typedef enum {
|
||
|
SPI_SLAVE_INIT,
|
||
|
SPI_SLAVE_STATUS_TX,
|
||
|
SPI_SLAVE_STATUS_RX,
|
||
|
SPI_SLAVE_DEINIT,
|
||
|
} SPI_Slave_Status;
|
||
|
|
||
|
SPI_Slave_Status slave_status = SPI_SLAVE_DEINIT;
|
||
|
OS_Semaphore_t cmd_slave_sem;
|
||
|
|
||
|
__nonxip_text
|
||
|
static void cmd_slave_dma_half_cb(void *arg)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
__nonxip_text
|
||
|
static void cmd_slave_dma_end_cb(void *arg)
|
||
|
{
|
||
|
//OS_SemaphoreRelease(&cmd_slave_sem);
|
||
|
//CMD_DBG("dam end\n");
|
||
|
}
|
||
|
|
||
|
__nonxip_text
|
||
|
static void cmd_slave_irq_cb(uint32_t irq, void *arg)
|
||
|
{
|
||
|
//CMD_DBG("slave spi irq %#x\n", irq);
|
||
|
/*if spi slave init first, spi slave cs level is high defult,but master cs connect slave and low,
|
||
|
*spi slave cs change to low too. then master init, master cs set high defaut and then slave cs low
|
||
|
*change to high and the deselect irq is triggered.
|
||
|
*/
|
||
|
if ((slave_status == SPI_SLAVE_STATUS_TX) | (slave_status == SPI_SLAVE_STATUS_RX))
|
||
|
OS_SemaphoreRelease(&cmd_slave_sem);
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_slave_init_exec(char *cmd)
|
||
|
{
|
||
|
SPI_Device param;
|
||
|
uint8_t cnt;
|
||
|
uint32_t test_len;
|
||
|
|
||
|
cnt = cmd_sscanf(cmd, "l=%u", &test_len);
|
||
|
if (cnt != 1) {
|
||
|
CMD_ERR("invalid cnt %u\n", cnt);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (test_len < 1 || test_len > 1024) {
|
||
|
CMD_ERR("invalid speed %u\n", test_len);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (OS_SemaphoreCreateBinary(&cmd_slave_sem) != OS_OK) {
|
||
|
CMD_ERR("create sem fail\n");
|
||
|
}
|
||
|
|
||
|
cmd_memset(¶m, 0, sizeof(SPI_Device));
|
||
|
param.port = CMD_SPI_PORT;
|
||
|
param.cs = SPI_TCTRL_SS_SEL_SS0;
|
||
|
param.config.mode = SPI_CTRL_MODE_SLAVE;
|
||
|
param.config.opMode = SPI_OPERATION_MODE_DMA;
|
||
|
param.config.firstBit = CMD_SPI_FIRST_BIT;
|
||
|
//param.config.sclk = CMD_SPI_SCLK; //no need to set
|
||
|
param.config.sclkMode = CMD_SPI_SCLK_MODE;
|
||
|
|
||
|
testlen = test_len;
|
||
|
CMD_DBG("test len %d\n", testlen);
|
||
|
|
||
|
/* init spi */
|
||
|
if (HAL_SPI_Slave_Open(param.port, param.cs, ¶m.config, 5000) != HAL_OK) {
|
||
|
CMD_ERR("HAL_SPI_Slave_Open() fail\n");
|
||
|
}
|
||
|
|
||
|
DMA_ChannelInitParam dma_param;
|
||
|
cmd_memset(&dma_param, 0, sizeof(dma_param));
|
||
|
dma_param.irqType = DMA_IRQ_TYPE_BOTH;
|
||
|
dma_param.endCallback = cmd_slave_dma_end_cb;
|
||
|
dma_param.endArg = NULL;
|
||
|
dma_param.halfCallback = cmd_slave_dma_half_cb;
|
||
|
dma_param.halfArg = NULL;
|
||
|
|
||
|
if (HAL_SPI_Slave_InitTxDMA(param.port, &dma_param) != HAL_OK) {
|
||
|
CMD_ERR("HAL_SPI_Slave_InitTxDMA() fail\n");
|
||
|
}
|
||
|
|
||
|
if (HAL_SPI_Slave_InitRxDMA(param.port, &dma_param) != HAL_OK) {
|
||
|
CMD_ERR("HAL_SPI_Slave_InitRxDMA() fail\n");
|
||
|
}
|
||
|
|
||
|
#if 1
|
||
|
SPI_IrqParam irq_param;
|
||
|
irq_param.irqMask = SPI_INT_CS_DESELECT; /* or SPI_INT_TRANSFER_COMPLETE/SPI_INT_CS_DESELECT */
|
||
|
irq_param.callback = cmd_slave_irq_cb;
|
||
|
irq_param.arg = NULL;
|
||
|
HAL_SPI_Slave_EnableIRQ(param.port, &irq_param);
|
||
|
#endif
|
||
|
slave_status = SPI_SLAVE_INIT;
|
||
|
|
||
|
return CMD_STATUS_OK;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_slave_deinit_exec(char *cmd)
|
||
|
{
|
||
|
HAL_SPI_Slave_DisableIRQ(CMD_SPI_PORT);
|
||
|
HAL_SPI_Slave_DeInitRxDMA(CMD_SPI_PORT);
|
||
|
HAL_SPI_Slave_DeInitTxDMA(CMD_SPI_PORT);
|
||
|
HAL_SPI_Slave_Close(CMD_SPI_PORT);
|
||
|
slave_status = SPI_SLAVE_DEINIT;
|
||
|
OS_SemaphoreDelete(&cmd_slave_sem);
|
||
|
return CMD_STATUS_OK;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_slave_send_exec(char *cmd)
|
||
|
{
|
||
|
uint8_t *buf = cmd_spi_master_buf;
|
||
|
int32_t len = testlen;
|
||
|
enum cmd_status ret = CMD_STATUS_OK;
|
||
|
|
||
|
cmd_spi_init_data(buf, len);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_slave_init_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
if (HAL_SPI_Slave_StartTransmit_DMA(CMD_SPI_PORT, buf, len) != HAL_OK) {
|
||
|
CMD_ERR("HAL_SPI_Slave_StartTransmit_DMA() fail\n");
|
||
|
}
|
||
|
|
||
|
slave_status = SPI_SLAVE_STATUS_TX;
|
||
|
if (OS_SemaphoreWait(&cmd_slave_sem, 10000) != OS_OK) {
|
||
|
CMD_ERR("%s(), wait timeout\n", __func__);
|
||
|
}
|
||
|
|
||
|
#if CMD_SPI_SLAVE_DELAY_STOP
|
||
|
cmd_msleep(CMD_SPI_SLAVE_DELAY_STOP);
|
||
|
#endif
|
||
|
|
||
|
int32_t left = HAL_SPI_Slave_StopTransmit_DMA(CMD_SPI_PORT);
|
||
|
if (left != 0) {
|
||
|
CMD_ERR("HAL_SPI_Slave_StopTransmit_DMA(), left %d\n", left);
|
||
|
ret = CMD_STATUS_FAIL;
|
||
|
}
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_slave_deinit_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_slave_send_continue_exec(char *cmd)
|
||
|
{
|
||
|
uint8_t *buf = cmd_spi_master_buf;
|
||
|
int32_t len = testlen;
|
||
|
enum cmd_status ret = CMD_STATUS_OK;
|
||
|
|
||
|
cmd_spi_init_data(buf, len);
|
||
|
while (1) {
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_slave_init_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
if (HAL_SPI_Slave_StartTransmit_DMA(CMD_SPI_PORT, buf, len) != HAL_OK) {
|
||
|
CMD_ERR("HAL_SPI_Slave_StartTransmit_DMA() fail\n");
|
||
|
}
|
||
|
|
||
|
slave_status = SPI_SLAVE_STATUS_TX;
|
||
|
if (OS_SemaphoreWait(&cmd_slave_sem, OS_WAIT_FOREVER) != OS_OK) {
|
||
|
CMD_ERR("%s(), wait timeout\n", __func__);
|
||
|
}
|
||
|
|
||
|
#if CMD_SPI_SLAVE_DELAY_STOP
|
||
|
cmd_msleep(CMD_SPI_SLAVE_DELAY_STOP);
|
||
|
#endif
|
||
|
|
||
|
int32_t left = HAL_SPI_Slave_StopTransmit_DMA(CMD_SPI_PORT);
|
||
|
if (left != 0) {
|
||
|
CMD_ERR("HAL_SPI_Slave_StopTransmit_DMA(), left %d\n", left);
|
||
|
ret = CMD_STATUS_FAIL;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_slave_deinit_exec(NULL);
|
||
|
#endif
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_slave_recv_exec(char *cmd)
|
||
|
{
|
||
|
uint8_t *buf = cmd_spi_master_buf;
|
||
|
int32_t len = testlen;
|
||
|
enum cmd_status ret = CMD_STATUS_OK;
|
||
|
|
||
|
cmd_memset(buf, 0, len);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_slave_init_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
if (HAL_SPI_Slave_StartReceive_DMA(CMD_SPI_PORT, buf, len) != HAL_OK) {
|
||
|
CMD_ERR("HAL_SPI_Slave_StartReceive_DMA() fail\n");
|
||
|
}
|
||
|
|
||
|
slave_status = SPI_SLAVE_STATUS_RX;
|
||
|
if (OS_SemaphoreWait(&cmd_slave_sem, 10000) != OS_OK) {
|
||
|
CMD_ERR("%s(), wait timeout\n", __func__);
|
||
|
}
|
||
|
|
||
|
|
||
|
#if CMD_SPI_SLAVE_DELAY_STOP
|
||
|
cmd_msleep(CMD_SPI_SLAVE_DELAY_STOP);
|
||
|
#endif
|
||
|
|
||
|
int32_t left = HAL_SPI_Slave_StopReceive_DMA(CMD_SPI_PORT);
|
||
|
if (left != 0) {
|
||
|
CMD_ERR("HAL_SPI_Slave_StopReceive_DMA(), left %d\n", left);
|
||
|
ret = CMD_STATUS_FAIL;
|
||
|
}
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_slave_deinit_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
cmd_spi_verify_data(buf, len);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_slave_recv_continue_exec(char *cmd)
|
||
|
{
|
||
|
uint8_t *buf = cmd_spi_master_buf;
|
||
|
int32_t len = testlen;
|
||
|
enum cmd_status ret = CMD_STATUS_OK;
|
||
|
|
||
|
uint32_t test_timeout = 1000 * 120;
|
||
|
uint32_t timeout = OS_GetTicks() + OS_TicksToMSecs(test_timeout);
|
||
|
uint32_t correct = 0;
|
||
|
uint32_t wrong = 0;
|
||
|
uint32_t sum = 0;
|
||
|
|
||
|
while (OS_TimeBeforeEqual(OS_GetTicks(), timeout)) {
|
||
|
|
||
|
cmd_memset(buf, 0, len);
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_slave_init_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
if (HAL_SPI_Slave_StartReceive_DMA(CMD_SPI_PORT, buf, len) != HAL_OK) {
|
||
|
CMD_ERR("HAL_SPI_Slave_StartReceive_DMA() fail\n");
|
||
|
}
|
||
|
|
||
|
slave_status = SPI_SLAVE_STATUS_RX;
|
||
|
if (OS_SemaphoreWait(&cmd_slave_sem, OS_WAIT_FOREVER) != OS_OK) {
|
||
|
CMD_ERR("%s(), wait timeout\n", __func__);
|
||
|
}
|
||
|
|
||
|
|
||
|
#if CMD_SPI_SLAVE_DELAY_STOP
|
||
|
cmd_msleep(CMD_SPI_SLAVE_DELAY_STOP);
|
||
|
#endif
|
||
|
|
||
|
int32_t left = HAL_SPI_Slave_StopReceive_DMA(CMD_SPI_PORT);
|
||
|
if (left != 0) {
|
||
|
CMD_ERR("HAL_SPI_Slave_StopReceive_DMA(), left %d\n", left);
|
||
|
ret = CMD_STATUS_FAIL;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
#if CMD_SPI_DO_OPEN_CLOSE
|
||
|
cmd_spi_slave_deinit_exec(NULL);
|
||
|
#endif
|
||
|
|
||
|
sum += 1;
|
||
|
|
||
|
int i;
|
||
|
for (i = 0; i < len; ++i) {
|
||
|
if (buf[i] != ((i + 1) & 0xff)) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (i >= len) {
|
||
|
correct += 1;
|
||
|
} else {
|
||
|
wrong += 1;
|
||
|
}
|
||
|
}
|
||
|
/* master need to wait slave recv first exec, so the speed is not exact */
|
||
|
CMD_DBG("slave rx sum %u, correct %u, wrong %u, speed %u(KB/s)\n",
|
||
|
sum, correct, wrong, (sum * testlen)/((test_timeout / 1000) * 1000));
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static enum cmd_status cmd_spi_slave_stable_test_exec(char *cmd)
|
||
|
{
|
||
|
while (1) {
|
||
|
cmd_spi_slave_send_exec(NULL);
|
||
|
cmd_spi_slave_recv_exec(NULL);
|
||
|
}
|
||
|
return CMD_STATUS_OK;
|
||
|
}
|
||
|
|
||
|
#if PRJCONF_SPI_EN
|
||
|
/*
|
||
|
* SPI board config
|
||
|
*/
|
||
|
static enum cmd_status cmd_board_init_exec(char *cmd)
|
||
|
{
|
||
|
int ret;
|
||
|
ret = board_spi_init(CMD_SPI_PORT);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("board_spi_init failed\n");
|
||
|
return CMD_STATUS_FAIL;
|
||
|
}
|
||
|
|
||
|
return CMD_STATUS_OK;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* spi flash_id m=<mode> l=<line> s=<speed>
|
||
|
* spi flash_id m=0 l=1 s=1000
|
||
|
*/
|
||
|
static enum cmd_status cmd_spi_flash_id_exec(char *cmd)
|
||
|
{
|
||
|
int ret;
|
||
|
int cnt;
|
||
|
uint32_t mode, line, speed;
|
||
|
SPI_Config config;
|
||
|
uint8_t dataBuf[1];
|
||
|
uint8_t rece_dataBuf[3];
|
||
|
uint8_t *recv;
|
||
|
recv = rece_dataBuf;
|
||
|
|
||
|
cmd_memset(rece_dataBuf, 0, 3);
|
||
|
|
||
|
cnt = cmd_sscanf(cmd, "m=%u l=%u s=%u", &mode, &line, &speed);
|
||
|
if (cnt != 3) {
|
||
|
CMD_ERR("invalid cnt %u\n", cnt);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (mode < 0 || mode > 3) {
|
||
|
CMD_ERR("invalid line %u\n", mode);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (line < 1 || line > 2) {
|
||
|
CMD_ERR("invalid line %u\n", line);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
cmd_memset(&config, 0, sizeof(config));
|
||
|
config.firstBit = SPI_TCTRL_FBS_MSB;
|
||
|
config.mode = SPI_CTRL_MODE_MASTER;
|
||
|
config.opMode = SPI_OPERATION_MODE_POLL;
|
||
|
config.sclk = speed * 1000;
|
||
|
config.sclkMode = mode;
|
||
|
|
||
|
ret = HAL_SPI_Open(CMD_SPI_PORT, SPI_TCTRL_SS_SEL_SS0, &config, 10);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Open failed\n");
|
||
|
return CMD_STATUS_FAIL;
|
||
|
}
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 1);
|
||
|
|
||
|
dataBuf[0] = 0x9F; //get flash id
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)&dataBuf, 1);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Transmit failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
|
||
|
if (line == 2) {
|
||
|
HAL_SPI_Config(CMD_SPI_PORT, SPI_ATTRIBUTION_IO_MODE, SPI_IO_MODE_DUAL_RX);
|
||
|
} else {
|
||
|
HAL_SPI_Config(CMD_SPI_PORT, SPI_ATTRIBUTION_IO_MODE, SPI_IO_MODE_NORMAL);
|
||
|
}
|
||
|
HAL_SPI_Receive(CMD_SPI_PORT, recv, 3);
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 0);
|
||
|
|
||
|
printf("jedec:0x");
|
||
|
printf("%02x%02x%02x", rece_dataBuf[2], rece_dataBuf[1], rece_dataBuf[0]);
|
||
|
printf("\n");
|
||
|
|
||
|
close:
|
||
|
HAL_SPI_Close(CMD_SPI_PORT);
|
||
|
return (ret == 0) ? CMD_STATUS_OK : ret;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* spi flash_read m=0 l=1 s=1000 a=0x0 rl=16
|
||
|
*/
|
||
|
static enum cmd_status cmd_spi_flash_read_exec(char *cmd)
|
||
|
{
|
||
|
int ret;
|
||
|
int cnt, r_len;
|
||
|
uint32_t mode, line, speed, addr_r;
|
||
|
SPI_Config config;
|
||
|
uint32_t dataBuf[1];
|
||
|
uint8_t rece_dataBuf[128];
|
||
|
uint8_t *recv;
|
||
|
recv = rece_dataBuf;
|
||
|
|
||
|
cmd_memset(rece_dataBuf, 0, 128);
|
||
|
|
||
|
cnt = cmd_sscanf(cmd, "m=%u l=%u s=%u a=0x%x rl=%u", &mode, &line, &speed, &addr_r, &r_len);
|
||
|
if (cnt != 5) {
|
||
|
CMD_ERR("invalid cnt %u\n", cnt);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (mode < 0 || mode > 3) {
|
||
|
CMD_ERR("invalid line %u\n", mode);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (line < 1 || line > 1) {
|
||
|
CMD_ERR("invalid line %u\n", line);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
cmd_memset(&config, 0, sizeof(config));
|
||
|
config.firstBit = SPI_TCTRL_FBS_MSB;
|
||
|
config.mode = SPI_CTRL_MODE_MASTER;
|
||
|
config.opMode = SPI_OPERATION_MODE_POLL;
|
||
|
config.sclk = speed * 1000;
|
||
|
config.sclkMode = mode;
|
||
|
|
||
|
ret = HAL_SPI_Open(CMD_SPI_PORT, SPI_TCTRL_SS_SEL_SS0, &config, 10);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Open failed\n");
|
||
|
return CMD_STATUS_FAIL;
|
||
|
}
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 1);
|
||
|
//send cmd
|
||
|
dataBuf[0] = 0x03; //read data cmd
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)&dataBuf, 1);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Transmit failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
//send addr
|
||
|
uint8_t add_temp;
|
||
|
add_temp = (addr_r >> 16) & 0xff;
|
||
|
printf("add_temp:%02x", add_temp);
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)&add_temp, 1);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Transmit failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
add_temp = (addr_r >> 8) & 0xff;
|
||
|
printf("%02x", add_temp);
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)&add_temp, 1);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Transmit failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
add_temp = (addr_r) & 0xff;
|
||
|
printf("%02x\n", add_temp);
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)&add_temp, 1);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Transmit failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
|
||
|
if (line == 2) {
|
||
|
HAL_SPI_Config(CMD_SPI_PORT, SPI_ATTRIBUTION_IO_MODE, SPI_IO_MODE_DUAL_RX);
|
||
|
} else {
|
||
|
HAL_SPI_Config(CMD_SPI_PORT, SPI_ATTRIBUTION_IO_MODE, SPI_IO_MODE_NORMAL);
|
||
|
}
|
||
|
|
||
|
HAL_SPI_Receive(CMD_SPI_PORT, recv, r_len);
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 0);
|
||
|
|
||
|
printf("recv data:");
|
||
|
for (int i = 0; i < r_len; i++) {
|
||
|
if ((i % 16) == 0) {
|
||
|
printf("\n");
|
||
|
}
|
||
|
printf("%02x ", rece_dataBuf[i]);
|
||
|
}
|
||
|
printf("\n");
|
||
|
|
||
|
cmd_spi_verify_data(rece_dataBuf, r_len);
|
||
|
|
||
|
close:
|
||
|
HAL_SPI_Close(CMD_SPI_PORT);
|
||
|
return (ret == 0) ? CMD_STATUS_OK : ret;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* spi flash_write m=0 l=1 s=1000 a=0x0 wl=16
|
||
|
*/
|
||
|
static enum cmd_status cmd_spi_flash_write_exec(char *cmd)
|
||
|
{
|
||
|
int ret;
|
||
|
int cnt, w_len;
|
||
|
uint32_t mode, line, speed, addr_r;
|
||
|
SPI_Config config;
|
||
|
uint32_t dataBuf[1];
|
||
|
uint8_t *write_dataBuf;
|
||
|
|
||
|
cnt = cmd_sscanf(cmd, "m=%u l=%u s=%u a=0x%x wl=%u", &mode, &line, &speed, &addr_r, &w_len);
|
||
|
if (cnt != 5) {
|
||
|
CMD_ERR("invalid cnt %u\n", cnt);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (mode < 0 || mode > 3) {
|
||
|
CMD_ERR("invalid line %u\n", mode);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
if (line < 1 || line > 1) {
|
||
|
CMD_ERR("invalid line %u\n", line);
|
||
|
return CMD_STATUS_INVALID_ARG;
|
||
|
}
|
||
|
|
||
|
write_dataBuf = cmd_malloc(w_len);
|
||
|
if (write_dataBuf == NULL) {
|
||
|
CMD_ERR("Malloc write buffer fail!\n");
|
||
|
return CMD_STATUS_FAIL;
|
||
|
}
|
||
|
cmd_spi_init_data(write_dataBuf, w_len);
|
||
|
|
||
|
cmd_memset(&config, 0, sizeof(config));
|
||
|
config.firstBit = SPI_TCTRL_FBS_MSB;
|
||
|
config.mode = SPI_CTRL_MODE_MASTER;
|
||
|
config.opMode = SPI_OPERATION_MODE_POLL;
|
||
|
config.sclk = speed * 1000;
|
||
|
config.sclkMode = mode;
|
||
|
|
||
|
ret = HAL_SPI_Open(CMD_SPI_PORT, SPI_TCTRL_SS_SEL_SS0, &config, 10);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Open failed\n");
|
||
|
cmd_free(write_dataBuf);
|
||
|
return CMD_STATUS_FAIL;
|
||
|
}
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 1);
|
||
|
|
||
|
//send cmd
|
||
|
dataBuf[0] = 0x02; //write data cmd
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)&dataBuf, 1);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Transmit failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
|
||
|
//send addr
|
||
|
uint8_t add_temp;
|
||
|
add_temp = (addr_r >> 16) & 0xff;
|
||
|
printf("add_temp:%02x", add_temp);
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)&add_temp, 1);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Transmit failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
|
||
|
add_temp = (addr_r >> 8) & 0xff;
|
||
|
printf("%02x", add_temp);
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)&add_temp, 1);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Transmit failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
|
||
|
add_temp = (addr_r) & 0xff;
|
||
|
printf("%02x\n", add_temp);
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, (uint8_t *)&add_temp, 1);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("HAL_SPI_Transmit failed\n");
|
||
|
goto close;
|
||
|
}
|
||
|
|
||
|
//send data
|
||
|
ret = HAL_SPI_Transmit(CMD_SPI_PORT, write_dataBuf, w_len);
|
||
|
if (ret != 0) {
|
||
|
CMD_ERR("write data failed\n");
|
||
|
}
|
||
|
|
||
|
HAL_SPI_CS(CMD_SPI_PORT, 0);
|
||
|
|
||
|
close:
|
||
|
cmd_free(write_dataBuf);
|
||
|
HAL_SPI_Close(CMD_SPI_PORT);
|
||
|
return (ret == 0) ? CMD_STATUS_OK : ret;
|
||
|
}
|
||
|
|
||
|
static const struct cmd_data g_spi_slave_cmds[] = {
|
||
|
{ "init", cmd_spi_slave_init_exec },
|
||
|
{ "deinit", cmd_spi_slave_deinit_exec },
|
||
|
{ "send", cmd_spi_slave_send_exec },
|
||
|
{ "recv", cmd_spi_slave_recv_exec },
|
||
|
{ "send_continue", cmd_spi_slave_send_continue_exec },
|
||
|
{ "recv_continue", cmd_spi_slave_recv_continue_exec },
|
||
|
{ "stable_test", cmd_spi_slave_stable_test_exec},
|
||
|
};
|
||
|
|
||
|
static enum cmd_status cmd_spi_slave_exec(char *cmd)
|
||
|
{
|
||
|
return cmd_exec(cmd, g_spi_slave_cmds, cmd_nitems(g_spi_slave_cmds));
|
||
|
}
|
||
|
|
||
|
static const struct cmd_data g_spi_cmds[] = {
|
||
|
{ "config", cmd_spi_config_exec },
|
||
|
{ "deconfig", cmd_spi_deconfig_exec },
|
||
|
{ "start", cmd_spi_start_exec },
|
||
|
{ "master", cmd_spi_master_exec },
|
||
|
{ "slave", cmd_spi_slave_exec },
|
||
|
#if PRJCONF_SPI_EN
|
||
|
{ "board_init", cmd_board_init_exec },
|
||
|
#endif
|
||
|
{ "flash_id", cmd_spi_flash_id_exec },
|
||
|
{ "flash_read", cmd_spi_flash_read_exec },
|
||
|
{ "flash_write", cmd_spi_flash_write_exec },
|
||
|
};
|
||
|
|
||
|
enum cmd_status cmd_spi_exec(char *cmd)
|
||
|
{
|
||
|
return cmd_exec(cmd, g_spi_cmds, cmd_nitems(g_spi_cmds));
|
||
|
}
|