├── .gitignore
├── stm32f429zi_flash.ld
├── LICENSE
├── libs
├── r3dfb-stm32f429-discovery
│ ├── r3dfb.h
│ └── r3dfb.c
└── r3d
│ ├── r3d.h
│ ├── r3d.c
│ └── r3d_math.h
├── README.md
├── stm32f4xx_it.h
├── stm32f4xx_conf.h
├── Makefile
├── stm32f4xx_it.c
├── main.c
├── system_stm32f4xx.c
├── startup_stm32f429_439xx.S
└── examples
└── textures
└── nyan.h
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.bin
3 | *.elf
4 | *.hex
5 | *.lst
6 |
--------------------------------------------------------------------------------
/stm32f429zi_flash.ld:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jserv/stm32f429-r3d/HEAD/stm32f429zi_flash.ld
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | /*
2 | * ----------------------------------------------------------------------------
3 | * "THE CLUB-MATE-WARE LICENSE" (Revision 23):
4 | * ands wrote this file.
5 | * It is based on THE BEER-WARE LICENSE (Revision 42) by Poul-Henning Kamp.
6 | * As long as you retain this notice you can do whatever you want with this
7 | * stuff. If we meet some day, and you think this stuff is worth it, you can
8 | * buy us a club-mate in return
9 | * ----------------------------------------------------------------------------
10 | */
11 |
--------------------------------------------------------------------------------
/libs/r3dfb-stm32f429-discovery/r3dfb.h:
--------------------------------------------------------------------------------
1 | /**
2 | * r3dfb -- 3D rendering library framebuffer for STM32F429-DISCOVERY
3 | * author: Andreas Mantler (ands)
4 | */
5 |
6 | #ifndef R3DFB_H
7 | #define R3DFB_H
8 |
9 | #define R3DFB_PIXEL_WIDTH ((uint16_t) 240)
10 | #define R3DFB_PIXEL_HEIGHT ((uint16_t) 320)
11 |
12 | #define R3DFB_COLOR_BUFFER_SIZE (R3DFB_PIXEL_WIDTH * R3DFB_PIXEL_HEIGHT * sizeof(uint16_t))
13 | #define R3DFB_DEPTH_BUFFER_SIZE (R3DFB_PIXEL_WIDTH * R3DFB_PIXEL_HEIGHT * sizeof(uint16_t))
14 |
15 | #define R3DFB_BUFFER_OFFSET ((uint32_t) 0x50000)
16 | #define R3DFB_BUFFER0 ((uint32_t) 0xD0000000)
17 | #define R3DFB_BUFFER1 (R3DFB_BUFFER0 + R3DFB_BUFFER_OFFSET)
18 | #define R3DFB_DEPTH_BUFFER (R3DFB_BUFFER1 + R3DFB_BUFFER_OFFSET)
19 |
20 | void r3dfb_init(void);
21 | void r3dfb_clear(void); // clears color back buffer and depth buffer
22 | void r3dfb_swap_buffers(void); // swaps back and front color buffers
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Introduction
2 | ============
3 | A small software 3D rendering program on the STM32F429 Discovery evaluation
4 | board. Based on Andreas Mantler's work.
5 |
6 | Build Instructions
7 | ==================
8 | Because the STM32F429 Discovery is relatively new, we would recommend to
9 | prepare several recent utilities:
10 |
11 | * [OpenOCD](http://openocd.sourceforge.net/)
12 | ```
13 | git clone git://git.code.sf.net/p/openocd/code openocd
14 | cd openocd
15 | ./bootstrap
16 | ./configure --prefix=/usr/local \
17 | --enable-stlink
18 | echo -e "all:\ninstall:" > doc/Makefile
19 | make
20 | sudo make install
21 | ```
22 | * [GNU Tools for ARM Embedded Processors](https://launchpad.net/gcc-arm-embedded)
23 | ```
24 | apt-get install gcc-arm-none-eabi
25 | ```
26 | If you encounter the problems of missing packages, try to execute the
27 | following commands in advance:
28 | ```
29 | sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded
30 | sudo apt-get update
31 | ```
32 |
33 | In addition, you need to download [STM32F429I-Discovery firmware](http://www.st.com/web/en/catalog/tools/PF259429)
34 | and extract it to the toplevel directory where `stm32f429-r3d` exists.
35 |
36 | ```
37 | unzip stsw-stm32138.zip
38 | ```
39 |
40 | Then, get the latest source from GitHub and then build:
41 | ```
42 | git clone https://github.com/jserv/stm32f429-r3d
43 | cd stm32f429-r3d
44 | make
45 | ```
46 |
47 | Please confirm STM32F429 Discovery is properly connected to USB, and let's flash the device:
48 | ```
49 | make flash
50 | ```
51 |
52 | Be patient when OpenOCD is flashing.
53 |
--------------------------------------------------------------------------------
/stm32f4xx_it.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file Touch_Panel/stm32f4xx_it.h
4 | * @author MCD Application Team
5 | * @version V1.0.1
6 | * @date 11-November-2013
7 | * @brief This file contains the headers of the interrupt handlers.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | *
© COPYRIGHT 2013 STMicroelectronics
12 | *
13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
14 | * You may not use this file except in compliance with the License.
15 | * You may obtain a copy of the License at:
16 | *
17 | * http://www.st.com/software_license_agreement_liberty_v2
18 | *
19 | * Unless required by applicable law or agreed to in writing, software
20 | * distributed under the License is distributed on an "AS IS" BASIS,
21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 | * See the License for the specific language governing permissions and
23 | * limitations under the License.
24 | *
25 | ******************************************************************************
26 | */
27 |
28 | /* Define to prevent recursive inclusion -------------------------------------*/
29 | #ifndef __STM32F4xx_IT_H
30 | #define __STM32F4xx_IT_H
31 |
32 | #ifdef __cplusplus
33 | extern "C" {
34 | #endif
35 |
36 | /* Includes ------------------------------------------------------------------*/
37 | /* Exported types ------------------------------------------------------------*/
38 | /* Exported constants --------------------------------------------------------*/
39 | /* Exported macro ------------------------------------------------------------*/
40 | /* Exported functions ------------------------------------------------------- */
41 |
42 | void NMI_Handler(void);
43 | void HardFault_Handler(void);
44 | void MemManage_Handler(void);
45 | void BusFault_Handler(void);
46 | void UsageFault_Handler(void);
47 | void SVC_Handler(void);
48 | void DebugMon_Handler(void);
49 | void PendSV_Handler(void);
50 | void SysTick_Handler(void);
51 |
52 | #ifdef __cplusplus
53 | }
54 | #endif
55 |
56 | #endif /* __STM32F4xx_IT_H */
57 |
58 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
59 |
--------------------------------------------------------------------------------
/libs/r3dfb-stm32f429-discovery/r3dfb.c:
--------------------------------------------------------------------------------
1 | /**
2 | * r3dfb -- 3D rendering library framebuffer for STM32F429-DISCOVERY
3 | * author: Andreas Mantler (ands)
4 | */
5 |
6 | #include "stm32f4xx.h"
7 | #include "stm32f429i_discovery.h"
8 | #include "stm32f429i_discovery_lcd.h"
9 | #include "r3d.h"
10 | #include "r3dfb.h"
11 |
12 | static uint32_t r3dfb_front_buffer = R3DFB_BUFFER0;
13 | static uint32_t r3dfb_back_buffer = R3DFB_BUFFER1;
14 |
15 | void r3dfb_init(void)
16 | {
17 | LCD_Init();
18 |
19 | LTDC_Layer_InitTypeDef LTDC_Layer_InitStruct;
20 | LTDC_Layer_InitStruct.LTDC_HorizontalStart = 30;
21 | LTDC_Layer_InitStruct.LTDC_HorizontalStop = (R3DFB_PIXEL_WIDTH + 30 - 1);
22 | LTDC_Layer_InitStruct.LTDC_VerticalStart = 4;
23 | LTDC_Layer_InitStruct.LTDC_VerticalStop = (R3DFB_PIXEL_HEIGHT + 4 - 1);
24 | LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_RGB565;
25 | LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 255;
26 | LTDC_Layer_InitStruct.LTDC_DefaultColorBlue = 0;
27 | LTDC_Layer_InitStruct.LTDC_DefaultColorGreen = 0;
28 | LTDC_Layer_InitStruct.LTDC_DefaultColorRed = 0;
29 | LTDC_Layer_InitStruct.LTDC_DefaultColorAlpha = 0;
30 | LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_CA;
31 | LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_CA;
32 | LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((R3DFB_PIXEL_WIDTH * 2) + 3);
33 | LTDC_Layer_InitStruct.LTDC_CFBPitch = (R3DFB_PIXEL_WIDTH * 2);
34 | LTDC_Layer_InitStruct.LTDC_CFBLineNumber = R3DFB_PIXEL_HEIGHT;
35 | LTDC_Layer_InitStruct.LTDC_CFBStartAdress = r3dfb_front_buffer;
36 | LTDC_LayerInit(LTDC_Layer1, <DC_Layer_InitStruct);
37 |
38 | LTDC_LayerCmd(LTDC_Layer1, ENABLE);
39 | LTDC_LayerCmd(LTDC_Layer2, DISABLE);
40 |
41 | LTDC_ReloadConfig(LTDC_IMReload);
42 |
43 | LTDC_Cmd(ENABLE);
44 | }
45 |
46 | void r3dfb_clear(void)
47 | {
48 | memset((void *) R3DFB_DEPTH_BUFFER, 0, R3DFB_DEPTH_BUFFER_SIZE);
49 | memset((void *) r3dfb_back_buffer, 0xff, R3DFB_COLOR_BUFFER_SIZE);
50 | }
51 |
52 | void r3dfb_swap_buffers(void)
53 | {
54 | uint32_t tmp = r3dfb_front_buffer;
55 | r3dfb_front_buffer = r3dfb_back_buffer;
56 | r3dfb_back_buffer = tmp;
57 |
58 | // hack for font rendering
59 | LCD_SetLayer(r3dfb_back_buffer == R3DFB_BUFFER0 ?
60 | LCD_BACKGROUND_LAYER : LCD_FOREGROUND_LAYER);
61 |
62 | LTDC_Cmd(DISABLE);
63 | LTDC_LayerAddress(LTDC_Layer1, r3dfb_front_buffer);
64 | LTDC_ReloadConfig(LTDC_IMReload);
65 | LTDC_Cmd(ENABLE);
66 | }
67 |
68 | // r3d interface
69 | void r3d_set_pixel(uint16_t x, uint16_t y, float z, vec3_t color)
70 | {
71 | // convert color to RGB565
72 | uint16_t c = ((uint16_t)(color.r * 63488.0f) & 63488) |
73 | ((uint16_t)(color.g * 2016.0f) & 2016) |
74 | ((uint16_t)(color.b * 31.0f) & 31);
75 | // set color + depth
76 | const uint32_t offset = 2 * (x + R3DFB_PIXEL_WIDTH * y);
77 | *(__IO uint16_t *) (r3dfb_back_buffer + offset) = c;
78 | *(__IO uint16_t *) (R3DFB_DEPTH_BUFFER + offset) = z * 65535.0f;
79 | }
80 |
81 | float r3d_get_depth(uint16_t x, uint16_t y)
82 | {
83 | const float uint16to1f = 1.0f / 65535.0f;
84 | const uint32_t offset = 2 * (x + R3DFB_PIXEL_WIDTH * y);
85 | return (*(__IO uint16_t *) (R3DFB_DEPTH_BUFFER + offset)) * uint16to1f;
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/libs/r3d/r3d.h:
--------------------------------------------------------------------------------
1 | /**
2 | * r3d -- 3D rendering library
3 | * author: Andreas Mantler (ands)
4 | */
5 |
6 | #ifndef R3D_H
7 | #define R3D_H
8 |
9 | #include
10 | #include
11 |
12 | /*****************************************************************************/
13 | // to configure by user:
14 |
15 | // number of float elements per vertex passed to/between shaders (at least 3)
16 | #define R3D_VERTEX_ELEMENTS_MAX 16
17 |
18 | // sets the maximum number for *_FAN vertices.
19 | // should be at least:
20 | // 6 if quads are used, ?
21 | // 4 if triangles are used,
22 | // 2 if lines are used or
23 | // 0 if only points are used
24 | #define R3D_PRIMITIVE_VERTEX_BUFFER 4
25 |
26 | // to implement:
27 | void r3d_set_pixel(uint16_t x, uint16_t y, float z, vec3_t color);
28 | float r3d_get_depth(uint16_t x, uint16_t y);
29 |
30 | // end of configuration section
31 | /*****************************************************************************/
32 |
33 | // types
34 | typedef uint8_t r3d_switch_t;
35 | #define R3D_DISABLE 0
36 | #define R3D_ENABLE 1
37 |
38 | typedef uint8_t r3d_primitive_winding_t;
39 | #define R3D_PRIMITIVE_WINDING_CW 0
40 | #define R3D_PRIMITIVE_WINDING_CCW 1
41 |
42 | typedef uint8_t r3d_primitive_type_t;
43 | #define R3D_PRIMITIVE_TYPE_POINTS 0x00
44 | #define R3D_PRIMITIVE_TYPE_LINES 0x01
45 | #define R3D_PRIMITIVE_TYPE_LINE_LOOP 0x02
46 | #define R3D_PRIMITIVE_TYPE_LINE_STRIP 0x03
47 | #define R3D_PRIMITIVE_TYPE_LINE_FAN 0x04
48 | #define R3D_PRIMITIVE_TYPE_TRIANGLES 0x05
49 | #define R3D_PRIMITIVE_TYPE_TRIANGLE_STRIP 0x06
50 | #define R3D_PRIMITIVE_TYPE_TRIANGLE_FAN 0x07
51 | //#define R3D_PRIMITIVE_TYPE_QUADS 0x08
52 | //#define R3D_PRIMITIVE_TYPE_QUAD_STRIP 0x09
53 | #define R3D_PRIMITIVE_TYPE_NUM 0x08 //0x0a
54 |
55 | typedef void (*r3d_vertexshader_func)(const void *in, float *out);
56 | typedef vec4_t (*r3d_fragmentshader_func)(const float *in);
57 | typedef struct {
58 | r3d_vertexshader_func vertexshader;
59 | r3d_fragmentshader_func fragmentshader;
60 | uint8_t vertex_out_elements; // number of floats passed from vs to fs
61 | } r3d_shader_t;
62 |
63 | typedef struct {
64 | r3d_primitive_type_t primitive_type;
65 | const void *vertices; // vertex buffer
66 | uint8_t stride; // vertex stride
67 | uint32_t count; // number of vertices/indices
68 | const uint16_t *indices; // index buffer
69 | } r3d_drawcall_t;
70 |
71 | typedef struct {
72 | uint16_t width;
73 | uint16_t height;
74 | uint16_t data[];
75 | } r3d_texture_t;
76 |
77 | // variables
78 | extern r3d_switch_t r3d_backface_culling;
79 | extern r3d_primitive_winding_t r3d_primitive_winding;
80 | extern r3d_shader_t r3d_shader;
81 |
82 | // functions
83 | void r3d_viewport(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
84 | void r3d_draw(const r3d_drawcall_t *drawcall);
85 |
86 | // texturing (inlined for speed)
87 | static inline vec3_t r3d_texture_nearest(const r3d_texture_t *texture, vec2_t uv)
88 | {
89 | int ui = (int)uv.x;
90 | int vi = (int)uv.y;
91 | if (uv.x < 0) ui--;
92 | if (uv.y < 0) vi--;
93 | uv.x -= ui;
94 | uv.y -= vi;
95 | uv.x *= texture->width - 1;
96 | uv.y *= texture->height - 1;
97 | ui = uv.x;
98 | vi = uv.y;
99 | uint16_t c = texture->data[vi * texture->width + ui];
100 | const float ri = 1.0f / 63488.0f, gi = 1.0f / 2016.0f, bi = 1.0f / 31.0f;
101 | return vec3((c & 63488) * ri, (c & 2016) * gi, (c & 31) * bi);
102 | }
103 |
104 | #endif
105 |
--------------------------------------------------------------------------------
/stm32f4xx_conf.h:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file Touch_Panel/stm32f4xx_conf.h
4 | * @author MCD Application Team
5 | * @version V1.0.1
6 | * @date 11-November-2013
7 | * @brief Library configuration file.
8 | ******************************************************************************
9 | * @attention
10 | *
11 | * © COPYRIGHT 2013 STMicroelectronics
12 | *
13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
14 | * You may not use this file except in compliance with the License.
15 | * You may obtain a copy of the License at:
16 | *
17 | * http://www.st.com/software_license_agreement_liberty_v2
18 | *
19 | * Unless required by applicable law or agreed to in writing, software
20 | * distributed under the License is distributed on an "AS IS" BASIS,
21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 | * See the License for the specific language governing permissions and
23 | * limitations under the License.
24 | *
25 | ******************************************************************************
26 | */
27 |
28 | /* Define to prevent recursive inclusion -------------------------------------*/
29 | #ifndef __STM32F4xx_CONF_H
30 | #define __STM32F4xx_CONF_H
31 |
32 | #if defined (HSE_VALUE)
33 | /* Redefine the HSE value; it's equal to 8 MHz on the STM32F429I-DISCO Kit */
34 | #undef HSE_VALUE
35 | #define HSE_VALUE ((uint32_t)8000000)
36 | #endif /* HSE_VALUE */
37 |
38 | /* Includes ------------------------------------------------------------------*/
39 | /* Uncomment the line below to enable peripheral header file inclusion */
40 | #include "stm32f4xx_adc.h"
41 | #include "stm32f4xx_can.h"
42 | #include "stm32f4xx_crc.h"
43 | #include "stm32f4xx_cryp.h"
44 | #include "stm32f4xx_dac.h"
45 | #include "stm32f4xx_dbgmcu.h"
46 | #include "stm32f4xx_dcmi.h"
47 | #include "stm32f4xx_dma.h"
48 | #include "stm32f4xx_exti.h"
49 | #include "stm32f4xx_flash.h"
50 | #include "stm32f4xx_ltdc.h"
51 | #include "stm32f4xx_dma2d.h"
52 | #include "stm32f4xx_fmc.h"
53 | #include "stm32f4xx_hash.h"
54 | #include "stm32f4xx_gpio.h"
55 | #include "stm32f4xx_i2c.h"
56 | #include "stm32f4xx_iwdg.h"
57 | #include "stm32f4xx_pwr.h"
58 | #include "stm32f4xx_rcc.h"
59 | #include "stm32f4xx_rng.h"
60 | #include "stm32f4xx_rtc.h"
61 | #include "stm32f4xx_sdio.h"
62 | #include "stm32f4xx_spi.h"
63 | #include "stm32f4xx_syscfg.h"
64 | #include "stm32f4xx_tim.h"
65 | #include "stm32f4xx_usart.h"
66 | #include "stm32f4xx_wwdg.h"
67 | #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
68 |
69 | /* Exported types ------------------------------------------------------------*/
70 | /* Exported constants --------------------------------------------------------*/
71 |
72 | /* If an external clock source is used, then the value of the following define
73 | should be set to the value of the external clock source, else, if no external
74 | clock is used, keep this define commented */
75 | /*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */
76 |
77 |
78 | /* Uncomment the line below to expanse the "assert_param" macro in the
79 | Standard Peripheral Library drivers code */
80 | /* #define USE_FULL_ASSERT 1 */
81 |
82 | /* Exported macro ------------------------------------------------------------*/
83 | #ifdef USE_FULL_ASSERT
84 |
85 | /**
86 | * @brief The assert_param macro is used for function's parameters check.
87 | * @param expr: If expr is false, it calls assert_failed function
88 | * which reports the name of the source file and the source
89 | * line number of the call that failed.
90 | * If expr is true, it returns no value.
91 | * @retval None
92 | */
93 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
94 | /* Exported functions ------------------------------------------------------- */
95 | void assert_failed(uint8_t* file, uint32_t line);
96 | #else
97 | #define assert_param(expr) ((void)0)
98 | #endif /* USE_FULL_ASSERT */
99 |
100 | #endif /* __STM32F4xx_CONF_H */
101 |
102 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
103 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PROJECT = r3d
2 |
3 | EXECUTABLE = $(PROJECT).elf
4 | BIN_IMAGE = $(PROJECT).bin
5 | HEX_IMAGE = $(PROJECT).hex
6 |
7 | # set the path to STM32F429I-Discovery firmware package
8 | STDP ?= ../STM32F429I-Discovery_FW_V1.0.1
9 |
10 | # Toolchain configurations
11 | CROSS_COMPILE ?= arm-none-eabi-
12 | CC = $(CROSS_COMPILE)gcc
13 | LD = $(CROSS_COMPILE)ld
14 | OBJCOPY = $(CROSS_COMPILE)objcopy
15 | OBJDUMP = $(CROSS_COMPILE)objdump
16 | SIZE = $(CROSS_COMPILE)size
17 |
18 | # Cortex-M4 implements the ARMv7E-M architecture
19 | CPU = cortex-m4
20 | CFLAGS = -mcpu=$(CPU) -march=armv7e-m -mtune=cortex-m4
21 | CFLAGS += -mlittle-endian -mthumb
22 | # FPU
23 | CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard
24 |
25 | LDFLAGS =
26 | define get_library_path
27 | $(shell dirname $(shell $(CC) $(CFLAGS) -print-file-name=$(1)))
28 | endef
29 | LDFLAGS += -L $(call get_library_path,libc.a)
30 | LDFLAGS += -L $(call get_library_path,libgcc.a)
31 |
32 | # Basic configurations
33 | CFLAGS += -g -std=c99
34 | CFLAGS += -Wall
35 |
36 | # Optimizations
37 | CFLAGS += -O3 -ffast-math
38 | CFLAGS += -ffunction-sections -fdata-sections
39 | CFLAGS += -Wl,--gc-sections
40 | CFLAGS += -fno-common
41 | CFLAGS += --param max-inline-insns-single=1000
42 |
43 | # FPU
44 | CFLAGS += -DARM_MATH_CM4 -D__FPU_PRESENT
45 |
46 | # specify STM32F429
47 | CFLAGS += -DSTM32F429_439xx
48 |
49 | # to run from FLASH
50 | CFLAGS += -DVECT_TAB_FLASH
51 | LDFLAGS += -T stm32f429zi_flash.ld
52 |
53 | # project starts here
54 | CFLAGS += -I.
55 | OBJS = \
56 | main.o \
57 | stm32f4xx_it.o \
58 | system_stm32f4xx.o
59 |
60 | # LIB r3d
61 | CFLAGS += -I libs/r3d/
62 | OBJS += libs/r3d/r3d.o
63 |
64 | # LIB r3dfb
65 | CFLAGS += -I libs/r3dfb-stm32f429-discovery/
66 | OBJS += libs/r3dfb-stm32f429-discovery/r3dfb.o
67 |
68 | # example data
69 | CFLAGS += -I examples/meshes/
70 | CFLAGS += -I examples/textures/
71 | # L3GD20 default callback
72 | # CFLAGS += -DUSE_DEFAULT_TIMEOUT_CALLBACK
73 |
74 | # STARTUP FILE
75 | OBJS += startup_stm32f429_439xx.o
76 |
77 | # CMSIS
78 | CFLAGS += -I$(STDP)/Libraries/CMSIS/Device/ST/STM32F4xx/Include
79 | CFLAGS += -I$(STDP)/Libraries/CMSIS/Include
80 | LIBS += $(STDP)/Libraries/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a
81 |
82 | # STemWinLibrary522_4x9i
83 | CFLAGS += -I$(STDP)/Libraries/STemWinLibrary522_4x9i/inc
84 | LIBS += \
85 | $(STDP)/Libraries/STemWinLibrary522_4x9i/Lib/STemWin522_4x9i_CM4_OS_GCC.a
86 |
87 | # STM32F4xx_StdPeriph_Driver
88 | CFLAGS += -DUSE_STDPERIPH_DRIVER
89 | CFLAGS += -I$(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/inc
90 | CFLAGS += -D"assert_param(expr)=((void)0)"
91 | OBJS += \
92 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/misc.o \
93 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma2d.o \
94 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.o \
95 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.o \
96 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.o \
97 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fmc.o \
98 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.o \
99 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_i2c.o \
100 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_ltdc.o \
101 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.o \
102 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.o \
103 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.o \
104 | $(STDP)/Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.o
105 |
106 | # STM32F429I-Discovery Utilities
107 | CFLAGS += -I$(STDP)/Utilities/STM32F429I-Discovery
108 | OBJS += $(STDP)/Utilities/STM32F429I-Discovery/stm32f429i_discovery.o
109 | OBJS += $(STDP)/Utilities/STM32F429I-Discovery/stm32f429i_discovery_l3gd20.o
110 | OBJS += $(STDP)/Utilities/STM32F429I-Discovery/stm32f429i_discovery_lcd.o
111 | OBJS += $(STDP)/Utilities/STM32F429I-Discovery/stm32f429i_discovery_sdram.o
112 |
113 | all: $(BIN_IMAGE)
114 |
115 | $(BIN_IMAGE): $(EXECUTABLE)
116 | $(OBJCOPY) -O binary $^ $@
117 | $(OBJCOPY) -O ihex $^ $(HEX_IMAGE)
118 | $(OBJDUMP) -h -S -D $(EXECUTABLE) > $(PROJECT).lst
119 | $(SIZE) $(EXECUTABLE)
120 |
121 | $(EXECUTABLE): $(OBJS)
122 | $(LD) -o $@ $(OBJS) \
123 | --start-group $(LIBS) --end-group \
124 | $(LDFLAGS)
125 |
126 | %.o: %.c
127 | $(CC) $(CFLAGS) -c $< -o $@
128 |
129 | %.o: %.S
130 | $(CC) $(CFLAGS) -c $< -o $@
131 |
132 | clean:
133 | rm -rf $(EXECUTABLE)
134 | rm -rf $(BIN_IMAGE)
135 | rm -rf $(HEX_IMAGE)
136 | rm -f $(OBJS)
137 | rm -f $(PROJECT).lst
138 |
139 | flash:
140 | openocd -f interface/stlink-v2.cfg \
141 | -f target/stm32f4x_stlink.cfg \
142 | -c "init" \
143 | -c "reset init" \
144 | -c "halt" \
145 | -c "flash write_image erase $(PROJECT).elf" \
146 | -c "verify_image $(PROJECT).elf" \
147 | -c "reset run" -c shutdown || \
148 | st-flash write $(BIN_IMAGE) 0x8000000
149 |
150 | .PHONY: clean
151 |
--------------------------------------------------------------------------------
/stm32f4xx_it.c:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file Touch_Panel/stm32f4xx_it.c
4 | * @author MCD Application Team
5 | * @version V1.0.1
6 | * @date 11-November-2013
7 | * @brief Main Interrupt Service Routines.
8 | * This file provides template for all exceptions handler and
9 | * peripherals interrupt service routine.
10 | ******************************************************************************
11 | * @attention
12 | *
13 | * © COPYRIGHT 2013 STMicroelectronics
14 | *
15 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
16 | * You may not use this file except in compliance with the License.
17 | * You may obtain a copy of the License at:
18 | *
19 | * http://www.st.com/software_license_agreement_liberty_v2
20 | *
21 | * Unless required by applicable law or agreed to in writing, software
22 | * distributed under the License is distributed on an "AS IS" BASIS,
23 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 | * See the License for the specific language governing permissions and
25 | * limitations under the License.
26 | *
27 | ******************************************************************************
28 | */
29 |
30 | /* Includes ------------------------------------------------------------------*/
31 | #include "stm32f4xx_it.h"
32 |
33 | /** @addtogroup STM32F429I_DISCOVERY_Examples
34 | * @{
35 | */
36 |
37 | /** @addtogroup Touch_Panel
38 | * @{
39 | */
40 |
41 | /* Private typedef -----------------------------------------------------------*/
42 | /* Private define ------------------------------------------------------------*/
43 | /* Private macro -------------------------------------------------------------*/
44 | /* Private variables ---------------------------------------------------------*/
45 | /* Private function prototypes -----------------------------------------------*/
46 | /* Private functions ---------------------------------------------------------*/
47 |
48 | /******************************************************************************/
49 | /* Cortex-M4 Processor Exceptions Handlers */
50 | /******************************************************************************/
51 |
52 | /**
53 | * @brief This function handles NMI exception.
54 | * @param None
55 | * @retval None
56 | */
57 | void NMI_Handler(void)
58 | {
59 | }
60 |
61 | /**
62 | * @brief This function handles Hard Fault exception.
63 | * @param None
64 | * @retval None
65 | */
66 | void HardFault_Handler(void)
67 | {
68 | /* Go to infinite loop when Hard Fault exception occurs */
69 | while (1)
70 | {
71 | }
72 | }
73 |
74 | /**
75 | * @brief This function handles Memory Manage exception.
76 | * @param None
77 | * @retval None
78 | */
79 | void MemManage_Handler(void)
80 | {
81 | /* Go to infinite loop when Memory Manage exception occurs */
82 | while (1)
83 | {
84 | }
85 | }
86 |
87 | /**
88 | * @brief This function handles Bus Fault exception.
89 | * @param None
90 | * @retval None
91 | */
92 | void BusFault_Handler(void)
93 | {
94 | /* Go to infinite loop when Bus Fault exception occurs */
95 | while (1)
96 | {
97 | }
98 | }
99 |
100 | /**
101 | * @brief This function handles Usage Fault exception.
102 | * @param None
103 | * @retval None
104 | */
105 | void UsageFault_Handler(void)
106 | {
107 | /* Go to infinite loop when Usage Fault exception occurs */
108 | while (1)
109 | {
110 | }
111 | }
112 |
113 | /**
114 | * @brief This function handles SVCall exception.
115 | * @param None
116 | * @retval None
117 | */
118 | void SVC_Handler(void)
119 | {
120 | }
121 |
122 | /**
123 | * @brief This function handles Debug Monitor exception.
124 | * @param None
125 | * @retval None
126 | */
127 | void DebugMon_Handler(void)
128 | {
129 | }
130 |
131 | /**
132 | * @brief This function handles PendSVC exception.
133 | * @param None
134 | * @retval None
135 | */
136 | void PendSV_Handler(void)
137 | {
138 | }
139 |
140 | /**
141 | * @brief This function handles SysTick Handler.
142 | * @param None
143 | * @retval None
144 | */
145 | extern void OnSysTick(void);
146 | void SysTick_Handler(void)
147 | {
148 | OnSysTick();
149 | }
150 |
151 | void _exit(int code)
152 | {
153 | while(42);
154 | }
155 |
156 | /******************************************************************************/
157 | /* STM32F4xx Peripherals Interrupt Handlers */
158 | /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
159 | /* available peripheral interrupt handler's name please refer to the startup */
160 | /* file (startup_stm32f429_439xx.s). */
161 | /******************************************************************************/
162 |
163 | /**
164 | * @}
165 | */
166 |
167 | /**
168 | * @}
169 | */
170 |
171 |
172 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
173 |
--------------------------------------------------------------------------------
/main.c:
--------------------------------------------------------------------------------
1 | #include "stm32f4xx.h"
2 | #include "arm_math.h"
3 | #include "stm32f429i_discovery.h"
4 | #include "stm32f429i_discovery_lcd.h"
5 | #include "stm32f429i_discovery_l3gd20.h"
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | static char *itoa(int value, char* result, int base);
12 |
13 | // vertex format
14 | typedef struct {
15 | uint16_t x, y, z;
16 | uint8_t nx, ny, nz;
17 | uint8_t u, v;
18 | } vertex_t;
19 |
20 | // meshes:
21 | #include "teapot.h"
22 | #include "box.h"
23 | #include "pony.h"
24 |
25 | // textures:
26 | #include "nyan.h"
27 | #include "box_texture.h"
28 | #include "twilight.h"
29 |
30 | static const r3d_drawcall_t meshes[] = {
31 | { R3D_PRIMITIVE_TYPE_TRIANGLES, vertices0,
32 | sizeof(vertex_t), sizeof(vertices0) / sizeof(vertex_t), 0 },
33 | { R3D_PRIMITIVE_TYPE_TRIANGLES, vertices1,
34 | sizeof(vertex_t), sizeof(vertices1) / sizeof(vertex_t), 0 },
35 | { R3D_PRIMITIVE_TYPE_TRIANGLES, vertices2,
36 | sizeof(vertex_t), sizeof(vertices2) / sizeof(vertex_t), 0 },
37 | };
38 | static const r3d_primitive_winding_t windings[] = {
39 | R3D_PRIMITIVE_WINDING_CW,
40 | R3D_PRIMITIVE_WINDING_CCW,
41 | R3D_PRIMITIVE_WINDING_CCW
42 | };
43 | static const r3d_texture_t *textures[] = {
44 | (r3d_texture_t *) &nyan,
45 | (r3d_texture_t *) &box_texture,
46 | (r3d_texture_t *) &twilight
47 | };
48 |
49 | // simulation stuff
50 | static float time = 0.0f, frametime = 0.0f;
51 | static uint32_t fps = 0;
52 | static uint8_t fps_str[8] = "? FPS";
53 | static uint8_t info_str[16];
54 | static mat4_t model, view, projection, mv, mvp;
55 | static int mesh = 0;
56 | static float axes[3] = {0};
57 |
58 | // shader
59 | typedef struct {
60 | vec3_t position;
61 | vec3_t normal;
62 | vec2_t uv;
63 | } vs_to_fs_t;
64 |
65 | static void vertex_shader(const vertex_t *in, vs_to_fs_t *out)
66 | {
67 | // decode vertex
68 | const vec3_t pc = { 0.5f, 0.5f, 0.5f }, nc = { 1.0f, 1.0f, 1.0f };
69 | const float pi = 1.0f / 65535.0f, ni = 2.0f / 255.0f, uvi = 1.0f / 255.0f;
70 | vec3_t position = vec3_sub(vec3_mul(vec3(in->x, in->y, in->z), pi), pc);
71 | vec3_t normal = vec3_sub(vec3_mul(vec3(in->nx, in->ny, in->nz), ni), nc);
72 | vec2_t uv = vec2_mul(vec2(in->u, in->v), uvi);
73 | // transform vertex
74 | out->position = mat4_transform_position(mvp, position);
75 | out->normal = mat4_transform_vector(mv, normal);
76 | out->uv = uv;
77 | }
78 |
79 | static vec4_t fragment_shader(const vs_to_fs_t *in)
80 | {
81 | const vec3_t E = { 0, 0, 1 };
82 | const vec3_t L = { -0.577350269f, 0.577350269f, 0.577350269f };
83 | vec3_t N = vec3_normalize(in->normal);
84 | vec3_t H = vec3_normalize(vec3_add(E, L));
85 |
86 | const float ambient = 0.05f;
87 | float diffuse = vec3_dot(N, L) * 0.6f;
88 | float specular = vec3_dot(N, H);
89 | specular *= specular;
90 | specular *= specular;
91 | specular *= specular;
92 | specular *= specular;
93 | specular *= specular;
94 | specular *= specular * 0.6f;
95 |
96 | vec3_t c = r3d_texture_nearest(textures[mesh], in->uv); // read texel
97 | return vec4(ambient + diffuse * c.r + specular,
98 | ambient + diffuse * c.g + specular,
99 | ambient + diffuse * c.b + specular, 1.0f);
100 | }
101 |
102 | static r3d_shader_t shader = {
103 | (r3d_vertexshader_func)vertex_shader,
104 | (r3d_fragmentshader_func)fragment_shader,
105 | sizeof(vs_to_fs_t) / sizeof(float)
106 | };
107 |
108 | static void init(void)
109 | {
110 | STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_GPIO);
111 |
112 | r3dfb_init();
113 | LCD_SetColors(0x0000, 0xffff);
114 | LCD_SetFont(&Font8x8);
115 |
116 | itoa(meshes[mesh].count / 3, info_str, 10);
117 | strcat(info_str, " tris");
118 |
119 | r3d_viewport(1, 1, R3DFB_PIXEL_WIDTH - 1, R3DFB_PIXEL_HEIGHT - 1);
120 | r3d_backface_culling = R3D_ENABLE;
121 | r3d_primitive_winding = windings[mesh];
122 |
123 | projection = mat4_perspective(60.0f, (float)R3DFB_PIXEL_WIDTH / (float)R3DFB_PIXEL_HEIGHT, 0.5f, 5.0f);
124 | view = mat4_lookat(vec3(0.0f, 0.25f, 1.5f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
125 |
126 | L3GD20_InitTypeDef L3GD20_InitStructure;
127 | L3GD20_InitStructure.Power_Mode = L3GD20_MODE_ACTIVE;
128 | L3GD20_InitStructure.Output_DataRate = L3GD20_OUTPUT_DATARATE_1;
129 | L3GD20_InitStructure.Axes_Enable = L3GD20_AXES_ENABLE;
130 | L3GD20_InitStructure.Band_Width = L3GD20_BANDWIDTH_4;
131 | L3GD20_InitStructure.BlockData_Update = L3GD20_BlockDataUpdate_Continous;
132 | L3GD20_InitStructure.Endianness = L3GD20_BLE_LSB;
133 | L3GD20_InitStructure.Full_Scale = L3GD20_FULLSCALE_250;
134 | L3GD20_Init(&L3GD20_InitStructure);
135 |
136 | L3GD20_FilterConfigTypeDef L3GD20_FilterStructure;
137 | L3GD20_FilterStructure.HighPassFilter_Mode_Selection = L3GD20_HPM_NORMAL_MODE_RES;
138 | L3GD20_FilterStructure.HighPassFilter_CutOff_Frequency = L3GD20_HPFCF_0;
139 | L3GD20_FilterConfig(&L3GD20_FilterStructure);
140 | L3GD20_FilterCmd(L3GD20_HIGHPASSFILTER_ENABLE);
141 | }
142 |
143 | static void update(void)
144 | {
145 | uint8_t tmp[6] = {0};
146 | int16_t a[3] = {0};
147 | uint8_t tmpreg = 0;
148 |
149 | L3GD20_Read(&tmpreg, L3GD20_CTRL_REG4_ADDR, 1);
150 | L3GD20_Read(tmp, L3GD20_OUT_X_L_ADDR, 6);
151 |
152 | /* check in the control register 4 the data alignment (Big Endian or Little Endian)*/
153 | if (!(tmpreg & 0x40)) {
154 | for (int i = 0; i < 3; i++)
155 | a[i] = (int16_t)(((uint16_t)tmp[2 * i + 1] << 8) | (uint16_t)tmp[2 * i]);
156 | } else {
157 | for (int i = 0; i < 3; i++)
158 | a[i] = (int16_t)(((uint16_t)tmp[2 * i] << 8) | (uint16_t)tmp[2 * i + 1]);
159 | }
160 |
161 | if (STM_EVAL_PBGetState(BUTTON_USER)) {
162 | mesh = (mesh + 1) % 3; // next mesh
163 | r3d_primitive_winding = windings[mesh];
164 | itoa(meshes[mesh].count / 3, info_str, 10);
165 | strcat(info_str, " tris");
166 | while (STM_EVAL_PBGetState(BUTTON_USER)); // debounce
167 | }
168 |
169 | float delta = frametime - time;
170 | frametime = time; // make frametime a consistent time value during the frames
171 | for (int i = 0; i < 3; i++)
172 | axes[i] += (float)a[i] * delta / 114.285f;
173 | if (axes[0] < 0) axes[0] = 0;
174 | if (axes[0] > 180) axes[0] = 180;
175 | model = mat4_mul(
176 | mat4_rotation(axes[0], vec3(1.0f, 0.0f, 0.0f)),
177 | mat4_rotation(axes[1], vec3(0.0f, 1.0f, 0.0f)));
178 | if (mesh == 1) model = mat4_mul(model, mat4_scaling(vec3(0.5f, 0.5f, 0.5f)));
179 | mv = mat4_mul(view, model);
180 | mvp = mat4_mul(projection, mv);
181 | }
182 |
183 | static void render(void)
184 | {
185 | r3dfb_clear();
186 |
187 | r3d_shader = shader;
188 | r3d_draw(&meshes[mesh]);
189 |
190 | LCD_DisplayStringLine(LCD_LINE_1, info_str);
191 | LCD_DisplayStringLine(LCD_LINE_3, fps_str);
192 |
193 | char str[16] = "X: ";
194 | itoa(axes[0], str + 3, 10);
195 | LCD_DisplayStringLine(LCD_LINE_5, str);
196 | str[0] = 'Y';
197 | itoa(axes[1], str + 3, 10);
198 | LCD_DisplayStringLine(LCD_LINE_6, str);
199 | str[0] = 'Z';
200 | itoa(axes[2], str + 3, 10);
201 | LCD_DisplayStringLine(LCD_LINE_7, str);
202 |
203 | r3dfb_swap_buffers();
204 | fps++;
205 | }
206 |
207 | int main(void)
208 | {
209 | SysTick_Config(SystemCoreClock / 100); // SysTick event each 10ms
210 | init();
211 |
212 | while (1) {
213 | update();
214 | render();
215 | }
216 | }
217 |
218 | static char* itoa(int value, char* result, int base)
219 | {
220 | if (base < 2 || base > 36) {
221 | *result = '\0';
222 | return result;
223 | }
224 | char *ptr = result, *ptr1 = result, tmp_char;
225 | int tmp_value;
226 |
227 | do {
228 | tmp_value = value;
229 | value /= base;
230 | *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
231 | } while (value);
232 |
233 | if (tmp_value < 0) *ptr++ = '-';
234 | *ptr-- = '\0';
235 | while (ptr1 < ptr) {
236 | tmp_char = *ptr;
237 | *ptr-- = *ptr1;
238 | *ptr1++ = tmp_char;
239 | }
240 | return result;
241 | }
242 |
243 | uint32_t fps_countdown = 100;
244 | void OnSysTick(void)
245 | {
246 | if (--fps_countdown == 0) {
247 | itoa(fps, fps_str, 10);
248 | strcat(fps_str, " FPS");
249 | fps = 0;
250 | fps_countdown = 100;
251 | }
252 | time += 0.01f;
253 | }
254 |
255 | uint32_t L3GD20_TIMEOUT_UserCallback(void)
256 | {
257 | return 0;
258 | }
259 |
260 | #ifdef USE_FULL_ASSERT
261 | void assert_failed(uint8_t* file, uint32_t line)
262 | {
263 | /* printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
264 | while (1) { }
265 | }
266 | #endif
267 |
--------------------------------------------------------------------------------
/libs/r3d/r3d.c:
--------------------------------------------------------------------------------
1 | /**
2 | * r3d -- 3D rendering library
3 | * author: Andreas Mantler (ands)
4 | */
5 |
6 | #include
7 | #include
8 |
9 | typedef void (*r3d_primitive_rasterizer_func)(const float *in);
10 | static void r3d_points_rasterizer(const float *in);
11 | static void r3d_lines_rasterizer(const float *in);
12 | static void r3d_line_strip_rasterizer(const float *in);
13 | static void r3d_line_fan_rasterizer(const float *in);
14 | static void r3d_triangles_rasterizer(const float *in);
15 | static void r3d_triangle_strip_rasterizer(const float *in);
16 | static void r3d_triangle_fan_rasterizer(const float *in);
17 | //static void r3d_quads_rasterizer(const float *in);
18 | //static void r3d_quad_strip_rasterizer(const float *in);
19 |
20 | // public variables
21 | r3d_switch_t r3d_backface_culling = R3D_DISABLE;
22 | r3d_primitive_winding_t r3d_primitive_winding = R3D_PRIMITIVE_WINDING_CCW;
23 | r3d_shader_t r3d_shader = {0};
24 |
25 | // private variables
26 | static vec2_t r3d_viewport_position = {0};
27 | static vec2_t r3d_viewport_half_size = {0};
28 | static int r3d_viewport_width = 0;
29 | static int r3d_viewport_height = 0;
30 | static float *r3d_primitive_vertex_buffer;
31 | static uint8_t r3d_primitive_vertex_index = 0;
32 | static r3d_primitive_rasterizer_func r3d_primitive_rasterizers[R3D_PRIMITIVE_TYPE_NUM] = {
33 | r3d_points_rasterizer,
34 | r3d_lines_rasterizer,
35 | r3d_line_strip_rasterizer, // line_loop: differentiation happens in r3d_draw.
36 | r3d_line_strip_rasterizer,
37 | r3d_line_fan_rasterizer,
38 | r3d_triangles_rasterizer,
39 | r3d_triangle_strip_rasterizer,
40 | r3d_triangle_fan_rasterizer,
41 | //r3d_quads_rasterizer,
42 | //r3d_quad_strip_rasterizer
43 | };
44 |
45 | void r3d_viewport(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
46 | {
47 | r3d_viewport_position.x = x0;
48 | r3d_viewport_position.y = y0;
49 | r3d_viewport_half_size.x = (float)(x1 - x0) * 0.5f;
50 | r3d_viewport_half_size.y = (float)(y1 - y0) * 0.5f;
51 | r3d_viewport_width = x1 - x0;
52 | r3d_viewport_height = y1 - y0;
53 | }
54 |
55 | void r3d_draw(const r3d_drawcall_t *drawcall)
56 | {
57 | const void *vs_in;
58 | float vs_out[R3D_VERTEX_ELEMENTS_MAX];
59 |
60 | // initialize rasterizer
61 | float primitive_buffer[R3D_PRIMITIVE_VERTEX_BUFFER * R3D_VERTEX_ELEMENTS_MAX];
62 | r3d_primitive_rasterizer_func rasterizer = r3d_primitive_rasterizers[drawcall->primitive_type];
63 | r3d_primitive_vertex_buffer = primitive_buffer;
64 | r3d_primitive_vertex_index = 0;
65 |
66 | if (drawcall->indices == 0) {
67 | // rasterize vertex arrays
68 | vs_in = drawcall->vertices;
69 | const void *vs_end = vs_in + drawcall->count * drawcall->stride;
70 | if (drawcall->primitive_type == R3D_PRIMITIVE_TYPE_LINE_LOOP) {
71 | r3d_shader.vertexshader(vs_end - drawcall->stride, vs_out);
72 | rasterizer(vs_out);
73 | }
74 | while (vs_in != vs_end) {
75 | r3d_shader.vertexshader(vs_in, vs_out);
76 | rasterizer(vs_out);
77 | vs_in += drawcall->stride;
78 | }
79 | } else {
80 | // rasterize indexed arrays
81 | if (drawcall->primitive_type == R3D_PRIMITIVE_TYPE_LINE_LOOP) {
82 | vs_in = drawcall->vertices + drawcall->indices[drawcall->count - 1] * drawcall->stride;
83 | r3d_shader.vertexshader(vs_in, vs_out);
84 | rasterizer(vs_out);
85 | }
86 | for (uint32_t i = 0; i < drawcall->count; i++) {
87 | vs_in = drawcall->vertices + drawcall->indices[i] * drawcall->stride;
88 | r3d_shader.vertexshader(vs_in, vs_out);
89 | rasterizer(vs_out);
90 | }
91 | }
92 | }
93 |
94 | // interpolators
95 | static inline void r3d_primitive_linear_interpolate(const float *in0, const float *in1, float *out, float x)
96 | {
97 | float xr = 1.0f - x;
98 | for (int i = 0; i < r3d_shader.vertex_out_elements; i++)
99 | out[i] = in0[i] * xr + in1[i] * x;
100 | }
101 |
102 | static inline void r3d_primitive_barycentric_interpolate(const float *in0, const float *in1, const float *in2, float *out, float t0, float t1, float t2)
103 | {
104 | for (int i = 0; i < r3d_shader.vertex_out_elements; i++)
105 | out[i] = in0[i] * t0 + in1[i] * t1 + in2[i] * t2;
106 | }
107 |
108 | // temporary buffer access
109 | #define r3d_primitive_vertex_buffer(i) (r3d_primitive_vertex_buffer + (i) * r3d_shader.vertex_out_elements)
110 | #define r3d_primitive_vertex_buffer_put(i, in) memcpy(r3d_primitive_vertex_buffer(i), in, r3d_shader.vertex_out_elements * sizeof(float));
111 |
112 | static inline void r3d_fragment_rasterizer(const float *in, uint16_t x, uint16_t y)
113 | {
114 | // TODO: alpha test
115 | float z = (in[2] - 1.0f) * -0.5f;
116 | if (z > r3d_get_depth(x, y)) {
117 | vec4_t color = r3d_shader.fragmentshader(in);
118 | color.r = float_clamp(color.r, 0.0f, 1.0f);
119 | color.g = float_clamp(color.g, 0.0f, 1.0f);
120 | color.b = float_clamp(color.b, 0.0f, 1.0f);
121 | r3d_set_pixel(x, y, z, color.rgb);
122 | }
123 | }
124 |
125 | static void r3d_points_rasterizer(const float *in)
126 | {
127 | if (in[0] < -1.0f || in[0] > 1.0f || in[1] < -1.0f || in[1] > 1.0f || in[2] < -1.0f || in[2] > 1.0f)
128 | return;
129 | uint16_t x = (uint16_t)((in[0] + 1.0f) * r3d_viewport_half_size.x + r3d_viewport_position.x);
130 | uint16_t y = (uint16_t)((in[1] - 1.0f) * -r3d_viewport_half_size.y + r3d_viewport_position.y);
131 | r3d_fragment_rasterizer(in, x, y);
132 | }
133 |
134 | static void r3d_line_rasterizer(const float *v0, const float *v1)
135 | {
136 | // bresenham
137 | int x0 = (int)((v0[0] + 1.0f) * r3d_viewport_half_size.x + r3d_viewport_position.x);
138 | int y0 = (int)((v0[1] - 1.0f) * -r3d_viewport_half_size.y + r3d_viewport_position.y);
139 | int x1 = (int)((v1[0] + 1.0f) * r3d_viewport_half_size.x + r3d_viewport_position.x);
140 | int y1 = (int)((v1[1] - 1.0f) * -r3d_viewport_half_size.y + r3d_viewport_position.y);
141 |
142 | int dx = x1 - x0, sx = x0 < x1 ? 1 : -1;
143 | int dy = y1 - y0, sy = y0 < y1 ? 1 : -1;
144 | if (dx < 0) dx = -dx;
145 | if (dy < 0) dy = -dy;
146 | int cur = 0, len = dx < dy ? dy : dx;
147 | int err = (dx > dy ? dx : -dy) / 2, e2;
148 | float t;
149 | float *vi = r3d_primitive_vertex_buffer(1);
150 |
151 | for (;;) {
152 | t = (float)(cur++) / (float)len; // TODO: incremental?
153 | r3d_primitive_linear_interpolate(v0, v1, vi, t);
154 | r3d_fragment_rasterizer(vi, x0, y0);
155 |
156 | if (x0 == x1 && y0 == y1) break;
157 | e2 = err;
158 | if (e2 > -dx) {
159 | err -= dy;
160 | x0 += sx;
161 | }
162 | if (e2 < dy) {
163 | err += dx;
164 | y0 += sy;
165 | }
166 | }
167 | }
168 |
169 | static void r3d_lines_rasterizer(const float *in)
170 | {
171 | if (r3d_primitive_vertex_index == 1) {
172 | r3d_line_rasterizer(r3d_primitive_vertex_buffer(0), in);
173 | r3d_primitive_vertex_index = 0;
174 | } else {
175 | r3d_primitive_vertex_buffer_put(0, in);
176 | r3d_primitive_vertex_index = 1;
177 | }
178 | }
179 |
180 | static void r3d_line_strip_rasterizer(const float *in)
181 | {
182 | if (r3d_primitive_vertex_index == 1) {
183 | r3d_line_rasterizer(r3d_primitive_vertex_buffer(0), in);
184 | r3d_primitive_vertex_buffer_put(0, in);
185 | } else {
186 | r3d_primitive_vertex_buffer_put(0, in);
187 | r3d_primitive_vertex_index = 1;
188 | }
189 | }
190 |
191 | static void r3d_line_fan_rasterizer(const float *in)
192 | {
193 | if (r3d_primitive_vertex_index == 1) {
194 | r3d_line_rasterizer(r3d_primitive_vertex_buffer(0), in);
195 | } else {
196 | r3d_primitive_vertex_buffer_put(0, in);
197 | r3d_primitive_vertex_index = 1;
198 | }
199 | }
200 |
201 | // screen orientations: cw vs ccw
202 | static inline float r3d_orientation2f(const float *i0, const float *i1, const float *i2)
203 | {
204 | return (i1[0] - i0[0]) * (i2[1] - i0[1]) - (i1[1] - i0[1]) * (i2[0] - i0[0]);
205 | }
206 |
207 | static inline int r3d_orientation2i(const int *i0, const int *i1, const int *i2)
208 | {
209 | return (i1[0] - i0[0]) * (i2[1] - i0[1]) - (i1[1] - i0[1]) * (i2[0] - i0[0]);
210 | }
211 |
212 | // triangle front face rasterizer
213 | static void r3d_triangle_front_rasterizer(const float *v0, const float *v1, const float *v2)
214 | {
215 | int i0[2], i1[2], i2[2];
216 | i0[0] = (int)((v0[0] + 1.0f) * r3d_viewport_half_size.x + r3d_viewport_position.x);
217 | i0[1] = (int)((v0[1] - 1.0f) * -r3d_viewport_half_size.y + r3d_viewport_position.y);
218 | i1[0] = (int)((v1[0] + 1.0f) * r3d_viewport_half_size.x + r3d_viewport_position.x);
219 | i1[1] = (int)((v1[1] - 1.0f) * -r3d_viewport_half_size.y + r3d_viewport_position.y);
220 | i2[0] = (int)((v2[0] + 1.0f) * r3d_viewport_half_size.x + r3d_viewport_position.x);
221 | i2[1] = (int)((v2[1] - 1.0f) * -r3d_viewport_half_size.y + r3d_viewport_position.y);
222 |
223 | int minX = int_max(int_min(i0[0], int_min(i1[0], i2[0])), (int)r3d_viewport_position.x); // bounding box
224 | int minY = int_max(int_min(i0[1], int_min(i1[1], i2[1])), (int)r3d_viewport_position.y);
225 | int maxX = int_min(int_max(i0[0], int_max(i1[0], i2[0])), (int)r3d_viewport_position.x + r3d_viewport_width - 1);
226 | int maxY = int_min(int_max(i0[1], int_max(i1[1], i2[1])), (int)r3d_viewport_position.y + r3d_viewport_height - 1);
227 |
228 | int A01 = i0[1] - i1[1], B01 = i1[0] - i0[0]; // triangle setup
229 | int A12 = i1[1] - i2[1], B12 = i2[0] - i1[0];
230 | int A20 = i2[1] - i0[1], B20 = i0[0] - i2[0];
231 |
232 | int p[2] = { minX, minY }; // barycentric coordinates at minX/minY corner
233 | int w0_row = r3d_orientation2i(i1, i2, p);
234 | int w1_row = r3d_orientation2i(i2, i0, p);
235 | int w2_row = r3d_orientation2i(i0, i1, p);
236 |
237 | float vi[R3D_VERTEX_ELEMENTS_MAX]; // interpolated vertex
238 |
239 | for (p[1] = minY; p[1] <= maxY; p[1]++) {
240 | int w0 = w0_row; // barycentric coordinates at start of row
241 | int w1 = w1_row;
242 | int w2 = w2_row;
243 |
244 | for (p[0] = minX; p[0] <= maxX; p[0]++) {
245 | if ((w0 | w1 | w2) >= 0) { // if p is on or inside all edges, render pixel.
246 | float wai = 1.0f / (float)(w0 + w1 + w2);
247 | r3d_primitive_barycentric_interpolate(v0, v1, v2, vi, w0 * wai, w1 * wai, w2 * wai);
248 | r3d_fragment_rasterizer(vi, p[0], p[1]);
249 | }
250 | w0 += A12; // one step to the right
251 | w1 += A20;
252 | w2 += A01;
253 | }
254 | w0_row += B12; // one row step
255 | w1_row += B20;
256 | w2_row += B01;
257 | }
258 | }
259 |
260 | static void r3d_triangle_rasterizer(const float *v0, const float *v1, const float *v2)
261 | {
262 | if (r3d_primitive_winding == R3D_PRIMITIVE_WINDING_CCW) {
263 | if (r3d_orientation2f(v0, v1, v2) > 0.0f)
264 | r3d_triangle_front_rasterizer(v0, v2, v1); // ccw front face
265 | else if (!r3d_backface_culling)
266 | r3d_triangle_front_rasterizer(v0, v1, v2); // ccw back face
267 | } else {
268 | if (r3d_orientation2f(v0, v1, v2) < 0.0f)
269 | r3d_triangle_front_rasterizer(v0, v1, v2); // cw front face
270 | else if (!r3d_backface_culling)
271 | r3d_triangle_front_rasterizer(v0, v2, v1); // cw back face
272 | }
273 | }
274 |
275 | static void r3d_triangles_rasterizer(const float *in)
276 | {
277 | if (r3d_primitive_vertex_index == 2) {
278 | r3d_triangle_rasterizer(r3d_primitive_vertex_buffer(0), r3d_primitive_vertex_buffer(1), in);
279 | r3d_primitive_vertex_index = 0;
280 | } else {
281 | r3d_primitive_vertex_buffer_put(r3d_primitive_vertex_index, in);
282 | r3d_primitive_vertex_index++;
283 | }
284 | }
285 |
286 | static void r3d_triangle_strip_rasterizer(const float *in)
287 | {
288 | if (r3d_primitive_vertex_index == 2) {
289 | r3d_triangle_rasterizer(r3d_primitive_vertex_buffer(0), r3d_primitive_vertex_buffer(1), in);
290 | r3d_primitive_vertex_buffer_put(r3d_primitive_vertex_index, in);
291 | r3d_primitive_vertex_index++;
292 | } else if (r3d_primitive_vertex_index == 3) {
293 | r3d_triangle_rasterizer(r3d_primitive_vertex_buffer(2), r3d_primitive_vertex_buffer(1), in);
294 | r3d_primitive_vertex_buffer_put(0, r3d_primitive_vertex_buffer(2));
295 | r3d_primitive_vertex_buffer_put(1, in);
296 | r3d_primitive_vertex_index = 2;
297 | } else {
298 | r3d_primitive_vertex_buffer_put(r3d_primitive_vertex_index, in);
299 | r3d_primitive_vertex_index++;
300 | }
301 | }
302 |
303 | static void r3d_triangle_fan_rasterizer(const float *in)
304 | {
305 | if (r3d_primitive_vertex_index == 2) {
306 | r3d_triangle_rasterizer(r3d_primitive_vertex_buffer(0), r3d_primitive_vertex_buffer(1), in);
307 | r3d_primitive_vertex_buffer_put(1, in);
308 | } else {
309 | r3d_primitive_vertex_buffer_put(r3d_primitive_vertex_index, in);
310 | r3d_primitive_vertex_index++;
311 | }
312 | }
313 |
314 | /*static void r3d_quads_rasterizer(const float *in)
315 | {
316 |
317 | }
318 |
319 | static void r3d_quad_strip_rasterizer(const float *in)
320 | {
321 |
322 | }*/
323 |
324 |
325 |
--------------------------------------------------------------------------------
/libs/r3d/r3d_math.h:
--------------------------------------------------------------------------------
1 | /**
2 | * r3d -- 3D rendering library
3 | * author: Andreas Mantler (ands)
4 | */
5 |
6 | #ifndef R3D_MATH_H
7 | #define R3D_MATH_H
8 |
9 | #if defined (ARM_MATH_CM4) || (ARM_MATH_CM3) || (ARM_MATH_CM0)
10 | #define R3D_ARM_MATH
11 | #include "arm_math.h"
12 | #else
13 | #include
14 | #endif
15 |
16 | #define float_pi 3.1415926535897932f
17 | #define float_pi_over180 0.017453293f
18 |
19 | typedef struct {
20 | union {
21 | float v[2];
22 | struct {
23 | float x, y;
24 | };
25 | struct {
26 | float r, g;
27 | };
28 | };
29 | } vec2_t;
30 |
31 | typedef struct {
32 | union {
33 | float v[3];
34 | struct {
35 | float x, y, z;
36 | };
37 | struct {
38 | float r, g, b;
39 | };
40 | vec2_t xy;
41 | };
42 | } vec3_t;
43 |
44 | typedef struct {
45 | union {
46 | float v[4];
47 | struct {
48 | float x, y, z, w;
49 | };
50 | struct {
51 | float r, g, b, a;
52 | };
53 | vec2_t xy;
54 | vec3_t xyz;
55 | vec3_t rgb;
56 | };
57 | } vec4_t;
58 |
59 | typedef struct {
60 | union {
61 | float m[16];
62 | struct {
63 | float m00, m10, m20, m30,
64 | m01, m11, m21, m31,
65 | m02, m12, m22, m32,
66 | m03, m13, m23, m33;
67 | };
68 | vec4_t c[4];
69 | };
70 | } mat4_t;
71 |
72 | static inline int int_min(int a, int b)
73 | {
74 | return a < b ? a : b;
75 | }
76 | static inline int int_max(int a, int b)
77 | {
78 | return a < b ? b : a;
79 | }
80 | static inline int int_clamp(int value, int min, int max)
81 | {
82 | return value < min ? min : (value < max ? value : max);
83 | }
84 |
85 | static inline float float_min(float a, float b)
86 | {
87 | return a < b ? a : b;
88 | }
89 | static inline float float_max(float a, float b)
90 | {
91 | return a < b ? b : a;
92 | }
93 | static inline float float_clamp(float value, float min, float max)
94 | {
95 | return value < min ? min : (value < max ? value : max);
96 | }
97 |
98 | static inline vec2_t vec2(float x, float y)
99 | {
100 | vec2_t r = { x, y };
101 | return r;
102 | }
103 | static inline vec2_t vec2_add(vec2_t v0, vec2_t v1)
104 | {
105 | vec2_t r = { v0.x + v1.x, v0.y + v1.y };
106 | return r;
107 | }
108 | static inline vec2_t vec2_sub(vec2_t v0, vec2_t v1)
109 | {
110 | vec2_t r = { v0.x - v1.x, v0.y - v1.y };
111 | return r;
112 | }
113 | static inline vec2_t vec2_mul(vec2_t v, float f)
114 | {
115 | vec2_t r = { v.x * f, v.y * f };
116 | return r;
117 | }
118 | static inline vec2_t vec2_div(vec2_t v, float f)
119 | {
120 | float fi = 1.0f / f;
121 | vec2_t r = { v.x * fi, v.y * fi };
122 | return r;
123 | }
124 | static inline float vec2_dot(vec2_t v0, vec2_t v1)
125 | {
126 | return v0.x * v1.x + v0.y * v1.y;
127 | }
128 | static inline float vec2_cross(vec2_t v0, vec2_t v1)
129 | {
130 | return v0.x * v1.y - v0.y * v1.x;
131 | }
132 | static inline float vec2_length(vec2_t v)
133 | {
134 | return sqrtf(v.x * v.x + v.y * v.y);
135 | }
136 | static inline vec2_t vec2_normalize(vec2_t v)
137 | {
138 | float fi = 1.0f / sqrtf(v.x * v.x + v.y * v.y);
139 | vec2_t r = { v.x * fi, v.y * fi };
140 | return r;
141 | }
142 |
143 | static inline vec3_t vec3(float x, float y, float z)
144 | {
145 | vec3_t r = { x, y, z };
146 | return r;
147 | }
148 | static inline vec3_t vec3_2(vec2_t xy, float z)
149 | {
150 | vec3_t r = { xy.x, xy.y, z };
151 | return r;
152 | }
153 | static inline vec3_t vec3_add(vec3_t v0, vec3_t v1)
154 | {
155 | vec3_t r = { v0.x + v1.x, v0.y + v1.y, v0.z + v1.z };
156 | return r;
157 | }
158 | static inline vec3_t vec3_sub(vec3_t v0, vec3_t v1)
159 | {
160 | vec3_t r = { v0.x - v1.x, v0.y - v1.y, v0.z - v1.z };
161 | return r;
162 | }
163 | static inline vec3_t vec3_mul(vec3_t v, float f)
164 | {
165 | vec3_t r = { v.x * f, v.y * f, v.z * f };
166 | return r;
167 | }
168 | static inline vec3_t vec3_div(vec3_t v, float f)
169 | {
170 | float fi = 1.0f / f;
171 | vec3_t r = { v.x * fi, v.y * fi, v.z * fi };
172 | return r;
173 | }
174 | static inline float vec3_dot(vec3_t v0, vec3_t v1)
175 | {
176 | return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
177 | }
178 | static inline vec3_t vec3_cross(vec3_t v0, vec3_t v1)
179 | {
180 | vec3_t r = { v0.y * v1.z - v0.z * v1.y, v0.z * v1.x - v0.x * v1.z, v0.x * v1.y - v0.y * v1.x };
181 | return r;
182 | }
183 | static inline float vec3_length(vec3_t v)
184 | {
185 | return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
186 | }
187 | static inline vec3_t vec3_normalize(vec3_t v)
188 | {
189 | float fi = 1.0f / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
190 | vec3_t r = { v.x * fi, v.y * fi, v.z * fi };
191 | return r;
192 | }
193 |
194 | static inline vec4_t vec4(float x, float y, float z, float w)
195 | {
196 | vec4_t r = { x, y, z, w };
197 | return r;
198 | }
199 | static inline vec4_t vec4_2(vec2_t xy, float z, float w)
200 | {
201 | vec4_t r = { xy.x, xy.y, z, w };
202 | return r;
203 | }
204 | static inline vec4_t vec4_3(vec3_t xyz, float w)
205 | {
206 | vec4_t r = { xyz.x, xyz.y, xyz.z, w };
207 | return r;
208 | }
209 | static inline vec4_t vec4_add(vec4_t v0, vec4_t v1)
210 | {
211 | vec4_t r = { v0.x + v1.x, v0.y + v1.y, v0.z + v1.z, v0.w + v1.w };
212 | return r;
213 | }
214 | static inline vec4_t vec4_sub(vec4_t v0, vec4_t v1)
215 | {
216 | vec4_t r = { v0.x - v1.x, v0.y - v1.y, v0.z - v1.z, v0.w - v1.w };
217 | return r;
218 | }
219 | static inline vec4_t vec4_mul(vec4_t v, float f)
220 | {
221 | vec4_t r = { v.x * f, v.y * f, v.z * f, v.w * f };
222 | return r;
223 | }
224 | static inline vec4_t vec4_div(vec4_t v, float f)
225 | {
226 | float fi = 1.0f / f;
227 | vec4_t r = { v.x * fi, v.y * fi, v.z * fi, v.w * fi };
228 | return r;
229 | }
230 | static inline float vec4_dot(vec4_t v0, vec4_t v1)
231 | {
232 | return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w;
233 | }
234 | static inline vec4_t vec4_cross(vec4_t v0, vec4_t v1)
235 | {
236 | return vec4_3(vec3_cross(v0.xyz, v1.xyz), (v0.w + v1.w) * 0.5f); // USUALLY FAIL
237 | }
238 | static inline float vec4_length(vec4_t v)
239 | {
240 | return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
241 | }
242 | static inline vec4_t vec4_normalize(vec4_t v)
243 | {
244 | float fi = 1.0f / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
245 | vec4_t r = { v.x * fi, v.y * fi, v.z * fi, v.w * fi };
246 | return r;
247 | }
248 |
249 | static inline mat4_t mat4(float m00, float m10, float m20, float m30, float m01, float m11, float m21, float m31, float m02, float m12, float m22, float m32, float m03, float m13, float m23, float m33)
250 | {
251 | mat4_t m = {
252 | m00, m10, m20, m30,
253 | m01, m11, m21, m31,
254 | m02, m12, m22, m32,
255 | m03, m13, m23, m33
256 | };
257 | return m;
258 | }
259 |
260 | static inline mat4_t mat4_identity()
261 | {
262 | mat4_t m = {
263 | 1.0f, 0.0f, 0.0f, 0.0f,
264 | 0.0f, 1.0f, 0.0f, 0.0f,
265 | 0.0f, 0.0f, 1.0f, 0.0f,
266 | 0.0f, 0.0f, 0.0f, 1.0f
267 | };
268 | return m;
269 | }
270 |
271 | static inline mat4_t mat4_ortho(float left, float right,
272 | float bottom, float top,
273 | float near, float far)
274 | {
275 | float rl = right - left;
276 | float tx = - (right + left) / rl;
277 | float tb = top - bottom;
278 | float ty = - (top + bottom) / tb;
279 | float fn = far - near;
280 | float tz = - (far + near) / fn;
281 | mat4_t m = {
282 | 2.0f / rl, 0.0f, 0.0f, 0.0f,
283 | 0.0f, 2.0f / tb, 0.0f, 0.0f,
284 | 0.0f, 0.0f, -2.0f / fn, 0.0f,
285 | tx, ty, tz, 1.0f
286 | };
287 | return m;
288 | }
289 |
290 | static inline mat4_t mat4_perspective(float fovy, float aspect,
291 | float near, float far)
292 | {
293 | float a = fovy * float_pi_over180 * 0.5f;
294 | #ifdef R3D_ARM_MATH
295 | float f = arm_cos_f32(a) / arm_sin_f32(a);
296 | #else
297 | float f = 1.0f / tanf(a);
298 | #endif
299 | float nfi = 1.0f / (near - far);
300 | mat4_t m = {
301 | f / aspect, 0.0f, 0.0f, 0.0f,
302 | 0.0f, f, 0.0f, 0.0f,
303 | 0.0f, 0.0f, (far + near) * nfi, -1.0f,
304 | 0.0f, 0.0f, 2.0f * far * near * nfi, 0.0f
305 | };
306 | return m;
307 | }
308 |
309 | static inline mat4_t mat4_mul(mat4_t m0, mat4_t m1)
310 | {
311 | mat4_t m = {
312 | m0.m00*m1.m00 + m0.m01*m1.m10 + m0.m02*m1.m20 + m0.m03 * m1.m30,
313 | m0.m10*m1.m00 + m0.m11*m1.m10 + m0.m12*m1.m20 + m0.m13 * m1.m30,
314 | m0.m20*m1.m00 + m0.m21*m1.m10 + m0.m22*m1.m20 + m0.m23 * m1.m30,
315 | m0.m30*m1.m00 + m0.m31*m1.m10 + m0.m32*m1.m20 + m0.m33 * m1.m30,
316 |
317 | m0.m00*m1.m01 + m0.m01*m1.m11 + m0.m02*m1.m21 + m0.m03 * m1.m31,
318 | m0.m10*m1.m01 + m0.m11*m1.m11 + m0.m12*m1.m21 + m0.m13 * m1.m31,
319 | m0.m20*m1.m01 + m0.m21*m1.m11 + m0.m22*m1.m21 + m0.m23 * m1.m31,
320 | m0.m30*m1.m01 + m0.m31*m1.m11 + m0.m32*m1.m21 + m0.m33 * m1.m31,
321 |
322 | m0.m00*m1.m02 + m0.m01*m1.m12 + m0.m02*m1.m22 + m0.m03 * m1.m32,
323 | m0.m10*m1.m02 + m0.m11*m1.m12 + m0.m12*m1.m22 + m0.m13 * m1.m32,
324 | m0.m20*m1.m02 + m0.m21*m1.m12 + m0.m22*m1.m22 + m0.m23 * m1.m32,
325 | m0.m30*m1.m02 + m0.m31*m1.m12 + m0.m32*m1.m22 + m0.m33 * m1.m32,
326 |
327 | m0.m00*m1.m03 + m0.m01*m1.m13 + m0.m02*m1.m23 + m0.m03 * m1.m33,
328 | m0.m10*m1.m03 + m0.m11*m1.m13 + m0.m12*m1.m23 + m0.m13 * m1.m33,
329 | m0.m20*m1.m03 + m0.m21*m1.m13 + m0.m22*m1.m23 + m0.m23 * m1.m33,
330 | m0.m30*m1.m03 + m0.m31*m1.m13 + m0.m32*m1.m23 + m0.m33*m1.m33
331 | };
332 | return m;
333 | }
334 |
335 | static inline mat4_t mat4_translation(vec3_t v)
336 | {
337 | mat4_t m = {
338 | 1.0f, 0.0f, 0.0f, 0.0f,
339 | 0.0f, 1.0f, 0.0f, 0.0f,
340 | 0.0f, 0.0f, 1.0f, 0.0f,
341 | v.x, v.y, v.z, 1.0f
342 | };
343 | return m;
344 | }
345 |
346 | static inline mat4_t mat4_lookat(vec3_t eye, vec3_t center, vec3_t up)
347 | {
348 | vec3_t f = vec3_normalize(vec3_sub(center, eye));
349 | vec3_t s = vec3_cross(f, vec3_normalize(up));
350 | vec3_t u = vec3_cross(vec3_normalize(s), f);
351 |
352 | mat4_t m = {
353 | s.x, u.x, -f.x, 0.0f,
354 | s.y, u.y, -f.y, 0.0f,
355 | s.z, u.z, -f.z, 0.0f,
356 | 0.0f, 0.0f, 0.0f, 1.0f
357 | };
358 | return mat4_mul(m, mat4_translation(vec3_mul(eye, -1.0f)));
359 | }
360 |
361 | static inline mat4_t mat4_scaling(vec3_t v)
362 | {
363 | mat4_t m = {
364 | v.x, 0.0f, 0.0f, 0.0f,
365 | 0.0f, v.y, 0.0f, 0.0f,
366 | 0.0f, 0.0f, v.z, 0.0f,
367 | 0.0f, 0.0f, 0.0f, 1.0f
368 | };
369 | return m;
370 | }
371 |
372 | static inline mat4_t mat4_rotation(float angle, vec3_t axis)
373 | {
374 | #ifdef R3D_ARM_MATH
375 | float c, s;
376 | const float i360 = 1.0f / 360.0f;
377 | int a = (int)(angle * i360);
378 | if (angle < 0.0f) a--;
379 | arm_sin_cos_f32(angle - (a * 360.0f) - 180.0f, &c, &s); // accepts [-180, 180]
380 | // = arm_sin_cos_f32(fmod(angle, 360) - 180, &c, &s)
381 | c *= -1.0f;
382 | s *= -1.0f; // we're 180° off. correct this
383 | #else
384 | angle *= float_pi_over180;
385 | float c = cosf(angle);
386 | float s = sinf(angle);
387 | #endif
388 | float c2 = 1.0f - c;
389 | axis = vec3_normalize(axis);
390 | float x = axis.x;
391 | float y = axis.y;
392 | float z = axis.z;
393 |
394 | mat4_t m = {
395 | x*x*c2 + c, y*x*c2 + z * s, x*z*c2 - y * s, 0.0f,
396 | x*y*c2 - z * s, y*y*c2 + c, y*z*c2 + x * s, 0.0f,
397 | x*z*c2 + y * s, y*z*c2 - x * s, z*z*c2 + c, 0.0f,
398 | 0.0f, 0.0f, 0.0f, 1.0f
399 | };
400 | return m;
401 | }
402 |
403 | static inline vec4_t mat4_transform(mat4_t m, vec4_t v)
404 | {
405 | vec4_t r = {
406 | m.m00*v.x + m.m01*v.y + m.m02*v.z + m.m03 * v.w,
407 | m.m10*v.x + m.m11*v.y + m.m12*v.z + m.m13 * v.w,
408 | m.m20*v.x + m.m21*v.y + m.m22*v.z + m.m23 * v.w,
409 | m.m30*v.x + m.m31*v.y + m.m32*v.z + m.m33*v.w
410 | };
411 | return r;
412 | }
413 |
414 | static inline vec3_t mat4_transform_position(mat4_t m, vec3_t v)
415 | {
416 | float fi = 1.0f / (m.m30 * v.x + m.m31 * v.y + m.m32 * v.z + m.m33);
417 | vec3_t r = {
418 | (m.m00 * v.x + m.m01 * v.y + m.m02 * v.z + m.m03) * fi,
419 | (m.m10 * v.x + m.m11 * v.y + m.m12 * v.z + m.m13) * fi,
420 | (m.m20 * v.x + m.m21 * v.y + m.m22 * v.z + m.m23) * fi
421 | };
422 | return r;
423 | }
424 |
425 | static inline vec3_t mat4_transform_vector(mat4_t m, vec3_t v)
426 | {
427 | vec3_t r = {
428 | m.m00*v.x + m.m01*v.y + m.m02 * v.z,
429 | m.m10*v.x + m.m11*v.y + m.m12 * v.z,
430 | m.m20*v.x + m.m21*v.y + m.m22*v.z
431 | };
432 | return r;
433 | }
434 |
435 | static inline mat4_t mat4_invert(mat4_t m)
436 | {
437 | mat4_t mi = {
438 | m.m11*m.m22*m.m33 + m.m12*m.m23*m.m31 + m.m13*m.m21*m.m32 - m.m11*m.m23*m.m32 - m.m12*m.m21*m.m33 - m.m13*m.m22 * m.m31,
439 | m.m10*m.m23*m.m32 + m.m12*m.m20*m.m33 + m.m13*m.m22*m.m30 - m.m10*m.m22*m.m33 - m.m12*m.m23*m.m30 - m.m13*m.m20 * m.m32,
440 | m.m10*m.m21*m.m33 + m.m11*m.m23*m.m30 + m.m13*m.m20*m.m31 - m.m10*m.m23*m.m31 - m.m11*m.m20*m.m33 - m.m13*m.m21 * m.m30,
441 | m.m10*m.m22*m.m31 + m.m11*m.m20*m.m32 + m.m12*m.m21*m.m30 - m.m10*m.m21*m.m32 - m.m11*m.m22*m.m30 - m.m12*m.m20 * m.m31,
442 | m.m01*m.m23*m.m32 + m.m02*m.m21*m.m33 + m.m03*m.m22*m.m31 - m.m01*m.m22*m.m33 - m.m02*m.m23*m.m31 - m.m03*m.m21 * m.m32,
443 | m.m00*m.m22*m.m33 + m.m02*m.m23*m.m30 + m.m03*m.m20*m.m32 - m.m00*m.m23*m.m32 - m.m02*m.m20*m.m33 - m.m03*m.m22 * m.m30,
444 | m.m00*m.m23*m.m31 + m.m01*m.m20*m.m33 + m.m03*m.m31*m.m30 - m.m00*m.m21*m.m33 - m.m01*m.m23*m.m30 - m.m03*m.m20 * m.m31,
445 | m.m00*m.m21*m.m32 + m.m01*m.m22*m.m30 + m.m02*m.m20*m.m31 - m.m00*m.m22*m.m31 - m.m01*m.m20*m.m32 - m.m02*m.m21 * m.m30,
446 | m.m01*m.m12*m.m33 + m.m02*m.m13*m.m31 + m.m03*m.m11*m.m32 - m.m01*m.m13*m.m32 - m.m02*m.m11*m.m33 - m.m03*m.m12 * m.m31,
447 | m.m00*m.m13*m.m32 + m.m02*m.m10*m.m33 + m.m03*m.m12*m.m30 - m.m00*m.m12*m.m33 - m.m02*m.m13*m.m30 - m.m03*m.m10 * m.m32,
448 | m.m00*m.m11*m.m33 + m.m01*m.m13*m.m30 + m.m03*m.m10*m.m31 - m.m00*m.m13*m.m31 - m.m01*m.m10*m.m33 - m.m03*m.m11 * m.m30,
449 | m.m00*m.m12*m.m31 + m.m01*m.m10*m.m32 + m.m02*m.m11*m.m30 - m.m00*m.m11*m.m32 - m.m01*m.m12*m.m30 - m.m02*m.m10 * m.m31,
450 | m.m01*m.m13*m.m22 + m.m02*m.m11*m.m23 + m.m03*m.m12*m.m21 - m.m01*m.m12*m.m23 - m.m02*m.m13*m.m21 - m.m03*m.m11 * m.m22,
451 | m.m00*m.m12*m.m23 + m.m02*m.m13*m.m20 + m.m03*m.m10*m.m22 - m.m00*m.m13*m.m22 - m.m02*m.m10*m.m23 - m.m03*m.m12 * m.m20,
452 | m.m00*m.m13*m.m21 + m.m01*m.m10*m.m23 + m.m03*m.m11*m.m20 - m.m00*m.m11*m.m23 - m.m01*m.m13*m.m20 - m.m03*m.m10 * m.m21,
453 | m.m00*m.m11*m.m22 + m.m01*m.m12*m.m20 + m.m02*m.m10*m.m21 - m.m00*m.m12*m.m21 - m.m01*m.m10*m.m22 - m.m02*m.m11 * m.m20,
454 | };
455 | return mi;
456 | }
457 |
458 | static inline mat4_t mat4_transpose(mat4_t m)
459 | {
460 | mat4_t mt = {
461 | m.m00, m.m01, m.m02, m.m03,
462 | m.m10, m.m11, m.m12, m.m13,
463 | m.m20, m.m21, m.m22, m.m23,
464 | m.m30, m.m31, m.m32, m.m33
465 | };
466 | return mt;
467 | }
468 |
469 | #endif
470 |
--------------------------------------------------------------------------------
/system_stm32f4xx.c:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file system_stm32f4xx.c
4 | * @author MCD Application Team
5 | * @version V1.0.1
6 | * @date 11-November-2013
7 | * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
8 | * This file is customized to run on STM32F429I-DISCO board only.
9 | *
10 | * The STM32F4xx is configured to run at 180 MHz, following the three
11 | * configuration below:
12 | * - PLL_SOURCE_HSI : HSI (~16MHz) used to clock the PLL, and
13 | * the PLL is used as system clock source.
14 | * - PLL_SOURCE_HSE : HSE (8MHz) used to clock the PLL, and
15 | * the PLL is used as system clock source.
16 | * - PLL_SOURCE_HSE_BYPASS(default): HSE bypassed with an external clock
17 | * (8MHz, coming from ST-Link) used to clock
18 | * the PLL, and the PLL is used as system
19 | * clock source.
20 | *
21 | * 1. This file provides two functions and one global variable to be called from
22 | * user application:
23 | * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
24 | * and Divider factors, AHB/APBx prescalers and Flash settings),
25 | * depending on the configuration made in the clock xls tool.
26 | * This function is called at startup just after reset and
27 | * before branch to main program. This call is made inside
28 | * the "startup_stm32f429_439xx.s" file.
29 | *
30 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
31 | * by the user application to setup the SysTick
32 | * timer or configure other parameters.
33 | *
34 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
35 | * be called whenever the core clock is changed
36 | * during program execution.
37 | *
38 | * 2. After each device reset the HSI (16 MHz) is used as system clock source.
39 | * Then SystemInit() function is called, in "startup_stm32f429_439xx.s" file, to
40 | * configure the system clock before to branch to main program.
41 | *
42 | * 3. If the system clock source selected by user fails to startup, the SystemInit()
43 | * function will do nothing and HSI still used as system clock source. User can
44 | * add some code to deal with this issue inside the SetSysClock() function.
45 | *
46 | * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define
47 | * in "stm32f4xx.h" file. When HSE is used as system clock source, directly or
48 | * through PLL, and you are using different crystal you have to adapt the HSE
49 | * value to your own configuration.
50 | ******************************************************************************
51 | * @attention
52 | *
53 | * © COPYRIGHT 2013 STMicroelectronics
54 | *
55 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
56 | * You may not use this file except in compliance with the License.
57 | * You may obtain a copy of the License at:
58 | *
59 | * http://www.st.com/software_license_agreement_liberty_v2
60 | *
61 | * Unless required by applicable law or agreed to in writing, software
62 | * distributed under the License is distributed on an "AS IS" BASIS,
63 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64 | * See the License for the specific language governing permissions and
65 | * limitations under the License.
66 | *
67 | ******************************************************************************
68 | */
69 |
70 | /** @addtogroup CMSIS
71 | * @{
72 | */
73 |
74 | /** @addtogroup stm32f4xx_system
75 | * @{
76 | */
77 |
78 | /** @addtogroup STM32F4xx_System_Private_Includes
79 | * @{
80 | */
81 |
82 | #include "stm32f4xx.h"
83 |
84 | /**
85 | * @}
86 | */
87 |
88 | /** @addtogroup STM32F4xx_System_Private_TypesDefinitions
89 | * @{
90 | */
91 |
92 | /**
93 | * @}
94 | */
95 |
96 | /** @addtogroup STM32F4xx_System_Private_Defines
97 | * @{
98 | */
99 |
100 | /************************* Miscellaneous Configuration ************************/
101 | /*!< Uncomment the following line if you need to use external SDRAM mounted
102 | on STM32F429I-DISCO board as data memory */
103 | /* #define DATA_IN_ExtSDRAM */
104 |
105 | /*!< Uncomment the following line if you need to relocate your vector Table in
106 | Internal SRAM. */
107 | /* #define VECT_TAB_SRAM */
108 | #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
109 | This value must be a multiple of 0x200. */
110 | /******************************************************************************/
111 |
112 | /************************* PLL Parameters *************************************/
113 | /* Select the PLL clock source */
114 |
115 | //#define PLL_SOURCE_HSI // HSI (~16 MHz) used to clock the PLL, and the PLL is used as system clock source
116 | #define PLL_SOURCE_HSE // HSE (8MHz) used to clock the PLL, and the PLL is used as system clock source
117 | //#define PLL_SOURCE_HSE_BYPASS // HSE bypassed with an external clock (8MHz, coming from ST-Link) used to clock
118 | // the PLL, and the PLL is used as system clock source
119 |
120 |
121 | /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
122 | #if defined (PLL_SOURCE_HSI)
123 | #define PLL_M 16
124 | #else
125 | #define PLL_M 8
126 | #endif
127 | #define PLL_N 360
128 |
129 | /* SYSCLK = PLL_VCO / PLL_P */
130 | #define PLL_P 2
131 |
132 | /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
133 | #define PLL_Q 7
134 |
135 | /******************************************************************************/
136 |
137 |
138 |
139 | /**
140 | * @}
141 | */
142 |
143 | /** @addtogroup STM32F4xx_System_Private_Macros
144 | * @{
145 | */
146 |
147 | /**
148 | * @}
149 | */
150 |
151 | /** @addtogroup STM32F4xx_System_Private_Variables
152 | * @{
153 | */
154 |
155 | uint32_t SystemCoreClock = 180000000;
156 |
157 | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
158 |
159 | /**
160 | * @}
161 | */
162 |
163 | /** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
164 | * @{
165 | */
166 |
167 | static void SetSysClock(void);
168 | #if defined (DATA_IN_ExtSDRAM)
169 | static void SystemInit_ExtMemCtl(void);
170 | #endif /* DATA_IN_ExtSDRAM */
171 |
172 | /**
173 | * @}
174 | */
175 |
176 | /** @addtogroup STM32F4xx_System_Private_Functions
177 | * @{
178 | */
179 |
180 | /**
181 | * @brief Setup the microcontroller system
182 | * Initialize the Embedded Flash Interface, the PLL and update the
183 | * SystemFrequency variable.
184 | * @param None
185 | * @retval None
186 | */
187 | void SystemInit(void)
188 | {
189 | /* FPU settings ------------------------------------------------------------*/
190 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
191 | SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
192 | #endif
193 | /* Reset the RCC clock configuration to the default reset state ------------*/
194 | /* Set HSION bit */
195 | RCC->CR |= (uint32_t)0x00000001;
196 |
197 | /* Reset CFGR register */
198 | RCC->CFGR = 0x00000000;
199 |
200 | /* Reset HSEON, CSSON and PLLON bits */
201 | RCC->CR &= (uint32_t)0xFEF6FFFF;
202 |
203 | /* Reset PLLCFGR register */
204 | RCC->PLLCFGR = 0x24003010;
205 |
206 | /* Reset HSEBYP bit */
207 | RCC->CR &= (uint32_t)0xFFFBFFFF;
208 |
209 | /* Disable all interrupts */
210 | RCC->CIR = 0x00000000;
211 |
212 | #if defined (DATA_IN_ExtSDRAM)
213 | SystemInit_ExtMemCtl();
214 | #endif /* DATA_IN_ExtSDRAM */
215 |
216 | /* Configure the System clock source, PLL Multiplier and Divider factors,
217 | AHB/APBx prescalers and Flash settings ----------------------------------*/
218 | SetSysClock();
219 |
220 | /* Configure the Vector Table location add offset address ------------------*/
221 | #ifdef VECT_TAB_SRAM
222 | SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
223 | #else
224 | SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
225 | #endif
226 | }
227 |
228 | /**
229 | * @brief Update SystemCoreClock variable according to Clock Register Values.
230 | * The SystemCoreClock variable contains the core clock (HCLK), it can
231 | * be used by the user application to setup the SysTick timer or configure
232 | * other parameters.
233 | *
234 | * @note Each time the core clock (HCLK) changes, this function must be called
235 | * to update SystemCoreClock variable value. Otherwise, any configuration
236 | * based on this variable will be incorrect.
237 | *
238 | * @note - The system frequency computed by this function is not the real
239 | * frequency in the chip. It is calculated based on the predefined
240 | * constant and the selected clock source:
241 | *
242 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
243 | *
244 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
245 | *
246 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
247 | * or HSI_VALUE(*) multiplied/divided by the PLL factors.
248 | *
249 | * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value
250 | * 16 MHz) but the real value may vary depending on the variations
251 | * in voltage and temperature.
252 | *
253 | * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value
254 | * 8 MHz), user has to ensure that HSE_VALUE is same as the real
255 | * frequency of the crystal used. Otherwise, this function may
256 | * have wrong result.
257 | *
258 | * - The result of this function could be not correct when using fractional
259 | * value for HSE crystal.
260 | *
261 | * @param None
262 | * @retval None
263 | */
264 | void SystemCoreClockUpdate(void)
265 | {
266 | uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
267 |
268 | /* Get SYSCLK source -------------------------------------------------------*/
269 | tmp = RCC->CFGR & RCC_CFGR_SWS;
270 |
271 | switch (tmp)
272 | {
273 | case 0x00: /* HSI used as system clock source */
274 | SystemCoreClock = HSI_VALUE;
275 | break;
276 | case 0x04: /* HSE used as system clock source */
277 | SystemCoreClock = HSE_VALUE;
278 | break;
279 | case 0x08: /* PLL used as system clock source */
280 |
281 | /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
282 | SYSCLK = PLL_VCO / PLL_P
283 | */
284 | pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
285 | pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
286 |
287 | if (pllsource != 0)
288 | {
289 | /* HSE used as PLL clock source */
290 | pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
291 | }
292 | else
293 | {
294 | /* HSI used as PLL clock source */
295 | pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
296 | }
297 |
298 | pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
299 | SystemCoreClock = pllvco/pllp;
300 | break;
301 | default:
302 | SystemCoreClock = HSI_VALUE;
303 | break;
304 | }
305 | /* Compute HCLK frequency --------------------------------------------------*/
306 | /* Get HCLK prescaler */
307 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
308 | /* HCLK frequency */
309 | SystemCoreClock >>= tmp;
310 | }
311 |
312 | /**
313 | * @brief Configures the System clock source, PLL Multiplier and Divider factors,
314 | * AHB/APBx prescalers and Flash settings
315 | * @Note This function should be called only once the RCC clock configuration
316 | * is reset to the default reset state (done in SystemInit() function).
317 | * @param None
318 | * @retval None
319 | */
320 | static void SetSysClock(void)
321 | {
322 | /******************************************************************************/
323 | /* PLL (clocked by HSE) used as System clock source */
324 | /******************************************************************************/
325 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
326 |
327 |
328 | #ifdef PLL_SOURCE_HSI
329 |
330 | /* Configure the main PLL */
331 | RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
332 | (RCC_PLLCFGR_PLLSRC_HSI) | (PLL_Q << 24);
333 |
334 | #else /* PLL_SOURCE_HSE_BYPASS or PLL_SOURCE_HSE */
335 |
336 | /* Enable HSE */
337 | RCC->CR |= ((uint32_t)RCC_CR_HSEON);
338 | #ifdef PLL_SOURCE_HSE_BYPASS
339 | /* Enable HSE */
340 | RCC->CR |= ((uint32_t)RCC_CR_HSEBYP);
341 | #endif /* PLL_SOURCE_HSE_BYPASS */
342 | /* Wait till HSE is ready and if Time out is reached exit */
343 | do
344 | {
345 | HSEStatus = RCC->CR & RCC_CR_HSERDY;
346 | StartUpCounter++;
347 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
348 |
349 | if ((RCC->CR & RCC_CR_HSERDY) != RESET)
350 | {
351 | HSEStatus = (uint32_t)0x01;
352 | }
353 | else
354 | {
355 | HSEStatus = (uint32_t)0x00;
356 | }
357 |
358 | if (HSEStatus == (uint32_t)0x01)
359 | {
360 | /* Configure the main PLL */
361 | RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
362 | (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
363 |
364 | }
365 | else
366 | { /* If HSE fails to start-up, the application will have wrong clock
367 | configuration. User can add here some code to deal with this error */
368 | }
369 | #endif /*PLL_SOURCE_HSI*/
370 |
371 | /* Select regulator voltage output Scale 1 mode, System frequency up to 180 MHz */
372 | RCC->APB1ENR |= RCC_APB1ENR_PWREN;
373 | PWR->CR |= PWR_CR_VOS;
374 |
375 | /* HCLK = SYSCLK / 1*/
376 | RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
377 |
378 | /* PCLK2 = HCLK / 2*/
379 | RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
380 |
381 | /* PCLK1 = HCLK / 4*/
382 | RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
383 |
384 | /* Enable the main PLL */
385 | RCC->CR |= RCC_CR_PLLON;
386 |
387 | /* Wait till the main PLL is ready */
388 | while((RCC->CR & RCC_CR_PLLRDY) == 0)
389 | {
390 | }
391 |
392 | /* Enable the Over-drive to extend the clock frequency to 180 Mhz */
393 | PWR->CR |= PWR_CR_ODEN;
394 | while((PWR->CSR & PWR_CSR_ODRDY) == 0)
395 | {
396 | }
397 | PWR->CR |= PWR_CR_ODSWEN;
398 | while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
399 | {
400 | }
401 |
402 | /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
403 | FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
404 |
405 | /* Select the main PLL as system clock source */
406 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
407 | RCC->CFGR |= RCC_CFGR_SW_PLL;
408 |
409 | /* Wait till the main PLL is used as system clock source */
410 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
411 | {
412 | }
413 | }
414 |
415 | #ifdef DATA_IN_ExtSDRAM
416 | /**
417 | * @brief Setup the external memory controller.
418 | * Called in startup_stm32f429_439xx.s before jump to main.
419 | * This function configures the external SDRAM mounted on STM32F429I DISCO board
420 | * This SDRAM will be used as program data memory (including heap and stack).
421 | * @param None
422 | * @retval None
423 | */
424 | void SystemInit_ExtMemCtl(void)
425 | {
426 | register uint32_t tmpreg = 0, timeout = 0xFFFF;
427 | register uint32_t index;
428 |
429 | /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
430 | clock */
431 | RCC->AHB1ENR |= 0x000001FC;
432 |
433 | /* Connect PCx pins to FMC Alternate function */
434 | GPIOC->AFR[0] = 0x0000000c;
435 | GPIOC->AFR[1] = 0x00007700;
436 | /* Configure PCx pins in Alternate function mode */
437 | GPIOC->MODER = 0x00a00002;
438 | /* Configure PCx pins speed to 50 MHz */
439 | GPIOC->OSPEEDR = 0x00a00002;
440 | /* Configure PCx pins Output type to push-pull */
441 | GPIOC->OTYPER = 0x00000000;
442 | /* No pull-up, pull-down for PCx pins */
443 | GPIOC->PUPDR = 0x00500000;
444 |
445 | /* Connect PDx pins to FMC Alternate function */
446 | GPIOD->AFR[0] = 0x000000CC;
447 | GPIOD->AFR[1] = 0xCC000CCC;
448 | /* Configure PDx pins in Alternate function mode */
449 | GPIOD->MODER = 0xA02A000A;
450 | /* Configure PDx pins speed to 50 MHz */
451 | GPIOD->OSPEEDR = 0xA02A000A;
452 | /* Configure PDx pins Output type to push-pull */
453 | GPIOD->OTYPER = 0x00000000;
454 | /* No pull-up, pull-down for PDx pins */
455 | GPIOD->PUPDR = 0x00000000;
456 |
457 | /* Connect PEx pins to FMC Alternate function */
458 | GPIOE->AFR[0] = 0xC00000CC;
459 | GPIOE->AFR[1] = 0xCCCCCCCC;
460 | /* Configure PEx pins in Alternate function mode */
461 | GPIOE->MODER = 0xAAAA800A;
462 | /* Configure PEx pins speed to 50 MHz */
463 | GPIOE->OSPEEDR = 0xAAAA800A;
464 | /* Configure PEx pins Output type to push-pull */
465 | GPIOE->OTYPER = 0x00000000;
466 | /* No pull-up, pull-down for PEx pins */
467 | GPIOE->PUPDR = 0x00000000;
468 |
469 | /* Connect PFx pins to FMC Alternate function */
470 | GPIOF->AFR[0] = 0xcccccccc;
471 | GPIOF->AFR[1] = 0xcccccccc;
472 | /* Configure PFx pins in Alternate function mode */
473 | GPIOF->MODER = 0xAA800AAA;
474 | /* Configure PFx pins speed to 50 MHz */
475 | GPIOF->OSPEEDR = 0xAA800AAA;
476 | /* Configure PFx pins Output type to push-pull */
477 | GPIOF->OTYPER = 0x00000000;
478 | /* No pull-up, pull-down for PFx pins */
479 | GPIOF->PUPDR = 0x00000000;
480 |
481 | /* Connect PGx pins to FMC Alternate function */
482 | GPIOG->AFR[0] = 0xcccccccc;
483 | GPIOG->AFR[1] = 0xcccccccc;
484 | /* Configure PGx pins in Alternate function mode */
485 | GPIOG->MODER = 0xaaaaaaaa;
486 | /* Configure PGx pins speed to 50 MHz */
487 | GPIOG->OSPEEDR = 0xaaaaaaaa;
488 | /* Configure PGx pins Output type to push-pull */
489 | GPIOG->OTYPER = 0x00000000;
490 | /* No pull-up, pull-down for PGx pins */
491 | GPIOG->PUPDR = 0x00000000;
492 |
493 | /* Connect PHx pins to FMC Alternate function */
494 | GPIOH->AFR[0] = 0x00C0CC00;
495 | GPIOH->AFR[1] = 0xCCCCCCCC;
496 | /* Configure PHx pins in Alternate function mode */
497 | GPIOH->MODER = 0xAAAA08A0;
498 | /* Configure PHx pins speed to 50 MHz */
499 | GPIOH->OSPEEDR = 0xAAAA08A0;
500 | /* Configure PHx pins Output type to push-pull */
501 | GPIOH->OTYPER = 0x00000000;
502 | /* No pull-up, pull-down for PHx pins */
503 | GPIOH->PUPDR = 0x00000000;
504 |
505 | /* Connect PIx pins to FMC Alternate function */
506 | GPIOI->AFR[0] = 0xCCCCCCCC;
507 | GPIOI->AFR[1] = 0x00000CC0;
508 | /* Configure PIx pins in Alternate function mode */
509 | GPIOI->MODER = 0x0028AAAA;
510 | /* Configure PIx pins speed to 50 MHz */
511 | GPIOI->OSPEEDR = 0x0028AAAA;
512 | /* Configure PIx pins Output type to push-pull */
513 | GPIOI->OTYPER = 0x00000000;
514 | /* No pull-up, pull-down for PIx pins */
515 | GPIOI->PUPDR = 0x00000000;
516 |
517 | /*-- FMC Configuration ------------------------------------------------------*/
518 | /* Enable the FMC interface clock */
519 | RCC->AHB3ENR |= 0x00000001;
520 |
521 | /* Configure and enable SDRAM bank1 */
522 | FMC_Bank5_6->SDCR[0] = 0x000029D0;
523 | FMC_Bank5_6->SDTR[0] = 0x01115351;
524 |
525 | /* SDRAM initialization sequence */
526 | /* Clock enable command */
527 | FMC_Bank5_6->SDCMR = 0x00000011;
528 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
529 | while((tmpreg != 0) && (timeout-- > 0))
530 | {
531 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
532 | }
533 |
534 | /* Delay */
535 | for (index = 0; index<1000; index++);
536 |
537 | /* PALL command */
538 | FMC_Bank5_6->SDCMR = 0x00000012;
539 | timeout = 0xFFFF;
540 | while((tmpreg != 0) && (timeout-- > 0))
541 | {
542 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
543 | }
544 |
545 | /* Auto refresh command */
546 | FMC_Bank5_6->SDCMR = 0x00000073;
547 | timeout = 0xFFFF;
548 | while((tmpreg != 0) && (timeout-- > 0))
549 | {
550 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
551 | }
552 |
553 | /* MRD register program */
554 | FMC_Bank5_6->SDCMR = 0x00046014;
555 | timeout = 0xFFFF;
556 | while((tmpreg != 0) && (timeout-- > 0))
557 | {
558 | tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
559 | }
560 |
561 | /* Set refresh count */
562 | tmpreg = FMC_Bank5_6->SDRTR;
563 | FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
564 |
565 | /* Disable write protection */
566 | tmpreg = FMC_Bank5_6->SDCR[0];
567 | FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
568 |
569 | /*
570 | Bank1_SDRAM is configured as follow:
571 |
572 | FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2;
573 | FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 6;
574 | FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4;
575 | FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 6;
576 | FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2;
577 | FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2;
578 | FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2;
579 |
580 | FMC_SDRAMInitStructure.FMC_Bank = SDRAM_BANK;
581 | FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b;
582 | FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_11b;
583 | FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b;
584 | FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4;
585 | FMC_SDRAMInitStructure.FMC_CASLatency = FMC_CAS_Latency_3;
586 | FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable;
587 | FMC_SDRAMInitStructure.FMC_SDClockPeriod = FMC_SDClock_Period_2;
588 | FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_disable;
589 | FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1;
590 | FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure;
591 | */
592 |
593 | }
594 | #endif /* DATA_IN_ExtSDRAM */
595 |
596 |
597 | /**
598 | * @}
599 | */
600 |
601 | /**
602 | * @}
603 | */
604 |
605 | /**
606 | * @}
607 | */
608 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
609 |
--------------------------------------------------------------------------------
/startup_stm32f429_439xx.S:
--------------------------------------------------------------------------------
1 | /**
2 | ******************************************************************************
3 | * @file startup_stm32f429_439xx.s
4 | * @author MCD Application Team
5 | * @version V1.3.0
6 | * @date 08-November-2013
7 | * @brief STM32F429xx/439xx Devices vector table for RIDE7 toolchain.
8 | * This module performs:
9 | * - Set the initial SP
10 | * - Set the initial PC == Reset_Handler,
11 | * - Set the vector table entries with the exceptions ISR address
12 | * - Configure the clock system and the external SRAM mounted on
13 | * STM324x9I-EVAL board to be used as data memory (optional,
14 | * to be enabled by user)
15 | * - Branches to main in the C library (which eventually
16 | * calls main()).
17 | * After Reset the Cortex-M4 processor is in Thread mode,
18 | * priority is Privileged, and the Stack is set to Main.
19 | ******************************************************************************
20 | * @attention
21 | *
22 | * © COPYRIGHT 2013 STMicroelectronics
23 | *
24 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
25 | * You may not use this file except in compliance with the License.
26 | * You may obtain a copy of the License at:
27 | *
28 | * http://www.st.com/software_license_agreement_liberty_v2
29 | *
30 | * Unless required by applicable law or agreed to in writing, software
31 | * distributed under the License is distributed on an "AS IS" BASIS,
32 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33 | * See the License for the specific language governing permissions and
34 | * limitations under the License.
35 | *
36 | ******************************************************************************
37 | */
38 |
39 | .syntax unified
40 | /*.cpu cortex-m3
41 | .fpu softvfp*/
42 | .thumb
43 |
44 | .global g_pfnVectors
45 | .global Default_Handler
46 |
47 | /* start address for the initialization values of the .data section.
48 | defined in linker script */
49 | .word _sidata
50 | /* start address for the .data section. defined in linker script */
51 | .word _sdata
52 | /* end address for the .data section. defined in linker script */
53 | .word _edata
54 | /* start address for the .bss section. defined in linker script */
55 | .word _sbss
56 | /* end address for the .bss section. defined in linker script */
57 | .word _ebss
58 | /* stack used for SystemInit_ExtMemCtl; always internal RAM used */
59 |
60 | /**
61 | * @brief This is the code that gets called when the processor first
62 | * starts execution following a reset event. Only the absolutely
63 | * necessary set is performed, after which the application
64 | * supplied main() routine is called.
65 | * @param None
66 | * @retval : None
67 | */
68 |
69 | .section .text.Reset_Handler
70 | .weak Reset_Handler
71 | .type Reset_Handler, %function
72 | Reset_Handler:
73 |
74 | /* Copy the data segment initializers from flash to SRAM */
75 | movs r1, #0
76 | b LoopCopyDataInit
77 |
78 | CopyDataInit:
79 | ldr r3, =_sidata
80 | ldr r3, [r3, r1]
81 | str r3, [r0, r1]
82 | adds r1, r1, #4
83 |
84 | LoopCopyDataInit:
85 | ldr r0, =_sdata
86 | ldr r3, =_edata
87 | adds r2, r0, r1
88 | cmp r2, r3
89 | bcc CopyDataInit
90 | ldr r2, =_sbss
91 | b LoopFillZerobss
92 | /* Zero fill the bss segment. */
93 | FillZerobss:
94 | movs r3, #0
95 | str r3, [r2], #4
96 |
97 | LoopFillZerobss:
98 | ldr r3, = _ebss
99 | cmp r2, r3
100 | bcc FillZerobss
101 |
102 | /* Call the clock system intitialization function.*/
103 | bl SystemInit
104 | /* Call the application's entry point.*/
105 | bl main
106 | bx lr
107 | .size Reset_Handler, .-Reset_Handler
108 |
109 | /**
110 | * @brief This is the code that gets called when the processor receives an
111 | * unexpected interrupt. This simply enters an infinite loop, preserving
112 | * the system state for examination by a debugger.
113 | * @param None
114 | * @retval None
115 | */
116 | .section .text.Default_Handler,"ax",%progbits
117 | Default_Handler:
118 | Infinite_Loop:
119 | b Infinite_Loop
120 | .size Default_Handler, .-Default_Handler
121 | /******************************************************************************
122 | *
123 | * The minimal vector table for a Cortex M3. Note that the proper constructs
124 | * must be placed on this to ensure that it ends up at physical address
125 | * 0x0000.0000.
126 | *
127 | *******************************************************************************/
128 | .section .isr_vector,"a",%progbits
129 | .type g_pfnVectors, %object
130 | .size g_pfnVectors, .-g_pfnVectors
131 |
132 |
133 | g_pfnVectors:
134 | .word _estack
135 | .word Reset_Handler
136 | .word NMI_Handler
137 | .word HardFault_Handler
138 | .word MemManage_Handler
139 | .word BusFault_Handler
140 | .word UsageFault_Handler
141 | .word 0
142 | .word 0
143 | .word 0
144 | .word 0
145 | .word SVC_Handler
146 | .word DebugMon_Handler
147 | .word 0
148 | .word PendSV_Handler
149 | .word SysTick_Handler
150 |
151 | /* External Interrupts */
152 | .word WWDG_IRQHandler /* Window WatchDog */
153 | .word PVD_IRQHandler /* PVD through EXTI Line detection */
154 | .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
155 | .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
156 | .word FLASH_IRQHandler /* FLASH */
157 | .word RCC_IRQHandler /* RCC */
158 | .word EXTI0_IRQHandler /* EXTI Line0 */
159 | .word EXTI1_IRQHandler /* EXTI Line1 */
160 | .word EXTI2_IRQHandler /* EXTI Line2 */
161 | .word EXTI3_IRQHandler /* EXTI Line3 */
162 | .word EXTI4_IRQHandler /* EXTI Line4 */
163 | .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
164 | .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
165 | .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
166 | .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
167 | .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
168 | .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
169 | .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
170 | .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
171 | .word CAN1_TX_IRQHandler /* CAN1 TX */
172 | .word CAN1_RX0_IRQHandler /* CAN1 RX0 */
173 | .word CAN1_RX1_IRQHandler /* CAN1 RX1 */
174 | .word CAN1_SCE_IRQHandler /* CAN1 SCE */
175 | .word EXTI9_5_IRQHandler /* External Line[9:5]s */
176 | .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
177 | .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
178 | .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
179 | .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
180 | .word TIM2_IRQHandler /* TIM2 */
181 | .word TIM3_IRQHandler /* TIM3 */
182 | .word TIM4_IRQHandler /* TIM4 */
183 | .word I2C1_EV_IRQHandler /* I2C1 Event */
184 | .word I2C1_ER_IRQHandler /* I2C1 Error */
185 | .word I2C2_EV_IRQHandler /* I2C2 Event */
186 | .word I2C2_ER_IRQHandler /* I2C2 Error */
187 | .word SPI1_IRQHandler /* SPI1 */
188 | .word SPI2_IRQHandler /* SPI2 */
189 | .word USART1_IRQHandler /* USART1 */
190 | .word USART2_IRQHandler /* USART2 */
191 | .word USART3_IRQHandler /* USART3 */
192 | .word EXTI15_10_IRQHandler /* External Line[15:10]s */
193 | .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
194 | .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
195 | .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
196 | .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
197 | .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
198 | .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
199 | .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
200 | .word FSMC_IRQHandler /* FSMC */
201 | .word SDIO_IRQHandler /* SDIO */
202 | .word TIM5_IRQHandler /* TIM5 */
203 | .word SPI3_IRQHandler /* SPI3 */
204 | .word UART4_IRQHandler /* UART4 */
205 | .word UART5_IRQHandler /* UART5 */
206 | .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
207 | .word TIM7_IRQHandler /* TIM7 */
208 | .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
209 | .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
210 | .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
211 | .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
212 | .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
213 | .word ETH_IRQHandler /* Ethernet */
214 | .word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */
215 | .word CAN2_TX_IRQHandler /* CAN2 TX */
216 | .word CAN2_RX0_IRQHandler /* CAN2 RX0 */
217 | .word CAN2_RX1_IRQHandler /* CAN2 RX1 */
218 | .word CAN2_SCE_IRQHandler /* CAN2 SCE */
219 | .word OTG_FS_IRQHandler /* USB OTG FS */
220 | .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
221 | .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
222 | .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
223 | .word USART6_IRQHandler /* USART6 */
224 | .word I2C3_EV_IRQHandler /* I2C3 event */
225 | .word I2C3_ER_IRQHandler /* I2C3 error */
226 | .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
227 | .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
228 | .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
229 | .word OTG_HS_IRQHandler /* USB OTG HS */
230 | .word DCMI_IRQHandler /* DCMI */
231 | .word CRYP_IRQHandler /* CRYP crypto */
232 | .word HASH_RNG_IRQHandler /* Hash and Rng */
233 | .word FPU_IRQHandler /* FPU */
234 | .word UART7_IRQHandler /* UART7 */
235 | .word UART8_IRQHandler /* UART8 */
236 | .word SPI4_IRQHandler /* SPI4 */
237 | .word SPI5_IRQHandler /* SPI5 */
238 | .word SPI6_IRQHandler /* SPI6 */
239 | .word SAI1_IRQHandler /* SAI1 */
240 | .word LTDC_IRQHandler /* LTDC */
241 | .word LTDC_ER_IRQHandler /* LTDC error */
242 | .word DMA2D_IRQHandler /* DMA2D */
243 |
244 | /*******************************************************************************
245 | *
246 | * Provide weak aliases for each Exception handler to the Default_Handler.
247 | * As they are weak aliases, any function with the same name will override
248 | * this definition.
249 | *
250 | *******************************************************************************/
251 | .weak NMI_Handler
252 | .thumb_set NMI_Handler,Default_Handler
253 |
254 | .weak HardFault_Handler
255 | .thumb_set HardFault_Handler,Default_Handler
256 |
257 | .weak MemManage_Handler
258 | .thumb_set MemManage_Handler,Default_Handler
259 |
260 | .weak BusFault_Handler
261 | .thumb_set BusFault_Handler,Default_Handler
262 |
263 | .weak UsageFault_Handler
264 | .thumb_set UsageFault_Handler,Default_Handler
265 |
266 | .weak SVC_Handler
267 | .thumb_set SVC_Handler,Default_Handler
268 |
269 | .weak DebugMon_Handler
270 | .thumb_set DebugMon_Handler,Default_Handler
271 |
272 | .weak PendSV_Handler
273 | .thumb_set PendSV_Handler,Default_Handler
274 |
275 | .weak SysTick_Handler
276 | .thumb_set SysTick_Handler,Default_Handler
277 |
278 | .weak WWDG_IRQHandler
279 | .thumb_set WWDG_IRQHandler,Default_Handler
280 |
281 | .weak PVD_IRQHandler
282 | .thumb_set PVD_IRQHandler,Default_Handler
283 |
284 | .weak TAMP_STAMP_IRQHandler
285 | .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
286 |
287 | .weak RTC_WKUP_IRQHandler
288 | .thumb_set RTC_WKUP_IRQHandler,Default_Handler
289 |
290 | .weak FLASH_IRQHandler
291 | .thumb_set FLASH_IRQHandler,Default_Handler
292 |
293 | .weak RCC_IRQHandler
294 | .thumb_set RCC_IRQHandler,Default_Handler
295 |
296 | .weak EXTI0_IRQHandler
297 | .thumb_set EXTI0_IRQHandler,Default_Handler
298 |
299 | .weak EXTI1_IRQHandler
300 | .thumb_set EXTI1_IRQHandler,Default_Handler
301 |
302 | .weak EXTI2_IRQHandler
303 | .thumb_set EXTI2_IRQHandler,Default_Handler
304 |
305 | .weak EXTI3_IRQHandler
306 | .thumb_set EXTI3_IRQHandler,Default_Handler
307 |
308 | .weak EXTI4_IRQHandler
309 | .thumb_set EXTI4_IRQHandler,Default_Handler
310 |
311 | .weak DMA1_Stream0_IRQHandler
312 | .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
313 |
314 | .weak DMA1_Stream1_IRQHandler
315 | .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
316 |
317 | .weak DMA1_Stream2_IRQHandler
318 | .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
319 |
320 | .weak DMA1_Stream3_IRQHandler
321 | .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
322 |
323 | .weak DMA1_Stream4_IRQHandler
324 | .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
325 |
326 | .weak DMA1_Stream5_IRQHandler
327 | .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
328 |
329 | .weak DMA1_Stream6_IRQHandler
330 | .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
331 |
332 | .weak ADC_IRQHandler
333 | .thumb_set ADC_IRQHandler,Default_Handler
334 |
335 | .weak CAN1_TX_IRQHandler
336 | .thumb_set CAN1_TX_IRQHandler,Default_Handler
337 |
338 | .weak CAN1_RX0_IRQHandler
339 | .thumb_set CAN1_RX0_IRQHandler,Default_Handler
340 |
341 | .weak CAN1_RX1_IRQHandler
342 | .thumb_set CAN1_RX1_IRQHandler,Default_Handler
343 |
344 | .weak CAN1_SCE_IRQHandler
345 | .thumb_set CAN1_SCE_IRQHandler,Default_Handler
346 |
347 | .weak EXTI9_5_IRQHandler
348 | .thumb_set EXTI9_5_IRQHandler,Default_Handler
349 |
350 | .weak TIM1_BRK_TIM9_IRQHandler
351 | .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
352 |
353 | .weak TIM1_UP_TIM10_IRQHandler
354 | .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
355 |
356 | .weak TIM1_TRG_COM_TIM11_IRQHandler
357 | .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
358 |
359 | .weak TIM1_CC_IRQHandler
360 | .thumb_set TIM1_CC_IRQHandler,Default_Handler
361 |
362 | .weak TIM2_IRQHandler
363 | .thumb_set TIM2_IRQHandler,Default_Handler
364 |
365 | .weak TIM3_IRQHandler
366 | .thumb_set TIM3_IRQHandler,Default_Handler
367 |
368 | .weak TIM4_IRQHandler
369 | .thumb_set TIM4_IRQHandler,Default_Handler
370 |
371 | .weak I2C1_EV_IRQHandler
372 | .thumb_set I2C1_EV_IRQHandler,Default_Handler
373 |
374 | .weak I2C1_ER_IRQHandler
375 | .thumb_set I2C1_ER_IRQHandler,Default_Handler
376 |
377 | .weak I2C2_EV_IRQHandler
378 | .thumb_set I2C2_EV_IRQHandler,Default_Handler
379 |
380 | .weak I2C2_ER_IRQHandler
381 | .thumb_set I2C2_ER_IRQHandler,Default_Handler
382 |
383 | .weak SPI1_IRQHandler
384 | .thumb_set SPI1_IRQHandler,Default_Handler
385 |
386 | .weak SPI2_IRQHandler
387 | .thumb_set SPI2_IRQHandler,Default_Handler
388 |
389 | .weak USART1_IRQHandler
390 | .thumb_set USART1_IRQHandler,Default_Handler
391 |
392 | .weak USART2_IRQHandler
393 | .thumb_set USART2_IRQHandler,Default_Handler
394 |
395 | .weak USART3_IRQHandler
396 | .thumb_set USART3_IRQHandler,Default_Handler
397 |
398 | .weak EXTI15_10_IRQHandler
399 | .thumb_set EXTI15_10_IRQHandler,Default_Handler
400 |
401 | .weak RTC_Alarm_IRQHandler
402 | .thumb_set RTC_Alarm_IRQHandler,Default_Handler
403 |
404 | .weak OTG_FS_WKUP_IRQHandler
405 | .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
406 |
407 | .weak TIM8_BRK_TIM12_IRQHandler
408 | .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
409 |
410 | .weak TIM8_UP_TIM13_IRQHandler
411 | .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
412 |
413 | .weak TIM8_TRG_COM_TIM14_IRQHandler
414 | .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
415 |
416 | .weak TIM8_CC_IRQHandler
417 | .thumb_set TIM8_CC_IRQHandler,Default_Handler
418 |
419 | .weak DMA1_Stream7_IRQHandler
420 | .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
421 |
422 | .weak FSMC_IRQHandler
423 | .thumb_set FSMC_IRQHandler,Default_Handler
424 |
425 | .weak SDIO_IRQHandler
426 | .thumb_set SDIO_IRQHandler,Default_Handler
427 |
428 | .weak TIM5_IRQHandler
429 | .thumb_set TIM5_IRQHandler,Default_Handler
430 |
431 | .weak SPI3_IRQHandler
432 | .thumb_set SPI3_IRQHandler,Default_Handler
433 |
434 | .weak UART4_IRQHandler
435 | .thumb_set UART4_IRQHandler,Default_Handler
436 |
437 | .weak UART5_IRQHandler
438 | .thumb_set UART5_IRQHandler,Default_Handler
439 |
440 | .weak TIM6_DAC_IRQHandler
441 | .thumb_set TIM6_DAC_IRQHandler,Default_Handler
442 |
443 | .weak TIM7_IRQHandler
444 | .thumb_set TIM7_IRQHandler,Default_Handler
445 |
446 | .weak DMA2_Stream0_IRQHandler
447 | .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
448 |
449 | .weak DMA2_Stream1_IRQHandler
450 | .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
451 |
452 | .weak DMA2_Stream2_IRQHandler
453 | .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
454 |
455 | .weak DMA2_Stream3_IRQHandler
456 | .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
457 |
458 | .weak DMA2_Stream4_IRQHandler
459 | .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
460 |
461 | .weak ETH_IRQHandler
462 | .thumb_set ETH_IRQHandler,Default_Handler
463 |
464 | .weak ETH_WKUP_IRQHandler
465 | .thumb_set ETH_WKUP_IRQHandler,Default_Handler
466 |
467 | .weak CAN2_TX_IRQHandler
468 | .thumb_set CAN2_TX_IRQHandler,Default_Handler
469 |
470 | .weak CAN2_RX0_IRQHandler
471 | .thumb_set CAN2_RX0_IRQHandler,Default_Handler
472 |
473 | .weak CAN2_RX1_IRQHandler
474 | .thumb_set CAN2_RX1_IRQHandler,Default_Handler
475 |
476 | .weak CAN2_SCE_IRQHandler
477 | .thumb_set CAN2_SCE_IRQHandler,Default_Handler
478 |
479 | .weak OTG_FS_IRQHandler
480 | .thumb_set OTG_FS_IRQHandler,Default_Handler
481 |
482 | .weak DMA2_Stream5_IRQHandler
483 | .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
484 |
485 | .weak DMA2_Stream6_IRQHandler
486 | .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
487 |
488 | .weak DMA2_Stream7_IRQHandler
489 | .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
490 |
491 | .weak USART6_IRQHandler
492 | .thumb_set USART6_IRQHandler,Default_Handler
493 |
494 | .weak I2C3_EV_IRQHandler
495 | .thumb_set I2C3_EV_IRQHandler,Default_Handler
496 |
497 | .weak I2C3_ER_IRQHandler
498 | .thumb_set I2C3_ER_IRQHandler,Default_Handler
499 |
500 | .weak OTG_HS_EP1_OUT_IRQHandler
501 | .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
502 |
503 | .weak OTG_HS_EP1_IN_IRQHandler
504 | .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
505 |
506 | .weak OTG_HS_WKUP_IRQHandler
507 | .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
508 |
509 | .weak OTG_HS_IRQHandler
510 | .thumb_set OTG_HS_IRQHandler,Default_Handler
511 |
512 | .weak DCMI_IRQHandler
513 | .thumb_set DCMI_IRQHandler,Default_Handler
514 |
515 | .weak CRYP_IRQHandler
516 | .thumb_set CRYP_IRQHandler,Default_Handler
517 |
518 | .weak HASH_RNG_IRQHandler
519 | .thumb_set HASH_RNG_IRQHandler,Default_Handler
520 |
521 | .weak FPU_IRQHandler
522 | .thumb_set FPU_IRQHandler,Default_Handler
523 |
524 | .weak UART7_IRQHandler
525 | .thumb_set UART7_IRQHandler,Default_Handler
526 |
527 | .weak UART8_IRQHandler
528 | .thumb_set UART8_IRQHandler,Default_Handler
529 |
530 | .weak SPI4_IRQHandler
531 | .thumb_set SPI4_IRQHandler,Default_Handler
532 |
533 | .weak SPI5_IRQHandler
534 | .thumb_set SPI5_IRQHandler,Default_Handler
535 |
536 | .weak SPI6_IRQHandler
537 | .thumb_set SPI6_IRQHandler,Default_Handler
538 |
539 | .weak SAI1_IRQHandler
540 | .thumb_set SAI1_IRQHandler,Default_Handler
541 |
542 | .weak LTDC_IRQHandler
543 | .thumb_set LTDC_IRQHandler,Default_Handler
544 |
545 | .weak LTDC_ER_IRQHandler
546 | .thumb_set LTDC_ER_IRQHandler,Default_Handler
547 |
548 | .weak DMA2D_IRQHandler
549 | .thumb_set DMA2D_IRQHandler,Default_Handler
550 |
551 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
552 |
--------------------------------------------------------------------------------
/examples/textures/nyan.h:
--------------------------------------------------------------------------------
1 | static const struct { uint16_t w, h; uint8_t d[]; } nyan =
2 | {
3 | 64, 64,
4 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
5 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
6 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
7 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
8 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
9 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
10 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
11 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
12 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
13 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
14 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
15 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
16 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
17 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
18 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
19 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
20 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
21 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
22 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
23 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
24 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
25 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
26 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
27 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
28 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
29 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
30 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
31 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
32 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
33 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
34 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
35 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
36 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
37 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
38 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
39 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
40 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
41 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
42 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
43 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
44 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
45 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
46 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
47 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
48 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
49 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
50 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
51 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
52 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
53 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
54 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
55 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
56 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
57 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
58 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
59 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
60 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
61 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
62 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
63 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
64 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
65 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
66 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
67 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
68 | "\377\377\377\377\337\377\377\377\377\377\377\377\377\377\377\377\377\377"
69 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
70 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
71 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
72 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
73 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
74 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
75 | "\377\377\377\377\337\377\377\377\377\377\377\377\377\377\377\377\377\377"
76 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
77 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
78 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
79 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
80 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
81 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
82 | "\377\377\377\377\377\377\337\377\377\377\377\377\377\377\377\377\377\377"
83 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
84 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
85 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
86 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
87 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
88 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
89 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
90 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
91 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
92 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
93 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
94 | "\377\377\377\377\377\377\377\377\337\377\337\377\377\377\377\377\377\377"
95 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
96 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
97 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
98 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
99 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
100 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
101 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
102 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
103 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
104 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
105 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
106 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
107 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
108 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
109 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
110 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
111 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
112 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
113 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
114 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
115 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
116 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
117 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
118 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
119 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
120 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
121 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
122 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
123 | "\377\377\377\377\337\377\337\377\337\377\377\377\377\377\377\377\377\377"
124 | "\377\377\377\377\337\377\377\377\377\377\377\377\377\377\377\377\377\377"
125 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
126 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
127 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
128 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
129 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
130 | "\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377\337\377"
131 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
132 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
133 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
134 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
135 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
136 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
137 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
138 | "\377\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
139 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
140 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
141 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
142 | "\377\377\377\377\377\377\377\377\377\377\377\377\336\377\337\377\377\377"
143 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
144 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
145 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
146 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
147 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
148 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
149 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\337\377"
150 | "\337\377\377\377\377\377\336\377\377\377\377\377\377\377\377\377\377\377"
151 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
152 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
153 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
154 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
155 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
156 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377A\10\0\0\202\10\0"
157 | "\0\0\0\0\0\0\0\0\0\0\0\40\0\40\0\0\0\0\0\0\0\40\0A\10\0\0\40\0\377\377\337"
158 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
159 | "\377\377\377\377\377\377\377\377\377\40\372a\372\202\372@\372\377\377\377"
160 | "\377\377\377\377\377\377\377\377\377\377\377\201\372\40\372A\372\40\372a"
161 | "\372A\372\377\377\377\377\377\377\377\377\377\377\377\377\202\372\40\372"
162 | "b\372A\372A\372\40\372\0\372\40\10\265\376\265\376\265\376\225\376\325\376"
163 | "\325\376\265\376\264\376\265\376\264\376\264\376\265\376\264\376\265\376"
164 | "\325\376\266\376\325\376\326\376@\10\377\377\377\377\377\377\377\377\377"
165 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
166 | "\377@\372\40\372\40\372\40\372b\372\202\372A\372\202\372\202\372A\372A\372"
167 | "\40\372\0\372\40\372\0\372\0\372\0\372a\372\40\372A\372\40\372A\372\202\372"
168 | "\40\372\0\372\0\372\0\372\0\372\0\372\201\20\325\376\264\376\264\376\233"
169 | "\375Z\375z\375\233\375Z\375z\375\232\375\233\375z\375{\375\233\375\233\375"
170 | "z\375\232\375\264\376\224\376\265\376\0\0\377\377\377\377\377\377\377\377"
171 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
172 | "a\372\40\372\40\372A\372\40\372\0\372\0\372\0\372\0\372\40\372\0\372!\372"
173 | "\0\372\40\372a\372!\372\40\372\40\372\40\372\40\372\0\372\0\372\40\372\40"
174 | "\372\0\372\40\372A\372\40\372\40\372\202\10\264\376\264\376\233\375Z\375"
175 | "Z\375Z\375Z\3757\373:\375Z\375Z\375Z\375\366\372:\375Z\375Z\375Z\375\232"
176 | "\375\264\376\264\376\0\0\377\377\377\377\377\377\377\377\377\377\377\377"
177 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377c\375@\375a\375b"
178 | "\375a\372\0\372A\372\40\372\40\372\40\372a\372b\375a\375@\375A\375@\375@"
179 | "\375@\372\40\372!\372\0\372\40\372b\372\202\375@\375@\375@\375@\375`\375"
180 | "\303\40\265\376\272\375Z\375\326\372Z\375Z\375Z\375:\375Z\375Z\375Z\375Z"
181 | "\375:\375:\375Z\375{\375\326\372\32\375Z\375\264\376\0\0\337\377\377\377"
182 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
183 | "\377\377\377\377@\375@\375@\375@\375b\375a\375a\375a\375b\375a\375@\375@"
184 | "\375@\375@\375@\375@\375@\375A\375@\375A\375@\375@\375A\375@\375@\375@\375"
185 | "@\375@\375@\375\202\20\265\376Z\375Z\375:\375:\375Z\375Z\375Z\375Z\375z\375"
186 | "{\375Z\375Z\375\207A\207AY\355Z\375:\375Z\375\264\376\0\0\337\377\337\377"
187 | "\303\30\343\30\336\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
188 | "\377\377\377A\375@\375@\375@\375@\375@\375\40\375\40\375@\375@\375@\375b"
189 | "\375a\375A\375@\375@\375@\375@\375@\375@\375@\375\40\375@\375A\375A\375@"
190 | "\375@\375@\375@\375A\10\325\376Z\375Z\375Z\375Z\375{\375Z\375Z\375:\375\225"
191 | "\372Z\375Z\375\303\30""4\245\24\245\303\30Z\375Z\375z\375\265\376\0\0\376"
192 | "\377e)T\2454\255HJ\337\377\377\377\377\377\377\377\377\377\377\377\377\377"
193 | "\377\377\341\377\343\377\342\377\341\377`\375\40\375@\375@\375@\375@\375"
194 | "a\375\346\377\341\377\345\377\342\377\345\377\347\377A\375@\375@\375@\375"
195 | "@\375\200\375\340\377\340\377\340\377\340\377\341\377\345\377\242\20\265"
196 | "\376Z\375:\375:\375Z\375z\375Z\375:\375Z\375:\375z\375Z\375\243\20""4\245"
197 | "T\245T\255\242\20z\375Z\375\264\376E)\3\31""4\255T\2555\255E)\377\377\377"
198 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\340\377\340\377\342"
199 | "\377\342\377\343\377\342\377\342\377\344\377\347\377\350\377\342\377\341"
200 | "\377\340\377\340\377\340\377\341\377\343\377\342\377\343\377\343\377\344"
201 | "\377\343\377\341\377\340\377B)\3029\343\377\340\377\340\377\0\0\325\376z"
202 | "\375Z\375Z\375Z\375Z\375\225\372z\375Z\375Z\375Z\375Z\375\242\20T\2554\255"
203 | "T\2554\245E)\303\30\303\30\4\31""4\255U\2554\245T\255E)\377\377\377\377\377"
204 | "\377\377\377\377\377\377\377\377\377\377\377\341\377\340\377\340\377\340"
205 | "\377\340\377\340\377\340\377\340\377\340\377\340\377\340\377\343\377\340"
206 | "\377\342\377\346\377\345\377\341\377\340\377\340\377\340\377\340\377\340"
207 | "\377\342\377#)T\2554\255$!\341\377\340\377\40\0\325\376Z\375Z\375Z\375Z\375"
208 | "[\375:\375Z\375Z\375Z\375Z\375Z\375\242\20T\2554\245T\255T\255T\255T\255"
209 | "T\255T\255U\255T\2554\2554\255\303\30\377\377\377\377\377\377\377\377\377"
210 | "\377\377\377\377\377\377\377\353\267\351\257\350\257\353\267\340\377\340"
211 | "\377\342\377\340\377\341\377\341\377\341\377\353\267\353\267\351\257\352"
212 | "\267\350\257\352\267\350\377\341\377\346\377\343\377\340\377\353\377\242"
213 | "\20T\2554\245\242\20\242\20\242\20$!\326\376z\375\325\372:\375Z\375Z\375"
214 | "Z\375Z\375Z\3755\372\371\374%)\363\2344\245T\255T\2454\255T\2555\255T\255"
215 | "T\255T\2554\255U\245U\255T\255\3069\377\377\377\377\377\377\377\377\377\377"
216 | "\377\377\377\377\347\257\347\257\347\257\350\257\352\267\351\257\353\267"
217 | "\351\257\352\267\352\267\354\277\350\257\347\257\347\247\350\257\347\257"
218 | "\347\257\350\257\350\257\353\267\351\257\351\257\352\267\355\277e)U\2554"
219 | "\255T\255T\255f)\325\376[\375:\375:\375Z\375Z\375z\375Z\375Z\375\32\375Z"
220 | "\375\202\20""4\245T\255U\255\337\377$!T\255T\255T\2554\255T\255\377\377\4"
221 | "!4\2454\255\343\30\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
222 | "\352\267\350\257\347\257\347\257\347\257\347\247\347\257\347\257\347\257"
223 | "\347\257\350\257\352\267\347\257\350\257\350\257\350\257\347\257\347\257"
224 | "\347\257\347\257\347\247\347\257\347\257\347\257\350\257\243\30\243\20T\255"
225 | "4\255\302\30\325\376{\375Z\375Z\375Z\375Z\375Z\375Z\375Z\375Z\375:\375\242"
226 | "\20""4\255U\255T\255\242\20\242\20T\255T\255T\255\20514\255\302\30\242\30"
227 | """4\245T\255D)\377\377\377\377\377\377\377\377\377\377\377\377\377\377\177"
228 | "\15\177\25\177\15_\5\350\257\350\257\350\257\350\257\347\257\347\247\347"
229 | "\257\237\35_\5\177\15\177\25_\15\177\25\352\267\351\267\347\257\347\257\351"
230 | "\257\350\257\350\257\3375\277%\237%\344\40\242\20E!\264\376z\375Z\375Z\375"
231 | ":\375Y\3755\372Z\375Z\375Z\375Z\375\243\20T\255\324\373\324\373T\255U\255"
232 | "T\255T\2554\2554\255T\255T\2554\255\324\373\324\373$!\337\377\377\377\377"
233 | "\377\377\377\377\377\377\377\377\377_\5_\5_\5_\5_\15_\15_\15\177\25\177\15"
234 | "\177\25\177\25_\5_\5_\5_\5_\5_\5\177\25\177\25\177\15\177\15\177\15_\5_\5"
235 | "_\5_\5_\5_\15\177\25\242\20\265\376\264\376{\375\225\372:\375Z\375:\375Z"
236 | "\375Z\375Z\375Z\375\242\20T\245\324\373\324\373T\255$!4\245U\255\343\30""4"
237 | "\255T\255(BT\255\364\363\324\373\302\30\377\377\377\377\377\377\377\377\377"
238 | "\377\377\377\377\377_\15_\5_\15_\15_\5_\5_\5?\5_\5_\5\177\15\177\25_\5_\15"
239 | "_\5?\5_\5_\15\177\5?\5?\5_\5_\5_\5\177\15\177\15?\5_\5\177\25\0\0\264\376"
240 | "\264\376\264\376\231\374\32\375Z\375Z\375Z\375Z\375Z\375Z\375[\375$)4\245"
241 | "U\2554\255\303\30\303\30\242\20\242\20\303\30\343\30\303\30\24\255T\255E"
242 | "!\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\277\332"
243 | "?\332?\332\177\322_\5_\15\177\15_\5_\15_\5?\5_\332?\322_\332\237\322\177"
244 | "\332_\332\177\15_\5_\5\177\15_\5_\5\237\25?\332\377\321\377\321_\322\37\322"
245 | "\0\0\302\30\265\376\264\376\225\376u\376\264\376\224\376\264\376\264\376"
246 | "\225\376u\376\225\376\264\376\343\30T\255U\255T\255T\2555\2555\2554\245T"
247 | "\255T\255T\255\242\20\337\377\377\377\377\377\377\377\377\377\377\377\377"
248 | "\377\377\377\377\377?\322\37\322\37\332?\332\237\332\237\332_\332\177\322"
249 | "_\332_\332\177\322\37\322\37\322\37\332?\332?\322\37\332\177\322_\322_\332"
250 | "?\322?\332?\322?\332\377\321?\322\37\322\37\332\0\0\24\245T\255\302\30\0"
251 | "\0\303\20$!\243\20\242\30\242\20@\10\0\0A\10a\10\202\30\303\30\3!\343\30"
252 | "\303\30\303\30\343\40\343\30\3079\3!\302\20\302\30\377\377\377\377\377\377"
253 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377_\332_\322_\322_"
254 | "\322\37\332\37\322\37\322\37\322?\322\37\322?\322?\322_\332?\322?\322?\322"
255 | "?\322?\322\37\332\37\322\37\322?\322?\332?\322_\332?\322?\322\37\322\0\0"
256 | "\24\245T\255\243\20\276\367$!T\255T\255T\255\242\20\377\377\377\377\377\377"
257 | "\377\377\377\377\336\377\243\20T\2454\255\243\30\377\377\302\20""4\2454\255"
258 | "\302\30\377\377\337\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
259 | "\377\377\377\377\377\377\377\377\377\377\377\377\377_\332?\322_\332?\322"
260 | "\237\332\37\322?\332\377\377\377\377\377\377\377\377\377\377\377\377_\332"
261 | "\237\322_\332_\322?\332\37\322?\322\377\377\377\377\377\377\377\377\242\20"
262 | "e)\303\30\377\377\337\377\377\377\343\30a\10\343\30\303\30\377\377\377\377"
263 | "\377\377\377\377\377\377\377\377\377\377\303\30\242\20\343\30\377\377\377"
264 | "\377\242\30\201\20\303\30\377\377\377\377\377\377\377\377\377\377\377\377"
265 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
266 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
267 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
268 | "\377\377\277\377\377\377\377\377\377\377\377\377\377\377\377\377\337\377"
269 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\337\377\377\377"
270 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
271 | "\337\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
272 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
273 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
274 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
275 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
276 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\337\377\377\377"
277 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
278 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
279 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
280 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
281 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
282 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
283 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
284 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
285 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
286 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
287 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
288 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
289 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
290 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
291 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
292 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
293 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
294 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
295 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
296 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
297 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
298 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
299 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
300 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
301 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
302 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
303 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
304 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
305 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
306 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
307 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
308 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
309 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
310 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
311 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
312 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
313 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
314 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
315 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
316 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
317 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
318 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
319 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
320 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
321 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
322 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
323 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
324 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
325 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
326 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
327 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
328 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
329 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
330 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
331 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
332 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
333 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
334 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
335 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
336 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
337 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
338 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
339 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
340 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
341 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
342 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
343 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
344 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
345 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
346 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
347 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
348 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
349 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
350 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
351 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
352 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
353 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
354 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
355 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
356 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
357 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
358 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
359 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
360 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
361 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
362 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
363 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
364 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
365 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
366 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
367 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
368 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
369 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
370 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
371 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
372 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
373 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
374 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
375 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
376 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
377 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
378 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
379 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
380 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
381 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
382 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
383 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
384 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
385 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
386 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
387 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
388 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
389 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
390 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
391 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
392 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
393 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
394 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
395 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
396 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
397 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
398 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
399 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
400 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
401 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
402 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
403 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
404 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
405 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
406 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
407 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
408 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
409 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
410 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
411 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
412 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
413 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
414 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
415 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
416 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
417 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
418 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
419 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
420 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
421 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
422 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
423 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
424 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
425 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
426 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
427 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
428 | "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
429 | "\377\377"
430 | };
431 |
432 |
--------------------------------------------------------------------------------