Sony's LANC camera control protocol project.

Dependencies:   aconno_LANC aconno_bsp aconno_SEGGER_RTT

Revision:
5:ecb7712b0825
Parent:
4:6560e2966186
Child:
6:8cf24e946b0b
--- a/main.cpp	Wed Nov 01 12:52:30 2017 +0000
+++ b/main.cpp	Wed Nov 01 17:39:50 2017 +0000
@@ -23,70 +23,103 @@
 
 #define LANC_COMMAND_PIN    (p2)   // Pin connected to Tr to pull lanc bus down/up     2/26
 #define LANC_PIN            (p3)   // Lanc bus pin (to scan for START/STOP bits)        3/25
+#define LED_ON              (0)
+#define LED_OFF             (1)
 
 DigitalOut alive(p24);
 
 uint8_t normalCommand[MY_BUF_SIZE] __attribute__ ((aligned (32))) = {LANC_L,LANC_L,LANC_L,LANC_H, LANC_H,LANC_L,LANC_L,LANC_L};
-uint8_t specialCommand[MY_BUF_SIZE] __attribute__ ((aligned (32))) = {LANC_L,LANC_L,LANC_L,LANC_H, LANC_L,LANC_H,LANC_L,LANC_L};
+uint8_t zoomCommand[MY_BUF_SIZE] __attribute__ ((aligned (32))) = {LANC_L,LANC_L,LANC_L,LANC_H, LANC_L,LANC_H,LANC_L,LANC_L};
 uint8_t startStop[MY_BUF_SIZE] __attribute__ ((aligned (32))) = {LANC_H,LANC_H,LANC_L,LANC_L,LANC_H,LANC_H,LANC_L,LANC_L};
 uint8_t zoomIn[MY_BUF_SIZE] __attribute__ ((aligned (32))) = {LANC_H,LANC_L,LANC_L,LANC_H,LANC_H,LANC_H,LANC_L,LANC_L};     // Tele
 uint8_t zoomOut[MY_BUF_SIZE] __attribute__ ((aligned (32))) = {LANC_H,LANC_H,LANC_L,LANC_H,LANC_H,LANC_H,LANC_L,LANC_L};    // Wide
 
-uint32_t *normalCmdAddr = (uint32_t*)specialCommand;
-uint32_t *startStopAddr = (uint32_t*)zoomOut;
+uint32_t *normalCmdAddr = (uint32_t*)normalCommand;
+uint32_t *zoomCmdAddr = (uint32_t*)zoomCommand;
+uint32_t *startStopAddr = (uint32_t*)startStop;
+uint32_t *zoomInAddr = (uint32_t*)zoomIn;
+uint32_t *zoomOutAddr = (uint32_t*)zoomOut;
 
-uint8_t firstInt = 1;
-uint8_t flag = 0;   
+
+uint8_t volatile i2sFlag = 0;   
 uint8_t state = 0;  /* 1 -> Send command type, 0 -> send command */
 InterruptIn button(LANC_PIN);
 Timer frameTimer;
 
+void i2sReady(){
+    /* Interrupt handler */
+    i2sFlag = 1;
+}
 
