onewire_master: remove malloc in favor of pre-allocated buffers

This commit is contained in:
King Kévin 2017-08-01 19:17:22 +02:00
parent 39100c53b6
commit bd2f1642cc
2 changed files with 31 additions and 75 deletions

View File

@ -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

View File

@ -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);