Sony's LANC camera control protocol project.

Dependencies:   aconno_LANC aconno_bsp aconno_SEGGER_RTT

main.cpp

Committer:
jurica238814
Date:
2017-11-01
Revision:
2:b28027b9c099
Parent:
1:3e3dded8192f
Child:
3:eb5b87baf6cf

File content as of revision 2:b28027b9c099:

/*
 * Example to demonstrate usage of the nrf52's I2S interface
 *
 * Made by Jurica Resetar @ aconno
 * jurica_resetar@yahoo.com
 * More info @ aconno.de
 *
 * All rights reserved
 *
 */
 
#include "mbed.h"
#include "acd52832_bsp.h"

#define MY_BUF_SIZE     13*8
#define LANC_H      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF    /* 13 B */
#define LANC_H_L    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF    /* 13 B */
#define LANC_L      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00    /* 13 B */

/*
 *  Bitovi na I2S bus idu od MSBa do LSBa
 */

#define REC_CMD_1           (0xE7)      // 0xE7  or 0x18
#define REC_CMD_2           (0xCC)      // 0xCC  or 0x33

#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

DigitalOut led(p22);
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 startStop[MY_BUF_SIZE] __attribute__ ((aligned (32))) = {LANC_L,LANC_L,LANC_H,LANC_H,LANC_L,LANC_L,LANC_H,LANC_H_L};
//uint8_t normalCommand[MY_BUF_SIZE] __attribute__ ((aligned (32))) = {LANC_L,LANC_H,LANC_H,LANC_L, LANC_L,LANC_H,LANC_H,LANC_H};
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};

uint32_t *normalCmdAddr = (uint32_t*)normalCommand;
uint32_t *startStopAddr = (uint32_t*)startStop;

uint8_t firstInt = 1;
uint8_t flag = 0;   
uint8_t state = 0;  /* 0 -> Send command type, 1-> send command */
InterruptIn button(LANC_PIN);
Timer lancTimer;
Timer frameTimer;


void sendCommand(void){
    static int timePassed_ms = 0;
    static int lastIntTime_ms = 0;
    
    /*
     *  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();
    }
    
    lastIntTime_ms = frameTimer.read_ms() - lastIntTime_ms;
    frameTimer.reset();
    
    if(lastIntTime_ms > 15){
        state = 0;
        if(!state){
            lancTimer.start();
        }
        state++;
        
        if(state == 1){
            NRF_I2S->TXD.PTR = (uint32_t)normalCmdAddr;
        }
        else if(state == 2){
            NRF_I2S->TXD.PTR = (uint32_t)startStopAddr;
        }
        
        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;
        }
        else{
            timePassed_ms = lancTimer.read_ms();
            if(timePassed_ms > 8){
                lancTimer.reset();
                timePassed_ms = 0;
                //state = 0;
            }
        }
    }
}



int main(void){
    led = 1;
    alive = 0;
    
    NRF_I2S->CONFIG.RXEN = 0;       // Disable reception
    NRF_I2S->CONFIG.MCKEN = 1;      // Enable MCK generator
    
    //NRF_I2S->CONFIG.MCKFREQ = 0x04100000; // DIV 63
    //NRF_I2S->CONFIG.RATIO = 0;        // Ratio = 32x
    NRF_I2S->CONFIG.MCKFREQ = 0x10000000; // DIV 31
    NRF_I2S->CONFIG.RATIO = 0;          // Ratio = 32x
    
    NRF_I2S->CONFIG.SWIDTH = 0;         // Sample width = 8 bit
    NRF_I2S->CONFIG.ALIGN = 0;          // Alignment = Right
    NRF_I2S->CONFIG.FORMAT = 0;         // Format = I2S
    NRF_I2S->CONFIG.CHANNELS = 0;       // Use stereo
    
    
    
    // In debug mode
    NRF_I2S->PSEL.LRCK = 27;                // LRCK routed to pin 26
    NRF_I2S->PSEL.SDOUT = LANC_COMMAND_PIN; // SDOUT routed to pin 28
    NRF_I2S->PSEL.SCK = 30;                 // SCK routed to pin 30
    NRF_I2S->PSEL.MCK = 0x80000000;         // MCK disconnected
    NRF_I2S->PSEL.SDIN = 0x80000000;        // SDIN disconnected
    
    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
    
        
        
    //NRF_I2S->ENABLE = 1;
    //NRF_I2S->TASKS_START = 1;
    
    button.fall(sendCommand);
    while(1){
        if(flag){              
            /*
            if(state == 1){
                NRF_I2S->TXD.PTR = (uint32_t)startStopAddr;
            }
            else if(state == 2){
                NRF_I2S->TXD.PTR = (uint32_t)normalCmdAddr;
            }
            */
            
            led = 0;
            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;
            led = 1;
            __enable_irq();
        }
    }
}