[D.I.D2014] Hướng dẫn sử dụng thư viện simpliciTI Phần 1 - Tạo project đơn giản

gochit

Cố Vấn CLB
Trong bài viết này, mình sẽ hướng dẫn các bạn sử dụng thư viện SimpliciTI đơn giản chỉ bao gồm giao tiếp truyền nhận gói tin giữa MCU và CC1101 (chỉ để test module RF xem có tèo không thôi :)) . Hiện tại nó chỉ dùng được với các loại module RF của TI sử dụng giao tiếp SPI ( không phải loại truyền UART =)) ) như các module trong các link sau:
+ http://dientuachau.com/page/index.php?_m=mod_product&_a=view&p_id=775

+ http://dientuachau.com/page/index.php?_m=mod_product&_a=view&p_id=773
+ http://www.anaren.com/air/cc110l-air-module-boosterpack-embedded-antenna-module-anaren ( đây là module các bạn sẽ được hỗ trợ trong vòng 2 :6cool_boss:)
Đầu tiên là giới thiệu sơ lược về thư viện simpliciTI:
SimpliciTI là một bộ thư viện dùng để thiết lập một mạng không dây với qui mô nhỏ, sử dụng các dòng chip RF của TI như CC1XXX/CC25XX/CC430. SimpliciTI cung cấp cho các bạn công cụ để hiện thực một mạng không dây đơn giản, vừa dễ sử dụng. Thông tin và tài liệu về simpliciTI các bạn có thể dễ dàng tìm được tại địa chỉ http://www.ti.com/tool/SimpliciTI?keyMatch=simpliciTI&tisearch=Search-EN. Trong file tải về từ link trên sẽ có phần tài liệu hướng dẫn đầy đủ bằng tiếng anh như các bạn có thể thấy ở hình dưới, các bạn có thể đọc để tìm hiểu sâu hơn về hoạt động của bộ thư viện này :D .

Tuy nhiên, bộ thư viện này chỉ hổ trợ cho dòng vi điều khiển msp430 và lõi 8051 trong các SoC RF của TI. Để sử dụng được với kit ek-tm4c123gxl thì cần phải sử dụng bản chỉnh sửa dành cho chip TM4C123.
1/ Việc đầu tiên là cẩn phải tải thư viện về, bản SimpliciTI v1.1 cho kit TM4C123gxl có thể được tải ở link:
https://www.dropbox.com/s/mi3wtjkr1ieluuf/simpiciti_ek-tm4c123gxl.rar?dl=0
Sau khi giải nén, ta được các folder như hình:


+ Folder app sẽ chứa code của chương trình sẽ viết,
+ Folder bsp chứa các mô tả về MCU, board, nếu muốn thay đổi các thiết lập phần cứng, hoặc muốn port qua cho một MCU khác thì có thể chỉnh sửa trong này
+ Folder driverlib chứa các driver của Tivaware
+ Folder mrfi chứa các file về giao tiếp với ic RF
+ Folder simpliciTI chứa các file về mạng của simpliciTI
2/ Khởi động CCS, phiên bản sử dụng trong bài này là CCS 6.0.1:
3/ Tạo project với vi điều khiển TM4C123GH6PM ( chọn empty project)


4/ Add các file cần thiết vào project:
+ Chuột phải vào tên project, chọn import>import


+ Chọn file system> next

+ Tìm đến nơi chứa code:



+ Trong folder app chọn tất cả, main.c là một ví dụ đơn giản được viết sẵn, simpliciTI_config.h là 1 file thiết lập mẫu (có thể add file tự tạo nếu thích :misdoubt:)


+ Trong folder bsp chọn bsp.c

+ Trong mục driverlib chọn chọn file driverlib.lib như hình:

+ Trong mục mrfi chọn mrfi.c

5/ Thêm các đường dẫn vào project:
+ Chuột phải vào project, chọn Property, chọn include Option


+ Thêm vào các đường dẫn tương tự như hình:

+ Chọn Predefine Symbols như hình





 
Last edited by a moderator:

gochit

