231 lines
6.5 KiB
C
231 lines
6.5 KiB
C
#include "onewire_it_driver.h"
|
|
|
|
#define owtim htim3
|
|
OneWire_ITHandleTypeDef honewire;
|
|
static OneWire_State ow_state = OW_IDLE;
|
|
static int32_t ow_delay_counter = 0; // Ñ÷åò÷èê âðåìåíè äëÿ çàäåðæåê
|
|
|
|
|
|
extern TIM_HandleTypeDef owtim;
|
|
extern OneWire_t OW;
|
|
void OneWireIT_Init(OneWire_ITHandleTypeDef *OW_IT) {
|
|
OW_IT->onewire = &OW;
|
|
// Ðàçðåøàåì ïðåðûâàíèå òàéìåðà
|
|
HAL_TIM_Base_Start_IT(&owtim);
|
|
}
|
|
void OneWire_AddOperation(OneWire_ITHandleTypeDef *OW_IT, void (*operation)(OneWire_t*), uint8_t *io_data_buffer)
|
|
{
|
|
uint8_t next_tail = (OW_IT->tail + 1) % OP_QUEUE_SIZE;
|
|
if (next_tail != OW_IT->head)
|
|
{ // Î÷åðåäü íå ïåðåïîëíåíà
|
|
OW_IT->operation_queue[OW_IT->tail] = operation;
|
|
OW_IT->tail = next_tail;
|
|
}
|
|
}
|
|
|
|
void OneWire_ProcessNextOperation(OneWire_ITHandleTypeDef *OW_IT) {
|
|
if (OW_IT->head != OW_IT->tail) { // Åñëè î÷åðåäü íå ïóñòà
|
|
void (*current_op)(OneWire_t*) = OW_IT->operation_queue[OW_IT->head];
|
|
|
|
current_op(OW_IT->onewire);
|
|
|
|
if(OW_IT->op_done)
|
|
{
|
|
OW_IT->op_done = 0;
|
|
OW_IT->head = (OW_IT->head + 1) % OP_QUEUE_SIZE; // Ïåðåõîäèì ê ñëåäóþùåé îïåðàöèè
|
|
}
|
|
}
|
|
}
|
|
|
|
void OneWireTIMHandler(TIM_HandleTypeDef *htim, OneWire_ITHandleTypeDef *OW_IT)
|
|
{
|
|
if (htim == &owtim)
|
|
{
|
|
if (ow_delay_counter > 0)
|
|
{
|
|
ow_delay_counter -= ONE_WIRE_TIMER_PERIOD_US; // Óìåíüøàåì ñ÷åò÷èê çàäåðæêè
|
|
}
|
|
|
|
OneWire_Reset_ITHandle(OW_IT->onewire);
|
|
// OneWire_ProcessNextOperation(OW_IT);
|
|
|
|
}
|
|
}
|
|
|
|
void OneWire_WriteBytes_IT(OneWire_ITHandleTypeDef *OW_IT)
|
|
{
|
|
static HAL_StatusTypeDef res;
|
|
|
|
if (OW_IT->current_byte_idx < OW_IT->data_len) // Åñëè íå îáðàáîòàíû âñå äàííûå
|
|
{
|
|
uint8_t byte = OW_IT->data[OW_IT->current_byte_idx]; // Áåðåì òåêóùèé áàéò äàííûõ
|
|
for (OW_IT->current_bit_idx = 0; OW_IT->current_bit_idx < 8; OW_IT->current_bit_idx++)
|
|
{
|
|
uint8_t bit = (byte >> (7 - OW_IT->current_bit_idx)) & 0x01; // Ïîëó÷àåì áèò èç áàéòà
|
|
OneWire_WriteBit_ITHandle(OW_IT->onewire, bit); // Ïèøåì ýòîò áèò â OneWire
|
|
}
|
|
OW_IT->current_byte_idx++; // Ïåðåõîäèì ê ñëåäóþùåìó áàéòó
|
|
}
|
|
else
|
|
{
|
|
OW_IT->current_byte_idx = 0; // Çàâåðøàåì îïåðàöèþ çàïèñè
|
|
OW_IT->op_done = 1;
|
|
}
|
|
}
|
|
|
|
void OneWire_ReadBytes_IT(OneWire_ITHandleTypeDef *OW_IT)
|
|
{
|
|
uint8_t bit;
|
|
if (OW_IT->current_byte_idx < OW_IT->data_len) // Åñëè íå îáðàáîòàíû âñå äàííûå
|
|
{
|
|
uint8_t byte = 0; // Äëÿ õðàíåíèÿ ïðî÷èòàííîãî áàéòà
|
|
for (OW_IT->current_bit_idx = 0; OW_IT->current_bit_idx < 8; OW_IT->current_bit_idx++)
|
|
{
|
|
OneWire_ReadBit_ITHandle(OW_IT->onewire, &bit); // ×èòàåì áèò
|
|
byte |= (bit << (7 - OW_IT->current_bit_idx)); // Ñîáèðàåì áàéò èç áèòîâ
|
|
}
|
|
OW_IT->data[OW_IT->current_byte_idx] = byte; // Ñîõðàíÿåì áàéò â áóôåð
|
|
OW_IT->current_byte_idx++; // Ïåðåõîäèì ê ñëåäóþùåìó áàéòó
|
|
}
|
|
else
|
|
{
|
|
OW_IT->current_byte_idx = 0; // Çàâåðøàåì îïåðàöèþ ÷òåíèÿ
|
|
OW_IT->head = (OW_IT->head + 1) % OP_QUEUE_SIZE; // Óáèðàåì âûïîëíåííóþ îïåðàöèþ èç î÷åðåäè
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
HAL_StatusTypeDef OneWire_ReadBit_ITHandle(OneWire_t *OW, uint8_t *bit) {
|
|
static uint8_t read_bit_step = 0;
|
|
|
|
switch (read_bit_step)
|
|
{
|
|
case 0:
|
|
// Ñíèæàåì ïèí íà 1 ìêñ äëÿ íà÷àëà ïåðåäà÷è áèòà
|
|
OneWire_Pin_Level(OW, 0);
|
|
OneWire_Pin_Mode(OW, Output);
|
|
ow_delay_counter = ONEWIRE_READ_CMD_US; // Çàäåðæêà 1 ìêñ äëÿ ÷òåíèÿ áèòà
|
|
read_bit_step++;
|
|
return HAL_BUSY;
|
|
case 1:
|
|
// Ïîäíèìàåì ïèí è ïðîâåðÿåì ñîñòîÿíèå äëÿ ÷òåíèÿ áèòà
|
|
if (ow_delay_counter <= 0)
|
|
{
|
|
OneWire_Pin_Mode(OW, Input);
|
|
ow_delay_counter = ONEWIRE_READ_DELAY_US; // Çàäåðæêà ïåðåä ñ÷èòûâàíèåì
|
|
read_bit_step++;
|
|
}
|
|
return HAL_BUSY;
|
|
case 2:
|
|
// ×èòàåì ïèí íà 1 ìêñ äëÿ îïðåäåëåíèÿ áèòà
|
|
if (ow_delay_counter <= 0)
|
|
{
|
|
*bit = OneWire_Pin_Read(OW);
|
|
ow_delay_counter = ONEWIRE_COMMAND_SLOT_US - ONEWIRE_READ_CMD_US - ONEWIRE_READ_DELAY_US;
|
|
}
|
|
return HAL_BUSY;
|
|
case 3:
|
|
read_bit_step = 0; // Çàâåðøàåì êîìàíäó ÷òåíèÿ
|
|
ow_state = OW_IDLE;
|
|
return HAL_OK;
|
|
default:
|
|
read_bit_step = 3;
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
|
|
HAL_StatusTypeDef OneWire_WriteBit_ITHandle(OneWire_t *OW, uint8_t bit)
|
|
{
|
|
static uint8_t write_bit_step = 0;
|
|
|
|
switch (write_bit_step)
|
|
{
|
|
case 0:
|
|
// Ïèøåì áèò 0 èëè 1
|
|
OneWire_Pin_Level(OW, 0);
|
|
OneWire_Pin_Mode(OW, Output);
|
|
if (bit)
|
|
{
|
|
ow_delay_counter = ONEWIRE_WRITE_1_US; // Çàäåðæêà ìêñ äëÿ çàïèñè 1
|
|
}
|
|
else
|
|
{
|
|
ow_delay_counter = ONEWIRE_WRITE_0_US; // Çàäåðæêà ìêñ äëÿ çàïèñè 0
|
|
}
|
|
write_bit_step++;
|
|
return HAL_BUSY;
|
|
case 1:
|
|
// Çàâåðøàåì çàïèñü, ïîäíèìàåì ïèí
|
|
if (ow_delay_counter == 0)
|
|
{
|
|
OneWire_Pin_Mode(OW, Input);
|
|
|
|
if (bit) {
|
|
ow_delay_counter = ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_1_US; // Çàäåðæêà ìêñ äëÿ çàâåðøåíèÿ çàïèñè 1
|
|
}
|
|
else
|
|
{
|
|
ow_delay_counter = ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_0_US; // Çàäåðæêà ìêñ äëÿ çàâåðøåíèÿ çàïèñè 0
|
|
}
|
|
write_bit_step++;
|
|
}
|
|
return HAL_BUSY;
|
|
case 2:
|
|
OneWire_Pin_Mode(OW, Input);
|
|
// Çàâåðøàåì çàïèñü
|
|
write_bit_step = 0;
|
|
ow_state = OW_IDLE;
|
|
return HAL_OK;
|
|
default:
|
|
write_bit_step = 2;
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
HAL_StatusTypeDef OneWire_Reset_ITHandle(OneWire_t *OW)
|
|
{
|
|
static uint8_t reset_step = 0;
|
|
static uint8_t rslt = 0;
|
|
GPIOC->ODR ^= (1<<13);
|
|
switch (reset_step)
|
|
{
|
|
case 0:
|
|
// Íà÷àëî êîìàíäû Reset - îïóñêàåì ïèí íà 480 ìêñ
|
|
OneWire_Pin_Level(OW, 0);
|
|
OneWire_Pin_Mode(OW, Output);
|
|
ow_delay_counter = ONEWIRE_RESET_PULSE_US; // Óñòàíàâëèâàåì çàäåðæêó â 480 ìêñ
|
|
reset_step++;
|
|
return HAL_BUSY;
|
|
case 1:
|
|
// Ïðîâåðÿåì, ïðîøëà ëè çàäåðæêà 480 ìêñ
|
|
if (ow_delay_counter <= 0)
|
|
{
|
|
/* Release line and wait for 70us */
|
|
OneWire_Pin_Mode(OW, Input);
|
|
ow_delay_counter = ONEWIRE_PRESENCE_WAIT_US; // Óñòàíàâëèâàåì çàäåðæêó íà 70 ìêñ
|
|
reset_step++;
|
|
}
|
|
return HAL_BUSY;
|
|
case 2:
|
|
// Æäåì îòâåòà îò óñòðîéñòâà íà ïîäíÿòèå ïèíà
|
|
if (ow_delay_counter <= 0)
|
|
{
|
|
// ×èòàåì ïèí, åñëè óñòðîéñòâî îòâåòèëî
|
|
uint8_t rslt = OneWire_Pin_Read(OW);
|
|
reset_step++;
|
|
}
|
|
return HAL_BUSY;
|
|
case 3:
|
|
reset_step = 0; // Çàâåðøàåì êîìàíäó Reset
|
|
ow_delay_counter = ONEWIRE_PRESENCE_DURATION_US; // Óñòàíàâëèâàåì çàäåðæêó íà 70 ìêñ
|
|
ow_state = OW_IDLE;
|
|
return HAL_OK;
|
|
default:
|
|
reset_step = 3;
|
|
return HAL_ERROR;
|
|
}
|
|
}
|