Name change of E7000

This commit is contained in:
Hakan Bastedt
2025-02-19 09:30:31 +01:00
parent 7e0225711b
commit 72e861b174
68 changed files with 189 additions and 2428 deletions

View File

@@ -0,0 +1,6 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
.vscode/settings.json

View File

@@ -0,0 +1,139 @@
//
// !!! WARNING !!! AUTO-GENERATED FILE!
// PLEASE DO NOT MODIFY IT AND USE "platformio.ini":
// https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
//
{
"configurations": [
{
"name": "PlatformIO",
"includePath": [
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/include",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/src",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/lib/MyMCP3221",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/lib/soes-esi",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/lib/soes",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/.pio/libdeps/genericSTM32F407VGT6/ADS1X15",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/.pio/libdeps/genericSTM32F407VGT6/MCP3X21",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/Wire/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SPI/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/cores/arduino/avr",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/cores/arduino/stm32",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SrcWrapper/inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SrcWrapper/inc/LL",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/USBDevice/inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/VirtIO/inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Drivers/STM32F4xx_HAL_Driver/Inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Drivers/STM32F4xx_HAL_Driver/Src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/STM32F4xx",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/OpenAMP",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/OpenAMP/open-amp/lib/include",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/OpenAMP/libmetal/lib/include",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/OpenAMP/virtual_driver",
"C:/Users/Hakan/.platformio/packages/framework-cmsis/CMSIS/Core/Include",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Drivers/CMSIS/Device/ST/STM32F4xx/Include",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc",
"C:/Users/Hakan/.platformio/packages/framework-cmsis/CMSIS/DSP/Include",
"C:/Users/Hakan/.platformio/packages/framework-cmsis/CMSIS/DSP/PrivateInclude",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/cores/arduino",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/variants/STM32F4xx/F407V(E-G)T_F417V(E-G)T",
"C:/Users/Hakan/.platformio/lib/RunningAverage",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/CMSIS_DSP/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/EEPROM/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/IWatchdog/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/Keyboard/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/Mouse/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/RGB_LED_TLC59731/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/Servo/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SoftwareSerial/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SrcWrapper/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SubGhz/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/USBDevice/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/VirtIO/src",
""
],
"browse": {
"limitSymbolsToIncludedHeaders": true,
"path": [
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/include",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/src",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/lib/MyMCP3221",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/lib/soes-esi",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/lib/soes",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/.pio/libdeps/genericSTM32F407VGT6/ADS1X15",
"Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/.pio/libdeps/genericSTM32F407VGT6/MCP3X21",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/Wire/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SPI/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/cores/arduino/avr",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/cores/arduino/stm32",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SrcWrapper/inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SrcWrapper/inc/LL",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/USBDevice/inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/VirtIO/inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Drivers/STM32F4xx_HAL_Driver/Inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Drivers/STM32F4xx_HAL_Driver/Src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/STM32F4xx",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/OpenAMP",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/OpenAMP/open-amp/lib/include",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/OpenAMP/libmetal/lib/include",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Middlewares/OpenAMP/virtual_driver",
"C:/Users/Hakan/.platformio/packages/framework-cmsis/CMSIS/Core/Include",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Drivers/CMSIS/Device/ST/STM32F4xx/Include",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/system/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc",
"C:/Users/Hakan/.platformio/packages/framework-cmsis/CMSIS/DSP/Include",
"C:/Users/Hakan/.platformio/packages/framework-cmsis/CMSIS/DSP/PrivateInclude",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/cores/arduino",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/variants/STM32F4xx/F407V(E-G)T_F417V(E-G)T",
"C:/Users/Hakan/.platformio/lib/RunningAverage",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/CMSIS_DSP/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/EEPROM/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/IWatchdog/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/Keyboard/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/Mouse/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/RGB_LED_TLC59731/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/Servo/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SoftwareSerial/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SrcWrapper/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/SubGhz/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/USBDevice/src",
"C:/Users/Hakan/.platformio/packages/framework-arduinoststm32/libraries/VirtIO/src",
""
]
},
"defines": [
"PLATFORMIO=60117",
"STM32F407xx",
"STM32F4",
"NO_ECAT",
"ADS1xxx",
"STM32F4xx",
"ARDUINO=10808",
"ARDUINO_ARCH_STM32",
"NDEBUG",
"ARDUINO_GENERIC_F407VGTX",
"BOARD_NAME=\"GENERIC_F407VGTX\"",
"HAL_UART_MODULE_ENABLED",
"USE_HAL_DRIVER",
"USE_FULL_LL_DRIVER",
"VARIANT_H=\"variant_generic.h\"",
"VECT_TAB_OFFSET=0x0",
""
],
"cStandard": "gnu17",
"cppStandard": "gnu++17",
"compilerPath": "C:/Users/Hakan/.platformio/packages/toolchain-gccarmnoneeabi/bin/arm-none-eabi-gcc.exe",
"compilerArgs": [
"-mcpu=cortex-m4",
"-mthumb",
"-mfpu=fpv4-sp-d16",
"-mfloat-abi=hard",
""
]
}
],
"version": 4
}

View File

@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@@ -0,0 +1,47 @@
// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY
//
// PlatformIO Debugging Solution
//
// Documentation: https://docs.platformio.org/en/latest/plus/debugging.html
// Configuration: https://docs.platformio.org/en/latest/projectconf/sections/env/options/debug/index.html
{
"version": "0.2.0",
"configurations": [
{
"type": "platformio-debug",
"request": "launch",
"name": "PIO Debug",
"executable": "Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/.pio/build/genericSTM32F407VGT6/firmware.elf",
"projectEnvName": "genericSTM32F407VGT6",
"toolchainBinDir": "C:/Users/Hakan/.platformio/packages/toolchain-gccarmnoneeabi/bin",
"internalConsoleOptions": "openOnSessionStart",
"svdPath": "C:/Users/Hakan/.platformio/platforms/ststm32/misc/svd/STM32F40x.svd",
"preLaunchTask": {
"type": "PlatformIO",
"task": "Pre-Debug"
}
},
{
"type": "platformio-debug",
"request": "launch",
"name": "PIO Debug (skip Pre-Debug)",
"executable": "Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/.pio/build/genericSTM32F407VGT6/firmware.elf",
"projectEnvName": "genericSTM32F407VGT6",
"toolchainBinDir": "C:/Users/Hakan/.platformio/packages/toolchain-gccarmnoneeabi/bin",
"internalConsoleOptions": "openOnSessionStart",
"svdPath": "C:/Users/Hakan/.platformio/platforms/ststm32/misc/svd/STM32F40x.svd"
},
{
"type": "platformio-debug",
"request": "launch",
"name": "PIO Debug (without uploading)",
"executable": "Z:/src/MyOwnEtherCATDevice/Cards/EaserCAT-7000-DIO+THCAD+I2C/Firmware/.pio/build/genericSTM32F407VGT6/firmware.elf",
"projectEnvName": "genericSTM32F407VGT6",
"toolchainBinDir": "C:/Users/Hakan/.platformio/packages/toolchain-gccarmnoneeabi/bin",
"internalConsoleOptions": "openOnSessionStart",
"svdPath": "C:/Users/Hakan/.platformio/platforms/ststm32/misc/svd/STM32F40x.svd",
"loadMode": "manual"
}
]
}

View File

@@ -0,0 +1,22 @@
{
"files.associations": {
"ecat_slv.h": "c",
"compare": "cpp",
"*.tpp": "cpp",
"*.tcc": "cpp",
"deque": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"system_error": "cpp",
"numeric": "cpp",
"ostream": "cpp",
"cmath": "cpp",
"cstddef": "cpp",
"array": "cpp",
"string_view": "cpp",
"initializer_list": "cpp"
},
"C_Cpp.errorSquiggles": "disabled",
"cmake.configureOnOpen": false
}

View File

@@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View File

@@ -0,0 +1,14 @@
#ifndef EXTEND32TO64
#define EXTEND32TO54
#include <Arduino.h>
class extend32to64
{
public:
int64_t previousTimeValue = 0;
const uint64_t ONE_PERIOD = 4294967296; // almost UINT32_MAX;
const uint64_t HALF_PERIOD = 2147483648; // Half of that
int64_t extendTime(uint32_t in);
};
#endif

View File

@@ -0,0 +1,285 @@
/*==============================================================================================================*
@file MyMCP3221.cpp
@author Nadav Matalon
@license MIT (c) 2016 Nadav Matalon
MCP3221 Driver (12-BIT Single Channel ADC with I2C Interface)
Ver. 1.0.0 - First release (16.10.16)
*==============================================================================================================*
LICENSE
*==============================================================================================================*
The MIT License (MIT)
Copyright (c) 2016 Nadav Matalon
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without
limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*==============================================================================================================*/
#include "MyMCP3221.h"
/*==============================================================================================================*
CONSTRUCTOR
*==============================================================================================================*/
MyMCP3221::MyMCP3221(
byte devAddr,
TwoWire *Wire,
unsigned int vRef,
unsigned int res1,
unsigned int res2,
unsigned int alpha,
voltage_input_t voltageInput,
smoothing_t smoothingMethod,
byte numSamples) :
_Wire(Wire),
_devAddr(devAddr),
_vRef(vRef),
_alpha(alpha),
_voltageInput(voltageInput),
_smoothing(smoothingMethod),
_numSamples(numSamples)
{
memset(_samples, 0, sizeof(_samples));
if (((res1 != 0) && (res2 != 0)) && (_voltageInput == VOLTAGE_INPUT_12V)) {
_res1 = res1;
_res2 = res2;
} else if (_voltageInput == VOLTAGE_INPUT_5V) {
_res1 = 0;
_res2 = 0;
} else {
_res1 = DEFAULT_RES_1;
_res2 = DEFAULT_RES_2;
}
_comBuffer = COM_SUCCESS;
}
/*==============================================================================================================*
DESTRUCTOR
*==============================================================================================================*/
MyMCP3221::~MyMCP3221() {}
/*==============================================================================================================*
PING (0 = SUCCESS / 1, 2, ... = ERROR CODE)
*==============================================================================================================*/
// See meaning of I2C Error Code values in README
byte MyMCP3221::ping() {
_Wire->beginTransmission(_devAddr);
return _comBuffer = _Wire->endTransmission();
}
/*==============================================================================================================*
GET VOLTAGE REFERENCE (2700mV - 5500mV)
*==============================================================================================================*/
unsigned int MyMCP3221::getVref() {
return _vRef;
}
/*==============================================================================================================*
GET VOLTAGE DIVIDER RESISTOR 1 (Ω)
*==============================================================================================================*/
unsigned int MyMCP3221::getRes1() {
return _res1;
}
/*==============================================================================================================*
GET VOLTAGE DIVIDER RESISTOR 2 (Ω)
*==============================================================================================================*/
unsigned int MyMCP3221::getRes2() {
return _res2;
}
/*==============================================================================================================*
GET ALPHA (RELEVANT ONLY FOR EMAVG SMOOTHING METHOD, RANGE: 1 - 256)
*==============================================================================================================*/
unsigned int MyMCP3221::getAlpha() {
return _alpha;
}
/*==============================================================================================================*
GET NUMBER OF SAMPLES (RELEVANT ONLY FOR ROLLING-AVAREGE SMOOTHING METHOD, RANGE: 1-20 SAMPLES)
*==============================================================================================================*/
byte MyMCP3221::getNumSamples() {
return _numSamples;
}
/*==============================================================================================================*
GET VOLTAGE INPUT (0 = VOLTAGE_INPUT_5V / 1 = VOLTAGE_INPUT_12V)
*==============================================================================================================*/
byte MyMCP3221::getVinput() {
return _voltageInput;
}
/*==============================================================================================================*
GET SMOOTHING METHOD (0 = NONE / 1 = ROLLING-AVAREGE / 2 = EMAVG)
*==============================================================================================================*/
byte MyMCP3221::getSmoothing() {
return _smoothing;
}
/*==============================================================================================================*
GET DATA
*==============================================================================================================*/
unsigned int MyMCP3221::getData() {
return (_smoothing == NO_SMOOTHING) ? getRawData() : smoothData(getRawData());
}
/*==============================================================================================================*
GET VOLTAGE (Vref 4.096V: 2700 - 4096mV)
*==============================================================================================================*/
unsigned int MyMCP3221::getVoltage() {
if (_voltageInput == VOLTAGE_INPUT_5V) return round((_vRef / (float)DEFAULT_VREF) * getData());
else return round(getData() * ((float)(_res1 + _res2) / _res2));
}
/*==============================================================================================================*
GET LATEST I2C COMMUNICATION RESULT (0 = OK / 1, 2, ... = ERROR)
*==============================================================================================================*/
byte MyMCP3221::getComResult() {
return _comBuffer;
}
/*==============================================================================================================*
SET REFERENCE VOLTAGE (2700mV - 5500mV)
*==============================================================================================================*/
void MyMCP3221::setVref(unsigned int newVref) { // PARAM RANGE: 2700-5500
newVref = constrain(newVref, MIN_VREF, MAX_VREF);
_vRef = newVref;
}
/*==============================================================================================================*
SET VOLTAGE DIVIDER RESISTOR 1 (Ω)
*==============================================================================================================*/
void MyMCP3221::setRes1(unsigned int newRes1) {
_res1 = newRes1;
}
/*==============================================================================================================*
SET VOLTAGE DIVIDER RESISTOR 2 (Ω)
*==============================================================================================================*/
void MyMCP3221::setRes2(unsigned int newRes2) {
_res2 = newRes2;
}
/*==============================================================================================================*
SET ALPHA (RELEVANT ONLY FOR EMAVG SMOOTHING METHOD)
*==============================================================================================================*/
void MyMCP3221::setAlpha(unsigned int newAlpha) { // PARAM RANGE: 1-256
newAlpha = constrain(newAlpha, MIN_ALPHA, MAX_ALPHA);
_alpha = newAlpha;
}
/*==============================================================================================================*
SET NUMBER OF SAMPLES (RELEVANT ONLY FOR ROLLING-AVAREGE SMOOTHING METHOD)
*==============================================================================================================*/
void MyMCP3221::setNumSamples(byte newNumSamples) { // PARAM RANGE: 1-20
newNumSamples = constrain(newNumSamples, MIN_NUM_SAMPLES, MAX_NUM_SAMPLES);
_numSamples = newNumSamples;
for (byte i=0; i<MAX_NUM_SAMPLES; i++) _samples[i] = 0;
}
/*==============================================================================================================*
SET VOLTAGE INPUT (NOTE: 12V INPUT READINGS REQUIRE A HARDWARE VOLTAGE DIVIDER)
*==============================================================================================================*/
void MyMCP3221::setVinput(voltage_input_t newVoltageInput) { // PARAMS: VOLTAGE_INPUT_5V / VOLTAGE_INPUT_12V
_voltageInput = newVoltageInput;
if (newVoltageInput == VOLTAGE_INPUT_12V) {
if (!_res1) _res1 = DEFAULT_RES_1;
if (!_res2) _res2 = DEFAULT_RES_2;
}
}
/*==============================================================================================================*
SET SMOOTHING METHOD
*==============================================================================================================*/
void MyMCP3221::setSmoothing(smoothing_t newSmoothing) { // PARAMS: NO_SMOOTHING / ROLLING / EMAVG
_smoothing = newSmoothing;
}
/*==============================================================================================================*
RESET
*==============================================================================================================*/
void MyMCP3221::reset() {
setVref(DEFAULT_VREF);
setAlpha(DEFAULT_ALPHA);
setVinput(VOLTAGE_INPUT_5V);
setSmoothing(EMAVG);
setRes1(0);
setRes2(0);
setNumSamples(DEFAULT_NUM_SAMPLES);
}
/*==============================================================================================================*
GET RAW DATA
*==============================================================================================================*/
unsigned int MyMCP3221::getRawData() {
unsigned int rawData = 0;
_Wire->requestFrom(_devAddr, DATA_BYTES);
if (_Wire->available() == DATA_BYTES) rawData = (_Wire->read() << 8) | (_Wire->read());
else ping();
return rawData;
}
/*==============================================================================================================*
SMOOTH DATA
*==============================================================================================================*/
unsigned int MyMCP3221::smoothData(unsigned int rawData) {
unsigned int smoothedData;
if (_smoothing == EMAVG) { // Exmponential Moving Average
unsigned int emAvg = rawData;
emAvg = (_alpha * (unsigned long)rawData + (MAX_ALPHA - _alpha) * (unsigned long)emAvg) / MAX_ALPHA;
smoothedData = emAvg;
} else { // Rolling-Average
unsigned long sum = 0;
if (_samples[_numSamples - 1] != 0) {
for (byte i = 1; i<_numSamples; i++) _samples[i - 1] = _samples[i]; // drop last reading & rearrange array
_samples[_numSamples - 1] = rawData; // add a new sample at the end of array
for (byte j=0; j<_numSamples; j++) sum += _samples[j]; // aggregate all samples
smoothedData = sum / _numSamples; // calculate average
} else {
for (byte i = 0; i<_numSamples; i++) _samples[i] = rawData;
smoothedData = rawData;
}
}
return smoothedData;
}

View File

@@ -0,0 +1,207 @@
/*==============================================================================================================*
@file MyMCP3221.h
@author Nadav Matalon
@license MIT (c) 2016 Nadav Matalon
MCP3221 Driver (12-BIT Single Channel ADC with I2C Interface)
Ver. 1.0.0 - First release (16.10.16)
*===============================================================================================================*
INTRODUCTION
*===============================================================================================================*
The MCP3221 is a 12-Bit Single Channel ADC with hardware I2C interface.
This library contains a complete driver for the MCP3221 allowing the user to get raw conversion data,
smoothed conversion data (Rollong-Average or EMAVG), or voltage readings ranging 0-5V or 0-12V (the latter
requires a voltage divider setup).
*===============================================================================================================*
DEVICE HOOKUP
*===============================================================================================================*
MCP3221
-------
VCC --| • |-- SCL
| |
GND --| |
| |
AIN --| |-- SDA
-------
PIN 1 (VCC/VREF) - Serves as both Power Supply input and Voltage Reference for the ADC. Connect to the Arduino
5V Output or any other equivalent power source (5.5V max). If using an external power source,
remember to connect all GND's together
PIN 2 (GND) - connect to Arduino GND
PIN 3 (AIN) - Connect to Arduino's 3.3V Output or the middle pin of a 10K potentiometer (other two pins go to 5V & GND)
PIN 4 (SDA) - Connect to Arduino's PIN A4 with a 2K2 (400MHz I2C Bus speed) or 10K (100MHz I2C Bus speed) pull-up resistor
PIN 5 (SCL) - Connect to Arduino's PIN A5 with a 2K2 (400MHz I2C Bus speed) or 10K (100MHz I2C Bus speed) pull-up resistor
DECOUPING: Minimal decoupling consists of a 0.1uF Ceramic Capacitor between the VCC & GND PINS. For improved
performance, add a 1uF and a 10uF Ceramic Capacitors as well across these pins
*===============================================================================================================*
VOLTAGE DIVIDER HOOKUP (OPTIONAL: FOR 12V READINGS)
*===============================================================================================================*
12V
| MCP3221
| -------
R1 | | | |
| | | |
| AIN | |
|-----------| |
| | |
| | -------
R2 | |
|
|
GND
R1 - 10K Resistor
R2 - 4K7 Resistor
*===============================================================================================================*
I2C ADDRESSES
*===============================================================================================================*
Each MCP3221 has 1 of 8 possible I2C addresses (factory hardwired & recognized by its specific
part number & top marking on the package itself):
PART DEVICE I2C ADDRESS PART
NUMBER (BIN) (HEX) (DEC) MARKING
MCP3221A0T-E/OT 01001000 0x48 72 GE
MCP3221A1T-E/OT 01001001 0x49 73 GH
MCP3221A2T-E/OT 01001010 0x4A 74 GB
MCP3221A3T-E/OT 01001000 0x4B 75 GC
MCP3221A4T-E/OT 01001100 0x4C 76 GD
MCP3221A5T-E/OT 01001101 0x4D 77 GA
MCP3221A6T-E/OT 01001110 0x4E 78 GF
MCP3221A7T-E/OT 01001111 0x4F 79 GG
*===============================================================================================================*
DEVICE SETTING DEFAULTS
*===============================================================================================================*
VOLTAGE REFERENCE: 4096mV // this value is equal to the voltage fed to VCC
VOLTAGE INPUT: 5V // direct measurment of voltage at AIN pin (hw setup without voltage divider)
VOLTAGE DIVIDER RESISTOR 1: 0R // value used when measuring voltage of up to 12V at AIN pin
VOLTAGE DIVIDER RESISTOR 2: 0R // value used when measuring voltage of up to 12V at AIN pin
NUMBER OF SAMPLES: 10 // used by Rolling-Average smoothing method (range: 1-20 Samples)
ALPHA 178 // factor used by EMAVG smoothing method (range: 1-256)
*===============================================================================================================*
BUG REPORTS
*===============================================================================================================*
Please report any bugs/issues/suggestions at the Github Repo of this library at:
https://github.com/nadavmatalon/MCP3221
*===============================================================================================================*
LICENSE
*===============================================================================================================*
The MIT License (MIT)
Copyright (c) 2016 Nadav Matalon
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without
limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*==============================================================================================================*/
#ifndef MyMCP3221_h
#define MyMCP3221_h
#include <Arduino.h>
#include <Wire.h>
//#include "utility/MCP3221_PString.h"
namespace Mymcp3221 {
const byte DATA_BYTES = 2; // number of data bytes requested from the device
const byte MIN_CON_TIME = 15; // single conversion time with a small overhead (in uS)
const byte COM_SUCCESS = 0; // I2C communication success Code (No Error)
const unsigned int MIN_VREF = 2700; // minimum Voltage Reference value in mV (same as VCC)
const unsigned int MAX_VREF = 5500; // minimum Voltage Reference value in mV (same as VCC)
const unsigned int DEFAULT_VREF = 4096; // default Voltage Reference value in mV (same as VCC)
const unsigned int DEFAULT_RES_1 = 10000; // default Resistor 1 value (in Ω) of voltage divider for 12V readings
const unsigned int DEFAULT_RES_2 = 4700; // default Resistor 2 value (in Ω) of voltage divider for 12V readings
const unsigned int MIN_ALPHA = 1; // minimum value of alpha (slowest change) (for EMAVG)
const unsigned int MAX_ALPHA = 256; // maximum value of alpha (raw change/no filter) (for EMAVG)
const unsigned int DEFAULT_ALPHA = 178; // default value of alpha (for EMAVG)
const byte MIN_NUM_SAMPLES = 1; // minimum number of samples (for Rolling-Average smoothing)
const byte MAX_NUM_SAMPLES = 20; // maximum number of samples (for Rolling-Average smoothing)
const byte DEFAULT_NUM_SAMPLES = 10; // default number of samples (for Rolling-Average smoothing)
typedef enum:byte {
VOLTAGE_INPUT_5V = 0, // default
VOLTAGE_INPUT_12V = 1
} voltage_input_t;
typedef enum:byte {
NO_SMOOTHING = 0,
ROLLING_AVG = 1,
EMAVG = 2 // Default
} smoothing_t;
class MyMCP3221 {
public:
MyMCP3221(
byte devAddr,
TwoWire *Wire,
unsigned int vRef = DEFAULT_VREF,
unsigned int res1 = DEFAULT_RES_1,
unsigned int res2 = DEFAULT_RES_2,
unsigned int alpha = DEFAULT_ALPHA,
voltage_input_t voltageInput = VOLTAGE_INPUT_5V,
smoothing_t smoothingMethod = EMAVG,
byte numSamples = DEFAULT_NUM_SAMPLES
);
~MyMCP3221();
byte ping();
unsigned int getVref();
unsigned int getRes1();
unsigned int getRes2();
unsigned int getAlpha();
byte getNumSamples();
byte getVinput();
byte getSmoothing();
unsigned int getData();
unsigned int getVoltage();
byte getComResult();
void setVref(unsigned int newVref);
void setRes1(unsigned int newRes1);
void setRes2(unsigned int newRes2);
void setAlpha(unsigned int newAlpha);
void setNumSamples(byte newNumSamples);
void setVinput(voltage_input_t newVinput);
void setSmoothing(smoothing_t newSmoothing);
void reset();
private:
TwoWire *_Wire;
byte _devAddr, _voltageInput, _smoothing, _numSamples, _comBuffer;
unsigned int _vRef, _res1, _res2, _alpha;
unsigned int _samples[MAX_NUM_SAMPLES];
unsigned int getRawData();
unsigned int smoothData(unsigned int rawData);
// friend MyMCP3221_PString MyMCP3221ComStr(const MyMCP3221&);
// friend MyMCP3221_PString MyMCP3221InfoStr(const MyMCP3221&);
};
}
using namespace Mymcp3221;
#endif

