Files
templates/c/ds18b20/instance/Tests/test_ds18b20_copy_delay.c

93 lines
2.9 KiB
C

#include "ds18b20.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
typedef struct {
uint8_t scratchpad[DS18B20_SCRATCHPAD_SIZE];
uint16_t read_call;
uint32_t max_delay_us;
uint16_t copy_delay_chunks;
uint8_t critical_active;
} mock_port_t;
static void drive_low(void *context) { (void)context; }
static void release_line(void *context) { (void)context; }
static uint8_t read_line(void *context)
{
mock_port_t *port = (mock_port_t *)context;
uint16_t call = port->read_call++;
assert(port->critical_active); /* Presence and data sampling must be protected. */
if (call == 0U) return 0U; /* Read Scratchpad reset presence. */
if (call <= 72U) {
uint16_t bit = (uint16_t)(call - 1U);
return (uint8_t)((port->scratchpad[bit / 8U] >> (bit % 8U)) & 1U);
}
/* Write Scratchpad and Copy Scratchpad reset presence pulses. */
return 0U;
}
static void delay_us(void *context, uint32_t us)
{
mock_port_t *port = (mock_port_t *)context;
if (us > port->max_delay_us) port->max_delay_us = us;
if (us == 100U) port->copy_delay_chunks++;
}
static void critical_enter(void *context)
{
mock_port_t *port = (mock_port_t *)context;
assert(!port->critical_active);
port->critical_active = 1U;
}
static void critical_exit(void *context)
{
mock_port_t *port = (mock_port_t *)context;
assert(port->critical_active);
port->critical_active = 0U;
}
int main(void)
{
static const ds18b20_onewire_ops_t ops = {
drive_low, release_line, read_line, delay_us, NULL, critical_enter, critical_exit, NULL
};
ds18b20_t bus;
mock_port_t port;
uint8_t roms[1][DS18B20_ROM_SIZE] = {{0}};
memset(&port, 0, sizeof(port));
roms[0][0] = 0x28U;
roms[0][1] = 0x11U;
roms[0][7] = ds18b20_crc8(roms[0], 7U);
port.scratchpad[0] = 0x50U;
port.scratchpad[1] = 0x05U;
port.scratchpad[2] = 0x4BU;
port.scratchpad[3] = 0x46U;
port.scratchpad[4] = 0x7FU;
port.scratchpad[5] = 0xFFU;
port.scratchpad[6] = 0x0CU;
port.scratchpad[7] = 0x10U;
port.scratchpad[8] = ds18b20_crc8(port.scratchpad, 8U);
assert(ds18b20_init(&bus, &ops, &port, roms, 1U) == DS18B20_OK);
bus.rom_count = 1U;
assert(ds18b20_set_resolution(&bus, roms[0], 9U) == DS18B20_OK);
/* Regression: a 10 ms callback overflows the 16-bit 72 MHz timer port. */
assert(port.max_delay_us <= 480U);
assert(port.copy_delay_chunks >= 100U);
bus.rom_count = 0U;
assert(ds18b20_search_retry_due(&bus, 0U, 1999U, 0U, 2000U) == 0U);
assert(ds18b20_search_retry_due(&bus, 0U, 2000U, 0U, 2000U) == 1U);
assert(ds18b20_search_retry_due(&bus, 1U, 4000U, 0U, 2000U) == 0U);
/* Wrap-safe deadline: 0x20 - 0xFFFFFF00 = 0x120 ms. */
assert(ds18b20_search_retry_due(&bus, 0U, 0x20U, 0xFFFFFF00U, 0x120U) == 1U);
bus.rom_count = 1U;
assert(ds18b20_search_retry_due(&bus, 0U, 4000U, 0U, 2000U) == 0U);
puts("DS18B20 copy delay regression: OK");
return 0;
}