NodeLinkMaster.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #include "nodelinkmaster.h"
  2. #include "NodeLinkCommon.h"
  3. #include "encrypt_xxtea.h"
  4. #include <string.h>
  5. #include <stdint.h>
  6. #include "stm32f10x.h"
  7. #include "core_cm3.h"
  8. #include "board.h"
  9. /**
  10. * 超时处理
  11. *
  12. * @author lxz (042620 16:02:40)
  13. *
  14. * @param device
  15. */
  16. static void deivce0_on_timeout(struct nodelink_device *device) {
  17. }
  18. /**
  19. * 接收事件处理
  20. *
  21. * @author lxz (042620 16:02:58)
  22. *
  23. * @param device
  24. * @param data
  25. */
  26. static void device0_on_recv(struct nodelink_device *device, unsigned char *data) {
  27. }
  28. /**
  29. * 发送事件
  30. *
  31. * @author lxz (042620 16:03:17)
  32. *
  33. * @param device
  34. * @param data
  35. * @param len
  36. */
  37. static int device0_on_send(struct nodelink_device *device, unsigned char *data) {
  38. return 0;
  39. }
  40. static nodelink_device_ops device0 = {
  41. device0_on_recv,
  42. device0_on_send,
  43. deivce0_on_timeout
  44. };
  45. /**
  46. * 执行主站初始化
  47. *
  48. * @author LXZ (070720)
  49. *
  50. * @param master
  51. */
  52. void nodelink_master_init(nodelink_master_t *master) {
  53. unsigned char code[16];
  54. unsigned char i;
  55. unsigned long cDelay=1000000;
  56. //产生主站随机code,这里使用定时器最后8位,
  57. //由于晶振细微差异,可以保证每次上电不同
  58. for(i=0;i<16;i++)
  59. {
  60. while(cDelay--);
  61. code[i]=(unsigned char)(SysTick->VAL & 0xff);
  62. cDelay=1000000;
  63. }
  64. //清空内存
  65. memset(master, 0, sizeof(nodelink_master_t));
  66. master->device[0].ops = &device0;
  67. //设置code
  68. nodelink_master_set_code(master,code);
  69. //设置开始扫描从站
  70. nodelink_master_reset(master);
  71. }
  72. /**
  73. * 通过ID查找设备
  74. *
  75. * @author LXZ (070720)
  76. *
  77. * @param master
  78. */
  79. unsigned char nodelink_find_device_by_ID(nodelink_master_t *master,unsigned char id) {
  80. int i;
  81. for(i=1;i<=master->dev_count;i++)
  82. {
  83. if(master->device[i].id == id) return i;
  84. }
  85. return 0;
  86. }
  87. /**
  88. * 执行主站的接收动作
  89. *
  90. * @author lxz (041820 16:51:42)
  91. *
  92. * @param master 主站对象
  93. * @param src 接收缓冲
  94. * @param len 接收长度
  95. *
  96. */
  97. void nodelink_master_recv(nodelink_master_t *master,
  98. unsigned char *src,
  99. int len) {
  100. int i = 0;
  101. unsigned char id;
  102. unsigned long length;
  103. length = nodelink_decode(&(master->data_in[0]), src, len);
  104. if (length > 0) {
  105. //分配ID过程中
  106. if (master->bus_status == 0xF0)
  107. {
  108. if (master->step == 0)//发送了KEY,接收返回信息
  109. {
  110. if(master->data_in[1]==0xA0)//数据帧类型
  111. {
  112. if (memcmp(&(master->data_in[2]), master->code, 16) == 0) //判断设备合法性
  113. {
  114. master->step=1;
  115. master->count = 5;
  116. }
  117. }
  118. }
  119. else if(master->step == 1)//Key验证通过,接收物理ID
  120. {
  121. if(master->data_in[1]==0xA1)//数据帧类型
  122. {
  123. for(i=length-3;i>=2;i-=3)//从队尾(靠近主站的板卡)开始添加设备
  124. {
  125. master->dev_count++;
  126. master->count = 5;
  127. master->device[master->dev_count].id = master->data_in[i];
  128. master->device[master->dev_count].uniqueid = master->data_in[i+1];
  129. master->device[master->dev_count].model = master->data_in[i+2];
  130. if (master->callback != 0) {
  131. master->callback(master,NL_MASTER_EVENT_FOUND_DEVICE, &master->device[master->dev_count]);
  132. }
  133. }
  134. }
  135. if(master->dev_count>0)
  136. {
  137. master->step = 2;//主板通知配置完成
  138. master->count=100;
  139. }
  140. }
  141. }
  142. //正常通信模式
  143. else if(master->bus_status == 0xF1)
  144. {
  145. if(master->data_in[1]==0xA3)//数据帧类型
  146. {
  147. id = nodelink_find_device_by_ID(master,master->data_in[0]);
  148. if(id>0)
  149. {
  150. if (master->device[id].ops != 0)
  151. master->device[id].ops->on_recv(&master->device[id], &(master->data_in[0]));
  152. }
  153. }
  154. }
  155. }
  156. }
  157. /**
  158. *
  159. *
  160. * @author lxz (042620 16:49:13)
  161. *
  162. * @param master
  163. */
  164. void nodelink_master_reset(nodelink_master_t *master) {
  165. master->bus_status = 0xFF;
  166. master->step = 0;
  167. master->count = 500;
  168. }
  169. /**
  170. *
  171. *
  172. * @author lxz (042620 16:49:17)
  173. *
  174. * @param master
  175. */
  176. void nodelink_master_begin_scan(nodelink_master_t *master) {
  177. master->bus_status = 0xF0;
  178. master->step = 0;
  179. master->dev_count = 0;
  180. master->count = 100;
  181. memset(&master->device[0],0,sizeof(master->device));
  182. }
  183. /**
  184. * 进入工作模式
  185. *
  186. * @author LXZ (070720)
  187. *
  188. * @param master
  189. */
  190. void nodelink_master_begin_working(nodelink_master_t *master) {
  191. master->bus_status = 0xF1;
  192. master->step = 0;
  193. master->count = 5;
  194. }
  195. /**
  196. * 注册16字节识别码
  197. *
  198. * @author LXZ (070720)
  199. *
  200. * @param master
  201. * @param code
  202. */
  203. void nodelink_master_set_code(nodelink_master_t * master, unsigned char * code)
  204. {
  205. memcpy(master->code,code,16);
  206. }
  207. /**
  208. * 注册回调事件
  209. *
  210. * @author LXZ (070720)
  211. *
  212. * @param master
  213. */
  214. void nodelink_master_set_callback(nodelink_master_t * master,
  215. void(*callback)(nodelink_master_t * master, char , void *))
  216. {
  217. master->callback = callback;
  218. }
  219. /**
  220. * 执行主站输入输出处理
  221. *
  222. * @author lxz (041820 16:20:35)
  223. *
  224. * @param master 主站对象
  225. * @param dst 目标缓冲
  226. * @param src 当前缓冲
  227. * @param len 长度
  228. */
  229. int nodelink_master_send(nodelink_master_t *master,
  230. unsigned char *dst) {
  231. int res = 0;
  232. int length = 0;
  233. uint32_t key[4] = { 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF };
  234. uint32_t code[4];
  235. //static uint8_t k;
  236. static unsigned char curDevice;
  237. if (master->bus_status == 0xFF) {
  238. //复位总线,发送指定个数的包
  239. if (master->count > 0) {
  240. master->data_out[0] = 0x80;//广播ID
  241. master->data_out[1] = 0xAA;//复位命令
  242. length = nodelink_encode(&dst[0], &(master->data_out[0]), 2);
  243. res = length;
  244. master->count--;
  245. }
  246. else {
  247. //进入配置ID模式
  248. nodelink_master_begin_scan(master);
  249. }
  250. }
  251. else if (master->bus_status == 0xF0) {
  252. //定向分配ID
  253. switch (master->step) {
  254. case 0:
  255. //需要先执行设置设备进入ID配置模式
  256. //if (master->count > 0) {
  257. code[0] = (master->code[0]) | (master->code[1] << 8) | (master->code[2] << 16) | (master->code[3] << 24);
  258. code[1] = (master->code[4]) | (master->code[5] << 8) | (master->code[6] << 16) | (master->code[7] << 24);
  259. code[2] = (master->code[8]) | (master->code[9] << 8) | (master->code[10] << 16) | (master->code[11] << 24);
  260. code[3] = (master->code[12]) | (master->code[13] << 8) | (master->code[14] << 16) | (master->code[15] << 24);
  261. xxtea_uint_encrypt(code, 4, key);
  262. master->data_out[0] = 0x80;//广播ID
  263. master->data_out[1] = 0xA0;//验证CODE命令
  264. //master->data_out[1] = k++;//验证CODE命令
  265. memcpy(&master->data_out[2], code, 16);
  266. res = nodelink_encode(dst, &(master->data_out[0]), 18);
  267. //master->count--;
  268. //}
  269. break;
  270. case 1:
  271. //key[4] = { 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF };
  272. //uint32_t code[4];
  273. code[0] = (master->code[0]) | (master->code[1] << 8) | (master->code[2] << 16) | (master->code[3] << 24);
  274. code[1] = (master->code[4]) | (master->code[5] << 8) | (master->code[6] << 16) | (master->code[7] << 24);
  275. code[2] = (master->code[8]) | (master->code[9] << 8) | (master->code[10] << 16) | (master->code[11] << 24);
  276. code[3] = (master->code[12]) | (master->code[13] << 8) | (master->code[14] << 16) | (master->code[15] << 24);
  277. xxtea_uint_encrypt(code, 4, key);
  278. master->data_out[0] = 0x80;//广播ID
  279. master->data_out[1] = 0xA0;//验证CODE命令
  280. //master->data_out[1] = k++;//验证CODE命令
  281. memcpy(&master->data_out[2], code, 16);
  282. res = nodelink_encode(dst, &(master->data_out[0]), 18);
  283. //master->count--;
  284. //等待接收物理ID,无须发送
  285. curDevice=1;
  286. break;
  287. case 2:
  288. //配置成功通知
  289. if (master->count > 0) {
  290. master->data_out[0] = master->device[curDevice].id;
  291. master->data_out[1] = 0xA2;//通知命令
  292. master->data_out[2] = master->device[curDevice].uniqueid;//发送唯一码
  293. res = nodelink_encode(dst, &(master->data_out[0]), 3);
  294. master->count--;
  295. }
  296. else
  297. {
  298. if(curDevice<master->dev_count)
  299. {
  300. curDevice++;
  301. master->count=100;
  302. }
  303. else
  304. {
  305. curDevice=1;
  306. master->count = 0;
  307. //进入工作模式
  308. nodelink_master_begin_working(master);
  309. }
  310. }
  311. break;
  312. }
  313. }
  314. else if (master->bus_status == 0xF1) {
  315. //执行周期数据
  316. if(curDevice<master->dev_count)
  317. {
  318. curDevice++;
  319. }
  320. else
  321. {
  322. curDevice=1;
  323. }
  324. //让设备执行输入
  325. if (master->device[curDevice].ops != 0) {
  326. length = master->device[curDevice].ops->on_send(&master->device[curDevice], &(master->data_out[0]));
  327. if (length > 0) {
  328. length = nodelink_encode(&dst[0], &(master->data_out[0]), length);
  329. res = length;
  330. master->device[curDevice].txcount++;
  331. }
  332. }
  333. }
  334. return res;
  335. }