Need help in fixing Arm Mbed C++ Program Error

Hi JohnnyK,
Thank you for the information.

Is there a way to have pdf files of these Mbed OS help docs please?
Thanks,

I do not know about nothing actual and if something exist, it is not done by Mbed, but someone else, usually a teacher of a school for his students. I use only online documentation with Mbed github repo.

BR, Jan

Thank you very much for your excellent Hiden Code just with main loop in your prior reply earlier.
I need your help in using ShiftOut class please, in the following main.cpp I am getting compile error:

#include "mbed.h"
#include <iostream>
#include <string>
#include <map>
#include <tuple>

#include "ShiftOut.h"

using std::map;
using std::pair;
using std::string;
using std::tuple;

typedef pair<int, int> pair_key;
typedef tuple<int, int, int> tuple_vals;
typedef map< pair<int, int>, tuple<int, int, int> > pair_tuple_map_type;

pair_tuple_map_type lookup_pins
{       // Brd, BNK, srclk, rclk, ser_data
        {   {1,0}, {(PD_13), (PD_12),  (PE_15)}     },  { {1,1}, {(PD_13), (PD_12),  (PF_13)} },
        {   {2,0}, {(PD_14), (PD_15),  (PF_14)}     },  { {2,1}, {(PD_14), (PD_15),  (PF_15)} },
};

UnbufferedSerial uartUsb(USBTX, USBRX, 115200);

enum Speed{
    None = 0,
    Slow = 1,
    Fast = 2
};

volatile Speed speed = None;

void uartTask();
void onSerialRx();
void serial_str_write( const char* str );
void serial_int_write( const int x );
void show_menu();
void reset_to_slow();
void set_to_fast();

PwmOut pwm_clk();
PwmOut pwm_pulse();

DigitalOut ser0();
DigitalOut ser1();
//ShiftOut reg();



int main()
{
    uartUsb.attach(&onSerialRx);
    serial_str_write("\n"); show_menu();

    while (true) {
        if(speed != None){
            switch (speed)
            {
                case Slow:  reset_to_slow();    break;
                case Fast:  set_to_fast();      break;
                default:                        break;
            }
            show_menu(); 
            speed = None;
        }

    }
}

void onSerialRx()
{
    char chIn;
    if (uartUsb.readable())
    {
        uartUsb.read( &chIn, 1 );
        switch (chIn)
        {
            case 'x': case 'X': if(speed == None) speed = Fast; break;
            case 'y': case 'Y': if(speed == None) speed = Slow; break;
            default: 
                    
                break;
        }
    }
}

void reset_to_slow()
{

    serial_str_write("\n");
    serial_str_write( "Resetting to slow:\r\n" );
}

void set_to_fast()
{
    serial_str_write("\n");     serial_str_write( "Setting to fast:\n" );

    for (const auto &lookup_row : lookup_pins)
    {
        auto key_pair = lookup_row.first;
        auto [srclk, rclk, ser_data] = lookup_row.second;

        PwmOut pwm_clk((PinName)srclk);     PwmOut pwm_pulse((PinName)rclk);
        DigitalOut ser_pin((PinName)ser_data);

        pwm_clk.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_clk.write(0.50f); // duty cycle 0.5 or 50% or 1 second

        pwm_pulse.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_pulse.pulsewidth_ms(1.0f); // pulse width 1 milli second

        // ShiftOut(PinName ser, PinName srclk, PinName rclk);
        ShiftOut reg(ser_pin, pwm_clk, pwm_pulse);

        for (int i = 0; i < 5; i++)
        {
            reg.writeByte(0xFF);
            wait_us(20000.0);
        }  
        reg.updateOutput();
        wait_us(20000.0);
/*
        static auto map_vals = lookup_row.second;   static int sr = get<0>(map_vals);
        static int rc = get<1>(map_vals);           static int s0 = get<2>(map_vals);
*/
        /* serial_str_write("\n"); */   serial_str_write( "Sr: " );    serial_int_write(srclk);  serial_str_write("\n"); 
        /* serial_str_write("\n"); */   serial_str_write( "Rc: " );    serial_int_write(rclk);  serial_str_write("\n"); 
        /* serial_str_write("\n"); */   serial_str_write( "S0: " );    serial_int_write(ser_data);  serial_str_write("\n");
    }
}


void serial_int_write( const int x )
{
    char buffer[20];

    sprintf(buffer, "%d", x);
    uartUsb.write( buffer, strlen(buffer) );
}



void serial_str_write( const char* str )
{
    uartUsb.write( str, strlen(str) );
}

void show_menu()
{
    serial_str_write("\nType X to LED ON\n");
    serial_str_write("Type Y to LED OFF\n");   
}

set_to_fast function of above program is giving compile error on one line of code of ShiftOut constructor call.

I need your help in fixing this compile error on line 114 please.

Best regards.

Below screen capture is showing the errors:

Yeah, your code is wrong - object types.
Look these lines of your code

        PwmOut pwm_clk((PinName)srclk);    
        PwmOut pwm_pulse((PinName)rclk);
        DigitalOut ser_pin((PinName)ser_data);
        //-----------------------------------//
        // ShiftOut(PinName ser, PinName srclk, PinName rclk);
        ShiftOut reg(ser_pin, pwm_clk, pwm_pulse);

The comented line tell you the constructor need 3 parametrs of PinName type. And object what you used are PwmOut and DigitalOut. That is what compiler not want accept it.

I am not sure what is the goal but probably

ShiftOut reg((PinName)ser_data, (PinName)srclk, (PinName)rclk);

BR, Jan

Hi JohnnyK,
Many, many thanks for your excellent help and information.

I am adding more code/features to the program.

Thanks and best regards,

Hi JohnnyK,
Following program is giving
SIGABRT Abnormal termination error.

Can you please help in let me know how to fix this abnormal error?

Thanks and best regards,

Welcome to ATG Lens Antenna Micro-Controller Commands Program:

Available Commands:

Press 'R' to Reset all 40 GPIO Pins:
Press 'S' to Set all 40 GPIO Pins:
Press 'H' to See list of Available Commands:

Type HEX sting of length of 12 Hex digits (For example, 8F0F0F0F0Fc3) 
by Typing  0 to F  HEX chars followed by Enter key:
8F0F0F0F0FC3

Pressed Enter Key



Inside parse_hex_fcps function. 

12

8F0F0F0F0FC3
HEX


SR_BNK : 1



PA_BRD : 3



 Input Hex String : 8F0F0F0F0FC3



 FCPS Hex String : 1E1E1E1E1F

stoi: no conversion

SIGABRT: Abnormal termination

Above Abnormal termination error is caused by the following program:

Please let me know of the code line that is causing error and how to fix?

Thanks,

#include "mbed.h"
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <tuple>

#include "ShiftOut.h"


// #define GPIO_STR_LEN    40
// #define GPIO_STR_BYTES   6 
#define GPIO_HEX_STR_DIGITS 12
#define GPIO_HEX_STR_BYTES  6

using std::map;
using std::pair;
using std::string;
using std::tuple;

typedef pair<int, int> PairKey;
typedef tuple<int, int, int> TupleVals;
typedef map< pair<int, int>, tuple<int, int, int> > Pair_tuple_map_type;

Pair_tuple_map_type lookup_pins
{       // Brd, BNK, srclk, rclk, ser_data
        {   {1,0}, {(PD_13), (PD_12),  (PE_15)}     },  { {1,1}, {(PD_13), (PD_12),  (PF_13)} },
        {   {2,0}, {(PD_14), (PD_15),  (PF_14)}     },  { {2,1}, {(PD_14), (PD_15),  (PF_15)} },
        {   {3,0}, {(PE_9), (PE_11),  (PG_5)}       },  { {3,1}, {(PE_9), (PE_11),  (PG_6)}   },
        {   {4,0}, {(PE_13), (PE_14),  (PF_12)}     },  { {4,1}, {(PE_13), (PE_14),  (PD_10)} }

};

UnbufferedSerial uart_USB(USBTX, USBRX, 115200);

char serialInBuf[GPIO_HEX_STR_DIGITS+1];
int  serialCount;

enum Set_reset_GPIO
{
    None = 0,
    Reset_GPIO = 1,
    Set_GPIO = 2,
    Help = 3,
    Parse_FCPS = 4
};

volatile Set_reset_GPIO set_reset = None;

void uartTask();
void onSerialRx();
static void serial_ch_write( char chr );
void serial_str_write( const char* str );
void serial_int_write( const int x );
void parse_hex_fcps();
void parse_hex_brd_bnk( const string serialInHexBuf);
bool extract_FCPS( char *input_hex, char *output_hex );
void show_menu();
void reset_to_off();
void set_to_on();
int hex_to_dec(std::string s);
void setHexGPIOpins(char* serialInHexBuf, const string inHexBuf );

PwmOut pwm_clk();
PwmOut pwm_pulse();

DigitalOut ser0();
DigitalOut ser1();
//ShiftOut reg();

int main()
{
    uart_USB.attach(&onSerialRx);
    serial_str_write("\n"); show_menu();

    while (true) {
        if(set_reset != None){
            switch (set_reset)
            {
                case Reset_GPIO:  reset_to_off();           
                    break;
                case Set_GPIO:  set_to_on();                
                    break;
                case Help: break;
                case Parse_FCPS:  parse_hex_fcps();     
                    break;
                default:                        
                    break;
            }
            show_menu(); 
            set_reset = None;
        }
    }
}

void onSerialRx()
{
//    static char serialInBuf[GPIO_STR_LEN];
//    static char serialInHexBuf[GPIO_HEX_STR_DIGITS+1];

    char chIn;
    if (uart_USB.readable())
    {
        uart_USB.read( &chIn, 1 );
        switch (chIn)
        {
            
            case '0': case '1': case '2': case '3': case '4': case '5':
            case '6': case '7': case '8': case '9': 
            case 'A': case 'B': case 'C': case 'D': case 'E':  case 'F':
            case 'a': case 'b': case 'c': case 'd': case 'e':  case 'f':
                serialInBuf[serialCount] = chIn;
                if (serialCount < GPIO_HEX_STR_DIGITS)
                    serialCount++;
                serial_ch_write(chIn);
                break;

            case 'h': case 'H': if(set_reset == None) set_reset = Help; break;
            case 's': case 'S': if(set_reset == None) set_reset = Set_GPIO; break;
            case 'r': case 'R': if(set_reset == None) set_reset = Reset_GPIO; break;
            case '\r':  
                serial_str_write("\n\nPressed Enter Key\n\n"); 


                if(set_reset == None) set_reset = Parse_FCPS; 
            
                break;
 /*                    
                serialInBuf[serialCount] = 0;
                serial_int_write(serialCount);

                if (GPIO_HEX_STR_DIGITS == serialCount)
                {
                    // gotPacket = true;
                    serial_str_write( "\r\n\n" );
                    serial_str_write(serialInBuf); 
                    serial_str_write( "\r\nHEX\n" );

                    // setHexGPIOpins(serialInBuf);
                    
                    // map_pa_brd_sr_bank(serialInBuf);
                    // lookup_GPIO();
                    // parse_hex_sr_bnk_pa_brd(serialInBuf);

                    serialCount = 0;
                }
                else 
                {
                    serial_str_write( "\r\nNo HEX  string Input\r\n" ); 
                    serial_str_write(serialInBuf); 
                    show_menu(); 
                }
*/

            default: 
                show_menu();                     
                break;
        }
    }
}

