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