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:
Tue Sep 12 17:09:43 2017 +0000
Revision:
0:7816b38c99cc
Child:
2:e0fc1b098ce8
first release

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