예제 #1
0
파일: Bits1.c 프로젝트: JinhoAndyPark/AVR
/*
** ===================================================================
**     Method      :  Bits1_SetBit (component BitsIO)
**
**     Description :
**         This method sets (sets to one) the specified bit of the
**         output value.
**         [ It is the same as "PutBit(Bit,TRUE);" ]
**           a) direction = Input  : sets the specified bit to "1";
**                                   this operation will be shown on
**                                   output after the direction has
**                                   been switched to output
**                                   (SetDir(TRUE);)
**           b) direction = Output : directly writes "1" to the
**                                   appropriate pin
**     Parameters  :
**         NAME       - DESCRIPTION
**         Bit        - Number of the bit to set (0 to 1)
**     Returns     : Nothing
** ===================================================================
*/
void Bits1_SetBit(byte Bit)
{
  register byte Mask=Bits1_GetMsk(Bit); /* Temporary variable - bit mask */

  if (Mask) {                          /* Is bit mask correct? */
    Shadow_GPIO_B_DATA |= Mask;        /* Set appropriate bit in shadow variable */
    setRegBits(GPIO_B_DATA,Mask);      /* Set appropriate bit on port */
  }
}
예제 #2
0
파일: Bits1.c 프로젝트: JinhoAndyPark/AVR
/*
** ===================================================================
**     Method      :  Bits1_SetDir (component BitsIO)
**
**     Description :
**         This method sets direction of the bean.
**     Parameters  :
**         NAME       - DESCRIPTION
**         Dir        - Direction to set (FALSE or TRUE)
**                      FALSE = Input, TRUE = Output
**     Returns     : Nothing
** ===================================================================
*/
void Bits1_SetDir(bool Dir)
{
  if (Dir) {                           /* Is given direction output? */
    setReg(GPIO_B_DATA,((getReg(GPIO_B_DATA)) & ~Bits1_PIN_MASK)|(Shadow_GPIO_B_DATA & Bits1_PIN_MASK)); /* Restore correct value of output from shadow variable */
    setRegBits(GPIO_B_DDIR,Bits1_PIN_MASK); /* Set direction to output */
  }
  else {                               /* Is direction input? */
    clrRegBits(GPIO_B_DDIR,Bits1_PIN_MASK); /* Set direction to input */
  }
}
예제 #3
0
/*
** ===================================================================
**     Method      :  LED_SetDir (component BitIO)
**
**     Description :
**         This method sets direction of the bean.
**     Parameters  :
**         NAME       - DESCRIPTION
**         Dir        - Direction to set (FALSE or TRUE)
**                      FALSE = Input, TRUE = Output
**     Returns     : Nothing
** ===================================================================
*/
void LED_SetDir(bool Dir)
{
  if (Dir) {                           /* Is given direction output? */
    setReg(GPIO_A_DR,((getReg(GPIO_A_DR)) & ~LED_PIN_MASK) | (Shadow_GPIO_A_DR & LED_PIN_MASK)); /* Restore correct value of output from shadow variable */
    setRegBits(GPIO_A_DDR,LED_PIN_MASK); /* Set direction to output */
  }
  else {                               /* Is given direction input? */
    clrRegBits(GPIO_A_DDR,LED_PIN_MASK); /* Set direction to input */
  }
}
예제 #4
0
/*
** ===================================================================
**     Method      :  LED_PutVal (component BitIO)
**
**     Description :
**         This method writes the new output value.
**           a) direction = Input  : sets the new output value;
**                                   this operation will be shown on
**                                   output after the direction has
**                                   been switched to output
**                                   (SetDir(TRUE);)
**           b) direction = Output : directly writes the value to the
**                                   appropriate pin
**     Parameters  :
**         NAME       - DESCRIPTION
**         Val             - Output value. Possible values:
**                           FALSE - logical "0" (Low level)
**                           TRUE - logical "1" (High level)
**     Returns     : Nothing
** ===================================================================
*/
void LED_PutVal(bool Val)
{
  if (Val) {                           /* Is it one to be written? */
    Shadow_GPIO_A_DR |= LED_PIN_MASK;  /* Set bit in shadow variable */
    setRegBits(GPIO_A_DR,LED_PIN_MASK); /* Set bit on port */
  }
  else {                               /* Is it zero to be written? */
    Shadow_GPIO_A_DR &= ~LED_PIN_MASK; /* Clear bit in shadow variable */
    clrRegBits(GPIO_A_DR,LED_PIN_MASK); /* Clear bit on port */
  }
}
예제 #5
0
/**
 * sets the clock prescaler.
 * @param presc is the prescaler value in range 0-3 that mean divisors 1 to 8.
 * @return ERR_OK if successful.
 */
byte PWMC1_setPrescaler(byte presc)
{
	if (presc < 4) 
	{
		clrRegBits (PWMB_PMCTL, 0x00c0);
		setRegBits (PWMB_PMCTL, (presc << 6));
		///setRegBitGroup(PWMB_PMCTL, PRSC, presc);
		return ERR_OK;
	}
	else
		return ERR_RANGE;
}
예제 #6
0
/**
 * initializes the timers C0(PHA), C1(PHB), D2(INDEX) for quadrature decoding.
 */
