| 1 | #include "macros.h"
 | 
|---|
| 2 | #include <avr/io.h>
 | 
|---|
| 3 | /*
 | 
|---|
| 4 | Mockup for the PLD of Volker Commichaus 
 | 
|---|
| 5 | Bias Crate Controller of the FACt Bias 
 | 
|---|
| 6 | voltage supply system
 | 
|---|
| 7 | 
 | 
|---|
| 8 | Interface to FT245R or 
 | 
|---|
| 9 | something that behaves similarly:
 | 
|---|
| 10 | 
 | 
|---|
| 11 | I am not going to use the Arduino specific digital input
 | 
|---|
| 12 | and digital output routines anymore . they are slow and stupid.
 | 
|---|
| 13 | But I like Serial.println very much.... so :-)
 | 
|---|
| 14 | 
 | 
|---|
| 15 | 
 | 
|---|
| 16 | 
 | 
|---|
| 17 | Digital I/O:
 | 
|---|
| 18 | 
 | 
|---|
| 19 | ATmega: Net Name        :               Int/Out/Bi              : mnemonic
 | 
|---|
| 20 | ---------------------------------------------------------------------
 | 
|---|
| 21 | PC0     :               RXF#            :               IN                                              :       Read from FIFO possible
 | 
|---|
| 22 | PC1     :               TXE#            :               IN                                              :       transmit enable
 | 
|---|
| 23 | PC2 :           RD#                     :               OUT                                             :       Read from 'FIFO'
 | 
|---|
| 24 | PC3 :     WR            :               OUT                                             :       Write to 'FIFO'
 | 
|---|
| 25 | PC4 :                   :               IN                                              : HV down request button - low active
 | 
|---|
| 26 | PD2 :           D0                      :               BI
 | 
|---|
| 27 | PD3     :               D1                      :               BI
 | 
|---|
| 28 | PD4 :           D2                      :               BI
 | 
|---|
| 29 | PD5     :               D3                      :               BI
 | 
|---|
| 30 | PD6     :               D4                      :               BI                                              :       Data
 | 
|---|
| 31 | PD7     :               D5                      :               BI
 | 
|---|
| 32 | PB0     :               D6                      :               BI
 | 
|---|
| 33 | PB1     :               D7                      :               BI
 | 
|---|
| 34 | */
 | 
|---|
| 35 | #define WR PC3
 | 
|---|
| 36 | #define RD PC2
 | 
|---|
| 37 | #define TXE PC1
 | 
|---|
| 38 | #define RXF PC0
 | 
|---|
| 39 | #define BUTTON PC4 
 | 
|---|
| 40 | /*
 | 
|---|
| 41 | -----------------------------------------------------------------------------
 | 
|---|
| 42 | 
 | 
|---|
| 43 | Analog Inputs:
 | 
|---|
| 44 | 
 | 
|---|
| 45 | This Software is intended to be run on an Arduino-like board.
 | 
|---|
| 46 | 12 of the digi I/Os are used to communicate with the outside world,
 | 
|---|
| 47 | which is the FTDI245R in the first place.
 | 
|---|
| 48 | The FTDI245R interconnects this mockup via USB with a PC.
 | 
|---|
| 49 | This mockup will *not* provide any real functionality, as 
 | 
|---|
| 50 | the PLD in the CrateController does. It will just fake this 
 | 
|---|
| 51 | functionality. 
 | 
|---|
| 52 | So when it is ordered to set the voltage to e.g. 80V,
 | 
|---|
| 53 | it will store, that it was ordered so.
 | 
|---|
| 54 | If later it is asked to set the voltage to 10V, with a single 
 | 
|---|
| 55 | command, it will endure a fake 'trip'. 
 | 
|---|
| 56 | Everything, which happens, will be output via Serial Interface.
 | 
|---|
| 57 | 
 | 
|---|
| 58 | It is not intended to input anything via the serial interface,
 | 
|---|
| 59 | since this is not possible in reality anyway.
 | 
|---|
| 60 | */
 | 
|---|
| 61 | 
 | 
|---|
| 62 | // comment this line out, if you want to skip the Serial 
 | 
