diff --git a/Makefile b/Makefile index bb0fa5f9cc1cd754f5716e5ba69777ee29fd331d..507160c724f5490fac05ecbe34ff907f6b92995b 100755 --- a/Makefile +++ b/Makefile @@ -4,8 +4,13 @@ PROJECT_NAME=darwin_firmware #TARGET_FILES=$(wildcard src/*.c) TARGET_FILES=src/cm730_fw.c +TARGET_FILES+=src/system_stm32f1xx.c TARGET_FILES+=src/gpio.c TARGET_FILES+=src/ram.c +TARGET_FILES+=src/time.c +TARGET_FILES+=src/eeprom.c +TARGET_FILES+=src/comm.c +TARGET_FILES+=src/dynamixel_slave_uart_dma.c TARGET_FILES+=src/stm32f1xx_hal_msp.c TARGET_PROCESSOR=STM32F103RE @@ -15,12 +20,13 @@ include $(HAL_PATH)/select_processor.mk STM32_STARTUP_FILES_PATH = $(HAL_PATH)/startup_code/ STM32_LINKER_SCRIPTS_PATH = ./linker_script +DYNAMIXEL_LIBRARY_PATH=../../STM32_processor/libraries/dynamixel_base BUILD_PATH=build COMPILE_OPTS = -mlittle-endian -mcpu=cortex-m3 -mthumb -mthumb-interwork -COMPILE_OPTS += -Wall -g -O2 -fno-common -msoft-float +COMPILE_OPTS += -Wall -O2 -fno-common -msoft-float COMPILE_OPTS += -ffreestanding -nostdlib -D$(PROCESSOR_MACRO) -INCLUDE_DIRS = -I$(HAL_PATH)/include -I$(HAL_PATH)/include/core -I$(HAL_PATH)/include/devices -I./include +INCLUDE_DIRS = -I$(HAL_PATH)/include -I$(HAL_PATH)/include/core -I$(HAL_PATH)/include/devices -I$(DYNAMIXEL_LIBRARY_PATH)/include -I./include TCHAIN_PREFIX=arm-none-eabi- @@ -45,7 +51,6 @@ MAIN_OUT_BIN = $(BUILD_PATH)/$(PROJECT_NAME).bin MAIN_OUT_LSS = $(BUILD_PATH)/$(PROJECT_NAME).lss # add STM32 src files -TARGET_FILES+=$(HAL_PATH)/src/devices/system_stm32f1xx.c TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_gpio.c TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_cortex.c TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_rcc.c @@ -53,6 +58,7 @@ TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_pwr.c TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_tim.c TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_tim_ex.c TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_dma.c +TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_uart.c TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_flash.c TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal_flash_ex.c TARGET_FILES+=$(HAL_PATH)/src/stm32f1xx_hal.c @@ -73,7 +79,7 @@ $(BUILD_PATH)/%.o: $(HAL_PATH)/src/%.c $(CC) -c $(CFLAGS) -o $@ $< $(MAIN_OUT_ELF): mkdir_build $(DARWIN_OBJS) $(BUID_PATH)/$(STARTUP_FILE:.s=.o) - $(LD) $(LDFLAGS) $(DARWIN_OBJS) $(BUILD_PATH)/$(STARTUP_FILE:.s=.o) --output $@ + $(LD) $(LDFLAGS) $(DARWIN_OBJS) $(BUILD_PATH)/$(STARTUP_FILE:.s=.o) $(DYNAMIXEL_LIBRARY_PATH)/lib/dynamixel_soft.a --output $@ $(MAIN_OUT_HEX): $(MAIN_OUT_ELF) $(OBJCP) $(OBJCPFLAGS_HEX) $< $@ diff --git a/include/comm.h b/include/comm.h index c5e404e9005fd2c665384daab6bcfb129c862a87..cb2d4e6c3d5d0c8fea722384ea6576652641d9fc 100644 --- a/include/comm.h +++ b/include/comm.h @@ -1,7 +1,7 @@ #ifndef _COMM_H #define _COMM_H -#include "stm32f10x.h" +#include "stm32f1xx_hal.h" // public functions void comm_init(void); diff --git a/include/dynamixel_slave_uart_dma.h b/include/dynamixel_slave_uart_dma.h index 88b0a66f62b065cb3d223c444eece4df1afcefd7..58dc177a8437339e8636f99a67d744ad0f4d42f3 100755 --- a/include/dynamixel_slave_uart_dma.h +++ b/include/dynamixel_slave_uart_dma.h @@ -2,7 +2,7 @@ #define _DYNAXIXEL_SLAVE_UART_DMA_H #include "dynamixel.h" -#include "stm32f10x.h" +#include "stm32f1xx_hal.h" // public functions void dyn_slave_init(void); diff --git a/include/eeprom.h b/include/eeprom.h index f24837912dbf5b76e1d83d7e9dffdb5908d3a9b8..b58e7c9a25826b79f99ac01161b001791d44cd66 100755 --- a/include/eeprom.h +++ b/include/eeprom.h @@ -2,21 +2,37 @@ ****************************************************************************** * @file EEPROM_Emulation/inc/eeprom.h * @author MCD Application Team - * @version V1.0.0 - * @date 10-October-2011 + * @version V1.0.0 + * @date 17-December-2014 * @brief This file contains all the functions prototypes for the EEPROM * emulation firmware library. ****************************************************************************** * @attention * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * 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 STMicroelectronics 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. * - * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> ****************************************************************************** */ @@ -25,27 +41,23 @@ #define __EEPROM_H /* Includes ------------------------------------------------------------------*/ -#include "stm32f1xx.h" +#include "stm32f1xx_hal.h" /* Exported constants --------------------------------------------------------*/ /* Define the size of the sectors to be used */ -#define PAGE_SIZE (uint32_t)0x0800 /* Page size = 2KByte */ - -/* Device voltage range supposed to be [2.7V to 3.6V], the operation will - be done by word */ -#define VOLTAGE_RANGE (uint8_t)VoltageRange_3 +#define PAGE_SIZE (uint32_t)FLASH_PAGE_SIZE /* Page size */ /* EEPROM start address in Flash */ -#define EEPROM_START_ADDRESS ((uint32_t)0x08003800) /* EEPROM emulation start address: - from sector2 : after 16KByte of used - Flash memory */ +#define EEPROM_START_ADDRESS ((uint32_t)0x08003800) /* EEPROM emulation start address */ /* Pages 0 and 1 base and end addresses */ #define PAGE0_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x0000)) #define PAGE0_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1))) +#define PAGE0_ID 0x08003800 #define PAGE1_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x0800)) -#define PAGE1_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (2 * PAGE_SIZE - 1))) +#define PAGE1_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 2*PAGE_SIZE - 1)) +#define PAGE1_ID 0x08004000 /* Used Flash pages for EEPROM emulation */ #define PAGE0 ((uint16_t)0x0000) @@ -77,6 +89,9 @@ #define LAST_EEPROM_OFFSET ((uint16_t)0x0017) +/* Variables' number */ +#define NB_OF_VAR ((uint8_t)0x03) + /* Exported types ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ @@ -86,4 +101,4 @@ uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data); #endif /* __EEPROM_H */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/include/stm32f1xx_hal_conf.h b/include/stm32f1xx_hal_conf.h index 4f2e8cfa12169afb99c46d2fe9f6daf6f9a0fe0d..15a6ba69c3a23578bc51d149aa69bf253d0b5159 100755 --- a/include/stm32f1xx_hal_conf.h +++ b/include/stm32f1xx_hal_conf.h @@ -80,7 +80,7 @@ //#define HAL_SPI_MODULE_ENABLED //#define HAL_SRAM_MODULE_ENABLED #define HAL_TIM_MODULE_ENABLED -//#define HAL_UART_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED //#define HAL_USART_MODULE_ENABLED //#define HAL_WWDG_MODULE_ENABLED diff --git a/include/time.h b/include/time.h index b9bd3579c9bfa7fdcc55be122f7cfeb9bd01b4b4..3e495e8a3f3584f6373b5855269940c225ceac9a 100755 --- a/include/time.h +++ b/include/time.h @@ -1,11 +1,9 @@ #ifndef _TIME_H #define _TIME_H -#include "stm32f10x.h" -#include "system_stm32f10x.h" +#include "stm32f1xx_hal.h" void time_init(void); -void delay_ms(__IO uint32_t time); void delay_us(uint32_t us); #endif diff --git a/src/cm730_fw.c b/src/cm730_fw.c index 7221b7666fec488ddb9d3447e17c5333eeb36d44..706a3921fe78a6c6aac8d72faf546f777297060c 100755 --- a/src/cm730_fw.c +++ b/src/cm730_fw.c @@ -1,45 +1,34 @@ #include "stm32f1xx_hal.h" #include "gpio.h" -//#include "time.h" -//#include "eeprom.h" +#include "time.h" +#include "eeprom.h" +#include "ram.h" +#include "comm.h" +#include "dynamixel_slave_uart_dma.h" //#include "motion_manager.h" //#include "action.h" //#include "walking.h" //#include "joint_motion.h" //#include "head_tracking.h" //#include "grippers.h" -//#include "dynamixel_slave_uart_dma.h" //#include "dynamixel_master_uart_dma.h" -//#include "ram.h" //#include "imu.h" //#include "adc_dma.h" -//#include "comm.h" //#include <math.h> +void SysTick_Handler(void) +{ + HAL_IncTick(); +} + int main(void) { -// uint16_t eeprom_data; + uint16_t eeprom_data; // uint16_t period,count=0; - /* initialize EEPROM */ -// EE_Init(); - // initialize the Dynamixel RAM memory space -// ram_init(); - /* initialize the 1ms system timer */ -// time_init(); - /* initialize the gpio */ -// gpio_init(); /* initialize the dynamixel master interface */ // dyn_master_init(); // dyn_master_set_timeout(50); - /* initialize the dynamixel slave interface*/ -// dyn_slave_init(); -// EE_ReadVariable(DEVICE_ID_OFFSET,&eeprom_data); -// dyn_slave_set_address((uint8_t)eeprom_data); -// EE_ReadVariable(RETURN_DELAY_OFFSET,&eeprom_data); -// dyn_slave_set_return_delay((uint8_t)eeprom_data); -// EE_ReadVariable(RETURN_LEVEL_OFFSET,&eeprom_data); -// dyn_slave_set_return_level((uint8_t)eeprom_data); // initialize motion manager // EE_ReadVariable(MM_PERIOD_OFFSET,&eeprom_data); // period=eeprom_data&0x00FF; @@ -51,20 +40,35 @@ int main(void) // imu_init(); // initialize adc // adc_init(); -// gpio_blink_led(LED_5_R,1000); -// comm_init(); // dyn_master_enable_power(); // delay_ms(1000); -// comm_start(); - /* initialize the HAL module */ +// /* initialize the HAL module */ HAL_Init(); /* initialize the GPIO module */ gpio_init(); + /* initialize the us delay module */ + time_init(); + /* initialize EEPROM */ + EE_Init(); + // initialize the Dynamixel RAM memory space + ram_init(); + /* initialize the dynamixel slave interface*/ + dyn_slave_init(); + EE_ReadVariable(DEVICE_ID_OFFSET,&eeprom_data); + dyn_slave_set_address((uint8_t)eeprom_data); + EE_ReadVariable(RETURN_DELAY_OFFSET,&eeprom_data); + dyn_slave_set_return_delay((uint8_t)eeprom_data); + EE_ReadVariable(RETURN_LEVEL_OFFSET,&eeprom_data); + dyn_slave_set_return_level((uint8_t)eeprom_data); + // initlaize the communication module + comm_init(); + + gpio_blink_led(LED_5_R,1000); - gpio_blink_led(LED_2,1000); + comm_start(); while(1); /* main function does not return */ } diff --git a/src/comm.c b/src/comm.c index 1e685accb99faf4c3722fe72d132d8b25295df7c..0d0431ae5bd5c7ead5ca61a7e966b3e16966fa84 100644 --- a/src/comm.c +++ b/src/comm.c @@ -1,21 +1,21 @@ #include "comm.h" #include "gpio.h" #include "ram.h" -#include "motion_manager.h" -#include "action.h" -#include "walking.h" -#include "joint_motion.h" -#include "head_tracking.h" -#include "grippers.h" +//#include "motion_manager.h" +//#include "action.h" +//#include "walking.h" +//#include "joint_motion.h" +//#include "head_tracking.h" +//#include "grippers.h" #include "dynamixel_slave_uart_dma.h" -#include "dynamixel_master_uart_dma.h" -#include "imu.h" -#include "adc_dma.h" +//#include "dynamixel_master_uart_dma.h" +//#include "imu.h" +//#include "adc_dma.h" #define COMM_TIMER TIM7 #define COMM_TIMER_IRQn TIM7_IRQn #define COMM_TIMER_IRQHandler TIM7_IRQHandler -#define COMM_TIMER_CLK RCC_APB1Periph_TIM7 +#define COMM_TIMER_ENABLE_CLK __HAL_RCC_TIM7_CLK_ENABLE() // private variables uint8_t inst_packet[MAX_DATA_LENGTH]; @@ -24,6 +24,8 @@ uint8_t data[MAX_DATA_LENGTH]; // registered write operation variables uint8_t reg_data[MAX_DATA_LENGTH]; uint8_t reg_address,reg_length,reg_op; +// Timer handle +TIM_HandleTypeDef COMM_TIMHandle; // private functions uint8_t read_operation(uint8_t address, uint8_t length, uint8_t *data) @@ -46,7 +48,7 @@ uint8_t write_operation(uint8_t address,uint8_t length, uint8_t *data) uint16_t word_value; // pre-write operation - if(ram_in_range(DARWIN_DXL_POWER,DARWIN_DXL_POWER,address,length)) +/* if(ram_in_range(DARWIN_DXL_POWER,DARWIN_DXL_POWER,address,length)) { if(data[DARWIN_DXL_POWER-address]&0x01) dyn_master_enable_power(); else dyn_master_disable_power(); @@ -207,7 +209,7 @@ uint8_t write_operation(uint8_t address,uint8_t length, uint8_t *data) grippers_open(RIGHT_GRIPPER); else if(data[DARWIN_GRIPPER_CONTROL-address]&0x08) grippers_close(RIGHT_GRIPPER); - } + }*/ // write eeprom for(i=address,j=0;i<LAST_EEPROM_OFFSET && i<(address+length);i++,j++) EE_WriteVariable(i,data[j]); @@ -223,108 +225,114 @@ void COMM_TIMER_IRQHandler(void) { uint8_t error,length,prev_id,id; - TIM_ClearITPendingBit(COMM_TIMER,TIM_IT_Update); - if(dyn_slave_is_packet_ready())// check if a new instruction packet has been received + if(__HAL_TIM_GET_FLAG(&COMM_TIMHandle, TIM_FLAG_UPDATE) != RESET) { - dyn_slave_get_inst_packet(inst_packet);// get the received packet - // check address - id=dyn_get_id(inst_packet); - if(id==dyn_slave_get_address() || id==DYN_BROADCAST_ID)// the packet is addressed to this device or it is a broadcast - { - // check the packet checksum - if(dyn_check_checksum(inst_packet)==0xFF)// the incomming packet is okay - { - // process the packet - switch(dyn_get_instruction(inst_packet)) - { - case DYN_PING: if(id!=DYN_BROADCAST_ID) - dyn_slave_send_status_packet(DYN_NO_ERROR,0,data); - break; - case DYN_READ: error=read_operation(dyn_get_read_address(inst_packet),dyn_get_read_length(inst_packet),data); - if(dyn_slave_get_return_level()!=0 && id!=DYN_BROADCAST_ID) - { - if(error==RAM_SUCCESS) - dyn_slave_send_status_packet(DYN_NO_ERROR,dyn_get_read_length(inst_packet),data); - else - dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); - } - break; - case DYN_WRITE: length=dyn_get_write_data(inst_packet,data); - error=write_operation(dyn_get_write_address(inst_packet),length,data); - if(dyn_slave_get_return_level()==2 && id!=DYN_BROADCAST_ID) - { - if(error==RAM_SUCCESS) - dyn_slave_send_status_packet(DYN_NO_ERROR,0,data); - else - dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); - } - break; - case DYN_REG_WRITE: reg_length=dyn_get_reg_write_data(inst_packet,reg_data); - reg_address=dyn_get_reg_write_address(inst_packet); - reg_op=0x01;// signal there is a registered operation pending - if(dyn_slave_get_return_level()==2 && id!=DYN_BROADCAST_ID) - dyn_slave_send_status_packet(DYN_NO_ERROR,0,data); - break; - case DYN_ACTION: if(reg_op) - { - error=write_operation(reg_address,reg_length,reg_data); - reg_op=0x00; - } - break; - case DYN_RESET: - break; - case DYN_SYNC_READ: dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); - break; - case DYN_SYNC_WRITE: if(dyn_sync_write_id_present(inst_packet,dyn_slave_get_address()))// the device is addressed - { - length=dyn_get_sync_write_data(inst_packet,dyn_slave_get_address(),data); - error=write_operation(dyn_get_sync_write_address(inst_packet),length,data); - } - break; - case DYN_BULK_READ: if(dyn_bulk_read_id_present(inst_packet,dyn_slave_get_address(),&prev_id)) - { - length=dyn_get_bulk_read_length(inst_packet,dyn_slave_get_address()); - error=read_operation(dyn_get_bulk_read_address(inst_packet,dyn_slave_get_address()),length,data); - if(prev_id==0xFF)// first device in the bulk read sequence - { - if(error==RAM_SUCCESS) - dyn_slave_send_status_packet(DYN_NO_ERROR,length,data); - else - dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); - } - else// wait for the previous device in the sequence to send its data - { - do{ - while(!dyn_slave_is_packet_ready());// wait until a new packet is received - dyn_slave_get_inst_packet(inst_packet); - }while(dyn_get_id(inst_packet)!=prev_id); - if(error==RAM_SUCCESS) - dyn_slave_send_status_packet(DYN_NO_ERROR,length,data); - else - dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); - } - } - break; - case DYN_BULK_WRITE: dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); - break; - default: - break; - } - } - else - { - // send a checksum error answer - if(dyn_get_id(inst_packet)!=DYN_BROADCAST_ID) - dyn_slave_send_status_packet(DYN_CHECKSUM_ERROR,0,0x00); - } - } - else// the packet is addressed to another device + if(__HAL_TIM_GET_IT_SOURCE(&COMM_TIMHandle, TIM_IT_UPDATE) !=RESET) { - // send the incomming packet to the dynamixel bus - if(dyn_master_resend_inst_packet(inst_packet,status_packet)!=DYN_TIMEOUT) + __HAL_TIM_CLEAR_IT(&COMM_TIMHandle, TIM_IT_UPDATE); + if(dyn_slave_is_packet_ready())// check if a new instruction packet has been received { - // send the answer back to the computer - dyn_slave_resend_status_packet(status_packet); + dyn_slave_get_inst_packet(inst_packet);// get the received packet + // check address + id=dyn_get_id(inst_packet); + if(id==dyn_slave_get_address() || id==DYN_BROADCAST_ID)// the packet is addressed to this device or it is a broadcast + { + // check the packet checksum + if(dyn_check_checksum(inst_packet)==0xFF)// the incomming packet is okay + { + // process the packet + switch(dyn_get_instruction(inst_packet)) + { + case DYN_PING: if(id!=DYN_BROADCAST_ID) + dyn_slave_send_status_packet(DYN_NO_ERROR,0,data); + break; + case DYN_READ: error=read_operation(dyn_get_read_address(inst_packet),dyn_get_read_length(inst_packet),data); + if(dyn_slave_get_return_level()!=0 && id!=DYN_BROADCAST_ID) + { + if(error==RAM_SUCCESS) + dyn_slave_send_status_packet(DYN_NO_ERROR,dyn_get_read_length(inst_packet),data); + else + dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); + } + break; + case DYN_WRITE: length=dyn_get_write_data(inst_packet,data); + error=write_operation(dyn_get_write_address(inst_packet),length,data); + if(dyn_slave_get_return_level()==2 && id!=DYN_BROADCAST_ID) + { + if(error==RAM_SUCCESS) + dyn_slave_send_status_packet(DYN_NO_ERROR,0,data); + else + dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); + } + break; + case DYN_REG_WRITE: reg_length=dyn_get_reg_write_data(inst_packet,reg_data); + reg_address=dyn_get_reg_write_address(inst_packet); + reg_op=0x01;// signal there is a registered operation pending + if(dyn_slave_get_return_level()==2 && id!=DYN_BROADCAST_ID) + dyn_slave_send_status_packet(DYN_NO_ERROR,0,data); + break; + case DYN_ACTION: if(reg_op) + { + error=write_operation(reg_address,reg_length,reg_data); + reg_op=0x00; + } + break; + case DYN_RESET: + break; + case DYN_SYNC_READ: dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); + break; + case DYN_SYNC_WRITE: if(dyn_sync_write_id_present(inst_packet,dyn_slave_get_address()))// the device is addressed + { + length=dyn_get_sync_write_data(inst_packet,dyn_slave_get_address(),data); + error=write_operation(dyn_get_sync_write_address(inst_packet),length,data); + } + break; + case DYN_BULK_READ: if(dyn_bulk_read_id_present(inst_packet,dyn_slave_get_address(),&prev_id)) + { + length=dyn_get_bulk_read_length(inst_packet,dyn_slave_get_address()); + error=read_operation(dyn_get_bulk_read_address(inst_packet,dyn_slave_get_address()),length,data); + if(prev_id==0xFF)// first device in the bulk read sequence + { + if(error==RAM_SUCCESS) + dyn_slave_send_status_packet(DYN_NO_ERROR,length,data); + else + dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); + } + else// wait for the previous device in the sequence to send its data + { + do{ + while(!dyn_slave_is_packet_ready());// wait until a new packet is received + dyn_slave_get_inst_packet(inst_packet); + }while(dyn_get_id(inst_packet)!=prev_id); + if(error==RAM_SUCCESS) + dyn_slave_send_status_packet(DYN_NO_ERROR,length,data); + else + dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); + } + } + break; + case DYN_BULK_WRITE: dyn_slave_send_status_packet(DYN_INST_ERROR,0,data); + break; + default: + break; + } + } + else + { + // send a checksum error answer + if(dyn_get_id(inst_packet)!=DYN_BROADCAST_ID) + dyn_slave_send_status_packet(DYN_CHECKSUM_ERROR,0,0x00); + } + } + else// the packet is addressed to another device + { + // send the incomming packet to the dynamixel bus +/* if(dyn_master_resend_inst_packet(inst_packet,status_packet)!=DYN_TIMEOUT) + { + // send the answer back to the computer + dyn_slave_resend_status_packet(status_packet); + }*/ + } } } } @@ -333,22 +341,16 @@ void COMM_TIMER_IRQHandler(void) // public functions void comm_init(void) { - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - NVIC_InitTypeDef NVIC_InitStructure; - - RCC_APB1PeriphClockCmd(COMM_TIMER_CLK,ENABLE); - - TIM_TimeBaseStructure.TIM_Period = 1000; - TIM_TimeBaseStructure.TIM_Prescaler = 72; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(COMM_TIMER,&TIM_TimeBaseStructure); - - NVIC_InitStructure.NVIC_IRQChannel = COMM_TIMER_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + COMM_TIMHandle.Instance=COMM_TIMER; + COMM_TIMHandle.Init.Period = 1000; + COMM_TIMHandle.Init.Prescaler = 72; + COMM_TIMHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + COMM_TIMHandle.Init.CounterMode = TIM_COUNTERMODE_UP; + HAL_TIM_Base_Init(&COMM_TIMHandle); + COMM_TIMER_ENABLE_CLK; + // initialize the timer interrupts + HAL_NVIC_SetPriority(COMM_TIMER_IRQn, 2, 0); + HAL_NVIC_EnableIRQ(COMM_TIMER_IRQn); /* initialize variables */ reg_op=0x00; @@ -356,7 +358,6 @@ void comm_init(void) void comm_start(void) { - TIM_Cmd(COMM_TIMER, ENABLE); - TIM_ITConfig(COMM_TIMER, TIM_IT_Update, ENABLE); + HAL_TIM_Base_Start_IT(&COMM_TIMHandle); } diff --git a/src/dynamixel_slave_uart_dma.c b/src/dynamixel_slave_uart_dma.c index ce0e4aa7513273c91c6726732606a684b5fa5245..e4050ab9b2b39871f96c032ea31b2916973ec218 100755 --- a/src/dynamixel_slave_uart_dma.c +++ b/src/dynamixel_slave_uart_dma.c @@ -2,37 +2,24 @@ #include "gpio.h" #define DYN_SLAVE USART3 -#define DYN_SLAVE_CLK RCC_APB1Periph_USART3 -#define DYN_SLAVE_CLK_INIT RCC_APB1PeriphClockCmd +#define DYN_SLAVE_ENABLE_CLK __HAL_RCC_USART3_CLK_ENABLE() #define DYN_SLAVE_IRQn USART3_IRQn #define DYN_SLAVE_IRQHandler USART3_IRQHandler -#define DYN_SLAVE_TX_PIN GPIO_Pin_10 +#define DYN_SLAVE_TX_PIN GPIO_PIN_10 #define DYN_SLAVE_TX_GPIO_PORT GPIOB -#define DYN_SLAVE_TX_GPIO_CLK RCC_APB2Periph_GPIOB -#define DYN_SLAVE_TX_SOURCE GPIO_PinSource10 +#define DYN_SLAVE_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOB_CLK_ENABLE() -#define DYN_SLAVE_RX_PIN GPIO_Pin_11 +#define DYN_SLAVE_RX_PIN GPIO_PIN_11 #define DYN_SLAVE_RX_GPIO_PORT GPIOB -#define DYN_SLAVE_RX_GPIO_CLK RCC_APB2Periph_GPIOB -#define DYN_SLAVE_RX_SOURCE GPIO_PinSource11 +#define DYN_SLAVE_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOB_CLK_ENABLE() /* DMA configuration */ -#define DYN_SLAVE_DR_ADDRESS ((uint32_t)USART3 + 0x04) #define DYN_SLAVE_DMA DMA1 -#define DYN_SLAVE_DMA_CLK RCC_AHBPeriph_DMA1 +#define DYN_SLAVE_ENABLE_DMA_CLK __HAL_RCC_DMA1_CLK_ENABLE() #define DYN_SLAVE_TX_DMA_CHANNEL DMA1_Channel2 -#define DYN_SLAVE_TX_DMA_FLAG_GLIF DMA1_FLAG_GL2 -#define DYN_SLAVE_TX_DMA_FLAG_TEIF DMA1_FLAG_TE2 -#define DYN_SLAVE_TX_DMA_FLAG_HTIF DMA1_FLAG_HT2 -#define DYN_SLAVE_TX_DMA_FLAG_TCIF DMA1_FLAG_TC2 - #define DYN_SLAVE_RX_DMA_CHANNEL DMA1_Channel3 -#define DYN_SLAVE_RX_DMA_FLAG_GLIF DMA1_FLAG_GL3 -#define DYN_SLAVE_RX_DMA_FLAG_TEIF DMA1_FLAG_TE3 -#define DYN_SLAVE_RX_DMA_FLAG_HTIF DMA1_FLAG_HT3 -#define DYN_SLAVE_RX_DMA_FLAG_TCIF DMA1_FLAG_TC3 #define DYN_SLAVE_DMA_TX_IRQn DMA1_Channel2_IRQn #define DYN_SLAVE_DMA_RX_IRQn DMA1_Channel3_IRQn @@ -52,9 +39,10 @@ uint8_t dyn_slave_tx_buffer[MAX_BUFFER_LEN]; volatile uint8_t dyn_slave_packet_ready; // sending status packet flag volatile uint8_t dyn_slave_sending_packet; -// DMA initialization data structures -DMA_InitTypeDef DYN_SLAVE_DMA_TX_InitStructure; -DMA_InitTypeDef DYN_SLAVE_DMA_RX_InitStructure; +// usart communication device handler +UART_HandleTypeDef UartHandle; +DMA_HandleTypeDef hdma_tx; +DMA_HandleTypeDef hdma_rx; // private functions @@ -64,68 +52,126 @@ void DYN_SLAVE_IRQHandler(void) static uint8_t num_bytes=0; uint8_t data; - if(USART_GetITStatus(DYN_SLAVE, USART_IT_RXNE) != RESET) + if(__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) { - USART_ClearFlag(DYN_SLAVE,USART_FLAG_RXNE); - data=USART_ReceiveData(DYN_SLAVE); - switch(num_bytes) + if(__HAL_UART_GET_IT_SOURCE(&UartHandle, UART_IT_RXNE) !=RESET) { - case 0: if(data==0xFF) - { - dyn_slave_rx_buffer[num_bytes]=data; - num_bytes++; - } - break; - case 1: if(data==0xFF) - { - dyn_slave_rx_buffer[num_bytes]=data; - num_bytes++; - } - else num_bytes--; - break; - case 2: if(data!=0xFF) - { - dyn_slave_rx_buffer[num_bytes]=data; - num_bytes++; - } - break; - case 3: dyn_slave_rx_buffer[num_bytes]=data; - num_bytes=0; - /* disable USART RX interrupts */ - USART_ITConfig(DYN_SLAVE,USART_IT_RXNE,DISABLE); - /* enable DMA RX */ - DMA_SetCurrDataCounter(DYN_SLAVE_RX_DMA_CHANNEL, data); - DMA_Cmd(DYN_SLAVE_RX_DMA_CHANNEL,ENABLE); - USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, ENABLE); - break; - default: break; + __HAL_UART_CLEAR_FLAG(&UartHandle,UART_FLAG_RXNE); + data=(uint8_t)(UartHandle.Instance->DR & (uint8_t)0x00FF); + switch(num_bytes) + { + case 0: if(data==0xFF) + { + dyn_slave_rx_buffer[num_bytes]=data; + num_bytes++; + } + break; + case 1: if(data==0xFF) + { + dyn_slave_rx_buffer[num_bytes]=data; + num_bytes++; + } + else num_bytes--; + break; + case 2: if(data!=0xFF) + { + dyn_slave_rx_buffer[num_bytes]=data; + num_bytes++; + } + break; + case 3: dyn_slave_rx_buffer[num_bytes]=data; + gpio_toggle_led(LED_RX); + num_bytes=0; + // disable USART RX interrupts + __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE); + // enable DMA RX + HAL_DMA_Start_IT(UartHandle.hdmarx,(uint32_t)&UartHandle.Instance->DR,(uint32_t)&dyn_slave_rx_buffer[4],data); + SET_BIT(UartHandle.Instance->CR3, USART_CR3_DMAR); + break; + default: break; + } } } - else if(USART_GetITStatus(DYN_SLAVE, USART_IT_TC) != RESET) + else if(__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) { - USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC); - USART_ITConfig(DYN_SLAVE, USART_IT_TC, DISABLE); - dyn_slave_sending_packet=0x00; + if(__HAL_UART_GET_IT_SOURCE(&UartHandle, UART_IT_TC) !=RESET) + { + gpio_toggle_led(LED_3); + __HAL_UART_CLEAR_FLAG(&UartHandle,UART_FLAG_TC); + __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC); + dyn_slave_sending_packet=0x00; + } } } void DYN_SLAVE_DMA_TX_IRQHandler(void) { - DMA_Cmd(DYN_SLAVE_TX_DMA_CHANNEL,DISABLE); - DMA_ClearFlag(DYN_SLAVE_TX_DMA_FLAG_GLIF); - DMA_ClearITPendingBit(DYN_SLAVE_TX_DMA_FLAG_GLIF); - USART_ITConfig(DYN_SLAVE, USART_IT_TC, ENABLE); + if(__HAL_DMA_GET_FLAG(UartHandle.hdmatx,__HAL_DMA_GET_TC_FLAG_INDEX(UartHandle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(UartHandle.hdmatx, DMA_IT_TC) != RESET) + { + gpio_toggle_led(LED_2); + if((UartHandle.hdmatx->Instance->CCR & DMA_CCR_CIRC) == 0) + { + /* Disable the transfer complete interrupt */ + __HAL_DMA_DISABLE_IT(UartHandle.hdmatx, DMA_IT_TC); + } + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(UartHandle.hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX(UartHandle.hdmatx)); + HAL_UART_DMAStop(&UartHandle); + __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC); + } + } + if(__HAL_DMA_GET_FLAG(UartHandle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(UartHandle.hdmatx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(UartHandle.hdmatx, DMA_IT_HT) != RESET) + { + /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ + if((UartHandle.hdmatx->Instance->CCR & DMA_CCR_CIRC) == 0) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(UartHandle.hdmatx, DMA_IT_HT); + } + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(UartHandle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX(UartHandle.hdmatx)); + } + } } void DYN_SLAVE_DMA_RX_IRQHandler(void) { - DMA_Cmd(DYN_SLAVE_RX_DMA_CHANNEL,DISABLE); - DMA_ClearFlag(DYN_SLAVE_RX_DMA_FLAG_GLIF); - DMA_ClearITPendingBit(DYN_SLAVE_RX_DMA_FLAG_GLIF); - USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, DISABLE); - // enable USART RX interrupt - USART_ITConfig(DYN_SLAVE,USART_IT_RXNE,ENABLE); - dyn_slave_packet_ready=0x01; + gpio_toggle_led(LED_4); + if(__HAL_DMA_GET_FLAG(UartHandle.hdmarx,__HAL_DMA_GET_TC_FLAG_INDEX(UartHandle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(UartHandle.hdmarx, DMA_IT_TC) != RESET) + { + gpio_toggle_led(LED_TX); + if((UartHandle.hdmarx->Instance->CCR & DMA_CCR_CIRC) == 0) + { + /* Disable the transfer complete interrupt */ + __HAL_DMA_DISABLE_IT(UartHandle.hdmarx, DMA_IT_TC); + } + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(UartHandle.hdmarx, __HAL_DMA_GET_TC_FLAG_INDEX(UartHandle.hdmarx)); + HAL_UART_DMAStop(&UartHandle); + __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE); + dyn_slave_packet_ready=0x01; + } + } + if(__HAL_DMA_GET_FLAG(UartHandle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(UartHandle.hdmarx)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(UartHandle.hdmarx, DMA_IT_HT) != RESET) + { + /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ + if((UartHandle.hdmarx->Instance->CCR & DMA_CCR_CIRC) == 0) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(UartHandle.hdmarx, DMA_IT_HT); + } + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(UartHandle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX(UartHandle.hdmarx)); + } + } } // public functions @@ -133,24 +179,23 @@ void dyn_slave_init(void) { uint16_t i; GPIO_InitTypeDef GPIO_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - USART_InitTypeDef USART_InitStructure; /* Enable GPIO clock */ - DYN_SLAVE_CLK_INIT(DYN_SLAVE_CLK, ENABLE); - RCC_APB1PeriphClockCmd(DYN_SLAVE_TX_GPIO_CLK | DYN_SLAVE_RX_GPIO_CLK, ENABLE); + DYN_SLAVE_ENABLE_TX_GPIO_CLK; + DYN_SLAVE_ENABLE_RX_GPIO_CLK; + DYN_SLAVE_ENABLE_DMA_CLK; // configure the GPIO pins /* Configure USART Tx and Rx as alternate function push-pull */ - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Pin = DYN_SLAVE_TX_PIN; - GPIO_Init(DYN_SLAVE_TX_GPIO_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = DYN_SLAVE_TX_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; + HAL_GPIO_Init(DYN_SLAVE_TX_GPIO_PORT, &GPIO_InitStructure); - GPIO_InitStructure.GPIO_Pin = DYN_SLAVE_RX_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(DYN_SLAVE_RX_GPIO_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = DYN_SLAVE_RX_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + HAL_GPIO_Init(DYN_SLAVE_RX_GPIO_PORT, &GPIO_InitStructure); // initialize the buffers for(i=0;i<MAX_BUFFER_LEN;i++) @@ -162,102 +207,59 @@ void dyn_slave_init(void) dyn_slave_packet_ready=0x00; dyn_slave_sending_packet=0x00; - USART_DeInit(DYN_SLAVE); - USART_StructInit(&USART_InitStructure); - // configure the serial port - USART_InitStructure.USART_BaudRate = 921600; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - USART_Init(DYN_SLAVE, &USART_InitStructure); - - NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - /* disable all interrupts of the USART */ - USART_ITConfig(DYN_SLAVE,USART_IT_RXNE | - USART_IT_ORE | - USART_IT_TXE | - USART_IT_CTS | - USART_IT_LBD | - USART_IT_IDLE | - USART_IT_PE | - USART_IT_ERR | - USART_IT_TC, DISABLE); - /* Clear all USART interrupt flags */ - USART_ClearFlag(DYN_SLAVE,USART_FLAG_RXNE | - USART_FLAG_ORE | - USART_FLAG_TXE | - USART_FLAG_CTS | - USART_FLAG_LBD | - USART_FLAG_IDLE | - USART_FLAG_PE | - USART_FLAG_TC); - /* Clear all USART interrupt pending bits */ - USART_ClearITPendingBit(DYN_SLAVE, USART_FLAG_RXNE | - USART_FLAG_ORE | - USART_FLAG_TXE | - USART_FLAG_CTS | - USART_FLAG_LBD | - USART_FLAG_IDLE | - USART_FLAG_PE | - USART_FLAG_TC); - /* Enable the DYN_SLAVE */ - USART_Cmd(DYN_SLAVE, ENABLE); + UartHandle.Instance = DYN_SLAVE; + + UartHandle.Init.BaudRate = 921600; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.Mode = UART_MODE_TX_RX; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; + HAL_UART_Init(&UartHandle); + DYN_SLAVE_ENABLE_CLK; + + HAL_NVIC_SetPriority(DYN_SLAVE_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DYN_SLAVE_IRQn); // configure the DMA channels - /* Configure TX DMA */ - RCC_AHBPeriphClockCmd(DYN_SLAVE_DMA_CLK, ENABLE); - DMA_DeInit(DYN_SLAVE_TX_DMA_CHANNEL); - DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DYN_SLAVE_DMA_TX_InitStructure.DMA_Mode = DMA_Mode_Normal; - DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(DYN_SLAVE->DR)); - DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DYN_SLAVE_DMA_TX_InitStructure.DMA_Priority = DMA_Priority_High; - DYN_SLAVE_DMA_TX_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; - DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryBaseAddr = (uint32_t)dyn_slave_tx_buffer; - DYN_SLAVE_DMA_TX_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_Init(DYN_SLAVE_TX_DMA_CHANNEL,&DYN_SLAVE_DMA_TX_InitStructure); - /* initialize DMA interrupts */ - NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_DMA_TX_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - DMA_ITConfig(DYN_SLAVE_TX_DMA_CHANNEL,DMA_IT_TC,ENABLE); - DMA_ITConfig(DYN_SLAVE_TX_DMA_CHANNEL,DMA_IT_HT | DMA_IT_TE,DISABLE); - - /* Configure RX DMA */ - DMA_DeInit(DYN_SLAVE_RX_DMA_CHANNEL); - DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&dyn_slave_rx_buffer[4]; - DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DYN_SLAVE_DMA_RX_InitStructure.DMA_Mode = DMA_Mode_Normal; - DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(DYN_SLAVE->DR)); - DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DYN_SLAVE_DMA_RX_InitStructure.DMA_Priority = DMA_Priority_High; - DYN_SLAVE_DMA_RX_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; - DYN_SLAVE_DMA_RX_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_Init(DYN_SLAVE_RX_DMA_CHANNEL,&DYN_SLAVE_DMA_RX_InitStructure); - /* initialize DMA interrupts */ - NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_DMA_RX_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - DMA_ITConfig(DYN_SLAVE_RX_DMA_CHANNEL,DMA_IT_TC,ENABLE); - DMA_ITConfig(DYN_SLAVE_RX_DMA_CHANNEL,DMA_IT_HT | DMA_IT_TE,DISABLE); - - /* enable USART RX interrupts */ - USART_ITConfig(DYN_SLAVE,USART_IT_RXNE,ENABLE); + hdma_tx.Instance = DYN_SLAVE_TX_DMA_CHANNEL; + hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_tx.Init.Mode = DMA_NORMAL; + hdma_tx.Init.Priority = DMA_PRIORITY_LOW; + + HAL_DMA_Init(&hdma_tx); + + /* Associate the initialized DMA handle to the UART handle */ + __HAL_LINKDMA(&UartHandle, hdmatx, hdma_tx); + + HAL_NVIC_SetPriority(DYN_SLAVE_DMA_TX_IRQn, 1, 0); + HAL_NVIC_EnableIRQ(DYN_SLAVE_DMA_TX_IRQn); + + /* Configure the DMA handler for reception process */ + hdma_rx.Instance = DYN_SLAVE_RX_DMA_CHANNEL; + hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_rx.Init.Mode = DMA_NORMAL; + hdma_rx.Init.Priority = DMA_PRIORITY_HIGH; + + HAL_DMA_Init(&hdma_rx); + + /* Associate the initialized DMA handle to the the UART handle */ + __HAL_LINKDMA(&UartHandle, hdmarx, hdma_rx); + + HAL_NVIC_SetPriority(DYN_SLAVE_DMA_RX_IRQn, 1, 1); + HAL_NVIC_EnableIRQ(DYN_SLAVE_DMA_RX_IRQn); + + /* enable the rx interrupt */ + __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE); } inline void dyn_slave_set_address(uint8_t id) @@ -306,10 +308,12 @@ void dyn_slave_send_status_packet(uint8_t error,uint8_t length, uint8_t *data) // create the status packet dyn_init_status_packet(dyn_slave_tx_buffer,dyn_slave_address,error,length,data); // set the DMA transfer - DMA_SetCurrDataCounter(DYN_SLAVE_TX_DMA_CHANNEL,dyn_get_length(dyn_slave_tx_buffer)+4); - DMA_Cmd(DYN_SLAVE_TX_DMA_CHANNEL,ENABLE); - USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC); - USART_DMACmd(DYN_SLAVE, USART_DMAReq_Tx, ENABLE); + HAL_DMA_Start_IT(UartHandle.hdmatx,(uint32_t)dyn_slave_tx_buffer,(uint32_t)&UartHandle.Instance->DR,dyn_get_length(dyn_slave_tx_buffer)+4); + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_UART_CLEAR_FLAG(&UartHandle,UART_FLAG_TC); + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the UART CR3 register */ + SET_BIT(UartHandle.Instance->CR3, USART_CR3_DMAT); dyn_slave_sending_packet=0x01; } @@ -320,9 +324,11 @@ void dyn_slave_resend_status_packet(uint8_t *packet) // create the status packet dyn_copy_packet(packet,dyn_slave_tx_buffer); // set the DMA transfer - DMA_SetCurrDataCounter(DYN_SLAVE_TX_DMA_CHANNEL,dyn_get_length(dyn_slave_tx_buffer)+4); - DMA_Cmd(DYN_SLAVE_TX_DMA_CHANNEL,ENABLE); - USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC); - USART_DMACmd(DYN_SLAVE, USART_DMAReq_Tx, ENABLE); + HAL_DMA_Start_IT(UartHandle.hdmatx,(uint32_t)dyn_slave_tx_buffer,(uint32_t)&UartHandle.Instance->DR,dyn_get_length(dyn_slave_tx_buffer)+4); + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_UART_CLEAR_FLAG(&UartHandle,UART_FLAG_TC); + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the UART CR3 register */ + SET_BIT(UartHandle.Instance->CR3, USART_CR3_DMAT); dyn_slave_sending_packet=0x01; } diff --git a/src/eeprom.c b/src/eeprom.c index 0477a437945e2a91869fe6f08d94c81c5c4ec9c9..5af13c96a942abdbc9e13c58cc38b72b017a2da5 100755 --- a/src/eeprom.c +++ b/src/eeprom.c @@ -3,19 +3,35 @@ * @file EEPROM_Emulation/src/eeprom.c * @author MCD Application Team * @version V1.0.0 - * @date 10-October-2011 + * @date 17-December-2014 * @brief This file provides all the EEPROM emulation firmware functions. ****************************************************************************** * @attention * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * 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 STMicroelectronics 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. * - * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> ****************************************************************************** */ @@ -42,7 +58,7 @@ /* Global variable used to store variable value in read sequence */ uint16_t DataVar = 0; -// EEPROM memory map +/* Virtual address defined by the user: 0xFFFF value is prohibited */ uint16_t eeprom_data[] __attribute__ ((section (".eeprom")))={VALID_PAGE, 0xFFFF, DEFAULT_DEVICE_MODEL&0xFF,// model number LSB @@ -66,10 +82,11 @@ uint16_t eeprom_data[] __attribute__ ((section (".eeprom")))={VALID_PAGE, /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ -static FLASH_Status EE_Format(void); +static HAL_StatusTypeDef EE_Format(void); static uint16_t EE_FindValidPage(uint8_t Operation); static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data); static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data); +static uint16_t EE_VerifyPageFullyErased(uint32_t Address); /** * @brief Restore the pages to a known good state in case of page's status @@ -80,208 +97,285 @@ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data); */ uint16_t EE_Init(void) { - uint16_t PageStatus0 = 6, PageStatus1 = 6; - uint16_t VarIdx = 0; - uint16_t EepromStatus = 0, ReadStatus = 0; + uint16_t pagestatus0 = 6, pagestatus1 = 6; + uint16_t varidx = 0; + uint16_t eepromstatus = 0, readstatus = 0; int16_t x = -1; - uint16_t FlashStatus; + HAL_StatusTypeDef flashstatus; + uint32_t page_error = 0; + FLASH_EraseInitTypeDef s_eraseinit; + + /* Unlock the Flash Program Erase controller */ + HAL_FLASH_Unlock(); - FLASH_Unlock(); /* Get Page0 status */ - PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS); + pagestatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS); /* Get Page1 status */ - PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS); + pagestatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS); + /* Fill EraseInit structure*/ + s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; + s_eraseinit.PageAddress = PAGE0_ID; + s_eraseinit.NbPages = 1; + /* Check for invalid header states and repair if necessary */ - switch (PageStatus0) + switch (pagestatus0) { case ERASED: - if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */ + if (pagestatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */ { - /* Erase Page0 */ - FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS); - /* If erase operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + /* Erase Page0 */ + if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) { - return FlashStatus; + flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); + /* If erase operation was failed, a Flash error code is returned */ + if (flashstatus != HAL_OK) + { + return flashstatus; + } } } - else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */ + else if (pagestatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */ { /* Erase Page0 */ - FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS); - /* If erase operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) - { - return FlashStatus; + if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) + { + flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); + /* If erase operation was failed, a Flash error code is returned */ + if (flashstatus != HAL_OK) + { + return flashstatus; + } } /* Mark Page1 as valid */ - FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE); + flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } } else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */ { /* Erase both Page0 and Page1 and set Page0 as valid page */ - FlashStatus = EE_Format(); + flashstatus = EE_Format(); /* If erase/program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } } break; case RECEIVE_DATA: - if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */ + if (pagestatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */ { /* Transfer data from Page1 to Page0 */ - for (VarIdx = 0; VarIdx < EEPROM_SIZE; VarIdx++) + for (varidx = 0; varidx < NB_OF_VAR; varidx++) { - if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == eeprom_data[VarIdx]) + if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == eeprom_data[varidx]) { - x = VarIdx; + x = varidx; } - if (VarIdx != x) + if (varidx != x) { /* Read the last variables' updates */ - ReadStatus = EE_ReadVariable(eeprom_data[VarIdx], &DataVar); + readstatus = EE_ReadVariable(eeprom_data[varidx], &DataVar); /* In case variable corresponding to the virtual address was found */ - if (ReadStatus != 0x1) + if (readstatus != 0x1) { /* Transfer the variable to the Page0 */ - EepromStatus = EE_VerifyPageFullWriteVariable(eeprom_data[VarIdx], DataVar); + eepromstatus = EE_VerifyPageFullWriteVariable(eeprom_data[varidx], DataVar); /* If program operation was failed, a Flash error code is returned */ - if (EepromStatus != FLASH_COMPLETE) + if (eepromstatus != HAL_OK) { - return EepromStatus; + return eepromstatus; } } } } /* Mark Page0 as valid */ - FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE); + flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } + s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; + s_eraseinit.PageAddress = PAGE1_ID; + s_eraseinit.NbPages = 1; /* Erase Page1 */ - FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS); - /* If erase operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) - { - return FlashStatus; + if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) + { + flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); + /* If erase operation was failed, a Flash error code is returned */ + if (flashstatus != HAL_OK) + { + return flashstatus; + } } } - else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */ + else if (pagestatus1 == ERASED) /* Page0 receive, Page1 erased */ { + s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; + s_eraseinit.PageAddress = PAGE1_ID; + s_eraseinit.NbPages = 1; /* Erase Page1 */ - FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS); - /* If erase operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) - { - return FlashStatus; + if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) + { + flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); + /* If erase operation was failed, a Flash error code is returned */ + if (flashstatus != HAL_OK) + { + return flashstatus; + } } /* Mark Page0 as valid */ - FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE); + flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } } else /* Invalid state -> format eeprom */ { /* Erase both Page0 and Page1 and set Page0 as valid page */ - FlashStatus = EE_Format(); + flashstatus = EE_Format(); /* If erase/program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } } break; case VALID_PAGE: - if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */ + if (pagestatus1 == VALID_PAGE) /* Invalid state -> format eeprom */ { /* Erase both Page0 and Page1 and set Page0 as valid page */ - FlashStatus = EE_Format(); + flashstatus = EE_Format(); /* If erase/program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } } - else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */ + else if (pagestatus1 == ERASED) /* Page0 valid, Page1 erased */ { + s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; + s_eraseinit.PageAddress = PAGE1_ID; + s_eraseinit.NbPages = 1; /* Erase Page1 */ - FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS); - /* If erase operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) - { - return FlashStatus; + if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) + { + flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); + /* If erase operation was failed, a Flash error code is returned */ + if (flashstatus != HAL_OK) + { + return flashstatus; + } } } else /* Page0 valid, Page1 receive */ { /* Transfer data from Page0 to Page1 */ - for (VarIdx = 0; VarIdx < EEPROM_SIZE; VarIdx++) + for (varidx = 0; varidx < NB_OF_VAR; varidx++) { - if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == eeprom_data[VarIdx]) + if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == eeprom_data[varidx]) { - x = VarIdx; + x = varidx; } - if (VarIdx != x) + if (varidx != x) { /* Read the last variables' updates */ - ReadStatus = EE_ReadVariable(eeprom_data[VarIdx], &DataVar); + readstatus = EE_ReadVariable(eeprom_data[varidx], &DataVar); /* In case variable corresponding to the virtual address was found */ - if (ReadStatus != 0x1) + if (readstatus != 0x1) { /* Transfer the variable to the Page1 */ - EepromStatus = EE_VerifyPageFullWriteVariable(eeprom_data[VarIdx], DataVar); + eepromstatus = EE_VerifyPageFullWriteVariable(eeprom_data[varidx], DataVar); /* If program operation was failed, a Flash error code is returned */ - if (EepromStatus != FLASH_COMPLETE) + if (eepromstatus != HAL_OK) { - return EepromStatus; + return eepromstatus; } } } } /* Mark Page1 as valid */ - FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE); + flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } + s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; + s_eraseinit.PageAddress = PAGE0_ID; + s_eraseinit.NbPages = 1; /* Erase Page0 */ - FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS); - /* If erase operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) - { - return FlashStatus; + if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) + { + flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); + /* If erase operation was failed, a Flash error code is returned */ + if (flashstatus != HAL_OK) + { + return flashstatus; + } } } break; default: /* Any other state -> format eeprom */ /* Erase both Page0 and Page1 and set Page0 as valid page */ - FlashStatus = EE_Format(); + flashstatus = EE_Format(); /* If erase/program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } break; } - return FLASH_COMPLETE; + return HAL_OK; +} + +/** + * @brief Verify if specified page is fully erased. + * @param Address: page address + * This parameter can be one of the following values: + * @arg PAGE0_BASE_ADDRESS: Page0 base address + * @arg PAGE1_BASE_ADDRESS: Page1 base address + * @retval page fully erased status: + * - 0: if Page not erased + * - 1: if Page erased + */ +uint16_t EE_VerifyPageFullyErased(uint32_t Address) +{ + uint32_t readstatus = 1; + uint16_t addressvalue = 0x5555; + + /* Check each active page address starting from end */ + while (Address <= PAGE0_END_ADDRESS) + { + /* Get the current location content to be compared with virtual address */ + addressvalue = (*(__IO uint16_t*)Address); + + /* Compare the read address with the virtual address */ + if (addressvalue != ERASED) + { + + /* In case variable value is read, reset readstatus flag */ + readstatus = 0; + + break; + } + /* Next address location */ + Address = Address + 4; + } + + /* Return readstatus value: (0: Page not erased, 1: Page erased) */ + return readstatus; } /** @@ -296,51 +390,51 @@ uint16_t EE_Init(void) */ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) { - uint16_t ValidPage = PAGE0; - uint16_t AddressValue = 0x5555, ReadStatus = 1; - uint32_t Address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS; + uint16_t validpage = PAGE0; + uint16_t addressvalue = 0x5555, readstatus = 1; + uint32_t address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS; /* Get active Page for read operation */ - ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE); + validpage = EE_FindValidPage(READ_FROM_VALID_PAGE); /* Check if there is no valid page */ - if (ValidPage == NO_VALID_PAGE) + if (validpage == NO_VALID_PAGE) { return NO_VALID_PAGE; } /* Get the valid Page start Address */ - PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE)); + PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage * PAGE_SIZE)); /* Get the valid Page end Address */ - Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE)); + address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + validpage) * PAGE_SIZE)); /* Check each active page address starting from end */ - while (Address > (PageStartAddress + 2)) + while (address > (PageStartAddress + 2)) { /* Get the current location content to be compared with virtual address */ - AddressValue = (*(__IO uint16_t*)Address); + addressvalue = (*(__IO uint16_t*)address); /* Compare the read address with the virtual address */ - if (AddressValue == VirtAddress) + if (addressvalue == VirtAddress) { /* Get content of Address-2 which is variable value */ - *Data = (*(__IO uint16_t*)(Address - 2)); + *Data = (*(__IO uint16_t*)(address - 2)); - /* In case variable value is read, reset ReadStatus flag */ - ReadStatus = 0; + /* In case variable value is read, reset readstatus flag */ + readstatus = 0; break; } else { /* Next address location */ - Address = Address - 4; + address = address - 4; } } - /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */ - return ReadStatus; + /* Return readstatus value: (0: variable exist, 1: variable doesn't exist) */ + return readstatus; } /** @@ -377,33 +471,46 @@ uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) * @retval Status of the last operation (Flash write or erase) done during * EEPROM formating */ -static FLASH_Status EE_Format(void) +static HAL_StatusTypeDef EE_Format(void) { - FLASH_Status FlashStatus = FLASH_COMPLETE; + HAL_StatusTypeDef flashstatus = HAL_OK; + uint32_t page_error = 0; + FLASH_EraseInitTypeDef s_eraseinit; + s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; + s_eraseinit.PageAddress = PAGE0_ID; + s_eraseinit.NbPages = 1; /* Erase Page0 */ - FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS); - - /* If erase operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) { - return FlashStatus; + flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); + /* If erase operation was failed, a Flash error code is returned */ + if (flashstatus != HAL_OK) + { + return flashstatus; + } } - /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */ - FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE); - + flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } + s_eraseinit.PageAddress = PAGE1_ID; /* Erase Page1 */ - FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS); - - /* Return Page1 erase operation status */ - return FlashStatus; + if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) + { + flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); + /* If erase operation was failed, a Flash error code is returned */ + if (flashstatus != HAL_OK) + { + return flashstatus; + } + } + + return HAL_OK; } /** @@ -417,22 +524,22 @@ static FLASH_Status EE_Format(void) */ static uint16_t EE_FindValidPage(uint8_t Operation) { - uint16_t PageStatus0 = 6, PageStatus1 = 6; + uint16_t pagestatus0 = 6, pagestatus1 = 6; /* Get Page0 actual status */ - PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS); + pagestatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS); /* Get Page1 actual status */ - PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS); + pagestatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS); /* Write or read operation */ switch (Operation) { case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */ - if (PageStatus1 == VALID_PAGE) + if (pagestatus1 == VALID_PAGE) { /* Page0 receiving data */ - if (PageStatus0 == RECEIVE_DATA) + if (pagestatus0 == RECEIVE_DATA) { return PAGE0; /* Page0 valid */ } @@ -441,10 +548,10 @@ static uint16_t EE_FindValidPage(uint8_t Operation) return PAGE1; /* Page1 valid */ } } - else if (PageStatus0 == VALID_PAGE) + else if (pagestatus0 == VALID_PAGE) { /* Page1 receiving data */ - if (PageStatus1 == RECEIVE_DATA) + if (pagestatus1 == RECEIVE_DATA) { return PAGE1; /* Page1 valid */ } @@ -459,11 +566,11 @@ static uint16_t EE_FindValidPage(uint8_t Operation) } case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */ - if (PageStatus0 == VALID_PAGE) + if (pagestatus0 == VALID_PAGE) { return PAGE0; /* Page0 valid */ } - else if (PageStatus1 == VALID_PAGE) + else if (pagestatus1 == VALID_PAGE) { return PAGE1; /* Page1 valid */ } @@ -489,49 +596,50 @@ static uint16_t EE_FindValidPage(uint8_t Operation) */ static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data) { - FLASH_Status FlashStatus = FLASH_COMPLETE; - uint16_t ValidPage = PAGE0; - uint32_t Address = EEPROM_START_ADDRESS, PageEndAddress = EEPROM_START_ADDRESS+PAGE_SIZE; + HAL_StatusTypeDef flashstatus = HAL_OK; + uint16_t validpage = PAGE0; + uint32_t address = EEPROM_START_ADDRESS, pageendaddress = EEPROM_START_ADDRESS+PAGE_SIZE; /* Get valid Page for write operation */ - ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE); - + validpage = EE_FindValidPage(WRITE_IN_VALID_PAGE); + /* Check if there is no valid page */ - if (ValidPage == NO_VALID_PAGE) + if (validpage == NO_VALID_PAGE) { return NO_VALID_PAGE; } - /* Get the valid Page start Address */ - Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE)); + /* Get the valid Page start address */ + address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage * PAGE_SIZE)); - /* Get the valid Page end Address */ - PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE)); + /* Get the valid Page end address */ + pageendaddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((validpage + 1) * PAGE_SIZE)); /* Check each active page address starting from begining */ - while (Address < PageEndAddress) + while (address < pageendaddress) { - /* Verify if Address and Address+2 contents are 0xFFFFFFFF */ - if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF) + /* Verify if address and address+2 contents are 0xFFFFFFFF */ + if ((*(__IO uint32_t*)address) == 0xFFFFFFFF) { /* Set variable data */ - FlashStatus = FLASH_ProgramHalfWord(Address, Data); + flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, Data); /* If program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } /* Set variable virtual address */ - FlashStatus = FLASH_ProgramHalfWord(Address + 2, VirtAddress); + flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address + 2, VirtAddress); /* Return program operation status */ - return FlashStatus; + return flashstatus; } else { /* Next address location */ - Address = Address + 4; + address = address + 4; } } + /* Return PAGE_FULL in case the valid page is full */ return PAGE_FULL; } @@ -549,93 +657,103 @@ static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Da */ static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) { - FLASH_Status FlashStatus = FLASH_COMPLETE; - uint32_t NewPageAddress = EEPROM_START_ADDRESS; - uint32_t OldPageId=0; - uint16_t ValidPage = PAGE0, VarIdx = 0; - uint16_t EepromStatus = 0, ReadStatus = 0; + HAL_StatusTypeDef flashstatus = HAL_OK; + uint32_t newpageaddress = EEPROM_START_ADDRESS; + uint32_t oldpageid = 0; + uint16_t validpage = PAGE0, varidx = 0; + uint16_t eepromstatus = 0, readstatus = 0; + uint32_t page_error = 0; + FLASH_EraseInitTypeDef s_eraseinit; /* Get active Page for read operation */ - ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE); + validpage = EE_FindValidPage(READ_FROM_VALID_PAGE); - if (ValidPage == PAGE1) /* Page1 valid */ + if (validpage == PAGE1) /* Page1 valid */ { /* New page address where variable will be moved to */ - NewPageAddress = PAGE0_BASE_ADDRESS; + newpageaddress = PAGE0_BASE_ADDRESS; /* Old page ID where variable will be taken from */ - OldPageId = PAGE1_BASE_ADDRESS; + oldpageid = PAGE1_ID; } - else if (ValidPage == PAGE0) /* Page0 valid */ + else if (validpage == PAGE0) /* Page0 valid */ { /* New page address where variable will be moved to */ - NewPageAddress = PAGE1_BASE_ADDRESS; + newpageaddress = PAGE1_BASE_ADDRESS; /* Old page ID where variable will be taken from */ - OldPageId = PAGE0_BASE_ADDRESS; + oldpageid = PAGE0_ID; } else { return NO_VALID_PAGE; /* No valid Page */ } + /* Set the new Page status to RECEIVE_DATA status */ - FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA); + flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, RECEIVE_DATA); /* If program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } + /* Write the variable passed as parameter in the new active page */ - EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data); + eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data); /* If program operation was failed, a Flash error code is returned */ - if (EepromStatus != FLASH_COMPLETE) + if (eepromstatus != HAL_OK) { - return EepromStatus; + return eepromstatus; } /* Transfer process: transfer variables from old to the new active page */ - for (VarIdx = 0; VarIdx < EEPROM_SIZE; VarIdx++) + for (varidx = 0; varidx < NB_OF_VAR; varidx++) { - if (eeprom_data[VarIdx] != VirtAddress) /* Check each variable except the one passed as parameter */ + if (eeprom_data[varidx] != VirtAddress) /* Check each variable except the one passed as parameter */ { /* Read the other last variable updates */ - ReadStatus = EE_ReadVariable(eeprom_data[VarIdx], &DataVar); + readstatus = EE_ReadVariable(eeprom_data[varidx], &DataVar); /* In case variable corresponding to the virtual address was found */ - if (ReadStatus != 0x1) + if (readstatus != 0x1) { /* Transfer the variable to the new active page */ - EepromStatus = EE_VerifyPageFullWriteVariable(eeprom_data[VarIdx], DataVar); + eepromstatus = EE_VerifyPageFullWriteVariable(eeprom_data[varidx], DataVar); /* If program operation was failed, a Flash error code is returned */ - if (EepromStatus != FLASH_COMPLETE) + if (eepromstatus != HAL_OK) { - return EepromStatus; + return eepromstatus; } } } } + + s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; + s_eraseinit.PageAddress = oldpageid; + s_eraseinit.NbPages = 1; /* Erase the old Page: Set old Page status to ERASED status */ - FlashStatus = FLASH_ErasePage(OldPageId); + flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error); /* If erase operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } /* Set new Page status to VALID_PAGE status */ - FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE); + flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ - if (FlashStatus != FLASH_COMPLETE) + if (flashstatus != HAL_OK) { - return FlashStatus; + return flashstatus; } - + + + /* Return last operation flash status */ - return FlashStatus; + return flashstatus; } /** * @} */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/gpio.c b/src/gpio.c index c86e0f8cd1724761082d103d8778b34105331685..1297921809283193b266a12b49e07dc2c8a0e48c 100755 --- a/src/gpio.c +++ b/src/gpio.c @@ -94,138 +94,147 @@ void (*mode_pb_callback)(void); // IRQ handler functions void GPI_EXTI1_IRQHandler(void) { - HAL_GPIO_EXTI_IRQHandler(START_PB_PIN); - HAL_GPIO_EXTI_IRQHandler(MODE_PB_PIN); -} - -void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) -{ - if(GPIO_Pin==START_PB_PIN && start_pb_callback!=0) - start_pb_callback(); - - if(GPIO_Pin==MODE_PB_PIN && mode_pb_callback!=0) - mode_pb_callback(); + 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(__HAL_GPIO_EXTI_GET_IT(START_PB_PIN) != RESET) + { + __HAL_GPIO_EXTI_CLEAR_IT(START_PB_PIN); + if(mode_pb_callback!=0) + mode_pb_callback(); + } } void GPO_TIMER1_IRQHandler(void) -{ - HAL_TIM_IRQHandler(&GPO_TIM1Handle); -} - -void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) { uint32_t capture; - if(htim->Instance==GPO_TIMER1) + if(__HAL_TIM_GET_FLAG(&GPO_TIM1Handle, TIM_FLAG_CC1) != RESET) { - if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM1Handle, TIM_IT_CC1) !=RESET) { - capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); - __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, (capture + led_tx_period)); + __HAL_TIM_CLEAR_IT(&GPO_TIM1Handle, TIM_IT_CC1); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM1Handle, TIM_CHANNEL_1); + __HAL_TIM_SET_COMPARE(&GPO_TIM1Handle, TIM_CHANNEL_1, (capture + led_tx_period)); HAL_GPIO_TogglePin(LED_TX_GPIO_PORT,LED_TX_PIN); } - if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) + } + if(__HAL_TIM_GET_FLAG(&GPO_TIM1Handle, TIM_FLAG_CC2) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM1Handle, TIM_IT_CC2) !=RESET) { - capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); - __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_2, (capture + led_rx_period)); - HAL_GPIO_TogglePin(LED_RX_GPIO_PORT,LED_RX_PIN); + __HAL_TIM_CLEAR_IT(&GPO_TIM1Handle, TIM_IT_CC2); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM1Handle, TIM_CHANNEL_2); + __HAL_TIM_SET_COMPARE(&GPO_TIM1Handle, TIM_CHANNEL_2, (capture + led_rx_period)); + HAL_GPIO_TogglePin(LED_RX_GPIO_PORT,LED_RX_PIN); } - if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3) + } + if(__HAL_TIM_GET_FLAG(&GPO_TIM1Handle, TIM_FLAG_CC3) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM1Handle, TIM_IT_CC3) !=RESET) { - capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3); - __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_3, (capture + led_2_period)); - HAL_GPIO_TogglePin(LED_2_GPIO_PORT,LED_2_PIN); + __HAL_TIM_CLEAR_IT(&GPO_TIM1Handle, TIM_IT_CC3); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM1Handle, TIM_CHANNEL_3); + __HAL_TIM_SET_COMPARE(&GPO_TIM1Handle, TIM_CHANNEL_3, (capture + led_2_period)); + HAL_GPIO_TogglePin(LED_2_GPIO_PORT,LED_2_PIN); } - if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) + } + if(__HAL_TIM_GET_FLAG(&GPO_TIM1Handle, TIM_FLAG_CC4) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM1Handle, TIM_IT_CC4) !=RESET) { - capture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4); - __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_4, (capture + led_3_period)); + __HAL_TIM_CLEAR_IT(&GPO_TIM1Handle, TIM_IT_CC4); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM1Handle, TIM_CHANNEL_4); + __HAL_TIM_SET_COMPARE(&GPO_TIM1Handle, TIM_CHANNEL_4, (capture + led_3_period)); HAL_GPIO_TogglePin(LED_3_GPIO_PORT,LED_3_PIN); - } + } } } -/*void GPO_TIMER2_IRQHandler(void) +void GPO_TIMER2_IRQHandler(void) { - uint16_t capture; + uint32_t capture; - if(TIM_GetITStatus(GPO_TIMER2, TIM_IT_CC1)!=RESET) + if(__HAL_TIM_GET_FLAG(&GPO_TIM2Handle, TIM_FLAG_CC1) != RESET) { - TIM_ClearITPendingBit(GPO_TIMER2,TIM_IT_CC1); - if(GPIO_ReadOutputDataBit(LED_5_R_GPIO_PORT,LED_5_R_PIN)) - HAL_GPIO_WritePin(LED_5_R_GPIO_PORT,LED_5_R_PIN); - else - GPIO_SetBits(LED_5_R_GPIO_PORT,LED_5_R_PIN); - capture = TIM_GetCapture1(GPO_TIMER2); - TIM_SetCompare1(GPO_TIMER2, capture + led_5_R_period); + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM2Handle, TIM_IT_CC1) !=RESET) + { + __HAL_TIM_CLEAR_IT(&GPO_TIM2Handle, TIM_IT_CC1); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM2Handle, TIM_CHANNEL_1); + __HAL_TIM_SET_COMPARE(&GPO_TIM2Handle, TIM_CHANNEL_1, (capture + led_5_R_period)); + HAL_GPIO_TogglePin(LED_5_R_GPIO_PORT,LED_5_R_PIN); + } } - if(TIM_GetITStatus(GPO_TIMER2, TIM_IT_CC2)!=RESET) + if(__HAL_TIM_GET_FLAG(&GPO_TIM2Handle, TIM_FLAG_CC2) != RESET) { - TIM_ClearITPendingBit(GPO_TIMER2,TIM_IT_CC2); - if(GPIO_ReadOutputDataBit(LED_5_G_GPIO_PORT,LED_5_G_PIN)) - HAL_GPIO_WritePin(LED_5_G_GPIO_PORT,LED_5_G_PIN); - else - GPIO_SetBits(LED_5_G_GPIO_PORT,LED_5_G_PIN); - capture = TIM_GetCapture2(GPO_TIMER2); - TIM_SetCompare2(GPO_TIMER2, capture + led_5_G_period); + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM2Handle, TIM_IT_CC2) !=RESET) + { + __HAL_TIM_CLEAR_IT(&GPO_TIM2Handle, TIM_IT_CC2); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM2Handle, TIM_CHANNEL_2); + __HAL_TIM_SET_COMPARE(&GPO_TIM2Handle, TIM_CHANNEL_2, (capture + led_5_G_period)); + HAL_GPIO_TogglePin(LED_5_G_GPIO_PORT,LED_5_G_PIN); + } } - if(TIM_GetITStatus(GPO_TIMER2, TIM_IT_CC3)!=RESET) + if(__HAL_TIM_GET_FLAG(&GPO_TIM2Handle, TIM_FLAG_CC3) != RESET) { - TIM_ClearITPendingBit(GPO_TIMER2,TIM_IT_CC3); - if(GPIO_ReadOutputDataBit(LED_5_B_GPIO_PORT,LED_5_B_PIN)) - HAL_GPIO_WritePin(LED_5_B_GPIO_PORT,LED_5_B_PIN); - else - GPIO_SetBits(LED_5_B_GPIO_PORT,LED_5_B_PIN); - capture = TIM_GetCapture3(GPO_TIMER2); - TIM_SetCompare3(GPO_TIMER2, capture + led_5_B_period); + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM2Handle, TIM_IT_CC3) !=RESET) + { + __HAL_TIM_CLEAR_IT(&GPO_TIM2Handle, TIM_IT_CC3); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM2Handle, TIM_CHANNEL_3); + __HAL_TIM_SET_COMPARE(&GPO_TIM2Handle, TIM_CHANNEL_3, (capture + led_5_B_period)); + HAL_GPIO_TogglePin(LED_5_B_GPIO_PORT,LED_5_B_PIN); + } } - if(TIM_GetITStatus(GPO_TIMER2, TIM_IT_CC4)!=RESET) + if(__HAL_TIM_GET_FLAG(&GPO_TIM2Handle, TIM_FLAG_CC4) != RESET) { - TIM_ClearITPendingBit(GPO_TIMER2,TIM_IT_CC4); - if(GPIO_ReadOutputDataBit(LED_4_GPIO_PORT,LED_4_PIN)) - HAL_GPIO_WritePin(LED_4_GPIO_PORT,LED_4_PIN); - else - GPIO_SetBits(LED_4_GPIO_PORT,LED_4_PIN); - capture = TIM_GetCapture4(GPO_TIMER2); - TIM_SetCompare4(GPO_TIMER2, capture + led_4_period); + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM2Handle, TIM_IT_CC4) !=RESET) + { + __HAL_TIM_CLEAR_IT(&GPO_TIM2Handle, TIM_IT_CC4); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM2Handle, TIM_CHANNEL_4); + __HAL_TIM_SET_COMPARE(&GPO_TIM2Handle, TIM_CHANNEL_4, (capture + led_4_period)); + HAL_GPIO_TogglePin(LED_4_GPIO_PORT,LED_4_PIN); + } } } void GPO_TIMER3_IRQHandler(void) { - uint16_t capture; + uint32_t capture; - if(TIM_GetITStatus(GPO_TIMER3, TIM_IT_CC1)!=RESET) + if(__HAL_TIM_GET_FLAG(&GPO_TIM3Handle, TIM_FLAG_CC1) != RESET) { - TIM_ClearITPendingBit(GPO_TIMER3,TIM_IT_CC1); - if(GPIO_ReadOutputDataBit(LED_6_R_GPIO_PORT,LED_6_R_PIN)) - HAL_GPIO_WritePin(LED_6_R_GPIO_PORT,LED_6_R_PIN); - else - GPIO_SetBits(LED_6_R_GPIO_PORT,LED_6_R_PIN); - capture = TIM_GetCapture1(GPO_TIMER3); - TIM_SetCompare1(GPO_TIMER3, capture + led_6_R_period); + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM3Handle, TIM_IT_CC1) !=RESET) + { + __HAL_TIM_CLEAR_IT(&GPO_TIM3Handle, TIM_IT_CC1); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM3Handle, TIM_CHANNEL_1); + __HAL_TIM_SET_COMPARE(&GPO_TIM3Handle, TIM_CHANNEL_1, (capture + led_6_R_period)); + HAL_GPIO_TogglePin(LED_6_R_GPIO_PORT,LED_6_R_PIN); + } } - if(TIM_GetITStatus(GPO_TIMER3, TIM_IT_CC2)!=RESET) + if(__HAL_TIM_GET_FLAG(&GPO_TIM3Handle, TIM_FLAG_CC2) != RESET) { - TIM_ClearITPendingBit(GPO_TIMER3,TIM_IT_CC2); - if(GPIO_ReadOutputDataBit(LED_6_G_GPIO_PORT,LED_6_G_PIN)) - HAL_GPIO_WritePin(LED_6_G_GPIO_PORT,LED_6_G_PIN); - else - GPIO_SetBits(LED_6_G_GPIO_PORT,LED_6_G_PIN); - capture = TIM_GetCapture2(GPO_TIMER3); - TIM_SetCompare2(GPO_TIMER3, capture + led_6_G_period); + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM3Handle, TIM_IT_CC2) !=RESET) + { + __HAL_TIM_CLEAR_IT(&GPO_TIM3Handle, TIM_IT_CC2); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM3Handle, TIM_CHANNEL_2); + __HAL_TIM_SET_COMPARE(&GPO_TIM3Handle, TIM_CHANNEL_2, (capture + led_6_G_period)); + HAL_GPIO_TogglePin(LED_6_G_GPIO_PORT,LED_6_G_PIN); + } } - if(TIM_GetITStatus(GPO_TIMER3, TIM_IT_CC3)!=RESET) + if(__HAL_TIM_GET_FLAG(&GPO_TIM3Handle, TIM_FLAG_CC3) != RESET) { - TIM_ClearITPendingBit(GPO_TIMER3,TIM_IT_CC3); - if(GPIO_ReadOutputDataBit(LED_6_B_GPIO_PORT,LED_6_B_PIN)) - HAL_GPIO_WritePin(LED_6_B_GPIO_PORT,LED_6_B_PIN); - else - GPIO_SetBits(LED_6_B_GPIO_PORT,LED_6_B_PIN); - capture = TIM_GetCapture3(GPO_TIMER3); - TIM_SetCompare3(GPO_TIMER3, capture + led_6_B_period); + if(__HAL_TIM_GET_IT_SOURCE(&GPO_TIM3Handle, TIM_IT_CC3) !=RESET) + { + __HAL_TIM_CLEAR_IT(&GPO_TIM3Handle, TIM_IT_CC3); + capture = HAL_TIM_ReadCapturedValue(&GPO_TIM3Handle, TIM_CHANNEL_3); + __HAL_TIM_SET_COMPARE(&GPO_TIM3Handle, TIM_CHANNEL_3, (capture + led_6_B_period)); + HAL_GPIO_TogglePin(LED_6_B_GPIO_PORT,LED_6_B_PIN); + } } -}*/ +} // private functions @@ -248,14 +257,12 @@ void gpio_init(void) ENABLE_LED_6_B_GPIO_CLK; ENABLE_START_PB_GPIO_CLK; ENABLE_MODE_PB_GPIO_CLK; - ENABLE_GPO_TIMER1_CLK; - ENABLE_GPO_TIMER2_CLK; - ENABLE_GPO_TIMER3_CLK; /* GPIO Configuration */ GPIO_InitStructure.Pin = LED_RX_PIN; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; + GPIO_InitStructure.Pull = GPIO_NOPULL; HAL_GPIO_Init(LED_RX_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.Pin = LED_TX_PIN; @@ -311,10 +318,6 @@ void gpio_init(void) start_pb_callback=0; mode_pb_callback=0; - // initialize the timer interrupts - HAL_NVIC_SetPriority(GPO_TIMER1_IRQn, 3, 1); - HAL_NVIC_EnableIRQ(GPO_TIMER1_IRQn); - /* LED's timer configuration */ GPO_TIM1Handle.Instance=GPO_TIMER1; GPO_TIM1Handle.Init.Period = 0xFFFF; @@ -322,11 +325,12 @@ void gpio_init(void) GPO_TIM1Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2; GPO_TIM1Handle.Init.CounterMode = TIM_COUNTERMODE_UP; GPO_TIM1Handle.Init.RepetitionCounter=0; - HAL_TIM_OC_Init(&GPO_TIM1Handle); - + HAL_TIM_Base_Init(&GPO_TIM1Handle); + ENABLE_GPO_TIMER1_CLK; // initialize the timer interrupts - HAL_NVIC_SetPriority(GPO_TIMER2_IRQn, 3, 2); - HAL_NVIC_EnableIRQ(GPO_TIMER2_IRQn); + HAL_NVIC_SetPriority(GPO_TIMER1_IRQn, 3, 1); + HAL_NVIC_EnableIRQ(GPO_TIMER1_IRQn); + HAL_TIM_OC_Init(&GPO_TIM1Handle); /* LED's timer configuration */ GPO_TIM2Handle.Instance=GPO_TIMER2; @@ -335,11 +339,12 @@ void gpio_init(void) GPO_TIM2Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2; GPO_TIM2Handle.Init.CounterMode = TIM_COUNTERMODE_UP; GPO_TIM2Handle.Init.RepetitionCounter=0; - HAL_TIM_OC_Init(&GPO_TIM2Handle); - + HAL_TIM_Base_Init(&GPO_TIM2Handle); + ENABLE_GPO_TIMER2_CLK; // initialize the timer interrupts - HAL_NVIC_SetPriority(GPO_TIMER3_IRQn, 3, 3); - HAL_NVIC_EnableIRQ(GPO_TIMER3_IRQn); + HAL_NVIC_SetPriority(GPO_TIMER2_IRQn, 3, 2); + HAL_NVIC_EnableIRQ(GPO_TIMER2_IRQn); + HAL_TIM_OC_Init(&GPO_TIM2Handle); /* LED's timer configuration */ GPO_TIM3Handle.Instance=GPO_TIMER3; @@ -348,10 +353,15 @@ void gpio_init(void) GPO_TIM3Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2; GPO_TIM3Handle.Init.CounterMode = TIM_COUNTERMODE_UP; GPO_TIM3Handle.Init.RepetitionCounter=0; + HAL_TIM_Base_Init(&GPO_TIM3Handle); + ENABLE_GPO_TIMER3_CLK; + // initialize the timer interrupts + HAL_NVIC_SetPriority(GPO_TIMER3_IRQn, 3, 3); + HAL_NVIC_EnableIRQ(GPO_TIMER3_IRQn); HAL_TIM_OC_Init(&GPO_TIM3Handle); /* enable external interrupts */ - HAL_NVIC_SetPriority(GPI_EXTI1_IRQn, 2, 3); + HAL_NVIC_SetPriority(GPI_EXTI1_IRQn, 3, 0); HAL_NVIC_EnableIRQ(GPI_EXTI1_IRQn); // turn off all leds @@ -533,7 +543,7 @@ void gpio_blink_led(led_t led_id, int16_t period_ms) { led_2_period=period_ms; TIM_OCInitStructure.Pulse = led_2_period; - HAL_TIM_OC_ConfigChannel(&GPO_TIM1Handle, &TIM_OCInitStructure,TIM_CHANNEL_3); + HAL_TIM_OC_ConfigChannel(&GPO_TIM1Handle, &TIM_OCInitStructure,TIM_CHANNEL_3); HAL_TIM_OC_Start_IT(&GPO_TIM1Handle, TIM_CHANNEL_3); } else @@ -550,120 +560,99 @@ void gpio_blink_led(led_t led_id, int16_t period_ms) else HAL_TIM_OC_Stop_IT(&GPO_TIM1Handle, TIM_CHANNEL_4); break; -/* case LED_4: + case LED_4: if(period_ms>1) { led_4_period=period_ms; - TIM_OCInitStructure.TIM_Pulse = led_4_period; - TIM_OC4Init(GPO_TIMER2, &TIM_OCInitStructure); - TIM_OC4PreloadConfig(GPO_TIMER2, TIM_OCPreload_Disable); - capture = TIM_GetCounter(GPO_TIMER2); - TIM_SetCompare4(GPO_TIMER2, capture + led_4_period); - TIM_ITConfig(GPO_TIMER2, TIM_IT_CC4, ENABLE); + TIM_OCInitStructure.Pulse = led_4_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM2Handle, &TIM_OCInitStructure,TIM_CHANNEL_4); + HAL_TIM_OC_Start_IT(&GPO_TIM2Handle, TIM_CHANNEL_4); } else - TIM_ITConfig(GPO_TIMER2, TIM_IT_CC4, DISABLE); + HAL_TIM_OC_Stop_IT(&GPO_TIM2Handle, TIM_CHANNEL_4); break; case LED_5_R: if(period_ms>1) { led_5_R_period=period_ms; - TIM_OCInitStructure.TIM_Pulse = led_5_R_period; - TIM_OC1Init(GPO_TIMER2, &TIM_OCInitStructure); - TIM_OC1PreloadConfig(GPO_TIMER2, TIM_OCPreload_Disable); - capture = TIM_GetCounter(GPO_TIMER2); - TIM_SetCompare1(GPO_TIMER2, capture + led_5_R_period); - TIM_ITConfig(GPO_TIMER2, TIM_IT_CC1, ENABLE); + TIM_OCInitStructure.Pulse = led_5_R_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM2Handle, &TIM_OCInitStructure,TIM_CHANNEL_1); + HAL_TIM_OC_Start_IT(&GPO_TIM2Handle, TIM_CHANNEL_1); } else - TIM_ITConfig(GPO_TIMER2, TIM_IT_CC1, DISABLE); + HAL_TIM_OC_Stop_IT(&GPO_TIM2Handle, TIM_CHANNEL_1); break; case LED_5_G: if(period_ms>1) { led_5_G_period=period_ms; - TIM_OCInitStructure.TIM_Pulse = led_5_G_period; - TIM_OC2Init(GPO_TIMER2, &TIM_OCInitStructure); - TIM_OC2PreloadConfig(GPO_TIMER2, TIM_OCPreload_Disable); - capture = TIM_GetCounter(GPO_TIMER2); - TIM_SetCompare2(GPO_TIMER2, capture + led_5_G_period); - TIM_ITConfig(GPO_TIMER2, TIM_IT_CC2, ENABLE); + TIM_OCInitStructure.Pulse = led_5_G_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM2Handle, &TIM_OCInitStructure,TIM_CHANNEL_2); + HAL_TIM_OC_Start_IT(&GPO_TIM2Handle, TIM_CHANNEL_2); } else - TIM_ITConfig(GPO_TIMER2, TIM_IT_CC2, DISABLE); + HAL_TIM_OC_Stop_IT(&GPO_TIM2Handle, TIM_CHANNEL_2); break; case LED_5_B: if(period_ms>1) { led_5_B_period=period_ms; - TIM_OCInitStructure.TIM_Pulse = led_5_B_period; - TIM_OC3Init(GPO_TIMER2, &TIM_OCInitStructure); - TIM_OC3PreloadConfig(GPO_TIMER2, TIM_OCPreload_Disable); - capture = TIM_GetCounter(GPO_TIMER2); - TIM_SetCompare3(GPO_TIMER2, capture + led_5_B_period); - TIM_ITConfig(GPO_TIMER2, TIM_IT_CC3, ENABLE); + TIM_OCInitStructure.Pulse = led_5_B_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM2Handle, &TIM_OCInitStructure,TIM_CHANNEL_3); + HAL_TIM_OC_Start_IT(&GPO_TIM2Handle, TIM_CHANNEL_3); } else - TIM_ITConfig(GPO_TIMER2, TIM_IT_CC3, DISABLE); + HAL_TIM_OC_Stop_IT(&GPO_TIM2Handle, TIM_CHANNEL_3); break; case LED_6_R: if(period_ms>1) { led_6_R_period=period_ms; - TIM_OCInitStructure.TIM_Pulse = led_6_R_period; - TIM_OC1Init(GPO_TIMER3, &TIM_OCInitStructure); - TIM_OC1PreloadConfig(GPO_TIMER3, TIM_OCPreload_Disable); - capture = TIM_GetCounter(GPO_TIMER3); - TIM_SetCompare1(GPO_TIMER3, capture + led_6_R_period); - TIM_ITConfig(GPO_TIMER3, TIM_IT_CC1, ENABLE); + TIM_OCInitStructure.Pulse = led_6_R_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM3Handle, &TIM_OCInitStructure,TIM_CHANNEL_1); + HAL_TIM_OC_Start_IT(&GPO_TIM3Handle, TIM_CHANNEL_1); } else - TIM_ITConfig(GPO_TIMER3, TIM_IT_CC1, DISABLE); + HAL_TIM_OC_Stop_IT(&GPO_TIM3Handle, TIM_CHANNEL_1); break; case LED_6_G: if(period_ms>1) { led_6_G_period=period_ms; - TIM_OCInitStructure.TIM_Pulse = led_6_G_period; - TIM_OC2Init(GPO_TIMER3, &TIM_OCInitStructure); - TIM_OC2PreloadConfig(GPO_TIMER3, TIM_OCPreload_Disable); - capture = TIM_GetCounter(GPO_TIMER3); - TIM_SetCompare2(GPO_TIMER3, capture + led_6_G_period); - TIM_ITConfig(GPO_TIMER3, TIM_IT_CC2, ENABLE); + TIM_OCInitStructure.Pulse = led_6_G_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM3Handle, &TIM_OCInitStructure,TIM_CHANNEL_2); + HAL_TIM_OC_Start_IT(&GPO_TIM3Handle, TIM_CHANNEL_2); } else - TIM_ITConfig(GPO_TIMER3, TIM_IT_CC2, DISABLE); + HAL_TIM_OC_Stop_IT(&GPO_TIM3Handle, TIM_CHANNEL_2); break; case LED_6_B: if(period_ms>1) { led_6_B_period=period_ms; - TIM_OCInitStructure.TIM_Pulse = led_6_B_period; - TIM_OC3Init(GPO_TIMER3, &TIM_OCInitStructure); - TIM_OC3PreloadConfig(GPO_TIMER3, TIM_OCPreload_Disable); - capture = TIM_GetCounter(GPO_TIMER3); - TIM_SetCompare3(GPO_TIMER3, capture + led_6_B_period); - TIM_ITConfig(GPO_TIMER3, TIM_IT_CC3, ENABLE); + TIM_OCInitStructure.Pulse = led_6_B_period; + HAL_TIM_OC_ConfigChannel(&GPO_TIM3Handle, &TIM_OCInitStructure,TIM_CHANNEL_3); + HAL_TIM_OC_Start_IT(&GPO_TIM3Handle, TIM_CHANNEL_3); } else - TIM_ITConfig(GPO_TIMER3, TIM_IT_CC3, DISABLE); - break;*/ + HAL_TIM_OC_Stop_IT(&GPO_TIM3Handle, TIM_CHANNEL_3); + break; default: break; } } -/*uint8_t gpio_is_pushbutton_pressed(pushbutton_t pb_id) +uint8_t gpio_is_pushbutton_pressed(pushbutton_t pb_id) { switch(pb_id) { case START_PB: - if(GPIO_ReadInputDataBit(START_PB_GPIO_PORT,START_PB_PIN)==Bit_SET) + if(HAL_GPIO_ReadPin(START_PB_GPIO_PORT,START_PB_PIN)==GPIO_PIN_SET) return 0x01; else return 0x00; break; case MODE_PB: - if(GPIO_ReadInputDataBit(MODE_PB_GPIO_PORT,MODE_PB_PIN)==Bit_SET) + if(HAL_GPIO_ReadPin(MODE_PB_GPIO_PORT,MODE_PB_PIN)==GPIO_PIN_SET) return 0x01; else return 0x00; @@ -684,4 +673,4 @@ void gpio_set_pushbutton_callback(pushbutton_t pb_id,void (*callback)(void)) mode_pb_callback=callback; break; } -}*/ +} diff --git a/src/ram.c b/src/ram.c index 521d8f821541cc9b73a081284e91c8f3afe5dfd8..65cf3bc6a3ffc215f9179f2d3f102e573a79d72e 100755 --- a/src/ram.c +++ b/src/ram.c @@ -9,7 +9,7 @@ void ram_init(void) 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) + if(EE_ReadVariable(DEVICE_MODEL_OFFSET,&eeprom_data)==0) ram_data[DEVICE_MODEL_OFFSET]=(uint8_t)(eeprom_data&0x00FF); if(EE_ReadVariable(DEVICE_MODEL_OFFSET+1,&eeprom_data)==0) ram_data[DEVICE_MODEL_OFFSET+1]=(uint8_t)(eeprom_data&0x00FF); @@ -26,7 +26,7 @@ void ram_init(void) 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;*/ + ram_data[RETURN_LEVEL_OFFSET]=(uint8_t)eeprom_data; } inline void ram_read_byte(uint8_t address,uint8_t *data) diff --git a/src/stm32f1xx_hal_msp.c b/src/stm32f1xx_hal_msp.c index 1997e3bfc43114d24943e1d2686fbf100326b3fa..62b98879c377f6cf49011bb99a52f850e467435b 100755 --- a/src/stm32f1xx_hal_msp.c +++ b/src/stm32f1xx_hal_msp.c @@ -79,28 +79,25 @@ void HAL_MspInit(void) /* NOTE : This function is generated automatically by MicroXplorer and eventually modified by the user */ - RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct; - /* Set Interrupt Group Priority */ - HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);// 4 priorities, 4 subpriorities + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; HAL_RCC_OscConfig(&RCC_OscInitStruct); - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1; + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); - - __HAL_RCC_AFIO_CLK_ENABLE(); } /** diff --git a/src/system_stm32f1xx.c b/src/system_stm32f1xx.c new file mode 100644 index 0000000000000000000000000000000000000000..6014fa957ffbd54063b032a05006869fe577c5e6 --- /dev/null +++ b/src/system_stm32f1xx.c @@ -0,0 +1,446 @@ +/** + ****************************************************************************** + * @file system_stm32f1xx.c + * @author MCD Application Team + * @version V4.0.0 + * @date 16-December-2014 + * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier + * factors, AHB/APBx prescalers and Flash settings). + * This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f1xx_xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * 2. After each device reset the HSI (8 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to + * configure the system clock before to branch to main program. + * + * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on + * the product used), refer to "HSE_VALUE". + * When HSE is used as system clock source, directly or through PLL, and you + * are using different crystal you have to adapt the HSE value to your own + * configuration. + * + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f1xx_system + * @{ + */ + +/** @addtogroup STM32F1xx_System_Private_Includes + * @{ + */ + +#include "stm32f1xx.h" + +/** + * @} + */ + +/** @addtogroup STM32F1xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F1xx_System_Private_Defines + * @{ + */ + +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSI_VALUE */ + +/*!< Uncomment the following line if you need to use external SRAM */ +#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) +/* #define DATA_IN_ExtSRAM */ +#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x3000 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ + + +/** + * @} + */ + +/** @addtogroup STM32F1xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F1xx_System_Private_Variables + * @{ + */ + +/******************************************************************************* +* Clock Definitions +*******************************************************************************/ +#if defined(STM32F100xB) ||defined(STM32F100xE) + uint32_t SystemCoreClock = 24000000; /*!< System Clock Frequency (Core Clock) */ +#else /*!< HSI Selected as System Clock source */ + uint32_t SystemCoreClock = 72000000; /*!< System Clock Frequency (Core Clock) */ +#endif + +__IO const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +/** + * @} + */ + +/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes + * @{ + */ + +#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) +#ifdef DATA_IN_ExtSRAM + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM */ +#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ + +/** + * @} + */ + +/** @addtogroup STM32F1xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the Embedded Flash Interface, the PLL and update the + * SystemCoreClock variable. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ +#if !defined(STM32F105xC) && !defined(STM32F107xC) + RCC->CFGR &= (uint32_t)0xF8FF0000; +#else + RCC->CFGR &= (uint32_t)0xF0FF0000; +#endif /* STM32F105xC */ + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ + RCC->CFGR &= (uint32_t)0xFF80FFFF; + +#if defined(STM32F105xC) || defined(STM32F107xC) + /* Reset PLL2ON and PLL3ON bits */ + RCC->CR &= (uint32_t)0xEBFFFFFF; + + /* Disable all interrupts and clear pending bits */ + RCC->CIR = 0x00FF0000; + + /* Reset CFGR2 register */ + RCC->CFGR2 = 0x00000000; +#elif defined(STM32F100xB) || defined(STM32F100xE) + /* Disable all interrupts and clear pending bits */ + RCC->CIR = 0x009F0000; + + /* Reset CFGR2 register */ + RCC->CFGR2 = 0x00000000; +#else + /* Disable all interrupts and clear pending bits */ + RCC->CIR = 0x009F0000; +#endif /* STM32F105xC */ + +#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) + #ifdef DATA_IN_ExtSRAM + SystemInit_ExtMemCtl(); + #endif /* DATA_IN_ExtSRAM */ +#endif + +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value + * 8 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value + * 8 MHz or 25 MHz, depending on the product used), user has to ensure + * that HSE_VALUE is same as the real frequency of the crystal used. + * Otherwise, this function may have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * @param None + * @retval None + */ +void SystemCoreClockUpdate (void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0; + +#if defined(STM32F105xC) || defined(STM32F107xC) + uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0; +#endif /* STM32F105xC */ + +#if defined(STM32F100xB) || defined(STM32F100xE) + uint32_t prediv1factor = 0; +#endif /* STM32F100xB or STM32F100xE */ + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock */ + + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + +#if !defined(STM32F105xC) && !defined(STM32F107xC) + pllmull = ( pllmull >> 18) + 2; + + if (pllsource == 0x00) + { + /* HSI oscillator clock divided by 2 selected as PLL clock entry */ + SystemCoreClock = (HSI_VALUE >> 1) * pllmull; + } + else + { + #if defined(STM32F100xB) || defined(STM32F100xE) + prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; + /* HSE oscillator clock selected as PREDIV1 clock entry */ + SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; + #else + /* HSE selected as PLL clock entry */ + if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET) + {/* HSE oscillator clock divided by 2 */ + SystemCoreClock = (HSE_VALUE >> 1) * pllmull; + } + else + { + SystemCoreClock = HSE_VALUE * pllmull; + } + #endif + } +#else + pllmull = pllmull >> 18; + + if (pllmull != 0x0D) + { + pllmull += 2; + } + else + { /* PLL multiplication factor = PLL input clock * 6.5 */ + pllmull = 13 / 2; + } + + if (pllsource == 0x00) + { + /* HSI oscillator clock divided by 2 selected as PLL clock entry */ + SystemCoreClock = (HSI_VALUE >> 1) * pllmull; + } + else + {/* PREDIV1 selected as PLL clock entry */ + + /* Get PREDIV1 clock source and division factor */ + prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC; + prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; + + if (prediv1source == 0) + { + /* HSE oscillator clock selected as PREDIV1 clock entry */ + SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; + } + else + {/* PLL2 clock selected as PREDIV1 clock entry */ + + /* Get PREDIV2 division factor and PLL2 multiplication factor */ + prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1; + pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; + SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull; + } + } +#endif /* STM32F105xC */ + break; + + default: + SystemCoreClock = HSI_VALUE; + break; + } + + /* Compute HCLK clock frequency ----------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) +/** + * @brief Setup the external memory controller. Called in startup_stm32f1xx.s + * before jump to __main + * @param None + * @retval None + */ +#ifdef DATA_IN_ExtSRAM +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f1xx_xx.s/.c before jump to main. + * This function configures the external SRAM mounted on STM3210E-EVAL + * board (STM32 High density devices). This SRAM will be used as program + * data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmpreg; + /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is + required, then adjust the Register Addresses */ + + /* Enable FSMC clock */ + RCC->AHBENR = 0x00000114; + + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN); + + /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */ + RCC->APB2ENR = 0x000001E0; + + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN); + + (void)(tmpreg); + +/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/ +/*---------------- SRAM Address lines configuration -------------------------*/ +/*---------------- NOE and NWE configuration --------------------------------*/ +/*---------------- NE3 configuration ----------------------------------------*/ +/*---------------- NBL0, NBL1 configuration ---------------------------------*/ + + GPIOD->CRL = 0x44BB44BB; + GPIOD->CRH = 0xBBBBBBBB; + + GPIOE->CRL = 0xB44444BB; + GPIOE->CRH = 0xBBBBBBBB; + + GPIOF->CRL = 0x44BBBBBB; + GPIOF->CRH = 0xBBBB4444; + + GPIOG->CRL = 0x44BBBBBB; + GPIOG->CRH = 0x444B4B44; + +/*---------------- FSMC Configuration ---------------------------------------*/ +/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/ + + FSMC_Bank1->BTCR[4] = 0x00001091; + FSMC_Bank1->BTCR[5] = 0x00110212; +} +#endif /* DATA_IN_ExtSRAM */ +#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/time.c b/src/time.c index e2d6e6b49ee208244184e893fc89551755d14f2c..5b0cbee6b1bfe6fd45f9eec883154d8b826ded73 100755 --- a/src/time.c +++ b/src/time.c @@ -1,60 +1,33 @@ #include "time.h" -static __IO uint32_t timing_delay; uint32_t clocks_per_us; - -/******************************************************************************* -* Function Name : SysTickHandler -* Description : This function handles SysTick Handler. -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -void SysTick_Handler(void) -{ - if(timing_delay!=0) - timing_delay--; -} +TIM_HandleTypeDef us_timer_Handle; // public functions void time_init(void) { - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - - // set the time base to 1ms - SysTick_Config(SystemCoreClock / 1000); - NVIC_SetPriority(SysTick_IRQn,0); - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); - - TIM_TimeBaseStructure.TIM_Period = 0xFFFF; - TIM_TimeBaseStructure.TIM_Prescaler = 0; - TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseStructure.TIM_RepetitionCounter=0x0000; - TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); - TIM_SetCounter(TIM1,0); - + us_timer_Handle.Instance=TIM1; + us_timer_Handle.Init.Period = 0xFFFF; + us_timer_Handle.Init.Prescaler = 0; + us_timer_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + us_timer_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; + us_timer_Handle.Init.RepetitionCounter=0; + HAL_TIM_Base_Init(&us_timer_Handle); + __HAL_RCC_TIM1_CLK_ENABLE(); + __HAL_TIM_SET_COUNTER(&us_timer_Handle,0); clocks_per_us=(SystemCoreClock/1000000)+1; } -void delay_ms(__IO uint32_t time) -{ - timing_delay=time; - - while(timing_delay!=0); -} - void delay_us(uint32_t us) // microseconds { uint32_t clocks,current; clocks=clocks_per_us*us; - TIM_SetCounter(TIM1,0); - TIM_Cmd(TIM1, ENABLE); + __HAL_TIM_SET_COUNTER(&us_timer_Handle,0); + HAL_TIM_Base_Start(&us_timer_Handle); do{ - current=TIM_GetCounter(TIM1); + current=__HAL_TIM_GET_COUNTER(&us_timer_Handle); }while(current<clocks); - TIM_Cmd(TIM1, DISABLE); + HAL_TIM_Base_Stop(&us_timer_Handle); }