void QD3_init (void)
{
  /* TMRD0_CTRL: CM=0,PCS=0,SCS=1,ONCE=0,LENGTH=0,DIR=0,Co_INIT=0,OM=0 */
  setReg(TMRD0_CTRL,128);              /* Set up mode */
  /* TMRD0_SCR: TCF=0,TCFIE=0,TOF=0,TOFIE=0,IEF=0,IEFIE=0,IPS=0,INPUT=0,Capture_Mode=0,MSTR=0,EEOF=0,VAL=0,FORCE=0,OPS=0,OEN=0 */
  setReg(TMRD0_SCR,0);
  setReg(TMRD0_CNTR,32000);                /* Reset counter register */
  setReg(TMRD0_LOAD,0);            /* Reset load register */
  setReg(TMRD0_CMP1,65535);            /* Set up compare 1 register */
  setReg(TMRD0_CMP2,0);                /* Set up compare 2 register */
  setRegBits(TMRD0_CTRL,0x8000);     /* Run counter */ 	
}
예제 #7
0
/*
** ===================================================================
**     Method      :  HWEnDi (component ADC)
**
**     Description :
**         Enables or disables the peripheral(s) associated with the 
**         component. The method is called automatically as a part of 
**         Enable, Disable and Init methods and several internal methods.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void HWEnDi(void)
{
  if (AD1_ModeFlg) {                   /* Launch measurement? */
    OutFlg = FALSE;                    /* Measured values are available */
    setRegBits(ADC_ADSTAT,2048);       /* Clear flag */
    clrRegBit(ADC_ADCR1,STOP0);        /* Normal operation mode */
    setRegBit(ADC_ADCR1,START0);       /* Launching of conversion */
  }
  else {
    setRegBit(ADC_ADCR1,STOP0);        /* Stop command issued */
  }
}
void init_faults(bool internal_fault_enable,  bool external_fault_enable, bool interrupts_enable)
{

	#warning //so far we are not using the DRV1_2_3_4FAULT
	  
	
	setReg (PWMA_PMFCTL, 	0); 
	setReg (PWMA_PMDISMAP1, 0);
	setReg (PWMA_PMDISMAP2, 0);  
	setReg (PWMB_PMFCTL, 	0); 
	setReg (PWMB_PMDISMAP1, 0);
	setReg (PWMB_PMDISMAP2, 0);  
	if (internal_fault_enable==true)
	{
		// manual fault reset
		// FAULT0    signal disables PWMx channels 0123
		// FAULT1    signal disables PWMx channels 0123		 
		setRegBits (PWMA_PMDISMAP1, 0x1111);//setRegBits (PWMA_PMDISMAP1, 0b0001000100010001);		
		setRegBits (PWMA_PMDISMAP2, 0x00);   
		setRegBits (PWMB_PMDISMAP1, 0x1111);
		setRegBits (PWMB_PMDISMAP2, 0x00);  
		if (interrupts_enable==true)
		{
			setRegBits (PWMA_PMFCTL,PWMA_PMFCTL_FIE0_MASK |
									PWMA_PMFCTL_FIE3_MASK);
			setRegBits (PWMB_PMFCTL,PWMB_PMFCTL_FIE0_MASK |					
									PWMB_PMFCTL_FIE3_MASK);
		}
	}	
	
	if (external_fault_enable==true)
	{
		setRegBits (PWMA_PMDISMAP1, 0x8888);
		setRegBits (PWMA_PMDISMAP2, 0);
		setRegBits (PWMB_PMDISMAP1, 0x8888);
		setRegBits (PWMB_PMDISMAP2, 0); 
	}
		
}
예제 #9
0
파일: Resolver.c 프로젝트: RiverLiang/test
/*
** ===================================================================
**     Method      :  HWEnDi (component SynchroMaster)
**
**     Description :
**         Enables or disables the peripheral(s) associated with the bean.
**         The method is called automatically as a part of the Enable and 
**         Disable methods and several internal methods.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void HWEnDi(void)
{
  if (EnUser) {                        /* Enable device? */
    setRegBit(QSPI0_SCTRL,SPE);        /* Enable device */
    setRegBits(GPIO_C_PEREN,0x0200);   /* Switch pin to peripheral */
    if (SerFlag & FULL_TX) {           /* Is any char in transmit buffer? */
      setReg(QSPI0_DXMIT,BufferWrite); /* Store char to transmitter register */
      SerFlag &= ~FULL_TX;             /* Zeroize FULL_TX flag */
    }
  }
  else {
    clrRegBits(GPIO_C_PEREN,0x0200);   /* Switch pin to GPIO */
    clrRegBit(QSPI0_SCTRL,SPE);        /* Disable device */
  }
}
예제 #10
0
파일: Bits1.c 프로젝트: JinhoAndyPark/AVR
/*
** ===================================================================
**     Method      :  Bits1_PutBit (component BitsIO)
**
**     Description :
**         This method writes the new value to the specified bit
**         of the output value.
**           a) direction = Input  : sets the value of the specified
**                                   bit; this operation will be
**                                   shown on output after the
**                                   direction has been switched to
**                                   output (SetDir(TRUE);)
**           b) direction = Output : directly writes the value of the
**                                   bit to the appropriate pin
**     Parameters  :
**         NAME       - DESCRIPTION
**         Bit        - Number of the bit (0 to 1)
**         Val        - New value of the bit (FALSE or TRUE)
**                      FALSE = "0" or "Low", TRUE = "1" or "High"
**     Returns     : Nothing
** ===================================================================
*/
void Bits1_PutBit(byte Bit, bool Val)
{
  register byte Mask=Bits1_GetMsk(Bit); /* Temporary variable - bit mask */

  if (Mask) {                          /* Is bit mask correct? */
    if (Val) {                         /* Is it one to be written? */
      Shadow_GPIO_B_DATA |= Mask;      /* Set appropriate bit in shadow variable */
      setRegBits(GPIO_B_DATA,Mask);    /* Set appropriate bit on port */
    }
    else {                             /* Is it zero to be written? */
      Shadow_GPIO_B_DATA &= ~Mask;     /* Clear appropriate bit in shadow variable */
      clrRegBits(GPIO_B_DATA,Mask);    /* Clear appropriate bit on port */
    }
  }
}
예제 #11
0
/**
 * enables triggered sequential mode synchronous with the
 * PWM generation signal.
 *
 **************************************************************************************/
