Firmware for Raw 1-Wire Interface

Dependencies:   mbed OneWire max32630fthr USBDevice

main.cpp

Committer:
mfruge
Date:
2019-08-13
Revision:
0:06aa90721d89

File content as of revision 0:06aa90721d89:

/*******************************************************************************
* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved.
* 
* This software is protected by copyright laws of the United States and
* of foreign countries. This material may also be protected by patent laws
* and technology transfer regulations of the United States and of foreign
* countries. This software is furnished under a license agreement and/or a
* nondisclosure agreement and may only be used or reproduced in accordance
* with the terms of those agreements. Dissemination of this information to
* any party or parties not specified in the license agreement and/or
* nondisclosure agreement is expressly prohibited.
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* 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 AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/



/* Included Libraries */
#include "mbed.h"
#include "OneWire.h"
#include "max32630fthr.h"
#include "USBSerial.h"
#include "string"
#include "sstream"
#include "vector"


/* Define Constants */
#define BUF_SIZE_BYTES   1024

#define STRING_DATA_BEGIN   3
#define BYTES_IN_ROM_ID     8
#define SCRATCHPAD_WRITE_BYTES  3

#define ALARM_SEARCH_CMD    0xEC

/* Define the Flags */
#define USB_RECEIVED_FLAG   0x00000002

using namespace OneWire;
using namespace RomCommands;
using namespace std;


/****************** Global Variables ******************/

float VersionNumber = 1.01;

/* Buffer for what is read in from Serial */
string InitComp = "INIT";
string ReadBuffer = "";
bool StringReceived = false;
bool OutputRomID;
int CmdData;


/* Flag variable used for interrupts */
uint32_t int_flag;
uint32_t cmd_flag;

/* Set up and configure lights */
DigitalOut rLED(LED1, LED_OFF);
DigitalOut gLED(LED2, LED_OFF);
DigitalOut bLED(LED3, LED_OFF);

/* Set up virtual Serial Port */
USBSerial microUSB;

/* One Wire Master pointer and CmdResult */
MCU_OWM* owm_ptr;
vector<RomId> RomIDs;
int DeviceCount;
int mostRecentIdx;
SearchState search_state;

OneWireMaster::OWLevel NextLevel;
OneWireMaster::OWLevel CurrLevel;
OneWireMaster::OWSpeed NextSpeed;
OneWireMaster::OWSpeed CurrSpeed;


/* Error Messages */
string ROM_Error = "Not a recognized ROM command";
string Speed_Error = "Not a recognized Speed command";
string Pullup_Error = "Cannot configure Pullup";
string RW_Error = "Cannot parse R/W string";


/************** Function Definitions ***************/

/**
* @brief    Sets flag for main to process DataIn from USB Serial Port
* @version  1.0
* @post     Sets bit in int_flag
*****************************************************************************/
void USB_Received();

/**
* @brief    Processes the data recieved through the serial port and calls the corresponding One Wire functions
* @param[in] cmd: The string containing the data read from the serial port
* @param[in] owm: Pointer to the OneWireMaster object that preforms the operations
* @version  1.0
* @notes    Requires 'string' and 'OneWire.h'
* @pre      owm must be initialized and cmd must not be 'null'
* @post     Depending on specific contents of cmd, could change:
                 OutputRomID, RomIDs, search_state, NextLevel, CurrLevel, NextSpeed, CurrSpeed
*****************************************************************************/
void Parse_and_Execute(string cmd, MCU_OWM* owm);

/**
* @brief    Converts a string to a uint8_t
* @version  1.0
* @param[in] _string: String containing characters '0'-'9' to be converted
* @param[out] The equivalent value of the string
*****************************************************************************/
uint8_t StringtoDecimal(string _string);

/**
* @brief    Initializes the owm to be used, cycles red LED if not able to initialize
* @version  1.0
* @param[in] owm: OneWireMaster structure to be initialized
*****************************************************************************/
void OWM_Initialize(MCU_OWM owm);

/**
* @brief    Searches the bus for any one wire devices on the bus
* @version  1.0
* @param[in/out] owm: Reference to owm to conduct the search
* @param[in/out] search_state: SearchState structure to use to conduct the search
* @param[out] Returns the result of the command
* @post     Populates the RomIDs vector with the RomID of every device on the bus
* @notes    Requires 'OneWire.h'
*****************************************************************************/
OneWireMaster::CmdResult FindAllRomIDs(MCU_OWM & owm, SearchState &search_state);

