同時公開のFunctionGenerator-DACと同時利用によりファンクション・ジェネレータを実現する。
Dependencies: BLE_API mbed nRF51822
FunctionGenerator-DAC
/users/ohneta/code/FunctionGenerator-DAC/
詳細は上記、FunctionGenerator-DACでおこないます。
Revision 0:6e47fe8d8f5c, committed 2015-06-16
- Comitter:
- ohneta
- Date:
- Tue Jun 16 07:20:05 2015 +0000
- Commit message:
- 1st release commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLE_API.lib Tue Jun 16 07:20:05 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#0e714ad205b4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FunctionGenCommands.h Tue Jun 16 07:20:05 2015 +0000 @@ -0,0 +1,122 @@ +//--------------------------------------------------------- +/** + * FunctionGenCommands.h + */ +//--------------------------------------------------------- + +#define FGC_BUFFERTRANSFER_MAX 16 + +typedef enum { + // commands + FGCommand_Non = 0x00, + FGCommand_Device, + FGCommand_Output, + FGCommand_Frequency, + FGCommand_WaveformInfo, + FGCommand_WaveformBlock, + FGCommand_WaveformToBuffer, + + // status + FGStatus_Device = 0x80 | FGCommand_Device, + FGStatus_Output = 0x80 | FGCommand_Output, + FGStatus_Frequency = 0x80 | FGCommand_Frequency, + + // special + FGCommand_Reset = 0xff, + +} enumFGCommand; + + +// Characteristics +#define CHARACTERISTICS_UUID_RESET 0xA100 +#define CHARACTERISTICS_UUID_DEVICE 0xA101 +#define CHARACTERISTICS_UUID_OUTPUT 0xA102 +#define CHARACTERISTICS_UUID_FREQUENCY 0xA103 +#define CHARACTERISTICS_UUID_WAVEFORMINFO 0xA110 +#define CHARACTERISTICS_UUID_WAVEFORMBLOCK 0xA111 +#define CHARACTERISTICS_UUID_WAVEFORMTOBUFFER 0xA112 + +//--------------------------------------------------------- +#pragma pack(1) +// for BLE waveform transfer format + +typedef struct { + uint16_t waveSize; // Waveform全体のデータ長(byte) = blockSize * blockMaxNum + uint8_t bitPerData; // 1データあたりのbit数 (8, 10, 12 or 16bit) + + uint8_t blockSize; // 1ブロックあたりのデータ転送サイズ(byte) (通常16bytes) + uint8_t blockMaxNum; // ブロックの最大数 = (waveSize + 1) / blockSize +} WaveformInfo, FGCommandWaveformInfo; + +typedef struct { + uint16_t blockNo; // ブロックNo. 0 〜 (WaveformInfo.blockMaxNum - 1) + uint8_t length; // WaveformBlock.bufferの有効な長さ + uint8_t buffer[FGC_BUFFERTRANSFER_MAX]; // 実際のデータ +} WaveformBlock, FGCommandWaveformBlock; + +//--------------------------------------------------------- +// for I2C packet format + +// header +typedef struct { + uint8_t command; + uint8_t length; +} FGHeader; + +// command bodys +typedef struct { + uint8_t device; +} FGCommandDevice; + +typedef struct { + uint8_t on; +} FGCommandOutput; + +typedef struct { + uint32_t frequency; +} FGCommandFrequency; + +//#define FGCommandWaveformInfo WaveformInfo +//#define FGCommandWaveformBlock WaveformInfoBlock + +typedef struct { +} FGCommandWaveformToBuffer; + +typedef struct { +} FGCommandReset; + +// status bodys +typedef struct { + uint8_t device; +} FGStatusDevice; + +typedef struct { + uint8_t xxx; +} FGStatusOutput; + +typedef struct { + uint8_t xxx; +} FGStatusFrequency; + + + +// command Packet format +typedef struct { + FGHeader header; + union { + FGCommandDevice commandDevice; + FGCommandOutput commandOutput; + FGCommandFrequency commandFrequency; + FGCommandWaveformInfo commandWaveformInfo; + FGCommandWaveformBlock commandWaveformBlock; + FGCommandWaveformToBuffer commandWaveformToBuffer; + + FGCommandReset commandReset; + + FGStatusDevice statusDevice; + FGStatusOutput statusOutput; + FGStatusFrequency statusFrequency; + } body; +} FGPacket; + +#pragma pack()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jun 16 07:20:05 2015 +0000 @@ -0,0 +1,286 @@ +#include "mbed.h" + +#include <I2C.h> +#include "BLEDevice.h" +#include "FunctionGenCommands.h" + +// prototypes + void connectionCallback(Gap::Handle_t Handle_t, + Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, + Gap::addr_type_t ownAddrType, const Gap::address_t ownAddr, + const Gap::ConnectionParams_t *params); +void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason); +void writeCharCallback(const GattCharacteristicWriteCBParams *params); +void lookme(); +void tickerCallback(); + +//void commandPrint(FGCommand *command); + +//--------------------------------------------------------- + +Ticker ticker; +Serial pc(P0_9, P0_11); +DigitalOut led1(P0_18); +DigitalOut led2(P0_19); + +DigitalOut lookmeOut(P0_21); +I2C i2c(P0_22, P0_20); +const int i2cSlaveAddr = 0x62; + +//--------------------------------------------------------- + +BLEDevice ble; + +const static char DEVICE_NAME[] = "mbedFuncGen 0.01"; +static const uint16_t uuid16_list[] = {0xFFFF}; // Custom UUID, FFFF is reserved for development + +// Set Up custom Characteristics +static uint8_t deviceValue = 0; +static uint8_t outputValue = 0; +static uint32_t frequencyValue = 0; +static WaveformInfo waveformInfoValue; +static WaveformBlock waveformBlockValue; + +WriteOnlyArrayGattCharacteristic<uint8_t, 0> resetChar(CHARACTERISTICS_UUID_RESET, NULL); +ReadWriteArrayGattCharacteristic<uint8_t, 1> deviceChar(CHARACTERISTICS_UUID_DEVICE, &deviceValue); +ReadWriteArrayGattCharacteristic<uint8_t, 1> outputChar(CHARACTERISTICS_UUID_OUTPUT, &outputValue); +ReadWriteArrayGattCharacteristic<uint32_t, 1> frequencyChar(CHARACTERISTICS_UUID_FREQUENCY, &frequencyValue); +WriteOnlyArrayGattCharacteristic<WaveformInfo, 1> waveformInfoChar(CHARACTERISTICS_UUID_WAVEFORMINFO, &waveformInfoValue); +WriteOnlyArrayGattCharacteristic<WaveformBlock, 1> waveformBlockChar(CHARACTERISTICS_UUID_WAVEFORMBLOCK, &waveformBlockValue); +WriteOnlyArrayGattCharacteristic<uint8_t, 0> waveformToBufferChar(CHARACTERISTICS_UUID_WAVEFORMTOBUFFER, NULL); + +// Set up custom service +GattCharacteristic *characteristics[] = { + &resetChar, + &deviceChar, + &outputChar, + &frequencyChar, + &waveformInfoChar, + &waveformBlockChar, + &waveformToBufferChar +}; +GattService customService( 0xA000, + characteristics, + sizeof(characteristics) / sizeof(GattCharacteristic *) ); + + +//--------------------------------------------------------- +/** + * + */ + void connectionCallback(Gap::Handle_t Handle_t, + Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, + Gap::addr_type_t ownAddrType, const Gap::address_t ownAddr, + const Gap::ConnectionParams_t *params) +{ + pc.printf("connectionCallback\n"); +} + +//--------------------------------------------------------- +/* + * Restart advertising when phone app disconnects + */ +void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) +{ + pc.printf("disconnectionCallback\n"); + ble.startAdvertising(); +} + +//--------------------------------------------------------- +//--------------------------------------------------------- +/* + * handle writes to writeCharacteristic + */ +void writeCharCallback(const GattCharacteristicWriteCBParams *params) +{ + led2 = !led2; + + FGPacket fgPacket; + + pc.printf("--------\n"); + pc.printf("writeCharCallback\n"); + { + pc.printf("Data received: length = %d, data = ", params->len); + for(int x = 0; x < params->len; x++) { + pc.printf("%02x ", params->data[x]); + } + pc.printf("\n"); + } + + if (params->charHandle == resetChar.getValueHandle()) { + pc.printf("resetChar\n"); + + fgPacket.header.command = FGCommand_Reset; + fgPacket.header.length = sizeof(FGHeader) + sizeof(FGCommandReset); + //fgPacket.body.commandReset = NULL; + + } else + if (params->charHandle == deviceChar.getValueHandle()) { + memcpy(&deviceValue, params->data, params->len); + pc.printf("deviceChar : deviceValue: %x\n", deviceValue); + + fgPacket.header.command = FGCommand_Device; + fgPacket.header.length = sizeof(FGHeader) + sizeof(FGCommandDevice); + fgPacket.body.commandDevice.device = deviceValue; + + } else + if (params->charHandle == outputChar.getValueHandle()) { + memcpy(&outputValue, params->data, params->len); + pc.printf("outputChar : outputValue: %x\n", outputValue); + + fgPacket.header.command = FGCommand_Output; + fgPacket.header.length = sizeof(FGHeader) + sizeof(FGCommandOutput); + fgPacket.body.commandOutput.on = outputValue; + + } else + if (params->charHandle == frequencyChar.getValueHandle()) { + memcpy(&frequencyValue, params->data, params->len); + pc.printf("frequencyChar\n"); + pc.printf("frequencyValue: %d (0x%x)\n", frequencyValue, frequencyValue); + + fgPacket.header.command = FGCommand_Frequency; + fgPacket.header.length = sizeof(FGHeader) + sizeof(FGCommandFrequency); + fgPacket.body.commandFrequency.frequency = frequencyValue; + + } else + if (params->charHandle == waveformInfoChar.getValueHandle()) { + memcpy(&waveformInfoValue, params->data, params->len); + pc.printf("waveformInfoChar\n"); + pc.printf("FGCommandWaveformInfo.waveSize: %d\n", waveformInfoValue.waveSize); + pc.printf(" bitPerData: %d\n", waveformInfoValue.bitPerData); + pc.printf(" blockSize: %d\n", waveformInfoValue.blockSize); + pc.printf(" blockMaxNum: %d\n", waveformInfoValue.blockMaxNum); + + fgPacket.header.command = FGCommand_WaveformInfo; + fgPacket.header.length = sizeof(FGHeader) + sizeof(FGCommandWaveformInfo); + fgPacket.body.commandWaveformInfo = waveformInfoValue; + + } else + if (params->charHandle == waveformBlockChar.getValueHandle()) { + memcpy(&waveformBlockValue, params->data, params->len); + pc.printf("waveformBlockChar\n"); + pc.printf("waveformBlockChar.blockNo: %d\n", waveformBlockValue.blockNo); + pc.printf(" length: %d\n", waveformBlockValue.length); + pc.printf(" buffer: "); + for (int i = 0; i < waveformBlockValue.length; i++) { + pc.printf("%02x ", waveformBlockValue.buffer[i]); + } + pc.printf("\n"); + + fgPacket.header.command = FGCommand_WaveformBlock; + fgPacket.header.length = sizeof(FGHeader) + sizeof(FGCommandWaveformBlock); + fgPacket.body.commandWaveformBlock = waveformBlockValue; + + } else + if (params->charHandle == waveformToBufferChar.getValueHandle()) { + pc.printf("waveformToBufferChar : non\n"); + + fgPacket.header.command = FGCommand_WaveformToBuffer; + fgPacket.header.length = sizeof(FGHeader) + sizeof(FGCommand_WaveformToBuffer); + //fgPacket.body.commandWaveformToBuffer = NULL; + } + + + // I2C送信 + { + lookme(); + int ret = i2c.write(i2cSlaveAddr, (const char *)&fgPacket, fgPacket.header.length); + pc.printf("I2C ret: %d \n", ret); + + //ble.updateCharacteristicValue(readChar.getValueHandle(),params->data,params->len); + } +} + +//--------------------------------------------------------- +// 要調整 +void lookme() +{ + lookmeOut = 0; + wait_ms(5); + lookmeOut = 1; + wait_ms(5); + lookmeOut = 0; +} + +//--------------------------------------------------------- +unsigned long gTickerCount = 0; + +void tickerCallback() +{ + led1 = !led1; + gTickerCount++; +} + +//--------------------------------------------------------- +/* + * main loop + */ +int main(void) +{ + ticker.attach(&tickerCallback, 0.5); + i2c.frequency(100000); + + pc.baud(115200); + pc.printf("\n"); + pc.printf("mbed function generator BLE translator\n"); + pc.printf("--\n"); + + + ble.init(); + ble.onConnection(connectionCallback); + ble.onDisconnection(disconnectionCallback); + + ble.onDataWritten(writeCharCallback); // 書き込まれたときのコールバック + //ble_error_t err = ble.onDataRead(readCharCallback); // 読み込まれたときのコールバック + +/* +void onDataSent (void(*callback)(unsigned count)) +void onDataWritten (void(*callback)(const GattCharacteristicWriteCBParams *eventDataP)) +ble_error_t onDataRead (void(*callback)(const GattCharacteristicReadCBParams *eventDataP)) +void onRadioNotification (Gap::RadioNotificationEventCallback_t callback) + +*/ + + // setup advertising + { + // BLE only, no classic BT + ble.accumulateAdvertisingPayload( GapAdvertisingData::BREDR_NOT_SUPPORTED | + GapAdvertisingData::LE_GENERAL_DISCOVERABLE ); + // advertising type + ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + // add name + ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LOCAL_NAME, + (uint8_t *)DEVICE_NAME, + sizeof(DEVICE_NAME) ); + // UUID's broadcast in advertising packet + ble.accumulateAdvertisingPayload( GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, + (uint8_t *)uuid16_list, + sizeof(uuid16_list) ); + ble.setAdvertisingInterval(100); // interval is 100ms. + // add my service + ble.addService(customService); + + // start advertising + ble.startAdvertising(); + } + + + + while (true) { + ble.waitForEvent(); +#if 0 + { + led2 = 0; wait(0.1); + led2 = 1; wait(0.2); + led2 = 0; wait(0.1); + led2 = 1; wait(0.2); + led2 = 0; wait(0.1); + led2 = 1; wait(0.2); + led2 = 0; wait(0.1); + led2 = 1; wait(0.2); + led2 = 0; + } +#endif + led2 = !led2; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Jun 16 07:20:05 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/8ab26030e058 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nRF51822.lib Tue Jun 16 07:20:05 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#03a9fc49c21e