byte AD_enableIntTriggerA(void)
{
	if (ad_ModeFlgA != IDLE)             /* Is the device in running mode? */
		return ERR_BUSY;
		
	/// starts sampling in triggered sequential mode
	/// synchro with PWM generation.
	setRegBits (ADCA_ADCR1, 0x04);
//	clrRegBits (ADCA_ADCR1, 0x03);
	
	ad_ModeFlgA = MEASURE;               /* Set state of device to the measure mode */
	
	HWEnDiA();
	return ERR_OK;
}
예제 #12
0
/**
 * This method reads a byte from the SPI bus
 * @param Chr is the read byte
 * @return ERR_OK always
 ***************************************************************************/
byte SPI1_RecvChar(byte *Chr)
{
	int i=0;
	byte ToRead=0;  
	*Chr=0;
    //SCLK   
 	setRegBits(GPIO_E_DR,0x10);
 	wait(4); 
	for(i=7;i>=0;i--)
	{	
	  //SCLK   
 	  clrRegBits(GPIO_E_DR,0x10); 
 	  wait(4);
 	  ToRead= getRegBits(GPIO_E_DR,0x40);
	  wait(1);
	  *Chr |=(ToRead & 1)<<i;
	  //SCLK   
 	  setRegBits(GPIO_E_DR,0x10);
 	  wait(4);  
	}
	wait(4); 
	//SCLK   
 	setRegBits(GPIO_E_DR,0x10);
}
예제 #13
0
/**
 * gets the encoder position value as a 32 bit integer.
 * @param Position is the pointer to the variable holding the value.
 * @return ERR_OK always.
 */
byte QD3_getPosition (dword *Position)
{ 
	dword TimerValue=getReg(TMRD0_CNTR);
	if (TimerValue>=32000)
	{
		qd3_position=qd3_position+ (TimerValue-32000); 	
	}
	else
	{
		qd3_position =qd3_position-(32000 - TimerValue);
	}
	*Position=qd3_position;
	setReg(TMRD0_CNTR,32000);
	setRegBits(TMRD0_CTRL,0x8000);     /* Run counter */
	return ERR_OK;
}
/**
 * initializes the counter/timer. the timer is initialized w/ 1ms period.
 */
void TD0_init (void)
{
	/* TMRD0_CTRL: CM=0,PCS=0,SCS=0,ONCE=0,LENGTH=1,DIR=0,Co_INIT=0,OM=0 */
	setReg (TMRD0_CTRL, 0x20);           /* Stop all functions of the timer */

	/* TMRD0_SCR: TCF=0,TCFIE=1,TOF=0,TOFIE=0,IEF=0,IEFIE=0,IPS=0,INPUT=0,Capture_Mode=0,MSTR=0,EEOF=0,VAL=0,FORCE=0,OPS=0,OEN=0 */
	setReg (TMRD0_SCR, 0x4000);
	setReg (TMRD0_LOAD, 0);                /* Reset load register */
	setReg (TMRD0_CMP1, 39999);            /* Store appropriate value to the compare register according to the selected high speed CPU mode */

	clrRegBits (TMRD0_CTRL, 0x1e00);
	setRegBits (TMRD0_CTRL, 0x08 << 9);    /* Set prescaler register according to the selected high speed CPU mode */
	setReg 	   (TMRD0_CNTR, 0); 		   /* Reset counter */
		
	clrRegBits (TMRD0_CTRL, 0xe000);
	TD0_Enable();						   /* counter on! */
}
예제 #15
0
/**
 * initializes the PWM module w/ 30KHz indipendent mode.
 *
 **************************************************************************************/
