CAN无法退出初始化 ..... CAN cannot exit initialization

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CAN无法退出初始化 ..... CAN cannot exit initialization

1,392 Views
panda2022
Contributor II

void Init_Can(void){
// DDL_GpioInit_Pin_t3(output);
// BSW_SetDigitalChnlState('t3', 1);//can芯片上电

//initialise MSCAN
CAN0CTL0 = 0x01;
while (!(CAN0CTL1_INITAK)){}
CAN0CTL1_CANE = 1; /* Enable MSCAN module */
CAN0CTL1_CLKsrc=0; /* Clock source is OSCCLK = 4 MHz */ // 选择外部晶振做时钟源 我的板子上是20M
CAN0CTL1_LOOPB = 0; /* Set to 1 for LoopBack Mode, 0 otherwise */
CAN0CTL1_LISTEN = 0; /* Not listen only mode */
CAN0CTL0_WUPE = 1; /* Enable WAKEUP */


//Baud rate = CANCLK/(Pre-scaler * time quanta) 1M=20M/(1+14+5)
CAN0BTR1_TSEG_10 = 0x0d; // d为十进制 的13 手册上D对应Tq为14
CAN0BTR1_TSEG_20 = 0x04; //Tq为5
CAN0BTR0_BRP = 0x00;
CAN0BTR0_SJW = 0x03;
CAN0BTR1_SAMP = 0;

//accept all messages
CAN0IDAC_IDAM = 0; /* Two 32 bit filters */
CAN0IDMR0 = 0xFF; /* Accept all incoming ID's */
CAN0IDMR1 = 0xFF;
CAN0IDMR2 = 0xFF;
CAN0IDMR3 = 0xFF;
CAN0IDMR4 = 0xFF;
CAN0IDMR5 = 0xFF;
CAN0IDMR6 = 0xFF;
CAN0IDMR7 = 0xFF;

//exit initialisation mode
CAN0CTL0_INITRQ = 0;
while (CAN0CTL1_INITAK){};
while(!(CAN0CTL0_SYNCH)){};

//clear flags
CAN0RFLG_RXF = 1;
CAN0RIER_RXFIE = 1;


}

 

 

0 Kudos
5 Replies

1,372 Views
lama
NXP TechSupport
NXP TechSupport

Hi,


Could you please confirm:
1) you have 4MHz oscillator and you want to use thi oscillator as a source clock for CAN.
2) Te bitrate you want oto use is 1Mbps. (Note, it i not possible)

Of course, if you use BUSCLK as a source clock then your CLKSRC should be 1.You have 0 (1 MSCAN clock source is the bus clock)

If I consider you will use 20MHz BUSCLK then the setup is (for given transceiver RxTx propagation delay)... can be seen in attached Excel.

 


Note, in this case the code
CAN0RFLG_RXF = 1;
This code is clearing all flags in the register because bit operation is read- modify-write and writing all 1 back after reading clars flags not only expected.

You must use CAN0RFLG = 0x01;
The proof can be found in https://www.nxp.com/docs/en/application-note/AN2554.pdf

Incorrect interrupt flag clearing.
For example clear flag 0
correct: flag = 0x01;
incorrect: flag_flag0 = 1; // the instruction works with entire byte read-modify-write so it clears all interrupt flags and not only selected

 

 

0 Kudos

1,361 Views
panda2022
Contributor II

/*****************************************************************************
* Define motor type
*
* MOTOR_TYPE 0 Linix 40W
* Motor wires connection
* J24-1 -phase0: white
* J24-2 -phase2: green
* J24-3 -phase1: blue
*
* Hall wires connection
* J11-1: red
* J11-2: black
* J11-3: white
* J11-4: blue
* J11-5: green
* J11-6: NC
*
* MOTOR_TYPE 1 Linix 90W
* Motor wires connection
* J24-1 -phase0: green
* J24-2 -phase2: white
* J24-3 -phase1: blue
* Hall wires connection
* J11-1: red
* J11-2: black
* J11-3: white
* J11-4: green
* J11-5: blue
* J11-6: NC
*
******************************************************************************/
#define MOTOR_TYPE 1

/*****************************************************************************
* Define Hall based or Sensorless based BLDC SixStep Control
*
* HALL_SENSOR 0 Sensorless operation, motor position/speed obtained by the back-EMF voltage
* zero-cross detection method
* HALL_SENSOR 1 Sensorbased operation, motor position/speed is obtained by the Hall sensor
*
******************************************************************************/
#define HALL_SENSOR 0


#include "typedefs.h"
#include "mc9s12zvml128.h"

#if MOTOR_TYPE
#include "BLDC_appconfig_90W.h"
#else
#include "BLDC_appconfig_40W.h"
#endif

#include "S12ZVM_devconfig.h"
#include "mlib.h"
#include "gflib.h"
#include "gdflib.h"
#include "SWLIBS_Config.h"
#include "freemaster.h"

/*****************************************************************************
*
* Types Definition
*
*****************************************************************************/
typedef void (*tPointerFcn)(void); /* pointer to function */

// BLDC drive status register
typedef union uDriveStatus {
unsigned int word;
struct
{
unsigned int Alignment :1;
unsigned int Sensorless :1;
unsigned int DisableAdc :1;
unsigned int StallCheckReq :1;
unsigned int EnableCMT :1;
unsigned int AfterCMT :1;
unsigned int CloseLoop :1;
unsigned int NewZC :1;
unsigned int AdcSaved :1;
unsigned int CurrentLimiting :1;
unsigned int Fault :1;
unsigned int HallSensor :1;
unsigned int :4;
}bit;
}tDriveStatus;

// User control bits and counters
typedef struct
{
tU32 ledCounter;
tU32 ledFlashing;
tU16 btCounter;
tU8 btSpeedUp; // Variable to increase the speed command by given step
tU8 btSpeedDown; // Variable to lower the speed command by given step
tU8 btFlipFlop, btFlipFlopTemp; // Enable/Disable Control
tBool switchAppOnOff; /*! raw value */
tBool switchAppOnOffState; /*! raw value */
tBool switchFaultClear; /*! raw value */
tBool switchAppReset; /*! raw value */
tBool readFault; // Read fault status
}userControl_t;

// Application events
typedef enum
{
e_stop = 0,
e_run = 1
}Events;

// MCU related faults
typedef union
{
tU16 R;
struct
{
tU16 PTU_Error : 1; /* Error in PTU hw initialization*/
tU16 ADC_Error : 1; /* Error in ADC hw initialization*/
tU16 PWM_Error : 1; /* Error in PWM hw initialization */
tU16 GDU_Error : 1; /* Error in GDU hw initialization */
tU16 : 12; /* RESERVED */
}B;
}mcuFaultStatus_t;

// Motor related faults
typedef union
{
tU16 R;
struct
{
tU16 OffCancError : 1; /* Offset Cancellation Error flag */
tU16 OverCurrent : 1; /* OverCurrent fault flag */
tU16 OverHeating : 1; /* Overheating fault flag */
tU16 MainsFault : 1; /* Mains out of range */
tU16 OverLoad : 1; /* Overload Flag */
tU16 OverDCBusCurrent : 1; /* OverCurrent fault flag */
tU16 UnderDCBusVoltage : 1; /* Undervoltage fault flag */
tU16 OverDCBusVoltage : 1; /* Overvoltage fault flag */
tU16 HallPatternError : 1; /* HallPatternError */
tU16 : 7; /* RESERVED */
}B;
}motorFaultStatus_t;

/*! Application fault status user type */
typedef struct
{
mcuFaultStatus_t mcu;
motorFaultStatus_t motor;
}appFaultStatus_t; /* Application fault status user type*/

// Application states
typedef struct
{
tU16 state; /*! raw value */
Events event; /*! raw value */
userControl_t usrControl; /* user action required */
appFaultStatus_t faults;
}driveStates_t;

// FreeMASTER scales
typedef struct
{
tU32 current;
tU32 voltage;
tU32 dcb_voltage;
tU32 speed_w_e;
tU32 speed_n_m;
tU32 speed_ramp;
tU32 position;
}fm_scale_t;

 

/*****************************************************************************
*
* Constants Definition
*
*****************************************************************************/
int rotationDir = 0; // FMSTR variable for change direction
int dir = 0; // 0 = CW / 1 = CCW

#if !HALL_SENSOR
// CW CCW
const char MaskVal[2][6] = {{0x34, 0x1c, 0x13, 0x31, 0x0d, 0x07}, {0x31, 0x13, 0x1c, 0x34, 0x07, 0x0d}};
const char OutCtl[2][6] = {{0x0c, 0x30, 0x30, 0x03, 0x03, 0x0c}, {0x03, 0x30, 0x30, 0x0c, 0x0c, 0x03}};
const char BemfPhase[2][6] = {{0x03, 0x02, 0x01, 0x03, 0x02, 0x01}, {0x03, 0x01, 0x02, 0x03, 0x01, 0x02}};
#else
#if MOTOR_TYPE
// CW CCW
const char MaskVal[2][6] = {{0x34, 0x1c, 0x13, 0x31, 0x0d, 0x07}, {0x31, 0x0d, 0x07, 0x34, 0x1c, 0x13}};
const char OutCtl[2][6] = {{0x0c, 0x30, 0x30, 0x03, 0x03, 0x0c}, {0x03, 0x03, 0x0c, 0x0c, 0x30, 0x30}};
const char BemfPhase[2][6] = {{0x03, 0x02, 0x01, 0x03, 0x02, 0x01}, {0x03, 0x02, 0x01, 0x03, 0x02, 0x01}};
#else
const char MaskVal[2][6] = {{0x13, 0x1c, 0x34, 0x07, 0x0d, 0x31}, {0x07, 0x0d, 0x31, 0x13, 0x1c, 0x34}};
const char OutCtl[2][6] = {{0x30, 0x30, 0x0c, 0x0c, 0x03, 0x03}, {0x0c, 0x03, 0x03, 0x30, 0x30, 0x0c}};
const char BemfPhase[2][6] = {{0x03, 0x02, 0x01, 0x03, 0x02, 0x01}, {0x03, 0x01, 0x02, 0x03, 0x01, 0x02}};
#endif
#endif

