

/**
 ******************************************************************************
 *
 * @file        BSP_7_StepMotor.c
 * @brief       This is Step Motor C file.
 
 * @par         Project
 *              MG32
 * @version     V1.01
 * @date        2022/05/23
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2017 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 * 
 ******************************************************************************* 
 * @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 */

/*==============================================================================
                                 User Notes
How To use this function:
-----------------------
    1. Use BSP_StepMotor_Init() function to inital.
    2. Use "BSP_StepMotor_ClockwiseRotate" function to control step motor clockwise rotate n step.
    3. Use "BSP_StepMotor_AnticlockwiseRotate" function to control step motor anticlockwise rotate n step.
    4. By calling "BSP_StepMotor_GetStatus" function to get previous rotate whether complete or not.
    5. Use "BSP_StepMotor_SetSpeed" function to control step motor rotating speed.
    
--------------------
    + MG32_GPIO_DRV
    + MG32_TM_DRV

Known Limitations:
------------------

Require parameter
------------------
    Require module : CSC / GPIO / TM10 
    
    GPIO pin configuration : 
        Pin  / IO mode / AFS
        ---  --------  -----
        PC8 / PPO     / GPIO
        PC9 / PPO     / GPIO
        PC10/ PPO     / GPIO
        PC11/ PPO     / GPIO
        
    TM10 Module :
        Mode              : Cascade mode
        Overflow time     : 1ms ( in TM10 clock source is 48Mhz)            
        
Example codes:
------------------

==============================================================================*/ 



/* Includes ------------------------------------------------------------------*/
#include "BSP_7_StepMotor.h" 
 
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//GPIO
#define STEPMOTOR_OUT1_PIN            PX_Pin_8
#define STEPMOTOR_OUT2_PIN            PX_Pin_9
#define STEPMOTOR_OUT3_PIN            PX_Pin_10
#define STEPMOTOR_OUT4_PIN            PX_Pin_11
#define STEPMOTOR_IN_PIN_MODE         PINX_Mode_PushPull_O
#define STEPMOTOR_IN_PIN_AFS          0                      // 0 = GPIO mode.
#define STEPMOTOR_IN_PORT             IOMC
                                      
//TM                                      
#define STEPMOTOR_TM                  TM10                 
#define STEPMOTOR_TM_CLK_FREQ         48000000                                      
                                      
//Step motor control                                      
#define STEPMOTOR_REDUCTION_RADIO     64

#define STEPMOTOR_STOP()              GPIOC->SC.H[1] = (STEPMOTOR_OUT1_PIN|STEPMOTOR_OUT2_PIN|STEPMOTOR_OUT3_PIN|STEPMOTOR_OUT4_PIN)
#define STEPMOTOR_RUN(__STEP__)       GPIOC->SC.W    = (__STEP__)


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
//1-2 Phase Excitation Control table(GPIO)
static uint32_t const StepMotor_SetPattern[8] =
{
    0x07000800,      // OUT1
    0x03000C00,      // OUT1 + OUT2
    0x0B000400,      //        OUT2
    0x09000600,      //        OUT2 + OUT3
    0x0D000200,      //               OUT3
    0x0C000300,      //               OUT3 + OUT4
    0x0E000100,      //                      OUT4
    0x06000900,      // OUT1                 OUT4
};

static uint32_t StepMotor_Step;
static uint8_t  StepMotor_PhaseControl;
static uint8_t  StepMotor_ClockwiseRotate;

/* Private function prototypes -----------------------------------------------*/
void TM10_IRQHandler(void);

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External vairables --------------------------------------------------------*/

/**
 *******************************************************************************
 * @brief	    Step motor inital.
 * @details     
 * @return      
 * @exception   No
 * @note        No
 *******************************************************************************
 */
void TM10_IRQHandler(void)
{
    TM_ClearFlag( STEPMOTOR_TM, TMx_TOF);
    
    if( StepMotor_Step == 0)
    {
        TM_Timer_Cmd(STEPMOTOR_TM,DISABLE);
        STEPMOTOR_STOP();
        return;
    }
    
    STEPMOTOR_RUN(StepMotor_SetPattern[StepMotor_PhaseControl]);
    
    if( StepMotor_ClockwiseRotate == 1)
    {
        if( StepMotor_PhaseControl == 7)
        {
            StepMotor_PhaseControl = 0;
        }
        else
        {
            StepMotor_PhaseControl =  StepMotor_PhaseControl + 1;
        }
    }
    else if( StepMotor_PhaseControl == 0)
    {
        StepMotor_PhaseControl = 7;
    }
    else
    {
        StepMotor_PhaseControl = StepMotor_PhaseControl - 1;   
    }
    
    StepMotor_Step = StepMotor_Step - 1;
    
}
/**
 *******************************************************************************
 * @brief	    Step motor inital.
 * @details     
 * @return      
 * @exception   No
 * @note        No
 *******************************************************************************
 */
