]> mj.ucw.cz Git - home-hw.git/blobdiff - lib/ds18b20.c
Power daemon: A new daemon for relaying power meter data to MQTT
[home-hw.git] / lib / ds18b20.c
index 8f6b550e1b7f665ab4f01cd644fba21f3e91df53..02a62cf0e31b8b483c5d8c5d1396ad2c5e0a4e1e 100644 (file)
@@ -73,11 +73,17 @@ static bool ds_reset(void)
        // Set timer period to the length of the whole transaction (1 ms)
        timer_set_period(DS_TIMER, 999);
 
+       // XXX: We do not know why this is needed...
+       static bool once;
+       if (!once) {
+               for (int i=0; i<10000; i++) __asm__ volatile ("nop");
+               once = 1;
+       }
+
        // Pull line down and start timer
-       cm_disable_interrupts();
-       timer_enable_counter(DS_TIMER);
+       timer_generate_event(DS_TIMER, TIM_EGR_UG);
        timer_set_oc_mode(DS_TIMER, TIM_OC2, TIM_OCM_INACTIVE);
-       cm_enable_interrupts();
+       timer_enable_counter(DS_TIMER);
 
        // Wait until the timer expires
        while (timer_is_counter_enabled(DS_TIMER))
@@ -106,12 +112,9 @@ static void ds_send_bit(bool bit)
        timer_set_period(DS_TIMER, 99);                         // Each write slot takes 100 μs
        timer_set_oc_mode(DS_TIMER, TIM_OC2, TIM_OCM_FORCE_HIGH);
        timer_set_oc_value(DS_TIMER, TIM_OC2, (bit ? 3 : 89));  // 1: 3μs pulse, 0: 89μs pulse
-       cm_disable_interrupts();
-       // XXX: On STM32F1, we must configure the OC channel _after_ we enable the counter,
-       // otherwise OC triggers immediately. Reasons?
-       timer_enable_counter(DS_TIMER);
+       timer_generate_event(DS_TIMER, TIM_EGR_UG);
        timer_set_oc_mode(DS_TIMER, TIM_OC2, TIM_OCM_INACTIVE);
-       cm_enable_interrupts();
+       timer_enable_counter(DS_TIMER);
        while (timer_is_counter_enabled(DS_TIMER))
                ;
 }
@@ -134,10 +137,9 @@ static bool ds_recv_bit(void)
        dma_set_number_of_data(DS_DMA, DS_DMA_CH, 1);
        dma_enable_channel(DS_DMA, DS_DMA_CH);
        timer_set_oc_mode(DS_TIMER, TIM_OC2, TIM_OCM_FORCE_HIGH);
-       cm_disable_interrupts();
-       timer_enable_counter(DS_TIMER);
+       timer_generate_event(DS_TIMER, TIM_EGR_UG);
        timer_set_oc_mode(DS_TIMER, TIM_OC2, TIM_OCM_INACTIVE);
-       cm_enable_interrupts();
+       timer_enable_counter(DS_TIMER);
        while (timer_is_counter_enabled(DS_TIMER))
                ;
        // DEBUG2("XXX %08x\n", ds_dma_buffer);