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:
EasyCAT
Date:
Sat Apr 10 14:49:17 2021 +0000
Revision:
3:7d8b74ba7225
Parent:
2:e0fc1b098ce8
Updated for OS6 compatibility

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 3:7d8b74ba7225 114
EasyCAT 3:7d8b74ba7225 115 #if (MBED_MAJOR_VERSION != 2)
EasyCAT 3:7d8b74ba7225 116 ThisThread::sleep_for(100ms);
EasyCAT 3:7d8b74ba7225 117 #else
EasyCAT 3:7d8b74ba7225 118 wait_ms(100);
EasyCAT 3:7d8b74ba7225 119 #endif
EasyCAT 0:7816b38c99cc 120
EasyCAT 0:7816b38c99cc 121 SPIWriteRegisterDirect (RESET_CTL, DIGITAL_RST); // LAN9252 reset
EasyCAT 0:7816b38c99cc 122
EasyCAT 0:7816b38c99cc 123 i = 0; // reset timeout
EasyCAT 0:7816b38c99cc 124 do // wait for reset to complete
EasyCAT 0:7816b38c99cc 125 { //
EasyCAT 0:7816b38c99cc 126 i++; //
EasyCAT 0:7816b38c99cc 127 TempLong.Long = SPIReadRegisterDirect (RESET_CTL, 4); //
EasyCAT 0:7816b38c99cc 128 }while (((TempLong.Byte[0] & 0x01) != 0x00) && (i != Tout));
EasyCAT 0:7816b38c99cc 129 //
EasyCAT 0:7816b38c99cc 130 if (i == Tout) // time out expired
EasyCAT 0:7816b38c99cc 131 { //
EasyCAT 0:7816b38c99cc 132 return false; // initialization failed
EasyCAT 0:7816b38c99cc 133 }
EasyCAT 0:7816b38c99cc 134
EasyCAT 0:7816b38c99cc 135 i = 0; // reset timeout
EasyCAT 0:7816b38c99cc 136 do // check the Byte Order Test Register
EasyCAT 0:7816b38c99cc 137 { //
EasyCAT 0:7816b38c99cc 138 i++; //
EasyCAT 0:7816b38c99cc 139 TempLong.Long = SPIReadRegisterDirect (BYTE_TEST, 4); //
EasyCAT 0:7816b38c99cc 140 }while ((TempLong.Long != 0x87654321) && (i != Tout)); //
EasyCAT 0:7816b38c99cc 141 //
EasyCAT 0:7816b38c99cc 142 if (i == Tout) // time out expired
EasyCAT 0:7816b38c99cc 143 { //
EasyCAT 0:7816b38c99cc 144 return false; // initialization failed
EasyCAT 0:7816b38c99cc 145 }
EasyCAT 0:7816b38c99cc 146
EasyCAT 0:7816b38c99cc 147 i = 0; // reset timeout
EasyCAT 0:7816b38c99cc 148 do // check the Ready flag
EasyCAT 0:7816b38c99cc 149 { //
EasyCAT 0:7816b38c99cc 150 i++; //
EasyCAT 0:7816b38c99cc 151 TempLong.Long = SPIReadRegisterDirect (HW_CFG, 4); //
EasyCAT 0:7816b38c99cc 152 }while (((TempLong.Byte[3] & READY) == 0) && (i != Tout));//
EasyCAT 0:7816b38c99cc 153 //
EasyCAT 0:7816b38c99cc 154 if (i == Tout) // time out expired
EasyCAT 0:7816b38c99cc 155 { //
EasyCAT 0:7816b38c99cc 156 return false; // initialization failed
EasyCAT 0:7816b38c99cc 157 }
EasyCAT 0:7816b38c99cc 158
EasyCAT 0:7816b38c99cc 159
EasyCAT 0:7816b38c99cc 160
EasyCAT 0:7816b38c99cc 161 #ifdef BYTE_NUM
EasyCAT 0:7816b38c99cc 162 printf ("STANDARD MODE\n");
EasyCAT 0:7816b38c99cc 163 #else
EasyCAT 0:7816b38c99cc 164 printf ("CUSTOM MODE\n");
EasyCAT 0:7816b38c99cc 165 #endif
EasyCAT 0:7816b38c99cc 166
EasyCAT 0:7816b38c99cc 167 printf ("%u Byte Out\n",TOT_BYTE_NUM_OUT);
EasyCAT 0:7816b38c99cc 168 printf ("%u Byte In\n",TOT_BYTE_NUM_IN);
EasyCAT 0:7816b38c99cc 169
EasyCAT 0:7816b38c99cc 170 printf ("Sync = ");
EasyCAT 0:7816b38c99cc 171
EasyCAT 0:7816b38c99cc 172
EasyCAT 0:7816b38c99cc 173 if ((Sync_ == DC_SYNC) || (Sync_ == SM_SYNC)) //--- if requested, enable --------
EasyCAT 0:7816b38c99cc 174 { //--- interrupt generation --------
EasyCAT 0:7816b38c99cc 175
EasyCAT 0:7816b38c99cc 176 if (Sync_ == DC_SYNC)
EasyCAT 0:7816b38c99cc 177 { // enable interrupt from SYNC 0
EasyCAT 0:7816b38c99cc 178 SPIWriteRegisterIndirect (0x00000004, AL_EVENT_MASK, 4);
EasyCAT 0:7816b38c99cc 179 // in AL event mask register, and disable
EasyCAT 0:7816b38c99cc 180 // other interrupt sources
EasyCAT 0:7816b38c99cc 181 printf("DC_SYNC\n");
EasyCAT 0:7816b38c99cc 182 }
EasyCAT 0:7816b38c99cc 183
EasyCAT 0:7816b38c99cc 184 else
EasyCAT 0:7816b38c99cc 185 { // enable interrupt from SM 0 event
EasyCAT 0:7816b38c99cc 186 SPIWriteRegisterIndirect (0x00000100, AL_EVENT_MASK, 4);
EasyCAT 0:7816b38c99cc 187 // in AL event mask register, and disable
EasyCAT 0:7816b38c99cc 188 // other interrupt sources
EasyCAT 0:7816b38c99cc 189 printf("SM_SYNC\n");
EasyCAT 0:7816b38c99cc 190 }
EasyCAT 0:7816b38c99cc 191
EasyCAT 0:7816b38c99cc 192 SPIWriteRegisterDirect (IRQ_CFG, 0x00000111); // set LAN9252 interrupt pin driver
EasyCAT 0:7816b38c99cc 193 // as push-pull active high
EasyCAT 0:7816b38c99cc 194 // (On the EasyCAT shield board the IRQ pin
EasyCAT 0:7816b38c99cc 195 // is inverted by a mosfet, so Arduino
EasyCAT 0:7816b38c99cc 196 // receives an active low signal)
EasyCAT 0:7816b38c99cc 197
EasyCAT 0:7816b38c99cc 198 SPIWriteRegisterDirect (INT_EN, 0x00000001); // enable LAN9252 interrupt
EasyCAT 0:7816b38c99cc 199 }
EasyCAT 0:7816b38c99cc 200
EasyCAT 0:7816b38c99cc 201 else
EasyCAT 0:7816b38c99cc 202 {
EasyCAT 0:7816b38c99cc 203 printf("ASYNC\n");
EasyCAT 0:7816b38c99cc 204 }
EasyCAT 0:7816b38c99cc 205
EasyCAT 0:7816b38c99cc 206
EasyCAT 0:7816b38c99cc 207 TempLong.Long = SPIReadRegisterDirect (ID_REV, 4); // read the chip identification
EasyCAT 0:7816b38c99cc 208 printf ("Detected chip "); // and revision, and print it
EasyCAT 0:7816b38c99cc 209 printf ("%x ", TempLong.Word[1]); // out on the serial line
EasyCAT 0:7816b38c99cc 210 printf (" Rev "); //
EasyCAT 0:7816b38c99cc 211 printf ("%u \n", TempLong.Word[0]); //
EasyCAT 0:7816b38c99cc 212
EasyCAT 0:7816b38c99cc 213
EasyCAT 0:7816b38c99cc 214 /*
EasyCAT 0:7816b38c99cc 215 printf ("%u \n", TOT_BYTE_NUM_OUT);
EasyCAT 0:7816b38c99cc 216 printf ("%u \n", BYTE_NUM_OUT);
EasyCAT 0:7816b38c99cc 217 printf ("%u \n", BYTE_NUM_ROUND_OUT);
EasyCAT 0:7816b38c99cc 218 printf ("%u \n", LONG_NUM_OUT);
EasyCAT 0:7816b38c99cc 219
EasyCAT 0:7816b38c99cc 220 printf ("%u \n", SEC_BYTE_NUM_OUT);
EasyCAT 0:7816b38c99cc 221 printf ("%u \n", SEC_BYTE_NUM_ROUND_OUT);
EasyCAT 0:7816b38c99cc 222 printf ("%u \n\n", SEC_LONG_NUM_OUT);
EasyCAT 0:7816b38c99cc 223
EasyCAT 0:7816b38c99cc 224 printf ("%u \n", TOT_BYTE_NUM_IN);
EasyCAT 0:7816b38c99cc 225 printf ("%u \n", BYTE_NUM_IN);
EasyCAT 0:7816b38c99cc 226 printf ("%u \n", BYTE_NUM_ROUND_IN);
EasyCAT 0:7816b38c99cc 227 printf ("%u \n", LONG_NUM_IN);
EasyCAT 0:7816b38c99cc 228
EasyCAT 0:7816b38c99cc 229 printf ("%u \n", SEC_BYTE_NUM_IN);
EasyCAT 0:7816b38c99cc 230 printf ("%u \n", SEC_BYTE_NUM_ROUND_IN);
EasyCAT 0:7816b38c99cc 231 printf ("%u \n", SEC_LONG_NUM_IN);
EasyCAT 0:7816b38c99cc 232 */
EasyCAT 0:7816b38c99cc 233
EasyCAT 0:7816b38c99cc 234
EasyCAT 0:7816b38c99cc 235 //--------------------------------------------------------------------------------------------
EasyCAT 0:7816b38c99cc 236
EasyCAT 0:7816b38c99cc 237
EasyCAT 0:7816b38c99cc 238 return true; // initalization completed
EasyCAT 0:7816b38c99cc 239 };
EasyCAT 0:7816b38c99cc 240
EasyCAT 0:7816b38c99cc 241
EasyCAT 0:7816b38c99cc 242
EasyCAT 0:7816b38c99cc 243
EasyCAT 0:7816b38c99cc 244 //---- EtherCAT task ------------------------------------------------------------------------------
EasyCAT 0:7816b38c99cc 245
EasyCAT 0:7816b38c99cc 246 unsigned char EasyCAT::MainTask() // must be called cyclically by the application
EasyCAT 0:7816b38c99cc 247
EasyCAT 0:7816b38c99cc 248 {
EasyCAT 0:7816b38c99cc 249 bool WatchDog = true;
EasyCAT 0:7816b38c99cc 250 bool Operational = false;
EasyCAT 0:7816b38c99cc 251 unsigned char i;
EasyCAT 0:7816b38c99cc 252 ULONG TempLong;
EasyCAT 0:7816b38c99cc 253 unsigned char Status;
EasyCAT 0:7816b38c99cc 254
EasyCAT 0:7816b38c99cc 255
EasyCAT 0:7816b38c99cc 256 TempLong.Long = SPIReadRegisterIndirect (WDOG_STATUS, 1); // read watchdog status
EasyCAT 0:7816b38c99cc 257 if ((TempLong.Byte[0] & 0x01) == 0x01) //
EasyCAT 0:7816b38c99cc 258 WatchDog = false; // set/reset the corrisponding flag
EasyCAT 0:7816b38c99cc 259 else //
EasyCAT 0:7816b38c99cc 260 WatchDog = true; //
EasyCAT 0:7816b38c99cc 261
EasyCAT 0:7816b38c99cc 262
EasyCAT 0:7816b38c99cc 263 TempLong.Long = SPIReadRegisterIndirect (AL_STATUS, 1); // read the EtherCAT State Machine status
EasyCAT 0:7816b38c99cc 264 Status = TempLong.Byte[0] & 0x0F; //
EasyCAT 0:7816b38c99cc 265 if (Status == ESM_OP) // to see if we are in operational state
EasyCAT 0:7816b38c99cc 266 Operational = true; //
EasyCAT 0:7816b38c99cc 267 else // set/reset the corrisponding flag
EasyCAT 0:7816b38c99cc 268 Operational = false; //
EasyCAT 0:7816b38c99cc 269
EasyCAT 0:7816b38c99cc 270
EasyCAT 0:7816b38c99cc 271 //--- process data transfert ----------
EasyCAT 0:7816b38c99cc 272 //
EasyCAT 0:7816b38c99cc 273 if (WatchDog | !Operational) // if watchdog is active or we are
EasyCAT 0:7816b38c99cc 274 { // not in operational state, reset
EasyCAT 0:7816b38c99cc 275 for (i=0; i < TOT_BYTE_NUM_OUT ; i++) // the output buffer
EasyCAT 0:7816b38c99cc 276 BufferOut.Byte[i] = 0; //
EasyCAT 0:7816b38c99cc 277
EasyCAT 0:7816b38c99cc 278 /* // debug
EasyCAT 0:7816b38c99cc 279 if (!Operational) //
EasyCAT 0:7816b38c99cc 280 printf("Not operational\n"); //
EasyCAT 0:7816b38c99cc 281 if (WatchDog) //
EasyCAT 0:7816b38c99cc 282 printf("WatchDog\n"); //
EasyCAT 0:7816b38c99cc 283 */ //
EasyCAT 0:7816b38c99cc 284 }
EasyCAT 0:7816b38c99cc 285
EasyCAT 0:7816b38c99cc 286 else
EasyCAT 0:7816b38c99cc 287 {
EasyCAT 0:7816b38c99cc 288 SPIReadProcRamFifo(); // otherwise transfer process data from
EasyCAT 0:7816b38c99cc 289 } // the EtherCAT core to the output buffer
EasyCAT 0:7816b38c99cc 290
EasyCAT 0:7816b38c99cc 291 SPIWriteProcRamFifo(); // we always transfer process data from
EasyCAT 0:7816b38c99cc 292 // the input buffer to the EtherCAT core
EasyCAT 0:7816b38c99cc 293
EasyCAT 0:7816b38c99cc 294 if (WatchDog) // return the status of the State Machine
EasyCAT 0:7816b38c99cc 295 { // and of the watchdog
EasyCAT 0:7816b38c99cc 296 Status |= 0x80; //
EasyCAT 0:7816b38c99cc 297 } //
EasyCAT 0:7816b38c99cc 298 return Status; //
EasyCAT 0:7816b38c99cc 299
EasyCAT 0:7816b38c99cc 300 }
EasyCAT 0:7816b38c99cc 301
EasyCAT 0:7816b38c99cc 302
EasyCAT 0:7816b38c99cc 303
EasyCAT 0:7816b38c99cc 304 //---- read a directly addressable registers -----------------------------------------------------
EasyCAT 0:7816b38c99cc 305
EasyCAT 0:7816b38c99cc 306 unsigned long EasyCAT::SPIReadRegisterDirect (unsigned short Address, unsigned char Len)
EasyCAT 0:7816b38c99cc 307
EasyCAT 0:7816b38c99cc 308 // Address = register to read
EasyCAT 0:7816b38c99cc 309 // Len = number of bytes to read (1,2,3,4)
EasyCAT 0:7816b38c99cc 310 //
EasyCAT 0:7816b38c99cc 311 // a long is returned but only the requested bytes
EasyCAT 0:7816b38c99cc 312 // are meaningful, starting from LsByte
EasyCAT 0:7816b38c99cc 313 {
EasyCAT 0:7816b38c99cc 314 ULONG Result;
EasyCAT 0:7816b38c99cc 315 UWORD Addr;
EasyCAT 0:7816b38c99cc 316 Addr.Word = Address;
EasyCAT 0:7816b38c99cc 317
EasyCAT 0:7816b38c99cc 318 SCS_Low_macro // SPI chip select enable
EasyCAT 0:7816b38c99cc 319
daid 2:e0fc1b098ce8 320 char buffer[3] = {COMM_SPI_READ, Addr.Byte[1], Addr.Byte[0]};
daid 2:e0fc1b098ce8 321 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 322 SPI_TransferRxBuffer(Result.Byte, Len);
EasyCAT 0:7816b38c99cc 323
EasyCAT 0:7816b38c99cc 324 SCS_High_macro // SPI chip select disable
EasyCAT 0:7816b38c99cc 325
EasyCAT 0:7816b38c99cc 326 return Result.Long; // return the result
EasyCAT 0:7816b38c99cc 327 }
EasyCAT 0:7816b38c99cc 328
EasyCAT 0:7816b38c99cc 329
EasyCAT 0:7816b38c99cc 330
EasyCAT 0:7816b38c99cc 331
EasyCAT 0:7816b38c99cc 332 //---- write a directly addressable registers ----------------------------------------------------
EasyCAT 0:7816b38c99cc 333
EasyCAT 0:7816b38c99cc 334 void EasyCAT::SPIWriteRegisterDirect (unsigned short Address, unsigned long DataOut)
EasyCAT 0:7816b38c99cc 335
EasyCAT 0:7816b38c99cc 336 // Address = register to write
EasyCAT 0:7816b38c99cc 337 // DataOut = data to write
EasyCAT 0:7816b38c99cc 338 {
EasyCAT 0:7816b38c99cc 339 ULONG Data;
EasyCAT 0:7816b38c99cc 340 UWORD Addr;
EasyCAT 0:7816b38c99cc 341 Addr.Word = Address;
EasyCAT 0:7816b38c99cc 342 Data.Long = DataOut;
EasyCAT 0:7816b38c99cc 343
EasyCAT 0:7816b38c99cc 344 SCS_Low_macro // SPI chip select enable
EasyCAT 0:7816b38c99cc 345
daid 2:e0fc1b098ce8 346 char buffer[7] = {COMM_SPI_WRITE, Addr.Byte[1], Addr.Byte[0],
daid 2:e0fc1b098ce8 347 Data.Byte[0], Data.Byte[1], Data.Byte[2], Data.Byte[3]};
daid 2:e0fc1b098ce8 348 SPI_TransferTxBuffer(buffer, 7);
EasyCAT 0:7816b38c99cc 349
EasyCAT 0:7816b38c99cc 350 SCS_High_macro // SPI chip select enable
EasyCAT 0:7816b38c99cc 351 }
EasyCAT 0:7816b38c99cc 352
EasyCAT 0:7816b38c99cc 353
EasyCAT 0:7816b38c99cc 354 //---- read an undirectly addressable registers --------------------------------------------------
EasyCAT 0:7816b38c99cc 355
EasyCAT 0:7816b38c99cc 356 unsigned long EasyCAT::SPIReadRegisterIndirect (unsigned short Address, unsigned char Len)
EasyCAT 0:7816b38c99cc 357
EasyCAT 0:7816b38c99cc 358 // Address = register to read
EasyCAT 0:7816b38c99cc 359 // Len = number of bytes to read (1,2,3,4)
EasyCAT 0:7816b38c99cc 360 //
EasyCAT 0:7816b38c99cc 361 // a long is returned but only the requested bytes
EasyCAT 0:7816b38c99cc 362 // are meaningful, starting from LsByte
EasyCAT 0:7816b38c99cc 363 {
EasyCAT 0:7816b38c99cc 364 ULONG TempLong;
EasyCAT 0:7816b38c99cc 365 UWORD Addr;
EasyCAT 0:7816b38c99cc 366 Addr.Word = Address;
EasyCAT 0:7816b38c99cc 367 // compose the command
EasyCAT 0:7816b38c99cc 368 //
EasyCAT 0:7816b38c99cc 369 TempLong.Byte[0] = Addr.Byte[0]; // address of the register
EasyCAT 0:7816b38c99cc 370 TempLong.Byte[1] = Addr.Byte[1]; // to read, LsByte first
EasyCAT 0:7816b38c99cc 371 TempLong.Byte[2] = Len; // number of bytes to read
EasyCAT 0:7816b38c99cc 372 TempLong.Byte[3] = ESC_READ; // ESC read
EasyCAT 0:7816b38c99cc 373
EasyCAT 0:7816b38c99cc 374 SPIWriteRegisterDirect (ECAT_CSR_CMD, TempLong.Long); // write the command
EasyCAT 0:7816b38c99cc 375
EasyCAT 0:7816b38c99cc 376 do
EasyCAT 0:7816b38c99cc 377 { // wait for command execution
EasyCAT 0:7816b38c99cc 378 TempLong.Long = SPIReadRegisterDirect(ECAT_CSR_CMD,4); //
EasyCAT 0:7816b38c99cc 379 } //
EasyCAT 0:7816b38c99cc 380 while(TempLong.Byte[3] & ECAT_CSR_BUSY); //
EasyCAT 0:7816b38c99cc 381
EasyCAT 0:7816b38c99cc 382
EasyCAT 0:7816b38c99cc 383 TempLong.Long = SPIReadRegisterDirect(ECAT_CSR_DATA,Len); // read the requested register
EasyCAT 0:7816b38c99cc 384 return TempLong.Long; //
EasyCAT 0:7816b38c99cc 385 }
EasyCAT 0:7816b38c99cc 386
EasyCAT 0:7816b38c99cc 387
EasyCAT 0:7816b38c99cc 388 //---- write an undirectly addressable registers -------------------------------------------------
EasyCAT 0:7816b38c99cc 389
EasyCAT 0:7816b38c99cc 390 void EasyCAT::SPIWriteRegisterIndirect (unsigned long DataOut, unsigned short Address, unsigned char Len)
EasyCAT 0:7816b38c99cc 391
EasyCAT 0:7816b38c99cc 392 // Address = register to write
EasyCAT 0:7816b38c99cc 393 // DataOut = data to write
EasyCAT 0:7816b38c99cc 394 {
EasyCAT 0:7816b38c99cc 395 ULONG TempLong;
EasyCAT 0:7816b38c99cc 396 UWORD Addr;
EasyCAT 0:7816b38c99cc 397 Addr.Word = Address;
EasyCAT 0:7816b38c99cc 398
EasyCAT 0:7816b38c99cc 399
EasyCAT 0:7816b38c99cc 400 SPIWriteRegisterDirect (ECAT_CSR_DATA, DataOut); // write the data
EasyCAT 0:7816b38c99cc 401
EasyCAT 0:7816b38c99cc 402 // compose the command
EasyCAT 0:7816b38c99cc 403 //
EasyCAT 0:7816b38c99cc 404 TempLong.Byte[0] = Addr.Byte[0]; // address of the register
EasyCAT 0:7816b38c99cc 405 TempLong.Byte[1] = Addr.Byte[1]; // to write, LsByte first
EasyCAT 0:7816b38c99cc 406 TempLong.Byte[2] = Len; // number of bytes to write
EasyCAT 0:7816b38c99cc 407 TempLong.Byte[3] = ESC_WRITE; // ESC write
EasyCAT 0:7816b38c99cc 408
EasyCAT 0:7816b38c99cc 409 SPIWriteRegisterDirect (ECAT_CSR_CMD, TempLong.Long); // write the command
EasyCAT 0:7816b38c99cc 410
EasyCAT 0:7816b38c99cc 411 do // wait for command execution
EasyCAT 0:7816b38c99cc 412 { //
EasyCAT 0:7816b38c99cc 413 TempLong.Long = SPIReadRegisterDirect (ECAT_CSR_CMD, 4); //
EasyCAT 0:7816b38c99cc 414 } //
EasyCAT 0:7816b38c99cc 415 while (TempLong.Byte[3] & ECAT_CSR_BUSY); //
EasyCAT 0:7816b38c99cc 416 }
EasyCAT 0:7816b38c99cc 417
EasyCAT 0:7816b38c99cc 418
EasyCAT 0:7816b38c99cc 419 //---- read from process ram fifo ----------------------------------------------------------------
EasyCAT 0:7816b38c99cc 420
EasyCAT 0:7816b38c99cc 421
EasyCAT 0:7816b38c99cc 422 void EasyCAT::SPIReadProcRamFifo() // read BYTE_NUM bytes from the output process ram, through the fifo
EasyCAT 0:7816b38c99cc 423 //
EasyCAT 0:7816b38c99cc 424 // these are the bytes received from the EtherCAT master and
EasyCAT 0:7816b38c99cc 425 // that will be use by our application to write the outputs
EasyCAT 0:7816b38c99cc 426 {
EasyCAT 0:7816b38c99cc 427 ULONG TempLong;
EasyCAT 0:7816b38c99cc 428
EasyCAT 0:7816b38c99cc 429 #if TOT_BYTE_NUM_OUT > 0
EasyCAT 0:7816b38c99cc 430
EasyCAT 0:7816b38c99cc 431 SPIWriteRegisterDirect (ECAT_PRAM_RD_CMD, PRAM_ABORT); // abort any possible pending transfer
EasyCAT 0:7816b38c99cc 432
EasyCAT 0:7816b38c99cc 433
EasyCAT 0:7816b38c99cc 434 SPIWriteRegisterDirect (ECAT_PRAM_RD_ADDR_LEN, (0x00001000 | (((uint32_t)TOT_BYTE_NUM_OUT) << 16)));
EasyCAT 0:7816b38c99cc 435 // the high word is the num of bytes
EasyCAT 0:7816b38c99cc 436 // to read 0xTOT_BYTE_NUM_OUT----
EasyCAT 0:7816b38c99cc 437 // the low word is the output process
EasyCAT 0:7816b38c99cc 438 // ram offset 0x----1000
EasyCAT 0:7816b38c99cc 439
EasyCAT 0:7816b38c99cc 440 SPIWriteRegisterDirect (ECAT_PRAM_RD_CMD, 0x80000000); // start command
EasyCAT 0:7816b38c99cc 441
EasyCAT 0:7816b38c99cc 442
EasyCAT 0:7816b38c99cc 443 //------- one round is enough if we have ----
EasyCAT 0:7816b38c99cc 444 //------- to transfer up to 64 bytes --------
EasyCAT 0:7816b38c99cc 445
EasyCAT 0:7816b38c99cc 446 do // wait for the data to be
EasyCAT 0:7816b38c99cc 447 { // transferred from the output
EasyCAT 0:7816b38c99cc 448 TempLong.Long = SPIReadRegisterDirect (ECAT_PRAM_RD_CMD,2); // process ram to the read fifo
EasyCAT 0:7816b38c99cc 449 } //
EasyCAT 0:7816b38c99cc 450 while (TempLong.Byte[1] != FST_LONG_NUM_OUT); //
EasyCAT 0:7816b38c99cc 451
EasyCAT 0:7816b38c99cc 452 SCS_Low_macro // enable SPI chip select
EasyCAT 0:7816b38c99cc 453
daid 2:e0fc1b098ce8 454 char buffer[3] = {COMM_SPI_READ, 0, 0x00};
daid 2:e0fc1b098ce8 455 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 456 SPI_TransferRxBuffer(BufferOut.Byte, FST_BYTE_NUM_ROUND_OUT);
EasyCAT 0:7816b38c99cc 457
EasyCAT 0:7816b38c99cc 458 SCS_High_macro // disable SPI chip select
EasyCAT 0:7816b38c99cc 459 #endif
EasyCAT 0:7816b38c99cc 460
EasyCAT 0:7816b38c99cc 461
EasyCAT 0:7816b38c99cc 462 #if SEC_BYTE_NUM_OUT > 0 //-- if we have to transfer more then 64 bytes --
EasyCAT 0:7816b38c99cc 463 //-- we must do another round -------------------
EasyCAT 0:7816b38c99cc 464 //-- to transfer the remainig bytes -------------
EasyCAT 0:7816b38c99cc 465
EasyCAT 0:7816b38c99cc 466
EasyCAT 0:7816b38c99cc 467 do // wait for the data to be
EasyCAT 0:7816b38c99cc 468 { // transferred from the output
EasyCAT 0:7816b38c99cc 469 TempLong.Long = SPIReadRegisterDirect(ECAT_PRAM_RD_CMD,2);// process ram to the read fifo
EasyCAT 0:7816b38c99cc 470 } //
EasyCAT 0:7816b38c99cc 471 while (TempLong.Byte[1] != SEC_LONG_NUM_OUT); //
EasyCAT 0:7816b38c99cc 472
EasyCAT 0:7816b38c99cc 473 SCS_Low_macro // enable SPI chip select
EasyCAT 0:7816b38c99cc 474
daid 2:e0fc1b098ce8 475 char buffer[3] = {COMM_SPI_READ, 0, 0x00};
daid 2:e0fc1b098ce8 476 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 477 SPI_TransferRxBuffer(&BufferOut.Byte[64], SEC_BYTE_NUM_ROUND_OUT);
EasyCAT 0:7816b38c99cc 478
EasyCAT 0:7816b38c99cc 479 SCS_High_macro // SPI chip select disable
EasyCAT 0:7816b38c99cc 480 #endif
EasyCAT 0:7816b38c99cc 481 }
EasyCAT 0:7816b38c99cc 482
EasyCAT 0:7816b38c99cc 483
EasyCAT 0:7816b38c99cc 484 //---- write to the process ram fifo --------------------------------------------------------------
EasyCAT 0:7816b38c99cc 485
EasyCAT 0:7816b38c99cc 486 void EasyCAT::SPIWriteProcRamFifo() // write BYTE_NUM bytes to the input process ram, through the fifo
EasyCAT 0:7816b38c99cc 487 //
EasyCAT 0:7816b38c99cc 488 // these are the bytes that we have read from the inputs of our
EasyCAT 0:7816b38c99cc 489 // application and that will be sent to the EtherCAT master
EasyCAT 0:7816b38c99cc 490 {
EasyCAT 0:7816b38c99cc 491 ULONG TempLong;
EasyCAT 0:7816b38c99cc 492
EasyCAT 0:7816b38c99cc 493
EasyCAT 0:7816b38c99cc 494
EasyCAT 0:7816b38c99cc 495 #if TOT_BYTE_NUM_IN > 0
EasyCAT 0:7816b38c99cc 496
EasyCAT 0:7816b38c99cc 497 SPIWriteRegisterDirect (ECAT_PRAM_WR_CMD, PRAM_ABORT); // abort any possible pending transfer
EasyCAT 0:7816b38c99cc 498
EasyCAT 0:7816b38c99cc 499
EasyCAT 0:7816b38c99cc 500 SPIWriteRegisterDirect (ECAT_PRAM_WR_ADDR_LEN, (0x00001200 | (((uint32_t)TOT_BYTE_NUM_IN) << 16)));
EasyCAT 0:7816b38c99cc 501 // the high word is the num of bytes
EasyCAT 0:7816b38c99cc 502 // to write 0xTOT_BYTE_NUM_IN----
EasyCAT 0:7816b38c99cc 503 // the low word is the input process
EasyCAT 0:7816b38c99cc 504 // ram offset 0x----1200
EasyCAT 0:7816b38c99cc 505
EasyCAT 0:7816b38c99cc 506 SPIWriteRegisterDirect (ECAT_PRAM_WR_CMD, 0x80000000); // start command
EasyCAT 0:7816b38c99cc 507
EasyCAT 0:7816b38c99cc 508
EasyCAT 0:7816b38c99cc 509 //------- one round is enough if we have ----
EasyCAT 0:7816b38c99cc 510 //------- to transfer up to 64 bytes --------
EasyCAT 0:7816b38c99cc 511
EasyCAT 0:7816b38c99cc 512 do // check that the fifo has
EasyCAT 0:7816b38c99cc 513 { // enough free space
EasyCAT 0:7816b38c99cc 514 TempLong.Long = SPIReadRegisterDirect (ECAT_PRAM_WR_CMD,2); //
EasyCAT 0:7816b38c99cc 515 } //
EasyCAT 0:7816b38c99cc 516 while (TempLong.Byte[1] < FST_LONG_NUM_IN); //
EasyCAT 0:7816b38c99cc 517
EasyCAT 0:7816b38c99cc 518 SCS_Low_macro // enable SPI chip select
EasyCAT 0:7816b38c99cc 519
daid 2:e0fc1b098ce8 520 char buffer[3] = {COMM_SPI_WRITE, 0x00, 0x20};
daid 2:e0fc1b098ce8 521 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 522 SPI_TransferTxBuffer(BufferIn.Byte, FST_BYTE_NUM_ROUND_IN);
EasyCAT 0:7816b38c99cc 523
EasyCAT 0:7816b38c99cc 524 SCS_High_macro // disable SPI chip select
EasyCAT 0:7816b38c99cc 525 #endif
EasyCAT 0:7816b38c99cc 526
EasyCAT 0:7816b38c99cc 527
EasyCAT 0:7816b38c99cc 528 #if SEC_BYTE_NUM_IN > 0 //-- if we have to transfer more then 64 bytes --
EasyCAT 0:7816b38c99cc 529 //-- we must do another round -------------------
EasyCAT 0:7816b38c99cc 530 //-- to transfer the remainig bytes -------------
EasyCAT 0:7816b38c99cc 531
EasyCAT 0:7816b38c99cc 532 do // check that the fifo has
EasyCAT 0:7816b38c99cc 533 { // enough free space
EasyCAT 0:7816b38c99cc 534 TempLong.Long = SPIReadRegisterDirect(ECAT_PRAM_WR_CMD,2);//
EasyCAT 0:7816b38c99cc 535 } //
EasyCAT 0:7816b38c99cc 536 while (TempLong.Byte[1] < (SEC_LONG_NUM_IN)); //
EasyCAT 0:7816b38c99cc 537
EasyCAT 0:7816b38c99cc 538 SCS_Low_macro // enable SPI chip select
EasyCAT 0:7816b38c99cc 539
daid 2:e0fc1b098ce8 540 char buffer[3] = {COMM_SPI_WRITE, 0x00, 0x20};
daid 2:e0fc1b098ce8 541 SPI_TransferTxBuffer(buffer, 3);
daid 2:e0fc1b098ce8 542 SPI_TransferTxBuffer(&BufferIn.Byte[64], SEC_BYTE_NUM_ROUND_IN);
EasyCAT 0:7816b38c99cc 543
EasyCAT 0:7816b38c99cc 544 SCS_High_macro // disable SPI chip select
EasyCAT 0:7816b38c99cc 545 #endif
EasyCAT 0:7816b38c99cc 546 }