Compare commits
2 Commits
256499f7b4
...
3dd654bdda
| Author | SHA1 | Date | |
|---|---|---|---|
| 3dd654bdda | |||
| 802b85ae5c |
@ -10,10 +10,10 @@
|
|||||||
|
|
||||||
#include <arm_acle.h>
|
#include <arm_acle.h>
|
||||||
|
|
||||||
//#define BASE_SWAP32(value) __builtin_bswap32(value)
|
#define BASE_SWAP32(value) __builtin_bswap32(value)
|
||||||
#define BASE_SWAP32(value) __rev(value)
|
//#define BASE_SWAP32(value) __rev(value)
|
||||||
|
|
||||||
//#define BASE_SWAP16(value) (uint16_t)__builtin_bswap16(value)
|
#define BASE_SWAP16(value) (uint16_t)__builtin_bswap16(value)
|
||||||
#define BASE_SWAP16(value) (uint16_t)__rev16(value)
|
//#define BASE_SWAP16(value) (uint16_t)__rev16(value)
|
||||||
|
|
||||||
#endif /* FREE_RTOS_BASE_SWAP_H_ */
|
#endif /* FREE_RTOS_BASE_SWAP_H_ */
|
||||||
|
|||||||
@ -98,6 +98,34 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EtherCAT Command
|
||||||
|
*
|
||||||
|
* Типы параметров шаблона должны быть struct Type и struct Dir или их синонимы
|
||||||
|
*
|
||||||
|
* Возможные значения первого параметра шаблона (синонимы):
|
||||||
|
*
|
||||||
|
* EcatCommand< AP, ... >
|
||||||
|
* EcatCommand< B, ... >
|
||||||
|
* EcatCommand< FP, ... >
|
||||||
|
* EcatCommand< L, ... >
|
||||||
|
*
|
||||||
|
* Возможные значения второго параметра шаблона (синонимы):
|
||||||
|
*
|
||||||
|
* EcatCommand< ... ,RD >
|
||||||
|
* EcatCommand< ... ,WR >
|
||||||
|
* EcatCommand< ... ,RW >
|
||||||
|
* EcatCommand< ... ,RMW >
|
||||||
|
* EcatCommand< ... ,NO >
|
||||||
|
*
|
||||||
|
* Так же можно использовать готовые синонимы EcatCommand<>:
|
||||||
|
*
|
||||||
|
* APRD, APWR, APRW, ARMW
|
||||||
|
* BRD, BWR, BRW, NOP
|
||||||
|
* FPRD, FPWR, FPRW, FRMW
|
||||||
|
* LRD, LWR, LRW, NOP
|
||||||
|
*
|
||||||
|
*/
|
||||||
template<typename TypeT, typename DirT>
|
template<typename TypeT, typename DirT>
|
||||||
class EcatCommand : public EcatCommandBase {
|
class EcatCommand : public EcatCommandBase {
|
||||||
static_assert(std::is_base_of<TypeBase, TypeT>::value == true, "TypeT should be derived from command::TypeBase");
|
static_assert(std::is_base_of<TypeBase, TypeT>::value == true, "TypeT should be derived from command::TypeBase");
|
||||||
|
|||||||
@ -110,6 +110,29 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EtherCAT Datagram
|
||||||
|
*
|
||||||
|
* Первый параметр шаблона должен быть class EcatCommand
|
||||||
|
*
|
||||||
|
* Возможные значения первого параметра шаблона:
|
||||||
|
*
|
||||||
|
* EcatDatagram< BWR, DataType >
|
||||||
|
* или
|
||||||
|
* EcatDatagram< EcatCommand< B, WR >, DataType >
|
||||||
|
*
|
||||||
|
* EcatDatagram< LWR, DataType >
|
||||||
|
* или
|
||||||
|
* EcatDatagram< EcatCommand< L, WR >, DataType >
|
||||||
|
*
|
||||||
|
* Пример:
|
||||||
|
*
|
||||||
|
* datagram::EcatDatagram<command::BWR, DataType > a{ {{broadcast, address}}, expected_wkc, data };
|
||||||
|
* datagram::EcatDatagram<command::LWR, DataType > b{ {{logic, address}}, expected_wkc, data };
|
||||||
|
*
|
||||||
|
* auto queue = a + b;
|
||||||
|
*
|
||||||
|
*/
|
||||||
template<typename CommandT, typename... DataTypes>
|
template<typename CommandT, typename... DataTypes>
|
||||||
class EcatDatagram : public IEcatDatagram {
|
class EcatDatagram : public IEcatDatagram {
|
||||||
static_assert(std::is_base_of<command::EcatCommandBase, CommandT>::value == true, "CommandT should be derived from ECatCommandBase");
|
static_assert(std::is_base_of<command::EcatCommandBase, CommandT>::value == true, "CommandT should be derived from ECatCommandBase");
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "free_rtos/base/swap.h"
|
#include "free_rtos/base/swap.h"
|
||||||
|
|
||||||
#include <arm_acle.h>
|
#include <arm_acle.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
uint16_t eth_calcChksum(uint32_t sum, uint8_t * const data, uint16_t len)
|
uint16_t eth_calcChksum(uint32_t sum, uint8_t * const data, uint16_t len)
|
||||||
{
|
{
|
||||||
@ -56,69 +57,60 @@ uint16_t eth_calcChksum2(uint32_t sum, uint8_t * const hdata, uint16_t hlen, uin
|
|||||||
return ~sum;
|
return ~sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
union PointerConverter
|
|
||||||
{
|
|
||||||
void * unknown;
|
|
||||||
uint64_t * octet;
|
|
||||||
uint32_t * quartet;
|
|
||||||
uint16_t * duet;
|
|
||||||
uint8_t * solo;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Array {
|
|
||||||
uint16_t duet0;
|
|
||||||
uint16_t duet1;
|
|
||||||
uint16_t duet2;
|
|
||||||
uint16_t duet3;
|
|
||||||
};
|
|
||||||
|
|
||||||
union ValueConverter
|
|
||||||
{
|
|
||||||
uint64_t octet;
|
|
||||||
uint32_t quartet;
|
|
||||||
uint16_t duet;
|
|
||||||
uint8_t solo;
|
|
||||||
struct Array array;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t calcSum(void * const buffer, uint32_t sum, void * const data, uint16_t len)
|
uint32_t calcSum(void * const buffer, uint32_t sum, void * const data, uint16_t len)
|
||||||
{
|
{
|
||||||
union PointerConverter buffer_start;
|
uint8_t* buffer_start;
|
||||||
union PointerConverter data_start;
|
uint8_t* data_start;
|
||||||
union ValueConverter value;
|
uint32_t value;
|
||||||
|
|
||||||
buffer_start.unknown = buffer;
|
buffer_start = (uint8_t*)buffer;
|
||||||
data_start.unknown = data;
|
data_start = (uint8_t*)data;
|
||||||
|
value = 0x00000000;
|
||||||
|
|
||||||
while(len >= sizeof(uint32_t)) {
|
#define SIZE sizeof(uint32_t)
|
||||||
len -= sizeof(uint32_t);
|
while(len >= SIZE) {
|
||||||
|
len -= SIZE;
|
||||||
|
|
||||||
value.quartet = *data_start.quartet++;
|
memcpy(&value, data_start, SIZE);
|
||||||
*buffer_start.quartet++ = value.quartet;
|
data_start += SIZE;
|
||||||
|
|
||||||
value.quartet = __rev16(value.quartet);
|
memcpy(buffer_start, &value, SIZE);
|
||||||
sum += value.array.duet0 + value.array.duet1;
|
buffer_start += SIZE;
|
||||||
|
|
||||||
|
value = __rev16(value);
|
||||||
|
sum += (value&0xFFFF) + (value>>16);
|
||||||
}
|
}
|
||||||
|
#undef SIZE
|
||||||
|
|
||||||
if(len >= sizeof(uint16_t)) {
|
#define SIZE sizeof(uint16_t)
|
||||||
len -= sizeof(uint16_t);
|
if(len >= SIZE) {
|
||||||
|
len -= SIZE;
|
||||||
|
value = 0x00000000;
|
||||||
|
|
||||||
value.duet = *data_start.duet++;
|
memcpy(&value, data_start, SIZE);
|
||||||
*buffer_start.duet++ = value.duet;
|
data_start += SIZE;
|
||||||
|
|
||||||
value.quartet = __rev16(value.quartet);
|
memcpy(buffer_start, &value, SIZE);
|
||||||
sum += value.duet;
|
buffer_start += SIZE;
|
||||||
|
|
||||||
|
sum += __rev16(value);
|
||||||
}
|
}
|
||||||
|
#undef SIZE
|
||||||
|
|
||||||
if(len >= sizeof(uint8_t)) {
|
#define SIZE sizeof(uint8_t)
|
||||||
len -= sizeof(uint8_t);
|
if(len >= SIZE) {
|
||||||
|
len -= SIZE;
|
||||||
|
value = 0x00000000;
|
||||||
|
|
||||||
value.solo = *data_start.solo++;
|
memcpy(&value, data_start, SIZE);
|
||||||
*buffer_start.solo++ = value.solo;
|
data_start += SIZE;
|
||||||
|
|
||||||
value.quartet = __rev16(value.quartet);
|
memcpy(buffer_start, &value, SIZE);
|
||||||
sum += value.solo;
|
buffer_start += SIZE;
|
||||||
|
|
||||||
|
sum += __rev16(value);
|
||||||
}
|
}
|
||||||
|
#undef SIZE
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user