void parse_hex_fcps()
{
    serial_str_write("\n\nInside parse_hex_fcps function. \n\n"); 
    serialInBuf[serialCount] = 0;
    serial_int_write(serialCount);

    if (GPIO_HEX_STR_DIGITS == serialCount)
    {
        serial_str_write( "\r\n\n" );
        serial_str_write(serialInBuf); 
        serial_str_write( "\r\nHEX\n" );

        parse_hex_brd_bnk(serialInBuf);

        char output_hex_str[11];
        extract_FCPS(serialInBuf, output_hex_str);

        serial_str_write("\r\n\n Input Hex String : ");
        serial_str_write(serialInBuf);
        serial_str_write("\r\n\n");

        serial_str_write("\r\n\n FCPS Hex String : ");
        serial_str_write(output_hex_str);    

        serial_str_write("\r\n\n");

        setHexGPIOpins(output_hex_str, string(output_hex_str) );


        // setHexGPIOpins(serialInBuf);
                    
        // map_pa_brd_sr_bank(serialInBuf);
        // lookup_GPIO();
        // parse_hex_sr_bnk_pa_brd(serialInBuf);

        serialCount = 0;
    }
    else 
    {
        serial_str_write( "\r\nNo HEX  string Input\r\n" ); 
        serial_str_write(serialInBuf); 
        serialCount = 0;
        show_menu(); 
    }
}

void parse_hex_brd_bnk( const string serialInHexBuf)
{
    int i = std::stoi( serialInHexBuf.substr( 10, 2 ), 0, 16 );
    int sr_bnk = ( i >> 6 ) & 1;
    int pa_brd = i & 63;

    serial_str_write("\r\n\nSR_BNK : ");
    serial_int_write(sr_bnk);
    serial_str_write("\r\n\n");

    serial_str_write("\r\n\nPA_BRD : ");
    serial_int_write(pa_brd);
    serial_str_write("\r\n\n");
}

// remove left most 1 bit and right most 7 bits
bool extract_FCPS( char *input_hex, char *output_hex )
{
    // 0. preliminary stuff
    constexpr std::size_t NBITSULL = std::numeric_limits<unsigned long long>::digits ;
    static_assert( NBITSULL >= 48, "we need at least 48 bits " ) ; // sanity check
    constexpr std::size_t EXTRA_BITS = NBITSULL - 48 ; // bits in excess of 48

    // 1. convert the input hex string into an unsigned long long integer
    unsigned long long value = std::strtoull( input_hex, nullptr, 16 ) ;

    value <<= ( 1 + EXTRA_BITS ) ; value >>= ( 1 + EXTRA_BITS ) ; // 2. knock off the leftmost bit of the 48 bits

    value >>= 7U ; // 3. knock off the rightmost 7 bits

    // convert the resultant 40-bit value to 10 hex digits
    std::sprintf( output_hex, "%010llX", value ) ;

    return true ; // TO DO: add validation, return false on failure
}


void reset_to_off()
{
    for (const auto &lookup_row : lookup_pins)
    {
        auto key_pair = lookup_row.first;
        auto [srclk, rclk, ser_data] = lookup_row.second;

        PwmOut pwm_clk((PinName)srclk);     PwmOut pwm_pulse((PinName)rclk);
        DigitalOut ser_pin((PinName)ser_data);

        pwm_clk.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_clk.write(0.50f); // duty cycle 0.5 or 50% or 1 second

        pwm_pulse.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_pulse.pulsewidth_ms(1.0f); // pulse width 1 milli second

        // ShiftOut(PinName ser, PinName srclk, PinName rclk);
        ShiftOut reg((PinName)ser_data, (PinName)srclk, (PinName)rclk);

        for (int i = 0; i < 5; i++)
        {
            reg.writeByte(0x00);    wait_us(20000.0);    reg.updateRegister();    wait_us(20000.0);
        }
        
        reg.updateOutput();   wait_us(20000.0);
    }
}

void setHexGPIOpins(char* serialInHexBuf, const string inHexBuf )
{
    char byte_str[3];
    int hex_byte;

    int i = std::stoi( inHexBuf.substr( 10, 2 ), 0, 16 );
    int sr_bnk = ( i >> 6 ) & 1;
    int pa_brd = i & 63;


    for (const auto &lookup_row : lookup_pins)
    {
        auto key_pair = lookup_row.first;
        auto [srclk, rclk, ser_data] = lookup_row.second;

        if (key_pair.first == pa_brd && key_pair.second == sr_bnk)
        {
            PwmOut pwm_clk((PinName)srclk);     PwmOut pwm_pulse((PinName)rclk);
            DigitalOut ser_pin((PinName)ser_data);

            pwm_clk.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
            pwm_clk.write(0.50f); // duty cycle 0.5 or 50% or 1 second

            pwm_pulse.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
            pwm_pulse.pulsewidth_ms(1.0f); // pulse width 1 milli second

            // ShiftOut(PinName ser, PinName srclk, PinName rclk);
            ShiftOut reg((PinName)ser_data, (PinName)srclk, (PinName)rclk);

            for (int i = GPIO_HEX_STR_DIGITS - 1; i >= 1; i = i - 2)
            {
                byte_str[0] = serialInHexBuf[i-1];    byte_str[1] = serialInHexBuf[i];  byte_str[2] = '\0';  

                hex_byte = hex_to_dec(byte_str);    reg.writeByte(hex_byte);   wait_us(20000.0);
            }

            reg.updateOutput();    wait_us(20000.0);
        }
    }
}

void set_to_on()
{
    for (const auto &lookup_row : lookup_pins)
    {
        auto key_pair = lookup_row.first;
        auto [srclk, rclk, ser_data] = lookup_row.second;

        PwmOut pwm_clk((PinName)srclk);     PwmOut pwm_pulse((PinName)rclk);
        DigitalOut ser_pin((PinName)ser_data);

        pwm_clk.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_clk.write(0.50f); // duty cycle 0.5 or 50% or 1 second

        pwm_pulse.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_pulse.pulsewidth_ms(1.0f); // pulse width 1 milli second

        // ShiftOut(PinName ser, PinName srclk, PinName rclk);
        ShiftOut reg((PinName)ser_data, (PinName)srclk, (PinName)rclk);

        for (int i = 0; i < 5; i++)
        {
            reg.writeByte(0xFF);
            wait_us(20000.0);
        }  
        reg.updateOutput();
        wait_us(20000.0);
    }
}

int hex_to_dec(std::string s)
{
    std::stringstream ss(s);
    int i;

    ss >> std::hex >> i;
    return i;
}


void serial_int_write( const int x )
{
    char buffer[20];

    sprintf(buffer, "%d", x);
    uart_USB.write( buffer, strlen(buffer) );
}

void serial_str_write( const char* str )
{
    uart_USB.write( str, strlen(str) );
}


static void serial_ch_write( char chr )
{
    char str[2] = "";
    sprintf (str, "%c", chr);
    uart_USB.write( str, strlen(str) );
}

void show_menu()
{
    // serial_str_write("\nType S to LED ON\n");
    // serial_str_write("Type R to LED OFF\n");   
    serial_str_write( "\n\nWelcome to ATG Lens Antenna Micro-Controller Commands Program:\r\n\n" );
    serial_str_write( "Available Commands:\r\n\n" );

    serial_str_write( "Press 'R' to Reset all 40 GPIO Pins:\n" );
    serial_str_write( "Press 'S' to Set all 40 GPIO Pins:\n" );
 
    serial_str_write( "Press 'H' to See list of Available Commands:\n\n" );

    serial_str_write( "Type HEX sting of length of 12 Hex digits (For example, 8F0F0F0F0Fc3) \n");
    serial_str_write( "by Typing  0 to F  HEX chars followed by Enter key:\n");
}


Please help me in finding and fixing about abnormal termination error.

The stoi function is causing abnormal termination error.

Thanks and best regards,

You probably need to secure the stoi will never failed, maybe like this - isdigit - C++ Reference (cplusplus.com)

BR, Jan

Hi JohnnyK,
Many, many thanks for the information.
I found another alternate function instead of stoi function.
I am testing the code.
I will let you know more information after some time.

Again, thank you very much for your help.

Best regards,

I need help about “how to steps” of debugging Arm Mbed C++ program please.

I want to see value of byte char input parameter and
I kept break point in the following ShiftOut::writeByte function of ShiftOut.cpp on the line

hasChanged = true;

of the function :

//Writes a byte to the shift register
void ShiftOut::writeByte(unsigned char byte){
   
    hasChanged = true;
    for(int i = 0; i<8*REGISTER_CNT; i++){
        DSERIAL = (byte & 0x01<<i)>>i;

        updateRegister();    
    } 
//    updateOutput();   
}

Above writeByte function is called by setHexGPIOpins function of main_lens_fcps.cpp shown below:

void setHexGPIOpins(char* serialInHexBuf, const string inHexBuf )
{
    char byte_str[3];
    int hex_byte;

    // int i = std::stoi( inHexBuf.substr( 10, 2 ), 0, 16 );

    unsigned long i = strtoul( inHexBuf.substr( 10, 2 ).c_str(), 0, 16 );
    int sr_bnk = ( i >> 6 ) & 1;
    int pa_brd = i & 63;

    serial_str_write("\nSR_BNK : ");
    serial_int_write(sr_bnk);
    serial_str_write("\n");

    serial_str_write("\nPA_BRD : ");
    serial_int_write(pa_brd);
    serial_str_write("\n");

    for (const auto &lookup_row : lookup_pins)
    {
        auto key_pair = lookup_row.first;
        auto [srclk, rclk, ser_data] = lookup_row.second;



        if (key_pair.first == pa_brd && key_pair.second == sr_bnk)
        {
            PwmOut pwm_clk((PinName)srclk);     PwmOut pwm_pulse((PinName)rclk);
            DigitalOut ser_pin((PinName)ser_data);

            pwm_clk.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
            pwm_clk.write(0.50f); // duty cycle 0.5 or 50% or 1 second

            pwm_pulse.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
            pwm_pulse.pulsewidth_ms(1.0f); // pulse width 1 milli second

            // ShiftOut(PinName ser, PinName srclk, PinName rclk);
            ShiftOut reg((PinName)ser_data, (PinName)srclk, (PinName)rclk);
                serial_str_write("\n(PinName)ser_data : ");
                serial_int_write((PinName)ser_data);
                serial_str_write("\n");
               serial_str_write("\nser_data : ");
                serial_int_write(ser_data);
                serial_str_write("\n");

            for (int i = FCPS_HEX_STR_DIGITS - 1; i >= 1; i = i - 2)
            {
                byte_str[0] = serialInHexBuf[i-1];    byte_str[1] = serialInHexBuf[i];  byte_str[2] = '\0';  
                serial_str_write( "\nFCPS BYTE STR " ); 
                serial_str_write(byte_str); 

                hex_byte = hex_to_dec(byte_str);    
                
                serial_str_write("\nHex Byte : ");
                serial_int_write(hex_byte);
                serial_str_write("\n");

                reg.writeByte(hex_byte);   
                wait_us(20000.0);
            }

            reg.updateOutput();     
            wait_us(20000.0);
        }
    }
}
 

I will post the three files main_lens_fcps.cpp, ShiftOut.cpp and ShiftOut.h next

Following is main_lens_fcps.cpp

#include "mbed.h"
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <tuple>

#include "ShiftOut.h"


// #define GPIO_STR_LEN    40
// #define GPIO_STR_BYTES   6 
#define GPIO_HEX_STR_DIGITS 12
#define GPIO_HEX_STR_BYTES  6

#define FCPS_HEX_STR_DIGITS 12
#define FCPS_HEX_STR_BYTES  6

using std::map;
using std::pair;
using std::string;
using std::tuple;

typedef pair<int, int> PairKey;
typedef tuple<int, int, int> TupleVals;
typedef map< pair<int, int>, tuple<int, int, int> > Pair_tuple_map_type;

Pair_tuple_map_type lookup_pins
{       // Brd, BNK, srclk, rclk, ser_data
        {   {1,0}, {(PD_13), (PD_12),  (PE_15)}     },  { {1,1}, {(PD_13), (PD_12),  (PF_13)} },
        {   {2,0}, {(PD_14), (PD_15),  (PF_14)}     },  { {2,1}, {(PD_14), (PD_15),  (PF_15)} },
        {   {3,0}, {(PE_9), (PE_11),  (PG_5)}       },  { {3,1}, {(PE_9), (PE_11),  (PG_6)}   },
        {   {4,0}, {(PE_13), (PE_14),  (PF_12)}     },  { {4,1}, {(PE_13), (PE_14),  (PD_10)} }

};

UnbufferedSerial uart_USB(USBTX, USBRX, 115200);

char serialInBuf[GPIO_HEX_STR_DIGITS+1];
int  serialCount;

enum Set_reset_GPIO
{
    None = 0,
    Reset_GPIO = 1,
    Set_GPIO = 2,
    Help = 3,
    Parse_FCPS = 4
};

volatile Set_reset_GPIO set_reset = None;
static bool hasChanged = false;

void uartTask();
void onSerialRx();
static void serial_ch_write( char chr );
void serial_str_write( const char* str );
void serial_int_write( const int x );
void parse_hex_fcps();
void parse_hex_brd_bnk( const string serialInHexBuf);
bool extract_FCPS( char *input_hex, char *output_hex );
void show_menu();
void reset_to_off();
void set_to_on();
int hex_to_dec(std::string s);
void setHexGPIOpins(char* serialInHexBuf, const string inHexBuf );

PwmOut pwm_clk();
PwmOut pwm_pulse();

DigitalOut ser0();
DigitalOut ser1();
//ShiftOut reg();

int main()
{
    uart_USB.attach(&onSerialRx);
    serial_str_write("\n"); show_menu();

    while (true) {
        if(set_reset != None){
            switch (set_reset)
            {
                case Reset_GPIO:  reset_to_off();           
                    break;
                case Set_GPIO:  set_to_on();                
                    break;
                case Help: break;
                case Parse_FCPS:  parse_hex_fcps();     
                    break;
                default:                        
                    break;
            }
            show_menu(); 
            set_reset = None;
        }
    }
}

void onSerialRx()
{
//    static char serialInBuf[GPIO_STR_LEN];
//    static char serialInHexBuf[GPIO_HEX_STR_DIGITS+1];

    char chIn;
    if (uart_USB.readable())
    {
        uart_USB.read( &chIn, 1 );
        switch (chIn)
        {
            
            case '0': case '1': case '2': case '3': case '4': case '5':
            case '6': case '7': case '8': case '9': 
            case 'A': case 'B': case 'C': case 'D': case 'E':  case 'F':
            case 'a': case 'b': case 'c': case 'd': case 'e':  case 'f':
                serialInBuf[serialCount] = chIn;
                if (serialCount < GPIO_HEX_STR_DIGITS)
                    serialCount++;
                serial_ch_write(chIn);
                break;

            case 'h': case 'H': if(set_reset == None) set_reset = Help; break;
            case 's': case 'S': if(set_reset == None) set_reset = Set_GPIO; break;
            case 'r': case 'R': if(set_reset == None) set_reset = Reset_GPIO; break;
            case '\r':  
                serial_str_write("\n\nPressed Enter Key\n\n"); 


                if(set_reset == None) set_reset = Parse_FCPS; 
            
                break;
            default: 
                show_menu();                     
                break;
        }
    }
}

void parse_hex_fcps()
{
    serial_str_write("\n\nInside parse_hex_fcps function. \n\n"); 
    serialInBuf[serialCount] = 0;
    serial_int_write(serialCount);

    if (GPIO_HEX_STR_DIGITS == serialCount)
    {
        serial_str_write( "\r\n\n" );
        serial_str_write(serialInBuf); 
        serial_str_write( "\r\nHEX\n" );

        parse_hex_brd_bnk(serialInBuf);

        char output_hex_str[11];
        extract_FCPS(serialInBuf, output_hex_str);

        serial_str_write("\r\n\n Input Hex String : ");
        serial_str_write(serialInBuf);
        serial_str_write("\r\n\n");

        serial_str_write("\r\n\n FCPS Hex String : ");
        serial_str_write(output_hex_str);    

        serial_str_write("\r\n\n");

        setHexGPIOpins(output_hex_str, string(serialInBuf) );


        // setHexGPIOpins(serialInBuf);
                    
        // map_pa_brd_sr_bank(serialInBuf);
        // lookup_GPIO();
        // parse_hex_sr_bnk_pa_brd(serialInBuf);

        serialCount = 0;
    }
    else 
    {
        serial_str_write( "\r\nNo HEX  string Input\r\n" ); 
        serial_str_write(serialInBuf); 
        serialCount = 0;
        show_menu(); 
    }
}

void parse_hex_brd_bnk( const string serialInHexBuf)
{
    // int i = std::stoi( serialInHexBuf.substr( 10, 2 ), 0, 16 );

    unsigned long i = strtoul( serialInHexBuf.substr( 10, 2 ).c_str(), 0, 16 );

    int sr_bnk = ( i >> 6 ) & 1;
    int pa_brd = i & 63;

    serial_str_write("\nSR_BNK : ");
    serial_int_write(sr_bnk);
    serial_str_write("\n");

    serial_str_write("\nPA_BRD : ");
    serial_int_write(pa_brd);
    serial_str_write("\n");
}

