SOES implementation i.c.w. ET1100 (Beckhoff ASIC)
Dependencies: KL25Z_ClockControl MODSERIAL mbed
Fork of EtherCAT-XbusMaster by
soes.cpp
- Committer:
- vsluiter
- Date:
- 2015-03-08
- Revision:
- 26:c7959f1fd09a
- Parent:
- 25:829af6f3429f
- Child:
- 27:93c0e4ae943e
File content as of revision 26:c7959f1fd09a:
/* * SOES Simple Open EtherCAT Slave * * File : soes.c * Version : 0.9.2 * Date : 22-02-2010 * Copyright (C) 2007-2010 Arthur Ketels * * SOES is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by the Free * Software Foundation. * * SOES is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * As a special exception, if other files instantiate templates or use macros * or inline functions from this file, or you compile this file and link it * with other works to produce a work based on this file, this file does not * by itself cause the resulting work to be covered by the GNU General Public * License. However the source code for this file must still be made available * in accordance with section (3) of the GNU General Public License. * * This exception does not invalidate any other reasons why a work based on * this file might be covered by the GNU General Public License. * * The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual * property of, and protected by Beckhoff Automation GmbH. */ /**************************************************** Chip type : STM32F051R8 Clock frequency : 48 MHz *****************************************************/ /* Includes ------------------------------------------------------------------*/ #include "mbed.h" #include "cpuinit.h" #include "utypes.h" #include "esc.h" #include "MODSERIAL.h" #include "xbus.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define wd_reset 1000 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ _ESCvar ESCvar; uint8 APPstate; _MBX MBX[MBXBUFFERS]; _MBXcontrol MBXcontrol[MBXBUFFERS]; uint8 MBXrun=0; uint16 SM2_sml,SM3_sml; _Rbuffer Rb; _Wbuffer Wb; _Ebuffer Eb; //EEprom uint8 TXPDOsize,RXPDOsize; uint16 wd_ok = 1, wd_cnt = wd_reset; _Rbuffer local_Rb; //to prevent issues when updating DigitalOut led(LED_PIN); DigitalOut et1100_ss(ET1100_SS); DigitalIn et1100_miso(ET1100_MISO); SPI et1100_spi(ET1100_MOSI,ET1100_MISO,ET1100_SCK); MODSERIAL xbus_serial(PTC4,PTC3); xbus_t xbus_master; MODSERIAL pc(USBTX,USBRX); DigitalOut ploep(PTA13); #define PLOEP do{ploep = !(ploep);}while(0); /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /** void ESC_objecthandler(uint16 index, uint8 subindex) \brief Object handler, declared from esc.h, as extern function \param index \param subindex */ void ESC_objecthandler(uint16 index, uint8 subindex); void TXPDO_update(void); void RXPDO_update(void); void DIG_process(void); void sample(void); void ESC_objecthandler(uint16 index, uint8 subindex) { uint8 dummy8; uint16 dummy16; switch (index) { case 0x8000: switch (subindex) { case 0x01: { uint32_t rates[] = {460800,230400,115200,76800,57600,38400,28800,19200,14400,9600}; if(Eb.setting8 < (sizeof(rates)/sizeof(uint32_t)) ) { XbusSetBaudRate(Eb.setting8); XbusReset(); xbus_serial.baud(rates[Eb.setting8]); XbusInitializeXbusMaster(); } break; } case 0x02: dummy16 = 0;//Eb.setting16;//Write value to EEPROM; eeprom_write_word(&eedat.setting16, Wb.setting16); break; } break; } } void TXPDO_update(void) { ESC_write(SM3_sma, &Rb, TXPDOsize, &ESCvar.ALevent); } void RXPDO_update(void) { ESC_read(SM2_sma, &Wb, RXPDOsize, &ESCvar.ALevent); } void APP_safeoutput(void) { asm("nop"); //Wb.dout = 0; //DOUTPORT = (Wb.dout >> 4) & 0xf0; } void DIG_process(void) { uint8_t correct_offset; if (APPstate & APPSTATE_OUTPUT) //output enabled { if (ESCvar.ALevent & ESCREG_ALEVENT_SM2) // SM2 trigger ? { ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2; RXPDO_update(); // dummy output point correct_offset = Wb.correct_offset; if(correct_offset & 0x01) { // led.write(1); asm("nop"); } // else // led.write(0); wd_cnt = wd_reset; } if (!wd_cnt) { ESC_stopoutput(); // watchdog, invalid outputs ESC_ALerror(ALERR_WATCHDOG); // goto safe-op with error bit set ESC_ALstatus(ESCsafeop | ESCerror); } } else { //wd_ok = 1; wd_cnt = wd_reset; } if (APPstate) //input or output enabled { //Rb.timestamp = ESCvar.Time; //just some dummy data to test //Rb.counter++; //Rb.diginput = diginput; //Rb.analog[0] = 1; //Rb.analog[1] = 2; memcpy(&Rb, &local_Rb, sizeof(Rb)); TXPDO_update(); } } //Watch out, this is an uggly fix; for odd numbers of num_bytes, still the trailing byte will be used too. //No memory protection what so ever. void memcpy_byteswap(uint8_t * dest, uint8_t * source, uint16_t num_bytes) { for( int i = 0 ; i < num_bytes ; i+=2 ) { dest[i] = source[i+1]; dest[i+1] = source[i]; } } int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f0xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f0xx.c file */ cpuinit(); TXPDOsize = sizeTXPDO(); RXPDOsize = sizeRXPDO(); wait_ms(200); /*initialize configuration*/ //Eb.setting16 = 0xABCD; //Eb.setting8 = 111; // wait until ESC is started up while ((ESCvar.DLstatus & 0x0001) == 0) ESC_read(ESCREG_DLSTATUS, &ESCvar.DLstatus, sizeof(ESCvar.DLstatus), &ESCvar.ALevent); // reset ESC to init state ESC_ALstatus(ESCinit); ESC_ALerror(ALERR_NONE); ESC_stopmbx(); ESC_stopinput(); ESC_stopoutput(); // pc.baud(115200); // application run loop while (1) { while(xbus_serial.readable()) { PLOEP; XbusReceiveState(&xbus_master, xbus_serial.getc()); if(xbus_master.rx.checksum_ok) { if(xbus_master.rx.buffer[2] == 0x32) { memcpy_byteswap((uint8_t *)&local_Rb.timestamp ,&xbus_master.rx.buffer[4], 2); memcpy_byteswap((uint8_t *)&local_Rb.first.acc[0],&xbus_master.rx.buffer[6],60); //pc.printf("%x %x\n",Rb.timestamp, *((uint16_t *)(&xbus_master.rx.buffer[4]))); } xbus_master.rx.checksum_ok = 0; } } ESC_read(ESCREG_LOCALTIME, &ESCvar.Time, sizeof(ESCvar.Time), &ESCvar.ALevent); ESC_ALevent(); ESC_state(); if (ESC_mbxprocess()) { ESC_coeprocess(); ESC_xoeprocess(); } DIG_process(); } } /** void ESC_objecthandler(uint16 index, uint8 subindex) \brief Object handler, declared from esc.h, as extern function \param index \param subindex */ #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/