/*
Phase Voltage sensing select bits:
00 Pin HD selected , VHD / 12 connected to ADC channel
01 Pin HS0 selected , VHS0 / 6 connected to ADC channel
10 Pin HS1 selected , VHS1 / 6 connected to ADC channel
11 Pin HS2 selected, VHS2 / 6 connected to ADC channel
*/

/*****************************************************************************
*
* Variables Definition
*
*****************************************************************************/
volatile tU16 NextCmtPeriod, duty_cycle;
volatile tU16 NextCmtSector, ActualCmtSector, test;
volatile tU16 alignmentTimer, alignmentTimeValue, startCMTcounter, startCMTcounterPeriod;
volatile tFrac16 startCMTacceleration;
volatile tU16 hallPattern;
volatile tU16 hallEdgePerod1msCounter;
volatile tU16 timerValue, timerLastValue, timerValueLim, cmtSector;

// Hall period array
tU16 hallEdgePeriod[7] = {0, 0, 0, 0, 0, 0, 0};

/* IMPORTANT: jumper J9 must be opened for Hall base application */
// Hall pattern, clockwise and counter clockwise. Array first member is not used.
// CW CCW
#if MOTOR_TYPE
const uint8_t BLDCPatternBasedOnHall[7] = {0, 4, 0, 5, 2, 3, 1};
const uint8_t BLDCStartVectorOnHall [6] = {3, 4, 5, 0, 1, 2};
#else
const uint8_t BLDCPatternBasedOnHall[7] = {0, 1, 5, 0, 3, 2, 4};
const uint8_t BLDCStartVectorOnHall [6] = {3, 4, 5, 0, 1, 2};
#endif

volatile driveStates_t ctrlStates;
volatile tDriveStatus driveStatus;

appFaultStatus_t tempfaults; // Temporary faults to be indicated inhere
appFaultStatus_t permFaults; // Permanent faults to be indicated inhere

GDFLIB_FILTER_MA_T dcCurrentFilterParams;

volatile unsigned char phaseStatus;

volatile tFrac16 DCBusCurrentOffset, DCBusCurrent, DCBusCurrentZC, DCBusCurrentFiltered;
volatile tFrac16 requiredOpenLoopCurrent, requiredAlignCurrent;
volatile tU16 phaseVoltage, DCBusVoltageHalf, DCBusVoltage;
volatile short bemfVoltage, bemfVoltageOld;
volatile tU16 timeBEMF, timeOldBEMF, timeCommutation, timeZCToff;
volatile tU16 timeZC, lastTimeZC;
volatile tU16 actualPeriodZC;
volatile uint16_t periodZC[6];
volatile unsigned long period6ZC, periodZcAvrg;
volatile tU16 advanceAngle;

volatile tU16 debugPeriodMin, debugPeriodMax, stallCheckCounter;
volatile unsigned char StallError;

volatile tFrac16 speedErr, requiredSpeed, requiredSpeedOld, requiredSpeed_Ramp, reqSpeed, currentErr, DCBusCurrentLimit;
volatile tFrac32 actualSpeed, actSpeed;
volatile tS32 speedScale;
volatile tS16 maxSpeed;
volatile tFrac16 speedPIOut, currentPIOut;
volatile GFLIB_CONTROLLER_PIAW_R_T_F16 speedPIPrms, currentPIPrms, AlignCurrentPIPrms;
GFLIB_RAMP_T_F32 speedRamp;

volatile int AdcErrorLDOK, AdcErrorRSTAR, AdcErrorTRIG, AdcErrorEOL, AdcErrorCMD, AdcErrorIA;
volatile tBool sensorType;

volatile unsigned char GduFlags;

void initCPMU(void);
void initGPIO(void);
void initTIM(void);
void initPMF(void);
void initGDU(void);
void initPTU(void);
void initADC(void);
void initSCI(void);
void initInt(void);
void AdcCalibration(void);

void UpdateDutycycle(void);
void StallCheck(void);
void CheckManualInterface(void);
void AppStartToRun(void);
void AppRunToStop(void);
void AppAlignmentToStart(void);
void AppStopToAlignment(void);
void AppError(void);
void AppStop(void);
void AppRun(void);
void AppStart(void);
void AppAlignment(void);
void AppInit(void);
void AppFault(void);
void UpdateCurrentLimitingLed(void);
void UpdateDutycycle(void);

static tBool faultDetection();

INTERRUPT void TIMchan0_ISR(void);
INTERRUPT void TIMchan1_ISR(void);
INTERRUPT void TIMchan3_ISR(void);
INTERRUPT void ADC1done_ISR(void);
INTERRUPT void PMFfault_ISR(void);
INTERRUPT void PMFreloadA_ISR(void);
INTERRUPT void PMFreloadA_ISR(void);
INTERRUPT void PTUTrigger0Done_ISR(void);
INTERRUPT void PMFreloadoverrun_ISR(void);
INTERRUPT void PTUTrigger1Done_ISR(void);
INTERRUPT void ADC0error_ISR(void);
INTERRUPT void ADC0done_ISR(void);
INTERRUPT void ADC1error_ISR(void);

/* LED application control*/
void stateLedOFF();
void stateLedON();
void stateLedFLASHING_SLOW();
void stateLedFLASHING_FASTER();
void stateLedFLASHING_FAST();

void InitializeApp(void);

static tPointerFcn AppStateMachine[] = {
AppInit,
AppAlignment,
AppStart,
AppRun,
AppStop,
AppError,
AppFault
};

static tPointerFcn state_LED[7] = {
stateLedFLASHING_SLOW,
stateLedFLASHING_FASTER,
stateLedFLASHING_FASTER,
stateLedON,
stateLedOFF,
stateLedFLASHING_FAST,
stateLedFLASHING_FAST
};

/****************************************************************************
* Trigger event list
*
* +-------------------+ - (int)PTUTriggerEventList)
* +===================+ - Trigger 0 space
* +*******************+ - List 0 Offset from PTUTriggerEventList = 0 = (int)&PTUTriggerEventList[0][0][0] - (int)PTUTriggerEventList
* | DelayT0 |
* +-------------------+
* | DelayT1 |
* +-------------------+
* | 0x0000 | - End of delay List 0
* +*******************+ - List 1 Offset from PTUTriggerEventList = 3 = (int)&PTUTriggerEventList[0][1][0] - (int)PTUTriggerEventList
* | DelayT0 |
* +-------------------+
* | DelayT1 |
* +-------------------+
* | DelayT2 |
* +-------------------+
* | 0x0000 | - End of delay List 1
* +===================+ - Trigger 1 space
* +*******************+ - List 0 Offset from PTUTriggerEventList = 8 = (int)&PTUTriggerEventList[1][0][0] - (int)PTUTriggerEventList
* | DelayT0 |
* +-------------------+
* | DelayT1 |
* +-------------------+
* | 0x0000 | - End of delay List 0
* +*******************+ - List 1 Offset from PTUTriggerEventList = 12 = (int)&PTUTriggerEventList[1][1][0] - (int)PTUTriggerEventList
* | DelayT0 |
* +-------------------+
* | DelayT1 |
* +-------------------+
* | DelayT2 |
* +-------------------+
* | 0x0000 | - End of delay List 1
* +===================+
*
*
***************************************************************************/
PR_SECTION(ptuTrigE)
volatile short PTUTriggerEventList[PTU_TOT_TRIGGERs_GEN_NO][PTU_TOT_LISTS_NO][3] = {
{ /*DelayT0 */
{0x0100,0x0200,0x0000},{0x0000,0x0000,0x0000}
},
{
{0x0100,0x0000,0x0000},{0x0000,0x0000,0x0000}
}
};

/****
* CMD_SEL[1:0]:
* 00 normal conversion
* 40 end of sequence
* 80 end of list, wrap to top, continue
* C0 end of list, stop
*
*/
PR_SECTION(adcLists)
volatile char ADC0CommandList[6][4] = {
{0x40,0xD0,0x00,0x00}, // current sense channel, end of sequence [D0]
{0xC0,0xCB,0x00,0x00}, // end of list + no int [C0], HD voltage [CB], 4 clock cycles sample time [00], reserved [00]
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00}
};
PR_SECTION(adcLists)
volatile char ADC1CommandList[6][4] = {
{0xC0,0xCA,0x00,0x00}, // [end of list] + no int [C0], phase voltage [CA], 4 clock cycles sample time [00], reserved [00]
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00}
};

volatile unsigned short ADC0ResultList[6] = {0, 0, 0, 0, 0, 0};
volatile unsigned short ADC1ResultList[6] = {0, 0, 0, 0, 0, 0};
PR_SECTION(DEFAULT_SEC)

void Init_Can(void){
// DDL_GpioInit_Pin_t3(output);
// BSW_SetDigitalChnlState('t3', 1);//can芯片上电
//initialise MSCAN
CAN0CTL0 = 0x01;
while (!(CAN0CTL1_INITAK)){}
CAN0CTL1_CANE = 1; /* Enable MSCAN module */
CAN0CTL1_CLKsrc=0; /* Clock source is OSCCLK = 20 MHz */ // 选择外部晶振做时钟源 我的板子上是20M
CAN0CTL1_LOOPB = 0; /* Set to 1 for LoopBack Mode, 0 otherwise */
CAN0CTL1_LISTEN = 0; /* Not listen only mode */
CAN0CTL0_WUPE = 0; /* Enable WAKEUP */


//Baud rate = CANCLK/(Pre-scaler * time quanta) 1M=20M/(1+14+5)
CAN0BTR1_TSEG_10 = 0x0d; // d为十进制 的13 手册上D对应Tq为14
CAN0BTR1_TSEG_20 = 0x04; //Tq为5
CAN0BTR0_BRP = 0x00;
CAN0BTR0_SJW = 0x03;
CAN0BTR1_SAMP = 0;

//accept all messages
CAN0IDAC_IDAM = 0; /* Two 32 bit filters */
CAN0IDMR0 = 0xFF; /* Accept all incoming ID's */
CAN0IDMR1 = 0xFF;
CAN0IDMR2 = 0xFF;
CAN0IDMR3 = 0xFF;
CAN0IDMR4 = 0xFF;
CAN0IDMR5 = 0xFF;
CAN0IDMR6 = 0xFF;
CAN0IDMR7 = 0xFF;

//exit initialisation mode
CAN0CTL1_CANE=0;

while (CAN0CTL1_INITAK){CAN0CTL0_INITRQ = 0;}

while(!(CAN0CTL0_SYNCH)){};

//clear flags
CAN0RFLG_RXF = 1;
CAN0RIER_RXFIE = 1;
}

