konbaasiang

stm8_esp01_expander.ino

Nov 22nd, 2020
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.08 KB | None | 0 0
  1. #include "stm8_esp01_msg.h"
  2.  
  3. uint8_t gpi_pin[]={0,1,2,4,3};  //NOTE: 4, 3 are swapped because we're following the PB4/PB5 bit order
  4. uint8_t gpo_pin[]={5,6,7,8,9};
  5.  
  6. #define SERIAL_PIN_OUTPUT
  7.  
  8.  
  9. #define ESP_RESET 13
  10. #define ESP_GPIO0 11
  11. #define ESP_GPIO2 12
  12. #define ESP_RX 14
  13. #define ESP_TX 15
  14.  
  15. #define READ_ESP_GPIO0 ((GPIOD->IDR & (1<<2))!=0)
  16. #define READ_ESP_GPIO2 ((GPIOD->IDR & (1<<3))!=0)
  17.  
  18. /*
  19. #define WATCHDOG_TIMEOUT 5000
  20. #define WATCHDOG_INITIAL 10000
  21. #define WATCHDOG_RELAX  60000
  22. */
  23.  
  24. //screw it
  25. #define WATCHDOG_TIMEOUT 60000
  26. #define WATCHDOG_INITIAL 60000
  27. #define WATCHDOG_RELAX  60000
  28.  
  29. uint32_t timestampNow=0;
  30.  
  31. uint32_t timestampWatchdog=0;
  32.  
  33. void apply_config();
  34.  
  35. void do_esp_reset()
  36. {
  37.     pinMode(ESP_GPIO0,OUTPUT);
  38.     pinMode(ESP_GPIO2,OUTPUT);
  39.    
  40.     digitalWrite(ESP_GPIO0,HIGH);
  41.     digitalWrite(ESP_GPIO2,HIGH);
  42.    
  43.     digitalWrite(ESP_RESET,LOW);
  44.     delay(50);
  45.  
  46.     reset_sync_state();
  47.    
  48.     digitalWrite(ESP_RESET,HIGH);
  49.     delay(50);
  50.    
  51.     apply_config();
  52. }
  53.  
  54.  
  55. void setup()
  56. {
  57.  
  58.     pinMode(ESP_RESET,OUTPUT);
  59.  
  60.     memset(&cfg,0,sizeof(cfg));
  61.  
  62.  
  63.     do_esp_reset();
  64.  
  65.     Serial_begin(STM8_BAUDRATE);
  66.     //Serial_begin(115200);
  67.  
  68. #ifndef SERIAL_PIN_OUTPUT
  69.     Serial_println_s("");
  70.     Serial_println_s("");
  71.     Serial_println_s("");
  72. #endif
  73.  
  74.  
  75.     // put your setup code here, to run once:
  76.     for(int i=0;i<sizeof(gpo_pin)/sizeof(gpo_pin[0]);i++)
  77.     {
  78.         pinMode(gpo_pin[i],OUTPUT);
  79.         digitalWrite(gpo_pin[i],FALSE);
  80.     }
  81.  
  82.     for(int i=0;i<sizeof(gpi_pin)/sizeof(gpi_pin[0]);i++)
  83.     {
  84.         pinMode(gpi_pin[i],INPUT);
  85.     }
  86.  
  87.  
  88.     timestampWatchdog=millis() + WATCHDOG_INITIAL;
  89.  
  90.    
  91. }  
  92.  
  93.  
  94.  
  95.  
  96. uint8_t esp_outputs=0;
  97.  
  98.  
  99. void apply_config()
  100. {
  101.     pinMode(ESP_GPIO0,(cfg.gpio0_mode>=pinmode_input0 && cfg.gpio0_mode<=pinmode_input4)?OUTPUT:INPUT);
  102.     pinMode(ESP_GPIO2,(cfg.gpio2_mode>=pinmode_input0 && cfg.gpio2_mode<=pinmode_input4)?OUTPUT:INPUT);
  103. }
  104.  
  105. uint8_t lastInputs=0xFF;
  106.  
  107. void pet_watchdog()
  108. {
  109.     if((int32_t) (timestampWatchdog-timestampNow)<WATCHDOG_TIMEOUT)
  110.     {
  111.         timestampWatchdog=timestampNow+WATCHDOG_TIMEOUT;
  112.     }
  113. }
  114.  
  115. void onmessage()
  116. {
  117.     pet_watchdog();
  118.  
  119. #ifndef SERIAL_PIN_OUTPUT
  120.     Serial_print_s("message: ");
  121.     Serial_println_u(msg.message);
  122. #endif
  123.    
  124.     switch(msg.message)
  125.     {
  126.     default:
  127.     case message_nop:
  128.         break;
  129.     case message_needs_reset:
  130. #ifndef SERIAL_PIN_OUTPUT
  131.         Serial_println_s("needs reset");
  132. #endif
  133.         do_esp_reset();
  134.         break;
  135.     case message_relax_watchdog:
  136.         timestampWatchdog=timestampNow+WATCHDOG_RELAX;
  137. #ifndef SERIAL_PIN_OUTPUT
  138.         Serial_println_s("relaxing watchdog");
  139. #endif
  140.         break;
  141.     case message_set_config:
  142.         apply_config();
  143. #ifndef SERIAL_PIN_OUTPUT
  144.         Serial_print_s("configuration received... gpio0 ");
  145.         Serial_print_u(cfg.gpio0_mode);
  146.         Serial_print_s(" gpio2 ");
  147.         Serial_println_u(cfg.gpio2_mode);
  148. #endif
  149.         timestampWatchdog=timestampNow+WATCHDOG_TIMEOUT;
  150.         lastInputs=0xFF;
  151.  
  152.         break;
  153. /*  case message_tx_ir:
  154. #ifndef SERIAL_PIN_OUTPUT
  155.         Serial_print_s("tx_ir received: ");
  156.         Serial_print_u((msg.data2 << 8 | msg.data3));
  157.         Serial_print_s(" bytes");
  158.         Serial_print_s("\n");
  159. #endif
  160.         break;*/
  161.        
  162.     }
  163. }
  164.  
  165.  
  166. void onpin(uint8_t pinvalue)
  167. {
  168.     esp_outputs=pinvalue;
  169.     pet_watchdog();
  170. }
  171.  
  172.  
  173. uint32_t bench_counter=0;
  174. uint8_t loop_counter=0;
  175.            
  176. void loop()
  177. {
  178.  
  179.     bench_counter++;
  180.  
  181.     loop_counter++;
  182.  
  183.  
  184.     while(Serial_available())
  185.     {
  186.         handle_receive(Serial_read());
  187.     }
  188.  
  189.  
  190.     uint8_t inputs=(GPIOA->IDR >> 1 ) & 7;      //read STM8 inputs 0, 1, 2 (PA1, PA2, PA3)
  191.     inputs |= (GPIOB->IDR >> 1) & 0x18;         //read STM8 inputs 3, 4 (PB4, PB5)
  192.  
  193.    
  194.     switch(cfg.gpio0_mode)      //pass through selected STM8 input to ESP GPIO0 if selected
  195.     {
  196.     default:
  197.         break;
  198.     case pinmode_input0:    GPIOD->ODR = (GPIOD->ODR & ~(1<<2)) | (((inputs >> 0) & 1)<<2); break;
  199.     case pinmode_input1:    GPIOD->ODR = (GPIOD->ODR & ~(1<<2)) | (((inputs >> 1) & 1)<<2); break;
  200.     case pinmode_input2:    GPIOD->ODR = (GPIOD->ODR & ~(1<<2)) | (((inputs >> 2) & 1)<<2); break;
  201.     case pinmode_input3:    GPIOD->ODR = (GPIOD->ODR & ~(1<<2)) | (((inputs >> 3) & 1)<<2); break;
  202.     case pinmode_input4:    GPIOD->ODR = (GPIOD->ODR & ~(1<<2)) | (((inputs >> 4) & 1)<<2); break;
  203.     }
  204.  
  205.     switch(cfg.gpio2_mode)      //pass through selected STM8 input to ESP GPIO2 if selected
  206.     {
  207.     default:
  208.         break;
  209.     case pinmode_input0:    GPIOD->ODR = (GPIOD->ODR & ~(1<<3)) | (((inputs >> 0) & 1)<<3); break;
  210.     case pinmode_input1:    GPIOD->ODR = (GPIOD->ODR & ~(1<<3)) | (((inputs >> 1) & 1)<<3); break;
  211.     case pinmode_input2:    GPIOD->ODR = (GPIOD->ODR & ~(1<<3)) | (((inputs >> 2) & 1)<<3); break;
  212.     case pinmode_input3:    GPIOD->ODR = (GPIOD->ODR & ~(1<<3)) | (((inputs >> 3) & 1)<<3); break;
  213.     case pinmode_input4:    GPIOD->ODR = (GPIOD->ODR & ~(1<<3)) | (((inputs >> 4) & 1)<<3); break;
  214.     }
  215.  
  216.  
  217.     switch(cfg.gpio0_mode)      //if an STM8 input has already been sent to ESP GPIO0 then clear it out so we don't trigger a serial update
  218.     {
  219.     default:
  220.         break;
  221.     case pinmode_input0:    inputs &= ~(1 << 0);    break;
  222.     case pinmode_input1:    inputs &= ~(1 << 1);    break;
  223.     case pinmode_input2:    inputs &= ~(1 << 2);    break;
  224.     case pinmode_input3:    inputs &= ~(1 << 3);    break;
  225.     case pinmode_input4:    inputs &= ~(1 << 4);    break;
  226.     }
  227.  
  228.     switch(cfg.gpio2_mode)      //if an STM8 input has already been sent to ESP GPIO2 then clear it out so we don't trigger a serial update
  229.     {
  230.     default:
  231.         break;
  232.     case pinmode_input0:    inputs &= ~(1 << 0);    break;
  233.     case pinmode_input1:    inputs &= ~(1 << 1);    break;
  234.     case pinmode_input2:    inputs &= ~(1 << 2);    break;
  235.     case pinmode_input3:    inputs &= ~(1 << 3);    break;
  236.     case pinmode_input4:    inputs &= ~(1 << 4);    break;
  237.     }
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.     uint8_t outputs=esp_outputs;    //start with the output pins as commanded from the ESP through our serial interface
  245.  
  246.     switch(cfg.gpio0_mode)  //override the appropriate output pin with the current state of the ESP GPIO0 output, if selected
  247.     {
  248.     default:
  249.         break;
  250.     case pinmode_output0:   outputs = (outputs & ~(1<<0)) | (READ_ESP_GPIO0 << 0);  break;
  251.     case pinmode_output1:   outputs = (outputs & ~(1<<1)) | (READ_ESP_GPIO0 << 1);  break;
  252.     case pinmode_output2:   outputs = (outputs & ~(1<<2)) | (READ_ESP_GPIO0 << 2);  break;
  253.     case pinmode_output3:   outputs = (outputs & ~(1<<3)) | (READ_ESP_GPIO0 << 3);  break;
  254.     case pinmode_output4:   outputs = (outputs & ~(1<<4)) | (READ_ESP_GPIO0 << 4);  break;
  255.     }
  256.  
  257.     switch(cfg.gpio2_mode)  //override the appropriate output pin with the current state of the ESP GPIO2 output, if selected
  258.     {
  259.     default:
  260.         break;
  261.     case pinmode_output0:   outputs = (outputs & ~(1<<0)) | (READ_ESP_GPIO2 << 0);  break;
  262.     case pinmode_output1:   outputs = (outputs & ~(1<<1)) | (READ_ESP_GPIO2 << 1);  break;
  263.     case pinmode_output2:   outputs = (outputs & ~(1<<2)) | (READ_ESP_GPIO2 << 2);  break;
  264.     case pinmode_output3:   outputs = (outputs & ~(1<<3)) | (READ_ESP_GPIO2 << 3);  break;
  265.     case pinmode_output4:   outputs = (outputs & ~(1<<4)) | (READ_ESP_GPIO2 << 4);  break;
  266.     }
  267.    
  268.  
  269.     //write the STM8 outputs
  270.  
  271.     GPIOC->ODR = (GPIOC->ODR & 7) | ((outputs & 0x1f)<<3);
  272.  
  273.  
  274.  
  275.  
  276.     loop_counter &= 31;     //spread these operations out for improved timing stability
  277.  
  278.     switch(loop_counter)
  279.     {
  280.     case 8:
  281.         if(lastInputs!=inputs)  //if an input has changed, send an update message
  282.         {
  283.             lastInputs=inputs;
  284. #ifdef SERIAL_PIN_OUTPUT
  285.             Serial_write(PIN_MSG);
  286.             Serial_write(lastInputs);
  287. #endif
  288.         }
  289.         break;
  290.     case 16:
  291.         timestampNow=millis();
  292.    
  293.         if((int32_t) (timestampWatchdog-timestampNow)<0)
  294.         {
  295.             timestampWatchdog=timestampNow+WATCHDOG_TIMEOUT;
  296. #ifndef SERIAL_PIN_OUTPUT
  297.             Serial_println_s("watchdog reset");
  298. #endif
  299.    
  300. #ifdef SERIAL_PIN_OUTPUT
  301.             do_esp_reset();
  302. #endif
  303. /*          for(int i=0;i<2;i++)
  304.             {
  305.                 digitalWrite(gpo_pin[4],HIGH);
  306.                 delay(250);
  307.                 digitalWrite(gpo_pin[4],LOW);
  308.                 delay(250);
  309.             }*/
  310.            
  311.         }
  312.         break;
  313.     case 32:
  314.         {
  315.             static uint32_t lastMillis=0;
  316.            
  317.             if(millis()-lastMillis>=1000)
  318.             {
  319.                 lastMillis+=1000;
  320.  
  321. #ifndef SERIAL_PIN_OUTPUT
  322. //              Serial_println_u(bench_counter);
  323. #endif
  324.                 bench_counter=0;
  325.    
  326.                 int32_t diff=(int32_t) (timestampWatchdog-timestampNow);
  327.    
  328.                 if(diff<3000 || diff>6000)
  329.                 {
  330. #ifndef SERIAL_PIN_OUTPUT
  331. //                  Serial_print_s("watchdog counter: ");
  332. //                  Serial_println_i(diff);
  333. #endif
  334.                 }
  335.  
  336.                
  337.  
  338.                
  339.                
  340.             }
  341.            
  342.         }
  343.         break;
  344.     }
  345.  
  346.  
  347.  
  348.    
  349.  
  350.  
  351.  
  352. }
Advertisement
Add Comment
Please, Sign In to add comment