/****************************************************************************
* file name: mc_drv.c
*
*****************************************************************************/
#include "config.h"
#include "mc_drv.h"
#include "mc_lib.h"
#include "mc_control.h"
#include "serial.h"
#include "adc_drv.h"
#include "dac_drv.h"
#include "amplifier_drv.h"
#include "pll_drv.h"
#include "comparator_drv.h"
#include "stdio.h"
U8 count = 1; // variable "count" is use for calculate the "average" speed on 'n' samples
U16 average = 0;
U8 ovf_timer = 0; // variable "ovf_timer" is use to simulate a 16 bits timer with 8 bits timer
Bool g_mc_read_enable = FALSE; // the speed can be read
Bool g_tic = FALSE; //!< Use for control the sampling period value
Bool current_EOC = FALSE; //End Of Concersion Flag
S32 Num_turn = 0; //Used to count the number of motor revolutions
S32 Num_turn2 = 0;
U8 hall_state = 0;
char State = CONV_INIT; // State of the ADC scheduler
char ADC_State = FREE; // ADC State : running = BUSY not running = FREE
/******************************************************************************************************************************/
/******************************************************************************************************************************/
/* Hardware Initialization */
/******************************************************************************************************************************/
/******************************************************************************************************************************/
/**
* @brief init HW
* @pre set all functions mc_init_port(), mc_init_pwm()...
* @post initialization of hardware
*/
void mc_init_HW(void)
{
mc_init_port();
mc_init_IT();
// Be careful : initialize DAC and Over_Current before PWM.
init_dac();
mc_set_Over_Current(100); // 5 => 1A ; 8 => 40A
mc_init_pwm();
mc_config_time_estimation_speed();
mc_config_sampling_period();
init_comparator0();
init_comparator1();
init_comparator2();
}
/**
* @brief init SW
* @pre none
* @post initialization of software
*/
void mc_init_SW(void)
{
Enable_interrupt();
}
/**
* @brief Initialization of IO PORTS for AT90PWM3
* @pre none
* @post initialization of I/O Ports
*/
void mc_init_port(void)
{
// Output Pin configuration
// PD0 => H_A PB7 => L_A
// PC0 => H_B PB6 => L_B
// PB0 => H_C PB1 => L_C
//Do not modify PSCOUT Configuration
// PORT B :
DDRB = (1<<DDB7)|(1<<DDB6)|(1<<DDB1)|(1<<DDB0);
// PORT C :
DDRC = (1<<DDC0);
// PORT D :
DDRD = (1<<DDD0);
// DDnx = 0:Input 1:Output (n = B,C,D,E ; x = 0,1,2,3,4,5,6,7)
// PB3 => EXT1 PB4 => EXT2
// PC1 => EXT3 PC2 => EXT4
// PB5 => EXT5/POT PE1 => EXT6
// PD3 => EXT7/MOSI/LIN_TxD/TxD PD4 => EXT8/MISO/LIN_RxD/RxD
// PE0 => EXT9/NRES PD2 => EXT10/MISO
// Modify DDnx according to your hardware implementation
// PORT B :
DDRB |= (0<<DDB5)|(1<<DDB4)|(0<<DDB3);
// PORT C :
DDRC |= (0<<DDC2)|(0<<DDC1);
// PORT D :
DDRD |= (0<<DDD4)|(0<<DDD3)|(0<<DDD2); // Becareful if using the UART interface or JTAGE ICE mkII.
// PORT E :
DDRE |= (1<<DDE2)|(0<<DDE1)|(0<<DDE0); // Becareful PE0 is you by JTAGE ICE mkII.
// Warning Output Low for MOSFET Drivers
PORTB &= ~(1<<PORTB7 | 1<<PORTB6 | 1<<PORTB1 | 1<<PORTB0);
PORTC &= ~(1<<PORTC0);
PORTD &= ~(1<<PORTD0);
// pull up activation
PORTC |= (1<<PORTC1);
PORTD |= (1<<PORTD1);
// Disable Digital Input for amplifier1
// Digitals Inputs for comparators are not disable.
DIDR0 = (0<<ADC6D)|(0<<ADC3D)|(0<<ADC2D);
DIDR1 = (0<<ACMP0D)|(0<<ACMP1D)|(1<<AMP1PD)|(1<<AMP1ND);
}
/**
* @brief Initialization of PWM generators (PSC) for AT90PWM3
* @pre none
* @post initialization of PSC
*/
void mc_init_pwm()
{
Start_pll_32_mega();
Wait_pll_ready();
// In Center Aligned Mode :
// => PSCx_Init(Period_Half, Dutyx0_Half, Synchro, Dutyx1_Half)
PSC0_Init(255,0,1,0);
PSC1_Init(255,0,1,0);
PSC2_Init(255,0,1,0);
}
/**
* @brief Initialization of AT90PWM3 External Interrupts
* @pre none
* @post External Interrupts (INT0, INT1, INT2, INT3) initialized
*/
void mc_init_IT(void)
{
EICRA =(0<<ISC21)|(1<<ISC20)|(0<<ISC11)|(1<<ISC10)|(0<<ISC01)|(1<<ISC00);
EIFR = (1<<INTF2)|(1<<INTF1)|(1<<INTF0); // clear possible IT due to config
EIMSK=(1<<INT2)|(1<<INT1)|(1<<INT0);
}
// PSC initialization depend on the PSC mode
// 0- One ramp Mode
// 1- Two ramp Mode
// 2- Four ramp Mode
// 3- Center Aligned Mode
/**
* @brief Initialization of PWM generator PSC0
*/
void PSC0_Init ( unsigned int OCRnRB,
unsigned int OCRnSB,
unsigned int OCRnRA,
unsigned int OCRnSA)
{
OCR0SAH = HIGH(OCRnSA);
OCR0SAL = LOW(OCRnSA);
OCR0RAH = HIGH(OCRnRA);
OCR0RAL = LOW(OCRnRA);
OCR0SBH = HIGH(OCRnSB);
OCR0SBL = LOW(OCRnSB);
OCR0RBH = HIGH(OCRnRB);
OCR0RBL = LOW(OCRnRB);
PCNF0 = RAMP_MODE_NUMBER | (1<<PCLKSEL0) | OUTPUT_ACTIVE_HIGH ;
PFRC0A = (1<<PELEV0A)|(1<<PFLTE0A)|(0<<PRFM0A3)|(1<<PRFM0A2)|(1<<PRFM0A1)|(1<<PRFM0A0);
PFRC0B = 0;
PSOC0 = (1<<PSYNC00); //Send signal on match with OCRnSA (during counting up of PSC)
PCTL0 = (0<<PAOC0A)|(1<<PARUN0)|PRESC_NODIV; /* AUTORUN !! */
}
/**
* @brief Initialization of PWM generator PSC1
*/
void PSC1_Init ( unsigned int OCRnRB,
unsigned int OCRnSB,
unsigned int OCRnRA,
unsigned int OCRnSA)
{
OCR1SAH = HIGH(OCRnSA);
OCR1SAL = LOW(OCRnSA);
OCR1RAH = HIGH(OCRnRA);
OCR1RAL = LOW(OCRnRA);
OCR1SBH = HIGH(OCRnSB);
OCR1SBL = LOW(OCRnSB);
OCR1RBH = HIGH(OCRnRB);
OCR1RBL = LOW(OCRnRB);
PCNF1 = RAMP_MODE_NUMBER | (1<<PCLKSEL1) | OUTPUT_ACTIVE_HIGH ;
PFRC1A = 0;
PFRC1B = 0;
PCTL1 = (0<<PAOC1A)|(1<<PARUN1)|PRESC_NODIV; /* AUTORUN !! */
}
/**
* @brief Initialization of PWM generator PSC2
*/
void PSC2_Init ( unsigned int OCRnRB,
unsigned int OCRnSB,
unsigned int OCRnRA,
unsigned int OCRnSA)
{
OCR2SAH = HIGH(OCRnSA);
OCR2SAL = LOW(OCRnSA);
OCR2RAH = HIGH(OCRnRA);
OCR2RAL = LOW(OCRnRA);
OCR2SBH = HIGH(OCRnSB);
OCR2SBL = LOW(OCRnSB);
OCR2RBH = HIGH(OCRnRB);
OCR2RBL = LOW(OCRnRB);
PCNF2 = RAMP_MODE_NUMBER | (1<<PCLKSEL2) | OUTPUT_ACTIVE_HIGH ;
PFRC2A = 0;
PFRC2B = 0;
PCTL2 = (0<<PAOC2A)|(1<<PRUN2)|PRESC_NODIV; /* RUN !! */
}
/******************************************************************************************************************************/
/******************************************************************************************************************************/
/* All functions for motor's phases commutation */
/******************************************************************************************************************************/
/******************************************************************************************************************************/
/**
* @brief Get the value of hall sensors (1 to 6)
* @param return an unsigned char
* value of hall sensor
* @pre configuration of port PB and PD
* @post new value of position
*/
U8 mc_get_hall(void)
{
return HALL_SENSOR_VALUE();
}
/**
* @brief External interruption
* Sensor (A) mode toggle
* @pre configuration of external interruption (initialization)
* @post New value in Hall variable
*/
#pragma vector = HALL_A()
__interrupt void mc_hall_a(void)
{
mc_switch_commutation(HALL_SENSOR_VALUE());
//estimatio