/*****************************************************************************
*
* Function: void main(void)
*
* Description: main function
*
*****************************************************************************/
void main(void)
{

initCPMU();
initGPIO();
initTIM();
initPMF();
initPTU();
initADC();
initSCI();
initGDU();
initInt();
Init_Can();
FMSTR_Init();

EnableInterrupts;

InitializeApp();


speedScale = SPEEDSCALE;
maxSpeed = MAXSPEED;
//sensorType = HALL_SENSOR;

for(;;)
{
FMSTR_Poll();
AppStateMachine[ctrlStates.state]();
}
}

/*****************************************************************************
*
* Function: void initCPMU(void)
*
* Description: Clock, Reset and Power Management Unit configuration
*
*****************************************************************************/
void initCPMU(void)
{
// Wait for stable supply after power up
while (GDUF_GLVLSF)
GDUF_GLVLSF = 1;

CPMUREFDIV_REFDIV = CPMU_REFDIV;
CPMUREFDIV_REFFRQ = CPMU_REFFRQ;
CPMUSYNR_SYNDIV = CPMU_SYNDIV;
CPMUSYNR_VCOFRQ = CPMU_VCOFRQ;
CPMUPOSTDIV_POSTDIV = CPMU_POSTDIV;
CPMUHTCTL_HTE = 1; // 打开温度传感器

#ifdef _EXTERNAL_CLOCK
CPMUOSC_OSCE = 1;
while (CPMUIFLG_UPOSC == 0) {}; // Wait for oscillator to start up (UPOSC=1) and PLL to lock (LOCK=1)
#endif

while (CPMUIFLG_LOCK == 0) {};
CPMURFLG = 0x60; //Clear PORF and LVRF
return;
}


/*****************************************************************************
*
* Function: void initGPIO(void)
*
* Description: I/O pins configuration
*
*****************************************************************************/
void initGPIO(void) //PIM
{
MODRR0_SCI1RR = 1; // serial port

#if HALL_SENSOR
// TIM0 input capture channel 1 is connected to logic XOR of PT1, PT2, PT3
MODRR2_T0IC1RR = 1;
// Hall sensor PT1, PT2, PT3 pull-ups enabled
PERT = 0x0E;

DDRP_DDRP0 = 1; // Hall sensor power
PTP_PTP0 = 1; // ...power ON
#endif

DDRS_DDRS4 = 1; // config pin to output (DC Bus current limit LED)
DDRS_DDRS5 = 1; // config pin to output (Fault LED)
return;
}

/*****************************************************************************
*
* Function: void initTIM(void)
*
* Description: Timer module configuration
*
*****************************************************************************/
void initTIM(void)
{
TIM0TIOS_IOS0 = 1; // TIM ch0 output compare

#if HALL_SENSOR
TIM0TIOS_IOS1 = 0; // TIM ch1 input capture
#endif

TIM0TIOS_IOS3 = 1; // Set channel 1 as output compare

TIM0TSCR1_PRNT = 0; // NON Precision timer (legacy timer)

TIM0TCTL2_OL0 = 1; // Toggle output of tim chan 0
TIM0TCTL2_OM0 = 0;

#if HALL_SENSOR
TIM0TCTL4_EDG1A = 1; // TIM ch1 input capture on any edge
TIM0TCTL4_EDG1B = 1;
#endif

TIM0TCTL2_OL3 = 0; // No action on output of tim chan 3
TIM0TCTL2_OM3 = 0;

TIM0TIE_C0I = 1; // Enable Interrupts
TIM0TIE_C3I = 1; // Enable Interrupts

#if HALL_SENSOR
TIM0TIE_C1I = 1; // Enable Interrupts
#endif

TIM0TSCR2_PR = TIM_PRESCALER; // Timer prescaler select

TIM0TC3 = TIMER_1MS; // Interrupt to be every ~ 1[ms]

TIM0OCPD = 0xff; // disconnect all output compare pins

TIM0TSCR1_TEN = 1; // Allows the timer to function normally
return;
}

/*****************************************************************************
*
* Function: void initPMF(void)
*
* Description: PMF module configuration
*
*****************************************************************************/
void initPMF(void)
{
PMFCFG0_EDGEA = 1;
PMFCFG0_EDGEB = 1;
PMFCFG0_EDGEC = 1;

PMFCFG2_REV0 = 1; // 01 PWM generator A generates reload event.
PMFCFG2_REV1 = 0;

PMFOUTB = 0x2A; // Low MOSFETs ON while SW control (Unipolar PWM)

PMFCFG3_VLMODE = 0x01; // Writing to value register zero also writes to value registers one to five

//PMFFEN = 0 // Fault disabled
// .... (other fault registers)

PMFFQCA = 0; // Reload every PWM, Half-cycle disabled, fcore / 1

PMFMODA = PWM_MODULO;
PMFDTMA = PWM_DEADTIME;

PMFCFG2 |= 0x3f; // mask all PWM outputs
PMFOUTC_OUTCTL = 0x3f; // all outputs in Software mode
PMFENCA_LDOKA = 1; // apply PMF Modulo value

PMFENCA_RSTRTA = 1; // 1 = PWM restart at commutation event

PMFENCA_PWMENA = 1;

//PMFENCA_PWMRIEA = 1; // Reload Interrupt - Used only for debugging

PMFCFG1_ENCE = 1; // buffered PMFOUTC, PMFOUTB, SWAPx and MSKx (change on commutation event)

PMFENCA_GLDOKA = 1; // 0 = Local LDOKA controls buffered registers / 1 = external Load OK controls buffered registers
return;
}


/*****************************************************************************
*
* Function: void initGDU(void)
*
* Description: GDU module configuration
*
*****************************************************************************/
void initGDU()
{
GDUE_GCPE = 1; // charge pump enable

GDUE_GCSE0 = 1; // enable Current Sense Amplifier 0

GDUF = 0xff; // Flag Register - clear all error flags

// BOOST OPTION SETTINGS
GDUE_GBOE = 1; // boost option enabled
GDUCLK1_GBOCD = 0x1C; // Output clock fbus / 400
GDUCLK1_GBODC = 0x00; // Output duty-cycle 50%
GDUBCL_GBCL = 0x01; // Current limit 108.75 ~ 421.875 mA

GDUCLK2_GCPCD = 2; // Fbus / 32

GDUCTR = 0x13; // blanking time

GDUDSLVL = 0x77; // desat. level

GDUE_GFDE = 1; // enable FET pre-driver

GDUDSE = 0x77; // Clear Desaturation Error Flags

GDUE_EPRES = 1; // enable preserve functionality ??
// GDUE_GCPE = 1; // charge pump
//
// GDUE_GCSE0 = 1; // enable Current Sense Amplifier 0
// GDUE_GCSE1 = 1; // enable Current Sense Amplifier 1
//
// GDUOC0_GOCA0 = 1; // switch off all MOSFETs on overcurrent
// GDUOC0_GOCE0 = 1; // Overcurrent comparator enabled
// GDUOC0_GOCT0 = 12; // Overcurrent threshold = ((48 + 0) / 64) * VDDA = 3.75 V
// // 3.75 V represents
//
// GDUF = 0xff; // Flag Register - clear High & Low Voltage Supply flags
//
// GDUCLK2_GCPCD = 4; // Fbus / 64 !_! for bus clock 50Mhz
//
// GDUCTR = 0x13; // blanking time ! ! 0x0f
// GDUCTR_GHHDLVL = 1; // 26 V overvoltage
//
// GDUDSLVL = 0x77; // desat. level !-! previous 0x44
//
// GDUDSE = 0x77; // Clear Desaturation Error Flags
return;
}

/*****************************************************************************
*
* Function: void initPTU(void)
*
* Description: Programmable Trigger Unit module configuration
*
*****************************************************************************/
void initPTU(void)
{
//PTUIEL_TG0DIE = 1; // Trigger Generator 0 Done Interrupt Enable - Used only for debugging
PTUIEL_TG1DIE = 1; // Trigger Generator 1 Done Interrupt Enable - store Adc measurement time

PTUPTRL = (uint8_t)((long)PTUTriggerEventList);
PTUPTRM = (uint8_t)(((long)PTUTriggerEventList) >> 8);
PTUPTRH = (uint8_t)(((long)PTUTriggerEventList) >> 16);

TG0L1IDX = (uint8_t)(((long)&PTUTriggerEventList[0][0][0] - (long)PTUTriggerEventList) >> 1); // same as TG0L0IDX
TG1L0IDX = (uint8_t)(((long)&PTUTriggerEventList[1][0][0] - (long)PTUTriggerEventList) >> 1);
TG1L1IDX = (uint8_t)(((long)&PTUTriggerEventList[1][0][0] - (long)PTUTriggerEventList) >> 1); // same as TG1L0IDX

PTUE_TG0EN = 1; // Enable Trigger Generation 0
PTUE_TG1EN = 1; // Enable Trigger Generation 1


//PTUDEBUG_PTUREPE = 1; // Enable Reload generation to PIN // Only for debugging - affects the ON/OFF switch
PTUDEBUG_PTUT0PE = 1; // Enable T0 trigger to PIN
PTUDEBUG_PTUT1PE = 1; // Enable T0 trigger to PIN

PTUC_PTULDOK = 1; // Switch list when next reload event
return;
}

