EasyCAT shield library - It allows you to make an EtherCAT slave

Dependents:   TestEasyCAT_SM_sync TestEasyCAT_LoopBack TestEasyCAT_DC_sync TestEasyCAT

The EasyCAT Shield and /static/img/mbed.gif boards

/media/uploads/EasyCAT/easycat_onnucleo.jpg

  • The EasyCAT Shield is an Arduino shield, designed and manufactured in Italy by AB&T Tecnologie Informatiche, that allow us to build a custom EtherCAT® slave in an easy way.
  • The EasyCAT Shield uses the 3x2 SPI connector to communicate with the microcontroller. This connector is standard on all the Arduino boards but some Arduino compatible boards don’t provide it. In this case, the SPI signal are always present on pins 13,12,and 11. Some examples of this boards are the STM32 Nucleo and the NXP LPCXpresso, part of the Mbed ecosystem.
  • To address this issue in the EasyCAT Shield revision “C” there are three solder jumpers, on the bottom side of the board, that allow us to connect the SPI signals, SCK,MISO and MOSI, also on pins 13, 12 and 11.

/media/uploads/EasyCAT/spi_selection_jumpered.jpg

  • For your convenience the EasyCAT Shield can be ordered with the three solder jumpers already bridged and with the 3x2 connector not installed on the board. To request this option select EasyCAT spi_on_13_12_11 in the webshop.

Import libraryEasyCAT_lib

EasyCAT shield library - It allows you to make an EtherCAT slave

Committer:
daid
Date:
Thu Mar 28 08:32:57 2019 +0000
Revision:
2:e0fc1b098ce8
Parent:
0:7816b38c99cc
Child:
3:7d8b74ba7225
Update the EasyCAT library to use block transfers instead of single byte transfers. This significantly decreases the total time spend in the MainTask function. From 500uSec down to 150uSec on a STM32F767 with 32bytes in/out data.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
EasyCAT 0:7816b38c99cc 1 //********************************************************************************************
EasyCAT 0:7816b38c99cc 2 // *
EasyCAT 0:7816b38c99cc 3 // AB&T Tecnologie Informatiche - Ivrea Italy *
EasyCAT 0:7816b38c99cc 4 // http://www.bausano.net *
EasyCAT 0:7816b38c99cc 5 // https://www.ethercat.org/en/products/791FFAA126AD43859920EA64384AD4FD.htm *
EasyCAT 0:7816b38c99cc 6 // *
EasyCAT 0:7816b38c99cc 7 //********************************************************************************************
EasyCAT 0:7816b38c99cc 8 // *
EasyCAT 0:7816b38c99cc 9 // This software is distributed as an example, in the hope that it could be useful, *
EasyCAT 0:7816b38c99cc 10 // WITHOUT ANY WARRANTY, even the implied warranty of FITNESS FOR A PARTICULAR PURPOSE *
EasyCAT 0:7816b38c99cc 11 // *
EasyCAT 0:7816b38c99cc 12 //********************************************************************************************
EasyCAT 0:7816b38c99cc 13
EasyCAT 0:7816b38c99cc 14
EasyCAT 0:7816b38c99cc 15 //----- EasyCAT library for mbed boards -----------------------------------------------------
EasyCAT 0:7816b38c99cc 16 //----- Derived from the AB&T EasyCAT Arduino shield library V 1.5 170912--------------------------
EasyCAT 0:7816b38c99cc 17
EasyCAT 0:7816b38c99cc 18 //----- Tested with the STM32 NUCLEO-F767ZI board -------------------------------------------
EasyCAT 0:7816b38c99cc 19
EasyCAT 0:7816b38c99cc 20
EasyCAT 0:7816b38c99cc 21
EasyCAT 0:7816b38c99cc 22 #include "mbed.h"
EasyCAT 0:7816b38c99cc 23 #include "EasyCAT.h"
EasyCAT 0:7816b38c99cc 24
EasyCAT 0:7816b38c99cc 25
daid 2:e0fc1b098ce8 26 static DigitalOut * SpiCs;
daid 2:e0fc1b098ce8 27 static SPI Spi(D11, D12, D13); // declare MOSI MISO SCK
EasyCAT 0:7816b38c99cc 28
EasyCAT 0:7816b38c99cc 29 #define SCS_Low_macro (*SpiCs = 0); // macro for set/reset SPI chip select
EasyCAT 0:7816b38c99cc 30 #define SCS_High_macro (*SpiCs = 1); //
EasyCAT 0:7816b38c99cc 31
daid 2:e0fc1b098ce8 32 inline static void SPI_TransferTxBuffer(const void* buffer, int buffer_size)
daid 2:e0fc1b098ce8 33 {
daid 2:e0fc1b098ce8 34 Spi.write(static_cast<const char*>(buffer), buffer_size, NULL, 0);
daid 2:e0fc1b098ce8 35 }
EasyCAT 0:7816b38c99cc 36
daid 2:e0fc1b098ce8 37 inline static void SPI_TransferRxBuffer(void* buffer, int buffer_size)
daid 2:e0fc1b098ce8 38 {
daid 2:e0fc1b098ce8 39 Spi.write(NULL, 0, static_cast<char*>(buffer), buffer_size);
daid 2:e0fc1b098ce8 40 }
EasyCAT 0:7816b38c99cc 41
EasyCAT 0:7816b38c99cc 42 //---- constructors --------------------------------------------------------------------------------
EasyCAT 0:7816b38c99cc 43
EasyCAT 0:7816b38c99cc 44 EasyCAT::EasyCAT() //------- default constructor ----------------------
EasyCAT 0:7816b38c99cc 45 { //
EasyCAT 0:7816b38c99cc 46 Sync_ = ASYNC; // if no synchronization mode is declared
EasyCAT 0:7816b38c99cc 47 // ASYNC is the default
EasyCAT 0:7816b38c99cc 48 //
EasyCAT 0:7816b38c99cc 49 SCS_ = (PinName)D9; // if no chip select is declared
EasyCAT 0:7816b38c99cc 50 SpiCs = new DigitalOut(SCS_, 1); // pin D9 is the default
EasyCAT 0:7816b38c99cc 51 } //
EasyCAT 0:7816b38c99cc 52
EasyCAT 0:7816b38c99cc 53
EasyCAT 0:7816b38c99cc 54 EasyCAT::EasyCAT(PinName SCS) //------- SPI_CHIP_SELECT options -----------------
EasyCAT 0:7816b38c99cc 55 //
EasyCAT 0:7816b38c99cc 56 // for EasyCAT board REV_A we can choose between:
EasyCAT 0:7816b38c99cc 57 // D8, D9, D10
EasyCAT 0:7816b38c99cc 58 //
EasyCAT 0:7816b38c99cc 59 // for EasyCAT board REV_B we have three additional options:
EasyCAT 0:7816b38c99cc 60 // A5, D6, D7
EasyCAT 0:7816b38c99cc 61 {
daid 2:e0fc1b098ce8 62 Sync_ = ASYNC; // if no synchronization mode is declared
daid 2:e0fc1b098ce8 63 // ASYNC is the default
daid 2:e0fc1b098ce8 64
EasyCAT 0:7816b38c99cc 65 SCS_ = SCS; // initialize chip select
EasyCAT 0:7816b38c99cc 66 SpiCs = new DigitalOut(SCS_, 1); //
EasyCAT 0:7816b38c99cc 67 } //
EasyCAT 0:7816b38c99cc 68
EasyCAT 0:7816b38c99cc 69
EasyCAT 0:7816b38c99cc 70 EasyCAT::EasyCAT(SyncMode Sync) //-------Synchronization options ----------------------
EasyCAT 0:7816b38c99cc 71 //
EasyCAT 0:7816b38c99cc 72 // we can choose between:
EasyCAT 0:7816b38c99cc 73 // ASYNC = free running i.e. no synchronization
EasyCAT 0:7816b38c99cc 74 // between master and slave (default)
EasyCAT 0:7816b38c99cc 75 //
EasyCAT 0:7816b38c99cc 76 // DC_SYNC = interrupt is generated from the
EasyCAT 0:7816b38c99cc 77 // Distributed clock unit
EasyCAT 0:7816b38c99cc 78 //
EasyCAT 0:7816b38c99cc 79 // SM_SYNC = interrupt is generated from the
EasyCAT 0:7816b38c99cc 80 // Syncronizatiom manager 2
EasyCAT 0:7816b38c99cc 81 { //
EasyCAT 0:7816b38c99cc 82 Sync_ = Sync; //
EasyCAT 0:7816b38c99cc 83 //
EasyCAT 0:7816b38c99cc 84 SCS_ = (PinName)D9; // default chip select is pin 9
EasyCAT 0:7816b38c99cc 85 SpiCs = new DigitalOut(SCS_, 1); //
EasyCAT 0:7816b38c99cc 86 } //
EasyCAT 0:7816b38c99cc 87
EasyCAT 0:7816b38c99cc 88
EasyCAT 0:7816b38c99cc 89 //-- Synchronization and chip select options -----
EasyCAT 0:7816b38c99cc 90 EasyCAT::EasyCAT(PinName SCS, SyncMode Sync) //
EasyCAT 0:7816b38c99cc 91 //
EasyCAT 0:7816b38c99cc 92 { //
EasyCAT 0:7816b38c99cc 93 Sync_ = Sync; //
EasyCAT 0:7816b38c99cc 94 //
EasyCAT 0:7816b38c99cc 95 SCS_ = SCS; // initialize chip select
EasyCAT 0:7816b38c99cc 96 SpiCs = new DigitalOut(SCS_, 1); //
EasyCAT 0:7816b38c99cc 97 } //
EasyCAT 0:7816b38c99cc 98
EasyCAT 0:7816b38c99cc 99
EasyCAT 0:7816b38c99cc 100
EasyCAT 0:7816b38c99cc 101 //---- EasyCAT board initialization ---------------------------------------------------------------
EasyCAT 0:7816b38c99cc 102
EasyCAT 0:7816b38c99cc 103
EasyCAT 0:7816b38c99cc 104 bool EasyCAT::Init()
EasyCAT 0:7816b38c99cc 105 {
EasyCAT 0:7816b38c99cc 106 #define Tout 1000
EasyCAT 0:7816b38c99cc 107
EasyCAT 0:7816b38c99cc 108 ULONG TempLong;
EasyCAT 0:7816b38c99cc 109 unsigned short i;
EasyCAT 0:7816b38c99cc 110
EasyCAT 0:7816b38c99cc 111 Spi.frequency(14000000); // SPI speed 14MHz
EasyCAT 0:7816b38c99cc 112 Spi.format(8,0); // 8 bit mode 0
EasyCAT 0:7816b38c99cc 113
EasyCAT 0:7816b38c99cc 114 wait_ms(100);
EasyCAT 0:7816b38c99cc 115
EasyCAT 0:7816b38c99cc 116 SPIWriteRegisterDirect (RESET_CTL, DIGITAL_RST); // LAN9252 reset
EasyCAT 0:7816b38c99cc 117
EasyCAT 0:7816b38c99cc 118 i = 0; // reset timeout
EasyCAT 0:7816b38c99cc 119 do // wait for reset to complete
EasyCAT 0:7816b38c99cc 120 { //
EasyCAT 0:7816b38c99cc 121 i++; //
EasyCAT 0:7816b38c99cc 122 TempLong.Long = SPIReadRegisterDirect (RESET_CTL, 4); //
EasyCAT 0:7816b38c99cc 123 }while (((TempLong.Byte[0] & 0x01) != 0x00) && (i != Tout));
EasyCAT 0:7816b38c99cc 124 //
EasyCAT 0:7816b38c99cc 125 if (i == Tout) // time out expired
EasyCAT 0:7816b38c99cc 126 { //
EasyCAT 0:7816b38c99cc 127 return false; // initialization failed
EasyCAT 0:7816b38c99cc 128 }
EasyCAT 0:7816b38c99cc 129
EasyCAT 0:7816b38c99cc 130 i = 0; // reset timeout
EasyCAT 0:7816b38c99cc 131 do // check the Byte Order Test Register
EasyCAT 0:7816b38c99cc 132 { //
EasyCAT 0:7816b38c99cc 133 i++; //
EasyCAT 0:7816b38c99cc 134 TempLong.Long = SPIReadRegisterDirect (BYTE_TEST, 4); //
EasyCAT 0:7816b38c99cc 135 }while ((TempLong.Long != 0x87654321) && (i != Tout)); //
EasyCAT 0:7816b38c99cc 136 //
EasyCAT 0:7816b38c99cc 137 if (i == Tout) // time out expired
EasyCAT 0:7816b38c99cc 138 { //
EasyCAT 0:7816b38c99cc 139 return false; // initialization failed
EasyCAT 0:7816b38c99cc 140 }
EasyCAT 0:7816b38c99cc 141
EasyCAT 0:7816b38c99cc 142 i = 0; // reset timeout
EasyCAT 0:7816b38c99cc 143 do // check the Ready flag
EasyCAT 0:7816b38c99cc 144 { //
EasyCAT 0:7816b38c99cc 145 i++; //
EasyCAT 0:7816b38c99cc 146 TempLong.Long = SPIReadRegisterDirect (HW_CFG, 4); //
EasyCAT 0:7816b38c99cc 147 }while (((TempLong.Byte[3] & READY) == 0) && (i != Tout));//
EasyCAT 0:7816b38c99cc 148 //
EasyCAT 0:7816b38c99cc 149 if (i == Tout) // time out expired
EasyCAT 0:7816b38c99cc 150 { //
EasyCAT 0:7816b38c99cc 151 return false; // initialization failed
EasyCAT 0:7816b38c99cc 152 }
EasyCAT 0:7816b38c99cc 153
EasyCAT 0:7816b38c99cc 154
EasyCAT 0:7816b38c99cc 155
EasyCAT 0:7816b38c99cc 156 #ifdef BYTE_NUM
EasyCAT 0:7816b38c99cc 157 printf ("STANDARD MODE\n");
EasyCAT 0:7816b38c99cc 158 #else
EasyCAT 0:7816b38c99cc 159 printf ("CUSTOM MODE\n");
EasyCAT 0:7816b38c99cc 160 #endif
EasyCAT 0:7816b38c99cc 161
EasyCAT 0:7816b38c99cc 162 printf ("%u Byte Out\n",TOT_BYTE_NUM_OUT);
EasyCAT 0:7816b38c99cc 163 printf ("%u Byte In\n",TOT_BYTE_NUM_IN);
EasyCAT 0:7816b38c99cc 164
EasyCAT 0:7816b38c99cc 165 printf ("Sync = ");
EasyCAT 0:7816b38c99cc 166
EasyCAT 0:7816b38c99cc 167
EasyCAT 0:7816b38c99cc 168 if ((Sync_ == DC_SYNC) || (Sync_ == SM_SYNC)) //--- if requested, enable --------
EasyCAT 0:7816b38c99cc 169 { //--- interrupt generation --------
EasyCAT 0:7816b38c99cc 170
EasyCAT 0:7816b38c99cc 171 if (Sync_ == DC_SYNC)
EasyCAT 0:7816b38c99cc 172 { // enable interrupt from SYNC 0
EasyCAT 0:7816b38c99cc 173 SPIWriteRegisterIndirect (0x00000004, AL_EVENT_MASK, 4);
EasyCAT 0:7816b38c99cc 174 // in AL event mask register, and disable
EasyCAT 0:7816b38c99cc 175 // other interrupt sources
EasyCAT 0:7816b38c99cc 176 printf("DC_SYNC\n");
EasyCAT 0:7816b38c99cc 177 }
EasyCAT 0:7816b38c99cc 178
EasyCAT 0:7816b38c99cc 179 else
EasyCAT 0:7816b38c99cc 180 { // enable interrupt from SM 0 event
EasyCAT 0:7816b38c99cc 181 SPIWriteRegisterIndirect (0x00000100, AL_EVENT_MASK, 4);
EasyCAT 0:7816b38c99cc 182 // in AL event mask register, and disable
EasyCAT 0:7816b38c99cc 183 // other interrupt sources
EasyCAT 0:7816b38c99cc 184 printf("SM_SYNC\n");
EasyCAT 0:7816b38c99cc 185 }
EasyCAT 0:7816b38c99cc 186
EasyCAT 0:7816b38c99cc 187 SPIWriteRegisterDirect (IRQ_CFG, 0x00000111); // set LAN9252 interrupt pin driver
EasyCAT 0:7816b38c99cc 188 // as push-pull active high
EasyCAT 0:7816b38c99cc 189 // (On the EasyCAT shield board the IRQ pin
EasyCAT 0:7816b38c99cc 190 // is inverted by a mosfet, so Arduino
EasyCAT 0:7816b38c99cc 191 // receives an active low signal)
EasyCAT 0:7816b38c99cc 192
EasyCAT 0:7816b38c99cc 193 SPIWriteRegisterDirect (INT_EN, 0x00000001); // enable LAN9252 interrupt
EasyCAT 0:7816b38c99cc 194 }
EasyCAT 0:7816b38c99cc 195
EasyCAT 0:7816b38c99cc 196 else
EasyCAT 0:7816b38c99cc 197 {
EasyCAT 0:7816b38c99cc 198 printf("ASYNC\n");
EasyCAT 0:7816b38c99cc 199 }
EasyCAT 0:7816b38c99cc 200
EasyCAT 0:7816b38c99cc 201
EasyCAT 0:7816b38c99cc 202 TempLong.Long = SPIReadRegisterDirect (ID_REV, 4); // read the chip identification
EasyCAT 0:7816b38c99cc 203 printf ("Detected chip "); // and revision, and print it
EasyCAT 0:7816b38c99cc 204 printf ("%x ", TempLong.Word[1]); // out on the serial line
EasyCAT 0:7816b38c99cc 205 printf (" Rev "); //
EasyCAT 0:7816b38c99cc 206 printf ("%u \n", TempLong.Word[0]); //
EasyCAT 0:7816b38c99cc 207
EasyCAT 0:7816b38c99cc 208
EasyCAT 0:7816b38c99cc 209 /*
EasyCAT 0:7816b38c99cc 210 printf ("%u \n", TOT_BYTE_NUM_OUT);
EasyCAT 0:7816b38c99cc 211 printf ("%u \n", BYTE_NUM_OUT);
EasyCAT 0:7816b38c99cc 212 printf ("%u \n", BYTE_NUM_ROUND_OUT);
EasyCAT 0:7816b38c99cc 213 printf ("%u \n", LONG_NUM_OUT);
EasyCAT 0:7816b38c99cc 214
EasyCAT 0:7816b38c99cc 215 printf ("%u \n", SEC_BYTE_NUM_OUT);
EasyCAT 0:7816b38c99cc 216 printf ("%u \n", SEC_BYTE_NUM_ROUND_OUT);
EasyCAT 0:7816b38c99cc 217 printf ("%u \n\n", SEC_LONG_NUM_OUT);
EasyCAT 0:7816b38c99cc 218
EasyCAT 0:7816b38c99cc 219 printf ("%u \n", TOT_BYTE_NUM_IN);
EasyCAT 0:7816b38c99cc 220 printf ("%u \n", BYTE_NUM_IN);
EasyCAT 0:7816b38c99cc 221 printf ("%u \n", BYTE_NUM_ROUND_IN);
EasyCAT 0:7816b38c99cc 222 printf ("%u \n", LONG_NUM_IN);
EasyCAT 0:7816b38c99cc 223
EasyCAT 0:7816b38c99cc 224 printf ("%u \n", SEC_BYTE_NUM_IN);
EasyCAT 0:7816b38c99cc 225 printf ("%u \n", SEC_BYTE_NUM_ROUND_IN);
EasyCAT 0:7816b38c99cc 226 printf ("%u \n", SEC_LONG_NUM_IN);
EasyCAT 0:7816b38c99cc 227 */
EasyCAT 0:7816b38c99cc 228
EasyCAT 0:7816b38c99cc 229
EasyCAT 0:7816b38c99cc 230 //--------------------------------------------------------------------------------------------
EasyCAT 0:7816b38c99cc 231
EasyCAT 0:7816b38c99cc 232
EasyCAT 0:7816b38c99cc 233 return true; // initalization completed
EasyCAT 0:7816b38c99cc 234 };
EasyCAT 0:7816b38c99cc 235
EasyCAT 0:7816b38c99cc 236
EasyCAT 0:7816b38c99cc 237
EasyCAT 0:7816b38c99cc 238
EasyCAT 0:7816b38c99cc 239 //---- EtherCAT task ------------------------------------------------------------------------------
EasyCAT 0:7816b38c99cc 240
EasyCAT 0:7816b38c99cc 241 unsigned char EasyCAT::MainTask() // must be called cyclically by the application
EasyCAT 0:7816b38c99cc 242
EasyCAT 0:7816b38c99cc 243 {
EasyCAT 0:7816b38c99cc 244 bool WatchDog = true;
EasyCAT 0:7816b38c99cc 245 bool Operational = false;
EasyCAT 0:7816b38c99cc 246 unsigned char i;
EasyCAT 0:7816b38c99cc 247 ULONG TempLong;
EasyCAT 0:7816b38c99cc 248 unsigned char Status;
EasyCAT 0:7816b38c99cc 249
EasyCAT 0:7816b38c99cc 250
EasyCAT 0:7816b38c99cc 251 TempLong.Long = SPIReadRegisterIndirect (WDOG_STATUS, 1); // read watchdog status
EasyCAT 0:7816b38c99cc 252 if ((TempLong.Byte[0] & 0x01) == 0x01) //
EasyCAT 0:7816b38c99cc 253 WatchDog = false; // set/reset the corrisponding flag
EasyCAT 0:7816b38c99cc 254 else //
EasyCAT 0:7816b38c99cc 255 WatchDog = true; //
EasyCAT 0:7816b38c99cc 256
EasyCAT 0:7816b38c99cc 257
EasyCAT 0:7816b38c99cc 258 TempLong.Long = SPIReadRegisterIndirect (AL_STATUS, 1); // read the EtherCAT State Machine status
EasyCAT 0:7816b38c99cc 259 Status = TempLong.Byte[0] & 0x0F; //
EasyCAT 0:7816b38c99cc 260 if (Status == ESM_OP) // to see if we are in operational state
EasyCAT 0:7816b38c99cc 261 Operational = true; //
EasyCAT 0:7816b38c99cc 262 else // set/reset the corrisponding flag
EasyCAT 0:7816b38c99cc 263 Operational = false; //
EasyCAT 0:7816b38c99cc 264
EasyCAT 0:7816b38c99cc 265
EasyCAT 0:7816b38c99cc 266 //--- process data transfert ----------
EasyCAT 0:7816b38c99cc 267 //
EasyCAT 0:7816b38c99cc 268 if (WatchDog | !Operational) // if watchdog is active or we are
EasyCAT 0:7816b38c99cc 269 { // not in operational state, reset
EasyCAT 0:7816b38c99cc 270 for (i=0; i < TOT_BYTE_NUM_OUT ; i++) // the output buffer
EasyCAT 0:7816b38c99cc 271 BufferOut.Byte[i] = 0; //
EasyCAT 0:7816b38c99cc 272
EasyCAT 0:7816b38c99cc 273 /* // debug
EasyCAT 0:7816b38c99cc 274 if (!Operational) //
EasyCAT 0:7816b38c99cc 275 printf("Not operational\n"); //
EasyCAT 0:7816b38c99cc 276 if (WatchDog) //
EasyCAT 0:7816b38c99cc 277 printf("WatchDog\n"); //
EasyCAT 0:7816b38c99cc 278 */ //
EasyCAT 0:7816b38c99cc 279 }
EasyCAT 0:7816b38c99cc 280
EasyCAT 0:7816b38c99cc 281 else
EasyCAT 0:7816b38c99cc 282 {
EasyCAT 0:7816b38c99cc 283 SPIReadProcRamFifo(); // otherwise transfer process data from
EasyCAT 0:7816b38c99cc 284 } // the EtherCAT core to the output buffer
EasyCAT 0:7816b38c99cc 285
EasyCAT 0:7816b38c99cc 286 SPIWriteProcRamFifo(); // we always transfer process data from
EasyCAT 0:7816b38c99cc 287 // the input buffer to the EtherCAT core
EasyCAT 0:7816b38c99cc 288
EasyCAT 0:7816b38c99cc 289 if (WatchDog) // return the status of the State Machine
EasyCAT 0:7816b38c99cc 290 { // and of the watchdog
EasyCAT 0:7816b38c99cc 291 Status |= 0x80; //
EasyCAT 0:7816b38c99cc 292 } //
EasyCAT 0:7816b38c99cc 293 return Status; //
EasyCAT 0:7816b38c99cc 294
EasyCAT 0:7816b38c99cc 295 }
EasyCAT 0:7816b38c99cc 296
EasyCAT 0:7816b38c99cc 297
EasyCAT 0:7816b38c99cc 298
EasyCAT 0:7816b38c99cc 299 //---- read a directly addressable registers -----------------------------------------------------
EasyCAT 0:7816b38c99cc 300
EasyCAT 0:7816b38c99cc 301 unsigned long EasyCAT::SPIReadRegisterDirect (unsigned short Address, unsigned char Len)
EasyCAT 0:7816b38c99cc 302
EasyCAT 0:7816b38c99cc 303 // Address = register to read
EasyCAT 0:7816b38c99cc 304 // Len = number of bytes to read (1,2,3,4)
EasyCAT 0:7816b38c99cc 305 //
EasyCAT 0:7816b38c99cc 306 // a long is returned but only the requested bytes
EasyCAT 0:7816b38c99cc 307 // are meaningful, starting from LsByte
EasyCAT 0:7816b38c99cc 308 {
EasyCAT 0:7816b38c99cc 309 ULONG Result;
EasyCAT 0:7816b38c99cc 310 UWORD Addr;
EasyCAT 0:7816b38c99cc 311 Addr.Word = Address;
EasyCAT 0:7816b38c99cc 312
EasyCAT 0:7816b38c99cc 313 SCS_Low_macro // SPI chip select enable
EasyCAT 0:7816b38c99cc 314
daid 2:e0fc1b098ce8 315 char buffer[3] = {COMM_SPI_READ, Addr.Byte[1], Addr.Byte[0]};
daid 2:e0fc1b098ce8 316 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 317 SPI_TransferRxBuffer(Result.Byte, Len);
EasyCAT 0:7816b38c99cc 318
EasyCAT 0:7816b38c99cc 319 SCS_High_macro // SPI chip select disable
EasyCAT 0:7816b38c99cc 320
EasyCAT 0:7816b38c99cc 321 return Result.Long; // return the result
EasyCAT 0:7816b38c99cc 322 }
EasyCAT 0:7816b38c99cc 323
EasyCAT 0:7816b38c99cc 324
EasyCAT 0:7816b38c99cc 325
EasyCAT 0:7816b38c99cc 326
EasyCAT 0:7816b38c99cc 327 //---- write a directly addressable registers ----------------------------------------------------
EasyCAT 0:7816b38c99cc 328
EasyCAT 0:7816b38c99cc 329 void EasyCAT::SPIWriteRegisterDirect (unsigned short Address, unsigned long DataOut)
EasyCAT 0:7816b38c99cc 330
EasyCAT 0:7816b38c99cc 331 // Address = register to write
EasyCAT 0:7816b38c99cc 332 // DataOut = data to write
EasyCAT 0:7816b38c99cc 333 {
EasyCAT 0:7816b38c99cc 334 ULONG Data;
EasyCAT 0:7816b38c99cc 335 UWORD Addr;
EasyCAT 0:7816b38c99cc 336 Addr.Word = Address;
EasyCAT 0:7816b38c99cc 337 Data.Long = DataOut;
EasyCAT 0:7816b38c99cc 338
EasyCAT 0:7816b38c99cc 339 SCS_Low_macro // SPI chip select enable
EasyCAT 0:7816b38c99cc 340
daid 2:e0fc1b098ce8 341 char buffer[7] = {COMM_SPI_WRITE, Addr.Byte[1], Addr.Byte[0],
daid 2:e0fc1b098ce8 342 Data.Byte[0], Data.Byte[1], Data.Byte[2], Data.Byte[3]};
daid 2:e0fc1b098ce8 343 SPI_TransferTxBuffer(buffer, 7);
EasyCAT 0:7816b38c99cc 344
EasyCAT 0:7816b38c99cc 345 SCS_High_macro // SPI chip select enable
EasyCAT 0:7816b38c99cc 346 }
EasyCAT 0:7816b38c99cc 347
EasyCAT 0:7816b38c99cc 348
EasyCAT 0:7816b38c99cc 349 //---- read an undirectly addressable registers --------------------------------------------------
EasyCAT 0:7816b38c99cc 350
EasyCAT 0:7816b38c99cc 351 unsigned long EasyCAT::SPIReadRegisterIndirect (unsigned short Address, unsigned char Len)
EasyCAT 0:7816b38c99cc 352
EasyCAT 0:7816b38c99cc 353 // Address = register to read
EasyCAT 0:7816b38c99cc 354 // Len = number of bytes to read (1,2,3,4)
EasyCAT 0:7816b38c99cc 355 //
EasyCAT 0:7816b38c99cc 356 // a long is returned but only the requested bytes
EasyCAT 0:7816b38c99cc 357 // are meaningful, starting from LsByte
EasyCAT 0:7816b38c99cc 358 {
EasyCAT 0:7816b38c99cc 359 ULONG TempLong;
EasyCAT 0:7816b38c99cc 360 UWORD Addr;
EasyCAT 0:7816b38c99cc 361 Addr.Word = Address;
EasyCAT 0:7816b38c99cc 362 // compose the command
EasyCAT 0:7816b38c99cc 363 //
EasyCAT 0:7816b38c99cc 364 TempLong.Byte[0] = Addr.Byte[0]; // address of the register
EasyCAT 0:7816b38c99cc 365 TempLong.Byte[1] = Addr.Byte[1]; // to read, LsByte first
EasyCAT 0:7816b38c99cc 366 TempLong.Byte[2] = Len; // number of bytes to read
EasyCAT 0:7816b38c99cc 367 TempLong.Byte[3] = ESC_READ; // ESC read
EasyCAT 0:7816b38c99cc 368
EasyCAT 0:7816b38c99cc 369 SPIWriteRegisterDirect (ECAT_CSR_CMD, TempLong.Long); // write the command
EasyCAT 0:7816b38c99cc 370
EasyCAT 0:7816b38c99cc 371 do
EasyCAT 0:7816b38c99cc 372 { // wait for command execution
EasyCAT 0:7816b38c99cc 373 TempLong.Long = SPIReadRegisterDirect(ECAT_CSR_CMD,4); //
EasyCAT 0:7816b38c99cc 374 } //
EasyCAT 0:7816b38c99cc 375 while(TempLong.Byte[3] & ECAT_CSR_BUSY); //
EasyCAT 0:7816b38c99cc 376
EasyCAT 0:7816b38c99cc 377
EasyCAT 0:7816b38c99cc 378 TempLong.Long = SPIReadRegisterDirect(ECAT_CSR_DATA,Len); // read the requested register
EasyCAT 0:7816b38c99cc 379 return TempLong.Long; //
EasyCAT 0:7816b38c99cc 380 }
EasyCAT 0:7816b38c99cc 381
EasyCAT 0:7816b38c99cc 382
EasyCAT 0:7816b38c99cc 383 //---- write an undirectly addressable registers -------------------------------------------------
EasyCAT 0:7816b38c99cc 384
EasyCAT 0:7816b38c99cc 385 void EasyCAT::SPIWriteRegisterIndirect (unsigned long DataOut, unsigned short Address, unsigned char Len)
EasyCAT 0:7816b38c99cc 386
EasyCAT 0:7816b38c99cc 387 // Address = register to write
EasyCAT 0:7816b38c99cc 388 // DataOut = data to write
EasyCAT 0:7816b38c99cc 389 {
EasyCAT 0:7816b38c99cc 390 ULONG TempLong;
EasyCAT 0:7816b38c99cc 391 UWORD Addr;
EasyCAT 0:7816b38c99cc 392 Addr.Word = Address;
EasyCAT 0:7816b38c99cc 393
EasyCAT 0:7816b38c99cc 394
EasyCAT 0:7816b38c99cc 395 SPIWriteRegisterDirect (ECAT_CSR_DATA, DataOut); // write the data
EasyCAT 0:7816b38c99cc 396
EasyCAT 0:7816b38c99cc 397 // compose the command
EasyCAT 0:7816b38c99cc 398 //
EasyCAT 0:7816b38c99cc 399 TempLong.Byte[0] = Addr.Byte[0]; // address of the register
EasyCAT 0:7816b38c99cc 400 TempLong.Byte[1] = Addr.Byte[1]; // to write, LsByte first
EasyCAT 0:7816b38c99cc 401 TempLong.Byte[2] = Len; // number of bytes to write
EasyCAT 0:7816b38c99cc 402 TempLong.Byte[3] = ESC_WRITE; // ESC write
EasyCAT 0:7816b38c99cc 403
EasyCAT 0:7816b38c99cc 404 SPIWriteRegisterDirect (ECAT_CSR_CMD, TempLong.Long); // write the command
EasyCAT 0:7816b38c99cc 405
EasyCAT 0:7816b38c99cc 406 do // wait for command execution
EasyCAT 0:7816b38c99cc 407 { //
EasyCAT 0:7816b38c99cc 408 TempLong.Long = SPIReadRegisterDirect (ECAT_CSR_CMD, 4); //
EasyCAT 0:7816b38c99cc 409 } //
EasyCAT 0:7816b38c99cc 410 while (TempLong.Byte[3] & ECAT_CSR_BUSY); //
EasyCAT 0:7816b38c99cc 411 }
EasyCAT 0:7816b38c99cc 412
EasyCAT 0:7816b38c99cc 413
EasyCAT 0:7816b38c99cc 414 //---- read from process ram fifo ----------------------------------------------------------------
EasyCAT 0:7816b38c99cc 415
EasyCAT 0:7816b38c99cc 416
EasyCAT 0:7816b38c99cc 417 void EasyCAT::SPIReadProcRamFifo() // read BYTE_NUM bytes from the output process ram, through the fifo
EasyCAT 0:7816b38c99cc 418 //
EasyCAT 0:7816b38c99cc 419 // these are the bytes received from the EtherCAT master and
EasyCAT 0:7816b38c99cc 420 // that will be use by our application to write the outputs
EasyCAT 0:7816b38c99cc 421 {
EasyCAT 0:7816b38c99cc 422 ULONG TempLong;
EasyCAT 0:7816b38c99cc 423
EasyCAT 0:7816b38c99cc 424 #if TOT_BYTE_NUM_OUT > 0
EasyCAT 0:7816b38c99cc 425
EasyCAT 0:7816b38c99cc 426 SPIWriteRegisterDirect (ECAT_PRAM_RD_CMD, PRAM_ABORT); // abort any possible pending transfer
EasyCAT 0:7816b38c99cc 427
EasyCAT 0:7816b38c99cc 428
EasyCAT 0:7816b38c99cc 429 SPIWriteRegisterDirect (ECAT_PRAM_RD_ADDR_LEN, (0x00001000 | (((uint32_t)TOT_BYTE_NUM_OUT) << 16)));
EasyCAT 0:7816b38c99cc 430 // the high word is the num of bytes
EasyCAT 0:7816b38c99cc 431 // to read 0xTOT_BYTE_NUM_OUT----
EasyCAT 0:7816b38c99cc 432 // the low word is the output process
EasyCAT 0:7816b38c99cc 433 // ram offset 0x----1000
EasyCAT 0:7816b38c99cc 434
EasyCAT 0:7816b38c99cc 435 SPIWriteRegisterDirect (ECAT_PRAM_RD_CMD, 0x80000000); // start command
EasyCAT 0:7816b38c99cc 436
EasyCAT 0:7816b38c99cc 437
EasyCAT 0:7816b38c99cc 438 //------- one round is enough if we have ----
EasyCAT 0:7816b38c99cc 439 //------- to transfer up to 64 bytes --------
EasyCAT 0:7816b38c99cc 440
EasyCAT 0:7816b38c99cc 441 do // wait for the data to be
EasyCAT 0:7816b38c99cc 442 { // transferred from the output
EasyCAT 0:7816b38c99cc 443 TempLong.Long = SPIReadRegisterDirect (ECAT_PRAM_RD_CMD,2); // process ram to the read fifo
EasyCAT 0:7816b38c99cc 444 } //
EasyCAT 0:7816b38c99cc 445 while (TempLong.Byte[1] != FST_LONG_NUM_OUT); //
EasyCAT 0:7816b38c99cc 446
EasyCAT 0:7816b38c99cc 447 SCS_Low_macro // enable SPI chip select
EasyCAT 0:7816b38c99cc 448
daid 2:e0fc1b098ce8 449 char buffer[3] = {COMM_SPI_READ, 0, 0x00};
daid 2:e0fc1b098ce8 450 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 451 SPI_TransferRxBuffer(BufferOut.Byte, FST_BYTE_NUM_ROUND_OUT);
EasyCAT 0:7816b38c99cc 452
EasyCAT 0:7816b38c99cc 453 SCS_High_macro // disable SPI chip select
EasyCAT 0:7816b38c99cc 454 #endif
EasyCAT 0:7816b38c99cc 455
EasyCAT 0:7816b38c99cc 456
EasyCAT 0:7816b38c99cc 457 #if SEC_BYTE_NUM_OUT > 0 //-- if we have to transfer more then 64 bytes --
EasyCAT 0:7816b38c99cc 458 //-- we must do another round -------------------
EasyCAT 0:7816b38c99cc 459 //-- to transfer the remainig bytes -------------
EasyCAT 0:7816b38c99cc 460
EasyCAT 0:7816b38c99cc 461
EasyCAT 0:7816b38c99cc 462 do // wait for the data to be
EasyCAT 0:7816b38c99cc 463 { // transferred from the output
EasyCAT 0:7816b38c99cc 464 TempLong.Long = SPIReadRegisterDirect(ECAT_PRAM_RD_CMD,2);// process ram to the read fifo
EasyCAT 0:7816b38c99cc 465 } //
EasyCAT 0:7816b38c99cc 466 while (TempLong.Byte[1] != SEC_LONG_NUM_OUT); //
EasyCAT 0:7816b38c99cc 467
EasyCAT 0:7816b38c99cc 468 SCS_Low_macro // enable SPI chip select
EasyCAT 0:7816b38c99cc 469
daid 2:e0fc1b098ce8 470 char buffer[3] = {COMM_SPI_READ, 0, 0x00};
daid 2:e0fc1b098ce8 471 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 472 SPI_TransferRxBuffer(&BufferOut.Byte[64], SEC_BYTE_NUM_ROUND_OUT);
EasyCAT 0:7816b38c99cc 473
EasyCAT 0:7816b38c99cc 474 SCS_High_macro // SPI chip select disable
EasyCAT 0:7816b38c99cc 475 #endif
EasyCAT 0:7816b38c99cc 476 }
EasyCAT 0:7816b38c99cc 477
EasyCAT 0:7816b38c99cc 478
EasyCAT 0:7816b38c99cc 479 //---- write to the process ram fifo --------------------------------------------------------------
EasyCAT 0:7816b38c99cc 480
EasyCAT 0:7816b38c99cc 481 void EasyCAT::SPIWriteProcRamFifo() // write BYTE_NUM bytes to the input process ram, through the fifo
EasyCAT 0:7816b38c99cc 482 //
EasyCAT 0:7816b38c99cc 483 // these are the bytes that we have read from the inputs of our
EasyCAT 0:7816b38c99cc 484 // application and that will be sent to the EtherCAT master
EasyCAT 0:7816b38c99cc 485 {
EasyCAT 0:7816b38c99cc 486 ULONG TempLong;
EasyCAT 0:7816b38c99cc 487
EasyCAT 0:7816b38c99cc 488
EasyCAT 0:7816b38c99cc 489
EasyCAT 0:7816b38c99cc 490 #if TOT_BYTE_NUM_IN > 0
EasyCAT 0:7816b38c99cc 491
EasyCAT 0:7816b38c99cc 492 SPIWriteRegisterDirect (ECAT_PRAM_WR_CMD, PRAM_ABORT); // abort any possible pending transfer
EasyCAT 0:7816b38c99cc 493
EasyCAT 0:7816b38c99cc 494
EasyCAT 0:7816b38c99cc 495 SPIWriteRegisterDirect (ECAT_PRAM_WR_ADDR_LEN, (0x00001200 | (((uint32_t)TOT_BYTE_NUM_IN) << 16)));
EasyCAT 0:7816b38c99cc 496 // the high word is the num of bytes
EasyCAT 0:7816b38c99cc 497 // to write 0xTOT_BYTE_NUM_IN----
EasyCAT 0:7816b38c99cc 498 // the low word is the input process
EasyCAT 0:7816b38c99cc 499 // ram offset 0x----1200
EasyCAT 0:7816b38c99cc 500
EasyCAT 0:7816b38c99cc 501 SPIWriteRegisterDirect (ECAT_PRAM_WR_CMD, 0x80000000); // start command
EasyCAT 0:7816b38c99cc 502
EasyCAT 0:7816b38c99cc 503
EasyCAT 0:7816b38c99cc 504 //------- one round is enough if we have ----
EasyCAT 0:7816b38c99cc 505 //------- to transfer up to 64 bytes --------
EasyCAT 0:7816b38c99cc 506
EasyCAT 0:7816b38c99cc 507 do // check that the fifo has
EasyCAT 0:7816b38c99cc 508 { // enough free space
EasyCAT 0:7816b38c99cc 509 TempLong.Long = SPIReadRegisterDirect (ECAT_PRAM_WR_CMD,2); //
EasyCAT 0:7816b38c99cc 510 } //
EasyCAT 0:7816b38c99cc 511 while (TempLong.Byte[1] < FST_LONG_NUM_IN); //
EasyCAT 0:7816b38c99cc 512
EasyCAT 0:7816b38c99cc 513 SCS_Low_macro // enable SPI chip select
EasyCAT 0:7816b38c99cc 514
daid 2:e0fc1b098ce8 515 char buffer[3] = {COMM_SPI_WRITE, 0x00, 0x20};
daid 2:e0fc1b098ce8 516 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 517 SPI_TransferTxBuffer(BufferIn.Byte, FST_BYTE_NUM_ROUND_IN);
EasyCAT 0:7816b38c99cc 518
EasyCAT 0:7816b38c99cc 519 SCS_High_macro // disable SPI chip select
EasyCAT 0:7816b38c99cc 520 #endif
EasyCAT 0:7816b38c99cc 521
EasyCAT 0:7816b38c99cc 522
EasyCAT 0:7816b38c99cc 523 #if SEC_BYTE_NUM_IN > 0 //-- if we have to transfer more then 64 bytes --
EasyCAT 0:7816b38c99cc 524 //-- we must do another round -------------------
EasyCAT 0:7816b38c99cc 525 //-- to transfer the remainig bytes -------------
EasyCAT 0:7816b38c99cc 526
EasyCAT 0:7816b38c99cc 527 do // check that the fifo has
EasyCAT 0:7816b38c99cc 528 { // enough free space
EasyCAT 0:7816b38c99cc 529 TempLong.Long = SPIReadRegisterDirect(ECAT_PRAM_WR_CMD,2);//
EasyCAT 0:7816b38c99cc 530 } //
EasyCAT 0:7816b38c99cc 531 while (TempLong.Byte[1] < (SEC_LONG_NUM_IN)); //
EasyCAT 0:7816b38c99cc 532
EasyCAT 0:7816b38c99cc 533 SCS_Low_macro // enable SPI chip select
EasyCAT 0:7816b38c99cc 534
daid 2:e0fc1b098ce8 535 char buffer[3] = {COMM_SPI_WRITE, 0x00, 0x20};
daid 2:e0fc1b098ce8 536 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 537 SPI_TransferTxBuffer(&BufferIn.Byte[64], SEC_BYTE_NUM_ROUND_IN);
EasyCAT 0:7816b38c99cc 538
EasyCAT 0:7816b38c99cc 539 SCS_High_macro // disable SPI chip select
EasyCAT 0:7816b38c99cc 540 #endif
EasyCAT 0:7816b38c99cc 541 }