Compare commits
156 Commits
Author | SHA1 | Date |
---|---|---|
nakarlsson | 8f3841e3ce | |
Andreas Karlsson | fcd43fb2e6 | |
nakarlsson | 66111d50fa | |
Andreas Karlsson | 41438c4a33 | |
nakarlsson | 56124c2348 | |
Andreas Karlsson | d04bed4666 | |
nakarlsson | 05bf6c6726 | |
Andreas Karlsson | 9525469a68 | |
nakarlsson | 3fe4511230 | |
Vijay Katoch | e2f3fb7fd2 | |
nakarlsson | 6e70471e1b | |
Andreas Karlsson | 70a1042188 | |
Andreas Karlsson | 2f4afb3230 | |
nakarlsson | 5221cfbe76 | |
Andreas Karlsson | 0d232899bb | |
Andreas Karlsson | 3896a981ce | |
Andreas Karlsson | 45d390a014 | |
Andreas Karlsson | f63bca476d | |
Andreas Karlsson | d22277f4a5 | |
Andreas Karlsson | ac198e05b1 | |
Andreas Karlsson | 60e397aebc | |
Andreas Karlsson | 97472108e3 | |
Andreas Karlsson | fd6dbdf188 | |
Andreas Karlsson | 3bb489469b | |
nakarlsson | 8bb4350cd5 | |
Andreas Karlsson | fff8e22603 | |
nakarlsson | a7a017c26f | |
nakarlsson | ac0031aef5 | |
Andreas Karlsson | 8ebb78ea10 | |
m-dema | 66b040a257 | |
nakarlsson | 8de160a851 | |
Fumihito Sugai | 35288ff3e7 | |
nakarlsson | fc72fbeeec | |
Konrad Hermsdorf | 254a6f807d | |
andreas karlsson | 48c80f5cae | |
nakarlsson | acc59dd6b8 | |
andreas karlsson | 366c07f446 | |
nakarlsson | 6fc395e085 | |
Hans-Erik Floryd | d96f7cefef | |
nakarlsson | fa0d6bf4d6 | |
Lars Danielsson | 69b1049970 | |
Hans-Erik Floryd | 3c5af65be6 | |
andreas karlsson | df0d169eef | |
nakarlsson | 311977e47a | |
Juan Leyva | da33a714a1 | |
Juan Leyva | cd12c0d156 | |
nakarlsson | ff6be22c80 | |
Hans-Erik Floryd | 2808e95668 | |
Hans-Erik Floryd | 097477035d | |
Hans-Erik Floryd | 4d9da268be | |
Juan Leyva | 5e94f0bb81 | |
Hans-Erik Floryd | 4549d0af9a | |
MechaMagpie | 98a90d61ea | |
iwoodsawyer | b3e2a0a2c1 | |
nakarlsson | 2fd5088fea | |
m-dema | c84a3ffb4d | |
nakarlsson | 1f24b72c5c | |
Lars Danielsson | e40d95cc1e | |
nakarlsson | f244ea522d | |
Hans-Erik Floryd | 0d6f7de0e6 | |
Hans-Erik Floryd | 591d08d474 | |
Hans-Erik Floryd | 85319b8524 | |
Hans-Erik Floryd | eb1848a9a3 | |
Lars Danielsson | 8d5afc9b2d | |
Lars Danielsson | 87b2c1eb93 | |
Lars Danielsson | 48772707a6 | |
Lars Danielsson | c814d2dacf | |
Hans-Erik Floryd | 71bb37091f | |
Lars Danielsson | 74d710b8b7 | |
Lars Danielsson | a6f45c308f | |
Hans-Erik Floryd | 9ea52dff56 | |
Lars Danielsson | c0d3e17bcf | |
Lars Danielsson | 177739b02d | |
Hans-Erik Floryd | ed6a6542c8 | |
Lars Danielsson | d9ebdc99fe | |
Lars Danielsson | 59728c994c | |
Lars Danielsson | dd21bd3423 | |
Lars Danielsson | d970d8eb1e | |
Lars Danielsson | 9a430287d1 | |
Lars Danielsson | aee9bf569b | |
Hans-Erik Floryd | 4746f22c78 | |
Hans-Erik Floryd | 09394ecfc8 | |
Lars Danielsson | 32c8901940 | |
Lars Danielsson | 12006a53a5 | |
Lars Danielsson | 86c17dbb14 | |
Lars Danielsson | cde698b1ea | |
Andreas Karlsson | 28e19f4f82 | |
nakarlsson | ba3adf8b74 | |
Lars Danielsson | e428008ea3 | |
Lars Danielsson | b6f4444b9e | |
Lars Danielsson | 78871af81b | |
Lars Danielsson | 6eedcb7cdf | |
Lars Danielsson | bdea958dd5 | |
Andreas Karlsson | 24b700e1c4 | |
Hans-Erik Floryd | 46240450af | |
Lars Danielsson | bb566504de | |
Lars Danielsson | 81ff180e7e | |
Hans-Erik Floryd | 3792b58fea | |
Lars Danielsson | 2296b55812 | |
Hans-Erik Floryd | 0878d71924 | |
Andreas Karlsson | 8ff826c409 | |
Andreas Karlsson | 767c38b0b6 | |
Hans-Erik Floryd | f16daf271e | |
Hans-Erik Floryd | 9cc583613b | |
nakarlsson | 45bca4853a | |
Hans-Erik Floryd | c8575b795f | |
Hans-Erik Floryd | f0a378382e | |
Hans-Erik Floryd | f61e77a5d1 | |
Ilias Patsiaouras | 75a5514430 | |
Ilias Patsiaouras | 38099d31ed | |
nakarlsson | 0f2959be46 | |
Ilias Patsiaouras | 576624fd70 | |
Hans-Erik Floryd | b46bb0ab0e | |
Hans-Erik Floryd | 489c5e257e | |
Hans-Erik Floryd | 27ab8dfba5 | |
Andreas Karlsson | e600a515c5 | |
Andreas Karlsson | 5770a66558 | |
Andreas Karlsson | 68427b6e1e | |
Andreas Karlsson | 54de5af4b5 | |
Hans-Erik Floryd | 14397b0575 | |
Hans-Erik Floryd | d204255ad3 | |
Hans-Erik Floryd | 236a02bfb4 | |
Hans-Erik Floryd | 55df56821a | |
Hans-Erik Floryd | e27b6bcbb1 | |
Hans-Erik Floryd | aa811ae2f4 | |
Hans-Erik Floryd | 675d3516fb | |
Hans-Erik Floryd | 0170a15229 | |
Hans-Erik Floryd | 5b33b077ca | |
Andreas Karlsson | 6fb665a701 | |
Andreas Karlsson | ca48f9db21 | |
Andreas Karlsson | 446b79d456 | |
Hans-Erik Floryd | c8675af12c | |
nakarlsson | df1ef3f076 | |
Hans-Erik Floryd | 0bbc40096a | |
Andreas Karlsson | ef6e55a6e2 | |
Hans-Erik Floryd | 1917a6f72b | |
Hans-Erik Floryd | 15e976f58e | |
Hans-Erik Floryd | 8abbbb1fb8 | |
Hans-Erik Floryd | c66a5efb32 | |
Hans-Erik Floryd | 45f5c616ca | |
Hans-Erik Floryd | bdb212942b | |
nakarlsson | edcce5af0f | |
Andreas Karlsson | 830a7fb394 | |
nakarlsson | 7808b675e0 | |
Andreas Karlsson | 973b774ddf | |
Andreas Karlsson | e38301eb5c | |
nakarlsson | 23291ba465 | |
xoduddk123 | 4e7f341298 | |
nakarlsson | 4bf6be795b | |
rtlaka | c08f90bb82 | |
rtlaka | 8711eb5968 | |
nakarlsson | b2bfd419a5 | |
rtlaka | ba3716ba52 | |
magnjo | 56a4dbf247 | |
Hans-Erik Floryd | 49f488ece7 | |
rtlaka | e27c903b9d |
|
@ -0,0 +1,23 @@
|
|||
name: build
|
||||
on: [push, pull_request]
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Configure
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -E make_directory $GITHUB_WORKSPACE/build
|
||||
cmake -B $GITHUB_WORKSPACE/build -S $GITHUB_WORKSPACE \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
cmake --build $GITHUB_WORKSPACE/build -j4
|
|
@ -33,3 +33,4 @@
|
|||
|
||||
/build
|
||||
soes/version.h
|
||||
applications/xmc4300_slavedemo/XMC_Peripheral_Library
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
language: c
|
||||
|
||||
script:
|
||||
- mkdir build
|
||||
- pushd build
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
- make
|
||||
- popd
|
|
@ -1,12 +1,12 @@
|
|||
# CMakeLists files in this project can
|
||||
# refer to the root source directory of the project as ${SOES_SOURCE_DIR} and
|
||||
# to the root binary directory of the project as ${SOES_BINARY_DIR}.
|
||||
cmake_minimum_required (VERSION 2.8.4)
|
||||
cmake_minimum_required (VERSION 2.8.12)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
project (SOES)
|
||||
|
||||
set (SOES_VERSION_MAJOR 2)
|
||||
set (SOES_VERSION_MINOR 1)
|
||||
set (SOES_VERSION_MAJOR 3)
|
||||
set (SOES_VERSION_MINOR 0)
|
||||
set (SOES_VERSION_PATCH 0)
|
||||
|
||||
# Generate version numbers
|
||||
|
|
10
README.md
10
README.md
|
@ -1,6 +1,6 @@
|
|||
Simple Open Source EtherCAT Slave
|
||||
====
|
||||
[![Build Status](https://travis-ci.org/OpenEtherCATsociety/SOES.svg?branch=master)](https://travis-ci.org/OpenEtherCATsociety/SOES)
|
||||
[![Build Status](https://github.com/OpenEtherCATsociety/SOES/workflows/build/badge.svg?branch=master)](https://github.com/OpenEtherCATsociety/SOES/actions?workflow=build)
|
||||
|
||||
SOES (Simple OpenSource EtherCAT Slave Stack) is an opensource slave
|
||||
stack that is very easy to use and provides a small footprint. It is a
|
||||
|
@ -12,7 +12,7 @@ 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 functions.
|
||||
|
||||
Features as of 2.1.0:
|
||||
Feature list:
|
||||
- Address offset based HAL for easy ESC read/write access via any
|
||||
interface
|
||||
- Mailbox with data link layer
|
||||
|
@ -20,14 +20,16 @@ Features as of 2.1.0:
|
|||
- Object dictionary
|
||||
- SDO read and write for all sizes including segmented transfers
|
||||
- Easy portable C-code suited for embedded applications
|
||||
- Fixed PDO mapping
|
||||
- Fixed and/or dynamic PDO mapping
|
||||
- FoE with bootstrap template
|
||||
- Support for Little and Big endian targets
|
||||
- Run polling, mixed polling/interrupt or interrupt
|
||||
- Support for SM Synchronization
|
||||
- Support DC sync0 and DC Synchronization
|
||||
- Add stack configuration via new configuration paramater to/or from
|
||||
- Add stack configuration via new configuration parameter to/or from
|
||||
"stack"_init
|
||||
- EoE
|
||||
|
||||
TODO
|
||||
- Update documentation
|
||||
- Add EoE sample application
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
add_executable (demo
|
||||
main.c
|
||||
slave.c
|
||||
slave_objectlist.c
|
||||
)
|
||||
target_link_libraries(demo LINK_PUBLIC soes)
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
#include <cc.h>
|
||||
|
||||
#define MBXSIZE 128
|
||||
#define MBXSIZEBOOT 128
|
||||
#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 0x1100
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1180
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#endif /* __CONFIG_H__ */
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef __ECAT_OPTIONS_H__
|
||||
#define __ECAT_OPTIONS_H__
|
||||
|
||||
#include "cc.h"
|
||||
|
||||
#define USE_FOE 1
|
||||
#define USE_EOE 0
|
||||
|
||||
#define MBXSIZE 128
|
||||
#define MBXSIZEBOOT 128
|
||||
#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 0x1100
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1180
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#define MAX_RXPDO_SIZE 42
|
||||
#define MAX_TXPDO_SIZE 42
|
||||
|
||||
#define MAX_MAPPINGS_SM2 2
|
||||
#define MAX_MAPPINGS_SM3 1
|
||||
|
||||
#endif /* __ECAT_OPTIONS_H__ */
|
|
@ -1,48 +1,54 @@
|
|||
#include <stdio.h>
|
||||
#include "slave.h"
|
||||
#include "ecat_slv.h"
|
||||
#include "utypes.h"
|
||||
|
||||
/**
|
||||
* This function reads physical input values and assigns the corresponding members
|
||||
* of Rb.Buttons
|
||||
*/
|
||||
void cb_get_Buttons()
|
||||
/* Application variables */
|
||||
_Objects Obj;
|
||||
|
||||
void cb_get_inputs (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members of
|
||||
* Wb.LEDs
|
||||
*/
|
||||
|
||||
|
||||
void cb_set_LEDs()
|
||||
void cb_set_outputs (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is called after a SDO write of the object Cb.Parameters.
|
||||
*/
|
||||
void cb_post_write_Parameters(int subindex)
|
||||
int main_run (void * arg)
|
||||
{
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = "/dev/lan9252",
|
||||
.use_interrupt = 0,
|
||||
.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 = NULL,
|
||||
.esc_hw_interrupt_disable = NULL,
|
||||
.esc_hw_eep_handler = NULL,
|
||||
.esc_check_dc_handler = NULL,
|
||||
};
|
||||
|
||||
}
|
||||
printf ("Hello Main\n");
|
||||
ecat_slv_init (&config);
|
||||
|
||||
void main_run(void * arg)
|
||||
{
|
||||
soes_init();
|
||||
while (1)
|
||||
{
|
||||
ecat_slv();
|
||||
}
|
||||
|
||||
while(1) {
|
||||
soes();
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Hello Main\n");
|
||||
main_run(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
printf ("Hello Main\n");
|
||||
main_run (NULL);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,300 +0,0 @@
|
|||
#include <stddef.h>
|
||||
#include "utypes.h"
|
||||
#include "esc.h"
|
||||
#include "esc_coe.h"
|
||||
#include "esc_foe.h"
|
||||
#include "config.h"
|
||||
#include "slave.h"
|
||||
|
||||
#define WATCHDOG_RESET_VALUE 150
|
||||
#define DEFAULTTXPDOMAP 0x1a00
|
||||
#define DEFAULTRXPDOMAP 0x1600
|
||||
#define DEFAULTTXPDOITEMS 1
|
||||
#define DEFAULTRXPDOITEMS 1
|
||||
|
||||
/* Global variables used by the stack */
|
||||
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
|
||||
_MBXcontrol MBXcontrol[MBXBUFFERS];
|
||||
_ESCvar ESCvar;
|
||||
|
||||
/* Application variables */
|
||||
_Rbuffer Rb;
|
||||
_Wbuffer Wb;
|
||||
_Cbuffer Cb;
|
||||
|
||||
/* Private variables */
|
||||
uint16_t txpdomap = DEFAULTTXPDOMAP;
|
||||
uint16_t rxpdomap = DEFAULTRXPDOMAP;
|
||||
uint8_t txpdoitems = DEFAULTTXPDOITEMS;
|
||||
uint8_t rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
|
||||
static int watchdog = WATCHDOG_RESET_VALUE;
|
||||
static void (*application_loop_callback)(void) = NULL;
|
||||
|
||||
/** 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 1 if the SDO Download is correct. 0 If not correct.
|
||||
*/
|
||||
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
if ((index == 0x1c12) && (subindex > 0) && (rxpdoitems != 0))
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
if ((index == 0x1c13) && (subindex > 0) && (txpdoitems != 0))
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Mandatory: 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
|
||||
*/
|
||||
void ESC_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0x1c12:
|
||||
{
|
||||
if (rxpdoitems > 1)
|
||||
{
|
||||
rxpdoitems = 1;
|
||||
}
|
||||
if ((rxpdomap != 0x1600) && (rxpdomap != 0x1601)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
rxpdomap = 0x1600;
|
||||
}
|
||||
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
|
||||
break;
|
||||
}
|
||||
case 0x1c13:
|
||||
{
|
||||
if (txpdoitems > 1)
|
||||
{
|
||||
txpdoitems = 1;
|
||||
}
|
||||
if ((txpdomap != 0x1A00) && (txpdomap != 0x1A01)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
txpdomap = 0x1A00;
|
||||
}
|
||||
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
|
||||
break;
|
||||
}
|
||||
/* Handle post-write of parameter values */
|
||||
case 0x8000:
|
||||
{
|
||||
cb_post_write_Parameters(subindex);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Mandatory: 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.
|
||||
* set
|
||||
*/
|
||||
void APP_safeoutput (void)
|
||||
{
|
||||
DPRINT ("APP_safeoutput\n");
|
||||
|
||||
// Set safe values for Wb.LEDs
|
||||
Wb.LEDs.LED0 = 0;
|
||||
Wb.LEDs.LED1 = 0;
|
||||
|
||||
}
|
||||
|
||||
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
|
||||
*/
|
||||
void TXPDO_update (void)
|
||||
{
|
||||
ESC_write (SM3_sma, &Rb, ESCvar.TXPDOsize);
|
||||
}
|
||||
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
|
||||
*/
|
||||
void RXPDO_update (void)
|
||||
{
|
||||
ESC_read (SM2_sma, &Wb, ESCvar.RXPDOsize);
|
||||
}
|
||||
|
||||
/** Mandatory: 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 (void)
|
||||
{
|
||||
if (watchdog > 0)
|
||||
{
|
||||
watchdog--;
|
||||
}
|
||||
if (ESCvar.App.state & APPSTATE_OUTPUT)
|
||||
{
|
||||
/* SM2 trigger ? */
|
||||
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
|
||||
{
|
||||
ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2;
|
||||
RXPDO_update();
|
||||
watchdog = WATCHDOG_RESET_VALUE;
|
||||
|
||||
/* Set outputs */
|
||||
cb_set_LEDs();
|
||||
}
|
||||
if (watchdog <= 0)
|
||||
{
|
||||
DPRINT("DIG_process watchdog expired\n");
|
||||
ESC_stopoutput();
|
||||
/* watchdog, invalid outputs */
|
||||
ESC_ALerror (ALERR_WATCHDOG);
|
||||
/* goto safe-op with error bit set */
|
||||
ESC_ALstatus (ESCsafeop | ESCerror);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
watchdog = WATCHDOG_RESET_VALUE;
|
||||
}
|
||||
if (ESCvar.App.state)
|
||||
{
|
||||
/* Update inputs */
|
||||
cb_get_Buttons();
|
||||
TXPDO_update();
|
||||
}
|
||||
}
|
||||
|
||||
/********** TODO: Generic code beyond this point ***************/
|
||||
|
||||
/** Optional: Hook called after state change for application specific
|
||||
* actions for specific state changes.
|
||||
*/
|
||||
void post_state_change_hook (uint8_t * as, uint8_t * an)
|
||||
{
|
||||
#if 0
|
||||
/* Add specific step change hooks here */
|
||||
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
|
||||
{
|
||||
boot_inithook();
|
||||
}
|
||||
else if((*as == INIT_TO_BOOT) && (*an & ESCerror ) == 0)
|
||||
{
|
||||
init_boothook();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Set callback run once every loop in the SOES application loop.
|
||||
*/
|
||||
void set_application_loop_hook(void (*callback)(void))
|
||||
{
|
||||
application_loop_callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* SOES main function. It should be called periodically.
|
||||
* Reads the EtherCAT state and status. Responsible for I/O updates.
|
||||
*/
|
||||
void soes (void)
|
||||
{
|
||||
/* On init restore PDO mappings to default size */
|
||||
if((ESCvar.ALstatus & 0x0f) == ESCinit)
|
||||
{
|
||||
txpdomap = DEFAULTTXPDOMAP;
|
||||
rxpdomap = DEFAULTRXPDOMAP;
|
||||
txpdoitems = DEFAULTTXPDOITEMS;
|
||||
rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
}
|
||||
|
||||
/* 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();
|
||||
ESC_foeprocess();
|
||||
ESC_xoeprocess();
|
||||
}
|
||||
DIG_process();
|
||||
|
||||
if (application_loop_callback != NULL)
|
||||
{
|
||||
(application_loop_callback)();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the SOES stack.
|
||||
*/
|
||||
void soes_init (void)
|
||||
{
|
||||
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
|
||||
|
||||
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
|
||||
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
|
||||
|
||||
/* Setup config hooks */
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = "/dev/lan9252",
|
||||
.use_interrupt = 0,
|
||||
.watchdog_cnt = 0,
|
||||
.mbxsize = MBXSIZE,
|
||||
.mbxsizeboot = MBXSIZEBOOT,
|
||||
.mbxbuffers = MBXBUFFERS,
|
||||
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
|
||||
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
|
||||
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
|
||||
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
|
||||
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
|
||||
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
|
||||
.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 = NULL,
|
||||
.esc_hw_interrupt_disable = NULL,
|
||||
.esc_hw_eep_handler = NULL
|
||||
};
|
||||
|
||||
ESC_config (&config);
|
||||
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);
|
||||
}
|
||||
|
||||
/* Init FoE */
|
||||
FOE_init();
|
||||
|
||||
/* reset ESC to init state */
|
||||
ESC_ALstatus (ESCinit);
|
||||
ESC_ALerror (ALERR_NONE);
|
||||
ESC_stopmbx();
|
||||
ESC_stopinput();
|
||||
ESC_stopoutput();
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Slave id="evb9252_dig" productCode="1234">
|
||||
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="evb9252_dig" productCode="1234" additionalInfo="0x0190">
|
||||
<Name>lan9252</Name>
|
||||
<Vendor>
|
||||
<Id>0x1337</Id>
|
||||
|
@ -24,275 +24,332 @@
|
|||
<BootStrap>0010800080108000</BootStrap>
|
||||
</Eeprom>
|
||||
<Dictionary>
|
||||
<Item>
|
||||
<Name>Device Type</Name>
|
||||
<Item Managed="true">
|
||||
<Index>0x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x01901389</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Device Name</Name>
|
||||
<Index>0x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>evb9252_dig</DefaultValue>
|
||||
<Length>11</Length>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name>Hardware Version</Name>
|
||||
<Item Managed="false">
|
||||
<Index>0x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name>Software Version</Name>
|
||||
<Item Managed="false">
|
||||
<Index>0x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Identity Object</Name>
|
||||
<Index>0x1018</Index>
|
||||
<Name>Identity Object</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Vendor ID</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x1337</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Product Code</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>1234</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Revision Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Serial Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00000000</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>LEDs</Name>
|
||||
<Index>0x1600</Index>
|
||||
<Name>LEDs</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>LED0</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000108</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>LED1</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000208</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Buttons</Name>
|
||||
<Index>0x1A00</Index>
|
||||
<Name>Buttons</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Button1</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x60000108</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Sync Manager Communication Type</Name>
|
||||
<Index>0x1C00</Index>
|
||||
<Name>Sync Manager Communication Type</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Communications Type SM0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Communications Type SM1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Communications Type SM2</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>3</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Communications Type SM3</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<Index>0x1C12</Index>
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1600</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Sync Manager 3 PDO Assignment</Name>
|
||||
<Index>0x1C13</Index>
|
||||
<Name>Sync Manager 3 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1A00</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Buttons</Name>
|
||||
<Index>0x6000</Index>
|
||||
<Name>Buttons</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>Buttons</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>Button1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RO</Access>
|
||||
<Variable>Button1</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>LEDs</Name>
|
||||
<Index>0x7000</Index>
|
||||
<Name>LEDs</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>LEDs</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RO</Access>
|
||||
<Variable>LED0</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RO</Access>
|
||||
<Variable>LED1</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Parameters</Name>
|
||||
<Index>0x8000</Index>
|
||||
<Name>Parameters</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>Parameters</Variable>
|
||||
<VariableType>Parameter</VariableType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RW</Access>
|
||||
<Name>Multiplier</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RW</Access>
|
||||
<Variable>Multiplier</Variable>
|
||||
<VariableType>Parameter</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
</Dictionary>
|
||||
<SmAssignment>
|
||||
<Index>0x1C12</Index>
|
||||
<Entry>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1600</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<SmAssignment>
|
||||
<Index>0x1C13</Index>
|
||||
<Entry>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1A00</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<RxPdo>
|
||||
<Index>0x1600</Index>
|
||||
<Container>LEDs</Container>
|
||||
<Name>LEDs</Name>
|
||||
<Entry>
|
||||
<Index>0x7000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x01</MappedSubIndex>
|
||||
<Variable>LED0</Variable>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>0x7000</Index>
|
||||
<SubIndex>2</SubIndex>
|
||||
<Index>0x2</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x02</MappedSubIndex>
|
||||
<Variable>LED1</Variable>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<TxPdo>
|
||||
<Index>0x1A00</Index>
|
||||
<Container>Buttons</Container>
|
||||
<Name>Buttons</Name>
|
||||
<Entry>
|
||||
<Index>0x6000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x6000</MappedIndex>
|
||||
<MappedSubIndex>0x01</MappedSubIndex>
|
||||
<Variable>Button1</Variable>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Input>
|
||||
<Index>0x6000</Index>
|
||||
<Name>Buttons</Name>
|
||||
<Type>RECORD</Type>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>Button1</Name>
|
||||
<Type>UNSIGNED8</Type>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Member>
|
||||
</Input>
|
||||
<Output>
|
||||
<Index>0x7000</Index>
|
||||
<Name>LEDs</Name>
|
||||
<Type>RECORD</Type>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED0</Name>
|
||||
<Type>UNSIGNED8</Type>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x02</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED1</Name>
|
||||
<Type>UNSIGNED8</Type>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Member>
|
||||
</Output>
|
||||
<Parameter>
|
||||
<Index>0x8000</Index>
|
||||
<Name>Parameters</Name>
|
||||
<Type>RECORD</Type>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Access>RW</Access>
|
||||
<Name>Multiplier</Name>
|
||||
<Type>UNSIGNED32</Type>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Member>
|
||||
</Parameter>
|
||||
</Slave>
|
||||
</Slave>
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef __SLAVE_H__
|
||||
#define __SLAVE_H__
|
||||
|
||||
#include "utypes.h"
|
||||
|
||||
/**
|
||||
* This function reads physical input values and assigns the corresponding members
|
||||
* of Rb.Buttons
|
||||
*/
|
||||
void cb_get_Buttons();
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members of
|
||||
* Wb.LEDs
|
||||
*/
|
||||
void cb_set_LEDs();
|
||||
|
||||
/**
|
||||
* This function is called after a SDO write of the object Cb.Parameters.
|
||||
*/
|
||||
void cb_post_write_Parameters(int subindex);
|
||||
|
||||
/**
|
||||
* This function sets an application loop callback function.
|
||||
*/
|
||||
void set_application_loop_hook(void (*callback)(void));
|
||||
|
||||
/**
|
||||
* Main function for SOES application
|
||||
*/
|
||||
void soes (void);
|
||||
|
||||
/**
|
||||
* Initialize the SOES stack
|
||||
*/
|
||||
void soes_init (void);
|
||||
|
||||
#endif /* __SLAVE_H__ */
|
|
@ -26,7 +26,7 @@
|
|||
<BitSize>144</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -80,7 +80,7 @@
|
|||
<BitSize>80</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -114,7 +114,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -147,7 +147,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -179,7 +179,7 @@
|
|||
<BitSize>32</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -211,7 +211,7 @@
|
|||
<BitSize>32</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -234,7 +234,7 @@
|
|||
<BitSize>24</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -258,7 +258,7 @@
|
|||
<BitSize>32</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -292,7 +292,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -311,10 +311,6 @@
|
|||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(3)</Name>
|
||||
<BitSize>24</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(11)</Name>
|
||||
<BitSize>88</BitSize>
|
||||
|
@ -327,6 +323,10 @@
|
|||
<Name>UINT</Name>
|
||||
<BitSize>16</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(0)</Name>
|
||||
<BitSize>0</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>USINT</Name>
|
||||
<BitSize>8</BitSize>
|
||||
|
@ -361,8 +361,8 @@
|
|||
<Object>
|
||||
<Index>#x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Type>STRING(0)</Type>
|
||||
<BitSize>0</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</DefaultString>
|
||||
</Info>
|
||||
|
@ -374,8 +374,8 @@
|
|||
<Object>
|
||||
<Index>#x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Type>STRING(0)</Type>
|
||||
<BitSize>0</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</DefaultString>
|
||||
</Info>
|
||||
|
@ -390,7 +390,7 @@
|
|||
<BitSize>144</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</Info>
|
||||
|
@ -431,7 +431,7 @@
|
|||
<BitSize>80</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</Info>
|
||||
|
@ -460,7 +460,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
|
@ -483,7 +483,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</Info>
|
||||
|
@ -524,7 +524,7 @@
|
|||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
|
@ -547,7 +547,7 @@
|
|||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
|
@ -570,7 +570,7 @@
|
|||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
|
@ -593,7 +593,7 @@
|
|||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</Info>
|
||||
|
@ -622,7 +622,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
|
@ -652,14 +652,14 @@
|
|||
<Name>LEDs</Name>
|
||||
<Entry>
|
||||
<Index>#x7000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<SubIndex>#x1</SubIndex>
|
||||
<BitLen>8</BitLen>
|
||||
<Name>LED0</Name>
|
||||
<DataType>USINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x7000</Index>
|
||||
<SubIndex>2</SubIndex>
|
||||
<SubIndex>#x2</SubIndex>
|
||||
<BitLen>8</BitLen>
|
||||
<Name>LED1</Name>
|
||||
<DataType>USINT</DataType>
|
||||
|
@ -670,14 +670,14 @@
|
|||
<Name>Buttons</Name>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<SubIndex>#x1</SubIndex>
|
||||
<BitLen>8</BitLen>
|
||||
<Name>Button1</Name>
|
||||
<DataType>USINT</DataType>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Mailbox DataLinkLayer="true">
|
||||
<CoE CompleteAccess="false" PdoUpload="true" SdoInfo="true"/>
|
||||
<CoE CompleteAccess="false" PdoUpload="false" SdoInfo="true"/>
|
||||
<FoE/>
|
||||
</Mailbox>
|
||||
<Eeprom>
|
||||
|
|
|
@ -1,66 +1,70 @@
|
|||
#include "soes/esc_coe.h"
|
||||
#include "esc_coe.h"
|
||||
#include "utypes.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef HW_REV
|
||||
#define HW_REV "1.0"
|
||||
#endif
|
||||
|
||||
#ifndef SW_REV
|
||||
#define SW_REV "1.0"
|
||||
#endif
|
||||
|
||||
static const char acName1000[] = "Device Type";
|
||||
static const char acName1000_0[] = "Device Type";
|
||||
static const char acName1008[] = "Device Name";
|
||||
static const char acName1008_0[] = "Device Name";
|
||||
static const char acName1009[] = "Hardware Version";
|
||||
static const char acName1009_0[] = "Hardware Version";
|
||||
static const char acName100A[] = "Software Version";
|
||||
static const char acName100A_0[] = "Software Version";
|
||||
static const char acName1018[] = "Identity Object";
|
||||
static const char acName1018_00[] = "Number of Elements";
|
||||
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[] = "LEDs";
|
||||
static const char acName1600_00[] = "Number of Elements";
|
||||
static const char acName1600_00[] = "Max SubIndex";
|
||||
static const char acName1600_01[] = "LED0";
|
||||
static const char acName1600_02[] = "LED1";
|
||||
static const char acName1A00[] = "Buttons";
|
||||
static const char acName1A00_00[] = "Number of Elements";
|
||||
static const char acName1A00_00[] = "Max SubIndex";
|
||||
static const char acName1A00_01[] = "Button1";
|
||||
static const char acName1C00[] = "Sync Manager Communication Type";
|
||||
static const char acName1C00_00[] = "Number of Elements";
|
||||
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[] = "Number of Elements";
|
||||
static const char acName1C12_00[] = "Max SubIndex";
|
||||
static const char acName1C12_01[] = "PDO Mapping";
|
||||
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
|
||||
static const char acName1C13_00[] = "Number of Elements";
|
||||
static const char acName1C13_00[] = "Max SubIndex";
|
||||
static const char acName1C13_01[] = "PDO Mapping";
|
||||
static const char acName6000[] = "Buttons";
|
||||
static const char acName6000_00[] = "Number of Elements";
|
||||
static const char acName6000_00[] = "Max SubIndex";
|
||||
static const char acName6000_01[] = "Button1";
|
||||
static const char acName7000[] = "LEDs";
|
||||
static const char acName7000_00[] = "Number of Elements";
|
||||
static const char acName7000_00[] = "Max SubIndex";
|
||||
static const char acName7000_01[] = "LED0";
|
||||
static const char acName7000_02[] = "LED1";
|
||||
static const char acName8000[] = "Parameters";
|
||||
static const char acName8000_00[] = "Number of Elements";
|
||||
static const char acName8000_00[] = "Max SubIndex";
|
||||
static const char acName8000_01[] = "Multiplier";
|
||||
|
||||
const _objd SDO1000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000_0, 0x01901389, NULL},
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x01901389, NULL},
|
||||
};
|
||||
const _objd SDO1008[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008_0, 0, "evb9252_dig"},
|
||||
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008, 0, "evb9252_dig"},
|
||||
};
|
||||
const _objd SDO1009[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009_0, 0, "1.0"},
|
||||
{0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName1009, 0, HW_REV},
|
||||
};
|
||||
const _objd SDO100A[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A_0, 0, "1.0"},
|
||||
{0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName100A, 0, SW_REV},
|
||||
};
|
||||
const _objd SDO1018[] =
|
||||
{
|
||||
|
@ -102,18 +106,18 @@ const _objd SDO1C13[] =
|
|||
const _objd SDO6000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_01, 0, &Rb.Buttons.Button1},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_01, 0, &Obj.Buttons.Button1},
|
||||
};
|
||||
const _objd SDO7000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 2, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_01, 0, &Wb.LEDs.LED0},
|
||||
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_02, 0, &Wb.LEDs.LED1},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_01, 0, &Obj.LEDs.LED0},
|
||||
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_02, 0, &Obj.LEDs.LED1},
|
||||
};
|
||||
const _objd SDO8000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Cb.Parameters.Multiplier},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Obj.Parameters.Multiplier},
|
||||
};
|
||||
|
||||
const _objectlist SDOobjects[] =
|
||||
|
|
|
@ -1,47 +1,45 @@
|
|||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
#include <cc.h>
|
||||
#include "cc.h"
|
||||
|
||||
|
||||
/* Object dictionary storage */
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
/* Inputs */
|
||||
struct
|
||||
{
|
||||
uint8_t Button1;
|
||||
} CC_PACKED Buttons;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Rbuffer;
|
||||
CC_PACKED_END
|
||||
} Buttons;
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
|
||||
/* Outputs */
|
||||
struct
|
||||
{
|
||||
uint8_t LED0;
|
||||
uint8_t LED1;
|
||||
} CC_PACKED LEDs;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Wbuffer;
|
||||
CC_PACKED_END
|
||||
} LEDs;
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
|
||||
/* Parameters */
|
||||
struct
|
||||
{
|
||||
uint32_t Multiplier;
|
||||
} CC_PACKED Parameters;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Cbuffer;
|
||||
CC_PACKED_END
|
||||
} Parameters;
|
||||
|
||||
extern _Rbuffer Rb;
|
||||
extern _Wbuffer Wb;
|
||||
extern _Cbuffer Cb;
|
||||
|
||||
/* Manufacturer specific data */
|
||||
|
||||
/* Dynamic TX PDO:s */
|
||||
|
||||
/* Dynamic RX PDO:s */
|
||||
|
||||
/* Sync Managers */
|
||||
|
||||
} _Objects;
|
||||
|
||||
extern _Objects Obj;
|
||||
|
||||
#endif /* __UTYPES_H__ */
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
add_executable (soes-demo
|
||||
main.c
|
||||
slave_objectlist.c
|
||||
)
|
||||
target_link_libraries(soes-demo LINK_PUBLIC soes bcm2835)
|
||||
install (TARGETS soes-demo DESTINATION sbin)
|
||||
install (PROGRAMS S60soes DESTINATION /etc/init.d)
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# soes Starts soes.
|
||||
#
|
||||
|
||||
start() {
|
||||
printf "Starting soes: "
|
||||
/usr/sbin/soes-demo &
|
||||
touch /var/lock/soes-demo
|
||||
echo "OK"
|
||||
}
|
||||
stop() {
|
||||
printf "Stopping soes: "
|
||||
killall soes-demo
|
||||
rm -f /var/lock/soes-demo
|
||||
echo "OK"
|
||||
}
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
restart|reload)
|
||||
restart
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit $?
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef __ECAT_OPTIONS_H__
|
||||
#define __ECAT_OPTIONS_H__
|
||||
|
||||
#define USE_FOE 1
|
||||
#define USE_EOE 0
|
||||
|
||||
#define MBXSIZE 128
|
||||
#define MBXSIZEBOOT 128
|
||||
#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 0x1100
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1180
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#define MAX_MAPPINGS_SM2 7
|
||||
#define MAX_MAPPINGS_SM3 7
|
||||
|
||||
#define MAX_RXPDO_SIZE 42
|
||||
#define MAX_TXPDO_SIZE 42
|
||||
|
||||
#endif /* __ECAT_OPTIONS_H__ */
|
|
@ -0,0 +1,108 @@
|
|||
#include <stdio.h>
|
||||
#include "ecat_slv.h"
|
||||
#include "utypes.h"
|
||||
#include <bcm2835.h>
|
||||
|
||||
/* Application variables */
|
||||
_Objects Obj;
|
||||
|
||||
#define GPIO21 RPI_BPLUS_GPIO_J8_40
|
||||
#define GPIO20 RPI_BPLUS_GPIO_J8_38
|
||||
#define GPIO16 RPI_BPLUS_GPIO_J8_36
|
||||
#define GPIO12 RPI_BPLUS_GPIO_J8_32
|
||||
#define GPIO24 RPI_BPLUS_GPIO_J8_18
|
||||
#define GPIO23 RPI_BPLUS_GPIO_J8_16
|
||||
#define GPIO26 RPI_BPLUS_GPIO_J8_37
|
||||
#define GPIO19 RPI_BPLUS_GPIO_J8_35
|
||||
#define GPIO13 RPI_BPLUS_GPIO_J8_33
|
||||
#define GPIO06 RPI_BPLUS_GPIO_J8_31
|
||||
#define GPIO05 RPI_BPLUS_GPIO_J8_29
|
||||
#define GPIO22 RPI_BPLUS_GPIO_J8_15
|
||||
|
||||
void cb_get_inputs (void)
|
||||
{
|
||||
// Assume LEDs connected to 3.3v
|
||||
bcm2835_gpio_write(GPIO21, (Obj.LEDs.LED0 ? LOW : HIGH));
|
||||
bcm2835_gpio_write(GPIO20, (Obj.LEDs.LED1 ? LOW : HIGH));
|
||||
bcm2835_gpio_write(GPIO16, (Obj.LEDs.LED2 ? LOW : HIGH));
|
||||
bcm2835_gpio_write(GPIO12, (Obj.LEDs.LED3 ? LOW : HIGH));
|
||||
bcm2835_gpio_write(GPIO24, (Obj.LEDs.LED4 ? LOW : HIGH));
|
||||
bcm2835_gpio_write(GPIO23, (Obj.LEDs.LED5 ? LOW : HIGH));
|
||||
}
|
||||
|
||||
void cb_set_outputs (void)
|
||||
{
|
||||
// Assume Buttons connected to 3.3v
|
||||
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO26);
|
||||
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO19);
|
||||
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO13);
|
||||
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO06);
|
||||
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO05);
|
||||
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO22);
|
||||
}
|
||||
|
||||
void GPIO_init (void)
|
||||
{
|
||||
bcm2835_init();
|
||||
// Assume LEDs connected to 3.3v side of header
|
||||
bcm2835_gpio_fsel(GPIO21, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_fsel(GPIO20, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_fsel(GPIO16, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_fsel(GPIO12, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_fsel(GPIO24, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_fsel(GPIO23, BCM2835_GPIO_FSEL_OUTP);
|
||||
// Assume buttons connected to 5v side of header
|
||||
// Do not bridge to 5v, the ports might burn
|
||||
bcm2835_gpio_fsel(GPIO26, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(GPIO19, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(GPIO13, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(GPIO06, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(GPIO05, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(GPIO22, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_set_pud(GPIO26, BCM2835_GPIO_PUD_DOWN);
|
||||
bcm2835_gpio_set_pud(GPIO19, BCM2835_GPIO_PUD_DOWN);
|
||||
bcm2835_gpio_set_pud(GPIO13, BCM2835_GPIO_PUD_DOWN);
|
||||
bcm2835_gpio_set_pud(GPIO06, BCM2835_GPIO_PUD_DOWN);
|
||||
bcm2835_gpio_set_pud(GPIO05, BCM2835_GPIO_PUD_DOWN);
|
||||
bcm2835_gpio_set_pud(GPIO22, BCM2835_GPIO_PUD_DOWN);
|
||||
}
|
||||
|
||||
int main_run (void * arg)
|
||||
{
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = "rpi3,cs0",
|
||||
.use_interrupt = 0,
|
||||
.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 = NULL,
|
||||
.esc_hw_interrupt_disable = NULL,
|
||||
.esc_hw_eep_handler = NULL,
|
||||
.esc_check_dc_handler = NULL,
|
||||
};
|
||||
|
||||
printf ("Hello Main\n");
|
||||
GPIO_init();
|
||||
ecat_slv_init (&config);
|
||||
while (1)
|
||||
{
|
||||
ecat_slv();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
printf ("Hello Main\n");
|
||||
main_run (NULL);
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,532 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="evb9252_dig" productCode="1234" additionalInfo="0x0190">
|
||||
<Name>lan9252</Name>
|
||||
<Vendor>
|
||||
<Id>0x1337</Id>
|
||||
<Name>rt-labs AB</Name>
|
||||
</Vendor>
|
||||
<Group>
|
||||
<Type>lan9252_spi</Type>
|
||||
<Name>lan9252</Name>
|
||||
</Group>
|
||||
<Fmmu>Outputs</Fmmu>
|
||||
<Fmmu>Inputs</Fmmu>
|
||||
<Sm ControlByte="0x26" DefaultSize="128" StartAddress="0x1000">MBoxOut</Sm>
|
||||
<Sm ControlByte="0x22" DefaultSize="128" StartAddress="0x1080">MBoxIn</Sm>
|
||||
<Sm ControlByte="0x24" DefaultSize="0" StartAddress="0x1100">Outputs</Sm>
|
||||
<Sm ControlByte="0x20" DefaultSize="0" StartAddress="0x1180">Inputs</Sm>
|
||||
<Mailbox CoE="true" FoE="true">
|
||||
<Bootstrap Length="128" Start="0x1000"/>
|
||||
<Standard Length="128" Start="0x1000"/>
|
||||
</Mailbox>
|
||||
<Eeprom Lan9252="true">
|
||||
<ConfigData>8002000000000000</ConfigData>
|
||||
<BootStrap>0010800080108000</BootStrap>
|
||||
</Eeprom>
|
||||
<Dictionary>
|
||||
<Item Managed="true">
|
||||
<Index>0x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x01901389</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>evb9252_dig</DefaultValue>
|
||||
<Length>11</Length>
|
||||
</Item>
|
||||
<Item Managed="false">
|
||||
<Index>0x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="false">
|
||||
<Index>0x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1018</Index>
|
||||
<Name>Identity Object</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Vendor ID</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x1337</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Product Code</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>1234</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Revision Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Serial Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00000000</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1600</Index>
|
||||
<Name>LEDs</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>9</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>LED0</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000108</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>LED1</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000208</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>New Member</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000301</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>New Member</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000401</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x05</Index>
|
||||
<Name>New Member</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000501</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x06</Index>
|
||||
<Name>New Member</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000601</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x07</Index>
|
||||
<Name>New Member</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000701</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x08</Index>
|
||||
<Name>New Member</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000801</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x09</Index>
|
||||
<Name>Padding 9</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00000002</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1A00</Index>
|
||||
<Name>Buttons</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Button1</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x60000108</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1C00</Index>
|
||||
<Name>Sync Manager Communication Type</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Communications Type SM0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Communications Type SM1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Communications Type SM2</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>3</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Communications Type SM3</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1C12</Index>
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1600</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1C13</Index>
|
||||
<Name>Sync Manager 3 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1A00</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x6000</Index>
|
||||
<Name>Buttons</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>Buttons</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>Button1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Variable>Button1</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x7000</Index>
|
||||
<Name>LEDs</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>LEDs</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>8</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Variable>LED0</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Variable>LED1</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>New Member</Name>
|
||||
<DataType>BOOLEAN</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>New_Member</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>New Member</Name>
|
||||
<DataType>BOOLEAN</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>New_Member</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x05</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>New Member</Name>
|
||||
<DataType>BOOLEAN</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>New_Member</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x06</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>New Member</Name>
|
||||
<DataType>BOOLEAN</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>New_Member</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x07</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>New Member</Name>
|
||||
<DataType>BOOLEAN</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>New_Member</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x08</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>New Member</Name>
|
||||
<DataType>BOOLEAN</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>New_Member</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x8000</Index>
|
||||
<Name>Parameters</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>Parameters</Variable>
|
||||
<VariableType>Parameter</VariableType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RW</Access>
|
||||
<Name>Multiplier</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Variable>Multiplier</Variable>
|
||||
<VariableType>Parameter</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
</Dictionary>
|
||||
<SmAssignment>
|
||||
<Index>0x1C12</Index>
|
||||
<Entry>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1600</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<SmAssignment>
|
||||
<Index>0x1C13</Index>
|
||||
<Entry>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1A00</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<RxPdo>
|
||||
<Index>0x1600</Index>
|
||||
<Name>LEDs</Name>
|
||||
<Entry>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x01</MappedSubIndex>
|
||||
<Variable>LED0</Variable>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>0x2</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x02</MappedSubIndex>
|
||||
<Variable>LED1</Variable>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>0x3</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x03</MappedSubIndex>
|
||||
<Variable>LED2</Variable>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>0x4</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x04</MappedSubIndex>
|
||||
<Variable>LED3</Variable>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>0x5</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x05</MappedSubIndex>
|
||||
<Variable>LED4</Variable>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>0x6</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x06</MappedSubIndex>
|
||||
<Variable>LED5</Variable>
|
||||
</Entry>
|
||||
<Entry padBits="2">
|
||||
<Index>0x09</Index>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<TxPdo>
|
||||
<Index>0x1A00</Index>
|
||||
<Name>Buttons</Name>
|
||||
<Entry>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x6000</MappedIndex>
|
||||
<MappedSubIndex>0x01</MappedSubIndex>
|
||||
<Variable>Button0</Variable>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Input>
|
||||
<Index>0x6000</Index>
|
||||
<Name>Buttons</Name>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>Button0</Name>
|
||||
<Type>BOOLEAN</Type>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x02</Index>
|
||||
<Name>Button1</Name>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x03</Index>
|
||||
<Name>Button2</Name>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x04</Index>
|
||||
<Name>Button3</Name>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x05</Index>
|
||||
<Name>Button4</Name>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x06</Index>
|
||||
<Name>Button5</Name>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
</Member>
|
||||
</Input>
|
||||
<Output>
|
||||
<Index>0x7000</Index>
|
||||
<Name>LEDs</Name>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED0</Name>
|
||||
<Type>BOOLEAN</Type>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x02</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED1</Name>
|
||||
<Type>BOOLEAN</Type>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x03</Index>
|
||||
<Name>LED2</Name>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x04</Index>
|
||||
<Name>LED3</Name>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x05</Index>
|
||||
<Name>LED4</Name>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
</Member>
|
||||
<Member>
|
||||
<Index>0x06</Index>
|
||||
<Name>LED5</Name>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
</Member>
|
||||
</Output>
|
||||
<Parameter>
|
||||
<Index>0x8000</Index>
|
||||
<Name>Parameters</Name>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Access>RW</Access>
|
||||
<Name>Multiplier</Name>
|
||||
<Type>UNSIGNED32</Type>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Member>
|
||||
</Parameter>
|
||||
</Slave>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,179 @@
|
|||
#include "esc_coe.h"
|
||||
#include "utypes.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef HW_REV
|
||||
#define HW_REV "1.0"
|
||||
#endif
|
||||
|
||||
#ifndef SW_REV
|
||||
#define SW_REV "1.0"
|
||||
#endif
|
||||
|
||||
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[] = "LEDs";
|
||||
static const char acName1600_00[] = "Max SubIndex";
|
||||
static const char acName1600_01[] = "LED0";
|
||||
static const char acName1600_02[] = "LED1";
|
||||
static const char acName1600_03[] = "LED2";
|
||||
static const char acName1600_04[] = "LED3";
|
||||
static const char acName1600_05[] = "LED4";
|
||||
static const char acName1600_06[] = "LED5";
|
||||
static const char acName1600_07[] = "Padding 7";
|
||||
static const char acName1A00[] = "Buttons";
|
||||
static const char acName1A00_00[] = "Max SubIndex";
|
||||
static const char acName1A00_01[] = "Button0";
|
||||
static const char acName1A00_02[] = "Button1";
|
||||
static const char acName1A00_03[] = "Button2";
|
||||
static const char acName1A00_04[] = "Button3";
|
||||
static const char acName1A00_05[] = "Button4";
|
||||
static const char acName1A00_06[] = "Button5";
|
||||
static const char acName1A00_07[] = "Padding 7";
|
||||
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 acName1C13[] = "Sync Manager 3 PDO Assignment";
|
||||
static const char acName1C13_00[] = "Max SubIndex";
|
||||
static const char acName1C13_01[] = "PDO Mapping";
|
||||
static const char acName6000[] = "Buttons";
|
||||
static const char acName6000_00[] = "Max SubIndex";
|
||||
static const char acName6000_01[] = "Button0";
|
||||
static const char acName6000_02[] = "Button1";
|
||||
static const char acName6000_03[] = "Button2";
|
||||
static const char acName6000_04[] = "Button3";
|
||||
static const char acName6000_05[] = "Button4";
|
||||
static const char acName6000_06[] = "Button5";
|
||||
static const char acName7000[] = "LEDs";
|
||||
static const char acName7000_00[] = "Max SubIndex";
|
||||
static const char acName7000_01[] = "LED0";
|
||||
static const char acName7000_02[] = "LED1";
|
||||
static const char acName7000_03[] = "LED2";
|
||||
static const char acName7000_04[] = "LED3";
|
||||
static const char acName7000_05[] = "LED4";
|
||||
static const char acName7000_06[] = "LED5";
|
||||
static const char acName8000[] = "Parameters";
|
||||
static const char acName8000_00[] = "Max SubIndex";
|
||||
static const char acName8000_01[] = "Multiplier";
|
||||
|
||||
const _objd SDO1000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x01901389, NULL},
|
||||
};
|
||||
const _objd SDO1008[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008, 0, "evb9252_dig"},
|
||||
};
|
||||
const _objd SDO1009[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName1009, 0, HW_REV},
|
||||
};
|
||||
const _objd SDO100A[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName100A, 0, SW_REV},
|
||||
};
|
||||
const _objd SDO1018[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 1234, NULL},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, &Obj.serial},
|
||||
};
|
||||
const _objd SDO1600[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 7, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000101, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_02, 0x70000201, NULL},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_03, 0x70000301, NULL},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_04, 0x70000401, NULL},
|
||||
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_05, 0x70000501, NULL},
|
||||
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_06, 0x70000601, NULL},
|
||||
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_07, 0x00000002, NULL},
|
||||
};
|
||||
const _objd SDO1A00[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 7, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60000101, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_02, 0x60000201, NULL},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_03, 0x60000301, NULL},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_04, 0x60000401, NULL},
|
||||
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_05, 0x60000501, NULL},
|
||||
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_06, 0x60000601, NULL},
|
||||
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_07, 0x00000002, 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, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
|
||||
};
|
||||
const _objd SDO1C13[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL},
|
||||
};
|
||||
const _objd SDO6000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_00, 6, NULL},
|
||||
{0x01, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_01, 0, &Obj.Buttons.Button0},
|
||||
{0x02, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_02, 0, &Obj.Buttons.Button1},
|
||||
{0x03, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_03, 0, &Obj.Buttons.Button2},
|
||||
{0x04, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_04, 0, &Obj.Buttons.Button3},
|
||||
{0x05, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_05, 0, &Obj.Buttons.Button4},
|
||||
{0x06, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_06, 0, &Obj.Buttons.Button5},
|
||||
};
|
||||
const _objd SDO7000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 6, NULL},
|
||||
{0x01, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_01, 0, &Obj.LEDs.LED0},
|
||||
{0x02, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_02, 0, &Obj.LEDs.LED1},
|
||||
{0x03, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_03, 0, &Obj.LEDs.LED2},
|
||||
{0x04, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_04, 0, &Obj.LEDs.LED3},
|
||||
{0x05, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_05, 0, &Obj.LEDs.LED4},
|
||||
{0x06, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_06, 0, &Obj.LEDs.LED5},
|
||||
};
|
||||
const _objd SDO8000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Obj.Parameters.Multiplier},
|
||||
};
|
||||
|
||||
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, 7, 0, acName1600, SDO1600},
|
||||
{0x1A00, OTYPE_RECORD, 7, 0, acName1A00, SDO1A00},
|
||||
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
|
||||
{0x1C12, OTYPE_ARRAY, 1, 0, acName1C12, SDO1C12},
|
||||
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
|
||||
{0x6000, OTYPE_RECORD, 6, 0, acName6000, SDO6000},
|
||||
{0x7000, OTYPE_RECORD, 6, 0, acName7000, SDO7000},
|
||||
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
|
||||
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
#include "cc.h"
|
||||
|
||||
/* Object dictionary storage */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Identity */
|
||||
|
||||
uint32_t serial;
|
||||
|
||||
/* Inputs */
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t Button0;
|
||||
uint8_t Button1;
|
||||
uint8_t Button2;
|
||||
uint8_t Button3;
|
||||
uint8_t Button4;
|
||||
uint8_t Button5;
|
||||
} Buttons;
|
||||
|
||||
/* Outputs */
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t LED0;
|
||||
uint8_t LED1;
|
||||
uint8_t LED2;
|
||||
uint8_t LED3;
|
||||
uint8_t LED4;
|
||||
uint8_t LED5;
|
||||
} LEDs;
|
||||
|
||||
/* Parameters */
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t Multiplier;
|
||||
} Parameters;
|
||||
|
||||
} _Objects;
|
||||
|
||||
extern _Objects Obj;
|
||||
|
||||
#endif /* __UTYPES_H__ */
|
|
@ -1,49 +0,0 @@
|
|||
#include <kern.h>
|
||||
#include "slave.h"
|
||||
|
||||
/**
|
||||
* This function reads physical input values and assigns the corresponding members
|
||||
* of Rb.Buttons
|
||||
*/
|
||||
void cb_get_Buttons()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members of
|
||||
* Wb.LEDs
|
||||
*/
|
||||
|
||||
|
||||
void cb_set_LEDs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is called after a SDO write of the object Cb.Parameters.
|
||||
*/
|
||||
void cb_post_write_Parameters(int subindex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void main_run(void * arg)
|
||||
{
|
||||
soes_init();
|
||||
|
||||
while(1) {
|
||||
soes();
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
rprintf("Hello Main\n");
|
||||
task_spawn ("soes", main_run, 8, 2048, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,298 +0,0 @@
|
|||
#include <stddef.h>
|
||||
#include "utypes.h"
|
||||
#include "esc.h"
|
||||
#include "esc_coe.h"
|
||||
#include "esc_foe.h"
|
||||
#include "config.h"
|
||||
#include "slave.h"
|
||||
|
||||
#define WATCHDOG_RESET_VALUE 150
|
||||
#define DEFAULTTXPDOMAP 0x1a00
|
||||
#define DEFAULTRXPDOMAP 0x1600
|
||||
#define DEFAULTTXPDOITEMS 1
|
||||
#define DEFAULTRXPDOITEMS 1
|
||||
|
||||
/* Global variables used by the stack */
|
||||
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
|
||||
_MBXcontrol MBXcontrol[MBXBUFFERS];
|
||||
_ESCvar ESCvar;
|
||||
|
||||
/* Application variables */
|
||||
_Rbuffer Rb;
|
||||
_Wbuffer Wb;
|
||||
_Cbuffer Cb;
|
||||
|
||||
/* Private variables */
|
||||
uint16_t txpdomap = DEFAULTTXPDOMAP;
|
||||
uint16_t rxpdomap = DEFAULTRXPDOMAP;
|
||||
uint8_t txpdoitems = DEFAULTTXPDOITEMS;
|
||||
uint8_t rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
|
||||
static int watchdog = WATCHDOG_RESET_VALUE;
|
||||
static void (*application_loop_callback)(void) = NULL;
|
||||
|
||||
/** 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 1 if the SDO Download is correct. 0 If not correct.
|
||||
*/
|
||||
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
if ((index == 0x1c12) && (subindex > 0) && (rxpdoitems != 0))
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
if ((index == 0x1c13) && (subindex > 0) && (txpdoitems != 0))
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Mandatory: 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
|
||||
*/
|
||||
void ESC_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0x1c12:
|
||||
{
|
||||
if (rxpdoitems > 1)
|
||||
{
|
||||
rxpdoitems = 1;
|
||||
}
|
||||
if ((rxpdomap != 0x1600) && (rxpdomap != 0x1601)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
rxpdomap = 0x1600;
|
||||
}
|
||||
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
|
||||
break;
|
||||
}
|
||||
case 0x1c13:
|
||||
{
|
||||
if (txpdoitems > 1)
|
||||
{
|
||||
txpdoitems = 1;
|
||||
}
|
||||
if ((txpdomap != 0x1A00) && (txpdomap != 0x1A01)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
txpdomap = 0x1A00;
|
||||
}
|
||||
ESCvar.TXPDOsize = ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
|
||||
break;
|
||||
}
|
||||
/* Handle post-write of parameter values */
|
||||
case 0x8000:
|
||||
{
|
||||
cb_post_write_Parameters(subindex);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Mandatory: 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.
|
||||
* set
|
||||
*/
|
||||
void APP_safeoutput (void)
|
||||
{
|
||||
DPRINT ("APP_safeoutput\n");
|
||||
|
||||
// Set safe values for Wb.LEDs
|
||||
Wb.LEDs.LED0 = 0;
|
||||
Wb.LEDs.LED1 = 0;
|
||||
|
||||
}
|
||||
|
||||
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
|
||||
*/
|
||||
void TXPDO_update (void)
|
||||
{
|
||||
ESC_write (SM3_sma, &Rb, ESCvar.TXPDOsize);
|
||||
}
|
||||
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
|
||||
*/
|
||||
void RXPDO_update (void)
|
||||
{
|
||||
ESC_read (SM2_sma, &Wb, ESCvar.RXPDOsize);
|
||||
}
|
||||
|
||||
/** Mandatory: 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 (void)
|
||||
{
|
||||
if (watchdog > 0)
|
||||
{
|
||||
watchdog--;
|
||||
}
|
||||
if (ESCvar.App.state & APPSTATE_OUTPUT)
|
||||
{
|
||||
/* SM2 trigger ? */
|
||||
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
|
||||
{
|
||||
ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2;
|
||||
RXPDO_update();
|
||||
watchdog = WATCHDOG_RESET_VALUE;
|
||||
|
||||
/* Set outputs */
|
||||
cb_set_LEDs();
|
||||
}
|
||||
if (watchdog <= 0)
|
||||
{
|
||||
DPRINT("DIG_process watchdog expired\n");
|
||||
ESC_stopoutput();
|
||||
/* watchdog, invalid outputs */
|
||||
ESC_ALerror (ALERR_WATCHDOG);
|
||||
/* goto safe-op with error bit set */
|
||||
ESC_ALstatus (ESCsafeop | ESCerror);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
watchdog = WATCHDOG_RESET_VALUE;
|
||||
}
|
||||
if (ESCvar.App.state)
|
||||
{
|
||||
/* Update inputs */
|
||||
cb_get_Buttons();
|
||||
TXPDO_update();
|
||||
}
|
||||
}
|
||||
|
||||
/********** TODO: Generic code beyond this point ***************/
|
||||
|
||||
/** Optional: Hook called after state change for application specific
|
||||
* actions for specific state changes.
|
||||
*/
|
||||
void post_state_change_hook (uint8_t * as, uint8_t * an)
|
||||
{
|
||||
#if 0
|
||||
/* Add specific step change hooks here */
|
||||
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
|
||||
{
|
||||
boot_inithook();
|
||||
}
|
||||
else if((*as == INIT_TO_BOOT) && (*an & ESCerror ) == 0)
|
||||
{
|
||||
init_boothook();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Set callback run once every loop in the SOES application loop.
|
||||
*/
|
||||
void set_application_loop_hook(void (*callback)(void))
|
||||
{
|
||||
application_loop_callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* SOES main function. It should be called periodically.
|
||||
* Reads the EtherCAT state and status. Responsible for I/O updates.
|
||||
*/
|
||||
void soes (void)
|
||||
{
|
||||
/* On init restore PDO mappings to default size */
|
||||
if((ESCvar.ALstatus & 0x0f) == ESCinit)
|
||||
{
|
||||
txpdomap = DEFAULTTXPDOMAP;
|
||||
rxpdomap = DEFAULTRXPDOMAP;
|
||||
txpdoitems = DEFAULTTXPDOITEMS;
|
||||
rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
}
|
||||
|
||||
/* 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 mailboxes */
|
||||
if (ESC_mbxprocess())
|
||||
{
|
||||
ESC_coeprocess();
|
||||
ESC_foeprocess();
|
||||
ESC_xoeprocess();
|
||||
}
|
||||
DIG_process();
|
||||
|
||||
if (application_loop_callback != NULL)
|
||||
{
|
||||
(application_loop_callback)();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the SOES stack.
|
||||
*/
|
||||
void soes_init (void)
|
||||
{
|
||||
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
|
||||
|
||||
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
|
||||
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
|
||||
|
||||
/* Setup config hooks */
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = "/spi1/lan9252",
|
||||
.use_interrupt = 0,
|
||||
.watchdog_cnt = 0,
|
||||
.mbxsize = MBXSIZE,
|
||||
.mbxsizeboot = MBXSIZEBOOT,
|
||||
.mbxbuffers = MBXBUFFERS,
|
||||
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
|
||||
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
|
||||
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
|
||||
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
|
||||
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
|
||||
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
|
||||
.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 = NULL,
|
||||
.esc_hw_interrupt_disable = NULL,
|
||||
.esc_hw_eep_handler = NULL
|
||||
};
|
||||
|
||||
ESC_config (&config);
|
||||
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);
|
||||
}
|
||||
|
||||
/* Init FoE */
|
||||
FOE_init();
|
||||
|
||||
/* reset ESC to init state */
|
||||
ESC_ALstatus (ESCinit);
|
||||
ESC_ALerror (ALERR_NONE);
|
||||
ESC_stopmbx();
|
||||
ESC_stopinput();
|
||||
ESC_stopoutput();
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef __SLAVE_H__
|
||||
#define __SLAVE_H__
|
||||
|
||||
#include "utypes.h"
|
||||
|
||||
/**
|
||||
* This function reads physical input values and assigns the corresponding members
|
||||
* of Rb.Buttons
|
||||
*/
|
||||
void cb_get_Buttons();
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members of
|
||||
* Wb.LEDs
|
||||
*/
|
||||
void cb_set_LEDs();
|
||||
|
||||
/**
|
||||
* This function is called after a SDO write of the object Cb.Parameters.
|
||||
*/
|
||||
void cb_post_write_Parameters(int subindex);
|
||||
|
||||
/**
|
||||
* This function sets an application loop callback function.
|
||||
*/
|
||||
void set_application_loop_hook(void (*callback)(void));
|
||||
|
||||
/**
|
||||
* Main function for SOES application
|
||||
*/
|
||||
void soes (void);
|
||||
|
||||
/**
|
||||
* Initialize the SOES stack
|
||||
*/
|
||||
void soes_init (void);
|
||||
|
||||
#endif /* __SLAVE_H__ */
|
|
@ -1,47 +0,0 @@
|
|||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
#include <cc.h>
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint8_t Button1;
|
||||
} CC_PACKED Buttons;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Rbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint8_t LED0;
|
||||
uint8_t LED1;
|
||||
} CC_PACKED LEDs;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Wbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint32_t Multiplier;
|
||||
} CC_PACKED Parameters;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Cbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
extern _Rbuffer Rb;
|
||||
extern _Wbuffer Wb;
|
||||
extern _Cbuffer Cb;
|
||||
|
||||
#endif /* __UTYPES_H__ */
|
|
@ -1,7 +1,13 @@
|
|||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
#ifndef __ECAT_OPTIONS_H__
|
||||
#define __ECAT_OPTIONS_H__
|
||||
|
||||
#include <cc.h>
|
||||
#include "cc.h"
|
||||
|
||||
#define USE_FOE 0
|
||||
#define USE_EOE 1
|
||||
|
||||
#define MAX_INPUT_SIZE 128
|
||||
#define MAX_OUTPUT_SIZE 128
|
||||
|
||||
#define MBXSIZE 128
|
||||
#define MBXSIZEBOOT 128
|
||||
|
@ -26,10 +32,13 @@
|
|||
#define MBX1_smc_b 0x22
|
||||
|
||||
#define SM2_sma 0x1100
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_smc 0x64
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1180
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#endif /* __CONFIG_H__ */
|
||||
#define MAX_MAPPINGS_SM2 2
|
||||
#define MAX_MAPPINGS_SM3 1
|
||||
|
||||
#endif /* __ECAT_OPTIONS_H__ */
|
|
@ -0,0 +1,361 @@
|
|||
|
||||
#include <kern.h>
|
||||
#include <xmc4.h>
|
||||
#include <bsp.h>
|
||||
#include "esc.h"
|
||||
#include "esc_eoe.h"
|
||||
#include "esc_hw.h"
|
||||
#include "ecat_slv.h"
|
||||
#include "options.h"
|
||||
#include "utypes.h"
|
||||
#include <lwip/sys.h>
|
||||
#include <lwip/netifapi.h>
|
||||
#include <netif/etharp.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CFG_HOSTNAME "xmc48relax"
|
||||
|
||||
static struct netif * found_if;
|
||||
static mbox_t * pbuf_mbox;
|
||||
static uint8_t mac_address[6] = {0x1E, 0x30, 0x6C, 0xA2, 0x45, 0x5E};
|
||||
|
||||
static void appl_get_buffer (eoe_pbuf_t * ebuf);
|
||||
static void appl_free_buffer (eoe_pbuf_t * ebuf);
|
||||
static int appl_load_eth_settings (void);
|
||||
static int appl_store_ethernet_settings (void);
|
||||
static void appl_handle_recv_buffer (uint8_t port, eoe_pbuf_t * ebuf);
|
||||
static int appl_fetch_send_buffer (uint8_t port, eoe_pbuf_t * ebuf);
|
||||
|
||||
/* Application variables */
|
||||
_Objects Obj;
|
||||
|
||||
extern sem_t * ecat_isr_sem;
|
||||
|
||||
struct netif * net_add_interface (err_t (*netif_fn) (struct netif * netif))
|
||||
{
|
||||
struct netif * netif;
|
||||
ip_addr_t ipaddr;
|
||||
ip_addr_t netmask;
|
||||
ip_addr_t gateway;
|
||||
err_enum_t error;
|
||||
|
||||
netif = malloc (sizeof(struct netif));
|
||||
UASSERT (netif != NULL, EMEM);
|
||||
|
||||
/* Set default (zero) values */
|
||||
ip_addr_set_zero (&ipaddr);
|
||||
ip_addr_set_zero (&netmask);
|
||||
ip_addr_set_zero (&gateway);
|
||||
|
||||
/* Let lwIP TCP/IP thread initialise and add the interface. The interface
|
||||
* will be down until net_configure() is called.
|
||||
*/
|
||||
error = netifapi_netif_add (
|
||||
netif, &ipaddr, &netmask, &gateway, NULL, netif_fn, tcpip_input);
|
||||
UASSERT (error == ERR_OK, EARG);
|
||||
|
||||
return netif;
|
||||
}
|
||||
|
||||
void cb_get_inputs (void)
|
||||
{
|
||||
static int count;
|
||||
Obj.Buttons.Button1 = gpio_get(GPIO_BUTTON1);
|
||||
if(Obj.Buttons.Button1 == 0)
|
||||
{
|
||||
count++;
|
||||
if(count > 1000)
|
||||
{
|
||||
ESC_ALstatusgotoerror((ESCsafeop | ESCerror), ALERR_WATCHDOG);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cb_set_outputs (void)
|
||||
{
|
||||
gpio_set(GPIO_LED1, Obj.LEDgroup0.LED0);
|
||||
gpio_set(GPIO_LED2, Obj.LEDgroup1.LED1);
|
||||
}
|
||||
|
||||
void cb_state_change (uint8_t * as, uint8_t * an)
|
||||
{
|
||||
if (*as == SAFEOP_TO_OP)
|
||||
{
|
||||
/* Enable watchdog interrupt */
|
||||
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | ESCREG_ALEVENT_WD);
|
||||
}
|
||||
|
||||
/* Clean up data if we have been in INIT state */
|
||||
if ((*as == INIT_TO_PREOP) && (*an == ESCinit))
|
||||
{
|
||||
struct pbuf *p;
|
||||
int i = 0;
|
||||
while(mbox_fetch_tmo(pbuf_mbox, (void **)&p, 0) == 0)
|
||||
{
|
||||
pbuf_free(p);
|
||||
i++;
|
||||
}
|
||||
if(i)
|
||||
{
|
||||
rprintf("Cleaned eoe pbuf: %d\n",i);
|
||||
}
|
||||
EOE_init();
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback to allocate a buffer */
|
||||
static void appl_get_buffer (eoe_pbuf_t * ebuf)
|
||||
{
|
||||
struct pbuf * p = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL);
|
||||
|
||||
if(p != NULL)
|
||||
{
|
||||
ebuf->payload = p->payload;
|
||||
ebuf->pbuf = p;
|
||||
ebuf->len = p->len;
|
||||
}
|
||||
else
|
||||
{
|
||||
ebuf->payload = NULL;
|
||||
ebuf->pbuf = NULL;
|
||||
ebuf->len = p->len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback to free a buffer */
|
||||
static void appl_free_buffer (eoe_pbuf_t * ebuf)
|
||||
{
|
||||
if(ebuf->pbuf != NULL)
|
||||
{
|
||||
pbuf_free(ebuf->pbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback to act on a received get IP request.
|
||||
* From here we can retrieve locla IP and DNS information
|
||||
*
|
||||
*/
|
||||
static int appl_load_eth_settings (void)
|
||||
{
|
||||
/*
|
||||
* ip_addr_t ip;
|
||||
* IP4_ADDR (&ip, 192, 168, 9, 200)
|
||||
* ip.addr = ntohl(ip.addr);
|
||||
* EOE_ecat_set_ip();
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Callback to act on a received set IP request.
|
||||
* Avalaible IP and DNS data depends on what the master provide.
|
||||
* We only fetch what is needed to init lwIP
|
||||
*/
|
||||
static int appl_store_ethernet_settings (void)
|
||||
{
|
||||
int ret = 0;
|
||||
ip_addr_t ip;
|
||||
ip_addr_t netmask;
|
||||
ip_addr_t gateway;
|
||||
|
||||
/* Fetch received IP information, IP returned in host uint32_t format */
|
||||
if(EOE_ecat_get_ip (0, &ip.addr) == -1)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else if(EOE_ecat_get_subnet (0, &netmask.addr) == -1)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else if(EOE_ecat_get_gateway (0, &gateway.addr) == -1)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip.addr = htonl(ip.addr);
|
||||
netmask.addr = htonl(netmask.addr);
|
||||
gateway.addr = htonl(gateway.addr);
|
||||
/* Configure TCP/IP network stack. DNS server and host name are not set. */
|
||||
net_configure (found_if, &ip, &netmask, &gateway, NULL, CFG_HOSTNAME);
|
||||
net_link_up (found_if);
|
||||
if (netif_is_up (found_if))
|
||||
{
|
||||
rprintf ("netif up (%d.%d.%d.%d)\n",
|
||||
ip4_addr1 (&found_if->ip_addr),
|
||||
ip4_addr2 (&found_if->ip_addr),
|
||||
ip4_addr3 (&found_if->ip_addr),
|
||||
ip4_addr4 (&found_if->ip_addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
rprintf ("netif down\n");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Callback from the stack to handled a completed Ethernet frame. */
|
||||
static void appl_handle_recv_buffer (uint8_t port, eoe_pbuf_t * ebuf)
|
||||
{
|
||||
struct pbuf * p = ebuf->pbuf;
|
||||
p->len = p->tot_len = ebuf->len;
|
||||
if(ebuf->pbuf != NULL)
|
||||
{
|
||||
/* Dummy code for bounce back a L2 frame of type 0x88A4U back to
|
||||
* the EtherCAT master.
|
||||
*/
|
||||
struct eth_hdr *ethhdr;
|
||||
uint16_t type;
|
||||
ethhdr = p->payload;
|
||||
type = htons(ethhdr->type);
|
||||
if (type == 0x88A4U)
|
||||
{
|
||||
if(mbox_post_tmo(pbuf_mbox, p, 0))
|
||||
{
|
||||
pbuf_free (p);
|
||||
rprintf("transmit_frame timeout full?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sem_signal(ecat_isr_sem);
|
||||
}
|
||||
}
|
||||
/* Normal procedure to pass the Ethernet frame to lwIP to handle */
|
||||
else if (found_if->input (p, found_if) != 0)
|
||||
{
|
||||
pbuf_free (p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback from the stack to fetch a posted Ethernet frame to send to the
|
||||
* Master over EtherCAT
|
||||
*/
|
||||
static int appl_fetch_send_buffer (uint8_t port, eoe_pbuf_t * ebuf)
|
||||
{
|
||||
int ret;
|
||||
struct pbuf *p;
|
||||
|
||||
if(mbox_fetch_tmo(pbuf_mbox, (void **)&p, 0))
|
||||
{
|
||||
ebuf->pbuf = NULL;
|
||||
ebuf->payload = NULL;
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ebuf->pbuf = p;
|
||||
ebuf->payload = p->payload;
|
||||
ebuf->len = p->tot_len;
|
||||
ret = ebuf->len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Util function for lwIP to post Ethernet frames to be sent over dummy
|
||||
* EtherCAT network interface.
|
||||
*/
|
||||
static err_t transmit_frame (struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
/* Try posting the buffer to the EoE stack send Q, the caller will try to
|
||||
* free the buffer if we fail to post..
|
||||
*/
|
||||
if(mbox_post_tmo(pbuf_mbox, p, 0))
|
||||
{
|
||||
rprintf("transmit_frame timeout full?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a pbuf ref to keep the buf alive until it is sent over EoE */
|
||||
pbuf_ref(p);
|
||||
sem_signal(ecat_isr_sem);
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/* Create an dummy lwIP EtherCAT interface */
|
||||
err_t eoe_netif_init (struct netif * netif)
|
||||
{
|
||||
rprintf("EOE eoe_netif_init called\n");
|
||||
|
||||
/* Initialise netif */
|
||||
netif->name[0] = 'e';
|
||||
netif->name[1] = 'c';
|
||||
netif->output = etharp_output;
|
||||
netif->linkoutput = transmit_frame;
|
||||
netif->mtu = 1500; /* maximum transfer unit */
|
||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
|
||||
netif->hwaddr_len = ETHARP_HWADDR_LEN;
|
||||
memcpy (netif->hwaddr, mac_address, sizeof(netif->hwaddr));
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/* Callback on fragment sent event, we trigger a stack cycle to handle mailbox traffic
|
||||
* if we might have more fragements in queue.
|
||||
*/
|
||||
void eoe_frame_sent (void)
|
||||
{
|
||||
sem_signal(ecat_isr_sem);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = NULL,
|
||||
.use_interrupt = 1,
|
||||
.watchdog_cnt = INT32_MAX, /* Use HW SM watchdog instead */
|
||||
.set_defaults_hook = NULL,
|
||||
.pre_state_change_hook = NULL,
|
||||
.post_state_change_hook = cb_state_change,
|
||||
.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 = ESC_eep_handler,
|
||||
.esc_check_dc_handler = NULL
|
||||
};
|
||||
|
||||
/* Configuration parameters for EoE
|
||||
* Function callbacks to interact with an TCP/IP stack
|
||||
*/
|
||||
static eoe_cfg_t eoe_config =
|
||||
{
|
||||
.get_buffer = appl_get_buffer,
|
||||
.free_buffer = appl_free_buffer,
|
||||
.load_eth_settings = appl_load_eth_settings,
|
||||
.store_ethernet_settings = appl_store_ethernet_settings,
|
||||
.handle_recv_buffer = appl_handle_recv_buffer,
|
||||
.fetch_send_buffer = appl_fetch_send_buffer,
|
||||
.fragment_sent_event = eoe_frame_sent,
|
||||
};
|
||||
|
||||
/* Create an mailbox for interprocess communication between TCP/IP stack and
|
||||
* EtherCAT stack.
|
||||
*/
|
||||
pbuf_mbox = mbox_create (10);
|
||||
/* Set up dummy IF */
|
||||
found_if = net_add_interface(eoe_netif_init);
|
||||
if(found_if == NULL)
|
||||
{
|
||||
rprintf("OBS! Failed to create an EtherCAT network interface\n");
|
||||
}
|
||||
/* Init EoE */
|
||||
EOE_config(&eoe_config);
|
||||
|
||||
rprintf ("Hello world\n");
|
||||
ecat_slv_init (&config);
|
||||
|
||||
/* The stack is run from interrupt and a worker thread in esc_hw.c */
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,14 @@
|
|||
#include <stddef.h>
|
||||
#include "utypes.h"
|
||||
#include "ecat_options.h"
|
||||
#include "esc.h"
|
||||
|
||||
/* Global variables used by the stack */
|
||||
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
|
||||
_MBXcontrol MBXcontrol[MBXBUFFERS];
|
||||
_ESCvar ESCvar;
|
||||
_SMmap SMmap2[MAX_MAPPINGS_SM2];
|
||||
_SMmap SMmap3[MAX_MAPPINGS_SM3];
|
||||
|
||||
/* Application variables */
|
||||
_Objects _Obj;
|
|
@ -1,298 +1,421 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Slave id="evb9252_dig" productCode="1234">
|
||||
<Name>lan9252</Name>
|
||||
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="slave30" productCode="0x3030">
|
||||
<Name>slave30 product</Name>
|
||||
<Vendor>
|
||||
<Id>0x1337</Id>
|
||||
<Name>rt-labs AB</Name>
|
||||
<Name>rt-labs</Name>
|
||||
</Vendor>
|
||||
<Group>
|
||||
<Type>lan9252_spi</Type>
|
||||
<Name>lan9252</Name>
|
||||
<Type>sdk test</Type>
|
||||
<Name>sdk test</Name>
|
||||
</Group>
|
||||
<Fmmu>Outputs</Fmmu>
|
||||
<Fmmu>Inputs</Fmmu>
|
||||
<Fmmu>MBoxState</Fmmu>
|
||||
<Sm ControlByte="0x26" DefaultSize="128" StartAddress="0x1000">MBoxOut</Sm>
|
||||
<Sm ControlByte="0x22" DefaultSize="128" StartAddress="0x1080">MBoxIn</Sm>
|
||||
<Sm ControlByte="0x24" DefaultSize="0" StartAddress="0x1100">Outputs</Sm>
|
||||
<Sm ControlByte="0x64" DefaultSize="0" StartAddress="0x1100">Outputs</Sm>
|
||||
<Sm ControlByte="0x20" DefaultSize="0" StartAddress="0x1180">Inputs</Sm>
|
||||
<Mailbox CoE="true" FoE="true">
|
||||
<Mailbox CoE="true" EoE="true">
|
||||
<Bootstrap Length="128" Start="0x1000"/>
|
||||
<Standard Length="128" Start="0x1000"/>
|
||||
</Mailbox>
|
||||
<Eeprom>
|
||||
<ConfigData>8002000000000000</ConfigData>
|
||||
<ConfigData>8006810600000000</ConfigData>
|
||||
<BootStrap>0010800080108000</BootStrap>
|
||||
</Eeprom>
|
||||
<Dictionary>
|
||||
<Item>
|
||||
<Name>Device Type</Name>
|
||||
<Index>0x1000</Index>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x01901389</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Device Name</Name>
|
||||
<Index>0x1008</Index>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>evb9252_dig</DefaultValue>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name>Hardware Version</Name>
|
||||
<Index>0x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
<Length>4</Length>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name>Software Version</Name>
|
||||
<Index>0x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
<Length>4</Length>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00001389</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>slave30</DefaultValue>
|
||||
<Length>7</Length>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Identity Object</Name>
|
||||
<Index>0x1018</Index>
|
||||
<Name>Identity Object</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Vendor ID</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x1337</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Product Code</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>1234</DefaultValue>
|
||||
<DefaultValue>0x3030</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Revision Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Serial Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00000000</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>LEDs</Name>
|
||||
<Index>0x1600</Index>
|
||||
<Name>LEDgroup0</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED0</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000108</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED1</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000208</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Buttons</Name>
|
||||
<Index>0x1A00</Index>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>LED0</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000108</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1601</Index>
|
||||
<Name>LEDgroup1</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>LED1</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70010108</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1A00</Index>
|
||||
<Name>Buttons</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Button1</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x60000108</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Sync Manager Communication Type</Name>
|
||||
<Index>0x1C00</Index>
|
||||
<Name>Sync Manager Communication Type</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Communications Type SM0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Communications Type SM1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Communications Type SM2</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>3</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Communications Type SM3</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<Index>0x1C12</Index>
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1600</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1601</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Sync Manager 3 PDO Assignment</Name>
|
||||
<Index>0x1C13</Index>
|
||||
<Name>Sync Manager 3 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1A00</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Buttons</Name>
|
||||
<Index>0x6000</Index>
|
||||
<Name>Buttons</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>Buttons</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>Button1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RO</Access>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
<Variable>Button1</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>LEDs</Name>
|
||||
<Index>0x7000</Index>
|
||||
<Name>LEDgroup0</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>LEDs</Variable>
|
||||
<Variable>LEDgroup0</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RO</Access>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>LED0</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x7001</Index>
|
||||
<Name>LEDgroup1</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>LEDgroup1</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RO</Access>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>LED1</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Parameters</Name>
|
||||
<Index>0x8000</Index>
|
||||
<Name>Parameters</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>Parameters</Variable>
|
||||
<VariableType>Parameter</VariableType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>Multiplier</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RW</Access>
|
||||
<PdoMapping>TX_AND_RX</PdoMapping>
|
||||
<Variable>Multiplier</Variable>
|
||||
<VariableType>Parameter</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x8001</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>variableRW</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Variable>variableRW</Variable>
|
||||
<VariableType>Parameter</VariableType>
|
||||
</Item>
|
||||
</Dictionary>
|
||||
<RxPdo>
|
||||
<Index>0x1600</Index>
|
||||
<Container>LEDs</Container>
|
||||
<Name>LEDs</Name>
|
||||
<SmAssignment>
|
||||
<Index>0x1C12</Index>
|
||||
<Entry>
|
||||
<Index>0x7000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<Variable>LED0</Variable>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1600</AssignedPdo>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>0x7000</Index>
|
||||
<SubIndex>2</SubIndex>
|
||||
<Index>0x02</Index>
|
||||
<AssignedPdo>0x1601</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<SmAssignment>
|
||||
<Index>0x1C13</Index>
|
||||
<Entry>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1A00</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<RxPdo>
|
||||
<Index>0x1600</Index>
|
||||
<Name>LEDgroup0</Name>
|
||||
<Entry>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x01</MappedSubIndex>
|
||||
<Variable>LED0</Variable>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<RxPdo>
|
||||
<Index>0x1601</Index>
|
||||
<Name>LEDgroup1</Name>
|
||||
<Entry>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x7001</MappedIndex>
|
||||
<MappedSubIndex>0x01</MappedSubIndex>
|
||||
<Variable>LED1</Variable>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<TxPdo>
|
||||
<Index>0x1A00</Index>
|
||||
<Container>Buttons</Container>
|
||||
<Name>Buttons</Name>
|
||||
<Entry>
|
||||
<Index>0x6000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x6000</MappedIndex>
|
||||
<MappedSubIndex>0x01</MappedSubIndex>
|
||||
<Variable>Button1</Variable>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Input>
|
||||
<Index>0x6000</Index>
|
||||
<Name>Buttons</Name>
|
||||
<Type>RECORD</Type>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Name>Button1</Name>
|
||||
<Type>UNSIGNED8</Type>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
</Member>
|
||||
</Input>
|
||||
<Output>
|
||||
<Name>LEDs</Name>
|
||||
<Type>RECORD</Type>
|
||||
<Index>0x7000</Index>
|
||||
<Name>LEDgroup0</Name>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Name>LED0</Name>
|
||||
<Type>UNSIGNED8</Type>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
</Member>
|
||||
</Output>
|
||||
<Output>
|
||||
<Index>0x7001</Index>
|
||||
<Name>LEDgroup1</Name>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Name>LED1</Name>
|
||||
<Type>UNSIGNED8</Type>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
</Member>
|
||||
</Output>
|
||||
<Parameter>
|
||||
<Index>0x8000</Index>
|
||||
<Name>Parameters</Name>
|
||||
<Type>RECORD</Type>
|
||||
<PdoMapping>NONE</PdoMapping>
|
||||
<ObjectType>RECORD</ObjectType>
|
||||
<Member>
|
||||
<Index>0x01</Index>
|
||||
<Name>Multiplier</Name>
|
||||
<Type>UNSIGNED32</Type>
|
||||
<PdoMapping>TX_AND_RX</PdoMapping>
|
||||
</Member>
|
||||
</Parameter>
|
||||
</Slave>
|
||||
<Parameter>
|
||||
<Index>0x8001</Index>
|
||||
<Name>variableRW</Name>
|
||||
<Type>UNSIGNED32</Type>
|
||||
<PdoMapping>NONE</PdoMapping>
|
||||
<ObjectType>VAR</ObjectType>
|
||||
</Parameter>
|
||||
</Slave>
|
|
@ -2,23 +2,23 @@
|
|||
<EtherCATInfo>
|
||||
<Vendor>
|
||||
<Id>#x1337</Id>
|
||||
<Name LcId="1033">rt-labs AB</Name>
|
||||
<Name LcId="1033">rt-labs</Name>
|
||||
</Vendor>
|
||||
<Descriptions>
|
||||
<Groups>
|
||||
<Group>
|
||||
<Type>lan9252_spi</Type>
|
||||
<Name LcId="1033">lan9252</Name>
|
||||
<Type>sdk test</Type>
|
||||
<Name LcId="1033">sdk test</Name>
|
||||
</Group>
|
||||
</Groups>
|
||||
<Devices>
|
||||
<Device Physics="YY">
|
||||
<Type ProductCode="1234" RevisionNo="0">evb9252_dig</Type>
|
||||
<Name LcId="1033">lan9252</Name>
|
||||
<GroupType>lan9252_spi</GroupType>
|
||||
<Type ProductCode="#x3030" RevisionNo="0">slave30</Type>
|
||||
<Name LcId="1033">slave30 product</Name>
|
||||
<GroupType>sdk test</GroupType>
|
||||
<Profile>
|
||||
<ProfileNo>5001</ProfileNo>
|
||||
<AddInfo>400</AddInfo>
|
||||
<AddInfo>0</AddInfo>
|
||||
<Dictionary>
|
||||
<DataTypes>
|
||||
<DataType>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<BitSize>144</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -77,10 +77,10 @@
|
|||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1600</Name>
|
||||
<BitSize>80</BitSize>
|
||||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -98,12 +98,26 @@
|
|||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1601</Name>
|
||||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>2</SubIdx>
|
||||
<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>LED1</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>48</BitOffs>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
|
@ -114,7 +128,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -147,7 +161,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -168,18 +182,18 @@
|
|||
<DataType>
|
||||
<Name>DT1C12ARR</Name>
|
||||
<BaseType>UINT</BaseType>
|
||||
<BitSize>16</BitSize>
|
||||
<BitSize>32</BitSize>
|
||||
<ArrayInfo>
|
||||
<LBound>1</LBound>
|
||||
<Elements>1</Elements>
|
||||
<Elements>2</Elements>
|
||||
</ArrayInfo>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C12</Name>
|
||||
<BitSize>32</BitSize>
|
||||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -190,7 +204,7 @@
|
|||
<SubItem>
|
||||
<Name>Elements</Name>
|
||||
<Type>DT1C12ARR</Type>
|
||||
<BitSize>16</BitSize>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
|
@ -211,7 +225,7 @@
|
|||
<BitSize>32</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -234,7 +248,7 @@
|
|||
<BitSize>24</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -250,15 +264,16 @@
|
|||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<PdoMapping>T</PdoMapping>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT7000</Name>
|
||||
<BitSize>32</BitSize>
|
||||
<BitSize>24</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -272,18 +287,34 @@
|
|||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<PdoMapping>R</PdoMapping>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT7001</Name>
|
||||
<BitSize>24</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>2</SubIdx>
|
||||
<SubIdx>1</SubIdx>
|
||||
<Name>LED1</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>24</BitOffs>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<PdoMapping>R</PdoMapping>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
|
@ -292,7 +323,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
|
@ -307,17 +338,14 @@
|
|||
<BitSize>32</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>rw</Access>
|
||||
<Access>ro</Access>
|
||||
<PdoMapping>TR</PdoMapping>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(3)</Name>
|
||||
<BitSize>24</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(11)</Name>
|
||||
<BitSize>88</BitSize>
|
||||
<Name>STRING(4)</Name>
|
||||
<BitSize>32</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>UDINT</Name>
|
||||
|
@ -327,42 +355,21 @@
|
|||
<Name>UINT</Name>
|
||||
<BitSize>16</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(7)</Name>
|
||||
<BitSize>56</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>USINT</Name>
|
||||
<BitSize>8</BitSize>
|
||||
</DataType>
|
||||
</DataTypes>
|
||||
<Objects>
|
||||
<Object>
|
||||
<Index>#x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultValue>#x01901389</DefaultValue>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<Category>m</Category>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<Type>STRING(11)</Type>
|
||||
<BitSize>88</BitSize>
|
||||
<Info>
|
||||
<DefaultString>evb9252_dig</DefaultString>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Type>STRING(4)</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</DefaultString>
|
||||
</Info>
|
||||
|
@ -374,8 +381,8 @@
|
|||
<Object>
|
||||
<Index>#x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Type>STRING(4)</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</DefaultString>
|
||||
</Info>
|
||||
|
@ -383,6 +390,31 @@
|
|||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultValue>#x00001389</DefaultValue>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<Category>m</Category>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<Type>STRING(7)</Type>
|
||||
<BitSize>56</BitSize>
|
||||
<Info>
|
||||
<DefaultString>slave30</DefaultString>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1018</Index>
|
||||
<Name>Identity Object</Name>
|
||||
|
@ -390,7 +422,7 @@
|
|||
<BitSize>144</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</Info>
|
||||
|
@ -404,7 +436,7 @@
|
|||
<SubItem>
|
||||
<Name>Product Code</Name>
|
||||
<Info>
|
||||
<DefaultValue>1234</DefaultValue>
|
||||
<DefaultValue>#x3030</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
|
@ -426,14 +458,14 @@
|
|||
</Object>
|
||||
<Object>
|
||||
<Index>#x1600</Index>
|
||||
<Name>LEDs</Name>
|
||||
<Name>LEDgroup0</Name>
|
||||
<Type>DT1600</Type>
|
||||
<BitSize>80</BitSize>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
|
@ -442,10 +474,27 @@
|
|||
<DefaultValue>#x70000108</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1601</Index>
|
||||
<Name>LEDgroup1</Name>
|
||||
<Type>DT1601</Type>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED1</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x70000208</DefaultValue>
|
||||
<DefaultValue>#x70010108</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
|
@ -460,7 +509,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
|
@ -483,7 +532,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</Info>
|
||||
|
@ -521,12 +570,12 @@
|
|||
<Index>#x1C12</Index>
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<Type>DT1C12</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
|
@ -535,6 +584,12 @@
|
|||
<DefaultValue>#x1600</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>PDO Mapping</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x1601</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
|
@ -547,7 +602,7 @@
|
|||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
|
@ -570,7 +625,7 @@
|
|||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
|
@ -588,14 +643,14 @@
|
|||
</Object>
|
||||
<Object>
|
||||
<Index>#x7000</Index>
|
||||
<Name>LEDs</Name>
|
||||
<Name>LEDgroup0</Name>
|
||||
<Type>DT7000</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
|
@ -604,6 +659,23 @@
|
|||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x7001</Index>
|
||||
<Name>LEDgroup1</Name>
|
||||
<Type>DT7001</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED1</Name>
|
||||
<Info>
|
||||
|
@ -622,7 +694,7 @@
|
|||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
|
@ -638,28 +710,45 @@
|
|||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x8001</Index>
|
||||
<Name>variableRW</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
</Objects>
|
||||
</Dictionary>
|
||||
</Profile>
|
||||
<Fmmu>Outputs</Fmmu>
|
||||
<Fmmu>Inputs</Fmmu>
|
||||
<Fmmu>MBoxState</Fmmu>
|
||||
<Sm ControlByte="#x26" DefaultSize="128" Enable="1" StartAddress="#x1000">MBoxOut</Sm>
|
||||
<Sm ControlByte="#x22" DefaultSize="128" Enable="1" StartAddress="#x1080">MBoxIn</Sm>
|
||||
<Sm ControlByte="#x24" Enable="1" StartAddress="#x1100">Outputs</Sm>
|
||||
<Sm ControlByte="#x64" Enable="1" StartAddress="#x1100">Outputs</Sm>
|
||||
<Sm ControlByte="#x20" Enable="1" StartAddress="#x1180">Inputs</Sm>
|
||||
<RxPdo Fixed="true" Mandatory="true" Sm="2">
|
||||
<Index>#x1600</Index>
|
||||
<Name>LEDs</Name>
|
||||
<Name>LEDgroup0</Name>
|
||||
<Entry>
|
||||
<Index>#x7000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<SubIndex>#x1</SubIndex>
|
||||
<BitLen>8</BitLen>
|
||||
<Name>LED0</Name>
|
||||
<DataType>USINT</DataType>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<RxPdo Fixed="true" Mandatory="true" Sm="2">
|
||||
<Index>#x1601</Index>
|
||||
<Name>LEDgroup1</Name>
|
||||
<Entry>
|
||||
<Index>#x7000</Index>
|
||||
<SubIndex>2</SubIndex>
|
||||
<Index>#x7001</Index>
|
||||
<SubIndex>#x1</SubIndex>
|
||||
<BitLen>8</BitLen>
|
||||
<Name>LED1</Name>
|
||||
<DataType>USINT</DataType>
|
||||
|
@ -670,19 +759,19 @@
|
|||
<Name>Buttons</Name>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<SubIndex>#x1</SubIndex>
|
||||
<BitLen>8</BitLen>
|
||||
<Name>Button1</Name>
|
||||
<DataType>USINT</DataType>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Mailbox DataLinkLayer="true">
|
||||
<CoE CompleteAccess="false" PdoUpload="true" SdoInfo="true"/>
|
||||
<FoE/>
|
||||
<EoE/>
|
||||
<CoE CompleteAccess="false" PdoAssign="false" PdoUpload="false" SdoInfo="true"/>
|
||||
</Mailbox>
|
||||
<Eeprom>
|
||||
<ByteSize>256</ByteSize>
|
||||
<ConfigData>8002000000000000</ConfigData>
|
||||
<ConfigData>8006810600000000</ConfigData>
|
||||
<BootStrap>0010800080108000</BootStrap>
|
||||
</Eeprom>
|
||||
</Device>
|
|
@ -1,80 +1,94 @@
|
|||
#include "soes/esc_coe.h"
|
||||
#include "esc_coe.h"
|
||||
#include "utypes.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static const char acName1000[] = "Device Type";
|
||||
static const char acName1000_0[] = "Device Type";
|
||||
static const char acName1008[] = "Device Name";
|
||||
static const char acName1008_0[] = "Device Name";
|
||||
#ifndef HW_REV
|
||||
#define HW_REV "1.0"
|
||||
#endif
|
||||
|
||||
#ifndef SW_REV
|
||||
#define SW_REV "1.0"
|
||||
#endif
|
||||
|
||||
static const char acName1009[] = "Hardware Version";
|
||||
static const char acName1009_0[] = "Hardware Version";
|
||||
static const char acName100A[] = "Software Version";
|
||||
static const char acName100A_0[] = "Software Version";
|
||||
static const char acName1000[] = "Device Type";
|
||||
static const char acName1008[] = "Device Name";
|
||||
static const char acName1018[] = "Identity Object";
|
||||
static const char acName1018_00[] = "Number of Elements";
|
||||
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[] = "LEDs";
|
||||
static const char acName1600_00[] = "Number of Elements";
|
||||
static const char acName1600[] = "LEDgroup0";
|
||||
static const char acName1600_00[] = "Max SubIndex";
|
||||
static const char acName1600_01[] = "LED0";
|
||||
static const char acName1600_02[] = "LED1";
|
||||
static const char acName1601[] = "LEDgroup1";
|
||||
static const char acName1601_00[] = "Max SubIndex";
|
||||
static const char acName1601_01[] = "LED1";
|
||||
static const char acName1A00[] = "Buttons";
|
||||
static const char acName1A00_00[] = "Number of Elements";
|
||||
static const char acName1A00_00[] = "Max SubIndex";
|
||||
static const char acName1A00_01[] = "Button1";
|
||||
static const char acName1C00[] = "Sync Manager Communication Type";
|
||||
static const char acName1C00_00[] = "Number of Elements";
|
||||
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[] = "Number of Elements";
|
||||
static const char acName1C12_00[] = "Max SubIndex";
|
||||
static const char acName1C12_01[] = "PDO Mapping";
|
||||
static const char acName1C12_02[] = "PDO Mapping";
|
||||
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
|
||||
static const char acName1C13_00[] = "Number of Elements";
|
||||
static const char acName1C13_00[] = "Max SubIndex";
|
||||
static const char acName1C13_01[] = "PDO Mapping";
|
||||
static const char acName6000[] = "Buttons";
|
||||
static const char acName6000_00[] = "Number of Elements";
|
||||
static const char acName6000_00[] = "Max SubIndex";
|
||||
static const char acName6000_01[] = "Button1";
|
||||
static const char acName7000[] = "LEDs";
|
||||
static const char acName7000_00[] = "Number of Elements";
|
||||
static const char acName7000[] = "LEDgroup0";
|
||||
static const char acName7000_00[] = "Max SubIndex";
|
||||
static const char acName7000_01[] = "LED0";
|
||||
static const char acName7000_02[] = "LED1";
|
||||
static const char acName7001[] = "LEDgroup1";
|
||||
static const char acName7001_00[] = "Max SubIndex";
|
||||
static const char acName7001_01[] = "LED1";
|
||||
static const char acName8000[] = "Parameters";
|
||||
static const char acName8000_00[] = "Number of Elements";
|
||||
static const char acName8000_00[] = "Max SubIndex";
|
||||
static const char acName8000_01[] = "Multiplier";
|
||||
static const char acName8001[] = "variableRW";
|
||||
|
||||
const _objd SDO1000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000_0, 0x01901389, NULL},
|
||||
};
|
||||
const _objd SDO1008[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008_0, 0, "evb9252_dig"},
|
||||
};
|
||||
const _objd SDO1009[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009_0, 0, "1.0"},
|
||||
{0x0, DTYPE_VISIBLE_STRING, 32, ATYPE_RO, acName1009, 0, HW_REV},
|
||||
};
|
||||
const _objd SDO100A[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A_0, 0, "1.0"},
|
||||
{0x0, DTYPE_VISIBLE_STRING, 32, ATYPE_RO, acName100A, 0, SW_REV},
|
||||
};
|
||||
const _objd SDO1000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x00001389, NULL},
|
||||
};
|
||||
const _objd SDO1008[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 56, ATYPE_RO, acName1008, 0, "slave30"},
|
||||
};
|
||||
const _objd SDO1018[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 1234, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x3030, NULL},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
|
||||
};
|
||||
const _objd SDO1600[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 2, NULL},
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000108, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_02, 0x70000208, NULL},
|
||||
};
|
||||
const _objd SDO1601[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1601_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1601_01, 0x70010108, NULL},
|
||||
};
|
||||
const _objd SDO1A00[] =
|
||||
{
|
||||
|
@ -91,8 +105,9 @@ const _objd SDO1C00[] =
|
|||
};
|
||||
const _objd SDO1C12[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 1, NULL},
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 2, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
|
||||
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_02, 0x1601, NULL},
|
||||
};
|
||||
const _objd SDO1C13[] =
|
||||
{
|
||||
|
@ -102,18 +117,26 @@ const _objd SDO1C13[] =
|
|||
const _objd SDO6000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_01, 0, &Rb.Buttons.Button1},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_TXPDO, acName6000_01, 0, &Obj.Buttons.Button1},
|
||||
};
|
||||
const _objd SDO7000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 2, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_01, 0, &Wb.LEDs.LED0},
|
||||
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_02, 0, &Wb.LEDs.LED1},
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_RXPDO, acName7000_01, 0, &Obj.LEDgroup0.LED0},
|
||||
};
|
||||
const _objd SDO7001[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7001_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_RXPDO, acName7001_01, 0, &Obj.LEDgroup1.LED1},
|
||||
};
|
||||
const _objd SDO8000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Cb.Parameters.Multiplier},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_TXPDO | ATYPE_RXPDO, acName8000_01, 0, &Obj.Parameters.Multiplier},
|
||||
};
|
||||
const _objd SDO8001[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName8001, 0, &Obj.variableRW},
|
||||
};
|
||||
|
||||
const _objectlist SDOobjects[] =
|
||||
|
@ -123,13 +146,16 @@ const _objectlist SDOobjects[] =
|
|||
{0x1009, OTYPE_VAR, 0, 0, acName1009, SDO1009},
|
||||
{0x100A, OTYPE_VAR, 0, 0, acName100A, SDO100A},
|
||||
{0x1018, OTYPE_RECORD, 4, 0, acName1018, SDO1018},
|
||||
{0x1600, OTYPE_RECORD, 2, 0, acName1600, SDO1600},
|
||||
{0x1600, OTYPE_RECORD, 1, 0, acName1600, SDO1600},
|
||||
{0x1601, OTYPE_RECORD, 1, 0, acName1601, SDO1601},
|
||||
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
|
||||
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
|
||||
{0x1C12, OTYPE_ARRAY, 1, 0, acName1C12, SDO1C12},
|
||||
{0x1C12, OTYPE_ARRAY, 2, 0, acName1C12, SDO1C12},
|
||||
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
|
||||
{0x6000, OTYPE_RECORD, 1, 0, acName6000, SDO6000},
|
||||
{0x7000, OTYPE_RECORD, 2, 0, acName7000, SDO7000},
|
||||
{0x7000, OTYPE_RECORD, 1, 0, acName7000, SDO7000},
|
||||
{0x7001, OTYPE_RECORD, 1, 0, acName7001, SDO7001},
|
||||
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
|
||||
{0x8001, OTYPE_VAR, 0, 0, acName8001, SDO8001},
|
||||
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
#include "cc.h"
|
||||
|
||||
|
||||
/* Object dictionary storage */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Inputs */
|
||||
struct
|
||||
{
|
||||
uint8_t Button1;
|
||||
} Buttons;
|
||||
|
||||
|
||||
/* Outputs */
|
||||
struct
|
||||
{
|
||||
uint8_t LED0;
|
||||
} LEDgroup0;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t LED1;
|
||||
} LEDgroup1;
|
||||
|
||||
|
||||
/* Parameters */
|
||||
struct
|
||||
{
|
||||
uint32_t Multiplier;
|
||||
} Parameters;
|
||||
|
||||
uint32_t variableRW;
|
||||
|
||||
/* Manufacturer specific data */
|
||||
|
||||
/* Dynamic TX PDO:s */
|
||||
|
||||
/* Dynamic RX PDO:s */
|
||||
|
||||
/* Sync Managers */
|
||||
|
||||
} _Objects;
|
||||
|
||||
extern _Objects Obj;
|
||||
|
||||
#endif /* __UTYPES_H__ */
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
add_executable (rtl_slavedemo
|
||||
soes.c
|
||||
objectlist.c
|
||||
led_handler.c
|
||||
bootstrap.c
|
||||
|
|
|
@ -46,7 +46,7 @@ void boot_inithook (void)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t flash_foe_buffer (foe_writefile_cfg_t * self, uint8_t * data)
|
||||
uint32_t flash_foe_buffer (foe_writefile_cfg_t * self, uint8_t * data, size_t length)
|
||||
{
|
||||
uint32_t flash_cmd_failed = 0;
|
||||
uint32_t calculated_address = self->dest_start_address + self->address_offset;
|
||||
|
@ -118,7 +118,6 @@ void bootstrap_foe_init (void)
|
|||
{
|
||||
.buffer_size = FLASH_WRITE_BLOCK_SIZE, /* Buffer size before we flush to destination */
|
||||
.fbuffer = (uint8_t *)&fbuf,
|
||||
.empty_write = 0xFF,
|
||||
.n_files = NELEMENTS (files),
|
||||
.files = files
|
||||
};
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef __ECAT_OPTIONS_H__
|
||||
#define __ECAT_OPTIONS_H__
|
||||
|
||||
#include "cc.h"
|
||||
|
||||
#define USE_FOE 1
|
||||
#define USE_EOE 0
|
||||
|
||||
#define MBXSIZE 128
|
||||
#define MBXSIZEBOOT 128
|
||||
#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 0x1100
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1180
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#define MAX_RXPDO_SIZE 42
|
||||
#define MAX_TXPDO_SIZE 42
|
||||
|
||||
#define MAX_MAPPINGS_SM2 1
|
||||
#define MAX_MAPPINGS_SM3 2
|
||||
|
||||
#endif /* __ECAT_OPTIONS_H__ */
|
|
@ -4,8 +4,128 @@
|
|||
*/
|
||||
|
||||
#include <kern.h>
|
||||
#include "ecat_slv.h"
|
||||
#include "utypes.h"
|
||||
#include "bsp.h"
|
||||
#include "bootstrap.h"
|
||||
|
||||
int main(void)
|
||||
/* Application variables */
|
||||
_Rbuffer Rb;
|
||||
_Wbuffer Wb;
|
||||
_Cbuffer Cb;
|
||||
|
||||
uint32_t encoder_scale;
|
||||
uint32_t encoder_scale_mirror;
|
||||
|
||||
void cb_get_inputs (void)
|
||||
{
|
||||
Rb.button = gpio_get(GPIO_BUTTON_SW1);
|
||||
//Rb.button = (flash_drv_get_active_swap() && 0x8);
|
||||
Cb.reset_counter++;
|
||||
Rb.encoder = Cb.reset_counter;
|
||||
}
|
||||
|
||||
void cb_set_outputs (void)
|
||||
{
|
||||
gpio_set(GPIO_LED_BLUE, Wb.LED & BIT(0));
|
||||
}
|
||||
|
||||
/** Optional: Hook called after state change for application specific
|
||||
* actions for specific state changes.
|
||||
*/
|
||||
void post_state_change_hook (uint8_t * as, uint8_t * an)
|
||||
{
|
||||
|
||||
/* Add specific step change hooks here */
|
||||
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
|
||||
{
|
||||
boot_inithook ();
|
||||
}
|
||||
else if((*as == INIT_TO_BOOT) && (*an & ESCerror ) == 0)
|
||||
{
|
||||
init_boothook ();
|
||||
}
|
||||
}
|
||||
|
||||
void post_object_download_hook (uint16_t index, uint8_t subindex,
|
||||
uint16_t flags)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0x7100:
|
||||
{
|
||||
switch (subindex)
|
||||
{
|
||||
case 0x01:
|
||||
{
|
||||
encoder_scale_mirror = encoder_scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x8001:
|
||||
{
|
||||
switch (subindex)
|
||||
{
|
||||
case 0x01:
|
||||
{
|
||||
Cb.reset_counter = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void soes (void * arg)
|
||||
{
|
||||
|
||||
/* Setup config hooks */
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = "/spi0/et1100",
|
||||
.use_interrupt = 0,
|
||||
.set_defaults_hook = NULL,
|
||||
.watchdog_cnt = 1000,
|
||||
.pre_state_change_hook = NULL,
|
||||
.post_state_change_hook = post_state_change_hook,
|
||||
.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 = NULL,
|
||||
.esc_hw_interrupt_disable = NULL,
|
||||
.esc_hw_eep_handler = NULL
|
||||
};
|
||||
|
||||
ecat_slv_init (&config);
|
||||
|
||||
while (1)
|
||||
{
|
||||
ecat_slv();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t load1s, load5s, load10s;
|
||||
void my_cyclic_callback (void * arg)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
task_delay(tick_from_ms (20000));
|
||||
stats_get_load (&load1s, &load5s, &load10s);
|
||||
DPRINT ("%d:%d:%d (1s:5s:10s)\n",
|
||||
load1s, load5s, load10s);
|
||||
DPRINT ("Local bootstate: %d App.state: %d\n", local_boot_state,App.state);
|
||||
DPRINT ("AlStatus : 0x%x, AlError : 0x%x, Watchdog : %d \n", (ESCvar.ALstatus & 0x001f),ESCvar.ALerror,wd_cnt);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
extern void led_run (void *arg);
|
||||
extern void led_error (void *arg);
|
||||
|
|
|
@ -1,351 +0,0 @@
|
|||
/*
|
||||
* Licensed under the GNU General Public License version 2 with exceptions. See
|
||||
* LICENSE file in the project root for full license information
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief
|
||||
* The application.
|
||||
*
|
||||
* The application, the main loop that service EtherCAT.
|
||||
*/
|
||||
|
||||
#include <kern.h>
|
||||
#include <flash_drv.h>
|
||||
|
||||
#include <esc.h>
|
||||
#include <esc_coe.h>
|
||||
#include <esc_foe.h>
|
||||
#include "utypes.h"
|
||||
#include "config.h"
|
||||
#include "bootstrap.h"
|
||||
|
||||
#define WD_RESET 1000
|
||||
#define DEFAULTTXPDOMAP 0x1a00
|
||||
#define DEFAULTRXPDOMAP 0x1600
|
||||
#define DEFAULTTXPDOITEMS 1
|
||||
#define DEFAULTRXPDOITEMS 1
|
||||
|
||||
uint32_t encoder_scale;
|
||||
uint32_t encoder_scale_mirror;
|
||||
|
||||
/* Global variables used by the stack */
|
||||
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
|
||||
_MBXcontrol MBXcontrol[MBXBUFFERS];
|
||||
_ESCvar ESCvar;
|
||||
|
||||
/* Application variables */
|
||||
_Rbuffer Rb;
|
||||
_Wbuffer Wb;
|
||||
_Cbuffer Cb;
|
||||
|
||||
/* Private variables */
|
||||
int wd_cnt = WD_RESET;
|
||||
volatile uint8_t digoutput;
|
||||
volatile uint8_t diginput;
|
||||
uint16_t txpdomap = DEFAULTTXPDOMAP;
|
||||
uint16_t rxpdomap = DEFAULTRXPDOMAP;
|
||||
uint8_t txpdoitems = DEFAULTTXPDOITEMS;
|
||||
uint8_t rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
|
||||
|
||||
extern uint32_t local_boot_state;
|
||||
|
||||
/** 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 1 if the SDO Download is correct. 0 If not correct.
|
||||
*/
|
||||
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
if ((index == 0x1c12) && (subindex > 0) && (rxpdoitems != 0))
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
if ((index == 0x1c13) && (subindex > 0) && (txpdoitems != 0))
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/** Mandatory: 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
|
||||
*/
|
||||
void ESC_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0x1c12:
|
||||
{
|
||||
if (rxpdoitems > 1)
|
||||
{
|
||||
rxpdoitems = 1;
|
||||
}
|
||||
if ((rxpdomap != 0x1600) && (rxpdomap != 0x1601)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
rxpdomap = 0x1600;
|
||||
}
|
||||
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
|
||||
break;
|
||||
}
|
||||
case 0x1c13:
|
||||
{
|
||||
if (txpdoitems > 1)
|
||||
{
|
||||
txpdoitems = 1;
|
||||
}
|
||||
if ((txpdomap != 0x1A00) && (txpdomap != 0x1A01)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
txpdomap = 0x1A00;
|
||||
}
|
||||
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
|
||||
break;
|
||||
}
|
||||
case 0x7100:
|
||||
{
|
||||
switch (subindex)
|
||||
{
|
||||
case 0x01:
|
||||
{
|
||||
encoder_scale_mirror = encoder_scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x8001:
|
||||
{
|
||||
switch (subindex)
|
||||
{
|
||||
case 0x01:
|
||||
{
|
||||
Cb.reset_counter = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Mandatory: 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.
|
||||
* set
|
||||
*/
|
||||
void APP_safeoutput (void)
|
||||
{
|
||||
DPRINT ("APP_safeoutput called\n");
|
||||
Wb.LED = 0;
|
||||
}
|
||||
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
|
||||
*/
|
||||
void TXPDO_update (void)
|
||||
{
|
||||
ESC_write (SM3_sma, &Rb.button, ESCvar.TXPDOsize);
|
||||
}
|
||||
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
|
||||
*/
|
||||
void RXPDO_update (void)
|
||||
{
|
||||
ESC_read (SM2_sma, &Wb.LED, ESCvar.RXPDOsize);
|
||||
}
|
||||
|
||||
/** Mandatory: 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 (void)
|
||||
{
|
||||
if (wd_cnt)
|
||||
{
|
||||
wd_cnt--;
|
||||
}
|
||||
if (ESCvar.App.state & APPSTATE_OUTPUT)
|
||||
{
|
||||
/* SM2 trigger ? */
|
||||
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
|
||||
{
|
||||
ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2;
|
||||
RXPDO_update ();
|
||||
wd_cnt = WD_RESET;
|
||||
/* dummy output point */
|
||||
//gpio_set(GPIO_LED, Wb.LED & BIT(0));
|
||||
}
|
||||
if (!wd_cnt)
|
||||
{
|
||||
DPRINT("DIG_process watchdog tripped\n");
|
||||
ESC_stopoutput ();
|
||||
/* watchdog, invalid outputs */
|
||||
ESC_ALerror (ALERR_WATCHDOG);
|
||||
/* goto safe-op with error bit set */
|
||||
ESC_ALstatus (ESCsafeop | ESCerror);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wd_cnt = WD_RESET;
|
||||
}
|
||||
if (ESCvar.App.state)
|
||||
{
|
||||
//Rb.button = gpio_get(GPIO_WAKEUP);
|
||||
Rb.button = (flash_drv_get_active_swap() && 0x8);
|
||||
Cb.reset_counter++;
|
||||
Rb.encoder = Cb.reset_counter;
|
||||
TXPDO_update ();
|
||||
}
|
||||
}
|
||||
|
||||
/** Optional: Hook called after state change for application specific
|
||||
* actions for specific state changes.
|
||||
*/
|
||||
void post_state_change_hook (uint8_t * as, uint8_t * an)
|
||||
{
|
||||
|
||||
/* Add specific step change hooks here */
|
||||
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
|
||||
{
|
||||
boot_inithook ();
|
||||
}
|
||||
else if((*as == INIT_TO_BOOT) && (*an & ESCerror ) == 0)
|
||||
{
|
||||
init_boothook ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** SOES main loop. Start by initializing the stack software followed by
|
||||
* the application loop for cyclic read the EtherCAT state and staus, update
|
||||
* of I/O.
|
||||
*/
|
||||
void soes (void *arg)
|
||||
{
|
||||
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
|
||||
|
||||
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
|
||||
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
|
||||
|
||||
/* Setup config hooks */
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = "/spi0/et1100",
|
||||
.use_interrupt = 0,
|
||||
.watchdog_cnt = 0,
|
||||
.mbxsize = MBXSIZE,
|
||||
.mbxsizeboot = MBXSIZEBOOT,
|
||||
.mbxbuffers = MBXBUFFERS,
|
||||
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
|
||||
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
|
||||
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
|
||||
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
|
||||
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
|
||||
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
|
||||
.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 = NULL,
|
||||
.esc_hw_interrupt_disable = NULL,
|
||||
.esc_hw_eep_handler = NULL
|
||||
};
|
||||
|
||||
ESC_config (&config);
|
||||
ESC_init (&config);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* Pre FoE to set up Application information */
|
||||
bootstrap_foe_init ();
|
||||
/* Init FoE */
|
||||
FOE_init();
|
||||
|
||||
/* reset ESC to init state */
|
||||
ESC_ALstatus (ESCinit);
|
||||
ESC_ALerror (ALERR_NONE);
|
||||
ESC_stopmbx ();
|
||||
ESC_stopinput ();
|
||||
ESC_stopoutput ();
|
||||
|
||||
DPRINT ("Application_loop GO\n");
|
||||
/* application run loop */
|
||||
while (1)
|
||||
{
|
||||
/* On init restore PDO mappings to default size */
|
||||
if((ESCvar.ALstatus & 0x0f) == ESCinit)
|
||||
{
|
||||
txpdomap = DEFAULTTXPDOMAP;
|
||||
rxpdomap = DEFAULTRXPDOMAP;
|
||||
txpdoitems = DEFAULTTXPDOITEMS;
|
||||
rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
}
|
||||
/* 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 ();
|
||||
|
||||
/* If else to two separate execution paths
|
||||
* If we're running BOOSTRAP
|
||||
* - MailBox
|
||||
* - FoE
|
||||
* Else we're running normal execution
|
||||
* - MailBox
|
||||
* - CoE
|
||||
*/
|
||||
if(local_boot_state)
|
||||
{
|
||||
if (ESC_mbxprocess ())
|
||||
{
|
||||
ESC_foeprocess ();
|
||||
ESC_xoeprocess ();
|
||||
}
|
||||
bootstrap_state ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ESC_mbxprocess ())
|
||||
{
|
||||
ESC_coeprocess ();
|
||||
ESC_xoeprocess ();
|
||||
}
|
||||
DIG_process ();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
uint8_t load1s, load5s, load10s;
|
||||
void my_cyclic_callback (void * arg)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
task_delay(tick_from_ms (20000));
|
||||
stats_get_load (&load1s, &load5s, &load10s);
|
||||
DPRINT ("%d:%d:%d (1s:5s:10s)\n",
|
||||
load1s, load5s, load10s);
|
||||
DPRINT ("Local bootstate: %d App.state: %d\n", local_boot_state,App.state);
|
||||
DPRINT ("AlStatus : 0x%x, AlError : 0x%x, Watchdog : %d \n", (ESCvar.ALstatus & 0x001f),ESCvar.ALerror,wd_cnt);
|
||||
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t state;
|
||||
uint8_t button;
|
||||
uint32_t encoder;
|
||||
} _Rbuffer;
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
add_custom_command (
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sii_eeprom.o
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/sii_eeprom.bin
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND arm-eabi-objcopy -I binary -O elf32-littlearm -B arm sii_eeprom.bin ${CMAKE_CURRENT_BINARY_DIR}/sii_eeprom.o
|
||||
)
|
||||
|
||||
add_executable (demo
|
||||
slave_objectlist.c
|
||||
main.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/sii_eeprom.o
|
||||
)
|
||||
target_link_libraries(demo LINK_PUBLIC soes)
|
|
@ -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 0x1400
|
||||
#define SM2_smc 0x64
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1A00
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#define MAX_MAPPINGS_SM2 10
|
||||
#define MAX_MAPPINGS_SM3 9
|
||||
|
||||
#define MAX_RXPDO_SIZE 512
|
||||
#define MAX_TXPDO_SIZE 512
|
||||
|
||||
#endif /* __ECAT_OPTIONS_H__ */
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Licensed under the GNU General Public License version 2 with exceptions. See
|
||||
* LICENSE file in the project root for full license information
|
||||
*/
|
||||
|
||||
#include <kern.h>
|
||||
#include "esc.h"
|
||||
#include "esc_hw.h"
|
||||
#include "ecat_slv.h"
|
||||
#include "options.h"
|
||||
#include "utypes.h"
|
||||
#include "bsp.h"
|
||||
|
||||
/* Application variables */
|
||||
_Objects Obj;
|
||||
|
||||
/*
|
||||
* This function is called to get input values
|
||||
*/
|
||||
void cb_get_inputs()
|
||||
{
|
||||
Obj.Buttons.Button1 = gpio_get (GPIO_BUTTON1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called to set output values
|
||||
*/
|
||||
void cb_set_outputs()
|
||||
{
|
||||
gpio_set (GPIO_LED1, Obj.LEDgroup0.LED0);
|
||||
gpio_set (GPIO_LED2, Obj.LEDgroup1.LED1);
|
||||
}
|
||||
|
||||
void cb_state_change (uint8_t * as, uint8_t * an)
|
||||
{
|
||||
if (*as == SAFEOP_TO_OP)
|
||||
{
|
||||
/* Enable watchdog interrupt */
|
||||
ESC_ALeventmaskwrite (ESC_ALeventmaskread() | ESCREG_ALEVENT_WD);
|
||||
}
|
||||
else if (*as == PREOP_TO_SAFEOP)
|
||||
{
|
||||
/* Write initial input data requried if an input only slave,
|
||||
* otherwise the SM3 will never occur.
|
||||
*/
|
||||
DIG_process (DIG_PROCESS_INPUTS_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup of DC */
|
||||
uint16_t dc_checker (void)
|
||||
{
|
||||
/* Indicate we run DC */
|
||||
ESCvar.dcsync = 1;
|
||||
/* Fetch the sync counter limit (SDO10F1) */
|
||||
ESCvar.synccounterlimit = Obj.ErrorSettings.SyncErrorCounterLimit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = NULL,
|
||||
.use_interrupt = 1,
|
||||
.watchdog_cnt = INT32_MAX, /* Use HW SM watchdog instead */
|
||||
.set_defaults_hook = NULL,
|
||||
.pre_state_change_hook = NULL,
|
||||
.post_state_change_hook = cb_state_change,
|
||||
.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 = ESC_eep_handler,
|
||||
.esc_check_dc_handler = dc_checker
|
||||
.get_device_id = NULL
|
||||
};
|
||||
|
||||
rprintf ("Hello world\n");
|
||||
ecat_slv_init (&config);
|
||||
return 0;
|
||||
}
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,289 @@
|
|||
#include "esc_coe.h"
|
||||
#include "utypes.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef HW_REV
|
||||
#define HW_REV "1.0"
|
||||
#endif
|
||||
|
||||
#ifndef SW_REV
|
||||
#define SW_REV "1.0"
|
||||
#endif
|
||||
|
||||
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 acName10F1[] = "ErrorSettings";
|
||||
static const char acName10F1_00[] = "Max SubIndex";
|
||||
static const char acName10F1_01[] = "Local Error Reaction";
|
||||
static const char acName10F1_02[] = "SyncErrorCounterLimit";
|
||||
static const char acName1600[] = "RXPDO 1";
|
||||
static const char acName1600_00[] = "Max SubIndex";
|
||||
static const char acName1600_01[] = "LED0";
|
||||
static const char acName1601[] = "RXPDO 2";
|
||||
static const char acName1601_00[] = "Max SubIndex";
|
||||
static const char acName1601_01[] = "LED1";
|
||||
static const char acName1602[] = "RXPDO 3";
|
||||
static const char acName1602_00[] = "Max SubIndex";
|
||||
static const char acName1602_01[] = "PDO Entry 1602:01";
|
||||
static const char acName1602_02[] = "PDO Entry 1602:02";
|
||||
static const char acName1602_03[] = "PDO Entry 1602:03";
|
||||
static const char acName1602_04[] = "PDO Entry 1602:04";
|
||||
static const char acName1602_05[] = "PDO Entry 1602:05";
|
||||
static const char acName1602_06[] = "PDO Entry 1602:06";
|
||||
static const char acName1602_07[] = "PDO Entry 1602:07";
|
||||
static const char acName1602_08[] = "PDO Entry 1602:08";
|
||||
static const char acName1A00[] = "TXPDO 1";
|
||||
static const char acName1A00_00[] = "Max SubIndex";
|
||||
static const char acName1A00_01[] = "Button1";
|
||||
static const char acName1A01[] = "TXPDO 2";
|
||||
static const char acName1A01_00[] = "Max SubIndex";
|
||||
static const char acName1A01_01[] = "PDO Entry 1A01:01";
|
||||
static const char acName1A01_02[] = "PDO Entry 1A01:02";
|
||||
static const char acName1A01_03[] = "PDO Entry 1A01:03";
|
||||
static const char acName1A01_04[] = "PDO Entry 1A01:04";
|
||||
static const char acName1A01_05[] = "PDO Entry 1A01:05";
|
||||
static const char acName1A01_06[] = "PDO Entry 1A01:06";
|
||||
static const char acName1A01_07[] = "PDO Entry 1A01:07";
|
||||
static const char acName1A01_08[] = "PDO Entry 1A01:08";
|
||||
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[] = "SM Entry 1C12:03";
|
||||
static const char acName1C12_04[] = "SM Entry 1C12:04";
|
||||
static const char acName1C12_05[] = "SM Entry 1C12:05";
|
||||
static const char acName1C12_06[] = "SM Entry 1C12:06";
|
||||
static const char acName1C12_07[] = "SM Entry 1C12:07";
|
||||
static const char acName1C12_08[] = "SM Entry 1C12:08";
|
||||
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[] = "SM Entry 1C13:02";
|
||||
static const char acName1C13_03[] = "SM Entry 1C13:03";
|
||||
static const char acName1C13_04[] = "SM Entry 1C13:04";
|
||||
static const char acName1C13_05[] = "SM Entry 1C13:05";
|
||||
static const char acName1C13_06[] = "SM Entry 1C13:06";
|
||||
static const char acName1C13_07[] = "SM Entry 1C13:07";
|
||||
static const char acName1C13_08[] = "SM Entry 1C13:08";
|
||||
static const char acName1C32[] = "SyncMgrParam";
|
||||
static const char acName1C32_00[] = "Max SubIndex";
|
||||
static const char acName1C32_01[] = "Sync mode";
|
||||
static const char acName1C32_02[] = "CycleTime";
|
||||
static const char acName1C32_03[] = "ShiftTime";
|
||||
static const char acName1C32_04[] = "Sync modes supported";
|
||||
static const char acName1C32_05[] = "Minimum Cycle Time";
|
||||
static const char acName1C32_06[] = "Calc and Copy Time";
|
||||
static const char acName1C32_07[] = "Minimum Delay Time";
|
||||
static const char acName1C32_08[] = "GetCycleTime";
|
||||
static const char acName1C32_09[] = "DelayTime";
|
||||
static const char acName1C32_0A[] = "Sync0CycleTime";
|
||||
static const char acName1C32_0B[] = "SMEventMissedCnt";
|
||||
static const char acName1C32_0C[] = "CycleTimeTooSmallCnt";
|
||||
static const char acName1C32_0D[] = "Shift too short counter";
|
||||
static const char acName1C32_0E[] = "RxPDOToggleFailed";
|
||||
static const char acName1C32_0F[] = "Minimum Cycle Distance";
|
||||
static const char acName1C32_10[] = "Maximum Cycle Distance";
|
||||
static const char acName1C32_11[] = "Minimum SM Sync Distance";
|
||||
static const char acName1C32_12[] = "Maximum SM Sync Distance";
|
||||
static const char acName1C32_20[] = "SyncError";
|
||||
static const char acName6000[] = "Buttons";
|
||||
static const char acName6000_00[] = "Max SubIndex";
|
||||
static const char acName6000_01[] = "Button1";
|
||||
static const char acName7000[] = "LEDgroup0";
|
||||
static const char acName7000_00[] = "Max SubIndex";
|
||||
static const char acName7000_01[] = "LED0";
|
||||
static const char acName7001[] = "LEDgroup1";
|
||||
static const char acName7001_00[] = "Max SubIndex";
|
||||
static const char acName7001_01[] = "LED1";
|
||||
static const char acName8000[] = "Parameters";
|
||||
static const char acName8000_00[] = "Max SubIndex";
|
||||
static const char acName8000_01[] = "Multiplier";
|
||||
static const char acName8001[] = "variableRW";
|
||||
|
||||
const _objd SDO1000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x00001389, NULL},
|
||||
};
|
||||
const _objd SDO1008[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 80, ATYPE_RO, acName1008, 0, "xmc48relax"},
|
||||
};
|
||||
const _objd SDO1009[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009, 0, HW_REV},
|
||||
};
|
||||
const _objd SDO100A[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A, 0, SW_REV},
|
||||
};
|
||||
const _objd SDO1018[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x4800, NULL},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, &Obj.serial},
|
||||
};
|
||||
const _objd SDO10F1[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName10F1_00, 2, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName10F1_01, 0, &Obj.ErrorSettings.Local_Error_Reaction},
|
||||
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RW, acName10F1_02, 2, &Obj.ErrorSettings.SyncErrorCounterLimit},
|
||||
};
|
||||
const _objd SDO1600[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000108, NULL},
|
||||
};
|
||||
const _objd SDO1601[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1601_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1601_01, 0x70010108, NULL},
|
||||
};
|
||||
const _objd SDO1602[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RWpre, acName1602_00, 8, &Obj.PDO1602.maxsub},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_01, 0x00000000, &Obj.PDO1602.value[0]},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_02, 0x00000000, &Obj.PDO1602.value[1]},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_03, 0x00000000, &Obj.PDO1602.value[2]},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_04, 0x00000000, &Obj.PDO1602.value[3]},
|
||||
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_05, 0x00000000, &Obj.PDO1602.value[4]},
|
||||
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_06, 0x00000000, &Obj.PDO1602.value[5]},
|
||||
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_07, 0x00000000, &Obj.PDO1602.value[6]},
|
||||
{0x08, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_08, 0x00000000, &Obj.PDO1602.value[7]},
|
||||
};
|
||||
const _objd SDO1A00[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60000108, NULL},
|
||||
};
|
||||
const _objd SDO1A01[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RWpre, acName1A01_00, 8, &Obj.PDO1A01.maxsub},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_01, 0x00000000, &Obj.PDO1A01.value[0]},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_02, 0x00000000, &Obj.PDO1A01.value[1]},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_03, 0x00000000, &Obj.PDO1A01.value[2]},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_04, 0x00000000, &Obj.PDO1A01.value[3]},
|
||||
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_05, 0x00000000, &Obj.PDO1A01.value[4]},
|
||||
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_06, 0x00000000, &Obj.PDO1A01.value[5]},
|
||||
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_07, 0x00000000, &Obj.PDO1A01.value[6]},
|
||||
{0x08, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_08, 0x00000000, &Obj.PDO1A01.value[7]},
|
||||
};
|
||||
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_RWpre, acName1C12_00, 8, &Obj.SM1C12.maxsub},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_01, 0x1600, &Obj.SM1C12.value[0]},
|
||||
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_02, 0x1601, &Obj.SM1C12.value[1]},
|
||||
{0x03, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_03, 0x0000, &Obj.SM1C12.value[2]},
|
||||
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_04, 0x0000, &Obj.SM1C12.value[3]},
|
||||
{0x05, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_05, 0x0000, &Obj.SM1C12.value[4]},
|
||||
{0x06, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_06, 0x0000, &Obj.SM1C12.value[5]},
|
||||
{0x07, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_07, 0x0000, &Obj.SM1C12.value[6]},
|
||||
{0x08, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_08, 0x0000, &Obj.SM1C12.value[7]},
|
||||
};
|
||||
const _objd SDO1C13[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RWpre, acName1C13_00, 8, &Obj.SM1C13.maxsub},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_01, 0x1A00, &Obj.SM1C13.value[0]},
|
||||
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_02, 0x0000, &Obj.SM1C13.value[1]},
|
||||
{0x03, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_03, 0x0000, &Obj.SM1C13.value[2]},
|
||||
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_04, 0x0000, &Obj.SM1C13.value[3]},
|
||||
{0x05, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_05, 0x0000, &Obj.SM1C13.value[4]},
|
||||
{0x06, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_06, 0x0000, &Obj.SM1C13.value[5]},
|
||||
{0x07, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_07, 0x0000, &Obj.SM1C13.value[6]},
|
||||
{0x08, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_08, 0x0000, &Obj.SM1C13.value[7]},
|
||||
};
|
||||
const _objd SDO1C32[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_00, 32, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RW, acName1C32_01, 0, &Obj.SyncMgrParam.Sync_mode},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_02, 0, &Obj.SyncMgrParam.CycleTime},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_03, 0, &Obj.SyncMgrParam.ShiftTime},
|
||||
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_04, 0, &Obj.SyncMgrParam.Sync_modes_supported},
|
||||
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_05, 125000, &Obj.SyncMgrParam.Minimum_Cycle_Time},
|
||||
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_06, 0, &Obj.SyncMgrParam.Calc_and_Copy_Time},
|
||||
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_07, 0, &Obj.SyncMgrParam.Minimum_Delay_Time},
|
||||
{0x08, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_08, 0, &Obj.SyncMgrParam.GetCycleTime},
|
||||
{0x09, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_09, 0, &Obj.SyncMgrParam.DelayTime},
|
||||
{0x0A, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0A, 0, &Obj.SyncMgrParam.Sync0CycleTime},
|
||||
{0x0B, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0B, 0, &Obj.SyncMgrParam.SMEventMissedCnt},
|
||||
{0x0C, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0C, 0, &Obj.SyncMgrParam.CycleTimeTooSmallCnt},
|
||||
{0x0D, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0D, 0, &Obj.SyncMgrParam.Shift_too_short_counter},
|
||||
{0x0E, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0E, 0, &Obj.SyncMgrParam.RxPDOToggleFailed},
|
||||
{0x0F, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0F, 0, &Obj.SyncMgrParam.Minimum_Cycle_Distance},
|
||||
{0x10, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_10, 0, &Obj.SyncMgrParam.Maximum_Cycle_Distance},
|
||||
{0x11, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_11, 0, &Obj.SyncMgrParam.Minimum_SM_Sync_Distance},
|
||||
{0x12, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_12, 0, &Obj.SyncMgrParam.Maximum_SM_Sync_Distance},
|
||||
{0x20, DTYPE_BOOLEAN, 1, ATYPE_RO, acName1C32_20, 0, &Obj.SyncMgrParam.SyncError},
|
||||
};
|
||||
const _objd SDO6000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_TXPDO, acName6000_01, 0, &Obj.Buttons.Button1},
|
||||
};
|
||||
const _objd SDO7000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_RXPDO, acName7000_01, 0, &Obj.LEDgroup0.LED0},
|
||||
};
|
||||
const _objd SDO7001[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7001_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_RXPDO, acName7001_01, 0, &Obj.LEDgroup1.LED1},
|
||||
};
|
||||
const _objd SDO8000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName8000_01, 0, &Obj.Parameters.Multiplier},
|
||||
};
|
||||
const _objd SDO8001[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8001, 0, &Obj.variableRW},
|
||||
};
|
||||
|
||||
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},
|
||||
{0x10F1, OTYPE_RECORD, 2, 0, acName10F1, SDO10F1},
|
||||
{0x1600, OTYPE_RECORD, 1, 0, acName1600, SDO1600},
|
||||
{0x1601, OTYPE_RECORD, 1, 0, acName1601, SDO1601},
|
||||
{0x1602, OTYPE_RECORD, 8, 0, acName1602, SDO1602},
|
||||
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
|
||||
{0x1A01, OTYPE_RECORD, 8, 0, acName1A01, SDO1A01},
|
||||
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
|
||||
{0x1C12, OTYPE_ARRAY, 8, 0, acName1C12, SDO1C12},
|
||||
{0x1C13, OTYPE_ARRAY, 8, 0, acName1C13, SDO1C13},
|
||||
{0x1C32, OTYPE_RECORD, 19, 0, acName1C32, SDO1C32},
|
||||
{0x6000, OTYPE_RECORD, 1, 0, acName6000, SDO6000},
|
||||
{0x7000, OTYPE_RECORD, 1, 0, acName7000, SDO7000},
|
||||
{0x7001, OTYPE_RECORD, 1, 0, acName7001, SDO7001},
|
||||
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
|
||||
{0x8001, OTYPE_VAR, 0, 0, acName8001, SDO8001},
|
||||
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
|
||||
};
|
|
@ -0,0 +1,103 @@
|
|||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
#include "cc.h"
|
||||
|
||||
/* Object dictionary storage */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Identity */
|
||||
|
||||
uint32_t serial;
|
||||
|
||||
/* Inputs */
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t Button1;
|
||||
} Buttons;
|
||||
|
||||
/* Outputs */
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t LED0;
|
||||
} LEDgroup0;
|
||||
struct
|
||||
{
|
||||
uint8_t LED1;
|
||||
} LEDgroup1;
|
||||
|
||||
/* Parameters */
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t Multiplier;
|
||||
} Parameters;
|
||||
uint32_t variableRW;
|
||||
|
||||
/* Manufacturer specific data */
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t Local_Error_Reaction;
|
||||
uint16_t SyncErrorCounterLimit;
|
||||
} ErrorSettings;
|
||||
struct
|
||||
{
|
||||
uint16_t Sync_mode;
|
||||
uint32_t CycleTime;
|
||||
uint32_t ShiftTime;
|
||||
uint16_t Sync_modes_supported;
|
||||
uint32_t Minimum_Cycle_Time;
|
||||
uint32_t Calc_and_Copy_Time;
|
||||
uint32_t Minimum_Delay_Time;
|
||||
uint16_t GetCycleTime;
|
||||
uint32_t DelayTime;
|
||||
uint32_t Sync0CycleTime;
|
||||
uint16_t SMEventMissedCnt;
|
||||
uint16_t CycleTimeTooSmallCnt;
|
||||
uint16_t Shift_too_short_counter;
|
||||
uint16_t RxPDOToggleFailed;
|
||||
uint32_t Minimum_Cycle_Distance;
|
||||
uint32_t Maximum_Cycle_Distance;
|
||||
uint32_t Minimum_SM_Sync_Distance;
|
||||
uint32_t Maximum_SM_Sync_Distance;
|
||||
uint8_t SyncError;
|
||||
} SyncMgrParam;
|
||||
|
||||
/* Dynamic TX PDO:s */
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t maxsub;
|
||||
uint32_t value[8];
|
||||
} PDO1A01;
|
||||
|
||||
/* Dynamic RX PDO:s */
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t maxsub;
|
||||
uint32_t value[8];
|
||||
} PDO1602;
|
||||
|
||||
/* Dynamic Sync Managers */
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t maxsub;
|
||||
uint32_t value[8];
|
||||
} SM1C12;
|
||||
struct
|
||||
{
|
||||
uint8_t maxsub;
|
||||
uint32_t value[8];
|
||||
} SM1C13;
|
||||
|
||||
} _Objects;
|
||||
|
||||
extern _Objects Obj;
|
||||
|
||||
#endif /* __UTYPES_H__ */
|
|
@ -1,35 +0,0 @@
|
|||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
#include <cc.h>
|
||||
|
||||
#define MBXSIZE 128
|
||||
#define MBXSIZEBOOT 256
|
||||
#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 0x1100
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1180
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#endif /* __CONFIG_H__ */
|
|
@ -1,184 +0,0 @@
|
|||
#include <kern.h>
|
||||
#include <xmc4.h>
|
||||
#include <bsp.h>
|
||||
#include "slave.h"
|
||||
#include "esc_hw.h"
|
||||
#include "config.h"
|
||||
|
||||
#define SAMPLE_CODE 0
|
||||
|
||||
/**
|
||||
* This function reads physical input values and assigns the corresponding members
|
||||
* of Rb.Buttons
|
||||
*/
|
||||
void cb_get_Buttons()
|
||||
{
|
||||
Rb.Buttons.Button1 = gpio_get(GPIO_BUTTON1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members of
|
||||
* Wb.LEDs
|
||||
*/
|
||||
void cb_set_LEDgroup0()
|
||||
{
|
||||
gpio_set(GPIO_LED1, Wb.LEDgroup0.LED0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members of
|
||||
* Wb.LEDs
|
||||
*/
|
||||
void cb_set_LEDgroup1()
|
||||
{
|
||||
gpio_set(GPIO_LED2, Wb.LEDgroup1.LED1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called after a SDO write of the object Cb.Parameters.
|
||||
*/
|
||||
void cb_post_write_variableRW(int subindex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Optional: Hook called after state change for application specific
|
||||
* actions for specific state changes.
|
||||
*/
|
||||
void pre_state_change_hook (uint8_t * as, uint8_t * an)
|
||||
{
|
||||
}
|
||||
|
||||
/** Optional: Hook called after state change for application specific
|
||||
* actions for specific state changes.
|
||||
*/
|
||||
void post_state_change_hook (uint8_t * as, uint8_t * an)
|
||||
{
|
||||
#if SAMPLE_CODE
|
||||
/* Add specific step change hooks here */
|
||||
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
|
||||
{
|
||||
rprintf("boot BOOT_TO_INIT\n");
|
||||
upgrade_finished();
|
||||
/* If we return here */
|
||||
ESC_ALerror (ALERR_NOVALIDFIRMWARE);
|
||||
/* Upgrade failed, enter init with error */
|
||||
*an = (ESCinit | ESCerror);
|
||||
}
|
||||
else if((*as == PREOP_TO_SAFEOP))
|
||||
{
|
||||
rprintf("boot PREOP_TO_SAFEOP\n");
|
||||
ESC_ALerror (ALERR_NOVALIDFIRMWARE);
|
||||
/* Stay in preop with error bit set */
|
||||
*an = (ESCpreop | ESCerror);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void user_post_dl_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
#if SAMPLE_CODE
|
||||
switch (index)
|
||||
{
|
||||
case 0x1c12:
|
||||
{
|
||||
RXPDOsize = ESC_SM2_sml = sizeRXPDO();
|
||||
break;
|
||||
}
|
||||
|
||||
/* Handle post-write of parameter values */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int user_pre_dl_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
#if SAMPLE_CODE
|
||||
if (index == 0x1c12)
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
if (index == 0x1c13)
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Called from stack when stopping outputs */
|
||||
void user_safeoutput (void)
|
||||
{
|
||||
#if SAMPLE_CODE
|
||||
DPRINT ("APP_safeoutput\n");
|
||||
|
||||
// Set safe values for Wb.LEDgroup0
|
||||
Wb.LEDgroup0.LED0 = 1;
|
||||
|
||||
// Set safe values for Wb.LEDgroup1
|
||||
Wb.LEDgroup1.LED1 = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Configuration parameters for SOES
|
||||
* SM and Mailbox parameters comes from the
|
||||
* generated config.h
|
||||
*/
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = NULL,
|
||||
.use_interrupt = 1,
|
||||
.watchdog_cnt = 100,
|
||||
.mbxsize = MBXSIZE,
|
||||
.mbxsizeboot = MBXSIZEBOOT,
|
||||
.mbxbuffers = MBXBUFFERS,
|
||||
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
|
||||
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
|
||||
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
|
||||
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
|
||||
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
|
||||
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
|
||||
.pre_state_change_hook = NULL,
|
||||
.post_state_change_hook = NULL,
|
||||
.application_hook = NULL,
|
||||
.safeoutput_override = user_safeoutput,
|
||||
.pre_object_download_hook = user_pre_dl_objecthandler,
|
||||
.post_object_download_hook = user_post_dl_objecthandler,
|
||||
.rxpdo_override = NULL,
|
||||
.txpdo_override = NULL,
|
||||
.esc_hw_interrupt_enable = ESC_interrupt_enable,
|
||||
.esc_hw_interrupt_disable = ESC_interrupt_disable,
|
||||
.esc_hw_eep_handler = ESC_eep_handler
|
||||
};
|
||||
|
||||
void main_run(void * arg)
|
||||
{
|
||||
ecat_slv_init(&config);
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(config.use_interrupt != 0)
|
||||
{
|
||||
DIG_process(DIG_PROCESS_WD_FLAG);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecat_slv();
|
||||
}
|
||||
task_delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
rprintf("Hello Main\n");
|
||||
task_spawn ("soes", main_run, 8, 2048, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Binary file not shown.
|
@ -1,218 +0,0 @@
|
|||
#ifndef SOES_V1
|
||||
#include "esc_coe.h"
|
||||
#include "utypes.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static const char acName1000[] = "Device Type";
|
||||
static const char acName1000_0[] = "Device Type";
|
||||
static const char acName1008[] = "Device Name";
|
||||
static const char acName1008_0[] = "Device Name";
|
||||
static const char acName1009[] = "Hardware Version";
|
||||
static const char acName1009_0[] = "Hardware Version";
|
||||
static const char acName100A[] = "Software Version";
|
||||
static const char acName100A_0[] = "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 acName10F1[] = "ErrorSettings";
|
||||
static const char acName10F1_00[] = "Max SubIndex";
|
||||
static const char acName10F1_01[] = "Dummy_x01";
|
||||
static const char acName10F1_02[] = "SyncErrorCounterLimit";
|
||||
static const char acName1600[] = "LEDgroup0";
|
||||
static const char acName1600_00[] = "Max SubIndex";
|
||||
static const char acName1600_01[] = "LED0";
|
||||
static const char acName1601[] = "LEDgroup1";
|
||||
static const char acName1601_00[] = "Max SubIndex";
|
||||
static const char acName1601_01[] = "LED1";
|
||||
static const char acName1A00[] = "Buttons";
|
||||
static const char acName1A00_00[] = "Max SubIndex";
|
||||
static const char acName1A00_01[] = "Button1";
|
||||
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 acName1C13[] = "Sync Manager 3 PDO Assignment";
|
||||
static const char acName1C13_00[] = "Max SubIndex";
|
||||
static const char acName1C13_01[] = "PDO Mapping";
|
||||
static const char acName1C32[] = "SyncMgrParam";
|
||||
static const char acName1C32_00[] = "Max SubIndex";
|
||||
static const char acName1C32_01[] = "SyncType";
|
||||
static const char acName1C32_02[] = "CycleTime";
|
||||
static const char acName1C32_03[] = "ShiftTime";
|
||||
static const char acName1C32_04[] = "SyncTypeSupport";
|
||||
static const char acName1C32_05[] = "MinCycleTime";
|
||||
static const char acName1C32_06[] = "CalcCopyTime";
|
||||
static const char acName1C32_07[] = "MinDelayTime";
|
||||
static const char acName1C32_08[] = "GetCycleTime";
|
||||
static const char acName1C32_09[] = "DelayTime";
|
||||
static const char acName1C32_0A[] = "Sync0CycleTime";
|
||||
static const char acName1C32_0B[] = "SMEventMissedCnt";
|
||||
static const char acName1C32_0C[] = "CycleTimeTooSmallCnt";
|
||||
static const char acName1C32_0D[] = "ShiftTimeTooSmallCnt";
|
||||
static const char acName1C32_0E[] = "RxPDOToggleFailed";
|
||||
static const char acName1C32_0F[] = "MinCycleDist";
|
||||
static const char acName1C32_10[] = "MaxCycleDist";
|
||||
static const char acName1C32_11[] = "MinSMSYNCDist";
|
||||
static const char acName1C32_12[] = "MaxSMSYNCDist";
|
||||
static const char acName1C32_14[] = "Dummy_x14";
|
||||
static const char acName1C32_20[] = "SyncError";
|
||||
static const char acName6005[] = "Buttons";
|
||||
static const char acName6005_00[] = "Max SubIndex";
|
||||
static const char acName6005_01[] = "Button1";
|
||||
static const char acName7005[] = "LEDgroup0";
|
||||
static const char acName7005_00[] = "Max SubIndex";
|
||||
static const char acName7005_01[] = "LED0";
|
||||
static const char acName7006[] = "LEDgroup1";
|
||||
static const char acName7006_00[] = "Max SubIndex";
|
||||
static const char acName7006_01[] = "LED1";
|
||||
static const char acName8000[] = "Parameters";
|
||||
static const char acName8000_00[] = "Max SubIndex";
|
||||
static const char acName8000_01[] = "Multiplier";
|
||||
static const char acName8001[] = "variableRW";
|
||||
static const char acName8001_0[] = "variableRW";
|
||||
|
||||
const _objd SDO1000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000_0, 0x00001389, NULL},
|
||||
};
|
||||
const _objd SDO1008[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008_0, 0, "xmc43_slave"},
|
||||
};
|
||||
const _objd SDO1009[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009_0, 0, "1.0"},
|
||||
};
|
||||
const _objd SDO100A[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A_0, 0, "1.0"},
|
||||
};
|
||||
const _objd SDO1018[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 4300, NULL},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
|
||||
};
|
||||
const _objd SDO10F1[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName10F1_00, 2, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName10F1_01, 0, &Mb.ErrorSettings.Dummy_x01},
|
||||
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RW, acName10F1_02, 2, &Mb.ErrorSettings.SyncErrorCounterLimit},
|
||||
};
|
||||
const _objd SDO1600[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70050108, NULL},
|
||||
};
|
||||
const _objd SDO1601[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1601_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1601_01, 0x70060108, NULL},
|
||||
};
|
||||
const _objd SDO1A00[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60050108, 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, 2, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
|
||||
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_02, 0x1601, NULL},
|
||||
};
|
||||
const _objd SDO1C13[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL},
|
||||
};
|
||||
const _objd SDO1C32[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_00, 32, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_01, 1, &Mb.SyncMgrParam.SyncType},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_02, 0, &Mb.SyncMgrParam.CycleTime},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_03, 0, &Mb.SyncMgrParam.ShiftTime},
|
||||
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_04, 0x6, &Mb.SyncMgrParam.SyncTypeSupport},
|
||||
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_05, 125000, &Mb.SyncMgrParam.MinCycleTime},
|
||||
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_06, 0, &Mb.SyncMgrParam.CalcCopyTime},
|
||||
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_07, 0, &Mb.SyncMgrParam.MinDelayTime},
|
||||
{0x08, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_08, 0, &Mb.SyncMgrParam.GetCycleTime},
|
||||
{0x09, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_09, 0, &Mb.SyncMgrParam.DelayTime},
|
||||
{0x0A, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0A, 0, &Mb.SyncMgrParam.Sync0CycleTime},
|
||||
{0x0B, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0B, 0, &Mb.SyncMgrParam.SMEventMissedCnt},
|
||||
{0x0C, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0C, 0, &Mb.SyncMgrParam.CycleTimeTooSmallCnt},
|
||||
{0x0D, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0D, 0, &Mb.SyncMgrParam.ShiftTimeTooSmallCnt},
|
||||
{0x0E, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0E, 0, &Mb.SyncMgrParam.RxPDOToggleFailed},
|
||||
{0x0F, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0F, 0, &Mb.SyncMgrParam.MinCycleDist},
|
||||
{0x10, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_10, 0, &Mb.SyncMgrParam.MaxCycleDist},
|
||||
{0x11, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_11, 0, &Mb.SyncMgrParam.MinSMSYNCDist},
|
||||
{0x12, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_12, 0, &Mb.SyncMgrParam.MaxSMSYNCDist},
|
||||
{0x14, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_14, 0, &Mb.SyncMgrParam.Dummy_x14},
|
||||
{0x20, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_20, 0, &Mb.SyncMgrParam.SyncError},
|
||||
};
|
||||
const _objd SDO6005[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6005_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6005_01, 0, &Rb.Buttons.Button1},
|
||||
};
|
||||
const _objd SDO7005[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7005_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7005_01, 0, &Wb.LEDgroup0.LED0},
|
||||
};
|
||||
const _objd SDO7006[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7006_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7006_01, 0, &Wb.LEDgroup1.LED1},
|
||||
};
|
||||
const _objd SDO8000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Cb.Parameters.Multiplier},
|
||||
};
|
||||
const _objd SDO8001[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8001_0, 0, &Cb.variableRW},
|
||||
};
|
||||
|
||||
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},
|
||||
{0x10F1, OTYPE_RECORD, 2, 0, acName10F1, SDO10F1},
|
||||
{0x1600, OTYPE_RECORD, 1, 0, acName1600, SDO1600},
|
||||
{0x1601, OTYPE_RECORD, 1, 0, acName1601, SDO1601},
|
||||
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
|
||||
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
|
||||
{0x1C12, OTYPE_ARRAY, 2, 0, acName1C12, SDO1C12},
|
||||
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
|
||||
{0x1C32, OTYPE_RECORD, 32, 0, acName1C32, SDO1C32},
|
||||
{0x6005, OTYPE_RECORD, 1, 0, acName6005, SDO6005},
|
||||
{0x7005, OTYPE_RECORD, 1, 0, acName7005, SDO7005},
|
||||
{0x7006, OTYPE_RECORD, 1, 0, acName7006, SDO7006},
|
||||
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
|
||||
{0x8001, OTYPE_VAR, 0, 0, acName8001, SDO8001},
|
||||
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
|
||||
};
|
||||
#endif
|
|
@ -1,96 +0,0 @@
|
|||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
#include <cc.h>
|
||||
|
||||
/* Inputs */
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint8_t Button1;
|
||||
} CC_PACKED Buttons;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Rbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
/* Outputs */
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint8_t LED0;
|
||||
} CC_PACKED LEDgroup0;
|
||||
CC_PACKED_END
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint8_t LED1;
|
||||
} CC_PACKED LEDgroup1;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Wbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
/* Parameters */
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint32_t Multiplier;
|
||||
} CC_PACKED Parameters;
|
||||
CC_PACKED_END
|
||||
uint32_t variableRW;
|
||||
} CC_PACKED _Cbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
/* Manufacturer specific data */
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint16_t SyncType;
|
||||
uint32_t CycleTime;
|
||||
uint32_t ShiftTime;
|
||||
uint16_t SyncTypeSupport;
|
||||
uint32_t MinCycleTime;
|
||||
uint32_t CalcCopyTime;
|
||||
uint32_t MinDelayTime;
|
||||
uint16_t GetCycleTime;
|
||||
uint32_t DelayTime;
|
||||
uint32_t Sync0CycleTime;
|
||||
uint16_t SMEventMissedCnt;
|
||||
uint16_t CycleTimeTooSmallCnt;
|
||||
uint16_t ShiftTimeTooSmallCnt;
|
||||
uint16_t RxPDOToggleFailed;
|
||||
uint32_t MinCycleDist;
|
||||
uint32_t MaxCycleDist;
|
||||
uint32_t MinSMSYNCDist;
|
||||
uint32_t MaxSMSYNCDist;
|
||||
uint8_t Dummy_x14;
|
||||
uint8_t SyncError;
|
||||
} CC_PACKED SyncMgrParam;
|
||||
CC_PACKED_END
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint8_t Dummy_x01;
|
||||
uint16_t SyncErrorCounterLimit;
|
||||
} CC_PACKED ErrorSettings;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Mbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
extern _Rbuffer Rb;
|
||||
extern _Wbuffer Wb;
|
||||
extern _Cbuffer Cb;
|
||||
extern _Mbuffer Mb;
|
||||
|
||||
#endif /* __UTYPES_H__ */
|
Binary file not shown.
|
@ -0,0 +1,263 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="am335xice" productCode="0x9876">
|
||||
<Name>slave</Name>
|
||||
<Vendor>
|
||||
<Id>0x1337</Id>
|
||||
<Name>rt-labs</Name>
|
||||
</Vendor>
|
||||
<Group>
|
||||
<Type>am335xice_t</Type>
|
||||
<Name>am335xice_n</Name>
|
||||
</Group>
|
||||
<Fmmu>Outputs</Fmmu>
|
||||
<Fmmu>Inputs</Fmmu>
|
||||
<Fmmu>MBoxState</Fmmu>
|
||||
<Sm ControlByte="0x26" DefaultSize="512" StartAddress="0x1000">MBoxOut</Sm>
|
||||
<Sm ControlByte="0x22" DefaultSize="512" StartAddress="0x1200">MBoxIn</Sm>
|
||||
<Sm ControlByte="0x24" DefaultSize="0" StartAddress="0x1400">Outputs</Sm>
|
||||
<Sm ControlByte="0x20" DefaultSize="0" StartAddress="0x1A00">Inputs</Sm>
|
||||
<Mailbox CoE="true">
|
||||
<Bootstrap Length="512" Start="0x1000"/>
|
||||
<Standard Length="512" Start="0x1000"/>
|
||||
</Mailbox>
|
||||
<Eeprom>
|
||||
<ByteSize>2048</ByteSize>
|
||||
<ConfigData>8006E08800000000</ConfigData>
|
||||
<BootStrap>0010000200120002</BootStrap>
|
||||
</Eeprom>
|
||||
<Dictionary>
|
||||
<Item Managed="true">
|
||||
<Index>0x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00001389</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>am335xice</DefaultValue>
|
||||
<Length>9</Length>
|
||||
</Item>
|
||||
<Item>
|
||||
<Index>0x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
<Length>3</Length>
|
||||
</Item>
|
||||
<Item>
|
||||
<Index>0x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
<Length>3</Length>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1018</Index>
|
||||
<Name>Identity Object</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Vendor ID</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x1337</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Product Code</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x9876</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Revision Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Serial Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00000000</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1600</Index>
|
||||
<Name>LED</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>LED</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000020</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1A00</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x60000020</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1C00</Index>
|
||||
<Name>Sync Manager Communication Type</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Communications Type SM0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Communications Type SM1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Communications Type SM2</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>3</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Communications Type SM3</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1C12</Index>
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1600</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1C13</Index>
|
||||
<Name>Sync Manager 3 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1A00</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x6000</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>BUTTON</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
<Variable>BUTTON</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x7000</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>LED</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</Item>
|
||||
</Dictionary>
|
||||
<SmAssignment>
|
||||
<Index>0x1C12</Index>
|
||||
<Entry>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1600</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<SmAssignment>
|
||||
<Index>0x1C13</Index>
|
||||
<Entry>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1A00</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<RxPdo>
|
||||
<Index>0x1600</Index>
|
||||
<Name>LED</Name>
|
||||
<Entry>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x00</MappedSubIndex>
|
||||
<Variable>LED</Variable>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<TxPdo>
|
||||
<Index>0x1A00</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Entry>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x6000</MappedIndex>
|
||||
<MappedSubIndex>0x00</MappedSubIndex>
|
||||
<Variable>BUTTON</Variable>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Input>
|
||||
<Index>0x6000</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Type>UNSIGNED32</Type>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
<ObjectType>VAR</ObjectType>
|
||||
</Input>
|
||||
<Output>
|
||||
<Index>0x7000</Index>
|
||||
<Name>LED</Name>
|
||||
<Type>UNSIGNED32</Type>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<ObjectType>VAR</ObjectType>
|
||||
</Output>
|
||||
</Slave>
|
|
@ -0,0 +1,537 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<EtherCATInfo>
|
||||
<Vendor>
|
||||
<Id>#x1337</Id>
|
||||
<Name LcId="1033">rt-labs</Name>
|
||||
</Vendor>
|
||||
<Descriptions>
|
||||
<Groups>
|
||||
<Group>
|
||||
<Type>am335xice_t</Type>
|
||||
<Name LcId="1033">am335xice_n</Name>
|
||||
</Group>
|
||||
</Groups>
|
||||
<Devices>
|
||||
<Device Physics="YY">
|
||||
<Type ProductCode="#x9876" RevisionNo="0">am335xice</Type>
|
||||
<Name LcId="1033">slave</Name>
|
||||
<GroupType>am335xice_t</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>LED</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>BUTTON</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>16</BitSize>
|
||||
<ArrayInfo>
|
||||
<LBound>1</LBound>
|
||||
<Elements>1</Elements>
|
||||
</ArrayInfo>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C12</Name>
|
||||
<BitSize>32</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>16</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C13ARR</Name>
|
||||
<BaseType>UINT</BaseType>
|
||||
<BitSize>16</BitSize>
|
||||
<ArrayInfo>
|
||||
<LBound>1</LBound>
|
||||
<Elements>1</Elements>
|
||||
</ArrayInfo>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C13</Name>
|
||||
<BitSize>32</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>16</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(3)</Name>
|
||||
<BitSize>24</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>UDINT</Name>
|
||||
<BitSize>32</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>UINT</Name>
|
||||
<BitSize>16</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>USINT</Name>
|
||||
<BitSize>8</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(9)</Name>
|
||||
<BitSize>72</BitSize>
|
||||
</DataType>
|
||||
</DataTypes>
|
||||
<Objects>
|
||||
<Object>
|
||||
<Index>#x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultValue>#x00001389</DefaultValue>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<Category>m</Category>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<Type>STRING(9)</Type>
|
||||
<BitSize>72</BitSize>
|
||||
<Info>
|
||||
<DefaultString>am335xice</DefaultString>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</DefaultString>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<Category>o</Category>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</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>#x1337</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Product Code</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x9876</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Revision Number</Name>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Serial Number</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x00000000</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1600</Index>
|
||||
<Name>LED</Name>
|
||||
<Type>DT1600</Type>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x70000020</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1A00</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Type>DT1A00</Type>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>BUTTON</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x60000020</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>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>PDO Mapping</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x1600</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>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>PDO Mapping</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x1A00</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x6000</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<PdoMapping>T</PdoMapping>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x7000</Index>
|
||||
<Name>LED</Name>
|
||||
<Type>UDINT</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 ControlByte="#x26" DefaultSize="512" Enable="1" StartAddress="#x1000">MBoxOut</Sm>
|
||||
<Sm ControlByte="#x22" DefaultSize="512" Enable="1" StartAddress="#x1200">MBoxIn</Sm>
|
||||
<Sm ControlByte="#x24" Enable="1" StartAddress="#x1400">Outputs</Sm>
|
||||
<Sm ControlByte="#x20" Enable="1" StartAddress="#x1A00">Inputs</Sm>
|
||||
<RxPdo Fixed="true" Mandatory="true" Sm="2">
|
||||
<Index>#x1600</Index>
|
||||
<Name>LED</Name>
|
||||
<Entry>
|
||||
<Index>#x7000</Index>
|
||||
<SubIndex>#x0</SubIndex>
|
||||
<BitLen>32</BitLen>
|
||||
<Name>LED</Name>
|
||||
<DataType>UDINT</DataType>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<TxPdo Fixed="true" Mandatory="true" Sm="3">
|
||||
<Index>#x1A00</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>#x0</SubIndex>
|
||||
<BitLen>32</BitLen>
|
||||
<Name>BUTTON</Name>
|
||||
<DataType>UDINT</DataType>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Mailbox DataLinkLayer="true">
|
||||
<CoE CompleteAccess="false" PdoUpload="false" SdoInfo="true"/>
|
||||
</Mailbox>
|
||||
<Eeprom>
|
||||
<ByteSize>2048</ByteSize>
|
||||
<ConfigData>8006E08800000000</ConfigData>
|
||||
<BootStrap>0010000200120002</BootStrap>
|
||||
</Eeprom>
|
||||
</Device>
|
||||
</Devices>
|
||||
</Descriptions>
|
||||
</EtherCATInfo>
|
|
@ -0,0 +1,120 @@
|
|||
#include "esc_coe.h"
|
||||
#include "utypes.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef HW_REV
|
||||
#define HW_REV "1.0"
|
||||
#endif
|
||||
|
||||
#ifndef SW_REV
|
||||
#define SW_REV "1.0"
|
||||
#endif
|
||||
|
||||
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[] = "LED";
|
||||
static const char acName1600_00[] = "Max SubIndex";
|
||||
static const char acName1600_01[] = "LED";
|
||||
static const char acName1A00[] = "BUTTON";
|
||||
static const char acName1A00_00[] = "Max SubIndex";
|
||||
static const char acName1A00_01[] = "BUTTON";
|
||||
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 acName1C13[] = "Sync Manager 3 PDO Assignment";
|
||||
static const char acName1C13_00[] = "Max SubIndex";
|
||||
static const char acName1C13_01[] = "PDO Mapping";
|
||||
static const char acName6000[] = "BUTTON";
|
||||
static const char acName7000[] = "LED";
|
||||
|
||||
const _objd SDO1000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x00001389, NULL},
|
||||
};
|
||||
const _objd SDO1008[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 72, ATYPE_RO, acName1008, 0, "am335xice"},
|
||||
};
|
||||
const _objd SDO1009[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009, 0, HW_REV},
|
||||
};
|
||||
const _objd SDO100A[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A, 0, SW_REV},
|
||||
};
|
||||
const _objd SDO1018[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x9876, NULL},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
|
||||
};
|
||||
const _objd SDO1600[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000020, 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 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, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
|
||||
};
|
||||
const _objd SDO1C13[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL},
|
||||
};
|
||||
const _objd SDO6000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_TXPDO, acName6000, 0, &Obj.BUTTON},
|
||||
};
|
||||
const _objd SDO7000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_RXPDO, acName7000, 0, &Obj.LED},
|
||||
};
|
||||
|
||||
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},
|
||||
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
|
||||
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
|
||||
{0x1C12, OTYPE_ARRAY, 1, 0, acName1C12, SDO1C12},
|
||||
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
|
||||
{0x6000, OTYPE_VAR, 0, 0, acName6000, SDO6000},
|
||||
{0x7000, OTYPE_VAR, 0, 0, acName7000, SDO7000},
|
||||
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
|
||||
};
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef __ECAT_OPTIONS_H__
|
||||
#define __ECAT_OPTIONS_H__
|
||||
|
||||
#include "cc.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 0x1400
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1A00
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#define MAX_RXPDO_SIZE 512
|
||||
#define MAX_TXPDO_SIZE 512
|
||||
|
||||
#define MAX_MAPPINGS_SM2 1
|
||||
#define MAX_MAPPINGS_SM3 1
|
||||
|
||||
#endif /* __ECAT_OPTIONS_H__ */
|
|
@ -0,0 +1,85 @@
|
|||
#include "esc_hw.h"
|
||||
#include "ecat_slv.h"
|
||||
#include "options.h"
|
||||
#include "utypes.h"
|
||||
#include <string.h>
|
||||
#include "tiescutils.h"
|
||||
#include <examples/board/include/board_i2cLed.h>
|
||||
#include <examples/board/include/board_rotary_switch.h>
|
||||
|
||||
#if 1
|
||||
/* Application variables */
|
||||
_Objects Obj;
|
||||
|
||||
/**
|
||||
* This function reads physical input values and assigns the corresponding members
|
||||
* of Rb.Buttons
|
||||
*/
|
||||
void cb_get_inputs()
|
||||
{
|
||||
volatile uint8_t io_input;
|
||||
Board_readRotarySwitch((uint8_t *)&io_input);
|
||||
Obj.BUTTON = io_input;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members of
|
||||
* Wb.LEDs
|
||||
*/
|
||||
void cb_set_outputs()
|
||||
{
|
||||
volatile uint8_t io_output;
|
||||
io_output = Obj.LED;
|
||||
Board_setDigOutput(io_output);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Called from stack when stopping outputs */
|
||||
void user_safeoutput (void)
|
||||
{
|
||||
memset(&Obj.LED, 0, (sizeof(Obj.LED)));
|
||||
Board_setDigOutput(0);
|
||||
}
|
||||
|
||||
/* Configuration parameters for SOES
|
||||
* SM and Mailbox parameters comes from the
|
||||
* generated config.h
|
||||
*/
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = NULL,
|
||||
.use_interrupt = 1,
|
||||
.watchdog_cnt = 9998,
|
||||
.set_defaults_hook = NULL,
|
||||
.pre_state_change_hook = NULL,
|
||||
.post_state_change_hook = NULL,
|
||||
.application_hook = NULL,
|
||||
.safeoutput_override = user_safeoutput,
|
||||
.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 = ESC_eep_handler,
|
||||
.esc_check_dc_handler = NULL
|
||||
};
|
||||
|
||||
int MainInit(void)
|
||||
{
|
||||
ecat_slv_init(&config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MainLoop(void)
|
||||
{
|
||||
ecat_slv_poll();
|
||||
DIG_process(DIG_PROCESS_WD_FLAG);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
common_main();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
#include "cc.h"
|
||||
|
||||
|
||||
/* Object dictionary storage */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Inputs */
|
||||
uint32_t BUTTON;
|
||||
|
||||
/* Outputs */
|
||||
uint32_t LED;
|
||||
|
||||
/* Parameters */
|
||||
|
||||
/* Manufacturer specific data */
|
||||
|
||||
/* Dynamic TX PDO:s */
|
||||
|
||||
/* Dynamic RX PDO:s */
|
||||
|
||||
/* Sync Managers */
|
||||
|
||||
} _Objects;
|
||||
|
||||
extern _Objects Obj;
|
||||
|
||||
#endif /* __UTYPES_H__ */
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef __ECAT_OPTIONS_H__
|
||||
#define __ECAT_OPTIONS_H__
|
||||
|
||||
#include "cc.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 0x1400
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1A00
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#define MAX_RXPDO_SIZE 512
|
||||
#define MAX_TXPDO_SIZE 512
|
||||
|
||||
#define MAX_MAPPINGS_SM2 1
|
||||
#define MAX_MAPPINGS_SM3 1
|
||||
|
||||
#endif /* __ECAT_OPTIONS_H__ */
|
Binary file not shown.
|
@ -0,0 +1,263 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="k2gice" productCode="0x4291ce">
|
||||
<Name>k2gice_n</Name>
|
||||
<Vendor>
|
||||
<Id>0x1337</Id>
|
||||
<Name>rt-labs</Name>
|
||||
</Vendor>
|
||||
<Group>
|
||||
<Type>k2gice_t</Type>
|
||||
<Name>am335xice_n</Name>
|
||||
</Group>
|
||||
<Fmmu>Outputs</Fmmu>
|
||||
<Fmmu>Inputs</Fmmu>
|
||||
<Fmmu>MBoxState</Fmmu>
|
||||
<Sm ControlByte="0x26" DefaultSize="512" StartAddress="0x1000">MBoxOut</Sm>
|
||||
<Sm ControlByte="0x22" DefaultSize="512" StartAddress="0x1200">MBoxIn</Sm>
|
||||
<Sm ControlByte="0x24" DefaultSize="0" StartAddress="0x1400">Outputs</Sm>
|
||||
<Sm ControlByte="0x20" DefaultSize="0" StartAddress="0x1A00">Inputs</Sm>
|
||||
<Mailbox CoE="true">
|
||||
<Bootstrap Length="512" Start="0x1000"/>
|
||||
<Standard Length="512" Start="0x1000"/>
|
||||
</Mailbox>
|
||||
<Eeprom>
|
||||
<ByteSize>2048</ByteSize>
|
||||
<ConfigData>800CE08800000000</ConfigData>
|
||||
<BootStrap>0010000200120002</BootStrap>
|
||||
</Eeprom>
|
||||
<Dictionary>
|
||||
<Item Managed="true">
|
||||
<Index>0x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00001389</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>k2gice</DefaultValue>
|
||||
<Length>6</Length>
|
||||
</Item>
|
||||
<Item>
|
||||
<Index>0x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
<Length>3</Length>
|
||||
</Item>
|
||||
<Item>
|
||||
<Index>0x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
<Length>3</Length>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1018</Index>
|
||||
<Name>Identity Object</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Vendor ID</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x1337</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Product Code</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x4291ce</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Revision Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Serial Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00000000</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1600</Index>
|
||||
<Name>LED</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>LED</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000020</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1A00</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x60000020</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1C00</Index>
|
||||
<Name>Sync Manager Communication Type</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>Communications Type SM0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x02</Index>
|
||||
<Name>Communications Type SM1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x03</Index>
|
||||
<Name>Communications Type SM2</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>3</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x04</Index>
|
||||
<Name>Communications Type SM3</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1C12</Index>
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1600</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x1C13</Index>
|
||||
<Name>Sync Manager 3 PDO Assignment</Name>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Index>0x00</Index>
|
||||
<Name>Max SubIndex</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Index>0x01</Index>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1A00</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x6000</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>BUTTON</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
<Variable>BUTTON</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Index>0x7000</Index>
|
||||
<Access>RO</Access>
|
||||
<Name>LED</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<Variable>LED</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</Item>
|
||||
</Dictionary>
|
||||
<SmAssignment>
|
||||
<Index>0x1C12</Index>
|
||||
<Entry>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1600</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<SmAssignment>
|
||||
<Index>0x1C13</Index>
|
||||
<Entry>
|
||||
<Index>0x01</Index>
|
||||
<AssignedPdo>0x1A00</AssignedPdo>
|
||||
</Entry>
|
||||
</SmAssignment>
|
||||
<RxPdo>
|
||||
<Index>0x1600</Index>
|
||||
<Name>LED</Name>
|
||||
<Entry>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x7000</MappedIndex>
|
||||
<MappedSubIndex>0x00</MappedSubIndex>
|
||||
<Variable>LED</Variable>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<TxPdo>
|
||||
<Index>0x1A00</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Entry>
|
||||
<Index>0x1</Index>
|
||||
<MappedIndex>0x6000</MappedIndex>
|
||||
<MappedSubIndex>0x00</MappedSubIndex>
|
||||
<Variable>BUTTON</Variable>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Input>
|
||||
<Index>0x6000</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Type>UNSIGNED32</Type>
|
||||
<PdoMapping>TX</PdoMapping>
|
||||
<ObjectType>VAR</ObjectType>
|
||||
</Input>
|
||||
<Output>
|
||||
<Index>0x7000</Index>
|
||||
<Name>LED</Name>
|
||||
<Type>UNSIGNED32</Type>
|
||||
<PdoMapping>RX</PdoMapping>
|
||||
<ObjectType>VAR</ObjectType>
|
||||
</Output>
|
||||
</Slave>
|
|
@ -0,0 +1,537 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<EtherCATInfo>
|
||||
<Vendor>
|
||||
<Id>#x1337</Id>
|
||||
<Name LcId="1033">rt-labs</Name>
|
||||
</Vendor>
|
||||
<Descriptions>
|
||||
<Groups>
|
||||
<Group>
|
||||
<Type>k2gice_t</Type>
|
||||
<Name LcId="1033">am335xice_n</Name>
|
||||
</Group>
|
||||
</Groups>
|
||||
<Devices>
|
||||
<Device Physics="YY">
|
||||
<Type ProductCode="#x4291ce" RevisionNo="0">k2gice</Type>
|
||||
<Name LcId="1033">k2gice_n</Name>
|
||||
<GroupType>k2gice_t</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>LED</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>BUTTON</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>16</BitSize>
|
||||
<ArrayInfo>
|
||||
<LBound>1</LBound>
|
||||
<Elements>1</Elements>
|
||||
</ArrayInfo>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C12</Name>
|
||||
<BitSize>32</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>16</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C13ARR</Name>
|
||||
<BaseType>UINT</BaseType>
|
||||
<BitSize>16</BitSize>
|
||||
<ArrayInfo>
|
||||
<LBound>1</LBound>
|
||||
<Elements>1</Elements>
|
||||
</ArrayInfo>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C13</Name>
|
||||
<BitSize>32</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>16</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(6)</Name>
|
||||
<BitSize>48</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(3)</Name>
|
||||
<BitSize>24</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>UDINT</Name>
|
||||
<BitSize>32</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>UINT</Name>
|
||||
<BitSize>16</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>USINT</Name>
|
||||
<BitSize>8</BitSize>
|
||||
</DataType>
|
||||
</DataTypes>
|
||||
<Objects>
|
||||
<Object>
|
||||
<Index>#x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultValue>#x00001389</DefaultValue>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<Category>m</Category>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<Type>STRING(6)</Type>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<DefaultString>k2gice</DefaultString>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</DefaultString>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<Category>o</Category>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</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>#x1337</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Product Code</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x4291ce</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Revision Number</Name>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Serial Number</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x00000000</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1600</Index>
|
||||
<Name>LED</Name>
|
||||
<Type>DT1600</Type>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x70000020</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1A00</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Type>DT1A00</Type>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>BUTTON</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x60000020</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>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>PDO Mapping</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x1600</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>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Max SubIndex</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>PDO Mapping</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x1A00</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x6000</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<PdoMapping>T</PdoMapping>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x7000</Index>
|
||||
<Name>LED</Name>
|
||||
<Type>UDINT</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 ControlByte="#x26" DefaultSize="512" Enable="1" StartAddress="#x1000">MBoxOut</Sm>
|
||||
<Sm ControlByte="#x22" DefaultSize="512" Enable="1" StartAddress="#x1200">MBoxIn</Sm>
|
||||
<Sm ControlByte="#x24" Enable="1" StartAddress="#x1400">Outputs</Sm>
|
||||
<Sm ControlByte="#x20" Enable="1" StartAddress="#x1A00">Inputs</Sm>
|
||||
<RxPdo Fixed="true" Mandatory="true" Sm="2">
|
||||
<Index>#x1600</Index>
|
||||
<Name>LED</Name>
|
||||
<Entry>
|
||||
<Index>#x7000</Index>
|
||||
<SubIndex>#x0</SubIndex>
|
||||
<BitLen>32</BitLen>
|
||||
<Name>LED</Name>
|
||||
<DataType>UDINT</DataType>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<TxPdo Fixed="true" Mandatory="true" Sm="3">
|
||||
<Index>#x1A00</Index>
|
||||
<Name>BUTTON</Name>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>#x0</SubIndex>
|
||||
<BitLen>32</BitLen>
|
||||
<Name>BUTTON</Name>
|
||||
<DataType>UDINT</DataType>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Mailbox DataLinkLayer="true">
|
||||
<CoE CompleteAccess="false" PdoUpload="false" SdoInfo="true"/>
|
||||
</Mailbox>
|
||||
<Eeprom>
|
||||
<ByteSize>2048</ByteSize>
|
||||
<ConfigData>800EE08800000000</ConfigData>
|
||||
<BootStrap>0010000200120002</BootStrap>
|
||||
</Eeprom>
|
||||
</Device>
|
||||
</Devices>
|
||||
</Descriptions>
|
||||
</EtherCATInfo>
|
|
@ -0,0 +1,120 @@
|
|||
#include "esc_coe.h"
|
||||
#include "utypes.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef HW_REV
|
||||
#define HW_REV "1.0"
|
||||
#endif
|
||||
|
||||
#ifndef SW_REV
|
||||
#define SW_REV "1.0"
|
||||
#endif
|
||||
|
||||
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[] = "LED";
|
||||
static const char acName1600_00[] = "Max SubIndex";
|
||||
static const char acName1600_01[] = "LED";
|
||||
static const char acName1A00[] = "BUTTON";
|
||||
static const char acName1A00_00[] = "Max SubIndex";
|
||||
static const char acName1A00_01[] = "BUTTON";
|
||||
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 acName1C13[] = "Sync Manager 3 PDO Assignment";
|
||||
static const char acName1C13_00[] = "Max SubIndex";
|
||||
static const char acName1C13_01[] = "PDO Mapping";
|
||||
static const char acName6000[] = "BUTTON";
|
||||
static const char acName7000[] = "LED";
|
||||
|
||||
const _objd SDO1000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x00001389, NULL},
|
||||
};
|
||||
const _objd SDO1008[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 48, ATYPE_RO, acName1008, 0, "k2gice"},
|
||||
};
|
||||
const _objd SDO1009[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009, 0, HW_REV},
|
||||
};
|
||||
const _objd SDO100A[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A, 0, SW_REV},
|
||||
};
|
||||
const _objd SDO1018[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x4291ce, NULL},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
|
||||
};
|
||||
const _objd SDO1600[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000020, 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 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, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
|
||||
};
|
||||
const _objd SDO1C13[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL},
|
||||
};
|
||||
const _objd SDO6000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_TXPDO, acName6000, 0, &Obj.BUTTON},
|
||||
};
|
||||
const _objd SDO7000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_RXPDO, acName7000, 0, &Obj.LED},
|
||||
};
|
||||
|
||||
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},
|
||||
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
|
||||
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
|
||||
{0x1C12, OTYPE_ARRAY, 1, 0, acName1C12, SDO1C12},
|
||||
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
|
||||
{0x6000, OTYPE_VAR, 0, 0, acName6000, SDO6000},
|
||||
{0x7000, OTYPE_VAR, 0, 0, acName7000, SDO7000},
|
||||
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
|
||||
};
|
|
@ -0,0 +1,80 @@
|
|||
#include "esc_hw.h"
|
||||
#include "ecat_slv.h"
|
||||
#include "options.h"
|
||||
#include "utypes.h"
|
||||
#include <string.h>
|
||||
#include "tiescutils.h"
|
||||
#include <examples/board/include/board_i2cLed.h>
|
||||
#include <examples/board/include/board_rotary_switch.h>
|
||||
|
||||
/* Application variables */
|
||||
_Objects Obj;
|
||||
|
||||
/**
|
||||
* This function reads physical input values and assigns the corresponding members
|
||||
*/
|
||||
void cb_get_inputs()
|
||||
{
|
||||
volatile uint8_t io_input;
|
||||
Board_readRotarySwitch((uint8_t *)&io_input);
|
||||
Obj.BUTTON = io_input;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members
|
||||
*/
|
||||
void cb_set_outputs()
|
||||
{
|
||||
volatile uint8_t io_output;
|
||||
io_output = Obj.LED;
|
||||
Board_setDigOutput(io_output);
|
||||
}
|
||||
|
||||
/* Called from stack when stopping outputs */
|
||||
void user_safeoutput (void)
|
||||
{
|
||||
memset(&Obj.LED, 0, (sizeof(Obj.LED)));
|
||||
Board_setDigOutput(0);
|
||||
}
|
||||
|
||||
/* Configuration parameters for SOES
|
||||
* SM and Mailbox parameters comes from the
|
||||
* generated config.h
|
||||
*/
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = NULL,
|
||||
.use_interrupt = 1,
|
||||
.watchdog_cnt = 9998,
|
||||
.set_defaults_hook = NULL,
|
||||
.pre_state_change_hook = NULL,
|
||||
.post_state_change_hook = NULL,
|
||||
.application_hook = NULL,
|
||||
.safeoutput_override = user_safeoutput,
|
||||
.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 = ESC_eep_handler,
|
||||
.esc_check_dc_handler = NULL
|
||||
};
|
||||
|
||||
int MainInit(void)
|
||||
{
|
||||
ecat_slv_init(&config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MainLoop(void)
|
||||
{
|
||||
ecat_slv_poll();
|
||||
DIG_process(DIG_PROCESS_WD_FLAG);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
common_main();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
#include "cc.h"
|
||||
|
||||
|
||||
/* Object dictionary storage */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Inputs */
|
||||
uint32_t BUTTON;
|
||||
|
||||
/* Outputs */
|
||||
uint32_t LED;
|
||||
|
||||
/* Parameters */
|
||||
|
||||
/* Manufacturer specific data */
|
||||
|
||||
/* Dynamic TX PDO:s */
|
||||
|
||||
/* Dynamic RX PDO:s */
|
||||
|
||||
/* Sync Managers */
|
||||
|
||||
} _Objects;
|
||||
|
||||
extern _Objects Obj;
|
||||
|
||||
#endif /* __UTYPES_H__ */
|
|
@ -13,7 +13,7 @@ SOES_DIR = ../../soes
|
|||
SRC = \
|
||||
main.c \
|
||||
objectlist.c \
|
||||
soes.c \
|
||||
$(SOES_DIR)/ecat_slv.c \
|
||||
$(SOES_DIR)/esc.c \
|
||||
$(SOES_DIR)/esc_coe.c \
|
||||
$(SOES_DIR)/esc_eep.c \
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef __ECAT_OPTIONS_H__
|
||||
#define __ECAT_OPTIONS_H__
|
||||
|
||||
#include "cc.h"
|
||||
|
||||
#define USE_FOE 0
|
||||
#define USE_EOE 0
|
||||
|
||||
#define MBXSIZE 128
|
||||
#define MBXSIZEBOOT 128
|
||||
#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 0x1100
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1180
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#define MAX_RXPDO_SIZE 42
|
||||
#define MAX_TXPDO_SIZE 42
|
||||
|
||||
#define MAX_MAPPINGS_SM2 0
|
||||
#define MAX_MAPPINGS_SM3 0
|
||||
|
||||
#endif /* __ECAT_OPTIONS_H__ */
|
|
@ -1,15 +1,136 @@
|
|||
#include <string.h>
|
||||
/*
|
||||
* Licensed under the GNU General Public License version 2 with exceptions. See
|
||||
* LICENSE file in the project root for full license information
|
||||
*/
|
||||
|
||||
#include "ecat_slv.h"
|
||||
#include "utypes.h"
|
||||
#include "xmc_gpio.h"
|
||||
|
||||
#include "soes.h"
|
||||
#ifdef XMC4800_F144x2048
|
||||
#define P_LED P5_8
|
||||
#define P_BTN P15_12
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
#ifdef XMC4300_F100x256
|
||||
#define P_LED P4_1
|
||||
#define P_BTN P3_4
|
||||
#endif
|
||||
|
||||
extern void ESC_eep_handler(void);
|
||||
|
||||
/* Application variables */
|
||||
_Rbuffer Rb;
|
||||
_Wbuffer Wb;
|
||||
_Cbuffer Cb;
|
||||
|
||||
uint8_t * rxpdo = (uint8_t *)&Wb.LED;
|
||||
uint8_t * txpdo = (uint8_t *)&Rb.button;
|
||||
|
||||
uint32_t encoder_scale;
|
||||
uint32_t encoder_scale_mirror;
|
||||
|
||||
static const XMC_GPIO_CONFIG_t gpio_config_btn = {
|
||||
.mode = XMC_GPIO_MODE_INPUT_INVERTED_PULL_UP,
|
||||
.output_level = 0,
|
||||
.output_strength = 0
|
||||
};
|
||||
|
||||
static const XMC_GPIO_CONFIG_t gpio_config_led = {
|
||||
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL,
|
||||
.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW,
|
||||
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_SOFT_EDGE
|
||||
};
|
||||
|
||||
void cb_get_inputs (void)
|
||||
{
|
||||
soes_init();
|
||||
|
||||
while(1) {
|
||||
soes_task();
|
||||
}
|
||||
Rb.button = XMC_GPIO_GetInput(P_BTN);
|
||||
Cb.reset_counter++;
|
||||
Rb.encoder = ESCvar.Time;
|
||||
}
|
||||
|
||||
void cb_set_outputs (void)
|
||||
{
|
||||
if (Wb.LED)
|
||||
{
|
||||
XMC_GPIO_SetOutputHigh(P_LED);
|
||||
}
|
||||
else
|
||||
{
|
||||
XMC_GPIO_SetOutputLow(P_LED);
|
||||
}
|
||||
}
|
||||
|
||||
void post_object_download_hook (uint16_t index, uint8_t subindex,
|
||||
uint16_t flags)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0x7100:
|
||||
{
|
||||
switch (subindex)
|
||||
{
|
||||
case 0x01:
|
||||
{
|
||||
encoder_scale_mirror = encoder_scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x8001:
|
||||
{
|
||||
switch (subindex)
|
||||
{
|
||||
case 0x01:
|
||||
{
|
||||
Cb.reset_counter = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void soes (void * arg)
|
||||
{
|
||||
/* Setup config hooks */
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = NULL,
|
||||
.use_interrupt = 0,
|
||||
.watchdog_cnt = 5000,
|
||||
.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 = post_object_download_hook,
|
||||
.rxpdo_override = NULL,
|
||||
.txpdo_override = NULL,
|
||||
.esc_hw_interrupt_enable = NULL,
|
||||
.esc_hw_interrupt_disable = NULL,
|
||||
.esc_hw_eep_handler = ESC_eep_handler
|
||||
};
|
||||
|
||||
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
|
||||
|
||||
// configure I/O
|
||||
XMC_GPIO_Init(P_BTN, &gpio_config_btn);
|
||||
XMC_GPIO_Init(P_LED, &gpio_config_led);
|
||||
|
||||
ecat_slv_init (&config);
|
||||
|
||||
while (1)
|
||||
{
|
||||
ecat_slv();
|
||||
}
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
soes (NULL);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,318 +0,0 @@
|
|||
/*
|
||||
* Licensed under the GNU General Public License version 2 with exceptions. See
|
||||
* LICENSE file in the project root for full license information
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief
|
||||
* The application.
|
||||
*
|
||||
* The application, the main loop that service EtherCAT.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "esc.h"
|
||||
#include "esc_coe.h"
|
||||
#include "esc_eep.h"
|
||||
#include "esc_hw_eep.h"
|
||||
|
||||
#include "utypes.h"
|
||||
#include "soes.h"
|
||||
|
||||
#define WD_RESET 1000
|
||||
#define DEFAULTTXPDOMAP 0x1a00
|
||||
#define DEFAULTRXPDOMAP 0x1600
|
||||
#define DEFAULTTXPDOITEMS 1
|
||||
#define DEFAULTRXPDOITEMS 1
|
||||
|
||||
static const XMC_GPIO_CONFIG_t gpio_config_btn = {
|
||||
.mode = XMC_GPIO_MODE_INPUT_INVERTED_PULL_UP,
|
||||
.output_level = 0,
|
||||
.output_strength = 0
|
||||
};
|
||||
|
||||
static const XMC_GPIO_CONFIG_t gpio_config_led = {
|
||||
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL,
|
||||
.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW,
|
||||
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_SOFT_EDGE
|
||||
};
|
||||
|
||||
uint32_t encoder_scale;
|
||||
uint32_t encoder_scale_mirror;
|
||||
|
||||
/* Global variables used by the stack */
|
||||
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
|
||||
_MBXcontrol MBXcontrol[MBXBUFFERS];
|
||||
_ESCvar ESCvar;
|
||||
|
||||
/* Application variables */
|
||||
_Rbuffer Rb;
|
||||
_Wbuffer Wb;
|
||||
_Cbuffer Cb;
|
||||
|
||||
/* Private variables */
|
||||
volatile uint8_t digoutput;
|
||||
volatile uint8_t diginput;
|
||||
uint16_t txpdomap = DEFAULTTXPDOMAP;
|
||||
uint16_t rxpdomap = DEFAULTRXPDOMAP;
|
||||
uint8_t txpdoitems = DEFAULTTXPDOITEMS;
|
||||
uint8_t rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
|
||||
|
||||
/** 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 1 if the SDO Download is correct. 0 If not correct.
|
||||
*/
|
||||
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
if ((index == 0x1c12) && (subindex > 0) && (rxpdoitems != 0))
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
if ((index == 0x1c13) && (subindex > 0) && (txpdoitems != 0))
|
||||
{
|
||||
SDO_abort (index, subindex, ABORT_READONLY);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Mandatory: 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
|
||||
*/
|
||||
void ESC_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0x1c12:
|
||||
{
|
||||
if (rxpdoitems > 1)
|
||||
{
|
||||
rxpdoitems = 1;
|
||||
}
|
||||
if ((rxpdomap != 0x1600) && (rxpdomap != 0x1601)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
rxpdomap = 0x1600;
|
||||
}
|
||||
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
|
||||
break;
|
||||
}
|
||||
case 0x1c13:
|
||||
{
|
||||
if (txpdoitems > 1)
|
||||
{
|
||||
txpdoitems = 1;
|
||||
}
|
||||
if ((txpdomap != 0x1A00) && (txpdomap != 0x1A01)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
txpdomap = 0x1A00;
|
||||
}
|
||||
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
|
||||
break;
|
||||
}
|
||||
case 0x7100:
|
||||
{
|
||||
switch (subindex)
|
||||
{
|
||||
case 0x01:
|
||||
{
|
||||
encoder_scale_mirror = encoder_scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x8001:
|
||||
{
|
||||
switch (subindex)
|
||||
{
|
||||
case 0x01:
|
||||
{
|
||||
Cb.reset_counter = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Mandatory: 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.
|
||||
* set
|
||||
*/
|
||||
void APP_safeoutput (void)
|
||||
{
|
||||
DPRINT ("APP_safeoutput called\n");
|
||||
Wb.LED = 0;
|
||||
}
|
||||
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
|
||||
*/
|
||||
void TXPDO_update (void)
|
||||
{
|
||||
ESC_write (SM3_sma, &Rb.button, ESCvar.TXPDOsize);
|
||||
}
|
||||
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
|
||||
*/
|
||||
void RXPDO_update (void)
|
||||
{
|
||||
ESC_read (SM2_sma, &Wb.LED, ESCvar.RXPDOsize);
|
||||
}
|
||||
|
||||
/** Mandatory: 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 (void)
|
||||
{
|
||||
if (wd_cnt)
|
||||
{
|
||||
wd_cnt--;
|
||||
}
|
||||
if (ESCvar.App.state & APPSTATE_OUTPUT)
|
||||
{
|
||||
/* SM2 trigger ? */
|
||||
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
|
||||
{
|
||||
ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2;
|
||||
RXPDO_update ();
|
||||
wd_cnt = WD_RESET;
|
||||
/* dummy output point */
|
||||
if (Wb.LED) {
|
||||
XMC_GPIO_SetOutputHigh(P_LED);
|
||||
} else {
|
||||
XMC_GPIO_SetOutputLow(P_LED);
|
||||
}
|
||||
}
|
||||
if (!wd_cnt)
|
||||
{
|
||||
DPRINT("DIG_process watchdog tripped\n");
|
||||
ESC_stopoutput ();
|
||||
/* watchdog, invalid outputs */
|
||||
ESC_ALerror (ALERR_WATCHDOG);
|
||||
/* goto safe-op with error bit set */
|
||||
ESC_ALstatus (ESCsafeop | ESCerror);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wd_cnt = WD_RESET;
|
||||
}
|
||||
if (ESCvar.App.state)
|
||||
{
|
||||
Rb.button = XMC_GPIO_GetInput(P_BTN);
|
||||
Cb.reset_counter++;
|
||||
Rb.encoder = ESCvar.Time;
|
||||
TXPDO_update ();
|
||||
}
|
||||
}
|
||||
|
||||
/** SOES main loop. Start by initializing the stack software followed by
|
||||
* the application loop for cyclic read the EtherCAT state and staus, update
|
||||
* of I/O.
|
||||
*/
|
||||
void soes_init (void)
|
||||
{
|
||||
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
|
||||
|
||||
ESC_reset();
|
||||
|
||||
// configure I/O
|
||||
XMC_GPIO_Init(P_BTN, &gpio_config_btn);
|
||||
XMC_GPIO_Init(P_LED, &gpio_config_led);
|
||||
|
||||
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
|
||||
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
|
||||
|
||||
/* Setup config hooks */
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.user_arg = NULL,
|
||||
.use_interrupt = 0,
|
||||
.watchdog_cnt = 0,
|
||||
.mbxsize = MBXSIZE,
|
||||
.mbxsizeboot = MBXSIZEBOOT,
|
||||
.mbxbuffers = MBXBUFFERS,
|
||||
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
|
||||
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
|
||||
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
|
||||
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
|
||||
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
|
||||
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
|
||||
.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 = NULL,
|
||||
.esc_hw_interrupt_disable = NULL,
|
||||
.esc_hw_eep_handler = NULL
|
||||
};
|
||||
|
||||
ESC_config (&config);
|
||||
ESC_init (NULL);
|
||||
|
||||
/* wait until ESC is started up */
|
||||
do {
|
||||
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
|
||||
sizeof (ESCvar.DLstatus));
|
||||
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
|
||||
} while ((ESCvar.DLstatus & 0x0001) == 0);
|
||||
|
||||
/* reset ESC to init state */
|
||||
ESC_ALstatus (ESCinit);
|
||||
ESC_ALerror (ALERR_NONE);
|
||||
ESC_stopmbx ();
|
||||
ESC_stopinput ();
|
||||
ESC_stopoutput ();
|
||||
}
|
||||
|
||||
void soes_task (void)
|
||||
{
|
||||
/* On init restore PDO mappings to default size */
|
||||
if((ESCvar.ALstatus & 0x0f) == ESCinit)
|
||||
{
|
||||
txpdomap = DEFAULTTXPDOMAP;
|
||||
rxpdomap = DEFAULTRXPDOMAP;
|
||||
txpdoitems = DEFAULTTXPDOITEMS;
|
||||
rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
}
|
||||
/* 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();
|
||||
|
||||
/* If else to two separate execution paths
|
||||
* If we're running BOOSTRAP
|
||||
* - MailBox
|
||||
* - FoE
|
||||
* Else we're running normal execution
|
||||
* - MailBox
|
||||
* - CoE
|
||||
*/
|
||||
if (ESC_mbxprocess ())
|
||||
{
|
||||
ESC_coeprocess ();
|
||||
ESC_xoeprocess ();
|
||||
}
|
||||
DIG_process ();
|
||||
EEP_process ();
|
||||
EEP_hw_process();
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef _SOES_H_
|
||||
#define _SOES_H_
|
||||
|
||||
#include <xmc_gpio.h>
|
||||
#include <xmc_scu.h>
|
||||
|
||||
#define P_LED P4_1
|
||||
#define P_BTN P3_4
|
||||
|
||||
extern void soes_init (void);
|
||||
extern void soes_task (void);
|
||||
|
||||
#endif
|
||||
|
|
@ -16,21 +16,27 @@
|
|||
|
||||
#include <cc.h>
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
uint8_t state;
|
||||
uint8_t button;
|
||||
uint32_t encoder;
|
||||
} _Rbuffer;
|
||||
}CC_PACKED _Rbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
uint8_t LED;
|
||||
} _Wbuffer;
|
||||
}CC_PACKED _Wbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
uint32_t reset_counter;
|
||||
} _Cbuffer;
|
||||
}CC_PACKED _Cbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
|
||||
set(SOES_DEMO applications/linux_lan9252demo)
|
||||
if(RPI_VARIANT)
|
||||
set (SOES_DEMO applications/raspberry_lan9252demo)
|
||||
set(HAL_SOURCES
|
||||
${SOES_SOURCE_DIR}/soes/hal/raspberrypi-lan9252/esc_hw.c
|
||||
${SOES_SOURCE_DIR}/soes/hal/raspberrypi-lan9252/esc_hw.h
|
||||
)
|
||||
else()
|
||||
set(SOES_DEMO applications/linux_lan9252demo)
|
||||
set(HAL_SOURCES
|
||||
${SOES_SOURCE_DIR}/soes/hal/linux-lan9252/esc_hw.c
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${SOES_SOURCE_DIR}/soes/include/sys/gcc
|
||||
${SOES_SOURCE_DIR}/${SOES_DEMO}
|
||||
)
|
||||
|
||||
set(HAL_SOURCES
|
||||
${SOES_SOURCE_DIR}/soes/hal/linux-lan9252/esc_hw.c
|
||||
)
|
||||
|
||||
# Common compile flags
|
||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Werror)
|
||||
add_compile_options(-Wall -Wextra -Wconversion -Wno-unused-parameter -Werror)
|
||||
|
|
|
@ -41,7 +41,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MACHINE_FLAGS}" CACHE STRING "" FORCE)
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MACHINE_FLAGS}" CACHE STRING "" FORCE)
|
||||
|
||||
# Default libs
|
||||
set(RTK_LIBS "-l${BSP} -l${ARCH} -lkern -ldev -lsio -lblock -lfs -lusb -llwip -lptpd -leth -li2c -lrtc -lcan -lnand -lspi -lnor -lpwm -ladc -ltrace -lcounter -lc -lm")
|
||||
set(RTK_LIBS "-l${BSP} -l${ARCH} -lkern -ldev -lsio -lblock -lfs -lusb -llwip -lptpd -leth -li2c -lrtc -lcan -lnand -lspi -lnor -lpwm -ladc -ltrace -lcounter -lc -lm -lshell")
|
||||
|
||||
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostartfiles -T${RTK}/bsp/${BSP}/${BSP}.ld -Wl,--start-group <LINK_LIBRARIES> ${RTK_LIBS} -Wl,--end-group")
|
||||
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostartfiles -T${RTK}/bsp/${BSP}/${BSP}.ld -Wl,--start-group <LINK_LIBRARIES> ${RTK_LIBS} -Wl,--end-group")
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# Guard against multiple inclusion
|
||||
if(_TOOLCHAIN_CMAKE_)
|
||||
return()
|
||||
endif()
|
||||
set(_TOOLCHAIN_CMAKE_ TRUE)
|
||||
|
||||
INCLUDE(CMakeForceCompiler)
|
||||
SET(CMAKE_SYSTEM_NAME rt-kernel)
|
||||
|
||||
# specify the cross compiler
|
||||
CMAKE_FORCE_C_COMPILER(arm-eabi-gcc GNU)
|
||||
CMAKE_FORCE_CXX_COMPILER(arm-eabi-g++ GNU)
|
||||
|
||||
set(ARCH xmc4)
|
||||
set(CPU cortex-m4f)
|
||||
set(BSP xmc48relax)
|
||||
set(MACHINE_FLAGS "-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16")
|
||||
|
||||
set(SOES_DEMO applications/rtl_xmc4_dynpdo)
|
||||
|
||||
include_directories(
|
||||
${SOES_SOURCE_DIR}/${SOES_DEMO}
|
||||
${SOES_SOURCE_DIR}/soes/hal/rt-kernel-xmc4
|
||||
)
|
||||
|
||||
set(HAL_SOURCES
|
||||
${SOES_SOURCE_DIR}/soes/hal/rt-kernel-xmc4/esc_hw.c
|
||||
${SOES_SOURCE_DIR}/soes/hal/rt-kernel-xmc4/esc_hw_eep.c
|
||||
)
|
|
@ -1,184 +1,160 @@
|
|||
/*
|
||||
Datasheet : http://ww1.microchip.com/downloads/en/DeviceDoc/
|
||||
00001909A.pdf
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
/*
|
||||
Datasheet : http://ww1.microchip.com/downloads/en/DeviceDoc/
|
||||
00001909A.pdf
|
||||
*/
|
||||
#include <linux/miscdevice.h>
|
||||
|
||||
#define LAN9252_MAGIC 'l' //8bit=0~0xff 'l'an9252
|
||||
#define TEST _IO(LAN9252_MAGIC, 0)
|
||||
|
||||
#define LAN9252_LOCK mutex_lock(&lan9252_mutex);
|
||||
#define LAN9252_UNLOCK mutex_unlock(&lan9252_mutex);
|
||||
#define LAN9252_LOCK mutex_lock(&lan9252_mutex);
|
||||
#define LAN9252_UNLOCK mutex_unlock(&lan9252_mutex);
|
||||
|
||||
#define DEVICE_NAME "lan9252"
|
||||
#define LAN9252_MAJOR 153
|
||||
|
||||
/* spi command */
|
||||
#define FAST_READ 0x0B
|
||||
#define FAST_READ_DUMMY 1
|
||||
|
||||
struct mutex lock;
|
||||
static DEFINE_MUTEX(lan9252_mutex);
|
||||
|
||||
dev_t id;
|
||||
static struct device *dev;
|
||||
static struct class *lan9252_class;
|
||||
static struct spi_device *lan9252_devices;
|
||||
static struct spi_device *lan9252;
|
||||
|
||||
static int lan9252_ethercat_probe(struct spi_device *spi);
|
||||
static int lan9252_ethercat_remove(struct spi_device *spi);
|
||||
|
||||
static int lan9252_open(struct inode *inode, struct file *filp)
|
||||
static loff_t lan9252_llseek(struct file *file, loff_t address, int whence)
|
||||
{
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
int ret;
|
||||
|
||||
static int lan9252_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
LAN9252_LOCK;
|
||||
|
||||
static loff_t lan9252_llseek(struct file *file, loff_t address,
|
||||
int whence)
|
||||
{
|
||||
int status;
|
||||
file->f_pos = address;
|
||||
ret = file->f_pos;
|
||||
|
||||
LAN9252_LOCK;
|
||||
LAN9252_UNLOCK;
|
||||
|
||||
file->f_pos = address;
|
||||
|
||||
status = file->f_pos;
|
||||
|
||||
LAN9252_UNLOCK;
|
||||
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int * lan9252_reg_addr_make(int address)
|
||||
{
|
||||
|
||||
int temp;
|
||||
static int lan9252_reg_addr[2];
|
||||
int temp;
|
||||
static int lan9252_reg_addr[2];
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
|
||||
temp = address & 0xff00;
|
||||
lan9252_reg_addr[0] = temp >> 8;
|
||||
temp = address & 0x00ff;
|
||||
lan9252_reg_addr[1] = temp;
|
||||
temp = address & 0xff00;
|
||||
lan9252_reg_addr[0] = temp >> 8;
|
||||
temp = address & 0x00ff;
|
||||
lan9252_reg_addr[1] = temp;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i=0; i<2; i++)
|
||||
dev_dbg(&lan9252_devices->dev, "%s() lan9252_reg_addr[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, lan9252_reg_addr[i]);
|
||||
for (i=0; i<2; i++)
|
||||
dev_dbg(&lan9252->dev, "%s() lan9252_reg_addr[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, lan9252_reg_addr[i]);
|
||||
#endif
|
||||
|
||||
return lan9252_reg_addr;
|
||||
return lan9252_reg_addr;
|
||||
}
|
||||
|
||||
/*
|
||||
int lan9252_test(void);
|
||||
Description : Check the connection status of LAN9252
|
||||
Retrun Value
|
||||
0 : success
|
||||
other : fail
|
||||
int lan9252_test(void);
|
||||
Description : Check the connection status of LAN9252
|
||||
Retrun Value
|
||||
0 : success
|
||||
other : fail
|
||||
|
||||
Register Type : SYSTEM CONTROL AND STATUS REGISTERS
|
||||
Register Name(SYMBOL) : BYTE ORDER TEST REGISTER(BYTE_TEST)
|
||||
Offset : 0x0064
|
||||
Size : 32bit
|
||||
Default : 0x87654321
|
||||
Datasheet description : Chip-level reset/configuration
|
||||
completion can be determined by first
|
||||
polling the
|
||||
Byte Order Test Register(BYTE_TEST).
|
||||
Register Type : SYSTEM CONTROL AND STATUS REGISTERS
|
||||
Register Name(SYMBOL) : BYTE ORDER TEST REGISTER(BYTE_TEST)
|
||||
Offset : 0x0064
|
||||
Size : 32bit
|
||||
Default : 0x87654321
|
||||
Datasheet description : Chip-level reset/configuration
|
||||
completion can be determined by first
|
||||
polling the
|
||||
Byte Order Test Register(BYTE_TEST).
|
||||
*/
|
||||
static int lan9252_test(void)
|
||||
{
|
||||
u8 command[4];
|
||||
u8 test_buffer[4];
|
||||
int status=0;
|
||||
u8 command[4];
|
||||
u8 test_buffer[4];
|
||||
int ret=0;
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
int i;
|
||||
#endif
|
||||
command[0]=FAST_READ;
|
||||
command[1]=0x00;
|
||||
command[2]=0x64;
|
||||
command[3]=FAST_READ_DUMMY;
|
||||
command[0]=FAST_READ;
|
||||
command[1]=0x00;
|
||||
command[2]=0x64;
|
||||
command[3]=FAST_READ_DUMMY;
|
||||
|
||||
ret = spi_write_then_read(lan9252, &command, sizeof(command),
|
||||
test_buffer, sizeof(test_buffer));
|
||||
if (ret < 0 ) {
|
||||
dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
|
||||
"ret=%d\n", __FUNCTION__, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = spi_write_then_read(lan9252_devices, &command,
|
||||
sizeof(command), test_buffer, sizeof(test_buffer));
|
||||
if (status < 0 ) {
|
||||
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
|
||||
" failed status=%d\n", __FUNCTION__, status);
|
||||
return -1;
|
||||
}
|
||||
ret = spi_write_then_read(lan9252, &command, sizeof(command),
|
||||
test_buffer, sizeof(test_buffer));
|
||||
if (ret < 0) {
|
||||
dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
|
||||
"ret=%d\n", __FUNCTION__, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = spi_write_then_read(lan9252_devices, &command,
|
||||
sizeof(command), test_buffer, sizeof(test_buffer));
|
||||
if (status < 0 ) {
|
||||
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
|
||||
" failed status=%d\n", __FUNCTION__, status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i=0; i<sizeof(test_buffer); i++)
|
||||
dev_dbg(&lan9252_devices->dev, "%s() test_buffer[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, test_buffer[i]);
|
||||
for (i=0; i<sizeof(test_buffer); i++)
|
||||
dev_dbg(&lan9252->dev, "%s() test_buffer[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, test_buffer[i]);
|
||||
#endif
|
||||
|
||||
if (test_buffer[0]==0x21 && test_buffer[1]==0x43 &&
|
||||
test_buffer[2]==0x65 && test_buffer[3]==0x87)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
if (test_buffer[0]==0x21 && test_buffer[1]==0x43 &&
|
||||
test_buffer[2]==0x65 && test_buffer[3]==0x87)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ssize_t lan9252_read(
|
||||
struct file *file, char *buffer,
|
||||
size_t read_buffer_size, loff_t *f_pos)
|
||||
static ssize_t lan9252_read(struct file *file, char *buffer,
|
||||
size_t read_buffer_size, loff_t *f_pos)
|
||||
{
|
||||
u8 command[4];
|
||||
u8 *read_buffer;
|
||||
int status=0;
|
||||
int *lan9252_reg_read_addr;
|
||||
u8 command[4];
|
||||
u8 *read_buffer;
|
||||
int ret = 0;
|
||||
int *lan9252_reg_read_addr;
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
|
||||
LAN9252_LOCK;
|
||||
LAN9252_LOCK;
|
||||
|
||||
if (read_buffer_size <= 0) {
|
||||
dev_err(&lan9252_devices->dev, "read_buffer_size(%d) <= 0 \n",
|
||||
dev_err(&lan9252->dev, "read_buffer_size(%d) <= 0 \n",
|
||||
read_buffer_size);
|
||||
goto out;
|
||||
} else {
|
||||
dev_dbg(&lan9252_devices->dev, "read_buffer_size = %d\n",
|
||||
read_buffer_size);
|
||||
dev_dbg(&lan9252->dev, "read_buffer_size = %d\n",
|
||||
read_buffer_size);
|
||||
}
|
||||
|
||||
read_buffer= (u8 *)kmalloc((read_buffer_size) *
|
||||
sizeof(u32), GFP_KERNEL | GFP_DMA);
|
||||
read_buffer= (u8 *)kmalloc((read_buffer_size) * sizeof(u32),
|
||||
GFP_KERNEL | GFP_DMA);
|
||||
if (!read_buffer) {
|
||||
dev_err(&lan9252_devices->dev, "read_buffer kmalloc error\n");
|
||||
status = -ENOMEM;
|
||||
dev_err(&lan9252->dev, "write read_buffer kmalloc error\n");
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
memset(read_buffer, 0, (read_buffer_size) * sizeof(u8));
|
||||
memset(read_buffer, 0, (read_buffer_size) * sizeof(u8));
|
||||
|
||||
lan9252_reg_read_addr = lan9252_reg_addr_make(file->f_pos);
|
||||
command[0] = FAST_READ;
|
||||
|
@ -188,94 +164,88 @@ static ssize_t lan9252_read(
|
|||
|
||||
#ifdef DEBUG
|
||||
for (i=0; i<4; i++)
|
||||
dev_dbg(&lan9252_devices->dev, "%s() command[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, command[i]);
|
||||
dev_dbg(&lan9252->dev, "%s() command[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, command[i]);
|
||||
#endif
|
||||
|
||||
status = spi_write_then_read(lan9252_devices, &command,
|
||||
sizeof(command), read_buffer,read_buffer_size);
|
||||
if (status < 0 ) {
|
||||
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
|
||||
"failed status=%d\n", __FUNCTION__, status);
|
||||
ret = spi_write_then_read(lan9252, &command, sizeof(command),
|
||||
read_buffer,read_buffer_size);
|
||||
if (ret < 0) {
|
||||
dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
|
||||
"ret=%d\n", __FUNCTION__, ret);
|
||||
goto kfree_read_buffer;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i=0; i<read_buffer_size; i++)
|
||||
dev_dbg(&lan9252_devices->dev, "%s() read_buffer[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, read_buffer[i]);
|
||||
dev_dbg(&lan9252->dev, "%s() read_buffer[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, read_buffer[i]);
|
||||
#endif
|
||||
|
||||
if (copy_to_user(buffer, read_buffer, read_buffer_size)) {
|
||||
dev_err(&lan9252_devices->dev, "%s() copy_to_user failed\n",
|
||||
__FUNCTION__);
|
||||
status = -EFAULT;
|
||||
dev_err(&lan9252->dev, "%s() copy_to_user failed\n",
|
||||
__FUNCTION__);
|
||||
ret = -EFAULT;
|
||||
goto kfree_read_buffer;
|
||||
}
|
||||
|
||||
status = read_buffer_size;
|
||||
ret = read_buffer_size;
|
||||
|
||||
kfree_read_buffer:
|
||||
kfree(read_buffer);
|
||||
|
||||
out:
|
||||
LAN9252_UNLOCK;
|
||||
return status;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t lan9252_write(
|
||||
struct file *file, const char *command_buff,
|
||||
size_t command_buff_size, loff_t *f_pos)
|
||||
static ssize_t lan9252_write(struct file *file, const char *command_buff,
|
||||
size_t command_buff_size, loff_t *f_pos)
|
||||
{
|
||||
u8 *command;
|
||||
int status=0;
|
||||
int ret = 0;
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
#endif
|
||||
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
|
||||
LAN9252_LOCK;
|
||||
|
||||
if (command_buff_size <= 0) {
|
||||
dev_err(&lan9252_devices->dev, "command_buff_size(%d) <= 0 \n",
|
||||
dev_err(&lan9252->dev, "command_buff_size(%d) <= 0 \n",
|
||||
command_buff_size);
|
||||
goto out;
|
||||
} else {
|
||||
dev_dbg(&lan9252_devices->dev, "command_buff_size = %d\n",
|
||||
command_buff_size);
|
||||
dev_dbg(&lan9252->dev, "command_buff_size = %d\n",
|
||||
command_buff_size);
|
||||
}
|
||||
|
||||
command = (u8 *)kmalloc((command_buff_size) *
|
||||
sizeof(u8), GFP_KERNEL | GFP_DMA);
|
||||
command = (u8 *)kmalloc((command_buff_size) * sizeof(u8),
|
||||
GFP_KERNEL | GFP_DMA);
|
||||
if (!command) {
|
||||
dev_err(&lan9252_devices->dev, "write command buffer kmalloc"
|
||||
" error\n");
|
||||
status = -ENOMEM;
|
||||
dev_err(&lan9252->dev, "write command kmalloc error\n");
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(command, 0, (command_buff_size) * sizeof(u8));
|
||||
|
||||
if (copy_from_user(command, command_buff, command_buff_size)) {
|
||||
dev_err(&lan9252_devices->dev, "%s() copy_from_user failed\n",
|
||||
__FUNCTION__);
|
||||
status = -EFAULT;
|
||||
dev_err(&lan9252->dev, "%s() copy_from_user failed\n",
|
||||
__FUNCTION__);
|
||||
ret = -EFAULT;
|
||||
goto kfree_command;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for(i=0;i<command_buff_size;i++)
|
||||
dev_dbg(&lan9252_devices->dev, "command[%d]=0x%x\n", i,
|
||||
command[i]);
|
||||
dev_dbg(&lan9252->dev, "command[%d]=0x%x\n",i,command[i]);
|
||||
#endif
|
||||
|
||||
status = spi_write_then_read(lan9252_devices, command,
|
||||
command_buff_size, NULL, 0);
|
||||
if (status < 0 ) {
|
||||
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
|
||||
"failed status=%d\n", __FUNCTION__, status);
|
||||
ret = spi_write_then_read(lan9252, command,
|
||||
command_buff_size, NULL, 0);
|
||||
if (ret < 0) {
|
||||
dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
|
||||
"ret=%d\n", __FUNCTION__, ret);
|
||||
goto kfree_command;
|
||||
}
|
||||
|
||||
|
@ -284,29 +254,30 @@ kfree_command:
|
|||
|
||||
out:
|
||||
LAN9252_UNLOCK;
|
||||
return status;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long lan9252_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long argument)
|
||||
unsigned long argument)
|
||||
{
|
||||
int status;
|
||||
int ret;
|
||||
|
||||
LAN9252_LOCK;
|
||||
|
||||
switch (cmd) {
|
||||
case TEST:
|
||||
status=lan9252_test();
|
||||
break;
|
||||
LAN9252_LOCK;
|
||||
|
||||
default:
|
||||
status=0;
|
||||
break;
|
||||
}
|
||||
switch (cmd) {
|
||||
case TEST:
|
||||
ret = lan9252_test();
|
||||
break;
|
||||
|
||||
LAN9252_UNLOCK;
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
LAN9252_UNLOCK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -317,13 +288,11 @@ static const struct spi_device_id lan9252_id_table[] = {
|
|||
MODULE_DEVICE_TABLE(spi, lan9252_id_table);
|
||||
|
||||
static const struct file_operations lan9252_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = lan9252_open,
|
||||
.release = lan9252_release,
|
||||
.llseek = lan9252_llseek,
|
||||
.write = lan9252_write,
|
||||
.read = lan9252_read,
|
||||
.unlocked_ioctl = lan9252_ioctl,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = lan9252_llseek,
|
||||
.write = lan9252_write,
|
||||
.read = lan9252_read,
|
||||
.unlocked_ioctl = lan9252_ioctl,
|
||||
};
|
||||
|
||||
static struct spi_driver lan9252_ethercat_driver = {
|
||||
|
@ -335,80 +304,47 @@ static struct spi_driver lan9252_ethercat_driver = {
|
|||
.remove = lan9252_ethercat_remove,
|
||||
};
|
||||
|
||||
struct miscdevice lan9252_miscdev = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = DEVICE_NAME,
|
||||
.fops = &lan9252_fops,
|
||||
};
|
||||
|
||||
static int lan9252_ethercat_probe(struct spi_device *spi)
|
||||
{
|
||||
int status;
|
||||
|
||||
dev_dbg(&spi->dev, "%s() called\n", __FUNCTION__);
|
||||
int ret;
|
||||
|
||||
mutex_init(&lock);
|
||||
|
||||
lan9252_devices = spi;
|
||||
lan9252 = spi;
|
||||
|
||||
if(lan9252_test())
|
||||
dev_warn(&lan9252_devices->dev, "lan9252 not connected\n");
|
||||
if(lan9252_test())
|
||||
dev_warn(&spi->dev, "lan9252 not connected\n");
|
||||
|
||||
if (register_chrdev(LAN9252_MAJOR,
|
||||
lan9252_ethercat_driver.driver.name, &lan9252_fops)) {
|
||||
dev_err(&lan9252_devices->dev, "unable to get major %d for "
|
||||
, LAN9252_MAJOR);
|
||||
status = -ENODEV;
|
||||
goto register_chrdev_fail;
|
||||
}
|
||||
ret = misc_register(&lan9252_miscdev);
|
||||
if (ret)
|
||||
goto misc_register_fail;
|
||||
|
||||
lan9252_class = class_create(THIS_MODULE,
|
||||
lan9252_ethercat_driver.driver.name);
|
||||
if (IS_ERR(lan9252_class)) {
|
||||
status = PTR_ERR(lan9252_class);
|
||||
goto class_create_fail;
|
||||
}
|
||||
|
||||
id = MKDEV(LAN9252_MAJOR, 0);
|
||||
dev = device_create(lan9252_class, NULL, id, NULL,
|
||||
lan9252_ethercat_driver.driver.name);
|
||||
if (IS_ERR(dev)) {
|
||||
status = PTR_ERR(dev);
|
||||
dev_err(dev, "device_create error %d\n", status);
|
||||
goto device_create_fail;
|
||||
|
||||
}
|
||||
|
||||
dev_dbg(&lan9252_devices->dev, "spi->max_speed_hz=%d"
|
||||
" spi->bits_per_word=%d spi->mode=%d\n", spi->max_speed_hz,
|
||||
spi->bits_per_word, spi->mode);
|
||||
dev_dbg(&lan9252_devices->dev, "spi->chip_select=%d spi->cs_gpio=%d\n",
|
||||
spi->chip_select, spi->cs_gpio);
|
||||
|
||||
dev_info(&lan9252_devices->dev, "Probed\n");
|
||||
dev_info(&spi->dev, "Probed\n");
|
||||
|
||||
return 0;
|
||||
|
||||
device_create_fail:
|
||||
class_destroy(lan9252_class);
|
||||
misc_register_fail:
|
||||
dev_err(&spi->dev, "Probed failed : %d\n", ret);
|
||||
|
||||
class_create_fail:
|
||||
unregister_chrdev(LAN9252_MAJOR,
|
||||
lan9252_ethercat_driver.driver.name);
|
||||
|
||||
register_chrdev_fail:
|
||||
dev_err(&lan9252_devices->dev, "Probed failed : %d\n", status);
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lan9252_ethercat_remove(struct spi_device *spi)
|
||||
{
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
misc_deregister(&lan9252_miscdev);
|
||||
|
||||
device_destroy(lan9252_class, id);
|
||||
class_destroy(lan9252_class);
|
||||
unregister_chrdev(LAN9252_MAJOR,
|
||||
lan9252_ethercat_driver.driver.name);
|
||||
dev_info(&spi->dev, "Removed\n");
|
||||
|
||||
dev_info(&lan9252_devices->dev, "Removed\n");
|
||||
return 0;
|
||||
}
|
||||
module_spi_driver(lan9252_ethercat_driver);
|
||||
|
||||
MODULE_AUTHOR("tykwon@m2i.co.kr");
|
||||
MODULE_DESCRIPTION("Microchip LAN9252 Ethercat Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -6,8 +6,8 @@ Required properties:
|
|||
- reg: SPI chip select.
|
||||
|
||||
Example:
|
||||
ethercat: lan9252@1 {
|
||||
compatible = "lan9252";
|
||||
spi-max-frequency = <20000000>;
|
||||
reg = <1>;
|
||||
};
|
||||
ethercat: lan9252@1 {
|
||||
compatible = "lan9252";
|
||||
spi-max-frequency = <20000000>;
|
||||
reg = <1>;
|
||||
};
|
||||
|
|
|
@ -7,8 +7,13 @@ add_library (soes
|
|||
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}
|
||||
)
|
||||
|
||||
|
@ -19,5 +24,6 @@ install (FILES
|
|||
esc.h
|
||||
esc_coe.h
|
||||
esc_foe.h
|
||||
esc_eoe.h
|
||||
esc_eep.h
|
||||
DESTINATION include)
|
||||
|
|
|
@ -1,74 +1,135 @@
|
|||
#ifndef SOES_V1
|
||||
/*
|
||||
* 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 "utypes.h"
|
||||
#include "esc.h"
|
||||
#include "esc_coe.h"
|
||||
#include "esc_foe.h"
|
||||
#include "config.h"
|
||||
#include "slave.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;
|
||||
|
||||
/* Application variables */
|
||||
_Rbuffer Rb;
|
||||
_Wbuffer Wb;
|
||||
_Cbuffer Cb;
|
||||
_Mbuffer Mb;
|
||||
|
||||
/* Private variables */
|
||||
static volatile int watchdog;
|
||||
|
||||
/** Mandatory: Function to pre-qualify the incoming SDO download.
|
||||
#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 1 if the SDO Download is correct. 0 If not correct.
|
||||
* @return SDO abort code, or 0 on success
|
||||
*/
|
||||
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
|
||||
uint32_t ESC_download_pre_objecthandler (uint16_t index,
|
||||
uint8_t subindex,
|
||||
void * data,
|
||||
size_t size,
|
||||
uint16_t flags)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
if(ESCvar.pre_object_download_hook)
|
||||
if (IS_RXPDO (index) ||
|
||||
IS_TXPDO (index) ||
|
||||
index == RX_PDO_OBJIDX ||
|
||||
index == TX_PDO_OBJIDX)
|
||||
{
|
||||
result = (ESCvar.pre_object_download_hook)(index, subindex);
|
||||
uint8_t minSub = ((flags & COMPLETE_ACCESS_FLAG) == 0) ? 0 : 1;
|
||||
if (subindex > minSub && COE_maxSub (index) != 0)
|
||||
{
|
||||
return ABORT_SUBINDEX0_NOT_ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
if (ESCvar.pre_object_download_hook)
|
||||
{
|
||||
return (ESCvar.pre_object_download_hook) (index,
|
||||
subindex,
|
||||
data,
|
||||
size,
|
||||
flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Mandatory: Hook called from the slave stack SDO Download handler to act on
|
||||
/** 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
|
||||
*/
|
||||
void ESC_objecthandler (uint16_t index, uint8_t subindex)
|
||||
uint32_t ESC_download_post_objecthandler (uint16_t index, uint8_t subindex, uint16_t flags)
|
||||
{
|
||||
switch (index)
|
||||
if (ESCvar.post_object_download_hook != NULL)
|
||||
{
|
||||
/* Handle post-write of parameter values */
|
||||
case 0x8001:
|
||||
{
|
||||
cb_post_write_variableRW(subindex);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if(ESCvar.post_object_download_hook != NULL)
|
||||
{
|
||||
(ESCvar.post_object_download_hook)(index, subindex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (ESCvar.post_object_download_hook)(index, subindex, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Mandatory: Hook called from the slave stack ESC_stopoutputs to act on state changes
|
||||
/** 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.
|
||||
* set
|
||||
*/
|
||||
void APP_safeoutput (void)
|
||||
{
|
||||
|
@ -78,16 +139,9 @@ void APP_safeoutput (void)
|
|||
{
|
||||
(ESCvar.safeoutput_override)();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set safe values for Wb.LEDgroup0
|
||||
Wb.LEDgroup0.LED0 = 0;
|
||||
// Set safe values for Wb.LEDgroup1
|
||||
Wb.LEDgroup1.LED1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
|
||||
/** Write local process data to Sync Manager 3, Master Inputs.
|
||||
*/
|
||||
void TXPDO_update (void)
|
||||
{
|
||||
|
@ -97,11 +151,15 @@ void TXPDO_update (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
ESC_write (SM3_sma, &Rb, ESCvar.TXPDOsize);
|
||||
if (MAX_MAPPINGS_SM3 > 0)
|
||||
{
|
||||
COE_pdoPack (txpdo, ESCvar.sm3mappings, SMmap3);
|
||||
}
|
||||
ESC_write (ESC_SM3_sma, txpdo, ESCvar.ESC_SM3_sml);
|
||||
}
|
||||
}
|
||||
|
||||
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
|
||||
/** Read Sync Manager 2 to local process data, Master Outputs.
|
||||
*/
|
||||
void RXPDO_update (void)
|
||||
{
|
||||
|
@ -111,11 +169,25 @@ void RXPDO_update (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
ESC_read (SM2_sma, &Wb, ESCvar.RXPDOsize);
|
||||
ESC_read (ESC_SM2_sma, rxpdo, ESCvar.ESC_SM2_sml);
|
||||
if (MAX_MAPPINGS_SM2 > 0)
|
||||
{
|
||||
COE_pdoUnpack (rxpdo, ESCvar.sm2mappings, SMmap2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Mandatory: Function to update local I/O, call read ethercat outputs, call
|
||||
/* 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.
|
||||
*/
|
||||
|
@ -124,21 +196,17 @@ void DIG_process (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))
|
||||
((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0) &&
|
||||
(ESCvar.ESC_SM2_sml > 0))
|
||||
{
|
||||
DPRINT("DIG_process watchdog expired\n");
|
||||
ESC_stopoutput();
|
||||
/* watchdog, invalid outputs */
|
||||
ESC_ALerror (ALERR_WATCHDOG);
|
||||
/* goto safe-op with error bit set */
|
||||
ESC_ALstatus (ESCsafeop | ESCerror);
|
||||
ESC_ALstatusgotoerror((ESCsafeop | ESCerror), ALERR_WATCHDOG);
|
||||
}
|
||||
else if(((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) == 0))
|
||||
{
|
||||
|
@ -154,44 +222,18 @@ void DIG_process (uint8_t flags)
|
|||
{
|
||||
RXPDO_update();
|
||||
CC_ATOMIC_SET(watchdog, ESCvar.watchdogcnt);
|
||||
if(ESCvar.dcsync > 0)
|
||||
{
|
||||
CC_ATOMIC_ADD(ESCvar.synccounter, 1);
|
||||
}
|
||||
/* Set outputs */
|
||||
cb_set_LEDgroup0();
|
||||
cb_set_LEDgroup1();
|
||||
cb_set_outputs();
|
||||
}
|
||||
else if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
|
||||
{
|
||||
RXPDO_update();
|
||||
ESC_read (ESC_SM2_sma, rxpdo, ESCvar.ESC_SM2_sml);
|
||||
}
|
||||
}
|
||||
|
||||
/* Call application */
|
||||
if ((flags & DIG_PROCESS_APP_HOOK_FLAG) > 0)
|
||||
{
|
||||
|
||||
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
|
||||
{
|
||||
CC_ATOMIC_SUB(ESCvar.synccounter, 1);
|
||||
}
|
||||
|
||||
if((ESCvar.dcsync > 0) &&
|
||||
((CC_ATOMIC_GET(ESCvar.synccounter) < -ESCvar.synccounterlimit) ||
|
||||
(CC_ATOMIC_GET(ESCvar.synccounter) > ESCvar.synccounterlimit)))
|
||||
{
|
||||
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
|
||||
{
|
||||
DPRINT("sync error = %d\n", ESCvar.synccounter);
|
||||
ESC_stopoutput();
|
||||
/* Sync error */
|
||||
ESC_ALerror (ALERR_SYNCERROR);
|
||||
/* goto safe-op with error bit set */
|
||||
ESC_ALstatus (ESCsafeop | ESCerror);
|
||||
CC_ATOMIC_SET(ESCvar.synccounter, 0);
|
||||
}
|
||||
}
|
||||
/* Call application callback if set */
|
||||
if (ESCvar.application_hook != NULL)
|
||||
{
|
||||
|
@ -205,13 +247,13 @@ void DIG_process (uint8_t flags)
|
|||
if(CC_ATOMIC_GET(ESCvar.App.state) > 0)
|
||||
{
|
||||
/* Update inputs */
|
||||
cb_get_Buttons();
|
||||
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
|
||||
|
@ -229,10 +271,17 @@ void ecat_slv_worker (uint32_t event_mask)
|
|||
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)
|
||||
{
|
||||
|
@ -246,18 +295,7 @@ void ecat_slv_worker (uint32_t event_mask)
|
|||
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | event_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* ISR function. It should be called from ISR for applications entirely driven by
|
||||
* interrupts.
|
||||
* Read and handle events for the EtherCAT state, status, mailbox and eeprom.
|
||||
*/
|
||||
void ecat_slv_isr (void)
|
||||
{
|
||||
ecat_slv_worker(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
|
||||
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* 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.
|
||||
|
@ -277,9 +315,17 @@ void ecat_slv_poll (void)
|
|||
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)
|
||||
|
@ -288,6 +334,9 @@ void ecat_slv_poll (void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Poll all events in a free-run application
|
||||
*/
|
||||
void ecat_slv (void)
|
||||
{
|
||||
ecat_slv_poll();
|
||||
|
@ -295,16 +344,13 @@ void ecat_slv (void)
|
|||
DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Initialize the slave stack.
|
||||
*/
|
||||
void ecat_slv_init (esc_cfg_t * config)
|
||||
{
|
||||
DPRINT ("Slave stack init started\n");
|
||||
|
||||
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
|
||||
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
|
||||
|
||||
/* Init watchdog */
|
||||
watchdog = config->watchdog_cnt;
|
||||
|
||||
|
@ -321,14 +367,22 @@ void ecat_slv_init (esc_cfg_t * config)
|
|||
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
|
||||
}
|
||||
|
||||
#if USE_FOE
|
||||
/* Init FoE */
|
||||
FOE_init();
|
||||
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();
|
||||
ESC_stopmbx ();
|
||||
ESC_stopinput ();
|
||||
ESC_stopoutput ();
|
||||
/* Init Object Dictionary default values */
|
||||
COE_initDefaultValues ();
|
||||
}
|
||||
#endif
|
|
@ -1,28 +1,29 @@
|
|||
#ifndef __SLAVE_H__
|
||||
#define __SLAVE_H__
|
||||
/*
|
||||
* Licensed under the GNU General Public License version 2 with exceptions. See
|
||||
* LICENSE file in the project root for full license information
|
||||
*/
|
||||
|
||||
#include "utypes.h"
|
||||
#ifndef __ECAT_SLV_H__
|
||||
#define __ECAT_SLV_H__
|
||||
|
||||
#include "options.h"
|
||||
#include "esc.h"
|
||||
|
||||
/**
|
||||
* This function gets input values and updates Rb.Buttons
|
||||
* This function is called when to get input values
|
||||
*/
|
||||
void cb_get_Buttons();
|
||||
void cb_get_inputs();
|
||||
|
||||
/**
|
||||
* This function sets output values according to Wb.LEDgroup0
|
||||
* This function is called when to set outputs values
|
||||
*/
|
||||
void cb_set_LEDgroup0();
|
||||
void cb_set_outputs();
|
||||
|
||||
/**
|
||||
* This function sets output values according to Wb.LEDgroup1
|
||||
/** Set the watchdog count value
|
||||
*
|
||||
* @param[in] watchdogcnt = new watchdog count value
|
||||
*/
|
||||
void cb_set_LEDgroup1();
|
||||
|
||||
/**
|
||||
* This function is called after a SDO write of the object Cb.variableRW.
|
||||
*/
|
||||
void cb_post_write_variableRW(int subindex);
|
||||
void APP_setwatchdog (int watchdogcnt);
|
||||
|
||||
#define DIG_PROCESS_INPUTS_FLAG 0x01
|
||||
#define DIG_PROCESS_OUTPUTS_FLAG 0x02
|
||||
|
@ -47,12 +48,6 @@ void DIG_process (uint8_t flags);
|
|||
*/
|
||||
void ecat_slv_worker (uint32_t event_mask);
|
||||
|
||||
/**
|
||||
* ISR for SM0/1, EEPROM and AL CONTROL events in a SM/DC
|
||||
* synchronization application
|
||||
*/
|
||||
CC_DEPRECATED void ecat_slv_isr (void);
|
||||
|
||||
/**
|
||||
* Poll SM0/1, EEPROM and AL CONTROL events in a SM/DC synchronization
|
||||
* application
|
||||
|
@ -71,4 +66,4 @@ void ecat_slv (void);
|
|||
*/
|
||||
void ecat_slv_init (esc_cfg_t * config);
|
||||
|
||||
#endif /* __SLAVE_H__ */
|
||||
#endif /* __ECAT_SLV_H__ */
|
411
soes/esc.c
411
soes/esc.c
|
@ -41,6 +41,48 @@ void ESC_ALstatus (uint8_t status)
|
|||
ESC_write (ESCREG_ALSTATUS, &dummy, sizeof (dummy));
|
||||
}
|
||||
|
||||
/** Write AL Status and AL Status code to the ESC.
|
||||
* Call pre- and poststate change hook
|
||||
*
|
||||
* @param[in] status = Write current slave status to register 0x130 AL Status
|
||||
* reflecting actual state and error indication if present
|
||||
* @param[in] errornumber = Write an by EtherCAT specified Error number
|
||||
* register 0x134 AL Status Code
|
||||
*/
|
||||
void ESC_ALstatusgotoerror (uint8_t status, uint16_t errornumber)
|
||||
{
|
||||
uint8_t an, as;
|
||||
|
||||
if(status & ESCop)
|
||||
{
|
||||
/* Erroneous input, ignore */
|
||||
return;
|
||||
}
|
||||
/* Mask error ack of current state */
|
||||
as = ESCvar.ALstatus & ESCREG_AL_ERRACKMASK;
|
||||
an = as;
|
||||
/* Set the state transition, new state in high bits and old in bits */
|
||||
as = (uint8_t)(((status & ESCREG_AL_ERRACKMASK) << 4) | (as & 0x0f));
|
||||
/* Call post state change hook case it have been configured */
|
||||
if (ESCvar.pre_state_change_hook != NULL)
|
||||
{
|
||||
ESCvar.pre_state_change_hook (&as, &an);
|
||||
}
|
||||
/* Stop outputs if active */
|
||||
if ((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
|
||||
{
|
||||
ESC_stopoutput();
|
||||
}
|
||||
ESC_ALerror(errornumber);
|
||||
ESC_ALstatus(status);
|
||||
an = status;
|
||||
/* Call post state change hook case it have been configured */
|
||||
if (ESCvar.post_state_change_hook != NULL)
|
||||
{
|
||||
ESCvar.post_state_change_hook (&as, &an);
|
||||
}
|
||||
}
|
||||
|
||||
/** Write ALeventMask register 0x204.
|
||||
*
|
||||
* @param[in] n = AL Event Mask
|
||||
|
@ -86,15 +128,15 @@ uint32_t ESC_ALeventread (void)
|
|||
return htoel(alevent);
|
||||
}
|
||||
|
||||
/** Read SM Status register 0x805(+ offset to SyncManager n) to acknowledge a
|
||||
/** Read SM Activate register 0x806(+ offset to SyncManager n) to acknowledge a
|
||||
* Sync Manager event Bit 3 in ALevent. The result is not used.
|
||||
*
|
||||
* @param[in] n = Read Sync Manager no. n
|
||||
*/
|
||||
void ESC_SMack (uint8_t n)
|
||||
{
|
||||
uint16_t dummy;
|
||||
ESC_read (ESCREG_SM0STATUS + (n << 3), &dummy, 2);
|
||||
uint8_t dummy;
|
||||
ESC_read ((uint16_t)(ESCREG_SM0ACTIVATE + (n << 3)), &dummy, 1);
|
||||
}
|
||||
|
||||
/** Read SM Status register 0x805(+ offset to SyncManager n) and save the
|
||||
|
@ -105,18 +147,8 @@ void ESC_SMack (uint8_t n)
|
|||
void ESC_SMstatus (uint8_t n)
|
||||
{
|
||||
_ESCsm2 *sm;
|
||||
uint16_t temp;
|
||||
sm = (_ESCsm2 *) & ESCvar.SM[n];
|
||||
ESC_read (ESCREG_SM0STATUS + (n << 3), &temp, 2);
|
||||
#if defined(EC_LITTLE_ENDIAN)
|
||||
sm->ActESC = temp >> 8;
|
||||
sm->Status = temp;
|
||||
#endif
|
||||
|
||||
#if defined(EC_BIG_ENDIAN)
|
||||
sm->ActESC = temp;
|
||||
sm->Status = temp >> 8;
|
||||
#endif
|
||||
sm = (_ESCsm2 *)&ESCvar.SM[n];
|
||||
ESC_read ((uint16_t)(ESCREG_SM0STATUS + (n << 3)), &(sm->Status), 1);
|
||||
}
|
||||
|
||||
/** Write ESCvar.SM[n] data to ESC PDI control register 0x807(+ offset to SyncManager n).
|
||||
|
@ -126,8 +158,19 @@ void ESC_SMstatus (uint8_t n)
|
|||
void ESC_SMwritepdi (uint8_t n)
|
||||
{
|
||||
_ESCsm2 *sm;
|
||||
sm = (_ESCsm2 *) & ESCvar.SM[n];
|
||||
ESC_write (ESCREG_SM0PDI + (n << 3), &(sm->ActPDI), 1);
|
||||
sm = (_ESCsm2 *)&ESCvar.SM[n];
|
||||
ESC_write ((uint16_t)(ESCREG_SM0PDI + (n << 3)), &(sm->ActPDI), 1);
|
||||
}
|
||||
|
||||
/** Read ESC PDI control register 0x807(+ offset to SyncManager n) to ESCvar.SM[n] data.
|
||||
*
|
||||
* @param[in] n = Read from Sync Manager no. n
|
||||
*/
|
||||
void ESC_SMreadpdi (uint8_t n)
|
||||
{
|
||||
_ESCsm2* sm;
|
||||
sm = (_ESCsm2*)&ESCvar.SM[n];
|
||||
ESC_read ((uint16_t)(ESCREG_SM0PDI + (n << 3)), &(sm->ActPDI), 1);
|
||||
}
|
||||
|
||||
/** Write 0 to Bit0 in SM PDI control register 0x807(+ offset to SyncManager n) to Activate the Sync Manager n.
|
||||
|
@ -137,9 +180,14 @@ void ESC_SMwritepdi (uint8_t n)
|
|||
void ESC_SMenable (uint8_t n)
|
||||
{
|
||||
_ESCsm2 *sm;
|
||||
sm = (_ESCsm2 *) & ESCvar.SM[n];
|
||||
sm->ActPDI &= ~ESCREG_SMENABLE_BIT;
|
||||
sm = (_ESCsm2 *)&ESCvar.SM[n];
|
||||
sm->ActPDI &= (uint8_t)~ESCREG_SMENABLE_BIT;
|
||||
ESC_SMwritepdi (n);
|
||||
/* Read back wait until enabled */
|
||||
do
|
||||
{
|
||||
ESC_SMreadpdi (n);
|
||||
} while ((sm->ActPDI & ESCREG_SMENABLE_BIT) == 1);
|
||||
}
|
||||
/** Write 1 to Bit0 in SM PDI control register 0x807(+ offset to SyncManager n) to De-activte the Sync Manager n.
|
||||
*
|
||||
|
@ -148,9 +196,14 @@ void ESC_SMenable (uint8_t n)
|
|||
void ESC_SMdisable (uint8_t n)
|
||||
{
|
||||
_ESCsm2 *sm;
|
||||
sm = (_ESCsm2 *) & ESCvar.SM[n];
|
||||
sm = (_ESCsm2 *)&ESCvar.SM[n];
|
||||
sm->ActPDI |= ESCREG_SMENABLE_BIT;
|
||||
ESC_SMwritepdi (n);
|
||||
/* Read back wait until disabled */
|
||||
do
|
||||
{
|
||||
ESC_SMreadpdi (n);
|
||||
} while ((sm->ActPDI & ESCREG_SMENABLE_BIT) == 0);
|
||||
}
|
||||
/** Read Configured Station Address register 0x010 assigned by the Master.
|
||||
*
|
||||
|
@ -218,51 +271,16 @@ uint16_t ESC_checkDC (void)
|
|||
uint16_t ret = 0;
|
||||
|
||||
uint8_t sync_act = ESC_SYNCactivation();
|
||||
uint32_t sync0_cycletime = ESC_SYNC0cycletime();
|
||||
uint16_t sync_type_supported1c32 = 0;
|
||||
uint32_t mincycletime = 0;
|
||||
|
||||
/* Do we need to check sync settings? */
|
||||
if((sync_act & (ESCREG_SYNC_ACT_ACTIVATED | ESCREG_SYNC_AUTO_ACTIVATED)) > 0)
|
||||
{
|
||||
/* If the sync unit is active at least on signal should be activated */
|
||||
if(COE_getSyncMgrPara(0x1c32, 0x4, &sync_type_supported1c32, DTYPE_UNSIGNED16) == 0)
|
||||
/* Trigger a by the application given DC check handler, return error if
|
||||
* non is given
|
||||
*/
|
||||
ret = ALERR_DCINVALIDSYNCCFG;
|
||||
if(ESCvar.esc_check_dc_handler != NULL)
|
||||
{
|
||||
ret = ALERR_DCINVALIDSYNCCFG;
|
||||
|
||||
}
|
||||
else if(COE_getSyncMgrPara(0x1c32, 0x5, &mincycletime, DTYPE_UNSIGNED32) == 0)
|
||||
{
|
||||
ret = ALERR_DCINVALIDSYNCCFG;
|
||||
}
|
||||
else if(COE_getSyncMgrPara(0x10F1, 0x2, &ESCvar.synccounterlimit, DTYPE_UNSIGNED16) == 0)
|
||||
{
|
||||
ret = ALERR_DCINVALIDSYNCCFG;
|
||||
}
|
||||
else if((sync_act & (ESCREG_SYNC_SYNC0_EN | ESCREG_SYNC_SYNC1_EN)) == 0)
|
||||
{
|
||||
ret = ALERR_DCINVALIDSYNCCFG;
|
||||
}
|
||||
/* Do we support activated signals */
|
||||
else if(((sync_type_supported1c32 & SYNCTYPE_SUPPORT_DCSYNC0) == 0) &&
|
||||
((sync_act & ESCREG_SYNC_SYNC0_EN) > 0))
|
||||
{
|
||||
ret = ALERR_DCINVALIDSYNCCFG;
|
||||
}
|
||||
/* Do we support activated signals */
|
||||
else if(((sync_type_supported1c32 & SYNCTYPE_SUPPORT_DCSYNC1) == 0) &&
|
||||
((sync_act & ESCREG_SYNC_SYNC1_EN) > 0))
|
||||
{
|
||||
ret = ALERR_DCINVALIDSYNCCFG;
|
||||
}
|
||||
else if((sync0_cycletime != 0) && (sync0_cycletime < mincycletime))
|
||||
{
|
||||
ret = ALERR_DCSYNC0CYCLETIME;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESCvar.dcsync = 1;
|
||||
ESCvar.synccounter = 0;
|
||||
ret = (ESCvar.esc_check_dc_handler)();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -320,11 +338,10 @@ uint8_t ESC_checkmbx (uint8_t state)
|
|||
uint8_t ESC_startmbx (uint8_t state)
|
||||
{
|
||||
/* Assign SM settings */
|
||||
ESCvar.activembxsize = ESCvar.mbxsize;
|
||||
ESCvar.activembxsize = MBXSIZE;
|
||||
ESCvar.activemb0 = &ESCvar.mb[0];
|
||||
ESCvar.activemb1 = &ESCvar.mb[1];
|
||||
|
||||
|
||||
ESC_SMenable (0);
|
||||
ESC_SMenable (1);
|
||||
ESC_SMstatus (0);
|
||||
|
@ -337,6 +354,8 @@ uint8_t ESC_startmbx (uint8_t state)
|
|||
else
|
||||
{
|
||||
ESCvar.toggle = ESCvar.SM[1].ECrep; //sync repeat request toggle state
|
||||
ESCvar.SM[1].PDIrep = ESCvar.toggle & 0x1U;
|
||||
ESC_SMwritepdi (1);
|
||||
ESCvar.MBXrun = 1;
|
||||
}
|
||||
return state;
|
||||
|
@ -354,7 +373,7 @@ uint8_t ESC_startmbx (uint8_t state)
|
|||
uint8_t ESC_startmbxboot (uint8_t state)
|
||||
{
|
||||
/* Assign SM settings */
|
||||
ESCvar.activembxsize = ESCvar.mbxsizeboot;
|
||||
ESCvar.activembxsize = MBXSIZEBOOT;
|
||||
ESCvar.activemb0 = &ESCvar.mbboot[0];
|
||||
ESCvar.activemb1 = &ESCvar.mbboot[1];
|
||||
|
||||
|
@ -370,6 +389,8 @@ uint8_t ESC_startmbxboot (uint8_t state)
|
|||
else
|
||||
{
|
||||
ESCvar.toggle = ESCvar.SM[1].ECrep; //sync repeat request toggle state
|
||||
ESCvar.SM[1].PDIrep = ESCvar.toggle & 0x1U;
|
||||
ESC_SMwritepdi (1);
|
||||
ESCvar.MBXrun = 1;
|
||||
}
|
||||
return state;
|
||||
|
@ -398,6 +419,9 @@ void ESC_stopmbx (void)
|
|||
ESCvar.frags = 0;
|
||||
ESCvar.fragsleft = 0;
|
||||
ESCvar.txcue = 0;
|
||||
ESCvar.index = 0;
|
||||
ESCvar.subindex = 0;
|
||||
ESCvar.flags = 0;
|
||||
}
|
||||
|
||||
/** Read Receive mailbox and store data in local ESCvar.MBX variable.
|
||||
|
@ -414,9 +438,9 @@ void ESC_readmbx (void)
|
|||
|
||||
if (length > (ESC_MBX0_sml - ESC_MBXHSIZE))
|
||||
{
|
||||
length = ESC_MBX0_sml - ESC_MBXHSIZE;
|
||||
length = (uint16_t)(ESC_MBX0_sml - ESC_MBXHSIZE);
|
||||
}
|
||||
ESC_read (ESC_MBX0_sma + ESC_MBXHSIZE, MB->b, length);
|
||||
ESC_read ((uint16_t)(ESC_MBX0_sma + ESC_MBXHSIZE), MB->b, length);
|
||||
if (length + ESC_MBXHSIZE < ESC_MBX0_sml)
|
||||
{
|
||||
ESC_read (ESC_MBX0_sme, &length, 1);
|
||||
|
@ -439,9 +463,9 @@ void ESC_writembx (uint8_t n)
|
|||
|
||||
if (length > (ESC_MBX1_sml - ESC_MBXHSIZE))
|
||||
{
|
||||
length = ESC_MBX1_sml - ESC_MBXHSIZE;
|
||||
length = (uint16_t)(ESC_MBX1_sml - ESC_MBXHSIZE);
|
||||
}
|
||||
ESC_write (ESC_MBX1_sma, MBh, ESC_MBXHSIZE + length);
|
||||
ESC_write (ESC_MBX1_sma, MBh, (uint16_t)(ESC_MBXHSIZE + length));
|
||||
if (length + ESC_MBXHSIZE < ESC_MBX1_sml)
|
||||
{
|
||||
ESC_write (ESC_MBX1_sme, &dummy, 1);
|
||||
|
@ -487,7 +511,7 @@ uint8_t ESC_claimbuffer (void)
|
|||
MBh->address = htoes (0x0000); // destination is master
|
||||
MBh->channel = 0;
|
||||
MBh->priority = 0;
|
||||
MBh->mbxcnt = ESCvar.mbxcnt;
|
||||
MBh->mbxcnt = ESCvar.mbxcnt & 0xFU;
|
||||
ESCvar.txcue++;
|
||||
}
|
||||
return n;
|
||||
|
@ -545,15 +569,15 @@ uint8_t ESC_mbxprocess (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* SM0/1 access or SMn change event */
|
||||
if (ESCvar.ALevent & ESCREG_ALEVENT_SM_MASK)
|
||||
/* SM0/1 access */
|
||||
if (ESCvar.ALevent & (ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1))
|
||||
{
|
||||
ESC_SMstatus (0);
|
||||
ESC_SMstatus (1);
|
||||
}
|
||||
|
||||
/* outmbx read by master */
|
||||
if (ESCvar.mbxoutpost && ESCvar.SM[1].IntR)
|
||||
if (ESCvar.mbxoutpost && (ESCvar.ALevent & ESCREG_ALEVENT_SM1))
|
||||
{
|
||||
ESC_ackmbxread ();
|
||||
/* dispose old backup */
|
||||
|
@ -601,7 +625,7 @@ uint8_t ESC_mbxprocess (void)
|
|||
ESC_writembx (ESCvar.mbxbackup);
|
||||
}
|
||||
ESCvar.toggle = ESCvar.SM[1].ECrep;
|
||||
ESCvar.SM[1].PDIrep = ESCvar.toggle;
|
||||
ESCvar.SM[1].PDIrep = ESCvar.toggle & 0x1U;
|
||||
ESC_SMwritepdi (1);
|
||||
}
|
||||
return 0;
|
||||
|
@ -616,6 +640,8 @@ uint8_t ESC_mbxprocess (void)
|
|||
if (mbxhandle)
|
||||
{
|
||||
ESC_writembx (mbxhandle);
|
||||
/* Refresh SM status */
|
||||
ESC_SMstatus (1);
|
||||
/* change state */
|
||||
MBXcontrol[mbxhandle].state = MBXstate_outpost;
|
||||
ESCvar.mbxoutpost = mbxhandle;
|
||||
|
@ -686,17 +712,78 @@ uint8_t ESC_checkSM23 (uint8_t state)
|
|||
_ESCsm2 *SM;
|
||||
ESC_read (ESCREG_SM2, (void *) &ESCvar.SM[2], sizeof (ESCvar.SM[2]));
|
||||
SM = (_ESCsm2 *) & ESCvar.SM[2];
|
||||
if ((etohs (SM->PSA) != ESC_SM2_sma) || (etohs (SM->Length) != ESCvar.ESC_SM2_sml)
|
||||
|| (SM->Command != ESC_SM2_smc) || !(SM->ActESC & ESC_SM2_act))
|
||||
|
||||
/* Check SM settings */
|
||||
if ((etohs (SM->PSA) != ESC_SM2_sma) ||
|
||||
(SM->Command != ESC_SM2_smc))
|
||||
{
|
||||
ESCvar.SMtestresult = SMRESULT_ERRSM2;
|
||||
/* fail state change */
|
||||
return (ESCpreop | ESCerror);
|
||||
}
|
||||
/* Check run-time settings */
|
||||
/* Check length */
|
||||
else if (etohs (SM->Length) != ESCvar.ESC_SM2_sml)
|
||||
{
|
||||
ESCvar.SMtestresult = SMRESULT_ERRSM2;
|
||||
/* fail state change */
|
||||
return (ESCpreop | ESCerror);
|
||||
}
|
||||
/* SM disabled and (SM activated or length > 0) set by master */
|
||||
else if (((ESC_SM2_act & ESCREG_SYNC_ACT_ACTIVATED) == 0) &&
|
||||
((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (ESCvar.ESC_SM2_sml > 0)))
|
||||
{
|
||||
ESCvar.SMtestresult = SMRESULT_ERRSM2;
|
||||
/* fail state change */
|
||||
return (ESCpreop | ESCerror);
|
||||
}
|
||||
/* SM enabled and (length > 0 but SM disabled) set by master */
|
||||
else if (((ESC_SM2_act & ESCREG_SYNC_ACT_ACTIVATED) > 0) &&
|
||||
((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) == 0) &&
|
||||
(ESCvar.ESC_SM2_sml > 0))
|
||||
{
|
||||
ESCvar.SMtestresult = SMRESULT_ERRSM2;
|
||||
/* fail state change */
|
||||
return (ESCpreop | ESCerror);
|
||||
}
|
||||
|
||||
if ((ESC_SM2_sma + (etohs (SM->Length) * 3)) > ESC_SM3_sma)
|
||||
{
|
||||
ESCvar.SMtestresult = SMRESULT_ERRSM2;
|
||||
/* SM2 overlaps SM3, fail state change */
|
||||
return (ESCpreop | ESCerror);
|
||||
}
|
||||
|
||||
ESC_read (ESCREG_SM3, (void *) &ESCvar.SM[3], sizeof (ESCvar.SM[3]));
|
||||
SM = (_ESCsm2 *) & ESCvar.SM[3];
|
||||
if ((etohs (SM->PSA) != ESC_SM3_sma) || (etohs (SM->Length) != ESCvar.ESC_SM3_sml)
|
||||
|| (SM->Command != ESC_SM3_smc) || !(SM->ActESC & ESC_SM3_act))
|
||||
/* Check SM settings */
|
||||
if ((etohs (SM->PSA) != ESC_SM3_sma) ||
|
||||
(SM->Command != ESC_SM3_smc))
|
||||
{
|
||||
ESCvar.SMtestresult = SMRESULT_ERRSM3;
|
||||
/* fail state change */
|
||||
return (ESCpreop | ESCerror);
|
||||
}
|
||||
/* Check run-time settings */
|
||||
/* Check length */
|
||||
else if (etohs (SM->Length) != ESCvar.ESC_SM3_sml)
|
||||
{
|
||||
ESCvar.SMtestresult = SMRESULT_ERRSM3;
|
||||
/* fail state change */
|
||||
return (ESCpreop | ESCerror);
|
||||
}
|
||||
/* SM disabled and (SM activated or length > 0) set by master */
|
||||
else if (((ESC_SM3_act & ESCREG_SYNC_ACT_ACTIVATED) == 0) &&
|
||||
((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (ESCvar.ESC_SM3_sml > 0)))
|
||||
{
|
||||
ESCvar.SMtestresult = SMRESULT_ERRSM3;
|
||||
/* fail state change */
|
||||
return (ESCpreop | ESCerror);
|
||||
}
|
||||
/* SM enabled and (length > 0 but SM disabled) set by master */
|
||||
else if (((ESC_SM3_act & ESCREG_SYNC_ACT_ACTIVATED) > 0) &&
|
||||
((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) == 0) &&
|
||||
(ESCvar.ESC_SM3_sml > 0))
|
||||
{
|
||||
ESCvar.SMtestresult = SMRESULT_ERRSM3;
|
||||
/* fail state change */
|
||||
|
@ -719,7 +806,12 @@ uint8_t ESC_startinput (uint8_t state)
|
|||
|
||||
if (state != (ESCpreop | ESCerror))
|
||||
{
|
||||
ESC_SMenable (3);
|
||||
/* If inputs > 0 , enable SM3 */
|
||||
if (ESCvar.ESC_SM3_sml > 0)
|
||||
{
|
||||
ESC_SMenable (3);
|
||||
}
|
||||
/* Go to state input regardless of any inputs present */
|
||||
CC_ATOMIC_SET(ESCvar.App.state, APPSTATE_INPUT);
|
||||
}
|
||||
else
|
||||
|
@ -759,15 +851,22 @@ uint8_t ESC_startinput (uint8_t state)
|
|||
{
|
||||
if (ESCvar.esc_hw_interrupt_enable != NULL)
|
||||
{
|
||||
if(ESCvar.dcsync > 0)
|
||||
uint32_t int_mask;
|
||||
|
||||
if (ESCvar.ESC_SM2_sml == 0)
|
||||
{
|
||||
ESCvar.esc_hw_interrupt_enable(ESCREG_ALEVENT_DC_SYNC0 |
|
||||
ESCREG_ALEVENT_SM2);
|
||||
int_mask = ESCREG_ALEVENT_SM3;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESCvar.esc_hw_interrupt_enable(ESCREG_ALEVENT_SM2);
|
||||
int_mask = ESCREG_ALEVENT_SM2;
|
||||
}
|
||||
|
||||
if (ESCvar.dcsync > 0)
|
||||
{
|
||||
int_mask |= ESCREG_ALEVENT_DC_SYNC0;
|
||||
}
|
||||
ESCvar.esc_hw_interrupt_enable (int_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -790,7 +889,8 @@ void ESC_stopinput (void)
|
|||
(ESCvar.esc_hw_interrupt_disable != NULL))
|
||||
{
|
||||
ESCvar.esc_hw_interrupt_disable (ESCREG_ALEVENT_DC_SYNC0 |
|
||||
ESCREG_ALEVENT_SM2);
|
||||
ESCREG_ALEVENT_SM2 |
|
||||
ESCREG_ALEVENT_SM3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -804,8 +904,13 @@ void ESC_stopinput (void)
|
|||
*/
|
||||
uint8_t ESC_startoutput (uint8_t state)
|
||||
{
|
||||
|
||||
ESC_SMenable (2);
|
||||
|
||||
/* If outputs > 0 , enable SM2 */
|
||||
if (ESCvar.ESC_SM2_sml > 0)
|
||||
{
|
||||
ESC_SMenable (2);
|
||||
}
|
||||
/* Go to state output regardless of any outputs present */
|
||||
CC_ATOMIC_OR(ESCvar.App.state, APPSTATE_OUTPUT);
|
||||
return state;
|
||||
|
||||
|
@ -912,6 +1017,75 @@ void ESC_sm_act_event (void)
|
|||
ESC_SMack (7);
|
||||
}
|
||||
}
|
||||
|
||||
static bool ESC_check_id_request (uint16_t ALcontrol, uint8_t * an)
|
||||
{
|
||||
if ((ALcontrol & ESCREG_AL_ID_REQUEST) != 0)
|
||||
{
|
||||
uint8_t state = ALcontrol & ESCREG_AL_ERRACKMASK;
|
||||
|
||||
if ((state != ESCboot) &&
|
||||
((state < ESCsafeop) || (*an == ESCsafeop) || (*an == ESCop)))
|
||||
{
|
||||
uint16_t ALstatuscode;
|
||||
|
||||
ESC_read (ESCREG_ALERROR,
|
||||
(void *)&ALstatuscode,
|
||||
sizeof (ALstatuscode));
|
||||
|
||||
return (ALstatuscode == ALERR_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint8_t ESC_load_device_id (void)
|
||||
{
|
||||
uint16_t device_id;
|
||||
|
||||
if (ESCvar.get_device_id != NULL)
|
||||
{
|
||||
if (ESCvar.get_device_id (&device_id) != 0)
|
||||
{
|
||||
device_id = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESC_read (ESCREG_CONF_STATION_ALIAS,
|
||||
(void *)&device_id,
|
||||
sizeof (device_id));
|
||||
}
|
||||
|
||||
if (device_id != 0)
|
||||
{
|
||||
/* Load the Device Identification Value to the AL Status Code register */
|
||||
ESC_ALerror (device_id);
|
||||
|
||||
return ESCREG_AL_ID_REQUEST;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ESC_DEBUG
|
||||
static char * ESC_state_to_string (uint8_t ESC_state)
|
||||
{
|
||||
switch (ESC_state)
|
||||
{
|
||||
case ESCinit: return "Init";
|
||||
case ESCpreop: return "Pre-Operational";
|
||||
case ESCboot: return "Bootstrap";
|
||||
case ESCsafeop: return "Safe-Operational";
|
||||
case ESCop: return "Operational";
|
||||
case ESCerror: return "Error";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
#endif
|
||||
|
||||
/** The state handler acting on ALControl Bit(0)
|
||||
* events in the Al Event Request register 0x220.
|
||||
*
|
||||
|
@ -950,7 +1124,7 @@ void ESC_state (void)
|
|||
}
|
||||
|
||||
/* Mask high bits ALcommand, low bits ALstatus */
|
||||
as = (ac << 4) | (as & 0x0f);
|
||||
as = (uint8_t)((ac << 4) | (as & 0x0f));
|
||||
|
||||
/* Call post state change hook case it have been configured */
|
||||
if (ESCvar.pre_state_change_hook != NULL)
|
||||
|
@ -973,7 +1147,6 @@ void ESC_state (void)
|
|||
{
|
||||
/* get station address */
|
||||
ESC_address ();
|
||||
COE_initDefaultSyncMgrPara ();
|
||||
an = ESC_startmbx (ac);
|
||||
break;
|
||||
}
|
||||
|
@ -1031,8 +1204,24 @@ void ESC_state (void)
|
|||
case PREOP_TO_SAFEOP:
|
||||
case SAFEOP_TO_SAFEOP:
|
||||
{
|
||||
ESCvar.ESC_SM2_sml = sizeOfPDO (RX_PDO_OBJIDX);
|
||||
ESCvar.ESC_SM3_sml = sizeOfPDO (TX_PDO_OBJIDX);
|
||||
ESCvar.ESC_SM2_sml = sizeOfPDO (RX_PDO_OBJIDX, &ESCvar.sm2mappings,
|
||||
SMmap2, MAX_MAPPINGS_SM2);
|
||||
if (ESCvar.sm2mappings < 0)
|
||||
{
|
||||
an = ESCpreop | ESCerror;
|
||||
ESC_ALerror (ALERR_INVALIDOUTPUTSM);
|
||||
break;
|
||||
}
|
||||
|
||||
ESCvar.ESC_SM3_sml = sizeOfPDO (TX_PDO_OBJIDX, &ESCvar.sm3mappings,
|
||||
SMmap3, MAX_MAPPINGS_SM3);
|
||||
if (ESCvar.sm3mappings < 0)
|
||||
{
|
||||
an = ESCpreop | ESCerror;
|
||||
ESC_ALerror (ALERR_INVALIDINPUTSM);
|
||||
break;
|
||||
}
|
||||
|
||||
an = ESC_startinput (ac);
|
||||
if (an == ac)
|
||||
{
|
||||
|
@ -1075,6 +1264,11 @@ void ESC_state (void)
|
|||
an = ESCsafeop | ESCerror;
|
||||
ESC_ALerror (ALERR_INVALIDSTATECHANGE);
|
||||
ESC_stopoutput ();
|
||||
/* If no outputs present, we need to flag error using SM3 */
|
||||
if (ESCvar.ESC_SM2_sml == 0 && ESCvar.ESC_SM3_sml > 0)
|
||||
{
|
||||
ESC_SMdisable (3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_TO_SAFEOP:
|
||||
|
@ -1088,6 +1282,11 @@ void ESC_state (void)
|
|||
if (an == ESCop)
|
||||
{
|
||||
ESC_stopoutput ();
|
||||
/* If no outputs present, we need to flag error using SM3 */
|
||||
if (ESCvar.ESC_SM2_sml == 0 && ESCvar.ESC_SM3_sml > 0)
|
||||
{
|
||||
ESC_SMdisable (3);
|
||||
}
|
||||
an = ESCsafeop;
|
||||
}
|
||||
if (as == ESCsafeop)
|
||||
|
@ -1112,8 +1311,16 @@ void ESC_state (void)
|
|||
ESC_ALerror (ALERR_NONE);
|
||||
}
|
||||
|
||||
if (ESC_check_id_request (ESCvar.ALcontrol, &an))
|
||||
{
|
||||
an |= ESC_load_device_id ();
|
||||
}
|
||||
|
||||
ESC_ALstatus (an);
|
||||
|
||||
#ifdef ESC_DEBUG
|
||||
DPRINT ("state %s\n", ESC_state_to_string (an & 0xF));
|
||||
#endif
|
||||
}
|
||||
/** Function copying the application configuration variable
|
||||
* data to the stack local variable.
|
||||
|
@ -1123,29 +1330,35 @@ void ESC_state (void)
|
|||
*/
|
||||
void ESC_config (esc_cfg_t * cfg)
|
||||
{
|
||||
/* Copy configuration data */
|
||||
static sm_cfg_t mb0 = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0};
|
||||
static sm_cfg_t mb1 = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0};
|
||||
static sm_cfg_t mbboot0 = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0};
|
||||
static sm_cfg_t mbboot1 = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0};
|
||||
|
||||
/* Configure stack */
|
||||
ESCvar.use_interrupt = cfg->use_interrupt;
|
||||
ESCvar.watchdogcnt = cfg->watchdog_cnt;
|
||||
ESCvar.mbxsize = cfg->mbxsize;
|
||||
ESCvar.mbxsizeboot = cfg->mbxsizeboot;
|
||||
ESCvar.mbxbuffers = cfg->mbxbuffers;
|
||||
|
||||
ESCvar.mb[0] = cfg->mb[0];
|
||||
ESCvar.mb[1] = cfg->mb[1];
|
||||
ESCvar.mbboot[0] = cfg->mb_boot[0];
|
||||
ESCvar.mbboot[1] = cfg->mb_boot[1];
|
||||
ESCvar.pdosm[0] = cfg->pdosm[0];
|
||||
ESCvar.pdosm[1] = cfg->pdosm[1];
|
||||
ESCvar.mb[0] = mb0;
|
||||
ESCvar.mb[1] = mb1;
|
||||
ESCvar.mbboot[0] = mbboot0;
|
||||
ESCvar.mbboot[1] = mbboot1;
|
||||
|
||||
ESCvar.skip_default_initialization = cfg->skip_default_initialization;
|
||||
ESCvar.set_defaults_hook = cfg->set_defaults_hook;
|
||||
ESCvar.pre_state_change_hook = cfg->pre_state_change_hook;
|
||||
ESCvar.post_state_change_hook = cfg->post_state_change_hook;
|
||||
ESCvar.application_hook = cfg->application_hook;
|
||||
ESCvar.safeoutput_override = cfg->safeoutput_override;
|
||||
ESCvar.pre_object_download_hook = cfg->pre_object_download_hook;
|
||||
ESCvar.post_object_download_hook = cfg->post_object_download_hook;
|
||||
ESCvar.pre_object_upload_hook = cfg->pre_object_upload_hook;
|
||||
ESCvar.post_object_upload_hook = cfg->post_object_upload_hook;
|
||||
ESCvar.rxpdo_override = cfg->rxpdo_override;
|
||||
ESCvar.txpdo_override = cfg->txpdo_override;
|
||||
ESCvar.esc_hw_interrupt_enable = cfg->esc_hw_interrupt_enable;
|
||||
ESCvar.esc_hw_interrupt_disable = cfg->esc_hw_interrupt_disable;
|
||||
ESCvar.esc_hw_eep_handler = cfg->esc_hw_eep_handler;
|
||||
ESCvar.esc_check_dc_handler = cfg->esc_check_dc_handler;
|
||||
ESCvar.get_device_id = cfg->get_device_id;
|
||||
}
|
||||
|
|
229
soes/esc.h
229
soes/esc.h
|
@ -11,12 +11,18 @@
|
|||
#ifndef __esc__
|
||||
#define __esc__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <cc.h>
|
||||
#include <esc_coe.h>
|
||||
#include "options.h"
|
||||
|
||||
#define ESCREG_ADDRESS 0x0010
|
||||
#define ESCREG_CONF_STATION_ALIAS 0x0012
|
||||
#define ESCREG_DLSTATUS 0x0110
|
||||
#define ESCREG_ALCONTROL 0x0120
|
||||
#define ESCREG_ALCONTROL_ERROR_ACK 0x0010
|
||||
#define ESCREG_ALSTATUS 0x0130
|
||||
#define ESCREG_ALSTATUS_ERROR_IND 0x0010
|
||||
#define ESCREG_ALERROR 0x0134
|
||||
#define ESCREG_ALEVENTMASK 0x0204
|
||||
#define ESCREG_ALEVENT 0x0220
|
||||
|
@ -27,6 +33,7 @@
|
|||
#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
|
||||
|
@ -36,11 +43,13 @@
|
|||
#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
|
||||
|
@ -52,6 +61,7 @@
|
|||
#define ESCREG_AL_STATEMASK 0x001f
|
||||
#define ESCREG_AL_ALLBUTINITMASK 0x0e
|
||||
#define ESCREG_AL_ERRACKMASK 0x0f
|
||||
#define ESCREG_AL_ID_REQUEST 0x0020
|
||||
|
||||
#define SYNCTYPE_SUPPORT_FREERUN 0x01
|
||||
#define SYNCTYPE_SUPPORT_SYNCHRON 0x02
|
||||
|
@ -93,6 +103,8 @@
|
|||
#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
|
||||
|
@ -100,12 +112,49 @@
|
|||
#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
|
||||
|
@ -117,15 +166,41 @@
|
|||
#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
|
||||
|
@ -135,9 +210,9 @@
|
|||
#define MBXstate_backup 0x05
|
||||
#define MBXstate_again 0x06
|
||||
|
||||
#define COE_DEFAULTLENGTH 0x0a
|
||||
#define COE_HEADERSIZE 0x0a
|
||||
#define COE_SEGMENTHEADERSIZE 0x03
|
||||
#define COE_DEFAULTLENGTH 0x0AU
|
||||
#define COE_HEADERSIZE 0x0AU
|
||||
#define COE_SEGMENTHEADERSIZE 0x03U
|
||||
#define COE_SDOREQUEST 0x02
|
||||
#define COE_SDORESPONSE 0x03
|
||||
#define COE_SDOINFORMATION 0x08
|
||||
|
@ -146,7 +221,10 @@
|
|||
#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
|
||||
|
@ -193,6 +271,7 @@
|
|||
#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
|
||||
|
@ -206,10 +285,19 @@
|
|||
#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_BUFFER_SIZE (PREALLOC_FACTOR * MBXSIZE)
|
||||
|
||||
typedef struct sm_cfg
|
||||
{
|
||||
uint16_t cfg_sma;
|
||||
|
@ -224,23 +312,35 @@ typedef struct esc_cfg
|
|||
void * user_arg;
|
||||
int use_interrupt;
|
||||
int watchdog_cnt;
|
||||
size_t mbxsize;
|
||||
size_t mbxsizeboot;
|
||||
int mbxbuffers;
|
||||
sm_cfg_t mb[2];
|
||||
sm_cfg_t mb_boot[2];
|
||||
sm_cfg_t pdosm[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);
|
||||
int (*pre_object_download_hook) (uint16_t index, uint8_t subindex);
|
||||
void (*post_object_download_hook) (uint16_t index, uint8_t subindex);
|
||||
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);
|
||||
int (*get_device_id) (uint16_t * device_id);
|
||||
} esc_cfg_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -331,36 +431,47 @@ typedef struct CC_PACKED
|
|||
} _ESCsmCompact;
|
||||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct CC_PACKED
|
||||
typedef struct
|
||||
{
|
||||
/* Configuration input is saved so the user variable may go out-of-scope */
|
||||
int use_interrupt;
|
||||
size_t mbxsize;
|
||||
size_t mbxsizeboot;
|
||||
int mbxbuffers;
|
||||
sm_cfg_t mb[2];
|
||||
sm_cfg_t mbboot[2];
|
||||
sm_cfg_t pdosm[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);
|
||||
int (*pre_object_download_hook) (uint16_t index, uint8_t subindex);
|
||||
void (*post_object_download_hook) (uint16_t index, uint8_t subindex);
|
||||
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);
|
||||
int (*get_device_id) (uint16_t * device_id);
|
||||
uint8_t MBXrun;
|
||||
size_t activembxsize;
|
||||
uint32_t activembxsize;
|
||||
sm_cfg_t * activemb0;
|
||||
sm_cfg_t * activemb1;
|
||||
uint16_t ESC_SM2_sml;
|
||||
uint16_t ESC_SM3_sml;
|
||||
uint16_t TXPDOsize;
|
||||
uint16_t RXPDOsize;
|
||||
uint8_t dcsync;
|
||||
uint16_t synccounterlimit;
|
||||
uint16_t ALstatus;
|
||||
|
@ -378,33 +489,28 @@ typedef struct CC_PACKED
|
|||
uint8_t segmented;
|
||||
void *data;
|
||||
uint16_t entries;
|
||||
uint16_t frags;
|
||||
uint16_t fragsleft;
|
||||
uint32_t frags;
|
||||
uint32_t fragsleft;
|
||||
uint16_t index;
|
||||
uint8_t subindex;
|
||||
uint16_t flags;
|
||||
|
||||
#if defined(EC_LITTLE_ENDIAN)
|
||||
uint8_t r1:1;
|
||||
uint8_t toggle:1;
|
||||
uint8_t r2:6;
|
||||
#endif
|
||||
uint8_t toggle;
|
||||
|
||||
#if defined(EC_BIG_ENDIAN)
|
||||
uint8_t r2:6;
|
||||
uint8_t toggle:1;
|
||||
uint8_t r1:1;
|
||||
#endif
|
||||
int sm2mappings;
|
||||
int sm3mappings;
|
||||
|
||||
uint8_t SMtestresult;
|
||||
int16_t temp;
|
||||
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 uint32_t ALevent;
|
||||
volatile int8_t synccounter;
|
||||
volatile _App App;
|
||||
uint8_t mbxdata[PREALLOC_BUFFER_SIZE];
|
||||
} _ESCvar;
|
||||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct CC_PACKED
|
||||
|
@ -473,7 +579,7 @@ typedef struct CC_PACKED
|
|||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct CC_PACKED
|
||||
typedef struct CC_PACKED CC_ALIGNED(4)
|
||||
{
|
||||
_MBXh mbxheader;
|
||||
_COEh coeheader;
|
||||
|
@ -485,7 +591,7 @@ typedef struct CC_PACKED
|
|||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct CC_PACKED
|
||||
typedef struct CC_PACKED CC_ALIGNED(4)
|
||||
{
|
||||
_MBXh mbxheader;
|
||||
_COEh coeheader;
|
||||
|
@ -541,6 +647,28 @@ typedef struct CC_PACKED
|
|||
};
|
||||
} _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
|
||||
|
@ -565,18 +693,20 @@ typedef struct
|
|||
#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 (ESCvar.mbxbuffers)
|
||||
#define ESC_SM2_sma (ESCvar.pdosm[0].cfg_sma)
|
||||
#define ESC_SM2_smc (ESCvar.pdosm[0].cfg_smc)
|
||||
#define ESC_SM2_act (ESCvar.pdosm[0].cfg_smact)
|
||||
#define ESC_SM3_sma (ESCvar.pdosm[1].cfg_sma)
|
||||
#define ESC_SM3_smc (ESCvar.pdosm[1].cfg_smc)
|
||||
#define ESC_SM3_act (ESCvar.pdosm[1].cfg_smact)
|
||||
#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_MBXHSIZE ((uint32_t)sizeof(_MBXh))
|
||||
#define ESC_MBXDSIZE (ESC_MBXSIZE - ESC_MBXHSIZE)
|
||||
#define ESC_FOEHSIZE sizeof(_FOEh)
|
||||
#define ESC_FOEHSIZE (uint32_t)sizeof(_FOEh)
|
||||
#define ESC_FOE_DATA_SIZE (ESC_MBXSIZE - (ESC_MBXHSIZE +ESC_FOEHSIZE))
|
||||
#define ESC_EOEHSIZE ((uint32_t)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);
|
||||
|
@ -585,6 +715,7 @@ 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);
|
||||
|
@ -611,6 +742,8 @@ 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
|
||||
|
|
1533
soes/esc_coe.c
1533
soes/esc_coe.c
File diff suppressed because it is too large
Load Diff
|
@ -13,21 +13,20 @@
|
|||
|
||||
#include <cc.h>
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct CC_PACKED
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t subindex;
|
||||
uint16_t datatype;
|
||||
uint16_t bitlength;
|
||||
uint16_t access;
|
||||
uint16_t flags;
|
||||
const char *name;
|
||||
uint32_t value;
|
||||
void *data;
|
||||
} _objd;
|
||||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct CC_PACKED
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t index;
|
||||
uint16_t objtype;
|
||||
|
@ -36,7 +35,14 @@ typedef struct CC_PACKED
|
|||
const char *name;
|
||||
const _objd *objdesc;
|
||||
} _objectlist;
|
||||
CC_PACKED_END
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const _objd * obj;
|
||||
const _objectlist * objectlistitem;
|
||||
uint32_t offset;
|
||||
} _SMmap;
|
||||
|
||||
#define OBJH_READ 0
|
||||
#define OBJH_WRITE 1
|
||||
|
@ -66,6 +72,9 @@ CC_PACKED_END
|
|||
#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
|
||||
|
@ -74,24 +83,56 @@ CC_PACKED_END
|
|||
#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_RO 0x07
|
||||
#define ATYPE_RW 0x3F
|
||||
#define ATYPE_RWpre 0x0F
|
||||
#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_BACKUP 0x100
|
||||
#define ATYPE_SETTING 0x200
|
||||
|
||||
#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 ATYPE_RWop (ATYPE_Wop | ATYPE_RO)
|
||||
#define ATYPE_RWpre_safe (ATYPE_Wpre | ATYPE_Wsafe | ATYPE_RO)
|
||||
|
||||
#define TX_PDO_OBJIDX 0x1c13
|
||||
#define RX_PDO_OBJIDX 0x1c12
|
||||
|
||||
void ESC_coeprocess (void);
|
||||
uint16_t sizeOfPDO (uint16_t index);
|
||||
void SDO_abort (uint16_t index, uint8_t subindex, uint32_t abortcode);
|
||||
void COE_initDefaultSyncMgrPara (void);
|
||||
int COE_getSyncMgrPara (uint16_t index, uint8_t subindex, void * buf, uint16_t datatype);
|
||||
#define COMPLETE_ACCESS_FLAG (1 << 15)
|
||||
|
||||
extern void ESC_objecthandler (uint16_t index, uint8_t subindex);
|
||||
extern int ESC_pre_objecthandler (uint16_t index, uint8_t subindex);
|
||||
void ESC_coeprocess (void);
|
||||
int16_t SDO_findsubindex (int32_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 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
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <string.h>
|
||||
|
||||
static uint8_t eep_buf[8];
|
||||
static uint16_t eep_read_size = 8U;
|
||||
static void (*eep_reload_ptr)(eep_stat_t *stat) = NULL;
|
||||
|
||||
/** EPP periodic task of ESC side EEPROM emulation.
|
||||
*
|
||||
|
@ -51,19 +53,53 @@ void EEP_process (void)
|
|||
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) {
|
||||
if (EEP_read (stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, eep_read_size) != 0) {
|
||||
stat.contstat.bits.ackErr = 1;
|
||||
} else {
|
||||
ESC_write (ESCREG_EEDATA, eep_buf, EEP_READ_SIZE);
|
||||
}
|
||||
else {
|
||||
ESC_write(ESCREG_EEDATA, eep_buf, eep_read_size);
|
||||
}
|
||||
break;
|
||||
|
||||
case EEP_CMD_RELOAD:
|
||||
/* user defined reload if set */
|
||||
if (eep_reload_ptr != NULL) {
|
||||
/* Reload function is responsible to update
|
||||
* control status register bits.
|
||||
*/
|
||||
(*eep_reload_ptr)(&stat);
|
||||
}
|
||||
else {
|
||||
if (eep_read_size == 8U) {
|
||||
/* handle reload request */
|
||||
if (EEP_read(stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, eep_read_size) != 0) {
|
||||
stat.contstat.bits.ackErr = 1;
|
||||
}
|
||||
else {
|
||||
ESC_write(ESCREG_EEDATA, eep_buf, eep_read_size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Default handler of reload request for 4 Byte read, load config alias.
|
||||
* To support other ESC behavior, implement user defined reload.
|
||||
*/
|
||||
if (EEP_read(EEP_CONFIG_ALIAS_WORD_OFFSET * 2U /* sizeof(uint16_t) */,
|
||||
eep_buf,
|
||||
2U /* 2 Bytes config alias*/) != 0) {
|
||||
stat.contstat.bits.ackErr = 1;
|
||||
}
|
||||
else {
|
||||
ESC_write(ESCREG_EEDATA, eep_buf, 2U /* 2 Bytes config alias*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
if (EEP_write (stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, EEP_WRITE_SIZE) != 0) {
|
||||
stat.contstat.bits.ackErr = 1;
|
||||
}
|
||||
break;
|
||||
|
@ -78,3 +114,24 @@ void EEP_process (void)
|
|||
}
|
||||
}
|
||||
|
||||
/** EPP Set read size, 4 Byte or 8 Byte depending on ESC.
|
||||
* Default 8 Byte.
|
||||
*/
|
||||
void EEP_set_read_size (uint16_t read_size)
|
||||
{
|
||||
if ((read_size == 8U) || (read_size == 4U)) {
|
||||
eep_read_size = read_size;
|
||||
}
|
||||
}
|
||||
|
||||
/** EPP Set reload function pointer.
|
||||
* Function shall update current stat accordingly.
|
||||
* Eg. on CRC error reload function shall set
|
||||
* stat.contstat.bits.csumErr = 1
|
||||
* stat.contstat.bits.ackErr = 1
|
||||
*
|
||||
*/
|
||||
void EEP_set_reload_function_pointer(void (*reload_ptr)(eep_stat_t* stat))
|
||||
{
|
||||
eep_reload_ptr = reload_ptr;
|
||||
}
|
||||
|
|
|
@ -15,14 +15,16 @@
|
|||
#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
|
||||
#define EEP_CMD_IDLE 0x0
|
||||
#define EEP_CMD_READ 0x1
|
||||
#define EEP_CMD_WRITE 0x2
|
||||
#define EEP_CMD_RELOAD 0x4
|
||||
|
||||
/* read/write size */
|
||||
#define EEP_READ_SIZE 8
|
||||
#define EEP_WRITE_SIZE 2
|
||||
/* write size */
|
||||
#define EEP_WRITE_SIZE 2
|
||||
|
||||
/* EEPROm word offset */
|
||||
#define EEP_CONFIG_ALIAS_WORD_OFFSET 4
|
||||
|
||||
/* CONSTAT register content */
|
||||
typedef struct CC_PACKED
|
||||
|
@ -69,6 +71,80 @@ typedef union eep_config
|
|||
/* periodic task */
|
||||
void EEP_process (void);
|
||||
|
||||
/**
|
||||
* Application Notes: EEPROM emulation
|
||||
*
|
||||
* NOTE: Special handling needed when 4 Byte read is supported.
|
||||
*
|
||||
* Ref. ET1100 Datasheet sec2_registers_3i0, chapter 2.45.1,
|
||||
* "EEPROM emulation with 32 bit EEPROM data register (0x0502[6]=0)".
|
||||
*
|
||||
* For a Reload command, fill the EEPROM Data register with the
|
||||
* values shown in the chapter 2.45.1 before acknowledging
|
||||
* the command. These values are automatically transferred to the
|
||||
* designated registers after the Reload command is acknowledged.
|
||||
*
|
||||
* NOTE: When 4 Byte read is supported, EEP_process will only load
|
||||
* config alias on reload.
|
||||
*
|
||||
* NOTE: EEP_process support implementing a custom reload function
|
||||
* for both 4 Byte and 8 Byte read support.
|
||||
*
|
||||
* NOTE: Code snippet for custom reload function when 4 Byte read is supported.
|
||||
*
|
||||
* void reload_ptr(eep_stat_t *stat)
|
||||
* {
|
||||
* eep_config_t ee_cfg;
|
||||
*
|
||||
* // Read configuration area
|
||||
* EEP_read(0, &ee_cfg, sizeof(ee_cfg);
|
||||
*
|
||||
* // Check CRC
|
||||
* if(is_crc_ok(&ee_cfg) == true)
|
||||
* {
|
||||
* // Write config alias to EEPROM data registers.
|
||||
* // Will be loaded to 0x12:13 on command ack.
|
||||
* ESC_write(ESCREG_EEDATA,
|
||||
* &ee_cfg.configured_station_alias,
|
||||
* sizeof(configured_station_alias));
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // Indicate CRC error
|
||||
* stat->contstat.bits.csumErr = 1;
|
||||
* stat->contstat.bits.ackErr = 1;
|
||||
* }
|
||||
* }
|
||||
* NOTE: Code snippet for custom reload function when 8 Byte read is supported.
|
||||
*
|
||||
* void reload_ptr(eep_stat_t *stat)
|
||||
* {
|
||||
* eep_config_t ee_cfg;
|
||||
*
|
||||
* // Read configuration area
|
||||
* EEP_read(0, &ee_cfg, sizeof(ee_cfg);
|
||||
*
|
||||
* // Check CRC
|
||||
* if(is_crc_ok(&ee_cfg) == true)
|
||||
* {
|
||||
* // Load EEPROM data at requested EEPROM address
|
||||
* EEP_read (stat->addr * sizeof(uint16_t), eep_buf, 8U);
|
||||
* // Write loaded data to EEPROM data registers
|
||||
* ESC_write(ESCREG_EEDATA, eep_buf, 8U);
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // Indicate CRC error
|
||||
* stat->contstat.bits.csumErr = 1;
|
||||
* stat->contstat.bits.ackErr = 1;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/* Set eep internal variables */
|
||||
void EEP_set_read_size (uint16_t read_size);
|
||||
void EEP_set_reload_function_pointer (void (*reload_ptr)(eep_stat_t *stat));
|
||||
|
||||
/* From hardware file */
|
||||
void EEP_init (void);
|
||||
int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t size);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
152
soes/esc_foe.c
152
soes/esc_foe.c
|
@ -26,20 +26,16 @@
|
|||
|
||||
/** Variable holding current filename read at FOE Open.
|
||||
*/
|
||||
char foe_file_name[FOE_FN_MAX + 1];
|
||||
static char foe_file_name[FOE_FN_MAX + 1];
|
||||
|
||||
|
||||
/** Main FoE configuration pointer data array. Structure i allocated and filled
|
||||
* by the application defining what preferences it require.
|
||||
/** 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;
|
||||
/** Collection of files possible to receive by FoE. Structure i allocated and
|
||||
* filled by the application defining what preferences it require.
|
||||
*/
|
||||
static foe_writefile_cfg_t * foe_files;
|
||||
/** Pointer to current file configuration item used by FoE.
|
||||
*/
|
||||
static foe_writefile_cfg_t * foe_file;
|
||||
static foe_file_cfg_t * foe_file;
|
||||
/** Main FoE status data array. Structure gets filled with current status
|
||||
* variables during FoE usage.
|
||||
*/
|
||||
|
@ -54,7 +50,7 @@ static _FOEvar FOEvar;
|
|||
* @return 0= if we succeed, FOE_ERR_NOTFOUND something wrong with filename or
|
||||
* password
|
||||
*/
|
||||
int FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
|
||||
static uint32_t FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
|
@ -73,10 +69,21 @@ int FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
|
|||
/* Figure out what file they're talking about. */
|
||||
for (i = 0; i < foe_cfg->n_files; i++)
|
||||
{
|
||||
if ((0 == strncmp (foe_file_name, foe_files[i].name, num_chars)) &&
|
||||
(pass == foe_files[i].filepass))
|
||||
if (0 == strncmp (foe_file_name, foe_cfg->files[i].name, num_chars))
|
||||
{
|
||||
foe_file = &foe_files[i];
|
||||
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)
|
||||
|
@ -84,13 +91,13 @@ int FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
|
|||
case FOE_OP_RRQ:
|
||||
{
|
||||
FOEvar.fposition = 0;
|
||||
FOEvar.fend = foe_files[i].max_data;
|
||||
FOEvar.fend = foe_cfg->files[i].max_data;
|
||||
return 0;
|
||||
}
|
||||
case FOE_OP_WRQ:
|
||||
{
|
||||
FOEvar.fposition = 0;
|
||||
FOEvar.fend = foe_files[i].max_data;
|
||||
FOEvar.fend = foe_cfg->files[i].max_data;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -111,14 +118,14 @@ int FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
|
|||
|
||||
* @return Number of copied bytes.
|
||||
*/
|
||||
uint16_t FOE_fread (uint8_t * data, uint16_t maxlength)
|
||||
static uint32_t FOE_fread (uint8_t * data, uint32_t maxlength)
|
||||
{
|
||||
uint16_t ncopied = 0;
|
||||
uint32_t ncopied = 0;
|
||||
|
||||
while (maxlength && (FOEvar.fend - FOEvar.fposition))
|
||||
{
|
||||
maxlength--;
|
||||
*(data++) = fbuffer[FOEvar.fposition++];
|
||||
*(data++) = foe_cfg->fbuffer[FOEvar.fposition++];
|
||||
ncopied++;
|
||||
}
|
||||
|
||||
|
@ -137,9 +144,9 @@ uint16_t FOE_fread (uint8_t * data, uint16_t maxlength)
|
|||
|
||||
* @return Number of copied bytes.
|
||||
*/
|
||||
uint16_t FOE_fwrite (uint8_t *data, uint16_t length)
|
||||
static uint32_t FOE_fwrite (uint8_t *data, uint32_t length)
|
||||
{
|
||||
uint16_t ncopied = 0;
|
||||
uint32_t ncopied = 0;
|
||||
uint32_t failed = 0;
|
||||
|
||||
DPRINT("FOE_fwrite\n");
|
||||
|
@ -150,17 +157,24 @@ uint16_t FOE_fwrite (uint8_t *data, uint16_t length)
|
|||
foe_cfg->fbuffer[FOEvar.fbufposition++] = *(data++);
|
||||
if(FOEvar.fbufposition >= foe_cfg->buffer_size)
|
||||
{
|
||||
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer);
|
||||
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++;
|
||||
if(failed)
|
||||
{
|
||||
DPRINT("Failed FOE_fwrite ncopied=%"PRIu32"\n", ncopied);
|
||||
}
|
||||
else
|
||||
{
|
||||
ncopied++;
|
||||
}
|
||||
}
|
||||
|
||||
foe_file->total_size += ncopied;
|
||||
|
||||
DPRINT("FOE_fwrite END with : %d\n",ncopied);
|
||||
DPRINT("FOE_fwrite END with : %"PRIu32"\n",ncopied);
|
||||
return ncopied;
|
||||
}
|
||||
|
||||
|
@ -170,25 +184,16 @@ uint16_t FOE_fwrite (uint8_t *data, uint16_t length)
|
|||
*
|
||||
* @return Number of copied bytes on success, 0= if failed.
|
||||
*/
|
||||
uint32_t FOE_fclose (void)
|
||||
static uint32_t FOE_fclose (void)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t failed = 0;
|
||||
|
||||
DPRINT("FOE_fclose\n");
|
||||
if (FOEvar.fbufposition)
|
||||
{
|
||||
|
||||
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer, FOEvar.fbufposition);
|
||||
foe_file->address_offset += FOEvar.fbufposition;
|
||||
FOEvar.fbufposition = 0;
|
||||
|
||||
DPRINT("FOE_fclose EXTRA write\n");
|
||||
for(i = FOEvar.fbufposition; i < foe_cfg->buffer_size; i++)
|
||||
{
|
||||
foe_cfg->fbuffer[FOEvar.fbufposition++] = foe_cfg->empty_write;
|
||||
}
|
||||
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer);
|
||||
FOEvar.fbufposition = 0;
|
||||
foe_file->address_offset += foe_cfg->buffer_size;
|
||||
DPRINT("FOE_fclose EXTRA write ended\n");
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
|
@ -209,7 +214,7 @@ void FOE_init ()
|
|||
*
|
||||
* @param[in] code = abort code
|
||||
*/
|
||||
void FOE_abort (uint32_t code)
|
||||
static void FOE_abort (uint32_t code)
|
||||
{
|
||||
_FOE *foembx;
|
||||
uint8_t mbxhandle;
|
||||
|
@ -229,7 +234,7 @@ void FOE_abort (uint32_t code)
|
|||
}
|
||||
/* Nothing we can do if we can't get an outbound mailbox. */
|
||||
}
|
||||
DPRINT("FOE_abort: 0x%X\n", code);
|
||||
DPRINT("FOE_abort: 0x%"PRIX32"\n", code);
|
||||
FOE_init ();
|
||||
}
|
||||
|
||||
|
@ -244,21 +249,21 @@ void FOE_abort (uint32_t code)
|
|||
* @return Number of data bytes written or an error number. Error numbers
|
||||
* will be greater than FOE_DATA_SIZE.
|
||||
*/
|
||||
int FOE_send_data_packet ()
|
||||
static uint32_t FOE_send_data_packet ()
|
||||
{
|
||||
_FOE *foembx;
|
||||
uint16_t data_len;
|
||||
uint32_t data_len;
|
||||
uint8_t mbxhandle;
|
||||
|
||||
mbxhandle = ESC_claimbuffer ();
|
||||
if (mbxhandle)
|
||||
{
|
||||
foembx = (_FOE *) &MBX[mbxhandle * ESC_MBXSIZE];
|
||||
data_len = FOE_fread (foembx->data, FOE_DATA_SIZE);
|
||||
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 + FOEHSIZE);
|
||||
foembx->mbxheader.length = htoes (data_len + ESC_FOEHSIZE);
|
||||
foembx->mbxheader.mbxtype = MBXFOE;
|
||||
/* Mark the outbound mailbox as filled. */
|
||||
MBXcontrol[mbxhandle].state = MBXstate_outreq;
|
||||
|
@ -275,7 +280,7 @@ int FOE_send_data_packet ()
|
|||
|
||||
* @return 0= or error number.
|
||||
*/
|
||||
int FOE_send_ack ()
|
||||
static uint32_t FOE_send_ack ()
|
||||
{
|
||||
_FOE *foembx;
|
||||
uint8_t mbxhandle;
|
||||
|
@ -308,12 +313,12 @@ int FOE_send_ack ()
|
|||
* On error we will send FOE Abort.
|
||||
*
|
||||
*/
|
||||
void FOE_read ()
|
||||
static void FOE_read ()
|
||||
{
|
||||
_FOE *foembx;
|
||||
uint32_t data_len;
|
||||
uint32_t password;
|
||||
int res;
|
||||
uint32_t res;
|
||||
uint8_t data_len;
|
||||
|
||||
if (FOEvar.foestate != FOE_READY)
|
||||
{
|
||||
|
@ -324,7 +329,7 @@ void FOE_read ()
|
|||
FOE_init ();
|
||||
foembx = (_FOE *) &MBX[0];
|
||||
/* Get the length of the file name in octets. */
|
||||
data_len = etohs (foembx->mbxheader.length) - FOEHSIZE;
|
||||
data_len = (uint8_t)(etohs (foembx->mbxheader.length) - ESC_FOEHSIZE);
|
||||
password = etohl (foembx->foeheader.password);
|
||||
|
||||
res = FOE_fopen (foembx->filename, data_len, password, FOE_OP_RRQ);
|
||||
|
@ -335,7 +340,7 @@ void FOE_read ()
|
|||
* Attempt to send the packet
|
||||
*/
|
||||
res = FOE_send_data_packet ();
|
||||
if (res <= (int)FOE_DATA_SIZE)
|
||||
if (res <= ESC_FOE_DATA_SIZE)
|
||||
{
|
||||
FOEvar.foestate = FOE_WAIT_FOR_ACK;
|
||||
}
|
||||
|
@ -349,20 +354,13 @@ void FOE_read ()
|
|||
FOE_abort (res);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void FOE_read()
|
||||
{
|
||||
FOE_abort(FOE_ERR_NOTDEFINED);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FOE_READ_SUPPORTED
|
||||
/** FoE data ack handler. Will continue sending next frame until finished.
|
||||
* On error we will send FOE Abort.
|
||||
*/
|
||||
void FOE_ack ()
|
||||
static void FOE_ack ()
|
||||
{
|
||||
int res;
|
||||
uint32_t res;
|
||||
|
||||
/* Make sure we're able to take this. */
|
||||
if (FOEvar.foestate == FOE_WAIT_FOR_FINAL_ACK)
|
||||
|
@ -377,7 +375,7 @@ void FOE_ack ()
|
|||
return;
|
||||
}
|
||||
res = FOE_send_data_packet ();
|
||||
if (res < (int) FOE_DATA_SIZE)
|
||||
if (res < ESC_FOE_DATA_SIZE)
|
||||
{
|
||||
FOEvar.foestate = FOE_WAIT_FOR_FINAL_ACK;
|
||||
}
|
||||
|
@ -392,12 +390,12 @@ void FOE_ack ()
|
|||
* receive data. On error we will send FOE Abort.
|
||||
*
|
||||
*/
|
||||
void FOE_write ()
|
||||
static void FOE_write ()
|
||||
{
|
||||
_FOE *foembx;
|
||||
uint32_t data_len;
|
||||
uint32_t password;
|
||||
int res;
|
||||
uint32_t res;
|
||||
uint8_t data_len;
|
||||
|
||||
if (FOEvar.foestate != FOE_READY)
|
||||
{
|
||||
|
@ -407,12 +405,12 @@ void FOE_write ()
|
|||
|
||||
FOE_init ();
|
||||
foembx = (_FOE *) &MBX[0];
|
||||
data_len = etohs (foembx->mbxheader.length) - ESC_FOEHSIZE;
|
||||
data_len = (uint8_t)(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("FOE_write\n");
|
||||
DPRINT("%s %sOK, file \"%s\"\n", __func__, (res == 0) ? "" : "N", foe_file_name);
|
||||
if (res == 0)
|
||||
{
|
||||
res = FOE_send_ack ();
|
||||
|
@ -430,16 +428,16 @@ void FOE_write ()
|
|||
FOE_abort (res);
|
||||
}
|
||||
}
|
||||
/** FoE data request handler. Validates and reads data until we're finsihed. Every
|
||||
* read frame follwed by an Ack frame. On error we will send FOE Abort.
|
||||
/** 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.
|
||||
*
|
||||
*/
|
||||
void FOE_data ()
|
||||
static void FOE_data ()
|
||||
{
|
||||
_FOE *foembx;
|
||||
uint32_t packet;
|
||||
uint16_t data_len, ncopied;
|
||||
int res;
|
||||
uint32_t data_len, ncopied;
|
||||
uint32_t res;
|
||||
|
||||
if(FOEvar.foestate != FOE_WAIT_FOR_DATA)
|
||||
{
|
||||
|
@ -453,7 +451,9 @@ void FOE_data ()
|
|||
|
||||
if (packet != FOEvar.foepacket)
|
||||
{
|
||||
DPRINT("FOE_data packet error,packet: %d foeheader.packet: %d\n",packet,FOEvar.foepacket);
|
||||
DPRINT("FOE_data packet error, packet: %"PRIu32", foeheader.packet: %"PRIu32"\n",
|
||||
packet,
|
||||
FOEvar.foepacket);
|
||||
FOE_abort (FOE_ERR_PACKETNO);
|
||||
}
|
||||
else if (data_len == 0)
|
||||
|
@ -481,7 +481,7 @@ void FOE_data ()
|
|||
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);
|
||||
DPRINT("FOE_data only %"PRIu32" of %"PRIu32" copied\n",ncopied, data_len);
|
||||
FOE_abort (FOE_ERR_PROGERROR);
|
||||
}
|
||||
res = FOE_send_ack ();
|
||||
|
@ -508,11 +508,11 @@ void FOE_data ()
|
|||
}
|
||||
|
||||
#ifdef FOE_READ_SUPPORTED
|
||||
/** FoE read request buys handler. Send an Ack of last frame again. On error
|
||||
/** FoE read request busy handler. Send an Ack of last frame again. On error
|
||||
* we will send FOE Abort.
|
||||
*
|
||||
*/
|
||||
void FOE_busy ()
|
||||
static void FOE_busy ()
|
||||
{
|
||||
/* Only valid if we're servicing a read request. */
|
||||
if (FOEvar.foestate != FOE_WAIT_FOR_ACK)
|
||||
|
@ -532,7 +532,7 @@ void FOE_busy ()
|
|||
/** FoE error requesthandler. Send an FOE Abort.
|
||||
*
|
||||
*/
|
||||
void FOE_error ()
|
||||
static void FOE_error ()
|
||||
{
|
||||
/* Master panic! abort the transfer. */
|
||||
FOE_abort (0);
|
||||
|
@ -543,14 +543,10 @@ void FOE_error ()
|
|||
*
|
||||
* @param[in] cfg = Pointer to by the Application static declared
|
||||
* configuration variable holding application specific details.
|
||||
* @param[in] cfg_files = Pointer to by the Application static declared
|
||||
* configuration variable holding file specific details for files to be handled
|
||||
* by FoE
|
||||
*/
|
||||
void FOE_config (foe_cfg_t * cfg, foe_writefile_cfg_t * cfg_files)
|
||||
void FOE_config (foe_cfg_t * cfg)
|
||||
{
|
||||
foe_cfg = cfg;
|
||||
foe_files = cfg_files;
|
||||
}
|
||||
|
||||
/** Main FoE function checking the status on current mailbox buffers carrying
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
#include <cc.h>
|
||||
|
||||
/** Maximum number of characters allowed in a file name. */
|
||||
#define FOE_FN_MAX 15
|
||||
#define FOE_FN_MAX 31
|
||||
|
||||
typedef struct foe_writefile_cfg foe_writefile_cfg_t;
|
||||
struct foe_writefile_cfg
|
||||
typedef struct foe_file_cfg foe_file_cfg_t;
|
||||
struct foe_file_cfg
|
||||
{
|
||||
/** Name of file to receive from master */
|
||||
const char * name;
|
||||
|
@ -31,22 +31,24 @@ struct foe_writefile_cfg
|
|||
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_writefile_cfg_t * self, uint8_t * data);
|
||||
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;
|
||||
/** Write this to fill-up, ex. 0xFF for "non write" */
|
||||
uint8_t empty_write;
|
||||
/** 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_writefile_cfg_t * files;
|
||||
foe_file_cfg_t * files;
|
||||
} foe_cfg_t;
|
||||
|
||||
typedef struct CC_PACKED
|
||||
|
@ -68,7 +70,7 @@ typedef struct CC_PACKED
|
|||
} _FOEvar;
|
||||
|
||||
/* Initializes FoE state. */
|
||||
void FOE_config (foe_cfg_t * cfg, foe_writefile_cfg_t * cfg_files);
|
||||
void FOE_config (foe_cfg_t * cfg);
|
||||
void FOE_init (void);
|
||||
void ESC_foeprocess (void);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BIT(x) 1 << (x)
|
||||
#define BIT(x) (1U << (x))
|
||||
|
||||
#define ESC_CMD_SERIAL_WRITE 0x02
|
||||
#define ESC_CMD_SERIAL_READ 0x03
|
||||
|
@ -59,15 +59,15 @@ static int lan9252 = -1;
|
|||
static void lan9252_write_32 (uint16_t address, uint32_t val)
|
||||
{
|
||||
uint8_t data[7];
|
||||
int n;
|
||||
ssize_t n;
|
||||
|
||||
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);
|
||||
data[1] = (uint8_t)((address >> 8) & 0xFF);
|
||||
data[2] = (uint8_t)(address & 0xFF);
|
||||
data[3] = (uint8_t)(val & 0xFF);
|
||||
data[4] = (uint8_t)((val >> 8) & 0xFF);
|
||||
data[5] = (uint8_t)((val >> 16) & 0xFF);
|
||||
data[6] = (uint8_t)((val >> 24) & 0xFF);
|
||||
|
||||
/* Write data */
|
||||
n = write (lan9252, data, sizeof(data));
|
||||
|
@ -80,17 +80,17 @@ static uint32_t lan9252_read_32 (uint32_t address)
|
|||
uint8_t data[2];
|
||||
uint8_t result[4];
|
||||
uint16_t lseek_addr;
|
||||
int n;
|
||||
ssize_t n;
|
||||
|
||||
data[0] = ((address >>8) & 0xFF);
|
||||
data[1] = (address & 0xFF);
|
||||
|
||||
lseek_addr=((uint16_t)data[0] << 8) | data[1];
|
||||
lseek (lan9252, lseek_addr, SEEK_SET);
|
||||
lseek_addr=(uint16_t)((data[0] << 8) | data[1]);
|
||||
lseek (lan9252, lseek_addr, SEEK_SET);
|
||||
n = read (lan9252, result, sizeof(result));
|
||||
(void)n;
|
||||
|
||||
return ((result[3] << 24) |
|
||||
return (uint32_t)((result[3] << 24) |
|
||||
(result[2] << 16) |
|
||||
(result[1] << 8) |
|
||||
result[0]);
|
||||
|
@ -101,7 +101,9 @@ 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);
|
||||
value = ESC_CSR_CMD_READ;
|
||||
value |= (uint32_t)ESC_CSR_CMD_SIZE(len);
|
||||
value |= address;
|
||||
lan9252_write_32(ESC_CSR_CMD_REG, value);
|
||||
|
||||
do
|
||||
|
@ -120,7 +122,9 @@ static void ESC_write_csr (uint16_t address, void *buf, uint16_t len)
|
|||
|
||||
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);
|
||||
value = ESC_CSR_CMD_WRITE;
|
||||
value |= (uint32_t)ESC_CSR_CMD_SIZE(len);
|
||||
value |= address;
|
||||
lan9252_write_32(ESC_CSR_CMD_REG, value);
|
||||
|
||||
do
|
||||
|
@ -137,10 +141,10 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
|
|||
uint16_t byte_offset = 0;
|
||||
uint8_t fifo_cnt, first_byte_position, temp_len;
|
||||
uint8_t *buffer;
|
||||
int i, array_size, size;
|
||||
size_t i, array_size, size;
|
||||
float quotient,remainder;
|
||||
uint32_t temp;
|
||||
int n;
|
||||
ssize_t n;
|
||||
|
||||
value = ESC_PRAM_CMD_ABORT;
|
||||
lan9252_write_32(ESC_PRAM_RD_CMD_REG, value);
|
||||
|
@ -150,7 +154,7 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
|
|||
value = lan9252_read_32(ESC_PRAM_RD_CMD_REG);
|
||||
}while(value & ESC_PRAM_CMD_BUSY);
|
||||
|
||||
value = ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address);
|
||||
value = (uint32_t)(ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address));
|
||||
lan9252_write_32(ESC_PRAM_RD_ADDR_LEN_REG, value);
|
||||
|
||||
value = ESC_PRAM_CMD_BUSY;
|
||||
|
@ -162,7 +166,7 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
|
|||
}while((value & ESC_PRAM_CMD_AVAIL) == 0);
|
||||
|
||||
/* Fifo count */
|
||||
fifo_cnt = ESC_PRAM_CMD_CNT(value);
|
||||
fifo_cnt = (uint8_t)ESC_PRAM_CMD_CNT(value);
|
||||
|
||||
/* Read first value from FIFO */
|
||||
value = lan9252_read_32(ESC_PRAM_RD_FIFO_REG);
|
||||
|
@ -172,27 +176,27 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
|
|||
* 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);
|
||||
temp_len = ((4 - first_byte_position) > len) ? (uint8_t)len : (uint8_t)(4 - first_byte_position);
|
||||
|
||||
memcpy(temp_buf ,((uint8_t *)&value + first_byte_position), temp_len);
|
||||
len -= temp_len;
|
||||
byte_offset += temp_len;
|
||||
len = (uint16_t)(len - temp_len);
|
||||
byte_offset = (uint16_t)(byte_offset + temp_len);
|
||||
|
||||
/* Continue reading until we have read len */
|
||||
if (len > 0){
|
||||
|
||||
quotient = len/4;
|
||||
remainder = len%4;
|
||||
quotient = (float)(len/4);
|
||||
remainder = (float)(len%4);
|
||||
|
||||
if (remainder == 0)
|
||||
array_size = quotient;
|
||||
array_size = (size_t)quotient;
|
||||
else
|
||||
array_size = quotient+1;
|
||||
array_size = (size_t)quotient+1;
|
||||
|
||||
size = 4*array_size;
|
||||
|
||||
buffer = (uint8_t *)malloc(size);
|
||||
buffer[0] = size;
|
||||
buffer[0] = (uint8_t)size;
|
||||
memset(buffer,0,size);
|
||||
|
||||
lseek (lan9252, ESC_PRAM_RD_FIFO_REG, SEEK_SET);
|
||||
|
@ -203,13 +207,13 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
|
|||
{
|
||||
|
||||
for (i=0; i<size; i=i+4) {
|
||||
temp_len = (len > 4) ? 4: len;
|
||||
temp_len = (len > 4) ? 4: (uint8_t)len;
|
||||
|
||||
temp = buffer[i] | (buffer[i+1] << 8) | (buffer[i+2] << 16) | (buffer[i+3] << 24);
|
||||
temp = (uint32_t)(buffer[i] | (buffer[i+1] << 8) | (buffer[i+2] << 16) | (buffer[i+3] << 24));
|
||||
memcpy(temp_buf + byte_offset ,&temp, temp_len);
|
||||
fifo_cnt--;
|
||||
len -= temp_len;
|
||||
byte_offset += temp_len;
|
||||
len = (uint16_t)(len - temp_len);
|
||||
byte_offset = (uint16_t)(byte_offset + temp_len);
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
|
@ -224,9 +228,9 @@ static void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
|
|||
uint16_t byte_offset = 0;
|
||||
uint8_t fifo_cnt, first_byte_position, temp_len;
|
||||
uint8_t *buffer;
|
||||
int i, array_size, size;
|
||||
size_t i, array_size, size;
|
||||
float quotient,remainder;
|
||||
int n;
|
||||
ssize_t n;
|
||||
|
||||
value = ESC_PRAM_CMD_ABORT;
|
||||
lan9252_write_32(ESC_PRAM_WR_CMD_REG, value);
|
||||
|
@ -236,7 +240,7 @@ static void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
|
|||
value = lan9252_read_32(ESC_PRAM_WR_CMD_REG);
|
||||
}while(value & ESC_PRAM_CMD_BUSY);
|
||||
|
||||
value = ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address);
|
||||
value = (uint32_t)(ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address));
|
||||
lan9252_write_32(ESC_PRAM_WR_ADDR_LEN_REG, value);
|
||||
|
||||
value = ESC_PRAM_CMD_BUSY;
|
||||
|
@ -248,37 +252,37 @@ static void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
|
|||
}while((value & ESC_PRAM_CMD_AVAIL) == 0);
|
||||
|
||||
/* Fifo count */
|
||||
fifo_cnt = ESC_PRAM_CMD_CNT(value);
|
||||
fifo_cnt = (uint8_t)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);
|
||||
temp_len = ((4 - first_byte_position) > len) ? (uint8_t)len : (uint8_t)(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;
|
||||
len = (uint16_t)(len - temp_len);
|
||||
byte_offset = (uint16_t)(byte_offset + temp_len);
|
||||
fifo_cnt--;
|
||||
|
||||
if (len > 0){
|
||||
|
||||
quotient = len/4;
|
||||
remainder = len%4;
|
||||
remainder = (float)(len%4);
|
||||
|
||||
if (remainder == 0)
|
||||
array_size = quotient;
|
||||
array_size = (size_t)quotient;
|
||||
else
|
||||
array_size = quotient+1;
|
||||
array_size = (size_t)quotient+1;
|
||||
|
||||
size = 3+4*array_size;
|
||||
|
||||
buffer = (uint8_t *)malloc(size);
|
||||
buffer[0] = size;
|
||||
buffer[0] = (uint8_t)size;
|
||||
memset(buffer,0,size);
|
||||
|
||||
buffer[0] = ESC_CMD_SERIAL_WRITE;
|
||||
|
@ -287,17 +291,17 @@ static void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
|
|||
while(len > 0)
|
||||
{
|
||||
for (i=3; i<size; i=i+4) {
|
||||
temp_len = (len > 4) ? 4 : len;
|
||||
temp_len = (len > 4) ? 4 : (uint8_t)len;
|
||||
|
||||
memcpy((uint8_t *)&value, (temp_buf + byte_offset), temp_len);
|
||||
buffer[i] = (value & 0xFF);
|
||||
buffer[i+1] = ((value >> 8) & 0xFF);
|
||||
buffer[i+2] = ((value >> 16) & 0xFF);
|
||||
buffer[i+3] = ((value >> 24) & 0xFF);
|
||||
buffer[i] = (uint8_t)(value & 0xFF);
|
||||
buffer[i+1] = (uint8_t)((value >> 8) & 0xFF);
|
||||
buffer[i+2] = (uint8_t)((value >> 16) & 0xFF);
|
||||
buffer[i+3] = (uint8_t)((value >> 24) & 0xFF);
|
||||
|
||||
fifo_cnt--;
|
||||
len -= temp_len;
|
||||
byte_offset += temp_len;
|
||||
len = (uint16_t)(len - temp_len);
|
||||
byte_offset= (uint16_t)(byte_offset + temp_len);
|
||||
}
|
||||
}
|
||||
n = write (lan9252, buffer, size);
|
||||
|
@ -351,9 +355,9 @@ void ESC_read (uint16_t address, void *buf, uint16_t len)
|
|||
ESC_read_csr(address, temp_buf, size);
|
||||
|
||||
/* next address */
|
||||
len -= size;
|
||||
temp_buf += size;
|
||||
address += size;
|
||||
len = (uint16_t)(len - size);
|
||||
temp_buf = (uint8_t *)(temp_buf + size);
|
||||
address = (uint16_t)(address + size);
|
||||
}
|
||||
}
|
||||
/* To mimic the ET1100 always providing AlEvent on every read or write */
|
||||
|
@ -406,9 +410,9 @@ void ESC_write (uint16_t address, void *buf, uint16_t len)
|
|||
ESC_write_csr(address, temp_buf, size);
|
||||
|
||||
/* next address */
|
||||
len -= size;
|
||||
temp_buf += size;
|
||||
address += size;
|
||||
len = (uint16_t)(len - size);
|
||||
temp_buf = (uint8_t *)(temp_buf + size);
|
||||
address = (uint16_t)(address + size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,602 @@
|
|||
/*
|
||||
* 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 through BCM2835 SPI on Raspberry PI.
|
||||
*
|
||||
* Function to read and write commands to the ESC. Used to read/write ESC
|
||||
* registers and memory.
|
||||
*/
|
||||
#include "esc.h"
|
||||
#include "esc_hw.h"
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <bcm2835.h>
|
||||
|
||||
#define BIT(x) (1U << (x))
|
||||
|
||||
#define ESC_CMD_SERIAL_WRITE 0x02
|
||||
#define ESC_CMD_SERIAL_READ 0x03
|
||||
|
||||
#define ESC_CMD_RESET_CTL 0x01F8 // reset register
|
||||
#define ESC_CMD_HW_CFG 0x0074 // hardware configuration register
|
||||
#define ESC_CMD_BYTE_TEST 0x0064 // byte order test register
|
||||
#define ESC_CMD_ID_REV 0x0050 // chip ID and revision
|
||||
#define ESC_CMD_IRQ_CFG 0x0054 // interrupt configuration
|
||||
#define ESC_CMD_INT_EN 0x005C // interrupt enable
|
||||
|
||||
#define ESC_RESET_DIGITAL 0x00000001
|
||||
#define ESC_RESET_ETHERCAT 0x00000040
|
||||
#define ESC_RESET_CTRL_RST (ESC_RESET_DIGITAL & ESC_RESET_ETHERCAT)
|
||||
#define ESC_HW_CFG_READY 0x08000000
|
||||
#define ESC_BYTE_TEST_OK 0x87654321
|
||||
|
||||
#define ESC_PRAM_RD_FIFO_REG 0x0000
|
||||
#define ESC_PRAM_WR_FIFO_REG 0x0020
|
||||
#define ESC_PRAM_RD_ADDR_LEN_REG 0x0308
|
||||
#define ESC_PRAM_RD_CMD_REG 0x030C
|
||||
#define ESC_PRAM_WR_ADDR_LEN_REG 0x0310
|
||||
#define ESC_PRAM_WR_CMD_REG 0x0314
|
||||
|
||||
#define ESC_PRAM_CMD_BUSY 0x80000000
|
||||
#define ESC_PRAM_CMD_ABORT 0x40000000
|
||||
#define ESC_PRAM_CMD_AVAIL 0x00000001
|
||||
#define ESC_PRAM_CMD_CNT(x) (((x) >> 8) & 0x1F)
|
||||
#define ESC_PRAM_SIZE(x) ((x) << 16)
|
||||
#define ESC_PRAM_ADDR(x) ((x) << 0)
|
||||
|
||||
#define ESC_CSR_DATA_REG 0x0300
|
||||
#define ESC_CSR_CMD_REG 0x0304
|
||||
|
||||
#define ESC_CSR_CMD_BUSY 0x80000000
|
||||
#define ESC_CSR_CMD_READ (0x80000000 | 0x40000000)
|
||||
#define ESC_CSR_CMD_WRITE 0x80000000
|
||||
#define ESC_CSR_CMD_SIZE(x) ((x) << 16)
|
||||
|
||||
/* bcm2835 spi single write */
|
||||
static void bcm2835_spi_write_32 (uint16_t address, uint32_t val)
|
||||
{
|
||||
char 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);
|
||||
|
||||
/* Write data */
|
||||
bcm2835_spi_transfern(data, 7);
|
||||
}
|
||||
|
||||
/* bcm2835 spi single read */
|
||||
static uint32_t bcm2835_spi_read_32 (uint16_t address)
|
||||
{
|
||||
char data[7];
|
||||
|
||||
data[0] = ESC_CMD_SERIAL_READ;
|
||||
data[1] = ((address >> 8) & 0xFF);
|
||||
data[2] = (address & 0xFF);
|
||||
|
||||
/* Read data */
|
||||
bcm2835_spi_transfern(data, 7);
|
||||
|
||||
return ((data[6] << 24) |
|
||||
(data[5] << 16) |
|
||||
(data[4] << 8) |
|
||||
data[3]);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
bcm2835_spi_write_32(ESC_CSR_CMD_REG, value);
|
||||
|
||||
do
|
||||
{
|
||||
value = bcm2835_spi_read_32(ESC_CSR_CMD_REG);
|
||||
} while(value & ESC_CSR_CMD_BUSY);
|
||||
|
||||
value = bcm2835_spi_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);
|
||||
bcm2835_spi_write_32(ESC_CSR_DATA_REG, value);
|
||||
value = (ESC_CSR_CMD_WRITE | ESC_CSR_CMD_SIZE(len) | address);
|
||||
bcm2835_spi_write_32(ESC_CSR_CMD_REG, value);
|
||||
|
||||
do
|
||||
{
|
||||
value = bcm2835_spi_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 = buf;
|
||||
uint16_t quotient, remainder, byte_offset = 0;
|
||||
uint8_t fifo_cnt, fifo_size, fifo_range, first_byte_position, temp_len;
|
||||
uint8_t *buffer = NULL;
|
||||
int i, size;
|
||||
|
||||
bcm2835_spi_write_32(ESC_PRAM_RD_CMD_REG, ESC_PRAM_CMD_ABORT);
|
||||
do
|
||||
{
|
||||
value = bcm2835_spi_read_32(ESC_PRAM_RD_CMD_REG);
|
||||
}while(value & ESC_PRAM_CMD_BUSY);
|
||||
|
||||
bcm2835_spi_write_32(ESC_PRAM_RD_ADDR_LEN_REG, (ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address)));
|
||||
|
||||
bcm2835_spi_write_32(ESC_PRAM_RD_CMD_REG, ESC_PRAM_CMD_BUSY);
|
||||
|
||||
/* Find out first byte position and adjust the copy from that
|
||||
* according to LAN9252 datasheet and MicroChip SDK code
|
||||
*/
|
||||
first_byte_position = (address & 0x03);
|
||||
|
||||
/* Transfer data */
|
||||
while (len > 0)
|
||||
{
|
||||
/* Wait for read availabiliy */
|
||||
if (byte_offset > 0)
|
||||
{
|
||||
quotient = len/4;
|
||||
remainder = len - quotient*4;
|
||||
}
|
||||
else
|
||||
{
|
||||
quotient = (len + first_byte_position)/4;
|
||||
remainder = (len + first_byte_position) - quotient*4;
|
||||
}
|
||||
if (remainder != 0)
|
||||
{
|
||||
quotient++;
|
||||
}
|
||||
fifo_range = MIN(quotient,16);
|
||||
do
|
||||
{
|
||||
value = bcm2835_spi_read_32(ESC_PRAM_RD_CMD_REG);
|
||||
}while(!(value & ESC_PRAM_CMD_AVAIL) || (ESC_PRAM_CMD_CNT(value) < fifo_range));
|
||||
|
||||
/* Fifo size */
|
||||
fifo_size = ESC_PRAM_CMD_CNT(value);
|
||||
|
||||
/* Transfer data size */
|
||||
size = 3+4*fifo_size;
|
||||
|
||||
/* Allocate buffer */
|
||||
buffer = (uint8_t *)realloc(buffer, size);
|
||||
|
||||
/* Reset fifo count */
|
||||
fifo_cnt = fifo_size;
|
||||
|
||||
/* Reset buffer */
|
||||
memset(buffer,0,size);
|
||||
buffer[0] = ESC_CMD_SERIAL_READ;
|
||||
buffer[1] = ((ESC_PRAM_RD_FIFO_REG >>8) & 0xFF);
|
||||
buffer[2] = ( ESC_PRAM_RD_FIFO_REG & 0xFF);
|
||||
|
||||
/* Transfer batch of data */
|
||||
bcm2835_spi_transfern((char *)buffer, size);
|
||||
|
||||
i = 3;
|
||||
while (fifo_cnt > 0 && len > 0)
|
||||
{
|
||||
value = buffer[i] | (buffer[i+1] << 8) | (buffer[i+2] << 16) | (buffer[i+3] << 24);
|
||||
|
||||
if (byte_offset > 0)
|
||||
{
|
||||
temp_len = (len > 4) ? 4: len;
|
||||
memcpy(temp_buf + byte_offset ,&value, temp_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_len = (len > (4 - first_byte_position)) ? (4 - first_byte_position) : len;
|
||||
memcpy(temp_buf ,((uint8_t *)&value + first_byte_position), temp_len);
|
||||
}
|
||||
|
||||
i += 4;
|
||||
fifo_cnt--;
|
||||
len -= temp_len;
|
||||
byte_offset += temp_len;
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
/* 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 = buf;
|
||||
uint16_t quotient, remainder, byte_offset = 0;
|
||||
uint8_t fifo_cnt, fifo_size, fifo_range, first_byte_position, temp_len;
|
||||
uint8_t *buffer = NULL;
|
||||
int i, size;
|
||||
|
||||
bcm2835_spi_write_32(ESC_PRAM_WR_CMD_REG, ESC_PRAM_CMD_ABORT);
|
||||
do
|
||||
{
|
||||
value = bcm2835_spi_read_32(ESC_PRAM_WR_CMD_REG);
|
||||
}while(value & ESC_PRAM_CMD_BUSY);
|
||||
|
||||
bcm2835_spi_write_32(ESC_PRAM_WR_ADDR_LEN_REG, (ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address)));
|
||||
|
||||
bcm2835_spi_write_32(ESC_PRAM_WR_CMD_REG, ESC_PRAM_CMD_BUSY);
|
||||
|
||||
/* Find out first byte position and adjust the copy from that
|
||||
* according to LAN9252 datasheet and MicroChip SDK code
|
||||
*/
|
||||
first_byte_position = (address & 0x03);
|
||||
|
||||
/* Transfer data */
|
||||
while (len > 0)
|
||||
{
|
||||
/* Wait for write availabiliy */
|
||||
if (byte_offset > 0)
|
||||
{
|
||||
quotient = len/4;
|
||||
remainder = len - quotient*4;
|
||||
}
|
||||
else
|
||||
{
|
||||
quotient = (len + first_byte_position)/4;
|
||||
remainder = (len + first_byte_position) - quotient*4;
|
||||
}
|
||||
if (remainder != 0)
|
||||
{
|
||||
quotient++;
|
||||
}
|
||||
fifo_range = MIN(quotient,16);
|
||||
do
|
||||
{
|
||||
value = bcm2835_spi_read_32(ESC_PRAM_WR_CMD_REG);
|
||||
}while(!(value & ESC_PRAM_CMD_AVAIL) || (ESC_PRAM_CMD_CNT(value) < fifo_range));
|
||||
|
||||
/* Fifo size */
|
||||
fifo_size = ESC_PRAM_CMD_CNT(value);
|
||||
|
||||
/* Transfer data size */
|
||||
size = 3+4*fifo_size;
|
||||
|
||||
/* Allocate buffer */
|
||||
buffer = (uint8_t *)realloc(buffer, size);
|
||||
|
||||
/* Reset fifo count */
|
||||
fifo_cnt = fifo_size;
|
||||
|
||||
/* Reset buffer */
|
||||
memset(buffer,0,size);
|
||||
buffer[0] = ESC_CMD_SERIAL_WRITE;
|
||||
buffer[1] = ((ESC_PRAM_WR_FIFO_REG >> 8) & 0xFF);
|
||||
buffer[2] = (ESC_PRAM_WR_FIFO_REG & 0xFF);
|
||||
|
||||
i = 3;
|
||||
while (fifo_cnt > 0 && len > 0)
|
||||
{
|
||||
value = 0;
|
||||
if (byte_offset > 0)
|
||||
{
|
||||
temp_len = (len > 4) ? 4: len;
|
||||
memcpy(&value, (temp_buf + byte_offset), temp_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_len = (len > (4 - first_byte_position)) ? (4 - first_byte_position) : len;
|
||||
memcpy(((uint8_t *)&value + first_byte_position), temp_buf, temp_len);
|
||||
}
|
||||
|
||||
buffer[i] = (value & 0xFF);
|
||||
buffer[i+1] = ((value >> 8) & 0xFF);
|
||||
buffer[i+2] = ((value >> 16) & 0xFF);
|
||||
buffer[i+3] = ((value >> 24) & 0xFF);
|
||||
|
||||
i += 4;
|
||||
fifo_cnt--;
|
||||
len -= temp_len;
|
||||
byte_offset += temp_len;
|
||||
}
|
||||
|
||||
/* Transfer batch of data */
|
||||
bcm2835_spi_transfern((char *)buffer, size);
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ESC_init (const esc_cfg_t * config)
|
||||
{
|
||||
bool rpi4 = false, cs1 = false;
|
||||
uint32_t value;
|
||||
uint32_t counter = 0;
|
||||
uint32_t timeout = 1000; // wait 100msec
|
||||
const char * user_arg = (char *)config->user_arg;
|
||||
size_t arg_len = strlen(user_arg)+1;
|
||||
char * arg_str = (char *)calloc(arg_len, sizeof(char));
|
||||
strncpy(arg_str,user_arg,arg_len);
|
||||
char * delim = " ,.-";
|
||||
char * token = strtok(arg_str,delim);
|
||||
|
||||
// parse user arguments
|
||||
while (token != NULL)
|
||||
{
|
||||
if (strncmp(token,"cs1",3) == 0)
|
||||
{
|
||||
cs1 = true; // select CS1 pin
|
||||
}
|
||||
else if (strncmp(token,"rpi4",4) == 0)
|
||||
{
|
||||
rpi4 = true; // select clock divider for raspberry pi 4 or newer
|
||||
}
|
||||
token = strtok(NULL,delim);
|
||||
}
|
||||
free(arg_str);
|
||||
|
||||
// start initialization
|
||||
if (bcm2835_init())
|
||||
{
|
||||
if (bcm2835_spi_begin())
|
||||
{
|
||||
// Set SPI bit order
|
||||
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
|
||||
// Set SPI data mode BCM2835_SPI_MODE0 = 0, CPOL = 0, CPHA = 0,
|
||||
// Clock idle low, data is clocked in on rising edge, output data (change) on falling edge
|
||||
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
|
||||
if (rpi4)
|
||||
{
|
||||
// Raspberry 4 due to a higher CPU speed this value is to change to: BCM2835_SPI_CLOCK_DIVIDER_32
|
||||
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_32);
|
||||
DPRINT("bcm2835_spi_setClockDivider set to 32 \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set SPI clock speed BCM2835_SPI_CLOCK_DIVIDER_16 = 16, 16 = 64ns = 15.625MHz
|
||||
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_16);
|
||||
DPRINT("bcm2835_spi_setClockDivider set to 16 \n");
|
||||
}
|
||||
if (cs1)
|
||||
{
|
||||
// Enable management of CS1 pin
|
||||
bcm2835_spi_chipSelect(BCM2835_SPI_CS1);
|
||||
// Enable CS1 and set polarity
|
||||
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS1, LOW);
|
||||
DPRINT("bcm2835_spi_chipSelect set to CS1 \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enable management of CS0 pin
|
||||
bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
|
||||
// enable CS0 and set polarity
|
||||
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
|
||||
DPRINT("bcm2835_spi_chipSelect set to CS0 \n");
|
||||
}
|
||||
|
||||
// Reset the ecat core here due to evb-lan9252-digio not having any GPIO for that purpose.
|
||||
bcm2835_spi_write_32(ESC_CMD_RESET_CTL,ESC_RESET_CTRL_RST);
|
||||
|
||||
// Wait until reset command has been executed
|
||||
do
|
||||
{
|
||||
usleep(100);
|
||||
counter++;
|
||||
value = bcm2835_spi_read_32(ESC_CMD_RESET_CTL);
|
||||
} while ((value & ESC_RESET_CTRL_RST) && (counter < timeout));
|
||||
|
||||
// Perform byte test
|
||||
do
|
||||
{
|
||||
usleep(100);
|
||||
counter++;
|
||||
value = bcm2835_spi_read_32(ESC_CMD_BYTE_TEST);
|
||||
} while ((value != ESC_BYTE_TEST_OK) && (counter < timeout));
|
||||
|
||||
// Check hardware is ready
|
||||
do
|
||||
{
|
||||
usleep(100);
|
||||
counter++;
|
||||
value = bcm2835_spi_read_32(ESC_CMD_HW_CFG);
|
||||
} while (!(value & ESC_HW_CFG_READY) && (counter < timeout));
|
||||
|
||||
// Check if timeout occured
|
||||
if (counter < timeout)
|
||||
{
|
||||
// Read the chip identification and revision
|
||||
value = bcm2835_spi_read_32(ESC_CMD_ID_REV);
|
||||
DPRINT("Detected chip %x Rev %u \n", ((value >> 16) & 0xFFFF), (value & 0xFFFF));
|
||||
|
||||
// Set AL event mask
|
||||
value = (ESCREG_ALEVENT_CONTROL |
|
||||
ESCREG_ALEVENT_SMCHANGE |
|
||||
ESCREG_ALEVENT_SM0 |
|
||||
ESCREG_ALEVENT_SM1 );
|
||||
ESC_ALeventmaskwrite(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Timeout occurred during reset \n");
|
||||
bcm2835_spi_end();
|
||||
bcm2835_close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("bcm2835_spi_begin failed. Are you running as root?\n");
|
||||
bcm2835_close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("bcm2835_init failed. Are you running as root?\n");
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
// Set LAN9252 interrupt pin driver as push-pull active high
|
||||
bcm2835_spi_write_32(ESC_CMD_IRQ_CFG, 0x00000111);
|
||||
|
||||
// Enable LAN9252 interrupt
|
||||
bcm2835_spi_write_32(ESC_CMD_INT_EN, 0x00000001);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (mask & user_int_mask)
|
||||
{
|
||||
// Disable interrupt from SYNC0
|
||||
ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(mask & user_int_mask));
|
||||
}
|
||||
|
||||
|
||||
// Disable LAN9252 interrupt
|
||||
bcm2835_spi_write_32(ESC_CMD_INT_EN, 0x00000000);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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 specifoc EEPROM emulation functions.
|
||||
*/
|
||||
|
||||
#ifndef __esc_hw__
|
||||
#define __esc_hw__
|
||||
|
||||
void ESC_interrupt_enable (uint32_t mask);
|
||||
void ESC_interrupt_disable (uint32_t mask);
|
||||
|
||||
#endif
|
|
@ -16,6 +16,8 @@
|
|||
#include <string.h>
|
||||
#include <gpio.h>
|
||||
|
||||
#define MAX_READ_SIZE 128
|
||||
|
||||
#define ESC_CMD_READ 0x02
|
||||
#define ESC_CMD_READWS 0x03
|
||||
#define ESC_CMD_WRITE 0x04
|
||||
|
@ -24,7 +26,7 @@
|
|||
#define ESC_NEXT 0x00
|
||||
|
||||
static int et1100 = -1;
|
||||
static uint8_t read_termination[MAX(sizeof(Wb), 128)] = { 0 };
|
||||
static uint8_t read_termination[MAX_READ_SIZE] = { 0 };
|
||||
|
||||
#define GPIO_ECAT_RESET 1 /* specific function to hold ESC reset on startup
|
||||
* when emulating EEPROM
|
||||
|
@ -56,7 +58,7 @@ static void esc_address (uint16_t address, uint8_t command)
|
|||
*/
|
||||
void ESC_read (uint16_t address, void *buf, uint16_t len)
|
||||
{
|
||||
ASSERT(len <= sizeof(read_termination));
|
||||
ASSERT(len <= MAX_READ_SIZE);
|
||||
|
||||
/* Select device. */
|
||||
spi_select (et1100);
|
||||
|
@ -69,7 +71,7 @@ void ESC_read (uint16_t address, void *buf, uint16_t len)
|
|||
* Read (and write termination bytes).
|
||||
*/
|
||||
spi_bidirectionally_transfer (et1100, buf, read_termination +
|
||||
(sizeof(read_termination) - len), len);
|
||||
(MAX_READ_SIZE - len), len);
|
||||
|
||||
/* Un-select device. */
|
||||
spi_unselect (et1100);
|
||||
|
@ -122,5 +124,5 @@ void ESC_init (const esc_cfg_t * config)
|
|||
{
|
||||
const char * spi_name = (char *)config->user_arg;
|
||||
et1100 = open (spi_name, O_RDWR, 0);
|
||||
read_termination[sizeof(read_termination) - 1] = 0xFF;
|
||||
read_termination[MAX_READ_SIZE - 1] = 0xFF;
|
||||
}
|
||||
|
|
|
@ -10,21 +10,23 @@
|
|||
* Function to read and write commands to the ESC. Used to read/write ESC
|
||||
* registers and memory.
|
||||
*/
|
||||
#include <kern.h>
|
||||
#include <kern/kern.h>
|
||||
#include <bsp.h>
|
||||
#include <xmc4.h>
|
||||
#include <eru.h>
|
||||
#include <string.h>
|
||||
#include "esc_hw.h"
|
||||
#include "slave.h"
|
||||
#include "esc_eep.h"
|
||||
|
||||
#include "ecat_slv.h"
|
||||
#include "esc_hw_eep.h"
|
||||
|
||||
#define ESCADDR(x) (((uint8_t *) ECAT0_BASE) + x)
|
||||
|
||||
/* Global sem to make it possible to kick worker from the application */
|
||||
sem_t * ecat_isr_sem;
|
||||
|
||||
static volatile esc_registers_t * ecat0 = (esc_registers_t *)ECAT0_BASE;
|
||||
static int use_all_interrupts = 0;
|
||||
static sem_t * ecat_isr_sem;
|
||||
static void sync0_isr (void * arg);
|
||||
static volatile uint8_t read_ack;
|
||||
|
||||
|
@ -81,6 +83,25 @@ void ESC_enable(void)
|
|||
scu_put_peripheral_in_reset (SCU_PERIPHERAL_ECAT0);
|
||||
scu_ungate_clock_to_peripheral (SCU_PERIPHERAL_ECAT0);
|
||||
scu_release_peripheral_from_reset (SCU_PERIPHERAL_ECAT0);
|
||||
|
||||
/* Used to perform PHY reset after ECAT module have been released as
|
||||
* described in 16.3.2.3 final section;
|
||||
* "In some case PHYs may be released from reset after releasing the ECAT
|
||||
* module, the pin for nPHY_RESET can be used as an I/O and shell be
|
||||
* switched later to the alternate output function".
|
||||
* Works well with relax boards.
|
||||
*/
|
||||
static const gpio_cfg_t gpio_cfg[] =
|
||||
{
|
||||
{ ECAT0_PHY_RESET,
|
||||
ECAT0_PHY_RESET_GPIO_AF,
|
||||
GPIO_STRONG_SOFT,
|
||||
GPIO_PAD_ENABLED,
|
||||
GPIO_POWS_DISABLED,
|
||||
GPIO_SW },
|
||||
};
|
||||
/* Re-configure the pin to correct alternate output function */
|
||||
gpio_configure (gpio_cfg, NELEMENTS (gpio_cfg));
|
||||
}
|
||||
|
||||
/* EtherCAT module clock gating and assert reset API (Disables ECAT)*/
|
||||
|
@ -175,7 +196,6 @@ void ESC_interrupt_disable (uint32_t mask)
|
|||
mask &= ~ESCREG_ALEVENT_DC_LATCH;
|
||||
UASSERT(0,EARG);
|
||||
}
|
||||
|
||||
ecat0->AL_EVENT_MASK &= ~mask;
|
||||
}
|
||||
|
||||
|
@ -193,6 +213,22 @@ void ESC_eep_handler(void)
|
|||
*/
|
||||
static void sync0_isr (void * arg)
|
||||
{
|
||||
/* Subtract the sync counter to check the pace compared to the SM IRQ */
|
||||
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
|
||||
{
|
||||
CC_ATOMIC_SUB(ESCvar.synccounter, 1);
|
||||
}
|
||||
/* Check so we're inside the limit */
|
||||
if((CC_ATOMIC_GET(ESCvar.synccounter) < -ESCvar.synccounterlimit) ||
|
||||
(CC_ATOMIC_GET(ESCvar.synccounter) > ESCvar.synccounterlimit))
|
||||
{
|
||||
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
|
||||
{
|
||||
DPRINT("sync error = %d\n", ESCvar.synccounter);
|
||||
ESC_ALstatusgotoerror((ESCsafeop | ESCerror), ALERR_SYNCERROR);
|
||||
CC_ATOMIC_SET(ESCvar.synccounter, 0);
|
||||
}
|
||||
}
|
||||
DIG_process(DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
|
||||
read_ack = ecat0->DC_SYNC0_STAT;
|
||||
}
|
||||
|
@ -203,13 +239,13 @@ static void sync0_isr (void * arg)
|
|||
*/
|
||||
static void ecat_isr (void * arg)
|
||||
{
|
||||
|
||||
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
|
||||
ESCvar.Time = etohl (ESCvar.Time);
|
||||
CC_ATOMIC_SET(ESCvar.ALevent, etohl(ecat0->AL_EVENT_REQ));
|
||||
CC_ATOMIC_SET(ESCvar.Time, etohl(ecat0->READMode_DC_SYS_TIME[0]));
|
||||
|
||||
if(ESCvar.ALevent & ESCREG_ALEVENT_SM2)
|
||||
/* Handle SM2 & SM3 interrupt */
|
||||
if(ESCvar.ALevent & (ESCREG_ALEVENT_SM2 | ESCREG_ALEVENT_SM3))
|
||||
{
|
||||
/* Is DC active or not */
|
||||
if(ESCvar.dcsync == 0)
|
||||
{
|
||||
DIG_process(DIG_PROCESS_OUTPUTS_FLAG | DIG_PROCESS_APP_HOOK_FLAG |
|
||||
|
@ -217,10 +253,16 @@ static void ecat_isr (void * arg)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Add the sync counter to check the pace compared to the SM IRQ */
|
||||
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
|
||||
{
|
||||
CC_ATOMIC_ADD(ESCvar.synccounter, 1);
|
||||
}
|
||||
DIG_process(DIG_PROCESS_OUTPUTS_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle low prio interrupts */
|
||||
if(ESCvar.ALevent & (ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
|
||||
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP))
|
||||
{
|
||||
|
@ -229,16 +271,40 @@ static void ecat_isr (void * arg)
|
|||
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
|
||||
sem_signal(ecat_isr_sem);
|
||||
}
|
||||
|
||||
/* SM watchdog */
|
||||
if(ESCvar.ALevent & ESCREG_ALEVENT_WD)
|
||||
{
|
||||
uint16_t wd;
|
||||
/* Ack the WD IRQ */
|
||||
wd = ecat0->WD_STAT_PDATA;
|
||||
/* Check if the WD have expired and if we're in OP */
|
||||
if(((wd & 0x1) == 0) &&
|
||||
((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0))
|
||||
{
|
||||
ESC_ALstatusgotoerror((ESCsafeop | ESCerror), ALERR_WATCHDOG);
|
||||
ecat0->AL_EVENT_MASK &= ~ESCREG_ALEVENT_WD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Function for PDI ISR serving task */
|
||||
/* Function for low prio PDI interrupts and flushing of EEPROM RAM buffer
|
||||
* to flash.
|
||||
*/
|
||||
static void isr_run(void * arg)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
sem_wait(ecat_isr_sem);
|
||||
ecat_slv_worker(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
|
||||
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
|
||||
/* Do while to handle write of eeprom, the write to flash is delayed */
|
||||
do
|
||||
{
|
||||
/* Update time, used by emulated eeprom handler to measure idle time */
|
||||
CC_ATOMIC_SET(ESCvar.Time, etohl(ecat0->READMode_DC_SYS_TIME[0]));
|
||||
ecat_slv_worker(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
|
||||
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
|
||||
|
||||
}while(eep_write_pending);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#ifndef __esc_hw__
|
||||
#define __esc_hw__
|
||||
|
||||
#include <kern.h>
|
||||
#include <kern/kern.h>
|
||||
/* ================================================================================ */
|
||||
/* ================ ECAT [ECAT0] ================ */
|
||||
/* ================================================================================ */
|
||||
|
|
|
@ -63,6 +63,7 @@ static eep_block_t *cleanup_unused_sect(eep_block_t *block);
|
|||
|
||||
static int32_t is_sector_empty(uint32_t *addr);
|
||||
|
||||
uint8_t eep_write_pending;
|
||||
|
||||
/** Initialize EEPROM emulation (load default data, validate checksums, ...).
|
||||
*
|
||||
|
@ -135,6 +136,7 @@ void EEP_hw_process (void)
|
|||
/* update block pointer and reset write state */
|
||||
eep_curr_block = eep_next_block;
|
||||
eep_next_block = NULL;
|
||||
eep_write_pending = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -204,6 +206,7 @@ int8_t EEP_write (uint32_t addr, uint8_t *data, uint16_t count)
|
|||
eep_buf_dirty = 1;
|
||||
eep_write_req = 0;
|
||||
eep_last_write = ESCvar.Time;
|
||||
eep_write_pending = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue