Sony's LANC camera control protocol project.

Dependencies:   aconno_LANC aconno_bsp aconno_SEGGER_RTT

Committer:
jurica238814
Date:
Thu Jul 12 16:51:44 2018 +0000
Revision:
11:e5f11b96088e
Parent:
9:978106d4b181
Child:
12:69dbd9ef58e8
Segger RTT added. Charac. extended on 2B.

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