[Add] First commit

This commit is contained in:
gaoyang3513
2023-05-18 18:53:00 +08:00
commit 179cffc2c1
6607 changed files with 2163514 additions and 0 deletions

View File

@ -0,0 +1,375 @@
/*!
\file rc5_decode.c
\brief the rc5 infrared decoding file
\version 2021-10-30, V1.0.0, firmware for GD32W51x
*/
/*
Copyright (c) 2021, GigaDevice Semiconductor Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#include "rc5_decode.h"
#include "ir_decode.h"
/* logic table for rising edge: every line has values corresponding to previous bit.
in columns are actual bit values for given bit time. */
const trc5_last_bit_type rc5_logic_table_rising_edge[2][2] =
{
/* last_bit = ZERO */
{RC5_ZER ,RC5_INV},
/* last_bit = ONE */
{RC5_NAN ,RC5_ZER},
};
/* logic table for falling edge: every line has values corresponding to previous bit.
in columns are actual bit values for given bit time. */
const trc5_last_bit_type rc5_logic_table_falling_edge[2][2] =
{
/* last_bit = ZERO */
{RC5_NAN ,RC5_ONE},
/* last_bit = ONE */
{RC5_ONE ,RC5_INV},
};
/* rc5 frame state */
__IO status_yes_or_no rc5_frame_received = NO;
/* first empty packet */
__IO trc5_packet_struct rc5_tmp_packet;
/* rc5 bits time definitions */
uint16_t rc5_mint = 0;
uint16_t rc5_maxt = 0;
uint16_t rc5_min2t = 0;
uint16_t rc5_max2t = 0;
uint32_t rc5_data = 0;
/* timer clock */
static uint32_t timer_clk_value_khz = 0;
static uint8_t rc5_get_pulse_length (uint16_t pulse_length);
static void rc5_modify_last_bit(trc5_last_bit_type bit);
static void rc5_write_bit(uint8_t bit_val);
static uint32_t timer_get_counter_clk_value(void);
/*!
\brief de-initializes the peripherals
\param[in] none
\param[out] none
\retval none
*/
void rc5_decode_deinit(void)
{
timer_deinit(IR_TIMER);
gpio_deinit(IR_GPIO_PORT);
}
/*!
\brief initialize the rc5 decoder module
\param[in] none
\param[out] none
\retval none
*/
void rc5_decode_init(void)
{
__IO uint16_t rc5_time_out = 0;
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
/* clock configuration for TIMER */
rcu_periph_clock_enable(IR_TIMER_CLK);
/* enable GPIO clock */
rcu_periph_clock_enable(IR_GPIO_PORT_CLK);
/* IR_decode */
/* GD32W515P-EVAL:TIMER3_CH1 PB7 */
{
/*configure PB7 (TIMER3 CH1) as alternate function*/
gpio_mode_set(IR_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, IR_GPIO_PIN);
gpio_output_options_set(IR_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ , IR_GPIO_PIN);
gpio_af_set(IR_GPIO_PORT, GPIO_AF_2, IR_GPIO_PIN);
}
/* enable the TIMER global interrupt */
nvic_irq_enable(IR_TIMER_IRQn, 0, 1);
{
timer_ic_parameter_struct timer_icinitpara;
timer_parameter_struct timer_initpara;
/* deinit IR_TIMER */
/* TIMER3 configuration */
timer_deinit(IR_TIMER);
/* timer base configuration for timer IR_TIMER */
timer_initpara.prescaler = 0x00;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 0x00;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(IR_TIMER,&timer_initpara);
/* prescaler configuration */
timer_prescaler_config(IR_TIMER, 179, TIMER_PSC_RELOAD_NOW);
/* TIMER2 CH0 input capture configuration */
timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING;
timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
timer_icinitpara.icfilter = 0x0;
timer_input_pwm_capture_config(IR_TIMER,IR_TIMER_Channel,&timer_icinitpara);
}
/* timer clock */
timer_clk_value_khz = timer_get_counter_clk_value()/1000;
/* select the TIMER input trigger */
#if defined TIMER_CHANNEL1
timer_input_trigger_source_select(IR_TIMER, TIMER_SMCFG_TRGSEL_CI1FE1);
#else
timer_input_trigger_source_select(IR_TIMER, TIMER_SMCFG_TRGSEL_CI0FE0);
#endif
/* select the slave mode: reset mode */
timer_slave_mode_select(IR_TIMER, TIMER_SLAVE_MODE_RESTART);
/* configures the TIMER update request interrupt source: counter overflow */
timer_update_source_config( IR_TIMER, TIMER_UPDATE_SRC_REGULAR );
rc5_time_out = timer_clk_value_khz * RC5_TIME_OUT_US/1000;
/* set the TIMER auto-reload register for each IR protocol */
TIMER_CAR(IR_TIMER) = rc5_time_out;
/* clear flag */
timer_interrupt_flag_clear(IR_TIMER, TIMER_INT_UP | TIMER_INT_CH0 | TIMER_INT_CH1);
/* enable the CH1 interrupt request */
timer_interrupt_enable(IR_TIMER, TIMER_INT_CH1);
/* enable the CH0 interrupt request */
timer_interrupt_enable(IR_TIMER, TIMER_INT_CH0);
/* enable the timer */
timer_enable(IR_TIMER);
/* bit time range */
rc5_mint = ( RC5_T_US - RC5_T_TOLERANCE_US ) * timer_clk_value_khz / 1000 ;
rc5_maxt = ( RC5_T_US + RC5_T_TOLERANCE_US ) * timer_clk_value_khz / 1000 ;
rc5_min2t = ( 2 * RC5_T_US - RC5_T_TOLERANCE_US ) * timer_clk_value_khz / 1000 ;
rc5_max2t = ( 2 * RC5_T_US + RC5_T_TOLERANCE_US ) * timer_clk_value_khz / 1000 ;
/* default state */
rc5_reset_packet();
}
/*!
\brief decode the IR frame when all the frame is received, the rc5_frame_received will equal to YES
\param[in] rc5_frame: pointer to rc5_frame_struct structure that contains the IR protocol fields
\param[out] none
\retval none
*/
void rc5_decode(rc5_frame_struct *rc5_frame)
{
/* if frame received */
if(rc5_frame_received != NO){
rc5_data = rc5_tmp_packet.data ;
/* rc5 frame field decoding */
rc5_frame->address = (rc5_tmp_packet.data >> 6) & 0x1F;
rc5_frame->command = (rc5_tmp_packet.data) & 0x3F;
rc5_frame->field_bit = (rc5_tmp_packet.data >> 12) & 0x1;
rc5_frame->toggle_bit = (rc5_tmp_packet.data >> 11) & 0x1;
/* check if command ranges between 64 to 127:upper field */
if(rc5_frame->field_bit == 0x00){
rc5_frame->command = (1<<6)| rc5_frame->command;
}
/* default state */
rc5_frame_received = NO;
rc5_reset_packet();
}
}
/*!
\brief set the incoming packet structure to default state
\param[in] none
\param[out] none
\retval none
*/
void rc5_reset_packet(void)
{
rc5_tmp_packet.data = 0;
rc5_tmp_packet.bit_count = RC5_PACKET_BIT_COUNT - 1;
rc5_tmp_packet.last_bit = RC5_ONE;
rc5_tmp_packet.status = RC5_PACKET_STATUS_EMPTY;
}
/*!
\brief identify the rc5 data bits
\param[in] raw_pulse_length: low/high pulse duration
\param[in] edge: '1' for rising or '0' for falling edge
\param[out] none
\retval none
*/
void rc5_data_sampling(uint16_t raw_pulse_length, uint8_t edge)
{
uint8_t pulse;
trc5_last_bit_type tmp_last_bit;
/* decode the pulse length in protocol units */
pulse = rc5_get_pulse_length(raw_pulse_length);
/* on rising edge */
if(1 == edge){
if(pulse <= RC5_2T_TIME){
/* bit determination by the rising edge */
tmp_last_bit = rc5_logic_table_rising_edge[rc5_tmp_packet.last_bit][pulse];
rc5_modify_last_bit(tmp_last_bit);
}else{
rc5_reset_packet();
}
}
/* on falling edge */
else {
/* if this is the first falling edge - don't compute anything */
if(rc5_tmp_packet.status & RC5_PACKET_STATUS_EMPTY){
rc5_tmp_packet.status &= (uint8_t)~RC5_PACKET_STATUS_EMPTY;
}else{
if(pulse <= RC5_2T_TIME){
/* bit determination by the falling edge */
tmp_last_bit = rc5_logic_table_falling_edge[rc5_tmp_packet.last_bit][pulse];
rc5_modify_last_bit(tmp_last_bit);
}else{
rc5_reset_packet();
}
}
}
}
/*!
\brief convert raw pulse length expressed in timer ticks to protocol bit times
\param[in] pulse_length: pulse duration
\param[out] none
\retval bit time value
*/
static uint8_t rc5_get_pulse_length (uint16_t pulse_length)
{
/* valid bit time */
if((pulse_length > rc5_mint) && (pulse_length < rc5_maxt)){
/* found the length,return the correct value */
return (RC5_1T_TIME);
}else if((pulse_length > rc5_min2t) && (pulse_length < rc5_max2t)){
/* found the length,return the correct value */
return (RC5_2T_TIME);
}
/* error */
return RC5_WRONG_TIME;
}
/*!
\brief perform checks if the last bit was not incorrect
\param[in] bit: where bit can be RC5_NAN or RC5_INV or RC5_ZER or RC5_ONE
\param[out] none
\retval none
*/
static void rc5_modify_last_bit(trc5_last_bit_type bit)
{
if(RC5_NAN != bit){
if(RC5_INV != rc5_tmp_packet.last_bit){
/* restore the last bit */
rc5_tmp_packet.last_bit = bit;
/* insert one bit into the rc5 packet */
rc5_write_bit(rc5_tmp_packet.last_bit);
}else{
rc5_reset_packet();
}
}
}
/*!
\brief insert one bit into the final data word
\param[in] bit_val: bit value 'RC5_ONE' or 'RC5_ZER'
\param[out] none
\retval none
*/
static void rc5_write_bit(uint8_t bit_val)
{
/* first convert rc5 symbols to ones and zeros */
if(bit_val == RC5_ONE){
bit_val = 1;
}else if(bit_val == RC5_ZER){
bit_val = 0;
}else{
rc5_reset_packet();
return;
}
/* write this particular bit to data field */
rc5_tmp_packet.data |= bit_val;
/* test the bit number determined */
/* if this is not the last bit */
if(0 != rc5_tmp_packet.bit_count){
/* shift the data field */
rc5_tmp_packet.data = rc5_tmp_packet.data << 1;
/* decrement the bit_count */
rc5_tmp_packet.bit_count--;
}else{
rc5_frame_received = YES;
}
}
/*!
\brief identify TIMER clock
\param[in] none
\param[out] none
\retval timer clock
*/
static uint32_t timer_get_counter_clk_value(void)
{
uint32_t apb_prescaler = 0, apb_frequency = 0;
uint32_t timer_prescaler = 0;
rcu_clock_freq_get(CK_APB1);
/* get the clock prescaler of APB1 */
apb_prescaler = ((RCU_CFG0>> 8) & 0x7);
apb_frequency=rcu_clock_freq_get(CK_APB1);
timer_prescaler = TIMER_PRESCALER;
/* if APBx clock div >= 4 */
if(apb_prescaler >= 4){
return((apb_frequency * 2)/(timer_prescaler + 1));
}else{
return(apb_frequency/(timer_prescaler+ 1));
}
}