|---|
| 63 | // Port entirely
 | 
|---|
| 64 | // #define SERIAL_ON
 | 
|---|
| 65 | 
 | 
|---|
| 66 | #define DATABUSWIDTH 8
 | 
|---|
| 67 | #define MAXBOARDS 13
 | 
|---|
| 68 | #define EXISTINGBOARDS 10
 | 
|---|
| 69 | #define CHPERBOARD 32
 | 
|---|
| 70 | #define NUMCHANNELS EXISTINGBOARDS*CHPERBOARD
 | 
|---|
| 71 | 
 | 
|---|
| 72 | #define BUTTON_PRESSED_BIT_POS 4
 | 
|---|
| 73 | #define DANGEROUSSTEP 200
 | 
|---|
| 74 | 
 | 
|---|
| 75 | #define REFFGAPD 3 
 | 
|---|
| 76 | 
 | 
|---|
| 77 | 
 | 
|---|
| 78 | 
 | 
|---|
| 79 | 
 | 
|---|
| 80 | unsigned char message[3];
 | 
|---|
| 81 | unsigned char messageindex=0; 
 | 
|---|
| 82 | unsigned char answer[3];
 | 
|---|
| 83 | unsigned char answerindex=0; 
 | 
|---|
| 84 | 
 | 
|---|
| 85 | unsigned char overcurrentbitmap[NUMCHANNELS/8 ];
 | 
|---|
| 86 | unsigned short voltages[NUMCHANNELS];
 | 
|---|
| 87 | unsigned short setvoltage =0;
 | 
|---|
| 88 | unsigned char statusbit =0;
 | 
|---|
| 89 | unsigned char w = 0;
 | 
|---|
| 90 | unsigned short current =0;
 | 
|---|
| 91 | unsigned char errorbits = 0;
 | 
|---|
| 92 | unsigned char board = 0;
 | 
|---|
| 93 | unsigned char channel = 0;
 | 
|---|
| 94 | 
 | 
|---|
| 95 | unsigned char timeoutcounter =0;
 | 
|---|
| 96 | 
 | 
|---|
| 97 | typedef enum {
 | 
|---|
| 98 |         state_receiving,
 | 
|---|
| 99 |         state_parsing,
 | 
|---|
| 100 |                 state_system_reset,
 | 
|---|
| 101 |                 state_read_status,
 | 
|---|
| 102 |                 state_global_set,
 | 
|---|
| 103 |                 state_set_voltage,
 | 
|---|
| 104 |         state_sending
 | 
|---|
| 105 | } state_t;
 | 
|---|
| 106 | 
 | 
|---|
| 107 |   state_t last_state =  state_set_voltage;
 | 
|---|
| 108 |   state_t state =  state_receiving;
 | 
|---|
| 109 |         unsigned char command =0;
 | 
|---|
| 110 | 
 | 
|---|
| 111 | 
 | 
