Yang Zhang / EasyCAT_lib
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 }