Stefan Poels
/
MLX8030x_B6PV_Demo
MLX8030x_B6PV_Demo
main.cpp@0:f0d7e4b016ce, 2014-09-05 (annotated)
- Committer:
- StefanP
- Date:
- Fri Sep 05 13:28:28 2014 +0000
- Revision:
- 0:f0d7e4b016ce
MLX8030x_B6PV_Demo
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
StefanP | 0:f0d7e4b016ce | 1 | #include "mbed.h" |
StefanP | 0:f0d7e4b016ce | 2 | #include "LPC17xx.h" |
StefanP | 0:f0d7e4b016ce | 3 | |
StefanP | 0:f0d7e4b016ce | 4 | #define GUI 1 |
StefanP | 0:f0d7e4b016ce | 5 | #define TeraTerm 0 |
StefanP | 0:f0d7e4b016ce | 6 | |
StefanP | 0:f0d7e4b016ce | 7 | LocalFileSystem local("local"); |
StefanP | 0:f0d7e4b016ce | 8 | |
StefanP | 0:f0d7e4b016ce | 9 | Serial pc(USBTX, USBRX); |
StefanP | 0:f0d7e4b016ce | 10 | |
StefanP | 0:f0d7e4b016ce | 11 | DigitalOut LedSpi(LED1); // LED active during SPI communication |
StefanP | 0:f0d7e4b016ce | 12 | PwmOut LedDiagn(LED2); // LED active with duty cycle of B6PV "DIAG"-pin |
StefanP | 0:f0d7e4b016ce | 13 | DigitalOut LedUSB(LED3); // LED active if USB connection is established with GUI |
StefanP | 0:f0d7e4b016ce | 14 | DigitalOut LedApplication(LED4); // LED active when application is running |
StefanP | 0:f0d7e4b016ce | 15 | |
StefanP | 0:f0d7e4b016ce | 16 | PwmOut pwmon(p26); // B6PV "PWMON"-pin |
StefanP | 0:f0d7e4b016ce | 17 | DigitalIn spibusy(p9); // B6PV "SPI_BUSY"-pin |
StefanP | 0:f0d7e4b016ce | 18 | SPI spi(p5, p6, p7); // B6PV "MOSI", "MISO", "CLK"-pins |
StefanP | 0:f0d7e4b016ce | 19 | DigitalOut cs(p8); // B6PV "CS"-pin |
StefanP | 0:f0d7e4b016ce | 20 | |
StefanP | 0:f0d7e4b016ce | 21 | DigitalOut OCsimulation(p24); |
StefanP | 0:f0d7e4b016ce | 22 | |
StefanP | 0:f0d7e4b016ce | 23 | int iPWMPeriod = 1000; // Set initial PWM period to 1000us or 1kHz |
StefanP | 0:f0d7e4b016ce | 24 | float fPWMDutyCycle = 0.0; // Set initial duty cycle to 0.0 or 0% -> OFF |
StefanP | 0:f0d7e4b016ce | 25 | |
StefanP | 0:f0d7e4b016ce | 26 | volatile uint32_t u32DiagnDC = 0; // Duty cycle from the diagnostics input |
StefanP | 0:f0d7e4b016ce | 27 | const uint16_t DUTY_CYCLE_ACCURACY = 1000; // Used to enhance the duty cycle calculation (HighTime * 1000)/Period |
StefanP | 0:f0d7e4b016ce | 28 | volatile uint32_t u32DiagnPeriod = 0; // Period from the diagnostics input |
StefanP | 0:f0d7e4b016ce | 29 | const uint32_t u32DiagnMaxPeriod = 9600000;// Minimum 10Hz diagnostics frequeny (96MHz/10Hz=9.6e6) |
StefanP | 0:f0d7e4b016ce | 30 | volatile uint32_t u32DiagnCapA = 0; // Timer capture for a falling edge of diagnostics input |
StefanP | 0:f0d7e4b016ce | 31 | volatile uint32_t u32DiagnCapB = 0; // Timer capture for a rising edge of diagnostics input |
StefanP | 0:f0d7e4b016ce | 32 | volatile bool bTimer2MR0 = false; // Timer2 reached match register MR0 (used to detect 0% and 100% duty cycle) |
StefanP | 0:f0d7e4b016ce | 33 | |
StefanP | 0:f0d7e4b016ce | 34 | volatile uint32_t u32SpeedCapA = 0; // Timer capture for a 1st edge of speed feedback |
StefanP | 0:f0d7e4b016ce | 35 | volatile uint32_t u32SpeedCapB = 0; // Timer capture for a 2nd edge of speed feedback |
StefanP | 0:f0d7e4b016ce | 36 | volatile uint32_t u32Speed = 0; // Minimum speed |
StefanP | 0:f0d7e4b016ce | 37 | const uint32_t u32SpeedMaxPeriod= 16000000;// Minum 1eHz = 6Hz commutation speed (96MHz/6Hz=16e6) |
StefanP | 0:f0d7e4b016ce | 38 | volatile bool bTimer2MR1 = false; // Timer2 reached match register MR1 (used to detect 0eHz speed = motor still) |
StefanP | 0:f0d7e4b016ce | 39 | |
StefanP | 0:f0d7e4b016ce | 40 | bool bUsbConnected = false; // Boolean to indicate USB connection with GUI |
StefanP | 0:f0d7e4b016ce | 41 | |
StefanP | 0:f0d7e4b016ce | 42 | void SpiInit(void); // SPI initialization |
StefanP | 0:f0d7e4b016ce | 43 | void Timer2Init(void); // Timer 2 initialization |
StefanP | 0:f0d7e4b016ce | 44 | void SerialUSBInit(void); // Serial USB intialization |
StefanP | 0:f0d7e4b016ce | 45 | void TIMER2_IRQHandler(void); // Timer 2 interrupt handler for determining diagnostics duty cycle |
StefanP | 0:f0d7e4b016ce | 46 | uint32_t TransceiveSpiFrame(uint32_t); // Transceive one SPI frame: Transmit MOSI - Receive MISO |
StefanP | 0:f0d7e4b016ce | 47 | |
StefanP | 0:f0d7e4b016ce | 48 | int main() { |
StefanP | 0:f0d7e4b016ce | 49 | |
StefanP | 0:f0d7e4b016ce | 50 | SpiInit(); |
StefanP | 0:f0d7e4b016ce | 51 | Timer2Init(); |
StefanP | 0:f0d7e4b016ce | 52 | SerialUSBInit(); |
StefanP | 0:f0d7e4b016ce | 53 | |
StefanP | 0:f0d7e4b016ce | 54 | int iCnt = 0; |
StefanP | 0:f0d7e4b016ce | 55 | uint32_t u32SPIframe = 0; |
StefanP | 0:f0d7e4b016ce | 56 | uint32_t u32result = 0; |
StefanP | 0:f0d7e4b016ce | 57 | |
StefanP | 0:f0d7e4b016ce | 58 | pwmon.period_us(iPWMPeriod); |
StefanP | 0:f0d7e4b016ce | 59 | pwmon.write(fPWMDutyCycle); |
StefanP | 0:f0d7e4b016ce | 60 | |
StefanP | 0:f0d7e4b016ce | 61 | while(1) |
StefanP | 0:f0d7e4b016ce | 62 | { |
StefanP | 0:f0d7e4b016ce | 63 | LedApplication = 1; |
StefanP | 0:f0d7e4b016ce | 64 | LedDiagn = float(u32DiagnDC)/DUTY_CYCLE_ACCURACY; |
StefanP | 0:f0d7e4b016ce | 65 | |
StefanP | 0:f0d7e4b016ce | 66 | #if GUI |
StefanP | 0:f0d7e4b016ce | 67 | char strCommand[8]; |
StefanP | 0:f0d7e4b016ce | 68 | if (pc.readable()) |
StefanP | 0:f0d7e4b016ce | 69 | { |
StefanP | 0:f0d7e4b016ce | 70 | int err = pc.scanf("%s",&strCommand); |
StefanP | 0:f0d7e4b016ce | 71 | if ((strCommand[0] == 'I') && (strCommand[1] == 'D')) |
StefanP | 0:f0d7e4b016ce | 72 | { |
StefanP | 0:f0d7e4b016ce | 73 | if (pc.writeable()) |
StefanP | 0:f0d7e4b016ce | 74 | pc.printf("MBED\n"); |
StefanP | 0:f0d7e4b016ce | 75 | |
StefanP | 0:f0d7e4b016ce | 76 | int err = pc.scanf("%s",&strCommand); |
StefanP | 0:f0d7e4b016ce | 77 | if ((strCommand[0] == 'O') && (strCommand[1] == 'K')) |
StefanP | 0:f0d7e4b016ce | 78 | { |
StefanP | 0:f0d7e4b016ce | 79 | bUsbConnected = true; |
StefanP | 0:f0d7e4b016ce | 80 | LedUSB = 1; |
StefanP | 0:f0d7e4b016ce | 81 | } |
StefanP | 0:f0d7e4b016ce | 82 | } |
StefanP | 0:f0d7e4b016ce | 83 | else if (strCommand[0] == 'X') |
StefanP | 0:f0d7e4b016ce | 84 | { |
StefanP | 0:f0d7e4b016ce | 85 | bUsbConnected = false; |
StefanP | 0:f0d7e4b016ce | 86 | LedUSB = 0; |
StefanP | 0:f0d7e4b016ce | 87 | } |
StefanP | 0:f0d7e4b016ce | 88 | } |
StefanP | 0:f0d7e4b016ce | 89 | #endif //GUI |
StefanP | 0:f0d7e4b016ce | 90 | |
StefanP | 0:f0d7e4b016ce | 91 | #ifdef TeraTerm |
StefanP | 0:f0d7e4b016ce | 92 | char c = pc.getc(); |
StefanP | 0:f0d7e4b016ce | 93 | switch (c) |
StefanP | 0:f0d7e4b016ce | 94 | { |
StefanP | 0:f0d7e4b016ce | 95 | case '\r': // If 'enter' is pressed, send the SPI MOSI-frame |
StefanP | 0:f0d7e4b016ce | 96 | if (!spibusy) |
StefanP | 0:f0d7e4b016ce | 97 | { |
StefanP | 0:f0d7e4b016ce | 98 | // Show SPI communication active via LED |
StefanP | 0:f0d7e4b016ce | 99 | LedSpi = 1; |
StefanP | 0:f0d7e4b016ce | 100 | wait(0.1); |
StefanP | 0:f0d7e4b016ce | 101 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 102 | LedSpi = 0; |
StefanP | 0:f0d7e4b016ce | 103 | |
StefanP | 0:f0d7e4b016ce | 104 | pc.printf("\nThe SPI MOSI-frame send = 0x%.8X \n", u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 105 | pc.printf("The SPI MISO-frame received = 0x%.8X\n", u32result); |
StefanP | 0:f0d7e4b016ce | 106 | |
StefanP | 0:f0d7e4b016ce | 107 | iCnt = 0; |
StefanP | 0:f0d7e4b016ce | 108 | //u32SPIframe = 0; |
StefanP | 0:f0d7e4b016ce | 109 | } |
StefanP | 0:f0d7e4b016ce | 110 | else |
StefanP | 0:f0d7e4b016ce | 111 | { |
StefanP | 0:f0d7e4b016ce | 112 | pc.printf("\nSPI busy \nPress enter to try again \n"); |
StefanP | 0:f0d7e4b016ce | 113 | } |
StefanP | 0:f0d7e4b016ce | 114 | |
StefanP | 0:f0d7e4b016ce | 115 | pc.printf("The diagnostics frequency is %uHz \n", SystemCoreClock/u32DiagnPeriod); |
StefanP | 0:f0d7e4b016ce | 116 | pc.printf("The diagnostics duty cycle is %.1f%%\n\n", float(u32DiagnDC)/DUTY_CYCLE_ACCURACY*100); |
StefanP | 0:f0d7e4b016ce | 117 | //pc.printf("The speed is %u eHz \n", u32Speed); |
StefanP | 0:f0d7e4b016ce | 118 | |
StefanP | 0:f0d7e4b016ce | 119 | break; |
StefanP | 0:f0d7e4b016ce | 120 | |
StefanP | 0:f0d7e4b016ce | 121 | case '1': // Set '1' in SPI MOSI-frame to be send |
StefanP | 0:f0d7e4b016ce | 122 | if (iCnt == 0) |
StefanP | 0:f0d7e4b016ce | 123 | u32SPIframe = (1<<31); |
StefanP | 0:f0d7e4b016ce | 124 | else |
StefanP | 0:f0d7e4b016ce | 125 | u32SPIframe |= (1<<(31-iCnt)); // shift bits: first entered is MSB |
StefanP | 0:f0d7e4b016ce | 126 | iCnt++; |
StefanP | 0:f0d7e4b016ce | 127 | pc.printf("%c",c); // print entered character |
StefanP | 0:f0d7e4b016ce | 128 | if (iCnt > 31) // 32-bits can be entered (circular) |
StefanP | 0:f0d7e4b016ce | 129 | iCnt = 0; |
StefanP | 0:f0d7e4b016ce | 130 | else if (((iCnt) % 4) == 0) // print space every 4-bits |
StefanP | 0:f0d7e4b016ce | 131 | pc.printf(" "); |
StefanP | 0:f0d7e4b016ce | 132 | break; |
StefanP | 0:f0d7e4b016ce | 133 | |
StefanP | 0:f0d7e4b016ce | 134 | case '0': // Set '0' in SPI MOSI-frame to be send |
StefanP | 0:f0d7e4b016ce | 135 | if (iCnt == 0) |
StefanP | 0:f0d7e4b016ce | 136 | u32SPIframe = 0; |
StefanP | 0:f0d7e4b016ce | 137 | else |
StefanP | 0:f0d7e4b016ce | 138 | u32SPIframe &=~ (1<<(31-iCnt)); // shift bits: first entered is MSB |
StefanP | 0:f0d7e4b016ce | 139 | iCnt++; |
StefanP | 0:f0d7e4b016ce | 140 | pc.printf("%c",c); // print entered character |
StefanP | 0:f0d7e4b016ce | 141 | if (iCnt > 31) // 32-bits can be entered (circular) |
StefanP | 0:f0d7e4b016ce | 142 | iCnt = 0; |
StefanP | 0:f0d7e4b016ce | 143 | else if (((iCnt) % 4) == 0) // print space every 4-bits |
StefanP | 0:f0d7e4b016ce | 144 | pc.printf(" "); |
StefanP | 0:f0d7e4b016ce | 145 | break; |
StefanP | 0:f0d7e4b016ce | 146 | |
StefanP | 0:f0d7e4b016ce | 147 | case 'h': // PWM higher frequency |
StefanP | 0:f0d7e4b016ce | 148 | if ((iPWMPeriod - 10) > 100) // max 10kHz or 100us |
StefanP | 0:f0d7e4b016ce | 149 | { iPWMPeriod -= 10;} |
StefanP | 0:f0d7e4b016ce | 150 | else |
StefanP | 0:f0d7e4b016ce | 151 | { iPWMPeriod = 100;} |
StefanP | 0:f0d7e4b016ce | 152 | pwmon.period_us(iPWMPeriod); |
StefanP | 0:f0d7e4b016ce | 153 | pwmon.write(fPWMDutyCycle); // bug in mbed that duty cycle is not maintained on update of period |
StefanP | 0:f0d7e4b016ce | 154 | break; |
StefanP | 0:f0d7e4b016ce | 155 | |
StefanP | 0:f0d7e4b016ce | 156 | case 'l': // PWM lower frequency |
StefanP | 0:f0d7e4b016ce | 157 | if ((iPWMPeriod + 10) < 10000) // min 100Hz or 10000us |
StefanP | 0:f0d7e4b016ce | 158 | { iPWMPeriod += 10;} |
StefanP | 0:f0d7e4b016ce | 159 | else |
StefanP | 0:f0d7e4b016ce | 160 | { iPWMPeriod = 10000;} |
StefanP | 0:f0d7e4b016ce | 161 | pwmon.period_us(iPWMPeriod); |
StefanP | 0:f0d7e4b016ce | 162 | pwmon.write(fPWMDutyCycle); // bug in mbed that duty cycle is not maintained on update of period |
StefanP | 0:f0d7e4b016ce | 163 | break; |
StefanP | 0:f0d7e4b016ce | 164 | |
StefanP | 0:f0d7e4b016ce | 165 | case 'b': // PWM bigger duty cycle |
StefanP | 0:f0d7e4b016ce | 166 | if ((fPWMDutyCycle + 0.001) < 1) // max 100% duty cycle |
StefanP | 0:f0d7e4b016ce | 167 | { fPWMDutyCycle += 0.001;} |
StefanP | 0:f0d7e4b016ce | 168 | else |
StefanP | 0:f0d7e4b016ce | 169 | { fPWMDutyCycle = 1;} |
StefanP | 0:f0d7e4b016ce | 170 | pwmon.write(fPWMDutyCycle); |
StefanP | 0:f0d7e4b016ce | 171 | break; |
StefanP | 0:f0d7e4b016ce | 172 | |
StefanP | 0:f0d7e4b016ce | 173 | case 's': // PWM smaller duty cycle |
StefanP | 0:f0d7e4b016ce | 174 | if ((fPWMDutyCycle - 0.001) > 0) // min 0% duty cycle |
StefanP | 0:f0d7e4b016ce | 175 | { fPWMDutyCycle -= 0.001;} |
StefanP | 0:f0d7e4b016ce | 176 | else |
StefanP | 0:f0d7e4b016ce | 177 | { fPWMDutyCycle = 0;} |
StefanP | 0:f0d7e4b016ce | 178 | pwmon.write(fPWMDutyCycle); |
StefanP | 0:f0d7e4b016ce | 179 | break; |
StefanP | 0:f0d7e4b016ce | 180 | |
StefanP | 0:f0d7e4b016ce | 181 | case 'r': // read |
StefanP | 0:f0d7e4b016ce | 182 | //pc.printf("Read FPGA register 1"); |
StefanP | 0:f0d7e4b016ce | 183 | //u32SPIframe = 0xCF020000; |
StefanP | 0:f0d7e4b016ce | 184 | //u32SPIframe |= (1<<16); |
StefanP | 0:f0d7e4b016ce | 185 | //u32SPIframe |= 0x00000000; |
StefanP | 0:f0d7e4b016ce | 186 | u32result = TransceiveSpiFrame(0xCF090000);//(0xCC290000); |
StefanP | 0:f0d7e4b016ce | 187 | pc.printf("Read FPGA register 4 returns 0x%.8X \n",u32result); |
StefanP | 0:f0d7e4b016ce | 188 | |
StefanP | 0:f0d7e4b016ce | 189 | break; |
StefanP | 0:f0d7e4b016ce | 190 | |
StefanP | 0:f0d7e4b016ce | 191 | case 'w': //write |
StefanP | 0:f0d7e4b016ce | 192 | //pc.printf("Write 0xA16C to FPGA register 1"); |
StefanP | 0:f0d7e4b016ce | 193 | //u32SPIframe = 0xCF020000; |
StefanP | 0:f0d7e4b016ce | 194 | //u32SPIframe |= (0<<16); |
StefanP | 0:f0d7e4b016ce | 195 | //u32SPIframe |= 0x0000A16C; |
StefanP | 0:f0d7e4b016ce | 196 | u32result = TransceiveSpiFrame(0xCF083182);//(0xCC28FFFF); |
StefanP | 0:f0d7e4b016ce | 197 | pc.printf("Write FPGA register 4 returns 0x%.8X \n",u32result); |
StefanP | 0:f0d7e4b016ce | 198 | break; |
StefanP | 0:f0d7e4b016ce | 199 | |
StefanP | 0:f0d7e4b016ce | 200 | case 'i': // read ID from B6PV |
StefanP | 0:f0d7e4b016ce | 201 | u32result = TransceiveSpiFrame(0xCC810000); |
StefanP | 0:f0d7e4b016ce | 202 | if (u32result == 0x00000000) |
StefanP | 0:f0d7e4b016ce | 203 | pc.printf("B6PV - DOE1 \n"); |
StefanP | 0:f0d7e4b016ce | 204 | else if (u32result == 0x00000001) |
StefanP | 0:f0d7e4b016ce | 205 | pc.printf("B6PV - DOE2 \n"); |
StefanP | 0:f0d7e4b016ce | 206 | else if (u32result == 0x00000002) |
StefanP | 0:f0d7e4b016ce | 207 | pc.printf("B6PV - DOE3 \n"); |
StefanP | 0:f0d7e4b016ce | 208 | else if (u32result == 0x00000003) |
StefanP | 0:f0d7e4b016ce | 209 | pc.printf("B6PV - DOE4 \n"); |
StefanP | 0:f0d7e4b016ce | 210 | else |
StefanP | 0:f0d7e4b016ce | 211 | pc.printf("B6PV - Read ID error \n B6PV returns 0x%.8X \n",u32result); |
StefanP | 0:f0d7e4b016ce | 212 | break; |
StefanP | 0:f0d7e4b016ce | 213 | |
StefanP | 0:f0d7e4b016ce | 214 | case 't': // trim B6PV and configure FPGA |
StefanP | 0:f0d7e4b016ce | 215 | u32result = TransceiveSpiFrame(0xCC0A0001); // DOE1_IC5_TRIM_VDDA |
StefanP | 0:f0d7e4b016ce | 216 | u32result = TransceiveSpiFrame(0xCC0C0001); // DOE1_IC5_TRIM_VDDD |
StefanP | 0:f0d7e4b016ce | 217 | u32result = TransceiveSpiFrame(0xCC0E0001); // DOE1_IC5_TRIM_VBG |
StefanP | 0:f0d7e4b016ce | 218 | u32result = TransceiveSpiFrame(0xCC100004); // DOE1_IC5_TRIM_IBIAS |
StefanP | 0:f0d7e4b016ce | 219 | u32result = TransceiveSpiFrame(0xCC3A0016); // DOE1_IC5_TRIM_RCO |
StefanP | 0:f0d7e4b016ce | 220 | |
StefanP | 0:f0d7e4b016ce | 221 | u32result = TransceiveSpiFrame(0xCF000200); // Set PWM mode |
StefanP | 0:f0d7e4b016ce | 222 | u32result = TransceiveSpiFrame(0xCF02FFFF); // Set current limit to max |
StefanP | 0:f0d7e4b016ce | 223 | u32result = TransceiveSpiFrame(0xCF04FFFF); // Set current limit to max |
StefanP | 0:f0d7e4b016ce | 224 | u32result = TransceiveSpiFrame(0xCF06FFFF); // Set |
StefanP | 0:f0d7e4b016ce | 225 | u32result = TransceiveSpiFrame(0xCF083182); // Set ALIGN1-2_TIME, STEP1_TIME |
StefanP | 0:f0d7e4b016ce | 226 | u32result = TransceiveSpiFrame(0xCF0A0CE9); // Set STEP2-4_TIME |
StefanP | 0:f0d7e4b016ce | 227 | u32result = TransceiveSpiFrame(0xCF0C0010); // Set wait time to ??? |
StefanP | 0:f0d7e4b016ce | 228 | u32result = TransceiveSpiFrame(0xCF0E0000); // Set timer6-7 |
StefanP | 0:f0d7e4b016ce | 229 | u32result = TransceiveSpiFrame(0xCF100000); // Set CW |
StefanP | 0:f0d7e4b016ce | 230 | u32result = TransceiveSpiFrame(0xCF120003); // Set rotor trials to 3 |
StefanP | 0:f0d7e4b016ce | 231 | |
StefanP | 0:f0d7e4b016ce | 232 | u32result = TransceiveSpiFrame(0xCF3A0001); // Set EE_READY |
StefanP | 0:f0d7e4b016ce | 233 | |
StefanP | 0:f0d7e4b016ce | 234 | pc.printf("\nTrimming of B6PV and start-up configuration in FPGA done \n"); |
StefanP | 0:f0d7e4b016ce | 235 | break; |
StefanP | 0:f0d7e4b016ce | 236 | |
StefanP | 0:f0d7e4b016ce | 237 | case 'g': // trim B6PV and configure FPGA |
StefanP | 0:f0d7e4b016ce | 238 | if (fPWMDutyCycle == 0) |
StefanP | 0:f0d7e4b016ce | 239 | { |
StefanP | 0:f0d7e4b016ce | 240 | fPWMDutyCycle = 0.5; |
StefanP | 0:f0d7e4b016ce | 241 | pwmon.write(fPWMDutyCycle); |
StefanP | 0:f0d7e4b016ce | 242 | } |
StefanP | 0:f0d7e4b016ce | 243 | else |
StefanP | 0:f0d7e4b016ce | 244 | { |
StefanP | 0:f0d7e4b016ce | 245 | fPWMDutyCycle = 0.0; |
StefanP | 0:f0d7e4b016ce | 246 | pwmon.write(fPWMDutyCycle); |
StefanP | 0:f0d7e4b016ce | 247 | } |
StefanP | 0:f0d7e4b016ce | 248 | pc.printf("\nSet PWM/ON to %1.1f%% duty cycle on PWM-ON pin\n",fPWMDutyCycle*100); |
StefanP | 0:f0d7e4b016ce | 249 | |
StefanP | 0:f0d7e4b016ce | 250 | break; |
StefanP | 0:f0d7e4b016ce | 251 | |
StefanP | 0:f0d7e4b016ce | 252 | case 'n': //write to FPGA to turn LED on |
StefanP | 0:f0d7e4b016ce | 253 | u32SPIframe = 0xCF3E8000; |
StefanP | 0:f0d7e4b016ce | 254 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 255 | pc.printf("\nLED on \n"); |
StefanP | 0:f0d7e4b016ce | 256 | break; |
StefanP | 0:f0d7e4b016ce | 257 | |
StefanP | 0:f0d7e4b016ce | 258 | case 'f': //write to FPGA to turn LED off |
StefanP | 0:f0d7e4b016ce | 259 | u32SPIframe = 0xCF3E0000;//0xCF3E0000; |
StefanP | 0:f0d7e4b016ce | 260 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 261 | pc.printf("\nLED off \n"); |
StefanP | 0:f0d7e4b016ce | 262 | break; |
StefanP | 0:f0d7e4b016ce | 263 | |
StefanP | 0:f0d7e4b016ce | 264 | case '2': //write to FPGA to turn LED off |
StefanP | 0:f0d7e4b016ce | 265 | u32SPIframe = 0xCF360081; |
StefanP | 0:f0d7e4b016ce | 266 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 267 | pc.printf("\nInduce soft error 0 by sending MOSI frame = 0x%.8X \n", u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 268 | break; |
StefanP | 0:f0d7e4b016ce | 269 | case '3': //write to FPGA to turn LED off |
StefanP | 0:f0d7e4b016ce | 270 | u32SPIframe = 0xCF360082; |
StefanP | 0:f0d7e4b016ce | 271 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 272 | pc.printf("\nInduce soft error 1 by sending MOSI frame = 0x%.8X \n", u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 273 | break; |
StefanP | 0:f0d7e4b016ce | 274 | case '4': //write to FPGA to turn LED off |
StefanP | 0:f0d7e4b016ce | 275 | u32SPIframe = 0xCF360084; |
StefanP | 0:f0d7e4b016ce | 276 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 277 | pc.printf("\nInduce soft error 2 by sending MOSI frame = 0x%.8X \n", u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 278 | break; |
StefanP | 0:f0d7e4b016ce | 279 | case '5': //write to FPGA to turn LED off |
StefanP | 0:f0d7e4b016ce | 280 | u32SPIframe = 0xCF360088; |
StefanP | 0:f0d7e4b016ce | 281 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 282 | pc.printf("\nInduce soft error 3 by sending MOSI frame = 0x%.8X \n", u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 283 | break; |
StefanP | 0:f0d7e4b016ce | 284 | case '6': //write to FPGA to turn LED off |
StefanP | 0:f0d7e4b016ce | 285 | u32SPIframe = 0xCF360090; |
StefanP | 0:f0d7e4b016ce | 286 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 287 | pc.printf("\nInduce soft error 4 by sending MOSI frame = 0x%.8X \n", u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 288 | break; |
StefanP | 0:f0d7e4b016ce | 289 | case '7': //write to FPGA to turn LED off |
StefanP | 0:f0d7e4b016ce | 290 | u32SPIframe = 0xCF3600A0; |
StefanP | 0:f0d7e4b016ce | 291 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 292 | pc.printf("\nInduce soft error 5 by sending MOSI frame = 0x%.8X \n", u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 293 | break; |
StefanP | 0:f0d7e4b016ce | 294 | case '8': //write to FPGA to turn LED off |
StefanP | 0:f0d7e4b016ce | 295 | u32SPIframe = 0xCF3600C0; |
StefanP | 0:f0d7e4b016ce | 296 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 297 | pc.printf("\nInduce soft error 6 by sending MOSI frame = 0x%.8X \n", u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 298 | break; |
StefanP | 0:f0d7e4b016ce | 299 | case '9': //write to FPGA to turn LED off |
StefanP | 0:f0d7e4b016ce | 300 | u32SPIframe = 0xCF3600FF; |
StefanP | 0:f0d7e4b016ce | 301 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 302 | wait(0.0011); |
StefanP | 0:f0d7e4b016ce | 303 | u32SPIframe = 0xCF360080; |
StefanP | 0:f0d7e4b016ce | 304 | u32result = TransceiveSpiFrame(u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 305 | pc.printf("\nInduce all soft errors by sending MOSI frame = 0x%.8X followed by removing all soft errors \n", u32SPIframe); |
StefanP | 0:f0d7e4b016ce | 306 | break; |
StefanP | 0:f0d7e4b016ce | 307 | |
StefanP | 0:f0d7e4b016ce | 308 | case 'o': // give a pulse on FPGA OC-pin to simulate over current error |
StefanP | 0:f0d7e4b016ce | 309 | OCsimulation = 1; |
StefanP | 0:f0d7e4b016ce | 310 | wait(0.0001); |
StefanP | 0:f0d7e4b016ce | 311 | OCsimulation = 0; |
StefanP | 0:f0d7e4b016ce | 312 | break; |
StefanP | 0:f0d7e4b016ce | 313 | |
StefanP | 0:f0d7e4b016ce | 314 | case 'a': //try to write 0xFFFF to all FPGA register addresses [31:0] |
StefanP | 0:f0d7e4b016ce | 315 | int iSpiErrCnt = 0; |
StefanP | 0:f0d7e4b016ce | 316 | for (uint32_t i3=0; i3<0x0000FFFF; i3+=0x00000155) |
StefanP | 0:f0d7e4b016ce | 317 | { |
StefanP | 0:f0d7e4b016ce | 318 | uint32_t u32MosiWriteFrame = 0xCF000000; |
StefanP | 0:f0d7e4b016ce | 319 | uint32_t u32MosiReadFrame = 0xCF010000; |
StefanP | 0:f0d7e4b016ce | 320 | pc.printf("Using data 0x%.8X to test read instruction \n", i3); |
StefanP | 0:f0d7e4b016ce | 321 | for (int i2=0; i2<32; i2++) |
StefanP | 0:f0d7e4b016ce | 322 | { |
StefanP | 0:f0d7e4b016ce | 323 | //pc.printf("Testing address %i\n", i2); |
StefanP | 0:f0d7e4b016ce | 324 | for (int i1=0; i1<0x0000FFFF; i1++) |
StefanP | 0:f0d7e4b016ce | 325 | { |
StefanP | 0:f0d7e4b016ce | 326 | uint32_t u32MisoWriteFrame = TransceiveSpiFrame(u32MosiWriteFrame+i1); |
StefanP | 0:f0d7e4b016ce | 327 | //pc.printf("The SPI MOSI-frame to write = 0x%.8X \nThe SPI MISO-frame received = 0x%.8X \n", u32SPIframe,u32result); |
StefanP | 0:f0d7e4b016ce | 328 | wait(0.00001); |
StefanP | 0:f0d7e4b016ce | 329 | uint32_t u32MisoReadFrame = TransceiveSpiFrame(u32MosiReadFrame+i3); |
StefanP | 0:f0d7e4b016ce | 330 | //pc.printf("The SPI MOSI-frame to read = 0x%.8X \nThe SPI MISO-frame received = 0x%.8X \n", u32SPIframe,u32result); |
StefanP | 0:f0d7e4b016ce | 331 | if ((u32MisoReadFrame & 0x0000FFFF) != i1) |
StefanP | 0:f0d7e4b016ce | 332 | { |
StefanP | 0:f0d7e4b016ce | 333 | iSpiErrCnt++; |
StefanP | 0:f0d7e4b016ce | 334 | pc.printf("The SPI MOSI-frame to write = 0x%.8X \nThe SPI MISO-frame received to write = 0x%.8X \n", u32MosiWriteFrame+i1,u32MisoWriteFrame); |
StefanP | 0:f0d7e4b016ce | 335 | pc.printf("The SPI MOSI-frame to read = 0x%.8X \nThe SPI MISO-frame received to read = 0x%.8X \n", u32MosiReadFrame+i3,u32MisoReadFrame); |
StefanP | 0:f0d7e4b016ce | 336 | } |
StefanP | 0:f0d7e4b016ce | 337 | } |
StefanP | 0:f0d7e4b016ce | 338 | u32MosiWriteFrame += 0x00020000; |
StefanP | 0:f0d7e4b016ce | 339 | u32MosiReadFrame += 0x00020000; |
StefanP | 0:f0d7e4b016ce | 340 | } |
StefanP | 0:f0d7e4b016ce | 341 | pc.printf("The number of SPI errors = %i \n", iSpiErrCnt); |
StefanP | 0:f0d7e4b016ce | 342 | } |
StefanP | 0:f0d7e4b016ce | 343 | break; |
StefanP | 0:f0d7e4b016ce | 344 | |
StefanP | 0:f0d7e4b016ce | 345 | case 'p': //PWM decoder test [31:0] |
StefanP | 0:f0d7e4b016ce | 346 | u32result = TransceiveSpiFrame(0xCF000200); |
StefanP | 0:f0d7e4b016ce | 347 | FILE *Datalogging = fopen("/local/PWMDecoder.csv", "w"); |
StefanP | 0:f0d7e4b016ce | 348 | for (int i1=10000; i1>80; i1=i1*0.90) |
StefanP | 0:f0d7e4b016ce | 349 | { |
StefanP | 0:f0d7e4b016ce | 350 | pwmon.period_us(i1); |
StefanP | 0:f0d7e4b016ce | 351 | for (float f1=0.2; f1>0; f1-=0.001) |
StefanP | 0:f0d7e4b016ce | 352 | { |
StefanP | 0:f0d7e4b016ce | 353 | pwmon.write(f1); |
StefanP | 0:f0d7e4b016ce | 354 | //float fWaitTime = (float)(i1*5)/(1000000); |
StefanP | 0:f0d7e4b016ce | 355 | wait(0.1); |
StefanP | 0:f0d7e4b016ce | 356 | fprintf(Datalogging, "%i-%.4f+%u*%.2f\n", i1,f1,u32DiagnPeriod,float(u32DiagnDC)/DUTY_CYCLE_ACCURACY*100); |
StefanP | 0:f0d7e4b016ce | 357 | } |
StefanP | 0:f0d7e4b016ce | 358 | for (float f1=0.0; f1<=1.001; f1+=0.001) |
StefanP | 0:f0d7e4b016ce | 359 | { |
StefanP | 0:f0d7e4b016ce | 360 | pwmon.write(f1); |
StefanP | 0:f0d7e4b016ce | 361 | //float fWaitTime = (float)(i1*5)/(1000000); |
StefanP | 0:f0d7e4b016ce | 362 | wait(0.1); |
StefanP | 0:f0d7e4b016ce | 363 | fprintf(Datalogging, "%i-%.4f+%u*%.2f\n", i1,f1,u32DiagnPeriod,float(u32DiagnDC)/DUTY_CYCLE_ACCURACY*100); |
StefanP | 0:f0d7e4b016ce | 364 | } |
StefanP | 0:f0d7e4b016ce | 365 | } |
StefanP | 0:f0d7e4b016ce | 366 | fclose(Datalogging); |
StefanP | 0:f0d7e4b016ce | 367 | break; |
StefanP | 0:f0d7e4b016ce | 368 | |
StefanP | 0:f0d7e4b016ce | 369 | |
StefanP | 0:f0d7e4b016ce | 370 | } |
StefanP | 0:f0d7e4b016ce | 371 | #endif //TeraTerm |
StefanP | 0:f0d7e4b016ce | 372 | } |
StefanP | 0:f0d7e4b016ce | 373 | } |
StefanP | 0:f0d7e4b016ce | 374 | |
StefanP | 0:f0d7e4b016ce | 375 | |
StefanP | 0:f0d7e4b016ce | 376 | /* ************************************************************************************** |
StefanP | 0:f0d7e4b016ce | 377 | * Setup the spi for 16 bit data, high steady state clock, |
StefanP | 0:f0d7e4b016ce | 378 | * base value of the clock is zero CPOL = 0 |
StefanP | 0:f0d7e4b016ce | 379 | * data captured on the rising edge and data propagated on a falling edge = CPHA = 0 |
StefanP | 0:f0d7e4b016ce | 380 | * SPImode = [CPOL CPHA] = [01] = 1 |
StefanP | 0:f0d7e4b016ce | 381 | * with a 1MHz clock rate |
StefanP | 0:f0d7e4b016ce | 382 | ****************************************************************************************/ |
StefanP | 0:f0d7e4b016ce | 383 | |
StefanP | 0:f0d7e4b016ce | 384 | void SpiInit() { |
StefanP | 0:f0d7e4b016ce | 385 | cs = 1; |
StefanP | 0:f0d7e4b016ce | 386 | spi.format(16,0); |
StefanP | 0:f0d7e4b016ce | 387 | spi.frequency(1000000); |
StefanP | 0:f0d7e4b016ce | 388 | } |
StefanP | 0:f0d7e4b016ce | 389 | |
StefanP | 0:f0d7e4b016ce | 390 | |
StefanP | 0:f0d7e4b016ce | 391 | uint32_t TransceiveSpiFrame(uint32_t u32MosiMessage){ |
StefanP | 0:f0d7e4b016ce | 392 | |
StefanP | 0:f0d7e4b016ce | 393 | // LPC_PINCON->PINSEL0 &=~ 0x0000C000; // Set p7(=P0.7) to GPIO mode |
StefanP | 0:f0d7e4b016ce | 394 | // LPC_GPIO0->FIODIR |= (1<<7); // Set p7 as output |
StefanP | 0:f0d7e4b016ce | 395 | // LPC_GPIO0->FIOSET = (1<<7); // Set p7 high |
StefanP | 0:f0d7e4b016ce | 396 | // LPC_GPIO0->FIOCLR = (1<<7); // Set p7 low |
StefanP | 0:f0d7e4b016ce | 397 | // LPC_PINCON->PINSEL0 |= 0x00008000; // Set p7(=P0.7) to SPI-SCK mode |
StefanP | 0:f0d7e4b016ce | 398 | |
StefanP | 0:f0d7e4b016ce | 399 | // Select the device by seting chip select low |
StefanP | 0:f0d7e4b016ce | 400 | cs = 0; |
StefanP | 0:f0d7e4b016ce | 401 | |
StefanP | 0:f0d7e4b016ce | 402 | // Send first 16 bit of 32-bit frame |
StefanP | 0:f0d7e4b016ce | 403 | uint32_t u32MisoMessage = (spi.write((uint16_t)(u32MosiMessage>>16))<<16); |
StefanP | 0:f0d7e4b016ce | 404 | |
StefanP | 0:f0d7e4b016ce | 405 | // Send second 16 bit of 32-bit frame |
StefanP | 0:f0d7e4b016ce | 406 | u32MisoMessage |= spi.write((uint16_t)(u32MosiMessage)); |
StefanP | 0:f0d7e4b016ce | 407 | |
StefanP | 0:f0d7e4b016ce | 408 | // Deselect the device |
StefanP | 0:f0d7e4b016ce | 409 | wait(0.0000000000000001); |
StefanP | 0:f0d7e4b016ce | 410 | cs = 1; |
StefanP | 0:f0d7e4b016ce | 411 | |
StefanP | 0:f0d7e4b016ce | 412 | return u32MisoMessage; |
StefanP | 0:f0d7e4b016ce | 413 | } |
StefanP | 0:f0d7e4b016ce | 414 | |
StefanP | 0:f0d7e4b016ce | 415 | /* ************************************************************************************** |
StefanP | 0:f0d7e4b016ce | 416 | * Setup the spi for 16 bit data, high steady state clock, |
StefanP | 0:f0d7e4b016ce | 417 | * base value of the clock is zero CPOL = 0 |
StefanP | 0:f0d7e4b016ce | 418 | * data captured on the falling edge and data propagated on a rising edge = CPHA = 1 |
StefanP | 0:f0d7e4b016ce | 419 | * SPImode = [CPOL CPHA] = [01] = 1 |
StefanP | 0:f0d7e4b016ce | 420 | * with a 1MHz clock rate |
StefanP | 0:f0d7e4b016ce | 421 | ****************************************************************************************/ |
StefanP | 0:f0d7e4b016ce | 422 | |
StefanP | 0:f0d7e4b016ce | 423 | void SerialUSBInit() { |
StefanP | 0:f0d7e4b016ce | 424 | pc.format(8, Serial::None, 1); |
StefanP | 0:f0d7e4b016ce | 425 | pc.baud(9600); |
StefanP | 0:f0d7e4b016ce | 426 | } |
StefanP | 0:f0d7e4b016ce | 427 | |
StefanP | 0:f0d7e4b016ce | 428 | |
StefanP | 0:f0d7e4b016ce | 429 | /* ************************************************************************************** |
StefanP | 0:f0d7e4b016ce | 430 | * Setup TIMER2 to capture edges on two seperate channels |
StefanP | 0:f0d7e4b016ce | 431 | * - Channel 0 : B6PV "DIAG"-pin |
StefanP | 0:f0d7e4b016ce | 432 | * Capture alternating rising/falling edge to determine duty cycle |
StefanP | 0:f0d7e4b016ce | 433 | * - Channel 1 : B6PV "SPEED"-pin |
StefanP | 0:f0d7e4b016ce | 434 | * Capture rising/falling edges to determine average high-low time |
StefanP | 0:f0d7e4b016ce | 435 | ****************************************************************************************/ |
StefanP | 0:f0d7e4b016ce | 436 | void Timer2Init(){ |
StefanP | 0:f0d7e4b016ce | 437 | |
StefanP | 0:f0d7e4b016ce | 438 | LPC_PINCON->PINSEL0 |= 0x00000300; // Set p30(=P0.4) to CAP2.0 = B6PV "DIAG"-pin |
StefanP | 0:f0d7e4b016ce | 439 | LPC_PINCON->PINMODE0 |= 0x00000200; // set p30(=P0.4) to have neither pull-up nor pull-down resistors |
StefanP | 0:f0d7e4b016ce | 440 | |
StefanP | 0:f0d7e4b016ce | 441 | LPC_PINCON->PINSEL0 |= 0x00000C00; // set p29(=P0.5) to CAP2.1 = B6PV "SPEED"-pin |
StefanP | 0:f0d7e4b016ce | 442 | LPC_PINCON->PINMODE0 |= 0x00000800; // set p29(=P0.5) to have neither pull-up nor pull-down resistors |
StefanP | 0:f0d7e4b016ce | 443 | |
StefanP | 0:f0d7e4b016ce | 444 | NVIC_SetVector(TIMER2_IRQn, uint32_t(TIMER2_IRQHandler)); |
StefanP | 0:f0d7e4b016ce | 445 | NVIC_EnableIRQ(TIMER2_IRQn); |
StefanP | 0:f0d7e4b016ce | 446 | //NVIC_DisableIRQ(TIMER2_IRQn); |
StefanP | 0:f0d7e4b016ce | 447 | |
StefanP | 0:f0d7e4b016ce | 448 | LPC_SC->PCONP |= (1 << 22); // Timer2 power on |
StefanP | 0:f0d7e4b016ce | 449 | LPC_SC->PCLKSEL1 |= (1 << 12); // Divide CCLK by 1 for Timer2 |
StefanP | 0:f0d7e4b016ce | 450 | |
StefanP | 0:f0d7e4b016ce | 451 | LPC_TIM2->TC = 0; // Clear timer counter |
StefanP | 0:f0d7e4b016ce | 452 | LPC_TIM2->PC = 0; // Clear prescale counter |
StefanP | 0:f0d7e4b016ce | 453 | LPC_TIM2->PR = 0; // Clear prescale register |
StefanP | 0:f0d7e4b016ce | 454 | LPC_TIM2->CTCR = 0x00; // Set timer mode |
StefanP | 0:f0d7e4b016ce | 455 | LPC_TIM2->TCR |= (1 << 1); // Reset timer |
StefanP | 0:f0d7e4b016ce | 456 | LPC_TIM2->TCR &=~(1 << 1); // Release reset |
StefanP | 0:f0d7e4b016ce | 457 | LPC_TIM2->IR = 0xFFFFFFFF; // Clear interrupt register |
StefanP | 0:f0d7e4b016ce | 458 | |
StefanP | 0:f0d7e4b016ce | 459 | LPC_TIM2->CCR |=(1<<0); // Enable cap2.0 on rising edge |
StefanP | 0:f0d7e4b016ce | 460 | LPC_TIM2->CCR |=(1<<2); // Enable interrupt on cap2.0 event |
StefanP | 0:f0d7e4b016ce | 461 | LPC_TIM2->MR0 = u32DiagnMaxPeriod; // Match register 0 for 0%-100% detection |
StefanP | 0:f0d7e4b016ce | 462 | LPC_TIM2->MCR |=(1<<0); // Enable interrupt when TIM2 reaches MR0 |
StefanP | 0:f0d7e4b016ce | 463 | |
StefanP | 0:f0d7e4b016ce | 464 | LPC_TIM2->CCR |=((1<<3)|(1<<4)); // Enable cap2.1 on rising and falling edge |
StefanP | 0:f0d7e4b016ce | 465 | LPC_TIM2->CCR |=(1<<5); // Enable interrupt on cap2.1 event |
StefanP | 0:f0d7e4b016ce | 466 | LPC_TIM2->MR0 = u32SpeedMaxPeriod; // Match register 1 for motor speed 0 detection |
StefanP | 0:f0d7e4b016ce | 467 | LPC_TIM2->MCR |=(1<<3); // Enable interrupt when TIM2 reaches MR1 |
StefanP | 0:f0d7e4b016ce | 468 | |
StefanP | 0:f0d7e4b016ce | 469 | LPC_TIM2->TCR |= (1 << 0); // start Timer2 |
StefanP | 0:f0d7e4b016ce | 470 | } |
StefanP | 0:f0d7e4b016ce | 471 | |
StefanP | 0:f0d7e4b016ce | 472 | |
StefanP | 0:f0d7e4b016ce | 473 | /* ********************************************************************************** |
StefanP | 0:f0d7e4b016ce | 474 | * |
StefanP | 0:f0d7e4b016ce | 475 | ************************************************************************************/ |
StefanP | 0:f0d7e4b016ce | 476 | void TIMER2_IRQHandler(void) |
StefanP | 0:f0d7e4b016ce | 477 | { |
StefanP | 0:f0d7e4b016ce | 478 | uint32_t pending = LPC_TIM2->IR; |
StefanP | 0:f0d7e4b016ce | 479 | |
StefanP | 0:f0d7e4b016ce | 480 | /********************************************************** |
StefanP | 0:f0d7e4b016ce | 481 | * If timer2 capture channel 0 interrupt |
StefanP | 0:f0d7e4b016ce | 482 | * Used for edge detection on DIAG-pin (duty cycle) |
StefanP | 0:f0d7e4b016ce | 483 | **********************************************************/ |
StefanP | 0:f0d7e4b016ce | 484 | if(pending & (1<<4)) // if timer2 interrupt on capture channel 0 = DIAGNOSTICS |
StefanP | 0:f0d7e4b016ce | 485 | { |
StefanP | 0:f0d7e4b016ce | 486 | if(LPC_TIM2->CCR & (1<<0)) // if cap2.0 rising edge |
StefanP | 0:f0d7e4b016ce | 487 | { |
StefanP | 0:f0d7e4b016ce | 488 | LPC_TIM2->CCR &=~(1<<0); // disable cap2.0 rising edge |
StefanP | 0:f0d7e4b016ce | 489 | |
StefanP | 0:f0d7e4b016ce | 490 | u32DiagnCapA = LPC_TIM2->CR0; |
StefanP | 0:f0d7e4b016ce | 491 | |
StefanP | 0:f0d7e4b016ce | 492 | LPC_TIM2->CCR |= (1<<1); // enable cap2.0 falling edge |
StefanP | 0:f0d7e4b016ce | 493 | } |
StefanP | 0:f0d7e4b016ce | 494 | else if (LPC_TIM2->CCR & (1<<1)) // if cap2.0 falling edge |
StefanP | 0:f0d7e4b016ce | 495 | { |
StefanP | 0:f0d7e4b016ce | 496 | LPC_TIM2->CCR &=~(1<<1); // disable cap2.0 falling edge |
StefanP | 0:f0d7e4b016ce | 497 | |
StefanP | 0:f0d7e4b016ce | 498 | uint32_t u32DiagnCapBtemp = LPC_TIM2->CR0; |
StefanP | 0:f0d7e4b016ce | 499 | uint32_t diagnHighT = u32DiagnCapBtemp - u32DiagnCapA; |
StefanP | 0:f0d7e4b016ce | 500 | |
StefanP | 0:f0d7e4b016ce | 501 | if ((u32DiagnCapBtemp-u32DiagnCapB)>(u32DiagnPeriod+(u32DiagnPeriod>>1))) |
StefanP | 0:f0d7e4b016ce | 502 | u32DiagnPeriod = ((u32DiagnCapBtemp-u32DiagnCapB)>>1); |
StefanP | 0:f0d7e4b016ce | 503 | else |
StefanP | 0:f0d7e4b016ce | 504 | u32DiagnPeriod = u32DiagnCapBtemp-u32DiagnCapB; |
StefanP | 0:f0d7e4b016ce | 505 | |
StefanP | 0:f0d7e4b016ce | 506 | if (diagnHighT<u32DiagnPeriod) |
StefanP | 0:f0d7e4b016ce | 507 | u32DiagnDC = (diagnHighT*DUTY_CYCLE_ACCURACY)/u32DiagnPeriod; |
StefanP | 0:f0d7e4b016ce | 508 | |
StefanP | 0:f0d7e4b016ce | 509 | u32DiagnCapB = u32DiagnCapBtemp; |
StefanP | 0:f0d7e4b016ce | 510 | |
StefanP | 0:f0d7e4b016ce | 511 | LPC_TIM2->CCR |= (1<<0); // enable cap2.0 rising edge |
StefanP | 0:f0d7e4b016ce | 512 | } |
StefanP | 0:f0d7e4b016ce | 513 | |
StefanP | 0:f0d7e4b016ce | 514 | LPC_TIM2->IR |= (1<<4); // clear Timer2 interrupt flag for capture channel 0 event |
StefanP | 0:f0d7e4b016ce | 515 | LPC_TIM2->MR0 = LPC_TIM2->TC + (u32DiagnMaxPeriod<<1); |
StefanP | 0:f0d7e4b016ce | 516 | } |
StefanP | 0:f0d7e4b016ce | 517 | else if(pending & (1<<0)) |
StefanP | 0:f0d7e4b016ce | 518 | { |
StefanP | 0:f0d7e4b016ce | 519 | if(LPC_TIM2->CCR & (1<<1)) |
StefanP | 0:f0d7e4b016ce | 520 | u32DiagnDC = 1*DUTY_CYCLE_ACCURACY; |
StefanP | 0:f0d7e4b016ce | 521 | else |
StefanP | 0:f0d7e4b016ce | 522 | u32DiagnDC = 0; |
StefanP | 0:f0d7e4b016ce | 523 | |
StefanP | 0:f0d7e4b016ce | 524 | u32DiagnPeriod = 0xFFFFFFFF; |
StefanP | 0:f0d7e4b016ce | 525 | LPC_TIM2->IR |= (1<<0); // clear Timer2 interrupt flag for match register 0 event |
StefanP | 0:f0d7e4b016ce | 526 | LPC_TIM2->MR0 = LPC_TIM2->TC + (u32DiagnMaxPeriod<<1); |
StefanP | 0:f0d7e4b016ce | 527 | } |
StefanP | 0:f0d7e4b016ce | 528 | |
StefanP | 0:f0d7e4b016ce | 529 | /********************************************************** |
StefanP | 0:f0d7e4b016ce | 530 | * If timer2 capture channel 1 interrupt |
StefanP | 0:f0d7e4b016ce | 531 | * Used for edge detection on SPEED-pin (high / low time) |
StefanP | 0:f0d7e4b016ce | 532 | **********************************************************/ |
StefanP | 0:f0d7e4b016ce | 533 | if(pending & (1<<5)) |
StefanP | 0:f0d7e4b016ce | 534 | { |
StefanP | 0:f0d7e4b016ce | 535 | u32SpeedCapA = u32SpeedCapB; |
StefanP | 0:f0d7e4b016ce | 536 | u32SpeedCapB = LPC_TIM2->CR1; |
StefanP | 0:f0d7e4b016ce | 537 | |
StefanP | 0:f0d7e4b016ce | 538 | // Calculate time between 2 edges = commutation time [us] |
StefanP | 0:f0d7e4b016ce | 539 | uint32_t tempCommTime = ((u32SpeedCapB-u32SpeedCapA)/96); |
StefanP | 0:f0d7e4b016ce | 540 | |
StefanP | 0:f0d7e4b016ce | 541 | // Calculate averaged speed via 1/(6 x commutation time) [eHz] |
StefanP | 0:f0d7e4b016ce | 542 | u32Speed = ((u32Speed + (1000000000/(tempCommTime*6)))>>1); |
StefanP | 0:f0d7e4b016ce | 543 | |
StefanP | 0:f0d7e4b016ce | 544 | // Clear timer2 chanel 1 interrupt flag |
StefanP | 0:f0d7e4b016ce | 545 | LPC_TIM2->IR |= (1<<5); |
StefanP | 0:f0d7e4b016ce | 546 | |
StefanP | 0:f0d7e4b016ce | 547 | // |
StefanP | 0:f0d7e4b016ce | 548 | LPC_TIM2->MR1 = LPC_TIM2->TC + (u32SpeedMaxPeriod<<1); |
StefanP | 0:f0d7e4b016ce | 549 | } |
StefanP | 0:f0d7e4b016ce | 550 | else if(pending & (1<<1)) |
StefanP | 0:f0d7e4b016ce | 551 | { |
StefanP | 0:f0d7e4b016ce | 552 | u32Speed = 0; |
StefanP | 0:f0d7e4b016ce | 553 | LPC_TIM2->IR |= (1<<1); // clear Timer2 interrupt flag for match register 0 event |
StefanP | 0:f0d7e4b016ce | 554 | LPC_TIM2->MR1 = LPC_TIM2->TC + (u32SpeedMaxPeriod<<1); |
StefanP | 0:f0d7e4b016ce | 555 | } |
StefanP | 0:f0d7e4b016ce | 556 | } |
StefanP | 0:f0d7e4b016ce | 557 |