etisserant@0: /* etisserant@0: This file is part of CanFestival, a library implementing CanOpen Stack. etisserant@0: etisserant@0: Author: CANopen Canada (canfestival@canopencanada.ca) etisserant@0: etisserant@0: See COPYING file for copyrights details. etisserant@0: etisserant@0: This library is free software; you can redistribute it and/or etisserant@0: modify it under the terms of the GNU Lesser General Public etisserant@0: License as published by the Free Software Foundation; either etisserant@0: version 2.1 of the License, or (at your option) any later version. etisserant@0: etisserant@0: This library is distributed in the hope that it will be useful, etisserant@0: but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@0: Lesser General Public License for more details. etisserant@0: etisserant@0: You should have received a copy of the GNU Lesser General Public etisserant@0: License along with this library; if not, write to the Free Software etisserant@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: */ etisserant@0: etisserant@0: #include etisserant@0: #include etisserant@0: etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: #include "can_driver.h" etisserant@0: etisserant@0: #ifdef LED_ENABLE etisserant@0: #include "led.h" etisserant@0: #else etisserant@0: #define led_set_state(a,b) etisserant@0: #endif etisserant@0: etisserant@0: #include "lss.h" etisserant@0: etisserant@0: etisserant@0: etisserant@0: /* etisserant@0: NOTES etisserant@0: etisserant@0: 1. since in the LSS protocol all LSS Slave use the same COB, only 1 Slave etisserant@0: must be allowed to communicate with the Master etisserant@0: etisserant@0: 2. the Master always take the iniative. the Slave is only allowed to transmit etisserant@0: within a confirmed service etisserant@0: etisserant@0: 3. requesting message (from the Master) using COB-ID 2021 and response messages etisserant@0: (from the Slave) using COB-ID 2020 etisserant@0: */ etisserant@0: etisserant@0: /* etisserant@0: 0 = this slave is not talking to the master etisserant@0: 1 = this slave is talking to the master (this slave has been selected via ) etisserant@0: */ etisserant@0: int slave_selector; etisserant@0: etisserant@0: int current_mode; etisserant@0: etisserant@0: int lss_table_selector, lss_table_index; etisserant@0: etisserant@0: etisserant@0: /* slave storing the information sent by the master */ etisserant@0: UNS32 lss_buffer[10]; etisserant@0: /* etisserant@0: how this buffer is used etisserant@0: etisserant@0: for a SLAVE etisserant@0: [0..3] used to store the LSS Address etisserant@0: [4..9] use by LSS Identify Remort Slave etisserant@0: etisserant@0: for the MASTER etisserant@0: [0..3] hold the answer from the slave regarding its ID etisserant@0: */ etisserant@0: etisserant@0: etisserant@0: void lss_copy(UNS8 *data, UNS32 value) etisserant@0: /* transfert 32 bits value into uns8 data vector */ etisserant@0: { etisserant@0: data[0] = value & 0xff; etisserant@0: data[1] = (value>>8) & 0xff; etisserant@0: data[2] = (value>>16) & 0xff; etisserant@0: data[3] = (value>>24) & 0xff; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: UNS32 lss_get_value(UNS8 *data) etisserant@0: /* build a 'UNS32' value from a 'unsigned char' vector */ etisserant@0: { etisserant@0: return data[0] + (data[1]<<8) + (data[2]<<16) + (data[3]<<24); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_init_msg(Message *msg) etisserant@0: { etisserant@0: msg->cob_id.w = 0; etisserant@0: msg->rtr = 0; etisserant@0: msg->len = 0; etisserant@0: msg->data[0] = 0; etisserant@0: msg->data[1] = 0; etisserant@0: msg->data[2] = 0; etisserant@0: msg->data[3] = 0; etisserant@0: msg->data[4] = 0; etisserant@0: msg->data[5] = 0; etisserant@0: msg->data[6] = 0; etisserant@0: msg->data[7] = 0; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_SwitchModeGlobal(CO_Data *d, UNS32 mode) etisserant@0: /* etisserant@0: this service is used to switch all LSS slaves in the network between operation etisserant@0: mode and configuration mode. etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: /* etisserant@0: sending a COB-ID 2021 etisserant@0: [0] = 4 (for switch mode global) etisserant@0: [1] = 0 for operation mode, = 1 for configuration mode etisserant@0: [2..7] = 0 reserved etisserant@0: */ etisserant@0: etisserant@0: if (!(d->iam_a_slave)) etisserant@0: { etisserant@0: msg.cob_id.w = 0x07E5 /* 2021 */; etisserant@0: etisserant@0: msg.len = 2; etisserant@0: msg.data[0] = 4; etisserant@0: msg.data[1] = (UNS8)mode; etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: else etisserant@0: { etisserant@0: /* set mode global */ etisserant@0: current_mode = mode; etisserant@0: } etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_SwitchModeSelective_master(CO_Data *d, UNS32 *LSSaddr) etisserant@0: /* etisserant@0: LSS address : etisserant@0: vendor-id : provided by CiA etisserant@0: identical to the CANopen identity object etisserant@0: etisserant@0: select the slave corresponding to this ADDRESS etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: if (d->iam_a_slave) /* not the master */ etisserant@0: return; etisserant@0: etisserant@0: msg.cob_id.w = 0x07E5 /* 2021 */; etisserant@0: msg.len=5; etisserant@0: etisserant@0: msg.data[0] = 64; etisserant@0: lss_copy(msg.data+1, LSSaddr[0]); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: etisserant@0: msg.data[0] = 65; etisserant@0: lss_copy(msg.data+1, LSSaddr[1]); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: etisserant@0: msg.data[0] = 66; etisserant@0: lss_copy(msg.data+1, LSSaddr[2]); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: etisserant@0: msg.data[0] = 67; etisserant@0: lss_copy(msg.data+1, LSSaddr[3]); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: UNS32 lss_validate_address(CO_Data* d) etisserant@0: { etisserant@0: #if 0 etisserant@0: extern s_identity obj1018; etisserant@0: etisserant@0: /* maybe we should go throught getODentry but those etisserant@0: data are 1) RO and 2) the proper ID of this device */ etisserant@0: #else etisserant@0: UNS32 r, vendor_id, product_code, revision_number, serial_number; etisserant@0: UNS8 sz = sizeof(UNS32), dt = int32; etisserant@0: etisserant@0: r = getODentry(d, 0x1018, 1, (void *)&vendor_id, &sz, &dt, 0); etisserant@0: r = getODentry(d, 0x1018, 2, (void *)&product_code, &sz, &dt, 0); etisserant@0: r = getODentry(d, 0x1018, 3, (void *)&revision_number, &sz, &dt, 0); etisserant@0: r = getODentry(d, 0x1018, 4, (void *)&serial_number, &sz, &dt, 0); etisserant@0: etisserant@0: #endif etisserant@0: /* etisserant@0: if etisserant@0: lss_buffer[0] == vendor-id etisserant@0: lss_buffer[1] == product code etisserant@0: lss_buffer[2] == revision etisserant@0: lss_buffer[3] == serial etisserant@0: etisserant@0: then return 1 etisserant@0: else return 0; etisserant@0: */ etisserant@0: etisserant@0: if (lss_buffer[0] == vendor_id && etisserant@0: lss_buffer[1] == product_code && etisserant@0: lss_buffer[2] == revision_number && etisserant@0: lss_buffer[3] == serial_number) etisserant@0: { etisserant@0: return 1; etisserant@0: } etisserant@0: etisserant@0: return 0; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_SwitchModeSelective_slave(CO_Data *d) etisserant@0: /* etisserant@0: SwitchModeSelective for the SLAVE etisserant@0: received the frames from the master and start building etisserant@0: the lss address etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: /* etisserant@0: the master broadcast the address of a particular slave etisserant@0: for 64,65 and 66 store the partial address etisserant@0: when 67 arrive process the call and asknowledge if necessary etisserant@0: */ etisserant@0: etisserant@0: if (lss_validate_address(d)) etisserant@0: { etisserant@0: /* slave should transmit cob_id 2020 */ etisserant@0: msg.cob_id.w = 0x07E4 /* 2020 */; etisserant@0: etisserant@0: msg.len = 2; etisserant@0: msg.data[0] = 68; etisserant@0: msg.data[1] = (UNS8)current_mode; etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: etisserant@0: /* reset the address */ etisserant@0: lss_buffer[0] = 0; etisserant@0: lss_buffer[1] = 0; etisserant@0: lss_buffer[2] = 0; etisserant@0: lss_buffer[3] = 0; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_ConfigureNode_ID(CO_Data *d, UNS32 node_id) etisserant@0: /* etisserant@0: through this service the LSS Master configures the NMT-address etisserant@0: parameter of a LSS slave. etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: if (!(d->iam_a_slave)) etisserant@0: { etisserant@0: msg.cob_id.w = 0x07E5 /* 2021 */; etisserant@0: etisserant@0: msg.len = 2; etisserant@0: msg.data[0] = 17; etisserant@0: msg.data[1] = (UNS8)node_id; etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: else etisserant@0: { etisserant@0: /* etisserant@0: receiving NODE ID from the master etisserant@0: */ etisserant@0: etisserant@0: /* etisserant@0: error code etisserant@0: 0 = success etisserant@0: 1 = node id out of range etisserant@0: 2..254 = reserved etisserant@0: 255 = implementation specific error occured etisserant@0: spec error = mode detailed error etisserant@0: */ etisserant@0: msg.cob_id.w = 0x07E4 /* 2020 */; etisserant@0: etisserant@0: msg.len = 3; etisserant@0: msg.data[0] = 17; etisserant@0: /* msg.data[1] = error code */ etisserant@0: /* msg.data[2] = spec error */ etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_ConfigureBitTimingParameters(CO_Data *d, etisserant@0: UNS32 table_selector, etisserant@0: UNS32 table_index) etisserant@0: /* etisserant@0: this service allows all LSS slaves in configuration mode. etisserant@0: must be followed by an Activate Bit Timing Parameters etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: if (!(d->iam_a_slave)) etisserant@0: { etisserant@0: msg.cob_id.w = 0x07E5 /* 2021 */; etisserant@0: etisserant@0: msg.len = 3; etisserant@0: msg.data[0] = 19; etisserant@0: msg.data[1] = (UNS8)table_selector; etisserant@0: msg.data[2] = (UNS8)table_index; etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: else etisserant@0: { etisserant@0: UNS8 error_code; etisserant@0: etisserant@0: /* validate if this baudrate is possible */ etisserant@0: if (table_selector == 0 && baudrate_valid(table_index) == 1) etisserant@0: { etisserant@0: lss_table_selector = table_selector; etisserant@0: lss_table_index = table_index; etisserant@0: } etisserant@0: else etisserant@0: error_code = 1; /* bit timing not supported */ etisserant@0: etisserant@0: msg.cob_id.w = 0x07E4 /* 2020 */; etisserant@0: etisserant@0: msg.len = 3; etisserant@0: msg.data[0] = 19; etisserant@0: msg.data[1] = error_code; etisserant@0: msg.data[2] = 0; etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: etisserant@0: led_set_state(d, LED_AUTOBITRATE); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_ActivateBitTimingParameters_master(CO_Data *d, unsigned short switch_delay) etisserant@0: /* etisserant@0: switch_delay in ms etisserant@0: etisserant@0: switch_delay has to be longer than the longest timeof any node etisserant@0: in the network to avoid that a node already switches while another etisserant@0: stills transmist the old bit timing parameters etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: if (d->iam_a_slave) etisserant@0: return; etisserant@0: etisserant@0: msg.cob_id.w = 0x07E5 /* 2021 */; etisserant@0: etisserant@0: msg.len = 3; etisserant@0: msg.data[0] = 21; etisserant@0: msg.data[1] = (UNS8)(switch_delay & 0xff); etisserant@0: msg.data[2] = (UNS8)((switch_delay >> 8) & 0xff); etisserant@0: etisserant@0: #ifdef LED_ENABLE etisserant@0: led_set_state(LED_AUTOBITRATE); etisserant@0: #endif etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_ActivateBitTimingParameters_slave(UNS8 byte_low, UNS8 byte_high) etisserant@0: { etisserant@0: /* rebuild the delay value (short) from the 2 (UNS8) data */ etisserant@0: unsigned short switch_delay = byte_low + (((UNS16)byte_high)<<8); etisserant@0: etisserant@0: /* set the baudrate to the value proposed by the master */ etisserant@0: if (lss_table_selector == 0) etisserant@0: baudrate_set(lss_table_index); etisserant@0: etisserant@0: /* wait for switch_delay ms before continuing */ etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_StoreConfiguredParameters(CO_Data *d) etisserant@0: /* etisserant@0: store configured parameters into non-volatile storage etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: if (!(d->iam_a_slave)) etisserant@0: { etisserant@0: msg.cob_id.w = 0x07E5 /* 2021 */; etisserant@0: etisserant@0: msg.len = 1; etisserant@0: msg.data[0] = 23; etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: else etisserant@0: { etisserant@0: msg.cob_id.w = 0x07E4 /* 2020 */; etisserant@0: etisserant@0: msg.data[0] = 23; etisserant@0: /* msg.data[1] = error code; */ etisserant@0: /* msg.data[2] = spec err */ etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_InquireLSSAddress_master(CO_Data *d, int flag) etisserant@0: /* etisserant@0: this service allows to determine the LSS-address parameters of a LSS-slave in etisserant@0: configuration mode etisserant@0: etisserant@0: request 1 single item of the LSS address etisserant@0: 0 = request vendor-id etisserant@0: 1 = request product-id etisserant@0: 2 = request revision etisserant@0: 3 = request serial etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: if (!(d->iam_a_slave)) etisserant@0: { etisserant@0: msg.cob_id.w = 0x07E5 /* 2021 */; etisserant@0: etisserant@0: msg.len = 1; etisserant@0: msg.data[0] = 90 + flag; etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: } etisserant@0: etisserant@0: etisserant@0: int lss_InquireLSSAddress_slave(CO_Data *d, int cs) etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: if (!(d->iam_a_slave)) /* not a slave */ etisserant@0: return -1; etisserant@0: etisserant@0: UNS32 value = 0; etisserant@0: etisserant@0: switch(cs) etisserant@0: { etisserant@0: case 90: etisserant@0: value = 0; /* = vendor id */ etisserant@0: break; etisserant@0: case 91: etisserant@0: value = 0; /* = product code */ etisserant@0: break; etisserant@0: case 92: etisserant@0: value = 0; /* = revision */ etisserant@0: break; etisserant@0: case 93: etisserant@0: value = 0; /* = serial */ etisserant@0: break; etisserant@0: } etisserant@0: etisserant@0: if (value > 0) etisserant@0: { etisserant@0: msg.cob_id.w = 0x07E4 /* 2020 */; etisserant@0: etisserant@0: msg.len=5; etisserant@0: msg.data[0] = cs; etisserant@0: lss_copy(msg.data+1, value); etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: etisserant@0: return 0; etisserant@0: } etisserant@0: etisserant@0: return -1; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_IdentifyRemoteSlaves(CO_Data *d, etisserant@0: UNS32 vendor_id, etisserant@0: UNS32 product_code, etisserant@0: UNS32 rev_low, etisserant@0: UNS32 rev_high, etisserant@0: UNS32 serial_low, etisserant@0: UNS32 serial_high) etisserant@0: /* etisserant@0: throught this service, the LSS Master requests all LSS slave whose LSS address etisserant@0: meets the LSSaddr_sel to idenfity themselves through LSS Identify Slave etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: if (!(d->iam_a_slave)) etisserant@0: { etisserant@0: /* etisserant@0: request answers from all slaves corresponding etisserant@0: to the revision and serial range of values etisserant@0: */ etisserant@0: etisserant@0: msg.cob_id.w = 0x07E5 /* 2021 */; etisserant@0: msg.len=5; etisserant@0: etisserant@0: msg.data[0] = 70; etisserant@0: lss_copy(msg.data+1, vendor_id); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: etisserant@0: msg.data[0] = 71; etisserant@0: lss_copy(msg.data+1, product_code); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: etisserant@0: msg.data[0] = 72; /* revision number low */ etisserant@0: lss_copy(msg.data+1, rev_low); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: etisserant@0: msg.data[0] = 73; /* revision number high */ etisserant@0: lss_copy(msg.data+1, rev_high); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: etisserant@0: msg.data[0] = 74; /* serial number low */ etisserant@0: lss_copy(msg.data+1, serial_low); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: etisserant@0: msg.data[0] = 75; /* serial number high */ etisserant@0: lss_copy(msg.data+1, serial_high); etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: } etisserant@0: etisserant@0: etisserant@0: int lss_validate_range_addr(CO_Data *d) etisserant@0: { etisserant@0: /* etisserant@0: if etisserant@0: etisserant@0: lss_buffer[4] == vendor_id etisserant@0: lss_buffer[5] == product code etisserant@0: lss_buffer[6] <= revision <= lss_buffer[7] etisserant@0: lss_buffer[8] <= serial <= lss_buffer[9] etisserant@0: etisserant@0: then return 1 etisserant@0: else return 0 etisserant@0: */ etisserant@0: etisserant@0: UNS32 r, vendor_id, product_code, revision_number, serial_number; etisserant@0: UNS8 sz = sizeof(UNS32), dt = int32; etisserant@0: etisserant@0: r = getODentry(d, 0x1018, 1, (void *)&vendor_id, &sz, &dt, 0); etisserant@0: r = getODentry(d, 0x1018, 2, (void *)&product_code, &sz, &dt, 0); etisserant@0: r = getODentry(d, 0x1018, 3, (void *)&revision_number, &sz, &dt, 0); etisserant@0: r = getODentry(d, 0x1018, 4, (void *)&serial_number, &sz, &dt, 0); etisserant@0: etisserant@0: if (lss_buffer[4] == vendor_id && etisserant@0: lss_buffer[5] == product_code && etisserant@0: lss_buffer[6] <= revision_number && etisserant@0: revision_number <= lss_buffer[7] && etisserant@0: lss_buffer[8] <= serial_number && etisserant@0: serial_number <= lss_buffer[9]) etisserant@0: { etisserant@0: return 1; etisserant@0: } etisserant@0: etisserant@0: return 0; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: void lss_IdentifySlave(CO_Data *d) etisserant@0: /* etisserant@0: through this service, an LSS slave indicates that it is a slave etisserant@0: with LSS address within the LSSaddr_sel etisserant@0: */ etisserant@0: { etisserant@0: Message msg; etisserant@0: lss_init_msg(&msg); etisserant@0: etisserant@0: if (lss_validate_range_addr(d)) etisserant@0: { etisserant@0: msg.cob_id.w = 0x07E4 /* 2020 */; etisserant@0: etisserant@0: msg.len = 1; etisserant@0: msg.data[0] = 79; etisserant@0: etisserant@0: /* transmit */ etisserant@0: (*d->canSend)(&msg); etisserant@0: } etisserant@0: etisserant@0: /* reset */ etisserant@0: lss_buffer[4] = 0; etisserant@0: lss_buffer[5] = 0; etisserant@0: lss_buffer[6] = 0; etisserant@0: lss_buffer[7] = 0; etisserant@0: lss_buffer[8] = 0; etisserant@0: lss_buffer[9] = 0; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: int lss_process_msg(CO_Data *d, Message *msg) etisserant@0: { etisserant@0: /* process the incoming message */ etisserant@0: if (msg->cob_id.w == 0x07E4 /* 2020 */) etisserant@0: { etisserant@0: // should be the master etisserant@0: // a slave just answered etisserant@0: switch(msg->data[0]) etisserant@0: { etisserant@0: /* slave acknowledging the SwitchModeSelective call */ etisserant@0: case 68: etisserant@0: /* msg->data[1] contains the 'mode global' value from the slave*/ etisserant@0: break; etisserant@0: etisserant@0: /* a slave had acknowledged the call from LSS Identify Remote Slave */ etisserant@0: case 79: etisserant@0: break; etisserant@0: etisserant@0: /* the slave acknowledged and sent the requested data */ etisserant@0: case 90: etisserant@0: lss_buffer[0] = lss_get_value(msg->data+1); etisserant@0: /* action ? */ etisserant@0: break; etisserant@0: case 91: etisserant@0: lss_buffer[1] = lss_get_value(msg->data+1); etisserant@0: /* action ? */ etisserant@0: break; etisserant@0: case 92: etisserant@0: lss_buffer[2] = lss_get_value(msg->data+1); etisserant@0: /* action ? */ etisserant@0: break; etisserant@0: case 93: etisserant@0: lss_buffer[3] = lss_get_value(msg->data+1); etisserant@0: /* action ? */ etisserant@0: break; etisserant@0: } etisserant@0: } etisserant@0: etisserant@0: else if (msg->cob_id.w == 0x07E5 /* 2021 */) etisserant@0: { etisserant@0: // should be a slave etisserant@0: // the master sent a request etisserant@0: switch(msg->data[0]) etisserant@0: { etisserant@0: case 4: etisserant@0: lss_SwitchModeGlobal(d, msg->data[1]); etisserant@0: break; etisserant@0: etisserant@0: case 17: etisserant@0: lss_ConfigureNode_ID(d, msg->data[1]); etisserant@0: break; etisserant@0: etisserant@0: case 19: etisserant@0: lss_ConfigureBitTimingParameters(d, msg->data[1], msg->data[2]); etisserant@0: break; etisserant@0: case 21: etisserant@0: lss_ActivateBitTimingParameters_slave(msg->data[1], msg->data[2]); etisserant@0: break; etisserant@0: etisserant@0: /* Switch Mode Selective */ etisserant@0: case 64: etisserant@0: lss_buffer[0] = lss_get_value(msg->data+1); etisserant@0: break; etisserant@0: case 65: etisserant@0: lss_buffer[1] = lss_get_value(msg->data+1); etisserant@0: break; etisserant@0: case 66: etisserant@0: lss_buffer[2] = lss_get_value(msg->data+1); etisserant@0: break; etisserant@0: case 67: etisserant@0: lss_buffer[3] = lss_get_value(msg->data+1); etisserant@0: lss_SwitchModeSelective_slave(d); etisserant@0: break; etisserant@0: etisserant@0: /* Identify Remote Slave */ etisserant@0: case 70: etisserant@0: lss_buffer[4] = lss_get_value(msg->data+1); etisserant@0: break; etisserant@0: case 71: etisserant@0: lss_buffer[5] = lss_get_value(msg->data+1); etisserant@0: break; etisserant@0: case 72: etisserant@0: lss_buffer[6] = lss_get_value(msg->data+1); etisserant@0: break; etisserant@0: case 73: etisserant@0: lss_buffer[7] = lss_get_value(msg->data+1); etisserant@0: break; etisserant@0: case 74: etisserant@0: lss_buffer[8] = lss_get_value(msg->data+1); etisserant@0: break; etisserant@0: case 75: etisserant@0: lss_buffer[9] = lss_get_value(msg->data+1); etisserant@0: lss_IdentifySlave(d); etisserant@0: break; etisserant@0: etisserant@0: /* Inquire Identify of Slave */ etisserant@0: case 90: etisserant@0: case 91: etisserant@0: case 92: etisserant@0: case 93: etisserant@0: lss_InquireLSSAddress_slave(d, msg->data[0]); etisserant@0: break; etisserant@0: } etisserant@0: } etisserant@0: etisserant@0: return 0; etisserant@0: }