View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View File

@@ -0,0 +1,965 @@
<?xml version="1.0" encoding="UTF-8"?>
<EtherCATInfo>
<Vendor>
<Id>3502166480</Id>
<Name LcId="1033">MetalMusings</Name>
</Vendor>
<Descriptions>
<Groups>
<Group>
<Type>MachineControl</Type>
<Name LcId="1033">Plasma cutter</Name>
</Group>
</Groups>
<Devices>
<Device Physics="YY ">
<Type ProductCode="#x7000" RevisionNo="#x2">EaserCAT 7000</Type>
<Name LcId="1033">MetalMusings EaserCAT 7000</Name>
<GroupType>MachineControl</GroupType>
<Profile>
<ProfileNo>5001</ProfileNo>
<AddInfo>0</AddInfo>
<Dictionary>
<DataTypes>
<DataType>
<Name>DT1018</Name>
<BitSize>144</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>Vendor ID</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>2</SubIdx>
<Name>Product Code</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>48</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>3</SubIdx>
<Name>Revision Number</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>80</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>4</SubIdx>
<Name>Serial Number</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>112</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1600</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>Output4</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1601</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>VoltageScale</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1602</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>VoltageOffset</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1A00</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>Input12</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1A01</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>RawData</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1A02</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>CalculatedVoltage</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1A03</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>Status</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1C00ARR</Name>
<BaseType>USINT</BaseType>
<BitSize>32</BitSize>
<ArrayInfo>
<LBound>1</LBound>
<Elements>4</Elements>
</ArrayInfo>
</DataType>
<DataType>
<Name>DT1C00</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<Name>Elements</Name>
<Type>DT1C00ARR</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1C12ARR</Name>
<BaseType>UINT</BaseType>
<BitSize>48</BitSize>
<ArrayInfo>
<LBound>1</LBound>
<Elements>3</Elements>
</ArrayInfo>
</DataType>
<DataType>
<Name>DT1C12</Name>
<BitSize>64</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<Name>Elements</Name>
<Type>DT1C12ARR</Type>
<BitSize>48</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1C13ARR</Name>
<BaseType>UINT</BaseType>
<BitSize>64</BitSize>
<ArrayInfo>
<LBound>1</LBound>
<Elements>4</Elements>
</ArrayInfo>
</DataType>
<DataType>
<Name>DT1C13</Name>
<BitSize>80</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<Name>Elements</Name>
<Type>DT1C13ARR</Type>
<BitSize>64</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>UDINT</Name>
<BitSize>32</BitSize>
</DataType>
<DataType>
<Name>STRING(26)</Name>
<BitSize>208</BitSize>
</DataType>
<DataType>
<Name>STRING(5)</Name>
<BitSize>40</BitSize>
</DataType>
<DataType>
<Name>USINT</Name>
<BitSize>8</BitSize>
</DataType>
<DataType>
<Name>UINT</Name>
<BitSize>16</BitSize>
</DataType>
<DataType>
<Name>REAL</Name>
<BitSize>32</BitSize>
</DataType>
<DataType>
<Name>DINT</Name>
<BitSize>32</BitSize>
</DataType>
</DataTypes>
<Objects>
<Object>
<Index>#x1000</Index>
<Name>Device Type</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>5001</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<Category>m</Category>
</Flags>
</Object>
<Object>
<Index>#x1008</Index>
<Name>Device Name</Name>
<Type>STRING(26)</Type>
<BitSize>208</BitSize>
<Info>
<DefaultString>MetalMusings EaserCAT 7000</DefaultString>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1009</Index>
<Name>Hardware Version</Name>
<Type>STRING(5)</Type>
<BitSize>40</BitSize>
<Info>
<DefaultString>0.0.1</DefaultString>
</Info>
<Flags>
<Access>ro</Access>
<Category>o</Category>
</Flags>
</Object>
<Object>
<Index>#x100A</Index>
<Name>Software Version</Name>
<Type>STRING(5)</Type>
<BitSize>40</BitSize>
<Info>
<DefaultString>0.0.1</DefaultString>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1018</Index>
<Name>Identity Object</Name>
<Type>DT1018</Type>
<BitSize>144</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Vendor ID</Name>
<Info>
<DefaultValue>3502166480</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Product Code</Name>
<Info>
<DefaultValue>28672</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Revision Number</Name>
<Info>
<DefaultValue>2</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Serial Number</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1600</Index>
<Name>Output4</Name>
<Type>DT1600</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Output4</Name>
<Info>
<DefaultValue>#x70000008</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1601</Index>
<Name>VoltageScale</Name>
<Type>DT1601</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>VoltageScale</Name>
<Info>
<DefaultValue>#x70010020</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1602</Index>
<Name>VoltageOffset</Name>
<Type>DT1602</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>VoltageOffset</Name>
<Info>
<DefaultValue>#x70020020</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1A00</Index>
<Name>Input12</Name>
<Type>DT1A00</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Input12</Name>
<Info>
<DefaultValue>#x60000020</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1A01</Index>
<Name>RawData</Name>
<Type>DT1A01</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>RawData</Name>
<Info>
<DefaultValue>#x60010020</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1A02</Index>
<Name>CalculatedVoltage</Name>
<Type>DT1A02</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>CalculatedVoltage</Name>
<Info>
<DefaultValue>#x60020020</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1A03</Index>
<Name>Status</Name>
<Type>DT1A03</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Status</Name>
<Info>
<DefaultValue>#x60030008</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1C00</Index>
<Name>Sync Manager Communication Type</Name>
<Type>DT1C00</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Communications Type SM0</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Communications Type SM1</Name>
<Info>
<DefaultValue>2</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Communications Type SM2</Name>
<Info>
<DefaultValue>3</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Communications Type SM3</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1C12</Index>
<Name>Sync Manager 2 PDO Assignment</Name>
<Type>DT1C12</Type>
<BitSize>64</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>3</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1600</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1601</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1602</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1C13</Index>
<Name>Sync Manager 3 PDO Assignment</Name>
<Type>DT1C13</Type>
<BitSize>80</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1A00</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1A01</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1A02</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1A03</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x2000</Index>
<Name>Scale</Name>
<Type>REAL</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x2001</Index>
<Name>Offset</Name>
<Type>REAL</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x6000</Index>
<Name>Input12</Name>
<Type>DINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>T</PdoMapping>
</Flags>
</Object>
<Object>
<Index>#x6001</Index>
<Name>RawData</Name>
<Type>DINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>T</PdoMapping>
</Flags>
</Object>
<Object>
<Index>#x6002</Index>
<Name>CalculatedVoltage</Name>
<Type>REAL</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>T</PdoMapping>
</Flags>
</Object>
<Object>
<Index>#x6003</Index>
<Name>Status</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>T</PdoMapping>
</Flags>
</Object>
<Object>
<Index>#x7000</Index>
<Name>Output4</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>R</PdoMapping>
</Flags>
</Object>
<Object>
<Index>#x7001</Index>
<Name>VoltageScale</Name>
<Type>REAL</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>R</PdoMapping>
</Flags>
</Object>
<Object>
<Index>#x7002</Index>
<Name>VoltageOffset</Name>
<Type>REAL</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>R</PdoMapping>
</Flags>
</Object>
</Objects>
</Dictionary>
</Profile>
<Fmmu>Outputs</Fmmu>
<Fmmu>Inputs</Fmmu>
<Fmmu>MBoxState</Fmmu>
<Sm DefaultSize="512" StartAddress="#x1000" ControlByte="#x26" Enable="1">MBoxOut</Sm>
<Sm DefaultSize="512" StartAddress="#x1200" ControlByte="#x22" Enable="1">MBoxIn</Sm>
<Sm StartAddress="#x1600" ControlByte="#x24" Enable="1">Outputs</Sm>
<Sm StartAddress="#x1A00" ControlByte="#x20" Enable="1">Inputs</Sm>
<RxPdo Fixed="true" Mandatory="true" Sm="2">
<Index>#x1600</Index>
<Name>Output4</Name>
<Entry>
<Index>#x7000</Index>
<SubIndex>#x0</SubIndex>
<BitLen>8</BitLen>
<Name>Output4</Name>
<DataType>USINT</DataType>
</Entry>
</RxPdo>
<RxPdo Fixed="true" Mandatory="true" Sm="2">
<Index>#x1601</Index>
<Name>VoltageScale</Name>
<Entry>
<Index>#x7001</Index>
<SubIndex>#x0</SubIndex>
<BitLen>32</BitLen>
<Name>VoltageScale</Name>
<DataType>REAL</DataType>
</Entry>
</RxPdo>
<RxPdo Fixed="true" Mandatory="true" Sm="2">
<Index>#x1602</Index>
<Name>VoltageOffset</Name>
<Entry>
<Index>#x7002</Index>
<SubIndex>#x0</SubIndex>
<BitLen>32</BitLen>
<Name>VoltageOffset</Name>
<DataType>REAL</DataType>
</Entry>
</RxPdo>
<TxPdo Fixed="true" Mandatory="true" Sm="3">
<Index>#x1A00</Index>
<Name>Input12</Name>
<Entry>
<Index>#x6000</Index>
<SubIndex>#x0</SubIndex>
<BitLen>32</BitLen>
<Name>Input12</Name>
<DataType>DINT</DataType>
</Entry>
</TxPdo>
<TxPdo Fixed="true" Mandatory="true" Sm="3">
<Index>#x1A01</Index>
<Name>RawData</Name>
<Entry>
<Index>#x6001</Index>
<SubIndex>#x0</SubIndex>
<BitLen>32</BitLen>
<Name>RawData</Name>
<DataType>DINT</DataType>
</Entry>
</TxPdo>
<TxPdo Fixed="true" Mandatory="true" Sm="3">
<Index>#x1A02</Index>
<Name>CalculatedVoltage</Name>
<Entry>
<Index>#x6002</Index>
<SubIndex>#x0</SubIndex>
<BitLen>32</BitLen>
<Name>CalculatedVoltage</Name>
<DataType>REAL</DataType>
</Entry>
</TxPdo>
<TxPdo Fixed="true" Mandatory="true" Sm="3">
<Index>#x1A03</Index>
<Name>Status</Name>
<Entry>
<Index>#x6003</Index>
<SubIndex>#x0</SubIndex>
<BitLen>8</BitLen>
<Name>Status</Name>
<DataType>USINT</DataType>
</Entry>
</TxPdo>
<Mailbox DataLinkLayer="true">
<CoE SdoInfo="true" PdoAssign="false" PdoConfig="false" PdoUpload="true" CompleteAccess="false" />
</Mailbox>
<Dc>
<OpMode>
<Name>SM-Synchron</Name>
<Desc>SM-Synchron</Desc>
<AssignActivate>#x000</AssignActivate>
</OpMode>
<OpMode>
<Name>DC</Name>
<Desc>DC-Synchron</Desc>
<AssignActivate>#x300</AssignActivate>
</OpMode>
</Dc>
<Eeprom>
<ByteSize>2048</ByteSize>
<ConfigData>80060344640000</ConfigData>
</Eeprom>
</Device>
</Devices>
</Descriptions>
</EtherCATInfo>

View File

@@ -0,0 +1,42 @@
#ifndef __ECAT_OPTIONS_H__
#define __ECAT_OPTIONS_H__
#define USE_FOE 0
#define USE_EOE 0
#define MBXSIZE 512
#define MBXSIZEBOOT 512
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1600
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1A00
#define SM3_smc 0x20
#define SM3_act 1
#define MAX_MAPPINGS_SM2 3
#define MAX_MAPPINGS_SM3 4
#define MAX_RXPDO_SIZE 512
#define MAX_TXPDO_SIZE 512
#endif /* __ECAT_OPTIONS_H__ */

Binary file not shown.

View File

@@ -0,0 +1,65 @@
:2000000080060344640000000000000000001400D0D1BED0007000000200000001000000F9
:20002000000000000000000000000000000000000010000200120002040000000000000096
:200040000000000000000000000000000000000000000000000000000000000000000000A0
:20006000000000000000000000000000000000000000000000000000000000000F00010070
:200080000A002000040D456173657243415420373030300E4D616368696E65436F6E7472AD
:2000A0006F6C06494D474342591A4D6574616C4D7573696E677320456173657243415420A9
:2000C000373030301E001000020301040013000000000000000000001100000000000000FD
:2000E000000000000000000028000200010203002900100000100002260001010012000249
:20010000220001020016000024000103001A000020000104FFFFFFFFFFFFFFFFFFFFFFFF49
:20012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
:20014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
:20016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F
:20018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
:2001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
:2001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
:2001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F
:20020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
:20022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
:20024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
:20026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E
:20028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
:2002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
:2002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
:2002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E
:20030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
:20032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
:20034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
:20036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
:20038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
:2003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
:2003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
:2003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
:20040000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
:20042000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
:20044000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
:20046000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
:20048000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C
:2004A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C
:2004C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C
:2004E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C
:20050000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
:20052000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB
:20054000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB
:20056000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B
:20058000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B
:2005A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B
:2005C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B
:2005E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B
:20060000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
:20062000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA
:20064000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
:20066000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A
:20068000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
:2006A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A
:2006C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A
:2006E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A
:20070000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9
:20072000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9
:20074000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9
:20076000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99
:20078000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79
:2007A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59
:2007C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39
:2007E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
:00000001FF

View File

@@ -0,0 +1,193 @@
{
"form": {
"VendorName": "MetalMusings",
"VendorID": "0xd0bed1d0",
"ProductCode": "0x7000",
"ProfileNo": "5001",
"RevisionNumber": "0x002",
"SerialNumber": "0x001",
"HWversion": "0.0.1",
"SWversion": "0.0.1",
"EEPROMsize": "2048",
"RxMailboxOffset": "0x1000",
"TxMailboxOffset": "0x1200",
"MailboxSize": "512",
"SM2Offset": "0x1600",
"SM3Offset": "0x1A00",
"TextGroupType": "MachineControl",
"TextGroupName5": "Plasma cutter",
"ImageName": "IMGCBY",
"TextDeviceType": "EaserCAT 7000",
"TextDeviceName": "MetalMusings EaserCAT 7000",
"Port0Physical": "Y",
"Port1Physical": "Y",
"Port2Physical": " ",
"Port3Physical": " ",
"ESC": "LAN9252",
"SPImode": "3",
"CoeDetailsEnableSDO": "EnableSDO",
"CoeDetailsEnableSDOInfo": "EnableSDOInfo",
"CoeDetailsEnablePDOAssign": "EnablePDOAssign",
"CoeDetailsEnablePDOConfiguration": "EnablePDOConfiguration",
"CoeDetailsEnableUploadAtStartup": "EnableUploadAtStartup",
"CoeDetailsEnableSDOCompleteAccess": "EnableSDOCompleteAccess"
},
"od": {
"sdo": {
"2000": {
"otype": "VAR",
"name": "Scale",
"access": "RO",
"dtype": "REAL32",
"value": "0",
"isSDOitem": true,
"data": "&Obj.Scale"
},
"2001": {
"otype": "VAR",
"name": "Offset",
"access": "RO",
"dtype": "REAL32",
"value": "0",
"isSDOitem": true,
"data": "&Obj.Offset"
},
"A": {
"otype": "RECORD",
"name": "Error Settings",
"access": "RO",
"items": [
{
"name": "Max SubIndex"
},
{
"name": "New record subitem",
"dtype": "UNSIGNED8"
}
]
}
},
"txpdo": {
"600": {
"otype": "VAR",
"name": "EncFrequency",
"access": "RO",
"pdo_mappings": [
"txpdo"
],
"dtype": "INTEGER32",
"value": "0",
"data": "&Obj.EncFrequency"
},
"6000": {
"otype": "VAR",
"name": "Input12",
"access": "RO",
"pdo_mappings": [
"txpdo"
],
"dtype": "INTEGER32",
"value": "0",
"data": "&Obj.Input12"
},
"6001": {
"otype": "VAR",
"name": "RawData",
"access": "RO",
"pdo_mappings": [
"txpdo"
],
"dtype": "INTEGER32",
"value": "0",
"data": "&Obj.RawData"
},
"6002": {
"otype": "VAR",
"name": "CalculatedVoltage",
"access": "RO",
"pdo_mappings": [
"txpdo"
],
"dtype": "REAL32",
"value": "0",
"data": "&Obj.CalculatedVoltage"
},
"6003": {
"otype": "VAR",
"name": "Status",
"access": "RO",
"pdo_mappings": [
"txpdo"
],
"dtype": "UNSIGNED8",
"value": "0",
"data": "&Obj.Status"
}
},
"rxpdo": {
"7000": {
"otype": "VAR",
"name": "Output4",
"access": "RO",
"pdo_mappings": [
"rxpdo"
],
"dtype": "UNSIGNED8",
"value": "0",
"data": "&Obj.Output4"
},
"7001": {
"otype": "VAR",
"name": "VoltageScale",
"access": "RO",
"pdo_mappings": [
"rxpdo"
],
"dtype": "REAL32",
"value": "0",
"data": "&Obj.VoltageScale"
},
"7002": {
"otype": "VAR",
"name": "VoltageOffset",
"access": "RO",
"pdo_mappings": [
"rxpdo"
],
"dtype": "REAL32",
"value": "0",
"data": "&Obj.VoltageOffset"
},
"60664": {
"otype": "VAR",
"name": "ActualPosition",
"access": "RO",
"pdo_mappings": [
"rxpdo"
],
"dtype": "INTEGER32",
"value": "0"
}
}
},
"dc": [
{
"Name": "SM-Synchron",
"Description": "SM-Synchron",
"AssignActivate": "#x000",
"Sync0cycleTime": "0",
"Sync0shiftTime": "0",
"Sync1cycleTime": "0",
"Sync1shiftTime": "0"
},
{
"Name": "DC",
"Description": "DC-Synchron",
"AssignActivate": "#x300",
"Sync0cycleTime": "0",
"Sync0shiftTime": "0",
"Sync1cycleTime": "0",
"Sync1shiftTime": "0"
}
]
}

View File