// remove left most 1 bit and right most 7 bits
bool extract_FCPS( char *input_hex, char *output_hex )
{
    // 0. preliminary stuff
    constexpr std::size_t NBITSULL = std::numeric_limits<unsigned long long>::digits ;
    static_assert( NBITSULL >= 48, "we need at least 48 bits " ) ; // sanity check
    constexpr std::size_t EXTRA_BITS = NBITSULL - 48 ; // bits in excess of 48

    // 1. convert the input hex string into an unsigned long long integer
    unsigned long long value = std::strtoull( input_hex, nullptr, 16 ) ;

    value <<= ( 1 + EXTRA_BITS ) ; value >>= ( 1 + EXTRA_BITS ) ; // 2. knock off the leftmost bit of the 48 bits

    value >>= 7U ; // 3. knock off the rightmost 7 bits

    // convert the resultant 40-bit value to 10 hex digits
    std::sprintf( output_hex, "%010llX", value ) ;

    return true ; // TO DO: add validation, return false on failure
}


void reset_to_off()
{
    for (const auto &lookup_row : lookup_pins)
    {
        auto key_pair = lookup_row.first;
        auto [srclk, rclk, ser_data] = lookup_row.second;

        PwmOut pwm_clk((PinName)srclk);     PwmOut pwm_pulse((PinName)rclk);
        DigitalOut ser_pin((PinName)ser_data);

        pwm_clk.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_clk.write(0.50f); // duty cycle 0.5 or 50% or 1 second

        pwm_pulse.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_pulse.pulsewidth_ms(1.0f); // pulse width 1 milli second

        // ShiftOut(PinName ser, PinName srclk, PinName rclk);
        ShiftOut reg((PinName)ser_data, (PinName)srclk, (PinName)rclk);

        for (int i = 0; i < 5; i++)
        {
            reg.writeByte(0x00);    wait_us(20000.0);    reg.updateRegister();    wait_us(20000.0);
        }
        
        reg.updateOutput();   wait_us(20000.0);
    }
}

void setHexGPIOpins(char* serialInHexBuf, const string inHexBuf )
{
    char byte_str[3];
    int hex_byte;

    // int i = std::stoi( inHexBuf.substr( 10, 2 ), 0, 16 );

    unsigned long i = strtoul( inHexBuf.substr( 10, 2 ).c_str(), 0, 16 );
    int sr_bnk = ( i >> 6 ) & 1;
    int pa_brd = i & 63;

    serial_str_write("\nSR_BNK : ");
    serial_int_write(sr_bnk);
    serial_str_write("\n");

    serial_str_write("\nPA_BRD : ");
    serial_int_write(pa_brd);
    serial_str_write("\n");

    for (const auto &lookup_row : lookup_pins)
    {
        auto key_pair = lookup_row.first;
        auto [srclk, rclk, ser_data] = lookup_row.second;



        if (key_pair.first == pa_brd && key_pair.second == sr_bnk)
        {
            PwmOut pwm_clk((PinName)srclk);     PwmOut pwm_pulse((PinName)rclk);
            DigitalOut ser_pin((PinName)ser_data);

            pwm_clk.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
            pwm_clk.write(0.50f); // duty cycle 0.5 or 50% or 1 second

            pwm_pulse.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
            pwm_pulse.pulsewidth_ms(1.0f); // pulse width 1 milli second

            // ShiftOut(PinName ser, PinName srclk, PinName rclk);
            ShiftOut reg((PinName)ser_data, (PinName)srclk, (PinName)rclk);
                serial_str_write("\n(PinName)ser_data : ");
                serial_int_write((PinName)ser_data);
                serial_str_write("\n");
               serial_str_write("\nser_data : ");
                serial_int_write(ser_data);
                serial_str_write("\n");

            for (int i = FCPS_HEX_STR_DIGITS - 1; i >= 1; i = i - 2)
            {
                byte_str[0] = serialInHexBuf[i-1];    byte_str[1] = serialInHexBuf[i];  byte_str[2] = '\0';  
                serial_str_write( "\nFCPS BYTE STR " ); 
                serial_str_write(byte_str); 

                hex_byte = hex_to_dec(byte_str);    
                
                serial_str_write("\nHex Byte : ");
                serial_int_write(hex_byte);
                serial_str_write("\n");

                reg.writeByte(hex_byte);   
                wait_us(20000.0);
            }

            reg.updateOutput();     
            wait_us(20000.0);
        }
    }
}
 
void set_to_on()
{
    for (const auto &lookup_row : lookup_pins)
    {
        auto key_pair = lookup_row.first;
        auto [srclk, rclk, ser_data] = lookup_row.second;

        PwmOut pwm_clk((PinName)srclk);     PwmOut pwm_pulse((PinName)rclk);
        DigitalOut ser_pin((PinName)ser_data);

        pwm_clk.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_clk.write(0.50f); // duty cycle 0.5 or 50% or 1 second

        pwm_pulse.period(0.1f); // 0.1 second period or 1/0.1 = 10 Hz frequency
        pwm_pulse.pulsewidth_ms(1.0f); // pulse width 1 milli second

        // ShiftOut(PinName ser, PinName srclk, PinName rclk);
        ShiftOut reg((PinName)ser_data, (PinName)srclk, (PinName)rclk);

        for (int i = 0; i < 5; i++)
        {
            reg.writeByte(0xFF);
            wait_us(20000.0);
        }  
        reg.updateOutput();
        wait_us(20000.0);
    }
}

int hex_to_dec(std::string s)
{
    std::stringstream ss(s);
    int i;

    ss >> std::hex >> i;
    return i;
}


void serial_int_write( const int x )
{
    char buffer[20];

    sprintf(buffer, "%d", x);
    uart_USB.write( buffer, strlen(buffer) );
}

void serial_str_write( const char* str )
{
    uart_USB.write( str, strlen(str) );
}


