Jurica Resetar / Mbed OS acn52832_LANC_BLE

Dependencies:   aconno_LANC aconno_bsp aconno_SEGGER_RTT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Example to demonstrate usage of the nrf52's I2S interface
00003  *
00004  * Made by Jurica Resetar @ aconno
00005  * jurica_resetar@yahoo.com
00006  * More info @ aconno.de
00007  *
00008  * All rights reserved
00009  *
00010  */
00011  
00012 #include "mbed.h"
00013 #include "acd52832_bsp.h"
00014 #include "ble/BLE.h"
00015 #include "GapAdvertisingData.h"
00016 #include "AckService.h"
00017 
00018 #define PRINT_ON_RTT    (1)
00019 
00020 #ifdef PRINT_ON_RTT
00021     #include "SEGGER_RTT.h"
00022     #define printf(...) SEGGER_RTT_printf(0, __VA_ARGS__)
00023 #else
00024     #define printf(...)
00025 #endif
00026 
00027 #define MY_BUF_SIZE     (13*8)
00028 #define LANC_H          0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\
00029                         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF    /* 13 B */
00030 #define LANC_H_L        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,\
00031                         0x00, 0x00, 0x00, 0x00, 0x00, 0xFF    /* 13 B */
00032 #define LANC_L          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
00033                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00    /* 13 B */
00034 
00035 /*
00036  *  Bitovi na I2S bus idu od MSBa do LSBa
00037  */
00038 
00039 #define LANC_COMMAND_PIN    (p2)   // Pin connected to Tr to pull lanc bus down/up     2/26
00040 #define LANC_PIN            (p3)   // Lanc bus pin (to scan for START/STOP bits)        3/25
00041 #define LED_ON              (0)
00042 #define LED_OFF             (1)
00043 #define MSD_SIZE            (29)             /* Manufacturer Specific Data lenght (in B) */
00044 
00045 uint8_t MSD[MSD_SIZE] = {0x59, 0x00, 0xDD, 0x4E, 0xCD, 0xC5, 0x5E, 0xA3, 0x43, 0x67, 0x8B, 0x84, 0x94, 0xFF, 0xBA, 0xD9, 0x29, 0xC6};
00046 uint8_t myMacAddress[6] = {};
00047 ACKService<2> *ackServicePtr;
00048 BLE &ble = BLE::Instance();
00049 
00050 void sendCommand(uint32_t *commandType, uint32_t *command);
00051 GapAdvertisingData advData = GapAdvertisingData();
00052 
00053 DigitalOut alive(p23);
00054 DigitalOut connectedLED(p24);
00055 DigitalOut testLED(p22);
00056 
00057 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};
00058 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};
00059 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};
00060 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
00061 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
00062 
00063 uint32_t *normalCmdAddr = (uint32_t*)normalCommand;
00064 uint32_t *zoomCmdAddr = (uint32_t*)zoomCommand;
00065 uint32_t *startStopAddr = (uint32_t*)startStop;
00066 uint32_t *zoomInAddr = (uint32_t*)zoomIn;
00067 uint32_t *zoomOutAddr = (uint32_t*)zoomOut;
00068 
00069 uint8_t volatile i2sFlag = 0;   
00070 uint8_t state = 0;  /* 1 -> Send command type, 0 -> send command */
00071 
00072 InterruptIn button(LANC_PIN);
00073 Timer frameTimer;
00074 
00075 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params){
00076     //connectedLED = LED_ON;
00077     ble.gap().stopAdvertising();
00078 }
00079 
00080 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
00081     /*
00082     switch(params->data[0]){
00083         case 0x00:{
00084             sendCommand(normalCmdAddr, startStopAddr);        
00085             alive = !alive;
00086     
00087             break;
00088         }
00089         case 0x01:{
00090             sendCommand(zoomCmdAddr, zoomOutAddr);        
00091             connectedLED = !connectedLED;
00092     
00093             break;
00094         }
00095         case 0x02:{
00096             sendCommand(zoomCmdAddr, zoomInAddr);        
00097             testLED = !testLED;
00098             break;
00099         }
00100         default: break;
00101     }
00102     */
00103     uint32_t commandType[MY_BUF_SIZE];
00104     uint32_t command[MY_BUF_SIZE];
00105     uint8_t counter;
00106     
00107     printf("Data[0]: %d\n", params->data[0]);
00108     printf("Data[1]: %d\n", params->data[1]);
00109     
00110     for(counter = 0; counter < 8; counter++)
00111     {
00112         (params->data[0] & (1 << 7 - counter)) ? commandType[counter] = LANC_H : 
00113                                              commandType[counter] = LANC_L;
00114     }
00115     
00116     for(counter = 0; counter < 8; counter++)
00117     {
00118         (params->data[0] & (1 << 7 - counter)) ? command[counter] = LANC_H : 
00119                                              command[counter] = LANC_L;
00120     }
00121     
00122     sendCommand(commandType, command);
00123     
00124     return;
00125 }
00126 
00127 /**
00128  * Restart Advertising on disconnection
00129  */
00130 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){
00131     connectedLED = LED_OFF;
00132     BLE::Instance().gap().startAdvertising();
00133 }
00134 
00135 
00136 /**
00137  * This function is called when the ble initialization process has failed
00138  */
00139 void onBleInitError(BLE &ble, ble_error_t error){
00140     /* Avoid compiler warnings */
00141     (void) ble;
00142     (void) error;
00143     /* Initialization error handling should go here */
00144 }
00145 
00146 /**
00147  * Callback triggered when the ble initialization process has finished
00148  */
00149 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){
00150     BLE&        ble   = params->ble;  
00151     uint8_t init_values[2];
00152     
00153    
00154     /* Get my MAC address */
00155     BLEProtocol::AddressType_t temp_address_type;
00156     ble.gap().getAddress(&temp_address_type, myMacAddress);
00157     ackServicePtr = new ACKService<2>(ble, init_values);
00158     
00159     ble.gap().onDisconnection(disconnectionCallback);
00160     ble.gap().onConnection(onConnectionCallback);         
00161     ble.gattServer().onDataWritten(onDataWrittenCallback);
00162     
00163     /* setup advertising */
00164     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)MSD, MSD_SIZE);
00165     ble.gap().setAdvertisingInterval(500);  // --> Has to be at least 100ms!
00166     ble.gap().startAdvertising();
00167 }
00168 
00169 void i2sReady(){
00170     /* Interrupt handler */
00171     i2sFlag = 1;
00172 }
00173 
00174 uint8_t waitForStartBit(){
00175     static uint8_t firstInt = 1;
00176     static int lastIntTime_us = 0;
00177     
00178     while(!i2sFlag);       // Wait for the interrupt to change the flag
00179     if(firstInt){
00180         firstInt = 0;
00181         frameTimer.start();
00182     }
00183     lastIntTime_us = frameTimer.read_us();
00184     frameTimer.reset();
00185     i2sFlag = 0;
00186     
00187     if(lastIntTime_us > 10000){
00188        return 1; 
00189     }
00190     else{
00191         return 0;
00192     }
00193 }
00194 
00195 void sendi2sData(){
00196     NRF_I2S->EVENTS_TXPTRUPD = 0;
00197     NRF_I2S->ENABLE = 1;
00198     NRF_I2S->TASKS_START = 1;    
00199     
00200     while(!NRF_I2S->EVENTS_TXPTRUPD);    // Wait for the data to be send
00201     NRF_I2S->EVENTS_TXPTRUPD = 0;
00202     while(!NRF_I2S->EVENTS_TXPTRUPD);    // Wait for the data to be send
00203     NRF_I2S->EVENTS_TXPTRUPD = 0; 
00204     NRF_I2S->TASKS_STOP = 1;
00205     while(!NRF_I2S->EVENTS_STOPPED);
00206     NRF_I2S->ENABLE = 0;
00207 }
00208 
00209 void sendCommand(uint32_t *commandType, uint32_t *command){
00210     
00211     
00212     /*
00213      *  Na prvi interrupt pokreni frameTimer. 
00214      *  Na svaki interrupt (falling edge na Lanc busu) izmjeri vrijeme od zadnjeg eventa
00215      *  Ako je to vrijeme > 5ms, onda je upravo taj prekid izazvao start bit novog framea
00216      *  U tom slučaju, kreni s donjim kodom, inaće nemoj ništa slati
00217      */
00218     uint8_t cnt = 0;
00219     
00220     for(cnt; cnt < 4; cnt++){
00221         while(!(waitForStartBit()));
00222         NRF_I2S->TXD.PTR = (uint32_t)commandType;        
00223         __disable_irq();
00224         // First or second start bit
00225         wait_us(60);    // Small delay for first bit after start bit
00226         sendi2sData();
00227         __enable_irq();
00228         i2sFlag = 0;
00229         
00230         while(!i2sFlag);        // Wait for new start bit (second byte into frame)
00231         
00232         NRF_I2S->TXD.PTR = (uint32_t)command;
00233         __disable_irq();
00234         // First or second start bit
00235         wait_us(60);    // Small delay for first bit after start bit
00236         sendi2sData();
00237         i2sFlag = 0;
00238         __enable_irq();
00239     }
00240 }
00241 
00242 void i2sInit(){
00243     NRF_I2S->CONFIG.RXEN = 0;       // Disable reception
00244     NRF_I2S->CONFIG.MCKEN = 1;      // Enable MCK generator
00245  
00246     NRF_I2S->CONFIG.MCKFREQ = 0x10000000; // DIV 31
00247     NRF_I2S->CONFIG.RATIO = 0;          // Ratio = 32x
00248     
00249     NRF_I2S->CONFIG.SWIDTH = 0;         // Sample width = 8 bit
00250     NRF_I2S->CONFIG.ALIGN = 0;          // Alignment = Right
00251     NRF_I2S->CONFIG.FORMAT = 0;         // Format = I2S
00252     NRF_I2S->CONFIG.CHANNELS = 0;       // Use stereo
00253     
00254     NRF_I2S->PSEL.LRCK = 27;                // LRCK routed to pin 26
00255     NRF_I2S->PSEL.SDOUT = LANC_COMMAND_PIN; // SDOUT routed to pin 28
00256     NRF_I2S->PSEL.SCK = 30;                 // SCK routed to pin 30
00257     NRF_I2S->PSEL.MCK = 0x80000000;         // MCK disconnected
00258     NRF_I2S->PSEL.SDIN = 0x80000000;        // SDIN disconnected
00259     
00260     NRF_I2S->TXD.PTR = (uint32_t)normalCmdAddr;
00261     NRF_I2S->RXTXD.MAXCNT = MY_BUF_SIZE/4;  // Div with 4 cuz that's number of 32 bit words
00262 }
00263 
00264 
00265 int main(void){
00266     alive = LED_OFF;
00267     
00268     ble.init(bleInitComplete);
00269     while (ble.hasInitialized()  == false) { /* spin loop */ }
00270     ble.gap().startAdvertising();
00271     
00272     i2sInit();
00273     button.fall(i2sReady);
00274     
00275     //sendCommand(zoomCmdAddr, zoomInAddr);
00276     
00277     connectedLED = LED_OFF;
00278     testLED = LED_OFF;
00279     
00280     while(1){
00281         ble.waitForEvent();
00282     }
00283 }