|---|
| 112 | void setup(){
 | 
|---|
| 113 |   
 | 
|---|
| 114 |         DDRC |= 1<<PC5;
 | 
|---|
| 115 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 116 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 117 |         #ifdef SERIAL_ON
 | 
|---|
| 118 |                 Serial.begin(9600);
 | 
|---|
| 119 |         #endif  
 | 
|---|
| 120 | 
 | 
|---|
| 121 |         // WR and RD are outputs
 | 
|---|
| 122 |         DDRC |= (1<<WR) | (1<<RD);
 | 
|---|
| 123 |         // WR idles low
 | 
|---|
| 124 |         PORTC &= ~1<<WR;
 | 
|---|
| 125 |         // RD idles high
 | 
|---|
| 126 |         PORTC |= (1<<RD);
 | 
|---|
| 127 | 
 | 
|---|
| 128 |         // RXF, TXE and BUTTON are inputs
 | 
|---|
| 129 |         DDRC &= ~( (1<<TXE) | (1<<RXF) | (1<<BUTTON) ); 
 | 
|---|
| 130 |   
 | 
|---|
| 131 |         // TXE and RXF should be held high by the FT245 or Arduino anyway, 
 | 
|---|
| 132 |         // but for convenience
 | 
|---|
| 133 |         // I pull them up, with ~20kohm reistors.
 | 
|---|
| 134 | 
 | 
|---|
| 135 |         PORTC |= 1<<TXE;
 | 
|---|
| 136 |         PORTC |= 1<<RXF;
 | 
|---|
| 137 | 
 | 
|---|
| 138 |         // The button should be low active.
 | 
|---|
| 139 |         // so I need a pull up here as well.
 | 
|---|
| 140 |         PORTC |= 1<< BUTTON;
 | 
|---|
| 141 | 
 | 
|---|
| 142 |         // this affects PD2..PD7, PB0 and PB1.
 | 
|---|
| 143 |         //MakeDataBusInput ();
 | 
|---|
| 144 |         MAKEDATABUSINPUT;
 | 
|---|
| 145 |         
 | 
|---|
| 146 |         // for security, all unused pins I set to inputs, but 
 | 
|---|
| 147 |         // this might be anyway the atmega default case...
 | 
|---|
| 148 |         //DDRC &= ~( (1<<PC5) | (1<<PC6) | (1<<PC7) );  //arduino states: PC7 is not defined in this scope
 | 
|---|
| 149 |         DDRC &= ~( (1<<PC5) | (1<<PC6)  );      
 | 
|---|
| 150 |         DDRC |= 1<<PC5;
 | 
|---|
| 151 |         DDRB &= ~( (1<<PB2) | (1<<PB3) | (1<<PB4) );
 | 
|---|
| 152 |         
 | 
|---|
| 153 |         // to PB5 a LED is connected
 | 
|---|
| 154 |         DDRB |= 1<<PB5;
 | 
|---|
| 155 |         // this LED is high active ... I switch it on & off quickly
 | 
|---|
| 156 |         PORTB |= 1<<PB5;
 | 
|---|
| 157 |         delay (100);
 | 
|---|
| 158 |         PORTB &= ~(1<<PB5);
 | 
|---|
| 159 | 
 | 
|---|
| 160 |         #ifdef SERIAL_ON
 | 
|---|
| 161 |         Serial.println("\n\nwelcome to the arduino FACT bias crate controller");
 | 
|---|
| 162 |         #endif
 | 
|---|
| 163 | 
 | 
|---|
| 164 |         for (unsigned short channel = 0; channel < NUMCHANNELS; channel++)
 | 
|---|
| 165 |                 voltages[channel] = 0;
 | 
|---|
| 166 |         for (unsigned short channel = 0; channel < NUMCHANNELS/8; channel++)
 | 
|---|
| 167 |                 overcurrentbitmap[channel] = 0x00;
 | 
|---|
| 168 |         
 | 
|---|
| 169 |         /*
 | 
|---|
| 170 |         delay (1000);
 | 
|---|
| 171 |         delay (1000);
 | 
|---|
| 172 |         delay (1000);
 | 
|---|
| 173 |         delay (1000);
 | 
|---|
| 174 |         delay (1000);
 | 
|---|
| 175 |         delay (1000);
 | 
|---|
| 176 |         delay (1000);
 | 
|---|
| 177 |         delay (1000);
 | 
|---|
| 178 |         delay (1000);
 | 
|---|
| 179 |         delay (1000);
 | 
|---|
| 180 |         delay (1000);
 | 
|---|
| 181 |         delay (1000);
 | 
|---|
| 182 |         delay (1000);
 | 
|---|
| 183 |         delay (1000);
 | 
|---|
| 184 |         delay (1000);
 | 
|---|
| 185 |         delay (1000);
 | 
|---|
| 186 |         delay (1000);
 | 
|---|
| 187 |         delay (1000);
 | 
|---|
| 188 |         delay (1000);
 | 
|---|
| 189 |         delay (1000);
 | 
|---|
| 190 |         delay (1000);
 | 
|---|
| 191 |         delay (1000);
 | 
|---|
| 192 |         delay (1000);
 | 
|---|
| 193 | */
 | 
|---|
| 194 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 195 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 196 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 197 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 198 | }
 | 
|---|
| 199 | 
 | 