Cố Vấn CLB
:1cool_byebye: Sau khi tạo xong project, việc tiếp theo là nói về code:
Muốn chạy được code, cần sửa lại file tm4c123gh6pm_startup_ccs.c 1 tí :D
+ Thêm extern void MRFI_GpioIsr(void); vào trước đoạn khai báo các vector ngắt
+ Sửa lại trình phục vụ ngắt của GPIOB thành MRFI_GpioIsr thay vì IntDefaultHandler
Sau khi chỉnh sửa xong các file đó thì bắt đầu build để chạy thôi nào :brick:
Nếu muốn chỉ nhận thì giữ nguyên code file main, nếu muốn gửi thì xóa mấy dấu "//" trước 2 câu lệnh trong while(1) của file main.c
Các module CC1101 khác nhau sẽ có các anten loại khác nhau và đi kèm với nó là tần số hoạt động khác nhau, nếu như các bạn cài đặt sai tần số thì khoảng cách truyền được sẽ rất ngắn, các bạn có thể sửa file mrfi\smartrf\CC1101\smartrf_CC1101.h để cài đặt lại tần số như mong muốn
Cuối cùng là lời kết cho một bài viết dài, đây là bước khởi đầu cho việc thiết lập thư viện simpliciTI, phía sau còn nhiều tình tiết hấp dẫn, hy vọng các bạn đừng vội hoang mang vì nó còn nhiều bước làm tào lao phía sau nếu như muốn xây dựng được một mạng hoàn chỉnh:6cool_boss:, còn nhiều điều mình định nhắn nhủ mà quên mất tiêu rồi, hẹn gặp lại ở các post sau :met:
Update:
+ Đây là clip sau khi nạp code cho 2 board, cái chớp xanh là board gửi, board chớp đỏ là board nhận
+ Code có các phần BSP led, thực ra phần này ko cần thiết vì có thể điều khiển led bằng code tự viết, nhưng mình đưa vào cho biết tới sự tồn tại của nó :6cool_boss:
 

Fujiko

Thành Viên PIF
Bài viết hay đây. :1cool_byebye: giá như có module C1101 SPI thì test ngay và luôn.
Thanh du sâu mất :4cool_beauty:
 

hoangthien94

Ban Chủ Nhiệm
anh cho em hỏi, em làm theo đúng hướng dẫn nhưng khi build thì ở dòng
Code:
#include "driverlib/sysctl.h"
nó báo lỗi " unresolved inclusion "driverlib/sysctl.h" "
đồng thời trong file bsp.c và mrfi.c nó cũng báo lỗi " #1965 cannot open source file "inc/hw_types.h" "
em đã thử include path các đường dẫn đến các file trên nhưng vẫn có lỗi như vậy, không biết sửa làm sao
mong anh giúp đỡ :9cool_too_sad:
 

hmtmarconi

Thành Viên PIF
anh cho em hỏi là em làm đúng theo hường dẫn nhưng khi built thì nó bị lỗi này "CORTEX_M4_0: GEL: Encountered a problem loading file: E:\DID2014\simpiciti\Debug\simpliciTI.out Could not open file"
 

Attachments

gochit

Cố Vấn CLB
Hình như bạn chưa built thành công file nên nó xuất hiện lỗi như thế, bạn build lại rồi check xem bị lỗi chỗ nào.
 

Davion Dawn

Thành Viên PIF
Các anh cho em hỏi, trong main hàm "MRFI_Transmit(&packet, MRFI_TX_TYPE_FORCED);" có đối số là "packet", vậy dữ liệu được gửi đi nằm trong các frame của packet hay sao ạ? Em thử Debug nhưng tab expressions không tìm thấy biến "packet"?
 

gochit

Cố Vấn CLB
Packet là một chuỗi dữ liệu, byte bắt đầu sẽ là độ dài dữ liệu, các byte tiếp theo là nội dung.
 

Davion Dawn

Thành Viên PIF
Trong Simpliciti có cái nói về cascade network, em làm theo code mẫu, chạy đoạn đầu giống như hướng dẫn (chớp tắt led chờ tín hiệu và phát tín hiệu khi nhấn nút), nhưng lại không nhận được tín hiệu khi device khác phát tín hiệu (không có phản ứng gì cả, nó cứ chớp tắt chờ tín hiệu như chưa có gì xảy ra :5cool_sweat: ) các anh xem giúp em với
Code:
#include "bsp.h"
#include "mrfi.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "nwk.h"
 
