mbed HRM1017によるAD9850の操作

Dependencies:   BLE_API mbed nRF51822

what's this ? / 概要

あとで、ちゃんと書く(とおもう)

detail / 詳細

あとで、ちゃんと書く(とおもう)

BEL command format / BLEコマンドフォーマット

あとで、ちゃんと書く(とおもう)

BLE App for iPhone

iOS用アプリソースコード App source codes for iOS

https://github.com/ohneta/AD9850BLE

pictures / とりあえず写真など

外観

/media/uploads/ohneta/img_5653.jpg

アプリ画面

/media/uploads/ohneta/img_0101.png

more ...

Files at this revision

API Documentation at this revision

Comitter:
ohneta
Date:
Thu Jun 18 03:58:23 2015 +0000
Commit message:
1st commit

Changed in this revision

AD9850/AD9850.cpp Show annotated file Show diff for this revision Revisions of this file
AD9850/AD9850.h Show annotated file Show diff for this revision Revisions of this file
BLE_API.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
nRF51822.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD9850/AD9850.cpp	Thu Jun 18 03:58:23 2015 +0000
@@ -0,0 +1,135 @@
+//----------------------------------------------------------------
+/**
+ * 中華DDS AD9850のコントロール
+ * 
+ * mbed LPC1768では SPIを操作することで40bitの出力ができるが、
+ * mbed HRM1017等ではSPIの動作が違うためソフトウェアでシリアルデータを出力する
+ * 
+ * 参考資料
+ *   AD9850データシート
+ *     http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf
+ *   mbed LPC1768 SPIでの実装例
+ *     http://developer.mbed.org/users/liamg/code/AD9850-function-generator-SPI-driver/
+ */
+//----------------------------------------------------------------
+
+#include "AD9850.h"
+
+#define AD9850_FREQ_CONST   34.359738368
+/*
+ * AD9850/clock=125MHz 
+ * 2の32乗=4294967296、DDSクロック==125MHzを前提とすると...
+ * 1Hz設定時の値 = 4294967296/125000000 = 34.359738368 となる
+ */
+
+//----------------------------------------------------------------
+/**
+ * コンストラクタ
+ *
+ * @param PinName data   データ転送ピン
+ * @param PinName w_clk  クロックピン
+ * @param PinName fu_ud  モジュール選択
+ * @param PinName reset  リセット
+ */
+AD9850::AD9850(PinName data, PinName w_clk, PinName fu_ud, PinName reset)
+    : _outBit(data), _w_clk(w_clk), _fu_ud(fu_ud), _reset(reset)
+{
+    init();
+}
+
+//----------------------------------------------------------------
+/**
+ * デストラクタ
+ */
+AD9850::~AD9850()
+{
+}
+
+//----------------------------------------------------------------
+/**
+ * 初期化
+ */
+void AD9850::init()
+{
+    reset();
+}
+
+//----------------------------------------------------------------
+/**
+ * リセット
+ */
+void AD9850::reset()
+{
+    _reset = 0; wait_ms(5);
+    _reset = 1; wait_ms(5);
+    _reset = 0; wait_ms(5);
+}
+
+//----------------------------------------------------------------
+/**
+ * 周波数設定
+ *
+ * @param int freq  設定する周波数(Hz)
+ *                  AD9850ボードに依存するがクロック125MHzで概ね 1〜40000000(1Hz〜40MHz)程度まで安定して動作する模様
+ * @param int pdwon パワーダウンビット (W34)
+ * @param int phase コントロール/フェーズ等データ (W32〜W39)
+ *
+ * AD9850へ送信する40bit
+ *  W0〜W31:
+ *    freqにAD9850_FREQ_CONSTを乗算した32bit値
+ *  W32, W33:
+ *    コントロールビット。常に0
+ *  W34:
+ *    1でパワーダウン(通常は0)
+ *  W35〜W39:
+ *    位相オフセット調整値 (11.25度単位)
+ */
+void AD9850::setFrequency(int freq, int pdwon, int phase)
+{
+    int freqParam = (int)((double)freq * AD9850_FREQ_CONST);    // 周波数に対応した32bitデータ(W0〜W31)
+
+    _w_clk = 0;
+    _fu_ud = 0; wait_ms(5);
+    _fu_ud = 1; wait_ms(5);
+    _fu_ud = 0;
+
+    for (int i = 0; i < 32; i++) {
+        int bit = ((freqParam >> i) & 0x01);    // LSBから送信
+        _w_clk = 0;
+        _outBit = bit;
+        wait_ms(0.1);
+        _w_clk = 1; wait_ms(2);
+        _w_clk = 0; wait_ms(2);
+    }
+
+    for (int i = 0; i < 8; i++) {
+        int bit = ((phase >> (7 - i)) & 0x01);
+        _w_clk = 0;
+        _outBit = bit;
+        wait_ms(0.1);
+        _w_clk = 1; wait_ms(2);
+        _w_clk = 0; wait_ms(2);
+    }
+
+    _fu_ud = 0; wait_ms(5);
+    _fu_ud = 1; wait_ms(5);
+    _fu_ud = 0;
+}
+
+//----------------------------------------------------------------
+/*
+
+// mbed HRM1017の場合
+AD9850 dds(P0_20, P0_25, P0_24, P0_23);
+
+int main()
+{
+    int frq = 10 * 1000 * 1000; // 10MHz
+    int phase = 0;
+    
+    dds.setFrequency(frq, phase);
+    while(1) {
+        // 
+    }
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD9850/AD9850.h	Thu Jun 18 03:58:23 2015 +0000
@@ -0,0 +1,29 @@
+//----------------------------------------------------------------
+//----------------------------------------------------------------
+/**
+ * 中華DDS AD9850のコントロール
+ * 
+ */
+//----------------------------------------------------------------
+//----------------------------------------------------------------
+
+#include "mbed.h"
+
+
+class AD9850 {
+
+public:
+    AD9850(PinName data, PinName w_clk, PinName fu_ud, PinName reset);
+    ~AD9850();
+
+    void init();
+    void reset();
+    void setFrequency(int freq, int pdwon = 0, int phase = 0);
+
+private:
+    DigitalOut  _outBit;
+    DigitalOut  _w_clk;
+    DigitalOut  _fu_ud;
+    DigitalOut  _reset;
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BLE_API.lib	Thu Jun 18 03:58:23 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#c4436674db7b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Jun 18 03:58:23 2015 +0000
@@ -0,0 +1,191 @@
+#include "mbed.h"
+#include "AD9850.h"
+#include "BLEDevice.h"
+
+#define DEBUG 1
+
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+Ticker ticker;
+Serial		pc(P0_9, P0_11);
+DigitalOut  led1(P0_18);
+DigitalOut  led2(P0_19);
+DigitalIn   btn1(P0_16);
+DigitalIn   btn2(P0_17);
+
+AD9850 dds(P0_20, P0_25, P0_24, P0_23);
+
+//-----------------------------------------------------------------------
+
+uint32_t targetFreq		= 10 * 1000 * 1000; // 10MHz - default
+uint32_t incrementFreq	= 100 * 1000;		// This is a 100KHz frequency increment
+
+//-----------------------------------------------------------------------
+
+BLEDevice  ble;
+
+const static char     DEVICE_NAME[] = "DDS-CTRL 0.2";
+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;
+
+ReadWriteArrayGattCharacteristic<uint8_t, 1>    deviceChar(0xA201,    &deviceValue);
+ReadWriteArrayGattCharacteristic<uint8_t, 1>    outputChar(0xA202,    &outputValue);
+ReadWriteArrayGattCharacteristic<uint32_t, 1> 	frequencyChar(0xA203, &frequencyValue);
+
+// Set up custom service
+GattCharacteristic *characteristics[] = {
+    &deviceChar,
+    &outputChar,
+    &frequencyChar,
+};
+GattService customService(0xA001, 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;
+
+	pc.printf("BLE:onDataWritten\n");
+
+    if (params->charHandle == deviceChar.getValueHandle()) {
+        memcpy(&deviceChar, params->data, params->len);
+        pc.printf("deviceChar\n");
+        pc.printf("deviceChar: deviceValue: %x\n", deviceValue);
+
+    } else
+    if (params->charHandle == outputChar.getValueHandle()) {
+        memcpy(&outputValue, params->data, params->len);
+        pc.printf("outputChar : outputValue: %x\n", outputValue);
+
+    } else
+    if (params->charHandle == frequencyChar.getValueHandle()) {
+        memcpy(&targetFreq, params->data, params->len);
+        pc.printf("frequencyChar\n");
+        pc.printf("targetFreq: %d\n", targetFreq);
+    }
+
+}
+
+//-----------------------------------------------------------------------
+
+void tickerCallback()
+{
+    led1 = !led1;
+}
+
+char guruguru(int cnt)
+{
+	static char gurus[] = {'-', '\\', '|', '/'};
+	return gurus[cnt % 4];
+}
+
+//--------------------------------
+
+int main(void)
+{
+    ticker.attach(&tickerCallback, 0.5);
+
+    pc.baud(115200);
+    pc.printf("\n");
+	pc.printf("------------------------\n");
+	pc.printf("DDS-CTRL start\n");
+	led1 = 0; led2 = 0;;
+
+
+    ble.init();
+    ble.onConnection(connectionCallback);
+    ble.onDisconnection(disconnectionCallback);
+    ble.onDataWritten(writeCharCallback);
+		
+	// 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();
+    }
+	pc.printf("BLE init\n");
+
+
+	// DDS 初期化
+	{
+		dds.init();
+pc.printf("\nFREQ: %d [default]\n", targetFreq);
+	    dds.setFrequency(targetFreq, 0, 0);
+	    dds.setFrequency(targetFreq, 0, 0);
+			// TODO: なぜか最初だけ2回ださないと設定されない... 
+	}
+	pc.printf("DDS init\n");
+
+
+	int loopCounter = 0;
+	int lastFreq = targetFreq;
+    while (true) {
+        ble.waitForEvent();
+
+		loopCounter++;
+		//pc.putc(guruguru(loopCounter));
+		//pc.putc('\r');
+		pc.putc('*');
+		wait_ms(100);
+
+		if (lastFreq != targetFreq) {
+pc.printf("\nFREQ: %d\n", targetFreq);
+        	dds.setFrequency(targetFreq, 0, 0);
+
+			//gInternalStorageBuffer.freq = targetFreq;
+			//nRF51822_internalStorage_write();
+
+			lastFreq = targetFreq;
+		}
+	}
+
+}
+
+//---------------------------------------------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Jun 18 03:58:23 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/7cff1c4259d7
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51822.lib	Thu Jun 18 03:58:23 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#d0fc349b9a1b