void start_twi_slave(uint8_t slave_address_in, uint8_t use_sleep, void (*data_callback_in)(uint8_t input_buffer_length, const uint8_t *input_buffer, uint8_t *output_buffer_length, uint8_t *output_buffer), void (*idle_callback_in)(void)) { uint8_t call_datacallback = 0; slave_address = slave_address_in; data_callback = data_callback_in; idle_callback = idle_callback_in; input_buffer_length = 0; output_buffer_length = 0; output_buffer_current = 0; ss_state = ss_state_idle; init_twi_slave(slave_address_in); for (;;) { if(idle_callback) { idle_callback(); } if (ss_state == ss_state_new_data) { call_datacallback = 1; } if(call_datacallback) { output_buffer_length = 0; output_buffer_current = 0; data_callback(input_buffer_length, input_buffer, &output_buffer_length, output_buffer); input_buffer_length = 0; call_datacallback = 0; ss_state = ss_state_idle; } } }
void usi_twi_slave(uint8_t slave_address_in, uint8_t use_sleep, void (*data_callback_in)(uint8_t buffer_size, volatile uint8_t input_buffer_length, volatile const uint8_t *input_buffer, volatile uint8_t *output_buffer_length, volatile uint8_t *output_buffer), void (*idle_callback_in)(void)) { slave_address = slave_address_in; data_callback = data_callback_in; idle_callback = idle_callback_in; input_buffer_length = 0; output_buffer_length = 0; output_buffer_current = 0; ss_state = ss_state_before_start; if(use_sleep) set_sleep_mode(SLEEP_MODE_IDLE); twi_init(); sei(); for(;;) { if(use_sleep && (ss_state == ss_state_before_start)) sleep_mode(); if(USISR & _BV(USIPF)) { cli(); #ifdef USE_STATS if(stats_enabled)stop_conditions_count++; #endif USISR |= _BV(USIPF); // clear stop condition flag switch(ss_state) { case(ss_state_after_start): { twi_reset(); break; } case(ss_state_data_processed): { #ifdef USE_STATS if(stats_enabled)local_frames_count++; #endif output_buffer_length = 0; output_buffer_current = 0; data_callback(buffer_size, input_buffer_length, input_buffer, &output_buffer_length, output_buffer); input_buffer_length = 0; break; } } ss_state = ss_state_before_start; sei(); } if(idle_callback) { idle_callback(); #ifdef USE_STATS if(stats_enabled)idle_call_count++; #endif } } }