View File

@ -0,0 +1,96 @@
/*!
\file rc5_decode.h
\brief the header file of rc5 infrared decoding
\version 2021-10-30, V1.0.0, firmware for GD32W51x
*/
/*
Copyright (c) 2021, GigaDevice Semiconductor Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#ifndef RC5_DECODE_H
#define RC5_DECODE_H
#include "gd32w51x.h"
/* rc5 frame structure */
typedef struct
{
__IO uint8_t field_bit; /*!< field bit */
__IO uint8_t toggle_bit; /*!< toggle bit field */
__IO uint8_t address; /*!< address field */
__IO uint8_t command; /*!< command field */
} rc5_frame_struct;
/* rc5 packet structure */
typedef struct
{
__IO uint16_t data; /*!< rc5 data */
__IO uint8_t status; /*!< rc5 status */
__IO uint8_t last_bit; /*!< rc5 last bit */
__IO uint8_t bit_count; /*!< rc5 bit count */
} trc5_packet_struct;
/* rc5 last bit type enum */
enum rc5_last_bit_type
{
RC5_ZER,
RC5_ONE,
RC5_NAN,
RC5_INV
};
typedef enum rc5_last_bit_type trc5_last_bit_type;
#define RC5_1T_TIME 0x00
#define RC5_2T_TIME 0x01
#define RC5_WRONG_TIME 0xFF
#define RC5_TIME_OUT_US 3600
/* half bit period */
#define RC5_T_US 900
/* tolerance time */
#define RC5_T_TOLERANCE_US 270
#define RC5_NUMBER_OF_VALID_PULSE_LENGTH 2
/* total bits */
#define RC5_PACKET_BIT_COUNT 13
/* packet struct for reception */
#define RC5_PACKET_STATUS_EMPTY (uint16_t)(1<<0)
void menu_rc5decode_func(void);
void rc5_decode_deinit(void);
void rc5_decode_init(void);
void rc5_decode(rc5_frame_struct *rc5_frame);
void rc5_reset_packet(void);
void rc5_data_sampling(uint16_t raw_pulse_length, uint8_t edge);
#endif /* RC5_DECODE_H */

