2016年3月30日 星期三

nRF51x22 SPI Master Driver

1. 簡單替nRF51822 SPI Driver做個備份.

2. 本範例搭配ST LIS3DH Sensor Board測試使用.

3. 需先include spi_master.c 和 spi_master.h, 路徑在 \app\components\drivers_nrf\spi_master\ 底下.



4. spi_master.c 和 spi_master.h 的下載連結:

    spi_master.c

    spi_master.h

5. code:

spi_example.h

  1. #include "app_util_platform.h"
  2. #include "bsp.h"
  3. #include "spi_master.h"
  4.  
  5. bool SPI_Write( uint8_t register_address, uint8_t *value, uint8_t number_of_bytes );
  6. bool SPI_Read( uint8_t register_address, uint8_t *destination, uint8_t number_of_bytes );
  7.  

spi_example.c

  1. #include "spi_example.h"
  2.  
  3.  
  4. static void spi_master_init(spi_master_hw_instance_t spi_master_instance )
  5. {
  6. uint32_t err_code = NRF_SUCCESS;
  7.  
  8. // Configure SPI master.
  9. spi_master_config_t spi_config = SPI_MASTER_INIT_DEFAULT;
  10. spi_config.SPI_CONFIG_CPHA=SPI_CONFIG_CPHA_Leading ;
  11. spi_config.SPI_CONFIG_CPOL=SPI_CONFIG_CPOL_ActiveHigh;
  12. spi_config.SPI_Pin_SCK = SPIM0_SCK_PIN;
  13. spi_config.SPI_Pin_MISO = SPIM0_MISO_PIN;
  14. spi_config.SPI_Pin_MOSI = SPIM0_MOSI_PIN;
  15. spi_config.SPI_Pin_SS = SPIM0_SS_PIN;
  16. spi_config.SPI_Freq = SPI_FREQUENCY_FREQUENCY_M4;
  17. spi_config.SPI_CONFIG_ORDER = SPI_CONFIG_ORDER_MsbFirst;
  18. spi_config.SPI_PriorityIRQ = APP_IRQ_PRIORITY_LOW;
  19. spi_config.SPI_DisableAllIRQ = 0;
  20. err_code = spi_master_open(spi_master_instance, &spi_config);
  21. APP_ERROR_CHECK(err_code);
  22. }
  23.  
  24. static void spi_send_recv(const spi_master_hw_instance_t spi_master_hw_instance, uint8_t * const p_tx_data, uint8_t * const p_rx_data, const uint16_t len)
  25. {
  26. // Start transfer.
  27. spi_master_init(spi_master_hw_instance);
  28. uint32_t err_code = spi_master_send_recv(spi_master_hw_instance, p_tx_data, len, p_rx_data, len);
  29. APP_ERROR_CHECK(err_code);
  30. for (int i = 0 ; i < 1000 ; i++ ) {
  31. if ( spi_master_get_state(spi_master_hw_instance) != SPI_MASTER_STATE_BUSY )
  32. break;
  33. }
  34. spi_master_close(spi_master_hw_instance);
  35. }
  36.  
  37. bool SPI_Write( uint8_t register_address, uint8_t *value, uint8_t number_of_bytes )
  38. {
  39. #define i2c_write_data_len 6
  40. uint8_t w2_data[i2c_write_data_len+1];
  41. uint8_t r2_data[i2c_write_data_len+1];
  42. uint8_t i;
  43.  
  44. if(number_of_bytes > 0x01)
  45. {
  46. register_address |= (uint8_t)MULTIPLEBYTE_CMD;
  47. }
  48. w2_data[0] = register_address;
  49. for ( i = 0 ; i < number_of_bytes ; i++ ) {
  50. w2_data[i+1] = value[i];
  51. }
  52.  
  53. spi_send_recv(SPI_MASTER_0, w2_data, r2_data, number_of_bytes +1);
  54.  
  55. return true;
  56. }
  57.  
  58. bool SPI_Read(uint8_t register_address, uint8_t * destination, uint8_t number_of_bytes)
  59. {
  60. #define i2c_read_data_len 8
  61.  
  62. uint8_t w2_data[i2c_write_data_len+1];
  63. uint8_t r2_data[i2c_write_data_len+1];
  64. uint8_t i;
  65.  
  66. if(number_of_bytes > 0x01)
  67. {
  68. register_address |= (uint8_t)(READWRITE_CMD | MULTIPLEBYTE_CMD);
  69. }
  70. else
  71. {
  72. register_address |= (uint8_t)READWRITE_CMD;
  73. }
  74. w2_data[0] = register_address;
  75. spi_send_recv(SPI_MASTER_0, w2_data, r2_data, number_of_bytes+1);
  76. for( i = 0 ; i < number_of_bytes ; i++ ) {
  77. destination[i] = r2_data[i+1];
  78. }
  79.  
  80. return true;
  81. }
  82.  

