onewire_master: remove malloc in favor of pre-allocated buffers
This commit is contained in:
parent
39100c53b6
commit
bd2f1642cc
|
@ -17,13 +17,14 @@
|
|||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2017
|
||||
* @note peripherals used: timer @ref onewire_master_timer, GPIO @ref onewire_master_gpio
|
||||
* @warning this library does not support parasite power mode
|
||||
* @note overdrive mode is not supported
|
||||
* @warning this library does not support active parasite power mode (more than the pull-up resistor itself)
|
||||
*/
|
||||
|
||||
/* standard libraries */
|
||||
#include <stdint.h> // standard integer types
|
||||
#include <stdbool.h> // boolean type
|
||||
#include <stdlib.h> // memory utilities
|
||||
#include <stddef.h> // NULL definition
|
||||
|
||||
/* STM32 (including CM3) libraries */
|
||||
#include <libopencmsis/core_cm3.h> // Cortex M3 utilities
|
||||
|
@ -64,8 +65,8 @@ volatile enum {
|
|||
|
||||
volatile bool slave_presence = false; /**< if slaves have been detected */
|
||||
uint8_t* buffer = NULL; /**< input/output buffer for read/write commands/functions */
|
||||
size_t buffer_size = 0; /**< size of buffer in bits */
|
||||
volatile size_t buffer_bit = 0; /**< number of bits read/written */
|
||||
uint32_t buffer_size = 0; /**< size of buffer in bits */
|
||||
volatile uint32_t buffer_bit = 0; /**< number of bits read/written */
|
||||
|
||||
void onewire_master_setup(void)
|
||||
{
|
||||
|
@ -81,10 +82,10 @@ void onewire_master_setup(void)
|
|||
timer_set_prescaler(TIM(ONEWIRE_MASTER_TIMER), 1-1); // don't use prescale since this 16 bits timer allows to wait > 480 us used for the reset pulse ( 1/(72E6/1/(2**16))=910us )
|
||||
|
||||
// use comparator to time signal (without using the output), starting at slot start
|
||||
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC1, 1*(rcc_ahb_frequency/1000000)); // use compare function to time master pulling low (1 < Tlowr < 15)
|
||||
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC2, 7*(rcc_ahb_frequency/1000000)); // use compare function to read of write (1 < Trw < 15)
|
||||
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC3, 62*(rcc_ahb_frequency/1000000)); // use compare function to end time slot (60 < Tslot < 120), this will be followed by a recovery time (end of timer)
|
||||
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC4, 120*(rcc_ahb_frequency/1000000)); // use compare function to detect slave presence (60 < Tpdl < 240)
|
||||
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC1, 1*(rcc_ahb_frequency/1000000)-1); // use compare function to time master pulling low (1 < Tlowr < 15)
|
||||
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC2, 7*(rcc_ahb_frequency/1000000)-1); // use compare function to read of write (1 < Trw < 15)
|
||||
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC3, 62*(rcc_ahb_frequency/1000000)-1); // use compare function to end time slot (60 < Tslot < 120), this will be followed by a recovery time (end of timer)
|
||||
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC4, 120*(rcc_ahb_frequency/1000000)-1); // use compare function to detect slave presence (60 < Tpdl < 240)
|
||||
|
||||
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_UIF); // clear update (overflow) flag
|
||||
timer_update_on_overflow(TIM(ONEWIRE_MASTER_TIMER)); // only use counter overflow as UEV source (use overflow as start time or timeout)
|
||||
|
@ -100,7 +101,7 @@ bool onewire_master_reset(void)
|
|||
// prepare timer
|
||||
timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to reconfigure it
|
||||
timer_set_counter(TIM(ONEWIRE_MASTER_TIMER),0); // reset counter
|
||||
timer_set_period(TIM(ONEWIRE_MASTER_TIMER), 490*(rcc_ahb_frequency/1000000)); // set timeout to > 480 us (490)
|
||||
timer_set_period(TIM(ONEWIRE_MASTER_TIMER), 490*(rcc_ahb_frequency/1000000)-1); // set timeout to > 480 us
|
||||
|
||||
slave_presence = false; // reset state
|
||||
onewire_master_state = ONEWIRE_STATE_MASTER_RESET; // set new state
|
||||
|
@ -119,7 +120,7 @@ bool onewire_master_reset(void)
|
|||
}
|
||||
|
||||
/** write bits on 1-Wire bus
|
||||
* @warning buffer_size must be set to the number of bits to write and buffer must contain the data to write
|
||||
* @warning buffer_size must be set to the number of bits to writen and buffer must contain the data to write
|
||||
* @return if write succeeded
|
||||
*/
|
||||
static bool onewire_master_write(void)
|
||||
|
@ -139,7 +140,7 @@ static bool onewire_master_write(void)
|
|||
// start writing
|
||||
gpio_clear(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal low to start slot
|
||||
timer_enable_counter(TIM(ONEWIRE_MASTER_TIMER)); // start timer
|
||||
while (onewire_master_state!=ONEWIRE_STATE_DONE && onewire_master_state!=ONEWIRE_STATE_ERROR) { // wait until reset procedure completed
|
||||
while (onewire_master_state!=ONEWIRE_STATE_DONE && onewire_master_state!=ONEWIRE_STATE_ERROR) { // wait until write procedure completed
|
||||
__WFI(); // go to sleep
|
||||
}
|
||||
if (ONEWIRE_STATE_ERROR==onewire_master_state) { // an error occurred
|
||||
|
@ -157,9 +158,6 @@ static bool onewire_master_read(void)
|
|||
if (0==buffer_size) { // check input
|
||||
return false;
|
||||
}
|
||||
if (!(buffer=realloc(buffer, (buffer_size-1)/8+1))) { // allocate memory
|
||||
return false; // error in memory allocation
|
||||
}
|
||||
buffer_bit = 0; // reset bit index
|
||||
onewire_master_state = ONEWIRE_STATE_MASTER_READ; // set new state
|
||||
|
||||
|
@ -175,7 +173,7 @@ static bool onewire_master_read(void)
|
|||
// start reading
|
||||
gpio_clear(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal low to start slot
|
||||
timer_enable_counter(TIM(ONEWIRE_MASTER_TIMER)); // start timer
|
||||
while (onewire_master_state!=ONEWIRE_STATE_DONE && onewire_master_state!=ONEWIRE_STATE_ERROR) { // wait until reset procedure completed
|
||||
while (onewire_master_state!=ONEWIRE_STATE_DONE && onewire_master_state!=ONEWIRE_STATE_ERROR) { // wait until read procedure completed
|
||||
__WFI(); // go to sleep
|
||||
}
|
||||
if (ONEWIRE_STATE_ERROR==onewire_master_state) { // an error occurred
|
||||
|
@ -184,14 +182,14 @@ static bool onewire_master_read(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
uint8_t onewire_master_crc(uint8_t* data, size_t size)
|
||||
uint8_t onewire_master_crc(uint8_t* data, uint32_t length)
|
||||
{
|
||||
if (NULL==data || 0==size) { // check input
|
||||
if (NULL==data || 0==length) { // check input
|
||||
return 0; // wrong input
|
||||
}
|
||||
|
||||
uint8_t crc = 0x00; // initial value
|
||||
for (uint8_t i=0; i<size; i++) { // go through every byte
|
||||
for (uint8_t i=0; i<length; i++) { // go through every byte
|
||||
crc ^= data[i]; // XOR byte
|
||||
for (uint8_t b=0; b<8; b++) { // go through every bit
|
||||
if (crc&0x01) { // least significant bit is set (we are using the reverse way)
|
||||
|
@ -204,14 +202,11 @@ uint8_t onewire_master_crc(uint8_t* data, size_t size)
|
|||
return crc;
|
||||
}
|
||||
|
||||
bool onewire_master_function_read(uint8_t function, uint8_t* data, size_t bits)
|
||||
bool onewire_master_function_read(uint8_t function, uint8_t* data, uint32_t bits)
|
||||
{
|
||||
// send function command
|
||||
buffer_size = 8; // function command is only one byte
|
||||
if (!(buffer=realloc(buffer, (buffer_size-1)/8+1))) { // allocate memory
|
||||
return false; // error in memory allocation
|
||||
}
|
||||
buffer[0] = function; // set function command
|
||||
buffer = &function; // set the buffer to the function code
|
||||
if (!onewire_master_write()) { // send command
|
||||
return false; // an error occurred
|
||||
}
|
||||
|
@ -222,52 +217,19 @@ bool onewire_master_function_read(uint8_t function, uint8_t* data, size_t bits)
|
|||
|
||||
// read data
|
||||
buffer_size = bits; // save number of bits to read
|
||||
buffer = data; // set the buffer to the data to write
|
||||
if (!onewire_master_read()) { // read bits from slave
|
||||
return false; // an error occurred
|
||||
}
|
||||
|
||||
// copy data to user buffer
|
||||
for (uint8_t i=0; i<bits/8; i++) { // copy bytes
|
||||
data[i] = buffer[i]; // copy data
|
||||
}
|
||||
// copy remaining bits
|
||||
switch (bits%8) {
|
||||
case 1:
|
||||
data[(bits-1)/8] = data[(bits-1)/8]&0x01;
|
||||
break;
|
||||
case 2:
|
||||
data[(bits-1)/8] = data[(bits-1)/8]&0x03;
|
||||
break;
|
||||
case 3:
|
||||
data[(bits-1)/8] = data[(bits-1)/8]&0x07;
|
||||
break;
|
||||
case 4:
|
||||
data[(bits-1)/8] = data[(bits-1)/8]&0x0f;
|
||||
break;
|
||||
case 5:
|
||||
data[(bits-1)/8] = data[(bits-1)/8]&0x1f;
|
||||
break;
|
||||
case 6:
|
||||
data[(bits-1)/8] = data[(bits-1)/8]&0x3f;
|
||||
break;
|
||||
case 7:
|
||||
data[(bits-1)/8] = data[(bits-1)/8]&0x7f;
|
||||
break;
|
||||
case 0: // no bits remaining
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onewire_master_function_write(uint8_t function, uint8_t* data, size_t bits)
|
||||
bool onewire_master_function_write(uint8_t function, uint8_t* data, uint32_t bits)
|
||||
{
|
||||
// send function command
|
||||
buffer_size = 8; // function command is only one byte
|
||||
if (!(buffer=realloc(buffer, (buffer_size-1)/8+1))) { // allocate memory
|
||||
return false; // error in memory allocation
|
||||
}
|
||||
buffer[0] = function; // set function command
|
||||
buffer = &function; // set the buffer to the function code
|
||||
if (!onewire_master_write()) { // send command
|
||||
return false; // an error occurred
|
||||
}
|
||||
|
@ -278,12 +240,7 @@ bool onewire_master_function_write(uint8_t function, uint8_t* data, size_t bits)
|
|||
|
||||
// copy data from user buffer
|
||||
buffer_size = bits; // save number of bits to write
|
||||
if (!(buffer=realloc(buffer, (buffer_size-1)/8+1))) { // allocate memory
|
||||
return false; // error in memory allocation
|
||||
}
|
||||
for (uint8_t i=0; i<(buffer_size-1)/8+1; i++) { // copy bytes
|
||||
buffer[i] = data[i]; // copy data
|
||||
}
|
||||
buffer = data; // set the buffer to the data to write
|
||||
// write data
|
||||
if (!onewire_master_write()) { // read bits from slave
|
||||
return false; // an error occurred
|
||||
|
@ -304,7 +261,7 @@ uint64_t onewire_master_rom_read(void)
|
|||
|
||||
// return ROM code
|
||||
uint64_t code = 0;
|
||||
for (size_t i=0; i<8; i++) {
|
||||
for (uint32_t i=0; i<8; i++) {
|
||||
code += (uint64_t)rom_code[i]<<(8*i); // add byte
|
||||
}
|
||||
|
||||
|
@ -329,6 +286,7 @@ bool onewire_master_rom_search(uint64_t* code, bool alarm)
|
|||
*code = 0; // restart search codes
|
||||
}
|
||||
|
||||
buffer = (uint8_t*){0}; // buffer to read up to two bits
|
||||
for (uint8_t bit=0; bit<64; bit++) { // go through all 64 bits ROM code
|
||||
buffer_size = 2; // read two first bits to detect conflict
|
||||
if (!onewire_master_read()) { // read ROM ID from slave
|
||||
|
@ -353,9 +311,6 @@ bool onewire_master_rom_search(uint64_t* code, bool alarm)
|
|||
goto end; // an error has occurred
|
||||
}
|
||||
buffer_size = 1; // to send next bit
|
||||
if (!(buffer=realloc(buffer, 1))) { // allocate memory
|
||||
goto end; // an error has occurred
|
||||
}
|
||||
buffer[0] = (*code>>bit); // set bit to send
|
||||
if (!onewire_master_write()) { // send bit
|
||||
goto end; // an error has occurred
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2017
|
||||
* @note peripherals used: timer @ref onewire_master_timer, GPIO @ref onewire_master_gpio
|
||||
* @warning this library does not support parasite power mode
|
||||
* @note overdrive mode is not supported
|
||||
* @warning this library does not support active parasite power mode (more than the pull-up resistor itself)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
@ -30,11 +31,11 @@ bool onewire_master_reset(void);
|
|||
/** compute CRC for 1-Wire
|
||||
* @note this CRC-8 uses normal polynomial 0x31, reverse polynomial 0x8C, start value 0x00
|
||||
* @param[in] data bytes on which to calculate CRC checksum on
|
||||
* @param[in] size number of bytes in data
|
||||
* @param[in] length number of bytes in data
|
||||
* @return computed CRC checksum
|
||||
*/
|
||||
uint8_t onewire_master_crc(uint8_t* data, size_t size);
|
||||
/** send READ ROM command
|
||||
uint8_t onewire_master_crc(uint8_t* data, uint32_t length);
|
||||
/** send READ ROM command and read ROM code response
|
||||
* @note user needs to send reset pulse before
|
||||
* @return ROM code read
|
||||
*/
|
||||
|
@ -65,7 +66,7 @@ bool onewire_master_rom_match(uint64_t code);
|
|||
* @param[in] bits number of bits to read (0 if only the function command should be sent)
|
||||
* @return if operation succeeded
|
||||
*/
|
||||
bool onewire_master_function_read(uint8_t function, uint8_t* data, size_t bits);
|
||||
bool onewire_master_function_read(uint8_t function, uint8_t* data, uint32_t bits);
|
||||
/** issue function and write data
|
||||
* @note user needs to send a ROM command before
|
||||
* @param[in] function function command to send
|
||||
|
@ -73,4 +74,4 @@ bool onewire_master_function_read(uint8_t function, uint8_t* data, size_t bits);
|
|||
* @param[in] bits number of bits to write (0 if only the function command should be sent)
|
||||
* @return if operation succeeded
|
||||
*/
|
||||
bool onewire_master_function_write(uint8_t function, uint8_t* data, size_t bits);
|
||||
bool onewire_master_function_write(uint8_t function, uint8_t* data, uint32_t bits);
|
||||
|
|
Loading…
Reference in New Issue