You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.3 KiB
130 lines
3.3 KiB
6 years ago
|
//
|
||
|
// Created by MightyPork on 2018/02/03.
|
||
|
//
|
||
|
|
||
|
#include "platform.h"
|
||
|
#include "unit_1wire.h"
|
||
|
|
||
|
// 1WIRE master
|
||
|
#define OW_INTERNAL
|
||
|
#include "_ow_internal.h"
|
||
|
#include "_ow_commands.h"
|
||
|
#include "_ow_low_level.h"
|
||
|
|
||
|
/* Check presence of any devices on the bus */
|
||
|
error_t UU_1WIRE_CheckPresence(Unit *unit, bool *presence)
|
||
|
{
|
||
|
CHECK_TYPE(unit, &UNIT_1WIRE);
|
||
|
// reset
|
||
|
*presence = ow_reset(unit);
|
||
|
return E_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* Read address of a lone device on the bus */
|
||
|
error_t UU_1WIRE_ReadAddress(Unit *unit, uint64_t *address)
|
||
|
{
|
||
|
CHECK_TYPE(unit, &UNIT_1WIRE);
|
||
|
*address = 0;
|
||
|
if (!ow_reset(unit)) return E_HW_TIMEOUT;
|
||
|
|
||
|
// command
|
||
|
ow_write_u8(unit, OW_ROM_READ);
|
||
|
|
||
|
// read the ROM code
|
||
|
*address = ow_read_u64(unit);
|
||
|
|
||
|
const uint8_t *addr_as_bytes = (void*)address;
|
||
|
if (0 != ow_checksum(addr_as_bytes, 8)) {
|
||
|
*address = 0;
|
||
|
return E_CHECKSUM_MISMATCH; // checksum mismatch
|
||
|
}
|
||
|
return E_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* Write bytes to a device */
|
||
|
error_t UU_1WIRE_Write(Unit *unit, uint64_t address, const uint8_t *buff, uint32_t len)
|
||
|
{
|
||
|
CHECK_TYPE(unit, &UNIT_1WIRE);
|
||
|
if (!ow_reset(unit)) return E_HW_TIMEOUT;
|
||
|
|
||
|
// MATCH_ROM+addr, or SKIP_ROM
|
||
|
if (address != 0) {
|
||
|
ow_write_u8(unit, OW_ROM_MATCH);
|
||
|
ow_write_u64(unit, address);
|
||
|
} else {
|
||
|
ow_write_u8(unit, OW_ROM_SKIP);
|
||
|
}
|
||
|
|
||
|
// write the payload;
|
||
|
for (uint32_t i = 0; i < len; i++) {
|
||
|
ow_write_u8(unit, *buff++);
|
||
|
}
|
||
|
return E_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* Write a request to a device and read a response */
|
||
|
error_t UU_1WIRE_Read(Unit *unit, uint64_t address,
|
||
|
const uint8_t *request_buff, uint32_t request_len,
|
||
|
uint8_t *response_buff, uint32_t response_len, bool check_crc)
|
||
|
{
|
||
|
CHECK_TYPE(unit, &UNIT_1WIRE);
|
||
|
if (!ow_reset(unit)) return E_HW_TIMEOUT;
|
||
|
|
||
|
uint8_t *rb = response_buff;
|
||
|
|
||
|
// MATCH_ROM+addr, or SKIP_ROM
|
||
|
if (address != 0) {
|
||
|
ow_write_u8(unit, OW_ROM_MATCH);
|
||
|
ow_write_u64(unit, address);
|
||
|
} else {
|
||
|
ow_write_u8(unit, OW_ROM_SKIP);
|
||
|
}
|
||
|
|
||
|
// write the payload;
|
||
|
for (uint32_t i = 0; i < request_len; i++) {
|
||
|
ow_write_u8(unit, *request_buff++);
|
||
|
}
|
||
|
|
||
|
// read the requested number of bytes
|
||
|
for (uint32_t i = 0; i < response_len; i++) {
|
||
|
*rb++ = ow_read_u8(unit);
|
||
|
}
|
||
|
|
||
|
if (check_crc) {
|
||
|
if (0 != ow_checksum(response_buff, response_len)) {
|
||
|
return E_CHECKSUM_MISMATCH;
|
||
|
}
|
||
|
}
|
||
|
return E_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* Perform the search algorithm (start or continue) */
|
||
|
error_t UU_1WIRE_Search(Unit *unit, bool with_alarm, bool restart,
|
||
|
uint64_t *buffer, uint32_t capacity, uint32_t *real_count,
|
||
|
bool *have_more)
|
||
|
{
|
||
|
CHECK_TYPE(unit, &UNIT_1WIRE);
|
||
|
struct priv *priv = unit->data;
|
||
|
|
||
|
if (restart) {
|
||
|
uint8_t search_cmd = (uint8_t) (with_alarm ? OW_ROM_ALM_SEARCH : OW_ROM_SEARCH);
|
||
|
ow_search_init(unit, search_cmd, true);
|
||
|
}
|
||
|
|
||
|
*real_count = ow_search_run(unit, (ow_romcode_t *) buffer, capacity);
|
||
|
|
||
|
// resolve the code
|
||
|
switch (priv->searchState.status) {
|
||
|
case OW_SEARCH_MORE:
|
||
|
*have_more = priv->searchState.status == OW_SEARCH_MORE;
|
||
|
|
||
|
case OW_SEARCH_DONE:
|
||
|
return E_SUCCESS;
|
||
|
|
||
|
case OW_SEARCH_FAILED:
|
||
|
return priv->searchState.error;
|
||
|
}
|
||
|
|
||
|
return E_INTERNAL_ERROR;
|
||
|
}
|