Initial public release.
This commit is contained in:
parent
7b169e8116
commit
dac4af8d25
255 changed files with 68595 additions and 2 deletions
223
2020TPCApp1.cydsn/Fire_Control.c
Normal file
223
2020TPCApp1.cydsn/Fire_Control.c
Normal file
|
@ -0,0 +1,223 @@
|
|||
/* Include Files */
|
||||
#include "KTag.h"
|
||||
|
||||
#define FIRE_CONTROL_REGISTER__IR_OFF 0b00000
|
||||
#define FIRE_CONTROL_REGISTER__IR_ON_MODULATED_LOW_POWER 0b00011
|
||||
#define FIRE_CONTROL_REGISTER__IR_ON_MODULATED_HIGH_POWER 0b00101
|
||||
#define FIRE_CONTROL_REGISTER__IR_ON_MODULATED_MAX_POWER 0b11111
|
||||
#define FIRE_CONTROL_REGISTER__IR_ON_UNMODULATED_LOW_POWER 0b00010
|
||||
#define FIRE_CONTROL_REGISTER__IR_ON_UNMODULATED_HIGH_POWER 0b00100
|
||||
#define FIRE_CONTROL_REGISTER__IR_ON_UNMODULATED_MAX_POWER 0b00110
|
||||
|
||||
#define TRIGGER_STATUS_REGISTER__NO_ACTION 0x00
|
||||
#define TRIGGER_STATUS_REGISTER__TRIGGER_PULLED 0x01
|
||||
#define TRIGGER_STATUS_REGISTER__TRIGGER_RELEASED 0x02
|
||||
|
||||
|
||||
void Trigger_Interrupt_ISR();
|
||||
void Bit_Stream_Timer_ISR();
|
||||
|
||||
TimedPulseTrain_T * Shot_Buffer;
|
||||
TagPacket_T Shot_Packet;
|
||||
|
||||
TaskHandle_t Fire_Control_Task_Handle;
|
||||
|
||||
static TimedPulseTrain_T * Active_Pulse_Train = NULL;
|
||||
static uint8_t Active_Bitstream_Index = 0;
|
||||
|
||||
static TickType_t TicksAtTriggerPress;
|
||||
|
||||
static inline void Initiate_Pulse_Train(TimedPulseTrain_T * pulsetrain)
|
||||
{
|
||||
Bit_Stream_Timer_Disable();
|
||||
Active_Pulse_Train = pulsetrain;
|
||||
Active_Bitstream_Index = 0;
|
||||
|
||||
if (Active_Pulse_Train->bitstream[Active_Bitstream_Index].symbol == MARK)
|
||||
{
|
||||
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_ON_MODULATED_MAX_POWER);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
|
||||
}
|
||||
Bit_Stream_Timer_SetPeriod(Active_Pulse_Train->bitstream[0].duration);
|
||||
Bit_Stream_Timer_SetCounter(0);
|
||||
Active_Bitstream_Index++;
|
||||
Bit_Stream_Timer_Enable();
|
||||
Bit_Stream_Timer_TriggerStart();
|
||||
}
|
||||
|
||||
static inline void Next_Bit(void)
|
||||
{
|
||||
static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
Bit_Stream_Timer_Disable();
|
||||
|
||||
if (Active_Pulse_Train->bitstream[Active_Bitstream_Index].duration != LAST_PULSE)
|
||||
{
|
||||
if (Active_Pulse_Train->bitstream[Active_Bitstream_Index].symbol == MARK)
|
||||
{
|
||||
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_ON_MODULATED_MAX_POWER);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
|
||||
}
|
||||
|
||||
if (Active_Bitstream_Index < ((2*MAX_PULSES) - 2))
|
||||
{
|
||||
Bit_Stream_Timer_SetPeriod(Active_Pulse_Train->bitstream[Active_Bitstream_Index].duration);
|
||||
Bit_Stream_Timer_SetCounter(0);
|
||||
Active_Bitstream_Index++;
|
||||
Bit_Stream_Timer_Enable();
|
||||
Bit_Stream_Timer_TriggerStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The bitstream is too long!
|
||||
|
||||
// Turn the IR Emitter off, and wait a long time.
|
||||
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
|
||||
xSemaphoreGiveFromISR(NeoPixels_Semaphore, &xHigherPriorityTaskWoken);
|
||||
Bit_Stream_Timer_SetPeriod(UINT16_MAX);
|
||||
Bit_Stream_Timer_SetCounter(0);
|
||||
Active_Pulse_Train = NULL;
|
||||
Bit_Stream_Timer_Enable();
|
||||
Bit_Stream_Timer_TriggerStart();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Turn the IR Emitter off, and wait a long time.
|
||||
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
|
||||
xSemaphoreGiveFromISR(NeoPixels_Semaphore, &xHigherPriorityTaskWoken);
|
||||
Bit_Stream_Timer_SetPeriod(UINT16_MAX);
|
||||
Bit_Stream_Timer_SetCounter(0);
|
||||
Active_Pulse_Train = NULL;
|
||||
Bit_Stream_Timer_Enable();
|
||||
Bit_Stream_Timer_TriggerStart();
|
||||
}
|
||||
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
void Init_Fire_Control(void)
|
||||
{
|
||||
// Register and enable the ISRs.
|
||||
Cy_SysInt_Init(&Trigger_Interrupt_cfg, Trigger_Interrupt_ISR);
|
||||
Cy_SysInt_Init(&Bit_Stream_Timer_Interrupt_cfg, Bit_Stream_Timer_ISR);
|
||||
NVIC_EnableIRQ(Trigger_Interrupt_cfg.intrSrc);
|
||||
NVIC_EnableIRQ(Bit_Stream_Timer_Interrupt_cfg.intrSrc);
|
||||
|
||||
// Initialize the hardware.
|
||||
Bit_Stream_Timer_Clock_Enable();
|
||||
Bit_Stream_Timer_Init(&Bit_Stream_Timer_config);
|
||||
Bit_Stream_Timer_SetPeriod(2);
|
||||
Bit_Stream_Timer_Start();
|
||||
SW_CLK_Enable();
|
||||
PWM_IR_Modulation_Start();
|
||||
|
||||
|
||||
Fire_Control_Register_Write(FIRE_CONTROL_REGISTER__IR_OFF);
|
||||
}
|
||||
|
||||
void Fire_Control_Task(void * pvParameters)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
SystemKResult_T Prepare_Tag()
|
||||
{
|
||||
Shot_Packet.player_ID = NVM_PLAYER_ID;
|
||||
Shot_Packet.team_ID = NVM_TEAM_ID;
|
||||
Weapon_t weapon = GetWeaponFromID(NVM_WEAPON_ID);
|
||||
Shot_Packet.color = (uint32_t)PROTOCOLS_GetColor(weapon.Protocol, Shot_Packet.team_ID, Shot_Packet.player_ID);
|
||||
Shot_Packet.protocol = weapon.Protocol;
|
||||
Shot_Packet.damage = weapon.Damage_Per_Shot;
|
||||
Shot_Buffer = PROTOCOLS_EncodePacket(&Shot_Packet);
|
||||
Fire_Control_Set_Modulation_Frequency(PROTOCOLS_GetModulationFrequency(weapon.Protocol));
|
||||
return SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
SystemKResult_T Send_Tag()
|
||||
{
|
||||
xSemaphoreTake(NeoPixels_Semaphore, portMAX_DELAY);
|
||||
Initiate_Pulse_Train(Shot_Buffer);
|
||||
|
||||
KEvent_T tag_sent_event = { .ID = KEVENT_TAG_SENT, .Data = (void *)0x00 };
|
||||
Post_KEvent(&tag_sent_event);
|
||||
|
||||
return SYSTEMK_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void Fire_Control_Set_Modulation_Frequency(ModulationFrequency_T freq)
|
||||
{
|
||||
PWM_IR_Modulation_TriggerKill();
|
||||
if (freq == FREQUENCY_38kHz)
|
||||
{
|
||||
PWM_IR_Modulation_SetPeriod0(314);
|
||||
//PWM_IR_Modulation_SetCompare0(314/2); // 50% Duty Cycle
|
||||
PWM_IR_Modulation_SetCompare0((314 * 3)/10); // 30% Duty Cycle
|
||||
}
|
||||
else // (freq == FREQUENCY_56kHz)
|
||||
{
|
||||
PWM_IR_Modulation_SetPeriod0(213);
|
||||
//PWM_IR_Modulation_SetCompare0(213/2); // 50% Duty Cycle
|
||||
PWM_IR_Modulation_SetCompare0((213 * 3)/10); // 30% Duty Cycle
|
||||
}
|
||||
PWM_IR_Modulation_TriggerStart();
|
||||
}
|
||||
|
||||
//! ISR for the trigger input.
|
||||
void Trigger_Interrupt_ISR()
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
// Clear the interrupt.
|
||||
NVIC_ClearPendingIRQ(Trigger_Interrupt_cfg.intrSrc);
|
||||
|
||||
// Read the trigger register to know if this was a pull or a release.
|
||||
uint8_t trigger_status = Trigger_Status_Reg_Read();
|
||||
|
||||
if ((trigger_status & TRIGGER_STATUS_REGISTER__TRIGGER_PULLED) == TRIGGER_STATUS_REGISTER__TRIGGER_PULLED)
|
||||
{
|
||||
TicksAtTriggerPress = xTaskGetTickCountFromISR();
|
||||
KEvent_T switch_event = {.ID = KEVENT_CENTER_SWITCH_PRESSED, .Data = NULL};
|
||||
Post_KEvent_From_ISR(&switch_event, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
else if ((trigger_status & TRIGGER_STATUS_REGISTER__TRIGGER_RELEASED) == TRIGGER_STATUS_REGISTER__TRIGGER_RELEASED)
|
||||
{
|
||||
uint32_t triggerPressDurationInms = pdTICKS_TO_MS(xTaskGetTickCountFromISR() - TicksAtTriggerPress);
|
||||
KEvent_T switch_event = {.ID = KEVENT_CENTER_SWITCH_RELEASED, .Data = (void *) triggerPressDurationInms};
|
||||
Post_KEvent_From_ISR(&switch_event, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
else
|
||||
{
|
||||
// What happened!!?
|
||||
}
|
||||
|
||||
// If an event was enqueued above, a context switch might be required.
|
||||
// xHigherPriorityTaskWoken was initialized to pdFALSE on interrupt entry. If calling
|
||||
// xSemaphoreGiveFromISR() caused a task to unblock, and the unblocked task has a
|
||||
// priority equal to or higher than the currently running task (the task that was
|
||||
// interrupted by this ISR), then xHigherPriorityTaskWoken will have been set to pdTRUE
|
||||
// and portEND_SWITCHING_ISR() will request a context switch to the newly unblocked task.
|
||||
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
void Bit_Stream_Timer_ISR()
|
||||
{
|
||||
// Get all the enabled pending interrupts...
|
||||
uint32_t source = Bit_Stream_Timer_GetInterruptStatusMasked();
|
||||
// ...and clear them.
|
||||
Bit_Stream_Timer_ClearInterrupt(source);
|
||||
|
||||
if (Active_Pulse_Train != NULL)
|
||||
{
|
||||
Next_Bit();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue