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

Last change on this file since 26 was 26, checked in by f.jahn, 7 weeks ago
  • Bug in ADC Kalibrierung (STM32 ADC Strom) behoben
  • DMA Buffer für ADC 1 und ADC wird vor Überschreibung während bearbeitung geschützt, indem Datenübertragung nur einmalig erfolgt und erst nach Auswertung wieder gestartet wird
  • RS485Modbus: Timeout Zeit wird für Baudraten >19200 korrekt berechnet
  • Hardware ID geändert
  • Separates Register für "Batterie Empty detection mode" auf Adresse 92 angelegt
File size: 20.0 KB
Line 
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 --------------------------------------------
69  extern  modbus_t modbusData;
70  extern  sys_data_t sys_data;
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
112    // Berechne Anzahl der Bits per Char
113    numberOfBitsPerChar = NUMBER_OF_STARTBITS + NUMBER_OF_DATABITS + stopBits;
114    if ((parityMode == MODBUS_UART_PARITY_EVEN) || (parityMode == MODBUS_UART_PARITY_ODD)) 
115    {
116      numberOfBitsPerChar +=1; 
117    }
118     
119    mbUartInit(mb_data,usart, baudrate, parityMode, stopBits, numberOfBitsPerChar);
120
121    // Datenstrukturen zurcksetzen
122    mb_data->last_query_function_code         =   0;
123    mb_data->last_query_tcp_id.w              =   0;
124    mb_data->last_query_number_of_register.=   0;
125    mb_data->current_query                    =   MB_QUERY_NOTHING;
126    mb_data->last_query_slave_adress          =   0;
127    mb_data->last_query_start_adress.w        =   0;
128    mb_data->last_query_timeout               =   false;
129  }
130
131  /*
132    *
133    * @brief  Diese Funktion Initialisert die Modbus UART Hardware
134    *
135    * @param  mb_data : Datenstruktur zur Aufnahme aller Daten
136    * @param  usart : UART Modul, z.B. USART1
137    * @param  baudrate : UART BAUD
138    * @param  parityMmode : Parity, mglich ist:
139              UART_PARITY_ODD, UART_PARITY_EVEN, UART_PARITY_NONE.
140              Default ist lt. Modbus Standart EVEN
141    * @param  stopBits : Anzahl der Stop Bits, lt Modbus Standart
142    *         2 Stop Bits bei Parity None, ansonsten 2 Stop Bits
143    * @retval None   
144  */
145  void mbUartInit(modbus_t * mb_data,UART_HandleTypeDef * usart, uint32_t baudrate,  uint32_t parityMode,  uint32_t stopBits , uint32_t nrOfBitsPerChar)
146  {
147    //--- Uart Init ------------------------------------------------------------
148    mb_data->uart      = usart;
149   
150    // Baudrate
151    mb_data->uart->Init.BaudRate   = baudrate;
152
153    // Parity Mode // Word length
154    if(parityMode == MODBUS_UART_PARITY_EVEN)
155    {
156       mb_data->uart->Init.Parity = UART_PARITY_EVEN;
157       mb_data->uart->Init.WordLength = UART_WORDLENGTH_9B;
158    } 
159    else if(parityMode == MODBUS_UART_PARITY_ODD)
160    {
161       mb_data->uart->Init.Parity = UART_PARITY_ODD;
162       mb_data->uart->Init.WordLength = UART_WORDLENGTH_9B;
163    }
164    else
165    {
166       mb_data->uart->Init.Parity = UART_PARITY_NONE;
167       mb_data->uart->Init.WordLength = UART_WORDLENGTH_8B;
168    }
169
170    // Stopbits
171    if (stopBits == 1)
172    { 
173      mb_data->uart->Init.StopBits = UART_STOPBITS_1;
174    }
175    else
176    {
177      mb_data->uart->Init.StopBits = UART_STOPBITS_2;
178    }
179
180        if (HAL_UART_Init(mb_data->uart) != HAL_OK)
181        {
182          Error_Handler();
183        }
184       
185       
186        HAL_UART_EnableReceiverTimeout( usart);
187        if (baudrate <= 19200)
188        {
189          HAL_UART_ReceiverTimeout_Config(usart,  3.5 * nrOfBitsPerChar);
190        }
191        else
192        {
193      uint32_t fixedDelayInBitDurations = (FAST_BAUDRATE_INTERFRAME_DELAY_us * baudrate) / 1000000UL + 1UL;
194          HAL_UART_ReceiverTimeout_Config(usart, fixedDelayInBitDurations);
195        }
196
197
198        SET_BIT(usart->Instance->CR1, USART_CR1_RTOIE); 
199
200
201    if(HAL_UART_Receive_DMA(mb_data->uart, mb_data->rx_buffer, RXBUFFERSIZE) != HAL_OK)
202    {
203      printf("uart error \n\r");
204      while(1)
205      {
206      }     
207    }   
208  }
209
210
211
212void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
213{
214    modbusData.mb_rx_frame_complete = 1;
215    modbusData.setRxLed = false;
216        modbusData.rx_head = huart->RxXferSize - __HAL_DMA_GET_COUNTER(huart->hdmarx);
217       
218
219  if (huart->ErrorCode == HAL_UART_ERROR_RTO)
220  {
221
222        // printf("MB RTO Event! \n\r");
223        // Kein Fehler, normale Funktion
224  }
225  if (huart->ErrorCode == HAL_UART_ERROR_FE)
226  {
227        printf("MB FE Error! \n\r");
228  }
229 
230  if (huart->ErrorCode == HAL_UART_ERROR_PE)
231  {
232        printf("MB PE Error! \n\r");
233  }
234
235  if (huart->ErrorCode == HAL_UART_ERROR_NE)
236  {
237        printf("MB NE Error! \n\r");
238  }
239
240  if (huart->ErrorCode == HAL_UART_ERROR_DMA)
241  {
242        printf("MB DMA Error! \n\r");
243  }
244
245  if (huart->ErrorCode == HAL_UART_ERROR_DMA)
246  {
247        printf("MB DMA Error! \n\r");
248  }
249
250  if (huart->ErrorCode == HAL_UART_ERROR_ORE)
251  {
252        printf("MB ORE Error! \n\r");
253  }
254
255
256 
257  if(HAL_UART_Receive_DMA(huart, huart->pRxBuffPtr, RXBUFFERSIZE) != HAL_OK)
258   {
259     printf("Uart Error bei neustart nach Fehler \n\r");
260  //   while(1)
261  //   {
262  //   }     
263   }   
264 
265}
266
267//void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
268//{
269//  //printf("MB rxEvent!RX=%d \n\r",Size);
270//  modbusData.setRxLed = true;
271
272//  modbusData.mb_rx_frame_complete = 1;
273//  modbusData.rx_head= Size +1;
274
275//  if(HAL_UART_Receive_DMA(huart, huart->pRxBuffPtr, RXBUFFERSIZE) != HAL_OK)
276//   {
277//     printf("uart error \n\r");
278//  //   while(1)
279//  //   {
280//  //   }     
281//   }   
282 
283
284//}
285
286void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
287{
288  //printf("uart complete \n\r");
289  modbusData.current_query = MB_QUERY_NOTHING;
290
291}
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313  void mbSend(modbus_t * mb_data )
314  {   
315    mb_data->current_query = MB_QUERY_SEND_DATA;
316    HAL_UART_Transmit_DMA(mb_data->uart, mb_data->tx_buffer, mb_data->tx_head);
317  }
318
319  void mbClearTxBuffer(modbus_t * mb_data)
320  {
321    mb_data->tx_head = 0;
322  }
323
324
325
326  // Compute the MODBUS RTU CRC
327  uint16_t mbCrc16 ( uint8_t *buf, uint32_t len)
328  {
329    uint16_t crc = 0xFFFF;
330
331    for (uint32_t pos = 0; pos < len; pos++) 
332    {
333      crc ^= (uint16_t)buf[pos];          // XOR byte into least sig. byte of crc
334   
335      for (int i = 8; i != 0; i--) 
336      {    // Loop over each bit
337        if ((crc & 0x0001) != 0) 
338        {      // If the LSB is set
339                crc >>= 1;                    // Shift right and XOR 0xA001
340                crc ^= 0xA001;
341        }
342        else                            // Else LSB is not set
343        {
344                crc >>= 1;                    // Just shift right
345        }
346      }
347    }                                   
348 
349    // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
350    return crc; 
351  }
352
353  /* If CRC is correct returns msg_length else returns INVALID_CRC */
354  int mbCheckCrc16( uint8_t *msg, const int msg_length) 
355  {
356    int ret;
357    uint16_t crc_calc;
358    uint16_t crc_received;
359
360    crc_calc = mbCrc16(msg, msg_length - 2);
361    crc_received = (msg[msg_length - 1] << 8) | msg[msg_length - 2];
362
363    // Check CRC of msg
364    if (crc_calc == crc_received) {
365            ret = msg_length;
366    } else {
367            ret = INVALID_CRC;
368    }
369    return ret;
370  }
371
372  uint32_t mbAppendCrc16(uint8_t * buffer, uint32_t tx_position)
373  {
374    uint16_t crc = mbCrc16( buffer , tx_position);
375 
376    uint8_t l_crc = (uint8_t) (crc & 0x00FF) ;
377    uint8_t h_crc = (uint8_t) (crc >> 8);
378    buffer[tx_position] = l_crc;
379    tx_position++;
380    buffer[tx_position] = h_crc; 
381    tx_position++;
382    return tx_position; 
383  }
384
385  /************************************************************************************************************
386  Function: mb_get_frame_complete
387  Purpose:  Rckabe ob Frame komplett empfangen wurde
388  *************************************************************************************************************/
389  bool mbGetFrameComplete(modbus_t * mb_data)
390  {
391          return mb_data->mb_rx_frame_complete;
392  }
393
394  void mbClearRxFrame(modbus_t * mb_data)
395  {
396    // Wieder bei 0 im buffer anfangen
397    mb_data->rx_head = 0;
398 
399    // keine Daten mehr vorhanden
400    mb_data->mb_rx_frame_complete=false; 
401  }
402
403
404  // --------------------- SLAVE FUNCTIONS ---------------------------------------     
405
406#define SEND_TO_SLAVES_BUFFER_COUNT 1000
407//static TASK_MODBUS_MASTER_Message_t xMessage[255];
408//static TASK_MODBUS_MASTER_Message_t *pxMessage;
409static bword_t values[SEND_TO_SLAVES_BUFFER_COUNT];
410static uint32_t y;
411static uint32_t z;
412
413  uint32_t mbSlaveCheckModbusRtuQuery(modbus_t * mb_data)
414  {
415    uint32_t message_lengh;
416    uint8_t *modbus_rx_message;
417    modbus_rx_message = mb_data->rx_buffer;
418    message_lengh= mb_data->rx_head;
419    uint32_t slave_adress;
420    slave_adress = modbus_rx_message[0];
421 
422    if (message_lengh < 5) //Mindestens 5 Zeichen (Slave Adress + Function Code + 2x CRC
423    {
424      mbClearRxFrame(mb_data);
425      return 0;
426    } 
427 
428    // Prfe CRC
429    if (mbCheckCrc16(modbus_rx_message,message_lengh) == INVALID_CRC)
430    {
431      mbClearRxFrame(mb_data);
432      return 0;
433    }
434
435    if  (slave_adress == MODBUS_BROADCAST_ADDRESS)
436    {
437
438      return  RESPOND_TO_QUERY; 
439    } 
440    /* auf richtige Slave Adresse checken ansonsten nicht antworten*/
441    else if (slave_adress == sys_data.s.parameter.slave_address)
442    {
443      return RESPOND_TO_QUERY;
444    }
445   
446    mbClearRxFrame(mb_data);
447    return 0;
448  }
449
450  void mbSlaveProcessRtuQuery(modbus_t * mb_data)
451  {
452    uint32_t tx_position=0; //die _Nchste_ Position in der Zeichen eingefgt werden mssen
453    uint8_t *modbus_rx_message;
454    modbus_rx_message = &mb_data->rx_buffer[0];
455
456    //Vorbereiten auf neues senden
457    mbClearTxBuffer(mb_data);
458 
459    //mb_data->tx_buffer[0] = sys_data.s.vmGreenview.s.lb_slave_adress;
460    mb_data->tx_buffer[0] = *modbus_rx_message;
461    tx_position++;
462    tx_position = mbSlaveProcessPdu(mb_data->tx_buffer , modbus_rx_message,tx_position, *modbus_rx_message);
463 
464    tx_position = mbAppendCrc16(mb_data->tx_buffer ,tx_position);       
465    mb_data->tx_head=tx_position;
466    mbSend(mb_data);   
467    mbClearRxFrame(mb_data);   
468  }
469
470  uint32_t mbSlaveProcessPdu (uint8_t* response_string,    uint8_t * msg,    uint32_t tx_position,     uint8_t deviceID)
471  {
472    uint32_t function_code;
473    uint32_t ret;
474   
475    function_code = msg[OFFSET_FUNCTION_CODE];
476
477    switch (function_code)
478    {
479      case FC_READ_HOLDING_REGISTERS:
480      ret= mbSlaveReadHoldingRegisters(response_string, msg,tx_position, deviceID);
481      break;
482   
483      case FC_WRITE_SINGLE_REGISTER:
484      ret = mbSlaveWriteSingleRegister(response_string, msg,tx_position, deviceID);
485      break;
486   
487      case FC_WRITE_MULTIPLE_REGISTER:
488      ret=mbSlaveWriteMultipleRegisters(response_string, msg,tx_position, deviceID);
489      break;
490   
491      default:
492      ret=mbSlaveResponseException(response_string,function_code,ILLEGAL_FUNCTION,tx_position);
493      break;
494    }
495 
496    return ret;
497  }
498
499
500  uint32_t mbSlaveReadHoldingRegisters( uint8_t * response_string, uint8_t *msg, uint32_t tx_position, uint8_t deviceID)
501  {
502    uint32_t start_adress;
503    uint32_t adress;
504    uint32_t number_of_registers;
505
506    /*stimmt die device ID mit der eigenen berein*/
507    if((deviceID != sys_data.s.parameter.slave_address) && (deviceID != 0))
508    {
509       return mbSlaveResponseException(response_string,FC_WRITE_SINGLE_REGISTER,GATEWAY_PROBLEM_TARGET,tx_position);
510    }
511
512    start_adress = (msg[OFFSET_START_ADRESS_HI] << 8) + msg[OFFSET_START_ADRESS_LO];
513    number_of_registers = ( msg[OFFSET_NO_OF_REGISTERS_HI] << 8) + msg[OFFSET_NO_OF_REGISTERS_LO];
514 
515    if ((number_of_registers < MIN_NUMBER_OF_REGISTERS_FC3) || (number_of_registers > MAX_NUMBER_OF_REGISTERS_FC3) )
516    {
517      return mbSlaveResponseException(response_string,FC_READ_HOLDING_REGISTERS,ILLEGAL_DATA_VALUE,tx_position);
518    }
519 
520    if (start_adress+number_of_registers-1 > MAX_ADRESS) 
521    {
522      return mbSlaveResponseException(response_string, FC_READ_HOLDING_REGISTERS,ILLEGAL_DATA_ADDRESS,tx_position);
523    }   
524
525    response_string[tx_position] = FC_READ_HOLDING_REGISTERS;                                                                                   // FUNCTION CODE
526    tx_position++;
527    response_string[tx_position] = number_of_registers * 2;                                                                                             // Bytes
528    tx_position++;
529
530    for(adress=start_adress;adress < (start_adress + number_of_registers);adress++)
531    {
532      /*Daten aus dem Speicher senden*/
533      response_string[tx_position] = sys_data.mb[adress].b[1];
534      tx_position++;
535      response_string[tx_position] = sys_data.mb[adress].b[0];
536      tx_position++;
537    }
538 
539    return tx_position;
540  }
541
542
543  uint32_t mbSlaveWriteMultipleRegisters(uint8_t * response_string, uint8_t *msg, uint32_t tx_position, uint32_t deviceID)
544  {
545   
546    uint32_t start_adress;
547    uint32_t number_of_registers;
548    uint32_t adress;
549    uint32_t offset;
550
551    /*stimmt die device ID mit der eigenen berein*/
552    if((deviceID != sys_data.s.parameter.slave_address) && (deviceID != 0))
553    {
554       return mbSlaveResponseException(response_string,FC_WRITE_SINGLE_REGISTER,GATEWAY_PROBLEM_TARGET,tx_position);
555    }
556
557    start_adress = (msg[OFFSET_START_ADRESS_HI] << 8) + msg[OFFSET_START_ADRESS_LO];
558    number_of_registers = ( msg[OFFSET_NO_OF_REGISTERS_HI] << 8) + msg[OFFSET_NO_OF_REGISTERS_LO];
559    offset=7;
560
561    if ((number_of_registers < MIN_NUMBER_OF_REGISTERS_FC16) || (number_of_registers > MAX_NUMBER_OF_REGISTERS_FC16) )
562    {
563      return mbSlaveResponseException(response_string, FC_WRITE_MULTIPLE_REGISTER,ILLEGAL_DATA_VALUE,tx_position);
564    }
565
566    if (start_adress+number_of_registers-1 > MAX_ADRESS) 
567    {
568      return mbSlaveResponseException(response_string, FC_WRITE_MULTIPLE_REGISTER,ILLEGAL_DATA_ADDRESS,tx_position);
569    }
570   
571    /*Daten in Gertespeicher schreiben*/
572    for(adress=start_adress;adress < (start_adress + number_of_registers);adress++)
573    { 
574      sys_data.mb[adress].b[1] = msg[offset];
575      sys_data.mb[adress].b[0] = msg[offset+1];
576      offset+=2;
577    }
578
579    response_string[tx_position] = FC_WRITE_MULTIPLE_REGISTER; // FUNCTION CODE - 1 byte
580    tx_position++;
581    response_string[tx_position] = start_adress >> 8; 
582    tx_position++;
583    response_string[tx_position] = (uint8_t ) ( start_adress  & 0x00FF); // start adresse 2 byte
584    tx_position++;
585    response_string[tx_position] = number_of_registers >> 8; 
586    tx_position++;
587    response_string[tx_position] = (uint8_t ) ( number_of_registers  & 0x00FF); // Anzahl Register 2 byte
588    tx_position++;
589    return tx_position;
590  }
591
592
593  uint32_t mbSlaveWriteSingleRegister(uint8_t * response_string,uint8_t *msg,uint32_t tx_position, uint32_t deviceID)
594  {
595 
596    uint32_t adress;
597
598    /*stimmt die device ID mit der eigenen berein*/
599    if((deviceID != sys_data.s.parameter.slave_address) && (deviceID != 0))
600    {
601       return mbSlaveResponseException(response_string,FC_WRITE_SINGLE_REGISTER,GATEWAY_PROBLEM_TARGET,tx_position);
602    }
603
604    adress = (msg[2] << 8) + msg[3];
605
606    if (adress >  MAX_ADRESS) 
607    {
608      return mbSlaveResponseException(response_string,FC_WRITE_SINGLE_REGISTER,ILLEGAL_DATA_ADDRESS,tx_position);
609    }   
610
611    /*schreibe Daten in eigenen Speicher*/
612    sys_data.mb[adress].b[1] = msg[4];
613    sys_data.mb[adress].b[0] = msg[5];
614
615    response_string[tx_position]= FC_WRITE_SINGLE_REGISTER; // FUNCTION CODE
616    tx_position++;
617    response_string[tx_position]= adress >> 8; 
618    tx_position++;
619    response_string[tx_position]= (uint8_t ) ( adress  & 0x00FF);
620   
621    tx_position++;
622    response_string[tx_position]= msg[4]; 
623    tx_position++;
624    response_string[tx_position]= msg[5];
625    tx_position++;
626
627    return tx_position;
628  }
629
630
631  uint32_t mbSlaveResponseException(uint8_t* response_string, uint32_t function_code, uint32_t exception_code,uint32_t tx_position ) 
632  {
633    function_code += 0x80;
634    response_string[tx_position] = function_code; //  FUNCTION CODE
635    tx_position++;
636    response_string[tx_position] = exception_code; //
637    tx_position++;
638    return tx_position;
639  }
640
641
642  //---------------------------- UNKNOWN -----------------------------------------
643  //-                                                                            -
644  //------------------------------------------------------------------------------
645
646#endif
647       
Note: See TracBrowser for help on using the repository browser.