A cut-down version of https://os.mbed.com/users/Sissors/code/DS1820/ tweaked for use with the STM32F103. It is all generic Mbed operations though, so should be usable anywhere. Non-essential functions have been removed, as this is intended for use within a tutorial.

Dependencies:   LinkedList

Dependents:   STM32F103C8T6_DS18B20 stm32f103c8t6-ds18b20

Fork of DS1820 by Erik -

Revision:
16:d490e11c466d
Parent:
14:c591209285e9
Child:
17:045f96704cc6
--- a/DS1820.cpp	Sun Jan 08 17:26:21 2017 +0000
+++ b/DS1820.cpp	Thu Jan 11 04:37:42 2018 +0000
@@ -1,88 +1,35 @@
 #include "DS1820.h"
 
-#ifdef TARGET_STM
-//STM targets use opendrain mode since their GPIO code is too bad to be used like the others
-    #define ONEWIRE_INPUT(pin)  pin->write(1)
-    #define ONEWIRE_OUTPUT(pin) 
-    #define ONEWIRE_INIT(pin)   pin->output(); pin->mode(OpenDrain)
-    
-    // TEMP, remove once STM fixed their stuff
-// Enable GPIO clock and return GPIO base address 
-static uint32_t Set_GPIO_Clock(uint32_t port_idx) { 
-    uint32_t gpio_add = 0; 
-    switch (port_idx) { 
-        case PortA: 
-           gpio_add = GPIOA_BASE; 
-           __GPIOA_CLK_ENABLE(); 
-           break; 
-        case PortB: 
-            gpio_add = GPIOB_BASE; 
-            __GPIOB_CLK_ENABLE(); 
-            break; 
-#if defined(GPIOC_BASE) 
-        case PortC: 
-            gpio_add = GPIOC_BASE; 
-            __GPIOC_CLK_ENABLE(); 
-            break; 
-#endif 
-#if defined(GPIOD_BASE) 
-       case PortD: 
-           gpio_add = GPIOD_BASE; 
-            __GPIOD_CLK_ENABLE(); 
-            break; 
-#endif 
-#if defined(GPIOF_BASE) 
-        case PortF: 
-            gpio_add = GPIOF_BASE; 
-            __GPIOF_CLK_ENABLE(); 
-            break; 
-#endif 
-      default: 
-           error("Pinmap error: wrong port number."); 
-           break; 
-   } 
-   return gpio_add; 
-} 
+DigitalOut tracer(PA_6);
 
+static inline void onewire_input(DigitalInOut &pin) {
+    pin.input();
+    pin.mode(PullUp);
+}
 
-#else
-    #define ONEWIRE_INPUT(pin)  pin->input()
-    #define ONEWIRE_OUTPUT(pin) pin->output()
-    #define ONEWIRE_INIT(pin)
-#endif
+static inline void onewire_output(DigitalInOut &pin) {
+    pin.output();
+    pin.write(0);
+}
 
 LinkedList<node> DS1820::probes;
  
  
-DS1820::DS1820 (PinName data_pin, PinName power_pin, bool power_polarity) : _datapin(data_pin), _parasitepin(power_pin) {
+DS1820::DS1820 (PinName data_pin) : _datapin(data_pin) {
     int byte_counter;
-    _power_polarity = power_polarity;
+    
+    tracer = 1;
 
-    _power_mosfet = power_pin != NC;
-    
     for(byte_counter=0;byte_counter<9;byte_counter++)
         RAM[byte_counter] = 0x00;
     
-    ONEWIRE_INIT((&_datapin));
-    // Temp code since the above doesn't actually do anything in mbed revisions up to 133
-    #ifdef TARGET_STM
-    
-    uint32_t port_index = STM_PORT(data_pin); 
-    uint32_t pin_index  = STM_PIN(data_pin); 
+    onewire_input(_datapin);
     
-    // Enable GPIO clock 
-    uint32_t gpio_add = Set_GPIO_Clock(port_index); 
-    GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; 
-
-    gpio->OTYPER |= (uint32_t)(1 << pin_index); 
-    #endif
-    
-    if (!unassignedProbe(&_datapin, _ROM))
-        error("No unassigned DS1820 found!\n");
+    if (!unassignedProbe(_ROM))
+        error("No unassigned DS1820 found!\r\n");
     else {
-        _datapin.input();
+        onewire_input(_datapin);
         probes.append(this);
-        _parasite_power = !read_power_supply();
     }
 }
 
@@ -97,51 +44,48 @@
 }
 
  
-bool DS1820::onewire_reset(DigitalInOut *pin) {
+bool DS1820::onewire_reset() {
 // This will return false if no devices are present on the data bus
     bool presence=false;
-    ONEWIRE_OUTPUT(pin);
-    pin->write(0);          // bring low for 500 us
+    onewire_output(_datapin);    // bring low for 500 us
     wait_us(500);
-    ONEWIRE_INPUT(pin);       // let the data line float high
+    onewire_input(_datapin);       // let the data line float high
     wait_us(90);            // wait 90us
-    if (pin->read()==0) // see if any devices are pulling the data line low
+    if (_datapin.read()==0) // see if any devices are pulling the data line low
         presence=true;
     wait_us(410);
     return presence;
 }
  
-void DS1820::onewire_bit_out (DigitalInOut *pin, bool bit_data) {
-    ONEWIRE_OUTPUT(pin);
-    pin->write(0);
-    wait_us(3);                 // DXP modified from 5
+void DS1820::onewire_bit_out (bool bit_data) {
+    onewire_output(_datapin);
+    wait_us(1);                 // DXP modified from 5
     if (bit_data) {
-        pin->write(1); // bring data line high
-        wait_us(55);
+        onewire_input(_datapin); // bring data line high
     } else {
-        wait_us(55);            // keep data line low
-        pin->write(1);
-        wait_us(10);            // DXP added to allow bus to float high before next bit_out
+        wait_us(57);            // keep data line low
+        onewire_input(_datapin);
     }
+        wait_us(55);
 }
  
 void DS1820::onewire_byte_out(char data) { // output data character (least sig bit first).
     int n;
     for (n=0; n<8; n++) {
-        onewire_bit_out(&this->_datapin, data & 0x01);
+        onewire_bit_out(data & 0x01);
         data = data >> 1; // now the next bit is in the least sig bit position.
     }
+    wait_us(100);
 }
  
-bool DS1820::onewire_bit_in(DigitalInOut *pin) {
+bool DS1820::onewire_bit_in() {
     bool answer;
-    ONEWIRE_OUTPUT(pin);
-    pin->write(0);
-    wait_us(3);                 // DXP modofied from 5
-    ONEWIRE_INPUT(pin);
+    onewire_output(_datapin);
+    wait_us(1);                 // DXP modified from 5
+    onewire_input(_datapin);
     wait_us(10);                // DXP modified from 5
-    answer = pin->read();
-    wait_us(45);                // DXP modified from 50
+    answer = _datapin.read();
+    wait_us(49);                // DXP modified from 50
     return answer;
 }
  
@@ -150,36 +94,18 @@
     int i;
     for (i=0; i<8; i++) {
         answer = answer >> 1; // shift over to make room for the next bit
-        if (onewire_bit_in(&this->_datapin))
+        if (onewire_bit_in())
             answer = answer | 0x80; // if the data port is high, make this bit a 1
     }
     return answer;
 }
 
-bool DS1820::unassignedProbe(PinName pin) {
-    DigitalInOut _pin(pin);
-    ONEWIRE_INIT((&_pin));
-    // Temp code since the above doesn't actually do anything in mbed revisions up to 133
-    #ifdef TARGET_STM
-    
-    uint32_t port_index = STM_PORT(pin); 
-    uint32_t pin_index  = STM_PIN(pin); 
-    
-    // Enable GPIO clock 
-    uint32_t gpio_add = Set_GPIO_Clock(port_index); 
-    GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; 
-
-    gpio->OTYPER |= (uint32_t)(1 << pin_index); 
-    #endif
-    char ROM_address[8];
-    return search_ROM_routine(&_pin, 0xF0, ROM_address);
+ 
+bool DS1820::unassignedProbe(char *ROM_address) {
+    return search_ROM_routine(0xF0, ROM_address);
 }
  
-bool DS1820::unassignedProbe(DigitalInOut *pin, char *ROM_address) {
-    return search_ROM_routine(pin, 0xF0, ROM_address);
-}
- 
-bool DS1820::search_ROM_routine(DigitalInOut *pin, char command, char *ROM_address) {
+bool DS1820::search_ROM_routine(char command, char *ROM_address) {
     bool DS1820_done_flag = false;
     int DS1820_last_descrepancy = 0;
     char DS1820_search_ROM[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -190,21 +116,23 @@
  
     return_value=false;
     while (!DS1820_done_flag) {
-        if (!onewire_reset(pin)) {
+        if (!onewire_reset()) {
             return false;
         } else {
             ROM_bit_index=1;
             descrepancy_marker=0;
             char command_shift = command;
             for (int n=0; n<8; n++) {           // Search ROM command or Search Alarm command
-                onewire_bit_out(pin, command_shift & 0x01);
+                onewire_bit_out(command_shift & 0x01);
                 command_shift = command_shift >> 1; // now the next bit is in the least sig bit position.
             } 
+            wait_us(100);
+            
             byte_counter = 0;
             bit_mask = 0x01;
             while (ROM_bit_index<=64) {
-                Bit_A = onewire_bit_in(pin);
-                Bit_B = onewire_bit_in(pin);
+                Bit_A = onewire_bit_in();
+                Bit_B = onewire_bit_in();
                 if (Bit_A & Bit_B) {
                     descrepancy_marker = 0; // data read error, this should never happen
                     ROM_bit_index = 0xFF;
@@ -230,7 +158,7 @@
                             }
                         }
                     }
-                    onewire_bit_out (pin, DS1820_search_ROM[byte_counter] & bit_mask);
+                    onewire_bit_out (DS1820_search_ROM[byte_counter] & bit_mask);
                     ROM_bit_index++;
                     if (bit_mask & 0x80) {
                         byte_counter++;
@@ -239,6 +167,8 @@
                         bit_mask = bit_mask << 1;
                     }
                 }
+                
+                wait_us(100);
             }
             DS1820_last_descrepancy = descrepancy_marker;
             if (ROM_bit_index != 0xFF) {
@@ -252,6 +182,9 @@
                         }
                         for(byte_counter=0;byte_counter<8;byte_counter++)
                             ROM_address[byte_counter] = DS1820_search_ROM[byte_counter];
+                            
+                        printf("Found DS18B20: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n",
+                            ROM_address[0], ROM_address[1], ROM_address[2], ROM_address[3], ROM_address[4], ROM_address[5], ROM_address[6], ROM_address[7]);
                         return true;
                     } else {                    //Otherwise, check if ROM is already known
                         bool equal = true;
@@ -279,15 +212,15 @@
 void DS1820::match_ROM() {
 // Used to select a specific device
     int i;
-    onewire_reset(&this->_datapin);
-    onewire_byte_out( 0x55);  //Match ROM command
+    onewire_reset();
+    onewire_byte_out(0x55);  //Match ROM command
     for (i=0;i<8;i++) {
         onewire_byte_out(_ROM[i]);
     }
 }
  
 void DS1820::skip_ROM() {
-    onewire_reset(&this->_datapin);
+    onewire_reset();
     onewire_byte_out(0xCC);   // Skip ROM command
 }
  
@@ -360,24 +293,13 @@
         }
     }
     
+    tracer = 0;    
     onewire_byte_out( 0x44);  // perform temperature conversion
-    if (_parasite_power) {
-        if (_power_mosfet) {
-            _parasitepin = _power_polarity;     // Parasite power strong pullup
-            wait_ms(delay_time);
-            _parasitepin = !_power_polarity;
-            delay_time = 0;
-        } else {
-            _datapin.output();
-            _datapin.write(1);
-            wait_ms(delay_time);
-            _datapin.input();
-        }
-    } else {
-        if (wait) {
-            wait_ms(delay_time);
-            delay_time = 0;
-        }
+    tracer = 1;
+    
+    if (wait) {
+        wait_ms(delay_time);
+        delay_time = 0;
     }
     return delay_time;
 }
@@ -453,16 +375,5 @@
     }
     return answer;
 }
- 
-bool DS1820::read_power_supply(devices device) {
-// This will return true if the device (or all devices) are Vcc powered
-// This will return false if the device (or ANY device) is parasite powered
-    if (device==all_devices)
-        skip_ROM();          // Skip ROM command, will poll for any device using parasite power
-    else
-        match_ROM();
-    onewire_byte_out(0xB4);   // Read power supply command
-    return onewire_bit_in(&this->_datapin);
-}