Modular Pinball Machine Controller

pinkit.h

00001 #ifndef PINKIT_H
00002 #define PINKIT_H
00003 
00014 #include "pinkit_defs.h"
00015 #include "types.h"
00016 
00017 //define PK_SOUND
00018 //define AUXGI_MODE
00019 
00020 #if defined(PK_SOUND)
00021   #warning pinkit.h: pk_sound mode in pk_common
00022 #endif
00023 
00024 /* These should be in pinkit_defs.h file */
00025 #define COIL0           LATAbits.LATA5
00026 #define COIL1           LATAbits.LATA4
00027 #define COIL2           LATAbits.LATA3
00028 #define COIL3           LATAbits.LATA2
00029 #define COIL4           coil_dummy
00030 #define COIL5           coil_dummy
00031 #define COIL6           coil_dummy
00032 #define COIL7           coil_dummy
00033 
00034 #define LAMP0           LATAbits.LATA0
00035 #define LAMP1           LATAbits.LATA1
00036 #define LAMP2           LATBbits.LATB6
00037 #define LAMP3           LATBbits.LATB7
00038 #define LAMP4           LATCbits.LATC4
00039 #define LAMP5           LATCbits.LATC5
00040 #define LAMP6           LATCbits.LATC6
00041 #define LAMP7           LATCbits.LATC7
00042 
00043 #define SW0             PORTCbits.RC0
00044 #define SW1             PORTCbits.RC1
00045 #define SW2             PORTCbits.RC2
00046 #define SW3             PORTCbits.RC3
00047 #define SW4             PORTCbits.RC4
00048 #define SW5             PORTCbits.RC5
00049 #define SW6             PORTCbits.RC6
00050 #define SW7             PORTCbits.RC7
00051 
00052 #define ID0             PORTBbits.RB5
00053 #define ID1             PORTBbits.RB4
00054 #define ID2             PORTBbits.RB1
00055 #define ID3             PORTBbits.RB0
00056 
00057 
00058 //define BLINK_RATE(n)   (UINT16) (2000L >> (n))
00059 #define ERROR_FLAG(n)   reg[15] |= ((BYTE)(1UL << (n)))
00060 #define TEST_DELAY      200
00061 
00062 
00063 /* Note that space is reserved for 16 devices to avoid having out-of-range checks on the */
00064 /* incoming messages.  Targeting a device that doesn't exist will be a no-op. */
00065 #if defined (PK_SOUND)
00066   #define MAX_LAMPS     0
00067   #define MAX_SWITCHES  1
00068   #define MAX_COILS     0
00069   #define MAX_DIGITS    1
00070   #define MAX_REGS      16
00071 #else
00072   #if !defined (MAX_LAMPS)
00073   #define MAX_LAMPS     16
00074   #endif
00075   #define MAX_SWITCHES  16
00076   #define MAX_COILS     16
00077   #define MAX_DIGITS     7
00078   #define MAX_REGS      16
00079 #endif
00080 
00091 #if !defined(MAX_PLAYER)
00092 #define MAX_PLAYER       1
00093 #endif
00094 
00095 #if !defined(COIL_PULSE)
00096 #define COIL_PULSE       40
00097 #endif
00098 
00099 #if !defined(MAX_CREDITS)
00100 #define MAX_CREDITS             29
00101 #endif
00102 
00103 #if !defined(PK_SOUND)
00104   #if !defined(MAX_ATTRACT)
00105     #define MAX_ATTRACT     64
00106   #endif
00107 #endif
00108 #define BALL_WDT        200     /* 20 seconds */
00109 
00118 typedef union PK_MSG_ID_T {
00119    unsigned long id;
00120    struct {
00121       BYTE BYTE_0;
00122       BYTE BYTE_1;
00123       BYTE BYTE_2;
00124       BYTE BYTE_3;
00125    } u;
00126 } PK_MSG_ID;
00127 
00134 struct LAMP {
00135   BYTE state;           
00136   BYTE group;           
00137   union {
00138     UINT16 patt_all;         
00139     struct { BYTE patt_lo;   
00140              BYTE patt_hi;   
00141            };
00142     } pattern;          
00143   UINT16 timer;         
00144   BYTE blink;           
00145 };
00146 extern BYTE cmd_patt[2];
00147 
00148 #define SW_LEVEL        0x7F
00149 #define SW_EDGE_SLOWEST 0x3F
00150 #define SW_EDGE_SLOW    0x1F
00151 #define SW_EDGE_MED     0x07
00152 #define SW_EDGE         0x03
00153 #define SW_EDGE_FAST    0x01
00154 
00157 struct SW {
00158   BYTE state;           
00159   BYTE type;            
00160   BYTE score;           
00161   BYTE coil;            
00162   BYTE cmd[2];          
00163 };
00164 
00168 struct COIL {
00169   BYTE state;           
00170   BYTE timer;           
00171   BYTE max;             
00172 };
00173 
00178 struct PK_CMD_FUNC {
00179   BYTE ttype;              
00180   union  {
00181      BYTE cmd[2];          
00182      void (*func)(void);   
00183   } fc;                    
00184 };
00185 
00186 struct EVENT {
00187   BYTE next;
00188   struct PK_CMD_FUNC u;
00189 };
00190 
00194 struct PK_QCMD {
00195   BYTE cmd1;    
00196   BYTE cmd2;    
00197 };
00198 
00199 #ifdef CPU_MODE
00200 #define ATTRACT_OFF             0
00201 #define ATTRACT_SWEEP_LEFT      1
00202 #define ATTRACT_SWEEP_RIGHT     2
00203 #define ATTRACT_CHASE           3
00204 #define ATTRACT_SWEEP_UP        4
00205 #define ATTRACT_SWEEP_DOWN      5
00206 #define ATTRACT_FADE_ON         6
00207 #define ATTRACT_FADE_OFF        7
00208 #define ATTRACT_TWINKLE         8
00209 #define ATTRACT_RANDOM          9
00210 #define ATTRACT_RESET          10
00211 #define MAX_ATTRACT_MODE        9
00212 
00213 extern struct {
00214   BYTE lampID;
00215   BYTE x;
00216   BYTE y;
00217 } attract[64];
00218 extern BYTE attract_rate;
00219 extern BYTE attract_enable = 0xFF;
00220 #endif
00221 
00233 typedef enum {
00234   MS_RESET = 0,   
00235   MS_GAME_OVER,   
00236   MS_NEW_GAME,    
00237   MS_NEW_BALL,
00238   MS_LAUNCH_BALL,
00239   MS_PLAY_BALL,   
00241   MS_COLLECT_BONUS,
00242   MS_END_BALL,
00243   MS_CUSTOM1,    
00244   MS_CUSTOM2,    
00245   MS_MATCH1,
00246   MS_MATCH2,
00247   MS_END_GAME,
00248   MS_ABORT_GAME,
00249   MS_TILT,
00250   MS_SLAM,
00251   MS_SLAM_HOLD,
00252   MS_ATTRACT, MS_ATTRACT_OFF,
00253   MS_NV_UPDATE,
00254   MS_DIAG, MS_DIAG_ADJUST1, MS_DIAG_ADJUST2, MS_DIAG_LAMP, MS_DIAG_COIL, MS_DIAG_SWITCH, MS_DIAG_PINCAN,
00255   MS_CLOCK }  MACHINE_STATE;
00256 
00257 //define ID_PANIC      0x110    /* Lower IDs have higher priority in CAN protocol */
00258 //define ID_DIAG       0x120
00259 //define ID_COIL       0x140
00260 //define ID_SW         0x150
00261 //define ID_LAMP       0x160
00262 //define ID_SCORE      0x180
00263 //define ID_SOUND      0x190
00264 //define ID_LOWPRI     0x1E0
00265 
00266 #define MSG_REG_READ  0x00
00267 #define MSG_REG_WRITE 0x10
00268 #define MSG_2         0x20
00269 #define MSG_VOLUME    0x30
00270 #define MSG_COIL      0x40
00271 #define MSG_SW        0x50
00272 #define MSG_LAMP      0x60
00273 #define MSG_LGROUP    0x70
00274 #define MSG_SCORE     0x80
00275 #define MSG_SOUND     0x90
00276 #define MSG_PLAY      0x90
00277 #define MSG_ASSIGN    0xA0
00278 #define MSG_BLINK     0xB0
00279 #define MSG_CTL       0xC0
00280 #define MSG_D         0xD0
00281 #define MSG_XOP       0xE0
00282 #define MSG_USER      0xF0
00283 
00284 #define MSG_COIL_OFF   (MSG_COIL | 0x00)
00285 #define MSG_COIL_ON    (MSG_COIL | 0x0F)
00286 #define MSG_COIL_PULSE (MSG_COIL | 0x03)
00287 
00288 #define MSG_SW_OFF       (MSG_SW | 0x00)
00289 #define MSG_SW_ON        (MSG_SW | 0x01)
00290 #define MSG_SW_EDGE      (MSG_SW | SW_EDGE)
00291 #define MSG_SW_QUERY     (MSG_SW | 0x04)
00292 
00293 #define MSG_LAMP_OFF  (MSG_LAMP | 0x00)
00294 #define MSG_LAMP_ON   (MSG_LAMP | 0x0F)
00295 
00296 #define MSG_LGROUP_OFF    (MSG_LGROUP | 0x00)
00297 #define MSG_LGROUP_ON     (MSG_LGROUP | 0x01)
00298 #define MSG_LGROUP_RESET  (MSG_LGROUP | 0x03)
00299 #define MSG_LGROUP_TOGGLE (MSG_LGROUP | 0x04)
00300 #define MSG_LAMP_FLASH    0x77
00301 
00302 #define MSG_SCORE_RESET (MSG_SCORE | 0x00)
00303 #define MSG_SET_PLAYER  (MSG_SCORE | 0x01)
00304 #define MSG_SCORE_SET   (MSG_SCORE | 0x02)
00305 #define MSG_SCORE_ADD   (MSG_SCORE | 0x08)
00306 
00307 #define TRACK1          0x00
00308 #define TRACK2          0x01
00309 #define TRACK3          0x02
00310 #define TRACK_ALL       0x03
00311 #define VOL_MASTER      0x03
00312 
00313 #define CHANNEL_RIGHT    0x04
00314 #define CHANNEL_LEFT     0x08
00315 #define CHANNEL_BOTH     0x0C
00316 
00317 #define MSG_VOLUME_MASTER         (MSG_VOLUME | VOL_MASTER | CHANNEL_BOTH)
00318 #define MSG_VOLUME_MASTER_RIGHT   (MSG_VOLUME | VOL_MASTER | CHANNEL_RIGHT)
00319 #define MSG_VOLUME_MASTER_LEFT    (MSG_VOLUME | VOL_MASTER | CHANNEL_LEFT)
00320 #define MSG_VOLUME_TRACK1         (MSG_VOLUME | TRACK1 | CHANNEL_BOTH)
00321 #define MSG_VOLUME_TRACK2         (MSG_VOLUME | TRACK2 | CHANNEL_BOTH)
00322 #define MSG_VOLUME_TRACK3         (MSG_VOLUME | TRACK3 | CHANNEL_BOTH)
00323 #define MSG_SET_SOUND_BANK        (MSG_VOLUME | 0x00);
00324 
00325 #define MSG_PLAY_STOP      (MSG_PLAY | 0x00)
00326 #define MSG_PLAY_ONCE      (MSG_PLAY | 0x04)
00327 #define MSG_PLAY_NEXT      (MSG_PLAY | 0x08)
00328 #define MSG_PLAY_REPEAT    (MSG_PLAY | 0x0C)
00329 
00330 #define MSG_PLAY_TRACK1    (MSG_PLAY_ONCE | TRACK1)
00331 #define MSG_PLAY_TRACK2    (MSG_PLAY_ONCE | TRACK2)
00332 #define MSG_PLAY_TRACK3    (MSG_PLAY_ONCE | TRACK3)
00333 
00334 #define MSG_NOP        (MSG_CTL | 0x04)
00335 #define MSG_TIMER_SYNC (MSG_CTL | 0x05)
00336 #define MSG_SET_MODE   (MSG_CTL | 0x06)
00337 #define MSG_RESET_MODE (MSG_CTL | 0x07)
00338 #define MSG_NEW_GAME   (MSG_CTL | 0x0A)
00339 #define MSG_GAME_OVER  (MSG_CTL | 0x0B)
00340 #define MSG_NEW_BALL   (MSG_CTL | 0x0E)
00341 #define MSG_TILT       (MSG_CTL | 0x0F)
00342                       
00343 #define COIL0_ON     COIL0 = 0;
00344 #define COIL1_ON     COIL1 = 0;
00345 #define COIL2_ON     COIL2 = 0;
00346 #define COIL3_ON     COIL3 = 0;
00347 #define COIL4_ON     COIL4 = 0;
00348 #define COIL5_ON     COIL5 = 0;
00349 #define COIL6_ON     COIL6 = 0;
00350 #define COIL7_ON     COIL7 = 0;
00351 
00352 #define COIL0_OFF    COIL0 = 1;
00353 #define COIL1_OFF    COIL1 = 1;
00354 #define COIL2_OFF    COIL2 = 1;
00355 #define COIL3_OFF    COIL3 = 1;
00356 #define COIL4_OFF    COIL4 = 1;
00357 #define COIL5_OFF    COIL5 = 1;
00358 #define COIL6_OFF    COIL6 = 1;
00359 #define COIL7_OFF    COIL7 = 1;
00360 
00361 #define ROW0_ON     COIL0 = 1;
00362 #define ROW1_ON     COIL1 = 1;
00363 #define ROW2_ON     COIL2 = 1;
00364 #define ROW3_ON     COIL3 = 1;
00365                       
00366 #define ROW0_OFF    COIL0 = 0;
00367 #define ROW1_OFF    COIL1 = 0;
00368 #define ROW2_OFF    COIL2 = 0;
00369 #define ROW3_OFF    COIL3 = 0;
00370 
00371 #define LAMP0_ON   LAMP0 = 1;
00372 #define LAMP1_ON   LAMP1 = 1;
00373 #define LAMP2_ON   LAMP2 = 1;
00374 #define LAMP3_ON   LAMP3 = 1;
00375 #define LAMP4_ON   LAMP4 = 1;
00376 #define LAMP5_ON   LAMP5 = 1;
00377 #define LAMP6_ON   LAMP6 = 1;
00378 #define LAMP7_ON   LAMP7 = 1;
00379 
00380 #define LAMP0_OFF  LAMP0 = 0;
00381 #define LAMP1_OFF  LAMP1 = 0;
00382 #define LAMP2_OFF  LAMP2 = 0;
00383 #define LAMP3_OFF  LAMP3 = 0;
00384 #define LAMP4_OFF  LAMP4 = 0;
00385 #define LAMP5_OFF  LAMP5 = 0;
00386 #define LAMP6_OFF  LAMP6 = 0;
00387 #define LAMP7_OFF  LAMP7 = 0;
00388 
00389 #define ROW0_ON     COIL0 = 1;
00390 #define ROW1_ON     COIL1 = 1;
00391 #define ROW2_ON     COIL2 = 1;
00392 #define ROW3_ON     COIL3 = 1;
00393                       
00394 #define ROW0_OFF    COIL0 = 0;
00395 #define ROW1_OFF    COIL1 = 0;
00396 #define ROW2_OFF    COIL2 = 0;
00397 #define ROW3_OFF    COIL3 = 0;
00398 
00399 #define CMD_ON          0x01
00400 #define CMD_OFF         0x00
00401 #define CMD_PULSE_STRONG  0x05
00402 #define CMD_PULSE       0x03
00403 #define CMD_PULSE_WEAK  0x02
00404 
00405 #define PK_MODE_MODE1   0x01
00406 #define PK_MODE_MODE2   0x02
00407 #define PK_MODE_MODE3   0x04
00408 #define PK_MODE_MODE4   0x08
00409 #define PK_MODE_DIAG    0x40
00410 #define PK_MODE_REVERSE 0x80
00411 
00412 
00413 
00414 #define POLY 0xF1A7
00415 
00416 #if defined(PK_SOUND)
00417   #define MAX_EVENTS 1
00418   #define MAX_EVENTS_MASK  0x01;
00419   #define WHEELSIZE  1
00420 #else
00421   #define MAX_EVENTS          32
00422   #define MAX_EVENTS_MASK   0x1F;
00423   #define MAX_SCHED           32
00424   #define WHEELSIZE           64
00425   #define WHEELSIZE_MASK    0x3F
00426 #endif
00427 
00428 extern BYTE wheel[WHEELSIZE];
00429 extern struct EVENT eventq[MAX_SCHED];
00430 
00431 /* PinKit Controller Variables */
00432 #if MAX_LAMPS > 0
00433 extern struct LAMP lamp[MAX_LAMPS];
00434 #endif
00435 
00436 extern struct SW   sw[MAX_SWITCHES];
00437 #if MAX_COILS > 0
00438 extern struct COIL coil[MAX_COILS];
00439 #endif
00440 
00441 /* Predefine the COIL_PULSE multiplication to avoid multiply operation */
00442 extern BYTE PULSE_LOOKUP[];
00443 extern UINT16 BLINK_RATE[];
00444 
00445 /* Score Reel (SR) State */
00446 #define SR_ENABLE    0
00447 #define SR_SYNC      1
00448 #define SR_UNKNOWN   2
00449 #define SR_DISABLE   3
00450 
00451 extern BYTE player;
00452 extern BYTE score[MAX_PLAYER][MAX_DIGITS];         /* 8 digits for each player */
00453 extern BYTE reel[MAX_DIGITS];                      /* current score reel position */
00454 extern BYTE reg[16];
00455 
00456 extern BYTE num_digits;
00457 BYTE score_reset(void);
00458 void zero_scores(BYTE n);
00459 
00469 void set_scores(BYTE n);
00470 
00481 void add_score(BYTE player, BYTE value);
00482 
00483 
00484 #define SEND_PINCAN_MSG(id, data)   while(!ECANSendMessage(id, data, 2, ECAN_TX_STD_FRAME))
00485 
00486 /* Low priority message, 1 try only */
00487 #define SEND_PINCAN_MSG_LP(id, data)   ECANSendMessage(id, data, 2, ECAN_TX_STD_FRAME)
00488 
00489 
00501 UINT16 rand_lfsr(UINT16 min, UINT16 max, BYTE mask);
00502 BYTE rand8(BYTE min, BYTE max);
00503 
00530 int choice16(UINT16 *list, BYTE min, BYTE max);
00531 
00537 void pinkit_init(void);
00538 
00563 BYTE ensched_cmd(BYTE time, BYTE cmd1, BYTE cmd2);
00564 BYTE ensched_fn(BYTE time, void (*func)(void));
00565 /* returns the next entry from the requested time slot */
00566 
00584 BYTE desched(BYTE time);
00585 
00586 
00596 BYTE enqueue(BYTE cmd1, BYTE cmd2);
00597 
00604 BYTE dequeue(BYTE *cmd1, BYTE *cmd2);
00605 void requeue(void);
00606 
00607 
00608 /* coil_on: Drive the PIN to turn coil n ON */
00609 void coil_on(BYTE n);
00610 
00611 /* coil_off: Drive the PIN to turn coil n OFF */
00612 void coil_off(BYTE n);
00613 
00614 /* lamp_on: Drive the PIN to turn lamp n ON */
00615 void lamp_on(BYTE n);
00616 
00617 /* lamp_off: Drive the PIN to turn lamp n ON */
00618 void lamp_off(BYTE n);
00619 
00620 void local_coil_pulse(BYTE n, BYTE dur);
00621 
00622 #if MAX_LAMPS > 0
00623 void lamp_group_assign(BYTE lnum, BYTE group);
00624 void lamp_group_on(BYTE group);
00625 void lamp_group_off(BYTE group);
00626 void lamp_group_reset(BYTE group);
00627 void lamp_group_toggle(BYTE group);
00628 void set_lamp(BYTE lnum, BYTE state, BYTE pwm, BYTE blink);
00629 #endif
00630 
00631 #endif /*PINKIT_H*/