@@ -0,0 +1,210 @@
#include "esc_coe.h"
#include "utypes.h"
#include <stddef.h>
static const char acName1000[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1009[] = "Hardware Version";
static const char acName100A[] = "Software Version";
static const char acName1018[] = "Identity Object";
static const char acName1018_00[] = "Max SubIndex";
static const char acName1018_01[] = "Vendor ID";
static const char acName1018_02[] = "Product Code";
static const char acName1018_03[] = "Revision Number";
static const char acName1018_04[] = "Serial Number";
static const char acName1600[] = "Output4";
static const char acName1600_00[] = "Max SubIndex";
static const char acName1600_01[] = "Output4";
static const char acName1601[] = "VoltageScale";
static const char acName1601_00[] = "Max SubIndex";
static const char acName1601_01[] = "VoltageScale";
static const char acName1602[] = "VoltageOffset";
static const char acName1602_00[] = "Max SubIndex";
static const char acName1602_01[] = "VoltageOffset";
static const char acName1A00[] = "Input12";
static const char acName1A00_00[] = "Max SubIndex";
static const char acName1A00_01[] = "Input12";
static const char acName1A01[] = "RawData";
static const char acName1A01_00[] = "Max SubIndex";
static const char acName1A01_01[] = "RawData";
static const char acName1A02[] = "CalculatedVoltage";
static const char acName1A02_00[] = "Max SubIndex";
static const char acName1A02_01[] = "CalculatedVoltage";
static const char acName1A03[] = "Status";
static const char acName1A03_00[] = "Max SubIndex";
static const char acName1A03_01[] = "Status";
static const char acName1C00[] = "Sync Manager Communication Type";
static const char acName1C00_00[] = "Max SubIndex";
static const char acName1C00_01[] = "Communications Type SM0";
static const char acName1C00_02[] = "Communications Type SM1";
static const char acName1C00_03[] = "Communications Type SM2";
static const char acName1C00_04[] = "Communications Type SM3";
static const char acName1C12[] = "Sync Manager 2 PDO Assignment";
static const char acName1C12_00[] = "Max SubIndex";
static const char acName1C12_01[] = "PDO Mapping";
static const char acName1C12_02[] = "PDO Mapping";
static const char acName1C12_03[] = "PDO Mapping";
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
static const char acName1C13_00[] = "Max SubIndex";
static const char acName1C13_01[] = "PDO Mapping";
static const char acName1C13_02[] = "PDO Mapping";
static const char acName1C13_03[] = "PDO Mapping";
static const char acName1C13_04[] = "PDO Mapping";
static const char acName2000[] = "Scale";
static const char acName2001[] = "Offset";
static const char acName6000[] = "Input12";
static const char acName6001[] = "RawData";
static const char acName6002[] = "CalculatedVoltage";
static const char acName6003[] = "Status";
static const char acName7000[] = "Output4";
static const char acName7001[] = "VoltageScale";
static const char acName7002[] = "VoltageOffset";
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 5001, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 208, ATYPE_RO, acName1008, 0, "MetalMusings EaserCAT 7000"},
};
const _objd SDO1009[] =
{
{0x0, DTYPE_VISIBLE_STRING, 40, ATYPE_RO, acName1009, 0, "0.0.1"},
};
const _objd SDO100A[] =
{
{0x0, DTYPE_VISIBLE_STRING, 40, ATYPE_RO, acName100A, 0, "0.0.1"},
};
const _objd SDO1018[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 3502166480, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 28672, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 2, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 1, &Obj.serial},
};
const _objd SDO1600[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000008, NULL},
};
const _objd SDO1601[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1601_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1601_01, 0x70010020, NULL},
};
const _objd SDO1602[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1602_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1602_01, 0x70020020, NULL},
};
const _objd SDO1A00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60000020, NULL},
};
const _objd SDO1A01[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A01_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A01_01, 0x60010020, NULL},
};
const _objd SDO1A02[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A02_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A02_01, 0x60020020, NULL},
};
const _objd SDO1A03[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A03_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A03_01, 0x60030008, NULL},
};
const _objd SDO1C00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_00, 4, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_01, 1, NULL},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_02, 2, NULL},
{0x03, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_03, 3, NULL},
{0x04, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_04, 4, NULL},
};
const _objd SDO1C12[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 3, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_02, 0x1601, NULL},
{0x03, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_03, 0x1602, NULL},
};
const _objd SDO1C13[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 4, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_02, 0x1A01, NULL},
{0x03, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_03, 0x1A02, NULL},
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_04, 0x1A03, NULL},
};
const _objd SDO2000[] =
{
{0x0, DTYPE_REAL32, 32, ATYPE_RO, acName2000, 0x00000000, &Obj.Scale},
};
const _objd SDO2001[] =
{
{0x0, DTYPE_REAL32, 32, ATYPE_RO, acName2001, 0x00000000, &Obj.Offset},
};
const _objd SDO6000[] =
{
{0x0, DTYPE_INTEGER32, 32, ATYPE_RO | ATYPE_TXPDO, acName6000, 0, &Obj.Input12},
};
const _objd SDO6001[] =
{
{0x0, DTYPE_INTEGER32, 32, ATYPE_RO | ATYPE_TXPDO, acName6001, 0, &Obj.RawData},
};
const _objd SDO6002[] =
{
{0x0, DTYPE_REAL32, 32, ATYPE_RO | ATYPE_TXPDO, acName6002, 0x00000000, &Obj.CalculatedVoltage},
};
const _objd SDO6003[] =
{
{0x0, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_TXPDO, acName6003, 0, &Obj.Status},
};
const _objd SDO7000[] =
{
{0x0, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_RXPDO, acName7000, 0, &Obj.Output4},
};
const _objd SDO7001[] =
{
{0x0, DTYPE_REAL32, 32, ATYPE_RO | ATYPE_RXPDO, acName7001, 0x00000000, &Obj.VoltageScale},
};
const _objd SDO7002[] =
{
{0x0, DTYPE_REAL32, 32, ATYPE_RO | ATYPE_RXPDO, acName7002, 0x00000000, &Obj.VoltageOffset},
};
const _objectlist SDOobjects[] =
{
{0x1000, OTYPE_VAR, 0, 0, acName1000, SDO1000},
{0x1008, OTYPE_VAR, 0, 0, acName1008, SDO1008},
{0x1009, OTYPE_VAR, 0, 0, acName1009, SDO1009},
{0x100A, OTYPE_VAR, 0, 0, acName100A, SDO100A},
{0x1018, OTYPE_RECORD, 4, 0, acName1018, SDO1018},
{0x1600, OTYPE_RECORD, 1, 0, acName1600, SDO1600},
{0x1601, OTYPE_RECORD, 1, 0, acName1601, SDO1601},
{0x1602, OTYPE_RECORD, 1, 0, acName1602, SDO1602},
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
{0x1A01, OTYPE_RECORD, 1, 0, acName1A01, SDO1A01},
{0x1A02, OTYPE_RECORD, 1, 0, acName1A02, SDO1A02},
{0x1A03, OTYPE_RECORD, 1, 0, acName1A03, SDO1A03},
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
{0x1C12, OTYPE_ARRAY, 3, 0, acName1C12, SDO1C12},
{0x1C13, OTYPE_ARRAY, 4, 0, acName1C13, SDO1C13},
{0x2000, OTYPE_VAR, 0, 0, acName2000, SDO2000},
{0x2001, OTYPE_VAR, 0, 0, acName2001, SDO2001},
{0x6000, OTYPE_VAR, 0, 0, acName6000, SDO6000},
{0x6001, OTYPE_VAR, 0, 0, acName6001, SDO6001},
{0x6002, OTYPE_VAR, 0, 0, acName6002, SDO6002},
{0x6003, OTYPE_VAR, 0, 0, acName6003, SDO6003},
{0x7000, OTYPE_VAR, 0, 0, acName7000, SDO7000},
{0x7001, OTYPE_VAR, 0, 0, acName7001, SDO7001},
{0x7002, OTYPE_VAR, 0, 0, acName7002, SDO7002},
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
};

View File

@@ -0,0 +1,35 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include "cc.h"
/* Object dictionary storage */
typedef struct
{
/* Identity */
uint32_t serial;
/* Inputs */
int32_t Input12;
int32_t RawData;
float CalculatedVoltage;
uint8_t Status;
/* Outputs */
uint8_t Output4;
float VoltageScale;
float VoltageOffset;
/* Parameters */
float Scale;
float Offset;
} _Objects;
extern _Objects Obj;
#endif /* __UTYPES_H__ */

View File

@@ -0,0 +1,29 @@
# NOTE: add headers to make them show up in an IDE
add_library (soes
esc.c
esc.h
esc_coe.c
esc_coe.h
esc_foe.c
esc_foe.h
esc_eoe.c
esc_eoe.h
esc_eep.c
esc_eep.h
ecat_slv.c
ecat_slv.h
options.h
${HAL_SOURCES}
)
include_directories(${HAL_INCLUDES})
install (TARGETS soes DESTINATION bin)
install (FILES
esc.h
esc_coe.h
esc_foe.h
esc_eoe.h
esc_eep.h
DESTINATION include)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
#ifndef CC_H
#define CC_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <assert.h>
#include <stdint.h>
#include <stddef.h>
#include <sys/param.h>
#ifdef __linux__
#include <endian.h>
#else
#include <machine/endian.h>
#endif
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
#define CC_PACKED_BEGIN
#define CC_PACKED_END
#define CC_PACKED __attribute__((packed))
#ifdef __rtk__
#define CC_ASSERT(exp) ASSERT (exp)
#else
#define CC_ASSERT(exp) assert (exp)
#endif
#define CC_STATIC_ASSERT(exp) _Static_assert (exp, "")
#define CC_DEPRECATED __attribute__((deprecated))
#define CC_SWAP32(x) __builtin_bswap32 (x)
#define CC_SWAP16(x) __builtin_bswap16 (x)
#define CC_ATOMIC_SET(var,val) __atomic_store_n(&var,val,__ATOMIC_SEQ_CST)
#define CC_ATOMIC_GET(var) __atomic_load_n(&var,__ATOMIC_SEQ_CST)
#define CC_ATOMIC_ADD(var,val) __atomic_add_fetch(&var,val,__ATOMIC_SEQ_CST)
#define CC_ATOMIC_SUB(var,val) __atomic_sub_fetch(&var,val,__ATOMIC_SEQ_CST)
#define CC_ATOMIC_AND(var,val) __atomic_and_fetch(&var,val,__ATOMIC_SEQ_CST)
#define CC_ATOMIC_OR(var,val) __atomic_or_fetch(&var,val,__ATOMIC_SEQ_CST)
#if BYTE_ORDER == BIG_ENDIAN
#define htoes(x) CC_SWAP16 (x)
#define htoel(x) CC_SWAP32 (x)
#else
#define htoes(x) (x)
#define htoel(x) (x)
#endif
#define etohs(x) htoes (x)
#define etohl(x) htoel (x)
#if BYTE_ORDER == LITTLE_ENDIAN
#define EC_LITTLE_ENDIAN
#else
#define EC_BIG_ENDIAN
#endif
#ifdef ESC_DEBUG
#ifdef __rtk__
#include <rprint.h>
#define DPRINT(...) rprintp ("soes: "__VA_ARGS__)
#else
#include <stdio.h>
#define DPRINT(...) printf ("soes: "__VA_ARGS__)
#endif
#else
#define DPRINT(...)
#endif
#ifdef __cplusplus
}
#endif
#endif /* CC_H */

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,50 @@
/**
* \mainpage Simple Open EtherCAT Slave or SOES
*
* \section start Tutorial
* For a tutorial on SOES See tutorial.txt
*
* \section overview Overview
* SOES is an EtherCAT slave stack written in c. Its purpose is to learn and
* to use. All users are invited to study the source to get an understanding
* how an EtherCAT slave function
*
* Features as of 1.0.0 :
* - Address offset based HAL for easy ESC read/write access via any interface
* - Mailbox with data link layer
* - CoE
* - Object dictionary
* - SDO read and write for all sizes including segmented transfers
* - Easy portable C-code suited for embedded applications
* - Fixed PDO mapping
* - FoE with bootstrap template
* - Support for Little and Big endian targets.
* - Polling for interrupts
*
* \section legal Legal notice
* SOES Simple Open EtherCAT Slave \n
* Copyright (C) 2007-2013 Arthur Ketels \n
* Copyright (C) 2012-2013 rt-labs \n
*
* SOES is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* SOES is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* As a special exception, if other files instantiate templates or use macros
* or inline functions from this file, or you compile this file and link it
* with other works to produce a work based on this file, this file does not
* by itself cause the resulting work to be covered by the GNU General Public
* License. However the source code for this file must still be made available
* in accordance with section (3) of the GNU General Public License.
*
* This exception does not invalidate any other reasons why a work based on
* this file might be covered by the GNU General Public License.
*
* The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual
* property of, and protected by Beckhoff Automation GmbH.
*/

View File

@@ -0,0 +1,476 @@
/** \file
\section general General
The SOES is a library that provides the Micro Controller user application with
the means to access the EtherCAT fieldbus communication environment:
- EtherCAT State Machine
- Mailbox Interfaces
- Protocols
- CoE
- FoE + bootstrap template
Support for mailbox and protocols are typical examples when you need a slave
stack to control the Application Layer of EtherCAT. The PDI used for such
applications is either SPI or some Micro Controller Interface
The following sections show some basic examples on how to get the SOES up
and running, as well as a lightweight example on howto design your slave.
Since all code is local to the application or global variables, it is possible
to tweak and optimize when possible.
Our target Application:
- Inputs 40bit
- One button 8bit
- One encoder value 32bit
- Outputs 8bit
- LED 8bit
- Parameters
- Encoder settings
- Slave commands
- Reset counter
Now to translate and implement on top of SOES.
First look on the start up code. This example shows how to add a
main function that will be called by startup code. In this example
main's only purpose is to spawn two new tasks. One that executes
SOES and one that control the ERROR LED. Some ESCs provided a pin
for the RUN LED, some even for the ERROR LED, if it don't you can
control them from the slave Micro Controller. We'll focus on the "soes" task.
\code
int main (void)
{
rprintp ("SOES (Simple Open EtherCAT Slave)\nsoes test\n");
/* task_spawn ("led_run", led_error, 15, 512, NULL); /
task_spawn ("led_error", led_error, 15, 512, NULL);
task_spawn ("soes", soes, 9, 1024, NULL);
return (0);
}
\endcode
\section configuration Configuration
The function soes is our EtherCAT slave device and can be split in 3 parts.
Hardware Init, Software Init and Application loop. We will start with the
Hardware Init.
- Hardware Init
- esc_reset, special function used for ESC reset if no Physical
EEPROM used. This is local to the Application not part of the generic
ESC handling.
- ESC_init, initialise SPI communication or similar
- Wait for ESC is started, waiting for SPI to be up and running,
we'll query the ESC register DL status if EEPROM loaded OK and PDI
operational, eg. SPI OK.
\code
void soes (void *arg)
{
TXPDOsize = SM3_sml = sizeTXPDO ();
RXPDOsize = SM2_sml = sizeRXPDO ();
esc_reset ();
ESC_init ((void *)spi_name);
task_delay (tick_from_ms (200));
// wait until ESC is started up
while ((ESCvar.DLstatus & 0x0001) == 0)
{
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
sizeof (ESCvar.DLstatus));
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
}
// reset ESC to init state
ESC_ALstatus (ESCinit);
...
}
\endcode
- Software Init
- Reset the slave into Init state by writing AL Status register.
- Clear Errors by writing AL Status Code register.
- Stop the Application Layer, basically we disable the SyncManagers
that implicitly block the data exchange.
\code
void soes (void *arg)
{
...
while ((ESCvar.DLstatus & 0x0001) == 0)
{
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
sizeof (ESCvar.DLstatus));
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
}
// reset ESC to init state
ESC_ALstatus (ESCinit);
ESC_ALerror (ALERR_NONE);
ESC_stopmbx ();
ESC_stopinput ();
ESC_stopoutput ();
// application run loop
while (1)
...
}
\endcode
- Application loop
- ALevent handling, ALevent hold information on changes in ALControl or
SyncManagers. ALControl for state changes and SyncManagers for changes written
by EtherCAT in local memory mapped to active SyncManagers
- ESC_state for state handling, such as state step up or down with correct
error and acknowledge response.
- Mailbox handler, generic support of mailboxes used by all Application Layer
protocols.
- On mailbox actions we'll also check if we need to use a specific protocol
handler to handle the incoming or outgoing Mailbox data.
Up until the now we're using the SOES protocol stack without any application specific
calls. Next up we'll look at the application Code, here named DIG_process ().
\code
void soes (void *arg)
{
...
// application run loop
while (1)
{
if((ESCvar.ALstatus & 0x0f) == ESCinit)
{
txpdomap = DEFAULTTXPDOMAP;
rxpdomap = DEFAULTRXPDOMAP;
txpdoitems = DEFAULTTXPDOITEMS;
rxpdoitems = DEFAULTTXPDOITEMS;
}
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
ESCvar.Time = etohl (ESCvar.Time);
ESC_state ();
if (ESC_mbxprocess ())
{
ESC_coeprocess ();
ESC_foeprocess ();
ESC_xoeprocess ();
}
DIG_process ();
};
}
\endcode
\section application Application
The function DIG_process is the User part of the application and could be joined
by more cyclic User functions for executing other parts of the application.
The example code can be split in 2 parts
- Outputs
- Start by evaluating if we're in a state supporting update of outputs, eg.
Operational state.
- If we're in OP we can read the current PDO data in the 3-buffer SyncManager
mapped to the output SM, the default is SyncManager2, we read the ESC RAM address
of SM2 and store it at the local address of the local variable Wb.LED.
We'll read RXPDOsize bytes to trigger a complete SyncManager read.
- After local variables have been refreshed we basically write the local
PDO variables to the User application, ex. a GPIO.
- Basically this is the API of the SOES toward the User Application.
- This function also include a watchdog mechanism, if triggered it will
shutdown the outputs and trigger a state changes to safe operational.
AlError is updated with cause of error to inform the Master.
\code
void RXPDO_update (void)
{
ESC_read (SM2_sma, &Wb.LED, RXPDOsize);
}
void DIG_process (void)
{
if (App.state & APPSTATE_OUTPUT)
{
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2) // SM2 trigger ?
{
RXPDO_update ();
reset_wd ();
gpio_set(GPIO_LED, Wb.LED & BIT(0));
}
if (!wd_cnt)
{
ESC_stopoutput ();
// watchdog, invalid outputs
ESC_ALerror (ALERR_WATCHDOG);
// goto safe-op with error bit set
ESC_ALstatus (ESCsafeop | ESCerror);
wd_trigger = 1;
}
}
else
{
reset_wd ();
}
...
}
\endcode
- Inputs
- Is handled a bit simpler than outputs but in reverse order, the slave will
continue update the inputs in state Safe Operational.
- Here we first read User application data from ex. GPIO and then write to
local PDO variables.
- After the local variables have been refreshed we write those to the current
PDO data 3-buffer SyncManager mapped to the input SM, the default is SyncManager3.
This way we update the ESC RAM address with User Application data accessed by
the EtherCAT master.
\code
void TXPDO_update (void)
{
ESC_write (SM3_sma, &Rb.button, TXPDOsize);
}
void DIG_process (void)
{
...
Rb.button = gpio_get(GPIO_WAKEUP);
Cb.reset_counter++;
Rb.encoder = Cb.reset_counter;
TXPDO_update ();
}
\endcode
\section ApplicationdataProcessdata ApplicationdataProcessdata
To run application data through EtherCAT processdata we need to describe for
the fieldbus what data we have and will read/write. For this we have 3 objects,
the ESI file, SII-EEPROM and CoE Object Dictionary. The first 2 are mandatory
and the third is a very convenient way of describing complex slaves.
Our strategy is to keep the ESI file and the SII-EEPROM as thin as possible to
avoid duplication of data that need to be maintained. Both will hold the bare
minimum of mandatory + optional data to pass CTT. Optional data will be
included to tell EtherCAT that detailed information can be retrieved via CoE
from the OD stored in the slave it self.
\section SII-EEPROM SII-EEPROM
Snapshot from SII information matrix from EtherCAT communication slides.
\image html sii_pdo.png "Our target slave is Fixed PDO and OD"
\image latex sii_pdo.png "Our target slave is Fixed PDO and OD" width=15cm
\section ESI-file ESI-file
Snapshot from ESI tree from EtherCAT communication slides.
\image html esi_pdo.png "mandatory and optional ESI data"
\image latex esi_pdo.png "mandatory and optional ESI data" width=15cm
To briefly give a hint what are describe in the ESI and SII we're listing
a set of included elements marked M for mandatory and O for optional.
\code
- Vendor (M) , Describes the identity.
- Id (M), Hex, EtherCAT Vendor ID, OD 1018.01
- Name (M), NameType, Expedient vendor name
- Descriptions (M), Describes the EtherCAT device(s) using elements.
- Groups (M), Similar devices can be assigned to one group.
- Group (M), One group groups similar devices with slightly different features
- Type (M), A reference handle corresponding to the GroupType value in Description:Devices:Device:Group
- Name (M), Name for this group show by a configuration tool
- Devices (M), Element devices may describe one or several devices with their EtherCAT features such as SyncManagers, FMMUs and Dictionaries
- Device (O), Holds all information about the device like syncmanagers and FMMU, object dictionary, data types and the PDO mapping and assign description
- Device ATT: Physics (M),string, Physics at individual ports
- Type (M), Device identity
- Type ATT:ProductCode="#x98123467"
- Type ATT:RevisionNo="#x00000001"
- Name (M), Detailed name of device shown by a configuration tool (not used for identification)
- GroupType (M), Reference to a group (described in element Groups) to which this device should be assigned to. Name of the handle used in element Groups:Group:Type
- Fmmu (O), String to describe function, Outputs -> RxPDO, Inputs -> TxPDO , MBoxState -> FMMU is used to poll Input Mailbox
- Sm (O), Description of SyncManager including start address and direction.
- MBoxOut Mailbox Data Master -> Slave
- MBoxIn Mailbox Data Slave -> Master
- Outputs Process Data Master -> Slave
- Inputs Process Data Slave -> master
- Sm ATT:DefaultSize="128" , Size
- Sm ATT:StartAddress="#x1000" , Start address
- Sm ATT:ControlByte="#x26" , Settings , Bit [1][0] = 10, Operation mode Mailbox, 00 Buffered 3.
- Sm ATT:Enable="1", Enabled
- Mailbox (O), Description of available mailbox protocols
- Mailbox ATT: DataLinkLayer="true", Support of Mailbox Data Link Layer is mandatory.
- CoE (O), Device support CoE
- CoE (O) ATT: SdoInfo="true" , SDO Information Service
- CoE (O) ATT: CompleteAccess="false" , SDO complete access not supported
- CoE (O) ATT: PdoUpload="true", PDO description uploaded from the slave's object dictionary and SyncManager length calculated based on the same
- Dc (O), describes synchronization modes supported by the device.
- OpMode (O), Definition of supported operation modes
- Name (M), Internal Handle of operation mode
- Desc (O(M)), description of operation mode, recommended, Free Run (no sync), SM Synchronous, DC Synchronous
- AssignActive (M), Value of Latch and Sync Control registers
- Eeprom (O, use is mandatory)
- Data (M)
Or
- ByteSize (M), Byte Size of connected EEPROM device
- ConfigData (M), First 7 words of EEPROM, Configuration Areas
- BootStrap (O), Start address and length of mailboxes for BootStrap
\endcode
So to describe the application we use CoE and Object Dictionary. The mapping between
Object Dictionary and the User Application are done via local variables defined as
user types. The Object Dictionary itself is stored in a matrix where all
the indexes are listed. Every index then have a submatrix with its subindex.
\section ObjectDictionary ObjectDictionary
The Object Dictionary used as example follow the CANopen DS301 ranges.
- 0x0000 - 0x0FFF, Data Type Area
- 0x1000 - 0x1FFF, Communication Area
- 0x2000 - 0x5FFF, Manufacture specific area
- 0x6000 - 0x6FFF, Input area
- 0x7000 - 0x7FFF, Output area
- 0x8000 - 0x8FFF, Configuration area
- 0x9000 - 0x9FFF, Information area
- 0xA000 - 0xAFFF, Diagnosis Area
- 0xB000 - 0xBFFF, Service Transfer Area
- 0xC000 - 0xEFFF, Reserved Area
- 0xF000 - 0xFFFF, Device Area
RxPDO , 0x1600 - 0x17FF
TxPDO , 0x1A00 - 0x1BFF
Example, on how the the OD index are linked.
Top index, SyncManagers Communication Types. In index 0 the 0x04 indicates we have 4
SyncManagers defined. Every SyncManager is assigned a type, in index 1-4, we have standard
settings SM0 = 1, SM1 = 2, SM2 = 3, SM3 = 4 from ETG 1000.6, 5.6.7.4.
- 0, Unused
- 1, MailBox Receive, master to slave
- 2, MailBox Send, slave to master
- 3, Processdata output, master to slave
- 4, Processdata input, slave to master
\code
objectlist.h
FLASHSTORE _objectlist SDOobjects[] =
...
{0x1C00, OTYPE_ARRAY, 4, 0, &acName1C00[0], &SDO1C00[0]},
FLASHSTORE _objd SDO1C00[] =
{ {0x00, DTYPE_UNSIGNED8, 8, ATYPE_R, &acNameNOE[0], 0x04, nil},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_R, &acName1C00_01[0], 0x01, nil},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_R, &acName1C00_02[0], 0x02, nil},
{0x03, DTYPE_UNSIGNED8, 8, ATYPE_R, &acName1C00_03[0], 0x03, nil},
{0x04, DTYPE_UNSIGNED8, 8, ATYPE_R, &acName1C00_04[0], 0x04, nil}
\endcode
SyncManagers channels 0-31 are listed in SDO1C10-SDO1C2F. If we look
at SyncManager channel 2, we see.
- Type 3, Processdata output, master to slave
It got one RxPDO index 0x1600 connected, and the submatrix for 0x1600 link
one PDO object index 0x7000 subindex 1. The output object 0x70000108 give
you the index 0x7000, subindex 1 and PDO object length 1(byte).
\code
objectlist.h
FLASHSTORE _objd SDO1C12[] =
{ {0x00, DTYPE_UNSIGNED8, 8, ATYPE_R, &acNameNOE[0], 0x01, nil},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_R, &acNameMO[0], 0x1600, nil}
};
FLASHSTORE _objd SDO1600[] =
{ {0x00, DTYPE_UNSIGNED8, 8, ATYPE_R, &acNameNOE[0], 0x01, nil},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_R, &acNameMO[0], 0x70000108, nil}
};
\endcode
At PDO level we make the connection between the local application and
the object dictionary. For all subindex in the PDO the last element
is the address to the local variable.
\code
objectlist.h
FLASHSTORE _objd SDO7000[] =
{ {0x00, DTYPE_UNSIGNED8, 8, ATYPE_R, &acNameNOE[0], 0x01, nil},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RW, &acName7000_01[0], 0, &(Wb.LED)}
};
utypes.h
typedef struct
{
uint8 LED;
} _Wbuffer;
\endcode
Beside SyncManager to PDO mapping we also have mandatory data as
0x1000 Device Type
0x1018 Object Identity
0x10C0 SyncManager Communication Type, as we used as top index when
figuring out our PDOs in the Object Dictionary.
For a complete description of the object dictionary you can get guidance
by the ETG1000.6 EcatAlProtocols
A useful feature is the Asynchronous use of SDO parameters. In the example
we have Parameter set holding an encoder scale value, just for show we also
have a read only mirror value of the encoder scale. Parameters defined as a
RW SDO parameter and can be written/read by SDO Download or Upload. In
addition there is a ESC_objecthandler Hook on SDO Download where you can
add additional logic, ex. we execute the mirror of the encoder scale value
by assigning the encoder scale value to the mirror.
\code
objectlist.h
FLASHSTORE _objd SDO7100[] =
{ {0x00, DTYPE_UNSIGNED8, 8, ATYPE_R, &acNameNOE[0], 0x02, nil},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, &acName7100_01[0], 0, &(encoder_scale)},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_R, &acName7100_02[0], 0, &(encoder_scale_mirror)}
};
soes.c
void ESC_objecthandler (uint16 index, uint8 subindex)
{
switch (index)
{
...
case 0x7100:
{
switch (subindex)
{
case 0x01:
{
encoder_scale_mirror = encoder_scale;
break;
}
}
break;
}
...
}
\endcode
This tutorial is just one way of doing it.
Enjoy and happy coding!
Andreas Karlsson, rt-labs AB, www.rt-labs.com
*/

View File

@@ -0,0 +1,386 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
#include <stddef.h>
#include "esc.h"
#include "esc_coe.h"
#include "esc_foe.h"
#include "esc_eoe.h"
#include "ecat_slv.h"
#define IS_RXPDO(index) ((index) >= 0x1600 && (index) < 0x1800)
#define IS_TXPDO(index) ((index) >= 0x1A00 && (index) < 0x1C00)
/* Global variables used by the stack */
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE, MBXSIZEBOOT)];
_MBXcontrol MBXcontrol[MBXBUFFERS];
_SMmap SMmap2[MAX_MAPPINGS_SM2];
_SMmap SMmap3[MAX_MAPPINGS_SM3];
_ESCvar ESCvar;
/* Private variables */
static volatile int watchdog;
#if MAX_MAPPINGS_SM2 > 0
static uint8_t rxpdo[MAX_RXPDO_SIZE] __attribute__((aligned(8)));
#else
extern uint8_t *rxpdo;
#endif
#if MAX_MAPPINGS_SM3 > 0
static uint8_t txpdo[MAX_TXPDO_SIZE] __attribute__((aligned(8)));
#else
extern uint8_t *txpdo;
#endif
/** Function to pre-qualify the incoming SDO download.
*
* @param[in] index = index of SDO download request to check
* @param[in] sub-index = sub-index of SDO download request to check
* @return SDO abort code, or 0 on success
*/
uint32_t ESC_download_pre_objecthandler(uint16_t index,
uint8_t subindex,
void *data,
size_t size,
uint16_t flags)
{
if (IS_RXPDO(index) ||
IS_TXPDO(index) ||
index == RX_PDO_OBJIDX ||
index == TX_PDO_OBJIDX)
{
uint8_t minSub = ((flags & COMPLETE_ACCESS_FLAG) == 0) ? 0 : 1;
if (subindex > minSub && COE_maxSub(index) != 0)
{
return ABORT_SUBINDEX0_NOT_ZERO;
}
}
if (ESCvar.pre_object_download_hook)
{
return (ESCvar.pre_object_download_hook)(index,
subindex,
data,
size,
flags);
}
return 0;
}
/** Hook called from the slave stack SDO Download handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO download request to handle
* @param[in] sub-index = sub-index of SDO download request to handle
* @return SDO abort code, or 0 on success
*/
uint32_t ESC_download_post_objecthandler(uint16_t index, uint8_t subindex, uint16_t flags)
{
if (ESCvar.post_object_download_hook != NULL)
{
return (ESCvar.post_object_download_hook)(index, subindex, flags);
}
return 0;
}
/** Function to pre-qualify the incoming SDO upload.
*
* @param[in] index = index of SDO upload request to handle
* @param[in] sub-index = sub-index of SDO upload request to handle
* @return SDO abort code, or 0 on success
*/
uint32_t ESC_upload_pre_objecthandler(uint16_t index,
uint8_t subindex,
void *data,
size_t size,
uint16_t flags)
{
if (ESCvar.pre_object_upload_hook != NULL)
{
return (ESCvar.pre_object_upload_hook)(index,
subindex,
data,
size,
flags);
}
return 0;
}
/** Hook called from the slave stack SDO Upload handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO upload request to handle
* @param[in] sub-index = sub-index of SDO upload request to handle
* @return SDO abort code, or 0 on success
*/
uint32_t ESC_upload_post_objecthandler(uint16_t index, uint8_t subindex, uint16_t flags)
{
if (ESCvar.post_object_upload_hook != NULL)
{
return (ESCvar.post_object_upload_hook)(index, subindex, flags);
}
return 0;
}
/** Hook called from the slave stack ESC_stopoutputs to act on state changes
* forcing us to stop outputs. Here we can set them to a safe state.
*/
void APP_safeoutput(void)
{
DPRINT("APP_safeoutput\n");
if (ESCvar.safeoutput_override != NULL)
{
(ESCvar.safeoutput_override)();
}
}
/** Write local process data to Sync Manager 3, Master Inputs.
*/
void TXPDO_update(void)
{
if (ESCvar.txpdo_override != NULL)
{
(ESCvar.txpdo_override)();
}
else
{
if (MAX_MAPPINGS_SM3 > 0)
{
COE_pdoPack(txpdo, ESCvar.sm3mappings, SMmap3);
}
ESC_write(ESC_SM3_sma, txpdo, ESCvar.ESC_SM3_sml);
}
}
/** Read Sync Manager 2 to local process data, Master Outputs.
*/
void RXPDO_update(void)
{
if (ESCvar.rxpdo_override != NULL)
{
(ESCvar.rxpdo_override)();
}
else
{
ESC_read(ESC_SM2_sma, rxpdo, ESCvar.ESC_SM2_sml);
if (MAX_MAPPINGS_SM2 > 0)
{
COE_pdoUnpack(rxpdo, ESCvar.sm2mappings, SMmap2);
}
}
}
/* Set the watchdog count value, don't have any affect when using
* HW watchdog 0x4xx
*
* @param[in] watchdogcnt = new watchdog count value
*/
void APP_setwatchdog(int watchdogcnt)
{
CC_ATOMIC_SET(ESCvar.watchdogcnt, watchdogcnt);
}
/* Function to update local I/O, call read ethercat outputs, call
* write ethercat inputs. Implement watch-dog counter to count-out if we have
* made state change affecting the App.state.
*/
void DIG_process(uint16_t ALEvent, uint8_t flags)
{
/* Handle watchdog */
if ((flags & DIG_PROCESS_WD_FLAG) > 0)
{
if (CC_ATOMIC_GET(watchdog) > 0)
{
CC_ATOMIC_SUB(watchdog, 1);
}
if ((CC_ATOMIC_GET(watchdog) <= 0) &&
((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0))
{
DPRINT("DIG_process watchdog expired\n");
ESC_ALstatusgotoerror((ESCsafeop | ESCerror), ALERR_WATCHDOG);
}
else if (((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) == 0))
{
CC_ATOMIC_SET(watchdog, ESCvar.watchdogcnt);
}
}
/* Handle Outputs */
if ((flags & DIG_PROCESS_OUTPUTS_FLAG) > 0)
{
if (((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0) &&
(ALEvent & ESCREG_ALEVENT_SM2))
{
RXPDO_update();
CC_ATOMIC_SET(watchdog, ESCvar.watchdogcnt);
/* Set outputs */
cb_set_outputs();
}
else if (ALEvent & ESCREG_ALEVENT_SM2)
{
RXPDO_update();
}
}
/* Call application */
if ((flags & DIG_PROCESS_APP_HOOK_FLAG) > 0)
{
/* Call application callback if set */
if (ESCvar.application_hook != NULL)
{
(ESCvar.application_hook)();
}
}
/* Handle Inputs */
if ((flags & DIG_PROCESS_INPUTS_FLAG) > 0)
{
if (CC_ATOMIC_GET(ESCvar.App.state) > 0)
{
/* Update inputs */
cb_get_inputs();
TXPDO_update();
}
}
}
/*
* Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application
* control what interrupts that should be served and re-activated with
* event mask argument
*/
void ecat_slv_worker(uint32_t event_mask)
{
do
{
/* Check the state machine */
ESC_state();
/* Check the SM activation event */
ESC_sm_act_event();
/* Check mailboxes */
while ((ESC_mbxprocess() > 0) || (ESCvar.txcue > 0))
{
ESC_coeprocess();
#if USE_FOE
ESC_foeprocess();
#endif
#if USE_EOE
ESC_eoeprocess();
#endif
ESC_xoeprocess();
}
#if USE_EOE
ESC_eoeprocess_tx();
#endif
/* Call emulated eeprom handler if set */
if (ESCvar.esc_hw_eep_handler != NULL)
{
(ESCvar.esc_hw_eep_handler)();
}
CC_ATOMIC_SET(ESCvar.ALevent, ESC_ALeventread());
} while (ESCvar.ALevent & event_mask);
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | event_mask);
}
/*
* Polling function. It should be called periodically for an application
* when only SM2/DC interrupt is active.
* Read and handle events for the EtherCAT state, status, mailbox and eeprom.
*/
void ecat_slv_poll(void)
{
/* Read local time from ESC*/
ESC_read(ESCREG_LOCALTIME, (void *)&ESCvar.Time, sizeof(ESCvar.Time));
ESCvar.Time = etohl(ESCvar.Time);
/* Check the state machine */
ESC_state();
/* Check the SM activation event */
ESC_sm_act_event();
/* Check mailboxes */
if (ESC_mbxprocess())
{
ESC_coeprocess();
#if USE_FOE
ESC_foeprocess();
#endif
#if USE_EOE
ESC_eoeprocess();
#endif
ESC_xoeprocess();
}
#if USE_EOE
ESC_eoeprocess_tx();
#endif
/* Call emulated eeprom handler if set */
if (ESCvar.esc_hw_eep_handler != NULL)
{
(ESCvar.esc_hw_eep_handler)();
}
}
/*
* Poll all events in a free-run application
*/
void ecat_slv(void)
{
ecat_slv_poll();
DIG_process(ESC_ALeventread(), DIG_PROCESS_WD_FLAG | DIG_PROCESS_OUTPUTS_FLAG |
DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
}
/*
* Initialize the slave stack.
*/
void ecat_slv_init(esc_cfg_t *config)
{
/* Init watchdog */
watchdog = config->watchdog_cnt;
/* Call stack configuration */
ESC_config(config);
/* Call HW init */
ESC_init(config);
/* wait until ESC is started up */
while ((ESCvar.DLstatus & 0x0001) == 0)
{
ESC_read(ESCREG_DLSTATUS, (void *)&ESCvar.DLstatus,
sizeof(ESCvar.DLstatus));
ESCvar.DLstatus = etohs(ESCvar.DLstatus);
}
#if USE_FOE
/* Init FoE */
FOE_init();
#endif
#if USE_EOE
/* Init EoE */
EOE_init();
#endif
/* reset ESC to init state */
ESC_ALstatus(ESCinit);
ESC_ALerror(ALERR_NONE);
ESC_stopmbx();
ESC_stopinput();
ESC_stopoutput();
/* Init Object Dictionary default values */
COE_initDefaultValues();
}

View File

@@ -0,0 +1,69 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
#ifndef __ECAT_SLV_H__
#define __ECAT_SLV_H__
#include "ecat_options.h"
#include "esc.h"
/**
* This function is called when to get input values
*/
void cb_get_inputs();
/**
* This function is called when to set outputs values
*/
void cb_set_outputs();
/** Set the watchdog count value
*
* @param[in] watchdogcnt = new watchdog count value
*/
void APP_setwatchdog(int watchdogcnt);
#define DIG_PROCESS_INPUTS_FLAG 0x01
#define DIG_PROCESS_OUTPUTS_FLAG 0x02
#define DIG_PROCESS_WD_FLAG 0x04
#define DIG_PROCESS_APP_HOOK_FLAG 0x08
/** Implements the watch-dog counter to count if we should make a state change
* due to missing incoming SM2 events. Updates local I/O and run the application
* in the following order, call read EtherCAT outputs, execute user provided
* application hook and call write EtherCAT inputs.
*
* @param[in] flags = User input what to execute
*/
void DIG_process(uint16_t ALEvent, uint8_t flags);
/**
* Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application
* control what interrupts that should be served and re-activated with
* event mask argument
*
* @param[in] event_mask = Event mask for interrupts to serve and re-activate
* after served
*/
void ecat_slv_worker(uint32_t event_mask);
/**
* Poll SM0/1, EEPROM and AL CONTROL events in a SM/DC synchronization
* application
*/
void ecat_slv_poll(void);
/**
* Poll all events in a free-run application
*/
void ecat_slv(void);
/**
* Initialize the slave stack
*
* @param[in] config = User input how to configure the stack
*/
void ecat_slv_init(esc_cfg_t *config);
#endif /* __ECAT_SLV_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,769 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* Headerfile for esc.h
*/
#ifndef __esc__
#define __esc__
#include <stdbool.h>
#include <cc.h>
#include <esc_coe.h>
#include "ecat_options.h"
#define ESCREG_ADDRESS 0x0010
#define ESCREG_DLSTATUS 0x0110
#define ESCREG_ALCONTROL 0x0120
#define ESCREG_ALSTATUS 0x0130
#define ESCREG_ALERROR 0x0134
#define ESCREG_ALEVENTMASK 0x0204
#define ESCREG_ALEVENT 0x0220
#define ESCREG_ALEVENT_SM_MASK 0x0310
#define ESCREG_ALEVENT_SMCHANGE 0x0010
#define ESCREG_ALEVENT_CONTROL 0x0001
#define ESCREG_ALEVENT_DC_LATCH 0x0002
#define ESCREG_ALEVENT_DC_SYNC0 0x0004
#define ESCREG_ALEVENT_DC_SYNC1 0x0008
#define ESCREG_ALEVENT_EEP 0x0020
#define ESCREG_ALEVENT_WD 0x0040
#define ESCREG_ALEVENT_SM0 0x0100
#define ESCREG_ALEVENT_SM1 0x0200
#define ESCREG_ALEVENT_SM2 0x0400
#define ESCREG_ALEVENT_SM3 0x0800
#define ESCREG_WDSTATUS 0x0440
#define ESCREG_EECONTSTAT 0x0502
#define ESCREG_EEDATA 0x0508
#define ESCREG_SM0 0x0800
#define ESCREG_SM0STATUS (ESCREG_SM0 + 5)
#define ESCREG_SM0ACTIVATE (ESCREG_SM0 + 6)
#define ESCREG_SM0PDI (ESCREG_SM0 + 7)
#define ESCREG_SM1 (ESCREG_SM0 + 0x08)
#define ESCREG_SM2 (ESCREG_SM0 + 0x10)
#define ESCREG_SM3 (ESCREG_SM0 + 0x18)
#define ESCREG_LOCALTIME 0x0910
#define ESCREG_LOCALTIME_OFFSET 0x0920
#define ESCREG_SYNC_ACT 0x0981
#define ESCREG_SYNC_ACT_ACTIVATED 0x01
#define ESCREG_SYNC_SYNC0_EN 0x02
#define ESCREG_SYNC_SYNC1_EN 0x04
#define ESCREG_SYNC_AUTO_ACTIVATED 0x08
#define ESCREG_SYNC0_CYCLE_TIME 0x09A0
#define ESCREG_SYNC1_CYCLE_TIME 0x09A4
#define ESCREG_SMENABLE_BIT 0x01
#define ESCREG_AL_STATEMASK 0x001f
#define ESCREG_AL_ALLBUTINITMASK 0x0e
#define ESCREG_AL_ERRACKMASK 0x0f
#define SYNCTYPE_SUPPORT_FREERUN 0x01
#define SYNCTYPE_SUPPORT_SYNCHRON 0x02
#define SYNCTYPE_SUPPORT_DCSYNC0 0x04
#define SYNCTYPE_SUPPORT_DCSYNC1 0x08
#define SYNCTYPE_SUPPORT_SUBCYCLE 0x10
#define ESCinit 0x01
#define ESCpreop 0x02
#define ESCboot 0x03
#define ESCsafeop 0x04
#define ESCop 0x08
#define ESCerror 0x10
#define INIT_TO_INIT 0x11
#define INIT_TO_PREOP 0x21
#define INIT_TO_BOOT 0x31
#define INIT_TO_SAFEOP 0x41
#define INIT_TO_OP 0x81
#define PREOP_TO_INIT 0x12
#define PREOP_TO_PREOP 0x22
#define PREOP_TO_BOOT 0x32
#define PREOP_TO_SAFEOP 0x42
#define PREOP_TO_OP 0x82
#define BOOT_TO_INIT 0x13
#define BOOT_TO_PREOP 0x23
#define BOOT_TO_BOOT 0x33
#define BOOT_TO_SAFEOP 0x43
#define BOOT_TO_OP 0x83
#define SAFEOP_TO_INIT 0x14
#define SAFEOP_TO_PREOP 0x24
#define SAFEOP_TO_BOOT 0x34
#define SAFEOP_TO_SAFEOP 0x44
#define SAFEOP_TO_OP 0x84
#define OP_TO_INIT 0x18
#define OP_TO_PREOP 0x28
#define OP_TO_BOOT 0x38
#define OP_TO_SAFEOP 0x48
#define OP_TO_OP 0x88
#define ALERR_NONE 0x0000
#define ALERR_UNSPECIFIEDERROR 0x0001
#define ALERR_NOMEMORY 0x0002
#define ALERR_INVALIDSTATECHANGE 0x0011
#define ALERR_UNKNOWNSTATE 0x0012
#define ALERR_BOOTNOTSUPPORTED 0x0013
#define ALERR_NOVALIDFIRMWARE 0x0014
#define ALERR_INVALIDBOOTMBXCONFIG 0x0015
#define ALERR_INVALIDMBXCONFIG 0x0016
#define ALERR_INVALIDSMCONFIG 0x0017
#define ALERR_NOVALIDINPUTS 0x0018
#define ALERR_NOVALIDOUTPUTS 0x0019
#define ALERR_SYNCERROR 0x001A
#define ALERR_WATCHDOG 0x001B
#define ALERR_INVALIDSYNCMANAGERTYP 0x001C
#define ALERR_INVALIDOUTPUTSM 0x001D
#define ALERR_INVALIDINPUTSM 0x001E
#define ALERR_INVALIDWDTCFG 0x001F
#define ALERR_SLAVENEEDSCOLDSTART 0x0020
#define ALERR_SLAVENEEDSINIT 0x0021
#define ALERR_SLAVENEEDSPREOP 0x0022
#define ALERR_SLAVENEEDSSAFEOP 0x0023
#define ALERR_INVALIDINPUTMAPPING 0x0024
#define ALERR_INVALIDOUTPUTMAPPING 0x0025
#define ALERR_INCONSISTENTSETTINGS 0x0026
#define ALERR_FREERUNNOTSUPPORTED 0x0027
#define ALERR_SYNCNOTSUPPORTED 0x0028
#define ALERR_FREERUNNEEDS3BUFFMODE 0x0029
#define ALERR_BACKGROUNDWATCHDOG 0x002A
#define ALERR_NOVALIDINPUTSOUTPUTS 0x002B
#define ALERR_FATALSYNCERROR 0x002C
#define ALERR_NOSYNCERROR 0x002D
#define ALERR_INVALIDINPUTFMMUCFG 0x002E
#define ALERR_DCINVALIDSYNCCFG 0x0030
#define ALERR_INVALIDDCLATCHCFG 0x0031
#define ALERR_PLLERROR 0x0032
#define ALERR_DCSYNCIOERROR 0x0033
#define ALERR_DCSYNCTIMEOUT 0x0034
#define ALERR_DCSYNCCYCLETIME 0x0035
#define ALERR_DCSYNC0CYCLETIME 0x0036
#define ALERR_DCSYNC1CYCLETIME 0x0037
#define ALERR_MBXAOE 0x0041
#define ALERR_MBXEOE 0x0042
#define ALERR_MBXCOE 0x0043
#define ALERR_MBXFOE 0x0044
#define ALERR_MBXSOE 0x0045
#define ALERR_MBXVOE 0x004F
#define ALERR_EEPROMNOACCESS 0x0050
#define ALERR_EEPROMERROR 0x0051
#define ALERR_SLAVERESTARTEDLOCALLY 0x0060
#define ALERR_DEVICEIDVALUEUPDATED 0x0061
#define ALERR_APPLCTRLAVAILABLE 0x00f0
#define ALERR_UNKNOWN 0xffff
#define MBXERR_SYNTAX 0x0001
#define MBXERR_UNSUPPORTEDPROTOCOL 0x0002
#define MBXERR_INVALIDCHANNEL 0x0003
#define MBXERR_SERVICENOTSUPPORTED 0x0004
#define MBXERR_INVALIDHEADER 0x0005
#define MBXERR_SIZETOOSHORT 0x0006
#define MBXERR_NOMOREMEMORY 0x0007
#define MBXERR_INVALIDSIZE 0x0008
#define ABORT_NOTOGGLE 0x05030000
#define ABORT_TRANSFER_TIMEOUT 0x05040000
#define ABORT_UNKNOWN 0x05040001
#define ABORT_INVALID_BLOCK_SIZE 0x05040002
#define ABORT_INVALID_SEQUENCE_NUMBER 0x05040003
#define ABORT_BLOCK_CRC_ERROR 0x05040004
#define ABORT_OUT_OF_MEMORY 0x05040005
#define ABORT_UNSUPPORTED 0x06010000
#define ABORT_WRITEONLY 0x06010001
#define ABORT_READONLY 0x06010002
#define ABORT_SUBINDEX0_NOT_ZERO 0x06010003
#define ABORT_CA_NOT_SUPPORTED 0x06010004
#define ABORT_EXCEEDS_MBOX_SIZE 0x06010005
#define ABORT_SDO_DOWNLOAD_BLOCKED 0x06010006
#define ABORT_NOOBJECT 0x06020000
#define ABORT_MAPPING_OBJECT_ERROR 0x06040041
#define ABORT_MAPPING_LENGTH_ERROR 0x06040042
#define ABORT_GENERAL_PARAMETER_ERROR 0x06040043
#define ABORT_GENERAL_DEVICE_ERROR 0x06040047
#define ABORT_HARDWARE_ERROR 0x06060000
#define ABORT_TYPEMISMATCH 0x06070010
#define ABORT_DATATYPE_TOO_HIGH 0x06070012
#define ABORT_DATATYPE_TOO_LOW 0x06070013
#define ABORT_NOSUBINDEX 0x06090011
#define ABORT_VALUE_EXCEEDED 0x06090030
#define ABORT_VALUE_TOO_HIGH 0x06090031
#define ABORT_VALUE_TOO_LOW 0x06090032
#define ABORT_MODULE_LIST_MISMATCH 0x06090033
#define ABORT_MAX_VAL_LESS_THAN_MIN_VAL 0x06090036
#define ABORT_RESOURCE_NOT_AVAILABLE 0x060A0023
#define ABORT_GENERALERROR 0x08000000
#define ABORT_DATA_STORE_ERROR 0x08000020
#define ABORT_DATA_STORE_LOCAL_ERROR 0x08000021
#define ABORT_NOTINTHISSTATE 0x08000022
#define ABORT_OBJECT_DICTIONARY_ERROR 0x08000023
#define ABORT_NO_DATA_AVAILABLE 0x08000024
#define MBXstate_idle 0x00
#define MBXstate_inclaim 0x01
#define MBXstate_outclaim 0x02
#define MBXstate_outreq 0x03
#define MBXstate_outpost 0x04
#define MBXstate_backup 0x05
#define MBXstate_again 0x06
#define COE_DEFAULTLENGTH 0x0a
#define COE_HEADERSIZE 0x0a
#define COE_SEGMENTHEADERSIZE 0x03
#define COE_SDOREQUEST 0x02
#define COE_SDORESPONSE 0x03
#define COE_SDOINFORMATION 0x08
#define COE_COMMAND_SDOABORT 0x80
#define COE_COMMAND_UPLOADREQUEST 0x40
#define COE_COMMAND_UPLOADRESPONSE 0x40
#define COE_COMMAND_UPLOADSEGMENT 0x00
#define COE_COMMAND_UPLOADSEGREQ 0x60
#define COE_COMMAND_DOWNLOADREQUEST 0x20
#define COE_COMMAND_DOWNLOADRESPONSE 0x60
#define COE_COMMAND_DOWNLOADSEGREQ 0x00
#define COE_COMMAND_DOWNLOADSEGRESP 0x20
#define COE_COMMAND_LASTSEGMENTBIT 0x01
#define COE_SIZE_INDICATOR 0x01
#define COE_EXPEDITED_INDICATOR 0x02
#define COE_COMPLETEACCESS 0x10
#define COE_TOGGLEBIT 0x10
#define COE_INFOERROR 0x07
#define COE_GETODLISTRESPONSE 0x02
#define COE_GETODRESPONSE 0x04
#define COE_ENTRYDESCRIPTIONRESPONSE 0x06
#define COE_VALUEINFO_ACCESS 0x01
#define COE_VALUEINFO_OBJECT 0x02
#define COE_VALUEINFO_MAPPABLE 0x04
#define COE_VALUEINFO_TYPE 0x08
#define COE_VALUEINFO_DEFAULT 0x10
#define COE_VALUEINFO_MINIMUM 0x20
#define COE_VALUEINFO_MAXIMUM 0x40
#define COE_MINIMUM_LENGTH 8
#define MBXERR 0x00
#define MBXAOE 0x01
#define MBXEOE 0x02
#define MBXCOE 0x03
#define MBXFOE 0x04
#define MBXODL 0x10
#define MBXOD 0x20
#define MBXED 0x30
#define MBXSEU 0x40
#define MBXSED 0x50
#define SMRESULT_ERRSM0 0x01
#define SMRESULT_ERRSM1 0x02
#define SMRESULT_ERRSM2 0x04
#define SMRESULT_ERRSM3 0x08
#define FOE_ERR_NOTDEFINED 0x8000
#define FOE_ERR_NOTFOUND 0x8001
#define FOE_ERR_ACCESS 0x8002
#define FOE_ERR_DISKFULL 0x8003
#define FOE_ERR_ILLEGAL 0x8004
#define FOE_ERR_PACKETNO 0x8005
#define FOE_ERR_EXISTS 0x8006
#define FOE_ERR_NOUSER 0x8007
#define FOE_ERR_BOOTSTRAPONLY 0x8008
#define FOE_ERR_NOTINBOOTSTRAP 0x8009
#define FOE_ERR_NORIGHTS 0x800A
#define FOE_ERR_PROGERROR 0x800B
#define FOE_ERR_CHECKSUM 0x800C
#define FOE_OP_RRQ 1
#define FOE_OP_WRQ 2
#define FOE_OP_DATA 3
#define FOE_OP_ACK 4
#define FOE_OP_ERR 5
#define FOE_OP_BUSY 6
#define FOE_READY 0
#define FOE_WAIT_FOR_ACK 1
#define FOE_WAIT_FOR_FINAL_ACK 2
#define FOE_WAIT_FOR_DATA 3
#define EOE_RESULT_SUCCESS 0x0000
#define EOE_RESULT_UNSPECIFIED_ERROR 0x0001
#define EOE_RESULT_UNSUPPORTED_FRAME_TYPE 0x0002
#define EOE_RESULT_NO_IP_SUPPORT 0x0201
#define EOE_RESULT_NO_DHCP_SUPPORT 0x0202
#define EOE_RESULT_NO_FILTER_SUPPORT 0x0401
#define APPSTATE_IDLE 0x00
#define APPSTATE_INPUT 0x01
#define APPSTATE_OUTPUT 0x02
#define PREALLOC_FACTOR 3
#define PREALLOC_BUFFER_SIZE (PREALLOC_FACTOR * MBXSIZE)
typedef struct sm_cfg
{
uint16_t cfg_sma;
uint16_t cfg_sml;
uint16_t cfg_sme;
uint8_t cfg_smc;
uint8_t cfg_smact;
}sm_cfg_t;
typedef struct esc_cfg
{
void * user_arg;
int use_interrupt;
int watchdog_cnt;
bool skip_default_initialization;
void (*set_defaults_hook) (void);
void (*pre_state_change_hook) (uint8_t * as, uint8_t * an);
void (*post_state_change_hook) (uint8_t * as, uint8_t * an);
void (*application_hook) (void);
void (*safeoutput_override) (void);
uint32_t (*pre_object_download_hook) (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags);
uint32_t (*post_object_download_hook) (uint16_t index,
uint8_t subindex,
uint16_t flags);
uint32_t (*pre_object_upload_hook) (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags);
uint32_t (*post_object_upload_hook) (uint16_t index,
uint8_t subindex,
uint16_t flags);
void (*rxpdo_override) (void);
void (*txpdo_override) (void);
void (*esc_hw_interrupt_enable) (uint32_t mask);
void (*esc_hw_interrupt_disable) (uint32_t mask);
void (*esc_hw_eep_handler) (void);
uint16_t (*esc_check_dc_handler) (void);
} esc_cfg_t;
typedef struct
{
uint8_t state;
} _App;
// Attention! this struct is always little-endian
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint16_t PSA;
uint16_t Length;
#if defined(EC_LITTLE_ENDIAN)
uint8_t Mode:2;
uint8_t Direction:2;
uint8_t IntECAT:1;
uint8_t IntPDI:1;
uint8_t WTE:1;
uint8_t R1:1;
uint8_t IntW:1;
uint8_t IntR:1;
uint8_t R2:1;
uint8_t MBXstat:1;
uint8_t BUFstat:2;
uint8_t R3:2;
uint8_t ECsm:1;
uint8_t ECrep:1;
uint8_t ECr4:4;
uint8_t EClatchEC:1;
uint8_t EClatchPDI:1;
uint8_t PDIsm:1;
uint8_t PDIrep:1;
uint8_t PDIr5:6;
#endif
#if defined(EC_BIG_ENDIAN)
uint8_t R1:1;
uint8_t WTE:1;
uint8_t IntPDI:1;
uint8_t IntECAT:1;
uint8_t Direction:2;
uint8_t Mode:2;
uint8_t R3:2;
uint8_t BUFstat:2;
uint8_t MBXstat:1;
uint8_t R2:1;
uint8_t IntR:1;
uint8_t IntW:1;
uint8_t EClatchPDI:1;
uint8_t EClatchEC:1;
uint8_t ECr4:4;
uint8_t ECrep:1;
uint8_t ECsm:1;
uint8_t PDIr5:6;
uint8_t PDIrep:1;
uint8_t PDIsm:1;
#endif
} _ESCsm;
CC_PACKED_END
/* Attention! this struct is always little-endian */
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint16_t PSA;
uint16_t Length;
uint8_t Command;
uint8_t Status;
uint8_t ActESC;
uint8_t ActPDI;
} _ESCsm2;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint16_t PSA;
uint16_t Length;
uint8_t Command;
} _ESCsmCompact;
CC_PACKED_END
typedef struct
{
/* Configuration input is saved so the user variable may go out-of-scope */
int use_interrupt;
sm_cfg_t mb[2];
sm_cfg_t mbboot[2];
bool skip_default_initialization;
void (*set_defaults_hook) (void);
void (*pre_state_change_hook) (uint8_t * as, uint8_t * an);
void (*post_state_change_hook) (uint8_t * as, uint8_t * an);
void (*application_hook) (void);
void (*safeoutput_override) (void);
uint32_t (*pre_object_download_hook) (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags);
uint32_t (*post_object_download_hook) (uint16_t index,
uint8_t subindex,
uint16_t flags);
uint32_t (*pre_object_upload_hook) (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags);
uint32_t (*post_object_upload_hook) (uint16_t index,
uint8_t subindex,
uint16_t flags);
void (*rxpdo_override) (void);
void (*txpdo_override) (void);
void (*esc_hw_interrupt_enable) (uint32_t mask);
void (*esc_hw_interrupt_disable) (uint32_t mask);
void (*esc_hw_eep_handler) (void);
uint16_t (*esc_check_dc_handler) (void);
uint8_t MBXrun;
size_t activembxsize;
sm_cfg_t * activemb0;
sm_cfg_t * activemb1;
uint16_t ESC_SM2_sml;
uint16_t ESC_SM3_sml;
uint8_t dcsync;
uint16_t synccounterlimit;
uint16_t ALstatus;
uint16_t ALcontrol;
uint16_t ALerror;
uint16_t DLstatus;
uint16_t address;
uint8_t mbxcnt;
uint8_t mbxincnt;
uint8_t mbxoutpost;
uint8_t mbxbackup;
uint8_t xoe;
uint8_t txcue;
uint8_t mbxfree;
uint8_t segmented;
void *data;
uint16_t entries;
uint16_t frags;
uint16_t fragsleft;
uint16_t index;
uint8_t subindex;
uint16_t flags;
uint8_t toggle;
int sm2mappings;
int sm3mappings;
uint8_t SMtestresult;
uint32_t PrevTime;
_ESCsm SM[4];
/* Volatile since it may be read from ISR */
volatile int watchdogcnt;
volatile uint32_t Time;
volatile uint16_t ALevent;
volatile int8_t synccounter;
volatile _App App;
uint8_t mbxdata[PREALLOC_BUFFER_SIZE];
} _ESCvar;
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint16_t length;
uint16_t address;
#if defined(EC_LITTLE_ENDIAN)
uint8_t channel:6;
uint8_t priority:2;
uint8_t mbxtype:4;
uint8_t mbxcnt:4;
#endif
#if defined(EC_BIG_ENDIAN)
uint8_t priority:2;
uint8_t channel:6;
uint8_t mbxcnt:4;
uint8_t mbxtype:4;
#endif
} _MBXh;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
_MBXh header;
uint8_t b[0];
} _MBX;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint16_t numberservice;
} _COEh;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
#if defined(EC_LITTLE_ENDIAN)
uint8_t opcode:7;
uint8_t incomplete:1;
#endif
#if defined(EC_BIG_ENDIAN)
uint8_t incomplete:1;
uint8_t opcode:7;
#endif
uint8_t reserved;
uint16_t fragmentsleft;
} _INFOh;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
_MBXh mbxheader;
uint16_t type;
uint16_t detail;
} _MBXerr;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
_MBXh mbxheader;
_COEh coeheader;
uint8_t command;
uint16_t index;
uint8_t subindex;
uint32_t size;
} _COEsdo;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
_MBXh mbxheader;
_COEh coeheader;
_INFOh infoheader;
uint16_t index;
uint16_t datatype;
uint8_t maxsub;
uint8_t objectcode;
char name;
} _COEobjdesc;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
_MBXh mbxheader;
_COEh coeheader;
_INFOh infoheader;
uint16_t index;
uint8_t subindex;
uint8_t valueinfo;
uint16_t datatype;
uint16_t bitlength;
uint16_t access;
char name;
} _COEentdesc;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint8_t opcode;
uint8_t reserved;
union
{
uint32_t password;
uint32_t packetnumber;
uint32_t errorcode;
};
} _FOEh;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
_MBXh mbxheader;
_FOEh foeheader;
union
{
char filename[0];
uint8_t data[0];
char errortext[0];
};
} _FOE;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint16_t frameinfo1;
union
{
uint16_t frameinfo2;
uint16_t result;
};
} _EOEh;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
_MBXh mbxheader;
_EOEh eoeheader;
uint8_t data[0];
} _EOE;
CC_PACKED_END
/* state definition in mailbox
* 0 : idle
* 1 : claimed for inbox
* 2 : claimed for outbox
* 3 : request post outbox
* 4 : outbox posted not send
* 5 : backup outbox
* 6 : mailbox needs to be transmitted again
*/
typedef struct
{
uint8_t state;
} _MBXcontrol;
/* Stack reference to application configuration of the ESC */
#define ESC_MBXSIZE (ESCvar.activembxsize)
#define ESC_MBX0_sma (ESCvar.activemb0->cfg_sma)
#define ESC_MBX0_sml (ESCvar.activemb0->cfg_sml)
#define ESC_MBX0_sme (ESCvar.activemb0->cfg_sme)
#define ESC_MBX0_smc (ESCvar.activemb0->cfg_smc)
#define ESC_MBX1_sma (ESCvar.activemb1->cfg_sma)
#define ESC_MBX1_sml (ESCvar.activemb1->cfg_sml)
#define ESC_MBX1_sme (ESCvar.activemb1->cfg_sme)
#define ESC_MBX1_smc (ESCvar.activemb1->cfg_smc)
#define ESC_MBXBUFFERS (MBXBUFFERS)
#define ESC_SM2_sma (SM2_sma)
#define ESC_SM2_smc (SM2_smc)
#define ESC_SM2_act (SM2_act)
#define ESC_SM3_sma (SM3_sma)
#define ESC_SM3_smc (SM3_smc)
#define ESC_SM3_act (SM3_act)
#define ESC_MBXHSIZE sizeof(_MBXh)
#define ESC_MBXDSIZE (ESC_MBXSIZE - ESC_MBXHSIZE)
#define ESC_FOEHSIZE sizeof(_FOEh)
#define ESC_FOE_DATA_SIZE (ESC_MBXSIZE - (ESC_MBXHSIZE +ESC_FOEHSIZE))
#define ESC_EOEHSIZE sizeof(_EOEh)
#define ESC_EOE_DATA_SIZE (ESC_MBXSIZE - (ESC_MBXHSIZE +ESC_EOEHSIZE))
void ESC_config (esc_cfg_t * cfg);
void ESC_ALerror (uint16_t errornumber);
void ESC_ALeventwrite (uint32_t event);
uint32_t ESC_ALeventread (void);
void ESC_ALeventmaskwrite (uint32_t mask);
uint32_t ESC_ALeventmaskread (void);
void ESC_ALstatus (uint8_t status);
void ESC_ALstatusgotoerror (uint8_t status, uint16_t errornumber);
void ESC_SMstatus (uint8_t n);
uint8_t ESC_WDstatus (void);
uint8_t ESC_claimbuffer (void);
uint8_t ESC_startmbx (uint8_t state);
void ESC_stopmbx (void);
void MBX_error (uint16_t error);
uint8_t ESC_mbxprocess (void);
void ESC_xoeprocess (void);
uint8_t ESC_startinput (uint8_t state);
void ESC_stopinput (void);
uint8_t ESC_startoutput (uint8_t state);
void ESC_stopoutput (void);
void ESC_state (void);
void ESC_sm_act_event (void);
/* From hardware file */
void ESC_read (uint16_t address, void *buf, uint16_t len);
void ESC_write (uint16_t address, void *buf, uint16_t len);
void ESC_init (const esc_cfg_t * cfg);
void ESC_reset (void);
/* From application */
extern void APP_safeoutput ();
extern _ESCvar ESCvar;
extern _MBXcontrol MBXcontrol[];
extern uint8_t MBX[];
extern _SMmap SMmap2[];
extern _SMmap SMmap3[];
/* ATOMIC operations are used when running interrupt driven */
#ifndef CC_ATOMIC_SET
#define CC_ATOMIC_SET(var,val) (var = val)
#endif
#ifndef CC_ATOMIC_GET
#define CC_ATOMIC_GET(var) (var)
#endif
#ifndef CC_ATOMIC_ADD
#define CC_ATOMIC_ADD(var,val) (var += val)
#endif
#ifndef CC_ATOMIC_SUB
#define CC_ATOMIC_SUB(var,val) (var -= val)
#endif
#ifndef CC_ATOMIC_AND
#define CC_ATOMIC_AND(var,val) (var &= val)
#endif
#ifndef CC_ATOMIC_OR
#define CC_ATOMIC_OR(var,val) (var |= val)
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* Headerfile for esc_coe.c
*/
#ifndef __esc_coe__
#define __esc_coe__
#include <cc.h>
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint16_t subindex;
uint16_t datatype;
uint16_t bitlength;
uint16_t flags;
const char *name;
uint32_t value;
void *data;
} _objd;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint16_t index;
uint16_t objtype;
uint8_t maxsub;
uint8_t pad1;
const char *name;
const _objd *objdesc;
} _objectlist;
CC_PACKED_END
typedef struct
{
const _objd * obj;
uint16_t offset;
} _SMmap;
#define OBJH_READ 0
#define OBJH_WRITE 1
#define OTYPE_DOMAIN 0x0002
#define OTYPE_DEFTYPE 0x0005
#define OTYPE_DEFSTRUCT 0x0006
#define OTYPE_VAR 0x0007
#define OTYPE_ARRAY 0x0008
#define OTYPE_RECORD 0x0009
#define DTYPE_BOOLEAN 0x0001
#define DTYPE_INTEGER8 0x0002
#define DTYPE_INTEGER16 0x0003
#define DTYPE_INTEGER32 0x0004
#define DTYPE_UNSIGNED8 0x0005
#define DTYPE_UNSIGNED16 0x0006
#define DTYPE_UNSIGNED32 0x0007
#define DTYPE_REAL32 0x0008
#define DTYPE_VISIBLE_STRING 0x0009
#define DTYPE_OCTET_STRING 0x000A
#define DTYPE_UNICODE_STRING 0x000B
#define DTYPE_INTEGER24 0x0010
#define DTYPE_UNSIGNED24 0x0016
#define DTYPE_INTEGER64 0x0015
#define DTYPE_UNSIGNED64 0x001B
#define DTYPE_REAL64 0x0011
#define DTYPE_PDO_MAPPING 0x0021
#define DTYPE_IDENTITY 0x0023
#define DTYPE_BITARR8 0x002D
#define DTYPE_BITARR16 0x002E
#define DTYPE_BITARR32 0x002F
#define DTYPE_BIT1 0x0030
#define DTYPE_BIT2 0x0031
#define DTYPE_BIT3 0x0032
#define DTYPE_BIT4 0x0033
#define DTYPE_BIT5 0x0034
#define DTYPE_BIT6 0x0035
#define DTYPE_BIT7 0x0036
#define DTYPE_BIT8 0x0037
#define DTYPE_ARRAY_OF_INT 0x0260
#define DTYPE_ARRAY_OF_SINT 0x0261
#define DTYPE_ARRAY_OF_DINT 0x0262
#define DTYPE_ARRAY_OF_UDINT 0x0263
#define ATYPE_Rpre 0x01
#define ATYPE_Rsafe 0x02
#define ATYPE_Rop 0x04
#define ATYPE_Wpre 0x08
#define ATYPE_Wsafe 0x10
#define ATYPE_Wop 0x20
#define ATYPE_RXPDO 0x40
#define ATYPE_TXPDO 0x80
#define ATYPE_RO (ATYPE_Rpre | ATYPE_Rsafe | ATYPE_Rop)
#define ATYPE_WO (ATYPE_Wpre | ATYPE_Wsafe | ATYPE_Wop)
#define ATYPE_RW (ATYPE_RO | ATYPE_WO)
#define ATYPE_RWpre (ATYPE_Wpre | ATYPE_RO)
#define TX_PDO_OBJIDX 0x1c13
#define RX_PDO_OBJIDX 0x1c12
#define COMPLETE_ACCESS_FLAG (1 << 15)
void ESC_coeprocess (void);
int16_t SDO_findsubindex (int16_t nidx, uint8_t subindex);
int32_t SDO_findobject (uint16_t index);
uint16_t sizeOfPDO (uint16_t index, int * nmappings, _SMmap * sm, int max_mappings);
void SDO_abort (uint16_t index, uint8_t subindex, uint32_t abortcode);
void COE_initDefaultValues (void);
void COE_pdoPack (uint8_t * buffer, int nmappings, _SMmap * sm);
void COE_pdoUnpack (uint8_t * buffer, int nmappings, _SMmap * sm);
uint8_t COE_maxSub (uint16_t index);
extern uint32_t ESC_download_post_objecthandler (uint16_t index, uint8_t subindex, uint16_t flags);
extern uint32_t ESC_download_pre_objecthandler (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags);
extern uint32_t ESC_upload_pre_objecthandler (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags);
extern uint32_t ESC_upload_post_objecthandler (uint16_t index, uint8_t subindex, uint16_t flags);
extern const _objectlist SDOobjects[];
#endif

