picstick
An AVR based programming adapter for PIC microcontrollers.
/** @file commands.c
*
* Handle serial commands from the host and convert them into ICSP commands.
*
*/
#include <string.h>
#include <avr/io.h>
#include <util/delay.h>
#include "uuart.h"
#include "icsp.h"
#include "commands.h"
void
cmd_ping (void)
{
uuart_tx_byte(RESP_PONG);
}
void
cmd_unknown (void)
{
uuart_tx_byte(RESP_UNK);
}
void
cmd_start_msb (void)
{
icsp_enable_msb();
uuart_tx_byte(RESP_OK);
}
void
cmd_start_lsb (void)
{
icsp_enable_lsb();
uuart_tx_byte(RESP_OK);
}
void
cmd_quit (void)
{
icsp_disable();
uuart_tx_byte(RESP_OK);
}
void
cmd_command (void)
{
icsp_command(uuart_rx_byte());
// Wait 100ms for command to finish executing
_delay_ms(10);
uuart_tx_byte(RESP_OK);
}
void
cmd_payload (void)
{
// Get command
unsigned char cmd = uuart_rx_byte();
// Get payload
unsigned long payload = (unsigned long)uuart_rx_byte() << 16;
payload |= (unsigned long)uuart_rx_byte() << 8;
payload |= (unsigned long)uuart_rx_byte();
// Send command
icsp_command(cmd);
// Send payload
icsp_payload(payload);
// Wait 100ms for command to finish executing
_delay_ms(10);
uuart_tx_byte(RESP_OK);
}
void
cmd_read (void)
{
// Get command
unsigned char cmd = uuart_rx_byte();
// Send command
icsp_command(cmd);
// Wait 10ms for command to finish executing
_delay_ms(10);
// Read response payload
unsigned long resp = icsp_read();
uuart_tx_byte((resp >> 16) & 0xFF);
uuart_tx_byte((resp >> 8) & 0xFF);
uuart_tx_byte(resp & 0xFF);
}
void
cmd_short_command (void)
{
icsp_short_command(uuart_rx_byte());
// Wait 10ms for command to finish executing
_delay_ms(10);
uuart_tx_byte(RESP_OK);
}
void
cmd_short_payload (void)
{
// Get command
unsigned char cmd = uuart_rx_byte();
// Get payload
uuart_rx_byte();
unsigned int payload = (unsigned int)uuart_rx_byte() << 8;
payload |= (unsigned int)uuart_rx_byte();
// Send command
icsp_short_command(cmd);
// Wait 10ms for command to finish executing
_delay_ms(10);
// Send payload
icsp_short_payload(payload);
// Wait 10ms for command to finish executing
_delay_ms(10);
uuart_tx_byte(RESP_OK);
}
void
cmd_short_read (void)
{
// Get command
unsigned char cmd = uuart_rx_byte();
// Send command
icsp_short_command(cmd);
// Wait 10ms for command to finish executing
_delay_ms(10);
// Read response payload
unsigned int resp = icsp_short_read();
uuart_tx_byte(0);
uuart_tx_byte((resp >> 8) & 0xFF);
uuart_tx_byte(resp & 0xFF);
}
void
handle_command (void)
{
unsigned char cmd = uuart_rx_byte();
switch (cmd)
{
case CMD_PING:
cmd_ping();
break;
case CMD_START_MSB:
cmd_start_msb();
break;
case CMD_START_LSB:
cmd_start_lsb();
break;
case CMD_QUIT:
cmd_quit();
break;
case CMD_COMMAND:
cmd_command();
break;
case CMD_PAYLOAD:
cmd_payload();
break;
case CMD_READ:
cmd_read();
break;
case CMD_SHORT_COMMAND:
cmd_short_command();
break;
case CMD_SHORT_PAYLOAD:
cmd_short_payload();
break;
case CMD_SHORT_READ:
cmd_short_read();
break;
default:
cmd_unknown();
break;
}
}