/**
* @brief    Conducts an AlarmSearch on the devices on the bus
* @version  1.0
* @param[in/out] owm: Reference to owm to conduct the search
* @param[in/out] search_state: SearchState structure to use to conduct the search
* @param[out] Returns the result of the command
* @notes    Requires  'OneWire.h'
*****************************************************************************/
OneWireMaster::CmdResult AlarmSearchBus(MCU_OWM &owm, SearchState &search_state);



int main()
{
    /* Initialize the Board */
    MAX32630FTHR feather;
    feather.init(MAX32630FTHR::VIO_3V3);

    /* Initialize OWM and other OWM related variables */
    MCU_OWM owm(false, true);
    OWM_Initialize(owm);
    NextLevel = OneWireMaster::NormalLevel;
    NextSpeed = OneWireMaster::StandardSpeed;
    owm.OWSetLevel(NextLevel);
    owm.OWSetSpeed(NextSpeed);
    CurrLevel = NextLevel;
    CurrSpeed = NextSpeed;
    search_state.reset();

    DeviceCount = 0;

    bool InitReceived = false;

    /* Initialize Serial Interface */
    microUSB.attach(&USB_Received);

    /* Temporary Variable Storage */
    volatile char BufIn;

    while(1) {
        if(!int_flag) {
            // Go to sleep
        }

        /* Get from USB into Buffer */
        if(int_flag & USB_RECEIVED_FLAG) {            
            int_flag &= !(USB_RECEIVED_FLAG);

            while(microUSB.readable()) {
                BufIn = microUSB.getc();
                if(BufIn == '\r' || BufIn == '\0' || BufIn == '\n') {
                    StringReceived = true;
                    gLED = !gLED;
                    /* Detects the GUI initialization, resets the Firmware to keep it in sync */
                    if(ReadBuffer == InitComp){
                        microUSB.printf("Version %f\r\n", VersionNumber);
                        InitReceived = true;
                        owm.OWSetLevel(OneWireMaster::NormalLevel);
                        owm.OWSetSpeed(OneWireMaster::StandardSpeed);
                        search_state.reset();
                        RomIDs.clear();
                        gLED = LED_ON;
                        rLED = LED_OFF;
                        bLED = LED_OFF;
                    }
                }
                if(!StringReceived) {
                    ReadBuffer += BufIn;
                }
            }
            
            /* String is now in Buffer */
            StringReceived = false;
            
            if(!InitReceived){
                Parse_and_Execute(ReadBuffer, &owm);
            }
            ReadBuffer ="";
            bLED = !bLED;
            InitReceived = false;
        }
    }

    return 0;
}


/***************** Functions ********************/

void USB_Received()
{
    int_flag |= USB_RECEIVED_FLAG;
}

