Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: aconno_LANC aconno_bsp aconno_SEGGER_RTT
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 }
Generated on Tue Jul 26 2022 04:57:25 by
1.7.2