Subversion Repositories HomeAutomation

Rev

Rev 2026 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. #define UART_RX_BUFFER_SIZE 128
  2.  
  3. #include "sns_heatPower.h"
  4.  
  5. uint32_t sns_heatPower_energy;
  6. uint16_t sns_heatPower_power;
  7. uint8_t sns_heatPower_values_ok;
  8.  
  9. const char sns_heatPower_request[sns_heatPower_REQ_STRING_LEN] = sns_heatPower_REQ_STRING;
  10.  
  11. /* TODO: add filtering of power (power32) */
  12.  
  13. typedef enum {
  14.     PARITY_NONE = 0,
  15.     PARITY_EVEN = 1,
  16.     PARITY_ODD = 2,
  17. } parityMode_t;
  18.  
  19. uint8_t RxdCnt;
  20. uint8_t RxdEnable;
  21.  
  22. uint8_t a2d (unsigned char chr) { // Convert ascii to decimal
  23.     return (chr-48);
  24. }
  25.  
  26. void sns_heatPower_Init(void)
  27. {
  28.     /* Set up UART */
  29.     uart_setDatabits(sns_heatPower_CNF_DATABITS);
  30.     uart_setStopbits(sns_heatPower_CNF_STOPBITS);
  31.     uart_setParity(sns_heatPower_CNF_PARITY!=PARITY_NONE, sns_heatPower_CNF_PARITY==PARITY_ODD);
  32.     uart_init(UART_BAUD_SELECT_DOUBLE_SPEED(sns_heatPower_BAUD_RX, F_CPU));
  33.  
  34.     /* Start request data timer */
  35.     Timer_SetTimeout(sns_heatPower_REQ_TIMER, sns_heatPower_REQ_INTERVAL_S*1000 , TimerTypeFreeRunning, 0);
  36.  
  37.     RxdCnt = 0;
  38.     RxdEnable = 0;
  39.     sns_heatPower_values_ok = 0;
  40. }
  41.  
  42. void sns_heatPower_Process(void)
  43. {
  44.     /* At timer timeout send a new request */
  45.     if (Timer_Expired(sns_heatPower_REQ_TIMER))
  46.     {
  47. #if (CAN_PRINTF == 1)
  48.         printf("TX\n");
  49. #endif
  50.         /* Set baudrate to transmit baudrate */
  51.         uart_init(UART_BAUD_SELECT_DOUBLE_SPEED(sns_heatPower_BAUD_TX, F_CPU));
  52.        
  53.         /* Send request string */
  54.         uart_puts(sns_heatPower_request);
  55.        
  56.         /* TX buffer must be empty before we change buadrate */
  57.         //while(uart_txbufempty()) {;}
  58.        
  59.         Timer_SetTimeout(sns_heatPower_REQ_TIMER2, 300 , TimerTypeOneShot, 0);     
  60.     }
  61.  
  62.     /* At timer timeout send a new request */
  63.     if (Timer_Expired(sns_heatPower_REQ_TIMER2))
  64.     {
  65.         /* Set baudrate to receive baudrate */
  66.         uart_init(UART_BAUD_SELECT_DOUBLE_SPEED(sns_heatPower_BAUD_RX, F_CPU));
  67.         RxdCnt = 0;
  68.         RxdEnable = 1;
  69.         sns_heatPower_energy = 0;
  70.         sns_heatPower_power = 0;
  71.         sns_heatPower_values_ok = 0;
  72. #if (CAN_PRINTF == 1)
  73.         printf("RX\n");
  74. #endif
  75.     }
  76.    
  77.     unsigned char status;
  78.     do
  79.     {
  80.         /* ask uart driver for more data */
  81.         unsigned int data = uart_getc();
  82.         /* character is contained in LSB */
  83.         unsigned char c = (unsigned char)(data & 0x00FF);
  84.  
  85.         /* status is contained in MSB */
  86.         status = (unsigned char)((data & 0xFF00) >> 8);
  87.        
  88.         /* status == 0 means we just received a new char */
  89.         if (status == 0 && RxdEnable)
  90.         {
  91.             //printf("%c", c&0x7F);
  92.             /* c contains an ascii value to be processed */
  93.             /* get the decimal representation of ascii value */
  94.             uint8_t decimalval = a2d(c);
  95.  
  96.             if (RxdCnt >= sns_heatPower_RES_ENERGY_START && RxdCnt < (sns_heatPower_RES_ENERGY_START + sns_heatPower_RES_ENERGY_LEN))
  97.             {
  98.                 /* Check that recied char was between 0-9 */
  99.                 if (decimalval > 9)
  100.                 {
  101.                     /* ERROR!! */
  102.                     RxdEnable = 0;
  103. #if (CAN_PRINTF == 1)
  104.                     printf("E0 %u\n", c&0x7F);
  105. #endif
  106.                 }
  107.                 if (decimalval > 0)
  108.                 {
  109.                     uint32_t multiplier = 1;
  110.                     /* multiply received char with 1000000, 100000, 10000, 1000 etc */
  111.                     for (uint8_t i = 0; i < sns_heatPower_RES_ENERGY_LEN-(RxdCnt-sns_heatPower_RES_ENERGY_START)-1; i++)
  112.                     {
  113.                         multiplier = multiplier*10;
  114.                     }
  115.                     sns_heatPower_energy += decimalval*multiplier;
  116.                 }
  117.             }
  118.             /* When all data in energy are fetched */
  119.             if (RxdCnt == (sns_heatPower_RES_ENERGY_START + sns_heatPower_RES_ENERGY_LEN))
  120.             {
  121.                 /* Recieved data is in kWh, data to be transmitted on CAN must be in Wh */
  122.                 sns_heatPower_energy = sns_heatPower_energy*1000;
  123. #if (CAN_PRINTF == 1)
  124.                 printf("%lu", sns_heatPower_energy);
  125. #endif
  126.             }
  127.  
  128.             if (RxdCnt >= sns_heatPower_RES_POWER_START && RxdCnt < (sns_heatPower_RES_POWER_START + sns_heatPower_RES_POWER_LEN))
  129.             {
  130.                 /* Check that recied char was between 0-9 */
  131.                 if (decimalval > 9)
  132.                 {
  133.                     /* ERROR!! */
  134.                     RxdEnable = 0;
  135. #if (CAN_PRINTF == 1)
  136.                     printf("E1 %u\n", c&0x7F);
  137. #endif
  138.                 }
  139.                 if (decimalval > 0)
  140.                 {
  141.                     uint32_t multiplier = 1;
  142.                     /* multiply received char with 1000000, 100000, 10000, 1000 etc */
  143.                     for (uint8_t i = 0; i < sns_heatPower_RES_POWER_LEN-(RxdCnt-sns_heatPower_RES_POWER_START)-1; i++)
  144.                     {
  145.                         multiplier = multiplier*10;
  146.                     }
  147.  
  148.                     sns_heatPower_power += decimalval*multiplier;
  149.                 }
  150.             }
  151.             if (RxdCnt == (sns_heatPower_RES_POWER_START + sns_heatPower_RES_POWER_LEN))
  152.             {
  153.                 /* Recieved data is in 100Wh, data to be transmitted on CAN must be in Wh */
  154.                 sns_heatPower_power = sns_heatPower_power*100;
  155. #if (CAN_PRINTF == 1)
  156.                 printf("P%u\n", sns_heatPower_power);
  157. #endif
  158.             }
  159.  
  160. #if (sns_heatPower_RES_POWER_START > sns_heatPower_RES_ENERGY_START)
  161.             if (RxdCnt == (sns_heatPower_RES_POWER_START + sns_heatPower_RES_POWER_LEN))
  162. #else
  163.             if (RxdCnt == (sns_heatPower_RES_ENERGY_START + sns_heatPower_RES_ENERGY_LEN))
  164. #endif
  165.             {
  166.                 sns_heatPower_values_ok = 1;
  167.             }
  168.  
  169.             RxdCnt++;
  170.         }
  171.         else if (status == 0x10 && RxdEnable)
  172.         {
  173.             /* Frame error */
  174. #if (CAN_PRINTF == 1)
  175.             printf("E2%x\n", c);
  176. #endif
  177.             RxdEnable = 0;
  178.         }
  179.         else if (status == 0x08 && RxdEnable)
  180.         {
  181.             /* Overrun error */
  182. #if (CAN_PRINTF == 1)
  183.             printf("E3%x\n", c);
  184. #endif
  185.             RxdEnable = 0;
  186.         }
  187.         else if (status == 0x02 && RxdEnable)
  188.         {
  189.             /* Buffer overflow error */
  190. #if (CAN_PRINTF == 1)
  191.             printf("E4%x\n", c);
  192. #endif
  193.             RxdEnable = 0;
  194.         }
  195.         else if (status != 0 && data != UART_NO_DATA && RxdEnable)
  196.         {
  197. #if (CAN_PRINTF == 1)
  198.             printf("E5%x%x\n", status, c);
  199. #endif
  200.             RxdEnable = 0;
  201.         }
  202.     /* keep going until uart RXBUF is empty */
  203.     } while (status == 0);
  204.    
  205.     if (sns_heatPower_values_ok)
  206.     {
  207.         StdCan_Msg_t txMsg;
  208.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  209.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  210.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_HEATPOWER;
  211.         txMsg.Header.ModuleId = sns_heatPower_ID;
  212.         txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_ELECTRICPOWER;
  213.         txMsg.Length = 8;
  214.         txMsg.Data[0] = (uint8_t)((sns_heatPower_power>>8) & 0xff);
  215.         txMsg.Data[1] = (uint8_t)(sns_heatPower_power & 0xff);
  216.         txMsg.Data[5] = (uint8_t)sns_heatPower_energy & 0xff;
  217.         txMsg.Data[4] = (uint8_t)(sns_heatPower_energy >> 8) & 0xff;
  218.         txMsg.Data[3] = (uint8_t)(sns_heatPower_energy >> 16) & 0xff;
  219.         txMsg.Data[2] = (uint8_t)(sns_heatPower_energy >> 24) & 0xff;
  220.         txMsg.Data[6] = (uint8_t)((sns_heatPower_power>>8) & 0xff);
  221.         txMsg.Data[7] = (uint8_t)(sns_heatPower_power & 0xff);
  222.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  223.         sns_heatPower_values_ok = 0;
  224.     }
  225. }
  226.  
  227. void sns_heatPower_HandleMessage(StdCan_Msg_t *rxMsg)
  228. {
  229.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  230.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  231.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_HEATPOWER &&
  232.         rxMsg->Header.ModuleId == sns_heatPower_ID)
  233.     {
  234.         switch (rxMsg->Header.Command)
  235.         {
  236.         //case CAN_CMD_MODULE_DUMMY:
  237.         ///TODO: Do something dummy
  238.         break;
  239.         }
  240.     }
  241. }
  242.  
  243. void sns_heatPower_List(uint8_t ModuleSequenceNumber)
  244. {
  245.     StdCan_Msg_t txMsg;
  246.  
  247.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  248.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  249.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_HEATPOWER;
  250.     txMsg.Header.ModuleId = sns_heatPower_ID;
  251.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  252.     txMsg.Length = 6;
  253.  
  254.     uint32_t HwId=BIOS_GetHwId();
  255.     txMsg.Data[0] = HwId&0xff;
  256.     txMsg.Data[1] = (HwId>>8)&0xff;
  257.     txMsg.Data[2] = (HwId>>16)&0xff;
  258.     txMsg.Data[3] = (HwId>>24)&0xff;
  259.  
  260.     txMsg.Data[4] = NUMBER_OF_MODULES;
  261.     txMsg.Data[5] = ModuleSequenceNumber;
  262.  
  263.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  264. }
  265.