int serial_send_disconnect_packet(int fd) { uint8_t packet[SEND_PACKET_SIZE]; memset(&packet[0], 0, sizeof(packet)); packet[0] = 0x5A; packet[19] = 0x5A; return serial_send_packet(fd, &packet); }
int soft_serial_transaction(void) { SSTD_t *trans = Transaction_table; #else int soft_serial_transaction(int sstd_index) { SSTD_t *trans = &Transaction_table[sstd_index]; #endif cli(); // signal to the target that we want to start a transaction serial_output(); serial_low(); _delay_us(SLAVE_INT_WIDTH_US); #ifndef SERIAL_USE_MULTI_TRANSACTION // wait for the target response serial_input_with_pullup(); _delay_us(SLAVE_INT_RESPONSE_TIME); // check if the target is present if (serial_read_pin()) { // target failed to pull the line low, assume not present serial_output(); serial_high(); *trans->status = TRANSACTION_NO_RESPONSE; sei(); return TRANSACTION_NO_RESPONSE; } #else // send transaction table index sync_send(); _delay_sub_us(TID_SEND_ADJUST); serial_write_chunk(sstd_index, 4); serial_delay_half1(); // wait for the target response (step1 low->high) serial_input_with_pullup(); while( !serial_read_pin() ) { _delay_sub_us(2); } // check if the target is present (step2 high->low) for( int i = 0; serial_read_pin(); i++ ) { if (i > SLAVE_INT_ACK_WIDTH + 1) { // slave failed to pull the line low, assume not present serial_output(); serial_high(); *trans->status = TRANSACTION_NO_RESPONSE; sei(); return TRANSACTION_NO_RESPONSE; } _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); } #endif // initiator recive phase // if the target is present syncronize with it if( trans->target2initiator_buffer_size > 0 ) { if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, trans->target2initiator_buffer_size) ) { serial_output(); serial_high(); *trans->status = TRANSACTION_DATA_ERROR; sei(); return TRANSACTION_DATA_ERROR; } } // initiator switch to output change_reciver2sender(); // initiator send phase if( trans->initiator2target_buffer_size > 0 ) { serial_send_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size); } // always, release the line when not in use sync_send(); *trans->status = TRANSACTION_END; sei(); return TRANSACTION_END; }