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:
Fri May 13 00:03:32 2016 +0000
Revision:
6:dc06cc75c1c8
Parent:
5:a206f6505109
Child:
7:c0bee1397f3e
updated docs

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 1:7e9b864ddacf 172
j3 3:89bf07b855e5 173 set_pwm_duty_cycle(md, 0.0f);
j3 0:b5189f4ce1cb 174 break;
j3 0:b5189f4ce1cb 175
j3 0:b5189f4ce1cb 176 case BRAKE:
j3 0:b5189f4ce1cb 177 if(md % 2)
j3 0:b5189f4ce1cb 178 {
j3 0:b5189f4ce1cb 179 port_data &= ~MD_EN;
j3 0:b5189f4ce1cb 180 }
j3 0:b5189f4ce1cb 181 else
j3 0:b5189f4ce1cb 182 {
j3 0:b5189f4ce1cb 183 port_data &= ~(MD_EN << 4);
j3 0:b5189f4ce1cb 184 }
j3 0:b5189f4ce1cb 185
j3 3:89bf07b855e5 186 set_pwm_duty_cycle(md, 0.0f);
j3 0:b5189f4ce1cb 187 break;
j3 0:b5189f4ce1cb 188
j3 0:b5189f4ce1cb 189 case REVERSE:
j3 0:b5189f4ce1cb 190 if(md % 2)
j3 0:b5189f4ce1cb 191 {
j3 0:b5189f4ce1cb 192 port_data &= ~(MD_EN + MD_DIR);
j3 0:b5189f4ce1cb 193 }
j3 0:b5189f4ce1cb 194 else
j3 0:b5189f4ce1cb 195 {
j3 0:b5189f4ce1cb 196 port_data &= ~((MD_EN + MD_DIR) << 4);
j3 0:b5189f4ce1cb 197 }
j3 0:b5189f4ce1cb 198 break;
j3 0:b5189f4ce1cb 199
j3 0:b5189f4ce1cb 200 case FORWARD:
j3 0:b5189f4ce1cb 201 if(md % 2)
j3 0:b5189f4ce1cb 202 {
j3 0:b5189f4ce1cb 203 port_data &= ~MD_EN;
j3 0:b5189f4ce1cb 204 port_data |= MD_DIR;
j3 0:b5189f4ce1cb 205 }
j3 0:b5189f4ce1cb 206 else
j3 0:b5189f4ce1cb 207 {
j3 0:b5189f4ce1cb 208 port_data &= ~(MD_EN << 4);
j3 0:b5189f4ce1cb 209 port_data |= (MD_DIR << 4);
j3 0:b5189f4ce1cb 210 }
j3 0:b5189f4ce1cb 211 break;
j3 0:b5189f4ce1cb 212
j3 0:b5189f4ce1cb 213 default:
j3 0:b5189f4ce1cb 214 result = -1;
j3 0:b5189f4ce1cb 215 break;
j3 0:b5189f4ce1cb 216 }
j3 0:b5189f4ce1cb 217
j3 0:b5189f4ce1cb 218 if(!result)
j3 0:b5189f4ce1cb 219 {
j3 0:b5189f4ce1cb 220 //write data back to port
j3 0:b5189f4ce1cb 221 result = _p_io_expander->write_8_ports(low_port, (uint8_t) port_data);
j3 3:89bf07b855e5 222
j3 3:89bf07b855e5 223 if(!result)
j3 3:89bf07b855e5 224 {
j3 3:89bf07b855e5 225 _motor_data_array[(md - 1)].op_mode = mode;
j3 3:89bf07b855e5 226 }
j3 0:b5189f4ce1cb 227 }
j3 0:b5189f4ce1cb 228
j3 0:b5189f4ce1cb 229 return result;
j3 0:b5189f4ce1cb 230 }
j3 0:b5189f4ce1cb 231
j3 0:b5189f4ce1cb 232
j3 0:b5189f4ce1cb 233 //*********************************************************************
j3 0:b5189f4ce1cb 234 int16_t Max14871_Shield::set_current_regulation_mode(max14871_motor_driver_t md,
j3 0:b5189f4ce1cb 235 max14871_current_regulation_mode_t mode,
j3 1:7e9b864ddacf 236 float vref)
j3 0:b5189f4ce1cb 237 {
j3 0:b5189f4ce1cb 238 int16_t result = 0;
j3 0:b5189f4ce1cb 239 int16_t port_data;
j3 1:7e9b864ddacf 240 uint8_t local_vref = 0;
j3 0:b5189f4ce1cb 241
j3 0:b5189f4ce1cb 242 Max7300::max7300_port_number_t low_port;
j3 0:b5189f4ce1cb 243 Max5387 *p_digi_pot;
j3 0:b5189f4ce1cb 244
j3 1:7e9b864ddacf 245 if(vref > MAX_VREF)
j3 1:7e9b864ddacf 246 {
j3 1:7e9b864ddacf 247 vref = MAX_VREF;
j3 1:7e9b864ddacf 248 }
j3 2:9b50d36d69c8 249 local_vref = ((uint8_t) ((vref * 255.0f) / 3.3f));
j3 1:7e9b864ddacf 250
j3 0:b5189f4ce1cb 251 //determine the low port of an 8 bit register to read/write
j3 1:7e9b864ddacf 252 //and digipot associated with motor driver
j3 0:b5189f4ce1cb 253 if(md < MD3)
j3 0:b5189f4ce1cb 254 {
j3 0:b5189f4ce1cb 255 low_port = Max7300::MAX7300_PORT_04;
j3 0:b5189f4ce1cb 256 p_digi_pot = _p_digi_pot1;
j3 0:b5189f4ce1cb 257 }
j3 0:b5189f4ce1cb 258 else
j3 0:b5189f4ce1cb 259 {
j3 0:b5189f4ce1cb 260 low_port = Max7300::MAX7300_PORT_12;
j3 0:b5189f4ce1cb 261 p_digi_pot = _p_digi_pot2;
j3 0:b5189f4ce1cb 262 }
j3 0:b5189f4ce1cb 263
j3 0:b5189f4ce1cb 264 //get current state of outputs
j3 0:b5189f4ce1cb 265 port_data = _p_io_expander->read_8_ports(low_port);
j3 0:b5189f4ce1cb 266
j3 0:b5189f4ce1cb 267 switch(mode)
j3 0:b5189f4ce1cb 268 {
j3 0:b5189f4ce1cb 269 case RIPPLE_25_INTERNAL_REF:
j3 0:b5189f4ce1cb 270 if(md % 2)
j3 0:b5189f4ce1cb 271 {
j3 0:b5189f4ce1cb 272 port_data &= ~MD_MODE0;
j3 0:b5189f4ce1cb 273 port_data |= MD_MODE1;
j3 0:b5189f4ce1cb 274 p_digi_pot->write_ch_A(0);
j3 0:b5189f4ce1cb 275 }
j3 0:b5189f4ce1cb 276 else
j3 0:b5189f4ce1cb 277 {
j3 0:b5189f4ce1cb 278 port_data &= ~(MD_MODE0 << 4);
j3 0:b5189f4ce1cb 279 port_data |= (MD_MODE1 << 4);
j3 0:b5189f4ce1cb 280 p_digi_pot->write_ch_B(0);
j3 0:b5189f4ce1cb 281 }
j3 0:b5189f4ce1cb 282 break;
j3 0:b5189f4ce1cb 283
j3 0:b5189f4ce1cb 284 case RIPPLE_25_EXTERNAL_REF:
j3 0:b5189f4ce1cb 285 if(md % 2)
j3 0:b5189f4ce1cb 286 {
j3 0:b5189f4ce1cb 287 port_data &= ~MD_MODE0;
j3 0:b5189f4ce1cb 288 port_data |= MD_MODE1;
j3 1:7e9b864ddacf 289 p_digi_pot->write_ch_A(local_vref);
j3 0:b5189f4ce1cb 290 }
j3 0:b5189f4ce1cb 291 else
j3 0:b5189f4ce1cb 292 {
j3 0:b5189f4ce1cb 293 port_data &= ~(MD_MODE0 << 4);
j3 0:b5189f4ce1cb 294 port_data |= (MD_MODE1 << 4);
j3 1:7e9b864ddacf 295 p_digi_pot->write_ch_B(local_vref);
j3 0:b5189f4ce1cb 296 }
j3 0:b5189f4ce1cb 297 break;
j3 0:b5189f4ce1cb 298
j3 0:b5189f4ce1cb 299 case TCOFF_FAST_INTERNAL_REF:
j3 0:b5189f4ce1cb 300 if(md % 2)
j3 0:b5189f4ce1cb 301 {
j3 0:b5189f4ce1cb 302 port_data |= (MD_MODE1 + MD_MODE0);
j3 0:b5189f4ce1cb 303 p_digi_pot->write_ch_A(0);
j3 0:b5189f4ce1cb 304 }
j3 0:b5189f4ce1cb 305 else
j3 0:b5189f4ce1cb 306 {
j3 0:b5189f4ce1cb 307 port_data |= ((MD_MODE1 + MD_MODE0) << 4);
j3 0:b5189f4ce1cb 308 p_digi_pot->write_ch_B(0);
j3 0:b5189f4ce1cb 309 }
j3 0:b5189f4ce1cb 310 break;
j3 0:b5189f4ce1cb 311
j3 0:b5189f4ce1cb 312 case TCOFF_SLOW_INTERNAL_REF:
j3 0:b5189f4ce1cb 313 if(md % 2)
j3 0:b5189f4ce1cb 314 {
j3 0:b5189f4ce1cb 315 port_data |= MD_MODE0;
j3 0:b5189f4ce1cb 316 port_data &= ~MD_MODE1;
j3 0:b5189f4ce1cb 317 p_digi_pot->write_ch_A(0);
j3 0:b5189f4ce1cb 318 }
j3 0:b5189f4ce1cb 319 else
j3 0:b5189f4ce1cb 320 {
j3 0:b5189f4ce1cb 321 port_data |= (MD_MODE0 << 4);
j3 0:b5189f4ce1cb 322 port_data &= ~(MD_MODE1 << 4);
j3 0:b5189f4ce1cb 323 p_digi_pot->write_ch_B(0);
j3 0:b5189f4ce1cb 324 }
j3 0:b5189f4ce1cb 325 break;
j3 0:b5189f4ce1cb 326
j3 0:b5189f4ce1cb 327 case TCOFF_FAST_EXTERNAL_REF:
j3 0:b5189f4ce1cb 328 if(md % 2)
j3 0:b5189f4ce1cb 329 {
j3 0:b5189f4ce1cb 330 port_data |= (MD_MODE1 + MD_MODE0);
j3 1:7e9b864ddacf 331 p_digi_pot->write_ch_A(local_vref);
j3 0:b5189f4ce1cb 332 }
j3 0:b5189f4ce1cb 333 else
j3 0:b5189f4ce1cb 334 {
j3 0:b5189f4ce1cb 335 port_data |= ((MD_MODE1 + MD_MODE0) << 4);
j3 1:7e9b864ddacf 336 p_digi_pot->write_ch_B(local_vref);
j3 0:b5189f4ce1cb 337 }
j3 0:b5189f4ce1cb 338 break;
j3 0:b5189f4ce1cb 339
j3 0:b5189f4ce1cb 340 case TCOFF_SLOW_EXTERNAL_REF:
j3 0:b5189f4ce1cb 341 if(md % 2)
j3 0:b5189f4ce1cb 342 {
j3 0:b5189f4ce1cb 343 port_data |= MD_MODE0;
j3 0:b5189f4ce1cb 344 port_data &= ~MD_MODE1;
j3 1:7e9b864ddacf 345 p_digi_pot->write_ch_A(local_vref);
j3 0:b5189f4ce1cb 346 }
j3 0:b5189f4ce1cb 347 else
j3 0:b5189f4ce1cb 348 {
j3 0:b5189f4ce1cb 349 port_data |= (MD_MODE0 << 4);
j3 0:b5189f4ce1cb 350 port_data &= ~(MD_MODE1 << 4);
j3 1:7e9b864ddacf 351 p_digi_pot->write_ch_B(local_vref);
j3 0:b5189f4ce1cb 352 }
j3 0:b5189f4ce1cb 353 break;
j3 0:b5189f4ce1cb 354
j3 0:b5189f4ce1cb 355 default:
j3 0:b5189f4ce1cb 356 result = -1;
j3 0:b5189f4ce1cb 357 break;
j3 0:b5189f4ce1cb 358 }
j3 0:b5189f4ce1cb 359
j3 0:b5189f4ce1cb 360 if(!result)
j3 0:b5189f4ce1cb 361 {
j3 0:b5189f4ce1cb 362 //write data back to port
j3 0:b5189f4ce1cb 363 result = _p_io_expander->write_8_ports(low_port, (uint8_t) port_data);
j3 3:89bf07b855e5 364
j3 3:89bf07b855e5 365 if(!result)
j3 3:89bf07b855e5 366 {
j3 3:89bf07b855e5 367 _motor_data_array[(md - 1)].i_reg_mode = mode;
j3 3:89bf07b855e5 368 _motor_data_array[(md - 1)].v_ref = vref;
j3 3:89bf07b855e5 369 }
j3 0:b5189f4ce1cb 370 }
j3 0:b5189f4ce1cb 371
j3 0:b5189f4ce1cb 372 return result;
j3 0:b5189f4ce1cb 373 }
j3 0:b5189f4ce1cb 374
j3 0:b5189f4ce1cb 375
j3 0:b5189f4ce1cb 376 //*********************************************************************
j3 5:a206f6505109 377 int16_t Max14871_Shield::set_pwm_channel(max14871_motor_driver_t md, PinName ch)
j3 5:a206f6505109 378 {
j3 5:a206f6505109 379
j3 5:a206f6505109 380 int16_t result = 0;
j3 5:a206f6505109 381 float pwm_duty_cycle;
j3 5:a206f6505109 382 float pwm_period;
j3 5:a206f6505109 383
j3 5:a206f6505109 384
j3 5:a206f6505109 385 if((ch != D3) && (ch != D4) && (ch != D5) && (ch != D6) &&
j3 5:a206f6505109 386 (ch != D8) && (ch != D9) && (ch != D10) && (ch != D11))
j3 5:a206f6505109 387 {
j3 5:a206f6505109 388 result = -1;
j3 5:a206f6505109 389 }
j3 5:a206f6505109 390 else
j3 5:a206f6505109 391 {
j3 5:a206f6505109 392 switch(md)
j3 5:a206f6505109 393 {
j3 5:a206f6505109 394 case MD1:
j3 5:a206f6505109 395 if((ch != D3) && (ch != D4))
j3 5:a206f6505109 396 {
j3 5:a206f6505109 397 result = -1;
j3 5:a206f6505109 398 }
j3 5:a206f6505109 399 else
j3 5:a206f6505109 400 {
j3 5:a206f6505109 401 pwm_duty_cycle = get_pwm_duty_cycle(md);
j3 5:a206f6505109 402 pwm_period = get_pwm_period(md);
j3 5:a206f6505109 403
j3 5:a206f6505109 404 _p_pwm1->pulsewidth_us(0);
j3 5:a206f6505109 405
j3 5:a206f6505109 406 delete _p_pwm1;
j3 5:a206f6505109 407 _p_pwm1 = new PwmOut(ch);
j3 5:a206f6505109 408
j3 5:a206f6505109 409 set_pwm_period(md, pwm_period);
j3 5:a206f6505109 410 set_pwm_duty_cycle(md, pwm_duty_cycle);
j3 5:a206f6505109 411 }
j3 5:a206f6505109 412 break;
j3 5:a206f6505109 413
j3 5:a206f6505109 414 case MD2:
j3 5:a206f6505109 415 if((ch != D5) && (ch != D6))
j3 5:a206f6505109 416 {
j3 5:a206f6505109 417 result = -1;
j3 5:a206f6505109 418 }
j3 5:a206f6505109 419 else
j3 5:a206f6505109 420 {
j3 5:a206f6505109 421 pwm_duty_cycle = get_pwm_duty_cycle(md);
j3 5:a206f6505109 422 pwm_period = get_pwm_period(md);
j3 5:a206f6505109 423
j3 5:a206f6505109 424 _p_pwm2->pulsewidth_us(0);
j3 5:a206f6505109 425
j3 5:a206f6505109 426 delete _p_pwm2;
j3 5:a206f6505109 427 _p_pwm2 = new PwmOut(ch);
j3 5:a206f6505109 428
j3 5:a206f6505109 429 set_pwm_period(md, pwm_period);
j3 5:a206f6505109 430 set_pwm_duty_cycle(md, pwm_duty_cycle);
j3 5:a206f6505109 431 }
j3 5:a206f6505109 432 break;
j3 5:a206f6505109 433
j3 5:a206f6505109 434 case MD3:
j3 5:a206f6505109 435 if((ch != D8) && (ch != D9))
j3 5:a206f6505109 436 {
j3 5:a206f6505109 437 result = -1;
j3 5:a206f6505109 438 }
j3 5:a206f6505109 439 else
j3 5:a206f6505109 440 {
j3 5:a206f6505109 441 pwm_duty_cycle = get_pwm_duty_cycle(md);
j3 5:a206f6505109 442 pwm_period = get_pwm_period(md);
j3 5:a206f6505109 443
j3 5:a206f6505109 444 _p_pwm3->pulsewidth_us(0);
j3 5:a206f6505109 445
j3 5:a206f6505109 446 delete _p_pwm3;
j3 5:a206f6505109 447 _p_pwm3 = new PwmOut(ch);
j3 5:a206f6505109 448
j3 5:a206f6505109 449 set_pwm_period(md, pwm_period);
j3 5:a206f6505109 450 set_pwm_duty_cycle(md, pwm_duty_cycle);
j3 5:a206f6505109 451 }
j3 5:a206f6505109 452 break;
j3 5:a206f6505109 453
j3 5:a206f6505109 454 case MD4:
j3 5:a206f6505109 455 if((ch != D10) && (ch != D11))
j3 5:a206f6505109 456 {
j3 5:a206f6505109 457 result = -1;
j3 5:a206f6505109 458 }
j3 5:a206f6505109 459 else
j3 5:a206f6505109 460 {
j3 5:a206f6505109 461 pwm_duty_cycle = get_pwm_duty_cycle(md);
j3 5:a206f6505109 462 pwm_period = get_pwm_period(md);
j3 5:a206f6505109 463
j3 5:a206f6505109 464 _p_pwm4->pulsewidth_us(0);
j3 5:a206f6505109 465
j3 5:a206f6505109 466 delete _p_pwm4;
j3 5:a206f6505109 467 _p_pwm4 = new PwmOut(ch);
j3 5:a206f6505109 468
j3 5:a206f6505109 469 set_pwm_period(md, pwm_period);
j3 5:a206f6505109 470 set_pwm_duty_cycle(md, pwm_duty_cycle);
j3 5:a206f6505109 471 }
j3 5:a206f6505109 472 break;
j3 5:a206f6505109 473
j3 5:a206f6505109 474 default:
j3 5:a206f6505109 475 result = -1;
j3 5:a206f6505109 476 break;
j3 5:a206f6505109 477 }
j3 5:a206f6505109 478 }
j3 5:a206f6505109 479
j3 5:a206f6505109 480 return result;
j3 5:a206f6505109 481 }
j3 5:a206f6505109 482
j3 5:a206f6505109 483
j3 5:a206f6505109 484 //*********************************************************************
j3 1:7e9b864ddacf 485 int16_t Max14871_Shield::set_pwm_period(max14871_motor_driver_t md, float period)
j3 0:b5189f4ce1cb 486 {
j3 0:b5189f4ce1cb 487 int16_t result = 0;
j3 0:b5189f4ce1cb 488
j3 0:b5189f4ce1cb 489 if(period < MIN_PERIOD)
j3 0:b5189f4ce1cb 490 {
j3 0:b5189f4ce1cb 491 result = -1;
j3 0:b5189f4ce1cb 492 }
j3 0:b5189f4ce1cb 493 else
j3 0:b5189f4ce1cb 494 {
j3 0:b5189f4ce1cb 495 switch(md)
j3 0:b5189f4ce1cb 496 {
j3 0:b5189f4ce1cb 497 case MD1:
j3 1:7e9b864ddacf 498 _p_pwm1->period(period);
j3 5:a206f6505109 499 _motor_data_array[(md - 1)].period = period;
j3 0:b5189f4ce1cb 500 break;
j3 0:b5189f4ce1cb 501
j3 0:b5189f4ce1cb 502 case MD2:
j3 1:7e9b864ddacf 503 _p_pwm2->period(period);
j3 5:a206f6505109 504 _motor_data_array[(md - 1)].period = period;
j3 0:b5189f4ce1cb 505 break;
j3 0:b5189f4ce1cb 506
j3 0:b5189f4ce1cb 507 case MD3:
j3 1:7e9b864ddacf 508 _p_pwm3->period(period);
j3 5:a206f6505109 509 _motor_data_array[(md - 1)].period = period;
j3 0:b5189f4ce1cb 510 break;
j3 0:b5189f4ce1cb 511
j3 0:b5189f4ce1cb 512 case MD4:
j3 1:7e9b864ddacf 513 _p_pwm4->period(period);
j3 5:a206f6505109 514 _motor_data_array[(md - 1)].period = period;
j3 0:b5189f4ce1cb 515 break;
j3 0:b5189f4ce1cb 516
j3 0:b5189f4ce1cb 517 default:
j3 0:b5189f4ce1cb 518 result = -1;
j3 0:b5189f4ce1cb 519 break;
j3 0:b5189f4ce1cb 520 }
j3 0:b5189f4ce1cb 521 }
j3 0:b5189f4ce1cb 522
j3 0:b5189f4ce1cb 523 return result;
j3 0:b5189f4ce1cb 524 }
j3 0:b5189f4ce1cb 525
j3 0:b5189f4ce1cb 526
j3 0:b5189f4ce1cb 527 //*********************************************************************
j3 1:7e9b864ddacf 528 int16_t Max14871_Shield::set_pwm_duty_cycle(max14871_motor_driver_t md, float duty_cycle)
j3 0:b5189f4ce1cb 529 {
j3 0:b5189f4ce1cb 530 int16_t result = 0;
j3 0:b5189f4ce1cb 531
j3 0:b5189f4ce1cb 532 switch(md)
j3 0:b5189f4ce1cb 533 {
j3 0:b5189f4ce1cb 534 case MD1:
j3 1:7e9b864ddacf 535 _p_pwm1->write(duty_cycle);
j3 3:89bf07b855e5 536 _motor_data_array[(md - 1)].duty_cycle = duty_cycle;
j3 0:b5189f4ce1cb 537 break;
j3 0:b5189f4ce1cb 538
j3 0:b5189f4ce1cb 539 case MD2:
j3 1:7e9b864ddacf 540 _p_pwm2->write(duty_cycle);
j3 3:89bf07b855e5 541 _motor_data_array[(md - 1)].duty_cycle = duty_cycle;
j3 0:b5189f4ce1cb 542 break;
j3 0:b5189f4ce1cb 543
j3 0:b5189f4ce1cb 544 case MD3:
j3 1:7e9b864ddacf 545 _p_pwm3->write(duty_cycle);
j3 3:89bf07b855e5 546 _motor_data_array[(md - 1)].duty_cycle = duty_cycle;
j3 0:b5189f4ce1cb 547 break;
j3 0:b5189f4ce1cb 548
j3 0:b5189f4ce1cb 549 case MD4:
j3 1:7e9b864ddacf 550 _p_pwm4->write(duty_cycle);
j3 3:89bf07b855e5 551 _motor_data_array[(md - 1)].duty_cycle = duty_cycle;
j3 0:b5189f4ce1cb 552 break;
j3 0:b5189f4ce1cb 553
j3 0:b5189f4ce1cb 554 default:
j3 0:b5189f4ce1cb 555 result = -1;
j3 0:b5189f4ce1cb 556 break;
j3 0:b5189f4ce1cb 557 }
j3 0:b5189f4ce1cb 558
j3 0:b5189f4ce1cb 559 return result;
j3 0:b5189f4ce1cb 560 }
j3 3:89bf07b855e5 561
j3 3:89bf07b855e5 562
j3 3:89bf07b855e5 563 //*********************************************************************
j3 3:89bf07b855e5 564 Max14871_Shield::max14871_operating_mode_t Max14871_Shield::get_operating_mode(max14871_motor_driver_t md)
j3 3:89bf07b855e5 565 {
j3 3:89bf07b855e5 566 return(_motor_data_array[(md - 1)].op_mode);
j3 3:89bf07b855e5 567 }
j3 3:89bf07b855e5 568
j3 3:89bf07b855e5 569
j3 3:89bf07b855e5 570 //*********************************************************************
j3 3:89bf07b855e5 571 Max14871_Shield::max14871_current_regulation_mode_t Max14871_Shield::get_current_regulation_mode(max14871_motor_driver_t md)
j3 3:89bf07b855e5 572 {
j3 3:89bf07b855e5 573 return(_motor_data_array[(md - 1)].i_reg_mode);
j3 3:89bf07b855e5 574 }
j3 3:89bf07b855e5 575
j3 3:89bf07b855e5 576
j3 3:89bf07b855e5 577 //*********************************************************************
j3 3:89bf07b855e5 578 float Max14871_Shield::get_pwm_duty_cycle(max14871_motor_driver_t md)
j3 3:89bf07b855e5 579 {
j3 3:89bf07b855e5 580 return(_motor_data_array[(md - 1)].duty_cycle);
j3 3:89bf07b855e5 581 }
j3 3:89bf07b855e5 582
j3 3:89bf07b855e5 583
j3 3:89bf07b855e5 584 //*********************************************************************
j3 5:a206f6505109 585 float Max14871_Shield::get_pwm_period(max14871_motor_driver_t md)
j3 5:a206f6505109 586 {
j3 5:a206f6505109 587 return(_motor_data_array[(md - 1)].period);
j3 5:a206f6505109 588 }
j3 5:a206f6505109 589
j3 5:a206f6505109 590
j3 5:a206f6505109 591 //*********************************************************************
j3 3:89bf07b855e5 592 float Max14871_Shield::get_external_voltage_ref(max14871_motor_driver_t md)
j3 3:89bf07b855e5 593 {
j3 3:89bf07b855e5 594 return(_motor_data_array[(md - 1)].v_ref);
j3 3:89bf07b855e5 595 }
j3 0:b5189f4ce1cb 596
j3 0:b5189f4ce1cb 597
j3 0:b5189f4ce1cb 598 //*********************************************************************
j3 0:b5189f4ce1cb 599 void Max14871_Shield::init_board(void)
j3 0:b5189f4ce1cb 600 {
j3 0:b5189f4ce1cb 601 //configure these ports as outputs
j3 0:b5189f4ce1cb 602 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_04, MAX7300_ALL_OUTPUTS);
j3 0:b5189f4ce1cb 603 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_08, MAX7300_ALL_OUTPUTS);
j3 0:b5189f4ce1cb 604 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_12, MAX7300_ALL_OUTPUTS);
j3 0:b5189f4ce1cb 605 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_16, MAX7300_ALL_OUTPUTS);
j3 0:b5189f4ce1cb 606
j3 0:b5189f4ce1cb 607 //Set /EN and DIR pin of all motor drivers and set mode pin
j3 0:b5189f4ce1cb 608 //of all motor drivers to 0.75V
j3 0:b5189f4ce1cb 609 _p_io_expander->write_8_ports(Max7300::MAX7300_PORT_04, MAX7300_OUTPUT_DEFAULT);
j3 0:b5189f4ce1cb 610 _p_io_expander->write_8_ports(Max7300::MAX7300_PORT_12, MAX7300_OUTPUT_DEFAULT);
j3 0:b5189f4ce1cb 611
j3 0:b5189f4ce1cb 612 //configure these ports as inputs w/pull-up,
j3 0:b5189f4ce1cb 613 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_20, MAX7300_ALL_INPUTS);
j3 0:b5189f4ce1cb 614 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_24, MAX7300_ALL_INPUTS);
j3 0:b5189f4ce1cb 615 _p_io_expander->config_4_ports(Max7300::MAX7300_PORT_28, MAX7300_ALL_INPUTS);
j3 0:b5189f4ce1cb 616
j3 0:b5189f4ce1cb 617 //config port 31 as output for interrupt
j3 0:b5189f4ce1cb 618 _p_io_expander->config_port(Max7300::MAX7300_PORT_31, Max7300::MAX7300_PORT_OUTPUT);
j3 0:b5189f4ce1cb 619
j3 0:b5189f4ce1cb 620 _p_io_expander->enable_transition_detection();
j3 0:b5189f4ce1cb 621 _p_io_expander->enable_ports();
j3 0:b5189f4ce1cb 622
j3 2:9b50d36d69c8 623 //set Vref pin of all motor drivers to 0V,
j3 2:9b50d36d69c8 624 //internal vref used for current regulation
j3 2:9b50d36d69c8 625 _p_digi_pot1->write_ch_AB(0);
j3 2:9b50d36d69c8 626 _p_digi_pot2->write_ch_AB(0);
j3 0:b5189f4ce1cb 627
j3 0:b5189f4ce1cb 628 //set switching frequency of all motor drivers to 50KHz
j3 1:7e9b864ddacf 629 _p_pwm1->period(MIN_PERIOD);
j3 1:7e9b864ddacf 630 _p_pwm2->period(MIN_PERIOD);
j3 1:7e9b864ddacf 631 _p_pwm3->period(MIN_PERIOD);
j3 1:7e9b864ddacf 632 _p_pwm4->period(MIN_PERIOD);
j3 3:89bf07b855e5 633
j3 3:89bf07b855e5 634 //init motor data to defaults
j3 3:89bf07b855e5 635 for(uint8_t idx = 0; idx < 4; idx++)
j3 3:89bf07b855e5 636 {
j3 3:89bf07b855e5 637 _motor_data_array[idx].op_mode = COAST;
j3 3:89bf07b855e5 638 _motor_data_array[idx].i_reg_mode = RIPPLE_25_INTERNAL_REF;
j3 3:89bf07b855e5 639 _motor_data_array[idx].duty_cycle = 0.0f;
j3 5:a206f6505109 640 _motor_data_array[idx].period = MIN_PERIOD;
j3 3:89bf07b855e5 641 _motor_data_array[idx].v_ref = 0.0f;
j3 3:89bf07b855e5 642 }
j3 0:b5189f4ce1cb 643 }