diff --git a/CMakeLists.txt b/CMakeLists.txt index 4df2e09419a93d1a797f9f094a98c6c3e0c0301a..c7c74ae2dea01fdf9b725f65b7dcb8e1f3feb510 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ add_executable(test-sensormanager src/tests/test-sensormanager.cpp) sbs_target(test-sensormanager stm32f429zi_skyward_death_stack_x) add_executable(test-serial src/tests/test-serial.cpp) -sbs_target(test-serial stm32f407vg_stm32f4discovery) +sbs_target(test-serial stm32f429zi_stm32f4discovery) add_executable(test-taskscheduler src/tests/scheduler/test-taskscheduler.cpp) sbs_target(test-taskscheduler stm32f407vg_stm32f4discovery) diff --git a/src/shared/drivers/canbus/CanProtocol.h b/src/shared/drivers/canbus/CanProtocol.h index cf78a0c341fd185d846b8fc077c48e8d1497552d..ae2384a0bc15a1bdc64ec462a05b755b7f755c4f 100644 --- a/src/shared/drivers/canbus/CanProtocol.h +++ b/src/shared/drivers/canbus/CanProtocol.h @@ -56,8 +56,8 @@ namespace Canbus */ struct CanData { - uint32_t canId = - 0; // the id of the can packet without the last 7 bits (sequence bit) + int32_t canId = + -1; // the id of the can packet without the last 7 bits (sequence bit) uint8_t len; uint8_t nRec = 0; uint64_t payload[32]; @@ -88,25 +88,34 @@ public: getPacket() // return the packet, if buffer is empty return an empty packet { CanData temp; - mutex.lock(); + miosix::Lock<miosix::FastMutex> l(mutex); if (!buffer.isEmpty()) { temp = buffer.pop(); } - mutex.unlock(); return temp; } bool isEmpty() { - mutex.lock(); + miosix::Lock<miosix::FastMutex> l(mutex); return buffer.isEmpty(); - mutex.unlock(); } void waitEmpty() { buffer.waitUntilNotEmpty(); } + uint8_t byteForInt(uint64_t number) + { + uint8_t i; + for (i = 1; i <= 8; i++) + { + number = number >> 8; + if (number == 0) + return i; + } + return i; + } /** * @brief Takes a canData, it splits it into single canpacket with the * correct sequential id @@ -116,33 +125,28 @@ public: void sendCan(CanData toSend) //@requires toSen to not be empty { CanPacket packet; - uint32_t tempLen = toSend.len - 1; - uint32_t tempId = toSend.canId; - packet.ext = true; - packet.id = - (tempId << 7) | idMask.firstPacket | (tempLen & idMask.leftToSend); - packet.length = (toSend.payload[0] + 8) / - 8; // simple formula for upper approximation + uint8_t tempLen = toSend.len - 1; + uint32_t tempId = toSend.canId; + packet.ext = true; + packet.id = (tempId << 7) | idMask.firstPacket | + (63 - (tempLen & idMask.leftToSend)); + packet.length = byteForInt(toSend.payload[0]); for (int k = 0; k < packet.length; k++) { packet.data[k] = toSend.payload[0] >> (8 * k); } tempLen--; - can->send(packet); - TRACE("tosend len %d\n", toSend.len); - for (int i = 1; i < toSend.len; i++) { tempId = toSend.canId; packet.id = (tempId << 7) | !(idMask.firstPacket) | - (tempLen & idMask.leftToSend); - packet.length = (toSend.payload[i] + 8) / 8; + (63 - (tempLen & idMask.leftToSend)); + packet.length = byteForInt(toSend.payload[i]); for (int k = 0; k < packet.length; k++) { - packet.data[k] = toSend.payload[i] << (8 * k); + packet.data[k] = toSend.payload[i] >> (8 * k); } - TRACE("packetlen %d\n, dato %d\n", packet.length, packet.data[0]); can->send(packet); tempLen--; } @@ -168,49 +172,60 @@ protected: if (!can->getRXBuffer().isEmpty()) { - packet = can->getRXBuffer().pop().packet; - - sourceId = packet.id & idMask.source; - if (data[sourceId].canId == 0 || - (data[sourceId].canId & idMask.source) == sourceId) + packet = can->getRXBuffer().pop().packet; + sourceId = (packet.id & idMask.source) >> 15; + if (sourceId >= 0 && + sourceId < NPACKET) // check for maximum size { - if (packet.id & idMask.firstPacket) // it is a first - // packet of a data; - { - data[sourceId].len = - (packet.id & idMask.leftToSend) + 1; - data[sourceId].canId = - packet.id >> 7; // discard the sequence number - } - TRACE("pakcet %d, nrec %d, left %lu\n", packet.data[0], - data[sourceId].nRec, (packet.id & idMask.leftToSend)); - if ((data[sourceId].len - (data[sourceId].nRec + 1)) == - (packet.id & idMask.leftToSend)) + if (data[sourceId].canId == -1 || + (((data[sourceId].canId << 7) & idMask.source) >> 15) == + sourceId) { + uint32_t leftToSend = + 63 - (packet.id & idMask.leftToSend); - uint64_t tempPayload = 0; - for (int f = 0; f < packet.length; f++) + if ((packet.id & idMask.firstPacket) >> + 6) // it is a first + // packet of a data; { - uint64_t tempData = packet.data[f]; - tempPayload = tempPayload | (tempData << (f * 8)); + + data[sourceId].len = leftToSend + 1; + data[sourceId].canId = + packet.id >> 7; // discard the sequence number } + if ((data[sourceId].len - (data[sourceId].nRec + 1)) == + leftToSend) + { - data[sourceId] - .payload[data[sourceId].len - - (packet.id & idMask.leftToSend) - 1] = - tempPayload; - data[sourceId].nRec++; - } + uint64_t tempPayload = 0; + for (int f = 0; f < packet.length; f++) + { + uint64_t tempData = packet.data[f]; + tempPayload = + tempPayload | (tempData << (f * 8)); + } + if (data[sourceId].len - leftToSend - 1 >= 0 && + data[sourceId].len - leftToSend - 1 < + 32) // check for index + { + + data[sourceId].payload[data[sourceId].len - + leftToSend - 1] = + tempPayload; + data[sourceId].nRec++; + } + } - if (data[sourceId].nRec == data[sourceId].len) - { - mutex.lock(); - buffer.put(data[sourceId]); - // empties the struct - data[sourceId].canId = 0; - data[sourceId].nRec = 0; - data[sourceId].len = 0; - mutex.unlock(); + if (data[sourceId].nRec == data[sourceId].len && + data[sourceId].nRec != 0) + { + miosix::Lock<miosix::FastMutex> l(mutex); + buffer.put(data[sourceId]); + // empties the struct + data[sourceId].canId = -1; + data[sourceId].nRec = 0; + data[sourceId].len = 0; + } } } } diff --git a/src/shared/drivers/canbus/Canbus.h b/src/shared/drivers/canbus/Canbus.h index 96a686b9206069d6fac893ef38efb5c643769acb..b841096f29ade3f3ec47fb8af18198709075e4bf 100644 --- a/src/shared/drivers/canbus/Canbus.h +++ b/src/shared/drivers/canbus/Canbus.h @@ -64,13 +64,13 @@ public: uint8_t awum = 1; // Automatic wakeup (1: automatic wakeup upon new // message received) uint8_t nart = - 0; // No auto retransmission (0: packets are retrasmitted until + 0; // No auto retransmission (0: packets are retransmitted until // success, 1: only one transfer attempt) uint8_t abom = 1; // Automatic bus off management (1: automatically // recovers from bus-off state) uint8_t rflm = 1; // Receive fifo locked (0: new messages overwrite // last ones, 1: new message discarded) - uint8_t txfp = 0; // TX Fifo priority (0: identifier, 1: chronological) + uint8_t txfp = 1; // TX Fifo priority (0: identifier, 1: chronological) }; /** diff --git a/src/tests/drivers/canbus/test-can-protocol.cpp b/src/tests/drivers/canbus/test-can-protocol.cpp index e2126819497d35abdf939256d70a0e4bd8fb3caf..9f8eef1ed68be96fccad479a789df19a701d2ba5 100644 --- a/src/tests/drivers/canbus/test-can-protocol.cpp +++ b/src/tests/drivers/canbus/test-can-protocol.cpp @@ -23,7 +23,6 @@ */ #include <drivers/canbus/CanProtocol.h> -#include <inttypes.h> #include <thread> @@ -49,21 +48,39 @@ using CanRX = Gpio<GPIOA_BASE, 11>; using CanTX = Gpio<GPIOA_BASE, 12>; #endif -#define SLP 5000 - -void sendData(CanProtocol* protocol, CanData toSend) +#define SLP 100 +miosix::FastMutex mutex; +CanData toSend1; +CanData toSend2; +void sendData(CanProtocol* protocol, CanData* toSend) { while (true) { + TRACE("send\n"); - (*protocol).sendCan(toSend); + { + miosix::Lock<miosix::FastMutex> l(mutex); + (*protocol).sendCan(*toSend); + } Thread::sleep(SLP); } } +bool equal(CanData* first, CanData* second) +{ + if ((*first).canId != (*second).canId || (*first).len != (*second).len) + { + return false; + } + for (int i = 0; i < (*first).len; i++) + { + if ((*first).payload[i] != (*second).payload[i]) + return false; + } + return true; +} int main() { - { miosix::FastInterruptDisableLock dLock; @@ -78,12 +95,10 @@ int main() CanTX::alternateFunction(9); #endif } - CanbusDriver::CanbusConfig cfg{}; CanbusDriver::AutoBitTiming bt; - bt.baudRate = BAUD_RATE; - bt.samplePoint = SAMPLE_POINT; - + bt.baudRate = BAUD_RATE; + bt.samplePoint = SAMPLE_POINT; CanbusDriver* c = new CanbusDriver(CAN1, cfg, bt); CanProtocol protocol(c); // Allow every message @@ -92,40 +107,47 @@ int main() c->addFilter(f2); c->init(); protocol.start(); - CanData toSend; - toSend.canId = 0x01; - toSend.len = 3; - toSend.payload[0] = 1; - toSend.payload[1] = 2; - toSend.payload[2] = 3; - std::thread second(sendData, &protocol, toSend); + + toSend1.canId = 0x200; + toSend1.len = 8; + toSend1.payload[0] = 0xffffffffffffffff; + toSend1.payload[1] = 2; + toSend1.payload[2] = 78022; + toSend1.payload[3] = 0xfffffffffffff; + toSend1.payload[4] = 23; + toSend1.payload[5] = 3234; + toSend1.payload[6] = 12; + toSend1.payload[7] = 0; + std::thread firstSend(sendData, &protocol, &toSend1); + + Thread::sleep(10); + toSend2.canId = 0x100; + toSend2.len = 4; + toSend2.payload[0] = 0xffffff; + toSend2.payload[1] = 2; + toSend2.payload[2] = 0x123ff; + toSend2.payload[3] = 1; + std::thread secondSend(sendData, &protocol, &toSend2); + TRACE("start \n"); for (;;) { - TRACE("start \n"); + protocol.waitEmpty(); CanData temp = protocol.getPacket(); - if (temp.canId != toSend.canId || temp.len != toSend.len || - temp.payload[0] != toSend.payload[0] || - temp.payload[1] != toSend.payload[1] || - temp.payload[2] != toSend.payload[2]) + TRACE("received packet \n"); + if ((!equal(&temp, &toSend1) && !equal(&temp, &toSend2))) { TRACE("Error\n"); - TRACE("Expected id %lu, received %lu\n", toSend.canId, temp.canId); - TRACE("Expected len %d , received %d\n", toSend.len, temp.len); - TRACE( - "Expected payload 0 %llu , received " - "%llu\n", - toSend.payload[0], temp.payload[0]); - TRACE("Expected payload 1 %llu, received %llu\n", - toSend.payload[1], temp.payload[1]); - TRACE( - "Expected payload 2 %llu, received " - "%llu\n", - toSend.payload[2], temp.payload[2]); + TRACE("Received %lu\n", temp.canId); + TRACE("Received %d\n", temp.len); + for (int i = 0; i < temp.len; i++) + { + TRACE("Received payload %d: %llu,\n", i, temp.payload[i]); + } } else { - TRACE("OK :)\n"); + TRACE("OK :) id %lu\n", temp.canId); } } }