├── .cproject
├── .gitignore
├── .project
├── .settings
└── org.eclipse.cdt.codan.core.prefs
├── README.md
├── inc
├── core_cm3.h
├── node.h
├── stm32-template.h
├── stm32f10x_conf.h
└── stm32f10x_it.h
├── modbus
├── crc.cpp
├── crc.h
├── slave-rtu.cpp
├── slave-rtu.h
├── usart-rs485-modbus.cpp
└── usart-rs485-modbus.h
├── readme.txt
├── src
├── main.cpp
├── node.cpp
└── stm32f10x_it.cpp
├── stm32-modbus.doxyfile
├── stm32_flash.ld
├── sys
├── core_cm3.c
├── library_hacks.cpp
├── newlib_stubs.cpp
├── startup_stm32f10x_md_vl.S
└── system_stm32f10x.c
└── test
└── md_readbit.py
/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
38 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
56 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
117 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
137 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Debug/
2 | Release/
3 | html/
4 |
5 | stm32libs
6 | *.swp
7 |
8 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | demo
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 |
14 |
15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
16 | full,incremental,
17 |
18 |
19 |
20 |
21 |
22 | org.eclipse.cdt.core.cnature
23 | org.eclipse.cdt.core.ccnature
24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
26 |
27 |
28 |
29 | StdPeriph
30 | 2
31 | PARENT-1-PROJECT_LOC/Libraries/STM32F10x_StdPeriph_Driver/src
32 |
33 |
34 | stm32libs
35 | 2
36 | PARENT-1-PROJECT_LOC/stm32libs
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.cdt.codan.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.cdt.codan.checkers.errnoreturn=Warning
3 | org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
4 | org.eclipse.cdt.codan.checkers.errreturnvalue=Error
5 | org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
6 | org.eclipse.cdt.codan.checkers.noreturn=Error
7 | org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
8 | org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
9 | org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
10 | org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
11 | org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
12 | org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
13 | org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
14 | org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
15 | org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
16 | org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
17 | org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
18 | org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
19 | org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
20 | org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
21 | org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
22 | org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
23 | org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
24 | org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
25 | org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
26 | org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
27 | org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
28 | org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
29 | org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
30 | org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
31 | org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
32 | org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
33 | org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
34 | org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
35 | org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
36 | org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
37 | org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
38 | org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
39 | org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
40 | org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
41 | org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
42 | org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
43 | org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
44 | org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
45 | org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
46 | org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
47 | org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
48 | org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
49 | org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
50 | org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
51 | org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
52 | org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
53 | org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
54 | org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
55 | org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
56 | org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
57 | org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
58 | org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
59 | org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
60 | org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
61 | org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
62 | org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
63 | org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
64 | org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
65 | org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
66 | org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
67 | org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
68 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | stm32 development template for modbus based on ST STM32F100 STM32Discovery
2 |
3 | OS: ubuntu
4 |
5 | Toolchain: Sourcery CodeBench Lite Edition for ARM EABI hosted on IA32 GNU/Linux
6 |
7 | IDE: eclipse + cdt + gnu arm eclipe plug-in
8 |
9 | note: the startup asm source file should be copied from Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup, and rename startup_stm32f10x_hd.s to startup_stm32f10x_hd.S
10 |
--------------------------------------------------------------------------------
/inc/node.h:
--------------------------------------------------------------------------------
1 | /*
2 | * node.h
3 | *
4 | * Created on: Jul 23, 2013
5 | * Author: agu
6 | */
7 |
8 | #ifndef NODE_H_
9 | #define NODE_H_
10 |
11 | #include
12 |
13 | #include "modbus/slave-rtu.h"
14 | #include "gpio/gpio.h"
15 | #include "adc/adc.h"
16 | #include "dma/dma.h"
17 |
18 | class Node: public SlaveRtu {
19 | public:
20 | Node(UsartRs485Modbus & usart, uint8_t address);
21 | ~Node();
22 | void init();
23 |
24 | private:
25 | Gpio ** _bit_input_pins;
26 | Gpio ** _coil_pins;
27 | Gpio ** _short_input_pins;
28 |
29 | Adc * _adc;
30 | uint8_t * _adc_channels;
31 | const static uint8_t _uuid[];
32 | const static uint8_t _lengths[];
33 |
34 | uint8_t updateBitInputs(uint16_t index, uint16_t length);
35 | uint8_t updateShortInputs(uint16_t index, uint16_t length);
36 | uint8_t updateCoils(uint16_t index, uint16_t length);
37 | uint8_t updateHoldings(uint16_t index, uint16_t length) {return 0;}
38 | };
39 |
40 | #endif /* NODE_H_ */
41 |
--------------------------------------------------------------------------------
/inc/stm32-template.h:
--------------------------------------------------------------------------------
1 | /*
2 | * stm32-template.h
3 | *
4 | * Created on: May 31, 2013
5 | * Author: agu
6 | */
7 |
8 | #ifndef STM32_TEMPLATE_H_
9 | #define STM32_TEMPLATE_H_
10 |
11 | #include "stm32f10x.h"
12 |
13 | #include
14 | #include
15 | #include
16 |
17 | #include "common/bit_op.h"
18 | #include "usart/usart.h"
19 | #include "gpio/gpio.h"
20 | #include "tim/tim.h"
21 | #include "nvic/nvic.h"
22 | #include "i2c/i2c.h"
23 | #include "adc/adc.h"
24 |
25 | void init();
26 | extern void setup();
27 | extern void loop();
28 | extern void delay(u32 ms);
29 | extern void delayMicroseconds(vu32 us);
30 |
31 | #endif /* STM32_TEMPLATE_H_ */
32 |
--------------------------------------------------------------------------------
/inc/stm32f10x_conf.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file stm32f10x_conf.h
4 | * @author MCD Application Team
5 | * @version V3.5.0
6 | * @date 08-April-2011
7 | * @brief Library configuration file.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17 | *
18 | * © COPYRIGHT 2011 STMicroelectronics
19 | ******************************************************************************
20 | */
21 |
22 | /* Define to prevent recursive inclusion -------------------------------------*/
23 | #ifndef __STM32F10x_CONF_H
24 | #define __STM32F10x_CONF_H
25 |
26 | #ifdef __cplusplus
27 | extern "C" {
28 | #endif
29 |
30 | /* Includes ------------------------------------------------------------------*/
31 | /* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */
32 | #include "stm32f10x_adc.h"
33 | #include "stm32f10x_bkp.h"
34 | #include "stm32f10x_can.h"
35 | #include "stm32f10x_cec.h"
36 | #include "stm32f10x_crc.h"
37 | #include "stm32f10x_dac.h"
38 | #include "stm32f10x_dbgmcu.h"
39 | #include "stm32f10x_dma.h"
40 | #include "stm32f10x_exti.h"
41 | #include "stm32f10x_flash.h"
42 | #include "stm32f10x_fsmc.h"
43 | #include "stm32f10x_gpio.h"
44 | #include "stm32f10x_i2c.h"
45 | #include "stm32f10x_iwdg.h"
46 | #include "stm32f10x_pwr.h"
47 | #include "stm32f10x_rcc.h"
48 | #include "stm32f10x_rtc.h"
49 | #include "stm32f10x_sdio.h"
50 | #include "stm32f10x_spi.h"
51 | #include "stm32f10x_tim.h"
52 | #include "stm32f10x_usart.h"
53 | #include "stm32f10x_wwdg.h"
54 | #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
55 |
56 | /* Exported types ------------------------------------------------------------*/
57 | /* Exported constants --------------------------------------------------------*/
58 | /* Uncomment the line below to expanse the "assert_param" macro in the
59 | Standard Peripheral Library drivers code */
60 | /* #define USE_FULL_ASSERT 1 */
61 |
62 | /* Exported macro ------------------------------------------------------------*/
63 | #ifdef USE_FULL_ASSERT
64 |
65 | /**
66 | * @brief The assert_param macro is used for function's parameters check.
67 | * @param expr: If expr is false, it calls assert_failed function which reports
68 | * the name of the source file and the source line number of the call
69 | * that failed. If expr is true, it returns no value.
70 | * @retval None
71 | */
72 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
73 | /* Exported functions ------------------------------------------------------- */
74 | void assert_failed(uint8_t* file, uint32_t line);
75 | #else
76 | #define assert_param(expr) ((void)0)
77 | #endif /* USE_FULL_ASSERT */
78 |
79 | #ifdef __cplusplus
80 | }
81 | #endif
82 |
83 | #endif /* __STM32F10x_CONF_H */
84 |
85 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
86 |
--------------------------------------------------------------------------------
/inc/stm32f10x_it.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file stm32f10x_it.h
4 | * @author MCD Application Team
5 | * @version V3.5.0
6 | * @date 08-April-2011
7 | * @brief This file contains the headers of the interrupt handlers.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17 | *
18 | * © COPYRIGHT 2011 STMicroelectronics
19 | ******************************************************************************
20 | */
21 |
22 | /* Define to prevent recursive inclusion -------------------------------------*/
23 | #ifndef __STM32F10x_IT_H
24 | #define __STM32F10x_IT_H
25 |
26 | /* Includes ------------------------------------------------------------------*/
27 | #include "stm32f10x.h"
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif
32 |
33 | /* Exported types ------------------------------------------------------------*/
34 | /* Exported constants --------------------------------------------------------*/
35 | /* Exported macro ------------------------------------------------------------*/
36 | /* Exported functions ------------------------------------------------------- */
37 |
38 | void NMI_Handler(void);
39 | void HardFault_Handler(void);
40 | void MemManage_Handler(void);
41 | void BusFault_Handler(void);
42 | void UsageFault_Handler(void);
43 | void SVC_Handler(void);
44 | void DebugMon_Handler(void);
45 | void PendSV_Handler(void);
46 | void SysTick_Handler(void);
47 | void TIM2_IRQHandler(void);
48 | void USART1_IRQHandler(void);
49 | void TIM1_UP_TIM16_IRQHandler(void);
50 |
51 | #ifdef __cplusplus
52 | }
53 | #endif
54 |
55 | #endif /* __STM32F10x_IT_H */
56 |
57 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
58 |
--------------------------------------------------------------------------------
/modbus/crc.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Crc.cpp
3 | *
4 | * Created on: Jul 17, 2013
5 | * Author: agu
6 | */
7 |
8 | #include "crc.h"
9 |
10 | const uint8_t Crc::_HI[] = {
11 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
12 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
13 |
14 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
15 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
16 |
17 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
18 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
19 |
20 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
21 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
22 |
23 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
24 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
25 |
26 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
27 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
28 |
29 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
30 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
31 |
32 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
33 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
34 |
35 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
36 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
37 |
38 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
39 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
40 |
41 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
42 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
43 |
44 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
45 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
46 |
47 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
48 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
49 |
50 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
51 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
52 |
53 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
54 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
55 |
56 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
57 | 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
58 | };
59 |
60 | const uint8_t Crc::_LO[] = {
61 | 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2,
62 | 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04,
63 |
64 | 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
65 | 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8,
66 |
67 | 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
68 | 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
69 |
70 | 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6,
71 | 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10,
72 |
73 | 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
74 | 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
75 |
76 | 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE,
77 | 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
78 |
79 | 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA,
80 | 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C,
81 |
82 | 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
83 | 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0,
84 |
85 | 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62,
86 | 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
87 |
88 | 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE,
89 | 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
90 |
91 | 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
92 | 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C,
93 |
94 | 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76,
95 | 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
96 |
97 | 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
98 | 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54,
99 |
100 | 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
101 | 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98,
102 |
103 | 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A,
104 | 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
105 |
106 | 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86,
107 | 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
108 | };
109 |
110 | uint16_t Crc::calc(const uint8_t *p, uint16_t length) {
111 | uint8_t hi = 0xFF;
112 | uint8_t lo = 0xFF;
113 |
114 | while (length--) {
115 | uint8_t i = lo ^ *p++;
116 | lo = hi ^ _HI[i];
117 | hi = _LO[i];
118 | }
119 | return (uint16_t) (hi << 8) | lo;
120 | }
121 |
122 | Crc crc;
123 |
--------------------------------------------------------------------------------
/modbus/crc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Crc.h
3 | *
4 | * Created on: Jul 17, 2013
5 | * Author: agu
6 | */
7 |
8 | #ifndef CRC_H_
9 | #define CRC_H_
10 |
11 | #include "stm32f10x.h"
12 |
13 | class Crc {
14 | public:
15 | static uint16_t calc(const uint8_t *p, uint16_t length);
16 | private:
17 | const static uint8_t _HI[];
18 | const static uint8_t _LO[];
19 | };
20 |
21 | extern Crc crc;
22 |
23 | #endif /* CRC_H_ */
24 |
--------------------------------------------------------------------------------
/modbus/slave-rtu.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * slave-rtu.cpp
3 | *
4 | * Created on: Jul 17, 2013
5 | * Author: agu
6 | */
7 |
8 | #include "slave-rtu.h"
9 |
10 | /**
11 | *
12 | *
13 | *
14 | */
15 |
16 | SlaveRtu::SlaveRtu(UsartRs485Modbus & usart, uint8_t address) :
17 | _usart(usart), _address(address) {
18 |
19 | _bit_inputs = NULL;
20 | _bit_input_length = 0;
21 |
22 | _short_inputs = NULL;
23 | _short_input_length = 0;
24 |
25 | _coils = NULL;
26 | _coil_length = 0;
27 |
28 | _holdings = NULL;
29 | _holding_length = 0;
30 |
31 | this->initBitInputs(16);
32 | this->initShortInputs(8);
33 | this->initCoils(32);
34 | this->initHoldings(16);
35 | }
36 |
37 | SlaveRtu::~SlaveRtu() {
38 | free(_bit_inputs);
39 | free(_short_inputs);
40 |
41 | free(_coils);
42 | free(_holdings);
43 | }
44 |
45 | void SlaveRtu::initBitInputs(uint16_t length) {
46 | if (_bit_inputs) free(_bit_inputs);
47 |
48 | _bit_input_length = length;
49 | uint8_t bit_input_byte_size = (_bit_input_length + 7) >> 3;
50 | _bit_inputs = (uint8_t *) malloc(bit_input_byte_size * sizeof(uint8_t));
51 |
52 | assert_param(_bit_inputs);
53 | memset(_bit_inputs, 0, bit_input_byte_size);
54 | }
55 |
56 | void SlaveRtu::initShortInputs(uint16_t length) {
57 | if (_short_inputs) free(_short_inputs);
58 |
59 | _short_input_length = length;
60 | _short_inputs = (uint16_t *) malloc(_short_input_length * sizeof(uint16_t));
61 | assert_param(_short_inputs);
62 | memset(_short_inputs, 0, _short_input_length * sizeof(uint16_t));
63 | }
64 |
65 | void SlaveRtu::initCoils(uint16_t length) {
66 | if (_coils) free(_coils);
67 |
68 | _coil_length = length;
69 | uint8_t coils_byte_size = (_coil_length + 7) >> 3;
70 | _coils = (uint8_t *) malloc(coils_byte_size * sizeof(uint8_t));
71 | assert_param(_coils);
72 | memset(_coils, 0, coils_byte_size);
73 | }
74 |
75 | void SlaveRtu::initHoldings(uint16_t length) {
76 | if (_holdings) free(_holdings);
77 |
78 | _holding_length = length;
79 | _holdings = (uint16_t *) malloc(_holding_length * sizeof(uint16_t));
80 | assert_param(_holdings);
81 | memset(_holdings, 0, _holding_length * sizeof(uint16_t));
82 | }
83 |
84 | void SlaveRtu::init() {
85 | _usart.init();
86 | }
87 |
88 | void SlaveRtu::setAddress(uint8_t address) {
89 | _address = address;
90 | }
91 |
92 | void SlaveRtu::handler() {
93 | static uint16_t length_rx = 0;
94 |
95 | if (_usart.available()) {
96 | _buff_rx[length_rx++] = _usart.read();
97 | }
98 |
99 | if (_usart.isReceiving() == false) {
100 | memset(_buff_tx, 0, _BUFF_LENGTH);
101 |
102 | do {
103 | if (length_rx < 4 || length_rx >= _BUFF_LENGTH) break;
104 | if (_buff_rx[0] && _buff_rx[0] != _address) break;
105 | if (this->checkFrameCrc(_buff_rx, length_rx) == false) break;
106 |
107 | _buff_tx[0] = _address;
108 | _buff_tx[1] = _buff_rx[1]; // function code
109 |
110 | uint8_t length_tx = 1;
111 | uint8_t exception = 0;
112 |
113 | switch (_buff_rx[1]) {
114 | case 0x01:
115 | exception = onReadCoils(&length_tx);
116 | break;
117 | case 0x02:
118 | exception = onReadBitInputs(&length_tx);
119 | break;
120 | case 0x03:
121 | exception = onReadHoldings(&length_tx);
122 | break;
123 | case 0x04:
124 | exception = onReadShortInputs(&length_tx);
125 | break;
126 | case 0x05:
127 | exception = onWriteSingleCoil(&length_tx);
128 | break;
129 | case 0x06:
130 | exception = onWriteSingleHolding(&length_tx);
131 | break;
132 | case 0x0f:
133 | exception = onWriteMultipleCoils(length_rx, &length_tx);
134 | break;
135 | case 0x10:
136 | exception = onWriteMultipleHoldings(length_rx, &length_tx);
137 | break;
138 | default:
139 | exception = 0x01;
140 | break;
141 | }
142 |
143 | if (exception) {
144 | _buff_tx[1] += 0x80;
145 | _buff_tx[2] = exception;
146 | length_tx = 3;
147 | }
148 |
149 | if (_buff_tx[0]) this->appendCrcAndReply(length_tx);
150 | } while (false);
151 |
152 | _usart.setReady();
153 | length_rx = 0;
154 | }
155 | }
156 |
157 | bool SlaveRtu::checkFrameCrc(const uint8_t *p, uint8_t length) {
158 | uint16_t crc0 = crc.calc(p, length - 2);
159 | uint16_t crc1 = p[length - 2] | (p[length - 1] << 8);
160 | return crc0 == crc1;
161 | }
162 |
163 | void SlaveRtu::appendCrcAndReply(uint8_t length_tx) {
164 | uint16_t v = crc.calc(_buff_tx, length_tx);
165 | _buff_tx[length_tx] = lowByte(v);
166 | _buff_tx[length_tx + 1] = highByte(v);
167 | _usart.write(_buff_tx, length_tx + 2);
168 | _usart.flush();
169 | }
170 |
171 | void SlaveRtu::setCoil(uint16_t index, BitAction state) {
172 | assert_param(index < _coil_length);
173 | bitWrite(_coils[index >> 3], index & 0x07, state == Bit_SET);
174 | }
175 |
176 | BitAction SlaveRtu::getCoil(uint16_t index) {
177 | assert_param(index < _coil_length);
178 | return bitRead(_coils[index >> 3],index & 0x07) ? Bit_SET : Bit_RESET;
179 | }
180 |
181 | uint8_t SlaveRtu::onReadCoils(uint8_t * p_length_tx) {
182 |
183 | uint16_t length = make16(_buff_rx[4], _buff_rx[5]);
184 | if (!length || length > 0x07d0) return 0x03;
185 |
186 | uint16_t address = make16(_buff_rx[2], _buff_rx[3]);
187 | if (address + length > _coil_length) return 0x02;
188 |
189 | for (uint16_t i = 0; i < length; i++) {
190 | bitWrite(_buff_tx[3 + (i >> 3)], i & 0x07,
191 | this->getCoil(address + i) == Bit_SET);
192 | }
193 |
194 | _buff_tx[2] = (length + 7) >> 3;
195 |
196 | *p_length_tx = 3 + _buff_tx[2];
197 | return 0;
198 | }
199 |
200 | void SlaveRtu::setBitInput(uint16_t index, BitAction state) {
201 | assert_param(index < _bit_input_length);
202 | bitWrite(_bit_inputs[index >> 3], index & 0x07, state == Bit_SET);
203 | }
204 |
205 | BitAction SlaveRtu::getBitInput(uint16_t index) {
206 | assert_param(index < _bit_input_length);
207 | return bitRead(_bit_inputs[index >> 3], index & 0x07) ? Bit_SET : Bit_RESET;
208 | }
209 |
210 | uint8_t SlaveRtu::onReadBitInputs(uint8_t * p_length_tx) {
211 | uint16_t length = make16(_buff_rx[4], _buff_rx[5]);
212 | if (!length || length > 0x07d0) return 0x03;
213 |
214 | uint16_t address = make16(_buff_rx[2], _buff_rx[3]);
215 | if (address + length > _bit_input_length) return 0x02;
216 |
217 | if (updateBitInputs(address, length)) return 0x04;
218 |
219 | for (uint16_t i = 0; i < length; i++)
220 | bitWrite(_buff_tx[3 + (i >> 3)], i & 0x07,
221 | this->getBitInput(address + i) == Bit_SET);
222 |
223 | _buff_tx[2] = (length + 7) >> 3;
224 |
225 | *p_length_tx = 3 + _buff_tx[2];
226 | return 0;
227 | }
228 |
229 | uint8_t SlaveRtu::onWriteSingleCoil(uint8_t * p_length_tx) {
230 | uint16_t val = make16(_buff_rx[4], _buff_rx[5]);
231 | if (val && val != 0xff00) return 0x03;
232 |
233 | uint16_t address = make16(_buff_rx[2], _buff_rx[3]);
234 | if (address >= _coil_length) return 0x02;
235 |
236 | this->setCoil(address, val ? Bit_SET : Bit_RESET);
237 |
238 | if (updateCoils(address, 1)) return 0x04;
239 |
240 | memcpy(_buff_tx + 2, _buff_rx + 2, 4);
241 | *p_length_tx = 6;
242 | return 0;
243 | }
244 |
245 | uint8_t SlaveRtu::onWriteMultipleCoils(uint8_t length_rx,
246 | uint8_t * p_length_tx) {
247 | uint16_t length = make16(_buff_rx[4], _buff_rx[5]);
248 | if (!length || length > 0x07b0) return 0x03;
249 | if (length_rx - 9 != _buff_rx[6]) return 0x03;
250 |
251 | uint16_t index = make16(_buff_rx[2], _buff_rx[3]);
252 | if (index + length > _coil_length) return 0x02;
253 |
254 | for (uint16_t i = 0; i < length; i++)
255 | this->setCoil(index + i,
256 | bitRead(_buff_rx[7 + (i >> 3)], i & 0x07) ? Bit_SET : Bit_RESET);
257 |
258 | if (updateCoils(index, length)) return 0x04;
259 |
260 | memcpy(_buff_tx + 2, _buff_rx + 2, 4);
261 | *p_length_tx = 6;
262 | return 0;
263 | }
264 |
265 | uint8_t SlaveRtu::onReadShortInputs(uint8_t * p_length_tx) {
266 | uint16_t length = make16(_buff_rx[4], _buff_rx[5]);
267 | if (!length || length > 0x07d) return 0x03;
268 |
269 | uint16_t index = make16(_buff_rx[2], _buff_rx[3]);
270 | if (index + length > _short_input_length) return 0x02;
271 |
272 | if (updateShortInputs(index, length)) return 0x04;
273 |
274 | for (uint8_t i = 0; i < length; i++) {
275 | _buff_tx[3 + i + i] = highByte(_short_inputs[index + i]);
276 | _buff_tx[4 + i + i] = lowByte(_short_inputs[index + i]);
277 | }
278 |
279 | _buff_tx[2] = length * 2;
280 | *p_length_tx = _buff_tx[2] + 3;
281 | return 0;
282 | }
283 |
284 | void SlaveRtu::setShortInput(uint16_t index, uint16_t val) {
285 | assert_param(index < _short_input_length);
286 | _short_inputs[index] = val;
287 | }
288 |
289 | uint16_t SlaveRtu::getShortInput(uint16_t index) {
290 | assert_param(index < _short_input_length);
291 | return _short_inputs[index];
292 | }
293 |
294 | uint8_t SlaveRtu::onReadHoldings(uint8_t * p_length_tx) {
295 | uint16_t length = make16(_buff_rx[4], _buff_rx[5]);
296 | if (!length || length > 0x07d) return 0x03;
297 |
298 | uint16_t index = make16(_buff_rx[2], _buff_rx[3]);
299 | if (index + length > _holding_length) return 0x02;
300 |
301 | for (uint8_t i = 0; i < length; i++) {
302 | _buff_tx[3 + i + i] = highByte(_holdings[index + i]);
303 | _buff_tx[4 + i + i] = lowByte(_holdings[index + i]);
304 | }
305 |
306 | _buff_tx[2] = length * 2;
307 | *p_length_tx = _buff_tx[2] + 3;
308 | return 0;
309 | }
310 |
311 | void SlaveRtu::setHolding(uint16_t index, uint16_t val) {
312 | assert_param(index < _holding_length);
313 | _holdings[index] = val;
314 | }
315 |
316 | uint16_t SlaveRtu::getHolding(uint16_t index) {
317 | assert_param(index < _holding_length);
318 | return _holdings[index];
319 | }
320 |
321 | uint8_t SlaveRtu::onWriteSingleHolding(uint8_t * p_length_tx) {
322 | uint16_t val = make16(_buff_rx[4], _buff_rx[5]);
323 |
324 | uint16_t index = make16(_buff_rx[2], _buff_rx[3]);
325 | if (index >= _holding_length) return 0x02;
326 |
327 | this->setHolding(index, val);
328 |
329 | if (updateHoldings(index, 1)) return 0x04;
330 |
331 | memcpy(_buff_tx + 2, _buff_rx + 2, 4);
332 | *p_length_tx = 6;
333 | return 0;
334 | }
335 |
336 | uint8_t SlaveRtu::onWriteMultipleHoldings(uint8_t length_rx,
337 | uint8_t * p_length_tx) {
338 | uint16_t length = make16(_buff_rx[4], _buff_rx[5]);
339 | if (!length || length > 0x7b) return 0x03;
340 | if (length_rx - 9 != _buff_rx[6]) return 0x03;
341 | if (length != _buff_rx[6] >> 1) return 0x03;
342 |
343 | uint16_t index = make16(_buff_rx[2], _buff_rx[3]);
344 | if (index + length > _holding_length) return 0x02;
345 |
346 | for (uint8_t i = 0; i < length; i++) {
347 | _holdings[index + i] =
348 | make16(_buff_rx[7 + i + i], _buff_rx[8 + i + i]);
349 | }
350 |
351 | if (updateHoldings(index, length)) return 0x04;
352 |
353 | memcpy(_buff_tx + 2, _buff_rx + 2, 4);
354 | *p_length_tx = 6;
355 | return 0;
356 | }
357 |
358 |
--------------------------------------------------------------------------------
/modbus/slave-rtu.h:
--------------------------------------------------------------------------------
1 | /*
2 | * slave-rtu.h
3 | *
4 | * Created on: Jul 17, 2013
5 | * Author: agu
6 | */
7 |
8 | #ifndef SLAVE_RTU_H_
9 | #define SLAVE_RTU_H_
10 |
11 | #include
12 | #include
13 |
14 | #include "stm32f10x.h"
15 |
16 | #include "usart-rs485-modbus.h"
17 | #include "nvic/nvic.h"
18 | #include "gpio/gpio.h"
19 | #include "common/bit_op.h"
20 |
21 | #include "crc.h"
22 |
23 | /**
24 | * SlaveRtu class
25 | * get me
26 | */
27 |
28 | class SlaveRtu {
29 | public:
30 | SlaveRtu(UsartRs485Modbus & usart, uint8_t address);
31 | virtual ~SlaveRtu();
32 |
33 | void init();
34 | void setAddress(uint8_t address);
35 | void handler();
36 | void handleTimIrq();
37 |
38 | void initBitInputs(uint16_t length);
39 | void initShortInputs(uint16_t length);
40 |
41 | void initCoils(uint16_t length);
42 | void initHoldings(uint16_t length);
43 |
44 | void setBitInput(uint16_t index, BitAction state);
45 | BitAction getBitInput(uint16_t index);
46 |
47 | void setShortInput(uint16_t index, uint16_t val);
48 | uint16_t getShortInput(uint16_t index);
49 |
50 | void setCoil(uint16_t index, BitAction state);
51 | BitAction getCoil(uint16_t index);
52 |
53 | void setHolding(uint16_t index, uint16_t val);
54 | uint16_t getHolding(uint16_t index);
55 |
56 | protected:
57 |
58 | int16_t _coil_length;
59 | uint16_t _bit_input_length;
60 | uint16_t _short_input_length;
61 | uint16_t _holding_length;
62 |
63 | virtual uint8_t updateBitInputs(uint16_t index, uint16_t length) {return 0;};
64 | virtual uint8_t updateShortInputs(uint16_t index, uint16_t length) {return 0;};
65 | virtual uint8_t updateCoils(uint16_t index, uint16_t length) {return 0;};
66 | virtual uint8_t updateHoldings(uint16_t index, uint16_t length) {return 0;};
67 |
68 | private:
69 | UsartRs485Modbus & _usart;
70 |
71 | static const uint16_t _BUFF_LENGTH = 256;
72 | uint8_t _buff_rx[_BUFF_LENGTH];
73 | uint8_t _buff_tx[_BUFF_LENGTH];
74 |
75 | uint8_t _address;
76 |
77 | uint8_t * _bit_inputs;
78 | uint16_t * _short_inputs;
79 | uint8_t * _coils;
80 | uint16_t * _holdings;
81 |
82 | bool checkFrameCrc(const uint8_t *p, uint8_t length);
83 | void appendCrcAndReply(uint8_t length_tx);
84 |
85 | uint8_t onReadBitInputs(uint8_t * p_length_tx);
86 | uint8_t onReadShortInputs(uint8_t * p_length_tx);
87 |
88 | uint8_t onReadCoils(uint8_t * p_length_tx);
89 | uint8_t onWriteSingleCoil(uint8_t * p_length_tx);
90 | uint8_t onWriteMultipleCoils(uint8_t length_rx, uint8_t * p_length_tx);
91 |
92 | uint8_t onReadHoldings(uint8_t * p_length_tx);
93 | uint8_t onWriteSingleHolding(uint8_t * p_length_tx);
94 | uint8_t onWriteMultipleHoldings(uint8_t length_rx, uint8_t * p_length_tx);
95 | };
96 |
97 | #endif /* SLAVE_RTU_H_ */
98 |
--------------------------------------------------------------------------------
/modbus/usart-rs485-modbus.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * usart.cpp
3 | *
4 | * Created on: May 28, 2013
5 | * Author: agu
6 | */
7 |
8 | #include "usart-rs485-modbus.h"
9 |
10 | UsartRs485Modbus::UsartRs485Modbus(USART_TypeDef * usart, uint32_t rcc_apbx_periph,
11 | void (*rcc_apbx_periph_clock_cmd)(uint32_t, FunctionalState), Gpio & de,
12 | Gpio & re, Tim & tim, uint8_t buff_size, uint16_t time_out) :
13 | UsartRs485(usart, rcc_apbx_periph, rcc_apbx_periph_clock_cmd, de, re, buff_size,
14 | time_out), _tim(tim) {
15 | _is_receiving = true;
16 | }
17 |
18 | UsartRs485Modbus::~UsartRs485Modbus() {
19 |
20 | }
21 |
22 | void UsartRs485Modbus::init(uint32_t baudrate, uint16_t word_length,
23 | uint16_t stop_bits, uint16_t parity, uint16_t mode,
24 | uint16_t hardware_flow_control) {
25 |
26 | this->UsartRs485::init(baudrate, word_length, stop_bits, parity, mode,
27 | hardware_flow_control);
28 |
29 | // t = 11 * 3.5 / baudrate / (1 / 20000)
30 | _tim.init(20000, (770000UL / baudrate));
31 | _tim.configureIT(TIM_IT_Update);
32 | _tim.configureArrPreload();
33 |
34 | _tim.setCounter(0x0000);
35 | //_tim.setState(ENABLE);
36 | }
37 |
38 | void UsartRs485Modbus::onRXNE() {
39 | this->UsartRs485::onRXNE();
40 | _tim.setCounter(0x0000);
41 | _tim.setState(ENABLE);
42 | }
43 |
44 | void UsartRs485Modbus::onTimIrq() {
45 | if (_tim.getITStatus(TIM_IT_Update) == SET) {
46 | _tim.clearITPendingBit(TIM_IT_Update);
47 | _tim.setState(DISABLE);
48 | _is_receiving = false;
49 | }
50 | }
51 |
52 | bool UsartRs485Modbus::isReceiving() {
53 | return _is_receiving;
54 | }
55 |
56 | void UsartRs485Modbus::setReady() {
57 | _is_receiving = true;
58 | }
59 |
--------------------------------------------------------------------------------
/modbus/usart-rs485-modbus.h:
--------------------------------------------------------------------------------
1 | /*
2 | * usart.h
3 | *
4 | * Created on: May 28, 2013
5 | * Author: agu
6 | */
7 |
8 | #ifndef USART_RS485_MODBUS_H_
9 | #define USART_RS485_MODBUS_H_
10 |
11 | #include "usart-rs485/usart-rs485.h"
12 | #include "gpio/gpio.h"
13 | #include "tim/tim.h"
14 |
15 | #include
16 |
17 | class UsartRs485Modbus: public UsartRs485 {
18 | public:
19 | UsartRs485Modbus(USART_TypeDef * usart,
20 | uint32_t rcc_apbx_periph,
21 | void (*rcc_apbx_periph_clock_cmd)(uint32_t, FunctionalState),
22 | Gpio & de, Gpio & re, Tim & tim,
23 | uint8_t buff_size = 128,
24 | uint16_t time_out = 4);
25 | ~UsartRs485Modbus();
26 |
27 | void init(uint32_t baudrate = 19200,
28 | uint16_t word_length = USART_WordLength_9b,
29 | uint16_t stop_bits = USART_StopBits_1,
30 | uint16_t parity = USART_Parity_Even,
31 | uint16_t mode = USART_Mode_Rx | USART_Mode_Tx,
32 | uint16_t hardware_flow_control = USART_HardwareFlowControl_None);
33 |
34 | void onTimIrq();
35 | bool isReceiving();
36 | void setReady();
37 |
38 | protected:
39 | void onRXNE();
40 |
41 | private:
42 | Tim & _tim;
43 | volatile bool _is_receiving;
44 | };
45 |
46 | #endif /* USART_RS485_MODBUS_H_ */
47 |
48 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | /**
2 | @page GPIO_IOToggle GPIO IO Toggle example
3 |
4 | @verbatim
5 | ******************** (C) COPYRIGHT 2011 STMicroelectronics *******************
6 | * @file GPIO/IOToggle/readme.txt
7 | * @author MCD Application Team
8 | * @version V3.5.0
9 | * @date 08-April-2011
10 | * @brief Description of the GPIO IO Toggle example.
11 | ******************************************************************************
12 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
13 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
14 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
15 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
16 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
17 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
18 | ******************************************************************************
19 | @endverbatim
20 |
21 | @par Example Description
22 |
23 | GPIO ports are connected on APB2 bus, using BSRRH and BSRRL registers 2 cycles
24 | are required to set a pin and another cycle to reset it. So GPIO pins can toggle
25 | at AHB clock divided by 4.
26 |
27 | This example describes how to use BSRR and BRR (Port Bit Set/Reset Register
28 | and Port Bit Reset Register) for maximum IO toggling.
29 |
30 | PD0 and PD2 (configured in output pushpull mode) toggles in a forever loop:
31 | - Set PD0 and PD2 by setting corresponding bits in BSRR register
32 | - Reset PD0 and PD2 by setting corresponding bits in BRR register
33 |
34 | In this example, HCLK is configured at 72 MHz so PD0 and PD2 toggles at 18MHz.
35 | To achieve the maximum IO toggling frequency, you have to configure your compiler
36 | options for high speed optimization.
37 |
38 | @par Directory contents
39 |
40 | - GPIO/IOToggle/stm32f10x_conf.h Library Configuration file
41 | - GPIO/IOToggle/stm32f10x_it.c Interrupt handlers
42 | - GPIO/IOToggle/stm32f10x_it.h Header for stm32f10x_it.c
43 | - GPIO/IOToggle/main.c Main program
44 | - GPIO/IOToggle/system_stm32f10x.c STM32F10x system source file
45 |
46 | @par Hardware and Software environment
47 |
48 | - This example runs on STM32F10x Connectivity line, High-Density, High-Density
49 | Value line, Medium-Density, XL-Density, Medium-Density Value line, Low-Density
50 | and Low-Density Value line Devices.
51 |
52 | - This example has been tested with STMicroelectronics STM32100E-EVAL (High-Density
53 | Value line), STM32100B-EVAL (Medium-Density Value line), STM3210C-EVAL
54 | (Connectivity line), STM3210E-EVAL (High-Density and XL-Density) and
55 | STM3210B-EVAL (Medium-Density) evaluation boards and can be easily tailored
56 | to any other supported device and development board.
57 | To select the STMicroelectronics evaluation board used to run the example,
58 | uncomment the corresponding line in stm32_eval.h file (under Utilities\STM32_EVAL)
59 |
60 | @par How to use it ?
61 |
62 | In order to make the program work, you must do the following :
63 | - Copy all source files from this example folder to the template folder under
64 | Project\STM32F10x_StdPeriph_Template
65 | - Open your preferred toolchain
66 | - Rebuild all files and load your image into target memory
67 | - Run the example
68 |
69 | @note
70 | - Low-density Value line devices are STM32F100xx microcontrollers where the
71 | Flash memory density ranges between 16 and 32 Kbytes.
72 | - Low-density devices are STM32F101xx, STM32F102xx and STM32F103xx
73 | microcontrollers where the Flash memory density ranges between 16 and 32 Kbytes.
74 | - Medium-density Value line devices are STM32F100xx microcontrollers where
75 | the Flash memory density ranges between 64 and 128 Kbytes.
76 | - Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx
77 | microcontrollers where the Flash memory density ranges between 64 and 128 Kbytes.
78 | - High-density Value line devices are STM32F100xx microcontrollers where
79 | the Flash memory density ranges between 256 and 512 Kbytes.
80 | - High-density devices are STM32F101xx and STM32F103xx microcontrollers where
81 | the Flash memory density ranges between 256 and 512 Kbytes.
82 | - XL-density devices are STM32F101xx and STM32F103xx microcontrollers where
83 | the Flash memory density ranges between 512 and 1024 Kbytes.
84 | - Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.
85 |
86 | * © COPYRIGHT 2011 STMicroelectronics
87 | */
88 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "stm32-template.h"
2 | #include "gpio-array/gpio-array.h"
3 | #include "node.h"
4 |
5 | int main(void) __attribute__((weak));
6 |
7 | Gpio usart_de(GPIOB, GPIO_Pin_15, RCC_APB2Periph_GPIOB);
8 | Gpio usart_re(GPIOB, GPIO_Pin_15, RCC_APB2Periph_GPIOB);
9 |
10 | Tim t1(TIM1, RCC_APB2Periph_TIM1, RCC_APB2PeriphClockCmd);
11 | UsartRs485Modbus usart(USART1, RCC_APB2Periph_USART1, RCC_APB2PeriphClockCmd,
12 | usart_de, usart_re, t1);
13 |
14 | Gpio led_green(GPIOC, GPIO_Pin_9, RCC_APB2Periph_GPIOC);
15 | Gpio led_blue(GPIOC, GPIO_Pin_8, RCC_APB2Periph_GPIOC);
16 |
17 | Node slave(usart, 0x02);
18 |
19 | Gpio dip_0(GPIOB, GPIO_Pin_14, RCC_APB2Periph_GPIOB);
20 | Gpio dip_1(GPIOB, GPIO_Pin_13, RCC_APB2Periph_GPIOB);
21 | Gpio dip_2(GPIOB, GPIO_Pin_12, RCC_APB2Periph_GPIOB);
22 | Gpio dip_3(GPIOB, GPIO_Pin_11, RCC_APB2Periph_GPIOB);
23 | Gpio dip_4(GPIOB, GPIO_Pin_10, RCC_APB2Periph_GPIOB);
24 | Gpio dip_5(GPIOB, GPIO_Pin_0, RCC_APB2Periph_GPIOB);
25 | Gpio dip_6(GPIOB, GPIO_Pin_1, RCC_APB2Periph_GPIOB);
26 | GpioArray dips(7);
27 |
28 | void setup() {
29 | dips.setGpio(0, dip_0);
30 | dips.setGpio(1, dip_1);
31 | dips.setGpio(2, dip_2);
32 | dips.setGpio(3, dip_3);
33 | dips.setGpio(4, dip_4);
34 | dips.setGpio(5, dip_5);
35 | dips.setGpio(6, dip_6);
36 |
37 | dips.init(GPIO_Mode_IPU);
38 | slave.setAddress(dips.getInput());
39 | }
40 |
41 | int main(void) {
42 | init();
43 | setup();
44 | slave.init();
45 |
46 | for (;;)
47 | slave.handler();
48 | }
49 |
50 | void init() {
51 | SysTick_Config(SystemCoreClock / 1000); // Tick per ms
52 |
53 | Gpio usart_tx(GPIOA, GPIO_Pin_9,
54 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO);
55 | usart_tx.init(GPIO_Mode_AF_OD);
56 |
57 | Gpio usart_rx(GPIOA, GPIO_Pin_10,
58 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO);
59 | usart_rx.init(GPIO_Mode_IN_FLOATING);
60 |
61 | setvbuf(stdin, NULL, _IONBF, 0);
62 | setvbuf(stdout, NULL, _IONBF, 0);
63 | setvbuf(stderr, NULL, _IONBF, 0);
64 |
65 | nvic.configureGroup(NVIC_PriorityGroup_1);
66 | nvic.configure(TIM1_UP_TIM16_IRQn, 0, 3, ENABLE);
67 | nvic.configure(USART1_IRQn, 1, 2, ENABLE);
68 |
69 | led_green.init(GPIO_Mode_Out_PP);
70 |
71 | nvic.configure(TIM2_IRQn, 1, 3, ENABLE);
72 | Tim t2(TIM2, RCC_APB1Periph_TIM2, RCC_APB1PeriphClockCmd);
73 | t2.init(1000, 1000);
74 | t2.configureIT(TIM_IT_Update);
75 | t2.setState();
76 | }
77 |
78 | void delay(u32 ms) {
79 | extern vu32 millis;
80 | uint32_t start = millis;
81 |
82 | while (ms) {
83 | if (millis - start) {
84 | ms--;
85 | start++;
86 | }
87 | }
88 | }
89 |
90 | // delayMicroseconds ref to libmaple
91 | void delayMicroseconds(vu32 us) {
92 | us *= SystemCoreClock / 3000000;
93 |
94 | asm volatile(
95 | " mov r0, %[us] \n\t"
96 | "1: subs r0, #1 \n\t"
97 | " bhi 1b \n\t"
98 | :
99 | : [us] "r" (us)
100 | : "r0"
101 | );
102 | }
103 |
104 | #ifdef USE_FULL_ASSERT
105 |
106 | void assert_failed(uint8_t* file, uint32_t line) {
107 | fprintf(stderr, "assert failed on %s, line # %ld\r\n", file, line);
108 | while (1)
109 | ;
110 | }
111 |
112 | #endif
113 |
--------------------------------------------------------------------------------
/src/node.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * node.cpp
3 | *
4 | * Created on: Jul 23, 2013
5 | * Author: agu
6 | */
7 |
8 | #include "node.h"
9 |
10 | const uint8_t Node::_uuid[] = "665247461d1c11e395bc73bf3a254a5f";
11 |
12 | const uint8_t Node::_lengths[] = { 2, 1, 2, 16 };
13 |
14 | Node::Node(UsartRs485Modbus & usart, uint8_t address) :
15 | SlaveRtu(usart, address) {
16 |
17 | this->initBitInputs(_lengths[0]);
18 | this->initCoils(_lengths[1]);
19 |
20 | this->initShortInputs(16 + 4 + _lengths[2]);
21 | this->initHoldings(_lengths[3]);
22 |
23 | _bit_input_pins = (Gpio **) malloc(_bit_input_length * sizeof(Gpio *));
24 |
25 | _bit_input_pins[0] = new Gpio(GPIOA, GPIO_Pin_0, RCC_APB2Periph_GPIOA);
26 | _bit_input_pins[1] = new Gpio(GPIOA, GPIO_Pin_1, RCC_APB2Periph_GPIOA);
27 |
28 | _coil_pins = (Gpio **) malloc(_coil_length * sizeof(Gpio *));
29 | _coil_pins[0] = new Gpio(GPIOC, GPIO_Pin_8, RCC_APB2Periph_GPIOC);
30 |
31 | _short_input_pins = (Gpio **) malloc(2 * sizeof(Gpio *));
32 | _short_input_pins[0] = new Gpio(GPIOA, GPIO_Pin_5, RCC_APB2Periph_GPIOA);
33 | _short_input_pins[1] = new Gpio(GPIOA, GPIO_Pin_6, RCC_APB2Periph_GPIOA);
34 |
35 | _adc = new Adc(ADC1, RCC_APB2Periph_ADC1);
36 | _adc_channels = new uint8_t[2];
37 | _adc_channels[0] = ADC_Channel_5;
38 | _adc_channels[1] = ADC_Channel_6;
39 |
40 | for (uint8_t i = 0; i < 16; i++) {
41 | this->setShortInput(i, make16(_uuid[i + i], _uuid[i + i + 1]));
42 | }
43 |
44 | for (uint8_t i = 0; i < 4; i++)
45 | this->setShortInput(i + 16, _lengths[i]);
46 | }
47 |
48 | Node::~Node() {
49 | for (uint8_t i = 0; i < _bit_input_length; i++)
50 | delete _bit_input_pins[i];
51 | delete[] _bit_input_pins;
52 |
53 | for (uint8_t i = 0; i < _coil_length; i++)
54 | delete _coil_pins[i];
55 | delete[] _coil_pins;
56 |
57 | for (uint8_t i = 0; i < 2; i++)
58 | delete _short_input_pins[i];
59 | delete[] _short_input_pins;
60 |
61 | delete _adc;
62 | delete _adc_channels;
63 | }
64 |
65 | void Node::init() {
66 | this->SlaveRtu::init();
67 |
68 | for (uint8_t i = 0; i < _bit_input_length; i++)
69 | _bit_input_pins[i]->init(GPIO_Mode_IPD);
70 |
71 | for (uint8_t i = 0; i < _coil_length; i++)
72 | _coil_pins[i]->init(GPIO_Mode_Out_PP);
73 |
74 | for (uint8_t i = 0; i < 2; i++)
75 | _short_input_pins[i]->init(GPIO_Mode_AIN);
76 |
77 | _adc->init(ADC_Mode_Independent, DISABLE, DISABLE,
78 | ADC_ExternalTrigConv_None);
79 | _adc->calibrate();
80 |
81 | _adc->configChannel(ADC_Channel_5, 1);
82 | }
83 |
84 | uint8_t Node::updateBitInputs(uint16_t index, uint16_t length) {
85 | for (uint16_t i = 0; i < length; i++)
86 | this->setBitInput(index + i, _bit_input_pins[index + i]->getInput());
87 | return 0;
88 | }
89 |
90 | uint8_t Node::updateCoils(uint16_t index, uint16_t length) {
91 | for (uint16_t i = 0; i < length; i++)
92 | _coil_pins[index + i]->set(this->getCoil(index + i));
93 | return 0;
94 | }
95 |
96 | uint8_t Node::updateShortInputs(uint16_t index, uint16_t length) {
97 | for (uint16_t i = 0; i < length; i++) {
98 | if (index + i >= 20) {
99 | _adc->configChannel(_adc_channels[index - 20 + i], 1);
100 | _adc->startSoftwareConvert();
101 | this->setShortInput(index + i, _adc->getValue());
102 | }
103 | }
104 | return 0;
105 | }
106 |
107 |
--------------------------------------------------------------------------------
/src/stm32f10x_it.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file stm32f10x_it.cpp
4 | * @author MCD Application Team
5 | * @version V3.5.0
6 | * @date 08-April-2011
7 | * @brief Main Interrupt Service Routines.
8 | * This file provides template for all exceptions handler and peripherals
9 | * interrupt service routine.
10 | ******************************************************************************
11 | * @attention
12 | *
13 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
14 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
15 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
16 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
17 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
18 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
19 | *
20 | * © COPYRIGHT 2011 STMicroelectronics
21 | ******************************************************************************
22 | */
23 |
24 | /* Includes ------------------------------------------------------------------*/
25 | #include "stm32f10x_it.h"
26 | #include "gpio/gpio.h"
27 | #include "modbus/slave-rtu.h"
28 |
29 | /** @addtogroup STM32F10x_StdPeriph_Examples
30 | * @{
31 | */
32 |
33 | /** @addtogroup GPIO_IOToggle
34 | * @{
35 | */
36 |
37 | /* Private typedef -----------------------------------------------------------*/
38 | /* Private define ------------------------------------------------------------*/
39 | /* Private macro -------------------------------------------------------------*/
40 | /* Private variables ---------------------------------------------------------*/
41 | /* Private function prototypes -----------------------------------------------*/
42 | /* Private functions ---------------------------------------------------------*/
43 |
44 | /******************************************************************************/
45 | /* Cortex-M3 Processor Exceptions Handlers */
46 | /******************************************************************************/
47 |
48 | /**
49 | * @brief This function handles NMI exception.
50 | * @retval None
51 | */
52 | void NMI_Handler(void) {
53 | }
54 |
55 | /**
56 | * @brief This function handles Hard Fault exception.
57 | * @retval None
58 | */
59 | void HardFault_Handler(void) {
60 | /* Go to infinite loop when Hard Fault exception occurs */
61 | while (1) {
62 | }
63 | }
64 |
65 | /**
66 | * @brief This function handles Memory Manage exception.
67 | * @retval None
68 | */
69 | void MemManage_Handler(void) {
70 | /* Go to infinite loop when Memory Manage exception occurs */
71 | while (1) {
72 | }
73 | }
74 |
75 | /**
76 | * @brief This function handles Bus Fault exception.
77 | * @retval None
78 | */
79 | void BusFault_Handler(void) {
80 | /* Go to infinite loop when Bus Fault exception occurs */
81 | while (1) {
82 | }
83 | }
84 |
85 | /**
86 | * @brief This function handles Usage Fault exception.
87 | * @retval None
88 | */
89 | void UsageFault_Handler(void) {
90 | /* Go to infinite loop when Usage Fault exception occurs */
91 | while (1) {
92 | }
93 | }
94 |
95 | /**
96 | * @brief This function handles SVCall exception.
97 | * @retval None
98 | */
99 | void SVC_Handler(void) {
100 | }
101 |
102 | /**
103 | * @brief This function handles Debug Monitor exception.
104 | * @retval None
105 | */
106 | void DebugMon_Handler(void) {
107 | }
108 |
109 | /**
110 | * @brief This function handles PendSV_Handler exception.
111 | * @retval None
112 | */
113 | void PendSV_Handler(void) {
114 | }
115 |
116 | /**
117 | * @brief This function handles SysTick Handler.
118 | * @param None
119 | * @retval None
120 | */
121 |
122 | //vu32 TimingDelay = 0;
123 | vu32 millis = 0;
124 |
125 | void SysTick_Handler(void) {
126 | millis++;
127 | }
128 |
129 | /******************************************************************************/
130 | /* STM32F10x Peripherals Interrupt Handlers */
131 | /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
132 | /* available peripheral interrupt handler's name please refer to the startup */
133 | /* file (startup_stm32f10x_xx.s). */
134 | /******************************************************************************/
135 |
136 | /**
137 | * @brief This function handles PPP interrupt request.
138 | * @retval None
139 | */
140 | /*void PPP_IRQHandler(void)
141 | {
142 | }*/
143 |
144 | void TIM2_IRQHandler(void) {
145 | extern Gpio led_green;
146 |
147 | if (TIM_GetITStatus(TIM2, TIM_IT_Update)) {
148 | TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
149 | led_green.toggle();
150 | }
151 | }
152 |
153 | void USART1_IRQHandler(void) {
154 | extern UsartRs485Modbus usart;
155 | usart.ithandler();
156 | }
157 |
158 | void TIM1_UP_TIM16_IRQHandler(void) {
159 | extern UsartRs485Modbus usart;
160 | usart.onTimIrq();
161 | }
162 | /**
163 | * @}
164 | */
165 |
166 | /**
167 | * @}
168 | */
169 |
170 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
171 |
--------------------------------------------------------------------------------
/stm32_flash.ld:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aguegu/stm32-modbus/9ea4504e134e74652d6a87873a13852d730b6ca2/stm32_flash.ld
--------------------------------------------------------------------------------
/sys/core_cm3.c:
--------------------------------------------------------------------------------
1 | /**************************************************************************//**
2 | * @file core_cm3.c
3 | * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
4 | * @version V1.30
5 | * @date 30. October 2009
6 | *
7 | * @note
8 | * Copyright (C) 2009 ARM Limited. All rights reserved.
9 | *
10 | * @par
11 | * ARM Limited (ARM) is supplying this software for use with Cortex-M
12 | * processor based microcontrollers. This file can be freely distributed
13 | * within development tools that are supporting such ARM based processors.
14 | *
15 | * @par
16 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
17 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
19 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
20 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
21 | *
22 | ******************************************************************************/
23 |
24 | #include
25 |
26 | /* define compiler specific symbols */
27 | #if defined ( __CC_ARM )
28 | #define __ASM __asm /*!< asm keyword for ARM Compiler */
29 | #define __INLINE __inline /*!< inline keyword for ARM Compiler */
30 |
31 | #elif defined ( __ICCARM__ )
32 | #define __ASM __asm /*!< asm keyword for IAR Compiler */
33 | #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
34 |
35 | #elif defined ( __GNUC__ )
36 | #define __ASM __asm /*!< asm keyword for GNU Compiler */
37 | #define __INLINE inline /*!< inline keyword for GNU Compiler */
38 |
39 | #elif defined ( __TASKING__ )
40 | #define __ASM __asm /*!< asm keyword for TASKING Compiler */
41 | #define __INLINE inline /*!< inline keyword for TASKING Compiler */
42 |
43 | #endif
44 |
45 | /* ################### Compiler specific Intrinsics ########################### */
46 |
47 | #if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
48 | /* ARM armcc specific functions */
49 |
50 | /**
51 | * @brief Return the Process Stack Pointer
52 | *
53 | * @return ProcessStackPointer
54 | *
55 | * Return the actual process stack pointer
56 | */
57 | __ASM uint32_t __get_PSP(void)
58 | {
59 | mrs r0, psp
60 | bx lr
61 | }
62 |
63 | /**
64 | * @brief Set the Process Stack Pointer
65 | *
66 | * @param topOfProcStack Process Stack Pointer
67 | *
68 | * Assign the value ProcessStackPointer to the MSP
69 | * (process stack pointer) Cortex processor register
70 | */
71 | __ASM void __set_PSP(uint32_t topOfProcStack)
72 | {
73 | msr psp, r0
74 | bx lr
75 | }
76 |
77 | /**
78 | * @brief Return the Main Stack Pointer
79 | *
80 | * @return Main Stack Pointer
81 | *
82 | * Return the current value of the MSP (main stack pointer)
83 | * Cortex processor register
84 | */
85 | __ASM uint32_t __get_MSP(void)
86 | {
87 | mrs r0, msp
88 | bx lr
89 | }
90 |
91 | /**
92 | * @brief Set the Main Stack Pointer
93 | *
94 | * @param topOfMainStack Main Stack Pointer
95 | *
96 | * Assign the value mainStackPointer to the MSP
97 | * (main stack pointer) Cortex processor register
98 | */
99 | __ASM void __set_MSP(uint32_t mainStackPointer)
100 | {
101 | msr msp, r0
102 | bx lr
103 | }
104 |
105 | /**
106 | * @brief Reverse byte order in unsigned short value
107 | *
108 | * @param value value to reverse
109 | * @return reversed value
110 | *
111 | * Reverse byte order in unsigned short value
112 | */
113 | __ASM uint32_t __REV16(uint16_t value)
114 | {
115 | rev16 r0, r0
116 | bx lr
117 | }
118 |
119 | /**
120 | * @brief Reverse byte order in signed short value with sign extension to integer
121 | *
122 | * @param value value to reverse
123 | * @return reversed value
124 | *
125 | * Reverse byte order in signed short value with sign extension to integer
126 | */
127 | __ASM int32_t __REVSH(int16_t value)
128 | {
129 | revsh r0, r0
130 | bx lr
131 | }
132 |
133 | #if (__ARMCC_VERSION < 400000)
134 |
135 | /**
136 | * @brief Remove the exclusive lock created by ldrex
137 | *
138 | * Removes the exclusive lock which is created by ldrex.
139 | */
140 | __ASM void __CLREX(void)
141 | {
142 | clrex
143 | }
144 |
145 | /**
146 | * @brief Return the Base Priority value
147 | *
148 | * @return BasePriority
149 | *
150 | * Return the content of the base priority register
151 | */
152 | __ASM uint32_t __get_BASEPRI(void)
153 | {
154 | mrs r0, basepri
155 | bx lr
156 | }
157 |
158 | /**
159 | * @brief Set the Base Priority value
160 | *
161 | * @param basePri BasePriority
162 | *
163 | * Set the base priority register
164 | */
165 | __ASM void __set_BASEPRI(uint32_t basePri)
166 | {
167 | msr basepri, r0
168 | bx lr
169 | }
170 |
171 | /**
172 | * @brief Return the Priority Mask value
173 | *
174 | * @return PriMask
175 | *
176 | * Return state of the priority mask bit from the priority mask register
177 | */
178 | __ASM uint32_t __get_PRIMASK(void)
179 | {
180 | mrs r0, primask
181 | bx lr
182 | }
183 |
184 | /**
185 | * @brief Set the Priority Mask value
186 | *
187 | * @param priMask PriMask
188 | *
189 | * Set the priority mask bit in the priority mask register
190 | */
191 | __ASM void __set_PRIMASK(uint32_t priMask)
192 | {
193 | msr primask, r0
194 | bx lr
195 | }
196 |
197 | /**
198 | * @brief Return the Fault Mask value
199 | *
200 | * @return FaultMask
201 | *
202 | * Return the content of the fault mask register
203 | */
204 | __ASM uint32_t __get_FAULTMASK(void)
205 | {
206 | mrs r0, faultmask
207 | bx lr
208 | }
209 |
210 | /**
211 | * @brief Set the Fault Mask value
212 | *
213 | * @param faultMask faultMask value
214 | *
215 | * Set the fault mask register
216 | */
217 | __ASM void __set_FAULTMASK(uint32_t faultMask)
218 | {
219 | msr faultmask, r0
220 | bx lr
221 | }
222 |
223 | /**
224 | * @brief Return the Control Register value
225 | *
226 | * @return Control value
227 | *
228 | * Return the content of the control register
229 | */
230 | __ASM uint32_t __get_CONTROL(void)
231 | {
232 | mrs r0, control
233 | bx lr
234 | }
235 |
236 | /**
237 | * @brief Set the Control Register value
238 | *
239 | * @param control Control value
240 | *
241 | * Set the control register
242 | */
243 | __ASM void __set_CONTROL(uint32_t control)
244 | {
245 | msr control, r0
246 | bx lr
247 | }
248 |
249 | #endif /* __ARMCC_VERSION */
250 |
251 | #elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
252 | /* IAR iccarm specific functions */
253 | #pragma diag_suppress=Pe940
254 |
255 | /**
256 | * @brief Return the Process Stack Pointer
257 | *
258 | * @return ProcessStackPointer
259 | *
260 | * Return the actual process stack pointer
261 | */
262 | uint32_t __get_PSP(void)
263 | {
264 | __ASM("mrs r0, psp");
265 | __ASM("bx lr");
266 | }
267 |
268 | /**
269 | * @brief Set the Process Stack Pointer
270 | *
271 | * @param topOfProcStack Process Stack Pointer
272 | *
273 | * Assign the value ProcessStackPointer to the MSP
274 | * (process stack pointer) Cortex processor register
275 | */
276 | void __set_PSP(uint32_t topOfProcStack)
277 | {
278 | __ASM("msr psp, r0");
279 | __ASM("bx lr");
280 | }
281 |
282 | /**
283 | * @brief Return the Main Stack Pointer
284 | *
285 | * @return Main Stack Pointer
286 | *
287 | * Return the current value of the MSP (main stack pointer)
288 | * Cortex processor register
289 | */
290 | uint32_t __get_MSP(void)
291 | {
292 | __ASM("mrs r0, msp");
293 | __ASM("bx lr");
294 | }
295 |
296 | /**
297 | * @brief Set the Main Stack Pointer
298 | *
299 | * @param topOfMainStack Main Stack Pointer
300 | *
301 | * Assign the value mainStackPointer to the MSP
302 | * (main stack pointer) Cortex processor register
303 | */
304 | void __set_MSP(uint32_t topOfMainStack)
305 | {
306 | __ASM("msr msp, r0");
307 | __ASM("bx lr");
308 | }
309 |
310 | /**
311 | * @brief Reverse byte order in unsigned short value
312 | *
313 | * @param value value to reverse
314 | * @return reversed value
315 | *
316 | * Reverse byte order in unsigned short value
317 | */
318 | uint32_t __REV16(uint16_t value)
319 | {
320 | __ASM("rev16 r0, r0");
321 | __ASM("bx lr");
322 | }
323 |
324 | /**
325 | * @brief Reverse bit order of value
326 | *
327 | * @param value value to reverse
328 | * @return reversed value
329 | *
330 | * Reverse bit order of value
331 | */
332 | uint32_t __RBIT(uint32_t value)
333 | {
334 | __ASM("rbit r0, r0");
335 | __ASM("bx lr");
336 | }
337 |
338 | /**
339 | * @brief LDR Exclusive (8 bit)
340 | *
341 | * @param *addr address pointer
342 | * @return value of (*address)
343 | *
344 | * Exclusive LDR command for 8 bit values)
345 | */
346 | uint8_t __LDREXB(uint8_t *addr)
347 | {
348 | __ASM("ldrexb r0, [r0]");
349 | __ASM("bx lr");
350 | }
351 |
352 | /**
353 | * @brief LDR Exclusive (16 bit)
354 | *
355 | * @param *addr address pointer
356 | * @return value of (*address)
357 | *
358 | * Exclusive LDR command for 16 bit values
359 | */
360 | uint16_t __LDREXH(uint16_t *addr)
361 | {
362 | __ASM("ldrexh r0, [r0]");
363 | __ASM("bx lr");
364 | }
365 |
366 | /**
367 | * @brief LDR Exclusive (32 bit)
368 | *
369 | * @param *addr address pointer
370 | * @return value of (*address)
371 | *
372 | * Exclusive LDR command for 32 bit values
373 | */
374 | uint32_t __LDREXW(uint32_t *addr)
375 | {
376 | __ASM("ldrex r0, [r0]");
377 | __ASM("bx lr");
378 | }
379 |
380 | /**
381 | * @brief STR Exclusive (8 bit)
382 | *
383 | * @param value value to store
384 | * @param *addr address pointer
385 | * @return successful / failed
386 | *
387 | * Exclusive STR command for 8 bit values
388 | */
389 | uint32_t __STREXB(uint8_t value, uint8_t *addr)
390 | {
391 | __ASM("strexb r0, r0, [r1]");
392 | __ASM("bx lr");
393 | }
394 |
395 | /**
396 | * @brief STR Exclusive (16 bit)
397 | *
398 | * @param value value to store
399 | * @param *addr address pointer
400 | * @return successful / failed
401 | *
402 | * Exclusive STR command for 16 bit values
403 | */
404 | uint32_t __STREXH(uint16_t value, uint16_t *addr)
405 | {
406 | __ASM("strexh r0, r0, [r1]");
407 | __ASM("bx lr");
408 | }
409 |
410 | /**
411 | * @brief STR Exclusive (32 bit)
412 | *
413 | * @param value value to store
414 | * @param *addr address pointer
415 | * @return successful / failed
416 | *
417 | * Exclusive STR command for 32 bit values
418 | */
419 | uint32_t __STREXW(uint32_t value, uint32_t *addr)
420 | {
421 | __ASM("strex r0, r0, [r1]");
422 | __ASM("bx lr");
423 | }
424 |
425 | #pragma diag_default=Pe940
426 |
427 | #elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
428 | /* GNU gcc specific functions */
429 |
430 | /**
431 | * @brief Return the Process Stack Pointer
432 | *
433 | * @return ProcessStackPointer
434 | *
435 | * Return the actual process stack pointer
436 | */
437 | uint32_t __get_PSP(void) __attribute__( ( naked ) );
438 | uint32_t __get_PSP(void) {
439 | uint32_t result = 0;
440 |
441 | __ASM volatile ("MRS %0, psp\n\t"
442 | "MOV r0, %0 \n\t"
443 | "BX lr \n\t" : "=r" (result) );
444 | return (result);
445 | }
446 |
447 | /**
448 | * @brief Set the Process Stack Pointer
449 | *
450 | * @param topOfProcStack Process Stack Pointer
451 | *
452 | * Assign the value ProcessStackPointer to the MSP
453 | * (process stack pointer) Cortex processor register
454 | */
455 | void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
456 | void __set_PSP(uint32_t topOfProcStack) {
457 | __ASM volatile ("MSR psp, %0\n\t"
458 | "BX lr \n\t" : : "r" (topOfProcStack) );
459 | }
460 |
461 | /**
462 | * @brief Return the Main Stack Pointer
463 | *
464 | * @return Main Stack Pointer
465 | *
466 | * Return the current value of the MSP (main stack pointer)
467 | * Cortex processor register
468 | */
469 | uint32_t __get_MSP(void) __attribute__( ( naked ) );
470 | uint32_t __get_MSP(void) {
471 | uint32_t result = 0;
472 |
473 | __ASM volatile ("MRS %0, msp\n\t"
474 | "MOV r0, %0 \n\t"
475 | "BX lr \n\t" : "=r" (result) );
476 | return (result);
477 | }
478 |
479 | /**
480 | * @brief Set the Main Stack Pointer
481 | *
482 | * @param topOfMainStack Main Stack Pointer
483 | *
484 | * Assign the value mainStackPointer to the MSP
485 | * (main stack pointer) Cortex processor register
486 | */
487 | void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
488 | void __set_MSP(uint32_t topOfMainStack) {
489 | __ASM volatile ("MSR msp, %0\n\t"
490 | "BX lr \n\t" : : "r" (topOfMainStack) );
491 | }
492 |
493 | /**
494 | * @brief Return the Base Priority value
495 | *
496 | * @return BasePriority
497 | *
498 | * Return the content of the base priority register
499 | */
500 | uint32_t __get_BASEPRI(void) {
501 | uint32_t result = 0;
502 |
503 | __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
504 | return (result);
505 | }
506 |
507 | /**
508 | * @brief Set the Base Priority value
509 | *
510 | * @param basePri BasePriority
511 | *
512 | * Set the base priority register
513 | */
514 | void __set_BASEPRI(uint32_t value) {
515 | __ASM volatile ("MSR basepri, %0" : : "r" (value) );
516 | }
517 |
518 | /**
519 | * @brief Return the Priority Mask value
520 | *
521 | * @return PriMask
522 | *
523 | * Return state of the priority mask bit from the priority mask register
524 | */
525 | uint32_t __get_PRIMASK(void) {
526 | uint32_t result = 0;
527 |
528 | __ASM volatile ("MRS %0, primask" : "=r" (result) );
529 | return (result);
530 | }
531 |
532 | /**
533 | * @brief Set the Priority Mask value
534 | *
535 | * @param priMask PriMask
536 | *
537 | * Set the priority mask bit in the priority mask register
538 | */
539 | void __set_PRIMASK(uint32_t priMask) {
540 | __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
541 | }
542 |
543 | /**
544 | * @brief Return the Fault Mask value
545 | *
546 | * @return FaultMask
547 | *
548 | * Return the content of the fault mask register
549 | */
550 | uint32_t __get_FAULTMASK(void) {
551 | uint32_t result = 0;
552 |
553 | __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
554 | return (result);
555 | }
556 |
557 | /**
558 | * @brief Set the Fault Mask value
559 | *
560 | * @param faultMask faultMask value
561 | *
562 | * Set the fault mask register
563 | */
564 | void __set_FAULTMASK(uint32_t faultMask) {
565 | __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
566 | }
567 |
568 | /**
569 | * @brief Return the Control Register value
570 | *
571 | * @return Control value
572 | *
573 | * Return the content of the control register
574 | */
575 | uint32_t __get_CONTROL(void) {
576 | uint32_t result = 0;
577 |
578 | __ASM volatile ("MRS %0, control" : "=r" (result) );
579 | return (result);
580 | }
581 |
582 | /**
583 | * @brief Set the Control Register value
584 | *
585 | * @param control Control value
586 | *
587 | * Set the control register
588 | */
589 | void __set_CONTROL(uint32_t control) {
590 | __ASM volatile ("MSR control, %0" : : "r" (control) );
591 | }
592 |
593 | /**
594 | * @brief Reverse byte order in integer value
595 | *
596 | * @param value value to reverse
597 | * @return reversed value
598 | *
599 | * Reverse byte order in integer value
600 | */
601 | uint32_t __REV(uint32_t value) {
602 | uint32_t result = 0;
603 |
604 | __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
605 | return (result);
606 | }
607 |
608 | /**
609 | * @brief Reverse byte order in unsigned short value
610 | *
611 | * @param value value to reverse
612 | * @return reversed value
613 | *
614 | * Reverse byte order in unsigned short value
615 | */
616 | uint32_t __REV16(uint16_t value) {
617 | uint32_t result = 0;
618 |
619 | __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
620 | return (result);
621 | }
622 |
623 | /**
624 | * @brief Reverse byte order in signed short value with sign extension to integer
625 | *
626 | * @param value value to reverse
627 | * @return reversed value
628 | *
629 | * Reverse byte order in signed short value with sign extension to integer
630 | */
631 | int32_t __REVSH(int16_t value) {
632 | uint32_t result = 0;
633 |
634 | __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
635 | return (result);
636 | }
637 |
638 | /**
639 | * @brief Reverse bit order of value
640 | *
641 | * @param value value to reverse
642 | * @return reversed value
643 | *
644 | * Reverse bit order of value
645 | */
646 | uint32_t __RBIT(uint32_t value) {
647 | uint32_t result = 0;
648 |
649 | __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
650 | return (result);
651 | }
652 |
653 | /**
654 | * @brief LDR Exclusive (8 bit)
655 | *
656 | * @param *addr address pointer
657 | * @return value of (*address)
658 | *
659 | * Exclusive LDR command for 8 bit value
660 | */
661 | uint8_t __LDREXB(uint8_t *addr) {
662 | uint8_t result = 0;
663 |
664 | __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
665 | return (result);
666 | }
667 |
668 | /**
669 | * @brief LDR Exclusive (16 bit)
670 | *
671 | * @param *addr address pointer
672 | * @return value of (*address)
673 | *
674 | * Exclusive LDR command for 16 bit values
675 | */
676 | uint16_t __LDREXH(uint16_t *addr) {
677 | uint16_t result = 0;
678 |
679 | __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
680 | return (result);
681 | }
682 |
683 | /**
684 | * @brief LDR Exclusive (32 bit)
685 | *
686 | * @param *addr address pointer
687 | * @return value of (*address)
688 | *
689 | * Exclusive LDR command for 32 bit values
690 | */
691 | uint32_t __LDREXW(uint32_t *addr) {
692 | uint32_t result = 0;
693 |
694 | __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
695 | return (result);
696 | }
697 |
698 | /**
699 | * @brief STR Exclusive (8 bit)
700 | *
701 | * @param value value to store
702 | * @param *addr address pointer
703 | * @return successful / failed
704 | *
705 | * Exclusive STR command for 8 bit values
706 | */
707 | uint32_t __STREXB(uint8_t value, uint8_t *addr) {
708 | uint32_t result = 0;
709 |
710 | /*
711 | origin:
712 | __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
713 |
714 | modify according to
715 | http://old.nabble.com/-Bug-gas-13215--New%3A-ARM-Cortex-M3-strexh-strexb-instructions-with-same-registers-generates-error-to32516436.html#a33051551
716 |
717 | */
718 |
719 | __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
720 | return (result);
721 | }
722 |
723 | /**
724 | * @brief STR Exclusive (16 bit)
725 | *
726 | * @param value value to store
727 | * @param *addr address pointer
728 | * @return successful / failed
729 | *
730 | * Exclusive STR command for 16 bit values
731 | */
732 | uint32_t __STREXH(uint16_t value, uint16_t *addr) {
733 | uint32_t result = 0;
734 |
735 | /*
736 | origin:
737 | __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
738 |
739 | modify according to
740 | http://old.nabble.com/-Bug-gas-13215--New%3A-ARM-Cortex-M3-strexh-strexb-instructions-with-same-registers-generates-error-to32516436.html#a33051551
741 |
742 | */
743 |
744 | __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
745 | return (result);
746 | }
747 |
748 | /**
749 | * @brief STR Exclusive (32 bit)
750 | *
751 | * @param value value to store
752 | * @param *addr address pointer
753 | * @return successful / failed
754 | *
755 | * Exclusive STR command for 32 bit values
756 | */
757 | uint32_t __STREXW(uint32_t value, uint32_t *addr) {
758 | uint32_t result = 0;
759 |
760 | __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
761 | return (result);
762 | }
763 |
764 | #elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
765 | /* TASKING carm specific functions */
766 |
767 | /*
768 | * The CMSIS functions have been implemented as intrinsics in the compiler.
769 | * Please use "carm -?i" to get an up to date list of all instrinsics,
770 | * Including the CMSIS ones.
771 | */
772 |
773 | #endif
774 |
--------------------------------------------------------------------------------
/sys/library_hacks.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * LibraryHacks.cpp
3 | *
4 | * Created on: 23 Jan 2011
5 | * Author: Andy
6 | * source: : stm32plus, version 2.1.0
7 | * @ http://andybrown.me.uk/wk/downloads/
8 | */
9 |
10 | #include
11 | #include
12 |
13 |
14 | /*
15 | * The default pulls in 70K of garbage
16 | */
17 |
18 | namespace __gnu_cxx {
19 |
20 | void __verbose_terminate_handler() {
21 | for(;;);
22 | }
23 | }
24 |
25 |
26 | /*
27 | * The default pulls in about 12K of garbage
28 | */
29 |
30 | extern "C" void __cxa_pure_virtual() {
31 | for(;;);
32 | }
33 |
34 |
35 | /*
36 | * Implement C++ new/delete operators using the heap
37 | */
38 |
39 | void *operator new(size_t size) {
40 | return malloc(size);
41 | }
42 |
43 | void *operator new(size_t,void *ptr) {
44 | return ptr;
45 | }
46 |
47 | void *operator new[](size_t size) {
48 | return malloc(size);
49 | }
50 |
51 | void *operator new[](size_t,void *ptr) {
52 | return ptr;
53 | }
54 |
55 | void operator delete(void *p) {
56 | free(p);
57 | }
58 |
59 | void operator delete[](void *p) {
60 | free(p);
61 | }
62 |
63 |
64 | /*
65 | * EABI builds can generate reams of stack unwind code for system generated exceptions
66 | * e.g. (divide-by-zero). Since we don't support exceptions we'll wrap out these
67 | * symbols and save a lot of flash space.
68 | */
69 |
70 | extern "C" void __wrap___aeabi_unwind_cpp_pr0() {}
71 | extern "C" void __wrap___aeabi_unwind_cpp_pr1() {}
72 | extern "C" void __wrap___aeabi_unwind_cpp_pr2() {}
73 |
74 |
75 | /*
76 | * sbrk function for getting space for malloc and friends
77 | */
78 |
79 | extern "C" {
80 |
81 | caddr_t _sbrk ( int incr ) {
82 |
83 | extern int _end;
84 |
85 | static unsigned char *heap = NULL;
86 | unsigned char *prev_heap;
87 |
88 | if (heap == NULL) {
89 | heap = (unsigned char *)&_end;
90 | }
91 | prev_heap = heap;
92 | /* check removed to show basic approach */
93 |
94 | heap += incr;
95 |
96 | return (caddr_t) prev_heap;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/sys/newlib_stubs.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * newlib_stubs.c
3 | *
4 | * Created on: 2 Nov 2010
5 | * Author: nanoage.co.uk
6 | * Weihong Guan (@aGuegu)
7 | *
8 | * modified on source:
9 | https://sites.google.com/site/stm32discovery/
10 | open-source-development-with-the-stm32-discovery/
11 | getting-newlib-to-work-with-stm32-and-code-sourcery-lite-eabi
12 |
13 | http://andybrown.me.uk/wk/2011/12/28/
14 | stm32plus-a-c-library-for-stm32-development/
15 | *
16 | */
17 |
18 | #ifdef __cplusplus
19 | extern "C" {
20 | #endif
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include "usart/usart.h"
27 | #include
28 | #include
29 |
30 | #undef errno
31 | extern int errno;
32 |
33 | /*
34 | environ
35 | A pointer to a list of environment variables and their values.
36 | For a minimal environment, this empty list is adequate:
37 | */
38 | char *__env[1] = { 0 };
39 | char **environ = __env;
40 |
41 | int _write(int file, const char *ptr, int len);
42 |
43 | void _exit(int status) {
44 | _write(STDOUT_FILENO, "exit", 4);
45 | while (1)
46 | ;
47 | }
48 |
49 | int _close(int file) {
50 | return -1;
51 | }
52 | /*
53 | execve
54 | Transfer control to a new process. Minimal implementation (for a system without processes):
55 | */
56 | int _execve(char *name, char **argv, char **env) {
57 | errno = ENOMEM;
58 | return -1;
59 | }
60 | /*
61 | fork
62 | Create a new process. Minimal implementation (for a system without processes):
63 | */
64 |
65 | int _fork() {
66 | errno = EAGAIN;
67 | return -1;
68 | }
69 | /*
70 | fstat
71 | Status of an open file. For consistency with other minimal implementations in these examples,
72 | all files are regarded as character special devices.
73 | The `sys/stat.h' header file required is distributed in the `include' subdirectory for this C library.
74 | */
75 | int _fstat(int file, struct stat *st) {
76 | st->st_mode = S_IFCHR;
77 | return 0;
78 | }
79 |
80 | /*
81 | getpid
82 | Process-ID; this is sometimes used to generate strings unlikely to conflict with other processes. Minimal implementation, for a system without processes:
83 | */
84 |
85 | int _getpid() {
86 | return 1;
87 | }
88 |
89 | /*
90 | isatty
91 | Query whether output stream is a terminal. For consistency with the other minimal implementations,
92 | */
93 | int _isatty(int file) {
94 | switch (file) {
95 | case STDOUT_FILENO:
96 | case STDERR_FILENO:
97 | case STDIN_FILENO:
98 | return 1;
99 | default:
100 | //errno = ENOTTY;
101 | errno = EBADF;
102 | return 0;
103 | }
104 | }
105 |
106 | /*
107 | kill
108 | Send a signal. Minimal implementation:
109 | */
110 | int _kill(int pid, int sig) {
111 | errno = EINVAL;
112 | return (-1);
113 | }
114 |
115 | /*
116 | link
117 | Establish a new name for an existing file. Minimal implementation:
118 | */
119 |
120 | int _link(char *s_old, char *s_new) {
121 | errno = EMLINK;
122 | return -1;
123 | }
124 |
125 | /*
126 | lseek
127 | Set position in a file. Minimal implementation:
128 | */
129 | int _lseek(int file, int ptr, int dir) {
130 | return 0;
131 | }
132 |
133 | /*
134 | sbrk
135 | Increase program data space.
136 | Malloc and related functions depend on this
137 | */
138 | //caddr_t _sbrk(int incr) {
139 | //
140 | // extern char _ebss; // Defined by the linker
141 | // static char *heap_end;
142 | // char *prev_heap_end;
143 | //
144 | // if (heap_end == 0) {
145 | // heap_end = &_ebss;
146 | // }
147 | // prev_heap_end = heap_end;
148 | //
149 | // char * stack = (char*) __get_MSP();
150 | // if (heap_end + incr > stack) {
151 | // _write(STDERR_FILENO, "Heap and stack collision\n", 25);
152 | // errno = ENOMEM;
153 | // return (caddr_t) -1;
154 | // //abort ();
155 | // }
156 | //
157 | // heap_end += incr;
158 | // return (caddr_t) prev_heap_end;
159 | //}
160 |
161 | /*
162 | read
163 | Read a character to a file. `libc' subroutines will use this system routine for input from all files, including stdin
164 | Returns -1 on error or blocks until the number of characters have been read.
165 | */
166 |
167 | int _read(int file, char *ptr, int len) {
168 |
169 | extern Usart usart;
170 |
171 | int num = 0;
172 | switch (file) {
173 | case STDIN_FILENO:
174 | for (int i = 0; i < len; i++) {
175 | *ptr++ = usart.read();
176 | num++;
177 | }
178 | break;
179 | default:
180 | errno = EBADF;
181 | return -1;
182 | }
183 | return num;
184 | }
185 |
186 | /*
187 | stat
188 | Status of a file (by name). Minimal implementation:
189 | int _EXFUN(stat,( const char *__path, struct stat *__sbuf ));
190 | */
191 |
192 | int _stat(const char *filepath, struct stat *st) {
193 | st->st_mode = S_IFCHR;
194 | return 0;
195 | }
196 |
197 | /*
198 | times
199 | Timing information for current process. Minimal implementation:
200 | */
201 |
202 | clock_t _times(struct tms *buf) {
203 | return -1;
204 | }
205 |
206 | /*
207 | unlink
208 | Remove a file's directory entry. Minimal implementation:
209 | */
210 | int _unlink(char *name) {
211 | errno = ENOENT;
212 | return -1;
213 | }
214 |
215 | /*
216 | wait
217 | Wait for a child process. Minimal implementation:
218 | */
219 | int _wait(int *status) {
220 | errno = ECHILD;
221 | return -1;
222 | }
223 |
224 | /*
225 | write
226 | Write a character to a file. `libc' subroutines will use this system routine for output to all files, including stdout
227 | Returns -1 on error or number of bytes sent
228 | */
229 |
230 | int _write(int file, const char *ptr, int len) {
231 |
232 | extern Usart usart;
233 |
234 | int n;
235 | switch (file) {
236 | case STDOUT_FILENO: /*stdout*/
237 | for (n = 0; n < len; n++) {
238 | usart.write(*ptr++);
239 | }
240 | break;
241 | case STDERR_FILENO: /* stderr */
242 | for (n = 0; n < len; n++) {
243 | usart.write(*ptr++);
244 | }
245 | break;
246 | default:
247 | errno = EBADF;
248 | return -1;
249 | }
250 | return len;
251 | }
252 |
253 | #ifdef __cplusplus
254 | }
255 | #endif
256 |
--------------------------------------------------------------------------------
/sys/startup_stm32f10x_md_vl.S:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file startup_stm32f10x_md_vl.s
4 | * @author MCD Application Team
5 | * @version V3.5.0
6 | * @date 11-March-2011
7 | * @brief STM32F10x Medium Density Value Line Devices vector table for Atollic
8 | * toolchain.
9 | * This module performs:
10 | * - Set the initial SP
11 | * - Set the initial PC == Reset_Handler,
12 | * - Set the vector table entries with the exceptions ISR address
13 | * - Configure the clock system
14 | * - Branches to main in the C library (which eventually
15 | * calls main()).
16 | * After Reset the Cortex-M3 processor is in Thread mode,
17 | * priority is Privileged, and the Stack is set to Main.
18 | ******************************************************************************
19 | * @attention
20 | *
21 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
22 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
23 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
24 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
25 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
26 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
27 | *
28 | * © COPYRIGHT 2011 STMicroelectronics
29 | ******************************************************************************
30 | */
31 |
32 | .syntax unified
33 | .cpu cortex-m3
34 | .fpu softvfp
35 | .thumb
36 |
37 | .global g_pfnVectors
38 | .global Default_Handler
39 |
40 | /* start address for the initialization values of the .data section.
41 | defined in linker script */
42 | .word _sidata
43 | /* start address for the .data section. defined in linker script */
44 | .word _sdata
45 | /* end address for the .data section. defined in linker script */
46 | .word _edata
47 | /* start address for the .bss section. defined in linker script */
48 | .word _sbss
49 | /* end address for the .bss section. defined in linker script */
50 | .word _ebss
51 |
52 | .equ BootRAM, 0xF108F85F
53 | /**
54 | * @brief This is the code that gets called when the processor first
55 | * starts execution following a reset event. Only the absolutely
56 | * necessary set is performed, after which the application
57 | * supplied main() routine is called.
58 | * @param None
59 | * @retval : None
60 | */
61 |
62 | .section .text.Reset_Handler
63 | .weak Reset_Handler
64 | .type Reset_Handler, %function
65 | Reset_Handler:
66 |
67 | /* Copy the data segment initializers from flash to SRAM */
68 | movs r1, #0
69 | b LoopCopyDataInit
70 |
71 | CopyDataInit:
72 | ldr r3, =_sidata
73 | ldr r3, [r3, r1]
74 | str r3, [r0, r1]
75 | adds r1, r1, #4
76 |
77 | LoopCopyDataInit:
78 | ldr r0, =_sdata
79 | ldr r3, =_edata
80 | adds r2, r0, r1
81 | cmp r2, r3
82 | bcc CopyDataInit
83 | ldr r2, =_sbss
84 | b LoopFillZerobss
85 | /* Zero fill the bss segment. */
86 | FillZerobss:
87 | movs r3, #0
88 | str r3, [r2], #4
89 |
90 | LoopFillZerobss:
91 | ldr r3, = _ebss
92 | cmp r2, r3
93 | bcc FillZerobss
94 |
95 | /* Call the clock system intitialization function.*/
96 | bl SystemInit
97 | /* Call static constructors */
98 | bl __libc_init_array
99 | /* Call the application's entry point.*/
100 | bl main
101 | bx lr
102 | .size Reset_Handler, .-Reset_Handler
103 |
104 | /**
105 | * @brief This is the code that gets called when the processor receives an
106 | * unexpected interrupt. This simply enters an infinite loop, preserving
107 | * the system state for examination by a debugger.
108 | *
109 | * @param None
110 | * @retval : None
111 | */
112 | .section .text.Default_Handler,"ax",%progbits
113 | Default_Handler:
114 | Infinite_Loop:
115 | b Infinite_Loop
116 | .size Default_Handler, .-Default_Handler
117 | /******************************************************************************
118 | *
119 | * The minimal vector table for a Cortex M3. Note that the proper constructs
120 | * must be placed on this to ensure that it ends up at physical address
121 | * 0x0000.0000.
122 | *
123 | ******************************************************************************/
124 | .section .isr_vector,"a",%progbits
125 | .type g_pfnVectors, %object
126 | .size g_pfnVectors, .-g_pfnVectors
127 |
128 |
129 | g_pfnVectors:
130 | .word _estack
131 | .word Reset_Handler
132 | .word NMI_Handler
133 | .word HardFault_Handler
134 | .word MemManage_Handler
135 | .word BusFault_Handler
136 | .word UsageFault_Handler
137 | .word 0
138 | .word 0
139 | .word 0
140 | .word 0
141 | .word SVC_Handler
142 | .word DebugMon_Handler
143 | .word 0
144 | .word PendSV_Handler
145 | .word SysTick_Handler
146 | .word WWDG_IRQHandler
147 | .word PVD_IRQHandler
148 | .word TAMPER_IRQHandler
149 | .word RTC_IRQHandler
150 | .word FLASH_IRQHandler
151 | .word RCC_IRQHandler
152 | .word EXTI0_IRQHandler
153 | .word EXTI1_IRQHandler
154 | .word EXTI2_IRQHandler
155 | .word EXTI3_IRQHandler
156 | .word EXTI4_IRQHandler
157 | .word DMA1_Channel1_IRQHandler
158 | .word DMA1_Channel2_IRQHandler
159 | .word DMA1_Channel3_IRQHandler
160 | .word DMA1_Channel4_IRQHandler
161 | .word DMA1_Channel5_IRQHandler
162 | .word DMA1_Channel6_IRQHandler
163 | .word DMA1_Channel7_IRQHandler
164 | .word ADC1_IRQHandler
165 | .word 0
166 | .word 0
167 | .word 0
168 | .word 0
169 | .word EXTI9_5_IRQHandler
170 | .word TIM1_BRK_TIM15_IRQHandler
171 | .word TIM1_UP_TIM16_IRQHandler
172 | .word TIM1_TRG_COM_TIM17_IRQHandler
173 | .word TIM1_CC_IRQHandler
174 | .word TIM2_IRQHandler
175 | .word TIM3_IRQHandler
176 | .word TIM4_IRQHandler
177 | .word I2C1_EV_IRQHandler
178 | .word I2C1_ER_IRQHandler
179 | .word I2C2_EV_IRQHandler
180 | .word I2C2_ER_IRQHandler
181 | .word SPI1_IRQHandler
182 | .word SPI2_IRQHandler
183 | .word USART1_IRQHandler
184 | .word USART2_IRQHandler
185 | .word USART3_IRQHandler
186 | .word EXTI15_10_IRQHandler
187 | .word RTCAlarm_IRQHandler
188 | .word CEC_IRQHandler
189 | .word 0
190 | .word 0
191 | .word 0
192 | .word 0
193 | .word 0
194 | .word 0
195 | .word 0
196 | .word 0
197 | .word 0
198 | .word 0
199 | .word 0
200 | .word TIM6_DAC_IRQHandler
201 | .word TIM7_IRQHandler
202 | .word 0
203 | .word 0
204 | .word 0
205 | .word 0
206 | .word 0
207 | .word 0
208 | .word 0
209 | .word 0
210 | .word 0
211 | .word 0
212 | .word 0
213 | .word 0
214 | .word 0
215 | .word 0
216 | .word 0
217 | .word 0
218 | .word 0
219 | .word 0
220 | .word 0
221 | .word 0
222 | .word 0
223 | .word 0
224 | .word 0
225 | .word 0
226 | .word 0
227 | .word 0
228 | .word 0
229 | .word 0
230 | .word 0
231 | .word 0
232 | .word 0
233 | .word 0
234 | .word 0
235 | .word 0
236 | .word 0
237 | .word 0
238 | .word 0
239 | .word 0
240 | .word 0
241 | .word 0
242 | .word 0
243 | .word 0
244 | .word 0
245 | .word BootRAM /* @0x01CC. This is for boot in RAM mode for
246 | STM32F10x Medium Value Line Density devices. */
247 |
248 | /*******************************************************************************
249 | *
250 | * Provide weak aliases for each Exception handler to the Default_Handler.
251 | * As they are weak aliases, any function with the same name will override
252 | * this definition.
253 | *
254 | *******************************************************************************/
255 |
256 |
257 | .weak NMI_Handler
258 | .thumb_set NMI_Handler,Default_Handler
259 |
260 | .weak HardFault_Handler
261 | .thumb_set HardFault_Handler,Default_Handler
262 |
263 | .weak MemManage_Handler
264 | .thumb_set MemManage_Handler,Default_Handler
265 |
266 | .weak BusFault_Handler
267 | .thumb_set BusFault_Handler,Default_Handler
268 |
269 | .weak UsageFault_Handler
270 | .thumb_set UsageFault_Handler,Default_Handler
271 |
272 | .weak SVC_Handler
273 | .thumb_set SVC_Handler,Default_Handler
274 |
275 | .weak DebugMon_Handler
276 | .thumb_set DebugMon_Handler,Default_Handler
277 |
278 | .weak PendSV_Handler
279 | .thumb_set PendSV_Handler,Default_Handler
280 |
281 | .weak SysTick_Handler
282 | .thumb_set SysTick_Handler,Default_Handler
283 |
284 | .weak WWDG_IRQHandler
285 | .thumb_set WWDG_IRQHandler,Default_Handler
286 |
287 | .weak PVD_IRQHandler
288 | .thumb_set PVD_IRQHandler,Default_Handler
289 |
290 | .weak TAMPER_IRQHandler
291 | .thumb_set TAMPER_IRQHandler,Default_Handler
292 |
293 | .weak RTC_IRQHandler
294 | .thumb_set RTC_IRQHandler,Default_Handler
295 |
296 | .weak FLASH_IRQHandler
297 | .thumb_set FLASH_IRQHandler,Default_Handler
298 |
299 | .weak RCC_IRQHandler
300 | .thumb_set RCC_IRQHandler,Default_Handler
301 |
302 | .weak EXTI0_IRQHandler
303 | .thumb_set EXTI0_IRQHandler,Default_Handler
304 |
305 | .weak EXTI1_IRQHandler
306 | .thumb_set EXTI1_IRQHandler,Default_Handler
307 |
308 | .weak EXTI2_IRQHandler
309 | .thumb_set EXTI2_IRQHandler,Default_Handler
310 |
311 | .weak EXTI3_IRQHandler
312 | .thumb_set EXTI3_IRQHandler,Default_Handler
313 |
314 | .weak EXTI4_IRQHandler
315 | .thumb_set EXTI4_IRQHandler,Default_Handler
316 |
317 | .weak DMA1_Channel1_IRQHandler
318 | .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
319 |
320 | .weak DMA1_Channel2_IRQHandler
321 | .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
322 |
323 | .weak DMA1_Channel3_IRQHandler
324 | .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
325 |
326 | .weak DMA1_Channel4_IRQHandler
327 | .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
328 |
329 | .weak DMA1_Channel5_IRQHandler
330 | .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
331 |
332 | .weak DMA1_Channel6_IRQHandler
333 | .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
334 |
335 | .weak DMA1_Channel7_IRQHandler
336 | .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
337 |
338 | .weak ADC1_IRQHandler
339 | .thumb_set ADC1_IRQHandler,Default_Handler
340 |
341 | .weak EXTI9_5_IRQHandler
342 | .thumb_set EXTI9_5_IRQHandler,Default_Handler
343 |
344 | .weak TIM1_BRK_TIM15_IRQHandler
345 | .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler
346 |
347 | .weak TIM1_UP_TIM16_IRQHandler
348 | .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler
349 |
350 | .weak TIM1_TRG_COM_TIM17_IRQHandler
351 | .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler
352 |
353 | .weak TIM1_CC_IRQHandler
354 | .thumb_set TIM1_CC_IRQHandler,Default_Handler
355 |
356 | .weak TIM2_IRQHandler
357 | .thumb_set TIM2_IRQHandler,Default_Handler
358 |
359 | .weak TIM3_IRQHandler
360 | .thumb_set TIM3_IRQHandler,Default_Handler
361 |
362 | .weak TIM4_IRQHandler
363 | .thumb_set TIM4_IRQHandler,Default_Handler
364 |
365 | .weak I2C1_EV_IRQHandler
366 | .thumb_set I2C1_EV_IRQHandler,Default_Handler
367 |
368 | .weak I2C1_ER_IRQHandler
369 | .thumb_set I2C1_ER_IRQHandler,Default_Handler
370 |
371 | .weak I2C2_EV_IRQHandler
372 | .thumb_set I2C2_EV_IRQHandler,Default_Handler
373 |
374 | .weak I2C2_ER_IRQHandler
375 | .thumb_set I2C2_ER_IRQHandler,Default_Handler
376 |
377 | .weak SPI1_IRQHandler
378 | .thumb_set SPI1_IRQHandler,Default_Handler
379 |
380 | .weak SPI2_IRQHandler
381 | .thumb_set SPI2_IRQHandler,Default_Handler
382 |
383 | .weak USART1_IRQHandler
384 | .thumb_set USART1_IRQHandler,Default_Handler
385 |
386 | .weak USART2_IRQHandler
387 | .thumb_set USART2_IRQHandler,Default_Handler
388 |
389 | .weak USART3_IRQHandler
390 | .thumb_set USART3_IRQHandler,Default_Handler
391 |
392 | .weak EXTI15_10_IRQHandler
393 | .thumb_set EXTI15_10_IRQHandler,Default_Handler
394 |
395 | .weak RTCAlarm_IRQHandler
396 | .thumb_set RTCAlarm_IRQHandler,Default_Handler
397 |
398 | .weak CEC_IRQHandler
399 | .thumb_set CEC_IRQHandler,Default_Handler
400 |
401 | .weak TIM6_DAC_IRQHandler
402 | .thumb_set TIM6_DAC_IRQHandler,Default_Handler
403 |
404 | .weak TIM7_IRQHandler
405 | .thumb_set TIM7_IRQHandler,Default_Handler
406 |
407 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
408 |
409 |
--------------------------------------------------------------------------------
/sys/system_stm32f10x.c:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file system_stm32f10x.c
4 | * @author MCD Application Team
5 | * @version V3.5.0
6 | * @date 08-April-2011
7 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
8 | *
9 | * 1. This file provides two functions and one global variable to be called from
10 | * user application:
11 | * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
12 | * factors, AHB/APBx prescalers and Flash settings).
13 | * This function is called at startup just after reset and
14 | * before branch to main program. This call is made inside
15 | * the "startup_stm32f10x_xx.s" file.
16 | *
17 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
18 | * by the user application to setup the SysTick
19 | * timer or configure other parameters.
20 | *
21 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
22 | * be called whenever the core clock is changed
23 | * during program execution.
24 | *
25 | * 2. After each device reset the HSI (8 MHz) is used as system clock source.
26 | * Then SystemInit() function is called, in "startup_stm32f10x_xx.s" file, to
27 | * configure the system clock before to branch to main program.
28 | *
29 | * 3. If the system clock source selected by user fails to startup, the SystemInit()
30 | * function will do nothing and HSI still used as system clock source. User can
31 | * add some code to deal with this issue inside the SetSysClock() function.
32 | *
33 | * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depedning on
34 | * the product used), refer to "HSE_VALUE" define in "stm32f10x.h" file.
35 | * When HSE is used as system clock source, directly or through PLL, and you
36 | * are using different crystal you have to adapt the HSE value to your own
37 | * configuration.
38 | *
39 | ******************************************************************************
40 | * @attention
41 | *
42 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
43 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
44 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
45 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
46 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
47 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
48 | *
49 | * © COPYRIGHT 2011 STMicroelectronics
50 | ******************************************************************************
51 | */
52 |
53 | /** @addtogroup CMSIS
54 | * @{
55 | */
56 |
57 | /** @addtogroup stm32f10x_system
58 | * @{
59 | */
60 |
61 | /** @addtogroup STM32F10x_System_Private_Includes
62 | * @{
63 | */
64 |
65 | #include "stm32f10x.h"
66 |
67 | /**
68 | * @}
69 | */
70 |
71 | /** @addtogroup STM32F10x_System_Private_TypesDefinitions
72 | * @{
73 | */
74 |
75 | /**
76 | * @}
77 | */
78 |
79 | /** @addtogroup STM32F10x_System_Private_Defines
80 | * @{
81 | */
82 |
83 | /*!< Uncomment the line corresponding to the desired System clock (SYSCLK)
84 | frequency (after reset the HSI is used as SYSCLK source)
85 |
86 | IMPORTANT NOTE:
87 | ==============
88 | 1. After each device reset the HSI is used as System clock source.
89 |
90 | 2. Please make sure that the selected System clock doesn't exceed your device's
91 | maximum frequency.
92 |
93 | 3. If none of the define below is enabled, the HSI is used as System clock
94 | source.
95 |
96 | 4. The System clock configuration functions provided within this file assume that:
97 | - For Low, Medium and High density Value line devices an external 8MHz
98 | crystal is used to drive the System clock.
99 | - For Low, Medium and High density devices an external 8MHz crystal is
100 | used to drive the System clock.
101 | - For Connectivity line devices an external 25MHz crystal is used to drive
102 | the System clock.
103 | If you are using different crystal you have to adapt those functions accordingly.
104 | */
105 |
106 | #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
107 | /* #define SYSCLK_FREQ_HSE HSE_VALUE */
108 | #define SYSCLK_FREQ_24MHz 24000000
109 | #else
110 | /* #define SYSCLK_FREQ_HSE HSE_VALUE */
111 | /* #define SYSCLK_FREQ_24MHz 24000000 */
112 | /* #define SYSCLK_FREQ_36MHz 36000000 */
113 | /* #define SYSCLK_FREQ_48MHz 48000000 */
114 | /* #define SYSCLK_FREQ_56MHz 56000000 */
115 | #define SYSCLK_FREQ_72MHz 72000000
116 | #endif
117 |
118 | /*!< Uncomment the following line if you need to use external SRAM mounted
119 | on STM3210E-EVAL board (STM32 High density and XL-density devices) or on
120 | STM32100E-EVAL board (STM32 High-density value line devices) as data memory */
121 | #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
122 | /* #define DATA_IN_ExtSRAM */
123 | #endif
124 |
125 | /*!< Uncomment the following line if you need to relocate your vector Table in
126 | Internal SRAM. */
127 | /* #define VECT_TAB_SRAM */
128 | #define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
129 | This value must be a multiple of 0x200. */
130 |
131 |
132 | /**
133 | * @}
134 | */
135 |
136 | /** @addtogroup STM32F10x_System_Private_Macros
137 | * @{
138 | */
139 |
140 | /**
141 | * @}
142 | */
143 |
144 | /** @addtogroup STM32F10x_System_Private_Variables
145 | * @{
146 | */
147 |
148 | /*******************************************************************************
149 | * Clock Definitions
150 | *******************************************************************************/
151 | #ifdef SYSCLK_FREQ_HSE
152 | uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */
153 | #elif defined SYSCLK_FREQ_24MHz
154 | uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */
155 | #elif defined SYSCLK_FREQ_36MHz
156 | uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */
157 | #elif defined SYSCLK_FREQ_48MHz
158 | uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */
159 | #elif defined SYSCLK_FREQ_56MHz
160 | uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */
161 | #elif defined SYSCLK_FREQ_72MHz
162 | uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */
163 | #else /*!< HSI Selected as System Clock source */
164 | uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */
165 | #endif
166 |
167 | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
168 | /**
169 | * @}
170 | */
171 |
172 | /** @addtogroup STM32F10x_System_Private_FunctionPrototypes
173 | * @{
174 | */
175 |
176 | static void SetSysClock(void);
177 |
178 | #ifdef SYSCLK_FREQ_HSE
179 | static void SetSysClockToHSE(void);
180 | #elif defined SYSCLK_FREQ_24MHz
181 | static void SetSysClockTo24(void);
182 | #elif defined SYSCLK_FREQ_36MHz
183 | static void SetSysClockTo36(void);
184 | #elif defined SYSCLK_FREQ_48MHz
185 | static void SetSysClockTo48(void);
186 | #elif defined SYSCLK_FREQ_56MHz
187 | static void SetSysClockTo56(void);
188 | #elif defined SYSCLK_FREQ_72MHz
189 | static void SetSysClockTo72(void);
190 | #endif
191 |
192 | #ifdef DATA_IN_ExtSRAM
193 | static void SystemInit_ExtMemCtl(void);
194 | #endif /* DATA_IN_ExtSRAM */
195 |
196 | /**
197 | * @}
198 | */
199 |
200 | /** @addtogroup STM32F10x_System_Private_Functions
201 | * @{
202 | */
203 |
204 | /**
205 | * @brief Setup the microcontroller system
206 | * Initialize the Embedded Flash Interface, the PLL and update the
207 | * SystemCoreClock variable.
208 | * @note This function should be used only after reset.
209 | * @retval None
210 | */
211 | void SystemInit (void)
212 | {
213 | /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
214 | /* Set HSION bit */
215 | RCC->CR |= (uint32_t)0x00000001;
216 |
217 | /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
218 | #ifndef STM32F10X_CL
219 | RCC->CFGR &= (uint32_t)0xF8FF0000;
220 | #else
221 | RCC->CFGR &= (uint32_t)0xF0FF0000;
222 | #endif /* STM32F10X_CL */
223 |
224 | /* Reset HSEON, CSSON and PLLON bits */
225 | RCC->CR &= (uint32_t)0xFEF6FFFF;
226 |
227 | /* Reset HSEBYP bit */
228 | RCC->CR &= (uint32_t)0xFFFBFFFF;
229 |
230 | /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
231 | RCC->CFGR &= (uint32_t)0xFF80FFFF;
232 |
233 | #ifdef STM32F10X_CL
234 | /* Reset PLL2ON and PLL3ON bits */
235 | RCC->CR &= (uint32_t)0xEBFFFFFF;
236 |
237 | /* Disable all interrupts and clear pending bits */
238 | RCC->CIR = 0x00FF0000;
239 |
240 | /* Reset CFGR2 register */
241 | RCC->CFGR2 = 0x00000000;
242 | #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
243 | /* Disable all interrupts and clear pending bits */
244 | RCC->CIR = 0x009F0000;
245 |
246 | /* Reset CFGR2 register */
247 | RCC->CFGR2 = 0x00000000;
248 | #else
249 | /* Disable all interrupts and clear pending bits */
250 | RCC->CIR = 0x009F0000;
251 | #endif /* STM32F10X_CL */
252 |
253 | #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
254 | #ifdef DATA_IN_ExtSRAM
255 | SystemInit_ExtMemCtl();
256 | #endif /* DATA_IN_ExtSRAM */
257 | #endif
258 |
259 | /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
260 | /* Configure the Flash Latency cycles and enable prefetch buffer */
261 | SetSysClock();
262 |
263 | #ifdef VECT_TAB_SRAM
264 | SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
265 | #else
266 | SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
267 | #endif
268 | }
269 |
270 | /**
271 | * @brief Update SystemCoreClock variable according to Clock Register Values.
272 | * The SystemCoreClock variable contains the core clock (HCLK), it can
273 | * be used by the user application to setup the SysTick timer or configure
274 | * other parameters.
275 | *
276 | * @note Each time the core clock (HCLK) changes, this function must be called
277 | * to update SystemCoreClock variable value. Otherwise, any configuration
278 | * based on this variable will be incorrect.
279 | *
280 | * @note - The system frequency computed by this function is not the real
281 | * frequency in the chip. It is calculated based on the predefined
282 | * constant and the selected clock source:
283 | *
284 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
285 | *
286 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
287 | *
288 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
289 | * or HSI_VALUE(*) multiplied by the PLL factors.
290 | *
291 | * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
292 | * 8 MHz) but the real value may vary depending on the variations
293 | * in voltage and temperature.
294 | *
295 | * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
296 | * 8 MHz or 25 MHz, depedning on the product used), user has to ensure
297 | * that HSE_VALUE is same as the real frequency of the crystal used.
298 | * Otherwise, this function may have wrong result.
299 | *
300 | * - The result of this function could be not correct when using fractional
301 | * value for HSE crystal.
302 | * @retval None
303 | */
304 | void SystemCoreClockUpdate (void)
305 | {
306 | uint32_t tmp = 0, pllmull = 0, pllsource = 0;
307 |
308 | #ifdef STM32F10X_CL
309 | uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
310 | #endif /* STM32F10X_CL */
311 |
312 | #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
313 | uint32_t prediv1factor = 0;
314 | #endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL */
315 |
316 | /* Get SYSCLK source -------------------------------------------------------*/
317 | tmp = RCC->CFGR & RCC_CFGR_SWS;
318 |
319 | switch (tmp)
320 | {
321 | case 0x00: /* HSI used as system clock */
322 | SystemCoreClock = HSI_VALUE;
323 | break;
324 | case 0x04: /* HSE used as system clock */
325 | SystemCoreClock = HSE_VALUE;
326 | break;
327 | case 0x08: /* PLL used as system clock */
328 |
329 | /* Get PLL clock source and multiplication factor ----------------------*/
330 | pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
331 | pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
332 |
333 | #ifndef STM32F10X_CL
334 | pllmull = ( pllmull >> 18) + 2;
335 |
336 | if (pllsource == 0x00)
337 | {
338 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */
339 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
340 | }
341 | else
342 | {
343 | #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
344 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
345 | /* HSE oscillator clock selected as PREDIV1 clock entry */
346 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
347 | #else
348 | /* HSE selected as PLL clock entry */
349 | if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
350 | {/* HSE oscillator clock divided by 2 */
351 | SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
352 | }
353 | else
354 | {
355 | SystemCoreClock = HSE_VALUE * pllmull;
356 | }
357 | #endif
358 | }
359 | #else
360 | pllmull = pllmull >> 18;
361 |
362 | if (pllmull != 0x0D)
363 | {
364 | pllmull += 2;
365 | }
366 | else
367 | { /* PLL multiplication factor = PLL input clock * 6.5 */
368 | pllmull = 13 / 2;
369 | }
370 |
371 | if (pllsource == 0x00)
372 | {
373 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */
374 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
375 | }
376 | else
377 | {/* PREDIV1 selected as PLL clock entry */
378 |
379 | /* Get PREDIV1 clock source and division factor */
380 | prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
381 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
382 |
383 | if (prediv1source == 0)
384 | {
385 | /* HSE oscillator clock selected as PREDIV1 clock entry */
386 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
387 | }
388 | else
389 | {/* PLL2 clock selected as PREDIV1 clock entry */
390 |
391 | /* Get PREDIV2 division factor and PLL2 multiplication factor */
392 | prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;
393 | pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2;
394 | SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
395 | }
396 | }
397 | #endif /* STM32F10X_CL */
398 | break;
399 |
400 | default:
401 | SystemCoreClock = HSI_VALUE;
402 | break;
403 | }
404 |
405 | /* Compute HCLK clock frequency ----------------*/
406 | /* Get HCLK prescaler */
407 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
408 | /* HCLK clock frequency */
409 | SystemCoreClock >>= tmp;
410 | }
411 |
412 | /**
413 | * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
414 | * @param None
415 | * @retval None
416 | */
417 | static void SetSysClock(void)
418 | {
419 | #ifdef SYSCLK_FREQ_HSE
420 | SetSysClockToHSE();
421 | #elif defined SYSCLK_FREQ_24MHz
422 | SetSysClockTo24();
423 | #elif defined SYSCLK_FREQ_36MHz
424 | SetSysClockTo36();
425 | #elif defined SYSCLK_FREQ_48MHz
426 | SetSysClockTo48();
427 | #elif defined SYSCLK_FREQ_56MHz
428 | SetSysClockTo56();
429 | #elif defined SYSCLK_FREQ_72MHz
430 | SetSysClockTo72();
431 | #endif
432 |
433 | /* If none of the define above is enabled, the HSI is used as System clock
434 | source (default after reset) */
435 | }
436 |
437 | /**
438 | * @brief Setup the external memory controller. Called in startup_stm32f10x.s
439 | * before jump to __main
440 | * @param None
441 | * @retval None
442 | */
443 | #ifdef DATA_IN_ExtSRAM
444 | /**
445 | * @brief Setup the external memory controller.
446 | * Called in startup_stm32f10x_xx.s/.c before jump to main.
447 | * This function configures the external SRAM mounted on STM3210E-EVAL
448 | * board (STM32 High density devices). This SRAM will be used as program
449 | * data memory (including heap and stack).
450 | * @param None
451 | * @retval None
452 | */
453 | void SystemInit_ExtMemCtl(void)
454 | {
455 | /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
456 | required, then adjust the Register Addresses */
457 |
458 | /* Enable FSMC clock */
459 | RCC->AHBENR = 0x00000114;
460 |
461 | /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
462 | RCC->APB2ENR = 0x000001E0;
463 |
464 | /* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
465 | /*---------------- SRAM Address lines configuration -------------------------*/
466 | /*---------------- NOE and NWE configuration --------------------------------*/
467 | /*---------------- NE3 configuration ----------------------------------------*/
468 | /*---------------- NBL0, NBL1 configuration ---------------------------------*/
469 |
470 | GPIOD->CRL = 0x44BB44BB;
471 | GPIOD->CRH = 0xBBBBBBBB;
472 |
473 | GPIOE->CRL = 0xB44444BB;
474 | GPIOE->CRH = 0xBBBBBBBB;
475 |
476 | GPIOF->CRL = 0x44BBBBBB;
477 | GPIOF->CRH = 0xBBBB4444;
478 |
479 | GPIOG->CRL = 0x44BBBBBB;
480 | GPIOG->CRH = 0x44444B44;
481 |
482 | /*---------------- FSMC Configuration ---------------------------------------*/
483 | /*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
484 |
485 | FSMC_Bank1->BTCR[4] = 0x00001011;
486 | FSMC_Bank1->BTCR[5] = 0x00000200;
487 | }
488 | #endif /* DATA_IN_ExtSRAM */
489 |
490 | #ifdef SYSCLK_FREQ_HSE
491 | /**
492 | * @brief Selects HSE as System clock source and configure HCLK, PCLK2
493 | * and PCLK1 prescalers.
494 | * @note This function should be used only after reset.
495 | * @param None
496 | * @retval None
497 | */
498 | static void SetSysClockToHSE(void)
499 | {
500 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
501 |
502 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
503 | /* Enable HSE */
504 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
505 |
506 | /* Wait till HSE is ready and if Time out is reached exit */
507 | do
508 | {
509 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
510 | StartUpCounter++;
511 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
512 |
513 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
514 | {
515 | HSEStatus = (uint32_t)0x01;
516 | }
517 | else
518 | {
519 | HSEStatus = (uint32_t)0x00;
520 | }
521 |
522 | if (HSEStatus == (uint32_t)0x01)
523 | {
524 |
525 | #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL
526 | /* Enable Prefetch Buffer */
527 | FLASH->ACR |= FLASH_ACR_PRFTBE;
528 |
529 | /* Flash 0 wait state */
530 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
531 |
532 | #ifndef STM32F10X_CL
533 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
534 | #else
535 | if (HSE_VALUE <= 24000000)
536 | {
537 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
538 | }
539 | else
540 | {
541 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
542 | }
543 | #endif /* STM32F10X_CL */
544 | #endif
545 |
546 | /* HCLK = SYSCLK */
547 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
548 |
549 | /* PCLK2 = HCLK */
550 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
551 |
552 | /* PCLK1 = HCLK */
553 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
554 |
555 | /* Select HSE as system clock source */
556 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
557 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE;
558 |
559 | /* Wait till HSE is used as system clock source */
560 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04)
561 | {
562 | }
563 | }
564 | else
565 | { /* If HSE fails to start-up, the application will have wrong clock
566 | configuration. User can add here some code to deal with this error */
567 | }
568 | }
569 | #elif defined SYSCLK_FREQ_24MHz
570 | /**
571 | * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2
572 | * and PCLK1 prescalers.
573 | * @note This function should be used only after reset.
574 | * @param None
575 | * @retval None
576 | */
577 | static void SetSysClockTo24(void)
578 | {
579 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
580 |
581 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
582 | /* Enable HSE */
583 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
584 |
585 | /* Wait till HSE is ready and if Time out is reached exit */
586 | do
587 | {
588 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
589 | StartUpCounter++;
590 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
591 |
592 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
593 | {
594 | HSEStatus = (uint32_t)0x01;
595 | }
596 | else
597 | {
598 | HSEStatus = (uint32_t)0x00;
599 | }
600 |
601 | if (HSEStatus == (uint32_t)0x01)
602 | {
603 | #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL
604 | /* Enable Prefetch Buffer */
605 | FLASH->ACR |= FLASH_ACR_PRFTBE;
606 |
607 | /* Flash 0 wait state */
608 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
609 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
610 | #endif
611 |
612 | /* HCLK = SYSCLK */
613 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
614 |
615 | /* PCLK2 = HCLK */
616 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
617 |
618 | /* PCLK1 = HCLK */
619 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
620 |
621 | #ifdef STM32F10X_CL
622 | /* Configure PLLs ------------------------------------------------------*/
623 | /* PLL configuration: PLLCLK = PREDIV1 * 6 = 24 MHz */
624 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
625 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
626 | RCC_CFGR_PLLMULL6);
627 |
628 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
629 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */
630 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
631 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
632 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
633 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);
634 |
635 | /* Enable PLL2 */
636 | RCC->CR |= RCC_CR_PLL2ON;
637 | /* Wait till PLL2 is ready */
638 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
639 | {
640 | }
641 | #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
642 | /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */
643 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
644 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6);
645 | #else
646 | /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */
647 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
648 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL6);
649 | #endif /* STM32F10X_CL */
650 |
651 | /* Enable PLL */
652 | RCC->CR |= RCC_CR_PLLON;
653 |
654 | /* Wait till PLL is ready */
655 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
656 | {
657 | }
658 |
659 | /* Select PLL as system clock source */
660 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
661 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
662 |
663 | /* Wait till PLL is used as system clock source */
664 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
665 | {
666 | }
667 | }
668 | else
669 | { /* If HSE fails to start-up, the application will have wrong clock
670 | configuration. User can add here some code to deal with this error */
671 | }
672 | }
673 | #elif defined SYSCLK_FREQ_36MHz
674 | /**
675 | * @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2
676 | * and PCLK1 prescalers.
677 | * @note This function should be used only after reset.
678 | * @param None
679 | * @retval None
680 | */
681 | static void SetSysClockTo36(void)
682 | {
683 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
684 |
685 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
686 | /* Enable HSE */
687 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
688 |
689 | /* Wait till HSE is ready and if Time out is reached exit */
690 | do
691 | {
692 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
693 | StartUpCounter++;
694 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
695 |
696 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
697 | {
698 | HSEStatus = (uint32_t)0x01;
699 | }
700 | else
701 | {
702 | HSEStatus = (uint32_t)0x00;
703 | }
704 |
705 | if (HSEStatus == (uint32_t)0x01)
706 | {
707 | /* Enable Prefetch Buffer */
708 | FLASH->ACR |= FLASH_ACR_PRFTBE;
709 |
710 | /* Flash 1 wait state */
711 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
712 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
713 |
714 | /* HCLK = SYSCLK */
715 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
716 |
717 | /* PCLK2 = HCLK */
718 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
719 |
720 | /* PCLK1 = HCLK */
721 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
722 |
723 | #ifdef STM32F10X_CL
724 | /* Configure PLLs ------------------------------------------------------*/
725 |
726 | /* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */
727 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
728 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
729 | RCC_CFGR_PLLMULL9);
730 |
731 | /*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
732 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */
733 |
734 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
735 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
736 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
737 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);
738 |
739 | /* Enable PLL2 */
740 | RCC->CR |= RCC_CR_PLL2ON;
741 | /* Wait till PLL2 is ready */
742 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
743 | {
744 | }
745 |
746 | #else
747 | /* PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */
748 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
749 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9);
750 | #endif /* STM32F10X_CL */
751 |
752 | /* Enable PLL */
753 | RCC->CR |= RCC_CR_PLLON;
754 |
755 | /* Wait till PLL is ready */
756 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
757 | {
758 | }
759 |
760 | /* Select PLL as system clock source */
761 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
762 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
763 |
764 | /* Wait till PLL is used as system clock source */
765 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
766 | {
767 | }
768 | }
769 | else
770 | { /* If HSE fails to start-up, the application will have wrong clock
771 | configuration. User can add here some code to deal with this error */
772 | }
773 | }
774 | #elif defined SYSCLK_FREQ_48MHz
775 | /**
776 | * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2
777 | * and PCLK1 prescalers.
778 | * @note This function should be used only after reset.
779 | * @param None
780 | * @retval None
781 | */
782 | static void SetSysClockTo48(void)
783 | {
784 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
785 |
786 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
787 | /* Enable HSE */
788 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
789 |
790 | /* Wait till HSE is ready and if Time out is reached exit */
791 | do
792 | {
793 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
794 | StartUpCounter++;
795 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
796 |
797 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
798 | {
799 | HSEStatus = (uint32_t)0x01;
800 | }
801 | else
802 | {
803 | HSEStatus = (uint32_t)0x00;
804 | }
805 |
806 | if (HSEStatus == (uint32_t)0x01)
807 | {
808 | /* Enable Prefetch Buffer */
809 | FLASH->ACR |= FLASH_ACR_PRFTBE;
810 |
811 | /* Flash 1 wait state */
812 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
813 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
814 |
815 | /* HCLK = SYSCLK */
816 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
817 |
818 | /* PCLK2 = HCLK */
819 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
820 |
821 | /* PCLK1 = HCLK */
822 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
823 |
824 | #ifdef STM32F10X_CL
825 | /* Configure PLLs ------------------------------------------------------*/
826 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
827 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
828 |
829 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
830 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
831 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
832 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
833 |
834 | /* Enable PLL2 */
835 | RCC->CR |= RCC_CR_PLL2ON;
836 | /* Wait till PLL2 is ready */
837 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
838 | {
839 | }
840 |
841 |
842 | /* PLL configuration: PLLCLK = PREDIV1 * 6 = 48 MHz */
843 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
844 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
845 | RCC_CFGR_PLLMULL6);
846 | #else
847 | /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */
848 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
849 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6);
850 | #endif /* STM32F10X_CL */
851 |
852 | /* Enable PLL */
853 | RCC->CR |= RCC_CR_PLLON;
854 |
855 | /* Wait till PLL is ready */
856 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
857 | {
858 | }
859 |
860 | /* Select PLL as system clock source */
861 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
862 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
863 |
864 | /* Wait till PLL is used as system clock source */
865 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
866 | {
867 | }
868 | }
869 | else
870 | { /* If HSE fails to start-up, the application will have wrong clock
871 | configuration. User can add here some code to deal with this error */
872 | }
873 | }
874 |
875 | #elif defined SYSCLK_FREQ_56MHz
876 | /**
877 | * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2
878 | * and PCLK1 prescalers.
879 | * @note This function should be used only after reset.
880 | * @param None
881 | * @retval None
882 | */
883 | static void SetSysClockTo56(void)
884 | {
885 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
886 |
887 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
888 | /* Enable HSE */
889 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
890 |
891 | /* Wait till HSE is ready and if Time out is reached exit */
892 | do
893 | {
894 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
895 | StartUpCounter++;
896 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
897 |
898 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
899 | {
900 | HSEStatus = (uint32_t)0x01;
901 | }
902 | else
903 | {
904 | HSEStatus = (uint32_t)0x00;
905 | }
906 |
907 | if (HSEStatus == (uint32_t)0x01)
908 | {
909 | /* Enable Prefetch Buffer */
910 | FLASH->ACR |= FLASH_ACR_PRFTBE;
911 |
912 | /* Flash 2 wait state */
913 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
914 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
915 |
916 | /* HCLK = SYSCLK */
917 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
918 |
919 | /* PCLK2 = HCLK */
920 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
921 |
922 | /* PCLK1 = HCLK */
923 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
924 |
925 | #ifdef STM32F10X_CL
926 | /* Configure PLLs ------------------------------------------------------*/
927 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
928 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
929 |
930 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
931 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
932 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
933 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
934 |
935 | /* Enable PLL2 */
936 | RCC->CR |= RCC_CR_PLL2ON;
937 | /* Wait till PLL2 is ready */
938 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
939 | {
940 | }
941 |
942 |
943 | /* PLL configuration: PLLCLK = PREDIV1 * 7 = 56 MHz */
944 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
945 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
946 | RCC_CFGR_PLLMULL7);
947 | #else
948 | /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */
949 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
950 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL7);
951 |
952 | #endif /* STM32F10X_CL */
953 |
954 | /* Enable PLL */
955 | RCC->CR |= RCC_CR_PLLON;
956 |
957 | /* Wait till PLL is ready */
958 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
959 | {
960 | }
961 |
962 | /* Select PLL as system clock source */
963 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
964 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
965 |
966 | /* Wait till PLL is used as system clock source */
967 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
968 | {
969 | }
970 | }
971 | else
972 | { /* If HSE fails to start-up, the application will have wrong clock
973 | configuration. User can add here some code to deal with this error */
974 | }
975 | }
976 |
977 | #elif defined SYSCLK_FREQ_72MHz
978 | /**
979 | * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2
980 | * and PCLK1 prescalers.
981 | * @note This function should be used only after reset.
982 | * @param None
983 | * @retval None
984 | */
985 | static void SetSysClockTo72(void)
986 | {
987 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
988 |
989 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
990 | /* Enable HSE */
991 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
992 |
993 | /* Wait till HSE is ready and if Time out is reached exit */
994 | do
995 | {
996 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
997 | StartUpCounter++;
998 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
999 |
1000 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
1001 | {
1002 | HSEStatus = (uint32_t)0x01;
1003 | }
1004 | else
1005 | {
1006 | HSEStatus = (uint32_t)0x00;
1007 | }
1008 |
1009 | if (HSEStatus == (uint32_t)0x01)
1010 | {
1011 | /* Enable Prefetch Buffer */
1012 | FLASH->ACR |= FLASH_ACR_PRFTBE;
1013 |
1014 | /* Flash 2 wait state */
1015 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
1016 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
1017 |
1018 |
1019 | /* HCLK = SYSCLK */
1020 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
1021 |
1022 | /* PCLK2 = HCLK */
1023 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
1024 |
1025 | /* PCLK1 = HCLK */
1026 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
1027 |
1028 | #ifdef STM32F10X_CL
1029 | /* Configure PLLs ------------------------------------------------------*/
1030 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
1031 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
1032 |
1033 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
1034 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
1035 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
1036 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
1037 |
1038 | /* Enable PLL2 */
1039 | RCC->CR |= RCC_CR_PLL2ON;
1040 | /* Wait till PLL2 is ready */
1041 | while((RCC->CR & RCC_CR_PLL2RDY) == 0)
1042 | {
1043 | }
1044 |
1045 |
1046 | /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */
1047 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
1048 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
1049 | RCC_CFGR_PLLMULL9);
1050 | #else
1051 | /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
1052 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
1053 | RCC_CFGR_PLLMULL));
1054 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
1055 | #endif /* STM32F10X_CL */
1056 |
1057 | /* Enable PLL */
1058 | RCC->CR |= RCC_CR_PLLON;
1059 |
1060 | /* Wait till PLL is ready */
1061 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
1062 | {
1063 | }
1064 |
1065 | /* Select PLL as system clock source */
1066 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
1067 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
1068 |
1069 | /* Wait till PLL is used as system clock source */
1070 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
1071 | {
1072 | }
1073 | }
1074 | else
1075 | { /* If HSE fails to start-up, the application will have wrong clock
1076 | configuration. User can add here some code to deal with this error */
1077 | }
1078 | }
1079 | #endif
1080 |
1081 | /**
1082 | * @}
1083 | */
1084 |
1085 | /**
1086 | * @}
1087 | */
1088 |
1089 | /**
1090 | * @}
1091 | */
1092 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
1093 |
--------------------------------------------------------------------------------
/test/md_readbit.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import sys
3 | import minimalmodbus
4 |
5 | if len(sys.argv) == 2:
6 | slave = int(sys.argv[1], 0)
7 | else:
8 | slave = 0x02
9 |
10 | x = minimalmodbus.Instrument('/dev/ttyUSB0', slave)
11 | x.serial.parity = 'E'
12 |
13 | #x.debug = True
14 |
15 | print "bit_input: %d" % x.read_register(16, 0, 4, False)
16 | print "coil: %d" % x.read_register(17, 0, 4, False)
17 | print "short_input: %d" % x.read_register(18, 0, 4, False)
18 | print "holding: %d" % x.read_register(19, 0, 4, False)
19 | print
20 |
21 | print "bit_input [0]: %d" % x.read_bit(0, 2)
22 | print "bit_input [1]: %d" % x.read_bit(1, 2)
23 | print
24 |
25 | x.write_bit(0, 1, 5)
26 | print "coil [0]: " + str(x.read_bit(0, 1))
27 |
28 | x.write_bit(0, 0, 15)
29 | print "coil [0]: " + str(x.read_bit(0, 1))
30 |
31 | print
32 |
33 | adc = x.read_register(20 , 0, 4, False)
34 | print "short_input[0]: %4d\t%.2f%%" % (adc, adc / 40.95)
35 | adc = x.read_register(21, 0, 4, False)
36 | print "short_input[1]: %4d\t%.2f%%" % (adc, adc / 40.95)
37 |
38 | print
39 |
40 | print "uuid: %s" % x.read_string(0, 16, 4)
41 |
42 |
43 | '''
44 | x.write_string(10, "hello", 3)
45 | print x.read_string(10, 3, 3)
46 |
47 | x.write_string(10, "world", 3)
48 | print x.read_string(10, 3, 3)
49 | '''
50 |
51 | '''
52 | 02050000ff008C09
53 | 020500000000CDf9
54 |
55 | 00050000ff008DEB
56 | 000500000000CC1B
57 |
58 | '''
59 |
--------------------------------------------------------------------------------