| 1 | 143 | olivier.gi | #include "omsp_system.h"
 | 
      
         | 2 | 80 | olivier.gi | #include "spacewar.h"
 | 
      
         | 3 |  |  |  
 | 
      
         | 4 |  |  | //************************************************************
 | 
      
         | 5 |  |  | // externals
 | 
      
         | 6 |  |  | //
 | 
      
         | 7 |  |  | extern volatile unsigned char flags;
 | 
      
         | 8 |  |  |  
 | 
      
         | 9 |  |  | extern void reset_rkts(rkt_data *, rkt_data *);
 | 
      
         | 10 |  |  | extern void reset_game(rkt_data *);
 | 
      
         | 11 |  |  |  
 | 
      
         | 12 |  |  | //************************************************************
 | 
      
         | 13 |  |  | //
 | 
      
         | 14 |  |  | // init_hardware
 | 
      
         | 15 |  |  | //
 | 
      
         | 16 |  |  | //    initalize all the MSP430 hardware before we start
 | 
      
         | 17 |  |  | //
 | 
      
         | 18 |  |  | /* Description:
 | 
      
         | 19 |  |  | Sets up all the hardware in the MSP430 used by the SPACEWAR game.
 | 
      
         | 20 |  |  | Stops the watchdog timer.  Sets the internal cpu clock to a maximun.
 | 
      
         | 21 |  |  | Sets the timer to cause an interrupt every 10ms.  Sets the SPI interface
 | 
      
         | 22 |  |  | to talk to the dual DAC.  Sets the A to D to use an external reference
 | 
      
         | 23 |  |  | and unipolar operation.  Finally initializes all the variable used by the game.
 | 
      
         | 24 |  |  | */
 | 
      
         | 25 |  |  | void init_all(rkt_data *rkt1, rkt_data *rkt2)
 | 
      
         | 26 |  |  | {
 | 
      
         | 27 |  |  |  
 | 
      
         | 28 |  |  |   WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
 | 
      
         | 29 |  |  |  
 | 
      
         | 30 |  |  |   BCSCTL1 = 0x08;                       // Setup DCO highest range
 | 
      
         | 31 |  |  |   DCOCTL = 0xe0;                        // biggest DCO
 | 
      
         | 32 |  |  |  
 | 
      
         | 33 |  |  |   P1OUT = 0x04;                         // TLV5618A CS high
 | 
      
         | 34 |  |  |   P1DIR |= 0x01+0x04;                   // P1.0=LED, P1.2=TLV5618A_cs
 | 
      
         | 35 |  |  |   P1SEL = 0x08;                         // P1.3 = VREF
 | 
      
         | 36 |  |  |  
 | 
      
         | 37 | 84 | olivier.gi |   //BCSCTL2 = 0x00;                       // SMCLK divider = 1
 | 
      
         | 38 |  |  |   //BCSCTL2 = 0x02;                       // SMCLK divider = 2
 | 
      
         | 39 |  |  |   //BCSCTL2 = 0x04;                       // SMCLK divider = 4
 | 
      
         | 40 |  |  |   BCSCTL2 = 0x06;                       // SMCLK divider = 8
 | 
      
         | 41 | 80 | olivier.gi |   CCTL0 = CCIE;                         // CCR0 interrupt enabled
 | 
      
         | 42 |  |  |   CCR0 = 23500;
 | 
      
         | 43 |  |  |   TACTL = TASSEL_2 + MC_1;              // SMCLK, upmode
 | 
      
         | 44 |  |  |   _BIS_SR(GIE);                         // enable interrupts
 | 
      
         | 45 |  |  |  
 | 
      
         | 46 |  |  |   // USICTL0 |= USIPE7+USIPE6+USIPE5+USIMST+USIOE; // Port, SPI master
 | 
      
         | 47 |  |  |   // USICKCTL = USIDIV_0+USISSEL_2+USICKPL;  // divide by 1 SMCLK, inactive high
 | 
      
         | 48 |  |  |   // USICTL0 &= ~USISWRST;                 // release USI for operation
 | 
      
         | 49 |  |  |   // USICTL1 = USICKPH;                    // take data on falling edge
 | 
      
         | 50 |  |  |  
 | 
      
         | 51 |  |  |   // SD16CTL = SD16SSEL_1;                 // exter ref, SMCLK
 | 
      
         | 52 |  |  |   // SD16CCTL0 = SD16UNI + SD16SNGL;       // 256OSR, unipolar, inter
 | 
      
         | 53 |  |  |   // SD16AE = 0;                           // P1.1 A4+, A4- = VSS
 | 
      
         | 54 |  |  |   //                                       // P1.4 A2+, A2- = VSS
 | 
      
         | 55 |  |  |   // SD16INCTL0 = SD16INCH_4;              // A4+/- start with rocket 1
 | 
      
         | 56 |  |  |   // SD16CCTL0 |= SD16SC;                  // Start A2D conversion
 | 
      
         | 57 |  |  |  
 | 
      
         | 58 |  |  |   reset_rkts(rkt1, rkt2);               // reset rkt positons                        
 | 
      
         | 59 |  |  |   reset_game(rkt1);
 | 
      
         | 60 |  |  |   reset_game(rkt2);
 | 
      
         | 61 |  |  |   rkt1->game = 0;
 | 
      
         | 62 |  |  |   rkt2->game = 0;
 | 
      
         | 63 |  |  |   flags |= time_tick;                    // force an update at startup
 | 
      
         | 64 |  |  | }
 | 
      
         | 65 |  |  |  
 | 
      
         | 66 |  |  |  
 | 
      
         | 67 |  |  | //************************************************************
 | 
      
         | 68 |  |  | //
 | 
      
         | 69 |  |  | // Timer A0 interrupt service routine
 | 
      
         | 70 |  |  | //
 | 
      
         | 71 |  |  | /* Description:
 | 
      
         | 72 |  |  | Interrupt service routine for the timer.  The function sets a flag for the main
 | 
      
         | 73 |  |  | loop to update object positions.
 | 
      
         | 74 |  |  | */
 | 
      
         | 75 |  |  | interrupt (TIMERA0_VECTOR) irq_routine(void)
 | 
      
         | 76 |  |  | {
 | 
      
         | 77 |  |  |  
 | 
      
         | 78 |  |  | //  P1OUT ^= 0x01;                        // Toggle P1.0
 | 
      
         | 79 |  |  |   flags |= time_tick;                   // flag a timer tick has occured
 | 
      
         | 80 |  |  | }
 | 
      
         | 81 |  |  |  
 | 
      
         | 82 |  |  | //************************************************************
 | 
      
         | 83 |  |  | //
 | 
      
         | 84 |  |  | // read_a2d
 | 
      
         | 85 |  |  | //
 | 
      
         | 86 |  |  | /* Description:
 | 
      
         | 87 |  |  | Waits for present A to D to finish.  Reads 16 bit A to D value.  Switches
 | 
      
         | 88 |  |  | A to D mux to a channel passed into function.  Starts another A to D on new
 | 
      
         | 89 |  |  | mux input.  Returns int value read from last mux input A to D.
 | 
      
         | 90 |  |  | */
 | 
      
         | 91 |  |  | unsigned int read_a2d(unsigned int next_mux)
 | 
      
         | 92 |  |  | {
 | 
      
         | 93 |  |  |   unsigned int last_a2d;
 | 
      
         | 94 |  |  |  
 | 
      
         | 95 | 143 | olivier.gi |   if (next_mux==0x0002) {
 | 
      
         | 96 | 80 | olivier.gi |     last_a2d = MY_CNTRL1;
 | 
      
         | 97 |  |  |   } else {
 | 
      
         | 98 |  |  |     last_a2d = MY_CNTRL2;
 | 
      
         | 99 |  |  |   }
 | 
      
         | 100 |  |  |  
 | 
      
         | 101 |  |  |   if (last_a2d & 0x8) {             // CCW
 | 
      
         | 102 |  |  |     last_a2d = 0xE000;
 | 
      
         | 103 |  |  |   } else if (last_a2d & 0x4) {      // CW
 | 
      
         | 104 |  |  |     last_a2d = 0xB000;
 | 
      
         | 105 |  |  |   } else if (last_a2d & 0x2) {      // Thrust
 | 
      
         | 106 |  |  |     last_a2d = 0x8000;
 | 
      
         | 107 |  |  |   } else if (last_a2d & 0x1) {      // Fire
 | 
      
         | 108 |  |  |     last_a2d = 0x4000;
 | 
      
         | 109 |  |  |   } else {
 | 
      
         | 110 |  |  |     last_a2d = 0x0000;
 | 
      
         | 111 |  |  |   }
 | 
      
         | 112 |  |  |  
 | 
      
         | 113 |  |  |   //while ((SD16CCTL0 & SD16IFG) == 0); // wait for a2d to finish
 | 
      
         | 114 |  |  |   //last_a2d = SD16MEM0;                // save results from last a2d
 | 
      
         | 115 |  |  |   //SD16INCTL0 = next_mux;              // switch analog mux for next rocket
 | 
      
         | 116 |  |  |   //SD16CCTL0 |= SD16SC;                // Start another conversion
 | 
      
         | 117 |  |  |   return last_a2d;
 | 
      
         | 118 |  |  | }
 | 
      
         | 119 |  |  |  
 | 
      
         | 120 |  |  | // ************************************************************
 | 
      
         | 121 |  |  | //
 | 
      
         | 122 |  |  | //  send one 16 bit value to SPI DAC
 | 
      
         | 123 |  |  | //
 | 
      
         | 124 |  |  | /* Description:
 | 
      
         | 125 |  |  | First put the value into the transmit register.  Chip select the DAC.
 | 
      
         | 126 |  |  | Start the automatic SPI transfer.  Wait until the transfer is complete.
 | 
      
         | 127 |  |  | Finally remove the chip select.
 | 
      
         | 128 |  |  | */
 | 
      
         | 129 | 143 | olivier.gi | /*
 | 
      
         | 130 | 80 | olivier.gi | void set_one(int set_1)
 | 
      
         | 131 |  |  | {
 | 
      
         | 132 |  |  |  
 | 
      
         | 133 |  |  |   USISR = set_1;                        // send value to DAC
 | 
      
         | 134 |  |  |   P1OUT &= ~0x04;                       // chip select TLV5618A
 | 
      
         | 135 |  |  |   USICNT = 0x10 + USI16B;               // start spi
 | 
      
         | 136 |  |  |   while ((USIIFG & USICTL1) == 0) ;     // wait until y spi done
 | 
      
         | 137 |  |  |   P1OUT |= 0x04;                        // remove chip select
 | 
      
         | 138 |  |  | }
 | 
      
         | 139 | 143 | olivier.gi | */
 | 
      
         | 140 | 80 | olivier.gi |  
 | 
      
         | 141 |  |  | // ************************************************************
 | 
      
         | 142 |  |  | //
 | 
      
         | 143 |  |  | //  Move DAC's to dot position
 | 
      
         | 144 |  |  | //
 | 
      
         | 145 |  |  | // set_x and set_y enter as 0 to 4095
 | 
      
         | 146 |  |  | // Masked to 12 bit dac 0 to 4095
 | 
      
         | 147 |  |  | /* Description:
 | 
      
         | 148 |  |  | Move DAC to position set_x, set_y.  Write the set_y value into the DAC's
 | 
      
         | 149 |  |  | BUFFER.  Write the set_x value to DAC_x and at the same time move the BUFFER
 | 
      
         | 150 |  |  | value to DAC_y.  This technique removes the stair steping in lines.
 | 
      
         | 151 |  |  | */
 | 
      
         | 152 |  |  | void set_xy(int set_x, int set_y)
 | 
      
         | 153 |  |  | {
 | 
      
         | 154 |  |  |  
 | 
      
         | 155 |  |  |   //set_one((set_y & 0x0FFF) | 0x5000);   // send y value to BUFFER
 | 
      
         | 156 |  |  |   //set_one((set_x & 0x0FFF) | 0xc000);   // send x DAC_X, BUFFER to DAC_Y
 | 
      
         | 157 |  |  |  
 | 
      
         | 158 |  |  |   while (MY_DAC_X_STAT);
 | 
      
         | 159 |  |  |   while (MY_DAC_Y_STAT);
 | 
      
         | 160 |  |  |   MY_DAC_Y = (set_y & 0x0FFF);
 | 
      
         | 161 |  |  |   MY_DAC_X = (set_x & 0x0FFF);
 | 
      
         | 162 |  |  |  
 | 
      
         | 163 |  |  | }
 |