void PWM_B_init(void)
{
	/* PWMB_PMCTL: LDFQ=0,HALF=0,IPOL2=0,IPOL1=0,IPOL0=0,PRSC=0,PWMRIE=0,PWMF=0,ISENS=0,LDOK=0,PWMEN=0 */
	setReg (PWMB_PMCTL, 0);
	            
	/* PWMB_PMOUT: PAD_EN=0,??=0,OUTCTL=111111,??=0,??=0,OUT=0 */
	setReg (PWMB_PMOUT, 0x3F00);

	/* PWMB_PMCCR: ENHA=0,??=0,MSK=0,??=0,??=0,VLMODE=0,??=0,SWP45=0,SWP23=0,SWP01=0 */
	setReg (PWMB_PMCCR, 0);
         
	/* PWMB_PMCFG: ??=0,??=0,??=0,EDG=0,??=0,TOPNEG45=0,TOPNEG23=0,TOPNEG01=0,??=0,BOTNEG45=0,BOTNEG23=0,BOTNEG01=0,INDEP45=1,INDEP23=1,INDEP01=1,WP=0 */
	setReg (PWMB_PMCFG, 0x100E);           

	/* PWMB_PMDEADTM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,PWMDT=0 */
	setReg (PWMB_PMDEADTM, 0);          

	/* PWMB_PWMVAL0: PWMVAL=0 */
	setReg (PWMB_PWMVAL0, 0x0);            

	/* PWMB_PWMVAL1: PWMVAL=0 */
	setReg (PWMB_PWMVAL1, 0x0);         

	/* PWMB_PWMVAL2: PWMVAL=0 */
	setReg (PWMB_PWMVAL2, 0);            

	/* PWMB_PWMVAL3: PWMVAL=0 */
	setReg (PWMB_PWMVAL3, 0x0);         

	/* PWMB_PWMVAL4: PWMVAL=0 */
	setReg (PWMB_PWMVAL4, 0);            

	/* PWMB_PWMVAL5: PWMVAL=0 */
	setReg (PWMB_PWMVAL5, 0x0);         

	/* PWMB_PWMCM: ??=0,PWMCM=1333 i.e. 30KHz*/
	setReg (PWMB_PWMCM, 0x535);           

	// PWMB_PMCTL: LDQF=2, LDOK=1,PWMEN=1 
	setRegBits (PWMB_PMCTL, 0x2003);      //the load of the PWM duty is setted every 3 cycle (10KHz)
	
	/* write protect on */
	//setRegBits (PWMB_PMCFG, PWMB_PMCFG_WP_MASK);   	
}
예제 #16
0
/***********************************************************************
	This is the main controller loop.
	sequences of operations:
		- reads from CAN bus or serial port 1.
		- reads encoders (or ADC).
		- computes the control value (a PID in this version).
		- checks limits and other errors.
		- sets PWM
		- does extra functions (e.g. communicate with neighboring cards).
 ***********************************************************************/