View File

@ -0,0 +1,289 @@
/*!
\file rc5_encode.c
\brief the rc5 infrared encoder file
\version 2021-10-30, V1.0.0, firmware for GD32W51x
*/
/*
Copyright (c) 2021, GigaDevice Semiconductor Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#include "rc5_encode.h"
#include "ir_decode.h"
/* rc5 high level definition*/
#define RC5_HIGH_STATE ((uint8_t)0x02)
/* rc5 low level definition*/
#define RC5_LOW_STATE ((uint8_t)0x01)
rc5_ctrl_enum rc5_ctrl1 = RC5_CTRL_RESET;
uint8_t rc5_real_frame_length = 14;
uint8_t rc5_global_frame_length = 64;
uint16_t rc5_frame_binary_format = 0;
uint32_t rc5_frame_manchester_format = 0;
uint8_t send_operation_ready = 0;
__IO uint8_t send_operation_completed = 1;
uint8_t bits_sent_counter = 0;
uint8_t address_index = 0;
uint8_t instruction_index = 0;
static uint16_t rc5_bin_frame_generation(uint8_t rc5_address, uint8_t rc5_instruction, rc5_ctrl_enum rc5_ctrl);
static uint32_t rc5_manchester_convert(uint16_t rc5_binary_frame_format);
/*!
\brief init hardware (ips used) for rc5 generation
\param[in] none
\param[out] none
\retval none
*/
void rc5_encode_init( void )
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
/* TIMER15 clock enable */
rcu_periph_clock_enable(RCU_TIMER15);
/* TIMER16 clock enable */
rcu_periph_clock_enable(RCU_TIMER16);
{
/* IR_encode */
/* PB5 IR_OUT pin configuration: output */
gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_5);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_5);
}
{
{
/* deinit TIMER16 */
timer_deinit(TIMER16);
/* time base = 36Khz */
/* time base configuration for TIMER16 */
timer_initpara.prescaler = 0x01;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 2499;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER16,&timer_initpara);
/* prescaler configuration */
timer_prescaler_config(TIMER16,0x01,TIMER_PSC_RELOAD_NOW);
/* output compare timing mode configuration: channel 0N */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_LOW;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER16,TIMER_CH_0,&timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER16,TIMER_CH_0,(2500/4-1));
timer_channel_output_mode_config(TIMER16,TIMER_CH_0,TIMER_OC_MODE_PWM1);
timer_channel_output_shadow_config(TIMER16,TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);
/* TIMER16 enable */
timer_enable(TIMER16);
/* enable the TIMER16 channel1 output to be connected internly to the IRTIMER */
timer_primary_output_config(TIMER16,ENABLE);
}
{
/* deinit TIMER15 */
timer_deinit(TIMER15);
/* elementary period 889 us */
/* time base configuration for TIMER15 */
timer_initpara.prescaler = 4;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 64008 /2 - 1;
timer_initpara.clockdivision = 0;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER15,&timer_initpara);
/* duty cycle = 25% */
/* channel 1 configuration in timing mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER15,TIMER_CH_0,&timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER15,TIMER_CH_0,(64008 /2 /4));
timer_channel_output_mode_config(TIMER15,TIMER_CH_0,TIMER_OC_MODE_TIMING);
/* enable the TIMER15 interrupt */
// nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
nvic_irq_enable(TIMER15_IRQn, 0, 0);
/* TIMER15 main output enable */
timer_primary_output_config(TIMER15,ENABLE);
/* TIMER15 INT disable */
timer_interrupt_disable(TIMER15,TIMER_INT_UP);
/* TIMER15 disable */
timer_disable(TIMER15);
}
}
}
/*!
\brief generate and send the rc5 frame
\param[in] rc5_address: the rc5 device destination
\param[in] rc5_instruction: the rc5 command instruction
\param[in] rc5_ctrl: the rc5 control bit
\param[out] none
\retval none
*/
void rc5_encode_send_frame(uint8_t rc5_address, uint8_t rc5_instruction, rc5_ctrl_enum rc5_ctrl)
{
uint16_t rc5_frame_binary_format = 0;
/* generate a binary format of the frame */
rc5_frame_binary_format = rc5_bin_frame_generation(rc5_address, rc5_instruction, rc5_ctrl);
/* generate a manchester format of the frame */
rc5_frame_manchester_format = rc5_manchester_convert(rc5_frame_binary_format);
/* set the send operation ready flag to indicate that the frame is ready to be sent */
send_operation_ready = 1;
/* TIMER15 INT enable */
timer_interrupt_enable(TIMER15,TIMER_INT_UP);
/* enable TIMER15 */
timer_enable(TIMER15);
}
/*!
\brief send by hardware manchester format rc5 frame
\param[in] rc5_manchester_frame_format: the rc5 frame in manchester format
\param[out] none
\retval none
*/
void rc5_encode_signal_generate( uint32_t rc5_manchester_frame_format )
{
uint8_t bit_msg = 0;
if((1 == send_operation_ready ) && ((rc5_global_frame_length * 2) >= bits_sent_counter)){
send_operation_completed = 0x00;
bit_msg = (uint8_t)((rc5_manchester_frame_format >> bits_sent_counter) & 1);
if(1 == bit_msg){
timer_channel_output_mode_config(TIMER15, TIMER_CH_0, TIMER_OC_MODE_HIGH);
}else{
timer_channel_output_mode_config(TIMER15, TIMER_CH_0, TIMER_OC_MODE_LOW);
}
bits_sent_counter++;
}else{
send_operation_completed = 0x01;
/* TIMER15 INT disable */
timer_interrupt_disable(TIMER15, TIMER_INT_UP);
timer_disable(TIMER15);
send_operation_ready = 0;
bits_sent_counter = 0;
timer_channel_output_mode_config(TIMER15, TIMER_CH_0, TIMER_OC_MODE_LOW);
}
}
/*!
\brief generate the binary format of the rc5 frame
\param[in] rc5_address: select the device adress
\param[in] rc5_instruction: select the device instruction
\param[in] rc5_ctrl: select the device control bit status
\param[out] none
\retval binary format of the rc5 frame
*/
static uint16_t rc5_bin_frame_generation(uint8_t rc5_address, uint8_t rc5_instruction, rc5_ctrl_enum rc5_ctrl)
{
uint16_t star1 = 0x2000;
uint16_t star2 = 0x1000;
uint16_t addr = 0;
while(0x00 == send_operation_completed);
/* check if instruction is 128-bit length */
if(64 <= rc5_instruction){
/* reset field bit: command is 7-bit length */
star2 = 0;
/* keep the lowest 6 bits of the command */
rc5_instruction &= 0x003F;
}
/* instruction is 64-bit length */
else{
/* set field bit: command is 6-bit length */
star2 = 0x1000;
}
send_operation_ready = 0;
rc5_frame_manchester_format = 0;
rc5_frame_binary_format = 0;
addr = ((uint16_t)(rc5_address))<<6;
rc5_frame_binary_format = (star1) | (star2) | (rc5_ctrl) | (addr) | (rc5_instruction);
return(rc5_frame_binary_format);
}
/*!
\brief convert the rc5 frame from binary to manchester format
\param[in] rc5_binary_frame_format: the rc5 frame in binary format
\param[out] none
\retval the rc5 frame in manchester format
*/
static uint32_t rc5_manchester_convert(uint16_t rc5_binary_frame_format)
{
uint8_t i=0;
uint16_t mask = 1;
uint16_t bit_format = 0;
uint32_t converted_msg =0;
for(i = 0; i < rc5_real_frame_length; i++){
bit_format = ((((uint16_t)(rc5_binary_frame_format))>>i)& mask)<<i;
converted_msg = converted_msg << 2;
if(0 != bit_format){
/* manchester 1 -|_ */
converted_msg |= RC5_HIGH_STATE;
}else{
/* manchester 0 _|- */
converted_msg |= RC5_LOW_STATE;
}
}
return(converted_msg);
}

View File

@ -0,0 +1,55 @@
/*!
\file rc5_encode.h
\brief the header file of rc5 infrared encoder
\version 2021-10-30, V1.0.0, firmware for GD32W51x
*/
/*
Copyright (c) 2021, GigaDevice Semiconductor Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/
#ifndef RC5_ENCODE_H
#define RC5_ENCODE_H
#include "gd32w51x.h"
/* definition of the rc5 control bit value */
typedef enum
{
RC5_CTRL_RESET = ((uint16_t)0),
RC5_CTRL_SET = ((uint16_t)0x0800)
}rc5_ctrl_enum;
void menu_rc5_encode_func(void);
void rc5_encode_init(void);
void rc5_encode_send_frame(uint8_t rc5_address, uint8_t rc5_instruction, rc5_ctrl_enum rc5_ctrl);
void rc5_encode_signal_generate(uint32_t rc5_manchester_frame_format);
#endif /*RC5_ENCODE_H */