Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@0:867c4eabf128, 2016-02-26 (annotated)
- Committer:
- ibestwill
- Date:
- Fri Feb 26 21:28:57 2016 +0000
- Revision:
- 0:867c4eabf128
- Child:
- 1:f1d9b55f7dd7
US & RC
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ibestwill | 0:867c4eabf128 | 1 | #include "mbed.h" |
ibestwill | 0:867c4eabf128 | 2 | #include "rtos.h" |
ibestwill | 0:867c4eabf128 | 3 | #include "stdlib.h" |
ibestwill | 0:867c4eabf128 | 4 | |
ibestwill | 0:867c4eabf128 | 5 | // IO Port Configuration |
ibestwill | 0:867c4eabf128 | 6 | DigitalOut led1(LED1); |
ibestwill | 0:867c4eabf128 | 7 | DigitalOut led2(LED2); |
ibestwill | 0:867c4eabf128 | 8 | DigitalOut led3(LED3); |
ibestwill | 0:867c4eabf128 | 9 | DigitalOut led4(LED4); |
ibestwill | 0:867c4eabf128 | 10 | PwmOut PwmR(p21); // define p21 as PwmR, p22 as PwmL |
ibestwill | 0:867c4eabf128 | 11 | PwmOut PwmL(p22); // define p21 as PwmR, p22 as PwmL |
ibestwill | 0:867c4eabf128 | 12 | DigitalOut DirR(p30); // define p30 as DirR, p29 as DirL |
ibestwill | 0:867c4eabf128 | 13 | DigitalOut DirL(p29); // define p30 as DirR, p29 as DirL |
ibestwill | 0:867c4eabf128 | 14 | DigitalOut SpiReset(p11);//Reset for all devices within the slave SPI peripheral in the DE0 FPGA |
ibestwill | 0:867c4eabf128 | 15 | DigitalOut IoReset(p12); //Places SPI interface on the DE0 FPGA into control mode |
ibestwill | 0:867c4eabf128 | 16 | SPI DE0(p5,p6,p7); //(mosi,miso,sclk)DE0 is the SPI channel with the FPGA |
ibestwill | 0:867c4eabf128 | 17 | Serial pc(USBTX, USBRX); // Pins (tx, rx) for PC serial channel |
ibestwill | 0:867c4eabf128 | 18 | Serial BluetoothSerial(p9, p10); // tx, rx |
ibestwill | 0:867c4eabf128 | 19 | Ticker PeriodicInt; // Declare a timer interrupt: PeriodicInt |
ibestwill | 0:867c4eabf128 | 20 | InterruptIn Bumper(p8); // External interrupt pin declared as Bumper |
ibestwill | 0:867c4eabf128 | 21 | |
ibestwill | 0:867c4eabf128 | 22 | // Function prototypes |
ibestwill | 0:867c4eabf128 | 23 | void Initialize(void); |
ibestwill | 0:867c4eabf128 | 24 | char DisplayMenu(void); |
ibestwill | 0:867c4eabf128 | 25 | void ManualControl(void); |
ibestwill | 0:867c4eabf128 | 26 | void BluetoothTest(void); |
ibestwill | 0:867c4eabf128 | 27 | void PiControllerISR(void); |
ibestwill | 0:867c4eabf128 | 28 | void WdtFaultISR(void); |
ibestwill | 0:867c4eabf128 | 29 | void ExtCollisionISR(void); |
ibestwill | 0:867c4eabf128 | 30 | void PiControlThread(void const *argument); |
ibestwill | 0:867c4eabf128 | 31 | void ExtCollisionThread(void const *argument); |
ibestwill | 0:867c4eabf128 | 32 | void Watchdog(void const *n); |
ibestwill | 0:867c4eabf128 | 33 | void PIController(void); |
ibestwill | 0:867c4eabf128 | 34 | void SpeedControl(void); |
ibestwill | 0:867c4eabf128 | 35 | int SatAdd(int x, int y); |
ibestwill | 0:867c4eabf128 | 36 | int SatSub(int x, int y); |
ibestwill | 0:867c4eabf128 | 37 | int SatValue(int x, int Limit); |
ibestwill | 0:867c4eabf128 | 38 | int Signextend(int x); |
ibestwill | 0:867c4eabf128 | 39 | void Userinterface(void); |
ibestwill | 0:867c4eabf128 | 40 | void QeiInterface(void); |
ibestwill | 0:867c4eabf128 | 41 | void UsRangefinder(void); |
ibestwill | 0:867c4eabf128 | 42 | void RcServoMotor(void); |
ibestwill | 0:867c4eabf128 | 43 | |
ibestwill | 0:867c4eabf128 | 44 | |
ibestwill | 0:867c4eabf128 | 45 | // Processes and threads |
ibestwill | 0:867c4eabf128 | 46 | int32_t SignalPi, SignalWdt, SignalExtCollision; |
ibestwill | 0:867c4eabf128 | 47 | osThreadId PiControl,WdtFault,ExtCollision; |
ibestwill | 0:867c4eabf128 | 48 | osThreadDef(PiControlThread, osPriorityRealtime, DEFAULT_STACK_SIZE); // Declare Control as a thread/process |
ibestwill | 0:867c4eabf128 | 49 | osThreadDef(ExtCollisionThread, osPriorityHigh, DEFAULT_STACK_SIZE); // Declare External Collision as a thread/process |
ibestwill | 0:867c4eabf128 | 50 | osTimerDef(Wdtimer, Watchdog); // Declare a watch dog timer |
ibestwill | 0:867c4eabf128 | 51 | |
ibestwill | 0:867c4eabf128 | 52 | |
ibestwill | 0:867c4eabf128 | 53 | // Global variables for interrupt handler |
ibestwill | 0:867c4eabf128 | 54 | int32_t dPos_R, dTime_R, Vel_R; |
ibestwill | 0:867c4eabf128 | 55 | int32_t Setspeed_R; |
ibestwill | 0:867c4eabf128 | 56 | int32_t u_R=0,uS_R=0; |
ibestwill | 0:867c4eabf128 | 57 | int32_t uP_R,uI_R; |
ibestwill | 0:867c4eabf128 | 58 | int32_t e_R; |
ibestwill | 0:867c4eabf128 | 59 | int32_t x_R=0, xT_R=0; |
ibestwill | 0:867c4eabf128 | 60 | |
ibestwill | 0:867c4eabf128 | 61 | float T = 5000; //us |
ibestwill | 0:867c4eabf128 | 62 | float y_R=0; |
ibestwill | 0:867c4eabf128 | 63 | float Kp_R=3.5, Ki_R=0.8; |
ibestwill | 0:867c4eabf128 | 64 | |
ibestwill | 0:867c4eabf128 | 65 | |
ibestwill | 0:867c4eabf128 | 66 | //************************************************************************** |
ibestwill | 0:867c4eabf128 | 67 | //************************************************************************** |
ibestwill | 0:867c4eabf128 | 68 | |
ibestwill | 0:867c4eabf128 | 69 | |
ibestwill | 0:867c4eabf128 | 70 | int main() |
ibestwill | 0:867c4eabf128 | 71 | { |
ibestwill | 0:867c4eabf128 | 72 | |
ibestwill | 0:867c4eabf128 | 73 | //Initialize(); |
ibestwill | 0:867c4eabf128 | 74 | |
ibestwill | 0:867c4eabf128 | 75 | //Userinterface(); |
ibestwill | 0:867c4eabf128 | 76 | |
ibestwill | 0:867c4eabf128 | 77 | //UsRangefinder(); |
ibestwill | 0:867c4eabf128 | 78 | |
ibestwill | 0:867c4eabf128 | 79 | RcServoMotor(); |
ibestwill | 0:867c4eabf128 | 80 | |
ibestwill | 0:867c4eabf128 | 81 | } |
ibestwill | 0:867c4eabf128 | 82 | |
ibestwill | 0:867c4eabf128 | 83 | |
ibestwill | 0:867c4eabf128 | 84 | void UsRangefinder(void) |
ibestwill | 0:867c4eabf128 | 85 | { |
ibestwill | 0:867c4eabf128 | 86 | unsigned int V, duration; |
ibestwill | 0:867c4eabf128 | 87 | float distance; |
ibestwill | 0:867c4eabf128 | 88 | DE0.format(16,1); // SPI is mode 1 |
ibestwill | 0:867c4eabf128 | 89 | DE0.frequency(500000); // SPI frequency |
ibestwill | 0:867c4eabf128 | 90 | |
ibestwill | 0:867c4eabf128 | 91 | IoReset=0; // Reset all SPI peripherals |
ibestwill | 0:867c4eabf128 | 92 | IoReset=1; |
ibestwill | 0:867c4eabf128 | 93 | wait_us(5); |
ibestwill | 0:867c4eabf128 | 94 | IoReset=0; |
ibestwill | 0:867c4eabf128 | 95 | |
ibestwill | 0:867c4eabf128 | 96 | SpiReset=0; |
ibestwill | 0:867c4eabf128 | 97 | SpiReset=1; |
ibestwill | 0:867c4eabf128 | 98 | wait_us(5); |
ibestwill | 0:867c4eabf128 | 99 | SpiReset=0; |
ibestwill | 0:867c4eabf128 | 100 | V=DE0.write(0x8901); // Control word to read ultrasonic range finder. |
ibestwill | 0:867c4eabf128 | 101 | do { |
ibestwill | 0:867c4eabf128 | 102 | duration = DE0.write(0x0000); // Read ultrasonic rangefinder. |
ibestwill | 0:867c4eabf128 | 103 | pc.printf("\r\n SPI ID=%4x Us Range=%5d",V,duration); |
ibestwill | 0:867c4eabf128 | 104 | |
ibestwill | 0:867c4eabf128 | 105 | //Need to check if duration is singed or unsigned value, if extend 16bit to 32bit |
ibestwill | 0:867c4eabf128 | 106 | distance = (duration / 2) * 0.0344; |
ibestwill | 0:867c4eabf128 | 107 | |
ibestwill | 0:867c4eabf128 | 108 | if (distance >= 400 || distance <= 2){ |
ibestwill | 0:867c4eabf128 | 109 | pc.printf("\r\nOut of Range\r\n"); |
ibestwill | 0:867c4eabf128 | 110 | } |
ibestwill | 0:867c4eabf128 | 111 | else { |
ibestwill | 0:867c4eabf128 | 112 | pc.printf("Distance = %2f", distance); |
ibestwill | 0:867c4eabf128 | 113 | wait(1); |
ibestwill | 0:867c4eabf128 | 114 | } |
ibestwill | 0:867c4eabf128 | 115 | wait(0.5); |
ibestwill | 0:867c4eabf128 | 116 | } while(!pc.readable()); |
ibestwill | 0:867c4eabf128 | 117 | } |
ibestwill | 0:867c4eabf128 | 118 | |
ibestwill | 0:867c4eabf128 | 119 | void RcServoMotor(void) |
ibestwill | 0:867c4eabf128 | 120 | { |
ibestwill | 0:867c4eabf128 | 121 | unsigned int V, W, X, n; |
ibestwill | 0:867c4eabf128 | 122 | DE0.format(16,1); // SPI is mode 1 |
ibestwill | 0:867c4eabf128 | 123 | DE0.frequency(500000); // SPI frequency |
ibestwill | 0:867c4eabf128 | 124 | IoReset=0; // Reset all SPI peripherals |
ibestwill | 0:867c4eabf128 | 125 | IoReset=1; |
ibestwill | 0:867c4eabf128 | 126 | wait_us(5); |
ibestwill | 0:867c4eabf128 | 127 | IoReset=0; |
ibestwill | 0:867c4eabf128 | 128 | |
ibestwill | 0:867c4eabf128 | 129 | SpiReset=0; |
ibestwill | 0:867c4eabf128 | 130 | SpiReset=1; |
ibestwill | 0:867c4eabf128 | 131 | wait_us(5); |
ibestwill | 0:867c4eabf128 | 132 | SpiReset=0; |
ibestwill | 0:867c4eabf128 | 133 | V=DE0.write(0x0402); // Control word to write RC Servo pulse interval in ms. |
ibestwill | 0:867c4eabf128 | 134 | //n=4000; |
ibestwill | 0:867c4eabf128 | 135 | |
ibestwill | 0:867c4eabf128 | 136 | do { |
ibestwill | 0:867c4eabf128 | 137 | /* |
ibestwill | 0:867c4eabf128 | 138 | wait_us(10); |
ibestwill | 0:867c4eabf128 | 139 | W=DE0.write(0x10); // Write RC Servo pulse interval in ms |
ibestwill | 0:867c4eabf128 | 140 | X=DE0.write(n); // Write position to RC Servo M1. |
ibestwill | 0:867c4eabf128 | 141 | n=n+2000; |
ibestwill | 0:867c4eabf128 | 142 | if(n==60000) n=4000; |
ibestwill | 0:867c4eabf128 | 143 | pc.printf("\r\n SPI ID=%4x Nms=%4x R/C Servo 1=%5d",V,W,X); |
ibestwill | 0:867c4eabf128 | 144 | wait(1); |
ibestwill | 0:867c4eabf128 | 145 | |
ibestwill | 0:867c4eabf128 | 146 | */ |
ibestwill | 0:867c4eabf128 | 147 | |
ibestwill | 0:867c4eabf128 | 148 | for(n=0;n<=60000;n=n+6000){ |
ibestwill | 0:867c4eabf128 | 149 | wait_us(10); |
ibestwill | 0:867c4eabf128 | 150 | W=DE0.write(0x10); // Write RC Servo pulse interval in ms |
ibestwill | 0:867c4eabf128 | 151 | X=DE0.write(n); // Write position to RC Servo M1. |
ibestwill | 0:867c4eabf128 | 152 | pc.printf("\r\n SPI ID=%4x Nms=%4x R/C Servo 1=%5d",V,W,X); |
ibestwill | 0:867c4eabf128 | 153 | wait(1); |
ibestwill | 0:867c4eabf128 | 154 | } |
ibestwill | 0:867c4eabf128 | 155 | |
ibestwill | 0:867c4eabf128 | 156 | for(n=60000;n>=6000;n=n-6000){ |
ibestwill | 0:867c4eabf128 | 157 | wait_us(10); |
ibestwill | 0:867c4eabf128 | 158 | W=DE0.write(0x10); // Write RC Servo pulse interval in ms |
ibestwill | 0:867c4eabf128 | 159 | X=DE0.write(n); // Write position to RC Servo M1. |
ibestwill | 0:867c4eabf128 | 160 | pc.printf("\r\n SPI ID=%4x Nms=%4x R/C Servo 1=%5d",V,W,X); |
ibestwill | 0:867c4eabf128 | 161 | wait(1); |
ibestwill | 0:867c4eabf128 | 162 | } |
ibestwill | 0:867c4eabf128 | 163 | |
ibestwill | 0:867c4eabf128 | 164 | } while(!pc.readable()); |
ibestwill | 0:867c4eabf128 | 165 | |
ibestwill | 0:867c4eabf128 | 166 | } |
ibestwill | 0:867c4eabf128 | 167 | |
ibestwill | 0:867c4eabf128 | 168 | |
ibestwill | 0:867c4eabf128 | 169 | //************************************************************************** |
ibestwill | 0:867c4eabf128 | 170 | void Userinterface(void) |
ibestwill | 0:867c4eabf128 | 171 | { |
ibestwill | 0:867c4eabf128 | 172 | |
ibestwill | 0:867c4eabf128 | 173 | pc.printf("\n\rEnter number:\n "); |
ibestwill | 0:867c4eabf128 | 174 | pc.scanf("%d",&Setspeed_R); |
ibestwill | 0:867c4eabf128 | 175 | pc.printf("\n\rYou Entered :%d\n\n",Setspeed_R); |
ibestwill | 0:867c4eabf128 | 176 | |
ibestwill | 0:867c4eabf128 | 177 | /* |
ibestwill | 0:867c4eabf128 | 178 | DirR=1; |
ibestwill | 0:867c4eabf128 | 179 | y_R=Setspeed_R/36*T; |
ibestwill | 0:867c4eabf128 | 180 | pc.printf("y_R = %f\n",y_R); |
ibestwill | 0:867c4eabf128 | 181 | PwmR.pulsewidth_us(y_R); |
ibestwill | 0:867c4eabf128 | 182 | */ |
ibestwill | 0:867c4eabf128 | 183 | |
ibestwill | 0:867c4eabf128 | 184 | } |
ibestwill | 0:867c4eabf128 | 185 | |
ibestwill | 0:867c4eabf128 | 186 | //************************************************************************** |
ibestwill | 0:867c4eabf128 | 187 | void Initialize(void) |
ibestwill | 0:867c4eabf128 | 188 | { |
ibestwill | 0:867c4eabf128 | 189 | //Baud Rate |
ibestwill | 0:867c4eabf128 | 190 | //pc.baud (460800); |
ibestwill | 0:867c4eabf128 | 191 | |
ibestwill | 0:867c4eabf128 | 192 | //Intialization Motor |
ibestwill | 0:867c4eabf128 | 193 | PwmR.period_us(T); |
ibestwill | 0:867c4eabf128 | 194 | PwmL.period_us(T); |
ibestwill | 0:867c4eabf128 | 195 | |
ibestwill | 0:867c4eabf128 | 196 | |
ibestwill | 0:867c4eabf128 | 197 | //Initialization QEI - to be exected once(normally) |
ibestwill | 0:867c4eabf128 | 198 | DE0.format(16,1); //SPI format:16-bit words, mode 1 protocol or mode 0???????????? |
ibestwill | 0:867c4eabf128 | 199 | //DE0.frequency(500000); |
ibestwill | 0:867c4eabf128 | 200 | IoReset=0; |
ibestwill | 0:867c4eabf128 | 201 | IoReset=1; |
ibestwill | 0:867c4eabf128 | 202 | IoReset=0; |
ibestwill | 0:867c4eabf128 | 203 | |
ibestwill | 0:867c4eabf128 | 204 | SpiReset=0; |
ibestwill | 0:867c4eabf128 | 205 | SpiReset=1; |
ibestwill | 0:867c4eabf128 | 206 | wait_us(10); |
ibestwill | 0:867c4eabf128 | 207 | SpiReset=0; |
ibestwill | 0:867c4eabf128 | 208 | int ID = DE0.write(0x8002); //SPI slave control word to read (only) 2-word transactions starting at base address 0 within the peripheral |
ibestwill | 0:867c4eabf128 | 209 | |
ibestwill | 0:867c4eabf128 | 210 | if(ID == 23) printf("\r\n\nSPI Interface is Successful ! ID = %d\r\n\n",ID); //ID=0x0017 |
ibestwill | 0:867c4eabf128 | 211 | else printf("\r\n********SPI Interface failed!********\r\n\n"); |
ibestwill | 0:867c4eabf128 | 212 | |
ibestwill | 0:867c4eabf128 | 213 | |
ibestwill | 0:867c4eabf128 | 214 | } |
ibestwill | 0:867c4eabf128 | 215 | |
ibestwill | 0:867c4eabf128 | 216 | |
ibestwill | 0:867c4eabf128 | 217 | //************************************************************************** |
ibestwill | 0:867c4eabf128 | 218 | void QeiInterface(void) |
ibestwill | 0:867c4eabf128 | 219 | { |
ibestwill | 0:867c4eabf128 | 220 | |
ibestwill | 0:867c4eabf128 | 221 | dPos_R = DE0.write(0x00); |
ibestwill | 0:867c4eabf128 | 222 | dTime_R = DE0.write(0x00); |
ibestwill | 0:867c4eabf128 | 223 | |
ibestwill | 0:867c4eabf128 | 224 | dPos_R = Signextend(dPos_R); |
ibestwill | 0:867c4eabf128 | 225 | |
ibestwill | 0:867c4eabf128 | 226 | |
ibestwill | 0:867c4eabf128 | 227 | Vel_R = (123*dPos_R)/dTime_R; //radians per second |
ibestwill | 0:867c4eabf128 | 228 | |
ibestwill | 0:867c4eabf128 | 229 | printf("\r\ndPos_R: %d dTime_R: %d Vel_R: %d \r\n",dPos_R,dTime_R,Vel_R); |
ibestwill | 0:867c4eabf128 | 230 | |
ibestwill | 0:867c4eabf128 | 231 | |
ibestwill | 0:867c4eabf128 | 232 | } |
ibestwill | 0:867c4eabf128 | 233 | |
ibestwill | 0:867c4eabf128 | 234 | //************************************************************************** |
ibestwill | 0:867c4eabf128 | 235 | |
ibestwill | 0:867c4eabf128 | 236 | void PIController(void){ |
ibestwill | 0:867c4eabf128 | 237 | |
ibestwill | 0:867c4eabf128 | 238 | dPos_R = DE0.write(0x00); |
ibestwill | 0:867c4eabf128 | 239 | dTime_R = DE0.write(0x00); |
ibestwill | 0:867c4eabf128 | 240 | |
ibestwill | 0:867c4eabf128 | 241 | dPos_R = Signextend(dPos_R); |
ibestwill | 0:867c4eabf128 | 242 | |
ibestwill | 0:867c4eabf128 | 243 | |
ibestwill | 0:867c4eabf128 | 244 | Vel_R = (123*dPos_R)/dTime_R; |
ibestwill | 0:867c4eabf128 | 245 | |
ibestwill | 0:867c4eabf128 | 246 | |
ibestwill | 0:867c4eabf128 | 247 | //Error |
ibestwill | 0:867c4eabf128 | 248 | e_R = SatSub(Setspeed_R,Vel_R); |
ibestwill | 0:867c4eabf128 | 249 | //e_R = SatValue(e_R,36); |
ibestwill | 0:867c4eabf128 | 250 | |
ibestwill | 0:867c4eabf128 | 251 | |
ibestwill | 0:867c4eabf128 | 252 | //xtate |
ibestwill | 0:867c4eabf128 | 253 | xT_R = SatAdd(x_R,e_R); |
ibestwill | 0:867c4eabf128 | 254 | //xT_R = SatValue(x_R,xlimit); |
ibestwill | 0:867c4eabf128 | 255 | |
ibestwill | 0:867c4eabf128 | 256 | |
ibestwill | 0:867c4eabf128 | 257 | //proportional and integral control terms |
ibestwill | 0:867c4eabf128 | 258 | uP_R=(Kp_R*e_R); |
ibestwill | 0:867c4eabf128 | 259 | uI_R=(Ki_R*x_R); |
ibestwill | 0:867c4eabf128 | 260 | |
ibestwill | 0:867c4eabf128 | 261 | uS_R = SatAdd(uP_R,uI_R); |
ibestwill | 0:867c4eabf128 | 262 | u_R = SatValue(uS_R,36); |
ibestwill | 0:867c4eabf128 | 263 | |
ibestwill | 0:867c4eabf128 | 264 | if (u_R==uS_R) x_R = xT_R; //Integrator windup prevention |
ibestwill | 0:867c4eabf128 | 265 | |
ibestwill | 0:867c4eabf128 | 266 | if(u_R >= 0) DirR = 1; else DirR = 0; |
ibestwill | 0:867c4eabf128 | 267 | |
ibestwill | 0:867c4eabf128 | 268 | y_R=u_R/36.0*T; |
ibestwill | 0:867c4eabf128 | 269 | PwmR.pulsewidth_us(abs(y_R)); |
ibestwill | 0:867c4eabf128 | 270 | |
ibestwill | 0:867c4eabf128 | 271 | |
ibestwill | 0:867c4eabf128 | 272 | } |
ibestwill | 0:867c4eabf128 | 273 | |
ibestwill | 0:867c4eabf128 | 274 | |
ibestwill | 0:867c4eabf128 | 275 | //************************************************************************** |
ibestwill | 0:867c4eabf128 | 276 | |
ibestwill | 0:867c4eabf128 | 277 | int SatAdd(int x, int y) |
ibestwill | 0:867c4eabf128 | 278 | { |
ibestwill | 0:867c4eabf128 | 279 | // Detect overflow and saturate result |
ibestwill | 0:867c4eabf128 | 280 | int z; |
ibestwill | 0:867c4eabf128 | 281 | z = x + y; |
ibestwill | 0:867c4eabf128 | 282 | if((x > 0) && (y > 0) && (z < 0)) z = 0x7FFFFFFF; |
ibestwill | 0:867c4eabf128 | 283 | else if ((x < 0) && (y < 0) && (z > 0)) z = 0x80000000; |
ibestwill | 0:867c4eabf128 | 284 | return z; |
ibestwill | 0:867c4eabf128 | 285 | } |
ibestwill | 0:867c4eabf128 | 286 | |
ibestwill | 0:867c4eabf128 | 287 | |
ibestwill | 0:867c4eabf128 | 288 | int SatSub(int x, int y) |
ibestwill | 0:867c4eabf128 | 289 | { |
ibestwill | 0:867c4eabf128 | 290 | int z; |
ibestwill | 0:867c4eabf128 | 291 | z = x - y; |
ibestwill | 0:867c4eabf128 | 292 | // 32-bit overflow detection and saturating arithmetic |
ibestwill | 0:867c4eabf128 | 293 | if((x > 0) && (y < 0) && (z < 0)) z = 0x7FFFFFFF; |
ibestwill | 0:867c4eabf128 | 294 | else if((x < 0) && (y > 0) && (z > 0)) z = 0x80000000; |
ibestwill | 0:867c4eabf128 | 295 | return z; |
ibestwill | 0:867c4eabf128 | 296 | } |
ibestwill | 0:867c4eabf128 | 297 | |
ibestwill | 0:867c4eabf128 | 298 | |
ibestwill | 0:867c4eabf128 | 299 | int SatValue(int x, int Limit) |
ibestwill | 0:867c4eabf128 | 300 | { |
ibestwill | 0:867c4eabf128 | 301 | // Impose maximum limit on integrator state |
ibestwill | 0:867c4eabf128 | 302 | if(x > Limit) return(Limit); |
ibestwill | 0:867c4eabf128 | 303 | else if(x < -Limit) return(-Limit); |
ibestwill | 0:867c4eabf128 | 304 | else return(x); |
ibestwill | 0:867c4eabf128 | 305 | } |
ibestwill | 0:867c4eabf128 | 306 | |
ibestwill | 0:867c4eabf128 | 307 | |
ibestwill | 0:867c4eabf128 | 308 | int Signextend(int x) { |
ibestwill | 0:867c4eabf128 | 309 | if (x & 0x00008000) { |
ibestwill | 0:867c4eabf128 | 310 | x = x | 0xFFFF0000; |
ibestwill | 0:867c4eabf128 | 311 | } |
ibestwill | 0:867c4eabf128 | 312 | return x; |
ibestwill | 0:867c4eabf128 | 313 | } |
ibestwill | 0:867c4eabf128 | 314 | |
ibestwill | 0:867c4eabf128 | 315 | //************************************************************************** |
ibestwill | 0:867c4eabf128 | 316 | //************************************************************************** |
ibestwill | 0:867c4eabf128 | 317 | |
ibestwill | 0:867c4eabf128 | 318 | |
ibestwill | 0:867c4eabf128 | 319 | // ******** Control Thread ******** |
ibestwill | 0:867c4eabf128 | 320 | void PiControlThread(void const *argument) |
ibestwill | 0:867c4eabf128 | 321 | { |
ibestwill | 0:867c4eabf128 | 322 | while (true) { |
ibestwill | 0:867c4eabf128 | 323 | osSignalWait(SignalPi, osWaitForever); // Go to sleep until signal, SignalPi, is received. |
ibestwill | 0:867c4eabf128 | 324 | led2= !led2; // Alive status - led2 toggles each time PiControlThread is signaled. |
ibestwill | 0:867c4eabf128 | 325 | |
ibestwill | 0:867c4eabf128 | 326 | PIController(); |
ibestwill | 0:867c4eabf128 | 327 | |
ibestwill | 0:867c4eabf128 | 328 | } |
ibestwill | 0:867c4eabf128 | 329 | } |
ibestwill | 0:867c4eabf128 | 330 | |
ibestwill | 0:867c4eabf128 | 331 | // ******** Collision Thread ******** |
ibestwill | 0:867c4eabf128 | 332 | void ExtCollisionThread(void const *argument) |
ibestwill | 0:867c4eabf128 | 333 | { |
ibestwill | 0:867c4eabf128 | 334 | while (true) { |
ibestwill | 0:867c4eabf128 | 335 | osSignalWait(SignalExtCollision, osWaitForever); // Go to sleep until signal, SignalExtCollision, is received |
ibestwill | 0:867c4eabf128 | 336 | led4 = 1; |
ibestwill | 0:867c4eabf128 | 337 | } |
ibestwill | 0:867c4eabf128 | 338 | } |
ibestwill | 0:867c4eabf128 | 339 | |
ibestwill | 0:867c4eabf128 | 340 | // ******** Watchdog Interrupt Handler ******** |
ibestwill | 0:867c4eabf128 | 341 | void Watchdog(void const *n) |
ibestwill | 0:867c4eabf128 | 342 | { |
ibestwill | 0:867c4eabf128 | 343 | led3=1; // led3 is activated when the watchdog timer times out |
ibestwill | 0:867c4eabf128 | 344 | } |
ibestwill | 0:867c4eabf128 | 345 | |
ibestwill | 0:867c4eabf128 | 346 | // ******** Period Timer Interrupt Handler ******** |
ibestwill | 0:867c4eabf128 | 347 | void PiControllerISR(void) |
ibestwill | 0:867c4eabf128 | 348 | { |
ibestwill | 0:867c4eabf128 | 349 | osSignalSet(PiControl,0x1); // Activate the signal, PiControl, with each periodic timer interrupt. |
ibestwill | 0:867c4eabf128 | 350 | |
ibestwill | 0:867c4eabf128 | 351 | } |
ibestwill | 0:867c4eabf128 | 352 | |
ibestwill | 0:867c4eabf128 | 353 | // ******** Collision Interrupt Handler ******** |
ibestwill | 0:867c4eabf128 | 354 | void ExtCollisionISR(void) |
ibestwill | 0:867c4eabf128 | 355 | { |
ibestwill | 0:867c4eabf128 | 356 | osSignalSet(ExtCollision,0x1); // Activate the signal, ExtCollision, with each pexternal interrupt. |
ibestwill | 0:867c4eabf128 | 357 | } |
ibestwill | 0:867c4eabf128 | 358 | |
ibestwill | 0:867c4eabf128 | 359 | //************************************************************************** |