From 058047da3483dc4daaf1ee6cf8e9a02ede57ffc3 Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Sun, 7 Mar 2021 19:47:25 +0300 Subject: [PATCH] DS18 works --- F1-nolib/DS18/DS18.bin | Bin 6704 -> 7496 bytes F1-nolib/DS18/ds18.c | 68 ++++++++++- F1-nolib/DS18/ds18.h | 3 + F1-nolib/DS18/proto.c | 272 +++++++++++++++++++++++++++++++++-------- 4 files changed, 287 insertions(+), 56 deletions(-) diff --git a/F1-nolib/DS18/DS18.bin b/F1-nolib/DS18/DS18.bin index 1609d46e2ac8f49e35a874e36dce53dfe81f6ae9..0430dfd7fcc6128ed0fb1046596fd2f8448a668d 100755 GIT binary patch delta 2871 zcma)83v5%@89w)6`z9gD4KWZx5>DfUgxugdjBa@pVeHhg;}kQJ77DbpLmUzWiR-xZ zQjOV7TdJ)v5Lc?8ovK!$5=Cr~h6vaQMlERL(aoMJ)mg{zv}q1xsMjUMHiq2&$CQaj zRn^jW{&UX%{g3mXbMEocC4Xx4qm>B9=OXSp;Oav_5B&&-fJ_tl4fm+c!#*A!pVvHK z<9{UR$vF=YGWt6Y8a-n3aF8E9UioOSA8!0zw$ci!yFjE6-Ue_2dH|=SbJWlLUC>(( zK!`S$0JP{X;}}R(OBoSI8S6)puCh(%Q4+sU_6%3p=ZRTDUU+#~js?XzwlGOOuGD0O ze`898$0q8HrB)Thk zEAN=t5HaMzaBYy4mNQaG^*E`5~mMvQ@QFxX_d1(K(ew zP+@U}tN$uUM$g#U(-uH07ER$|Q(3xUOWT*J>m^zBMn8yn|T+9Z{)B(^Gt zp@4Ms5@}c&#TTOC4-Rdk2u%6`D{X0&|M>QT%FZ7PT}8$M z&!^Dxr#vkf1qrzW0Kx6W9#0DyQ}!a!(?V)5HL|~>L0n_?v@#|Yt5y|}NW?2SO$Gpo zN=}%xM_r!VJ>3jT+AvK)yHg6P8%hbCRQO)9gnlon%TkuQQd2%n_RKClp>8VsKK3j| z`n9?uH+qK@@A4h8!D7OQM(yE?O< z{CAgB`mJUt@8^(r{pid#+=Jwcx1|@jRysh99O9NxbY5DDW_8r=PAiFA1yx@TolBws zl5Hte{Y8kezy%UeO*)KZL;5cv9S&~b{c zix6jYv`}_B{u5>=KfTYLMt@^`k15Cbk8ri+@3Bt71|F!z#Fi44W$dUZ5-xsOS4&cG zTr)Ey2`*@sDTdO=#|OdI|IZK!k90gF^81)1(u)g6Amjo*s(O4V?qap$s#FQazhg#y&h0H?Uc?L-FOBiHM=%dh90^ld(Zlp7Z#(KC8j!o|sASPrZ0# zIJSTP{<)|;&;B+;sk(-t^z|RKgZfIE1@T-RQhK405H?C3XEzKpl z@q7*S5rz-d+3EL9&xNRW72(;48Ztj_VlDA7eNaib(i$J#>V(bO}m9$_NT2Zw& z=r6MHmS4seTHgd9c}t39w+U$eSdL*q8;a&w4y2jK&U4h{tMt&Mi8d^Tlb56xeI5Bc zHXkfHQo$RJ-KDlN`-L8QD%x3SzUU+~)3IXf^MG}L=K!k#&j8v1KaH&^L0lJr_d~M; zfaW1C02hLVz6`P!B)KqTrwq{70`|eY3_L6JKf8445(bH`qbQ4RsY0MT3pfTi2uK3& z-vrPnZ-^RFRgz?jPD~^DR+79SG|Xjxa{>i>z!6^}U7Jx+^4ICZupeU+9wP(VFF+}R zGLveFRFk`j-o;37=WeCWNV$0<*=JaUcS44H80kXZ-us8$`GaL4(45alTqzIFF5n&; z{@f4?HQ%TvQ@fZE3tvO2PC!2*y;Sf=Dk3eNxtofNd^Ynds*!jhs?R|pCo)DriZGr5 zUWoZ&$nOjw1h@ov9l(|%&QLmXQ@e^PCVXN~xY=Ms{B4(B5G94p@ML;KS=n`;8{=O<79&q<{;is2(n5}q~<7uK;?dtVm z7v9{<`h1(+(xSP`T2|b12>MlSS66S}Mm(^=tJlN0%3OsP;SHPJE-&8V@@?qJ_^E0p zvm_r97Z3PcK6kb>HOHbKfVuzkaCJL2h%Og2ot=8U9&GAy=Qf{v0QYypQWi=rMNc)h zZ+5#q5R+t=Sy3hpaOAr?c`qefb0#Cy?sIv4?k-?Se=e$-znWACce#A7MhqTM``s$} h`WvB=22n~Bl}elE9@Pfmlq(cM6ub=R6X?L9{vYw`oj(8o delta 2033 zcma)6eQZ-z6hH5^Yu~zcds|!AZr!+{8!Ovb1|q>Rq}kZ$$7Hyn5Dc*^E3BkpwN$Aj z+JS=qn4r5F1!oM3iqRP6STYk!kpL1LaZ5CaVk|0IBN%EJwkxjBb2}Dg5JHpRJLlZ< zJ0JJldwZt-$l?&J0rGee2#+BioduZnV;lyy%w)50XUyyzvu%U&wwTZzMN4(J5vKjO z2i*}fyU6|9Ywl8P))ekP8OudibDImI0OS(l3}O@!pr^Q}LL;c1L;&y>BSMQhV|dwG z4QBxXVG@T5T1`GF@q#owAUaBd+0~jc?m1adn%@{K7!`S#h&uI6aHSWH3mSzrVrhiW z!!gkU@i}3o$>bBmvMVpbU*iyA^;jq3ki11oJW(X+2jmVz@L(g1is9*y;&2pbp{#~m zPglqms#rIyt4lz4W)?q^RfJdy=FnsuK$1gJ;>b~?! zY;9kf!|yQdQ9fMC=xh)(bs2r8&K~-OqC&YkEg*Xby{uSPb}x3Ar;jMh)wyXlgX}b$ z!6H`To6A~SaJ?$ei z6}FOYh<|^R=4IRY7z}R6Ud-|O6n#~-wq}1yN~k3;|2%ps3B3@nOoI9RsH{bk}tyK(5i8rUr12q}#yD2a)AFImf)~Wf9Dm$395q*nT z-ol7){G%{eU6_aNc~*#DoP@a*jtXl@_X+<`137i&^zFRT5X4VT8qxdJB)*Gq32I+X zLS$;Z&IC!-ifiLVj*cV&G5i2#nFho^nT%X-+o!YX9A~@viKt7{^o^6Pr16dQ>p^%0 zaTPaw80AHjCz(XBp~QF~=SD_GqRiHVK{$?tqi9T^97PF#LR1c^EZU#jz{hy{WA0W3 z3%brzyLw5ja#D6=V^V&TyHMwy4W2F%pXJQ-V{uSrmIIlt)u9)#zJmab`hUFV81R*M;X?+XUYBoHH z--CuG{9ZOJ4@rsFl6X2eT0lDcM>7`V2vF8wie|sR$4_>60^MX~$HJvG#P9ZO^8_$6 zfF8@1BkB+h2zHjODAyy_b$SA%lXyLWfY*)eOdgb#wo0;qY;gxN>4M$HcXoNUZ9zh9Ei2~h@p{qD)a?j#`UCE+j6TELzR8~qt%{|X- z>r&A&V-@W-8Vv-)JG^eU?^b-fd%HUjK!bizyn?=DJfe-^W+e`Q!$%1xP{FJAFX~S? A$N&HU diff --git a/F1-nolib/DS18/ds18.c b/F1-nolib/DS18/ds18.c index a4ff4ad..05d6642 100644 --- a/F1-nolib/DS18/ds18.c +++ b/F1-nolib/DS18/ds18.c @@ -18,12 +18,15 @@ #include "ds18.h" #include "proto.h" - +#include "usb.h" //#define EBUG +// ID1: 0x28 0xba 0xc7 0xea 0x05 0x00 0x00 0xc2 +// ID2: 0x28 0x68 0xc9 0xe9 0x05 0x00 0x00 0x42 +// ID3: 0x28 0x23 0xef 0xe9 0x05 0x00 0x00 0xab + #ifdef EBUG -#include "usb.h" #define DBG(x) do{USB_send(x);}while(0) #else #define DBG(x) @@ -99,8 +102,8 @@ * 8 - CRC */ -// max amount of bits (1bytes x 8bits) -#define NmeasurementMax (88) +// max amount of bits (20bytes x 8bits) +#define NmeasurementMax (160) // reset pulse length (ms+1..2) #define DS18_RESETPULSE_LEN (3) // max length of measurement (ms+1..2) @@ -108,6 +111,8 @@ // maximal received data bytes #define IMAXCTR (10) +static uint8_t DS18ID[8] = {0}, matchID = 0; + static void (*ow_process_resdata)() = NULL; // what to do with received data static DS18_state dsstate = DS18_SLEEP; @@ -122,6 +127,25 @@ static uint8_t receivectr = 0; // data bytes amount to receive // prepare buffers to sending #define OW_reset_buffer() do{cc1buff_ctr = 0; receivectr = 0; totbytesctr = 0;}while(0) +// several devices on line +void DS18_setID(const uint8_t ID[8]){ + uint32_t *O = (uint32_t*)DS18ID, *I = (uint32_t*)ID; + *O++ = *I++; *O = *I; + matchID = 1; +#ifdef EBUG + USB_send("DS18_setID: "); + for(int i = 0; i < 8; ++i){ + USB_send(" 0x"); + printhex(DS18ID[i]); + } + USB_send("\n"); +#endif +} +// the only device on line +void DS18_clearID(){ + matchID = 0; +} + /** * add next data byte * @param ow_byte - byte to convert @@ -224,6 +248,22 @@ static void DS18_getReg(int n){ printsp(r, n); } +static int chkCRC(const uint8_t data[9]){ + uint8_t crc = 0; + for(int n = 0; n < 8; ++n){ + crc = crc ^ data[n]; + for(int i = 0; i < 8; i++){ + if(crc & 1) + crc = (crc >> 1) ^ 0x8C; + else + crc >>= 1; + } + } + //USB_send("got crc: "); printhex(crc); USB_send("\n"); + if(data[8] == crc) return 0; + return 1; +} + // data processing functions static void DS18_gettemp(){ // calculate T dsstate = DS18_SLEEP; @@ -238,6 +278,18 @@ static void DS18_gettemp(){ // calculate T dsstate = DS18_ERROR; return; } + int ctr; + for(ctr = 0; ctr < 9; ++ctr){ + if(r[ctr] != 0xff) break; + } + if(ctr == 9){ + USB_send("Target ID not found"); + return; + } + if(chkCRC(r)){ + USB_send("CRC is wrong\n"); + return; + } uint16_t l = r[0], m = r[1], v; int32_t t; if(r[4] == 0xff){ // DS18S20 @@ -256,7 +308,13 @@ static void DS18_pollt(){ // poll T if((r = OW_readbuf()) && receivectr == 1){ if(*r == CONVERSION_DONE){ OW_reset_buffer(); - OW_add_byte(OW_SKIP_ROM); + if(matchID){ // add MATCH command & target ID + OW_add_byte(OW_MATCH_ROM); + for(int i = 0; i < 8; ++i) + OW_add_byte(DS18ID[i]); + }else{ + OW_add_byte(OW_SKIP_ROM); + } OW_add_byte(OW_READ_SCRATCHPAD); OW_add_read_seq(9); ow_process_resdata = DS18_gettemp; diff --git a/F1-nolib/DS18/ds18.h b/F1-nolib/DS18/ds18.h index 7ab140e..56e1403 100644 --- a/F1-nolib/DS18/ds18.h +++ b/F1-nolib/DS18/ds18.h @@ -42,5 +42,8 @@ void DS18_process(uint32_t Tms); int DS18_readScratchpad(); void DS18_poll(); +void DS18_clearID(); +void DS18_setID(const uint8_t ID[8]); + #endif // DHT_H__ diff --git a/F1-nolib/DS18/proto.c b/F1-nolib/DS18/proto.c index d66614b..5ee884f 100644 --- a/F1-nolib/DS18/proto.c +++ b/F1-nolib/DS18/proto.c @@ -22,67 +22,237 @@ extern volatile uint32_t Tms; + +char *omit_spaces(const char *buf){ + while(*buf){ + if(*buf > ' ') break; + ++buf; + } + return (char*)buf; +} + +// In case of overflow return `buf` and N==0xffffffff +// read decimal number & return pointer to next non-number symbol +static char *getdec(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '9'){ + break; + } + if(num > 429496729 || (num == 429496729 && c > '5')){ // overflow + *N = 0xffffff; + return start; + } + num *= 10; + num += c - '0'; + ++buf; + } + *N = num; + return (char*)buf; +} +// read hexadecimal number (without 0x prefix!) +static char *gethex(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + uint8_t M = 0; + if(c >= '0' && c <= '9'){ + M = '0'; + }else if(c >= 'A' && c <= 'F'){ + M = 'A' - 10; + }else if(c >= 'a' && c <= 'f'){ + M = 'a' - 10; + } + if(M){ + if(num & 0xf0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 4; + num += c - M; + }else{ + break; + } + ++buf; + } + *N = num; + return (char*)buf; +} +// read octal number (without 0 prefix!) +static char *getoct(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '7'){ + break; + } + if(num & 0xe0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 3; + num += c - '0'; + ++buf; + } + *N = num; + return (char*)buf; +} +// read binary number (without b prefix!) +static char *getbin(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '1'){ + break; + } + if(num & 0x80000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 1; + if(c == '1') num |= 1; + ++buf; + } + *N = num; + return (char*)buf; +} + +/** + * @brief getnum - read uint32_t from string (dec, hex or bin: 127, 0x7f, 0b1111111) + * @param buf - buffer with number and so on + * @param N - the number read + * @return pointer to first non-number symbol in buf + * (if it is == buf, there's no number or if *N==0xffffffff there was overflow) + */ +char *getnum(const char *txt, uint32_t *N){ + char *nxt = NULL; + char *s = omit_spaces(txt); + if(*s == '0'){ // hex, oct or 0 + if(s[1] == 'x' || s[1] == 'X'){ // hex + nxt = gethex(s+2, N); + if(nxt == s+2) nxt = (char*)txt; + }else if(s[1] > '0'-1 && s[1] < '8'){ // oct + nxt = getoct(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ // 0 + nxt = s+1; + *N = 0; + } + }else if(*s == 'b' || *s == 'B'){ + nxt = getbin(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ + nxt = getdec(s, N); + if(nxt == s) nxt = (char*)txt; + } + return nxt; +} + static const char *helpmesg = + "'C' - clear match ROM\n" + "'D' - get DS18 state\n" "'I' - get DS18 ID\n" "'M' - start measurement\n" "'P' - read scratchpad\n" - "'S' - get DHT state\n" + "'S' - set match ROM (S 0xaa 0xbb... - 8 bytes of ID)\n" "'R' - software reset\n" "'T' - get time from start\n" "'W' - test watchdog\n" ; +// read 8 bytes of ROM and run SETROM +static void setROM(const char *buf){ + uint8_t ID[8]; + uint32_t N; + for(int i = 0; i < 8; ++i){ + char *nxt = getnum(buf, &N); + if(nxt == buf || N > 0xff){ + USB_send("Wrong data: "); + USB_send(buf); + return; + } + ID[i] = (uint8_t) N; + buf = nxt; + } + DS18_setID(ID); + USB_send("Set ID to:"); + for(int i = 0; i < 8; ++i){ + USB_send(" 0x"); + printhex(ID[i]); + } + USB_send("\n"); +} + const char *parse_cmd(const char *buf){ - if(buf[1] != '\n') return buf; - switch(*buf){ - case 'I': - if(DS18_readID()) return "Reading ID..\n"; - else return "Error\n"; - case 'M': - if(DS18_start()) return "Started\n"; - else return "Wait a little\n"; - break; -/* case 'p': - DS18_poll(); - return "polling\n"; - break;*/ - case 'P': - if(DS18_readScratchpad()) return "Reading scr..\n"; - else return "Error\n"; - break; - case 'R': - USB_send("Soft reset\n"); - NVIC_SystemReset(); - break; - case 'S': - switch(DS18_getstate()){ - case DS18_SLEEP: - return "Sleeping\n"; - case DS18_RESETTING: - return "Resetting\n"; - case DS18_DETECTING: - return "Detecting\n"; - case DS18_DETDONE: - return "Detection done\n"; - case DS18_READING: - return "Measuring\n"; - case DS18_GOTANSWER: - return "Results are ready\n"; - default: - return "Not found\n"; - } - case 'T': - USB_send("T="); - USB_send(u2str(Tms)); - USB_send("ms\n"); - break; - case 'W': - USB_send("Wait for reboot\n"); - while(1){nop();}; - break; - default: // help - return helpmesg; - break; + if(buf[1] == '\n'){ + switch(*buf){ + case 'C': + DS18_clearID(); + return "Don't send MATCH ROM\n"; + break; + case 'D': + switch(DS18_getstate()){ + case DS18_SLEEP: + return "Sleeping\n"; + case DS18_RESETTING: + return "Resetting\n"; + case DS18_DETECTING: + return "Detecting\n"; + case DS18_DETDONE: + return "Detection done\n"; + case DS18_READING: + return "Measuring\n"; + case DS18_GOTANSWER: + return "Results are ready\n"; + default: + return "Not found\n"; + } + break; + case 'I': + if(DS18_readID()) return "Reading ID..\n"; + else return "Error\n"; + case 'M': + if(DS18_start()) return "Started\n"; + else return "Wait a little\n"; + break; + /* case 'p': + DS18_poll(); + return "polling\n"; + break;*/ + case 'P': + if(DS18_readScratchpad()) return "Reading scr..\n"; + else return "Error\n"; + break; + case 'R': + USB_send("Soft reset\n"); + NVIC_SystemReset(); + break; + case 'T': + USB_send("T="); + USB_send(u2str(Tms)); + USB_send("ms\n"); + break; + case 'W': + USB_send("Wait for reboot\n"); + while(1){nop();}; + break; + default: // help + return helpmesg; + break; + } + }else{ // several letters + switch(*buf){ + case 'S': + setROM(buf + 1); + break; + default: + return buf; + } } return NULL; }