Skip to content
Permalink
85060eceb7
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
522 lines (463 sloc) 17 KB
/******************************************************************************
* File Name: main.c
*
* Description: This is the source code for the XMC MCU: Flash BMI Example
* for ModusToolbox. This example demonstrates how BMI can be
* configured.
*
* Related Document: See README.md
*
******************************************************************************
*
* Copyright (c) 2021, Infineon Technologies AG
* All rights reserved.
*
* Boost Software License - Version 1.0 - August 17th, 2003
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
/* Include header files */
#include <stdio.h>
#include <stdlib.h>
#include "cybsp.h"
#include "cy_utils.h"
#include "retarget_io.h"
#include "shell.h"
#include <xmc_common.h>
#include <xmc_scu.h>
#include <xmc_flash.h>
/*******************************************************************************
* Macros
********************************************************************************/
/* Maximum number of times the UCBs can be programmed */
#define UCB_PROGRAM_MAX_LIMIT (4)
/* UCBs can be programmed upto 4 times maximum, use 3 for safe use */
#define UCB_PROGRAM_SAFE_LIMIT (3)
/* Set to 1 to enable safety check when programming UCBs
* Set to 0 to disable safety check
*/
#define UCB_PROGRAM_SAFETY_ENABLED (1)
/* BMI String Offsets */
#define BMI_WORD_OFFSET (0)
#define BMI_MAC_ADDR_OFFSET (4)
#define BMI_ETH_IP_LSB_OFFSET (10)
#define BMI_ETH_IPV4_MSB_OFFSET (13)
#define BMI_ETH_IPV6_MSB_OFFSET (25)
#define BMI_USB_SER_NO_OFFSET (26)
#define BMI_XOR_CHSM_OFFSET (33)
/* BMI String lengths */
#define CHIPID_LEN (16)
#define BMI_STRING_LEN (64)
#define MAC_ADDR_LEN (6)
#define ETH_IPV4_LSB_LEN (4)
#define ETH_IPV4_MSB_LEN (11)
#define ETH_IPV6_MSB_LEN (1)
#define USB_SER_NO_LEN (4)
/* DSRAM1 memory locations */
#define CHIPID_LOC ((uint8_t *)0x20000000UL)
#define BMI_STRING_LOC ((uint8_t *)0x20000090UL)
/*******************************************************************************
* Function Prototypes
********************************************************************************/
static void initialize_shell();
static void help_cmd(uint32_t argc, char **argv);
static void bmi_install_cmd(uint32_t argc, char **argv);
static void bmi_usb_read_cmd(uint32_t argc, char **argv);
static void bmi_mac_read_cmd(uint32_t argc, char **argv);
static void bmi_ip_read_cmd(uint32_t argc, char **argv);
static void bmi_status_cmd(uint32_t argc, char **argv);
static uint32_t flash_get_ucb_program_count();
static void flash_ucb_program_count(uint32_t count);
void SystemInit(void);
/*******************************************************************************
* Global Variables
********************************************************************************/
/* Shell command table with commands and relevant information */
const shell_cmd_t shell_cmd_table[] =
{
{"help", 0u, 0u, help_cmd, "Display help message", ""},
{"install", 0u, 0u, bmi_install_cmd, "Install BMI String", ""},
{"usb", 0u, 0u, bmi_usb_read_cmd, "Retrieve USB Serial Number", ""},
{"mac", 0u, 0u, bmi_mac_read_cmd, "Retrieve MAC address", ""},
{"ipv4", 0u, 0u, bmi_ip_read_cmd, "Retrieve IPv4 address", ""},
{"status", 0u, 0u, bmi_status_cmd, "Check if BMI is installed", ""},
{0, 0u, 0u, 0, 0, 0}
};
/* Configure a BMI String with:
*
* 1) BMI Word (4 bytes) - Describe set of activities to be performed on startup:
* a) Normal Boot Sequence - XMC_FLASH_BMI_BOOT_MODE_NORMAL
* b) Store MAC Address into DSRAM1 - XMC_FLASH_BMI_MAC_BIT_MSK
* c) Store IPv4 Address into DSRAM1 - XMC_FLASH_BMI_IPV4_BIT_MSK
* d) Store USB Serial Number into DSRAM1 - XMC_FLASH_BMI_USB_BIT_MAK
*
* 2) MAC Address (6 bytes) - {0x8C, 0x16, 0x45, 0x23, 0x12, 0xD0}
*
* 3) IPv4 Address (4 bytes) - {0xC0, 0xA8, 0x00, 0xB5}
*
* 4) USB Serial Number (4 bytes) - {0x5B, 0x0C, 0x3A, 0x40}
*
* See XMC_FLASH_BMI_STRING_t for other options.
*
*/
XMC_FLASH_BMI_STRING_t myBMIString =
{
.bmi = (XMC_FLASH_BMI_BOOT_MODE_NORMAL | XMC_FLASH_BMI_MAC_BIT_MSK
| XMC_FLASH_BMI_IPV4_BIT_MSK | XMC_FLASH_BMI_USB_BIT_MAK),
.mac_addr = {0x8C, 0x16, 0x45, 0x23, 0x12, 0xD0},
.ip_extension = {0xC0, 0xA8, 0x00, 0xB5},
.usb_serial_no = {0x5B, 0x0C, 0x3A, 0x40}
};
/* UCB Program Counter */
uint8_t ucb_program_count = 0;
/* BMI String array */
uint8_t g_bmi_string[BMI_STRING_LEN] __attribute__((section(".no_init")));
/*******************************************************************************
* Function Name: initialize_shell
********************************************************************************
* Summary:
* This function prompts useful information about the shell and supported
* commands.
*
* Parameters:
* none
*
* Return:
* void
*
*******************************************************************************/
static void initialize_shell()
{
const char DELIMITER_STR[] = "*****************************************";
shell_print("\r\n%s", DELIMITER_STR);
shell_print(" %s", "Shell Application");
shell_print(DELIMITER_STR);
shell_print(" Version %s", "1.0.0");
shell_print(" Built %s", __DATE__ " at " __TIME__);
shell_print("\n Enter 'help' for command list.");
shell_print("\nNote: UCBs can be programmed only 4 times.\r\nCurrent UCB "
"Program Count: %d\n", ucb_program_count);
shell_print("%s\n", DELIMITER_STR);
}
/*******************************************************************************
* Function Name: help_cmd
********************************************************************************
* Summary:
* This function displays all the commands supported by the shell
*
* Parameters:
* uint32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
*
* Return:
* void
*
*******************************************************************************/
static void help_cmd(uint32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
XMC_UNUSED_ARG(argv);
/* Display help options */
shell_help();
}
/*******************************************************************************
* Function Name: bmi_install_cmd
********************************************************************************
* Summary:
* This function installs the BMI configuration into UCB2 Page1
*
* Parameters:
* uint32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
static void bmi_install_cmd(uint32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
#if UCB_PROGRAM_SAFETY_ENABLED
if(ucb_program_count == UCB_PROGRAM_SAFE_LIMIT)
{
shell_print("UCB program safe limit reached. BMI Configuration can"
" be changed only one last time. Device might become unusable"
" if there is any failure!"
"\r\nSet UCB_PROGRAM_SAFETY_ENABLED to 0 in code to enable"
" programming the last time!");
return;
}
#endif
if(ucb_program_count == UCB_PROGRAM_MAX_LIMIT)
{
shell_print("ERROR: UCBs can be programmed only four times. Cannot "
"configure BMI!");
return;
}
/* Check if protection is enabled on the flash */
if((XMC_FLASH_GetStatus() & XMC_FLASH_STATUS_PROTECTION_INSTALLED) == 0)
{
shell_print("Flash Protection not installed");
/* Erase User Configuration Block to remove any prior BMI
* configuration or flash protection */
XMC_FLASH_EraseUCB(XMC_FLASH_UCB2);
/* Increment UCB program counter */
ucb_program_count++;
/* Flash UCB program count into flash */
flash_ucb_program_count(ucb_program_count);
/* Install the BMI */
XMC_FLASH_InstallBMI(&myBMIString);
/* Clear reset reason */
XMC_SCU_RESET_ClearDeviceResetReason();
/* Configure the boot mode pins */
XMC_SCU_SetBootMode(XMC_SCU_BOOTMODE_BMI);
/* Reset device for the changes to take effect */
NVIC_SystemReset();
}
else
{
shell_print("Flash Protection installed, please remove protection before"
"installing BMI!");
}
}
/*******************************************************************************
* Function Name: bmi_usb_read_cmd
********************************************************************************
* Summary:
* This function reads the USB Serial number from the DSRAM1
*
* Parameters:
* uint32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
static void bmi_usb_read_cmd(uint32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
/* Point to USB offset in the BMI String array */
const uint8_t *usb_address = (uint8_t *)&g_bmi_string[BMI_USB_SER_NO_OFFSET];
/* Print USB Serial Number */
for(uint32_t i = 0; i < USB_SER_NO_LEN; i++)
{
shell_print("USB Serial Number: 0x%X", *(usb_address++));
}
}
/*******************************************************************************
* Function Name: bmi_mac_read_cmd
********************************************************************************
* Summary:
* This function reads MAC Address from the DSRAM1
*
* Parameters:
* uint32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
static void bmi_mac_read_cmd(uint32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
XMC_UNUSED_ARG(argv);
/* Point to MAC offset in the BMI String array */
const uint8_t *mac_address = (uint8_t *)&g_bmi_string[BMI_MAC_ADDR_OFFSET];
/* Print MAC Address */
for(uint32_t i = 0; i < MAC_ADDR_LEN; i++)
{
shell_print("MAC Address: 0x%X", *(mac_address++));
}
}
/*******************************************************************************
* Function Name: bmi_ip_read_cmd
********************************************************************************
* Summary:
* This function reads IPv4 Address (LSB) from the DSRAM1
*
* Parameters:
* uint32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
static void bmi_ip_read_cmd(uint32_t argc, char **argv)
{
XMC_UNUSED_ARG(argc);
XMC_UNUSED_ARG(argv);
/* Point to IPv4 Address (LSB) in the BMI String array */
const uint8_t *ipv4_address = (uint8_t *)&g_bmi_string[BMI_ETH_IP_LSB_OFFSET];
/* Print IPv4 Address (LSB) */
for(uint32_t i = 0; i < ETH_IPV4_LSB_LEN; i++)
{
shell_print("IPv4 Address (LSB): 0x%X", *(ipv4_address++));
}
}
/*******************************************************************************
* Function Name: bmi_status_cmd
********************************************************************************
* Summary:
* This function checks if the BMI valid bit is set or not
*
* Parameters:
* uint32_t argc - number of command strings
* char **argv - pointer to command arguments array
*
* Return:
* void
*
*******************************************************************************/
static void bmi_status_cmd(uint32_t argc, char **argv)
{
uint32_t *bmi_word = (uint32_t *)&g_bmi_string[0];
shell_print("BMI Word: %0x8", *bmi_word);
shell_print("UCB Program Count: %d", flash_get_ucb_program_count());
if((*bmi_word & XMC_FLASH_BMI_VALID) == XMC_FLASH_BMI_VALID)
{
shell_print("BMI is installed and valid!");
}
else
{
shell_print("BMI is not yet installed or is invalid!");
}
}
/*******************************************************************************
* Function Name: flash_ucb_program_count
********************************************************************************
* Summary:
* This function programs the UCB program count into the flash sector 8
*
* Parameters:
* uint32_t count - UCB programming count
*
* Return:
* void
*
*******************************************************************************/
static void flash_ucb_program_count(uint32_t count)
{
/* Data array */
uint32_t data[XMC_FLASH_WORDS_PER_PAGE] = {count, 0};
/* Erase Flash Sector 8 */
XMC_FLASH_EraseSector(XMC_FLASH_SECTOR_8);
/* Program Flash Sector 8 */
XMC_FLASH_ProgramPage(XMC_FLASH_SECTOR_8, data);
}
/*******************************************************************************
* Function Name: flash_get_ucb_program_count
********************************************************************************
* Summary:
* This function retrieves the UCB program count stored in flash sector 8
*
* Parameters:
* none
*
* Return:
* uint32_t address
*
*******************************************************************************/
static uint32_t flash_get_ucb_program_count()
{
/* Point to XMC_FLASH_SECTOR_8 flash address */
const uint32_t *address = XMC_FLASH_SECTOR_8;
return *address;
}
/*******************************************************************************
* Function Name: SystemInit
********************************************************************************
* Summary:
* This function overrides the weak SystemInit function startup_XMC4700.c file.
* It performs a copy of the Chip ID and BMI String during startup from the
* DSRAM1 into arrays and performs some system initializations.
*
* Parameters:
* none
*
* Return:
* void
*
*******************************************************************************/
void SystemInit(void)
{
memcpy(g_chipid, CHIPID_LOC, CHIPID_LEN);
memcpy(g_bmi_string, BMI_STRING_LOC, BMI_STRING_LEN);
SystemCoreSetup();
SystemCoreClockSetup();
}
/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
* This is the main function. It initializes the shell and processes the user
* input for demonstrating flash BMI options like:
* 1. Installing BMI Configuration
* 2. Reading MAC Address from DSRAM1
* 3. Reading USB Serial Number from DSRAM1
* 4. Reading IPv4 Address (LSB) from DSRAM1
* 5. Checking BMI Installation status
*
* Parameters:
* none
*
* Return:
* int
*
*******************************************************************************/
int main(void)
{
cy_rslt_t result;
/* Initialize the device and board peripherals */
result = cybsp_init();
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
/* Initialize retarget-io to use the debug UART port */
retarget_io_init();
/* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
printf("\x1b[2J\x1b[;H");
printf("**************** XMC MCU: Flash BMI *****************\r\n");
/* Initialize the UCB Program counter */
ucb_program_count = flash_get_ucb_program_count();
/* Reset the counter and erase flash sector if invalid counter
* value found in flash
*/
if(ucb_program_count > UCB_PROGRAM_MAX_LIMIT)
{
flash_ucb_program_count(0);
ucb_program_count = 0;
}
/* Initialize shell */
shell_init(shell_cmd_table, initialize_shell);
while(1){
/* Process user input */
shell_process_input();
}
}
/* [] END OF FILE */