blob: 18cd24b8a30c3f0340081db86e63635b2e7d183a [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
2
3#include "ctre/CtreCanNode.h"
4#include "FRC_NetworkCommunication/CANSessionMux.h"
5#include <string.h> // memset
6#include <unistd.h> // usleep
7
8static const UINT32 kFullMessageIDMask = 0x1fffffff;
9
10CtreCanNode::CtreCanNode(UINT8 deviceNumber)
11{
12 _deviceNumber = deviceNumber;
13}
14CtreCanNode::~CtreCanNode()
15{
16}
17void CtreCanNode::RegisterRx(uint32_t arbId)
18{
19 /* no need to do anything, we just use new API to poll last received message */
20}
21void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
22{
23 int32_t status = 0;
24
25 txJob_t job = {0};
26 job.arbId = arbId;
27 job.periodMs = periodMs;
28 _txJobs[arbId] = job;
29 FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
30 job.toSend,
31 8,
32 job.periodMs,
33 &status);
34}
35timespec diff(const timespec & start, const timespec & end)
36{
37 timespec temp;
38 if ((end.tv_nsec-start.tv_nsec)<0) {
39 temp.tv_sec = end.tv_sec-start.tv_sec-1;
40 temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
41 } else {
42 temp.tv_sec = end.tv_sec-start.tv_sec;
43 temp.tv_nsec = end.tv_nsec-start.tv_nsec;
44 }
45 return temp;
46}
47CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
48{
49 CTR_Code retval = CTR_OKAY;
50 int32_t status = 0;
51 uint8_t len = 0;
52 uint32_t timeStamp;
53 /* cap timeout at 999ms */
54 if(timeoutMs > 999)
55 timeoutMs = 999;
56 FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
57 if(status == 0){
58 /* fresh update */
59 rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
60 clock_gettime(2,&r.time); /* fill in time */
61 memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
62 }else{
63 /* did not get the message */
64 rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
65 if(i == _rxRxEvents.end()){
66 /* we've never gotten this mesage */
67 retval = CTR_RxTimeout;
68 /* fill caller's buffer with zeros */
69 memset(dataBytes,0,8);
70 }else{
71 /* we've gotten this message before but not recently */
72 memcpy(dataBytes,i->second.bytes,8);
73 /* get the time now */
74 struct timespec temp;
75 clock_gettime(2,&temp); /* get now */
76 /* how long has it been? */
77 temp = diff(i->second.time,temp); /* temp = now - last */
78 if(temp.tv_sec > 0){
79 retval = CTR_RxTimeout;
80 }else if(temp.tv_nsec > ((int32_t)timeoutMs*1000*1000)){
81 retval = CTR_RxTimeout;
82 }else {
83 /* our last update was recent enough */
84 }
85 }
86 }
87
88 return retval;
89}
90void CtreCanNode::FlushTx(uint32_t arbId)
91{
92 int32_t status = 0;
93 txJobs_t::iterator iter = _txJobs.find(arbId);
94 if(iter != _txJobs.end())
95 FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
96 iter->second.toSend,
97 8,
98 iter->second.periodMs,
99 &status);
100}
101