-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathowtemp.c
More file actions
109 lines (90 loc) · 3.19 KB
/
owtemp.c
File metadata and controls
109 lines (90 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* owtemp.c - 1-Wire temperature sensor DS1820B driver
*
* Created on: 28.03.2013
* Author: A.Polyakov
*/
#include "ch.h"
#include "hal.h"
#include "owtemp.h"
#include "oneWire.h"
#include "ds1820b.h"
#include <stdlib.h>
#include <string.h>
//#define ARRAY_LEN(a) (sizeof(a)/sizeof(a[0]))
#define OWSCAN_TIMEOUT_MS 250 // задержка сканирования датчиков температуры (мсек)
#define OWTEMPCONV 190 // задержка конвертирования (мсек) для датчиков температуры DS1820B
#define OWTEMPPREC 10 // точность преобразования для датчиков температуры
static OneWireRomAddress romAddr[OWDEVICES];
// признак инициализации oneWire
extern bool_t ow_initialized;
extern OneWireDriver owDrv;
extern const OneWireConfig owCfg;
extern BinarySemaphore owsem;
ow_temp_read_t ow_temp_read; // возвращает значения температуры и признак ошибки
static BinarySemaphore owtempsem;
/*
* Процесс сканирования температурных датчиков DS1820B
*/
static Thread *OWTempThread_p;
static WORKING_AREA(waOWTempThread, 256);
__attribute__((noreturn))
static msg_t OWTempThread(void *arg) {
(void)arg;
chRegSetThreadName("owTempThd");
while (TRUE) {
ow_temp_read_t *req;
Thread *tp;
tp = chMsgWait();
req = (ow_temp_read_t *) chMsgGet(tp);
chMsgRelease(tp, (msg_t) req);
req->error = OW_TEMP_NO_ERROR;
chBSemWait(&owsem);
oneWireSearchRom (&owDrv, FALSE, romAddr, OWDEVICES);
bool_t ow_found = FALSE;
for (uint8_t i=0; i<OWDEVICES; i++) {
if (romAddr[i].addr[0] != 0x28) continue;
ow_found = TRUE;
ds1820BInit (&owDrv, &(romAddr[i]), OWTEMPPREC);
ds1820BAskTemp (&owDrv, &(romAddr[i]));
}
chBSemSignal(&owsem);
if (ow_found){
chThdSleepMilliseconds(OWTEMPCONV);
chBSemWait(&owsem);
for (uint8_t i=0; i<OWDEVICES; i++) {
req->owtemp[i].key[0] = 0x00;
if (romAddr[i].addr[0] == 0x28) {
memcpy(&req->owtemp[i].key,&romAddr[i],8);
req->owtemp[i].value = ds1820BGGetTempFromRam(&owDrv, &(romAddr[i]));
}
}
chBSemSignal(&owsem);
}
else {
req->error = OW_TEMP_NOT_FOUND;
}
chBSemSignal(&owtempsem);
}//while
}
// получает значения с температурных датчиков DS1820B
ow_temp_error_t owtemp_read(void) {
ow_temp_read_t *ow_temp_read_p = &ow_temp_read;
chBSemWait(&owtempsem); /* to be sure */
chMsgSend(OWTempThread_p, (msg_t) ow_temp_read_p);
/* wait for reply */
if(chBSemWaitTimeout(&owtempsem, MS2ST(OWSCAN_TIMEOUT_MS)) == RDY_TIMEOUT) {
chBSemReset(&owtempsem, FALSE);
ow_temp_read.error = OW_TEMP_TIMEOUT;
return OW_TEMP_TIMEOUT;
}
chBSemReset(&owtempsem, FALSE);
return ow_temp_read.error;
}
// создает процесс опроса датчиков DS1820B
void ow_temp_init(void){
chBSemInit(&owtempsem, FALSE);
oneWireInit(&owDrv,&owCfg);
// Создаем процесс опроса датчиков 1-wire
OWTempThread_p = chThdCreateStatic(waOWTempThread, sizeof(waOWTempThread), OWTEMP_PRIO, OWTempThread, NULL);
}