void main(void)
{

	Int32 PWMoutput [JN];
	Int32 PWMoutput_old [JN];
	byte i=0;
	byte wi=0;
	byte k=0;
	UInt16 *value=0;
	Int32 t1val=0;
	Int32 PID_R= 2;
	Int32 kpp=1;
	Int16 current_turn=0;
	Int16 print_number=0;
	Int16 real_pos=0;
	byte first_step=0;

#if (VERSION == 0x0351)
	#define winSizeMax 32
	#define initialWindowSize 4
#else
	#define winSizeMax 32
	#define initialWindowSize 30
#endif

	byte divJntPos[JN]=INIT_ARRAY(initialWindowSize-1);
	byte divJntVel[JN]=INIT_ARRAY(initialWindowSize-1);
	byte divMotPos[JN]=INIT_ARRAY(initialWindowSize-1);
	byte divMotVel[JN]=INIT_ARRAY(initialWindowSize-1);
	byte headJntPos[JN]=INIT_ARRAY(0);  //current joint pos
	byte tailJntPos[JN]=INIT_ARRAY(0); 
	byte headJntVel[JN]=INIT_ARRAY(0);  //current joint vel
	byte tailJntVel[JN]=INIT_ARRAY(0); 
	byte headMotPos[JN]=INIT_ARRAY(0);  //current motor pos
	byte tailMotPos[JN]=INIT_ARRAY(0); 
	byte headMotVel[JN]=INIT_ARRAY(0);  //current motor vel
	byte tailMotVel[JN]=INIT_ARRAY(0); 
	Int32 jntPosWindow[winSizeMax][JN]; //max window size = winSizeMax
	Int32 jntVelWindow[winSizeMax][JN]; //max window size = winSizeMax
	Int32 motPosWindow[winSizeMax][JN]; //max window size = winSizeMax
	Int32 motVelWindow[winSizeMax][JN]; //max window size = winSizeMax
	Int16 _safeband[JN];	//it is a value for reducing the JOINT limit of 2*_safeband [tick encoder]
#ifdef TEMPERATURE_SENSOR
	byte   TempSensCount1 = 0;
	UInt32 TempSensCount2 = 0;
	byte   temp_sens_status=0;
	overtemp[0]=0;
	overtemp[1]=0;
	errortemp[0]=0;
	errortemp[1]=0;

#endif
	
	/* gets the address of flash memory from the linker */
	_flash_addr = get_flash_addr();
		
	/* enable interrupts */
	setReg(SYS_CNTL, 0);
	
	// IPL channels from 0 to 6 enabled
	// external interrupts IRQA and IRQB disabled
	setRegBits(IPR, 0xFE00); 

	// enable FAULT
	__ENIGROUP (61, 3); 
	#if (VERSION == 0x0254)
	#else
	__ENIGROUP (60, 3);
	#endif	
	// enable SCI
	__ENIGROUP (52, 4);
	__ENIGROUP (53, 4);
	__ENIGROUP (50, 4);
	__ENIGROUP (51, 4);
	
    // enable data flash
	__ENIGROUP (13, 4);
	
	// enable CAN	
	__ENIGROUP (14, 6);
	__ENIGROUP (15, 6);
	__ENIGROUP (16, 6);
	__ENIGROUP (17, 6);
	
	// enable ADCA/ADCB
	__ENIGROUP (55, 6);
	__ENIGROUP (54, 6);
	
	//enable PWM reload 
	__ENIGROUP (59, 7); // PMWA
	
	#if (VERSION == 0x0254)
	#else	
	__ENIGROUP (58, 7); // PWMB
	#endif
	// enable timers
	// TIMER_A
	__ENIGROUP (45, 7); //Timer for the encoder commutation if used
    __ENIGROUP (44, 7); //
	__ENIGROUP (43, 7); //
	__ENIGROUP (42, 4); //TI1 1ms delay main loop
	// TIMER_B

	__ENIGROUP (41, 7); //
	__ENIGROUP (40, 7); //
	__ENIGROUP (39, 7); //
	__ENIGROUP (38, 7);

	// TIMER_C
	__ENIGROUP (37, 1); 
	__ENIGROUP (36, 1);
	__ENIGROUP (35, 1);
	__ENIGROUP (34, 1);
	// TIMER_D
	__ENIGROUP (33, 7); //1ms delay duty cycle
	__ENIGROUP (32, 1);
	__ENIGROUP (31, 1);
	__ENIGROUP (30, 1);

	__EI();
	
	flash_interface_init  (JN);			
	readFromFlash (_flash_addr);  
	if (_version==_flash_version)
	{
		
	}
	else
	{
		writeToFlash(_flash_addr);
	}
	__DI();
	
	#warning "debug"//   ;
	
	__EI();

	init_leds  			  ();
	
	#if (VERSION == 0x0254)
	
	Init_Brushless_Comm	  (1,HALL); 
  	
  	#else 

	Init_Brushless_Comm	  (JN,HALL); 
  	
  	#endif
	can_interface_init    (JN);	 
    init_strain ();


    init_position_abs_ssi ();
#if VERSION ==0x0257 
    init_relative_position_abs_ssi();
#endif 
 
    init_faults           (true,true,true);	 
    
    init_position_encoder ();


	TI1_init 			  ();

//variable init	
	mainLoopOVF=0;
	_count=0;
	
	for(i=0;i<JN;i++)
	{
	_received_pid[i].rec_pid=0;
	}
	
	BUS_OFF=false;
 	#warning "debug"//   ;
	
	//__EI();

	  
//	print_version ();
	
	/* initialization */
	for (i=0; i<JN; i++) _calibrated[i] = false;
	
	/* reset trajectory generation */
	for (i=0; i<JN; i++) abort_trajectory (i, 0);
	
	
	///////////////////////////////////////
	// reset of the ABS_SSI
	// this is needed because the AS5045 gives the first value wrong !!!
    for (i=0; i<JN; i++)	_position[i]=(Int32) Filter_Bit(get_position_abs_ssi(i));
    for (i=0; i<JN; i++)    _max_real_position[i]=Filter_Bit(4095);
 	
	//////////////////////////////////////
	
	/* initialize speed and acceleration to zero (useful later on) */
	for (i=0; i<JN; i++) _position_old[i] = 0;
	for (i=0; i<JN; i++) _speed[i] = 0;
	for (i=0; i<JN; i++) _accel[i] = 0;
	for (i=0; i<JN; i++) _safeband[i] =5; //5 ticks => 1 grado di AEA.
	for (i=0; i<JN; i++) PWMoutput [i] = PWMoutput_old[i] = 0;
	
	/* reset the recursive windows for storage of position and velocity data */
	/* (for velocity and position estimates) */
	for(i=0;i<JN;i++)
	{
		for(wi=0;wi<winSizeMax;wi++)
		{
			jntPosWindow[wi][i]=_position[i];	
			jntVelWindow[wi][i]=0;
			motPosWindow[wi][i]=0;	
			motVelWindow[wi][i]=0;
		}
	}
	
	//set_relative_position_abs_ssi(1,get_absolute_real_position_abs_ssi(1));
	/* main control loop */
	for(_counter = 0;; _counter ++) 
	{
		if (_counter >= CAN_SYNCHRO_STEPS) _counter = 0;
		led3_on
		while (_wait);
		_count=0;
		led3_off
		
// BUS_OFF check
		if (getCanBusOffstatus() )
		{
			#ifdef DEBUG_CAN_MSG
				can_printf("DISABLE BUS OFF");
			#endif	
			for (i=0; i<JN; i++) put_motor_in_fault(i);
			led1_off
		}
		else
			led1_on

// READING CAN MESSAGES
		can_interface();

		for (i=0; i<JN; i++)
		if (_pad_enabled[i]==false && _control_mode[i]!=MODE_HW_FAULT) _control_mode[i]=MODE_IDLE;		
	
	
	    //Position calculation
	    // This is used to have a shift of the zero-cross out of the 
	    // joint workspace
	    //
	    // max_real_position is the limit of the joint starting from 
	    // 4095 and going to decrease this number without zero-cross
	    // untill the joint limit is reached
#if    VERSION == 0x0257 
		_position_old[0]=_position[0]; 
		if(get_error_abs_ssi(0)==ERR_OK)
			_position[0]=Filter_Bit (get_position_abs_ssi(0));
    	_position_old[1]=_position[1];
		if(get_error_abs_ssi(1)==ERR_OK) 
			_position[1]=Filter_Bit (get_position_abs_ssi(1));		 
#else
	 	for (i=0; i<JN; i++) 
		{
		_position_old[i]=_position[i];
		if(get_error_abs_ssi(i)==ERR_OK)
		_position[i]=Filter_Bit (get_position_abs_ssi(i));
		
		}
#endif 

		// get_commutations() is used to read the incremental encoder of the motors.
		// the variable _motor_position is then used to estimate the rotor speed and
		// compensate the back-EMF of the motor.
		for (i=0; i<JN; i++) _motor_position[i]=get_position_encoder(i);//get_commutations(i);


///////////////////////////////////////////DEBUG////////////
#if (VERSION !=0x0254)
	    for (i=0; i<JN; i++) 
		{		
		   if (get_error_abs_ssi(i)==ERR_ABS_SSI)
		   {
				put_motor_in_fault(i);	
				#ifdef DEBUG_CAN_MSG
		    	can_printf("ABS error %d",i);	
				#endif
		   }				
		}  
#endif
	
#if (VERSION ==0x0254)
		   if (get_error_abs_ssi(0)==ERR_ABS_SSI)
		   {
				put_motor_in_fault(0);
				#ifdef DEBUG_CAN_MSG
		    	can_printf("ABS error %d",0);	
				#endif
		   }	
					 
#endif	


 //DO NOTHING


		// decoupling the position	 	
		decouple_positions();
		

				/* velocity and acceleration estimators */
		{	
			for (i=0; i<JN; i++)
			{	
				//joint velocity estimator
				tailJntPos[i]=headJntPos[i]+(winSizeMax-divJntPos[i]); if(tailJntPos[i]>=winSizeMax) tailJntPos[i]=tailJntPos[i]%winSizeMax;			
				_speed_old[i] = _speed[i];
				jntPosWindow[headJntPos[i]][i]=_position[i];
				_speed[i] = (Int32) (((jntPosWindow[headJntPos[i]][i] - jntPosWindow[tailJntPos[i]][i] ))<<_jntVel_est_shift[i]);
			//	_speed[i] <<= _jntVel_est_shift[i];
				_speed[i] = (Int32)(_speed[i]) / divJntPos[i];
				headJntPos[i]=headJntPos[i]+1; if(headJntPos[i]>=winSizeMax) headJntPos[i]=0;
/*
				//joint acceleration estimator
				tailJntVel[i]=headJntVel[i]+(winSizeMax-divJntVel[i]); if(tailJntVel[i]>=winSizeMax) tailJntVel[i]=tailJntVel[i]%winSizeMax;			
				_accel_old[i] = _accel[i];
				jntVelWindow[headJntVel[i]][i]=_speed[i];
				_accel[i] = ((jntVelWindow[headJntVel[i]][i] - jntVelWindow[tailJntVel[i]][i] ));
				_accel[i] << _jntAcc_est_shift[i];
				_accel[i] = (Int32)(_accel[i]) / divJntVel[i];
				headJntVel[i]=headJntVel[i]+1; if(headJntVel[i]>=winSizeMax) headJntVel[i]=0;
*/				
				//motor velocity estimator
				tailMotPos[i]=headMotPos[i]+(winSizeMax-divMotPos[i]); if(tailMotPos[i]>=winSizeMax) tailMotPos[i]=tailMotPos[i]%winSizeMax;			
				_motor_speed_old[i] = _motor_speed[i];
				motPosWindow[headMotPos[i]][i]=_motor_position[i];
				_motor_speed[i] = ((motPosWindow[headMotPos[i]][i] - motPosWindow[tailMotPos[i]][i] ));
				_motor_speed[i] <<= _motVel_est_shift[i];
				_motor_speed[i] = (_motor_speed[i]) / divMotPos[i];
				headMotPos[i]=headMotPos[i]+1; if(headMotPos[i]>=winSizeMax) headMotPos[i]=0;				
			}
		}
		


					
		/* in position? */
#if (VERSION != 0x0254)
		for (i=0; i<JN; i++) _in_position[i] = check_in_position(i); 
#else
		_in_position[0] = check_in_position(0);
#endif
				
		/* in reference configuration for calibration? */
		//for (i=0; i<JN; i++) check_in_position_calib(i); 

	
//******************************************* POSITION LIMIT CHECK ***************************/
		for (i=0; i<JN; i++)  check_range(i, _safeband[i], PWMoutput);

//******************************************* COMPUTES CONTROLS *****************************/

		//FT sensor watchdog update 
		for (i=0; i<STRAIN_MAX; i++) 
			if (_strain_wtd[i]>0) _strain_wtd[i]--;
			
		for (i=0; i<JN; i++) 
		{
			//computing the PWM value (PID)
			PWMoutput[i] = compute_pwm(i);

			// PWM filtering in torque control if there is no bemf compensation
			#if (VERSION != 0x0351)
			if (_control_mode[i] == MODE_TORQUE ||
			 	_control_mode[i] == MODE_IMPEDANCE_POS ||
			 	_control_mode[i] == MODE_IMPEDANCE_VEL)
				{
					if (_useFilter[i] == 3) PWMoutput[i] = lpf_ord1_3hz (PWMoutput[i], i);
				}	
			// saving the PWM value before the decoupling					
			_bfc_PWMoutput[i] = PWMoutput_old[i] = PWMoutput[i];

			// applying the saturation to the PWM
			if      (_bfc_PWMoutput[i] < -MAX_DUTY) _bfc_PWMoutput[i]=-MAX_DUTY;
			else if (_bfc_PWMoutput[i] > MAX_DUTY)  _bfc_PWMoutput[i]= MAX_DUTY;
			#endif //(VERSION != 0x0351)			
		}

        //decouple PWM	
		decouple_dutycycle(PWMoutput);
		
//******************************************* SATURATES CONTROLS ***************************/                
		/* back emf compensation + controls saturation (if necessary) */
		for (i=0; i<JN; i++)
		{
			if (_control_mode[i] == MODE_TORQUE ||
				_control_mode[i] == MODE_IMPEDANCE_POS ||
				_control_mode[i] == MODE_IMPEDANCE_VEL)
			{
				#if (VERSION != 0x0351)
				// Back emf compensation			
			
				//PWMoutput[i]+=compensate_bemf(i, _comm_speed[i]); //use the motor speed
				PWMoutput[i]+=compensate_bemf(i, _speed[i]); //use the joint speed
				
				//add the coulomb friction compensation term
				if (_kstp_torque[i] != 0 ||
				    _kstn_torque[i] != 0)
				//PWMoutput[i]+=compensate_friction(i, _comm_speed[i]); //use the motor speed
				PWMoutput[i]+=compensate_friction(i, _speed[i]); //use the joint speed
				
				// Protection for joints out of the admissible range during force control
				check_range_torque(i, _safeband[i], PWMoutput);
				// PWM saturation
				ENFORCE_LIMITS	(i,PWMoutput[i], _pid_limit_torque[i] );
				#else  //(VERSION != 0x0351)
				ENFORCE_LIMITS	(i,PWMoutput[i], _pid_limit[i] );
				#endif //(VERSION != 0x0351)
			}
			else
			{
				ENFORCE_LIMITS	(i,PWMoutput[i], _pid_limit[i] );
			}			
			if      (_pid[i] < -MAX_DUTY) _pid[i]=-MAX_DUTY;
			else if (_pid[i] > MAX_DUTY)  _pid[i]= MAX_DUTY;
		}
				
		/* generate PWM */		
		for (i=0; i<JN; i++)
		{
			if (!mode_is_idle(i)) {PWM_generate(i,_pid[i]);}			
		}
	
		/* Check Current done in T1 */

		/* do extra functions, communicate, etc. */
		//send broadcast data	
		can_send_broadcast();

		//send additional debug information
		//can_send_broadcast_debug(1,1);
	 
/***********************************************************************
// Check Current is made here
/***********************************************************************/

#if (VERSION != 0x0254)
		for (i=0; i<JN; i++)
#else
		for (i=0; i<1; i++)
#endif  
		{
			if ((get_current(i)>=25000) || (get_current(i)<=-25000))
			{
				put_motor_in_fault(i);	
				highcurrent[i]=true;
				#ifdef DEBUG_CAN_MSG
				can_printf("j%d curr %f",i,get_current(i));
				#endif
			}
			check_current(i, (_pid[i] > 0));		
			compute_i2t(i);
			if (_filt_current[i] > MAX_I2T_CURRENT)
			{
				put_motor_in_fault(i);	
				highcurrent[i]=true;
				#ifdef DEBUG_CAN_MSG
				can_printf("j%d filtcurr %f",i,_filt_current[i]);
				#endif	
			}			
		}

//	Check for the MAIN LOOP duration
 
			
//		t1val= (UInt16) TI1_getCounter(); 	
		if (	_count>0)
		{	
			mainLoopOVF=1;
			_count=0;
		}


		
		/* tells that the control cycle is completed */
		
		_wait = true;		
		
	} /* end for(;;) */
//**********************************************************************
void TD0_Enable(void)
{
	setRegBits (TMRD0_CTRL, 0x2000);
}
예제 #18
0
void PWM_B_Write_Protect()
{
	// write protect on 
	setRegBits (PWMB_PMCFG, PWMB_PMCFG_WP_MASK); 
}
예제 #19
0
/**
 * This method inits the LED interface for the 4DC motor board
 ***************************************************************************/
void init_leds(void)
{
	setRegBits(GPIO_A_DDR,0xF0);   
	clrRegBits(GPIO_A_PER,0xF0); 
	setRegBits(GPIO_A_DR, 0xF0);	
}
예제 #20
0
void PWM_B_outputPadDisable (word mask)
{
     mask &= 0x3F00;
	 setRegBits(PWMB_PMOUT, mask);
}
예제 #21
0
/**
 * initializes the PWM module w/ 30KHz complementary mode and 8 clock tick dead time.
 */
void PWMC1_init(void)
{
	/* PWMB_PMCTL: LDFQ=0,HALF=0,IPOL2=0,IPOL1=0,IPOL0=0,PRSC=0,PWMRIE=0,PWMF=0,ISENS=0,LDOK=0,PWMEN=0 */
	setReg (PWMB_PMCTL, 0);
	            
	/* PWMB_PMFCTL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,FIE3=0,FMODE3=1,FIE2=0,FMODE2=1,FIE1=0,FMODE1=1,FIE0=0,FMODE0=1 */
	/* PWMB_PMDISMAP1: DISMAP=0 */
	/* PWMB_PMDISMAP2: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,DISMAP=0 */
#ifndef EMERGENCY_DISABLED	
	setReg (PWMB_PMFCTL, 0x00); 
#if VERSION == 0x0111 || VERSION == 0x0114
	setReg (PWMB_PMDISMAP1, 0x3333);
#else
	setReg (PWMB_PMDISMAP1, 0x2222);
#endif	          
	setReg (PWMB_PMDISMAP2, 0x00);          
#else
	setReg (PWMB_PMFCTL, 0x55);            
	setReg (PWMB_PMDISMAP1, 0);          
	setReg (PWMB_PMDISMAP2, 0);          
#endif

	/* PWMB_PMOUT: PAD_EN=0,??=0,OUTCTL=0,??=0,??=0,OUT=0 */
	setReg (PWMB_PMOUT, 0);

	/* PWMB_PMCCR: ENHA=0,??=0,MSK=0,??=0,??=0,VLMODE=0,??=0,SWP45=0,SWP23=0,SWP01=0 */
	setReg (PWMB_PMCCR, 0);
	            
	/* PWMB_PMCFG: ??=0,??=0,??=0,EDG=1,??=0,TOPNEG45=0,TOPNEG23=0,TOPNEG01=0,??=0,BOTNEG45=0,BOTNEG23=0,BOTNEG01=0,INDEP45=0,INDEP23=0,INDEP01=0,WP=0 */
	setReg (PWMB_PMCFG, 0x1000);           

	/* PWMB_PMDEADTM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,PWMDT=40 */
	setReg (PWMB_PMDEADTM, 0x28);          

	/* PWMB_PWMVAL0: PWMVAL=0 */
	setReg (PWMB_PWMVAL0, 0);            

	/* PWMB_PWMVAL1: PWMVAL=1333 */
	setReg (PWMB_PWMVAL1, 0x0535);         

	/* PWMB_PWMVAL2: PWMVAL=0 */
	setReg (PWMB_PWMVAL2, 0);            

	/* PWMB_PWMVAL3: PWMVAL=1333 */
	setReg (PWMB_PWMVAL3, 0x0535);         

	/* PWMB_PWMVAL4: PWMVAL=0 */
	setReg (PWMB_PWMVAL4, 0);            

	/* PWMB_PWMVAL5: PWMVAL=1333 */
	setReg (PWMB_PWMVAL5, 0x0535);         

	/* PWMB_PWMCM: ??=0,PWMCM=1333 i.e. 30KHz*/
	setReg (PWMB_PWMCM, 0x0535);           

	/* PWMB_PMCTL: LDOK=1,PWMEN=1 */
	setRegBits (PWMB_PMCTL, 3);         

	/* write protect on */
	setReg (PWMB_PMCFG, 0x1001);           
}
예제 #22
0
/*
** ===================================================================
**     Method      :  HWEnDi (component AsynchroSerial)
**
**     Description :
**         Enables or disables the peripheral(s) associated with the bean.
**         The method is called automatically as a part of the Enable and 
**         Disable methods and several internal methods.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void HWEnDi(void)
{
  setRegBits(SCI_CTRL1, (SCI_CTRL1_TE_MASK | SCI_CTRL1_RE_MASK)); /* Enable device */
}
예제 #23
0
/*
** ===================================================================
**     Method      :  HWEnDi (component AsynchroSerial)
**
**     Description :
**         Enables or disables the peripheral(s) associated with the bean.
**         The method is called automatically as a part of the Enable and 
**         Disable methods and several internal methods.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void HWEnDi(void)
{
  setRegBits(SCI_SCICR, (SCI_SCICR_TE_MASK | SCI_SCICR_RE_MASK)); /* Enable device */
}
예제 #24
0
파일: PWMC1.c 프로젝트: RiverLiang/test
void PWMC1_InterruptOnReload(void)
{
  setRegBits(PWM_SM0_STS,0x1000);      /* Clear reload flag */
    PWMC1_OnReload();                  /* Invoke user event */
}