one wire driver
Dependents: 09_PT1000 10_PT1000 11_PT1000
DS2482.cpp
- Committer:
- rs27
- Date:
- 2014-07-26
- Revision:
- 5:d94037eb31ed
- Parent:
- 4:c29e67d55f86
File content as of revision 5:d94037eb31ed:
#include "mbed.h" #include "DS2482.h" #include "monitor.h" extern Serial pc; //----------------------------------------------------------------------------- // CRC = X^8 + X^5 + X^4 + 1 #define CRC_TABLE_ITEMS 256 const uint8_t crc_table[CRC_TABLE_ITEMS] = { 0 , 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, 35 ,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 }; //========================================================================== // destructor DS2482::DS2482(PinName sda, PinName scl, int address) : i2c(sda, scl) { addr = address; i2c.frequency(100000); } //----------------------------------------------------------------------------- // Calculate the CRC8 of the byte value provided with the current // global 'crc8' value. // Returns current global crc8 value // uint8_t DS2482::crc_calc(uint8_t x) { crc_value = crc_table[crc_value ^ x]; return crc_value; } uint8_t DS2482::crc_calc_buffer(uint8_t *pbuffer, uint8_t count) { uint8_t n; crc_value = 0; for (n = 0; n < count; n++) { crc_value = crc_table[crc_value ^ *pbuffer++]; } return crc_value; } //========================================================================== // I2C DS2482 // //-------------------------------------------------------------------------- // DS2482 Detect routine that sets the I2C address and then performs a // device reset followed by writing the configuration byte to default values: // 1-Wire speed (c1WS) = standard (0) // Strong pullup (cSPU) = off (0) // Presence pulse masking (cPPM) = off (0) // Active pullup (cAPU) = on (CONFIG_APU = 0x01) // // Returns: TRUE if device was detected and written // FALSE device not detected or failure to write configuration byte //uint8_t DS2482_detect(unsigned char addr) // uint8_t DS2482::detect(void) { if (!reset()) // reset the DS2482 ON selected address { #if OW_MASTER_START pc.printf("\r\n--- DS2482 bus0 reset not executed \n"); wait(0.1); #endif return false; } // default configuration c1WS = 0; cSPU = 0; cPPM = 0; cAPU = DS2482_CFG_APU; // write the default configuration setup if (!write_config(c1WS | cSPU | cPPM | cAPU)) { #if OW_MASTER_START pc.printf("\r\n--- DS2482 configuration failure \n"); wait(0.1); #endif return false; } #if OW_MASTER_START pc.printf("\r\n*** DS2482 detect OK \n"); wait(0.1); #endif return true; } //-------------------------------------------------------------------------- // Perform a device reset on the DS2482 // // Returns: TRUE if device was reset // FALSE device not detected or failure to perform reset // int DS2482::reset(void) { char cmd[2]; cmd[0] = DS2482_CMD_DRST; // pc.printf("\nreset write"); i2c.write(addr, cmd, 1); // pc.printf("\nreset read"); i2c.read(addr, cmd, 1); // pc.printf(" cmd = %02x \n",cmd[0]); wait(0.1); return ((cmd[0] & 0xF7) == 0x10); } //-------------------------------------------------------------------------- // Write the configuration register in the DS2482. The configuration // options are provided in the lower nibble of the provided config byte. // The uppper nibble in bitwise inverted when written to the DS2482. // // Returns: TRUE: config written and response correct // FALSE: response incorrect // uint8_t DS2482::write_config(uint8_t config) { char cmd[2]; char read_config; cmd[0] = DS2482_CMD_WCFG; cmd[1] = config | (~config << 4); i2c.write(addr, cmd, 2); i2c.read(addr, cmd, 1); read_config = cmd[0]; if (config != read_config) // check for failure due to incorrect read back { // handle error // ... #if OW_MASTER_START pc.printf("\r\n---check for failure due to incorrect config read back"); #endif reset(); return false; } return true; } //-------------------------------------------------------------------------- // DS2482 1-Wire Operations //-------------------------------------------------------------------------- // //OWReset //-------------------------------------------------------------------------- // Reset all of the devices on the 1-Wire Net and return the result. // // Returns: TRUE(1): presence pulse(s) detected, device(s) reset // FALSE(0): no presence pulses detected // uint8_t DS2482::OWReset(void) { uint8_t poll_count = 0; char cmd[2]; cmd[0] = DS2482_CMD_1WRS; i2c.write(addr,cmd,1); #if OW_MASTER_DEBUG pc.printf("\r\n*** Reset all devices on the 1-Wire Net\r\n"); #endif do { i2c.read(addr,cmd,1); // pc.printf("\n read %04x",cmd[0]); } while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); // check for failure due to poll limit reached if (poll_count >= POLL_LIMIT) { // handle error // ... #if OW_MASTER_DEBUG pc.printf("\r\n---poll limit reached"); #endif reset(); return false; } // check for short condition if (cmd[0] & DS2482_STATUS_SD) { #if OW_MASTER_DEBUG pc.printf("\r\n---1-Wire Net short detected %04x",cmd[0]); #endif short_detected = true; } else { #if OW_MASTER_DEBUG pc.printf("\r\n*** 1-Wire electrical net is OK"); #endif short_detected = false; } // check for presence detect if (cmd[0] & DS2482_STATUS_PPD) { #if OW_MASTER_DEBUG pc.printf("\r\n*** 1-Wire Device detected"); #endif return true; } else { #if OW_MASTER_DEBUG pc.printf("\r\n---No Device detected"); #endif return false; } } //-------------------------------------------------------------------------- // Send 1 bit of communication to the 1-Wire Net. // The parameter 'sendbit' least significant bit is used. // // 'sendbit' - 1 bit to send (least significant byte) // void DS2482::OWWriteBit(uint8_t sendbit) { OWTouchBit(sendbit); } //-------------------------------------------------------------------------- // Reads 1 bit of communication from the 1-Wire Net and returns the // result // // Returns: 1 bit read from 1-Wire Net // uint8_t DS2482::OWReadBit(void) { return OWTouchBit(0x01); } //-------------------------------------------------------------------------- // Send 1 bit of communication to the 1-Wire Net and return the // result 1 bit read from the 1-Wire Net. The parameter 'sendbit' // least significant bit is used and the least significant bit // of the result is the return bit. // // 'sendbit' - the least significant bit is the bit to send // // Returns: 0: 0 bit read from sendbit // 1: 1 bit read from sendbit // uint8_t DS2482::OWTouchBit(uint8_t sendbit) { char cmd[2]; uint8_t poll_count = 0; cmd[0] = DS2482_CMD_1WSB; cmd[1] = sendbit ? 0x80 : 0x00; i2c.write(addr, cmd, 2); // loop checking 1WB bit for completion of 1-Wire operation // abort if poll limit reached do { i2c.read(addr, cmd, 1); } while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); #if OW_MASTER_DEBUG pc.printf("\r\n*** Send 1 bit to the 1-Wire Net"); #endif // check for failure due to poll limit reached if (poll_count >= POLL_LIMIT) { // handle error // ... #if OW_MASTER_DEBUG pc.printf("\r\n---handle error OW Write Bit"); #endif reset(); return 0; } // return bit state if (cmd[0] & DS2482_STATUS_SBR) { return 1; } else { return 0; } } //-------------------------------------------------------------------------- // Send 8 bits of communication to the 1-Wire Net and verify that the // 8 bits read from the 1-Wire Net are the same (write operation). // The parameter 'sendbyte' least significant 8 bits are used. // // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: TRUE: bytes written and echo was the same // FALSE: echo was not the same // void DS2482::OWWriteByte(uint8_t sendbyte) { char cmd[2]; uint8_t poll_count = 0; #if OW_MASTER_DEBUG pc.printf("\r\n*** Send 8 bits of WRITE to the 1-Wire Net"); #endif cmd[0] = DS2482_CMD_1WWB; cmd[1] = sendbyte; i2c.write(addr, cmd, 2); // loop checking 1WB bit for completion of 1-Wire operation // abort if poll limit reached do { i2c.read(addr, cmd, 1); } while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); // check for failure due to poll limit reached if (poll_count >= POLL_LIMIT) { // handle error // ... #if OW_MASTER_DEBUG pc.printf("\r\n---handle error OW Write Byte"); #endif reset(); } #if OW_MASTER_DEBUG pc.printf(" done"); #endif } //-------------------------------------------------------------------------- // Send 8 bits of read communication to the 1-Wire Net and return the // result 8 bits read from the 1-Wire Net. // // Returns: 8 bits read from 1-Wire Net // uint8_t DS2482::OWReadByte(void) { uint8_t poll_count = 0; char cmd[2]; #if OW_MASTER_DEBUG pc.printf("\r\n*** Read 8 bits from the 1-Wire Net"); #endif cmd[0] = DS2482_CMD_1WRB; // DS2482 1-Wire Read Byte i2c.write(addr, cmd, 1); // loop checking 1WB bit for completion of 1-Wire operation // abort if poll limit reached do { i2c.read(addr, cmd, 1); } while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); // check for failure due to poll limit reached if (poll_count >= POLL_LIMIT) { // handle error // ... #if OW_MASTER_DEBUG pc.printf("\r\n---handle error OW Read Byte"); #endif reset(); return 0; } cmd[0] = DS2482_CMD_SRP; // DS2482 Set Read Pointer cmd[1] = DS2482_READPTR_RDR; // DS2482 Read Data Register i2c.write(addr, cmd, 2); i2c.read(addr, cmd, 1); return cmd[0]; } //-------------------------------------------------------------------------- // The 'OWBlock' transfers a block of data to and from the // 1-Wire Net. The result is returned in the same buffer. // // 'tran_buf' - pointer to a block of unsigned // chars of length 'tran_len' that will be sent // to the 1-Wire Net // 'tran_len' - length in bytes to transfer // void DS2482::OWBlock(uint8_t *tran_buf, uint8_t tran_len) { uint8_t i; for (i = 0; i < tran_len; i++) { tran_buf[i] = OWTouchByte(tran_buf[i]); } } //-------------------------------------------------------------------------- // Send 8 bits of communication to the 1-Wire Net and return the // result 8 bits read from the 1-Wire Net. The parameter 'sendbyte' // least significant 8 bits are used and the least significant 8 bits // of the result are the return byte. // // 'sendbyte' - 8 bits to send (least significant byte) // // Returns: 8 bits read from sendbyte // uint8_t DS2482::OWTouchByte(uint8_t sendbyte) { if (sendbyte == 0xFF) { return OWReadByte(); } else { OWWriteByte(sendbyte); return sendbyte; } } //-------------------------------------------------------------------------- // Search state //-------------------------------------------------------------------------- // Find the 'first' devices on the 1-Wire network // Return TRUE : device found, ROM number in ROM_NO buffer // FALSE : no device present // uint8_t DS2482::OWFirst(void) { // reset the search state LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; #if OW_MASTER_DEBUG pc.printf("\r\n*** Find the 'first' device on the 1-Wire network"); #endif return OWSearch(); } //-------------------------------------------------------------------------- // Find the 'next' devices on the 1-Wire network // Return TRUE : device found, ROM number in ROM_NO buffer // FALSE : device not found, end of search // uint8_t DS2482::OWNext(void) { #if OW_MASTER_DEBUG pc.printf("\r\n*** Find the 'next' device on the 1-Wire network"); #endif // leave the search state alone return OWSearch(); } //-------------------------------------------------------------------------- // Verify the device with the ROM number in ROM_NO buffer is present. // Return TRUE : device present // FALSE : device not present // int DS2482::OWVerify(void) { uint8_t rom_backup[8], status; int i,ld_backup,ldf_backup,lfd_backup; // keep a backup copy of the current state for (i = 0; i < 8; i++) { rom_backup[i] = ROM_NO[i]; } ld_backup = LastDiscrepancy; ldf_backup = LastDeviceFlag; lfd_backup = LastFamilyDiscrepancy; // set search to find the same device LastDiscrepancy = 64; LastDeviceFlag = FALSE; if (OWSearch()) { // check if same device found status = TRUE; for (i = 0; i < 8; i++) { if (rom_backup[i] != ROM_NO[i]) { status = FALSE; break; } } } else { status = FALSE; } // restore the search state for (i = 0; i < 8; i++) { ROM_NO[i] = rom_backup[i]; } LastDiscrepancy = ld_backup; LastDeviceFlag = ldf_backup; LastFamilyDiscrepancy = lfd_backup; // return the result of the verify #if OW_MASTER_DEBUG pc.printf("\r\n*** 1-Wire Verify device with the ROM number in ROM_NO"); #endif return status; } //-------------------------------------------------------------------------- // Setup the search to find the device type 'family_code' on the next call // to OWNext() if it is present. // void DS2482::OWTargetSetup(uint8_t family_code) { uint8_t i; // set the search state to find SearchFamily type devices ROM_NO[0] = family_code; for (i = 1; i < 8; i++) { ROM_NO[i] = 0; } LastDiscrepancy = 64; LastFamilyDiscrepancy = 0; LastDeviceFlag = FALSE; } //-------------------------------------------------------------------------- // Setup the search to skip the current device type on the next call // to OWNext(). // void DS2482::OWFamilySkipSetup(void) { // set the Last discrepancy to last family discrepancy LastDiscrepancy = LastFamilyDiscrepancy; // clear the last family discrpepancy LastFamilyDiscrepancy = 0; // check for end of list if (LastDiscrepancy == 0) { LastDeviceFlag = TRUE; } } //-------------------------------------------------------------------------- // The 'OWSearch' function does a general search. This function // continues from the previous search state. The search state // can be reset by using the 'OWFirst' function. // This function contains one parameter 'alarm_only'. // When 'alarm_only' is TRUE (1) the find alarm command // 0xEC is sent instead of the normal search command 0xF0. // Using the find alarm command 0xEC will limit the search to only // 1-Wire devices that are in an 'alarm' state. // // Returns: TRUE (1) : when a 1-Wire device was found and its // Serial Number placed in the global ROM // FALSE (0): when no new device was found. Either the // last search was the last device or there // are no devices on the 1-Wire Net. // uint8_t DS2482::OWSearch() { int id_bit_number; int last_zero, rom_byte_number, search_result; int id_bit, cmp_id_bit; uint8_t rom_byte_mask, search_direction, status; // initialize for search id_bit_number = 1; last_zero = 0; rom_byte_number = 0; rom_byte_mask = 1; search_result = FALSE; crc_value = 0; #if OW_MASTER_DEBUG pc.printf("\r\n*** one wire search"); #endif if (!LastDeviceFlag) // if the last call was not the last one { // 1-Wire reset if (!OWReset()) { // reset the search LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; return FALSE; } // issue the search command OWWriteByte(OW_SEARCH_ROM); // loop to do the search do { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if (id_bit_number < LastDiscrepancy) { if ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0) search_direction = 1; else search_direction = 0; } else { // if equal to last pick 1, if not then pick 0 if (id_bit_number == LastDiscrepancy) search_direction = 1; else search_direction = 0; } // Perform a triple operation on the DS2482 which will perform 2 read bits and 1 write bit //pc.printf("\n *** preform triplet operation "); status = search_triplet(search_direction); //pc.printf("%04x",status); // check bit results in status byte id_bit = ((status & DS2482_STATUS_SBR) == DS2482_STATUS_SBR); cmp_id_bit = ((status & DS2482_STATUS_TSB) == DS2482_STATUS_TSB); search_direction = ((status & DS2482_STATUS_DIR) == DS2482_STATUS_DIR) ? 1 : 0; // check for no devices on 1-Wire if ((id_bit) && (cmp_id_bit)) { break; } else { if ((!id_bit) && (!cmp_id_bit) && (search_direction == 0)) { last_zero = id_bit_number; // check for Last discrepancy in family if (last_zero < 9) { LastFamilyDiscrepancy = last_zero; } } // set or clear the bit in the ROM byte rom_byte_number // with mask rom_byte_mask if (search_direction == 1) { ROM_NO[rom_byte_number] |= rom_byte_mask; } else { ROM_NO[rom_byte_number] &= ~rom_byte_mask; } // increment the byte counter id_bit_number // and shift the mask rom_byte_mask id_bit_number++; rom_byte_mask <<= 1; // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask if (rom_byte_mask == 0) { crc_calc(ROM_NO[rom_byte_number]); // accumulate the CRC rom_byte_number++; rom_byte_mask = 1; } } } while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 // if the search was successful then if (!((id_bit_number < 65) || (crc_value != 0))) { // search successful so set LastDiscrepancy,LastDeviceFlag,search_result LastDiscrepancy = last_zero; // check for last device if (LastDiscrepancy == 0) { LastDeviceFlag = TRUE; } search_result = TRUE; } } // if no device found then reset counters so next 'search' will be like a first if (!search_result || (ROM_NO[0] == 0)) { LastDiscrepancy = 0; LastDeviceFlag = FALSE; LastFamilyDiscrepancy = 0; search_result = FALSE; } #if OW_MASTER_DEBUG pc.printf(" pass "); #endif return search_result; } //-------------------------------------------------------------------------- // Use the DS2482 help command '1-Wire triplet' to perform one bit of a // 1-Wire search. // This command does two read bits and one write bit. The write bit // is either the default direction (all device have same bit) or in case of // a discrepancy, the 'search_direction' parameter is used. // // Returns – The DS2482 status byte result from the triplet command // uint8_t DS2482::search_triplet(uint8_t search_direction) { char cmd[2]; uint8_t status, poll_count = 0; cmd[0] = DS2482_CMD_1WT; cmd[1] = (search_direction ? 0x80 : 0x00); i2c.write(addr,cmd,2); do { i2c.read(addr,cmd,1); status = cmd[0]; } while ((status & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); // check for failure due to poll limit reached if (poll_count >= POLL_LIMIT) { // handle error // ... reset(); return 0; } // return status byte return status; } //-------------------------------------------------------------------------- // Set the 1-Wire Net communication speed. // // 'new_speed' - new speed defined as // MODE_STANDARD 0x00 // MODE_OVERDRIVE 0x01 // // Returns: current 1-Wire Net speed // uint8_t DS2482::OWSpeed(uint8_t new_speed) { // set the speed if (new_speed == MODE_OVERDRIVE) { c1WS = DS2482_CFG_1WS; } else { c1WS = FALSE; } // write the new config write_config(c1WS | cSPU | cPPM | cAPU); return new_speed; } //-------------------------------------------------------------------------- // Set the 1-Wire Net line level pullup to normal. The DS2482 only // allows enabling strong pullup on a bit or byte event. // Consequently this function only allows the MODE_STANDARD argument. // To enable strong pullup // use OWWriteBytePower or OWReadBitPower. // // 'new_level' - new level defined as // MODE_STANDARD 0x00 // // Returns: current 1-Wire Net level // uint8_t DS2482::OWLevel(uint8_t new_level) { // function only will turn back to non-strong pullup if (new_level != MODE_STANDARD) { return MODE_STRONG; } // clear the strong pullup bit in the global config state cSPU = FALSE; // write the new config write_config(c1WS | cSPU | cPPM | cAPU); return MODE_STANDARD; } //-------------------------------------------------------------------------- // Send 1 bit of communication to the 1-Wire Net and verify that the // response matches the 'applyPowerResponse' bit and apply power delivery // to the 1-Wire net. Note that some implementations may apply the power // first and then turn it off if the response is incorrect. // // 'applyPowerResponse' - 1 bit response to check, if correct then start // power delivery // // Returns: TRUE: bit written and response correct, strong pullup now on // FALSE: response incorrect // uint8_t DS2482::OWReadBitPower(uint8_t applyPowerResponse) { uint8_t rdbit; // set strong pullup enable cSPU = DS2482_CFG_SPU; // write the new config if (!write_config(c1WS | cSPU | cPPM | cAPU)) { return FALSE; } // perform read bit rdbit = OWReadBit(); // check if response was correct, if not then turn off strong pullup if (rdbit != applyPowerResponse) { OWLevel(MODE_STANDARD); return FALSE; } return TRUE; } //-------------------------------------------------------------------------- // Send 8 bits of communication to the 1-Wire Net and verify that the // 8 bits read from the 1-Wire Net are the same (write operation). // The parameter 'sendbyte' least significant 8 bits are used. After the // 8 bits are sent change the level of the 1-Wire net. // // 'sendbyte' - 8 bits to send (least significant bit) // // Returns: TRUE: bytes written and echo was the same, strong pullup now on // FALSE: echo was not the same // uint8_t DS2482::OWWriteBytePower(uint8_t sendbyte) { // set strong pullup enable cSPU = DS2482_CFG_SPU; // write the new config if (!write_config(c1WS | cSPU | cPPM | cAPU)) { #if OW_MASTER_DEBUG pc.printf("\r\nSPU off"); #endif return FALSE; } // perform write byte OWWriteByte(sendbyte); return TRUE; } // end I2C DS2482 //====================================================================== //--------------------------------------------------------------------------- //-------------------------DS18XX OPERATIONS--------------------------------- //--------------------------------------------------------------------------- // find ALL devices on bus 1 // void DS2482::DS18XX_Read_Address(void) { uint8_t status, i, j; //-------------------------------------------------------------- // Device Tabele für bus 1 und bus 2 löschen for (i = 0; i < OW_MAX_DEVICES; i++) { for (j = 0; j < 8; j++) { ow.device_table[i].rom[j] = 0; } } // pc.printf("\n --- DS18xx_Read_Address --- "); // wait(0.1); ow.devices = 0; //-------------------------------------------------------------- // die Bausteine am Bus suchen //pc.printf("\n -- detect -- \n"); //wait(0.5); detect(); // reset and init the 1-wire master //pc.printf("\n -- OWFirst --\n"); //wait(0.1); status = OWFirst(); if(status == 0) { #if OW_MASTER_START pc.printf("\r\nno 1-Wire slaves found"); #endif } while(status) { // TODO hier ins eeprom schreiben #if OW_MASTER_START pc.printf("\n*** #%02d ROM_NO= ",ow.devices); wait(0.1); #endif for (uint8_t i = 0; i < 8; i++) { ow.device_table[ow.devices].rom[i] = ROM_NO[i]; #if OW_MASTER_START pc.printf(" 0x%02x",ROM_NO[i]); wait (0.1); #endif } ow.device_table[ow.devices].status = 0x01; // Wandler gefunden status = OWNext(); ow.devices++; // Zeiger auf den nächsten freien Baustein // maximal 16 Bausteine if (ow.devices >= OW_MAX_DEVICES) { ow.devices--; // zeiget auf den letzten gültigen Baustein return; } } #if OW_MASTER_START pc.printf("\r\n"); #endif return; } //--------------------------------------------------------------------------- // void DS2482::start_conversion(void) { //-------------------------------------------------------------- // alle Bausteine an bus 0 starten // find a DS18S20 OWFirst(); OWReset(); // address all devices OWWriteByte(OW_SKIP_ROM); // Start Conversion and Config Strong Pull-Up if (!OWWriteBytePower(OW_CONVERT_TEMP)) { #if OW_MASTER_DEBUG pc.printf("Fail convert command\r\n"); #endif } //-------------------------------------------------------------- // alle Bausteine an bus 1 starten // find a DS18S20 OWFirst(); OWReset(); // address all devices OWWriteByte(OW_SKIP_ROM); // Start Conversion and Config Strong Pull-Up if (!OWWriteBytePower(OW_CONVERT_TEMP)) { #if OW_MASTER_DEBUG pc.printf("Fail convert command\r\n"); #endif } } //----------------------------------------------------------------------------- bool DS2482::ow_read_rom(void) { uint8_t n; // Write Read ROM Code command OWWriteByte(OW_CMD_READ_ROM); // Read 8 bytes of ROM code for (n = 0; n < 8; n++) { ow_rom_code[n] = OWReadByte(); } // Do Cyclic Redundancy Check if (crc_calc_buffer(&ow_rom_code[0],7) != ow_rom_code[7]) { ow_flags |= OW_CRC_ERROR; return false; } return true; } //----------------------------------------------------------------------------- bool DS2482::ow_read_scratchpad(void) { uint8_t i, crc; ow_flags = 0; if (!OWReset()) return false; // select the device // den Baustein wird über den ROM Code adressiert OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command for (i = 0; i < 8; i++) { OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); } OWWriteByte(OW_CMD_READ_SCRATCHPAD); // Read Scratch pad 0xBE // Read 9 bytes of scratchpad memory for (i = 0; i < OW_SCRATCHPAD_BYTES; i++) { crc = OWReadByte(); ow_scratchpad[i] = crc; } #if OW_MASTER_DEBUG pc.printf("\n*** Scratch_Val "); for (i = 1; i < OW_SCRATCHPAD_BYTES; i++) { pc.printf(":0x%02x",ow_scratchpad[i]); } pc.printf("\r\n"); #endif return true; } //----------------------------------------------------------------------------- bool DS2482::ow_read_scratchpad_ds2438(uint8_t page) { uint8_t n, crc; ow_flags = 0; if (!OWReset()) return false; // select the device // den Baustein wird über den ROM Code adressiert OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command for (n = 0; n < 8; n++) { OWWriteByte(ow.device_table[ow.device_table_index].rom[n]); } // Write command to read scratchpad memory OWWriteByte(0xbe); // 0xBE OWWriteByte(page); // 0x03 // Read 9 bytes of scratchpad memory for (n = 0; n < OW_SCRATCHPAD_BYTES; n++) { crc = OWReadByte(); ow_scratchpad[n] = crc; // printf_P(PSTR("%02x "),crc); } crc = crc_calc_buffer(ow_scratchpad,8); // Calculate CRC if (crc != ow_scratchpad[8]) { ow_flags |= OW_CRC_ERROR; // Read 9 bytes of scratchpad memory pc.printf("\now_read_scratchpad: "); for (n = 0; n < OW_SCRATCHPAD_BYTES; n++) { pc.printf("%02x ",ow_scratchpad[n]); } pc.printf(": CRC error %02x",crc); return false; } return true; } //---------------------------------------------------------------------------- bool DS2482::ow_write_scratchpad_ds18x20 (uint8_t th, uint8_t tl) { uint8_t i; // Do bus reset if (!OWReset()) return false; // select the device // den Baustein wird über den ROM Code adressiert OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command for (i = 0; i < 8; i++) { OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); } // Write command to read scratchpad memory OWWriteByte(OW_CMD_WRITE_SCRATCHPAD); // Write 1 byte at scratchpad memory OWWriteByte(th); // Th wait_us(8); // ist für das Timing der 8 MHZ CPU notwendig // Write 1 byte at scratchpad memory OWWriteByte(tl); // Th wait_us(8); // ist für das Timing der 8 MHZ CPU notwendig // Write 1 byte at scratchpad memory OWWriteByte(0x7F); // 12 Bit Auflösung wait_us(8); // ist für das Timing der 8 MHZ CPU notwendig return true; } //---------------------------------------------------------------------------- bool DS2482::ow_write_scratchpad_ds2438 (uint8_t th, uint8_t tl) { uint8_t i; // Do bus reset if (!OWReset()) return false; // select the device // den Baustein wird über den ROM Code adressiert OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command for (i = 0; i < 8; i++) { OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); } // Write command to read scratchpad memory OWWriteByte(0x4E); OWWriteByte(0x03); // Write 3 bytes to scratchpad memory OWWriteByte(th); // Th wait_us(8); OWWriteByte(tl); // Tl wait_us(8); return true; } //---------------------------------------------------------------------------- bool DS2482::ow_write_eeprom_ds18x20 (void) { uint8_t i; // Do bus reset if (!OWReset()) return false; // select the device // den Baustein wird über den ROM Code adressiert OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command for (i = 0; i < 8; i++) { OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); } // Write command to write eeprom OWWriteByte(0x48); return true; } //---------------------------------------------------------------------------- bool DS2482::ow_write_eeprom_ds2438 (void) { uint8_t i; // Do bus reset if (!OWReset()) return false; // select the device // den Baustein wird über den ROM Code adressiert OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command for (i = 0; i < 8; i++) { OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); } // Write command to read scratchpad memory OWWriteByte(0x48); OWWriteByte(0x03); return true; } //---------------------------------------------------------------------------- void DS2482::ow_read_address (void) { uint8_t n; // ow Adressen aus den Bausteinen lesen for (n = 0; n < OW_MAX_DEVICES; n++) { if ((ow.device_table[n].status & 0x0f) == 1) { // printf_P(PSTR("\n device table %d"),n); ow.device_table_index = n; if ((ow.device_table[n].rom[0] == 0x10) || (ow.device_table[n].rom[0] == 0x28)) { if (ow_read_scratchpad()) { if(ow_scratchpad[2] == ow_scratchpad[3]) ow.device_table[n].adr = ow_scratchpad[3]; } } if ((ow.device_table[n].rom[0] == 0xa6) || (ow.device_table[n].rom[0] == 0x26)) { if (ow_read_scratchpad_ds2438(0x03)) { if(ow_scratchpad[0] == ow_scratchpad[1]) ow.device_table[n].adr = ow_scratchpad[0]; } } } } // end for(... } //----------------------------------------------------------------------------- bool DS2482::ds1820_start_conversion(uint8_t command) { uint8_t i; // Do bus reset if (!OWReset()) return false; // Check if a match ROM code must be done or just skip ROM code (0xFF) if (command > 0xFE) { OWWriteByte(OW_CMD_SKIP_ROM); // Send Skip ROM Code command } else { // select the device // den Baustein wird über den ROM Code adressiert OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command for (i = 0; i < 8; i++) { OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); } } // Send the "Convert T" command to start conversion OWWriteByte(OW_CMD_CONVERT_T); // Set flag to mark a measurement in progress ds1820_request_pending = true; return TRUE; } //----------------------------------------------------------------------------- bool DS2482::ds18B20_read_hrtemp(void) { union ds18B20_temp_union { int16_t word; uint8_t byte[2]; } ds18B20_temp; // uint8_t temp_lo; // uint8_t temp_hi; // int8_t digit; float ds1820_float_result; // Preset float result to zero in case of function termination (return false) //ds1820_float_result = 0.0; ow.device_table[ow.device_table_index].result = 0; // Return false if reading scratchpad memory fails if (!ow_read_scratchpad()) { ow.device_table[ow.device_table_index].status &= 0xf0; ow.device_table[ow.device_table_index].status |= 4; return FALSE; } ds18B20_temp.byte[0] = ow_scratchpad[DS1820_LSB]; ds18B20_temp.byte[1] = ow_scratchpad[DS1820_MSB]; //ds18B20_temp.word <<= 4; // Vorzeichenbit auf MSB Bit schieben //ds18B20_temp.word /= 16; // die letzten 4 Stellen wieder löschen ds1820_float_result = ds18B20_temp.word * 0.0625; //pc.printf("\nDS18B20 T-Kanal: %d = %2.2f ",ow.device_table_index,ds1820_float_result); ow.device_table[ow.device_table_index].result = (int16_t)(ds1820_float_result * 100); // Clear flag to mark that no measurement is in progress ds1820_request_pending = false; // Flag für erfolgreiches Lesen setzen ow.device_table[ow.device_table_index].status &= 0xf0; ow.device_table[ow.device_table_index].status |= 3; return true; } //-----------------------------------------------------------------------------