483 lines
14 KiB
C
483 lines
14 KiB
C
|
/*
|
||
|
* Copyright 2018 The Chromium OS Authors. All rights reserved.
|
||
|
* Use of this source code is governed by a BSD-style license that can be
|
||
|
* found in the LICENSE file.
|
||
|
*/
|
||
|
|
||
|
/* This file creates the UART Program Protocol API commands. */
|
||
|
|
||
|
#include <stdint.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "cmd.h"
|
||
|
#include "lib_crc.h"
|
||
|
#include "main.h"
|
||
|
|
||
|
/* Extracting Byte - 8 bit: MSB, LSB */
|
||
|
#define MSB(u16) ((uint8_t)((uint16_t)(u16) >> 8))
|
||
|
#define LSB(u16) ((uint8_t)(u16))
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* SPI Flash commands
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
#define SPI_READ_JEDEC_ID_CMD 0x9F
|
||
|
#define SPI_WRITE_ENABLE_CMD 0x06
|
||
|
#define SPI_WRITE_DISABLE_CMD 0x04
|
||
|
#define SPI_READ_STATUS_REG_CMD 0x05
|
||
|
#define SPI_WRITE_STATUS_REG_CMD 0x01
|
||
|
#define SPI_READ_DATA_CMD 0x03
|
||
|
#define SPI_PAGE_PRGM_CMD 0x02
|
||
|
#define SPI_SECTOR_ERASE_CMD 0xD8
|
||
|
#define SPI_BULK_ERASE_CMD 0xC7
|
||
|
#define SPI_READ_PID_CMD 0x90
|
||
|
|
||
|
union cmd_addr {
|
||
|
uint8_t c_adr[4];
|
||
|
uint32_t h_adr;
|
||
|
};
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function implementation
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function: cmd_create_sync
|
||
|
*
|
||
|
* Parameters: cmd_info - Pointer to a command buffer.
|
||
|
* cmd_len - Pointer to command length.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Create a Host to Device SYNC protocol command.
|
||
|
* The total command length is written to 'cmd_len'.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_create_sync(uint8_t *cmd_info, uint32_t *cmd_len)
|
||
|
{
|
||
|
uint32_t len = 0;
|
||
|
|
||
|
/* Build the command buffer */
|
||
|
cmd_info[len++] = UFPP_H2D_SYNC_CMD;
|
||
|
|
||
|
/* Return total command length */
|
||
|
*cmd_len = len;
|
||
|
}
|
||
|
|
||
|
/*---------------------------------------------------------------------------
|
||
|
* Function: cmd_create_write
|
||
|
*
|
||
|
* Parameters: addr - Memory address to write to.
|
||
|
* size - Size of daya (in bytes) to write to memory.
|
||
|
* data_buf - Pointer to data buffer containing raw data to write.
|
||
|
* cmd_info - Pointer to a command buffer.
|
||
|
* cmd_len - Pointer to command length.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Create a WRITE protocol command.
|
||
|
* The command buffer is enclosed by CRC, calculated on command
|
||
|
* information and raw data.
|
||
|
* The total command length is written to 'cmd_len'.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_create_write(uint32_t addr, uint32_t size, uint8_t *data_buf,
|
||
|
uint8_t *cmd_info, uint32_t *cmd_len)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
union cmd_addr adr_tr;
|
||
|
uint16_t crc = 0;
|
||
|
uint32_t len = 0;
|
||
|
|
||
|
/* Build the command buffer */
|
||
|
cmd_info[len++] = UFPP_WRITE_CMD;
|
||
|
cmd_info[len++] = (uint8_t)(size - 1);
|
||
|
|
||
|
/* Insert Address */
|
||
|
adr_tr.h_adr = addr;
|
||
|
cmd_info[len++] = adr_tr.c_adr[3];
|
||
|
cmd_info[len++] = adr_tr.c_adr[2];
|
||
|
cmd_info[len++] = adr_tr.c_adr[1];
|
||
|
cmd_info[len++] = adr_tr.c_adr[0];
|
||
|
|
||
|
/* Insert data */
|
||
|
memcpy(&cmd_info[len], data_buf, size);
|
||
|
len += size;
|
||
|
|
||
|
/* Calculate CRC */
|
||
|
for (i = 0; i < len; i++)
|
||
|
crc = update_crc(crc, (char)cmd_info[i]);
|
||
|
|
||
|
/* Insert CRC */
|
||
|
cmd_info[len++] = MSB(crc);
|
||
|
cmd_info[len++] = LSB(crc);
|
||
|
|
||
|
/* Return total command length */
|
||
|
*cmd_len = len;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function: cmd_create_read
|
||
|
*
|
||
|
* Parameters: addr - Memory address to read from.
|
||
|
* size - Size of daya (in bytes) to read from memory.
|
||
|
* cmd_info - Pointer to a command buffer.
|
||
|
* cmd_len - Pointer to command length.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Create a READ protocol command.
|
||
|
* The command buffer is enclosed by CRC, calculated on command
|
||
|
* information and raw data.
|
||
|
* The total command length is written to 'cmd_len'.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_create_read(uint32_t addr, uint8_t size, uint8_t *cmd_info,
|
||
|
uint32_t *cmd_len)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
union cmd_addr adr_tr;
|
||
|
uint16_t crc = 0;
|
||
|
uint32_t len = 0;
|
||
|
|
||
|
/* Build the command buffer */
|
||
|
cmd_info[len++] = UFPP_READ_CMD;
|
||
|
cmd_info[len++] = (uint8_t)size;
|
||
|
|
||
|
/* Insert Address */
|
||
|
adr_tr.h_adr = addr;
|
||
|
cmd_info[len++] = adr_tr.c_adr[3];
|
||
|
cmd_info[len++] = adr_tr.c_adr[2];
|
||
|
cmd_info[len++] = adr_tr.c_adr[1];
|
||
|
cmd_info[len++] = adr_tr.c_adr[0];
|
||
|
|
||
|
/* Calculate CRC */
|
||
|
for (i = 0; i < len; i++)
|
||
|
crc = update_crc(crc, (char)cmd_info[i]);
|
||
|
|
||
|
/* Insert CRC */
|
||
|
cmd_info[len++] = MSB(crc);
|
||
|
cmd_info[len++] = LSB(crc);
|
||
|
|
||
|
/* Return total command length */
|
||
|
*cmd_len = len;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function: cmd_create_exec
|
||
|
*
|
||
|
* Parameters: addr - Memory address to execute from.
|
||
|
* cmd_info - Pointer to a command buffer.
|
||
|
* cmd_len - Pointer to command length.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Create an FCALL protocol command.
|
||
|
* The command buffer is enclosed by CRC, calculated on command
|
||
|
* information and raw data.
|
||
|
* The total command length is written to 'cmd_len'.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_create_exec(uint32_t addr, uint8_t *cmd_info, uint32_t *cmd_len)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
union cmd_addr adr_tr;
|
||
|
uint16_t crc = 0;
|
||
|
uint32_t len = 0;
|
||
|
|
||
|
/* Build the command buffer */
|
||
|
cmd_info[len++] = UFPP_FCALL_CMD;
|
||
|
cmd_info[len++] = 0;
|
||
|
|
||
|
/* Insert Address */
|
||
|
adr_tr.h_adr = addr;
|
||
|
cmd_info[len++] = adr_tr.c_adr[3];
|
||
|
cmd_info[len++] = adr_tr.c_adr[2];
|
||
|
cmd_info[len++] = adr_tr.c_adr[1];
|
||
|
cmd_info[len++] = adr_tr.c_adr[0];
|
||
|
|
||
|
/* Calculate CRC */
|
||
|
for (i = 0; i < len; i++)
|
||
|
crc = update_crc(crc, (char)cmd_info[i]);
|
||
|
|
||
|
/* Insert CRC */
|
||
|
cmd_info[len++] = MSB(crc);
|
||
|
cmd_info[len++] = LSB(crc);
|
||
|
|
||
|
/* Return total command length */
|
||
|
*cmd_len = len;
|
||
|
}
|
||
|
|
||
|
/*---------------------------------------------------------------------------
|
||
|
* Function: cmd_build_sync
|
||
|
*
|
||
|
* Parameters: cmd_buf - Pointer to a command buffer.
|
||
|
* cmd_num - Pointer to command number.
|
||
|
* Returns: none.
|
||
|
* Description:
|
||
|
* Build a synchronization command buffer.
|
||
|
* The total command number is written to 'cmd_num'.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_build_sync(struct command_node *cmd_buf, uint32_t *cmd_num)
|
||
|
{
|
||
|
uint32_t cmd = 0;
|
||
|
|
||
|
cmd_create_sync(cmd_buf[cmd].cmd, &cmd_buf[cmd].cmd_size);
|
||
|
cmd_buf[cmd].resp_size = 1;
|
||
|
cmd++;
|
||
|
|
||
|
*cmd_num = cmd;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function: cmd_build_exec_exit
|
||
|
*
|
||
|
* Parameters: addr - Memory address to execute from.
|
||
|
* cmd_buf - Pointer to a command buffer.
|
||
|
* cmd_num - Pointer to command number.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Build an Excute command buffer.
|
||
|
* Command does not expect the executed code to return, that is,
|
||
|
* only FCALL protocol
|
||
|
* command code is expected.
|
||
|
* Determine the expected response size per each command.
|
||
|
* The total command number is written to 'cmd_num'.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_build_exec_exit(uint32_t addr, struct command_node *cmd_buf,
|
||
|
uint32_t *cmd_num)
|
||
|
{
|
||
|
uint32_t cmd = 0;
|
||
|
|
||
|
cmd_create_exec(addr, cmd_buf[cmd].cmd, &cmd_buf[cmd].cmd_size);
|
||
|
cmd_buf[cmd].resp_size = 1;
|
||
|
cmd++;
|
||
|
|
||
|
*cmd_num = cmd;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function: cmd_build_exec_ret
|
||
|
*
|
||
|
* Parameters: addr - Memory address to execute from.
|
||
|
* cmd_buf - Pointer to a command buffer.
|
||
|
* cmd_num - Pointer to command number.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Build an Excute command buffer.
|
||
|
* Command expects the executed code to return, that is,
|
||
|
* FCALL_RSLT protocol command
|
||
|
* code is expected, together with the execution result.
|
||
|
* Determine the expected response size per each command.
|
||
|
* The total command number is written to 'cmd_num'.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_build_exec_ret(uint32_t addr, struct command_node *cmd_buf,
|
||
|
uint32_t *cmd_num)
|
||
|
{
|
||
|
uint32_t cmd = 0;
|
||
|
|
||
|
cmd_create_exec(addr, cmd_buf[cmd].cmd, &cmd_buf[cmd].cmd_size);
|
||
|
cmd_buf[cmd].resp_size = 3;
|
||
|
cmd++;
|
||
|
|
||
|
*cmd_num = cmd;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function: cmd_disp_sync
|
||
|
*
|
||
|
* Parameters: resp_buf - Pointer to a response buffer.
|
||
|
* Returns: TRUE if successful, FALSE in the case of an error.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Display SYNC command response information.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
bool cmd_disp_sync(uint8_t *resp_buf)
|
||
|
{
|
||
|
if (resp_buf[0] == (uint8_t)(UFPP_D2H_SYNC_CMD)) {
|
||
|
display_color_msg(SUCCESS, "Host/Device are synchronized\n");
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
display_color_msg(FAIL, "Host/Device synchronization failed!!!\n");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function: cmd_disp_write
|
||
|
*
|
||
|
* Parameters: resp_buf - Pointer to a response buffer.
|
||
|
* resp_size - Response size.
|
||
|
* resp_num - Response packet number.
|
||
|
* Returns: TRUE if successful, FALSE in the case of an error.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Display WRITE command response information.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
bool cmd_disp_write(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num,
|
||
|
uint32_t total_size)
|
||
|
{
|
||
|
if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) {
|
||
|
display_color_msg(SUCCESS,
|
||
|
"\rTransmitted packet of size %u bytes, packet "
|
||
|
"[%u]out of [%u]",
|
||
|
resp_size, resp_num, total_size);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
display_color_msg(FAIL, "\nWrite packet [%lu] Failed\n", resp_num);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/*-----------------------------------------------------------------------------
|
||
|
* Function: cmd_disp_read
|
||
|
*
|
||
|
* Parameters: resp_buf - Pointer to a response buffer.
|
||
|
* resp_size - Response size.
|
||
|
* resp_num - Response packet number.
|
||
|
* Returns: TRUE if successful, FALSE in the case of an error.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Display READ command response information.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
bool cmd_disp_read(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num,
|
||
|
uint32_t total_size)
|
||
|
{
|
||
|
if (resp_buf[0] == (uint8_t)(UFPP_READ_CMD)) {
|
||
|
display_color_msg(SUCCESS,
|
||
|
"\rReceived packet of size %u bytes, packet [%u] out "
|
||
|
"of [%u]",
|
||
|
resp_size, resp_num, total_size);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
display_color_msg(FAIL, "\nRead packet [%u] Failed\n", resp_num);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function: cmd_disp_data
|
||
|
*
|
||
|
* Parameters: resp_buf - Pointer to a response buffer.
|
||
|
* resp_size - Response size.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Display raw data, read from memory.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_disp_data(uint8_t *resp_buf, uint32_t resp_size)
|
||
|
{
|
||
|
uint32_t idx;
|
||
|
uint32_t i;
|
||
|
|
||
|
for (idx = 0; idx < resp_size; idx += 4) {
|
||
|
if ((idx % 16) == 0)
|
||
|
printf("\n");
|
||
|
|
||
|
printf("0x");
|
||
|
for (i = 4; i > 0; i--)
|
||
|
printf("%02x", resp_buf[idx + i - 1]);
|
||
|
|
||
|
if ((idx % 4) == 0)
|
||
|
printf(" ");
|
||
|
}
|
||
|
|
||
|
printf("\n");
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
* Function: cmd_disp_flash_erase_dev
|
||
|
*
|
||
|
* Parameters: resp_buf - Pointer to a response buffer.
|
||
|
* dev_num - Flash Device Number.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Display BULK_ERASE command response information.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_disp_flash_erase_dev(uint8_t *resp_buf, uint32_t dev_num)
|
||
|
{
|
||
|
if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) {
|
||
|
display_color_msg(SUCCESS,
|
||
|
"Flash Erase of device [%u] Passed\n", dev_num);
|
||
|
} else {
|
||
|
display_color_msg(
|
||
|
FAIL, "Flash Erase of device [%u] Failed\n", dev_num);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*---------------------------------------------------------------------------
|
||
|
* Function: cmd_disp_flash_erase_sect
|
||
|
*
|
||
|
* Parameters: resp_buf - Pointer to a response buffer.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Display BULK_ERASE command response information.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_disp_flash_erase_sect(uint8_t *resp_buf, uint32_t dev_num)
|
||
|
{
|
||
|
if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) {
|
||
|
display_color_msg(SUCCESS,
|
||
|
"Sector Erase of device [%lu] Passed\n", dev_num);
|
||
|
} else {
|
||
|
display_color_msg(
|
||
|
FAIL, "Sector Erase of device [%lu] Failed\n", dev_num);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*---------------------------------------------------------------------------
|
||
|
* Function: cmd_disp_exec_exit
|
||
|
*
|
||
|
* Parameters: resp_buf - Pointer to a response buffer.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Display Execute command response information.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_disp_exec_exit(uint8_t *resp_buf)
|
||
|
{
|
||
|
if (resp_buf[0] == (uint8_t)(UFPP_FCALL_CMD))
|
||
|
display_color_msg(SUCCESS, "Execute Command Passed\n");
|
||
|
else
|
||
|
display_color_msg(FAIL, "Execute Command Failed\n");
|
||
|
}
|
||
|
|
||
|
/*---------------------------------------------------------------------------
|
||
|
* Function: cmd_disp_exec_ret
|
||
|
*
|
||
|
* Parameters: resp_buf - Pointer to a response buffer.
|
||
|
* Returns: none.
|
||
|
* Side effects:
|
||
|
* Description:
|
||
|
* Display Execute Result command response information.
|
||
|
*---------------------------------------------------------------------------
|
||
|
*/
|
||
|
void cmd_disp_exec_ret(uint8_t *resp_buf)
|
||
|
{
|
||
|
if (resp_buf[1] == (uint8_t)(UFPP_FCALL_RSLT_CMD)) {
|
||
|
display_color_msg(SUCCESS,
|
||
|
"Execute Command Passed, execution result is [0x%X]\n",
|
||
|
resp_buf[2]);
|
||
|
} else {
|
||
|
display_color_msg(FAIL,
|
||
|
"Execute Command Failed [0x%X] [0x%X], rslt=[0x%X]\n",
|
||
|
resp_buf[0], resp_buf[1], resp_buf[2]);
|
||
|
}
|
||
|
}
|