View File

@@ -0,0 +1,80 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* ESI EEPROM emulator module.
*/
#include "cc.h"
#include "esc.h"
#include "esc_eep.h"
#include <string.h>
static uint8_t eep_buf[8];
/** EPP periodic task of ESC side EEPROM emulation.
*
*/
void EEP_process (void)
{
eep_stat_t stat;
/* check for eeprom event */
if ((ESCvar.ALevent & ESCREG_ALEVENT_EEP) == 0) {
return;
}
while (1) {
/* read eeprom status */
ESC_read (ESCREG_EECONTSTAT, &stat, sizeof (eep_stat_t));
stat.contstat.reg = etohs(stat.contstat.reg);
stat.addr = etohl(stat.addr);
/* check busy flag, exit if job finished */
if (!stat.contstat.bits.busy) {
return;
}
/* clear error bits */
stat.contstat.bits.csumErr = 0;
stat.contstat.bits.eeLoading = 0;
stat.contstat.bits.ackErr = 0;
stat.contstat.bits.wrErr = 0;
/* process commands */
switch (stat.contstat.bits.cmdReg) {
case EEP_CMD_IDLE:
break;
case EEP_CMD_READ:
case EEP_CMD_RELOAD:
/* handle read request */
if (EEP_read (stat.addr * sizeof(uint16_t), eep_buf, EEP_READ_SIZE) != 0) {
stat.contstat.bits.ackErr = 1;
} else {
ESC_write (ESCREG_EEDATA, eep_buf, EEP_READ_SIZE);
}
break;
case EEP_CMD_WRITE:
/* handle write request */
ESC_read (ESCREG_EEDATA, eep_buf, EEP_WRITE_SIZE);
if (EEP_write (stat.addr * sizeof(uint16_t), eep_buf, EEP_WRITE_SIZE) != 0) {
stat.contstat.bits.ackErr = 1;
}
break;
default:
stat.contstat.bits.ackErr = 1;
}
/* acknowledge command */
stat.contstat.reg = htoes(stat.contstat.reg);
ESC_write (ESCREG_EECONTSTAT, &stat.contstat.reg, sizeof(uint16_t));
}
}

