diff --git a/include/gpio.h b/include/gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..9031bf666bc01fd74840f84397d4e0da3a6d13ce --- /dev/null +++ b/include/gpio.h @@ -0,0 +1,15 @@ +#ifndef _GPIO_H +#define _GPIO_H + +#include "stm32f4xx.h" + +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); +void gpio_set_led(led_t led_id); +void gpio_clear_led(led_t led_id); +void gpio_blink_led(led_t led_id, int16_t period_ms); + +#endif diff --git a/src/bioloid_stm32.c b/src/bioloid_stm32.c index a4595d926154b004f3ddbeb40c0f60d56e912b8c..3fb2476a3f87cb8443e8f3aab408892d899cded8 100644 --- a/src/bioloid_stm32.c +++ b/src/bioloid_stm32.c @@ -7,6 +7,7 @@ #include "dynamixel_slave_spi.h" #include "eeprom.h" #include "imu_9dof_dma.h" +#include "gpio.h" uint8_t read_operation(uint8_t address, uint8_t length, uint8_t *data) { @@ -49,34 +50,30 @@ int32_t main(void) GPIO_Init(GPIOD, &GPIO_InitStructure); /* initialize EEPROM */ -// EE_Init(); + EE_Init(); /* initialize the 1ms system timer */ time_init(); /* initialize the dynamixel master interface */ -// dyn_master_init(); -// dyn_master_set_timeout(20); + dyn_master_init(); + dyn_master_set_timeout(20); /* initialize the dynamixel slave interface*/ -// dyn_slave_init(); -// EE_ReadVariable(DEVICE_ID_OFFSET,&address); -// dyn_slave_set_address((uint8_t)address); - + dyn_slave_init(); + EE_ReadVariable(DEVICE_ID_OFFSET,&address); + dyn_slave_set_address((uint8_t)address); + /* initialize the IMU */ imu_init(); + /* initialize the gpio */ + gpio_init(); - if(imu_detect_accel()) + if(imu_accel_detect()) GPIO_SetBits(GPIOD,GPIO_Pin_12); else GPIO_ResetBits(GPIOD,GPIO_Pin_12); - while(1) - { - imu_config_accel(); -// if(dyn_master_ping(1)) -// GPIO_SetBits(GPIOD,GPIO_Pin_12); -// else -// GPIO_ResetBits(GPIOD,GPIO_Pin_12); - GPIO_ToggleBits(GPIOD,GPIO_Pin_15); - delay_ms(1000); - } - + + gpio_blink_led(NORTH_LED,1000); + gpio_blink_led(SOUTH_LED,2000); + gpio_blink_led(EAST_LED,3000); + gpio_blink_led(WEST_LED,4000); 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 new file mode 100644 index 0000000000000000000000000000000000000000..9aa05b7b7666b0f60cf9ea3d8eca65962a025ee9 --- /dev/null +++ b/src/gpio.c @@ -0,0 +1,251 @@ +#include "gpio.h" + +#define LED1_GPIO_CLK RCC_AHB1Periph_GPIOE +#define LED1_PIN GPIO_Pin_2 +#define LED1_GPIO_PORT GPIOE +#define LED1_SOURCE GPIO_PinSource2 + +#define LED2_GPIO_CLK RCC_AHB1Periph_GPIOE +#define LED2_PIN GPIO_Pin_3 +#define LED2_GPIO_PORT GPIOE +#define LED2_SOURCE GPIO_PinSource3 + +#define LED3_GPIO_CLK RCC_AHB1Periph_GPIOE +#define LED3_PIN GPIO_Pin_4 +#define LED3_GPIO_PORT GPIOE +#define LED3_SOURCE GPIO_PinSource4 + +#define LED4_GPIO_CLK RCC_AHB1Periph_GPIOE +#define LED4_PIN GPIO_Pin_5 +#define LED4_GPIO_PORT GPIOE +#define LED4_SOURCE GPIO_PinSource5 + +#define PUSH_BUTTON1_GPIO_CLK RCC_AHB1Periph_GPIOE +#define PUSH_BUTTON1_PIN GPIO_Pin_6 +#define PUSH_BUTTON1_GPIO_PORT GPIOE +#define PUSH_BUTTON1_SOURCE GPIO_PinSource6 + +#define PUSH_BUTTON2_GPIO_CLK RCC_AHB1Periph_GPIOC +#define PUSH_BUTTON2_PIN GPIO_Pin_13 +#define PUSH_BUTTON2_GPIO_PORT GPIOC +#define PUSH_BUTTON2_SOURCE GPIO_PinSource13 + +#define PUSH_BUTTON3_GPIO_CLK RCC_AHB1Periph_GPIOC +#define PUSH_BUTTON3_PIN GPIO_Pin_14 +#define PUSH_BUTTON3_GPIO_PORT GPIOC +#define PUSH_BUTTON3_SOURCE GPIO_PinSource14 + +#define PUSH_BUTTON4_GPIO_CLK RCC_AHB1Periph_GPIOC +#define PUSH_BUTTON4_PIN GPIO_Pin_15 +#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 + +// private variables +__IO uint16_t north_led_period; +__IO uint16_t south_led_period; +__IO uint16_t east_led_period; +__IO uint16_t west_led_period; + +// IRQ hanfler functions +void TIM2_IRQHandler(void) +{ + uint16_t capture; + + if(TIM_GetITStatus(GPIO_TIMER, TIM_IT_CC1)!=RESET) + { + TIM_ClearITPendingBit(GPIO_TIMER,TIM_IT_CC1); + GPIO_ToggleBits(LED1_GPIO_PORT,LED1_PIN); + capture = TIM_GetCapture1(GPIO_TIMER); + TIM_SetCompare1(GPIO_TIMER, capture + north_led_period); + } + if(TIM_GetITStatus(GPIO_TIMER, TIM_IT_CC2)!=RESET) + { + TIM_ClearITPendingBit(GPIO_TIMER,TIM_IT_CC2); + GPIO_ToggleBits(LED2_GPIO_PORT,LED2_PIN); + capture = TIM_GetCapture2(GPIO_TIMER); + TIM_SetCompare2(GPIO_TIMER, capture + south_led_period); + } + if(TIM_GetITStatus(GPIO_TIMER, TIM_IT_CC3)!=RESET) + { + TIM_ClearITPendingBit(GPIO_TIMER,TIM_IT_CC3); + GPIO_ToggleBits(LED3_GPIO_PORT,LED3_PIN); + capture = TIM_GetCapture3(GPIO_TIMER); + TIM_SetCompare3(GPIO_TIMER, capture + east_led_period); + } + if(TIM_GetITStatus(GPIO_TIMER, TIM_IT_CC4)!=RESET) + { + TIM_ClearITPendingBit(GPIO_TIMER,TIM_IT_CC4); + GPIO_ToggleBits(LED4_GPIO_PORT,LED4_PIN); + capture = TIM_GetCapture4(GPIO_TIMER); + TIM_SetCompare4(GPIO_TIMER, capture + west_led_period); + } +} + +// private functions + +// public functions +void gpio_init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + NVIC_InitTypeDef NVIC_InitStructure; + + /* 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); + + /* GPIO Configuration */ + GPIO_InitStructure.GPIO_Pin = LED1_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = LED2_PIN; + GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = LED3_PIN; + GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = LED4_PIN; + GPIO_Init(LED4_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = PUSH_BUTTON1_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(PUSH_BUTTON1_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = PUSH_BUTTON2_PIN; + GPIO_Init(PUSH_BUTTON2_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = PUSH_BUTTON3_PIN; + GPIO_Init(PUSH_BUTTON3_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = PUSH_BUTTON4_PIN; + GPIO_Init(PUSH_BUTTON4_GPIO_PORT, &GPIO_InitStructure); + + // initialize the timer interrupts + NVIC_InitStructure.NVIC_IRQChannel = GPIO_TIMER_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + + NVIC_Init(&NVIC_InitStructure); + + /* Time base 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); +} + +void gpio_set_led(led_t led_id) +{ + switch(led_id) + { + case NORTH_LED: + GPIO_SetBits(LED1_GPIO_PORT,LED1_PIN); + break; + case SOUTH_LED: + GPIO_SetBits(LED2_GPIO_PORT,LED2_PIN); + break; + case EAST_LED: + GPIO_SetBits(LED3_GPIO_PORT,LED3_PIN); + break; + case WEST_LED: + GPIO_SetBits(LED4_GPIO_PORT,LED4_PIN); + break; + } +} + +void gpio_clear_led(led_t led_id) +{ + switch(led_id) + { + case NORTH_LED: + GPIO_ResetBits(LED1_GPIO_PORT,LED1_PIN); + break; + case SOUTH_LED: + GPIO_ResetBits(LED2_GPIO_PORT,LED2_PIN); + break; + case EAST_LED: + GPIO_ResetBits(LED3_GPIO_PORT,LED3_PIN); + break; + case WEST_LED: + GPIO_ResetBits(LED4_GPIO_PORT,LED4_PIN); + break; + } +} + +void gpio_blink_led(led_t led_id, int16_t period_ms) +{ + TIM_OCInitTypeDef TIM_OCInitStructure; + + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + switch(led_id) + { + case NORTH_LED: + if(period_ms>1) + { + 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); + } + else + TIM_ITConfig(GPIO_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); + } + else + TIM_ITConfig(GPIO_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); + } + else + TIM_ITConfig(GPIO_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); + } + else + TIM_ITConfig(GPIO_TIMER, TIM_IT_CC4, DISABLE); + break; + } +}