/*****************************************************************************
*
* Function: void initAdc(void)
*
* Description: ADC module configuration
*
*****************************************************************************/
void initADC(void)
{

/****************************************
* ADC0
****************************************/

ADC0CTL_0_ACC_CFG = 3; // Dual access mode
ADC0CTL_0_STR_SEQA = 1; // Store result at abort/restart

//ADC0CTL_1 = 0;
ADC0TIM = ADC_TIM; // clock: clk = fbus / (2x(reg.value + 1)) [0.25 - 8MHz]

ADC0FMT_DJM = 0; // left justified result data
ADC0FMT_SRES = 4; // 12-bit result

ADC0CONIE_1_EOL_IE = 1; // End of list interrupt enable

// ADC0 Command Base Pointer
ADC0CBP_0 = (uint8_t)(((long)ADC0CommandList) >> 16);
ADC0CBP_1 = (uint8_t)(((long)ADC0CommandList) >> 8);
ADC0CBP_2 = (uint8_t)((long)ADC0CommandList);

// ADC0 Result Base Pointer
ADC0RBP_0 = (uint8_t)(((long)ADC0ResultList) >> 16);
ADC0RBP_1 = (uint8_t)(((long)ADC0ResultList) >> 8);
ADC0RBP_2 = (uint8_t)((long)ADC0ResultList);

// ADC0 Command/Result Offset registers
ADC0CROFF1 = 0;

ADC0CTL_0_ADC_EN = 1; // enable ADC0
ADC0EIE = 0xEE; // enable all errors interrupts
//ADC0EIE = 0x08; // Enable Trigger Error ISR only


/****************************************
* ADC1
****************************************/

ADC1CTL_0_ACC_CFG = 3; // Dual access mode
ADC1CTL_0_STR_SEQA = 1; // Store result at abort/restart

//ADC1CTL_1 = 0;
ADC1TIM = ADC_TIM; // clock: clk = fbus / (2x(reg.value + 1)) [0.25 - 8MHz]

ADC1FMT_DJM = 0; // left justified result data
ADC1FMT_SRES = 4; // 12-bit result

//ADC1CONIE_1_EOL_IE = 1; // End of list interrupt enable - Used only for debugging

// ADC1 Command Base Pointer
ADC1CBP_0 = (uint8_t)((((long)ADC1CommandList) >> 16) & 0x0000FF);
ADC1CBP_1 = (uint8_t)((((long)ADC1CommandList) >> & 0x0000FF);
ADC1CBP_2 = (uint8_t)((long)ADC1CommandList & 0x0000FF);

// ADC1 Result Base Pointer
ADC1RBP_0 = (uint8_t)((((long)ADC1ResultList) >> 16) & 0x0000FF);
ADC1RBP_1 = (uint8_t)((((long)ADC1ResultList) >> & 0x0000FF);
ADC1RBP_2 = (uint8_t)((long)ADC1ResultList & 0x0000FF);

// ADC1 Command/Result Offset registers
ADC1CROFF1 = 0;

ADC1CTL_0_ADC_EN = 1; // enable ADC1
//ADC1EIE = 0xEE; // enable all error interrupts
ADC1EIE = 0x08; // Enable Trigger Error ISR only
return;
}

/*****************************************************************************
*
* Function: void initSCI(void)
*
* Description: SCI module configuration
*
*****************************************************************************/
void initSCI(void){
SCI1BD = SCI_BAUDRATE;
SCI1CR2_TE = 1; // transmitter enabled
SCI1CR2_RE = 1; // receiver enabled
//SCICR2_RIE = 1;
}


/*****************************************************************************
*
* Function: void initInt(void)
*
*
* Description: Interrupt priorities configuration
*
*****************************************************************************/
void initInt(void)
{
// set PTUTrigger0Done_ISR (0x0E4) priority to 6
// 0xE4 / 4 = 0x39 => reg. value = 0x38 + offset 1
//INT_CFADDR = 0x38;
//INT_CFDATA1 = 6;

// set PTUTrigger1Done_ISR (0x0E0) priority to 6
// 0xE0 / 4 = 0x38 => reg. value = 0x38 + offset 0
INT_CFADDR = 0x38;
INT_CFDATA0 = 6;

// set ADC0done_ISR (0x184) priority to 6
// 0x184 / 4 = 0x61 => reg. 0x60, offset 1
INT_CFADDR = 0x60;
INT_CFDATA1 = 6;

// set TIMchan0_ISR (Commutation)(0x1CC) priority to 5
// 0x1CC / 4 = 0x73 => reg. value = 0x70 + offset 3
INT_CFADDR = 0x70;
INT_CFDATA3 = 5;

#if HALL_SENSOR
// set TIMchan1_ISR (input capture) (0x1C8) priority set to 5
// 0x1C8 / 4 = 0x72 => reg. value = 0x70 + offset 2
INT_CFADDR = 0x70;
INT_CFDATA2 = 5;
#endif

// set TIMchan3_ISR (Speed control loop) (0x1C0) to 4
// 0x1C0 / 4 = 0x70 => reg. value = 0x70 + offset 0
INT_CFADDR = 0x70;
INT_CFDATA0 = 4;
return;
}

/*****************************************************************************
*
* Function: void TIMchan3_ISR(void)
*
* Description: Timer channel 3 Output Compare Interrupt Service Routine
* used to calculate speed, speed control loop and current control loop
*
*****************************************************************************/
tU16 test_duty = 200;
INTERRUPT void TIMchan3_ISR(void)
{
tFrac16 PIOut;
tU16 i = 0;

EnableInterrupts;

TIM0TC3 = TIM0TC3 + TIMER_1MS;

if (driveStatus.bit.StallCheckReq == 1)
{
driveStatus.bit.StallCheckReq = 0;
//StallCheck();
}


// limit the speed
if(requiredSpeed > 0)
{
requiredSpeed = requiredSpeed > MAX_SPEED ? MAX_SPEED : requiredSpeed;
requiredSpeed = requiredSpeed < MIN_SPEED ? MIN_SPEED : requiredSpeed;
}
else
{
requiredSpeed = requiredSpeed < -MAX_SPEED ? -MAX_SPEED : requiredSpeed;
requiredSpeed = requiredSpeed > -MIN_SPEED ? -MIN_SPEED : requiredSpeed;
}

#if !HALL_SENSOR
if (ctrlStates.state != APP_STOP)
{
requiredSpeed = ((actualSpeed > 0) && (requiredSpeed < 0)) ? requiredSpeedOld: requiredSpeed;
requiredSpeed = ((actualSpeed < 0) && (requiredSpeed > 0)) ? requiredSpeedOld: requiredSpeed;
}
requiredSpeedOld = requiredSpeed;
#endif



// requiredSpeed_Ramp = GFLIB_Ramp_F16(requiredSpeed, &speedRamp);
// reqSpeed = MLIB_Abs_F16(requiredSpeed_Ramp);
requiredSpeed_Ramp = (tFrac16)(GFLIB_Ramp_F32(((tFrac32) requiredSpeed)<<16,&speedRamp)>>16);
//dir = requiredSpeed_Ramp > 0 ? CW_DIR : CCW_DIR;

#if HALL_SENSOR
if((driveStatus.bit.HallSensor == 1)&&(ctrlStates.state == APP_RUN))
{
period6ZC = 0;
for(i=1;i<7;i++)
{
period6ZC += hallEdgePeriod[i];
}
actSpeed = SPEED_CALC_NUMERATOR / period6ZC;
actualSpeed = dir == 0 ? actSpeed : MLIB_Neg_F32(actSpeed);
speedErr = reqSpeed - (tFrac16) actSpeed;
speedPIOut = GFLIB_ControllerPIrAW(speedErr, (GFLIB_CONTROLLER_PIAW_R_T_F16 *)&speedPIPrms, F16);

currentErr = DCBusCurrentLimit - DCBusCurrentFiltered;
currentPIOut = GFLIB_ControllerPIrAW(currentErr, (GFLIB_CONTROLLER_PIAW_R_T_F16 *) &currentPIPrms, F16);


if (currentPIOut >= speedPIOut)
{
currentPIPrms.f32Acc = ((tFrac32) speedPIOut) << 16;
currentPIPrms.f16InErrK1 = 0;
PIOut = speedPIOut;
driveStatus.bit.CurrentLimiting = 0;
}
else
{
speedPIPrms.f32Acc = ((tFrac32) currentPIOut) << 16;
speedPIPrms.f16InErrK1 = 0;
PIOut = currentPIOut;
driveStatus.bit.CurrentLimiting = 1;
}

duty_cycle = MLIB_Mul(PIOut, PWM_MODULO, F16); // duty cycle 0-1 -> 0-PWM_MODULO
UpdateDutycycle();
}
#else
if (driveStatus.bit.Sensorless == 1)
{



period6ZC = 0;
for(i=1;i<7;i++)
{
period6ZC += periodZC[i];
}
actSpeed = SPEED_CALC_NUMERATOR / period6ZC;
actualSpeed = dir == 0 ? actSpeed : MLIB_Neg_F32(actSpeed);
speedErr = requiredSpeed_Ramp - (tFrac16) actSpeed;
speedPIOut = GFLIB_ControllerPIrAW(speedErr, (GFLIB_CONTROLLER_PIAW_R_T_F16 *)&speedPIPrms, F16);

currentErr = DCBusCurrentLimit - DCBusCurrentFiltered;
currentPIOut = GFLIB_ControllerPIrAW(currentErr, (GFLIB_CONTROLLER_PIAW_R_T_F16 *) &currentPIPrms, F16);

requiredSpeedOld = requiredSpeed;

PIOut = speedPIOut;
// if (currentPIOut >= speedPIOut)
// {
// currentPIPrms.f32Acc = ((tFrac32) speedPIOut) << 16;
// currentPIPrms.f16InErrK1 = 0;
// PIOut = speedPIOut;
// driveStatus.bit.CurrentLimiting = 0;
// }
// else
// {
// speedPIPrms.f32Acc = ((tFrac32) currentPIOut) << 16;
// speedPIPrms.f16InErrK1 = 0;
// PIOut = currentPIOut;
// driveStatus.bit.CurrentLimiting = 1;
// }

duty_cycle = MLIB_Mul(PIOut, PWM_MODULO, F16); // duty cycle 0-1 -> 0-PWM_MODULO
UpdateDutycycle();
}


else
{
if (ctrlStates.state == APP_ALIGNMENT || ctrlStates.state == APP_START)
{
switch(ctrlStates.state)
{
case APP_START: currentErr = requiredOpenLoopCurrent - DCBusCurrent; break;
case APP_ALIGNMENT: currentErr = requiredAlignCurrent - DCBusCurrent; break;
default: currentErr = 0; break;
}

PIOut = GFLIB_ControllerPIrAW(currentErr, (GFLIB_CONTROLLER_PIAW_R_T_F16 *) &AlignCurrentPIPrms, F16);

// duty_cycle = MLIB_Mul(PIOut, PWM_MODULO, F16); // duty cycle 0-1 -> 0-PWM_MODULO
// duty_cycle = 200;
duty_cycle = test_duty;
// UpdateDutycycle();
}
UpdateDutycycle();
}
#endif

// Read the user control interface
// ctrlStates.usrControl.btSpeedUp = UP_BUTTON;
// ctrlStates.usrControl.btSpeedDown = DOWN_BUTTON;

// if(ctrlStates.usrControl.btCounter++ > BTN_PERIOD_DIVIDER)
// {
// ctrlStates.usrControl.btCounter = 0;
// if ((ctrlStates.usrControl.btSpeedUp) && (!ctrlStates.usrControl.btSpeedDown) && (ctrlStates.state == APP_STOP))
// {
// speedRamp.f16State = (tFrac16)0;
// requiredSpeed = REQUIRED_RUN_SPEED;
// ctrlStates.usrControl.switchAppOnOff = true;
// }
//
// if ((!ctrlStates.usrControl.btSpeedUp) && (ctrlStates.usrControl.btSpeedDown) && (ctrlStates.state == APP_STOP))
// {
// speedRamp.f16State = (tFrac16)0;
// requiredSpeed = MLIB_Neg_F16(REQUIRED_RUN_SPEED);
// ctrlStates.usrControl.switchAppOnOff = true;
// }
//
// if ((!ctrlStates.usrControl.btSpeedDown) && (!ctrlStates.usrControl.btSpeedUp))
// ctrlStates.usrControl.switchAppOnOff = false;
//
// if ((!ctrlStates.usrControl.btSpeedUp) && (ctrlStates.state == APP_RUN))
// requiredSpeed = MLIB_AddSat_F16(requiredSpeed, SPEED_STEP);
//
// if ((!ctrlStates.usrControl.btSpeedDown) && (ctrlStates.state == APP_RUN))
// requiredSpeed = MLIB_SubSat_F16(requiredSpeed, SPEED_STEP);
// }

// // User switch should be checked only if the HALL sensor is not influencing it
// if(DDRP_DDRP0 == 0) // if the Hall sensor power supply is off
// {
// // User switch should be checked only if not in init state (see state machine table)
// if(ctrlStates.state != APP_INIT)
// ctrlStates.usrControl.btFlipFlop = PTT_PTT1;
// }
// User accessible switch for stopping the application.
// if (ctrlStates.usrControl.btFlipFlop ^ ctrlStates.usrControl.btFlipFlopTemp)
// {
// ctrlStates.usrControl.btFlipFlopTemp = ctrlStates.usrControl.btFlipFlop;
// ctrlStates.usrControl.switchAppOnOff = (ctrlStates.usrControl.btFlipFlop) ? false: true;
// }

// User accessible switch for stopping the application.
if (ctrlStates.usrControl.switchAppOnOff ^ ctrlStates.usrControl.switchAppOnOffState)
{
ctrlStates.usrControl.switchAppOnOffState = ctrlStates.usrControl.switchAppOnOff;
ctrlStates.event = (ctrlStates.usrControl.switchAppOnOff) ? e_run: e_stop;
}

UpdateCurrentLimitingLed();
state_LED[ctrlStates.state]();

TIM0TFLG1 = TIM0TFLG1_C3F_MASK;
return;
}

 

/*****************************************************************************
*
* Function: void UpdateDutycycle(void)
*
* Description: - Update of duty cycle to PMF
* - Update of trigger delays
*
*****************************************************************************/
void UpdateDutycycle(void)
{
tU16 delay1, delay2;

if(duty_cycle == 0) //if zero duty cycle, disable PWM output to prevent active braking
PMFCFG2 |= 0x3f;

PMFVAL0 = duty_cycle;

delay1 = duty_cycle >> 2; // middle of the pulse - DC Bus current
if (delay1 < MIN_ADC_TRIGGER_FIRST)
delay1 = MIN_ADC_TRIGGER_FIRST;
PTUTriggerEventList[0][0][0] = delay1;

delay2 = MLIB_Mul(duty_cycle,BEMF_SENSING_POINT_FRAC,F16); // end of the pulse

if (delay2 < (delay1 + MIN_ADC_TRIGGER_SECOND))
delay2 = delay1 + MIN_ADC_TRIGGER_SECOND;
PTUTriggerEventList[1][0][0] = delay2; // ADC1 - phase voltage
PTUTriggerEventList[0][0][1] = delay2; // ADC0 second sample - DC Bus Voltage

PTUC_PTULDOK = 1;
return;
}

/*****************************************************************************
*
* Function: void TIMchan0_ISR(void)
*
* Description: Timer channel 0 Output Compare Interrupt Service Routine
* - Commutation ISR
*
*****************************************************************************/
INTERRUPT void TIMchan0_ISR(void)
{
EnableInterrupts;

timeCommutation = TIM0TCNT;

#if !HALL_SENSOR
if (driveStatus.bit.Sensorless == 1)
{
if (driveStatus.bit.NewZC == 0)
{ // Zero-cross not found in previous commutation period
timeZC = timeCommutation - (actualPeriodZC >> 1); // Middle between two commutations
GDUPHMUX_GPHMX = BemfPhase[dir][NextCmtSector]; // will be applied at the next PMF Reload
PTUC_PTULDOK = 1;
}
TIM0TC0 = timeCommutation + (actualPeriodZC << 1);
timeZCToff = MLIB_Mul(actualPeriodZC, TIME_TOFF_FRAC,F16);
driveStatus.bit.StallCheckReq = 1;
}
else
#endif
{
TIM0TC0 = timeCommutation + NextCmtPeriod; // alignment + open loop
}

ActualCmtSector = NextCmtSector;

#if !HALL_SENSOR
if (driveStatus.bit.EnableCMT)
{
NextCmtSector++;
if (NextCmtSector > 5)
NextCmtSector = 0;
PMFCFG2 = 0x40 + MaskVal[dir][NextCmtSector]; // will be applied at the next commutation
PMFOUTC_OUTCTL = OutCtl[dir][NextCmtSector]; // will be applied at the next commutation
}
#endif

driveStatus.bit.AfterCMT = 1;
driveStatus.bit.DisableAdc = 1;
driveStatus.bit.NewZC = 0;
driveStatus.bit.AdcSaved = 0;


if (driveStatus.bit.Alignment)
{ // in high speeds applications move this code to control loop timer
if (alignmentTimer > 0)
alignmentTimer--;
}

TIM0TFLG1 = TIM0TFLG1_C0F_MASK;
return;
}


/*****************************************************************************
*
* Function: void TIMch1_ISR(void)
*
* Description: Hall sensor routine. It takes 11us.
*
*****************************************************************************/
INTERRUPT void TIMchan1_ISR(void)
{
#if HALL_SENSOR
if(driveStatus.bit.HallSensor)
{
// Load TIM counter value
timerValue = TIM0TC1;

// Read Hall pattern
hallPattern = 0x07 & (PTIT >> 1);

// Control loop
if (ctrlStates.state == APP_RUN)
{

// Select commutation sector
ActualCmtSector = BLDCPatternBasedOnHall[hallPattern];
// Update PMF only if RUN state is active
if(ctrlStates.state == APP_RUN)
{
PMFCFG2 = 0x40 + MaskVal[dir][ActualCmtSector];
PMFOUTC_OUTCTL = OutCtl[dir][ActualCmtSector];
}
// Select pattern
// Now 6.5 us from interrupt processing start
// TIM ch0 output toggle on compare to force commutation
TIM0TCTL2_OL0 = 1;
TIM0TCTL2_OM0 = 0;
// Force commutation (apply PMF MASK/Control configuration)
TIM0CFORC_FOC0 = 1;
// Disable TIM ch0 output compare action to do not generate
// force commutation (async_event), when TIM counter TCNT reaches value 0
TIM0TCTL2_OL0 = 0;
TIM0TCTL2_OM0 = 0;
}

// Calculate period between two hall edges
timerValueLim = timerValue - timerLastValue;
// Limit the value to do not exceed 16bit value
if (timerValueLim > 10900)
{
timerValueLim = 10900;
driveStatus.bit.StallCheckReq = 1;
}
else
{
driveStatus.bit.StallCheckReq = 0;
}
// Save hall signal period (measured between two following edges)
hallEdgePeriod[hallPattern] = timerValueLim;
// Load timer value
timerLastValue = timerValue;

// Reset motor stall counter
//motorStallCounter = 0;
stallCheckCounter = 0;

// Clear counter
hallEdgePerod1msCounter = 0;
}
// Clear flag
TIM0TFLG1 = TIM0TFLG1_C1F_MASK;
#endif
}

/*****************************************************************************
*
* Function: void PMFreloadA_ISR(void) - Used only for debugging
*
* Description: PMF Reload A Interrupt Service Routine
*
*****************************************************************************/
INTERRUPT void PMFreloadA_ISR(void)
{
volatile char tmp;
tmp = PMFFQCA;
PMFFQCA_PWMRFA = 1; // Clear flag
return;
}

/*****************************************************************************
*
* Function: void PMFfault_ISR(void)
*
* Description: PMF Fault Interrupt Service Routine
*
*****************************************************************************/
INTERRUPT void PMFfault_ISR(void)
{
PMFFIF = PMFFIF_FIF0_MASK; // Clear flag Fault 0, ...
return;
}

/*****************************************************************************
*
* Function: void PMFreloadoverrun_ISR(void)
*
* Description: PMF Reload Overrun Interrupt Service Routine
*
*****************************************************************************/
INTERRUPT void PMFreloadoverrun_ISR(void)
{
PMFROIF = PMFROIF_PMFROIFA_MASK; // Clear flag
return;
}

/*INTERRUPT void SCI1_ISR(void){
if (SCI1SR1_RDRF)
{
volatile uint8_t tmp1;
tmp1 = SCI1SR1;
tmp1 = SCI1DRL;
return;
}
}*/

 

/*****************************************************************************
*
* Function: void PTUTrigger0Done_ISR(void) - Used only for debugging
*
* Description: PTU Trigger0 Done Interrupt Service Routine
*
*****************************************************************************/
INTERRUPT void PTUTrigger0Done_ISR(void)
{
PTUIFL = PTUIFL_TG0DIF_MASK; // Clear flag
return;
}


/*****************************************************************************
*
* Function: void PTUTrigger1Done_ISR(void)
*
* Description: PTU Trigger1 Done Interrupt Service Routine
*
*****************************************************************************/
INTERRUPT void PTUTrigger1Done_ISR(void)
{
timeOldBEMF = timeBEMF;
timeBEMF = TIM0TCNT;

PTUIFL = PTUIFL_TG1DIF_MASK; // Clear flag
return;
}

/*****************************************************************************
*
* Function: void ADC0error_ISR(void)
*
* Description: ADC0 Error Interrupt Service Routine
*
*****************************************************************************/
INTERRUPT void ADC0error_ISR(void)
{
char tmpAdcEIF;

tmpAdcEIF = ADC0EIF;

if (tmpAdcEIF & ADC0EIF_LDOK_EIF_MASK)
{ // Load Ok Error
AdcErrorLDOK++;
ADC0EIF = ADC0EIF_LDOK_EIF_MASK;
}
if (tmpAdcEIF & ADC0EIF_RSTAR_EIF_MASK)
{ // Restart Request Error
AdcErrorRSTAR++;
ADC0EIF = ADC0EIF_RSTAR_EIF_MASK;
}
if (tmpAdcEIF & ADC0EIF_TRIG_EIF_MASK)
{ // Trigger Error => Soft Reset
AdcErrorTRIG++;
ADC0CTL_0_ADC_SR = 1;
}
if (tmpAdcEIF & ADC0EIF_EOL_EIF_MASK)
{ // End Of List Error => Soft Reset
AdcErrorEOL++;
ADC0CTL_0_ADC_SR = 1;
}
if (tmpAdcEIF & ADC0EIF_CMD_EIF_MASK)
{ // Command Value Error => Soft Reset
AdcErrorCMD++;
ADC0CTL_0_ADC_SR = 1;
}
if (tmpAdcEIF & ADC0EIF_IA_EIF_MASK)
{ // Illegal Access Error => Soft Reset
AdcErrorIA++;
ADC0CTL_0_ADC_SR = 1;
}
return;
}

/*****************************************************************************
*
* Function: void ADC0done_ISR(void)
*
* Description: ADC0 Conversion Done Interrupt Service Routine
*
*****************************************************************************
*
* Benchmark:
* 1) No ADC Approximation:
* - looking for zero-cross, not found: 4.6 us
* - zero-cross just found: 7.2 us
* - not looking for zero-cross (already found): 2.4 us
* 2) ADC Approximation:
* - looking for zero-cross, not found: 5.4 us
* - zero-cross just found: 9.8 us
* - not looking for zero-cross (already found): 2.64 us
*
*****************************************************************************/
INTERRUPT void ADC0done_ISR(void)
{
tFrac16 delta = 0;
// RIGHT justified result ADC data
/*
DCBusCurrent = ADC0ResultList[0] - DCBusCurrentOffset;
DCBusVoltageHalf = MLIB_Mul(ADC0ResultList[1] << 1, 27307 ,F16); // DC Bus Voltage * 2 * 10/12
phaseVoltage = ADC1ResultList[0] << 2; // Phase Voltage * 4
*/
// LEFT justified result ADC data
DCBusCurrent = ADC0ResultList[0] - DCBusCurrentOffset;
DCBusVoltage = ADC0ResultList[1]>>1;
DCBusVoltageHalf = MLIB_Mul(ADC0ResultList[1]>>1, 13653 ,F16); // DC Bus Voltage * 5/6 / 2
phaseVoltage = ADC1ResultList[0]>>1; // Phase Voltage

DCBusCurrentFiltered = GDFLIB_FilterMA_F16(DCBusCurrent, &dcCurrentFilterParams);

#if !HALL_SENSOR
bemfVoltage = phaseVoltage - DCBusVoltageHalf;

if (driveStatus.bit.AfterCMT == 1)
{
if ((timeBEMF - timeCommutation) > timeZCToff)
{
driveStatus.bit.AfterCMT = 0;
}
}

if ((driveStatus.bit.AfterCMT == 0) && (driveStatus.bit.NewZC == 0) && (driveStatus.bit.Sensorless == 1))
{
//ZCdetectionAdc[ActualCmtSector]();

/* If the BEMF voltage is falling, invert BEMF voltage value */
if((ActualCmtSector & 0x01) == 0)
{
bemfVoltage = -bemfVoltage;
}

/* Rising BEMF zero-crossing detection */
if(bemfVoltage >= 0)
{
// Raising approximation
delta = bemfVoltage - bemfVoltageOld; // bemfVoltage & delta > 0 for raising BEMF, bemfVoltage & delta < 0 for falling BEMF
if ((driveStatus.bit.AdcSaved == 1) && (delta > bemfVoltage)) { // if delta > bemfVoltage then also delta > 0
timeBEMF -= MLIB_Mul_F16(MLIB_Div(bemfVoltage, delta), timeBEMF - timeOldBEMF);
}
else { // middle of previous ADC sensing events
timeBEMF -= ((timeBEMF - timeOldBEMF) >> 1);
}

lastTimeZC = timeZC;
timeZC = timeBEMF;

periodZC[ActualCmtSector] = timeZC - lastTimeZC;
actualPeriodZC = (actualPeriodZC + periodZC[ActualCmtSector]) >> 1;
NextCmtPeriod = MLIB_Mul_F16(actualPeriodZC, advanceAngle);

TIM0TC0 = timeZC + NextCmtPeriod;
driveStatus.bit.NewZC = 1;
}

bemfVoltageOld = bemfVoltage; // save previous Back-EMF voltage (for ADC samples approximation)
driveStatus.bit.AdcSaved = 1;

if (driveStatus.bit.NewZC)
{
GDUPHMUX_GPHMX = BemfPhase[dir][NextCmtSector]; // will be applied at the next PMF Reload
PTUC_PTULDOK = 1;
// DCBusCurrentZC = DCBusCurrent;
// DCBusCurrentFiltered = (tFrac16)((long) ((long)DCBusCurrentFiltered + (long)DCBusCurrentFiltered + (long)DCBusCurrentFiltered + (long)DCBusCurrentZC) >> 2);
}
}

if (driveStatus.bit.DisableAdc == 1)
{
driveStatus.bit.DisableAdc = 0;
driveStatus.bit.NewZC = 0;
}
#endif

if(faultDetection())
ctrlStates.state = APP_FAULT;

FMSTR_Recorder();
ADC0CONIF = 1; // Clear flag
return;
}

/*****************************************************************************
*
* Function: void ADC1error_ISR(void)
*
* Description: ADC1 Error Interrupt Service Routine
*
*****************************************************************************/
INTERRUPT void ADC1error_ISR(void)
{
char tmpAdcEIF;

tmpAdcEIF = ADC1EIF;

if (tmpAdcEIF & ADC1EIF_LDOK_EIF_MASK)
{ // Load Ok Error
AdcErrorLDOK++;
ADC1EIF = ADC1EIF_LDOK_EIF_MASK;
}
if (tmpAdcEIF & ADC1EIF_RSTAR_EIF_MASK)
{ // Restart Request Error
AdcErrorRSTAR++;
ADC1EIF = ADC1EIF_RSTAR_EIF_MASK;
}
if (tmpAdcEIF & ADC1EIF_TRIG_EIF_MASK)
{ // Trigger Error => Soft Reset
AdcErrorTRIG++;
ADC1CTL_0_ADC_SR = 1;
}
if (tmpAdcEIF & ADC1EIF_EOL_EIF_MASK)
{ // End Of List Error => Soft Reset
AdcErrorEOL++;
ADC1CTL_0_ADC_SR = 1;
}
if (tmpAdcEIF & ADC1EIF_CMD_EIF_MASK)
{ // Command Value Error => Soft Reset
AdcErrorCMD++;
ADC1CTL_0_ADC_SR = 1;
}
if (tmpAdcEIF & ADC1EIF_IA_EIF_MASK)
{ // Illegal Access Error => Soft Reset
AdcErrorIA++;
ADC1CTL_0_ADC_SR = 1;
}
return;
}

/*****************************************************************************
*
* Function: void ADC1done_ISR(void) - Used only for debugging
*
* Description: ADC1 Conversion Done Interrupt Service Routine
*
*****************************************************************************/
INTERRUPT void ADC1done_ISR(void)
{
ADC1CONIF = 1; // Clear flag
return;
}

/*****************************************************************************
*
* Function: void AdcCalibration(void)
*
* Description: Calibration of the DC Bus current offset function
*
*****************************************************************************/
void AdcCalibration(void)
{
int i;
tFrac16 AdcOffset;

NextCmtPeriod = TIMER_1MS; // 1 ms
DCBusCurrentOffset = 0;
driveStatus.bit.AfterCMT = 0;
for (i = 0; i < 1000; i++)
{ // 1 second delay
while (driveStatus.bit.AfterCMT == 0){}

driveStatus.bit.AfterCMT = 0;
}
AdcOffset = DCBusCurrent;

for (i = 0; i < 1000; i++)
{ // 1 second measurement
while (driveStatus.bit.AfterCMT == 0){}

driveStatus.bit.AfterCMT = 0;
AdcOffset = ((long) AdcOffset + AdcOffset + AdcOffset + DCBusCurrent) >> 2;
}
DCBusCurrentOffset = AdcOffset;
return;
}


/*****************************************************************************
*
* Function: void AppInit(void)
*
* Description: BLDC application init. function
*
*****************************************************************************/
void InitializeApp(void)
{
timeZCToff = TIME_TOFF;
advanceAngle = ADVANCE_ANGLE;
requiredSpeed = REQUIRED_RUN_SPEED;
DCBusCurrentLimit = DC_BUS_CURRENT_LIMIT;
ctrlStates.state = APP_INIT;

startCMTcounterPeriod = START_CMT_CNT;
startCMTacceleration = START_CMT_ACCELERATION;

requiredOpenLoopCurrent = ALIGN_CURRENT_SCALED;
requiredAlignCurrent = ALIGN_CURRENT_SCALED;

alignmentTimeValue = ALIGNMENT_TIME;

AlignCurrentPIPrms.f16UpperLimit = ALIGN_PI_UPPER_LIMIT;
AlignCurrentPIPrms.f16LowerLimit = ALIGN_PI_LOWER_LIMIT;
AlignCurrentPIPrms.f16CC1sc = ALIGN_PI_PARAM_CC1;
AlignCurrentPIPrms.f16CC2sc = ALIGN_PI_PARAM_CC2;
AlignCurrentPIPrms.u16NShift = ALIGN_PI_PARAM_SHIFT;

currentPIPrms.f16UpperLimit = RUN_PI_UPPER_LIMIT;
currentPIPrms.f16LowerLimit = RUN_PI_CURRENT_LOWER_LIMIT;
currentPIPrms.f16CC1sc = RUN_PI_CURRENT_PARAM_CC1;
currentPIPrms.f16CC2sc = RUN_PI_CURRENT_PARAM_CC2;
currentPIPrms.u16NShift = RUN_PI_CURRENT_PARAM_SHIFT;

speedPIPrms.f16UpperLimit = RUN_PI_UPPER_LIMIT;
speedPIPrms.f16LowerLimit = RUN_PI_SPEED_LOWER_LIMIT;
speedPIPrms.f16CC1sc = RUN_PI_SPEED_PARAM_CC1;
speedPIPrms.f16CC2sc = RUN_PI_SPEED_PARAM_CC2;
speedPIPrms.u16NShift = RUN_PI_SPEED_PARAM_SHIFT;

speedRamp.f32RampUp = RUN_SPEED_RAMP_UP;
speedRamp.f32RampDown = RUN_SPEED_RAMP_DOWN;
speedRamp.f32State = (tFrac32)0;

dcCurrentFilterParams.u16NSamples = 10;
GDFLIB_FilterMAInit_F16(&dcCurrentFilterParams);

#if HALL_SENSOR
driveStatus.bit.HallSensor = 1;
#else
driveStatus.bit.Sensorless = 1;
#endif

return;
}

/*****************************************************************************
*
* Function: void AppInit(void)
*
* Description: BLDC application init. state
*
*****************************************************************************/
void AppInit(void)
{
duty_cycle = 0;
UpdateDutycycle();

driveStatus.bit.Alignment = 0;
driveStatus.bit.EnableCMT = 0;
driveStatus.bit.CloseLoop = 0;
driveStatus.bit.Sensorless = 0;
driveStatus.bit.DisableAdc = 0;
driveStatus.bit.NewZC = 0;

ctrlStates.usrControl.switchAppOnOff = false;
ctrlStates.usrControl.switchAppOnOffState = false;
ctrlStates.usrControl.switchFaultClear = false;
ctrlStates.usrControl.switchAppReset = false;

ctrlStates.usrControl.ledCounter = 0;
ctrlStates.usrControl.ledFlashing = 125;

actualSpeed = 0;

NextCmtPeriod = TIMER_1MS; // 1 ms

AdcCalibration();

ctrlStates.state = APP_STOP;
return;
}

/*****************************************************************************
*
* Function: void AppAlignment(void)
*
* Description: function
*
*****************************************************************************/
void AppAlignment(void)
{
#if HALL_SENSOR
AppAlignmentToStart();
alignmentTimer = 0;
#else
if (alignmentTimer == 0)
{
AppAlignmentToStart();
}
#endif

return;
}

/*****************************************************************************
*
* Function: void AppStart(void)
*
* Description: function
*
*****************************************************************************/
tU16 NextCmtPeriod_test = 2200;
void AppStart(void)
{
#if HALL_SENSOR
AppStartToRun();
#else
if (driveStatus.bit.AfterCMT == 1)
{
timeZC = TIM0TCNT - (NextCmtPeriod >> 1);

startCMTcounter--;
if (startCMTcounter > 0)
{
driveStatus.bit.AfterCMT = 0;

// NextCmtPeriod = MLIB_Mul_F16(NextCmtPeriod,startCMTacceleration);
NextCmtPeriod = NextCmtPeriod - NextCmtPeriod_test;
}
}

if (startCMTcounter == 0)
AppStartToRun();
#endif

return;
}

/*****************************************************************************
*
* Function: void AppRun(void)
*
* Description: function
*
*****************************************************************************/
void AppRun(void)
{
if (StallError)
{
ctrlStates.state = APP_FAULT;
return;
}
if(ctrlStates.event == e_stop)
AppRunToStop();
return;
}

/*****************************************************************************
*
* Function: void AppRunToStop(void)
*
* Description: Stop function, ready to run
*
*****************************************************************************/
void AppRunToStop(void)
{
driveStatus.bit.Alignment = 0;
driveStatus.bit.EnableCMT = 0;
driveStatus.bit.CloseLoop = 0;
driveStatus.bit.Sensorless = 0;
driveStatus.bit.CloseLoop = 0;

requiredSpeed_Ramp = 0;
speedRamp.f32State = (tFrac32)0;

duty_cycle = 0;
duty_cycle = 0;
UpdateDutycycle();

actualSpeed = 0;

ctrlStates.state = APP_STOP;
return;
}

/*****************************************************************************
*
* Function: void AppStop(void)
*
* Description: Stop function, ready to run
*
*****************************************************************************/
void AppStop(void)
{
driveStatus.bit.CurrentLimiting = 0;

if(ctrlStates.event == e_run)
{
//if (GDUF != 0) GDUF = GDUF; // clear fault flags
if (GDUF == 0)
AppStopToAlignment();
}
speedRamp.f32State = (tFrac32)0;
return;
}


/*****************************************************************************
*
* Function: void AppError(void)
*
* Description: Error function
*
*****************************************************************************/
void AppError(void)
{
driveStatus.bit.Alignment = 0;
driveStatus.bit.EnableCMT = 0;
driveStatus.bit.CloseLoop = 0;
driveStatus.bit.Sensorless = 0;
driveStatus.bit.CloseLoop = 0;

duty_cycle = 0;
speedRamp.f32State = (tFrac32)0;
UpdateDutycycle();
ctrlStates.state = APP_FAULT;
return;
}

/*****************************************************************************
*
* Function: void AppFault(void)
*
* Description: fault state function
*
*****************************************************************************/
void AppFault(void)
{
AppError();

ctrlStates.usrControl.switchAppOnOff = false;

// Clear fault by on board user buttons.
// Simultaneous press clearing faults
// if (!ctrlStates.usrControl.btSpeedUp && !ctrlStates.usrControl.btSpeedDown)
// ctrlStates.usrControl.switchFaultClear = true;

if(ctrlStates.usrControl.switchFaultClear == true)
{
ctrlStates.usrControl.switchFaultClear = false;
permFaults.mcu.R = 0;
permFaults.motor.R = 0;

StallError = 0;

AdcErrorCMD = 0;
AdcErrorEOL = 0;
AdcErrorIA = 0;
AdcErrorLDOK = 0;
AdcErrorRSTAR = 0;
AdcErrorTRIG = 0;

GDUF = 0xFF;
GDUDSE = 0xFF;

PMFFIF = PMFFIF;

PTUIFL = PTUIFL;

ctrlStates.state = APP_INIT;
}
return;
}

/*****************************************************************************
*
* Function: void AppStopToAlignment(void)
*
* Description: function
*
*****************************************************************************/
void AppStopToAlignment(void)
{
driveStatus.bit.Alignment = 1;
driveStatus.bit.EnableCMT = 0;
driveStatus.bit.CloseLoop = 0;
driveStatus.bit.Sensorless = 0;
driveStatus.bit.DisableAdc = 0;
driveStatus.bit.NewZC = 0;

NextCmtPeriod = TIMER_1MS; // 1 ms

TIM0TC0 = TIM0TCNT + NextCmtPeriod;
timeZCToff = TIME_TOFF;
alignmentTimer = alignmentTimeValue;
stallCheckCounter = 0;

/*
AlignCurrentPIPrms.f16UpperLimit = ALIGN_PI_UPPER_LIMIT;
AlignCurrentPIPrms.f16LowerLimit = ALIGN_PI_LOWER_LIMIT;
AlignCurrentPIPrms.f16CC1sc = ALIGN_PI_PARAM_CC1;
AlignCurrentPIPrms.f16CC2sc = ALIGN_PI_PARAM_CC2;
AlignCurrentPIPrms.u16NShift = ALIGN_PI_PARAM_SHIFT;
*/
AlignCurrentPIPrms.f32Acc = 0;
AlignCurrentPIPrms.f16InErrK1 = 0;

duty_cycle = 0;
UpdateDutycycle();

PMFCFG2 = 0x40 + 0x10; // set commutation vector (phase A = PWM, phase B = PWM, phase C is grounded)
PMFOUTC_OUTCTL = 0x30;
TIM0CFORC_FOC0 = 1; // force commutation event (apply PMF MASK/Control configuration)

ctrlStates.state = APP_ALIGNMENT;
return;
}

/*****************************************************************************
*
* Function: void AppAlignmentToStart(void)
*
* Description: function
*
*****************************************************************************/
void AppAlignmentToStart(void)
{
#if HALL_SENSOR

stallCheckCounter = 0;
driveStatus.bit.Alignment = 0;

//Shift initial vector to avoid stall during start-up, then update PMF and force commutation
ActualCmtSector = BLDCStartVectorOnHall[BLDCPatternBasedOnHall[hallPattern]];

// Update PMF only if RUN state is active
PMFCFG2 = 0x40 + MaskVal[dir][ActualCmtSector]; // ActualCmtSector
PMFOUTC_OUTCTL = OutCtl[dir][ActualCmtSector]; // ActualCmtSector
// Select pattern
// Now 6.5 us from interrupt processing start
// TIM ch0 output toggle on compare to force commutation
TIM0TCTL2_OL0 = 1;
TIM0TCTL2_OM0 = 0;
// Force commutation (apply PMF MASK/Control configuration)
TIM0CFORC_FOC0 = 1;
// Disable TIM ch0 output compare action to do not generate
// force commutation (async_event), when TIM counter TCNT reaches value 0
TIM0TCTL2_OL0 = 0;
TIM0TCTL2_OM0 = 0;
#else
NextCmtSector = 3; // starting sector

driveStatus.bit.Alignment = 0;
driveStatus.bit.EnableCMT = 1;
driveStatus.bit.AfterCMT = 0;

NextCmtPeriod = START_FIRST_PERIOD;
startCMTcounter = startCMTcounterPeriod;

TIM0TC0 = TIM0TCNT + NextCmtPeriod;
PMFCFG2 = 0x40 + MaskVal[dir][NextCmtSector];
PMFOUTC_OUTCTL = OutCtl[dir][NextCmtSector];
NextCmtSector++;
TIM0CFORC_FOC0 = 1; // force commutation event (apply first commutation sector)

PMFCFG2 = 0x40 + MaskVal[dir][NextCmtSector];
PMFOUTC_OUTCTL = OutCtl[dir][NextCmtSector]; // save another commutation sector values to the buffered registers

// NextCmtPeriod = MLIB_Mul_F16(NextCmtPeriod,startCMTacceleration);
NextCmtPeriod = NextCmtPeriod - NextCmtPeriod_test;
#endif

ctrlStates.state = APP_START;
return;
}

/*****************************************************************************
*
* Function: void AppStartToRun(void)
*
* Description: function
*
*****************************************************************************/
void AppStartToRun (void)
{
tU16 i = 0;
/*
speedPIPrms.f16UpperLimit = RUN_PI_UPPER_LIMIT;
speedPIPrms.f16LowerLimit = RUN_PI_LOWER_LIMIT;
speedPIPrms.f16CC1sc = RUN_PI_SPEED_PARAM_CC1;
speedPIPrms.f16CC2sc = RUN_PI_SPEED_PARAM_CC2;
speedPIPrms.u16NShift = RUN_PI_SPEED_PARAM_SHIFT;
*/
speedPIPrms.f32Acc = (((tFrac32) duty_cycle <<15)/(tFrac32) PWM_MODULO) << 16;
speedPIPrms.f16InErrK1 = 0;

/*
currentPIPrms.f16UpperLimit = RUN_PI_UPPER_LIMIT;
currentPIPrms.f16LowerLimit = RUN_PI_LOWER_LIMIT;
currentPIPrms.f16CC1sc = RUN_PI_CURRENT_PARAM_CC1;
currentPIPrms.f16CC2sc = RUN_PI_CURRENT_PARAM_CC2;
currentPIPrms.u16NShift = RUN_PI_CURRENT_PARAM_SHIFT;
*/
currentPIPrms.f32Acc = (((tFrac32) duty_cycle <<15)/(tFrac32) PWM_MODULO) << 16;
currentPIPrms.f16InErrK1 = 0;

ctrlStates.state = APP_RUN;
stallCheckCounter = 0;
StallError = 0;

#if HALL_SENSOR
for(i=1;i<7;i++)
{
hallEdgePeriod[i] = NextCmtPeriod;
}
actualPeriodZC = NextCmtPeriod;
#else
for(i=1;i<7;i++)
{
periodZC[i] = NextCmtPeriod;
}
actualPeriodZC = NextCmtPeriod;

driveStatus.bit.Sensorless = 1;
#endif

GDUPHMUX_GPHMX = BemfPhase[dir][ActualCmtSector]; // will be applied at the next PMF Reload
PTUC_PTULDOK = 1;


return;
}

/*****************************************************************************
*
* Function: void StallCheck(void)
*
* Description: Stall check function
*
*****************************************************************************/
void StallCheck(void)
{
tU16 i = 0;
tU16 max = 0, min = 65535;

for(i=1; i<7; i++)
{
if(periodZC[i] > max)
{
max = periodZC[i];
}

if(periodZC[i] < min)
{
min = periodZC[i];
}
}

/* Save min and max commutation periods for tuning purposes */
debugPeriodMin = min;
debugPeriodMax = max;

periodZcAvrg = period6ZC / 6;

if ((max > (periodZcAvrg << 1)) || (min < (periodZcAvrg >> 1)))
{
if (stallCheckCounter < STALLCHECK_MAX_ERRORS)
{
stallCheckCounter++;
} // max > (2 * periodZcAvrg) || min < (0.5 * periodZcAvrg) = period6ZC/8 * 0.5*8/6
}
else
{
if (min < STALLCHECK_MIN_CMT_PERIOD)
{
if (stallCheckCounter < STALLCHECK_MAX_ERRORS)
{
stallCheckCounter++;
}
}
else
{
if (stallCheckCounter > 0)
{
stallCheckCounter--;
}
}
}


if (stallCheckCounter >= STALLCHECK_MAX_ERRORS)
{
StallError = 1;
}
else
{
StallError = 0;
}
}


/*****************************************************************************
*
* Function: void UpdateCurrentLimitingLed(void)
*
* Description: The function displays current limiting condition on LED
*
*****************************************************************************/
void UpdateCurrentLimitingLed(void)
{
static unsigned char Led1Counter;

if (driveStatus.bit.CurrentLimiting == 0)
{
if (Led1Counter > 0)
{
Led1Counter--;
if (Led1Counter == 0) CURRENT_LIMIT_LED = 0;
}
}
else
{
Led1Counter = LED_TIMER_MS;
CURRENT_LIMIT_LED = 1;
}
}

/***************************************************************************//*!
*
* @brief Fault Detection function
*
* @Param none
*
* @return none
*
******************************************************************************/
static tBool faultDetection()
{
tBool faultDetectiontEvent;

faultDetectiontEvent = false;
//-----------------------------
// Actual Faults
//-----------------------------
// TRIP: Phase A over-current detected
if((ctrlStates.state != APP_INIT) && (ctrlStates.state != APP_STOP))
tempfaults.motor.B.OverCurrent = (DCBusCurrentFiltered > MLIB_Mul_F16(I_DC_OVER,FRAC16(0.9))) ? true : false;

// TRIP: DC-bus over-voltage
tempfaults.motor.B.OverDCBusVoltage = (DCBusVoltage > U_DCB_TRIP) ? true : false;

// TRIP: DC-bus under-voltage
tempfaults.motor.B.UnderDCBusVoltage = (DCBusVoltage < MLIB_Div_F16(U_DCB_UNDERVOLTAGE,FRAC16(0.91))) ? true : false;

// Fault: Over temperature
//tempfaults.motor.B.OverHeating = (meas.measured.f16Temp.filt > MLIB_Mul_F16(TEMP_OVER,FRAC16(0.9))) ? true : false;

// Fault: ADC timing errors - to indicate the restart error or the trigger error - not necessarily wrong
//tempfaults.mcu.B.ADC_Error = ((AdcErrorTRIG != 0) || (AdcErrorRSTAR != 0)) ? true : false;

//-----------------------------
// Pending Faults
//-----------------------------

if (ctrlStates.state != APP_FAULT)
{

if((ctrlStates.state != APP_INIT) && (ctrlStates.state != APP_STOP))
// Fault: Phase A over-current detected
permFaults.motor.B.OverCurrent = (DCBusCurrentFiltered > I_DC_OVER) ? true : permFaults.motor.B.OverCurrent;


// Fault: DC-bus over-voltage
permFaults.motor.B.OverDCBusVoltage = (DCBusVoltage > U_DCB_OVERVOLTAGE) ? true : permFaults.motor.B.OverDCBusVoltage;

// Fault: DC-bus under-voltage
permFaults.motor.B.UnderDCBusVoltage = (DCBusVoltage < U_DCB_UNDERVOLTAGE) ? true : permFaults.motor.B.UnderDCBusVoltage;

#if HALL_SENSOR
// Read Hall pattern
hallPattern = 0x07 & (PTIT >> 1);
// Fault: HallPattern error
permFaults.motor.B.HallPatternError = ((hallPattern < 1) || (hallPattern > 6)) ? true : permFaults.motor.B.HallPatternError;
#endif

// Fault: Over temperature
//permFaults.motor.B.OverHeating = (meas.measured.f16Temp.filt > TEMP_OVER) ? true : permFaults.motor.B.OverHeating;

permFaults.mcu.B.ADC_Error = (tU16) ((AdcErrorCMD != 0) || (AdcErrorEOL != 0) || (AdcErrorIA != 0) || (AdcErrorLDOK != 0));
permFaults.mcu.B.GDU_Error = GDUF|GDUDSE;
permFaults.mcu.B.PWM_Error = PMFFIF;
permFaults.mcu.B.PTU_Error = (PTUIFL & 0b11101110);
}

if ((permFaults.motor.R != 0x0))
faultDetectiontEvent = true;
if ((permFaults.mcu.R != 0x0))
faultDetectiontEvent = true;

return faultDetectiontEvent;
}


/* LED application control*/
/***************************************************************************//*!
*
* @brief LED OFF state
*
* @Param
*
* @return none
*
******************************************************************************/
void stateLedOFF()
{
STATUS_LED = 0;
}

/***************************************************************************//*!
*
* @brief LED ON state
*
* @Param
*
* @return none
*
******************************************************************************/
void stateLedON()
{
STATUS_LED = 1;
}

/***************************************************************************//*!
*
* @brief LED FLASHING state
*
* @Param
*
* @return none
*
******************************************************************************/
void stateLedFLASHING_SLOW()
{
ctrlStates.usrControl.ledCounter += 1;

if((ctrlStates.usrControl.ledCounter)>((ctrlStates.usrControl.ledFlashing)<<1))
{
STATUS_LED ^= 1;
ctrlStates.usrControl.ledCounter = 0;
}
}

/***************************************************************************//*!
*
* @brief LED FLASHING state
*
* @Param
*
* @return none
*
******************************************************************************/
void stateLedFLASHING_FASTER()
{
ctrlStates.usrControl.ledCounter += 1;

if((ctrlStates.usrControl.ledCounter)>((ctrlStates.usrControl.ledFlashing>>1)<<1))
{
STATUS_LED ^= 1;
ctrlStates.usrControl.ledCounter = 0;
}
}

/***************************************************************************//*!
*
* @brief LED FLASHING state
*
* @Param
*
* @return none
*
******************************************************************************/
void stateLedFLASHING_FAST()
{
ctrlStates.usrControl.ledCounter += 1;

if((ctrlStates.usrControl.ledCounter)>((ctrlStates.usrControl.ledFlashing)>>1))
{
STATUS_LED ^= 1;
ctrlStates.usrControl.ledCounter = 0;
}
}

0 Kudos

1,359 Views
panda2022
Contributor II

这是我的全部代码,您看看为什么我的CAN初始化配置是在哪里出错了?

0 Kudos

1,391 Views
panda2022
Contributor II

CAN0CTL0_INITRQ   无法写入0值,这是怎么回事?

CAN0CTL0_INITRQ can't write 0 value,this is how it works?
0 Kudos

1,391 Views
panda2022
Contributor II

panda2022_0-1662717135421.png

 

0 Kudos