1-Wire: remove misleading parasitic power function, add byte function

This commit is contained in:
King Kévin 2018-05-09 21:27:00 +02:00
parent accb5fd95b
commit 444534e214
2 changed files with 81 additions and 70 deletions

View File

@ -15,7 +15,7 @@
/** library for 1-wire protocol as master (code) /** library for 1-wire protocol as master (code)
* @file onewire_master.c * @file onewire_master.c
* @author King Kévin <kingkevin@cuvoodoo.info> * @author King Kévin <kingkevin@cuvoodoo.info>
* @date 2017 * @date 2017-2018
* @note peripherals used: timer @ref onewire_master_timer, GPIO @ref onewire_master_gpio * @note peripherals used: timer @ref onewire_master_timer, GPIO @ref onewire_master_gpio
* @note overdrive mode is not provided * @note overdrive mode is not provided
* @implements 1-Wire protocol description from Book of iButton Standards * @implements 1-Wire protocol description from Book of iButton Standards
@ -43,14 +43,6 @@
#define ONEWIRE_MASTER_TIMER 2 /**< timer ID */ #define ONEWIRE_MASTER_TIMER 2 /**< timer ID */
/** @} */ /** @} */
/** @defgroup onewire_master_gpio GPIO used for 1-wire signal
* @note external pull-up resistor on pin is required (< 5 kOhm)
* @{
*/
#define ONEWIRE_MASTER_PORT A /**< GPIO port */
#define ONEWIRE_MASTER_PIN 4 /**< GPIO pin */
/** @} */
/** state of 1-Wire communication */ /** state of 1-Wire communication */
volatile enum { volatile enum {
ONEWIRE_STATE_IDLE, /**< no current communication */ ONEWIRE_STATE_IDLE, /**< no current communication */
@ -67,43 +59,30 @@ static volatile bool slave_presence = false; /**< if slaves have been detected *
static uint8_t* buffer = NULL; /**< input/output buffer for read/write commands/functions */ static uint8_t* buffer = NULL; /**< input/output buffer for read/write commands/functions */
static uint32_t buffer_size = 0; /**< size of buffer in bits */ static uint32_t buffer_size = 0; /**< size of buffer in bits */
static volatile uint32_t buffer_bit = 0; /**< number of bits read/written */ static volatile uint32_t buffer_bit = 0; /**< number of bits read/written */
static bool onewire_master_parasite = false; /**< if parasite power should be provided whenever the is no communication */
static uint16_t onewire_master_recovery = 0; /**< the recovery time in us (1 < Trec) */
void onewire_master_setup(bool parasite, uint16_t recovery) void onewire_master_setup(void)
{ {
// setup GPIO with external interrupt // setup GPIO with external interrupt
rcc_periph_clock_enable(RCC_GPIO(ONEWIRE_MASTER_PORT)); // enable clock for GPIO peripheral rcc_periph_clock_enable(RCC_GPIO(ONEWIRE_MASTER_PORT)); // enable clock for GPIO peripheral
gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // idle is high (using pull-up resistor) gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // idle is high (using pull-up resistor)
onewire_master_parasite = parasite; // save if we should provide parasite power gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(ONEWIRE_MASTER_PIN)); // normal 1-Wire communication (only using external pull-up resistor)
// setup GPIO pin as output (master starts communication before slave replies)
if (onewire_master_parasite) {
gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(ONEWIRE_MASTER_PIN)); // provide parasite power (external pull-up resistor is still require for communication)
} else {
gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(ONEWIRE_MASTER_PIN)); // normal 1-Wire communication (only using external pull-up resistor)
}
// setup timer to generate/measure signal timing // setup timer to generate/measure signal timing
rcc_periph_clock_enable(RCC_TIM(ONEWIRE_MASTER_TIMER)); // enable clock for timer peripheral rcc_periph_clock_enable(RCC_TIM(ONEWIRE_MASTER_TIMER)); // enable clock for timer peripheral
timer_reset(TIM(ONEWIRE_MASTER_TIMER)); // reset timer state timer_reset(TIM(ONEWIRE_MASTER_TIMER)); // reset timer state
timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to configure it
timer_set_mode(TIM(ONEWIRE_MASTER_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up timer_set_mode(TIM(ONEWIRE_MASTER_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up
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 ) 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 // use comparator to time signal (without using the output), starting at slot start
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF); // clear flag
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC1, 1*(rcc_ahb_frequency/1000000)-1); // use compare function to time master pulling low when reading (1 < Tlowr < 15) timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC1, 1*(rcc_ahb_frequency/1000000)-1); // use compare function to time master pulling low when reading (1 < Tlowr < 15)
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC2IF); // clear flag
timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC2, 7*(rcc_ahb_frequency/1000000)-1); // use compare function to read or write 0 or 1 (1 < Trw < 15) timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC2, 7*(rcc_ahb_frequency/1000000)-1); // use compare function to read or write 0 or 1 (1 < Trw < 15)
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF); // clear flag
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_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, (70-10)*(rcc_ahb_frequency/1000000)-1); // use compare function to detect slave presence (15 < Tpdh < 60 + 60 < Tpdl < 240), with hand tunig timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC4IF); // clear flag
onewire_master_recovery = 5; // set minimum recovery time timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC4, (70-10)*(rcc_ahb_frequency/1000000)-1); // use compare function to detect slave presence (15 < Tpdh < 60 + 60 < Tpdl < 240), with hand tuning
if (recovery>onewire_master_recovery) {
onewire_master_recovery = recovery; // save desired recovery time
}
if (UINT16_MAX/onewire_master_recovery<(rcc_ahb_frequency/1000000)) { // catch integer overflow
onewire_master_recovery = UINT16_MAX; // save maximum value
} else {
onewire_master_recovery *= (rcc_ahb_frequency/1000000); // save actual recovery time value
}
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_UIF); // clear update (overflow) flag 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) timer_update_on_overflow(TIM(ONEWIRE_MASTER_TIMER)); // only use counter overflow as UEV source (use overflow as start time or timeout)
timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_UIE); // enable update interrupt for overflow timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_UIE); // enable update interrupt for overflow
@ -113,6 +92,17 @@ void onewire_master_setup(bool parasite, uint16_t recovery)
onewire_master_state = ONEWIRE_STATE_IDLE; // reset state onewire_master_state = ONEWIRE_STATE_IDLE; // reset state
} }
void onewire_master_release(void)
{
// release timer
timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer
timer_reset(TIM(ONEWIRE_MASTER_TIMER)); // reset timer state
rcc_periph_clock_disable(RCC_TIM(ONEWIRE_MASTER_TIMER)); // disable clock for timer peripheral
// release GPIO
gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO(ONEWIRE_MASTER_PIN)); // put back to input floating
}
bool onewire_master_reset(void) bool onewire_master_reset(void)
{ {
// prepare timer // prepare timer
@ -148,14 +138,8 @@ static bool onewire_master_write(void)
// prepare timer // prepare timer
timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to reconfigure it timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to reconfigure it
timer_set_counter(TIM(ONEWIRE_MASTER_TIMER),0); // reset counter timer_set_counter(TIM(ONEWIRE_MASTER_TIMER), 0); // reset counter
uint16_t timeout = TIM_CCR3(TIM(ONEWIRE_MASTER_TIMER)); // time until new slot (= end of slot+recovery) timer_set_period(TIM(ONEWIRE_MASTER_TIMER), TIM_CCR3(TIM(ONEWIRE_MASTER_TIMER))+2*(rcc_ahb_frequency/1000000)); // set time for new time slot (recovery timer Trec>1, after time slot end )
if (UINT16_MAX-timeout<onewire_master_recovery) { // catch integer overflow
timeout = UINT16_MAX; // set maximum value
} else {
timeout += onewire_master_recovery; // add recovery time to end of slot
}
timer_set_period(TIM(ONEWIRE_MASTER_TIMER), timeout-1); // set time for new time slot (Trec>1, after time slot end and recovery time)
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC2IF); // clear output compare flag timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC2IF); // clear output compare flag
timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC2IE); // enable compare interrupt for bit setting timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC2IE); // enable compare interrupt for bit setting
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF); // clear output compare flag timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF); // clear output compare flag
@ -188,14 +172,8 @@ static bool onewire_master_read(void)
// prepare timer // prepare timer
timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to reconfigure it timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to reconfigure it
timer_set_counter(TIM(ONEWIRE_MASTER_TIMER),0); // reset counter timer_set_counter(TIM(ONEWIRE_MASTER_TIMER), 0); // reset counter
uint16_t timeout = TIM_CCR3(TIM(ONEWIRE_MASTER_TIMER)); // time until new slot (= end of slot+recovery) timer_set_period(TIM(ONEWIRE_MASTER_TIMER), TIM_CCR3(TIM(ONEWIRE_MASTER_TIMER))+2*(rcc_ahb_frequency/1000000)); // set time for new time slot (recovery timer Trec>1, after time slot end )
if (UINT16_MAX-timeout<onewire_master_recovery) { // catch integer overflow
timeout = UINT16_MAX; // set maximum value
} else {
timeout += onewire_master_recovery; // add recovery time to end of slot
}
timer_set_period(TIM(ONEWIRE_MASTER_TIMER), timeout-1); // set time for new time slot (Trec>1, after time slot end and recovery time)
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF); // clear output compare flag timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF); // clear output compare flag
timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC1IE); // enable compare interrupt for stop pulling low timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC1IE); // enable compare interrupt for stop pulling low
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC2IF); // clear output compare flag timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC2IF); // clear output compare flag
@ -221,7 +199,7 @@ uint8_t onewire_master_crc(uint8_t* data, uint32_t length)
if (NULL==data || 0==length) { // check input if (NULL==data || 0==length) { // check input
return 0; // wrong input return 0; // wrong input
} }
uint8_t crc = 0x00; // initial value uint8_t crc = 0x00; // initial value
for (uint8_t i=0; i<length; i++) { // go through every byte for (uint8_t i=0; i<length; i++) { // go through every byte
crc ^= data[i]; // XOR byte crc ^= data[i]; // XOR byte
@ -236,12 +214,36 @@ uint8_t onewire_master_crc(uint8_t* data, uint32_t length)
return crc; return crc;
} }
bool onewire_master_read_byte(uint8_t* data)
{
if (NULL==data) { // check input
return false; // wrong input
}
// read data
buffer_size = 8; // save number of bits to read (1 byte)
buffer = data; // set the buffer to the data to write
if (!onewire_master_read()) { // read bits from slave
return false; // an error occurred
}
return true;
}
bool onewire_master_write_byte(uint8_t data)
{
// send data byte
buffer_size = 8; // function command is only one byte
buffer = &data; // set the buffer to the function code
if (!onewire_master_write()) { // send command
return false; // an error occurred
}
return true;
}
bool onewire_master_function_read(uint8_t function, uint8_t* data, uint32_t bits) bool onewire_master_function_read(uint8_t function, uint8_t* data, uint32_t bits)
{ {
// send function command // send function command
buffer_size = 8; // function command is only one byte if (!onewire_master_write_byte(function)) {
buffer = &function; // set the buffer to the function code
if (!onewire_master_write()) { // send command
return false; // an error occurred return false; // an error occurred
} }
@ -262,9 +264,7 @@ bool onewire_master_function_read(uint8_t function, uint8_t* data, uint32_t bits
bool onewire_master_function_write(uint8_t function, uint8_t* data, uint32_t bits) bool onewire_master_function_write(uint8_t function, uint8_t* data, uint32_t bits)
{ {
// send function command // send function command
buffer_size = 8; // function command is only one byte if (!onewire_master_write_byte(function)) {
buffer = &function; // set the buffer to the function code
if (!onewire_master_write()) { // send command
return false; // an error occurred return false; // an error occurred
} }
@ -346,7 +346,7 @@ bool onewire_master_rom_search(uint64_t* code, bool alarm)
goto end; // an error has occurred goto end; // an error has occurred
} }
buffer_size = 1; // to send next bit buffer_size = 1; // to send next bit
buffer[0] = (*code>>bit); // set bit to send buffer[0] = ((*code)>>bit); // set bit to send
if (!onewire_master_write()) { // send bit if (!onewire_master_write()) { // send bit
goto end; // an error has occurred goto end; // an error has occurred
} }
@ -354,7 +354,7 @@ bool onewire_master_rom_search(uint64_t* code, bool alarm)
// verify ROM code // verify ROM code
uint8_t rom_code[8] = {0}; // to store ROM code uint8_t rom_code[8] = {0}; // to store ROM code
for (uint8_t i=0; i<LENGTH(rom_code); i++) { for (uint8_t i=0; i<LENGTH(rom_code); i++) {
rom_code[i] = *code>>(8*i); // split and save last code in ROM code rom_code[i] = (*code)>>(8*i); // split and save last code in ROM code
} }
if (onewire_master_crc(rom_code, LENGTH(rom_code))) { // verify checksum if (onewire_master_crc(rom_code, LENGTH(rom_code))) { // verify checksum
*code = 0; // return the last code found since it's valid *code = 0; // return the last code found since it's valid
@ -389,7 +389,6 @@ bool onewire_master_rom_match(uint64_t code)
return true; return true;
} }
/** interrupt service routine called for timer */ /** interrupt service routine called for timer */
void TIM_ISR(ONEWIRE_MASTER_TIMER)(void) void TIM_ISR(ONEWIRE_MASTER_TIMER)(void)
{ {
@ -428,11 +427,6 @@ void TIM_ISR(ONEWIRE_MASTER_TIMER)(void)
gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal high (idle state) gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal high (idle state)
onewire_master_state = ONEWIRE_STATE_ERROR; // indicate error onewire_master_state = ONEWIRE_STATE_ERROR; // indicate error
} }
if (onewire_master_parasite && (ONEWIRE_STATE_ERROR==onewire_master_state || ONEWIRE_STATE_DONE==onewire_master_state)) {
gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(ONEWIRE_MASTER_PIN)); // provide parasite power
} else {
gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(ONEWIRE_MASTER_PIN)); // normal 1-Wire communication (only using external pull-up resistor)
}
} else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF)) { // compare event happened for master pull low end for read } else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF)) { // compare event happened for master pull low end for read
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF); // clear flag timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF); // clear flag
switch (onewire_master_state) { switch (onewire_master_state) {
@ -475,9 +469,6 @@ void TIM_ISR(ONEWIRE_MASTER_TIMER)(void)
} else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF)) { // compare event happened for end to time slot } else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF)) { // compare event happened for end to time slot
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF); // clear flag timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF); // clear flag
gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal high to end time slot gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal high to end time slot
if (onewire_master_parasite) { // provide power during recovery time
gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(ONEWIRE_MASTER_PIN)); // provide parasite power
}
} else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC4IF)) { // compare event happened for slave presence detection } else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC4IF)) { // compare event happened for slave presence detection
timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC4IF); // clear flag timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC4IF); // clear flag
if (gpio_get(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN))) { // check is a slave let its presence know by pulling low if (gpio_get(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN))) { // check is a slave let its presence know by pulling low

View File

@ -15,18 +15,26 @@
/** library for 1-wire protocol as master (API) /** library for 1-wire protocol as master (API)
* @file onewire_master.h * @file onewire_master.h
* @author King Kévin <kingkevin@cuvoodoo.info> * @author King Kévin <kingkevin@cuvoodoo.info>
* @date 2017 * @date 2017-2018
* @note peripherals used: timer @ref onewire_master_timer, GPIO @ref onewire_master_gpio * @note peripherals used: timer @ref onewire_master_timer, GPIO @ref onewire_master_gpio
* @note overdrive mode is not provided * @note overdrive mode is not provided
*/ */
#pragma once #pragma once
/** setup 1-wire peripheral /** @defgroup onewire_master_gpio GPIO used for 1-wire signal
* @param[in] parasite enable parasite power (provide power over 1-Wire line when not communicating) * @note external pull-up resistor on pin is required (< 5 kOhm)
* @warning multiple masters and interrupts are prevented when parasite power is used * @{
* @param[in] recovery recovery time in us between timeslot, e.g. to ensure enough parasite power is provided (0 if not required)
*/ */
void onewire_master_setup(bool parasite, uint16_t recovery); #define ONEWIRE_MASTER_PORT C /**< GPIO port */
#define ONEWIRE_MASTER_PIN 9 /**< GPIO pin */
/** @} */
/** setup 1-wire peripheral
*/
void onewire_master_setup(void);
/** release 1-wire peripheral
*/
void onewire_master_release(void);
/** send reset pulse /** send reset pulse
* @return if slaves have indicated their presence * @return if slaves have indicated their presence
*/ */
@ -62,6 +70,18 @@ bool onewire_master_rom_skip(void);
* @return if operation succeeded * @return if operation succeeded
*/ */
bool onewire_master_rom_match(uint64_t code); bool onewire_master_rom_match(uint64_t code);
/** read data byte
* @note it is up to the user to send the reset pulse
* @param[out] data buffer to save data read
* @return if operation succeeded
*/
bool onewire_master_read_byte(uint8_t* data);
/** write data byte
* @note it is up to the user to send the reset pulse
* @param[in] data byte to write
* @return if operation succeeded
*/
bool onewire_master_write_byte(uint8_t data);
/** issue function and read data /** issue function and read data
* @note user needs to send a ROM command before * @note user needs to send a ROM command before
* @param[in] function function command to send * @param[in] function function command to send