diff --git a/Makefile b/Makefile index b5792390a521b5ba0d657efa08d2513a457f6215..96d9771a07750574c3bf785d4247b4c017aa9e08 100755 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ TARGET_FILES+=src/system_stm32f4xx.c TARGET_FILES+=src/stm32f4xx_hal_msp.c TARGET_FILES+=src/gpio.c TARGET_FILES+=src/eeprom.c +TARGET_FILES+=src/ram.c TARGET_FILES+=src/bioloid_time.c TARGET_FILES+=src/bioloid_dyn_slave.c TARGET_PROCESSOR=STM32F407VG diff --git a/include/bioloid_dyn_slave.h b/include/bioloid_dyn_slave.h index 2298418bf77f015680f896614020e0c74e5eaa04..1bf96b38b4e854885652e380237da13898b933a1 100644 --- a/include/bioloid_dyn_slave.h +++ b/include/bioloid_dyn_slave.h @@ -13,6 +13,9 @@ extern "C" { extern TDynamixelSlave bioloid_dyn_slave; void bioloid_dyn_slave_init(void); +void bioloid_dyn_slave_set_int(void); +void bioloid_dyn_slave_clear_int(void); +uint8_t bioloid_dyn_slave_is_int_set(void); #ifdef __cplusplus } diff --git a/include/bioloid_registers.h b/include/bioloid_registers.h new file mode 100644 index 0000000000000000000000000000000000000000..4b606f9d3bd2270a26bd69d946850f13439eca09 --- /dev/null +++ b/include/bioloid_registers.h @@ -0,0 +1,64 @@ +#ifndef _BIOLOID_REGISTERS_H +#define _BIOLOID_REGISTERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEVICE_MODEL_OFFSET ((unsigned short int)0x0000) +#define FIRMWARE_VERSION_OFFSET ((unsigned short int)0x0002) +#define DEVICE_ID_OFFSET ((unsigned short int)0x0003) +#define BAUDRATE_OFFSET ((unsigned short int)0x0004) +#define RETURN_DELAY_OFFSET ((unsigned short int)0x0005) +#define RETURN_LEVEL_OFFSET ((unsigned short int)0x0010) + +#define LAST_EEPROM_OFFSET ((unsigned short int)0x0020) + +typedef enum { + BIOLOID_MODEL_NUMBER_L = DEVICE_MODEL_OFFSET, + BIOLOID_MODEL_NUMBER_H = DEVICE_MODEL_OFFSET+1, + BIOLOID_VERSION = FIRMWARE_VERSION_OFFSET, + BIOLOID_ID = DEVICE_ID_OFFSET, + BIOLOID_BAUD_RATE = BAUDRATE_OFFSET, + BIOLOID_RETURN_DELAY_TIME = RETURN_DELAY_OFFSET, + BIOLOID_RETURN_LEVEL = RETURN_LEVEL_OFFSET, + BIOLOID_USER1_LED_CNTRL = 0x20, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // | | | | blink | toggle | value | internally used + BIOLOID_USER1_LED_PERIOD_L = 0x21, + BIOLOID_USER1_LED_PERIOD_H = 0x22, + BIOLOID_USER2_LED_CNTRL = 0x23, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // | | | | blink | toggle | value | internally used + BIOLOID_USER2_LED_PERIOD_L = 0x24, + BIOLOID_USER2_LED_PERIOD_H = 0x25, + BIOLOID_RXD_LED_CNTRL = 0x26, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // | | | | blink | toggle | value | internally used + BIOLOID_RXD_LED_PERIOD_L = 0x27, + BIOLOID_RXD_LED_PERIOD_H = 0x28, + BIOLOID_TXD_LED_CNTRL = 0x29, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // | | | | blink | toggle | value | internally used + BIOLOID_TXD_LED_PERIOD_L = 0x2A, + BIOLOID_TXD_LED_PERIOD_H = 0x2B, + BIOLOID_USER_PB_CNTRL = 0x2C, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // | | | | interrupt flag | enable interrupt | value | internally used + BIOLOID_RESET_PB_CNTRL = 0x2D, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // | | | | interrupt flag | enable interrupt | value | internally used + BIOLOID_START_PB_CNTRL = 0x2E, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // | | | | interrupt flag | enable interrupt | value | internally used + BIOLOID_MODE_PB_CNTRL = 0x2F, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 + // | | | | interrupt flag | enable interrupt | value | internally used +} bioloid_registers; + +#define GPIO_BASE_ADDRESS 0x20 +#define GPIO_MEM_LENGTH 16 +#define GPIO_INT_USED 0x01 +#define GPIO_VALUE 0x02 +#define GPIO_TOGGLE 0x04 +#define GPIO_BLINK 0x08 +#define GPIO_INT_EN 0x04 +#define GPIO_INT_FLAG 0x08 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/eeprom.h b/include/eeprom.h index 6a199a1faceebb1086afbc20975a54dab8a7c8e5..25c56092a20b8b2c8795c3a052b5c87ca371016c 100755 --- a/include/eeprom.h +++ b/include/eeprom.h @@ -78,17 +78,6 @@ /* Page full define */ #define PAGE_FULL ((uint8_t)0x80) -/* Virtual address defined by the user: 0xFFFF value is prohibited */ -#define DEVICE_MODEL_OFFSET ((uint16_t)0x0000) -#define FIRMWARE_VERSION_OFFSET ((uint16_t)0x0002) -#define DEVICE_ID_OFFSET ((uint16_t)0x0003) -#define BAUDRATE_OFFSET ((uint16_t)0x0004) -#define RETURN_DELAY_OFFSET ((uint16_t)0x0005) -#define MM_PERIOD_OFFSET ((uint16_t)0x0006) -#define RETURN_LEVEL_OFFSET ((uint16_t)0x0010) - -#define LAST_EEPROM_OFFSET ((uint16_t)0x0017) - /* Variables' number */ #define NB_OF_VAR ((uint8_t)0x03) diff --git a/include/gpio.h b/include/gpio.h index 25be95af7cc2d496b868559cbde57dfba0daa99b..4f5ea59546abdde0bca4079660f0fadd901c248c 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -20,6 +20,8 @@ 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)); +// operation functions +void gpio_process_cmd(unsigned short int address,unsigned short int length,unsigned char *data); #ifdef __cplusplus } diff --git a/include/ram.h b/include/ram.h index a1d31eb2ebc8dcc4ff2097f24c60094acc7c000a..3b350e370257bc192a00a155c8ac68b6f17ee3af 100644 --- a/include/ram.h +++ b/include/ram.h @@ -6,7 +6,7 @@ extern "C" { #endif #include "stm32f4xx.h" -#include "eeprom.h" +#include "bioloid_registers.h" #define RAM_SUCCESS 0 #define RAM_BAD_ADDRESS -1 @@ -14,134 +14,6 @@ extern "C" { #define RAM_BAD_BIT -3 #define RAM_BAD_ACCESS -4 -typedef enum { - BIOLOID_MODEL_NUMBER_L = DEVICE_MODEL_OFFSET, - BIOLOID_MODEL_NUMBER_H = DEVICE_MODEL_OFFSET+1, - BIOLOID_VERSION = FIRMWARE_VERSION_OFFSET, - BIOLOID_ID = DEVICE_ID_OFFSET, - BIOLOID_BAUD_RATE = BAUDRATE_OFFSET, - BIOLOID_RETURN_DELAY_TIME = RETURN_DELAY_OFFSET, - BIOLOID_MM_PERIOD_L = MM_PERIOD_OFFSET, - BIOLOID_MM_PERIOD_H = MM_PERIOD_OFFSET+1, - BIOLOID_RETURN_LEVEL = RETURN_LEVEL_OFFSET, - BIOLOID_DXL_POWER = 0x18, - BIOLOID_LED = 0x19, - BIOLOID_PUSHBUTTON = 0x1A, - BIOLOID_MM_NUM_SERVOS = 0x1B, - BIOLOID_MM_CONTROL = 0x1C, - BIOLOID_MM_STATUS = 0x1D, - BIOLOID_MM_MODULE_EN0 = 0x1E, - BIOLOID_MM_MODULE_EN1 = 0x1F, - BIOLOID_MM_MODULE_EN2 = 0x20, - BIOLOID_MM_MODULE_EN3 = 0x21, - BIOLOID_MM_MODULE_EN4 = 0x22, - BIOLOID_MM_MODULE_EN5 = 0x23, - BIOLOID_MM_MODULE_EN6 = 0x24, - BIOLOID_MM_MODULE_EN7 = 0x25, - BIOLOID_MM_MODULE_EN8 = 0x26, - BIOLOID_MM_MODULE_EN9 = 0x27, - BIOLOID_MM_MODULE_EN10 = 0x28, - BIOLOID_MM_MODULE_EN11 = 0x29, - BIOLOID_MM_MODULE_EN12 = 0x2A, - BIOLOID_MM_MODULE_EN13 = 0x2B, - BIOLOID_MM_MODULE_EN14 = 0x2C, - BIOLOID_MM_MODULE_EN15 = 0x2D, - BIOLOID_MM_SERVO0_CUR_POS_L = 0x2E, - BIOLOID_MM_SERVO0_CUR_POS_H = 0x2F, - BIOLOID_MM_SERVO1_CUR_POS_L = 0x30, - BIOLOID_MM_SERVO1_CUR_POS_H = 0x31, - BIOLOID_MM_SERVO2_CUR_POS_L = 0x32, - BIOLOID_MM_SERVO2_CUR_POS_H = 0x33, - BIOLOID_MM_SERVO3_CUR_POS_L = 0x34, - BIOLOID_MM_SERVO3_CUR_POS_H = 0x35, - BIOLOID_MM_SERVO4_CUR_POS_L = 0x36, - BIOLOID_MM_SERVO4_CUR_POS_H = 0x37, - BIOLOID_MM_SERVO5_CUR_POS_L = 0x38, - BIOLOID_MM_SERVO5_CUR_POS_H = 0x39, - BIOLOID_MM_SERVO6_CUR_POS_L = 0x3A, - BIOLOID_MM_SERVO6_CUR_POS_H = 0x3B, - BIOLOID_MM_SERVO7_CUR_POS_L = 0x3C, - BIOLOID_MM_SERVO7_CUR_POS_H = 0x3D, - BIOLOID_MM_SERVO8_CUR_POS_L = 0x3E, - BIOLOID_MM_SERVO8_CUR_POS_H = 0x3F, - BIOLOID_MM_SERVO9_CUR_POS_L = 0x40, - BIOLOID_MM_SERVO9_CUR_POS_H = 0x41, - BIOLOID_MM_SERVO10_CUR_POS_L = 0x42, - BIOLOID_MM_SERVO10_CUR_POS_H = 0x43, - BIOLOID_MM_SERVO11_CUR_POS_L = 0x44, - BIOLOID_MM_SERVO11_CUR_POS_H = 0x45, - BIOLOID_MM_SERVO12_CUR_POS_L = 0x46, - BIOLOID_MM_SERVO12_CUR_POS_H = 0x47, - BIOLOID_MM_SERVO13_CUR_POS_L = 0x48, - BIOLOID_MM_SERVO13_CUR_POS_H = 0x49, - BIOLOID_MM_SERVO14_CUR_POS_L = 0x4A, - BIOLOID_MM_SERVO14_CUR_POS_H = 0x4B, - BIOLOID_MM_SERVO15_CUR_POS_L = 0x4C, - BIOLOID_MM_SERVO15_CUR_POS_H = 0x4D, - BIOLOID_MM_SERVO16_CUR_POS_L = 0x4E, - BIOLOID_MM_SERVO16_CUR_POS_H = 0x4F, - BIOLOID_MM_SERVO17_CUR_POS_L = 0x50, - BIOLOID_MM_SERVO17_CUR_POS_H = 0x51, - BIOLOID_MM_SERVO18_CUR_POS_L = 0x52, - BIOLOID_MM_SERVO18_CUR_POS_H = 0x53, - BIOLOID_MM_SERVO19_CUR_POS_L = 0x54, - BIOLOID_MM_SERVO19_CUR_POS_H = 0x55, - BIOLOID_MM_SERVO20_CUR_POS_L = 0x56, - BIOLOID_MM_SERVO20_CUR_POS_H = 0x57, - BIOLOID_MM_SERVO21_CUR_POS_L = 0x58, - BIOLOID_MM_SERVO21_CUR_POS_H = 0x59, - BIOLOID_MM_SERVO22_CUR_POS_L = 0x5A, - BIOLOID_MM_SERVO22_CUR_POS_H = 0x5B, - BIOLOID_MM_SERVO23_CUR_POS_L = 0x5C, - BIOLOID_MM_SERVO23_CUR_POS_H = 0x5D, - BIOLOID_MM_SERVO24_CUR_POS_L = 0x5E, - BIOLOID_MM_SERVO24_CUR_POS_H = 0x5F, - BIOLOID_MM_SERVO25_CUR_POS_L = 0x60, - BIOLOID_MM_SERVO25_CUR_POS_H = 0x61, - BIOLOID_MM_SERVO26_CUR_POS_L = 0x62, - BIOLOID_MM_SERVO26_CUR_POS_H = 0x63, - BIOLOID_MM_SERVO27_CUR_POS_L = 0x64, - BIOLOID_MM_SERVO27_CUR_POS_H = 0x65, - BIOLOID_MM_SERVO28_CUR_POS_L = 0x66, - BIOLOID_MM_SERVO28_CUR_POS_H = 0x67, - BIOLOID_MM_SERVO29_CUR_POS_L = 0x68, - BIOLOID_MM_SERVO29_CUR_POS_H = 0x69, - BIOLOID_MM_SERVO30_CUR_POS_L = 0x6A, - BIOLOID_MM_SERVO30_CUR_POS_H = 0x6B, - BIOLOID_IMU_STATUS = 0x6C, - BIOLOID_IMU_CONTROL = 0x6D, - BIOLOID_IMU_ACCEL_X_L = 0x6E, - BIOLOID_IMU_ACCEL_X_H = 0x6F, - BIOLOID_IMU_ACCEL_Y_L = 0x70, - BIOLOID_IMU_ACCEL_Y_H = 0x71, - BIOLOID_IMU_ACCEL_Z_L = 0x72, - BIOLOID_IMU_ACCEL_Z_H = 0x73, - BIOLOID_IMU_GYRO_X_L = 0x74, - BIOLOID_IMU_GYRO_X_H = 0x75, - BIOLOID_IMU_GYRO_Y_L = 0x76, - BIOLOID_IMU_GYRO_Y_H = 0x77, - BIOLOID_IMU_GYRO_Z_L = 0x78, - BIOLOID_IMU_GYRO_Z_H = 0x79, - BIOLOID_IMU_COMPASS_X_L = 0x7A, - BIOLOID_IMU_COMPASS_X_H = 0x7B, - BIOLOID_IMU_COMPASS_Y_L = 0x7C, - BIOLOID_IMU_COMPASS_Y_H = 0x7D, - BIOLOID_IMU_COMPASS_Z_L = 0x7E, - BIOLOID_IMU_COMPASS_Z_H = 0x7F, - BIOLOID_IMU_TEMP = 0x80, - BIOLOID_ACTION_PAGE = 0x81, - BIOLOID_ACTION_CONTROL = 0x82, - BIOLOID_ACTION_STATUS = 0x83, - BIOLOID_MM_PELVIS_ROLL_GAIN_L = 0x84, - BIOLOID_MM_PELVIS_ROLL_GAIN_R = 0x85, - BIOLOID_MM_ANKLE_ROLL_GAIN_L = 0x86, - BIOLOID_MM_ANKLE_ROLL_GAIN_R = 0x87, - BIOLOID_MM_ANKLE_PITCH_GAIN_L = 0x88, - BIOLOID_MM_ANKLE_PITCH_GAIN_R = 0x89, - BIOLOID_MM_KNEE_GAIN_L = 0x8A, - BIOLOID_MM_KNEE_GAIN_R = 0x8B -} bioloid_registers; - #define RAM_SIZE 256 extern uint8_t ram_data[RAM_SIZE]; @@ -155,7 +27,8 @@ uint8_t ram_clear_bit(uint8_t address, uint8_t bit); uint8_t ram_write_byte(uint8_t address, uint8_t data); uint8_t ram_write_word(uint8_t address, uint16_t data); uint8_t ram_write_table(uint8_t address, uint8_t length,uint8_t *data); -inline uint8_t ram_in_range(uint8_t start_reg,uint8_t end_reg,uint8_t address,uint8_t length); +inline uint8_t ram_in_range(uint8_t reg,uint8_t address,uint8_t length); +inline uint8_t ram_in_window(uint8_t start_reg,uint8_t reg_length,uint8_t start_address,uint8_t address_length); #ifdef __cplusplus } diff --git a/src/bioloid_dyn_slave.c b/src/bioloid_dyn_slave.c index 28eceee2a0077d80d2aff8ab3758dc65f183db0c..a4edced5d1a85756ec7e3962d8f8a4f4f4dd8714 100644 --- a/src/bioloid_dyn_slave.c +++ b/src/bioloid_dyn_slave.c @@ -1,20 +1,65 @@ #include "bioloid_dyn_slave.h" #include "bioloid_time.h" #include "usart3.h" +#include "ram.h" +#include "eeprom.h" +#include "gpio.h" + +/* external interrupt pin */ +#define DYN_SLAVE_EXT_INT_PIN GPIO_PIN_8 +#define DYN_SLAVE_EXT_INT_GPIO_PORT GPIOE +#define DYN_SLAVE_EXT_INT_EN_GPIO_CLK __HAL_RCC_GPIOE_CLK_ENABLE() /* private variables */ TDynamixelSlave bioloid_dyn_slave; TTime bioloid_dyn_slave_timer; TComm bioloid_dyn_slave_comm; +UART_InitTypeDef bioloid_comm_init; +uint8_t bioloid_slave_int_state; // private functions unsigned char bioloid_on_read(unsigned short int address,unsigned short int length,unsigned char *data) { - return 0x00; + unsigned char error; + /* dynamixel slave internal operation registers */ + error=ram_read_table(address,length,data); + + return error; } unsigned char bioloid_on_write(unsigned short int address,unsigned short int length,unsigned char *data) { + unsigned char i,j; + + /* dynamixel slave internal operation registers */ + if(ram_in_range(BIOLOID_ID,address,length)) + { + dyn_slave_set_address(&bioloid_dyn_slave,data[BIOLOID_ID-address]); + ram_write_byte(BIOLOID_ID,data[BIOLOID_ID-address]); + } + if(ram_in_range(BIOLOID_BAUD_RATE,address,length)) + { + bioloid_comm_init.BaudRate=2000000/(data[BIOLOID_BAUD_RATE-address]+1); + usart3_config(&bioloid_dyn_slave_comm,&bioloid_comm_init); + ram_write_byte(BIOLOID_BAUD_RATE,data[BIOLOID_BAUD_RATE-address]); + } + if(ram_in_range(BIOLOID_RETURN_DELAY_TIME,address,length)) + { + dyn_slave_set_return_delay(&bioloid_dyn_slave,data[BIOLOID_RETURN_DELAY_TIME-address]); + ram_write_byte(BIOLOID_RETURN_DELAY_TIME,data[BIOLOID_RETURN_DELAY_TIME-address]); + } + if(ram_in_range(BIOLOID_RETURN_LEVEL,address,length)) + { + dyn_slave_set_return_level(&bioloid_dyn_slave,data[BIOLOID_RETURN_LEVEL-address]); + ram_write_byte(BIOLOID_RETURN_LEVEL,data[BIOLOID_RETURN_LEVEL-address]); + } + // GPIO commands + if(ram_in_window(GPIO_BASE_ADDRESS,GPIO_MEM_LENGTH,address,length)) + gpio_process_cmd(address,length,data); + // write eeprom + for(i=address,j=0;i<LAST_EEPROM_OFFSET && i<(address+length);i++,j++) + EE_WriteVariable(i,data[j]); + return 0x00; } @@ -22,20 +67,23 @@ unsigned char bioloid_on_write(unsigned short int address,unsigned short int len void bioloid_dyn_slave_init(void) { TUSART_IRQ_Priorities priorities; - UART_InitTypeDef Init; + GPIO_InitTypeDef GPIO_InitStructure; + + // initialize private variables + bioloid_slave_int_state=0; // initialize timer structure time_init(&bioloid_dyn_slave_timer,bioloid_time_get_counts_per_us(),bioloid_time_get_counts); /* initialize the comm object */ comm_init(&bioloid_dyn_slave_comm,0x01,&bioloid_dyn_slave_timer); - Init.BaudRate = 921600; - Init.WordLength = UART_WORDLENGTH_8B; - Init.StopBits = UART_STOPBITS_1; - Init.Parity = UART_PARITY_NONE; - Init.Mode = UART_MODE_TX_RX; - Init.HwFlowCtl = UART_HWCONTROL_NONE; - Init.OverSampling = UART_OVERSAMPLING_16; + bioloid_comm_init.BaudRate = 921600; + bioloid_comm_init.WordLength = UART_WORDLENGTH_8B; + bioloid_comm_init.StopBits = UART_STOPBITS_1; + bioloid_comm_init.Parity = UART_PARITY_NONE; + bioloid_comm_init.Mode = UART_MODE_TX_RX; + bioloid_comm_init.HwFlowCtl = UART_HWCONTROL_NONE; + bioloid_comm_init.OverSampling = UART_OVERSAMPLING_16; priorities.irq_priority=0; priorities.irq_subpriority=0; @@ -44,11 +92,35 @@ void bioloid_dyn_slave_init(void) priorities.dma_tx_priority=1; priorities.dma_tx_subpriority=0; - usart3_init(&bioloid_dyn_slave_comm,&Init,&priorities); - dyn_slave_init(&bioloid_dyn_slave,&bioloid_dyn_slave_comm,0x01); + usart3_init(&bioloid_dyn_slave_comm,&bioloid_comm_init,&priorities); + dyn_slave_init(&bioloid_dyn_slave,&bioloid_dyn_slave_comm,ram_data[BIOLOID_ID]); bioloid_dyn_slave.on_read=bioloid_on_read; bioloid_dyn_slave.on_write=bioloid_on_write; - //dyn_slave_set_return_delay(&battery_dyn_slave,ram_data[BATTERY_RETURN_DELAY_TIME]); - //dyn_slave_set_return_level(&battery_dyn_slave,ram_data[BATTERY_STATUS_RETURN_LEVEL]); + dyn_slave_set_return_delay(&bioloid_dyn_slave,ram_data[BIOLOID_RETURN_DELAY_TIME]); + dyn_slave_set_return_level(&bioloid_dyn_slave,ram_data[BIOLOID_RETURN_LEVEL]); + + /* initialize the external interrupt pin */ + DYN_SLAVE_EXT_INT_EN_GPIO_CLK; + GPIO_InitStructure.Pin = DYN_SLAVE_EXT_INT_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; + HAL_GPIO_Init(DYN_SLAVE_EXT_INT_GPIO_PORT, &GPIO_InitStructure); } +void bioloid_dyn_slave_set_int(void) +{ + HAL_GPIO_WritePin(DYN_SLAVE_EXT_INT_GPIO_PORT,DYN_SLAVE_EXT_INT_PIN,GPIO_PIN_RESET); + bioloid_slave_int_state=1; +} + +void bioloid_dyn_slave_clear_int(void) +{ + HAL_GPIO_WritePin(DYN_SLAVE_EXT_INT_GPIO_PORT,DYN_SLAVE_EXT_INT_PIN,GPIO_PIN_SET); + bioloid_slave_int_state=0; +} + +uint8_t bioloid_dyn_slave_is_int_set(void) +{ + return bioloid_slave_int_state; +} diff --git a/src/bioloid_stm32.c b/src/bioloid_stm32.c index c65b2d86bafe79ecba0bc53d177008bc8556b567..e5bcd5387cf7547a48eab87c9ec95bd5814df588 100644 --- a/src/bioloid_stm32.c +++ b/src/bioloid_stm32.c @@ -1,9 +1,9 @@ #include "stm32f4xx_hal.h" -#include "bioloid_dyn_slave.h" #include "gpio.h" #include "eeprom.h" +#include "ram.h" #include "bioloid_time.h" -#include "stm32_time.h" +#include "bioloid_dyn_slave.h" int32_t main(void) { @@ -11,7 +11,9 @@ int32_t main(void) /* initialize the gpio */ gpio_init(); /* initialize the eeprom emmulation */ -// EE_Init(); + EE_Init(); + /* initialize the ram module */ + ram_init(); /* initialize the time module */ bioloid_time_init(); /* initialize the dynamixel slave interface */ diff --git a/src/eeprom.c b/src/eeprom.c index 18f4c047fe7da62a5fca0e628b7143b02340178f..8696f8cca185f890aced9f3a72435486ef5d0a3f 100755 --- a/src/eeprom.c +++ b/src/eeprom.c @@ -41,16 +41,16 @@ /* Includes ------------------------------------------------------------------*/ #include "eeprom.h" +#include "bioloid_registers.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define EEPROM_SIZE 0x09 #define DEFAULT_DEVICE_MODEL 0x7300 -#define DEFAULT_FIRMWARE_VERSION 0x0013 -#define DEFAULT_DEVICE_ID 0x00C0 +#define DEFAULT_FIRMWARE_VERSION 0x0001 +#define DEFAULT_DEVICE_ID 0x0002 #define DEFAULT_BAUDRATE 0x0001 #define DEFAULT_RETURN_DELAY 0x0000 -#define DEFAULT_MM_PERIOD 0x01FF #define DEFAULT_RETURN_LEVEL 0x0002 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ @@ -73,10 +73,6 @@ uint16_t eeprom_data[] __attribute__ ((section (".eeprom")))={VALID_PAGE, BAUDRATE_OFFSET, DEFAULT_RETURN_DELAY,// return delay time RETURN_DELAY_OFFSET, - DEFAULT_MM_PERIOD&0xFF, - MM_PERIOD_OFFSET, - DEFAULT_MM_PERIOD>>8, - MM_PERIOD_OFFSET+1, DEFAULT_RETURN_LEVEL, RETURN_LEVEL_OFFSET};// return level diff --git a/src/gpio.c b/src/gpio.c index 7e541ea51753318c560f464a7117119ad0dca99b..3dd9b2587abb5eb3ceaf79582a2eaf7bb8561596 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -55,10 +55,16 @@ void (*reset_pb_callback)(void); void (*user_pb_callback)(void); void (*start_pb_callback)(void); void (*mode_pb_callback)(void); -__IO uint16_t led_tx_period; -__IO uint16_t led_rx_period; -__IO uint16_t led_usr1_period; -__IO uint16_t led_usr2_period; +/* led period variables */ +uint16_t led_tx_period; +uint16_t led_rx_period; +uint16_t led_usr1_period; +uint16_t led_usr2_period; +/* led blinking status */ +uint8_t led_tx_blinking; +uint8_t led_rx_blinking; +uint8_t led_usr1_blinking; +uint8_t led_usr2_blinking; // IRQ handler functions void GPI_EXTI1_IRQHandler(void) @@ -66,14 +72,26 @@ void GPI_EXTI1_IRQHandler(void) if(__HAL_GPIO_EXTI_GET_IT(RESET_PB_PIN) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(RESET_PB_PIN); - if(reset_pb_callback!=0) - reset_pb_callback(); + if(ram_data[BIOLOID_RESET_PB_CNTRL]&GPIO_INT_USED) + { + if(reset_pb_callback!=0) + reset_pb_callback(); + } + else + { + } } if(__HAL_GPIO_EXTI_GET_IT(USER_PB_PIN) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(USER_PB_PIN); - if(user_pb_callback!=0) - user_pb_callback(); + if(ram_data[BIOLOID_USER_PB_CNTRL]&GPIO_INT_USED) + { + if(user_pb_callback!=0) + user_pb_callback(); + } + else + { + } } } @@ -82,8 +100,14 @@ void GPI_EXTI2_IRQHandler(void) if(__HAL_GPIO_EXTI_GET_IT(START_PB_PIN) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(START_PB_PIN); - if(start_pb_callback!=0) - start_pb_callback(); + if(ram_data[BIOLOID_START_PB_CNTRL]&GPIO_INT_USED) + { + if(start_pb_callback!=0) + start_pb_callback(); + } + else + { + } } } @@ -92,8 +116,14 @@ void GPI_EXTI3_IRQHandler(void) if(__HAL_GPIO_EXTI_GET_IT(MODE_PB_PIN) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(MODE_PB_PIN); - if(mode_pb_callback!=0) - mode_pb_callback(); + if(ram_data[BIOLOID_MODE_PB_CNTRL]&GPIO_INT_USED) + { + if(mode_pb_callback!=0) + mode_pb_callback(); + } + else + { + } } } @@ -109,6 +139,10 @@ void GPO_TIMER_IRQHandler(void) capture = HAL_TIM_ReadCapturedValue(&GPO_TIM_Handle, TIM_CHANNEL_1); __HAL_TIM_SET_COMPARE(&GPO_TIM_Handle, TIM_CHANNEL_1, (capture + led_tx_period)); HAL_GPIO_TogglePin(LED_TX_GPIO_PORT,LED_TX_PIN); + if(ram_data[BIOLOID_TXD_LED_CNTRL]&0x02) + ram_data[BIOLOID_TXD_LED_CNTRL]&=0xFD; + else + ram_data[BIOLOID_TXD_LED_CNTRL]|=0x02; } } if(__HAL_TIM_GET_FLAG(&GPO_TIM_Handle, TIM_FLAG_CC2) != RESET) @@ -119,6 +153,10 @@ void GPO_TIMER_IRQHandler(void) capture = HAL_TIM_ReadCapturedValue(&GPO_TIM_Handle, TIM_CHANNEL_2); __HAL_TIM_SET_COMPARE(&GPO_TIM_Handle, TIM_CHANNEL_2, (capture + led_rx_period)); HAL_GPIO_TogglePin(LED_RX_GPIO_PORT,LED_RX_PIN); + if(ram_data[BIOLOID_RXD_LED_CNTRL]&0x02) + ram_data[BIOLOID_RXD_LED_CNTRL]&=0xFD; + else + ram_data[BIOLOID_RXD_LED_CNTRL]|=0x02; } } if(__HAL_TIM_GET_FLAG(&GPO_TIM_Handle, TIM_FLAG_CC3) != RESET) @@ -129,6 +167,10 @@ void GPO_TIMER_IRQHandler(void) capture = HAL_TIM_ReadCapturedValue(&GPO_TIM_Handle, TIM_CHANNEL_3); __HAL_TIM_SET_COMPARE(&GPO_TIM_Handle, TIM_CHANNEL_3, (capture + led_usr1_period)); HAL_GPIO_TogglePin(LED_USR1_GPIO_PORT,LED_USR1_PIN); + if(ram_data[BIOLOID_USER1_LED_CNTRL]&0x02) + ram_data[BIOLOID_USER1_LED_CNTRL]&=0xFD; + else + ram_data[BIOLOID_USER1_LED_CNTRL]|=0x02; } } if(__HAL_TIM_GET_FLAG(&GPO_TIM_Handle, TIM_FLAG_CC4) != RESET) @@ -139,6 +181,10 @@ void GPO_TIMER_IRQHandler(void) capture = HAL_TIM_ReadCapturedValue(&GPO_TIM_Handle, TIM_CHANNEL_4); __HAL_TIM_SET_COMPARE(&GPO_TIM_Handle, TIM_CHANNEL_4, (capture + led_usr2_period)); HAL_GPIO_TogglePin(LED_USR2_GPIO_PORT,LED_USR2_PIN); + if(ram_data[BIOLOID_USER2_LED_CNTRL]&0x02) + ram_data[BIOLOID_USER2_LED_CNTRL]&=0xFD; + else + ram_data[BIOLOID_USER2_LED_CNTRL]|=0x02; } } /* TIM Update event */ @@ -177,6 +223,10 @@ void gpio_init(void) led_rx_period=0; led_usr1_period=0; led_usr2_period=0; + led_tx_blinking=0; + led_rx_blinking=0; + led_usr1_blinking=0; + led_usr2_blinking=0; /* enable clocks */ ENABLE_LED_TX_GPIO_CLK; @@ -320,6 +370,7 @@ void gpio_toggle_led(led_t led_id) void gpio_blink_led(led_t led_id, int16_t period_ms) { TIM_OC_InitTypeDef TIM_OCInitStructure; + uint32_t capture; TIM_OCInitStructure.OCMode = TIM_OCMODE_TIMING; TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH; @@ -328,48 +379,80 @@ void gpio_blink_led(led_t led_id, int16_t period_ms) switch(led_id) { case TXD_LED: - if(period_ms>1) + if(period_ms>=1) { led_tx_period=period_ms; - TIM_OCInitStructure.Pulse = led_tx_period; - HAL_TIM_OC_ConfigChannel(&GPO_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_1); - HAL_TIM_OC_Start_IT(&GPO_TIM_Handle, TIM_CHANNEL_1); + if(!led_tx_blinking) + { + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM_Handle, TIM_CHANNEL_1); + TIM_OCInitStructure.Pulse = capture+led_tx_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_1); + HAL_TIM_OC_Start_IT(&GPO_TIM_Handle, TIM_CHANNEL_1); + led_tx_blinking=1; + } } else + { HAL_TIM_OC_Stop_IT(&GPO_TIM_Handle, TIM_CHANNEL_1); + led_tx_blinking=0; + } break; case RXD_LED: - if(period_ms>1) + if(period_ms>=1) { led_rx_period=period_ms; - TIM_OCInitStructure.Pulse = led_rx_period; - HAL_TIM_OC_ConfigChannel(&GPO_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_2); - HAL_TIM_OC_Start_IT(&GPO_TIM_Handle, TIM_CHANNEL_2); + if(!led_rx_blinking) + { + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM_Handle, TIM_CHANNEL_2); + TIM_OCInitStructure.Pulse = capture+led_rx_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_2); + HAL_TIM_OC_Start_IT(&GPO_TIM_Handle, TIM_CHANNEL_2); + led_tx_blinking=1; + } } else + { HAL_TIM_OC_Stop_IT(&GPO_TIM_Handle, TIM_CHANNEL_2); + led_tx_blinking=0; + } break; case USER1_LED: - if(period_ms>1) + if(period_ms>=1) { led_usr1_period=period_ms; - TIM_OCInitStructure.Pulse = led_usr1_period; - HAL_TIM_OC_ConfigChannel(&GPO_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_3); - HAL_TIM_OC_Start_IT(&GPO_TIM_Handle, TIM_CHANNEL_3); + if(!led_usr1_blinking) + { + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM_Handle, TIM_CHANNEL_3); + TIM_OCInitStructure.Pulse = capture+led_usr1_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_3); + HAL_TIM_OC_Start_IT(&GPO_TIM_Handle, TIM_CHANNEL_3); + led_usr1_blinking=1; + } } else + { HAL_TIM_OC_Stop_IT(&GPO_TIM_Handle, TIM_CHANNEL_3); + led_usr1_blinking=0; + } break; case USER2_LED: - if(period_ms>1) + if(period_ms>=1) { led_usr2_period=period_ms; - TIM_OCInitStructure.Pulse = led_usr2_period; - HAL_TIM_OC_ConfigChannel(&GPO_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_4); - HAL_TIM_OC_Start_IT(&GPO_TIM_Handle, TIM_CHANNEL_4); + if(!led_usr2_blinking) + { + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM_Handle, TIM_CHANNEL_4); + TIM_OCInitStructure.Pulse = capture+led_usr2_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_4); + HAL_TIM_OC_Start_IT(&GPO_TIM_Handle, TIM_CHANNEL_4); + led_usr2_blinking=1; + } } else + { HAL_TIM_OC_Stop_IT(&GPO_TIM_Handle, TIM_CHANNEL_4); + led_usr2_blinking=0; + } break; } } @@ -425,3 +508,172 @@ void gpio_set_pushbutton_callback(pushbutton_t pb_id,void (*callback)(void)) break; } } + +void gpio_process_cmd(unsigned short int address,unsigned short int length,unsigned char *data) +{ + uint16_t period; + + /* LED's */ + if(ram_in_range(BIOLOID_USER1_LED_CNTRL,address,length)) + { + if(!ram_data[BIOLOID_USER1_LED_CNTRL]&GPIO_INT_USED)/* GPIO is not internally used */ + { + period=led_usr1_period; + if(ram_in_range(BIOLOID_USER1_LED_PERIOD_L,address,length)) + period=(period&0xFF00)+data[BIOLOID_USER1_LED_PERIOD_L-address]; + if(ram_in_range(BIOLOID_USER1_LED_PERIOD_H,address,length)) + period=(period&0x00FF)+(data[BIOLOID_USER1_LED_PERIOD_H-address]<<8); + if(data[BIOLOID_USER1_LED_CNTRL-address]&GPIO_BLINK) + gpio_blink_led(USER1_LED,period); + else + { + gpio_blink_led(USER1_LED,0x0000); + if(data[BIOLOID_USER1_LED_CNTRL-address]&GPIO_TOGGLE) + { + gpio_toggle_led(USER1_LED); + if(ram_data[BIOLOID_USER1_LED_CNTRL]&0x02) + ram_data[BIOLOID_USER1_LED_CNTRL]&=0xFD; + else + ram_data[BIOLOID_USER1_LED_CNTRL]|=0x02; + } + else + { + if(data[BIOLOID_USER1_LED_CNTRL-address]&GPIO_VALUE) + { + gpio_set_led(USER1_LED); + ram_data[BIOLOID_USER1_LED_CNTRL]|=0x02; + } + else + { + gpio_clear_led(USER1_LED); + ram_data[BIOLOID_USER1_LED_CNTRL]&=0xFD; + } + } + } + } + } + if(ram_in_range(BIOLOID_USER2_LED_CNTRL,address,length)) + { + if(!ram_data[BIOLOID_USER2_LED_CNTRL]&GPIO_INT_USED)/* GPIO is not internally used */ + { + period=led_usr2_period; + if(ram_in_range(BIOLOID_USER2_LED_PERIOD_L,address,length)) + period=(period&0xFF00)+data[BIOLOID_USER2_LED_PERIOD_L-address]; + if(ram_in_range(BIOLOID_USER2_LED_PERIOD_H,address,length)) + period=(period&0x00FF)+(data[BIOLOID_USER2_LED_PERIOD_H-address]<<8); + if(data[BIOLOID_USER2_LED_CNTRL-address]&GPIO_BLINK) + gpio_blink_led(USER2_LED,period); + else + { + gpio_blink_led(USER2_LED,0x0000); + if(data[BIOLOID_USER2_LED_CNTRL-address]&GPIO_TOGGLE) + { + gpio_toggle_led(USER2_LED); + if(ram_data[BIOLOID_USER2_LED_CNTRL]&0x02) + ram_data[BIOLOID_USER2_LED_CNTRL]&=0xFD; + else + ram_data[BIOLOID_USER2_LED_CNTRL]|=0x02; + } + else + { + if(data[BIOLOID_USER2_LED_CNTRL-address]&GPIO_VALUE) + { + gpio_set_led(USER2_LED); + ram_data[BIOLOID_USER2_LED_CNTRL]|=0x02; + } + else + { + gpio_clear_led(USER2_LED); + ram_data[BIOLOID_USER2_LED_CNTRL]&=0xFD; + } + } + } + } + } + if(ram_in_range(BIOLOID_RXD_LED_CNTRL,address,length)) + { + if(!ram_data[BIOLOID_RXD_LED_CNTRL]&GPIO_INT_USED)/* GPIO is not internally used */ + { + period=led_usr1_period; + if(ram_in_range(BIOLOID_RXD_LED_PERIOD_L,address,length)) + period=(period&0xFF00)+data[BIOLOID_RXD_LED_PERIOD_L-address]; + if(ram_in_range(BIOLOID_RXD_LED_PERIOD_H,address,length)) + period=(period&0x00FF)+(data[BIOLOID_RXD_LED_PERIOD_H-address]<<8); + if(data[BIOLOID_RXD_LED_CNTRL-address]&GPIO_BLINK) + gpio_blink_led(RXD_LED,period); + else + { + gpio_blink_led(RXD_LED,0x0000); + if(data[BIOLOID_RXD_LED_CNTRL-address]&GPIO_TOGGLE) + { + gpio_toggle_led(RXD_LED); + if(ram_data[BIOLOID_RXD_LED_CNTRL]&0x02) + ram_data[BIOLOID_RXD_LED_CNTRL]&=0xFD; + else + ram_data[BIOLOID_RXD_LED_CNTRL]|=0x02; + } + else + { + if(data[BIOLOID_RXD_LED_CNTRL-address]&GPIO_VALUE) + { + gpio_set_led(RXD_LED); + ram_data[BIOLOID_RXD_LED_CNTRL]|=0x02; + } + else + { + gpio_clear_led(RXD_LED); + ram_data[BIOLOID_RXD_LED_CNTRL]&=0xFD; + } + } + } + } + } + if(ram_in_range(BIOLOID_TXD_LED_CNTRL,address,length)) + { + if(!ram_data[BIOLOID_TXD_LED_CNTRL]&GPIO_INT_USED)/* GPIO is not internally used */ + { + period=led_usr1_period; + if(ram_in_range(BIOLOID_TXD_LED_PERIOD_L,address,length)) + period=(period&0xFF00)+data[BIOLOID_TXD_LED_PERIOD_L-address]; + if(ram_in_range(BIOLOID_TXD_LED_PERIOD_H,address,length)) + period=(period&0x00FF)+(data[BIOLOID_TXD_LED_PERIOD_H-address]<<8); + if(data[BIOLOID_TXD_LED_CNTRL-address]&GPIO_BLINK) + gpio_blink_led(TXD_LED,period); + else + { + gpio_blink_led(TXD_LED,0x0000); + if(data[BIOLOID_TXD_LED_CNTRL-address]&GPIO_TOGGLE) + { + gpio_toggle_led(TXD_LED); + if(ram_data[BIOLOID_TXD_LED_CNTRL]&0x02) + ram_data[BIOLOID_TXD_LED_CNTRL]&=0xFD; + else + ram_data[BIOLOID_TXD_LED_CNTRL]|=0x02; + } + else + { + if(data[BIOLOID_TXD_LED_CNTRL-address]&GPIO_VALUE) + { + gpio_set_led(TXD_LED); + ram_data[BIOLOID_TXD_LED_CNTRL]|=0x02; + } + else + { + gpio_clear_led(TXD_LED); + ram_data[BIOLOID_TXD_LED_CNTRL]&=0xFD; + } + } + } + } + } + /* pushbuttons */ + if(ram_in_range(BIOLOID_RESET_PB_CNTRL,address,length)) + { + if(!ram_data[BIOLOID_RESET_PB_CNTRL]&GPIO_INT_USED)/* GPIO is not internally used */ + { + if(data[BIOLOID_RESET_PB_CNTRL-address]&GPIO_INT_EN) + { + } + } + } +} diff --git a/src/ram.c b/src/ram.c index 0bdd49976e589d126604cae8c42e207f25854b58..5d4eb01c505425ac43254b0cd2e736212e34c7de 100644 --- a/src/ram.c +++ b/src/ram.c @@ -1,11 +1,14 @@ #include "ram.h" +#include "eeprom.h" uint8_t ram_data[RAM_SIZE]; void ram_init(void) { - uint16_t eeprom_data; + uint16_t eeprom_data,i; + for(i=0;i<RAM_SIZE;i++) + ram_data[i]=0x00; // read contents from EEPROM to RAM if(EE_ReadVariable(DEVICE_MODEL_OFFSET,&eeprom_data)==0) ram_data[DEVICE_MODEL_OFFSET]=(uint8_t)(eeprom_data&0x00FF); @@ -19,10 +22,6 @@ void ram_init(void) ram_data[BAUDRATE_OFFSET]=(uint8_t)eeprom_data; if(EE_ReadVariable(RETURN_DELAY_OFFSET,&eeprom_data)==0) ram_data[RETURN_DELAY_OFFSET]=(uint8_t)eeprom_data; - if(EE_ReadVariable(MM_PERIOD_OFFSET,&eeprom_data)==0) - ram_data[MM_PERIOD_OFFSET]=(uint8_t)eeprom_data; - if(EE_ReadVariable(MM_PERIOD_OFFSET+1,&eeprom_data)==0) - ram_data[MM_PERIOD_OFFSET+1]=(uint8_t)eeprom_data; if(EE_ReadVariable(RETURN_LEVEL_OFFSET,&eeprom_data)==0) ram_data[RETURN_LEVEL_OFFSET]=(uint8_t)eeprom_data; } @@ -108,11 +107,19 @@ uint8_t ram_write_table(uint8_t address, uint8_t length,uint8_t *data) return RAM_BAD_ADDRESS; } -inline uint8_t ram_in_range(uint8_t start_reg,uint8_t end_reg,uint8_t address,uint8_t length) +inline uint8_t ram_in_range(uint8_t reg,uint8_t address,uint8_t length) { - if(start_reg>=address && end_reg<(address+length)) + if(reg>=address && reg<(address+length)) return 0x01; else return 0x00; } +inline uint8_t ram_in_window(uint8_t start_reg,uint8_t reg_length,uint8_t start_address,uint8_t address_length) +{ + if((start_reg>=start_address && start_reg<(start_address+address_length)) || + ((start_reg+reg_length)>=start_address && (start_reg+reg_length)<(start_address+address_length))) + return 0x01; + else + return 0x00; +}