![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
statescriptMP
Dependencies: SMARTWAV USBDevice mbed
main.cpp@0:9d97f34c6f46, 2015-05-18 (annotated)
- Committer:
- alustig3
- Date:
- Mon May 18 01:18:45 2015 +0000
- Revision:
- 0:9d97f34c6f46
statescript MP
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
alustig3 | 0:9d97f34c6f46 | 1 | #include "mbed.h" |
alustig3 | 0:9d97f34c6f46 | 2 | #include <stdint.h> |
alustig3 | 0:9d97f34c6f46 | 3 | #include "behave.h" |
alustig3 | 0:9d97f34c6f46 | 4 | #include <string.h> |
alustig3 | 0:9d97f34c6f46 | 5 | #include <sstream> |
alustig3 | 0:9d97f34c6f46 | 6 | #include "SMARTWAV.h" |
alustig3 | 0:9d97f34c6f46 | 7 | #include "USBSerial.h" |
alustig3 | 0:9d97f34c6f46 | 8 | |
alustig3 | 0:9d97f34c6f46 | 9 | |
alustig3 | 0:9d97f34c6f46 | 10 | uint32_t timeKeeper; //the main clock (updated every ms) |
alustig3 | 0:9d97f34c6f46 | 11 | bool resetTimer = false; //if true, the clock is reset |
alustig3 | 0:9d97f34c6f46 | 12 | bool clockSlave = false; //slave mode |
alustig3 | 0:9d97f34c6f46 | 13 | bool changeToSlave = false; |
alustig3 | 0:9d97f34c6f46 | 14 | bool changeToStandAlone = false; |
alustig3 | 0:9d97f34c6f46 | 15 | |
alustig3 | 0:9d97f34c6f46 | 16 | //static char buf1[0x2000] __attribute__((section("AHBSRAM0"))); |
alustig3 | 0:9d97f34c6f46 | 17 | __attribute((section("AHBSRAM0"),aligned)) outputStream textDisplay(512); |
alustig3 | 0:9d97f34c6f46 | 18 | __attribute((section("AHBSRAM0"),aligned)) char buffer[128]; |
alustig3 | 0:9d97f34c6f46 | 19 | |
alustig3 | 0:9d97f34c6f46 | 20 | |
alustig3 | 0:9d97f34c6f46 | 21 | __attribute((section("AHBSRAM1"),aligned)) event eventBlock[NUMEVENTS]; |
alustig3 | 0:9d97f34c6f46 | 22 | |
alustig3 | 0:9d97f34c6f46 | 23 | __attribute((section("AHBSRAM1"),aligned)) condition conditionBlock[NUMCONDITIONS]; |
alustig3 | 0:9d97f34c6f46 | 24 | |
alustig3 | 0:9d97f34c6f46 | 25 | __attribute((section("AHBSRAM1"),aligned)) intCompare intCompareBlock[NUMINTCOMPARE]; |
alustig3 | 0:9d97f34c6f46 | 26 | |
alustig3 | 0:9d97f34c6f46 | 27 | __attribute((section("AHBSRAM0"),aligned)) action actionBlock[NUMACTIONS]; |
alustig3 | 0:9d97f34c6f46 | 28 | |
alustig3 | 0:9d97f34c6f46 | 29 | __attribute((section("AHBSRAM0"),aligned)) portMessage portMessageBlock[NUMPORTMESSAGES]; |
alustig3 | 0:9d97f34c6f46 | 30 | |
alustig3 | 0:9d97f34c6f46 | 31 | //__attribute((section("AHBSRAM1"),aligned)) intVariable intVariableBlock[10]; |
alustig3 | 0:9d97f34c6f46 | 32 | |
alustig3 | 0:9d97f34c6f46 | 33 | __attribute((section("AHBSRAM0"),aligned)) intOperation intOperationBlock[NUMINTOPERATIONS]; |
alustig3 | 0:9d97f34c6f46 | 34 | |
alustig3 | 0:9d97f34c6f46 | 35 | __attribute((section("AHBSRAM0"),aligned)) displayAction displayActionBlock[NUMDISPLAYACTIONS]; |
alustig3 | 0:9d97f34c6f46 | 36 | |
alustig3 | 0:9d97f34c6f46 | 37 | |
alustig3 | 0:9d97f34c6f46 | 38 | |
alustig3 | 0:9d97f34c6f46 | 39 | Ticker clockBroadCast; //timer used when sending out timestamps on a GPIO |
alustig3 | 0:9d97f34c6f46 | 40 | uint32_t currentBroadcastTime; |
alustig3 | 0:9d97f34c6f46 | 41 | int currentBroadcastBit = 0; |
alustig3 | 0:9d97f34c6f46 | 42 | bool broadcastHigh = false; |
alustig3 | 0:9d97f34c6f46 | 43 | |
alustig3 | 0:9d97f34c6f46 | 44 | int currentDIOstate[2] = {0,0}; //the first number is a bit-wise representaion of the digital inputs, the 2nd is for the outputs |
alustig3 | 0:9d97f34c6f46 | 45 | bool digitalInChanged = false; |
alustig3 | 0:9d97f34c6f46 | 46 | bool digitalOutChanged = false; |
alustig3 | 0:9d97f34c6f46 | 47 | bool broadCastStateChanges = true; |
alustig3 | 0:9d97f34c6f46 | 48 | bool textStreaming = true; |
alustig3 | 0:9d97f34c6f46 | 49 | uint32_t changeTime; |
alustig3 | 0:9d97f34c6f46 | 50 | |
alustig3 | 0:9d97f34c6f46 | 51 | LocalFileSystem local("local"); |
alustig3 | 0:9d97f34c6f46 | 52 | |
alustig3 | 0:9d97f34c6f46 | 53 | digitalPort* portVector[NUMPORTS+1]; //create the digital ports |
alustig3 | 0:9d97f34c6f46 | 54 | |
alustig3 | 0:9d97f34c6f46 | 55 | float brightness = 0.0; |
alustig3 | 0:9d97f34c6f46 | 56 | |
alustig3 | 0:9d97f34c6f46 | 57 | //Define the digial ports |
alustig3 | 0:9d97f34c6f46 | 58 | |
alustig3 | 0:9d97f34c6f46 | 59 | //Pins for clock syncing |
alustig3 | 0:9d97f34c6f46 | 60 | //InterruptIn clockResetInt(p24); |
alustig3 | 0:9d97f34c6f46 | 61 | DigitalOut clockOutSync(p19); |
alustig3 | 0:9d97f34c6f46 | 62 | DigitalOut clockOutSignal(p29); |
alustig3 | 0:9d97f34c6f46 | 63 | InterruptIn clockExternalIncrement(p30); |
alustig3 | 0:9d97f34c6f46 | 64 | |
alustig3 | 0:9d97f34c6f46 | 65 | |
alustig3 | 0:9d97f34c6f46 | 66 | //Pins for digital ports. Each port has 1 out and 1 in |
alustig3 | 0:9d97f34c6f46 | 67 | //DigitalOut out1(LED1); //route to LED for debugging |
alustig3 | 0:9d97f34c6f46 | 68 | //1A,1B |
alustig3 | 0:9d97f34c6f46 | 69 | DigitalOut out1(p5); |
alustig3 | 0:9d97f34c6f46 | 70 | DigitalIn in1(p6); |
alustig3 | 0:9d97f34c6f46 | 71 | InterruptIn int1(p6); |
alustig3 | 0:9d97f34c6f46 | 72 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port1(&out1, &in1); |
alustig3 | 0:9d97f34c6f46 | 73 | //1C,1D |
alustig3 | 0:9d97f34c6f46 | 74 | DigitalOut out2(p7); |
alustig3 | 0:9d97f34c6f46 | 75 | DigitalIn in2(p8); |
alustig3 | 0:9d97f34c6f46 | 76 | InterruptIn int2(p8); |
alustig3 | 0:9d97f34c6f46 | 77 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port2(&out2, &in2); |
alustig3 | 0:9d97f34c6f46 | 78 | //2A,2B |
alustig3 | 0:9d97f34c6f46 | 79 | DigitalOut out3(p17); |
alustig3 | 0:9d97f34c6f46 | 80 | DigitalIn in3(p18); |
alustig3 | 0:9d97f34c6f46 | 81 | InterruptIn int3(p18); |
alustig3 | 0:9d97f34c6f46 | 82 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port3(&out3, &in3); |
alustig3 | 0:9d97f34c6f46 | 83 | //2C,2D |
alustig3 | 0:9d97f34c6f46 | 84 | DigitalOut out4(p11); |
alustig3 | 0:9d97f34c6f46 | 85 | DigitalIn in4(p12); |
alustig3 | 0:9d97f34c6f46 | 86 | InterruptIn int4(p12); |
alustig3 | 0:9d97f34c6f46 | 87 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port4(&out4, &in4); |
alustig3 | 0:9d97f34c6f46 | 88 | //3A,3B |
alustig3 | 0:9d97f34c6f46 | 89 | DigitalOut out5(p21); |
alustig3 | 0:9d97f34c6f46 | 90 | DigitalIn in5(p22); |
alustig3 | 0:9d97f34c6f46 | 91 | InterruptIn int5(p22); |
alustig3 | 0:9d97f34c6f46 | 92 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port5(&out5, &in5); |
alustig3 | 0:9d97f34c6f46 | 93 | //3C,3D |
alustig3 | 0:9d97f34c6f46 | 94 | DigitalOut out6(p15); |
alustig3 | 0:9d97f34c6f46 | 95 | DigitalIn in6(p16); |
alustig3 | 0:9d97f34c6f46 | 96 | InterruptIn int6(p16); |
alustig3 | 0:9d97f34c6f46 | 97 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port6(&out6, &in6); |
alustig3 | 0:9d97f34c6f46 | 98 | //4A,4B |
alustig3 | 0:9d97f34c6f46 | 99 | DigitalOut out7(p9); |
alustig3 | 0:9d97f34c6f46 | 100 | DigitalIn in7(p10); |
alustig3 | 0:9d97f34c6f46 | 101 | InterruptIn int7(p10); |
alustig3 | 0:9d97f34c6f46 | 102 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port7(&out7, &in7); |
alustig3 | 0:9d97f34c6f46 | 103 | //5A,5B |
alustig3 | 0:9d97f34c6f46 | 104 | DigitalOut out8(p13); |
alustig3 | 0:9d97f34c6f46 | 105 | DigitalIn in8(p14); |
alustig3 | 0:9d97f34c6f46 | 106 | InterruptIn int8(p14); |
alustig3 | 0:9d97f34c6f46 | 107 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port8(&out8, &in8); |
alustig3 | 0:9d97f34c6f46 | 108 | //6A,6B |
alustig3 | 0:9d97f34c6f46 | 109 | DigitalOut out9(p23); |
alustig3 | 0:9d97f34c6f46 | 110 | DigitalIn in9(p24); |
alustig3 | 0:9d97f34c6f46 | 111 | InterruptIn int9(p24); |
alustig3 | 0:9d97f34c6f46 | 112 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port9(&out9, &in9); |
alustig3 | 0:9d97f34c6f46 | 113 | //Pump1 |
alustig3 | 0:9d97f34c6f46 | 114 | DigitalOut out10(p25); |
alustig3 | 0:9d97f34c6f46 | 115 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port10(&out10); |
alustig3 | 0:9d97f34c6f46 | 116 | //Pump2 |
alustig3 | 0:9d97f34c6f46 | 117 | DigitalOut out11(p26); |
alustig3 | 0:9d97f34c6f46 | 118 | __attribute((section("AHBSRAM0"),aligned)) digitalPort port11(&out11); |
alustig3 | 0:9d97f34c6f46 | 119 | |
alustig3 | 0:9d97f34c6f46 | 120 | |
alustig3 | 0:9d97f34c6f46 | 121 | |
alustig3 | 0:9d97f34c6f46 | 122 | //Serial communication |
alustig3 | 0:9d97f34c6f46 | 123 | Serial pc(USBTX, USBRX); // tx, rx |
alustig3 | 0:9d97f34c6f46 | 124 | //USBSerial pc; |
alustig3 | 0:9d97f34c6f46 | 125 | |
alustig3 | 0:9d97f34c6f46 | 126 | |
alustig3 | 0:9d97f34c6f46 | 127 | //Main event queue |
alustig3 | 0:9d97f34c6f46 | 128 | eventQueue mainQueue(portVector, &timeKeeper); |
alustig3 | 0:9d97f34c6f46 | 129 | |
alustig3 | 0:9d97f34c6f46 | 130 | //The script parser |
alustig3 | 0:9d97f34c6f46 | 131 | scriptStream parser(&pc, portVector, NUMPORTS, &mainQueue); |
alustig3 | 0:9d97f34c6f46 | 132 | |
alustig3 | 0:9d97f34c6f46 | 133 | //The sound output uses a SmartWav device and their simple serial library |
alustig3 | 0:9d97f34c6f46 | 134 | SMARTWAV sWav(p28,p27,p20); //(TX,RX,Reset); |
alustig3 | 0:9d97f34c6f46 | 135 | //Serial device(p9,p10); |
alustig3 | 0:9d97f34c6f46 | 136 | //Erases the input buffer for serial input |
alustig3 | 0:9d97f34c6f46 | 137 | void eraseBuffer(char* buffer,int numToErase) { |
alustig3 | 0:9d97f34c6f46 | 138 | for (int i = 0; i < numToErase; i++) { |
alustig3 | 0:9d97f34c6f46 | 139 | buffer[i] = NULL; |
alustig3 | 0:9d97f34c6f46 | 140 | } |
alustig3 | 0:9d97f34c6f46 | 141 | } |
alustig3 | 0:9d97f34c6f46 | 142 | |
alustig3 | 0:9d97f34c6f46 | 143 | |
alustig3 | 0:9d97f34c6f46 | 144 | //Called by clockBroadCast timer to output a 32-bit timestamp. When the timestmap has been |
alustig3 | 0:9d97f34c6f46 | 145 | //sent, the function is detached from the timer. |
alustig3 | 0:9d97f34c6f46 | 146 | void broadcastNextBit() { |
alustig3 | 0:9d97f34c6f46 | 147 | |
alustig3 | 0:9d97f34c6f46 | 148 | if (currentBroadcastBit < 32) { |
alustig3 | 0:9d97f34c6f46 | 149 | broadcastHigh = !broadcastHigh; //flip the sync signal |
alustig3 | 0:9d97f34c6f46 | 150 | if (broadcastHigh) { |
alustig3 | 0:9d97f34c6f46 | 151 | clockOutSync = 1; |
alustig3 | 0:9d97f34c6f46 | 152 | clockOutSignal = (currentBroadcastTime & ( 1 << currentBroadcastBit)) >> currentBroadcastBit; |
alustig3 | 0:9d97f34c6f46 | 153 | |
alustig3 | 0:9d97f34c6f46 | 154 | } else { |
alustig3 | 0:9d97f34c6f46 | 155 | clockOutSync = 0; |
alustig3 | 0:9d97f34c6f46 | 156 | clockOutSignal = 0; |
alustig3 | 0:9d97f34c6f46 | 157 | currentBroadcastBit++; |
alustig3 | 0:9d97f34c6f46 | 158 | } |
alustig3 | 0:9d97f34c6f46 | 159 | } |
alustig3 | 0:9d97f34c6f46 | 160 | } |
alustig3 | 0:9d97f34c6f46 | 161 | |
alustig3 | 0:9d97f34c6f46 | 162 | |
alustig3 | 0:9d97f34c6f46 | 163 | //intiatiation of timer2 (specific to the LPC17xx chip). This is used in |
alustig3 | 0:9d97f34c6f46 | 164 | //standalone mode to increment the clock every ms. |
alustig3 | 0:9d97f34c6f46 | 165 | //we use lower-lever code here to get better control over the timer if we reset it |
alustig3 | 0:9d97f34c6f46 | 166 | void timer0_init(void) |
alustig3 | 0:9d97f34c6f46 | 167 | { |
alustig3 | 0:9d97f34c6f46 | 168 | //LPC_SC->PCLKSEL1 &= (3 << 12); //mask |
alustig3 | 0:9d97f34c6f46 | 169 | //LPC_SC->PCLKSEL1 |= (1 << 12); //sets it to 1*SystemCoreClock - table 42 (page 57 in user manual) |
alustig3 | 0:9d97f34c6f46 | 170 | |
alustig3 | 0:9d97f34c6f46 | 171 | //LPC_SC->PCLKSEL0 &= (3 << 3); //mask |
alustig3 | 0:9d97f34c6f46 | 172 | //LPC_SC->PCLKSEL0 |= (1 << 3); //sets it to 1*SystemCoreClock - table 42 (page 57 in user manual) |
alustig3 | 0:9d97f34c6f46 | 173 | LPC_SC->PCONP |=1<1; //timer0 power on |
alustig3 | 0:9d97f34c6f46 | 174 | LPC_TIM0->MR0 = 23980; //1 msec |
alustig3 | 0:9d97f34c6f46 | 175 | //LPC_TIM0->PR = (SystemCoreClock / 1000000); //microsecond steps |
alustig3 | 0:9d97f34c6f46 | 176 | //LPC_TIM0->MR0 = 1000; //100 msec |
alustig3 | 0:9d97f34c6f46 | 177 | //LPC_TIM0->MR0 = (SystemCoreClock / 1000000); //microsecond steps |
alustig3 | 0:9d97f34c6f46 | 178 | LPC_TIM0->MCR = 3; //interrupt and reset control |
alustig3 | 0:9d97f34c6f46 | 179 | //3 = Interrupt & reset timer0 on match |
alustig3 | 0:9d97f34c6f46 | 180 | //1 = Interrupt only, no reset of timer0 |
alustig3 | 0:9d97f34c6f46 | 181 | NVIC_EnableIRQ(TIMER0_IRQn); //enable timer0 interrupt |
alustig3 | 0:9d97f34c6f46 | 182 | LPC_TIM0->TCR = 1; //enable Timer0 |
alustig3 | 0:9d97f34c6f46 | 183 | |
alustig3 | 0:9d97f34c6f46 | 184 | |
alustig3 | 0:9d97f34c6f46 | 185 | /* |
alustig3 | 0:9d97f34c6f46 | 186 | LPC_SC->PCONP |= (0x1<<22); // turn on power for timer 2 |
alustig3 | 0:9d97f34c6f46 | 187 | LPC_TIM2->TCR = 0x02; // reset timer |
alustig3 | 0:9d97f34c6f46 | 188 | LPC_TIM2->PR = (SystemCoreClock / 1000000); //microsecond steps |
alustig3 | 0:9d97f34c6f46 | 189 | LPC_TIM2->MR0 = 1000; // 1000 microsecond interval interrupts |
alustig3 | 0:9d97f34c6f46 | 190 | LPC_TIM2->IR = 0x3f; // reset all interrrupts |
alustig3 | 0:9d97f34c6f46 | 191 | LPC_TIM2->MCR = 0x03; // reset timer on match and generate interrupt (MR0) |
alustig3 | 0:9d97f34c6f46 | 192 | LPC_TIM2->TCR = 0x01; // start timer |
alustig3 | 0:9d97f34c6f46 | 193 | |
alustig3 | 0:9d97f34c6f46 | 194 | NVIC_EnableIRQ(TIMER2_IRQn); // Enable the interrupt |
alustig3 | 0:9d97f34c6f46 | 195 | */ |
alustig3 | 0:9d97f34c6f46 | 196 | //pc.printf("Done timer_init\n\r"); |
alustig3 | 0:9d97f34c6f46 | 197 | } |
alustig3 | 0:9d97f34c6f46 | 198 | |
alustig3 | 0:9d97f34c6f46 | 199 | //This is the callback for timer2 |
alustig3 | 0:9d97f34c6f46 | 200 | extern "C" void TIMER0_IRQHandler (void) { |
alustig3 | 0:9d97f34c6f46 | 201 | |
alustig3 | 0:9d97f34c6f46 | 202 | if((LPC_TIM0->IR & 0x01) == 0x01) { // if MR0 interrupt, proceed |
alustig3 | 0:9d97f34c6f46 | 203 | |
alustig3 | 0:9d97f34c6f46 | 204 | LPC_TIM0->IR |= 1 << 0; // Clear MR0 interrupt flag |
alustig3 | 0:9d97f34c6f46 | 205 | timeKeeper++; |
alustig3 | 0:9d97f34c6f46 | 206 | |
alustig3 | 0:9d97f34c6f46 | 207 | if (resetTimer) { |
alustig3 | 0:9d97f34c6f46 | 208 | timeKeeper = 0; |
alustig3 | 0:9d97f34c6f46 | 209 | resetTimer = false; |
alustig3 | 0:9d97f34c6f46 | 210 | } |
alustig3 | 0:9d97f34c6f46 | 211 | |
alustig3 | 0:9d97f34c6f46 | 212 | if (currentBroadcastBit > 31) { |
alustig3 | 0:9d97f34c6f46 | 213 | clockBroadCast.detach(); |
alustig3 | 0:9d97f34c6f46 | 214 | currentBroadcastBit = 0; |
alustig3 | 0:9d97f34c6f46 | 215 | } |
alustig3 | 0:9d97f34c6f46 | 216 | |
alustig3 | 0:9d97f34c6f46 | 217 | //Every second, we broadcast out the current time |
alustig3 | 0:9d97f34c6f46 | 218 | if ((timeKeeper % 1000) == 0) { |
alustig3 | 0:9d97f34c6f46 | 219 | currentBroadcastTime = timeKeeper; |
alustig3 | 0:9d97f34c6f46 | 220 | clockOutSync = 1; |
alustig3 | 0:9d97f34c6f46 | 221 | |
alustig3 | 0:9d97f34c6f46 | 222 | currentBroadcastBit = 0; |
alustig3 | 0:9d97f34c6f46 | 223 | |
alustig3 | 0:9d97f34c6f46 | 224 | clockOutSignal = (currentBroadcastTime & ( 1 << currentBroadcastBit)) >> currentBroadcastBit; |
alustig3 | 0:9d97f34c6f46 | 225 | broadcastHigh = true; |
alustig3 | 0:9d97f34c6f46 | 226 | clockBroadCast.attach_us(&broadcastNextBit, 1000); |
alustig3 | 0:9d97f34c6f46 | 227 | } |
alustig3 | 0:9d97f34c6f46 | 228 | } |
alustig3 | 0:9d97f34c6f46 | 229 | } |
alustig3 | 0:9d97f34c6f46 | 230 | |
alustig3 | 0:9d97f34c6f46 | 231 | |
alustig3 | 0:9d97f34c6f46 | 232 | //In slave mode, the clock is updated with an external trigger every ms. No need for |
alustig3 | 0:9d97f34c6f46 | 233 | //100us resolution. |
alustig3 | 0:9d97f34c6f46 | 234 | void callback_clockExternalIncrement(void) { |
alustig3 | 0:9d97f34c6f46 | 235 | |
alustig3 | 0:9d97f34c6f46 | 236 | timeKeeper++; |
alustig3 | 0:9d97f34c6f46 | 237 | |
alustig3 | 0:9d97f34c6f46 | 238 | if (resetTimer) { |
alustig3 | 0:9d97f34c6f46 | 239 | timeKeeper = 0; |
alustig3 | 0:9d97f34c6f46 | 240 | resetTimer = false; |
alustig3 | 0:9d97f34c6f46 | 241 | } |
alustig3 | 0:9d97f34c6f46 | 242 | |
alustig3 | 0:9d97f34c6f46 | 243 | if (currentBroadcastBit > 31) { |
alustig3 | 0:9d97f34c6f46 | 244 | clockBroadCast.detach(); |
alustig3 | 0:9d97f34c6f46 | 245 | currentBroadcastBit = 0; |
alustig3 | 0:9d97f34c6f46 | 246 | } |
alustig3 | 0:9d97f34c6f46 | 247 | |
alustig3 | 0:9d97f34c6f46 | 248 | //Every second, we broadcast out the current time |
alustig3 | 0:9d97f34c6f46 | 249 | if ((timeKeeper % 1000) == 0) { |
alustig3 | 0:9d97f34c6f46 | 250 | currentBroadcastTime = timeKeeper; |
alustig3 | 0:9d97f34c6f46 | 251 | clockOutSync = 1; |
alustig3 | 0:9d97f34c6f46 | 252 | |
alustig3 | 0:9d97f34c6f46 | 253 | currentBroadcastBit = 0; |
alustig3 | 0:9d97f34c6f46 | 254 | |
alustig3 | 0:9d97f34c6f46 | 255 | clockOutSignal = (currentBroadcastTime & ( 1 << currentBroadcastBit)) >> currentBroadcastBit; |
alustig3 | 0:9d97f34c6f46 | 256 | broadcastHigh = true; |
alustig3 | 0:9d97f34c6f46 | 257 | clockBroadCast.attach_us(&broadcastNextBit, 1000); |
alustig3 | 0:9d97f34c6f46 | 258 | } |
alustig3 | 0:9d97f34c6f46 | 259 | } |
alustig3 | 0:9d97f34c6f46 | 260 | |
alustig3 | 0:9d97f34c6f46 | 261 | //Every digital port's in pin has a hardware interrupt. We use a callback stub for each port |
alustig3 | 0:9d97f34c6f46 | 262 | //that routes the int_callback. |
alustig3 | 0:9d97f34c6f46 | 263 | void int_callback(int portNum, int direction) { |
alustig3 | 0:9d97f34c6f46 | 264 | portVector[portNum]->addStateChange(direction, timeKeeper); |
alustig3 | 0:9d97f34c6f46 | 265 | } |
alustig3 | 0:9d97f34c6f46 | 266 | |
alustig3 | 0:9d97f34c6f46 | 267 | //Callback stubs |
alustig3 | 0:9d97f34c6f46 | 268 | void callback_port1_rise(void) { int_callback(1, 1); } |
alustig3 | 0:9d97f34c6f46 | 269 | void callback_port1_fall(void) { int_callback(1, 0); } |
alustig3 | 0:9d97f34c6f46 | 270 | void callback_port2_rise(void) { int_callback(2, 1); } |
alustig3 | 0:9d97f34c6f46 | 271 | void callback_port2_fall(void) { int_callback(2, 0); } |
alustig3 | 0:9d97f34c6f46 | 272 | void callback_port3_rise(void) { int_callback(3, 1); } |
alustig3 | 0:9d97f34c6f46 | 273 | void callback_port3_fall(void) { int_callback(3, 0); } |
alustig3 | 0:9d97f34c6f46 | 274 | void callback_port4_rise(void) { int_callback(4, 1); } |
alustig3 | 0:9d97f34c6f46 | 275 | void callback_port4_fall(void) { int_callback(4, 0); } |
alustig3 | 0:9d97f34c6f46 | 276 | void callback_port5_rise(void) { int_callback(5, 1); } |
alustig3 | 0:9d97f34c6f46 | 277 | void callback_port5_fall(void) { int_callback(5, 0); } |
alustig3 | 0:9d97f34c6f46 | 278 | void callback_port6_rise(void) { int_callback(6, 1); } |
alustig3 | 0:9d97f34c6f46 | 279 | void callback_port6_fall(void) { int_callback(6, 0); } |
alustig3 | 0:9d97f34c6f46 | 280 | void callback_port7_rise(void) { int_callback(7, 1); } |
alustig3 | 0:9d97f34c6f46 | 281 | void callback_port7_fall(void) { int_callback(7, 0); } |
alustig3 | 0:9d97f34c6f46 | 282 | void callback_port8_rise(void) { int_callback(8, 1); } |
alustig3 | 0:9d97f34c6f46 | 283 | void callback_port8_fall(void) { int_callback(8, 0); } |
alustig3 | 0:9d97f34c6f46 | 284 | void callback_port9_rise(void) { int_callback(9, 1); } |
alustig3 | 0:9d97f34c6f46 | 285 | void callback_port9_fall(void) { int_callback(9, 0); } |
alustig3 | 0:9d97f34c6f46 | 286 | |
alustig3 | 0:9d97f34c6f46 | 287 | |
alustig3 | 0:9d97f34c6f46 | 288 | //This function is attached to an interrupt pin for external clock reset |
alustig3 | 0:9d97f34c6f46 | 289 | void callback_clockReset(void) { |
alustig3 | 0:9d97f34c6f46 | 290 | if (timeKeeper > 100) { |
alustig3 | 0:9d97f34c6f46 | 291 | LPC_TIM2->TCR = 0x02; // reset timer |
alustig3 | 0:9d97f34c6f46 | 292 | timeKeeper = 0; |
alustig3 | 0:9d97f34c6f46 | 293 | pc.printf("%d Clock reset\r\n", timeKeeper); |
alustig3 | 0:9d97f34c6f46 | 294 | } |
alustig3 | 0:9d97f34c6f46 | 295 | } |
alustig3 | 0:9d97f34c6f46 | 296 | |
alustig3 | 0:9d97f34c6f46 | 297 | |
alustig3 | 0:9d97f34c6f46 | 298 | int main() { |
alustig3 | 0:9d97f34c6f46 | 299 | timeKeeper = 0; //set main clock to 0; |
alustig3 | 0:9d97f34c6f46 | 300 | sWav.reset(); |
alustig3 | 0:9d97f34c6f46 | 301 | pc.baud(115200); |
alustig3 | 0:9d97f34c6f46 | 302 | // device.baud(4800); |
alustig3 | 0:9d97f34c6f46 | 303 | //pc.baud(9600); |
alustig3 | 0:9d97f34c6f46 | 304 | |
alustig3 | 0:9d97f34c6f46 | 305 | for (int i = 0; i <NUMPORTS+1; i++) { |
alustig3 | 0:9d97f34c6f46 | 306 | portVector[i] = NULL; |
alustig3 | 0:9d97f34c6f46 | 307 | } |
alustig3 | 0:9d97f34c6f46 | 308 | //We keep portVector 1-based to eliminate confusion |
alustig3 | 0:9d97f34c6f46 | 309 | portVector[1] = &port1; |
alustig3 | 0:9d97f34c6f46 | 310 | portVector[2] = &port2; |
alustig3 | 0:9d97f34c6f46 | 311 | portVector[3] = &port3; |
alustig3 | 0:9d97f34c6f46 | 312 | portVector[4] = &port4; |
alustig3 | 0:9d97f34c6f46 | 313 | portVector[5] = &port5; |
alustig3 | 0:9d97f34c6f46 | 314 | portVector[6] = &port6; |
alustig3 | 0:9d97f34c6f46 | 315 | portVector[7] = &port7; |
alustig3 | 0:9d97f34c6f46 | 316 | portVector[8] = &port8; |
alustig3 | 0:9d97f34c6f46 | 317 | portVector[9] = &port9; |
alustig3 | 0:9d97f34c6f46 | 318 | portVector[10] = &port10; |
alustig3 | 0:9d97f34c6f46 | 319 | portVector[11] = &port11; |
alustig3 | 0:9d97f34c6f46 | 320 | |
alustig3 | 0:9d97f34c6f46 | 321 | //Callback to update the main clock |
alustig3 | 0:9d97f34c6f46 | 322 | //timeTick1.attach_us(&incrementTime, 100); |
alustig3 | 0:9d97f34c6f46 | 323 | |
alustig3 | 0:9d97f34c6f46 | 324 | timer0_init(); |
alustig3 | 0:9d97f34c6f46 | 325 | |
alustig3 | 0:9d97f34c6f46 | 326 | |
alustig3 | 0:9d97f34c6f46 | 327 | //Set up callbacks for the port interrupts |
alustig3 | 0:9d97f34c6f46 | 328 | int1.rise(&callback_port1_rise); |
alustig3 | 0:9d97f34c6f46 | 329 | int1.fall(&callback_port1_fall); |
alustig3 | 0:9d97f34c6f46 | 330 | int2.rise(&callback_port2_rise); |
alustig3 | 0:9d97f34c6f46 | 331 | int2.fall(&callback_port2_fall); |
alustig3 | 0:9d97f34c6f46 | 332 | int3.rise(&callback_port3_rise); |
alustig3 | 0:9d97f34c6f46 | 333 | int3.fall(&callback_port3_fall); |
alustig3 | 0:9d97f34c6f46 | 334 | int4.rise(&callback_port4_rise); |
alustig3 | 0:9d97f34c6f46 | 335 | int4.fall(&callback_port4_fall); |
alustig3 | 0:9d97f34c6f46 | 336 | int5.rise(&callback_port5_rise); |
alustig3 | 0:9d97f34c6f46 | 337 | int5.fall(&callback_port5_fall); |
alustig3 | 0:9d97f34c6f46 | 338 | int6.rise(&callback_port6_rise); |
alustig3 | 0:9d97f34c6f46 | 339 | int6.fall(&callback_port6_fall); |
alustig3 | 0:9d97f34c6f46 | 340 | int7.rise(&callback_port7_rise); |
alustig3 | 0:9d97f34c6f46 | 341 | int7.fall(&callback_port7_fall); |
alustig3 | 0:9d97f34c6f46 | 342 | int8.rise(&callback_port8_rise); |
alustig3 | 0:9d97f34c6f46 | 343 | int8.fall(&callback_port8_fall); |
alustig3 | 0:9d97f34c6f46 | 344 | int9.rise(&callback_port9_rise); |
alustig3 | 0:9d97f34c6f46 | 345 | int9.fall(&callback_port9_fall); |
alustig3 | 0:9d97f34c6f46 | 346 | |
alustig3 | 0:9d97f34c6f46 | 347 | //clockResetInt.rise(&callback_clockReset); |
alustig3 | 0:9d97f34c6f46 | 348 | //clockResetInt.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 349 | |
alustig3 | 0:9d97f34c6f46 | 350 | clockExternalIncrement.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 351 | |
alustig3 | 0:9d97f34c6f46 | 352 | //The inputs are set for pull-up mode (might need to change this) |
alustig3 | 0:9d97f34c6f46 | 353 | in1.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 354 | in2.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 355 | in3.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 356 | in4.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 357 | in5.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 358 | in6.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 359 | in7.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 360 | in8.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 361 | in9.mode(PullDown); |
alustig3 | 0:9d97f34c6f46 | 362 | |
alustig3 | 0:9d97f34c6f46 | 363 | //Set up input buffer for the serial port |
alustig3 | 0:9d97f34c6f46 | 364 | //char buffer[128]; |
alustig3 | 0:9d97f34c6f46 | 365 | int bufferPos = 0; |
alustig3 | 0:9d97f34c6f46 | 366 | eraseBuffer(buffer,128); |
alustig3 | 0:9d97f34c6f46 | 367 | |
alustig3 | 0:9d97f34c6f46 | 368 | ostringstream timeConvert; // stream used for the conversion |
alustig3 | 0:9d97f34c6f46 | 369 | ostringstream stateConvert; |
alustig3 | 0:9d97f34c6f46 | 370 | char junkChar; |
alustig3 | 0:9d97f34c6f46 | 371 | int tmpChar; |
alustig3 | 0:9d97f34c6f46 | 372 | |
alustig3 | 0:9d97f34c6f46 | 373 | //while (pc.readable()) { |
alustig3 | 0:9d97f34c6f46 | 374 | while (pc.readable()) { |
alustig3 | 0:9d97f34c6f46 | 375 | junkChar = pc.getc(); |
alustig3 | 0:9d97f34c6f46 | 376 | } |
alustig3 | 0:9d97f34c6f46 | 377 | |
alustig3 | 0:9d97f34c6f46 | 378 | FILE *fp = fopen("/local/STARTUP.TXT", "r"); |
alustig3 | 0:9d97f34c6f46 | 379 | if (fp != NULL) { |
alustig3 | 0:9d97f34c6f46 | 380 | pc.printf("Executing startup script...\r\n"); |
alustig3 | 0:9d97f34c6f46 | 381 | do { |
alustig3 | 0:9d97f34c6f46 | 382 | tmpChar = fgetc(fp); |
alustig3 | 0:9d97f34c6f46 | 383 | if ((tmpChar >= 32) && (tmpChar <= 126)) { |
alustig3 | 0:9d97f34c6f46 | 384 | buffer[bufferPos] = tmpChar; |
alustig3 | 0:9d97f34c6f46 | 385 | bufferPos++; |
alustig3 | 0:9d97f34c6f46 | 386 | } |
alustig3 | 0:9d97f34c6f46 | 387 | if ((tmpChar == 13) || (tmpChar == 10)) { //carrriage return |
alustig3 | 0:9d97f34c6f46 | 388 | parser.addLineToCurrentBlock(buffer); |
alustig3 | 0:9d97f34c6f46 | 389 | bufferPos = 0; |
alustig3 | 0:9d97f34c6f46 | 390 | eraseBuffer(buffer,128); |
alustig3 | 0:9d97f34c6f46 | 391 | } |
alustig3 | 0:9d97f34c6f46 | 392 | //pc.putc(tmpChar); |
alustig3 | 0:9d97f34c6f46 | 393 | } while (tmpChar != EOF); |
alustig3 | 0:9d97f34c6f46 | 394 | |
alustig3 | 0:9d97f34c6f46 | 395 | buffer[bufferPos] = 59; |
alustig3 | 0:9d97f34c6f46 | 396 | parser.addLineToCurrentBlock(buffer); |
alustig3 | 0:9d97f34c6f46 | 397 | eraseBuffer(buffer,128); |
alustig3 | 0:9d97f34c6f46 | 398 | fclose(fp); |
alustig3 | 0:9d97f34c6f46 | 399 | } else { |
alustig3 | 0:9d97f34c6f46 | 400 | pc.printf("No startup script found.\r\n"); |
alustig3 | 0:9d97f34c6f46 | 401 | } |
alustig3 | 0:9d97f34c6f46 | 402 | |
alustig3 | 0:9d97f34c6f46 | 403 | //main loop |
alustig3 | 0:9d97f34c6f46 | 404 | while(1) { |
alustig3 | 0:9d97f34c6f46 | 405 | //check the main event queue to see if anything needs to be done |
alustig3 | 0:9d97f34c6f46 | 406 | mainQueue.check(); |
alustig3 | 0:9d97f34c6f46 | 407 | |
alustig3 | 0:9d97f34c6f46 | 408 | //https://developer.mbed.org/handbook/Serial |
alustig3 | 0:9d97f34c6f46 | 409 | //if(device.readable()) { |
alustig3 | 0:9d97f34c6f46 | 410 | // pc.putc(device.getc()); |
alustig3 | 0:9d97f34c6f46 | 411 | // } |
alustig3 | 0:9d97f34c6f46 | 412 | //check if anything has been written to the serial input |
alustig3 | 0:9d97f34c6f46 | 413 | //if (pc.readable()) { |
alustig3 | 0:9d97f34c6f46 | 414 | if (pc.readable()) { |
alustig3 | 0:9d97f34c6f46 | 415 | |
alustig3 | 0:9d97f34c6f46 | 416 | buffer[bufferPos] = pc.getc(); |
alustig3 | 0:9d97f34c6f46 | 417 | bufferPos++; |
alustig3 | 0:9d97f34c6f46 | 418 | |
alustig3 | 0:9d97f34c6f46 | 419 | //'Return' key pressed |
alustig3 | 0:9d97f34c6f46 | 420 | if ((buffer[bufferPos-1] == 13) || (buffer[bufferPos-1] == 10)) { |
alustig3 | 0:9d97f34c6f46 | 421 | //pc.printf("\r\n"); |
alustig3 | 0:9d97f34c6f46 | 422 | buffer[bufferPos-1] = '\0'; |
alustig3 | 0:9d97f34c6f46 | 423 | parser.addLineToCurrentBlock(buffer); |
alustig3 | 0:9d97f34c6f46 | 424 | bufferPos = 0; |
alustig3 | 0:9d97f34c6f46 | 425 | eraseBuffer(buffer,128); |
alustig3 | 0:9d97f34c6f46 | 426 | |
alustig3 | 0:9d97f34c6f46 | 427 | } else { |
alustig3 | 0:9d97f34c6f46 | 428 | //pc.putc(buffer[bufferPos-1]); |
alustig3 | 0:9d97f34c6f46 | 429 | //Backspace was pressed |
alustig3 | 0:9d97f34c6f46 | 430 | if (((buffer[bufferPos-1] == 127)||(buffer[bufferPos-1] == 8)) && (bufferPos > 0)) { |
alustig3 | 0:9d97f34c6f46 | 431 | |
alustig3 | 0:9d97f34c6f46 | 432 | bufferPos = bufferPos-2; |
alustig3 | 0:9d97f34c6f46 | 433 | } |
alustig3 | 0:9d97f34c6f46 | 434 | } |
alustig3 | 0:9d97f34c6f46 | 435 | } |
alustig3 | 0:9d97f34c6f46 | 436 | |
alustig3 | 0:9d97f34c6f46 | 437 | // __disable_irq(); |
alustig3 | 0:9d97f34c6f46 | 438 | |
alustig3 | 0:9d97f34c6f46 | 439 | |
alustig3 | 0:9d97f34c6f46 | 440 | //Check all the digital ports to see if anything has changed. In the update routine, the port's |
alustig3 | 0:9d97f34c6f46 | 441 | //script callbacks are called if the port was triggered |
alustig3 | 0:9d97f34c6f46 | 442 | digitalInChanged = false; |
alustig3 | 0:9d97f34c6f46 | 443 | digitalOutChanged = false; |
alustig3 | 0:9d97f34c6f46 | 444 | changeTime = timeKeeper; |
alustig3 | 0:9d97f34c6f46 | 445 | for (int i = 0; i < NUMPORTS; i++) { |
alustig3 | 0:9d97f34c6f46 | 446 | if (portVector[i+1]->update()) { |
alustig3 | 0:9d97f34c6f46 | 447 | digitalInChanged = true; |
alustig3 | 0:9d97f34c6f46 | 448 | changeTime = min(changeTime,portVector[i+1]->lastChangeTime); |
alustig3 | 0:9d97f34c6f46 | 449 | |
alustig3 | 0:9d97f34c6f46 | 450 | //The input state of all the ports in condensed into one number (each bit contains the info) |
alustig3 | 0:9d97f34c6f46 | 451 | if (portVector[i+1]->getLastChangeState() == 1) { |
alustig3 | 0:9d97f34c6f46 | 452 | currentDIOstate[0] = currentDIOstate[0] | (1 << i); |
alustig3 | 0:9d97f34c6f46 | 453 | } else { |
alustig3 | 0:9d97f34c6f46 | 454 | currentDIOstate[0] = currentDIOstate[0] & (255^(1 << i)); |
alustig3 | 0:9d97f34c6f46 | 455 | } |
alustig3 | 0:9d97f34c6f46 | 456 | } |
alustig3 | 0:9d97f34c6f46 | 457 | if (portVector[i+1]->outStateChanged) { |
alustig3 | 0:9d97f34c6f46 | 458 | digitalOutChanged = true; |
alustig3 | 0:9d97f34c6f46 | 459 | changeTime = min(changeTime,portVector[i+1]->lastOutChangeTime); |
alustig3 | 0:9d97f34c6f46 | 460 | //The out state of all the ports in condensed into one number (each bit contains the info) |
alustig3 | 0:9d97f34c6f46 | 461 | if (portVector[i+1]->outState == 1) { |
alustig3 | 0:9d97f34c6f46 | 462 | currentDIOstate[1] = currentDIOstate[1] | (1 << i); |
alustig3 | 0:9d97f34c6f46 | 463 | } else { |
alustig3 | 0:9d97f34c6f46 | 464 | currentDIOstate[1] = currentDIOstate[1] & (255^(1 << i)); |
alustig3 | 0:9d97f34c6f46 | 465 | } |
alustig3 | 0:9d97f34c6f46 | 466 | portVector[i+1]->outStateChanged = false; |
alustig3 | 0:9d97f34c6f46 | 467 | } |
alustig3 | 0:9d97f34c6f46 | 468 | } |
alustig3 | 0:9d97f34c6f46 | 469 | |
alustig3 | 0:9d97f34c6f46 | 470 | //If anything changed, we write the new values to the serial port (this can be turned off |
alustig3 | 0:9d97f34c6f46 | 471 | //with broadCastStateChanges) |
alustig3 | 0:9d97f34c6f46 | 472 | if ( (digitalInChanged||digitalOutChanged) && broadCastStateChanges) { |
alustig3 | 0:9d97f34c6f46 | 473 | timeConvert << changeTime; //broadcast the earliest timestamp when a change occured |
alustig3 | 0:9d97f34c6f46 | 474 | //stateConvert << currentDIOstate[0] << " " << currentDIOstate[1]; |
alustig3 | 0:9d97f34c6f46 | 475 | stateConvert << currentDIOstate[0] << " " << currentDIOstate[1] << " "; |
alustig3 | 0:9d97f34c6f46 | 476 | textDisplay.send(timeConvert.str() + " " + stateConvert.str() + "\r\n"); |
alustig3 | 0:9d97f34c6f46 | 477 | timeConvert.clear(); |
alustig3 | 0:9d97f34c6f46 | 478 | timeConvert.seekp(0); |
alustig3 | 0:9d97f34c6f46 | 479 | stateConvert.clear(); |
alustig3 | 0:9d97f34c6f46 | 480 | stateConvert.seekp(0); |
alustig3 | 0:9d97f34c6f46 | 481 | digitalInChanged = false; |
alustig3 | 0:9d97f34c6f46 | 482 | digitalOutChanged = false; |
alustig3 | 0:9d97f34c6f46 | 483 | } |
alustig3 | 0:9d97f34c6f46 | 484 | |
alustig3 | 0:9d97f34c6f46 | 485 | //We use a buffer to send text via the serial port. For every loop |
alustig3 | 0:9d97f34c6f46 | 486 | //in the main loop, we send one character if there is enything to send. |
alustig3 | 0:9d97f34c6f46 | 487 | //This way, outputting text to serial does not hold up other time-sensitive |
alustig3 | 0:9d97f34c6f46 | 488 | //things in the event queue |
alustig3 | 0:9d97f34c6f46 | 489 | if ((textDisplay.unsentData) && (textStreaming)) { |
alustig3 | 0:9d97f34c6f46 | 490 | pc.printf("%c", textDisplay.getNextChar()); |
alustig3 | 0:9d97f34c6f46 | 491 | } |
alustig3 | 0:9d97f34c6f46 | 492 | |
alustig3 | 0:9d97f34c6f46 | 493 | //Here is how we toggle between standalone and slave mode for the clock updating. |
alustig3 | 0:9d97f34c6f46 | 494 | if (changeToSlave) { |
alustig3 | 0:9d97f34c6f46 | 495 | //timeTick1.detach(); |
alustig3 | 0:9d97f34c6f46 | 496 | NVIC_DisableIRQ(TIMER2_IRQn); // Disable the interrupt |
alustig3 | 0:9d97f34c6f46 | 497 | clockExternalIncrement.rise(&callback_clockExternalIncrement); |
alustig3 | 0:9d97f34c6f46 | 498 | clockSlave = true; |
alustig3 | 0:9d97f34c6f46 | 499 | changeToSlave = false; |
alustig3 | 0:9d97f34c6f46 | 500 | changeToStandAlone = false; |
alustig3 | 0:9d97f34c6f46 | 501 | } else if (changeToStandAlone) { |
alustig3 | 0:9d97f34c6f46 | 502 | //timeTick1.attach_us(&incrementTime, 100); |
alustig3 | 0:9d97f34c6f46 | 503 | timer0_init(); |
alustig3 | 0:9d97f34c6f46 | 504 | clockExternalIncrement.rise(NULL); //remove the callback to the external interrupt |
alustig3 | 0:9d97f34c6f46 | 505 | clockSlave = false; |
alustig3 | 0:9d97f34c6f46 | 506 | changeToSlave = false; |
alustig3 | 0:9d97f34c6f46 | 507 | changeToStandAlone = false; |
alustig3 | 0:9d97f34c6f46 | 508 | } |
alustig3 | 0:9d97f34c6f46 | 509 | |
alustig3 | 0:9d97f34c6f46 | 510 | //__enable_irq(); |
alustig3 | 0:9d97f34c6f46 | 511 | |
alustig3 | 0:9d97f34c6f46 | 512 | } |
alustig3 | 0:9d97f34c6f46 | 513 | } |