Segfault code

Read about the project here.


//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules
#include <I2CHW_1Common.h>
#include <I2CHW_1mstr.h>
#include <stdlib.h>
#include <math.h>
//#include  "PWM8.h"
#define SLAVE_ADDRESS 0x52
#define SLAVE_ADDRESS2 0x53
#define PI 3.14159
#define NLOOPS 50
#define NSWITCH 50
#define TIMEOUT 10

#define DEBUG

//Towing constants
#define T_ANGLE_LIMIT 20
#define T_TURN_LIMIT 10
#define T_S 3
#define T_P 5

//Balance constants
#define B_OFFSET_ANGLE 5
#define B_TURN_LIMIT 5
#define B_S 6 //Steering 6
#define B_P 9 //Gyro 12
#define B_I 18 //Accelerometer 24
#define B_D 0 //dGyro
#define TIME_STEP 0.009765625
#define OS_LIMIT 80 //Speed limit
#define OS_P 0.0
#define OS_I 0.03
#define OS_R 1.0
#define OS_ANGLE_MAX 0.02

//Loop constants
#define A_LP_S 0.1
#define A_LP 0.01 //Low pass frequency (in 100 Hz) 0.01
#define A_HP 0.99

BYTE    Zero=0x00;
BYTE    Initialize[2];
BYTE    rxBuffer[6];
BYTE    status;
int msg;

// For Nunchuck
int Ax, Ay, Az;
float ThetaX,ThetaY,ThetaX_LP,ThetaY_LP,ThetaX_LP_Old;

// For WMP
int Roll;
float OmegaY,OmegaY_Old,OmegaY_HP,OmegaY_HP_Old,dOmegaY_HP;
//int Yaw, Pitch;
//float OmegaX,OmegaZ;

// For main program
BYTE line;
int nLoops;
int watchtime;
char timeout;
int nSwitch;

// For output
float Angle,Vel,Drive,Duty_1,Duty_2,ThetaX_Out,ThetaY_Out;
float os_sum,os_angle,os_angle_old;

float CoerceRange(float x_min, float x_max, float x) {
if (x<x_min) x=x_min;
if (x>x_max) x=x_max;
return x;
}

void Nunchuck() {
Ax=(rxBuffer[2]*2)+((rxBuffer[5]>>4)&0x1)-255;
Ay=(rxBuffer[3]*2)+((rxBuffer[5]>>5)&0x1)-255;
Az=((rxBuffer[4]&~0x01)*2)+((rxBuffer[5]>>6)&0x03)-255;

//Exact way
//ThetaX=-atan(Az/sqrt(Ax*Ax+Ay*Ay))*180.0/PI;
//ThetaY=atan(Ax/sqrt(Ay*Ay+Az*Az))*180.0/PI;

//Good enough way
ThetaX=Az*90/103*2/PI;
ThetaY=Ax*90/103*2/PI;

//Low pass filter
ThetaX_LP_Old=ThetaX_LP;
ThetaX_LP*=(1-A_LP);
ThetaX_LP+=A_LP*ThetaX;

ThetaY_LP*=(1-A_LP_S);
ThetaY_LP+=A_LP_S*ThetaY;

//LCD Stuff
/*
LCD_1_Position(0,0);
LCD_1_PrCString("       ");
LCD_1_Position(0,0);
LCD_1_PrString(ftoa(ThetaX, &msg));
LCD_1_Position(0,7);
LCD_1_PrCString("         ");
LCD_1_Position(0,8);
LCD_1_PrString(ftoa(ThetaY, &msg));
*/

//UART stuff
/*
UART_1_CPutString("Theta X_LP: ");
UART_1_PutString(ftoa(ThetaX_LP, &msg));
UART_1_CPutString("     Theta X: ");
UART_1_PutString(ftoa(ThetaX, &msg));
UART_1_CPutString("     Theta Y: ");
UART_1_PutString(ftoa(ThetaY, &msg));
UART_1_CPutString("     Time: ");
*/

}