|---|
| 200 | void loop(){
 | 
|---|
| 201 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 202 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 203 | 
 | 
|---|
| 204 |         #ifdef SERIAL_ON  
 | 
|---|
| 205 |   if (state != last_state){
 | 
|---|
| 206 |         Serial.print("state: ");
 | 
|---|
| 207 |                 switch (state){
 | 
|---|
| 208 |                         case state_receiving:
 | 
|---|
| 209 |             Serial.println("receiving");
 | 
|---|
| 210 |                                 break;
 | 
|---|
| 211 |             case state_parsing:
 | 
|---|
| 212 |             Serial.println("parsing");
 | 
|---|
| 213 |                                 break;
 | 
|---|
| 214 |                   case state_system_reset:
 | 
|---|
| 215 |             Serial.println("sys reset");
 | 
|---|
| 216 |                                 break;
 | 
|---|
| 217 |                   case state_read_status:
 | 
|---|
| 218 |             Serial.println("read stat");
 | 
|---|
| 219 |                                 break;
 | 
|---|
| 220 |                   case state_global_set:
 | 
|---|
| 221 |             Serial.println("global set");
 | 
|---|
| 222 |                                 break;
 | 
|---|
| 223 |                   case state_set_voltage:
 | 
|---|
| 224 |             Serial.println("set volt");
 | 
|---|
| 225 |                                 break;
 | 
|---|
| 226 |             case state_sending:
 | 
|---|
| 227 |             Serial.println("sending");
 | 
|---|
| 228 |                                 break;
 | 
|---|
| 229 |                 }
 | 
|---|
| 230 |   }
 | 
|---|
| 231 |   last_state = state;
 | 
|---|
| 232 |         #endif
 | 
|---|
| 233 | 
 | 
|---|
| 234 | switch( state ) {
 | 
|---|
| 235 |                 case state_receiving:
 | 
|---|
| 236 |                         //PORTB |= 1<<PB5;
 | 
|---|
| 237 |                         //delay (100);
 | 
|---|
| 238 |                         //PORTB &= ~(1<<PB5);
 | 
|---|
| 239 |         // empfange bytes vom FT245 und 
 | 
|---|
| 240 |                         // schreibe diese in ein byte-array der Länge 3
 | 
|---|
| 241 |                         // wenn vollständig, dann gehe in zustand: state_parsing
 | 
|---|
| 242 |                         if ( ISRXFLOW ){
 | 
|---|
| 243 |                                 // read one byte
 | 
|---|
| 244 |                                 CLRBIT(PORTC, RD);
 | 
|---|
| 245 |                                 message[messageindex]=READFROMDATABUS;
 | 
|---|
| 246 |                                 SETBIT(PORTC, RD); 
 | 
|---|
| 247 |                                 messageindex++;
 | 
|---|
| 248 |                                 while ( ISRXFLOW ){}
 | 
|---|
| 249 |                         }
 | 
|---|
| 250 |                         if (messageindex == 3) {
 | 
|---|
| 251 |                                 messageindex = 0;
 | 
|---|
| 252 |                                 state = state_parsing;
 | 
|---|
| 253 |                         }
 | 
|---|
| 254 |                         break;
 | 
|---|
| 255 | 
 | 
|---|
| 256 |                 case state_parsing:
 | 
|---|
| 257 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 258 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 259 |                         #ifdef SERIAL_ON
 | 
|---|
| 260 |                         for (int i=0; i<3; i++){
 | 
|---|
| 261 |                                 Serial.print(message[i], HEX);
 | 
|---|
| 262 |                                 if (i<2)
 | 
|---|
| 263 |                                         Serial.print(" ");
 | 
|---|
| 264 |                                 else
 | 
|---|
| 265 |                                         Serial.println("");
 | 
|---|
| 266 |                         }
 | 
|---|
| 267 |                         #endif
 | 
|---|
| 268 |                         // schau in das 3-byte array und finde heraus, was zu tun ist.
 | 
|---|
| 269 |                         // je nachdem was zu tun ist, wird die state variable anders gesetzt. 
 | 
|---|
| 270 |                         // die message wird nicht verändert .. also die ersten bits nicht weggeschnitten oder so.
 | 
|---|
| 271 |                         //
 | 
|---|
| 272 |                         command = (message[0]) >> 5;
 | 
|---|
| 273 |                         // das & 0x07 ist hier garnicht unbedingt notwendig, aber
 | 
|---|
| 274 |                         // es stellt sicher, dass ich mit case 0 bis case 7 
 | 
|---|
| 275 |                         // wirklich alle cases bearbeitet habe.. dann brauch
 | 
|---|
| 276 |                         // ich keinen default case.
 | 
|---|
| 277 |                         switch ( command & 0x07 ) {              
 | 
|---|
| 278 |                                 case 0:
 | 
|---|
| 279 |                                         // System Reset
 | 
|---|
| 280 |                                         state = state_system_reset;
 | 
|---|
| 281 |                                         break;
 | 
|---|
| 282 |         
 | 
|---|
| 283 |                                 case 1:
 | 
|---|
| 284 |                                         // Read Channel Status & Current
 | 
|---|
| 285 |                                         state = state_read_status;
 | 
|---|
| 286 |                                         break;
 | 
|---|
| 287 | 
 | 
|---|
| 288 |                                 case 2:
 | 
|---|
| 289 |                                         // Global Set
 | 
|---|
| 290 |                                         state = state_global_set;
 | 
|---|
| 291 |                                         break;
 | 
|---|
| 292 |         
 | 
|---|
| 293 |                                 case 3:
 | 
|---|
| 294 |                                         // Channel Set to voltage
 | 
|---|
| 295 |                                         state = state_set_voltage;
 | 
|---|
| 296 |                                         break;
 | 
|---|
| 297 |         
 | 
|---|
| 298 |         default:
 | 
|---|
| 299 |                                         // TODO Alarm, das ist unfug, aber nur zum testen
 | 
|---|
| 300 |                                         answer[0] = 0xff ;
 | 
|---|
| 301 |                                         answer[1] = 0x00 ;
 | 
|---|
| 302 |                                         answer[2] = 0xff ;
 | 
|---|
| 303 |                                   state = state_sending;
 | 
|---|
| 304 |           break;
 | 
|---|
| 305 |                                 }
 | 
|---|
| 306 |                                   //state = state_receiving;
 | 
|---|
| 307 |     break;
 | 
|---|
| 308 | 
 | 
|---|
| 309 |                 case state_system_reset:
 | 
|---|
| 310 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 311 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 312 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 313 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 314 |                         w = (w+1)%8;
 | 
|---|
| 315 |                         // Die message hat also den Befehl 'crate_reset' enthalten
 | 
|---|
| 316 |                         // Also werde ich mal alles resetten, was ich so weiss 
 | 
|---|
| 317 |                         // Ist aber wichtig, nochmal nach zu lesen, was eigentlich 
 | 
|---|
| 318 |                         // wirklich resetted werden muss.
 | 
|---|
| 319 |                         // 
 | 
|---|
| 320 |                         // System reset setzt nicht die Spannungen auf null
 | 
|---|
| 321 |                         // for (unsigned short channel = 0; channel < NUMCHANNELS; channel++)
 | 
|---|
| 322 |                         // voltages[channel] = 0;
 | 
|---|
| 323 |                         for (unsigned short channel = 0; channel < NUMCHANNELS/8; channel++)
 | 
|---|
| 324 |                                 overcurrentbitmap[channel] = 0x00;
 | 
|---|
| 325 |                         answer[0] = w<<4;
 | 
|---|
| 326 |                         answer[1] = 0x00;
 | 
|---|
| 327 |                         answer[2] = 0x00;
 | 
|---|
| 328 |                         state = state_sending;
 | 
|---|
| 329 |                         break;
 | 
|---|
| 330 | 
 | 
|---|
| 331 |                 case state_read_status:
 | 
|---|
| 332 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 333 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 334 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 335 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 336 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 337 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 338 |                         w = (w+1)%8;
 | 
|---|
| 339 |                         // Hier hat der User, nach dem status eines bestimmten 
 | 
|---|
| 340 |                         // boards und channels gefragt. Wo nach wurde gefragt?
 | 
|---|
| 341 |                         board = (message[0] & 0x1e) >> 1;
 | 
|---|
| 342 |                         channel = ((message[0] & 0x01) << 4) | ((message[1] & 0xf0) >> 4) ;
 | 
|---|
| 343 |                         // Jetzt ist interessant, ob das angefragte board vorhanden ist
 | 
|---|
| 344 |                         if (board < EXISTINGBOARDS){ // board exists
 | 
|---|
| 345 |                                 // we calculate the current I=U/R
 | 
|---|
| 346 |                                 current = voltages[board * CHPERBOARD + channel] / REFFGAPD;
 | 
|---|
| 347 |                                 answer[0] = (statusbit<<7) | (w<<4) | (unsigned char)((current>>8) & 0x000f);
 | 
|---|
| 348 |                                 answer[1] = (unsigned   char)(current & 0x00ff);
 | 
|---|
| 349 |                                 answer[2] = (errorbits<<4) | (board&0x0f);
 | 
|---|
| 350 |                         } else { // board is not exisiting
 | 
|---|
| 351 |                                 answer[0] = w<<4;
 | 
|---|
| 352 |                                 answer[1] = 0x00;
 | 
|---|
| 353 |                                 answer[2] = 0xf0 | (board&0x0f);
 | 
|---|
| 354 |                         }
 | 
|---|
| 355 |                         state = state_sending;
 | 
|---|
| 356 |                         break;
 | 
|---|
| 357 | 
 | 
|---|
| 358 |                 
 | 
|---|
| 359 |                 case state_set_voltage:
 | 
|---|
| 360 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 361 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 362 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 363 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 364 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 365 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 366 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 367 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 368 |                         w = (w+1)%8;
 | 
|---|
| 369 |                         board = (message[0] & 0x1e) >> 1;
 | 
|---|
| 370 |                         channel = ((message[0] & 0x01) << 4) | ((message[1] & 0xf0) >> 4) ;
 | 
|---|
| 371 |                         errorbits = 0;
 | 
|---|
| 372 |                         statusbit = 0;
 | 
|---|
| 373 |         
 | 
|---|
| 374 |                         errorbits |= ISBUTTONPRESSED<<(BUTTON_PRESSED_BIT_POS);
 | 
|---|
| 375 |                         
 | 
|---|
| 376 |                         if ( board < EXISTINGBOARDS){
 | 
|---|
| 377 |                                 setvoltage = ((unsigned short)*message+1) & 0x0fff;
 | 
|---|
| 378 |                                 if ( abs(voltages[board*CHPERBOARD + channel] - setvoltage) > DANGEROUSSTEP ) {// overcurrent!
 | 
|---|
| 379 |                                         overcurrentbitmap[board*CHPERBOARD/8+channel/8] |= 1<<channel%8;
 | 
|---|
| 380 |                                         statusbit = 1;
 | 
|---|
| 381 |                                 }
 | 
|---|
| 382 |                                 voltages[board*CHPERBOARD + channel] = setvoltage;
 | 
|---|
| 383 |                                 current = voltages[board * CHPERBOARD + channel] / REFFGAPD;
 | 
|---|
| 384 |                         } else {
 | 
|---|
| 385 |                                 current = 0;
 | 
|---|
| 386 |                                 errorbits |= 0x07;
 | 
|---|
| 387 |                         }
 | 
|---|
| 388 | 
 | 
|---|
| 389 | 
 | 
|---|
| 390 |                         answer[0] =  statusbit<<7 | w<<4 | (unsigned char)((current>>8) & 0x000f);
 | 
|---|
| 391 |                         answer[1] = (unsigned   char)(current & 0x00ff);
 | 
|---|
| 392 |                         answer[2] = errorbits<<4 | (board&0x0f);
 | 
|---|
| 393 | 
 | 
|---|
| 394 |                         state = state_sending;
 | 
|---|
| 395 |                         break;
 | 
|---|
| 396 | 
 | 
|---|
| 397 |                 case state_global_set:
 | 
|---|
| 398 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 399 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 400 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 401 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 402 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 403 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 404 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 405 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 406 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 407 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 408 |                         w = (w+1)%8;
 | 
|---|
| 409 |                         // Erstmal schauen, was der user für eine Spannung setzen wollte
 | 
|---|
| 410 |                         setvoltage = ((unsigned short)*message+1) & 0x0fff;
 | 
|---|
| 411 |                         // so .. da jemand eine Spannung hoch oder runter setzt, könnte es sein
 | 
|---|
| 412 |                         // dass ein überstrom zustand auftritt ... sagen wir mal, wenn die Spannung in einem 
 | 
|---|
| 413 |                         // Schritt um mehr als 3 geändert wird, dann gibts nen Überstrom
 | 
|---|
| 414 |                         // das ist eigentlich mist, aber ich will erstmal irgendwas hier einbauen.
 | 
|---|
| 415 |                         for (unsigned char b=0; b < EXISTINGBOARDS; b++)
 | 
|---|
| 416 |                                 for (unsigned char c=0; c < CHPERBOARD; c++){
 | 
|---|
| 417 |                                         if ( abs(voltages[b*CHPERBOARD + c] - setvoltage) > DANGEROUSSTEP )// overcurrent!
 | 
|---|
| 418 |                                                 overcurrentbitmap[b*CHPERBOARD/8+c/8] |= 1<<c%8;
 | 
|---|
| 419 |                                         voltages[b*CHPERBOARD + c] = setvoltage;
 | 
|---|
| 420 |                                 }
 | 
|---|
| 421 |                         answer[0] = w<<4 ;
 | 
|---|
| 422 |                         answer[1] = 0x00 ;
 | 
|---|
| 423 |                         answer[2] = 0x00 ;
 | 
|---|
| 424 |                         state = state_sending;
 | 
|---|
| 425 |                         break;
 | 
|---|
| 426 |         
 | 
|---|
| 427 |                 case state_sending:
 | 
|---|
| 428 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 429 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 430 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 431 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 432 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 433 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 434 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 435 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 436 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 437 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 438 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 439 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 440 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 441 |                         PORTC ^= 1<<PC5;
 | 
|---|
| 442 |                         // in diesem State bleibe ich solange es dauert, um die 'answer' 
 | 
|---|
| 443 |                         // zu senden. Falls das senden aus irgendeinem Grund nicht gehen sollte
 | 
|---|
| 444 |                         // bleibe ich *für immer* in diesem state.
 | 
|---|
| 445 |                         if ( ISTXELOW ){
 | 
|---|
| 446 |                                 MAKEDATABUSOUTPUT;
 | 
|---|
| 447 |                                 PUTONDATABUS(answer[answerindex]);
 | 
|---|
| 448 |                                 SETBIT (PORTC, WR);
 | 
|---|
| 449 |                                 delayMicroseconds(6);
 | 
|---|
| 450 |                                 CLRBIT (PORTC, WR);
 | 
|---|
| 451 |                                 MAKEDATABUSINPUT;
 | 
|---|
| 452 |                                 
 | 
|---|
| 453 |                                 answerindex++;
 | 
|---|
| 454 |                                 //wait for txe going high
 | 
|---|
| 455 |                                 while ( ISTXELOW ){ }
 | 
|---|
| 456 |                         } 
 | 
|---|
| 457 |                                 
 | 
|---|
| 458 |                         if (answerindex == 3 || timeoutcounter >250) {
 | 
|---|
| 459 |                                 answerindex =0;
 | 
|---|
| 460 |                                 state = state_receiving;
 | 
|---|
| 461 |                         }
 | 
|---|
| 462 |                         break;  
 | 
|---|
| 463 |                         
 | 
|---|
| 464 |                 default:
 | 
|---|
| 465 |                                 // ungültiger Zustand!
 | 
|---|
| 466 |         // Sollte eigentlich nie auftreten
 | 
|---|
| 467 |                                 // Wenn er auftritt, dann erzeuge ich eine Nachricht via 
 | 
|---|
| 468 |                                 // USB.
 | 
|---|
| 469 |                         break;
 | 
|---|
| 470 |     }
 | 
|---|
| 471 |     
 | 
|---|
| 472 | }
 | 
|---|
| 473 | 
 | 
|---|