MSP430 3Ph

Simple 3 Phase driver for MSP430. Written for the MSP430G2232, but should work on bigger chips.

Some features don't really work correctly, but alas.

/* * P1.0: L1  / L1A * P1.1: L2 / L1B * P1.2: L3 / L2A * P1.3: Com / L2B * P1.4: Speed Pot * P1.5: Speed Duty * P1.6: Voltage Sense * P1.7: Voltage Ref * * P2.0: Voltage Control * P2.1: Out1 * P2.2: Direction * P2.3: Sin/Square * P2.4: 3/2 Phase * * Clock: 32kHz. * Phase_Div=0, Out=1kHz * Phase_Div=16, Out=62.5Hz * Phase_Div=1000, Out=1Hz * * VfDuty controls the duty-cycle decay, and is scaled by phase_div. * Larger dividers mean more duty-cycle decay at low frequencies. */ typedef unsigned char byte; typedef unsigned int uint; typedef unsigned long ulong; const byte sintab[64]= { 128, 140, 152, 165, 176, 188, 198, 208, 		218, 226, 234, 240, 245, 250, 253, 254, 		255, 254, 253, 250, 245, 240, 234, 226, 		218, 208, 198, 188, 176, 165, 152, 140, 		128, 115, 103, 90,  79,  67,  57,  47, 		 37,  29,  21,  15,  10,   5,   2,   1, 		  0,   1,   2,   5,  10,  15,  21,  29, 		 37,  47,  57,  67,  79,  90, 103, 115 }; const byte sintab1_2[64]= { 128, 167, 184, 196, 206, 215, 223, 229, 		235, 240, 244, 247, 250, 252, 254, 255, 		255, 255, 254, 252, 250, 247, 244, 240, 		235, 229, 223, 215, 206, 196, 184, 167, 		128, 88,  71,  59,  49,  40,  32,  26, 		 20,  15,  11,   8,   5,   3,   1,   0, 		  0,   0,   1,   3,   5,   8,  11,  15, 		 20,  26,  32,  40,  49,  59,  71,  88 }; short phase_cnt; short phase_div; short phase_pot; byte phofs[4]; byte phcnt[4]; byte phduty[4]; byte phase; byte dutysc;			//duty-cycle scale byte madutysc;			//master duty-cycle scale uint vfduty;			//VF duty drop-off byte phcnt2[2]; byte phduty2[2]; byte dacm; byte vcsense; byte vcref; byte vcphase; byte (*func)(byte ph); void (*updatePhase)(byte ph); void (*updatePhaseB)(byte ph); byte fix_sin8(byte ph) { 	return(sintab1_2[(byte)(ph>>2)]); } byte fix_cos8(byte ph) { 	return(sintab1_2[(byte)((ph+64)>>2)]); } byte fix_sqr8(byte ph) { 	return((byte)(((signed char)ph)>>7)); } void updateDutyVfDecay(void) { 	uint i; 	i=(((ulong)phase_div)*vfduty+128)>>8; if(i>255)i=255; i=((255-i)*madutysc)>>8; dutysc=i; } void updatePhase1(byte ph) { 	int ds; ds=func(phase+phofs[ph]); //	ds=(ds*dutysc)>>8; ds=(((ds-128)*dutysc)>>8)+128; phduty[ph]=ds; } void updatePhase1C(byte ph) { 	phduty[ph]=128; } void updatePhase2(byte ph) { 	int ds; ds=func(phase+phofs[ph]); ds=(ds<<1)-256; if(ph&1)ds=-ds; if(ds<0)ds=0; ds=(((unsigned int)ds)*dutysc)>>8; //	ds=(((ds-128)*dutysc)>>8)+128; phduty[ph]=ds; } void updateVreg(void) { 	int i; 	if(vcsensevcref) { 		i=phduty2[0]+1; if(i>240)i=240; phduty2[0]=i; } } void updatePin1(byte ph) { 	int i; //	i=phcnt[ph]+sintab[(byte)(phase+phofs[ph])]; i=phcnt[ph]+phduty[ph]; phcnt[ph]=i; if(i&0x100) { P1OUT|=1<<ph; } else { P1OUT&=~(1<<ph); } } void updatePin2(byte ph) { 	int i; 	i=phcnt2[ph]+phduty2[ph]; phcnt2[ph]=i; if(i&0x100) { P2OUT|=1<<ph; } else { P2OUT&=~(1<<ph); } } void clearPhases(void) { 	phduty[0]=0;	phduty[1]=0; phduty[2]=0;	phduty[3]=0; phduty2[0]=0;	phduty2[1]=0; P1OUT&=~15; P2OUT&=~3; } byte st, lst, nph; struct phaseMode_s { byte phofs[4]; byte (*func)(byte ph); void (*updatePhase)(byte ph); void (*updatePhaseB)(byte ph); byte nph; }; const struct phaseMode_s phaseMode[]={ {	0, 85, 171, 0, fix_sin8, updatePhase1, updatePhase1C, 3}, {	171, 85, 0, 0, fix_sin8, updatePhase1, updatePhase1C, 3}, {	0, 85, 171, 0, fix_sqr8, updatePhase1, updatePhase1C, 3}, {	171, 85, 0, 0, fix_sqr8, updatePhase1, updatePhase1C, 3}, {	0, 0, 64, 64, fix_sin8, updatePhase2, updatePhase2, 4}, {	64,	64,	0,	0, fix_sin8, updatePhase2, updatePhase2, 4}, {	0, 0, 64, 64, fix_sqr8, updatePhase2, updatePhase2, 4}, {	64,	64,	0,	0, fix_sqr8, updatePhase2, updatePhase2, 4} }; void setPhaseMode(byte mode) { 	struct phaseMode_s *phm; st=mode; lst=st; phm=(struct phaseMode_s *)(&(phaseMode[st])); phofs[0]=phm->phofs[0]; phofs[1]=phm->phofs[1]; phofs[2]=phm->phofs[2]; phofs[3]=phm->phofs[3]; func=phm->func; updatePhase=phm->updatePhase; updatePhaseB=phm->updatePhaseB; nph=phm->nph; } void updateMainPhase(void) { 	int i; 	phase=phase+8; phase_cnt=phase_div; updateDutyVfDecay; updatePhase(0); updatePhase(1); updatePhase(2); updatePhaseB(3); i=P2IN; st=(i>>2)&7; if(st!=lst) { 		lst=st; setPhaseMode(st); } } void updateMainPhase2(void) { 	if(!(vcphase++)) { 		updateVreg; } 	if(phase_cnt<=0) { 		if(phase_div>1012) { 			clearPhases; while(phase_div>1012) __bis_SR_register(CPUOFF + GIE); return; } 		updateMainPhase; } } int main(void) { 	BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; //	WDTCTL=WDTPW|WDTHOLD; WDTCTL = WDT_MDLY_0_5;		//0.5ms at 1MHz (2kHz), 0.03125ms (32kHz) at 16MHz //	WDTCTL = WDT_MDLY_0_064; IE1 |= WDTIE; //	P1DIR|=0x07; P1DIR|=0x0F; P2DIR|=0x03; P1OUT=0; P2OUT=0; P2REN|=0x1C; //	ADC10CTL0 = SREF_1 + ADC10SHT_2 + ADC10ON + ADC10IE + REF2_5V + REFON; ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE + REF2_5V + REFON; ADC10CTL1 = INCH_4; ADC10AE0 |= 0x10; phase_div=16; setPhaseMode(0); dutysc=255; madutysc=255; vfduty=192; dacm=0; ADC10CTL0 |= ENC + ADC10SC; __bis_SR_register(GIE); for { 		updatePin1(0); updatePin1(1); updatePin1(2); updatePin1(3); updatePin2(0); updatePin2(1); updateMainPhase2; } //	return 0; } __interrupt void ADC10_ISR(void) void __attribute__ ((interrupt(ADC10_VECTOR))) ADC10_ISR (void) { 	unsigned long i; 	__bic_SR_register_on_exit(CPUOFF); switch(dacm) { 	case 0: phase_pot=ADC10MEM; i=1023-phase_pot; i=(i*i+512)>>10; //		i=(i*i*i)>>20; phase_div=i; dacm=1; break; case 1: //		dutysc=ADC10MEM>>2; //		madutysc=ADC10MEM>>2; dacm=2; break; case 2: vcsense=ADC10MEM>>2; dacm=3; break; case 3: vcref=ADC10MEM>>2; dacm=0; break; default: dacm=0; break; } //	phase_div=1024-ADC10MEM; //	phase_div=16383-(ADC10MEM<<4); ADC10CTL1 = (ADC10CTL1&0x0FFF)|((4+dacm)<<12); ADC10AE0 = 0x10<
 * 1) if 0
 * 1) endif
 * 1) if 1
 * 1) endif
 * 1) if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
 * 2) pragma vector=ADC10_VECTOR
 * 1) elif defined(__GNUC__)
 * 1) else
 * 2) error Compiler not supported!
 * 3) endif
 * 1) if 1
 * 1) endif
 * 1) if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
 * 2) pragma vector=WDT_VECTOR
 * 1) elif defined(__GNUC__)
 * 1) else
 * 2) error Compiler not supported!
 * 3) endif