2021-11-09 09:54:09 +01:00
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright ( C ) 2021 Martin Beynon < martin . beynon @ abaco . com >
*/
# include <stdio.h>
# include <stdlib.h>
# include <stdint.h>
# include <string.h>
# include <strings.h>
# include <algorithm>
# include <fstream>
# include <iostream>
# include <iterator>
# include <sstream>
# include <utility>
# include <vector>
# include "display.hpp"
# include "feaparser.hpp"
2021-11-11 10:04:50 +01:00
/* FEAbits element defines */
2021-11-19 16:11:02 +01:00
# define FEA_I2C_DG_FIL_EN (1 << 0) /* I2C deglitch filter enable for Primary I2C Port 0=Disabled (Default), 1=Enabled */
2021-11-11 10:04:50 +01:00
# define FEA_FLASH_PROT_SEC_SEL (0x7 << 1) /* Flash Protection Sector Selection */
2021-11-19 16:11:02 +01:00
# define FEA_MY_ASSP_EN (1 << 4) /* MY_ASSP Enabled 0=Disabled (Default), 1=Enabled */
# define FEA_PROG_PERSIST (1 << 5) /* PROGRAMN Persistence 0=Enabled (Default), 1=Disabled */
# define FEA_INITN_PERSIST (1 << 6) /* INITN Persistence 0=Disabled (Default), 1=Enabled */
# define FEA_DONE_PERSIST (1 << 7) /* DONE Persistence 0=Disabled (Default), 1=Enabled */
# define FEA_JTAG_PERSIST (1 << 8) /* JTAG Port Persistence 0=Enabled (Default), 1=Disabled */
# define FEA_SSPI_PERSIST (1 << 9) /* Slave SPI Port Persistence 0=Enabled (Default), 1=Disabled */
# define FEA_I2C_PERSIST (1 << 10) /* I²C Port Persistence 0=Enabled (Default), 1=Disabled */
# define FEA_MSPI_PERSIST (1 << 11) /* Master SPI Port Persistence 0=Disabled (Default), 1=Enabled */
# define FEA_BOOT_SEQ_SEL (0x07 << 12) /* Boot Sequence selection (used along with Master SPI Port Persistence bit) */
2021-11-11 10:04:50 +01:00
# define FEA_I2C_DG_RANGE_SEL (1 << 15) /* I2C deglitch filter range selection on primary I2C port2 0= 8 to 25 ns range (Default) 1= 16 to 50 ns range */
2021-11-19 16:11:02 +01:00
# define FEA_VERSION_RB_PROT (1 << 16) /* Version Rollback Protection1 0= Disabled (Default) 1= Enabled */
# define FEA_RESERVED_ZERO (0xffff << 17)
2021-11-11 10:04:50 +01:00
/* Feature Row element defines */
2021-11-19 16:11:02 +01:00
# define FEATURE_CUSTOM_ID (0xffffffff) /* 32 bits of Custom ID code */
2021-11-11 10:04:50 +01:00
2021-11-19 16:11:02 +01:00
# define FEATURE_TRACE_ID (0xff << 0) /* 8 bits for the user programmable TraceID */
2021-11-11 10:04:50 +01:00
# define FEATURE_I2C_SLAVE_ADDR (0xff << 8) /* 8 bits for the user programmable I2C Slave Address */
# define FEATURE_DUAL_BOOT_ADDR (0xffff << 16) /* 16 bits for Dual boot address (Most significant 16- bit of address for secondary boot from external flash) */
# define FEATURE_MASTER_RETRY_CNT (0x3 << 2) /* Master Retry Count */
# define FEATURE_MASTER_TIMER_CNT (0x0f << 4) /* Master Timer Count */
# define FEATURE_SLAVE_IDLE_TIMER_CNT (0x0f << 8) /* Slave Idle Timer Count */
# define FEATURE_SFDP_CONT_FAIL (1 << 14) /* SFDP Continue on Fail */
2021-11-19 16:11:02 +01:00
# define FEATURE_SFDP_EN (1 << 15) /* SFDP Enable */
2021-11-11 10:04:50 +01:00
# define FEATURE_BULK_ERASE_DISABLE (1 << 16) /* No Bulk Erase */
# define FEATURE_32BIT_SPIM (1 << 17) /* 32-bit SPIM */
# define FEATURE_MCLK_BYPASS (1 << 18) /* MCLK Bypass */
2021-11-19 16:11:02 +01:00
# define FEATURE_LSBF (1 << 19) /* LSBF */
# define FEATURE_RX_EDGE (1 << 20)
# define FEATURE_TX_EDGE (1 << 21)
# define FEATURE_CPOL (1 << 22)
# define FEATURE_CPHA (1 << 23)
2021-11-11 10:04:50 +01:00
# define FEATURE_HSE_CLOCK_SEL (0x3 << 24)
# define FEATURE_EBR_ENABLE (1 << 26)
2021-11-19 16:11:02 +01:00
# define FEATURE_SSPI_AUTO (1 << 28) /* SSPI Auto */
# define FEATURE_CPU (1 << 29) /* CPU */
2021-11-11 10:04:50 +01:00
# define FEATURE_CORE_CLK_SEL (0x03 << 30) /* Core Clock Sel */
2021-11-09 09:54:09 +01:00
using namespace std ;
FeaParser : : FeaParser ( string filename , bool verbose ) :
ConfigBitstreamParser ( filename , ConfigBitstreamParser : : BIN_MODE , verbose ) ,
_feabits ( 0 ) , _has_feabits ( false )
{
2021-11-11 10:04:50 +01:00
for ( int i = 0 ; i < 3 ; i + + )
_featuresRow [ i ] = 0 ;
2021-11-09 09:54:09 +01:00
}
/* fill a vector with consecutive lines, begining with 0 or 1, until EOF
* \ brief read a line with ' \r ' ' \n ' or ' \n ' termination
* check if last char is ' \r '
* \ return a vector of lines without [ \ r ] \ n
*/
vector < string > FeaParser : : readFeaFile ( )
{
vector < string > lines ;
while ( true ) {
2021-11-11 10:04:50 +01:00
string buffer ;
2021-11-09 09:54:09 +01:00
std : : getline ( _ss , buffer , ' \n ' ) ;
2021-11-11 10:04:50 +01:00
if ( buffer . empty ( ) )
2021-11-09 09:54:09 +01:00
break ;
/* if '\r' is present -> drop */
if ( buffer . back ( ) = = ' \r ' )
buffer . pop_back ( ) ;
if ( buffer . front ( ) = = ' 0 ' | | buffer . front ( ) = = ' 1 ' )
2021-11-11 10:04:50 +01:00
lines . push_back ( buffer ) ;
2021-11-09 09:54:09 +01:00
}
2021-11-11 10:04:50 +01:00
return lines ;
2021-11-09 09:54:09 +01:00
}
void FeaParser : : displayHeader ( )
{
if ( _has_feabits ) {
2021-11-11 10:04:50 +01:00
printf ( " \n Feature Row: [0x " ) ;
for ( int i = 2 ; i > = 0 ; i - - ) {
printf ( " %08x " , _featuresRow [ i ] ) ;
}
printf ( " ] \n " ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t Core Clock Select : 0x%x \n " , ( _featuresRow [ 2 ] > > 30 ) & 0x03 ) ;
printf ( " \t CPU : %d \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_CPU ) ? 1 : 0 ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t SSPI Auto : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_SSPI_AUTO ) ? " Enabled " : " Disabled " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t Reserved Zero (1) : 0x%x \n " , ( _featuresRow [ 2 ] > > 27 ) & 0x01 ) ;
printf ( " \t EBR Enable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_EBR_ENABLE ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t HSE Clock Select : 0x%x \n " , ( _featuresRow [ 2 ] > > 24 ) & 0x03 ) ;
printf ( " \t CPHA : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_CPHA ) ? " Enabled " : " Disabled " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t CPOL : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_CPOL ) ? " Enabled " : " Disabled " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t Tx Edge : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_TX_EDGE ) ? " Enabled " : " Disabled " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t Rx Edge : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_RX_EDGE ) ? " Enabled " : " Disabled " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t LSBF : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_LSBF ) ? " Enabled " : " Disabled " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t MClock Bypass : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_MCLK_BYPASS ) ? " Enabled " : " Disabled " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t 32-bit SPIM : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_32BIT_SPIM ) ? " Enabled " : " Disabled " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t Bulk Erase Disable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_BULK_ERASE_DISABLE ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t SFDP Enable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_SFDP_EN ) ? " Yes " : " No " ) ) ;
2021-11-11 10:04:50 +01:00
printf ( " \t SFDP Continue on Fail : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _featuresRow [ 2 ] & FEATURE_SFDP_CONT_FAIL ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t Reserved Zero (2) : 0x%x \n " , ( _featuresRow [ 2 ] > > 12 ) & 0x03 ) ;
2021-11-11 10:04:50 +01:00
printf ( " \t Slave Idle Timer Count: %d \n " , ( _featuresRow [ 2 ] > > 8 ) & 0x0f ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t Master Timer Count : %d \n " , ( _featuresRow [ 2 ] > > 4 ) & 0x0f ) ;
printf ( " \t Master Retry Count : %d \n " , ( _featuresRow [ 2 ] > > 2 ) & 0x03 ) ;
printf ( " \t Reserved Zero (2) : 0x%x \n " , _featuresRow [ 2 ] & 0x03 ) ;
2021-11-09 09:54:09 +01:00
2021-11-19 16:11:02 +01:00
printf ( " \t Dual Boot Address : 0x%x \n " , ( _featuresRow [ 1 ] > > 16 ) & 0xffff ) ;
printf ( " \t I2C Slave Address : 0x%x \n " , ( _featuresRow [ 1 ] > > 8 ) & 0xff ) ;
printf ( " \t Custom Trace ID : 0x%x \n " , _featuresRow [ 1 ] & 0xff ) ;
printf ( " \t Custom ID Code : 0x%x \n " , _featuresRow [ 0 ] ) ;
2021-11-09 09:54:09 +01:00
printf ( " \n FEAbits: [0x%08x] \n " , _feabits ) ;
2021-11-11 10:04:50 +01:00
printf ( " \t Reserved Zero (16) : 0x%x \n " , ( _feabits > > 17 ) & 0xffff ) ;
printf ( " \t Rollback Protection : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_VERSION_RB_PROT ) ? " Enabled " : " Disabled " ) ) ;
2021-11-11 10:04:50 +01:00
printf ( " \t I2C Deglitch Range : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_I2C_DG_RANGE_SEL ) ? " (1) 16 to 50 ns " : " (0) 8 to 25 ns " ) ) ;
2021-11-11 10:04:50 +01:00
int boot_mode = ( _feabits > > 12 ) & 0x07 ;
2021-11-19 16:11:02 +01:00
printf ( " \t Boot Mode : " ) ;
2021-11-11 10:04:50 +01:00
if ( ( _feabits & FEA_MSPI_PERSIST ) = = 0 ) {
if ( boot_mode = = 0 )
printf ( " Dual Boot, CFG0 - CFG1 \n " ) ;
else if ( boot_mode = = 1 )
printf ( " Dual Boot, CFG1 - CFG0 \n " ) ;
else if ( boot_mode = = 3 )
printf ( " Single Boot, CFG0 \n " ) ;
else if ( boot_mode = = 4 )
printf ( " Single Boot, CFG1 \n " ) ;
else if ( boot_mode = = 5 )
printf ( " Dual Boot, Boot from former bitstream first \n " ) ;
else if ( boot_mode = = 7 )
printf ( " Dual Boot, Boot from latter bitstream first \n " ) ;
else if ( ( boot_mode & 0x03 ) = = 2 )
printf ( " Dual Boot, No Boot \n " ) ;
else
printf ( " Unknown boot sequence selection " ) ;
} else {
if ( boot_mode = = 0 )
printf ( " Dual Boot, CFG0 - Ext \n " ) ;
else if ( ( boot_mode & 0x03 ) = = 1 )
printf ( " Single Boot, Ext \n " ) ;
else if ( boot_mode = = 2 )
printf ( " Dual Boot, Ext - CFG0 \n " ) ;
else if ( ( boot_mode & 0x03 ) = = 3 )
printf ( " Dual Boot, Ext - Ext \n " ) ;
else if ( boot_mode = = 4 )
printf ( " Dual Boot, CFG1 - Ext \n " ) ;
else if ( boot_mode = = 6 )
printf ( " Dual Boot, Ext - CFG1 \n " ) ;
else
printf ( " Unknown boot sequence selection " ) ;
}
2021-11-19 16:11:02 +01:00
printf ( " \t MSPI Enable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_MSPI_PERSIST ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t I2C Disable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_I2C_PERSIST ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t SSPI Disable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_SSPI_PERSIST ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t JTAG Disable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_JTAG_PERSIST ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t DONE Enable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_DONE_PERSIST ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t INIT Enable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_INITN_PERSIST ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t PROGRAM Disable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_PROG_PERSIST ) ? " Yes " : " No " ) ) ;
2021-11-19 16:11:02 +01:00
printf ( " \t Custom ID Enable : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_MY_ASSP_EN ) ? " Yes " : " No " ) ) ;
2021-11-11 10:04:50 +01:00
int flash_prot = ( _feabits > > 1 ) & 0x07 ;
2021-11-19 16:11:02 +01:00
printf ( " \t Flash Protection : " ) ;
2021-11-11 10:04:50 +01:00
if ( flash_prot = = 0 ) {
printf ( " None \n " ) ;
} else {
if ( flash_prot & 0x04 )
printf ( " CFG0 & CFG1 " ) ;
if ( flash_prot & 0x02 )
printf ( " Feature, Security Keys " ) ;
if ( flash_prot & 0x01 )
printf ( " All UFMs " ) ;
printf ( " \n " ) ;
}
printf ( " \t I2C Deglitch Filter : %s \n " ,
2021-11-09 09:54:09 +01:00
( ( _feabits & FEA_I2C_DG_FIL_EN ) ? " Enabled " : " Disabled " ) ) ;
}
}
/* Features Row & Feabits - this data is in a separate .fea file (MachXO3D)
* DATA :
* 1 : xxxx \ n : feature Row ( 96 bits )
* 2 : yyyy * \ n : feabits ( 32 bits )
*/
void FeaParser : : parseFeatureRowAndFeabits ( const vector < string > & content )
{
2021-11-11 10:04:50 +01:00
printf ( " Parsing Feature Row & FEAbits... \n " ) ;
2021-11-09 09:54:09 +01:00
string featuresRow = content [ 0 ] ;
//printf("Features: [%s]\n", featuresRow.c_str());
for ( size_t i = 0 ; i < featuresRow . size ( ) ; i + + )
_featuresRow [ 3 - ( i / 32 ) - 1 ] | = ( ( featuresRow [ i ] - ' 0 ' ) < < ( 32 - ( i % 32 ) - 1 ) ) ;
string feabits = content [ 1 ] ;
2021-11-11 10:04:50 +01:00
//printf("Feabits: [%s]\n", feabits.c_str());
2021-11-09 09:54:09 +01:00
_feabits = 0 ;
for ( size_t i = 0 ; i < feabits . size ( ) ; i + + ) {
_feabits | = ( ( feabits [ i ] - ' 0 ' ) < < ( feabits . size ( ) - i - 1 ) ) ;
}
}
int FeaParser : : parse ( )
{
std : : vector < string > lines ;
2021-11-19 16:11:02 +01:00
_ss . str ( _raw_data ) ;
2021-11-09 09:54:09 +01:00
2021-11-11 10:04:50 +01:00
lines = readFeaFile ( ) ;
/* empty or end of file */
if ( lines . size ( ) > 0 ) {
parseFeatureRowAndFeabits ( lines ) ;
_has_feabits = true ;
}
2021-11-09 09:54:09 +01:00
return EXIT_SUCCESS ;
}