Advertisement
Guest User

Modbus 8 bit cpu

a guest
Nov 21st, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.28 KB | None | 0 0
  1. #include <SI_EFM8UB2_Register_Enums.h>
  2.  
  3. #define UART_BUFFERSIZE 64
  4. uint8_t UART_Buffer[UART_BUFFERSIZE];
  5. extern uint8_t UART_Buffer_Size;
  6. uint8_t UART_Input_First;
  7. uint8_t UART_Output_First;
  8. extern uint8_t TX_Ready;
  9. extern char Byte;
  10.  
  11. bool CrC_is_Error = false;
  12.  
  13. /* Supported function codes */
  14. #define _READ_GPIO_REGISTERS 0x01
  15. #define _WRITE_GPIO_REGISTERS 0x05
  16.  
  17. char Chip_Address;
  18.  
  19. // Port0 1-7 inputs
  20. SI_SBIT(IN1, SFR_P0, 1);                // IN1 = '0' means on
  21. SI_SBIT(IN2, SFR_P0, 2);
  22. SI_SBIT(IN3, SFR_P0, 3);
  23. SI_SBIT(IN4, SFR_P0, 4);
  24. SI_SBIT(IN5, SFR_P0, 5);
  25. SI_SBIT(IN6, SFR_P0, 6);
  26. SI_SBIT(IN7, SFR_P0, 7);
  27. // Port1 1-7 inputs
  28. SI_SBIT(IN1, SFR_P1, 1);                // IN1 = '0' means on
  29. SI_SBIT(IN2, SFR_P1, 2);
  30. SI_SBIT(IN3, SFR_P1, 3);
  31. SI_SBIT(IN4, SFR_P1, 4);
  32. SI_SBIT(IN5, SFR_P1, 5);
  33. SI_SBIT(IN6, SFR_P1, 6);
  34. SI_SBIT(IN7, SFR_P1, 7);
  35. // Port2 1-7 outputs
  36. SI_SBIT(OUT1, SFR_P2, 1);
  37. SI_SBIT(OUT2, SFR_P2, 2);
  38. SI_SBIT(OUT3, SFR_P2, 3);
  39. SI_SBIT(OUT4, SFR_P2, 4);
  40. SI_SBIT(OUT5, SFR_P2, 5);
  41. SI_SBIT(OUT6, SFR_P2, 6);
  42. SI_SBIT(OUT7, SFR_P2, 7);
  43. // Port3 1-7 outputs
  44. SI_SBIT(OUT1, SFR_P3, 1);
  45. SI_SBIT(OUT2, SFR_P3, 2);
  46. SI_SBIT(OUT3, SFR_P3, 3);
  47. SI_SBIT(OUT4, SFR_P3, 4);
  48. SI_SBIT(OUT5, SFR_P3, 5);
  49. SI_SBIT(OUT6, SFR_P3, 6);
  50. SI_SBIT(OUT7, SFR_P3, 7);
  51.  
  52. static void DO_Request_Message(){   // I have to do a requet message based on the things i do?
  53.     if(CrC_is_Error){
  54.         // CrC Error response message
  55.     }else{
  56.         // GPIO Status message
  57.     }
  58. }
  59. static void Check_GPIO_Status(uint8_t Data){
  60.     uint8_t GPIO_STATUS_Input_P0 = SFR_P0;  // I have to put the gpio statuses together to be able to send back to master on request.
  61.     uint8_t GPIO_STATUS_Input_P1 = SFR_P1;
  62.     uint8_t GPIO_STATUS_Output_P2 = SFR_P2;
  63.     uint8_t GPIO_STATUS_Output_P3 = SFR_P3;
  64.     uint8_t From_Where = Data[0] +1;
  65.     uint8_t How_Many = Data[1];
  66. }
  67.  
  68. static void Toggle_IO_Pins(uint8_t Data){       // Need to toggle the I/O pins based on the master request
  69.     //Data[0] tells us from where should i start to toggle the pins ( in theory )
  70.     //Data[1] tells us how many pins should i toggle ( in theory )
  71. }
  72. static int Check_Chip_Address(uint8_t Msg_Address){         // ADRESS BASED ON THE P0.1-P0.4 GPIOS
  73.     char Address1, Address2, Address3, Address4;            // This function is not okay.
  74.     Address1 = IN1;                                         // I have to read the input gpio statuses and match it with a 8 bit variable
  75.     Address2 = IN2;
  76.     Address3 = IN3;
  77.     Address4 = IN4;
  78.     Chip_Address = Address1;
  79.     Chip_Address += Address2;
  80.     Chip_Address += Address3;
  81.     Chip_Address += Address4;
  82.     if(Chip_Address == Msg_Address){
  83.         return 1;
  84.     }else{
  85.         return -1;
  86.     }
  87. }
  88.  
  89. static uint16_t Crc_Check(uint8_t *req, uint8_t req_length)
  90. {
  91.     uint8_t j;
  92.     uint16_t crc;
  93.     crc = 0xFFFF;
  94.     while (req_length--) {
  95.         crc = crc ^ *req++;
  96.         for (j = 0; j < 8; j++) {
  97.             if (crc & 0x0001)
  98.                 crc = (crc >> 1) ^ 0xA001;
  99.             else
  100.                 crc = crc >> 1;
  101.         }
  102.     }
  103.     return (crc << 8 | crc >> 8);
  104. }
  105.  
  106. static int check_integrity(uint8_t *msg, uint8_t msg_length)
  107. {
  108.     uint16_t crc_calculated;
  109.     uint16_t crc_received;
  110.     if (msg_length < 2)
  111.         return -1;
  112.     crc_calculated = Crc_Check(msg, msg_length - 2);
  113.     crc_received = (msg[msg_length - 2] << 8) | msg[msg_length - 1];
  114.  
  115.     /* Check CRC of msg */
  116.     if (crc_calculated == crc_received) {
  117.         return msg_length;
  118.     } else {
  119.         return -1;
  120.     }
  121. }
  122.  
  123. static void Check_Message(){
  124.     uint8_t Address,Code;
  125.     uint8_t Data[2];
  126.     uint8_t Crc[2];
  127.     int k = 0;
  128.     int i = 0;
  129.     // Get the whole message in separate variables for further analization
  130.     for(i = 0; i < UART_Input_First;i++){
  131.         if (i <= 2){
  132.             Address = UART_Buffer[i];
  133.         }
  134.         else if (i <= 4){
  135.             Code = UART_Buffer[i];
  136.         }
  137.         else if (i <= 8){
  138.             if(i <= 6){
  139.                 Data[0] = UART_Buffer[i];
  140.             }else{
  141.                 Data[1] = UART_Buffer[i];
  142.             }
  143.         }else{
  144.             Crc[k] = UART_Buffer[i];
  145.             k++;
  146.         }
  147.     }
  148.     // Checking the separated variables
  149.     if(Check_Chip_Address(Address) != -1){                  // Check if Message is ours.
  150.         if(check_integrity(Crc,UART_Buffer_Size) != -1){    // Check if no errors on crc
  151.             if(Code == _READ_GPIO_REGISTERS){
  152.                 /** MASTER WANTS TO READ THE GPIOS **/
  153.                 Check_GPIO_Status(Data);
  154.             }else if(Code == _WRITE_GPIO_REGISTERS){
  155.                 /** MASTER WANTS TO TOGGLE THE GPIOS **/
  156.                 Toggle_IO_Pins(Data);
  157.             }
  158.             DO_Request_Message();
  159.         }else{
  160.             CrC_is_Error = true;
  161.         }
  162.     }
  163. }
  164.  
  165. //-----------------------------------------------------------------------------
  166. // SCON0::RI (Receive Interrupt Flag)
  167. // SCON0::TI (Transmit Interrupt Flag)
  168. //-----------------------------------------------------------------------------
  169. SI_INTERRUPT(UART0_ISR, UART0_IRQn)
  170. {
  171.     if (SCON0_RI == 1)
  172.        {
  173.           if( UART_Buffer_Size == 0)  {         // If new word is entered
  174.              UART_Input_First = 0;
  175.           }
  176.           SCON0_RI = 0;                         // Clear interrupt flag
  177.           Byte = SBUF0;                         // Read a character from UART
  178.           if (UART_Buffer_Size < UART_BUFFERSIZE)
  179.           {
  180.              UART_Buffer[UART_Input_First] = Byte; // Store in array
  181.  
  182.              UART_Buffer_Size++;                // Update array's size
  183.  
  184.              UART_Input_First++;                // Update counter
  185.           }else{
  186.               Check_Message();                  // Get the whole message and brake it into pieces
  187.           }
  188.        }
  189.  
  190.  
  191.  /** ECHO BACK THE MESSAGES **/
  192.  
  193. if (SCON0_TI == 1)                              // Check if transmit flag is set
  194.    {
  195.       SCON0_TI = 0;                             // Clear interrupt flag
  196.       if (UART_Buffer_Size != 1)                // If buffer not empty
  197.       {
  198.          // If a new word is being output
  199.          if ( UART_Buffer_Size == UART_Input_First ) {
  200.               UART_Output_First = 0;
  201.          }
  202.          // Store a character in the variable byte
  203.          Byte = UART_Buffer[UART_Output_First];
  204.          if ((Byte >= 0x61) && (Byte <= 0x7A)) { // If upper case letter
  205.             Byte -= 32;
  206.          }
  207.          SBUF0 = Byte;                          // Transmit to Hyperterminal
  208.          UART_Output_First++;                   // Update counter
  209.          UART_Buffer_Size--;                    // Decrease array size
  210.       }
  211.       else
  212.       {
  213.          UART_Buffer_Size = 0;                  // Set the array size to 0
  214.          TX_Ready = 1;                          // Indicate transmission complete
  215.       }
  216.    }
  217. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement