EtherCAT slave that reads 3 Xsens IMU's connected to a Xbus Master
Dependencies: MODSERIAL mbed KL25Z_ClockControl
Fork of EtherCAT by
EtherCAT/esc.c@0:a8daa9348a67, 2014-11-17 (annotated)
- Committer:
- vsluiter
- Date:
- Mon Nov 17 13:55:07 2014 +0000
- Revision:
- 0:a8daa9348a67
changed esc_hw
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
vsluiter | 0:a8daa9348a67 | 1 | /* |
vsluiter | 0:a8daa9348a67 | 2 | * SOES Simple Open EtherCAT Slave |
vsluiter | 0:a8daa9348a67 | 3 | * |
vsluiter | 0:a8daa9348a67 | 4 | * File : esc.c |
vsluiter | 0:a8daa9348a67 | 5 | * Version : 1.0.0 |
vsluiter | 0:a8daa9348a67 | 6 | * Date : 11-07-2010 |
vsluiter | 0:a8daa9348a67 | 7 | * Copyright (C) 2007-2010 Arthur Ketels |
vsluiter | 0:a8daa9348a67 | 8 | * |
vsluiter | 0:a8daa9348a67 | 9 | * SOES is free software; you can redistribute it and/or modify it under |
vsluiter | 0:a8daa9348a67 | 10 | * the terms of the GNU General Public License version 2 as published by the Free |
vsluiter | 0:a8daa9348a67 | 11 | * Software Foundation. |
vsluiter | 0:a8daa9348a67 | 12 | * |
vsluiter | 0:a8daa9348a67 | 13 | * SOES is distributed in the hope that it will be useful, but WITHOUT ANY |
vsluiter | 0:a8daa9348a67 | 14 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or |
vsluiter | 0:a8daa9348a67 | 15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
vsluiter | 0:a8daa9348a67 | 16 | * for more details. |
vsluiter | 0:a8daa9348a67 | 17 | * |
vsluiter | 0:a8daa9348a67 | 18 | * As a special exception, if other files instantiate templates or use macros |
vsluiter | 0:a8daa9348a67 | 19 | * or inline functions from this file, or you compile this file and link it |
vsluiter | 0:a8daa9348a67 | 20 | * with other works to produce a work based on this file, this file does not |
vsluiter | 0:a8daa9348a67 | 21 | * by itself cause the resulting work to be covered by the GNU General Public |
vsluiter | 0:a8daa9348a67 | 22 | * License. However the source code for this file must still be made available |
vsluiter | 0:a8daa9348a67 | 23 | * in accordance with section (3) of the GNU General Public License. |
vsluiter | 0:a8daa9348a67 | 24 | * |
vsluiter | 0:a8daa9348a67 | 25 | * This exception does not invalidate any other reasons why a work based on |
vsluiter | 0:a8daa9348a67 | 26 | * this file might be covered by the GNU General Public License. |
vsluiter | 0:a8daa9348a67 | 27 | * |
vsluiter | 0:a8daa9348a67 | 28 | * The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual |
vsluiter | 0:a8daa9348a67 | 29 | * property of, and protected by Beckhoff Automation GmbH. |
vsluiter | 0:a8daa9348a67 | 30 | */ |
vsluiter | 0:a8daa9348a67 | 31 | //#include <stdio.h> |
vsluiter | 0:a8daa9348a67 | 32 | |
vsluiter | 0:a8daa9348a67 | 33 | #ifdef TARGET_ATMEL |
vsluiter | 0:a8daa9348a67 | 34 | #include <avr/io.h> |
vsluiter | 0:a8daa9348a67 | 35 | #include <avr/pgmspace.h> |
vsluiter | 0:a8daa9348a67 | 36 | #else |
vsluiter | 0:a8daa9348a67 | 37 | #define PROGMEM |
vsluiter | 0:a8daa9348a67 | 38 | #define pgm_read_dword(x) *(x) |
vsluiter | 0:a8daa9348a67 | 39 | #define pgm_read_word(x) *(x) |
vsluiter | 0:a8daa9348a67 | 40 | #define pgm_read_byte(x) *(x) |
vsluiter | 0:a8daa9348a67 | 41 | |
vsluiter | 0:a8daa9348a67 | 42 | #endif |
vsluiter | 0:a8daa9348a67 | 43 | |
vsluiter | 0:a8daa9348a67 | 44 | #include <string.h> |
vsluiter | 0:a8daa9348a67 | 45 | #include "utypes.h" |
vsluiter | 0:a8daa9348a67 | 46 | #include "esc.h" |
vsluiter | 0:a8daa9348a67 | 47 | #include "objectlist.h" |
vsluiter | 0:a8daa9348a67 | 48 | |
vsluiter | 0:a8daa9348a67 | 49 | #define BITS2BYTES(b) ((b + 7) >> 3) |
vsluiter | 0:a8daa9348a67 | 50 | |
vsluiter | 0:a8daa9348a67 | 51 | uint16 SDO_findobject(uint16 index) |
vsluiter | 0:a8daa9348a67 | 52 | { |
vsluiter | 0:a8daa9348a67 | 53 | int16 n = 0; |
vsluiter | 0:a8daa9348a67 | 54 | while (pgm_read_word(&SDOobjects[n].index) < index) |
vsluiter | 0:a8daa9348a67 | 55 | { |
vsluiter | 0:a8daa9348a67 | 56 | n++; |
vsluiter | 0:a8daa9348a67 | 57 | } |
vsluiter | 0:a8daa9348a67 | 58 | if (pgm_read_word(&SDOobjects[n].index) != index) |
vsluiter | 0:a8daa9348a67 | 59 | { |
vsluiter | 0:a8daa9348a67 | 60 | return -1; |
vsluiter | 0:a8daa9348a67 | 61 | } |
vsluiter | 0:a8daa9348a67 | 62 | return n; |
vsluiter | 0:a8daa9348a67 | 63 | } |
vsluiter | 0:a8daa9348a67 | 64 | |
vsluiter | 0:a8daa9348a67 | 65 | uint16 sizeTXPDO(void) |
vsluiter | 0:a8daa9348a67 | 66 | { |
vsluiter | 0:a8daa9348a67 | 67 | uint8 c , l, si, sic; |
vsluiter | 0:a8daa9348a67 | 68 | uint16 size = 0; |
vsluiter | 0:a8daa9348a67 | 69 | int16 nidx; |
vsluiter | 0:a8daa9348a67 | 70 | _objd FLASHSTORE *objd; |
vsluiter | 0:a8daa9348a67 | 71 | |
vsluiter | 0:a8daa9348a67 | 72 | if (pgm_read_word(&SDO1C13[0].data)) |
vsluiter | 0:a8daa9348a67 | 73 | si = *((uint8 *)pgm_read_word(&SDO1C13[0].data)); |
vsluiter | 0:a8daa9348a67 | 74 | else |
vsluiter | 0:a8daa9348a67 | 75 | si = pgm_read_byte(&SDO1C13[0].value); |
vsluiter | 0:a8daa9348a67 | 76 | if (si) |
vsluiter | 0:a8daa9348a67 | 77 | { |
vsluiter | 0:a8daa9348a67 | 78 | for (sic = 1 ; sic <= si ; sic++) |
vsluiter | 0:a8daa9348a67 | 79 | { |
vsluiter | 0:a8daa9348a67 | 80 | nidx = SDO_findobject(pgm_read_word(&SDO1C13[sic].value)); |
vsluiter | 0:a8daa9348a67 | 81 | if (nidx > 0) |
vsluiter | 0:a8daa9348a67 | 82 | { |
vsluiter | 0:a8daa9348a67 | 83 | objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); |
vsluiter | 0:a8daa9348a67 | 84 | l = pgm_read_byte(&objd->value); |
vsluiter | 0:a8daa9348a67 | 85 | for (c = 1 ; c <= l ; c++) |
vsluiter | 0:a8daa9348a67 | 86 | size += (pgm_read_dword(&(objd + c)->value) & 0xff); |
vsluiter | 0:a8daa9348a67 | 87 | } |
vsluiter | 0:a8daa9348a67 | 88 | } |
vsluiter | 0:a8daa9348a67 | 89 | } |
vsluiter | 0:a8daa9348a67 | 90 | return BITS2BYTES(size); |
vsluiter | 0:a8daa9348a67 | 91 | } |
vsluiter | 0:a8daa9348a67 | 92 | |
vsluiter | 0:a8daa9348a67 | 93 | uint16 sizeRXPDO(void) |
vsluiter | 0:a8daa9348a67 | 94 | { |
vsluiter | 0:a8daa9348a67 | 95 | uint8 c , l, si, sic; |
vsluiter | 0:a8daa9348a67 | 96 | uint16 size = 0; |
vsluiter | 0:a8daa9348a67 | 97 | int16 nidx; |
vsluiter | 0:a8daa9348a67 | 98 | _objd FLASHSTORE *objd; |
vsluiter | 0:a8daa9348a67 | 99 | |
vsluiter | 0:a8daa9348a67 | 100 | if (pgm_read_word(&SDO1C12[0].data)) |
vsluiter | 0:a8daa9348a67 | 101 | si = *((uint8 *)pgm_read_word(&SDO1C12[0].data)); |
vsluiter | 0:a8daa9348a67 | 102 | else |
vsluiter | 0:a8daa9348a67 | 103 | si = pgm_read_byte(&SDO1C12[0].value); |
vsluiter | 0:a8daa9348a67 | 104 | if (si) |
vsluiter | 0:a8daa9348a67 | 105 | { |
vsluiter | 0:a8daa9348a67 | 106 | for (sic = 1 ; sic <= si ; sic++) |
vsluiter | 0:a8daa9348a67 | 107 | { |
vsluiter | 0:a8daa9348a67 | 108 | nidx = SDO_findobject(pgm_read_word(&SDO1C12[sic].value)); |
vsluiter | 0:a8daa9348a67 | 109 | if (nidx > 0) |
vsluiter | 0:a8daa9348a67 | 110 | { |
vsluiter | 0:a8daa9348a67 | 111 | objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); |
vsluiter | 0:a8daa9348a67 | 112 | l = pgm_read_byte(&objd->value); |
vsluiter | 0:a8daa9348a67 | 113 | for (c = 1 ; c <= l ; c++) |
vsluiter | 0:a8daa9348a67 | 114 | size += (pgm_read_dword(&(objd + c)->value) & 0xff); |
vsluiter | 0:a8daa9348a67 | 115 | } |
vsluiter | 0:a8daa9348a67 | 116 | } |
vsluiter | 0:a8daa9348a67 | 117 | } |
vsluiter | 0:a8daa9348a67 | 118 | return BITS2BYTES(size); |
vsluiter | 0:a8daa9348a67 | 119 | } |
vsluiter | 0:a8daa9348a67 | 120 | |
vsluiter | 0:a8daa9348a67 | 121 | void ESC_ALerror(uint16 errornumber) |
vsluiter | 0:a8daa9348a67 | 122 | { |
vsluiter | 0:a8daa9348a67 | 123 | uint16 dummy; |
vsluiter | 0:a8daa9348a67 | 124 | ESCvar.ALerror = errornumber; |
vsluiter | 0:a8daa9348a67 | 125 | dummy = htoes(errornumber); |
vsluiter | 0:a8daa9348a67 | 126 | ESC_write(ESCREG_ALERROR, &dummy, sizeof(dummy), &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 127 | } |
vsluiter | 0:a8daa9348a67 | 128 | |
vsluiter | 0:a8daa9348a67 | 129 | void ESC_ALstatus(uint8 status) |
vsluiter | 0:a8daa9348a67 | 130 | { |
vsluiter | 0:a8daa9348a67 | 131 | uint16 dummy; |
vsluiter | 0:a8daa9348a67 | 132 | ESCvar.ALstatus = status; |
vsluiter | 0:a8daa9348a67 | 133 | dummy = htoes((uint16)status); |
vsluiter | 0:a8daa9348a67 | 134 | ESC_write(ESCREG_ALSTATUS, &dummy, sizeof(dummy), &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 135 | } |
vsluiter | 0:a8daa9348a67 | 136 | |
vsluiter | 0:a8daa9348a67 | 137 | void ESC_SMack(uint8 n) |
vsluiter | 0:a8daa9348a67 | 138 | { |
vsluiter | 0:a8daa9348a67 | 139 | uint16 dummy; |
vsluiter | 0:a8daa9348a67 | 140 | ESC_read(ESCREG_SM0STATUS + (n << 3), &dummy, 2, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 141 | } |
vsluiter | 0:a8daa9348a67 | 142 | |
vsluiter | 0:a8daa9348a67 | 143 | void ESC_SMstatus(uint8 n) |
vsluiter | 0:a8daa9348a67 | 144 | { |
vsluiter | 0:a8daa9348a67 | 145 | _ESCsm2 *sm; |
vsluiter | 0:a8daa9348a67 | 146 | uint16 temp; |
vsluiter | 0:a8daa9348a67 | 147 | sm = (_ESCsm2 *)&ESCvar.SM[n]; |
vsluiter | 0:a8daa9348a67 | 148 | ESC_read(ESCREG_SM0STATUS + (n << 3), &temp, 2, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 149 | temp = etohs(temp); |
vsluiter | 0:a8daa9348a67 | 150 | sm->ActESC = temp >> 8; |
vsluiter | 0:a8daa9348a67 | 151 | sm->Status = temp; |
vsluiter | 0:a8daa9348a67 | 152 | } |
vsluiter | 0:a8daa9348a67 | 153 | |
vsluiter | 0:a8daa9348a67 | 154 | void ESC_SMwritepdi(uint8 n) |
vsluiter | 0:a8daa9348a67 | 155 | { |
vsluiter | 0:a8daa9348a67 | 156 | _ESCsm2 *sm; |
vsluiter | 0:a8daa9348a67 | 157 | sm = (_ESCsm2 *)&ESCvar.SM[n]; |
vsluiter | 0:a8daa9348a67 | 158 | ESC_write(ESCREG_SM0PDI + (n << 3), &(sm->ActPDI), 1, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 159 | } |
vsluiter | 0:a8daa9348a67 | 160 | |
vsluiter | 0:a8daa9348a67 | 161 | void ESC_SMenable(uint8 n) |
vsluiter | 0:a8daa9348a67 | 162 | { |
vsluiter | 0:a8daa9348a67 | 163 | _ESCsm2 *sm; |
vsluiter | 0:a8daa9348a67 | 164 | sm = (_ESCsm2 *)&ESCvar.SM[n]; |
vsluiter | 0:a8daa9348a67 | 165 | sm->ActPDI &= ~ESCREG_SMENABLE_BIT; |
vsluiter | 0:a8daa9348a67 | 166 | ESC_SMwritepdi(n); |
vsluiter | 0:a8daa9348a67 | 167 | } |
vsluiter | 0:a8daa9348a67 | 168 | |
vsluiter | 0:a8daa9348a67 | 169 | void ESC_SMdisable(uint8 n) |
vsluiter | 0:a8daa9348a67 | 170 | { |
vsluiter | 0:a8daa9348a67 | 171 | _ESCsm2 *sm; |
vsluiter | 0:a8daa9348a67 | 172 | sm = (_ESCsm2 *)&ESCvar.SM[n]; |
vsluiter | 0:a8daa9348a67 | 173 | sm->ActPDI |= ESCREG_SMENABLE_BIT; |
vsluiter | 0:a8daa9348a67 | 174 | ESC_SMwritepdi(n); |
vsluiter | 0:a8daa9348a67 | 175 | } |
vsluiter | 0:a8daa9348a67 | 176 | |
vsluiter | 0:a8daa9348a67 | 177 | void ESC_address(void) |
vsluiter | 0:a8daa9348a67 | 178 | { |
vsluiter | 0:a8daa9348a67 | 179 | ESC_read(ESCREG_ADDRESS, &ESCvar.address, sizeof(ESCvar.address), &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 180 | ESCvar.address = etohs(ESCvar.address); |
vsluiter | 0:a8daa9348a67 | 181 | } |
vsluiter | 0:a8daa9348a67 | 182 | |
vsluiter | 0:a8daa9348a67 | 183 | uint8 ESC_WDstatus(void) |
vsluiter | 0:a8daa9348a67 | 184 | { |
vsluiter | 0:a8daa9348a67 | 185 | uint16 wdstatus; |
vsluiter | 0:a8daa9348a67 | 186 | ESC_read(ESCREG_WDSTATUS, &wdstatus, 2, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 187 | wdstatus = etohs(wdstatus); |
vsluiter | 0:a8daa9348a67 | 188 | return (uint8)wdstatus; |
vsluiter | 0:a8daa9348a67 | 189 | } |
vsluiter | 0:a8daa9348a67 | 190 | |
vsluiter | 0:a8daa9348a67 | 191 | uint8 ESC_checkmbx(uint8 state) |
vsluiter | 0:a8daa9348a67 | 192 | { |
vsluiter | 0:a8daa9348a67 | 193 | _ESCsm2 *SM; |
vsluiter | 0:a8daa9348a67 | 194 | ESC_read(ESCREG_SM0, &ESCvar.SM[0], sizeof(ESCvar.SM[0]), &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 195 | ESC_read(ESCREG_SM1, &ESCvar.SM[1], sizeof(ESCvar.SM[1]), &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 196 | SM = (_ESCsm2 *)&ESCvar.SM[0]; |
vsluiter | 0:a8daa9348a67 | 197 | if ((etohs(SM->PSA) != MBX0_sma) || (etohs(SM->Length) != MBX0_sml) || (SM->Command != MBX0_smc) || (ESCvar.SM[0].ECsm == 0)) |
vsluiter | 0:a8daa9348a67 | 198 | { |
vsluiter | 0:a8daa9348a67 | 199 | ESCvar.SMtestresult = SMRESULT_ERRSM0; |
vsluiter | 0:a8daa9348a67 | 200 | ESC_SMdisable(0); |
vsluiter | 0:a8daa9348a67 | 201 | ESC_SMdisable(1); |
vsluiter | 0:a8daa9348a67 | 202 | return (uint8)(ESCinit | ESCerror); //fail state change |
vsluiter | 0:a8daa9348a67 | 203 | } |
vsluiter | 0:a8daa9348a67 | 204 | SM = (_ESCsm2 *)&ESCvar.SM[1]; |
vsluiter | 0:a8daa9348a67 | 205 | if ((etohs(SM->PSA) != MBX1_sma) || (etohs(SM->Length) != MBX1_sml) || (SM->Command != MBX1_smc) || (ESCvar.SM[1].ECsm == 0)) |
vsluiter | 0:a8daa9348a67 | 206 | { |
vsluiter | 0:a8daa9348a67 | 207 | ESCvar.SMtestresult = SMRESULT_ERRSM1; |
vsluiter | 0:a8daa9348a67 | 208 | ESC_SMdisable(0); |
vsluiter | 0:a8daa9348a67 | 209 | ESC_SMdisable(1); |
vsluiter | 0:a8daa9348a67 | 210 | return ESCinit | ESCerror; //fail state change |
vsluiter | 0:a8daa9348a67 | 211 | } |
vsluiter | 0:a8daa9348a67 | 212 | return state; |
vsluiter | 0:a8daa9348a67 | 213 | } |
vsluiter | 0:a8daa9348a67 | 214 | |
vsluiter | 0:a8daa9348a67 | 215 | uint8 ESC_startmbx(uint8 state) |
vsluiter | 0:a8daa9348a67 | 216 | { |
vsluiter | 0:a8daa9348a67 | 217 | ESC_SMenable(0); |
vsluiter | 0:a8daa9348a67 | 218 | ESC_SMenable(1); |
vsluiter | 0:a8daa9348a67 | 219 | ESC_SMstatus(0); |
vsluiter | 0:a8daa9348a67 | 220 | ESC_SMstatus(1); |
vsluiter | 0:a8daa9348a67 | 221 | if ((state = ESC_checkmbx(state)) & ESCerror) |
vsluiter | 0:a8daa9348a67 | 222 | { |
vsluiter | 0:a8daa9348a67 | 223 | ESC_ALerror(ALERR_INVALIDMBXCONFIG); |
vsluiter | 0:a8daa9348a67 | 224 | MBXrun = 0; |
vsluiter | 0:a8daa9348a67 | 225 | } |
vsluiter | 0:a8daa9348a67 | 226 | else |
vsluiter | 0:a8daa9348a67 | 227 | { |
vsluiter | 0:a8daa9348a67 | 228 | ESCvar.toggle = ESCvar.SM[1].ECrep; //sync repeat request toggle state |
vsluiter | 0:a8daa9348a67 | 229 | MBXrun = 1; |
vsluiter | 0:a8daa9348a67 | 230 | } |
vsluiter | 0:a8daa9348a67 | 231 | return state; |
vsluiter | 0:a8daa9348a67 | 232 | } |
vsluiter | 0:a8daa9348a67 | 233 | |
vsluiter | 0:a8daa9348a67 | 234 | void ESC_stopmbx(void) |
vsluiter | 0:a8daa9348a67 | 235 | { |
vsluiter | 0:a8daa9348a67 | 236 | uint8 n; |
vsluiter | 0:a8daa9348a67 | 237 | MBXrun = 0; |
vsluiter | 0:a8daa9348a67 | 238 | ESC_SMdisable(0); |
vsluiter | 0:a8daa9348a67 | 239 | ESC_SMdisable(1); |
vsluiter | 0:a8daa9348a67 | 240 | for (n = 0 ; n < MBXBUFFERS ; n++) MBXcontrol[n].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 241 | ESCvar.mbxoutpost = 0; |
vsluiter | 0:a8daa9348a67 | 242 | ESCvar.mbxbackup = 0; |
vsluiter | 0:a8daa9348a67 | 243 | ESCvar.xoe = 0; |
vsluiter | 0:a8daa9348a67 | 244 | ESCvar.mbxfree = 1; |
vsluiter | 0:a8daa9348a67 | 245 | ESCvar.toggle = 0; |
vsluiter | 0:a8daa9348a67 | 246 | ESCvar.mbxincnt = 0; |
vsluiter | 0:a8daa9348a67 | 247 | ESCvar.segmented = 0; |
vsluiter | 0:a8daa9348a67 | 248 | ESCvar.frags = 0; |
vsluiter | 0:a8daa9348a67 | 249 | ESCvar.fragsleft = 0; |
vsluiter | 0:a8daa9348a67 | 250 | ESCvar.txcue = 0; |
vsluiter | 0:a8daa9348a67 | 251 | } |
vsluiter | 0:a8daa9348a67 | 252 | |
vsluiter | 0:a8daa9348a67 | 253 | void ESC_readmbx(void) |
vsluiter | 0:a8daa9348a67 | 254 | { |
vsluiter | 0:a8daa9348a67 | 255 | _MBX *MB = &MBX[0]; |
vsluiter | 0:a8daa9348a67 | 256 | uint16 length; |
vsluiter | 0:a8daa9348a67 | 257 | ESC_read(MBX0_sma, MB,MBXHSIZE, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 258 | length = etohs(MB->header.length); |
vsluiter | 0:a8daa9348a67 | 259 | if (length > (MBX0_sml - MBXHSIZE)) length = MBX0_sml - MBXHSIZE; |
vsluiter | 0:a8daa9348a67 | 260 | ESC_read(MBX0_sma + MBXHSIZE, &(MB->b[0]), length, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 261 | if (length + MBXHSIZE < MBX0_sml) |
vsluiter | 0:a8daa9348a67 | 262 | { |
vsluiter | 0:a8daa9348a67 | 263 | ESC_read(MBX0_sme, &length, 1, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 264 | } |
vsluiter | 0:a8daa9348a67 | 265 | MBXcontrol[0].state = MBXstate_inclaim; |
vsluiter | 0:a8daa9348a67 | 266 | } |
vsluiter | 0:a8daa9348a67 | 267 | |
vsluiter | 0:a8daa9348a67 | 268 | void ESC_writembx(uint8 n) |
vsluiter | 0:a8daa9348a67 | 269 | { |
vsluiter | 0:a8daa9348a67 | 270 | _MBX *MB = &MBX[n]; |
vsluiter | 0:a8daa9348a67 | 271 | uint8 dummy = 0; |
vsluiter | 0:a8daa9348a67 | 272 | uint16 length; |
vsluiter | 0:a8daa9348a67 | 273 | length = etohs(MB->header.length); |
vsluiter | 0:a8daa9348a67 | 274 | if (length > (MBX1_sml - MBXHSIZE)) length = MBX1_sml - MBXHSIZE; |
vsluiter | 0:a8daa9348a67 | 275 | ESC_write(MBX1_sma, MB, MBXHSIZE + length, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 276 | if (length + MBXHSIZE < MBX1_sml) |
vsluiter | 0:a8daa9348a67 | 277 | { |
vsluiter | 0:a8daa9348a67 | 278 | ESC_write(MBX1_sme, &dummy, 1, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 279 | } |
vsluiter | 0:a8daa9348a67 | 280 | ESCvar.mbxfree = 0; |
vsluiter | 0:a8daa9348a67 | 281 | } |
vsluiter | 0:a8daa9348a67 | 282 | |
vsluiter | 0:a8daa9348a67 | 283 | void ESC_ackmbxread(void) |
vsluiter | 0:a8daa9348a67 | 284 | { |
vsluiter | 0:a8daa9348a67 | 285 | uint8 dummy = 0; |
vsluiter | 0:a8daa9348a67 | 286 | ESC_write(MBX1_sma, &dummy, 1, &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 287 | ESCvar.mbxfree = 1; |
vsluiter | 0:a8daa9348a67 | 288 | } |
vsluiter | 0:a8daa9348a67 | 289 | |
vsluiter | 0:a8daa9348a67 | 290 | uint8 ESC_claimbuffer(void) |
vsluiter | 0:a8daa9348a67 | 291 | { |
vsluiter | 0:a8daa9348a67 | 292 | _MBX *MB; |
vsluiter | 0:a8daa9348a67 | 293 | uint8 n = MBXBUFFERS - 1; |
vsluiter | 0:a8daa9348a67 | 294 | while ((n > 0) && (MBXcontrol[n].state)) n--; |
vsluiter | 0:a8daa9348a67 | 295 | if (n) |
vsluiter | 0:a8daa9348a67 | 296 | { |
vsluiter | 0:a8daa9348a67 | 297 | MBXcontrol[n].state = MBXstate_outclaim; |
vsluiter | 0:a8daa9348a67 | 298 | MB = &MBX[n]; |
vsluiter | 0:a8daa9348a67 | 299 | ESCvar.mbxcnt = (++ESCvar.mbxcnt) & 0x07; |
vsluiter | 0:a8daa9348a67 | 300 | if (ESCvar.mbxcnt == 0) ESCvar.mbxcnt = 1; |
vsluiter | 0:a8daa9348a67 | 301 | MB->header.address = htoes(0x0000); // destination is master |
vsluiter | 0:a8daa9348a67 | 302 | MB->header.channel = 0; |
vsluiter | 0:a8daa9348a67 | 303 | MB->header.priority = 0; |
vsluiter | 0:a8daa9348a67 | 304 | MB->header.mbxcnt = ESCvar.mbxcnt; |
vsluiter | 0:a8daa9348a67 | 305 | ESCvar.txcue++; |
vsluiter | 0:a8daa9348a67 | 306 | } |
vsluiter | 0:a8daa9348a67 | 307 | return n; |
vsluiter | 0:a8daa9348a67 | 308 | } |
vsluiter | 0:a8daa9348a67 | 309 | |
vsluiter | 0:a8daa9348a67 | 310 | uint8 ESC_outreqbuffer(void) |
vsluiter | 0:a8daa9348a67 | 311 | { |
vsluiter | 0:a8daa9348a67 | 312 | uint8 n = MBXBUFFERS-1; |
vsluiter | 0:a8daa9348a67 | 313 | while ((n > 0) && (MBXcontrol[n].state != MBXstate_outreq)) n--; |
vsluiter | 0:a8daa9348a67 | 314 | return n; |
vsluiter | 0:a8daa9348a67 | 315 | } |
vsluiter | 0:a8daa9348a67 | 316 | |
vsluiter | 0:a8daa9348a67 | 317 | void MBX_error(uint16 error) |
vsluiter | 0:a8daa9348a67 | 318 | { |
vsluiter | 0:a8daa9348a67 | 319 | uint8 MBXout; |
vsluiter | 0:a8daa9348a67 | 320 | _MBXerr *mbxerr; |
vsluiter | 0:a8daa9348a67 | 321 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 322 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 323 | { |
vsluiter | 0:a8daa9348a67 | 324 | mbxerr = (_MBXerr *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 325 | mbxerr->mbxheader.length = htoes((uint16)0x04); |
vsluiter | 0:a8daa9348a67 | 326 | mbxerr->mbxheader.mbxtype = MBXERR; |
vsluiter | 0:a8daa9348a67 | 327 | mbxerr->type = htoes((uint16)0x01); |
vsluiter | 0:a8daa9348a67 | 328 | mbxerr->detail = htoes(error); |
vsluiter | 0:a8daa9348a67 | 329 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 330 | } |
vsluiter | 0:a8daa9348a67 | 331 | } |
vsluiter | 0:a8daa9348a67 | 332 | |
vsluiter | 0:a8daa9348a67 | 333 | uint8 ESC_mbxprocess(void) |
vsluiter | 0:a8daa9348a67 | 334 | { |
vsluiter | 0:a8daa9348a67 | 335 | uint8 mbxhandle = 0; |
vsluiter | 0:a8daa9348a67 | 336 | _MBX *MB = &MBX[0]; |
vsluiter | 0:a8daa9348a67 | 337 | |
vsluiter | 0:a8daa9348a67 | 338 | if (!MBXrun) |
vsluiter | 0:a8daa9348a67 | 339 | { |
vsluiter | 0:a8daa9348a67 | 340 | return 0; //nothing to do |
vsluiter | 0:a8daa9348a67 | 341 | } |
vsluiter | 0:a8daa9348a67 | 342 | |
vsluiter | 0:a8daa9348a67 | 343 | if (ESCvar.ALevent & ESCREG_ALEVENT_SM_MASK) // SM0/1 access or SMn change event |
vsluiter | 0:a8daa9348a67 | 344 | { |
vsluiter | 0:a8daa9348a67 | 345 | ESC_SMstatus(0); |
vsluiter | 0:a8daa9348a67 | 346 | ESC_SMstatus(1); |
vsluiter | 0:a8daa9348a67 | 347 | } |
vsluiter | 0:a8daa9348a67 | 348 | |
vsluiter | 0:a8daa9348a67 | 349 | if (ESCvar.mbxoutpost && ESCvar.SM[1].IntR) //outmbx read by master |
vsluiter | 0:a8daa9348a67 | 350 | { |
vsluiter | 0:a8daa9348a67 | 351 | ESC_ackmbxread(); |
vsluiter | 0:a8daa9348a67 | 352 | if (ESCvar.mbxbackup) // dispose old backup |
vsluiter | 0:a8daa9348a67 | 353 | { |
vsluiter | 0:a8daa9348a67 | 354 | MBXcontrol[ESCvar.mbxbackup].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 355 | } |
vsluiter | 0:a8daa9348a67 | 356 | if (MBXcontrol[ESCvar.mbxoutpost].state == MBXstate_again) // if still to do |
vsluiter | 0:a8daa9348a67 | 357 | { |
vsluiter | 0:a8daa9348a67 | 358 | ESC_writembx(ESCvar.mbxoutpost); |
vsluiter | 0:a8daa9348a67 | 359 | } |
vsluiter | 0:a8daa9348a67 | 360 | MBXcontrol[ESCvar.mbxoutpost].state = MBXstate_backup; //create new backup |
vsluiter | 0:a8daa9348a67 | 361 | ESCvar.mbxbackup = ESCvar.mbxoutpost; |
vsluiter | 0:a8daa9348a67 | 362 | ESCvar.mbxoutpost = 0; |
vsluiter | 0:a8daa9348a67 | 363 | return 0; |
vsluiter | 0:a8daa9348a67 | 364 | } |
vsluiter | 0:a8daa9348a67 | 365 | |
vsluiter | 0:a8daa9348a67 | 366 | if (ESCvar.SM[1].ECrep != ESCvar.toggle) // repeat request |
vsluiter | 0:a8daa9348a67 | 367 | { |
vsluiter | 0:a8daa9348a67 | 368 | if (ESCvar.mbxoutpost || ESCvar.mbxbackup) |
vsluiter | 0:a8daa9348a67 | 369 | { |
vsluiter | 0:a8daa9348a67 | 370 | if (!ESCvar.mbxoutpost) // if outmbx empty |
vsluiter | 0:a8daa9348a67 | 371 | { |
vsluiter | 0:a8daa9348a67 | 372 | ESC_writembx(ESCvar.mbxbackup); // use backup mbx |
vsluiter | 0:a8daa9348a67 | 373 | } |
vsluiter | 0:a8daa9348a67 | 374 | else |
vsluiter | 0:a8daa9348a67 | 375 | { |
vsluiter | 0:a8daa9348a67 | 376 | ESC_SMdisable(1); // reset mailbox |
vsluiter | 0:a8daa9348a67 | 377 | MBXcontrol[ESCvar.mbxoutpost].state = MBXstate_again; // have to resend later |
vsluiter | 0:a8daa9348a67 | 378 | ESC_SMenable(1); // activate mailbox |
vsluiter | 0:a8daa9348a67 | 379 | ESC_writembx(ESCvar.mbxbackup); // use backup mbx |
vsluiter | 0:a8daa9348a67 | 380 | } |
vsluiter | 0:a8daa9348a67 | 381 | ESCvar.toggle = ESCvar.SM[1].ECrep; |
vsluiter | 0:a8daa9348a67 | 382 | ESCvar.SM[1].PDIrep = ESCvar.toggle; |
vsluiter | 0:a8daa9348a67 | 383 | ESC_SMwritepdi(1); |
vsluiter | 0:a8daa9348a67 | 384 | } |
vsluiter | 0:a8daa9348a67 | 385 | return 0; |
vsluiter | 0:a8daa9348a67 | 386 | } |
vsluiter | 0:a8daa9348a67 | 387 | |
vsluiter | 0:a8daa9348a67 | 388 | // if the outmailbox is free check if we have something to send |
vsluiter | 0:a8daa9348a67 | 389 | if (ESCvar.txcue && (ESCvar.mbxfree || !ESCvar.SM[1].MBXstat)) |
vsluiter | 0:a8daa9348a67 | 390 | { |
vsluiter | 0:a8daa9348a67 | 391 | mbxhandle = ESC_outreqbuffer(); // check out request mbx |
vsluiter | 0:a8daa9348a67 | 392 | if (mbxhandle) // outmbx empty and outreq mbx available |
vsluiter | 0:a8daa9348a67 | 393 | { |
vsluiter | 0:a8daa9348a67 | 394 | ESC_writembx(mbxhandle); |
vsluiter | 0:a8daa9348a67 | 395 | MBXcontrol[mbxhandle].state = MBXstate_outpost; // change state |
vsluiter | 0:a8daa9348a67 | 396 | ESCvar.mbxoutpost = mbxhandle; |
vsluiter | 0:a8daa9348a67 | 397 | if (ESCvar.txcue) ESCvar.txcue--; |
vsluiter | 0:a8daa9348a67 | 398 | } |
vsluiter | 0:a8daa9348a67 | 399 | } |
vsluiter | 0:a8daa9348a67 | 400 | |
vsluiter | 0:a8daa9348a67 | 401 | // read mailbox if full and no xoe in progress |
vsluiter | 0:a8daa9348a67 | 402 | if (ESCvar.SM[0].MBXstat && !MBXcontrol[0].state && !ESCvar.mbxoutpost && !ESCvar.xoe) |
vsluiter | 0:a8daa9348a67 | 403 | { |
vsluiter | 0:a8daa9348a67 | 404 | ESC_readmbx(); |
vsluiter | 0:a8daa9348a67 | 405 | ESCvar.SM[0].MBXstat = 0; |
vsluiter | 0:a8daa9348a67 | 406 | if (etohs(MB->header.length) < 8) |
vsluiter | 0:a8daa9348a67 | 407 | { |
vsluiter | 0:a8daa9348a67 | 408 | if (etohs(MB->header.length) == 0) |
vsluiter | 0:a8daa9348a67 | 409 | MBX_error(MBXERR_INVALIDHEADER); |
vsluiter | 0:a8daa9348a67 | 410 | else |
vsluiter | 0:a8daa9348a67 | 411 | MBX_error(MBXERR_SIZETOOSHORT); |
vsluiter | 0:a8daa9348a67 | 412 | MBXcontrol[0].state = MBXstate_idle; // drop mailbox |
vsluiter | 0:a8daa9348a67 | 413 | } |
vsluiter | 0:a8daa9348a67 | 414 | if ((MB->header.mbxcnt !=0) && (MB->header.mbxcnt == ESCvar.mbxincnt)) |
vsluiter | 0:a8daa9348a67 | 415 | { |
vsluiter | 0:a8daa9348a67 | 416 | MBXcontrol[0].state = MBXstate_idle; // drop mailbox |
vsluiter | 0:a8daa9348a67 | 417 | } |
vsluiter | 0:a8daa9348a67 | 418 | ESCvar.mbxincnt = MB->header.mbxcnt; |
vsluiter | 0:a8daa9348a67 | 419 | return 1; |
vsluiter | 0:a8daa9348a67 | 420 | } |
vsluiter | 0:a8daa9348a67 | 421 | |
vsluiter | 0:a8daa9348a67 | 422 | if (ESCvar.ALevent & ESCREG_ALEVENT_SMCHANGE) // ack changes in non used SM |
vsluiter | 0:a8daa9348a67 | 423 | { |
vsluiter | 0:a8daa9348a67 | 424 | ESC_SMack(4); |
vsluiter | 0:a8daa9348a67 | 425 | ESC_SMack(5); |
vsluiter | 0:a8daa9348a67 | 426 | ESC_SMack(6); |
vsluiter | 0:a8daa9348a67 | 427 | ESC_SMack(7); |
vsluiter | 0:a8daa9348a67 | 428 | } |
vsluiter | 0:a8daa9348a67 | 429 | |
vsluiter | 0:a8daa9348a67 | 430 | return 0; |
vsluiter | 0:a8daa9348a67 | 431 | } |
vsluiter | 0:a8daa9348a67 | 432 | |
vsluiter | 0:a8daa9348a67 | 433 | int16 SDO_findsubindex(int16 nidx, uint8 subindex) |
vsluiter | 0:a8daa9348a67 | 434 | { |
vsluiter | 0:a8daa9348a67 | 435 | _objd FLASHSTORE *objd; |
vsluiter | 0:a8daa9348a67 | 436 | int16 n = 0; |
vsluiter | 0:a8daa9348a67 | 437 | uint8 maxsub; |
vsluiter | 0:a8daa9348a67 | 438 | objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); |
vsluiter | 0:a8daa9348a67 | 439 | maxsub = pgm_read_byte(&SDOobjects[nidx].maxsub); |
vsluiter | 0:a8daa9348a67 | 440 | while (( pgm_read_byte(&(objd + n)->subindex) < subindex) && (n < maxsub)) |
vsluiter | 0:a8daa9348a67 | 441 | { |
vsluiter | 0:a8daa9348a67 | 442 | n++; |
vsluiter | 0:a8daa9348a67 | 443 | } |
vsluiter | 0:a8daa9348a67 | 444 | if (pgm_read_byte(&(objd + n)->subindex) != subindex) |
vsluiter | 0:a8daa9348a67 | 445 | { |
vsluiter | 0:a8daa9348a67 | 446 | return -1; |
vsluiter | 0:a8daa9348a67 | 447 | } |
vsluiter | 0:a8daa9348a67 | 448 | return n; |
vsluiter | 0:a8daa9348a67 | 449 | } |
vsluiter | 0:a8daa9348a67 | 450 | |
vsluiter | 0:a8daa9348a67 | 451 | void copy2mbx(void *source, void *dest, uint16 size) |
vsluiter | 0:a8daa9348a67 | 452 | { |
vsluiter | 0:a8daa9348a67 | 453 | memcpy(dest, source, size); |
vsluiter | 0:a8daa9348a67 | 454 | } |
vsluiter | 0:a8daa9348a67 | 455 | |
vsluiter | 0:a8daa9348a67 | 456 | void SDO_abort(uint16 index, uint8 subindex, uint32 abortcode) |
vsluiter | 0:a8daa9348a67 | 457 | { |
vsluiter | 0:a8daa9348a67 | 458 | uint8 MBXout; |
vsluiter | 0:a8daa9348a67 | 459 | _COEsdo *coeres; |
vsluiter | 0:a8daa9348a67 | 460 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 461 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 462 | { |
vsluiter | 0:a8daa9348a67 | 463 | coeres = (_COEsdo *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 464 | coeres->mbxheader.length = htoes(COE_DEFAULTLENGTH); |
vsluiter | 0:a8daa9348a67 | 465 | coeres->mbxheader.mbxtype = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 466 | coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOREQUEST << 12)); |
vsluiter | 0:a8daa9348a67 | 467 | coeres->index = htoes(index); |
vsluiter | 0:a8daa9348a67 | 468 | coeres->subindex = subindex; |
vsluiter | 0:a8daa9348a67 | 469 | coeres->command = COE_COMMAND_SDOABORT; |
vsluiter | 0:a8daa9348a67 | 470 | coeres->size = htoel(abortcode); |
vsluiter | 0:a8daa9348a67 | 471 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 472 | } |
vsluiter | 0:a8daa9348a67 | 473 | } |
vsluiter | 0:a8daa9348a67 | 474 | |
vsluiter | 0:a8daa9348a67 | 475 | void SDO_upload(void) |
vsluiter | 0:a8daa9348a67 | 476 | { |
vsluiter | 0:a8daa9348a67 | 477 | _COEsdo *coesdo,*coeres; |
vsluiter | 0:a8daa9348a67 | 478 | uint16 index; |
vsluiter | 0:a8daa9348a67 | 479 | uint8 subindex; |
vsluiter | 0:a8daa9348a67 | 480 | int16 nidx, nsub; |
vsluiter | 0:a8daa9348a67 | 481 | uint8 MBXout; |
vsluiter | 0:a8daa9348a67 | 482 | uint16 size; |
vsluiter | 0:a8daa9348a67 | 483 | uint8 dss; |
vsluiter | 0:a8daa9348a67 | 484 | _objd FLASHSTORE *objd; |
vsluiter | 0:a8daa9348a67 | 485 | coesdo = (_COEsdo *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 486 | index = etohs(coesdo->index); |
vsluiter | 0:a8daa9348a67 | 487 | subindex = coesdo->subindex; |
vsluiter | 0:a8daa9348a67 | 488 | nidx = SDO_findobject(index); |
vsluiter | 0:a8daa9348a67 | 489 | if (nidx >= 0) |
vsluiter | 0:a8daa9348a67 | 490 | { |
vsluiter | 0:a8daa9348a67 | 491 | nsub = SDO_findsubindex(nidx, subindex); |
vsluiter | 0:a8daa9348a67 | 492 | if (nsub >= 0) |
vsluiter | 0:a8daa9348a67 | 493 | { |
vsluiter | 0:a8daa9348a67 | 494 | objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); |
vsluiter | 0:a8daa9348a67 | 495 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 496 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 497 | { |
vsluiter | 0:a8daa9348a67 | 498 | coeres = (_COEsdo *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 499 | coeres->mbxheader.length = htoes(COE_DEFAULTLENGTH); |
vsluiter | 0:a8daa9348a67 | 500 | coeres->mbxheader.mbxtype = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 501 | coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDORESPONSE << 12)); |
vsluiter | 0:a8daa9348a67 | 502 | size = pgm_read_word(&(objd + nsub)->bitlength); |
vsluiter | 0:a8daa9348a67 | 503 | // expedited bits used calculation |
vsluiter | 0:a8daa9348a67 | 504 | dss = 0x0c; |
vsluiter | 0:a8daa9348a67 | 505 | if (size>8) dss = 0x08; |
vsluiter | 0:a8daa9348a67 | 506 | if (size>16) dss = 0x04; |
vsluiter | 0:a8daa9348a67 | 507 | if (size>24) dss = 0x00; |
vsluiter | 0:a8daa9348a67 | 508 | coeres->index = htoes(index); |
vsluiter | 0:a8daa9348a67 | 509 | coeres->subindex = subindex; |
vsluiter | 0:a8daa9348a67 | 510 | if (size <= 32) |
vsluiter | 0:a8daa9348a67 | 511 | { // expedited response i.e. length<=4 bytes |
vsluiter | 0:a8daa9348a67 | 512 | coeres->command = COE_COMMAND_UPLOADRESPONSE + |
vsluiter | 0:a8daa9348a67 | 513 | COE_SIZE_INDICATOR + |
vsluiter | 0:a8daa9348a67 | 514 | COE_EXPEDITED_INDICATOR + dss; |
vsluiter | 0:a8daa9348a67 | 515 | if (pgm_read_word(&(objd+nsub)->data) == nil) |
vsluiter | 0:a8daa9348a67 | 516 | { |
vsluiter | 0:a8daa9348a67 | 517 | coeres->size = htoel(pgm_read_dword(&(objd + nsub)->value)); //use constant value |
vsluiter | 0:a8daa9348a67 | 518 | } |
vsluiter | 0:a8daa9348a67 | 519 | else |
vsluiter | 0:a8daa9348a67 | 520 | { |
vsluiter | 0:a8daa9348a67 | 521 | size = (size + 7) >> 3; //convert bits to bytes |
vsluiter | 0:a8daa9348a67 | 522 | copy2mbx((void *)pgm_read_word(&(objd + nsub)->data), &(coeres->size), size); //use dynamic data |
vsluiter | 0:a8daa9348a67 | 523 | } |
vsluiter | 0:a8daa9348a67 | 524 | } |
vsluiter | 0:a8daa9348a67 | 525 | else |
vsluiter | 0:a8daa9348a67 | 526 | { // normal response i.e. length>4 bytes |
vsluiter | 0:a8daa9348a67 | 527 | coeres->command = COE_COMMAND_UPLOADRESPONSE + |
vsluiter | 0:a8daa9348a67 | 528 | COE_SIZE_INDICATOR; |
vsluiter | 0:a8daa9348a67 | 529 | size=(size + 7) >> 3; //convert bits to bytes |
vsluiter | 0:a8daa9348a67 | 530 | coeres->size = htoel(size); |
vsluiter | 0:a8daa9348a67 | 531 | if ((size + COE_HEADERSIZE) > MBXDSIZE) |
vsluiter | 0:a8daa9348a67 | 532 | { // segemented transfer needed |
vsluiter | 0:a8daa9348a67 | 533 | ESCvar.frags = size; // set total size in bytes |
vsluiter | 0:a8daa9348a67 | 534 | size = MBXDSIZE - COE_HEADERSIZE; //limit to mailbox size |
vsluiter | 0:a8daa9348a67 | 535 | ESCvar.fragsleft = size; // number of bytes done |
vsluiter | 0:a8daa9348a67 | 536 | ESCvar.segmented = MBXSEU; // signal segmented transfer |
vsluiter | 0:a8daa9348a67 | 537 | ESCvar.data = (void *)pgm_read_word(&(objd + nsub)->data); |
vsluiter | 0:a8daa9348a67 | 538 | } |
vsluiter | 0:a8daa9348a67 | 539 | else |
vsluiter | 0:a8daa9348a67 | 540 | { |
vsluiter | 0:a8daa9348a67 | 541 | ESCvar.segmented = 0; |
vsluiter | 0:a8daa9348a67 | 542 | } |
vsluiter | 0:a8daa9348a67 | 543 | coeres->mbxheader.length = htoes(COE_HEADERSIZE + size); |
vsluiter | 0:a8daa9348a67 | 544 | copy2mbx((void *)pgm_read_word(&(objd + nsub)->data), (&(coeres->size)) + 1, size); //use dynamic data |
vsluiter | 0:a8daa9348a67 | 545 | } |
vsluiter | 0:a8daa9348a67 | 546 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 547 | } |
vsluiter | 0:a8daa9348a67 | 548 | } |
vsluiter | 0:a8daa9348a67 | 549 | else |
vsluiter | 0:a8daa9348a67 | 550 | { |
vsluiter | 0:a8daa9348a67 | 551 | SDO_abort(index, subindex, ABORT_NOSUBINDEX); |
vsluiter | 0:a8daa9348a67 | 552 | } |
vsluiter | 0:a8daa9348a67 | 553 | } |
vsluiter | 0:a8daa9348a67 | 554 | else |
vsluiter | 0:a8daa9348a67 | 555 | { |
vsluiter | 0:a8daa9348a67 | 556 | SDO_abort(index, subindex, ABORT_NOOBJECT); |
vsluiter | 0:a8daa9348a67 | 557 | } |
vsluiter | 0:a8daa9348a67 | 558 | MBXcontrol[0].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 559 | ESCvar.xoe = 0; |
vsluiter | 0:a8daa9348a67 | 560 | } |
vsluiter | 0:a8daa9348a67 | 561 | |
vsluiter | 0:a8daa9348a67 | 562 | |
vsluiter | 0:a8daa9348a67 | 563 | void SDO_uploadsegment(void) |
vsluiter | 0:a8daa9348a67 | 564 | { |
vsluiter | 0:a8daa9348a67 | 565 | _COEsdo *coesdo, *coeres; |
vsluiter | 0:a8daa9348a67 | 566 | uint8 MBXout; |
vsluiter | 0:a8daa9348a67 | 567 | uint16 size, offset; |
vsluiter | 0:a8daa9348a67 | 568 | coesdo = (_COEsdo *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 569 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 570 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 571 | { |
vsluiter | 0:a8daa9348a67 | 572 | coeres = (_COEsdo *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 573 | offset = ESCvar.fragsleft; |
vsluiter | 0:a8daa9348a67 | 574 | size = ESCvar.frags - ESCvar.fragsleft; |
vsluiter | 0:a8daa9348a67 | 575 | coeres->mbxheader.mbxtype = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 576 | coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDORESPONSE << 12)); |
vsluiter | 0:a8daa9348a67 | 577 | coeres->command = COE_COMMAND_UPLOADSEGMENT + |
vsluiter | 0:a8daa9348a67 | 578 | (coesdo->command & COE_TOGGLEBIT); // copy toggle bit |
vsluiter | 0:a8daa9348a67 | 579 | if ((size + COE_SEGMENTHEADERSIZE) > MBXDSIZE) |
vsluiter | 0:a8daa9348a67 | 580 | { // more segemented transfer needed |
vsluiter | 0:a8daa9348a67 | 581 | size = MBXDSIZE - COE_SEGMENTHEADERSIZE; //limit to mailbox size |
vsluiter | 0:a8daa9348a67 | 582 | ESCvar.fragsleft += size; // number of bytes done |
vsluiter | 0:a8daa9348a67 | 583 | coeres->mbxheader.length = htoes(COE_SEGMENTHEADERSIZE + size); |
vsluiter | 0:a8daa9348a67 | 584 | } |
vsluiter | 0:a8daa9348a67 | 585 | else |
vsluiter | 0:a8daa9348a67 | 586 | {// last segment |
vsluiter | 0:a8daa9348a67 | 587 | ESCvar.segmented = 0; |
vsluiter | 0:a8daa9348a67 | 588 | ESCvar.frags = 0; |
vsluiter | 0:a8daa9348a67 | 589 | ESCvar.fragsleft = 0; |
vsluiter | 0:a8daa9348a67 | 590 | coeres->command += COE_COMMAND_LASTSEGMENTBIT; |
vsluiter | 0:a8daa9348a67 | 591 | if (size >= 7) |
vsluiter | 0:a8daa9348a67 | 592 | { |
vsluiter | 0:a8daa9348a67 | 593 | coeres->mbxheader.length = htoes(COE_SEGMENTHEADERSIZE + size); |
vsluiter | 0:a8daa9348a67 | 594 | } |
vsluiter | 0:a8daa9348a67 | 595 | else |
vsluiter | 0:a8daa9348a67 | 596 | { |
vsluiter | 0:a8daa9348a67 | 597 | coeres->command += (7 - size) << 1; |
vsluiter | 0:a8daa9348a67 | 598 | coeres->mbxheader.length = htoes(COE_DEFAULTLENGTH); |
vsluiter | 0:a8daa9348a67 | 599 | } |
vsluiter | 0:a8daa9348a67 | 600 | } |
vsluiter | 0:a8daa9348a67 | 601 | copy2mbx((uint8*)ESCvar.data + offset, (&(coeres->command)) + 1, size); //copy to mailbox |
vsluiter | 0:a8daa9348a67 | 602 | |
vsluiter | 0:a8daa9348a67 | 603 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 604 | } |
vsluiter | 0:a8daa9348a67 | 605 | MBXcontrol[0].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 606 | ESCvar.xoe = 0; |
vsluiter | 0:a8daa9348a67 | 607 | } |
vsluiter | 0:a8daa9348a67 | 608 | |
vsluiter | 0:a8daa9348a67 | 609 | void SDO_download(void) |
vsluiter | 0:a8daa9348a67 | 610 | { |
vsluiter | 0:a8daa9348a67 | 611 | _COEsdo *coesdo, *coeres; |
vsluiter | 0:a8daa9348a67 | 612 | uint16 index; |
vsluiter | 0:a8daa9348a67 | 613 | uint8 subindex; |
vsluiter | 0:a8daa9348a67 | 614 | int16 nidx, nsub; |
vsluiter | 0:a8daa9348a67 | 615 | uint8 MBXout; |
vsluiter | 0:a8daa9348a67 | 616 | uint16 size, actsize; |
vsluiter | 0:a8daa9348a67 | 617 | _objd FLASHSTORE *objd; |
vsluiter | 0:a8daa9348a67 | 618 | uint32 *mbxdata; |
vsluiter | 0:a8daa9348a67 | 619 | coesdo = (_COEsdo *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 620 | index = etohs(coesdo->index); |
vsluiter | 0:a8daa9348a67 | 621 | subindex = coesdo->subindex; |
vsluiter | 0:a8daa9348a67 | 622 | nidx = SDO_findobject(index); |
vsluiter | 0:a8daa9348a67 | 623 | if (nidx >= 0) |
vsluiter | 0:a8daa9348a67 | 624 | { |
vsluiter | 0:a8daa9348a67 | 625 | nsub = SDO_findsubindex(nidx, subindex); |
vsluiter | 0:a8daa9348a67 | 626 | if (nsub >= 0) |
vsluiter | 0:a8daa9348a67 | 627 | { |
vsluiter | 0:a8daa9348a67 | 628 | objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); |
vsluiter | 0:a8daa9348a67 | 629 | if ((pgm_read_word(&(objd + nsub)->access) == ATYPE_RW) || |
vsluiter | 0:a8daa9348a67 | 630 | ((pgm_read_word(&(objd + nsub)->access) == ATYPE_RWpre) && ((ESCvar.ALstatus & 0x0f) == ESCpreop))) |
vsluiter | 0:a8daa9348a67 | 631 | { |
vsluiter | 0:a8daa9348a67 | 632 | if (coesdo->command & COE_EXPEDITED_INDICATOR) //expedited? |
vsluiter | 0:a8daa9348a67 | 633 | { |
vsluiter | 0:a8daa9348a67 | 634 | size = 4 - ((coesdo->command & 0x0c) >> 2); |
vsluiter | 0:a8daa9348a67 | 635 | mbxdata = &(coesdo->size); |
vsluiter | 0:a8daa9348a67 | 636 | } |
vsluiter | 0:a8daa9348a67 | 637 | else // normal upload |
vsluiter | 0:a8daa9348a67 | 638 | { |
vsluiter | 0:a8daa9348a67 | 639 | size = (etohs(coesdo->size) & 0xffff); |
vsluiter | 0:a8daa9348a67 | 640 | mbxdata = (&(coesdo->size)) + 1; |
vsluiter | 0:a8daa9348a67 | 641 | } |
vsluiter | 0:a8daa9348a67 | 642 | actsize = (pgm_read_word(&(objd + nsub)->bitlength) + 7) >> 3; |
vsluiter | 0:a8daa9348a67 | 643 | if ( actsize == size ) |
vsluiter | 0:a8daa9348a67 | 644 | { |
vsluiter | 0:a8daa9348a67 | 645 | copy2mbx(mbxdata, (void *)pgm_read_word(&(objd + nsub)->data), size); |
vsluiter | 0:a8daa9348a67 | 646 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 647 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 648 | { |
vsluiter | 0:a8daa9348a67 | 649 | coeres = (_COEsdo *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 650 | coeres->mbxheader.length = htoes(COE_DEFAULTLENGTH); |
vsluiter | 0:a8daa9348a67 | 651 | coeres->mbxheader.mbxtype = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 652 | coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDORESPONSE << 12)); |
vsluiter | 0:a8daa9348a67 | 653 | coeres->index = htoes(index); |
vsluiter | 0:a8daa9348a67 | 654 | coeres->subindex = subindex; |
vsluiter | 0:a8daa9348a67 | 655 | coeres->command = COE_COMMAND_DOWNLOADRESPONSE; |
vsluiter | 0:a8daa9348a67 | 656 | coeres->size = htoel(0); |
vsluiter | 0:a8daa9348a67 | 657 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 658 | } |
vsluiter | 0:a8daa9348a67 | 659 | // external object write handler |
vsluiter | 0:a8daa9348a67 | 660 | ESC_objecthandler(index, subindex); |
vsluiter | 0:a8daa9348a67 | 661 | } |
vsluiter | 0:a8daa9348a67 | 662 | else |
vsluiter | 0:a8daa9348a67 | 663 | { |
vsluiter | 0:a8daa9348a67 | 664 | SDO_abort(index, subindex, ABORT_TYPEMISMATCH); |
vsluiter | 0:a8daa9348a67 | 665 | } |
vsluiter | 0:a8daa9348a67 | 666 | } |
vsluiter | 0:a8daa9348a67 | 667 | else |
vsluiter | 0:a8daa9348a67 | 668 | { |
vsluiter | 0:a8daa9348a67 | 669 | if(pgm_read_word(&(objd + nsub)->access) == ATYPE_RWpre) |
vsluiter | 0:a8daa9348a67 | 670 | SDO_abort(index, subindex, ABORT_NOTINTHISSTATE); |
vsluiter | 0:a8daa9348a67 | 671 | else |
vsluiter | 0:a8daa9348a67 | 672 | SDO_abort(index, subindex, ABORT_READONLY); |
vsluiter | 0:a8daa9348a67 | 673 | } |
vsluiter | 0:a8daa9348a67 | 674 | } |
vsluiter | 0:a8daa9348a67 | 675 | else |
vsluiter | 0:a8daa9348a67 | 676 | { |
vsluiter | 0:a8daa9348a67 | 677 | SDO_abort(index, subindex, ABORT_NOSUBINDEX); |
vsluiter | 0:a8daa9348a67 | 678 | } |
vsluiter | 0:a8daa9348a67 | 679 | } |
vsluiter | 0:a8daa9348a67 | 680 | else |
vsluiter | 0:a8daa9348a67 | 681 | { |
vsluiter | 0:a8daa9348a67 | 682 | SDO_abort(index, subindex, ABORT_NOOBJECT); |
vsluiter | 0:a8daa9348a67 | 683 | } |
vsluiter | 0:a8daa9348a67 | 684 | MBXcontrol[0].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 685 | ESCvar.xoe = 0; |
vsluiter | 0:a8daa9348a67 | 686 | } |
vsluiter | 0:a8daa9348a67 | 687 | |
vsluiter | 0:a8daa9348a67 | 688 | void SDO_infoerror(uint32 abortcode) |
vsluiter | 0:a8daa9348a67 | 689 | { |
vsluiter | 0:a8daa9348a67 | 690 | uint8 MBXout; |
vsluiter | 0:a8daa9348a67 | 691 | _COEobjdesc *coeres; |
vsluiter | 0:a8daa9348a67 | 692 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 693 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 694 | { |
vsluiter | 0:a8daa9348a67 | 695 | coeres = (_COEobjdesc *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 696 | coeres->mbxheader.length = htoes((uint16)0x0a); |
vsluiter | 0:a8daa9348a67 | 697 | coeres->mbxheader.mbxtype = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 698 | coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); |
vsluiter | 0:a8daa9348a67 | 699 | coeres->infoheader.opcode = COE_INFOERROR; //SDO info error request |
vsluiter | 0:a8daa9348a67 | 700 | coeres->infoheader.incomplete = 0; |
vsluiter | 0:a8daa9348a67 | 701 | coeres->infoheader.reserved = 0x00; |
vsluiter | 0:a8daa9348a67 | 702 | coeres->infoheader.fragmentsleft = 0; |
vsluiter | 0:a8daa9348a67 | 703 | coeres->index = htoel(abortcode); |
vsluiter | 0:a8daa9348a67 | 704 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 705 | } |
vsluiter | 0:a8daa9348a67 | 706 | } |
vsluiter | 0:a8daa9348a67 | 707 | |
vsluiter | 0:a8daa9348a67 | 708 | #define ODLISTSIZE ((MBX1_sml - MBXHSIZE - sizeof(_COEh) - sizeof(_INFOh) - 2) & 0xfffe) |
vsluiter | 0:a8daa9348a67 | 709 | |
vsluiter | 0:a8daa9348a67 | 710 | void SDO_getodlist(void) |
vsluiter | 0:a8daa9348a67 | 711 | { |
vsluiter | 0:a8daa9348a67 | 712 | uint16 frags; |
vsluiter | 0:a8daa9348a67 | 713 | uint8 MBXout = 0; |
vsluiter | 0:a8daa9348a67 | 714 | uint16 entries = 0; |
vsluiter | 0:a8daa9348a67 | 715 | uint16 i, n; |
vsluiter | 0:a8daa9348a67 | 716 | uint16 *p; |
vsluiter | 0:a8daa9348a67 | 717 | _COEobjdesc *coel, *coer; |
vsluiter | 0:a8daa9348a67 | 718 | |
vsluiter | 0:a8daa9348a67 | 719 | while (pgm_read_word(&SDOobjects[entries].index) != 0xffff) entries++; |
vsluiter | 0:a8daa9348a67 | 720 | ESCvar.entries = entries; |
vsluiter | 0:a8daa9348a67 | 721 | frags = ((entries << 1) + ODLISTSIZE - 1); |
vsluiter | 0:a8daa9348a67 | 722 | frags /= ODLISTSIZE; |
vsluiter | 0:a8daa9348a67 | 723 | coer = (_COEobjdesc *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 724 | if (etohs(coer->index) > 0x01) // check for unsupported opcodes |
vsluiter | 0:a8daa9348a67 | 725 | { |
vsluiter | 0:a8daa9348a67 | 726 | SDO_infoerror(ABORT_UNSUPPORTED); |
vsluiter | 0:a8daa9348a67 | 727 | } |
vsluiter | 0:a8daa9348a67 | 728 | else |
vsluiter | 0:a8daa9348a67 | 729 | { |
vsluiter | 0:a8daa9348a67 | 730 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 731 | } |
vsluiter | 0:a8daa9348a67 | 732 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 733 | { |
vsluiter | 0:a8daa9348a67 | 734 | coel = (_COEobjdesc *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 735 | coel->mbxheader.mbxtype = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 736 | coel->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); |
vsluiter | 0:a8daa9348a67 | 737 | coel->infoheader.opcode = COE_GETODLISTRESPONSE; |
vsluiter | 0:a8daa9348a67 | 738 | if (etohs(coer->index) == 0x00) //number of objects request |
vsluiter | 0:a8daa9348a67 | 739 | { |
vsluiter | 0:a8daa9348a67 | 740 | coel->index = htoes((uint16)0x00); |
vsluiter | 0:a8daa9348a67 | 741 | coel->infoheader.incomplete = 0; |
vsluiter | 0:a8daa9348a67 | 742 | coel->infoheader.reserved = 0x00; |
vsluiter | 0:a8daa9348a67 | 743 | coel->infoheader.fragmentsleft = htoes((uint16)0); |
vsluiter | 0:a8daa9348a67 | 744 | MBXcontrol[0].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 745 | ESCvar.xoe = 0; |
vsluiter | 0:a8daa9348a67 | 746 | ESCvar.frags = frags; |
vsluiter | 0:a8daa9348a67 | 747 | ESCvar.fragsleft = frags - 1; |
vsluiter | 0:a8daa9348a67 | 748 | p = &(coel->datatype); |
vsluiter | 0:a8daa9348a67 | 749 | *p = htoes(entries); |
vsluiter | 0:a8daa9348a67 | 750 | p++; |
vsluiter | 0:a8daa9348a67 | 751 | *p = 0; |
vsluiter | 0:a8daa9348a67 | 752 | p++; |
vsluiter | 0:a8daa9348a67 | 753 | *p = 0; |
vsluiter | 0:a8daa9348a67 | 754 | p++; |
vsluiter | 0:a8daa9348a67 | 755 | *p = 0; |
vsluiter | 0:a8daa9348a67 | 756 | p++; |
vsluiter | 0:a8daa9348a67 | 757 | *p = 0; |
vsluiter | 0:a8daa9348a67 | 758 | coel->mbxheader.length = htoes(0x08 + (5 << 1)); |
vsluiter | 0:a8daa9348a67 | 759 | } |
vsluiter | 0:a8daa9348a67 | 760 | if (etohs(coer->index) == 0x01) //only return all objects |
vsluiter | 0:a8daa9348a67 | 761 | { |
vsluiter | 0:a8daa9348a67 | 762 | if (frags > 1) |
vsluiter | 0:a8daa9348a67 | 763 | { |
vsluiter | 0:a8daa9348a67 | 764 | coel->infoheader.incomplete = 1; |
vsluiter | 0:a8daa9348a67 | 765 | ESCvar.xoe = MBXCOE + MBXODL; |
vsluiter | 0:a8daa9348a67 | 766 | n = ODLISTSIZE >> 1; |
vsluiter | 0:a8daa9348a67 | 767 | } |
vsluiter | 0:a8daa9348a67 | 768 | else |
vsluiter | 0:a8daa9348a67 | 769 | { |
vsluiter | 0:a8daa9348a67 | 770 | coel->infoheader.incomplete = 0; |
vsluiter | 0:a8daa9348a67 | 771 | MBXcontrol[0].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 772 | ESCvar.xoe = 0; |
vsluiter | 0:a8daa9348a67 | 773 | n = entries; |
vsluiter | 0:a8daa9348a67 | 774 | } |
vsluiter | 0:a8daa9348a67 | 775 | coel->infoheader.reserved = 0x00; |
vsluiter | 0:a8daa9348a67 | 776 | ESCvar.frags = frags; |
vsluiter | 0:a8daa9348a67 | 777 | ESCvar.fragsleft = frags - 1; |
vsluiter | 0:a8daa9348a67 | 778 | coel->infoheader.fragmentsleft = htoes(ESCvar.fragsleft); |
vsluiter | 0:a8daa9348a67 | 779 | coel->index = htoes((uint16)0x01); |
vsluiter | 0:a8daa9348a67 | 780 | |
vsluiter | 0:a8daa9348a67 | 781 | p = &(coel->datatype); |
vsluiter | 0:a8daa9348a67 | 782 | for (i = 0 ; i < n ; i++) |
vsluiter | 0:a8daa9348a67 | 783 | { |
vsluiter | 0:a8daa9348a67 | 784 | *p = htoes(pgm_read_word(&SDOobjects[i].index)); |
vsluiter | 0:a8daa9348a67 | 785 | p++; |
vsluiter | 0:a8daa9348a67 | 786 | } |
vsluiter | 0:a8daa9348a67 | 787 | |
vsluiter | 0:a8daa9348a67 | 788 | coel->mbxheader.length = htoes(0x08 + ( n << 1)); |
vsluiter | 0:a8daa9348a67 | 789 | } |
vsluiter | 0:a8daa9348a67 | 790 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 791 | } |
vsluiter | 0:a8daa9348a67 | 792 | } |
vsluiter | 0:a8daa9348a67 | 793 | |
vsluiter | 0:a8daa9348a67 | 794 | void SDO_getodlistcont(void) |
vsluiter | 0:a8daa9348a67 | 795 | { |
vsluiter | 0:a8daa9348a67 | 796 | uint8 MBXout; |
vsluiter | 0:a8daa9348a67 | 797 | uint16 i , n, s; |
vsluiter | 0:a8daa9348a67 | 798 | uint16 *p; |
vsluiter | 0:a8daa9348a67 | 799 | _COEobjdesc *coel; |
vsluiter | 0:a8daa9348a67 | 800 | |
vsluiter | 0:a8daa9348a67 | 801 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 802 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 803 | { |
vsluiter | 0:a8daa9348a67 | 804 | coel = (_COEobjdesc *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 805 | coel->mbxheader.mbxtype = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 806 | coel->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); |
vsluiter | 0:a8daa9348a67 | 807 | coel->infoheader.opcode = COE_GETODLISTRESPONSE; |
vsluiter | 0:a8daa9348a67 | 808 | s = (ESCvar.frags - ESCvar.fragsleft) * (ODLISTSIZE >> 1); |
vsluiter | 0:a8daa9348a67 | 809 | if (ESCvar.fragsleft > 1) |
vsluiter | 0:a8daa9348a67 | 810 | { |
vsluiter | 0:a8daa9348a67 | 811 | coel->infoheader.incomplete = 1; |
vsluiter | 0:a8daa9348a67 | 812 | n = s + (ODLISTSIZE >> 1); |
vsluiter | 0:a8daa9348a67 | 813 | } |
vsluiter | 0:a8daa9348a67 | 814 | else |
vsluiter | 0:a8daa9348a67 | 815 | { |
vsluiter | 0:a8daa9348a67 | 816 | coel->infoheader.incomplete = 0; |
vsluiter | 0:a8daa9348a67 | 817 | MBXcontrol[0].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 818 | ESCvar.xoe = 0; |
vsluiter | 0:a8daa9348a67 | 819 | n = ESCvar.entries; |
vsluiter | 0:a8daa9348a67 | 820 | } |
vsluiter | 0:a8daa9348a67 | 821 | coel->infoheader.reserved = 0x00; |
vsluiter | 0:a8daa9348a67 | 822 | ESCvar.fragsleft--; |
vsluiter | 0:a8daa9348a67 | 823 | coel->infoheader.fragmentsleft = htoes(ESCvar.fragsleft); |
vsluiter | 0:a8daa9348a67 | 824 | p = &(coel->index); //pointer 2 bytes back to exclude index |
vsluiter | 0:a8daa9348a67 | 825 | for ( i = s ; i < n ; i++) |
vsluiter | 0:a8daa9348a67 | 826 | { |
vsluiter | 0:a8daa9348a67 | 827 | *p = htoes(pgm_read_word(&SDOobjects[i].index)); |
vsluiter | 0:a8daa9348a67 | 828 | p++; |
vsluiter | 0:a8daa9348a67 | 829 | } |
vsluiter | 0:a8daa9348a67 | 830 | coel->mbxheader.length = htoes(0x06 + ((n - s) << 1)); |
vsluiter | 0:a8daa9348a67 | 831 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 832 | } |
vsluiter | 0:a8daa9348a67 | 833 | } |
vsluiter | 0:a8daa9348a67 | 834 | |
vsluiter | 0:a8daa9348a67 | 835 | void SDO_getod(void) |
vsluiter | 0:a8daa9348a67 | 836 | { |
vsluiter | 0:a8daa9348a67 | 837 | uint8 MBXout; |
vsluiter | 0:a8daa9348a67 | 838 | uint16 index; |
vsluiter | 0:a8daa9348a67 | 839 | int16 nidx; |
vsluiter | 0:a8daa9348a67 | 840 | uint8 *d; |
vsluiter | 0:a8daa9348a67 | 841 | uint8 FLASHSTORE *s; |
vsluiter | 0:a8daa9348a67 | 842 | uint8 n = 0; |
vsluiter | 0:a8daa9348a67 | 843 | _COEobjdesc *coer, *coel; |
vsluiter | 0:a8daa9348a67 | 844 | coer = (_COEobjdesc *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 845 | index = etohs(coer->index); |
vsluiter | 0:a8daa9348a67 | 846 | nidx = SDO_findobject(index); |
vsluiter | 0:a8daa9348a67 | 847 | if (nidx >= 0) |
vsluiter | 0:a8daa9348a67 | 848 | { |
vsluiter | 0:a8daa9348a67 | 849 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 850 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 851 | { |
vsluiter | 0:a8daa9348a67 | 852 | coel = (_COEobjdesc *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 853 | coel->mbxheader.mbxtype = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 854 | coel->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); |
vsluiter | 0:a8daa9348a67 | 855 | coel->infoheader.opcode = COE_GETODRESPONSE; |
vsluiter | 0:a8daa9348a67 | 856 | coel->infoheader.incomplete = 0; |
vsluiter | 0:a8daa9348a67 | 857 | coel->infoheader.reserved = 0x00; |
vsluiter | 0:a8daa9348a67 | 858 | coel->infoheader.fragmentsleft = htoes(0); |
vsluiter | 0:a8daa9348a67 | 859 | coel->index = htoes(index); |
vsluiter | 0:a8daa9348a67 | 860 | coel->datatype = htoes(0); |
vsluiter | 0:a8daa9348a67 | 861 | coel->maxsub = pgm_read_byte(&SDOobjects[nidx].maxsub); |
vsluiter | 0:a8daa9348a67 | 862 | coel->objectcode = pgm_read_word(&SDOobjects[nidx].objtype); |
vsluiter | 0:a8daa9348a67 | 863 | s = (uint8 *)pgm_read_word(&SDOobjects[nidx].name); |
vsluiter | 0:a8daa9348a67 | 864 | d = (uint8 *)&(coel->name); |
vsluiter | 0:a8daa9348a67 | 865 | while (pgm_read_byte(s) && (n < (MBXDSIZE - 0x0c))) |
vsluiter | 0:a8daa9348a67 | 866 | { |
vsluiter | 0:a8daa9348a67 | 867 | *d = pgm_read_byte(s); |
vsluiter | 0:a8daa9348a67 | 868 | n++; |
vsluiter | 0:a8daa9348a67 | 869 | s++; |
vsluiter | 0:a8daa9348a67 | 870 | d++; |
vsluiter | 0:a8daa9348a67 | 871 | } |
vsluiter | 0:a8daa9348a67 | 872 | *d = pgm_read_byte(s); |
vsluiter | 0:a8daa9348a67 | 873 | coel->mbxheader.length = htoes((uint16)0x0c + n); |
vsluiter | 0:a8daa9348a67 | 874 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 875 | MBXcontrol[0].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 876 | ESCvar.xoe=0; |
vsluiter | 0:a8daa9348a67 | 877 | } |
vsluiter | 0:a8daa9348a67 | 878 | } |
vsluiter | 0:a8daa9348a67 | 879 | else |
vsluiter | 0:a8daa9348a67 | 880 | { |
vsluiter | 0:a8daa9348a67 | 881 | SDO_infoerror(ABORT_NOOBJECT); |
vsluiter | 0:a8daa9348a67 | 882 | } |
vsluiter | 0:a8daa9348a67 | 883 | } |
vsluiter | 0:a8daa9348a67 | 884 | |
vsluiter | 0:a8daa9348a67 | 885 | void SDO_geted(void) |
vsluiter | 0:a8daa9348a67 | 886 | { |
vsluiter | 0:a8daa9348a67 | 887 | uint8 MBXout; |
vsluiter | 0:a8daa9348a67 | 888 | uint16 index; |
vsluiter | 0:a8daa9348a67 | 889 | int16 nidx, nsub; |
vsluiter | 0:a8daa9348a67 | 890 | uint8 subindex; |
vsluiter | 0:a8daa9348a67 | 891 | uint8 *d; |
vsluiter | 0:a8daa9348a67 | 892 | uint8 FLASHSTORE *s; |
vsluiter | 0:a8daa9348a67 | 893 | _objd FLASHSTORE *objd; |
vsluiter | 0:a8daa9348a67 | 894 | uint8 n = 0; |
vsluiter | 0:a8daa9348a67 | 895 | _COEentdesc *coer, *coel; |
vsluiter | 0:a8daa9348a67 | 896 | coer = (_COEentdesc *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 897 | index = etohs(coer->index); |
vsluiter | 0:a8daa9348a67 | 898 | subindex = coer->subindex; |
vsluiter | 0:a8daa9348a67 | 899 | nidx = SDO_findobject(index); |
vsluiter | 0:a8daa9348a67 | 900 | if (nidx >= 0) |
vsluiter | 0:a8daa9348a67 | 901 | { |
vsluiter | 0:a8daa9348a67 | 902 | nsub = SDO_findsubindex(nidx, subindex); |
vsluiter | 0:a8daa9348a67 | 903 | if (nsub >= 0) |
vsluiter | 0:a8daa9348a67 | 904 | { |
vsluiter | 0:a8daa9348a67 | 905 | objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); |
vsluiter | 0:a8daa9348a67 | 906 | MBXout = ESC_claimbuffer(); |
vsluiter | 0:a8daa9348a67 | 907 | if (MBXout) |
vsluiter | 0:a8daa9348a67 | 908 | { |
vsluiter | 0:a8daa9348a67 | 909 | coel = (_COEentdesc *)&MBX[MBXout]; |
vsluiter | 0:a8daa9348a67 | 910 | coel->mbxheader.mbxtype = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 911 | coel->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); |
vsluiter | 0:a8daa9348a67 | 912 | coel->infoheader.opcode = COE_ENTRYDESCRIPTIONRESPONSE; |
vsluiter | 0:a8daa9348a67 | 913 | coel->infoheader.incomplete = 0; |
vsluiter | 0:a8daa9348a67 | 914 | coel->infoheader.reserved = 0x00; |
vsluiter | 0:a8daa9348a67 | 915 | coel->infoheader.fragmentsleft = htoes((uint16)0); |
vsluiter | 0:a8daa9348a67 | 916 | coel->index = htoes(index); |
vsluiter | 0:a8daa9348a67 | 917 | coel->subindex = subindex; |
vsluiter | 0:a8daa9348a67 | 918 | coel->valueinfo = COE_VALUEINFO_ACCESS + |
vsluiter | 0:a8daa9348a67 | 919 | COE_VALUEINFO_OBJECT + |
vsluiter | 0:a8daa9348a67 | 920 | COE_VALUEINFO_MAPPABLE; |
vsluiter | 0:a8daa9348a67 | 921 | coel->datatype = htoes(pgm_read_word(&(objd + nsub)->datatype)); |
vsluiter | 0:a8daa9348a67 | 922 | coel->bitlength = htoes(pgm_read_word(&(objd + nsub)->bitlength)); |
vsluiter | 0:a8daa9348a67 | 923 | coel->access = htoes(pgm_read_word(&(objd + nsub)->access)); |
vsluiter | 0:a8daa9348a67 | 924 | s = (uint8 *)pgm_read_word(&(objd+nsub)->name); |
vsluiter | 0:a8daa9348a67 | 925 | d = (uint8 *)&(coel->name); |
vsluiter | 0:a8daa9348a67 | 926 | while (pgm_read_byte(s) && (n < (MBXDSIZE - 0x10))) |
vsluiter | 0:a8daa9348a67 | 927 | { |
vsluiter | 0:a8daa9348a67 | 928 | *d = pgm_read_byte(s); |
vsluiter | 0:a8daa9348a67 | 929 | n++; |
vsluiter | 0:a8daa9348a67 | 930 | s++; |
vsluiter | 0:a8daa9348a67 | 931 | d++; |
vsluiter | 0:a8daa9348a67 | 932 | } |
vsluiter | 0:a8daa9348a67 | 933 | *d = pgm_read_byte(s); |
vsluiter | 0:a8daa9348a67 | 934 | coel->mbxheader.length = htoes((uint16)0x10 + n); |
vsluiter | 0:a8daa9348a67 | 935 | MBXcontrol[MBXout].state = MBXstate_outreq; |
vsluiter | 0:a8daa9348a67 | 936 | MBXcontrol[0].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 937 | ESCvar.xoe = 0; |
vsluiter | 0:a8daa9348a67 | 938 | } |
vsluiter | 0:a8daa9348a67 | 939 | } |
vsluiter | 0:a8daa9348a67 | 940 | else |
vsluiter | 0:a8daa9348a67 | 941 | { |
vsluiter | 0:a8daa9348a67 | 942 | SDO_infoerror(ABORT_NOSUBINDEX); |
vsluiter | 0:a8daa9348a67 | 943 | } |
vsluiter | 0:a8daa9348a67 | 944 | } |
vsluiter | 0:a8daa9348a67 | 945 | else |
vsluiter | 0:a8daa9348a67 | 946 | { |
vsluiter | 0:a8daa9348a67 | 947 | SDO_infoerror(ABORT_NOOBJECT); |
vsluiter | 0:a8daa9348a67 | 948 | } |
vsluiter | 0:a8daa9348a67 | 949 | } |
vsluiter | 0:a8daa9348a67 | 950 | |
vsluiter | 0:a8daa9348a67 | 951 | void ESC_coeprocess(void) |
vsluiter | 0:a8daa9348a67 | 952 | { |
vsluiter | 0:a8daa9348a67 | 953 | _MBXh *mbh; |
vsluiter | 0:a8daa9348a67 | 954 | _COEsdo *coesdo; |
vsluiter | 0:a8daa9348a67 | 955 | _COEobjdesc *coeobjdesc; |
vsluiter | 0:a8daa9348a67 | 956 | uint8 service; |
vsluiter | 0:a8daa9348a67 | 957 | if (!MBXrun) |
vsluiter | 0:a8daa9348a67 | 958 | { |
vsluiter | 0:a8daa9348a67 | 959 | return; |
vsluiter | 0:a8daa9348a67 | 960 | } |
vsluiter | 0:a8daa9348a67 | 961 | if (!ESCvar.xoe && (MBXcontrol[0].state == MBXstate_inclaim)) |
vsluiter | 0:a8daa9348a67 | 962 | { |
vsluiter | 0:a8daa9348a67 | 963 | mbh = (_MBXh *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 964 | if (mbh->mbxtype == MBXCOE) |
vsluiter | 0:a8daa9348a67 | 965 | { |
vsluiter | 0:a8daa9348a67 | 966 | ESCvar.xoe = MBXCOE; |
vsluiter | 0:a8daa9348a67 | 967 | } |
vsluiter | 0:a8daa9348a67 | 968 | } |
vsluiter | 0:a8daa9348a67 | 969 | if ((ESCvar.xoe == (MBXCOE + MBXODL)) && (!ESCvar.mbxoutpost)) |
vsluiter | 0:a8daa9348a67 | 970 | { |
vsluiter | 0:a8daa9348a67 | 971 | SDO_getodlistcont(); // continue get OD list |
vsluiter | 0:a8daa9348a67 | 972 | } |
vsluiter | 0:a8daa9348a67 | 973 | if (ESCvar.xoe == MBXCOE) |
vsluiter | 0:a8daa9348a67 | 974 | { |
vsluiter | 0:a8daa9348a67 | 975 | coesdo = (_COEsdo *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 976 | coeobjdesc = (_COEobjdesc *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 977 | service = etohs(coesdo->coeheader.numberservice) >> 12; |
vsluiter | 0:a8daa9348a67 | 978 | //initiate SDO upload request |
vsluiter | 0:a8daa9348a67 | 979 | if ((service == COE_SDOREQUEST) |
vsluiter | 0:a8daa9348a67 | 980 | && (coesdo->command == COE_COMMAND_UPLOADREQUEST) |
vsluiter | 0:a8daa9348a67 | 981 | && (etohs(coesdo->mbxheader.length) == 0x0a)) |
vsluiter | 0:a8daa9348a67 | 982 | { |
vsluiter | 0:a8daa9348a67 | 983 | SDO_upload(); |
vsluiter | 0:a8daa9348a67 | 984 | } |
vsluiter | 0:a8daa9348a67 | 985 | //SDO upload segment request |
vsluiter | 0:a8daa9348a67 | 986 | if ((service == COE_SDOREQUEST) |
vsluiter | 0:a8daa9348a67 | 987 | && ((coesdo->command & 0xef) == COE_COMMAND_UPLOADSEGREQ) |
vsluiter | 0:a8daa9348a67 | 988 | && (etohs(coesdo->mbxheader.length) == 0x0a) |
vsluiter | 0:a8daa9348a67 | 989 | && (ESCvar.segmented == MBXSEU)) |
vsluiter | 0:a8daa9348a67 | 990 | { |
vsluiter | 0:a8daa9348a67 | 991 | SDO_uploadsegment(); |
vsluiter | 0:a8daa9348a67 | 992 | } |
vsluiter | 0:a8daa9348a67 | 993 | //initiate SDO download request |
vsluiter | 0:a8daa9348a67 | 994 | else |
vsluiter | 0:a8daa9348a67 | 995 | if ((service == COE_SDOREQUEST) |
vsluiter | 0:a8daa9348a67 | 996 | && ((coesdo->command & 0xf1) == 0x21)) |
vsluiter | 0:a8daa9348a67 | 997 | { |
vsluiter | 0:a8daa9348a67 | 998 | SDO_download(); |
vsluiter | 0:a8daa9348a67 | 999 | } |
vsluiter | 0:a8daa9348a67 | 1000 | //initiate SDO get OD list |
vsluiter | 0:a8daa9348a67 | 1001 | else |
vsluiter | 0:a8daa9348a67 | 1002 | if ((service == COE_SDOINFORMATION) |
vsluiter | 0:a8daa9348a67 | 1003 | &&(coeobjdesc->infoheader.opcode == 0x01)) |
vsluiter | 0:a8daa9348a67 | 1004 | { |
vsluiter | 0:a8daa9348a67 | 1005 | SDO_getodlist(); |
vsluiter | 0:a8daa9348a67 | 1006 | } |
vsluiter | 0:a8daa9348a67 | 1007 | //initiate SDO get OD |
vsluiter | 0:a8daa9348a67 | 1008 | else |
vsluiter | 0:a8daa9348a67 | 1009 | if ((service == COE_SDOINFORMATION) |
vsluiter | 0:a8daa9348a67 | 1010 | && (coeobjdesc->infoheader.opcode == 0x03)) |
vsluiter | 0:a8daa9348a67 | 1011 | { |
vsluiter | 0:a8daa9348a67 | 1012 | SDO_getod(); |
vsluiter | 0:a8daa9348a67 | 1013 | } |
vsluiter | 0:a8daa9348a67 | 1014 | //initiate SDO get ED |
vsluiter | 0:a8daa9348a67 | 1015 | else |
vsluiter | 0:a8daa9348a67 | 1016 | if ((service == COE_SDOINFORMATION) |
vsluiter | 0:a8daa9348a67 | 1017 | && (coeobjdesc->infoheader.opcode == 0x05)) |
vsluiter | 0:a8daa9348a67 | 1018 | { |
vsluiter | 0:a8daa9348a67 | 1019 | SDO_geted(); |
vsluiter | 0:a8daa9348a67 | 1020 | } |
vsluiter | 0:a8daa9348a67 | 1021 | else |
vsluiter | 0:a8daa9348a67 | 1022 | if (ESCvar.xoe == MBXCOE) //COE not recognised above |
vsluiter | 0:a8daa9348a67 | 1023 | { |
vsluiter | 0:a8daa9348a67 | 1024 | if (service == 0) |
vsluiter | 0:a8daa9348a67 | 1025 | { |
vsluiter | 0:a8daa9348a67 | 1026 | MBX_error(MBXERR_INVALIDHEADER); |
vsluiter | 0:a8daa9348a67 | 1027 | } |
vsluiter | 0:a8daa9348a67 | 1028 | else |
vsluiter | 0:a8daa9348a67 | 1029 | { |
vsluiter | 0:a8daa9348a67 | 1030 | SDO_abort(etohs(coesdo->index), coesdo->subindex, ABORT_UNKNOWN); |
vsluiter | 0:a8daa9348a67 | 1031 | } |
vsluiter | 0:a8daa9348a67 | 1032 | MBXcontrol[0].state = MBXstate_idle; |
vsluiter | 0:a8daa9348a67 | 1033 | ESCvar.xoe = 0; |
vsluiter | 0:a8daa9348a67 | 1034 | } |
vsluiter | 0:a8daa9348a67 | 1035 | } |
vsluiter | 0:a8daa9348a67 | 1036 | } |
vsluiter | 0:a8daa9348a67 | 1037 | |
vsluiter | 0:a8daa9348a67 | 1038 | void ESC_xoeprocess(void) |
vsluiter | 0:a8daa9348a67 | 1039 | { |
vsluiter | 0:a8daa9348a67 | 1040 | _MBXh *mbh; |
vsluiter | 0:a8daa9348a67 | 1041 | if (!MBXrun) |
vsluiter | 0:a8daa9348a67 | 1042 | { |
vsluiter | 0:a8daa9348a67 | 1043 | return; |
vsluiter | 0:a8daa9348a67 | 1044 | } |
vsluiter | 0:a8daa9348a67 | 1045 | if (!ESCvar.xoe && (MBXcontrol[0].state == MBXstate_inclaim)) |
vsluiter | 0:a8daa9348a67 | 1046 | { |
vsluiter | 0:a8daa9348a67 | 1047 | mbh = (_MBXh *)&MBX[0]; |
vsluiter | 0:a8daa9348a67 | 1048 | if ((mbh->mbxtype == 0) || (etohs(mbh->length) == 0)) |
vsluiter | 0:a8daa9348a67 | 1049 | { |
vsluiter | 0:a8daa9348a67 | 1050 | MBX_error(MBXERR_INVALIDHEADER); |
vsluiter | 0:a8daa9348a67 | 1051 | } |
vsluiter | 0:a8daa9348a67 | 1052 | else |
vsluiter | 0:a8daa9348a67 | 1053 | { |
vsluiter | 0:a8daa9348a67 | 1054 | MBX_error(MBXERR_UNSUPPORTEDPROTOCOL); |
vsluiter | 0:a8daa9348a67 | 1055 | } |
vsluiter | 0:a8daa9348a67 | 1056 | MBXcontrol[0].state = MBXstate_idle; // mailbox type not supported, drop mailbox |
vsluiter | 0:a8daa9348a67 | 1057 | } |
vsluiter | 0:a8daa9348a67 | 1058 | } |
vsluiter | 0:a8daa9348a67 | 1059 | |
vsluiter | 0:a8daa9348a67 | 1060 | uint8 ESC_checkSM23(uint8 state) |
vsluiter | 0:a8daa9348a67 | 1061 | { |
vsluiter | 0:a8daa9348a67 | 1062 | _ESCsm2 *SM; |
vsluiter | 0:a8daa9348a67 | 1063 | ESC_read(ESCREG_SM2, &ESCvar.SM[2], sizeof(ESCvar.SM[2]), &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 1064 | ESC_read(ESCREG_SM3, &ESCvar.SM[3], sizeof(ESCvar.SM[3]), &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 1065 | SM = (_ESCsm2 *)&ESCvar.SM[2]; |
vsluiter | 0:a8daa9348a67 | 1066 | if ((etohs(SM->PSA) != SM2_sma) || (etohs(SM->Length) != SM2_sml) || (SM->Command != SM2_smc) || !(SM->ActESC & SM2_act)) |
vsluiter | 0:a8daa9348a67 | 1067 | { |
vsluiter | 0:a8daa9348a67 | 1068 | ESCvar.SMtestresult = SMRESULT_ERRSM2; |
vsluiter | 0:a8daa9348a67 | 1069 | return ESCpreop | ESCerror; //fail state change |
vsluiter | 0:a8daa9348a67 | 1070 | } |
vsluiter | 0:a8daa9348a67 | 1071 | SM = (_ESCsm2 *)&ESCvar.SM[3]; |
vsluiter | 0:a8daa9348a67 | 1072 | if ((etohs(SM->PSA) != SM3_sma) || (etohs(SM->Length) != SM3_sml) || (SM->Command != SM3_smc) || !(SM->ActESC & SM3_act)) |
vsluiter | 0:a8daa9348a67 | 1073 | { |
vsluiter | 0:a8daa9348a67 | 1074 | ESCvar.SMtestresult = SMRESULT_ERRSM3; |
vsluiter | 0:a8daa9348a67 | 1075 | return ESCpreop | ESCerror; //fail state change |
vsluiter | 0:a8daa9348a67 | 1076 | } |
vsluiter | 0:a8daa9348a67 | 1077 | return state; |
vsluiter | 0:a8daa9348a67 | 1078 | } |
vsluiter | 0:a8daa9348a67 | 1079 | |
vsluiter | 0:a8daa9348a67 | 1080 | uint8 ESC_startinput(uint8 state) |
vsluiter | 0:a8daa9348a67 | 1081 | { |
vsluiter | 0:a8daa9348a67 | 1082 | state = ESC_checkSM23(state); |
vsluiter | 0:a8daa9348a67 | 1083 | if (state != (ESCpreop | ESCerror)) |
vsluiter | 0:a8daa9348a67 | 1084 | { |
vsluiter | 0:a8daa9348a67 | 1085 | ESC_SMenable(3); |
vsluiter | 0:a8daa9348a67 | 1086 | APPstate = APPSTATE_INPUT; |
vsluiter | 0:a8daa9348a67 | 1087 | } |
vsluiter | 0:a8daa9348a67 | 1088 | else |
vsluiter | 0:a8daa9348a67 | 1089 | { |
vsluiter | 0:a8daa9348a67 | 1090 | ESC_SMdisable(2); |
vsluiter | 0:a8daa9348a67 | 1091 | ESC_SMdisable(3); |
vsluiter | 0:a8daa9348a67 | 1092 | if( ESCvar.SMtestresult & SMRESULT_ERRSM3 ) |
vsluiter | 0:a8daa9348a67 | 1093 | ESC_ALerror(ALERR_INVALIDINPUTSM); |
vsluiter | 0:a8daa9348a67 | 1094 | else |
vsluiter | 0:a8daa9348a67 | 1095 | ESC_ALerror(ALERR_INVALIDOUTPUTSM); |
vsluiter | 0:a8daa9348a67 | 1096 | } |
vsluiter | 0:a8daa9348a67 | 1097 | return state; |
vsluiter | 0:a8daa9348a67 | 1098 | } |
vsluiter | 0:a8daa9348a67 | 1099 | |
vsluiter | 0:a8daa9348a67 | 1100 | void ESC_stopinput(void) |
vsluiter | 0:a8daa9348a67 | 1101 | { |
vsluiter | 0:a8daa9348a67 | 1102 | APPstate = APPSTATE_IDLE; |
vsluiter | 0:a8daa9348a67 | 1103 | ESC_SMdisable(3); |
vsluiter | 0:a8daa9348a67 | 1104 | ESC_SMdisable(2); |
vsluiter | 0:a8daa9348a67 | 1105 | } |
vsluiter | 0:a8daa9348a67 | 1106 | |
vsluiter | 0:a8daa9348a67 | 1107 | uint8 ESC_startoutput(uint8 state) |
vsluiter | 0:a8daa9348a67 | 1108 | { |
vsluiter | 0:a8daa9348a67 | 1109 | ESC_SMenable(2); |
vsluiter | 0:a8daa9348a67 | 1110 | APPstate |= APPSTATE_OUTPUT; |
vsluiter | 0:a8daa9348a67 | 1111 | return state; |
vsluiter | 0:a8daa9348a67 | 1112 | } |
vsluiter | 0:a8daa9348a67 | 1113 | |
vsluiter | 0:a8daa9348a67 | 1114 | void ESC_stopoutput(void) |
vsluiter | 0:a8daa9348a67 | 1115 | { |
vsluiter | 0:a8daa9348a67 | 1116 | APPstate &= APPSTATE_INPUT; |
vsluiter | 0:a8daa9348a67 | 1117 | ESC_SMdisable(2); |
vsluiter | 0:a8daa9348a67 | 1118 | APP_safeoutput(); |
vsluiter | 0:a8daa9348a67 | 1119 | } |
vsluiter | 0:a8daa9348a67 | 1120 | |
vsluiter | 0:a8daa9348a67 | 1121 | void ESC_ALevent(void) |
vsluiter | 0:a8daa9348a67 | 1122 | { |
vsluiter | 0:a8daa9348a67 | 1123 | if (!(ESCvar.ALevent & (ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE)) && |
vsluiter | 0:a8daa9348a67 | 1124 | (ESCvar.wdcnt++ < 1000)) |
vsluiter | 0:a8daa9348a67 | 1125 | { //nothing to do |
vsluiter | 0:a8daa9348a67 | 1126 | ESCvar.ALcontrol = 0; |
vsluiter | 0:a8daa9348a67 | 1127 | return; |
vsluiter | 0:a8daa9348a67 | 1128 | } |
vsluiter | 0:a8daa9348a67 | 1129 | ESCvar.wdcnt = 0; |
vsluiter | 0:a8daa9348a67 | 1130 | ESC_read(ESCREG_ALCONTROL, &ESCvar.ALcontrol, sizeof(ESCvar.ALcontrol), &ESCvar.ALevent); |
vsluiter | 0:a8daa9348a67 | 1131 | ESCvar.ALcontrol = etohs(ESCvar.ALcontrol); |
vsluiter | 0:a8daa9348a67 | 1132 | } |
vsluiter | 0:a8daa9348a67 | 1133 | |
vsluiter | 0:a8daa9348a67 | 1134 | void ESC_state(void) |
vsluiter | 0:a8daa9348a67 | 1135 | { |
vsluiter | 0:a8daa9348a67 | 1136 | uint8 ac, an, as, ax; |
vsluiter | 0:a8daa9348a67 | 1137 | if (!ESCvar.ALcontrol) return; //nothing to do |
vsluiter | 0:a8daa9348a67 | 1138 | ac = ESCvar.ALcontrol & 0x001f; |
vsluiter | 0:a8daa9348a67 | 1139 | as = ESCvar.ALstatus & 0x001f; |
vsluiter | 0:a8daa9348a67 | 1140 | an = as; |
vsluiter | 0:a8daa9348a67 | 1141 | if (((ac & ESCerror) || (ac == ESCinit))) |
vsluiter | 0:a8daa9348a67 | 1142 | { |
vsluiter | 0:a8daa9348a67 | 1143 | ac &= 0x0f; // if error bit confirmed reset |
vsluiter | 0:a8daa9348a67 | 1144 | an &= 0x0f; |
vsluiter | 0:a8daa9348a67 | 1145 | } |
vsluiter | 0:a8daa9348a67 | 1146 | if ((ESCvar.ALevent & ESCREG_ALEVENT_SMCHANGE) && |
vsluiter | 0:a8daa9348a67 | 1147 | (as & 0x0e) && |
vsluiter | 0:a8daa9348a67 | 1148 | !(ESCvar.ALevent & ESCREG_ALEVENT_CONTROL) && |
vsluiter | 0:a8daa9348a67 | 1149 | MBXrun) |
vsluiter | 0:a8daa9348a67 | 1150 | { |
vsluiter | 0:a8daa9348a67 | 1151 | ESCvar.ALevent = 0; |
vsluiter | 0:a8daa9348a67 | 1152 | ax = ESC_checkmbx(as); |
vsluiter | 0:a8daa9348a67 | 1153 | if ((as & ESCerror) && ((ac != (ESCinit | ESCerror)) || (ac != ESCinit))) |
vsluiter | 0:a8daa9348a67 | 1154 | return; // if in error then stay there |
vsluiter | 0:a8daa9348a67 | 1155 | if (ax == (ESCinit | ESCerror)) |
vsluiter | 0:a8daa9348a67 | 1156 | { |
vsluiter | 0:a8daa9348a67 | 1157 | if (APPstate) |
vsluiter | 0:a8daa9348a67 | 1158 | { |
vsluiter | 0:a8daa9348a67 | 1159 | ESC_stopoutput(); |
vsluiter | 0:a8daa9348a67 | 1160 | ESC_stopinput(); |
vsluiter | 0:a8daa9348a67 | 1161 | } |
vsluiter | 0:a8daa9348a67 | 1162 | ESC_stopmbx(); |
vsluiter | 0:a8daa9348a67 | 1163 | ESC_ALerror(ALERR_INVALIDMBXCONFIG); |
vsluiter | 0:a8daa9348a67 | 1164 | MBXrun = 0; |
vsluiter | 0:a8daa9348a67 | 1165 | ESC_ALstatus(ax); |
vsluiter | 0:a8daa9348a67 | 1166 | return; |
vsluiter | 0:a8daa9348a67 | 1167 | } |
vsluiter | 0:a8daa9348a67 | 1168 | ax = ESC_checkSM23(as); |
vsluiter | 0:a8daa9348a67 | 1169 | if ((APPstate) && (ax == (ESCpreop | ESCerror))) |
vsluiter | 0:a8daa9348a67 | 1170 | { |
vsluiter | 0:a8daa9348a67 | 1171 | ESC_stopoutput(); |
vsluiter | 0:a8daa9348a67 | 1172 | ESC_stopinput(); |
vsluiter | 0:a8daa9348a67 | 1173 | if( ESCvar.SMtestresult & SMRESULT_ERRSM3 ) |
vsluiter | 0:a8daa9348a67 | 1174 | ESC_ALerror(ALERR_INVALIDINPUTSM); |
vsluiter | 0:a8daa9348a67 | 1175 | else |
vsluiter | 0:a8daa9348a67 | 1176 | ESC_ALerror(ALERR_INVALIDOUTPUTSM); |
vsluiter | 0:a8daa9348a67 | 1177 | ESC_ALstatus(ax); |
vsluiter | 0:a8daa9348a67 | 1178 | return; |
vsluiter | 0:a8daa9348a67 | 1179 | } |
vsluiter | 0:a8daa9348a67 | 1180 | } |
vsluiter | 0:a8daa9348a67 | 1181 | ESCvar.ALevent = 0; |
vsluiter | 0:a8daa9348a67 | 1182 | if ((an & ESCerror) && !(ac & ESCerror)) return; //error state not acked, leave original |
vsluiter | 0:a8daa9348a67 | 1183 | as = (ac << 4) | (as & 0x0f); // high bits ALcommand, low bits ALstatus |
vsluiter | 0:a8daa9348a67 | 1184 | switch (as) |
vsluiter | 0:a8daa9348a67 | 1185 | { |
vsluiter | 0:a8daa9348a67 | 1186 | case INIT_TO_INIT: |
vsluiter | 0:a8daa9348a67 | 1187 | case PREOP_TO_PREOP: |
vsluiter | 0:a8daa9348a67 | 1188 | case OP_TO_OP: |
vsluiter | 0:a8daa9348a67 | 1189 | break; |
vsluiter | 0:a8daa9348a67 | 1190 | case INIT_TO_PREOP: |
vsluiter | 0:a8daa9348a67 | 1191 | ESC_address(); // get station address |
vsluiter | 0:a8daa9348a67 | 1192 | an = ESC_startmbx(ac); |
vsluiter | 0:a8daa9348a67 | 1193 | break; |
vsluiter | 0:a8daa9348a67 | 1194 | case INIT_TO_BOOT: |
vsluiter | 0:a8daa9348a67 | 1195 | an = ESCinit | ESCerror; |
vsluiter | 0:a8daa9348a67 | 1196 | ESC_ALerror(ALERR_BOOTNOTSUPPORTED); |
vsluiter | 0:a8daa9348a67 | 1197 | break; |
vsluiter | 0:a8daa9348a67 | 1198 | case INIT_TO_SAFEOP: |
vsluiter | 0:a8daa9348a67 | 1199 | case INIT_TO_OP: |
vsluiter | 0:a8daa9348a67 | 1200 | an = ESCinit | ESCerror; |
vsluiter | 0:a8daa9348a67 | 1201 | ESC_ALerror(ALERR_INVALIDSTATECHANGE); |
vsluiter | 0:a8daa9348a67 | 1202 | break; |
vsluiter | 0:a8daa9348a67 | 1203 | case OP_TO_INIT: |
vsluiter | 0:a8daa9348a67 | 1204 | ESC_stopoutput(); |
vsluiter | 0:a8daa9348a67 | 1205 | case SAFEOP_TO_INIT: |
vsluiter | 0:a8daa9348a67 | 1206 | ESC_stopinput(); |
vsluiter | 0:a8daa9348a67 | 1207 | case PREOP_TO_INIT: |
vsluiter | 0:a8daa9348a67 | 1208 | ESC_stopmbx(); |
vsluiter | 0:a8daa9348a67 | 1209 | an = ESCinit; |
vsluiter | 0:a8daa9348a67 | 1210 | break; |
vsluiter | 0:a8daa9348a67 | 1211 | case PREOP_TO_BOOT: |
vsluiter | 0:a8daa9348a67 | 1212 | an = ESCpreop | ESCerror; |
vsluiter | 0:a8daa9348a67 | 1213 | ESC_ALerror(ALERR_INVALIDSTATECHANGE); |
vsluiter | 0:a8daa9348a67 | 1214 | break; |
vsluiter | 0:a8daa9348a67 | 1215 | case PREOP_TO_SAFEOP: |
vsluiter | 0:a8daa9348a67 | 1216 | case SAFEOP_TO_SAFEOP: |
vsluiter | 0:a8daa9348a67 | 1217 | SM2_sml = sizeRXPDO(); |
vsluiter | 0:a8daa9348a67 | 1218 | SM3_sml = sizeTXPDO(); |
vsluiter | 0:a8daa9348a67 | 1219 | an = ESC_startinput(ac); |
vsluiter | 0:a8daa9348a67 | 1220 | if (an == ac) ESC_SMenable(2); |
vsluiter | 0:a8daa9348a67 | 1221 | break; |
vsluiter | 0:a8daa9348a67 | 1222 | case PREOP_TO_OP: |
vsluiter | 0:a8daa9348a67 | 1223 | an = ESCpreop | ESCerror; |
vsluiter | 0:a8daa9348a67 | 1224 | ESC_ALerror(ALERR_INVALIDSTATECHANGE); |
vsluiter | 0:a8daa9348a67 | 1225 | break; |
vsluiter | 0:a8daa9348a67 | 1226 | case OP_TO_PREOP: |
vsluiter | 0:a8daa9348a67 | 1227 | ESC_stopoutput(); |
vsluiter | 0:a8daa9348a67 | 1228 | case SAFEOP_TO_PREOP: |
vsluiter | 0:a8daa9348a67 | 1229 | ESC_stopinput(); |
vsluiter | 0:a8daa9348a67 | 1230 | an = ESCpreop; |
vsluiter | 0:a8daa9348a67 | 1231 | break; |
vsluiter | 0:a8daa9348a67 | 1232 | case SAFEOP_TO_BOOT: |
vsluiter | 0:a8daa9348a67 | 1233 | an = ESCsafeop | ESCerror; |
vsluiter | 0:a8daa9348a67 | 1234 | ESC_ALerror(ALERR_INVALIDSTATECHANGE); |
vsluiter | 0:a8daa9348a67 | 1235 | break; |
vsluiter | 0:a8daa9348a67 | 1236 | case SAFEOP_TO_OP: |
vsluiter | 0:a8daa9348a67 | 1237 | an = ESC_startoutput(ac); |
vsluiter | 0:a8daa9348a67 | 1238 | break; |
vsluiter | 0:a8daa9348a67 | 1239 | case OP_TO_BOOT: |
vsluiter | 0:a8daa9348a67 | 1240 | an = ESCsafeop | ESCerror; |
vsluiter | 0:a8daa9348a67 | 1241 | ESC_ALerror(ALERR_INVALIDSTATECHANGE); |
vsluiter | 0:a8daa9348a67 | 1242 | ESC_stopoutput(); |
vsluiter | 0:a8daa9348a67 | 1243 | break; |
vsluiter | 0:a8daa9348a67 | 1244 | case OP_TO_SAFEOP: |
vsluiter | 0:a8daa9348a67 | 1245 | an = ESCsafeop; |
vsluiter | 0:a8daa9348a67 | 1246 | ESC_stopoutput(); |
vsluiter | 0:a8daa9348a67 | 1247 | break; |
vsluiter | 0:a8daa9348a67 | 1248 | default : |
vsluiter | 0:a8daa9348a67 | 1249 | if (an == ESCop) |
vsluiter | 0:a8daa9348a67 | 1250 | { |
vsluiter | 0:a8daa9348a67 | 1251 | ESC_stopoutput(); |
vsluiter | 0:a8daa9348a67 | 1252 | an = ESCsafeop; |
vsluiter | 0:a8daa9348a67 | 1253 | } |
vsluiter | 0:a8daa9348a67 | 1254 | if (as == ESCsafeop) |
vsluiter | 0:a8daa9348a67 | 1255 | ESC_stopinput(); |
vsluiter | 0:a8daa9348a67 | 1256 | an |= ESCerror; |
vsluiter | 0:a8daa9348a67 | 1257 | ESC_ALerror(ALERR_UNKNOWNSTATE); |
vsluiter | 0:a8daa9348a67 | 1258 | } |
vsluiter | 0:a8daa9348a67 | 1259 | if (!(an & ESCerror) && (ESCvar.ALerror)) |
vsluiter | 0:a8daa9348a67 | 1260 | { |
vsluiter | 0:a8daa9348a67 | 1261 | ESC_ALerror(ALERR_NONE); // clear error |
vsluiter | 0:a8daa9348a67 | 1262 | } |
vsluiter | 0:a8daa9348a67 | 1263 | ESC_ALstatus(an); |
vsluiter | 0:a8daa9348a67 | 1264 | } |
vsluiter | 0:a8daa9348a67 | 1265 |