form of HeloWorld_IHM04A1
Dependencies: FastPWM mbed ST_INTERFACES
Fork of HelloWorld_IHM04A1 by
Revision 9:b7fc55bf70b2, committed 2017-07-21
- Comitter:
- cerimis
- Date:
- Fri Jul 21 11:19:39 2017 +0000
- Parent:
- 8:05340e740644
- Commit message:
- first commit
Changed in this revision
diff -r 05340e740644 -r b7fc55bf70b2 FastPWM.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastPWM.lib Fri Jul 21 11:19:39 2017 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/Sissors/code/FastPWM/#e880dcb178f4
diff -r 05340e740644 -r b7fc55bf70b2 X_NUCLEO_IHM04A1.lib --- a/X_NUCLEO_IHM04A1.lib Wed May 24 15:36:18 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://developer.mbed.org/teams/ST/code/X_NUCLEO_IHM04A1/#51ad3c4b904c
diff -r 05340e740644 -r b7fc55bf70b2 X_NUCLEO_IHM04A1/Components/Common/component_def.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IHM04A1/Components/Common/component_def.h Fri Jul 21 11:19:39 2017 +0000 @@ -0,0 +1,93 @@ +/** + ****************************************************************************** + * @file component_def.h + * @author AST + * @version V1.0.0 + * @date 1 April 2015 + * @brief Generic header file containing a generic component's definitions + * and I/O functions. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __COMPONENT_H +#define __COMPONENT_H + + +/* Types ---------------------------------------------------------------------*/ + +/** + * @brief Component's Context structure definition. + */ +typedef struct +{ + /* Identity. */ + uint8_t who_am_i; + + /* ACTION ----------------------------------------------------------------*/ + /* There should be only a unique identifier for each component, which */ + /* should be the "who_am_i" parameter, hence this parameter is optional. */ + /* -----------------------------------------------------------------------*/ + /* Type. */ + uint8_t type; + + /* Configuration. */ + uint8_t address; + + /* Pointer to the Data. */ + void *p_data; + + /* Pointer to the Virtual Table. */ + void *p_vt; + + /* ACTION ----------------------------------------------------------------*/ + /* There should be only a unique virtual table for each component, which */ + /* should be the "p_vt" parameter, hence this parameter is optional. */ + /* -----------------------------------------------------------------------*/ + /* Pointer to the Extended Virtual Table. */ + void *p_ext_vt; +} handle_t; + +/** + * @brief Component's Status enumerator definition. + */ +typedef enum +{ + COMPONENT_OK = 0, + COMPONENT_ERROR, + COMPONENT_TIMEOUT, + COMPONENT_NOT_IMPLEMENTED +} status_t; + +#endif /* __COMPONENT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff -r 05340e740644 -r b7fc55bf70b2 X_NUCLEO_IHM04A1/Components/Common/motor_def.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IHM04A1/Components/Common/motor_def.h Fri Jul 21 11:19:39 2017 +0000 @@ -0,0 +1,437 @@ +/** + ****************************************************************************** + * @file motor_def.h + * @author IPC Rennes + * @version V1.5.0 + * @date January 25, 2016 + * @brief This file contains all the functions prototypes for motor drivers. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MOTOR_H +#define __MOTOR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> +#include "component_def.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @defgroup Motor Motor + * @{ + */ + +/** @defgroup Motor_Exported_Constants Motor Exported Constants + * @{ + */ + +/// boolean for false condition +#ifndef FALSE +#define FALSE (0) +#endif +/// boolean for true condition +#ifndef TRUE +#define TRUE (1) +#endif + + /** + * @} + */ + +/** @defgroup Motor_Exported_Types Motor Exported Types + * @{ + */ + +/** @defgroup Motor_Boolean_Type Motor Boolean Type + * @{ + */ +///bool Type +//typedef uint8_t bool; +/** + * @} + */ + +/** @defgroup Device_Direction_Options Device Direction Options + * @{ + */ +/// Direction options +typedef enum { + BACKWARD = 0, + FORWARD = 1, + UNKNOW_DIR = ((uint8_t)0xFF) +} motorDir_t; +/** + * @} + */ + +/** @defgroup Device_Action_Options Device Action Options + * @{ + */ +/// Action options +typedef enum { + ACTION_RESET = ((uint8_t)0x00), + ACTION_COPY = ((uint8_t)0x08) +} motorAction_t; +/** + * @} + */ + +/** @defgroup Device_States Device States + * @{ + */ +/// Device states +typedef enum { + ACCELERATING = 0, + DECELERATINGTOSTOP = 1, + DECELERATING = 2, + STEADY = 3, + INDEX_ACCEL = 4, + INDEX_RUN = 5, + INDEX_DECEL = 6, + INDEX_DWELL = 7, + INACTIVE = 8, + STANDBY = 9, + STANDBYTOINACTIVE = 10 +} motorState_t; +/** + * @} + */ + +/** @defgroup Device_Step_mode Device Step mode + * @{ + */ + /// Stepping options +typedef enum { + STEP_MODE_FULL = ((uint8_t)0x00), + STEP_MODE_HALF = ((uint8_t)0x01), + STEP_MODE_1_4 = ((uint8_t)0x02), + STEP_MODE_1_8 = ((uint8_t)0x03), + STEP_MODE_1_16 = ((uint8_t)0x04), + STEP_MODE_1_32 = ((uint8_t)0x05), + STEP_MODE_1_64 = ((uint8_t)0x06), + STEP_MODE_1_128 = ((uint8_t)0x07), + STEP_MODE_1_256 = ((uint8_t)0x08), + STEP_MODE_UNKNOW = ((uint8_t)0xFE), + STEP_MODE_WAVE = ((uint8_t)0xFF) +} motorStepMode_t; + +/** + * @} + */ + +/** @defgroup Decay_mode Decay mode + * @{ + */ +/// Decay Mode +typedef enum { + SLOW_DECAY = 0, + FAST_DECAY = 1, + UNKNOW_DECAY = ((uint8_t)0xFF) +} motorDecayMode_t; +/** + * @} + */ + +/** @defgroup Stop_mode Stop mode + * @{ + */ +/// Stop mode +typedef enum +{ + HOLD_MODE = 0, + HIZ_MODE = 1, + STANDBY_MODE = 2, + UNKNOW_STOP_MODE = ((uint8_t)0xFF) +} motorStopMode_t; +/** + * @} + */ + +/** @defgroup Torque_mode Torque mode + * @{ + */ +/// Torque mode +typedef enum +{ + ACC_TORQUE = 0, + DEC_TORQUE = 1, + RUN_TORQUE = 2, + HOLD_TORQUE = 3, + CURRENT_TORQUE = 4, + UNKNOW_TORQUE = ((uint8_t)0xFF) +} motorTorqueMode_t; +/** + * @} + */ + +/** @defgroup Dual_Full_Bridge_Configuration Dual Full Bridge Configuration + * @{ + */ +///Dual full bridge configurations for brush DC motors +typedef enum { + PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B = 0, + PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B = 1, + PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B = 2, + PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B = 3, + PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B = 4, + PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B = 5, + PARALLELING_IN1B_IN2B__1_BIDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B = 6, + PARALLELING_IN1B_IN2B__2_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B = 7, + PARALLELING_IN1A_IN2A__IN1B_IN2B__1_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B = 8, + PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR = 9, + PARALLELING_IN1A_IN1B__IN2A_IN2B__1_UNDIR_MOTOR_BRIDGE_1A__1_UNDIR_MOTOR_BRIDGE_2A = 10, + PARALLELING_IN1A_IN1B__IN2A_IN2B__1_BIDIR_MOTOR = 11, + PARALLELING_ALL_WITH_IN1A___1_UNDIR_MOTOR = 12, + PARALLELING_END_ENUM = 13 +} dualFullBridgeConfig_t; +/** + * @} + */ + +/** @defgroup Motor_Driver_Structure Motor Driver Structure + * @{ + */ +/// Motor driver structure definition +typedef struct +{ + + /* Generic */ + status_t (*init)(void *handle, void *init); + status_t (*read_id)(void *handle, uint8_t *id); + + /* Interrupts */ + /// Function pointer to attach_error_handler + void(*attach_error_handler)(void *handle, void (*callback)(void *handle, uint16_t error)); + /// Function pointer to attach_flag_interrupt + void (*attach_flag_interrupt)(void *handle, void (*callback)(void *handle)); + /// Function pointer to AttachBusyInterrupt + void (*AttachBusyInterrupt)(void *handle, void (*callback)(void *handle)); + /// Function pointer to FlagInterruptHandler + void (*FlagInterruptHandler)(void *handle); + + /* Specific */ + /// Function pointer to get_acceleration + uint16_t (*get_acceleration)(void *handle); + /// Function pointer to GetCurrentSpeed + uint16_t (*GetCurrentSpeed)(void *handle, uint8_t motorId); + /// Function pointer to get_deceleration + uint16_t (*get_deceleration)(void *handle); + /// Function pointer to get_device_state + motorState_t(*get_device_state)(void *handle, uint8_t motorId); + /// Function pointer to get_fw_version + uint8_t (*get_fw_version)(void *handle); + /// Function pointer to get_mark + int32_t (*get_mark)(void *handle); + /// Function pointer to get_max_speed + uint16_t (*get_max_speed)(void *handle, uint8_t motorId); + /// Function pointer to get_min_speed + uint16_t (*get_min_speed)(void *handle, uint8_t motorId); + /// Function pointer to get_position + int32_t (*get_position)(void *handle); + /// Function pointer to go_home + void (*go_home)(void *handle); + /// Function pointer to go_mark + void (*go_mark)(void *handle); + /// Function pointer to go_to + void (*go_to)(void *handle, uint8_t deviceId, int32_t motorId); + /// Function pointer to hard_stop + void (*hard_stop)(void *handle, uint8_t motorId); + /// Function pointer to move + void (*move)(void *handle, motorDir_t direction, uint32_t stepCount); + /// Function pointer to ResetAllDevices + void (*ResetAllDevices)(void *handle); + /// Function pointer to run + void (*run)(void *handle, uint8_t stepCount, motorDir_t direction); + /// Function pointer to set_acceleration + bool(*set_acceleration)(void *handle, uint16_t newAcc); + /// Function pointer to set_deceleration + bool(*set_deceleration)(void *handle, uint16_t newDec); + /// Function pointer to set_home + void (*set_home)(void *handle); + /// Function pointer to set_mark + void (*set_mark)(void *handle); + /// Function pointer to set_max_speed + bool (*set_max_speed)(void *handle, uint8_t motorId, uint16_t newMaxSpeed); + /// Function pointer to set_min_speed + bool (*set_min_speed)(void *handle, uint8_t motorId, uint16_t newMinSpeed); + /// Function pointer to soft_stop + bool (*soft_stop)(void *handle); + /// Function pointer to StepClockHandler + void (*StepClockHandler)(void *handle); + /// Function pointer to wait_while_active + void (*wait_while_active)(void *handle); + /// Function pointer to CmdDisable + void (*CmdDisable)(void *handle, uint8_t bridgeId); + /// Function pointer to CmdEnable + void (*CmdEnable)(void *handle, uint8_t bridgeId); + /// Function pointer to CmdGetParam + uint32_t (*CmdGetParam)(void *handle, uint32_t param); + /// Function pointer to CmdGetStatus + uint16_t (*CmdGetStatus)(void *handle, uint8_t bridgeId); + /// Function pointer to CmdNop + void (*CmdNop)(void *handle); + /// Function pointer to CmdSetParam + void (*CmdSetParam)(void *handle, uint32_t param, uint32_t value); + /// Function pointer to read_status_register + uint16_t (*read_status_register)(void *handle); + /// Function pointer to release_reset + void (*release_reset)(void *handle); + /// Function pointer to Reset + void (*Reset)(void *handle); + /// Function pointer to SelectStepMode + void (*SelectStepMode)(void *handle, motorStepMode_t stepMode); + /// Function pointer to set_direction + void (*set_direction)(void *handle, motorDir_t direction); + /// Function pointer to CmdGoToDir + void (*CmdGoToDir)(void *handle, motorDir_t direction, int32_t abs_pos); + /// Function pointer to check_busy_hw + uint8_t (*check_busy_hw)(void *handle); + /// Function pointer to check_status_hw + uint8_t (*check_status_hw)(void *handle); + /// Function pointer to CmdGoUntil + void (*CmdGoUntil)(void *handle, motorAction_t action, motorDir_t direction, uint32_t speed); + /// Function pointer to CmdHardHiZ + void (*CmdHardHiZ)(void *handle, uint8_t motorId); + /// Function pointer to CmdReleaseSw + void (*CmdReleaseSw)(void *handle, motorAction_t action, motorDir_t direction); + /// Function pointer to CmdResetDevice + void (*CmdResetDevice)(void *handle); + /// Function pointer to CmdResetPos + void (*CmdResetPos)(void *handle); + /// Function pointer to CmdRun + void (*CmdRun)(void *handle, motorDir_t direction, uint32_t speed); + /// Function pointer to CmdSoftHiZ + void (*CmdSoftHiZ)(void *handle); + /// Function pointer to CmdStepClock + void (*CmdStepClock)(void *handle, motorDir_t direction); + /// Function pointer to fetch_and_clear_all_status + void (*fetch_and_clear_all_status)(void *handle); + /// Function pointer to get_fetched_status + uint16_t (*get_fetched_status)(void *handle); + /// Function pointer to get_nb_devices + uint8_t (*get_nb_devices)(void *handle); + /// Function pointer to is_device_busy + bool (*is_device_busy)(void *handle); + /// Function pointer to send_queued_commands + void (*send_queued_commands)(void *handle); + /// Function pointer to queue_commands + void (*queue_commands)(void *handle, uint8_t param, int32_t value); + /// Function pointer to WaitForAllDevicesNotBusy + void (*WaitForAllDevicesNotBusy)(void *handle); + /// Function pointer to error_handler + void (*error_handler)(void *handle, uint16_t error); + /// Function pointer to BusyInterruptHandler + void (*BusyInterruptHandler)(void *handle); + /// Function pointer to CmdSoftStop + void (*CmdSoftStop)(void *handle); + /// Function pointer to StartStepClock + void (*StartStepClock)(void *handle); + /// Function pointer to StopStepClock + void (*StopStepClock)(void *handle); + /// Function pointer to set_dual_full_bridge_config + void (*set_dual_full_bridge_config)(void *handle, uint8_t newConfig); + /// Function pointer to get_bridge_input_pwm_freq + uint32_t (*get_bridge_input_pwm_freq)(void *handle, uint8_t bridgeId); + /// Function pointer to set_bridge_input_pwm_freq + void (*set_bridge_input_pwm_freq)(void *handle, uint8_t bridgeId, uint32_t newFreq); + /// Function pointer to set_stop_mode + void (*set_stop_mode)(void *handle, motorStopMode_t stopMode); + /// Function pointer to get_stop_mode + motorStopMode_t (*get_stop_mode)(void *handle); + /// Function pointer to set_decay_mode + void (*set_decay_mode)(void *handle, motorDecayMode_t decayMode); + /// Function pointer to get_decay_mode + motorDecayMode_t (*get_decay_mode)(void *handle); + /// Function pointer to get_step_mode + motorStepMode_t (*get_step_mode)(void *handle); + /// Function pointer to get_direction + motorDir_t (*get_direction)(void *handle); + /// Function pointer to ExitDeviceFromReset + void (*ExitDeviceFromReset)(void *handle); + /// Function pointer to set_torque + void (*set_torque)(void *handle, motorTorqueMode_t torqueMode, uint8_t torqueValue); + /// Function pointer to get_torque + uint8_t (*get_torque)(void *handle, motorTorqueMode_t torqueMode); + /// Function pointer to SetVRefFreq + void (*SetRefFreq)(void *handle, uint32_t freq); + /// Function pointer to GetVRefFreq + uint32_t (*GetRefFreq)(void *handle); + /// Function pointer to SetVRefDc + void (*SetRefDc)(void *handle, uint8_t RefDc); + /// Function pointer to GetVRefDc + uint8_t (*GetRefDc)(void *handle); + /// Function pointer to set_nb_devices + bool (*set_nb_devices)(void *handle, uint8_t nbDevices); + /// Function pointer to set a parameter + bool (*set_analog_value)(void *handle, uint32_t param, float value); + /// Function pointer to get a parameter + float (*get_analog_value)(void *handle, uint32_t param); +} MOTOR_VTable_t; + +/** + +* @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MOTOR_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
diff -r 05340e740644 -r b7fc55bf70b2 X_NUCLEO_IHM04A1/Components/L6206/L6206.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IHM04A1/Components/L6206/L6206.cpp Fri Jul 21 11:19:39 2017 +0000 @@ -0,0 +1,1281 @@ +/** + ****************************************************************************** + * @file L6206.cpp + * @author IPC Rennes + * @version V1.1.0 + * @date March 02, 2016 + * @brief L6206 driver (dual full bridge driver) + * @note (C) COPYRIGHT 2015 STMicroelectronics + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/* Generated with STM32CubeTOO -----------------------------------------------*/ + + +/* Revision ------------------------------------------------------------------*/ +/* + Repository: http://svn.x-nucleodev.codex.cro.st.com/svnroot/X-NucleoDev + Branch/Trunk/Tag: trunk + Based on: X-CUBE-SPN4/trunk/Drivers/BSP/Components/L6206/L6206.c + Revision: 0 +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "L6206.h" +#include "string.h" + + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup L6206 + * @{ + */ + +/* Private constants ---------------------------------------------------------*/ + + +/* Private variables ---------------------------------------------------------*/ + +/** @defgroup L6206_Private_Variables L6206 Private Variables + * @{ + */ +static uint8_t l6206ArrayNbMaxMotorsByConfig[PARALLELING_END_ENUM] = {2,3,3,4,2,3,2,3,2,1,2,1,1}; + /** + * @} + */ + +/* Private constant ---------------------------------------------------------*/ + + +/* Public Function prototypes -----------------------------------------------*/ + + + +/* Private function prototypes -----------------------------------------------*/ + +/** @defgroup L6206_Private_functions L6206 Private functions + * @{ + */ + + +/******************************************************//** + * @brief Attaches a user callback to the error Handler. + * The call back will be then called each time the library + * detects an error + * @param[in] callback Name of the callback to attach + * to the error Hanlder + * @retval None + **********************************************************/ +void L6206::L6206_AttachErrorHandler(void (*callback)(uint16_t error)) +{ + errorHandlerCallback = (void (*)(uint16_t error)) callback; +} + +/******************************************************//** + * @brief Attaches a user callback to the flag Interrupt + * The call back will be then called each time the status + * flag pin will be pulled down due to the occurrence of + * a programmed alarms ( OCD, thermal alert) + * @param[in] callback Name of the callback to attach + * to the Flag Interrupt + * @retval None + **********************************************************/ +void L6206::L6206_attach_flag_interrupt(void (*callback)(void)) +{ + flagInterruptCallback = (void (*)(void))callback; +} + +/******************************************************//** + * @brief Disable the specified bridge + * @param[in] bridgeId (from 0 for bridge A to 1 for bridge B) + * @retval None + * @note When input of different brigdes are parallelized + * together, the disabling of one bridge leads to the disabling + * of the second one + **********************************************************/ +void L6206::L6206_DisableBridge(uint8_t bridgeId) +{ + L6206_Board_DisableBridge(bridgeId); + + devicePrm.bridgeEnabled[bridgeId] = FALSE; + if (devicePrm.config >= PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR) + { + if (bridgeId == BRIDGE_A) + { + L6206_Board_DisableBridge(BRIDGE_B); + devicePrm.bridgeEnabled[BRIDGE_B] = FALSE; + } + else + { + L6206_Board_DisableBridge(BRIDGE_A); + devicePrm.bridgeEnabled[BRIDGE_A] = FALSE; + } + } +} + +/******************************************************//** + * @brief Enable the specified bridge + * @param[in] bridgeId (from 0 for bridge A to 1 for bridge B) + * @retval None + * @note When input of different brigdes are parallelized + * together, the enabling of one bridge leads to the enabling + * of the second one + **********************************************************/ +void L6206::L6206_EnableBridge(uint8_t bridgeId) +{ + devicePrm.bridgeEnabled[bridgeId] = TRUE; + if (devicePrm.config >= PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR) + { + L6206_Board_EnableBridge(bridgeId, 0); + if (bridgeId == BRIDGE_A) + { + L6206_Board_EnableBridge(BRIDGE_B, 1); + devicePrm.bridgeEnabled[BRIDGE_B] = TRUE; + } + else + { + L6206_Board_EnableBridge(BRIDGE_A, 1); + devicePrm.bridgeEnabled[BRIDGE_A] = TRUE; + } + } + else + { + L6206_Board_EnableBridge(bridgeId, 1); + } +} + +/******************************************************//** + * @brief Start the L6206 library + * @param[in] init pointer to the initialization data + * @retval None + **********************************************************/ +status_t L6206::L6206_Init(void *init) +{ + deviceInstance++; + + /* Initialise the GPIOs */ + L6206_Board_GpioInit(); + + if (init == NULL) + { + /* Set context variables to the predefined values from l6206_target_config.h */ + /* Set GPIO according to these values */ + L6206_SetDeviceParamsToPredefinedValues(); + } + else + { + L6206_SetDeviceParamsToGivenValues((L6206_init_t*) init); + } + + /* Initialise input bridges PWMs */ + L6206_SetDualFullBridgeConfig(devicePrm.config); + + return COMPONENT_OK; +} + +/******************************************************//** + * @brief Get the PWM frequency of the specified bridge + * @param[in] bridgeId 0 for bridge A, 1 for bridge B + * @retval Freq in Hz + **********************************************************/ +uint32_t L6206::L6206_GetBridgeInputPwmFreq(uint8_t bridgeId) +{ + return (devicePrm.pwmFreq[(bridgeId << 1)]); +} + +/******************************************************//** + * @brief Returns the current speed of the specified motor + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval current speed in % from 0 to 100 + **********************************************************/ +uint16_t L6206::L6206_GetCurrentSpeed(uint8_t motorId) +{ + uint16_t speed = 0; + + if (motorId > l6206ArrayNbMaxMotorsByConfig[devicePrm.config]) + { + L6206_ErrorHandler(L6206_ERROR_1); + } + else if (devicePrm.motionState[motorId] != INACTIVE) + { + speed = devicePrm.speed[motorId]; + } + + return (speed); +} + +/******************************************************//** + * @brief Returns the device state + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval State (STEADY or INACTIVE) + **********************************************************/ +motorState_t L6206::L6206_get_device_state(uint8_t motorId) +{ + motorState_t state = INACTIVE; + + if (motorId > l6206ArrayNbMaxMotorsByConfig[devicePrm.config]) + { + L6206_ErrorHandler(L6206_ERROR_1); + } + else + { + state = devicePrm.motionState[motorId]; + } + return (state); +} + +/******************************************************//** + * @brief Returns the FW version of the library + * @retval L6206_FW_VERSION + **********************************************************/ +uint8_t L6206::L6206_GetFwVersion(void) +{ + return (L6206_FW_VERSION); +} + +/******************************************************//** + * @brief Returns the max speed of the specified motor + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval maxSpeed in % from 0 to 100 + **********************************************************/ +uint16_t L6206::L6206_GetMaxSpeed(uint8_t motorId) +{ + uint16_t speed = 0; + if (motorId > l6206ArrayNbMaxMotorsByConfig[devicePrm.config]) + { + L6206_ErrorHandler(L6206_ERROR_1); + } + else + { + speed = devicePrm.speed[motorId]; + } + return (speed); +} + + +/******************************************************//** + * @brief Get the status of the bridge enabling of the corresponding bridge + * @param[in] bridgeId from 0 for bridge A to 1 for bridge B + * @retval State of the Enable&Flag pin of the corresponding bridge (1 set, 0 for reset) + **********************************************************/ +uint16_t L6206::L6206_GetBridgeStatus(uint8_t bridgeId) +{ + uint16_t status = L6206_Board_GetFlagPinState(bridgeId); + + return (status); +} + +/******************************************************//** + * @brief Immediatly stops the motor and disable the power bridge + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval None + * @note if two motors uses the same power bridge, the + * power bridge will be disable only if the two motors are + * stopped + **********************************************************/ +void L6206::L6206_HardHiz(uint8_t motorId) +{ + if (motorId > l6206ArrayNbMaxMotorsByConfig[devicePrm.config]) + { + L6206_ErrorHandler(L6206_ERROR_1); + } + else + { + /* Get bridge Id of the corresponding motor */ + uint8_t bridgeId = L6206_GetBridgeIdUsedByMotorId(motorId); + + if (devicePrm.bridgeEnabled[bridgeId] != FALSE) + { + bool skip = FALSE; + + /* Check if another motor is currently running by using the same bridge */ + switch (devicePrm.config) + { + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + if ((motorId > 0) && (devicePrm.motionState[1] == STEADY) && (devicePrm.motionState[2] == STEADY)) + { + skip = TRUE; + } + break; + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + if ((motorId < 2) && (devicePrm.motionState[0] == STEADY) && (devicePrm.motionState[1] == STEADY)) + { + skip = TRUE; + } + break; + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + if (((motorId < 2) && (devicePrm.motionState[0] == STEADY) && (devicePrm.motionState[1] == STEADY))|| + ((motorId > 1) && (devicePrm.motionState[2] == STEADY) && (devicePrm.motionState[3] == STEADY))) + { + skip = TRUE; + } + break; + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + if ((motorId > 0) && (devicePrm.motionState[1] == STEADY) && (devicePrm.motionState[2] == STEADY)) + { + skip = TRUE; + } + break; + case PARALLELING_IN1B_IN2B__2_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if ((motorId < 2) && (devicePrm.motionState[0] == STEADY) && (devicePrm.motionState[1] == STEADY)) + { + skip = TRUE; + } + break; + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_UNDIR_MOTOR_BRIDGE_1A__1_UNDIR_MOTOR_BRIDGE_2A: + if ((devicePrm.motionState[0] == STEADY) && (devicePrm.motionState[1] == STEADY)) + { + skip = TRUE; + } + break; + default: + break; + } + + if (skip == FALSE) + { + /* Disable the bridge */ + L6206_DisableBridge(bridgeId); + } + } + /* Disable the PWM */ + L6206_HardStop(motorId); + } +} + +/******************************************************//** + * @brief Stops the motor without disabling the bridge + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval none + **********************************************************/ +void L6206::L6206_HardStop(uint8_t motorId) +{ + if (motorId > l6206ArrayNbMaxMotorsByConfig[devicePrm.config]) + { + L6206_ErrorHandler(L6206_ERROR_1); + } + else if (devicePrm.motionState[motorId] != INACTIVE) + { + uint8_t bridgeInput; + + /* Get bridge input of the corresponding motor */ + bridgeInput = L6206_GetBridgeInputUsedByMotorId(motorId); + + /* Disable corresponding PWM */ + L6206_Board_PwmStop(bridgeInput); + + /* for bidirectionnal motor, disable second PWM*/ + if (L6206_IsBidirectionnalMotor(motorId)) + { + bridgeInput = L6206_GetSecondBridgeInputUsedByMotorId(motorId); + L6206_Board_PwmStop(bridgeInput); + } + /* Set inactive state */ + devicePrm.motionState[motorId] = INACTIVE; + } +} + +/******************************************************//** + * @brief Read id + * @retval Id of the l6206 Driver Instance + **********************************************************/ +status_t L6206::L6206_ReadId(uint8_t *id) +{ + *id = deviceInstance; + + return COMPONENT_OK; +} + +/******************************************************//** + * @brief Runs the motor + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @param[in] direction FORWARD or BACKWARD + * @retval None + * @note For unidirectionnal motor, direction parameter has + * no effect + **********************************************************/ +void L6206::L6206_Run(uint8_t motorId, motorDir_t direction) +{ + if (motorId > l6206ArrayNbMaxMotorsByConfig[devicePrm.config]) + { + L6206_ErrorHandler(L6206_ERROR_1); + } + else if ((devicePrm.motionState[motorId] == INACTIVE) || + (devicePrm.direction[motorId] != direction)) + { + uint8_t bridgeId; + uint8_t bridgeInput; + + /* Eventually deactivate motor */ + if (devicePrm.motionState[motorId] != INACTIVE) + { + L6206_HardStop(motorId); + } + + /* Store new direction */ + devicePrm.direction[motorId] = direction; + + /* Switch to steady state */ + devicePrm.motionState[motorId] = STEADY; + + /* Get bridge Id of the corresponding motor */ + bridgeId = L6206_GetBridgeIdUsedByMotorId(motorId); + + /* Get bridge input of the corresponding motor */ + bridgeInput = L6206_GetBridgeInputUsedByMotorId(motorId); + + /* Enable bridge */ + L6206_EnableBridge(bridgeId); + + /* Set PWM */ + if (L6206_IsBidirectionnalMotor(motorId)) + { + /* for bidirectionnal motor */ + L6206_Board_PwmSetFreq(bridgeInput, devicePrm.pwmFreq[bridgeInput],(10000 - devicePrm.speed[motorId])); + bridgeInput = L6206_GetSecondBridgeInputUsedByMotorId(motorId); + L6206_Board_PwmSetFreq(bridgeInput, devicePrm.pwmFreq[bridgeInput],10000); + } + else + { + /* for unidirectionnal motor */ + L6206_Board_PwmSetFreq(bridgeInput, devicePrm.pwmFreq[bridgeInput],devicePrm.speed[motorId]); + } + } +} +/******************************************************//** + * @brief Set dual full bridge parallelling configuration + * @param[in] newConfig bridge configuration to apply from + * dualFullBridgeConfig_t enum + * @retval None + **********************************************************/ +void L6206::L6206_SetDualFullBridgeConfig(uint8_t newConfig) +{ + devicePrm.config = (dualFullBridgeConfig_t)newConfig; + + /* Start to reset all else if several inits are used successively */ + /* they will fail */ + L6206_Board_PwmDeInit(INPUT_1A); + L6206_Board_PwmDeInit(INPUT_2A); + L6206_Board_PwmDeInit(INPUT_1B); + L6206_Board_PwmDeInit(INPUT_2B); + + + /* Initialise the bridges inputs PWMs --------------------------------------*/ + switch (devicePrm.config) + { + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + L6206_Board_PwmInit(INPUT_1A); + L6206_Board_PwmInit(INPUT_2A); + L6206_Board_PwmInit(INPUT_1B); + L6206_Board_PwmInit(INPUT_2B); + break; + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + L6206_Board_PwmDeInit(INPUT_2A); + L6206_Board_PwmInit(INPUT_1A); + L6206_Board_PwmInit(INPUT_1B); + L6206_Board_PwmInit(INPUT_2B); + break; + case PARALLELING_IN1B_IN2B__1_BIDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1B_IN2B__2_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + L6206_Board_PwmDeInit(INPUT_2B); + L6206_Board_PwmInit(INPUT_1A); + L6206_Board_PwmInit(INPUT_2A); + L6206_Board_PwmInit(INPUT_1B); + break; + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR: + L6206_Board_PwmDeInit(INPUT_2A); + L6206_Board_PwmDeInit(INPUT_2B); + L6206_Board_PwmInit(INPUT_1A); + L6206_Board_PwmInit(INPUT_1B); + break; + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_UNDIR_MOTOR_BRIDGE_1A__1_UNDIR_MOTOR_BRIDGE_2A: + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_BIDIR_MOTOR: + L6206_Board_PwmDeInit(INPUT_1B); + L6206_Board_PwmDeInit(INPUT_2B); + L6206_Board_PwmInit(INPUT_1A); + L6206_Board_PwmInit(INPUT_2A); + break; + case PARALLELING_ALL_WITH_IN1A___1_UNDIR_MOTOR: + L6206_Board_PwmDeInit(INPUT_2A); + L6206_Board_PwmDeInit(INPUT_1B); + L6206_Board_PwmDeInit(INPUT_2B); + L6206_Board_PwmInit(INPUT_1A); + break; + default: + break; + } +} +/******************************************************//** + * @brief Changes the max speed of the specified device + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @param[in] newMaxSpeed in % from 0 to 100 + * @retval true if the command is successfully executed, else false + **********************************************************/ +bool L6206::L6206_SetMaxSpeed(uint8_t motorId, uint16_t newMaxSpeed) +{ + bool cmdExecuted = FALSE; + + if (motorId > l6206ArrayNbMaxMotorsByConfig[devicePrm.config]) + { + L6206_ErrorHandler(L6206_ERROR_1); + } + else + { + devicePrm.speed[motorId] = newMaxSpeed; + if (devicePrm.motionState[motorId] != INACTIVE) + { + uint8_t bridgeInput; + + /* Get Bridge input of the corresponding motor */ + bridgeInput = L6206_GetBridgeInputUsedByMotorId(motorId); + + /* Set PWM frequency*/ + if (L6206_IsBidirectionnalMotor(motorId)) + { + /* for bidirectionnal motor */ + L6206_Board_PwmSetFreq(bridgeInput, devicePrm.pwmFreq[bridgeInput],(10000 - devicePrm.speed[motorId])); + } + else + { + /* for unidirectionnal motor */ + L6206_Board_PwmSetFreq(bridgeInput, devicePrm.pwmFreq[bridgeInput],devicePrm.speed[motorId]); + } + } + cmdExecuted = TRUE; + } + return cmdExecuted; +} + +/******************************************************//** + * @brief Changes the PWM frequency of the bridge input + * @param[in] bridgeId 0 for bridge A, 1 for bridge B + * @param[in] newFreq in Hz + * @retval None + **********************************************************/ +void L6206::L6206_SetBridgeInputPwmFreq(uint8_t bridgeId, uint32_t newFreq) +{ + uint8_t loop; + + if (newFreq > L6206_MAX_PWM_FREQ) + { + newFreq = L6206_MAX_PWM_FREQ; + } + for (loop = 0; loop < 2;loop ++) + { + uint8_t motorId; + uint8_t bridgeInput = (bridgeId << 1) + loop; + devicePrm.pwmFreq[bridgeInput] = newFreq; + + /* Get motor Id using this bridge */ + motorId = L6206_GetMotorIdUsingbridgeInput(bridgeInput); + + /* Immediatly update frequency if motor is running */ + if (devicePrm.motionState[motorId] != INACTIVE) + { + /* Test if motor is bidir */ + if (L6206_IsBidirectionnalMotor(motorId)) + { + if (bridgeInput != L6206_GetSecondBridgeInputUsedByMotorId(motorId)) + { + /* Set PWM frequency for bidirectionnal motor of the first bridge*/ + L6206_Board_PwmSetFreq(bridgeInput, devicePrm.pwmFreq[bridgeInput],(10000 - devicePrm.speed[motorId])); + } + else + { + /* Set PWM frequency for bidirectionnal motor of the second bridge */ + L6206_Board_PwmSetFreq(bridgeInput, devicePrm.pwmFreq[bridgeInput],10000); + } + } + else + { + /* Set PWM frequency for unidirectionnal motor */ + L6206_Board_PwmSetFreq(bridgeInput, devicePrm.pwmFreq[bridgeInput],devicePrm.speed[motorId]); + } + } + } +} +/******************************************************//** + * @brief Sets the number of devices to be used + * @param[in] nbDevices (from 1 to MAX_NUMBER_OF_DEVICES) + * @retval TRUE if successfull, FALSE if failure, attempt to set a number of + * devices greater than MAX_NUMBER_OF_DEVICES + **********************************************************/ +bool L6206::L6206_SetNbDevices(uint8_t nbDevices) +{ + if (nbDevices <= MAX_NUMBER_OF_DEVICES) + { + return TRUE; + } + else + { + return FALSE; + } +} + + +/******************************************************//** + * @brief Error handler which calls the user callback (if defined) + * @param[in] error Number of the error + * @retval None + **********************************************************/ +void L6206::L6206_ErrorHandler(uint16_t error) +{ + if (errorHandlerCallback != 0) + { + (void) errorHandlerCallback(error); + } + else + { + while(1) + { + /* Infinite loop */ + } + } +} + +/******************************************************//** + * @brief Handlers of the flag interrupt which calls the user callback (if defined) + * @retval None + **********************************************************/ +void L6206::L6206_FlagInterruptHandler(void) +{ + bool status; + + status = L6206_GetBridgeStatus(BRIDGE_A); + if (status != devicePrm.bridgeEnabled[BRIDGE_A]) + { + devicePrm.bridgeEnabled[BRIDGE_A] = status; + } + + status = L6206_GetBridgeStatus(BRIDGE_B); + if (status != devicePrm.bridgeEnabled[BRIDGE_B]) + { + devicePrm.bridgeEnabled[BRIDGE_B] = status; + } + + if (flagInterruptCallback != 0) + { + flagInterruptCallback(); + } +} + +/******************************************************//** + * @brief Get the bridges Id used by a given motor + * @param motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval bridgeId 0 for bridge A , 1 for bridge B + **********************************************************/ +uint8_t L6206::L6206_GetBridgeIdUsedByMotorId(uint8_t motorId) +{ + uint8_t bridgeId; + + switch (devicePrm.config) + { + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1B_IN2B__1_BIDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + bridgeId = 0; + } + else + { + bridgeId = 1; + } + break; + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1B_IN2B__2_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if (motorId < 2) + { + bridgeId = 0; + } + else + { + bridgeId = 1; + } + break; + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR: + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_UNDIR_MOTOR_BRIDGE_1A__1_UNDIR_MOTOR_BRIDGE_2A: + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_BIDIR_MOTOR: + case PARALLELING_ALL_WITH_IN1A___1_UNDIR_MOTOR: + default: + bridgeId = 0; + break; + } + return (bridgeId); +} + +/******************************************************//** + * @brief Get the motor Id which is using the specified bridge input + * @param bridgeInput 0 for bridgeInput 1A, 1 for 2A, 2 for 1B, 3 for 3B + * @retval bridgeId 0 for bridge A , 1 for bridge B + **********************************************************/ +uint8_t L6206::L6206_GetMotorIdUsingbridgeInput(uint8_t bridgeInput) +{ + uint8_t motorId; + + switch (devicePrm.config) + { + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1B_IN2B__1_BIDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if (bridgeInput >= INPUT_1B) + { + motorId = 1; + } + else + { + motorId = 0; + } + break; + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + if (bridgeInput == INPUT_2B) + { + motorId = 2; + } + else if (bridgeInput == INPUT_1B) + { + motorId = 1; + } + else + { + motorId = 0; + } + break; + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1B_IN2B__2_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if (bridgeInput >= INPUT_1B) + { + motorId = 2; + } + else if (bridgeInput == INPUT_2A) + { + motorId = 1; + } + else + { + motorId = 0; + } + break; + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + if (bridgeInput == INPUT_2B) + { + motorId = 3; + } + else if (bridgeInput == INPUT_1B) + { + motorId = 2; + } + else if (bridgeInput == INPUT_2A) + { + motorId = 1; + } + else + { + motorId = 0; + } + break; + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_UNDIR_MOTOR_BRIDGE_1A__1_UNDIR_MOTOR_BRIDGE_2A: + if ((bridgeInput == INPUT_2A) || (bridgeInput == INPUT_2B)) + { + motorId = 1; + } + else + { + motorId = 0; + } + break; + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR: + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_BIDIR_MOTOR: + case PARALLELING_ALL_WITH_IN1A___1_UNDIR_MOTOR: + default: + motorId = 0; + break; + } + + return (motorId); +} +/******************************************************//** + * @brief Get the PWM input used by a given motor + * @param motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval PWM input 0 for 1A, 1 for 2A, 2 for 1B, 3 for 3B + **********************************************************/ +uint8_t L6206::L6206_GetBridgeInputUsedByMotorId(uint8_t motorId) +{ + uint8_t bridgeInput; + + switch (devicePrm.config) + { + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_1A; + } + else + { + bridgeInput = INPUT_2A; + } + } + else + { + if (devicePrm.direction[1] == FORWARD) + { + bridgeInput = INPUT_1B; + } + else + { + bridgeInput = INPUT_2B; + } + } + break; + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_1A; + } + else + { + bridgeInput = INPUT_2A; + } + } + else if (motorId == 1) + { + + bridgeInput = INPUT_1B; + } + else + { + bridgeInput = INPUT_2B; + } + break; + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + bridgeInput = INPUT_1A; + } + else if (motorId == 1) + { + bridgeInput = INPUT_2A; + } + else + { + if (devicePrm.direction[2] == FORWARD) + { + bridgeInput = INPUT_1B; + } + else + { + bridgeInput = INPUT_2B; + } + } + break; + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + bridgeInput = INPUT_1A; + } + else if (motorId == 1) + { + bridgeInput = INPUT_2A; + } + else if (motorId == 2) + { + bridgeInput = INPUT_1B; + } + else + { + bridgeInput = INPUT_2B; + } + break; + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + bridgeInput = INPUT_1A; + } + else + { + if (devicePrm.direction[1] == FORWARD) + { + bridgeInput = INPUT_1B; + } + else + { + bridgeInput = INPUT_2B; + } + } + break; + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + bridgeInput = INPUT_1A; + } + else if (motorId == 1) + { + bridgeInput = INPUT_1B; + } + else + { + bridgeInput = INPUT_2B; + } + break; + case PARALLELING_IN1B_IN2B__1_BIDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_1A; + } + else + { + bridgeInput = INPUT_2A; + } + } + else + { + bridgeInput = INPUT_1B; + } + break; + case PARALLELING_IN1B_IN2B__2_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + bridgeInput = INPUT_1A; + } + else if (motorId == 1) + { + bridgeInput = INPUT_2A; + } + else + { + bridgeInput = INPUT_1B; + } + break; + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_UNDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + bridgeInput = INPUT_1A; + } + else + { + bridgeInput = INPUT_1B; + } + break; + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR: + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_1A; + } + else + { + bridgeInput = INPUT_1B; + } + break; + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_UNDIR_MOTOR_BRIDGE_1A__1_UNDIR_MOTOR_BRIDGE_2A: + if (motorId == 0) + { + bridgeInput = INPUT_1A; + } + else + { + bridgeInput = INPUT_2A; + } + break; + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_BIDIR_MOTOR: + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_1A; + } + else + { + bridgeInput = INPUT_2A; + } + break; + case PARALLELING_ALL_WITH_IN1A___1_UNDIR_MOTOR: + default: + bridgeInput = INPUT_1A; + break; + } + return (bridgeInput); +} + +/******************************************************//** + * @brief Get the second PWM input used by a given bidirectionnal motor + * @param motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval PWM input 0 for 1A, 1 for 2A, 2 for 1B, 3 for 3B + **********************************************************/ +uint8_t L6206::L6206_GetSecondBridgeInputUsedByMotorId(uint8_t motorId) +{ + uint8_t bridgeInput = 0xFF; + + switch (devicePrm.config) + { + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_2A; + } + else + { + bridgeInput = INPUT_1A; + } + } + else + { + if (devicePrm.direction[1] == FORWARD) + { + bridgeInput = INPUT_2B; + } + else + { + bridgeInput = INPUT_1B; + } + } + break; + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_2A; + } + else + { + bridgeInput = INPUT_1A; + } + } + break; + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + if (motorId == 2) + { + if (devicePrm.direction[2] == FORWARD) + { + bridgeInput = INPUT_2B; + } + else + { + bridgeInput = INPUT_1B; + } + } + break; + + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + if (motorId == 1) + { + if (devicePrm.direction[1] == FORWARD) + { + bridgeInput = INPUT_2B; + } + else + { + bridgeInput = INPUT_1B; + } + } + break; + + case PARALLELING_IN1B_IN2B__1_BIDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_2A; + } + else + { + bridgeInput = INPUT_1A; + } + } + break; + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR: + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_1B; + } + else + { + bridgeInput = INPUT_1A; + } + break; + + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_BIDIR_MOTOR: + if (devicePrm.direction[0] == FORWARD) + { + bridgeInput = INPUT_2A; + } + else + { + bridgeInput = INPUT_1A; + } + break; + default: + bridgeInput = 0XFF; + break; + } + if (bridgeInput == 0XFF) + { + L6206_ErrorHandler(L6206_ERROR_2); + } + + return (bridgeInput); +} + +/******************************************************//** + * @brief Test if motor is bidirectionnal + * @param motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval True if motor is bidirectionnal, else false + **********************************************************/ +bool L6206::L6206_IsBidirectionnalMotor(uint8_t motorId) +{ + bool isBiDir = FALSE; + + switch (devicePrm.config) + { + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1A_IN2A__IN1B_IN2B__1_BIDIR_MOTOR: + case PARALLELING_IN1A_IN1B__IN2A_IN2B__1_BIDIR_MOTOR: + isBiDir = TRUE; + break; + + case PARALLELING_NONE___1_BIDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B: + case PARALLELING_IN1B_IN2B__1_BIDIR_MOTOR_BRIDGE_A__1_UNDIR_MOTOR_BRIDGE_B: + if (motorId == 0) + { + isBiDir = TRUE; + } + break; + case PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + if (motorId == 2) + { + isBiDir = TRUE; + } + break; + case PARALLELING_IN1A_IN2A__1_UNDIR_MOTOR_BRIDGE_A__1_BIDIR_MOTOR_BRIDGE_B: + if (motorId == 1) + { + isBiDir = TRUE; + } + break; + + default: + break; + } + + return (isBiDir); +} + + +/******************************************************//** + * @brief Sets the parameters of the device to predefined values + * from l6206_target_config.h + * @retval None + **********************************************************/ +void L6206::L6206_SetDeviceParamsToPredefinedValues(void) +{ + uint32_t i; + + memset(&devicePrm, 0, sizeof(devicePrm)); + + devicePrm.config = L6206_CONF_PARAM_PARALLE_BRIDGES; + + devicePrm.pwmFreq[INPUT_1A] = L6206_CONF_PARAM_FREQ_PWM1A; + devicePrm.pwmFreq[INPUT_2A] = L6206_CONF_PARAM_FREQ_PWM2A; + devicePrm.pwmFreq[INPUT_1B] = L6206_CONF_PARAM_FREQ_PWM1B; + devicePrm.pwmFreq[INPUT_2B] = L6206_CONF_PARAM_FREQ_PWM2B; + + for (i = 0; i < MAX_NUMBER_OF_BRUSH_DC_MOTORS; i++) + { + devicePrm.speed[i] = 100; + devicePrm.direction[i] = FORWARD; + devicePrm.motionState[i] = INACTIVE; + } + for (i = 0; i < L6206_NB_MAX_BRIDGES; i++) + { + devicePrm.bridgeEnabled[i] = FALSE; + } +} + + +/******************************************************//** + * @brief Set the parameters of the device to values of initDevicePrm structure + * Set GPIO according to these values + * @param initDevicePrm structure containing values to initialize the device + * parameters + * @retval None + **********************************************************/ +void L6206::L6206_SetDeviceParamsToGivenValues(L6206_init_t* initDevicePrm) +{ + memcpy(&devicePrm, initDevicePrm, sizeof(devicePrm)); +} + + /** + * @} + */ + + + + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + +
diff -r 05340e740644 -r b7fc55bf70b2 X_NUCLEO_IHM04A1/Components/L6206/L6206.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IHM04A1/Components/L6206/L6206.h Fri Jul 21 11:19:39 2017 +0000 @@ -0,0 +1,842 @@ +/** + ****************************************************************************** + * @file L6206.h + * @author IPC Rennes + * @version V1.1.0 + * @date March 02, 2016 + * @brief L6206 driver (dual full bridge driver) + * @note (C) COPYRIGHT 2015 STMicroelectronics + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/* Generated with STM32CubeTOO -----------------------------------------------*/ + + +/* Revision ------------------------------------------------------------------*/ +/* + Repository: http://svn.x-nucleodev.codex.cro.st.com/svnroot/X-NucleoDev + Branch/Trunk/Tag: trunk + Based on: X-CUBE-SPN4/trunk/Drivers/BSP/Components/L6206/L6206.h + Revision: 0 +*/ + + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __L6206_CLASS_H +#define __L6206_CLASS_H + + +/* Includes ------------------------------------------------------------------*/ + +/* ACTION 1 ------------------------------------------------------------------* + * Include here platform specific header files. * + *----------------------------------------------------------------------------*/ +#include "mbed.h" +/* ACTION 2 ------------------------------------------------------------------* + * Include here component specific header files. * + *----------------------------------------------------------------------------*/ +#include "L6206_def.h" +/* ACTION 3 ------------------------------------------------------------------* + * Include here interface specific header files. * + * * + * Example: * + * #include "HumiditySensor.h" * + * #include "TemperatureSensor.h" * + *----------------------------------------------------------------------------*/ +#include "BDCMotor.h" + +#include "FastPWM.h" + +/* Private constants ---------------------------------------------------------*/ + +/** @defgroup L6206_Private_Constants L6206 Private Constants + * @{ + */ + +/// The Number of L6206 devices required for initialisation is not supported +#define L6206_ERROR_0 (0x8000) +/// Error: Access a motor index greater than the one of the current brigde configuration +#define L6206_ERROR_1 (0x8001) +/// Error: Access a motor index which is not bidirectionnal +#define L6206_ERROR_2 (0x8002) + +/// Maximum frequency of the PWMs in Hz +#define L6206_MAX_PWM_FREQ (100000) + +/// Minimum frequency of the PWMs in Hz +#define L6206_MIN_PWM_FREQ (2) + +/// Bridge Input 1A +#define INPUT_1A (0) +/// Bridge Input 2A +#define INPUT_2A (1) +/// Bridge Input 1B +#define INPUT_1B (2) +/// Bridge Input 2B +#define INPUT_2B (3) + +/// Bridge A +#define BRIDGE_A (0) +/// Bridge B +#define BRIDGE_B (1) + + + + + +/* Classes -------------------------------------------------------------------*/ + +/** + * @brief Class representing a L6206 component. + */ +class L6206 : public BDCMotor +{ +public: + + /*** Constructor and Destructor Methods ***/ + + /** + * @brief Constructor. + */ + L6206(PinName EN_flag_A, PinName EN_flag_B, PinName pwm_1A, PinName pwm_2A, PinName pwm_1B, PinName pwm_2B) : BDCMotor(), flag_A_irq(EN_flag_A), flag_B_irq(EN_flag_B), EN_flag_A(EN_flag_A), EN_flag_B(EN_flag_B), pwm_1A(pwm_1A), pwm_2A(pwm_2A), pwm_1B(pwm_1B), pwm_2B(pwm_2B) + { + /* ACTION 4 ----------------------------------------------------------* + * Initialize here the component's member variables, one variable per * + * line. * + * * + * Example: * + * measure = 0; * + * instance_id = number_of_instances++; * + *--------------------------------------------------------------------*/ + + flagInterruptCallback = 0; + errorHandlerCallback = 0; + numberOfDevices = 0; + deviceInstance = 0; + } + + /** + * @brief Destructor. + */ + virtual ~L6206(void) {} + + + /*** Public Component Related Methods ***/ + + /* ACTION 5 --------------------------------------------------------------* + * Implement here the component's public methods, as wrappers of the C * + * component's functions. * + * They should be: * + * + Methods with the same name of the C component's virtual table's * + * functions (1); * + * + Methods with the same name of the C component's extended virtual * + * table's functions, if any (2). * + * * + * Example: * + * virtual int get_value(float *f) //(1) * + * { * + * return COMPONENT_get_value(float *f); * + * } * + * * + * virtual int enable_feature(void) //(2) * + * { * + * return COMPONENT_enable_feature(); * + * } * + *------------------------------------------------------------------------*/ + + /** + * @brief Initializing the component. + * @param init Pointer to device specific initalization structure. + * @retval "0" in case of success, an error code otherwise. + */ + virtual int init(void *init = NULL) + { + return (int) L6206_Init((void *) init); + } + + /** + * @brief Getting the ID of the component. + * @param id Pointer to an allocated variable to store the ID into. + * @retval "0" in case of success, an error code otherwise. + */ + virtual int read_id(uint8_t *id = NULL) + { + return (int) L6206_ReadId((uint8_t *) id); + } + + + /** + * @brief Attaches a user callback to the error Handler. + * The call back will be then called each time the library detects an error + * @param[in] callback Name of the callback to attach to the error Hanlder + * @retval None + */ + virtual void attach_error_handler(void (*callback)(uint16_t error)) + { + L6206_AttachErrorHandler((void (*)(uint16_t error)) callback); + } + + + /** + * @brief Attaches a user callback to the flag Interrupt + * The call back will be then called each time the status + * flag pin will be pulled down due to the occurrence of + * a programmed alarms ( OCD, thermal alert) + * @param[in] callback Name of the callback to attach + * to the Flag Interrupt + * @retval None + */ + virtual void attach_flag_interrupt(void (*callback)(void)) + { + L6206_attach_flag_interrupt((void (*)(void)) callback); + } + + /** + * @brief Returns the current speed of the specified motor + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval current speed in % from 0 to 100 + */ + virtual unsigned int get_speed(unsigned int motorId) + { + return (unsigned int) L6206_GetCurrentSpeed((uint8_t) motorId); + } + + /** + * @brief Returns the device state + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval State (STEADY or INACTIVE) + */ + virtual unsigned int get_device_state(unsigned int motorId) + { + return (motorState_t) L6206_get_device_state((uint8_t) motorId); + } + + /** + * @brief Returns the FW version of the library + * @retval L6206_FW_VERSION + */ + virtual uint8_t get_fw_version(void) + { + return (uint8_t) L6206_GetFwVersion(); + } + + /** + * @brief Returns the max speed of the specified motor + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval maxSpeed in % from 0 to 100 + */ + virtual uint16_t get_max_speed(unsigned int motorId) + { + return (uint16_t) L6206_GetMaxSpeed((uint8_t) motorId); + } + + /** + * @brief Stops the motor without disabling the bridge + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval none + */ + virtual void hard_stop(unsigned int motorId) + { + L6206_HardStop((uint8_t) motorId); + } + + /** + * @brief Runs the motor + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @param[in] direction FORWARD or BACKWARD + * @retval None + * @note For unidirectionnal motor, direction parameter has no effect + */ + virtual void run(unsigned int motorId, direction_t direction) + { + L6206_Run((uint8_t) motorId, (motorDir_t) direction); + } + + /** + * @brief Changes the max speed of the specified device + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @param[in] newMaxSpeed in % from 0 to 100 + * @retval true if the command is successfully executed, else false + */ + virtual bool set_speed(unsigned int motorId, unsigned int newMaxSpeed) + { + return (bool) L6206_SetMaxSpeed((uint8_t) motorId, (uint32_t) newMaxSpeed); + } + + /** + * @brief Disable the specified bridge + * @param[in] bridgeId (from 0 for bridge A to 1 for bridge B) + * @retval None + * @note When input of different brigdes are parallelized + * together, the disabling of one bridge leads to the disabling + * of the second one + */ + virtual void disable_bridge(unsigned int bridgeId) + { + L6206_DisableBridge((uint8_t) bridgeId); + } + + /** + * @brief Enable the specified bridge + * @param[in] bridgeId (from 0 for bridge A to 1 for bridge B) + * @retval None + * @note When input of different brigdes are parallelized + * together, the enabling of one bridge leads to the enabling + * of the second one + */ + virtual void enable_bridge(unsigned int bridgeId) + { + L6206_EnableBridge((uint8_t) bridgeId); + } + + /** + * @brief Get the status of the bridge enabling of the corresponding bridge + * @param[in] bridgeId from 0 for bridge A to 1 for bridge B + * @retval State of the Enable&Flag pin of the corresponding bridge (1 set, 0 for reset) + */ + virtual unsigned int get_bridge_status(unsigned int bridgeId) + { + return (unsigned int) L6206_GetBridgeStatus((uint8_t) bridgeId); + } + + /** + * @brief Immediatly stops the motor and disable the power bridge + * @param[in] motorId from 0 to MAX_NUMBER_OF_BRUSH_DC_MOTORS + * @retval None + * @note if two motors uses the same power bridge, the + * power bridge will be disable only if the two motors are stopped + */ + virtual void hard_hiz(unsigned int motorId) + { + L6206_HardHiz((uint8_t) motorId); + } + + /** + * @brief Error handler which calls the user callback (if defined) + * @param[in] error Number of the error + * @retval None + */ + virtual void error_handler(uint16_t error) + { + L6206_ErrorHandler((uint16_t) error); + } + + /** + * @brief Set dual full bridge parallelling configuration + * @param[in] newConfig bridge configuration to apply from + * dualFullBridgeConfig_t enum + * @retval None + */ + virtual void set_dual_full_bridge_config(unsigned int newConfig) + { + L6206_SetDualFullBridgeConfig((uint8_t) newConfig); + } + + /** + * @brief Get the PWM frequency of the specified bridge + * @param[in] bridgeId 0 for bridge A, 1 for bridge B + * @retval Freq in Hz + */ + virtual unsigned int get_bridge_input_pwm_freq(unsigned int bridgeId) + { + return (unsigned int) L6206_GetBridgeInputPwmFreq((uint8_t) bridgeId); + } + + /** + * @brief Changes the PWM frequency of the bridge input + * @param[in] bridgeId 0 for bridge A, 1 for bridge B + * @param[in] newFreq in Hz + * @retval None + */ + virtual void set_bridge_input_pwm_freq(unsigned int bridgeId, unsigned int newFreq) + { + L6206_SetBridgeInputPwmFreq((uint8_t) bridgeId, (uint32_t) newFreq); + } + + /** + * @brief Sets the number of devices to be used + * @param[in] nbDevices (from 1 to MAX_NUMBER_OF_DEVICES) + * @retval TRUE if successfull, FALSE if failure, attempt to set a number of + * devices greater than MAX_NUMBER_OF_DEVICES + */ + virtual bool set_nb_devices(uint8_t nbDevices) + { + return (bool) L6206_SetNbDevices((uint8_t) nbDevices); + } + + + /*** Public Interrupt Related Methods ***/ + + /* ACTION 6 --------------------------------------------------------------* + * Implement here interrupt related methods, if any. * + * Note that interrupt handling is platform dependent, e.g.: * + * + mbed: * + * InterruptIn feature_irq(pin); //Interrupt object. * + * feature_irq.fall(callback); //Attach a callback. * + * feature_irq.mode(PullNone); //Set interrupt mode. * + * feature_irq.enable_irq(); //Enable interrupt. * + * feature_irq.disable_irq(); //Disable interrupt. * + * + Arduino: * + * attachInterrupt(pin, callback, RISING); //Attach a callback. * + * detachInterrupt(pin); //Detach a callback. * + * * + * Example (mbed): * + * void attach_feature_irq(void (*fptr) (void)) * + * { * + * feature_irq.fall(fptr); * + * } * + * * + * void enable_feature_irq(void) * + * { * + * feature_irq.enable_irq(); * + * } * + * * + * void disable_feature_irq(void) * + * { * + * feature_irq.disable_irq(); * + * } * + *------------------------------------------------------------------------*/ + + + /** + * @brief Enabling the FLAG interrupt handling. + * @param[in] bridgeId 0 for bridge A, 1 for bridge B + * @retval None. + */ + virtual void enable_flag_irq(uint8_t bridgeId) + { + if (bridgeId == BRIDGE_A) + { + flag_A_irq.mode(PullUp); + flag_A_irq.fall(this, &L6206::L6206_FlagInterruptHandler); + } + else + { + flag_B_irq.mode(PullUp); + flag_B_irq.fall(this, &L6206::L6206_FlagInterruptHandler); + } + } + + /** + * @brief Disabling the FLAG interrupt handling. + * @param[in] bridgeId 0 for bridge A, 1 for bridge B + * @retval None. + */ + virtual void disable_flag_irq(uint8_t bridgeId) + { + if (bridgeId == BRIDGE_A) + flag_A_irq.fall(NULL); + else + flag_B_irq.fall(NULL); + } + + + /*** Public In/Out Related Methods ***/ + + + +protected: + + /*** Protected Component Related Methods ***/ + + /* ACTION 7 --------------------------------------------------------------* + * Declare here the component's specific methods. * + * They should be: * + * + Methods with the same name of the C component's virtual table's * + * functions (1); * + * + Methods with the same name of the C component's extended virtual * + * table's functions, if any (2); * + * + Helper methods, if any, like functions declared in the component's * + * source files but not pointed by the component's virtual table (3). * + * * + * Example: * + * status_t COMPONENT_get_value(float *f); //(1) * + * status_t COMPONENT_enable_feature(void); //(2) * + * status_t COMPONENT_compute_average(void); //(3) * + *------------------------------------------------------------------------*/ + status_t L6206_Init(void *init); + status_t L6206_ReadId(uint8_t *id); + void L6206_TickHandler(uint8_t deviceId); //Handle the device state machine at each tick timer pulse end + void L6206_AttachErrorHandler(void (*callback)(uint16_t error)); //Attach a user callback to the error handler + void L6206_attach_flag_interrupt(void (*callback)(void)); //Attach a user callback to the flag Interrupt + void L6206_DisableBridge(uint8_t bridgeId); //Disable the specified bridge + void L6206_EnableBridge(uint8_t bridgeId); //Enable the specified bridge + uint16_t L6206_GetBridgeStatus(uint8_t deviceId); //Get bridge status + uint16_t L6206_GetCurrentSpeed(uint8_t motorId); //Return the current speed in pps + motorState_t L6206_get_device_state(uint8_t motorId); //Return the device state + uint8_t L6206_GetFwVersion(void); //Return the FW version + uint16_t L6206_GetMaxSpeed(uint8_t motorId); //Return the max speed in pps + void L6206_HardHiz(uint8_t motorId); //Stop the motor and disable the power bridge + void L6206_HardStop(uint8_t motorId); //Stop the motor without disabling the power bridge + void L6206_Run(uint8_t motorId, motorDir_t direction); //run the motor + uint32_t L6206_GetBridgeInputPwmFreq(uint8_t bridgeId); // Get the PWM frequency of the bridge input + void L6206_SetBridgeInputPwmFreq(uint8_t bridgeId, uint32_t newFreq); // Set the PWM frequency of the bridge input + void L6206_SetDualFullBridgeConfig(uint8_t newConfig); // Set dual full bridge configuration + bool L6206_SetMaxSpeed(uint8_t motorId,uint16_t newMaxSpeed); //Set the max speed in pps + bool L6206_SetNbDevices(uint8_t nbDevices); //Set the number of driver devices + void L6206_ErrorHandler(uint16_t error); + void L6206_FlagInterruptHandler(void); + uint8_t L6206_GetBridgeIdUsedByMotorId(uint8_t motorId); + uint8_t L6206_GetBridgeInputUsedByMotorId(uint8_t motorId); + uint8_t L6206_GetMotorIdUsingbridgeInput(uint8_t bridgeInput); + uint8_t L6206_GetSecondBridgeInputUsedByMotorId(uint8_t motorId); + bool L6206_IsBidirectionnalMotor(uint8_t motorId); + void L6206_SetDeviceParamsToPredefinedValues(void); + void L6206_SetDeviceParamsToGivenValues(L6206_init_t* initDevicePrm); + + /*** Component's I/O Methods ***/ + + /* ACTION 8 --------------------------------------------------------------* + * Implement here other I/O methods beyond those already implemented * + * above, which are declared extern within the component's header file. * + *------------------------------------------------------------------------*/ + + /** + * @brief Utility function to set or unset EN pin for Bridge A or Bridge B. + * @param[out] none + * @param[in] bridgeId 0 for bridge A, 1 for bridge B + * @retval none + */ + void L6206_OutVal( uint8_t bridgeId, uint8_t val) + { + if( bridgeId == BRIDGE_A) + { + EN_flag_A.output(); + EN_flag_A.mode(PullNone); + EN_flag_A.write(val); + } + else + { + EN_flag_B.output(); + EN_flag_B.mode(PullNone); + EN_flag_B.write(val); + } + } + + /** + * @brief Making the CPU wait. + * @param None. + * @retval None. + */ + void L6206_Board_Delay(uint32_t delay) + { + wait_ms(delay); + } + + /** + * @brief Disable the specified bridge + * @param[in] bridgeId (from 0 for bridge A to 1 for bridge B) + * @retval None + * @note When input of different brigdes are parallelized + * together, the disabling of one bridge leads to the disabling + * of the second one + */ + void L6206_Board_DisableBridge(uint8_t bridgeId) + { + disable_flag_irq(BRIDGE_A); + disable_flag_irq(BRIDGE_B); + + __disable_irq(); + L6206_OutVal( bridgeId, 0); + __enable_irq(); + } + + /** + * @brief Enable the specified bridge + * @param[in] bridgeId (from 0 for bridge A to 1 for bridge B) + * @retval None + * @note When input of different brigdes are parallelized + * together, the enabling of one bridge leads to the enabling + * of the second one + */ + void L6206_Board_EnableBridge(uint8_t bridgeId, uint8_t addDelay) + { + L6206_OutVal( bridgeId, 1); + + if (addDelay != 0) { + wait_ms(BSP_MOTOR_CONTROL_BOARD_BRIDGE_TURN_ON_DELAY); + } + + enable_flag_irq( bridgeId); + } + + /** + * @brief Returns the FLAG pin state. + * @param[in] bridgeId (from 0 for bridge A to 1 for bridge B) + * @retval The FLAG pin value. + */ + uint32_t L6206_Board_GetFlagPinState(uint8_t bridgeId) + { + if (bridgeId == 0) + { + EN_flag_A.input(); + return EN_flag_A.read(); + } + else + { + EN_flag_B.input(); + return EN_flag_B.read(); + } + } + + /** + * @brief Initiliases the GPIOs used by the L6206s + * @retval None + */ + void L6206_Board_GpioInit(void) + { + /* init bridge Enable */ + EN_flag_A.output(); + EN_flag_A.write(0); + EN_flag_A.input(); + + EN_flag_B.output(); + EN_flag_B.write(0); + EN_flag_B.input(); + + + /* init flag Irq */ + disable_flag_irq(BRIDGE_A); + disable_flag_irq(BRIDGE_B); + + } + + /** + * @brief Sets the frequency of PWM used for bridges inputs + * @param[in] bridgeInput 0 for input 1A, 1 for input 2A, + * 2 for input 1B, 3 for input 2B + * @param[in] newFreq in Hz + * @param[in] duty Duty cycle + * @retval None + * @note The frequency is directly the current speed of the device + */ + void L6206_Board_PwmSetFreq(uint8_t bridgeInput, uint32_t newFreq, uint16_t duty) + { + /* Computing the period of PWM. */ + float period = 1.0f / newFreq; + double duty_cycle; + int period_us = (int)(period * 1000000); + + if (duty > 10000) duty = 10000; + duty_cycle = (double)duty / 10000.0f; + printf("duty cycle set: %5.4f\r\n",duty_cycle); + switch (bridgeInput) + { + + case 0: + default: + /* Setting the period and the duty-cycle of PWM. */ + pwm_1A.period_us(period_us); + pwm_1A.write(duty_cycle); + + break; + + case 1: + /* Setting the period and the duty-cycle of PWM. */ + pwm_2A.period_us(period_us); + pwm_2A.write(duty_cycle); + break; + + case 2: + /* Setting the period and the duty-cycle of PWM. */ + pwm_1B.period_us(period_us); + pwm_1B.write(duty_cycle); + break; + + case 3: + /* Setting the period and the duty-cycle of PWM. */ + pwm_2B.period_us(period_us); + pwm_2B.write(duty_cycle); + break; + } + } + + /** + * @brief Reset the PWM for the specified brigde input + * @param[in] bridgeInput 0 for input 1A, 1 for input 2A, + * 2 for input 1B, 3 for input 2B + * @retval None + */ + void L6206_Board_PwmDeInit(uint8_t bridgeInput) + { + switch (bridgeInput) + { + case 0: + default: + //timer_pwm_1A.detach(); + break; + + case 1: + //timer_pwm_2A.detach(); + break; + + case 2: + //timer_pwm_1B.detach(); + break; + + case 3: + //timer_pwm_2B.detach(); + break; + } + } + + /** + * @brief Set the PWM frequency the for the specified bridge input + * @param[in] bridgeInput 0 for input 1A, 1 for input 2A, + * 2 for input 1B, 3 for input 2B + * @retval None + */ + void L6206_Board_PwmInit(uint8_t bridgeInput) + { + } + + /** + * @brief Stops the PWM uses for the specified brige input + * @param[in] bridgeInput 0 for input 1A, 1 for input 2A, + * 2 for input 1B, 3 for input 2B + * @retval None + */ + void L6206_Board_PwmStop(uint8_t bridgeInput) + { + switch (bridgeInput) + { + case 0: + default: + pwm_1A.write(0.0); + break; + + case 1: + pwm_2A.write(0.0); + break; + + case 2: + pwm_1B.write(0.0); + break; + + case 3: + pwm_2B.write(0.0); + break; + } + } + + + /*** Component's Instance Variables ***/ + + /* ACTION 9 --------------------------------------------------------------* + * Declare here interrupt related variables, if needed. * + * Note that interrupt handling is platform dependent, see * + * "Interrupt Related Methods" above. * + * * + * Example: * + * + mbed: * + * InterruptIn feature_irq; * + *------------------------------------------------------------------------*/ + + /* Flag Interrupt. */ + InterruptIn flag_A_irq; + InterruptIn flag_B_irq; + + /* ACTION 10 -------------------------------------------------------------* + * Declare here other pin related variables, if needed. * + * * + * Example: * + * + mbed: * + * DigitalOut standby_reset; * + *------------------------------------------------------------------------*/ + + /* Digital In/Out for Flag EN pin */ + DigitalInOut EN_flag_A; + DigitalInOut EN_flag_B; + + /* PWM Out pin */ + /* + PwmOut pwm_1A; + PwmOut pwm_2A; + PwmOut pwm_1B; + PwmOut pwm_2B; + */ + FastPWM pwm_1A; + FastPWM pwm_2A; + FastPWM pwm_1B; + FastPWM pwm_2B; + + /* ACTION 11 -------------------------------------------------------------* + * Declare here communication related variables, if needed. * + * * + * Example: * + * + mbed: * + * DigitalOut address; * + * DevI2C &dev_i2c; * + *------------------------------------------------------------------------*/ + + /* ACTION 12 -------------------------------------------------------------* + * Declare here identity related variables, if needed. * + * Note that there should be only a unique identifier for each component, * + * which should be the "who_am_i" parameter. * + *------------------------------------------------------------------------*/ + /* Identity */ + uint8_t who_am_i; + + /* ACTION 13 -------------------------------------------------------------* + * Declare here the component's static and non-static data, one variable * + * per line. * + * * + * Example: * + * float measure; * + * int instance_id; * + * static int number_of_instances; * + *------------------------------------------------------------------------*/ + void (*flagInterruptCallback)(void); + + void (*errorHandlerCallback)(uint16_t error); + + uint8_t numberOfDevices; + + uint8_t deviceInstance; + + deviceParams_t devicePrm; + + + /** PWM timer variables */ + + bool pwm_1A_activated; + bool pwm_2A_activated; + bool pwm_1B_activated; + bool pwm_2B_activated; +}; + +#endif /* __L6206_CLASS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + +
diff -r 05340e740644 -r b7fc55bf70b2 X_NUCLEO_IHM04A1/Components/L6206/L6206_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IHM04A1/Components/L6206/L6206_config.h Fri Jul 21 11:19:39 2017 +0000 @@ -0,0 +1,104 @@ +/**************************************************************************//** + * @file L6206_config.h + * @author IPC Rennes + * @version V1.0.0 + * @date January 06, 2015 + * @brief Predefines values for the L6206 parameters + * and for the devices parameters + * @note (C) COPYRIGHT 2015 STMicroelectronics + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __L6206_CONFIG_H +#define __L6206_CONFIG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup L6474 + * @{ + */ + +/** @addtogroup L6206_Exported_Constants + * @{ + */ + +/** @defgroup Predefined_L6206_Parameters_Values Predefined L6206 Parameters Values + * @{ + */ + +/// The maximum number of L6206 devices +#define MAX_NUMBER_OF_DEVICES (1) + +/// The maximum number of BLDC motors connected to the L6206 +#define MAX_NUMBER_OF_BRUSH_DC_MOTORS (1) + +/// Frequency of PWM of Input 1 Bridge A in Hz up to 100000Hz +#define L6206_CONF_PARAM_FREQ_PWM1A (20000) +/// Frequency of PWM of Input 2 Bridge A in Hz up to 100000Hz +/// ON IHM04A1, must be identical to L6206_CONF_PARAM_FREQ_PWM1A as used timer is the same +#define L6206_CONF_PARAM_FREQ_PWM2A (20000) +/// Frequency of PWM of Input 1 Bridge B in Hz up to 100000Hz +#define L6206_CONF_PARAM_FREQ_PWM1B (20000) +/// Frequency of PWM of Input 2 Bridge B in Hz up to 100000Hz +/// On IHM04A1, must be identical to L6206_CONF_PARAM_FREQ_PWM2B as used timer is the same +#define L6206_CONF_PARAM_FREQ_PWM2B (20000) + +/// Frequency of PWM of Input 2 Bridge B (in kHz) +#define L6206_CONF_PARAM_PARALLE_BRIDGES (PARALLELING_ALL_WITH_IN1A___1_UNDIR_MOTOR) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus + } +#endif + +#endif /* __L6206_CONFIG_H */ + +
diff -r 05340e740644 -r b7fc55bf70b2 X_NUCLEO_IHM04A1/Components/L6206/L6206_def.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IHM04A1/Components/L6206/L6206_def.h Fri Jul 21 11:19:39 2017 +0000 @@ -0,0 +1,228 @@ +/** + ****************************************************************************** + * @file L6206_def.h + * @author IPC Rennes + * @version V1.2.0 + * @date March 30, 2016 + * @brief Header for L6206 driver (dual full bridge driver) + * @note (C) COPYRIGHT 2015 STMicroelectronics + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __L6206_H +#define __L6206_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "L6206_config.h" +#include "../Common/motor_def.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup L6206 + * @{ + */ + +/* Exported Constants --------------------------------------------------------*/ + +/** @defgroup L6206_Exported_Defines L6206 Exported Defines + * @{ + */ + +/// Current FW version +#define L6206_FW_VERSION (0) +///Max number of Brush DC motors +#define L6206_NB_MAX_MOTORS (4) +///Max number of Bridges +#define L6206_NB_MAX_BRIDGES (2) +///Max number of input of Bridges +#define L6206_NB_MAX_BRIDGE_INPUT (2 * L6206_NB_MAX_BRIDGES) +/// MCU wait time in ms after power bridges are enabled +#define BSP_MOTOR_CONTROL_BOARD_BRIDGE_TURN_ON_DELAY (20) + + /** + * @} + */ + + +/* Exported Types -------------------------------------------------------*/ + +/** @defgroup L6206_Exported_Types L6206 Exported Types + * @{ + */ + + + + +/** @defgroup Initialization_Structure Initialization Structure + * @{ + */ + +typedef struct +{ + /// Bridge configuration structure. + dualFullBridgeConfig_t config; + + /// PWM frequency + uint32_t pwmFreq[L6206_NB_MAX_BRIDGE_INPUT]; + + /// Motor speed + double speed[L6206_NB_MAX_MOTORS]; + + /// Motor direction + motorDir_t direction[L6206_NB_MAX_MOTORS]; + + /// Current motor state + motorState_t motionState[L6206_NB_MAX_MOTORS]; + + /// Bridge enabled (true) or not (false) + bool bridgeEnabled[L6206_NB_MAX_BRIDGES]; +} deviceParams_t; + + + + +typedef deviceParams_t L6206_init_t; + + + +/** + * @} + */ + + +/** @defgroup Data_Structure Data Structure + * @{ + */ + +/* ACTION --------------------------------------------------------------------* + * Declare here the structure of component's data, if any, one variable per * + * line without initialization. * + * * + * Example: * + * typedef struct * + * { * + * int T0_out; * + * int T1_out; * + * float T0_degC; * + * float T1_degC; * + * } COMPONENT_Data_t; * + *----------------------------------------------------------------------------*/ +typedef struct +{ + /// Function pointer to flag interrupt call back + void (*flagInterruptCallback)(void); + + /// Function pointer to error handler call back + void (*errorHandlerCallback)(uint16_t error); + + /// number of L6206 devices + uint8_t numberOfDevices; + + /// L6206 driver instance + uint8_t deviceInstance; + + /// L6206 Device Paramaters structure + deviceParams_t devicePrm; +} L6206_Data_t; + +/** + * @} + */ + + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + + +/** @defgroup MotorControl_Board_Linked_Functions MotorControl Board Linked Functions + * @{ + */ +///Delay of the requested number of milliseconds +extern void L6206_Board_Delay(void *handle, uint32_t delay); +///Disable the specified bridge +extern void L6206_Board_DisableBridge(void *handle, uint8_t bridgeId); +///Enable the specified bridge +extern void L6206_Board_EnableBridge(void *handle, uint8_t bridgeId, uint8_t addDelay); +//Get the status of the flag and enable Pin +extern uint32_t L6206_Board_GetFlagPinState(void *handle, uint8_t bridgeId); +///Initialise GPIOs used for L6206s +extern void L6206_Board_GpioInit(void *handle); +///Set Briges Inputs PWM frequency and start it +extern void L6206_Board_PwmSetFreq(void *handle, uint8_t bridgeInput, uint32_t newFreq, uint8_t duty); +///Deinitialise the PWM of the specified bridge input +extern void L6206_Board_PwmDeInit(void *handle, uint8_t bridgeInput); +///init the PWM of the specified bridge input +extern void L6206_Board_PwmInit(void *handle, uint8_t bridgeInput); +///Stop the PWM of the specified bridge input +extern void L6206_Board_PwmStop(void *handle, uint8_t bridgeInput); +/** + * @} + */ + + + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus + } +#endif + +#endif /* #ifndef __L6206_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + +
diff -r 05340e740644 -r b7fc55bf70b2 X_NUCLEO_IHM04A1/ST_INTERFACES.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IHM04A1/ST_INTERFACES.lib Fri Jul 21 11:19:39 2017 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/teams/ST/code/ST_INTERFACES/#d3c9b33b992c
diff -r 05340e740644 -r b7fc55bf70b2 main.cpp --- a/main.cpp Wed May 24 15:36:18 2017 +0000 +++ b/main.cpp Fri Jul 21 11:19:39 2017 +0000 @@ -68,8 +68,8 @@ { L6206_CONF_PARAM_PARALLE_BRIDGES, {L6206_CONF_PARAM_FREQ_PWM1A, L6206_CONF_PARAM_FREQ_PWM2A, L6206_CONF_PARAM_FREQ_PWM1B, L6206_CONF_PARAM_FREQ_PWM2B}, - {100,100,100,100}, - {FORWARD,FORWARD,BACKWARD,FORWARD}, + {0,0,0,0}, + {FORWARD,FORWARD,FORWARD,FORWARD}, {INACTIVE,INACTIVE,INACTIVE,INACTIVE}, {FALSE,FALSE} }; @@ -94,6 +94,7 @@ gLastError = error; /* Enter your own code here */ + printf("Error: %u\r\n\n",error); } /** @@ -164,14 +165,21 @@ /* Initializing Motor Control Component. */ motor = new L6206( D2, A4, D5, D4, A0, A1); - + DigitalIn Pin_d4(D4); + DigitalIn Pin_a0(A0); + DigitalIn Pin_a1(A1); + + Pin_d4.mode(PullNone); + Pin_a0.mode(PullNone); + Pin_a1.mode(PullNone); + /* When init method is called with NULL pointer, the L6206 parameters are set */ /* with the predefined values from file l6206_target_config.h, otherwise the */ - /* parameters are set using the init structure values. */ + /* parameters are set using the init structure values. */ if (motor->init(&init) != COMPONENT_OK) { exit(EXIT_FAILURE); } - + /* Attach the function my_flag_irq_handler (defined below) to the flag interrupt */ motor->attach_flag_interrupt(my_flag_irq_handler); @@ -183,63 +191,82 @@ /* Select the configuration with no bridge paralleling, two unidirectionnal motors on bridge A and two unidirectionnal motors on bridge B */ - motor->set_dual_full_bridge_config(PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B); + //motor->set_dual_full_bridge_config(PARALLELING_NONE___2_UNDIR_MOTOR_BRIDGE_A__2_UNDIR_MOTOR_BRIDGE_B); + motor->set_dual_full_bridge_config(PARALLELING_ALL_WITH_IN1A___1_UNDIR_MOTOR); /* Set PWM Frequency of bridge A inputs to 1000 Hz */ - motor->set_bridge_input_pwm_freq(0,1000); + // motor->set_bridge_input_pwm_freq(0,10000); /* Set PWM Frequency of bridge B inputs to 2000 Hz */ - motor->set_bridge_input_pwm_freq(1,2000); + //motor->set_bridge_input_pwm_freq(1,2000); + motor->set_bridge_input_pwm_freq(0,1000); + //motor->set_bridge_input_pwm_freq(1,50000); + Pin_d4.mode(PullNone); + Pin_a0.mode(PullNone); + Pin_a1.mode(PullNone); // Attach my_button_pressed function to Irq my_button_irq.fall(&my_button_pressed); /* Infinite loop */ while (true) { + + if (gStep == 0) { + printf("stopping motor 0\r\n"); + /* Set speed of motor 0 to 5% */ + motor->hard_hiz(0); + } - if (gStep > 0) { + + + if (gStep == 1) { + printf("Running motor 0 at 1%% of the maximum speed\r\n"); + /* Set speed of motor 0 to 5% */ + motor->set_speed(0,100); + /* start motor 0 */ + motor->run(0, BDCMotor::FWD); + + } + + if (gStep == 2) { printf("Running motor 0 at 5%% of the maximum speed\r\n"); - /* Set speed of motor 0 to 5% */ - motor->set_speed(0,5); - /* start motor 0 */ + /* Set speed of motor 1 to 10 % */ + motor->set_speed(0,500); + /* start motor 1 */ + //motor->run(1, BDCMotor::FWD); motor->run(0, BDCMotor::FWD); } - if (gStep > 1) { - printf("Running motor 1 at 10%% of the maximum speed\r\n"); - /* Set speed of motor 1 to 10 % */ - motor->set_speed(1,10); - /* start motor 1 */ - motor->run(1, BDCMotor::FWD); - } - - if (gStep > 2) { - printf("Running motor 2 at 15%% of the maximum speed\r\n"); + if (gStep == 3) { + printf("Running motor 0 at 10%% of the maximum speed\r\n"); /* Set speed of motor 2 to 15 % */ - motor->set_speed(2,15); + motor->set_speed(0,1000); /* start motor 2 */ - motor->run(2, BDCMotor::FWD); + //motor->run(2, BDCMotor::FWD); + motor->run(0, BDCMotor::FWD); } - if (gStep > 3) { - printf("Running motor 3 at 20%% of the maximum speed\r\n"); + if (gStep == 4) { + printf("Running motor 0 at 50%% of the maximum speed\r\n"); /* Set speed of motor 3 to 20 % */ - motor->set_speed(3,20); + motor->set_speed(0,5000); /* start motor 3 */ - motor->run(3, BDCMotor::FWD); + //motor->run(3, BDCMotor::FWD); + motor->run(0, BDCMotor::FWD); } - if (gStep > 0) { + if (gStep >= 0) { wait_ms(1000); - motor->hard_hiz(0); - motor->hard_hiz(1); - motor->hard_hiz(2); - motor->hard_hiz(3); + //motor->hard_hiz(0); + //motor->hard_hiz(1); + //motor->hard_hiz(2); + //motor->hard_hiz(3); - wait_ms(1000); + //wait_ms(1000); } } } /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +