diff --git a/include/gpio.h b/include/gpio.h index 9031bf666bc01fd74840f84397d4e0da3a6d13ce..8fea176627702e56e994c46522bdd37bbf40c203 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -8,8 +8,13 @@ typedef enum {NORTH_LED,SOUTH_LED,EAST_LED,WEST_LED} led_t; typedef enum {NORTH_PB,SOUTH_PB,EAST_PB,WEST_PB} pushbutton_t; void gpio_init(void); +// LED functions void gpio_set_led(led_t led_id); void gpio_clear_led(led_t led_id); +void gpio_toggle_led(led_t led_id); void gpio_blink_led(led_t led_id, int16_t period_ms); +// Pushbuttons functions +uint8_t gpio_is_pushbutton_pressed(pushbutton_t pb_id); +void gpio_set_pushbutton_callback(pushbutton_t pb_id,void (*callback)(void)); #endif diff --git a/src/bioloid_stm32.c b/src/bioloid_stm32.c index 3fb2476a3f87cb8443e8f3aab408892d899cded8..c9917ba99788c9e79e18a3e9c6ecc1a34015465d 100644 --- a/src/bioloid_stm32.c +++ b/src/bioloid_stm32.c @@ -30,6 +30,11 @@ uint8_t read_operation(uint8_t address, uint8_t length, uint8_t *data) } } +void test_led(void) +{ + gpio_toggle_led(NORTH_LED); +} + int32_t main(void) { uint8_t inst_packet[1024]; @@ -70,10 +75,9 @@ int32_t main(void) else GPIO_ResetBits(GPIOD,GPIO_Pin_12); - gpio_blink_led(NORTH_LED,1000); - gpio_blink_led(SOUTH_LED,2000); - gpio_blink_led(EAST_LED,3000); - gpio_blink_led(WEST_LED,4000); + gpio_set_pushbutton_callback(NORTH_PB,test_led); + gpio_blink_led(EAST_LED,2000); + gpio_blink_led(WEST_LED,1000); while(1) /* main function does not return */ { if(dyn_slave_is_packet_ready())// check if a new instruction packet has been received diff --git a/src/gpio.c b/src/gpio.c index 9aa05b7b7666b0f60cf9ea3d8eca65962a025ee9..625c0a23dd646d4d4f8219923df81c6f5a127752 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -40,49 +40,95 @@ #define PUSH_BUTTON4_GPIO_PORT GPIOC #define PUSH_BUTTON4_SOURCE GPIO_PinSource15 -#define GPIO_TIMER TIM2 -#define GPIO_TIMER_CLK RCC_APB1Periph_TIM2 -#define GPIO_TIMER_IRQn TIM2_IRQn -#define GPIO_TIMER_IRQHandler TIM2_IRQHandler +#define GPO_TIMER TIM2 +#define GPO_TIMER_CLK RCC_APB1Periph_TIM2 +#define GPO_TIMER_IRQn TIM2_IRQn +#define GPO_TIMER_IRQHandler TIM2_IRQHandler + +#define GPI_TIMER TIM3 +#define GPI_TIMER_CLK RCC_APB1Periph_TIM3 +#define GPI_TIMER_IRQn TIM3_IRQn +#define GPI_TIMER_IRQHandler TIM3_IRQHandler // private variables +// LED blink periods __IO uint16_t north_led_period; __IO uint16_t south_led_period; __IO uint16_t east_led_period; __IO uint16_t west_led_period; +// Pushbuttons callbacks +void (*north_pb_callback)(void); +void (*south_pb_callback)(void); +void (*east_pb_callback)(void); +void (*west_pb_callback)(void); // IRQ hanfler functions -void TIM2_IRQHandler(void) +void GPI_TIMER_IRQHandler(void) { uint16_t capture; + static uint8_t north_pb_last=Bit_SET,south_pb_last=Bit_SET,east_pb_last=Bit_SET,west_pb_last=Bit_SET; + uint8_t north_pb_new,south_pb_new,east_pb_new,west_pb_new; - if(TIM_GetITStatus(GPIO_TIMER, TIM_IT_CC1)!=RESET) + if(TIM_GetITStatus(GPI_TIMER, TIM_IT_CC1)!=RESET) { - TIM_ClearITPendingBit(GPIO_TIMER,TIM_IT_CC1); + TIM_ClearITPendingBit(GPI_TIMER,TIM_IT_CC1); + capture = TIM_GetCapture1(GPI_TIMER); + TIM_SetCompare1(GPI_TIMER, capture + 10); + /* check all the pushbuttons */ + north_pb_new=GPIO_ReadInputDataBit(PUSH_BUTTON1_GPIO_PORT,PUSH_BUTTON1_PIN); + if(north_pb_last==Bit_SET && north_pb_new==Bit_RESET) + if(north_pb_callback!=0) + north_pb_callback(); + north_pb_last=north_pb_new; + south_pb_new=GPIO_ReadInputDataBit(PUSH_BUTTON2_GPIO_PORT,PUSH_BUTTON2_PIN); + if(south_pb_last==Bit_SET && south_pb_new==Bit_RESET) + if(south_pb_callback!=0) + south_pb_callback(); + south_pb_last=south_pb_new; + east_pb_new=GPIO_ReadInputDataBit(PUSH_BUTTON3_GPIO_PORT,PUSH_BUTTON3_PIN); + if(east_pb_last==Bit_SET && east_pb_new==Bit_RESET) + if(east_pb_callback!=0) + east_pb_callback(); + east_pb_last=east_pb_new; + west_pb_new=GPIO_ReadInputDataBit(PUSH_BUTTON4_GPIO_PORT,PUSH_BUTTON4_PIN); + if(west_pb_last==Bit_SET && west_pb_new==Bit_RESET) + if(west_pb_callback!=0) + west_pb_callback(); + west_pb_last=west_pb_new; + } +} + +void GPO_TIMER_IRQHandler(void) +{ + uint16_t capture; + + if(TIM_GetITStatus(GPO_TIMER, TIM_IT_CC1)!=RESET) + { + TIM_ClearITPendingBit(GPO_TIMER,TIM_IT_CC1); GPIO_ToggleBits(LED1_GPIO_PORT,LED1_PIN); - capture = TIM_GetCapture1(GPIO_TIMER); - TIM_SetCompare1(GPIO_TIMER, capture + north_led_period); + capture = TIM_GetCapture1(GPO_TIMER); + TIM_SetCompare1(GPO_TIMER, capture + north_led_period); } - if(TIM_GetITStatus(GPIO_TIMER, TIM_IT_CC2)!=RESET) + if(TIM_GetITStatus(GPO_TIMER, TIM_IT_CC2)!=RESET) { - TIM_ClearITPendingBit(GPIO_TIMER,TIM_IT_CC2); + TIM_ClearITPendingBit(GPO_TIMER,TIM_IT_CC2); GPIO_ToggleBits(LED2_GPIO_PORT,LED2_PIN); - capture = TIM_GetCapture2(GPIO_TIMER); - TIM_SetCompare2(GPIO_TIMER, capture + south_led_period); + capture = TIM_GetCapture2(GPO_TIMER); + TIM_SetCompare2(GPO_TIMER, capture + south_led_period); } - if(TIM_GetITStatus(GPIO_TIMER, TIM_IT_CC3)!=RESET) + if(TIM_GetITStatus(GPO_TIMER, TIM_IT_CC3)!=RESET) { - TIM_ClearITPendingBit(GPIO_TIMER,TIM_IT_CC3); + TIM_ClearITPendingBit(GPO_TIMER,TIM_IT_CC3); GPIO_ToggleBits(LED3_GPIO_PORT,LED3_PIN); - capture = TIM_GetCapture3(GPIO_TIMER); - TIM_SetCompare3(GPIO_TIMER, capture + east_led_period); + capture = TIM_GetCapture3(GPO_TIMER); + TIM_SetCompare3(GPO_TIMER, capture + east_led_period); } - if(TIM_GetITStatus(GPIO_TIMER, TIM_IT_CC4)!=RESET) + if(TIM_GetITStatus(GPO_TIMER, TIM_IT_CC4)!=RESET) { - TIM_ClearITPendingBit(GPIO_TIMER,TIM_IT_CC4); + TIM_ClearITPendingBit(GPO_TIMER,TIM_IT_CC4); GPIO_ToggleBits(LED4_GPIO_PORT,LED4_PIN); - capture = TIM_GetCapture4(GPIO_TIMER); - TIM_SetCompare4(GPIO_TIMER, capture + west_led_period); + capture = TIM_GetCapture4(GPO_TIMER); + TIM_SetCompare4(GPO_TIMER, capture + west_led_period); } } @@ -94,11 +140,12 @@ void gpio_init(void) GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; + TIM_OCInitTypeDef TIM_OCInitStructure; /* enable clocks */ RCC_AHB1PeriphClockCmd(LED1_GPIO_CLK | LED2_GPIO_CLK | LED3_GPIO_CLK | LED4_GPIO_CLK, ENABLE); RCC_AHB1PeriphClockCmd(PUSH_BUTTON1_GPIO_CLK | PUSH_BUTTON2_GPIO_CLK | PUSH_BUTTON3_GPIO_CLK | PUSH_BUTTON4_GPIO_CLK, ENABLE); - RCC_APB1PeriphClockCmd(GPIO_TIMER_CLK,ENABLE); + RCC_APB1PeriphClockCmd(GPO_TIMER_CLK | GPI_TIMER_CLK,ENABLE); /* GPIO Configuration */ GPIO_InitStructure.GPIO_Pin = LED1_PIN; @@ -133,23 +180,49 @@ void gpio_init(void) GPIO_InitStructure.GPIO_Pin = PUSH_BUTTON4_PIN; GPIO_Init(PUSH_BUTTON4_GPIO_PORT, &GPIO_InitStructure); + // initialize private variables + north_led_period=0; + south_led_period=0; + east_led_period=0; + west_led_period=0; + north_pb_callback=0; + south_pb_callback=0; + east_pb_callback=0; + west_pb_callback=0; + // initialize the timer interrupts - NVIC_InitStructure.NVIC_IRQChannel = GPIO_TIMER_IRQn; + NVIC_InitStructure.NVIC_IRQChannel = GPO_TIMER_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + NVIC_InitStructure.NVIC_IRQChannel = GPI_TIMER_IRQn; NVIC_Init(&NVIC_InitStructure); - /* Time base configuration */ + /* LED's timer configuration */ + TIM_TimeBaseStructure.TIM_Period = 0xFFFF; + TIM_TimeBaseStructure.TIM_Prescaler = 0; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(GPO_TIMER,&TIM_TimeBaseStructure); + TIM_Cmd(GPO_TIMER, ENABLE); + TIM_PrescalerConfig(GPO_TIMER, 42000, TIM_PSCReloadMode_Immediate); + TIM_SetClockDivision(GPO_TIMER,TIM_CKD_DIV2); + + /* pushbutton timer configuration */ TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(GPIO_TIMER,&TIM_TimeBaseStructure); - TIM_Cmd(GPIO_TIMER, ENABLE); - TIM_PrescalerConfig(GPIO_TIMER, 42000, TIM_PSCReloadMode_Immediate); - TIM_SetClockDivision(GPIO_TIMER,TIM_CKD_DIV2); + TIM_TimeBaseInit(GPI_TIMER,&TIM_TimeBaseStructure); + TIM_Cmd(GPI_TIMER, ENABLE); + TIM_PrescalerConfig(GPI_TIMER, 42000, TIM_PSCReloadMode_Immediate); + TIM_SetClockDivision(GPI_TIMER,TIM_CKD_DIV2); + TIM_OCInitStructure.TIM_Pulse = 10;// 10 Hz + TIM_OC1Init(GPI_TIMER, &TIM_OCInitStructure); + TIM_OC1PreloadConfig(GPI_TIMER, TIM_OCPreload_Disable); + TIM_ITConfig(GPI_TIMER, TIM_IT_CC1, ENABLE); } void gpio_set_led(led_t led_id) @@ -190,6 +263,25 @@ void gpio_clear_led(led_t led_id) } } +void gpio_toggle_led(led_t led_id) +{ + switch(led_id) + { + case NORTH_LED: + GPIO_ToggleBits(LED1_GPIO_PORT,LED1_PIN); + break; + case SOUTH_LED: + GPIO_ToggleBits(LED2_GPIO_PORT,LED2_PIN); + break; + case EAST_LED: + GPIO_ToggleBits(LED3_GPIO_PORT,LED3_PIN); + break; + case WEST_LED: + GPIO_ToggleBits(LED4_GPIO_PORT,LED4_PIN); + break; + } +} + void gpio_blink_led(led_t led_id, int16_t period_ms) { TIM_OCInitTypeDef TIM_OCInitStructure; @@ -204,48 +296,98 @@ void gpio_blink_led(led_t led_id, int16_t period_ms) { north_led_period=period_ms; TIM_OCInitStructure.TIM_Pulse = north_led_period; - TIM_OC1Init(GPIO_TIMER, &TIM_OCInitStructure); - TIM_OC1PreloadConfig(GPIO_TIMER, TIM_OCPreload_Disable); - TIM_ITConfig(GPIO_TIMER, TIM_IT_CC1, ENABLE); + TIM_OC1Init(GPO_TIMER, &TIM_OCInitStructure); + TIM_OC1PreloadConfig(GPO_TIMER, TIM_OCPreload_Disable); + TIM_ITConfig(GPO_TIMER, TIM_IT_CC1, ENABLE); } else - TIM_ITConfig(GPIO_TIMER, TIM_IT_CC1, DISABLE); + TIM_ITConfig(GPO_TIMER, TIM_IT_CC1, DISABLE); break; case SOUTH_LED: if(period_ms>1) { south_led_period=period_ms; TIM_OCInitStructure.TIM_Pulse = south_led_period; - TIM_OC2Init(GPIO_TIMER, &TIM_OCInitStructure); - TIM_OC2PreloadConfig(GPIO_TIMER, TIM_OCPreload_Disable); - TIM_ITConfig(GPIO_TIMER, TIM_IT_CC2, ENABLE); + TIM_OC2Init(GPO_TIMER, &TIM_OCInitStructure); + TIM_OC2PreloadConfig(GPO_TIMER, TIM_OCPreload_Disable); + TIM_ITConfig(GPO_TIMER, TIM_IT_CC2, ENABLE); } else - TIM_ITConfig(GPIO_TIMER, TIM_IT_CC2, DISABLE); + TIM_ITConfig(GPO_TIMER, TIM_IT_CC2, DISABLE); break; case EAST_LED: if(period_ms>1) { east_led_period=period_ms; TIM_OCInitStructure.TIM_Pulse = east_led_period; - TIM_OC3Init(GPIO_TIMER, &TIM_OCInitStructure); - TIM_OC3PreloadConfig(GPIO_TIMER, TIM_OCPreload_Disable); - TIM_ITConfig(GPIO_TIMER, TIM_IT_CC3, ENABLE); + TIM_OC3Init(GPO_TIMER, &TIM_OCInitStructure); + TIM_OC3PreloadConfig(GPO_TIMER, TIM_OCPreload_Disable); + TIM_ITConfig(GPO_TIMER, TIM_IT_CC3, ENABLE); } else - TIM_ITConfig(GPIO_TIMER, TIM_IT_CC3, DISABLE); + TIM_ITConfig(GPO_TIMER, TIM_IT_CC3, DISABLE); break; case WEST_LED: if(period_ms>1) { west_led_period=period_ms; TIM_OCInitStructure.TIM_Pulse = west_led_period; - TIM_OC4Init(GPIO_TIMER, &TIM_OCInitStructure); - TIM_OC4PreloadConfig(GPIO_TIMER, TIM_OCPreload_Disable); - TIM_ITConfig(GPIO_TIMER, TIM_IT_CC4, ENABLE); + TIM_OC4Init(GPO_TIMER, &TIM_OCInitStructure); + TIM_OC4PreloadConfig(GPO_TIMER, TIM_OCPreload_Disable); + TIM_ITConfig(GPO_TIMER, TIM_IT_CC4, ENABLE); } else - TIM_ITConfig(GPIO_TIMER, TIM_IT_CC4, DISABLE); + TIM_ITConfig(GPO_TIMER, TIM_IT_CC4, DISABLE); + break; + } +} + +uint8_t gpio_is_pushbutton_pressed(pushbutton_t pb_id) +{ + switch(pb_id) + { + case NORTH_PB: + if(GPIO_ReadInputDataBit(PUSH_BUTTON1_GPIO_PORT,PUSH_BUTTON1_PIN)==Bit_SET) + return 0x01; + else + return 0x00; + break; + case SOUTH_PB: + if(GPIO_ReadInputDataBit(PUSH_BUTTON2_GPIO_PORT,PUSH_BUTTON2_PIN)==Bit_SET) + return 0x01; + else + return 0x00; + break; + case EAST_PB: + if(GPIO_ReadInputDataBit(PUSH_BUTTON3_GPIO_PORT,PUSH_BUTTON3_PIN)==Bit_SET) + return 0x01; + else + return 0x00; + break; + case WEST_PB: + if(GPIO_ReadInputDataBit(PUSH_BUTTON4_GPIO_PORT,PUSH_BUTTON4_PIN)==Bit_SET) + return 0x01; + else + return 0x00; + break; + } +} + +void gpio_set_pushbutton_callback(pushbutton_t pb_id,void (*callback)(void)) +{ + switch(pb_id) + { + case NORTH_PB: + north_pb_callback=callback; + break; + case SOUTH_PB: + south_pb_callback=callback; + break; + case EAST_PB: + east_pb_callback=callback; + break; + case WEST_PB: + west_pb_callback=callback; break; } }