├── assets ├── pdf │ └── readme.txt └── images │ └── readme.txt ├── doxygen ├── assets │ ├── images │ │ ├── placeholder │ │ └── search │ │ │ ├── mag_sel.png │ │ │ ├── search_l.jpg │ │ │ ├── search_m.jpg │ │ │ └── search_r.jpg │ ├── include │ │ ├── footer.html │ │ └── header.html │ ├── javascripts │ │ └── resize.js │ └── stylesheets │ │ ├── navtree.css │ │ ├── search │ │ └── search.css │ │ └── doxygen.css ├── build.xml └── config │ └── layout.xml ├── TODO ├── Target.comarker ├── .gitignore ├── app ├── cmsis_boot │ ├── stm32f10x.h │ ├── system_stm32f10x.h │ ├── stm32f10x_conf.h │ └── startup │ │ └── startup_stm32f10x_md.c ├── helpers.h ├── CustomStructs │ ├── GeneralMacros.h │ ├── time.h │ ├── WebService.h │ ├── time.c │ └── KeyValuePair.h ├── Server │ ├── WebServerConfig.c │ ├── WebServerConfig.h │ ├── WebServer.h │ └── WebServer.c ├── Config │ ├── USART1_Config.h │ ├── USART3_Config.h │ ├── USART1_Config.c │ └── USART3_Config.c ├── dimmerConfig │ └── globalDefines.h ├── esp8266 │ ├── include │ │ └── esp8266.h │ └── source │ │ └── esp8266.c ├── main.c └── cmsis │ ├── core_cmFunc.h │ └── core_cmInstr.h ├── Wifi_Dimmer.comemgui ├── semihosting ├── semihosting.h ├── semihosting.c └── sh_cmd.s ├── README.md~ ├── README.md ├── Target.cogui ├── Wifi_Dimmer.comarker ├── stdio └── printf.c └── Wifi_Dimmer.coproj /assets/pdf/readme.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/readme.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doxygen/assets/images/placeholder: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | #STM32-F103_CortexM3-ESP8266-Dimmer Project Todo File 2 | -------------------------------------------------------------------------------- /Target.comarker: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.ko 3 | *.obj 4 | *.elf 5 | 6 | Wifi_Dimmer/* 7 | Wifi_Dimmer/Debug/ 8 | -------------------------------------------------------------------------------- /app/cmsis_boot/stm32f10x.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbagel2/stm32-f103-CortexM3-ESP8266-Dimmer/HEAD/app/cmsis_boot/stm32f10x.h -------------------------------------------------------------------------------- /doxygen/assets/images/search/mag_sel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbagel2/stm32-f103-CortexM3-ESP8266-Dimmer/HEAD/doxygen/assets/images/search/mag_sel.png -------------------------------------------------------------------------------- /doxygen/assets/images/search/search_l.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbagel2/stm32-f103-CortexM3-ESP8266-Dimmer/HEAD/doxygen/assets/images/search/search_l.jpg -------------------------------------------------------------------------------- /doxygen/assets/images/search/search_m.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbagel2/stm32-f103-CortexM3-ESP8266-Dimmer/HEAD/doxygen/assets/images/search/search_m.jpg -------------------------------------------------------------------------------- /doxygen/assets/images/search/search_r.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbagel2/stm32-f103-CortexM3-ESP8266-Dimmer/HEAD/doxygen/assets/images/search/search_r.jpg -------------------------------------------------------------------------------- /Wifi_Dimmer.comemgui: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/helpers.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _HELPERS_H 3 | #define _HELPERS_H 4 | 5 | #include "stm32f10x.h" 6 | #include "misc.h" 7 | 8 | #define countof(a) (sizeof(a) / sizeof(*(a))) 9 | 10 | #endif //_HELPERS_H 11 | -------------------------------------------------------------------------------- /app/CustomStructs/GeneralMacros.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef _MYMACROS_H_ 4 | #define _MYMACROS_H_ 5 | 6 | //Calculate array size 7 | //#define ARRAYSIZE(x) (sizeof x/sizeof x[0]) 8 | 9 | 10 | #endif // _MYMACROS_H_ 11 | -------------------------------------------------------------------------------- /app/Server/WebServerConfig.c: -------------------------------------------------------------------------------- 1 | 2 | #include "WebServerConfig.h" 3 | 4 | 5 | 6 | char webResponse[RESPONSE_BUFFER_SIZE]; 7 | 8 | const char *ValidQueryStrings[4] = {"Dim","Reset","Settings","Status"}; // Query strings that are valid 9 | -------------------------------------------------------------------------------- /doxygen/assets/include/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/Server/WebServerConfig.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef _WEBSERVERCONFIG_H_ 4 | #define _WEBSERVERCONFIG_H_ 5 | 6 | #include "globalDefines.h" 7 | //#define RESPONSE_BUFFER_SIZE 1000 8 | 9 | //Modify this section to reflect your valid rest query strings 10 | 11 | const typedef enum {Dim,Reset,Settings,Status}REST_ValidQueryStrings; // The query strings that are accepted by the rest call 12 | const char *ValidQueryStrings[4]; // Query strings that are valid 13 | 14 | 15 | 16 | 17 | #endif // _WEBSERVERCONFIG_H_ 18 | -------------------------------------------------------------------------------- /app/Config/USART1_Config.h: -------------------------------------------------------------------------------- 1 | #ifndef _USART1_CONFIG_H 2 | #define _USART1_CONFIG_H 3 | 4 | #include "stm32f10x_gpio.h" 5 | #include "stm32f10x_usart.h" 6 | #include "misc.h" 7 | #include "stm32f10x_rcc.h" 8 | 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | void Init_USART1(uint32_t baud, FunctionalState USART1_Interrupts); 15 | void USART1_SendString(char *MessageToSend); 16 | void USART1_IRQHandler(void); 17 | 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif /* _USART1_CONFIG_H */ 24 | -------------------------------------------------------------------------------- /app/CustomStructs/time.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _TIME_H_ 3 | #define _TIME_H_ 4 | 5 | #include 6 | #include "stm32f10x.h" 7 | #include "stm32f10x_rcc.h" 8 | 9 | volatile uint32_t microseconds; 10 | 11 | typedef enum{ 12 | SECOND = 1, 13 | MILLISEC = 1000, 14 | MICROSEC = 1000000 15 | }Time_Resolution; 16 | 17 | 18 | void Init_Time(Time_Resolution res); 19 | 20 | void Delay(uint16_t milliseconds); 21 | 22 | //uint32_t Micros(); 23 | 24 | uint32_t Millis(); 25 | 26 | 27 | //systick interrupt 28 | 29 | 30 | #endif // _TIME_H_ 31 | -------------------------------------------------------------------------------- /app/CustomStructs/WebService.h: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************** 3 | * Author: Jacob Pagel 4 | * Date: 03/05/2015 5 | * Custom webserver specific types 6 | ********************************************************/ 7 | 8 | /* 9 | typedef struct 10 | { 11 | char *HttpStatusCode; 12 | char *Body; 13 | char *Headers[]; 14 | 15 | }HTTPResponse; 16 | 17 | 18 | typedef struct // Response object that will be transmitted back 19 | { 20 | char *uriAbsolute; 21 | char *body; 22 | Header headers[]; 23 | 24 | }HTTPRequest; 25 | 26 | */ 27 | -------------------------------------------------------------------------------- /app/CustomStructs/time.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "time.h" 4 | 5 | volatile uint32_t millis = 0; 6 | 7 | void Init_Time(Time_Resolution res) 8 | { 9 | SysTick_Config((SystemCoreClock/res)); 10 | 11 | //Just making sure that the Systick Interrupt is top priority 12 | //Or the timer wont be accurate 13 | NVIC_SetPriority(SysTick_IRQn, 0); 14 | 15 | } 16 | 17 | /* 18 | void Delay(uint16_t milliseconds) 19 | { 20 | 21 | } 22 | */ 23 | /* 24 | uint32_t Micros() 25 | { 26 | 27 | } 28 | */ 29 | uint32_t Millis() 30 | { 31 | return millis; 32 | } 33 | 34 | void SysTick_Handler() 35 | { 36 | 37 | millis++; 38 | } 39 | 40 | // 41 | -------------------------------------------------------------------------------- /app/CustomStructs/KeyValuePair.h: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************** 3 | * Author: Jacob Pagel 4 | * Date: 03/05/2015 5 | * Custom key value pair types variable types 6 | ********************************************************/ 7 | 8 | #ifndef _KEYVALUEPAIRS_H_ 9 | #define _KEYVALUEPAIRS_H_ 10 | 11 | 12 | #include 13 | 14 | typedef struct 15 | { 16 | char *key; 17 | char *value; 18 | 19 | }KeyValuePair_StringString; 20 | 21 | typedef struct 22 | { 23 | char *key; 24 | uint16_t value; 25 | 26 | }KeyValuePair_StringUint16_t; 27 | 28 | typedef struct 29 | { 30 | uint16_t key; 31 | uint16_t value; 32 | 33 | }KeyValuePair_Uint16_tUint16_t; 34 | 35 | 36 | 37 | #endif // _KEYVALUEPAIRS_H_ 38 | -------------------------------------------------------------------------------- /app/Config/USART3_Config.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | #ifndef _USART3_CONFIG_H 8 | #define _USART3_CONFIG_H 9 | 10 | #include "stm32f10x_gpio.h" 11 | #include "stm32f10x_usart.h" 12 | #include "misc.h" 13 | #include "stm32f10x_rcc.h" 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | void Init_USART3(uint32_t baud, FunctionalState USART3_Interrupts); 20 | void Init_USART3_DMA(uint32_t baud, volatile char DMA_RxBuffer[], uint16_t BufSize); 21 | //void USART3_Send_AT_TEST();//Just send the basic AT command looking for a ready response 22 | //void USART3_SendString(char *MessageToSend); 23 | void USART3_IRQHandler(void); 24 | void DMA_Initialize(volatile char DMA_RxBuffer[], uint16_t BufSize); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif /* _USART3_CONFIG_H */ 31 | -------------------------------------------------------------------------------- /semihosting/semihosting.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file semihosting.h 4 | * @author Coocox 5 | * @version V1.0 6 | * @date 09/10/2011 7 | * @brief Semihosting Low Layer GetChar/SendChar API. 8 | * 9 | ******************************************************************************* 10 | */ 11 | #ifndef __SIMIHOSTTING_IMPL 12 | #define __SIMIHOSTTING_IMPL 13 | 14 | /********************************************************************************************************//** 15 | * Semihosting functions prototype 16 | ************************************************************************************************************/ 17 | extern int SH_DoCommand(int n32In_R0, int n32In_R1, int *pn32Out_R0); 18 | void SH_SendChar(int ch); 19 | void SH_SendString(const char *str); 20 | char SH_GetChar(void); 21 | 22 | 23 | #endif 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/dimmerConfig/globalDefines.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef __GLOBALDEFINES_H__ 4 | #define __GLOBALDEFINES_H__ 5 | 6 | /* 7 | * General variable definitions that need to be available project wide 8 | * ie..(buffer sizes, timeout values, delay values) 9 | */ 10 | 11 | 12 | #define ESP_ResponseTimeout_ms 6000 13 | #define ESP_USART USART3 14 | #define DEBUG_CMD_USART USART1 15 | 16 | 17 | //USART buffers and related 18 | #define RxBuffSize 1000 19 | #define USART_TxComplete_Timeout_ms 1000 20 | #define DMA_Rx_Buff_Poll_Int_ms 500 21 | 22 | //Wifi related Variables and declarations 23 | #define WIFI_COMMAND_ERROR "ERROR" // Expected response from ESP8266 on error 24 | #define WIFI_COMMAND_ACCEPTED "OK" // Expected response from ESP8266 on successful command process 25 | #define WIFI_RX_LineComplete = "\r\n" 26 | 27 | 28 | //WebServer related defines 29 | #define RESPONSE_BUFFER_SIZE 300 30 | 31 | 32 | //Helpful Macros 33 | #define countof(a) (sizeof(a) / sizeof(*(a))) 34 | #define ARRAYSIZE(x) (sizeof(x)/sizeof (x)[0]) // Need to test this one.. I think its broken. 35 | 36 | 37 | #endif //#ifndef __GLOBALDEFINES_H__ 38 | -------------------------------------------------------------------------------- /doxygen/assets/include/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | $projectname: $title 9 | $title 10 | 11 | 12 | 13 | $treeview 14 | $search 15 | $mathjax 16 | 17 | $extrastylesheet 18 | 19 | 20 |
21 | 22 | 23 |
24 | $searchbox 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /doxygen/assets/javascripts/resize.js: -------------------------------------------------------------------------------- 1 | var cookie_namespace = 'doxygen'; 2 | var sidenav,navtree,content,header; 3 | 4 | function readCookie(cookie) 5 | { 6 | var myCookie = cookie_namespace+"_"+cookie+"="; 7 | if (document.cookie) 8 | { 9 | var index = document.cookie.indexOf(myCookie); 10 | if (index != -1) 11 | { 12 | var valStart = index + myCookie.length; 13 | var valEnd = document.cookie.indexOf(";", valStart); 14 | if (valEnd == -1) 15 | { 16 | valEnd = document.cookie.length; 17 | } 18 | var val = document.cookie.substring(valStart, valEnd); 19 | return val; 20 | } 21 | } 22 | return 0; 23 | } 24 | 25 | function writeCookie(cookie, val, expiration) 26 | { 27 | if (val==undefined) return; 28 | if (expiration == null) 29 | { 30 | var date = new Date(); 31 | date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week 32 | expiration = date.toGMTString(); 33 | } 34 | document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; expires=" + expiration+"; path=/"; 35 | } 36 | 37 | function resizeWidth() 38 | { 39 | 40 | } 41 | 42 | function restoreWidth(navWidth) 43 | { 44 | 45 | } 46 | 47 | function resizeHeight() 48 | { 49 | } 50 | 51 | function initResizable() 52 | { 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /doxygen/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/Server/WebServer.h: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************** 3 | * Author: Jacob Pagel 4 | * Date: 03/05/2015 5 | * WebServer.h (WebServer library include file) 6 | ********************************************************/ 7 | 8 | #ifndef _WEBSERVER_H_ 9 | #define _WEBSERVER_H_ 10 | 11 | #include "CustomStructs/KeyValuePair.h" 12 | #include "WebServerConfig.h" 13 | #include "esp8266.h" 14 | #include "CustomStructs/GeneralMacros.h" 15 | 16 | typedef KeyValuePair_StringString Header; 17 | 18 | const typedef enum {GET=0,POST,PUT,DELETE}Http_Method_Enum; // The rest call types that we know what to do with 19 | const char *HTTP_Method[4]; 20 | 21 | #define HttpMethod(methodEnum) (HTTP_Method[(methodEnum)]) // Converts the enum to its corresponding string representation 22 | 23 | 24 | const typedef enum {ContentType,ContentLength,Accept,AcceptEncoding,Host,UserAgent}RequestHeaders_Types; 25 | const char *RequestHeaders_Array[6]; 26 | 27 | #define HeaderKey(headerType) (RequestHeaders_Array[(headerType)]) // Testing macro to retrieve headerArray value 28 | 29 | typedef struct 30 | { 31 | char *HttpStatusCode; 32 | char *Body; 33 | char *Headers[]; 34 | 35 | }HTTPResponse; 36 | 37 | 38 | typedef struct // Response object that will be transmitted back 39 | { 40 | char *uriAbsolute; 41 | char *body; 42 | Header headers[]; 43 | 44 | }HTTPRequest; 45 | 46 | 47 | 48 | void buildHeader(Header *newHeaderOut, RequestHeaders_Types type, char *headerValue); 49 | void SendRESTResponse(uint8_t connectionNum, const char *responseHeaders, const char *responseBody); 50 | void StartServer(uint8_t serverNum, uint16_t portNum); 51 | void SendWebRequestResponse(uint8_t connectionNum); 52 | 53 | /* 54 | * 55 | * TEST ARRAYS FOR DEBUGGING ONLY 56 | * 57 | * 58 | */ 59 | 60 | const char *RESTResponse_Headers_Test_OK; //Just here for testing as this is just a static OK 200 response 61 | 62 | 63 | const char *RESTResponse_Body_TEST_JSON; 64 | 65 | 66 | 67 | 68 | 69 | 70 | #endif // _WEBSERVER_H_ 71 | -------------------------------------------------------------------------------- /semihosting/semihosting.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file semihosting.c 4 | * @author Coocox 5 | * @version V1.0 6 | * @date 09/10/2011 7 | * @brief Semihosting LowLayer GetChar/SendChar Implement. 8 | * 9 | ******************************************************************************* 10 | */ 11 | 12 | #include 13 | #include 14 | #include "semihosting.h" 15 | 16 | static unsigned char g_buf[16]; 17 | static unsigned char g_buf_len = 0; 18 | 19 | /**************************************************************************//** 20 | * @brief Transmit a char on semihosting mode. 21 | * 22 | * @param ch is the char that to send. 23 | * 24 | * @return Character to write. 25 | *****************************************************************************/ 26 | void SH_SendChar(int ch) { 27 | g_buf[g_buf_len++] = ch; 28 | g_buf[g_buf_len] = '\0'; 29 | if (g_buf_len + 1 >= sizeof(g_buf) || ch == '\n' || ch == '\0') { 30 | g_buf_len = 0; 31 | /* Send the char */ 32 | if (SH_DoCommand(0x04, (int) g_buf, NULL) != 0) { 33 | return; 34 | } 35 | } 36 | } 37 | 38 | /**************************************************************************//** 39 | * @brief Transmit a null-terminated string on semihosting mode. 40 | * 41 | * @param str is the string that to send. 42 | * 43 | * @return Character to write. 44 | *****************************************************************************/ 45 | void SH_SendString(const char *str) 46 | { 47 | //int j; 48 | if (SH_DoCommand(0x04, (int)str, NULL) != 0) { 49 | return; 50 | } 51 | } 52 | 53 | /**************************************************************************//** 54 | * @brief Read a char on semihosting mode. 55 | * 56 | * @param None. 57 | * 58 | * @return Character that have read. 59 | *****************************************************************************/ 60 | char SH_GetChar() { 61 | int nRet; 62 | 63 | while (SH_DoCommand(0x101, 0, &nRet) != 0) { 64 | if (nRet != 0) { 65 | SH_DoCommand(0x07, 0, &nRet); 66 | return (char) nRet; 67 | } 68 | } 69 | 70 | return 0; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /app/cmsis_boot/system_stm32f10x.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.h 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 11-March-2011 7 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 17 | * 18 | *

© COPYRIGHT 2011 STMicroelectronics

19 | ****************************************************************************** 20 | */ 21 | 22 | /** @addtogroup CMSIS 23 | * @{ 24 | */ 25 | 26 | /** @addtogroup stm32f10x_system 27 | * @{ 28 | */ 29 | 30 | /** 31 | * @brief Define to prevent recursive inclusion 32 | */ 33 | #ifndef __SYSTEM_STM32F10X_H 34 | #define __SYSTEM_STM32F10X_H 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /** @addtogroup STM32F10x_System_Includes 41 | * @{ 42 | */ 43 | 44 | /** 45 | * @} 46 | */ 47 | 48 | 49 | /** @addtogroup STM32F10x_System_Exported_types 50 | * @{ 51 | */ 52 | 53 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /** @addtogroup STM32F10x_System_Exported_Constants 60 | * @{ 61 | */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32F10x_System_Exported_Macros 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32F10x_System_Exported_Functions 76 | * @{ 77 | */ 78 | 79 | extern void SystemInit(void); 80 | extern void SystemCoreClockUpdate(void); 81 | /** 82 | * @} 83 | */ 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /*__SYSTEM_STM32F10X_H */ 90 | 91 | /** 92 | * @} 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 99 | -------------------------------------------------------------------------------- /app/Config/USART1_Config.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "USART1_Config.h" 4 | #include "misc.h" 5 | #include "helpers.h" 6 | 7 | 8 | USART_InitTypeDef USART1_Config; 9 | void Init_USART1_RCC(); 10 | void Init_USART1_GPIO(); 11 | void Init_USART1_Interrupt(); 12 | 13 | 14 | void Init_USART1(uint32_t baud, FunctionalState USART1_Interrupts) 15 | { 16 | 17 | Init_USART1_GPIO(); 18 | 19 | USART1_Config.USART_BaudRate = baud; 20 | USART1_Config.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 21 | USART1_Config.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 22 | USART1_Config.USART_Parity = USART_Parity_No; 23 | USART1_Config.USART_StopBits = USART_StopBits_1; 24 | USART1_Config.USART_WordLength = USART_WordLength_8b; 25 | USART_Init(USART1, &USART1_Config); 26 | 27 | USART_Cmd(USART1,ENABLE); 28 | 29 | Init_USART1_Interrupt(); 30 | 31 | } 32 | 33 | void Init_USART1_RCC() 34 | { 35 | 36 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 37 | //RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 38 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // (Starts and attaches Peripheral clock for USART1) 39 | } 40 | 41 | GPIO_InitTypeDef GPIOA_Config_USART1; 42 | 43 | void Init_USART1_GPIO() 44 | { 45 | 46 | //For RX Pin --------------------------------- 47 | GPIOA_Config_USART1.GPIO_Speed = GPIO_Speed_50MHz; 48 | GPIOA_Config_USART1.GPIO_Mode = GPIO_Mode_IN_FLOATING; 49 | GPIOA_Config_USART1.GPIO_Pin = GPIO_Pin_10; 50 | GPIO_Init(GPIOA, &GPIOA_Config_USART1); // Saves above configuration to associated registers 51 | 52 | //-------------------------------------------- 53 | 54 | //For TX Pin --------------------------------- 55 | GPIOA_Config_USART1.GPIO_Mode = GPIO_Mode_AF_PP; // Alternate Function Push-Pull 56 | GPIOA_Config_USART1.GPIO_Pin = GPIO_Pin_9; 57 | GPIO_Init(GPIOA, &GPIOA_Config_USART1); // Saves above configuration to associated registers 58 | 59 | //-------------------------------------------- 60 | } 61 | 62 | NVIC_InitTypeDef USART1_Interrupt_Config; 63 | void Init_USART1_Interrupt() 64 | { 65 | //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 66 | 67 | USART1_Interrupt_Config.NVIC_IRQChannel = USART1_IRQn; 68 | USART1_Interrupt_Config.NVIC_IRQChannelPreemptionPriority = 1; 69 | USART1_Interrupt_Config.NVIC_IRQChannelSubPriority = 0; 70 | USART1_Interrupt_Config.NVIC_IRQChannelCmd = ENABLE; 71 | NVIC_Init(&USART1_Interrupt_Config); 72 | 73 | USART_ITConfig(USART1,USART_IT_RXNE, ENABLE); // Enable USART Interrupts 74 | //USART_ITConfig(USART1,USART_IT_TXE, ENABLE); 75 | } 76 | -------------------------------------------------------------------------------- /semihosting/sh_cmd.s: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file semihost_cmd.s 4 | * @author Coocox 5 | * @version V1.0 6 | * @date 09/10/2011 7 | * @brief Semihost command support. 8 | * 9 | ******************************************************************************* 10 | */ 11 | 12 | 13 | .text 14 | .global SH_DoCommand 15 | .global HardFault_Handler 16 | .code 16 17 | .syntax unified 18 | .type SH_DoCommand, function 19 | .type HardFault_Handler, function 20 | 21 | 22 | /**************************************************************************//** 23 | * @brief prototype: int SH_DoCommand(int n32In_R0, int n32In_R1, int *pn32Out_R0) 24 | * 25 | * @param n32In_R0 R0 26 | * @param n32In_R1 R1 27 | * @param pn32Out_R0 R2 28 | * 29 | * @retval None 30 | *****************************************************************************/ 31 | SH_DoCommand: 32 | BKPT 0xAB /* Wait ICE or HardFault */ 33 | /* ICE will step over BKPT directly */ 34 | /* HardFault will step BKPT and the next line */ 35 | 36 | B SH_ICE 37 | 38 | SH_HardFault: /* Captured by HardFault */ 39 | MOVS R0, #0 /* Set return value to 0 */ 40 | BX LR /* Return */ 41 | 42 | SH_ICE: /* Captured by ICE */ 43 | /* Save return value */ 44 | CMP R2, #0 45 | BEQ SH_End 46 | STR R0, [R2] /* Save the return value to *pn32Out_R0 */ 47 | SH_End: 48 | MOVS R0, #1 /* Set return value to 1 */ 49 | BX LR /* Return */ 50 | 51 | /**************************************************************************//** 52 | * @brief HardFault Handler 53 | * 54 | * @param None. 55 | * 56 | * Skip the semihost command in free run mode. 57 | * 58 | * @retval None 59 | *****************************************************************************/ 60 | HardFault_Handler: 61 | LDR R0, [R13, #24] /* Get previous PC */ 62 | LDRH R1, [R0] /* Get instruction */ 63 | LDR R2, =0xBEAB /* The sepcial BKPT instruction */ 64 | CMP R1, R2 /* Test if the instruction at previous PC is BKPT */ 65 | BNE HardFault_Handler_Ret /* Not BKPT */ 66 | 67 | ADDS R0, #4 /* Skip BKPT and next line */ 68 | STR R0, [R13, #24] /* Save previous PC */ 69 | 70 | BX LR 71 | 72 | HardFault_Handler_Ret: 73 | B . 74 | 75 | 76 | .end 77 | 78 | -------------------------------------------------------------------------------- /app/esp8266/include/esp8266.h: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************** 3 | * Author: Jacob Pagel 4 | * Date: 03/05/2015 5 | * esp8266.h (esp8266 wifi library include file) 6 | ********************************************************/ 7 | 8 | #ifndef _ESP8266_H_ 9 | #define _ESP8266_H_ 10 | 11 | #include "stm32f10x_usart.h" 12 | #include 13 | #include "string.h" 14 | #include "time.h" 15 | #include "globalDefines.h" 16 | 17 | volatile uint8_t waitingForReponse; 18 | volatile uint8_t OKFound; 19 | volatile uint8_t ERRORFound; 20 | 21 | //#define ESP_ResponseTimeout_ms 3000 22 | //#define ESP_USART USART3 23 | 24 | 25 | const typedef enum {ESP_RESPONSE_READY,ESP_RESPONSE_Link,ESP_RESPONSE_Unlink,ESP_RESPONSE_OK, 26 | ESP_RESPONSE_SEND_OK,ESP_RESPONSE_IPD,ESP_RESPONSE_ERROR, 27 | ESP_RESPONSE_Wrong_Syntax,ESP_RESPONSE_BUSY_P,ESP_RESPONSE_BUSY_INET}ESP_Messages; 28 | 29 | typedef enum 30 | { 31 | WIFI_CHECK_MODULE_CONNECTION = 0, 32 | WIFI_CURRENT_STATUS, //Get current status 33 | WIFI_AP_LIST, // Get available AP's 34 | WIFI_FIRMWARE_VERSION, // Get current firmware version on ESP8266 35 | WIFI_GET_CURRENT_MODE, // Gets the current mode (Access Point, Station, both) 36 | WIFI_SET_MODE_BOTH_AP_ST, // Set Mode as both, Access Point, Station 37 | WIFI_JOIN_NONYA, 38 | WIFI_SHOW_CURRENT_CONNECTED_AP, 39 | WIFI_MODULE_RESET, 40 | WIFI_SET_MULTICONNECTION, 41 | WIFI_SET_BAUD_115200, 42 | WIFI_START_LOCAL_SERVER_PORT_80, 43 | WIFI_GET_CURRENT_IP, 44 | WIFI_SHOW_ACTIVE_CONNECTIONS, 45 | WIFI_LIST_CONNECTED_DEVICES_inAPModeOnly, 46 | WIFI_QUIT_CURRENT_AP, 47 | WIFI_START_ACCESS_POINT, 48 | WIFI_DISABLE_ECHO 49 | }Wifi_Commands; 50 | 51 | typedef enum 52 | { 53 | OPEN, 54 | WEP, 55 | WPA_PSK, 56 | WPA2_PSK, 57 | WPA_WPA2_PSK 58 | }Available_Encyption; 59 | 60 | //TYPEDEF DECLARATIONS 61 | typedef struct{ 62 | uint8_t ConnectionNum; 63 | char *DataSize; 64 | char *RequestType; //ie.. POST, GET, PUT, DELETE 65 | char *URI; //ie.. /api/foo?id=123 66 | char *Headers; 67 | char *Body; 68 | uint8_t Valid; 69 | }IPD_Data; 70 | 71 | extern const char *ATCommandsArray[18]; 72 | 73 | #define WIFI_COMMAND(commandEnum) (ATCommandsArray[(commandEnum)]) 74 | 75 | 76 | 77 | 78 | void Wifi_ReadyWaitForAnswer(); 79 | void Wifi_WaitForAnswer(); 80 | void Wifi_CloseConnection(uint8_t connectionNum); 81 | void Wifi_SendCustomCommand(char *customMessage); 82 | void Wifi_SendCustomCommand_External_Wait(char *customMessage); 83 | void Wifi_SendCommand(Wifi_Commands command ); 84 | IPD_Data Wifi_CheckDMABuff_ForIPDData(); 85 | void ConnectToAP(char *apName, char *password); 86 | void StartLocalAP(char *SSID, char *password, uint8_t channel, Available_Encyption encypt); 87 | 88 | 89 | #endif //_ESP8266_H_ 90 | -------------------------------------------------------------------------------- /doxygen/assets/stylesheets/navtree.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | #doc-content { 4 | overflow:hidden; 5 | display:block; 6 | padding:0px; 7 | margin:0px; 8 | } 9 | 10 | #side-nav { 11 | padding:0 0px 0 0px; 12 | margin: 10px; 13 | display:block; 14 | position: absolute; 15 | right: 50px; 16 | top: 150px; 17 | width: 300px; 18 | border: 1px solid #dddddd; 19 | border-radius: 5px; 20 | overflow-x: hidden; 21 | overflow-y: auto; 22 | } 23 | 24 | #nav-tree { 25 | padding: 0px 0px; 26 | font-size:14px; 27 | overflow:hidden; 28 | background-color: #fff; 29 | background-repeat:repeat-x; 30 | } 31 | 32 | 33 | 34 | #nav-tree .children_ul { 35 | margin:0px; 36 | padding:0px; 37 | } 38 | 39 | #nav-tree .children_ul { 40 | margin:0; 41 | padding:4px; 42 | } 43 | 44 | #nav-tree ul { 45 | list-style:none outside none; 46 | margin:0px; 47 | padding:0px; 48 | } 49 | 50 | #nav-tree li { 51 | white-space:nowrap; 52 | margin:0px; 53 | padding:0px; 54 | } 55 | 56 | #nav-tree .plus { 57 | margin:0px; 58 | } 59 | 60 | 61 | 62 | #nav-tree img { 63 | margin:0px; 64 | padding:0px; 65 | border:0px; 66 | vertical-align: middle; 67 | } 68 | 69 | #nav-tree a { 70 | text-decoration:none; 71 | padding:0px; 72 | margin:0px; 73 | outline:none; 74 | } 75 | 76 | #nav-tree .label { 77 | margin:0px; 78 | padding:0px; 79 | font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; 80 | } 81 | 82 | #nav-tree .label a { 83 | padding:2px; 84 | } 85 | 86 | 87 | 88 | #nav-tree .item { 89 | margin:0px; 90 | height: 20px; 91 | padding: 5px 5px; 92 | } 93 | 94 | #nav-tree .item a { 95 | font-family:'Open Sans',"Trebuchet MS",Helvetica,sans-serif; 96 | font-weight: 400; 97 | font-size: 15px; 98 | color: #1d66af; 99 | } 100 | 101 | #nav-tree .selected { 102 | background-color: #dddddd; 103 | color: #fff; 104 | } 105 | 106 | #nav-tree .selected a { 107 | text-decoration:none; 108 | font-family:'Open Sans',"Trebuchet MS",Helvetica,sans-serif; 109 | font-weight: 700; 110 | } 111 | 112 | .ui-resizable .ui-resizable-handle { 113 | display:block; 114 | } 115 | 116 | .ui-resizable-e { 117 | cursor:e-resize; 118 | height:100%; 119 | right:0; 120 | top:0; 121 | width:6px; 122 | } 123 | 124 | .ui-resizable-handle { 125 | display:none; 126 | font-size:0.1px; 127 | position:absolute; 128 | z-index:1; 129 | } 130 | 131 | #nav-tree-contents { 132 | margin: 0px 0px 0px 0px; 133 | } 134 | 135 | #nav-tree-contents ul { 136 | display: block; 137 | margin: 0; 138 | padding: 0; 139 | } 140 | 141 | #nav-tree-contents > ul > li:first-child > div { 142 | background-color: #f7f7f7; 143 | height: 25px; 144 | padding: 8px 5px; 145 | width: 100%; 146 | } 147 | 148 | 149 | #nav-tree-contents > ul > li:first-child > div a { 150 | font-weight: 700; 151 | font-size: 16px; 152 | font-family:'Open Sans',"Trebuchet MS",Helvetica,sans-serif; 153 | } 154 | 155 | 156 | #nav-sync { 157 | display: none; 158 | } 159 | 160 | #nav-sync img { 161 | opacity:0.3; 162 | } 163 | 164 | #nav-sync img:hover { 165 | opacity:0.9; 166 | } 167 | 168 | @media print 169 | { 170 | #nav-tree { display: none; } 171 | div.ui-resizable-handle { display: none; position: relative; } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /app/cmsis_boot/stm32f10x_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file RTC/Calendar/stm32f10x_conf.h 4 | * @author MCD Application Team 5 | * @version V3.4.0 6 | * @date 10/15/2010 7 | * @brief Library configuration file. 8 | ****************************************************************************** 9 | * @copy 10 | * 11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 17 | * 18 | *

© COPYRIGHT 2010 STMicroelectronics

19 | */ 20 | 21 | /* Define to prevent recursive inclusion -------------------------------------*/ 22 | #ifndef __STM32F10x_CONF_H 23 | #define __STM32F10x_CONF_H 24 | 25 | /* Includes ------------------------------------------------------------------*/ 26 | /* Uncomment the line below to enable peripheral header file inclusion */ 27 | /* #include "stm32f10x_adc.h" */ 28 | /* #include "stm32f10x_bkp.h" */ 29 | /* #include "stm32f10x_can.h" */ 30 | /* #include "stm32f10x_cec.h" */ 31 | /* #include "stm32f10x_crc.h" */ 32 | /* #include "stm32f10x_dac.h" */ 33 | /* #include "stm32f10x_dbgmcu.h" */ 34 | /* #include "stm32f10x_dma.h" */ 35 | /* #include "stm32f10x_exti.h" */ 36 | /* #include "stm32f10x_flash.h" */ 37 | /* #include "stm32f10x_fsmc.h" */ 38 | /* #include "stm32f10x_gpio.h" */ 39 | /* #include "stm32f10x_i2c.h" */ 40 | /* #include "stm32f10x_iwdg.h" */ 41 | /* #include "stm32f10x_pwr.h" */ 42 | /* #include "stm32f10x_rcc.h" */ 43 | /* #include "stm32f10x_rtc.h" */ 44 | /* #include "stm32f10x_sdio.h" */ 45 | /* #include "stm32f10x_spi.h" */ 46 | /* #include "stm32f10x_tim.h" */ 47 | /* #include "stm32f10x_usart.h" */ 48 | /* #include "stm32f10x_wwdg.h" */ 49 | /* #include "misc.h" */ /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ 50 | 51 | 52 | /* Exported types ------------------------------------------------------------*/ 53 | /* Exported constants --------------------------------------------------------*/ 54 | /* Uncomment the line below to expanse the "assert_param" macro in the 55 | Standard Peripheral Library drivers code */ 56 | /* #define USE_FULL_ASSERT 1 */ 57 | 58 | /* Exported macro ------------------------------------------------------------*/ 59 | #ifdef USE_FULL_ASSERT 60 | 61 | /** 62 | * @brief The assert_param macro is used for function's parameters check. 63 | * @param expr: If expr is false, it calls assert_failed function 64 | * which reports the name of the source file and the source 65 | * line number of the call that failed. 66 | * If expr is true, it returns no value. 67 | * @retval None 68 | */ 69 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) 70 | /* Exported functions ------------------------------------------------------- */ 71 | void assert_failed(uint8_t* file, uint32_t line); 72 | #else 73 | #define assert_param(expr) ((void)0) 74 | #endif /* USE_FULL_ASSERT */ 75 | 76 | #endif /* __STM32F10x_CONF_H */ 77 | 78 | /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ 79 | -------------------------------------------------------------------------------- /README.md~: -------------------------------------------------------------------------------- 1 | # stm32-f103-CortexM3-ESP8266-Dimmer 2 | 3 | ###--- CoIDE (v1.7.8) Project. --- 4 | 5 | AC mains triac controlled dimmer using STM32F103 for brains. ESP8266 Wifi for communication and mesh networking. 6 | 7 | I welcome comments on things you think can be improved along the way. CONSTRUCTIVE ONLY PLEASE!! 8 | 9 | THIS IS A SUB PROJECT OF A LARGER SOON TO BE KICKSTARTED OPEN SOURCED HOME AUTOMATION PROJECT 10 | --- I have been working on this project alone for over 2 years (long before all these other poser kits showed up.. LOL (no offense to the posers reading this... ;). hence the slow progress. I have a wife, daughter, and full time job. Liek alot of you. )) --- 11 | 12 | 13 | Current capabilities as software and hardware currently exist. 14 | 15 | - Connection to existing wifi network 16 | - Starting local TCP/UDP server 17 | - Echo and CMD RECVD response back to connected wifi client if properly formated CMD received over DEBUG connection (USART1) 18 | - USART buffer parsing in interrupt for USART1 and 3. (being done inside inturrupt for now to simply code base and development) Keeping close eye on active AC dimming as logic for USART expands inside interrupt (no flicker AT ALL on connected AC Cree 60W (equiv.) LED bulb). 19 | - Lots of dimming code tweaks (while monitoring with high frequency bench oscilloscope) (still in progress), to get the most dimming possible without ANY flicker on LED bulds (so sick of the crap out there, that makes LED bulbs hum or cut out before they even get DIM. This project already does better at dimming than any comercial "LED compatible" dimmer I have found.(not saying a better one doesn't exist)). 20 | - Dimming function is 360 degree of SINE (FULL WAVE), unlike a lot of dimmers that only work on the positive portion of the wave. 21 | - Serves basic page with textbox and Submit button to connecting Browser clients **(In Progress on seperate branch)** 22 | 23 | ----- I'm sure there is more i'm not thinking of. 24 | 25 | 26 | 27 | Project under heavy development. 28 | -(DevBoard is a Leaf Labs - Maple Mini (socketed on a custom protoboard (used as a connections breakout for testing))) 29 | -This will be implemented on a custom built multi-layer PCB for production. 30 | -EAGLE CAD files will be included soon for V0.1 hardware. 31 | 32 | -- Basic COMS/Commands for ESP8266 working 33 | -- USART1 - currently used for debuging and sending commands while testing (will come from parsed Wifi received data eventually) 34 | -- USART3 - used for serial connection to ESP8266 35 | 36 | 37 | As you can see below, there is still a lot to do. 38 | 39 | On the To-Do list: 40 | 41 | 1. Create basic http based response for a port 80 request to module. *(Active on branch "browser_response_return_testing")* 42 | 43 | - [ ] Report current status (to include) 44 | - [ ] Assigned IP 45 | - [ ] Currently connected Wifi AP SSID 46 | - [ ] Current Dimming level 47 | - [ ] Current, current throughput.. 48 | - [ ] Current angle of triac in AC SINE 49 | - [ ] Current frequency of AC mains 50 | - [ ] Current Triac, MCU, WIFI module tempurature 51 | - [ ] Flag for if recent errors (last hour or so, not sure how long I want it to hold on to them) 52 | - [x] Basic Textbox for direct input of dimming value 53 | - [ ] Manual MCU/Module reset/reboot 54 | - [ ] Option to enable Mesh network or Wifi network extention features (802.11n) 55 | 56 | 2. Make ESP8266 library more universal (more of a library, less of a specific implimentation). **In Progress** 57 | 3. Build stm32 hosted website library for ESP8266. **In Progress** 58 | 4. Test realworld throughput limits of USART data throughput to ESP8266 module. (current tested max without tweaking, 2Mbaud) 59 | 5. Build motion control/occupation sensor support (So user can add motion sensor if desired) 60 | 6. Build small current monitor library for AC and DC connection support (obviously hardware will also be required) 61 | 7. Build security and authentication library/layer for any write level connection requests. 62 | 8. Make dimming code auto adjust timing for 50Hz vs 60Hz mains (or any random freq fluctuation above or below) without code treaking required. 63 | 9. Lots more I'm not thinking of. I want the little STM32 to really have to work for its place in this project. So more functions and options will be added. 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # stm32-f103-CortexM3-ESP8266-Dimmer 2 | 3 | ###--- CoIDE (v1.7.8) Project. --- 4 | 5 | ####(UPDATE: 04/15/2015)TONS of new updates (will update this readme file soon). Example Working DMA circular USART buffer for ESP8266 responses 6 | 7 | AC mains triac controlled dimmer using STM32F103 for brains. ESP8266 Wifi for communication and mesh networking. 8 | 9 | I welcome comments on things you think can be improved along the way. CONSTRUCTIVE ONLY PLEASE!! 10 | 11 | THIS IS A SUB PROJECT OF A LARGER SOON TO BE KICKSTARTED OPEN SOURCED HOME AUTOMATION PROJECT 12 | --- I have been working on this project alone for over 2 years (long before all these other poser kits showed up.. LOL (no offense to the posers reading this... ;). hence the slow progress. I have a wife, daughter, and full time job. Liek alot of you. )) --- 13 | 14 | 15 | Current capabilities as software and hardware currently exist. 16 | 17 | - Connection to existing wifi network 18 | - Starting local TCP/UDP server 19 | - Echo and CMD RECVD response back to connected wifi client if properly formated CMD received over DEBUG connection (USART1) 20 | - USART buffer parsing in interrupt for USART1 and 3. (being done inside inturrupt for now to simply code base and development) Keeping close eye on active AC dimming as logic for USART expands inside interrupt (no flicker AT ALL on connected AC Cree 60W (equiv.) LED bulb). 21 | - Lots of dimming code tweaks (while monitoring with high frequency bench oscilloscope) (still in progress), to get the most dimming possible without ANY flicker on LED bulds (so sick of the crap out there, that makes LED bulbs hum or cut out before they even get DIM. This project already does better at dimming than any comercial "LED compatible" dimmer I have found.(not saying a better one doesn't exist)). 22 | - Dimming function is 360 degree of SINE (FULL WAVE), unlike a lot of dimmers that only work on the positive portion of the wave. 23 | - Serves basic page with textbox and Submit button to connecting Browser clients **(In Progress on seperate branch)** 24 | 25 | ----- I'm sure there is more i'm not thinking of. 26 | 27 | 28 | 29 | Project under heavy development. 30 | - (DevBoard is a Leaf Labs - Maple Mini (socketed on a custom protoboard (used as a connections breakout for testing))) 31 | - This will be implemented on a custom built multi-layer PCB for production. 32 | - EAGLE CAD files will be included soon for V0.1 hardware. 33 | - Basic COMS/Commands for ESP8266 working 34 | - USART1 - currently used for debuging and sending commands while testing (will come from parsed Wifi received data eventually) 35 | - USART3 - used for serial connection to ESP8266 36 | 37 | 38 | As you can see below, there is still a lot to do. 39 | 40 | On the To-Do list: 41 | 42 | 1. Create basic http based response for a port 80 request to module. *(Active on branch "browser_response_return_testing")* 43 | 44 | - [ ] Report current status (to include) 45 | - [ ] Assigned IP 46 | - [ ] Currently connected Wifi AP SSID 47 | - [ ] Current Dimming level 48 | - [ ] Current, current throughput.. 49 | - [ ] Current angle of triac in AC SINE 50 | - [ ] Current frequency of AC mains 51 | - [ ] Current Triac, MCU, WIFI module tempurature 52 | - [ ] Flag for if recent errors (last hour or so, not sure how long I want it to hold on to them) 53 | - [x] Basic Textbox for direct input of dimming value 54 | - [ ] Manual MCU/Module reset/reboot 55 | - [ ] Option to enable Mesh network or Wifi network extention features (802.11n) 56 | 57 | 2. Make ESP8266 library more universal (more of a library, less of a specific implimentation). **In Progress** 58 | 3. Build stm32 hosted website library for ESP8266. **In Progress** 59 | 4. Test realworld throughput limits of USART data throughput to ESP8266 module. (current tested max without tweaking, 2Mbaud) 60 | 5. Build motion control/occupation sensor support (So user can add motion sensor if desired) 61 | 6. Build small current monitor library for AC and DC connection support (obviously hardware will also be required) 62 | 7. Build security and authentication library/layer for any write level connection requests. 63 | 8. Make dimming code auto adjust timing for 50Hz vs 60Hz mains (or any random freq fluctuation above or below) without code treaking required. 64 | 9. Lots more I'm not thinking of. I want the little STM32 to really have to work for its place in this project. So more functions and options will be added. 65 | -------------------------------------------------------------------------------- /app/Server/WebServer.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "WebServer.h" 4 | 5 | 6 | extern char webResponse[RESPONSE_BUFFER_SIZE]; 7 | void ClearArray_Size(char buffer[], uint16_t size); 8 | 9 | uint32_t wi= 0; 10 | 11 | 12 | const char *HTTP_Method[4] = {"GET","POST","PUT","DELETE"}; // Array is used for string compare or value of for the Http_Call_Type ENUM 13 | const char *RequestHeaders_Array[6] = {"Content-Type: ","Content-Length: ","Accept: ", "Accept-Encoding: ", "Host: ", "User-Agent: "}; 14 | 15 | void buildHeader(Header *newHeaderOut, RequestHeaders_Types type, char *headerValue) 16 | { 17 | Header newHeader; 18 | newHeader.key = RequestHeaders_Array[type]; 19 | newHeader.value = headerValue; 20 | //sprintf(newHeaderOut,"%s%s",RequestHeaders_Array[type],headerValue); 21 | } 22 | 23 | 24 | const char *RESTResponse_Headers_Test_OK = //Just here for testing as this is just a static OK 200 response 25 | " HTTP/1.1 200 OK\r\n" 26 | "Content-Type: application/json\r\n" 27 | "Connection: close\r\n"; 28 | // Needs to include Content-Length:XX 29 | // Calculated and appended based on body 30 | 31 | const char *RESTResponse_Body_TEST_JSON = 32 | "{\"ID\":\"dim01\",\"Status\":{\"CurrentIP_WAN\":\"0.0.0.0\",\"currentip_lan\":\"192.168.4.1\",\"self_check_result\":\"OK\"}} \0"; 33 | 34 | 35 | const char DimmingInputPage[] = " Dimming Module Control Page
Dimming Value:
" 36 | "" 37 | "
"; 38 | 39 | 40 | 41 | uint16_t headLength = 0; 42 | uint16_t bodyLength = 0; 43 | uint8_t bodyLengthLength = 0; 44 | char bodyLengthSizeString[4]; 45 | 46 | uint16_t fullLength = 0; 47 | uint16_t fullCommandLen = 0; 48 | ///Sends a response to the active client (connectionNum) 49 | 50 | char *responseBuff; 51 | char data[200]; 52 | 53 | void SendRESTResponse(uint8_t connectionNum, const char *responseHeaders, const char *responseBody) 54 | { 55 | 56 | //Should check if client is still connected, or connectionNum is a valid connection 57 | 58 | //Wipes the webResponse buffer array to make sure there is no extra data being appended to response 59 | ClearArray_Size(webResponse,ARRAYSIZE(webResponse)); 60 | 61 | //Calculates lengths of strings to be sent (required prior to sending) 62 | headLength = strlen(responseHeaders); 63 | bodyLength = strlen(responseBody); 64 | sprintf(bodyLengthSizeString, "%d", bodyLength); 65 | bodyLengthLength = strlen(bodyLengthSizeString); 66 | 67 | fullLength = headLength + (((strlen(RequestHeaders_Array[ContentLength]))+bodyLengthLength)+4) + bodyLength+1; 68 | fullCommandLen = fullLength; 69 | sprintf(webResponse, "AT+CIPSEND=%d,%d\r\n", connectionNum, fullLength); 70 | fullCommandLen += strlen(webResponse); 71 | 72 | //void Wifi_ReadyWaitForAnswer(); 73 | //Wifi_SendCustomCommand(webResponse); 74 | 75 | Wifi_SendCustomCommand_External_Wait(webResponse); 76 | 77 | ClearArray_Size(webResponse,strlen(webResponse)); 78 | sprintf(webResponse,"%s%s%d\r\n\r\n%s",responseHeaders,RequestHeaders_Array[ContentLength],bodyLength + 1,responseBody); 79 | //strcat(webResponse, data); 80 | 81 | Wifi_SendCustomCommand_External_Wait(webResponse); 82 | 83 | Wifi_WaitForAnswer_SEND_OK(fullCommandLen); 84 | 85 | ClearArray_Size(webResponse,strlen(webResponse)); 86 | 87 | //for (wi=0;wi<70500;wi++); 88 | } 89 | 90 | 91 | 92 | void StartServer(uint8_t serverNum, uint16_t portNum) 93 | { 94 | for (wi=0;wi<73500;wi++); 95 | for (wi=0;wi<73500;wi++); 96 | for (wi=0;wi<73500;wi++);//TEMP waits to make sure ESP is ready 97 | //Need to just add check for "ready" 98 | 99 | Wifi_SendCommand(WIFI_SET_MULTICONNECTION); //Enables the multi-connection mode. 100 | 101 | 102 | //XXX: Need to build macro or function to append port number to request 103 | Wifi_SendCommand(WIFI_START_LOCAL_SERVER_PORT_80); // Currently just statically starts the server on 80 104 | 105 | //for (wi=0;i<73500;i++); 106 | //Wifi_SendCommand(WIFI_GET_CURRENT_IP); 107 | 108 | } 109 | 110 | 111 | void SendWebRequestResponse(uint8_t connectionNum) 112 | { 113 | 114 | //Wifi_SendCustomCommand("AT+CIPSEND=0,36\rGot your web request. I'm responding"); 115 | //Wifi_SendCustomCommand("AT+CIPSEND=1,36\rGot your web request. I'm responding"); 116 | sprintf(webResponse, "AT+CIPSEND=%d,%d\r\n%s", connectionNum, strlen(DimmingInputPage), DimmingInputPage); 117 | Wifi_SendCustomCommand(webResponse); 118 | for (wi=0;wi<70500;wi++); 119 | //Wifi_WaitForAnswer(); 120 | OKFound=0; 121 | Wifi_CloseConnection(connectionNum); 122 | } 123 | -------------------------------------------------------------------------------- /doxygen/assets/stylesheets/search/search.css: -------------------------------------------------------------------------------- 1 | /*---------------- Search Box */ 2 | 3 | #FSearchBox { 4 | float: left; 5 | } 6 | 7 | #MSearchBox { 8 | white-space : nowrap; 9 | position: absolute; 10 | float: none; 11 | display: inline; 12 | margin-top: 60px; 13 | right: 72px; 14 | width: 290px; 15 | z-index: 102; 16 | background-color: white; 17 | } 18 | 19 | #MSearchBox .left 20 | { 21 | display:block; 22 | position:absolute; 23 | left:10px; 24 | width:20px; 25 | height:33px; 26 | background:url('search_l.jpg') no-repeat; 27 | background-position:right; 28 | 29 | } 30 | 31 | #MSearchSelect { 32 | display:block; 33 | position:absolute; 34 | width:30px; 35 | height:32px; 36 | 37 | } 38 | 39 | .left #MSearchSelect { 40 | left:-2px; 41 | } 42 | 43 | .right #MSearchSelect { 44 | right:5px; 45 | } 46 | 47 | #MSearchField { 48 | display:block; 49 | position:absolute; 50 | height:33px; 51 | background:url('search_m.jpg') repeat-x; 52 | border:none; 53 | width:231px; 54 | margin-left:20px; 55 | padding-left:4px; 56 | color: #909090; 57 | outline: none; 58 | font-family:'Open Sans',"Trebuchet MS",Helvetica,sans-serif; 59 | font-size: 9pt; 60 | 61 | } 62 | 63 | #FSearchBox #MSearchField { 64 | margin-left:15px; 65 | } 66 | 67 | #MSearchBox .right { 68 | display:block; 69 | position:absolute; 70 | right:10px; 71 | top:0px; 72 | width:20px; 73 | height:33px; 74 | background:url('search_r.jpg') no-repeat; 75 | background-position:left; 76 | } 77 | 78 | #MSearchClose { 79 | display: none; 80 | position: absolute; 81 | top: 4px; 82 | background : none; 83 | border: none; 84 | margin: 0px 4px 0px 0px; 85 | padding: 0px 0px; 86 | outline: none; 87 | } 88 | 89 | .left #MSearchClose { 90 | left: 6px; 91 | } 92 | 93 | .right #MSearchClose { 94 | right: 2px; 95 | } 96 | 97 | .MSearchBoxActive #MSearchField { 98 | color: #000000; 99 | } 100 | 101 | /*---------------- Search filter selection */ 102 | 103 | #MSearchSelectWindow { 104 | display: none; 105 | position: absolute; 106 | left: 0; top: 0; 107 | border: 1px solid #90A5CE; 108 | background-color: #F9FAFC; 109 | z-index: 1; 110 | padding-top: 4px; 111 | padding-bottom: 4px; 112 | -moz-border-radius: 4px; 113 | -webkit-border-top-left-radius: 4px; 114 | -webkit-border-top-right-radius: 4px; 115 | -webkit-border-bottom-left-radius: 4px; 116 | -webkit-border-bottom-right-radius: 4px; 117 | -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); 118 | } 119 | 120 | .SelectItem { 121 | font-family:'Open Sans',"Trebuchet MS",Helvetica,sans-serif; 122 | font-size: 8pt; 123 | padding-left: 2px; 124 | padding-right: 12px; 125 | border: 0px; 126 | } 127 | 128 | span.SelectionMark { 129 | margin-right: 4px; 130 | font-family:'Open Sans',"Trebuchet MS",Helvetica,sans-serif; 131 | outline-style: none; 132 | text-decoration: none; 133 | } 134 | 135 | a.SelectItem { 136 | display: block; 137 | outline-style: none; 138 | color: #000000; 139 | text-decoration: none; 140 | padding-left: 6px; 141 | padding-right: 12px; 142 | } 143 | 144 | a.SelectItem:focus, 145 | a.SelectItem:active { 146 | color: #000000; 147 | outline-style: none; 148 | text-decoration: none; 149 | } 150 | 151 | a.SelectItem:hover { 152 | color: #FFFFFF; 153 | background-color: #3D578C; 154 | outline-style: none; 155 | text-decoration: none; 156 | cursor: pointer; 157 | display: block; 158 | } 159 | 160 | /*---------------- Search results window */ 161 | 162 | iframe#MSearchResults { 163 | width: 60ex; 164 | height: 15em; 165 | } 166 | 167 | #MSearchResultsWindow { 168 | display: none; 169 | position: absolute; 170 | left: 0; top: 0; 171 | border: 1px solid #000; 172 | background-color: #EEF1F7; 173 | } 174 | 175 | /* ----------------------------------- */ 176 | 177 | 178 | #SRIndex { 179 | clear:both; 180 | padding-bottom: 15px; 181 | } 182 | 183 | .SREntry { 184 | font-size: 10pt; 185 | padding-left: 1ex; 186 | } 187 | 188 | .SRPage .SREntry { 189 | font-size: 8pt; 190 | padding: 1px 5px; 191 | } 192 | 193 | body.SRPage { 194 | margin: 5px 2px; 195 | } 196 | 197 | .SRChildren { 198 | padding-left: 3ex; padding-bottom: .5em 199 | } 200 | 201 | .SRPage .SRChildren { 202 | display: none; 203 | } 204 | 205 | .SRSymbol { 206 | font-weight: bold; 207 | color: #425E97; 208 | font-family: Arial, Verdana, sans-serif; 209 | text-decoration: none; 210 | outline: none; 211 | } 212 | 213 | a.SRScope { 214 | display: block; 215 | color: #425E97; 216 | font-family: Arial, Verdana, sans-serif; 217 | text-decoration: none; 218 | outline: none; 219 | } 220 | 221 | a.SRSymbol:focus, a.SRSymbol:active, 222 | a.SRScope:focus, a.SRScope:active { 223 | text-decoration: underline; 224 | } 225 | 226 | span.SRScope { 227 | padding-left: 4px; 228 | } 229 | 230 | .SRPage .SRStatus { 231 | padding: 2px 5px; 232 | font-size: 8pt; 233 | font-style: italic; 234 | } 235 | 236 | .SRResult { 237 | display: none; 238 | } 239 | 240 | DIV.searchresults { 241 | margin-left: 10px; 242 | margin-right: 10px; 243 | } 244 | 245 | /*---------------- External search page results */ 246 | 247 | .searchresult { 248 | background-color: #F0F3F8; 249 | } 250 | 251 | .pages b { 252 | color: white; 253 | padding: 5px 5px 3px 5px; 254 | background-image: url("../tab_a.png"); 255 | background-repeat: repeat-x; 256 | text-shadow: 0 1px 1px #000000; 257 | } 258 | 259 | .pages { 260 | line-height: 17px; 261 | margin-left: 4px; 262 | text-decoration: none; 263 | } 264 | 265 | .hl { 266 | font-weight: bold; 267 | } 268 | 269 | #searchresults { 270 | margin-bottom: 20px; 271 | } 272 | 273 | .searchpages { 274 | margin-top: 10px; 275 | } 276 | 277 | -------------------------------------------------------------------------------- /doxygen/config/layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /Target.cogui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /Wifi_Dimmer.comarker: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /app/Config/USART3_Config.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | * @file USART3_Config.c 5 | * @author Jacob Pagel 6 | * @version 0.01 (Alpha) 7 | * @date 02/17/15 8 | * @brief All configuration required for USART3 periph placed in this file. 9 | * On my current dev board this USART is configured for the ESP8266 - Wifi 10 | * 11 | */ 12 | 13 | #include "USART3_Config.h" 14 | #include "misc.h" 15 | #include "helpers.h" 16 | #include "stm32f10x_dma.h" 17 | #include "time.h" 18 | //#include "Wifi.h" 19 | 20 | //extern uint8_t USART3_RxBufferSize; 21 | 22 | 23 | 24 | //extern uint8_t USART3_TxBuffer[]; 25 | extern volatile char USART3_RxBuffer[]; 26 | //extern uint8_t TxCounter; 27 | //extern uint8_t RxCounter; 28 | //extern uint8_t NbrOfDataToTransfer; 29 | //extern uint8_t NbrOfDataToRead; 30 | //extern volatile uint32_t lastUSARTCharReceived_Time; 31 | 32 | #define USART3_RxBufferSize (countof(USART3_RxBuffer) - 1) 33 | 34 | 35 | USART_InitTypeDef USART3_Config; 36 | void Init_USART3_RCC(); 37 | void Init_USART3_GPIO(); 38 | void Init_USART3_Interrupt(); 39 | void Init_USART_DMA(); 40 | 41 | //int i = 0; 42 | 43 | void Init_USART3(uint32_t baud, FunctionalState USART3_Interrupts) 44 | { 45 | //Init_USART3_RCC(); 46 | Init_USART3_GPIO(); 47 | 48 | USART3_Config.USART_BaudRate = baud; 49 | USART3_Config.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 50 | USART3_Config.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 51 | USART3_Config.USART_Parity = USART_Parity_No; 52 | USART3_Config.USART_StopBits = USART_StopBits_1; 53 | USART3_Config.USART_WordLength = USART_WordLength_8b; 54 | USART_Init(USART3, &USART3_Config); 55 | 56 | USART_Cmd(USART3,ENABLE); 57 | 58 | Init_USART3_Interrupt(); 59 | 60 | //Wifi_Init(); 61 | } 62 | 63 | //Need to split this apart after functional 64 | void Init_USART3_DMA(uint32_t baud, volatile char DMA_RxBuffer[], uint16_t BufSize) 65 | { 66 | NVIC_InitTypeDef USART3_DMA_Interrupt_Config; 67 | //Clock Start 68 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 69 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 70 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 71 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); 72 | 73 | //GPIO Config 74 | Init_USART3_GPIO(); 75 | 76 | DMA_ClearFlag(DMA1_FLAG_GL3 | DMA1_FLAG_HT3 | DMA1_FLAG_TC3 | DMA1_FLAG_TE3); 77 | 78 | //USART Config 79 | USART3_Config.USART_BaudRate = baud; 80 | USART3_Config.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 81 | USART3_Config.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 82 | USART3_Config.USART_Parity = USART_Parity_No; 83 | USART3_Config.USART_StopBits = USART_StopBits_1; 84 | USART3_Config.USART_WordLength = USART_WordLength_8b; 85 | USART_Init(USART3, &USART3_Config); 86 | 87 | 88 | 89 | //DMA Config 90 | DMA_DeInit(DMA1_Channel3); 91 | 92 | //USART3 DMA1 (RX Ch 3 | TX Ch 2 ) 93 | DMA_InitTypeDef USART3_DMA_Config; 94 | USART3_DMA_Config.DMA_PeripheralBaseAddr = 0x40004804; 95 | USART3_DMA_Config.DMA_MemoryBaseAddr = (uint32_t)DMA_RxBuffer; 96 | USART3_DMA_Config.DMA_DIR = DMA_DIR_PeripheralSRC; 97 | USART3_DMA_Config.DMA_BufferSize = BufSize; 98 | USART3_DMA_Config.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 99 | USART3_DMA_Config.DMA_MemoryInc = DMA_MemoryInc_Enable; 100 | USART3_DMA_Config.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 101 | USART3_DMA_Config.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 102 | USART3_DMA_Config.DMA_Mode = DMA_Mode_Circular; 103 | USART3_DMA_Config.DMA_Priority = DMA_Priority_VeryHigh; 104 | USART3_DMA_Config.DMA_M2M = DMA_M2M_Disable; 105 | 106 | DMA_Init(DMA1_Channel3, &USART3_DMA_Config); 107 | 108 | 109 | USART3_DMA_Interrupt_Config.NVIC_IRQChannel = DMA1_Channel3_IRQn; 110 | USART3_DMA_Interrupt_Config.NVIC_IRQChannelCmd = ENABLE; 111 | USART3_DMA_Interrupt_Config.NVIC_IRQChannelPreemptionPriority = 0; 112 | USART3_DMA_Interrupt_Config.NVIC_IRQChannelSubPriority = 0; 113 | 114 | NVIC_Init(&USART3_DMA_Interrupt_Config); 115 | //NVIC_EnableIRQ(DMA1_Channel3_IRQn); 116 | 117 | 118 | DMA_Cmd(DMA1_Channel3,ENABLE); 119 | 120 | USART_Cmd(USART3,ENABLE); 121 | //DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE); 122 | 123 | //Init_USART3_Interrupt(); 124 | 125 | 126 | 127 | USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE); 128 | } 129 | 130 | 131 | void DMA_Initialize(volatile char DMA_RxBuffer[], uint16_t BufSize) 132 | { 133 | NVIC_InitTypeDef USART3_DMA_Interrupt_Config; 134 | 135 | DMA_ClearFlag(DMA1_FLAG_GL3 | DMA1_FLAG_HT3 | DMA1_FLAG_TC3 | DMA1_FLAG_TE3); 136 | 137 | DMA_DeInit(DMA1_Channel3); 138 | 139 | //USART3 DMA1 (RX Ch 3 | TX Ch 2 ) 140 | DMA_InitTypeDef USART3_DMA_Config; 141 | USART3_DMA_Config.DMA_PeripheralBaseAddr = 0x40004804; 142 | USART3_DMA_Config.DMA_MemoryBaseAddr = (uint32_t)DMA_RxBuffer; 143 | USART3_DMA_Config.DMA_DIR = DMA_DIR_PeripheralSRC; 144 | USART3_DMA_Config.DMA_BufferSize = BufSize; 145 | USART3_DMA_Config.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 146 | USART3_DMA_Config.DMA_MemoryInc = DMA_MemoryInc_Enable; 147 | USART3_DMA_Config.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 148 | USART3_DMA_Config.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 149 | USART3_DMA_Config.DMA_Mode = DMA_Mode_Circular; 150 | USART3_DMA_Config.DMA_Priority = DMA_Priority_VeryHigh; 151 | USART3_DMA_Config.DMA_M2M = DMA_M2M_Disable; 152 | 153 | DMA_Init(DMA1_Channel3, &USART3_DMA_Config); 154 | 155 | 156 | USART3_DMA_Interrupt_Config.NVIC_IRQChannel = DMA1_Channel3_IRQn; 157 | USART3_DMA_Interrupt_Config.NVIC_IRQChannelCmd = ENABLE; 158 | USART3_DMA_Interrupt_Config.NVIC_IRQChannelPreemptionPriority = 0; 159 | USART3_DMA_Interrupt_Config.NVIC_IRQChannelSubPriority = 0; 160 | 161 | NVIC_Init(&USART3_DMA_Interrupt_Config); 162 | //NVIC_EnableIRQ(DMA1_Channel3_IRQn); 163 | 164 | 165 | DMA_Cmd(DMA1_Channel3,ENABLE); 166 | } 167 | 168 | 169 | 170 | /*void DMA1_Channel3_IRQHandler(void) 171 | { 172 | //DMA_ClearITPendingBit(DMA1_Channel3,DMA_IT_) 173 | lastUSARTCharReceived_Time = Millis(); 174 | }*/ 175 | 176 | 177 | 178 | void Init_USART3_RCC() 179 | { 180 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 181 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 182 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); // (Starts and attaches Peripheral clock for USART3) 183 | } 184 | 185 | GPIO_InitTypeDef GPIOB_Config_USART3; 186 | 187 | void Init_USART3_GPIO() 188 | { 189 | 190 | //For RX Pin --------------------------------- 191 | GPIOB_Config_USART3.GPIO_Speed = GPIO_Speed_50MHz; 192 | GPIOB_Config_USART3.GPIO_Mode = GPIO_Mode_IN_FLOATING; 193 | GPIOB_Config_USART3.GPIO_Pin = GPIO_Pin_11; 194 | GPIO_Init(GPIOB, &GPIOB_Config_USART3); // Saves above configuration to associated registers 195 | 196 | //-------------------------------------------- 197 | 198 | //For TX Pin --------------------------------- 199 | GPIOB_Config_USART3.GPIO_Mode = GPIO_Mode_AF_PP; // Alternate Function Push-Pull 200 | GPIOB_Config_USART3.GPIO_Pin = GPIO_Pin_10; 201 | GPIO_Init(GPIOB, &GPIOB_Config_USART3); // Saves above configuration to associated registers 202 | 203 | //-------------------------------------------- 204 | } 205 | 206 | NVIC_InitTypeDef USART3_Interrupt_Config; 207 | void Init_USART3_Interrupt() 208 | { 209 | //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 210 | 211 | USART3_Interrupt_Config.NVIC_IRQChannel = USART3_IRQn; 212 | USART3_Interrupt_Config.NVIC_IRQChannelPreemptionPriority = 0; 213 | USART3_Interrupt_Config.NVIC_IRQChannelSubPriority = 0; 214 | USART3_Interrupt_Config.NVIC_IRQChannelCmd = ENABLE; 215 | NVIC_Init(&USART3_Interrupt_Config); 216 | 217 | USART_ITConfig(USART3,USART_IT_RXNE, ENABLE); // Enable USART Interrupts 218 | //USART_ITConfig(USART3,USART_IT_TXE, ENABLE); 219 | } 220 | 221 | /*void USART3_SendString(char *MessageToSend) 222 | { 223 | while(MessageToSend++) 224 | { 225 | USART_SendData(USART3, MessageToSend); 226 | } 227 | } 228 | 229 | // Send "AT" to verify if ESP8266 is ready 230 | void USART3_Send_AT_TEST() 231 | { 232 | int i = 0; 233 | //AT+CWLAP 234 | while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); 235 | 236 | USART_SendData(USART3,'A'); 237 | 238 | while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); 239 | 240 | USART_SendData(USART3,'T'); 241 | 242 | while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); 243 | 244 | USART_SendData(USART3,'+'); 245 | 246 | while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); 247 | 248 | USART_SendData(USART3,'C'); 249 | 250 | while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); 251 | 252 | USART_SendData(USART3,'W'); 253 | 254 | while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); 255 | 256 | USART_SendData(USART3,'L'); 257 | 258 | while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); 259 | 260 | USART_SendData(USART3,'A'); 261 | 262 | while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); 263 | 264 | USART_SendData(USART3,'P'); 265 | 266 | while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); 267 | //USART_Send; 268 | USART_SendData(USART3,'\n'); 269 | for (i=0;i<500000;i++); 270 | } 271 | 272 | 273 | 274 | 275 | void USART3_SendNextChar() 276 | { 277 | 278 | }*/ 279 | 280 | // - Interrupt routines 281 | 282 | 283 | 284 | 285 | 286 | 287 | -------------------------------------------------------------------------------- /app/esp8266/source/esp8266.c: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************** 3 | * Author: Jacob Pagel 4 | * Date: 03/05/2015 5 | * esp8266.c (esp8266 wifi library source file) 6 | ********************************************************/ 7 | 8 | #include "esp8266.h" 9 | 10 | 11 | char *ESP_IPD_Data_Buffer_Pntr; 12 | char ESP_IPD_DataBuffer[RxBuffSize]; 13 | 14 | 15 | char commandToSend[70]; 16 | volatile uint8_t waitingForReponse = 0; 17 | volatile uint8_t OKFound = 0; 18 | volatile uint8_t ERRORFound = 0; 19 | volatile uint32_t TxWaitForResponse_TimeStmp = 0; 20 | //extern volatile char USART3_RxBuffer_Buffer[RxBuffSize]; 21 | extern volatile char USART3_RxBuffer[RxBuffSize]; 22 | 23 | uint32_t dimmingValueToValidate = 30000; //Just a starting value that is outside the allowed 24 | 25 | extern volatile uint32_t dimmingValue; 26 | extern uint32_t lastDMABuffPoll; 27 | 28 | 29 | uint16_t incommingDimmingValue = 0; 30 | char *dimmingString; 31 | char *URI; 32 | char *queryString1; 33 | char *queryValue1; 34 | char *queryString2; 35 | char *queryValue2; 36 | 37 | IPD_Data currentIPD; 38 | 39 | //METHOD DECLARATIONS 40 | IPD_Data ProcessIPD_Data(char *IPD_Buffer); 41 | 42 | 43 | 44 | const char *ATCommandsArray[18] = {"AT", 45 | "AT+CIPSTATUS", 46 | "AT+CWLAP", 47 | "AT+GMR", 48 | "AT+CWMODE?", 49 | "AT+CWMODE=3", 50 | "AT+CWJAP=\"SSID\",\"PASSWORD\"", 51 | "AT+CWJAP?", 52 | "AT+RST", 53 | "AT+CIPMUX=1", 54 | "AT+CIOBAUD=115200", 55 | "AT+CIPSERVER=1,80", 56 | "AT+CIFSR", 57 | "AT+CIPSTART=?", 58 | "AT+CWLIF", 59 | "AT+CWQAP", 60 | "AT+CWSAP=", 61 | "ATE0"}; 62 | 63 | 64 | const char *ESP_Responses[10] = 65 | { 66 | "ready", 67 | "Link", 68 | "Unlink", 69 | "OK", 70 | "SEND OK", 71 | "+IPD", 72 | "ERROR", 73 | "wrong syntax", 74 | "busy p...", 75 | "busy inet..." 76 | }; 77 | 78 | void ClearArray_Size(char buffer[], uint16_t size) 79 | { 80 | memset(buffer, '\0', size); 81 | } 82 | 83 | void SetArray_Size(char buffer[], uint16_t size) 84 | { 85 | memset(buffer, '1', size); 86 | } 87 | 88 | void Wifi_ReadyWaitForAnswer() 89 | { 90 | TxWaitForResponse_TimeStmp = Millis(); 91 | waitingForReponse = 1; 92 | 93 | } 94 | 95 | void Wifi_WaitForAnswer() 96 | { 97 | while(waitingForReponse == 1 && (Millis() - TxWaitForResponse_TimeStmp) < ESP_ResponseTimeout_ms); 98 | OKFound=0; 99 | ERRORFound=0; 100 | } 101 | 102 | 103 | char *WaitForAnswer_cmd_Buffer; 104 | char *WaitForAnswer_ans_Buffer; 105 | ///Will parse the USART buffer periodically (based on #defined poll interval) for the echo of cmdToWaitFor 106 | ///in the response from the ESP8266 module. 107 | void Wifi_WaitForAnswerCMD(char *cmdToWaitFor, uint16_t cmdSize) 108 | { 109 | 110 | while(waitingForReponse == 1 && (Millis() - TxWaitForResponse_TimeStmp) < ESP_ResponseTimeout_ms) 111 | { 112 | WaitForAnswer_cmd_Buffer = memmem(USART3_RxBuffer,RxBuffSize,cmdToWaitFor,cmdSize); 113 | if(strlen(WaitForAnswer_cmd_Buffer)>0) 114 | { 115 | if(WaitForAnswer_ans_Buffer = memmem(WaitForAnswer_cmd_Buffer,strlen(WaitForAnswer_cmd_Buffer),"OK\r\n",4)) 116 | { 117 | ClearArray_Size(WaitForAnswer_cmd_Buffer, strlen(WaitForAnswer_cmd_Buffer)); 118 | OKFound=1; 119 | waitingForReponse = 0; 120 | } 121 | //Check for OK or Error Message 122 | 123 | } 124 | 125 | }; 126 | //OKFound=0; 127 | //ERRORFound=0; 128 | } 129 | 130 | uint32_t pointerRange = 0; 131 | void Wifi_WaitForAnswer_SEND_OK(uint16_t cmdSize) 132 | { 133 | 134 | while(waitingForReponse == 1 && (Millis() - TxWaitForResponse_TimeStmp) < ESP_ResponseTimeout_ms) 135 | { 136 | WaitForAnswer_cmd_Buffer = memmem(USART3_RxBuffer,RxBuffSize,"AT+CIPSEND",10); 137 | if(strlen(WaitForAnswer_cmd_Buffer)>0) 138 | { 139 | while(waitingForReponse == 1 && (Millis() - TxWaitForResponse_TimeStmp) < ESP_ResponseTimeout_ms) 140 | { 141 | if(WaitForAnswer_ans_Buffer = memmem(USART3_RxBuffer,strlen(USART3_RxBuffer),"SEND OK\r\n",9)) 142 | { 143 | pointerRange = WaitForAnswer_cmd_Buffer - WaitForAnswer_ans_Buffer; 144 | ClearArray_Size(WaitForAnswer_cmd_Buffer, cmdSize + 9); 145 | OKFound=1; 146 | waitingForReponse = 0; 147 | } 148 | } 149 | //Check for OK or Error Message 150 | } 151 | } 152 | 153 | } 154 | 155 | 156 | char closeConnectionBuffer[15]; 157 | void Wifi_CloseConnection(uint8_t connectionNum) 158 | { 159 | sprintf(closeConnectionBuffer, "AT+CIPCLOSE=%d\r\n",connectionNum); 160 | Wifi_SendCustomCommand(closeConnectionBuffer); 161 | } 162 | 163 | 164 | void Wifi_SendCustomCommand(char *customMessage) 165 | { 166 | Wifi_SendCustomCommand_External_Wait(customMessage); 167 | 168 | Wifi_WaitForAnswer(); 169 | //for (wi=0;wi<735000;wi++); 170 | } 171 | 172 | void Wifi_SendCustomCommand_External_Wait(char *customMessage) 173 | { 174 | while(*customMessage) 175 | { 176 | while(USART_GetFlagStatus(ESP_USART,USART_FLAG_TXE) == RESET); 177 | USART_SendData(ESP_USART,*customMessage++); 178 | } 179 | 180 | while(USART_GetFlagStatus(ESP_USART, USART_FLAG_TXE) == RESET); 181 | USART_SendData(ESP_USART,'\r'); 182 | 183 | while(USART_GetFlagStatus(ESP_USART, USART_FLAG_TXE) == RESET); 184 | Wifi_ReadyWaitForAnswer(); 185 | USART_SendData(ESP_USART,'\n'); 186 | 187 | //Wifi_WaitForAnswer(); 188 | //for (wi=0;wi<735000;wi++); 189 | } 190 | 191 | //Waits to return untill wifi responds (OK or ERROR) 192 | void Wifi_SendCommand(Wifi_Commands command ) 193 | { 194 | const char *commandToSend = ATCommandsArray[command]; 195 | 196 | while(*commandToSend) 197 | { 198 | while(USART_GetFlagStatus(ESP_USART,USART_FLAG_TXE) == RESET); 199 | USART_SendData(ESP_USART,*commandToSend++); 200 | } 201 | Wifi_ReadyWaitForAnswer(); 202 | 203 | while(USART_GetFlagStatus(ESP_USART, USART_FLAG_TXE) == RESET); 204 | USART_SendData(ESP_USART,'\r'); 205 | 206 | //Wifi_ReadyWaitForAnswer(); 207 | while(USART_GetFlagStatus(ESP_USART, USART_FLAG_TXE) == RESET); 208 | 209 | USART_SendData(ESP_USART,'\n'); 210 | 211 | Wifi_WaitForAnswerCMD(ATCommandsArray[command], strlen(ATCommandsArray[command])); 212 | //for (wi=0;wi<735000;wi++); 213 | 214 | } 215 | 216 | char *IPD_Processing_buf; 217 | char *ConnectNum; 218 | //Breaks the IPD message into a proper request object 219 | IPD_Data ProcessIPD_Data(char *IPD_Buffer) 220 | { 221 | //IPD_Processing_buf = strdupa(IPD_Buffer); 222 | //IPD_Processing_buf = &IPD_Buffer + 5; 223 | IPD_Data thisIPDMessage; 224 | 225 | strtok(IPD_Buffer,","); 226 | 227 | ConnectNum = strtok(NULL,","); 228 | thisIPDMessage.ConnectionNum = atoi(ConnectNum); 229 | 230 | thisIPDMessage.DataSize = strtok(NULL,":"); 231 | //TODO: Probably need to add a check to make sure actual datasize matches expected.. 232 | 233 | thisIPDMessage.RequestType = strtok(NULL," "); 234 | 235 | thisIPDMessage.URI = strtok(NULL," "); 236 | 237 | strtok(NULL,"\r\n"); 238 | 239 | thisIPDMessage.Headers = strtok(NULL,"{"); 240 | 241 | thisIPDMessage.Body = strtok(NULL,"}"); 242 | return thisIPDMessage; 243 | 244 | } 245 | 246 | IPD_Data Wifi_CheckDMABuff_ForIPDData() 247 | { 248 | currentIPD.Valid = 0; 249 | //if((Millis() - lastDMABuffPoll) >= DMA_Rx_Buff_Poll_Int_ms) 250 | // { 251 | //Probably need to check for new client ({clientNum},CONNECT) 252 | lastDMABuffPoll = Millis(); 253 | ESP_IPD_Data_Buffer_Pntr = memmem(USART3_RxBuffer,RxBuffSize,"+IPD",4); 254 | if(ESP_IPD_Data_Buffer_Pntr) 255 | { 256 | //position = DMA_GetCurrDataCounter(DMA1_Channel3); 257 | //position = strlen(USART3_RxBuffer); 258 | //Copy IPD message and data to its own buffer so DMA can go about its business 259 | strcpy(ESP_IPD_DataBuffer,ESP_IPD_Data_Buffer_Pntr); 260 | DMA_Cmd(DMA1_Channel3,DISABLE); 261 | 262 | //Wipes the received message from the DMA buffer (using the pointer to the data) 263 | //This makes sure the data doesn't get mistaken for a new request, on the next buffer polling. 264 | ClearArray_Size(ESP_IPD_Data_Buffer_Pntr,strlen(ESP_IPD_Data_Buffer_Pntr)); 265 | DMA_Initialize(USART3_RxBuffer, RxBuffSize); 266 | 267 | 268 | //now we process since DMA isn't going to stomp on us. 269 | currentIPD = ProcessIPD_Data(ESP_IPD_DataBuffer); 270 | 271 | //TODO: Need to add a level of error detection/correction as data may be missing the 272 | if(strstr(currentIPD.RequestType, "POST")) 273 | { 274 | //if URI contains dimming (the test for now) 275 | if(strstr(currentIPD.URI, "dimming")) 276 | { 277 | if(strstr(currentIPD.URI, "?"))//If query String is found 278 | { 279 | URI = strtok(currentIPD.URI, "?"); 280 | if(strstr(URI,"="))//If URI was sent prepended with a '/' this will be true 281 | { 282 | queryString1 = strtok(URI, "="); 283 | 284 | queryValue1 = strtok(NULL, "\0"); 285 | } 286 | else 287 | { 288 | queryString1 = strtok(NULL, "="); 289 | if(strstr(currentIPD.URI, "&")) 290 | { 291 | queryValue1 = strtok(NULL, "&"); 292 | } 293 | else 294 | { 295 | queryValue1 = strtok(NULL, "\0"); 296 | } 297 | } 298 | currentIPD.Valid = 1; 299 | } 300 | 301 | dimmingValueToValidate = atoi(queryValue1); 302 | if(dimmingValueToValidate <= 13000) 303 | { 304 | dimmingValue = dimmingValueToValidate; 305 | 306 | RefreshCustomRESTResponseDimmer("172.20.112.136", "192.168.4.1", dimmingValue); 307 | //SendRESTResponse(currentIPD.ConnectionNum, RESTResponse_Headers_Test_OK, customRESTResponse); 308 | } 309 | else { 310 | RefreshCustomRESTResponse("172.20.112.136", "192.168.4.1", "dimmingValue", "InvalidValue"); 311 | } 312 | currentIPD.Valid = 1; 313 | } 314 | } 315 | //printf("Incoming webrequest\r\n"); 316 | } 317 | //DMA_Rx_Buff_Index = strlen(USART3_RxBuffer); 318 | //tstBuff = mempcpy(USART3_RxBuffer_Buffer, USART3_RxBuffer, RxBuffSize); 319 | //DMA_Rx_Buff_Index = tstBuff - &USART3_RxBuffer_Buffer[0]; 320 | //tstBuff = memmem(USART3_RxBuffer,sizeof(USART3_RxBuffer),"OK\r\n",4); 321 | //ClearArray_Size(USART3_RxBuffer, sizeof(USART3_RxBuffer)); 322 | 323 | // } 324 | 325 | return currentIPD; 326 | } 327 | 328 | 329 | ///Pretty self explanatory 330 | void ConnectToAP(char *apName, char *password) //Will utilize the arguments later, for now static to Nonya 331 | { 332 | //TODO: Need to add check that ESP is in a compatible client mode 333 | sprintf(commandToSend,"AT+CWJAP=\"%s\",\"%s\"",apName,password); 334 | Wifi_SendCustomCommand(commandToSend); 335 | } 336 | 337 | //Configures ESP82667 Access Point with given parameters. 338 | void StartLocalAP(char *SSID, char *password, uint8_t channel, Available_Encyption encypt) 339 | { 340 | sprintf(commandToSend, "AT+CWSAP=\"\",\"\",\"\",\"\""); 341 | } 342 | -------------------------------------------------------------------------------- /stdio/printf.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************//***** 2 | * @file printf.c 3 | * @brief Implementation of several stdio.h methods, such as printf(), 4 | * sprintf() and so on. This reduces the memory footprint of the 5 | * binary when using those methods, compared to the libc implementation. 6 | ********************************************************************************/ 7 | #include 8 | #include 9 | #include "semihosting.h" 10 | 11 | /** 12 | * @brief Transmit a char, if you want to use printf(), 13 | * you need implement this function 14 | * 15 | * @param pStr Storage string. 16 | * @param c Character to write. 17 | */ 18 | void PrintChar(char c) 19 | { 20 | SH_SendChar(c); 21 | /* Send a char like: 22 | while(Transfer not completed); 23 | Transmit a char; 24 | */ 25 | } 26 | 27 | /** Maximum string size allowed (in bytes). */ 28 | #define MAX_STRING_SIZE 100 29 | 30 | 31 | /** Required for proper compilation. */ 32 | struct _reent r = {0, (FILE *) 0, (FILE *) 1, (FILE *) 0}; 33 | struct _reent *_impure_ptr = &r; 34 | 35 | /** 36 | * @brief Writes a character inside the given string. Returns 1. 37 | * 38 | * @param pStr Storage string. 39 | * @param c Character to write. 40 | */ 41 | signed int PutChar(char *pStr, char c) 42 | { 43 | *pStr = c; 44 | return 1; 45 | } 46 | 47 | 48 | /** 49 | * @brief Writes a string inside the given string. 50 | * 51 | * @param pStr Storage string. 52 | * @param pSource Source string. 53 | * @return The size of the written 54 | */ 55 | signed int PutString(char *pStr, const char *pSource) 56 | { 57 | signed int num = 0; 58 | 59 | while (*pSource != 0) { 60 | 61 | *pStr++ = *pSource++; 62 | num++; 63 | } 64 | 65 | return num; 66 | } 67 | 68 | 69 | /** 70 | * @brief Writes an unsigned int inside the given string, using the provided fill & 71 | * width parameters. 72 | * 73 | * @param pStr Storage string. 74 | * @param fill Fill character. 75 | * @param width Minimum integer width. 76 | * @param value Integer value. 77 | */ 78 | signed int PutUnsignedInt( 79 | char *pStr, 80 | char fill, 81 | signed int width, 82 | unsigned int value) 83 | { 84 | signed int num = 0; 85 | 86 | /* Take current digit into account when calculating width */ 87 | width--; 88 | 89 | /* Recursively write upper digits */ 90 | if ((value / 10) > 0) { 91 | 92 | num = PutUnsignedInt(pStr, fill, width, value / 10); 93 | pStr += num; 94 | } 95 | 96 | /* Write filler characters */ 97 | else { 98 | 99 | while (width > 0) { 100 | 101 | PutChar(pStr, fill); 102 | pStr++; 103 | num++; 104 | width--; 105 | } 106 | } 107 | 108 | /* Write lower digit */ 109 | num += PutChar(pStr, (value % 10) + '0'); 110 | 111 | return num; 112 | } 113 | 114 | 115 | /** 116 | * @brief Writes a signed int inside the given string, using the provided fill & width 117 | * parameters. 118 | * 119 | * @param pStr Storage string. 120 | * @param fill Fill character. 121 | * @param width Minimum integer width. 122 | * @param value Signed integer value. 123 | */ 124 | signed int PutSignedInt( 125 | char *pStr, 126 | char fill, 127 | signed int width, 128 | signed int value) 129 | { 130 | signed int num = 0; 131 | unsigned int absolute; 132 | 133 | /* Compute absolute value */ 134 | if (value < 0) { 135 | 136 | absolute = -value; 137 | } 138 | else { 139 | 140 | absolute = value; 141 | } 142 | 143 | /* Take current digit into account when calculating width */ 144 | width--; 145 | 146 | /* Recursively write upper digits */ 147 | if ((absolute / 10) > 0) { 148 | 149 | if (value < 0) { 150 | 151 | num = PutSignedInt(pStr, fill, width, -(absolute / 10)); 152 | } 153 | else { 154 | 155 | num = PutSignedInt(pStr, fill, width, absolute / 10); 156 | } 157 | pStr += num; 158 | } 159 | else { 160 | 161 | /* Reserve space for sign */ 162 | if (value < 0) { 163 | 164 | width--; 165 | } 166 | 167 | /* Write filler characters */ 168 | while (width > 0) { 169 | 170 | PutChar(pStr, fill); 171 | pStr++; 172 | num++; 173 | width--; 174 | } 175 | 176 | /* Write sign */ 177 | if (value < 0) { 178 | 179 | num += PutChar(pStr, '-'); 180 | pStr++; 181 | } 182 | } 183 | 184 | /* Write lower digit */ 185 | num += PutChar(pStr, (absolute % 10) + '0'); 186 | 187 | return num; 188 | } 189 | 190 | 191 | /** 192 | * @brief Writes an hexadecimal value into a string, using the given fill, width & 193 | * capital parameters. 194 | * 195 | * @param pStr Storage string. 196 | * @param fill Fill character. 197 | * @param width Minimum integer width. 198 | * @param maj Indicates if the letters must be printed in lower- or upper-case. 199 | * @param value Hexadecimal value. 200 | * 201 | * @return The number of char written 202 | */ 203 | signed int PutHexa( 204 | char *pStr, 205 | char fill, 206 | signed int width, 207 | unsigned char maj, 208 | unsigned int value) 209 | { 210 | signed int num = 0; 211 | 212 | /* Decrement width */ 213 | width--; 214 | 215 | /* Recursively output upper digits */ 216 | if ((value >> 4) > 0) { 217 | 218 | num += PutHexa(pStr, fill, width, maj, value >> 4); 219 | pStr += num; 220 | } 221 | /* Write filler chars */ 222 | else { 223 | 224 | while (width > 0) { 225 | 226 | PutChar(pStr, fill); 227 | pStr++; 228 | num++; 229 | width--; 230 | } 231 | } 232 | 233 | /* Write current digit */ 234 | if ((value & 0xF) < 10) { 235 | 236 | PutChar(pStr, (value & 0xF) + '0'); 237 | } 238 | else if (maj) { 239 | 240 | PutChar(pStr, (value & 0xF) - 10 + 'A'); 241 | } 242 | else { 243 | 244 | PutChar(pStr, (value & 0xF) - 10 + 'a'); 245 | } 246 | num++; 247 | 248 | return num; 249 | } 250 | 251 | 252 | 253 | /* Global Functions ----------------------------------------------------------- */ 254 | 255 | 256 | /** 257 | * @brief Stores the result of a formatted string into another string. Format 258 | * arguments are given in a va_list instance. 259 | * 260 | * @param pStr Destination string. 261 | * @param length Length of Destination string. 262 | * @param pFormat Format string. 263 | * @param ap Argument list. 264 | * 265 | * @return The number of characters written. 266 | */ 267 | signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap) 268 | { 269 | char fill; 270 | unsigned char width; 271 | signed int num = 0; 272 | signed int size = 0; 273 | 274 | /* Clear the string */ 275 | if (pStr) { 276 | 277 | *pStr = 0; 278 | } 279 | 280 | /* Phase string */ 281 | while (*pFormat != 0 && size < length) { 282 | 283 | /* Normal character */ 284 | if (*pFormat != '%') { 285 | 286 | *pStr++ = *pFormat++; 287 | size++; 288 | } 289 | /* Escaped '%' */ 290 | else if (*(pFormat+1) == '%') { 291 | 292 | *pStr++ = '%'; 293 | pFormat += 2; 294 | size++; 295 | } 296 | /* Token delimiter */ 297 | else { 298 | 299 | fill = ' '; 300 | width = 0; 301 | pFormat++; 302 | 303 | /* Parse filler */ 304 | if (*pFormat == '0') { 305 | 306 | fill = '0'; 307 | pFormat++; 308 | } 309 | 310 | /* Parse width */ 311 | while ((*pFormat >= '0') && (*pFormat <= '9')) { 312 | 313 | width = (width*10) + *pFormat-'0'; 314 | pFormat++; 315 | } 316 | 317 | /* Check if there is enough space */ 318 | if (size + width > length) { 319 | 320 | width = length - size; 321 | } 322 | 323 | /* Parse type */ 324 | switch (*pFormat) { 325 | case 'd': 326 | case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break; 327 | case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break; 328 | case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break; 329 | case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break; 330 | case 's': num = PutString(pStr, va_arg(ap, char *)); break; 331 | case 'c': num = PutChar(pStr, va_arg(ap, unsigned int)); break; 332 | default: 333 | return EOF; 334 | } 335 | 336 | pFormat++; 337 | pStr += num; 338 | size += num; 339 | } 340 | } 341 | 342 | /* NULL-terminated (final \0 is not counted) */ 343 | if (size < length) { 344 | 345 | *pStr = 0; 346 | } 347 | else { 348 | 349 | *(--pStr) = 0; 350 | size--; 351 | } 352 | 353 | return size; 354 | } 355 | 356 | 357 | /** 358 | * @brief Stores the result of a formatted string into another string. Format 359 | * arguments are given in a va_list instance. 360 | * 361 | * @param pStr Destination string. 362 | * @param length Length of Destination string. 363 | * @param pFormat Format string. 364 | * @param ... Other arguments 365 | * 366 | * @return The number of characters written. 367 | */ 368 | signed int snprintf(char *pString, size_t length, const char *pFormat, ...) 369 | { 370 | va_list ap; 371 | signed int rc; 372 | 373 | va_start(ap, pFormat); 374 | rc = vsnprintf(pString, length, pFormat, ap); 375 | va_end(ap); 376 | 377 | return rc; 378 | } 379 | 380 | 381 | /** 382 | * @brief Stores the result of a formatted string into another string. Format 383 | * arguments are given in a va_list instance. 384 | * 385 | * @param pString Destination string. 386 | * @param length Length of Destination string. 387 | * @param pFormat Format string. 388 | * @param ap Argument list. 389 | * 390 | * @return The number of characters written. 391 | */ 392 | signed int vsprintf(char *pString, const char *pFormat, va_list ap) 393 | { 394 | return vsnprintf(pString, MAX_STRING_SIZE, pFormat, ap); 395 | } 396 | 397 | /** 398 | * @brief Outputs a formatted string on the given stream. Format arguments are given 399 | * in a va_list instance. 400 | * 401 | * @param pStream Output stream. 402 | * @param pFormat Format string 403 | * @param ap Argument list. 404 | */ 405 | signed int vfprintf(FILE *pStream, const char *pFormat, va_list ap) 406 | { 407 | char pStr[MAX_STRING_SIZE]; 408 | char pError[] = "stdio.c: increase MAX_STRING_SIZE\n\r"; 409 | 410 | /* Write formatted string in buffer */ 411 | if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) { 412 | 413 | fputs(pError, stderr); 414 | while (1); /* Increase MAX_STRING_SIZE */ 415 | } 416 | 417 | /* Display string */ 418 | return fputs(pStr, pStream); 419 | } 420 | 421 | 422 | /** 423 | * @brief Outputs a formatted string on the DBGU stream. Format arguments are given 424 | * in a va_list instance. 425 | * 426 | * @param pFormat Format string. 427 | * @param ap Argument list. 428 | */ 429 | signed int vprintf(const char *pFormat, va_list ap) 430 | { 431 | return vfprintf(stdout, pFormat, ap); 432 | } 433 | 434 | 435 | /** 436 | * @brief Outputs a formatted string on the given stream, using a variable 437 | * number of arguments. 438 | * 439 | * @param pStream Output stream. 440 | * @param pFormat Format string. 441 | */ 442 | signed int fprintf(FILE *pStream, const char *pFormat, ...) 443 | { 444 | va_list ap; 445 | signed int result; 446 | 447 | /* Forward call to vfprintf */ 448 | va_start(ap, pFormat); 449 | result = vfprintf(pStream, pFormat, ap); 450 | va_end(ap); 451 | 452 | return result; 453 | } 454 | 455 | 456 | /** 457 | * @brief Outputs a formatted string on the DBGU stream, using a variable number of 458 | * arguments. 459 | * 460 | * @param pFormat Format string. 461 | */ 462 | signed int printf(const char *pFormat, ...) 463 | { 464 | va_list ap; 465 | signed int result; 466 | 467 | /* Forward call to vprintf */ 468 | va_start(ap, pFormat); 469 | result = vprintf(pFormat, ap); 470 | va_end(ap); 471 | 472 | return result; 473 | } 474 | 475 | 476 | /** 477 | * @brief Writes a formatted string inside another string. 478 | * 479 | * @param pStr torage string. 480 | * @param pFormat Format string. 481 | */ 482 | signed int sprintf(char *pStr, const char *pFormat, ...) 483 | { 484 | va_list ap; 485 | signed int result; 486 | 487 | // Forward call to vsprintf 488 | va_start(ap, pFormat); 489 | result = vsprintf(pStr, pFormat, ap); 490 | va_end(ap); 491 | 492 | return result; 493 | } 494 | 495 | 496 | /** 497 | * @brief Outputs a string on stdout. 498 | * 499 | * @param pStr String to output. 500 | */ 501 | signed int puts(const char *pStr) 502 | { 503 | return fputs(pStr, stdout); 504 | } 505 | 506 | 507 | /** 508 | * @brief Implementation of fputc using the DBGU as the standard output. Required 509 | * for printf(). 510 | * 511 | * @param c Character to write. 512 | * @param pStream Output stream. 513 | * @param The character written if successful, or -1 if the output stream is 514 | * not stdout or stderr. 515 | */ 516 | signed int fputc(signed int c, FILE *pStream) 517 | { 518 | if ((pStream == stdout) || (pStream == stderr)) { 519 | 520 | PrintChar(c); 521 | 522 | return c; 523 | } 524 | else { 525 | 526 | return EOF; 527 | } 528 | } 529 | 530 | 531 | /** 532 | * @brief Implementation of fputs using the DBGU as the standard output. Required 533 | * for printf(). 534 | * 535 | * @param pStr String to write. 536 | * @param pStream Output stream. 537 | * 538 | * @return Number of characters written if successful, or -1 if the output 539 | * stream is not stdout or stderr. 540 | */ 541 | signed int fputs(const char *pStr, FILE *pStream) 542 | { 543 | signed int num = 0; 544 | 545 | while (*pStr != 0) { 546 | 547 | if (fputc(*pStr, pStream) == -1) { 548 | 549 | return -1; 550 | } 551 | num++; 552 | pStr++; 553 | } 554 | 555 | return num; 556 | } 557 | 558 | /* --------------------------------- End Of File ------------------------------ */ 559 | -------------------------------------------------------------------------------- /app/cmsis_boot/startup/startup_stm32f10x_md.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file startup_stm32f10x_md.c 4 | * @author Coocox 5 | * @version V1.0 6 | * @date 12/23/2009 7 | * @brief STM32F10x Medium Density Devices Startup code. 8 | * This module performs: 9 | * - Set the initial SP 10 | * - Set the vector table entries with the exceptions ISR address 11 | * - Initialize data and bss 12 | * - Setup the microcontroller system. 13 | * - Call the application's entry point. 14 | * After Reset the Cortex-M3 processor is in Thread mode, 15 | * priority is Privileged, and the Stack is set to Main. 16 | ******************************************************************************* 17 | */ 18 | 19 | 20 | /*----------Stack Configuration-----------------------------------------------*/ 21 | #define STACK_SIZE 0x00000100 /*!< The Stack size suggest using even number */ 22 | __attribute__ ((section(".co_stack"))) 23 | unsigned long pulStack[STACK_SIZE]; 24 | 25 | 26 | /*----------Macro definition--------------------------------------------------*/ 27 | #define WEAK __attribute__ ((weak)) 28 | 29 | 30 | /*----------Declaration of the default fault handlers-------------------------*/ 31 | /* System exception vector handler */ 32 | __attribute__ ((used)) 33 | void WEAK Reset_Handler(void); 34 | void WEAK NMI_Handler(void); 35 | void WEAK HardFault_Handler(void); 36 | void WEAK MemManage_Handler(void); 37 | void WEAK BusFault_Handler(void); 38 | void WEAK UsageFault_Handler(void); 39 | void WEAK SVC_Handler(void); 40 | void WEAK DebugMon_Handler(void); 41 | void WEAK PendSV_Handler(void); 42 | void WEAK SysTick_Handler(void); 43 | void WEAK WWDG_IRQHandler(void); 44 | void WEAK PVD_IRQHandler(void); 45 | void WEAK TAMPER_IRQHandler(void); 46 | void WEAK RTC_IRQHandler(void); 47 | void WEAK FLASH_IRQHandler(void); 48 | void WEAK RCC_IRQHandler(void); 49 | void WEAK EXTI0_IRQHandler(void); 50 | void WEAK EXTI1_IRQHandler(void); 51 | void WEAK EXTI2_IRQHandler(void); 52 | void WEAK EXTI3_IRQHandler(void); 53 | void WEAK EXTI4_IRQHandler(void); 54 | void WEAK DMA1_Channel1_IRQHandler(void); 55 | void WEAK DMA1_Channel2_IRQHandler(void); 56 | void WEAK DMA1_Channel3_IRQHandler(void); 57 | void WEAK DMA1_Channel4_IRQHandler(void); 58 | void WEAK DMA1_Channel5_IRQHandler(void); 59 | void WEAK DMA1_Channel6_IRQHandler(void); 60 | void WEAK DMA1_Channel7_IRQHandler(void); 61 | void WEAK ADC1_2_IRQHandler(void); 62 | void WEAK USB_HP_CAN1_TX_IRQHandler(void); 63 | void WEAK USB_LP_CAN1_RX0_IRQHandler(void); 64 | void WEAK CAN1_RX1_IRQHandler(void); 65 | void WEAK CAN1_SCE_IRQHandler(void); 66 | void WEAK EXTI9_5_IRQHandler(void); 67 | void WEAK TIM1_BRK_IRQHandler(void); 68 | void WEAK TIM1_UP_IRQHandler(void); 69 | void WEAK TIM1_TRG_COM_IRQHandler(void); 70 | void WEAK TIM1_CC_IRQHandler(void); 71 | void WEAK TIM2_IRQHandler(void); 72 | void WEAK TIM3_IRQHandler(void); 73 | void WEAK TIM4_IRQHandler(void); 74 | void WEAK I2C1_EV_IRQHandler(void); 75 | void WEAK I2C1_ER_IRQHandler(void); 76 | void WEAK I2C2_EV_IRQHandler(void); 77 | void WEAK I2C2_ER_IRQHandler(void); 78 | void WEAK SPI1_IRQHandler(void); 79 | void WEAK SPI2_IRQHandler(void); 80 | void WEAK USART1_IRQHandler(void); 81 | void WEAK USART2_IRQHandler(void); 82 | void WEAK USART3_IRQHandler(void); 83 | void WEAK EXTI15_10_IRQHandler(void); 84 | void WEAK RTCAlarm_IRQHandler(void); 85 | void WEAK USBWakeUp_IRQHandler(void); 86 | 87 | 88 | /*----------Symbols defined in linker script----------------------------------*/ 89 | extern unsigned long _sidata; /*!< Start address for the initialization 90 | values of the .data section. */ 91 | extern unsigned long _sdata; /*!< Start address for the .data section */ 92 | extern unsigned long _edata; /*!< End address for the .data section */ 93 | extern unsigned long _sbss; /*!< Start address for the .bss section */ 94 | extern unsigned long _ebss; /*!< End address for the .bss section */ 95 | extern void _eram; /*!< End address for ram */ 96 | 97 | 98 | /*----------Function prototypes-----------------------------------------------*/ 99 | extern int main(void); /*!< The entry point for the application. */ 100 | extern void SystemInit(void); /*!< Setup the microcontroller system(CMSIS) */ 101 | void Default_Reset_Handler(void); /*!< Default reset handler */ 102 | static void Default_Handler(void); /*!< Default exception handler */ 103 | 104 | 105 | /** 106 | *@brief The minimal vector table for a Cortex M3. Note that the proper constructs 107 | * must be placed on this to ensure that it ends up at physical address 108 | * 0x00000000. 109 | */ 110 | __attribute__ ((used,section(".isr_vector"))) 111 | void (* const g_pfnVectors[])(void) = 112 | { 113 | /*----------Core Exceptions-------------------------------------------------*/ 114 | (void *)&pulStack[STACK_SIZE], /*!< The initial stack pointer */ 115 | Reset_Handler, /*!< Reset Handler */ 116 | NMI_Handler, /*!< NMI Handler */ 117 | HardFault_Handler, /*!< Hard Fault Handler */ 118 | MemManage_Handler, /*!< MPU Fault Handler */ 119 | BusFault_Handler, /*!< Bus Fault Handler */ 120 | UsageFault_Handler, /*!< Usage Fault Handler */ 121 | 0,0,0,0, /*!< Reserved */ 122 | SVC_Handler, /*!< SVCall Handler */ 123 | DebugMon_Handler, /*!< Debug Monitor Handler */ 124 | 0, /*!< Reserved */ 125 | PendSV_Handler, /*!< PendSV Handler */ 126 | SysTick_Handler, /*!< SysTick Handler */ 127 | 128 | /*----------External Exceptions---------------------------------------------*/ 129 | WWDG_IRQHandler, /*!< 0: Window Watchdog */ 130 | PVD_IRQHandler, /*!< 1: PVD through EXTI Line detect */ 131 | TAMPER_IRQHandler, /*!< 2: Tamper */ 132 | RTC_IRQHandler, /*!< 3: RTC */ 133 | FLASH_IRQHandler, /*!< 4: Flash */ 134 | RCC_IRQHandler, /*!< 5: RCC */ 135 | EXTI0_IRQHandler, /*!< 6: EXTI Line 0 */ 136 | EXTI1_IRQHandler, /*!< 7: EXTI Line 1 */ 137 | EXTI2_IRQHandler, /*!< 8: EXTI Line 2 */ 138 | EXTI3_IRQHandler, /*!< 9: EXTI Line 3 */ 139 | EXTI4_IRQHandler, /*!< 10: EXTI Line 4 */ 140 | DMA1_Channel1_IRQHandler, /*!< 11: DMA1 Channel 1 */ 141 | DMA1_Channel2_IRQHandler, /*!< 12: DMA1 Channel 2 */ 142 | DMA1_Channel3_IRQHandler, /*!< 13: DMA1 Channel 3 */ 143 | DMA1_Channel4_IRQHandler, /*!< 14: DMA1 Channel 4 */ 144 | DMA1_Channel5_IRQHandler, /*!< 15: DMA1 Channel 5 */ 145 | DMA1_Channel6_IRQHandler, /*!< 16: DMA1 Channel 6 */ 146 | DMA1_Channel7_IRQHandler, /*!< 17: DMA1 Channel 7 */ 147 | ADC1_2_IRQHandler, /*!< 18: ADC1 & ADC2 */ 148 | USB_HP_CAN1_TX_IRQHandler, /*!< 19: USB High Priority or CAN1 TX */ 149 | USB_LP_CAN1_RX0_IRQHandler, /*!< 20: USB Low Priority or CAN1 RX0 */ 150 | CAN1_RX1_IRQHandler, /*!< 21: CAN1 RX1 */ 151 | CAN1_SCE_IRQHandler, /*!< 22: CAN1 SCE */ 152 | EXTI9_5_IRQHandler, /*!< 23: EXTI Line 9..5 */ 153 | TIM1_BRK_IRQHandler, /*!< 24: TIM1 Break */ 154 | TIM1_UP_IRQHandler, /*!< 25: TIM1 Update */ 155 | TIM1_TRG_COM_IRQHandler, /*!< 26: TIM1 Trigger and Commutation */ 156 | TIM1_CC_IRQHandler, /*!< 27: TIM1 Capture Compare */ 157 | TIM2_IRQHandler, /*!< 28: TIM2 */ 158 | TIM3_IRQHandler, /*!< 29: TIM3 */ 159 | TIM4_IRQHandler, /*!< 30: TIM4 */ 160 | I2C1_EV_IRQHandler, /*!< 31: I2C1 Event */ 161 | I2C1_ER_IRQHandler, /*!< 32: I2C1 Error */ 162 | I2C2_EV_IRQHandler, /*!< 33: I2C2 Event */ 163 | I2C2_ER_IRQHandler, /*!< 34: I2C2 Error */ 164 | SPI1_IRQHandler, /*!< 35: SPI1 */ 165 | SPI2_IRQHandler, /*!< 36: SPI2 */ 166 | USART1_IRQHandler, /*!< 37: USART1 */ 167 | USART2_IRQHandler, /*!< 38: USART2 */ 168 | USART3_IRQHandler, /*!< 39: USART3 */ 169 | EXTI15_10_IRQHandler, /*!< 40: EXTI Line 15..10 */ 170 | RTCAlarm_IRQHandler, /*!< 41: RTC Alarm through EXTI Line */ 171 | USBWakeUp_IRQHandler, /*!< 42: USB Wakeup from suspend */ 172 | 0,0,0,0,0,0,0, /*!< Reserved */ 173 | (void *)0xF108F85F /*!< Boot in RAM mode */ 174 | }; 175 | 176 | 177 | /** 178 | * @brief This is the code that gets called when the processor first 179 | * starts execution following a reset event. Only the absolutely 180 | * necessary set is performed, after which the application 181 | * supplied main() routine is called. 182 | * @param None 183 | * @retval None 184 | */ 185 | void Default_Reset_Handler(void) 186 | { 187 | /* Initialize data and bss */ 188 | unsigned long *pulSrc, *pulDest; 189 | 190 | /* Copy the data segment initializers from flash to SRAM */ 191 | pulSrc = &_sidata; 192 | 193 | for(pulDest = &_sdata; pulDest < &_edata; ) 194 | { 195 | *(pulDest++) = *(pulSrc++); 196 | } 197 | 198 | /* Zero fill the bss segment. This is done with inline assembly since this 199 | will clear the value of pulDest if it is not kept in a register. */ 200 | __asm(" ldr r0, =_sbss\n" 201 | " ldr r1, =_ebss\n" 202 | " mov r2, #0\n" 203 | " .thumb_func\n" 204 | "zero_loop:\n" 205 | " cmp r0, r1\n" 206 | " it lt\n" 207 | " strlt r2, [r0], #4\n" 208 | " blt zero_loop"); 209 | 210 | /* Setup the microcontroller system. */ 211 | SystemInit(); 212 | 213 | /* Call the application's entry point.*/ 214 | main(); 215 | } 216 | 217 | /** 218 | *@brief Provide weak aliases for each Exception handler to the Default_Handler. 219 | * As they are weak aliases, any function with the same name will override 220 | * this definition. 221 | */ 222 | #pragma weak Reset_Handler = Default_Reset_Handler 223 | #pragma weak NMI_Handler = Default_Handler 224 | #pragma weak HardFault_Handler = Default_Handler 225 | #pragma weak MemManage_Handler = Default_Handler 226 | #pragma weak BusFault_Handler = Default_Handler 227 | #pragma weak UsageFault_Handler = Default_Handler 228 | #pragma weak SVC_Handler = Default_Handler 229 | #pragma weak DebugMon_Handler = Default_Handler 230 | #pragma weak PendSV_Handler = Default_Handler 231 | #pragma weak SysTick_Handler = Default_Handler 232 | #pragma weak WWDG_IRQHandler = Default_Handler 233 | #pragma weak PVD_IRQHandler = Default_Handler 234 | #pragma weak TAMPER_IRQHandler = Default_Handler 235 | #pragma weak RTC_IRQHandler = Default_Handler 236 | #pragma weak FLASH_IRQHandler = Default_Handler 237 | #pragma weak RCC_IRQHandler = Default_Handler 238 | #pragma weak EXTI0_IRQHandler = Default_Handler 239 | #pragma weak EXTI1_IRQHandler = Default_Handler 240 | #pragma weak EXTI2_IRQHandler = Default_Handler 241 | #pragma weak EXTI3_IRQHandler = Default_Handler 242 | #pragma weak EXTI4_IRQHandler = Default_Handler 243 | #pragma weak DMA1_Channel1_IRQHandler = Default_Handler 244 | #pragma weak DMA1_Channel2_IRQHandler = Default_Handler 245 | #pragma weak DMA1_Channel3_IRQHandler = Default_Handler 246 | #pragma weak DMA1_Channel4_IRQHandler = Default_Handler 247 | #pragma weak DMA1_Channel5_IRQHandler = Default_Handler 248 | #pragma weak DMA1_Channel6_IRQHandler = Default_Handler 249 | #pragma weak DMA1_Channel7_IRQHandler = Default_Handler 250 | #pragma weak ADC1_2_IRQHandler = Default_Handler 251 | #pragma weak USB_HP_CAN1_TX_IRQHandler = Default_Handler 252 | #pragma weak USB_LP_CAN1_RX0_IRQHandler = Default_Handler 253 | #pragma weak CAN1_RX1_IRQHandler = Default_Handler 254 | #pragma weak CAN1_SCE_IRQHandler = Default_Handler 255 | #pragma weak EXTI9_5_IRQHandler = Default_Handler 256 | #pragma weak TIM1_BRK_IRQHandler = Default_Handler 257 | #pragma weak TIM1_UP_IRQHandler = Default_Handler 258 | #pragma weak TIM1_TRG_COM_IRQHandler = Default_Handler 259 | #pragma weak TIM1_CC_IRQHandler = Default_Handler 260 | #pragma weak TIM2_IRQHandler = Default_Handler 261 | #pragma weak TIM3_IRQHandler = Default_Handler 262 | #pragma weak TIM4_IRQHandler = Default_Handler 263 | #pragma weak I2C1_EV_IRQHandler = Default_Handler 264 | #pragma weak I2C1_ER_IRQHandler = Default_Handler 265 | #pragma weak I2C2_EV_IRQHandler = Default_Handler 266 | #pragma weak I2C2_ER_IRQHandler = Default_Handler 267 | #pragma weak SPI1_IRQHandler = Default_Handler 268 | #pragma weak SPI2_IRQHandler = Default_Handler 269 | #pragma weak USART1_IRQHandler = Default_Handler 270 | #pragma weak USART2_IRQHandler = Default_Handler 271 | #pragma weak USART3_IRQHandler = Default_Handler 272 | #pragma weak EXTI15_10_IRQHandler = Default_Handler 273 | #pragma weak RTCAlarm_IRQHandler = Default_Handler 274 | #pragma weak USBWakeUp_IRQHandler = Default_Handler 275 | 276 | 277 | /** 278 | * @brief This is the code that gets called when the processor receives an 279 | * unexpected interrupt. This simply enters an infinite loop, 280 | * preserving the system state for examination by a debugger. 281 | * @param None 282 | * @retval None 283 | */ 284 | static void Default_Handler(void) 285 | { 286 | /* Go into an infinite loop. */ 287 | while (1) 288 | { 289 | } 290 | } 291 | 292 | /*********************** (C) COPYRIGHT 2009 Coocox ************END OF FILE*****/ 293 | -------------------------------------------------------------------------------- /app/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f10x.h" 2 | #include "misc.h" 3 | //#include "stm32f10x_usart.h" 4 | #include "stm32f10x_gpio.h" 5 | #include 6 | #include "stm32f10x_rcc.h" 7 | #include 8 | #include "stm32f10x_adc.h" 9 | #include "stm32f10x_exti.h" 10 | #include "USART3_Config.h" 11 | #include "USART1_Config.h" 12 | #include 13 | //#include 14 | //#include "GeneralMacros.h" 15 | #include "globalDefines.h" 16 | #include "time.h" 17 | 18 | //#include "helpers.h" 19 | //#include "Wifi.h" 20 | //#include "GetCommands.h" 21 | 22 | 23 | #include "esp8266/include/esp8266.h" 24 | #include "Server/WebServer.h" 25 | 26 | 27 | /* 28 | * Possible Rx Command syntax 29 | * ::CMD:DIM:XXX:|: - :|: = end of transmission 30 | * ::CMD:DIM:XXX:??SECURITY_KEY??:|: Dim value only 3 chars as last two will just be 0's 31 | * - XXXXX = 16bit Dimming value 1-15000 (max value is dependent on LED vs incondecant) 32 | * - ??SECURITY_KEY?? = some (rotating if possible) security authentication key. 33 | * 34 | * 35 | * - Possible Different Commands (CMD) 36 | * - DIM - Dimming command (obviously) 37 | * - RST - Triggers soft reboot (Mainly a restart back to main) 38 | * - HRDRST - Hardware triggered system reboot 39 | */ 40 | 41 | /* 42 | * DO NOT USE THESE PINS!!!!! (SWD DEBUG AND PROGRAM INTERFACE) these can be re-mapped if required. 43 | * PA14 - SWCLK 44 | * PA13 - SWDIO 45 | * 46 | */ 47 | 48 | /* 49 | //TYPEDEF DECLARATIONS 50 | typedef struct{ 51 | uint8_t ConnectionNum; 52 | char *DataSize; 53 | char *RequestType; //ie.. POST, GET, PUT, DELETE 54 | char *URI; //ie.. /api/foo?id=123 55 | char *Headers; 56 | char *Body; 57 | }IPD_Data; 58 | 59 | 60 | 61 | //METHOD DECLARATIONS 62 | IPD_Data ProcessIPD_Data(char *IPD_Buffer); 63 | */ 64 | 65 | 66 | //#define RxBuffSize 400 67 | //#define USART_TxComplete_Timeout_ms 1000 68 | #define TxBufferSize (countof(USART3_TxBuffer) - 1) 69 | #define USART3_RxBufferSize (countof(USART3_RxBuffer) - 1) 70 | #define USART1_RxBufferSize (countof(USART1_RxBuffer) - 1) 71 | //#define DMA_Rx_Buff_Poll_Int_ms 200 72 | 73 | //char *testProto = "TCP"; 74 | //char *testIP = "172.20.112.1"; 75 | //uint16_t testPort = 80; 76 | 77 | //Wifi related Variables and declarations 78 | //#define WIFI_COMMAND_ERROR "ERROR" // Expected response from ESP8266 on error 79 | //#define WIFI_COMMAND_ACCEPTED "OK" // Expected response from ESP8266 on succesful command process 80 | //#define WIFI_RX_LineComplete = "\r\n" 81 | char WIFI_CMD_RECEIVE_COMPLETE[] = ":|:"; // Will be appended to the end of a valid command 82 | 83 | //Current_CMD parsedCommand; 84 | 85 | volatile char CMD_FULL_Incomming[13]; 86 | char CMD_FULL_ResponseBuffer[25]; 87 | volatile char byteToCommand[2]; 88 | 89 | volatile char lookForResponseBuffer[10]; 90 | volatile uint32_t lastUSARTCharReceived_Time = 0; 91 | volatile uint32_t DMA_Rx_Buff_Index = 0; 92 | uint32_t lastDMABuffPoll = 0; 93 | 94 | 95 | 96 | uint8_t CMD_Incomming_InProgress = 0; 97 | 98 | 99 | //uint8_t USART3_TxBuffer[10]; //Starting initialization at 10 (for now) 100 | volatile char USART3_RxBuffer[RxBuffSize]; // Currently used as DMA Circular buffer 101 | //char *ESP_IPD_Data_Buffer_Pntr; 102 | //char ESP_IPD_DataBuffer[RxBuffSize]; 103 | 104 | 105 | //volatile char USART1_RxBuffer[RxBuffSize]; 106 | uint8_t TxCounter = 0; 107 | volatile uint8_t RxCounter = 0; 108 | uint8_t USART1_RxCounter = 0; 109 | 110 | volatile uint8_t newCommandWaiting = 0; 111 | 112 | volatile uint8_t Command_To_Redirect = 0; 113 | volatile uint32_t dimmingValue; 114 | 115 | //USART_InitTypeDef ESP8266_Interface_Config; 116 | GPIO_InitTypeDef Button_Config; 117 | GPIO_InitTypeDef POWER_LED_Config; 118 | GPIO_InitTypeDef External_LED_Config; 119 | GPIO_InitTypeDef ZeroCross_Config; 120 | EXTI_InitTypeDef ZeroCross_Interrupt; 121 | NVIC_InitTypeDef ZeroCross_VectorPrior; 122 | 123 | 124 | void ConfigZeroCrossExternalInt(); 125 | void ConfigZeroCross_NVIC(); 126 | void LED(void); 127 | volatile uint32_t mi = 0; 128 | volatile uint32_t mj = 0; 129 | volatile uint32_t mdi = 0; 130 | volatile extern uint8_t waitingForReponse; 131 | //volatile uint8_t OKFound = 0; 132 | //volatile uint8_t ERRORFound = 0; 133 | volatile uint8_t OCount = 0; 134 | volatile uint8_t LINKFound = 0; 135 | volatile uint8_t indexPageRequestWaiting = 0; 136 | volatile uint8_t restRequestWaiting = 0; 137 | volatile uint8_t activeConnectionNum = 0; 138 | void RefreshCustomRESTResponseDimmer(char *IPWAN, char *IPLAN, uint32_t nodeValue1); 139 | void RefreshCustomRESTResponse(char *IPWAN, char *IPLAN, char *nodeKeyName, char *nodeValue); 140 | char customRESTResponse[400]; 141 | char dimValueString[6]; 142 | 143 | uint8_t USART3_Tx_Recieved = 0; 144 | 145 | uint16_t position = 0; 146 | 147 | 148 | IPD_Data currentIPD; 149 | //uint16_t incommingDimmingValue = 0; 150 | //char *dimmingString; 151 | //char *URI; 152 | //char *queryString1; 153 | //char *queryValue1; 154 | //char *queryString2; 155 | //char *queryValue2; 156 | 157 | 158 | int main(void) 159 | { 160 | //printf("Main()\r\n"); //SEMIHOSTING DEBUG OUT 161 | // LED lamp 12800 MAX (before no response, wont turn on) But a few second delay before Diode saturation (light comes on) 162 | // 12400 - min for reasonable saturation delay 163 | dimmingValue = 11000; // 12600 164 | 165 | //printf("RCC clocks Str\r\n"); //SEMIHOSTING DEBUG OUT 166 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); // ESP8266 - Wifi 167 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); 168 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 169 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 170 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 171 | //printf("RCC clocks Fin\r\n"); //SEMIHOSTING DEBUG OUT 172 | 173 | 174 | POWER_LED_Config.GPIO_Speed = GPIO_Speed_50MHz; 175 | POWER_LED_Config.GPIO_Mode = GPIO_Mode_Out_PP; 176 | POWER_LED_Config.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_6; // PB1 - Maple On-board LED | PB6 - Maple Pin 16 | PB0 - CH_PD (Power ON) Pin for ESP8266 Wifi 177 | GPIO_Init(GPIOB,&POWER_LED_Config); 178 | 179 | //SetArray_Size(USART3_RxBuffer,RxBuffSize); 180 | 181 | //printf("GPIO Port: B Pins: 0,1,6 Fin\r\n"); //SEMIHOSTING DEBUG OUT 182 | 183 | GPIOB->BRR = GPIO_Pin_0; // Power OFF for ESP8266 184 | //printf("ESP8266 Powered OFF (CH01 Pin Disabled (Pulled Low))\r\n"); //SEMIHOSTING DEBUG OUT 185 | GPIOB->BSRR = GPIO_Pin_1; // PB1 - Maple On-board LED 186 | GPIOB->BRR = GPIO_Pin_6; // PB6 - Maple Pin 16 187 | GPIOB->BSRR = GPIO_Pin_0; // Power On for ESP8266 188 | //printf("ESP8266 Powered ON\r\n"); //SEMIHOSTING DEBUG OUT 189 | GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14); 190 | 191 | ZeroCross_Config.GPIO_Mode = GPIO_Speed_50MHz; 192 | ZeroCross_Config.GPIO_Mode = GPIO_Mode_IPD; 193 | ZeroCross_Config.GPIO_Pin = GPIO_Pin_14; // PB14 - Maple Pin 29 194 | GPIO_Init(GPIOB,&ZeroCross_Config); 195 | //printf("GPIOB Pin 14 configured for Zero-Crossing detection (Maple Pin 29)\r\n"); //SEMIHOSTING DEBUG OUT 196 | 197 | Button_Config.GPIO_Mode = GPIO_Mode_IN_FLOATING; 198 | Button_Config.GPIO_Speed = GPIO_Speed_50MHz; 199 | Button_Config.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_7; 200 | GPIO_Init(GPIOB,&Button_Config); 201 | //printf("GPIOB Pin 14 configured for Zero-Crossing detection (Maple Pin 29)\r\n"); //SEMIHOSTING DEBUG OUT 202 | 203 | 204 | 205 | //Init_USART3(460800,ENABLE); 206 | //Init_USART1(460800,ENABLE); 207 | 208 | //*********USE USART3 Rx in DMA Mode 209 | #define ESP_RX_DMA_BUF_POLL_Interval_ms 1000 //Every 1 Sec check the Rx Buffer 210 | //uint32_t LastRxBufferReadTime = 0; 211 | Init_USART3_DMA(2000000,USART3_RxBuffer, USART3_RxBufferSize); 212 | 213 | //*********USE USART3 Rx in DMA Mode 214 | 215 | 216 | //Init_USART3(2000000,ENABLE); 217 | //Init_USART1(2000000,ENABLE); 218 | 219 | //for (mj=0;mj<500000;mj++);// FOR TESTING 220 | 221 | //for (mj=0;mj<5000;mj++);// FOR TESTING 222 | //Need to wait for a sec before transmitting data. Let ESP8266 power on 223 | //for (mj=0;mj<500000;mj++); // FOR TESTING 224 | 225 | 226 | //USART_SendData(USART3,"AT/r/n"); 227 | 228 | ConfigZeroCrossExternalInt(); 229 | ConfigZeroCross_NVIC(); 230 | Init_Time(MILLISEC); 231 | 232 | //for (mj=0;mj<20500;mj++); 233 | //Wifi_Init(); 234 | //printf("Wifi_Init() Complete\r\n"); //SEMIHOSTING DEBUG OUT 235 | //for (mj=0;mj<20500;mj++); 236 | for (mj=0;mj<130500;mj++); 237 | //ConnectToAP("Nonya","porsche911"); 238 | //for (mj=0;mj<70500;mj++); 239 | //printf("Preparing to start local ESP8266 server at ID: 1 Port: 80\r\n"); //SEMIHOSTING DEBUG OUT 240 | Wifi_SendCommand(WIFI_JOIN_NONYA); 241 | StartServer(1,80); 242 | 243 | Wifi_SendCommand(WIFI_GET_CURRENT_IP); 244 | 245 | //Sets data of first few bites of DMA so it doesn't start with 12 null terminators. 246 | USART3_RxBuffer[0] = "1"; 247 | USART3_RxBuffer[1] = "1"; 248 | USART3_RxBuffer[2] = "1"; 249 | USART3_RxBuffer[3] = "1"; 250 | USART3_RxBuffer[4] = "1"; 251 | USART3_RxBuffer[5] = "1"; 252 | USART3_RxBuffer[6] = "1"; 253 | USART3_RxBuffer[7] = "1"; 254 | USART3_RxBuffer[8] = "1"; 255 | USART3_RxBuffer[9] = "1"; 256 | USART3_RxBuffer[10] = "1"; 257 | USART3_RxBuffer[11] = "1"; 258 | USART3_RxBuffer[12] = "1"; 259 | 260 | 261 | 262 | //Main Run Loop 263 | for(;;) 264 | { 265 | 266 | if(restRequestWaiting == 1) 267 | { 268 | SendRESTResponse(activeConnectionNum,RESTResponse_Headers_Test_OK,RESTResponse_Body_TEST_JSON); 269 | } 270 | //This Polls the dma buffer ever [poll interval] For new incoming data from esp (Starting with +IPD) 271 | if((Millis() - lastDMABuffPoll) >= DMA_Rx_Buff_Poll_Int_ms) 272 | { 273 | lastDMABuffPoll = Millis(); 274 | currentIPD = Wifi_CheckDMABuff_ForIPDData(); 275 | if(currentIPD.Valid == 1) 276 | { 277 | SendRESTResponse(currentIPD.ConnectionNum, RESTResponse_Headers_Test_OK, customRESTResponse); 278 | } 279 | } 280 | //Check for data to transmit USART3 281 | 282 | if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)) // Power cycle the ESP8266 283 | { 284 | Wifi_SendCommand(Command_To_Redirect); 285 | for (mj=0;mj<130500;mj++);//debounce 286 | } 287 | } 288 | } 289 | 290 | void ClearRxBuffer(char buffer[]) 291 | { 292 | memset(&buffer[0], 0, sizeof(buffer)); 293 | } 294 | 295 | 296 | void SetRedirectCommand(uint8_t commandNum) 297 | { 298 | 299 | } 300 | 301 | #define NODE_ID "dim01" 302 | 303 | void RefreshCustomRESTResponseDimmer(char *IPWAN, char *IPLAN, uint32_t nodeValue1) 304 | { 305 | #ifndef NODE_ID 306 | #error NODE_ID not defined, Please define NODE_ID as char* 307 | #endif 308 | snprintf(customRESTResponse, ARRAYSIZE(customRESTResponse),"{\"ID\":\"%s\",\"Status\":{\"dimmingValue\":\"%d\",\"CurrentIP_WAN\":\"%s\",\"currentIP_LAN\":\"%s\",\"self_check_result\":\"OK\"}} ",NODE_ID, nodeValue1, IPWAN, IPLAN); 309 | } 310 | 311 | 312 | void RefreshCustomRESTResponse(char *IPWAN, char *IPLAN, char *nodeKeyName, char *nodeValue) 313 | { 314 | #ifndef NODE_ID 315 | #error NODE_ID not defined, Please define NODE_ID as char* 316 | #endif 317 | snprintf(customRESTResponse, ARRAYSIZE(customRESTResponse),"{\"ID\":\"%s\",\"Status\":{\"%s\":\"%s\",\"CurrentIP_WAN\":\"%s\",\"currentIP_LAN\":\"%s\",\"self_check_result\":\"OK\"}} ",NODE_ID, nodeKeyName, nodeValue, IPWAN, IPLAN); 318 | } 319 | 320 | #ifdef SUPPORT_CPLUSPLUS 321 | extern "C"{ 322 | #endif 323 | 324 | 325 | void ConfigZeroCrossExternalInt() // Configured for Maple Mini Pin 29 326 | { 327 | ZeroCross_Interrupt.EXTI_Line = EXTI_Line14; 328 | ZeroCross_Interrupt.EXTI_Mode = EXTI_Mode_Interrupt; 329 | ZeroCross_Interrupt.EXTI_Trigger = EXTI_Trigger_Rising; 330 | ZeroCross_Interrupt.EXTI_LineCmd = ENABLE; 331 | 332 | EXTI_Init(&ZeroCross_Interrupt); 333 | } 334 | 335 | #ifdef SUPPORT_CPLUSPLUS 336 | } 337 | #endif 338 | 339 | void ConfigZeroCross_NVIC() 340 | { 341 | //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); 342 | 343 | ZeroCross_VectorPrior.NVIC_IRQChannel = EXTI15_10_IRQn; 344 | ZeroCross_VectorPrior.NVIC_IRQChannelPreemptionPriority = 15; 345 | ZeroCross_VectorPrior.NVIC_IRQChannelSubPriority = 0; 346 | ZeroCross_VectorPrior.NVIC_IRQChannelCmd = ENABLE; 347 | NVIC_Init(&ZeroCross_VectorPrior); 348 | 349 | NVIC_SetPriority(EXTI15_10_IRQn, NVIC_EncodePriority(4,15,0)); 350 | } 351 | 352 | void EXTI15_10_IRQHandler(void) 353 | { 354 | for (mdi=0;mdi<1170;mdi++);// delay to allow 0 dimming value to be full brightness 355 | for (mdi=0;mdiBSRR = (1<<6); 357 | for (mdi=0;mdi<70;mdi++); // 70 = 11.8us 358 | GPIOB->BRR = (1<<6); 359 | EXTI_ClearITPendingBit(EXTI_Line14); 360 | 361 | } 362 | 363 | volatile uint8_t activeDataTrap = 0; 364 | volatile char IPDDataBuffer[1000]; 365 | volatile uint16_t IPDDataIndex = 0; 366 | volatile uint16_t bytesToGet = 367; //a count of the number of bytes to expect from an incoming +IPD data transmission DEBUG SET AT 400 need to get this from the IPD metadata 367 | volatile uint8_t activeIPDTrap = 0; 368 | volatile uint8_t IPDMetaIndex = 0; 369 | volatile char IPDMetaBuffer[15]; // contains data after +IPD ie +IPD[,0,394:] - (data inside brackets), denoting the connection number sending the data and the byte count of expected data 370 | 371 | 372 | 373 | 374 | void USART3_IRQHandler(void) //USART3 - ESP8266 Wifi Module 375 | { 376 | if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) 377 | { 378 | DMA_Rx_Buff_Index++; 379 | } 380 | USART_ClearITPendingBit(USART3,USART_IT_RXNE); 381 | } 382 | 383 | 384 | /* 385 | void USART1_IRQHandler(void) //USART1 - User Command recieve (DEBUG ONLY, commands from user will come from wifi) 386 | { 387 | if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET) 388 | { 389 | 390 | // Read one byte from the receive data register 391 | //byteToCommand[0] = ; 392 | USART1_RxBuffer[USART1_RxCounter++] = USART_ReceiveData(USART1); 393 | //char byteToCommand = USART1_RxBuffer[(USART1_RxCounter - 1)]; 394 | if(USART1_RxBuffer[USART1_RxCounter - 1] == '\r') 395 | { 396 | // validate message receive string (if CMD termination string found) 397 | if(((USART1_RxBuffer[USART1_RxCounter - 2] == WIFI_CMD_RECEIVE_COMPLETE[2]) && (USART1_RxBuffer[USART1_RxCounter - 3] == WIFI_CMD_RECEIVE_COMPLETE[1]) && (USART1_RxBuffer[USART1_RxCounter - 4] == WIFI_CMD_RECEIVE_COMPLETE[0]))) 398 | { 399 | 400 | strncpy(CMD_FULL_Incomming,&USART1_RxBuffer[USART1_RxCounter - 15],11); // pulls command from buffer into CMD_FULL_Incomming Array 401 | newCommandWaiting = 1; 402 | 403 | } 404 | else { // if CR is found but no CMD termination string (This is mainly for debugging, and this just references the 2 digit array index for the ATCommands array) 405 | byteToCommand[0] = USART1_RxBuffer[USART1_RxCounter - 3]; 406 | byteToCommand[1] = USART1_RxBuffer[USART1_RxCounter - 2]; 407 | 408 | Command_To_Redirect = atoi(byteToCommand); 409 | 410 | if(Command_To_Redirect >= sizeof(ATCommandsArray)) // Should probably run this outside the interrupt 411 | { 412 | //Command error has occured, as requested command is outside the bounds of the array 413 | Command_To_Redirect = 0; 414 | } 415 | } 416 | } 417 | 418 | if(USART1_RxCounter >= USART1_RxBufferSize) // if counter has hit the end of the buffer, reset counter to 0 (hack circular buffer) Will move this to DMA 419 | { 420 | USART1_RxCounter = 0; 421 | } 422 | 423 | USART_ClearITPendingBit(USART1,USART_IT_RXNE); 424 | } 425 | 426 | } 427 | */ 428 | -------------------------------------------------------------------------------- /Wifi_Dimmer.coproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 22 | 23 | 54 | 55 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /app/cmsis/core_cmFunc.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file core_cmFunc.h 3 | * @brief CMSIS Cortex-M Core Function Access Header File 4 | * @version V3.01 5 | * @date 06. March 2012 6 | * 7 | * @note 8 | * Copyright (C) 2009-2012 ARM Limited. All rights reserved. 9 | * 10 | * @par 11 | * ARM Limited (ARM) is supplying this software for use with Cortex-M 12 | * processor based microcontrollers. This file can be freely distributed 13 | * within development tools that are supporting such ARM based processors. 14 | * 15 | * @par 16 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 17 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 19 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR 20 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 21 | * 22 | ******************************************************************************/ 23 | 24 | #ifndef __CORE_CMFUNC_H 25 | #define __CORE_CMFUNC_H 26 | 27 | 28 | /* ########################### Core Function Access ########################### */ 29 | /** \ingroup CMSIS_Core_FunctionInterface 30 | \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions 31 | @{ 32 | */ 33 | 34 | #if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ 35 | /* ARM armcc specific functions */ 36 | 37 | #if (__ARMCC_VERSION < 400677) 38 | #error "Please use ARM Compiler Toolchain V4.0.677 or later!" 39 | #endif 40 | 41 | /* intrinsic void __enable_irq(); */ 42 | /* intrinsic void __disable_irq(); */ 43 | 44 | /** \brief Get Control Register 45 | 46 | This function returns the content of the Control Register. 47 | 48 | \return Control Register value 49 | */ 50 | __STATIC_INLINE uint32_t __get_CONTROL(void) 51 | { 52 | register uint32_t __regControl __ASM("control"); 53 | return(__regControl); 54 | } 55 | 56 | 57 | /** \brief Set Control Register 58 | 59 | This function writes the given value to the Control Register. 60 | 61 | \param [in] control Control Register value to set 62 | */ 63 | __STATIC_INLINE void __set_CONTROL(uint32_t control) 64 | { 65 | register uint32_t __regControl __ASM("control"); 66 | __regControl = control; 67 | } 68 | 69 | 70 | /** \brief Get IPSR Register 71 | 72 | This function returns the content of the IPSR Register. 73 | 74 | \return IPSR Register value 75 | */ 76 | __STATIC_INLINE uint32_t __get_IPSR(void) 77 | { 78 | register uint32_t __regIPSR __ASM("ipsr"); 79 | return(__regIPSR); 80 | } 81 | 82 | 83 | /** \brief Get APSR Register 84 | 85 | This function returns the content of the APSR Register. 86 | 87 | \return APSR Register value 88 | */ 89 | __STATIC_INLINE uint32_t __get_APSR(void) 90 | { 91 | register uint32_t __regAPSR __ASM("apsr"); 92 | return(__regAPSR); 93 | } 94 | 95 | 96 | /** \brief Get xPSR Register 97 | 98 | This function returns the content of the xPSR Register. 99 | 100 | \return xPSR Register value 101 | */ 102 | __STATIC_INLINE uint32_t __get_xPSR(void) 103 | { 104 | register uint32_t __regXPSR __ASM("xpsr"); 105 | return(__regXPSR); 106 | } 107 | 108 | 109 | /** \brief Get Process Stack Pointer 110 | 111 | This function returns the current value of the Process Stack Pointer (PSP). 112 | 113 | \return PSP Register value 114 | */ 115 | __STATIC_INLINE uint32_t __get_PSP(void) 116 | { 117 | register uint32_t __regProcessStackPointer __ASM("psp"); 118 | return(__regProcessStackPointer); 119 | } 120 | 121 | 122 | /** \brief Set Process Stack Pointer 123 | 124 | This function assigns the given value to the Process Stack Pointer (PSP). 125 | 126 | \param [in] topOfProcStack Process Stack Pointer value to set 127 | */ 128 | __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) 129 | { 130 | register uint32_t __regProcessStackPointer __ASM("psp"); 131 | __regProcessStackPointer = topOfProcStack; 132 | } 133 | 134 | 135 | /** \brief Get Main Stack Pointer 136 | 137 | This function returns the current value of the Main Stack Pointer (MSP). 138 | 139 | \return MSP Register value 140 | */ 141 | __STATIC_INLINE uint32_t __get_MSP(void) 142 | { 143 | register uint32_t __regMainStackPointer __ASM("msp"); 144 | return(__regMainStackPointer); 145 | } 146 | 147 | 148 | /** \brief Set Main Stack Pointer 149 | 150 | This function assigns the given value to the Main Stack Pointer (MSP). 151 | 152 | \param [in] topOfMainStack Main Stack Pointer value to set 153 | */ 154 | __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) 155 | { 156 | register uint32_t __regMainStackPointer __ASM("msp"); 157 | __regMainStackPointer = topOfMainStack; 158 | } 159 | 160 | 161 | /** \brief Get Priority Mask 162 | 163 | This function returns the current state of the priority mask bit from the Priority Mask Register. 164 | 165 | \return Priority Mask value 166 | */ 167 | __STATIC_INLINE uint32_t __get_PRIMASK(void) 168 | { 169 | register uint32_t __regPriMask __ASM("primask"); 170 | return(__regPriMask); 171 | } 172 | 173 | 174 | /** \brief Set Priority Mask 175 | 176 | This function assigns the given value to the Priority Mask Register. 177 | 178 | \param [in] priMask Priority Mask 179 | */ 180 | __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) 181 | { 182 | register uint32_t __regPriMask __ASM("primask"); 183 | __regPriMask = (priMask); 184 | } 185 | 186 | 187 | #if (__CORTEX_M >= 0x03) 188 | 189 | /** \brief Enable FIQ 190 | 191 | This function enables FIQ interrupts by clearing the F-bit in the CPSR. 192 | Can only be executed in Privileged modes. 193 | */ 194 | #define __enable_fault_irq __enable_fiq 195 | 196 | 197 | /** \brief Disable FIQ 198 | 199 | This function disables FIQ interrupts by setting the F-bit in the CPSR. 200 | Can only be executed in Privileged modes. 201 | */ 202 | #define __disable_fault_irq __disable_fiq 203 | 204 | 205 | /** \brief Get Base Priority 206 | 207 | This function returns the current value of the Base Priority register. 208 | 209 | \return Base Priority register value 210 | */ 211 | __STATIC_INLINE uint32_t __get_BASEPRI(void) 212 | { 213 | register uint32_t __regBasePri __ASM("basepri"); 214 | return(__regBasePri); 215 | } 216 | 217 | 218 | /** \brief Set Base Priority 219 | 220 | This function assigns the given value to the Base Priority register. 221 | 222 | \param [in] basePri Base Priority value to set 223 | */ 224 | __STATIC_INLINE void __set_BASEPRI(uint32_t basePri) 225 | { 226 | register uint32_t __regBasePri __ASM("basepri"); 227 | __regBasePri = (basePri & 0xff); 228 | } 229 | 230 | 231 | /** \brief Get Fault Mask 232 | 233 | This function returns the current value of the Fault Mask register. 234 | 235 | \return Fault Mask register value 236 | */ 237 | __STATIC_INLINE uint32_t __get_FAULTMASK(void) 238 | { 239 | register uint32_t __regFaultMask __ASM("faultmask"); 240 | return(__regFaultMask); 241 | } 242 | 243 | 244 | /** \brief Set Fault Mask 245 | 246 | This function assigns the given value to the Fault Mask register. 247 | 248 | \param [in] faultMask Fault Mask value to set 249 | */ 250 | __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) 251 | { 252 | register uint32_t __regFaultMask __ASM("faultmask"); 253 | __regFaultMask = (faultMask & (uint32_t)1); 254 | } 255 | 256 | #endif /* (__CORTEX_M >= 0x03) */ 257 | 258 | 259 | #if (__CORTEX_M == 0x04) 260 | 261 | /** \brief Get FPSCR 262 | 263 | This function returns the current value of the Floating Point Status/Control register. 264 | 265 | \return Floating Point Status/Control register value 266 | */ 267 | __STATIC_INLINE uint32_t __get_FPSCR(void) 268 | { 269 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 270 | register uint32_t __regfpscr __ASM("fpscr"); 271 | return(__regfpscr); 272 | #else 273 | return(0); 274 | #endif 275 | } 276 | 277 | 278 | /** \brief Set FPSCR 279 | 280 | This function assigns the given value to the Floating Point Status/Control register. 281 | 282 | \param [in] fpscr Floating Point Status/Control value to set 283 | */ 284 | __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) 285 | { 286 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 287 | register uint32_t __regfpscr __ASM("fpscr"); 288 | __regfpscr = (fpscr); 289 | #endif 290 | } 291 | 292 | #endif /* (__CORTEX_M == 0x04) */ 293 | 294 | 295 | #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ 296 | /* IAR iccarm specific functions */ 297 | 298 | #include 299 | 300 | 301 | #elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ 302 | /* TI CCS specific functions */ 303 | 304 | #include 305 | 306 | 307 | #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ 308 | /* GNU gcc specific functions */ 309 | 310 | /** \brief Enable IRQ Interrupts 311 | 312 | This function enables IRQ interrupts by clearing the I-bit in the CPSR. 313 | Can only be executed in Privileged modes. 314 | */ 315 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) 316 | { 317 | __ASM volatile ("cpsie i"); 318 | } 319 | 320 | 321 | /** \brief Disable IRQ Interrupts 322 | 323 | This function disables IRQ interrupts by setting the I-bit in the CPSR. 324 | Can only be executed in Privileged modes. 325 | */ 326 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) 327 | { 328 | __ASM volatile ("cpsid i"); 329 | } 330 | 331 | 332 | /** \brief Get Control Register 333 | 334 | This function returns the content of the Control Register. 335 | 336 | \return Control Register value 337 | */ 338 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) 339 | { 340 | uint32_t result; 341 | 342 | __ASM volatile ("MRS %0, control" : "=r" (result) ); 343 | return(result); 344 | } 345 | 346 | 347 | /** \brief Set Control Register 348 | 349 | This function writes the given value to the Control Register. 350 | 351 | \param [in] control Control Register value to set 352 | */ 353 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) 354 | { 355 | __ASM volatile ("MSR control, %0" : : "r" (control) ); 356 | } 357 | 358 | 359 | /** \brief Get IPSR Register 360 | 361 | This function returns the content of the IPSR Register. 362 | 363 | \return IPSR Register value 364 | */ 365 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) 366 | { 367 | uint32_t result; 368 | 369 | __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); 370 | return(result); 371 | } 372 | 373 | 374 | /** \brief Get APSR Register 375 | 376 | This function returns the content of the APSR Register. 377 | 378 | \return APSR Register value 379 | */ 380 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) 381 | { 382 | uint32_t result; 383 | 384 | __ASM volatile ("MRS %0, apsr" : "=r" (result) ); 385 | return(result); 386 | } 387 | 388 | 389 | /** \brief Get xPSR Register 390 | 391 | This function returns the content of the xPSR Register. 392 | 393 | \return xPSR Register value 394 | */ 395 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) 396 | { 397 | uint32_t result; 398 | 399 | __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); 400 | return(result); 401 | } 402 | 403 | 404 | /** \brief Get Process Stack Pointer 405 | 406 | This function returns the current value of the Process Stack Pointer (PSP). 407 | 408 | \return PSP Register value 409 | */ 410 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) 411 | { 412 | register uint32_t result; 413 | 414 | __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); 415 | return(result); 416 | } 417 | 418 | 419 | /** \brief Set Process Stack Pointer 420 | 421 | This function assigns the given value to the Process Stack Pointer (PSP). 422 | 423 | \param [in] topOfProcStack Process Stack Pointer value to set 424 | */ 425 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) 426 | { 427 | __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); 428 | } 429 | 430 | 431 | /** \brief Get Main Stack Pointer 432 | 433 | This function returns the current value of the Main Stack Pointer (MSP). 434 | 435 | \return MSP Register value 436 | */ 437 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) 438 | { 439 | register uint32_t result; 440 | 441 | __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); 442 | return(result); 443 | } 444 | 445 | 446 | /** \brief Set Main Stack Pointer 447 | 448 | This function assigns the given value to the Main Stack Pointer (MSP). 449 | 450 | \param [in] topOfMainStack Main Stack Pointer value to set 451 | */ 452 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) 453 | { 454 | __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); 455 | } 456 | 457 | 458 | /** \brief Get Priority Mask 459 | 460 | This function returns the current state of the priority mask bit from the Priority Mask Register. 461 | 462 | \return Priority Mask value 463 | */ 464 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) 465 | { 466 | uint32_t result; 467 | 468 | __ASM volatile ("MRS %0, primask" : "=r" (result) ); 469 | return(result); 470 | } 471 | 472 | 473 | /** \brief Set Priority Mask 474 | 475 | This function assigns the given value to the Priority Mask Register. 476 | 477 | \param [in] priMask Priority Mask 478 | */ 479 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) 480 | { 481 | __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); 482 | } 483 | 484 | 485 | #if (__CORTEX_M >= 0x03) 486 | 487 | /** \brief Enable FIQ 488 | 489 | This function enables FIQ interrupts by clearing the F-bit in the CPSR. 490 | Can only be executed in Privileged modes. 491 | */ 492 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) 493 | { 494 | __ASM volatile ("cpsie f"); 495 | } 496 | 497 | 498 | /** \brief Disable FIQ 499 | 500 | This function disables FIQ interrupts by setting the F-bit in the CPSR. 501 | Can only be executed in Privileged modes. 502 | */ 503 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) 504 | { 505 | __ASM volatile ("cpsid f"); 506 | } 507 | 508 | 509 | /** \brief Get Base Priority 510 | 511 | This function returns the current value of the Base Priority register. 512 | 513 | \return Base Priority register value 514 | */ 515 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) 516 | { 517 | uint32_t result; 518 | 519 | __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); 520 | return(result); 521 | } 522 | 523 | 524 | /** \brief Set Base Priority 525 | 526 | This function assigns the given value to the Base Priority register. 527 | 528 | \param [in] basePri Base Priority value to set 529 | */ 530 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) 531 | { 532 | __ASM volatile ("MSR basepri, %0" : : "r" (value) ); 533 | } 534 | 535 | 536 | /** \brief Get Fault Mask 537 | 538 | This function returns the current value of the Fault Mask register. 539 | 540 | \return Fault Mask register value 541 | */ 542 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) 543 | { 544 | uint32_t result; 545 | 546 | __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); 547 | return(result); 548 | } 549 | 550 | 551 | /** \brief Set Fault Mask 552 | 553 | This function assigns the given value to the Fault Mask register. 554 | 555 | \param [in] faultMask Fault Mask value to set 556 | */ 557 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) 558 | { 559 | __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); 560 | } 561 | 562 | #endif /* (__CORTEX_M >= 0x03) */ 563 | 564 | 565 | #if (__CORTEX_M == 0x04) 566 | 567 | /** \brief Get FPSCR 568 | 569 | This function returns the current value of the Floating Point Status/Control register. 570 | 571 | \return Floating Point Status/Control register value 572 | */ 573 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) 574 | { 575 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 576 | uint32_t result; 577 | 578 | __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); 579 | return(result); 580 | #else 581 | return(0); 582 | #endif 583 | } 584 | 585 | 586 | /** \brief Set FPSCR 587 | 588 | This function assigns the given value to the Floating Point Status/Control register. 589 | 590 | \param [in] fpscr Floating Point Status/Control value to set 591 | */ 592 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) 593 | { 594 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 595 | __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); 596 | #endif 597 | } 598 | 599 | #endif /* (__CORTEX_M == 0x04) */ 600 | 601 | 602 | #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ 603 | /* TASKING carm specific functions */ 604 | 605 | /* 606 | * The CMSIS functions have been implemented as intrinsics in the compiler. 607 | * Please use "carm -?i" to get an up to date list of all instrinsics, 608 | * Including the CMSIS ones. 609 | */ 610 | 611 | #endif 612 | 613 | /*@} end of CMSIS_Core_RegAccFunctions */ 614 | 615 | 616 | #endif /* __CORE_CMFUNC_H */ 617 | -------------------------------------------------------------------------------- /app/cmsis/core_cmInstr.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file core_cmInstr.h 3 | * @brief CMSIS Cortex-M Core Instruction Access Header File 4 | * @version V3.01 5 | * @date 06. March 2012 6 | * 7 | * @note 8 | * Copyright (C) 2009-2012 ARM Limited. All rights reserved. 9 | * 10 | * @par 11 | * ARM Limited (ARM) is supplying this software for use with Cortex-M 12 | * processor based microcontrollers. This file can be freely distributed 13 | * within development tools that are supporting such ARM based processors. 14 | * 15 | * @par 16 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 17 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 19 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR 20 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 21 | * 22 | ******************************************************************************/ 23 | 24 | #ifndef __CORE_CMINSTR_H 25 | #define __CORE_CMINSTR_H 26 | 27 | 28 | /* ########################## Core Instruction Access ######################### */ 29 | /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface 30 | Access to dedicated instructions 31 | @{ 32 | */ 33 | 34 | #if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ 35 | /* ARM armcc specific functions */ 36 | 37 | #if (__ARMCC_VERSION < 400677) 38 | #error "Please use ARM Compiler Toolchain V4.0.677 or later!" 39 | #endif 40 | 41 | 42 | /** \brief No Operation 43 | 44 | No Operation does nothing. This instruction can be used for code alignment purposes. 45 | */ 46 | #define __NOP __nop 47 | 48 | 49 | /** \brief Wait For Interrupt 50 | 51 | Wait For Interrupt is a hint instruction that suspends execution 52 | until one of a number of events occurs. 53 | */ 54 | #define __WFI __wfi 55 | 56 | 57 | /** \brief Wait For Event 58 | 59 | Wait For Event is a hint instruction that permits the processor to enter 60 | a low-power state until one of a number of events occurs. 61 | */ 62 | #define __WFE __wfe 63 | 64 | 65 | /** \brief Send Event 66 | 67 | Send Event is a hint instruction. It causes an event to be signaled to the CPU. 68 | */ 69 | #define __SEV __sev 70 | 71 | 72 | /** \brief Instruction Synchronization Barrier 73 | 74 | Instruction Synchronization Barrier flushes the pipeline in the processor, 75 | so that all instructions following the ISB are fetched from cache or 76 | memory, after the instruction has been completed. 77 | */ 78 | #define __ISB() __isb(0xF) 79 | 80 | 81 | /** \brief Data Synchronization Barrier 82 | 83 | This function acts as a special kind of Data Memory Barrier. 84 | It completes when all explicit memory accesses before this instruction complete. 85 | */ 86 | #define __DSB() __dsb(0xF) 87 | 88 | 89 | /** \brief Data Memory Barrier 90 | 91 | This function ensures the apparent order of the explicit memory operations before 92 | and after the instruction, without ensuring their completion. 93 | */ 94 | #define __DMB() __dmb(0xF) 95 | 96 | 97 | /** \brief Reverse byte order (32 bit) 98 | 99 | This function reverses the byte order in integer value. 100 | 101 | \param [in] value Value to reverse 102 | \return Reversed value 103 | */ 104 | #define __REV __rev 105 | 106 | 107 | /** \brief Reverse byte order (16 bit) 108 | 109 | This function reverses the byte order in two unsigned short values. 110 | 111 | \param [in] value Value to reverse 112 | \return Reversed value 113 | */ 114 | __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) 115 | { 116 | rev16 r0, r0 117 | bx lr 118 | } 119 | 120 | 121 | /** \brief Reverse byte order in signed short value 122 | 123 | This function reverses the byte order in a signed short value with sign extension to integer. 124 | 125 | \param [in] value Value to reverse 126 | \return Reversed value 127 | */ 128 | __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) 129 | { 130 | revsh r0, r0 131 | bx lr 132 | } 133 | 134 | 135 | /** \brief Rotate Right in unsigned value (32 bit) 136 | 137 | This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. 138 | 139 | \param [in] value Value to rotate 140 | \param [in] value Number of Bits to rotate 141 | \return Rotated value 142 | */ 143 | #define __ROR __ror 144 | 145 | 146 | #if (__CORTEX_M >= 0x03) 147 | 148 | /** \brief Reverse bit order of value 149 | 150 | This function reverses the bit order of the given value. 151 | 152 | \param [in] value Value to reverse 153 | \return Reversed value 154 | */ 155 | #define __RBIT __rbit 156 | 157 | 158 | /** \brief LDR Exclusive (8 bit) 159 | 160 | This function performs a exclusive LDR command for 8 bit value. 161 | 162 | \param [in] ptr Pointer to data 163 | \return value of type uint8_t at (*ptr) 164 | */ 165 | #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) 166 | 167 | 168 | /** \brief LDR Exclusive (16 bit) 169 | 170 | This function performs a exclusive LDR command for 16 bit values. 171 | 172 | \param [in] ptr Pointer to data 173 | \return value of type uint16_t at (*ptr) 174 | */ 175 | #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) 176 | 177 | 178 | /** \brief LDR Exclusive (32 bit) 179 | 180 | This function performs a exclusive LDR command for 32 bit values. 181 | 182 | \param [in] ptr Pointer to data 183 | \return value of type uint32_t at (*ptr) 184 | */ 185 | #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) 186 | 187 | 188 | /** \brief STR Exclusive (8 bit) 189 | 190 | This function performs a exclusive STR command for 8 bit values. 191 | 192 | \param [in] value Value to store 193 | \param [in] ptr Pointer to location 194 | \return 0 Function succeeded 195 | \return 1 Function failed 196 | */ 197 | #define __STREXB(value, ptr) __strex(value, ptr) 198 | 199 | 200 | /** \brief STR Exclusive (16 bit) 201 | 202 | This function performs a exclusive STR command for 16 bit values. 203 | 204 | \param [in] value Value to store 205 | \param [in] ptr Pointer to location 206 | \return 0 Function succeeded 207 | \return 1 Function failed 208 | */ 209 | #define __STREXH(value, ptr) __strex(value, ptr) 210 | 211 | 212 | /** \brief STR Exclusive (32 bit) 213 | 214 | This function performs a exclusive STR command for 32 bit values. 215 | 216 | \param [in] value Value to store 217 | \param [in] ptr Pointer to location 218 | \return 0 Function succeeded 219 | \return 1 Function failed 220 | */ 221 | #define __STREXW(value, ptr) __strex(value, ptr) 222 | 223 | 224 | /** \brief Remove the exclusive lock 225 | 226 | This function removes the exclusive lock which is created by LDREX. 227 | 228 | */ 229 | #define __CLREX __clrex 230 | 231 | 232 | /** \brief Signed Saturate 233 | 234 | This function saturates a signed value. 235 | 236 | \param [in] value Value to be saturated 237 | \param [in] sat Bit position to saturate to (1..32) 238 | \return Saturated value 239 | */ 240 | #define __SSAT __ssat 241 | 242 | 243 | /** \brief Unsigned Saturate 244 | 245 | This function saturates an unsigned value. 246 | 247 | \param [in] value Value to be saturated 248 | \param [in] sat Bit position to saturate to (0..31) 249 | \return Saturated value 250 | */ 251 | #define __USAT __usat 252 | 253 | 254 | /** \brief Count leading zeros 255 | 256 | This function counts the number of leading zeros of a data value. 257 | 258 | \param [in] value Value to count the leading zeros 259 | \return number of leading zeros in value 260 | */ 261 | #define __CLZ __clz 262 | 263 | #endif /* (__CORTEX_M >= 0x03) */ 264 | 265 | 266 | 267 | #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ 268 | /* IAR iccarm specific functions */ 269 | 270 | #include 271 | 272 | 273 | #elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ 274 | /* TI CCS specific functions */ 275 | 276 | #include 277 | 278 | 279 | #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ 280 | /* GNU gcc specific functions */ 281 | 282 | /** \brief No Operation 283 | 284 | No Operation does nothing. This instruction can be used for code alignment purposes. 285 | */ 286 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) 287 | { 288 | __ASM volatile ("nop"); 289 | } 290 | 291 | 292 | /** \brief Wait For Interrupt 293 | 294 | Wait For Interrupt is a hint instruction that suspends execution 295 | until one of a number of events occurs. 296 | */ 297 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) 298 | { 299 | __ASM volatile ("wfi"); 300 | } 301 | 302 | 303 | /** \brief Wait For Event 304 | 305 | Wait For Event is a hint instruction that permits the processor to enter 306 | a low-power state until one of a number of events occurs. 307 | */ 308 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) 309 | { 310 | __ASM volatile ("wfe"); 311 | } 312 | 313 | 314 | /** \brief Send Event 315 | 316 | Send Event is a hint instruction. It causes an event to be signaled to the CPU. 317 | */ 318 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) 319 | { 320 | __ASM volatile ("sev"); 321 | } 322 | 323 | 324 | /** \brief Instruction Synchronization Barrier 325 | 326 | Instruction Synchronization Barrier flushes the pipeline in the processor, 327 | so that all instructions following the ISB are fetched from cache or 328 | memory, after the instruction has been completed. 329 | */ 330 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) 331 | { 332 | __ASM volatile ("isb"); 333 | } 334 | 335 | 336 | /** \brief Data Synchronization Barrier 337 | 338 | This function acts as a special kind of Data Memory Barrier. 339 | It completes when all explicit memory accesses before this instruction complete. 340 | */ 341 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) 342 | { 343 | __ASM volatile ("dsb"); 344 | } 345 | 346 | 347 | /** \brief Data Memory Barrier 348 | 349 | This function ensures the apparent order of the explicit memory operations before 350 | and after the instruction, without ensuring their completion. 351 | */ 352 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) 353 | { 354 | __ASM volatile ("dmb"); 355 | } 356 | 357 | 358 | /** \brief Reverse byte order (32 bit) 359 | 360 | This function reverses the byte order in integer value. 361 | 362 | \param [in] value Value to reverse 363 | \return Reversed value 364 | */ 365 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) 366 | { 367 | uint32_t result; 368 | 369 | __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); 370 | return(result); 371 | } 372 | 373 | 374 | /** \brief Reverse byte order (16 bit) 375 | 376 | This function reverses the byte order in two unsigned short values. 377 | 378 | \param [in] value Value to reverse 379 | \return Reversed value 380 | */ 381 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) 382 | { 383 | uint32_t result; 384 | 385 | __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); 386 | return(result); 387 | } 388 | 389 | 390 | /** \brief Reverse byte order in signed short value 391 | 392 | This function reverses the byte order in a signed short value with sign extension to integer. 393 | 394 | \param [in] value Value to reverse 395 | \return Reversed value 396 | */ 397 | __attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) 398 | { 399 | uint32_t result; 400 | 401 | __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); 402 | return(result); 403 | } 404 | 405 | 406 | /** \brief Rotate Right in unsigned value (32 bit) 407 | 408 | This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. 409 | 410 | \param [in] value Value to rotate 411 | \param [in] value Number of Bits to rotate 412 | \return Rotated value 413 | */ 414 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) 415 | { 416 | 417 | __ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) ); 418 | return(op1); 419 | } 420 | 421 | 422 | #if (__CORTEX_M >= 0x03) 423 | 424 | /** \brief Reverse bit order of value 425 | 426 | This function reverses the bit order of the given value. 427 | 428 | \param [in] value Value to reverse 429 | \return Reversed value 430 | */ 431 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) 432 | { 433 | uint32_t result; 434 | 435 | __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); 436 | return(result); 437 | } 438 | 439 | 440 | /** \brief LDR Exclusive (8 bit) 441 | 442 | This function performs a exclusive LDR command for 8 bit value. 443 | 444 | \param [in] ptr Pointer to data 445 | \return value of type uint8_t at (*ptr) 446 | */ 447 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) 448 | { 449 | uint8_t result; 450 | 451 | __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); 452 | return(result); 453 | } 454 | 455 | 456 | /** \brief LDR Exclusive (16 bit) 457 | 458 | This function performs a exclusive LDR command for 16 bit values. 459 | 460 | \param [in] ptr Pointer to data 461 | \return value of type uint16_t at (*ptr) 462 | */ 463 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) 464 | { 465 | uint16_t result; 466 | 467 | __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); 468 | return(result); 469 | } 470 | 471 | 472 | /** \brief LDR Exclusive (32 bit) 473 | 474 | This function performs a exclusive LDR command for 32 bit values. 475 | 476 | \param [in] ptr Pointer to data 477 | \return value of type uint32_t at (*ptr) 478 | */ 479 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) 480 | { 481 | uint32_t result; 482 | 483 | __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); 484 | return(result); 485 | } 486 | 487 | 488 | /** \brief STR Exclusive (8 bit) 489 | 490 | This function performs a exclusive STR command for 8 bit values. 491 | 492 | \param [in] value Value to store 493 | \param [in] ptr Pointer to location 494 | \return 0 Function succeeded 495 | \return 1 Function failed 496 | */ 497 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) 498 | { 499 | uint32_t result; 500 | 501 | __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); 502 | return(result); 503 | } 504 | 505 | 506 | /** \brief STR Exclusive (16 bit) 507 | 508 | This function performs a exclusive STR command for 16 bit values. 509 | 510 | \param [in] value Value to store 511 | \param [in] ptr Pointer to location 512 | \return 0 Function succeeded 513 | \return 1 Function failed 514 | */ 515 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) 516 | { 517 | uint32_t result; 518 | 519 | __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); 520 | return(result); 521 | } 522 | 523 | 524 | /** \brief STR Exclusive (32 bit) 525 | 526 | This function performs a exclusive STR command for 32 bit values. 527 | 528 | \param [in] value Value to store 529 | \param [in] ptr Pointer to location 530 | \return 0 Function succeeded 531 | \return 1 Function failed 532 | */ 533 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) 534 | { 535 | uint32_t result; 536 | 537 | __ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); 538 | return(result); 539 | } 540 | 541 | 542 | /** \brief Remove the exclusive lock 543 | 544 | This function removes the exclusive lock which is created by LDREX. 545 | 546 | */ 547 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) 548 | { 549 | __ASM volatile ("clrex"); 550 | } 551 | 552 | 553 | /** \brief Signed Saturate 554 | 555 | This function saturates a signed value. 556 | 557 | \param [in] value Value to be saturated 558 | \param [in] sat Bit position to saturate to (1..32) 559 | \return Saturated value 560 | */ 561 | #define __SSAT(ARG1,ARG2) \ 562 | ({ \ 563 | uint32_t __RES, __ARG1 = (ARG1); \ 564 | __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ 565 | __RES; \ 566 | }) 567 | 568 | 569 | /** \brief Unsigned Saturate 570 | 571 | This function saturates an unsigned value. 572 | 573 | \param [in] value Value to be saturated 574 | \param [in] sat Bit position to saturate to (0..31) 575 | \return Saturated value 576 | */ 577 | #define __USAT(ARG1,ARG2) \ 578 | ({ \ 579 | uint32_t __RES, __ARG1 = (ARG1); \ 580 | __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ 581 | __RES; \ 582 | }) 583 | 584 | 585 | /** \brief Count leading zeros 586 | 587 | This function counts the number of leading zeros of a data value. 588 | 589 | \param [in] value Value to count the leading zeros 590 | \return number of leading zeros in value 591 | */ 592 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) 593 | { 594 | uint8_t result; 595 | 596 | __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); 597 | return(result); 598 | } 599 | 600 | #endif /* (__CORTEX_M >= 0x03) */ 601 | 602 | 603 | 604 | 605 | #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ 606 | /* TASKING carm specific functions */ 607 | 608 | /* 609 | * The CMSIS functions have been implemented as intrinsics in the compiler. 610 | * Please use "carm -?i" to get an up to date list of all intrinsics, 611 | * Including the CMSIS ones. 612 | */ 613 | 614 | #endif 615 | 616 | /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ 617 | 618 | #endif /* __CORE_CMINSTR_H */ 619 | -------------------------------------------------------------------------------- /doxygen/assets/stylesheets/doxygen.css: -------------------------------------------------------------------------------- 1 | /* The standard CSS for doxygen 1.8.8 */ 2 | 3 | body, table, div, p, dl { 4 | font-family:'Open Sans',"Trebuchet MS",Helvetica,sans-serif; 5 | font-weight: 400; 6 | font-size: 14px; 7 | } 8 | 9 | /* @group Heading Levels */ 10 | 11 | h1.groupheader { 12 | font-size: 150%; 13 | } 14 | 15 | .title { 16 | font-family:'Open Sans',"Trebuchet MS",Helvetica,sans-serif; 17 | font-size: 24px; 18 | font-weight: bold; 19 | margin: 10px 2px; 20 | } 21 | 22 | h2.groupheader { 23 | border-bottom: 1px solid #879ECB; 24 | color: #354C7B; 25 | font-size: 150%; 26 | font-weight: normal; 27 | margin-top: 1.75em; 28 | padding-top: 8px; 29 | padding-bottom: 4px; 30 | width: 100%; 31 | } 32 | 33 | h3.groupheader { 34 | font-size: 100%; 35 | } 36 | 37 | h1, h2, h3, h4, h5, h6 { 38 | -webkit-transition: text-shadow 0.5s linear; 39 | -moz-transition: text-shadow 0.5s linear; 40 | -ms-transition: text-shadow 0.5s linear; 41 | -o-transition: text-shadow 0.5s linear; 42 | transition: text-shadow 0.5s linear; 43 | margin-right: 15px; 44 | } 45 | 46 | h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { 47 | text-shadow: 0 0 15px cyan; 48 | } 49 | 50 | dt { 51 | font-weight: bold; 52 | } 53 | 54 | div.multicol { 55 | -moz-column-gap: 1em; 56 | -webkit-column-gap: 1em; 57 | -moz-column-count: 3; 58 | -webkit-column-count: 3; 59 | } 60 | 61 | p.startli, p.startdd { 62 | margin-top: 2px; 63 | } 64 | 65 | p.starttd { 66 | margin-top: 0px; 67 | } 68 | 69 | p.endli { 70 | margin-bottom: 0px; 71 | } 72 | 73 | p.enddd { 74 | margin-bottom: 4px; 75 | } 76 | 77 | p.endtd { 78 | margin-bottom: 2px; 79 | } 80 | 81 | /* @end */ 82 | 83 | caption { 84 | font-weight: bold; 85 | } 86 | 87 | span.legend { 88 | font-size: 70%; 89 | text-align: center; 90 | } 91 | 92 | h3.version { 93 | font-size: 90%; 94 | text-align: center; 95 | } 96 | 97 | div.qindex, div.navtab{ 98 | background-color: #EBEFF6; 99 | border: 1px solid #A3B4D7; 100 | text-align: center; 101 | } 102 | 103 | div.qindex, div.navpath { 104 | width: 100%; 105 | line-height: 140%; 106 | } 107 | 108 | div.navtab { 109 | margin-right: 15px; 110 | } 111 | 112 | /* @group Link Styling */ 113 | 114 | a { 115 | color: #3D578C; 116 | font-weight: normal; 117 | text-decoration: none; 118 | } 119 | 120 | .contents a:visited { 121 | color: #4665A2; 122 | } 123 | 124 | a:hover { 125 | text-decoration: underline; 126 | } 127 | 128 | a.qindex { 129 | font-weight: bold; 130 | } 131 | 132 | a.qindexHL { 133 | font-weight: bold; 134 | background-color: #9CAFD4; 135 | color: #ffffff; 136 | border: 1px double #869DCA; 137 | } 138 | 139 | .contents a.qindexHL:visited { 140 | color: #ffffff; 141 | } 142 | 143 | a.el { 144 | font-weight: bold; 145 | } 146 | 147 | a.elRef { 148 | } 149 | 150 | a.code, a.code:visited, a.line, a.line:visited { 151 | color: #4665A2; 152 | } 153 | 154 | a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { 155 | color: #4665A2; 156 | } 157 | 158 | /* @end */ 159 | 160 | dl.el { 161 | margin-left: -1cm; 162 | } 163 | 164 | pre.fragment { 165 | border: 1px solid #C4CFE5; 166 | background-color: #FBFCFD; 167 | padding: 4px 6px; 168 | margin: 4px 8px 4px 2px; 169 | overflow: auto; 170 | word-wrap: break-word; 171 | font-size: 9pt; 172 | line-height: 125%; 173 | font-family: monospace, fixed; 174 | font-size: 105%; 175 | } 176 | 177 | div.fragment { 178 | padding: 4px 6px; 179 | margin: 4px 8px 4px 2px; 180 | background-color: #FBFCFD; 181 | border: 1px solid #C4CFE5; 182 | } 183 | 184 | div.line { 185 | font-family: monospace, fixed; 186 | font-size: 13px; 187 | min-height: 13px; 188 | line-height: 1.0; 189 | text-wrap: unrestricted; 190 | white-space: -moz-pre-wrap; /* Moz */ 191 | white-space: -pre-wrap; /* Opera 4-6 */ 192 | white-space: -o-pre-wrap; /* Opera 7 */ 193 | white-space: pre-wrap; /* CSS3 */ 194 | word-wrap: break-word; /* IE 5.5+ */ 195 | text-indent: -53px; 196 | padding-left: 53px; 197 | padding-bottom: 0px; 198 | margin: 0px; 199 | -webkit-transition-property: background-color, box-shadow; 200 | -webkit-transition-duration: 0.5s; 201 | -moz-transition-property: background-color, box-shadow; 202 | -moz-transition-duration: 0.5s; 203 | -ms-transition-property: background-color, box-shadow; 204 | -ms-transition-duration: 0.5s; 205 | -o-transition-property: background-color, box-shadow; 206 | -o-transition-duration: 0.5s; 207 | transition-property: background-color, box-shadow; 208 | transition-duration: 0.5s; 209 | } 210 | 211 | div.line.glow { 212 | background-color: cyan; 213 | box-shadow: 0 0 10px cyan; 214 | } 215 | 216 | 217 | span.lineno { 218 | padding-right: 4px; 219 | text-align: right; 220 | border-right: 2px solid #0F0; 221 | background-color: #E8E8E8; 222 | white-space: pre; 223 | } 224 | span.lineno a { 225 | background-color: #D8D8D8; 226 | } 227 | 228 | span.lineno a:hover { 229 | background-color: #C8C8C8; 230 | } 231 | 232 | div.ah { 233 | background-color: black; 234 | font-weight: bold; 235 | color: #ffffff; 236 | margin-bottom: 3px; 237 | margin-top: 3px; 238 | padding: 0.2em; 239 | border: solid thin #333; 240 | border-radius: 0.5em; 241 | -webkit-border-radius: .5em; 242 | -moz-border-radius: .5em; 243 | box-shadow: 2px 2px 3px #999; 244 | -webkit-box-shadow: 2px 2px 3px #999; 245 | -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; 246 | background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); 247 | background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); 248 | } 249 | 250 | div.groupHeader { 251 | margin-left: 16px; 252 | margin-top: 12px; 253 | font-weight: bold; 254 | } 255 | 256 | div.groupText { 257 | margin-left: 16px; 258 | font-style: italic; 259 | } 260 | 261 | body { 262 | background-color: white; 263 | color: black; 264 | margin: 0; 265 | } 266 | 267 | div.contents { 268 | margin-top: 10px; 269 | margin-left: 12px; 270 | margin-right: 8px; 271 | } 272 | 273 | td.indexkey { 274 | background-color: #EBEFF6; 275 | font-weight: bold; 276 | border: 1px solid #C4CFE5; 277 | margin: 2px 0px 2px 0; 278 | padding: 2px 10px; 279 | white-space: nowrap; 280 | vertical-align: top; 281 | } 282 | 283 | td.indexvalue { 284 | background-color: #EBEFF6; 285 | border: 1px solid #C4CFE5; 286 | padding: 2px 10px; 287 | margin: 2px 0px; 288 | } 289 | 290 | tr.memlist { 291 | background-color: #EEF1F7; 292 | } 293 | 294 | p.formulaDsp { 295 | text-align: center; 296 | } 297 | 298 | img.formulaDsp { 299 | 300 | } 301 | 302 | img.formulaInl { 303 | vertical-align: middle; 304 | } 305 | 306 | div.center { 307 | text-align: center; 308 | margin-top: 0px; 309 | margin-bottom: 0px; 310 | padding: 0px; 311 | } 312 | 313 | div.center img { 314 | border: 0px; 315 | } 316 | 317 | address.footer { 318 | text-align: right; 319 | padding-right: 12px; 320 | } 321 | 322 | img.footer { 323 | border: 0px; 324 | vertical-align: middle; 325 | } 326 | 327 | /* @group Code Colorization */ 328 | 329 | span.keyword { 330 | color: #008000 331 | } 332 | 333 | span.keywordtype { 334 | color: #604020 335 | } 336 | 337 | span.keywordflow { 338 | color: #e08000 339 | } 340 | 341 | span.comment { 342 | color: #800000 343 | } 344 | 345 | span.preprocessor { 346 | color: #806020 347 | } 348 | 349 | span.stringliteral { 350 | color: #002080 351 | } 352 | 353 | span.charliteral { 354 | color: #008080 355 | } 356 | 357 | span.vhdldigit { 358 | color: #ff00ff 359 | } 360 | 361 | span.vhdlchar { 362 | color: #000000 363 | } 364 | 365 | span.vhdlkeyword { 366 | color: #700070 367 | } 368 | 369 | span.vhdllogic { 370 | color: #ff0000 371 | } 372 | 373 | blockquote { 374 | background-color: #F7F8FB; 375 | border-left: 2px solid #9CAFD4; 376 | margin: 0 24px 0 4px; 377 | padding: 0 12px 0 16px; 378 | } 379 | 380 | /* @end */ 381 | 382 | /* 383 | .search { 384 | color: #003399; 385 | font-weight: bold; 386 | } 387 | 388 | form.search { 389 | margin-bottom: 0px; 390 | margin-top: 0px; 391 | } 392 | 393 | input.search { 394 | font-size: 75%; 395 | color: #000080; 396 | font-weight: normal; 397 | background-color: #e8eef2; 398 | } 399 | */ 400 | 401 | td.tiny { 402 | font-size: 75%; 403 | } 404 | 405 | .dirtab { 406 | padding: 4px; 407 | border-collapse: collapse; 408 | border: 1px solid #A3B4D7; 409 | } 410 | 411 | th.dirtab { 412 | background: #EBEFF6; 413 | font-weight: bold; 414 | } 415 | 416 | hr { 417 | height: 0px; 418 | border: none; 419 | border-top: 1px solid #4A6AAA; 420 | } 421 | 422 | hr.footer { 423 | height: 1px; 424 | } 425 | 426 | /* @group Member Descriptions */ 427 | 428 | table.memberdecls { 429 | border-spacing: 0px; 430 | padding: 0px; 431 | } 432 | 433 | .memberdecls td, .fieldtable tr { 434 | -webkit-transition-property: background-color, box-shadow; 435 | -webkit-transition-duration: 0.5s; 436 | -moz-transition-property: background-color, box-shadow; 437 | -moz-transition-duration: 0.5s; 438 | -ms-transition-property: background-color, box-shadow; 439 | -ms-transition-duration: 0.5s; 440 | -o-transition-property: background-color, box-shadow; 441 | -o-transition-duration: 0.5s; 442 | transition-property: background-color, box-shadow; 443 | transition-duration: 0.5s; 444 | } 445 | 446 | .memberdecls td.glow, .fieldtable tr.glow { 447 | background-color: cyan; 448 | box-shadow: 0 0 15px cyan; 449 | } 450 | 451 | .mdescLeft, .mdescRight, 452 | .memItemLeft, .memItemRight, 453 | .memTemplItemLeft, .memTemplItemRight, .memTemplParams { 454 | background-color: #F9FAFC; 455 | border: none; 456 | margin: 4px; 457 | padding: 1px 0 0 8px; 458 | } 459 | 460 | .mdescLeft, .mdescRight { 461 | padding: 0px 8px 4px 8px; 462 | color: #555; 463 | } 464 | 465 | .memSeparator { 466 | border-bottom: 1px solid #DEE4F0; 467 | line-height: 1px; 468 | margin: 0px; 469 | padding: 0px; 470 | } 471 | 472 | .memItemLeft, .memTemplItemLeft { 473 | white-space: nowrap; 474 | } 475 | 476 | .memItemRight { 477 | width: 100%; 478 | } 479 | 480 | .memTemplParams { 481 | color: #4665A2; 482 | white-space: nowrap; 483 | font-size: 80%; 484 | } 485 | 486 | /* @end */ 487 | 488 | /* @group Member Details */ 489 | 490 | /* Styles for detailed member documentation */ 491 | 492 | .memtemplate { 493 | font-size: 80%; 494 | color: #4665A2; 495 | font-weight: normal; 496 | margin-left: 9px; 497 | } 498 | 499 | .memnav { 500 | background-color: #EBEFF6; 501 | border: 1px solid #A3B4D7; 502 | text-align: center; 503 | margin: 2px; 504 | margin-right: 15px; 505 | padding: 2px; 506 | } 507 | 508 | .mempage { 509 | width: 100%; 510 | } 511 | 512 | .memitem { 513 | padding: 0; 514 | margin-bottom: 10px; 515 | margin-right: 5px; 516 | -webkit-transition: box-shadow 0.5s linear; 517 | -moz-transition: box-shadow 0.5s linear; 518 | -ms-transition: box-shadow 0.5s linear; 519 | -o-transition: box-shadow 0.5s linear; 520 | transition: box-shadow 0.5s linear; 521 | display: table !important; 522 | width: 100%; 523 | } 524 | 525 | .memitem.glow { 526 | box-shadow: 0 0 15px cyan; 527 | } 528 | 529 | .memname { 530 | font-weight: bold; 531 | margin-left: 6px; 532 | } 533 | 534 | .memname td { 535 | vertical-align: bottom; 536 | } 537 | 538 | .memproto, dl.reflist dt { 539 | border-top: 1px solid #A8B8D9; 540 | border-left: 1px solid #A8B8D9; 541 | border-right: 1px solid #A8B8D9; 542 | padding: 6px 0px 6px 0px; 543 | color: #253555; 544 | font-weight: bold; 545 | text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); 546 | background-image:url('nav_f.png'); 547 | background-repeat:repeat-x; 548 | background-color: #E2E8F2; 549 | /* opera specific markup */ 550 | box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); 551 | border-top-right-radius: 4px; 552 | border-top-left-radius: 4px; 553 | /* firefox specific markup */ 554 | -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; 555 | -moz-border-radius-topright: 4px; 556 | -moz-border-radius-topleft: 4px; 557 | /* webkit specific markup */ 558 | -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); 559 | -webkit-border-top-right-radius: 4px; 560 | -webkit-border-top-left-radius: 4px; 561 | 562 | } 563 | 564 | .memdoc, dl.reflist dd { 565 | border-bottom: 1px solid #A8B8D9; 566 | border-left: 1px solid #A8B8D9; 567 | border-right: 1px solid #A8B8D9; 568 | padding: 6px 10px 2px 10px; 569 | background-color: #FBFCFD; 570 | border-top-width: 0; 571 | background-image:url('nav_g.png'); 572 | background-repeat:repeat-x; 573 | background-color: #FFFFFF; 574 | /* opera specific markup */ 575 | border-bottom-left-radius: 4px; 576 | border-bottom-right-radius: 4px; 577 | box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); 578 | /* firefox specific markup */ 579 | -moz-border-radius-bottomleft: 4px; 580 | -moz-border-radius-bottomright: 4px; 581 | -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; 582 | /* webkit specific markup */ 583 | -webkit-border-bottom-left-radius: 4px; 584 | -webkit-border-bottom-right-radius: 4px; 585 | -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); 586 | } 587 | 588 | dl.reflist dt { 589 | padding: 5px; 590 | } 591 | 592 | dl.reflist dd { 593 | margin: 0px 0px 10px 0px; 594 | padding: 5px; 595 | } 596 | 597 | .paramkey { 598 | text-align: right; 599 | } 600 | 601 | .paramtype { 602 | white-space: nowrap; 603 | } 604 | 605 | .paramname { 606 | color: #602020; 607 | white-space: nowrap; 608 | } 609 | .paramname em { 610 | font-style: normal; 611 | } 612 | .paramname code { 613 | line-height: 14px; 614 | } 615 | 616 | .params, .retval, .exception, .tparams { 617 | margin-left: 0px; 618 | padding-left: 0px; 619 | } 620 | 621 | .params .paramname, .retval .paramname { 622 | font-weight: bold; 623 | vertical-align: top; 624 | } 625 | 626 | .params .paramtype { 627 | font-style: italic; 628 | vertical-align: top; 629 | } 630 | 631 | .params .paramdir { 632 | font-family: "courier new",courier,monospace; 633 | vertical-align: top; 634 | } 635 | 636 | table.mlabels { 637 | border-spacing: 0px; 638 | } 639 | 640 | td.mlabels-left { 641 | width: 100%; 642 | padding: 0px; 643 | } 644 | 645 | td.mlabels-right { 646 | vertical-align: bottom; 647 | padding: 0px; 648 | white-space: nowrap; 649 | } 650 | 651 | span.mlabels { 652 | margin-left: 8px; 653 | } 654 | 655 | span.mlabel { 656 | background-color: #728DC1; 657 | border-top:1px solid #5373B4; 658 | border-left:1px solid #5373B4; 659 | border-right:1px solid #C4CFE5; 660 | border-bottom:1px solid #C4CFE5; 661 | text-shadow: none; 662 | color: white; 663 | margin-right: 4px; 664 | padding: 2px 3px; 665 | border-radius: 3px; 666 | font-size: 7pt; 667 | white-space: nowrap; 668 | vertical-align: middle; 669 | } 670 | 671 | 672 | 673 | /* @end */ 674 | 675 | /* these are for tree view inside a (index) page */ 676 | 677 | div.directory { 678 | margin: 10px 0px; 679 | border-top: 1px solid #9CAFD4; 680 | border-bottom: 1px solid #9CAFD4; 681 | width: 100%; 682 | } 683 | 684 | .directory table { 685 | border-collapse:collapse; 686 | } 687 | 688 | .directory td { 689 | margin: 0px; 690 | padding: 0px; 691 | vertical-align: top; 692 | } 693 | 694 | .directory td.entry { 695 | white-space: nowrap; 696 | padding-right: 6px; 697 | padding-top: 3px; 698 | } 699 | 700 | .directory td.entry a { 701 | outline:none; 702 | } 703 | 704 | .directory td.entry a img { 705 | border: none; 706 | } 707 | 708 | .directory td.desc { 709 | width: 100%; 710 | padding-left: 6px; 711 | padding-right: 6px; 712 | padding-top: 3px; 713 | border-left: 1px solid rgba(0,0,0,0.05); 714 | } 715 | 716 | .directory tr.even { 717 | padding-left: 6px; 718 | background-color: #F7F8FB; 719 | } 720 | 721 | .directory img { 722 | vertical-align: -30%; 723 | } 724 | 725 | .directory .levels { 726 | white-space: nowrap; 727 | width: 100%; 728 | text-align: right; 729 | font-size: 9pt; 730 | } 731 | 732 | .directory .levels span { 733 | cursor: pointer; 734 | padding-left: 2px; 735 | padding-right: 2px; 736 | color: #3D578C; 737 | } 738 | 739 | .arrow { 740 | color: #9CAFD4; 741 | -webkit-user-select: none; 742 | -khtml-user-select: none; 743 | -moz-user-select: none; 744 | -ms-user-select: none; 745 | user-select: none; 746 | cursor: pointer; 747 | font-size: 80%; 748 | display: inline-block; 749 | width: 16px; 750 | height: 22px; 751 | } 752 | 753 | .icon { 754 | font-family: Arial, Helvetica; 755 | font-weight: bold; 756 | font-size: 12px; 757 | height: 14px; 758 | width: 16px; 759 | display: inline-block; 760 | background-color: #728DC1; 761 | color: white; 762 | text-align: center; 763 | border-radius: 4px; 764 | margin-left: 2px; 765 | margin-right: 2px; 766 | } 767 | 768 | .icona { 769 | width: 24px; 770 | height: 22px; 771 | display: inline-block; 772 | } 773 | 774 | .iconfopen { 775 | width: 24px; 776 | height: 18px; 777 | margin-bottom: 4px; 778 | background-image:url('ftv2folderopen.png'); 779 | background-position: 0px -4px; 780 | background-repeat: repeat-y; 781 | vertical-align:top; 782 | display: inline-block; 783 | } 784 | 785 | .iconfclosed { 786 | width: 24px; 787 | height: 18px; 788 | margin-bottom: 4px; 789 | background-image:url('ftv2folderclosed.png'); 790 | background-position: 0px -4px; 791 | background-repeat: repeat-y; 792 | vertical-align:top; 793 | display: inline-block; 794 | } 795 | 796 | .icondoc { 797 | width: 24px; 798 | height: 18px; 799 | margin-bottom: 4px; 800 | background-image:url('ftv2doc.png'); 801 | background-position: 0px -4px; 802 | background-repeat: repeat-y; 803 | vertical-align:top; 804 | display: inline-block; 805 | } 806 | 807 | table.directory { 808 | font: 400 14px Roboto,sans-serif; 809 | } 810 | 811 | /* @end */ 812 | 813 | div.dynheader { 814 | margin-top: 8px; 815 | -webkit-touch-callout: none; 816 | -webkit-user-select: none; 817 | -khtml-user-select: none; 818 | -moz-user-select: none; 819 | -ms-user-select: none; 820 | user-select: none; 821 | } 822 | 823 | address { 824 | font-style: normal; 825 | color: #2A3D61; 826 | } 827 | 828 | table.doxtable { 829 | border-collapse:collapse; 830 | margin-top: 4px; 831 | margin-bottom: 4px; 832 | } 833 | 834 | table.doxtable td, table.doxtable th { 835 | border: 1px solid #2D4068; 836 | padding: 3px 7px 2px; 837 | } 838 | 839 | table.doxtable th { 840 | background-color: #374F7F; 841 | color: #FFFFFF; 842 | font-size: 110%; 843 | padding-bottom: 4px; 844 | padding-top: 5px; 845 | } 846 | 847 | table.fieldtable { 848 | /*width: 100%;*/ 849 | margin-bottom: 10px; 850 | border: 1px solid #A8B8D9; 851 | border-spacing: 0px; 852 | -moz-border-radius: 4px; 853 | -webkit-border-radius: 4px; 854 | border-radius: 4px; 855 | -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; 856 | -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); 857 | box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); 858 | } 859 | 860 | .fieldtable td, .fieldtable th { 861 | padding: 3px 7px 2px; 862 | } 863 | 864 | .fieldtable td.fieldtype, .fieldtable td.fieldname { 865 | white-space: nowrap; 866 | border-right: 1px solid #A8B8D9; 867 | border-bottom: 1px solid #A8B8D9; 868 | vertical-align: top; 869 | } 870 | 871 | .fieldtable td.fieldname { 872 | padding-top: 3px; 873 | } 874 | 875 | .fieldtable td.fielddoc { 876 | border-bottom: 1px solid #A8B8D9; 877 | /*width: 100%;*/ 878 | } 879 | 880 | .fieldtable td.fielddoc p:first-child { 881 | margin-top: 0px; 882 | } 883 | 884 | .fieldtable td.fielddoc p:last-child { 885 | margin-bottom: 2px; 886 | } 887 | 888 | .fieldtable tr:last-child td { 889 | border-bottom: none; 890 | } 891 | 892 | .fieldtable th { 893 | background-image:url('nav_f.png'); 894 | background-repeat:repeat-x; 895 | background-color: #E2E8F2; 896 | font-size: 90%; 897 | color: #253555; 898 | padding-bottom: 4px; 899 | padding-top: 5px; 900 | text-align:left; 901 | -moz-border-radius-topleft: 4px; 902 | -moz-border-radius-topright: 4px; 903 | -webkit-border-top-left-radius: 4px; 904 | -webkit-border-top-right-radius: 4px; 905 | border-top-left-radius: 4px; 906 | border-top-right-radius: 4px; 907 | border-bottom: 1px solid #A8B8D9; 908 | } 909 | 910 | 911 | .tabsearch { 912 | top: 0px; 913 | left: 10px; 914 | height: 36px; 915 | background-image: url('tab_b.png'); 916 | z-index: 101; 917 | overflow: hidden; 918 | font-size: 13px; 919 | } 920 | 921 | .navpath ul 922 | { 923 | font-size: 11px; 924 | background-image:url('tab_b.png'); 925 | background-repeat:repeat-x; 926 | background-position: 0 -5px; 927 | height:30px; 928 | line-height:30px; 929 | color:#8AA0CC; 930 | border:solid 1px #C2CDE4; 931 | overflow:hidden; 932 | margin:0px; 933 | padding:0px; 934 | } 935 | 936 | .navpath li 937 | { 938 | list-style-type:none; 939 | float:left; 940 | padding-left:10px; 941 | padding-right:15px; 942 | background-image:url('bc_s.png'); 943 | background-repeat:no-repeat; 944 | background-position:right; 945 | color:#364D7C; 946 | } 947 | 948 | .navpath li.navelem a 949 | { 950 | height:32px; 951 | display:block; 952 | text-decoration: none; 953 | outline: none; 954 | color: #283A5D; 955 | font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; 956 | text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); 957 | text-decoration: none; 958 | } 959 | 960 | .navpath li.navelem a:hover 961 | { 962 | color:#6884BD; 963 | } 964 | 965 | .navpath li.footer 966 | { 967 | list-style-type:none; 968 | float:right; 969 | padding-left:10px; 970 | padding-right:15px; 971 | background-image:none; 972 | background-repeat:no-repeat; 973 | background-position:right; 974 | color:#364D7C; 975 | font-size: 8pt; 976 | } 977 | 978 | 979 | div.summary 980 | { 981 | float: right; 982 | font-size: 8pt; 983 | padding-right: 5px; 984 | width: 50%; 985 | text-align: right; 986 | } 987 | 988 | div.summary a 989 | { 990 | white-space: nowrap; 991 | } 992 | 993 | div.ingroups 994 | { 995 | font-size: 8pt; 996 | width: 50%; 997 | text-align: left; 998 | } 999 | 1000 | div.ingroups a 1001 | { 1002 | white-space: nowrap; 1003 | } 1004 | 1005 | div.header 1006 | { 1007 | background-image:url('nav_h.png'); 1008 | background-repeat:repeat-x; 1009 | background-color: #F9FAFC; 1010 | margin: 0px; 1011 | border-bottom: 1px solid #C4CFE5; 1012 | } 1013 | 1014 | div.headertitle 1015 | { 1016 | padding: 5px 5px 5px 10px; 1017 | } 1018 | 1019 | dl 1020 | { 1021 | padding: 0 0 0 10px; 1022 | } 1023 | 1024 | /* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ 1025 | dl.section 1026 | { 1027 | margin-left: 0px; 1028 | padding-left: 0px; 1029 | } 1030 | 1031 | dl.note 1032 | { 1033 | margin-left:-7px; 1034 | padding-left: 3px; 1035 | border-left:4px solid; 1036 | border-color: #D0C000; 1037 | } 1038 | 1039 | dl.warning, dl.attention 1040 | { 1041 | margin-left:-7px; 1042 | padding-left: 3px; 1043 | border-left:4px solid; 1044 | border-color: #FF0000; 1045 | } 1046 | 1047 | dl.pre, dl.post, dl.invariant 1048 | { 1049 | margin-left:-7px; 1050 | padding-left: 3px; 1051 | border-left:4px solid; 1052 | border-color: #00D000; 1053 | } 1054 | 1055 | dl.deprecated 1056 | { 1057 | margin-left:-7px; 1058 | padding-left: 3px; 1059 | border-left:4px solid; 1060 | border-color: #505050; 1061 | } 1062 | 1063 | dl.todo 1064 | { 1065 | margin-left:-7px; 1066 | padding-left: 3px; 1067 | border-left:4px solid; 1068 | border-color: #00C0E0; 1069 | } 1070 | 1071 | dl.test 1072 | { 1073 | margin-left:-7px; 1074 | padding-left: 3px; 1075 | border-left:4px solid; 1076 | border-color: #3030E0; 1077 | } 1078 | 1079 | dl.bug 1080 | { 1081 | margin-left:-7px; 1082 | padding-left: 3px; 1083 | border-left:4px solid; 1084 | border-color: #C08050; 1085 | } 1086 | 1087 | dl.section dd { 1088 | margin-bottom: 6px; 1089 | } 1090 | 1091 | 1092 | #projectlogo 1093 | { 1094 | text-align: center; 1095 | vertical-align: bottom; 1096 | border-collapse: separate; 1097 | } 1098 | 1099 | #projectlogo img 1100 | { 1101 | border: 0px none; 1102 | } 1103 | 1104 | #projectname 1105 | { 1106 | font: 300% Tahoma, Arial,sans-serif; 1107 | margin: 0px; 1108 | padding: 2px 0px; 1109 | } 1110 | 1111 | #projectbrief 1112 | { 1113 | font: 120% Tahoma, Arial,sans-serif; 1114 | margin: 0px; 1115 | padding: 0px; 1116 | } 1117 | 1118 | #projectnumber 1119 | { 1120 | font: 50% Tahoma, Arial,sans-serif; 1121 | margin: 0px; 1122 | padding: 0px; 1123 | } 1124 | 1125 | #titlearea 1126 | { 1127 | padding: 0px; 1128 | margin: 0px; 1129 | width: 100%; 1130 | border-bottom: 1px solid #5373B4; 1131 | } 1132 | 1133 | .image 1134 | { 1135 | text-align: center; 1136 | } 1137 | 1138 | .dotgraph 1139 | { 1140 | text-align: center; 1141 | } 1142 | 1143 | .mscgraph 1144 | { 1145 | text-align: center; 1146 | } 1147 | 1148 | .diagraph 1149 | { 1150 | text-align: center; 1151 | } 1152 | 1153 | .caption 1154 | { 1155 | font-weight: bold; 1156 | } 1157 | 1158 | div.zoom 1159 | { 1160 | border: 1px solid #90A5CE; 1161 | } 1162 | 1163 | dl.citelist { 1164 | margin-bottom:50px; 1165 | } 1166 | 1167 | dl.citelist dt { 1168 | color:#334975; 1169 | float:left; 1170 | font-weight:bold; 1171 | margin-right:10px; 1172 | padding:5px; 1173 | } 1174 | 1175 | dl.citelist dd { 1176 | margin:2px 0; 1177 | padding:5px 0; 1178 | } 1179 | 1180 | div.toc { 1181 | padding: 14px 25px; 1182 | background-color: #F4F6FA; 1183 | border: 1px solid #D8DFEE; 1184 | border-radius: 7px 7px 7px 7px; 1185 | float: right; 1186 | height: auto; 1187 | margin: 0 20px 10px 10px; 1188 | width: 200px; 1189 | } 1190 | 1191 | div.toc li { 1192 | background: url("bdwn.png") no-repeat scroll 0 5px transparent; 1193 | font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; 1194 | margin-top: 5px; 1195 | padding-left: 10px; 1196 | padding-top: 2px; 1197 | } 1198 | 1199 | div.toc h3 { 1200 | font: bold 12px/1.2 Arial,FreeSans,sans-serif; 1201 | color: #4665A2; 1202 | border-bottom: 0 none; 1203 | margin: 0; 1204 | } 1205 | 1206 | div.toc ul { 1207 | list-style: none outside none; 1208 | border: medium none; 1209 | padding: 0px; 1210 | } 1211 | 1212 | div.toc li.level1 { 1213 | margin-left: 0px; 1214 | } 1215 | 1216 | div.toc li.level2 { 1217 | margin-left: 15px; 1218 | } 1219 | 1220 | div.toc li.level3 { 1221 | margin-left: 30px; 1222 | } 1223 | 1224 | div.toc li.level4 { 1225 | margin-left: 45px; 1226 | } 1227 | 1228 | .inherit_header { 1229 | font-weight: bold; 1230 | color: gray; 1231 | cursor: pointer; 1232 | -webkit-touch-callout: none; 1233 | -webkit-user-select: none; 1234 | -khtml-user-select: none; 1235 | -moz-user-select: none; 1236 | -ms-user-select: none; 1237 | user-select: none; 1238 | } 1239 | 1240 | .inherit_header td { 1241 | padding: 6px 0px 2px 5px; 1242 | } 1243 | 1244 | .inherit { 1245 | display: none; 1246 | } 1247 | 1248 | tr.heading h2 { 1249 | margin-top: 12px; 1250 | margin-bottom: 4px; 1251 | } 1252 | 1253 | /* tooltip related style info */ 1254 | 1255 | .ttc { 1256 | position: absolute; 1257 | display: none; 1258 | } 1259 | 1260 | #powerTip { 1261 | cursor: default; 1262 | white-space: nowrap; 1263 | background-color: white; 1264 | border: 1px solid gray; 1265 | border-radius: 4px 4px 4px 4px; 1266 | box-shadow: 1px 1px 7px gray; 1267 | display: none; 1268 | font-size: smaller; 1269 | max-width: 80%; 1270 | opacity: 0.9; 1271 | padding: 1ex 1em 1em; 1272 | position: absolute; 1273 | z-index: 2147483647; 1274 | } 1275 | 1276 | #powerTip div.ttdoc { 1277 | color: grey; 1278 | font-style: italic; 1279 | } 1280 | 1281 | #powerTip div.ttname a { 1282 | font-weight: bold; 1283 | } 1284 | 1285 | #powerTip div.ttname { 1286 | font-weight: bold; 1287 | } 1288 | 1289 | #powerTip div.ttdeci { 1290 | color: #006318; 1291 | } 1292 | 1293 | #powerTip div { 1294 | margin: 0px; 1295 | padding: 0px; 1296 | font: 12px/16px Roboto,sans-serif; 1297 | } 1298 | 1299 | #powerTip:before, #powerTip:after { 1300 | content: ""; 1301 | position: absolute; 1302 | margin: 0px; 1303 | } 1304 | 1305 | #powerTip.n:after, #powerTip.n:before, 1306 | #powerTip.s:after, #powerTip.s:before, 1307 | #powerTip.w:after, #powerTip.w:before, 1308 | #powerTip.e:after, #powerTip.e:before, 1309 | #powerTip.ne:after, #powerTip.ne:before, 1310 | #powerTip.se:after, #powerTip.se:before, 1311 | #powerTip.nw:after, #powerTip.nw:before, 1312 | #powerTip.sw:after, #powerTip.sw:before { 1313 | border: solid transparent; 1314 | content: " "; 1315 | height: 0; 1316 | width: 0; 1317 | position: absolute; 1318 | } 1319 | 1320 | #powerTip.n:after, #powerTip.s:after, 1321 | #powerTip.w:after, #powerTip.e:after, 1322 | #powerTip.nw:after, #powerTip.ne:after, 1323 | #powerTip.sw:after, #powerTip.se:after { 1324 | border-color: rgba(255, 255, 255, 0); 1325 | } 1326 | 1327 | #powerTip.n:before, #powerTip.s:before, 1328 | #powerTip.w:before, #powerTip.e:before, 1329 | #powerTip.nw:before, #powerTip.ne:before, 1330 | #powerTip.sw:before, #powerTip.se:before { 1331 | border-color: rgba(128, 128, 128, 0); 1332 | } 1333 | 1334 | #powerTip.n:after, #powerTip.n:before, 1335 | #powerTip.ne:after, #powerTip.ne:before, 1336 | #powerTip.nw:after, #powerTip.nw:before { 1337 | top: 100%; 1338 | } 1339 | 1340 | #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { 1341 | border-top-color: #ffffff; 1342 | border-width: 10px; 1343 | margin: 0px -10px; 1344 | } 1345 | #powerTip.n:before { 1346 | border-top-color: #808080; 1347 | border-width: 11px; 1348 | margin: 0px -11px; 1349 | } 1350 | #powerTip.n:after, #powerTip.n:before { 1351 | left: 50%; 1352 | } 1353 | 1354 | #powerTip.nw:after, #powerTip.nw:before { 1355 | right: 14px; 1356 | } 1357 | 1358 | #powerTip.ne:after, #powerTip.ne:before { 1359 | left: 14px; 1360 | } 1361 | 1362 | #powerTip.s:after, #powerTip.s:before, 1363 | #powerTip.se:after, #powerTip.se:before, 1364 | #powerTip.sw:after, #powerTip.sw:before { 1365 | bottom: 100%; 1366 | } 1367 | 1368 | #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { 1369 | border-bottom-color: #ffffff; 1370 | border-width: 10px; 1371 | margin: 0px -10px; 1372 | } 1373 | 1374 | #powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { 1375 | border-bottom-color: #808080; 1376 | border-width: 11px; 1377 | margin: 0px -11px; 1378 | } 1379 | 1380 | #powerTip.s:after, #powerTip.s:before { 1381 | left: 50%; 1382 | } 1383 | 1384 | #powerTip.sw:after, #powerTip.sw:before { 1385 | right: 14px; 1386 | } 1387 | 1388 | #powerTip.se:after, #powerTip.se:before { 1389 | left: 14px; 1390 | } 1391 | 1392 | #powerTip.e:after, #powerTip.e:before { 1393 | left: 100%; 1394 | } 1395 | #powerTip.e:after { 1396 | border-left-color: #ffffff; 1397 | border-width: 10px; 1398 | top: 50%; 1399 | margin-top: -10px; 1400 | } 1401 | #powerTip.e:before { 1402 | border-left-color: #808080; 1403 | border-width: 11px; 1404 | top: 50%; 1405 | margin-top: -11px; 1406 | } 1407 | 1408 | #powerTip.w:after, #powerTip.w:before { 1409 | right: 100%; 1410 | } 1411 | #powerTip.w:after { 1412 | border-right-color: #ffffff; 1413 | border-width: 10px; 1414 | top: 50%; 1415 | margin-top: -10px; 1416 | } 1417 | #powerTip.w:before { 1418 | border-right-color: #808080; 1419 | border-width: 11px; 1420 | top: 50%; 1421 | margin-top: -11px; 1422 | } 1423 | 1424 | @media print 1425 | { 1426 | #top { display: none; } 1427 | #side-nav { display: none; } 1428 | #nav-path { display: none; } 1429 | body { overflow:visible; } 1430 | h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } 1431 | .summary { display: none; } 1432 | .memitem { page-break-inside: avoid; } 1433 | #doc-content 1434 | { 1435 | margin-left:0 !important; 1436 | height:auto !important; 1437 | width:auto !important; 1438 | overflow:inherit; 1439 | display:inline; 1440 | } 1441 | } 1442 | 1443 | --------------------------------------------------------------------------------