void WMP() {
Roll = (rxBuffer[4]&~0x3)*64+rxBuffer[1];

if (rxBuffer[4]&0x2) OmegaY = ((float) Roll-8192.)/20.*1.45;
else OmegaY = ((float) Roll-8192.)/20.*6.59;

OmegaY_HP+=OmegaY-OmegaY_Old;
OmegaY_HP*=A_HP;
dOmegaY_HP=OmegaY_HP-OmegaY_HP_Old;
OmegaY_Old=OmegaY;
OmegaY_HP_Old=OmegaY_HP;

// X & Z
/*
Yaw = (rxBuffer[3]&~0x3)*64+rxBuffer[0];
Pitch = (rxBuffer[5]&~0x3)*64+rxBuffer[2];
if (rxBuffer[3]&0x1) OmegaX = ((float) Pitch-8192)/20;
else OmegaX = (Pitch-8192)/4;
if (rxBuffer[3]&0x2) OmegaZ = ((float) Yaw-8192)/20;
else OmegaZ = (Yaw-8192)/4;
*/

//Uart Stuff
/*
//UART_1_CPutString("Omega X: ");
//UART_1_PutString(ftoa(OmegaX, &msg));
UART_1_CPutString("   Omega Y: ");
UART_1_PutString(ftoa(OmegaY, &msg));
UART_1_CPutString("   Omega Y HP: ");
UART_1_PutString(ftoa(OmegaY_HP, &msg));
//UART_1_CPutString("    Omega Z: ");
//UART_1_PutString(ftoa(OmegaZ, &msg));
*/
}

void Tow() {
/*
if (fabs(ThetaX_LP)<ANGLE_LIMIT)
{
LED_1_Switch(1);
//UART_1_CPutString("%");
}
else {
LED_1_Switch(0);
}
*/

//UART_1_PutString(ftoa(ThetaX_LP, &msg));
//UART_1_PutCRLF();

LED_1_Switch(1);

ThetaX_Out=CoerceRange(-T_ANGLE_LIMIT,T_ANGLE_LIMIT,ThetaX_LP);
ThetaY_Out=CoerceRange(-T_TURN_LIMIT,T_TURN_LIMIT,ThetaY_LP);

Duty_1=(T_P*ThetaX_Out+T_S*ThetaY_Out+100)/200;
Duty_1=CoerceRange(0,1,Duty_1);

Duty_2=(T_P*ThetaX_Out-T_S*ThetaY_Out+100)/200;
Duty_2=CoerceRange(0,1,Duty_2);

PWM8_1_WritePulseWidth(Duty_1*255);
PWM8_2_WritePulseWidth(Duty_2*255);
}

void Balance() {
LED_1_Switch(1);
//Angle=OmegaY_HP*TIME_STEP+ThetaX_LP;
Angle=(1-A_LP)*(Angle+OmegaY_HP*TIME_STEP)+A_LP*(ThetaX-B_OFFSET_ANGLE)+os_angle;
//Vel=OmegaY_HP;
Vel=(ThetaX_LP-ThetaX_LP_Old)/TIME_STEP+OmegaY_HP+(os_angle-os_angle_old)/TIME_STEP;

//Drive+=(B_P*ThetaX_LP+B_D*OmegaY_HP)*TIME_STEP;
//Drive+=(B_P*Angle+B_D*OmegaY_HP)*TIME_STEP;
Drive+=(B_I*Angle+B_P*Vel)*TIME_STEP+B_D*dOmegaY_HP;

Drive=CoerceRange(-100,100,Drive);

/*
os_angle_old=os_angle;
if (Drive>OS_LIMIT) {
os_sum+=(Drive-OS_LIMIT)*TIME_STEP;
os_angle=OS_P*(Drive-OS_LIMIT)+OS_I*os_sum;
}
else {
os_sum=0;
os_angle+=-OS_R*TIME_STEP;
}
os_sum=CoerceRange(0,OS_ANGLE_MAX/OS_I,os_sum);
os_angle=CoerceRange(0,OS_ANGLE_MAX,os_angle);
*/

ThetaY_Out=CoerceRange(-B_TURN_LIMIT,B_TURN_LIMIT,ThetaY_LP);
Duty_1=(Drive+B_S*ThetaY_Out+100)/200;
Duty_1=CoerceRange(0,1,Duty_1);
Duty_2=(Drive-B_S*ThetaY_Out+100)/200;
Duty_2=CoerceRange(0,1,Duty_2);
PWM8_1_WritePulseWidth(Duty_1*255);
PWM8_2_WritePulseWidth(Duty_2*255);
}

void Neutral() {
LED_1_Switch(0);
}

void main()
{
Initialize[0]=0xfe;
Initialize[1]=0x05;

LCD_1_Start();
I2CHW_1_Start();
I2CHW_1_EnableMstr();
M8C_EnableGInt;
I2CHW_1_EnableInt();

LED_1_Start();

UART_1_Start(UART_1_PARITY_NONE);

DigInv_1_Start();
DigInv_2_Start();

PWM8_1_WritePulseWidth(127);
PWM8_2_WritePulseWidth(127);

/* ensure interrupt is disabled */
PWM8_1_DisableInt();
PWM8_2_DisableInt();

/* start the PWM8! */
PWM8_1_Start();
PWM8_2_Start();

LCD_1_Position(0,0);
LCD_1_PrHexByte(0xBE);

/* Enable the global and local interrupts */

SleepTimer_1_Start();
SleepTimer_1_SetInterval(SleepTimer_1_512_HZ);   // Set interrupt to a
SleepTimer_1_EnableInt();                     // 64 Hz rate

/* Initialize */
UART_1_CPutString("On");
UART_1_PutCRLF();
/* Send the contents of the data in txBuffer */;
I2CHW_1_bWriteBytes(SLAVE_ADDRESS2, Initialize, 2, I2CHW_1_CompleteXfer);
/* Wait until the data is transferred */
while(!(I2CHW_1_bReadI2CStatus() & I2CHW_WR_COMPLETE));

UART_1_CPutString("Initialized");
UART_1_PutCRLF();

LCD_1_Position(0,0);
LCD_1_PrHexByte(I2CHW_1_bReadI2CStatus());

I2CHW_1_ClrWrStatus();

/* Send and Receive forever*/
while( 1 )
{
timeout=FALSE;
/* Request Data */;
I2CHW_1_bWriteBytes(SLAVE_ADDRESS, &Zero, 1, I2CHW_1_CompleteXfer);
/* Wait until the data is transferred */
watchtime = SleepTimer_1_bGetTimer();

//while(!(I2CHW_1_bReadI2CStatus() & I2CHW_WR_COMPLETE));
while((!(I2CHW_1_bReadI2CStatus() & I2CHW_WR_COMPLETE))&&(SleepTimer_1_bGetTimer()>(watchtime-TIMEOUT)));
if (SleepTimer_1_bGetTimer()<=(watchtime-TIMEOUT)) timeout=TRUE;
/* Clear Write Complete Status bit */
I2CHW_1_ClrWrStatus();

//LCD_1_Position(0,3);
//LCD_1_PrHexByte(I2CHW_1_bReadI2CStatus());
SleepTimer_1_TickWait(1);

/* Read from the slave and place in rxBuffer */;
I2CHW_1_fReadBytes(SLAVE_ADDRESS,rxBuffer, 6, I2CHW_1_CompleteXfer);
/* Wait until the data is read */
watchtime = SleepTimer_1_bGetTimer();

//while(!(I2CHW_1_bReadI2CStatus() & I2CHW_RD_COMPLETE));
while((!(I2CHW_1_bReadI2CStatus() & I2CHW_RD_COMPLETE))&&(SleepTimer_1_bGetTimer()>(watchtime-TIMEOUT)));
if (SleepTimer_1_bGetTimer()<=(watchtime-TIMEOUT)) timeout=TRUE;
/* Clear Read Complete Status bit */
I2CHW_1_ClrRdStatus();

//LCD_1_Position(0,6);
//LCD_1_PrHexByte(I2CHW_1_bReadI2CStatus());
SleepTimer_1_TickWait(1);

// Check source - 0 = Nunchuck, 1 = WM+
line=(0x02&rxBuffer[5])>>1;

if (timeout) {
//Neutral();
UART_1_CPutString("~");
UART_1_PutCRLF();
UART_1_PutString(ftoa(255-SleepTimer_1_bGetTimer(), &msg));
SleepTimer_1_SetTimer(255);
UART_1_PutCRLF();}
else if (line==0x00) Nunchuck();
else if (line==0x01) {
WMP();

while ((255-SleepTimer_1_bGetTimer())%5!=0) SleepTimer_1_TickWait(1);

UART_1_PutString(ftoa(255-SleepTimer_1_bGetTimer(), &msg));
SleepTimer_1_SetTimer(255);
UART_1_PutCRLF();

if (nLoops>NLOOPS) {
LED_1_Switch(1);
if ((PRT1DR & 0x01)==0) {
if (nSwitch>NSWITCH) {
Drive=0;
Angle=ThetaX_LP;
os_sum=0;
os_angle=0;
}
else {
nSwitch++;
Balance();
}
}
else if (PRT1DR & 0x02) {
Drive=0;
Angle=ThetaX_LP;
Tow();
nSwitch=0;
os_sum=0;
os_angle=0;
}
else {
Balance();
nSwitch=0;
}
}
else {
nLoops++;
UART_1_CPutString("=");
UART_1_PutCRLF();
}
}

}
}