6. example-1:  read WHO_AM_I register(0x0F) from LIS3DH.

  1. #define LIS3DH_REGISTER_WHO_AM_I 0x0F
  2.  
  3. void Read_LIS3DH_WHOAMI_Register(void)
  4. {
  5. uint8_t temp[6];
  6. SPI_Read(LIS3DH_REGISTER_WHO_AM_I, temp, 1);
  7. if ( temp[0] == 0x33 ) {
  8. while(1);
  9. }
  10. }
  11.  




7. example-2: Enable LIS3DH Sensor.

  1. #define LIS3DH_CTRL_REG1_DATARATE_100HZ 0x50
  2. #define LIS3DH_CTRL_REG1_XYZEN 0x07
  3. #define LIS3DH_REGISTER_CTRL_REG1 0x20
  4.  
  5. void Enable_LIS3DH_Sensor(void)
  6. {
  7. uint8_t temp[6];
  8. temp[0] = (LIS3DH_CTRL_REG1_DATARATE_100HZ | LIS3DH_CTRL_REG1_XYZEN);
  9. SPI_Write( LIS3DH_REGISTER_CTRL_REG1, temp, 1 );
  10. }
 




2016年3月9日 星期三

[News] Eachpal HALO Bracelet

        沒想到跟客戶合作的體感手鐲居然在MWC展覽上有展出, 不過目前看到的新聞都是主打丹麥設計師Jacob Jensen的噱頭, 還沒秀出相關的Gesture功能來展示.








2016年3月4日 星期五

2016年3月2日 星期三

STM32F103 I2C Master Driver

話不說多, 直接上code.

I2C_Master.h
  1.  
  2. #include "stm32f10x.h"
  3.  
  4. void I2C_Master_Init(void);
  5. void I2C_Master_DeInit(void);
  6. int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer, uint16_t numByteToRead);
  7. int I2C_Master_Write(uint8_t deviceAddress, uint8_t WriteAddr, uint8_t* pBuffer, uint16_t numByteToWrite);
  8. int I2C_TIMEOUT_UserCallback(void);
  9.  