static void serial_ch_write( char chr )
{
    char str[2] = "";
    sprintf (str, "%c", chr);
    uart_USB.write( str, strlen(str) );
}

void show_menu()
{
    serial_str_write( "\n\n\nWelcome to ATG Lens Antenna Micro-Controller Commands Program:\r\n\n" );
    serial_str_write( "Available Commands:\n\n" );

    serial_str_write( "Press 'R' to Reset all 40 GPIO Pins:\n" );
    serial_str_write( "Press 'S' to Set all 40 GPIO Pins:\n" );
 
    serial_str_write( "Press 'H' to See list of Available Commands:\n\n" );

    serial_str_write( "Type HEX sting of length of 12 Hex digits (For example, 8F0F0F0F0Fc3) \n");
    serial_str_write( "by Typing  0 to F  HEX chars followed by Enter key:\n");
}

Following is ShiftOut.cpp

/*
A library for interfacing with the SN74HC595N Shift register. 
Includes functions for writing bits, bytes, animation and bits at spesified positions.
*/


#include "mbed.h"
#include "ShiftOut.h"
 
#define SET_LATCH() (LATCH = 0)
#define RESET_LATCH() (LATCH = 1)
 
#define ENABLE_RESET() (RESET = 0)
#define DISABLE_RESET() (RESET = 1)
 
static char stateArr[8*REGISTER_CNT] = {0};
static bool hasChanged = false;

// Shift register pins
// pin 14 (data in), pin 11 (clock), Pin 12 (rclk/latch pulse), pin 13 (OE output enable), pin 10 
// serial data line, clock, pulse, output enable (ground), reset (latch)  
ShiftOut::ShiftOut(PinName ser, PinName srclk, PinName rclk) : DSERIAL(ser), SRCLK(srclk), RCLK(rclk)
{
    writeByte(0x00); // Reset the values of the registers to 0  
//    if(RESET != NC)
//    {  
//    DISABLE_RESET();
//    }
//        LATCH = 0;
//        RESET = 1;
}
 
//Pulses the register
void ShiftOut::updateRegister(){
    SRCLK = 1;
    wait_us(2);
    SRCLK = 0;    
}
//Updates the output register
void ShiftOut::updateOutput(){
    RCLK = 1;
    wait_us(2);
    RCLK = 0;    
}
//Writes a byte to the shift register
void ShiftOut::writeByte(unsigned char byte){
   
    hasChanged = true;
    for(int i = 0; i<8*REGISTER_CNT; i++){
        DSERIAL = (byte & 0x01<<i)>>i;

        updateRegister();    
    } 
//    updateOutput();   
}

//Writes a bit to the shift register
void ShiftOut::writeBit(unsigned char bit){
    DSERIAL = bit & 0x01;
    updateRegister();
    updateOutput();
    } 
//Writes multiple bits from an array to create an animation
void ShiftOut::animate(int arr[][8], int lines, int delay_ms){
    hasChanged = true;
    for(int i = 0; i < lines; i++){
        for(int j = 0; j < 8; j++){
           writeBit(arr[i][j]); 
        } 
        wait_us(1000.0 * delay_ms);   
    }
}
 
void ShiftOut::animationExample(){
    hasChanged = true;
    int strobe[][8]= {{1,0,0,0,0,0,0,0},
                     {0,1,0,0,0,0,0,0},
                     {0,0,1,0,0,0,0,0},
                     {0,0,0,1,0,0,0,0},
                     {0,0,0,0,1,0,0,0},
                     {0,0,0,0,0,1,0,0},
                     {0,0,0,0,0,0,1,0},
                     {0,0,0,0,0,0,0,1}};
                     
    int nightrider[18][8]= {{1,0,0,0,0,0,0,0},
                           {1,1,0,0,0,0,0,0},
                           {1,1,1,0,0,0,0,0},
                           {0,1,1,1,0,0,0,0},
                           {0,0,1,1,1,0,0,0},
                           {0,0,0,1,1,1,0,0},
                           {0,0,0,0,1,1,1,0},
                           {0,0,0,0,0,1,1,1},
                           {0,0,0,0,0,0,1,1},
                           {0,0,0,0,0,0,0,1},
                           {0,0,0,0,0,0,1,1},
                           {0,0,0,0,0,1,1,1},
                           {0,0,0,0,1,1,1,0},
                           {0,0,0,1,1,1,0,0},
                           {0,0,1,1,1,0,0,0},
                           {0,1,1,1,0,0,0,0},
                           {1,1,1,0,0,0,0,0},
                           {1,1,0,0,0,0,0,0}};
                        
        animate(nightrider, 18, 50);
        wait_us(1e6);
        animate(strobe, 8, 200);
    }
    
void ShiftOut::writeBitAtPos(unsigned char pin, bool state){
    if(hasChanged){
        clearStateArray();
        hasChanged = false;
    } 
    if(pin < 8*REGISTER_CNT){
        stateArr[pin] = state;        
    }
    writeArray(stateArr);
}
 
void ShiftOut::writeArray(char arr[8*REGISTER_CNT]){
    for(int i = (8*REGISTER_CNT)-1; i >= 0; i--) {
        writeBit(arr[i]);
    }       
    
}
 
void ShiftOut::clearStateArray(){
    for(int i = 0; i < 8*REGISTER_CNT; i++){
        stateArr[i] = 0;
        }
    }

Following is ShiftOut.h



// ShiftOut.h
/*
 * Copyright 2015 Benjamin R. Moeklegaard
 *
 * 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.
*/
 
#ifndef SHIFT_H
#define SHIFT_H

#include "mbed.h"
 
