Library for MAX14871 Shield, MAXREFDES89#

Dependencies:   MAX5387 MAX7300

Dependents:   MAXREFDES89_MAX14871_Shield_Demo MAXREFDES89_Test_Program Line_Following_Bot Line_Following_Bot_Pololu

MAXREFDES89# Component Page

Files at this revision

API Documentation at this revision

Comitter:
j3
Date:
Thu Jul 23 23:36:46 2015 +0000
Child:
1:7e9b864ddacf
Commit message:
initial commit

Changed in this revision

MAX5387.lib Show annotated file Show diff for this revision Revisions of this file
MAX7300.lib Show annotated file Show diff for this revision Revisions of this file
max14871_shield.cpp Show annotated file Show diff for this revision Revisions of this file
max14871_shield.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX5387.lib	Thu Jul 23 23:36:46 2015 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/Maxim-Integrated/code/MAX5387/#f50b0fb1f7f6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX7300.lib	Thu Jul 23 23:36:46 2015 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/Maxim-Integrated/code/MAX7300/#fd2de5d21702
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/max14871_shield.cpp	Thu Jul 23 23:36:46 2015 +0000
@@ -0,0 +1,501 @@
+/******************************************************************//**
+* @file max14871_shield.h
+*
+* @author Justin Jordan
+*
+* @version 0.0
+*
+* Started: 18JUL15
+*
+* Updated: 
+*
+* @brief Source file for Max14871_Shield class
+***********************************************************************
+* Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* 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.
+**********************************************************************/
+
+
+#include "max14871_shield.h"
+
+#define MIN_PERIOD (20) //50KHz
+
+//Motor Driver control inputs
+#define MD_EN    (0x01)
+#define MD_DIR   (0x02)
+#define MD_MODE0 (0x04)
+#define MD_MODE1 (0x08)
+
+#define MAX_VREF (100)
+
+//GPIO Expander Default Configurations
+#define MAX7300_ALL_OUTPUTS    (0x55)
+#define MAX7300_ALL_INPUTS     (0xFF)
+#define MAX7300_OUTPUT_DEFAULT (0xBB)
+
+
+//*********************************************************************
+Max14871_Shield::Max14871_Shield(I2C *i2c_bus, bool default_config): _p_i2c(i2c_bus)
+{
+    _i2c_owner = false;
+    
+    if(default_config)
+    {
+        _p_io_expander = new Max7300(_p_i2c, Max7300::MAX7300_I2C_ADRS0);
+        _p_digi_pot1 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS0);
+        _p_digi_pot2 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS1);
+        
+        _p_pwm1 = new PwmOut(D4);
+        _p_pwm2 = new PwmOut(D5);
+        _p_pwm3 = new PwmOut(D9);
+        _p_pwm4 = new PwmOut(D10);
+    }
+    else
+    {
+        _p_io_expander = new Max7300(_p_i2c, Max7300::MAX7300_I2C_ADRS1);
+        _p_digi_pot1 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS2);
+        _p_digi_pot2 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS3);
+        
+        _p_pwm1 = new PwmOut(D3);
+        _p_pwm2 = new PwmOut(D6);
+        _p_pwm3 = new PwmOut(D8);
+        _p_pwm4 = new PwmOut(D11);
+    }
+    
+    init_board();
+}
+
+
+//*********************************************************************
+Max14871_Shield::Max14871_Shield(PinName sda, PinName scl, bool default_config)
+{
+     _p_i2c = new I2C(sda, scl);
+    _i2c_owner = true;
+    
+    if(default_config)
+    {
+        _p_io_expander = new Max7300(_p_i2c, Max7300::MAX7300_I2C_ADRS0);
+        _p_digi_pot1 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS0);
+        _p_digi_pot2 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS1);
+        
+        _p_pwm1 = new PwmOut(D4);
+        _p_pwm2 = new PwmOut(D5);
+        _p_pwm3 = new PwmOut(D9);
+        _p_pwm4 = new PwmOut(D10);
+    }
+    else
+    {
+        _p_io_expander = new Max7300(_p_i2c, Max7300::MAX7300_I2C_ADRS1);
+        _p_digi_pot1 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS2);
+        _p_digi_pot2 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS3);
+        
+        _p_pwm1 = new PwmOut(D3);
+        _p_pwm2 = new PwmOut(D6);
+        _p_pwm3 = new PwmOut(D8);
+        _p_pwm4 = new PwmOut(D11);
+    }
+    
+    init_board();
+}
+
+
+//*********************************************************************
+Max14871_Shield::~Max14871_Shield()
+{
+    if(_i2c_owner) 
+    {
+        delete _p_i2c;
+    }
+    
+    delete _p_io_expander;
+    delete _p_digi_pot1;
+    delete _p_digi_pot2;
+    delete _p_pwm1;
+    delete _p_pwm2;
+    delete _p_pwm3;
+    delete _p_pwm4;
+}
+
+
+//*********************************************************************
+int16_t Max14871_Shield::set_operating_mode(max14871_motor_driver_t md, 
+                                            max14871_operating_mode_t mode)
+{
+    int16_t result = 0;
+    int16_t port_data;
+    
+    Max7300::max7300_port_number_t low_port;
+    
+    //determine the low port of an 8 bit register to read/write 
+    if(md < MD3)
+    {
+        low_port = Max7300::MAX7300_PORT_04;
+    }
+    else
+    {
+        low_port = Max7300::MAX7300_PORT_12;
+    }
+    
+    //get current state of outputs
+    port_data = _p_io_expander->read_8_ports(low_port);
+
+    switch(mode)
+    {
+        //if(md % 2) for following cases, modify control bits
+        //of odd motor driver
+
+        case COAST:
+            if(md % 2)
+            {
+                port_data |= MD_EN;
+            }
+            else
+            {
+                port_data |= (MD_EN << 4);
+            }
+        break;
+        
+        case BRAKE:
+            if(md % 2)
+            {
+                port_data &= ~MD_EN;
+            }
+            else
+            {
+                port_data &= ~(MD_EN << 4);
+            }
+            
+            set_pwm_duty_cycle(md, 0);
+        break;
+        
+        case REVERSE:
+            if(md % 2)
+            {
+                port_data &= ~(MD_EN + MD_DIR);
+            }
+            else
+            {
+                port_data &= ~((MD_EN + MD_DIR) << 4);
+            }
+        break;
+        
+        case FORWARD:
+            if(md % 2)
+            {
+                port_data &= ~MD_EN;
+                port_data |= MD_DIR;
+            }
+            else
+            {
+                port_data &= ~(MD_EN << 4);
+                port_data |= (MD_DIR << 4);
+            } 
+        break;
+        
+        default:
+            result = -1;
+        break;
+    }
+    
+    if(!result)
+    {
+        //write data back to port
+        result = _p_io_expander->write_8_ports(low_port, (uint8_t) port_data);
+    }
+
+    return result;
+}
+
+
+//*********************************************************************
+int16_t Max14871_Shield::set_current_regulation_mode(max14871_motor_driver_t md, 
+                                                     max14871_current_regulation_mode_t mode,
+                                                     uint8_t vref)
+{
+    int16_t result = 0;
+    int16_t port_data;
+    
+    Max7300::max7300_port_number_t low_port;
+    Max5387 *p_digi_pot;
+    
+    //determine the low port of an 8 bit register to read/write 
+    if(md < MD3)
+    {
+        low_port = Max7300::MAX7300_PORT_04;
+        p_digi_pot = _p_digi_pot1;
+    }
+    else
+    {
+        low_port = Max7300::MAX7300_PORT_12;
+        p_digi_pot = _p_digi_pot2;
+    }
+    
+    //get current state of outputs
+    port_data = _p_io_expander->read_8_ports(low_port);
+        
+    switch(mode)
+    {
+        case RIPPLE_25_INTERNAL_REF:
+            if(md % 2)
+            {
+                port_data &= ~MD_MODE0;
+                port_data |= MD_MODE1;
+                p_digi_pot->write_ch_A(0);
+            }
+            else
+            {
+                port_data &= ~(MD_MODE0 << 4);
+                port_data |= (MD_MODE1 << 4);
+                p_digi_pot->write_ch_B(0);
+            }
+        break;
+        
+        case RIPPLE_25_EXTERNAL_REF:
+            if(md % 2)
+            {
+                port_data &= ~MD_MODE0;
+                port_data |= MD_MODE1;
+                
+                if(vref > MAX_VREF)
+                {
+                    vref = MAX_VREF;
+                }
+                p_digi_pot->write_ch_A(vref);
+            }
+            else
+            {
+                port_data &= ~(MD_MODE0 << 4);
+                port_data |= (MD_MODE1 << 4);
+                
+                if(vref > MAX_VREF)
+                {
+                    vref = MAX_VREF;
+                }
+                p_digi_pot->write_ch_B(vref);
+            }
+        break;
+        
+        case TCOFF_FAST_INTERNAL_REF:
+            if(md % 2)
+            {
+                port_data |= (MD_MODE1 + MD_MODE0);
+                p_digi_pot->write_ch_A(0);
+            }
+            else
+            {
+                port_data |= ((MD_MODE1 + MD_MODE0) << 4);
+                p_digi_pot->write_ch_B(0);
+            }
+        break;
+        
+        case TCOFF_SLOW_INTERNAL_REF:
+            if(md % 2)
+            {
+                port_data |= MD_MODE0;
+                port_data &= ~MD_MODE1;
+                p_digi_pot->write_ch_A(0);
+            }
+            else
+            {
+                port_data |= (MD_MODE0 << 4);
+                port_data &= ~(MD_MODE1 << 4);
+                p_digi_pot->write_ch_B(0);
+            }
+        break;
+        
+        case TCOFF_FAST_EXTERNAL_REF:
+            if(md % 2)
+            {
+                port_data |= (MD_MODE1 + MD_MODE0);
+                
+                if(vref > MAX_VREF)
+                {
+                    vref = MAX_VREF;
+                }
+                p_digi_pot->write_ch_A(vref);
+            }
+            else
+            {
+                port_data |= ((MD_MODE1 + MD_MODE0) << 4);
+                
+                if(vref > MAX_VREF)
+                {
+                    vref = MAX_VREF;
+                }
+                p_digi_pot->write_ch_B(vref);
+            }
+        break;
+        
+        case TCOFF_SLOW_EXTERNAL_REF:
+            if(md % 2)
+            {
+                port_data |= MD_MODE0;
+                port_data &= ~MD_MODE1;
+                
+                if(vref > MAX_VREF)
+                {
+                    vref = MAX_VREF;
+                }
+                p_digi_pot->write_ch_A(vref);
+            }
+            else
+            {
+                port_data |= (MD_MODE0 << 4);
+                port_data &= ~(MD_MODE1 << 4);
+                
+                if(vref > MAX_VREF)
+                {
+                    vref = MAX_VREF;
+                }
+                p_digi_pot->write_ch_B(vref);
+            }
+        break;
+        
+        default:
+            result = -1;
+        break;
+    }
+    
+    if(!result)
+    {
+        //write data back to port
+        result = _p_io_expander->write_8_ports(low_port, (uint8_t) port_data);
+    }
+    
+    return result;
+}
+
+
+//*********************************************************************
+int16_t Max14871_Shield::set_pwm_period(max14871_motor_driver_t md, uint16_t period)
+{
+    int16_t result = 0;
+    
+    if(period < MIN_PERIOD)
+    {
+        result = -1;
+    }
+    else
+    {
+        switch(md)
+        {
+            case MD1:
+                _p_pwm1->period_us(period);
+            break;
+            
+            case MD2:
+                _p_pwm2->period_us(period);
+            break;
+            
+            case MD3:
+                _p_pwm3->period_us(period);
+            break;
+            
+            case MD4:
+                _p_pwm4->period_us(period);
+            break;
+            
+            default:
+                result = -1;
+            break;
+        }
+    }
+    
+    return result;
+}
+
+
+//*********************************************************************
+int16_t Max14871_Shield::set_pwm_duty_cycle(max14871_motor_driver_t md, uint16_t duty_cycle)
+{
+    int16_t result = 0;
+    
+    switch(md)
+    {
+        case MD1:
+            _p_pwm1->pulsewidth_us(duty_cycle);
+        break;
+        
+        case MD2:
+            _p_pwm2->pulsewidth_us(duty_cycle);
+        break;
+        
+        case MD3:
+            _p_pwm3->pulsewidth_us(duty_cycle);
+        break;
+        
+        case MD4:
+            _p_pwm4->pulsewidth_us(duty_cycle);
+        break;
+        
+        default:
+            result = -1;
+        break;
+    }
+    
+    return result;
+}
+      
+
+//*********************************************************************
+void Max14871_Shield::init_board(void)
+{
+    //configure these ports as outputs
+    _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_04, MAX7300_ALL_OUTPUTS);
+    _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_08, MAX7300_ALL_OUTPUTS);
+    _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_12, MAX7300_ALL_OUTPUTS);
+    _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_16, MAX7300_ALL_OUTPUTS);
+    
+    //Set /EN and DIR pin of all motor drivers and set mode pin 
+    //of all motor drivers to 0.75V
+    _p_io_expander->write_8_ports(Max7300::MAX7300_PORT_04, MAX7300_OUTPUT_DEFAULT);
+    _p_io_expander->write_8_ports(Max7300::MAX7300_PORT_12, MAX7300_OUTPUT_DEFAULT);
+    
+    //configure these ports as inputs w/pull-up, 
+    _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_20, MAX7300_ALL_INPUTS);
+    _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_24, MAX7300_ALL_INPUTS);
+    _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_28, MAX7300_ALL_INPUTS);
+    
+    //config port 31 as output for interrupt
+    _p_io_expander->config_port(Max7300::MAX7300_PORT_31, Max7300::MAX7300_PORT_OUTPUT);
+    
+    _p_io_expander->enable_transition_detection();
+    _p_io_expander->enable_ports();
+    
+    //set Vref pin of all motor drivers to 1.3V
+    _p_digi_pot1->write_ch_AB(MAX_VREF);
+    _p_digi_pot2->write_ch_AB(MAX_VREF);
+    
+    //set switching frequency of all motor drivers to 50KHz
+    _p_pwm1->period_us(MIN_PERIOD);  
+    _p_pwm2->period_us(MIN_PERIOD);
+    _p_pwm3->period_us(MIN_PERIOD);
+    _p_pwm4->period_us(MIN_PERIOD);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/max14871_shield.h	Thu Jul 23 23:36:46 2015 +0000
@@ -0,0 +1,217 @@
+/******************************************************************//**
+* @file Max14871_Shield.h
+*
+* @author Justin Jordan
+*
+* @version 0.0
+*
+* Started: 18JUL15
+*
+* Updated: 
+*
+* @brief Header file for Max14871_Shield class
+***********************************************************************
+* Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* 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.
+**********************************************************************/
+
+
+#ifndef MAX14871_SHIELD_H
+#define MAX14871_SHIELD_H
+
+#include "mbed.h"
+#include "max7300.h"
+#include "max5387.h"
+
+
+class Max14871_Shield
+{
+    public:
+    
+    typedef enum
+    {
+        MD1 = 1,
+        MD2,
+        MD3,
+        MD4
+    }max14871_motor_driver_t;
+    
+    
+    typedef enum
+    {
+        COAST = 1,
+        BRAKE,
+        REVERSE,
+        FORWARD
+    }max14871_operating_mode_t;
+    
+    
+    typedef enum
+    {
+        RIPPLE_25_INTERNAL_REF = 1,
+        RIPPLE_25_EXTERNAL_REF,
+        TCOFF_FAST_INTERNAL_REF,
+        TCOFF_SLOW_INTERNAL_REF,
+        TCOFF_FAST_EXTERNAL_REF,
+        TCOFF_SLOW_EXTERNAL_REF
+    }max14871_current_regulation_mode_t;
+    
+    
+    /**********************************************************//**
+    * @brief Constructor for Max14871_Shield Class.  
+    * 
+    * @details Allows user to use existing I2C object
+    *
+    * On Entry:
+    *     @param[in] i2c_bus - pointer to existing I2C object
+    *     @param[in] default_config - true if board uses default
+    *                                 pwm channels and I2C addressing
+    *
+    * On Exit:
+    *    @return none
+    **************************************************************/
+    Max14871_Shield(I2C *i2c_bus, bool default_config);
+    
+    
+    /**********************************************************//**
+    * @brief Constructor for Max14871_Shield Class.  
+    * 
+    * @details Allows user to create a new I2C object if not 
+    *          already using one
+    *
+    * On Entry:
+    *     @param[in] sda - sda pin of I2C bus
+    *     @param[in] scl - scl pin of I2C bus
+    *     @param[in] default_config - true if board uses default
+    *                                 pwm channels and I2C addressing
+    *
+    * On Exit:
+    *    @return none
+    **************************************************************/
+    Max14871_Shield(PinName sda, PinName scl, bool default_config);
+    
+    
+    /**********************************************************//**
+    * @brief Default destructor for Max14871_Shield Class.  
+    *
+    * @details Destroys I2C object if owner 
+    *
+    * On Entry:
+    *
+    * On Exit:
+    *    @return none
+    **************************************************************/
+    ~Max14871_Shield();
+    
+    
+    /**********************************************************//**
+    * @brief Set the operating mode of the motor driver
+    *
+    * @details Configures the /EN and DIR pins of the motor driver
+    *  via the MAX7300 GPIO Expander   
+    *
+    * On Entry:
+    *    @param[in] md - 1 of 4 motor drivers on the shield
+    *    @param[in] mode - 1 of 4 operating modes of the motor driver 
+    *
+    * On Exit:
+    *    @return 0 on success, non-0 on failure
+    **************************************************************/
+    int16_t set_operating_mode(max14871_motor_driver_t md, 
+                               max14871_operating_mode_t mode);
+    
+    
+    /**********************************************************//**
+    * @brief 
+    *
+    * @details    
+    *
+    * On Entry:
+    *    @param[in] md - 1 of 4 motor drivers on the shield
+    *    @param[in] mode - 1 of 6 current regulation modes of the 
+    *                      motor driver
+    *
+    * On Exit:
+    *    @return 0 on success, non-0 on failure
+    **************************************************************/
+    int16_t set_current_regulation_mode(max14871_motor_driver_t md, 
+                                        max14871_current_regulation_mode_t mode,
+                                        uint8_t vref);
+    
+    
+    /**********************************************************//**
+    * @brief Sets period of pwm signal for selected motor driver
+    *
+    * @details period must be in micro-seconds
+    *
+    * On Entry:
+    *    @param[in] md - 1 of 4 motor drivers on the shield
+    *    @param[in] period - period of the pwm signal in 
+    *                            micro-seconds
+    *
+    * On Exit:
+    *    @return 0 on success, non-0 on failure
+    **************************************************************/
+    int16_t set_pwm_period(max14871_motor_driver_t md, uint16_t period);
+    
+    
+    /**********************************************************//**
+    * @brief Sets duty cycle of pwm signal for selected motor driver
+    *
+    * @details duty cycle must be in micro-seconds
+    *
+    * On Entry:
+    *    @param[in] md - 1 of 4 motor drivers on the shield
+    *    @param[in] duty_cycle - duty cycle of the pwm signal in 
+    *                            micro-seconds
+    *
+    * On Exit:
+    *    @return 0 on success, non-0 on failure
+    **************************************************************/
+    int16_t set_pwm_duty_cycle(max14871_motor_driver_t md, uint16_t duty_cycle);
+                                        
+    
+    private:
+    
+    I2C *_p_i2c;
+    Max7300 *_p_io_expander;
+    Max5387 *_p_digi_pot1;
+    Max5387 *_p_digi_pot2;
+    PwmOut *_p_pwm1;
+    PwmOut *_p_pwm2;
+    PwmOut *_p_pwm3;
+    PwmOut *_p_pwm4;
+    
+    bool _i2c_owner;
+    
+    void init_board(void);
+};
+
+#endif/* MAX14871_SHIELD_H */
\ No newline at end of file