c: CallBack
Jaroslav Buchta
jaroslav.buchta na hascomp.cz
Čtvrtek Únor 25 06:03:37 CET 2021
Jen jsem to prolitnul ale tenhle zdrojak se asi nechci snazit ani pochopit.
Sel jsem na to jinak, 2 stavove automaty a jen s cyklicky volanou
obsluhou main, pro inspiraci v priloze.
Funguje to uz 2 mesice bez selhani nebo restartu na tepelnem cerpadlo.
Blokuje to na max 60us preruseni, tomu jsem se chtel vyhnout a pouzit
SPI pres DMA (STM32L0), ono by to skvele a na pozadi i fungovalo ale
kdyby to nekdo zkousel, tak je potreba dat na MOSI latch - stav vystupu
mezi sekvencemi se mi nepodarilo dostat pod kontrolu, je tam v klidu
nejaky konec posuvneho registru a zalezi to na predchozim obsahu.
Dne 25.02.2021 v 0:06 Miroslav Draxal napsal(a):
>
> Dobrý večer,
>
> Jedná se o XC8 pro microchip.
>
> Mějme několik místních procedur, každá procedura v jiném kompilovaném
> modulu (Main.c, CallBack.c,). Tyto procedury se navzájem nemohou
> ovlivňovat, nejsou v ISR, proto kompilátor pro vnitřní „svoje potřeby“
> může použít adresu proměnné, která je ve všech procedurách stejná.
> (třeba adr. 0x00, kam si ukládá data pro „svoje potřeby“ )
>
> Existuje technika, jak přinutit, aby pro jeden konkrétní modul
> (CallBack.c) použil jedinečné adresy pro „svoje potřeby“.
>
> C nativně neumí CallBack, ale jde to velice jednoduše napsat. Proto
> píši, že se procedury nemohou ovlivňovat a nejsou v ISR. Kompilátor
> neví, že z přerušení skáču třeba doprostřed procedury.
>
> Proč to? Používám zpětné volání z ISR. V „voidProc(void)“ v Main.c,
> se používá adr. proměnné 0x00 pro předání parametru(neovlivním jeho
> adresu), přijde přerušení, z něj zpětným voláním volám proceduru
> v CallBack.c, která taky používá adr. proměnné 0x00 ( také to
> neovlivním), kde se obsah změní, a až se dostanu zpátky z přerušení,
> obsah paměti je změněn.
>
> Asi to je prasárna. Ale v systému, kde mi běží na přerušeních všechno,
> jakoby paralelně, je to zpětné volání fakt dobrá věc. Separované to
> běží jako z praku, pokud to zavedu do systému, začnou se mi hádat
> proměnné.
>
> Zasílám k nahlédnutí. Je to zatím neučesané.
>
>
> _______________________________________________
> HW-list mailing list - sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20210225/6b2a6ea4/attachment.html>
------------- další část ---------------
#include <globaldefs.h>
#define OWSLOTSCOUNT 2
#define OWDEVSLOTMAX 8
//read sampling time in us
#define OWBUSSTABLEDLY 8
#define OWSAMPTIME 10
#define INTR_DIS() EnterCritical()
#define INTR_ENA() ExitCritical()
#define OWCMD_SEARCHROM 0xF0
#define OWCMD_READROM 0x33
#define OWCMD_MATCH 0x55
#define OWCMD_SKIPROM 0xCC
#define OWCMD_CONVERTT 0x44
#define OWCMD_WRITESP 0x4E
#define OWCMD_READSP 0xBE
#define OWFAMID_DS18B20 0x28
#define OWFAMID_DS1820 0x10
//static const char *tag = "OWID";
// This table comes from Dallas sample code where it is freely reusable,
// though Copyright (C) 2000 Dallas Semiconductor Corporation
static const uint8_t dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
};
// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
// and the registers. (note: this might better be done without to
// table, it would probably be smaller and certainly fast enough
// compared to all those delayMicrosecond() calls. But I got
// confused, so I use this table from the examples.)
static uint8_t owcrc8(const uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;
while (len--)
{
crc = dscrc_table[crc ^ *(addr++)]; // pgm_read_byte(dscrc_table + (crc ^ *addr++));
}
return crc;
}
//static uint8_t owcrc8_comp(const uint8_t *addr, uint8_t len)
//{
// uint8_t crc = 0;
// while (len--)
// {
// uint8_t inbyte = *(addr++);
// for (uint8_t i = 8; i != 0; i--)
// {
// uint8_t mix = (crc ^ inbyte) & 0x01;
// crc >>= 1;
// if (mix) crc ^= 0x8C;
// inbyte >>= 1;
// }
// }
//
// return crc;
//
//}
///////////////////////////////////////////////////////////////////////////////
typedef enum owstate_e
{
owst_Idle,
owst_DoResetStart,
owst_ResetDelay,
owst_ResetWaitPresRls,
owst_ResetWaitRsth,
owst_DoCmdW,
owst_CmdWCmd,
owst_CmdWData,
owst_DoCmdR,
owst_CmdRCmd,
owst_CmdRData,
owst_DoCmdRomSrch,
owst_CmdRomSrchCmd,
owst_CmdRomSrchR,
owst_CmdRomSrchW,
owst_FinOK,
owst_FinError,
} owstate_t;
typedef enum owdevstate_e
{
owdst_StartupInit,
owdst_StartupWait,
owdst_Idle,
owdst_ResetIni,
owdst_ResetIniWait,
owdst_DoCmdSkipRom,
owdst_WaitCmdSkipRom,
owdst_DoCmdReadRom,
owdst_WaitReadRom,
owdst_DoRomSearch,
owdst_RomSearchResetStart,
owdst_RomSearchResetWait,
owdst_RomSearchFindNext,
owdst_DoStartConv,
owdst_ConvResetStart,
owdst_ConvResetWait,
owdst_ConvSkipRomCmd,
owdst_ConvStartConvCmd,
owdst_ConvWaitFinish,
owdst_ReadSpResetStart,
owdst_ReadSpResetWait,
owdst_ReadSpMatchRom,
owdst_ReadSpReadData,
owdst_Wait,
owdst_Error,
} owdevstate_t;
typedef struct owSlotData_s
{
owdev_data_t devData[OWDEVSLOTMAX];
uint32_t tckAction;
owstate_t owstate;
uint8_t owdata[9];
uint8_t owbitcntr;
uint8_t owbytecntr;
uint8_t owcmd;
uint8_t owcnt; // universal counter
uint8_t devCnt;
uint8_t devPosPart;
owdevstate_t owdevstate;
uint32_t tckDevOp;
uint32_t tckDevTout;
uint8_t slotId;
} owSlotData_t;
static owSlotData_t slotsData[OWSLOTSCOUNT];
static inline uint16_t slotIdx2Id(int idx)
{
return (uint16_t)1 << idx;
}
static inline void owPinSet(uint16_t slotId, bool state)
{
if (slotId == slotIdx2Id(0))
{
HAL_GPIO_WritePin(OWSLOT1_OUT_GPIO_Port, OWSLOT1_OUT_Pin, state ? GPIO_PIN_RESET : GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(OWSLOT2_OUT_GPIO_Port, OWSLOT2_OUT_Pin, state ? GPIO_PIN_RESET : GPIO_PIN_SET);
}
}
static inline bool owPinGet(uint16_t slotId)
{
if (slotId == slotIdx2Id(0))
{
return (HAL_GPIO_ReadPin(OWSLOT1_IN_GPIO_Port, OWSLOT1_IN_Pin) == GPIO_PIN_SET);
}
else
{
return (HAL_GPIO_ReadPin(OWSLOT2_IN_GPIO_Port, OWSLOT2_IN_Pin) == GPIO_PIN_SET);
}
}
static bool owPresenceTest(owSlotData_t *slot)
{
INTR_DIS();
owPinSet(slot->slotId, true);
uint16_t tckd = GetUsTicksDist(0);
while (GetUsTicksDist(tckd) < OWBUSSTABLEDLY); //wait to sample
if (!owPinGet(slot->slotId))
{ // short to ground error
INTR_ENA();
return false;
}
uint8_t samps = 3;
while (GetUsTicksDist(tckd) <= 60)
{
if (!owPinGet(slot->slotId))
{
samps --;
}
else
{
samps = 3;
}
if (samps == 0)
{
// presence pulse OK
INTR_ENA();
return true;
}
}
// presence pulse missing
INTR_ENA();
return false;
}
static void owWriteBit (owSlotData_t *slot, uint8_t b, uint8_t pos)
{
INTR_DIS();
owPinSet(slot->slotId, false);
uint16_t tckd = GetUsTicksDist(0);
if ((b & (1<<pos)) != 0)
{
while (GetUsTicksDist(tckd) < 2);
owPinSet(slot->slotId, true);
}
else
{
while (GetUsTicksDist(tckd) < 60);
owPinSet(slot->slotId, true);
}
INTR_ENA();
while (GetUsTicksDist(tckd) < 60 + OWBUSSTABLEDLY);
}
static void owReadBit (owSlotData_t *slot, uint8_t *b, uint8_t pos)
{
INTR_DIS();
owPinSet(slot->slotId, false);
uint16_t tckd = GetUsTicksDist(0);
while (GetUsTicksDist(tckd) < 2);
owPinSet(slot->slotId, true);
while (GetUsTicksDist(tckd) < OWSAMPTIME);
bool pin = owPinGet(slot->slotId);
INTR_ENA();
if (pin)
{
*b |= 1 << pos;
}
else
{
*b &= ~(1 << pos);
}
while (GetUsTicksDist(tckd) < 60 + OWBUSSTABLEDLY);
}
static void StartCommandW(owSlotData_t *slot, uint8_t cmd, uint16_t cnt, uint8_t *data, uint32_t tckms)
{
if (cnt > 8) Error_Handler();
slot->owcmd = cmd;
slot->owcnt = cnt;
if (cnt != 0 && data != NULL)
{
memcpy ((void *)slot->owdata, (void *)data, cnt);
}
slot->tckDevOp = tckms;
slot->owstate = owst_DoCmdW;
}
static void StartCommandR(owSlotData_t *slot, uint8_t cmd, uint16_t cnt, uint32_t tckms)
{
if (cnt > 8) Error_Handler();
slot->owcmd = cmd;
slot->owcnt = cnt;
memset ((void *)slot->owdata, 0, sizeof(slot->owdata));
slot->tckDevOp = tckms;
slot->owstate = owst_DoCmdR;
}
static void StartCommandSearch(owSlotData_t *slot, uint32_t tckms, bool bInit)
{
slot->owcmd = OWCMD_SEARCHROM;
slot->owcnt = 0; // match bits counter
if (bInit)
{
slot->devCnt = 0;
slot->devPosPart = 0;
for (int idx=0; idx< OWDEVSLOTMAX; idx++)
{
memset ((void *)&slot->devData[idx], 0, sizeof(owdev_data_t));
}
}
slot->tckDevOp = tckms;
slot->owstate = owst_DoCmdRomSrch;
}
static void SetDeviceRomBit(owdev_data_t *dev, uint8_t bitpos, uint8_t bit)
{
if (bit)
{
dev->romId[bitpos/8] |= 1 << (bitpos & 0x07);
}
else
{
dev->romId[bitpos/8] &= ~(1 << (bitpos & 0x07));
}
}
static uint8_t GetDeviceRomBit(owdev_data_t *dev, uint8_t bitpos)
{
return (dev->romId[bitpos/8] & (1 << (bitpos & 0x07))) != 0 ? 1 : 0;
}
static void owSlotService(owSlotData_t *slot, uint32_t tckus)
{
switch (slot->owstate)
{
case owst_Idle:
break;
case owst_DoResetStart:
owPinSet(slot->slotId, false);
slot->tckAction = tckus;
slot->owstate = owst_ResetDelay;
break;
case owst_ResetDelay:
if (tckus - slot->tckAction >= 500)
{
slot->tckAction = tckus;
if (owPresenceTest(slot))
{
slot->owstate = owst_ResetWaitPresRls;
}
else
{
slot->owstate = owst_FinError;
}
}
break;
case owst_ResetWaitPresRls:
if (owPinGet(slot->slotId))
{
slot->owstate = owst_ResetWaitRsth;
}
else
{
if (tckus - slot->tckAction > 240)
{
slot->owstate = owst_FinError;
}
}
break;
case owst_ResetWaitRsth:
if (tckus - slot->tckAction >= 500)
{
slot->owstate = owst_FinOK;
}
break;
case owst_DoCmdW:
slot->owbitcntr = 0;
slot->owbytecntr = 0;
slot->owstate = owst_CmdWCmd;
break;
case owst_CmdWCmd:
owWriteBit(slot, slot->owcmd, slot->owbitcntr++);
if (slot->owbitcntr == 8)
{
if (slot->owcnt != 0)
{
slot->owbitcntr = 0;
slot->owstate = owst_CmdWData;
}
else
{
slot->owstate = owst_FinOK;
}
}
break;
case owst_CmdWData:
owWriteBit(slot, slot->owdata[slot->owbytecntr], slot->owbitcntr++);
if (slot->owbitcntr == 8)
{
slot->owbitcntr = 0;
slot->owbytecntr++;
if (slot->owbytecntr == slot->owcnt)
{
slot->owstate = owst_FinOK;
}
}
break;
case owst_DoCmdR:
slot->owbitcntr = 0;
slot->owbytecntr = 0;
slot->owstate = owst_CmdRCmd;
break;
case owst_CmdRCmd:
owWriteBit(slot, slot->owcmd, slot->owbitcntr++);
if (slot->owbitcntr == 8)
{
if (slot->owcnt != 0)
{
slot->owbitcntr = 0;
slot->owstate = owst_CmdRData;
}
else
{
slot->owstate = owst_FinOK;
}
}
break;
case owst_CmdRData:
owReadBit(slot, &slot->owdata[slot->owbytecntr], slot->owbitcntr++);
if (slot->owbitcntr == 8)
{
slot->owbitcntr = 0;
slot->owbytecntr++;
if (slot->owbytecntr == slot->owcnt)
{
slot->owstate = owst_FinOK;
}
}
break;
case owst_DoCmdRomSrch:
slot->owbitcntr = 0;
slot->owstate = owst_CmdRomSrchCmd;
break;
case owst_CmdRomSrchCmd:
owWriteBit(slot, slot->owcmd, slot->owbitcntr++);
if (slot->owbitcntr == 8)
{
{
slot->owbitcntr = 0;
slot->owstate = owst_CmdRomSrchR;
}
}
break;
case owst_CmdRomSrchR:
{
uint8_t bits = 0;
owReadBit(slot, &bits, 0);
owReadBit(slot, &bits, 1);
slot->owstate = owst_CmdRomSrchW;
if (slot->owbitcntr >= slot->devData[slot->devCnt].bitpos)
{
switch (bits)
{
case 0x00: // collision, create next tree item
SetDeviceRomBit(&slot->devData[slot->devCnt], slot->owbitcntr, 0);
if (slot->devPosPart + 1 < OWDEVSLOTMAX)
{
slot->devPosPart++;
memcpy ((void *)slot->devData[slot->devPosPart].romId, (void *)slot->devData[slot->devCnt].romId, 8);
SetDeviceRomBit(&slot->devData[slot->devPosPart], slot->owbitcntr, 1);
slot->devData[slot->devPosPart].bitpos = slot->owbitcntr+1; // bit position of first not match bit
}
break;
case 0x01: // bit 1
SetDeviceRomBit(&slot->devData[slot->devCnt], slot->owbitcntr, 1);
break;
case 0x02: // bit 0
SetDeviceRomBit(&slot->devData[slot->devCnt], slot->owbitcntr, 0);
break;
case 3: // error
slot->owstate = owst_FinError;
break;
}
}
}
break;
case owst_CmdRomSrchW:
owWriteBit(slot, GetDeviceRomBit(&slot->devData[slot->devCnt], slot->owbitcntr++), 0);
if (slot->owbitcntr == 64)
{
uint8_t crc = owcrc8(slot->devData[slot->devCnt].romId, 8);
if (crc != 0)
{
slot->owstate = owst_FinError;
}
else
{
slot->devData[slot->devCnt].flags = OWDEV_FL_PRESENT;
slot->devCnt++;
slot->owstate = owst_FinOK;
}
}
else
{
slot->owstate = owst_CmdRomSrchR;
}
break;
case owst_FinOK:
break;
case owst_FinError:
break;
}
}
static void owDevService(owSlotData_t *slot, uint32_t tckms)
{
switch (slot->owdevstate)
{
case owdst_StartupInit:
slot->tckDevOp = tckms;
slot->owdevstate = owdst_StartupWait;
break;
case owdst_StartupWait:
if (tckms - slot->tckDevOp >= 1000)
{
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Idle;
}
break;
case owdst_Idle:
slot->owdevstate = owdst_DoRomSearch;
break;
case owdst_ResetIni:
slot->tckDevOp = tckms;
slot->owstate = owst_DoResetStart;
slot->owdevstate = owdst_ResetIniWait;
break;
case owdst_ResetIniWait:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
slot->owdevstate = owdst_DoCmdReadRom; // SkipRom;
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
case owdst_DoCmdSkipRom:
StartCommandW(slot, OWCMD_SKIPROM, 0, NULL, tckms);
slot->owdevstate = owdst_WaitCmdSkipRom;
break;
case owdst_WaitCmdSkipRom:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
slot->owdevstate = owdst_DoCmdReadRom;
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
case owdst_DoCmdReadRom:
StartCommandR(slot, OWCMD_READROM, 8, tckms);
slot->owdevstate = owdst_WaitReadRom;
break;
case owdst_WaitReadRom:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
uint8_t crc = owcrc8(slot->owdata, 7);
if (crc == slot->owdata[7])
{
slot->owdevstate = owdst_Idle;
}
else
{
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
case owdst_DoRomSearch:
slot->devCnt = 0;
slot->devPosPart = 0;
slot->owdevstate = owdst_RomSearchResetStart;
break;
case owdst_RomSearchResetStart:
slot->tckDevOp = tckms;
slot->owstate = owst_DoResetStart;
slot->owdevstate = owdst_RomSearchResetWait;
break;
case owdst_RomSearchResetWait:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
StartCommandSearch(slot, tckms, slot->devCnt == 0);
slot->owdevstate = owdst_RomSearchFindNext;
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
case owdst_RomSearchFindNext:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
if (slot->devCnt > slot->devPosPart)
{
slot->tckDevOp = tckms;
slot->owdevstate = owdst_DoStartConv;
}
else
{
slot->owdevstate = owdst_RomSearchResetStart;
}
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
// start conversion and read data from sensors
case owdst_DoStartConv:
slot->devPosPart = 0;
slot->owdevstate = owdst_ConvResetStart;
break;
case owdst_ConvResetStart:
slot->tckDevOp = tckms;
slot->owstate = owst_DoResetStart;
slot->owdevstate = owdst_ConvResetWait;
break;
case owdst_ConvResetWait:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
StartCommandW(slot, OWCMD_SKIPROM, 0, NULL, tckms);
slot->owdevstate = owdst_ConvSkipRomCmd;
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
case owdst_ConvSkipRomCmd:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
StartCommandW(slot, OWCMD_CONVERTT, 0, NULL, tckms);
slot->owdevstate = owdst_ConvStartConvCmd;
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
case owdst_ConvStartConvCmd:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->tckDevTout = tckms;
slot->owdevstate = owdst_ConvWaitFinish;
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
case owdst_ConvWaitFinish:
if (tckms - slot->tckDevOp >= 10)
{
slot->tckDevOp = tckms;
uint8_t b = 0;
owReadBit(slot, &b, 0);
if (b)
{
slot->owdevstate = owdst_ReadSpResetStart;
}
else if (tckms - slot->tckDevTout > 1000)
{ // timeout error
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
}
break;
case owdst_ReadSpResetStart:
slot->tckDevOp = tckms;
if (slot->devPosPart >= slot->devCnt)
{ // read data finished
slot->owdevstate = owdst_Wait;
}
else
{
slot->owstate = owst_DoResetStart;
slot->owdevstate = owdst_ReadSpResetWait;
}
break;
case owdst_ReadSpResetWait:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
StartCommandW(slot, OWCMD_MATCH, 8, slot->devData[slot->devPosPart].romId, tckms);
slot->owdevstate = owdst_ReadSpMatchRom;
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
case owdst_ReadSpMatchRom:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
StartCommandR(slot, OWCMD_READSP, 9, tckms);
slot->owdevstate = owdst_ReadSpReadData;
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
case owdst_ReadSpReadData:
if (slot->owstate == owst_FinOK)
{
slot->owstate = owst_Idle;
uint8_t crc = owcrc8(slot->owdata, 9);
if (crc != 0)
{
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
else
{
owdev_data_t *dd = &slot->devData[slot->devPosPart];
if (dd->romId[0] == OWFAMID_DS18B20)
{
int32_t t = ((int32_t)slot->owdata[0]) | (((int32_t)slot->owdata[1]) << 8);
if ((t & 0x8000) != 0) t |= 0xffff0000; //sign extension
t *= 100;
t /= 16;
dd->temperature = (int16_t)(t & 0xffff);
dd->timeStamp = tckms;
}
else if (dd->romId[0] == OWFAMID_DS1820)
{
int32_t t = ((int32_t)slot->owdata[0]) | (((int32_t)slot->owdata[1]) << 8);
if ((t & 0x8000) != 0) t |= 0xffff0000; //sign extension
t &= 0xfffffffe; //truncate LSB
t *= 50;
t += (((int32_t)(slot->owdata[7] - slot->owdata[6]))*100)/(int32_t)slot->owdata[7] - 25;
dd->temperature = (int16_t)(t & 0xffff);
dd->timeStamp = tckms;
}
slot->devPosPart++;
slot->owdevstate = owdst_ReadSpResetStart;
}
}
else if (slot->owstate == owst_FinError)
{
slot->owstate = owst_Idle;
slot->tckDevOp = tckms;
slot->owdevstate = owdst_Error;
}
break;
// finish state and manage next cycle
case owdst_Wait:
if (tckms - slot->tckDevOp >= 100)
{
slot->owdevstate = owdst_DoStartConv;
}
break;
case owdst_Error:
if (tckms - slot->tckDevOp >= 2000)
{
slot->owdevstate = owdst_Idle;
}
break;
}
}
void owdev_Init()
{
memset ((void *)slotsData, 0x00, sizeof(slotsData));
for (int idx=0; idx < OWSLOTSCOUNT; idx++)
{
slotsData[idx].slotId = slotIdx2Id(idx);
slotsData[idx].owstate = owst_Idle;
slotsData[idx].owdevstate = owdst_StartupInit;
}
}
void owdev_Service()
{
// DIAG1_S();
// for (int idx=0; idx < 1; idx++)
for (int idx=0; idx < OWSLOTSCOUNT; idx++)
{
owSlotService(&slotsData[idx], (uint32_t)GetUsTicks());
owDevService(&slotsData[idx], HAL_GetTick());
for (int id=0; id<OWDEVSLOTMAX; id++)
{
slotsData[idx].devData[id].slotId = idx;
}
}
// DIAG1_R();
}
owdev_data_t *owdev_GetData(int idx)
{
for (int islot = 0; islot < OWSLOTSCOUNT; islot++)
{
if (idx >= slotsData[islot].devCnt)
{
idx -= slotsData[islot].devCnt;
continue;
}
return &slotsData[islot].devData[idx];
}
return NULL;
}
static inline bool testIdMatch(uint8_t *id1, uint8_t *id2)
{
if (*((uint64_t *)id1) != *((uint64_t *)id2))
{
return false;
}
// for (int idx=0; idx<7; idx++)
// {
// if (id1[idx] != id2[idx]) return false;
// }
return true;
}
extern owdev_data_t *owdev_GetDataById(uint8_t *id)
{
for (int idx=0;;idx++)
{
owdev_data_t *dd = owdev_GetData(idx);
if (dd == NULL) break;
if (testIdMatch(id, dd->romId))
{
return dd;
}
}
return NULL;
}
------------- další část ---------------
/*
* SystemExt.h
*
* Created on: 10. 2. 2019
* Author: jaros
*/
#ifndef ONEWIRE_H_
#define ONEWIRE_H_
#define OWDEV_FL_PRESENT 0x01
//#define OWDWV_FL_PRESENT 0x01
typedef struct
{
uint8_t romId[8]; // device ROM id
uint32_t timeStamp; // last valid data in ms ticks, 0 if never
int16_t temperature; // temperature * 100 in degC
uint8_t slotId;
uint8_t flags; // OWDWV_FL_xxx
// uint8_t errors; // operation errors counter
uint8_t bitpos; // bit counter for search operation
} owdev_data_t;
extern void owdev_Init();
extern void owdev_Service();
extern owdev_data_t *owdev_GetData(int idx);
extern owdev_data_t *owdev_GetDataById(uint8_t *id);
#endif /* ONEWIRE_H_ */
Další informace o konferenci Hw-list