#define ENABLE PORTD3
#define BIT(x) (1<<(x))
-OutputPacket packet;
-uint8_t out_bit;
-uint8_t out_time;
-uint8_t out_data;
-uint8_t delay_time;
+enum State
+{
+ IDLE,
+ READY,
+ SENDING
+};
+
+OutputPacket packets[4];
+uint8_t chain_length;
+uint8_t current_packet;
+volatile uint8_t trigger_value;
+volatile uint8_t packet_state = IDLE;
+static uint8_t out_bit;
+static uint8_t out_time;
+static uint8_t out_data;
+static uint8_t delay_time;
void output_init(void)
{
DDRD = (DDRD&0xF3)|0x0C;
PORTD &= ~BIT(ENABLE);
- timer_start_hz(0, 80000, 1);
+ timer_start_hz(2, 80000, 1);
+}
+
+OutputPacket *output_create_packet(void)
+{
+ while(packet_state!=IDLE) ;
+ chain_length = 1;
+ packets[0].trigger_position = 0xFF;
+ return &packets[0];
}
-void clear_packet(void)
+OutputPacket *output_create_chained_packet(void)
{
- packet.ready = 0;
- packet.sending = 0;
- packet.done = 0;
+ uint8_t i = chain_length++;
+ packets[i].trigger_position = 0xFF;
+ return &packets[i];
+}
+
+void output_send_packet(void)
+{
+ if(packet_state!=IDLE)
+ return;
+
+ current_packet = 0;
+ trigger_value = 0;
+ packet_state = READY;
+}
+
+uint8_t output_get_trigger(void)
+{
+ return trigger_value;
}
void output_set_power(uint8_t p)
PORTD &= ~BIT(ENABLE);
}
-uint8_t output_command(void)
+uint8_t output_is_power_on()
+{
+ return (PORTD&BIT(ENABLE))!=0;
+}
+
+uint8_t output_command(const uint8_t *cmd_buf, uint8_t cmd_length)
{
if(cmd_buf[0]==POWER_ON || cmd_buf[0]==POWER_OFF)
{
output_set_power(cmd_buf[0]==POWER_ON);
}
+ else if(cmd_buf[0]==READ_POWER_STATE)
+ {
+ if(cmd_length!=1)
+ return LENGTH_ERROR;
+
+ uint8_t reply[2];
+ reply[0] = POWER_STATE;
+ reply[1] = output_is_power_on();
+ interface_send(reply, 2);
+ }
else
return INVALID_COMMAND;
if(out_time && !--out_time)
{
+ OutputPacket *packet = &packets[current_packet];
++out_bit;
- if(out_bit>=packet.length)
+ if(out_bit>=packet->length)
{
PORTD &= ~BIT(POLARITY);
- if(packet.repeat_count>1)
+ if(--packet->repeat_count)
{
- if(packet.repeat_count<0xFF)
- --packet.repeat_count;
- delay_time = packet.repeat_delay;
- packet.sending = 0;
+ delay_time = packet->repeat_delay;
+ packet_state = READY;
}
else
{
- delay_time = packet.final_delay;
- packet.done = 1;
+ delay_time = packet->final_delay;
+ if(++current_packet<chain_length)
+ packet_state = READY;
+ else
+ packet_state = IDLE;
}
}
else
{
if((out_bit&7)==0)
- out_data = packet.data[out_bit>>3];
+ out_data = packet->data[out_bit>>3];
else
out_data >>= 1;
else
PORTD &= ~BIT(POLARITY);
- out_time = packet.bit_duration;
+ if(out_bit==packet->trigger_position)
+ trigger_value = packet->trigger_value;
+
+ out_time = packet->bit_duration;
}
return;
}
- if(packet.ready && !packet.sending)
+ if(packet_state==READY)
{
- packet.sending = 1;
+ OutputPacket *packet = &packets[current_packet];
+ packet_state = SENDING;
out_bit = 0;
- out_time = packet.bit_duration;
- out_data = packet.data[0];
+ out_time = packet->bit_duration;
+ out_data = packet->data[0];
if(out_data&1)
PORTD |= BIT(POLARITY);
else
}
}
-TIMER_SET_CALLBACK(0, output_tick)
+TIMER_SET_CALLBACK(2, output_tick)