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

Committer:
j3
Date:
Tue Dec 22 04:24:07 2015 +0000
Revision:
5:a206f6505109
Parent:
3:89bf07b855e5
Child:
6:dc06cc75c1c8
Added set_pwm_channel member function

Who changed what in which revision?

UserRevisionLine numberNew contents of line
j3 0:b5189f4ce1cb 1 /******************************************************************//**
j3 1:7e9b864ddacf 2 * @file max14871_shield.cpp
j3 0:b5189f4ce1cb 3 *
j3 0:b5189f4ce1cb 4 * @author Justin Jordan
j3 0:b5189f4ce1cb 5 *
j3 0:b5189f4ce1cb 6 * @version 0.0
j3 0:b5189f4ce1cb 7 *
j3 0:b5189f4ce1cb 8 * Started: 18JUL15
j3 0:b5189f4ce1cb 9 *
j3 0:b5189f4ce1cb 10 * Updated:
j3 0:b5189f4ce1cb 11 *
j3 0:b5189f4ce1cb 12 * @brief Source file for Max14871_Shield class
j3 0:b5189f4ce1cb 13 ***********************************************************************
j3 0:b5189f4ce1cb 14 * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
j3 0:b5189f4ce1cb 15 *
j3 0:b5189f4ce1cb 16 * Permission is hereby granted, free of charge, to any person obtaining a
j3 0:b5189f4ce1cb 17 * copy of this software and associated documentation files (the "Software"),
j3 0:b5189f4ce1cb 18 * to deal in the Software without restriction, including without limitation
j3 0:b5189f4ce1cb 19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
j3 0:b5189f4ce1cb 20 * and/or sell copies of the Software, and to permit persons to whom the
j3 0:b5189f4ce1cb 21 * Software is furnished to do so, subject to the following conditions:
j3 0:b5189f4ce1cb 22 *
j3 0:b5189f4ce1cb 23 * The above copyright notice and this permission notice shall be included
j3 0:b5189f4ce1cb 24 * in all copies or substantial portions of the Software.
j3 0:b5189f4ce1cb 25 *
j3 0:b5189f4ce1cb 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
j3 0:b5189f4ce1cb 27 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
j3 0:b5189f4ce1cb 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
j3 0:b5189f4ce1cb 29 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
j3 0:b5189f4ce1cb 30 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
j3 0:b5189f4ce1cb 31 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
j3 0:b5189f4ce1cb 32 * OTHER DEALINGS IN THE SOFTWARE.
j3 0:b5189f4ce1cb 33 *
j3 0:b5189f4ce1cb 34 * Except as contained in this notice, the name of Maxim Integrated
j3 0:b5189f4ce1cb 35 * Products, Inc. shall not be used except as stated in the Maxim Integrated
j3 0:b5189f4ce1cb 36 * Products, Inc. Branding Policy.
j3 0:b5189f4ce1cb 37 *
j3 0:b5189f4ce1cb 38 * The mere transfer of this software does not imply any licenses
j3 0:b5189f4ce1cb 39 * of trade secrets, proprietary technology, copyrights, patents,
j3 0:b5189f4ce1cb 40 * trademarks, maskwork rights, or any other form of intellectual
j3 0:b5189f4ce1cb 41 * property whatsoever. Maxim Integrated Products, Inc. retains all
j3 0:b5189f4ce1cb 42 * ownership rights.
j3 0:b5189f4ce1cb 43 **********************************************************************/
j3 0:b5189f4ce1cb 44
j3 0:b5189f4ce1cb 45
j3 0:b5189f4ce1cb 46 #include "max14871_shield.h"
j3 0:b5189f4ce1cb 47
j3 2:9b50d36d69c8 48 #define MIN_PERIOD (0.00002f) //50KHz
j3 0:b5189f4ce1cb 49
j3 0:b5189f4ce1cb 50 //Motor Driver control inputs
j3 0:b5189f4ce1cb 51 #define MD_EN (0x01)
j3 0:b5189f4ce1cb 52 #define MD_DIR (0x02)
j3 0:b5189f4ce1cb 53 #define MD_MODE0 (0x04)
j3 0:b5189f4ce1cb 54 #define MD_MODE1 (0x08)
j3 0:b5189f4ce1cb 55
j3 2:9b50d36d69c8 56 #define MAX_VREF (2.0f)
j3 0:b5189f4ce1cb 57
j3 0:b5189f4ce1cb 58 //GPIO Expander Default Configurations
j3 0:b5189f4ce1cb 59 #define MAX7300_ALL_OUTPUTS (0x55)
j3 0:b5189f4ce1cb 60 #define MAX7300_ALL_INPUTS (0xFF)
j3 0:b5189f4ce1cb 61 #define MAX7300_OUTPUT_DEFAULT (0xBB)
j3 0:b5189f4ce1cb 62
j3 0:b5189f4ce1cb 63
j3 0:b5189f4ce1cb 64 //*********************************************************************
j3 0:b5189f4ce1cb 65 Max14871_Shield::Max14871_Shield(I2C *i2c_bus, bool default_config): _p_i2c(i2c_bus)
j3 0:b5189f4ce1cb 66 {
j3 0:b5189f4ce1cb 67 _i2c_owner = false;
j3 0:b5189f4ce1cb 68
j3 0:b5189f4ce1cb 69 if(default_config)
j3 0:b5189f4ce1cb 70 {
j3 0:b5189f4ce1cb 71 _p_io_expander = new Max7300(_p_i2c, Max7300::MAX7300_I2C_ADRS0);
j3 0:b5189f4ce1cb 72 _p_digi_pot1 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS0);
j3 0:b5189f4ce1cb 73 _p_digi_pot2 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS1);
j3 0:b5189f4ce1cb 74
j3 0:b5189f4ce1cb 75 _p_pwm1 = new PwmOut(D4);
j3 0:b5189f4ce1cb 76 _p_pwm2 = new PwmOut(D5);
j3 0:b5189f4ce1cb 77 _p_pwm3 = new PwmOut(D9);
j3 0:b5189f4ce1cb 78 _p_pwm4 = new PwmOut(D10);
j3 0:b5189f4ce1cb 79 }
j3 0:b5189f4ce1cb 80 else
j3 0:b5189f4ce1cb 81 {
j3 0:b5189f4ce1cb 82 _p_io_expander = new Max7300(_p_i2c, Max7300::MAX7300_I2C_ADRS1);
j3 0:b5189f4ce1cb 83 _p_digi_pot1 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS2);
j3 0:b5189f4ce1cb 84 _p_digi_pot2 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS3);
j3 0:b5189f4ce1cb 85
j3 0:b5189f4ce1cb 86 _p_pwm1 = new PwmOut(D3);
j3 0:b5189f4ce1cb 87 _p_pwm2 = new PwmOut(D6);
j3 0:b5189f4ce1cb 88 _p_pwm3 = new PwmOut(D8);
j3 0:b5189f4ce1cb 89 _p_pwm4 = new PwmOut(D11);
j3 0:b5189f4ce1cb 90 }
j3 0:b5189f4ce1cb 91
j3 0:b5189f4ce1cb 92 init_board();
j3 0:b5189f4ce1cb 93 }
j3 0:b5189f4ce1cb 94
j3 0:b5189f4ce1cb 95
j3 0:b5189f4ce1cb 96 //*********************************************************************
j3 0:b5189f4ce1cb 97 Max14871_Shield::Max14871_Shield(PinName sda, PinName scl, bool default_config)
j3 0:b5189f4ce1cb 98 {
j3 0:b5189f4ce1cb 99 _p_i2c = new I2C(sda, scl);
j3 0:b5189f4ce1cb 100 _i2c_owner = true;
j3 0:b5189f4ce1cb 101
j3 0:b5189f4ce1cb 102 if(default_config)
j3 0:b5189f4ce1cb 103 {
j3 0:b5189f4ce1cb 104 _p_io_expander = new Max7300(_p_i2c, Max7300::MAX7300_I2C_ADRS0);
j3 0:b5189f4ce1cb 105 _p_digi_pot1 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS0);
j3 0:b5189f4ce1cb 106 _p_digi_pot2 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS1);
j3 0:b5189f4ce1cb 107
j3 0:b5189f4ce1cb 108 _p_pwm1 = new PwmOut(D4);
j3 0:b5189f4ce1cb 109 _p_pwm2 = new PwmOut(D5);
j3 0:b5189f4ce1cb 110 _p_pwm3 = new PwmOut(D9);
j3 0:b5189f4ce1cb 111 _p_pwm4 = new PwmOut(D10);
j3 0:b5189f4ce1cb 112 }
j3 0:b5189f4ce1cb 113 else
j3 0:b5189f4ce1cb 114 {
j3 0:b5189f4ce1cb 115 _p_io_expander = new Max7300(_p_i2c, Max7300::MAX7300_I2C_ADRS1);
j3 0:b5189f4ce1cb 116 _p_digi_pot1 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS2);
j3 0:b5189f4ce1cb 117 _p_digi_pot2 = new Max5387(_p_i2c, Max5387::MAX5387_I2C_ADRS3);
j3 0:b5189f4ce1cb 118
j3 0:b5189f4ce1cb 119 _p_pwm1 = new PwmOut(D3);
j3 0:b5189f4ce1cb 120 _p_pwm2 = new PwmOut(D6);
j3 0:b5189f4ce1cb 121 _p_pwm3 = new PwmOut(D8);
j3 0:b5189f4ce1cb 122 _p_pwm4 = new PwmOut(D11);
j3 0:b5189f4ce1cb 123 }
j3 0:b5189f4ce1cb 124
j3 0:b5189f4ce1cb 125 init_board();
j3 0:b5189f4ce1cb 126 }
j3 0:b5189f4ce1cb 127
j3 0:b5189f4ce1cb 128
j3 0:b5189f4ce1cb 129 //*********************************************************************
j3 0:b5189f4ce1cb 130 Max14871_Shield::~Max14871_Shield()
j3 0:b5189f4ce1cb 131 {
j3 0:b5189f4ce1cb 132 if(_i2c_owner)
j3 0:b5189f4ce1cb 133 {
j3 0:b5189f4ce1cb 134 delete _p_i2c;
j3 0:b5189f4ce1cb 135 }
j3 0:b5189f4ce1cb 136
j3 0:b5189f4ce1cb 137 delete _p_io_expander;
j3 0:b5189f4ce1cb 138 delete _p_digi_pot1;
j3 0:b5189f4ce1cb 139 delete _p_digi_pot2;
j3 0:b5189f4ce1cb 140 delete _p_pwm1;
j3 0:b5189f4ce1cb 141 delete _p_pwm2;
j3 0:b5189f4ce1cb 142 delete _p_pwm3;
j3 0:b5189f4ce1cb 143 delete _p_pwm4;
j3 0:b5189f4ce1cb 144 }
j3 0:b5189f4ce1cb 145
j3 0:b5189f4ce1cb 146
j3 0:b5189f4ce1cb 147 //*********************************************************************
j3 0:b5189f4ce1cb 148 int16_t Max14871_Shield::set_operating_mode(max14871_motor_driver_t md,
j3 0:b5189f4ce1cb 149 max14871_operating_mode_t mode)
j3 0:b5189f4ce1cb 150 {
j3 0:b5189f4ce1cb 151 int16_t result = 0;
j3 0:b5189f4ce1cb 152 int16_t port_data;
j3 0:b5189f4ce1cb 153
j3 0:b5189f4ce1cb 154 Max7300::max7300_port_number_t low_port;
j3 0:b5189f4ce1cb 155
j3 0:b5189f4ce1cb 156 //determine the low port of an 8 bit register to read/write
j3 0:b5189f4ce1cb 157 if(md < MD3)
j3 0:b5189f4ce1cb 158 {
j3 0:b5189f4ce1cb 159 low_port = Max7300::MAX7300_PORT_04;
j3 0:b5189f4ce1cb 160 }
j3 0:b5189f4ce1cb 161 else
j3 0:b5189f4ce1cb 162 {
j3 0:b5189f4ce1cb 163 low_port = Max7300::MAX7300_PORT_12;
j3 0:b5189f4ce1cb 164 }
j3 0:b5189f4ce1cb 165
j3 0:b5189f4ce1cb 166 //get current state of outputs
j3 0:b5189f4ce1cb 167 port_data = _p_io_expander->read_8_ports(low_port);
j3 0:b5189f4ce1cb 168
j3 0:b5189f4ce1cb 169 switch(mode)
j3 0:b5189f4ce1cb 170 {
j3 0:b5189f4ce1cb 171 //if(md % 2) for following cases, modify control bits
j3 0:b5189f4ce1cb 172 //of odd motor driver
j3 0:b5189f4ce1cb 173
j3 0:b5189f4ce1cb 174 case COAST:
j3 0:b5189f4ce1cb 175 if(md % 2)
j3 0:b5189f4ce1cb 176 {
j3 0:b5189f4ce1cb 177 port_data |= MD_EN;
j3 0:b5189f4ce1cb 178 }
j3 0:b5189f4ce1cb 179 else
j3 0:b5189f4ce1cb 180 {
j3 0:b5189f4ce1cb 181 port_data |= (MD_EN << 4);
j3 0:b5189f4ce1cb 182 }
j3 1:7e9b864ddacf 183
j3 3:89bf07b855e5 184 set_pwm_duty_cycle(md, 0.0f);
j3 0:b5189f4ce1cb 185 break;
j3 0:b5189f4ce1cb 186
j3 0:b5189f4ce1cb 187 case BRAKE:
j3 0:b5189f4ce1cb 188 if(md % 2)
j3 0:b5189f4ce1cb 189 {
j3 0:b5189f4ce1cb 190 port_data &= ~MD_EN;
j3 0:b5189f4ce1cb 191 }
j3 0:b5189f4ce1cb 192 else
j3 0:b5189f4ce1cb 193 {
j3 0:b5189f4ce1cb 194 port_data &= ~(MD_EN << 4);
j3 0:b5189f4ce1cb 195 }
j3 0:b5189f4ce1cb 196
j3 3:89bf07b855e5 197 set_pwm_duty_cycle(md, 0.0f);
j3 0:b5189f4ce1cb 198 break;
j3 0:b5189f4ce1cb 199
j3 0:b5189f4ce1cb 200 case REVERSE:
j3 0:b5189f4ce1cb 201 if(md % 2)
j3 0:b5189f4ce1cb 202 {
j3 0:b5189f4ce1cb 203 port_data &= ~(MD_EN + MD_DIR);
j3 0:b5189f4ce1cb 204 }
j3 0:b5189f4ce1cb 205 else
j3 0:b5189f4ce1cb 206 {
j3 0:b5189f4ce1cb 207 port_data &= ~((MD_EN + MD_DIR) << 4);
j3 0:b5189f4ce1cb 208 }
j3 0:b5189f4ce1cb 209 break;
j3 0:b5189f4ce1cb 210
j3 0:b5189f4ce1cb 211 case FORWARD:
j3 0:b5189f4ce1cb 212 if(md % 2)
j3 0:b5189f4ce1cb 213 {
j3 0:b5189f4ce1cb 214 port_data &= ~MD_EN;
j3 0:b5189f4ce1cb 215 port_data |= MD_DIR;
j3 0:b5189f4ce1cb 216 }
j3 0:b5189f4ce1cb 217 else
j3 0:b5189f4ce1cb 218 {
j3 0:b5189f4ce1cb 219 port_data &= ~(MD_EN << 4);
j3 0:b5189f4ce1cb 220 port_data |= (MD_DIR << 4);
j3 0:b5189f4ce1cb 221 }
j3 0:b5189f4ce1cb 222 break;
j3 0:b5189f4ce1cb 223
j3 0:b5189f4ce1cb 224 default:
j3 0:b5189f4ce1cb 225 result = -1;
j3 0:b5189f4ce1cb 226 break;
j3 0:b5189f4ce1cb 227 }
j3 0:b5189f4ce1cb 228
j3 0:b5189f4ce1cb 229 if(!result)
j3 0:b5189f4ce1cb 230 {
j3 0:b5189f4ce1cb 231 //write data back to port
j3 0:b5189f4ce1cb 232 result = _p_io_expander->write_8_ports(low_port, (uint8_t) port_data);
j3 3:89bf07b855e5 233
j3 3:89bf07b855e5 234 if(!result)
j3 3:89bf07b855e5 235 {
j3 3:89bf07b855e5 236 _motor_data_array[(md - 1)].op_mode = mode;
j3 3:89bf07b855e5 237 }
j3 0:b5189f4ce1cb 238 }
j3 0:b5189f4ce1cb 239
j3 0:b5189f4ce1cb 240 return result;
j3 0:b5189f4ce1cb 241 }
j3 0:b5189f4ce1cb 242
j3 0:b5189f4ce1cb 243
j3 0:b5189f4ce1cb 244 //*********************************************************************
j3 0:b5189f4ce1cb 245 int16_t Max14871_Shield::set_current_regulation_mode(max14871_motor_driver_t md,
j3 0:b5189f4ce1cb 246 max14871_current_regulation_mode_t mode,
j3 1:7e9b864ddacf 247 float vref)
j3 0:b5189f4ce1cb 248 {
j3 0:b5189f4ce1cb 249 int16_t result = 0;
j3 0:b5189f4ce1cb 250 int16_t port_data;
j3 1:7e9b864ddacf 251 uint8_t local_vref = 0;
j3 0:b5189f4ce1cb 252
j3 0:b5189f4ce1cb 253 Max7300::max7300_port_number_t low_port;
j3 0:b5189f4ce1cb 254 Max5387 *p_digi_pot;
j3 0:b5189f4ce1cb 255
j3 1:7e9b864ddacf 256 if(vref > MAX_VREF)
j3 1:7e9b864ddacf 257 {
j3 1:7e9b864ddacf 258 vref = MAX_VREF;
j3 1:7e9b864ddacf 259 }
j3 2:9b50d36d69c8 260 local_vref = ((uint8_t) ((vref * 255.0f) / 3.3f));
j3 1:7e9b864ddacf 261
j3 0:b5189f4ce1cb 262 //determine the low port of an 8 bit register to read/write
j3 1:7e9b864ddacf 263 //and digipot associated with motor driver
j3 0:b5189f4ce1cb 264 if(md < MD3)
j3 0:b5189f4ce1cb 265 {
j3 0:b5189f4ce1cb 266 low_port = Max7300::MAX7300_PORT_04;
j3 0:b5189f4ce1cb 267 p_digi_pot = _p_digi_pot1;
j3 0:b5189f4ce1cb 268 }
j3 0:b5189f4ce1cb 269 else
j3 0:b5189f4ce1cb 270 {
j3 0:b5189f4ce1cb 271 low_port = Max7300::MAX7300_PORT_12;
j3 0:b5189f4ce1cb 272 p_digi_pot = _p_digi_pot2;
j3 0:b5189f4ce1cb 273 }
j3 0:b5189f4ce1cb 274
j3 0:b5189f4ce1cb 275 //get current state of outputs
j3 0:b5189f4ce1cb 276 port_data = _p_io_expander->read_8_ports(low_port);
j3 0:b5189f4ce1cb 277
j3 0:b5189f4ce1cb 278 switch(mode)
j3 0:b5189f4ce1cb 279 {
j3 0:b5189f4ce1cb 280 case RIPPLE_25_INTERNAL_REF:
j3 0:b5189f4ce1cb 281 if(md % 2)
j3 0:b5189f4ce1cb 282 {
j3 0:b5189f4ce1cb 283 port_data &= ~MD_MODE0;
j3 0:b5189f4ce1cb 284 port_data |= MD_MODE1;
j3 0:b5189f4ce1cb 285 p_digi_pot->write_ch_A(0);
j3 0:b5189f4ce1cb 286 }
j3 0:b5189f4ce1cb 287 else
j3 0:b5189f4ce1cb 288 {
j3 0:b5189f4ce1cb 289 port_data &= ~(MD_MODE0 << 4);
j3 0:b5189f4ce1cb 290 port_data |= (MD_MODE1 << 4);
j3 0:b5189f4ce1cb 291 p_digi_pot->write_ch_B(0);
j3 0:b5189f4ce1cb 292 }
j3 0:b5189f4ce1cb 293 break;
j3 0:b5189f4ce1cb 294
j3 0:b5189f4ce1cb 295 case RIPPLE_25_EXTERNAL_REF:
j3 0:b5189f4ce1cb 296 if(md % 2)
j3 0:b5189f4ce1cb 297 {
j3 0:b5189f4ce1cb 298 port_data &= ~MD_MODE0;
j3 0:b5189f4ce1cb 299 port_data |= MD_MODE1;
j3 1:7e9b864ddacf 300 p_digi_pot->write_ch_A(local_vref);
j3 0:b5189f4ce1cb 301 }
j3 0:b5189f4ce1cb 302 else
j3 0:b5189f4ce1cb 303 {
j3 0:b5189f4ce1cb 304 port_data &= ~(MD_MODE0 << 4);
j3 0:b5189f4ce1cb 305 port_data |= (MD_MODE1 << 4);
j3 1:7e9b864ddacf 306 p_digi_pot->write_ch_B(local_vref);
j3 0:b5189f4ce1cb 307 }
j3 0:b5189f4ce1cb 308 break;
j3 0:b5189f4ce1cb 309
j3 0:b5189f4ce1cb 310 case TCOFF_FAST_INTERNAL_REF:
j3 0:b5189f4ce1cb 311 if(md % 2)
j3 0:b5189f4ce1cb 312 {
j3 0:b5189f4ce1cb 313 port_data |= (MD_MODE1 + MD_MODE0);
j3 0:b5189f4ce1cb 314 p_digi_pot->write_ch_A(0);
j3 0:b5189f4ce1cb 315 }
j3 0:b5189f4ce1cb 316 else
j3 0:b5189f4ce1cb 317 {
j3 0:b5189f4ce1cb 318 port_data |= ((MD_MODE1 + MD_MODE0) << 4);
j3 0:b5189f4ce1cb 319 p_digi_pot->write_ch_B(0);
j3 0:b5189f4ce1cb 320 }
j3 0:b5189f4ce1cb 321 break;
j3 0:b5189f4ce1cb 322
j3 0:b5189f4ce1cb 323 case TCOFF_SLOW_INTERNAL_REF:
j3 0:b5189f4ce1cb 324 if(md % 2)
j3 0:b5189f4ce1cb 325 {
j3 0:b5189f4ce1cb 326 port_data |= MD_MODE0;
j3 0:b5189f4ce1cb 327 port_data &= ~MD_MODE1;
j3 0:b5189f4ce1cb 328 p_digi_pot->write_ch_A(0);
j3 0:b5189f4ce1cb 329 }
j3 0:b5189f4ce1cb 330 else
j3 0:b5189f4ce1cb 331 {
j3 0:b5189f4ce1cb 332 port_data |= (MD_MODE0 << 4);
j3 0:b5189f4ce1cb 333 port_data &= ~(MD_MODE1 << 4);
j3 0:b5189f4ce1cb 334 p_digi_pot->write_ch_B(0);
j3 0:b5189f4ce1cb 335 }
j3 0:b5189f4ce1cb 336 break;
j3 0:b5189f4ce1cb 337
j3 0:b5189f4ce1cb 338 case TCOFF_FAST_EXTERNAL_REF:
j3 0:b5189f4ce1cb 339 if(md % 2)
j3 0:b5189f4ce1cb 340 {
j3 0:b5189f4ce1cb 341 port_data |= (MD_MODE1 + MD_MODE0);
j3 1:7e9b864ddacf 342 p_digi_pot->write_ch_A(local_vref);
j3 0:b5189f4ce1cb 343 }
j3 0:b5189f4ce1cb 344 else
j3 0:b5189f4ce1cb 345 {
j3 0:b5189f4ce1cb 346 port_data |= ((MD_MODE1 + MD_MODE0) << 4);
j3 1:7e9b864ddacf 347 p_digi_pot->write_ch_B(local_vref);
j3 0:b5189f4ce1cb 348 }
j3 0:b5189f4ce1cb 349 break;
j3 0:b5189f4ce1cb 350
j3 0:b5189f4ce1cb 351 case TCOFF_SLOW_EXTERNAL_REF:
j3 0:b5189f4ce1cb 352 if(md % 2)
j3 0:b5189f4ce1cb 353 {
j3 0:b5189f4ce1cb 354 port_data |= MD_MODE0;
j3 0:b5189f4ce1cb 355 port_data &= ~MD_MODE1;
j3 1:7e9b864ddacf 356 p_digi_pot->write_ch_A(local_vref);
j3 0:b5189f4ce1cb 357 }
j3 0:b5189f4ce1cb 358 else
j3 0:b5189f4ce1cb 359 {
j3 0:b5189f4ce1cb 360 port_data |= (MD_MODE0 << 4);
j3 0:b5189f4ce1cb 361 port_data &= ~(MD_MODE1 << 4);
j3 1:7e9b864ddacf 362 p_digi_pot->write_ch_B(local_vref);
j3 0:b5189f4ce1cb 363 }
j3 0:b5189f4ce1cb 364 break;
j3 0:b5189f4ce1cb 365
j3 0:b5189f4ce1cb 366 default:
j3 0:b5189f4ce1cb 367 result = -1;
j3 0:b5189f4ce1cb 368 break;
j3 0:b5189f4ce1cb 369 }
j3 0:b5189f4ce1cb 370
j3 0:b5189f4ce1cb 371 if(!result)
j3 0:b5189f4ce1cb 372 {
j3 0:b5189f4ce1cb 373 //write data back to port
j3 0:b5189f4ce1cb 374 result = _p_io_expander->write_8_ports(low_port, (uint8_t) port_data);
j3 3:89bf07b855e5 375
j3 3:89bf07b855e5 376 if(!result)
j3 3:89bf07b855e5 377 {
j3 3:89bf07b855e5 378 _motor_data_array[(md - 1)].i_reg_mode = mode;
j3 3:89bf07b855e5 379 _motor_data_array[(md - 1)].v_ref = vref;
j3 3:89bf07b855e5 380 }
j3 0:b5189f4ce1cb 381 }
j3 0:b5189f4ce1cb 382
j3 0:b5189f4ce1cb 383 return result;
j3 0:b5189f4ce1cb 384 }
j3 0:b5189f4ce1cb 385
j3 0:b5189f4ce1cb 386
j3 0:b5189f4ce1cb 387 //*********************************************************************
j3 5:a206f6505109 388 int16_t Max14871_Shield::set_pwm_channel(max14871_motor_driver_t md, PinName ch)
j3 5:a206f6505109 389 {
j3 5:a206f6505109 390
j3 5:a206f6505109 391 int16_t result = 0;
j3 5:a206f6505109 392 float pwm_duty_cycle;
j3 5:a206f6505109 393 float pwm_period;
j3 5:a206f6505109 394
j3 5:a206f6505109 395
j3 5:a206f6505109 396 if((ch != D3) && (ch != D4) && (ch != D5) && (ch != D6) &&
j3 5:a206f6505109 397 (ch != D8) && (ch != D9) && (ch != D10) && (ch != D11))
j3 5:a206f6505109 398 {
j3 5:a206f6505109 399 result = -1;
j3 5:a206f6505109 400 }
j3 5:a206f6505109 401 else
j3 5:a206f6505109 402 {
j3 5:a206f6505109 403 switch(md)
j3 5:a206f6505109 404 {
j3 5:a206f6505109 405 case MD1:
j3 5:a206f6505109 406 if((ch != D3) && (ch != D4))
j3 5:a206f6505109 407 {
j3 5:a206f6505109 408 result = -1;
j3 5:a206f6505109 409 }
j3 5:a206f6505109 410 else
j3 5:a206f6505109 411 {
j3 5:a206f6505109 412 pwm_duty_cycle = get_pwm_duty_cycle(md);
j3 5:a206f6505109 413 pwm_period = get_pwm_period(md);
j3 5:a206f6505109 414
j3 5:a206f6505109 415 _p_pwm1->pulsewidth_us(0);
j3 5:a206f6505109 416
j3 5:a206f6505109 417 delete _p_pwm1;
j3 5:a206f6505109 418 _p_pwm1 = new PwmOut(ch);
j3 5:a206f6505109 419
j3 5:a206f6505109 420 set_pwm_period(md, pwm_period);
j3 5:a206f6505109 421 set_pwm_duty_cycle(md, pwm_duty_cycle);
j3 5:a206f6505109 422 }
j3 5:a206f6505109 423 break;
j3 5:a206f6505109 424
j3 5:a206f6505109 425 case MD2:
j3 5:a206f6505109 426 if((ch != D5) && (ch != D6))
j3 5:a206f6505109 427 {
j3 5:a206f6505109 428 result = -1;
j3 5:a206f6505109 429 }
j3 5:a206f6505109 430 else
j3 5:a206f6505109 431 {
j3 5:a206f6505109 432 pwm_duty_cycle = get_pwm_duty_cycle(md);
j3 5:a206f6505109 433 pwm_period = get_pwm_period(md);
j3 5:a206f6505109 434
j3 5:a206f6505109 435 _p_pwm2->pulsewidth_us(0);
j3 5:a206f6505109 436
j3 5:a206f6505109 437 delete _p_pwm2;
j3 5:a206f6505109 438 _p_pwm2 = new PwmOut(ch);
j3 5:a206f6505109 439
j3 5:a206f6505109 440 set_pwm_period(md, pwm_period);
j3 5:a206f6505109 441 set_pwm_duty_cycle(md, pwm_duty_cycle);
j3 5:a206f6505109 442 }
j3 5:a206f6505109 443 break;
j3 5:a206f6505109 444
j3 5:a206f6505109 445 case MD3:
j3 5:a206f6505109 446 if((ch != D8) && (ch != D9))
j3 5:a206f6505109 447 {
j3 5:a206f6505109 448 result = -1;
j3 5:a206f6505109 449 }
j3 5:a206f6505109 450 else
j3 5:a206f6505109 451 {
j3 5:a206f6505109 452 pwm_duty_cycle = get_pwm_duty_cycle(md);
j3 5:a206f6505109 453 pwm_period = get_pwm_period(md);
j3 5:a206f6505109 454
j3 5:a206f6505109 455 _p_pwm3->pulsewidth_us(0);
j3 5:a206f6505109 456
j3 5:a206f6505109 457 delete _p_pwm3;
j3 5:a206f6505109 458 _p_pwm3 = new PwmOut(ch);
j3 5:a206f6505109 459
j3 5:a206f6505109 460 set_pwm_period(md, pwm_period);
j3 5:a206f6505109 461 set_pwm_duty_cycle(md, pwm_duty_cycle);
j3 5:a206f6505109 462 }
j3 5:a206f6505109 463 break;
j3 5:a206f6505109 464
j3 5:a206f6505109 465 case MD4:
j3 5:a206f6505109 466 if((ch != D10) && (ch != D11))
j3 5:a206f6505109 467 {
j3 5:a206f6505109 468 result = -1;
j3 5:a206f6505109 469 }
j3 5:a206f6505109 470 else
j3 5:a206f6505109 471 {
j3 5:a206f6505109 472 pwm_duty_cycle = get_pwm_duty_cycle(md);
j3 5:a206f6505109 473 pwm_period = get_pwm_period(md);
j3 5:a206f6505109 474
j3 5:a206f6505109 475 _p_pwm4->pulsewidth_us(0);
j3 5:a206f6505109 476
j3 5:a206f6505109 477 delete _p_pwm4;
j3 5:a206f6505109 478 _p_pwm4 = new PwmOut(ch);
j3 5:a206f6505109 479
j3 5:a206f6505109 480 set_pwm_period(md, pwm_period);
j3 5:a206f6505109 481 set_pwm_duty_cycle(md, pwm_duty_cycle);
j3 5:a206f6505109 482 }
j3 5:a206f6505109 483 break;
j3 5:a206f6505109 484
j3 5:a206f6505109 485 default:
j3 5:a206f6505109 486 result = -1;
j3 5:a206f6505109 487 break;
j3 5:a206f6505109 488 }
j3 5:a206f6505109 489 }
j3 5:a206f6505109 490
j3 5:a206f6505109 491 return result;
j3 5:a206f6505109 492 }
j3 5:a206f6505109 493
j3 5:a206f6505109 494
j3 5:a206f6505109 495 //*********************************************************************
j3 1:7e9b864ddacf 496 int16_t Max14871_Shield::set_pwm_period(max14871_motor_driver_t md, float period)
j3 0:b5189f4ce1cb 497 {
j3 0:b5189f4ce1cb 498 int16_t result = 0;
j3 0:b5189f4ce1cb 499
j3 0:b5189f4ce1cb 500 if(period < MIN_PERIOD)
j3 0:b5189f4ce1cb 501 {
j3 0:b5189f4ce1cb 502 result = -1;
j3 0:b5189f4ce1cb 503 }
j3 0:b5189f4ce1cb 504 else
j3 0:b5189f4ce1cb 505 {
j3 0:b5189f4ce1cb 506 switch(md)
j3 0:b5189f4ce1cb 507 {
j3 0:b5189f4ce1cb 508 case MD1:
j3 1:7e9b864ddacf 509 _p_pwm1->period(period);
j3 5:a206f6505109 510 _motor_data_array[(md - 1)].period = period;
j3 0:b5189f4ce1cb 511 break;
j3 0:b5189f4ce1cb 512
j3 0:b5189f4ce1cb 513 case MD2:
j3 1:7e9b864ddacf 514 _p_pwm2->period(period);
j3 5:a206f6505109 515 _motor_data_array[(md - 1)].period = period;
j3 0:b5189f4ce1cb 516 break;
j3 0:b5189f4ce1cb 517
j3 0:b5189f4ce1cb 518 case MD3:
j3 1:7e9b864ddacf 519 _p_pwm3->period(period);
j3 5:a206f6505109 520 _motor_data_array[(md - 1)].period = period;
j3 0:b5189f4ce1cb 521 break;
j3 0:b5189f4ce1cb 522
j3 0:b5189f4ce1cb 523 case MD4:
j3 1:7e9b864ddacf 524 _p_pwm4->period(period);
j3 5:a206f6505109 525 _motor_data_array[(md - 1)].period = period;
j3 0:b5189f4ce1cb 526 break;
j3 0:b5189f4ce1cb 527
j3 0:b5189f4ce1cb 528 default:
j3 0:b5189f4ce1cb 529 result = -1;
j3 0:b5189f4ce1cb 530 break;
j3 0:b5189f4ce1cb 531 }
j3 0:b5189f4ce1cb 532 }
j3 0:b5189f4ce1cb 533
j3 0:b5189f4ce1cb 534 return result;
j3 0:b5189f4ce1cb 535 }
j3 0:b5189f4ce1cb 536
j3 0:b5189f4ce1cb 537
j3 0:b5189f4ce1cb 538 //*********************************************************************
j3 1:7e9b864ddacf 539 int16_t Max14871_Shield::set_pwm_duty_cycle(max14871_motor_driver_t md, float duty_cycle)
j3 0:b5189f4ce1cb 540 {
j3 0:b5189f4ce1cb 541 int16_t result = 0;
j3 0:b5189f4ce1cb 542
j3 0:b5189f4ce1cb 543 switch(md)
j3 0:b5189f4ce1cb 544 {
j3 0:b5189f4ce1cb 545 case MD1:
j3 1:7e9b864ddacf 546 _p_pwm1->write(duty_cycle);
j3 3:89bf07b855e5 547 _motor_data_array[(md - 1)].duty_cycle = duty_cycle;
j3 0:b5189f4ce1cb 548 break;
j3 0:b5189f4ce1cb 549
j3 0:b5189f4ce1cb 550 case MD2:
j3 1:7e9b864ddacf 551 _p_pwm2->write(duty_cycle);
j3 3:89bf07b855e5 552 _motor_data_array[(md - 1)].duty_cycle = duty_cycle;
j3 0:b5189f4ce1cb 553 break;
j3 0:b5189f4ce1cb 554
j3 0:b5189f4ce1cb 555 case MD3:
j3 1:7e9b864ddacf 556 _p_pwm3->write(duty_cycle);
j3 3:89bf07b855e5 557 _motor_data_array[(md - 1)].duty_cycle = duty_cycle;
j3 0:b5189f4ce1cb 558 break;
j3 0:b5189f4ce1cb 559
j3 0:b5189f4ce1cb 560 case MD4:
j3 1:7e9b864ddacf 561 _p_pwm4->write(duty_cycle);
j3 3:89bf07b855e5 562 _motor_data_array[(md - 1)].duty_cycle = duty_cycle;
j3 0:b5189f4ce1cb 563 break;
j3 0:b5189f4ce1cb 564
j3 0:b5189f4ce1cb 565 default:
j3 0:b5189f4ce1cb 566 result = -1;
j3 0:b5189f4ce1cb 567 break;
j3 0:b5189f4ce1cb 568 }
j3 0:b5189f4ce1cb 569
j3 0:b5189f4ce1cb 570 return result;
j3 0:b5189f4ce1cb 571 }
j3 3:89bf07b855e5 572
j3 3:89bf07b855e5 573
j3 3:89bf07b855e5 574 //*********************************************************************
j3 3:89bf07b855e5 575 Max14871_Shield::max14871_operating_mode_t Max14871_Shield::get_operating_mode(max14871_motor_driver_t md)
j3 3:89bf07b855e5 576 {
j3 3:89bf07b855e5 577 return(_motor_data_array[(md - 1)].op_mode);
j3 3:89bf07b855e5 578 }
j3 3:89bf07b855e5 579
j3 3:89bf07b855e5 580
j3 3:89bf07b855e5 581 //*********************************************************************
j3 3:89bf07b855e5 582 Max14871_Shield::max14871_current_regulation_mode_t Max14871_Shield::get_current_regulation_mode(max14871_motor_driver_t md)
j3 3:89bf07b855e5 583 {
j3 3:89bf07b855e5 584 return(_motor_data_array[(md - 1)].i_reg_mode);
j3 3:89bf07b855e5 585 }
j3 3:89bf07b855e5 586
j3 3:89bf07b855e5 587
j3 3:89bf07b855e5 588 //*********************************************************************
j3 3:89bf07b855e5 589 float Max14871_Shield::get_pwm_duty_cycle(max14871_motor_driver_t md)
j3 3:89bf07b855e5 590 {
j3 3:89bf07b855e5 591 return(_motor_data_array[(md - 1)].duty_cycle);
j3 3:89bf07b855e5 592 }
j3 3:89bf07b855e5 593
j3 3:89bf07b855e5 594
j3 3:89bf07b855e5 595 //*********************************************************************
j3 5:a206f6505109 596 float Max14871_Shield::get_pwm_period(max14871_motor_driver_t md)
j3 5:a206f6505109 597 {
j3 5:a206f6505109 598 return(_motor_data_array[(md - 1)].period);
j3 5:a206f6505109 599 }
j3 5:a206f6505109 600
j3 5:a206f6505109 601
j3 5:a206f6505109 602 //*********************************************************************
j3 3:89bf07b855e5 603 float Max14871_Shield::get_external_voltage_ref(max14871_motor_driver_t md)
j3 3:89bf07b855e5 604 {
j3 3:89bf07b855e5 605 return(_motor_data_array[(md - 1)].v_ref);
j3 3:89bf07b855e5 606 }
j3 0:b5189f4ce1cb 607
j3 0:b5189f4ce1cb 608
j3 0:b5189f4ce1cb 609 //*********************************************************************
j3 0:b5189f4ce1cb 610 void Max14871_Shield::init_board(void)
j3 0:b5189f4ce1cb 611 {
j3 0:b5189f4ce1cb 612 //configure these ports as outputs
j3 0:b5189f4ce1cb 613 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_04, MAX7300_ALL_OUTPUTS);
j3 0:b5189f4ce1cb 614 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_08, MAX7300_ALL_OUTPUTS);
j3 0:b5189f4ce1cb 615 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_12, MAX7300_ALL_OUTPUTS);
j3 0:b5189f4ce1cb 616 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_16, MAX7300_ALL_OUTPUTS);
j3 0:b5189f4ce1cb 617
j3 0:b5189f4ce1cb 618 //Set /EN and DIR pin of all motor drivers and set mode pin
j3 0:b5189f4ce1cb 619 //of all motor drivers to 0.75V
j3 0:b5189f4ce1cb 620 _p_io_expander->write_8_ports(Max7300::MAX7300_PORT_04, MAX7300_OUTPUT_DEFAULT);
j3 0:b5189f4ce1cb 621 _p_io_expander->write_8_ports(Max7300::MAX7300_PORT_12, MAX7300_OUTPUT_DEFAULT);
j3 0:b5189f4ce1cb 622
j3 0:b5189f4ce1cb 623 //configure these ports as inputs w/pull-up,
j3 0:b5189f4ce1cb 624 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_20, MAX7300_ALL_INPUTS);
j3 0:b5189f4ce1cb 625 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_24, MAX7300_ALL_INPUTS);
j3 0:b5189f4ce1cb 626 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_28, MAX7300_ALL_INPUTS);
j3 0:b5189f4ce1cb 627
j3 0:b5189f4ce1cb 628 //config port 31 as output for interrupt
j3 0:b5189f4ce1cb 629 _p_io_expander->config_port(Max7300::MAX7300_PORT_31, Max7300::MAX7300_PORT_OUTPUT);
j3 0:b5189f4ce1cb 630
j3 0:b5189f4ce1cb 631 _p_io_expander->enable_transition_detection();
j3 0:b5189f4ce1cb 632 _p_io_expander->enable_ports();
j3 0:b5189f4ce1cb 633
j3 2:9b50d36d69c8 634 //set Vref pin of all motor drivers to 0V,
j3 2:9b50d36d69c8 635 //internal vref used for current regulation
j3 2:9b50d36d69c8 636 _p_digi_pot1->write_ch_AB(0);
j3 2:9b50d36d69c8 637 _p_digi_pot2->write_ch_AB(0);
j3 0:b5189f4ce1cb 638
j3 0:b5189f4ce1cb 639 //set switching frequency of all motor drivers to 50KHz
j3 1:7e9b864ddacf 640 _p_pwm1->period(MIN_PERIOD);
j3 1:7e9b864ddacf 641 _p_pwm2->period(MIN_PERIOD);
j3 1:7e9b864ddacf 642 _p_pwm3->period(MIN_PERIOD);
j3 1:7e9b864ddacf 643 _p_pwm4->period(MIN_PERIOD);
j3 3:89bf07b855e5 644
j3 3:89bf07b855e5 645 //init motor data to defaults
j3 3:89bf07b855e5 646 for(uint8_t idx = 0; idx < 4; idx++)
j3 3:89bf07b855e5 647 {
j3 3:89bf07b855e5 648 _motor_data_array[idx].op_mode = COAST;
j3 3:89bf07b855e5 649 _motor_data_array[idx].i_reg_mode = RIPPLE_25_INTERNAL_REF;
j3 3:89bf07b855e5 650 _motor_data_array[idx].duty_cycle = 0.0f;
j3 5:a206f6505109 651 _motor_data_array[idx].period = MIN_PERIOD;
j3 3:89bf07b855e5 652 _motor_data_array[idx].v_ref = 0.0f;
j3 3:89bf07b855e5 653 }
j3 0:b5189f4ce1cb 654 }