void Parse_and_Execute(string cmd, MCU_OWM* _owm)
{
    /* Variable Declarations */
    string::iterator i;
    string temp = "";
    string c;
    char ch;
    string RomIDstr;
    string CmdResponse;
    uint8_t num;
    uint32_t word;
    char* strend;
    long int hex_val;
    int j;
    int k;
    bool Read_Ret = false;
    bool RomID_Ret = false;
    uint8_t Scratchpad_Data [SCRATCHPAD_WRITE_BYTES];
    uint8_t ReadBytes[BUF_SIZE_BYTES];
    uint8_t ReadCount = 0;
    RomId romId;
    bool AddROM = false;
    bool AlarmSearch = false;
    size_t strpos = 0;
    vector<bool> RomIDMatches(RomIDs.size(), true);

    MCU_OWM* owm = _owm;
    OneWireMaster::CmdResult result;

    /* Initialize result to Fail */
    result = OneWireMaster::OperationFailure;
    
    i=cmd.begin();
/* Decode the commands based on 'Family Code' and parse the data */
    switch(*i) 
    {
        /* ROM commands */
        case 'R':
            //microUSB.printf("1: ROM command \r\n");
            i++;
            switch(*i) 
            {
                case 'M':
//                    microUSB.printf("2: Match ROM command \r\n");
                    i++;
                    if( *i == 'T') 
                    {
                        RomIDstr = cmd.substr(3);       // Obtains the string after the 3 CMD characters (The ROM ID we are looking for)
                        if(RomIDstr == ""){
                            microUSB.printf("Please select a Rom ID from the Devices on the Bus\r\n");
                            break;
                        }
                        
                        for(j=0; j<BYTES_IN_ROM_ID; j++){
                            strpos = 2*j;
                            temp = RomIDstr.substr(strpos, 2);
                            num = strtol(temp.c_str(), &strend, 16);
                            for(k=0; k<RomIDs.size(); k++){
                                // First, check to make sure that the RomID we are checking still matches
                                if(!RomIDMatches[k]){
                                    break;
                                }
                                // If the byte in num does not match the byte in the RomID, set the corresponding index in 'matches' to false
                                if(num != RomIDs[k].buffer[(BYTES_IN_ROM_ID - 1) - j]){
                                    RomIDMatches[k] = false;
                                    break;
                                }
                            }
                        }
                        j=0;    // Reset the loop variables
                        k=0;
                        // Now, there should only be 1 or 0 'true' values in RomIDMatches, so use that index for the MatchROM
                        while(!RomIDMatches[j] && j<RomIDs.size()){
                            j++;
                        }
                        // Now we have determined that the jth index of the RomIDs vector contains the RomID given by the user, 
                        romId = RomIDs[j];
                        result = OWMatchRom(*owm, romId);
                        CmdResponse = "Match ROM";
                        RomID_Ret = true;
                        ReadCount = BYTES_IN_ROM_ID;
                    }
                    break;

                case 'O':
                    //its an OVERDRIVE command
                    i++;
                    switch(*i) 
                    {
                        case 'M':
                             RomIDstr = cmd.substr(3);       // Obtains the string after the 3 CMD characters (The ROM ID we are looking for)
                            if(RomIDstr == ""){
                                microUSB.printf("Please select a Rom ID from the Devices on the Bus\r\n");
                                break;
                            }
                            for(j=0; j<BYTES_IN_ROM_ID; j++){
                                strpos = 2*j;
                                temp = RomIDstr.substr(strpos, 2);
                                num = strtol(temp.c_str(), &strend, 16);
                                for(k=0; k<RomIDs.size(); k++){
                                    // First, check to make sure that the RomID we are checking still matches
                                    if(!RomIDMatches[k]){
                                        break;
                                    }
                                    // If the byte in num does not match the byte in the RomID, set the corresponding index in 'matches' to false
                                    if(num != RomIDs[k].buffer[(BYTES_IN_ROM_ID - 1) - j]){
                                        RomIDMatches[k] = false;
                                        break;
                                    }
                                }
                            }
                            j=0;    // Reset the loop variables
                            k=0;
                            // Now, there should only be 1 or 0 'true' values in RomIDMatches, so use that index for the MatchROM
                            while(!RomIDMatches[j] && j<RomIDs.size()){
                                j++;
                            }
                            // Now we have determined that the jth index of the RomIDs vector contains the RomID given by the user, 
                            romId = RomIDs[j];
                            result = OWOverdriveMatchRom(*owm, romId);
                            CmdResponse = "Overdrive Match ROM";
                            RomID_Ret = true;
                            ReadCount = BYTES_IN_ROM_ID;
                            break;
                            
                        case 'S':
//                            microUSB.printf("3: Its an OD Skip ROM\r\n");
                            result = OWOverdriveSkipRom(*owm);
                            CmdResponse = "Overdrive Skip ROM";
                            break;
                            
                        default:
                            microUSB.printf("%s \r\n", ROM_Error.c_str());
                            break;
                    }
                    break;

                case 'R':
                    // It's a Resume OR ReadROM
//                    microUSB.printf("2: Res or Read ROM command \r\n");
                    i++;
                    switch(*i) {
                        case 'D':
//                            microUSB.printf("3: Its a Read ROM\r\n");
                            result = OWReadRom(*owm, romId);
                            RomID_Ret = true;
                            ReadCount = 8;
                            CmdResponse = "Read ROM";
                            break;
                        case 'S':
//                            microUSB.printf("3: Its a Resume\r\n");
                            result = OWResume(*owm);
                            CmdResponse = "Resume";
                            break;
                        case 'I':
                        /* Preforms a search finidng all devices on the bus */
                            result = FindAllRomIDs(*owm, search_state);
                            CmdResponse = "Standard Search";
                            break;
                        default:
                            microUSB.printf("%s \r\n", ROM_Error.c_str());
                            break;
                    }
                    break;

                case 'S':
                    // It's a Search rom (f or n) OR a SkipROM
//                    microUSB.printf("2: Search or skip ROM command \r\n");
                    i++;
                    switch(*i) {
                        case 'K':
//                            microUSB.printf("3: Skip-ROM issued\r\n");
                            result = OWSkipRom(*owm);
                            CmdResponse = "Skip ROM";
                            break;
                            
                        default:
                            microUSB.printf("%s \r\n", ROM_Error.c_str());
                            break;
                    }
                    break;

                case 'A':
                    // It's an alarm search
                    i++;
                    if(*i == 'S'){
                        result = AlarmSearchBus(*owm, search_state);
                        CmdResponse = "Alarm Search";
                    }
                    else{
                        microUSB.printf(" %s \r\n", ROM_Error.c_str());
                    }
                break;

                default:
                microUSB.printf("%s \r\n", ROM_Error.c_str());
                break;
            }
            break;

        case 'S':
//            microUSB.printf("1: Speed command \r\n");
            // it is a speed command
            i++;
            switch(*i) {
                case 'N':
                    NextSpeed = OneWireMaster::StandardSpeed;
//                    microUSB.printf("2: Standard Speed command issued\r\n");
                    if(CurrSpeed == NextSpeed) {
                        microUSB.printf("Already in Standard Speed Mode \r\n");
                        result = OneWireMaster::Success;
                    } else {
                        result = owm->OWSetSpeed(NextSpeed);
                        CurrSpeed = NextSpeed;
                        CmdResponse = "Normal Speed";
                    }
                    break;
                case 'O':
                    NextSpeed = OneWireMaster::OverdriveSpeed;
//                    microUSB.printf("2: Overdrive speed command issued\r\n");
                    if(CurrSpeed == NextSpeed) {
                        microUSB.printf("Already in Overdrive Speed Mode\r\n");
                        result = OneWireMaster::Success;
                    } else {
                        result = owm->OWSetSpeed(NextSpeed);
                        CurrSpeed = NextSpeed;
                        CmdResponse = "Overdrive Speed";
                      }
                      break;
                default:
                    microUSB.printf("%s \r\n", Speed_Error.c_str());
                    break;
                }
            break;

        case 'W':
            // it is a R/W cmd
            i++;
            switch(*i) {

                case 'R':
                    // Its a read cmd
                    i++;
                    switch(*i) {
                        case 'I':
                            // Read single bit command
                            result = owm->OWTouchBitSetLevel(*ReadBytes, CurrLevel);
                            Read_Ret = true;
                            ReadCount = 1;
                            CmdResponse = "Read Bit";
                            break;

                        case 'Y':
                            // Read X Bytes
//                            microUSB.printf("3: Read byte command \r\n");
                            /* Extract the data from the CMD string */
                            temp = cmd.substr(3);
                            /* Convert the string to the corresponding int */
                            ReadCount = StringtoDecimal(temp);
                            result = owm->OWReadBlock(ReadBytes, (size_t)ReadCount);
                            Read_Ret = true;
                            CmdResponse = "Read " + temp + " Bytes";
                            break;

                        default:
                            microUSB.printf("%s \r\n", RW_Error.c_str());
                            break;
                    }
                    break;

                case 'W':
                    // Its a write command
//                    microUSB.printf("2: Write Command\r\n");
                    i++;
                    switch(*i) {
                        case 'I':
//                            microUSB.printf("3:Write bit command \r\n");
                            //Write a single bit
                            i++;
                            c = *i;  // Get the 1/0 needed as a string
                            //microUSB.printf("The string obtained is: '%s' and it has 0x%02X characters\r\n", c, c.length());
                            num = StringtoDecimal(c); //convert to decimal
//                            microUSB.printf("Issuing a Write %d command\r\n", num);
                            result = owm->OWTouchBitSetLevel(num, CurrLevel);
                            CmdResponse = "Write Bit";
                            break;

                        case 'Y':
                            // Write multiple bytes
//                            microUSB.printf("3:Write Byte command \r\n");
                            temp = cmd.substr(3);
                            
                            if((temp.length()%2) != 0){
                                microUSB.printf("Please enter a Byte Alligned Value\r\n");
                                return;
                            }
  
                            /* Throws an error and returns if input is not formatted correctly */
                            for(j=0; j<temp.length(); j++){   
                                ch= temp[j];
                                
                                if((ch < '0' || ch > '9') && (ch < 'A' || ch > 'F')){
                                    microUSB.printf("Please ensure that you enter hex values\r\n");
                                    return;
                                }
                            } 
                                
                            for(j=0; j<(temp.length()+1)/2; j++){
                                strpos = 2*j;
                                c = temp.substr(strpos, 2);
                                hex_val = strtol(c.c_str(), &strend, 16);
                                num = (uint8_t) hex_val;
                                Scratchpad_Data[j] = num;
                            }
                            microUSB.printf("Wrote '0x%s'\r\n", temp);
                            result = owm->OWWriteBlock(Scratchpad_Data, (temp.length()+1)/2);
                            CmdResponse = "Write";
                            break;
                        default:
                            microUSB.printf("Unrecognized Command\r\n");
                            break;
                    }
                    break;
            }
            break;

        case 'P':
//            microUSB.printf("1: Power command \r\n");
            i++;
            switch(*i) {
                case 'N':
//                    microUSB.printf("2: Normal PWR command \r\n");
                    i++;
                    if(*i == 'O') {
//                        microUSB.printf("3: Further Normal PWR command \r\n");
                        NextLevel = OneWireMaster::NormalLevel;
                        if(NextLevel == CurrLevel) {
                            microUSB.printf("Normal Power\r\n");
                        } else {
                            microUSB.printf("Normal Power\r\n");
                            result = owm->OWSetLevel(NextLevel);
                            CurrLevel = NextLevel;
                            CmdResponse = "Normal Power";
                        }
                    }

                    else microUSB.printf("Unrecognizable\r\n");
                    break;

                case 'W':
                    // Strong pullup after writing...
//                    microUSB.printf("2: Power Write command \r\n");
                    i++;
                    if(NextLevel == OneWireMaster::StrongLevel) {
                        microUSB.printf("Already in Strong Pull-Up Mode\r\n");
                        result = OneWireMaster::Success;
                        break;
                    }
                    NextLevel = OneWireMaster::StrongLevel;
                    switch(*i) {
                        case 'I':
//                            microUSB.printf("3: Power Write bit command \r\n");
                            temp = cmd.substr(3);
                            num = atoi(temp.c_str());
                            if(temp == "1" || temp == "0") {
                                //microUSB.printf("Issuing strong Pullup after writing %d \r\n", num);
                                result = owm->OWWriteBitPower(num);
                                microUSB.printf("Switching to Strong Pull-Up Mode\r\n");
                                CurrLevel = NextLevel;
                                CmdResponse = "Strong Pullup After Writing Bit";
                                microUSB.printf("Wrote '0x%s'\r\n", temp);    
                            } 
                            else {
                                microUSB.printf("Incorrect formatting error. Decoded data as 0x%02X, expecting 1 or 0 \r\n", num);
                            }
                            break;

                        case 'Y':
                        
//                            microUSB.printf("3: Issuing Strong Pullup after writing Byte\r\n");
                            temp = cmd.substr(3);
                            hex_val = strtol(temp.c_str(), &strend, 16);

                            result = owm->OWWriteByteSetLevel(hex_val, NextLevel);
                            microUSB.printf("Switching to Strong Power Mode\r\n");
                            CurrLevel = NextLevel;
                            CmdResponse = "Strong Pullup After Writing Byte";
                            microUSB.printf("Wrote '%s'\r\n", temp);
                            break;

                        default:
                            microUSB.printf("Could not identify that command\r\n");
                            break;
                    }
                    break;
                default:
                    microUSB.printf("%s\r\n", Pullup_Error.c_str());
                }
                break;
        case 'Z':
            result = owm->OWReset();
            CmdResponse = "Reset";
            break;
            
        default:
            microUSB.printf("Cannot Parse Command\r\n");
            break; 
        } // End of switch
        
        /* For loop to print out the 8 byte Rom ID and add it to the 'RomIDs' vector*/
        if(RomID_Ret && result == OneWireMaster::Success) {
          /* Flag to add to vector or not */
          AddROM = true;
          
          /* Printing */
          microUSB.printf("RomID: ");
          for(j=ReadCount-1; j>=0; j--) {
              microUSB.printf("%02X ",romId.buffer[j]);
          }
          microUSB.printf("\r\n");
          
          /* Add the Rom ID to the vector if not in there already, and update the most recent RomID index used */
          for(j=0; j<RomIDs.size(); j++){
              if(RomIDs[j] == romId){
                  AddROM = false;
                  mostRecentIdx = j;
                  break;
              }
          }
          
          if(AddROM){
             /* If we need to add the RomID to the vector, that means it was the most recent one that was used/found, so update the mostRecentIdx */ 
             RomIDs.push_back(romId);
             mostRecentIdx = RomIDs.size() - 1;
             microUSB.printf("Added RomID to array\r\n");
          }
          
          if(search_state.last_device_flag && AddROM && !AlarmSearch){
                microUSB.printf("Obtained RomID's for all devices on the bus\r\n");
          }
      }
      
        /*Return bytes that were read from the device */
      if(Read_Ret && result == OneWireMaster::Success) {
          microUSB.printf("Result: ");
          for(j=0; j<ReadCount; j++) {
              microUSB.printf("%02X ",ReadBytes[j]);
          }
          microUSB.printf("\r\n");
      } 

      if(result == OneWireMaster::Success) {
          microUSB.printf("The %s was successful\r\n", CmdResponse);
      } else if (result == OneWireMaster::CommunicationWriteError){
          microUSB.printf("Command not issued, Communication Write Error\r\n");
      } else if (result == OneWireMaster::CommunicationReadError){
          microUSB.printf("Command not issued, Communication Read Error\r\n");
      } else if (result == OneWireMaster::TimeoutError) {
          microUSB.printf("The device timed out before the command could be issued\r\n");
      } else {
          microUSB.printf("Operation Failed\r\n");
      } 
}


