Statistics
| Branch: | Tag: | Revision:

amiro-os / components / ControllerAreaNetworkRx.cpp @ 3f899f5d

History | View | Annotate | Download (5.474 KB)

1 58fe0e0b Thomas Schöpping
#include <ch.hpp>
2
#include <hal.h>
3
#include <string.h>  // memcpy
4
5
#include <amiro/Constants.h>
6
#include <amiro/ControllerAreaNetworkRx.h>
7
8
using namespace chibios_rt;
9
using namespace amiro;
10
11
using namespace types;
12
using namespace amiro::constants;
13
14
ControllerAreaNetworkRx::ControllerAreaNetworkRx(CANDriver *can, const uint8_t boardId)
15
    : BaseStaticThread<128>(),
16
      boardId(boardId),
17
      canDriver(can) {
18
#ifdef STM32F4XX
19
  this->canConfig.mcr = CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP;
20
  this->canConfig.btr = CAN_BTR_SJW(1) | CAN_BTR_TS2(3) | CAN_BTR_TS1(15)
21
                        | CAN_BTR_BRP(1);
22
#else
23
  this->canConfig.mcr = CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP;
24
  this->canConfig.btr = CAN_BTR_SJW(1) | CAN_BTR_TS2(2) | CAN_BTR_TS1(13)
25
                        | CAN_BTR_BRP(1);
26
#endif
27
}
28
29
ControllerAreaNetworkRx::
30
~ControllerAreaNetworkRx() {
31
32
}
33
34
//----------------------------------------------------------------
35
36
msg_t ControllerAreaNetworkRx::receiveSensorVal(CANRxFrame *frame) {
37
  int deviceId = this->decodeDeviceId(frame);
38
39
  // chprintf((BaseSequentialStream*) &SD1, "DeviceId: %d\r\n",deviceId);
40
41
  switch (deviceId) {
42
    case CAN::PROXIMITY_RING_ID(0):
43
    case CAN::PROXIMITY_RING_ID(1):
44
    case CAN::PROXIMITY_RING_ID(2):
45
    case CAN::PROXIMITY_RING_ID(3):
46
    case CAN::PROXIMITY_RING_ID(4):
47
    case CAN::PROXIMITY_RING_ID(5):
48
    case CAN::PROXIMITY_RING_ID(6):
49
    case CAN::PROXIMITY_RING_ID(7):
50
      if (frame->DLC == 2) {
51
        int index = deviceId & 0x7;
52
        proximityRingValue[index] = frame->data16[0];
53
        return RDY_OK;
54
      }
55
      break;
56
57
    case CAN::ACTUAL_SPEED_ID:
58
      if (frame->DLC == 8) {
59
        actualSpeed[0] = frame->data32[0];
60
        actualSpeed[1] = frame->data32[1];
61
        return RDY_OK;
62
      }
63
      break;
64
65
    case CAN::ODOMETRY_ID:
66
      if (frame->DLC == 8) {
67
        this->robotPosition.x = (frame->data8[0] << 8 | frame->data8[1] << 16 | frame->data8[2] << 24);
68
        this->robotPosition.y = (frame->data8[3] << 8 | frame->data8[4] << 16 | frame->data8[5] << 24);
69
        this->robotPosition.f_z = (frame->data8[6] << 8 | frame->data8[7] << 16);
70
        return RDY_OK;
71
      }
72
      break;
73
74
    case CAN::PROXIMITY_FLOOR_ID:
75
      // chprintf((BaseSequentialStream*) &SD1, "CAN::PROXIMITY_FLOOR_ID");
76
      if (frame->DLC == 8) {
77
        proximityFloorValue[0] = frame->data16[0];
78
        proximityFloorValue[1] = frame->data16[1];
79
        proximityFloorValue[2] = frame->data16[2];
80
        proximityFloorValue[3] = frame->data16[3];
81
        return RDY_OK;
82
      }
83
      break;
84
85
    case CAN::POWER_STATUS_ID:
86
      if (frame->DLC == 6) {
87
        powerStatus.charging_flags.value = frame->data8[0];
88
        powerStatus.state_of_charge = frame->data8[1];
89
        powerStatus.minutes_remaining = frame->data16[1];
90
        powerStatus.power_consumption = frame->data16[2];
91
        return RDY_OK;
92
      }
93
      break;
94
95
    case CAN::ROBOT_ID:
96
      if (frame->DLC == 1) {
97
        robotId = frame->data8[0];
98
        return RDY_OK;
99
      }
100
      break;
101
102
    default:
103
      break;
104
  }
105
106
  return RDY_RESET;
107
}
108
109
uint16_t ControllerAreaNetworkRx::getProximityRingValue(int index) {
110
  return this->proximityRingValue[index];
111
}
112
113
void ControllerAreaNetworkRx::getActualSpeed(types::kinematic &targetSpeed) {
114
  targetSpeed.x = this->actualSpeed[0];
115
  targetSpeed.w_z = this->actualSpeed[1];
116
}
117
118
types::position ControllerAreaNetworkRx::getOdometry() {
119
  return this->robotPosition;
120
}
121
122
power_status &ControllerAreaNetworkRx::getPowerStatus() {
123
  return this->powerStatus;
124
}
125
126
uint8_t ControllerAreaNetworkRx::getRobotID() {
127
  return this->robotId;
128
}
129
130
131
uint16_t ControllerAreaNetworkRx::getProximityFloorValue(int index) {
132
  return this->proximityFloorValue[index];
133
}
134
135
//----------------------------------------------------------------
136
137
msg_t ControllerAreaNetworkRx::main(void) {
138
139
  this->rxFullCanEvtSource = reinterpret_cast<EvtSource *>(&this->canDriver->rxfull_event);
140
141
  this->rxFullCanEvtSource->registerOne(&this->rxFullCanEvtListener, CAN::RECEIVED_ID);
142
143
  canStart(this->canDriver, &this->canConfig);
144
145
  this->setName("ControllerAreaNetworkRx");
146
147
  while (!this->shouldTerminate()) {
148
    eventmask_t eventMask = this->waitOneEventTimeout(ALL_EVENTS, MS2ST(10000));
149
    switch (eventMask) {
150
151
      case EVENT_MASK(CAN::RECEIVED_ID):
152
        CANRxFrame rxframe;
153
        msg_t message = canReceive(this->canDriver, CAN_ANY_MAILBOX, &rxframe, TIME_IMMEDIATE);
154
        if (message == RDY_OK) {
155
          // chprintf((BaseSequentialStream*) &SD1, "Rx Message");
156
          message = this->receiveMessage(&rxframe);
157
          if (message != RDY_OK)
158
            this->receiveSensorVal(&rxframe);
159
        }
160
        break;
161
    }
162
  }
163
164
  canStop(this->canDriver);
165
  this->rxFullCanEvtSource->unregister(&this->rxFullCanEvtListener);
166
167
  return RDY_OK;
168
}
169
170
msg_t ControllerAreaNetworkRx::receiveMessage(CANRxFrame *frame) {
171
  (void)frame;
172
  return RDY_OK;
173
}
174
175
//----------------------------------------------------------------
176
177
int ControllerAreaNetworkRx::decodeBoardId(CANRxFrame *frame) {
178
  return (frame->SID >> CAN::BOARD_ID_SHIFT) & CAN::BOARD_ID_MASK;
179
}
180
181
int ControllerAreaNetworkRx::decodeDeviceId(CANRxFrame *frame) {
182
  return (frame->SID >> CAN::DEVICE_ID_SHIFT) & CAN::DEVICE_ID_MASK;
183
}
184
185
int ControllerAreaNetworkRx::decodeIndexId(CANRxFrame *frame) {
186
  return (frame->SID >> CAN::INDEX_ID_SHIFT) & CAN::INDEX_ID_MASK;
187
}
188
189
//----------------------------------------------------------------
190
191
int ControllerAreaNetworkRx::rxCmdShell(CANRxFrame *frame) {
192
  return (frame->SID >> CAN::BOARD_ID_SHIFT) & CAN::BOARD_ID_MASK;
193
}