This is the first rev of HW3 for IDD

Dependencies:   MMA8451Q USBDevice mbed nRF24L01P

Revision:
0:d89cdf3d29f8
Child:
1:b58cf7dd20d7
diff -r 000000000000 -r d89cdf3d29f8 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Sep 29 08:45:58 2014 +0000
@@ -0,0 +1,353 @@
+//NOTE: NORDIC BOARD ONLY WORKS W/ MBED 84!
+//Chose pin ordering from https://mbed.org/questions/1360/Using-nRF24L01-Module-with-FRDM-Board/ -- unused pins
+
+#include "mbed.h"
+#include "nRF24L01P.h"                              // nordic library
+
+
+#define DEBUG 0
+#define BASE 0
+
+
+#include "USBMouseKeyboard.h"                       // for the sword - mouse/keyboard combo
+#if(BASE == 1)
+    USBMouseKeyboard MK;                                //Default is REL_MOUSE, bout could use ABS_MOUSE too
+#endif
+
+#define SCALING 50                                  // factor to multiply the accelerometer reading by (usually it is in the scale of g's. Decides sensitivity of mouse. Keep it less 100 (mouse is assigned an int8)
+ 
+// Accelerometer includes
+#include "MMA8451Q.h" 
+#define MMA8451_I2C_ADDRESS (0x1d<<1)
+
+// define I2C Pins and address for KL25Z. Taken from default sample code.
+PinName const SDA = PTE25;
+PinName const SCL = PTE24;
+
+// Base station TX/RX
+#define RX_NRF24L01P_ADDRESS       ((unsigned long long) 0xABABABABAB )
+#define TX_NRF24L01P_ADDRESS       ((unsigned long long) 0xCDCDCDCDCD )
+
+// Masks
+#define LOW8                        0x00FF
+#define HIGH3                       0x0007
+#define LOW5                        0x001F               
+#define HIGH6                       0x003F
+
+// The nRF24L01+ supports transfers from 1 to 32 bytes 
+// Assume 1680x1050 max screen resolution -- MSB to LSB 0 padded, 1 bit pressed, 11 bits x, 11 bits y for Fruit Ninja
+// For Blade Symphony, way fewer than 24 control bits for keyboard/house
+// From PC, only need (zero padded) 1 bit flag indicating if hit + 1 bit indicating Fruit Ninja (0) or Blade Symphony (1)
+#define TRANSFER_SIZE   3
+
+Serial pc(USBTX, USBRX);                                    // PC communication
+
+PwmOut motor(D2);                                           // Only specific pins have PWM capability
+
+nRF24L01P nordic(PTD2, PTD3, PTC5, PTD0, PTD5, PTA13);      // mosi, miso, sck, csn, ce, irq
+
+DigitalIn modeSW(D15);                                      // base station or sword mode
+
+// Accelerometer
+MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
+
+void Calibrate(void);
+void Acc_GetXY(void);
+
+int16_t x,y;                                              // variables to hold acceleration data after call to Acc_Get_All
+float x_b, y_b;                                           // acc bias
+
+// Debug
+DigitalOut greenLED(LED_GREEN);
+DigitalOut redLED(LED_RED);
+
+
+AnalogIn ATTACK(A0);
+AnalogIn SELECT(A1);
+AnalogIn XJOY(A2);
+AnalogIn YJOY(A3);
+
+DigitalIn JOYSEL(D3);
+
+
+bool isBaseStation;
+
+int main() {
+    int8_t mouse_x, mouse_y;
+    Calibrate();
+
+    modeSW.mode(PullUp);                                  // Configure pull down to minimize wire
+    
+    isBaseStation = (bool) !modeSW;                          // Detect device via jumper connection
+    wait(5);
+
+    // Power up wireless
+    nordic.powerUp();
+
+    // Display + change the (default) setup of the nRF24L01+ chip
+    
+    // Addresses 5 bytes long
+    
+    if (isBaseStation){
+        nordic.setTxAddress(TX_NRF24L01P_ADDRESS ,5); 
+        nordic.setRxAddress(RX_NRF24L01P_ADDRESS ,5); 
+    }
+    else{
+        nordic.setRxAddress(TX_NRF24L01P_ADDRESS ,5); 
+        nordic.setTxAddress(RX_NRF24L01P_ADDRESS ,5); 
+    }
+    
+    pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  nordic.getRfFrequency() );
+    pc.printf( "nRF24L01+ Output power : %d dBm\r\n",  nordic.getRfOutputPower() );
+    pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", nordic.getAirDataRate() );       // 1Mbps
+    pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", nordic.getTxAddress() );
+    pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n", nordic.getRxAddress() );
+
+    // Data packet length
+    nordic.setTransferSize( TRANSFER_SIZE );
+
+    nordic.setReceiveMode();
+    nordic.enable();
+    
+    // Set motor PWM period
+    motor.period(0.001f);       // 1ms period
+    motor.write(0.0f);          // initially not on
+    
+   // motor.write(0.40f);                         // 95% duty cycle, relative to period
+
+    // Status flags
+    bool isBladeSymphony = false;
+    bool sensor1ON = false; 
+    
+    bool motorON = false; 
+
+    int rxDataCnt = 0;
+    
+    // Debug
+    int testcount = 0;
+    
+    // counting the mode
+    uint8_t mode_count = 0;
+
+    while (1) {
+        // Only reads 1 byte from PC + sends to other mcu (pads w/ 0 bytes) if base station
+        if (isBaseStation){
+
+            // If we've received anything over the host serial link...
+            if ( pc.readable() ) {
+                char txData[TRANSFER_SIZE];
+                // ...add it to the transmit buffer -- only care about first byte
+                txData[0] = pc.getc();
+                txData[1] = 100;
+                txData[2] = '\n';
+                
+                // Send the transmitbuffer via the nRF24L01+
+                nordic.write( NRF24L01P_PIPE_P0, txData, TRANSFER_SIZE );
+
+                // Toggle LED1 (to help debug Host -> nRF24L01+ communication)
+                /*if (txData[0] == 66)
+                    greenLED = !greenLED;*/
+            }
+
+            // If we've received anything in the nRF24L01+... = sword
+            if ( nordic.readable() ) {
+                char rxData[TRANSFER_SIZE];
+                // ...read the data into the receive buffer
+                rxDataCnt = nordic.read( NRF24L01P_PIPE_P0, rxData, TRANSFER_SIZE );
+
+                //NOTE: NEED TO INTERPRET AS KEYS/MOUSE HERE
+                
+                int8_t dx = rxData[0];
+                int8_t dy = rxData[1];
+                
+              
+                bool mode_stat = (rxData[2] >> 7) & 1;
+                bool joy_but = (rxData[2] >> 6) & 1;
+                bool sel_stat = (rxData[2] >> 5) & 1;
+                bool attack_stat = (rxData[2] >> 4) & 1;
+                bool key_w = (rxData[2] >> 3) & 1;
+                bool key_s = (rxData[2] >> 2) & 1;
+                bool key_d = (rxData[2] >> 1) & 1;
+                bool key_a = (rxData[2] >> 0) & 1;
+                
+                #if(BASE == 1)
+                    MK.move(-dx, dy); 
+
+                    if(joy_but)
+                    {
+                        MK.putc(' ');
+                    }                
+                    if(key_w)
+                    {
+                        MK.putc('w');
+                    }
+                    if(key_a)
+                    {
+                        MK.putc('a');
+                    }
+                    if(key_s)
+                    {
+                        MK.putc('s');
+                    }
+                    if(key_d)
+                    {
+                        MK.putc('d');
+                    }
+                    if(sel_stat)
+                    {
+                        MK.click(MOUSE_RIGHT);
+                    }
+                    if(attack_stat)
+                    {
+                        MK.click(MOUSE_LEFT);
+                    }
+                    if(mode_stat)
+                    {
+                        MK.putc('1'+mode_count);
+                        mode_count = (mode_count+1)%3;
+                    }
+                    
+                    
+                #endif
+
+
+                pc.printf("x: %d y: %d \r\n",dx,dy);
+
+                // Display the receive buffer contents via the host serial link
+                /*for ( int i = 0; i < TRANSFER_SIZE; i++ ) {
+
+                    pc.putc( rxData[i] );
+                }*/
+
+                // Toggle LED2 (to help debug nRF24L01+ -> Host communication)
+                if (rxData[0] == 65 && rxData[1] == 66 && rxData[2] == 67){
+                    redLED = !redLED;
+                }
+
+            }
+        }
+
+
+        // sword
+        else{
+            int ATTACKVAL = ATTACK.read_u16();
+            int SELECTVAL = SELECT.read_u16();
+            int XJOYVAL = XJOY.read_u16();
+            int YJOYVAL = YJOY.read_u16();
+            int JOYSELVAL = (int) JOYSEL;
+            
+            bool mode_stat = (SELECTVAL > 45000) ? true: 0;
+            bool joy_but = JOYSEL == 0? true: 0;
+            bool sel_stat = (SELECTVAL > 10000 && SELECTVAL < 45000) ? true: 0;
+            bool attack_stat = ATTACKVAL > 10000? true: 0;
+            bool key_d = XJOYVAL > 35000 ? true: 0;
+            bool key_a = XJOYVAL < 30000 ? true : 0;
+            bool key_w = YJOYVAL > 35000 ? true: 0;
+            bool key_s = YJOYVAL < 30000 ? true: 0;
+            
+            uint8_t key_stat = mode_stat<<7|joy_but<<6|sel_stat<<5|attack_stat<<4|key_w<<3|key_s<<2|key_d<<1|key_a<<0;
+            
+            
+            pc.printf("F1: %d \t F2: %d \t X: %d \t Y: %d \t SEL: %d \r\n", ATTACKVAL, SELECTVAL, XJOYVAL, YJOYVAL, JOYSELVAL);
+      
+            greenLED = JOYSEL;
+
+            // Let serial read catch up on base station/PC side
+            wait_us(150);
+
+            char swordData[TRANSFER_SIZE]; 
+            
+            int16_t deltax = 768;
+            int16_t deltay = 345;
+            
+            if (testcount <= 2000){
+                deltax = testcount;
+                deltay = 2000-testcount;
+                testcount++;
+            }
+            else
+                testcount = 0;
+            
+            Acc_GetXY();
+        
+            mouse_x = x;
+            mouse_y = y;
+        
+            char lowX = char(mouse_x & LOW8);
+            char lowY = char(mouse_y & LOW8);
+            
+            // left A, right D, back S, up W
+            
+            // MSB -- LSB, 
+            swordData[0] = lowX;
+            swordData[1] = lowY; 
+            swordData[2] = char(key_stat); 
+            swordData[3] = char((sensor1ON << 7)|key_stat); 
+            
+            // Send the transmitbuffer via the nRF24L01+
+            nordic.write( NRF24L01P_PIPE_P0, swordData, TRANSFER_SIZE );
+
+            // NOTE: Action settings depending on type of game. Accelerometer data. Force sensitive resistor thresholding, etc. 
+
+            // If we've received anything from base station 
+                
+            if ( nordic.readable() ) {
+                char rxData[TRANSFER_SIZE];
+                // ...read the data into the receive buffer
+                rxDataCnt = nordic.read( NRF24L01P_PIPE_P0, rxData, TRANSFER_SIZE );
+
+                #if DEBUG == 1
+                    // Toggle LED1 (to help debug Host -> nRF24L01+ communication)
+                    pc.printf("x: %f \t y: %f \r\n", mouse_x,mouse_y);
+                    greenLED = !greenLED;
+
+                    // Display the receive buffer contents via the host serial link
+                    for ( int i = 0; i < TRANSFER_SIZE; i++ ) {
+    
+                        pc.putc( rxData[i] );
+                    }
+
+                    // Toggle LED2 (to help debug nRF24L01+ -> Host communication)
+                    if (rxData[0] == 65 && rxData[1] == 100 && rxData[2] == 100){
+                        redLED = !redLED;
+                        }
+                #endif
+
+
+                // From PC, only need (zero padded) 1 bit flag indicating if hit + 1 bit indicating Fruit Ninja (0) or Blade Symphony (1)
+                // In first byte
+                isBladeSymphony = (rxData[0] >> 0) & 1;
+                motorON = (rxData[0] >> 1) & 1;                 // Motor ON when sword contact made
+                
+                greenLED = !isBladeSymphony;                    // LEDs active low
+                redLED = !motorON;
+                
+            }
+        }
+    }
+}
+
+void Calibrate(void) 
+{
+     unsigned int count1;
+     count1 = 0;
+     float sstatex = 0;
+     float sstatey = 0;
+     
+     do{ 
+     sstatex += acc.getAccX(); // Accumulate Samples
+     sstatey += acc.getAccY();
+     count1++;
+     }while(count1!=0x0400); // 1024 times
+     x_b = sstatex/1024.0; // division between 1024
+     y_b = sstatey/1024.0;
+}
+
+void Acc_GetXY(void)
+{
+    x = (int16_t)((acc.getAccX()- x_b)*SCALING);
+    y = (int16_t)((acc.getAccY()- y_b)*SCALING);
+}
+
+
+