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:
Mon Aug 15 19:22:31 2016 +0000
Revision:
7:c0bee1397f3e
Parent:
6:dc06cc75c1c8
Added default value of true for default_config in constructor;; Changing operating mode to coast no longer clears duty cycle to 0

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