Sony's LANC camera control protocol project.

Dependencies:   aconno_LANC aconno_bsp aconno_SEGGER_RTT

Committer:
jurica238814
Date:
Fri Nov 03 14:03:14 2017 +0000
Revision:
7:5a9d22d7fe00
Parent:
6:8cf24e946b0b
Dummy commit (do not use).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jurica238814 0:d616ca59aad8 1 /*
jurica238814 0:d616ca59aad8 2 * Example to demonstrate usage of the nrf52's I2S interface
jurica238814 0:d616ca59aad8 3 *
jurica238814 0:d616ca59aad8 4 * Made by Jurica Resetar @ aconno
jurica238814 0:d616ca59aad8 5 * jurica_resetar@yahoo.com
jurica238814 0:d616ca59aad8 6 * More info @ aconno.de
jurica238814 0:d616ca59aad8 7 *
jurica238814 0:d616ca59aad8 8 * All rights reserved
jurica238814 0:d616ca59aad8 9 *
jurica238814 0:d616ca59aad8 10 */
jurica238814 0:d616ca59aad8 11
jurica238814 0:d616ca59aad8 12 #include "mbed.h"
jurica238814 0:d616ca59aad8 13 #include "acd52832_bsp.h"
jurica238814 6:8cf24e946b0b 14 #include "ble/BLE.h"
jurica238814 6:8cf24e946b0b 15 #include "GapAdvertisingData.h"
jurica238814 6:8cf24e946b0b 16 #include "AckService.h"
jurica238814 0:d616ca59aad8 17
jurica238814 2:b28027b9c099 18 #define MY_BUF_SIZE 13*8
jurica238814 1:3e3dded8192f 19 #define LANC_H 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF /* 13 B */
jurica238814 2:b28027b9c099 20 #define LANC_H_L 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF /* 13 B */
jurica238814 1:3e3dded8192f 21 #define LANC_L 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 13 B */
jurica238814 0:d616ca59aad8 22
jurica238814 0:d616ca59aad8 23 /*
jurica238814 0:d616ca59aad8 24 * Bitovi na I2S bus idu od MSBa do LSBa
jurica238814 0:d616ca59aad8 25 */
jurica238814 0:d616ca59aad8 26
jurica238814 2:b28027b9c099 27 #define LANC_COMMAND_PIN (p2) // Pin connected to Tr to pull lanc bus down/up 2/26
jurica238814 2:b28027b9c099 28 #define LANC_PIN (p3) // Lanc bus pin (to scan for START/STOP bits) 3/25
jurica238814 5:ecb7712b0825 29 #define LED_ON (0)
jurica238814 5:ecb7712b0825 30 #define LED_OFF (1)
jurica238814 6:8cf24e946b0b 31 #define MSD_SIZE (29) /* Manufacturer Specific Data lenght (in B) */
jurica238814 0:d616ca59aad8 32
jurica238814 7:5a9d22d7fe00 33 uint8_t MSD[MSD_SIZE] = {0x59, 0x00, 0xDD, 0x44, 0xCD, 0xC5, 0x5E, 0xA3, 0x43, 0x67, 0x8B, 0x84, 0x94, 0xFF, 0xBA, 0xD9, 0x29, 0xC5};
jurica238814 6:8cf24e946b0b 34 uint8_t myMacAddress[6] = {};
jurica238814 6:8cf24e946b0b 35 ACKService<1> *ackServicePtr;
jurica238814 6:8cf24e946b0b 36 BLE &ble = BLE::Instance();
jurica238814 6:8cf24e946b0b 37
jurica238814 6:8cf24e946b0b 38 void sendCommand(uint32_t *commandType, uint32_t *command);
jurica238814 6:8cf24e946b0b 39 GapAdvertisingData advData = GapAdvertisingData();
jurica238814 6:8cf24e946b0b 40
jurica238814 6:8cf24e946b0b 41 DigitalOut alive(p23);
jurica238814 6:8cf24e946b0b 42 DigitalOut connectedLED(p24);
jurica238814 2:b28027b9c099 43
jurica238814 2:b28027b9c099 44 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};
jurica238814 5:ecb7712b0825 45 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};
jurica238814 2:b28027b9c099 46 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};
jurica238814 4:6560e2966186 47 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
jurica238814 4:6560e2966186 48 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
jurica238814 1:3e3dded8192f 49
jurica238814 5:ecb7712b0825 50 uint32_t *normalCmdAddr = (uint32_t*)normalCommand;
jurica238814 5:ecb7712b0825 51 uint32_t *zoomCmdAddr = (uint32_t*)zoomCommand;
jurica238814 5:ecb7712b0825 52 uint32_t *startStopAddr = (uint32_t*)startStop;
jurica238814 5:ecb7712b0825 53 uint32_t *zoomInAddr = (uint32_t*)zoomIn;
jurica238814 5:ecb7712b0825 54 uint32_t *zoomOutAddr = (uint32_t*)zoomOut;
jurica238814 2:b28027b9c099 55
jurica238814 5:ecb7712b0825 56 uint8_t volatile i2sFlag = 0;
jurica238814 4:6560e2966186 57 uint8_t state = 0; /* 1 -> Send command type, 0 -> send command */
jurica238814 6:8cf24e946b0b 58
jurica238814 1:3e3dded8192f 59 InterruptIn button(LANC_PIN);
jurica238814 2:b28027b9c099 60 Timer frameTimer;
jurica238814 1:3e3dded8192f 61
jurica238814 6:8cf24e946b0b 62 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params){
jurica238814 6:8cf24e946b0b 63 connectedLED = LED_ON;
jurica238814 6:8cf24e946b0b 64 ble.gap().stopAdvertising();
jurica238814 6:8cf24e946b0b 65 }
jurica238814 6:8cf24e946b0b 66
jurica238814 6:8cf24e946b0b 67 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
jurica238814 6:8cf24e946b0b 68 //newImage[cnt] = params->data[i];
jurica238814 6:8cf24e946b0b 69 switch(params->data[0]){
jurica238814 6:8cf24e946b0b 70 case 0x00:{
jurica238814 6:8cf24e946b0b 71 sendCommand(normalCmdAddr, startStopAddr);
jurica238814 6:8cf24e946b0b 72 break;
jurica238814 6:8cf24e946b0b 73 }
jurica238814 6:8cf24e946b0b 74 case 0x01:{
jurica238814 6:8cf24e946b0b 75 sendCommand(zoomCmdAddr, zoomOutAddr);
jurica238814 6:8cf24e946b0b 76 break;
jurica238814 6:8cf24e946b0b 77 }
jurica238814 6:8cf24e946b0b 78 case 0x02:{
jurica238814 6:8cf24e946b0b 79 sendCommand(zoomCmdAddr, zoomInAddr);
jurica238814 6:8cf24e946b0b 80 break;
jurica238814 6:8cf24e946b0b 81 }
jurica238814 6:8cf24e946b0b 82 default: break;
jurica238814 6:8cf24e946b0b 83 }
jurica238814 6:8cf24e946b0b 84
jurica238814 6:8cf24e946b0b 85
jurica238814 6:8cf24e946b0b 86 return;
jurica238814 6:8cf24e946b0b 87 }
jurica238814 6:8cf24e946b0b 88
jurica238814 6:8cf24e946b0b 89 /**
jurica238814 6:8cf24e946b0b 90 * Restart Advertising on disconnection
jurica238814 6:8cf24e946b0b 91 */
jurica238814 6:8cf24e946b0b 92 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){
jurica238814 6:8cf24e946b0b 93 connectedLED = LED_OFF;
jurica238814 6:8cf24e946b0b 94 BLE::Instance().gap().startAdvertising();
jurica238814 6:8cf24e946b0b 95 }
jurica238814 6:8cf24e946b0b 96
jurica238814 6:8cf24e946b0b 97
jurica238814 6:8cf24e946b0b 98 /**
jurica238814 6:8cf24e946b0b 99 * This function is called when the ble initialization process has failed
jurica238814 6:8cf24e946b0b 100 */
jurica238814 6:8cf24e946b0b 101 void onBleInitError(BLE &ble, ble_error_t error){
jurica238814 6:8cf24e946b0b 102 /* Avoid compiler warnings */
jurica238814 6:8cf24e946b0b 103 (void) ble;
jurica238814 6:8cf24e946b0b 104 (void) error;
jurica238814 6:8cf24e946b0b 105 /* Initialization error handling should go here */
jurica238814 6:8cf24e946b0b 106 }
jurica238814 6:8cf24e946b0b 107
jurica238814 6:8cf24e946b0b 108 /**
jurica238814 6:8cf24e946b0b 109 * Callback triggered when the ble initialization process has finished
jurica238814 6:8cf24e946b0b 110 */
jurica238814 6:8cf24e946b0b 111 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){
jurica238814 6:8cf24e946b0b 112 BLE& ble = params->ble;
jurica238814 6:8cf24e946b0b 113 uint8_t init_values[1];
jurica238814 6:8cf24e946b0b 114
jurica238814 6:8cf24e946b0b 115
jurica238814 6:8cf24e946b0b 116 /* Get my MAC address */
jurica238814 6:8cf24e946b0b 117 BLEProtocol::AddressType_t temp_address_type;
jurica238814 6:8cf24e946b0b 118 ble.gap().getAddress(&temp_address_type, myMacAddress);
jurica238814 6:8cf24e946b0b 119 ackServicePtr = new ACKService<1>(ble, init_values);
jurica238814 6:8cf24e946b0b 120
jurica238814 6:8cf24e946b0b 121 ble.gap().onDisconnection(disconnectionCallback);
jurica238814 6:8cf24e946b0b 122 ble.gap().onConnection(onConnectionCallback);
jurica238814 6:8cf24e946b0b 123 ble.gattServer().onDataWritten(onDataWrittenCallback);
jurica238814 6:8cf24e946b0b 124
jurica238814 6:8cf24e946b0b 125 /* setup advertising */
jurica238814 6:8cf24e946b0b 126 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)MSD, MSD_SIZE);
jurica238814 6:8cf24e946b0b 127 ble.gap().setAdvertisingInterval(500); // --> Has to be at least 100ms!
jurica238814 6:8cf24e946b0b 128 ble.gap().startAdvertising();
jurica238814 6:8cf24e946b0b 129 }
jurica238814 6:8cf24e946b0b 130
jurica238814 5:ecb7712b0825 131 void i2sReady(){
jurica238814 5:ecb7712b0825 132 /* Interrupt handler */
jurica238814 5:ecb7712b0825 133 i2sFlag = 1;
jurica238814 5:ecb7712b0825 134 }
jurica238814 0:d616ca59aad8 135
jurica238814 5:ecb7712b0825 136 uint8_t waitForStartBit(){
jurica238814 5:ecb7712b0825 137 static uint8_t firstInt = 1;
jurica238814 3:eb5b87baf6cf 138 static int lastIntTime_us = 0;
jurica238814 1:3e3dded8192f 139
jurica238814 5:ecb7712b0825 140 while(!i2sFlag); // Wait for the interrupt to change the flag
jurica238814 5:ecb7712b0825 141 if(firstInt){
jurica238814 5:ecb7712b0825 142 firstInt = 0;
jurica238814 5:ecb7712b0825 143 frameTimer.start();
jurica238814 5:ecb7712b0825 144 }
jurica238814 5:ecb7712b0825 145 lastIntTime_us = frameTimer.read_us();
jurica238814 5:ecb7712b0825 146 frameTimer.reset();
jurica238814 5:ecb7712b0825 147 i2sFlag = 0;
jurica238814 5:ecb7712b0825 148
jurica238814 5:ecb7712b0825 149 if(lastIntTime_us > 10000){
jurica238814 5:ecb7712b0825 150 return 1;
jurica238814 5:ecb7712b0825 151 }
jurica238814 5:ecb7712b0825 152 else{
jurica238814 5:ecb7712b0825 153 return 0;
jurica238814 5:ecb7712b0825 154 }
jurica238814 5:ecb7712b0825 155 }
jurica238814 5:ecb7712b0825 156
jurica238814 5:ecb7712b0825 157 void sendi2sData(){
jurica238814 5:ecb7712b0825 158 NRF_I2S->EVENTS_TXPTRUPD = 0;
jurica238814 5:ecb7712b0825 159 NRF_I2S->ENABLE = 1;
jurica238814 5:ecb7712b0825 160 NRF_I2S->TASKS_START = 1;
jurica238814 5:ecb7712b0825 161
jurica238814 5:ecb7712b0825 162 while(!NRF_I2S->EVENTS_TXPTRUPD); // Wait for the data to be send
jurica238814 5:ecb7712b0825 163 NRF_I2S->EVENTS_TXPTRUPD = 0;
jurica238814 5:ecb7712b0825 164 while(!NRF_I2S->EVENTS_TXPTRUPD); // Wait for the data to be send
jurica238814 5:ecb7712b0825 165 NRF_I2S->EVENTS_TXPTRUPD = 0;
jurica238814 5:ecb7712b0825 166 NRF_I2S->TASKS_STOP = 1;
jurica238814 5:ecb7712b0825 167 while(!NRF_I2S->EVENTS_STOPPED);
jurica238814 5:ecb7712b0825 168 NRF_I2S->ENABLE = 0;
jurica238814 5:ecb7712b0825 169 }
jurica238814 5:ecb7712b0825 170
jurica238814 5:ecb7712b0825 171 void sendCommand(uint32_t *commandType, uint32_t *command){
jurica238814 5:ecb7712b0825 172
jurica238814 5:ecb7712b0825 173
jurica238814 2:b28027b9c099 174 /*
jurica238814 2:b28027b9c099 175 * Na prvi interrupt pokreni frameTimer.
jurica238814 2:b28027b9c099 176 * Na svaki interrupt (falling edge na Lanc busu) izmjeri vrijeme od zadnjeg eventa
jurica238814 2:b28027b9c099 177 * Ako je to vrijeme > 5ms, onda je upravo taj prekid izazvao start bit novog framea
jurica238814 2:b28027b9c099 178 * U tom slučaju, kreni s donjim kodom, inaće nemoj ništa slati
jurica238814 2:b28027b9c099 179 */
jurica238814 5:ecb7712b0825 180 uint8_t cnt = 0;
jurica238814 2:b28027b9c099 181
jurica238814 5:ecb7712b0825 182 for(cnt; cnt < 4; cnt++){
jurica238814 5:ecb7712b0825 183 while(!(waitForStartBit()));
jurica238814 5:ecb7712b0825 184 NRF_I2S->TXD.PTR = (uint32_t)commandType;
jurica238814 5:ecb7712b0825 185 __disable_irq();
jurica238814 5:ecb7712b0825 186 // First or second start bit
jurica238814 5:ecb7712b0825 187 wait_us(60); // Small delay for first bit after start bit
jurica238814 5:ecb7712b0825 188 sendi2sData();
jurica238814 5:ecb7712b0825 189 __enable_irq();
jurica238814 5:ecb7712b0825 190 i2sFlag = 0;
jurica238814 2:b28027b9c099 191
jurica238814 5:ecb7712b0825 192 while(!i2sFlag); // Wait for new start bit (second byte into frame)
jurica238814 2:b28027b9c099 193
jurica238814 5:ecb7712b0825 194 NRF_I2S->TXD.PTR = (uint32_t)command;
jurica238814 5:ecb7712b0825 195 __disable_irq();
jurica238814 5:ecb7712b0825 196 // First or second start bit
jurica238814 5:ecb7712b0825 197 wait_us(60); // Small delay for first bit after start bit
jurica238814 5:ecb7712b0825 198 sendi2sData();
jurica238814 5:ecb7712b0825 199 i2sFlag = 0;
jurica238814 5:ecb7712b0825 200 __enable_irq();
jurica238814 2:b28027b9c099 201 }
jurica238814 1:3e3dded8192f 202 }
jurica238814 1:3e3dded8192f 203
jurica238814 5:ecb7712b0825 204 void i2sInit(){
jurica238814 0:d616ca59aad8 205 NRF_I2S->CONFIG.RXEN = 0; // Disable reception
jurica238814 0:d616ca59aad8 206 NRF_I2S->CONFIG.MCKEN = 1; // Enable MCK generator
jurica238814 4:6560e2966186 207
jurica238814 1:3e3dded8192f 208 NRF_I2S->CONFIG.MCKFREQ = 0x10000000; // DIV 31
jurica238814 1:3e3dded8192f 209 NRF_I2S->CONFIG.RATIO = 0; // Ratio = 32x
jurica238814 0:d616ca59aad8 210
jurica238814 1:3e3dded8192f 211 NRF_I2S->CONFIG.SWIDTH = 0; // Sample width = 8 bit
jurica238814 1:3e3dded8192f 212 NRF_I2S->CONFIG.ALIGN = 0; // Alignment = Right
jurica238814 0:d616ca59aad8 213 NRF_I2S->CONFIG.FORMAT = 0; // Format = I2S
jurica238814 0:d616ca59aad8 214 NRF_I2S->CONFIG.CHANNELS = 0; // Use stereo
jurica238814 0:d616ca59aad8 215
jurica238814 1:3e3dded8192f 216 NRF_I2S->PSEL.LRCK = 27; // LRCK routed to pin 26
jurica238814 1:3e3dded8192f 217 NRF_I2S->PSEL.SDOUT = LANC_COMMAND_PIN; // SDOUT routed to pin 28
jurica238814 1:3e3dded8192f 218 NRF_I2S->PSEL.SCK = 30; // SCK routed to pin 30
jurica238814 1:3e3dded8192f 219 NRF_I2S->PSEL.MCK = 0x80000000; // MCK disconnected
jurica238814 1:3e3dded8192f 220 NRF_I2S->PSEL.SDIN = 0x80000000; // SDIN disconnected
jurica238814 0:d616ca59aad8 221
jurica238814 2:b28027b9c099 222 NRF_I2S->TXD.PTR = (uint32_t)normalCmdAddr;
jurica238814 2:b28027b9c099 223 NRF_I2S->RXTXD.MAXCNT = MY_BUF_SIZE/4; // Div with 4 cuz that's number of 32 bit words
jurica238814 0:d616ca59aad8 224 }
jurica238814 0:d616ca59aad8 225
jurica238814 0:d616ca59aad8 226
jurica238814 5:ecb7712b0825 227 int main(void){
jurica238814 7:5a9d22d7fe00 228 alive = LED_ON;
jurica238814 7:5a9d22d7fe00 229 connectedLED = LED_OFF;
jurica238814 5:ecb7712b0825 230
jurica238814 6:8cf24e946b0b 231 ble.init(bleInitComplete);
jurica238814 6:8cf24e946b0b 232 while (ble.hasInitialized() == false) { /* spin loop */ }
jurica238814 6:8cf24e946b0b 233 ble.gap().startAdvertising();
jurica238814 5:ecb7712b0825 234
jurica238814 6:8cf24e946b0b 235 i2sInit();
jurica238814 5:ecb7712b0825 236 button.fall(i2sReady);
jurica238814 5:ecb7712b0825 237
jurica238814 6:8cf24e946b0b 238 sendCommand(zoomCmdAddr, zoomInAddr);
jurica238814 7:5a9d22d7fe00 239
jurica238814 5:ecb7712b0825 240 while(1){
jurica238814 6:8cf24e946b0b 241 ble.waitForEvent();
jurica238814 5:ecb7712b0825 242 }
jurica238814 5:ecb7712b0825 243 }