-void sendCommand(void){
+uint8_t waitForStartBit(){
+    static uint8_t firstInt = 1;
     static int lastIntTime_us = 0;
     
+    while(!i2sFlag);       // Wait for the interrupt to change the flag
+    if(firstInt){
+        firstInt = 0;
+        frameTimer.start();
+    }
+    lastIntTime_us = frameTimer.read_us();
+    frameTimer.reset();
+    i2sFlag = 0;
+    
+    if(lastIntTime_us > 10000){
+       return 1; 
+    }
+    else{
+        return 0;
+    }
+}
+
+void sendi2sData(){
+    NRF_I2S->EVENTS_TXPTRUPD = 0;
+    NRF_I2S->ENABLE = 1;
+    NRF_I2S->TASKS_START = 1;    
+    
+    while(!NRF_I2S->EVENTS_TXPTRUPD);    // Wait for the data to be send
+    NRF_I2S->EVENTS_TXPTRUPD = 0;
+    while(!NRF_I2S->EVENTS_TXPTRUPD);    // Wait for the data to be send
+    NRF_I2S->EVENTS_TXPTRUPD = 0; 
+    NRF_I2S->TASKS_STOP = 1;
+    while(!NRF_I2S->EVENTS_STOPPED);
+    NRF_I2S->ENABLE = 0;
+}
+
+void sendCommand(uint32_t *commandType, uint32_t *command){
+    
+    
     /*
      *  Na prvi interrupt pokreni frameTimer. 
      *  Na svaki interrupt (falling edge na Lanc busu) izmjeri vrijeme od zadnjeg eventa
      *  Ako je to vrijeme > 5ms, onda je upravo taj prekid izazvao start bit novog framea
      *  U tom slučaju, kreni s donjim kodom, inaće nemoj ništa slati
      */
-    if(firstInt){
-        firstInt = 0;
-        frameTimer.start();
-    }
+    uint8_t cnt = 0;
     
-    lastIntTime_us = frameTimer.read_us();
-    frameTimer.reset();
-    
-    if(lastIntTime_us > 10000 || state == 1){
-        state++;
+    for(cnt; cnt < 4; cnt++){
+        while(!(waitForStartBit()));
+        NRF_I2S->TXD.PTR = (uint32_t)commandType;        
+        __disable_irq();
+        // First or second start bit
+        wait_us(60);    // Small delay for first bit after start bit
+        sendi2sData();
+        __enable_irq();
+        i2sFlag = 0;
         
-        if(state == 1){
-            NRF_I2S->TXD.PTR = (uint32_t)normalCmdAddr;
-        }
-        else if(state == 2){
-            NRF_I2S->TXD.PTR = (uint32_t)startStopAddr;
-            state = 0;
-        }
+        while(!i2sFlag);        // Wait for new start bit (second byte into frame)
         
-        if(state<=2){
-            __disable_irq();
-            // First or second start bit
-            wait_us(60);    // Small delay for first bit after start bit
-            NRF_I2S->EVENTS_TXPTRUPD = 0;
-            NRF_I2S->ENABLE = 1;
-            NRF_I2S->TASKS_START = 1;
-            flag = 1;
-        }
+        NRF_I2S->TXD.PTR = (uint32_t)command;
+        __disable_irq();
+        // First or second start bit
+        wait_us(60);    // Small delay for first bit after start bit
+        sendi2sData();
+        i2sFlag = 0;
+        __enable_irq();
     }
 }
 
-
-
-int main(void){
-    alive = 0;
-    
+void i2sInit(){
     NRF_I2S->CONFIG.RXEN = 0;       // Disable reception
     NRF_I2S->CONFIG.MCKEN = 1;      // Enable MCK generator
  
@@ -106,22 +139,34 @@
     
     NRF_I2S->TXD.PTR = (uint32_t)normalCmdAddr;
     NRF_I2S->RXTXD.MAXCNT = MY_BUF_SIZE/4;  // Div with 4 cuz that's number of 32 bit words
-    
-    button.fall(sendCommand);
-    while(1){
-        if(flag){                          
-            while(!NRF_I2S->EVENTS_TXPTRUPD);    // Wait for the data to be send
-            NRF_I2S->EVENTS_TXPTRUPD = 0;
-            while(!NRF_I2S->EVENTS_TXPTRUPD);    // Wait for the data to be send
-            NRF_I2S->EVENTS_TXPTRUPD = 0; 
-            
-            NRF_I2S->TASKS_STOP = 1;
-            while(!NRF_I2S->EVENTS_STOPPED);
-            NRF_I2S->ENABLE = 0;
-            flag = 0;
-            __enable_irq();
-        }
-    }
 }
 
 
+int main(void){
+    alive = 0;
+    
+    i2sInit();
+    
+    button.fall(i2sReady);
+    
+    while(1){
+        sendCommand(zoomCmdAddr, zoomInAddr);
+        sendCommand(zoomCmdAddr, zoomInAddr);
+        sendCommand(zoomCmdAddr, zoomInAddr);
+        sendCommand(zoomCmdAddr, zoomInAddr);
+        sendCommand(zoomCmdAddr, zoomInAddr);
+        sendCommand(zoomCmdAddr, zoomInAddr);
+        sendCommand(zoomCmdAddr, zoomInAddr);
+        sendCommand(zoomCmdAddr, zoomInAddr);
+        wait_ms(350);
+        sendCommand(zoomCmdAddr, zoomOutAddr);
+        sendCommand(zoomCmdAddr, zoomOutAddr);
+        sendCommand(zoomCmdAddr, zoomOutAddr);
+        sendCommand(zoomCmdAddr, zoomOutAddr);
+        sendCommand(zoomCmdAddr, zoomOutAddr);
+        sendCommand(zoomCmdAddr, zoomOutAddr);
+        sendCommand(zoomCmdAddr, zoomOutAddr);
+        sendCommand(zoomCmdAddr, zoomOutAddr);
+        wait_ms(350);
+    }
+}