I2C_Master.c
  1.  
  2. #include "I2C_Master.h"
  3.  
  4. #define I2C_MEMS I2C1
  5. #define I2C_MEMS_CLK RCC_APB1Periph_I2C1
  6. #define I2C_MEMS_GPIO GPIOB
  7. #define I2C_MEMS_GPIO_CLK RCC_APB2Periph_GPIOB
  8. #define I2C_MEMS_SCL GPIO_Pin_6
  9. #define I2C_MEMS_SDA GPIO_Pin_7
  10.  
  11. #define I2C_Speed 400000
  12. #define I2C_SLAVE_ADDRESS7 0xA0
  13. #define I2C_TIMEOUT 3000
  14.  
  15. /* I2C STOP mask */
  16. #define CR1_STOP_Set ((uint16_t)0x0200)
  17. #define CR1_STOP_Reset ((uint16_t)0xFDFF)
  18.  
  19. /* I2C ACK mask */
  20. #define CR1_ACK_Set ((uint16_t)0x0400)
  21. #define CR1_ACK_Reset ((uint16_t)0xFBFF)
  22.  
  23. /* I2C POS mask */
  24. #define CR1_POS_Set ((uint16_t)0x0800)
  25. #define CR1_POS_Reset ((uint16_t)0xF7FF)
  26.  
  27. #define NULL ((void *)0)
  28.  
  29.  
  30. void I2C_Master_Init(void)
  31. {
  32. GPIO_InitTypeDef GPIO_InitStructure;
  33. I2C_InitTypeDef I2C_InitStructure;
  34. /* I2C Periph clock enable */
  35. RCC_APB1PeriphClockCmd(I2C_MEMS_CLK, ENABLE);
  36. /* GPIO Periph clock enable */
  37. RCC_APB2PeriphClockCmd(I2C_MEMS_GPIO_CLK, ENABLE);
  38. /* GPIO configuration */
  39. GPIO_InitStructure.GPIO_Pin = I2C_MEMS_SCL | I2C_MEMS_SDA;
  40. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  41. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  42. GPIO_Init(I2C_MEMS_GPIO, &GPIO_InitStructure);
  43. /* I2C configuration */
  44. I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  45. I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  46. I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;
  47. I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  48. I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  49. I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
  50. /* I2C Peripheral Enable */
  51. I2C_Cmd(I2C_MEMS, ENABLE);
  52. /* Apply I2C configuration after enabling it */
  53. I2C_Init(I2C_MEMS, &I2C_InitStructure);
  54. }
  55.  
  56. void I2C_Master_DeInit(void)
  57. {
  58. GPIO_InitTypeDef GPIO_InitStructure;
  59. /* UnConfigure I2C */
  60. I2C_DeInit(I2C_MEMS);
  61. I2C_Cmd(I2C_MEMS, DISABLE);
  62. RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, DISABLE);
  63. /* UnConfigure I2C_MEMS pins: SCL and SDA */
  64. GPIO_InitStructure.GPIO_Pin = I2C_MEMS_SCL | I2C_MEMS_SDA;
  65. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  66. GPIO_Init(I2C_MEMS_GPIO, &GPIO_InitStructure);
  67. }
  68.  
  69.  
  70. int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer, uint16_t numByteToRead) {
  71. __IO uint32_t temp = 0;
  72. volatile int I2C_TimeOut = 0;
  73. // /* While the bus is busy * /
  74. I2C_TimeOut = I2C_TIMEOUT;
  75. while(I2C_GetFlagStatus(I2C_MEMS, I2C_FLAG_BUSY))
  76. {
  77. if (I2C_TimeOut-- <= 0){
  78. return(I2C_TIMEOUT_UserCallback());
  79. }
  80. }
  81. // * Send START condition * /
  82. I2C_GenerateSTART(I2C_MEMS, ENABLE);
  83.  
  84. // / * Test on EV5 and clear it * /
  85. I2C_TimeOut = I2C_TIMEOUT;
  86. while(!I2C_CheckEvent(I2C_MEMS, I2C_EVENT_MASTER_MODE_SELECT))
  87. {
  88. if (I2C_TimeOut-- <= 0){
  89. return(I2C_TIMEOUT_UserCallback());
  90. }
  91. }
  92. // / * Send EEPROM address for write * /
  93. I2C_Send7bitAddress(I2C_MEMS, deviceAddr, I2C_Direction_Transmitter);
  94.  
  95. // / * Test on EV6 and clear it * /
  96. I2C_TimeOut = I2C_TIMEOUT;
  97. while(!I2C_CheckEvent(I2C_MEMS, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  98. {
  99. if (I2C_TimeOut-- <= 0){
  100. return(I2C_TIMEOUT_UserCallback());
  101. }
  102. }
  103. // / * Send the EEPROM's internal address to read from: Only one byte address * /
  104. I2C_SendData(I2C_MEMS, readAddr);
  105.  
  106. /// * Test on EV8 and clear it * /
  107. I2C_TimeOut = I2C_TIMEOUT;
  108. while(!I2C_CheckEvent(I2C_MEMS, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  109. {
  110. if (I2C_TimeOut-- <= 0){
  111. return(I2C_TIMEOUT_UserCallback());
  112. }
  113. }
  114. /// * Send STRAT condition a second time * /
  115. I2C_GenerateSTART(I2C_MEMS, ENABLE);
  116.  
  117. /// * Test on EV5 and clear it * /
  118. I2C_TimeOut = I2C_TIMEOUT;
  119. while(!I2C_CheckEvent(I2C_MEMS, I2C_EVENT_MASTER_MODE_SELECT))
  120. {
  121. if (I2C_TimeOut-- <= 0){
  122. return(I2C_TIMEOUT_UserCallback());
  123. }
  124. }
  125. // * Send EEPROM address for read * /
  126. I2C_Send7bitAddress(I2C_MEMS, deviceAddr, I2C_Direction_Receiver);
  127.  
  128. if (numByteToRead == 1) {
  129. /* Wait until ADDR is set */
  130. I2C_TimeOut = I2C_TIMEOUT;
  131. while ((I2C_MEMS->SR1&0x0002) != 0x0002)
  132. {
  133. if (I2C_TimeOut-- <= 0){
  134. return(I2C_TIMEOUT_UserCallback());
  135. }
  136. }
  137. /* Clear ACK bit */
  138. I2C_MEMS->CR1 &= CR1_ACK_Reset;
  139. /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
  140. software sequence must complete before the current byte end of transfer */
  141. __disable_irq();
  142. /* Clear ADDR flag */
  143. temp = I2C_MEMS->SR2;
  144. /* Program the STOP */
  145. I2C_GenerateSTOP(I2C_MEMS, ENABLE);
  146. /* Re-enable IRQs */
  147. __enable_irq();
  148. /* Wait until a data is received in DR register (RXNE = 1) EV7 */
  149. I2C_TimeOut = I2C_TIMEOUT;
  150. while ((I2C_MEMS->SR1 & 0x00040) != 0x000040)
  151. {
  152. if (I2C_TimeOut-- <= 0){
  153. return(I2C_TIMEOUT_UserCallback());
  154. }
  155. }
  156. /* Read the data */
  157. *pBuffer = I2C_MEMS->DR;
  158. }
  159. else if (numByteToRead == 2) {
  160. /* Set POS bit */
  161. I2C_MEMS->CR1 |= CR1_POS_Set;
  162. /* Wait until ADDR is set: EV6 */
  163. I2C_TimeOut = I2C_TIMEOUT;
  164. while ((I2C_MEMS->SR1&0x0002) != 0x0002)
  165. {
  166. if (I2C_TimeOut-- <= 0){
  167. return(I2C_TIMEOUT_UserCallback());
  168. }
  169. }
  170. /* EV6_1: The acknowledge disable should be done just after EV6,
  171. that is after ADDR is cleared, so disable all active IRQs around ADDR clearing and
  172. ACK clearing */
  173. __disable_irq();
  174. /* Clear ADDR by reading SR2 register */
  175. temp = I2C_MEMS->SR2;
  176. /* Clear ACK */
  177. I2C_MEMS->CR1 &= CR1_ACK_Reset;
  178. /*Re-enable IRQs */
  179. __enable_irq();
  180. /* Wait until BTF is set */
  181. I2C_TimeOut = I2C_TIMEOUT;
  182. while ((I2C_MEMS->SR1 & 0x00004) != 0x000004)
  183. {
  184. if (I2C_TimeOut-- <= 0){
  185. return(I2C_TIMEOUT_UserCallback());
  186. }
  187. }
  188. /* Disable IRQs around STOP programming and data reading */
  189. __disable_irq();
  190. /* Program the STOP */
  191. I2C_GenerateSTOP(I2C_MEMS, ENABLE);
  192. /* Read first data */
  193. *pBuffer = I2C_MEMS->DR;
  194. /* Re-enable IRQs */
  195. __enable_irq();
  196. /**/
  197. pBuffer++;
  198. /* Read second data */
  199. *pBuffer = I2C_MEMS->DR;
  200. /* Clear POS bit */
  201. I2C_MEMS->CR1 &= CR1_POS_Reset;
  202. }
  203.  
  204. else { //numByteToRead > 2
  205. // * Test on EV6 and clear it * /
  206. I2C_TimeOut = I2C_TIMEOUT;
  207. while(!I2C_CheckEvent(I2C_MEMS, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  208. {
  209. if (I2C_TimeOut-- <= 0){
  210. return(I2C_TIMEOUT_UserCallback());
  211. }
  212. }
  213. // * While there is data to be read * /
  214. while(numByteToRead) {
  215. /* Receive bytes from first byte until byte N-3 */
  216. if (numByteToRead != 3) {
  217. /* Poll on BTF to receive data because in polling mode we can not guarantee the
  218. EV7 software sequence is managed before the current byte transfer completes */
  219. I2C_TimeOut = I2C_TIMEOUT;
  220. while ((I2C_MEMS->SR1 & 0x00004) != 0x000004)
  221. {
  222. if (I2C_TimeOut-- <= 0){
  223. return(I2C_TIMEOUT_UserCallback());
  224. }
  225. }
  226. /* Read data */
  227. *pBuffer = I2C_MEMS->DR;
  228. pBuffer++;
  229. /* Decrement the read bytes counter */
  230. numByteToRead--;
  231. }
  232. /* it remains to read three data: data N-2, data N-1, Data N */
  233. if (numByteToRead == 3) {
  234. /* Wait until BTF is set: Data N-2 in DR and data N -1 in shift register */
  235. I2C_TimeOut = I2C_TIMEOUT;
  236. while ((I2C_MEMS->SR1 & 0x00004) != 0x000004)
  237. {
  238. if (I2C_TimeOut-- <= 0){
  239. return(I2C_TIMEOUT_UserCallback());
  240. }
  241. }
  242. /* Clear ACK */
  243. I2C_MEMS->CR1 &= CR1_ACK_Reset;
  244. /* Disable IRQs around data reading and STOP programming */
  245. __disable_irq();
  246. /* Read Data N-2 */
  247. *pBuffer = I2C_MEMS->DR;
  248. /* Increment */
  249. pBuffer++;
  250. /* Program the STOP */
  251. I2C_MEMS->CR1 |= CR1_STOP_Set;
  252. /* Read DataN-1 */
  253. *pBuffer = I2C_MEMS->DR;
  254. /* Re-enable IRQs */
  255. __enable_irq();
  256. /* Increment */
  257. pBuffer++;
  258. /* Wait until RXNE is set (DR contains the last data) */
  259. I2C_TimeOut = I2C_TIMEOUT;
  260. while ((I2C_MEMS->SR1 & 0x00040) != 0x000040)
  261. {
  262. if (I2C_TimeOut-- <= 0){
  263. return(I2C_TIMEOUT_UserCallback());
  264. }
  265. }
  266. /* Read DataN */
  267. *pBuffer = I2C_MEMS->DR;
  268. /* Reset the number of bytes to be read by master */
  269. numByteToRead = 0;
  270. }
  271. }
  272. }
  273. /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
  274. I2C_TimeOut = I2C_TIMEOUT;
  275. while ((I2C_MEMS->CR1&0x200) == 0x200)
  276. {
  277. if (I2C_TimeOut-- <= 0){
  278. return(I2C_TIMEOUT_UserCallback());
  279. }
  280. }
  281. // * Enable Acknowledgement to be ready for another reception * /
  282. I2C_AcknowledgeConfig(I2C_MEMS, ENABLE);
  283. return 0;
  284. }
  285.  
  286. int I2C_Master_Write(uint8_t deviceAddress, uint8_t WriteAddr, uint8_t* pBuffer, uint16_t numByteToWrite) {
  287. volatile int I2C_TimeOut = 0;
  288. /* Send STRAT condition */
  289. I2C_GenerateSTART(I2C_MEMS, ENABLE);
  290.  
  291. /* Test on EV5 and clear it */
  292. I2C_TimeOut = I2C_TIMEOUT;
  293. while(!I2C_CheckEvent(I2C_MEMS, I2C_EVENT_MASTER_MODE_SELECT))
  294. {
  295. if (I2C_TimeOut-- <= 0){
  296. return(I2C_TIMEOUT_UserCallback());
  297. }
  298. }
  299.  
  300. /* Send EEPROM address for write */
  301. I2C_Send7bitAddress(I2C_MEMS, deviceAddress, I2C_Direction_Transmitter);
  302. /* Test on EV6 and clear it */
  303. I2C_TimeOut = I2C_TIMEOUT;
  304. while(!I2C_CheckEvent(I2C_MEMS, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  305. {
  306. if (I2C_TimeOut-- <= 0){
  307. return(I2C_TIMEOUT_UserCallback());
  308. }
  309. }
  310. /* Send the EEPROM's internal address to write to : only one byte Address */
  311. I2C_SendData(I2C_MEMS, WriteAddr);
  312. /* Test on EV8 and clear it */
  313. I2C_TimeOut = I2C_TIMEOUT;
  314. while(!I2C_CheckEvent(I2C_MEMS, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  315. {
  316. if (I2C_TimeOut-- <= 0){
  317. return(I2C_TIMEOUT_UserCallback());
  318. }
  319. }
  320. while(numByteToWrite > 0) {
  321. /* Send the byte to be written */
  322. I2C_SendData(I2C_MEMS, *pBuffer);
  323. /* Test on EV8 and clear it */
  324. I2C_TimeOut = I2C_TIMEOUT;
  325. while(!I2C_CheckEvent(I2C_MEMS, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  326. {
  327. if (I2C_TimeOut-- <= 0){
  328. return(I2C_TIMEOUT_UserCallback());
  329. }
  330. }
  331. pBuffer++;
  332. numByteToWrite--;
  333. }
  334. /* Send STOP condition */
  335. I2C_GenerateSTOP(I2C_MEMS, ENABLE);
  336. return 0;
  337. }
  338.  
  339. int I2C_TIMEOUT_UserCallback(void)
  340. {
  341. /* User can add his own implementation to manage TimeOut Communication failure */
  342. /* Block communication and all processes */
  343. I2C_Master_DeInit();
  344. for(int i=0; i<3000; i++){__asm("nop");}
  345. I2C_Master_Init();
  346. for(int i=0; i<3000; i++){__asm("nop");}
  347. return -1;
  348. }
  349.  

2016年3月1日 星期二

[Unboxing]] eMotion: ST MEMS adapters motherboard

1. 之前經常會拿到st提供的sensor board來進行相關的測試或是移植, 有時候在沒有ap或是pc端驗
   證軟體的時候, 就比較難以知道sensor是否正常動作, 因此st mems team有提供了專屬的開發板
   和pc tool來協助驗證.

2. mems motherboard如下圖所示, 編號是STEVAL-MKI109V2, 而搭配測試的sensor board編號
   是STEVAL-MKI108V2.

[將SWD拉出來]


3. 接下來將sensor board與mems motherboard相接, 基本上要測試的硬體已經準備好了.


4. 接著到ST官方網頁去下載STEVAL-MKI109V2的相關資料.

    http://www.st.com/web/en/catalog/tools/PF252688



5. 解壓縮後, 可以看到底下的相關檔案, 最重要的就是FIRMWAREUnico的執行檔.



6. 我們首先先使用IAR EWARM先開啟FIRMWARE, 並將Build好的檔案燒錄至mems
    motherboard, 這邊有一個需要特別注意的地方就是需要先將project的Workspace從
    EMOTION_DFU切換到EMOTION_FLASH, 否則一斷電後, 程式就會消失, 需要每次都
    使用ICE將程式燒錄進去.


7. 燒錄完成後, 接著就是安裝Setup_Unico_4.2.0.0.exe程式了, 完成後, pc上會產生Unico tool.


8. 接著就是透過usb cable將mems motherboard與pc相連接, 並開啟Unico tool, 若程式正常執行且
    sensor board也沒有接反的話, 則會有藍色LED亮起.


9. 開啟Unico tool後, 第一個會先要你選擇搭配的sensor board編號, 例如我們使用的為STEVAL-
    MKI108V2, 從清單列表上可以找到此顆編號, 看起來是一顆包含acc/gyro/mag sensor的9 axis
    sensor module, 最後按下Select Device.



10. 接著開始設定Unico tool, 首先先設定STM32 Virtual com-port的編號, 並按下Connect.




11. 連線成功後, 就可以開始對sensor module進行相關的設定, 如果還不熟的話, 也可以先選擇
     Easy Configuration來快速設定, 且連線成功後, mems motherboard上會多亮起3個LED.




12. 也可以直接對各個暫存器進行數值修改.


13. 當設定完成後, 接著按下Start按鈕, 便可以開始觀察數值上的變化.


14. 可以選擇各種不同的觀察資料方式, 例如可以選擇Plot等方式.


15. 這樣比看暫存器輸出的數值要方便地多了.