📄 main.c
字号:
{
*(++iso_msg_pntr) = ascii2byte(serial_msg_pntr);
serial_msg_pntr += 2;
}
// send ISO message and save return code
unsigned char return_code = iso_send_msg(iso_msg_buf, serial_msg_len+4);
// skip receive in case of transmit error or RESPONSE disabled
if( (return_code == ISO_RETURN_CODE_OK) && CHECKBIT(parameter_bits, RESPONSE) )
{
unsigned char time_count = 0;
do
{
/*
Run this loop until we received a valid response frame, or response timed out,
or the bus was idle for 100ms or an bus error occured.
*/
cnt = iso_recv_msg(iso_msg_buf); // receive ISO respond
/*
timeout_multiplier is by default 25
the iso_recv_msg() has a timeout of 4ms
so the loop will run 100ms by default before timeout
*/
++time_count;
if(time_count >= timeout_multiplier)
return ISO_RETURN_CODE_NO_DATA;
/*
Check for bus error. End the loop then.
*/
if( cnt == (ISO_RETURN_CODE_BUS_ERROR & 0x80) ) // check if we got an error code or just number of recv bytes
{
if(CHECKBIT(parameter_bits, PACKED))
{
serial_putc(0x80); // lenght byte with error indicator set
return ISO_RETURN_CODE_DATA; // surpress any other output
}
else
return cnt & 0x7F; // return "receive message" error code
}
iso_msg_pntr = &iso_msg_buf[0];
} while( auto_recv_addr != *(iso_msg_pntr+1) );
// check respond CS
if( *(iso_msg_pntr+(cnt-1)) != iso_checksum(iso_msg_buf, cnt-1) )
{
if(CHECKBIT(parameter_bits, PACKED))
{
serial_putc(0x80); // length byte with error indicator set
return ISO_RETURN_CODE_DATA; // surpress any other output
}
else
return ISO_RETURN_CODE_DATA_ERROR;
}
// check for respond from correct addr in auto or man recv mode
if( auto_recv_addr != *(iso_msg_pntr+1) )
{
if(CHECKBIT(parameter_bits, PACKED))
{
serial_putc(0x00); // length byte
return ISO_RETURN_CODE_DATA; // surpress any other output
}
else
return ISO_RETURN_CODE_NO_DATA;
}
if( !CHECKBIT(parameter_bits, HEADER) )
{ // surpess CRC and header bytes output
cnt -= 4;
iso_msg_pntr += 3;
}
if(CHECKBIT(parameter_bits, PACKED))
serial_putc(cnt); // length byte
// output response data
for(;cnt > 0; --cnt)
{
if(CHECKBIT(parameter_bits, PACKED))
serial_putc(*iso_msg_pntr++); // length byte
else
{
serial_put_byte2ascii(*iso_msg_pntr++);
serial_putc(' ');
}
}
if(!CHECKBIT(parameter_bits, PACKED))
{// formated output with CR and optional LF
serial_putc('\r');
if(CHECKBIT(parameter_bits, LINEFEED)) serial_putc('\n');
}
return ISO_RETURN_CODE_DATA; // surpress any other output
} // end if ISO OK && RESPONSE
else // transmit error or show RESPONSE OFF, return error code
return return_code;
} // end if !AT
// we should never reach this return
return 0;
} // end serial_processing
/*
**---------------------------------------------------------------------------
**
** Abstract: Send program ident string to terminal
**
**
** Parameters: none
**
**
** Returns: none
**
**
**---------------------------------------------------------------------------
*/
void ident(void)
{
serial_puts_P(ident_txt); // show code description
}
/*
**---------------------------------------------------------------------------
**
** Abstract: Convert 2 byte ASCII hex to 1 byte decimal
**
**
** Parameters: Pointer to first ASCII char
**
**
** Returns: decimal value
**
**
**---------------------------------------------------------------------------
*/
static unsigned char ascii2byte(char *val)
{
unsigned char temp = *val;
if(temp > 0x60) temp -= 39; // convert chars a-f
temp -= 48; // convert chars 0-9
temp *= 16;
temp += *(val+1);
if(*(val+1) > 0x60) temp -= 39; // convert chars a-f
temp -= 48; // convert chars 0-9
return temp;
}
/*
**---------------------------------------------------------------------------
**
** Abstract: Send one byte via USART
**
** Parameters: data byte
**
** Returns: NULL
**
**---------------------------------------------------------------------------
*/
void serial_putc(unsigned char data)
{
// wait for USART to become available
while ( (UCSRA & _BV(UDRE)) != _BV(UDRE));
UDR = data; // send character
}; //end usart_putc
/*
**---------------------------------------------------------------------------
**
** Abstract: Make 2 byte ASCII from one byte binary and send to terminal
**
** Parameters: input byte
**
** Returns: none
**
**---------------------------------------------------------------------------
*/
void serial_put_byte2ascii(unsigned char val)
{
unsigned char ascii1=val;
serial_putc( ((ascii1>>4) < 10) ? (ascii1>>4) + 48 : (ascii1>>4) + 55 ); // upper nibble
serial_putc( ((val&0x0f) < 10) ? (val&0x0f) + 48 : (val&0x0f) + 55 ); // lower nibble
}
/*
**---------------------------------------------------------------------------
**
** Abstract: Print string in program memory to terminal
**
** Parameters: Pointer to string
**
** Returns: none
**
**---------------------------------------------------------------------------
*/
void serial_puts_P(const char *s)
{
while( pgm_read_byte(&*s)) serial_putc( pgm_read_byte(&*s++));// send string char by char
}
/*
**---------------------------------------------------------------------------
**
** Abstract: Print command prompt to terminal
**
**
** Parameters: none
**
**
** Returns: none
**
**
**---------------------------------------------------------------------------
*/
void print_prompt(void)
{
serial_puts_P(PSTR("\n\r>")); // send new command prompt
}
/*
**---------------------------------------------------------------------------
**
** Abstract: USART Receive Interrupt
**
** Parameters: none
**
** Returns: none
**
**---------------------------------------------------------------------------
*/
SIGNAL(SIG_UART_RECV)
{
signed char *hlp_pntr = &serial_msg_buf[sizeof(serial_msg_buf)-1]; // get end of serial buffer
// check for buffer end, prevent buffer overflow
if ( serial_msg_pntr > hlp_pntr )
{
serial_msg_pntr = &serial_msg_buf[sizeof(serial_msg_buf)-1];
}
unsigned char in_char = UDR; // get received char
if(CHECKBIT(parameter_bits,MON_RX) || CHECKBIT(parameter_bits,MON_TX))
{
CLEARBIT(parameter_bits,MON_RX);
CLEARBIT(parameter_bits,MON_TX);
print_prompt(); // command prompt to terminal
}
else
{
if( CHECKBIT(parameter_bits,ECHO) ) // return char when echo is on
serial_putc(in_char);
// check for terminating char
if(in_char == 0x0D)
{
*(serial_msg_pntr) = 0x00; // terminate received message
switch ( serial_processing() ) // process serial message
{
case ISO_RETURN_CODE_OK: // success
serial_puts_P(PSTR("\n\rOK"));
print_prompt(); // command prompt to terminal
break;
case ISO_RETURN_CODE_BUS_BUSY: // bus was busy
serial_puts_P(bus_busy_txt);
print_prompt(); // command prompt to terminal
break;
case ISO_RETURN_CODE_BUS_ERROR: // bus error detected
serial_puts_P(bus_error_txt);
print_prompt(); // command prompt to terminal
break;
case ISO_RETURN_CODE_DATA_ERROR: // data error detected
serial_puts_P(data_error_txt);
print_prompt(); // command prompt to terminal
break;
case ISO_RETURN_CODE_NO_DATA: // no data response (response timeout)
serial_puts_P(no_data_txt);
print_prompt(); // command prompt to terminal
break;
case ISO_RETURN_CODE_INIT_ERROR: // bus init failed
serial_puts_P(bus_init_txt);
print_prompt(); // command prompt to terminal
break;
case ISO_RETURN_CODE_DATA: // data response
serial_puts_P(PSTR("\n\r?"));
break;
default: // unknown error
serial_puts_P(PSTR("\n\r?"));
print_prompt(); // command prompt to terminal
}
serial_msg_pntr = &serial_msg_buf[0]; // start new message
}
// received char was no termination
if(isalnum((int)in_char))
{ // check for valid alphanumeric char and save in buffer
*serial_msg_pntr = in_char;
++serial_msg_pntr;
}
}
};// end of UART receive interrupt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -