![](/media/cache/profiles/433cd42837eb8bc231c8db5e4267cafc.jpg.50x50_q85.jpg)
EasyCAT LAB - EtherCAT master simple example
Dependencies: SOEM SPI_TFT_ILI9341 TFT_fonts
- This repository contains a simple example for the EasyCAT LAB , a complete educational and experimental EtherCAT® system, composed of one master and two slaves.
- The EasyCAT LAB is provided as a kit by AB&T Tecnologie Informatiche, to allow everybody to have an educational EtherCAT® system up and running in a matter of minutes.
- It uses the SOEM (Simple Open EtherCAT® Master) library by rt-labs, that has been ported in the
ecosystem by AB&T Tecnologie Informatiche.
- The slaves are based on the EasyCAT SHIELD and the Arduino UNO.
Note
- This example uses two LAB 2 slaves.
Note
- In this example only two bytes of data are exchanged between the slaves and are also visualized on the TFT display.
main.cpp@0:13be39911caf, 2019-07-08 (annotated)
- Committer:
- sulymarco
- Date:
- Mon Jul 08 17:44:47 2019 +0000
- Revision:
- 0:13be39911caf
- Child:
- 1:385bdd2b4cd6
first release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sulymarco | 0:13be39911caf | 1 | //******************************************************************************************** |
sulymarco | 0:13be39911caf | 2 | // * |
sulymarco | 0:13be39911caf | 3 | // This software is distributed as an example, "AS IS", in the hope that it could * |
sulymarco | 0:13be39911caf | 4 | // be useful, WITHOUT ANY WARRANTY of any kind, express or implied, included, but * |
sulymarco | 0:13be39911caf | 5 | // not limited, to the warranties of merchantability, fitness for a particular * |
sulymarco | 0:13be39911caf | 6 | // purpose, and non infringiment. In no event shall the authors be liable for any * |
sulymarco | 0:13be39911caf | 7 | // claim, damages or other liability, arising from, or in connection with this software. * |
sulymarco | 0:13be39911caf | 8 | // * |
sulymarco | 0:13be39911caf | 9 | //******************************************************************************************** |
sulymarco | 0:13be39911caf | 10 | |
sulymarco | 0:13be39911caf | 11 | |
sulymarco | 0:13be39911caf | 12 | // The AB&T EasyCAT LAB is a complete experimental EtherCAT® system, composed by |
sulymarco | 0:13be39911caf | 13 | // one master and two slaves. |
sulymarco | 0:13be39911caf | 14 | // The EasyCAT LAB software is provided free of charge and its pourpose is to allow |
sulymarco | 0:13be39911caf | 15 | // makers and educational institutes to experiment with the EtherCAT® protocol. |
sulymarco | 0:13be39911caf | 16 | // |
sulymarco | 0:13be39911caf | 17 | // The EasyCAT LAB is developed by "AB&T Tecnologie Informatiche" Via dell'About 2A Ivrea Italy. |
sulymarco | 0:13be39911caf | 18 | // www.bausano.net |
sulymarco | 0:13be39911caf | 19 | // www.easycatshield.com |
sulymarco | 0:13be39911caf | 20 | // |
sulymarco | 0:13be39911caf | 21 | // The EasyCAT LAB uses the SOEM library by rt:labs |
sulymarco | 0:13be39911caf | 22 | // https://rt-labs.com/products/soem-ethercat-master-stack/ |
sulymarco | 0:13be39911caf | 23 | // |
sulymarco | 0:13be39911caf | 24 | // EtherCAT® is a registered trademark and patented technology, licensed by Beckhoff Automation GmbH. |
sulymarco | 0:13be39911caf | 25 | // www.beckhoff.com |
sulymarco | 0:13be39911caf | 26 | // www.ethercat.org |
sulymarco | 0:13be39911caf | 27 | |
sulymarco | 0:13be39911caf | 28 | |
sulymarco | 0:13be39911caf | 29 | #define ETH_TXBUFNB 16 |
sulymarco | 0:13be39911caf | 30 | #define ETH_RXBUFNB 16 |
sulymarco | 0:13be39911caf | 31 | |
sulymarco | 0:13be39911caf | 32 | #include "mbed.h" |
sulymarco | 0:13be39911caf | 33 | |
sulymarco | 0:13be39911caf | 34 | #ifndef __align |
sulymarco | 0:13be39911caf | 35 | #define __align MBED_ALIGN |
sulymarco | 0:13be39911caf | 36 | #endif |
sulymarco | 0:13be39911caf | 37 | |
sulymarco | 0:13be39911caf | 38 | #include "config.h" |
sulymarco | 0:13be39911caf | 39 | #include "SPI_TFT_ILI9341.h" |
sulymarco | 0:13be39911caf | 40 | #include "Arial12x12.h" |
sulymarco | 0:13be39911caf | 41 | #include "Arial24x23.h" |
sulymarco | 0:13be39911caf | 42 | #include "Arial28x28.h" |
sulymarco | 0:13be39911caf | 43 | #include "font_big.h" |
sulymarco | 0:13be39911caf | 44 | #include "soem_start.h" |
sulymarco | 0:13be39911caf | 45 | |
sulymarco | 0:13be39911caf | 46 | #define CYCLE_TIME 1000 // master cycle time in uS |
sulymarco | 0:13be39911caf | 47 | // 1000 = 1mS |
sulymarco | 0:13be39911caf | 48 | |
sulymarco | 0:13be39911caf | 49 | |
sulymarco | 0:13be39911caf | 50 | #define SysMilliS() (uint32_t)Kernel::get_ms_count() |
sulymarco | 0:13be39911caf | 51 | |
sulymarco | 0:13be39911caf | 52 | Serial pc(USBTX,USBRX,115200); // set the debug serial line speed to 115200 |
sulymarco | 0:13be39911caf | 53 | |
sulymarco | 0:13be39911caf | 54 | |
sulymarco | 0:13be39911caf | 55 | //---- TFT with resistive touchscreen pins ------------------------------------- |
sulymarco | 0:13be39911caf | 56 | |
sulymarco | 0:13be39911caf | 57 | // the display used is the SeeedStudio 2.8 inch TFT v2.0 |
sulymarco | 0:13be39911caf | 58 | // http://wiki.seeedstudio.com/2.8inch_TFT_Touch_Shield_v2.0/ |
sulymarco | 0:13be39911caf | 59 | |
sulymarco | 0:13be39911caf | 60 | #define PIN_YP A3 // resistive touchscreen |
sulymarco | 0:13be39911caf | 61 | #define PIN_YM A1 // |
sulymarco | 0:13be39911caf | 62 | #define PIN_XM A2 // |
sulymarco | 0:13be39911caf | 63 | #define PIN_XP A0 // |
sulymarco | 0:13be39911caf | 64 | |
sulymarco | 0:13be39911caf | 65 | #define PIN_MOSI D11 // TFT display SPI |
sulymarco | 0:13be39911caf | 66 | #define PIN_MISO D12 // |
sulymarco | 0:13be39911caf | 67 | #define PIN_SCLK D13 // |
sulymarco | 0:13be39911caf | 68 | #define PIN_CS_TFT D5 // |
sulymarco | 0:13be39911caf | 69 | #define PIN_DC_TFT D6 // |
sulymarco | 0:13be39911caf | 70 | |
sulymarco | 0:13be39911caf | 71 | |
sulymarco | 0:13be39911caf | 72 | |
sulymarco | 0:13be39911caf | 73 | //---- visualization parameters ------------------------------------------------ |
sulymarco | 0:13be39911caf | 74 | |
sulymarco | 0:13be39911caf | 75 | #define BUTTONS_1_X 80 |
sulymarco | 0:13be39911caf | 76 | #define BUTTONS_1_Y 60 |
sulymarco | 0:13be39911caf | 77 | |
sulymarco | 0:13be39911caf | 78 | #define BUTTONS_2_X 80 |
sulymarco | 0:13be39911caf | 79 | #define BUTTONS_2_Y 180 |
sulymarco | 0:13be39911caf | 80 | |
sulymarco | 0:13be39911caf | 81 | |
sulymarco | 0:13be39911caf | 82 | #define BUTTONS_1_WIDTH 26 |
sulymarco | 0:13be39911caf | 83 | #define BUTTONS_1_R 3 |
sulymarco | 0:13be39911caf | 84 | #define BUTTONS_1_STEP 60 |
sulymarco | 0:13be39911caf | 85 | |
sulymarco | 0:13be39911caf | 86 | #define BUTTONS_2_WIDTH BUTTONS_1_WIDTH |
sulymarco | 0:13be39911caf | 87 | #define BUTTONS_2_R BUTTONS_1_R |
sulymarco | 0:13be39911caf | 88 | #define BUTTONS_2_STEP BUTTONS_1_STEP |
sulymarco | 0:13be39911caf | 89 | |
sulymarco | 0:13be39911caf | 90 | |
sulymarco | 0:13be39911caf | 91 | //---- local functions --------------------------------------------------------- |
sulymarco | 0:13be39911caf | 92 | |
sulymarco | 0:13be39911caf | 93 | void DrawBanner(); |
sulymarco | 0:13be39911caf | 94 | void DrawSlaveFixedParts(); |
sulymarco | 0:13be39911caf | 95 | void DrawButtons_1_Value(uint8_t Value); |
sulymarco | 0:13be39911caf | 96 | void DrawButtons_2_Value(uint8_t Value); |
sulymarco | 0:13be39911caf | 97 | |
sulymarco | 0:13be39911caf | 98 | void Application(); |
sulymarco | 0:13be39911caf | 99 | |
sulymarco | 0:13be39911caf | 100 | |
sulymarco | 0:13be39911caf | 101 | //---- global variables -------------------------------------------------------- |
sulymarco | 0:13be39911caf | 102 | |
sulymarco | 0:13be39911caf | 103 | |
sulymarco | 0:13be39911caf | 104 | bool FirstRound; |
sulymarco | 0:13be39911caf | 105 | |
sulymarco | 0:13be39911caf | 106 | //------------------------------------------------------------------------------ |
sulymarco | 0:13be39911caf | 107 | |
sulymarco | 0:13be39911caf | 108 | SPI_TFT_ILI9341 TFT(PIN_MOSI, PIN_MISO, PIN_SCLK, PIN_CS_TFT, NC, PIN_DC_TFT); |
sulymarco | 0:13be39911caf | 109 | |
sulymarco | 0:13be39911caf | 110 | Ticker SampleTicker; |
sulymarco | 0:13be39911caf | 111 | Thread thread; |
sulymarco | 0:13be39911caf | 112 | |
sulymarco | 0:13be39911caf | 113 | DigitalOut Test_1(D1); // debug test points |
sulymarco | 0:13be39911caf | 114 | DigitalOut Test_2(D2); // |
sulymarco | 0:13be39911caf | 115 | DigitalOut Test_3(D3); // |
sulymarco | 0:13be39911caf | 116 | DigitalOut Test_4(D4); // |
sulymarco | 0:13be39911caf | 117 | |
sulymarco | 0:13be39911caf | 118 | |
sulymarco | 0:13be39911caf | 119 | //------------------------------------------------------------------------------ |
sulymarco | 0:13be39911caf | 120 | |
sulymarco | 0:13be39911caf | 121 | uint8_t Buttons_1; |
sulymarco | 0:13be39911caf | 122 | uint8_t PrevButtons_1; |
sulymarco | 0:13be39911caf | 123 | uint8_t Segments_1; |
sulymarco | 0:13be39911caf | 124 | uint8_t PrevSegments_1; |
sulymarco | 0:13be39911caf | 125 | |
sulymarco | 0:13be39911caf | 126 | uint8_t Buttons_2; |
sulymarco | 0:13be39911caf | 127 | uint8_t PrevButtons_2; |
sulymarco | 0:13be39911caf | 128 | uint8_t Segments_2; |
sulymarco | 0:13be39911caf | 129 | uint8_t PrevSegments_2; |
sulymarco | 0:13be39911caf | 130 | |
sulymarco | 0:13be39911caf | 131 | |
sulymarco | 0:13be39911caf | 132 | //------------------------------------------------------------------------------ |
sulymarco | 0:13be39911caf | 133 | |
sulymarco | 0:13be39911caf | 134 | int ExpectWorkCounter; |
sulymarco | 0:13be39911caf | 135 | int WorkCounter; |
sulymarco | 0:13be39911caf | 136 | int WorkCounterSafe; |
sulymarco | 0:13be39911caf | 137 | bool NetworkError; |
sulymarco | 0:13be39911caf | 138 | bool NetworkErrorSafe; |
sulymarco | 0:13be39911caf | 139 | |
sulymarco | 0:13be39911caf | 140 | #define DATA_EXCHANGE_FLAG (1UL << 0) |
sulymarco | 0:13be39911caf | 141 | #define APPLICATION_FLAG (1UL << 1) |
sulymarco | 0:13be39911caf | 142 | |
sulymarco | 0:13be39911caf | 143 | EventFlags event_flags; |
sulymarco | 0:13be39911caf | 144 | |
sulymarco | 0:13be39911caf | 145 | Mutex IO_data; |
sulymarco | 0:13be39911caf | 146 | |
sulymarco | 0:13be39911caf | 147 | |
sulymarco | 0:13be39911caf | 148 | //---- data exchange thread ---------------------------------------------------- |
sulymarco | 0:13be39911caf | 149 | |
sulymarco | 0:13be39911caf | 150 | void ExchangeMaster() |
sulymarco | 0:13be39911caf | 151 | { |
sulymarco | 0:13be39911caf | 152 | while (true) |
sulymarco | 0:13be39911caf | 153 | { |
sulymarco | 0:13be39911caf | 154 | event_flags.wait_any(DATA_EXCHANGE_FLAG); // the thread waits for the synchronization flag |
sulymarco | 0:13be39911caf | 155 | |
sulymarco | 0:13be39911caf | 156 | //Test_1 = 1; |
sulymarco | 0:13be39911caf | 157 | |
sulymarco | 0:13be39911caf | 158 | IO_data.lock(); // Ethercat data exchange |
sulymarco | 0:13be39911caf | 159 | ec_send_processdata(); // |
sulymarco | 0:13be39911caf | 160 | WorkCounter = ec_receive_processdata(EC_TIMEOUTRET); |
sulymarco | 0:13be39911caf | 161 | |
sulymarco | 0:13be39911caf | 162 | if (WorkCounter != ExpectWorkCounter) |
sulymarco | 0:13be39911caf | 163 | NetworkError = true; |
sulymarco | 0:13be39911caf | 164 | else |
sulymarco | 0:13be39911caf | 165 | NetworkError = false; |
sulymarco | 0:13be39911caf | 166 | |
sulymarco | 0:13be39911caf | 167 | IO_data.unlock(); // |
sulymarco | 0:13be39911caf | 168 | event_flags.set(APPLICATION_FLAG); // synchronize the application |
sulymarco | 0:13be39911caf | 169 | |
sulymarco | 0:13be39911caf | 170 | //Test_1 = 0; |
sulymarco | 0:13be39911caf | 171 | } |
sulymarco | 0:13be39911caf | 172 | } |
sulymarco | 0:13be39911caf | 173 | |
sulymarco | 0:13be39911caf | 174 | |
sulymarco | 0:13be39911caf | 175 | //----- thicker generated sample time ------------------------------------------ |
sulymarco | 0:13be39911caf | 176 | |
sulymarco | 0:13be39911caf | 177 | void SampleIsr() // set the event that starts |
sulymarco | 0:13be39911caf | 178 | { // the data exchange |
sulymarco | 0:13be39911caf | 179 | event_flags.set(DATA_EXCHANGE_FLAG); // |
sulymarco | 0:13be39911caf | 180 | } // |
sulymarco | 0:13be39911caf | 181 | |
sulymarco | 0:13be39911caf | 182 | |
sulymarco | 0:13be39911caf | 183 | //****** initialization ******************************************************** |
sulymarco | 0:13be39911caf | 184 | |
sulymarco | 0:13be39911caf | 185 | int main() |
sulymarco | 0:13be39911caf | 186 | { |
sulymarco | 0:13be39911caf | 187 | int i; |
sulymarco | 0:13be39911caf | 188 | |
sulymarco | 0:13be39911caf | 189 | printf("Start \n"); |
sulymarco | 0:13be39911caf | 190 | |
sulymarco | 0:13be39911caf | 191 | Test_1 = 0; |
sulymarco | 0:13be39911caf | 192 | Test_2 = 0; |
sulymarco | 0:13be39911caf | 193 | Test_3 = 0; |
sulymarco | 0:13be39911caf | 194 | Test_4 = 0; |
sulymarco | 0:13be39911caf | 195 | |
sulymarco | 0:13be39911caf | 196 | TFT.background(Black); // init TFT |
sulymarco | 0:13be39911caf | 197 | TFT.cls(); // |
sulymarco | 0:13be39911caf | 198 | TFT.set_orientation(3); // |
sulymarco | 0:13be39911caf | 199 | |
sulymarco | 0:13be39911caf | 200 | DrawBanner(); |
sulymarco | 0:13be39911caf | 201 | |
sulymarco | 0:13be39911caf | 202 | NetworkError = false; |
sulymarco | 0:13be39911caf | 203 | |
sulymarco | 0:13be39911caf | 204 | if (ec_init(NULL)) // init SOEM |
sulymarco | 0:13be39911caf | 205 | { |
sulymarco | 0:13be39911caf | 206 | printf("ec_init succeeded.\n"); |
sulymarco | 0:13be39911caf | 207 | printf("Scanning the network\n"); |
sulymarco | 0:13be39911caf | 208 | |
sulymarco | 0:13be39911caf | 209 | TFT.cls(); |
sulymarco | 0:13be39911caf | 210 | |
sulymarco | 0:13be39911caf | 211 | TFT.set_font((unsigned char*) Arial12x12); |
sulymarco | 0:13be39911caf | 212 | TFT.foreground(Green); |
sulymarco | 0:13be39911caf | 213 | TFT.locate(0, 0); |
sulymarco | 0:13be39911caf | 214 | |
sulymarco | 0:13be39911caf | 215 | TFT.printf("Scanning the network\n"); |
sulymarco | 0:13be39911caf | 216 | |
sulymarco | 0:13be39911caf | 217 | if (network_scanning()) |
sulymarco | 0:13be39911caf | 218 | { |
sulymarco | 0:13be39911caf | 219 | if (network_configuration()) // check network configuration |
sulymarco | 0:13be39911caf | 220 | { |
sulymarco | 0:13be39911caf | 221 | ec_config_map(&IOmap); // map the I/O |
sulymarco | 0:13be39911caf | 222 | MapLocalStructures(); |
sulymarco | 0:13be39911caf | 223 | |
sulymarco | 0:13be39911caf | 224 | printf("\nSlaves mapped, state to SAFE_OP.\n"); |
sulymarco | 0:13be39911caf | 225 | // wait for all slaves to reach SAFE_OP state |
sulymarco | 0:13be39911caf | 226 | ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); |
sulymarco | 0:13be39911caf | 227 | |
sulymarco | 0:13be39911caf | 228 | printf("Request operational state for all slaves\n"); |
sulymarco | 0:13be39911caf | 229 | ec_slave[0].state = EC_STATE_OPERATIONAL; |
sulymarco | 0:13be39911caf | 230 | |
sulymarco | 0:13be39911caf | 231 | ec_send_processdata(); // send one valid process data to make outputs in slaves happy |
sulymarco | 0:13be39911caf | 232 | ExpectWorkCounter = ec_receive_processdata(EC_TIMEOUTRET); |
sulymarco | 0:13be39911caf | 233 | |
sulymarco | 0:13be39911caf | 234 | ec_writestate(0); // request OP state for all slaves |
sulymarco | 0:13be39911caf | 235 | |
sulymarco | 0:13be39911caf | 236 | // wait for all slaves to reach OP state |
sulymarco | 0:13be39911caf | 237 | ec_statecheck(0, EC_STATE_OPERATIONAL, EC_TIMEOUTSTATE); |
sulymarco | 0:13be39911caf | 238 | if (ec_slave[0].state == EC_STATE_OPERATIONAL ) |
sulymarco | 0:13be39911caf | 239 | { |
sulymarco | 0:13be39911caf | 240 | printf("Operational state reached for all slaves.\n"); |
sulymarco | 0:13be39911caf | 241 | } |
sulymarco | 0:13be39911caf | 242 | else |
sulymarco | 0:13be39911caf | 243 | { |
sulymarco | 0:13be39911caf | 244 | printf("Not all slaves reached operational state.\n"); |
sulymarco | 0:13be39911caf | 245 | ec_readstate(); |
sulymarco | 0:13be39911caf | 246 | for(i = 1; i<=ec_slavecount ; i++) |
sulymarco | 0:13be39911caf | 247 | { |
sulymarco | 0:13be39911caf | 248 | if(ec_slave[i].state != EC_STATE_OPERATIONAL) |
sulymarco | 0:13be39911caf | 249 | { |
sulymarco | 0:13be39911caf | 250 | printf("Slave %d State=0x%04x StatusCode=0x%04x\n", |
sulymarco | 0:13be39911caf | 251 | i, ec_slave[i].state, ec_slave[i].ALstatuscode); |
sulymarco | 0:13be39911caf | 252 | } |
sulymarco | 0:13be39911caf | 253 | } |
sulymarco | 0:13be39911caf | 254 | |
sulymarco | 0:13be39911caf | 255 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 256 | TFT.locate(0, 0); |
sulymarco | 0:13be39911caf | 257 | TFT.printf("Not all slaves reached operational state!"); |
sulymarco | 0:13be39911caf | 258 | while(1){} |
sulymarco | 0:13be39911caf | 259 | } |
sulymarco | 0:13be39911caf | 260 | |
sulymarco | 0:13be39911caf | 261 | DrawSlaveFixedParts(); |
sulymarco | 0:13be39911caf | 262 | |
sulymarco | 0:13be39911caf | 263 | thread.start(ExchangeMaster); |
sulymarco | 0:13be39911caf | 264 | thread.set_priority(osPriorityRealtime); |
sulymarco | 0:13be39911caf | 265 | |
sulymarco | 0:13be39911caf | 266 | SampleTicker.attach_us(&SampleIsr, CYCLE_TIME); |
sulymarco | 0:13be39911caf | 267 | |
sulymarco | 0:13be39911caf | 268 | Application(); |
sulymarco | 0:13be39911caf | 269 | } |
sulymarco | 0:13be39911caf | 270 | |
sulymarco | 0:13be39911caf | 271 | else |
sulymarco | 0:13be39911caf | 272 | { |
sulymarco | 0:13be39911caf | 273 | printf("Mismatch of network units!\n"); |
sulymarco | 0:13be39911caf | 274 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 275 | TFT.locate(0, 0); |
sulymarco | 0:13be39911caf | 276 | TFT.printf("Mismatch of network units!"); |
sulymarco | 0:13be39911caf | 277 | |
sulymarco | 0:13be39911caf | 278 | while(1){} |
sulymarco | 0:13be39911caf | 279 | } |
sulymarco | 0:13be39911caf | 280 | } |
sulymarco | 0:13be39911caf | 281 | |
sulymarco | 0:13be39911caf | 282 | else |
sulymarco | 0:13be39911caf | 283 | { |
sulymarco | 0:13be39911caf | 284 | printf("No slaves found!\n"); |
sulymarco | 0:13be39911caf | 285 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 286 | TFT.printf("No slaves found!"); |
sulymarco | 0:13be39911caf | 287 | |
sulymarco | 0:13be39911caf | 288 | while(1){} |
sulymarco | 0:13be39911caf | 289 | } |
sulymarco | 0:13be39911caf | 290 | } |
sulymarco | 0:13be39911caf | 291 | else |
sulymarco | 0:13be39911caf | 292 | { |
sulymarco | 0:13be39911caf | 293 | printf("Ethernet interface init failed!"); |
sulymarco | 0:13be39911caf | 294 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 295 | TFT.locate(0, 0); |
sulymarco | 0:13be39911caf | 296 | TFT.printf("Ethernet interface init failed!"); |
sulymarco | 0:13be39911caf | 297 | while(1){} |
sulymarco | 0:13be39911caf | 298 | } |
sulymarco | 0:13be39911caf | 299 | } |
sulymarco | 0:13be39911caf | 300 | |
sulymarco | 0:13be39911caf | 301 | |
sulymarco | 0:13be39911caf | 302 | //****** user master application ********************************************** |
sulymarco | 0:13be39911caf | 303 | |
sulymarco | 0:13be39911caf | 304 | void Application() |
sulymarco | 0:13be39911caf | 305 | { |
sulymarco | 0:13be39911caf | 306 | |
sulymarco | 0:13be39911caf | 307 | while(1) |
sulymarco | 0:13be39911caf | 308 | { |
sulymarco | 0:13be39911caf | 309 | event_flags.wait_any(APPLICATION_FLAG); // the application waits for the synchronization flag |
sulymarco | 0:13be39911caf | 310 | |
sulymarco | 0:13be39911caf | 311 | //Test_2 = 1; |
sulymarco | 0:13be39911caf | 312 | |
sulymarco | 0:13be39911caf | 313 | IO_data.lock(); // copy the Ethercat data to a safe buffer |
sulymarco | 0:13be39911caf | 314 | memcpy(&IOmapSafe[0], &IOmap[0], IO_MAP_SIZE); // |
sulymarco | 0:13be39911caf | 315 | // |
sulymarco | 0:13be39911caf | 316 | if (NetworkError) // |
sulymarco | 0:13be39911caf | 317 | { // |
sulymarco | 0:13be39911caf | 318 | NetworkErrorSafe = NetworkError; // |
sulymarco | 0:13be39911caf | 319 | WorkCounterSafe = WorkCounter; // |
sulymarco | 0:13be39911caf | 320 | } // |
sulymarco | 0:13be39911caf | 321 | IO_data.unlock(); // |
sulymarco | 0:13be39911caf | 322 | |
sulymarco | 0:13be39911caf | 323 | if (NetworkErrorSafe) |
sulymarco | 0:13be39911caf | 324 | { |
sulymarco | 0:13be39911caf | 325 | TFT.rect(35,50, 285, 182, Red); |
sulymarco | 0:13be39911caf | 326 | TFT.fillrect(36,51, 284, 181, Black); |
sulymarco | 0:13be39911caf | 327 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 328 | TFT.set_font((unsigned char*) Arial28x28); |
sulymarco | 0:13be39911caf | 329 | TFT.locate(58, 65); |
sulymarco | 0:13be39911caf | 330 | TFT.printf("Network error!"); |
sulymarco | 0:13be39911caf | 331 | printf("Network error!\n"); |
sulymarco | 0:13be39911caf | 332 | TFT.foreground(Magenta); |
sulymarco | 0:13be39911caf | 333 | TFT.set_font((unsigned char*) Arial12x12); |
sulymarco | 0:13be39911caf | 334 | TFT.locate(58, 106); |
sulymarco | 0:13be39911caf | 335 | |
sulymarco | 0:13be39911caf | 336 | if(WorkCounterSafe >= 0) |
sulymarco | 0:13be39911caf | 337 | { |
sulymarco | 0:13be39911caf | 338 | TFT.printf("Expected working counter %d", ExpectWorkCounter); |
sulymarco | 0:13be39911caf | 339 | TFT.locate(58, 118); |
sulymarco | 0:13be39911caf | 340 | TFT.printf("Actual working counter %d", WorkCounterSafe); |
sulymarco | 0:13be39911caf | 341 | printf("Expected working counter %d\n", ExpectWorkCounter); |
sulymarco | 0:13be39911caf | 342 | printf("Actual working counter %d\n", WorkCounterSafe); |
sulymarco | 0:13be39911caf | 343 | } |
sulymarco | 0:13be39911caf | 344 | else |
sulymarco | 0:13be39911caf | 345 | { |
sulymarco | 0:13be39911caf | 346 | TFT.printf("Timeout"); |
sulymarco | 0:13be39911caf | 347 | printf("Timeout\n"); |
sulymarco | 0:13be39911caf | 348 | } |
sulymarco | 0:13be39911caf | 349 | |
sulymarco | 0:13be39911caf | 350 | TFT.foreground(Green); |
sulymarco | 0:13be39911caf | 351 | TFT.locate(58, 142); |
sulymarco | 0:13be39911caf | 352 | TFT.printf("Please fix the error and"); |
sulymarco | 0:13be39911caf | 353 | TFT.locate(58, 154); |
sulymarco | 0:13be39911caf | 354 | TFT.printf("press the reset button"); |
sulymarco | 0:13be39911caf | 355 | printf("Please fix the error and press the reset button \n"); |
sulymarco | 0:13be39911caf | 356 | |
sulymarco | 0:13be39911caf | 357 | SampleTicker.detach(); // stop the sample interrupt |
sulymarco | 0:13be39911caf | 358 | while(1){} // and loop for ever |
sulymarco | 0:13be39911caf | 359 | } |
sulymarco | 0:13be39911caf | 360 | |
sulymarco | 0:13be39911caf | 361 | |
sulymarco | 0:13be39911caf | 362 | //----- slave LAB_2_1 data management ------ |
sulymarco | 0:13be39911caf | 363 | // |
sulymarco | 0:13be39911caf | 364 | Buttons_1 = in_LAB_2_1->Buttons; // read the buttons status from the slave |
sulymarco | 0:13be39911caf | 365 | // |
sulymarco | 0:13be39911caf | 366 | if (Buttons_1 != PrevButtons_1) // check if the buttons value has changed |
sulymarco | 0:13be39911caf | 367 | { // |
sulymarco | 0:13be39911caf | 368 | PrevButtons_1 = Buttons_1; // remember the current buttons value |
sulymarco | 0:13be39911caf | 369 | DrawButtons_1_Value(Buttons_1); // draw the current buttons value on the TFT |
sulymarco | 0:13be39911caf | 370 | } // |
sulymarco | 0:13be39911caf | 371 | // |
sulymarco | 0:13be39911caf | 372 | out_LAB_2_1->Segments = Buttons_2; // send to the slave the buttons status |
sulymarco | 0:13be39911caf | 373 | // from the slave LAB_2_2 |
sulymarco | 0:13be39911caf | 374 | |
sulymarco | 0:13be39911caf | 375 | |
sulymarco | 0:13be39911caf | 376 | |
sulymarco | 0:13be39911caf | 377 | //----- slave 2_2 data management ---------- |
sulymarco | 0:13be39911caf | 378 | // |
sulymarco | 0:13be39911caf | 379 | Buttons_2 = in_LAB_2_2->Buttons; // read the buttons status from the slave |
sulymarco | 0:13be39911caf | 380 | // |
sulymarco | 0:13be39911caf | 381 | if (Buttons_2 != PrevButtons_2) // check if the buttons value has changed |
sulymarco | 0:13be39911caf | 382 | { // |
sulymarco | 0:13be39911caf | 383 | PrevButtons_2 = Buttons_2; // remember the current buttons value |
sulymarco | 0:13be39911caf | 384 | DrawButtons_2_Value(Buttons_2); // draw the current buttons value on the TFT |
sulymarco | 0:13be39911caf | 385 | } // |
sulymarco | 0:13be39911caf | 386 | // |
sulymarco | 0:13be39911caf | 387 | out_LAB_2_2->Segments = Buttons_1; // send to the slave the buttons status |
sulymarco | 0:13be39911caf | 388 | // from the slave LAB_2_1 |
sulymarco | 0:13be39911caf | 389 | |
sulymarco | 0:13be39911caf | 390 | |
sulymarco | 0:13be39911caf | 391 | |
sulymarco | 0:13be39911caf | 392 | IO_data.lock(); // copy the IO data from the safe area |
sulymarco | 0:13be39911caf | 393 | memcpy(&IOmap[0], &IOmapSafe[0], IO_MAP_SIZE); // to the EtherCAT buffer |
sulymarco | 0:13be39911caf | 394 | IO_data.unlock(); // |
sulymarco | 0:13be39911caf | 395 | |
sulymarco | 0:13be39911caf | 396 | //Test_2 = 0; |
sulymarco | 0:13be39911caf | 397 | } |
sulymarco | 0:13be39911caf | 398 | } |
sulymarco | 0:13be39911caf | 399 | |
sulymarco | 0:13be39911caf | 400 | |
sulymarco | 0:13be39911caf | 401 | //****************************************************************************** |
sulymarco | 0:13be39911caf | 402 | |
sulymarco | 0:13be39911caf | 403 | |
sulymarco | 0:13be39911caf | 404 | |
sulymarco | 0:13be39911caf | 405 | //******* general functions **************************************************** |
sulymarco | 0:13be39911caf | 406 | |
sulymarco | 0:13be39911caf | 407 | |
sulymarco | 0:13be39911caf | 408 | |
sulymarco | 0:13be39911caf | 409 | //----- draw the fixed part of the slaves visualization ------------------------ |
sulymarco | 0:13be39911caf | 410 | |
sulymarco | 0:13be39911caf | 411 | void DrawSlaveFixedParts() |
sulymarco | 0:13be39911caf | 412 | { |
sulymarco | 0:13be39911caf | 413 | int i; |
sulymarco | 0:13be39911caf | 414 | |
sulymarco | 0:13be39911caf | 415 | TFT.cls(); // clear screen |
sulymarco | 0:13be39911caf | 416 | TFT.line(0, 120, 340, 120, Green); // draw the separation line |
sulymarco | 0:13be39911caf | 417 | |
sulymarco | 0:13be39911caf | 418 | for (i=0; i<3; i++) // draw the buttons fixed parts |
sulymarco | 0:13be39911caf | 419 | { // for the LAB_2_1 slave |
sulymarco | 0:13be39911caf | 420 | TFT.circle(BUTTONS_1_X+(i*BUTTONS_1_STEP), BUTTONS_1_Y, BUTTONS_1_R, Red); |
sulymarco | 0:13be39911caf | 421 | TFT.circle(BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP), BUTTONS_1_Y, BUTTONS_1_R, Red); |
sulymarco | 0:13be39911caf | 422 | // |
sulymarco | 0:13be39911caf | 423 | TFT.line(BUTTONS_1_X+(i*BUTTONS_1_STEP)-BUTTONS_1_R, BUTTONS_1_Y, BUTTONS_1_X+(i*BUTTONS_1_STEP)-BUTTONS_1_R-4, BUTTONS_1_Y, Red); |
sulymarco | 0:13be39911caf | 424 | TFT.line(BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP)+BUTTONS_1_R, BUTTONS_1_Y, BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP)+BUTTONS_1_R+4 , BUTTONS_1_Y, Red); |
sulymarco | 0:13be39911caf | 425 | } // |
sulymarco | 0:13be39911caf | 426 | // |
sulymarco | 0:13be39911caf | 427 | TFT.set_font((unsigned char*) Arial12x12); // |
sulymarco | 0:13be39911caf | 428 | TFT.locate(BUTTONS_1_X+12, BUTTONS_1_Y+20); // |
sulymarco | 0:13be39911caf | 429 | TFT.printf("LAB_2_1 Buttons"); // |
sulymarco | 0:13be39911caf | 430 | |
sulymarco | 0:13be39911caf | 431 | for (i=0; i<3; i++) // draw the buttons fixed parts |
sulymarco | 0:13be39911caf | 432 | { // for the LAB_2_2 slave |
sulymarco | 0:13be39911caf | 433 | TFT.circle(BUTTONS_2_X+(i*BUTTONS_2_STEP), BUTTONS_2_Y, BUTTONS_2_R, Red); |
sulymarco | 0:13be39911caf | 434 | TFT.circle(BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP), BUTTONS_2_Y, BUTTONS_2_R, Red); |
sulymarco | 0:13be39911caf | 435 | // |
sulymarco | 0:13be39911caf | 436 | TFT.line(BUTTONS_2_X+(i*BUTTONS_2_STEP)-BUTTONS_2_R, BUTTONS_2_Y, BUTTONS_2_X+(i*BUTTONS_2_STEP)-BUTTONS_2_R-4, BUTTONS_2_Y, Red); |
sulymarco | 0:13be39911caf | 437 | TFT.line(BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP)+BUTTONS_2_R, BUTTONS_2_Y, BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP)+BUTTONS_2_R+4 , BUTTONS_2_Y, Red); |
sulymarco | 0:13be39911caf | 438 | } // |
sulymarco | 0:13be39911caf | 439 | // |
sulymarco | 0:13be39911caf | 440 | TFT.set_font((unsigned char*) Arial12x12); // |
sulymarco | 0:13be39911caf | 441 | TFT.locate(BUTTONS_2_X+12, BUTTONS_2_Y+20); // |
sulymarco | 0:13be39911caf | 442 | TFT.printf("LAB_2_2 Buttons"); // |
sulymarco | 0:13be39911caf | 443 | |
sulymarco | 0:13be39911caf | 444 | DrawButtons_1_Value (Buttons_1); // draw the buttons status |
sulymarco | 0:13be39911caf | 445 | DrawButtons_2_Value (Buttons_2); // |
sulymarco | 0:13be39911caf | 446 | |
sulymarco | 0:13be39911caf | 447 | FirstRound = true; |
sulymarco | 0:13be39911caf | 448 | } |
sulymarco | 0:13be39911caf | 449 | |
sulymarco | 0:13be39911caf | 450 | |
sulymarco | 0:13be39911caf | 451 | //---- draw the starting banner ------------------------------------------------ |
sulymarco | 0:13be39911caf | 452 | |
sulymarco | 0:13be39911caf | 453 | void DrawBanner() |
sulymarco | 0:13be39911caf | 454 | { |
sulymarco | 0:13be39911caf | 455 | TFT.set_font((unsigned char*) Arial24x23); |
sulymarco | 0:13be39911caf | 456 | TFT.foreground(Red); |
sulymarco | 0:13be39911caf | 457 | TFT.locate(30, 30); |
sulymarco | 0:13be39911caf | 458 | TFT.printf("EasyCAT"); |
sulymarco | 0:13be39911caf | 459 | TFT.locate(30, 60); |
sulymarco | 0:13be39911caf | 460 | TFT.printf("SOEM MASTER"); |
sulymarco | 0:13be39911caf | 461 | |
sulymarco | 0:13be39911caf | 462 | TFT.foreground(Magenta); |
sulymarco | 0:13be39911caf | 463 | TFT.locate(30, 100); |
sulymarco | 0:13be39911caf | 464 | TFT.printf("simple example"); |
sulymarco | 0:13be39911caf | 465 | |
sulymarco | 0:13be39911caf | 466 | TFT.set_font((unsigned char*) Arial12x12); |
sulymarco | 0:13be39911caf | 467 | TFT.foreground(Green); |
sulymarco | 0:13be39911caf | 468 | TFT.locate(30, 150); |
sulymarco | 0:13be39911caf | 469 | TFT.printf("www.bausano.net"); |
sulymarco | 0:13be39911caf | 470 | |
sulymarco | 0:13be39911caf | 471 | TFT.foreground(Green); |
sulymarco | 0:13be39911caf | 472 | TFT.locate(30, 170); |
sulymarco | 0:13be39911caf | 473 | TFT.printf("www.easycatshield.com"); |
sulymarco | 0:13be39911caf | 474 | |
sulymarco | 0:13be39911caf | 475 | TFT.locate(30, 190); |
sulymarco | 0:13be39911caf | 476 | TFT.printf("https://openethercatsociety.github.io/"); |
sulymarco | 0:13be39911caf | 477 | } |
sulymarco | 0:13be39911caf | 478 | |
sulymarco | 0:13be39911caf | 479 | |
sulymarco | 0:13be39911caf | 480 | //---- slaves data visualization functions ------------------------------------- |
sulymarco | 0:13be39911caf | 481 | |
sulymarco | 0:13be39911caf | 482 | void DrawButtons_1_Value (uint8_t Value) // visualize on the TFT the |
sulymarco | 0:13be39911caf | 483 | { // slave LAB_2_1 buttons status |
sulymarco | 0:13be39911caf | 484 | uint8_t Slope; |
sulymarco | 0:13be39911caf | 485 | int i; |
sulymarco | 0:13be39911caf | 486 | |
sulymarco | 0:13be39911caf | 487 | for (i=0; i<3; i++) |
sulymarco | 0:13be39911caf | 488 | { |
sulymarco | 0:13be39911caf | 489 | if ((Value & 0x04) == 0x04) |
sulymarco | 0:13be39911caf | 490 | Slope = BUTTONS_1_R; |
sulymarco | 0:13be39911caf | 491 | else |
sulymarco | 0:13be39911caf | 492 | Slope = 16; |
sulymarco | 0:13be39911caf | 493 | |
sulymarco | 0:13be39911caf | 494 | TFT.fillrect(BUTTONS_1_X+(i*BUTTONS_1_STEP), BUTTONS_1_Y-16-1, BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP), BUTTONS_1_Y-BUTTONS_1_R-1, Black); |
sulymarco | 0:13be39911caf | 495 | |
sulymarco | 0:13be39911caf | 496 | TFT.line(BUTTONS_1_X+(i*BUTTONS_1_STEP), BUTTONS_1_Y-BUTTONS_1_R-1, BUTTONS_1_X+BUTTONS_1_WIDTH+(i*BUTTONS_1_STEP), BUTTONS_1_Y-Slope-1, Red); |
sulymarco | 0:13be39911caf | 497 | |
sulymarco | 0:13be39911caf | 498 | Value = Value << 1; |
sulymarco | 0:13be39911caf | 499 | } |
sulymarco | 0:13be39911caf | 500 | } |
sulymarco | 0:13be39911caf | 501 | |
sulymarco | 0:13be39911caf | 502 | |
sulymarco | 0:13be39911caf | 503 | void DrawButtons_2_Value (uint8_t Value) // visualize on the TFT the |
sulymarco | 0:13be39911caf | 504 | { // slave LAB_2_2 buttons status |
sulymarco | 0:13be39911caf | 505 | uint8_t Slope; |
sulymarco | 0:13be39911caf | 506 | int i; |
sulymarco | 0:13be39911caf | 507 | |
sulymarco | 0:13be39911caf | 508 | for (i=0; i<3; i++) |
sulymarco | 0:13be39911caf | 509 | { |
sulymarco | 0:13be39911caf | 510 | if ((Value & 0x04) == 0x04) |
sulymarco | 0:13be39911caf | 511 | Slope = BUTTONS_1_R; |
sulymarco | 0:13be39911caf | 512 | else |
sulymarco | 0:13be39911caf | 513 | Slope = 16; |
sulymarco | 0:13be39911caf | 514 | |
sulymarco | 0:13be39911caf | 515 | TFT.fillrect(BUTTONS_2_X+(i*BUTTONS_2_STEP), BUTTONS_2_Y-16-1, BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP), BUTTONS_2_Y-BUTTONS_2_R-1, Black); |
sulymarco | 0:13be39911caf | 516 | |
sulymarco | 0:13be39911caf | 517 | TFT.line(BUTTONS_2_X+(i*BUTTONS_2_STEP), BUTTONS_2_Y-BUTTONS_2_R-1, BUTTONS_2_X+BUTTONS_2_WIDTH+(i*BUTTONS_2_STEP), BUTTONS_2_Y-Slope-1, Red); |
sulymarco | 0:13be39911caf | 518 | |
sulymarco | 0:13be39911caf | 519 | Value = Value << 1; |
sulymarco | 0:13be39911caf | 520 | } |
sulymarco | 0:13be39911caf | 521 | } |
sulymarco | 0:13be39911caf | 522 |