//Constant for managing n-numbers of registers, Function supported (writeByte, writeBit, writeBitAtPos)
// #define REGISTER_CNT 1 
#define REGISTER_CNT 1 
/**
 *  This is a library for easy interfacing with the SN74HC595N 8-bit Shift Register.
 *  The library includes functions for writing bits, bytes and animation array to the register.
 *  The Functions are mainly based for writting 8-bits or one byte and can be moddified to work
 *  with multiple shift registers.
 *@code
 * #include "mbed.h"
 * #include "ShiftOut.h"
 * ShiftOut reg(PA_8, PA_9, PC_7, PB_6, D1);
 *
 * int main(){              
 *    while(1){
 *     reg.writeBitAtPos(3, 1);
 *     wait(2);
 *     reg.writeByte(0x30);
 *     wait(2);
 *    }
 * }@endcode
 */
 
class ShiftOut
{
public:
 
    /** Create a ShiftOut interface
      *
      * @param ser      Serial data line
      * @param srclk    Data register clock
      * @param rclk     Output register clock
      * @param oe       Output enable (Active Low)
      * @param reset    Reset line for data register (Active Low)
      * Writing Byte Example:
      * @code
      * #include "mbed.h"
      * #include "ShiftOut.h"
      *
      * ShiftOut reg(PA_8, PA_9, PC_7, PB_6, D1);
      * int main()
      * {
      *     reg.writeByte(0x00); //Writes each bit to the SN74HC595N
      *     while(1) {
      *         wait_ms(300);
      *     }
      * }
      * @endcode
      */
// Shift register pins
// pin 14 (data in), pin 11 (clock), Pin 12 (reset/latch)
ShiftOut(PinName ser, PinName srclk, PinName rclk);
// ,
//         PinName oe, PinName reset);
 
/**
 * Writes a byte to the shift register
 * @param byte   0xXX or numbers from 0-255
 */
void writeByte(unsigned char);
 
/**
 * Writes a bit to the first output on the shift register
 * @param bit   0 or 1
 */
 
void writeBit(unsigned char);
 
/**
 * Writes bits from an 2D array, with configurable delay
 * @param int array, int lines, int delay_ms 
 * writes a 2D array with n-lines with a configurable delay in ms 
 * @code
 * #include "mbed.h"
 * #include "ShiftOut.h"
 * ShiftOut reg(PA_8, PA_9, PC_7, PB_6, D1);
 *
 * int main(){
 *   int strobe[][8]= {{1,0,0,0,0,0,0,0},
 *                    {0,1,0,0,0,0,0,0},
 *                    {0,0,1,0,0,0,0,0},
 *                    {0,0,0,1,0,0,0,0},
 *                    {0,0,0,0,1,0,0,0},
 *                    {0,0,0,0,0,1,0,0},
 *                    {0,0,0,0,0,0,1,0},
 *                    {0,0,0,0,0,0,0,1}};
 *      while(1){           
 *          reg.animate(strobe, 8, 200);
 *      }
 *  }
 * @endcode
 */
 
void animate(int[][8], int, int);
 
/**
 *  Demonstrates two animation examples by using the animate function
 */
 
void animationExample(void);
 
/**
 *   Writes the desired state to the output on the shift register
 *   @param  char output, state
 */
 
void writeBitAtPos(unsigned char, bool);
 
/**
 *   Writes the corresponding array item to the output on the shift register
 *   @param  char array   writes to the output from a state array
 */
 
void writeArray(char[8]);
 
public:
void updateRegister(void);
void updateOutput(void);
void clearStateArray(void);
DigitalOut DSERIAL; 
DigitalOut SRCLK, RCLK; //, SRCLK, RESET; 
};
 
#endif

Next reply shows output of this program.
It displays Menu of available commands.
I am typing string
8F0F0F0F0FC3
and hit Enter key.

Then this program output various values.
And then displays Menu of available commands.

Below is the output of this program:

Welcome to ATG Lens Antenna Micro-Controller Commands Program:

Available Commands:

Press 'R' to Reset all 40 GPIO Pins:
Press 'S' to Set all 40 GPIO Pins:
Press 'H' to See list of Available Commands:

Type HEX sting of length of 12 Hex digits (For example, 8F0F0F0F0Fc3) 
by Typing  0 to F  HEX chars followed by Enter key:
8F0F0F0F0FC3

Pressed Enter Key



Inside parse_hex_fcps function. 

12

8F0F0F0F0FC3
HEX

SR_BNK : 1

PA_BRD : 3


 Input Hex String : 8F0F0F0F0FC3



 FCPS Hex String : 1E1E1E1E1F


SR_BNK : 1

PA_BRD : 3

(PinName)ser_data : 102

ser_data : 102

FCPS BYTE STR 
Hex Byte : 16

FCPS BYTE STR 1F
Hex Byte : 31

FCPS BYTE STR 1E
Hex Byte : 30

FCPS BYTE STR 1E
Hex Byte : 30

FCPS BYTE STR 1E
Hex Byte : 30

FCPS BYTE STR 1E
Hex Byte : 30



Welcome to ATG Lens Antenna Micro-Controller Commands Program:

Available Commands:

Press 'R' to Reset all 40 GPIO Pins:
Press 'S' to Set all 40 GPIO Pins:
Press 'H' to See list of Available Commands:

Type HEX sting of length of 12 Hex digits (For example, 8F0F0F0F0Fc3) 
by Typing  0 to F  HEX chars followed by Enter key:

Below is screen capture image of lines of code from 272 to 320 of setHexGPIOpins function:

I am suspecting, line 311 is either not executing or hex_byte value is either blank (instead of expected 1E (decimal 30) or 1F (decimal 31) ).

I am executing for loop on lines 299 through 313 five times but the value of hex_byte is not being sent by reg.writeByte function of line 311 to DESERIAL of following function:

//Writes a byte to the shift register
void ShiftOut::writeByte(unsigned char byte){
   
    hasChanged = true;
    for(int i = 0; i<8*REGISTER_CNT; i++){
        DSERIAL = (byte & 0x01<<i)>>i;

        updateRegister();    
    } 
//    updateOutput();   
}

By debugging I want to find why writeByte function is not working?