西東京市にいる組み込みおやじ-電子工作、回路設計、ファーム TIPS

このブログはビーコンの代表である菅原が、電気電子、電子工作、組み込みソフトウェアなどで、自分が苦労したところや面白い気づきなどを記事にしていきます。電子工作やマイコンに親しむ人が少しでも増えたらという思いでつづります。
やっぱり、電子工作が好きなんですよ。
ble_nus_data_send() の送信タイミング
0

    JUGEMテーマ:組み込み開発

     

    nRF5_SDK_15.2

    softdevice6.10

     

    とりあえず、BLEでデータを送受信する場合 NordicのSDKの ble_nus を使うのが簡単。

    しかしながらうかつにble_nus_data_send()関数をコールするとハングアップしてしまう。

    nus_data_handler の引数 ble_nus_evt_t * p_evt->type はサンプルでは BLE_NUS_EVT_RX_DATA しかないが実際には

     

    BLE_NUS_EVT_RX_DATA //データを受信した

    BLE_NUS_EVT_TX_RDY  //送信可能状態になった

    BLE_NUS_EVT_COMM_STARTED //ble_nus 接続した

    BLE_NUS_EVT_COMM_STOPPED // ble_nus 切断した

     

    の四つのタイプがある。

    これらで BLE_NUS_EVT_COMM_STARTED がきたら ble_nus_data_send()することができる。

    ble_nus_data_send()後、BLE_NUS_EVT_TX_RDYで送信完了を確認するまでは ble_nus_data_send()をコールできない。

     

    ◆元のサンプルソース

    static void nus_data_handler(ble_nus_evt_t * p_evt)
    {

        if (p_evt->type == BLE_NUS_EVT_RX_DATA)
        {
            uint32_t err_code;

            NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
            NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);

            for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
            {
                do
                {
                    err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
                    if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
                    {
                        NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
                        APP_ERROR_CHECK(err_code);
                    }
                } while (err_code == NRF_ERROR_BUSY);
            }
            if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '¥r')
            {
                while (app_uart_put('¥n') == NRF_ERROR_BUSY);
            }
        }

    }
     

     

    ◆p_evt->type を switch文で処理してみた。各処理の中身は各自コーディングしてください。

    static void nus_data_handler(ble_nus_evt_t * p_evt)
    {
        uint32_t err_code;
        switch(p_evt->type){
            case BLE_NUS_EVT_RX_DATA:

            //データ受信の処理

                break;

     

            case BLE_NUS_EVT_TX_RDY:       /**< Service is ready to accept new data to be transmitted. */

            //データ送信完了

         // ble_nus_data_send()関数でデータ送信した後、送信できる状態になった

                break;

     

            case BLE_NUS_EVT_COMM_STARTED: /**< Notification has been enabled. */

         // BLE_NUS が接続した。ble_nus_data_send()関数で送信できるようになった。

                break;
            case BLE_NUS_EVT_COMM_STOPPED: /**< Notification has been disabled. */

         // BLE_NUS が切断した。

                break;
        }
    }

     

    | ビーコン菅原 | nRF5x Nordic | 19:14 | comments(0) | trackbacks(0) |
    nrf_fstorage_write の lenは4の倍数で
    0

      JUGEMテーマ:組み込み開発

       

      nRF5_SDK_15.2

      softdevice6.10

       

      Nordic提供のSDKには FlashROMのライブラリも提供されている。

      FlashROM関係の関数はSDKのバージョンによりかなり変化する。

      nRFのコンパクトさを生かすのに、外部の不揮発メモリを搭載することはしたくない。

      新しいSDKにする時の作業としてFlashROMのアクセスができるようにすることは欠かせない。

       

      いままでは Softdeviceを使うときとそうでないときで、違う関数をコールしていた。

      ble通信中に、一つのところでループして終了を待つみたいなことができないからだ。

       

      15.2ではSoftdeviceを使うときとそうでないときで同じ関数をコールすればよいようになっている。

      softdeviceを用いたときには

       nrf_fstrage.c と nrf_fstrage_sd.c をコンパイルする。

      そうでないときには

      nrf_fstrage.c と nrf_fstrage_nvmc.c をコンパイルする。・・と思う。

       

      (私は softdevieの方しか作っていないので、nrf_fstrage_nvmc.c のほうは間違っているかもしれない。)

       

      softdeviceでFlashROMを上書きしたいときには nrf_fstorage_erase をまずコールして、そこで待たずに次の処理に移る。

      イレースが終わったらコールバック関数に飛ぶので、ここで nrf_fstorage_writeをコールする。

      ライトが終わるとコールバック関数に再び飛ぶので、これで書き込み終了となる。

       

      ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
                                    uint32_t               dest,
                                    void           const * p_src,
                                    uint32_t               len,
                                    void                 * p_param);
       

      のlen は書き込むバイト数の指定になる。4の倍数でないとエラーになって書き込むことができない。

      nRFのFlashROMが 32bitを1ワードとしているので、32bitずつ書き込んでいるのだろうと思う。

       

       

      余談だけど、SDK15.2では今まで使っていたライブラリ関数を Legacyとかいうフォルダにまとめてあり

      nrf_・・・というファイルに加えて nrfx_・・のファイルが増えている。

      次あたり 大きな仕様変更があるかもしれない。

       

      | ビーコン菅原 | nRF5x Nordic | 00:55 | comments(0) | trackbacks(0) |
      UICRはなかなかに使いにくい。
      0

        JUGEMテーマ:組み込み開発

         

        パラメータなどを格納する必要があり、UICRを検討した。

        UICRはUser information configuration registers の略で、ユーザーに解放されたコンフィグ領域となる。

         

        UICRの末尾にはなぜか P0.09,P0.10 をNFCモードで使うかどうかの設定も入っているので注意が必要だが

        32このパラメータを格納できるように見える。

        だか、ちょっと使いにくい

         

        ・リセットしないと変更が有効にならない・・

        ・アクセスするときにフラグが変化するまで待つと、その間にBLE通信が止まってしまう。→タイマーなどで間隔をあけて制御しないといけない。

         

        一時は UICRにパラメータ格納しようとしたが、アプリケーションに解放されているFlashの末尾のページに格納することにした。

         

         

        | ビーコン菅原 | nRF5x Nordic | 10:34 | comments(0) | trackbacks(0) |
        SAADC のタイマーをTimer0からTimer1に変更する
        0

          JUGEMテーマ:組み込み開発

           

          nRF5_SDK_15.2.

          softdevice6.10

           

          examples/perifheral/saadc

          では SAADCを駆動するソースコードがある。

           

          TIMER0 を 400mSec に設定。コンペアマッチの信号を SAADCのトリガーにしている。

           

          これを

          examples/ble_xxxx

          の中にある BLEのサンプルに組み込むとハングアップする。

          bleの動作サンプルでは TIMER0を システムタイマーとして使っているらしく、ぶつかるためだ。

          ここで saadcのタイミングタイマーをTIMER1とした。

           

          本来であれば 一発でタイマーのチャンネルを切り替えることができればいいが、まだそうなっていないので、複数個所を変えないといけないのが、ちょっと残念。

           

           

          sdk_config.h

           

          #ifndef TIMER0_ENABLED
          #define TIMER0_ENABLED 1
          #endif

           

          main.c-72行目

          【旧】

          static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(0);

          【新】
          static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(1);
           

          main.c-98行目

          【旧】

              nrf_drv_timer_extended_compare(&m_timer,
                                             NRF_TIMER_CC_CHANNEL0,
                                             ticks,
                                             NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                             false);
          【新】
              nrf_drv_timer_extended_compare(&m_timer,
                                             NRF_TIMER_CC_CHANNEL1,
                                             ticks,
                                             NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK,
                                             false);

          main.c-105行目

          【旧】

              uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
                                                                                          NRF_TIMER_CC_CHANNEL0);

          【新】
              uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
                                                                                          NRF_TIMER_CC_CHANNEL1);

           

           

          | ビーコン菅原 | nRF5x Nordic | 11:25 | comments(0) | trackbacks(0) |
          nRF52 XTAL使わずにRCクロックでBLE通信
          0

            JUGEMテーマ:組み込み開発

             

            太陽誘電のEBSHSN をS132_SDKで開発している。

            nRF52832を搭載していて、すごく小さいのはいいが、IOが 15本しか出ていない

             

            太陽誘電

             

            このうち P0.00,P0.01 は 32.768KHzの水晶振動子

            P0.09,P0.10は NRFアンテナ端子

            P0.21 はリセット端子

            P0.05,P0.06,P0.07,P0.08は RTS/TX/CTS/RX 

            と決まっている。

            こうなると自由に使える端子は 6本しかない。

            P0.09,P0.10のNRFアンテナ端子は使わないのでIOにする。

             次にP0.05,P0.06,P0.07,P0.08は RTS/TX/CTS/RX は TX,RXのみ使い、RTS/CTSは使わないでポートとする。

            P0.21のリセット端子は残しておく。

            P0.00,P0.01 の XTALも外したい。・・だが単に LF_SRCを 内蔵の RC にしても、どうも動かない。。

            色々調べたが RCの場合は 定期的にキャリブレーションする設定にしないといけないらしい。

             

            sdk_config.h の Clockの以下定義にしたところ、BLE通信もするようになった。

            // <h> Clock - SoftDevice clock configuration

            #define NRF_SDH_CLOCK_LF_SRC 0
            #define NRF_SDH_CLOCK_LF_RC_CTIV 1
            #define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
            #define NRF_SDH_CLOCK_LF_ACCURACY 0

            これでP0.00,P0.01も IOポートとして使えるようになった。


             

            続きを読む >>
            | ビーコン菅原 | nRF5x Nordic | 20:05 | comments(0) | trackbacks(0) |
                123
            45678910
            11121314151617
            18192021222324
            252627282930 
            << November 2018 >>
            + RECOMMEND
            + RECOMMEND
            + SELECTED ENTRIES
            + RECENT COMMENTS
            + RECENT TRACKBACK
            + CATEGORIES
            + ARCHIVES
            + つぶやき
            + MOBILE
            qrcode
            + LINKS
            + PROFILE