void BSP_StepMotor_Init(void)
{
    PIN_InitTypeDef         StepMotor_Pin;
    TM_TimeBaseInitTypeDef  StepMotor_TimeBase;

    //GPIO Inital.
    /*GPIO intail*/
    StepMotor_Pin.PINX_Pin                = (STEPMOTOR_OUT1_PIN | STEPMOTOR_OUT2_PIN | STEPMOTOR_OUT3_PIN | STEPMOTOR_OUT4_PIN);
    StepMotor_Pin.PINX_Mode               = STEPMOTOR_IN_PIN_MODE;
    StepMotor_Pin.PINX_PUResistant        = PINX_PUResistant_Disable;
    StepMotor_Pin.PINX_Speed              = PINX_Speed_Low;
    StepMotor_Pin.PINX_Inverse            = PINX_Inverse_Disable;
    StepMotor_Pin.PINX_OUTDrive           = PINX_OUTDrive_Level0;
    StepMotor_Pin.PINX_FilterDivider      = PINX_FilterDivider_Bypass;
    StepMotor_Pin.PINX_Alternate_Function = STEPMOTOR_IN_PIN_AFS;                          
    GPIO_PortMode_Config( STEPMOTOR_IN_PORT ,&StepMotor_Pin);
    
    /*Timer Inital*/
    //Timer Default inital
    TM_DeInit(STEPMOTOR_TM);
    
    //TimeBase structure inital
    TM_TimeBaseStruct_Init(&StepMotor_TimeBase);
    
    //Set Step motor rotating speed.
    //Speed = TM clock source freq / ((TM_Prescaler + 1) * (TM_Period + 1));
    
    StepMotor_TimeBase.TM_MainClockDirection = TM_UpCount;
    StepMotor_TimeBase.TM_Prescaler          = (STEPMOTOR_TM_CLK_FREQ/1000) -1;    // In 48MHz  1 pulse is 1ms.
    StepMotor_TimeBase.TM_Period             = 1 - 1;                                 
    StepMotor_TimeBase.TM_CounterMode        = Cascade;
    TM_TimeBase_Init(STEPMOTOR_TM, &StepMotor_TimeBase);
    TM_Timer_Cmd(STEPMOTOR_TM,DISABLE);

    //Interrupt configure
    TM_ClearFlag( STEPMOTOR_TM, TMx_TOF);
    TM_IT_Config(STEPMOTOR_TM, TMx_TIE_IE,ENABLE);
    TM_ITEA_Cmd( STEPMOTOR_TM, ENABLE);
    NVIC_EnableIRQ( TM10_IRQn);

    /*Parameter inital*/
    StepMotor_Step            = 0;
    StepMotor_ClockwiseRotate = 0;
    StepMotor_PhaseControl    = 0;
    STEPMOTOR_STOP();
}
/**
 *******************************************************************************
 * @brief	    Control step motor clockwise rotate 
 * @details     
 * @param[in]   Clockwise_step : step motor clockwise rotate n step.
 * @return      
 * @exception   No
 * @note        No
 *******************************************************************************
 */
void BSP_StepMotor_ClockwiseRotate(uint32_t Clockwise_step)
{
    TM_ClearFlag( STEPMOTOR_TM, TMx_TOF);
    
    StepMotor_ClockwiseRotate = 1;
    StepMotor_Step            = (Clockwise_step * STEPMOTOR_REDUCTION_RADIO);
    
    TM_Timer_Cmd(STEPMOTOR_TM,ENABLE);
}
/**
 *******************************************************************************
 * @brief	    Control step motor anticlockwise rotate 
 * @details     
 * @param[in]   anticlockwise_step : step motor anticlockwise rotate n step.
 * @return      
 * @exception   No
 * @note        No
 *******************************************************************************
 */
void BSP_StepMotor_AnticlockwiseRotate(uint32_t anticlockwise_step)
{
    TM_ClearFlag( STEPMOTOR_TM, TMx_TOF);
    
    StepMotor_ClockwiseRotate = 0;
    StepMotor_Step            = (anticlockwise_step * STEPMOTOR_REDUCTION_RADIO);
    
    TM_Timer_Cmd(STEPMOTOR_TM,ENABLE);
    
}
/**
 *******************************************************************************
 * @brief	   Control step motor rotate speed.
 * @details  
 * @param[in]  StepMotor_Speed : 1 ~ 65535
 * @return      
 * @exception  No
 * @note        
 *             Rotate 1 step need 
 *             = (StepMotor_Speed)* (STEPMOTOR_TM_CLK_FREQ / 1000) * STEPMOTOR_REDUCTION_RADIO
 *******************************************************************************
 */
void BSP_StepMotor_SetSpeed(uint16_t StepMotor_Speed)
{
    TM_Counter_Config(STEPMOTOR_TM,(StepMotor_Speed - 1),(StepMotor_Speed - 1));
}
/**
 *******************************************************************************
 * @brief	    Get Step motor status.
 * @details     
 * @return      Step motor status.
 * @exception   No
 * @note        No
 *******************************************************************************
 */
uint8_t BSP_StepMotor_GetStatus(void)
{
    if( StepMotor_Step == 0)
    {
        return(BSP_STEPMOTOR_IDLE);
    }
    return(BSP_STEPMOTOR_BUSY);
}





 
 
 
 