View File

@@ -0,0 +1,77 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* Headerfile for esc_eep.c
*/
#ifndef __esc_eep__
#define __esc_eep__
#include <cc.h>
#include "esc.h"
/* EEPROM commands */
#define EEP_CMD_IDLE 0x0
#define EEP_CMD_READ 0x1
#define EEP_CMD_WRITE 0x2
#define EEP_CMD_RELOAD 0x3
/* read/write size */
#define EEP_READ_SIZE 8
#define EEP_WRITE_SIZE 2
/* CONSTAT register content */
typedef struct CC_PACKED
{
union {
uint16_t reg;
struct {
uint8_t wrEnable:1;
uint8_t reserved:4;
uint8_t eeEmulated:1;
uint8_t eightByteRead:1;
uint8_t twoByteAddr:1;
uint8_t cmdReg:3;
uint8_t csumErr:1;
uint8_t eeLoading:1;
uint8_t ackErr:1;
uint8_t wrErr:1;
uint8_t busy:1;
} bits;
} contstat;
uint32_t addr;
} eep_stat_t;
/**
* ECAT EEPROM configuration area data structure
*/
typedef union eep_config
{
struct
{
uint16_t pdi_control;
uint16_t pdi_configuration;
uint16_t sync_impulse_len;
uint16_t pdi_configuration2;
uint16_t configured_station_alias;
uint8_t reserved[4];
uint16_t checksum;
};
uint32_t dword[4]; /**< Four 32 bit double word equivalent to 8 16 bit configuration area word. */
}eep_config_t;
/* periodic task */
void EEP_process (void);
/* From hardware file */
void EEP_init (void);
int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t size);
int8_t EEP_write (uint32_t addr, uint8_t *data, uint16_t size);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* Headerfile for esc_eoe.c
*/
#ifndef __esc_eoe__
#define __esc_eoe__
#include <cc.h>
typedef struct eoe_pbuf
{
/** Pointer to frame buffer type used by a TCP/IP stack. (Not mandatory) */
void * pbuf;
/** Pointer to frame buffer to send or read from */
uint8_t * payload;
/** Length of data in frame buffer */
size_t len;
} eoe_pbuf_t;
typedef struct eoe_cfg
{
/** Callback function to get a frame buffer for storage of received frame */
void (*get_buffer) (eoe_pbuf_t * ebuf);
/** Callback function to free a frame buffer */
void (*free_buffer) (eoe_pbuf_t * ebuf);
/** Callback function to read local settings and update EtherCAT variables
* to be delivered to the EtherCAT Master
*/
int (*load_eth_settings) (void);
/** Callback function to read settings provided by the EtherCAT master
* and store to local settings.
*/
int (*store_ethernet_settings) (void);
/** Callback to frame receive function in TCP(IP stack,
* caller should free the buffer
* */
void (*handle_recv_buffer) (uint8_t port, eoe_pbuf_t * ebuf);
/** Callback to fetch a buffer to send */
int (*fetch_send_buffer) (uint8_t port, eoe_pbuf_t * ebuf);
/** Callback to notify the application fragment sent */
void (*fragment_sent_event) (void);
} eoe_cfg_t;
int EOE_ecat_get_mac (uint8_t port, uint8_t mac[]);
int EOE_ecat_get_ip (uint8_t port, uint32_t * ip);
int EOE_ecat_get_subnet (uint8_t port, uint32_t * subnet);
int EOE_ecat_get_gateway (uint8_t port, uint32_t * default_gateway);
int EOE_ecat_get_dns_ip (uint8_t port, uint32_t * dns_ip);
int EOE_ecat_get_dns_name (uint8_t port, char * dns_name);
int EOE_ecat_set_mac (uint8_t port, uint8_t mac[]);
int EOE_ecat_set_ip (uint8_t port, uint32_t ip);
int EOE_ecat_set_subnet (uint8_t port, uint32_t subnet);
int EOE_ecat_set_gateway (uint8_t port, uint32_t default_gateway);
int EOE_ecat_set_dns_ip (uint8_t port, uint32_t dns_ip);
int EOE_ecat_set_dns_name (uint8_t port, char * dns_name);
void EOE_config (eoe_cfg_t * cfg);
void EOE_init (void);
void ESC_eoeprocess (void);
void ESC_eoeprocess_tx (void);
#endif

View File

@@ -0,0 +1,627 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* File over EtherCAT (FoE) module.
*/
#include <cc.h>
#include "esc.h"
#include "esc_foe.h"
#include <string.h>
/** \file
* \brief
* File over EtherCAT (FoE) module.
*
* FOE read / write and FOE service functions
*/
//define if FOE_read should be supported
//#define FOE_READ_SUPPORTED
/** Variable holding current filename read at FOE Open.
*/
static char foe_file_name[FOE_FN_MAX + 1];
/** Main FoE configuration pointer data array. Structure is allocated and filled
* by the application defining what preferences it requires.
*/
static foe_cfg_t * foe_cfg;
/** Pointer to current file configuration item used by FoE.
*/
static foe_file_cfg_t * foe_file;
/** Main FoE status data array. Structure gets filled with current status
* variables during FoE usage.
*/
static _FOEvar FOEvar;
/** Validate a write or read request by checking filename and password.
*
* @param[in] name = Filename
* @param[in] num_chars = Length of filename
* @param[in] pass = Numeric variable of password
* @param[in] op = Request op-code
* @return 0= if we succeed, FOE_ERR_NOTFOUND something wrong with filename or
* password
*/
static int FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
{
uint32_t i;
/* Unpack the file name into characters we can look at. */
if (num_chars > FOE_FN_MAX)
{
num_chars = FOE_FN_MAX;
}
for (i = 0; i < num_chars; i++)
{
foe_file_name[i] = name[i];
}
foe_file_name[i] = '\0';
/* Figure out what file they're talking about. */
for (i = 0; i < foe_cfg->n_files; i++)
{
if (0 == strncmp (foe_file_name, foe_cfg->files[i].name, num_chars))
{
if (pass != foe_cfg->files[i].filepass)
{
return FOE_ERR_NORIGHTS;
}
if (op == FOE_OP_WRQ &&
(foe_cfg->files[i].write_only_in_boot) &&
(ESCvar.ALstatus != ESCboot))
{
return FOE_ERR_NOTINBOOTSTRAP;
}
foe_file = &foe_cfg->files[i];
foe_file->address_offset = 0;
foe_file->total_size = 0;
switch (op)
{
case FOE_OP_RRQ:
{
FOEvar.fposition = 0;
FOEvar.fend = foe_cfg->files[i].max_data;
return 0;
}
case FOE_OP_WRQ:
{
FOEvar.fposition = 0;
FOEvar.fend = foe_cfg->files[i].max_data;
return 0;
}
}
}
}
return FOE_ERR_NOTFOUND;
}
#ifdef FOE_READ_SUPPORTED
/** Function writing local data to mailbox buffer to be sent as next FoE frame.
* It will try to fill the Mailbox buffer available if there is enough data
* left to read.
*
* @param[in] data = pointer to buffer
* @param[in] maxlength = max length of data possible to read, controlled by
* Mailbox - FoE and Mailbox frame headers.
* @return Number of copied bytes.
*/
static uint16_t FOE_fread (uint8_t * data, uint16_t maxlength)
{
uint16_t ncopied = 0;
while (maxlength && (FOEvar.fend - FOEvar.fposition))
{
maxlength--;
*(data++) = foe_cfg->fbuffer[FOEvar.fposition++];
ncopied++;
}
return ncopied;
}
#endif
/** Function reading mailbox buffer to local buffer to be handled by
* application write hook. Ex. flash routine used by software update.
* It will consume the buffer and call the write hook every time the configured
* flush buffer limit is reached.
*
*
* @param[in] data = Pointer to buffer
* @param[in] length = Length of data to read
* @return Number of copied bytes.
*/
static uint16_t FOE_fwrite (uint8_t *data, uint16_t length)
{
uint16_t ncopied = 0;
uint32_t failed = 0;
DPRINT("FOE_fwrite\n");
FOEvar.fprevposition = FOEvar.fposition;
while (length && (FOEvar.fend - FOEvar.fposition) && !failed)
{
length--;
foe_cfg->fbuffer[FOEvar.fbufposition++] = *(data++);
if(FOEvar.fbufposition >= foe_cfg->buffer_size)
{
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer, FOEvar.fbufposition);
FOEvar.fbufposition = 0;
foe_file->address_offset += foe_cfg->buffer_size;
}
FOEvar.fposition++;
ncopied++;
}
foe_file->total_size += ncopied;
DPRINT("FOE_fwrite END with : %d\n",ncopied);
return ncopied;
}
/** Function handling the final FOE_fwrite when we close up regardless
* if we have filled the buffers or not.
*
* @return Number of copied bytes on success, 0= if failed.
*/
static uint32_t FOE_fclose (void)
{
uint32_t failed = 0;
DPRINT("FOE_fclose\n");
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer, FOEvar.fbufposition);
foe_file->address_offset += FOEvar.fbufposition;
FOEvar.fbufposition = 0;
return failed;
}
/** Initialize by clearing all current status variables.
*
*/
void FOE_init ()
{
DPRINT("FOE_init\n");
FOEvar.foepacket = 0;
FOEvar.foestate = FOE_READY;
FOEvar.fposition = 0;
FOEvar.fprevposition = 0;
FOEvar.fbufposition = 0;
}
/** Function for sending an FOE abort frame.
*
* @param[in] code = abort code
*/
static void FOE_abort (uint32_t code)
{
_FOE *foembx;
uint8_t mbxhandle;
if (code)
{
/* Send back an error packet. */
mbxhandle = ESC_claimbuffer ();
if (mbxhandle)
{
foembx = (_FOE *) &MBX[mbxhandle * ESC_MBXSIZE];
foembx->mbxheader.length = htoes (ESC_FOEHSIZE); /* Don't bother with error text for now. */
foembx->mbxheader.mbxtype = MBXFOE;
foembx->foeheader.opcode = FOE_OP_ERR;
foembx->foeheader.errorcode = htoel (code);
MBXcontrol[mbxhandle].state = MBXstate_outreq;
}
/* Nothing we can do if we can't get an outbound mailbox. */
}
DPRINT("FOE_abort: 0x%X\n", code);
FOE_init ();
}
#ifdef FOE_READ_SUPPORTED
/** Sends an FoE data frame, returning the number of data bytes
* written or an error number.
* Error numbers will be greater than FOE_DATA_SIZE.
* @param[in] data = pointer to buffer
* @param[in] length = length of data to read
* @return Number of data bytes written or an error number. Error numbers
* will be greater than FOE_DATA_SIZE.
*/
static int FOE_send_data_packet ()
{
_FOE *foembx;
uint16_t data_len;
uint8_t mbxhandle;
mbxhandle = ESC_claimbuffer ();
if (mbxhandle)
{
foembx = (_FOE *) &MBX[mbxhandle * ESC_MBXSIZE];
data_len = FOE_fread (foembx->data, ESC_FOE_DATA_SIZE);
foembx->foeheader.opcode = FOE_OP_DATA;
foembx->foeheader.packetnumber = htoel (FOEvar.foepacket);
FOEvar.foepacket++;
foembx->mbxheader.length = htoes (data_len + ESC_FOEHSIZE);
foembx->mbxheader.mbxtype = MBXFOE;
/* Mark the outbound mailbox as filled. */
MBXcontrol[mbxhandle].state = MBXstate_outreq;
return data_len;
}
else
{
return FOE_ERR_PROGERROR;
}
}
#endif
/** Sends an FoE ack data frame.
* @return 0= or error number.
*/
static int FOE_send_ack ()
{
_FOE *foembx;
uint8_t mbxhandle;
mbxhandle = ESC_claimbuffer ();
if (mbxhandle)
{
DPRINT("FOE_send_ack\n");
foembx = (_FOE *) &MBX[mbxhandle * ESC_MBXSIZE];
foembx->mbxheader.length = htoes (ESC_FOEHSIZE);
foembx->mbxheader.mbxtype = MBXFOE;
foembx->foeheader.opcode = FOE_OP_ACK;
foembx->foeheader.packetnumber = htoel (FOEvar.foepacket);
FOEvar.foepacket++;
MBXcontrol[mbxhandle].state = MBXstate_outreq;
return 0;
}
else
{
DPRINT("ERROR:FOE_send_ack\n");
return FOE_ERR_PROGERROR;
}
}
/* Handlers for various FoE states. */
#ifdef FOE_READ_SUPPORTED
/** FoE read request handler. Starts with Initialize, Open and Sending one frame.
* When first frame have been sent we will send data from Ack.
* On error we will send FOE Abort.
*
*/
static void FOE_read ()
{
_FOE *foembx;
uint32_t data_len;
uint32_t password;
int res;
if (FOEvar.foestate != FOE_READY)
{
FOE_abort (FOE_ERR_ILLEGAL);
return;
}
FOE_init ();
foembx = (_FOE *) &MBX[0];
/* Get the length of the file name in octets. */
data_len = etohs (foembx->mbxheader.length) - ESC_FOEHSIZE;
password = etohl (foembx->foeheader.password);
res = FOE_fopen (foembx->filename, data_len, password, FOE_OP_RRQ);
if (res == 0)
{
FOEvar.foepacket = 1;
/*
* Attempt to send the packet
*/
res = FOE_send_data_packet ();
if (res <= (int)ESC_FOE_DATA_SIZE)
{
FOEvar.foestate = FOE_WAIT_FOR_ACK;
}
else
{
FOE_abort (res);
}
}
else
{
FOE_abort (res);
}
}
/** FoE data ack handler. Will continue sending next frame until finished.
* On error we will send FOE Abort.
*/
static void FOE_ack ()
{
int res;
/* Make sure we're able to take this. */
if (FOEvar.foestate == FOE_WAIT_FOR_FINAL_ACK)
{
/* Move us back to ready state. */
FOE_init ();
return;
}
else if (FOEvar.foestate != FOE_WAIT_FOR_ACK)
{
FOE_abort (FOE_ERR_ILLEGAL);
return;
}
res = FOE_send_data_packet ();
if (res < (int)ESC_FOE_DATA_SIZE)
{
FOEvar.foestate = FOE_WAIT_FOR_FINAL_ACK;
}
else if (res >= FOE_ERR_NOTDEFINED)
{
FOE_abort (FOE_ERR_PROGERROR);
}
}
#endif
/** FoE write request handler. Starts with Initialize, Open and Ack that we can/will
* receive data. On error we will send FOE Abort.
*
*/
static void FOE_write ()
{
_FOE *foembx;
uint32_t data_len;
uint32_t password;
int res;
if (FOEvar.foestate != FOE_READY)
{
FOE_abort (FOE_ERR_ILLEGAL);
return;
}
FOE_init ();
foembx = (_FOE *) &MBX[0];
data_len = etohs (foembx->mbxheader.length) - ESC_FOEHSIZE;
password = etohl (foembx->foeheader.password);
/* Get an address we can write the file to, if possible. */
res = FOE_fopen (foembx->filename, data_len, password, FOE_OP_WRQ);
DPRINT("%s %sOK, file \"%s\"\n", __func__, (res == 0) ? "" : "N", foe_file_name);
if (res == 0)
{
res = FOE_send_ack ();
if (res)
{
FOE_abort (res);
}
else
{
FOEvar.foestate = FOE_WAIT_FOR_DATA;
}
}
else
{
FOE_abort (res);
}
}
/** FoE data request handler. Validates and reads data until we're finished. Every
* read frame followed by an Ack frame. On error we will send FOE Abort.
*
*/
static void FOE_data ()
{
_FOE *foembx;
uint32_t packet;
uint16_t data_len, ncopied;
int res;
if(FOEvar.foestate != FOE_WAIT_FOR_DATA)
{
FOE_abort(FOE_ERR_ILLEGAL);
return;
}
foembx = (_FOE*)&MBX[0];
data_len = etohs(foembx->mbxheader.length) - ESC_FOEHSIZE;
packet = etohl(foembx->foeheader.packetnumber);
if (packet != FOEvar.foepacket)
{
DPRINT("FOE_data packet error, packet: %d, foeheader.packet: %d\n",packet,FOEvar.foepacket);
FOE_abort (FOE_ERR_PACKETNO);
}
else if (data_len == 0)
{
DPRINT("FOE_data completed\n");
FOE_fclose ();
res = FOE_send_ack ();
FOE_init ();
}
else if (FOEvar.fposition + data_len > FOEvar.fend)
{
DPRINT("FOE_data disk full\n");
FOE_abort (FOE_ERR_DISKFULL);
}
else
{
ncopied = FOE_fwrite (foembx->data, data_len);
if (!ncopied)
{
DPRINT("FOE_data no copied\n");
FOE_abort (FOE_ERR_PROGERROR);
}
else if (data_len == ESC_FOE_DATA_SIZE)
{
DPRINT("FOE_data data_len == FOE_DATA_SIZE\n");
if (ncopied != data_len)
{
DPRINT("FOE_data only %d of %d copied\n",ncopied, data_len);
FOE_abort (FOE_ERR_PROGERROR);
}
res = FOE_send_ack ();
if (res)
{
FOE_abort (res);
}
}
else
{
if ((ncopied != data_len) || FOE_fclose ())
{
DPRINT("FOE_fclose failed to write extra buffer\n");
FOE_abort (FOE_ERR_PROGERROR);
}
else
{
DPRINT("FOE_data completed\n");
res = FOE_send_ack ();
FOE_init ();
}
}
}
}
#ifdef FOE_READ_SUPPORTED
/** FoE read request busy handler. Send an Ack of last frame again. On error
* we will send FOE Abort.
*
*/
static void FOE_busy ()
{
/* Only valid if we're servicing a read request. */
if (FOEvar.foestate != FOE_WAIT_FOR_ACK)
{
FOE_abort (FOE_ERR_ILLEGAL);
}
else
{
/* Send the last part again. */
FOEvar.fposition = FOEvar.fprevposition;
FOEvar.foepacket--;
FOE_ack ();
}
}
#endif
/** FoE error requesthandler. Send an FOE Abort.
*
*/
static void FOE_error ()
{
/* Master panic! abort the transfer. */
FOE_abort (0);
}
/** Function copying the application configuration variable
* to the FoE module local pointer variable.
*
* @param[in] cfg = Pointer to by the Application static declared
* configuration variable holding application specific details.
*/
void FOE_config (foe_cfg_t * cfg)
{
foe_cfg = cfg;
}
/** Main FoE function checking the status on current mailbox buffers carrying
* data, distributing the mailboxes to appropriate FOE functions depending
* on requested opcode.
* On Error an FoE Error or FoE Abort will be sent.
*/
void ESC_foeprocess (void)
{
_MBXh *mbh;
_FOE *foembx;
if (ESCvar.MBXrun == 0)
{
return;
}
if (!ESCvar.xoe && (MBXcontrol[0].state == MBXstate_inclaim))
{
mbh = (_MBXh *) &MBX[0];
if (mbh->mbxtype == MBXFOE)
{
ESCvar.xoe = MBXFOE;
}
}
if (ESCvar.xoe == MBXFOE)
{
foembx = (_FOE *) &MBX[0];
/* Verify the size of the file data. */
if (etohs (foembx->mbxheader.length) < ESC_FOEHSIZE)
{
FOE_abort (MBXERR_SIZETOOSHORT);
}
else
{
switch (foembx->foeheader.opcode)
{
case FOE_OP_WRQ:
{
DPRINT("FOE_OP_WRQ\n");
FOE_write ();
break;
}
case FOE_OP_DATA:
{
DPRINT("FOE_OP_DATA\n");
FOE_data ();
break;
}
#ifdef FOE_READ_SUPPORTED
case FOE_OP_RRQ:
{
DPRINT("FOE_OP_RRQ\n");
FOE_read ();
break;
}
case FOE_OP_ACK:
{
DPRINT("FOE_OP_ACK\n");
FOE_ack ();
break;
}
case FOE_OP_BUSY:
{
DPRINT("FOE_OP_BUSY\n");
FOE_busy ();
break;
}
#endif
case FOE_OP_ERR:
{
DPRINT("FOE_OP_ERR\n");
FOE_error ();
break;
}
default:
{
DPRINT("FOE_ERR_NOTDEFINED\n");
FOE_abort (FOE_ERR_NOTDEFINED);
break;
}
}
}
MBXcontrol[0].state = MBXstate_idle;
ESCvar.xoe = 0;
}
}

View File

@@ -0,0 +1,77 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* Headerfile for esc_foe.c
*/
#ifndef __esc_foe__
#define __esc_foe__
#include <cc.h>
/** Maximum number of characters allowed in a file name. */
#define FOE_FN_MAX 31
typedef struct foe_file_cfg foe_file_cfg_t;
struct foe_file_cfg
{
/** Name of file to receive from master */
const char * name;
/** Size of file,sizeof data we can recv */
uint32_t max_data;
/** Where to store the data initially */
uint32_t dest_start_address;
/** Current address during write of file */
uint32_t address_offset;
/** Calculated size of file received */
uint32_t total_size;
/** FoE password */
uint32_t filepass;
/** This file can be written only in BOOT state. Intended for FW files */
uint8_t write_only_in_boot;
/** for feature use */
uint32_t padding:24;
/** Pointer to application foe write function */
uint32_t (*write_function) (foe_file_cfg_t * self, uint8_t * data, size_t length);
};
typedef struct foe_cfg
{
/** Allocate static in caller func to fit buffer_size */
uint8_t * fbuffer;
/** Buffer size before we flush to destination */
uint32_t buffer_size;
/** Number of files used in firmware update */
uint32_t n_files;
/** Pointer to files configured to be used by FoE */
foe_file_cfg_t * files;
} foe_cfg_t;
typedef struct CC_PACKED
{
/** Current FoE state, ex. Waiting for ACK, Waiting for DATA */
uint8_t foestate;
/** Current file buffer position, evaluated against foe file buffer size
* when to flush
*/
uint16_t fbufposition;
/** Frame number in read or write sequence */
uint32_t foepacket;
/** Current position in file to be handled by FoE request */
uint32_t fposition;
/** Previous position in file to be handled by FoE request */
uint32_t fprevposition;
/** End position of allocated disk space for FoE requested file */
uint32_t fend;
} _FOEvar;
/* Initializes FoE state. */
void FOE_config (foe_cfg_t * cfg);
void FOE_init (void);
void ESC_foeprocess (void);
#endif

