├── .gitignore
├── Makefile
├── README.md
├── STM32F103C_MINI
├── board.c
├── board.h
└── board.mk
├── STM32F103x8.ld
├── aes
├── aes.mk
├── inc
│ ├── aes.h
│ ├── aes_user_options.h
│ └── util.h
└── src
│ ├── aes_add_round_key.c
│ ├── aes_decrypt_cbc.c
│ ├── aes_decrypt_cfb.c
│ ├── aes_decrypt_ecb.c
│ ├── aes_decrypt_ofb.c
│ ├── aes_encrypt_cbc.c
│ ├── aes_encrypt_cfb.c
│ ├── aes_encrypt_ecb.c
│ ├── aes_encrypt_ofb.c
│ ├── aes_get_rcon.c
│ ├── aes_get_sbox.c
│ ├── aes_get_sbox_inv.c
│ ├── aes_included_galois_multiplication.c
│ ├── aes_initialize.c
│ ├── aes_key_expansion.c
│ ├── aes_mix_columns.c
│ ├── aes_mix_columns_inv.c
│ ├── aes_rot_word.c
│ ├── aes_shift_rows.c
│ ├── aes_shift_rows_inv.c
│ ├── aes_src.h
│ ├── aes_sub_bytes.c
│ ├── aes_sub_bytes_inv.c
│ └── aes_sub_word.c
├── aes_secret.sample.h
├── am2302.c
├── am2302.h
├── bh1750.c
├── bh1750.h
├── build
├── rsensor.bin
└── rsensor.elf
├── chconf.h
├── devices.txt
├── ds1820b.c
├── ds1820b.h
├── halconf.h
├── main.c
├── main.h
├── mcuconf.h
├── nrf24l01.c
├── nrf24l01.h
├── nrf_spi.c
├── nrf_spi.h
├── oneWire.c
├── oneWire.h
├── owtemp.c
├── owtemp.h
├── sensors.c
├── sensors.h
├── stm32f103c_mini.txt
└── util
├── floatp10.c
├── itoa.c
├── printfs.c
├── printfs.h
└── utoa.c
/.gitignore:
--------------------------------------------------------------------------------
1 | .dep
2 | .settings
3 | .cproject
4 | .project
5 | build/lst
6 | build/obj
7 | build/rsensor.hex
8 | build/rsensor.dmp
9 | build/rsensor.map
10 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | ##############################################################################
2 | # Build global options
3 | # NOTE: Can be overridden externally.
4 | #
5 |
6 | # Compiler options here.
7 | ifeq ($(USE_OPT),)
8 | USE_OPT = -O2 -std=gnu99 -ggdb -fomit-frame-pointer -falign-functions=16
9 | endif
10 |
11 | # C specific options here (added to USE_OPT).
12 | ifeq ($(USE_COPT),)
13 | USE_COPT =
14 | endif
15 |
16 | # C++ specific options here (added to USE_OPT).
17 | ifeq ($(USE_CPPOPT),)
18 | USE_CPPOPT = -fno-rtti
19 | endif
20 |
21 | # Enable this if you want the linker to remove unused code and data
22 | ifeq ($(USE_LINK_GC),)
23 | USE_LINK_GC = yes
24 | endif
25 |
26 | # If enabled, this option allows to compile the application in THUMB mode.
27 | ifeq ($(USE_THUMB),)
28 | USE_THUMB = yes
29 | endif
30 |
31 | # Enable this if you want to see the full log while compiling.
32 | ifeq ($(USE_VERBOSE_COMPILE),)
33 | USE_VERBOSE_COMPILE = yes
34 | endif
35 |
36 | #
37 | # Build global options
38 | ##############################################################################
39 |
40 | ##############################################################################
41 | # Architecture or project specific options
42 | #
43 |
44 | # Enable this if you really want to use the STM FWLib.
45 | ifeq ($(USE_FWLIB),)
46 | USE_FWLIB = no
47 | endif
48 |
49 | #
50 | # Architecture or project specific options
51 | ##############################################################################
52 |
53 | ##############################################################################
54 | # Project, sources and paths
55 | #
56 |
57 | # Define project name here
58 | PROJECT = rsensor
59 |
60 | # Imported source files and paths
61 | CHIBIOS = ../chibios/ChibiOS_2.6.5
62 | include STM32F103C_MINI/board.mk
63 | include $(CHIBIOS)/os/hal/platforms/STM32F1xx/platform.mk
64 | include $(CHIBIOS)/os/hal/hal.mk
65 | include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F1xx/port.mk
66 | include $(CHIBIOS)/os/kernel/kernel.mk
67 | include aes/aes.mk
68 |
69 | # Define linker script file here
70 | LDSCRIPT= STM32F103x8.ld
71 |
72 | # C sources that can be compiled in ARM or THUMB mode depending on the global
73 | # setting.
74 | CSRC = $(PORTSRC) \
75 | $(KERNSRC) \
76 | $(HALSRC) \
77 | $(PLATFORMSRC) \
78 | $(BOARDSRC) \
79 | $(CHIBIOS)/os/various/shell.c \
80 | $(CHIBIOS)/os/various/syscalls.c \
81 | $(CHIBIOS)/os/various/chrtclib.c \
82 | $(CHIBIOS)/os/various/chprintf.c \
83 | owtemp.c ds1820b.c oneWire.c \
84 | $(AESSRC) \
85 | am2302.c \
86 | bh1750.c \
87 | nrf24l01.c nrf_spi.c \
88 | main.c
89 |
90 | # sensors.c \
91 |
92 | # C++ sources that can be compiled in ARM or THUMB mode depending on the global
93 | # setting.
94 | CPPSRC =
95 |
96 | # C sources to be compiled in ARM mode regardless of the global setting.
97 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
98 | # option that results in lower performance and larger code size.
99 | ACSRC =
100 |
101 | # C++ sources to be compiled in ARM mode regardless of the global setting.
102 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
103 | # option that results in lower performance and larger code size.
104 | ACPPSRC =
105 |
106 | # C sources to be compiled in THUMB mode regardless of the global setting.
107 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
108 | # option that results in lower performance and larger code size.
109 | TCSRC =
110 |
111 | # C sources to be compiled in THUMB mode regardless of the global setting.
112 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
113 | # option that results in lower performance and larger code size.
114 | TCPPSRC =
115 |
116 | # List ASM source files here
117 | ASMSRC = $(PORTASM)
118 |
119 | INCDIR = $(PORTINC) $(KERNINC) \
120 | $(HALINC) $(PLATFORMINC) $(BOARDINC) \
121 | $(CHIBIOS)/os/various $(AESINC)
122 |
123 | #
124 | # Project, sources and paths
125 | ##############################################################################
126 |
127 | ##############################################################################
128 | # Compiler settings
129 | #
130 |
131 | MCU = cortex-m3
132 |
133 | #TRGT = arm-elf-
134 | TRGT = arm-none-eabi-
135 | CC = $(TRGT)gcc
136 | CPPC = $(TRGT)g++
137 | # Enable loading with g++ only if you need C++ runtime support.
138 | # NOTE: You can use C++ even without C++ support if you are careful. C++
139 | # runtime support makes code size explode.
140 | LD = $(TRGT)gcc
141 | #LD = $(TRGT)g++
142 | CP = $(TRGT)objcopy
143 | AS = $(TRGT)gcc -x assembler-with-cpp
144 | OD = $(TRGT)objdump
145 | HEX = $(CP) -O ihex
146 | BIN = $(CP) -O binary
147 |
148 | # ARM-specific options here
149 | AOPT =
150 |
151 | # THUMB-specific options here
152 | TOPT = -mthumb -DTHUMB
153 |
154 | # Define C warning options here
155 | CWARN = -Wall -Wextra -Wstrict-prototypes
156 |
157 | # Define C++ warning options here
158 | CPPWARN = -Wall -Wextra
159 |
160 | #
161 | # Compiler settings
162 | ##############################################################################
163 |
164 | ##############################################################################
165 | # Start of default section
166 | #
167 |
168 | # List all default C defines here, like -D_DEBUG=1
169 | #DDEFS = -DSTDOUT_SD=SD1 -DSTDIN_SD=SD1
170 | DDEFS =
171 |
172 | # List all default ASM defines here, like -D_DEBUG=1
173 | DADEFS =
174 |
175 | # List all default directories to look for include files here
176 | DINCDIR =
177 |
178 | # List the default directory to look for the libraries here
179 | DLIBDIR =
180 |
181 | # List all default libraries here
182 | DLIBS =
183 |
184 | #
185 | # End of default section
186 | ##############################################################################
187 |
188 | ##############################################################################
189 | # Start of user section
190 | #
191 |
192 | # List all user C define here, like -D_DEBUG=1
193 | UDEFS =
194 |
195 | # Define ASM defines here
196 | UADEFS =
197 |
198 | # List all user directories here
199 | UINCDIR =
200 |
201 | # List the user directory to look for the libraries here
202 | ULIBDIR =
203 |
204 | # List all user libraries here
205 | ULIBS =
206 |
207 | #
208 | # End of user defines
209 | ##############################################################################
210 |
211 | ifeq ($(USE_FWLIB),yes)
212 | include $(CHIBIOS)/ext/stm32lib/stm32lib.mk
213 | CSRC += $(STM32SRC)
214 | INCDIR += $(STM32INC)
215 | USE_OPT += -DUSE_STDPERIPH_DRIVER
216 | endif
217 |
218 | include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk
219 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndruPol/remote-sensor/59614bfc98fa650fa8272af7875d21d7f5ca32bf/README.md
--------------------------------------------------------------------------------
/STM32F103C_MINI/board.c:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include "ch.h"
18 | #include "hal.h"
19 |
20 | /**
21 | * @brief PAL setup.
22 | * @details Digital I/O ports static configuration as defined in @p board.h.
23 | * This variable is used by the HAL when initializing the PAL driver.
24 | */
25 | #if HAL_USE_PAL || defined(__DOXYGEN__)
26 | const PALConfig pal_default_config =
27 | {
28 | {VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH},
29 | {VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH},
30 | {VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH},
31 | };
32 | #endif
33 |
34 | /*
35 | * Early initialization code.
36 | * This initialization must be performed just after stack setup and before
37 | * any other initialization.
38 | */
39 | void __early_init(void) {
40 |
41 | stm32_clock_init();
42 | }
43 |
44 | #if HAL_USE_MMC_SPI
45 | /* Board-related functions related to the MMC_SPI driver.*/
46 | bool_t mmc_lld_is_card_inserted(MMCDriver *mmcp) {
47 |
48 | (void)mmcp;
49 | // return palReadPad(GPIOB, GPIOB_MMCCP);
50 | return TRUE;
51 | }
52 |
53 | bool_t mmc_lld_is_write_protected(MMCDriver *mmcp) {
54 |
55 | (void)mmcp;
56 | // return !palReadPad(GPIOC, GPIOC_MMCWP);
57 | return FALSE;
58 | }
59 | #endif
60 |
61 | /*
62 | * Board-specific initialization code.
63 | */
64 | void boardInit(void) {
65 | }
66 |
--------------------------------------------------------------------------------
/STM32F103C_MINI/board.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef _BOARD_H_
18 | #define _BOARD_H_
19 |
20 | /*
21 | * Setup for the STM32F103C-MINNI proto board.
22 | */
23 |
24 | /*
25 | * Board identifier.
26 | */
27 | #define BOARD_STM32F103C_MINNI
28 | #define BOARD_NAME "STM32F103C-MINNI"
29 |
30 | /*
31 | * Board frequencies.
32 | */
33 | #define STM32_LSECLK 32768
34 | #define STM32_HSECLK 8000000
35 |
36 | /*
37 | * MCU type, supported types are defined in ./os/hal/platforms/hal_lld.h.
38 | */
39 | #define STM32F10X_MD
40 |
41 | /*
42 | * IO pins assignments.
43 | */
44 | #define GPIOA_PIN0 0
45 | #define GPIOA_PIN1 1
46 | #define GPIOA_PIN2 2
47 | #define GPIOA_PIN3 3
48 | #define GPIOA_PIN4 4
49 | #define GPIOA_PIN5 5
50 | #define GPIOA_PIN6 6
51 | #define GPIOA_PIN7 7
52 | #define GPIOA_PIN8 8
53 | #define GPIOA_USART1_TX 9
54 | #define GPIOA_USART1_RX 10
55 | #define GPIOA_USB_DM 11
56 | #define GPIOA_USB_DP 12
57 | #define GPIOA_JTMS 13
58 | #define GPIOA_JTCK 14
59 | #define GPIOA_JTDI 15
60 |
61 |
62 | #define GPIOB_PIN0 0
63 | #define GPIOB_PIN1 1
64 | #define GPIOB_BOOT1 2
65 | #define GPIOB_JTDO 3
66 | #define GPIOB_JNTRST 4
67 | #define GPIOB_PIN5 5
68 | #define GPIOB_PIN6 6
69 | #define GPIOB_PIN7 7
70 | #define GPIOB_PIN8 8
71 | #define GPIOB_PIN9 9
72 | #define GPIOB_PIN10 10
73 | #define GPIOB_PIN11 11
74 | #define GPIOB_PIN12 12
75 | #define GPIOB_PIN13 13
76 | #define GPIOB_PIN14 14
77 | #define GPIOB_PIN15 15
78 |
79 | /*
80 | * I/O ports initial setup, this configuration is established soon after reset
81 | * in the initialization code.
82 | *
83 | * The digits have the following meaning:
84 | * 0 - Analog input.
85 | * 1 - Push Pull output 10MHz.
86 | * 2 - Push Pull output 2MHz.
87 | * 3 - Push Pull output 50MHz.
88 | * 4 - Digital input.
89 | * 5 - Open Drain output 10MHz.
90 | * 6 - Open Drain output 2MHz.
91 | * 7 - Open Drain output 50MHz.
92 | * 8 - Digital input with PullUp or PullDown resistor depending on ODR.
93 | * 9 - Alternate Push Pull output 10MHz.
94 | * A - Alternate Push Pull output 2MHz.
95 | * B - Alternate Push Pull output 50MHz.
96 | * C - Reserved.
97 | * D - Alternate Open Drain output 10MHz.
98 | * E - Alternate Open Drain output 2MHz.
99 | * F - Alternate Open Drain output 50MHz.
100 | * Please refer to the STM32 Reference Manual for details.
101 | */
102 |
103 | /*
104 | * Port A setup.
105 | * Everything input with pull-up except:
106 | * PA9 - Alternate output (USART1 TX).
107 | * PA10 - Normal input (USART1 RX).
108 | * PA11 - Normal input (USB DM).
109 | * PA12 - Normal input (USB DP).
110 | */
111 | #define VAL_GPIOACRL 0x88888888 /* PA7...PA0 */
112 | #define VAL_GPIOACRH 0x888444B8 /* PA15...PA8 */
113 | #define VAL_GPIOAODR 0xFFFFFFFF
114 |
115 | /*
116 | * Port B setup.
117 | * Everything input with pull-up except:
118 | */
119 | #define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */
120 | #define VAL_GPIOBCRH 0x88888888 /* PB15...PB8 */
121 | #define VAL_GPIOBODR 0xFFFFFFFF
122 |
123 | /*
124 | * Port C setup.
125 | * Everything input with pull-up except:
126 | */
127 | #define VAL_GPIOCCRL 0x88888888 /* PC7...PC0 */
128 | #define VAL_GPIOCCRH 0x88888888 /* PC15...PC8 */
129 | #define VAL_GPIOCODR 0xFFFFFFFF
130 |
131 | /*
132 | * USB bus activation macro, required by the USB driver.
133 | */
134 | //#define usb_lld_connect_bus(usbp) palClearPad(GPIOC, GPIOC_USB_DISC)
135 | #define usb_lld_connect_bus(usbp) palSetPadMode(GPIOA, GPIOA_USB_DP, PAL_MODE_INPUT);
136 |
137 | /*
138 | * USB bus de-activation macro, required by the USB driver.
139 | */
140 | #define usb_lld_disconnect_bus(usbp) { \
141 | palSetPadMode(GPIOA, GPIOA_USB_DP, PAL_MODE_OUTPUT_PUSHPULL); \
142 | palClearPad(GPIOA, GPIOA_USB_DP); \
143 | }
144 |
145 | #if !defined(_FROM_ASM_)
146 | #ifdef __cplusplus
147 | extern "C" {
148 | #endif
149 | void boardInit(void);
150 | #ifdef __cplusplus
151 | }
152 | #endif
153 | #endif /* _FROM_ASM_ */
154 |
155 | #endif /* _BOARD_H_ */
156 |
--------------------------------------------------------------------------------
/STM32F103C_MINI/board.mk:
--------------------------------------------------------------------------------
1 | # List of all the board related files.
2 | BOARDSRC = STM32F103C_MINI/board.c
3 |
4 | # Required include directories
5 | BOARDINC = STM32F103C_MINI
6 |
--------------------------------------------------------------------------------
/STM32F103x8.ld:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
3 | 2011,2012,2013 Giovanni Di Sirio.
4 |
5 | This file is part of ChibiOS/RT.
6 |
7 | ChibiOS/RT is free software; you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation; either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | ChibiOS/RT is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 |
20 | ---
21 |
22 | A special exception to the GPL can be applied should you wish to distribute
23 | a combined work that includes ChibiOS/RT, without being obliged to provide
24 | the source code for any proprietary components. See the file exception.txt
25 | for full details of how and when the exception can be applied.
26 | */
27 |
28 | /*
29 | * ST32F103x8 memory setup.
30 | */
31 | __main_stack_size__ = 0x0800;
32 | __process_stack_size__ = 0x0400;
33 |
34 | MEMORY
35 | {
36 | flash : org = 0x08000000, len = 64k
37 | ram : org = 0x20000000, len = 20k
38 | }
39 |
40 | __ram_start__ = ORIGIN(ram);
41 | __ram_size__ = LENGTH(ram);
42 | __ram_end__ = __ram_start__ + __ram_size__;
43 |
44 | ENTRY(ResetHandler)
45 |
46 | SECTIONS
47 | {
48 | . = 0;
49 | _text = .;
50 |
51 | startup : ALIGN(16) SUBALIGN(16)
52 | {
53 | KEEP(*(vectors))
54 | } > flash
55 |
56 | constructors : ALIGN(4) SUBALIGN(4)
57 | {
58 | PROVIDE(__init_array_start = .);
59 | KEEP(*(SORT(.init_array.*)))
60 | KEEP(*(.init_array))
61 | PROVIDE(__init_array_end = .);
62 | } > flash
63 |
64 | destructors : ALIGN(4) SUBALIGN(4)
65 | {
66 | PROVIDE(__fini_array_start = .);
67 | KEEP(*(.fini_array))
68 | KEEP(*(SORT(.fini_array.*)))
69 | PROVIDE(__fini_array_end = .);
70 | } > flash
71 |
72 | .text : ALIGN(16) SUBALIGN(16)
73 | {
74 | *(.text.startup.*)
75 | *(.text)
76 | *(.text.*)
77 | *(.rodata)
78 | *(.rodata.*)
79 | *(.glue_7t)
80 | *(.glue_7)
81 | *(.gcc*)
82 | } > flash
83 |
84 | .ARM.extab :
85 | {
86 | *(.ARM.extab* .gnu.linkonce.armextab.*)
87 | } > flash
88 |
89 | .ARM.exidx : {
90 | PROVIDE(__exidx_start = .);
91 | *(.ARM.exidx* .gnu.linkonce.armexidx.*)
92 | PROVIDE(__exidx_end = .);
93 | } > flash
94 |
95 | .eh_frame_hdr :
96 | {
97 | *(.eh_frame_hdr)
98 | } > flash
99 |
100 | .eh_frame : ONLY_IF_RO
101 | {
102 | *(.eh_frame)
103 | } > flash
104 |
105 | .textalign : ONLY_IF_RO
106 | {
107 | . = ALIGN(8);
108 | } > flash
109 |
110 | _etext = .;
111 | _textdata = _etext;
112 |
113 | .stacks :
114 | {
115 | . = ALIGN(8);
116 | __main_stack_base__ = .;
117 | . += __main_stack_size__;
118 | . = ALIGN(8);
119 | __main_stack_end__ = .;
120 | __process_stack_base__ = .;
121 | __main_thread_stack_base__ = .;
122 | . += __process_stack_size__;
123 | . = ALIGN(8);
124 | __process_stack_end__ = .;
125 | __main_thread_stack_end__ = .;
126 | } > ram
127 |
128 | .data :
129 | {
130 | . = ALIGN(4);
131 | PROVIDE(_data = .);
132 | *(.data)
133 | . = ALIGN(4);
134 | *(.data.*)
135 | . = ALIGN(4);
136 | *(.ramtext)
137 | . = ALIGN(4);
138 | PROVIDE(_edata = .);
139 | } > ram AT > flash
140 |
141 | .bss :
142 | {
143 | . = ALIGN(4);
144 | PROVIDE(_bss_start = .);
145 | *(.bss)
146 | . = ALIGN(4);
147 | *(.bss.*)
148 | . = ALIGN(4);
149 | *(COMMON)
150 | . = ALIGN(4);
151 | PROVIDE(_bss_end = .);
152 | } > ram
153 | }
154 |
155 | PROVIDE(end = .);
156 | _end = .;
157 |
158 | __heap_base__ = _end;
159 | __heap_end__ = __ram_end__;
160 |
--------------------------------------------------------------------------------
/aes/aes.mk:
--------------------------------------------------------------------------------
1 | #
2 | #
3 |
4 | AESSRC = aes/src/aes_add_round_key.c \
5 | aes/src/aes_get_rcon.c \
6 | aes/src/aes_get_sbox.c \
7 | aes/src/aes_get_sbox_inv.c \
8 | aes/src/aes_included_galois_multiplication.c \
9 | aes/src/aes_key_expansion.c \
10 | aes/src/aes_mix_columns.c \
11 | aes/src/aes_mix_columns_inv.c \
12 | aes/src/aes_rot_word.c \
13 | aes/src/aes_sub_word.c \
14 | aes/src/aes_shift_rows.c \
15 | aes/src/aes_shift_rows_inv.c \
16 | aes/src/aes_sub_bytes.c \
17 | aes/src/aes_sub_bytes_inv.c \
18 | aes/src/aes_initialize.c \
19 | aes/src/aes_decrypt_ecb.c \
20 | aes/src/aes_encrypt_ecb.c
21 |
22 | AESINC = aes/inc
23 |
--------------------------------------------------------------------------------
/aes/inc/aes.h:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes.h
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #ifndef AES_H_
14 | #define AES_H_
15 |
16 | #include "util.h"
17 | #include "aes_user_options.h"
18 |
19 |
20 | ///////////////////////////////////////////////////////////////////////////////
21 | // Nb is the number of columns in the state matrix, which is always 4 with AES
22 | ///////////////////////////////////////////////////////////////////////////////
23 | #define Nb 4
24 |
25 | ///////////////////////////////////////////////////
26 | // Nk is the number of the 32-bit words in the key
27 | ///////////////////////////////////////////////////
28 | #define Nk_128 4
29 | #define Nk_192 6
30 | #define Nk_256 8
31 |
32 | ///////////////////////////////////////////////////////
33 | // Nr is the number of rounds to execute the algorithm
34 | ///////////////////////////////////////////////////////
35 | #define Nr_128 10
36 | #define Nr_192 12
37 | #define Nr_256 14
38 |
39 |
40 | ////////////////////////////////////////////////////////////
41 | // Enumeration to tell aes_initialize() how long the key is
42 | ////////////////////////////////////////////////////////////
43 | typedef enum
44 | {
45 | AES_KEY_LENGTH_128_BITS,
46 | AES_KEY_LENGTH_192_BITS,
47 | AES_KEY_LENGTH_256_BITS
48 | } aes_key_length_t;
49 |
50 | ////////////////////////////////////////////////////////////
51 | // Structure for holding data for an AES algorithm instance
52 | ////////////////////////////////////////////////////////////
53 | typedef struct
54 | {
55 | //For w, use the worst case size (i.e., that for 256 bit keys)
56 | unsigned char state[4][Nb];
57 | unsigned char w[4][Nb * (Nr_256 + 1)];
58 |
59 | //Nb is left out since it is always 4, there's no need to waste a byte of memory for it
60 | unsigned char Nk;
61 | unsigned char Nr;
62 |
63 | //Variable to hold initialization vector or intermediate data in CBC, CFB, and OFB modes
64 | unsigned char iv_or_intermediate_data[16];
65 |
66 | //Variable to hold a remaining bytes of key block data used for CFB and OFB modes
67 | unsigned int rem_key_bytes;
68 | } aes_data_t;
69 |
70 |
71 | ///////////////////////
72 | // Function prototypes
73 | ///////////////////////
74 | void aes_initialize(aes_data_t * aes_data_p, aes_key_length_t aes_key_length, const unsigned char * key, const unsigned char * iv) __REENTRANT;
75 |
76 | void aes_encrypt_ecb(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block) __REENTRANT;
77 | void aes_decrypt_ecb(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block) __REENTRANT;
78 |
79 | #if (AES_ALLOW_NON_ECB_BLOCK_CIPHER_MODES != 0)
80 | void aes_encrypt_cbc(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block) __REENTRANT;
81 | void aes_decrypt_cbc(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block) __REENTRANT;
82 |
83 | void aes_encrypt_cfb(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block, unsigned int len) __REENTRANT;
84 | void aes_decrypt_cfb(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block, unsigned int len) __REENTRANT;
85 |
86 | void aes_encrypt_ofb(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block, unsigned int len) __REENTRANT;
87 | void aes_decrypt_ofb(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block, unsigned int len) __REENTRANT;
88 | #endif
89 |
90 | #endif /* AES_H_ */
91 |
--------------------------------------------------------------------------------
/aes/inc/aes_user_options.h:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_user_options.h
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #ifndef AES_USER_OPTIONS_H_
14 | #define AES_USER_OPTIONS_H_
15 |
16 | /////////////////////////////////////////////////////////////
17 | // User options (recompile library if these are changed)
18 | /////////////////////////////////////////////////////////////
19 | #define AES_FORCE_TABLES_INTO_CODE_MEMORY_WITH_SDCC 0 //Force the sbox, sbox_inv, and rcon tables into code memory using the __code keyword (only for SDCC)
20 | #define AES_FORCE_FUNCTIONS_AS_REENTRANT_WITH_SDCC 0 //Force the aes_*_encrypt() and aes_*_decrypt() functions to be compiled as __reentrant
21 | #define AES_USE_USER_DEFINED_GALOIS_MULTIPLY_FUNCTION 0 //Use section below to define an alternate Galois multiplier function than the one used in the library
22 | #define AES_ALLOW_NON_ECB_BLOCK_CIPHER_MODES 0 //Allow the use of CBC, CFB, and OFB modes of operation in addition to ECB
23 |
24 |
25 | ///////////////////////////////////////////////////////////
26 | // Definition for a user-defined Galois multiplier
27 | ///////////////////////////////////////////////////////////
28 | #if (AES_USE_USER_DEFINED_GALOIS_MULTIPLY_FUNCTION != 0)
29 | //You must provide an alternate Galois multiply function that follows the following form (inlining the function is optional):
30 | // [inline] unsigned char galois_multiply_function(unsigned char a, unsigned char b)
31 | // where a and b are the multiplier/muliplicand and the return value is the Galois product.
32 | extern inline unsigned char enc_dec_accel_galois_multiply(unsigned char a, unsigned char b); //Extern function or include the header file for the function here
33 |
34 | #define aes_user_defined_galois_multiplication(a, b) enc_dec_accel_galois_multiply(a, b) //Change the name of the second function to your own
35 | #endif
36 |
37 |
38 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
39 | // Definition of __REENTRANT (use AES_FORCE_CRYPT_FUNCTIONS_REENTRANT_WITH_SDCC above to change...do not modify section below this comment!)
40 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
41 | #if (AES_FORCE_FUNCTIONS_AS_REENTRANT_WITH_SDCC != 0)
42 | #define __REENTRANT __reentrant
43 | #else
44 | #define __REENTRANT
45 | #endif
46 |
47 |
48 | #endif /* AES_USER_OPTIONS_H_ */
49 |
--------------------------------------------------------------------------------
/aes/inc/util.h:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: util.h
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #ifndef UTIL_H_
14 | #define UTIL_H_
15 |
16 |
17 |
18 |
19 |
20 | ///////////////////////
21 | // Function prototypes
22 | ///////////////////////
23 | void util_xor_arrays(const unsigned char * input_block_a, const unsigned char * input_block_b, unsigned char * output_block, unsigned int len);
24 | void util_copy_array(const unsigned char * input_block, unsigned char * output_block, unsigned int len);
25 |
26 |
27 | #endif /* UTIL_H_ */
28 |
--------------------------------------------------------------------------------
/aes/src/aes_add_round_key.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_add_round_key.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_add_round_key(aes_data_t * aes_data_p, unsigned char round)
20 | //
21 | // Description:
22 | // Adds the round key at "round" in w[] to state[].
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | // unsigned char round - round of key to add
27 | //
28 | // Return value:
29 | // None
30 | //
31 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32 | void aes_add_round_key(aes_data_t * aes_data_p, unsigned char round) __REENTRANT
33 | {
34 | unsigned char row, col;
35 |
36 | //loop through and add the appropriate state and round bytes
37 | for(row = 0; row < 4; row++)
38 | {
39 | for(col = 0; col < Nb; col++)
40 | {
41 | aes_data_p->state[row][col] = aes_data_p->state[row][col] ^ aes_data_p->w[row][(round * 4) + col];
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/aes/src/aes_decrypt_cbc.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_decrypt_cbc.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | #if (AES_ALLOW_NON_ECB_BLOCK_CIPHER_MODES != 0)
18 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 | //
20 | // void aes_decrypt_cbc(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block);
21 | //
22 | // Description:
23 | // Decrypts an input block of cipher text into an output block of plain text using cipher-block chaining (CBC) mode
24 | //
25 | // Parameters:
26 | // aes_data_t * aes_data_p - data structure for this instance
27 | // const unsigned char * input_cipher_text_block - cipher text to be decrypted (the first 16 bytes of this array will be decrypted)
28 | // unsigned char * output_plain_text_block - decrypted plain text (must be at least 16 bytes in length)
29 | //
30 | // Return value:
31 | // None
32 | //
33 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
34 | void aes_decrypt_cbc(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block) __REENTRANT
35 | {
36 | //The general algorithm for CBC decryption is
37 | // 1. Decrypt the cipher text
38 | // 2. XOR the IV (first decryption) or the previous cipher text block with the output of (1)
39 | // 3. Since the cipher text must be saved in aes_data_p->iv_or_intermediate_data, copy it
40 | aes_decrypt_ecb(aes_data_p, input_cipher_text_block, output_plain_text_block);
41 | util_xor_arrays(aes_data_p->iv_or_intermediate_data, output_plain_text_block, output_plain_text_block, 16);
42 | util_copy_array(input_cipher_text_block, aes_data_p->iv_or_intermediate_data, 16);
43 | }
44 | #endif
45 |
--------------------------------------------------------------------------------
/aes/src/aes_decrypt_cfb.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_decrypt_cfb.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | #if (AES_ALLOW_NON_ECB_BLOCK_CIPHER_MODES != 0)
18 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 | //
20 | // void aes_decrypt_cfb(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block,
21 | // unsigned char * output_plain_text_block, unsigned int len);
22 | //
23 | // Description:
24 | // Decrypts an input block of cipher text into an output block of plain text using cipher feedback (CFB) mode
25 | //
26 | // Parameters:
27 | // aes_data_t * aes_data_p - data structure for this instance
28 | // const unsigned char * input_plain_text_block - plain text to be encrypted (the first len bytes will be encrypted)
29 | // unsigned char * output_cipher_text_block - encrypted cipher text (must be at least len bytes in length)
30 | // unsigned int len - number of bytes to be encrypted (can be any valid unsigned integer value)
31 | //
32 | // Return value:
33 | // None
34 | //
35 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36 | void aes_decrypt_cfb(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block, unsigned int len) __REENTRANT
37 | {
38 | unsigned int i;
39 |
40 | //Since CFB allows turning a block cipher into a stream cipher, we can decrypt as many bytes as we want
41 | for(i = 0; i < len; i++)
42 | {
43 | //There are no key bytes left, so encrypt the IV/intermediate data to get another key byte block
44 | if(aes_data_p->rem_key_bytes == 0)
45 | {
46 | aes_encrypt_ecb(aes_data_p, aes_data_p->iv_or_intermediate_data, aes_data_p->iv_or_intermediate_data);
47 | aes_data_p->rem_key_bytes = 16;
48 | }
49 |
50 | //The general algorithm for CFB decryption is
51 | // 1. Set the current output plain text byte to the XOR of the current key byte and the current byte from the input cipher text
52 | // 2. Copy the current input cipher text byte to the current IV/intermediate data byte
53 | // 3. Decrement the number of remaining key block bytes
54 | output_plain_text_block[i] = aes_data_p->iv_or_intermediate_data[16 - aes_data_p->rem_key_bytes] ^ input_cipher_text_block[i];
55 | aes_data_p->iv_or_intermediate_data[16 - aes_data_p->rem_key_bytes] = input_cipher_text_block[i];
56 | aes_data_p->rem_key_bytes--;
57 | }
58 | }
59 | #endif
60 |
--------------------------------------------------------------------------------
/aes/src/aes_decrypt_ecb.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_decrypt_ecb.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_decrypt_ecb(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block)
20 | //
21 | // Description:
22 | // Decrypts an input block of cipher text into an output block of plain text using electronic codebook (ECB) mode
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | // const unsigned char * input_cipher_text_block - cipher text to be decrypted (the first 16 bytes of this array will be decrypted)
27 | // unsigned char * output_plain_text_block - decrypted plain text (must be at least 16 bytes in length)
28 | //
29 | // Return value:
30 | // None
31 | //
32 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33 | void aes_decrypt_ecb(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block) __REENTRANT
34 | {
35 | unsigned char row, col, round;
36 |
37 | //start out by copying the input cipher text onto the state
38 | for(row = 0; row < 4; row++)
39 | {
40 | for(col = 0; col < Nb; col++)
41 | {
42 | aes_data_p->state[row][col] = input_cipher_text_block[row + (4 * col)];
43 | }
44 | }
45 |
46 | //add the round key at round Nr
47 | aes_add_round_key(aes_data_p, aes_data_p->Nr);
48 |
49 | //To take this for loop all the way down to zero, the exit clause would look weird (either round < 255 or round != 255),
50 | // so we leave it out and just break when we have processed round zero.
51 | for(round = (aes_data_p->Nr - 1); ; round--)
52 | {
53 | aes_shift_rows_inv(aes_data_p);
54 | aes_sub_bytes_inv(aes_data_p);
55 |
56 | aes_add_round_key(aes_data_p, round);
57 |
58 | //we do not apply mix columns at iteration zero, but we do exit on iteration zero
59 | if(round != 0)
60 | {
61 | aes_mix_columns_inv(aes_data_p);
62 | }
63 | else
64 | {
65 | break;
66 | }
67 | }
68 |
69 | //copy the decrypted state onto the output plain text
70 | for(row = 0; row < 4; row++)
71 | {
72 | for(col = 0; col < Nb; col++)
73 | {
74 | output_plain_text_block[row + (4 * col)] = aes_data_p->state[row][col];
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/aes/src/aes_decrypt_ofb.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_decrypt_ofb.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | #if (AES_ALLOW_NON_ECB_BLOCK_CIPHER_MODES != 0)
18 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 | //
20 | // void aes_decrypt_ofb(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block,
21 | // unsigned char * output_plain_text_block, unsigned int len);
22 | //
23 | // Description:
24 | // Decrypts an input block of cipher text into an output block of plain text using output feedback (OFB) mode
25 | //
26 | // Parameters:
27 | // aes_data_t * aes_data_p - data structure for this instance
28 | // const unsigned char * input_plain_text_block - plain text to be encrypted (the first len bytes will be encrypted)
29 | // unsigned char * output_cipher_text_block - encrypted cipher text (must be at least len bytes in length)
30 | // unsigned int len - number of bytes to be encrypted (can be any valid unsigned integer value)
31 | //
32 | // Return value:
33 | // None
34 | //
35 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36 | void aes_decrypt_ofb(aes_data_t * aes_data_p, const unsigned char * input_cipher_text_block, unsigned char * output_plain_text_block, unsigned int len) __REENTRANT
37 | {
38 | unsigned int i;
39 |
40 | //Since OFB allows turning a block cipher into a stream cipher, we can decrypt as many bytes as we want
41 | for(i = 0; i < len; i++)
42 | {
43 | //There are no key bytes left, so encrypt the IV/intermediate data to get another key byte block
44 | if(aes_data_p->rem_key_bytes == 0)
45 | {
46 | aes_encrypt_ecb(aes_data_p, aes_data_p->iv_or_intermediate_data, aes_data_p->iv_or_intermediate_data);
47 | aes_data_p->rem_key_bytes = 16;
48 | }
49 |
50 | //The general algorithm for CFB decryption is
51 | // 1. Set the current output plain text byte to the XOR of the current key byte and the current byte from the input cipher text
52 | // 2. Decrement the number of remaining key block bytes
53 | output_plain_text_block[i] = aes_data_p->iv_or_intermediate_data[16 - aes_data_p->rem_key_bytes] ^ input_cipher_text_block[i];
54 | aes_data_p->rem_key_bytes--;
55 | }
56 | }
57 | #endif
58 |
--------------------------------------------------------------------------------
/aes/src/aes_encrypt_cbc.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_encrypt_cbc.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | #if (AES_ALLOW_NON_ECB_BLOCK_CIPHER_MODES != 0)
18 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 | //
20 | // void aes_encrypt_cbc(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block)
21 | //
22 | // Description:
23 | // Encrypts an input block of plain text into an output block of cipher text using cipher-block chaining (CBC) mode
24 | //
25 | // Parameters:
26 | // aes_data_t * aes_data_p - data structure for this instance
27 | // const unsigned char * input_plain_text_block - plain text to be encrypted (the first 16 bytes of this array will be encrypted)
28 | // unsigned char * output_cipher_text_block - encrypted cipher text (must be at least 16 bytes in length)
29 | //
30 | // Return value:
31 | // None
32 | //
33 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
34 | void aes_encrypt_cbc(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block) __REENTRANT
35 | {
36 | //The general algorithm for CBC encryption is
37 | // 1. XOR the IV (first decryption) or the previous cipher text block with the input plain text block
38 | // 2. Encryp the result of (1)
39 | // 3. Since the cipher text must be saved in aes_data_p->iv_or_intermediate_data, copy it
40 | util_xor_arrays(aes_data_p->iv_or_intermediate_data, input_plain_text_block, aes_data_p->iv_or_intermediate_data, 16);
41 | aes_encrypt_ecb(aes_data_p, aes_data_p->iv_or_intermediate_data, aes_data_p->iv_or_intermediate_data);
42 | util_copy_array(aes_data_p->iv_or_intermediate_data, output_cipher_text_block, 16);
43 | }
44 | #endif
45 |
--------------------------------------------------------------------------------
/aes/src/aes_encrypt_cfb.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_encrypt_cfb.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | #if (AES_ALLOW_NON_ECB_BLOCK_CIPHER_MODES != 0)
18 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 | //
20 | // void aes_encrypt_cfb(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block,
21 | // unsigned char * output_cipher_text_block, unsigned int len)
22 | //
23 | // Description:
24 | // Encrypts an input block of plain text into an output block of cipher text using cipher feedback (CFB) mode
25 | //
26 | // Parameters:
27 | // aes_data_t * aes_data_p - data structure for this instance
28 | // const unsigned char * input_plain_text_block - plain text to be encrypted (the first len bytes will be encrypted)
29 | // unsigned char * output_cipher_text_block - encrypted cipher text (must be at least len bytes in length)
30 | // unsigned int len - number of bytes to be encrypted (can be any valid unsigned integer value)
31 | //
32 | // Return value:
33 | // None
34 | //
35 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36 | void aes_encrypt_cfb(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block, unsigned int len) __REENTRANT
37 | {
38 | unsigned int i;
39 |
40 | //Since CFB allows turning a block cipher into a stream cipher, we can decrypt as many bytes as we want
41 | for(i = 0; i < len; i++)
42 | {
43 | //There are no key bytes left, so encrypt the IV/intermediate data to get another key byte block
44 | if(aes_data_p->rem_key_bytes == 0)
45 | {
46 | aes_encrypt_ecb(aes_data_p, aes_data_p->iv_or_intermediate_data, aes_data_p->iv_or_intermediate_data);
47 | aes_data_p->rem_key_bytes = 16;
48 | }
49 |
50 | //The general algorithm for CFB encryption is
51 | // 1. Set the current IV/intermediate data byte to itself XORed with the current input plain text byte
52 | // 2. Set the current output cipher text byte to the result of (1)
53 | // 3. Decrement the number of remaining key block bytes
54 | aes_data_p->iv_or_intermediate_data[16 - aes_data_p->rem_key_bytes] ^= input_plain_text_block[i];
55 | output_cipher_text_block[i] = aes_data_p->iv_or_intermediate_data[16 - aes_data_p->rem_key_bytes];
56 | aes_data_p->rem_key_bytes--;
57 | }
58 | }
59 | #endif
60 |
--------------------------------------------------------------------------------
/aes/src/aes_encrypt_ecb.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_encrypt_ecb.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_encrypt_ecb(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block)
20 | //
21 | // Description:
22 | // Encrypts an input block of plain text into an output block of cipher text using electronic codebook (ECB) mode
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | // const unsigned char * input_plain_text_block - plain text to be encrypted (the first 16 bytes of this array will be encrypted)
27 | // unsigned char * output_cipher_text_block - encrypted cipher text (must be at least 16 bytes in length)
28 | //
29 | // Return value:
30 | // None
31 | //
32 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33 | void aes_encrypt_ecb(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block) __REENTRANT
34 | {
35 | unsigned char row, col, round;
36 |
37 | //start out by copying the input plain text onto the state
38 | for(row = 0; row < 4; row++)
39 | {
40 | for(col = 0; col < Nb; col++)
41 | {
42 | aes_data_p->state[row][col] = input_plain_text_block[row + (4 * col)];
43 | }
44 | }
45 |
46 | //add the round key at round 0
47 | aes_add_round_key(aes_data_p, 0);
48 |
49 | //Rather than having round only count up to Nr - 1 and then calling the functions (less aes_mix_columns()) again outside
50 | // the for() loop, I am counting all the way up to Nr, but not calling aes_mix_columns on the last iteration.
51 | for(round = 1; round <= aes_data_p->Nr; round++)
52 | {
53 | aes_sub_bytes(aes_data_p);
54 | aes_shift_rows(aes_data_p);
55 |
56 | //don't apply mix columns on the last iteration
57 | if(round <= (aes_data_p->Nr - 1))
58 | {
59 | aes_mix_columns(aes_data_p);
60 | }
61 |
62 | aes_add_round_key(aes_data_p, round);
63 | }
64 |
65 | //copy the encrypted state onto the output cipher text
66 | for(row = 0; row < 4; row++)
67 | {
68 | for(col = 0; col < Nb; col++)
69 | {
70 | output_cipher_text_block[row + (4 * col)] = aes_data_p->state[row][col];
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/aes/src/aes_encrypt_ofb.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_encrypt_ofb.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | #if (AES_ALLOW_NON_ECB_BLOCK_CIPHER_MODES != 0)
18 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 | //
20 | // void aes_encrypt_ofb(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block,
21 | // unsigned char * output_cipher_text_block, unsigned int len)
22 | //
23 | // Description:
24 | // Encrypts an input block of plain text into an output block of cipher text using output feedback (OFB) mode
25 | //
26 | // Parameters:
27 | // aes_data_t * aes_data_p - data structure for this instance
28 | // const unsigned char * input_plain_text_block - plain text to be encrypted (the first len bytes will be encrypted)
29 | // unsigned char * output_cipher_text_block - encrypted cipher text (must be at least len bytes in length)
30 | // unsigned int len - number of bytes to be encrypted (can be any valid unsigned integer value)
31 | //
32 | // Return value:
33 | // None
34 | //
35 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36 | void aes_encrypt_ofb(aes_data_t * aes_data_p, const unsigned char * input_plain_text_block, unsigned char * output_cipher_text_block, unsigned int len) __REENTRANT
37 | {
38 | unsigned int i;
39 |
40 | //Since OFB allows turning a block cipher into a stream cipher, we can encrypt as many bytes as we want
41 | for(i = 0; i < len; i++)
42 | {
43 | //There are no key bytes left, so encrypt the IV/intermediate data to get another key byte block
44 | if(aes_data_p->rem_key_bytes == 0)
45 | {
46 | aes_encrypt_ecb(aes_data_p, aes_data_p->iv_or_intermediate_data, aes_data_p->iv_or_intermediate_data);
47 | aes_data_p->rem_key_bytes = 16;
48 | }
49 |
50 | //The general algorithm for CFB encryption is
51 | // 1. Set the current IV/intermediate data byte to itself XORed with the current input plain text byte
52 | // 3. Decrement the number of remaining key block bytes
53 | output_cipher_text_block[i] = aes_data_p->iv_or_intermediate_data[16 - aes_data_p->rem_key_bytes] ^ input_plain_text_block[i];
54 | aes_data_p->rem_key_bytes--;
55 | }
56 | }
57 | #endif
58 |
--------------------------------------------------------------------------------
/aes/src/aes_get_rcon.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_get_rcon.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // unsigned char aes_get_rcon(unsigned char index)
20 | //
21 | // Description:
22 | // Gets the specified rcon value
23 | //
24 | // Parameters:
25 | // unsigned char index - index into the rcon array
26 | //
27 | // Return value:
28 | // The specified rcon value
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | unsigned char aes_get_rcon(unsigned char index) __REENTRANT
32 | {
33 | //array to hold rcon values..."CODE" is only defined if using SDCC and forcing tables into code memory
34 | CODE static const unsigned char rcon[255] =
35 | {
36 | // 0 1 2 3 4 5 6 7 8 9 a b c d e f
37 | 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, //0
38 | 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, //1
39 | 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, //2
40 | 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, //3
41 | 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, //4
42 | 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, //5
43 | 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, //6
44 | 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, //7
45 | 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, //8
46 | 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, //9
47 | 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, //a
48 | 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, //b
49 | 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, //c
50 | 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, //d
51 | 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, //e
52 | 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb //f
53 | };
54 |
55 | //the array only has 255 entries, so guard against going out of bounds
56 | if(index == 255)
57 | {
58 | return 0;
59 | }
60 | else
61 | {
62 | return rcon[index];
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/aes/src/aes_get_sbox.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_get_sbox.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // unsigned char aes_get_sbox(unsigned char index)
20 | //
21 | // Description:
22 | // Gets the specified sbox value
23 | //
24 | // Parameters:
25 | // unsigned char index - index into the sbox array
26 | //
27 | // Return value:
28 | // The specified sbox value
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | unsigned char aes_get_sbox(unsigned char index) __REENTRANT
32 | {
33 | //array to hold sbox values..."CODE" is only defined if using SDCC and forcing tables into code memory
34 | CODE static const unsigned char sbox[256] =
35 | {
36 | // 0 1 2 3 4 5 6 7 8 9 a b c d e f
37 | 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
38 | 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
39 | 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
40 | 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
41 | 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
42 | 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
43 | 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
44 | 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
45 | 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
46 | 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
47 | 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //a
48 | 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //b
49 | 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //c
50 | 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //d
51 | 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //e
52 | 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 //f
53 | };
54 |
55 | return sbox[index];
56 | }
57 |
--------------------------------------------------------------------------------
/aes/src/aes_get_sbox_inv.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_get_sbox_inv.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // unsigned char aes_get_sbox_inv(unsigned char index)
20 | //
21 | // Description:
22 | // Gets the specified sbox_inv value
23 | //
24 | // Parameters:
25 | // unsigned char index - index into the sbox_inv array
26 | //
27 | // Return value:
28 | // The specified sbox_inv value
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | unsigned char aes_get_sbox_inv(unsigned char index) __REENTRANT
32 | {
33 | //array to hold sbox_inv values..."CODE" is only defined if using SDCC and forcing tables into code memory
34 | CODE static const unsigned char sbox_inv[256] =
35 | {
36 | // 0 1 2 3 4 5 6 7 8 9 a b c d e f
37 | 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, //0
38 | 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, //1
39 | 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, //2
40 | 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, //3
41 | 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, //4
42 | 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, //5
43 | 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, //6
44 | 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, //7
45 | 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, //8
46 | 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, //9
47 | 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, //a
48 | 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, //b
49 | 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, //c
50 | 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, //d
51 | 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, //d
52 | 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d //f
53 | };
54 |
55 | return sbox_inv[index];
56 | }
57 |
--------------------------------------------------------------------------------
/aes/src/aes_included_galois_multiplication.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_included_galois_multiplication.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // unsigned char aes_included_galois_multiplication(unsigned char a, unsigned char b)
20 | //
21 | // Description:
22 | // Executes a Galois multiplication over the field GF(2^8).
23 | //
24 | // Parameters:
25 | // unsigned char a - Multiplier in Galois multiplication
26 | // unsigned char b - Multiplicand in Galois multiplication
27 | //
28 | // Return value:
29 | // Galois multiplication of a and b over the field GF(2^8)
30 | //
31 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32 | unsigned char aes_included_galois_multiplication(unsigned char a, unsigned char b) __REENTRANT
33 | {
34 | unsigned char p = 0;
35 | unsigned char counter;
36 | unsigned char hi_bit_set;
37 |
38 | for(counter = 0; counter < 8; counter++)
39 | {
40 | if((b & 1) == 1)
41 | {
42 | p ^= a;
43 | }
44 |
45 | hi_bit_set = (a & 0x80);
46 | a <<= 1;
47 |
48 | if(hi_bit_set == 0x80)
49 | {
50 | a ^= 0x1b;
51 | }
52 |
53 | b >>= 1;
54 | }
55 |
56 | return p;
57 | }
58 |
--------------------------------------------------------------------------------
/aes/src/aes_initialize.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_initialize.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 | #include
16 |
17 |
18 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 | //
20 | // void aes_initialize(aes_data_t * aes_data_p, aes_key_length_t aes_key_length, const unsigned char * key, const unsigned char * iv)
21 | //
22 | // Description:
23 | // Initialize aes_data_p. This function only needs to be called before using aes_data_p the first time and then at any time the
24 | // key or key length is changed.
25 | //
26 | // Parameters:
27 | // aes_data_t * aes_data_p - data structure for this instance
28 | // aes_key_length_t aes_key_length - enumeration entry for the number of bits in the key
29 | // const unsigned char * key - key to use for encryption/decryption
30 | // const unsigned char * iv - only used with non-ECB modes, this is the initialization vector for encryption/decryption (set to
31 | // NULL to not use)
32 | //
33 | // Return value:
34 | // Galois multiplication of a and b over the field GF(2^8)
35 | //
36 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
37 | void aes_initialize(aes_data_t * aes_data_p, aes_key_length_t aes_key_length, const unsigned char * key, const unsigned char * iv) __REENTRANT
38 | {
39 | unsigned char i;
40 |
41 | //set up the constants to allow all 3 key lengths. Nb is not set here since it's always 4 for AES.
42 | if(aes_key_length == AES_KEY_LENGTH_128_BITS)
43 | {
44 | aes_data_p->Nk = Nk_128;
45 | aes_data_p->Nr = Nr_128;
46 | }
47 | else if(aes_key_length == AES_KEY_LENGTH_192_BITS)
48 | {
49 | aes_data_p->Nk = Nk_192;
50 | aes_data_p->Nr = Nr_192;
51 | }
52 | else
53 | {
54 | //default to 256 bit key length
55 | aes_data_p->Nk = Nk_256;
56 | aes_data_p->Nr = Nr_256;
57 | }
58 |
59 | //run the key expansion algorithm
60 | aes_key_expansion(aes_data_p, key);
61 |
62 | //Set up the initialization vector if provided
63 | if(iv != NULL)
64 | {
65 | for(i = 0; i < 16; i++)
66 | {
67 | aes_data_p->iv_or_intermediate_data[i] = iv[i];
68 | }
69 | }
70 |
71 | aes_data_p->rem_key_bytes = 0;
72 | }
73 |
--------------------------------------------------------------------------------
/aes/src/aes_key_expansion.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_key_expansion.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_key_expansion(aes_data_t * aes_data_p, unsigned char * key)
20 | //
21 | // Description:
22 | // Runs the key expansion algorithm
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | // const unsigned char * key - key to use for encryption/decryption
27 | //
28 | // Return value:
29 | // None
30 | //
31 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32 | void aes_key_expansion(aes_data_t * aes_data_p, unsigned char * key) __REENTRANT
33 | {
34 | unsigned char col;
35 | unsigned char temp[4];
36 |
37 | //the first round key is the key itself
38 | for(col = 0; col < aes_data_p->Nk; col++)
39 | {
40 | aes_data_p->w[0][col] = key[(4 * col)];
41 | aes_data_p->w[1][col] = key[(4 * col) + 1];
42 | aes_data_p->w[2][col] = key[(4 * col) + 2];
43 | aes_data_p->w[3][col] = key[(4 * col) + 3];
44 | }
45 |
46 | //subsequent rounds are derived from the previous round's key
47 | while (col < (Nb * (aes_data_p->Nr + 1)))
48 | {
49 | //copy the previous column
50 | temp[0] = aes_data_p->w[0][col - 1];
51 | temp[1] = aes_data_p->w[1][col - 1];
52 | temp[2] = aes_data_p->w[2][col - 1];
53 | temp[3] = aes_data_p->w[3][col - 1];
54 |
55 | //calculate the key adder
56 | if((col % aes_data_p->Nk) == 0)
57 | {
58 | aes_rot_word(temp);
59 | aes_sub_word(temp);
60 |
61 | //Only the zeroth entry has an item in rcon, the other three are 0's.
62 | //A value XOR'ed with 0 is itself, so we only need to XOR the zeroth entry.
63 | temp[0] = temp[0] ^ aes_get_rcon(col / aes_data_p->Nk);
64 | }
65 | else if((aes_data_p->Nk > 6) && ((col % aes_data_p->Nk) == 4))
66 | {
67 | aes_sub_word(temp);
68 | }
69 |
70 | //add the calculated word to the corresponding word in the previous round key to get the current key
71 | aes_data_p->w[0][col] = aes_data_p->w[0][col - aes_data_p->Nk] ^ temp[0];
72 | aes_data_p->w[1][col] = aes_data_p->w[1][col - aes_data_p->Nk] ^ temp[1];
73 | aes_data_p->w[2][col] = aes_data_p->w[2][col - aes_data_p->Nk] ^ temp[2];
74 | aes_data_p->w[3][col] = aes_data_p->w[3][col - aes_data_p->Nk] ^ temp[3];
75 |
76 | col++;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/aes/src/aes_mix_columns.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_mix_columns.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_mix_columns(aes_data_t * aes_data_p)
20 | //
21 | // Description:
22 | // Runs the mix columns algorithm
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | //
27 | // Return value:
28 | // None
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | void aes_mix_columns(aes_data_t * aes_data_p) __REENTRANT
32 | {
33 | unsigned char temp[4];
34 | unsigned char col;
35 |
36 | //go through each column and calculate the Galois multiplication
37 | for (col = 0; col < Nb; col++)
38 | {
39 | temp[0] = aes_data_p->state[0][col];
40 | temp[1] = aes_data_p->state[1][col];
41 | temp[2] = aes_data_p->state[2][col];
42 | temp[3] = aes_data_p->state[3][col];
43 |
44 | aes_data_p->state[0][col] = aes_galois_multiplication(temp[0], 2) ^
45 | aes_galois_multiplication(temp[3], 1) ^
46 | aes_galois_multiplication(temp[2], 1) ^
47 | aes_galois_multiplication(temp[1], 3);
48 |
49 | aes_data_p->state[1][col] = aes_galois_multiplication(temp[1], 2) ^
50 | aes_galois_multiplication(temp[0], 1) ^
51 | aes_galois_multiplication(temp[3], 1) ^
52 | aes_galois_multiplication(temp[2], 3);
53 |
54 | aes_data_p->state[2][col] = aes_galois_multiplication(temp[2], 2) ^
55 | aes_galois_multiplication(temp[1], 1) ^
56 | aes_galois_multiplication(temp[0], 1) ^
57 | aes_galois_multiplication(temp[3], 3);
58 |
59 | aes_data_p->state[3][col] = aes_galois_multiplication(temp[3], 2) ^
60 | aes_galois_multiplication(temp[2], 1) ^
61 | aes_galois_multiplication(temp[1], 1) ^
62 | aes_galois_multiplication(temp[0], 3);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/aes/src/aes_mix_columns_inv.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_mix_columns_inv.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_mix_columns_inv(aes_data_t * aes_data_p)
20 | //
21 | // Description:
22 | // Runs the inverted mix columns algorithm
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | //
27 | // Return value:
28 | // None
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | void aes_mix_columns_inv(aes_data_t * aes_data_p) __REENTRANT
32 | {
33 | unsigned char temp[4];
34 | unsigned char col;
35 |
36 | //go through each column and calculate the Galois multiplication
37 | for (col = 0; col < Nb; col++)
38 | {
39 | temp[0] = aes_data_p->state[0][col];
40 | temp[1] = aes_data_p->state[1][col];
41 | temp[2] = aes_data_p->state[2][col];
42 | temp[3] = aes_data_p->state[3][col];
43 |
44 | aes_data_p->state[0][col] = aes_galois_multiplication(temp[0], 14) ^
45 | aes_galois_multiplication(temp[3], 9) ^
46 | aes_galois_multiplication(temp[2], 13) ^
47 | aes_galois_multiplication(temp[1], 11);
48 |
49 | aes_data_p->state[1][col] = aes_galois_multiplication(temp[1], 14) ^
50 | aes_galois_multiplication(temp[0], 9) ^
51 | aes_galois_multiplication(temp[3], 13) ^
52 | aes_galois_multiplication(temp[2], 11);
53 |
54 | aes_data_p->state[2][col] = aes_galois_multiplication(temp[2], 14) ^
55 | aes_galois_multiplication(temp[1], 9) ^
56 | aes_galois_multiplication(temp[0], 13) ^
57 | aes_galois_multiplication(temp[3], 11);
58 |
59 | aes_data_p->state[3][col] = aes_galois_multiplication(temp[3], 14) ^
60 | aes_galois_multiplication(temp[2], 9) ^
61 | aes_galois_multiplication(temp[1], 13) ^
62 | aes_galois_multiplication(temp[0], 11);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/aes/src/aes_rot_word.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_rot_word.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_rot_word(unsigned char * word)
20 | //
21 | // Description:
22 | // Rotates a word one byte to the left
23 | //
24 | // Parameters:
25 | // unsigned char * word - pointer to the 4-byte word to rotate
26 | //
27 | // Return value:
28 | // None
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | void aes_rot_word(unsigned char * word) __REENTRANT
32 | {
33 | unsigned char temp;
34 |
35 | //rotate word one byte to the left
36 | temp = word[0];
37 | word[0] = word[1];
38 | word[1] = word[2];
39 | word[2] = word[3];
40 | word[3] = temp;
41 | }
42 |
--------------------------------------------------------------------------------
/aes/src/aes_shift_rows.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_shift_rows.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_shift_rows_inv(aes_data_t * aes_data_p)
20 | //
21 | // Description:
22 | // Shifts each row in the state by that row number of bytes to the left
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | //
27 | // Return value:
28 | // None
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | void aes_shift_rows(aes_data_t * aes_data_p) __REENTRANT
32 | {
33 | unsigned char temp;
34 |
35 | //row 0 does not get rotated
36 |
37 | //rotate row 1 left by 1 column
38 | temp = aes_data_p->state[1][0];
39 | aes_data_p->state[1][0] = aes_data_p->state[1][1];
40 | aes_data_p->state[1][1] = aes_data_p->state[1][2];
41 | aes_data_p->state[1][2] = aes_data_p->state[1][3];
42 | aes_data_p->state[1][3] = temp;
43 |
44 | //rotate row 2 left by 2 columns by switching items 0 and 2 and 1 and 3
45 | temp = aes_data_p->state[2][0];
46 | aes_data_p->state[2][0] = aes_data_p->state[2][2];
47 | aes_data_p->state[2][2] = temp;
48 | temp = aes_data_p->state[2][1];
49 | aes_data_p->state[2][1] = aes_data_p->state[2][3];
50 | aes_data_p->state[2][3] = temp;
51 |
52 | //rotate row 3 left by 3 columns
53 | temp = aes_data_p->state[3][0];
54 | aes_data_p->state[3][0] = aes_data_p->state[3][3];
55 | aes_data_p->state[3][3] = aes_data_p->state[3][2];
56 | aes_data_p->state[3][2] = aes_data_p->state[3][1];
57 | aes_data_p->state[3][1] = temp;
58 | }
59 |
--------------------------------------------------------------------------------
/aes/src/aes_shift_rows_inv.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_shift_rows_inv.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_shift_rows_inv(aes_data_t * aes_data_p)
20 | //
21 | // Description:
22 | // Shifts each row in the state by that row number of bytes to the right
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | //
27 | // Return value:
28 | // None
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | void aes_shift_rows_inv(aes_data_t * aes_data_p) __REENTRANT
32 | {
33 | unsigned char temp;
34 |
35 | //row 0 does not get rotated
36 |
37 | //rotate row 1 right by 1 column
38 | temp = aes_data_p->state[1][0];
39 | aes_data_p->state[1][0] = aes_data_p->state[1][3];
40 | aes_data_p->state[1][3] = aes_data_p->state[1][2];
41 | aes_data_p->state[1][2] = aes_data_p->state[1][1];
42 | aes_data_p->state[1][1] = temp;
43 |
44 | //rotate row 2 right by 2 columns by switching items 0 and 2 and 1 and 3
45 | temp = aes_data_p->state[2][0];
46 | aes_data_p->state[2][0] = aes_data_p->state[2][2];
47 | aes_data_p->state[2][2] = temp;
48 | temp = aes_data_p->state[2][1];
49 | aes_data_p->state[2][1] = aes_data_p->state[2][3];
50 | aes_data_p->state[2][3] = temp;
51 |
52 | //rotate row 3 right by 3 columns
53 | temp = aes_data_p->state[3][0];
54 | aes_data_p->state[3][0] = aes_data_p->state[3][1];
55 | aes_data_p->state[3][1] = aes_data_p->state[3][2];
56 | aes_data_p->state[3][2] = aes_data_p->state[3][3];
57 | aes_data_p->state[3][3] = temp;
58 | }
59 |
--------------------------------------------------------------------------------
/aes/src/aes_src.h:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_src.h
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #ifndef AES_SRC_H_
14 | #define AES_SRC_H_
15 |
16 | #include "aes.h"
17 | #include "aes_user_options.h"
18 |
19 |
20 | ////////////////////////////////////////////////////////////////////////////////////////////////
21 | // If the user is using SDCC and wants to force tables into code memory, use the __code keyword
22 | ////////////////////////////////////////////////////////////////////////////////////////////////
23 | #if (AES_FORCE_TABLES_INTO_CODE_MEMORY_WITH_SDCC != 0)
24 | #define CODE __code
25 | #else
26 | #define CODE
27 | #endif
28 |
29 |
30 | //////////////////////////////////////////////////////////////////////////////////////////////////
31 | // If the user has defined their own multiplier, set it up here. Otherwise, use the built-in one.
32 | //////////////////////////////////////////////////////////////////////////////////////////////////
33 | #if (AES_USE_USER_DEFINED_GALOIS_MULTIPLY_FUNCTION != 0)
34 | #define aes_galois_multiplication(a, b) aes_user_defined_galois_multiplication(a, b)
35 | #else
36 | #define aes_galois_multiplication(a, b) aes_included_galois_multiplication(a, b)
37 | #endif
38 |
39 |
40 | ///////////////////////
41 | // Function prototypes
42 | ///////////////////////
43 | unsigned char aes_get_sbox(unsigned char index) __REENTRANT;
44 | unsigned char aes_get_sbox_inv(unsigned char index) __REENTRANT;
45 | unsigned char aes_get_rcon(unsigned char index) __REENTRANT;
46 | void aes_rot_word(unsigned char * word) __REENTRANT;
47 | void aes_sub_word(unsigned char * word) __REENTRANT;
48 | void aes_shift_rows(aes_data_t * aes_data_p) __REENTRANT;
49 | void aes_shift_rows_inv(aes_data_t * aes_data_p) __REENTRANT;
50 | void aes_sub_bytes(aes_data_t * aes_data_p) __REENTRANT;
51 | void aes_sub_bytes_inv(aes_data_t * aes_data_p) __REENTRANT;
52 | void aes_add_round_key(aes_data_t * aes_data_p, unsigned char round) __REENTRANT;
53 | unsigned char aes_included_galois_multiplication(unsigned char a, unsigned char b) __REENTRANT;
54 | void aes_mix_columns(aes_data_t * aes_data_p) __REENTRANT;
55 | void aes_mix_columns_inv(aes_data_t * aes_data_p) __REENTRANT;
56 | void aes_key_expansion(aes_data_t * aes_data_p, unsigned char * key) __REENTRANT;
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/aes/src/aes_sub_bytes.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_sub_bytes.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_sub_bytes(aes_data_t * aes_data_p)
20 | //
21 | // Description:
22 | // Substitutes the values in the state array with corresponding values from the sbox array
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | //
27 | // Return value:
28 | // None
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | void aes_sub_bytes(aes_data_t * aes_data_p) __REENTRANT
32 | {
33 | int row, col;
34 |
35 | //substitute each byte in the state array with its corresponding entry in sbox[]
36 | for(row = 0; row < 4; row++)
37 | {
38 | for(col = 0; col < Nb; col++)
39 | {
40 | aes_data_p->state[row][col] = aes_get_sbox(aes_data_p->state[row][col]);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/aes/src/aes_sub_bytes_inv.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_sub_bytes_inv.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_sub_bytes_inv(aes_data_t * aes_data_p)
20 | //
21 | // Description:
22 | // Substitutes the values in the state array with corresponding values from the sbox_inv array
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | //
27 | // Return value:
28 | // None
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | void aes_sub_bytes_inv(aes_data_t * aes_data_p) __REENTRANT
32 | {
33 | int row, col;
34 |
35 | //substitute each byte in the state array with its corresponding entry in sbox_inv[]
36 | for(row = 0; row < 4; row++)
37 | {
38 | for(col = 0; col < Nb; col++)
39 | {
40 | aes_data_p->state[row][col] = aes_get_sbox_inv(aes_data_p->state[row][col]);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/aes/src/aes_sub_word.c:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////////////////////
2 | //
3 | // File: aes_sub_word.c
4 | //
5 | // Copyright S. Brennen Ball, 2010
6 | //
7 | // The author provides no guarantees, warantees, or promises, implied or
8 | // otherwise. By using this software you agree to indemnify the author
9 | // of any damages incurred by using it.
10 | //
11 | /////////////////////////////////////////////////////////////////////////////
12 |
13 | #include "aes.h"
14 | #include "aes_src.h"
15 |
16 |
17 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18 | //
19 | // void aes_sub_word(aes_data_t * aes_data_p)
20 | //
21 | // Description:
22 | // Substitutes the values in a word with corresponding values from the sbox array
23 | //
24 | // Parameters:
25 | // aes_data_t * aes_data_p - data structure for this instance
26 | //
27 | // Return value:
28 | // None
29 | //
30 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 | void aes_sub_word(unsigned char * word) __REENTRANT
32 | {
33 | //substitute each byte of "word" with its corresponding entry in sbox[]
34 | word[0] = aes_get_sbox(word[0]);
35 | word[1] = aes_get_sbox(word[1]);
36 | word[2] = aes_get_sbox(word[2]);
37 | word[3] = aes_get_sbox(word[3]);
38 | }
39 |
--------------------------------------------------------------------------------
/aes_secret.sample.h:
--------------------------------------------------------------------------------
1 | /*
2 | aes_secret.h - aes encryption key
3 | */
4 |
5 | static const unsigned char aes_key[16] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10};
--------------------------------------------------------------------------------
/am2302.c:
--------------------------------------------------------------------------------
1 | /*
2 | * DHT21/DHT22 driver
3 | */
4 |
5 | #include "ch.h"
6 | #include "hal.h"
7 |
8 | #include "am2302.h"
9 |
10 | #define DHT_BIT_TIMEOUT_US (80 * 4) /* one bit timeout */
11 | #define DHT_START_PULSE_MS 18
12 | #define DHT_IRQ_TIMEOUT_MS 2 /* irq timeout */
13 | #define DHT_PKT_SIZE 5
14 | #define DHT_PKT_TIMEOUT_MS 10
15 |
16 | #define DHT_CHANNEL1_GPIO GPIOA /* channel 1 GPIO */
17 | #define DHT_CHANNEL2_GPIO GPIOB /* channel 2 GPIO */
18 | #define DHT_CHANNEL1_PIN 15 /* channel 1 PIN */
19 | #define DHT_CHANNEL2_PIN 3 /* channel 2 PIN */
20 | #define DHT_CHANNEL1 ICU_CHANNEL_1
21 | #define DHT_CHANNEL2 ICU_CHANNEL_2
22 |
23 | #define ERROR_DIV 2
24 | #define PERIOD_OK(x, l, h) \
25 | ((x)->low >= ((l) - (l) / ERROR_DIV) && \
26 | (x)->low < ((l) + (l) / ERROR_DIV) && \
27 | ((x)->period - (x)->low) >= ((h) - (h) / ERROR_DIV) && \
28 | ((x)->period - (x)->low) < ((h) + (h) / ERROR_DIV))
29 | /*-----------------------------------------------------------------------------*/
30 |
31 | typedef struct _icu_capture_t icu_capture_t;
32 | struct _icu_capture_t {
33 | uint16_t period;
34 | uint16_t low;
35 | };
36 |
37 | typedef struct _dht_read_t dht_read_t;
38 | struct _dht_read_t {
39 | uint8_t channel; /* in */
40 | dht_error_t error; /* out */
41 | uint8_t data[DHT_PKT_SIZE]; /* out */
42 | };
43 |
44 | static BinarySemaphore icusem, cb_sem;
45 | static volatile icu_capture_t icu_data;
46 |
47 | static void icuwidthcb(ICUDriver *icup) {
48 | icu_data.low = icuGetWidth(icup);
49 | }
50 |
51 | static void icuperiodcb(ICUDriver *icup) {
52 | icu_data.period = icuGetPeriod(icup);
53 | chBSemSignalI(&cb_sem);
54 | }
55 |
56 | static void icuoverflowcb(ICUDriver *icup) {
57 | (void)icup;
58 | icu_data.period = 0;
59 | chBSemSignalI(&cb_sem);
60 | }
61 |
62 | static ICUConfig icucfgch1 = {
63 | ICU_INPUT_ACTIVE_LOW,
64 | 1000000, /* 1mHz ICU clock frequency. */
65 | icuwidthcb,
66 | icuperiodcb,
67 | icuoverflowcb,
68 | DHT_CHANNEL1,
69 | 0
70 | };
71 |
72 | static ICUConfig icucfgch2 = {
73 | ICU_INPUT_ACTIVE_LOW,
74 | 1000000, /* 1mHz ICU clock frequency. */
75 | icuwidthcb,
76 | icuperiodcb,
77 | icuoverflowcb,
78 | DHT_CHANNEL2,
79 | 0
80 | };
81 |
82 | /*
83 | * AM2302 read thread.
84 | */
85 | static Thread *DHTThread_p;
86 | static WORKING_AREA(waDHTThread, 128);
87 | __attribute__((noreturn))
88 | static msg_t DHTThread(void *arg) {
89 |
90 | (void)arg;
91 | chRegSetThreadName("DHTThd");
92 |
93 | chBSemInit(&cb_sem, TRUE);
94 | while (TRUE) {
95 | /* wait for read request */
96 | dht_read_t *req;
97 | Thread *tp;
98 | tp = chMsgWait();
99 | req = (dht_read_t *) chMsgGet(tp);
100 | chMsgRelease(tp, (msg_t) req);
101 |
102 | AFIO->MAPR |= AFIO_MAPR_TIM2_REMAP_NOREMAP;
103 |
104 | // set DHT pin low on 2ms
105 | if (req->channel == 1){
106 | palSetPadMode(DHT_CHANNEL1_GPIO, DHT_CHANNEL1_PIN, PAL_MODE_OUTPUT_OPENDRAIN);
107 | palClearPad(DHT_CHANNEL1_GPIO, DHT_CHANNEL1_PIN);
108 | }
109 | else if (req->channel == 2){
110 | palSetPadMode(DHT_CHANNEL2_GPIO, DHT_CHANNEL2_PIN, PAL_MODE_OUTPUT_OPENDRAIN);
111 | palClearPad(DHT_CHANNEL2_GPIO, DHT_CHANNEL2_PIN);
112 | }
113 | chThdSleepMilliseconds(DHT_START_PULSE_MS);
114 |
115 | AFIO->MAPR |= AFIO_MAPR_TIM2_REMAP_FULLREMAP;
116 |
117 | if (req->channel == 1){
118 | icuStart(&ICUD2, &icucfgch1);
119 | }
120 | else if (req->channel == 2){
121 | icuStart(&ICUD2, &icucfgch2);
122 | }
123 |
124 | if (req->channel == 1){
125 | palSetPadMode(DHT_CHANNEL1_GPIO, DHT_CHANNEL1_PIN, PAL_MODE_INPUT);
126 | }
127 | else if (req->channel == 2){
128 | palSetPadMode(DHT_CHANNEL2_GPIO, DHT_CHANNEL2_PIN, PAL_MODE_INPUT);
129 | }
130 | icuEnable(&ICUD2);
131 |
132 | /* skip first falling edge */
133 | int i;
134 | // IRQ timeout or receive timeout
135 | if(chBSemWaitTimeout(&cb_sem, MS2ST(DHT_IRQ_TIMEOUT_MS)) == RDY_TIMEOUT) {
136 | req->error = DHT_IRQ_TIMEOUT;
137 | goto reply;
138 | }
139 | if(!icu_data.period) {
140 | req->error = DHT_TIMEOUT;
141 | goto reply;
142 | }
143 |
144 | /* start sequence received */
145 | if(!PERIOD_OK(&icu_data, 80, 80)) {
146 | req->error = DHT_DECODE_ERROR;
147 | goto reply;
148 | }
149 |
150 | for(i = 0; i < DHT_PKT_SIZE; i++) {
151 | unsigned int mask = 0x80;
152 | uint8_t byte = 0;
153 | while(mask) {
154 | if(chBSemWaitTimeout(&cb_sem, MS2ST(DHT_IRQ_TIMEOUT_MS)) == RDY_TIMEOUT) {
155 | req->error = DHT_IRQ_TIMEOUT;
156 | goto reply;
157 | }
158 | if(!icu_data.period) {
159 | req->error = DHT_TIMEOUT;
160 | goto reply;
161 | }
162 |
163 | /* next bit received */
164 | if(PERIOD_OK(&icu_data, 50, 70)) {
165 | byte |= mask; /* 1 */
166 | } else if(!PERIOD_OK(&icu_data, 50, 27)) {
167 | req->error = DHT_DECODE_ERROR;
168 | goto reply;
169 | }
170 |
171 | mask >>= 1;
172 | }
173 | req->data[i] = byte;
174 | }
175 | req->error = DHT_NO_ERROR;
176 |
177 | reply:
178 | icuDisable(&ICUD2);
179 | icuStop(&ICUD2);
180 | chBSemSignal(&icusem);
181 | }
182 | }
183 |
184 | dht_error_t dht_read(uint8_t channel, int *temperature, int *humidity) {
185 | dht_read_t rd;
186 | dht_read_t *rd_p = &rd;
187 |
188 | rd.channel = channel;
189 |
190 | chBSemWait(&icusem); /* to be sure */
191 |
192 | chMsgSend(DHTThread_p, (msg_t) rd_p);
193 |
194 | /* wait for reply */
195 | if(chBSemWaitTimeout(&icusem, MS2ST(DHT_PKT_TIMEOUT_MS)) == RDY_TIMEOUT) {
196 | chBSemReset(&icusem, FALSE);
197 | return DHT_RCV_TIMEOUT;
198 | }
199 | chBSemReset(&icusem, FALSE);
200 |
201 | if(rd.error != DHT_NO_ERROR) {
202 | return rd.error;
203 | }
204 |
205 | /* compute checksum */
206 | unsigned int sum = 0;
207 | uint8_t i;
208 | for(i = 0; i < DHT_PKT_SIZE - 1; i++) sum += rd.data[i];
209 | if((sum & 0xff) != rd.data[i]) {
210 | return DHT_CHECKSUM_ERROR;
211 | }
212 |
213 | if (rd.data[1] == 0 && rd.data[3] == 0) { // DHT11
214 | *humidity = ((unsigned int)rd.data[0]);
215 | *temperature = ((unsigned int)rd.data[2]);
216 | }
217 | else { // DHT21/22
218 | /* read 16 bit humidity value */
219 | *humidity = ((unsigned int)rd.data[0] << 8) |
220 | (unsigned int)rd.data[1];
221 |
222 | /* read 16 bit temperature value */
223 | int val = ((unsigned int)rd.data[2] << 8) |
224 | (unsigned int)rd.data[3];
225 | *temperature = val & 0x8000 ? -(val & ~0x8000) : val;
226 | }
227 | return DHT_NO_ERROR;
228 | }
229 |
230 | void dht_init(void){
231 | AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE;
232 |
233 | chBSemInit(&icusem, FALSE);
234 | DHTThread_p = chThdCreateStatic(waDHTThread, sizeof(waDHTThread), DHT_PRIO, DHTThread, NULL);
235 | }
236 |
--------------------------------------------------------------------------------
/am2302.h:
--------------------------------------------------------------------------------
1 | #ifndef _AM2302_H_
2 | #define _AM2302_H_
3 | #ifdef __cplusplus
4 | extern "C" {
5 | #endif
6 |
7 | #define DHT_COLLECTION_PERIOD_MS 2000UL
8 | #define DHT_PRIO (NORMALPRIO+1)
9 |
10 | typedef enum {
11 | DHT_UNKNOWN,
12 | DHT_NO_ERROR,
13 | DHT_IRQ_TIMEOUT,
14 | DHT_TIMEOUT,
15 | DHT_RCV_TIMEOUT,
16 | DHT_DECODE_ERROR,
17 | DHT_CHECKSUM_ERROR,
18 | } dht_error_t;
19 |
20 | /*-----------------------------------------------------------------------------*/
21 | void dht_init(void);
22 | /* temperature in 1/10 deg C, humidity in 1/10 % */
23 | dht_error_t dht_read(uint8_t channel, int *temperature, int *humidity);
24 |
25 | #ifdef __cplusplus
26 | }
27 | #endif
28 | #endif
29 |
--------------------------------------------------------------------------------
/bh1750.c:
--------------------------------------------------------------------------------
1 | /*
2 | * bh1750.c
3 | */
4 |
5 | #include "ch.h"
6 | #include "hal.h"
7 |
8 | #include "bh1750.h"
9 |
10 | #define I2CD_BH1750 I2CD1
11 |
12 | #define BH1750_ADDR 0x23 // device address
13 | #define BH1750_PWR_DOWN 0x0 // No active state.
14 | #define BH1750_CONT_HMODE 0x10 // Continuously H-Resolution Mode
15 | #define BH1750_DELAY 200 // wait results (datasheet says max. 180ms)
16 | #define BH1750_TIMEOUT_MS 10 // i2c transmit timeout
17 |
18 | static const I2CConfig i2cfg = { OPMODE_I2C, 100000, STD_DUTY_CYCLE, };
19 |
20 | // read data
21 | bh1750_error_t bh1750_read(int16_t *value) {
22 | static uint8_t txbuf[2] = {0}, rxbuf[2] = {0};
23 |
24 | bh1750_error_t err = BH1750_NO_ERROR;
25 |
26 | i2cStart(&I2CD_BH1750, &i2cfg);
27 | i2cAcquireBus(&I2CD_BH1750);
28 | txbuf[0] = BH1750_CONT_HMODE;
29 | if (i2cMasterTransmitTimeout(&I2CD_BH1750, BH1750_ADDR, txbuf, 1, rxbuf, 0, MS2ST(BH1750_TIMEOUT_MS)) != RDY_OK){
30 | err = BH1750_TIMEOUT;
31 | goto error;
32 | }
33 | chThdSleepMilliseconds(BH1750_DELAY);
34 | txbuf[0] = BH1750_PWR_DOWN;
35 | if (i2cMasterTransmitTimeout(&I2CD_BH1750, BH1750_ADDR, txbuf, 1, rxbuf, 2, MS2ST(BH1750_TIMEOUT_MS)) != RDY_OK){
36 | err = BH1750_TIMEOUT;
37 | }
38 |
39 | error:
40 | i2cReleaseBus(&I2CD_BH1750);
41 | i2cStop(&I2CD_BH1750);
42 |
43 | if (err != BH1750_NO_ERROR){
44 | return err;
45 | }
46 |
47 | *value = ((rxbuf[0] << 8) + rxbuf[1])/1.2;
48 | return BH1750_NO_ERROR;
49 | }
50 |
51 | void bh1750_init(void) {
52 | // Start the i2c driver
53 | palSetPadMode(GPIOB, GPIOB_PIN6, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
54 | palSetPadMode(GPIOB, GPIOB_PIN7, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
55 | }
56 |
--------------------------------------------------------------------------------
/bh1750.h:
--------------------------------------------------------------------------------
1 | /*
2 | * bh1750.h
3 | */
4 |
5 | #ifndef BH1750_H_
6 | #define BH1750_H_
7 | #ifdef __cplusplus
8 | extern "C" {
9 | #endif
10 |
11 | #include "ch.h"
12 | #include "hal.h"
13 |
14 | typedef enum {
15 | BH1750_NO_ERROR,
16 | BH1750_ERROR,
17 | BH1750_TIMEOUT,
18 | } bh1750_error_t;
19 |
20 | typedef struct _bh1750_read_t bh1750_read_t;
21 | struct _bh1750_read_t {
22 | bh1750_error_t error; /* out */
23 | uint16_t value; /* out */
24 | };
25 |
26 | void bh1750_init(void);
27 | bh1750_error_t bh1750_read(int16_t *value);
28 |
29 | #ifdef __cplusplus
30 | }
31 | #endif
32 | #endif /* BH1750_H_ */
33 |
--------------------------------------------------------------------------------
/build/rsensor.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndruPol/remote-sensor/59614bfc98fa650fa8272af7875d21d7f5ca32bf/build/rsensor.bin
--------------------------------------------------------------------------------
/build/rsensor.elf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndruPol/remote-sensor/59614bfc98fa650fa8272af7875d21d7f5ca32bf/build/rsensor.elf
--------------------------------------------------------------------------------
/chconf.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | /**
18 | * @file templates/chconf.h
19 | * @brief Configuration file template.
20 | * @details A copy of this file must be placed in each project directory, it
21 | * contains the application specific kernel settings.
22 | *
23 | * @addtogroup config
24 | * @details Kernel related settings and hooks.
25 | * @{
26 | */
27 |
28 | #ifndef _CHCONF_H_
29 | #define _CHCONF_H_
30 |
31 | /*===========================================================================*/
32 | /**
33 | * @name Kernel parameters and options
34 | * @{
35 | */
36 | /*===========================================================================*/
37 |
38 | /**
39 | * @brief System tick frequency.
40 | * @details Frequency of the system timer that drives the system ticks. This
41 | * setting also defines the system tick time unit.
42 | */
43 | #if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
44 | #define CH_FREQUENCY 1000
45 | #endif
46 |
47 | /**
48 | * @brief Round robin interval.
49 | * @details This constant is the number of system ticks allowed for the
50 | * threads before preemption occurs. Setting this value to zero
51 | * disables the preemption for threads with equal priority and the
52 | * round robin becomes cooperative. Note that higher priority
53 | * threads can still preempt, the kernel is always preemptive.
54 | *
55 | * @note Disabling the round robin preemption makes the kernel more compact
56 | * and generally faster.
57 | */
58 | #if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
59 | #define CH_TIME_QUANTUM 20
60 | #endif
61 |
62 | /**
63 | * @brief Managed RAM size.
64 | * @details Size of the RAM area to be managed by the OS. If set to zero
65 | * then the whole available RAM is used. The core memory is made
66 | * available to the heap allocator and/or can be used directly through
67 | * the simplified core memory allocator.
68 | *
69 | * @note In order to let the OS manage the whole RAM the linker script must
70 | * provide the @p __heap_base__ and @p __heap_end__ symbols.
71 | * @note Requires @p CH_USE_MEMCORE.
72 | */
73 | #if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
74 | #define CH_MEMCORE_SIZE 0
75 | #endif
76 |
77 | /**
78 | * @brief Idle thread automatic spawn suppression.
79 | * @details When this option is activated the function @p chSysInit()
80 | * does not spawn the idle thread automatically. The application has
81 | * then the responsibility to do one of the following:
82 | * - Spawn a custom idle thread at priority @p IDLEPRIO.
83 | * - Change the main() thread priority to @p IDLEPRIO then enter
84 | * an endless loop. In this scenario the @p main() thread acts as
85 | * the idle thread.
86 | * .
87 | * @note Unless an idle thread is spawned the @p main() thread must not
88 | * enter a sleep state.
89 | */
90 | #if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__)
91 | #define CH_NO_IDLE_THREAD FALSE
92 | #endif
93 |
94 | /** @} */
95 |
96 | /*===========================================================================*/
97 | /**
98 | * @name Performance options
99 | * @{
100 | */
101 | /*===========================================================================*/
102 |
103 | /**
104 | * @brief OS optimization.
105 | * @details If enabled then time efficient rather than space efficient code
106 | * is used when two possible implementations exist.
107 | *
108 | * @note This is not related to the compiler optimization options.
109 | * @note The default is @p TRUE.
110 | */
111 | #if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__)
112 | #define CH_OPTIMIZE_SPEED TRUE
113 | #endif
114 |
115 | /** @} */
116 |
117 | /*===========================================================================*/
118 | /**
119 | * @name Subsystem options
120 | * @{
121 | */
122 | /*===========================================================================*/
123 |
124 | /**
125 | * @brief Threads registry APIs.
126 | * @details If enabled then the registry APIs are included in the kernel.
127 | *
128 | * @note The default is @p TRUE.
129 | */
130 | #if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__)
131 | #define CH_USE_REGISTRY TRUE
132 | #endif
133 |
134 | /**
135 | * @brief Threads synchronization APIs.
136 | * @details If enabled then the @p chThdWait() function is included in
137 | * the kernel.
138 | *
139 | * @note The default is @p TRUE.
140 | */
141 | #if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
142 | #define CH_USE_WAITEXIT TRUE
143 | #endif
144 |
145 | /**
146 | * @brief Semaphores APIs.
147 | * @details If enabled then the Semaphores APIs are included in the kernel.
148 | *
149 | * @note The default is @p TRUE.
150 | */
151 | #if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
152 | #define CH_USE_SEMAPHORES TRUE
153 | #endif
154 |
155 | /**
156 | * @brief Semaphores queuing mode.
157 | * @details If enabled then the threads are enqueued on semaphores by
158 | * priority rather than in FIFO order.
159 | *
160 | * @note The default is @p FALSE. Enable this if you have special requirements.
161 | * @note Requires @p CH_USE_SEMAPHORES.
162 | */
163 | #if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__)
164 | #define CH_USE_SEMAPHORES_PRIORITY FALSE
165 | #endif
166 |
167 | /**
168 | * @brief Atomic semaphore API.
169 | * @details If enabled then the semaphores the @p chSemSignalWait() API
170 | * is included in the kernel.
171 | *
172 | * @note The default is @p TRUE.
173 | * @note Requires @p CH_USE_SEMAPHORES.
174 | */
175 | #if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__)
176 | #define CH_USE_SEMSW TRUE
177 | #endif
178 |
179 | /**
180 | * @brief Mutexes APIs.
181 | * @details If enabled then the mutexes APIs are included in the kernel.
182 | *
183 | * @note The default is @p TRUE.
184 | */
185 | #if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
186 | #define CH_USE_MUTEXES TRUE
187 | #endif
188 |
189 | /**
190 | * @brief Conditional Variables APIs.
191 | * @details If enabled then the conditional variables APIs are included
192 | * in the kernel.
193 | *
194 | * @note The default is @p TRUE.
195 | * @note Requires @p CH_USE_MUTEXES.
196 | */
197 | #if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__)
198 | #define CH_USE_CONDVARS TRUE
199 | #endif
200 |
201 | /**
202 | * @brief Conditional Variables APIs with timeout.
203 | * @details If enabled then the conditional variables APIs with timeout
204 | * specification are included in the kernel.
205 | *
206 | * @note The default is @p TRUE.
207 | * @note Requires @p CH_USE_CONDVARS.
208 | */
209 | #if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__)
210 | #define CH_USE_CONDVARS_TIMEOUT TRUE
211 | #endif
212 |
213 | /**
214 | * @brief Events Flags APIs.
215 | * @details If enabled then the event flags APIs are included in the kernel.
216 | *
217 | * @note The default is @p TRUE.
218 | */
219 | #if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
220 | #define CH_USE_EVENTS TRUE
221 | #endif
222 |
223 | /**
224 | * @brief Events Flags APIs with timeout.
225 | * @details If enabled then the events APIs with timeout specification
226 | * are included in the kernel.
227 | *
228 | * @note The default is @p TRUE.
229 | * @note Requires @p CH_USE_EVENTS.
230 | */
231 | #if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__)
232 | #define CH_USE_EVENTS_TIMEOUT TRUE
233 | #endif
234 |
235 | /**
236 | * @brief Synchronous Messages APIs.
237 | * @details If enabled then the synchronous messages APIs are included
238 | * in the kernel.
239 | *
240 | * @note The default is @p TRUE.
241 | */
242 | #if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
243 | #define CH_USE_MESSAGES TRUE
244 | #endif
245 |
246 | /**
247 | * @brief Synchronous Messages queuing mode.
248 | * @details If enabled then messages are served by priority rather than in
249 | * FIFO order.
250 | *
251 | * @note The default is @p FALSE. Enable this if you have special requirements.
252 | * @note Requires @p CH_USE_MESSAGES.
253 | */
254 | #if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__)
255 | #define CH_USE_MESSAGES_PRIORITY FALSE
256 | #endif
257 |
258 | /**
259 | * @brief Mailboxes APIs.
260 | * @details If enabled then the asynchronous messages (mailboxes) APIs are
261 | * included in the kernel.
262 | *
263 | * @note The default is @p TRUE.
264 | * @note Requires @p CH_USE_SEMAPHORES.
265 | */
266 | #if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
267 | #define CH_USE_MAILBOXES TRUE
268 | #endif
269 |
270 | /**
271 | * @brief I/O Queues APIs.
272 | * @details If enabled then the I/O queues APIs are included in the kernel.
273 | *
274 | * @note The default is @p TRUE.
275 | */
276 | #if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
277 | #define CH_USE_QUEUES TRUE
278 | #endif
279 |
280 | /**
281 | * @brief Core Memory Manager APIs.
282 | * @details If enabled then the core memory manager APIs are included
283 | * in the kernel.
284 | *
285 | * @note The default is @p TRUE.
286 | */
287 | #if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__)
288 | #define CH_USE_MEMCORE TRUE
289 | #endif
290 |
291 | /**
292 | * @brief Heap Allocator APIs.
293 | * @details If enabled then the memory heap allocator APIs are included
294 | * in the kernel.
295 | *
296 | * @note The default is @p TRUE.
297 | * @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or
298 | * @p CH_USE_SEMAPHORES.
299 | * @note Mutexes are recommended.
300 | */
301 | #if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
302 | #define CH_USE_HEAP TRUE
303 | #endif
304 |
305 | /**
306 | * @brief C-runtime allocator.
307 | * @details If enabled the the heap allocator APIs just wrap the C-runtime
308 | * @p malloc() and @p free() functions.
309 | *
310 | * @note The default is @p FALSE.
311 | * @note Requires @p CH_USE_HEAP.
312 | * @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
313 | * appropriate documentation.
314 | */
315 | #if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
316 | #define CH_USE_MALLOC_HEAP FALSE
317 | #endif
318 |
319 | /**
320 | * @brief Memory Pools Allocator APIs.
321 | * @details If enabled then the memory pools allocator APIs are included
322 | * in the kernel.
323 | *
324 | * @note The default is @p TRUE.
325 | */
326 | #if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
327 | #define CH_USE_MEMPOOLS TRUE
328 | #endif
329 |
330 | /**
331 | * @brief Dynamic Threads APIs.
332 | * @details If enabled then the dynamic threads creation APIs are included
333 | * in the kernel.
334 | *
335 | * @note The default is @p TRUE.
336 | * @note Requires @p CH_USE_WAITEXIT.
337 | * @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS.
338 | */
339 | #if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__)
340 | #define CH_USE_DYNAMIC TRUE
341 | #endif
342 |
343 | /** @} */
344 |
345 | /*===========================================================================*/
346 | /**
347 | * @name Debug options
348 | * @{
349 | */
350 | /*===========================================================================*/
351 |
352 | /**
353 | * @brief Debug option, system state check.
354 | * @details If enabled the correct call protocol for system APIs is checked
355 | * at runtime.
356 | *
357 | * @note The default is @p FALSE.
358 | */
359 | #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
360 | #define CH_DBG_SYSTEM_STATE_CHECK FALSE
361 | #endif
362 |
363 | /**
364 | * @brief Debug option, parameters checks.
365 | * @details If enabled then the checks on the API functions input
366 | * parameters are activated.
367 | *
368 | * @note The default is @p FALSE.
369 | */
370 | #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
371 | #define CH_DBG_ENABLE_CHECKS FALSE
372 | #endif
373 |
374 | /**
375 | * @brief Debug option, consistency checks.
376 | * @details If enabled then all the assertions in the kernel code are
377 | * activated. This includes consistency checks inside the kernel,
378 | * runtime anomalies and port-defined checks.
379 | *
380 | * @note The default is @p FALSE.
381 | */
382 | #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
383 | #define CH_DBG_ENABLE_ASSERTS FALSE
384 | #endif
385 |
386 | /**
387 | * @brief Debug option, trace buffer.
388 | * @details If enabled then the context switch circular trace buffer is
389 | * activated.
390 | *
391 | * @note The default is @p FALSE.
392 | */
393 | #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
394 | #define CH_DBG_ENABLE_TRACE FALSE
395 | #endif
396 |
397 | /**
398 | * @brief Debug option, stack checks.
399 | * @details If enabled then a runtime stack check is performed.
400 | *
401 | * @note The default is @p FALSE.
402 | * @note The stack check is performed in a architecture/port dependent way.
403 | * It may not be implemented or some ports.
404 | * @note The default failure mode is to halt the system with the global
405 | * @p panic_msg variable set to @p NULL.
406 | */
407 | #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
408 | #define CH_DBG_ENABLE_STACK_CHECK FALSE
409 | #endif
410 |
411 | /**
412 | * @brief Debug option, stacks initialization.
413 | * @details If enabled then the threads working area is filled with a byte
414 | * value when a thread is created. This can be useful for the
415 | * runtime measurement of the used stack.
416 | *
417 | * @note The default is @p FALSE.
418 | */
419 | #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
420 | #define CH_DBG_FILL_THREADS FALSE
421 | #endif
422 |
423 | /**
424 | * @brief Debug option, threads profiling.
425 | * @details If enabled then a field is added to the @p Thread structure that
426 | * counts the system ticks occurred while executing the thread.
427 | *
428 | * @note The default is @p TRUE.
429 | * @note This debug option is defaulted to TRUE because it is required by
430 | * some test cases into the test suite.
431 | */
432 | #if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
433 | #define CH_DBG_THREADS_PROFILING FALSE
434 | #endif
435 |
436 | /** @} */
437 |
438 | /*===========================================================================*/
439 | /**
440 | * @name Kernel hooks
441 | * @{
442 | */
443 | /*===========================================================================*/
444 |
445 | /**
446 | * @brief Threads descriptor structure extension.
447 | * @details User fields added to the end of the @p Thread structure.
448 | */
449 | #if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
450 | #define THREAD_EXT_FIELDS \
451 | /* Add threads custom fields here.*/
452 | #endif
453 |
454 | /**
455 | * @brief Threads initialization hook.
456 | * @details User initialization code added to the @p chThdInit() API.
457 | *
458 | * @note It is invoked from within @p chThdInit() and implicitly from all
459 | * the threads creation APIs.
460 | */
461 | #if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
462 | #define THREAD_EXT_INIT_HOOK(tp) { \
463 | /* Add threads initialization code here.*/ \
464 | }
465 | #endif
466 |
467 | /**
468 | * @brief Threads finalization hook.
469 | * @details User finalization code added to the @p chThdExit() API.
470 | *
471 | * @note It is inserted into lock zone.
472 | * @note It is also invoked when the threads simply return in order to
473 | * terminate.
474 | */
475 | #if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__)
476 | #define THREAD_EXT_EXIT_HOOK(tp) { \
477 | /* Add threads finalization code here.*/ \
478 | }
479 | #endif
480 |
481 | /**
482 | * @brief Context switch hook.
483 | * @details This hook is invoked just before switching between threads.
484 | */
485 | #if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__)
486 | #define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
487 | /* System halt code here.*/ \
488 | }
489 | #endif
490 |
491 | /**
492 | * @brief Idle Loop hook.
493 | * @details This hook is continuously invoked by the idle thread loop.
494 | */
495 | #if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
496 | #define IDLE_LOOP_HOOK() { \
497 | /* Idle loop code here.*/ \
498 | }
499 | #endif
500 |
501 | /**
502 | * @brief System tick event hook.
503 | * @details This hook is invoked in the system tick handler immediately
504 | * after processing the virtual timers queue.
505 | */
506 | #if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__)
507 | #define SYSTEM_TICK_EVENT_HOOK() { \
508 | /* System tick event code here.*/ \
509 | }
510 | #endif
511 |
512 | /**
513 | * @brief System halt hook.
514 | * @details This hook is invoked in case to a system halting error before
515 | * the system is halted.
516 | */
517 | #if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
518 | #define SYSTEM_HALT_HOOK() { \
519 | /* System halt code here.*/ \
520 | }
521 | #endif
522 |
523 | /** @} */
524 |
525 | /*===========================================================================*/
526 | /* Port-specific settings (override port settings defaulted in chcore.h). */
527 | /*===========================================================================*/
528 | #define PORT_INT_REQUIRED_STACK 32
529 | #define CHPRINTF_USE_FLOAT 1
530 |
531 | #endif /* _CHCONF_H_ */
532 |
533 | /** @} */
534 |
--------------------------------------------------------------------------------
/devices.txt:
--------------------------------------------------------------------------------
1 | Unit VDD_min VDD_typ VDD_max,V I_min I_max, mA
2 | STM32F103C8T6 2 3.3 3.6 0.035 50/28(48Mhz)
3 | NRF24L01 1.9 3 3.6 0.001 11.8
4 | BH1750 2.4 3 3.6 ? 0.19
5 | DHT22/AM2303 3.3 5 5.5 1 2.1
6 | DHT21/HM2301 3.3 5 5.5 1 2.1
7 | DS1820B 3 5.5 1 >=4
8 | BMP085 1.8 2.5 3.6 0.0001 1
9 |
--------------------------------------------------------------------------------
/ds1820b.c:
--------------------------------------------------------------------------------
1 | #include "ch.h"
2 | #include "hal.h"
3 | #include "oneWire.h"
4 | #include "ds1820b.h"
5 | #include "math.h"
6 |
7 |
8 | void ds1820BInit (OneWireDriver* drv, const OneWireRomAddress *address,
9 | const uint8_t precBits)
10 | {
11 | uint8_t initVal[] = {0x4e, 0x00, 0xff, 0x1f};
12 |
13 | if (precBits <= 9) {
14 | initVal[3] |= 0;
15 | } else if (precBits == 10) {
16 | initVal[3] |= 0b00100000;
17 | } else if (precBits == 11) {
18 | initVal[3] |= 0b01000000;
19 | } else { // prec bit >= 12
20 | initVal[3] |= 0b01100000;
21 | }
22 |
23 | oneWireReset (drv);
24 | if (address == NULL) {
25 | oneWireSendByte (drv, 0xcc);
26 | } else {
27 | oneWireSendByte (drv, 0x55);
28 | oneWireSend (drv, address->addr, 8);
29 | }
30 |
31 | oneWireSend (drv, initVal, sizeof(initVal));
32 | }
33 |
34 | float ds1820BGetTemp (OneWireDriver* drv, const OneWireRomAddress *address)
35 | {
36 | uint8_t ram[9];
37 |
38 | oneWireAcquireBus (drv);
39 | oneWireReset (drv);
40 | if (address == NULL) {
41 | oneWireSendByte (drv, 0xcc);
42 | } else {
43 | oneWireSendByte (drv, 0x55);
44 | oneWireSend (drv, address->addr, 8);
45 | }
46 |
47 | oneWireSendByte (drv, 0x44);
48 | chThdSleepMilliseconds(100); // minimum conv time when 9 bit
49 | while (oneWireReceiveBit(drv) == FALSE) {
50 | chThdSleepMilliseconds(10); // waint until conversion is done
51 | }
52 |
53 | oneWireReset (drv);
54 | if (address == NULL) {
55 | oneWireSendByte (drv, 0xcc);
56 | } else {
57 | oneWireSendByte (drv, 0x55);
58 | oneWireSend (drv, address->addr, 8);
59 | }
60 |
61 | oneWireSendByte (drv, 0xbe);
62 | oneWireReceive (drv, ram, sizeof(ram));
63 | // uint8_t crc = oneWireCrc8(ram, 8);
64 | uint8_t crc = owCrc8(ram, 8);
65 | if (crc != ram[8]) {
66 | oneWireRealeaseBus ();
67 | return (nanf(""));
68 | }
69 |
70 |
71 | const int16_t rawTmp = (ram[1] << 8) | (ram [0]);
72 | oneWireRealeaseBus ();
73 | return (rawTmp * 0.0625f);
74 | }
75 |
76 |
77 | void ds1820BAskTemp (OneWireDriver* drv, const OneWireRomAddress *address)
78 | {
79 | oneWireAcquireBus (drv);
80 | oneWireReset (drv);
81 | if (address == NULL) {
82 | oneWireSendByte (drv, 0xcc);
83 | } else {
84 | oneWireSendByte (drv, 0x55);
85 | oneWireSend (drv, address->addr, 8);
86 | }
87 | oneWireSendByte (drv, 0x44);
88 | oneWireRealeaseBus ();
89 | }
90 |
91 |
92 | float ds1820BGGetTempFromRam (OneWireDriver* drv, const OneWireRomAddress *address)
93 | {
94 | uint8_t ram[9];
95 |
96 | oneWireAcquireBus (drv);
97 |
98 | oneWireReset (drv);
99 | if (address == NULL) {
100 | oneWireSendByte (drv, 0xcc);
101 | } else {
102 | oneWireSendByte (drv, 0x55);
103 | oneWireSend (drv, address->addr, 8);
104 | }
105 |
106 | oneWireSendByte (drv, 0xbe);
107 | oneWireReceive (drv, ram, sizeof(ram));
108 | // uint8_t crc = oneWireCrc8(ram, 8);
109 | uint8_t crc = owCrc8(ram, 8);
110 | if (crc != ram[8]) {
111 | oneWireRealeaseBus ();
112 | return (nanf(""));
113 | }
114 |
115 | oneWireRealeaseBus ();
116 | const int16_t rawTmp = (ram[1] << 8) | (ram [0]);
117 | return (rawTmp * 0.0625f);
118 | }
119 |
120 |
--------------------------------------------------------------------------------
/ds1820b.h:
--------------------------------------------------------------------------------
1 | #ifndef __DS_1820_B_H__
2 | #define __DS_1820_B_H__
3 |
4 | #include "oneWire.h"
5 |
6 |
7 | /*
8 | initialise and configure sensors
9 | */
10 | void ds1820BInit (OneWireDriver* drv, const OneWireRomAddress *address,
11 | const uint8_t precBits);
12 |
13 |
14 | /*
15 | ask conversion, wait for the conversion to be done, then return value,
16 | could be the simplest way to acquire data when there is only one sensor
17 | */
18 | float ds1820BGetTemp (OneWireDriver* drv, const OneWireRomAddress *address);
19 |
20 |
21 | /*
22 | separate ask conversion command and get values.
23 | this is the fastest way to acquire data when there is a lot of sensors :
24 | 1/ ask conversion for all sensors
25 | 2/ wait time accordingly to precision (see datasheet)
26 | 3/ get the temperature for all sensors
27 | */
28 | void ds1820BAskTemp (OneWireDriver* drv, const OneWireRomAddress *address);
29 | float ds1820BGGetTempFromRam (OneWireDriver* drv, const OneWireRomAddress *address);
30 |
31 | #endif //__DS_1820_B_H__
32 |
--------------------------------------------------------------------------------
/halconf.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | /**
18 | * @file templates/halconf.h
19 | * @brief HAL configuration header.
20 | * @details HAL configuration file, this file allows to enable or disable the
21 | * various device drivers from your application. You may also use
22 | * this file in order to override the device drivers default settings.
23 | *
24 | * @addtogroup HAL_CONF
25 | * @{
26 | */
27 |
28 | #ifndef _HALCONF_H_
29 | #define _HALCONF_H_
30 |
31 | #include "mcuconf.h"
32 |
33 | /**
34 | * @brief Enables the TM subsystem.
35 | */
36 | #if !defined(HAL_USE_TM) || defined(__DOXYGEN__)
37 | #define HAL_USE_TM FALSE
38 | #endif
39 |
40 | /**
41 | * @brief Enables the PAL subsystem.
42 | */
43 | #if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
44 | #define HAL_USE_PAL TRUE
45 | #endif
46 |
47 | /**
48 | * @brief Enables the ADC subsystem.
49 | */
50 | #if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
51 | #define HAL_USE_ADC FALSE
52 | #endif
53 |
54 | /**
55 | * @brief Enables the CAN subsystem.
56 | */
57 | #if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
58 | #define HAL_USE_CAN FALSE
59 | #endif
60 |
61 | /**
62 | * @brief Enables the EXT subsystem.
63 | */
64 | #if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
65 | #define HAL_USE_EXT TRUE
66 | #endif
67 |
68 | /**
69 | * @brief Enables the GPT subsystem.
70 | */
71 | #if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
72 | #define HAL_USE_GPT FALSE
73 | #endif
74 |
75 | /**
76 | * @brief Enables the I2C subsystem.
77 | */
78 | #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
79 | #define HAL_USE_I2C TRUE
80 | #endif
81 |
82 | /**
83 | * @brief Enables the ICU subsystem.
84 | */
85 | #if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
86 | #define HAL_USE_ICU TRUE
87 | #endif
88 |
89 | /**
90 | * @brief Enables the MAC subsystem.
91 | */
92 | #if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
93 | #define HAL_USE_MAC FALSE
94 | #endif
95 |
96 | /**
97 | * @brief Enables the MMC_SPI subsystem.
98 | */
99 | #if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
100 | #define HAL_USE_MMC_SPI FALSE
101 | #endif
102 |
103 | /**
104 | * @brief Enables the PWM subsystem.
105 | */
106 | #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
107 | #define HAL_USE_PWM FALSE
108 | #endif
109 |
110 | /**
111 | * @brief Enables the RTC subsystem.
112 | */
113 | #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
114 | #define HAL_USE_RTC TRUE
115 | #endif
116 |
117 | /**
118 | * @brief Enables the SDC subsystem.
119 | */
120 | #if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
121 | #define HAL_USE_SDC FALSE
122 | #endif
123 |
124 | /**
125 | * @brief Enables the SERIAL subsystem.
126 | */
127 | #if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
128 | #define HAL_USE_SERIAL TRUE
129 | #endif
130 |
131 | /**
132 | * @brief Enables the SERIAL over USB subsystem.
133 | */
134 | #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
135 | #define HAL_USE_SERIAL_USB FALSE
136 | #endif
137 |
138 | /**
139 | * @brief Enables the SPI subsystem.
140 | */
141 | #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
142 | #define HAL_USE_SPI TRUE
143 | #endif
144 |
145 | /**
146 | * @brief Enables the UART subsystem.
147 | */
148 | #if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
149 | #define HAL_USE_UART TRUE
150 | #endif
151 |
152 | /**
153 | * @brief Enables the USB subsystem.
154 | */
155 | #if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
156 | #define HAL_USE_USB FALSE
157 | #endif
158 |
159 | /*===========================================================================*/
160 | /* ADC driver related settings. */
161 | /*===========================================================================*/
162 |
163 | /**
164 | * @brief Enables synchronous APIs.
165 | * @note Disabling this option saves both code and data space.
166 | */
167 | #if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
168 | #define ADC_USE_WAIT TRUE
169 | #endif
170 |
171 | /**
172 | * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
173 | * @note Disabling this option saves both code and data space.
174 | */
175 | #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
176 | #define ADC_USE_MUTUAL_EXCLUSION TRUE
177 | #endif
178 |
179 | /*===========================================================================*/
180 | /* CAN driver related settings. */
181 | /*===========================================================================*/
182 |
183 | /**
184 | * @brief Sleep mode related APIs inclusion switch.
185 | */
186 | #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
187 | #define CAN_USE_SLEEP_MODE TRUE
188 | #endif
189 |
190 | /*===========================================================================*/
191 | /* I2C driver related settings. */
192 | /*===========================================================================*/
193 |
194 | /**
195 | * @brief Enables the mutual exclusion APIs on the I2C bus.
196 | */
197 | #if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
198 | #define I2C_USE_MUTUAL_EXCLUSION TRUE
199 | #endif
200 |
201 | /*===========================================================================*/
202 | /* MAC driver related settings. */
203 | /*===========================================================================*/
204 |
205 | /**
206 | * @brief Enables an event sources for incoming packets.
207 | */
208 | #if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
209 | #define MAC_USE_ZERO_COPY FALSE
210 | #endif
211 |
212 | /**
213 | * @brief Enables an event sources for incoming packets.
214 | */
215 | #if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
216 | #define MAC_USE_EVENTS TRUE
217 | #endif
218 |
219 | /*===========================================================================*/
220 | /* MMC_SPI driver related settings. */
221 | /*===========================================================================*/
222 |
223 | /**
224 | * @brief Delays insertions.
225 | * @details If enabled this options inserts delays into the MMC waiting
226 | * routines releasing some extra CPU time for the threads with
227 | * lower priority, this may slow down the driver a bit however.
228 | * This option is recommended also if the SPI driver does not
229 | * use a DMA channel and heavily loads the CPU.
230 | */
231 | #if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
232 | #define MMC_NICE_WAITING TRUE
233 | #endif
234 |
235 | /*===========================================================================*/
236 | /* SDC driver related settings. */
237 | /*===========================================================================*/
238 |
239 | /**
240 | * @brief Number of initialization attempts before rejecting the card.
241 | * @note Attempts are performed at 10mS intervals.
242 | */
243 | #if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
244 | #define SDC_INIT_RETRY 100
245 | #endif
246 |
247 | /**
248 | * @brief Include support for MMC cards.
249 | * @note MMC support is not yet implemented so this option must be kept
250 | * at @p FALSE.
251 | */
252 | #if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
253 | #define SDC_MMC_SUPPORT FALSE
254 | #endif
255 |
256 | /**
257 | * @brief Delays insertions.
258 | * @details If enabled this options inserts delays into the MMC waiting
259 | * routines releasing some extra CPU time for the threads with
260 | * lower priority, this may slow down the driver a bit however.
261 | */
262 | #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
263 | #define SDC_NICE_WAITING TRUE
264 | #endif
265 |
266 | /*===========================================================================*/
267 | /* SERIAL driver related settings. */
268 | /*===========================================================================*/
269 |
270 | /**
271 | * @brief Default bit rate.
272 | * @details Configuration parameter, this is the baud rate selected for the
273 | * default configuration.
274 | */
275 | #if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
276 | #define SERIAL_DEFAULT_BITRATE 38400
277 | #endif
278 |
279 | /**
280 | * @brief Serial buffers size.
281 | * @details Configuration parameter, you can change the depth of the queue
282 | * buffers depending on the requirements of your application.
283 | * @note The default is 64 bytes for both the transmission and receive
284 | * buffers.
285 | */
286 | #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
287 | #define SERIAL_BUFFERS_SIZE 16
288 | #endif
289 |
290 | /*===========================================================================*/
291 | /* SPI driver related settings. */
292 | /*===========================================================================*/
293 |
294 | /**
295 | * @brief Enables synchronous APIs.
296 | * @note Disabling this option saves both code and data space.
297 | */
298 | #if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
299 | #define SPI_USE_WAIT TRUE
300 | #endif
301 |
302 | /**
303 | * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
304 | * @note Disabling this option saves both code and data space.
305 | */
306 | #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
307 | #define SPI_USE_MUTUAL_EXCLUSION TRUE
308 | #endif
309 |
310 | #endif /* _HALCONF_H_ */
311 |
312 | /** @} */
313 |
--------------------------------------------------------------------------------
/main.h:
--------------------------------------------------------------------------------
1 | /*
2 | * main.h
3 | *
4 | * Created on: 16.08.2013
5 | * Author: pae
6 | */
7 |
8 | #ifndef MAIN_H_
9 | #define MAIN_H_
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #define FIRMWARE "0.4" // версия прошивки
15 | #define SLEEPTIME 720 // время режима пониженного энергопотребления, сек
16 | #define SENSORID 0 // this sensor ID
17 |
18 | typedef enum {
19 | SENSOR_INFO = 0, // not implemented
20 | SENSOR_DATA,
21 | SENSOR_ERROR
22 | } msgtype_t;
23 |
24 | typedef enum {
25 | DS1820 = 0,
26 | BH1750,
27 | DHT,
28 | BMP085,
29 | ADC
30 | } sensortype_t;
31 |
32 | typedef enum {
33 | TEMPERATURE = 0,
34 | HUMIDITY,
35 | PRESSURE,
36 | LIGHT,
37 | VOLTAGE
38 | } valuetype_t;
39 |
40 | // описание формата посылки
41 | #define MSGLEN 16
42 | typedef struct MESSAGE MESSAGE_T;
43 | struct MESSAGE{
44 | msgtype_t msgType; // тип сообщения: 0 - инфо, 1 - значение датчика, 2 - ошибка
45 | uint8_t sensorID; // board ID
46 | sensortype_t sensorType; // тип датчика: 0 - DS1820, 1 - BH1750, 2 - DHT21/22 сенсор, 3 - BMP085, 4 - ADC
47 | valuetype_t valueType; // тип значения: 0 - temperature, 1 - humidity, 2 - pressure, 3 - light, 4 - voltage
48 | uint8_t owkey[8]; // идентификатор датчика DS1820, номер датчика DHT в owkey[0]
49 | union { // значение датчика
50 | float fValue;
51 | int32_t iValue;
52 | uint8_t cValue[4];
53 | } data;
54 | };
55 |
56 | #ifdef __cplusplus
57 | }
58 | #endif
59 |
60 | #endif /* MAIN_H_ */
61 |
--------------------------------------------------------------------------------
/mcuconf.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #define STM32F103_MCUCONF
18 |
19 | /*
20 | * STM32F103 drivers configuration.
21 | * The following settings override the default settings present in
22 | * the various device driver implementation headers.
23 | * Note that the settings for each driver only have effect if the whole
24 | * driver is enabled in halconf.h.
25 | *
26 | * IRQ priorities:
27 | * 15...0 Lowest...Highest.
28 | *
29 | * DMA priorities:
30 | * 0...3 Lowest...Highest.
31 | */
32 |
33 | /*
34 | * HAL driver system settings.
35 | */
36 | #define STM32_NO_INIT FALSE
37 | #define STM32_HSI_ENABLED FALSE
38 | #define STM32_LSI_ENABLED TRUE
39 | #define STM32_HSE_ENABLED TRUE
40 | #define STM32_LSE_ENABLED TRUE
41 | #define STM32_SW STM32_SW_PLL
42 | #define STM32_PLLSRC STM32_PLLSRC_HSE
43 | #define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
44 | #define STM32_PLLMUL_VALUE 3
45 | #define STM32_HPRE STM32_HPRE_DIV1
46 | #define STM32_PPRE1 STM32_PPRE1_DIV2
47 | #define STM32_PPRE2 STM32_PPRE2_DIV2
48 | #define STM32_ADCPRE STM32_ADCPRE_DIV4
49 | #define STM32_USB_CLOCK_REQUIRED FALSE
50 | #define STM32_USBPRE STM32_USBPRE_DIV1P5
51 | #define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
52 | #define STM32_RTCSEL STM32_RTCSEL_LSE
53 | #define STM32_PVD_ENABLE FALSE
54 | #define STM32_PLS STM32_PLS_LEV0
55 |
56 | /*
57 | * ADC driver system settings.
58 | */
59 | #define STM32_ADC_USE_ADC1 FALSE
60 | #define STM32_ADC_ADC1_DMA_PRIORITY 2
61 | #define STM32_ADC_ADC1_IRQ_PRIORITY 6
62 |
63 | /*
64 | * CAN driver system settings.
65 | */
66 | #define STM32_CAN_USE_CAN1 FALSE
67 | #define STM32_CAN_CAN1_IRQ_PRIORITY 11
68 |
69 | /*
70 | * EXT driver system settings.
71 | */
72 | #define STM32_EXT_EXTI0_IRQ_PRIORITY 6
73 | #define STM32_EXT_EXTI1_IRQ_PRIORITY 6
74 | #define STM32_EXT_EXTI2_IRQ_PRIORITY 6
75 | #define STM32_EXT_EXTI3_IRQ_PRIORITY 6
76 | #define STM32_EXT_EXTI4_IRQ_PRIORITY 6
77 | #define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
78 | #define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
79 | #define STM32_EXT_EXTI16_IRQ_PRIORITY 6
80 | #define STM32_EXT_EXTI17_IRQ_PRIORITY 6
81 | #define STM32_EXT_EXTI18_IRQ_PRIORITY 6
82 | #define STM32_EXT_EXTI19_IRQ_PRIORITY 6
83 |
84 | /*
85 | * GPT driver system settings.
86 | */
87 | #define STM32_GPT_USE_TIM1 FALSE
88 | #define STM32_GPT_USE_TIM2 FALSE
89 | #define STM32_GPT_USE_TIM3 FALSE
90 | #define STM32_GPT_USE_TIM4 FALSE
91 | #define STM32_GPT_USE_TIM5 FALSE
92 | #define STM32_GPT_USE_TIM8 FALSE
93 | #define STM32_GPT_TIM1_IRQ_PRIORITY 7
94 | #define STM32_GPT_TIM2_IRQ_PRIORITY 7
95 | #define STM32_GPT_TIM3_IRQ_PRIORITY 7
96 | #define STM32_GPT_TIM4_IRQ_PRIORITY 7
97 | #define STM32_GPT_TIM5_IRQ_PRIORITY 7
98 | #define STM32_GPT_TIM8_IRQ_PRIORITY 7
99 |
100 | /*
101 | * I2C driver system settings.
102 | */
103 | #define STM32_I2C_USE_I2C1 TRUE
104 | #define STM32_I2C_USE_I2C2 FALSE
105 | #define STM32_I2C_I2C1_IRQ_PRIORITY 5
106 | #define STM32_I2C_I2C2_IRQ_PRIORITY 5
107 | #define STM32_I2C_I2C1_DMA_PRIORITY 3
108 | #define STM32_I2C_I2C2_DMA_PRIORITY 3
109 | #define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
110 | #define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
111 |
112 | /*
113 | * ICU driver system settings.
114 | */
115 | #define STM32_ICU_USE_TIM1 FALSE
116 | #define STM32_ICU_USE_TIM2 TRUE
117 | #define STM32_ICU_USE_TIM3 FALSE
118 | #define STM32_ICU_USE_TIM4 FALSE
119 | #define STM32_ICU_USE_TIM5 FALSE
120 | #define STM32_ICU_USE_TIM8 FALSE
121 | #define STM32_ICU_TIM1_IRQ_PRIORITY 7
122 | #define STM32_ICU_TIM2_IRQ_PRIORITY 7
123 | #define STM32_ICU_TIM3_IRQ_PRIORITY 7
124 | #define STM32_ICU_TIM4_IRQ_PRIORITY 7
125 | #define STM32_ICU_TIM5_IRQ_PRIORITY 7
126 | #define STM32_ICU_TIM8_IRQ_PRIORITY 7
127 |
128 | /*
129 | * PWM driver system settings.
130 | */
131 | #define STM32_PWM_USE_ADVANCED FALSE
132 | #define STM32_PWM_USE_TIM1 FALSE
133 | #define STM32_PWM_USE_TIM2 FALSE
134 | #define STM32_PWM_USE_TIM3 FALSE
135 | #define STM32_PWM_USE_TIM4 FALSE
136 | #define STM32_PWM_USE_TIM5 FALSE
137 | #define STM32_PWM_USE_TIM8 FALSE
138 | #define STM32_PWM_TIM1_IRQ_PRIORITY 7
139 | #define STM32_PWM_TIM2_IRQ_PRIORITY 7
140 | #define STM32_PWM_TIM3_IRQ_PRIORITY 7
141 | #define STM32_PWM_TIM4_IRQ_PRIORITY 7
142 | #define STM32_PWM_TIM5_IRQ_PRIORITY 7
143 | #define STM32_PWM_TIM8_IRQ_PRIORITY 7
144 |
145 | /*
146 | * RTC driver system settings.
147 | */
148 | #define STM32_RTC_IRQ_PRIORITY 15
149 |
150 | /*
151 | * SERIAL driver system settings.
152 | */
153 | #define STM32_SERIAL_USE_USART1 FALSE
154 | #define STM32_SERIAL_USE_USART2 TRUE
155 | #define STM32_SERIAL_USE_USART3 FALSE
156 | #define STM32_SERIAL_USE_UART4 FALSE
157 | #define STM32_SERIAL_USE_UART5 FALSE
158 | #define STM32_SERIAL_USART1_PRIORITY 12
159 | #define STM32_SERIAL_USART2_PRIORITY 12
160 | #define STM32_SERIAL_USART3_PRIORITY 12
161 | #define STM32_SERIAL_UART4_PRIORITY 12
162 | #define STM32_SERIAL_UART5_PRIORITY 12
163 |
164 | /*
165 | * SPI driver system settings.
166 | */
167 | #define STM32_SPI_USE_SPI1 TRUE
168 | #define STM32_SPI_USE_SPI2 FALSE
169 | #define STM32_SPI_USE_SPI3 FALSE
170 | #define STM32_SPI_SPI1_DMA_PRIORITY 1
171 | #define STM32_SPI_SPI2_DMA_PRIORITY 1
172 | #define STM32_SPI_SPI3_DMA_PRIORITY 1
173 | #define STM32_SPI_SPI1_IRQ_PRIORITY 10
174 | #define STM32_SPI_SPI2_IRQ_PRIORITY 10
175 | #define STM32_SPI_SPI3_IRQ_PRIORITY 10
176 | #define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
177 |
178 | /*
179 | * UART driver system settings.
180 | */
181 | #define STM32_UART_USE_USART1 TRUE
182 | #define STM32_UART_USE_USART2 FALSE
183 | #define STM32_UART_USE_USART3 FALSE
184 | #define STM32_UART_USART1_IRQ_PRIORITY 12
185 | #define STM32_UART_USART2_IRQ_PRIORITY 12
186 | #define STM32_UART_USART3_IRQ_PRIORITY 12
187 | #define STM32_UART_USART1_DMA_PRIORITY 0
188 | #define STM32_UART_USART2_DMA_PRIORITY 0
189 | #define STM32_UART_USART3_DMA_PRIORITY 0
190 | #define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
191 |
192 | /*
193 | * USB driver system settings.
194 | */
195 | #define STM32_USB_USE_USB1 FALSE
196 | #define STM32_USB_LOW_POWER_ON_SUSPEND TRUE
197 | #define STM32_USB_USB1_HP_IRQ_PRIORITY 13
198 | #define STM32_USB_USB1_LP_IRQ_PRIORITY 14
199 |
200 |
--------------------------------------------------------------------------------
/nrf24l01.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
3 | 2011,2012 Giovanni Di Sirio.
4 |
5 | This file is part of ChibiOS/RT.
6 |
7 | ChibiOS/RT is free software; you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation; either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | ChibiOS/RT is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 |
20 | ---
21 |
22 | A special exception to the GPL can be applied should you wish to distribute
23 | a combined work that includes ChibiOS/RT, without being obliged to provide
24 | the source code for any proprietary components. See the file exception.txt
25 | for full details of how and when the exception can be applied.
26 | */
27 |
28 | #define CHANNEL 0
29 |
30 | /*
31 | * The number of bytes the NRF24L01 RX FIFO is going to hold
32 | * This can be 32 bytes MAX
33 | */
34 | #define NRF_FIFO_BYTES 16
35 |
36 | /*
37 | * Define IRQ an CE PORT/PAD
38 | * Make sure to setup the IRQ pad with the EXT driver as well
39 | */
40 | #define NRF_PORT_CE_IRQ GPIOB
41 | #define NRF_PORT_IRQ 9
42 | #define NRF_PORT_CE 8
43 |
44 | /**
45 | * @name NRF status flags
46 | * @{
47 | */
48 | #define NRF_TX_NO_ERROR 0 /**< @brief No pending conditions. */
49 | #define NRF_TX_OVERRUN_ERROR 2 /**< @brief Overflow happened. */
50 | #define NRF_TRANSMIT_ERROR 4 /**< @brief Transmission error. */
51 | /** @} */
52 |
53 | /**
54 | * @brief Driver state machine possible states.
55 | */
56 | typedef enum {
57 | NRF_UNINIT = 0, /**< Not initialized. */
58 | NRF_STOP = 1, /**< Stopped. */
59 | NRF_READY = 2 /**< Ready. */
60 | } nrfstate_t;
61 |
62 | /**
63 | * @brief Transmitter state machine states.
64 | */
65 | typedef enum {
66 | NRF_TX_IDLE = 0, /**< Not transmitting. */
67 | NRF_TX_ACTIVE = 1, /**< Transmitting. */
68 | NRF_TX_COMPLETE = 2 /**< Buffer complete. */
69 | } nrftxstate_t;
70 |
71 | /**
72 | * @brief Receiver state machine states.
73 | */
74 | typedef enum {
75 | NRF_RX_IDLE = 0, /**< Not receiving. */
76 | NRF_RX_ACTIVE = 1, /**< Receiving. */
77 | NRF_RX_COMPLETE = 2 /**< Buffer complete. */
78 | } nrfrxstate_t;
79 |
80 | /**
81 | * @brief NRF driver condition flags type.
82 | */
83 | typedef uint8_t nrfflags_t;
84 |
85 | typedef struct _NRFD NRFD;
86 | struct _NRFD {
87 | /**
88 | * @brief Driver state.
89 | */
90 | volatile nrfstate_t state;
91 | /**
92 | * @brief Transmitter state.
93 | */
94 | volatile nrftxstate_t txstate;
95 | /**
96 | * @brief Receiver state.
97 | */
98 | volatile nrfrxstate_t rxstate;
99 | /**
100 | * @brief NRF driver condition flags type.
101 | */
102 | volatile nrfflags_t flags;
103 | /*
104 | * Binary semaphore, to lock access to the send and receive queue of the NRF24L01
105 | */
106 | BinarySemaphore NRFSemIRQ;
107 | BinarySemaphore NRFSemRX;
108 | BinarySemaphore NRFSemTX;
109 | };
110 |
111 | extern NRFD nrf;
112 |
113 | /*
114 | * Initialize the NRF24L01 Wifi chip.
115 | */
116 | void NRFInit(void);
117 |
118 | /*
119 | * Set channel
120 | * Frequency is F0= 2400 + RF_CH [MHz]
121 | */
122 | void NRFSetChannel(uint8_t chan);
123 |
124 | /*
125 | * Handle the IRQ signal, unlock the Semaphores or set flags.
126 | */
127 | void NRFHandleIrq(void);
128 |
129 | /*
130 | * NRF24L01 test
131 | */
132 | void NRFtest(void);
133 |
134 | /*
135 | * Function to send data
136 | * This functions blocks until data is available
137 | * The send output buffer needs to be NRF_FIFO_BYTES(32) bytes wide
138 | */
139 | bool_t NRFSendData(uint8_t *inBuf);
140 |
141 | /*
142 | * Routine to unlock IRQ handling.
143 | */
144 | void NRFReportIRQ(void);
145 |
146 | /*
147 | * Test if there is a carrier signal active on the channel
148 | * When present return true
149 | */
150 | uint8_t NRFCarrier(void);
151 |
152 | /*
153 | * Function to receive data from FIFO
154 | * This functions blocks until data is available
155 | * The output buffer needs to be NRF_FIFO_BYTES(32) bytes wide
156 | */
157 | void NRFReceiveData(uint8_t *pipeNr, uint8_t *outBuf);
158 |
159 | /*
160 | * Set the address to the receiver pipe
161 | * Normaly pipe is used to receive the ack packets by shockburst
162 | * Use pipe 1 as the first data receive pipe
163 | * @Arguments
164 | * pipe Pipe number to set the address to
165 | * addr_size The size of the address in bytes
166 | * addr Byte array holding the addr, LSB first
167 | */
168 | void NRFSetRecvAddr(uint8_t pipe, uint8_t addr[], uint8_t addrSize);
169 |
170 |
171 | /*
172 | * Set the address to the receiver pipe
173 | * The receive address of pipe 0 is set as well, to enable auto ACK handling
174 | * @Arguments
175 | * pipe Pipe number to set the address to
176 | * addr_size The size of the address in bytes
177 | * addr Byte array holding the address, LSB first
178 | */
179 | void NRFSetSendAddr(uint8_t addr[], uint8_t addrSize);
180 |
181 | void NRFPWRDown(void);
182 | void NRFPWRUp(void);
183 | void NRFGetAddrs(uint8_t *txaddr, uint8_t *rxaddr);
184 | uint8_t NRFChannelScan(uint8_t chan);
185 |
186 | /*
187 | * NRF thread
188 | */
189 | #define NRF_WA_SIZE 256
190 | extern WORKING_AREA(NRFThreadWA, NRF_WA_SIZE);
191 | extern msg_t NRFThread(void *arg);
192 |
--------------------------------------------------------------------------------
/nrf_spi.c:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
3 | 2011,2012 Giovanni Di Sirio.
4 |
5 | This file is part of ChibiOS/RT.
6 |
7 | ChibiOS/RT is free software; you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation; either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | ChibiOS/RT is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 |
20 | ---
21 |
22 | A special exception to the GPL can be applied should you wish to distribute
23 | a combined work that includes ChibiOS/RT, without being obliged to provide
24 | the source code for any proprietary components. See the file exception.txt
25 | for full details of how and when the exception can be applied.
26 | */
27 |
28 | #include "ch.h"
29 | #include "hal.h"
30 |
31 | #include "nrf_spi.h"
32 |
33 | #include
34 |
35 | /*
36 | * SPI speed definitions.
37 | */
38 | #define SPI_DIV2 0
39 | #define SPI_DIV4 (SPI_CR1_BR_0)
40 | #define SPI_DIV8 (SPI_CR1_BR_1)
41 | #define SPI_DIV16 (SPI_CR1_BR_1 | SPI_CR1_BR_0)
42 | #define SPI_DIV32 (SPI_CR1_BR_2)
43 | #define SPI_DIV64 (SPI_CR1_BR_2 | SPI_CR1_BR_0)
44 |
45 | #define HIGHSPEED_SPI_DIV SPI_DIV2
46 |
47 | /*
48 | * Mutex to lock output buffer
49 | */
50 | static Mutex SPIMtx; /* Mutex */
51 |
52 | /*
53 | * SPI configuration structure.
54 | */
55 | static const SPIConfig hs_spicfg = {NULL, GPIOA, GPIOA_PIN4, SPI_DIV2};
56 |
57 | /*
58 | * Initialize the SPI interface
59 | */
60 | void SPIInit(void)
61 | {
62 | /*
63 | * SPI1 I/O pins setup.
64 | */
65 | palSetPadMode(GPIOA, GPIOA_PIN5, PAL_MODE_STM32_ALTERNATE_PUSHPULL); /* SCK. */
66 | palSetPadMode(GPIOA, GPIOA_PIN6, PAL_MODE_STM32_ALTERNATE_PUSHPULL); /* MISO.*/
67 | palSetPadMode(GPIOA, GPIOA_PIN7, PAL_MODE_STM32_ALTERNATE_PUSHPULL); /* MOSI.*/
68 | palSetPadMode(GPIOA, GPIOA_PIN4, PAL_MODE_OUTPUT_PUSHPULL);
69 | palSetPad(GPIOA, GPIOA_PIN4);
70 |
71 | /*
72 | * Initialize Mutex
73 | */
74 | chMtxInit(&SPIMtx); /* Mutex initialization before use */
75 | }
76 |
77 | /*
78 | * SPI bus exchange routine
79 | */
80 | int SPIExchangeData(SPIDriver *spip, uint8_t *tx, uint8_t *rx, size_t size) {
81 | chMtxLock(&SPIMtx);
82 |
83 | /*
84 | * Do exchange between device and MCU.
85 | */
86 | spiAcquireBus(spip); /* Acquire ownership of the bus. */
87 | spiStart(spip, &hs_spicfg); /* Setup transfer parameters. */
88 | spiSelect(spip); /* Slave Select assertion. */
89 | spiExchange(spip, size, tx, rx); /* Atomic transfer operations. */
90 | spiUnselect(spip); /* Slave Select de-assertion. */
91 | spiReleaseBus(spip); /* Ownership release. */
92 |
93 | chMtxUnlock();
94 |
95 | return 0;
96 | }
97 |
98 | /*
99 | * SPI bus send routine
100 | */
101 | int SPISendData(SPIDriver *spip, uint8_t *tx, size_t size) {
102 |
103 | chMtxLock(&SPIMtx);
104 |
105 | /*
106 | * Do exchange between device and MCU.
107 | */
108 | spiAcquireBus(spip); /* Acquire ownership of the bus. */
109 | spiStart(spip, &hs_spicfg); /* Setup transfer parameters. */
110 | spiSelect(spip); /* Slave Select assertion. */
111 | spiSend(spip, size, tx); /* Send command */
112 | spiUnselect(spip); /* Slave Select de-assertion. */
113 | spiReleaseBus(spip); /* Ownership release. */
114 |
115 | chMtxUnlock();
116 |
117 | return 0;
118 | }
119 |
120 | /*
121 | * SPI bus receive routine
122 | */
123 | int SPIReceiveData(SPIDriver *spip, uint8_t *rx, size_t size) {
124 |
125 | chMtxLock(&SPIMtx);
126 |
127 | /*
128 | * Do exchange between device and MCU.
129 | */
130 | spiAcquireBus(spip); /* Acquire ownership of the bus. */
131 | spiStart(spip, &hs_spicfg); /* Setup transfer parameters. */
132 | spiSelect(spip); /* Slave Select assertion. */
133 | spiReceive(spip, size, rx);
134 | spiUnselect(spip); /* Slave Select de-assertion. */
135 | spiReleaseBus(spip); /* Ownership release. */
136 |
137 | chMtxUnlock();
138 |
139 | return 0;
140 | }
141 |
--------------------------------------------------------------------------------
/nrf_spi.h:
--------------------------------------------------------------------------------
1 | /*
2 | ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
3 | 2011,2012 Giovanni Di Sirio.
4 |
5 | This file is part of ChibiOS/RT.
6 |
7 | ChibiOS/RT is free software; you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation; either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | ChibiOS/RT is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 |
20 | ---
21 |
22 | A special exception to the GPL can be applied should you wish to distribute
23 | a combined work that includes ChibiOS/RT, without being obliged to provide
24 | the source code for any proprietary components. See the file exception.txt
25 | for full details of how and when the exception can be applied.
26 | */
27 |
28 | /*
29 | * Initialize the SPI interface
30 | */
31 | void SPIInit(void);
32 |
33 | /*
34 | * SPI bus exchange routine
35 | */
36 | int SPIExchangeData(SPIDriver *spip, uint8_t *tx, uint8_t *rx, size_t size);
37 |
38 | /*
39 | * SPI bus send routine
40 | */
41 | int SPISendData(SPIDriver *spip, uint8_t *tx, size_t size);
42 |
43 | /*
44 | * SPI bus receive routine
45 | */
46 | int SPIReceiveData(SPIDriver *spip, uint8_t *rx, size_t size);
47 |
48 |
--------------------------------------------------------------------------------
/oneWire.c:
--------------------------------------------------------------------------------
1 |
2 | #include "ch.h"
3 | #include "hal.h"
4 | #include "oneWire.h"
5 | #include "string.h"
6 |
7 | #define OW_TIMEOUT_MS 10 // break timeout
8 |
9 | static struct UsartDictionnary {
10 | OneWireDriver *drv[1];
11 | UARTDriver *uart[1];
12 | } usartDict = { .drv = {NULL},
13 | .uart = {NULL}
14 | };
15 |
16 |
17 |
18 | static void oneWireSerialMode (OneWireDriver* drv, SerialMode sm);
19 | static uint8_t oneWireUnpack (uint8_t buffer[8]);
20 | static void oneWirePack (uint8_t cmd, uint8_t buffer[8]);
21 | static uint8_t oneWireNext(OneWireDriver* drv, uint8_t *romBytes,
22 | bool_t conditional);
23 | static uint8_t oneWireFirst(OneWireDriver* drv, uint8_t *romBytes,
24 | bool_t conditional);
25 | static void usartDictionnaryAddPair (OneWireDriver* drv, UARTDriver *uart);
26 | static OneWireDriver* usartDictionnaryGetDriverByUart (UARTDriver *uart);
27 |
28 |
29 | // USART CALLBACK
30 | static void txBufferEmpty(UARTDriver *uartp) ;
31 | static void rxErr(UARTDriver *uartp, uartflags_t e);
32 | static void rxEnd(UARTDriver *uartp);
33 | //static void rxChar(UARTDriver *uartp, uint16_t c);
34 |
35 |
36 |
37 | static const UARTConfig uartCfgReset = {
38 | NULL,
39 | txBufferEmpty,
40 | rxEnd,
41 | NULL, // rxChar,
42 | rxErr,
43 | 9600,
44 | 0,
45 | 0,
46 | USART_CR3_HDSEL // half duplex mode
47 | };
48 |
49 | static const UARTConfig uartCfgTransfert = {
50 | NULL,
51 | txBufferEmpty,
52 | rxEnd,
53 | NULL, //rxChar,
54 | rxErr,
55 | 115200,
56 | 0,
57 | 0,
58 | USART_CR3_HDSEL // half duplex mode
59 | };
60 |
61 | static const uint8_t dscrc_table[] = {
62 | 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
63 | 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
64 | 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
65 | 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
66 | 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
67 | 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
68 | 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
69 | 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
70 | 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
71 | 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
72 | 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
73 | 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
74 | 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
75 | 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
76 | 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
77 | 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
78 |
79 |
80 | static const uint8_t owBufferWrite[] = {
81 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
82 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
83 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
84 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
85 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
86 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
87 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
88 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
89 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
90 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
91 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
92 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
93 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
94 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
95 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
96 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
97 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
98 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
99 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
100 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
101 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
102 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
103 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
104 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
105 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
106 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
107 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
108 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
109 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
110 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
111 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
112 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
113 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
114 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
115 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
116 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
117 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
118 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
119 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
120 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
121 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
122 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
123 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
124 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
125 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
126 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
127 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
128 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
129 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
130 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
131 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0xff, 0xff,
132 | 0xff, 0xff
133 | };
134 |
135 |
136 | void oneWireInit (OneWireDriver* drv, const OneWireConfig *cfg)
137 | {
138 | memcpy (&(drv->config), cfg, sizeof (OneWireConfig));
139 | oneWireSerialMode (drv, ModeGpioIn);
140 | chBSemInit (&(drv->semSent), TRUE);
141 | chBSemInit (&(drv->semReceive), TRUE);
142 | chMtxInit (&(drv->acquireLock));
143 | drv->lastDiscrep = 0;
144 | drv->doneFlag = FALSE;
145 | usartDictionnaryAddPair (drv, cfg->uartd);
146 | }
147 |
148 | #define ARRAY_LEN(a) (sizeof(a)/sizeof(a[0]))
149 |
150 |
151 | bool_t oneWireReset (OneWireDriver* drv)
152 | {
153 | uint8_t owPresence;
154 | const uint8_t resetByte = 0xf0;
155 |
156 | oneWireSerialMode (drv, ModeSerialReset);
157 |
158 | chBSemReset(&(drv->semSent), TRUE);
159 | chBSemReset(&(drv->semReceive), TRUE);
160 | uartStartReceive (drv->config.uartd, 1 , (void *) &owPresence);
161 | uartStartSend (drv->config.uartd, 1, &resetByte);
162 | if (chBSemWaitTimeout(&(drv->semSent), MS2ST(OW_TIMEOUT_MS)) == RDY_TIMEOUT){
163 | return FALSE;
164 | }
165 | if (chBSemWaitTimeout(&(drv->semReceive), MS2ST(OW_TIMEOUT_MS)) == RDY_TIMEOUT){
166 | return FALSE;
167 | }
168 |
169 | oneWireSerialMode (drv, ModeSerialTransfert);
170 |
171 | return (owPresence != resetByte);
172 | }
173 |
174 |
175 | void oneWireSendByte (OneWireDriver* drv, uint8_t command)
176 | {
177 | oneWireSend (drv, &command, 1);
178 | }
179 |
180 | uint8_t oneWireReceiveByte (OneWireDriver* drv)
181 | {
182 | uint8_t buf;
183 | oneWireReceive (drv, &buf, 1);
184 |
185 | return buf;
186 | }
187 |
188 |
189 | void oneWireSendBit (OneWireDriver* drv, bool_t bit)
190 | {
191 | uint8_t bitBuf;
192 | bitBuf = bit ? 0xff : 0x00;
193 |
194 | chBSemReset(&(drv->semSent), TRUE);
195 | uartStartSend (drv->config.uartd, 1, &bitBuf);
196 | chBSemWait (&(drv->semSent));
197 |
198 | }
199 |
200 |
201 |
202 | bool_t oneWireSend (OneWireDriver* drv, const uint8_t *command, uint8_t len)
203 | {
204 | const uint32_t owLen = len*8;
205 | uint8_t cmdBuf[owLen];
206 |
207 | for (uint32_t i=0; isemSent), TRUE);
212 | uartStartSend (drv->config.uartd, owLen, &cmdBuf);
213 | if (chBSemWaitTimeout(&(drv->semSent), MS2ST(OW_TIMEOUT_MS)) == RDY_TIMEOUT){
214 | return FALSE;
215 | }
216 |
217 | return TRUE;
218 | }
219 |
220 | bool_t oneWireReceive (OneWireDriver* drv, uint8_t *buffer, uint8_t len)
221 | {
222 | const uint32_t owLen = len*8;
223 | uint8_t owBufferRead[owLen];
224 |
225 | if (owLen > sizeof (owBufferWrite)) {
226 | return FALSE;
227 | }
228 | chBSemReset(&(drv->semReceive), TRUE);
229 | uartStartReceive (drv->config.uartd, owLen , (void *) owBufferRead);
230 | chBSemReset(&(drv->semSent), TRUE);
231 | uartStartSend (drv->config.uartd, owLen, (void *) owBufferWrite);
232 | if (chBSemWaitTimeout(&(drv->semSent), MS2ST(OW_TIMEOUT_MS)) == RDY_TIMEOUT){
233 | return FALSE;
234 | }
235 | if (chBSemWaitTimeout(&(drv->semReceive), MS2ST(OW_TIMEOUT_MS)) == RDY_TIMEOUT){
236 | return FALSE;
237 | }
238 |
239 | for (uint32_t i=0; isemReceive), TRUE);
252 | uartStartReceive (drv->config.uartd, 1 , (void *) &rec);
253 | chBSemReset(&(drv->semSent), TRUE);
254 | uartStartSend (drv->config.uartd, 1, (void *) owBufferWrite);
255 | if (chBSemWaitTimeout(&(drv->semSent), MS2ST(OW_TIMEOUT_MS)) == RDY_TIMEOUT){
256 | return FALSE;
257 | }
258 | if (chBSemWaitTimeout(&(drv->semReceive), MS2ST(OW_TIMEOUT_MS)) == RDY_TIMEOUT){
259 | return FALSE;
260 | }
261 |
262 | return (rec == 0xff);
263 | }
264 |
265 | bool_t oneWireReadRom (OneWireDriver* drv, OneWireRomAddress *rom)
266 | {
267 | oneWireReset (drv);
268 | oneWireSendByte (drv, 0x33);
269 | oneWireReceive (drv, rom->addr, sizeof (rom->addr));
270 | // uint8_t crc = oneWireCrc8(rom->addr, 7);
271 | uint8_t crc = owCrc8(rom->addr, 7);
272 | if (crc != rom->addr[7]) {
273 | return FALSE;
274 | } else {
275 | return TRUE;
276 | }
277 | }
278 |
279 |
280 |
281 |
282 | uint8_t oneWireSearchRom (OneWireDriver* drv, bool_t conditional,
283 | OneWireRomAddress *addrs, uint8_t len)
284 | {
285 | uint8_t m, cont = 0;
286 | uint8_t romBytes[8] = {0,0,0,0,0,0,0,0};
287 |
288 | oneWireAcquireBus (drv);
289 | if(oneWireReset(drv)) {
290 | if(oneWireFirst(drv, romBytes, conditional)) {
291 | // Begins when at least one part found
292 | uint8_t numROMs = 0;
293 | do {
294 | cont++;
295 | for (m=0;m<8;m++) {
296 | addrs[numROMs].addr[m] = romBytes[m];
297 | }
298 | numROMs++; // Continues until no additional
299 | } while ((numROMs < len) && oneWireNext(drv, romBytes, conditional));
300 |
301 | while (numROMs < len) {
302 | for (m=0;m<8;m++) {
303 | addrs[numROMs].addr[m] = 0;
304 | }
305 | numROMs++;
306 | }
307 | }
308 | }
309 | oneWireRealeaseBus ();
310 | return cont;
311 | }
312 |
313 |
314 | /*uint8_t oneWireCrc8( uint8_t *addr, uint8_t len)
315 | {
316 | uint8_t crc = 0;
317 |
318 | while (len--) {
319 | crc = dscrc_table[crc ^ *addr++];
320 | }
321 | return crc;
322 | }*/
323 |
324 | uint8_t crcDS(uint8_t inp, uint8_t crc) {
325 | inp ^= crc;
326 | crc = 0;
327 | if(inp & 0x1) crc ^= 0x5e;
328 | if(inp & 0x2) crc ^= 0xbc;
329 | if(inp & 0x4) crc ^= 0x61;
330 | if(inp & 0x8) crc ^= 0xc2;
331 | if(inp & 0x10) crc ^= 0x9d;
332 | if(inp & 0x20) crc ^= 0x23;
333 | if(inp & 0x40) crc ^= 0x46;
334 | if(inp & 0x80) crc ^= 0x8c;
335 | return crc;
336 | }
337 |
338 | uint8_t owCrc8(uint8_t *addr, uint8_t len) {
339 | uint8_t crc = 0;
340 | while (len--) {
341 | crc = crcDS(*addr++, crc);
342 | }
343 | return crc;
344 | }
345 |
346 | void oneWireAcquireBus (OneWireDriver* drv)
347 | {
348 | chMtxLock (&(drv->acquireLock));
349 | }
350 |
351 | void oneWireRealeaseBus (void)
352 | {
353 | chMtxUnlock ();
354 | }
355 |
356 | /*
357 | # _ __ _ _
358 | # | '_ \ (_) | |
359 | # | |_) | _ __ _ __ __ __ _ | |_ ___
360 | # | .__/ | '__| | | \ \ / / / _` | | __| / _ \
361 | # | | | | | | \ V / | (_| | \ |_ | __/
362 | # |_| |_| |_| \_/ \__,_| \__| \___|
363 | */
364 |
365 |
366 | static void oneWirePack (uint8_t cmd, uint8_t buffer[8])
367 | {
368 | for (uint32_t i=0; i<8; i++) {
369 | buffer[i] = (cmd & (1 << i)) ? 0xff : 0x00;
370 | }
371 | }
372 |
373 | static uint8_t oneWireUnpack (uint8_t buffer[8])
374 | {
375 | uint8_t res = 0;
376 |
377 | for (uint32_t i=0; i<8; i++) {
378 | if (buffer[i] == 0xff) {
379 | res |= (1 << i);
380 | }
381 | }
382 |
383 | return res;
384 | }
385 |
386 | static void oneWireSerialMode (OneWireDriver* drv, SerialMode sm)
387 | {
388 | /* for STM32F4DISCOVERY
389 | * const uint32_t modeTx =
390 | PAL_MODE_ALTERNATE(drv->config.dqAlternate) | PAL_STM32_OTYPE_OPENDRAIN
391 | | PAL_MODE_INPUT_PULLUP | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_MODE_ALTERNATE;
392 | */
393 | // for STM32F103
394 | const uint32_t modeTx = PAL_MODE_STM32_ALTERNATE_OPENDRAIN;
395 |
396 | if (sm == drv->currentSm)
397 | return;
398 |
399 | switch (sm) {
400 | case ModeGpioIn:
401 | uartStop (drv->config.uartd);
402 | palSetPadMode (drv->config.dqPort, drv->config.dqPad, PAL_MODE_INPUT_PULLUP);
403 | break;
404 |
405 | case ModeSerialReset:
406 | // uartStop (drv->config.uartd);
407 | uartStart(drv->config.uartd, &uartCfgReset);
408 |
409 | palSetPadMode (drv->config.dqPort, drv->config.dqPad, modeTx);
410 | break;
411 |
412 | case ModeSerialTransfert:
413 | // uartStop (drv->config.uartd);
414 | uartStart(drv->config.uartd, &uartCfgTransfert);
415 |
416 | palSetPadMode (drv->config.dqPort, drv->config.dqPad, modeTx);
417 | break;
418 | }
419 | drv->currentSm = sm;
420 | }
421 |
422 |
423 |
424 | static void txBufferEmpty(UARTDriver *uartp)
425 | {
426 | (void) uartp;
427 | OneWireDriver *drv = usartDictionnaryGetDriverByUart (uartp);
428 | if (drv != NULL) {
429 | chSysLockFromIsr();
430 | chBSemSignalI(&(drv->semSent));
431 | chSysUnlockFromIsr();
432 | }
433 | }
434 |
435 | static void rxErr(UARTDriver *uartp, uartflags_t e)
436 | {
437 | (void) uartp;
438 | (void) e;
439 | }
440 |
441 |
442 | static void rxEnd(UARTDriver *uartp)
443 | {
444 | (void) uartp;
445 | OneWireDriver *drv = usartDictionnaryGetDriverByUart (uartp);
446 | if (drv != NULL) {
447 | chSysLockFromIsr();
448 | chBSemSignalI(&(drv->semReceive));
449 | chSysUnlockFromIsr();
450 | }
451 | }
452 |
453 | /* static void rxChar(UARTDriver *uartp, uint16_t c) */
454 | /* { */
455 | /* (void) uartp; */
456 | /* (void) c; */
457 | /* } */
458 |
459 |
460 | static uint8_t oneWireFirst (OneWireDriver* drv, uint8_t *romBytes,
461 | bool_t conditional)
462 | {
463 | drv->lastDiscrep = 0;
464 | drv->doneFlag = FALSE;
465 | // Call Next and return it's return value;
466 | return oneWireNext(drv, romBytes, conditional);
467 | }
468 |
469 |
470 |
471 | static uint8_t oneWireNext (OneWireDriver* drv, uint8_t *romBytes,
472 | bool_t conditional)
473 | {
474 | uint8_t m = 1; // ROM Bit index
475 | uint8_t n = 0; // ROM Byte index
476 | uint8_t k = 1; // Bit mask
477 | uint8_t x = 0;
478 | uint8_t discrepMarker = 0;
479 | uint8_t g=0; // Output bit
480 | uint8_t nxt=0; // Return value
481 | short flag=0;
482 | static uint8_t dowcrc;
483 |
484 | nxt = FALSE; // Reset next flag to false
485 | dowcrc = 0; // Reset the dowcrc
486 | flag = !oneWireReset(drv);
487 |
488 | if (flag||drv->doneFlag) // If no parts return false
489 | {
490 | drv->lastDiscrep = 0; // Reset the search
491 | return FALSE;
492 | }
493 |
494 | // Send SearchROM or Conditional Search Rom command
495 | oneWireSendByte(drv, conditional ? 0xEC : 0xF0);
496 | do
497 | {
498 | x = 0;
499 | if (oneWireReceiveBit(drv) == 1)
500 | x = 2;
501 | if (oneWireReceiveBit(drv) == 1)
502 | x |= 1; // And it's complement
503 | if (x == 3) // There are no devices on the one wire bus
504 | break;
505 | else
506 | {
507 | if (x > 0) // All devices coupled have 0 or 1
508 | g = x >> 1; // Bit write value for search
509 |
510 | // If this discrepancy is before the last discrepancy on a previous
511 | // Next then pick the same as last time.
512 | else
513 | {
514 | if (m < drv->lastDiscrep)
515 | g = ((romBytes[n] & k) > 0);
516 | // If equal to last pick 1
517 | else
518 | g = (m == drv->lastDiscrep); // If not then pick 0
519 |
520 | // If 0 was picked then record position with mask k
521 | if (g == 0) discrepMarker = m;
522 | }
523 |
524 | // Isolate bit in ROM[n] with mask k
525 | if (g == 1) romBytes[n] |= k;
526 | else romBytes[n] &= ~k;
527 |
528 | oneWireSendBit(drv, g); // ROM search write
529 |
530 | m++; // Increment bit counter m
531 | k = k << 1; // and shift the bit mask k
532 | // If the mask is 0 then go to new ROM
533 | if (k == 0)
534 | { // Byte n and reset mask
535 | // dowcrc = dscrc_table[dowcrc ^ romBytes[n]]; // Accumulate the crc
536 | dowcrc = crcDS(romBytes[n], dowcrc);
537 | n++;
538 | k++;
539 | }
540 | }
541 | } while (n < 8); // Loop through until through all ROM bytes 0-7
542 |
543 | if (m < (65||dowcrc)) // If search was unsuccessful then
544 | drv->lastDiscrep = 0; // reset the last Discrepancy to zero
545 | else // Search was successful, so set lastDiscrep, lastOne, nxt
546 | {
547 | drv->lastDiscrep = discrepMarker;
548 | drv->doneFlag = (drv->lastDiscrep == 0);
549 | nxt = TRUE; // Indicates search not yet complete, more parts remain
550 | }
551 |
552 | return nxt;
553 | }
554 |
555 | static void usartDictionnaryAddPair (OneWireDriver* drv, UARTDriver *uart)
556 | {
557 | uint8_t i = 0;
558 |
559 | while (i++ < ARRAY_LEN (usartDict.drv)) {
560 | if (usartDict.drv[i] == drv) {
561 | usartDict.uart[i] = uart;
562 | return;
563 | }
564 | }
565 |
566 | i = 0;
567 | while (i < ARRAY_LEN (usartDict.drv) && (usartDict.drv[i] != NULL)) {
568 | i++;
569 | }
570 |
571 | if (i < ARRAY_LEN (usartDict.drv)) {
572 | usartDict.drv[i] = drv;
573 | usartDict.uart[i] = uart;
574 | }
575 | }
576 |
577 | static OneWireDriver* usartDictionnaryGetDriverByUart (UARTDriver *uart)
578 | {
579 | uint8_t i = 0;
580 | while ((i < ARRAY_LEN (usartDict.drv) && usartDict.uart[i] != uart)) {
581 | i++;
582 | }
583 | if (i < ARRAY_LEN (usartDict.drv)) {
584 | return usartDict.drv[i];
585 | } else {
586 | return NULL;
587 | }
588 | }
589 |
--------------------------------------------------------------------------------
/oneWire.h:
--------------------------------------------------------------------------------
1 | #ifndef __ONE_WIRE_H__
2 | #define __ONE_WIRE_H__
3 | #include "ch.h"
4 | #include "hal.h"
5 |
6 | /*
7 | This is a library for OneWire Master bus http://en.wikipedia.org/wiki/1-Wire
8 | based on advices found on dallas documentation :
9 | http://www.maximintegrated.com/app-notes/index.mvp/id/214
10 | this library use an usart to avoid to consume cpu cycle in bit banging
11 |
12 | the library is synchronous, but when waiting it yield the processor to chibios.
13 |
14 | Alexandre Bustico
15 | alexandre.bustico@enac.fr
16 |
17 | TODO : envoyer les 0xff depuis la flash pour economiser de la stack
18 | port discovery
19 | temperature en asynchrone sur plusieurs capteurs
20 |
21 |
22 | */
23 |
24 |
25 | struct OneWireDriver;
26 | typedef struct OneWireDriver OneWireDriver;
27 |
28 | typedef struct {
29 | uint8_t addr[8];
30 | } OneWireRomAddress;
31 |
32 | typedef struct {
33 | ioportid_t dqPort; // the port for the data IO
34 | uint8_t dqPad; // pad for the data IO, shloud be the tx of an usart
35 | uint8_t dqAlternate; // alternate function, see stm32 ref manuel to find it
36 | UARTDriver *uartd; // Chibios Uart Driver used as oneWire interface
37 | } OneWireConfig;
38 |
39 |
40 |
41 | /*
42 | create OneWireDriver object, initialise UART
43 | */
44 | void oneWireInit (OneWireDriver* drv, const OneWireConfig *cfg);
45 |
46 | /*
47 | send a reset condition on the OneWire bus to reinitialise all
48 | slave on this bus
49 | */
50 | bool_t oneWireReset (OneWireDriver* drv);
51 |
52 |
53 | /*
54 | basic io : send/receive bit, byte, buffers
55 | since every OneWire Bit involve uart byte,
56 | oneWireSend need to reserve len*8 bytes on the stack
57 | oneWireReceive need to reserve len*8*2 bytes on the stack
58 | So Stack size should be calculated according to this if you send receive
59 | big bunch of bytes.
60 | */
61 | bool_t oneWireReceiveBit (OneWireDriver* drv);
62 | void oneWireSendBit (OneWireDriver* drv, bool_t bit);
63 | void oneWireSendByte (OneWireDriver* drv, uint8_t command);
64 | uint8_t oneWireReceiveByte (OneWireDriver* drv);
65 | bool_t oneWireSend (OneWireDriver* drv, const uint8_t *command, uint8_t len);
66 | bool_t oneWireReceive (OneWireDriver* drv, uint8_t *buffer, uint8_t len);
67 |
68 | /*
69 | get rom address of the slave when there is just ONE slave connected
70 | otherwise (multiple slaves connected), use oneWireSearchRom
71 | */
72 | bool_t oneWireReadRom (OneWireDriver* drv, OneWireRomAddress *addr);
73 |
74 |
75 | /*
76 | get all rom address when multiple slave are connected
77 | depending on conditional value, get All the
78 | slave or just the slave which are in alarm state (cf conditional search)
79 | it's your responsability to give a pointer on an sufficently large
80 | array for all the slave, otherwise you will miss some slave.
81 | */
82 | uint8_t oneWireSearchRom (OneWireDriver* drv, bool_t conditional,
83 | OneWireRomAddress *addrs, uint8_t len);
84 |
85 |
86 | /*
87 | crc helper function implementing crc8 used bu oneWire slave, to ensure that
88 | the data received are valid
89 | */
90 | //uint8_t oneWireCrc8( uint8_t *addr, uint8_t len);
91 |
92 | uint8_t owCrc8( uint8_t *addr, uint8_t len);
93 |
94 | /*
95 | If more than one thread would communicate with different slaves,
96 | call to oneWire function should be pritected by these functions
97 | */
98 | void oneWireAcquireBus (OneWireDriver* drv);
99 | void oneWireRealeaseBus (void);
100 |
101 |
102 | /*
103 | This is private data, for internal library state only
104 | */
105 |
106 | // Private Data Daclaration
107 | typedef enum {ModeGpioIn, ModeSerialReset, ModeSerialTransfert} SerialMode;
108 |
109 | struct OneWireDriver {
110 | OneWireConfig config;
111 | SerialMode currentSm;
112 | Mutex acquireLock;
113 | BinarySemaphore semSent;
114 | BinarySemaphore semReceive;
115 | uint8_t lastDiscrep ;
116 | bool_t doneFlag ;
117 | };
118 |
119 |
120 | #endif //__ONE_WIRE_H__
121 |
--------------------------------------------------------------------------------
/owtemp.c:
--------------------------------------------------------------------------------
1 | /*
2 | * owtemp.c - 1-Wire temperature sensor DS1820B driver
3 | *
4 | * Created on: 28.03.2013
5 | * Author: A.Polyakov
6 | */
7 |
8 | #include "ch.h"
9 | #include "hal.h"
10 |
11 | #include "owtemp.h"
12 | #include "oneWire.h"
13 | #include "ds1820b.h"
14 |
15 | #include
16 | #include
17 |
18 | //#define ARRAY_LEN(a) (sizeof(a)/sizeof(a[0]))
19 | #define OWSCAN_TIMEOUT_MS 250 // задержка сканирования датчиков температуры (мсек)
20 | #define OWTEMPCONV 190 // задержка конвертирования (мсек) для датчиков температуры DS1820B
21 | #define OWTEMPPREC 10 // точность преобразования для датчиков температуры
22 |
23 | static OneWireRomAddress romAddr[OWDEVICES];
24 |
25 | // признак инициализации oneWire
26 | extern bool_t ow_initialized;
27 |
28 | extern OneWireDriver owDrv;
29 | extern const OneWireConfig owCfg;
30 | extern BinarySemaphore owsem;
31 |
32 | ow_temp_read_t ow_temp_read; // возвращает значения температуры и признак ошибки
33 | static BinarySemaphore owtempsem;
34 |
35 | /*
36 | * Процесс сканирования температурных датчиков DS1820B
37 | */
38 | static Thread *OWTempThread_p;
39 | static WORKING_AREA(waOWTempThread, 256);
40 | __attribute__((noreturn))
41 | static msg_t OWTempThread(void *arg) {
42 | (void)arg;
43 | chRegSetThreadName("owTempThd");
44 | while (TRUE) {
45 | ow_temp_read_t *req;
46 | Thread *tp;
47 |
48 | tp = chMsgWait();
49 | req = (ow_temp_read_t *) chMsgGet(tp);
50 | chMsgRelease(tp, (msg_t) req);
51 |
52 | req->error = OW_TEMP_NO_ERROR;
53 |
54 | chBSemWait(&owsem);
55 | oneWireSearchRom (&owDrv, FALSE, romAddr, OWDEVICES);
56 | bool_t ow_found = FALSE;
57 | for (uint8_t i=0; iowtemp[i].key[0] = 0x00;
70 | if (romAddr[i].addr[0] == 0x28) {
71 | memcpy(&req->owtemp[i].key,&romAddr[i],8);
72 | req->owtemp[i].value = ds1820BGGetTempFromRam(&owDrv, &(romAddr[i]));
73 | }
74 | }
75 | chBSemSignal(&owsem);
76 | }
77 | else {
78 | req->error = OW_TEMP_NOT_FOUND;
79 | }
80 |
81 | chBSemSignal(&owtempsem);
82 | }//while
83 | }
84 |
85 | // получает значения с температурных датчиков DS1820B
86 | ow_temp_error_t owtemp_read(void) {
87 | ow_temp_read_t *ow_temp_read_p = &ow_temp_read;
88 |
89 | chBSemWait(&owtempsem); /* to be sure */
90 |
91 | chMsgSend(OWTempThread_p, (msg_t) ow_temp_read_p);
92 |
93 | /* wait for reply */
94 | if(chBSemWaitTimeout(&owtempsem, MS2ST(OWSCAN_TIMEOUT_MS)) == RDY_TIMEOUT) {
95 | chBSemReset(&owtempsem, FALSE);
96 | ow_temp_read.error = OW_TEMP_TIMEOUT;
97 | return OW_TEMP_TIMEOUT;
98 | }
99 | chBSemReset(&owtempsem, FALSE);
100 | return ow_temp_read.error;
101 | }
102 |
103 | // создает процесс опроса датчиков DS1820B
104 | void ow_temp_init(void){
105 | chBSemInit(&owtempsem, FALSE);
106 | oneWireInit(&owDrv,&owCfg);
107 | // Создаем процесс опроса датчиков 1-wire
108 | OWTempThread_p = chThdCreateStatic(waOWTempThread, sizeof(waOWTempThread), OWTEMP_PRIO, OWTempThread, NULL);
109 | }
110 |
--------------------------------------------------------------------------------
/owtemp.h:
--------------------------------------------------------------------------------
1 | /*
2 | * owtemp.h
3 | */
4 | #ifndef OWTEMP_H_
5 | #define OWTEMP_H_
6 |
7 | #define OWDEVICES 6 // max 1-wire devices on bus
8 | #define OWTEMP_PRIO NORMALPRIO+1
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | typedef struct _ow_temp_t ow_temp_t; // описание датчика температуры DS1820B
15 | struct _ow_temp_t {
16 | uint8_t key[8]; // идентификатор датчика DS1820B
17 | float value; // значение датчика
18 | };
19 |
20 | typedef enum {
21 | OW_TEMP_UNKNOWN,
22 | OW_TEMP_NO_ERROR,
23 | OW_TEMP_NOT_FOUND,
24 | OW_TEMP_TIMEOUT,
25 | } ow_temp_error_t;
26 |
27 | typedef struct _ow_temp_read_t ow_temp_read_t;
28 | struct _ow_temp_read_t {
29 | ow_temp_error_t error;
30 | ow_temp_t owtemp[OWDEVICES]; /* out */
31 | };
32 |
33 | extern ow_temp_read_t ow_temp_read;
34 |
35 | void ow_temp_init(void);
36 | ow_temp_error_t owtemp_read(void);
37 |
38 | #ifdef __cplusplus
39 | }
40 | #endif
41 | #endif /* OWTEMP_H_ */
42 |
--------------------------------------------------------------------------------
/sensors.c:
--------------------------------------------------------------------------------
1 | /*
2 | * sensors.c
3 | *
4 | * Created on: 01.04.2013
5 | * Author: pae
6 | */
7 |
8 | /*
9 | * BOARD STM32F103C_MINNI MCU STM32F103C8T6
10 | *
11 | * PERIPHERALS MODES REMAP FUNCTIONS PINS
12 | * ADC1 IN8 0 ADC1_IN8 PB0
13 | * ADC1 IN9 0 ADC1_IN9 PB1
14 | */
15 |
16 | #include "ch.h"
17 | #include "hal.h"
18 |
19 | #include "sensors.h"
20 |
21 | adc_read_t sensors; // описание датчиков
22 | static BinarySemaphore adcsem, adc_cbsem; // семафор управления процессом adc
23 |
24 | static adcsample_t samples[SENSORSALL]; // буфер чтения АЦП
25 |
26 | static void adccallback(ADCDriver *adcp, adcsample_t *buffer, size_t n);
27 | static void adcerrcallback(ADCDriver *adcp, adcerror_t err);
28 |
29 | /*
30 | * ADC conversion group.
31 | * Mode: Linear buffer, 1 samples of 17 channels, SW triggered.
32 | * Channels: IN0-17 (239.5 cycles sampling time)
33 | */
34 | static const ADCConversionGroup adcgrpcfg = {
35 | FALSE, //circular
36 | SENSORSALL, //number of channels
37 | adccallback, //adc callback function
38 | adcerrcallback, //error callback function
39 | /* HW dependent part.*/
40 | 0, //cr1
41 | 0, //cr2
42 | //SMPR1 register
43 | // ADC_SMPR1_SMP_VREF(ADC_SAMPLE_239P5) |
44 | // ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_239P5) |
45 | // ADC_SMPR1_SMP_AN15(ADC_SAMPLE_239P5) |
46 | // ADC_SMPR1_SMP_AN14(ADC_SAMPLE_239P5) |
47 | // ADC_SMPR1_SMP_AN13(ADC_SAMPLE_239P5) |
48 | // ADC_SMPR1_SMP_AN12(ADC_SAMPLE_239P5) |
49 | // ADC_SMPR1_SMP_AN11(ADC_SAMPLE_239P5) |
50 | // ADC_SMPR1_SMP_AN10(ADC_SAMPLE_239P5) |
51 | 0,
52 | //SMPR2 register
53 | // ADC_SMPR2_SMP_AN9(ADC_SAMPLE_239P5) |
54 | // ADC_SMPR2_SMP_AN8(ADC_SAMPLE_239P5) |
55 | // ADC_SMPR2_SMP_AN7(ADC_SAMPLE_239P5) |
56 | // ADC_SMPR2_SMP_AN6(ADC_SAMPLE_239P5) |
57 | // ADC_SMPR2_SMP_AN5(ADC_SAMPLE_239P5) |
58 | // ADC_SMPR2_SMP_AN4(ADC_SAMPLE_239P5) |
59 | // ADC_SMPR2_SMP_AN3(ADC_SAMPLE_239P5) |
60 | // ADC_SMPR2_SMP_AN2(ADC_SAMPLE_239P5) |
61 | // ADC_SMPR2_SMP_AN1(ADC_SAMPLE_239P5) |
62 | ADC_SMPR2_SMP_AN0(ADC_SAMPLE_239P5) |
63 | 0,
64 | //SQR1 register
65 | // ADC_SQR1_SQ16_N(ADC_CHANNEL_SENSOR) |
66 | // ADC_SQR1_SQ15_N(ADC_CHANNEL_IN15) |
67 | // ADC_SQR1_SQ14_N(ADC_CHANNEL_IN14) |
68 | // ADC_SQR1_SQ13_N(ADC_CHANNEL_IN13) |
69 | ADC_SQR1_NUM_CH(SENSORSALL),
70 | //SQR2 register
71 | // ADC_SQR2_SQ12_N(ADC_CHANNEL_IN12) |
72 | // ADC_SQR2_SQ11_N(ADC_CHANNEL_IN11) |
73 | // ADC_SQR2_SQ10_N(ADC_CHANNEL_IN10) |
74 | // ADC_SQR2_SQ9_N(ADC_CHANNEL_IN9) |
75 | // ADC_SQR2_SQ8_N(ADC_CHANNEL_IN8) |
76 | // ADC_SQR2_SQ7_N(ADC_CHANNEL_IN7) |
77 | 0,
78 | //SQR3 register
79 | // ADC_SQR3_SQ6_N(ADC_CHANNEL_IN9) |
80 | // ADC_SQR3_SQ5_N(ADC_CHANNEL_IN8) |
81 | // ADC_SQR3_SQ4_N(ADC_CHANNEL_IN3) |
82 | // ADC_SQR3_SQ3_N(ADC_CHANNEL_IN9) |
83 | // ADC_SQR3_SQ2_N(ADC_CHANNEL_IN9) |
84 | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN8) |
85 | 0
86 | };
87 |
88 | /*
89 | * ADC end conversion callback
90 | */
91 | static void adccallback(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
92 | (void) buffer; (void) n;
93 | if (adcp->state == ADC_COMPLETE){
94 | chBSemSignal(&adc_cbsem);
95 | }
96 | }
97 |
98 | static void adcerrcallback(ADCDriver *adcp, adcerror_t err) {
99 | (void)adcp;
100 | (void)err;
101 | if (adcp->state == ADC_ERROR){
102 | sensors.error = ADC_CONV_ERROR;
103 | chBSemSignal(&adc_cbsem);
104 | }
105 | }
106 |
107 | /*
108 | * процесс опроса датчиков АЦП
109 | */
110 | static Thread *ADCThread_p;
111 | WORKING_AREA(waADCThread, 128);
112 | __attribute__((noreturn))
113 | msg_t ADCThread(void *arg) {
114 | chRegSetThreadName("ADCThd");
115 | chBSemInit(&adcsem,FALSE);
116 | chBSemInit(&adc_cbsem,TRUE);
117 |
118 | (void)arg;
119 | while (TRUE) {
120 | adc_read_t *req;
121 | Thread *tp;
122 |
123 | tp = chMsgWait();
124 | req = (adc_read_t *) chMsgGet(tp);
125 | chMsgRelease(tp, (msg_t) req);
126 |
127 | req->error = ADC_NO_ERROR;
128 | chBSemReset(&adc_cbsem,TRUE);
129 | adcStartConversion(&ADCD1, &adcgrpcfg, samples, 1);
130 | if (chBSemWaitTimeout(&adc_cbsem, MS2ST(ADC_TIMEOUT_MS)) == RDY_TIMEOUT){
131 | req->error = ADC_TIMEOUT;
132 | }
133 | if (req->error == ADC_NO_ERROR) {
134 | // датчик напряжения аккумулятора
135 | req->sensor[BATTSENSOR].value = samples[BATTSENSOR];
136 | // остальные датчики
137 | for (uint8_t i = 0; i < SENSORSNUM; i++){
138 | req->sensor[i].value = samples[i];
139 | }
140 | }
141 | chBSemSignal(&adcsem);
142 | }
143 | }
144 |
145 | /*
146 | * Initializes the ADC driver 1.
147 | */
148 | void sensors_init(void){
149 |
150 | adcStart(&ADCD1, NULL);
151 | palSetPadMode(GPIOB, GPIOB_PIN0, PAL_MODE_INPUT_ANALOG); // 00: PB.00 -> ADC1 channel 8
152 | // palSetPadMode(GPIOB, GPIOB_PIN1, PAL_MODE_INPUT_ANALOG); // 01: PB.01 -> ADC1 channel 9
153 |
154 | sensors.sensor[BATTSENSOR].type = 2;
155 | for (uint8_t i = 0; i < SENSORSNUM; i++){
156 | sensors.sensor[i].type = 0;
157 | }
158 |
159 | ADCThread_p = chThdCreateStatic(waADCThread, sizeof(waADCThread), ADC_PRIO, ADCThread, NULL);
160 | }
161 |
162 | adc_error_t sensors_read(void) {
163 | adc_read_t *adc_read_p = &sensors;
164 |
165 | chBSemWait(&adcsem); /* to be sure */
166 |
167 | chMsgSend(ADCThread_p, (msg_t) adc_read_p);
168 |
169 | /* wait for reply */
170 | if(chBSemWaitTimeout(&adcsem, MS2ST(ADC_TIMEOUT_MS)) == RDY_TIMEOUT) {
171 | adc_read_p->error = ADC_TIMEOUT;
172 | return ADC_TIMEOUT;
173 | }
174 | chBSemReset(&adcsem, FALSE);
175 | if (adc_read_p->error == ADC_CONV_ERROR){
176 | return ADC_CONV_ERROR;
177 | }
178 | adc_read_p->error = ADC_NO_ERROR;
179 | return ADC_NO_ERROR;
180 | }
181 |
--------------------------------------------------------------------------------
/sensors.h:
--------------------------------------------------------------------------------
1 | /*
2 | * sensors.h
3 | */
4 | #ifndef SENSORS_H_
5 | #define SENSORS_H_
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif
9 |
10 | #include "ch.h"
11 | #include "hal.h"
12 |
13 | #define SENSORSNUM 0 // число внешних датчиков
14 | #define SENSORSALL 1 // общее число датчиков
15 | #define BATTSENSOR 0 // номер датчика контроля напряжения батареи PB.00
16 | #define ADC_TIMEOUT_MS 100 // задержка опроса датчиков, мсек
17 |
18 | // значения АЦП
19 | #define BATTERYNORMA 995 // значение "норма" для батареи > 3.1V
20 | #define BATTERYLOW 500 // значение для обнаружения низкого заряда батареи < 3V
21 |
22 | typedef enum {
23 | ADC_NO_ERROR,
24 | ADC_CONV_ERROR,
25 | ADC_TIMEOUT,
26 | } adc_error_t;
27 |
28 | // описание датчика
29 | typedef struct _sensor sensor_t;
30 | struct _sensor{
31 | uint8_t type; // тип датчика: 0 - не используется, 1 - датчик, 2 - контроль питания
32 | uint16_t value; // последнее значение считанное АЦП
33 | };
34 |
35 | typedef struct _adc_read_t adc_read_t;
36 | struct _adc_read_t {
37 | adc_error_t error; /* out */
38 | sensor_t sensor[SENSORSALL]; /* out */
39 | };
40 |
41 | #define ADC_PRIO NORMALPRIO
42 | extern adc_read_t sensors; // описание датчиков
43 |
44 | // инициализация АЦП
45 | void sensors_init(void);
46 | // чтение значений ADC
47 | adc_error_t sensors_read(void);
48 |
49 | #ifdef __cplusplus
50 | }
51 | #endif
52 | #endif /* SENSORS_H_ */
53 |
--------------------------------------------------------------------------------
/stm32f103c_mini.txt:
--------------------------------------------------------------------------------
1 | Configuration stm32f103c_mini
2 | Date 08/20/2013
3 | MCU STM32F103C(8-B)Tx
4 |
5 |
6 |
7 | PERIPHERALS MODES REMAP FUNCTIONS PINS
8 | SPI1 Full-Duplex-Master_With-NSS 0 SPI1_MISO PA6
9 | SPI1 Full-Duplex-Master_With-NSS 0 SPI1_MOSI PA7
10 | SPI1 Full-Duplex-Master_With-NSS 0 SPI1_NSS PA4
11 | SPI1 Full-Duplex-Master_With-NSS 0 SPI1_SCK PA5
12 | I2C1 I2C 0 I2C1_SCL PB6
13 | I2C1 I2C 0 I2C1_SDA PB7
14 | USART1 Half-duplex(single-wire-mode) 0 USART1_TX PA9
15 | USB USB_FS 0 USB_USBDM PA11
16 | USB USB_FS 0 USB_USBDP PA12
17 | TIM2 PWM_INPUT 1 TIM2_CH1 PA15
18 | TIM2 PWM_INPUT 1 TIM2_CH2 PB3
19 | ADC1 IN2 0 ADC1_IN2 PA2
20 | ADC1 IN3 0 ADC1_IN3 PA3
21 | ADC1 IN8 0 ADC1_IN8 PB0
22 | ADC1 IN9 0 ADC1_IN9 PB1
23 | SYS Serial-Wire 0 SYS_JTCK-SWCLK PA14
24 | SYS Serial-Wire 0 SYS_JTMS-SWDIO PA13
25 | SYS SYS-OSC32 0 SYS_OSC32_IN PC14-OSC32_IN
26 | SYS SYS-OSC32 0 SYS_OSC32_OUT PC15-OSC32_OUT
27 |
28 |
29 |
30 | POS PIN FUNCTION Used
31 | 10 PA15 TIM2_CH1 AM2302
32 | 11 PB3 TIM2_CH2 AM2302
33 | 12 PA2 USART2_TX Serial console
34 | 13 PA3 USART2_RX Serial console
35 | 14 PA4 SPI1_NSS NRF24L01+
36 | 15 PA5 SPI1_SCK NRF24L01+
37 | 16 PA6 SPI1_MISO NRF24L01+
38 | 17 PA7 SPI1_MOSI NRF24L01+
39 | 18 PB0 ADC1_IN8 Battery voltage
40 | 19 PB1 ADC1_IN9 NU
41 | 25 PB12 Output_Push-Pull NU
42 | 26 PB13 Output_Push-Pull Sensors power control
43 | 27 PB14 Input_Floating Stop mode switch
44 | 28 PB15 Output_Push-Pull State LED
45 | 30 PA9 USART1_TX 1-Wire driver
46 | 42 PB6 I2C1_SCL BH1750
47 | 43 PB7 I2C1_SDA BH1750
48 | 45 PB8 Output_Push-Pull NRF24L01+ CE
49 | 46 PB9 Input_Floating NRF24L01+ IRQ
50 |
--------------------------------------------------------------------------------
/util/floatp10.c:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------*/
2 | /* _floatp10() get the characteristic, mantissa and sign of a double */
3 | /* precision floating point number such that: */
4 | /* */
5 | /* 1 <= mantissa < 10 */
6 | /* - 308 <= characteristic <= 308 */
7 | /* */
8 | /* negative: false if positive */
9 | /* true if negative */
10 | /*---------------------------------------------------------------------------*/
11 | #include
12 | #include
13 |
14 | int _floatp10(double *fnum, uint_fast8_t *negative, int prec)
15 | {
16 | int i;
17 | int fpower = 0;
18 | int ipower = 256;
19 | int rpower = 256;
20 | double fround = 0.5;
21 |
22 | static double const pfpower[] =
23 | {
24 | 1.0e+256,
25 | 1.0e+128,
26 | 1.0e+64,
27 | 1.0e+32,
28 | 1.0e+16,
29 | 1.0e+8,
30 | 1.0e+4,
31 | 1.0e+2,
32 | 1.0e+1
33 | };
34 |
35 | static double const nfpower[] =
36 | {
37 | 1.0e-256,
38 | 1.0e-128,
39 | 1.0e-64,
40 | 1.0e-32,
41 | 1.0e-16,
42 | 1.0e-8,
43 | 1.0e-4,
44 | 1.0e-2,
45 | 1.0e-1
46 | };
47 |
48 | *negative = *fnum < (double)0;
49 |
50 | if(*fnum != 0.0)
51 | {
52 | if(prec > 0)
53 | {
54 | if(prec < 309)
55 | {
56 | for(i = 0; i < 9; i++)
57 | {
58 | if(prec >= rpower)
59 | {
60 | fround /= pfpower[i];
61 | prec -= rpower;
62 | }
63 | rpower >>= 1;
64 | }
65 | }
66 | else
67 | fround = (double)0;
68 | }
69 | else if(prec < 0)
70 | {
71 | if(prec > -310)
72 | {
73 | fround = (double)5;
74 | for(i = 0; i < 9; i++)
75 | {
76 | if(prec >= rpower)
77 | {
78 | fround *= pfpower[i];
79 | prec += rpower;
80 | }
81 | rpower >>= 1;
82 | }
83 | }
84 | else
85 | fround = (double)0;
86 | }
87 | *fnum = fabs(*fnum) + fround;
88 | if(*fnum < (double)1)
89 | {
90 | for(i = 0; i < 9; i++)
91 | {
92 | if(*fnum <= nfpower[i])
93 | {
94 | *fnum *= pfpower[i];
95 | fpower -= ipower;
96 | }
97 | ipower >>= 1;
98 | }
99 | }
100 | else if(*fnum >= (double)10)
101 | {
102 | for(i = 0; i < 9; i++)
103 | {
104 | if(*fnum >= pfpower[i])
105 | {
106 | *fnum /= pfpower[i];
107 | fpower += ipower;
108 | }
109 | ipower >>= 1;
110 | }
111 | }
112 | if(*fnum < (double)1)
113 | {
114 | *fnum *= pfpower[8];
115 | fpower--;
116 | }
117 | }
118 | return fpower;
119 | }
120 |
--------------------------------------------------------------------------------
/util/itoa.c:
--------------------------------------------------------------------------------
1 | /*******************************************************
2 | * Code contributed by Chris Takahashi, *
3 | * ctakahashi (at) users (dot) sourceforge (dot) net. *
4 | * See stdlib.h for licence. *
5 | * $Date: 2005/08/31 11:39:47 $ *
6 | *******************************************************/
7 | #include
8 |
9 | char *itoa(int num, char *str, int radix)
10 | {
11 | char sign = 0;
12 | char temp[33]; //an int can only be 32 bits long
13 | //at radix 2 (binary) the string
14 | //is at most 16 + 1 null long.
15 | int temp_loc = 0;
16 | int digit;
17 | int str_loc = 0;
18 |
19 | //save sign for radix 10 conversion
20 | if (radix == 10 && num < 0) {
21 | sign = 1;
22 | num = -num;
23 | }
24 | unsigned int Tmp = num;
25 | //construct a backward string of the number.
26 | do {
27 | digit = Tmp % radix;
28 | Tmp = Tmp / radix;
29 | if (digit < 10)
30 | temp[temp_loc++] = digit + '0';
31 | else
32 | temp[temp_loc++] = digit - 10 + 'A';
33 | } while (Tmp > 0);
34 |
35 | //now add the sign for radix 10
36 | if (radix == 10 && sign) {
37 | temp[temp_loc] = '-';
38 | } else {
39 | temp_loc--;
40 | }
41 |
42 |
43 | //now reverse the string.
44 | while ( temp_loc >=0 ) {// while there are still chars
45 | str[str_loc++] = temp[temp_loc--];
46 | }
47 | str[str_loc] = 0; // add null termination.
48 |
49 | return str;
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/util/printfs.c:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------------------------*/
2 | /* _printfs() - print formatted data to a file or a string */
3 | /*---------------------------------------------------------------------------*/
4 | #include
5 | #define HUGE_VAL 1e256
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #ifdef __STDC__
13 | #include
14 | #else
15 | #include
16 | #endif
17 |
18 | #define POS_INFINITY "inf"
19 | #define NEG_INFINITY "-inf"
20 |
21 | #define _FLOAT_ROUND_ADJUST (double)5e-15
22 |
23 |
24 | int vsprintf(char *string, const char *format, va_list ap);
25 | int sprintf(char *buffer, char const *format, ...)
26 | {
27 | int Len;
28 | va_list ap;
29 | va_start(ap, format);
30 | Len = vsprintf(buffer, format, ap);
31 | va_end(ap);
32 | return Len;
33 | }
34 |
35 | extern int _floatp10(double *fnum, uint_fast8_t *negative, int prec);
36 |
37 | // as sizeof(int) == sizeof(long), 'l' specifier ignored
38 | char *itoa(int num, char *str, int radix);
39 | char *utoa(unsigned num, char *str, int radix);
40 |
41 | int vsprintf(char *string, char const *format, va_list ap)
42 | {
43 | char *output = string;
44 | char buffer[128];
45 | char *s;
46 | size_t width;
47 | uint_fast8_t prec;
48 | int fpower;
49 | uint_fast8_t negative;
50 | size_t padlen, zpadlen;
51 | double fnum;
52 |
53 | union
54 | {
55 | struct
56 | {
57 | uint_fast16_t left_justify:1; // %-
58 | uint_fast16_t show_sign:1; // %+
59 | uint_fast16_t zero_padding:1; // %0
60 | uint_fast16_t pad_sign:1; // %(space)
61 | uint_fast16_t alt:1; // %#
62 | uint_fast16_t uppercase:1; // %E%G%X / %e %g %x
63 | // uint_fast16_t long_val:1; // %l
64 |
65 | uint_fast16_t precision:1; // format string has precision field
66 | };
67 | uint_fast16_t raw;
68 | } flags;
69 |
70 | for(; *format; format++)
71 | {
72 | if(*format != '%')
73 | {
74 | *output++ = *format;
75 | }
76 | else
77 | {
78 | flags.raw = 0;
79 | width = 0;
80 | prec = 0;
81 | padlen = 0;
82 | zpadlen = 0;
83 | s = buffer;
84 |
85 | while(*++format)
86 | {
87 | switch(*format)
88 | {
89 | case '-':
90 | flags.left_justify = 1;
91 | continue;
92 | case '+':
93 | flags.show_sign = 1;
94 | continue;
95 | case '0':
96 | flags.zero_padding = 1;
97 | continue;
98 | case ' ':
99 | flags.pad_sign = 1;
100 | continue;
101 | case '#':
102 | flags.alt = 1;
103 | continue;
104 | default:
105 | break;
106 | }
107 | break;
108 | }
109 | if(*format == '*')
110 | {
111 | width = va_arg(ap, int);
112 | format++;
113 | }
114 | else
115 | {
116 | while(isdigit(*format))
117 | {
118 | width = (width * 10) + (*format - '0');
119 | format++;
120 | }
121 | }
122 | if(*format == '.')
123 | {
124 | format++;
125 | if(*format == '*')
126 | {
127 | prec = va_arg(ap, unsigned int);
128 | flags.precision = 1;
129 | format++;
130 | }
131 | else
132 | {
133 | while(isdigit(*format))
134 | {
135 | flags.precision = 1;
136 | prec = (prec * 10) + (*format - '0');
137 | format++;
138 | }
139 | }
140 | }
141 | if(*format == 'l')
142 | {
143 | // flags.long_val = 1;
144 | format++;
145 | }
146 | if(strchr("feEgG", *format))
147 | {
148 | if(fnum == HUGE_VAL)
149 | {
150 | strcpy(s, POS_INFINITY);
151 | flags.zero_padding = 0;
152 | flags.precision = 0;
153 | goto overflow;
154 | }
155 | else if(fnum == -HUGE_VAL)
156 | {
157 | strcpy(s, NEG_INFINITY);
158 | flags.zero_padding = 0;
159 | flags.precision = 0;
160 | goto overflow;
161 | }
162 | }
163 | switch(*format)
164 | {
165 | case 'c':
166 | *output++ = (char)va_arg(ap, int);
167 | continue;
168 | case 'd':
169 | case 'i':
170 | // if(flags.long_val)
171 | // ltoa(va_arg(ap, long), buffer, 10);
172 | // else
173 | itoa(va_arg(ap, int), buffer, 10);
174 | flags.alt = 0;
175 | break;
176 | case 'G':
177 | flags.uppercase = 1;
178 | case 'g':
179 | fnum = va_arg(ap, double);
180 | if(!flags.precision)
181 | prec = 6;
182 | {
183 | double sfnum = fnum;
184 | fpower = _floatp10(&sfnum, &negative, -999);
185 | sfnum = fnum;
186 | fpower = _floatp10(&sfnum, &negative, prec - fpower);
187 | if((fnum != 0.0) && ((fpower < -4) || (fpower >= (int)prec)))
188 | {
189 | fnum = sfnum;
190 | goto format_Ee;
191 | }
192 | }
193 | prec -= (fpower + 1);
194 | if((int)prec <= 0)
195 | prec = 1;
196 | goto format_f;
197 |
198 | case 'E':
199 | flags.uppercase = 1;
200 | case 'e':
201 | fnum = va_arg(ap, double);
202 | if(!flags.precision)
203 | prec = 6;
204 | {
205 | double sfnum = fnum;
206 | fpower = _floatp10(&sfnum, &negative, -999);
207 | fpower = _floatp10(&fnum, &negative, prec - fpower);
208 | }
209 | format_Ee:
210 | if(negative)
211 | *s++ = '-';
212 | {
213 | int fdigit = (int)fnum;
214 | *s++ = (char)(fdigit + '0');
215 | fnum -= (double)fdigit;
216 | }
217 | fnum *= 10.0;
218 | fnum += _FLOAT_ROUND_ADJUST;
219 | if(flags.alt || prec)
220 | {
221 | flags.precision = 0;
222 | *s++ = '.';
223 | uint_fast8_t fprec = 0;
224 | while(prec)
225 | {
226 | if(fprec < 16)
227 | {
228 | int fdigit = (int)fnum;
229 | *s++ = (char)(fdigit + '0');
230 | fnum -= (double)fdigit;
231 | fnum *= 10.0;
232 | fnum += _FLOAT_ROUND_ADJUST;
233 | fprec++;
234 | }
235 | else
236 | {
237 | *s++ = '0';
238 | }
239 | prec--;
240 | }
241 | }
242 | *s = flags.uppercase ? 'E' : 'e';
243 | if(fpower >= 0)
244 | {
245 | *s++ = '+';
246 | }
247 | else
248 | {
249 | *s++ = '-';
250 | fpower = -fpower;
251 | }
252 | if(fpower < 10)
253 | *s++ = '0';
254 | itoa(fpower, s, 10);
255 | s = buffer;
256 | break;
257 | case 'f':
258 | fnum = va_arg(ap, double);
259 | if(!flags.precision)
260 | prec = 6;
261 | format_f:
262 | fpower = _floatp10(&fnum, &negative, prec);
263 | if(negative)
264 | *s++ = '-';
265 | if(fpower < 0)
266 | {
267 | *s++ = '0';
268 | fpower++;
269 | }
270 | else
271 | {
272 | uint_fast8_t fprec = 0;
273 | while(fpower >= 0)
274 | {
275 | if(fprec < 16)
276 | {
277 | int fdigit = (int)fnum;
278 | *s++ = (char)(fdigit + '0');
279 | fnum -= (double)fdigit;
280 | fnum *= 10.0;
281 | fnum += _FLOAT_ROUND_ADJUST;
282 | fprec++;
283 | }
284 | else
285 | {
286 | *s++ = '0';
287 | }
288 | fpower--;
289 | }
290 | fpower = 0;
291 | }
292 | if(flags.alt || prec)
293 | {
294 | flags.precision = 0;
295 | *s++ = '.';
296 | uint_fast8_t fprec = 0;
297 | while(prec)
298 | {
299 | if(fpower < 0)
300 | {
301 | *s++ = '0';
302 | fpower++;
303 | }
304 | else
305 | {
306 | if(fprec < 16)
307 | {
308 | int fdigit = (int)fnum;
309 | *s++ = (char)(fdigit + '0');
310 |
311 | fnum -= (double)fdigit;
312 | fnum *= 10.0;
313 | fnum += _FLOAT_ROUND_ADJUST;
314 | fprec++;
315 | }
316 | else
317 | {
318 | *s++ = '0';
319 | }
320 | }
321 | prec--;
322 | }
323 | }
324 | *s = '\0';
325 | s = buffer;
326 | break;
327 | case 'n':
328 | *va_arg(ap, int *) = output - string;
329 | continue;
330 |
331 | case 'o':
332 | if(flags.alt)
333 | *s++ = '0';
334 | // if(flags.long_val)
335 | // ultoa(va_arg(ap, unsigned long), s, 8);
336 | // else
337 | utoa(va_arg(ap, unsigned int), s, 8);
338 | s = buffer;
339 | break;
340 |
341 | case 'p':
342 | strupr(utoa((uintptr_t)va_arg(ap, void *), s, 16));
343 | break;
344 |
345 | case 's':
346 | s = va_arg(ap, char *);
347 | flags.show_sign = 0;
348 | flags.zero_padding = 0;
349 | flags.pad_sign = 0;
350 | break;
351 |
352 | case 'u':
353 | // if(flags.long_val)
354 | // ultoa(va_arg(ap, unsigned long), s, 10);
355 | // else
356 | utoa(va_arg(ap, unsigned int), s, 10);
357 | break;
358 |
359 | case 'x':
360 | case 'X':
361 | s = buffer;
362 | if(flags.alt)
363 | {
364 | *s++ = '0';
365 | *s++ = *format;
366 | }
367 | // if(flags.long_val)
368 | // ultoa(va_arg(ap, unsigned long), s, 16);
369 | // else
370 | utoa(va_arg(ap, unsigned int), s, 16);
371 | if(*format == 'X')
372 | strupr(s);
373 | s = buffer;
374 | break;
375 | default:
376 | *output++ = *format;
377 | continue;
378 | }
379 | overflow:
380 | {
381 | size_t ssize = strlen(s);
382 | size_t dsize = ssize;
383 | char schar = '\0';
384 | size_t maxlen = -1;
385 |
386 | if(flags.left_justify)
387 | flags.zero_padding = 0;
388 | if(*format == 's')
389 | {
390 | if(flags.precision)
391 | {
392 | flags.precision = 0;
393 | maxlen = prec;
394 | }
395 | }
396 | else
397 | {
398 | if(ssize == 1 && *s == '0')
399 | {
400 | if(flags.precision && prec == 0)
401 | {
402 | *s = '\0';
403 | ssize = 0;
404 | dsize = 0;
405 | }
406 | }
407 | if(*format == 'o' && flags.alt && prec < ssize) //????????
408 | {
409 | flags.precision = 1;
410 | prec = ssize + 1;
411 | }
412 | if(*s == '-')
413 | {
414 | s++;
415 | schar = '-';
416 | dsize--;
417 | }
418 | else if(flags.show_sign)
419 | {
420 | schar = '+';
421 | ssize++;
422 | }
423 | else if(flags.pad_sign)
424 | {
425 | schar = ' ';
426 | ssize++;
427 | }
428 | }
429 | if(width > ssize)
430 | {
431 | if(flags.precision && (prec > dsize))
432 | {
433 | padlen = width - (ssize + (prec - dsize));
434 | }
435 | else
436 | {
437 | padlen = width - ssize;
438 | }
439 | }
440 | if(flags.precision && (prec > dsize))
441 | {
442 | zpadlen = prec - dsize;
443 | }
444 | else if(flags.zero_padding)
445 | {
446 | zpadlen = padlen;
447 | padlen = 0;
448 | }
449 | while(!flags.left_justify && (padlen > 0))
450 | {
451 | *output++ = ' ';
452 | padlen--;
453 | }
454 |
455 | if(schar)
456 | {
457 | *output++ = schar;
458 | }
459 |
460 | while(zpadlen > 0)
461 | {
462 | *output++ = '0';
463 | zpadlen--;
464 | }
465 | while(*s)
466 | {
467 | if(maxlen != (size_t)-1)
468 | {
469 | if(!(maxlen--)) break;
470 | }
471 | *output++ = *s++;
472 | }
473 |
474 | while(flags.left_justify && (padlen > 0))
475 | {
476 | *output++ = ' ';
477 | padlen--;
478 | }
479 | }
480 | }
481 | }
482 | *output = '\0';
483 | return(output - string);
484 | }
485 |
--------------------------------------------------------------------------------
/util/printfs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * printfs.h
3 | *
4 | * Created on: 17.01.2014
5 | * Author: andru
6 | */
7 |
8 | #ifndef PRINTFS_H_
9 | #define PRINTFS_H_
10 |
11 | int sprintf(char *buffer, char const *format, ...);
12 |
13 | #endif /* PRINTFS_H_ */
14 |
--------------------------------------------------------------------------------
/util/utoa.c:
--------------------------------------------------------------------------------
1 | /*******************************************************
2 | * Code contributed by Chris Takahashi, *
3 | * ctakahashi (at) users (dot) sourceforge (dot) net. *
4 | * See stdlib.h for licence. *
5 | * $Date: 2005/08/31 11:39:47 $ *
6 | *******************************************************/
7 | #include
8 |
9 | char *utoa(unsigned long num, char *str, int radix) {
10 | char temp[33]; //an int can only be 16 bits long
11 | //at radix 2 (binary) the string
12 | //is at most 16 + 1 null long.
13 | int temp_loc = 0;
14 | int digit;
15 | int str_loc = 0;
16 |
17 | //construct a backward string of the number.
18 | do {
19 | digit = num % radix;
20 | num = num / radix;
21 | if (digit < 10)
22 | temp[temp_loc++] = digit + '0';
23 | else
24 | temp[temp_loc++] = digit - 10 + 'A';
25 | } while (num > 0);
26 |
27 | temp_loc--;
28 |
29 |
30 | //now reverse the string.
31 | while ( temp_loc >=0 ) {// while there are still chars
32 | str[str_loc++] = temp[temp_loc--];
33 | }
34 | str[str_loc] = 0; // add null termination.
35 |
36 | return str;
37 | }
38 |
39 |
--------------------------------------------------------------------------------