uint8_t StringtoDecimal(string _string) {
    uint8_t number;
    number = atoi(_string.c_str());
    return number;
}

void OWM_Initialize(MCU_OWM owm) {
    rLED = LED_ON;
    OneWireMaster::CmdResult result = owm.OWInitMaster();
    while(result != OneWireMaster::Success) {
        microUSB.printf("Failed to init OWM...\r\n\r\n");
        result = owm.OWInitMaster();
        wait(0.5);
        rLED = !rLED;
    }
    rLED = LED_OFF;
}


OneWireMaster::CmdResult AlarmSearchBus(MCU_OWM & owm, SearchState & search_state){
    int numAlarms = 0;
    RomId RetRom;
    OneWireMaster::CmdResult res;
    search_state.reset();
    while(!search_state.last_device_flag){
        res = OWAlarmSearch(owm, search_state);
        if(res == OneWireMaster::Success){
            numAlarms++;
            RetRom = search_state.romId;
            microUSB.printf("Active Alarms: ");
            for(int j=BYTES_IN_ROM_ID-1; j>=0; j--) {
              microUSB.printf("%02X ",RetRom.buffer[j]);
            }
            microUSB.printf("\r\n");
        }
    }
    return res;
}
    
            
        
OneWireMaster::CmdResult FindAllRomIDs(MCU_OWM & owm, SearchState &search_state){
    int numDevices = 0;
    RomId romId;
    OneWireMaster::CmdResult res;
    
    RomIDs.clear();
    search_state.reset();
    
    /* Identify next Device on the bus, and print out its ROM ID so GUI can parse it, and add it to the FW array */
    while(!search_state.last_device_flag){
        res = OWSearch(owm, search_state);
        if(res == OneWireMaster::Success){
            numDevices++;
            romId = search_state.romId;
            microUSB.printf("RomID: ");
            for(int j=BYTES_IN_ROM_ID-1; j>=0; j--) {
              microUSB.printf("%02X ",romId.buffer[j]);
            }
            microUSB.printf("\r\n");
            RomIDs.push_back(romId);
        }
    }
    return res;
}