*/ uint16_t ReadDualSwitches( unsigned char bus_pattern, unsigned char * id ) { uint16_t value = 0x0; // continue if bus isn't active if ( 0 == ( ( owiBusMask & bus_pattern ) & 0xFF ) ) { return owiReadStatus_owi_bus_mismatch << 8; } // continue if bus doesn't contain any Dual Switches if ( 0 == ( ( owiDualSwitchMask & bus_pattern ) & 0xFF ) ) { return owiReadStatus_owi_bus_mismatch << 8; } /* Reset, presence.*/ if ( OWI_DetectPresence(bus_pattern) == 0 ) { return owiReadStatus_no_device_presence << 8; } OWI_MatchRom(id, bus_pattern); /* Match id found earlier*/ OWI_SendByte(DS2413_PIO_ACCESS_READ, bus_pattern); //PIO Access read command /*Read first byte and place them in the 16 bit channel variable*/ value = OWI_ReceiveByte(bus_pattern); value &= 0xFF; OWI_DetectPresence(bus_pattern); /* generate RESET to stop slave sending its status and presence pulse*/ return value | owiReadWriteStatus_OK << 8;
/***************************************************************************** * Function name : DS18B20_ReadDevice * Returns : коды - READ_CRC_ERROR, если считанные данные не прошли проверку * READ_SUCCESSFUL, если данные прошли проверку * Parameters : bus - вывод микроконтроллера, который выполн¤ет роль 1WIRE шины * *id - им¤ массива из 8-ми элементов, в котором хранитс¤ * адрес датчика DS18B20 * *temperature - указатель на шестнадцати разр¤дную переменную * в которой будет сохранено считанного зн. температуры * Purpose : ћетод только считывает значение ”∆≈ »«ћ≈–≈ЌЌќ… температуры из scratchpad, * Ќ≈ ¬џѕќЋЌя≈“ »«ћ≈–≈Ќ»≈ * јдресует датчик DS18B20, считывает его пам¤ть - scratchpad, провер¤ет CRC, * сохран¤ет значение температуры в переменной, возвращает код ошибки *****************************************************************************/ unsigned char DS18B20_ReadDevice(unsigned char bus, unsigned char* id, signed int* temperature){ unsigned char scratchpad[9]; OWI_DetectPresence(bus); OWI_MatchRom(id, bus); OWI_SendByte(DS18B20_READ_SCRATCHPAD, bus); for (unsigned char i = 0; i <= 8; i++){ scratchpad[i] = OWI_ReceiveByte(bus); } if(OWI_CheckScratchPadCRC(scratchpad) != OWI_CRC_OK){ return READ_CRC_ERROR; } *temperature = (unsigned int)scratchpad[0]; *temperature |= ((unsigned int)scratchpad[1] << 8); if ((*temperature & 0x8000) != 0){ *temperature = -(~(*temperature) + 1); } //*temperature *= 0.625f; *temperature *= 5; //0.625 = 5/8 *temperature /= 8; return READ_SUCCESSFUL; }
void OWI_ReadRom(myOneWire* ow) { uint8_t index; OWI_SendByte(ow, 0x33); for(index = 0; index < 8; index++) ow->address[index] = OWI_ReceiveByte(ow); return; }
/*! \brief Sends the READ ROM command and reads back the ROM id. * * \param romValue A pointer where the id will be placed. * * \param pin A bitmask of the bus to read from. */ void OWI_ReadRom( unsigned char * romValue, unsigned char pin ) { unsigned char bytesLeft = 8; // Send the READ ROM command on the bus. OWI_SendByte(OWI_ROM_READ, pin); // Do 8 times. while ( bytesLeft > 0 ) { // Place the received data in memory. *romValue++ = OWI_ReceiveByte(pin); bytesLeft--; } }
/***************************************************************************** * Function name : DS18B20_ReadTemperature * Returns : коды - READ_CRC_ERROR, если считанные данные не прошли проверку * READ_SUCCESSFUL, если данные прошли проверку * Parameters : bus - вывод микроконтроллера, который выполняет роль 1WIRE шины * *id - имя массива из 8-ми элементов, в котором хранится * адрес датчика DS18B20 * *ds18b20_temperature - указатель на шестнадцати разрядную переменную * в которой будет сохранено считанного зн. температуры * Purpose : Адресует датчик DS18B20, дает команду на преобразование температуры * ждет, считывает его память - scratchpad, проверяет CRC, * сохраняет значение температуры в переменной, возвращает код ошибки *****************************************************************************/ BYTE DS18B20_ReadTemperature(BYTE bus, BYTE * id, WORD* ds18b20_temperature) { unsigned char scratchpad[9]; unsigned char i; /*подаем сигнал сброса команду для адресации устройства на шине подаем команду - запук преобразования */ OWI_DetectPresence(bus); OWI_MatchRom(id, bus); OWI_SendByte(DS18B20_CONVERT_T ,bus); /*ждем, когда датчик завершит преобразование*/ while (!OWI_ReadBit(bus)); /*подаем сигнал сброса команду для адресации устройства на шине команду - чтение внутренней памяти затем считываем внутреннюю память датчика в массив */ OWI_DetectPresence(bus); OWI_MatchRom(id, bus); OWI_SendByte(DS18B20_READ_SCRATCHPAD, bus); for (i = 0; i<=8; i++){ scratchpad[i] = OWI_ReceiveByte(bus); } if(OWI_CheckScratchPadCRC(scratchpad) != OWI_CRC_OK){ return READ_CRC_ERROR; } *ds18b20_temperature = MAKEWORD(scratchpad[0], scratchpad[1]); return READ_SUCCESSFUL; }
/* *this function writes the state of dual switch */ uint16_t WriteDualSwitches( unsigned char bus_pattern, unsigned char * id, uint8_t value ) { static unsigned char timeout_flag; static uint32_t count; static uint8_t status; static uint32_t maxcount = OWI_DUAL_SWITCHES_MAXIMUM_WRITE_ACCESS_COUNTS; // continue if bus isn't active if ( 0 == ( ( owiBusMask & bus_pattern ) & 0xFF ) ) { return owiReadStatus_owi_bus_mismatch << 8; } // continue if bus doesn't contain any Dual Switches if ( 0 == ( ( owiDualSwitchMask & bus_pattern ) & 0xFF ) ) { return owiReadStatus_owi_bus_mismatch << 8; } /* Reset, presence.*/ if ( OWI_DetectPresence(bus_pattern) == 0 ) { return owiReadStatus_no_device_presence << 8; } count = maxcount; timeout_flag = FALSE; status = 0; /* Match id found earlier*/ OWI_MatchRom(id, bus_pattern); /* PIO Access write command */ OWI_SendByte(DS2413_PIO_ACCESS_WRITE, bus_pattern); /* loop writing value and its complement, and waiting for confirmation */ while (DS2413_WRITE_CONFIRMATION_PATTERN != status ) { status = 0; /* timeout check */ if ( 0 == --count) { timeout_flag = TRUE; break; } OWI_SendByte( (value |= 0xFC ), bus_pattern); // write value 0:on 1:off OWI_SendByte(~(value |= 0xFC ), bus_pattern); // to confirm, write inverted /*Read status */ status = OWI_ReceiveByte(bus_pattern); status &= 0xFF; } if ( FALSE == timeout_flag ) { /*Read first byte*/ value = OWI_ReceiveByte(bus_pattern); value &= 0xFF; OWI_DetectPresence(bus_pattern); /* generate RESET to stop slave sending its status and presence pulse*/ return value | owiReadWriteStatus_OK << 8; } else { OWI_DetectPresence(bus_pattern); /* generate RESET to stop slave sending its status and presence pulse*/ CommunicationError_p(ERRG, dynamicMessage_ErrorIndex, TRUE, PSTR("OWI Dual Switch write value timeout")); return value | owiWriteStatus_Timeout << 8; } return value | owiReadWriteStatus_OK << 8;
uint8_t owiADCMemoryWriteByte(unsigned char bus_pattern, unsigned char * id, uint16_t address, uint8_t data, uint8_t maxTrials) { uint16_t receive_CRC; uint8_t flag = FALSE; uint8_t verificationData = 0x0; uint8_t trialsCounter = maxTrials; printDebug_p(debugLevelEventDebug, debugSystemOWIADC, __LINE__, filename, PSTR("writing to ADC memory address: %#x \tdata: %#x"),address, data); /* 0 trials, give it a chance */ if (0 == trialsCounter) { trialsCounter++;} while ( FALSE == flag && trialsCounter != 0) { /* select one or all, depending if id is given */ if ( id == NULL) { /* * SKIP ROM [CCH] * * This command can save time in a single drop bus system by allowing the bus master to access the * memory/ convert functions without providing the 64-bit ROM code. If more than one slave is present on * the bus and a read command is issued following the Skip ROM command, data collision will occur on the * bus as multiple slaves transmit simultaneously (open drain pulldowns will produce a wired-AND result). */ OWI_SendByte(OWI_ROM_SKIP, bus_pattern); } else { /* * MATCH ROM [55H] * * The match ROM command, followed by a 64-bit ROM sequence, allows the bus master to address a * specific DS2450 on a multidrop bus. Only the DS2450 that exactly matches the 64-bit ROM sequence * will respond to the following memory/convert function command. All slaves that do not match the 64-bit * ROM sequence will wait for a reset pulse. This command can be used with a single or multiple devices * on the bus. */ OWI_MatchRom(id, bus_pattern); // Match id found earlier } /* * WRITE MEMORY [55H] * * The Write Memory command is used to write to memory pages 1 and 2 in order to set the channel specific * control data and alarm thresholds. The command can also be used to write the single control byte * on page 3 at address 1Ch. The bus master will follow the command byte with a two byte starting address * (TA1=(T7:T0), TA2=(T15:T8)) and a data byte of (D7:D0). A 16-bit CRC of the command byte, address * bytes, and data byte is computed by the DS2450 and read back by the bus master to confirm that the * correct command word, starting address, and data byte were received. Now the DS2450 copies the data * byte to the specified memory location. With the next eight time slots the bus master receives a copy of * the same byte but read from memory for verification. If the verification fails, a Reset Pulse should be * issued and the current byte address should be written again. * If the bus master does not issue a Reset Pulse and the end of memory was not yet reached, the DS2450 * will automatically increment its address counter to address the next memory location. The new two-byte * address will also be loaded into the 16-bit CRC-generator as a starting value. The bus master will send * the next byte using eight write time slots. As the DS2450 receives this byte it also shifts * it into the CRCgenerator and the result is a 16-bit CRC of the new data byte and the new address. * With the next sixteen read time slots the bus master * will read this 16-bit CRC from the DS2450 to verify that the address * incremented properly and the data byte was received correctly. Following the CRC the master receives * the byte just written as read from the memory. If the CRC or read-back byte is incorrect, a Reset Pulse * should be issued in order to repeat the Write Memory command sequence. * Note that the initial pass through the Write Memory flow chart will generate a 16-bit CRC value that is * the result of shifting the command byte into the CRC-generator, followed by the two address bytes, and * finally the data byte. Subsequent passes through the Write Memory flow chart due to the DS2450 * automatically incrementing its address counter will generate a 16-bit CRC that is the result of loading (not * shifting) the new (incremented) address into the CRC-generator and then shifting in the new data byte. * The decision to continue after having received a bad CRC or if the verification fails is made entirely by * the bus master. Write access to the conversion read-out registers is not possible. If a write attempt is * made to a page 0 address the device will follow the Write Memory flow chart correctly but the * verification of the data byte read back from memory will usually fail. The Write Memory command * sequence can be ended at any point by issuing a Reset Pulse. * */ OWI_SendByte(DS2450_WRITE_MEMORY, bus_pattern); OWI_SendWord(address, bus_pattern); OWI_SendByte(data, bus_pattern); /* receive 16bit CRC */ receive_CRC = OWI_ReceiveWord(bus_pattern); /* IMPORTANT AFTER EACH 'MEMORY WRITE' OPERATION to start memory writing*/ /* only possible if there is not OWI_ROM_SKIP, so wait until this device specific is implemented*/ if (id != NULL) { #warning TODO: add a complex check on the CRC, including the correct address, if in single device mode /*verify written data*/ verificationData = OWI_ReceiveByte(bus_pattern); if ( data == verificationData ) /* check passed */ { flag = TRUE; } else { trialsCounter--; } } else { flag = TRUE; } /* ending the Write Memory command sequence by issuing a Reset Pulse*/ OWI_DetectPresence(bus_pattern); /*the "DetectPresence" function includes sending a Reset Pulse*/ } /*end of while loop */ if (FALSE == flag) { return 1; } else { return 0; } }