Embedded RTOS class project. This project allows a Python/Tk program running on a PC host to monitor/control a test-CPU programmed into an altera development board.

Dependencies:   C12832_lcd USBDevice mbed-rtos mbed mmSPI-2 watchdog

Fork of USB_device_project by Mike Moore

Committer:
gatedClock
Date:
Tue Sep 17 19:25:25 2013 +0000
Revision:
15:b8df590ce219
Parent:
13:7e1688393abc
update for embedded RTOS project.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gatedClock 2:08655e2bb776 1 /*----------------------------------------------//------------------------------
gatedClock 2:08655e2bb776 2 student : m-moore
gatedClock 2:08655e2bb776 3 email : gated.clock@gmail.com
gatedClock 13:7e1688393abc 4 class : embedded RTOS
gatedClock 2:08655e2bb776 5 directory : USB_device_project
gatedClock 2:08655e2bb776 6 file : main.cpp
gatedClock 13:7e1688393abc 7 date : september 19, 2013.
gatedClock 2:08655e2bb776 8 ----copyright-----------------------------------//------------------------------
gatedClock 2:08655e2bb776 9 licensed for personal and academic use.
gatedClock 13:7e1688393abc 10 commercial use of original code must be approved by the account-holder of
gatedClock 2:08655e2bb776 11 gated.clock@gmail.com
gatedClock 13:7e1688393abc 12 ----revision------------------------------------//------------------------------
gatedClock 13:7e1688393abc 13 this is the embedded RTOS class revision.
gatedClock 13:7e1688393abc 14 changes made since the USB device class release:
gatedClock 13:7e1688393abc 15
gatedClock 13:7e1688393abc 16 1. a 'read all registers' feature has been added, which speeds up
gatedClock 13:7e1688393abc 17 CPU execution, since the UI obtains all of the register states after
gatedClock 13:7e1688393abc 18 each CPU clock. originally, each register was individually read.
gatedClock 13:7e1688393abc 19 now, all registers are read at once, if so requested by the python code.
gatedClock 13:7e1688393abc 20
gatedClock 13:7e1688393abc 21 2. some 'if' statements were changed to 'switch' statements (neatening).
gatedClock 13:7e1688393abc 22
gatedClock 13:7e1688393abc 23 3. added watchdog timers for the three threads. this via a meta-watchdog thread.
gatedClock 13:7e1688393abc 24
gatedClock 13:7e1688393abc 25 4. added #defined-based option to either boot on error detection
gatedClock 13:7e1688393abc 26 (such as malloc fail) or use error(); function.
gatedClock 13:7e1688393abc 27
gatedClock 13:7e1688393abc 28 5. the LCD is updated only if a display value is changed - reduced power
gatedClock 13:7e1688393abc 29 usage a little & reduces potential 'blinkieness'.
gatedClock 13:7e1688393abc 30
gatedClock 13:7e1688393abc 31 6. BOOT notification on LCD.
gatedClock 2:08655e2bb776 32 ----description---------------------------------//------------------------------
gatedClock 2:08655e2bb776 33 overview:
gatedClock 2:08655e2bb776 34 program to provide round-trip communication between a python test-control
gatedClock 2:08655e2bb776 35 program running on a pc host, and a device-under-test CPU implemented on
gatedClock 2:08655e2bb776 36 an altera board. the pc-host communication is over USBSerial, and the
gatedClock 2:08655e2bb776 37 altera communication is over SPI.
gatedClock 2:08655e2bb776 38
gatedClock 2:08655e2bb776 39 features:
gatedClock 2:08655e2bb776 40 1. multi-threaded design, use of memory-pools to transfer data between threads.
gatedClock 2:08655e2bb776 41 2. use of USBDevice library for communication with PC host.
gatedClock 2:08655e2bb776 42 3. use of mmSPI custom library for communication with FPGA.
gatedClock 2:08655e2bb776 43 4. main thread provides USBSerial communication to/from host.
gatedClock 2:08655e2bb776 44 5. SPI processing thread provides SPI communication to/from DUT.
gatedClock 2:08655e2bb776 45 6. mmSPI library generates non-overlapping SPI and CPU clocks.
gatedClock 13:7e1688393abc 46 7. background diagnostic thread provides LCD & error updates.
gatedClock 13:7e1688393abc 47 8. meta watchdog thread monitors itself & the other threads.
gatedClock 0:9a314675a67d 48
gatedClock 2:08655e2bb776 49 indicators: (led<3:0> = LED<1:4>)
gatedClock 2:08655e2bb776 50 1. LCD provides running counts for SPI and CPU clock cycles.
gatedClock 13:7e1688393abc 51 2. led0 indicates main thread processing.
gatedClock 13:7e1688393abc 52 3. led1 indicates SPI thread processing.
gatedClock 13:7e1688393abc 53 4. led2 indicates LCD thread processing.
gatedClock 13:7e1688393abc 54 5. led3 indicates watchdog thread processing.
gatedClock 2:08655e2bb776 55
gatedClock 2:08655e2bb776 56 implementation:
gatedClock 2:08655e2bb776 57 1. main.processIncomingSerial(): accept incoming serial data from host,
gatedClock 2:08655e2bb776 58 and map it into tFromHost structures.
gatedClock 2:08655e2bb776 59 2. SPIprocessingThread: take the incoming data structures instances, and
gatedClock 2:08655e2bb776 60 feed their content into mmSPI commands.
gatedClock 2:08655e2bb776 61 3. mmSPI object: given commands/data passed from caller,
gatedClock 2:08655e2bb776 62 map them into SPI outgoing vectors and scan them into the FPGA.
gatedClock 2:08655e2bb776 63 4. mmSPI object: receive incoming SPI vectors from FPGA.
gatedClock 2:08655e2bb776 64 make FPGA payload data available to caller.
gatedClock 2:08655e2bb776 65 5. SPIprocessingThread: load tToHost structures with said FPGA payload data.
gatedClock 2:08655e2bb776 66 6. main.processOutgoingSerial(): transfer tToHost structure data into a
gatedClock 2:08655e2bb776 67 serial outgoing buffer, and block-transfer it to the host PC.
gatedClock 2:08655e2bb776 68
gatedClock 2:08655e2bb776 69 electrical:
gatedClock 2:08655e2bb776 70 1. four pins (and ground) attached to the zigbee header,
gatedClock 2:08655e2bb776 71 programmed as three SPI pins and the CPU clock.
gatedClock 2:08655e2bb776 72 2. each of the four signals over twisted-pair.
gatedClock 2:08655e2bb776 73 3. but some ribbon cable is used at the FPGA end.
gatedClock 2:08655e2bb776 74 4. best if only the mbed application board USB cable is attached
gatedClock 2:08655e2bb776 75 to the host; if the mbed CPU board USB cable is also attached to
gatedClock 2:08655e2bb776 76 the host, then the python program may attempt to use the wrong USB
gatedClock 2:08655e2bb776 77 connection.
gatedClock 2:08655e2bb776 78 5. no particular power sequence is needed for this system to work.
gatedClock 2:08655e2bb776 79
gatedClock 13:7e1688393abc 80 timing critical path: serial processing. the python code needs
gatedClock 13:7e1688393abc 81 a delay between serial access of 40mS conservatively.
gatedClock 2:08655e2bb776 82
gatedClock 2:08655e2bb776 83 testing:
gatedClock 2:08655e2bb776 84 the python UI provides the main testing mechanism.
gatedClock 2:08655e2bb776 85
gatedClock 2:08655e2bb776 86 USB connect.
gatedClock 2:08655e2bb776 87 00. press 'CONNECT' button in UI. verify connection info in shell.
gatedClock 2:08655e2bb776 88
gatedClock 2:08655e2bb776 89 CPU register w/r
gatedClock 2:08655e2bb776 90 01. type values into {R0,R1,R2,R3,PC,IR} UI entry-forms.
gatedClock 2:08655e2bb776 91 02. press 'REG WRITE' UI button.
gatedClock 2:08655e2bb776 92 03. press 'REG READ' UI button.
gatedClock 2:08655e2bb776 93 04. verify that the read data is correct.
gatedClock 2:08655e2bb776 94
gatedClock 2:08655e2bb776 95 CPU main-memory w/r
gatedClock 2:08655e2bb776 96 05. type an address into 'mmADR' UI entry-form.
gatedClock 2:08655e2bb776 97 06. type data into 'mmVAL' UI entry-form.
gatedClock 2:08655e2bb776 98 07. press 'MM WRITE' UI button.
gatedClock 2:08655e2bb776 99 08. type a different address into 'mmADR' UI entry-form.
gatedClock 2:08655e2bb776 100 09. type different data into 'mmVAL' UI entry-form.
gatedClock 2:08655e2bb776 101 10. press 'MM WRITE' UI button.
gatedClock 2:08655e2bb776 102 11. type address from (05) into 'mmADR' UI entry-form.
gatedClock 2:08655e2bb776 103 12. press 'MM READ' UI button.
gatedClock 2:08655e2bb776 104 13. verify that the data from (06) is seen in the 'mmVAL' entry form.
gatedClock 2:08655e2bb776 105 14. type address from (08) into 'mmADR' UI entry-form.
gatedClock 2:08655e2bb776 106 15. press 'MM READ' UI button.
gatedClock 2:08655e2bb776 107 16. verify that the data from (09) is seen in the 'mmVAL' entry form.
gatedClock 2:08655e2bb776 108
gatedClock 2:08655e2bb776 109 CPU main-memory full load/dump.
gatedClock 2:08655e2bb776 110 17. press 'PROGRAM' in the UI. select a program file in the dialog-popup.
gatedClock 2:08655e2bb776 111 18. watch the load process in the shell text.
gatedClock 2:08655e2bb776 112 19. press 'DUMP in the UI. select a main-memory dump file in the diaglog-popup.
gatedClock 2:08655e2bb776 113 20. watch the dump process in the shell text.
gatedClock 2:08655e2bb776 114
gatedClock 2:08655e2bb776 115 CPU step function.
gatedClock 2:08655e2bb776 116 21. press 'STEP' in the UI repeatedly, watch the UI display the
gatedClock 2:08655e2bb776 117 CPU register states as the current program is executed one CPU clock
gatedClock 2:08655e2bb776 118 at a time.
gatedClock 2:08655e2bb776 119
gatedClock 2:08655e2bb776 120 CPU run function.
gatedClock 2:08655e2bb776 121 22. press 'RUN' in the UI. watch the current program run at high speed.
gatedClock 2:08655e2bb776 122 23. press 'SLOW' in the UI. watch the current program run at slow speed.
gatedClock 2:08655e2bb776 123 24. press 'STOP' in the UI. the program will stop execution.
gatedClock 2:08655e2bb776 124
gatedClock 2:08655e2bb776 125 CPU test function.
gatedClock 2:08655e2bb776 126 25. press 'TEST' in the UI. the program will load,execute,dump,compare.
gatedClock 2:08655e2bb776 127 26. tail -f testlog.txt to see test status.
gatedClock 2:08655e2bb776 128 27. the test will repeat until 'STOP TEST' is pressed.
gatedClock 2:08655e2bb776 129 28. long test performed by allowing this mode to continue.
gatedClock 2:08655e2bb776 130
gatedClock 2:08655e2bb776 131 UI exit function.
gatedClock 2:08655e2bb776 132 29. press 'EXIT' in the UI. it will exit.
gatedClock 2:08655e2bb776 133 -----includes-----------------------------------//----------------------------*/
gatedClock 2:08655e2bb776 134 #include "mbed.h" // general.
gatedClock 2:08655e2bb776 135 #include "USBSerial.h" // serial over USB.
gatedClock 2:08655e2bb776 136 #include "C12832_lcd.h" // LCD display.
gatedClock 2:08655e2bb776 137 #include "rtos.h" // RTOS.
gatedClock 2:08655e2bb776 138 #include "mmSPI.h" // SPI.
gatedClock 13:7e1688393abc 139 #include "watchdog.h" // watchdog.
gatedClock 2:08655e2bb776 140 //---defines------------------------------------//------------------------------
gatedClock 2:08655e2bb776 141 #define LCD1 lcd.locate(0, 0); // LCD line 1.
gatedClock 2:08655e2bb776 142 #define LCD2 lcd.locate(0,11); // LCD line 2.
gatedClock 2:08655e2bb776 143 #define LCD3 lcd.locate(0,22); // LCD line 3.
gatedClock 2:08655e2bb776 144 #define LCD3 lcd.locate(0,22); // LCD line 3.
gatedClock 13:7e1688393abc 145 #define WATCHDOG_S 10 // watchdog timeout, in seconds.
gatedClock 13:7e1688393abc 146 #define ERROR_BOOT 1 // 1 means boot rather than error().
gatedClock 2:08655e2bb776 147 #define SPI_BYTES 8 // number of SPI bytes.
gatedClock 2:08655e2bb776 148 #define SPI_HZ 100000 // SPI frequency in Hz.
gatedClock 13:7e1688393abc 149 #define SER_BYTES 18 // serial in/out # of bytes.
gatedClock 2:08655e2bb776 150 #define SER_ALIGN 7 // '$' location in shift-register.
gatedClock 2:08655e2bb776 151 #define THREAD_0_WAIT 8 // multitasking wait mS.
gatedClock 2:08655e2bb776 152 #define THREAD_1_WAIT 2 // multitasking wait mS.
gatedClock 2:08655e2bb776 153 #define THREAD_2_WAIT 128 // multitasking wait mS.
gatedClock 13:7e1688393abc 154 #define THREAD_3_WAIT 128 // multitasking wait mS.
gatedClock 2:08655e2bb776 155 #define HB_MODULO 64 // heartbeat slowdown factor.
gatedClock 2:08655e2bb776 156 #define POOL_LEN 16 // memory pool dimension.
gatedClock 2:08655e2bb776 157 #define HCMD_SETREG 1 // host command 'set register'.
gatedClock 2:08655e2bb776 158 #define HCMD_GETREG 2 // host command 'get register'.
gatedClock 2:08655e2bb776 159 #define HCMD_SETMM 3 // host command 'set main-memory.'
gatedClock 2:08655e2bb776 160 #define HCMD_GETMM 4 // host command 'get main-memory.'
gatedClock 2:08655e2bb776 161 #define HCMD_STEP 5 // host command 'step-CPU'.
gatedClock 2:08655e2bb776 162 #define HCMD_SETIR 6 // host command 'set-IR'.
gatedClock 13:7e1688393abc 163 #define HCMD_GETALLREG 7 // host command 'get-all-registers'.
gatedClock 2:08655e2bb776 164 #define CPU_REG_0 0 // CPU register 0.
gatedClock 2:08655e2bb776 165 #define CPU_REG_1 1 // CPU register 1.
gatedClock 2:08655e2bb776 166 #define CPU_REG_2 2 // CPU register 2.
gatedClock 2:08655e2bb776 167 #define CPU_REG_3 3 // CPU register 3.
gatedClock 2:08655e2bb776 168 #define CPU_REG_PC 4 // CPU Program Counter.
gatedClock 2:08655e2bb776 169 #define CPU_IR_H 5 // CPU IR high-byte.
gatedClock 2:08655e2bb776 170 #define CPU_IR_L 6 // CPU IR low-byte.
gatedClock 13:7e1688393abc 171 //--externals-----------------------------------//------------------------------
gatedClock 13:7e1688393abc 172 extern "C" void mbed_reset(); // processor reset.
gatedClock 2:08655e2bb776 173 //--global_definitions--------------------------//------------------------------
gatedClock 2:08655e2bb776 174 struct tFromHost // command from host.
gatedClock 2:08655e2bb776 175 {
gatedClock 2:08655e2bb776 176 char cCommand; // command from host.
gatedClock 2:08655e2bb776 177 char cRegisterID; // which CPU register.
gatedClock 2:08655e2bb776 178 char cRegisterValue; // write this to CPU register.
gatedClock 2:08655e2bb776 179 char cIRValueH; // write this to IR.
gatedClock 2:08655e2bb776 180 char cIRValueL; // write this to IR.
gatedClock 2:08655e2bb776 181 char cMMaddress; // access this MM address.
gatedClock 2:08655e2bb776 182 char cMMdataH; // MM content high byte.
gatedClock 2:08655e2bb776 183 char cMMdataL; // MM content low byte.
gatedClock 2:08655e2bb776 184 };
gatedClock 2:08655e2bb776 185 MemoryPool<tFromHost, POOL_LEN> mPoolFromHost;
gatedClock 2:08655e2bb776 186 Queue <tFromHost, POOL_LEN> qFromHost;
gatedClock 2:08655e2bb776 187
gatedClock 2:08655e2bb776 188 //----
gatedClock 2:08655e2bb776 189
gatedClock 2:08655e2bb776 190 struct tToHost // reply to host.
gatedClock 2:08655e2bb776 191 {
gatedClock 2:08655e2bb776 192 char cCommand; // command executed.
gatedClock 2:08655e2bb776 193 char cRegisterID; // which CPU register read.
gatedClock 2:08655e2bb776 194 char cRegisterValue; // data from CPU register.
gatedClock 2:08655e2bb776 195 char cMMaddress; // which MM address read.
gatedClock 2:08655e2bb776 196 char cMMdataH; // MM content high byte.
gatedClock 13:7e1688393abc 197 char cMMdataL; // MM content low byte.
gatedClock 13:7e1688393abc 198 char cReg0; // data from R0.
gatedClock 13:7e1688393abc 199 char cReg1; // data from R1.
gatedClock 13:7e1688393abc 200 char cReg2; // data from R2.
gatedClock 13:7e1688393abc 201 char cReg3; // data from R3.
gatedClock 13:7e1688393abc 202 char cPC; // data from program counter.
gatedClock 13:7e1688393abc 203 char cIRH; // high byte from instruction register.
gatedClock 13:7e1688393abc 204 char cIRL; // low byte from instruction register.
gatedClock 2:08655e2bb776 205 };
gatedClock 2:08655e2bb776 206 MemoryPool<tToHost, POOL_LEN> mPoolToHost;
gatedClock 2:08655e2bb776 207 Queue <tToHost, POOL_LEN> qToHost;
gatedClock 13:7e1688393abc 208
gatedClock 13:7e1688393abc 209 Queue<int, POOL_LEN> queueWatchdogThread_0; // main thread watchdog notice.
gatedClock 13:7e1688393abc 210 Queue<int, POOL_LEN> queueWatchdogThread_1; // thread 1 watchdog notice.
gatedClock 13:7e1688393abc 211 Queue<int, POOL_LEN> queueWatchdogThread_2; // thread 2 watchdog notice.
gatedClock 2:08655e2bb776 212 //--global_variables----------------------------//------------------------------
gatedClock 2:08655e2bb776 213 char gpcSerialFromHost[SER_BYTES]; // incoming serial buffer.
gatedClock 2:08655e2bb776 214 char gpcSerialToHost [SER_BYTES]; // outgoing serial buffer.
gatedClock 2:08655e2bb776 215 char gcNewCommand; // new command from host.
gatedClock 2:08655e2bb776 216 int gdRoundTrip; // +1 from host, -1 to host.
gatedClock 2:08655e2bb776 217 tToHost * gpToHost; // to-host structure.
gatedClock 2:08655e2bb776 218 osEvent gqToHostEvent; // incoming message event.
gatedClock 2:08655e2bb776 219 unsigned long gulSPIclkCount; // SPI clock count.
gatedClock 2:08655e2bb776 220 unsigned long gulCPUclkCount; // CPU clock count.
gatedClock 2:08655e2bb776 221 //--global_instances----------------------------//------------------------------
gatedClock 2:08655e2bb776 222 USBSerial serial; // serial over usb.
gatedClock 2:08655e2bb776 223 C12832_LCD lcd; // LCD display.
gatedClock 2:08655e2bb776 224 DigitalOut led0(LED4); // thread heartbeat.
gatedClock 2:08655e2bb776 225 DigitalOut led1(LED3); // thread heartbeat.
gatedClock 2:08655e2bb776 226 DigitalOut led2(LED2); // thread heartbeat.
gatedClock 2:08655e2bb776 227 DigitalOut led3(LED1); // SPI reply underflow warning.
gatedClock 2:08655e2bb776 228 //-------prototypes-----------------------------//------------------------------
gatedClock 2:08655e2bb776 229 int main(); // main.
gatedClock 2:08655e2bb776 230 void processIncomingSerial(); // process incoming host data.
gatedClock 2:08655e2bb776 231 void processOutgoingSerial(); // process outgoing data to host.
gatedClock 2:08655e2bb776 232 void SPIprocessingThread(void const *args); // SPI-side processing.
gatedClock 13:7e1688393abc 233 void diagnosticThread (void const *args); // LCD and LED notifications.
gatedClock 13:7e1688393abc 234 void watchdogThread (void const *args); // overall watchdog.
gatedClock 2:08655e2bb776 235 char ascii_nibble_to_binary(char cAscii); // ascii nibble -> binary.
gatedClock 2:08655e2bb776 236 char binary_to_ascii_nibble(char cBinary); // binary -> ascii nibble.
gatedClock 2:08655e2bb776 237 void clear_tFromHost(tFromHost *ptFromHost);// initialize structure.
gatedClock 2:08655e2bb776 238 void clear_tToHost (tToHost *ptToHost); // initialize structure.
gatedClock 2:08655e2bb776 239 //==============================================//==============================
gatedClock 2:08655e2bb776 240 int main(void) // USBSerial processing thread.
gatedClock 2:08655e2bb776 241 {
gatedClock 2:08655e2bb776 242 int dHeartbeat; // heartbeat counter.
gatedClock 2:08655e2bb776 243 int dLoop; // loop index.
gatedClock 2:08655e2bb776 244
gatedClock 2:08655e2bb776 245 gpToHost = NULL; // initialize global.
gatedClock 2:08655e2bb776 246 gcNewCommand = 0; // initialize global.
gatedClock 2:08655e2bb776 247 gdRoundTrip = 1024; // initialize global.
gatedClock 2:08655e2bb776 248 gulSPIclkCount = 0; // initialize global.
gatedClock 2:08655e2bb776 249 gulCPUclkCount = 0; // initialize global.
gatedClock 13:7e1688393abc 250 led0 = 0; // initialize global.
gatedClock 13:7e1688393abc 251 led1 = 0; // initialize global.
gatedClock 13:7e1688393abc 252 led2 = 0; // initialize global.
gatedClock 13:7e1688393abc 253 led3 = 0; // initialize global.
gatedClock 2:08655e2bb776 254 dHeartbeat = 0; // initialize local.
gatedClock 2:08655e2bb776 255 dLoop = 0; // initialize local.
gatedClock 13:7e1688393abc 256
gatedClock 13:7e1688393abc 257 // BOOT notification.
gatedClock 13:7e1688393abc 258 lcd.cls(); LCD2; lcd.printf(" BOOT"); wait(1.0);
gatedClock 2:08655e2bb776 259
gatedClock 2:08655e2bb776 260 // initialize serial-in shift-register.
gatedClock 2:08655e2bb776 261 for (dLoop = 0; dLoop < SER_BYTES; dLoop++) gpcSerialFromHost[dLoop] = 0;
gatedClock 2:08655e2bb776 262
gatedClock 2:08655e2bb776 263 // thread-out SPI-side processing.
gatedClock 2:08655e2bb776 264 Thread thread_1(SPIprocessingThread,NULL,osPriorityHigh,DEFAULT_STACK_SIZE,NULL);
gatedClock 2:08655e2bb776 265
gatedClock 2:08655e2bb776 266 // thread-out diagnostics.
gatedClock 13:7e1688393abc 267 Thread thread_2(diagnosticThread, NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL);
gatedClock 13:7e1688393abc 268
gatedClock 13:7e1688393abc 269 // thread-out universal watchdog.
gatedClock 13:7e1688393abc 270 Thread thread_3(watchdogThread, NULL,osPriorityIdle,DEFAULT_STACK_SIZE,NULL);
gatedClock 13:7e1688393abc 271
gatedClock 2:08655e2bb776 272 while(1) // main loop.
gatedClock 2:08655e2bb776 273 {
gatedClock 2:08655e2bb776 274 processIncomingSerial(); // process data in from host.
gatedClock 2:08655e2bb776 275 processOutgoingSerial(); // process data out to host.
gatedClock 2:08655e2bb776 276
gatedClock 2:08655e2bb776 277 dHeartbeat++; // thread heartbeat.
gatedClock 2:08655e2bb776 278 if (!(dHeartbeat % HB_MODULO)) led0 = !led0;
gatedClock 13:7e1688393abc 279 queueWatchdogThread_0.put((int *) 0,1); // adds 1mS to wait.
gatedClock 13:7e1688393abc 280 Thread::wait(THREAD_0_WAIT - 1); // multitasking.
gatedClock 2:08655e2bb776 281 } // main loop.
gatedClock 2:08655e2bb776 282 } // main.
gatedClock 2:08655e2bb776 283 /*----------------------------------------------//----------------------------*/
gatedClock 2:08655e2bb776 284 /*
gatedClock 2:08655e2bb776 285 the python program running on the host is sending/receiving ascii characters
gatedClock 2:08655e2bb776 286 which represent command/data binary nibbles. the python program will send
gatedClock 2:08655e2bb776 287 the '$' character for command-string alignment. this function reads-in the
gatedClock 2:08655e2bb776 288 incoming serial stream when any serial data is available, into a shift-register,
gatedClock 2:08655e2bb776 289 and breaks upon detection of the '$' alignment character for python
gatedClock 2:08655e2bb776 290 command-processing. at that point the shift-register will look something like
gatedClock 2:08655e2bb776 291 [0] [1] [2] [3] [4] [5] [6] [7]
gatedClock 2:08655e2bb776 292 '1' '2' '3' '4' x x x '$' (means write 0x34 to CPU R2).
gatedClock 2:08655e2bb776 293
gatedClock 2:08655e2bb776 294
gatedClock 2:08655e2bb776 295 command-host register-number interpretation:
gatedClock 2:08655e2bb776 296 0 = CPU R0.
gatedClock 2:08655e2bb776 297 1 = CPU R1.
gatedClock 2:08655e2bb776 298 2 = CPU R2.
gatedClock 2:08655e2bb776 299 3 = CPU R3.
gatedClock 2:08655e2bb776 300 4 = CPU program-counter.
gatedClock 2:08655e2bb776 301 5 = CPU instruction-register high-byte.
gatedClock 2:08655e2bb776 302 6 = CPU instruction-register low-byte.
gatedClock 2:08655e2bb776 303
gatedClock 2:08655e2bb776 304 instruction-register write is specially implemented,
gatedClock 2:08655e2bb776 305 instruction-register read is implemented as two standard register-reads.
gatedClock 2:08655e2bb776 306
gatedClock 2:08655e2bb776 307 host-command shift-register interpretation:
gatedClock 2:08655e2bb776 308
gatedClock 2:08655e2bb776 309 gpcSerialFromHost[0] = command.
gatedClock 2:08655e2bb776 310 subsequent interpretation depends on the command.
gatedClock 2:08655e2bb776 311
gatedClock 2:08655e2bb776 312 ----
gatedClock 2:08655e2bb776 313 if command = HCMD_SETREG (write-CPU-register) or HCMD_GETREG (read-CPU-register):
gatedClock 2:08655e2bb776 314
gatedClock 2:08655e2bb776 315 gpcSerialFromHost[1] = register number (see above).
gatedClock 2:08655e2bb776 316 gpcSerialFromHost[2] = register content, high nibble.
gatedClock 2:08655e2bb776 317 gpcSerialFromHost[3] = register content, low nibble.
gatedClock 2:08655e2bb776 318 gpcSerialFromHost[4] = not used.
gatedClock 2:08655e2bb776 319 gpcSerialFromHost[5] = not used.
gatedClock 2:08655e2bb776 320 gpcSerialFromHost[6] = not used.
gatedClock 2:08655e2bb776 321
gatedClock 2:08655e2bb776 322 ----
gatedClock 2:08655e2bb776 323 if command = HCMD_SETIR (write-CPU-instruction-register):
gatedClock 2:08655e2bb776 324
gatedClock 2:08655e2bb776 325 gpcSerialFromHost[1] = IR register number, implied anyway.
gatedClock 2:08655e2bb776 326 gpcSerialFromHost[2] = IR write value high byte high nibble.
gatedClock 2:08655e2bb776 327 gpcSerialFromHost[3] = IR write value high byte low nibble.
gatedClock 2:08655e2bb776 328 gpcSerialFromHost[4] = IR write value low byte high nibble.
gatedClock 2:08655e2bb776 329 gpcSerialFromHost[5] = IR write value low byte low nibble.
gatedClock 2:08655e2bb776 330 gpcSerialFromHost[6] = not used.
gatedClock 2:08655e2bb776 331
gatedClock 2:08655e2bb776 332 ----
gatedClock 2:08655e2bb776 333 if command = HCMD_SETMM (write to CPU main-memory) or HCMD_GETMM (read from CPU main-memory):
gatedClock 2:08655e2bb776 334
gatedClock 2:08655e2bb776 335 gpcSerialFromHost[1] = MM address high nibble.
gatedClock 2:08655e2bb776 336 gpcSerialFromHost[2] = MM address low nibble.
gatedClock 2:08655e2bb776 337 gpcSerialFromHost[3] = MM content high byte high nibble.
gatedClock 2:08655e2bb776 338 gpcSerialFromHost[4] = MM content high byte low nibble.
gatedClock 2:08655e2bb776 339 gpcSerialFromHost[5] = MM content low byte high nibble.
gatedClock 2:08655e2bb776 340 gpcSerialFromHost[6] = MM content low byte low nibble.
gatedClock 2:08655e2bb776 341
gatedClock 2:08655e2bb776 342 the above also applies to function 'processOutgoingSerial'.
gatedClock 2:08655e2bb776 343 */
gatedClock 0:9a314675a67d 344
gatedClock 2:08655e2bb776 345 void processIncomingSerial(void) // process incoming serial data.
gatedClock 2:08655e2bb776 346 {
gatedClock 2:08655e2bb776 347 int dLoop; // loop index.
gatedClock 2:08655e2bb776 348 tFromHost * pFromHost; // from-host structure.
gatedClock 2:08655e2bb776 349
gatedClock 2:08655e2bb776 350 while(serial.available()) // while data from host is available.
gatedClock 2:08655e2bb776 351 {
gatedClock 2:08655e2bb776 352 // shift-in the serial stream.
gatedClock 2:08655e2bb776 353 for (dLoop = 0; dLoop < (SER_BYTES - 1); dLoop++)
gatedClock 2:08655e2bb776 354 gpcSerialFromHost[dLoop] = gpcSerialFromHost[dLoop + 1];
gatedClock 2:08655e2bb776 355 gpcSerialFromHost[SER_BYTES - 1] = serial._getc();
gatedClock 2:08655e2bb776 356
gatedClock 2:08655e2bb776 357 if (gpcSerialFromHost[SER_ALIGN] == '$')// data from host is aligned.
gatedClock 2:08655e2bb776 358 {
gatedClock 2:08655e2bb776 359 gcNewCommand = 1; // new host command just recognised.
gatedClock 2:08655e2bb776 360 break; // need to process aligned data.
gatedClock 2:08655e2bb776 361 } // data from host is aligned.
gatedClock 2:08655e2bb776 362 } // while data from host is available.
gatedClock 2:08655e2bb776 363
gatedClock 2:08655e2bb776 364 // even if more data awaits from the
gatedClock 2:08655e2bb776 365 // incoming serial stream, we now need
gatedClock 2:08655e2bb776 366 // to process the aligned data recognised
gatedClock 2:08655e2bb776 367 // as a command from the host.
gatedClock 2:08655e2bb776 368
gatedClock 2:08655e2bb776 369 if (gcNewCommand) // execute once per new command.
gatedClock 2:08655e2bb776 370 {
gatedClock 2:08655e2bb776 371 pFromHost = mPoolFromHost.alloc(); // allocate next pool entry.
gatedClock 13:7e1688393abc 372 if (!pFromHost) // failure detection.
gatedClock 13:7e1688393abc 373 {
gatedClock 13:7e1688393abc 374 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 375 error("\n\r processIncomingSerial : FATAL malloc error for pFromHost. \n\r");
gatedClock 13:7e1688393abc 376 }
gatedClock 13:7e1688393abc 377
gatedClock 2:08655e2bb776 378 clear_tFromHost(pFromHost); // initialize structure.
gatedClock 2:08655e2bb776 379
gatedClock 2:08655e2bb776 380 // copy-in host message.
gatedClock 2:08655e2bb776 381 pFromHost->cCommand = ascii_nibble_to_binary(gpcSerialFromHost[0]);
gatedClock 2:08655e2bb776 382
gatedClock 13:7e1688393abc 383 //----
gatedClock 13:7e1688393abc 384
gatedClock 13:7e1688393abc 385 switch(pFromHost->cCommand) // command dependency.
gatedClock 2:08655e2bb776 386 {
gatedClock 13:7e1688393abc 387 case HCMD_SETREG : // host command 'set register'.
gatedClock 13:7e1688393abc 388 {
gatedClock 13:7e1688393abc 389 pFromHost->cRegisterID = ascii_nibble_to_binary(gpcSerialFromHost[1]);
gatedClock 13:7e1688393abc 390 pFromHost->cRegisterValue = ((ascii_nibble_to_binary(gpcSerialFromHost[2])) << 4) +
gatedClock 13:7e1688393abc 391 ascii_nibble_to_binary(gpcSerialFromHost[3]);
gatedClock 13:7e1688393abc 392 break;
gatedClock 13:7e1688393abc 393 } // host command 'set register'.
gatedClock 2:08655e2bb776 394
gatedClock 13:7e1688393abc 395 case HCMD_GETREG : // host command 'get register'.
gatedClock 13:7e1688393abc 396 {
gatedClock 13:7e1688393abc 397 pFromHost->cRegisterID = ascii_nibble_to_binary(gpcSerialFromHost[1]);
gatedClock 13:7e1688393abc 398 pFromHost->cRegisterValue = ((ascii_nibble_to_binary(gpcSerialFromHost[2])) << 4) +
gatedClock 13:7e1688393abc 399 ascii_nibble_to_binary(gpcSerialFromHost[3]);
gatedClock 13:7e1688393abc 400 gdRoundTrip++; // expected reply to host is pending.
gatedClock 13:7e1688393abc 401 break;
gatedClock 13:7e1688393abc 402 } // host command 'get register'.
gatedClock 13:7e1688393abc 403
gatedClock 13:7e1688393abc 404 case HCMD_SETMM : // host command 'set main-memory.'
gatedClock 13:7e1688393abc 405 {
gatedClock 13:7e1688393abc 406 pFromHost->cMMaddress = ((ascii_nibble_to_binary(gpcSerialFromHost[1])) << 4) +
gatedClock 13:7e1688393abc 407 ascii_nibble_to_binary(gpcSerialFromHost[2]);
gatedClock 13:7e1688393abc 408 pFromHost->cMMdataH = ((ascii_nibble_to_binary(gpcSerialFromHost[3])) << 4) +
gatedClock 13:7e1688393abc 409 ascii_nibble_to_binary(gpcSerialFromHost[4]);
gatedClock 13:7e1688393abc 410 pFromHost->cMMdataL = ((ascii_nibble_to_binary(gpcSerialFromHost[5])) << 4) +
gatedClock 13:7e1688393abc 411 ascii_nibble_to_binary(gpcSerialFromHost[6]);
gatedClock 13:7e1688393abc 412 break;
gatedClock 13:7e1688393abc 413 } // host command 'set main-memory.'
gatedClock 13:7e1688393abc 414
gatedClock 13:7e1688393abc 415 case HCMD_GETMM : // host command 'get main-memory.'
gatedClock 13:7e1688393abc 416 {
gatedClock 13:7e1688393abc 417 pFromHost->cMMaddress = ((ascii_nibble_to_binary(gpcSerialFromHost[1])) << 4) +
gatedClock 13:7e1688393abc 418 ascii_nibble_to_binary(gpcSerialFromHost[2]);
gatedClock 13:7e1688393abc 419 pFromHost->cMMdataH = ((ascii_nibble_to_binary(gpcSerialFromHost[3])) << 4) +
gatedClock 13:7e1688393abc 420 ascii_nibble_to_binary(gpcSerialFromHost[4]);
gatedClock 13:7e1688393abc 421 pFromHost->cMMdataL = ((ascii_nibble_to_binary(gpcSerialFromHost[5])) << 4) +
gatedClock 13:7e1688393abc 422 ascii_nibble_to_binary(gpcSerialFromHost[6]);
gatedClock 13:7e1688393abc 423
gatedClock 13:7e1688393abc 424 gdRoundTrip++; // expected reply to host is pending.
gatedClock 13:7e1688393abc 425 break;
gatedClock 13:7e1688393abc 426 } // host command 'get main-memory.'
gatedClock 13:7e1688393abc 427
gatedClock 13:7e1688393abc 428 case HCMD_STEP : // host command 'step-CPU'.
gatedClock 13:7e1688393abc 429 {
gatedClock 13:7e1688393abc 430 break;
gatedClock 13:7e1688393abc 431 } // host command 'step-CPU'.
gatedClock 13:7e1688393abc 432
gatedClock 13:7e1688393abc 433 case HCMD_SETIR : // host command 'set-IR'.
gatedClock 13:7e1688393abc 434 {
gatedClock 13:7e1688393abc 435 pFromHost->cIRValueH = ((ascii_nibble_to_binary(gpcSerialFromHost[2])) << 4) +
gatedClock 13:7e1688393abc 436 ascii_nibble_to_binary(gpcSerialFromHost[3]);
gatedClock 13:7e1688393abc 437 pFromHost->cIRValueL = ((ascii_nibble_to_binary(gpcSerialFromHost[4])) << 4) +
gatedClock 13:7e1688393abc 438 ascii_nibble_to_binary(gpcSerialFromHost[5]);
gatedClock 13:7e1688393abc 439 break;
gatedClock 13:7e1688393abc 440 } // host command 'set-IR'.
gatedClock 13:7e1688393abc 441
gatedClock 13:7e1688393abc 442 case HCMD_GETALLREG : // host command 'get-all-registers'.
gatedClock 13:7e1688393abc 443 {
gatedClock 13:7e1688393abc 444 gdRoundTrip++; // expected reply to host is pending.
gatedClock 13:7e1688393abc 445 break;
gatedClock 13:7e1688393abc 446 } // host command 'get-all-registers'.
gatedClock 2:08655e2bb776 447
gatedClock 13:7e1688393abc 448 default : // default.
gatedClock 13:7e1688393abc 449 {
gatedClock 13:7e1688393abc 450 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 451 error("\n\r processIncomingSerial : ERROR unrecognised command from host. \n\r");
gatedClock 13:7e1688393abc 452 break;
gatedClock 13:7e1688393abc 453 } // default.
gatedClock 13:7e1688393abc 454 } // command dependency.
gatedClock 13:7e1688393abc 455
gatedClock 13:7e1688393abc 456 //----
gatedClock 13:7e1688393abc 457
gatedClock 2:08655e2bb776 458 qFromHost.put(pFromHost); // send out for processing.
gatedClock 2:08655e2bb776 459 gcNewCommand = 0; // don't execute until next new command.
gatedClock 2:08655e2bb776 460 } // execute once per new command.
gatedClock 2:08655e2bb776 461 Thread::wait(THREAD_0_WAIT); // multitasking.
gatedClock 2:08655e2bb776 462 } // processIncomingSerial
gatedClock 2:08655e2bb776 463 /*----------------------------------------------//----------------------------*/
gatedClock 2:08655e2bb776 464 void processOutgoingSerial(void) // prepare/transmit data to host.
gatedClock 2:08655e2bb776 465 {
gatedClock 2:08655e2bb776 466 int dLoop; // loop index.
gatedClock 2:08655e2bb776 467
gatedClock 2:08655e2bb776 468 gqToHostEvent = qToHost.get(1); // check for reply back to host.
gatedClock 2:08655e2bb776 469
gatedClock 2:08655e2bb776 470 // if new reply to host:
gatedClock 2:08655e2bb776 471 if (gqToHostEvent.status == osEventMessage)
gatedClock 2:08655e2bb776 472 {
gatedClock 2:08655e2bb776 473 // bring it in from the queue.
gatedClock 2:08655e2bb776 474 gpToHost = (tToHost *) gqToHostEvent.value.p;
gatedClock 13:7e1688393abc 475 if (!gpToHost) // failure detection.
gatedClock 13:7e1688393abc 476 {
gatedClock 13:7e1688393abc 477 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 478 error("\n\r processOutgoingSerial : FATAL NULL gpToHost pointer. \n\r");
gatedClock 13:7e1688393abc 479 }
gatedClock 2:08655e2bb776 480
gatedClock 2:08655e2bb776 481 // clear outgoing buffer.
gatedClock 2:08655e2bb776 482 for (dLoop = 0; dLoop < SER_BYTES; dLoop++) gpcSerialToHost[dLoop] = 0;
gatedClock 13:7e1688393abc 483
gatedClock 13:7e1688393abc 484 switch(gpToHost->cCommand) // the from-host command was looped to here.
gatedClock 2:08655e2bb776 485 {
gatedClock 13:7e1688393abc 486 case HCMD_SETREG : // host command 'set register'.
gatedClock 13:7e1688393abc 487 {
gatedClock 13:7e1688393abc 488 break;
gatedClock 13:7e1688393abc 489 } // host command 'set register'.
gatedClock 13:7e1688393abc 490
gatedClock 13:7e1688393abc 491 case HCMD_GETREG : // host command 'get register'.
gatedClock 13:7e1688393abc 492 {
gatedClock 13:7e1688393abc 493 gpcSerialToHost[0] = binary_to_ascii_nibble( gpToHost->cCommand);
gatedClock 13:7e1688393abc 494 gpcSerialToHost[1] = binary_to_ascii_nibble( gpToHost->cRegisterID);
gatedClock 13:7e1688393abc 495 gpcSerialToHost[2] = binary_to_ascii_nibble(((gpToHost->cRegisterValue) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 496 gpcSerialToHost[3] = binary_to_ascii_nibble(((gpToHost->cRegisterValue) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 497 gpcSerialToHost[4] = '\n'; // signals end of transfer.
gatedClock 13:7e1688393abc 498
gatedClock 13:7e1688393abc 499 // transmit to the host.
gatedClock 13:7e1688393abc 500 serial.writeBlock((uint8_t *) gpcSerialToHost, (uint16_t) SER_BYTES);
gatedClock 13:7e1688393abc 501 gdRoundTrip--; // expected reply sent to host.
gatedClock 13:7e1688393abc 502 break;
gatedClock 13:7e1688393abc 503 } // host command 'get register'.
gatedClock 13:7e1688393abc 504
gatedClock 13:7e1688393abc 505 case HCMD_SETMM : // host command 'set main-memory.'
gatedClock 13:7e1688393abc 506 {
gatedClock 13:7e1688393abc 507 break;
gatedClock 13:7e1688393abc 508 } // host command 'set main-memory.'
gatedClock 13:7e1688393abc 509
gatedClock 13:7e1688393abc 510 case HCMD_GETMM : // host command 'get main-memory.'
gatedClock 13:7e1688393abc 511 {
gatedClock 13:7e1688393abc 512 gpcSerialToHost[0] = binary_to_ascii_nibble( gpToHost->cCommand);
gatedClock 13:7e1688393abc 513 gpcSerialToHost[1] = binary_to_ascii_nibble(((gpToHost->cMMaddress) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 514 gpcSerialToHost[2] = binary_to_ascii_nibble(((gpToHost->cMMaddress) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 515 gpcSerialToHost[3] = binary_to_ascii_nibble(((gpToHost->cMMdataH ) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 516 gpcSerialToHost[4] = binary_to_ascii_nibble(((gpToHost->cMMdataH ) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 517 gpcSerialToHost[5] = binary_to_ascii_nibble(((gpToHost->cMMdataL ) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 518 gpcSerialToHost[6] = binary_to_ascii_nibble(((gpToHost->cMMdataL ) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 519 gpcSerialToHost[7] = '\n'; // signals end of transfer.
gatedClock 2:08655e2bb776 520
gatedClock 2:08655e2bb776 521 // transmit to the host.
gatedClock 13:7e1688393abc 522 serial.writeBlock((uint8_t *) gpcSerialToHost, (uint16_t) SER_BYTES);
gatedClock 13:7e1688393abc 523 gdRoundTrip--; // expected reply sent to host.
gatedClock 13:7e1688393abc 524 break;
gatedClock 13:7e1688393abc 525 } // host command 'get main-memory.'
gatedClock 13:7e1688393abc 526
gatedClock 13:7e1688393abc 527 case HCMD_STEP : // host command 'step-CPU'.
gatedClock 13:7e1688393abc 528 {
gatedClock 13:7e1688393abc 529 break;
gatedClock 13:7e1688393abc 530 } // host command 'step-CPU'.
gatedClock 13:7e1688393abc 531
gatedClock 13:7e1688393abc 532 case HCMD_SETIR : // host command 'set-IR'.
gatedClock 13:7e1688393abc 533 {
gatedClock 13:7e1688393abc 534 break;
gatedClock 13:7e1688393abc 535 } // host command 'set-IR'.
gatedClock 13:7e1688393abc 536
gatedClock 13:7e1688393abc 537 case HCMD_GETALLREG : // host command 'get-all-registers'.
gatedClock 13:7e1688393abc 538 {
gatedClock 13:7e1688393abc 539 gpcSerialToHost[ 0] = binary_to_ascii_nibble( gpToHost->cCommand);
gatedClock 13:7e1688393abc 540 gpcSerialToHost[ 1] = binary_to_ascii_nibble(((gpToHost->cReg0) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 541 gpcSerialToHost[ 2] = binary_to_ascii_nibble(((gpToHost->cReg0) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 542 gpcSerialToHost[ 3] = binary_to_ascii_nibble(((gpToHost->cReg1) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 543 gpcSerialToHost[ 4] = binary_to_ascii_nibble(((gpToHost->cReg1) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 544 gpcSerialToHost[ 5] = binary_to_ascii_nibble(((gpToHost->cReg2) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 545 gpcSerialToHost[ 6] = binary_to_ascii_nibble(((gpToHost->cReg2) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 546 gpcSerialToHost[ 7] = binary_to_ascii_nibble(((gpToHost->cReg3) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 547 gpcSerialToHost[ 8] = binary_to_ascii_nibble(((gpToHost->cReg3) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 548 gpcSerialToHost[ 9] = binary_to_ascii_nibble(((gpToHost->cPC) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 549 gpcSerialToHost[10] = binary_to_ascii_nibble(((gpToHost->cPC) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 550 gpcSerialToHost[11] = binary_to_ascii_nibble(((gpToHost->cIRH) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 551 gpcSerialToHost[12] = binary_to_ascii_nibble(((gpToHost->cIRH) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 552 gpcSerialToHost[13] = binary_to_ascii_nibble(((gpToHost->cIRL) >> 4) & 0x0F);
gatedClock 13:7e1688393abc 553 gpcSerialToHost[14] = binary_to_ascii_nibble(((gpToHost->cIRL) >> 0) & 0x0F);
gatedClock 13:7e1688393abc 554 gpcSerialToHost[15] = '\n'; // signals end of transfer.
gatedClock 13:7e1688393abc 555
gatedClock 2:08655e2bb776 556 // transmit to the host.
gatedClock 13:7e1688393abc 557 serial.writeBlock((uint8_t *) gpcSerialToHost, (uint16_t) SER_BYTES);
gatedClock 13:7e1688393abc 558 gdRoundTrip--; // expected reply sent to host.
gatedClock 13:7e1688393abc 559 break;
gatedClock 13:7e1688393abc 560 } // host command 'get-all-registers'.
gatedClock 13:7e1688393abc 561
gatedClock 13:7e1688393abc 562 default :
gatedClock 13:7e1688393abc 563 {
gatedClock 13:7e1688393abc 564 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 565 error("\n\r processOutgoingSerial : ERROR unrecognised command from host. \n\r");
gatedClock 13:7e1688393abc 566 break;
gatedClock 13:7e1688393abc 567 } // default.
gatedClock 13:7e1688393abc 568 } // switch(gpToHost->cCommand)
gatedClock 13:7e1688393abc 569
gatedClock 2:08655e2bb776 570 mPoolToHost.free(gpToHost); // done with this queue entry.
gatedClock 2:08655e2bb776 571 gpToHost = NULL; // clear pointer.
gatedClock 2:08655e2bb776 572 } // if new reply to host.
gatedClock 2:08655e2bb776 573 } // processOutgoingSerial.
gatedClock 2:08655e2bb776 574 /*----------------------------------------------//----------------------------*/
gatedClock 2:08655e2bb776 575 // the pcSendBuffer and pcReceiveBuffer arrays are not used by this function,
gatedClock 2:08655e2bb776 576 // but they are declared by this function, and their pointers are passed
gatedClock 2:08655e2bb776 577 // down to the mmSPI library for its use of them.
gatedClock 2:08655e2bb776 578 // note- the prefix 'pc' means 'pointer of type character', not 'personal computer'.
gatedClock 2:08655e2bb776 579
gatedClock 2:08655e2bb776 580 void SPIprocessingThread(void const *args) // process host-commands via SPI.
gatedClock 2:08655e2bb776 581 {
gatedClock 2:08655e2bb776 582 char pcSendBuffer [SPI_BYTES]; // SPI send buffer.
gatedClock 2:08655e2bb776 583 char pcReceiveBuffer[SPI_BYTES]; // SPI receive buffer.
gatedClock 13:7e1688393abc 584 char pcRegisters [SPI_BYTES]; // fetch-all-registers vector.
gatedClock 2:08655e2bb776 585 int dHeartbeat; // heartbeat counter.
gatedClock 2:08655e2bb776 586 int dMemoryRead; // read main-memory into this.
gatedClock 2:08655e2bb776 587 int dLoop; // loop index.
gatedClock 2:08655e2bb776 588 osEvent qFromHostEvent; // incoming message event.
gatedClock 2:08655e2bb776 589 tFromHost * pFromHost; // message structure.
gatedClock 2:08655e2bb776 590 tToHost * gpToHost; // message structure.
gatedClock 2:08655e2bb776 591 mmSPI * pSPI; // SPI.
gatedClock 2:08655e2bb776 592
gatedClock 2:08655e2bb776 593 pFromHost = NULL; // NULL pointers.
gatedClock 2:08655e2bb776 594 gpToHost = NULL;
gatedClock 2:08655e2bb776 595 pSPI = NULL;
gatedClock 2:08655e2bb776 596 dHeartbeat = 0; // clear variables.
gatedClock 2:08655e2bb776 597 dMemoryRead = 0;
gatedClock 2:08655e2bb776 598 dLoop = 0;
gatedClock 2:08655e2bb776 599 // clear SPI vectors.
gatedClock 2:08655e2bb776 600 for (dLoop = 0; dLoop < SPI_BYTES; dLoop++) pcSendBuffer [dLoop] = 0;
gatedClock 2:08655e2bb776 601 for (dLoop = 0; dLoop < SPI_BYTES; dLoop++) pcReceiveBuffer[dLoop] = 0;
gatedClock 2:08655e2bb776 602
gatedClock 13:7e1688393abc 603 pSPI = new mmSPI; // SPI allocation.
gatedClock 13:7e1688393abc 604 if (!pSPI) // failure detection.
gatedClock 13:7e1688393abc 605 {
gatedClock 13:7e1688393abc 606 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 607 error("\n\r SPIprocessingThread : FATAL new error for pSPI. \n\r");
gatedClock 13:7e1688393abc 608 }
gatedClock 2:08655e2bb776 609
gatedClock 2:08655e2bb776 610 pSPI->setSendBuffer (pcSendBuffer); // set SPI send buffer.
gatedClock 2:08655e2bb776 611 pSPI->setReceiveBuffer(pcReceiveBuffer); // set SPI receive buffer.
gatedClock 2:08655e2bb776 612 pSPI->setNumberOfBytes(SPI_BYTES); // set SPI number of bytes.
gatedClock 2:08655e2bb776 613 pSPI->setSPIfrequency (SPI_HZ); // set SPI clock frequency.
gatedClock 2:08655e2bb776 614
gatedClock 2:08655e2bb776 615 while(1) // thread loop.
gatedClock 2:08655e2bb776 616 {
gatedClock 2:08655e2bb776 617 qFromHostEvent = qFromHost.get(1); // check for incoming host command.
gatedClock 2:08655e2bb776 618
gatedClock 2:08655e2bb776 619 // if new host command:
gatedClock 2:08655e2bb776 620 if (qFromHostEvent.status == osEventMessage)
gatedClock 2:08655e2bb776 621 {
gatedClock 2:08655e2bb776 622 // bring it in from the queue.
gatedClock 2:08655e2bb776 623 pFromHost = (tFromHost *) qFromHostEvent.value.p;
gatedClock 13:7e1688393abc 624 if (!pFromHost) // failure detection.
gatedClock 13:7e1688393abc 625 {
gatedClock 13:7e1688393abc 626 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 627 error("\n\r SPIprocessingThread : FATAL NULL pFromHost pointer. \n\r");
gatedClock 13:7e1688393abc 628 }
gatedClock 2:08655e2bb776 629
gatedClock 2:08655e2bb776 630 switch(pFromHost->cCommand) // host command decode.
gatedClock 2:08655e2bb776 631 {
gatedClock 2:08655e2bb776 632 case HCMD_SETREG : // set CPU register.
gatedClock 2:08655e2bb776 633 {
gatedClock 2:08655e2bb776 634 switch(pFromHost->cRegisterID) // which register to write to.
gatedClock 2:08655e2bb776 635 {
gatedClock 2:08655e2bb776 636 case CPU_REG_0 : {pSPI->write_register(CPU_REG_0 , pFromHost->cRegisterValue); break;}
gatedClock 2:08655e2bb776 637 case CPU_REG_1 : {pSPI->write_register(CPU_REG_1 , pFromHost->cRegisterValue); break;}
gatedClock 2:08655e2bb776 638 case CPU_REG_2 : {pSPI->write_register(CPU_REG_2 , pFromHost->cRegisterValue); break;}
gatedClock 2:08655e2bb776 639 case CPU_REG_3 : {pSPI->write_register(CPU_REG_3 , pFromHost->cRegisterValue); break;}
gatedClock 2:08655e2bb776 640 case CPU_REG_PC : {pSPI->write_register(CPU_REG_PC, pFromHost->cRegisterValue); break;}
gatedClock 2:08655e2bb776 641 default : {break;}
gatedClock 2:08655e2bb776 642 } // which register to write to.
gatedClock 2:08655e2bb776 643 break;
gatedClock 2:08655e2bb776 644 } // set CPU register.
gatedClock 2:08655e2bb776 645
gatedClock 2:08655e2bb776 646 case HCMD_SETIR: // set instruction register.
gatedClock 2:08655e2bb776 647 {
gatedClock 2:08655e2bb776 648 pSPI->write_IR(pFromHost->cIRValueH, pFromHost->cIRValueL);
gatedClock 2:08655e2bb776 649 break;
gatedClock 2:08655e2bb776 650 } // set instruction register.
gatedClock 2:08655e2bb776 651
gatedClock 2:08655e2bb776 652 case HCMD_GETREG : // get CPU register.
gatedClock 2:08655e2bb776 653 {
gatedClock 2:08655e2bb776 654 gpToHost = mPoolToHost.alloc(); // allocate next pool entry.
gatedClock 13:7e1688393abc 655 if (!gpToHost) // failure detection.
gatedClock 13:7e1688393abc 656 {
gatedClock 13:7e1688393abc 657 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 658 error("\n\r SPIprocessingThread : FATAL malloc error for gpToHost. \n\r");
gatedClock 13:7e1688393abc 659 }
gatedClock 13:7e1688393abc 660
gatedClock 2:08655e2bb776 661 clear_tToHost(gpToHost); // initialize structure.
gatedClock 2:08655e2bb776 662
gatedClock 2:08655e2bb776 663 switch(pFromHost->cRegisterID) // which register to read from.
gatedClock 2:08655e2bb776 664 {
gatedClock 2:08655e2bb776 665 case CPU_REG_0 : {gpToHost->cRegisterValue = pSPI->read_register(CPU_REG_0 ); break;}
gatedClock 2:08655e2bb776 666 case CPU_REG_1 : {gpToHost->cRegisterValue = pSPI->read_register(CPU_REG_1 ); break;}
gatedClock 2:08655e2bb776 667 case CPU_REG_2 : {gpToHost->cRegisterValue = pSPI->read_register(CPU_REG_2 ); break;}
gatedClock 2:08655e2bb776 668 case CPU_REG_3 : {gpToHost->cRegisterValue = pSPI->read_register(CPU_REG_3 ); break;}
gatedClock 2:08655e2bb776 669 case CPU_REG_PC : {gpToHost->cRegisterValue = pSPI->read_register(CPU_REG_PC); break;}
gatedClock 2:08655e2bb776 670 case CPU_IR_H : {gpToHost->cRegisterValue = pSPI->read_register(CPU_IR_H ); break;}
gatedClock 2:08655e2bb776 671 case CPU_IR_L : {gpToHost->cRegisterValue = pSPI->read_register(CPU_IR_L ); break;}
gatedClock 2:08655e2bb776 672 default : {break;}
gatedClock 2:08655e2bb776 673 } // which register to read from.
gatedClock 2:08655e2bb776 674
gatedClock 2:08655e2bb776 675 // loop-back to host.
gatedClock 2:08655e2bb776 676 gpToHost->cCommand = pFromHost->cCommand;
gatedClock 2:08655e2bb776 677 gpToHost->cRegisterID = pFromHost->cRegisterID;
gatedClock 2:08655e2bb776 678
gatedClock 2:08655e2bb776 679 qToHost.put(gpToHost); // send up for processing.
gatedClock 2:08655e2bb776 680 break;
gatedClock 2:08655e2bb776 681 } // get CPU register.
gatedClock 2:08655e2bb776 682
gatedClock 13:7e1688393abc 683 case HCMD_GETALLREG : // get all CPU registers.
gatedClock 13:7e1688393abc 684 {
gatedClock 13:7e1688393abc 685 gpToHost = mPoolToHost.alloc(); // allocate next pool entry.
gatedClock 13:7e1688393abc 686 if (!gpToHost) // failure detection.
gatedClock 13:7e1688393abc 687 {
gatedClock 13:7e1688393abc 688 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 689 error("\n\r SPIprocessingThread : FATAL malloc error for gpToHost. \n\r");
gatedClock 13:7e1688393abc 690 }
gatedClock 13:7e1688393abc 691
gatedClock 13:7e1688393abc 692 clear_tToHost(gpToHost); // initialize structure.
gatedClock 13:7e1688393abc 693
gatedClock 13:7e1688393abc 694 // tell SPI to return all reg content.
gatedClock 13:7e1688393abc 695 pSPI->read_all_registers(pcRegisters);
gatedClock 13:7e1688393abc 696
gatedClock 13:7e1688393abc 697 gpToHost->cReg0 = pcRegisters[6]; // transfer to outgoing structure.
gatedClock 13:7e1688393abc 698 gpToHost->cReg1 = pcRegisters[5];
gatedClock 13:7e1688393abc 699 gpToHost->cReg2 = pcRegisters[4];
gatedClock 13:7e1688393abc 700 gpToHost->cReg3 = pcRegisters[3];
gatedClock 13:7e1688393abc 701 gpToHost->cPC = pcRegisters[2];
gatedClock 13:7e1688393abc 702 gpToHost->cIRH = pcRegisters[1];
gatedClock 13:7e1688393abc 703 gpToHost->cIRL = pcRegisters[0];
gatedClock 13:7e1688393abc 704
gatedClock 13:7e1688393abc 705 // loop-back to host.
gatedClock 13:7e1688393abc 706 gpToHost->cCommand = pFromHost->cCommand;
gatedClock 13:7e1688393abc 707 qToHost.put(gpToHost); // send up for processing.
gatedClock 13:7e1688393abc 708
gatedClock 13:7e1688393abc 709 break;
gatedClock 13:7e1688393abc 710 } // get all CPU registers.
gatedClock 13:7e1688393abc 711
gatedClock 2:08655e2bb776 712 case HCMD_SETMM : // do main-memory write.
gatedClock 2:08655e2bb776 713 {
gatedClock 2:08655e2bb776 714 pSPI->write_memory(pFromHost->cMMdataH, pFromHost->cMMdataL, pFromHost->cMMaddress);
gatedClock 2:08655e2bb776 715 break;
gatedClock 2:08655e2bb776 716 } // do main-memory write.
gatedClock 2:08655e2bb776 717
gatedClock 2:08655e2bb776 718 case HCMD_GETMM : // do main-memory read.
gatedClock 2:08655e2bb776 719 {
gatedClock 13:7e1688393abc 720 gpToHost = mPoolToHost.alloc(); // allocate next pool entry.
gatedClock 13:7e1688393abc 721 if (!gpToHost) // failure detection.
gatedClock 13:7e1688393abc 722 {
gatedClock 13:7e1688393abc 723 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 724 error("\n\r SPIprocessingThread : FATAL malloc error for gpToHost. \n\r");
gatedClock 13:7e1688393abc 725 }
gatedClock 13:7e1688393abc 726
gatedClock 2:08655e2bb776 727 clear_tToHost(gpToHost); // initialize structure.
gatedClock 2:08655e2bb776 728
gatedClock 2:08655e2bb776 729 // read from CPU memory.
gatedClock 2:08655e2bb776 730 dMemoryRead = pSPI->read_memory(pFromHost->cMMaddress);
gatedClock 2:08655e2bb776 731 gpToHost->cMMdataH = (dMemoryRead >> 8) & 0xFF;
gatedClock 2:08655e2bb776 732 gpToHost->cMMdataL = (dMemoryRead >> 0) & 0xFF;
gatedClock 2:08655e2bb776 733
gatedClock 2:08655e2bb776 734 // loop-back to host.
gatedClock 2:08655e2bb776 735 gpToHost->cCommand = pFromHost->cCommand;
gatedClock 2:08655e2bb776 736 gpToHost->cMMaddress = pFromHost->cMMaddress;
gatedClock 2:08655e2bb776 737
gatedClock 2:08655e2bb776 738 qToHost.put(gpToHost); // send up for processing.
gatedClock 2:08655e2bb776 739 break;
gatedClock 2:08655e2bb776 740 } // do main-memory read.
gatedClock 2:08655e2bb776 741
gatedClock 2:08655e2bb776 742 case HCMD_STEP : // step the CPU.
gatedClock 2:08655e2bb776 743 {
gatedClock 2:08655e2bb776 744 pSPI->step();
gatedClock 2:08655e2bb776 745 break;
gatedClock 2:08655e2bb776 746 } // step the CPU.
gatedClock 2:08655e2bb776 747 default : break;
gatedClock 2:08655e2bb776 748 } // host command decode.
gatedClock 2:08655e2bb776 749 mPoolFromHost.free(pFromHost); // done with this queue entry.
gatedClock 2:08655e2bb776 750 pFromHost = NULL; // clear pointer.
gatedClock 2:08655e2bb776 751 } // if new host command.
gatedClock 2:08655e2bb776 752
gatedClock 2:08655e2bb776 753 gulSPIclkCount = pSPI->SPIClockCount(); // propagate to global variable.
gatedClock 2:08655e2bb776 754 gulCPUclkCount = pSPI->CPUClockCount(); // propagate to global variable.
gatedClock 2:08655e2bb776 755
gatedClock 2:08655e2bb776 756 // thread heartbeat.
gatedClock 2:08655e2bb776 757 dHeartbeat++; if (!(dHeartbeat % HB_MODULO)) led1 = !led1;
gatedClock 13:7e1688393abc 758 queueWatchdogThread_1.put((int *) 0,1); // adds 1mS to wait.
gatedClock 13:7e1688393abc 759 Thread::wait(THREAD_1_WAIT - 1); // cooperative multitasking.
gatedClock 2:08655e2bb776 760 } // thread loop.
gatedClock 2:08655e2bb776 761 } // SPIprocessingThread.
gatedClock 2:08655e2bb776 762 /*----------------------------------------------//----------------------------*/
gatedClock 13:7e1688393abc 763 void diagnosticThread(void const *args) // LCD notification & error check.
gatedClock 2:08655e2bb776 764 {
gatedClock 13:7e1688393abc 765 // track previous values.
gatedClock 13:7e1688393abc 766 static unsigned long ulLastSPIclkCount = 1;
gatedClock 13:7e1688393abc 767 static unsigned long ulLastCPUclkCount = 1;
gatedClock 13:7e1688393abc 768 int dHeartbeat; // heartbeat counter.
gatedClock 13:7e1688393abc 769
gatedClock 2:08655e2bb776 770 dHeartbeat = 0; // initialize.
gatedClock 13:7e1688393abc 771
gatedClock 2:08655e2bb776 772 while(1) // thread loop.
gatedClock 2:08655e2bb776 773 {
gatedClock 2:08655e2bb776 774 // if message round trip
gatedClock 2:08655e2bb776 775 // count not consistent.
gatedClock 13:7e1688393abc 776 if (gdRoundTrip > 1025 || gdRoundTrip < 1024)
gatedClock 13:7e1688393abc 777 {
gatedClock 13:7e1688393abc 778 if (ERROR_BOOT) mbed_reset(); else
gatedClock 13:7e1688393abc 779 error("\n\r diagnosticThread : ERROR serial reply underflow. \n\r");
gatedClock 13:7e1688393abc 780 }
gatedClock 2:08655e2bb776 781
gatedClock 13:7e1688393abc 782 // update LCD only if a display
gatedClock 13:7e1688393abc 783 // value has changed. anti-blink,
gatedClock 13:7e1688393abc 784 // save a bit of power.
gatedClock 13:7e1688393abc 785 if (gulSPIclkCount != ulLastSPIclkCount ||
gatedClock 13:7e1688393abc 786 gulCPUclkCount != ulLastCPUclkCount )
gatedClock 13:7e1688393abc 787 {
gatedClock 13:7e1688393abc 788 lcd.cls(); // clear LCD display.
gatedClock 13:7e1688393abc 789 LCD1; // lcd line 1.
gatedClock 13:7e1688393abc 790 lcd.printf(" RTOS CLASS PROJECT");
gatedClock 2:08655e2bb776 791
gatedClock 13:7e1688393abc 792 LCD2; // lcd line 2.
gatedClock 13:7e1688393abc 793 lcd.printf(" %11lu = SPI clocks",gulSPIclkCount);
gatedClock 13:7e1688393abc 794
gatedClock 13:7e1688393abc 795 LCD3; // lcd line 3.
gatedClock 13:7e1688393abc 796 lcd.printf(" %11lu = CPU clocks",gulCPUclkCount);
gatedClock 13:7e1688393abc 797 }
gatedClock 13:7e1688393abc 798
gatedClock 13:7e1688393abc 799 ulLastSPIclkCount = gulSPIclkCount; // pipeline.
gatedClock 13:7e1688393abc 800 ulLastCPUclkCount = gulCPUclkCount; // pipeline.
gatedClock 2:08655e2bb776 801
gatedClock 2:08655e2bb776 802 dHeartbeat++; // thread heartbeat.
gatedClock 2:08655e2bb776 803 if (!(dHeartbeat % HB_MODULO)) led2 = !led2;
gatedClock 13:7e1688393abc 804 queueWatchdogThread_2.put((int *) 0,1); // adds 1mS to wait.
gatedClock 13:7e1688393abc 805 Thread::wait(THREAD_2_WAIT - 1); // multitasking.
gatedClock 2:08655e2bb776 806 } // thread loop.
gatedClock 2:08655e2bb776 807 } // diagnosticThread.
gatedClock 2:08655e2bb776 808 /*----------------------------------------------//----------------------------*/
gatedClock 13:7e1688393abc 809 // this is its own watchdog.
gatedClock 13:7e1688393abc 810
gatedClock 13:7e1688393abc 811 void watchdogThread(void const *args) // overall watchdog.
gatedClock 13:7e1688393abc 812 {
gatedClock 13:7e1688393abc 813 int dHeartbeat; // heartbeat counter.
gatedClock 13:7e1688393abc 814 osEvent queueEvent; // queue event
gatedClock 13:7e1688393abc 815 Watchdog watchdog; // the one and only watchdog.
gatedClock 13:7e1688393abc 816
gatedClock 13:7e1688393abc 817 dHeartbeat = 0; // initialize.
gatedClock 13:7e1688393abc 818
gatedClock 13:7e1688393abc 819 watchdog.kick(WATCHDOG_S); // initialize watchdog.
gatedClock 13:7e1688393abc 820
gatedClock 13:7e1688393abc 821 while (1) // thread loop.
gatedClock 13:7e1688393abc 822 {
gatedClock 13:7e1688393abc 823 // all other threads report-in.
gatedClock 13:7e1688393abc 824 // blocking wait on all of them.
gatedClock 13:7e1688393abc 825 queueEvent = queueWatchdogThread_0.get(osWaitForever);
gatedClock 13:7e1688393abc 826 queueEvent = queueWatchdogThread_1.get(osWaitForever);
gatedClock 13:7e1688393abc 827 queueEvent = queueWatchdogThread_2.get(osWaitForever);
gatedClock 13:7e1688393abc 828
gatedClock 13:7e1688393abc 829 watchdog.kick(); // reset watchdog timer.
gatedClock 13:7e1688393abc 830
gatedClock 13:7e1688393abc 831 dHeartbeat++; // thread heartbeat.
gatedClock 13:7e1688393abc 832 if (!(dHeartbeat % HB_MODULO)) led3 = !led3;
gatedClock 13:7e1688393abc 833 Thread::wait(THREAD_3_WAIT); // multitasking.
gatedClock 13:7e1688393abc 834 } // thread loop.
gatedClock 13:7e1688393abc 835 }
gatedClock 13:7e1688393abc 836 /*----------------------------------------------//----------------------------*/
gatedClock 2:08655e2bb776 837 char ascii_nibble_to_binary(char cAscii) // ascii nibble -> binary.
gatedClock 2:08655e2bb776 838 {
gatedClock 2:08655e2bb776 839 char cBinary; // converted value.
gatedClock 2:08655e2bb776 840
gatedClock 2:08655e2bb776 841 switch(cAscii)
gatedClock 2:08655e2bb776 842 {
gatedClock 2:08655e2bb776 843 case 'F' : {cBinary = 15; break;}
gatedClock 2:08655e2bb776 844 case 'E' : {cBinary = 14; break;}
gatedClock 2:08655e2bb776 845 case 'D' : {cBinary = 13; break;}
gatedClock 2:08655e2bb776 846 case 'C' : {cBinary = 12; break;}
gatedClock 2:08655e2bb776 847 case 'B' : {cBinary = 11; break;}
gatedClock 2:08655e2bb776 848 case 'A' : {cBinary = 10; break;}
gatedClock 2:08655e2bb776 849 case 'f' : {cBinary = 15; break;}
gatedClock 2:08655e2bb776 850 case 'e' : {cBinary = 14; break;}
gatedClock 2:08655e2bb776 851 case 'd' : {cBinary = 13; break;}
gatedClock 2:08655e2bb776 852 case 'c' : {cBinary = 12; break;}
gatedClock 2:08655e2bb776 853 case 'b' : {cBinary = 11; break;}
gatedClock 2:08655e2bb776 854 case 'a' : {cBinary = 10; break;}
gatedClock 2:08655e2bb776 855 case '9' : {cBinary = 9; break;}
gatedClock 2:08655e2bb776 856 case '8' : {cBinary = 8; break;}
gatedClock 2:08655e2bb776 857 case '7' : {cBinary = 7; break;}
gatedClock 2:08655e2bb776 858 case '6' : {cBinary = 6; break;}
gatedClock 2:08655e2bb776 859 case '5' : {cBinary = 5; break;}
gatedClock 2:08655e2bb776 860 case '4' : {cBinary = 4; break;}
gatedClock 2:08655e2bb776 861 case '3' : {cBinary = 3; break;}
gatedClock 2:08655e2bb776 862 case '2' : {cBinary = 2; break;}
gatedClock 2:08655e2bb776 863 case '1' : {cBinary = 1; break;}
gatedClock 2:08655e2bb776 864 case '0' : {cBinary = 0; break;}
gatedClock 2:08655e2bb776 865 default : {cBinary = 0; break;}
gatedClock 2:08655e2bb776 866 } // switch(cAscii).
gatedClock 2:08655e2bb776 867 return(cBinary); // return the binary.
gatedClock 2:08655e2bb776 868 } // ascii_nibble_to_binary.
gatedClock 2:08655e2bb776 869 /*----------------------------------------------//----------------------------*/
gatedClock 2:08655e2bb776 870 char binary_to_ascii_nibble(char cBinary) // binary -> ascii nibble.
gatedClock 2:08655e2bb776 871 {
gatedClock 2:08655e2bb776 872 char cAscii; // converted value.
gatedClock 2:08655e2bb776 873
gatedClock 2:08655e2bb776 874 switch(cBinary)
gatedClock 2:08655e2bb776 875 {
gatedClock 2:08655e2bb776 876 case 15 : {cAscii = 'F'; break;}
gatedClock 2:08655e2bb776 877 case 14 : {cAscii = 'E'; break;}
gatedClock 2:08655e2bb776 878 case 13 : {cAscii = 'D'; break;}
gatedClock 2:08655e2bb776 879 case 12 : {cAscii = 'C'; break;}
gatedClock 2:08655e2bb776 880 case 11 : {cAscii = 'B'; break;}
gatedClock 2:08655e2bb776 881 case 10 : {cAscii = 'A'; break;}
gatedClock 2:08655e2bb776 882 case 9 : {cAscii = '9'; break;}
gatedClock 2:08655e2bb776 883 case 8 : {cAscii = '8'; break;}
gatedClock 2:08655e2bb776 884 case 7 : {cAscii = '7'; break;}
gatedClock 2:08655e2bb776 885 case 6 : {cAscii = '6'; break;}
gatedClock 2:08655e2bb776 886 case 5 : {cAscii = '5'; break;}
gatedClock 2:08655e2bb776 887 case 4 : {cAscii = '4'; break;}
gatedClock 2:08655e2bb776 888 case 3 : {cAscii = '3'; break;}
gatedClock 2:08655e2bb776 889 case 2 : {cAscii = '2'; break;}
gatedClock 2:08655e2bb776 890 case 1 : {cAscii = '1'; break;}
gatedClock 2:08655e2bb776 891 case 0 : {cAscii = '0'; break;}
gatedClock 2:08655e2bb776 892 default : {cAscii = '0'; break;}
gatedClock 2:08655e2bb776 893 } // switch(cBinary).
gatedClock 2:08655e2bb776 894 return(cAscii); // return the binary.
gatedClock 2:08655e2bb776 895 } // binary_to_ascii_nibble.
gatedClock 2:08655e2bb776 896 /*----------------------------------------------//----------------------------*/
gatedClock 2:08655e2bb776 897 void clear_tFromHost(tFromHost * ptFromHost)// clear structure.
gatedClock 2:08655e2bb776 898 {
gatedClock 2:08655e2bb776 899 ptFromHost->cCommand = 0x00;
gatedClock 2:08655e2bb776 900 ptFromHost->cRegisterID = 0x00;
gatedClock 2:08655e2bb776 901 ptFromHost->cRegisterValue = 0x00;
gatedClock 2:08655e2bb776 902 ptFromHost->cIRValueH = 0x00;
gatedClock 2:08655e2bb776 903 ptFromHost->cIRValueL = 0x00;
gatedClock 2:08655e2bb776 904 ptFromHost->cMMaddress = 0x00;
gatedClock 2:08655e2bb776 905 ptFromHost->cMMdataH = 0x00;
gatedClock 2:08655e2bb776 906 ptFromHost->cMMdataL = 0x00;
gatedClock 2:08655e2bb776 907 } // clear_tFromHost.
gatedClock 2:08655e2bb776 908 /*----------------------------------------------//----------------------------*/
gatedClock 2:08655e2bb776 909 void clear_tToHost(tToHost * ptToHost) // clear structure.
gatedClock 2:08655e2bb776 910 {
gatedClock 2:08655e2bb776 911 ptToHost->cCommand = 0x00;
gatedClock 2:08655e2bb776 912 ptToHost->cRegisterID = 0x00;
gatedClock 2:08655e2bb776 913 ptToHost->cRegisterValue = 0x00;
gatedClock 2:08655e2bb776 914 ptToHost->cMMaddress = 0x00;
gatedClock 2:08655e2bb776 915 ptToHost->cMMdataH = 0x00;
gatedClock 2:08655e2bb776 916 ptToHost->cMMdataL = 0x00;
gatedClock 2:08655e2bb776 917 } // clear_tToHost.
gatedClock 2:08655e2bb776 918 /*----------------------------------------------//----------------------------*/