#include "app_remap_led.h"
 
static void monitorForBadNews(void);
 
void toggleLED(uint8_t);
static void start2Babble(void);
 
#define SPIN_ABOUT_A_SECOND          NWK_DELAY(1000)
#define SPIN_ABOUT_A_QUARTER_SECOND  NWK_DELAY(250)
 
#define BAD_NEWS  (1)
#define CHECK_RATE (5)
 
void main (void)
{
  BSP_Init();
 
  /* If an on-the-fly device address is generated it must be done before the
  * call to SMPL_Init(). If the address is set here the ROM value will not
  * be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call
  * will not take effect. One shot only. The IOCTL call below is conformal.
  */
#ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE
  {
    addr_t lAddr;
 
    createRandomAddress(&lAddr);
    SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
  }
#endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */
 
  /* This call will fail because the join will fail since there is no Access Point
  * in this scenario. but we don't care -- just use the default link token later.
  * we supply a callback pointer to handle the message returned by the peer.
  */
  SMPL_Init(0);
 
  /* turn on LEDs. */
  if (!BSP_LED2_IS_ON())
  {
    toggleLED(2);
  }
  if (!BSP_LED1_IS_ON())
  {
    toggleLED(1);
  }
 
  /* wait for a button press... */
  do {
    if (BSP_BUTTON1() || BSP_BUTTON2())
    {
      break;
    }
  } while (1);
 
  /* never coming back... */
  monitorForBadNews();
 
  /* but in case we do... */
  while (1) ;
}
 
static void monitorForBadNews()
{
  uint8_t i, msg[1], len;
 
  /* Turn off LEDs. Check for bad news will toggle one LED.
  * The other LED will toggle when bad news message is sent.
  */
  toggleLED(2);
  toggleLED(1);
 
  /* start the radio off sleeping */
  SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
 
  while (1)
  {
    /* spoof MCU sleeping... */
    for (i=0; i<CHECK_RATE; ++i)
    {
      SPIN_ABOUT_A_SECOND;
    }
 
    toggleLED(1);
    /* check "sensor" to see if we need to send an alert */
    if (BSP_BUTTON1() || BSP_BUTTON2())
    {
      /* sensor activated. start babbling. */
      start2Babble();
    }
    /* wake up radio. we need it to listen for others babbling. */
    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
    /* turn on RX. default is RX off. */
    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
 
    /* stay on "long enough" to see if someone else is babbling */
    SPIN_ABOUT_A_QUARTER_SECOND;
 
    /* we're done with radio. shut it down */
    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
 
    /* got message? */
    if (SMPL_SUCCESS == SMPL_Receive(SMPL_LINKID_USER_UUD, msg, &len))
    {
      /* got something. is it bad news? */
      if (len && (msg[0] == BAD_NEWS))
      {
        /* Yep. start babbling. If there is a filtering token make
        * sure the token matches the expected value.
        */
        start2Babble();
      }
    }
  }
}
 
 
void toggleLED(uint8_t which)
{
  if (1 == which)
  {
    BSP_TOGGLE_LED1();
  }
  else if (2 == which)
  {
    BSP_TOGGLE_LED2();
  }
  return;
}
 
 
static void start2Babble()
{
  uint8_t msg[1];
 
  /* wake up radio. */
  SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
 
  /* Send the bad news message. To prevent confusion with different "networks"
  * such as neighboring smoke alarm arrays send a token controlled by a DIP
  * switch, for example, and filter in this token.
  */
  msg[0] = BAD_NEWS;
  while (1)
  {
    /*wait "a while" */
    NWK_DELAY(100);
    /* babble... */
    SMPL_Send(SMPL_LINKID_USER_UUD, msg, sizeof(msg));
    toggleLED(2);
  }
}
 

nvhai

Trứng gà
#error "ERROR: Unknown or missing radio selection."
Quynh nao bi loi nay trong code chua? chi minh sua voi. thanks
 
Top