View File

@@ -0,0 +1,458 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* ESC hardware layer functions for LAN9252.
*
* Function to read and write commands to the ESC. Used to read/write ESC
* registers and memory.
*/
#include "esc.h"
#include "spi.h"
#include <string.h>
#define O_RDWR 1
#define BIT(x) 1 << (x)
#define ESC_CMD_SERIAL_WRITE 0x02
#define ESC_CMD_SERIAL_READ 0x03
#define ESC_CMD_FAST_READ 0x0B
#define ESC_CMD_RESET_SQI 0xFF
#define ESC_CMD_FAST_READ_DUMMY 1
#define ESC_CMD_ADDR_INC BIT(6)
#define ESC_PRAM_RD_FIFO_REG 0x000
#define ESC_PRAM_WR_FIFO_REG 0x020
#define ESC_PRAM_RD_ADDR_LEN_REG 0x308
#define ESC_PRAM_RD_CMD_REG 0x30C
#define ESC_PRAM_WR_ADDR_LEN_REG 0x310
#define ESC_PRAM_WR_CMD_REG 0x314
#define ESC_PRAM_CMD_BUSY BIT(31)
#define ESC_PRAM_CMD_ABORT BIT(30)
#define ESC_PRAM_CMD_CNT(x) ((x >> 8) & 0x1F)
#define ESC_PRAM_CMD_AVAIL BIT(0)
#define ESC_PRAM_SIZE(x) ((x) << 16)
#define ESC_PRAM_ADDR(x) ((x) << 0)
#define ESC_CSR_DATA_REG 0x300
#define ESC_CSR_CMD_REG 0x304
#define ESC_CSR_CMD_BUSY BIT(31)
#define ESC_CSR_CMD_READ (BIT(31) | BIT(30))
#define ESC_CSR_CMD_WRITE BIT(31)
#define ESC_CSR_CMD_SIZE(x) (x << 16)
#define ESC_RESET_CTRL_REG 0x1F8
#define ESC_RESET_CTRL_RST BIT(6)
#define ESC_DIGITAL_RST 0x00000001
#define ESC_ID_REV_REG 0x050
#define LAN9252_ID_REV 0x9252
#define ESC_IRQ_CFG_REG 0x054
#define ESC_INT_EN_REG 0x05C
#define ESC_BYTE_TEST_REG 0x064
#define ESC_TEST_VALUE 0x87654321
#define ESC_HW_CFG_REG 0x074
#define ESC_READY BIT(27)
static int lan9252 = -1;
/* lan9252 singel write */
static void lan9252_write_32 (uint16_t address, uint32_t val)
{
uint8_t data[7];
data[0] = ESC_CMD_SERIAL_WRITE;
data[1] = ((address >> 8) & 0xFF);
data[2] = (address & 0xFF);
data[3] = (val & 0xFF);
data[4] = ((val >> 8) & 0xFF);
data[5] = ((val >> 16) & 0xFF);
data[6] = ((val >> 24) & 0xFF);
/* Select device. */
spi_select (lan9252);
/* Write data */
write (lan9252, data, sizeof(data));
/* Un-select device. */
spi_unselect (lan9252);
}
/* lan9252 single read */
static uint32_t lan9252_read_32 (uint32_t address)
{
uint8_t data[4];
uint8_t result[4];
data[0] = ESC_CMD_FAST_READ;
data[1] = ((address >> 8) & 0xFF);
data[2] = (address & 0xFF);
data[3] = ESC_CMD_FAST_READ_DUMMY;
/* Select device. */
spi_select (lan9252);
/* Read data */
write (lan9252, data, sizeof(data));
read (lan9252, result, sizeof(result));
/* Un-select device. */
spi_unselect (lan9252);
return ((result[3] << 24) |
(result[2] << 16) |
(result[1] << 8) |
result[0]);
}
/* ESC read CSR function */
static void ESC_read_csr (uint16_t address, void *buf, uint16_t len)
{
uint32_t value;
value = (ESC_CSR_CMD_READ | ESC_CSR_CMD_SIZE(len) | address);
lan9252_write_32(ESC_CSR_CMD_REG, value);
do
{
value = lan9252_read_32(ESC_CSR_CMD_REG);
} while(value & ESC_CSR_CMD_BUSY);
value = lan9252_read_32(ESC_CSR_DATA_REG);
memcpy(buf, (uint8_t *)&value, len);
}
/* ESC write CSR function */
static void ESC_write_csr (uint16_t address, void *buf, uint16_t len)
{
uint32_t value;
memcpy((uint8_t*)&value, buf,len);
lan9252_write_32(ESC_CSR_DATA_REG, value);
value = (ESC_CSR_CMD_WRITE | ESC_CSR_CMD_SIZE(len) | address);
lan9252_write_32(ESC_CSR_CMD_REG, value);
do
{
value = lan9252_read_32(ESC_CSR_CMD_REG);
} while(value & ESC_CSR_CMD_BUSY);
}
/* ESC read process data ram function */
/*static*/ void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
{
uint32_t value;
uint8_t * temp_buf = (uint8_t *)buf;
uint16_t byte_offset = 0;
uint8_t fifo_cnt, first_byte_position, temp_len, data[4];
value = ESC_PRAM_CMD_ABORT;
lan9252_write_32(ESC_PRAM_RD_CMD_REG, value);
do
{
value = lan9252_read_32(ESC_PRAM_RD_CMD_REG);
}while(value & ESC_PRAM_CMD_BUSY);
value = ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address);
lan9252_write_32(ESC_PRAM_RD_ADDR_LEN_REG, value);
value = ESC_PRAM_CMD_BUSY;
lan9252_write_32(ESC_PRAM_RD_CMD_REG, value);
do
{
value = lan9252_read_32(ESC_PRAM_RD_CMD_REG);
}while((value & ESC_PRAM_CMD_AVAIL) == 0);
/* Fifo count */
fifo_cnt = ESC_PRAM_CMD_CNT(value);
/* Read first value from FIFO */
value = lan9252_read_32(ESC_PRAM_RD_FIFO_REG);
fifo_cnt--;
/* Find out first byte position and adjust the copy from that
* according to LAN9252 datasheet and MicroChip SDK code
*/
first_byte_position = (address & 0x03);
temp_len = ((4 - first_byte_position) > len) ? len : (4 - first_byte_position);
memcpy(temp_buf ,((uint8_t *)&value + first_byte_position), temp_len);
len -= temp_len;
byte_offset += temp_len;
/* Select device. */
spi_select (lan9252);
/* Send command and address for fifo read */
data[0] = ESC_CMD_FAST_READ;
data[1] = ((ESC_PRAM_RD_FIFO_REG >> 8) & 0xFF);
data[2] = (ESC_PRAM_RD_FIFO_REG & 0xFF);
data[3] = ESC_CMD_FAST_READ_DUMMY;
write (lan9252, data, sizeof(data));
/* Continue reading until we have read len */
while(len > 0)
{
temp_len = (len > 4) ? 4: len;
/* Always read 4 byte */
read (lan9252, (temp_buf + byte_offset), sizeof(uint32_t));
fifo_cnt--;
len -= temp_len;
byte_offset += temp_len;
}
/* Un-select device. */
spi_unselect (lan9252);
}
/* ESC write process data ram function */
/* static */ void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
{
uint32_t value;
uint8_t * temp_buf = (uint8_t *)buf;
uint16_t byte_offset = 0;
uint8_t fifo_cnt, first_byte_position, temp_len, data[3];
value = ESC_PRAM_CMD_ABORT;
lan9252_write_32(ESC_PRAM_WR_CMD_REG, value);
do
{
value = lan9252_read_32(ESC_PRAM_WR_CMD_REG);
}while(value & ESC_PRAM_CMD_BUSY);
value = ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address);
lan9252_write_32(ESC_PRAM_WR_ADDR_LEN_REG, value);
value = ESC_PRAM_CMD_BUSY;
lan9252_write_32(ESC_PRAM_WR_CMD_REG, value);
do
{
value = lan9252_read_32(ESC_PRAM_WR_CMD_REG);
}while((value & ESC_PRAM_CMD_AVAIL) == 0);
/* Fifo count */
fifo_cnt = ESC_PRAM_CMD_CNT(value);
/* Find out first byte position and adjust the copy from that
* according to LAN9252 datasheet
*/
first_byte_position = (address & 0x03);
temp_len = ((4 - first_byte_position) > len) ? len : (4 - first_byte_position);
memcpy(((uint8_t *)&value + first_byte_position), temp_buf, temp_len);
/* Write first value from FIFO */
lan9252_write_32(ESC_PRAM_WR_FIFO_REG, value);
len -= temp_len;
byte_offset += temp_len;
fifo_cnt--;
/* Select device. */
spi_select (lan9252);
/* Send command and address for incrementing write */
data[0] = ESC_CMD_SERIAL_WRITE;
data[1] = ((ESC_PRAM_WR_FIFO_REG >> 8) & 0xFF);
data[2] = (ESC_PRAM_WR_FIFO_REG & 0xFF);
write (lan9252, data, sizeof(data));
/* Continue reading until we have read len */
while(len > 0)
{
temp_len = (len > 4) ? 4 : len;
value = 0;
memcpy((uint8_t *)&value, (temp_buf + byte_offset), temp_len);
/* Always write 4 byte */
write (lan9252, (uint8_t *)&value, sizeof(value));
fifo_cnt--;
len -= temp_len;
byte_offset += temp_len;
}
/* Un-select device. */
spi_unselect (lan9252);
}
/** ESC read function used by the Slave stack.
*
* @param[in] address = address of ESC register to read
* @param[out] buf = pointer to buffer to read in
* @param[in] len = number of bytes to read
*/
void ESC_read (uint16_t address, void *buf, uint16_t len)
{
/* Select Read function depending on address, process data ram or not */
if (address >= 0x1000)
{
ESC_read_pram(address, buf, len);
}
else
{
uint16_t size;
uint8_t *temp_buf = (uint8_t *)buf;
while(len > 0)
{
/* We write maximum 4 bytes at the time */
size = (len > 4) ? 4 : len;
/* Make size aligned to address according to LAN9252 datasheet
* Table 12-14 EtherCAT CSR Address VS size and MicroChip SDK code
*/
/* If we got an odd address size is 1 , 01b 11b is captured */
if(address & BIT(0))
{
size = 1;
}
/* If address 1xb and size != 1 and 3 , allow size 2 else size 1 */
else if (address & BIT(1))
{
size = (size & BIT(0)) ? 1 : 2;
}
/* size 3 not valid */
else if (size == 3)
{
size = 1;
}
/* else size is kept AS IS */
ESC_read_csr(address, temp_buf, size);
/* next address */
len -= size;
temp_buf += size;
address += size;
}
}
/* To mimic the ET1100 always providing AlEvent on every read or write */
ESC_read_csr(ESCREG_ALEVENT,(void *)&ESCvar.ALevent,sizeof(ESCvar.ALevent));
ESCvar.ALevent = etohs (ESCvar.ALevent);
}
/** ESC write function used by the Slave stack.
*
* @param[in] address = address of ESC register to write
* @param[out] buf = pointer to buffer to write from
* @param[in] len = number of bytes to write
*/
void ESC_write (uint16_t address, void *buf, uint16_t len)
{
/* Select Write function depending on address, process data ram or not */
if (address >= 0x1000)
{
ESC_write_pram(address, buf, len);
}
else
{
uint16_t size;
uint8_t *temp_buf = (uint8_t *)buf;
while(len > 0)
{
/* We write maximum 4 bytes at the time */
size = (len > 4) ? 4 : len;
/* Make size aligned to address according to LAN9252 datasheet
* Table 12-14 EtherCAT CSR Address VS size and MicroChip SDK code
*/
/* If we got an odd address size is 1 , 01b 11b is captured */
if(address & BIT(0))
{
size = 1;
}
/* If address 1xb and size != 1 and 3 , allow size 2 else size 1 */
else if (address & BIT(1))
{
size = (size & BIT(0)) ? 1 : 2;
}
/* size 3 not valid */
else if (size == 3)
{
size = 1;
}
/* else size is kept AS IS */
ESC_write_csr(address, temp_buf, size);
/* next address */
len -= size;
temp_buf += size;
address += size;
}
}
/* To mimic the ET1x00 always providing AlEvent on every read or write */
ESC_read_csr(ESCREG_ALEVENT,(void *)&ESCvar.ALevent,sizeof(ESCvar.ALevent));
ESCvar.ALevent = etohs (ESCvar.ALevent);
}
/* Un-used due to evb-lan9252-digio not havning any possability to
* reset except over SPI.
*/
void ESC_reset (void)
{
}
uint8_t ESC_IsLAN9252()
{
volatile uint32_t value;
uint16_t detectedChip, revision;
/* Read */
value = lan9252_read_32(ESC_ID_REV_REG);
detectedChip = value >> 16;
revision = value & 0xFF;
return detectedChip == LAN9252_ID_REV
&& revision >= 1;
}
void ESC_init (const esc_cfg_t * config)
{
uint32_t value;
spi_setup();
/* Reset the ecat core here due to evb-lan9252-digio not having any GPIO
* for that purpose.
*/
lan9252_write_32(ESC_RESET_CTRL_REG, ESC_DIGITAL_RST);
do
{
value = lan9252_read_32(ESC_RESET_CTRL_REG);
}
while(value & ESC_RESET_CTRL_RST);
/* Read test register */
do
{
value = lan9252_read_32(ESC_BYTE_TEST_REG);
}
while (value != ESC_TEST_VALUE);
/* Check Ready flag */
do
{
value = lan9252_read_32(ESC_HW_CFG_REG);
}
while ((value & ESC_READY) == 0);
if(!ESC_IsLAN9252())
{
while (1);
}
}

View File

@@ -0,0 +1,66 @@
#include "spi.hpp"
// #include <Arduino.h>
#include <SPI.h>
char SCS = ESC_GPIO_Pin_CS;
void spi_setup(void)
{
SPI.begin();
pinMode(SCS, OUTPUT);
spi_unselect(0);
delay(100);
SPI.beginTransaction(SPISettings(SPIX_ESC_SPEED, MSBFIRST, SPI_MODE0));
}
void spi_select (int8_t board)
{
// Soft CSN
#if SCS_ACTIVE_POLARITY == SCS_LOW
digitalWrite(SCS, LOW);
#endif
}
void spi_unselect (int8_t board)
{
// Soft CSN
#if SCS_ACTIVE_POLARITY == SCS_LOW
digitalWrite(SCS, HIGH);
#endif
}
inline static uint8_t spi_transfer_byte(uint8_t byte)
{
return SPI.transfer(byte);
// AVR will need handling last byte transfer difference,
// but then again they pobably wont even fit EtherCAT stack in RAM
// so no need to care for now
}
void write (int8_t board, uint8_t *data, uint8_t size)
{
for(int i = 0; i < size; ++i)
{
spi_transfer_byte(data[i]);
}
}
void read (int8_t board, uint8_t *result, uint8_t size)
{
for(int i = 0; i < size; ++i)
{
result[i] = spi_transfer_byte(DUMMY_BYTE);
}
}
void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size)
{
for(int i = 0; i < size; ++i)
{
result[i] = spi_transfer_byte(data[i]);
}
}

View File

@@ -0,0 +1,15 @@
#ifndef SRC_APP_SPI_H_
#define SRC_APP_SPI_H_
#include <stdint.h>
void spi_setup(void);
void spi_select (int8_t board);
void spi_unselect (int8_t board);
void write (int8_t board, uint8_t *data, uint8_t size);
void read (int8_t board, uint8_t *result, uint8_t size);
void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size);
#endif /* SRC_APP_SPI_H_ */

View File

@@ -0,0 +1,25 @@
#ifndef SRC_APP_SPI_H_
#define SRC_APP_SPI_H_
#include <stdint.h>
#define SCS_LOW 0
#define SCS_HIGH 1
#define SCS_ACTIVE_POLARITY SCS_LOW
#define SPIX_ESC SPI1
//#define SPIX_ESC_SPEED 18000000
#define SPIX_ESC_SPEED 50000000
#define ESC_GPIO_Pin_CS PC4
#define DUMMY_BYTE 0xFF
extern "C" void spi_setup(void);
extern "C" void spi_select (int8_t board);
extern "C" void spi_unselect (int8_t board);
extern "C" void write (int8_t board, uint8_t *data, uint8_t size);
extern "C" void read (int8_t board, uint8_t *result, uint8_t size);
extern "C" void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size);
#endif /* SRC_APP_SPI_H_ */

View File

@@ -0,0 +1,25 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:genericSTM32F407VGT6]
framework = arduino
platform = ststm32
board = genericSTM32F407VGT6
upload_protocol = stlink
debug_tool = stlink
debug_build_flags = -O0 -g -ggdb
monitor_port = COM19
monitor_filters = send_on_enter, time, colorize, log2file
monitor_speed = 115200
build_flags = -Wl,--no-warn-rwx-segment -DNO_ECAT -DADS1xxx
lib_deps =
SPI
pilotak/MCP3X21@^1.0.1
robtillaart/ADS1X15@^0.5.2

View File

@@ -0,0 +1,18 @@
#include "extend32to64.h"
// Extend from 32-bit to 64-bit precision
int64_t extend32to64::extendTime(uint32_t in)
{
int64_t c64 = (int64_t)in - HALF_PERIOD; // remove half period to determine (+/-) sign of the wrap
int64_t dif = (c64 - previousTimeValue); // core concept: prev + (current - prev) = current
// wrap difference from -HALF_PERIOD to HALF_PERIOD. modulo prevents differences after the wrap from having an incorrect result
int64_t mod_dif = ((dif + HALF_PERIOD) % ONE_PERIOD) - HALF_PERIOD;
if (dif < int64_t(-HALF_PERIOD))
mod_dif += ONE_PERIOD; // account for mod of negative number behavior in C
int64_t unwrapped = previousTimeValue + mod_dif;
previousTimeValue = unwrapped; // load previous value
return unwrapped + HALF_PERIOD; // remove the shift we applied at the beginning, and return
}

View File

@@ -0,0 +1,256 @@
#include <Arduino.h>
#include <stdio.h>
extern "C"
{
#include "ecat_slv.h"
#include "utypes.h"
};
_Objects Obj;
#include "extend32to64.h"
extend32to64 longTime;
volatile uint64_t irqTime = 0;
HardwareSerial Serial1(PA10, PA9);
uint8_t inputPin[] = {PD15, PD14, PD13, PD12, PD11, PD10, PD9, PD8, PB15, PB14, PB13, PB12};
uint8_t outputPin[] = {PE10, PE9, PE8, PE7};
const uint32_t I2C_BUS_SPEED = 100000;
uint32_t I2C_restarts = 0;
#include "Wire.h"
TwoWire Wire2(PB11, PB10);
#ifdef MCP3221
#include "MyMCP3221.h"
MyMCP3221 mcp3221_0(0x48, &Wire2);
MyMCP3221 mcp3221_7(0x4f, &Wire2);
#endif
#ifdef ADS1xxx
#include "ADS1X15.h"
ADS1115 ads1115(0x48, &Wire2);
#endif
#define bitset(byte, nbit) ((byte) |= (1 << (nbit)))
#define bitclear(byte, nbit) ((byte) &= ~(1 << (nbit)))
#define bitflip(byte, nbit) ((byte) ^= (1 << (nbit)))
#define bitcheck(byte, nbit) ((byte) & (1 << (nbit)))
volatile uint16_t ALEventIRQ; // ALEvent that caused the interrupt
void cb_set_outputs(void) // Get Master outputs, slave inputs, first operation
{
// Update digital output pins
for (int i = 0; i < sizeof(outputPin); i++)
digitalWrite(outputPin[i], bitcheck(Obj.Output4, i) ? HIGH : LOW);
}
void cb_get_inputs(void) // Set Master inputs, slave outputs, last operation
{
static float validData0 = 0.0, validVoltage0 = 0.0;
for (int i = 0; i < sizeof(inputPin); i++)
Obj.Input12 = digitalRead(inputPin[i]) == HIGH ? bitset(Obj.Input12, i) : bitclear(Obj.Input12, i);
float scale = Obj.VoltageScale;
if (scale == 0.0)
scale = 1.0;
#ifdef MCP3221
int data0 = mcp3221_0.getData();
int stat = mcp3221_0.ping();
#endif
#ifdef ADS1xxx
int data0 = ads1115.readADC_Differential_0_1();
int stat = ads1115.isConnected();
#endif
if (stat == 0)
{ // Read good value
Obj.CalculatedVoltage = scale * data0 + Obj.VoltageOffset; //
Obj.RawData = data0; // Raw voltage, read by ADC
validVoltage0 = Obj.CalculatedVoltage;
validData0 = data0;
}
else
{ // Didn't read a good value. Return a hopefully useful value and restart the I2C bus
Obj.CalculatedVoltage = validVoltage0; // Use value from previous call
Obj.RawData = validData0;
// Reset wire here
Wire2.end();
Wire2.begin();
Wire2.setClock(I2C_BUS_SPEED);
I2C_restarts++;
}
Obj.Status = I2C_restarts + (stat << 28); // Put status as bits 28-31, the lower are number of restarts (restart attempts)
}
void ESC_interrupt_enable(uint32_t mask);
void ESC_interrupt_disable(uint32_t mask);
uint16_t dc_checker(void);
void sync0Handler(void);
static esc_cfg_t config =
{
.user_arg = NULL,
.use_interrupt = 1,
.watchdog_cnt = 150,
.set_defaults_hook = NULL,
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = ESC_interrupt_enable,
.esc_hw_interrupt_disable = ESC_interrupt_disable,
.esc_hw_eep_handler = NULL,
.esc_check_dc_handler = dc_checker,
};
volatile byte serveIRQ = 0;
void setup(void)
{
Serial1.begin(115200);
for (int i = 0; i < sizeof(inputPin); i++)
pinMode(inputPin[i], INPUT_PULLDOWN);
for (int i = 0; i < sizeof(outputPin); i++)
{
pinMode(outputPin[i], OUTPUT);
digitalWrite(outputPin[i], LOW);
}
// Debug leds
pinMode(PB4, OUTPUT);
pinMode(PB5, OUTPUT);
pinMode(PB6, OUTPUT);
pinMode(PB7, OUTPUT);
digitalWrite(PB4, LOW);
digitalWrite(PB5, LOW);
digitalWrite(PB6, LOW);
digitalWrite(PB7, LOW);
Wire2.begin();
Wire2.setClock(I2C_BUS_SPEED);
#ifdef ADS1xxx
ads1115.begin();
ads1115.setGain(1); // 4.096V
ads1115.setMode(1); // Single
ads1115.setDataRate(7);
#endif
#ifdef ECAT
ecat_slv_init(&config);
#endif
#if 1 // Uncomment for commissioning tests
digitalWrite(outputPin[0], HIGH); // All four output leds should go high
digitalWrite(outputPin[1], HIGH);
digitalWrite(outputPin[2], HIGH);
digitalWrite(outputPin[3], HIGH);
while (1) // Apply voltage over the inputs 0-11 and see response in terminal
{
int nDevices = 0;
for (int i2caddr = 0; i2caddr < 127; i2caddr++)
{
Wire2.beginTransmission(i2caddr);
int stat = Wire2.endTransmission();
if (stat == 0)
{
Serial1.printf("I2C device found at address 0x%2x\b", i2caddr);
nDevices++;
}
}
Serial1.printf("Found %d devices\n", nDevices);
#ifdef MCP3221
Serial1.printf("I2C status=%d rawdata=%d ", mcp3221_0.ping(), mcp3221_0.getData());
#endif
#ifdef ADS1xxx
Serial1.printf("I2C status=%d rawdata=%d ", ads1115.isConnected() ? 0 : -1, ads1115.readADC_Differential_0_1());
#endif
for (int i = 0; i < 12; i++)
Serial1.printf("%u", digitalRead(inputPin[i]));
Serial1.println();
delay(100);
}
#endif
}
void loop(void)
{
#ifdef ECAT
uint64_t dTime;
if (serveIRQ)
{
DIG_process(ALEventIRQ, DIG_PROCESS_WD_FLAG | DIG_PROCESS_OUTPUTS_FLAG |
DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
serveIRQ = 0;
ESCvar.PrevTime = ESCvar.Time;
ecat_slv_poll();
}
dTime = longTime.extendTime(micros()) - irqTime;
if (dTime > 5000) // Not doing interrupts - handle free-run
ecat_slv();
#endif
}
void sync0Handler(void)
{
ALEventIRQ = ESC_ALeventread();
// if (ALEventIRQ & ESCREG_ALEVENT_SM2)
{
irqTime = longTime.extendTime(micros());
serveIRQ = 1;
}
}
// Enable SM2 interrupts
void ESC_interrupt_enable(uint32_t mask)
{
// Enable interrupt for SYNC0 or SM2 or SM3
uint32_t user_int_mask = ESCREG_ALEVENT_DC_SYNC0 | ESCREG_ALEVENT_SM2 | ESCREG_ALEVENT_SM3;
if (mask & user_int_mask)
{
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | (mask & user_int_mask));
ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(ESCREG_ALEVENT_DC_SYNC0 | ESCREG_ALEVENT_SM3));
attachInterrupt(digitalPinToInterrupt(PC3), sync0Handler, RISING);
// Set LAN9252 interrupt pin driver as push-pull active high
uint32_t bits = 0x00000111;
ESC_write(0x54, &bits, 4);
// Enable LAN9252 interrupt
bits = 0x00000001;
ESC_write(0x5c, &bits, 4);
}
}
// Disable SM2 interrupts
void ESC_interrupt_disable(uint32_t mask)
{
// Enable interrupt for SYNC0 or SM2 or SM3
// uint32_t user_int_mask = ESCREG_ALEVENT_DC_SYNC0 | ESCREG_ALEVENT_SM2 | ESCREG_ALEVENT_SM3;
uint32_t user_int_mask = ESCREG_ALEVENT_SM2;
if (mask & user_int_mask)
{
// Disable interrupt from SYNC0
ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(mask & user_int_mask));
detachInterrupt(digitalPinToInterrupt(PC3));
// Disable LAN9252 interrupt
uint32_t bits = 0x00000000;
ESC_write(0x5c, &bits, 4);
}
}
extern "C" uint32_t ESC_SYNC0cycletime(void);
// Setup of DC
uint16_t dc_checker(void)
{
// Indicate we run DC
ESCvar.dcsync = 1;
return 0;
}

View File

@@ -0,0 +1,2 @@
Gerbers

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "All Layers",
"auto_track_width": true,
"hidden_netclasses": [],
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"images": 0.6,
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": false,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
8,
9,
10,
11,
12,
13,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36,
39,
40
],
"visible_layers": "fffffff_ffffffff",
"zone_display_mode": 0
},
"git": {
"repo_password": "",
"repo_type": "",
"repo_username": "",
"ssh_key": ""
},
"meta": {
"filename": "EaserCAT-7000.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

View File

@@ -0,0 +1,690 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.1,
"copper_line_width": 0.2,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.05,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.1,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.15,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 3.5,
"height": 3.5,
"width": 3.5
},
"silk_line_width": 0.15,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_symbol_mismatch": "warning",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"holes_co_located": "warning",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.0,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.2,
"min_microvia_drill": 0.1,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.8,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.1,
"min_via_diameter": 0.5,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 1.0
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"conflicting_netclasses": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"simulation_model_issue": "ignore",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "EaserCAT-7000.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "C:/Program Files/KiCad/7.0/",
"plot": "Gerbers/",
"pos_files": "",
"specctra_dsn": "EaserCAT-7000.dsn",
"step": "EaserCAT-7000.step",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"bom_export_filename": "EaserCAT-7000.csv",
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
},
{
"group_by": false,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "${QUANTITY}",
"show": true
},
{
"group_by": true,
"label": "DNP",
"name": "${DNP}",
"show": true
},
{
"group_by": false,
"label": "#",
"name": "${ITEM_NUMBER}",
"show": false
},
{
"group_by": false,
"label": "Availability",
"name": "Availability",
"show": false
},
{
"group_by": false,
"label": "Check_prices",
"name": "Check_prices",
"show": false
},
{
"group_by": false,
"label": "MANUFACTURER",
"name": "MANUFACTURER",
"show": false
},
{
"group_by": false,
"label": "MAXIMUM_PACKAGE_HEIGHT",
"name": "MAXIMUM_PACKAGE_HEIGHT",
"show": false
},
{
"group_by": false,
"label": "MF",
"name": "MF",
"show": false
},
{
"group_by": false,
"label": "MP",
"name": "MP",
"show": false
},
{
"group_by": false,
"label": "PARTREV",
"name": "PARTREV",
"show": false
},
{
"group_by": false,
"label": "Package",
"name": "Package",
"show": false
},
{
"group_by": false,
"label": "Price",
"name": "Price",
"show": false
},
{
"group_by": false,
"label": "Purchase-URL",
"name": "Purchase-URL",
"show": false
},
{
"group_by": false,
"label": "STANDARD",
"name": "STANDARD",
"show": false
},
{
"group_by": false,
"label": "SnapEDA_Link",
"name": "SnapEDA_Link",
"show": false
},
{
"group_by": false,
"label": "Description",
"name": "Description",
"show": false
}
],
"filter_string": "",
"group_symbols": true,
"name": "",
"sort_asc": true,
"sort_field": "Reference"
},
"connection_grid_size": 50.0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"overbar_offset_ratio": 1.23,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"page_layout_descr_file": "",
"plot_directory": "",
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false,
"spice_save_all_dissipations": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"5597aedc-b607-407f-bbfd-31b3b298ecb1",
"Root"
],
[
"bb884533-7795-46fd-b0b1-55ff193103ce",
"LAN9252 SPI"
],
[
"650f1ee4-2ce7-4e9d-a70d-f9d8defa5d03",
"LAN9252 network etc"
],
[
"d564400f-40ba-4aca-9c2a-14ec52a8353b",
"STM32F407VGT6"
],
[
"b6f9794d-a1ac-41d9-a609-de182b88f0f8",
"Digital IOs"
],
[
"6bc8268b-123e-4904-80e9-de4fbe627e3b",
"I2C"
]
],
"text_variables": {}
}

View File

@@ -0,0 +1,206 @@
(kicad_sch
(version 20231120)
(generator "eeschema")
(generator_version "8.0")
(uuid "5597aedc-b607-407f-bbfd-31b3b298ecb1")
(paper "A4")
(title_block
(title "THCAD reader")
)
(lib_symbols)
(sheet
(at 40.64 59.055)
(size 82.55 17.78)
(fields_autoplaced yes)
(stroke
(width 0.1524)
(type solid)
)
(fill
(color 0 0 0 0.0000)
)
(uuid "650f1ee4-2ce7-4e9d-a70d-f9d8defa5d03")
(property "Sheetname" "LAN9252 network etc"
(at 40.64 58.3434 0)
(effects
(font
(size 1.27 1.27)
)
(justify left bottom)
)
)
(property "Sheetfile" "LAN9252_diverse.kicad_sch"
(at 40.64 77.4196 0)
(effects
(font
(size 1.27 1.27)
)
(justify left top)
)
)
(instances
(project "EaserCAT-7000"
(path "/5597aedc-b607-407f-bbfd-31b3b298ecb1"
(page "3")
)
)
)
)
(sheet
(at 138.43 59.69)
(size 76.835 17.78)
(fields_autoplaced yes)
(stroke
(width 0.1524)
(type solid)
)
(fill
(color 0 0 0 0.0000)
)
(uuid "6bc8268b-123e-4904-80e9-de4fbe627e3b")
(property "Sheetname" "I2C"
(at 138.43 58.9784 0)
(effects
(font
(size 1.27 1.27)
)
(justify left bottom)
)
)
(property "Sheetfile" "I2C.kicad_sch"
(at 138.43 78.0546 0)
(effects
(font
(size 1.27 1.27)
)
(justify left top)
)
)
(instances
(project "EaserCAT-7000"
(path "/5597aedc-b607-407f-bbfd-31b3b298ecb1"
(page "7")
)
)
)
)
(sheet
(at 137.16 33.655)
(size 71.12 16.51)
(fields_autoplaced yes)
(stroke
(width 0.1524)
(type solid)
)
(fill
(color 0 0 0 0.0000)
)
(uuid "b6f9794d-a1ac-41d9-a609-de182b88f0f8")
(property "Sheetname" "Digital IOs"
(at 137.16 32.9434 0)
(effects
(font
(size 1.27 1.27)
)
(justify left bottom)
)
)
(property "Sheetfile" "peripherals.kicad_sch"
(at 137.16 50.7496 0)
(effects
(font
(size 1.27 1.27)
)
(justify left top)
)
)
(instances
(project "EaserCAT-7000"
(path "/5597aedc-b607-407f-bbfd-31b3b298ecb1"
(page "6")
)
)
)
)
(sheet
(at 40.005 33.655)
(size 82.55 17.78)
(fields_autoplaced yes)
(stroke
(width 0.1524)
(type solid)
)
(fill
(color 0 0 0 0.0000)
)
(uuid "bb884533-7795-46fd-b0b1-55ff193103ce")
(property "Sheetname" "LAN9252 SPI"
(at 40.005 32.9434 0)
(effects
(font
(size 1.27 1.27)
)
(justify left bottom)
)
)
(property "Sheetfile" "LAN9252_DIO_SPI.kicad_sch"
(at 40.005 52.0196 0)
(effects
(font
(size 1.27 1.27)
)
(justify left top)
)
)
(instances
(project "EaserCAT-7000"
(path "/5597aedc-b607-407f-bbfd-31b3b298ecb1"
(page "2")
)
)
)
)
(sheet
(at 42.545 89.535)
(size 80.645 19.685)
(fields_autoplaced yes)
(stroke
(width 0.1524)
(type solid)
)
(fill
(color 0 0 0 0.0000)
)
(uuid "d564400f-40ba-4aca-9c2a-14ec52a8353b")
(property "Sheetname" "STM32F407VGT6"
(at 42.545 88.8234 0)
(effects
(font
(size 1.27 1.27)
)
(justify left bottom)
)
)
(property "Sheetfile" "STM32F4.kicad_sch"
(at 42.545 109.8046 0)
(effects
(font
(size 1.27 1.27)
)
(justify left top)
)
)
(instances
(project "EaserCAT-7000"
(path "/5597aedc-b607-407f-bbfd-31b3b298ecb1"
(page "4")
)
)
)
)
(sheet_instances
(path "/"
(page "1")
)
)
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,321 @@
(kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor)
(symbol "LAN9252_PT" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U" (at -60.96 59.69 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Value" "LAN9252_PT" (at -29.21 -60.96 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Footprint" "LAN9252_PT:QFP50P1200X1200X120-65N" (at -5.08 6.35 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Datasheet" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "MF" "Microchip" (at -1.27 -13.97 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MAXIMUM_PACKAGE_HEIGHT" "1.2 mm" (at 0 -2.54 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Package" "TQFP-64 Microchip" (at -1.27 -11.43 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Price" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Check_prices" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "STANDARD" "IPC 7351B" (at -1.27 -5.08 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "PARTREV" "04-08-15" (at -1.27 -13.97 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "SnapEDA_Link" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MP" "LAN9252/PT" (at -2.54 3.81 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Purchase-URL" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Description" "\nEthernet Controller 10/100 Base-FX/T/TX PHY SPI Interface 64-TQFP-EP (10x10)\n" (at -1.27 10.16 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Availability" "" (at 0 -2.54 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MANUFACTURER" "Microchip Technology" (at -1.27 -8.89 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(symbol "LAN9252_PT_0_0"
(rectangle (start -29.21 58.42) (end 60.96 -59.69)
(stroke (width 0.254) (type default))
(fill (type background))
)
(pin input line (at -34.29 -2.54 0) (length 5.08)
(name "OSCI" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin input line (at -34.29 12.7 0) (length 5.08)
(name "FXSDB/FXLOSB/~{FXSDENB}" (effects (font (size 1.016 1.016))))
(number "10" (effects (font (size 1.016 1.016))))
)
(pin input line (at -34.29 30.48 0) (length 5.08)
(name "~{RST}" (effects (font (size 1.016 1.016))))
(number "11" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -10.16 180) (length 5.08)
(name "D2/AD2/SOF/SIO2" (effects (font (size 1.016 1.016))))
(number "12" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -7.62 180) (length 5.08)
(name "D1/AD1/EOF/SO/SIO1" (effects (font (size 1.016 1.016))))
(number "13" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 59.69 180) (length 5.08)
(name "VDDIO" (effects (font (size 1.016 1.016))))
(number "14" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -40.64 180) (length 5.08)
(name "D14/AD14/DIGIO8/GPI8/GPO8/MII_TXD3/~{TX_SHIFT1}" (effects (font (size 1.016 1.016))))
(number "15" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -38.1 180) (length 5.08)
(name "D13/AD13/DIGIO7/GPI7/GPO7/MII_TXD2/~{TX_SHIFT0}" (effects (font (size 1.016 1.016))))
(number "16" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -5.08 180) (length 5.08)
(name "D0/AD0/WD_STATE/SI/SIO0" (effects (font (size 1.016 1.016))))
(number "17" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -34.29 -25.4 0) (length 5.08)
(name "SYNC1/LATCH1" (effects (font (size 1.016 1.016))))
(number "18" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -27.94 180) (length 5.08)
(name "D9/AD9/LATCH_IN/SCK" (effects (font (size 1.016 1.016))))
(number "19" (effects (font (size 1.016 1.016))))
)
(pin output line (at -34.29 -5.08 0) (length 5.08)
(name "OSCO" (effects (font (size 1.016 1.016))))
(number "2" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 60.96 180) (length 5.08)
(name "VDDIO" (effects (font (size 1.016 1.016))))
(number "20" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -35.56 180) (length 5.08)
(name "D12/AD12/DIGIO6/GPI6/GPO6/MII_TXD1" (effects (font (size 1.016 1.016))))
(number "21" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -33.02 180) (length 5.08)
(name "D11/AD11/DIGIO5/GPI5/GPO5/MII_TXD0" (effects (font (size 1.016 1.016))))
(number "22" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -30.48 180) (length 5.08)
(name "D10/AD10/DIGIO4/GPI4/GPO4/MII_TXEN" (effects (font (size 1.016 1.016))))
(number "23" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 55.88 180) (length 5.08)
(name "VDDCR" (effects (font (size 1.016 1.016))))
(number "24" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -34.29 -35.56 0) (length 5.08)
(name "A1/ALELO/OE_EXT/MII_CLK25" (effects (font (size 1.016 1.016))))
(number "25" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -34.29 -40.64 0) (length 5.08)
(name "A3/DIGIO11/GPI11/GPO11/MII_RXDV" (effects (font (size 1.016 1.016))))
(number "26" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -34.29 -43.18 0) (length 5.08)
(name "A4/DIGIO12/GPI12/GPO12/MII_RXD0" (effects (font (size 1.016 1.016))))
(number "27" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -34.29 -30.48 0) (length 5.08)
(name "CS/DIGIO13/GPI13/GPO13/MII_RXD1" (effects (font (size 1.016 1.016))))
(number "28" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -34.29 -38.1 0) (length 5.08)
(name "A2/ALEHI/DIGIO10/GPI10/GPO10/LINKACTLED2/~{MII_LINKPOL}" (effects (font (size 1.016 1.016))))
(number "29" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 48.26 180) (length 5.08)
(name "OSCVDD12" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 2.54 180) (length 5.08)
(name "WR/ENB/DIGIO14/GPI14/GPO14/MII_RXD2" (effects (font (size 1.016 1.016))))
(number "30" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 0 180) (length 5.08)
(name "RD/RD_WR/DIGIO15/GPI15/GPO15/MII_RXD3" (effects (font (size 1.016 1.016))))
(number "31" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 62.23 180) (length 5.08)
(name "VDDIO" (effects (font (size 1.016 1.016))))
(number "32" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -43.18 180) (length 5.08)
(name "A0/D15/AD15/DIGIO9/GPI9/GPO9/MII_RXER" (effects (font (size 1.016 1.016))))
(number "33" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -34.29 -22.86 0) (length 5.08)
(name "SYNC0/LATCH0" (effects (font (size 1.016 1.016))))
(number "34" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -12.7 180) (length 5.08)
(name "D3/AD3/WD_TRIG/SIO3" (effects (font (size 1.016 1.016))))
(number "35" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -20.32 180) (length 5.08)
(name "D6/AD6/DIGIO0/GPI0/GPO0/MII_RXCLK" (effects (font (size 1.016 1.016))))
(number "36" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 63.5 180) (length 5.08)
(name "VDDIO" (effects (font (size 1.016 1.016))))
(number "37" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 54.61 180) (length 5.08)
(name "VDDCR" (effects (font (size 1.016 1.016))))
(number "38" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -22.86 180) (length 5.08)
(name "D7/AD7/DIGIO1/GPI1/GPO1/MII_MDC" (effects (font (size 1.016 1.016))))
(number "39" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 -55.88 180) (length 5.08)
(name "OSCVSS" (effects (font (size 1.016 1.016))))
(number "4" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -25.4 180) (length 5.08)
(name "D8/AD8/DIGIO2/GPI2/GPO2/MII_MDIO" (effects (font (size 1.016 1.016))))
(number "40" (effects (font (size 1.016 1.016))))
)
(pin input line (at 66.04 -48.26 180) (length 5.08)
(name "TESTMODE" (effects (font (size 1.016 1.016))))
(number "41" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -34.29 5.08 0) (length 5.08)
(name "EESDA/TMS" (effects (font (size 1.016 1.016))))
(number "42" (effects (font (size 1.016 1.016))))
)
(pin output clock (at -34.29 2.54 0) (length 5.08)
(name "EESCL/TCK" (effects (font (size 1.016 1.016))))
(number "43" (effects (font (size 1.016 1.016))))
)
(pin output line (at 66.04 30.48 180) (length 5.08)
(name "IRQ" (effects (font (size 1.016 1.016))))
(number "44" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -34.29 -17.78 0) (length 5.08)
(name "RUNLED/~{E2PSIZE}" (effects (font (size 1.016 1.016))))
(number "45" (effects (font (size 1.016 1.016))))
)
(pin input line (at -34.29 -12.7 0) (length 5.08)
(name "LINKACTLED1/TDI/~{CHIP_MODE1}" (effects (font (size 1.016 1.016))))
(number "46" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 58.42 180) (length 5.08)
(name "VDDIO" (effects (font (size 1.016 1.016))))
(number "47" (effects (font (size 1.016 1.016))))
)
(pin output line (at -34.29 -10.16 0) (length 5.08)
(name "LINKACTLED0/TDO/~{CHIP_MODE0}" (effects (font (size 1.016 1.016))))
(number "48" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -15.24 180) (length 5.08)
(name "D4/AD4/DIGIO3/GPI3/GPO3/MII_LINK" (effects (font (size 1.016 1.016))))
(number "49" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 50.8 180) (length 5.08)
(name "VDD33" (effects (font (size 1.016 1.016))))
(number "5" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 -17.78 180) (length 5.08)
(name "D5/AD5/OUTVALID/SCS#" (effects (font (size 1.016 1.016))))
(number "50" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 38.1 180) (length 5.08)
(name "VDD33TXRX1" (effects (font (size 1.016 1.016))))
(number "51" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 22.86 180) (length 5.08)
(name "TXNA" (effects (font (size 1.016 1.016))))
(number "52" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 25.4 180) (length 5.08)
(name "TXPA" (effects (font (size 1.016 1.016))))
(number "53" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 17.78 180) (length 5.08)
(name "RXNA" (effects (font (size 1.016 1.016))))
(number "54" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 20.32 180) (length 5.08)
(name "RXPA" (effects (font (size 1.016 1.016))))
(number "55" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 45.72 180) (length 5.08)
(name "VDD12TX1" (effects (font (size 1.016 1.016))))
(number "56" (effects (font (size 1.016 1.016))))
)
(pin passive line (at -34.29 -48.26 0) (length 5.08)
(name "RBIAS" (effects (font (size 1.016 1.016))))
(number "57" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 40.64 180) (length 5.08)
(name "VDD33BIAS" (effects (font (size 1.016 1.016))))
(number "58" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 43.18 180) (length 5.08)
(name "VDD12TX2" (effects (font (size 1.016 1.016))))
(number "59" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 53.34 180) (length 5.08)
(name "VDDCR" (effects (font (size 1.016 1.016))))
(number "6" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 10.16 180) (length 5.08)
(name "RXPB" (effects (font (size 1.016 1.016))))
(number "60" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 7.62 180) (length 5.08)
(name "RXNB" (effects (font (size 1.016 1.016))))
(number "61" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 15.24 180) (length 5.08)
(name "TXPB" (effects (font (size 1.016 1.016))))
(number "62" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 66.04 12.7 180) (length 5.08)
(name "TXNB" (effects (font (size 1.016 1.016))))
(number "63" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 35.56 180) (length 5.08)
(name "VDD33TXRX2" (effects (font (size 1.016 1.016))))
(number "64" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 66.04 -53.34 180) (length 5.08)
(name "VSS" (effects (font (size 1.016 1.016))))
(number "65" (effects (font (size 1.016 1.016))))
)
(pin input line (at -34.29 25.4 0) (length 5.08)
(name "REG_EN" (effects (font (size 1.016 1.016))))
(number "7" (effects (font (size 1.016 1.016))))
)
(pin input line (at -34.29 17.78 0) (length 5.08)
(name "~{FXLOSEN}" (effects (font (size 1.016 1.016))))
(number "8" (effects (font (size 1.016 1.016))))
)
(pin input line (at -34.29 15.24 0) (length 5.08)
(name "FXSDA/FXLOSA/~{FXSDENA}" (effects (font (size 1.016 1.016))))
(number "9" (effects (font (size 1.016 1.016))))
)
)
)
)

View File

@@ -0,0 +1 @@
0

File diff suppressed because it is too large Load Diff