source: trunk/fw_g473rct/SES/src/modbus.c @ 22

Last change on this file since 22 was 22, checked in by f.jahn, 24 hours ago

DMA Rx funktioniert, aber BETA und nur feste Baudrate

File size: 20.2 KB
RevLine 
[20]1/*
2 * modbus.c
3 *
4 * Created: 03.09.2012 08:39:20
5 *  Author: Falko
6 */ 
7
8
9
10#if MODBUS_SUPPORT == TRUE
11 
12  #include "modbus.h"
13  //#include "stm32g4xx_hal.h"
14  #include "main.h"
15  //#include "stm32g0xx_hal_tim.h"
16  //#include "stm32_hal_legacy.h"
17  #include <stdio.h>
18  // ---------------------------------------------------------
19  // -------------------- MODUL DEFINES ----------------------
20  // ---------------------------------------------------------
21
22
23               
24
25  #define MODBUS_BROADCAST_ADDRESS        0x00
26  #define FC_READ_COILS                   0x01
27  #define FC_READ_HOLDING_REGISTERS       0x03
28  #define FC_WRITE_SINGLE_REGISTER        0x06
29  #define FC_WRITE_MULTIPLE_REGISTER      0x10
30
31  /* Protocol exceptions */
32  #define ILLEGAL_FUNCTION                0x01
33  #define ILLEGAL_DATA_ADDRESS            0x02
34  #define ILLEGAL_DATA_VALUE              0x03
35  #define SLAVE_DEVICE_FAILURE            0x04
36  #define SERVER_FAILURE                    0x04
37  #define ACKNOWLEDGE                     0x05
38  #define SLAVE_DEVICE_BUSY               0x06
39  #define SERVER_BUSY                     0x06
40  #define NEGATIVE_ACKNOWLEDGE            0x07
41  #define MEMORY_PARITY_ERROR             0x08
42  #define GATEWAY_PROBLEM_PATH            0x0A
43  #define GATEWAY_PROBLEM_TARGET            0x0B
44
45  /* Local Error codes */
46  #define INVALID_CRC                     -1
47
48  // Position der Daten im Rx String
49  #define OFFSET_SLAVE_ADRESS             0x00
50  #define OFFSET_FUNCTION_CODE            0x01
51  #define OFFSET_START_ADRESS_HI          0x02
52  #define OFFSET_START_ADRESS_LO          0x03
53  #define OFFSET_NO_OF_REGISTERS_HI       0x04
54  #define OFFSET_NO_OF_REGISTERS_LO       0x05
55
56  #define MIN_NUMBER_OF_REGISTERS_FC3     0x01
57  #define MAX_NUMBER_OF_REGISTERS_FC3     0x7D
58  #define MIN_NUMBER_OF_REGISTERS_FC16    0x01
59  #define MAX_NUMBER_OF_REGISTERS_FC16    0x7B
60
61  #ifdef DEBUG
62    #define RESPONSE_TIMEOUT                300 // * 1ms
63  #else
64    #define RESPONSE_TIMEOUT                1000 // * 1ms
65  #endif
66
67  #define FAST_BAUDRATE_INTERFRAME_DELAY_us   (1750UL)
68  // --- Externe Variablen --------------------------------------------
[22]69  extern volatile modbus_t modbusData;
70  extern volatile sys_data_t sys_data;
[20]71
72
73  // --- Private Funktions Prototypen --------------------------------------------
74 
75                    void    mbUartInit                      (modbus_t * mb_data,UART_HandleTypeDef * usart, uint32_t baudrate,  uint32_t parityMode,  uint32_t stopBits , uint32_t nrOfBitsPerChar);
76                uint16_t    mbCrc16                         (uint8_t *buf, uint32_t len);
77                    void    mbSend                          (modbus_t * mb_data );
78                uint32_t    mbSlaveReadHoldingRegisters     (uint8_t * response_string, uint8_t *msg, uint32_t tx_position, uint8_t deviceID);
79                uint32_t    mbSlaveWriteMultipleRegisters   (uint8_t * response_string, uint8_t *msg,    uint32_t tx_position, uint32_t deviceID);
80                uint32_t    mbSlaveWriteSingleRegister      (uint8_t * response_string,uint8_t *msg,uint32_t tx_position, uint32_t deviceID);
81                uint32_t    mbSlaveResponseException        (uint8_t* response_string, uint32_t function_code, uint32_t exception_code,uint32_t tx_position) ;
82static HAL_StatusTypeDef    RS485_ModbusEx_Init             (UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, uint32_t DeassertionTime, uint32_t charReceiveTimeout);
83static              void    UART_TxISR_8BIT                 (UART_HandleTypeDef *huart);
84
85  // --- GEMEINSAME MODBUS FUNKTIONEN --------------------------------------------
86  // Diese Funktionen werden sowohl von Modbus Master als auch Modbus Slave verwendet
87
88  /*
89    *
90    * @brief  Diese Funktion Initialisert die Modbus Datenstrukturen und die Hardware
91    *
92    * Das Modbus Modul bentigt einen UART und einen Timer pro Modbus Anschluss
93    * Die Funktion erfordert eine vorhandene Callback funktion namens HAL_UART_MspInit
94    * In dieser muss:
95    * - Der UART CLK eingeschaltet werden
96    * - Die Pins initialisert werden (Alternate Port Funktion)
97    * - Der NVIC Interrupt eingeschaltet werden
98    * @param  mb_data : Datenstruktur zur Aufnahme aller Daten
99    * @param  baudrate : Bautrate
100    * @param  parityMode : Parity, mglich ist UART_PARITY_ODD, UART_PARITY_EVEN, UART_PARITY_NONE. Default ist lt. Modbus Standart EVEN
101    * @param  usart : Timer Modul, z.B. USART1
102    * @retval None
103  */
104  void mbInit(modbus_t* mb_data, uint32_t baudrate, uint32_t parityMode, uint16_t stopBits, UART_HandleTypeDef* usart)
105  {
106    uint32_t numberOfBitsPerChar;
107    //uint32_t stopBits;
108
109    if (stopBits < 1U || stopBits > 2U) stopBits = 1U;
110
111    // Berechne Stop Bits
112    /*if ((parityMode== MODBUS_UART_PARITY_EVEN) || (parityMode == MODBUS_UART_PARITY_ODD))
113    {
114      stopBits = 1;
115    }
116    else
117    {
118      stopBits = 2;
119    }*/
120 
121    // Berechne Anzahl der Bits per Char
122    numberOfBitsPerChar = NUMBER_OF_STARTBITS + NUMBER_OF_DATABITS + stopBits;
123    if ((parityMode == MODBUS_UART_PARITY_EVEN) || (parityMode == MODBUS_UART_PARITY_ODD)) 
124    {
125      numberOfBitsPerChar +=1; 
126    }
127     
128    mbUartInit(mb_data,usart, baudrate, parityMode, stopBits, numberOfBitsPerChar);
129
130    // Datenstrukturen zurcksetzen
131    mb_data->last_query_function_code         =   0;
132    mb_data->last_query_tcp_id.w              =   0;
133    mb_data->last_query_number_of_register.=   0;
134    mb_data->current_query                    =   MB_QUERY_NOTHING;
135    mb_data->last_query_slave_adress          =   0;
136    mb_data->last_query_start_adress.w        =   0;
137    mb_data->last_query_timeout               =   false;
138  }
139
140  /*
141    *
142    * @brief  Diese Funktion Initialisert die Modbus UART Hardware
143    *
144    * @param  mb_data : Datenstruktur zur Aufnahme aller Daten
145    * @param  usart : UART Modul, z.B. USART1
146    * @param  baudrate : UART BAUD
147    * @param  parityMmode : Parity, mglich ist:
148              UART_PARITY_ODD, UART_PARITY_EVEN, UART_PARITY_NONE.
149              Default ist lt. Modbus Standart EVEN
150    * @param  stopBits : Anzahl der Stop Bits, lt Modbus Standart
151    *         2 Stop Bits bei Parity None, ansonsten 2 Stop Bits
152    * @retval None   
153  */
154  void mbUartInit(modbus_t * mb_data,UART_HandleTypeDef * usart, uint32_t baudrate,  uint32_t parityMode,  uint32_t stopBits , uint32_t nrOfBitsPerChar)
155  {
156    //--- Uart Init ------------------------------------------------------------
157    mb_data->uart      = usart;
158   
159    // Init aus Cube
[22]160    mb_data->uart->Instance = USART2;
161    mb_data->uart->Init.BaudRate = baudrate;
[20]162    mb_data->uart->Init.WordLength = UART_WORDLENGTH_9B;
163    mb_data->uart->Init.StopBits = UART_STOPBITS_1;
164    mb_data->uart->Init.Parity = UART_PARITY_EVEN;
165    mb_data->uart->Init.Mode = UART_MODE_TX_RX;
166    mb_data->uart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
167    mb_data->uart->Init.OverSampling = UART_OVERSAMPLING_16;
168    mb_data->uart->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
169    mb_data->uart->Init.ClockPrescaler = UART_PRESCALER_DIV1;
[22]170    mb_data->uart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_SWAP_INIT;
171        mb_data->uart->AdvancedInit.Swap = UART_ADVFEATURE_SWAP_ENABLE;
[20]172   
[22]173    // Init änderungen
[20]174
175    // Baudrate
176    mb_data->uart->Init.BaudRate   = baudrate;
177    // Parity Mode // Word length
178    if(parityMode == MODBUS_UART_PARITY_EVEN)
179    {
180       mb_data->uart->Init.Parity = UART_PARITY_EVEN;
181       mb_data->uart->Init.WordLength = UART_WORDLENGTH_9B;
182    } 
183    else if(parityMode == MODBUS_UART_PARITY_ODD)
184    {
185       mb_data->uart->Init.Parity = UART_PARITY_ODD;
186       mb_data->uart->Init.WordLength = UART_WORDLENGTH_9B;
187    }
188    else
189    {
190       mb_data->uart->Init.Parity = UART_PARITY_NONE;
191       mb_data->uart->Init.WordLength = UART_WORDLENGTH_8B;
192    }
193    // Stopbits
194    if (stopBits == 1)
195    { 
196      mb_data->uart->Init.StopBits = UART_STOPBITS_1;
197    }
198    else
199    {
200      mb_data->uart->Init.StopBits = UART_STOPBITS_2;
201    }
202    // Init
[22]203   // if (RS485_ModbusEx_Init(mb_data->uart, UART_DE_POLARITY_HIGH, 0, 0,TIMEOUT_FRAME_COMPLETE*nrOfBitsPerChar) != HAL_OK)
204   // {
205   //   Error_Handler();
206   // }
207   // if (HAL_UARTEx_DisableFifoMode(mb_data->uart) != HAL_OK)
208   // {
209   //   Error_Handler();
210   // }
211        uint32_t fixedDelayInBitDurations = (FAST_BAUDRATE_INTERFRAME_DELAY_us * baudrate) / 1000000UL + 1UL;
212//      HAL_UART_EnableReceiverTimeout( usart);
213//      HAL_UART_ReceiverTimeout_Config(usart,  fixedDelayInBitDurations);
[20]214
[22]215    if(HAL_UARTEx_ReceiveToIdle_DMA(mb_data->uart, mb_data->rx_buffer, RXBUFFERSIZE) != HAL_OK)
[20]216    {
217      printf("uart error \n\r");
218      while(1)
219      {
220      }     
221    }   
222  }
223
224
225
[22]226void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
[20]227{
[22]228  if (huart->ErrorCode == HAL_UART_ERROR_RTO)
[20]229  {
[22]230    modbusData.mb_rx_frame_complete = 1;
231    modbusData.setRxLed = true;
232        modbusData.rx_head= 8;
233        printf("MB RTO Event! \n\r");
[20]234  }
235
[22]236  if(HAL_UARTEx_ReceiveToIdle_DMA(huart, huart->pRxBuffPtr, RXBUFFERSIZE) != HAL_OK)
237   {
238     printf("uart error \n\r");
239  //   while(1)
240  //   {
241  //   }     
242   }   
243 
[20]244}
245
[22]246void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
[20]247{
[22]248  printf("MB rxEvent!RX=%d \n\r",Size);
249  modbusData.setRxLed = true;
[20]250
[22]251  modbusData.mb_rx_frame_complete = 1;
252  modbusData.rx_head= Size +1;
[20]253
[22]254  if(HAL_UARTEx_ReceiveToIdle_DMA(huart, huart->pRxBuffPtr, RXBUFFERSIZE) != HAL_OK)
255   {
256     printf("uart error \n\r");
257  //   while(1)
258  //   {
259  //   }     
260   }   
261 
[20]262
263}
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285  void mbSend(modbus_t * mb_data )
286  {   
287    mb_data->current_query = MB_QUERY_SEND_DATA;
288    HAL_UART_Transmit_IT(mb_data->uart, mb_data->tx_buffer, mb_data->tx_head);
289  }
290
291  void mbClearTxBuffer(modbus_t * mb_data)
292  {
293    mb_data->tx_head = 0;
294  }
295
296
297
298  // Compute the MODBUS RTU CRC
299  uint16_t mbCrc16 ( uint8_t *buf, uint32_t len)
300  {
301    uint16_t crc = 0xFFFF;
302
303    for (uint32_t pos = 0; pos < len; pos++) 
304    {
305      crc ^= (uint16_t)buf[pos];          // XOR byte into least sig. byte of crc
306   
307      for (int i = 8; i != 0; i--) 
308      {    // Loop over each bit
309        if ((crc & 0x0001) != 0) 
310        {      // If the LSB is set
311                crc >>= 1;                    // Shift right and XOR 0xA001
312                crc ^= 0xA001;
313        }
314        else                            // Else LSB is not set
315        {
316                crc >>= 1;                    // Just shift right
317        }
318      }
319    }                                   
320 
321    // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
322    return crc; 
323  }
324
325  /* If CRC is correct returns msg_length else returns INVALID_CRC */
326  int mbCheckCrc16( uint8_t *msg, const int msg_length) 
327  {
328    int ret;
329    uint16_t crc_calc;
330    uint16_t crc_received;
331
332    crc_calc = mbCrc16(msg, msg_length - 2);
333    crc_received = (msg[msg_length - 1] << 8) | msg[msg_length - 2];
334
335    // Check CRC of msg
336    if (crc_calc == crc_received) {
337            ret = msg_length;
338    } else {
339            ret = INVALID_CRC;
340    }
341    return ret;
342  }
343
344  uint32_t mbAppendCrc16(uint8_t * buffer, uint32_t tx_position)
345  {
346    uint16_t crc = mbCrc16( buffer , tx_position);
347 
348    uint8_t l_crc = (uint8_t) (crc & 0x00FF) ;
349    uint8_t h_crc = (uint8_t) (crc >> 8);
350    buffer[tx_position] = l_crc;
351    tx_position++;
352    buffer[tx_position] = h_crc; 
353    tx_position++;
354    return tx_position; 
355  }
356
357  /************************************************************************************************************
358  Function: mb_get_frame_complete
359  Purpose:  Rckabe ob Frame komplett empfangen wurde
360  *************************************************************************************************************/
361  bool mbGetFrameComplete(modbus_t * mb_data)
362  {
363          return mb_data->mb_rx_frame_complete;
364  }
365
366  void mbClearRxFrame(modbus_t * mb_data)
367  {
368    // Wieder bei 0 im buffer anfangen
369    mb_data->rx_head = 0;
370 
371    // keine Daten mehr vorhanden
372    mb_data->mb_rx_frame_complete=false; 
373  }
374
375
376  // --------------------- SLAVE FUNCTIONS ---------------------------------------     
377
378#define SEND_TO_SLAVES_BUFFER_COUNT 1000
379//static TASK_MODBUS_MASTER_Message_t xMessage[255];
380//static TASK_MODBUS_MASTER_Message_t *pxMessage;
381static bword_t values[SEND_TO_SLAVES_BUFFER_COUNT];
382static uint32_t y;
383static uint32_t z;
384
385  uint32_t mbSlaveCheckModbusRtuQuery(modbus_t * mb_data)
386  {
387    uint32_t message_lengh;
388    uint8_t *modbus_rx_message;
389    modbus_rx_message = mb_data->rx_buffer;
390    message_lengh= mb_data->rx_head;
391    uint32_t slave_adress;
392    slave_adress = modbus_rx_message[0];
393 
394    if (message_lengh < 5) //Mindestens 5 Zeichen (Slave Adress + Function Code + 2x CRC
395    {
396      mbClearRxFrame(mb_data);
397      return 0;
398    } 
399 
400    // Prfe CRC
401    if (mbCheckCrc16(modbus_rx_message,message_lengh) == INVALID_CRC)
402    {
403      mbClearRxFrame(mb_data);
404      return 0;
405    }
406
407    if  (slave_adress == MODBUS_BROADCAST_ADDRESS)
408    {
409
410      return  RESPOND_TO_QUERY; 
411    } 
412    /* auf richtige Slave Adresse checken ansonsten nicht antworten*/
413    else if (slave_adress == sys_data.s.parameter.slave_address)
414    {
415      return RESPOND_TO_QUERY;
416    }
417   
418    mbClearRxFrame(mb_data);
419    return 0;
420  }
421
422  void mbSlaveProcessRtuQuery(modbus_t * mb_data)
423  {
424    uint32_t tx_position=0; //die _Nchste_ Position in der Zeichen eingefgt werden mssen
425    uint8_t *modbus_rx_message;
426    modbus_rx_message = &mb_data->rx_buffer[0];
427
428    //Vorbereiten auf neues senden
429    mbClearTxBuffer(mb_data);
430 
431    //mb_data->tx_buffer[0] = sys_data.s.vmGreenview.s.lb_slave_adress;
432    mb_data->tx_buffer[0] = *modbus_rx_message;
433    tx_position++;
434    tx_position = mbSlaveProcessPdu(mb_data->tx_buffer , modbus_rx_message,tx_position, *modbus_rx_message);
435 
436    tx_position = mbAppendCrc16(mb_data->tx_buffer ,tx_position);       
437    mb_data->tx_head=tx_position;
438    mbSend(mb_data);   
439    mbClearRxFrame(mb_data);   
440  }
441
442  uint32_t mbSlaveProcessPdu (uint8_t* response_string,    uint8_t * msg,    uint32_t tx_position,     uint8_t deviceID)
443  {
444    uint32_t function_code;
445    uint32_t ret;
446   
447    function_code = msg[OFFSET_FUNCTION_CODE];
448
449    switch (function_code)
450    {
451      case FC_READ_HOLDING_REGISTERS:
452      ret= mbSlaveReadHoldingRegisters(response_string, msg,tx_position, deviceID);
453      break;
454   
455      case FC_WRITE_SINGLE_REGISTER:
456      ret = mbSlaveWriteSingleRegister(response_string, msg,tx_position, deviceID);
457      break;
458   
459      case FC_WRITE_MULTIPLE_REGISTER:
460      ret=mbSlaveWriteMultipleRegisters(response_string, msg,tx_position, deviceID);
461      break;
462   
463      default:
464      ret=mbSlaveResponseException(response_string,function_code,ILLEGAL_FUNCTION,tx_position);
465      break;
466    }
467 
468    return ret;
469  }
470
471
472  uint32_t mbSlaveReadHoldingRegisters( uint8_t * response_string, uint8_t *msg, uint32_t tx_position, uint8_t deviceID)
473  {
474    uint32_t start_adress;
475    uint32_t adress;
476    uint32_t number_of_registers;
477
478    /*stimmt die device ID mit der eigenen berein*/
479    if((deviceID != sys_data.s.parameter.slave_address) && (deviceID != 0))
480    {
481       return mbSlaveResponseException(response_string,FC_WRITE_SINGLE_REGISTER,GATEWAY_PROBLEM_TARGET,tx_position);
482    }
483
484    start_adress = (msg[OFFSET_START_ADRESS_HI] << 8) + msg[OFFSET_START_ADRESS_LO];
485    number_of_registers = ( msg[OFFSET_NO_OF_REGISTERS_HI] << 8) + msg[OFFSET_NO_OF_REGISTERS_LO];
486 
487    if ((number_of_registers < MIN_NUMBER_OF_REGISTERS_FC3) || (number_of_registers > MAX_NUMBER_OF_REGISTERS_FC3) )
488    {
489      return mbSlaveResponseException(response_string,FC_READ_HOLDING_REGISTERS,ILLEGAL_DATA_VALUE,tx_position);
490    }
491 
492    if (start_adress+number_of_registers-1 > MAX_ADRESS) 
493    {
494      return mbSlaveResponseException(response_string, FC_READ_HOLDING_REGISTERS,ILLEGAL_DATA_ADDRESS,tx_position);
495    }   
496
497    response_string[tx_position] = FC_READ_HOLDING_REGISTERS;                                                                                   // FUNCTION CODE
498    tx_position++;
499    response_string[tx_position] = number_of_registers * 2;                                                                                             // Bytes
500    tx_position++;
501
502    for(adress=start_adress;adress < (start_adress + number_of_registers);adress++)
503    {
504      /*Daten aus dem Speicher senden*/
505      response_string[tx_position] = sys_data.mb[adress].b[1];
506      tx_position++;
507      response_string[tx_position] = sys_data.mb[adress].b[0];
508      tx_position++;
509    }
510 
511    return tx_position;
512  }
513
514
515  uint32_t mbSlaveWriteMultipleRegisters(uint8_t * response_string, uint8_t *msg, uint32_t tx_position, uint32_t deviceID)
516  {
517   
518    uint32_t start_adress;
519    uint32_t number_of_registers;
520    uint32_t adress;
521    uint32_t offset;
522
523    /*stimmt die device ID mit der eigenen berein*/
524    if((deviceID != sys_data.s.parameter.slave_address) && (deviceID != 0))
525    {
526       return mbSlaveResponseException(response_string,FC_WRITE_SINGLE_REGISTER,GATEWAY_PROBLEM_TARGET,tx_position);
527    }
528
529    start_adress = (msg[OFFSET_START_ADRESS_HI] << 8) + msg[OFFSET_START_ADRESS_LO];
530    number_of_registers = ( msg[OFFSET_NO_OF_REGISTERS_HI] << 8) + msg[OFFSET_NO_OF_REGISTERS_LO];
531    offset=7;
532
533    if ((number_of_registers < MIN_NUMBER_OF_REGISTERS_FC16) || (number_of_registers > MAX_NUMBER_OF_REGISTERS_FC16) )
534    {
535      return mbSlaveResponseException(response_string, FC_WRITE_MULTIPLE_REGISTER,ILLEGAL_DATA_VALUE,tx_position);
536    }
537
538    if (start_adress+number_of_registers-1 > MAX_ADRESS) 
539    {
540      return mbSlaveResponseException(response_string, FC_WRITE_MULTIPLE_REGISTER,ILLEGAL_DATA_ADDRESS,tx_position);
541    }
542   
543    /*Daten in Gertespeicher schreiben*/
544    for(adress=start_adress;adress < (start_adress + number_of_registers);adress++)
545    { 
546      sys_data.mb[adress].b[1] = msg[offset];
547      sys_data.mb[adress].b[0] = msg[offset+1];
548      offset+=2;
549    }
550
551    response_string[tx_position] = FC_WRITE_MULTIPLE_REGISTER; // FUNCTION CODE - 1 byte
552    tx_position++;
553    response_string[tx_position] = start_adress >> 8; 
554    tx_position++;
555    response_string[tx_position] = (uint8_t ) ( start_adress  & 0x00FF); // start adresse 2 byte
556    tx_position++;
557    response_string[tx_position] = number_of_registers >> 8; 
558    tx_position++;
559    response_string[tx_position] = (uint8_t ) ( number_of_registers  & 0x00FF); // Anzahl Register 2 byte
560    tx_position++;
561    return tx_position;
562  }
563
564
565  uint32_t mbSlaveWriteSingleRegister(uint8_t * response_string,uint8_t *msg,uint32_t tx_position, uint32_t deviceID)
566  {
567 
568    uint32_t adress;
569
570    /*stimmt die device ID mit der eigenen berein*/
571    if((deviceID != sys_data.s.parameter.slave_address) && (deviceID != 0))
572    {
573       return mbSlaveResponseException(response_string,FC_WRITE_SINGLE_REGISTER,GATEWAY_PROBLEM_TARGET,tx_position);
574    }
575
576    adress = (msg[2] << 8) + msg[3];
577
578    if (adress >  MAX_ADRESS) 
579    {
580      return mbSlaveResponseException(response_string,FC_WRITE_SINGLE_REGISTER,ILLEGAL_DATA_ADDRESS,tx_position);
581    }   
582
583    /*schreibe Daten in eigenen Speicher*/
584    sys_data.mb[adress].b[1] = msg[4];
585    sys_data.mb[adress].b[0] = msg[5];
586
587    response_string[tx_position]= FC_WRITE_SINGLE_REGISTER; // FUNCTION CODE
588    tx_position++;
589    response_string[tx_position]= adress >> 8; 
590    tx_position++;
591    response_string[tx_position]= (uint8_t ) ( adress  & 0x00FF);
592   
593    tx_position++;
594    response_string[tx_position]= msg[4]; 
595    tx_position++;
596    response_string[tx_position]= msg[5];
597    tx_position++;
598
599    return tx_position;
600  }
601
602
603  uint32_t mbSlaveResponseException(uint8_t* response_string, uint32_t function_code, uint32_t exception_code,uint32_t tx_position ) 
604  {
605    function_code += 0x80;
606    response_string[tx_position] = function_code; //  FUNCTION CODE
607    tx_position++;
608    response_string[tx_position] = exception_code; //
609    tx_position++;
610    return tx_position;
611  }
612
613
614  //---------------------------- UNKNOWN -----------------------------------------
615  //-                                                                            -
616  //------------------------------------------------------------------------------
617
618#endif
619       
Note: See TracBrowser for help on using the repository browser.