Sony's LANC camera control protocol project.
Dependencies: aconno_LANC aconno_bsp aconno_SEGGER_RTT
Diff: main.cpp
- 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); + } +}