Initial port of STM32L100 code
This code was originally written for use with the CooCox IDE back in 2014. It uses ST StdPeriphLib (SPL) as opposed to HAL. I have ported this using the built-in board definition for a board that supports the SPL. After making some small changes (mostly to include paths, but also un-inlining a couple function calls) and removing dead code, it appears to compile cleanly. Actual binary is untested.
This commit is contained in:
		
							parent
							
								
									1182c9b578
								
							
						
					
					
						commit
						03376cc654
					
				
							
								
								
									
										5
									
								
								fw_dc22_stm32l100/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								fw_dc22_stm32l100/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | .pio | ||||||
|  | .vscode/.browse.c_cpp.db* | ||||||
|  | .vscode/c_cpp_properties.json | ||||||
|  | .vscode/launch.json | ||||||
|  | .vscode/ipch | ||||||
							
								
								
									
										10
									
								
								fw_dc22_stm32l100/.vscode/extensions.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								fw_dc22_stm32l100/.vscode/extensions.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | { | ||||||
|  |     // See http://go.microsoft.com/fwlink/?LinkId=827846 | ||||||
|  |     // for the documentation about the extensions.json format | ||||||
|  |     "recommendations": [ | ||||||
|  |         "platformio.platformio-ide" | ||||||
|  |     ], | ||||||
|  |     "unwantedRecommendations": [ | ||||||
|  |         "ms-vscode.cpptools-extension-pack" | ||||||
|  |     ] | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								fw_dc22_stm32l100/include/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								fw_dc22_stm32l100/include/README
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | 
 | ||||||
|  | This directory is intended for project header files. | ||||||
|  | 
 | ||||||
|  | A header file is a file containing C declarations and macro definitions | ||||||
|  | to be shared between several project source files. You request the use of a | ||||||
|  | header file in your project source file (C, C++, etc) located in `src` folder | ||||||
|  | by including it, with the C preprocessing directive `#include'. | ||||||
|  | 
 | ||||||
|  | ```src/main.c | ||||||
|  | 
 | ||||||
|  | #include "header.h" | ||||||
|  | 
 | ||||||
|  | int main (void) | ||||||
|  | { | ||||||
|  |  ... | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Including a header file produces the same results as copying the header file | ||||||
|  | into each source file that needs it. Such copying would be time-consuming | ||||||
|  | and error-prone. With a header file, the related declarations appear | ||||||
|  | in only one place. If they need to be changed, they can be changed in one | ||||||
|  | place, and programs that include the header file will automatically use the | ||||||
|  | new version when next recompiled. The header file eliminates the labor of | ||||||
|  | finding and changing all the copies as well as the risk that a failure to | ||||||
|  | find one copy will result in inconsistencies within a program. | ||||||
|  | 
 | ||||||
|  | In C, the usual convention is to give header files names that end with `.h'. | ||||||
|  | It is most portable to use only letters, digits, dashes, and underscores in | ||||||
|  | header file names, and at most one dot. | ||||||
|  | 
 | ||||||
|  | Read more about using header files in official GCC documentation: | ||||||
|  | 
 | ||||||
|  | * Include Syntax | ||||||
|  | * Include Operation | ||||||
|  | * Once-Only Headers | ||||||
|  | * Computed Includes | ||||||
|  | 
 | ||||||
|  | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html | ||||||
							
								
								
									
										98
									
								
								fw_dc22_stm32l100/include/pirate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								fw_dc22_stm32l100/include/pirate.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | |||||||
|  | /**
 | ||||||
|  |  * pirate.h: half-assed piracy-enabling features for drunken, brazen pirates | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: pirate.h 505 2021-09-05 19:07:51Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_PIRATE_H | ||||||
|  | #define __PIRATE_PIRATE_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | /* cmsis req'd */ | ||||||
|  | #include "stm32l1xx_conf.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define PIRATE_PROG_SAVED_MAX 	15 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* helper macros */ | ||||||
|  | #define sizeof_array(x) 		sizeof(x) / sizeof(x[0]) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* pirate settings */ | ||||||
|  | #define PIRATE_PROG_MATRIX 			0 | ||||||
|  | #define PIRATE_PROG_BONES 			1 | ||||||
|  | #define PIRATE_PROG_EYES 			2 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | typedef struct PirateProg { | ||||||
|  | 	uint8_t type; 		// bit0 = pattern(high)/program(low), bit1 = always init, bit7 = enabled
 | ||||||
|  | 	uint8_t progidx; | ||||||
|  | 	uint16_t wait; | ||||||
|  | 	uint16_t level; | ||||||
|  | 	uint32_t offset; | ||||||
|  | 	uint32_t option; | ||||||
|  | 	uint16_t dwell; | ||||||
|  | } PirateProg; | ||||||
|  | 
 | ||||||
|  | typedef struct PirateSettings { | ||||||
|  | 	char name[32]; | ||||||
|  | 	uint8_t fav_color[3]; | ||||||
|  | 	uint8_t beeper; | ||||||
|  | 	uint8_t beep_type[8]; | ||||||
|  | 	uint8_t contrast; | ||||||
|  | 	uint8_t autorun; | ||||||
|  | 	uint8_t led_autoadjust; | ||||||
|  | 	uint8_t led_autogain_lev_min; | ||||||
|  | 	uint8_t led_autogain_lev_max; | ||||||
|  | 	uint8_t led_autothresh[5]; | ||||||
|  | 	uint8_t light_setgain; | ||||||
|  | 	uint8_t lcd_autobrite; | ||||||
|  | 	uint8_t lcd_brightness; | ||||||
|  | 	PirateProg led_prog[3][PIRATE_PROG_SAVED_MAX]; | ||||||
|  | 	uint8_t led_prog_mode; | ||||||
|  | 	uint16_t mic_cal[2]; | ||||||
|  | } PirateSettings; | ||||||
|  | 
 | ||||||
|  | extern PirateSettings settings; | ||||||
|  | #define PIRATE_SETTINGS_EEPROM_ADDR 		(uint32_t)0x8080000 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* misc extras */ | ||||||
|  | extern uint8_t temperature; | ||||||
|  | extern int8_t temperature_cal; | ||||||
|  | extern uint8_t light_level; | ||||||
|  | extern uint8_t light_gain; | ||||||
|  | extern uint16_t mic_peak; | ||||||
|  | 
 | ||||||
|  | extern uint8_t dc23_nametx; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* pirate variables */ | ||||||
|  | extern uint32_t pirate_prng_val; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* pirate functions */ | ||||||
|  | void pirate_shutdown(uint16_t type); | ||||||
|  | 
 | ||||||
|  | uint8_t pirate_prng(); | ||||||
|  | void pirate_delay(uint16_t ms); | ||||||
|  | int16_t pirate_scale(int16_t value, int16_t src_min, int16_t src_max, int16_t dest_min, int16_t dest_max); | ||||||
|  | char * pirate_itoa(uint32_t val, uint8_t base, uint8_t leftpad); | ||||||
|  | char * pirate_sitoa(int32_t val, uint8_t base, uint8_t leftpad); | ||||||
|  | 
 | ||||||
|  | uint16_t pirate_batt_voltage(); | ||||||
|  | void pirate_batt_log(uint16_t rawvalue); | ||||||
|  | 
 | ||||||
|  | uint16_t pirate_thermometer(uint8_t deg_f); | ||||||
|  | void pirate_thermometer_log(uint8_t temp); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										85
									
								
								fw_dc22_stm32l100/include/stm32l1xx_conf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								fw_dc22_stm32l100/include/stm32l1xx_conf.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,85 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    USART/USART_TwoBoards/DataExchangeDMA/stm32l1xx_conf.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V1.2.0 | ||||||
|  |   * @date    16-May-2014 | ||||||
|  |   * @brief   Library configuration file. | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __STM32L1xx_CONF_H | ||||||
|  | #define __STM32L1xx_CONF_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */ | ||||||
|  | #include "stm32l1xx_adc.h" | ||||||
|  | //#include "stm32l1xx_aes.h"
 | ||||||
|  | //#include "stm32l1xx_comp.h"
 | ||||||
|  | #include "stm32l1xx_crc.h" | ||||||
|  | #include "stm32l1xx_dac.h" | ||||||
|  | //#include "stm32l1xx_dbgmcu.h"
 | ||||||
|  | #include "stm32l1xx_dma.h" | ||||||
|  | #include "stm32l1xx_exti.h" | ||||||
|  | #include "stm32l1xx_flash.h" | ||||||
|  | //#include "stm32l1xx_fsmc.h"
 | ||||||
|  | #include "stm32l1xx_gpio.h" | ||||||
|  | #include "stm32l1xx_i2c.h" | ||||||
|  | //#include "stm32l1xx_iwdg.h"
 | ||||||
|  | //#include "stm32l1xx_lcd.h"
 | ||||||
|  | //#include "stm32l1xx_opamp.h"
 | ||||||
|  | #include "stm32l1xx_pwr.h" | ||||||
|  | #include "stm32l1xx_rcc.h" | ||||||
|  | //#include "stm32l1xx_rtc.h"
 | ||||||
|  | //#include "stm32l1xx_sdio.h"
 | ||||||
|  | #include "stm32l1xx_spi.h" | ||||||
|  | #include "stm32l1xx_syscfg.h" | ||||||
|  | #include "stm32l1xx_tim.h" | ||||||
|  | #include "stm32l1xx_usart.h" | ||||||
|  | //#include "stm32l1xx_wwdg.h"
 | ||||||
|  | #include "misc.h"  /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ | ||||||
|  | 
 | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Uncomment the line below to expanse the "assert_param" macro in the
 | ||||||
|  |    Standard Peripheral Library drivers code */ | ||||||
|  | /* #define USE_FULL_ASSERT    1 */ | ||||||
|  | 
 | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | #ifdef  USE_FULL_ASSERT | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  The assert_param macro is used for function's parameters check. | ||||||
|  |   * @param  expr: If expr is false, it calls assert_failed function which reports | ||||||
|  |   *         the name of the source file and the source line number of the call | ||||||
|  |   *         that failed. If expr is true, it returns no value. | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  |   #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  |   void assert_failed(uint8_t* file, uint32_t line); | ||||||
|  | #else | ||||||
|  |   #define assert_param(expr) ((void)0) | ||||||
|  | #endif /* USE_FULL_ASSERT */ | ||||||
|  | 
 | ||||||
|  | #endif /* __STM32L1xx_CONF_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										52
									
								
								fw_dc22_stm32l100/include/stm32l1xx_it.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								fw_dc22_stm32l100/include/stm32l1xx_it.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    ADC/ADC1_AnalogWatchdog/stm32l1xx_it.h  | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V1.2.2 | ||||||
|  |   * @date    17-November-2021 | ||||||
|  |   * @brief   This file contains the headers of the interrupt handlers. | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * Copyright (c) 2015 STMicroelectronics. | ||||||
|  |   * All rights reserved. | ||||||
|  |   * | ||||||
|  |   * This software is licensed under terms that can be found in the LICENSE file | ||||||
|  |   * in the root directory of this software component. | ||||||
|  |   * If no LICENSE file comes with this software, it is provided AS-IS. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __STM32L1xx_IT_H | ||||||
|  | #define __STM32L1xx_IT_H | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  extern "C" { | ||||||
|  | #endif  | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "stm32l1xx.h" | ||||||
|  | 
 | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | void NMI_Handler(void); | ||||||
|  | void HardFault_Handler(void); | ||||||
|  | void MemManage_Handler(void); | ||||||
|  | void BusFault_Handler(void); | ||||||
|  | void UsageFault_Handler(void); | ||||||
|  | void SVC_Handler(void); | ||||||
|  | void DebugMon_Handler(void); | ||||||
|  | void PendSV_Handler(void); | ||||||
|  | void SysTick_Handler(void); | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* __STM32L1xx_IT_H */ | ||||||
|  | 
 | ||||||
							
								
								
									
										103
									
								
								fw_dc22_stm32l100/include/usb_conf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								fw_dc22_stm32l100/include/usb_conf.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_conf.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   Virtual COM Port Demo configuration  header | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_CONF_H | ||||||
|  | #define __USB_CONF_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /*-------------------------------------------------------------*/ | ||||||
|  | /* EP_NUM */ | ||||||
|  | /* defines how many endpoints are used by the device */ | ||||||
|  | /*-------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #define EP_NUM              (4) | ||||||
|  | 
 | ||||||
|  | /*-------------------------------------------------------------*/ | ||||||
|  | /* --------------   Buffer Description Table  -----------------*/ | ||||||
|  | /*-------------------------------------------------------------*/ | ||||||
|  | /* buffer table base address */ | ||||||
|  | /* buffer table base address */ | ||||||
|  | #define BTABLE_ADDRESS      (0x00) | ||||||
|  | 
 | ||||||
|  | /* EP0  */ | ||||||
|  | /* rx/tx buffer base address */ | ||||||
|  | #define ENDP0_RXADDR        (0x40) | ||||||
|  | #define ENDP0_TXADDR        (0x80) | ||||||
|  | 
 | ||||||
|  | /* EP1  */ | ||||||
|  | /* tx buffer base address */ | ||||||
|  | #define ENDP1_TXADDR        (0xC0) | ||||||
|  | #define ENDP2_TXADDR        (0x100) | ||||||
|  | #define ENDP3_RXADDR        (0x110) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*-------------------------------------------------------------*/ | ||||||
|  | /* -------------------   ISTR events  -------------------------*/ | ||||||
|  | /*-------------------------------------------------------------*/ | ||||||
|  | /* IMR_MSK */ | ||||||
|  | /* mask defining which events has to be handled */ | ||||||
|  | /* by the device application software */ | ||||||
|  | // #define IMR_MSK (CNTR_CTRM  | CNTR_WKUPM | CNTR_SUSPM | CNTR_ERRM  | CNTR_SOFM | CNTR_ESOFM | CNTR_RESETM )
 | ||||||
|  | #define IMR_MSK (CNTR_CTRM | CNTR_WKUPM | CNTR_ERRM | CNTR_SOFM | CNTR_RESETM) | ||||||
|  | 
 | ||||||
|  | /*#define CTR_CALLBACK*/ | ||||||
|  | /*#define DOVR_CALLBACK*/ | ||||||
|  | /*#define ERR_CALLBACK*/ | ||||||
|  | /*#define WKUP_CALLBACK*/ | ||||||
|  | /*#define SUSP_CALLBACK*/ | ||||||
|  | /*#define RESET_CALLBACK*/ | ||||||
|  | #define SOF_CALLBACK | ||||||
|  | /*#define ESOF_CALLBACK*/ | ||||||
|  | /* CTR service routines */ | ||||||
|  | /* associated to defined endpoints */ | ||||||
|  | /*#define  EP1_IN_Callback   NOP_Process*/ | ||||||
|  | #define  EP2_IN_Callback   NOP_Process | ||||||
|  | #define  EP3_IN_Callback   NOP_Process | ||||||
|  | #define  EP4_IN_Callback   NOP_Process | ||||||
|  | #define  EP5_IN_Callback   NOP_Process | ||||||
|  | #define  EP6_IN_Callback   NOP_Process | ||||||
|  | #define  EP7_IN_Callback   NOP_Process | ||||||
|  | 
 | ||||||
|  | #define  EP1_OUT_Callback   NOP_Process | ||||||
|  | #define  EP2_OUT_Callback   NOP_Process | ||||||
|  | /*#define  EP3_OUT_Callback   NOP_Process*/ | ||||||
|  | #define  EP4_OUT_Callback   NOP_Process | ||||||
|  | #define  EP5_OUT_Callback   NOP_Process | ||||||
|  | #define  EP6_OUT_Callback   NOP_Process | ||||||
|  | #define  EP7_OUT_Callback   NOP_Process | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_CONF_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										46
									
								
								fw_dc22_stm32l100/lib/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								fw_dc22_stm32l100/lib/README
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | 
 | ||||||
|  | This directory is intended for project specific (private) libraries. | ||||||
|  | PlatformIO will compile them to static libraries and link into executable file. | ||||||
|  | 
 | ||||||
|  | The source code of each library should be placed in a an own separate directory | ||||||
|  | ("lib/your_library_name/[here are source files]"). | ||||||
|  | 
 | ||||||
|  | For example, see a structure of the following two libraries `Foo` and `Bar`: | ||||||
|  | 
 | ||||||
|  | |--lib | ||||||
|  | |  | | ||||||
|  | |  |--Bar | ||||||
|  | |  |  |--docs | ||||||
|  | |  |  |--examples | ||||||
|  | |  |  |--src | ||||||
|  | |  |     |- Bar.c | ||||||
|  | |  |     |- Bar.h | ||||||
|  | |  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html | ||||||
|  | |  | | ||||||
|  | |  |--Foo | ||||||
|  | |  |  |- Foo.c | ||||||
|  | |  |  |- Foo.h | ||||||
|  | |  | | ||||||
|  | |  |- README --> THIS FILE | ||||||
|  | | | ||||||
|  | |- platformio.ini | ||||||
|  | |--src | ||||||
|  |    |- main.c | ||||||
|  | 
 | ||||||
|  | and a contents of `src/main.c`: | ||||||
|  | ``` | ||||||
|  | #include <Foo.h> | ||||||
|  | #include <Bar.h> | ||||||
|  | 
 | ||||||
|  | int main (void) | ||||||
|  | { | ||||||
|  |   ... | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | PlatformIO Library Dependency Finder will find automatically dependent | ||||||
|  | libraries scanning project source files. | ||||||
|  | 
 | ||||||
|  | More information about PlatformIO Library Dependency Finder | ||||||
|  | - https://docs.platformio.org/page/librarymanager/ldf.html | ||||||
							
								
								
									
										51
									
								
								fw_dc22_stm32l100/lib/xxtea/src/xxtea.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								fw_dc22_stm32l100/lib/xxtea/src/xxtea.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | /* improved reference xxtea implementation */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define DELTA 0x9e3779b9 | ||||||
|  | #define MX ( (((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(key[(p&3)^e]^z)) ); | ||||||
|  | 
 | ||||||
|  | /* btea usage:
 | ||||||
|  |  * uint32_t *v is the pointer to the data | ||||||
|  |  * int n is word count of v to en/decode. positive to encode, negative to decode | ||||||
|  |  * const key[4] is the 128-bit key | ||||||
|  |  */ | ||||||
|  | void btea(uint32_t *v, int n, uint32_t const key[4]) { | ||||||
|  | 	uint32_t y, z, sum; | ||||||
|  | 	int32_t p, rounds, e; | ||||||
|  | 
 | ||||||
|  | 	if (n > 1) {          /* Coding Part */ | ||||||
|  | 		rounds = 6 + 52/n; | ||||||
|  | 		sum = 0; | ||||||
|  | 		z = v[n-1]; | ||||||
|  | 
 | ||||||
|  | 		do { | ||||||
|  | 			sum += DELTA; | ||||||
|  | 			e = (sum >> 2) & 3; | ||||||
|  | 			for (p = 0; p < n - 1; p++) { | ||||||
|  | 				y = v[p + 1]; | ||||||
|  | 				z = v[p] += MX; | ||||||
|  | 			} | ||||||
|  | 			y = v[0]; | ||||||
|  | 			z = v[n - 1] += MX; | ||||||
|  | 		} while (--rounds); | ||||||
|  | 	} else if (n < -1) {  /* Decoding Part */ | ||||||
|  | 		n = -n; | ||||||
|  | 		rounds = 6 + 52/n; | ||||||
|  | 		sum = rounds * DELTA; | ||||||
|  | 		y = v[0]; | ||||||
|  | 
 | ||||||
|  | 		do { | ||||||
|  | 			e = (sum >> 2) & 3; | ||||||
|  | 			for (p = n - 1; p > 0; p--) { | ||||||
|  | 				z = v[p - 1]; | ||||||
|  | 				y = v[p] -= MX; | ||||||
|  | 			} | ||||||
|  | 			z = v[n - 1]; | ||||||
|  | 			y = v[0] -= MX; | ||||||
|  | 			sum -= DELTA; | ||||||
|  | 		} while (--rounds); | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								fw_dc22_stm32l100/lib/xxtea/src/xxtea.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								fw_dc22_stm32l100/lib/xxtea/src/xxtea.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | /* improved reference xxtea implementation */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void btea(uint32_t *v, int n, uint32_t const key[4]); | ||||||
							
								
								
									
										19
									
								
								fw_dc22_stm32l100/platformio.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								fw_dc22_stm32l100/platformio.ini
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | ; PlatformIO Project Configuration File | ||||||
|  | ; | ||||||
|  | ;   Build options: build flags, source filter | ||||||
|  | ;   Upload options: custom upload port, speed and extra flags | ||||||
|  | ;   Library options: dependencies, extra library storages | ||||||
|  | ;   Advanced options: extra scripting | ||||||
|  | ; | ||||||
|  | ; Please visit documentation for the other options and examples | ||||||
|  | ; https://docs.platformio.org/page/projectconf.html | ||||||
|  | 
 | ||||||
|  | [env:wp_dc22_stm32l] | ||||||
|  | platform = ststm32 | ||||||
|  | board = disco_l152rb | ||||||
|  | framework = spl | ||||||
|  | 
 | ||||||
|  | board_build.mcu = stm32l100rbt6 | ||||||
|  | board_build.f_cpu = 32000000L | ||||||
|  | 
 | ||||||
|  | build_flags = -DPDLIB_SPI | ||||||
							
								
								
									
										182
									
								
								fw_dc22_stm32l100/src/device/attiny.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								fw_dc22_stm32l100/src/device/attiny.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,182 @@ | |||||||
|  | /**
 | ||||||
|  |  * attiny.c: interface to attiny88's features | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: attiny.c 375 2015-07-06 02:52:40Z true $ | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * attiny88's I2C address is 0x73 - see led_eyes.h for define | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> 	// for settings | ||||||
|  | 
 | ||||||
|  | #include "attiny.h" | ||||||
|  | #include "../interface/i2c.h" | ||||||
|  | #include "../interface/gpio.h" | ||||||
|  | #include "../device/lightsensor.h" | ||||||
|  | 
 | ||||||
|  |   // led mode
 | ||||||
|  | static uint8_t led_eyes_mode; | ||||||
|  | 
 | ||||||
|  |   // led brightness
 | ||||||
|  | static uint8_t led_level[2][4]; | ||||||
|  | 
 | ||||||
|  |   // led programs
 | ||||||
|  | #include "../led/led_eyes_prog.h" | ||||||
|  | static void (*led_program)(); | ||||||
|  | static void (*led_program_list[])() = { | ||||||
|  | 	led_prog_candle_flicker, | ||||||
|  | 	led_prog_candle_flicker_favcolor, | ||||||
|  | 	led_prog_randflasher, | ||||||
|  | 	led_prog_mic_spl, | ||||||
|  | 	led_prog_fader | ||||||
|  | }; | ||||||
|  | const char led_eyes_prog_name[LED_EYES_PROG_COUNT][16] = { | ||||||
|  | 	{"CandleFlicker"}, | ||||||
|  | 	{"Candle+FavColor"}, | ||||||
|  | 	{"RandFlasher"}, | ||||||
|  | 	{"MicSPL"}, | ||||||
|  | 	{"CFader"} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | void attiny_write(uint16_t cmd, void *data, uint8_t bytes) | ||||||
|  | { | ||||||
|  | 	uint8_t cmdlen; | ||||||
|  | 	uint8_t *d; | ||||||
|  | 
 | ||||||
|  | 	cmdlen = (cmd > 0xff) ? 2 : 1; | ||||||
|  | 	d = ((uint8_t *)data); | ||||||
|  | 
 | ||||||
|  | 	if (bytes) { | ||||||
|  | 		I2C_WriteTransfer(ATTINY_I2C_ADDR, d, bytes, cmd, cmdlen); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint32_t attiny_read(uint16_t cmd, uint8_t bytes) | ||||||
|  | { | ||||||
|  | 	uint8_t cmdlen; | ||||||
|  | 	uint8_t fb[4] = {0, 0, 0, 0}; | ||||||
|  | 
 | ||||||
|  | 	cmdlen = (cmd > 0xff) ? 2 : 1; | ||||||
|  | 
 | ||||||
|  | 	if (bytes && bytes <= 4) { | ||||||
|  | 		I2C_ReadTransfer(ATTINY_I2C_ADDR, fb, bytes, cmd, cmdlen); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return fb[0] | fb[1] << 8 | fb[2] << 16 | fb[3] << 24; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t attiny_read_temp() | ||||||
|  | { | ||||||
|  | 	return (uint8_t)attiny_read(ATTINY_CMD_READ_TEMP, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t attiny_read_light_level(uint8_t led_idx) | ||||||
|  | { | ||||||
|  | 	return (uint8_t)attiny_read(ATTINY_CMD_READ_LIGHT + (led_idx & 0x03), 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void attiny_write_light_sensitivity(uint8_t led, uint8_t sensitivity) | ||||||
|  | { | ||||||
|  | 	uint8_t buf[2]; | ||||||
|  | 
 | ||||||
|  | 	buf[0] = led; | ||||||
|  | 	buf[1] = sensitivity; | ||||||
|  | 
 | ||||||
|  | 	attiny_write(ATTINY_CMD_LIGHTSENSOR_SENS, buf, 2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void attiny_sleep() | ||||||
|  | { | ||||||
|  | 	I2C_WriteTransfer(ATTINY_I2C_ADDR, 0, 0, ATTINY_CMD_SLEEP, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* rgbled-related functions */ | ||||||
|  | void led_eyes_tx() | ||||||
|  | { | ||||||
|  | 	uint8_t buf[12]; | ||||||
|  | 	uint16_t scaler; | ||||||
|  | 	uint8_t i, j; | ||||||
|  | 
 | ||||||
|  | 	// build up the packet
 | ||||||
|  | 	i = j = 0; | ||||||
|  | 	while (i < 12) { | ||||||
|  | 		buf[i++] = ATTINY_CMD_LED_LEVEL + j; | ||||||
|  | 
 | ||||||
|  | 		scaler = (settings.led_autoadjust & 0x80) ? lightsensor_get_scalerval(LIGHTSENS_SCALED_EYES) : 256; | ||||||
|  | 		buf[i++] = ((led_level[j >> 2][j % 4]) * scaler) >> 8; | ||||||
|  | 		if (i == 6) { | ||||||
|  | 			j = 4; | ||||||
|  | 		} else { | ||||||
|  | 			j++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// and send it
 | ||||||
|  | 	I2C_WriteTransfer(ATTINY_I2C_ADDR, buf, 12, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_eyes_set_level(uint8_t idx, uint8_t level) | ||||||
|  | { | ||||||
|  | 	led_level[idx >> 2][idx & 0x03] = level; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_eyes_set_mode(uint8_t mode) | ||||||
|  | { | ||||||
|  | 	led_eyes_mode = mode; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_eyes_set_program(uint8_t program_idx, uint8_t init, | ||||||
|  | 		uint16_t wait, uint16_t level, uint32_t offset, uint32_t settings) | ||||||
|  | { | ||||||
|  | 	// we need to be in program mode
 | ||||||
|  | 	led_eyes_set_mode(LED_EYES_MODE_PROGRAM); | ||||||
|  | 	// update the program pointer
 | ||||||
|  | 	led_program = led_program_list[program_idx]; | ||||||
|  | 
 | ||||||
|  | 	// set initial program variables
 | ||||||
|  | 	led_prog_set_wait = wait; | ||||||
|  | 	led_prog_set_level = level; | ||||||
|  | 	led_prog_set_offset = offset; | ||||||
|  | 	led_prog_set_option = settings; | ||||||
|  | 
 | ||||||
|  | 	// is this a new set? if so, initialize program parameters
 | ||||||
|  | 	if (init) { | ||||||
|  | 		uint8_t i; | ||||||
|  | 
 | ||||||
|  | 		led_prog_wait = 0; | ||||||
|  | 		for (i = 0; i < 4; i++) { | ||||||
|  | 			led_prog_state[i] = 0; | ||||||
|  | 			led_prog_work[i] = 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_eyes_mode_update() | ||||||
|  | { | ||||||
|  | 	uint8_t i; | ||||||
|  | 
 | ||||||
|  | 	switch (led_eyes_mode) { | ||||||
|  | 		case LED_EYES_MODE_PROGRAM: { | ||||||
|  | 			// if we have a valid program loaded, run it
 | ||||||
|  | 			if (led_program != NULL) { | ||||||
|  | 				led_program(); | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case LED_EYES_MODE_OFF: { | ||||||
|  | 			led_program = NULL; | ||||||
|  | 			for (i = 0; i < 4; i++) { | ||||||
|  | 				led_level[0][i] = 0; | ||||||
|  | 				led_level[1][i] = 0; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										65
									
								
								fw_dc22_stm32l100/src/device/attiny.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								fw_dc22_stm32l100/src/device/attiny.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | |||||||
|  | /**
 | ||||||
|  |  * attiny.h: interface to attiny88's RGBLED eyes prototypes | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: attiny.h 375 2015-07-06 02:52:40Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_DEV_ATTINY_H | ||||||
|  | #define __PIRATE_DEV_ATTINY_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* interface */ | ||||||
|  | #define ATTINY_I2C_DEV 				I2C1 | ||||||
|  | #define ATTINY_I2C_ADDR 			0x73 | ||||||
|  | 
 | ||||||
|  |   // write register commands, last 4 bits = data, >1 packet
 | ||||||
|  | #define ATTINY_CMD_EXT_CMD 			0x10 		// pkt = ext command (bit[7:4] must NOT == 0)
 | ||||||
|  | #define ATTINY_CMD_LED_LEVEL 		0x20 		// cmd[3:0] = led, pkt = level (0-250)
 | ||||||
|  | #define ATTINY_CMD_TEMP_CAL 		0x30 		// pkt = current temperature
 | ||||||
|  | #define ATTINY_CMD_EEPROM_READ 		0x40 		// pkt = address, read 1 byte after this command
 | ||||||
|  | #define ATTINY_CMD_EEPROM_WRITE 	0x50 		// pkt[0] = address, pkt[1] = data
 | ||||||
|  |   // write register commands, last 4 bits = data, immediate processing 1 packet
 | ||||||
|  | #define ATTINY_CMD_READ_TEMP 		0x80 		// read 1 byte after this command
 | ||||||
|  | #define ATTINY_CMD_READ_LIGHT 		0x90 		// cmd[3:0] = led (from 0-3), read 1 byte after this command
 | ||||||
|  | #define ATTINY_CMD_SLEEP 			0xF0 		// no data
 | ||||||
|  |   // write register commands, extended
 | ||||||
|  | #define ATTINY_CMD_LIGHTSENSOR_SENS 0x1019 		// 2 bytes data - led, new sensitivity value
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* leds */ | ||||||
|  | #define LED_EYES_LEFT 				0 | ||||||
|  | #define LED_EYES_RIGHT 				1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* programs */ | ||||||
|  | #define LED_EYES_MODE_OFF 			0 | ||||||
|  | #define LED_EYES_MODE_PROGRAM 		2 | ||||||
|  | 
 | ||||||
|  | #define LED_EYES_PROG_COUNT 		5 | ||||||
|  | #define LED_EYES_PTRN_COUNT 		0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void led_eyes_tx(); | ||||||
|  | void led_eyes_set_level(uint8_t idx, uint8_t level); | ||||||
|  | 
 | ||||||
|  | void led_eyes_mode_update(); | ||||||
|  | void led_eyes_set_mode(uint8_t mode); 	// used for disabling
 | ||||||
|  | void led_eyes_set_program(uint8_t program_idx, uint8_t init, | ||||||
|  | 		uint16_t wait, uint16_t level, uint32_t offset, uint32_t settings); | ||||||
|  | 
 | ||||||
|  | uint8_t attiny_read_temp(); | ||||||
|  | uint8_t attiny_read_light_level(uint8_t led_idx); | ||||||
|  | 
 | ||||||
|  | void attiny_write_light_sensitivity(uint8_t led, uint8_t sensitivity); | ||||||
|  | 
 | ||||||
|  | void attiny_sleep(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										118
									
								
								fw_dc22_stm32l100/src/device/beep.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								fw_dc22_stm32l100/src/device/beep.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | |||||||
|  | /**
 | ||||||
|  |  * beep.c: beeper fuckin musicality bitches, beep buzz boop | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: beep.c 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * TODO: remove freq lookup table, replace with freq defines by note (A4 = 440 for example) | ||||||
|  |  * TODO: let you know that the device we chose cannot play music; it is a buzzer. | ||||||
|  |  * TODO: do what you want 'cause a pirate is free | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "beep.h" | ||||||
|  | #include "../interface/gpio.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const tGPIO beep_pin = {GPIOA, GPIO_Pin_4, 4}; | ||||||
|  | 
 | ||||||
|  | uint8_t  beep_buf_idx; | ||||||
|  | uint8_t  beep_play_idx; | ||||||
|  | uint16_t beep_dur_buf[BEEP_BUF_SIZE]; | ||||||
|  | uint16_t beep_lev_buf[BEEP_BUF_SIZE]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* beeper bullshit */ | ||||||
|  | void beep_init() | ||||||
|  | { | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 
 | ||||||
|  | 	// set up beeper gpio struct
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_OUT; | ||||||
|  | 	gpio.GPIO_OType = GPIO_OType_PP; | ||||||
|  | 	gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; | ||||||
|  | 	gpio.GPIO_Speed = GPIO_Speed_400KHz; | ||||||
|  | 	gpio.GPIO_Pin = beep_pin.pin; | ||||||
|  | 
 | ||||||
|  | 	// and set it up
 | ||||||
|  | 	GPIO_Init(beep_pin.port, &gpio); | ||||||
|  | 
 | ||||||
|  | 	// reset buffer index
 | ||||||
|  | 	beep_buf_idx = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void beep_update() | ||||||
|  | { | ||||||
|  | 	uint16_t duration; | ||||||
|  | 	uint16_t level; | ||||||
|  | 
 | ||||||
|  | 	// do we have an active tone?
 | ||||||
|  | 	if (beep_buf_idx & 0x80) { | ||||||
|  | 		duration = beep_dur_buf[beep_play_idx]; | ||||||
|  | 		level = beep_lev_buf[beep_play_idx]; | ||||||
|  | 
 | ||||||
|  | 		if (duration) { | ||||||
|  | 			if (level == 0) { 						// loudest
 | ||||||
|  | 				GPIO_SetBits(beep_pin.port, beep_pin.pin); | ||||||
|  | 			} else if (level == 32) { 				// silent
 | ||||||
|  | 				GPIO_ResetBits(beep_pin.port, beep_pin.pin); | ||||||
|  | 			} else if (duration % level == 0) { 	// tones
 | ||||||
|  | 				GPIO_SetBits(beep_pin.port, beep_pin.pin); | ||||||
|  | 			} else { | ||||||
|  | 				GPIO_ResetBits(beep_pin.port, beep_pin.pin); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// count down the times
 | ||||||
|  | 			beep_dur_buf[beep_play_idx]--; | ||||||
|  | 		} else { | ||||||
|  | 			// stop the tone
 | ||||||
|  | 			GPIO_ResetBits(beep_pin.port, beep_pin.pin); | ||||||
|  | 
 | ||||||
|  | 			// move to the next buffer
 | ||||||
|  | 			beep_play_idx++; | ||||||
|  | 
 | ||||||
|  | 			// is there any more? need to reset buffer if there isn't any more
 | ||||||
|  | 			if (((beep_buf_idx & 0x7f) == beep_play_idx) || beep_play_idx >= BEEP_BUF_SIZE) { | ||||||
|  | 				// nope, no more
 | ||||||
|  | 				beep_buf_idx = 0; | ||||||
|  | 				beep_play_idx = 0; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* beep control */ | ||||||
|  | void beep_clear_queue() | ||||||
|  | { | ||||||
|  | 	beep_buf_idx = 0; | ||||||
|  | 	GPIO_ResetBits(beep_pin.port, beep_pin.pin); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint16_t beep(uint16_t tone_id, uint16_t duration) | ||||||
|  | { | ||||||
|  | 	if ((beep_buf_idx & 0x7f) < BEEP_BUF_SIZE) { | ||||||
|  | 		// if not in use, reset the playback index
 | ||||||
|  | 		if (beep_buf_idx == 0) { | ||||||
|  | 			beep_play_idx = 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// mark the beeper as being used
 | ||||||
|  | 		beep_buf_idx |= 0x80; | ||||||
|  | 
 | ||||||
|  | 		// set the desired tone and duration
 | ||||||
|  | 		beep_lev_buf[beep_buf_idx & 0x7f] = (tone_id < 32) ? 32 - tone_id : 0; | ||||||
|  | 		beep_dur_buf[beep_buf_idx & 0x7f] = duration * 5; | ||||||
|  | 
 | ||||||
|  | 		// prepare for the next buffer location
 | ||||||
|  | 		beep_buf_idx++; | ||||||
|  | 
 | ||||||
|  | 		return (beep_buf_idx & 0x7f); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0xff; | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								fw_dc22_stm32l100/src/device/beep.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								fw_dc22_stm32l100/src/device/beep.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | /**
 | ||||||
|  |  * beep.h: beeper fuckin musicality bitches | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: beep.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  |  * do what you want 'cause a pirate is free | ||||||
|  |  * you are a pirate | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_DEV_BEEP_H | ||||||
|  | #define __PIRATE_DEV_BEEP_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* constants */ | ||||||
|  | #define BEEP_BUF_SIZE 			8 		// max 127
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void beep_init(); | ||||||
|  | void beep_update(); | ||||||
|  | 
 | ||||||
|  | void beep_clear_queue(); | ||||||
|  | uint16_t beep(uint16_t tone_id, uint16_t duration); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										30
									
								
								fw_dc22_stm32l100/src/device/beep_song.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								fw_dc22_stm32l100/src/device/beep_song.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | /**
 | ||||||
|  |  * beep_music.h: musical scores for pirates | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: beep_song.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | static MusicSong you_are_a_pirate[] = { | ||||||
|  | 		{5, NOTE_E, 200}, | ||||||
|  | 		{5, NOTE_C, 200}, | ||||||
|  | 		{5, NOTE_C, 200}, | ||||||
|  | 		{5, NOTE_C, 200}, | ||||||
|  | 		{4, NOTE_G, 200}, | ||||||
|  | 		{4, NOTE_A, 200}, | ||||||
|  | 		{5, NOTE_C, 200}, | ||||||
|  | 		{4, NOTE_B, 200}, | ||||||
|  | 		{4, NOTE_D, 200}, | ||||||
|  | 		{4, NOTE_A, 250}, | ||||||
|  | 		{0, NOTE_NONE, 350}, | ||||||
|  | 		{4, NOTE_G, 600}, | ||||||
|  | 		{5, NOTE_C, 600}, | ||||||
|  | 		{5, NOTE_C, 200}, | ||||||
|  | 		{5, NOTE_D, 360}, | ||||||
|  | 		{4, NOTE_A, 360} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static MusicPlaylist you_are_a_pirate_s = {you_are_a_pirate, 16}; | ||||||
							
								
								
									
										225
									
								
								fw_dc22_stm32l100/src/device/lcd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								fw_dc22_stm32l100/src/device/lcd.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,225 @@ | |||||||
|  | /**
 | ||||||
|  |  * lcd.c: lcd menuing and support functions | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: lcd.c 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "lcd.h" | ||||||
|  | 
 | ||||||
|  | #include "../interface/i2c.h" | ||||||
|  | #include "../interface/gpio.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // led backlight
 | ||||||
|  | uint16_t lcd_led_level = 0; | ||||||
|  | uint16_t lcd_led_level_set = 0; | ||||||
|  | uint8_t lcd_led_rate; | ||||||
|  | uint8_t lcd_led_upd; | ||||||
|  | 
 | ||||||
|  |   // lcd control
 | ||||||
|  | uint8_t lcd_height; | ||||||
|  | uint8_t lcd_cursor_pos; | ||||||
|  | uint8_t lcd_cursor_type; | ||||||
|  | uint8_t (*lcd_cgram)[8]; | ||||||
|  | uint8_t lcd_cgram_len; | ||||||
|  | 
 | ||||||
|  |   // lcd display
 | ||||||
|  | char lcd_line[2][9]; | ||||||
|  | 
 | ||||||
|  |   // lcd hardware
 | ||||||
|  | const tGPIO lcd_led_pin = {GPIOA, GPIO_Pin_6, 6}; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | void lcd_init() | ||||||
|  | { | ||||||
|  | 	static const uint8_t cmd_init[] = { | ||||||
|  | 		0x38, 	// set to i2c
 | ||||||
|  | 		0x39, 	// set to i2c
 | ||||||
|  | 		0x1d, 	// 1/4 bias, osc ~220hz
 | ||||||
|  | 		0x78, 	// contrast low 4 bits
 | ||||||
|  | 		0x5d, 	// icon enable, voltage boost enable, contrast high 2 bits
 | ||||||
|  | 		0x6d, 	// internal follower enable,
 | ||||||
|  | 		0x0c, 	// display on
 | ||||||
|  | 		0x01, 	// clear display
 | ||||||
|  | 		0x06 	//
 | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	uint8_t *cmdptr = (uint8_t *)cmd_init; | ||||||
|  | 
 | ||||||
|  | 	I2C_WriteTransfer(LCD_I2C_ADDR, cmdptr, 9, LCD_CMD, 1); | ||||||
|  | 
 | ||||||
|  | 	// set stored contrast
 | ||||||
|  | 	lcd_set_contrast(settings.contrast); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_led_init() | ||||||
|  | { | ||||||
|  | 	TIM_TimeBaseInitTypeDef tim_tb; | ||||||
|  | 	TIM_OCInitTypeDef tim_oc; | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 
 | ||||||
|  | 	// enable clocks
 | ||||||
|  | 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// set up with 250 levels of brightness, with a bit of empty
 | ||||||
|  | 	tim_tb.TIM_Prescaler = 5 - 1; 		// 6.4MHz
 | ||||||
|  | 	tim_tb.TIM_Period = 320 - 1; 		// 25KHz PWM
 | ||||||
|  | 	tim_tb.TIM_ClockDivision = 0; | ||||||
|  | 	tim_tb.TIM_CounterMode = TIM_CounterMode_Up; | ||||||
|  | 	TIM_TimeBaseInit(LCD_LED_TIMER, &tim_tb); | ||||||
|  | 
 | ||||||
|  | 	// configure outputs as pwm
 | ||||||
|  | 	tim_oc.TIM_OCMode = TIM_OCMode_PWM1; | ||||||
|  | 	tim_oc.TIM_OutputState = TIM_OutputState_Enable; | ||||||
|  | 	tim_oc.TIM_Pulse = 0; | ||||||
|  | 	tim_oc.TIM_OCPolarity = LCD_LED_OC_POLARITY; | ||||||
|  | 	TIM_OC1Init(LCD_LED_TIMER, &tim_oc); | ||||||
|  | 	TIM_OC1PreloadConfig(LCD_LED_TIMER, TIM_OCPreload_Enable); | ||||||
|  | 
 | ||||||
|  | 	TIM_ARRPreloadConfig(LCD_LED_TIMER, ENABLE); | ||||||
|  | 	TIM_Cmd(LCD_LED_TIMER, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// configure output pin as timer AF
 | ||||||
|  | 	GPIO_StructInit(&gpio); | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_AF; | ||||||
|  | 	gpio.GPIO_Speed = GPIO_Speed_2MHz; | ||||||
|  | 	gpio.GPIO_Pin = lcd_led_pin.pin; | ||||||
|  | 	GPIO_Init(lcd_led_pin.port, &gpio); | ||||||
|  | 
 | ||||||
|  | 	GPIO_PinAFConfig(lcd_led_pin.port, lcd_led_pin.pinsource, GPIO_AF_TIM10); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_print(uint8_t pos, uint8_t *msg, uint8_t msg_len) | ||||||
|  | { | ||||||
|  | 	uint8_t len; | ||||||
|  | 
 | ||||||
|  | 	// which line/pos to print to?
 | ||||||
|  | 	I2C_WriteTransfer(LCD_I2C_ADDR, &pos, 1, LCD_CMD, 1); | ||||||
|  | 
 | ||||||
|  | 	// length to print
 | ||||||
|  | 	len = msg_len < LCD_MAX_LINE_LENGTH ? msg_len : LCD_MAX_LINE_LENGTH; | ||||||
|  | 
 | ||||||
|  | 	// send it
 | ||||||
|  | 	I2C_WriteTransfer(LCD_I2C_ADDR, msg, len, LCD_DATA, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_linebuf_send() | ||||||
|  | { | ||||||
|  | 	lcd_print(LCD_LINE_1, (uint8_t *)lcd_line[0], 8); | ||||||
|  | 
 | ||||||
|  | 	if (lcd_get_height() != LCD_CMD_DOUBLEHEIGHT) { | ||||||
|  | 		lcd_print(LCD_LINE_2, (uint8_t *)lcd_line[1], 8); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void lcd_cmd(uint8_t cmd) | ||||||
|  | { | ||||||
|  | 	I2C_WriteTransfer(LCD_I2C_ADDR, &cmd, 1, LCD_CMD, 1); | ||||||
|  | 	// pirate_delay(1);
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_set_contrast(uint8_t level) { | ||||||
|  | 	settings.contrast = level & 0x3f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_apply_contrast() | ||||||
|  | { | ||||||
|  | 	// contrast is 6 bits; can be between 0 and 63
 | ||||||
|  | 	uint8_t cmd[2] = {0}; | ||||||
|  | 
 | ||||||
|  | 	// form command
 | ||||||
|  | 	cmd[0] = 0x5c | (settings.contrast >> 4); | ||||||
|  | 	cmd[1] = 0x70 | (settings.contrast & 0x0f); | ||||||
|  | 
 | ||||||
|  | 	I2C_WriteTransfer(LCD_I2C_ADDR, cmd, 2, LCD_CMD, 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_set_height(uint8_t height) | ||||||
|  | { | ||||||
|  | 	if (height) | ||||||
|  | 		lcd_height = height; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t lcd_get_height() | ||||||
|  | { | ||||||
|  | 	return lcd_height; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_set_cursor(uint8_t pos, uint8_t type) | ||||||
|  | { | ||||||
|  | 	if (pos) | ||||||
|  | 		lcd_cursor_pos = pos; | ||||||
|  | 
 | ||||||
|  | 	if (type) | ||||||
|  | 		lcd_cursor_type = type; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t lcd_get_cursor_pos() | ||||||
|  | { | ||||||
|  | 	return lcd_cursor_pos; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t lcd_get_cursor_type() | ||||||
|  | { | ||||||
|  | 	return lcd_cursor_type; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_set_cgram_load(const uint8_t (*cgram)[8], const uint8_t len) | ||||||
|  | { | ||||||
|  | 	lcd_cgram = (uint8_t (*)[8])cgram; | ||||||
|  | 	lcd_cgram_len = (uint8_t)len; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_led_set_level(uint8_t level, uint8_t ramp_speed) | ||||||
|  | { | ||||||
|  | 	lcd_led_level_set = level; | ||||||
|  | 	lcd_led_rate = ramp_speed; | ||||||
|  | 	lcd_led_upd = LCD_LED_UPD_RATE; | ||||||
|  | 
 | ||||||
|  | 	// force an update now
 | ||||||
|  | 	lcd_led_update(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_led_update() | ||||||
|  | { | ||||||
|  | 	if (lcd_led_upd) { | ||||||
|  | 		lcd_led_upd--; | ||||||
|  | 		if (!lcd_led_upd) { | ||||||
|  | 			// are we done?
 | ||||||
|  | 			if (lcd_led_level == lcd_led_level_set) { | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 			// nope, check and see if we are increasing level
 | ||||||
|  | 			if (lcd_led_level_set > lcd_led_level) { | ||||||
|  | 				lcd_led_level += lcd_led_rate; | ||||||
|  | 				// level higher than target? then force to target
 | ||||||
|  | 				if (lcd_led_level > lcd_led_level_set) { | ||||||
|  | 					lcd_led_level = lcd_led_level_set; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			// nope, check and see if we are decreasing level
 | ||||||
|  | 			if (lcd_led_level_set < lcd_led_level) { | ||||||
|  | 				// rate lower than target? if so, force to target
 | ||||||
|  | 				if ((lcd_led_level - lcd_led_level_set) > lcd_led_rate) { | ||||||
|  | 					lcd_led_level = lcd_led_level_set; | ||||||
|  | 				} else { | ||||||
|  | 					lcd_led_level -= lcd_led_rate; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// set OC
 | ||||||
|  | 			LCD_LED_TIMER->CCR1 = lcd_led_level; | ||||||
|  | 
 | ||||||
|  | 			// and reset countdown timer
 | ||||||
|  | 			lcd_led_upd = LCD_LED_UPD_RATE; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										72
									
								
								fw_dc22_stm32l100/src/device/lcd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								fw_dc22_stm32l100/src/device/lcd.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | |||||||
|  | /**
 | ||||||
|  |  * lcd.c: lcd menuing and support function prototypes | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: lcd.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_DEV_LCD_H | ||||||
|  | #define __PIRATE_DEV_LCD_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define LCD_I2C_DEV 				I2C1 | ||||||
|  | #define LCD_I2C_ADDR 				0x3e | ||||||
|  | 
 | ||||||
|  | #define LCD_MAX_LINE_LENGTH 		8 		// we use an 8x2 LCD in this project
 | ||||||
|  | 
 | ||||||
|  | #define LCD_LED_TIMER 				TIM10 | ||||||
|  | #define LCD_LED_OC_POLARITY 		TIM_OCPolarity_High | ||||||
|  | #define LCD_LED_UPD_RATE 			100 	// updates every 5000/100 = 50ms update rate
 | ||||||
|  | 
 | ||||||
|  | #define LCD_LINE_1 					0x80 | ||||||
|  | #define LCD_LINE_2 					0xc0 | ||||||
|  | 
 | ||||||
|  | #define LCD_CMD 					0x00 | ||||||
|  | #define LCD_DATA 					0x40 | ||||||
|  | 
 | ||||||
|  | #define LCD_CMD_CLEAR_SCREEN 		0x01 | ||||||
|  | #define LCD_CMD_SINGLEHEIGHT 		0x39 | ||||||
|  | #define LCD_CMD_DOUBLEHEIGHT 		0x35 | ||||||
|  | #define LCD_CMD_NO_CURSOR_FLASH		0x0c | ||||||
|  | #define LCD_CMD_CURSOR_FLASH 		0x0d | ||||||
|  | #define LCD_CMD_CURSOR_UNDER 		0x0e | ||||||
|  | #define LCD_CMD_CURSOR_UNDER_FLASH 	0x0f | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* variables */ | ||||||
|  | extern char lcd_line[2][9]; | ||||||
|  | 
 | ||||||
|  | extern uint8_t (*lcd_cgram)[8]; | ||||||
|  | extern uint8_t lcd_cgram_len; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void lcd_init(); | ||||||
|  | void lcd_led_init(); | ||||||
|  | 
 | ||||||
|  | void lcd_cmd(uint8_t command); | ||||||
|  | void lcd_print(uint8_t pos, uint8_t *msg, uint8_t msg_len); | ||||||
|  | void lcd_linebuf_send(); | ||||||
|  | 
 | ||||||
|  | void lcd_set_contrast(uint8_t level); | ||||||
|  | void lcd_apply_contrast(); | ||||||
|  | 
 | ||||||
|  | void lcd_set_height(uint8_t height); | ||||||
|  | uint8_t lcd_get_height(); | ||||||
|  | 
 | ||||||
|  | void lcd_set_cursor(uint8_t pos, uint8_t type); | ||||||
|  | uint8_t lcd_get_cursor_pos(); | ||||||
|  | uint8_t lcd_get_cursor_type(); | ||||||
|  | 
 | ||||||
|  | void lcd_set_cgram_load(const uint8_t (*cgram)[8], const uint8_t len); | ||||||
|  | 
 | ||||||
|  | void lcd_led_set_level(uint8_t level, uint8_t ramp_speed); | ||||||
|  | void lcd_led_update(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										110
									
								
								fw_dc22_stm32l100/src/device/lightsensor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								fw_dc22_stm32l100/src/device/lightsensor.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | |||||||
|  | /**
 | ||||||
|  |  * lightsensor.c: control of the attiny's light sensor output plus helper functions | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: lightsensor.c 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "lightsensor.h" | ||||||
|  | #include "attiny.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // light variables
 | ||||||
|  | uint8_t light_level; | ||||||
|  | uint8_t light_gain; | ||||||
|  | 
 | ||||||
|  | static uint8_t wait = 0; | ||||||
|  | 
 | ||||||
|  |   // target brightness
 | ||||||
|  |   // TODO: make this adjustable?
 | ||||||
|  | static uint8_t lev_target[5][5] = { | ||||||
|  | 		{0x00, 0xff, 0xe0, 0x55, 0x0d}, 	// skull (white)
 | ||||||
|  | 		{0x00, 0x38, 0xff, 0xff, 0xff}, 	// skull (purple)
 | ||||||
|  | 		{0x00, 0xff, 0xe0, 0x55, 0x0d}, 	// bones
 | ||||||
|  | 		{0xff, 0xff, 0xf0, 0xe0, 0xc0}, 	// eyes
 | ||||||
|  | 		{0x00, 0xff, 0xe0, 0x55, 0x14} 		// backlight
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static uint8_t lev_set[5]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  |   // gain
 | ||||||
|  | uint8_t lightsensor_gainvalue_update() | ||||||
|  | { | ||||||
|  | 	if (light_level <= settings.led_autogain_lev_min) { | ||||||
|  | 		if (light_gain > LIGHTSENS_GAIN_MIN) { | ||||||
|  | 			light_gain--; | ||||||
|  | 			return 1; | ||||||
|  | 		} | ||||||
|  | 	} else if (light_level >= settings.led_autogain_lev_max) { | ||||||
|  | 		if (light_gain < LIGHTSENS_GAIN_MAX) { | ||||||
|  | 			light_gain++; | ||||||
|  | 			return 2; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |   // scaling
 | ||||||
|  | void lightsensor_scale_level(uint8_t idx) | ||||||
|  | { | ||||||
|  | 	int16_t scaled = 0; | ||||||
|  | 	uint8_t i = 5; | ||||||
|  | 
 | ||||||
|  | 	if (light_gain) { | ||||||
|  | 		if (light_gain == settings.led_autothresh[0]) { | ||||||
|  | 			scaled = lev_target[idx][0]; | ||||||
|  | 			i = 1; | ||||||
|  | 		} else { | ||||||
|  | 			for (i = 1; i < 5; i++) { | ||||||
|  | 				if (light_gain <= settings.led_autothresh[i]) { | ||||||
|  | 					scaled = pirate_scale(light_gain, | ||||||
|  | 							settings.led_autothresh[i - 1], | ||||||
|  | 							settings.led_autothresh[i], | ||||||
|  | 							lev_target[idx][i - 1], | ||||||
|  | 							lev_target[idx][i]); | ||||||
|  | 
 | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (i < 5) { | ||||||
|  | 			if (lev_set[idx] > scaled) { | ||||||
|  | 				lev_set[idx]--; | ||||||
|  | 			} else if (lev_set[idx] < scaled) { | ||||||
|  | 				lev_set[idx]++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lightsensor_scaler_update() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	if (!wait) { | ||||||
|  | 		wait = settings.led_autoadjust & 0x7f; | ||||||
|  | 
 | ||||||
|  | 		for (i = 0; i < 5; i++) { | ||||||
|  | 			lightsensor_scale_level(i); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// if the scaling speed isn't set, set it fast
 | ||||||
|  | 		if (!wait) wait = 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	wait--; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t lightsensor_get_scalerval(uint8_t which) | ||||||
|  | { | ||||||
|  | 	if (which <= LIGHTSENS_SCALED_BACKLIGHT) return lev_set[which]; else return 0; | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								fw_dc22_stm32l100/src/device/lightsensor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								fw_dc22_stm32l100/src/device/lightsensor.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | /**
 | ||||||
|  |  * lightsensor.h: control of the attiny's light sensor output plus helper functions | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: lightsensor.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_DEV_LIGHTSENSOR_H | ||||||
|  | #define __PIRATE_DEV_LIGHTSENSOR_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | extern uint8_t light_level; | ||||||
|  | extern uint8_t light_gain; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define LIGHTSENS_GAIN_MIN 				1 		// brightest
 | ||||||
|  | #define LIGHTSENS_GAIN_MAX  			64 		// darkest
 | ||||||
|  | 
 | ||||||
|  | #define LIGHTSENS_AUTOGAIN_LEVEL_MIN 	108		// threshold levels for gain
 | ||||||
|  | #define LIGHTSENS_AUTOGAIN_LEVEL_MAX 	114 	// should be a range of ~6-10
 | ||||||
|  | 
 | ||||||
|  | #define LIGHTSENS_THRESH_DAY			1 | ||||||
|  | #define LIGHTSENS_THRESH_TOP_BRIGHT		4 | ||||||
|  | #define LIGHTSENS_THRESH_TOP_NORM		30 | ||||||
|  | #define LIGHTSENS_THRESH_TOP_DIM 		48 | ||||||
|  | #define LIGHTSENS_THRESH_TOP_DARK 		64 | ||||||
|  | 
 | ||||||
|  | #define LIGHTSENS_SCALED_SKULL_WHT 		0 | ||||||
|  | #define LIGHTSENS_SCALED_SKULL_PUR 		1 | ||||||
|  | #define LIGHTSENS_SCALED_BONES	 		2 | ||||||
|  | #define LIGHTSENS_SCALED_EYES 			3 | ||||||
|  | #define LIGHTSENS_SCALED_BACKLIGHT 		4 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | uint8_t lightsensor_gainvalue_update(); | ||||||
|  | 
 | ||||||
|  | void lightsensor_scaler_update(); | ||||||
|  | uint8_t lightsensor_get_scalerval(uint8_t which); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										10
									
								
								fw_dc22_stm32l100/src/device/radio/address.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								fw_dc22_stm32l100/src/device/radio/address.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | /**
 | ||||||
|  |  * radio/address.c: address buffers and lookups | ||||||
|  |  * 2015 by true | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | static char dc22_name[32][8]; | ||||||
|  | static char dc23_name[300][3]; | ||||||
							
								
								
									
										7
									
								
								fw_dc22_stm32l100/src/device/radio/address.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								fw_dc22_stm32l100/src/device/radio/address.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | /**
 | ||||||
|  |  * radio/address.h: address buffers and lookups | ||||||
|  |  * 2015 by true | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
							
								
								
									
										15
									
								
								fw_dc22_stm32l100/src/device/radio/irq.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								fw_dc22_stm32l100/src/device/radio/irq.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | /**
 | ||||||
|  |  * radio/irq.c: nrf irq handler | ||||||
|  |  * 2015 by true | ||||||
|  | 
 | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | #include "nrf.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										142
									
								
								fw_dc22_stm32l100/src/device/radio/nrf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								fw_dc22_stm32l100/src/device/radio/nrf.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | |||||||
|  | /**
 | ||||||
|  |  * radio/nrf.c: interface to radiowaves | ||||||
|  |  * 2015 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * This is a nasty hack implementation of the NRF24L01+. | ||||||
|  |  * Modify as necessary if using on another STM32; see nrf.h | ||||||
|  |  *   and the NRF24L01 library. | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: nrf.c 375 2015-07-06 02:52:40Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | #include "nrf.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* variables */ | ||||||
|  |   // general radio
 | ||||||
|  | uint8_t nrf_detected; | ||||||
|  | uint8_t nrf_myaddr; | ||||||
|  | 
 | ||||||
|  | static uint8_t nrf_tx_addr[5] = {0x00, '8', 'r', 'i', 'P'}; | ||||||
|  | uint8_t nrf_tx_buf[NRF_PAYLOAD_LEN]; | ||||||
|  | 
 | ||||||
|  | static uint8_t nrf_rx_addr_p0[5] = {0x00, '8', 'r', 'i', 'P'}; | ||||||
|  | static uint8_t nrf_rx_addr_p1[5] = {0x01, '8', 'r', 'i', 'P'}; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // pingpong
 | ||||||
|  | uint8_t nrf_last_ping_id; 	// sender's last byte
 | ||||||
|  | uint8_t nrf_last_ping_idx; 	// index byte
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // encryption
 | ||||||
|  | static uint32_t xxtea_key[2][4]; | ||||||
|  | static uint8_t xxtea_key_done[2]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | uint8_t nrf_checksum(uint8_t *data, uint8_t len, int32_t offset) { | ||||||
|  | 	int32_t ret = 0; | ||||||
|  | 
 | ||||||
|  | 	while (len) { | ||||||
|  | 		ret += *data++; | ||||||
|  | 		len--; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return (ret + offset); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nrf_process_data(uint8_t pipe, uint8_t *pBuf, uint8_t len) | ||||||
|  | { | ||||||
|  | 	int32_t w = 0; | ||||||
|  | 
 | ||||||
|  | 	if (len != NRF_PAYLOAD_LEN) return; | ||||||
|  | 
 | ||||||
|  | 	// first see if there are any unencrypted commands
 | ||||||
|  | 	// TODO: verify checksum to see if packet is valid
 | ||||||
|  | 	switch (pBuf[0]) { | ||||||
|  | 		case NRF_CMD_GETKEY: { | ||||||
|  | 			// check to see if the message is formatted correctly
 | ||||||
|  | 			// we will oblige and send out the keys we have
 | ||||||
|  | 			// TODO: send key
 | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case NRF_CMD_SETKEY: { | ||||||
|  | 			// check to see if the message is formatted correctly
 | ||||||
|  | 			// we are a DC22 badge, so we have the keys already
 | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case NRF_CMD_PING: { | ||||||
|  | 			// get received address for this packet
 | ||||||
|  | 			nrf_last_ping_id = pipe; | ||||||
|  | 
 | ||||||
|  | 			// and pull the index
 | ||||||
|  | 			nrf_last_ping_idx = pBuf[2]; | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// decode with dc22 public key and see if checksum matches
 | ||||||
|  | 	if (xxtea_key_done[0]) { | ||||||
|  | 		btea((uint32_t *)pBuf, -2, xxtea_key[0]); | ||||||
|  | 		if (!nrf_checksum(pBuf, 7, pBuf[7])) { | ||||||
|  | 			w = 22; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// decode with dc22 shared key and see if it matches
 | ||||||
|  | 	if (xxtea_key_done[1] && !w) { | ||||||
|  | 		btea((uint32_t *)pBuf, -2, xxtea_key[1]); | ||||||
|  | 		if (!nrf_checksum(pBuf, 7, pBuf[7])) { | ||||||
|  | 			w = 23; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// try to process this data
 | ||||||
|  | 	if (w) { | ||||||
|  | 		// yes, we can
 | ||||||
|  | 		// TODO: process radio data
 | ||||||
|  | 		switch (pBuf[0]) { | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nrf_init() | ||||||
|  | { | ||||||
|  | 	// initialize nRF24 library
 | ||||||
|  | 	nRF24_init(SystemCoreClock); | ||||||
|  | 	// clear any pending interrupts, we don't give a shit about them
 | ||||||
|  | 	nRF24_clear_irq_flags(); | ||||||
|  | 
 | ||||||
|  | 	// set nrf data callbacks
 | ||||||
|  | 	nRF24_rx_cb = nrf_process_data; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	nrf_myaddr = *(uint8_t *)NRF_MYADDR_EEPROM; | ||||||
|  | 
 | ||||||
|  | 	nrf_detected = 0; | ||||||
|  | 	if (nRF24_is_present()) { | ||||||
|  | 		nrf_detected = 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// and finally, configure the radio and turn it on in listen mode
 | ||||||
|  | 	nRF24_set_payload_size(0, NRF_PAYLOAD_LEN); | ||||||
|  | 	nRF24_set_payload_size(1, NRF_PAYLOAD_LEN); | ||||||
|  | 	nRF24_set_autoack(1, 0); 	// no autoack on general receive pipe
 | ||||||
|  | 	nRF24_set_dynack(1); 		// allows us to NO_ACK packets
 | ||||||
|  | 	nRF24_update_config(_TRNRF_UPDATE_ALL); | ||||||
|  | 
 | ||||||
|  | 	nRF24_set_txaddr(nrf_tx_addr); | ||||||
|  | 	nRF24_set_rxaddr(0, nrf_rx_addr_p0); | ||||||
|  | 	nRF24_set_rxaddr(1, nrf_rx_addr_p1); | ||||||
|  | 
 | ||||||
|  | 	nRF24_mode_rx(); | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								fw_dc22_stm32l100/src/device/radio/nrf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								fw_dc22_stm32l100/src/device/radio/nrf.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | /**
 | ||||||
|  |  * radio/nrf.h: interface to radiowaves prototypes | ||||||
|  |  * 2015 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: nrf.h 505 2021-09-05 19:07:51Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_DEV_NRF24L01_H | ||||||
|  | #define __PIRATE_DEV_NRF24L01_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* libraries */ | ||||||
|  | #include "nrf24l01/true_nRF24L01.h" | ||||||
|  | #include <xxtea.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* defines */ | ||||||
|  | #define NRF_PAYLOAD_LEN 		8 		// 1 byte command, 1 byte class, 1 byte byte index, 4 bytes data, 1 byte checksum
 | ||||||
|  | #define NRF_MYADDR_EEPROM 		(uint32_t)0x080807fc 	// 4 bytes, only using highest byte right now
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* commands (main channel) */ | ||||||
|  | #define NRF_CMD_GETKEY 			0x00 	// TODO: devices query for a key until they get one
 | ||||||
|  | #define NRF_CMD_SETKEY 			0x01 	// TODO: sends a key for devices to use
 | ||||||
|  | #define NRF_CMD_REQ_SUBADDR 	0x08 	// TODO: asks for subaddress in use
 | ||||||
|  | #define NRF_CMD_PAGEDC22 		0x19 	// TODO: pages a dc22-style badge, index is block num, 3 blocks to send, 8 char name, 4 char nonce. index >=0x80 = direct
 | ||||||
|  | #define NRF_CMD_PAGEDC23 		0x1a 	// TODO: pages a dc23-style badge, index is block num, 2 blocks to send, 3 char name, 4 char nonce. index >=0x80 = direct
 | ||||||
|  | #define NRF_CMD_MUSICNOTES 		0x40 	// TODO: queues and plays the desired music notes. 2 bytes per note, one for note to play (or start play cmd), one for duration of note
 | ||||||
|  | #define NRF_CMD_MUSICLIBRARY 	0x42 	// TODO: queues playing a song from the music library. if index = 0xff, badges will repeat with countdown information.
 | ||||||
|  | #define NRF_CMD_ANIMATION 		0x8D | ||||||
|  | #define NRF_CMD_DC22_23GREET 	0x8F | ||||||
|  | #define NRF_CMD_PING 			0x91 	// TODO: sends ping. dest waits the amount of milliseconds of its ID times two before responding. index is this badge's P1
 | ||||||
|  | #define NRF_CMD_PONG 			0x92 	// TODO: reply sent to target in response to ping. sends to P1 as specified in ping.
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* variables */ | ||||||
|  | extern uint8_t nrf_detected; | ||||||
|  | extern uint8_t nrf_myaddr; | ||||||
|  | 
 | ||||||
|  | extern uint8_t nrf_tx_buf[NRF_PAYLOAD_LEN]; | ||||||
|  | 
 | ||||||
|  | extern uint8_t nrf_last_ping_id; 	// sender's last byte
 | ||||||
|  | extern uint8_t nrf_last_ping_idx; 	// index byte
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void nrf_init(); | ||||||
|  | uint8_t nrf_checksum(uint8_t *data, uint8_t len, int32_t offset); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										186
									
								
								fw_dc22_stm32l100/src/device/radio/nrf24l01/nRF24L01.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								fw_dc22_stm32l100/src/device/radio/nrf24l01/nRF24L01.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,186 @@ | |||||||
|  | /* nRF24L01.h
 | ||||||
|  |  * Register definitions for manipulating the Nordic Semiconductor | ||||||
|  |  * nRF24L01+ RF transceiver chipsets. | ||||||
|  |  * | ||||||
|  | 
 | ||||||
|  |     Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de> | ||||||
|  |     Some parts copyright (c) 2012 Eric Brundick <spirilis [at] linux dot com> | ||||||
|  | 
 | ||||||
|  |     Permission is hereby granted, free of charge, to any person  | ||||||
|  |     obtaining a copy of this software and associated documentation  | ||||||
|  |     files (the "Software"), to deal in the Software without  | ||||||
|  |     restriction, including without limitation the rights to use, copy,  | ||||||
|  |     modify, merge, publish, distribute, sublicense, and/or sell copies  | ||||||
|  |     of the Software, and to permit persons to whom the Software is  | ||||||
|  |     furnished to do so, subject to the following conditions: | ||||||
|  | 
 | ||||||
|  |     The above copyright notice and this permission notice shall be  | ||||||
|  |     included in all copies or substantial portions of the Software. | ||||||
|  | 
 | ||||||
|  |     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  | ||||||
|  |     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  | ||||||
|  |     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  | ||||||
|  |     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  | ||||||
|  |     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,  | ||||||
|  |     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  | ||||||
|  |     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  | ||||||
|  |     DEALINGS IN THE SOFTWARE. | ||||||
|  |  */ | ||||||
|  | #ifndef _NRF24L01_H | ||||||
|  | #define _NRF24L01_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define	NRF_BIT0	1 << 0 | ||||||
|  | #define	NRF_BIT1	1 << 1 | ||||||
|  | #define	NRF_BIT2	1 << 2 | ||||||
|  | #define	NRF_BIT3	1 << 3 | ||||||
|  | #define	NRF_BIT4	1 << 4 | ||||||
|  | #define	NRF_BIT5	1 << 5 | ||||||
|  | #define	NRF_BIT6	1 << 6 | ||||||
|  | #define	NRF_BIT7	1 << 7 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Register Map */ | ||||||
|  | #define RF24_CONFIG        0x00	// Configuration register
 | ||||||
|  | #define RF24_EN_AA         0x01	// Enable "Auto acknowledgment"
 | ||||||
|  | #define RF24_EN_RXADDR     0x02	// Enable RX addresses
 | ||||||
|  | #define RF24_SETUP_AW      0x03	// Setup of address widths
 | ||||||
|  | #define RF24_SETUP_RETR    0x04	// Setup of automatic retranslation
 | ||||||
|  | #define RF24_RF_CH         0x05	// RF channel
 | ||||||
|  | #define RF24_RF_SETUP      0x06	// RF setup register
 | ||||||
|  | #define RF24_STATUS        0x07	// Status register
 | ||||||
|  | #define RF24_OBSERVE_TX    0x08	// Transmit observe register
 | ||||||
|  | #define RF24_CD            0x09	// Carrier detect
 | ||||||
|  | #define RF24_RPD           0x09 | ||||||
|  | #define RF24_RX_ADDR_P0    0x0A	// Receive address data pipe 0
 | ||||||
|  | #define RF24_RX_ADDR_P1    0x0B	// ..
 | ||||||
|  | #define RF24_RX_ADDR_P2    0x0C	// ..
 | ||||||
|  | #define RF24_RX_ADDR_P3    0x0D	// ..
 | ||||||
|  | #define RF24_RX_ADDR_P4    0x0E	// ..
 | ||||||
|  | #define RF24_RX_ADDR_P5    0x0F	// Receive address data pipe 5
 | ||||||
|  | #define RF24_TX_ADDR       0x10	// Transmit address
 | ||||||
|  | #define RF24_RX_PW_P0      0x11	// Number of bytes in RX payload id data pipe 0
 | ||||||
|  | #define RF24_RX_PW_P1      0x12	// ..
 | ||||||
|  | #define RF24_RX_PW_P2      0x13	// ..
 | ||||||
|  | #define RF24_RX_PW_P3      0x14	// ..
 | ||||||
|  | #define RF24_RX_PW_P4      0x15	// ..
 | ||||||
|  | #define RF24_RX_PW_P5      0x16	// Number of bytes in RX payload id data pipe 5
 | ||||||
|  | #define RF24_FIFO_STATUS   0x17	// FIFO status register
 | ||||||
|  | #define RF24_DYNPD         0x1C	// Enable dynamic payload length
 | ||||||
|  | #define RF24_FEATURE       0x1D	// Feature register
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Register NRF_BITs */ | ||||||
|  | #define RF24_MASK_RX_DR    NRF_BIT6	// Mask interrupt caused by RX_DR
 | ||||||
|  | #define RF24_MASK_TX_DS    NRF_BIT5	// Mask interrupt caused by TX_DS
 | ||||||
|  | #define RF24_MASK_MAX_RT   NRF_BIT4	// Mask interrupt caused by MAX_RT
 | ||||||
|  | #define RF24_EN_CRC        NRF_BIT3 | ||||||
|  | #define RF24_CRCO          NRF_BIT2 | ||||||
|  | #define RF24_PWR_UP        NRF_BIT1 | ||||||
|  | #define RF24_PRIM_RX       NRF_BIT0 | ||||||
|  | #define RF24_ENAA_P5       NRF_BIT5 | ||||||
|  | #define RF24_ENAA_P4       NRF_BIT4 | ||||||
|  | #define RF24_ENAA_P3       NRF_BIT3 | ||||||
|  | #define RF24_ENAA_P2       NRF_BIT2 | ||||||
|  | #define RF24_ENAA_P1       NRF_BIT1 | ||||||
|  | #define RF24_ENAA_P0       NRF_BIT0 | ||||||
|  | #define RF24_ERX_P5        NRF_BIT5 | ||||||
|  | #define RF24_ERX_P4        NRF_BIT4 | ||||||
|  | #define RF24_ERX_P3        NRF_BIT3 | ||||||
|  | #define RF24_ERX_P2        NRF_BIT2 | ||||||
|  | #define RF24_ERX_P1        NRF_BIT1 | ||||||
|  | #define RF24_ERX_P0        NRF_BIT0 | ||||||
|  | #define RF24_DYNPL_P5	   NRF_BIT5 | ||||||
|  | #define RF24_DYNPL_P4	   NRF_BIT4 | ||||||
|  | #define RF24_DYNPL_P3	   NRF_BIT3 | ||||||
|  | #define RF24_DYNPL_P2	   NRF_BIT2 | ||||||
|  | #define RF24_DYNPL_P1	   NRF_BIT1 | ||||||
|  | #define RF24_DYNPL_P0	   NRF_BIT0 | ||||||
|  | #define RF24_AW            NRF_BIT0 | ||||||
|  | #define RF24_ARD           NRF_BIT4 | ||||||
|  | #define RF24_ARC           NRF_BIT0 | ||||||
|  | #define RF24_PLL_LOCK      NRF_BIT4 | ||||||
|  | #define RF24_CONT_WAVE     NRF_BIT7 | ||||||
|  | #define RF24_RF_DR         NRF_BIT3 | ||||||
|  | #define RF24_RF_DR_LOW     NRF_BIT5 | ||||||
|  | #define RF24_RF_DR_HIGH    NRF_BIT3 | ||||||
|  | #define RF24_RF_PWR        NRF_BIT1 | ||||||
|  | #define RF24_LNA_HCURR     NRF_BIT0 | ||||||
|  | #define RF24_RX_DR         NRF_BIT6 | ||||||
|  | #define RF24_TX_DS         NRF_BIT5 | ||||||
|  | #define RF24_MAX_RT        NRF_BIT4 | ||||||
|  | #define RF24_RX_P_NO       NRF_BIT1 | ||||||
|  | #define RF24_TX_FULL       NRF_BIT0 | ||||||
|  | #define RF24_PLOS_CNT      NRF_BIT4 | ||||||
|  | #define RF24_ARC_CNT       NRF_BIT0 | ||||||
|  | #define RF24_TX_REUSE      NRF_BIT6 | ||||||
|  | #define RF24_FIFO_FULL     NRF_BIT5 | ||||||
|  | #define RF24_TX_EMPTY      NRF_BIT4 | ||||||
|  | #define RF24_RX_FULL       NRF_BIT1	// RX FIFO full flag
 | ||||||
|  | #define RF24_RX_EMPTY      NRF_BIT0	// RX FIFO empty flag
 | ||||||
|  | #define RF24_EN_DPL        NRF_BIT2 | ||||||
|  | #define RF24_EN_ACK_PAY    NRF_BIT1 | ||||||
|  | #define RF24_EN_DYN_ACK    NRF_BIT0 | ||||||
|  | 
 | ||||||
|  | #define RF24_SPEED_250 	   NRF_BIT5 | ||||||
|  | #define RF24_SPEED_1000    0 | ||||||
|  | #define RF24_SPEED_2000    NRF_BIT3 | ||||||
|  | 
 | ||||||
|  | #define RF24_POWER_FULL    NRF_BIT2 | NRF_BIT1 | ||||||
|  | #define RF24_POWER_HIGH    NRF_BIT2 | ||||||
|  | #define RF24_POWER_MED     NRF_BIT1 | ||||||
|  | #define RF24_POWER_LOW     0 | ||||||
|  | 
 | ||||||
|  | #define RF24_RETRY_250US   0x00 | ||||||
|  | #define RF24_RETRY_500US   0x10 | ||||||
|  | #define RF24_RETRY_750US   0x20 | ||||||
|  | #define RF24_RETRY_1000US  0x30 | ||||||
|  | #define RF24_RETRY_1250US  0x40 | ||||||
|  | #define RF24_RETRY_1500US  0x50 | ||||||
|  | #define RF24_RETRY_1750US  0x60 | ||||||
|  | #define RF24_RETRY_2000US  0x70 | ||||||
|  | #define RF24_RETRY_2250US  0x80 | ||||||
|  | #define RF24_RETRY_2500US  0x90 | ||||||
|  | #define RF24_RETRY_2750US  0xa0 | ||||||
|  | #define RF24_RETRY_3000US  0xb0 | ||||||
|  | #define RF24_RETRY_3250US  0xc0 | ||||||
|  | #define RF24_RETRY_3500US  0xd0 | ||||||
|  | #define RF24_RETRY_3750US  0xe0 | ||||||
|  | #define RF24_RETRY_4000US  0xf0 | ||||||
|  | 
 | ||||||
|  | #define RF24_RETRANS_OFF   0 | ||||||
|  | #define RF24_RETRANS_1X    1 | ||||||
|  | #define RF24_RETRANS_2X    2 | ||||||
|  | #define RF24_RETRANS_3X    3 | ||||||
|  | #define RF24_RETRANS_4X    4 | ||||||
|  | #define RF24_RETRANS_5X    5 | ||||||
|  | #define RF24_RETRANS_6X    6 | ||||||
|  | #define RF24_RETRANS_7X    7 | ||||||
|  | #define RF24_RETRANS_8X    8 | ||||||
|  | #define RF24_RETRANS_9X    9 | ||||||
|  | #define RF24_RETRANS_10X   10 | ||||||
|  | #define RF24_RETRANS_11X   11 | ||||||
|  | #define RF24_RETRANS_12X   12 | ||||||
|  | #define RF24_RETRANS_13X   13 | ||||||
|  | #define RF24_RETRANS_14X   14 | ||||||
|  | #define RF24_RETRANS_15X   15 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Instructions */ | ||||||
|  | #define RF24_RREG 				0x00	// R_REGISTER -> Read command and status registers
 | ||||||
|  | #define RF24_WREG 				0x20	// W_REGISTER -> Write command and status registers
 | ||||||
|  | #define RF24_REGISTER_MASK 		0x1F | ||||||
|  | #define RF24_R_RX_PAYLOAD 		0x61	// R_RX_PAYLOAD -> Read RX payload
 | ||||||
|  | #define RF24_W_TX_PAYLOAD 		0xA0	// W_TX_PAYLOAD -> Write TX payload
 | ||||||
|  | #define RF24_FLUSH_TX 			0xE1	// FLUSH_TX -> Flush TX FIFO
 | ||||||
|  | #define RF24_FLUSH_RX 			0xE2	// FLUSH_RX -> Flush RX FIFO
 | ||||||
|  | #define RF24_REUSE_TX_PL 		0xE3	// REUSE_TX_PL -> Reuse last transmitted payload
 | ||||||
|  | #define RF24_R_RX_PL_WID 		0x60 | ||||||
|  | #define RF24_W_ACK_PAYLOAD 		0xA8 | ||||||
|  | #define RF24_W_TX_PAYLOAD_NOACK 0xB0 | ||||||
|  | #define RF24_ACTIVATE 			0x50 | ||||||
|  | #define RF24_NOP 				0xFF	// No operation (to read status register)
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										766
									
								
								fw_dc22_stm32l100/src/device/radio/nrf24l01/true_nRF24L01.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										766
									
								
								fw_dc22_stm32l100/src/device/radio/nrf24l01/true_nRF24L01.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,766 @@ | |||||||
|  | /*
 | ||||||
|  |  * true's NRF24L01+ C library | ||||||
|  |  * shamelessly stolen and modified heavily from some other shit | ||||||
|  |  * basically: it's better than nothing | ||||||
|  |  * | ||||||
|  |  * $Id: true_nRF24L01.c 505 2021-09-05 19:07:51Z true $ | ||||||
|  |  * ==== | ||||||
|  |  * | ||||||
|  |  * general instructions to set up: | ||||||
|  |  * - Edit any shit necessary for your driver to work, update "true_nRF24L01.h" | ||||||
|  |  *     with your driver include file | ||||||
|  |  * - #include "true_nRF24L01.h" in your radio setup code source file | ||||||
|  |  * - for RX devices, you should set nRF24_rx_cb to your data handler. this | ||||||
|  |  *     handler is called with the data buffer / buffer length and received pipe. | ||||||
|  |  * - call nRF24_init() which sets defaults, calls nRF24_driver_init() which | ||||||
|  |  *     sets up hardware tasks, peripherals, and interrupts | ||||||
|  |  * - set and update your configuration, tx/rx addresses in your code | ||||||
|  |  * - in your IRQ pin ISR, call nRF24_interrupt(). this might be in your driver. | ||||||
|  |  * - if you did not set nRF24_rx_cb, check for new data by reading status | ||||||
|  |  *     and RX FIFO, and receive data manually however you decide to do it | ||||||
|  |  * - no special shit for transmit, just set up and go | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* nrf24 library includes */ | ||||||
|  | #include "true_nRF24L01.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* nrf24 configuration */ | ||||||
|  | static uint32_t txdelay; | ||||||
|  | static nrfConfig config; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* nrf24 data handling */ | ||||||
|  | static uint8_t nRF24_pbuf[_TRNRF_MAX_PACKET_SIZE]; | ||||||
|  | void (*nRF24_rx_cb)(uint8_t pipe, uint8_t *pBuf, uint8_t len); | ||||||
|  | void (*nRF24_tx_done_cb)(); | ||||||
|  | void (*nRF24_tx_max_rt_cb)(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* nrf24 feedback */ | ||||||
|  | static uint8_t nrf_mode = _TRNRF_MODE_OFF; | ||||||
|  | static uint8_t rx_received_pipe; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*********************************/ | ||||||
|  | /**** NRF SETUP AND INTERRUPT ****/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Initializes nRF24 config and hardware layer abstracted shit. | ||||||
|  |  */ | ||||||
|  | void nRF24_init(uint32_t cpu_freq_hz) { | ||||||
|  | 	// TX pin delay factor
 | ||||||
|  | 	txdelay = cpu_freq_hz >> 19; | ||||||
|  | 
 | ||||||
|  | 	// set some defaults
 | ||||||
|  | 	config.channel 			= 2; | ||||||
|  | 	config.rate_power 		= RF24_SPEED_1000 | RF24_POWER_FULL; | ||||||
|  | 	config.addr_width 		= 5; | ||||||
|  | 	config.payload_size[0] 	= 8; | ||||||
|  | 	config.payload_size[1] 	= 8; | ||||||
|  | 	config.crc 				= RF24_EN_CRC | RF24_CRCO; | ||||||
|  | 	config.pipe_ena 		= RF24_ERX_P0 | RF24_ERX_P1; 	// this is NRF power-up default
 | ||||||
|  | 	config.autoack_ena 		= 0x3f; 						// this is NRF power-up default
 | ||||||
|  | 	config.retry 			= RF24_RETRY_500US | RF24_RETRANS_10X; | ||||||
|  | 	config.tx_config 		= _TRNRF_MAX_RT_AUTOFLUSH | _TRNRF_MODE_RX; | ||||||
|  | 
 | ||||||
|  | 	// start up the hardware shit
 | ||||||
|  | 	nRF24_driver_init(); | ||||||
|  | 
 | ||||||
|  | 	// clear the RX/TX FIFOs
 | ||||||
|  | 	nRF24_reg_write(RF24_FLUSH_RX); | ||||||
|  | 	nRF24_reg_write(RF24_FLUSH_TX); | ||||||
|  | 	// and clear interrupt sources
 | ||||||
|  | 	nRF24_clear_irq_flags(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Note: at this time, this code requires the IRQ pin to operate */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Handles doing shit (receive data, clear IRQ flags) when IRQ is asserted. | ||||||
|  |  * | ||||||
|  |  * Call this function from your IRQ handler. | ||||||
|  |  * | ||||||
|  |  * @return 	 			NRF status | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_interrupt() | ||||||
|  | { | ||||||
|  | 	uint8_t status; | ||||||
|  | 	uint8_t pipe; | ||||||
|  | 	uint8_t len; | ||||||
|  | 
 | ||||||
|  | 	status = nRF24_reg_write(RF24_NOP); | ||||||
|  | 
 | ||||||
|  | 	if (status & RF24_TX_DS) { | ||||||
|  | 		// packet sent successfully and should not be in our FIFO
 | ||||||
|  | 		if (nRF24_tx_done_cb != 0) { | ||||||
|  | 			nRF24_tx_done_cb(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (status & RF24_MAX_RT) { | ||||||
|  | 		// packet not sent successfully and IS still in our FIFO
 | ||||||
|  | 		if (config.tx_config & _TRNRF_MAX_RT_AUTOFLUSH) { | ||||||
|  | 			nRF24_reg_write(RF24_FLUSH_TX); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (nRF24_tx_max_rt_cb != 0) { | ||||||
|  | 			nRF24_tx_max_rt_cb(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (status & RF24_RX_DR) { | ||||||
|  | 		// process data
 | ||||||
|  | 		if ((status & RF24_RX_P_NO) == RF24_RX_P_NO) { | ||||||
|  | 			// fifo done interrupt, so what? we don't care
 | ||||||
|  | 		} else { | ||||||
|  | 			if (nRF24_data_is_ready()) { | ||||||
|  | 				// looks like we have some data waiting for us
 | ||||||
|  | 				// if no callback is set, assume we are handling this manually elsewhere
 | ||||||
|  | 				if (nRF24_rx_cb != 0) { | ||||||
|  | 					// but our callback is set, so receive data
 | ||||||
|  | 					len = nRF24_packet_rx(status, nRF24_pbuf); | ||||||
|  | 					pipe = nRF24_rx_received_pipe(); | ||||||
|  | 					// process data
 | ||||||
|  | 					if (len <= _TRNRF_MAX_PACKET_SIZE) { | ||||||
|  | 						nRF24_rx_cb(pipe, nRF24_pbuf, len); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// clear all pending interrupt flags
 | ||||||
|  | 	nRF24_clear_irq_flags(); | ||||||
|  | 
 | ||||||
|  | 	// resume wtf we needed to do
 | ||||||
|  | 	if (nrf_mode & _TRNRF_MODE_TX) { | ||||||
|  | 		switch (config.tx_config & _TRNRF_MODE_MASK) { | ||||||
|  | 			case _TRNRF_MODE_RX: { | ||||||
|  | 				nRF24_mode_rx(); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 			case _TRNRF_MODE_OFF: { | ||||||
|  | 				nRF24_mode_off(); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 			case _TRNRF_MODE_TX: { | ||||||
|  | 				// this will put us into standby-ii. this mode is not recommended.
 | ||||||
|  | 				_TRNRF_CE_H(); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} else if (nrf_mode & _TRNRF_MODE_RX) { | ||||||
|  | 		nRF24_mode_rx(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return status; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /***************************/ | ||||||
|  | /**** NRF SPI FUNCTIONS ****/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Writes a value to NRF register or a single-byte argument to a command, | ||||||
|  |  * and reads the following byte (usually the result, see the datasheet) | ||||||
|  |  * | ||||||
|  |  * @param 	reg 	register / command to write to | ||||||
|  |  * @param 	value 	value to write to register / command | ||||||
|  |  * | ||||||
|  |  * @return 			value of the STATUS register | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_reg_rw(uint8_t reg, uint8_t value) { | ||||||
|  | 	uint8_t status; | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_L(); | ||||||
|  | 
 | ||||||
|  | 	status = nRF24_spi_rw(reg); // Select register/command
 | ||||||
|  | 	nRF24_spi_rw(value); // Write value to register
 | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_H(); | ||||||
|  | 
 | ||||||
|  | 	return status; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Writes a command byte to the NRF, and returns STATUS. | ||||||
|  |  * | ||||||
|  |  * @param 	cmd 	command to write | ||||||
|  |  * | ||||||
|  |  * @return 			value of the STATUS register | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_reg_write(uint8_t cmd) { | ||||||
|  | 	uint8_t status; | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_L(); | ||||||
|  | 
 | ||||||
|  | 	status = nRF24_spi_rw(cmd); | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_H(); | ||||||
|  | 
 | ||||||
|  | 	return status; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Reads a byte from the NRF register or command. | ||||||
|  |  * | ||||||
|  |  * @param 	reg 	register / command to read from | ||||||
|  |  * | ||||||
|  |  * @return 			value of this register / command | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_reg_read(uint8_t reg) { | ||||||
|  | 	uint8_t value; | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_L(); | ||||||
|  | 
 | ||||||
|  | 	nRF24_spi_rw(reg); | ||||||
|  | 	value = nRF24_spi_rw(0x00); | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_H(); | ||||||
|  | 
 | ||||||
|  | 	return value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Writes a buffer to NRF. | ||||||
|  |  * | ||||||
|  |  * @param 	reg 	register (buffer) to write info | ||||||
|  |  * @param 	*pBuf 	source buffer contents to read from | ||||||
|  |  * @param 	len 	bytes to read | ||||||
|  |  * | ||||||
|  |  * @return 			value of the STATUS register | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_buf_write(uint8_t reg, void *pBuf, uint8_t bytes) { | ||||||
|  | 	uint8_t status; | ||||||
|  | 	uint8_t i; | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_L(); | ||||||
|  | 
 | ||||||
|  | 	status = nRF24_spi_rw(reg); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < bytes; i++) | ||||||
|  | 		nRF24_spi_rw(((uint8_t *)pBuf)[i]); | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_H(); | ||||||
|  | 
 | ||||||
|  | 	return status; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Reads a buffer from NRF. | ||||||
|  |  * | ||||||
|  |  * @param 	reg 	register (buffer) to read from | ||||||
|  |  * @param 	*pBuf 	buffer to read register into | ||||||
|  |  * @param 	bytes 	bytes to read | ||||||
|  |  * | ||||||
|  |  * @return 			value of the STATUS register | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_buf_read(uint8_t reg, void *pBuf, uint8_t bytes) { | ||||||
|  | 	uint8_t status; | ||||||
|  | 	uint8_t i; | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_L(); | ||||||
|  | 
 | ||||||
|  | 	status = nRF24_spi_rw(reg); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < bytes; i++) | ||||||
|  | 		((uint8_t *)pBuf)[i] = nRF24_spi_rw(0x00); | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CSN_H(); | ||||||
|  | 
 | ||||||
|  | 	return status; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /***********************************/ | ||||||
|  | /**** NRF USER CONFIG FUNCTIONS ****/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Updates the TX address to the radio. | ||||||
|  |  */ | ||||||
|  | void nRF24_update_txaddr() | ||||||
|  | { | ||||||
|  | 	_TRNRF_CE_L(); | ||||||
|  | 
 | ||||||
|  | 	if (config.tx_addr) { | ||||||
|  | 		nRF24_buf_write(RF24_WREG | RF24_TX_ADDR, config.tx_addr, config.addr_width); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// were we in RX mode? yeah? then start listening again
 | ||||||
|  | 	if ((nrf_mode & _TRNRF_MODE_MASK) == _TRNRF_MODE_RX) { | ||||||
|  | 		_TRNRF_CE_H(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sets the TX address buffer pointer, and updates the radio with this address. | ||||||
|  |  * Make sure this buffer is at least config.addr_width in size. | ||||||
|  |  * | ||||||
|  |  * @param 	*addr 	pointer to tx buffer | ||||||
|  |  */ | ||||||
|  | void nRF24_set_txaddr(const uint8_t *addr) | ||||||
|  | { | ||||||
|  | 	config.tx_addr = (uint8_t *)addr; | ||||||
|  | 	nRF24_update_txaddr(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Updates the specified RX address to the radio. | ||||||
|  |  * | ||||||
|  |  * Please remember, auto-acknowledge requires pipe 0's address to match the | ||||||
|  |  * transmit address. | ||||||
|  |  * | ||||||
|  |  * Please remember, pipes 2 through 5 copy pipe 1's most significant bytes. | ||||||
|  |  */ | ||||||
|  | void nRF24_update_rxaddr(uint8_t pipe) | ||||||
|  | { | ||||||
|  | 	_TRNRF_CE_L(); | ||||||
|  | 
 | ||||||
|  | 	if (pipe == 0 && config.rx_addr_p0) { | ||||||
|  | 		nRF24_buf_write(RF24_WREG | RF24_RX_ADDR_P0, config.rx_addr_p0, config.addr_width); | ||||||
|  | 	} else if (pipe == 1 && config.rx_addr_p1) { | ||||||
|  | 		nRF24_buf_write(RF24_WREG | RF24_RX_ADDR_P1, config.rx_addr_p1, config.addr_width); | ||||||
|  | 	} else if (pipe <= 5) { | ||||||
|  | 		nRF24_reg_rw(RF24_WREG | (RF24_RX_ADDR_P0 + pipe), config.rx_pipe[pipe - 2]); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// were we in RX mode? yeah? then start listening again
 | ||||||
|  | 	if ((nrf_mode & _TRNRF_MODE_MASK) == _TRNRF_MODE_RX) { | ||||||
|  | 		_TRNRF_CE_H(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sets the RX address buffer pointer for pipes 0 and 1, and sets the | ||||||
|  |  * unique byte for pipes 2 through 5. Afterwards, updates the radio | ||||||
|  |  * with the new address. | ||||||
|  |  * | ||||||
|  |  * For pipes 0 and 1, make sure this buffer is at least config.addr_width in size. | ||||||
|  |  * | ||||||
|  |  * @param 	*addr 	pointer to rx buffer (can be temporary for pipes 2 through 5) | ||||||
|  |  */ | ||||||
|  | void nRF24_set_rxaddr(uint8_t pipe, const uint8_t *addr) | ||||||
|  | { | ||||||
|  | 	if (pipe == 0) { | ||||||
|  | 		config.rx_addr_p0 = (uint8_t *)addr; | ||||||
|  | 	} else if (pipe == 1) { | ||||||
|  | 		config.rx_addr_p1 = (uint8_t *)addr; | ||||||
|  | 	} else if (pipe <= 5) { | ||||||
|  | 		config.rx_pipe[pipe - 2] = *addr; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	nRF24_update_rxaddr(pipe); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sets the active channel between 2400MHz (0) and 2.525MHz (125). | ||||||
|  |  * At 2Mbps channel width is larger than 1MHz, so use 2MHz spacings | ||||||
|  |  * if you have multiple channels with multiple devices in use. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_channel(uint8_t chan) | ||||||
|  | { | ||||||
|  | 	if (chan > 125) chan = 125; | ||||||
|  | 	config.channel = chan; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sets the data rate between RF_SPEED_250, RF_SPEED_1000, and RF_SPEED_2000. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_rate(uint8_t rate) | ||||||
|  | { | ||||||
|  | 	config.rate_power &= ~(RF24_SPEED_250 | RF24_SPEED_1000 | RF24_SPEED_2000); | ||||||
|  | 	config.rate_power |= (rate & (RF24_SPEED_250 | RF24_SPEED_1000 | RF24_SPEED_2000)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sets the output power level. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_power(uint8_t power) | ||||||
|  | { | ||||||
|  | 	config.rate_power &= ~(RF24_POWER_FULL); | ||||||
|  | 	config.rate_power |= (power & (RF24_POWER_FULL)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sets the address width from 3 to 5 bytes wide. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_addr_width(uint8_t width) | ||||||
|  | { | ||||||
|  | 	if (width < 3) width = 3; | ||||||
|  | 	if (width > 5) width = 5; | ||||||
|  | 	config.addr_width = width; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sets the payload size. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_payload_size(uint8_t pipe, uint8_t size) | ||||||
|  | { | ||||||
|  | 	if (pipe <= 5) { | ||||||
|  | 		config.payload_size[pipe] = size; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sets the CRC options. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_crc(uint8_t crc) | ||||||
|  | { | ||||||
|  | 	config.crc = crc & (RF24_EN_CRC | RF24_CRCO); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Enables and disables receive pipes. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_pipe(uint8_t pipe, uint8_t onoff) | ||||||
|  | { | ||||||
|  | 	if (pipe <= 5) { | ||||||
|  | 		if (onoff) { | ||||||
|  | 			config.pipe_ena |= (1 << pipe); | ||||||
|  | 		} else { | ||||||
|  | 			config.pipe_ena &= ~(1 << pipe); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Enables and disables Shockburst (auto-acknowledge) per pipe. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_autoack(uint8_t pipe, uint8_t onoff) | ||||||
|  | { | ||||||
|  | 	if (pipe <= 5) { | ||||||
|  | 		if (onoff) { | ||||||
|  | 			config.autoack_ena |= (1 << pipe); | ||||||
|  | 		} else { | ||||||
|  | 			config.autoack_ena &= ~(1 << pipe); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Enables or disables the Dynamic ACK transmit option. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_dynack(uint8_t onoff) | ||||||
|  | { | ||||||
|  | 	if (onoff) { | ||||||
|  | 		config.autoack_ena |= 0x80; | ||||||
|  | 	} else { | ||||||
|  | 		config.autoack_ena &= 0x7f; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sends the active configuration to the radio. | ||||||
|  |  */ | ||||||
|  | void nRF24_update_config(uint8_t mask) | ||||||
|  | { | ||||||
|  | 	uint8_t set[3]; | ||||||
|  | 	uint8_t bit; | ||||||
|  | 	uint8_t i; | ||||||
|  | 
 | ||||||
|  | 	set[0] = set[1] = set[2] = 0; | ||||||
|  | 
 | ||||||
|  | 	_TRNRF_CE_L(); | ||||||
|  | 
 | ||||||
|  | 	// set SETUP_AW address width
 | ||||||
|  | 	if (mask & _TRNRF_UPDATE_SETUP_AW) { | ||||||
|  | 		nRF24_reg_rw(RF24_WREG | RF24_SETUP_AW, config.addr_width - 2); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set up various per-pipe configurations
 | ||||||
|  | 	if (mask & (_TRNRF_UPDATE_EN_RXADDR | _TRNRF_UPDATE_EN_AA | _TRNRF_UPDATE_DYNPD | _TRNRF_UPDATE_FEATURE)) { | ||||||
|  | 		for (i = 0; i <= 5; i++) { | ||||||
|  | 			bit = 1 << i; | ||||||
|  | 
 | ||||||
|  | 			if (config.pipe_ena & bit) { | ||||||
|  | 				set[0] |= bit; | ||||||
|  | 
 | ||||||
|  | 				nRF24_reg_rw(RF24_WREG | (RF24_RX_PW_P0 + i), | ||||||
|  | 						(config.payload_size[i] > 32 ? 32 : config.payload_size[i])); | ||||||
|  | 			} | ||||||
|  | 			if (config.autoack_ena & bit) { | ||||||
|  | 				set[1] |= bit; | ||||||
|  | 			} | ||||||
|  | 			if (config.payload_size[i] == _TRNRF_DYN_PAYLOAD) { | ||||||
|  | 				set[2] |= bit; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (mask & _TRNRF_UPDATE_EN_AA)     nRF24_reg_rw(RF24_WREG | RF24_EN_AA, set[1]); | ||||||
|  | 		if (mask & _TRNRF_UPDATE_EN_RXADDR) nRF24_reg_rw(RF24_WREG | RF24_EN_RXADDR, set[0]); | ||||||
|  | 
 | ||||||
|  | 		if (mask & (_TRNRF_UPDATE_DYNPD | _TRNRF_UPDATE_FEATURE)) { | ||||||
|  | 			nRF24_reg_rw(RF24_WREG | RF24_DYNPD, set[2]); | ||||||
|  | 
 | ||||||
|  | 			// set up FEATURE register (dynamic payload length, ack payload, dynamic ack [noack])
 | ||||||
|  | 			set[0] = ((set[2] ? RF24_EN_DPL : 0) | ((config.autoack_ena & 0x80) ? RF24_EN_DYN_ACK : 0)); | ||||||
|  | 			nRF24_reg_rw(RF24_WREG | RF24_FEATURE, set[0]); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set SETUP_RETR auto-ack retry settings
 | ||||||
|  | 	if (mask & _TRNRF_UPDATE_SETUP_RETR) { | ||||||
|  | 		nRF24_reg_rw(RF24_WREG | RF24_SETUP_RETR, config.retry); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set RF_CH channel
 | ||||||
|  | 	if (mask & _TRNRF_UPDATE_RF_CH) { | ||||||
|  | 		nRF24_reg_rw(RF24_WREG | RF24_RF_CH, config.channel); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set RF_SETUP data rate, power output
 | ||||||
|  | 	if (mask & _TRNRF_UPDATE_RF_SETUP) { | ||||||
|  | 		nRF24_reg_rw(RF24_WREG | RF24_RF_SETUP, config.rate_power); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set CONFIG crc
 | ||||||
|  | 	if (mask & _TRNRF_UPDATE_CRC) { | ||||||
|  | 		set[0] = nRF24_reg_read(RF24_CONFIG) & (RF24_PWR_UP | RF24_PRIM_RX); | ||||||
|  | 		nRF24_reg_rw(RF24_WREG | RF24_CONFIG, config.crc | set[0]); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// were we in RX mode? yeah? then start listening again
 | ||||||
|  | 	if ((nrf_mode & _TRNRF_MODE_MASK) == _TRNRF_MODE_RX) { | ||||||
|  | 		_TRNRF_CE_H(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sets the state to go into after transmit is done. | ||||||
|  |  * This mode is applied after a TX is complete in the interrupt handler. | ||||||
|  |  */ | ||||||
|  | void nRF24_set_tx_config(uint8_t max_rt_flush, uint8_t new_done_state) | ||||||
|  | { | ||||||
|  | 	config.tx_config = (max_rt_flush & 0x80) | (new_done_state & 0x7f); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Checks to see if an NRF24L01 is present by setting and reading a fake address. | ||||||
|  |  * After completion, it resets to the configured address parameters. | ||||||
|  |  * | ||||||
|  |  * @return 			nRF24 is present (1 = yes, 0 = no) | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_is_present(void) { | ||||||
|  | 	uint8_t buf[3]; | ||||||
|  | 
 | ||||||
|  | 	// write address length and fake address
 | ||||||
|  | 	buf[2] = 0xa9; | ||||||
|  | 	nRF24_reg_rw(RF24_WREG | RF24_SETUP_AW, 0x01); 	// 3 bytes
 | ||||||
|  | 	nRF24_buf_write(RF24_WREG | RF24_TX_ADDR, buf, 3); | ||||||
|  | 	// clear some address data
 | ||||||
|  | 	buf[2] = 0x00; | ||||||
|  | 
 | ||||||
|  | 	// try to read TX_ADDR register back
 | ||||||
|  | 	nRF24_buf_read(RF24_TX_ADDR, buf, 3); | ||||||
|  | 
 | ||||||
|  | 	// reset SETUP_AW and TX addr
 | ||||||
|  | 	nRF24_reg_rw(RF24_WREG | RF24_SETUP_AW, config.addr_width - 2); | ||||||
|  | 	nRF24_update_txaddr(); | ||||||
|  | 
 | ||||||
|  | 	// verify address matches fake address
 | ||||||
|  | 	if (buf[2] == 0xa9) | ||||||
|  | 		return 1; | ||||||
|  | 
 | ||||||
|  | 	// seems to be missing...
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*************************/ | ||||||
|  | /**** OPERATING MODES ****/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Puts the NRF into RX mode, turns on the radio, and starts listening. | ||||||
|  |  * | ||||||
|  |  * Only sets registers necessary to do this. Configure the radio | ||||||
|  |  * with nRF24_update_rxaddr, nRF24_update_config before putting | ||||||
|  |  * it into RX mode. | ||||||
|  |  */ | ||||||
|  | void nRF24_mode_rx() { | ||||||
|  | 	_TRNRF_CE_L(); | ||||||
|  | 
 | ||||||
|  | 	nRF24_reg_rw(RF24_WREG | RF24_CONFIG, config.crc | RF24_PWR_UP | RF24_PRIM_RX); | ||||||
|  | 
 | ||||||
|  | 	// put into active receive mode immediately
 | ||||||
|  | 	_TRNRF_CE_H(); | ||||||
|  | 	nrf_mode = _TRNRF_MODE_RX; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Prepares for standby, then puts the NRF into TX mode and turns on the radio. | ||||||
|  |  * | ||||||
|  |  * This is called from nRF24_packet_tx() automatically if the mode is | ||||||
|  |  * currently not in a transmit mode. Transmit will occur when | ||||||
|  |  * nRF24_packet_tx() is used. | ||||||
|  |  * | ||||||
|  |  * Only sets registers necessary to complete changing the mode. Configure any | ||||||
|  |  * other settings for the radio with nRF24_update_rxaddr (if auto-ack is on), | ||||||
|  |  * nRF24_update_txaddr, nRF24_update_config before putting it into TX mode. | ||||||
|  |  */ | ||||||
|  | void nRF24_mode_tx() { | ||||||
|  | 	// we will set high when ready to transmit
 | ||||||
|  | 	_TRNRF_CE_L(); | ||||||
|  | 
 | ||||||
|  | 	nRF24_reg_rw(RF24_WREG | RF24_CONFIG, config.crc | RF24_PWR_UP); | ||||||
|  | 	nrf_mode = _TRNRF_MODE_TX; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Puts the radio into standby (useful when in RX mode to save power). | ||||||
|  |  */ | ||||||
|  | void nRF24_mode_standby() | ||||||
|  | { | ||||||
|  | 	_TRNRF_CE_L(); | ||||||
|  | 	nrf_mode |= _TRNRF_MODE_STANDBY; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Powers down the NRF24L01. | ||||||
|  |  */ | ||||||
|  | void nRF24_mode_off() | ||||||
|  | { | ||||||
|  | 	_TRNRF_CE_L(); | ||||||
|  | 
 | ||||||
|  | 	nRF24_reg_rw(RF24_WREG | RF24_CONFIG, nRF24_reg_read(RF24_CONFIG) & ~(RF24_PWR_UP)); | ||||||
|  | 	nrf_mode = _TRNRF_MODE_OFF; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Returns the currently operating NRF mode. | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_mode_get() | ||||||
|  | { | ||||||
|  | 	return nrf_mode; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**************************/ | ||||||
|  | /**** DATA TRANSCIEVER ****/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Checks if data is ready by seeing if there is anything in the RX FIFO. | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_data_is_ready(void) { | ||||||
|  |     uint8_t status; | ||||||
|  | 
 | ||||||
|  |     status = nRF24_reg_read(RF24_FIFO_STATUS); | ||||||
|  |     return (status & RF24_RX_EMPTY) ? 0 : 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Loads a packet for transmit, puts the radio into transmit mode, then signals | ||||||
|  |  * radio to begin transmitting. | ||||||
|  |  * | ||||||
|  |  * @param 	*pBuf 	pointer to transmit buffer | ||||||
|  |  * @param 	bytes 	bytes to send | ||||||
|  |  * @param 	noack 	if not zero, and if dynack enabled, flags the packet NO_ACK | ||||||
|  |  */ | ||||||
|  | void nRF24_packet_tx(void *pBuf, uint8_t bytes, uint8_t noack) { | ||||||
|  |     int i; | ||||||
|  | 
 | ||||||
|  |     // make sure we are in TX mode
 | ||||||
|  |     if ((nrf_mode & _TRNRF_MODE_TX) == 0) { | ||||||
|  |     	nRF24_mode_tx(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // write TX buffer to FIFO
 | ||||||
|  | 	// note: noack mode will only work if nRF24_set_dynack(1); nRF24_config_update(); has been done
 | ||||||
|  |     // also make sure that you have nRF24_set_rxaddr(0, txaddr) if using shockburst
 | ||||||
|  | 	nRF24_buf_write((noack && config.autoack_ena & 0x80) ? | ||||||
|  | 			RF24_W_TX_PAYLOAD_NOACK : RF24_W_TX_PAYLOAD, pBuf, bytes); | ||||||
|  | 
 | ||||||
|  |     // CE pin high => start transmit
 | ||||||
|  |     _TRNRF_CE_H(); | ||||||
|  | 
 | ||||||
|  |     // if we're going into standard standby-I mode, need to do a little more
 | ||||||
|  |     if (!(config.tx_config & _TRNRF_MODE_TX)) { | ||||||
|  |     	// needs to be high for at least 10us for tx to function, per datasheet
 | ||||||
|  | 		// this keeps it high for about 16us
 | ||||||
|  | 		for (i = txdelay; i; i--) { | ||||||
|  | 			asm volatile ("nop"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		_TRNRF_CE_L(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Receives a packet. | ||||||
|  |  * | ||||||
|  |  * @param 	status 	nRF24 status (please get with nRF24_reg_read(RF24_STATUS)) | ||||||
|  |  * @param 	*pBuf 	pointer to receive buffer | ||||||
|  |  * | ||||||
|  |  * @return 			length of data received | ||||||
|  |  */ | ||||||
|  | int8_t nRF24_packet_rx(uint8_t status, void *pBuf) { | ||||||
|  | 	uint8_t pipe; | ||||||
|  | 	uint8_t payload_len; | ||||||
|  | 
 | ||||||
|  | 	// status must indicate RX ready and RX FIFO not empty
 | ||||||
|  | 	if ((status & RF24_RX_DR) && ((status & RF24_RX_P_NO) != RF24_RX_P_NO)) { | ||||||
|  | 		// get pipe
 | ||||||
|  | 		pipe = (status & RF24_RX_P_NO) >> 1; | ||||||
|  | 
 | ||||||
|  | 		// payload is static, unless it isn't, in which case get the received payload length
 | ||||||
|  | 		payload_len = config.payload_size[pipe]; | ||||||
|  | 		if (payload_len == _TRNRF_DYN_PAYLOAD) { | ||||||
|  | 			payload_len = nRF24_reg_read(RF24_R_RX_PL_WID); | ||||||
|  | 
 | ||||||
|  | 			// is it valid?
 | ||||||
|  | 			if (payload_len > 32) { | ||||||
|  | 				// no, flush buffer and quit
 | ||||||
|  | 				nRF24_reg_write(RF24_FLUSH_RX); | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// everything else done, so set pipe, clear buffer, read payload from RX FIFO buffer
 | ||||||
|  | 		// NRF automatically removes this data from FIFO per datasheet
 | ||||||
|  | 		rx_received_pipe = pipe; | ||||||
|  | 		nRF24_buf_read(RF24_R_RX_PAYLOAD, pBuf, payload_len); | ||||||
|  | 		return payload_len; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 	// requests to receive that are not ready will clear RX FIFO
 | ||||||
|  | 	nRF24_reg_write(RF24_FLUSH_RX); | ||||||
|  | 	return -2; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Returns the last received data's pipe number. | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_rx_received_pipe() | ||||||
|  | { | ||||||
|  | 	return rx_received_pipe; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t nRF24_packet_ackreply(uint8_t *pBuf, uint8_t tx_payload_len) | ||||||
|  | { | ||||||
|  | 	if (config.payload_size[0] != _TRNRF_DYN_PAYLOAD) { | ||||||
|  | 		// ack reply payloads require dynamic payload to be enabled
 | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// not yet implemented
 | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*****************/ | ||||||
|  | /**** IRQ PIN ****/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Clear all IRQ status flags. | ||||||
|  |  */ | ||||||
|  | void nRF24_clear_irq_flags(void) { | ||||||
|  | 	// Clear RX_DR, TX_DS, MAX_RT flags. cleared by writing 1 to these bits
 | ||||||
|  |     nRF24_reg_rw(RF24_WREG | RF24_STATUS, (RF24_RX_DR | RF24_TX_DS | RF24_MAX_RT)); | ||||||
|  | } | ||||||
							
								
								
									
										128
									
								
								fw_dc22_stm32l100/src/device/radio/nrf24l01/true_nRF24L01.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								fw_dc22_stm32l100/src/device/radio/nrf24l01/true_nRF24L01.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | |||||||
|  | /*
 | ||||||
|  |  * true's NRF24L01+ C library | ||||||
|  |  * shamelessly stolen and modified heavily from some other shit | ||||||
|  |  * basically: it's better than nothing | ||||||
|  |  * | ||||||
|  |  * $Id: true_nRF24L01.h 505 2021-09-05 19:07:51Z true $ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __TRUE_NRF24L01_LIB_H | ||||||
|  | #define __TRUE_NRF24L01_LIB_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* common libraries */ | ||||||
|  | #include <stdint.h> | ||||||
|  | #include "nRF24L01.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* user compile-time configuration */ | ||||||
|  | #define _TRNRF_MAX_PACKET_SIZE 			32 		// 32 is the max the radio can handle
 | ||||||
|  |  	 	 	 	 	 	 	 	 	 	 		// set lower to save memory
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* platform driver select */ | ||||||
|  | #include "true_nRF24L01_stm32l1xx.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* compile-time user configuration */ | ||||||
|  | #define _TRNRF_USE_INTERRUPT_PIN 				// enables the use of interrupt pin
 | ||||||
|  | 												// only interrupt-mode implemented, currently mandatory
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* nrf library constants */ | ||||||
|  | #define _TRNRF_MODE_OFF 				0x00 | ||||||
|  | #define _TRNRF_MODE_STANDBY 			0x01 | ||||||
|  | #define _TRNRF_MODE_RX 					0x10 | ||||||
|  | #define _TRNRF_MODE_TX 					0x20 | ||||||
|  | #define _TRNRF_MODE_MASK 				0x3f | ||||||
|  | 
 | ||||||
|  | #define _TRNRF_UPDATE_ALL 				0xff | ||||||
|  | #define _TRNRF_UPDATE_EN_RXADDR 		0x01 | ||||||
|  | #define _TRNRF_UPDATE_EN_AA 			0x02 | ||||||
|  | #define _TRNRF_UPDATE_SETUP_AW 			0x04 | ||||||
|  | #define _TRNRF_UPDATE_SETUP_RETR 		0x08 | ||||||
|  | #define _TRNRF_UPDATE_RF_CH 			0x10 | ||||||
|  | #define _TRNRF_UPDATE_RF_SETUP 			0x20 | ||||||
|  | #define _TRNRF_UPDATE_CRC 				0x40 | ||||||
|  | #define _TRNRF_UPDATE_DYNPD 			0x80 	// this and
 | ||||||
|  | #define _TRNRF_UPDATE_FEATURE 			0x80 	// this should be updated together anyway
 | ||||||
|  | 
 | ||||||
|  | #define _TRNRF_ACK 						0 | ||||||
|  | #define _TRNRF_NO_ACK 					1 | ||||||
|  | 
 | ||||||
|  | #define _TRNRF_MAX_RT_AUTOFLUSH 		0x80 | ||||||
|  | #define _TRNRF_MAX_RT_NO_FLUSH 			0x00 | ||||||
|  | 
 | ||||||
|  | #define _TRNRF_DYN_PAYLOAD 				0xff | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* config struct */ | ||||||
|  | typedef struct nrfConfig { | ||||||
|  | 	uint8_t channel; 			// 0-125, 2400MHz to 2525MHz
 | ||||||
|  | 	uint8_t rate_power; 		// data rate, tx power
 | ||||||
|  | 	uint8_t addr_width; 		// width of address, from 2-5 bytes
 | ||||||
|  | 	uint8_t payload_size[6]; 	// per-pipe RX payload length, from 1-32 bytes, 0=variable payload
 | ||||||
|  | 	uint8_t crc; 				// crc enable and crc mode bits
 | ||||||
|  | 	uint8_t pipe_ena; 			// rx pipe enable bits
 | ||||||
|  | 	uint8_t autoack_ena; 		// per-pipe autoack (enhanced shockburst) on/off
 | ||||||
|  | 	uint8_t retry; 				// global autoack retry config
 | ||||||
|  | 	uint8_t *tx_addr; 			// pointer to tx address, addr_width long
 | ||||||
|  | 	uint8_t tx_config; 			// state to go into after transmitting a packet, flush max_rt FIFO automatically?
 | ||||||
|  | 	uint8_t *rx_addr_p0; 		// pointer to rxp0 address, addr_width long
 | ||||||
|  | 	uint8_t *rx_addr_p1; 		// pointer to rxp1 address, addr_width long
 | ||||||
|  | 	uint8_t rx_pipe[4]; 		// rxp2-rxp5 last byte of address
 | ||||||
|  | } nrfConfig; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* data handling */ | ||||||
|  | void (*nRF24_rx_cb)(uint8_t pipe, uint8_t *pBuf, uint8_t len); | ||||||
|  | void (*nRF24_tx_done_cb)(); | ||||||
|  | void (*nRF24_tx_max_rt_cb)(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* function prototypes */ | ||||||
|  | void nRF24_init(uint32_t cpu_freq); | ||||||
|  | uint8_t nRF24_interrupt(); | ||||||
|  | 
 | ||||||
|  | uint8_t nRF24_reg_rw(uint8_t reg, uint8_t value); | ||||||
|  | uint8_t nRF24_reg_write(uint8_t cmd); | ||||||
|  | uint8_t nRF24_reg_read(uint8_t reg); | ||||||
|  | uint8_t nRF24_buf_write(uint8_t reg, void *pBuf, uint8_t bytes); | ||||||
|  | uint8_t nRF24_buf_read(uint8_t reg, void *pBuf, uint8_t bytes); | ||||||
|  | 
 | ||||||
|  | uint8_t nRF24_is_present(void); | ||||||
|  | 
 | ||||||
|  | void nRF24_set_txaddr(const uint8_t *addr); | ||||||
|  | void nRF24_set_rxaddr(uint8_t pipe, const uint8_t *addr); | ||||||
|  | 
 | ||||||
|  | void nRF24_set_channel(uint8_t chan); | ||||||
|  | void nRF24_set_rate(uint8_t rate); | ||||||
|  | void nRF24_set_power(uint8_t power); | ||||||
|  | void nRF24_set_addr_width(uint8_t width); | ||||||
|  | void nRF24_set_payload_size(uint8_t pipe, uint8_t size); | ||||||
|  | void nRF24_set_crc(uint8_t crc); | ||||||
|  | void nRF24_set_pipe(uint8_t pipe, uint8_t onoff); | ||||||
|  | void nRF24_set_autoack(uint8_t pipe, uint8_t onoff); | ||||||
|  | void nRF24_set_dynack(uint8_t onoff); | ||||||
|  | 
 | ||||||
|  | void nRF24_update_config(uint8_t mask); | ||||||
|  | 
 | ||||||
|  | void nRF24_set_tx_config(uint8_t max_rt_flush, uint8_t new_done_state); | ||||||
|  | 
 | ||||||
|  | void nRF24_mode_rx(); | ||||||
|  | void nRF24_mode_tx(); | ||||||
|  | void nRF24_mode_standby(); | ||||||
|  | void nRF24_mode_off(); | ||||||
|  | uint8_t nRF24_mode_get(); | ||||||
|  | 
 | ||||||
|  | uint8_t nRF24_data_is_ready(void); | ||||||
|  | 
 | ||||||
|  | int8_t nRF24_packet_rx(uint8_t status, void *pBuf); | ||||||
|  | void   nRF24_packet_tx(void *pBuf, uint8_t bytes, uint8_t noack); | ||||||
|  | uint8_t nRF24_rx_received_pipe(); | ||||||
|  | 
 | ||||||
|  | void nRF24_clear_irq_flags(void); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -0,0 +1,146 @@ | |||||||
|  | /*
 | ||||||
|  |  * true's NRF24L01 C library | ||||||
|  |  * STM32L1xx interface driver | ||||||
|  |  * basically: it's better than nothing | ||||||
|  |  * | ||||||
|  |  * $Id: true_nRF24L01_stm32l1xx.c 375 2015-07-06 02:52:40Z true $ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include "true_nRF24l01_stm32l1xx.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* hardware init */ | ||||||
|  | void nRF24_spi_init(uint16_t speed) { | ||||||
|  | 	SPI_InitTypeDef spi; | ||||||
|  | 
 | ||||||
|  | 	spi.SPI_Mode = SPI_Mode_Master; | ||||||
|  | 	spi.SPI_BaudRatePrescaler = speed; | ||||||
|  | 	spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex; | ||||||
|  | 	spi.SPI_CPOL = SPI_CPOL_Low; | ||||||
|  | 	spi.SPI_CPHA = SPI_CPHA_1Edge; | ||||||
|  | 	spi.SPI_CRCPolynomial = 7; | ||||||
|  | 	spi.SPI_DataSize = SPI_DataSize_8b; | ||||||
|  | 	spi.SPI_FirstBit = SPI_FirstBit_MSB; | ||||||
|  | 	spi.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; | ||||||
|  | 
 | ||||||
|  | 	SPI_Init(_TRNRF_SPI_PORT, &spi); | ||||||
|  | 	SPI_Cmd(_TRNRF_SPI_PORT, ENABLE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nRF24_interrupt_init() | ||||||
|  | { | ||||||
|  | 	EXTI_InitTypeDef exti; | ||||||
|  | 	NVIC_InitTypeDef nvic; | ||||||
|  | 
 | ||||||
|  | 	// make sure SYSCFG clock is running
 | ||||||
|  | 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); | ||||||
|  | 	// set up the IRQ pin to actually attach to an interrupt
 | ||||||
|  | 	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource11); 	// IRQ pin, also see lonelywolf_nRF24L01.h
 | ||||||
|  | 
 | ||||||
|  | 	exti.EXTI_Line = EXTI_Line11; // EXTI will be on line 11
 | ||||||
|  | 	exti.EXTI_LineCmd = ENABLE; // EXTI enabled
 | ||||||
|  | 	exti.EXTI_Mode = EXTI_Mode_Interrupt; // Generate IRQ
 | ||||||
|  | 	exti.EXTI_Trigger = EXTI_Trigger_Falling; // IRQ on signal falling
 | ||||||
|  | 	EXTI_Init(&exti); | ||||||
|  | 
 | ||||||
|  | 	// and then enable this interrupt at the lowest priority
 | ||||||
|  | 	nvic.NVIC_IRQChannel = EXTI15_10_IRQn; | ||||||
|  | 	nvic.NVIC_IRQChannelCmd = ENABLE; | ||||||
|  | 	nvic.NVIC_IRQChannelPreemptionPriority = 0x0F; | ||||||
|  | 	nvic.NVIC_IRQChannelSubPriority = 0x0F; | ||||||
|  | 	NVIC_Init(&nvic); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* driver init */ | ||||||
|  | void nRF24_driver_init() | ||||||
|  | { | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 
 | ||||||
|  | #if _TRNRF_SPI_PORT_USE == 1 | ||||||
|  | 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); | ||||||
|  | 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); 	// SPI pins
 | ||||||
|  | #elif _TRNRF_SPI_PORT_USE == 2 | ||||||
|  | 	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); | ||||||
|  | 	RCC_AHBPeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 	// set up other pin clocks
 | ||||||
|  | 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); 	// CE/IRQ pins
 | ||||||
|  | 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); 	// CS pin
 | ||||||
|  | 
 | ||||||
|  | 	// Configure SPI pins GPIO
 | ||||||
|  | 	gpio.GPIO_Speed = GPIO_Speed_10MHz; | ||||||
|  | 	gpio.GPIO_OType = GPIO_OType_PP; | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_AF; | ||||||
|  | 	gpio.GPIO_Pin = _TRNRF_SPI_SCK_PIN | _TRNRF_SPI_MISO_PIN | _TRNRF_SPI_MOSI_PIN; | ||||||
|  | 	GPIO_Init(_TRNRF_SPI_GPIO_PORT, &gpio); | ||||||
|  | 
 | ||||||
|  | 	// configure SPI pin AF
 | ||||||
|  | 	GPIO_PinAFConfig(_TRNRF_SPI_GPIO_PORT, _TRNRF_SPI_SCK_PINSRC, _TRNRF_SPI_GPIO_AF); | ||||||
|  | 	GPIO_PinAFConfig(_TRNRF_SPI_GPIO_PORT, _TRNRF_SPI_MISO_PINSRC, _TRNRF_SPI_GPIO_AF); | ||||||
|  | 	GPIO_PinAFConfig(_TRNRF_SPI_GPIO_PORT, _TRNRF_SPI_MOSI_PINSRC, _TRNRF_SPI_GPIO_AF); | ||||||
|  | 
 | ||||||
|  | 	// configure CS pin as output with push-pull
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_OUT; | ||||||
|  | 	gpio.GPIO_Pin = _TRNRF_SPI_CS_PIN; | ||||||
|  | 	GPIO_Init(_TRNRF_SPI_CS_PORT, &gpio); | ||||||
|  | 
 | ||||||
|  | 	// configure CE pin as output with push-pull
 | ||||||
|  | 	gpio.GPIO_Pin = _TRNRF_nRF24_CE_PIN; | ||||||
|  | 	GPIO_Init(_TRNRF_nRF24_CE_PORT, &gpio); | ||||||
|  | 
 | ||||||
|  | 	// configure IRQ pin as input with weak pull-Up
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_IN; | ||||||
|  | 	gpio.GPIO_PuPd = GPIO_PuPd_UP; | ||||||
|  | 	gpio.GPIO_Pin = _TRNRF_nRF24_IRQ_PIN; | ||||||
|  | 	GPIO_Init(_TRNRF_nRF24_IRQ_PORT, &gpio); | ||||||
|  | 
 | ||||||
|  | 	// set SPI and CE pins to startup values
 | ||||||
|  | 	_TRNRF_CSN_H(); | ||||||
|  | 	_TRNRF_CE_L(); | ||||||
|  | 
 | ||||||
|  | 	// start up SPI and IRQ interrupt
 | ||||||
|  | 	nRF24_spi_init(_TRNRF_SPI_BAUD); | ||||||
|  | 	nRF24_interrupt_init(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Communicates with the nRF24L01 (or anything else, really) over SPI. | ||||||
|  |  * | ||||||
|  |  * Since this command can be used for bulk transfer, it does NOT do anything | ||||||
|  |  * with the SPI CS pin. Please check CS before and after using this function. | ||||||
|  |  * | ||||||
|  |  * @param 	data 	byte to send on SPI bus | ||||||
|  |  * | ||||||
|  |  * @return 			data returned on SPI bus | ||||||
|  |  */ | ||||||
|  | uint8_t nRF24_spi_rw(uint8_t data) { | ||||||
|  | 	// Wait while DR register is not empty
 | ||||||
|  | 	while (SPI_I2S_GetFlagStatus(_TRNRF_SPI_PORT, SPI_I2S_FLAG_TXE) == RESET); | ||||||
|  | 	// Send byte to SPI
 | ||||||
|  | 	SPI_I2S_SendData(_TRNRF_SPI_PORT, data); | ||||||
|  | 	// Wait to receive byte
 | ||||||
|  | 	while (SPI_I2S_GetFlagStatus(_TRNRF_SPI_PORT, SPI_I2S_FLAG_RXNE) == RESET); | ||||||
|  | 	// Read byte from SPI bus
 | ||||||
|  | 	return SPI_I2S_ReceiveData(_TRNRF_SPI_PORT); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* irq handler */ | ||||||
|  | void EXTI15_10_IRQHandler(void) { | ||||||
|  | 	uint8_t status = 0; | ||||||
|  | 
 | ||||||
|  | 	if (EXTI_GetITStatus(EXTI_Line11) != RESET) { | ||||||
|  | 		status = nRF24_interrupt(); | ||||||
|  | 
 | ||||||
|  | 		// do anything custom here if you like
 | ||||||
|  | 
 | ||||||
|  | 		EXTI_ClearITPendingBit(EXTI_Line11); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// fixes compiler warning for unused status
 | ||||||
|  | 	status = status | 0x00; | ||||||
|  | } | ||||||
| @ -0,0 +1,91 @@ | |||||||
|  | /*
 | ||||||
|  |  * true's NRF24L01 C library | ||||||
|  |  * STM32L1xx interface driver header | ||||||
|  |  * basically: it's better than nothing | ||||||
|  |  * | ||||||
|  |  * $Id: true_nRF24L01_stm32l1xx.h 375 2015-07-06 02:52:40Z true $ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __TRUE_NRF24L01_STM32L1XX_H | ||||||
|  | #define __TRUE_NRF24L01_STM32L1XX_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // include stm libraries
 | ||||||
|  | #include "stm32l1xx_conf.h" | ||||||
|  | 
 | ||||||
|  | // and the nrf libraries
 | ||||||
|  | #include "true_nrf24l01.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********************/ | ||||||
|  | /**** SPI SELECT ****/ | ||||||
|  |   // which SPI to use?
 | ||||||
|  | #define _TRNRF_SPI_PORT_USE 		1 | ||||||
|  | #define _TRNRF_SPI_BAUD 			SPI_BaudRatePrescaler_4 | ||||||
|  | 
 | ||||||
|  |   // nRF24L01 CS (Chip Select) pin (SPI CS)
 | ||||||
|  | #define _TRNRF_SPI_CS_PORT 			GPIOD | ||||||
|  | #define _TRNRF_SPI_CS_PIN 			GPIO_Pin_2 		// PD2
 | ||||||
|  | 
 | ||||||
|  |   // nRF24L01 CE (Chip Enable) pin (handles RX/TX mode)
 | ||||||
|  | #define _TRNRF_nRF24_CE_PORT 		GPIOC | ||||||
|  | #define _TRNRF_nRF24_CE_PIN 		GPIO_Pin_10 	// PC10
 | ||||||
|  | 
 | ||||||
|  |   // nRF24L01 IRQ pin
 | ||||||
|  | #define _TRNRF_nRF24_IRQ_PORT 		GPIOC | ||||||
|  | #define _TRNRF_nRF24_IRQ_PIN 		GPIO_Pin_11 	// PC11
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********************/ | ||||||
|  | /**** SPI CONFIG ****/ | ||||||
|  | #if _TRNRF_SPI_PORT_USE == 1 | ||||||
|  | 	#define _TRNRF_SPI_PORT 		SPI1 | ||||||
|  | 
 | ||||||
|  | 	#define _TRNRF_SPI_GPIO_AF 		GPIO_AF_SPI1 | ||||||
|  | 	#define _TRNRF_SPI_GPIO_PORT 	GPIOB | ||||||
|  | 
 | ||||||
|  | 	#define _TRNRF_SPI_SCK_PIN 		GPIO_Pin_3 | ||||||
|  | 	#define _TRNRF_SPI_MISO_PIN 	GPIO_Pin_4 | ||||||
|  | 	#define _TRNRF_SPI_MOSI_PIN 	GPIO_Pin_5 | ||||||
|  | 	#define _TRNRF_SPI_SCK_PINSRC 	GPIO_PinSource3 | ||||||
|  | 	#define _TRNRF_SPI_MISO_PINSRC 	GPIO_PinSource4 | ||||||
|  | 	#define _TRNRF_SPI_MOSI_PINSRC 	GPIO_PinSource5 | ||||||
|  | #elif _TRNRF_SPI_PORT_USE == 2 | ||||||
|  | 	#define _TRNRF_SPI_PORT 		SPI2 | ||||||
|  | 
 | ||||||
|  | 	#define _TRNRF_SPI_GPIO_AF 		GPIO_AF_SPI2 | ||||||
|  | 	#define _TRNRF_SPI_GPIO_PORT 	GPIOB | ||||||
|  | 
 | ||||||
|  | 	#define _TRNRF_SPI_SCK_PIN 		GPIO_Pin_13 | ||||||
|  | 	#define _TRNRF_SPI_MISO_PIN 	GPIO_Pin_14 | ||||||
|  | 	#define _TRNRF_SPI_MOSI_PIN 	GPIO_Pin_15 | ||||||
|  | 	#define _TRNRF_SPI_SCK_PINSRC 	GPIO_PinSource13 | ||||||
|  | 	#define _TRNRF_SPI_MISO_PINSRC 	GPIO_PinSource14 | ||||||
|  | 	#define _TRNRF_SPI_MOSI_PINSRC 	GPIO_PinSource15 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********************/ | ||||||
|  | /**** PIN MACROS ****/ | ||||||
|  |   // chip-enable (activates rx/tx modes)
 | ||||||
|  | #define _TRNRF_CE_L() 				GPIO_ResetBits(_TRNRF_nRF24_CE_PORT, _TRNRF_nRF24_CE_PIN) | ||||||
|  | #define _TRNRF_CE_H() 				GPIO_SetBits(_TRNRF_nRF24_CE_PORT, _TRNRF_nRF24_CE_PIN) | ||||||
|  | 
 | ||||||
|  |   // SPI chipselect
 | ||||||
|  | #define _TRNRF_CSN_L() 				GPIO_ResetBits(_TRNRF_SPI_CS_PORT, _TRNRF_SPI_CS_PIN) | ||||||
|  | #define _TRNRF_CSN_H() 				GPIO_SetBits(_TRNRF_SPI_CS_PORT, _TRNRF_SPI_CS_PIN) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********************/ | ||||||
|  | /**** PROTOTYPES ****/ | ||||||
|  | void nRF24_driver_init(); | ||||||
|  | 
 | ||||||
|  | uint8_t nRF24_spi_rw(uint8_t data); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										20
									
								
								fw_dc22_stm32l100/src/display/cgram/cgram.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								fw_dc22_stm32l100/src/display/cgram/cgram.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | /**
 | ||||||
|  |  * cgram.c: lcd cgram graphics constants | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: cgram.c 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | const uint8_t cgram_crown[6][8] = { | ||||||
|  | 	{0x00, 0x00, 0x1C, 0x14, 0x1C, 0x0C, 0x0A, 0x09}, | ||||||
|  | 	{0x0E, 0x0A, 0x0E, 0x04, 0x04, 0x0A, 0x11, 0x00}, | ||||||
|  | 	{0x00, 0x00, 0x07, 0x05, 0x07, 0x06, 0x0A, 0x12}, | ||||||
|  | 	{0x08, 0x08, 0x09, 0x0E, 0x08, 0x0F, 0x00, 0x00}, | ||||||
|  | 	{0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x00}, | ||||||
|  | 	{0x02, 0x02, 0x12, 0x0E, 0x02, 0x1E, 0x00, 0x00} | ||||||
|  | }; | ||||||
							
								
								
									
										20
									
								
								fw_dc22_stm32l100/src/display/cgram/cgram.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								fw_dc22_stm32l100/src/display/cgram/cgram.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | /**
 | ||||||
|  |  * cgram.h: lcd cgram graphics constants | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: cgram.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_DISPLAY_CGRAM_H | ||||||
|  | #define __PIRATE_DISPLAY_CGRAM_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | extern const uint8_t cgram_crown[6][8]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										103
									
								
								fw_dc22_stm32l100/src/display/infopirate.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								fw_dc22_stm32l100/src/display/infopirate.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | /**
 | ||||||
|  |  * infopirate.c: namebadge and other information animated 8x2 display | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: infopirate.c 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "../device/lcd.h" | ||||||
|  | 
 | ||||||
|  | #include "../menu/lcd_menu.h" 	// for lcd_line | ||||||
|  | 
 | ||||||
|  | #include "infopirate.h" | ||||||
|  | #include "infopirate_prog.h" | ||||||
|  | 
 | ||||||
|  | #include "cgram/cgram.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | uint8_t prog_idx; 				// currently selected program
 | ||||||
|  | uint8_t prog_loop; 				// current loop thru program
 | ||||||
|  | 
 | ||||||
|  | uint8_t (*infopirate_prog)(void); | ||||||
|  | uint8_t (*infopirate_prog_list[])() = { | ||||||
|  | 	&infopirate_prog_scroll_name_in_left, | ||||||
|  | 	&infopirate_prog_nameonly, | ||||||
|  | 	&infopirate_prog_scroll_name_out_left, | ||||||
|  | 	&infopirate_prog_logo01, | ||||||
|  | 	&infopirate_prog_logo02 | ||||||
|  | }; | ||||||
|  | const uint8_t prog_loop_run[] = { 	// amount of passes per program in static mode
 | ||||||
|  | 	1, | ||||||
|  | 	10, | ||||||
|  | 	1, | ||||||
|  | 	1, | ||||||
|  | 	1 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | void infopirate_init() | ||||||
|  | { | ||||||
|  | 	prog_wait = 0; | ||||||
|  | 	prog_loop = 0; | ||||||
|  | 	prog_idx = 0; | ||||||
|  | 	infopirate_prog = NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void infopirate_next_prog() | ||||||
|  | { | ||||||
|  | 	prog_wait = 0; 		// infopirate_prog.h
 | ||||||
|  | 	prog_loop = 0; | ||||||
|  | 	prog_idx++; | ||||||
|  | 
 | ||||||
|  | 	if (prog_idx >= sizeof_array(infopirate_prog_list)) prog_idx = 0; | ||||||
|  | 
 | ||||||
|  | 	infopirate_prog = infopirate_prog_list[prog_idx]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void infopirate_update() | ||||||
|  | { | ||||||
|  | 	uint8_t state; | ||||||
|  | 
 | ||||||
|  | 	state = INFOPIRATE_PROG_NONE; | ||||||
|  | 
 | ||||||
|  | 	if (infopirate_prog != NULL) { | ||||||
|  | 		state = infopirate_prog(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	switch (state) { | ||||||
|  | 		case INFOPIRATE_PROG_NONE: { | ||||||
|  | 			prog_idx = 0; | ||||||
|  | 			prog_loop = 0; | ||||||
|  | 			infopirate_prog = infopirate_prog_list[0]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case INFOPIRATE_PROG_DONE: { | ||||||
|  | 			prog_loop++; | ||||||
|  | 			if (prog_loop >= prog_loop_run[prog_idx]) { | ||||||
|  | 				infopirate_next_prog(); | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_infopirate_btn_prev() | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_infopirate_btn_next() | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_infopirate_btn_ok() | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								fw_dc22_stm32l100/src/display/infopirate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								fw_dc22_stm32l100/src/display/infopirate.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | /**
 | ||||||
|  |  * infopirate.h: namebadge and other information animated 8x2 display | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: infopirate.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_DISPLAY_INFOPIRATE_H | ||||||
|  | #define __PIRATE_DISPLAY_INFOPIRATE_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define INFOPIRATE_PROG_NONE 		0x00 | ||||||
|  | #define INFOPIRATE_PROG_PAUSED 		0x01 | ||||||
|  | #define INFOPIRATE_PROG_RUNNING 	0x02 | ||||||
|  | #define INFOPIRATE_PROG_DONE 		0xFE | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void infopirate_init(); | ||||||
|  | 
 | ||||||
|  | void infopirate_update(); | ||||||
|  | 
 | ||||||
|  | void menu_infopirate_btn_prev(); | ||||||
|  | void menu_infopirate_btn_next(); | ||||||
|  | void menu_infopirate_btn_ok(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										158
									
								
								fw_dc22_stm32l100/src/display/infopirate_prog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								fw_dc22_stm32l100/src/display/infopirate_prog.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,158 @@ | |||||||
|  | /**
 | ||||||
|  |  * infopirate_prog.h: program functions for badge related bullshit | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: infopirate_prog.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include "../menu/lcd_menu.h" | ||||||
|  | #include "cgram/cgram.h" 	// for CGRAM graphics tables | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | uint16_t prog_wait; 		// used by function to keep track of iteration time
 | ||||||
|  | uint32_t prog_state[4]; 	// used by the function to keep track of state
 | ||||||
|  | uint32_t prog_work[2]; 		// used for misc shit
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | uint8_t infopirate_prog_nameonly() | ||||||
|  | { | ||||||
|  | 	if (!prog_wait) { | ||||||
|  | 		prog_wait = 100; | ||||||
|  | 		lcd_set_height(LCD_CMD_DOUBLEHEIGHT); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	strncpy(lcd_line[0], settings.name, 8); | ||||||
|  | 
 | ||||||
|  | 	prog_wait--; | ||||||
|  | 	return prog_wait ? INFOPIRATE_PROG_RUNNING : INFOPIRATE_PROG_DONE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t infopirate_prog_scroll_name_in_left() | ||||||
|  | { | ||||||
|  | 	if (!prog_wait) { | ||||||
|  | 		prog_wait = 121; | ||||||
|  | 		prog_state[0] = 8; | ||||||
|  | 		lcd_set_height(LCD_CMD_DOUBLEHEIGHT); | ||||||
|  | 	} else if (prog_wait % 15 == 0) { | ||||||
|  | 		if (prog_state[0]) prog_state[0]--; | ||||||
|  | 
 | ||||||
|  | 		strncpy(lcd_line[0], "        ", 8); 		// make the line all spaces
 | ||||||
|  | 		if (prog_state[0] < 8) { | ||||||
|  | 			lcd_line[0][prog_state[0]] = 0x00; 		// set our null
 | ||||||
|  | 			strncat(lcd_line[0], settings.name, 8); // copy our name
 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	prog_wait--; | ||||||
|  | 	return prog_wait ? INFOPIRATE_PROG_RUNNING : INFOPIRATE_PROG_DONE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t infopirate_prog_scroll_name_out_left() | ||||||
|  | { | ||||||
|  | 	int i, j; | ||||||
|  | 
 | ||||||
|  | 	if (!prog_wait) { | ||||||
|  | 		prog_wait = 121; | ||||||
|  | 		prog_state[0] = 0; | ||||||
|  | 		lcd_set_height(LCD_CMD_DOUBLEHEIGHT); | ||||||
|  | 	} else if (prog_wait % 15 == 0) { | ||||||
|  | 		if (prog_state[0] < 7) prog_state[0]++; | ||||||
|  | 
 | ||||||
|  | 		strncpy(lcd_line[0], "        ", 8); 		// make the line all spaces
 | ||||||
|  | 		j = 0; | ||||||
|  | 		for (i = prog_state[0]; i < 8; i++) { | ||||||
|  | 			lcd_line[0][j++] = settings.name[i]; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	prog_wait--; | ||||||
|  | 	return prog_wait ? INFOPIRATE_PROG_RUNNING : INFOPIRATE_PROG_DONE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t infopirate_prog_logo01() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	static const char line1[8] = {0x00, 0x01, 0x02, 'T', 'h', 'r', 'e', 'e'}; | ||||||
|  | 	static const char line2[8] = {0x03, 0x04, 0x05, 'K', 'i', 'n', 'g', 's'}; | ||||||
|  | 
 | ||||||
|  | 	if (!prog_wait) { | ||||||
|  | 		// set our state timer
 | ||||||
|  | 		prog_wait = 400; | ||||||
|  | 		prog_state[0] = 0; | ||||||
|  | 
 | ||||||
|  | 		// enable CGRAM
 | ||||||
|  | 		lcd_set_height(LCD_CMD_SINGLEHEIGHT & 0xfe); 	// enable cgram
 | ||||||
|  | 
 | ||||||
|  | 		// set the CGRAM data to load
 | ||||||
|  | 		lcd_set_cgram_load(cgram_crown, sizeof_array(cgram_crown)); | ||||||
|  | 
 | ||||||
|  | 		// set data
 | ||||||
|  | 		for (i = 0; i < 8; i++) { | ||||||
|  | 			lcd_line[0][i] = line1[i]; | ||||||
|  | 			lcd_line[1][i] = line2[i]; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	prog_wait--; | ||||||
|  | 	return prog_wait ? INFOPIRATE_PROG_RUNNING : INFOPIRATE_PROG_DONE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t infopirate_prog_logo02() | ||||||
|  | { | ||||||
|  | 	// prog_state[0] is the current character on this line to print
 | ||||||
|  | 	// prog_work[0] is the current character overall to print
 | ||||||
|  | 	// prog_work[1] is the current position of the character
 | ||||||
|  | 	if (!prog_wait) { | ||||||
|  | 		// new setup
 | ||||||
|  | 		prog_wait = 9; | ||||||
|  | 		prog_state[0] = 0; 		// first character
 | ||||||
|  | 		prog_work[0] = 0; 		// first character
 | ||||||
|  | 		prog_work[1] = 8; 		// scrolling from right, set to last character
 | ||||||
|  | 
 | ||||||
|  | 		// clear strings for new setup
 | ||||||
|  | 		strncpy(lcd_line[0], "        ", 8); | ||||||
|  | 		strncpy(lcd_line[1], "        ", 8); | ||||||
|  | 	} else if (prog_work[0] == 16) { | ||||||
|  | 		// we're done. wait a while
 | ||||||
|  | 		prog_wait = 210; | ||||||
|  | 		prog_work[0]++; | ||||||
|  | 	} else if (prog_wait == 1) { | ||||||
|  | 		// loop timeout expired, reload timer and process
 | ||||||
|  | 		prog_wait = 9; | ||||||
|  | 
 | ||||||
|  | 		static const char line1[] = "Whiskey "; | ||||||
|  | 		static const char line2[] = " Pirates"; | ||||||
|  | 
 | ||||||
|  | 		lcd_set_height(LCD_CMD_SINGLEHEIGHT); | ||||||
|  | 
 | ||||||
|  | 		// did our character reach the end?
 | ||||||
|  | 		if (prog_work[1] <= prog_state[0]) { | ||||||
|  | 			// then go to the next character and reset right position
 | ||||||
|  | 			prog_work[0]++; | ||||||
|  | 			prog_state[0] = prog_work[0] & 0x07; | ||||||
|  | 			prog_work[1] = 8; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// do we have characters left to update?
 | ||||||
|  | 		if (prog_work[0] < 16) { | ||||||
|  | 			// working variables
 | ||||||
|  | 			char *src = prog_work[0] < 8 ? (char *)line1 : (char *)line2; | ||||||
|  | 			char *target = prog_work[0] < 8 ? lcd_line[0] : lcd_line[1]; | ||||||
|  | 
 | ||||||
|  | 			// set the character one less than prog_work[1] to our target
 | ||||||
|  | 			target[prog_work[1] - 1] = src[prog_state[0]]; | ||||||
|  | 			// if this isn't the last one, set the current working character to a space
 | ||||||
|  | 			if (prog_work[1] < 8) target[prog_work[1]] = 0x20; | ||||||
|  | 			// and continue scrolling our character in to the left
 | ||||||
|  | 			prog_work[1]--; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	prog_wait--; | ||||||
|  | 	return (prog_wait != 10) ? INFOPIRATE_PROG_RUNNING : INFOPIRATE_PROG_DONE; | ||||||
|  | } | ||||||
							
								
								
									
										135
									
								
								fw_dc22_stm32l100/src/interface/adc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								fw_dc22_stm32l100/src/interface/adc.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,135 @@ | |||||||
|  | /**
 | ||||||
|  |  * adc.h: manager for anything adc-related | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: adc.c 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "adc.h" | ||||||
|  | #include "gpio.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const tGPIO adc_gpio[] = { | ||||||
|  | 	{GPIOA, GPIO_Pin_5, 5}, 	// mic sig detect
 | ||||||
|  | 	{GPIOB, GPIO_Pin_0, 0}, 	// mic peak detect
 | ||||||
|  | 	{GPIOB, GPIO_Pin_0, 1}, 	// battery voltage
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | uint8_t adc_chan; | ||||||
|  | uint16_t adc_result[ADC_MAX_RESULT_COUNT]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | void adc_init() | ||||||
|  | { | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 	ADC_CommonInitTypeDef adc_com; | ||||||
|  | 	ADC_InitTypeDef adc_init; | ||||||
|  | 	NVIC_InitTypeDef nvic; | ||||||
|  | 
 | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	// make sure the HSI is turned on - STM32L1xx uses HSI only for ADC
 | ||||||
|  | 	RCC_HSICmd(ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// enable ADC clock
 | ||||||
|  | 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// set up pins as analog inputs
 | ||||||
|  | 	// NOTE: clocks were likely enabled earlier. fix if they weren't.
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_AN; | ||||||
|  | 	gpio.GPIO_Speed = GPIO_Speed_2MHz; | ||||||
|  | 	gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 3; i++) { | ||||||
|  | 		gpio.GPIO_Pin = adc_gpio[i].pin; | ||||||
|  | 		GPIO_Init(adc_gpio[i].port, &gpio); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// configure ADC initial values
 | ||||||
|  | 	ADC_CommonStructInit(&adc_com); | ||||||
|  | 	ADC_StructInit(&adc_init); | ||||||
|  | 	adc_init.ADC_ExternalTrigConv = 0; | ||||||
|  | 
 | ||||||
|  | 	// set up channels to read
 | ||||||
|  | 	ADC_RegularChannelConfig(ADC1, ADC_CHAN_MIC_SIG, ADC_READ_MIC_SIG + 1, ADC_SampleTime_4Cycles); | ||||||
|  | 	ADC_RegularChannelConfig(ADC1, ADC_CHAN_MIC_PEAK, ADC_READ_MIC_PEAK + 1, ADC_SampleTime_4Cycles); | ||||||
|  | 	ADC_RegularChannelConfig(ADC1, ADC_CHAN_BATT_VOLTAGE, ADC_READ_BATT_VOLTAGE + 1, ADC_SampleTime_4Cycles); | ||||||
|  | 	adc_init.ADC_ScanConvMode = ENABLE; | ||||||
|  | 	adc_init.ADC_NbrOfConversion = 3; | ||||||
|  | 
 | ||||||
|  | 	// enable end of conversion on each channel read
 | ||||||
|  | 	ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// freeze ADC until data has been read
 | ||||||
|  | 	ADC_DelaySelectionConfig(ADC1, ADC_DelayLength_Freeze); | ||||||
|  | 
 | ||||||
|  | 	// initialize the ADC
 | ||||||
|  | 	ADC_CommonInit(&adc_com); | ||||||
|  | 	ADC_Init(ADC1, &adc_init); | ||||||
|  | 
 | ||||||
|  | 	// it doesn't look like STM32L100 has auto-calibrate feature,
 | ||||||
|  | 	// but if it did, we'd set it up here. baw.
 | ||||||
|  | 
 | ||||||
|  | 	// set up ADC power saving
 | ||||||
|  | 	ADC_PowerDownCmd(ADC1, ADC_PowerDown_Idle_Delay, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// enable interrupt
 | ||||||
|  | 	ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// set interrupt priority
 | ||||||
|  | 	nvic.NVIC_IRQChannel = ADC1_IRQn; | ||||||
|  | 	nvic.NVIC_IRQChannelPreemptionPriority = 3; | ||||||
|  | 	nvic.NVIC_IRQChannelSubPriority = 0; | ||||||
|  | 	nvic.NVIC_IRQChannelCmd = ENABLE; | ||||||
|  | 	NVIC_Init(&nvic); | ||||||
|  | 
 | ||||||
|  | 	// finally, turn on the ADC
 | ||||||
|  | 	ADC_Cmd(ADC1, ENABLE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void adc_deinit() | ||||||
|  | { | ||||||
|  | 	// reset ADC
 | ||||||
|  | 	ADC_DeInit(ADC1); | ||||||
|  | 
 | ||||||
|  | 	// and disable ADC clock
 | ||||||
|  | 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void adc_start() | ||||||
|  | { | ||||||
|  | 	int adc_timeout = 200; | ||||||
|  | 
 | ||||||
|  | 	adc_chan = 0; | ||||||
|  | 
 | ||||||
|  | 	// verify ADC is powered up
 | ||||||
|  | 	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET) { | ||||||
|  | 		ADC_Cmd(ADC1, ENABLE); | ||||||
|  | 		if (--adc_timeout == 0) { | ||||||
|  | 			adc_result[2] |= 0xf000; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// then start conversion if ADC is on
 | ||||||
|  | 	if (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == SET) { | ||||||
|  | 		ADC_SoftwareStartConv(ADC1); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ADC1_IRQHandler() | ||||||
|  | { | ||||||
|  | 	if (adc_chan < ADC_MAX_RESULT_COUNT) { | ||||||
|  | 		adc_result[adc_chan] = ADC_GetConversionValue(ADC1); | ||||||
|  | 		adc_chan++; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								fw_dc22_stm32l100/src/interface/adc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								fw_dc22_stm32l100/src/interface/adc.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | /**
 | ||||||
|  |  * adc.h: prototypes for adc functions | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: adc.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_IF_ADC_H | ||||||
|  | #define __PIRATE_IF_ADC_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define ADC_MAX_RESULT_COUNT 	3 		// channels in use
 | ||||||
|  | 
 | ||||||
|  | #define ADC_READ_MIC_SIG 		0 | ||||||
|  | #define ADC_READ_MIC_PEAK 		1 | ||||||
|  | #define ADC_READ_BATT_VOLTAGE 	2 | ||||||
|  | 
 | ||||||
|  | #define ADC_CHAN_MIC_SIG 		ADC_Channel_5 | ||||||
|  | #define ADC_CHAN_MIC_PEAK 		ADC_Channel_8 | ||||||
|  | #define ADC_CHAN_BATT_VOLTAGE 	ADC_Channel_9 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | extern uint16_t adc_result[ADC_MAX_RESULT_COUNT]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void adc_init(); | ||||||
|  | void adc_deinit(); | ||||||
|  | 
 | ||||||
|  | void adc_channel(uint8_t rank); | ||||||
|  | void adc_start(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										8
									
								
								fw_dc22_stm32l100/src/interface/gpio.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								fw_dc22_stm32l100/src/interface/gpio.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | /**
 | ||||||
|  |  * pirate gpio interface | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: gpio.c 327 2015-02-18 04:43:42Z true $ | ||||||
|  | **/ | ||||||
							
								
								
									
										35
									
								
								fw_dc22_stm32l100/src/interface/gpio.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								fw_dc22_stm32l100/src/interface/gpio.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | /**
 | ||||||
|  |  * gpio.h: pirate gpio interface | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: gpio.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_IF_GPIO_H | ||||||
|  | #define __PIRATE_IF_GPIO_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define BIT_0 		1 | ||||||
|  | #define BIT_1 		(1 << 1) | ||||||
|  | #define BIT_2 		(1 << 2) | ||||||
|  | #define BIT_3 		(1 << 3) | ||||||
|  | #define BIT_4 		(1 << 4) | ||||||
|  | #define BIT_5 		(1 << 5) | ||||||
|  | #define BIT_6 		(1 << 6) | ||||||
|  | #define BIT_7 		(1 << 7) | ||||||
|  | 
 | ||||||
|  | #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) | ||||||
|  | 
 | ||||||
|  | typedef struct tGPIO { | ||||||
|  | 	GPIO_TypeDef *port; | ||||||
|  | 	uint16_t pin; | ||||||
|  | 	uint8_t pinsource; | ||||||
|  | } tGPIO; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										82
									
								
								fw_dc22_stm32l100/src/interface/i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								fw_dc22_stm32l100/src/interface/i2c.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | |||||||
|  | /**
 | ||||||
|  |  * i2c.h: pirate i2c interface, command and data buffering, and data receive callbacks | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: i2c.c 368 2015-06-16 06:49:48Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "i2c.h" | ||||||
|  | #include "gpio.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define I2C_GPIO_SCL 		0 | ||||||
|  | #define I2C_GPIO_SDA 		1 | ||||||
|  | 
 | ||||||
|  | static const tGPIO i2c_pins[2][2] = { | ||||||
|  | 	{ 	// i2c1
 | ||||||
|  | 		{GPIOB, GPIO_Pin_8, 8}, 	// scl
 | ||||||
|  | 		{GPIOB, GPIO_Pin_9, 9} 		// sda
 | ||||||
|  | 	}, | ||||||
|  | 	{ 	// i2c2
 | ||||||
|  | 		{GPIOB, GPIO_Pin_10, 10}, 	// scl
 | ||||||
|  | 		{GPIOB, GPIO_Pin_11, 11} 	// sda
 | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | void i2c_init(I2C_TypeDef *i2cdev, uint32_t speed) | ||||||
|  | { | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 	I2C_InitTypeDef i2c; | ||||||
|  | 
 | ||||||
|  | 	int i2c_idx; | ||||||
|  | 
 | ||||||
|  | 	if (i2cdev == I2C1) { | ||||||
|  | 		i2c_idx = 0; | ||||||
|  | 	} else { | ||||||
|  | 		i2c_idx = 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// enable peripheral clocks
 | ||||||
|  | 	// GPIOB is already enabled by LED driver
 | ||||||
|  | 	if (i2cdev == I2C1) { | ||||||
|  | 		RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); | ||||||
|  | 	} else if (i2cdev == I2C2) { | ||||||
|  | 		RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); | ||||||
|  | 		// and reset it (silicon bug?)
 | ||||||
|  | 		RCC_AHBPeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); | ||||||
|  | 		RCC_AHBPeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set up peripheral
 | ||||||
|  | 	I2C_StructInit(&i2c); | ||||||
|  | 	i2c.I2C_ClockSpeed = speed; | ||||||
|  | 	I2C_Init(i2cdev, &i2c); | ||||||
|  | 
 | ||||||
|  | 	// set up pins
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_AF; | ||||||
|  | 	gpio.GPIO_OType = GPIO_OType_OD; | ||||||
|  | 	gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; | ||||||
|  | 	gpio.GPIO_Speed = GPIO_Speed_2MHz; | ||||||
|  | 
 | ||||||
|  | 	gpio.GPIO_Pin = i2c_pins[i2c_idx][I2C_GPIO_SCL].pin | i2c_pins[i2c_idx][I2C_GPIO_SDA].pin; | ||||||
|  | 	GPIO_Init(i2c_pins[i2c_idx][I2C_GPIO_SCL].port, &gpio); | ||||||
|  | 
 | ||||||
|  | 	// set pin alternate function
 | ||||||
|  | 	GPIO_PinAFConfig(i2c_pins[i2c_idx][I2C_GPIO_SCL].port, | ||||||
|  | 			i2c_pins[i2c_idx][I2C_GPIO_SCL].pinsource, GPIO_AF_I2C1); | ||||||
|  | 	GPIO_PinAFConfig(i2c_pins[i2c_idx][I2C_GPIO_SDA].port, | ||||||
|  | 			i2c_pins[i2c_idx][I2C_GPIO_SDA].pinsource, GPIO_AF_I2C1); | ||||||
|  | 
 | ||||||
|  | 	// enable the i2c interrupts
 | ||||||
|  | 
 | ||||||
|  | 	// enable peripheral
 | ||||||
|  | 	I2C_Cmd(i2cdev, ENABLE); | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								fw_dc22_stm32l100/src/interface/i2c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								fw_dc22_stm32l100/src/interface/i2c.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | /**
 | ||||||
|  |  * i2c.h: pirate i2c interface, command and data buffering, and data receive callbacks | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: i2c.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_I2C_H | ||||||
|  | #define __PIRATE_I2C_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // we're using this guy's library because it seems to work
 | ||||||
|  | #include "peter_i2c/peter_i2c.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define I2C_BUF_SIZE 			16  	// power of 2
 | ||||||
|  | 
 | ||||||
|  | #define I2C_READ 				I2C_Direction_Receiver | ||||||
|  | #define I2C_WRITE 				I2C_Direction_Transmitter | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void i2c_init(I2C_TypeDef *i2c, uint32_t speed); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										90
									
								
								fw_dc22_stm32l100/src/interface/led_pwm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								fw_dc22_stm32l100/src/interface/led_pwm.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | |||||||
|  | /**
 | ||||||
|  |  * led_pwm.c: led pwm configuration functions | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_pwm.c 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "led_pwm.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | void led_pwm_init(TIM_TypeDef *timer, uint16_t polarity, uint8_t channel_mask) | ||||||
|  | { | ||||||
|  | 	TIM_TimeBaseInitTypeDef tim_tb; | ||||||
|  | 	TIM_OCInitTypeDef tim_oc; | ||||||
|  | 
 | ||||||
|  | 	// set up with 250 levels of brightness
 | ||||||
|  | 	tim_tb.TIM_Prescaler = 5 - 1; 		// 6.4MHz
 | ||||||
|  | 	tim_tb.TIM_Period = 256 - 1; 		// 25KHz PWM, 5 updates/LED
 | ||||||
|  | 	tim_tb.TIM_ClockDivision = 0; | ||||||
|  | 	tim_tb.TIM_CounterMode = TIM_CounterMode_Up; | ||||||
|  | 	TIM_TimeBaseInit(timer, &tim_tb); | ||||||
|  | 
 | ||||||
|  | 	// configure outputs as pwm
 | ||||||
|  | 	tim_oc.TIM_OCMode = TIM_OCMode_PWM1; | ||||||
|  | 	tim_oc.TIM_OutputState = TIM_OutputState_Enable; | ||||||
|  | 	tim_oc.TIM_Pulse = 0; | ||||||
|  | 	tim_oc.TIM_OCPolarity = polarity; | ||||||
|  | 
 | ||||||
|  | 	// configure pin for PWM output mode, enable preload
 | ||||||
|  | 	if (channel_mask & 0x01) { | ||||||
|  | 		TIM_OC1Init(timer, &tim_oc); | ||||||
|  | 		TIM_OC1PreloadConfig(timer, TIM_OCPreload_Enable); | ||||||
|  | 	} | ||||||
|  | 	if (channel_mask & 0x02) { | ||||||
|  | 		TIM_OC2Init(timer, &tim_oc); | ||||||
|  | 		TIM_OC2PreloadConfig(timer, TIM_OCPreload_Enable); | ||||||
|  | 	} | ||||||
|  | 	if (channel_mask & 0x04) { | ||||||
|  | 		TIM_OC3Init(timer, &tim_oc); | ||||||
|  | 		TIM_OC3PreloadConfig(timer, TIM_OCPreload_Enable); | ||||||
|  | 	} | ||||||
|  | 	if (channel_mask & 0x08) { | ||||||
|  | 		TIM_OC4Init(timer, &tim_oc); | ||||||
|  | 		TIM_OC4PreloadConfig(timer, TIM_OCPreload_Enable); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// finally, enable the timer
 | ||||||
|  | 	TIM_ARRPreloadConfig(timer, ENABLE); | ||||||
|  | 	TIM_Cmd(timer, ENABLE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_pwm_init_all() | ||||||
|  | { | ||||||
|  | 	// enable peripheral clock and configure timers with PWM settings
 | ||||||
|  | 
 | ||||||
|  | 	// main led matrix
 | ||||||
|  | 	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); | ||||||
|  | 	led_pwm_init(TIM2, TIM_OCPolarity_High, | ||||||
|  | 			LED_PWM_CH1 | LED_PWM_CH2 | LED_PWM_CH3 | LED_PWM_CH4); | ||||||
|  | 
 | ||||||
|  | 	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); | ||||||
|  | 	led_pwm_init(TIM3, TIM_OCPolarity_High, | ||||||
|  | 			LED_PWM_CH1 | LED_PWM_CH2 | LED_PWM_CH3 | LED_PWM_CH4); | ||||||
|  | 
 | ||||||
|  | 	// bone led matrix
 | ||||||
|  | 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11, ENABLE); | ||||||
|  | 	led_pwm_init(TIM11, TIM_OCPolarity_High, LED_PWM_CH1); | ||||||
|  | 
 | ||||||
|  | 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE); | ||||||
|  | 	led_pwm_init(TIM9, TIM_OCPolarity_High, LED_PWM_CH1 | LED_PWM_CH2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_pwm_set_oc(TIM_TypeDef *timer, uint32_t *oc) | ||||||
|  | { | ||||||
|  | 	timer->CCR1 = *oc++; | ||||||
|  | 
 | ||||||
|  | 	if (timer == TIM9) { | ||||||
|  | 		timer->CCR2 = *oc++; | ||||||
|  | 	} else if (timer == TIM2 || timer == TIM3 || timer == TIM4) { | ||||||
|  | 		timer->CCR2 = *oc++; | ||||||
|  | 		timer->CCR3 = *oc++; | ||||||
|  | 		timer->CCR4 = *oc; | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								fw_dc22_stm32l100/src/interface/led_pwm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								fw_dc22_stm32l100/src/interface/led_pwm.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | /**
 | ||||||
|  |  * led_pwm.h: led pwm configuration prototypes | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_pwm.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_LED_PWM_H | ||||||
|  | #define __PIRATE_LED_PWM_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define LED_PWM_CH1 	0x01 | ||||||
|  | #define LED_PWM_CH2 	0x02 | ||||||
|  | #define LED_PWM_CH3 	0x04 | ||||||
|  | #define LED_PWM_CH4 	0x08 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void led_pwm_init_all(); | ||||||
|  | void led_pwm_set_oc(TIM_TypeDef *timer, uint32_t *oc); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										351
									
								
								fw_dc22_stm32l100/src/interface/peter_i2c/peter_i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										351
									
								
								fw_dc22_stm32l100/src/interface/peter_i2c/peter_i2c.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,351 @@ | |||||||
|  | #include "peter_i2c.h" | ||||||
|  | 
 | ||||||
|  | //-------------------------------------------
 | ||||||
|  | // Definition of local constants
 | ||||||
|  | //-------------------------------------------
 | ||||||
|  | #define I2C_TIMEOUT  (0x1000) | ||||||
|  | 
 | ||||||
|  | //-------------------------------------------
 | ||||||
|  | // Declaration of local functions
 | ||||||
|  | //-------------------------------------------
 | ||||||
|  | static int I2C_check_dev(uint8_t addr); | ||||||
|  | static int I2C_start(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr); | ||||||
|  | static int I2C_restart(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr); | ||||||
|  | static int I2C_stop(I2C_TypeDef* I2Cx); | ||||||
|  | static int I2C_write(I2C_TypeDef* I2Cx, uint8_t data); | ||||||
|  | static int I2C_read(I2C_TypeDef* I2Cx, uint8_t ack); | ||||||
|  | // static int I2C_timeout(char *msg);
 | ||||||
|  | static int I2C_timeout(uint8_t flag); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | NVIC_InitStructure.NVIC_IRQChannel = PeterI2C_IRQn; | ||||||
|  | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; | ||||||
|  | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; | ||||||
|  | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; | ||||||
|  | NVIC_Init(&NVIC_InitStructure); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | //===============================================================================
 | ||||||
|  | // I2C_ReadTransfer - initiate a read transfer on the I2C bus
 | ||||||
|  | //
 | ||||||
|  | // Initiates a read transfer on the I2C bus.
 | ||||||
|  | // If a register address is specified (<addressLength> != 0) a write without a stop
 | ||||||
|  | // condition will be initiated to the device to write the address, before the
 | ||||||
|  | // read is initiated.
 | ||||||
|  | // If no address if required (sequential read) <addressLength> is set to 0.
 | ||||||
|  | //-------------------------------------------------------------------------------
 | ||||||
|  | // u08 dev_addr  I2C device address
 | ||||||
|  | // u08 *buffer   pointer to the buffer to store the read data.
 | ||||||
|  | //               The buffer must be at least 'cnt' bytes long
 | ||||||
|  | // int cnt       number of bytes to read
 | ||||||
|  | // u32 ptr       register address, if required by the I2C-device
 | ||||||
|  | // u08 ptrlen    length of the register address to be written.
 | ||||||
|  | //               Valid values are 0..4
 | ||||||
|  | //-------------------------------------------------------------------------------
 | ||||||
|  | int I2C_ReadTransfer(uint8_t dev_addr, uint8_t *buffer, int cnt, uint32_t ptr, uint8_t ptrlen) | ||||||
|  | { | ||||||
|  |   int i; | ||||||
|  |   int rc = SUCCESS; | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   // parameter check
 | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   if ((buffer == 0) || (ptrlen > 4) || ((cnt | ptrlen) == 0)) | ||||||
|  |   { | ||||||
|  |     return I2C_check_dev(dev_addr); // may be used to check if device is responding
 | ||||||
|  |   } | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   // write the register address pointer to the device
 | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   if (ptrlen > 0) | ||||||
|  |   { | ||||||
|  |     rc = I2C_start(PeterI2C, dev_addr, I2C_Direction_Transmitter); | ||||||
|  |     if (rc == SUCCESS) | ||||||
|  |     { | ||||||
|  |       for (i=1; i<=ptrlen; i++) | ||||||
|  |       { | ||||||
|  |         rc |= I2C_write(PeterI2C,((ptr >>(8*(ptrlen-i))) & 0xff)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   // read data from device
 | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   if ((cnt > 0) && (rc == SUCCESS)) | ||||||
|  |   { | ||||||
|  |     if (ptrlen > 0) | ||||||
|  |     { | ||||||
|  |       rc |= I2C_restart(PeterI2C, dev_addr, I2C_Direction_Receiver); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       rc |= I2C_start(PeterI2C, dev_addr, I2C_Direction_Receiver); | ||||||
|  |     } | ||||||
|  |     if (rc == SUCCESS) | ||||||
|  |     { | ||||||
|  |       while (--cnt>0)                         // while more than one byte to read
 | ||||||
|  |       { | ||||||
|  |         *(buffer++) = I2C_read(PeterI2C, 1); // read next databyte from I2C device
 | ||||||
|  |       } | ||||||
|  |       *(buffer) = I2C_read(PeterI2C, 0);    // read last databyte from I2C device
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   I2C_stop(PeterI2C);                         // stop the transmission
 | ||||||
|  |   return rc; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //===============================================================================
 | ||||||
|  | // I2C_WriteTransfer r- initiate a write transfer on the I2C bus
 | ||||||
|  | //
 | ||||||
|  | // Initiates a write transfer on the I2C bus.
 | ||||||
|  | // If a register address is supplied it is inserted between the I2C device address
 | ||||||
|  | // and the data.
 | ||||||
|  | //-------------------------------------------------------------------------------
 | ||||||
|  | // u08 dev_addr  I2C device address
 | ||||||
|  | // u08 *buffer   pointer to the buffer to store the read data.
 | ||||||
|  | //               The buffer must be at least 'cnt' bytes long
 | ||||||
|  | // int cnt       number of bytes to read
 | ||||||
|  | // u32 ptr       register address, if required by the I2C-device
 | ||||||
|  | // u08 ptrlen    length of the register address to be written.
 | ||||||
|  | //               Valid values are 0..4
 | ||||||
|  | //-------------------------------------------------------------------------------
 | ||||||
|  | int I2C_WriteTransfer(uint8_t dev_addr, uint8_t *buffer, int cnt, uint32_t ptr, uint8_t ptrlen) | ||||||
|  | { | ||||||
|  |   int i; | ||||||
|  |   int rc = SUCCESS; | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   // parameter check
 | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   if ((buffer == 0) || (ptrlen > 4) || ((cnt | ptrlen) == 0)) | ||||||
|  |   { | ||||||
|  |     return I2C_check_dev(dev_addr); // may be used to check if device is responding
 | ||||||
|  |   } | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   rc = I2C_start(PeterI2C, dev_addr, I2C_Direction_Transmitter); | ||||||
|  |   if (rc == SUCCESS) | ||||||
|  |   { | ||||||
|  |     //---------------------------------------------------------------------------
 | ||||||
|  |     // write the register address pointer to the device
 | ||||||
|  |     //---------------------------------------------------------------------------
 | ||||||
|  |     if (ptrlen > 0) | ||||||
|  |     { | ||||||
|  |       for (i=1; i<=ptrlen; i++) | ||||||
|  |       { | ||||||
|  |         rc |= I2C_write(PeterI2C,((ptr >>(8*(ptrlen-i))) & 0xff)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     //---------------------------------------------------------------------------
 | ||||||
|  |     // write data to the device
 | ||||||
|  |     //---------------------------------------------------------------------------
 | ||||||
|  |     for (i=0; i<cnt; i++) | ||||||
|  |     { | ||||||
|  |       rc |= I2C_write(PeterI2C,*(buffer++)); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   I2C_stop(PeterI2C);                // stop the transmission
 | ||||||
|  |   return rc; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //===============================================================================
 | ||||||
|  | // Check if a device is responding with acknowledge on the given I2C-Bus address
 | ||||||
|  | //-------------------------------------------------------------------------------
 | ||||||
|  | static int I2C_check_dev(uint8_t addr) | ||||||
|  | { | ||||||
|  |   int timeout; | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   timeout = I2C_TIMEOUT; | ||||||
|  |   while(I2C_GetFlagStatus(PeterI2C, I2C_FLAG_BUSY)) | ||||||
|  |   { | ||||||
|  |     if((timeout--)==0)   // wait until I2C-Bus is not busy anymore
 | ||||||
|  |     { | ||||||
|  |       return ERROR; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   I2C_GenerateSTART(PeterI2C, ENABLE); | ||||||
|  |   timeout = I2C_TIMEOUT; | ||||||
|  |   while(!I2C_CheckEvent(PeterI2C, I2C_EVENT_MASTER_MODE_SELECT)) | ||||||
|  |   { | ||||||
|  |     if((timeout--)==0)  // wait while sending I2C-Bus START condition
 | ||||||
|  |     { | ||||||
|  |       I2C_GenerateSTOP(PeterI2C, ENABLE); | ||||||
|  |       return ERROR; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   I2C_Send7bitAddress(PeterI2C, addr, I2C_Direction_Transmitter); | ||||||
|  |   timeout = I2C_TIMEOUT; | ||||||
|  |   while(!I2C_CheckEvent(PeterI2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) | ||||||
|  |   { | ||||||
|  |     if((timeout--)==0)   // wait while sending slave address for write
 | ||||||
|  |     { | ||||||
|  |       I2C_GenerateSTOP(PeterI2C, ENABLE); | ||||||
|  |       return ERROR; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   //-----------------------------------------------------------------------------
 | ||||||
|  |   I2C_GenerateSTOP(PeterI2C, ENABLE); | ||||||
|  |   return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | // This function issues a start condition and
 | ||||||
|  | // transmits the slave address + R/W bit
 | ||||||
|  | //
 | ||||||
|  | // Parameters:
 | ||||||
|  | //  I2Cx  --> the I2C peripheral e.g. I2C1
 | ||||||
|  | //  addr  --> the 7 bit slave address
 | ||||||
|  | //  rdwr  --> the tranmission direction can be:
 | ||||||
|  | //              I2C_Direction_Tranmitter for Master transmitter mode
 | ||||||
|  | //              I2C_Direction_Receiver for Master receiver
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | static int I2C_start(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr) | ||||||
|  | { | ||||||
|  |   uint32_t timeout = (100 * I2C_TIMEOUT); | ||||||
|  |   // wait until I2C1 is not busy anymore
 | ||||||
|  |   while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)) | ||||||
|  |   { | ||||||
|  |     if((timeout--)==0) return I2C_timeout(I2C_TFLAG_BUS_BUSY);//I2C_timeout("I2C_start(): bus busy");
 | ||||||
|  |   } | ||||||
|  |   // Send I2C1 RESTART condition
 | ||||||
|  |   return I2C_restart(I2Cx, addr, rdwr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | // This function issues a restart condition and
 | ||||||
|  | // transmits the slave address + R/W bit
 | ||||||
|  | //
 | ||||||
|  | // Parameters:
 | ||||||
|  | //  I2Cx  --> the I2C peripheral e.g. I2C1
 | ||||||
|  | //  addr  --> the 7 bit slave address
 | ||||||
|  | //  rdwr  --> the tranmission direction can be:
 | ||||||
|  | //              I2C_Direction_Tranmitter for Master transmitter mode
 | ||||||
|  | //              I2C_Direction_Receiver for Master receiver
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | static int I2C_restart(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr) | ||||||
|  | { | ||||||
|  |   uint32_t timeout = I2C_TIMEOUT; | ||||||
|  |   // Send I2C1 START condition
 | ||||||
|  |   I2C_GenerateSTART(I2Cx, ENABLE); | ||||||
|  |   // wait for I2C1 EV5 --> Slave has acknowledged start condition
 | ||||||
|  |   while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) | ||||||
|  |   { | ||||||
|  |     if((timeout--)==0) return I2C_timeout(I2C_TFLAG_START_FAILED);//I2C_timeout("I2C_start(): start failed");
 | ||||||
|  |   } | ||||||
|  |   // Send slave Address for read or write
 | ||||||
|  |   I2C_Send7bitAddress(I2Cx, addr << 1, rdwr); | ||||||
|  |   //------------------------------------------------------------------------
 | ||||||
|  |   // wait for I2C1 EV6, check if Slave has acknowledged Master transmitter
 | ||||||
|  |   // or Master receiver mode, depending on the transmission direction
 | ||||||
|  |   //------------------------------------------------------------------------
 | ||||||
|  |   timeout = I2C_TIMEOUT; | ||||||
|  |   if (rdwr==I2C_Direction_Transmitter) | ||||||
|  |   { | ||||||
|  |     while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) | ||||||
|  |     { | ||||||
|  |       if((timeout--)==0) return I2C_timeout(I2C_TFLAG_NO_ACK);//I2C_timeout("I2C_start(): no acknowledge");
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   else if(rdwr==I2C_Direction_Receiver) | ||||||
|  |   { | ||||||
|  |     while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) | ||||||
|  |     { | ||||||
|  |       if((timeout--)==0) return I2C_timeout(I2C_TFLAG_NO_ACK);//I2C_timeout("I2C_start(): no acknowledge");
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | // This function transmits one byte to the slave device
 | ||||||
|  | // Parameters:
 | ||||||
|  | //    I2Cx --> the I2C peripheral e.g. I2C1
 | ||||||
|  | //    data --> the data byte to be transmitted
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | static int I2C_write(I2C_TypeDef* I2Cx, uint8_t data) | ||||||
|  | { | ||||||
|  |   uint32_t timeout = I2C_TIMEOUT; | ||||||
|  |   I2C_SendData(I2Cx, data); | ||||||
|  |   // wait for I2C1 EV8_2 --> byte has been transmitted
 | ||||||
|  |   while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) | ||||||
|  |   { | ||||||
|  |     if((timeout--)==0) return I2C_timeout(I2C_TFLAG_WRITE_FAILED);//I2C_timeout("I2C_write(): write byte failed");
 | ||||||
|  |   } | ||||||
|  |   return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | // This function reads one byte from the slave device
 | ||||||
|  | // and acknowledges the byte (requests another byte)
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | static int I2C_read(I2C_TypeDef* I2Cx, uint8_t ack) | ||||||
|  | { | ||||||
|  |   uint32_t timeout = I2C_TIMEOUT; | ||||||
|  | 
 | ||||||
|  |   // enable acknowledge of recieved data
 | ||||||
|  |   if (ack) { | ||||||
|  | 	  I2C_AcknowledgeConfig(I2Cx, ENABLE); | ||||||
|  |   } else { | ||||||
|  | 	  I2C_AcknowledgeConfig(I2Cx, DISABLE); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // wait until one byte has been received
 | ||||||
|  |   while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)) | ||||||
|  |   { | ||||||
|  |     if((timeout--)==0) return I2C_timeout(I2C_TFLAG_READ_FAILED);//I2C_timeout("I2C_read_ack(): read byte failed");
 | ||||||
|  |   } | ||||||
|  |   // read data from I2C data register and return data byte
 | ||||||
|  |   return I2C_ReceiveData(I2Cx); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | // This funtion issues a stop condition and therefore
 | ||||||
|  | // releases the bus
 | ||||||
|  | //------------------------------------------------------------------
 | ||||||
|  | static int I2C_stop(I2C_TypeDef* I2Cx) | ||||||
|  | { | ||||||
|  |   // Send I2C1 STOP Condition
 | ||||||
|  |   I2C_GenerateSTOP(I2Cx, ENABLE); | ||||||
|  |   return SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | static int I2C_timeout(char *msg) | ||||||
|  | { | ||||||
|  |   // printf("TIMEOUT: %s\n",msg);
 | ||||||
|  |   return ERROR; | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | static int I2C_timeout(uint8_t flag) | ||||||
|  | { | ||||||
|  | 	if (flag < 32) { | ||||||
|  | 		// set some debug-related shit here, like maybe light an LED, etc.
 | ||||||
|  | 		// TODO: do this
 | ||||||
|  | 	} | ||||||
|  | 	return ERROR; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | void I2C1_EV_IRQHandler(void) | ||||||
|  | { | ||||||
|  |   u32 event; | ||||||
|  |   event = I2C_GetLastEvent(I2C2); | ||||||
|  |   printf("I2C1_EV_IRQHandler(): Event=0x%08X\n",event); | ||||||
|  |   //---------------------------------------------------
 | ||||||
|  |   // todo, if I2C1 ISR mode shall be used
 | ||||||
|  |   //---------------------------------------------------
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void I2C2_EV_IRQHandler(void) | ||||||
|  | { | ||||||
|  |   u32 event; | ||||||
|  |   event = I2C_GetLastEvent(I2C2); | ||||||
|  |   printf("I2C2_EV_IRQHandler(): Event=0x%08X\n",event); | ||||||
|  |   //---------------------------------------------------
 | ||||||
|  |   // todo, if I2C2 ISR mode shall be used
 | ||||||
|  |   //---------------------------------------------------
 | ||||||
|  | } | ||||||
|  | */ | ||||||
							
								
								
									
										72
									
								
								fw_dc22_stm32l100/src/interface/peter_i2c/peter_i2c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								fw_dc22_stm32l100/src/interface/peter_i2c/peter_i2c.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | |||||||
|  | #ifndef _I2C_H | ||||||
|  | #define _I2C_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | #include "stm32l1xx_conf.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //#define I2C1_OPEN
 | ||||||
|  | #define I2C2_OPEN | ||||||
|  | 
 | ||||||
|  | #define I2C_SCL_SPEED       (200000)    // SCL in Hz
 | ||||||
|  | #define I2C_OWN_ADDR        (0x00)      // use 0x00 for master
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Definition for I2C1 | ||||||
|  |  */   | ||||||
|  | #if defined	I2C1_OPEN | ||||||
|  | 	#define PeterI2C                        I2C1 | ||||||
|  | 	#define PeterI2C_CLK                    RCC_APB1Periph_I2C1 | ||||||
|  | 	 | ||||||
|  | 	#define PeterI2C_SCL_PIN                GPIO_Pin_6 | ||||||
|  | 	#define PeterI2C_SCL_GPIO_PORT          GPIOB | ||||||
|  | 	#define PeterI2C_SCL_GPIO_CLK           RCC_AHB1Periph_GPIOB | ||||||
|  | 	#define PeterI2C_SCL_SOURCE             GPIO_PinSource6 | ||||||
|  | 	#define PeterI2C_SCL_AF                 GPIO_AF_I2C1 | ||||||
|  | 	 | ||||||
|  | 	#define PeterI2C_SDA_PIN                GPIO_Pin_9 | ||||||
|  | 	#define PeterI2C_SDA_GPIO_PORT          GPIOB | ||||||
|  | 	#define PeterI2C_SDA_GPIO_CLK           RCC_AHB1Periph_GPIOB | ||||||
|  | 	#define PeterI2C_SDA_SOURCE             GPIO_PinSource9 | ||||||
|  | 	#define PeterI2C_SDA_AF                 GPIO_AF_I2C1 | ||||||
|  | 	 | ||||||
|  | 	#define PeterI2C_IRQn                   I2C1_EV_IRQn | ||||||
|  | 	#define I2Cx_IRQHANDLER                 I2C1_EV_IRQHandler | ||||||
|  | 
 | ||||||
|  | #elif defined I2C2_OPEN | ||||||
|  |   #define PeterI2C                        I2C2 | ||||||
|  |   #define PeterI2C_CLK                    RCC_APB1Periph_I2C2 | ||||||
|  | 
 | ||||||
|  |   #define PeterI2C_SCL_PIN                GPIO_Pin_10 | ||||||
|  |   #define PeterI2C_SCL_GPIO_PORT          GPIOB | ||||||
|  |   #define PeterI2C_SCL_GPIO_CLK           RCC_AHB1Periph_GPIOB | ||||||
|  |   #define PeterI2C_SCL_SOURCE             GPIO_PinSource10 | ||||||
|  |   #define PeterI2C_SCL_AF                 GPIO_AF_I2C2 | ||||||
|  | 
 | ||||||
|  |   #define PeterI2C_SDA_PIN                GPIO_Pin_11 | ||||||
|  |   #define PeterI2C_SDA_GPIO_PORT          GPIOB | ||||||
|  |   #define PeterI2C_SDA_GPIO_CLK           RCC_AHB1Periph_GPIOB | ||||||
|  |   #define PeterI2C_SDA_SOURCE             GPIO_PinSource11 | ||||||
|  |   #define PeterI2C_SDA_AF                 GPIO_AF_I2C2 | ||||||
|  | 
 | ||||||
|  |   #define PeterI2C_IRQn                   I2C2_EV_IRQn | ||||||
|  |   #define I2Cx_IRQHANDLER                 I2C2_EV_IRQHandler | ||||||
|  | 
 | ||||||
|  | #else | ||||||
|  | 	#error "Please select the I2C-Device to be used (in i2c.h)" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define I2C_TFLAG_BUS_BUSY 				0x01 | ||||||
|  | #define I2C_TFLAG_START_FAILED			0x02 | ||||||
|  | #define I2C_TFLAG_NO_ACK 				0x04 | ||||||
|  | #define I2C_TFLAG_WRITE_FAILED 			0x08 | ||||||
|  | #define I2C_TFLAG_READ_FAILED			0x10 | ||||||
|  | 
 | ||||||
|  | int  I2C_ReadTransfer(uint8_t dev_addr, uint8_t *buffer, int cnt, uint32_t ptr, uint8_t ptrlen); | ||||||
|  | int  I2C_WriteTransfer(uint8_t dev_addr, uint8_t *buffer, int cnt, uint32_t ptr, uint8_t ptrlen); | ||||||
|  | 
 | ||||||
|  | #endif /*_I2C_H*/ | ||||||
							
								
								
									
										236
									
								
								fw_dc22_stm32l100/src/led/led_bone.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								fw_dc22_stm32l100/src/led/led_bone.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,236 @@ | |||||||
|  | /**
 | ||||||
|  |  * led_bone.c: skull crossbones led matrix handling functions | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_bone.c 373 2015-06-25 06:21:27Z true $ | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * Resources: | ||||||
|  |  * - Uses TIM11 OC1 and TIM9 OC1 and OC2 for PWM output; for frequency, see led_pwm.c | ||||||
|  |  * | ||||||
|  |  * TODO: | ||||||
|  |  * - use PWM for bone LEDs | ||||||
|  |  * - integrate with main matrix patterns somehow | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "../interface/gpio.h" | ||||||
|  | #include "../interface/led_pwm.h" | ||||||
|  | #include "../device/lightsensor.h" | ||||||
|  | 
 | ||||||
|  | #include "led_matrix.h" | ||||||
|  | #include "led_bone.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // devices
 | ||||||
|  | static TIM_TypeDef *led_bone_row_pwm[3] = {TIM11, TIM9, TIM9}; | ||||||
|  | static const tGPIO led_bone_row_gpio[3] = { | ||||||
|  | 	{GPIOA, GPIO_Pin_7, 7}, | ||||||
|  | 	{GPIOB, GPIO_Pin_13, 13}, | ||||||
|  | 	{GPIOB, GPIO_Pin_14, 14} | ||||||
|  | }; | ||||||
|  | static const tGPIO led_bone_col_gpio[3] = { | ||||||
|  | 	{GPIOB, GPIO_Pin_12, 12}, | ||||||
|  | 	{GPIOB, GPIO_Pin_15, 15}, | ||||||
|  | 	{GPIOA, GPIO_Pin_8, 8} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const uint8_t led_bone_order[8] = { | ||||||
|  | 	BONE_LED_TR_UPPER, | ||||||
|  | 	BONE_LED_TR_LOWER, | ||||||
|  | 	BONE_LED_BR_UPPER, | ||||||
|  | 	BONE_LED_BR_LOWER, | ||||||
|  | 	BONE_LED_BL_LOWER, | ||||||
|  | 	BONE_LED_BL_UPPER, | ||||||
|  | 	BONE_LED_TL_LOWER, | ||||||
|  | 	BONE_LED_TL_UPPER | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // pwm level
 | ||||||
|  | static uint8_t led_bone_mode; | ||||||
|  | static uint8_t led_level[9]; | ||||||
|  | 
 | ||||||
|  |   // led programs
 | ||||||
|  | #include "led_bone_prog.h" | ||||||
|  | static void (*led_program)(); | ||||||
|  | static void (*led_program_list[])() = { | ||||||
|  | 	led_prog_all_on, | ||||||
|  | 	led_prog_loops, | ||||||
|  | 	led_prog_updown | ||||||
|  | }; | ||||||
|  | const char led_bone_prog_name[LED_BONE_PROG_COUNT][16] = { | ||||||
|  | 	{"AllOn"}, | ||||||
|  | 	{"Loops"}, | ||||||
|  | 	{"UpDown"}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // currently lit led
 | ||||||
|  | static uint8_t led_index = 0; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | void led_bone_io_init() | ||||||
|  | { | ||||||
|  | 	uint8_t i; | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 
 | ||||||
|  | 	// configure LOW as standard outputs
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_OUT; | ||||||
|  | 	gpio.GPIO_OType = GPIO_OType_PP; | ||||||
|  | 	gpio.GPIO_Speed = GPIO_Speed_2MHz; | ||||||
|  | 
 | ||||||
|  | 	// init and set low
 | ||||||
|  | 	for (i = 0; i < 3; i++) { | ||||||
|  | 		gpio.GPIO_Pin = led_bone_col_gpio[i].pin; | ||||||
|  | 		GPIO_Init(led_bone_col_gpio[i].port, &gpio); | ||||||
|  | 		GPIO_ResetBits(led_bone_col_gpio[i].port, led_bone_col_gpio[i].pin); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// configure HIGH pins as AF
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_AF; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 3; i++) { | ||||||
|  | 		gpio.GPIO_Pin = led_bone_row_gpio[i].pin; | ||||||
|  | 		GPIO_Init(led_bone_row_gpio[i].port, &gpio); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// configure AF on these pins
 | ||||||
|  | 	GPIO_PinAFConfig(led_bone_row_gpio[0].port, led_bone_row_gpio[0].pinsource, GPIO_AF_TIM11); | ||||||
|  | 	GPIO_PinAFConfig(led_bone_row_gpio[1].port, led_bone_row_gpio[1].pinsource, GPIO_AF_TIM9); | ||||||
|  | 	GPIO_PinAFConfig(led_bone_row_gpio[2].port, led_bone_row_gpio[2].pinsource, GPIO_AF_TIM9); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_bone_io_disable() | ||||||
|  | { | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_OUT; | ||||||
|  | 	gpio.GPIO_OType = GPIO_OType_OD; | ||||||
|  | 	gpio.GPIO_PuPd = GPIO_PuPd_UP; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 3; i++) { | ||||||
|  | 		gpio.GPIO_Pin = led_bone_row_gpio[i].pin; | ||||||
|  | 		GPIO_Init(led_bone_row_gpio[i].port, &gpio); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void inline led_bone_next() | ||||||
|  | { | ||||||
|  | 	uint8_t update_col; | ||||||
|  | 	uint8_t update_row; | ||||||
|  | 	uint16_t update_scaler; | ||||||
|  | 
 | ||||||
|  | 	uint32_t update_level[3] = { | ||||||
|  | 		0, 0, 0 | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	// set active column
 | ||||||
|  | 	update_col = led_index % 3; | ||||||
|  | 
 | ||||||
|  | 	// set updated row
 | ||||||
|  | 	if (led_index < 3) { | ||||||
|  | 		update_row = 0; | ||||||
|  | 	} else if (led_index < 6) { | ||||||
|  | 		update_row = 1; | ||||||
|  | 	} else { | ||||||
|  | 		update_row = 2; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set new levels
 | ||||||
|  | 	// update_level[update_row] = *(led_level + led_index);
 | ||||||
|  | 	update_scaler = (settings.led_autoadjust & 0x80) ? lightsensor_get_scalerval(LIGHTSENS_SCALED_BONES) : 256; | ||||||
|  | 	update_level[update_row] = (led_level[led_index] * update_scaler) >> 8; | ||||||
|  | 
 | ||||||
|  | 	// disable PWM
 | ||||||
|  | 	TIM_Cmd(led_bone_row_pwm[0], DISABLE); | ||||||
|  | 	TIM_Cmd(led_bone_row_pwm[1], DISABLE); | ||||||
|  | 
 | ||||||
|  | 	// clear all columns (set high)
 | ||||||
|  | 	GPIO_SetBits(led_bone_col_gpio[0].port, led_bone_col_gpio[0].pin); | ||||||
|  | 	GPIO_SetBits(led_bone_col_gpio[1].port, led_bone_col_gpio[1].pin); | ||||||
|  | 	GPIO_SetBits(led_bone_col_gpio[2].port, led_bone_col_gpio[2].pin); | ||||||
|  | 
 | ||||||
|  | 	// set new row pwm value
 | ||||||
|  | 	led_pwm_set_oc(led_bone_row_pwm[0], &update_level[0]); 	// TIM11 has pin0
 | ||||||
|  | 	led_pwm_set_oc(led_bone_row_pwm[1], &update_level[1]); 	// TIM9 has pin1, pin2
 | ||||||
|  | 
 | ||||||
|  | 	// reset pwm counter (fixes matrix glitches)
 | ||||||
|  | 	TIM_SetCounter(led_bone_row_pwm[0], 0xff); | ||||||
|  | 	TIM_SetCounter(led_bone_row_pwm[1], 0xff); | ||||||
|  | 
 | ||||||
|  | 	// generate update event to apply pwm values
 | ||||||
|  | 	TIM_GenerateEvent(led_bone_row_pwm[0], TIM_EventSource_Update); | ||||||
|  | 	TIM_GenerateEvent(led_bone_row_pwm[1], TIM_EventSource_Update); | ||||||
|  | 
 | ||||||
|  | 	// and now set the active column (set low)
 | ||||||
|  | 	GPIO_ResetBits(led_bone_col_gpio[update_col].port, led_bone_col_gpio[update_col].pin); | ||||||
|  | 
 | ||||||
|  | 	// re-enable PWM
 | ||||||
|  | 	TIM_Cmd(led_bone_row_pwm[0], ENABLE); | ||||||
|  | 	TIM_Cmd(led_bone_row_pwm[1], ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// next led
 | ||||||
|  | 	led_index++; | ||||||
|  | 	if (led_index >= 9) { | ||||||
|  | 		led_index = 0; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_bone_set_mode(uint8_t mode) | ||||||
|  | { | ||||||
|  | 	led_bone_mode = mode; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_bone_set_program(uint8_t program_idx, uint8_t init, | ||||||
|  | 		uint16_t wait, uint16_t level, uint32_t offset, uint32_t settings) | ||||||
|  | { | ||||||
|  | 	// we need to be in program mode
 | ||||||
|  | 	led_bone_set_mode(LED_MATRIX_MODE_PROGRAM); | ||||||
|  | 	// update the program pointer
 | ||||||
|  | 	led_program = led_program_list[program_idx]; | ||||||
|  | 
 | ||||||
|  | 	// set initial program variables
 | ||||||
|  | 	led_prog_set_wait = wait; | ||||||
|  | 	led_prog_set_level = level; | ||||||
|  | 	led_prog_set_offset = offset; | ||||||
|  | 	led_prog_set_option = settings; | ||||||
|  | 
 | ||||||
|  | 	// is this a new set? if so, initialize program parameters
 | ||||||
|  | 	if (init) { | ||||||
|  | 		uint8_t i; | ||||||
|  | 
 | ||||||
|  | 		led_prog_wait = 0; | ||||||
|  | 		for (i = 0; i < 4; i++) { | ||||||
|  | 			led_prog_state[i] = 0; | ||||||
|  | 			led_prog_work[i] = 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_bone_mode_update() | ||||||
|  | { | ||||||
|  | 	uint8_t i; | ||||||
|  | 
 | ||||||
|  | 	switch (led_bone_mode) { | ||||||
|  | 		case LED_MATRIX_MODE_PROGRAM: { | ||||||
|  | 			// if we have a valid program loaded, run it
 | ||||||
|  | 			if (led_program != NULL) { | ||||||
|  | 				led_program(); | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case LED_MATRIX_MODE_OFF: { | ||||||
|  | 			led_program = NULL; | ||||||
|  | 			for (i = 0; i < 9; i++) { | ||||||
|  | 				led_level[i] = 0; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								fw_dc22_stm32l100/src/led/led_bone.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								fw_dc22_stm32l100/src/led/led_bone.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | /**
 | ||||||
|  |  * led_bone.h: skull crossbones led matrix handling prototypes | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_bone.h 364 2015-06-12 04:44:55Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_LED_BONE_H | ||||||
|  | #define __PIRATE_LED_BONE_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* struct */ | ||||||
|  | typedef struct LEDBonePattern { | ||||||
|  | 	uint16_t wait; | ||||||
|  | 	uint8_t led[9]; | ||||||
|  | } LEDBonePattern; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* constants */ | ||||||
|  | #define LED_BONE_PROG_COUNT 3 | ||||||
|  | #define LED_BONE_PTRN_COUNT 0 | ||||||
|  | 
 | ||||||
|  | /* led positions */ | ||||||
|  | #define BONE_LED_BR_LOWER	0 | ||||||
|  | #define BONE_LED_TR_LOWER	1 | ||||||
|  | #define BONE_LED_BR_UPPER	3 | ||||||
|  | #define BONE_LED_TL_UPPER	4 | ||||||
|  | #define BONE_LED_TL_LOWER	5 | ||||||
|  | #define BONE_LED_TR_UPPER	6 | ||||||
|  | #define BONE_LED_BL_UPPER	7 | ||||||
|  | #define BONE_LED_BL_LOWER	8 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* variables */ | ||||||
|  | extern const char led_bone_prog_name[LED_BONE_PROG_COUNT][16]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void led_bone_io_init(); | ||||||
|  | void led_bone_io_disable(); | ||||||
|  | void led_bone_next(); | ||||||
|  | 
 | ||||||
|  | void led_bone_mode_update(); | ||||||
|  | void led_bone_set_mode(uint8_t mode); 	// used for turning off
 | ||||||
|  | void led_bone_set_program(uint8_t program_idx, uint8_t init, | ||||||
|  | 		uint16_t wait, uint16_t level, uint32_t offset, uint32_t settings); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										43
									
								
								fw_dc22_stm32l100/src/led/led_bone_pattern.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								fw_dc22_stm32l100/src/led/led_bone_pattern.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | /**
 | ||||||
|  |  * led_bone.c: skull crossbones led matrix fixed patterns | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_bone_pattern.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | // LEDs are in this arrangement:
 | ||||||
|  | // W-BR W-TR xxxx
 | ||||||
|  | // P-BR P-TL W-TL
 | ||||||
|  | // P-TR P-BL W-BL
 | ||||||
|  | 
 | ||||||
|  |   // all on 100%
 | ||||||
|  | static const LEDBonePattern led_pattern_01[] = { | ||||||
|  | 	{1000, {0xff, 0xff, 0x00, | ||||||
|  | 			0xff, 0xff, 0xff, | ||||||
|  | 			0xff, 0xff, 0xff}}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // all on 50%
 | ||||||
|  | static const LEDBonePattern led_pattern_02[] = { | ||||||
|  | 	{1000, {0x33, 0x33, 0x00, | ||||||
|  | 			0x33, 0x33, 0x33, | ||||||
|  | 			0x33, 0x33, 0x33}}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // all on, white matching apparent purple 100% brightness
 | ||||||
|  | static const LEDBonePattern led_pattern_03[] = { | ||||||
|  | 	{1000, {0x10, 0x10, 0x00, | ||||||
|  | 			0x10, 0x10, 0x10, | ||||||
|  | 			0x10, 0x10, 0x10}}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // pattern count - make sure this is updated with the amount
 | ||||||
|  |   // of entries in the patterns above!
 | ||||||
|  | static uint8_t led_pattern_size[] = { | ||||||
|  | 	1, | ||||||
|  | 	1, | ||||||
|  | 	1 | ||||||
|  | }; | ||||||
							
								
								
									
										143
									
								
								fw_dc22_stm32l100/src/led/led_bone_prog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								fw_dc22_stm32l100/src/led/led_bone_prog.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,143 @@ | |||||||
|  | /**
 | ||||||
|  |  * led_bone.c: skull crossbones led matrix fixed patterns | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_bone_prog.h 364 2015-06-12 04:44:55Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | static uint16_t led_prog_wait; 		// used by function to keep track of iteration time
 | ||||||
|  | static uint32_t led_prog_state[4]; 	// used by the function to keep track of lit LEDs, state
 | ||||||
|  | static uint32_t led_prog_work[4]; 		// used for misc shit
 | ||||||
|  | 
 | ||||||
|  | static uint16_t led_prog_set_wait; 	// used by setter function to set iteration time in ms
 | ||||||
|  | static uint16_t led_prog_set_level;	// used by setter function to set desired level
 | ||||||
|  | static uint32_t led_prog_set_offset;	// used by setter function to set desired offset
 | ||||||
|  | static uint32_t led_prog_set_option;	// used by setter to set options
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* programs */ | ||||||
|  | static void led_prog_all_on() | ||||||
|  | { | ||||||
|  | 	uint8_t i; | ||||||
|  | 
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		led_prog_wait = 50; | ||||||
|  | 
 | ||||||
|  | 		for (i = 0; i < 9; i++) { | ||||||
|  | 			led_level[i] = led_prog_set_level & 0xff; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * around the bones in a loop program | ||||||
|  |  * speed: 	set as desired | ||||||
|  |  * options: bit 2 = direction (0 = clockwise, 1 = counter-clockwise), | ||||||
|  |  * 			bit 4 = decay trails faster, bit 5 = decay trails even faster, | ||||||
|  |  *          bit 6 = trails enable | ||||||
|  |  *********/ | ||||||
|  | static void led_prog_loops() | ||||||
|  | { | ||||||
|  | 	uint8_t i; | ||||||
|  | 
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		// load new timer wait value
 | ||||||
|  | 		led_prog_wait = led_prog_set_wait * 5; | ||||||
|  | 
 | ||||||
|  | 		// first run?
 | ||||||
|  | 		if (!led_prog_state[3]) { | ||||||
|  | 			// store starting offset
 | ||||||
|  | 			led_prog_state[0] = led_prog_set_offset & 0x07; | ||||||
|  | 
 | ||||||
|  | 			// reset levels
 | ||||||
|  | 			for (i = 0; i < 9; i++) { | ||||||
|  | 				led_level[i] = 0; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			led_prog_state[3] = 1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// set decay rate (LED PWM active values are right shifted by this value)
 | ||||||
|  | 		led_prog_work[0] = 1; | ||||||
|  | 		if (led_prog_set_option & BIT_4) led_prog_work[0]++; | ||||||
|  | 		if (led_prog_set_option & BIT_5) led_prog_work[0] += 2; | ||||||
|  | 
 | ||||||
|  | 		for (i = 0; i < 8; i++) { | ||||||
|  | 			if (i == led_prog_state[0]) { | ||||||
|  | 				// LED is next in line so turn it on
 | ||||||
|  | 				led_level[led_bone_order[i]] = led_prog_set_level & 0xff; | ||||||
|  | 			} else { | ||||||
|  | 				// LED is not on so decay or turn off
 | ||||||
|  | 				led_level[led_bone_order[i]] = (led_prog_set_option & BIT_6) ? | ||||||
|  | 						led_level[led_bone_order[i]] >> led_prog_work[0] : 0; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// update state with next LED
 | ||||||
|  | 		led_prog_state[0] += (led_prog_set_option & BIT_2) ? 7 : 1; | ||||||
|  | 		led_prog_state[0] &= 0x07; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * sweeping up and down symetically | ||||||
|  |  * speed: 	set as desired | ||||||
|  |  * options: bit 4 = decay trails faster, bit 5 = decay trails even faster, | ||||||
|  |  *          bit 6 = trails enable | ||||||
|  |  *********/ | ||||||
|  | void led_prog_updown() | ||||||
|  | { | ||||||
|  | 	uint8_t i; | ||||||
|  | 
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		// load new timer wait value
 | ||||||
|  | 		led_prog_wait = led_prog_set_wait * 5; | ||||||
|  | 
 | ||||||
|  | 		// first run?
 | ||||||
|  | 		if (!led_prog_state[3]) { | ||||||
|  | 			// store starting offset
 | ||||||
|  | 			led_prog_state[0] = led_prog_set_offset & 0x07; | ||||||
|  | 
 | ||||||
|  | 			// reset levels
 | ||||||
|  | 			for (i = 0; i < 9; i++) { | ||||||
|  | 				led_level[i] = 0; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			led_prog_state[3] = 1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// set decay rate (LED PWM active values are right shifted by this value)
 | ||||||
|  | 		led_prog_work[0] = 1; | ||||||
|  | 		if (led_prog_set_option & BIT_4) led_prog_work[0] = 2; | ||||||
|  | 		if (led_prog_set_option & BIT_5) led_prog_work[0] += 2; | ||||||
|  | 
 | ||||||
|  | 		led_prog_work[1] = led_prog_state[0] >= 4 ? 7 - led_prog_state[0] : led_prog_state[0]; | ||||||
|  | 
 | ||||||
|  | 		for (i = 0; i < 4; i++) { | ||||||
|  | 			if (i == led_prog_work[1]) { | ||||||
|  | 				// LED is next in line so turn it on
 | ||||||
|  | 				led_level[led_bone_order[i]] = led_prog_set_level & 0xff; | ||||||
|  | 			} else { | ||||||
|  | 				// LED is not on so decay or turn off
 | ||||||
|  | 				led_level[led_bone_order[i]] = (led_prog_set_option & BIT_6) ? | ||||||
|  | 						led_level[led_bone_order[i]] >> led_prog_work[0] : 0; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			led_level[led_bone_order[7 - i]] = led_level[led_bone_order[i]]; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// update state with next LED
 | ||||||
|  | 		led_prog_state[0] += (led_prog_set_option & BIT_2) ? 7 : 1; | ||||||
|  | 		led_prog_state[0] &= 0x07; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
							
								
								
									
										295
									
								
								fw_dc22_stm32l100/src/led/led_eyes_prog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										295
									
								
								fw_dc22_stm32l100/src/led/led_eyes_prog.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,295 @@ | |||||||
|  | /*
 | ||||||
|  |  * led_eyes_prog.h: programs for the RGBLED eyes | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_eyes_prog.h 375 2015-07-06 02:52:40Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | uint16_t led_prog_wait; 		// used by function to keep track of iteration time
 | ||||||
|  | uint32_t led_prog_state[4]; 	// used by the function to keep track of lit LEDs, state
 | ||||||
|  | uint32_t led_prog_work[4]; 		// used for misc shit
 | ||||||
|  | 
 | ||||||
|  | uint16_t led_prog_set_wait; 	// used by setter function to set iteration time in ms
 | ||||||
|  | uint16_t led_prog_set_level;	// used by setter function to set desired level
 | ||||||
|  | uint32_t led_prog_set_offset;	// used by setter function to set desired offset
 | ||||||
|  | uint32_t led_prog_set_option;	// used by setter to set options
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* programs */ | ||||||
|  | /********
 | ||||||
|  |  * candle flicker | ||||||
|  |  * option sets the color mix; each 8 bits set the mix level in RGBx | ||||||
|  |  *     (so 0xff0000?? would be red, etc) | ||||||
|  |  * xx option bits determine if independent (1 = yes, 0 = no) | ||||||
|  | *********/ | ||||||
|  | static void led_prog_candle_flicker() | ||||||
|  | { | ||||||
|  | 	static const uint8_t lookup[] = {20, 52, 84, 116, 148, 184, 220, 255}; | ||||||
|  | 	uint32_t rand = 0; | ||||||
|  | 	uint8_t new_val[3]; | ||||||
|  | 
 | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	// ideally we want to update flicker at about 454.54hz (as close to 440hz as we can get) = 11
 | ||||||
|  | 	// I don't know where I read this so let's just update LEDs less often because it looks nicer
 | ||||||
|  | 
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		led_prog_wait = 45; | ||||||
|  | 
 | ||||||
|  | 		// set which LED to update if in alternating mode
 | ||||||
|  | 		led_prog_state[0] = led_prog_state[0] ? 0 : 1; | ||||||
|  | 
 | ||||||
|  | 		rand = pirate_prng() & 0x1f; | ||||||
|  | 		rand = (rand > 7) ? lookup[7] : lookup[rand]; | ||||||
|  | 
 | ||||||
|  | 		// create scaled value
 | ||||||
|  | 		new_val[0] = ((led_prog_set_option >> 24)); | ||||||
|  | 		new_val[1] = ((led_prog_set_option >> 16) & 0xff); | ||||||
|  | 		new_val[2] = ((led_prog_set_option >>  8) & 0xff); | ||||||
|  | 
 | ||||||
|  | 		for (i = 0; i < 3; i++) { | ||||||
|  | 			new_val[i] = (rand * new_val[i]) >> 8; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// update LED values
 | ||||||
|  | 		if (led_prog_set_option & 1) { | ||||||
|  | 			led_level[led_prog_state[0]][0] = new_val[0]; | ||||||
|  | 			led_level[led_prog_state[0]][1] = new_val[1]; | ||||||
|  | 			led_level[led_prog_state[0]][2] = new_val[2]; | ||||||
|  | 		} else { | ||||||
|  | 			led_level[0][0] = led_level[1][0] = new_val[0]; | ||||||
|  | 			led_level[0][1] = led_level[1][1] = new_val[1]; | ||||||
|  | 			led_level[0][2] = led_level[1][2] = new_val[2]; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void led_prog_candle_flicker_favcolor() | ||||||
|  | { | ||||||
|  | 	led_prog_set_option = settings.fav_color[0] << 24 | settings.fav_color[1] << 16 | | ||||||
|  | 			settings.fav_color[2] << 8 | (led_prog_set_option & 0x01); | ||||||
|  | 
 | ||||||
|  | 	led_prog_candle_flicker(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * static led or random led flasher | ||||||
|  |  * option sets the color mix; each 8 bits set the mix level in RGBx | ||||||
|  |  *     (so 0xff0000?? would be red, etc) | ||||||
|  |  * low bit of option sets LEDs in independent mode (1 = yes, 0 = no) | ||||||
|  |  * offset sets the flash color mix | ||||||
|  |  * low 8 bits of offset set the threshold of the flasher (0x00=always, 0xff=never) | ||||||
|  |  * having eyes on while set to always activate will simply alternate the LEDs | ||||||
|  | *********/ | ||||||
|  | static void led_prog_randflasher() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		led_prog_wait = led_prog_set_wait * 5; | ||||||
|  | 
 | ||||||
|  | 		// set which LED to operate
 | ||||||
|  | 		led_prog_state[0] = led_prog_state[0] ? 0 : 1; | ||||||
|  | 
 | ||||||
|  | 		// set background levels on all LEDs
 | ||||||
|  | 		for (i = 0; i < 2; i++) { | ||||||
|  | 			led_level[i][0] = ((led_prog_set_option >> 24)); | ||||||
|  | 			led_level[i][1] = ((led_prog_set_option >> 16) & 0xff); | ||||||
|  | 			led_level[i][2] = ((led_prog_set_option >>  8) & 0xff); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// set flash
 | ||||||
|  | 		if (pirate_prng() > (led_prog_set_offset & 0xff)) { | ||||||
|  | 			if (!(led_prog_set_option & BIT_0) || (led_prog_state[0] == 0)) { | ||||||
|  | 				led_level[0][0] = ((led_prog_set_offset >> 24)); | ||||||
|  | 				led_level[0][1] = ((led_prog_set_offset >> 16) & 0xff); | ||||||
|  | 				led_level[0][2] = ((led_prog_set_offset >>  8) & 0xff); | ||||||
|  | 			} | ||||||
|  | 			if (!(led_prog_set_option & BIT_0) || (led_prog_state[0] == 1)) { | ||||||
|  | 				led_level[1][0] = ((led_prog_set_offset >> 24)); | ||||||
|  | 				led_level[1][1] = ((led_prog_set_offset >> 16) & 0xff); | ||||||
|  | 				led_level[1][2] = ((led_prog_set_offset >>  8) & 0xff); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * mic spl meter | ||||||
|  |  * level: sets the threshold scaler. 0xff = 100 is max, 0x80 = 50 is max, and so on | ||||||
|  |  * offset: sets the cold (0%) color, see above for format | ||||||
|  |  * option: sets the hot (100%) color, see above for format | ||||||
|  |  * last 7 bits of option sets how fast the ramping up is | ||||||
|  |  * last 7 bits of offset sets how fast the ramping down is | ||||||
|  |  *********/ | ||||||
|  | static void led_prog_mic_spl() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		led_prog_wait = led_prog_set_wait * 5; | ||||||
|  | 
 | ||||||
|  | 		// first run?
 | ||||||
|  | 		if (led_prog_set_option & 0x80) { | ||||||
|  | 			led_prog_work[0] = 0; | ||||||
|  | 			led_prog_set_option |= 0x80; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// speed is set?
 | ||||||
|  | 		if (!(led_prog_set_option & 0x7f)) { | ||||||
|  | 			led_prog_set_option |= 0x0f; | ||||||
|  | 		} | ||||||
|  | 		if (!(led_prog_set_offset & 0x7f)) { | ||||||
|  | 			led_prog_set_offset |= 0x01; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// set our value
 | ||||||
|  | 		if (mic_peak > led_prog_work[0]) { | ||||||
|  | 			led_prog_work[0] += led_prog_set_option & 0xff; | ||||||
|  | 			if (led_prog_work[0] > mic_peak) led_prog_work[0] = mic_peak; | ||||||
|  | 		} else { | ||||||
|  | 			led_prog_work[0] -= led_prog_set_offset & 0xff; | ||||||
|  | 			if (led_prog_work[0] < mic_peak) led_prog_work[0] = mic_peak; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// make it a percentage
 | ||||||
|  | 		led_prog_work[1] = pirate_scale(led_prog_work[0], settings.mic_cal[0], settings.mic_cal[1], 0, 255); | ||||||
|  | 
 | ||||||
|  | 		// scale value
 | ||||||
|  | 		led_prog_state[0] = pirate_scale(led_prog_work[1], (led_prog_set_level >> 8), (led_prog_set_level & 0xff), 0, 248); | ||||||
|  | 
 | ||||||
|  | 		// scale hot/cold levels on LEDs
 | ||||||
|  | 		for (i = 0; i < 3; i++) { | ||||||
|  | 			led_level[0][i] = led_level[1][i] = pirate_scale(led_prog_state[0], 0, 248, | ||||||
|  | 					((led_prog_set_offset >> ((3 - i) << 3)) & 0xff), | ||||||
|  | 					((led_prog_set_option >> ((3 - i) << 3)) & 0xff)); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * color fader, rgb | ||||||
|  |  * starts out blank right now | ||||||
|  |  * level does nothing right now | ||||||
|  |  * option sets the order and mix, for each half byte (0x01=red, 0x02=blue, 0x04=grn, 0x08=rampdown) | ||||||
|  |  *     (order is LS to MS) - | ||||||
|  |  *     0x8 = stop pattern (go to beginning) | ||||||
|  |  *     0x9-0xF = 0x1-0x7 except other colors must finish dimming | ||||||
|  |  * offset sets the lag in the right eye, but this doesn't work right now, so just inverts | ||||||
|  |  * | ||||||
|  |  *********/ | ||||||
|  | static void led_prog_fader() | ||||||
|  | { | ||||||
|  | 	uint32_t bitshift; | ||||||
|  | 	uint32_t bitfield; | ||||||
|  | 	uint8_t nextstep; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		led_prog_wait = led_prog_set_wait * 5; | ||||||
|  | 
 | ||||||
|  | 		// first run?
 | ||||||
|  | 		if (!led_prog_state[3]) { | ||||||
|  | 			led_prog_work[0] = 0; | ||||||
|  | 			led_prog_work[1] = 0; | ||||||
|  | 			led_prog_work[2] = 0; | ||||||
|  | 			led_prog_state[0] = 0; | ||||||
|  | 			led_prog_state[1] = led_prog_set_offset; | ||||||
|  | 			led_prog_state[3] = 1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// figure out what colors to manipulate for the left eye
 | ||||||
|  | 		bitshift = (led_prog_state[0] << 2); | ||||||
|  | 		bitfield = (led_prog_set_option >> bitshift) & 0xF; | ||||||
|  | 
 | ||||||
|  | 		// is this a reset instruction?
 | ||||||
|  | 		if (bitfield == 0x8) { | ||||||
|  | 			// start over
 | ||||||
|  | 			led_prog_state[0] = 0; | ||||||
|  | 			bitfield = led_prog_set_option & 0xF; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// is this a require-clearing instruction?
 | ||||||
|  | 		if (bitfield & 0x8) { | ||||||
|  | 			//copy inverse of low nybble to high nybble
 | ||||||
|  | 			bitfield |= (~(bitfield & 0xf)) << 4; | ||||||
|  | 			// clear high bits in each nybble if set
 | ||||||
|  | 			bitfield &= 0x77; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		nextstep = 0; | ||||||
|  | 
 | ||||||
|  | 		// and manipulate (fade) them
 | ||||||
|  | 		if (bitfield) { | ||||||
|  | 			if (bitfield >> 4) { 						// fade-down bit set
 | ||||||
|  | 				for (i = 0; i <= 2; i++) { | ||||||
|  | 					if ((bitfield >> 4) & (1 << i)) { 	// config bit unset (set here)
 | ||||||
|  | 						if (led_prog_work[i]) { | ||||||
|  | 							led_prog_work[i]--; 		// means fade down for unused channels
 | ||||||
|  | 						} else { | ||||||
|  | 							nextstep |= (1 << (i + 4)); // and signal when we are done with this channel
 | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			for (i = 0; i <= 2; i++) { | ||||||
|  | 				if (bitfield & (1 << i)) { 				// low bit set, normal fade-up addition
 | ||||||
|  | 					if (led_prog_work[i] < 255) { | ||||||
|  | 						led_prog_work[i]++; | ||||||
|  | 					} else { | ||||||
|  | 						nextstep |= (1 << i); 			// all the way up? signal we're done
 | ||||||
|  | 					} | ||||||
|  | 				} else if (!(bitfield & 0x8) && led_prog_work[i]) { | ||||||
|  | 					led_prog_work[i]--; 				// neither high nor low set? fade down
 | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// figure out delay for right eye
 | ||||||
|  | 		if (led_prog_state[1]) { | ||||||
|  | 			led_prog_state[1]--; | ||||||
|  | 		} else { | ||||||
|  | 			// ok, delay is done, we can start manipulating the right eye
 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// special task for forcing all outputs to 0
 | ||||||
|  | 		if (!bitfield) { | ||||||
|  | 			// if unset, then we need to dim down to nothing
 | ||||||
|  | 			for (i = 0; i <= 2; i++) { | ||||||
|  | 				if (led_prog_work[i] & 0xff) { | ||||||
|  | 					led_prog_work[i]--; | ||||||
|  | 				} else { | ||||||
|  | 					nextstep++; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (nextstep == 3) { | ||||||
|  | 				led_prog_state[0]++; | ||||||
|  | 				led_prog_state[0] %= 8; | ||||||
|  | 			} | ||||||
|  | 		} else if (nextstep == bitfield) { | ||||||
|  | 			// all of our LEDs are set to level, we can proceed to the next step
 | ||||||
|  | 			led_prog_state[0]++; | ||||||
|  | 			led_prog_state[0] %= 8; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// actually set LEDs
 | ||||||
|  | 		for (i = 0; i <= 2; i++) { | ||||||
|  | 			led_level[0][i] =  led_prog_work[i]       & 0xff; | ||||||
|  | 			//led_level[1][i] = (led_prog_work[i] >> 8) & 0xff;
 | ||||||
|  | 			led_level[1][i] = led_prog_set_offset ? ~led_prog_work[i] : led_prog_work[i]; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
							
								
								
									
										238
									
								
								fw_dc22_stm32l100/src/led/led_matrix.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								fw_dc22_stm32l100/src/led/led_matrix.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,238 @@ | |||||||
|  | /*
 | ||||||
|  |  * led_matrix.c: main skull led matrix handling functions | ||||||
|  |  * 3414 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_matrix.c 373 2015-06-25 06:21:27Z true $ | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * Resources: | ||||||
|  |  * - Uses TIM2 and TIM3 as PWM output; for frequency, see led_pwm.c | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "../interface/gpio.h" | ||||||
|  | #include "../interface/led_pwm.h" | ||||||
|  | #include "../device/lightsensor.h" | ||||||
|  | 
 | ||||||
|  | #include "led_matrix.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // pwm devices
 | ||||||
|  | TIM_TypeDef *led_pwm[2] 			= {TIM2, TIM3}; | ||||||
|  | 
 | ||||||
|  |   // pwm pins
 | ||||||
|  |   // order is 0=white, 1=purple. row=high, col=low
 | ||||||
|  | GPIO_TypeDef *led_row_port[2] 		= {GPIOA, GPIOC}; | ||||||
|  | uint16_t led_row_pin_mask[2] 		= {0x000f, 0x03c0}; | ||||||
|  | const uint8_t led_row_pin_low[2] 	= {0, 6}; | ||||||
|  | 
 | ||||||
|  | GPIO_TypeDef *led_col_port[2] 		= {GPIOC, GPIOC}; | ||||||
|  | uint16_t led_col_pin_mask[2] 		= {0xf000, 0x003c}; | ||||||
|  | const uint8_t led_col_pin_low[2] 	= {12, 2}; | ||||||
|  | 
 | ||||||
|  |   // led mode
 | ||||||
|  | uint8_t led_matrix_mode; | ||||||
|  | 
 | ||||||
|  |   // led brightness
 | ||||||
|  | uint8_t led_level[2][16]; | ||||||
|  | 
 | ||||||
|  |   // led programs
 | ||||||
|  | #include "led_matrix_prog.h" | ||||||
|  | static void (*led_program)(); | ||||||
|  | static void (*led_program_list[])() = { | ||||||
|  | 	led_prog_debug, | ||||||
|  | 	led_prog_loops, | ||||||
|  | 	led_prog_loops_mic, | ||||||
|  | 	led_prog_loops_rotate, | ||||||
|  | 	led_prog_rand_on_rand_off, | ||||||
|  | 	led_prog_mic_spl_meter | ||||||
|  | }; | ||||||
|  | const char led_matrix_prog_name[LED_MATRIX_PROG_COUNT][16] = { | ||||||
|  | 	{"Debug"}, | ||||||
|  | 	{"Loops"}, | ||||||
|  | 	{"Loops+Mic"}, | ||||||
|  | 	{"Loops+Rotate"}, | ||||||
|  | 	{"Random"}, | ||||||
|  | 	{"SPLMeter"}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // currently lit LED
 | ||||||
|  | static uint8_t led_index; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | void led_matrix_io_init() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 
 | ||||||
|  | 	// configure LOW as standard outputs
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_OUT; | ||||||
|  | 	gpio.GPIO_OType = GPIO_OType_PP; | ||||||
|  | 	gpio.GPIO_Speed = GPIO_Speed_10MHz; | ||||||
|  | 
 | ||||||
|  | 	gpio.GPIO_Pin = led_col_pin_mask[0]; | ||||||
|  | 	GPIO_Init(led_col_port[0], &gpio); | ||||||
|  | 
 | ||||||
|  | 	gpio.GPIO_Pin = led_col_pin_mask[1]; | ||||||
|  | 	GPIO_Init(led_col_port[1], &gpio); | ||||||
|  | 
 | ||||||
|  | 	// and set low
 | ||||||
|  | 	GPIO_ResetBits(led_col_port[0], led_col_pin_mask[0]); | ||||||
|  | 	GPIO_ResetBits(led_col_port[1], led_col_pin_mask[1]); | ||||||
|  | 
 | ||||||
|  | 	// configure HIGH pins as AF
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_AF; | ||||||
|  | 
 | ||||||
|  | 	gpio.GPIO_Pin = led_row_pin_mask[0]; | ||||||
|  | 	GPIO_Init(led_row_port[0], &gpio); | ||||||
|  | 
 | ||||||
|  | 	gpio.GPIO_Pin = led_row_pin_mask[1]; | ||||||
|  | 	GPIO_Init(led_row_port[1], &gpio); | ||||||
|  | 
 | ||||||
|  | 	// set AF on HIGH pins
 | ||||||
|  | 	for (i = 0; i < 4; i++) { | ||||||
|  | 		GPIO_PinAFConfig(led_row_port[0], led_row_pin_low[0] + i, GPIO_AF_TIM2); | ||||||
|  | 		GPIO_PinAFConfig(led_row_port[1], led_row_pin_low[1] + i, GPIO_AF_TIM3); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// MAKE SURE to enable PWM for these to work!
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_matrix_io_disable() | ||||||
|  | { | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_OUT; | ||||||
|  | 	gpio.GPIO_OType = GPIO_OType_OD; | ||||||
|  | 	gpio.GPIO_PuPd = GPIO_PuPd_UP; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 4; i++) { | ||||||
|  | 		gpio.GPIO_Pin = led_row_pin_low[0] + i; | ||||||
|  | 		GPIO_Init(led_row_port[0], &gpio); | ||||||
|  | 		gpio.GPIO_Pin = led_row_pin_low[1] + i; | ||||||
|  | 		GPIO_Init(led_row_port[1], &gpio); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void inline led_matrix_next() | ||||||
|  | { | ||||||
|  | 	uint32_t update_col; | ||||||
|  | 	uint32_t update_row; | ||||||
|  | 	uint16_t update_scaler; | ||||||
|  | 	uint32_t update_level[2][4] = { | ||||||
|  | 		//{0xff, 0xff, 0xff, 0xff},
 | ||||||
|  | 		//{0xff, 0xff, 0xff, 0xff}
 | ||||||
|  | 		{0x100, 0x100, 0x100, 0x100}, | ||||||
|  | 		{0x100, 0x100, 0x100, 0x100} | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	// set next index
 | ||||||
|  | 	led_index++; | ||||||
|  | 	led_index &= 0x0f; | ||||||
|  | 
 | ||||||
|  | 	// set active column
 | ||||||
|  | 	update_col = led_index % 4; | ||||||
|  | 	update_row = led_index >> 2; | ||||||
|  | 
 | ||||||
|  | 	// set new levels
 | ||||||
|  | 	update_scaler = (settings.led_autoadjust & 0x80) ? lightsensor_get_scalerval(LIGHTSENS_SCALED_SKULL_WHT) : 256; | ||||||
|  | 	update_level[0][update_row] = 0x100 - ((led_level[0][led_index] * update_scaler) >> 8); | ||||||
|  | 	update_scaler = (settings.led_autoadjust & 0x80) ? lightsensor_get_scalerval(LIGHTSENS_SCALED_SKULL_PUR) : 256; | ||||||
|  | 	update_level[1][update_row] = 0x100 - ((led_level[1][led_index] * update_scaler) >> 8); | ||||||
|  | 
 | ||||||
|  | 	// updating the matrix is glitchy as best and I know I am doing something wrong here.
 | ||||||
|  | 	// but this is the best I could come up with while sleep-deprived forceful debugging.
 | ||||||
|  | 	// disable PWM
 | ||||||
|  | 	TIM_Cmd(led_pwm[0], DISABLE); | ||||||
|  | 	TIM_Cmd(led_pwm[1], DISABLE); | ||||||
|  | 
 | ||||||
|  | 	// set new PWM value for the active row
 | ||||||
|  | 	led_pwm_set_oc(led_pwm[0], update_level[0]); | ||||||
|  | 	led_pwm_set_oc(led_pwm[1], update_level[1]); | ||||||
|  | 
 | ||||||
|  | 	// reset pwm counter (fixes matrix glitches)
 | ||||||
|  | 	TIM_SetCounter(led_pwm[0], 0xff); | ||||||
|  | 	TIM_SetCounter(led_pwm[1], 0xff); | ||||||
|  | 
 | ||||||
|  | 	// generate update event to apply pwm values
 | ||||||
|  | 	TIM_GenerateEvent(led_pwm[0], TIM_EventSource_Update); | ||||||
|  | 	TIM_GenerateEvent(led_pwm[1], TIM_EventSource_Update); | ||||||
|  | 
 | ||||||
|  | 	// clear all columns
 | ||||||
|  | 	// we do this after setting PWM to fix glitchy other LEDs lighting
 | ||||||
|  | 	GPIO_ResetBits(led_col_port[0], led_col_pin_mask[0]); | ||||||
|  | 	GPIO_ResetBits(led_col_port[1], led_col_pin_mask[1]); | ||||||
|  | 
 | ||||||
|  | 	// and now set the active column
 | ||||||
|  | 	GPIO_SetBits(led_col_port[0], (1 << (led_col_pin_low[0] + update_col))); | ||||||
|  | 	GPIO_SetBits(led_col_port[1], (1 << (led_col_pin_low[1] + update_col))); | ||||||
|  | 
 | ||||||
|  | 	// re-enable PWM
 | ||||||
|  | 	TIM_Cmd(led_pwm[0], ENABLE); | ||||||
|  | 	TIM_Cmd(led_pwm[1], ENABLE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_matrix_set_mode(uint8_t mode) | ||||||
|  | { | ||||||
|  | 	led_matrix_mode = mode; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_matrix_set_program(uint8_t program_idx, uint8_t init, | ||||||
|  | 		uint16_t wait, uint16_t level, uint32_t offset, uint32_t settings) | ||||||
|  | { | ||||||
|  | 	// we need to be in program mode
 | ||||||
|  | 	led_matrix_set_mode(LED_MATRIX_MODE_PROGRAM); | ||||||
|  | 	// update the program pointer
 | ||||||
|  | 	led_program = led_program_list[program_idx]; | ||||||
|  | 
 | ||||||
|  | 	// set initial program variables
 | ||||||
|  | 	led_prog_set_wait = wait; | ||||||
|  | 	led_prog_set_level = level; | ||||||
|  | 	led_prog_set_offset = offset; | ||||||
|  | 	led_prog_set_option = settings; | ||||||
|  | 
 | ||||||
|  | 	// is this a new set? if so, initialize program parameters
 | ||||||
|  | 	if (init) { | ||||||
|  | 		int i; | ||||||
|  | 
 | ||||||
|  | 		led_prog_wait = 0; | ||||||
|  | 		for (i = 0; i < 4; i++) { | ||||||
|  | 			led_prog_state[i] = 0; | ||||||
|  | 			led_prog_work[i] = 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t led_matrix_get_mode() | ||||||
|  | { | ||||||
|  | 	return led_matrix_mode; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void led_matrix_mode_update() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	switch (led_matrix_mode) { | ||||||
|  | 		case LED_MATRIX_MODE_PROGRAM: { | ||||||
|  | 			// if we have a valid program loaded, run it
 | ||||||
|  | 			if (led_program != NULL) { | ||||||
|  | 				led_program(); | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case LED_MATRIX_MODE_OFF: { | ||||||
|  | 			led_program = NULL; | ||||||
|  | 			for (i = 0; i < 16; i++) { | ||||||
|  | 				led_level[LED_MATRIX_WHITE][i] = 0; | ||||||
|  | 				led_level[LED_MATRIX_PURPLE][i] = 0; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										52
									
								
								fw_dc22_stm32l100/src/led/led_matrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								fw_dc22_stm32l100/src/led/led_matrix.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | /*
 | ||||||
|  |  * led_matrix.h: main skull led matrix handling prototypes | ||||||
|  |  * 2014 true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_matrix.h 364 2015-06-12 04:44:55Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_LED_MATRIX_H | ||||||
|  | #define __PIRATE_LED_MATRIX_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* struct */ | ||||||
|  | typedef struct LEDFixedPattern { | ||||||
|  | 	uint16_t wait; | ||||||
|  | 	uint32_t led[8]; | ||||||
|  | } LEDFixedPattern; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* constants */ | ||||||
|  | #define LED_MATRIX_PROG_COUNT 	6 | ||||||
|  | 
 | ||||||
|  | /* interface */ | ||||||
|  | #define LED_MATRIX_WHITE 		0 | ||||||
|  | #define LED_MATRIX_PURPLE 		1 | ||||||
|  | 
 | ||||||
|  | /* programs */ | ||||||
|  | #define LED_MATRIX_MODE_OFF 	0 | ||||||
|  | #define LED_MATRIX_MODE_PROGRAM 2 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* variables */ | ||||||
|  | extern const char led_matrix_prog_name[LED_MATRIX_PROG_COUNT][16]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void led_matrix_io_init(); | ||||||
|  | void led_matrix_io_disable(); | ||||||
|  | void led_matrix_next(); | ||||||
|  | 
 | ||||||
|  | void led_matrix_mode_update(); | ||||||
|  | void led_matrix_set_mode(uint8_t mode); 	// used for turning off
 | ||||||
|  | void led_matrix_set_program(uint8_t program_idx, uint8_t init, | ||||||
|  | 		uint16_t wait, uint16_t level, uint32_t offset, uint32_t settings); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										58
									
								
								fw_dc22_stm32l100/src/led/led_matrix_pattern.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								fw_dc22_stm32l100/src/led/led_matrix_pattern.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | /**
 | ||||||
|  |  * led_matrix_pattern.h: fixed patterns for the RGBLED eyes | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_matrix_pattern.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  |   // all LEDs on 100%
 | ||||||
|  | static const LEDFixedPattern led_pattern_01[] = { | ||||||
|  | 	{1000, {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 			0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // all LEDs on 50%
 | ||||||
|  | static const LEDFixedPattern led_pattern_02[] = { | ||||||
|  | 	{1000, {0x7d7d7d7d, 0x7d7d7d7d, 0x7d7d7d7d, 0x7d7d7d7d, | ||||||
|  | 			0x7d7d7d7d, 0x7d7d7d7d, 0x7d7d7d7d, 0x7d7d7d7d}}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // alternate, fast fade
 | ||||||
|  | static const LEDFixedPattern led_pattern_03[] = { | ||||||
|  | 	{600,  {0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00, | ||||||
|  | 			0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff}}, | ||||||
|  | 	{80,  	{0x80808080, 0x80808080, 0x80808080, 0x80808080, | ||||||
|  | 			0x80808080, 0x80808080, 0x80808080, 0x80808080}}, | ||||||
|  | 	{600,  {0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, | ||||||
|  | 			0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00}}, | ||||||
|  | 	{80,   {0x80808080, 0x80808080, 0x80808080, 0x80808080, | ||||||
|  | 			0x80808080, 0x80808080, 0x80808080, 0x80808080}} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // fast white/alternate flash
 | ||||||
|  | static const LEDFixedPattern led_pattern_04[] = { | ||||||
|  | 	{80,   {0x34343434, 0x34343434, 0x34343434, 0x34343434, | ||||||
|  | 			0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0}}, | ||||||
|  | 	{80,   {0x04040404, 0x04040404, 0x04040404, 0x04040404, | ||||||
|  | 			0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd}}, | ||||||
|  | 	{80,   {0x78787878, 0x78787878, 0x78787878, 0x78787878, | ||||||
|  | 			0x86868686, 0x86868686, 0x86868686, 0x86868686}}, | ||||||
|  | 	{80,   {0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, | ||||||
|  | 			0x34343434, 0x34343434, 0x34343434, 0x34343434}}, | ||||||
|  | 	{80,   {0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd, | ||||||
|  | 			0x04040404, 0x04040404, 0x04040404, 0x04040404}}, | ||||||
|  | 	{80,   {0x86868686, 0x86868686, 0x86868686, 0x86868686, | ||||||
|  | 			0x78787878, 0x78787878, 0x78787878, 0x78787878}} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // pattern count - make sure this is updated with the amount
 | ||||||
|  |   // of entries in the patterns above!
 | ||||||
|  | static const uint8_t led_pattern_size[] = { | ||||||
|  | 	1, | ||||||
|  | 	1, | ||||||
|  | 	4, | ||||||
|  | 	6 | ||||||
|  | }; | ||||||
							
								
								
									
										300
									
								
								fw_dc22_stm32l100/src/led/led_matrix_prog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								fw_dc22_stm32l100/src/led/led_matrix_prog.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,300 @@ | |||||||
|  | /**
 | ||||||
|  |  * led_matrix_prog.h: programs for the main LED matrix | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: led_matrix_prog.h 364 2015-06-12 04:44:55Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  |   // program variables
 | ||||||
|  | static uint16_t led_prog_wait; 		// used by function to keep track of iteration time
 | ||||||
|  | static uint32_t led_prog_state[4]; 	// used by the function to keep track of lit LEDs, state
 | ||||||
|  | static uint32_t led_prog_work[4]; 	// used for misc shit
 | ||||||
|  | 
 | ||||||
|  | static uint16_t led_prog_set_wait; 	// used by setter function to set iteration time in ms
 | ||||||
|  | static uint16_t led_prog_set_level;	// used by setter function to set desired level
 | ||||||
|  | static uint32_t led_prog_set_offset;// used by setter function to set desired offset
 | ||||||
|  | static uint32_t led_prog_set_option;// used by setter to set options
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* programs */ | ||||||
|  | /********
 | ||||||
|  |  * debug light output | ||||||
|  |  * uses white LEDs as debug output. | ||||||
|  |  * set the offset to the LED mask for LEDs you want lit. | ||||||
|  |  * set the wait time to the time to stay lit (15000 is a good value). | ||||||
|  | *********/ | ||||||
|  | static void led_prog_debug() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	if (led_prog_set_wait) { | ||||||
|  | 		led_prog_wait = led_prog_set_wait; | ||||||
|  | 		led_prog_set_wait = 0; | ||||||
|  | 		led_prog_state[0] = led_prog_set_offset; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (led_prog_wait) { | ||||||
|  | 		led_prog_wait--; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 16; i++) { | ||||||
|  | 		if (led_prog_state[0] & (1 << i)) { | ||||||
|  | 			led_level[0][i] = led_prog_wait ? (led_prog_set_level & 0xff) : 0; | ||||||
|  | 		} else { | ||||||
|  | 			led_level[0][i] = 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | /********
 | ||||||
|  |  * around the skull in a loop program | ||||||
|  |  * speed: 	set as desired | ||||||
|  |  * options: bit 0 = white enable, bit 1 = purple enable, | ||||||
|  |  * 			bit 2 = white direction (0 = clockwise, 1 = counter-clockwise), | ||||||
|  |  * 			bit 3 = purple direction (0 = clockwise, 1 = counter-clockwise), | ||||||
|  |  * 			bit 4 = decay trails faster, bit 5 = decay trails even faster, | ||||||
|  |  *          bit 6 = trails enable on white, bit 7 = trails enable on purple | ||||||
|  |  *********/ | ||||||
|  | static void led_prog_loops() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	// timeout is done?
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		// load new timer wait value
 | ||||||
|  | 		led_prog_wait = led_prog_set_wait * 5; | ||||||
|  | 
 | ||||||
|  | 		// set decay rate (LED PWM active values are right shifted by this value)
 | ||||||
|  | 		led_prog_work[0] = 1; | ||||||
|  | 		if (led_prog_set_option & BIT_4) led_prog_work[0]++; | ||||||
|  | 		if (led_prog_set_option & BIT_5) led_prog_work[0] += 2; | ||||||
|  | 
 | ||||||
|  | 		// set initial LED offsets
 | ||||||
|  | 		if (!led_prog_work[3]) { | ||||||
|  | 			led_prog_state[0] = led_prog_set_offset & 0x0f; | ||||||
|  | 			led_prog_state[1] = (led_prog_set_offset >> 4) & 0x0f; | ||||||
|  | 			led_prog_work[3] = 1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// set LED PWM levels
 | ||||||
|  | 		for (i = 0; i < 16; i++) { | ||||||
|  | 			if ((i == led_prog_state[0]) && (led_prog_set_option & BIT_0)) { | ||||||
|  | 				// LED is active and enabled; set to desired level.
 | ||||||
|  | 				led_level[0][i] = led_prog_set_level & 0xff; | ||||||
|  | 			} else { | ||||||
|  | 				// led is not active - decay if trails on, otherwise turn off
 | ||||||
|  | 				led_level[0][i] = (led_prog_set_option & BIT_6) ? | ||||||
|  | 					led_level[0][i] >> led_prog_work[0] : 0; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if ((i == led_prog_state[1]) && (led_prog_set_option & BIT_1)) { | ||||||
|  | 				// LED is active and enabled; set to desired level.
 | ||||||
|  | 				led_level[1][i] = led_prog_set_level >> 8; | ||||||
|  | 			} else { | ||||||
|  | 				// led is not active - decay if trails on, otherwise turn off
 | ||||||
|  | 				led_level[1][i] = (led_prog_set_option & BIT_7) ? | ||||||
|  | 						led_level[1][i] >> led_prog_work[0] : 0; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// update program state with the next LED
 | ||||||
|  | 		for (i = 0; i < 2; i++) { | ||||||
|  | 			led_prog_state[i] += (led_prog_set_option & (1 << (i + 2))) ? 15 : 1; | ||||||
|  | 			led_prog_state[i] &= 0x0f; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// bide our time...
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * around the skull in a loop program modulated by microphone | ||||||
|  |  * speed: 	set as desired | ||||||
|  |  * options: see above program | ||||||
|  |  *********/ | ||||||
|  | static void led_prog_loops_mic() | ||||||
|  | { | ||||||
|  | 	static uint32_t delay = 0; | ||||||
|  | 	uint16_t low, high; | ||||||
|  | 
 | ||||||
|  | 	low = (led_prog_set_offset >> 8) & 0xff; | ||||||
|  | 	high = (led_prog_set_offset >> 16) & 0xff; | ||||||
|  | 
 | ||||||
|  | 	led_prog_state[3] = pirate_scale(mic_peak, settings.mic_cal[0], settings.mic_cal[1], 255, 0); | ||||||
|  | 	led_prog_state[3] = pirate_scale(led_prog_state[3], low, high, 1, 120); | ||||||
|  | 
 | ||||||
|  | 	// variable decay
 | ||||||
|  | 	if (!delay) { | ||||||
|  | 		delay = (led_prog_set_offset >> 24); | ||||||
|  | 		if (!delay) delay = 1; | ||||||
|  | 		if (led_prog_set_wait < led_prog_state[3]) { | ||||||
|  | 			led_prog_set_wait++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// always have fast attack
 | ||||||
|  | 	if (led_prog_set_wait > led_prog_state[3]) { | ||||||
|  | 		led_prog_set_wait = led_prog_state[3]; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	delay--; | ||||||
|  | 
 | ||||||
|  | 	led_prog_loops(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * around the skull in a loop program that rotates | ||||||
|  |  * most useful for oppositing direction loops so that the | ||||||
|  |  * point of contact changes | ||||||
|  |  * speed: 	set as desired | ||||||
|  |  * options: see above program, with the following: | ||||||
|  |  *          high 12 option bits: time between rotating in ms | ||||||
|  |  *          bits[19:16]: specify direction (1-15 = move pos cw) | ||||||
|  |  *********/ | ||||||
|  | static void led_prog_loops_rotate() | ||||||
|  | { | ||||||
|  | 	static uint32_t wait = 0; | ||||||
|  | 	uint32_t t; | ||||||
|  | 
 | ||||||
|  | 	if (!wait) { | ||||||
|  | 		wait = (led_prog_set_option >> 20) * 5; | ||||||
|  | 		if (!wait) wait = 1; | ||||||
|  | 
 | ||||||
|  | 		t = (led_prog_set_option >> 16 & 0x0f); | ||||||
|  | 
 | ||||||
|  | 		if (t >= 1 && t <= 15) { | ||||||
|  | 			led_prog_state[0] += t; | ||||||
|  | 			led_prog_state[0] &= 0x0f; | ||||||
|  | 
 | ||||||
|  | 			led_prog_state[1] += t; | ||||||
|  | 			led_prog_state[1] &= 0x0f; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	wait--; | ||||||
|  | 	led_prog_loops(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * random on, random off | ||||||
|  |  * speed: 	set as desired | ||||||
|  |  * options: bit 7 = fade off instead of turning off, bit 6 = fade faster | ||||||
|  |  *          bit 5 = fade even faster, bit 4 = fade faster still | ||||||
|  |  *          bit 1 = enable purple, bit 0 = enable white | ||||||
|  |  *********/ | ||||||
|  | static void led_prog_rand_on_rand_off() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	uint8_t fade; | ||||||
|  | 
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		// load new timer wait value
 | ||||||
|  | 		led_prog_wait = led_prog_set_wait * 5; | ||||||
|  | 
 | ||||||
|  | 		// is this a new run?
 | ||||||
|  | 		if (!led_prog_state[3]) { | ||||||
|  | 			led_prog_state[3] = 1; | ||||||
|  | 
 | ||||||
|  | 			for (i = 0; i < 16; i++) { | ||||||
|  | 				led_level[LED_MATRIX_WHITE][i] = 0; | ||||||
|  | 				led_level[LED_MATRIX_PURPLE][i] = 0; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		led_prog_state[0] = led_prog_state[0] ? 0 : 1; | ||||||
|  | 
 | ||||||
|  | 		fade = 0; | ||||||
|  | 		if (led_prog_set_option & 0x80) fade = 2; | ||||||
|  | 		if (led_prog_set_option & 0x40) fade += 6; | ||||||
|  | 		if (led_prog_set_option & 0x20) fade += 12; | ||||||
|  | 		if (led_prog_set_option & 0x10) fade += 24; | ||||||
|  | 
 | ||||||
|  | 		for (i = 0; i < 16; i++) { | ||||||
|  | 			if (fade) { | ||||||
|  | 				if (led_level[LED_MATRIX_WHITE][i] > fade) { | ||||||
|  | 					led_level[LED_MATRIX_WHITE][i] -= fade; | ||||||
|  | 				} else { | ||||||
|  | 					led_level[LED_MATRIX_WHITE][i] = 0; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if (led_level[LED_MATRIX_PURPLE][i] > fade) { | ||||||
|  | 					led_level[LED_MATRIX_PURPLE][i] -= fade; | ||||||
|  | 				} else { | ||||||
|  | 					led_level[LED_MATRIX_PURPLE][i] = 0; | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				led_level[LED_MATRIX_WHITE][i] = 0; | ||||||
|  | 				led_level[LED_MATRIX_PURPLE][i] = 0; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (led_prog_set_option & (1 << led_prog_state[0])) { | ||||||
|  | 			led_level[led_prog_state[0]][pirate_prng() % 16] = led_prog_set_level >> (led_prog_state[0] << 3); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * impulse spl meter | ||||||
|  |  * speed: 	ignored | ||||||
|  |  * options:	bits7-0 = sensitivity | ||||||
|  |  *********/ | ||||||
|  | static void led_prog_mic_spl_meter() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	uint8_t set[2]; | ||||||
|  | 
 | ||||||
|  | 	if (!led_prog_wait) { | ||||||
|  | 		led_prog_wait = led_prog_set_wait * 5; | ||||||
|  | 
 | ||||||
|  | 		if (led_prog_work[0] > mic_peak) { | ||||||
|  | 			led_prog_work[0] -= 4; | ||||||
|  | 		} else { | ||||||
|  | 			led_prog_work[0] = mic_peak; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// scale peak value to calculated value and invert it
 | ||||||
|  | 		led_prog_state[3] = pirate_scale(led_prog_work[0], settings.mic_cal[0], settings.mic_cal[1], 0, 255); | ||||||
|  | 
 | ||||||
|  | 		// and invert it
 | ||||||
|  | 		led_prog_state[3] ^= 0xff; | ||||||
|  | 
 | ||||||
|  | 		// set defaults high level if not set
 | ||||||
|  | 		if (!(led_prog_set_option >> 24)) led_prog_set_option |= (0xff << 24); | ||||||
|  | 
 | ||||||
|  | 		// stretch value with constrained bounds to original bounds
 | ||||||
|  | 		led_prog_state[3] = pirate_scale(led_prog_state[3], | ||||||
|  | 				(led_prog_set_option >> 16) & 0xff, (led_prog_set_option >> 24), 0, 255); | ||||||
|  | 
 | ||||||
|  | 		// finally determine which LEDs to light
 | ||||||
|  | 		led_prog_state[3] = pirate_scale(led_prog_state[3], 0, 255, 0, 8); | ||||||
|  | 
 | ||||||
|  | 		// then set them
 | ||||||
|  | 		for (i = 0; i < 8; i++) { | ||||||
|  | 			if (led_prog_state[3] < i) { | ||||||
|  | 				set[0] = led_prog_set_level & 0xff; | ||||||
|  | 				set[1] = led_prog_set_level >> 8; | ||||||
|  | 			} else if (led_prog_state[3] == i) { | ||||||
|  | 				set[0] = (led_prog_set_level & 0xff) >> 1; | ||||||
|  | 				set[1] = led_prog_set_level >> 9; | ||||||
|  | 			} else { | ||||||
|  | 				set[0] = 0; | ||||||
|  | 				set[1] = 0; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			led_level[LED_MATRIX_WHITE][i] = set[0]; | ||||||
|  | 			led_level[LED_MATRIX_WHITE][15 - i] = set[0]; | ||||||
|  | 
 | ||||||
|  | 			led_level[LED_MATRIX_PURPLE][i] = set[1]; | ||||||
|  | 			led_level[LED_MATRIX_PURPLE][15 - i] = set[1]; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	led_prog_wait--; | ||||||
|  | } | ||||||
							
								
								
									
										659
									
								
								fw_dc22_stm32l100/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										659
									
								
								fw_dc22_stm32l100/src/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,659 @@ | |||||||
|  | /**
 | ||||||
|  |  * Whiskey Pirates DC22 Badge "PIRATE CPU" Firmware | ||||||
|  |  * MCU firmware for STM32L100RBT6 | ||||||
|  |  * Originally written 2014 by true, updates in 2015 for DC23 by true | ||||||
|  |  * Created: 2014.05.16 | ||||||
|  |  * ts:4 | ||||||
|  |  *  | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * ISR Usage ~13% average, 26% max (as of rev186) | ||||||
|  |  * Yeah, some of this shit is hackish. What do you expect from a hacker. | ||||||
|  |  * I'm sorry for some of the shit in here, 90% was written while sleep-deprived | ||||||
|  |  * plus I don't know wtf I am doing     -- true | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* pirates */ | ||||||
|  | #include "pirate.h" 				// cmsis include is located here | ||||||
|  | 
 | ||||||
|  | #include "interface/gpio.h" | ||||||
|  | #include "interface/led_pwm.h" | ||||||
|  | #include "interface/adc.h" | ||||||
|  | #include "interface/i2c.h" | ||||||
|  | 
 | ||||||
|  | #include "device/lcd.h" | ||||||
|  | #include "device/beep.h" | ||||||
|  | #include "device/attiny.h" | ||||||
|  | #include "device/lightsensor.h" | ||||||
|  | #include "device/radio/nrf.h" | ||||||
|  | 
 | ||||||
|  | #include "led/led_matrix.h" | ||||||
|  | #include "led/led_bone.h" | ||||||
|  | 
 | ||||||
|  | #include "menu/lcd_menu.h" | ||||||
|  | #include "menu/menu_settings.h" 	// settings_restore() lives here | ||||||
|  | #include "menu/menu_program.h" 		// LED program related shit lives here | ||||||
|  | 
 | ||||||
|  | #include "display/infopirate.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* usb cdc serial port support */ | ||||||
|  | #include "usb/core/usb_lib.h" | ||||||
|  | #include "usb/glue.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // hard buttons
 | ||||||
|  | static const tGPIO btn[4] = { | ||||||
|  | 	{GPIOC, GPIO_Pin_0, 0}, | ||||||
|  | 	{GPIOA, GPIO_Pin_15, 15}, | ||||||
|  | 	{GPIOC, GPIO_Pin_1, 1}, | ||||||
|  | 	{GPIOB, GPIO_Pin_2, 2}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define BTN_DEBOUNCE_CYCLES 	30 | ||||||
|  | 
 | ||||||
|  | static const uint8_t btn_hilevel = 0b00001000; 	// button is active high when its bit is set, otherwise active low
 | ||||||
|  | uint16_t btn_press[4]; | ||||||
|  | uint16_t btn_hold[4]; | ||||||
|  | 
 | ||||||
|  |   // main handler timer timekeeping
 | ||||||
|  | uint32_t tim6_count; | ||||||
|  | uint32_t tim6_usage; 		// profiling
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | /********
 | ||||||
|  |  * initialize main handler interrupt | ||||||
|  |  ********/ | ||||||
|  | void pirate_tim6_init() | ||||||
|  | { | ||||||
|  | 	TIM_TimeBaseInitTypeDef tim_tb; | ||||||
|  | 	NVIC_InitTypeDef nvic; | ||||||
|  | 
 | ||||||
|  | 	// enable peripheral clock
 | ||||||
|  | 	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// set up to fire 0.2ms main handler loop (2.5KHz, ~12800 clocks per cycle)
 | ||||||
|  | 	// LED light rate for main LED matrix looprate/16 (for 16 LEDs per matrix), which is 156Hz...
 | ||||||
|  | 	TIM_TimeBaseStructInit(&tim_tb); | ||||||
|  | 	tim_tb.TIM_Period = (SystemCoreClock / 2500) - 1; | ||||||
|  | 	TIM_TimeBaseInit(TIM6, &tim_tb); | ||||||
|  | 
 | ||||||
|  | 	// enable interrupt
 | ||||||
|  | 	TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// set as highest priority - this is our UI handler too
 | ||||||
|  | 	nvic.NVIC_IRQChannel = TIM6_IRQn; | ||||||
|  | 	nvic.NVIC_IRQChannelPreemptionPriority = 2; | ||||||
|  | 	nvic.NVIC_IRQChannelSubPriority = 1; | ||||||
|  | 	nvic.NVIC_IRQChannelCmd = ENABLE; | ||||||
|  | 	NVIC_Init(&nvic); | ||||||
|  | 
 | ||||||
|  | 	// finally, enable the timer
 | ||||||
|  | 	TIM_Cmd(TIM6, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// make sure our profiling variable doesn't get optimized away
 | ||||||
|  | 	__asm__ __volatile__("" :: "m" (tim6_usage)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * initialize gpio for buttons | ||||||
|  |  * this assumes the GPIOs are clocked already | ||||||
|  |  ********/ | ||||||
|  | static inline void btn_init() | ||||||
|  | { | ||||||
|  | 	GPIO_InitTypeDef gpio; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	gpio.GPIO_Mode = GPIO_Mode_IN; | ||||||
|  | 	gpio.GPIO_Speed = GPIO_Speed_400KHz; | ||||||
|  | 
 | ||||||
|  | 	for (i = 3; i >= 0; i--) { | ||||||
|  | 		if (btn_hilevel & (1 << i)) { | ||||||
|  | 			gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; | ||||||
|  | 		} else { | ||||||
|  | 			gpio.GPIO_PuPd = GPIO_PuPd_UP; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		gpio.GPIO_Pin = btn[i].pin; | ||||||
|  | 		GPIO_Init(btn[i].port, &gpio); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set initial button types to operate the main menu
 | ||||||
|  | 	// TODO: maybe this won't do this and it'll instead run the program by default
 | ||||||
|  | 	menu_btntype_menus(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * default button push handlers | ||||||
|  |  * TODO: implement what is necessary to make these more useful | ||||||
|  |  ********/ | ||||||
|  | static inline void btn_evt_push(uint16_t btn) | ||||||
|  | { | ||||||
|  | 	if (lcd_btn_fn[btn]) { | ||||||
|  | 		lcd_btn_fn[btn](); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void btn_evt_hold(uint16_t btn, uint16_t count) | ||||||
|  | { | ||||||
|  | 	if (btn == BTN_UP || btn == BTN_DOWN) { | ||||||
|  | 		if (!(count == 0 || count == 2)) { | ||||||
|  | 			btn_evt_push(btn); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void btn_evt_release(uint16_t btn) | ||||||
|  | { | ||||||
|  | 	return; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * update the state of pressed buttons | ||||||
|  |  ********/ | ||||||
|  | static inline void btn_update() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	int pressed; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 4; i++) { | ||||||
|  | 		pressed = 0; | ||||||
|  | 
 | ||||||
|  | 		// button high or low?
 | ||||||
|  | 		if (btn_hilevel & (1 << i)) { | ||||||
|  | 			if (btn[i].pin & GPIO_ReadInputData(btn[i].port)) pressed = 1; | ||||||
|  | 		} else { | ||||||
|  | 			if (!(btn[i].pin & GPIO_ReadInputData(btn[i].port))) pressed = 1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (pressed) { | ||||||
|  | 			btn_press[i]++; | ||||||
|  | 			if (btn_press[i] == BTN_DEBOUNCE_CYCLES) { | ||||||
|  | 				// button is pushed
 | ||||||
|  | 				btn_evt_push(i); | ||||||
|  | 			} else if (btn_press[i] == 1500) { | ||||||
|  | 				// btn is held
 | ||||||
|  | 				btn_evt_hold(i, btn_hold[i]); | ||||||
|  | 
 | ||||||
|  | 				// btn is held for 0.3s (or re-fired 0.1s)
 | ||||||
|  | 				btn_hold[i]++; | ||||||
|  | 				// we only uniquely count 30 seconds of hold...
 | ||||||
|  | 				if (btn_hold[i] > 30000) { | ||||||
|  | 					btn_hold[i] = 30000; | ||||||
|  | 				} | ||||||
|  | 				// reset to re-fire in 0.1s increments
 | ||||||
|  | 				btn_press[i] = 1000; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// done handling buttons - we only do one pressed at a time right now
 | ||||||
|  | 			break; | ||||||
|  | 		} else { | ||||||
|  | 			// if pushed, fire release event
 | ||||||
|  | 			if (btn_press[i] > BTN_DEBOUNCE_CYCLES) { | ||||||
|  | 				btn_evt_release(i); | ||||||
|  | 			} | ||||||
|  | 			// reset pushed state
 | ||||||
|  | 			btn_press[i] = 0; | ||||||
|  | 			btn_hold[i] = 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* startup */ | ||||||
|  | int main(void) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	// update clock info
 | ||||||
|  | 	SystemCoreClockUpdate(); | ||||||
|  | 
 | ||||||
|  | 	// enable gpio clocks
 | ||||||
|  | 	// enable peripheral clocks
 | ||||||
|  | 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); | ||||||
|  | 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); | ||||||
|  | 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); | ||||||
|  | 
 | ||||||
|  | 	// set up LED matrix GPIO and clocks
 | ||||||
|  | 	led_matrix_io_init(); | ||||||
|  | 	// set up bone LED GPIO and clocks
 | ||||||
|  | 	led_bone_io_init(); | ||||||
|  | 
 | ||||||
|  | 	// set up LED PWM peripherals
 | ||||||
|  | 	led_pwm_init_all(); | ||||||
|  | 
 | ||||||
|  | 	// set up buttons
 | ||||||
|  | 	btn_init(); | ||||||
|  | 
 | ||||||
|  | 	// read settings from EEPROM
 | ||||||
|  | 	// NOTE: MENU button will load default settings (but keep name)
 | ||||||
|  | 	// NOTE: MENU+OK will also erase name, restoring all defaults
 | ||||||
|  | 	// TODO: separate programs from this, have another combo for erasing programs
 | ||||||
|  | 	i = (GPIO_ReadInputDataBit(btn[BTN_MENU].port, btn[BTN_MENU].pin)) ? 0x00 : 0x01; | ||||||
|  | 	if (i) i |= (GPIO_ReadInputDataBit(btn[BTN_OK].port, btn[BTN_OK].pin)) ? 0x00 : 0x02; | ||||||
|  | 
 | ||||||
|  | 	settings_restore(i); | ||||||
|  | 
 | ||||||
|  | 	// set up program run variables
 | ||||||
|  | 	prog_init(); | ||||||
|  | 
 | ||||||
|  | 	// set up ADC
 | ||||||
|  | 	adc_init(); | ||||||
|  | 
 | ||||||
|  | 	// set up I2C master peripheral (pegleg and LCD comms)
 | ||||||
|  | 	i2c_init(I2C2, 400000); | ||||||
|  | 
 | ||||||
|  | 	// wait some more time for pegleg to boot. it can take a while
 | ||||||
|  | 	pirate_delay(10); | ||||||
|  | 
 | ||||||
|  | 	// set up LCD
 | ||||||
|  | 	lcd_init(); | ||||||
|  | 	lcd_cmd(LCD_CMD_CLEAR_SCREEN); | ||||||
|  | 
 | ||||||
|  | 	// set up LCD menus
 | ||||||
|  | 	lcd_menu_init(); | ||||||
|  | 
 | ||||||
|  | 	// set up LCD backlight
 | ||||||
|  | 	lcd_led_init(); | ||||||
|  | 
 | ||||||
|  | 	// set up USB
 | ||||||
|  | 	USB_ClockEna(); | ||||||
|  | 	USB_Interrupts_Config(); | ||||||
|  | 	USB_Init_System(); | ||||||
|  | 
 | ||||||
|  | 	pirate_delay(10);  // need to wait a bit, if we start up too fast host won't find device
 | ||||||
|  | 	USB_Init(); | ||||||
|  | 
 | ||||||
|  | 	// set up magical beeper
 | ||||||
|  | 	beep_init(); | ||||||
|  | 
 | ||||||
|  | 	// and play startup tone
 | ||||||
|  | 	beep(26, 40); | ||||||
|  | 	beep(31, 40); | ||||||
|  | 	beep(30, 40); | ||||||
|  | 	beep(29, 40); | ||||||
|  | 	beep(28, 40); | ||||||
|  | 
 | ||||||
|  | 	// need to wait some more for NRF to be ready to configure
 | ||||||
|  | 	// this is per datasheet; it is probably actually working by now
 | ||||||
|  | 	pirate_delay(50); | ||||||
|  | 	// set up the radio
 | ||||||
|  | 	nrf_init(); | ||||||
|  | 
 | ||||||
|  | 	// set up pegleg light sensor gain
 | ||||||
|  | 	if (settings.light_setgain) { | ||||||
|  | 		// we have a fixed gain set
 | ||||||
|  | 		light_gain = settings.light_setgain; | ||||||
|  | 		attiny_write_light_sensitivity(0, light_gain); | ||||||
|  | 	} else { | ||||||
|  | 		// we don't have a fixed gain, so load a default gain value
 | ||||||
|  | 		light_gain = LIGHTSENS_THRESH_TOP_NORM; | ||||||
|  | 		attiny_write_light_sensitivity(0, LIGHTSENS_THRESH_TOP_NORM); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set up main handler interrupt
 | ||||||
|  | 	pirate_tim6_init(); | ||||||
|  | 
 | ||||||
|  | 	// after system is booted, we can enable the prefetch buffer
 | ||||||
|  | 	// for some reason, at 32MHz, power glitches could cause some
 | ||||||
|  | 	// freak out when booting if we turned this on any earlier
 | ||||||
|  | 	FLASH->ACR |= FLASH_ACR_PRFTEN; | ||||||
|  | 
 | ||||||
|  |     while (1) { | ||||||
|  |     	// update clock info
 | ||||||
|  |     	SystemCoreClockUpdate(); | ||||||
|  | 
 | ||||||
|  |     	// update various low-priority things
 | ||||||
|  |     	if (tim6_count % 500 == 0) { | ||||||
|  |     		static volatile uint32_t update = 0; | ||||||
|  | 
 | ||||||
|  |     		update++; | ||||||
|  |     		if (update == 20) update = 0; | ||||||
|  | 
 | ||||||
|  |     		switch (update) { | ||||||
|  |     			case 1: { 	 // light sensor
 | ||||||
|  | 					// TODO: investigate the bug that causes this to read ~70-80 when it
 | ||||||
|  |     				//       should be reading >100
 | ||||||
|  |     				if ((settings.led_autoadjust & 0x80) || settings.lcd_autobrite) { | ||||||
|  | 						if (!settings.light_setgain) { | ||||||
|  | 							light_level = attiny_read_light_level(0); | ||||||
|  | 						} | ||||||
|  | 					} else { | ||||||
|  | 						light_level = settings.led_autogain_lev_max - 1; | ||||||
|  | 					} | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  |     			case 2: { | ||||||
|  | 					// auto-update light sensor gain
 | ||||||
|  | 					if (!settings.light_setgain) { | ||||||
|  | 						if (lightsensor_gainvalue_update()) { | ||||||
|  | 							// updated, so send updated value
 | ||||||
|  | 							attiny_write_light_sensitivity(0, light_gain); | ||||||
|  | 						} | ||||||
|  | 					} else { | ||||||
|  | 						light_gain = settings.light_setgain; | ||||||
|  | 					} | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  |     			case 3: | ||||||
|  | 				case 13: { 		// temp sensor
 | ||||||
|  | 					pirate_thermometer_log(attiny_read_temp()); | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  |     		} | ||||||
|  |     	} | ||||||
|  | 
 | ||||||
|  |     	// max update 50 times/second
 | ||||||
|  |     	if (tim6_count % 50 == 8) { | ||||||
|  | 			// update eyes
 | ||||||
|  | 			led_eyes_tx(); | ||||||
|  | 
 | ||||||
|  | 			// update LCD contrast
 | ||||||
|  | 			lcd_apply_contrast(); | ||||||
|  | 
 | ||||||
|  | 			// update LCD CGRAM
 | ||||||
|  | 			if (lcd_cgram_len) { | ||||||
|  | 				// set LCD height
 | ||||||
|  | 				// make sure in your code that you set this to CGRAM mode!
 | ||||||
|  | 				lcd_cmd(lcd_get_height()); | ||||||
|  | 
 | ||||||
|  | 				// only update CGRAM if we are in CGRAM mode
 | ||||||
|  | 				if ((lcd_get_height() & 0x01) == 0) { | ||||||
|  | 					// make sure to force updating the mode again
 | ||||||
|  | 					lcd_cmd(lcd_get_height()); | ||||||
|  | 					// and update CGRAM contents
 | ||||||
|  | 					for (i = 0; i < lcd_cgram_len; i++) { | ||||||
|  | 						lcd_print(0x40 + (i << 3), lcd_cgram[i], 8); | ||||||
|  | 					} | ||||||
|  | 					lcd_cgram_len = 0; | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				// set LCD height
 | ||||||
|  | 				// this is here like this to fix compiler optimization bug?
 | ||||||
|  | 				// TODO: find out wtf I meant by this
 | ||||||
|  | 				lcd_cmd(lcd_get_height()); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// update LCD characters
 | ||||||
|  | 			lcd_linebuf_send(); | ||||||
|  | 
 | ||||||
|  | 			// set the LCD cursor position and type
 | ||||||
|  | 			lcd_cmd(lcd_get_cursor_type()); | ||||||
|  | 			lcd_cmd(lcd_get_cursor_pos()); | ||||||
|  |     	} | ||||||
|  | 
 | ||||||
|  |     	// update battery voltage info 10 times/second
 | ||||||
|  |     	if (tim6_count % 250 == 248) { | ||||||
|  |     		pirate_batt_log(adc_result[ADC_READ_BATT_VOLTAGE]); | ||||||
|  |     	} | ||||||
|  | 
 | ||||||
|  |     	// then go to sleep
 | ||||||
|  |     	__WFI(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* ISR */ | ||||||
|  | // main handler interrupt
 | ||||||
|  | void TIM6_IRQHandler() | ||||||
|  | { | ||||||
|  | 	int i, j, k, n; | ||||||
|  | 	static uint16_t nametx; | ||||||
|  | 
 | ||||||
|  | 	// update counter
 | ||||||
|  | 	tim6_count++; | ||||||
|  | 	if (tim6_count >= 2500) { | ||||||
|  | 		tim6_count = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// manage buttons
 | ||||||
|  | 	btn_update(); | ||||||
|  | 
 | ||||||
|  | 	// update ADC values, currently 2.5KHz
 | ||||||
|  | 	if ((tim6_count & 0x01) == 0x01) { | ||||||
|  | 		adc_start(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// update LED mic peak
 | ||||||
|  | 	// mic peak decaying
 | ||||||
|  | 	if ((tim6_count & 0x03) == 0x03) { | ||||||
|  | 		if (mic_peak > adc_result[ADC_READ_MIC_PEAK]) { | ||||||
|  | 			mic_peak--; | ||||||
|  | 		} else { | ||||||
|  | 			mic_peak = adc_result[ADC_READ_MIC_PEAK]; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// update autoadjust value for LEDs, polls 25 times/second (40ms)
 | ||||||
|  | 	if (tim6_count % 200 == 0) { | ||||||
|  | 		uint8_t brightness; | ||||||
|  | 
 | ||||||
|  | 		// always need to run this as the LCD might use it
 | ||||||
|  | 		lightsensor_scaler_update(); | ||||||
|  | 
 | ||||||
|  | 		// backlight LCD is a little different
 | ||||||
|  | 		brightness = settings.lcd_autobrite ? | ||||||
|  | 						lightsensor_get_scalerval(LIGHTSENS_SCALED_BACKLIGHT) : settings.lcd_brightness; | ||||||
|  | 
 | ||||||
|  | 		lcd_led_set_level(brightness, 1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// update LCD backlight
 | ||||||
|  | 	lcd_led_update(); | ||||||
|  | 
 | ||||||
|  | 	// update main matrix LEDs
 | ||||||
|  | 	led_matrix_mode_update(); | ||||||
|  | 	led_matrix_next(); | ||||||
|  | 
 | ||||||
|  | 	// update bone matrix LEDs
 | ||||||
|  | 	led_bone_mode_update(); | ||||||
|  | 	led_bone_next(); | ||||||
|  | 
 | ||||||
|  | 	// update eyes RGBLEDs
 | ||||||
|  | 	led_eyes_mode_update(); | ||||||
|  | 
 | ||||||
|  | 	// update beeper
 | ||||||
|  | 	beep_update(); | ||||||
|  | 
 | ||||||
|  | 	// update LCD data 100Hz
 | ||||||
|  | 	// yes, we only update it at 50Hz. but timings use 100Hz timings.
 | ||||||
|  | 	if (tim6_count % 50 == 0) { | ||||||
|  | 		if (menuc == (MenuItem *)&menu_runitem) { | ||||||
|  | 			// run mode display
 | ||||||
|  | 			infopirate_update(); | ||||||
|  | 		} else { | ||||||
|  | 			// info display
 | ||||||
|  | 			lcd_menu_update(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// runmode program
 | ||||||
|  | 	if (tim6_count == 0) { | ||||||
|  | 		for (i = 0; i < 3; i++) { | ||||||
|  | 			if (!( | ||||||
|  | 				   (menu_mode == MENU_MODE_RUNNING_PROGRAM) | ||||||
|  | 				|| (menu_mode == MENU_MODE_PROGRAM_EDITOR) | ||||||
|  | 				|| settings.autorun & 0x02)) { | ||||||
|  | 
 | ||||||
|  | 				// we aren't running the program or editing, so stop everything
 | ||||||
|  | 				prog_id[i] = 255; | ||||||
|  | 				switch (i) { | ||||||
|  | 					case PROG_TYPE_SKULL: { | ||||||
|  | 						led_matrix_set_mode(LED_MATRIX_MODE_OFF); | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  | 					case PROG_TYPE_BONES: { | ||||||
|  | 						led_bone_set_mode(LED_MATRIX_MODE_OFF); | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  | 					case PROG_TYPE_EYES: { | ||||||
|  | 						// only stop eyes if not in favcolor editor
 | ||||||
|  | 						if (!(menuc->root == &menu_pref_ritem[1])) { | ||||||
|  | 							led_eyes_set_mode(LED_EYES_MODE_OFF); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				// we're running the program or editing a program. update the display
 | ||||||
|  | 				if (prog_dwell[i] > 0) { | ||||||
|  | 					prog_dwell[i]--; | ||||||
|  | 				} | ||||||
|  | 				if (prog_dwell[i] == 0) { | ||||||
|  | 					if (menu_mode == MENU_MODE_PROGRAM_EDITOR) { | ||||||
|  | 						// if we are editing, set up what we are trying to edit for preview
 | ||||||
|  | 						n = menu_prog_get_type(); | ||||||
|  | 						j = menu_prog_get_idx(); | ||||||
|  | 						k = (prog_id[n] == 255 || (settings.led_prog[n][j].type & 0x02)) ? 1 : 0; | ||||||
|  | 
 | ||||||
|  | 						prog_id[i] = 0; | ||||||
|  | 						prog_dwell[i] = k ? (settings.led_prog[n][j].dwell << 1) : k; | ||||||
|  | 
 | ||||||
|  | 						switch (n) { | ||||||
|  | 							case PROG_TYPE_SKULL: { | ||||||
|  | 								led_matrix_set_program( | ||||||
|  | 										settings.led_prog[0][j].progidx, | ||||||
|  | 										k, | ||||||
|  | 										settings.led_prog[0][j].wait, | ||||||
|  | 										settings.led_prog[0][j].level, | ||||||
|  | 										settings.led_prog[0][j].offset, | ||||||
|  | 										settings.led_prog[0][j].option | ||||||
|  | 								); | ||||||
|  | 								break; | ||||||
|  | 							} | ||||||
|  | 							case PROG_TYPE_BONES: { | ||||||
|  | 								led_bone_set_program( | ||||||
|  | 										settings.led_prog[1][j].progidx, | ||||||
|  | 										k, | ||||||
|  | 										settings.led_prog[1][j].wait, | ||||||
|  | 										settings.led_prog[1][j].level, | ||||||
|  | 										settings.led_prog[1][j].offset, | ||||||
|  | 										settings.led_prog[1][j].option | ||||||
|  | 								); | ||||||
|  | 								break; | ||||||
|  | 							} | ||||||
|  | 							case PROG_TYPE_EYES: { | ||||||
|  | 								led_eyes_set_program( | ||||||
|  | 										settings.led_prog[2][j].progidx, | ||||||
|  | 										k, | ||||||
|  | 										settings.led_prog[2][j].wait, | ||||||
|  | 										settings.led_prog[2][j].level, | ||||||
|  | 										settings.led_prog[2][j].offset, | ||||||
|  | 										settings.led_prog[2][j].option | ||||||
|  | 								); | ||||||
|  | 								break; | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} else { | ||||||
|  | 						// we must be trying to run the program. show it all.
 | ||||||
|  | 						j = PIRATE_PROG_SAVED_MAX + 1; | ||||||
|  | 						k = prog_id[i]; | ||||||
|  | 						while (j) { | ||||||
|  | 							j--; | ||||||
|  | 							prog_id[i]++; | ||||||
|  | 							if (prog_id[i] >= PIRATE_PROG_SAVED_MAX) prog_id[i] = 0; | ||||||
|  | 
 | ||||||
|  | 							if (settings.led_prog[i][prog_id[i]].type & 0x80) { | ||||||
|  | 								// we have an enabled program
 | ||||||
|  | 								break; | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 
 | ||||||
|  | 						if (j) { | ||||||
|  | 							// load new program if it doesn't match the old program
 | ||||||
|  | 							// or if a program was never run (such as at reboot)
 | ||||||
|  | 							if (prog_get_mode(i) == 1) { | ||||||
|  | 								k = (k == 255 || (settings.led_prog[i][prog_id[i]].type & 0x02)) ? 1 : 0; | ||||||
|  | 								// program change check: (settings.led_prog[i][prog_id[i]].progidx != k)
 | ||||||
|  | 
 | ||||||
|  | 								prog_dwell[i] = (settings.led_prog[i][prog_id[i]].dwell << 1); | ||||||
|  | 
 | ||||||
|  | 								switch (i) { | ||||||
|  | 									case PROG_TYPE_SKULL: { | ||||||
|  | 										led_matrix_set_program( | ||||||
|  | 												settings.led_prog[0][prog_id[0]].progidx, | ||||||
|  | 												k, | ||||||
|  | 												settings.led_prog[0][prog_id[0]].wait, | ||||||
|  | 												settings.led_prog[0][prog_id[0]].level, | ||||||
|  | 												settings.led_prog[0][prog_id[0]].offset, | ||||||
|  | 												settings.led_prog[0][prog_id[0]].option | ||||||
|  | 										); | ||||||
|  | 										break; | ||||||
|  | 									} | ||||||
|  | 									case PROG_TYPE_BONES: { | ||||||
|  | 										led_bone_set_program( | ||||||
|  | 												settings.led_prog[1][prog_id[1]].progidx, | ||||||
|  | 												k, | ||||||
|  | 												settings.led_prog[1][prog_id[1]].wait, | ||||||
|  | 												settings.led_prog[1][prog_id[1]].level, | ||||||
|  | 												settings.led_prog[1][prog_id[1]].offset, | ||||||
|  | 												settings.led_prog[1][prog_id[1]].option | ||||||
|  | 										); | ||||||
|  | 										break; | ||||||
|  | 									} | ||||||
|  | 									case PROG_TYPE_EYES: { | ||||||
|  | 										led_eyes_set_program( | ||||||
|  | 												settings.led_prog[2][prog_id[2]].progidx, | ||||||
|  | 												k, | ||||||
|  | 												settings.led_prog[2][prog_id[2]].wait, | ||||||
|  | 												settings.led_prog[2][prog_id[2]].level, | ||||||
|  | 												settings.led_prog[2][prog_id[2]].offset, | ||||||
|  | 												settings.led_prog[2][prog_id[2]].option | ||||||
|  | 										); | ||||||
|  | 										break; | ||||||
|  | 									} | ||||||
|  | 								} | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// send nametx packet
 | ||||||
|  | 	if (dc23_nametx && tim6_count % 500 == 4) { | ||||||
|  | 		if (nametx == 2) { | ||||||
|  | 			// send first packet
 | ||||||
|  | 			nrf_tx_buf[0] = NRF_CMD_DC22_23GREET; | ||||||
|  | 			nrf_tx_buf[1] = 22; | ||||||
|  | 			nrf_tx_buf[2] = 0; | ||||||
|  | 			for (i = 0; i < 4; i++) { | ||||||
|  | 				nrf_tx_buf[3 + i] = settings.name[i]; | ||||||
|  | 			} | ||||||
|  | 			nrf_tx_buf[7] = nrf_checksum(nrf_tx_buf, 7, 0); | ||||||
|  | 			nRF24_packet_tx(nrf_tx_buf, NRF_PAYLOAD_LEN, 1); | ||||||
|  | 		} else if (nametx == 1) { | ||||||
|  | 			// send second packet
 | ||||||
|  | 			nrf_tx_buf[0] = NRF_CMD_DC22_23GREET; | ||||||
|  | 			nrf_tx_buf[1] = 22; | ||||||
|  | 			nrf_tx_buf[2] = 1; | ||||||
|  | 			for (i = 0; i < 4; i++) { | ||||||
|  | 				nrf_tx_buf[3 + i] = settings.name[4 + i]; | ||||||
|  | 			} | ||||||
|  | 			nrf_tx_buf[7] = nrf_checksum(nrf_tx_buf, 7, 0); | ||||||
|  | 			nRF24_packet_tx(nrf_tx_buf, NRF_PAYLOAD_LEN, 1); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (nametx) { | ||||||
|  | 			nametx--; | ||||||
|  | 		} else { | ||||||
|  | 			nametx = dc23_nametx * 600; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// profiling: get current counter value
 | ||||||
|  | 	tim6_usage = tim6_usage; | ||||||
|  | 	tim6_usage = TIM6->CNT; | ||||||
|  | 
 | ||||||
|  | 	// clear interrupt bit
 | ||||||
|  | 	TIM_ClearITPendingBit(TIM6, TIM_IT_Update); | ||||||
|  | } | ||||||
							
								
								
									
										735
									
								
								fw_dc22_stm32l100/src/menu/lcd_menu.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										735
									
								
								fw_dc22_stm32l100/src/menu/lcd_menu.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,735 @@ | |||||||
|  | /**
 | ||||||
|  |  * lcd_menu.c: lcd menuing functions, in particular editing functions | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: lcd_menu.c 368 2015-06-16 06:49:48Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "../interface/i2c.h" 		// for writing tempcal to attiny | ||||||
|  | #include "../device/lcd.h" 			// lcd constants, modes and buffer routines | ||||||
|  | 
 | ||||||
|  | #include "../device/attiny.h" 		// for temperature offset editing | ||||||
|  | #include "../device/lightsensor.h" 	// for light gain editing | ||||||
|  | #include "../device/beep.h" 		// for letting you know you did something | ||||||
|  | 
 | ||||||
|  | #include "../display/infopirate.h" | ||||||
|  | #include "lcd_menu.h" | ||||||
|  | 
 | ||||||
|  | #include "menu_radio.h" 			// all the various submenu helper functions and root menu declarations | ||||||
|  | #include "menu_settings.h" 			// editing handlers are in this file though | ||||||
|  | #include "menu_program.h" 			// the actual submenus are in their respective files | ||||||
|  | #include "menu_sensors.h" 			// this is what happens when sleep deprived | ||||||
|  | #include "menu_testing.h" | ||||||
|  | #include "menu_credits.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* lcd */ | ||||||
|  | MenuItem *menuc; | ||||||
|  | uint8_t menu_mode; | ||||||
|  | 
 | ||||||
|  | static uint16_t line_idx[2] = {0xffff, 0xffff}; | ||||||
|  | static uint16_t line_time[2] = {0, 0}; | ||||||
|  | 
 | ||||||
|  | static uint8_t lcd_fn_time = 0; | ||||||
|  | static char lcd_fn_output[64]; | ||||||
|  | 
 | ||||||
|  | void (*lcd_btn_fn[4])(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menus */ | ||||||
|  | uint16_t menu_editing; | ||||||
|  | uint32_t menu_oldval; | ||||||
|  | uint32_t menu_newval; | ||||||
|  | 
 | ||||||
|  | const MenuItem menu_runitem; 	// used for run mode
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* functions */ | ||||||
|  | void lcd_menu_init() | ||||||
|  | { | ||||||
|  | 	// initial menu
 | ||||||
|  | 	if (settings.autorun & 0x01) { | ||||||
|  | 		menuc = (MenuItem *)&menu_runitem; | ||||||
|  | 		menu_root_run(0); | ||||||
|  | 	} else { | ||||||
|  | 		menuc = (MenuItem *)&menu_ritem[0]; | ||||||
|  | 		menu_btntype_menus(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_menu_set(const MenuItem *set) | ||||||
|  | { | ||||||
|  | 	menuc = (MenuItem *)set; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_menu_linescroll_reset(uint8_t idx) | ||||||
|  | { | ||||||
|  | 	line_time[idx] = 0; | ||||||
|  | 	line_idx[idx] = 0xffff; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static uint8_t lcd_menu_linescroll(uint8_t idx, char *dst, char *src, uint8_t maxlen, | ||||||
|  | 			uint8_t spaces, uint16_t time_wait, uint16_t time_run) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	int len; | ||||||
|  | 
 | ||||||
|  | 	char *cpy; | ||||||
|  | 	uint16_t copied = 0; | ||||||
|  | 
 | ||||||
|  | 	len = strlen(src); | ||||||
|  | 
 | ||||||
|  | 	// is this line too long?
 | ||||||
|  | 	if (len > maxlen) { | ||||||
|  | 		// begin scrolling.
 | ||||||
|  | 		// if timeout occurred, update the index
 | ||||||
|  | 		if (line_time[idx] == 0) { | ||||||
|  | 			// set the pause time based on the max length plus padding spaces
 | ||||||
|  | 			// if we are over this limit, we are in "start over" phase and need to use that delay
 | ||||||
|  | 			if (line_idx[idx] > len + spaces) { | ||||||
|  | 				// this is where we start or start over
 | ||||||
|  | 				line_time[idx] = time_wait; | ||||||
|  | 				line_idx[idx] = 0; | ||||||
|  | 			} else { | ||||||
|  | 				// we are in normal continuing phase, use the continuing delay and increment index
 | ||||||
|  | 				line_time[idx] = time_run; | ||||||
|  | 				line_idx[idx]++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		line_time[idx]--; | ||||||
|  | 
 | ||||||
|  | 		// figure out how much to copy
 | ||||||
|  | 		cpy = src + line_idx[idx]; | ||||||
|  | 		len = ((len - maxlen) > line_idx[idx]) ? | ||||||
|  | 				maxlen : | ||||||
|  | 				len - line_idx[idx]; | ||||||
|  | 
 | ||||||
|  | 		// copy up to and including the trailing edge of the text
 | ||||||
|  | 		if (len > 0) { | ||||||
|  | 			for (i = 0; i < len && copied < maxlen; i++) { | ||||||
|  | 				*dst++ = *cpy++; | ||||||
|  | 				copied++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// if we have more left than the length provided, we are done
 | ||||||
|  | 		if (len >= maxlen) { | ||||||
|  | 			return maxlen; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// otherwise, we need to add some spaces
 | ||||||
|  | 		i = spaces; | ||||||
|  | 		if (len < 0) { | ||||||
|  | 			i += len; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// copy the spaces into the stream
 | ||||||
|  | 		if (i) { | ||||||
|  | 			for (; i > 0 && (copied < maxlen); i--) { | ||||||
|  | 				*dst++ = 0x20; | ||||||
|  | 				copied++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// and, if we have room, copy starting from the beginning of the source
 | ||||||
|  | 		while (copied < maxlen) { | ||||||
|  | 			*dst++ = *src++; | ||||||
|  | 			copied++; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return maxlen; | ||||||
|  | 	} else { | ||||||
|  | 		// nope, just copy directly
 | ||||||
|  | 		strncpy(dst, src, maxlen); | ||||||
|  | 		return len; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_menu_update() | ||||||
|  | { | ||||||
|  | 	int line_len; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	// header line static text
 | ||||||
|  | 	if (menuc->root == 0) { | ||||||
|  | 		lcd_menu_linescroll(0, lcd_line[0], LCD_ROOT_TEXT, LCD_MAX_LINE_LENGTH, | ||||||
|  | 					LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN); | ||||||
|  | 	} else if ((int)menuc->root > 255) { | ||||||
|  | 		lcd_menu_linescroll(0, lcd_line[0], menuc->root->this->disp, LCD_MAX_LINE_LENGTH, | ||||||
|  | 				menuc->root->this->scroll_spaces, menuc->root->this->scroll_time_wait, | ||||||
|  | 				menuc->root->this->scroll_time_run); | ||||||
|  | 	} else { | ||||||
|  | 		// maybe we can do other special shit here later
 | ||||||
|  | 		// if set to 255, then external tasks need to update this line
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// TODO: show header line dynamic text? or flag?
 | ||||||
|  | 
 | ||||||
|  | 	// do we update the function-based string?
 | ||||||
|  | 	if (!lcd_fn_time) { | ||||||
|  | 		// reset the timeout value
 | ||||||
|  | 		lcd_fn_time = menuc->this->dispfn_delay; | ||||||
|  | 
 | ||||||
|  | 		// if there was no timeout value, we need to fake one
 | ||||||
|  | 		if (lcd_fn_time == 0) { | ||||||
|  | 			lcd_fn_time++; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// if there is a function attached, call it
 | ||||||
|  | 		if (menuc->this->dispfn != NULL) { | ||||||
|  | 			strncpy(lcd_fn_output, menuc->this->dispfn(menuc->this->disp_id), 63); | ||||||
|  | 			lcd_fn_output[63] = 0; | ||||||
|  | 		} else { | ||||||
|  | 			// no function? no data.
 | ||||||
|  | 			lcd_fn_output[0] = 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	lcd_fn_time--; | ||||||
|  | 
 | ||||||
|  | 	// second line static text
 | ||||||
|  | 	line_len = lcd_menu_linescroll(1, lcd_line[1], menuc->this->disp, LCD_MAX_LINE_LENGTH, | ||||||
|  | 			menuc->this->scroll_spaces, menuc->this->scroll_time_wait, menuc->this->scroll_time_run); | ||||||
|  | 	// second line dynamic text
 | ||||||
|  | 	if (line_len < LCD_MAX_LINE_LENGTH) { | ||||||
|  | 		lcd_menu_linescroll(1, lcd_line[1] + line_len, lcd_fn_output, LCD_MAX_LINE_LENGTH - line_len, | ||||||
|  | 				menuc->this->scroll_spaces, menuc->this->scroll_time_wait, menuc->this->scroll_time_run); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// fix any nulls
 | ||||||
|  | 	for (i = 0; i < 9; i++) { | ||||||
|  | 		if (!lcd_line[0][i]) lcd_line[0][i] = 0x20; | ||||||
|  | 		if (!lcd_line[1][i]) lcd_line[1][i] = 0x20; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* menu nav functions */ | ||||||
|  | void menu_btn_next() | ||||||
|  | { | ||||||
|  | 	if (menuc->next != 0) { | ||||||
|  | 		lcd_menu_set(menuc->next); | ||||||
|  | 		lcd_menu_linescroll_reset(1); | ||||||
|  | 		lcd_fn_output[0] = 0; | ||||||
|  | 
 | ||||||
|  | 		if (settings.beeper) { | ||||||
|  | 			beep(settings.beep_type[0], 10); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_btn_prev() | ||||||
|  | { | ||||||
|  | 	if (menuc->prev != 0) { | ||||||
|  | 		lcd_menu_set(menuc->prev); | ||||||
|  | 		lcd_menu_linescroll_reset(1); | ||||||
|  | 		lcd_fn_output[0] = 0; | ||||||
|  | 
 | ||||||
|  | 		if (settings.beeper) { | ||||||
|  | 			beep(settings.beep_type[0], 10); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_btn_menu() | ||||||
|  | { | ||||||
|  | 	if (menuc->root) { | ||||||
|  | 		// call the root menu's entry function
 | ||||||
|  | 		if (menuc->root->this->entryfn != NULL) { | ||||||
|  | 			menuc->root->this->entryfn(menuc->root->this->entry_id); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// and set to that menu
 | ||||||
|  | 		lcd_menu_set(menuc->root); | ||||||
|  | 		lcd_menu_linescroll_reset(0); | ||||||
|  | 		lcd_menu_linescroll_reset(1); | ||||||
|  | 		lcd_fn_output[0] = 0; | ||||||
|  | 
 | ||||||
|  | 		if (settings.beeper) { | ||||||
|  | 			beep(settings.beep_type[0] - 1, 10); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	menu_btntype_menus(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_btn_ok() | ||||||
|  | { | ||||||
|  | 	// call this menu's entry function
 | ||||||
|  | 	if (menuc->this->entryfn != NULL) { | ||||||
|  | 		menuc->this->entryfn(menuc->this->entry_id); | ||||||
|  | 		if (settings.beeper) { | ||||||
|  | 			beep(settings.beep_type[0] + 1, 10); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// and set to the new menu if available
 | ||||||
|  | 	if (menuc->enter) { | ||||||
|  | 		lcd_menu_set(menuc->enter); | ||||||
|  | 		lcd_menu_linescroll_reset(0); | ||||||
|  | 		lcd_menu_linescroll_reset(1); | ||||||
|  | 		lcd_fn_output[0] = 0; | ||||||
|  | 		if (settings.beeper) { | ||||||
|  | 			beep(settings.beep_type[0], 10); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* menu edit functions */ | ||||||
|  | void menu_edit_next() | ||||||
|  | { | ||||||
|  | 	int work; | ||||||
|  | 	int do_beep = 0; | ||||||
|  | 
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case SETTING_NAME: { | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_CONTRAST: { | ||||||
|  | 			if (menu_newval < 63) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				lcd_set_contrast(menu_newval); | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_FAVCOLOR_RED: | ||||||
|  | 		case SETTING_FAVCOLOR_GREEN: | ||||||
|  | 		case SETTING_FAVCOLOR_BLUE: { | ||||||
|  | 			if (menu_newval < 0xff) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				settings.fav_color[menu_editing - SETTING_FAVCOLOR_RED] = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BEEP_TYPE_BUTTON: | ||||||
|  | 		case SETTING_BEEP_TYPE_PAGING: | ||||||
|  | 		case SETTING_BEEP_TYPE_ALARM: { | ||||||
|  | 			if (menu_newval < 30) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				settings.beep_type[menu_editing - SETTING_BEEP_TYPE_BUTTON] = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SENSOR_LIGHT_SETTINGSGAIN: { | ||||||
|  | 			if (menu_newval == 0) { | ||||||
|  | 				menu_newval = LIGHTSENS_GAIN_MIN; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} else if (menu_newval < LIGHTSENS_GAIN_MAX) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			settings.light_setgain = menu_newval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BRITE_LCD_VALUE: { | ||||||
|  | 			if (menu_newval < 200) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				settings.lcd_brightness = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_LO: { | ||||||
|  | 			if (menu_newval < 160) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				settings.led_autogain_lev_min = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_HI: { | ||||||
|  | 			if (menu_newval < 160) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				settings.led_autogain_lev_max = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_THRESH0: | ||||||
|  | 		case SETTING_BRITE_THRESH1: | ||||||
|  | 		case SETTING_BRITE_THRESH2: | ||||||
|  | 		case SETTING_BRITE_THRESH3: | ||||||
|  | 		case SETTING_BRITE_THRESH4: { | ||||||
|  | 			work = menu_editing - SETTING_BRITE_THRESH0; | ||||||
|  | 
 | ||||||
|  | 			if (menu_editing == SETTING_BRITE_THRESH4) { | ||||||
|  | 				work = LIGHTSENS_GAIN_MAX; | ||||||
|  | 			} else { | ||||||
|  | 				work = settings.led_autothresh[work + 1] - 1; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (menu_newval < work) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				settings.led_autothresh[menu_editing - SETTING_BRITE_THRESH0] = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SENSOR_TEMP_CALVALUE: { | ||||||
|  | 			if (temperature_cal < 60) { | ||||||
|  | 				temperature_cal++; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (do_beep) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_edit_prev() | ||||||
|  | { | ||||||
|  | 	int work; | ||||||
|  | 	int do_beep = 0; | ||||||
|  | 
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case SETTING_NAME: { | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_CONTRAST: { | ||||||
|  | 			if (settings.contrast) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				lcd_set_contrast(menu_newval); | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_FAVCOLOR_RED: | ||||||
|  | 		case SETTING_FAVCOLOR_GREEN: | ||||||
|  | 		case SETTING_FAVCOLOR_BLUE: { | ||||||
|  | 			if (menu_newval) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				settings.fav_color[menu_editing - SETTING_FAVCOLOR_RED] = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BEEP_TYPE_BUTTON: | ||||||
|  | 		case SETTING_BEEP_TYPE_PAGING: | ||||||
|  | 		case SETTING_BEEP_TYPE_ALARM: { | ||||||
|  | 			if (menu_newval > 1) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				settings.beep_type[menu_editing - SETTING_BEEP_TYPE_BUTTON] = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SENSOR_LIGHT_SETTINGSGAIN: { | ||||||
|  | 			if (menu_newval > LIGHTSENS_GAIN_MIN) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} else if (menu_newval == LIGHTSENS_GAIN_MIN) { | ||||||
|  | 				menu_newval = 0; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			settings.light_setgain = menu_newval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BRITE_LCD_VALUE: { | ||||||
|  | 			if (menu_newval) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				settings.lcd_brightness = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_LO: { | ||||||
|  | 			if (menu_newval > 0) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				settings.led_autogain_lev_min = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_HI: { | ||||||
|  | 			if (menu_newval > 0) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				settings.led_autogain_lev_max = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_THRESH0: | ||||||
|  | 		case SETTING_BRITE_THRESH1: | ||||||
|  | 		case SETTING_BRITE_THRESH2: | ||||||
|  | 		case SETTING_BRITE_THRESH3: | ||||||
|  | 		case SETTING_BRITE_THRESH4: { | ||||||
|  | 			work = menu_editing - SETTING_BRITE_THRESH0; | ||||||
|  | 
 | ||||||
|  | 			if (!work) { | ||||||
|  | 				work = LIGHTSENS_GAIN_MIN; | ||||||
|  | 			} else { | ||||||
|  | 				work = settings.led_autothresh[work - 1] + 1; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (menu_newval > work) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				settings.led_autothresh[menu_editing - SETTING_BRITE_THRESH0] = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SENSOR_TEMP_CALVALUE: { | ||||||
|  | 			if (temperature_cal > -20) { | ||||||
|  | 				temperature_cal--; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (do_beep) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_edit_menu() | ||||||
|  | { | ||||||
|  | 	// values in this switch need to REVERT previous settings
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case SETTING_NAME: { | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_CONTRAST: { | ||||||
|  | 			lcd_set_contrast(menu_oldval); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_FAVCOLOR_RED: | ||||||
|  | 		case SETTING_FAVCOLOR_GREEN: | ||||||
|  | 		case SETTING_FAVCOLOR_BLUE: { | ||||||
|  | 			settings.fav_color[menu_editing - SETTING_FAVCOLOR_RED] = menu_oldval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BEEP_TYPE_BUTTON: | ||||||
|  | 		case SETTING_BEEP_TYPE_PAGING: | ||||||
|  | 		case SETTING_BEEP_TYPE_ALARM: { | ||||||
|  | 			settings.beep_type[menu_editing - SETTING_BEEP_TYPE_BUTTON] = menu_oldval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SENSOR_LIGHT_SETTINGSGAIN: { | ||||||
|  | 			settings.light_setgain = menu_oldval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BRITE_LCD_VALUE: { | ||||||
|  | 			settings.lcd_brightness = menu_oldval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_LO: { | ||||||
|  | 			settings.led_autogain_lev_min = menu_oldval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_HI: { | ||||||
|  | 			settings.led_autogain_lev_max = menu_oldval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_THRESH0: | ||||||
|  | 		case SETTING_BRITE_THRESH1: | ||||||
|  | 		case SETTING_BRITE_THRESH2: | ||||||
|  | 		case SETTING_BRITE_THRESH3: | ||||||
|  | 		case SETTING_BRITE_THRESH4: { | ||||||
|  | 			settings.led_autothresh[menu_editing - SETTING_BRITE_THRESH0] = menu_oldval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 		case SENSOR_TEMP_CALVALUE: { | ||||||
|  | 			temperature_cal = 0; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// stop editing and return to menu control
 | ||||||
|  | 	menu_editing = 0; | ||||||
|  | 	menu_btntype_menus(); | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_edit_ok() | ||||||
|  | { | ||||||
|  | 	// values in this switch need to COMMIT edited settings
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case SENSOR_TEMP_CALVALUE: { | ||||||
|  | 			I2C_WriteTransfer(ATTINY_I2C_ADDR, (uint8_t *)&temperature_cal, 1, ATTINY_CMD_TEMP_CAL, 1); | ||||||
|  | 			temperature_cal = 0; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		default: {break;} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// stop editing and return to menu control
 | ||||||
|  | 	menu_editing = 0; | ||||||
|  | 	menu_btntype_menus(); | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0] + 1, 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_edit_start(uint16_t id) | ||||||
|  | { | ||||||
|  | 	menu_editing = id; | ||||||
|  | 
 | ||||||
|  | 	// set edited value
 | ||||||
|  | 	switch (id) { | ||||||
|  | 		case SETTING_CONTRAST: { | ||||||
|  | 			menu_oldval = menu_newval = settings.contrast; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_FAVCOLOR_RED: | ||||||
|  | 		case SETTING_FAVCOLOR_GREEN: | ||||||
|  | 		case SETTING_FAVCOLOR_BLUE: { | ||||||
|  | 			menu_newval = menu_oldval = settings.fav_color[menu_editing - SETTING_FAVCOLOR_RED]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BEEP_TYPE_BUTTON: | ||||||
|  | 		case SETTING_BEEP_TYPE_PAGING: | ||||||
|  | 		case SETTING_BEEP_TYPE_ALARM: { | ||||||
|  | 			menu_newval = menu_oldval = settings.beep_type[menu_editing - SETTING_BEEP_TYPE_BUTTON]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SENSOR_LIGHT_SETTINGSGAIN: { | ||||||
|  | 			menu_newval = menu_oldval = settings.light_setgain; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BRITE_LCD_VALUE: { | ||||||
|  | 			menu_newval = menu_oldval = settings.lcd_brightness; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_LO: { | ||||||
|  | 			menu_newval = menu_oldval = settings.led_autogain_lev_min; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_HI: { | ||||||
|  | 			menu_newval = menu_oldval = settings.led_autogain_lev_max; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_THRESH0: | ||||||
|  | 		case SETTING_BRITE_THRESH1: | ||||||
|  | 		case SETTING_BRITE_THRESH2: | ||||||
|  | 		case SETTING_BRITE_THRESH3: | ||||||
|  | 		case SETTING_BRITE_THRESH4: { | ||||||
|  | 			menu_newval = menu_oldval = settings.led_autothresh[menu_editing - SETTING_BRITE_THRESH0]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SENSOR_TEMP_CALVALUE: { | ||||||
|  | 			temperature_cal = 0; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// set buttons to editing control
 | ||||||
|  | 	menu_btntype_editing(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* menu fn pointer set functions */ | ||||||
|  | void menu_btntype_menus() | ||||||
|  | { | ||||||
|  | 	menu_mode = MENU_MODE_NAVIGATING_MENUS; | ||||||
|  | 
 | ||||||
|  | 	lcd_btn_fn[BTN_UP] = menu_btn_prev; | ||||||
|  | 	lcd_btn_fn[BTN_MENU] = menu_btn_menu; | ||||||
|  | 	lcd_btn_fn[BTN_OK] = menu_btn_ok; | ||||||
|  | 	lcd_btn_fn[BTN_DOWN] = menu_btn_next; | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_1, LCD_CMD_NO_CURSOR_FLASH); | ||||||
|  | 	lcd_set_height(LCD_CMD_SINGLEHEIGHT); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_btntype_run() | ||||||
|  | { | ||||||
|  | 	menu_mode = MENU_MODE_RUNNING_PROGRAM; | ||||||
|  | 
 | ||||||
|  | 	lcd_btn_fn[BTN_UP] = menu_infopirate_btn_prev; | ||||||
|  | 	lcd_btn_fn[BTN_MENU] = menu_btn_menu; | ||||||
|  | 	lcd_btn_fn[BTN_OK] = menu_infopirate_btn_ok; | ||||||
|  | 	lcd_btn_fn[BTN_DOWN] = menu_infopirate_btn_next; | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_1, LCD_CMD_NO_CURSOR_FLASH); | ||||||
|  | 	lcd_set_height(LCD_CMD_DOUBLEHEIGHT); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_btntype_editing() | ||||||
|  | { | ||||||
|  | 	menu_mode = MENU_MODE_EDITING; | ||||||
|  | 
 | ||||||
|  | 	lcd_btn_fn[BTN_UP] = menu_edit_prev; | ||||||
|  | 	lcd_btn_fn[BTN_MENU] = menu_edit_menu; | ||||||
|  | 	lcd_btn_fn[BTN_OK] = menu_edit_ok; | ||||||
|  | 	lcd_btn_fn[BTN_DOWN] = menu_edit_next; | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2 + 7, LCD_CMD_CURSOR_FLASH); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |   // run mode
 | ||||||
|  | void menu_root_run(uint16_t id) | ||||||
|  | { | ||||||
|  | 	prog_init(); | ||||||
|  | 	infopirate_init(); | ||||||
|  | 	menu_btntype_run(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu construction */ | ||||||
|  |   // root menu
 | ||||||
|  | const MenuData menu_rdata[9] = { | ||||||
|  | 	{"Run!",     NULL, 0, 0, 0, 0, 0, menu_root_run,      0}, | ||||||
|  | 	{"Radio",    NULL, 0, 0, 0, 0, 0, NULL,               0}, | ||||||
|  | 	{"Settings", NULL, 0, 0, 0, 0, 0, NULL,               0}, | ||||||
|  | 	{"Programs", NULL, 0, 0, 0, 0, 0, NULL,               0}, | ||||||
|  | 	{"Save",     NULL, 0, 0, 0, 0, 0, menu_settings_save, 0}, | ||||||
|  | 	{"Sensors",  NULL, 0, 0, 0, 0, 0, NULL,               0}, | ||||||
|  | 	{"Testing",  NULL, 0, 0, 0, 0, 0, NULL,               0}, | ||||||
|  | 	{"Credits",  NULL, 0, 0, 0, 0, 0, NULL,               0}, | ||||||
|  | 	{"Shutdown", NULL, 0, 0, 0, 0, 0, pirate_shutdown,    0} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_ritem[9] = { | ||||||
|  | 	{0,              0, &menu_ritem[1],       &menu_runitem, &menu_rdata[0]}, | ||||||
|  | 	{0, &menu_ritem[0], &menu_ritem[2], &menu_comm_ritem[0], &menu_rdata[1]}, | ||||||
|  | 	{0, &menu_ritem[1], &menu_ritem[3], &menu_pref_ritem[0], &menu_rdata[2]}, | ||||||
|  | 	{0, &menu_ritem[2], &menu_ritem[4], &menu_prog_ritem[0], &menu_rdata[3]}, | ||||||
|  | 	{0, &menu_ritem[3], &menu_ritem[5],                   0, &menu_rdata[4]}, | ||||||
|  | 	{0, &menu_ritem[4], &menu_ritem[6], &menu_sens_ritem[0], &menu_rdata[5]}, | ||||||
|  | 	{0, &menu_ritem[5], &menu_ritem[7], &menu_test_ritem[0], &menu_rdata[6]}, | ||||||
|  | 	{0, &menu_ritem[6], &menu_ritem[8], &menu_cred_ritem[0], &menu_rdata[7]}, | ||||||
|  | 	{0, &menu_ritem[7],              0,                   0, &menu_rdata[8]}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // run entry
 | ||||||
|  | const MenuData menu_rundata = {"", NULL, 0, 4, 0, 0, 0, NULL, 0}; | ||||||
|  | const MenuItem menu_runitem = {&menu_ritem[0], 0, 0, 0, &menu_rundata}; | ||||||
							
								
								
									
										106
									
								
								fw_dc22_stm32l100/src/menu/lcd_menu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								fw_dc22_stm32l100/src/menu/lcd_menu.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | |||||||
|  | /**
 | ||||||
|  |  * lcd_menu.c: lcd menuing prototypes | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: lcd_menu.h 374 2015-06-29 02:06:22Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_LCD_MENU_H | ||||||
|  | #define __PIRATE_LCD_MENU_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define LCD_ROOT_TEXT 				"WP DC22 and DC23 Badge v0.3d by true" | ||||||
|  | 
 | ||||||
|  | #define LCD_DEF_SPACING 			4 | ||||||
|  | #define LCD_DEF_SCROLL_WAIT 		144 | ||||||
|  | #define LCD_DEF_SCROLL_RUN 			16 | ||||||
|  | 
 | ||||||
|  | #define LCD_MENU_ROOT_COMMS 		1 | ||||||
|  | #define LCD_MENU_ROOT_SETTINGS 		2 | ||||||
|  | #define LCD_MENU_ROOT_PROGRAMS 		3 | ||||||
|  | #define LCD_MENU_ROOT_SENSORS 		5 | ||||||
|  | #define LCD_MENU_ROOT_TESTING 		6 | ||||||
|  | #define LCD_MENU_ROOT_CREDITS 		7 | ||||||
|  | 
 | ||||||
|  | #define BTN_UP 						0 | ||||||
|  | #define BTN_MENU 					1 | ||||||
|  | #define BTN_OK 						2 | ||||||
|  | #define BTN_DOWN 					3 | ||||||
|  | 
 | ||||||
|  | #define MENU_MODE_NAVIGATING_MENUS 	0 | ||||||
|  | #define MENU_MODE_EDITING 			1 | ||||||
|  | #define MENU_MODE_RUNNING_PROGRAM 	2 | ||||||
|  | #define MENU_MODE_PROGRAM_EDITOR 	3 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* struct */ | ||||||
|  | typedef struct MenuData { | ||||||
|  | 	char *disp; 					// string to display
 | ||||||
|  | 	char * (*dispfn)(uint16_t id); 	// function which returns string to display
 | ||||||
|  | 	uint16_t disp_id; 				// index to pass to dispfn
 | ||||||
|  | 	uint8_t dispfn_delay; 			// how many 5000hz ticks to wait before re-calling dispfn
 | ||||||
|  | 	uint8_t scroll_spaces; 			// how many spaces between scroll; 0 disables scroll
 | ||||||
|  | 	uint8_t scroll_time_wait; 		// how long to wait before (re)scrolling
 | ||||||
|  | 	uint8_t scroll_time_run; 		// how long to wait between characters
 | ||||||
|  | 	void (*entryfn)(uint16_t eid); 	// function to call when entering menu
 | ||||||
|  | 	uint16_t entry_id; 				// index to pass to entryfn
 | ||||||
|  | } MenuData; | ||||||
|  | 
 | ||||||
|  | typedef struct MenuItem MenuItem; | ||||||
|  | struct MenuItem { | ||||||
|  | 	const MenuItem *root; | ||||||
|  | 	const MenuItem *prev; | ||||||
|  | 	const MenuItem *next; | ||||||
|  | 	const MenuItem *enter; | ||||||
|  | 	const MenuData *this; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* lcd variables */ | ||||||
|  | extern MenuItem *menuc; | ||||||
|  | extern const MenuItem menu_ritem[9]; | ||||||
|  | 
 | ||||||
|  | extern void (*lcd_btn_fn[4])(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu variables */ | ||||||
|  | extern uint8_t menu_mode; | ||||||
|  | 
 | ||||||
|  | extern uint16_t menu_editing; | ||||||
|  | extern uint32_t menu_oldval; | ||||||
|  | extern uint32_t menu_newval; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu constants */ | ||||||
|  | extern const MenuItem menu_runitem; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void lcd_menu_init(); | ||||||
|  | void lcd_menu_set(const MenuItem *set); | ||||||
|  | void lcd_menu_update(); | ||||||
|  | 
 | ||||||
|  | void lcd_menu_linescroll_reset(uint8_t idx); | ||||||
|  | 
 | ||||||
|  | void menu_edit_start(uint16_t id); | ||||||
|  | void menu_root_run(uint16_t id); | ||||||
|  | 
 | ||||||
|  | void menu_btn_next(); | ||||||
|  | void menu_btn_prev(); | ||||||
|  | void menu_btn_menu(); | ||||||
|  | void menu_btn_ok(); | ||||||
|  | 
 | ||||||
|  | void menu_btntype_menus(); | ||||||
|  | void menu_btntype_run(); | ||||||
|  | void menu_btntype_editing(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										43
									
								
								fw_dc22_stm32l100/src/menu/menu_credits.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								fw_dc22_stm32l100/src/menu/menu_credits.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_credits.c: we are legit | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_credits.c 350 2015-05-28 02:23:03Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "lcd_menu.h" | ||||||
|  | #include "menu_credits.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu construction */ | ||||||
|  | const MenuData menu_cred_rdata[] = { | ||||||
|  | 	{"idea by rCON and true (at the last minute)",   NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"T3K shipmates Bad Kobold and the lord canon",  NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"a fire? don't blame us if you didn't know",    NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"financed by captain rCON's billions",          NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"code and design rushed by true",               NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"the lord canon's divorce",                     NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"keep it between the bones, guys",              NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"is your badge shit? did it break? blame BK",   NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"always  need moar cake from avah",             NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"do what you want 'cause a pirate is free",     NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT - 40, LCD_DEF_SCROLL_RUN - 4, NULL, 0}, | ||||||
|  | 	{"you are A PIRATE",                             NULL, 0, 0, 3, LCD_DEF_SCROLL_WAIT,      LCD_DEF_SCROLL_RUN + 2, NULL, 0} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_cred_ritem[] = { | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS],                   0,  &menu_cred_ritem[1], 0,  &menu_cred_rdata[0]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[0],  &menu_cred_ritem[2], 0,  &menu_cred_rdata[1]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[1],  &menu_cred_ritem[3], 0,  &menu_cred_rdata[2]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[2],  &menu_cred_ritem[4], 0,  &menu_cred_rdata[3]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[3],  &menu_cred_ritem[5], 0,  &menu_cred_rdata[4]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[4],  &menu_cred_ritem[6], 0,  &menu_cred_rdata[5]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[5],  &menu_cred_ritem[7], 0,  &menu_cred_rdata[6]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[6],  &menu_cred_ritem[7], 0,  &menu_cred_rdata[7]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[7],  &menu_cred_ritem[8], 0,  &menu_cred_rdata[8]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[8], &menu_cred_ritem[10], 0,  &menu_cred_rdata[9]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_CREDITS], &menu_cred_ritem[9],                    0, 0, &menu_cred_rdata[10]} | ||||||
|  | }; | ||||||
							
								
								
									
										21
									
								
								fw_dc22_stm32l100/src/menu/menu_credits.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								fw_dc22_stm32l100/src/menu/menu_credits.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_credits.h: we are a pirates | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_credits.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_MENU_CREDITS_H | ||||||
|  | #define __PIRATE_MENU_CREDITS_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* credits menus */ | ||||||
|  | extern const MenuItem menu_cred_ritem[]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										786
									
								
								fw_dc22_stm32l100/src/menu/menu_program.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										786
									
								
								fw_dc22_stm32l100/src/menu/menu_program.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,786 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_program.c: led and lcd program selection and configuration | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_program.c 368 2015-06-16 06:49:48Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "../device/lcd.h" | ||||||
|  | 
 | ||||||
|  | #include "../device/attiny.h" 	// eyes | ||||||
|  | #include "../device/beep.h" | ||||||
|  | 
 | ||||||
|  | #include "../led/led_matrix.h" | ||||||
|  | #include "../led/led_bone.h" | ||||||
|  | 
 | ||||||
|  | #include "lcd_menu.h" | ||||||
|  | #include "menu_program.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // programs
 | ||||||
|  | static char prog_str[20]; 		// program names max 16 characters (currently coded to 15 characters)
 | ||||||
|  | 
 | ||||||
|  | static uint8_t prog_type; 		// which menu has been selected (skull, bones, eyes)
 | ||||||
|  | static uint8_t prog_idx; 		// which program is being edited within the menu
 | ||||||
|  | 
 | ||||||
|  | static uint16_t prog_hex_val; 	// the value being edited
 | ||||||
|  | 
 | ||||||
|  | extern uint16_t menu_editing; 	// lcd_menu.h
 | ||||||
|  | extern uint32_t menu_oldval; | ||||||
|  | extern uint32_t menu_newval; | ||||||
|  | 
 | ||||||
|  |   // program running
 | ||||||
|  | uint8_t prog_id[3]; | ||||||
|  | uint16_t prog_dwell[3]; | ||||||
|  | 
 | ||||||
|  |   // program names
 | ||||||
|  | const char led_matrix_prog_name[LED_MATRIX_PROG_COUNT][16]; | ||||||
|  | const char led_bone_prog_name[LED_BONE_PROG_COUNT][16]; | ||||||
|  | const char led_eyes_prog_name[LED_EYES_PROG_COUNT][16]; | ||||||
|  | 
 | ||||||
|  | const char (*prog_name[3])[16] = { | ||||||
|  | 	led_matrix_prog_name, | ||||||
|  | 	led_bone_prog_name, | ||||||
|  | 	led_eyes_prog_name | ||||||
|  | }; | ||||||
|  | const uint8_t prog_count[3] = { | ||||||
|  | 	LED_MATRIX_PROG_COUNT, | ||||||
|  | 	LED_BONE_PROG_COUNT, | ||||||
|  | 	LED_EYES_PROG_COUNT | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // programs menu forward declaration
 | ||||||
|  | const MenuItem menu_prog_leditem[]; | ||||||
|  | const MenuItem menu_prog_ledaitem; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* external program functions */ | ||||||
|  | /********
 | ||||||
|  |  * initialize variables for program running | ||||||
|  |  ********/ | ||||||
|  | void prog_init() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 3; i++) { | ||||||
|  | 		prog_id[i] = 255; | ||||||
|  | 		prog_dwell[i] = 0; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t prog_get_mode(uint8_t id) | ||||||
|  | { | ||||||
|  | 	return (settings.led_prog_mode >> (id << 1)) & 0x03; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t menu_prog_get_type() | ||||||
|  | { | ||||||
|  | 	return prog_type; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t menu_prog_get_idx() | ||||||
|  | { | ||||||
|  | 	return prog_idx; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* program functions */ | ||||||
|  | char * menu_prog_disp(uint16_t id) | ||||||
|  | { | ||||||
|  | 	switch (id) { | ||||||
|  | 		case PROG_GLOBAL_MODE: { | ||||||
|  | 			switch ((settings.led_prog_mode >> (prog_type << 1)) & 0x03) { | ||||||
|  | 				case 0b00: 	return " Off"; | ||||||
|  | 				case 0b01: 	return "Nrml"; | ||||||
|  | 				case 0b10: 	return "Rand"; | ||||||
|  | 				default: 	return ""; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_GLOBAL_CHANGEIDX: { | ||||||
|  | 			prog_str[0] = '#'; | ||||||
|  | 			prog_str[1] = 0; | ||||||
|  | 			strncat(prog_str, pirate_sitoa(prog_idx + 1, 10, 2), 4); | ||||||
|  | 			if (prog_str[1] == 0x00 || prog_str[1] == 0x20) prog_str[1] = 0x30; | ||||||
|  | 			return prog_str; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_EDIT_ENABLE: { | ||||||
|  | 			if (settings.led_prog[prog_type][prog_idx].type & 0x80) { | ||||||
|  | 				return "Y"; | ||||||
|  | 			} else { | ||||||
|  | 				return "N"; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_FORCE_INIT: { | ||||||
|  | 			if (settings.led_prog[prog_type][prog_idx].type & 0x02) { | ||||||
|  | 				return "Y"; | ||||||
|  | 			} else { | ||||||
|  | 				return "N"; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_PROG_ID: { | ||||||
|  | 			prog_str[0] = 0; | ||||||
|  | 			prog_str[1] = 0; | ||||||
|  | 			strncat(prog_str, pirate_sitoa(settings.led_prog[prog_type][prog_idx].progidx, 10, 2), 4); | ||||||
|  | 			if (prog_str[0] == 0x00 || prog_str[0] == 0x20) prog_str[0] = 0x30; | ||||||
|  | 			return prog_str; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		default: {return "";} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char * prog_type_edit_str(uint16_t id) { | ||||||
|  | 	switch (id) { | ||||||
|  | 		case PROG_TYPE_SKULL: 		{strcpy(prog_str, "Skull   "); prog_str[5] = 0; break;} | ||||||
|  | 		case PROG_TYPE_BONES: 		{strcpy(prog_str, "Bones   "); prog_str[5] = 0; break;} | ||||||
|  | 		case PROG_TYPE_EYES: 		{strcpy(prog_str, "Eyes    "); prog_str[5] = 0; break;} | ||||||
|  | 		case PROG_TYPE_INFOPIR8: 	return "InfoPir8"; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (menu_mode == MENU_MODE_PROGRAM_EDITOR) { | ||||||
|  | 		if (prog_idx < PIRATE_PROG_SAVED_MAX) { | ||||||
|  | 			strncat(prog_str, "#", 8); | ||||||
|  | 			strncat(prog_str, pirate_sitoa(prog_idx + 1, 10, 2), 8); | ||||||
|  | 
 | ||||||
|  | 			if (prog_str[6] == 0x20 || prog_str[6] == 0x00) prog_str[6] = 0x30; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	prog_str[8] = 0x00; | ||||||
|  | 
 | ||||||
|  | 	return prog_str; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char * prog_dwell_str(uint16_t id) | ||||||
|  | { | ||||||
|  | 	strcpy(prog_str, pirate_sitoa(settings.led_prog[prog_type][prog_idx].dwell, 10, 2)); | ||||||
|  | 
 | ||||||
|  | 	if (settings.led_prog[prog_type][prog_idx].dwell <= 99) { | ||||||
|  | 		strncat(prog_str, "s", 4); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return prog_str; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char * prog_advanced_str(uint16_t id) | ||||||
|  | { | ||||||
|  | 	uint32_t work; | ||||||
|  | 
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case PROG_EDIT_PROG_ID: { | ||||||
|  | 			work = settings.led_prog[prog_type][prog_idx].progidx; | ||||||
|  | 			strcpy(prog_str, pirate_sitoa(work, 10, 0)); | ||||||
|  | 			strncat(prog_str, ":", 19); | ||||||
|  | 			strncat(prog_str, prog_name[prog_type][work], 19); | ||||||
|  | 			prog_str[19] = 0; | ||||||
|  | 			return prog_str; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_CYCLESPEED: { | ||||||
|  | 			work = settings.led_prog[prog_type][prog_idx].wait; | ||||||
|  | 			strcpy(prog_str, pirate_sitoa(work, 10, 6)); | ||||||
|  | 			strncat(prog_str, "ms", 8); | ||||||
|  | 			prog_str[8] = 0; | ||||||
|  | 			return prog_str; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_LEVEL: { | ||||||
|  | 			work = settings.led_prog[prog_type][prog_idx].level; | ||||||
|  | 			strcpy(prog_str, " 0x"); | ||||||
|  | 			strncat(prog_str, pirate_itoa(work, 16, 4), 6); | ||||||
|  | 
 | ||||||
|  | 			for (work = 3; work < 6; work++) { | ||||||
|  | 				if (prog_str[work] == 0x00 || prog_str[work] == 0x20) prog_str[work] = 0x30; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			prog_str[8] = 0; | ||||||
|  | 			return prog_str; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OFFSET: { | ||||||
|  | 			work = settings.led_prog[prog_type][prog_idx].offset; | ||||||
|  | 			strncpy(prog_str, pirate_itoa(work, 16, 8), 8); | ||||||
|  | 
 | ||||||
|  | 			for (work = 0; work < 8; work++) { | ||||||
|  | 				if (prog_str[work] == 0x00 || prog_str[work] == 0x20) prog_str[work] = 0x30; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			prog_str[8] = 0; | ||||||
|  | 			return prog_str; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OPTIONS: { | ||||||
|  | 			work = settings.led_prog[prog_type][prog_idx].option; | ||||||
|  | 			strncpy(prog_str, pirate_itoa(work, 16, 8), 8); | ||||||
|  | 
 | ||||||
|  | 			for (work = 0; work < 8; work++) { | ||||||
|  | 				if (prog_str[work] == 0x00 || prog_str[work] == 0x20) prog_str[work] = 0x30; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			prog_str[8] = 0; | ||||||
|  | 			return prog_str; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		default: {return "";} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* program editing */ | ||||||
|  | void menu_prog_edit_start(uint16_t id) | ||||||
|  | { | ||||||
|  | 	int cursor = 0; | ||||||
|  | 
 | ||||||
|  | 	menu_editing = id; | ||||||
|  | 
 | ||||||
|  | 	switch (id) { | ||||||
|  | 		case PROG_EDIT_PROG_DWELL: { | ||||||
|  | 			menu_newval = menu_oldval = settings.led_prog[prog_type][prog_idx].dwell; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_GLOBAL_CHANGEIDX: { | ||||||
|  | 			menu_newval = menu_oldval = prog_idx; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_EDIT_PROG_ID: { | ||||||
|  | 			menuc = (MenuItem *)&menu_prog_ledaitem; | ||||||
|  | 			strcpy(lcd_line[0], "Choose: "); | ||||||
|  | 			menu_oldval = settings.led_prog[prog_type][prog_idx].progidx; | ||||||
|  | 			cursor = 1; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_EDIT_CYCLESPEED: { | ||||||
|  | 			menuc = (MenuItem *)&menu_prog_ledaitem; | ||||||
|  | 			strcpy(lcd_line[0], "CycleSpd"); | ||||||
|  | 			menu_oldval = settings.led_prog[prog_type][prog_idx].wait; | ||||||
|  | 			cursor = 1; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!cursor) { | ||||||
|  | 		lcd_set_cursor(LCD_LINE_2 + 7, LCD_CMD_CURSOR_FLASH); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void prog_edit_tog_mode(uint16_t id) | ||||||
|  | { | ||||||
|  | 	int mode; | ||||||
|  | 
 | ||||||
|  | 	mode = (settings.led_prog_mode >> (prog_type << 1)) & 0b11; | ||||||
|  | 	mode++; | ||||||
|  | 
 | ||||||
|  | 	if (mode > 2) mode = 0; | ||||||
|  | 
 | ||||||
|  | 	settings.led_prog_mode &= ~(0b11 << (prog_type << 1)); | ||||||
|  | 	settings.led_prog_mode |= (mode << (prog_type << 1)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void prog_edit_tog_enable(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (prog_idx < PIRATE_PROG_SAVED_MAX) { | ||||||
|  | 		if (settings.led_prog[prog_type][prog_idx].type & 0x80) { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].type &= 0x7f; | ||||||
|  | 		} else { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].type |= 0x80; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void prog_edit_tog_type(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (prog_idx < PIRATE_PROG_SAVED_MAX) { | ||||||
|  | 		if (settings.led_prog[prog_type][prog_idx].type & 0x01) { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].type &= 0xfe; | ||||||
|  | 		} else { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].type |= 0x01; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void prog_edit_tog_force_init(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (prog_idx < PIRATE_PROG_SAVED_MAX) { | ||||||
|  | 		if (settings.led_prog[prog_type][prog_idx].type & 0x02) { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].type &= 0xfd; | ||||||
|  | 		} else { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].type |= 0x02; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* program button handlers */ | ||||||
|  | static void menu_btn_prog_prev() | ||||||
|  | { | ||||||
|  | 	int do_beep = 0; | ||||||
|  | 	uint32_t work; | ||||||
|  | 
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case 0: { | ||||||
|  | 			menu_btn_prev(); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_EDIT_PROG_DWELL: { | ||||||
|  | 			if (menu_newval > 1) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].dwell = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_GLOBAL_CHANGEIDX: { | ||||||
|  | 			if (menu_newval) { | ||||||
|  | 				menu_newval--; | ||||||
|  | 				prog_idx = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_PROG_ID: { | ||||||
|  | 			if (settings.led_prog[prog_type][prog_idx].progidx) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].progidx--; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_CYCLESPEED: { | ||||||
|  | 			work = settings.led_prog[prog_type][prog_idx].wait; | ||||||
|  | 			do_beep = settings.beeper; | ||||||
|  | 
 | ||||||
|  | 			if (work > 1000) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].wait -= 50; | ||||||
|  | 			} else if (work > 100) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].wait -= 20; | ||||||
|  | 			} else if (work > 10) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].wait -= 5; | ||||||
|  | 			} else if (work > 1) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].wait--; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (do_beep) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lcd_menu_linescroll_reset(1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_btn_prog_next() | ||||||
|  | { | ||||||
|  | 	int do_beep = 0; | ||||||
|  | 	uint32_t work; | ||||||
|  | 
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case 0: { | ||||||
|  | 			menu_btn_next(); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_EDIT_PROG_DWELL: { | ||||||
|  | 			if (menu_newval < 240) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].dwell = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_GLOBAL_CHANGEIDX: { | ||||||
|  | 			if (menu_newval < PIRATE_PROG_SAVED_MAX - 1) { | ||||||
|  | 				menu_newval++; | ||||||
|  | 				prog_idx = menu_newval; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_PROG_ID: { | ||||||
|  | 			if (settings.led_prog[prog_type][prog_idx].progidx < (prog_count[prog_type] - 1)) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].progidx++; | ||||||
|  | 				do_beep = settings.beeper; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_CYCLESPEED: { | ||||||
|  | 			work = settings.led_prog[prog_type][prog_idx].wait; | ||||||
|  | 			do_beep = settings.beeper; | ||||||
|  | 
 | ||||||
|  | 			if (work < 10) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].wait++; | ||||||
|  | 			} else if (work < 100) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].wait += 5; | ||||||
|  | 			} else if (work < 1000) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].wait += 20; | ||||||
|  | 			} else if (work < 5000) { | ||||||
|  | 				settings.led_prog[prog_type][prog_idx].wait += 50; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (do_beep) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lcd_menu_linescroll_reset(1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_btn_prog_menu() | ||||||
|  | { | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case 0: { | ||||||
|  | 			menuc = (MenuItem *)&menu_prog_ritem[prog_type]; | ||||||
|  | 
 | ||||||
|  | 			prog_type = 0; | ||||||
|  | 			prog_idx = 0; | ||||||
|  | 
 | ||||||
|  | 			menu_btntype_menus(); | ||||||
|  | 
 | ||||||
|  | 			if (settings.beeper) { | ||||||
|  | 				beep(settings.beep_type[0] - 1, 10); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_EDIT_PROG_DWELL: { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].dwell = menu_oldval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_GLOBAL_CHANGEIDX: { | ||||||
|  | 			prog_idx = menu_oldval; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_EDIT_PROG_ID: { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].progidx = menu_oldval; | ||||||
|  | 			strcpy(lcd_line[0], prog_type_edit_str(prog_type)); | ||||||
|  | 			menuc = (MenuItem *)&menu_prog_leditem[5]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_CYCLESPEED: { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].wait = menu_oldval; | ||||||
|  | 			strcpy(lcd_line[0], prog_type_edit_str(prog_type)); | ||||||
|  | 			menuc = (MenuItem *)&menu_prog_leditem[6]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	menu_editing = 0; | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2 + 7, LCD_CMD_NO_CURSOR_FLASH); | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_btn_prog_ok() | ||||||
|  | { | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case 0: { | ||||||
|  | 			menu_btn_ok(); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_GLOBAL_CHANGEIDX: { | ||||||
|  | 			strcpy(lcd_line[0], prog_type_edit_str(prog_type)); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case PROG_EDIT_PROG_ID: { | ||||||
|  | 			strcpy(lcd_line[0], prog_type_edit_str(prog_type)); | ||||||
|  | 			menuc = (MenuItem *)&menu_prog_leditem[5]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_CYCLESPEED: { | ||||||
|  | 			strcpy(lcd_line[0], prog_type_edit_str(prog_type)); | ||||||
|  | 			menuc = (MenuItem *)&menu_prog_leditem[6]; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	menu_editing = 0; | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2 + 7, LCD_CMD_NO_CURSOR_FLASH); | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0] + 1, 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_prog_hexedit_adj(uint32_t val, uint8_t offset, uint8_t size, uint8_t direction) | ||||||
|  | { | ||||||
|  | 	uint32_t mask; | ||||||
|  | 	uint32_t work; | ||||||
|  | 	uint8_t nybble; | ||||||
|  | 
 | ||||||
|  | 	nybble = (offset + size - menu_oldval - 1) << 2; | ||||||
|  | 
 | ||||||
|  | 	// create a mask of the affected bits
 | ||||||
|  | 	mask = (0xf << nybble); | ||||||
|  | 	// extract and shift the working bits
 | ||||||
|  | 	work = ((val & mask) >> (nybble)) & 0xf; | ||||||
|  | 	// clear working bits in value
 | ||||||
|  | 	val &= ~mask; | ||||||
|  | 	// increment/decrement them
 | ||||||
|  | 	if (direction) work++; else work--; | ||||||
|  | 	// shift them back and restore them to value
 | ||||||
|  | 	val |= (work << nybble) & mask; | ||||||
|  | 
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case PROG_EDIT_LED_LEVEL: { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].level = (uint16_t)val; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OFFSET: { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].offset = val; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OPTIONS: { | ||||||
|  | 			settings.led_prog[prog_type][prog_idx].option = val; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_prog_hexedit_prev() | ||||||
|  | { | ||||||
|  | 	uint32_t val = 0; | ||||||
|  | 	uint8_t size = 8; | ||||||
|  | 	uint8_t start = 0; | ||||||
|  | 
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case PROG_EDIT_LED_LEVEL: { | ||||||
|  | 			val = settings.led_prog[prog_type][prog_idx].level; | ||||||
|  | 			size = 4; | ||||||
|  | 			start = 3; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OFFSET: { | ||||||
|  | 			val = settings.led_prog[prog_type][prog_idx].offset; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OPTIONS: { | ||||||
|  | 			val = settings.led_prog[prog_type][prog_idx].option; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	if (menu_newval) { | ||||||
|  | 		menu_prog_hexedit_adj(val, start, size, 0); | ||||||
|  | 	} else { | ||||||
|  | 		if (menu_oldval > start) { | ||||||
|  | 			menu_oldval--; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2 + menu_oldval, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_prog_hexedit_next() | ||||||
|  | { | ||||||
|  | 	uint32_t val = 0; | ||||||
|  | 	uint8_t size = 8; | ||||||
|  | 	uint8_t start = 0; | ||||||
|  | 	uint8_t end = 7; | ||||||
|  | 
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case PROG_EDIT_LED_LEVEL: { | ||||||
|  | 			val = settings.led_prog[prog_type][prog_idx].level; | ||||||
|  | 			size = 4; | ||||||
|  | 			start = 3; | ||||||
|  | 			end = 6; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OFFSET: { | ||||||
|  | 			val = settings.led_prog[prog_type][prog_idx].offset; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OPTIONS: { | ||||||
|  | 			val = settings.led_prog[prog_type][prog_idx].option; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	if (menu_newval) { | ||||||
|  | 		menu_prog_hexedit_adj(val, start, size, 1); | ||||||
|  | 	} else { | ||||||
|  | 		if (menu_oldval < end) { | ||||||
|  | 			menu_oldval++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2 + menu_oldval, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_prog_hexedit_ok() | ||||||
|  | { | ||||||
|  | 	menu_newval ^= 1; | ||||||
|  | 
 | ||||||
|  | 	if (menu_newval) { | ||||||
|  | 		lcd_set_cursor(LCD_LINE_2 + menu_oldval, LCD_CMD_CURSOR_FLASH); | ||||||
|  | 	} else { | ||||||
|  | 		lcd_set_cursor(LCD_LINE_2 + menu_oldval, LCD_CMD_CURSOR_UNDER); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0] + 1, 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void menu_prog_hexedit_menu() | ||||||
|  | { | ||||||
|  | 	int id; | ||||||
|  | 
 | ||||||
|  | 	switch (menu_editing) { | ||||||
|  | 		case PROG_EDIT_LED_LEVEL: 	{id = 7; break;} | ||||||
|  | 		case PROG_EDIT_LED_OFFSET: 	{id = 8; break;} | ||||||
|  | 		case PROG_EDIT_LED_OPTIONS: {id = 9; break;} | ||||||
|  | 		default:                    {id = 0; break;} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	strcpy(lcd_line[0], prog_type_edit_str(prog_type)); | ||||||
|  | 
 | ||||||
|  | 	menu_editing = 0; | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2 + 7, LCD_CMD_NO_CURSOR_FLASH); | ||||||
|  | 
 | ||||||
|  | 	menuc = (MenuItem *)&menu_prog_leditem[id]; | ||||||
|  | 	menu_btntype_program(); | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0] - 1, 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_btntype_program() | ||||||
|  | { | ||||||
|  | 	menu_mode = MENU_MODE_PROGRAM_EDITOR; | ||||||
|  | 
 | ||||||
|  | 	lcd_btn_fn[BTN_UP] = menu_btn_prog_prev; | ||||||
|  | 	lcd_btn_fn[BTN_MENU] = menu_btn_prog_menu; | ||||||
|  | 	lcd_btn_fn[BTN_OK] = menu_btn_prog_ok; | ||||||
|  | 	lcd_btn_fn[BTN_DOWN] = menu_btn_prog_next; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_prog_enter_led(uint16_t id) | ||||||
|  | { | ||||||
|  | 	prog_type = id; | ||||||
|  | 	prog_idx = 0; | ||||||
|  | 
 | ||||||
|  | 	menuc = (MenuItem *)&menu_prog_leditem[0]; | ||||||
|  | 
 | ||||||
|  | 	menu_btntype_program(); | ||||||
|  | 
 | ||||||
|  | 	strcpy(lcd_line[0], prog_type_edit_str(id)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_prog_hexedit_start(uint16_t id) | ||||||
|  | { | ||||||
|  | 	// oldval is cursor pos, newval is editing-is-on
 | ||||||
|  | 	menu_newval = 0; | ||||||
|  | 	menu_editing = id; | ||||||
|  | 
 | ||||||
|  | 	menuc = (MenuItem *)&menu_prog_ledaitem; | ||||||
|  | 
 | ||||||
|  | 	switch (id) { | ||||||
|  | 		case PROG_EDIT_LED_LEVEL: { | ||||||
|  | 			strcpy(lcd_line[0], "Level:  "); | ||||||
|  | 			menu_oldval = 3; | ||||||
|  | 			prog_hex_val = settings.led_prog[prog_type][prog_idx].level; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OFFSET: { | ||||||
|  | 			strcpy(lcd_line[0], "Offset: "); | ||||||
|  | 			menu_oldval = 0; | ||||||
|  | 			prog_hex_val = settings.led_prog[prog_type][prog_idx].offset; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		case PROG_EDIT_LED_OPTIONS: { | ||||||
|  | 			strcpy(lcd_line[0], "Options:"); | ||||||
|  | 			menu_oldval = 0; | ||||||
|  | 			prog_hex_val = settings.led_prog[prog_type][prog_idx].option; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2 + menu_oldval, LCD_CMD_CURSOR_UNDER); | ||||||
|  | 
 | ||||||
|  | 	lcd_btn_fn[BTN_UP] = menu_prog_hexedit_prev; | ||||||
|  | 	lcd_btn_fn[BTN_MENU] = menu_prog_hexedit_menu; | ||||||
|  | 	lcd_btn_fn[BTN_OK] = menu_prog_hexedit_ok; | ||||||
|  | 	lcd_btn_fn[BTN_DOWN] = menu_prog_hexedit_next; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu construction */ | ||||||
|  |   // programs menu
 | ||||||
|  | const MenuData menu_prog_rdata[] = { | ||||||
|  | 	{"", prog_type_edit_str,    PROG_TYPE_SKULL, 0, 0, 0, 0, menu_prog_enter_led, PROG_TYPE_SKULL}, | ||||||
|  | 	{"", prog_type_edit_str,    PROG_TYPE_BONES, 0, 0, 0, 0, menu_prog_enter_led, PROG_TYPE_BONES}, | ||||||
|  | 	{"", prog_type_edit_str,     PROG_TYPE_EYES, 0, 0, 0, 0, menu_prog_enter_led, PROG_TYPE_EYES}, | ||||||
|  | 	{"", prog_type_edit_str, PROG_TYPE_INFOPIR8, 0, 0, 0, 0, NULL, 0}, | ||||||
|  | }; | ||||||
|  | const MenuItem menu_prog_ritem[] = { | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_PROGRAMS],                   0, &menu_prog_ritem[1], 0, &menu_prog_rdata[0]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_PROGRAMS], &menu_prog_ritem[0], &menu_prog_ritem[2], 0, &menu_prog_rdata[1]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_PROGRAMS], &menu_prog_ritem[1], &menu_prog_ritem[3], 0, &menu_prog_rdata[2]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_PROGRAMS], &menu_prog_ritem[2],                   0, 0, &menu_prog_rdata[3]}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const MenuData menu_prog_leddata[] = { | ||||||
|  | 	{"Mode",     menu_prog_disp,      PROG_GLOBAL_MODE, 0, 0, 0, 0,       prog_edit_tog_mode,                     0}, | ||||||
|  | 	{"Edit ",    menu_prog_disp, PROG_GLOBAL_CHANGEIDX, 0, 0, 0, 0,     menu_prog_edit_start, PROG_GLOBAL_CHANGEIDX}, | ||||||
|  | 	{"Enable ",  menu_prog_disp,      PROG_EDIT_ENABLE, 0, 0, 0, 0,     prog_edit_tog_enable,                     0}, | ||||||
|  | 	{"Dwell",    prog_dwell_str,  PROG_EDIT_PROG_DWELL, 0, 0, 0, 0,     menu_prog_edit_start,  PROG_EDIT_PROG_DWELL}, | ||||||
|  | 	{"PID  #",   menu_prog_disp,     PROG_EDIT_PROG_ID, 0, 0, 0, 0,     menu_prog_edit_start,     PROG_EDIT_PROG_ID}, | ||||||
|  | 	{"CycleSpd",           NULL,                     0, 0, 0, 0, 0,     menu_prog_edit_start,  PROG_EDIT_CYCLESPEED}, | ||||||
|  | 	{"LEDLevel",           NULL,                     0, 0, 0, 0, 0,  menu_prog_hexedit_start,   PROG_EDIT_LED_LEVEL}, | ||||||
|  | 	{"Offset",             NULL,                     0, 0, 0, 0, 0,  menu_prog_hexedit_start,  PROG_EDIT_LED_OFFSET}, | ||||||
|  | 	{"Options",            NULL,                     0, 0, 0, 0, 0,  menu_prog_hexedit_start, PROG_EDIT_LED_OPTIONS}, | ||||||
|  | 	{"InitFn?",  menu_prog_disp,  PROG_EDIT_FORCE_INIT, 0, 0, 0, 0, prog_edit_tog_force_init,  PROG_EDIT_FORCE_INIT} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_prog_leditem[] = { | ||||||
|  | 	{(MenuItem *)255,                     0, &menu_prog_leditem[1], 0, &menu_prog_leddata[0]}, | ||||||
|  | 	{(MenuItem *)255, &menu_prog_leditem[0], &menu_prog_leditem[2], 0, &menu_prog_leddata[1]}, | ||||||
|  | 	{(MenuItem *)255, &menu_prog_leditem[1], &menu_prog_leditem[3], 0, &menu_prog_leddata[2]}, | ||||||
|  | 	{(MenuItem *)255, &menu_prog_leditem[2], &menu_prog_leditem[4], 0, &menu_prog_leddata[3]}, | ||||||
|  | 	{(MenuItem *)255, &menu_prog_leditem[3], &menu_prog_leditem[5], 0, &menu_prog_leddata[4]}, | ||||||
|  | 	{(MenuItem *)255, &menu_prog_leditem[4], &menu_prog_leditem[6], 0, &menu_prog_leddata[5]}, | ||||||
|  | 	{(MenuItem *)255, &menu_prog_leditem[5], &menu_prog_leditem[7], 0, &menu_prog_leddata[6]}, | ||||||
|  | 	{(MenuItem *)255, &menu_prog_leditem[6], &menu_prog_leditem[8], 0, &menu_prog_leddata[7]}, | ||||||
|  | 	{(MenuItem *)255, &menu_prog_leditem[7], &menu_prog_leditem[9], 0, &menu_prog_leddata[8]}, | ||||||
|  | 	{(MenuItem *)255, &menu_prog_leditem[8],                      0, 0, &menu_prog_leddata[9]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // advanced LED menu editor target menu
 | ||||||
|  | const MenuData menu_prog_ledadata = { | ||||||
|  | 		"", prog_advanced_str, 0, 4, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0 | ||||||
|  | }; | ||||||
|  | const MenuItem menu_prog_ledaitem = {(MenuItem *)255, 0, 0, 0, &menu_prog_ledadata}; | ||||||
							
								
								
									
										57
									
								
								fw_dc22_stm32l100/src/menu/menu_program.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								fw_dc22_stm32l100/src/menu/menu_program.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_program.h: led and lcd program selection and configuration | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_program.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_MENU_PROGRAM_H | ||||||
|  | #define __PIRATE_MENU_PROGRAM_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* program specifics */ | ||||||
|  | #define PROG_TYPE_SKULL 		0x00 | ||||||
|  | #define PROG_TYPE_BONES 		0x01 | ||||||
|  | #define PROG_TYPE_EYES 			0x02 | ||||||
|  | #define PROG_TYPE_INFOPIR8 		0x10 | ||||||
|  | 
 | ||||||
|  | #define PROG_GLOBAL_MODE 		0x0200 | ||||||
|  | #define PROG_GLOBAL_CHANGEIDX 	0x0210 | ||||||
|  | 
 | ||||||
|  | #define PROG_EDIT_ENABLE 		0x0220 | ||||||
|  | #define PROG_EDIT_FORCE_INIT 	0x0221 | ||||||
|  | #define PROG_EDIT_PROG_DWELL 	0x0222 | ||||||
|  | #define PROG_EDIT_TYPE 			0x0223 | ||||||
|  | #define PROG_EDIT_PROG_ID 		0x0224 | ||||||
|  | #define PROG_EDIT_CYCLESPEED 	0x0225 | ||||||
|  | #define PROG_EDIT_LED_LEVEL 	0x0226 | ||||||
|  | #define PROG_EDIT_LED_OFFSET 	0x0227 | ||||||
|  | #define PROG_EDIT_LED_OPTIONS 	0x0228 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* program menus */ | ||||||
|  | extern const MenuItem menu_prog_ritem[]; | ||||||
|  | extern const MenuItem menu_prog_leditem[]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* variables */ | ||||||
|  | extern uint8_t prog_id[3]; | ||||||
|  | extern uint16_t prog_dwell[3]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void prog_init(); | ||||||
|  | uint8_t prog_get_mode(uint8_t id); | ||||||
|  | 
 | ||||||
|  | uint8_t menu_prog_get_type(); | ||||||
|  | uint8_t menu_prog_get_idx(); | ||||||
|  | 
 | ||||||
|  | void menu_btntype_program(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										196
									
								
								fw_dc22_stm32l100/src/menu/menu_radio.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								fw_dc22_stm32l100/src/menu/menu_radio.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,196 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_radio.c: cool radio tricks | ||||||
|  |  * 2015 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "../device/radio/nrf.h" | ||||||
|  | 
 | ||||||
|  | #include "lcd_menu.h" | ||||||
|  | #include "menu_radio.h" | ||||||
|  | 
 | ||||||
|  |   // radio comms
 | ||||||
|  | char comm_str[12]; | ||||||
|  | 
 | ||||||
|  |   // pingpong
 | ||||||
|  | uint8_t comm_ping_idx; | ||||||
|  | uint8_t comm_pingpong_timeout; | ||||||
|  | uint8_t comm_pong_last_idx; | ||||||
|  | uint8_t comm_pong_timeout; | ||||||
|  | 
 | ||||||
|  |   // radio menu forward declaration
 | ||||||
|  | MenuItem menu_comm_pingitem; | ||||||
|  | const MenuItem menu_comm_dc23item[5]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* special functions */ | ||||||
|  | void menu_comm_dc23cmd(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (id < 255) { | ||||||
|  | 		// music
 | ||||||
|  | 		nrf_tx_buf[0] = NRF_CMD_MUSICLIBRARY; | ||||||
|  | 		nrf_tx_buf[1] = (id > 127) ? 22 : 23; | ||||||
|  | 		if (id > 127) id -= 128; | ||||||
|  | 		nrf_tx_buf[2] = id & 0xff; | ||||||
|  | 		nrf_tx_buf[3] = 0; | ||||||
|  | 		nrf_tx_buf[4] = 0; | ||||||
|  | 		nrf_tx_buf[5] = 60000 >> 8; | ||||||
|  | 		nrf_tx_buf[6] = 60000 & 0xff; | ||||||
|  | 		nrf_tx_buf[7] = nrf_checksum(nrf_tx_buf, 7, 0) & 0xff; | ||||||
|  | 		nRF24_packet_tx(nrf_tx_buf, NRF_PAYLOAD_LEN, 1); | ||||||
|  | 	} else { | ||||||
|  | 		switch (id) { | ||||||
|  | 			case 301: { | ||||||
|  | 				// cawks go a-flyin'
 | ||||||
|  | 				nrf_tx_buf[0] = NRF_CMD_ANIMATION; | ||||||
|  | 				nrf_tx_buf[1] = 22; | ||||||
|  | 				nrf_tx_buf[2] = 0x00; | ||||||
|  | 				nrf_tx_buf[3] = 'B'; | ||||||
|  | 				nrf_tx_buf[4] = 'K'; | ||||||
|  | 				nrf_tx_buf[5] = '<'; | ||||||
|  | 				nrf_tx_buf[6] = '3'; | ||||||
|  | 				nrf_tx_buf[7] = nrf_checksum(nrf_tx_buf, 7, 0) & 0xff; | ||||||
|  | 				nRF24_packet_tx(nrf_tx_buf, NRF_PAYLOAD_LEN, 1); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 			case 401: { | ||||||
|  | 				// name auto-tx mode, timeout in minutes
 | ||||||
|  | 				dc23_nametx++; | ||||||
|  | 				dc23_nametx %= 16; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* external program functions */ | ||||||
|  | char * menu_comm_disp(uint16_t id) | ||||||
|  | { | ||||||
|  | 	switch (id) { | ||||||
|  | 		case COMM_TEST_PING: { | ||||||
|  | 			if (!comm_pingpong_timeout) { | ||||||
|  | 				// set our timeout to start this process again
 | ||||||
|  | 				comm_pingpong_timeout = 100; | ||||||
|  | 
 | ||||||
|  | 				// increment our ping output index
 | ||||||
|  | 				comm_ping_idx++; | ||||||
|  | 				if (comm_ping_idx == 0) comm_ping_idx++; | ||||||
|  | 
 | ||||||
|  | 				// and build and send a ping command packet
 | ||||||
|  | 				// 1 byte command, 1 byte class/sub, 1 byte byte index, 4 bytes data, 1 byte checksum
 | ||||||
|  | 				nrf_tx_buf[0] = NRF_CMD_PING; | ||||||
|  | 				nrf_tx_buf[1] = 22; | ||||||
|  | 				nrf_tx_buf[2] = comm_ping_idx; | ||||||
|  | 				nrf_tx_buf[3] = nrf_tx_buf[4] = nrf_tx_buf[5] = nrf_tx_buf[6] = 0; | ||||||
|  | 				nrf_tx_buf[7] = nrf_checksum(nrf_tx_buf, 7, 0) & 0xff; | ||||||
|  | 				nRF24_packet_tx(nrf_tx_buf, NRF_PAYLOAD_LEN, 1); | ||||||
|  | 			} else { | ||||||
|  | 				comm_pingpong_timeout--; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// show our address and index on the screen
 | ||||||
|  | 			strcpy(comm_str, pirate_itoa(nrf_myaddr, 16, 2)); | ||||||
|  | 			strcat(comm_str, pirate_itoa(comm_ping_idx, 16, 2)); | ||||||
|  | 
 | ||||||
|  | 			// fix up then return
 | ||||||
|  | 			if (comm_str[0] == 0x00 || comm_str[0] == 0x20) comm_str[0] = 0x30; | ||||||
|  | 			if (comm_str[2] == 0x00 || comm_str[2] == 0x20) comm_str[2] = 0x30; | ||||||
|  | 			comm_str[4] = 0; | ||||||
|  | 			return comm_str; | ||||||
|  | 		} | ||||||
|  | 		case COMM_TEST_PONG: { | ||||||
|  | 			if (!comm_pingpong_timeout) { | ||||||
|  | 				// set our timeout to start this process again
 | ||||||
|  | 				comm_pingpong_timeout = 25; | ||||||
|  | 
 | ||||||
|  | 				// clear ping receipt variables
 | ||||||
|  | 				if (nrf_last_ping_idx) { | ||||||
|  | 					// mismatch or unset?
 | ||||||
|  | 					if ((nrf_last_ping_idx != comm_pong_last_idx) || (comm_pong_last_idx == 0)) { | ||||||
|  | 						// ok, then start over
 | ||||||
|  | 						comm_pong_timeout = 6; | ||||||
|  | 						comm_pong_last_idx = nrf_last_ping_idx; | ||||||
|  | 					} else if (!comm_pong_timeout) { | ||||||
|  | 						nrf_last_ping_idx = comm_pong_last_idx = 0; | ||||||
|  | 					} else { | ||||||
|  | 						comm_pong_timeout--; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				comm_pingpong_timeout--; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (!nrf_last_ping_idx) { | ||||||
|  | 				return "----"; | ||||||
|  | 			} else { | ||||||
|  | 				// show received address and index on the screen
 | ||||||
|  | 				strcpy(comm_str, pirate_itoa(nrf_last_ping_id, 16, 2)); | ||||||
|  | 				strcat(comm_str, pirate_itoa(nrf_last_ping_idx, 16, 2)); | ||||||
|  | 
 | ||||||
|  | 				// fix up then return
 | ||||||
|  | 				if (comm_str[0] == 0x00 || comm_str[0] == 0x20) comm_str[0] = 0x30; | ||||||
|  | 				if (comm_str[2] == 0x00 || comm_str[2] == 0x20) comm_str[2] = 0x30; | ||||||
|  | 				comm_str[4] = 0; | ||||||
|  | 				return comm_str; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case COMM_RADIOSTATUS: { 	// radio detected?
 | ||||||
|  | 			if (nrf_detected) return "Radio OK"; | ||||||
|  | 			else              return "No Radio"; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case COMM_DC23NAMETX: { | ||||||
|  | 			strncpy(comm_str, pirate_itoa(dc23_nametx, 10, 2), 2); | ||||||
|  | 			comm_str[8] = 0; | ||||||
|  | 			return comm_str; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ""; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu construction */ | ||||||
|  |   // main menu
 | ||||||
|  | const MenuData menu_comm_rdata[] = { | ||||||
|  | 	{"DC22Page",        NULL,                0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"DC23Page",        NULL,                0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"DC23Cmds",        NULL,                0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"Ping",  menu_comm_disp,   COMM_TEST_PING, 0, LCD_DEF_SPACING,                 100,                100, NULL, 0}, | ||||||
|  | 	{"Pong",  menu_comm_disp,   COMM_TEST_PONG, 0, LCD_DEF_SPACING,                 100,                100, NULL, 0}, | ||||||
|  | 	{"",      menu_comm_disp, COMM_RADIOSTATUS, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0} 	// radio-detect
 | ||||||
|  | }; | ||||||
|  | const MenuItem menu_comm_ritem[] = { | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_COMMS],                   0, &menu_comm_ritem[1],                   NULL, &menu_comm_rdata[0]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[0], &menu_comm_ritem[2],                   NULL, &menu_comm_rdata[1]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[1], &menu_comm_ritem[3], &menu_comm_dc23item[0], &menu_comm_rdata[2]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[2], &menu_comm_ritem[4],                   NULL, &menu_comm_rdata[3]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[3], &menu_comm_ritem[5],                   NULL, &menu_comm_rdata[4]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_COMMS], &menu_comm_ritem[4],                   0,                   NULL, &menu_comm_rdata[5]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // pinger
 | ||||||
|  | const MenuData menu_comm_pingdata = {"", NULL, 0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}; | ||||||
|  | 
 | ||||||
|  |   // dc23 stuff
 | ||||||
|  | const MenuData menu_comm_dc23data[5] = { | ||||||
|  | 	{"S:URAPr8",         NULL,               0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_comm_dc23cmd,   0}, | ||||||
|  | 	{"M:URAPrL",         NULL,               0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_comm_dc23cmd, 129}, | ||||||
|  | 	{"S:PwrRgr",         NULL,               0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_comm_dc23cmd,   2}, | ||||||
|  | 	{"CawkSpam",         NULL,               0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_comm_dc23cmd, 301}, | ||||||
|  | 	{"NameTx", menu_comm_disp, COMM_DC23NAMETX, 0, LCD_DEF_SPACING,                  10,                 10, menu_comm_dc23cmd, 401}, | ||||||
|  | }; | ||||||
|  | const MenuItem menu_comm_dc23item[5] = { | ||||||
|  | 	{&menu_comm_ritem[2],                      0, &menu_comm_dc23item[1], 0, &menu_comm_dc23data[0]}, | ||||||
|  | 	{&menu_comm_ritem[2], &menu_comm_dc23item[0], &menu_comm_dc23item[2], 0, &menu_comm_dc23data[1]}, | ||||||
|  | 	{&menu_comm_ritem[2], &menu_comm_dc23item[1], &menu_comm_dc23item[3], 0, &menu_comm_dc23data[2]}, | ||||||
|  | 	{&menu_comm_ritem[2], &menu_comm_dc23item[2], &menu_comm_dc23item[4], 0, &menu_comm_dc23data[3]}, | ||||||
|  | 	{&menu_comm_ritem[2], &menu_comm_dc23item[3],                      0, 0, &menu_comm_dc23data[4]}, | ||||||
|  | }; | ||||||
							
								
								
									
										29
									
								
								fw_dc22_stm32l100/src/menu/menu_radio.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								fw_dc22_stm32l100/src/menu/menu_radio.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_radio.h: cool radio tricks | ||||||
|  |  * 2015 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_MENU_RADIO_H | ||||||
|  | #define __PIRATE_MENU_RADIO_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menus */ | ||||||
|  | extern const MenuItem menu_comm_ritem[]; | ||||||
|  | 
 | ||||||
|  | /* menu types */ | ||||||
|  | #define COMM_TEST_PING 			0x01e0 | ||||||
|  | #define COMM_TEST_PONG 			0x01e1 | ||||||
|  | 
 | ||||||
|  | #define COMM_RADIOSTATUS 		0x01ff | ||||||
|  | 
 | ||||||
|  | #define COMM_DC23NAMETX 		0x0201 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										212
									
								
								fw_dc22_stm32l100/src/menu/menu_sensors.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								fw_dc22_stm32l100/src/menu/menu_sensors.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,212 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_sensors.c: sensors menu | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_sensors.c 350 2015-05-28 02:23:03Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "../interface/adc.h" | ||||||
|  | 
 | ||||||
|  | #include "lcd_menu.h" | ||||||
|  | #include "menu_sensors.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu functions */ | ||||||
|  |   // feedback display
 | ||||||
|  | char * menu_sens_disp(uint16_t id) | ||||||
|  | { | ||||||
|  | 	switch (id) { | ||||||
|  | 		case SENSOR_LIGHT_CURRENTGAIN: { | ||||||
|  | 			return pirate_sitoa(light_gain, 10, 3); | ||||||
|  | 		} | ||||||
|  | 		case SENSOR_LIGHT_SETTINGSGAIN: { | ||||||
|  | 			return pirate_sitoa(settings.light_setgain, 10, 3); | ||||||
|  | 		} | ||||||
|  | 		case SENSOR_LIGHT_LEVEL: { | ||||||
|  | 			return pirate_sitoa(light_level, 10, 3); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SENSOR_MIC_CAL_LOW: | ||||||
|  | 		case SENSOR_MIC_CAL_HIGH: { | ||||||
|  | 			if (menu_editing == SENSOR_MIC_CAL_LOW) { | ||||||
|  | 				if (settings.mic_cal[0] > mic_peak) { | ||||||
|  | 					settings.mic_cal[0] = mic_peak - (mic_peak >> 6); | ||||||
|  | 				} | ||||||
|  | 			} else if (menu_editing == SENSOR_MIC_CAL_HIGH) { | ||||||
|  | 				if (settings.mic_cal[1] < mic_peak) { | ||||||
|  | 					settings.mic_cal[1] = mic_peak + (mic_peak >> 6); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return pirate_sitoa(settings.mic_cal[id - SENSOR_MIC_CAL_LOW], 10, 4); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SENSOR_TEMP_CALVALUE: { | ||||||
|  | 			return pirate_sitoa(temperature_cal, 10, 3); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		default: { | ||||||
|  | 			return ""; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char * menu_sensor_batt_disp(uint16_t id) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	static char volt[6]; | ||||||
|  | 	uint16_t raw; | ||||||
|  | 
 | ||||||
|  | 	// get voltage, clear target array
 | ||||||
|  | 	raw = pirate_batt_voltage(); | ||||||
|  | 	for (i = 0; i < 6; i++) { | ||||||
|  | 		volt[i] = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// voltage whole number
 | ||||||
|  | 	strcpy(volt, pirate_sitoa(raw / 100, 10, 0)); | ||||||
|  | 
 | ||||||
|  | 	// voltage decimal start
 | ||||||
|  | 	if (raw % 100 <= 9) { | ||||||
|  | 		strncat(volt, ".0", 6); | ||||||
|  | 	} else { | ||||||
|  | 		strncat(volt, ".", 6); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// voltage decimal
 | ||||||
|  | 	strncat(volt, pirate_sitoa(raw % 100, 10, 0), 5); | ||||||
|  | 
 | ||||||
|  | 	// voltage postfix
 | ||||||
|  | 	volt[4] = 'V'; | ||||||
|  | 	volt[5] = 0; | ||||||
|  | 
 | ||||||
|  | 	return volt; | ||||||
|  | } | ||||||
|  | char * menu_sensor_temp_disp(uint16_t id) | ||||||
|  | { | ||||||
|  | 	static char temp[7]; | ||||||
|  | 	uint16_t raw; | ||||||
|  | 
 | ||||||
|  | 	raw = pirate_thermometer(id); | ||||||
|  | 
 | ||||||
|  | 	if (!id) { | ||||||
|  | 		strcpy(temp, pirate_sitoa(raw / 10, 10, 0)); | ||||||
|  | 		strncat(temp, ".", 7); | ||||||
|  | 		strncat(temp, pirate_sitoa(raw % 10, 10, 0), 6); | ||||||
|  | 		strncat(temp, "C", 7); | ||||||
|  | 		temp[6] = 0; | ||||||
|  | 	} else { | ||||||
|  | 		strcpy(temp, pirate_sitoa(raw, 10, 0)); | ||||||
|  | 		strncat(temp, "F", 5); | ||||||
|  | 		temp[4] = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return temp; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char * menu_sensor_mic_disp(uint16_t id) | ||||||
|  | { | ||||||
|  | 	uint16_t w; | ||||||
|  | 
 | ||||||
|  | 	if (!id) { | ||||||
|  | 		return pirate_sitoa(mic_peak, 10, 4); | ||||||
|  | 	} else { | ||||||
|  | 		w = (settings.mic_cal[1] - settings.mic_cal[0]); | ||||||
|  | 		return pirate_sitoa(((mic_peak - settings.mic_cal[0]) * 100) / w, 10, 4); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // menu actions
 | ||||||
|  | void menu_sensor_mic_cal_start(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (menu_editing) { | ||||||
|  | 		menu_editing = 0; | ||||||
|  | 	} else { | ||||||
|  | 		menu_editing = id; | ||||||
|  | 		settings.mic_cal[id - SENSOR_MIC_CAL_LOW] = mic_peak; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	menu_btntype_editing(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu construction */ | ||||||
|  |   // forward declaration
 | ||||||
|  | const MenuItem menu_sens_viewitem[]; | ||||||
|  | 
 | ||||||
|  | const MenuItem menu_sens_setitem[]; | ||||||
|  | const MenuItem menu_sens_set_lightitem[]; | ||||||
|  | const MenuItem menu_sens_set_micitem[]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // main menu
 | ||||||
|  | const MenuData menu_sens_rdata[] = { | ||||||
|  | 	{"View",  NULL, 0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"Setup", NULL, 0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_sens_ritem[] = { | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SENSORS],                   0, &menu_sens_ritem[1], &menu_sens_viewitem[0], &menu_sens_rdata[0]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SENSORS], &menu_sens_ritem[0],                   0,  &menu_sens_setitem[0], &menu_sens_rdata[1]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // "view" menu
 | ||||||
|  | const MenuData menu_sens_viewdata[] = { | ||||||
|  | 	{"Bat",   menu_sensor_batt_disp,                      0, 20, 4, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"Tmp",   menu_sensor_temp_disp,                    0, 20, 4, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"Tmp ",  menu_sensor_temp_disp,                    1, 20, 4, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"MicR",  menu_sensor_mic_disp,                       0, 12, 4, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"Mic%",  menu_sensor_mic_disp,                       1, 12, 4, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"LitGn", menu_sens_disp, SENSOR_LIGHT_CURRENTGAIN, 12, 4, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"LitLv", menu_sens_disp,       SENSOR_LIGHT_LEVEL, 12, 4, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_sens_viewitem[] = { | ||||||
|  | 	{&menu_sens_ritem[0],                      0, &menu_sens_viewitem[1], 0, &menu_sens_viewdata[0]}, | ||||||
|  | 	{&menu_sens_ritem[0], &menu_sens_viewitem[0], &menu_sens_viewitem[2], 0, &menu_sens_viewdata[1]}, | ||||||
|  | 	{&menu_sens_ritem[0], &menu_sens_viewitem[1], &menu_sens_viewitem[3], 0, &menu_sens_viewdata[2]}, | ||||||
|  | 	{&menu_sens_ritem[0], &menu_sens_viewitem[2], &menu_sens_viewitem[4], 0, &menu_sens_viewdata[3]}, | ||||||
|  | 	{&menu_sens_ritem[0], &menu_sens_viewitem[3], &menu_sens_viewitem[5], 0, &menu_sens_viewdata[4]}, | ||||||
|  | 	{&menu_sens_ritem[0], &menu_sens_viewitem[4], &menu_sens_viewitem[6], 0, &menu_sens_viewdata[5]}, | ||||||
|  | 	{&menu_sens_ritem[0], &menu_sens_viewitem[5],                      0, 0, &menu_sens_viewdata[6]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // "setup" menu and submenus
 | ||||||
|  | const MenuData menu_sens_setdata[] = { | ||||||
|  | 	{"LightSensor", NULL, 0, 0, | ||||||
|  | 			LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"Mic", NULL, 0, 0, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0}, | ||||||
|  | 	{"T-Cal", menu_sens_disp, SENSOR_TEMP_CALVALUE, 0, | ||||||
|  | 			LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_edit_start, SENSOR_TEMP_CALVALUE} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_sens_setitem[] = { | ||||||
|  | 	{&menu_sens_ritem[1],                     0, &menu_sens_setitem[1], &menu_sens_set_lightitem[0], &menu_sens_setdata[0]}, | ||||||
|  | 	{&menu_sens_ritem[1], &menu_sens_setitem[0], &menu_sens_setitem[2],   &menu_sens_set_micitem[0], &menu_sens_setdata[1]}, | ||||||
|  | 	{&menu_sens_ritem[1], &menu_sens_setitem[1],                     0,                           0, &menu_sens_setdata[2]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // setup/lightsensor
 | ||||||
|  | const MenuData menu_sens_set_lightdata[] = { | ||||||
|  | 	{"Gain ", menu_sens_disp,  SENSOR_LIGHT_CURRENTGAIN, 4, 0, 0, 0,            NULL, 0}, | ||||||
|  | 	{"Fixed", menu_sens_disp, SENSOR_LIGHT_SETTINGSGAIN, 4, 0, 0, 0, menu_edit_start, SENSOR_LIGHT_SETTINGSGAIN} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_sens_set_lightitem[] = { | ||||||
|  | 	{&menu_sens_setitem[0],                           0, &menu_sens_set_lightitem[1], 0, &menu_sens_set_lightdata[0]}, | ||||||
|  | 	{&menu_sens_setitem[0], &menu_sens_set_lightitem[0], &menu_sens_set_lightitem[2], 0, &menu_sens_set_lightdata[1]}, | ||||||
|  | 	{&menu_sens_setitem[0], &menu_sens_set_lightitem[1],                           0, 0, &menu_sens_set_lightdata[2]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // setup/mic
 | ||||||
|  | const MenuData menu_sens_set_micdata[] = { | ||||||
|  | 	{"CLow", menu_sens_disp,  SENSOR_MIC_CAL_LOW, 1, 0, 0, 0, menu_sensor_mic_cal_start,  SENSOR_MIC_CAL_LOW}, | ||||||
|  | 	{"CHi ", menu_sens_disp, SENSOR_MIC_CAL_HIGH, 1, 0, 0, 0, menu_sensor_mic_cal_start, SENSOR_MIC_CAL_HIGH} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_sens_set_micitem[] = { | ||||||
|  | 	{&menu_sens_setitem[1],                         0, &menu_sens_set_micitem[1], 0, &menu_sens_set_micdata[0]}, | ||||||
|  | 	{&menu_sens_setitem[1], &menu_sens_set_micitem[0],                         0, 0, &menu_sens_set_micdata[1]} | ||||||
|  | }; | ||||||
							
								
								
									
										33
									
								
								fw_dc22_stm32l100/src/menu/menu_sensors.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								fw_dc22_stm32l100/src/menu/menu_sensors.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_sensors.h: sensors menu | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_sensors.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_MENU_SENSORS_H | ||||||
|  | #define __PIRATE_MENU_SENSORS_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menus */ | ||||||
|  | extern const MenuItem menu_sens_ritem[]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* sensors defines */ | ||||||
|  | #define SENSOR_LIGHT_CURRENTGAIN 		0x0400 | ||||||
|  | #define SENSOR_LIGHT_SETTINGSGAIN 		0x0401 | ||||||
|  | 
 | ||||||
|  | #define SENSOR_LIGHT_LEVEL 				0x0404 | ||||||
|  | 
 | ||||||
|  | #define SENSOR_MIC_CAL_LOW 				0x0410 | ||||||
|  | #define SENSOR_MIC_CAL_HIGH 			0x0411 | ||||||
|  | 
 | ||||||
|  | #define SENSOR_TEMP_CALVALUE 			0x0420 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										459
									
								
								fw_dc22_stm32l100/src/menu/menu_settings.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										459
									
								
								fw_dc22_stm32l100/src/menu/menu_settings.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,459 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_settings.c: setting shit up for pirates since | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_settings.c 375 2015-07-06 02:52:40Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "../device/lcd.h" | ||||||
|  | 
 | ||||||
|  | #include "../device/lightsensor.h" 	// for lightsensor default defines | ||||||
|  | #include "../device/attiny.h" 		// eyes program set for favcolor editor | ||||||
|  | #include "../device/beep.h" | ||||||
|  | 
 | ||||||
|  | #include "lcd_menu.h" | ||||||
|  | #include "menu_settings.h" | ||||||
|  | 
 | ||||||
|  |   // menus
 | ||||||
|  | uint32_t menu_oldval; | ||||||
|  | uint32_t menu_newval; | ||||||
|  | 
 | ||||||
|  |   // settings
 | ||||||
|  | PirateSettings *settings_eeprom = (PirateSettings *)PIRATE_SETTINGS_EEPROM_ADDR; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* settings functions */ | ||||||
|  | void menu_settings_save(uint16_t id) | ||||||
|  | { | ||||||
|  | 	settings_save(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void settings_save() | ||||||
|  | { | ||||||
|  | 	uint32_t *active = (uint32_t *)&settings; | ||||||
|  | 
 | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	DATA_EEPROM_Unlock(); | ||||||
|  | 
 | ||||||
|  | 	// make sure the first name byte is set to something not considered invalid
 | ||||||
|  | 	// if it isn't set we set it to be a space
 | ||||||
|  | 	if (settings.name[0] == 0x00 || settings.name[0] == 0xff) { | ||||||
|  | 		settings.name[0] = 0x20; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// write data
 | ||||||
|  | 	for (i = 0; i < sizeof(settings); i += 4) { | ||||||
|  | 		DATA_EEPROM_ProgramWord(PIRATE_SETTINGS_EEPROM_ADDR + i, *active++); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	DATA_EEPROM_Lock(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void settings_restore(uint8_t load_defaults) | ||||||
|  | { | ||||||
|  | 	uint32_t *active = (uint32_t *)&settings; | ||||||
|  | 	uint32_t *stored = (uint32_t *)PIRATE_SETTINGS_EEPROM_ADDR; | ||||||
|  | 
 | ||||||
|  | 	int i; | ||||||
|  | 	int j; | ||||||
|  | 	uint8_t valid = 0; | ||||||
|  | 
 | ||||||
|  | 	// see if valid settings are in EEPROM
 | ||||||
|  | 	if (!(settings_eeprom->name[0] == 0x00 || settings_eeprom->name[0] == 0xff)) { | ||||||
|  | 		// seems valid, copy it
 | ||||||
|  | 		for (i = 0; i < sizeof(settings); i += 4) { | ||||||
|  | 			*active++ = *stored++; | ||||||
|  | 		} | ||||||
|  | 		valid = 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!valid || load_defaults) { | ||||||
|  | 		// not valid, set defaults
 | ||||||
|  | 		if (load_defaults & 0x02) { | ||||||
|  | 			// only reset name if invalid settings, or if second bit is set
 | ||||||
|  | 			strncpy(settings.name, "        ", 8); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		settings.fav_color[0] = 0x80; | ||||||
|  | 		settings.fav_color[1] = 0x10; | ||||||
|  | 		settings.fav_color[2] = 0; | ||||||
|  | 
 | ||||||
|  | 		settings.beeper = 0x80 + 31; | ||||||
|  | 		settings.beep_type[0] = 24; | ||||||
|  | 		settings.beep_type[1] = 30; | ||||||
|  | 		settings.beep_type[2] = 28; | ||||||
|  | 
 | ||||||
|  | 		settings.contrast = 0x15; 	// gives great readability with scrolling on my badge
 | ||||||
|  | 
 | ||||||
|  | 		settings.autorun = 0; | ||||||
|  | 
 | ||||||
|  | 		settings.led_autoadjust = 0x88; | ||||||
|  | 		settings.led_autogain_lev_min = LIGHTSENS_AUTOGAIN_LEVEL_MIN; | ||||||
|  | 		settings.led_autogain_lev_max = LIGHTSENS_AUTOGAIN_LEVEL_MAX; | ||||||
|  | 		settings.led_autothresh[0] = LIGHTSENS_THRESH_DAY; | ||||||
|  | 		settings.led_autothresh[1] = LIGHTSENS_THRESH_TOP_BRIGHT; | ||||||
|  | 		settings.led_autothresh[2] = LIGHTSENS_THRESH_TOP_NORM; | ||||||
|  | 		settings.led_autothresh[3] = LIGHTSENS_THRESH_TOP_DIM; | ||||||
|  | 		settings.led_autothresh[4] = LIGHTSENS_THRESH_TOP_DARK; | ||||||
|  | 
 | ||||||
|  | 		settings.lcd_autobrite = 1; | ||||||
|  | 		settings.lcd_brightness = 50; | ||||||
|  | 
 | ||||||
|  | 		settings.light_setgain = 0; | ||||||
|  | 
 | ||||||
|  | 		for (i = 0; i < PIRATE_PROG_SAVED_MAX; i++) { | ||||||
|  | 			for (j = 0; j < 3; j++) { | ||||||
|  | 				settings.led_prog[j][i].type = 0b00000010; // not enabled, will init, program mode
 | ||||||
|  | 				settings.led_prog[j][i].progidx = 0; | ||||||
|  | 				settings.led_prog[j][i].wait = 80; | ||||||
|  | 				settings.led_prog[j][i].level = 0; | ||||||
|  | 				settings.led_prog[j][i].offset = 0; | ||||||
|  | 				settings.led_prog[j][i].option = 0; | ||||||
|  | 				settings.led_prog[j][i].dwell = 10; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		settings.led_prog_mode = 0b00010101; // all program types set to normal run
 | ||||||
|  | 
 | ||||||
|  | 		settings.mic_cal[0] = 2300; | ||||||
|  | 		settings.mic_cal[1] = 2800; | ||||||
|  | 
 | ||||||
|  | 		/* default programs */ | ||||||
|  | 		#include "menu_settings_defprog.h" | ||||||
|  | 
 | ||||||
|  | 		// fix the null name issue
 | ||||||
|  | 		if (settings.name[0] == 0x00) { | ||||||
|  | 			strncpy(settings.name, "        ", 8); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu functions */ | ||||||
|  |   // feedback display
 | ||||||
|  | static char * menu_pref_disp(uint16_t id) | ||||||
|  | { | ||||||
|  | 	switch (id) { | ||||||
|  | 		case SETTING_NAME: { | ||||||
|  | 			return settings.name; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_AUTORUN_ENA: { | ||||||
|  | 			return settings.autorun & 0x01 ? "Y" : "N"; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_ALWAYS_RUN_PROG_ENA: { | ||||||
|  | 			return settings.autorun & 0x02 ? "Y" : "N"; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_FAVCOLOR_RED: | ||||||
|  | 		case SETTING_FAVCOLOR_GREEN: | ||||||
|  | 		case SETTING_FAVCOLOR_BLUE: { | ||||||
|  | 			return pirate_sitoa(settings.fav_color[id - SETTING_FAVCOLOR_RED], 16, 2); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BEEPER_ENA: { | ||||||
|  | 			return (settings.beeper & 0x80) ? " On" : "Off"; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BEEP_TYPE_BUTTON: | ||||||
|  | 		case SETTING_BEEP_TYPE_PAGING: | ||||||
|  | 		case SETTING_BEEP_TYPE_ALARM: { | ||||||
|  | 			return pirate_sitoa(settings.beep_type[id - SETTING_BEEP_TYPE_BUTTON], 10, 2); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BRITE_AUTO_ENA: { | ||||||
|  | 			return (settings.led_autoadjust & 0x80) ? "  On" : " Off"; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		case SETTING_BRITE_AUTO_SPEED: { | ||||||
|  | 			switch (settings.led_autoadjust & 0x7f) { | ||||||
|  | 			 	case 0: 	return " Off"; | ||||||
|  | 				case 2: 	return "Hypr"; | ||||||
|  | 				case 4: 	return "High"; | ||||||
|  | 				case 6: 	return " Med"; | ||||||
|  | 				case 8: 	return "Norm"; | ||||||
|  | 				case 10: 	return "Slow"; | ||||||
|  | 				default: 	return pirate_sitoa(settings.led_autoadjust, 10, 4); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_LCD_AUTO: { | ||||||
|  | 			return (settings.lcd_autobrite) ? "Auto" : "Manu"; | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_LCD_VALUE: { | ||||||
|  | 			return pirate_sitoa(settings.lcd_brightness, 10, 3); | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_LO: { | ||||||
|  | 			return pirate_sitoa(settings.led_autogain_lev_min, 10, 2); | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_AUTOGAIN_HI: { | ||||||
|  | 			return pirate_sitoa(settings.led_autogain_lev_max, 10, 2); | ||||||
|  | 		} | ||||||
|  | 		case SETTING_BRITE_THRESH0: | ||||||
|  | 		case SETTING_BRITE_THRESH1: | ||||||
|  | 		case SETTING_BRITE_THRESH2: | ||||||
|  | 		case SETTING_BRITE_THRESH3: | ||||||
|  | 		case SETTING_BRITE_THRESH4: { | ||||||
|  | 			return pirate_sitoa(settings.led_autothresh[id - SETTING_BRITE_THRESH0], 10, 2); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		default: { | ||||||
|  | 			return ""; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char * menu_pref_run_prog_disp(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (settings.autorun & 0x02) { | ||||||
|  | 		return "RunProg:Always!"; | ||||||
|  | 	} else { | ||||||
|  | 		return "RunProg:Runmode"; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |   // name changing handler
 | ||||||
|  | void menu_pref_name_next() | ||||||
|  | { | ||||||
|  | 	if (menu_newval) { | ||||||
|  | 		if (settings.name[menu_oldval] < 0x20) { | ||||||
|  | 			settings.name[menu_oldval] = 0x20; | ||||||
|  | 		} else if (settings.name[menu_oldval] < 0x5e) { | ||||||
|  | 			settings.name[menu_oldval]++; | ||||||
|  | 		} else if (settings.name[menu_oldval] == 0x5e) { | ||||||
|  | 			settings.name[menu_oldval] = 0x61; | ||||||
|  | 		} else if (settings.name[menu_oldval] < 0x7d) { | ||||||
|  | 			settings.name[menu_oldval]++; | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		if (menu_oldval < 7) { | ||||||
|  | 			menu_oldval++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2 + menu_oldval, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_pref_name_prev() | ||||||
|  | { | ||||||
|  | 	if (menu_newval) { | ||||||
|  | 		if (settings.name[menu_oldval] > 0x7a) { | ||||||
|  | 			settings.name[menu_oldval] = 0x7a; | ||||||
|  | 		} else if (settings.name[menu_oldval] > 0x61) { | ||||||
|  | 			settings.name[menu_oldval]--; | ||||||
|  | 		} else if (settings.name[menu_oldval] == 0x61) { | ||||||
|  | 			settings.name[menu_oldval] = 0x5e; | ||||||
|  | 		} else if (settings.name[menu_oldval] > 0x20) { | ||||||
|  | 			settings.name[menu_oldval]--; | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		if (menu_oldval) { | ||||||
|  | 			menu_oldval--; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0], 10); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2 + menu_oldval, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_pref_name_menu() | ||||||
|  | { | ||||||
|  | 	menuc = (MenuItem *)&menu_pref_ritem[0]; | ||||||
|  | 	menu_btntype_menus(); | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0] - 1, 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void menu_pref_name_ok() | ||||||
|  | { | ||||||
|  | 	menu_newval ^= 1; | ||||||
|  | 
 | ||||||
|  | 	if (menu_newval) { | ||||||
|  | 		lcd_set_cursor(LCD_LINE_2 + menu_oldval, LCD_CMD_CURSOR_FLASH); | ||||||
|  | 	} else { | ||||||
|  | 		lcd_set_cursor(LCD_LINE_2 + menu_oldval, LCD_CMD_CURSOR_UNDER); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (settings.beeper) { | ||||||
|  | 		beep(settings.beep_type[0] + 1, 10); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_pref_name_start(uint16_t id) | ||||||
|  | { | ||||||
|  | 	// oldval is cursor pos, newval is editing-is-on
 | ||||||
|  | 	menu_oldval = menu_newval = 0; | ||||||
|  | 	lcd_set_cursor(LCD_LINE_2, LCD_CMD_CURSOR_UNDER); | ||||||
|  | 
 | ||||||
|  | 	lcd_btn_fn[BTN_UP] = menu_pref_name_prev; | ||||||
|  | 	lcd_btn_fn[BTN_MENU] = menu_pref_name_menu; | ||||||
|  | 	lcd_btn_fn[BTN_OK] = menu_pref_name_ok; | ||||||
|  | 	lcd_btn_fn[BTN_DOWN] = menu_pref_name_next; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_pref_favcolor_start(uint16_t id) | ||||||
|  | { | ||||||
|  | 	led_eyes_set_program(1, 1, 0, 0, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |   // other settings
 | ||||||
|  | static void menu_pref_autorun_set(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (settings.autorun & 0x01) { | ||||||
|  | 		settings.autorun &= 0xfe; | ||||||
|  | 	} else { | ||||||
|  | 		settings.autorun |= 0x01; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_pref_alwaysrun_tog(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (settings.autorun & 0x02) { | ||||||
|  | 		settings.autorun &= 0xfd; | ||||||
|  | 	} else { | ||||||
|  | 		settings.autorun |= 0x02; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_pref_beepena_set(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (settings.beeper & 0x80) { | ||||||
|  | 		settings.beeper = 0; | ||||||
|  | 	} else { | ||||||
|  | 		settings.beeper |= 0x80; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_pref_brite_auto_ena_set(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (settings.led_autoadjust & 0x80) { | ||||||
|  | 		settings.led_autoadjust &= 0x7f; | ||||||
|  | 	} else { | ||||||
|  | 		settings.led_autoadjust |= 0x80; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_pref_brite_auto_spd_set(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if ((settings.led_autoadjust & 0x7f) >= 10) { | ||||||
|  | 		settings.led_autoadjust &= 0x80; | ||||||
|  | 	} else { | ||||||
|  | 		settings.led_autoadjust += 2; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void menu_pref_brite_lcd_auto_set(uint16_t id) | ||||||
|  | { | ||||||
|  | 	if (settings.lcd_autobrite) { | ||||||
|  | 		settings.lcd_autobrite = 0; | ||||||
|  | 	} else { | ||||||
|  | 		settings.lcd_autobrite = 1; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu construction */ | ||||||
|  |   // declaration
 | ||||||
|  | const MenuItem menu_pref_nameitem[]; | ||||||
|  | const MenuItem menu_pref_favcitem[]; | ||||||
|  | const MenuItem menu_pref_beepitem[]; | ||||||
|  | const MenuItem menu_pref_briteitem[]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // main menu
 | ||||||
|  | const MenuData menu_pref_rdata[] = { | ||||||
|  | 	{"Set Name",            NULL,                   0, 0, 0, 0, 0,       menu_pref_name_start, 0}, | ||||||
|  | 	{"FavColor",            NULL,                   0, 0, 0, 0, 0,   menu_pref_favcolor_start, 0}, | ||||||
|  | 	{"", menu_pref_run_prog_disp,                   0, 4, | ||||||
|  | 			LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, menu_pref_alwaysrun_tog, 0}, | ||||||
|  | 	{"Contrast",            NULL,                   0, 0, 0, 0, 0,          menu_edit_start, SETTING_CONTRAST}, | ||||||
|  | 	{"Beeps",     menu_pref_disp,  SETTING_BEEPER_ENA, 4, 0, 0, 0,      menu_pref_beepena_set, 0}, | ||||||
|  | 	{"BeepMenu",            NULL,                   0, 0, 0, 0, 0,                       NULL, 0}, | ||||||
|  | 	{"Brightness",          NULL,                   0, 0, | ||||||
|  | 			LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN,                    NULL, 0}, | ||||||
|  | 	{"AutoRun",   menu_pref_disp, SETTING_AUTORUN_ENA, 4, 0, 0, 0,      menu_pref_autorun_set, 0} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const MenuItem menu_pref_ritem[] = { | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SETTINGS],                   0, &menu_pref_ritem[1],  &menu_pref_nameitem[0], &menu_pref_rdata[0]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SETTINGS], &menu_pref_ritem[0], &menu_pref_ritem[2],  &menu_pref_favcitem[0], &menu_pref_rdata[1]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SETTINGS], &menu_pref_ritem[1], &menu_pref_ritem[3],                       0, &menu_pref_rdata[2]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SETTINGS], &menu_pref_ritem[2], &menu_pref_ritem[4],                       0, &menu_pref_rdata[3]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SETTINGS], &menu_pref_ritem[3], &menu_pref_ritem[5],                       0, &menu_pref_rdata[4]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SETTINGS], &menu_pref_ritem[4], &menu_pref_ritem[6],  &menu_pref_beepitem[0], &menu_pref_rdata[5]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SETTINGS], &menu_pref_ritem[5], &menu_pref_ritem[7], &menu_pref_briteitem[0], &menu_pref_rdata[6]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_SETTINGS], &menu_pref_ritem[6],                   0,                       0, &menu_pref_rdata[7]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // name editing
 | ||||||
|  | const MenuData menu_pref_namedata[] = { | ||||||
|  | 	{"", menu_pref_disp, SETTING_NAME, 4, 0, 0, 0, NULL, 0} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_pref_nameitem[] = { | ||||||
|  | 	{&menu_pref_ritem[0], 0, 0, 0, &menu_pref_namedata[0]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // fav color menu
 | ||||||
|  | const MenuData menu_pref_favcdata[] = { | ||||||
|  | 	{"Red   ",   menu_pref_disp,   SETTING_FAVCOLOR_RED, 4, 0, 0, 0, menu_edit_start,   SETTING_FAVCOLOR_RED}, | ||||||
|  | 	{"Green ",   menu_pref_disp, SETTING_FAVCOLOR_GREEN, 4, 0, 0, 0, menu_edit_start, SETTING_FAVCOLOR_GREEN}, | ||||||
|  | 	{"Blue  ",   menu_pref_disp,  SETTING_FAVCOLOR_BLUE, 4, 0, 0, 0, menu_edit_start,  SETTING_FAVCOLOR_BLUE} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_pref_favcitem[] = { | ||||||
|  | 	{&menu_pref_ritem[1],                      0, &menu_pref_favcitem[1], 0, &menu_pref_favcdata[0]}, | ||||||
|  | 	{&menu_pref_ritem[1], &menu_pref_favcitem[0], &menu_pref_favcitem[2], 0, &menu_pref_favcdata[1]}, | ||||||
|  | 	{&menu_pref_ritem[1], &menu_pref_favcitem[1],                      0, 0, &menu_pref_favcdata[2]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // beeper config menu
 | ||||||
|  | const MenuData menu_pref_beepdata[] = { | ||||||
|  | 	{"Button", menu_pref_disp, SETTING_BEEP_TYPE_BUTTON, 4, 0, 0, 0, menu_edit_start, SETTING_BEEP_TYPE_BUTTON}, | ||||||
|  | 	{"Paging", menu_pref_disp, SETTING_BEEP_TYPE_PAGING, 4, 0, 0, 0, menu_edit_start, SETTING_BEEP_TYPE_PAGING}, | ||||||
|  | 	{"Alarm ", menu_pref_disp,  SETTING_BEEP_TYPE_ALARM, 4, 0, 0, 0, menu_edit_start,  SETTING_BEEP_TYPE_ALARM} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_pref_beepitem[] = { | ||||||
|  | 	{&menu_pref_ritem[5],                      0, &menu_pref_beepitem[1], 0, &menu_pref_beepdata[0]}, | ||||||
|  | 	{&menu_pref_ritem[5], &menu_pref_beepitem[0], &menu_pref_beepitem[2], 0, &menu_pref_beepdata[1]}, | ||||||
|  | 	{&menu_pref_ritem[5], &menu_pref_beepitem[1],                      0, 0, &menu_pref_beepdata[2]} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  |   // brightness menu
 | ||||||
|  | const MenuData menu_pref_britedata[] = { | ||||||
|  | 	{"Auto",   menu_pref_disp,    SETTING_BRITE_AUTO_ENA, 4, 0, 0, 0, menu_pref_brite_auto_ena_set,                         0}, | ||||||
|  | 	{"Spd ",   menu_pref_disp,  SETTING_BRITE_AUTO_SPEED, 4, 0, 0, 0, menu_pref_brite_auto_spd_set,                         0}, | ||||||
|  | 	{"LCD ",   menu_pref_disp,    SETTING_BRITE_LCD_AUTO, 4, 0, 0, 0, menu_pref_brite_lcd_auto_set,                         0}, | ||||||
|  | 	{"LCDlv",  menu_pref_disp,   SETTING_BRITE_LCD_VALUE, 4, 0, 0, 0,              menu_edit_start,   SETTING_BRITE_LCD_VALUE}, | ||||||
|  | 	{"AGNLo",  menu_pref_disp, SETTING_BRITE_AUTOGAIN_LO, 4, 0, 0, 0,              menu_edit_start, SETTING_BRITE_AUTOGAIN_LO}, | ||||||
|  | 	{"AGNHi",  menu_pref_disp, SETTING_BRITE_AUTOGAIN_HI, 4, 0, 0, 0,              menu_edit_start, SETTING_BRITE_AUTOGAIN_HI}, | ||||||
|  | 	{"GnDay ", menu_pref_disp,     SETTING_BRITE_THRESH0, 4, 0, 0, 0,              menu_edit_start,     SETTING_BRITE_THRESH0}, | ||||||
|  | 	{"GnBrt ", menu_pref_disp,     SETTING_BRITE_THRESH1, 4, 0, 0, 0,              menu_edit_start,     SETTING_BRITE_THRESH1}, | ||||||
|  | 	{"GnNrm ", menu_pref_disp,     SETTING_BRITE_THRESH2, 4, 0, 0, 0,              menu_edit_start,     SETTING_BRITE_THRESH2}, | ||||||
|  | 	{"GnDim ", menu_pref_disp,     SETTING_BRITE_THRESH3, 4, 0, 0, 0,              menu_edit_start,     SETTING_BRITE_THRESH3}, | ||||||
|  | 	{"GnDrk ", menu_pref_disp,     SETTING_BRITE_THRESH4, 4, 0, 0, 0,              menu_edit_start,     SETTING_BRITE_THRESH4} | ||||||
|  | }; | ||||||
|  | const MenuItem menu_pref_briteitem[] = { | ||||||
|  | 	{&menu_pref_ritem[6],                       0,  &menu_pref_briteitem[1], 0, &menu_pref_britedata[0]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[0],  &menu_pref_briteitem[2], 0, &menu_pref_britedata[1]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[1],  &menu_pref_briteitem[3], 0, &menu_pref_britedata[2]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[2],  &menu_pref_briteitem[4], 0, &menu_pref_britedata[3]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[3],  &menu_pref_briteitem[5], 0, &menu_pref_britedata[4]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[4],  &menu_pref_briteitem[6], 0, &menu_pref_britedata[5]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[5],  &menu_pref_briteitem[7], 0, &menu_pref_britedata[6]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[6],  &menu_pref_briteitem[8], 0, &menu_pref_britedata[7]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[7],  &menu_pref_briteitem[9], 0, &menu_pref_britedata[8]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[8], &menu_pref_briteitem[10], 0, &menu_pref_britedata[9]}, | ||||||
|  | 	{&menu_pref_ritem[6], &menu_pref_briteitem[9],                        0, 0, &menu_pref_britedata[10]} | ||||||
|  | }; | ||||||
							
								
								
									
										57
									
								
								fw_dc22_stm32l100/src/menu/menu_settings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								fw_dc22_stm32l100/src/menu/menu_settings.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_settings.h: setting shit up for pirates since | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_settings.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_MENU_SETTINGS_H | ||||||
|  | #define __PIRATE_MENU_SETTINGS_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | extern const MenuItem menu_pref_ritem[]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* settings defines */ | ||||||
|  | #define SETTING_NAME 				0x0101 | ||||||
|  | 
 | ||||||
|  | #define SETTING_AUTORUN_ENA 		0x0105 | ||||||
|  | #define SETTING_ALWAYS_RUN_PROG_ENA	0x0106 | ||||||
|  | 
 | ||||||
|  | #define SETTING_CONTRAST 			0x0107 | ||||||
|  | 
 | ||||||
|  | #define SETTING_FAVCOLOR_RED 		0x0109 | ||||||
|  | #define SETTING_FAVCOLOR_GREEN 		0x010a | ||||||
|  | #define SETTING_FAVCOLOR_BLUE 		0x010b | ||||||
|  | 
 | ||||||
|  | #define SETTING_BEEPER_ENA 			0x0110 | ||||||
|  | #define SETTING_BEEP_TYPE_BUTTON 	0x0111 | ||||||
|  | #define SETTING_BEEP_TYPE_PAGING 	0x0112 | ||||||
|  | #define SETTING_BEEP_TYPE_ALARM 	0x0113 | ||||||
|  | 
 | ||||||
|  | #define SETTING_BRITE_AUTO_ENA 		0x0120 | ||||||
|  | #define SETTING_BRITE_AUTO_SPEED 	0x0121 | ||||||
|  | #define SETTING_BRITE_LCD_AUTO 		0x0122 | ||||||
|  | #define SETTING_BRITE_LCD_VALUE 	0x0123 | ||||||
|  | #define SETTING_BRITE_AUTOGAIN_LO 	0x0124 | ||||||
|  | #define SETTING_BRITE_AUTOGAIN_HI 	0x0125 | ||||||
|  | #define SETTING_BRITE_THRESH0 		0x012a | ||||||
|  | #define SETTING_BRITE_THRESH1 		0x012b | ||||||
|  | #define SETTING_BRITE_THRESH2 		0x012c | ||||||
|  | #define SETTING_BRITE_THRESH3 		0x012d | ||||||
|  | #define SETTING_BRITE_THRESH4 		0x012e | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* prototypes */ | ||||||
|  | void menu_settings_save(uint16_t id); | ||||||
|  | 
 | ||||||
|  | void settings_save(); | ||||||
|  | void settings_restore(uint8_t load_defaults); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										111
									
								
								fw_dc22_stm32l100/src/menu/menu_settings_defprog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								fw_dc22_stm32l100/src/menu/menu_settings_defprog.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_settings_defprog.h: firmware default LED programs | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * $Id: menu_settings_defprog.h 375 2015-07-06 02:52:40Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | /* SKULL */ | ||||||
|  | // random flashing
 | ||||||
|  | settings.led_prog[0][0].type = 0b10000000; 	// enabled, no init, program mode
 | ||||||
|  | settings.led_prog[0][0].dwell = 8; | ||||||
|  | settings.led_prog[0][0].progidx = 4; | ||||||
|  | settings.led_prog[0][0].wait = 80; | ||||||
|  | settings.led_prog[0][0].level = 0xffe0; | ||||||
|  | settings.led_prog[0][0].offset = 0x00; | ||||||
|  | settings.led_prog[0][0].option = 0x03; | ||||||
|  | 
 | ||||||
|  | // loops with trails clockwise
 | ||||||
|  | settings.led_prog[0][1].type = 0b10000000; 	// enabled, no init, program mode
 | ||||||
|  | settings.led_prog[0][1].dwell = 7; | ||||||
|  | settings.led_prog[0][1].progidx = 1; | ||||||
|  | settings.led_prog[0][1].wait = 80; | ||||||
|  | settings.led_prog[0][1].level = 0xfff0; | ||||||
|  | settings.led_prog[0][1].offset = 0x80; | ||||||
|  | settings.led_prog[0][1].option = 0xc3; | ||||||
|  | 
 | ||||||
|  | // loops with trails white changes direction
 | ||||||
|  | settings.led_prog[0][2].type = 0b10000000; 	// enabled, no init, program mode
 | ||||||
|  | settings.led_prog[0][2].dwell = 7; | ||||||
|  | settings.led_prog[0][2].progidx = 3; | ||||||
|  | settings.led_prog[0][2].wait = 80; | ||||||
|  | settings.led_prog[0][2].level = 0xfff0; | ||||||
|  | settings.led_prog[0][2].offset = 0x00000000; | ||||||
|  | settings.led_prog[0][2].option = 0x400f00c7; | ||||||
|  | 
 | ||||||
|  | // purple haze
 | ||||||
|  | settings.led_prog[0][3].type = 0b10000000; 	// enabled, no init, program mode
 | ||||||
|  | settings.led_prog[0][3].dwell = 3; | ||||||
|  | settings.led_prog[0][3].progidx = 4; | ||||||
|  | settings.led_prog[0][3].wait = 15; | ||||||
|  | settings.led_prog[0][3].level = 0xff10; | ||||||
|  | settings.led_prog[0][3].offset = 0x00; | ||||||
|  | settings.led_prog[0][3].option = 0xc3; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* BONES */ | ||||||
|  | // clockwise rotation
 | ||||||
|  | settings.led_prog[1][0].type = 0b10000000; 	// enabled, no init, program mode
 | ||||||
|  | settings.led_prog[1][0].dwell = 15; | ||||||
|  | settings.led_prog[1][0].progidx = 1; | ||||||
|  | settings.led_prog[1][0].wait = 160; | ||||||
|  | settings.led_prog[1][0].level = 0xf0; | ||||||
|  | settings.led_prog[1][0].offset = 0x00; | ||||||
|  | settings.led_prog[1][0].option = 0x50; | ||||||
|  | 
 | ||||||
|  | // up-down scrubbing
 | ||||||
|  | settings.led_prog[1][1].type = 0b10000010; 	// enabled, init, program mode
 | ||||||
|  | settings.led_prog[1][1].dwell = 9; | ||||||
|  | settings.led_prog[1][1].progidx = 2; | ||||||
|  | settings.led_prog[1][1].wait = 100; | ||||||
|  | settings.led_prog[1][1].level = 0xff; | ||||||
|  | settings.led_prog[1][1].offset = 0x00; | ||||||
|  | settings.led_prog[1][1].option = 0x50; | ||||||
|  | 
 | ||||||
|  | // all on
 | ||||||
|  | settings.led_prog[1][2].type = 0b10000010; 	// enabled, init, program mode
 | ||||||
|  | settings.led_prog[1][2].dwell = 1; | ||||||
|  | settings.led_prog[1][2].progidx = 0; | ||||||
|  | settings.led_prog[1][2].wait = 80; | ||||||
|  | settings.led_prog[1][2].level = 0xf0; | ||||||
|  | settings.led_prog[1][2].offset = 0x00; | ||||||
|  | settings.led_prog[1][2].option = 0x00; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* EYES */ | ||||||
|  | // red with green flashes
 | ||||||
|  | settings.led_prog[2][0].type = 0b10000000; 	// enabled, no init, program mode
 | ||||||
|  | settings.led_prog[2][0].dwell = 15; | ||||||
|  | settings.led_prog[2][0].progidx = 2; | ||||||
|  | settings.led_prog[2][0].wait = 30; | ||||||
|  | settings.led_prog[2][0].level = 0x00; | ||||||
|  | settings.led_prog[2][0].offset = 0x00f000e6; | ||||||
|  | settings.led_prog[2][0].option = 0x14000001; | ||||||
|  | 
 | ||||||
|  | // pink-ized "cop mode-lite"
 | ||||||
|  | settings.led_prog[2][1].type = 0b10000000; 	// enabled, no init, program mode
 | ||||||
|  | settings.led_prog[2][1].dwell = 10; | ||||||
|  | settings.led_prog[2][1].progidx = 2; | ||||||
|  | settings.led_prog[2][1].wait = 50; | ||||||
|  | settings.led_prog[2][1].level = 0x00; | ||||||
|  | settings.led_prog[2][1].offset = 0x0000f090; | ||||||
|  | settings.led_prog[2][1].option = 0x20001001; | ||||||
|  | 
 | ||||||
|  | // candle flicker with favcolor
 | ||||||
|  | settings.led_prog[2][2].type = 0b10000000; 	// enabled, no init, program mode
 | ||||||
|  | settings.led_prog[2][2].dwell = 18; | ||||||
|  | settings.led_prog[2][2].progidx = 1; | ||||||
|  | settings.led_prog[2][2].wait = 80; | ||||||
|  | settings.led_prog[2][2].level = 0x00; | ||||||
|  | settings.led_prog[2][2].offset = 0x00000000; | ||||||
|  | settings.led_prog[2][2].option = 0x00000000; | ||||||
|  | 
 | ||||||
|  | // turquoise-type pulse with red fail-flicker
 | ||||||
|  | settings.led_prog[2][3].type = 0b10000000; 	// enabled, no init, program mode
 | ||||||
|  | settings.led_prog[2][3].dwell = 7; | ||||||
|  | settings.led_prog[2][3].progidx = 2; | ||||||
|  | settings.led_prog[2][3].wait = 20; | ||||||
|  | settings.led_prog[2][3].level = 0x00; | ||||||
|  | settings.led_prog[2][3].offset = 0x00f93012; | ||||||
|  | settings.led_prog[2][3].option = 0x70000001; | ||||||
							
								
								
									
										63
									
								
								fw_dc22_stm32l100/src/menu/menu_testing.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								fw_dc22_stm32l100/src/menu/menu_testing.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_testing.c: test menu and testing functions | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_testing.c 350 2015-05-28 02:23:03Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | #include "lcd_menu.h" | ||||||
|  | #include "menu_testing.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   // testing
 | ||||||
|  | static uint8_t buzzer_select; | ||||||
|  | static uint8_t matrix_select; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menu functions */ | ||||||
|  | static char * lcd_menu_testing_buzzer(uint16_t id) | ||||||
|  | { | ||||||
|  | 	return pirate_sitoa(buzzer_select, 10, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static char * lcd_menu_testing_matrix(uint16_t id) | ||||||
|  | { | ||||||
|  | 	return pirate_sitoa(matrix_select, 10, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static char * lcd_menu_testing_boneled(uint16_t id) | ||||||
|  | { | ||||||
|  | 	return pirate_sitoa(matrix_select, 10, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static char * lcd_menu_testing_settings_bytes(uint16_t id) | ||||||
|  | { | ||||||
|  | 	static char size[12]; | ||||||
|  | 
 | ||||||
|  | 	strcpy(size, pirate_sitoa(sizeof(settings), 10, 0)); | ||||||
|  | 	strncat(size, "bytes", 12); | ||||||
|  | 
 | ||||||
|  | 	return size; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* menu construction */ | ||||||
|  | const MenuData menu_test_rdata[] = { | ||||||
|  | 	{"Buzz  ",  lcd_menu_testing_buzzer,         0, 0,                 0,                  0,                  0, NULL, 0}, | ||||||
|  | 	{"MPurp ",  lcd_menu_testing_matrix,         0, 0,                 0,                  0,                  0, NULL, 0}, | ||||||
|  | 	{"MWht  ",  lcd_menu_testing_matrix,         0, 0,                 0,                  0,                  0, NULL, 0}, | ||||||
|  | 	{"Bone  ",  lcd_menu_testing_boneled,        0, 0,                 0,                  0,                  0, NULL, 0}, | ||||||
|  | 	{"NVRAM",   lcd_menu_testing_settings_bytes, 0, 10, LCD_DEF_SPACING, LCD_DEF_SCROLL_WAIT, LCD_DEF_SCROLL_RUN, NULL, 0} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const MenuItem menu_test_ritem[] = { | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_TESTING],                   0, &menu_test_ritem[1], 0, &menu_test_rdata[0]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_TESTING], &menu_test_ritem[0], &menu_test_ritem[2], 0, &menu_test_rdata[1]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_TESTING], &menu_test_ritem[1], &menu_test_ritem[3], 0, &menu_test_rdata[2]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_TESTING], &menu_test_ritem[2], &menu_test_ritem[4], 0, &menu_test_rdata[3]}, | ||||||
|  | 	{&menu_ritem[LCD_MENU_ROOT_TESTING], &menu_test_ritem[3],                   0, 0, &menu_test_rdata[4]} | ||||||
|  | }; | ||||||
							
								
								
									
										21
									
								
								fw_dc22_stm32l100/src/menu/menu_testing.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								fw_dc22_stm32l100/src/menu/menu_testing.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | /**
 | ||||||
|  |  * menu_testing.h: test menu and testing functions | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: menu_testing.h 327 2015-02-18 04:43:42Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | #ifndef __PIRATE_MENU_TESTING_H | ||||||
|  | #define __PIRATE_MENU_TESTING_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* menus */ | ||||||
|  | extern const MenuItem menu_test_ritem[]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										241
									
								
								fw_dc22_stm32l100/src/pirate.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								fw_dc22_stm32l100/src/pirate.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,241 @@ | |||||||
|  | /**
 | ||||||
|  |  * pirate.c: yarrrgh mateys miscellaneous shit and system-wide common crap | ||||||
|  |  * 2014 by true | ||||||
|  |  * | ||||||
|  |  * ---- | ||||||
|  |  * | ||||||
|  |  * $Id: pirate.c 505 2021-09-05 19:07:51Z true $ | ||||||
|  |  * | ||||||
|  | **/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include "pirate.h" | ||||||
|  | 
 | ||||||
|  | #include "device/attiny.h" | ||||||
|  | #include "device/lcd.h" | ||||||
|  | #include "display/cgram/cgram.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | uint8_t temperature; 		// pirate.h
 | ||||||
|  | int8_t temperature_cal; 	// pirate.h
 | ||||||
|  | uint8_t light_level; 		// pirate.h
 | ||||||
|  | uint8_t light_gain; 		// pirate.h
 | ||||||
|  | uint16_t mic_peak; 			// pirate.h
 | ||||||
|  | 
 | ||||||
|  | uint8_t dc23_nametx; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | PirateSettings settings; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * CEASE ALL OPERATIONS | ||||||
|  |  * note: we still consume ~7mA like this, probably because of circuit design fuckup | ||||||
|  |  ********/ | ||||||
|  | void pirate_shutdown(uint16_t type) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	// turn off eyes LEDs
 | ||||||
|  | 	for (i = 0; i < 8; i++) { | ||||||
|  | 		led_eyes_set_level(i, 0); | ||||||
|  | 	} | ||||||
|  | 	led_eyes_tx(); | ||||||
|  | 
 | ||||||
|  | 	// put attiny to sleep
 | ||||||
|  | 	attiny_sleep(); | ||||||
|  | 
 | ||||||
|  | 	// enable cgram
 | ||||||
|  | 	lcd_cmd(LCD_CMD_SINGLEHEIGHT & 0xfe); | ||||||
|  | 
 | ||||||
|  | 	// send crown data
 | ||||||
|  | 	for (i = 1; i <= 6; i++) { | ||||||
|  | 		lcd_print(0x40 + (i << 3), (uint8_t *)cgram_crown[i - 1], 8); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// print shutdown message
 | ||||||
|  | 	static const uint8_t line1[8] = {0x01, 0x02, 0x03, 'T', 'h', 'r', 'e', 'e'}; | ||||||
|  | 	static const uint8_t line2[8] = {0x04, 0x05, 0x06, 'K', 'i', 'n', 'g', 's'}; | ||||||
|  | 
 | ||||||
|  | 	lcd_print(LCD_LINE_1, (uint8_t *)line1, 8); | ||||||
|  | 	lcd_print(LCD_LINE_2, (uint8_t *)line2, 8); | ||||||
|  | 
 | ||||||
|  | 	// turn off CPU and all peripherals
 | ||||||
|  | 	PWR_EnterSTANDBYMode(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * update the pirate quick pseudorng | ||||||
|  |  ********/ | ||||||
|  | uint32_t pirate_prng_val = 1; | ||||||
|  | uint8_t pirate_prng() | ||||||
|  | { | ||||||
|  | 	int lsb = pirate_prng_val & 1; | ||||||
|  | 	pirate_prng_val >>= 1; | ||||||
|  | 	if (lsb) pirate_prng_val ^= 0x7ffff159; | ||||||
|  | 
 | ||||||
|  | 	return (uint8_t)pirate_prng_val; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * a really shitty hackish delay function | ||||||
|  |  ********/ | ||||||
|  | void pirate_delay(uint16_t ms) | ||||||
|  | { | ||||||
|  | 	uint32_t wait; | ||||||
|  | 
 | ||||||
|  | 	wait = ((SystemCoreClock / 2000) * ms) - 20; | ||||||
|  | 	while (wait--) asm volatile("nop"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * scale an int16_t from one range to another | ||||||
|  |  ********/ | ||||||
|  | int16_t pirate_scale(int16_t value, int16_t src_min, int16_t src_max, int16_t dest_min, int16_t dest_max) | ||||||
|  | { | ||||||
|  | 	int32_t w; | ||||||
|  | 
 | ||||||
|  | 	if (dest_min == dest_max) return dest_min; | ||||||
|  | 	if (value < src_min) return dest_min; | ||||||
|  | 	if (value > src_max) return dest_max; | ||||||
|  | 
 | ||||||
|  | 	w = (dest_max - dest_min) * (value - src_min); | ||||||
|  | 	w /= (src_max - src_min); | ||||||
|  | 	w += dest_min; | ||||||
|  | 
 | ||||||
|  | 	return (int16_t)w; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * itoa for pirates | ||||||
|  |  ********/ | ||||||
|  | char * pirate_itoa(uint32_t val, uint8_t base, uint8_t leftpad) | ||||||
|  | { | ||||||
|  | 	static char buf[11] = {0}; | ||||||
|  | 	int i; | ||||||
|  | 	int j; | ||||||
|  | 
 | ||||||
|  | 	buf[10] = 0; | ||||||
|  | 
 | ||||||
|  | 	if (val == 0) { | ||||||
|  | 		buf[9] = '0'; | ||||||
|  | 		i = 8; | ||||||
|  | 	} else { | ||||||
|  | 		for (i = 9; val && i; --i, val /= base) | ||||||
|  | 			buf[i] = "0123456789ABCDEF"[val % base]; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (leftpad) { | ||||||
|  | 		j = 9 - leftpad; | ||||||
|  | 		while (j < i) { | ||||||
|  | 			buf[i] = 0x20; | ||||||
|  | 			i--; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return &buf[i + 1]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char * pirate_sitoa(int32_t val, uint8_t base, uint8_t leftpad) | ||||||
|  | { | ||||||
|  | 	static char buf[11] = {0}; | ||||||
|  | 	int neg; | ||||||
|  | 	int i; | ||||||
|  | 	int j; | ||||||
|  | 
 | ||||||
|  | 	buf[10] = 0; | ||||||
|  | 
 | ||||||
|  | 	neg = val < 0 ? 1 : 0; | ||||||
|  | 	val = abs(val); | ||||||
|  | 
 | ||||||
|  | 	if (val == 0) { | ||||||
|  | 		buf[9] = '0'; | ||||||
|  | 		i = 8; | ||||||
|  | 	} else { | ||||||
|  | 		for (i = 9; val && i; --i, val /= base) | ||||||
|  | 			buf[i] = "0123456789ABCDEF"[val % base]; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (neg) { | ||||||
|  | 		buf[i] = '-'; | ||||||
|  | 		i--; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (leftpad) { | ||||||
|  | 		j = 9 - leftpad; | ||||||
|  | 		while (j < i) { | ||||||
|  | 			buf[i] = 0x20; | ||||||
|  | 			i--; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return &buf[i + 1]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * battery voltage | ||||||
|  |  ********/ | ||||||
|  | static uint8_t pirate_batt_histlog = 0; | ||||||
|  | static uint16_t pirate_batt_history[32]; | ||||||
|  | uint16_t pirate_batt_voltage() | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	uint32_t t = 0; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 32; i++) { | ||||||
|  | 		t += pirate_batt_history[i]; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return t >> 5; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void pirate_batt_log(uint16_t rawvalue) | ||||||
|  | { | ||||||
|  | 	int t; | ||||||
|  | 
 | ||||||
|  | 	t = (rawvalue << 4) / 195; | ||||||
|  | 
 | ||||||
|  | 	pirate_batt_history[pirate_batt_histlog] = t; | ||||||
|  | 
 | ||||||
|  | 	pirate_batt_histlog++; | ||||||
|  | 	pirate_batt_histlog &= 0x1f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * pirate temperature (always hot like a mofo) | ||||||
|  |  ********/ | ||||||
|  | static uint8_t pirate_temp_histlog = 0; | ||||||
|  | static uint8_t pirate_temp_history[20]; | ||||||
|  | uint16_t pirate_thermometer(uint8_t deg_f) { | ||||||
|  | 	int i; | ||||||
|  | 	uint32_t t = 0; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < 20; i++) { | ||||||
|  | 		t += pirate_temp_history[i]; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t >>= 1; | ||||||
|  | 
 | ||||||
|  | 	if (deg_f) { | ||||||
|  | 		return (((t * 9) / 5) / 10) + 32; | ||||||
|  | 	} else { | ||||||
|  | 		return t; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void pirate_thermometer_log(uint8_t temp) | ||||||
|  | { | ||||||
|  | 	pirate_temp_history[pirate_temp_histlog] = temp; | ||||||
|  | 
 | ||||||
|  | 	pirate_temp_histlog++; | ||||||
|  | 	if (pirate_temp_histlog > 20) pirate_temp_histlog = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********
 | ||||||
|  |  * shit used by USB | ||||||
|  |  ********/ | ||||||
|  | void Error_Handler() | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										171
									
								
								fw_dc22_stm32l100/src/stm32l1xx_it.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								fw_dc22_stm32l100/src/stm32l1xx_it.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,171 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    ADC/ADC1_AnalogWatchdog/stm32l1xx_it.c  | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V1.2.2 | ||||||
|  |   * @date    17-November-2021 | ||||||
|  |   * @brief   Main Interrupt Service Routines. | ||||||
|  |   *          This file provides template for all exceptions handler and peripherals | ||||||
|  |   *          interrupt service routine. | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * Copyright (c) 2015 STMicroelectronics. | ||||||
|  |   * All rights reserved. | ||||||
|  |   * | ||||||
|  |   * This software is licensed under terms that can be found in the LICENSE file | ||||||
|  |   * in the root directory of this software component. | ||||||
|  |   * If no LICENSE file comes with this software, it is provided AS-IS. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "stm32l1xx_it.h" | ||||||
|  | 
 | ||||||
|  | #ifdef USE_STM32L152D_EVAL  | ||||||
|  |   #include "stm32l152d_eval.h" | ||||||
|  | #elif defined USE_STM32L152_EVAL  | ||||||
|  |   #include "stm32l152_eval.h" | ||||||
|  | #endif  | ||||||
|  | 
 | ||||||
|  | /** @addtogroup STM32L1xx_StdPeriph_Examples
 | ||||||
|  |   * @{ | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /** @addtogroup ADC1_AnalogWatchdog
 | ||||||
|  |   * @{ | ||||||
|  |   */  | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /******************************************************************************/ | ||||||
|  | /*            Cortex-M3 Processor Exceptions Handlers                         */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles NMI exception. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void NMI_Handler(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles Hard Fault exception. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void HardFault_Handler(void) | ||||||
|  | { | ||||||
|  |   /* Go to infinite loop when Hard Fault exception occurs */ | ||||||
|  |   while (1) | ||||||
|  |   { | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles Memory Manage exception. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void MemManage_Handler(void) | ||||||
|  | { | ||||||
|  |   /* Go to infinite loop when Memory Manage exception occurs */ | ||||||
|  |   while (1) | ||||||
|  |   { | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles Bus Fault exception. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void BusFault_Handler(void) | ||||||
|  | { | ||||||
|  |   /* Go to infinite loop when Bus Fault exception occurs */ | ||||||
|  |   while (1) | ||||||
|  |   { | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles Usage Fault exception. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void UsageFault_Handler(void) | ||||||
|  | { | ||||||
|  |   /* Go to infinite loop when Usage Fault exception occurs */ | ||||||
|  |   while (1) | ||||||
|  |   { | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles SVCall exception. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void SVC_Handler(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles Debug Monitor exception. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void DebugMon_Handler(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles PendSV_Handler exception. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void PendSV_Handler(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles SysTick Handler. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void SysTick_Handler(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /******************************************************************************/ | ||||||
|  | /*                 STM32L1xx Peripherals Interrupt Handlers                   */ | ||||||
|  | /*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */ | ||||||
|  | /*  available peripheral interrupt handler's name please refer to the startup */ | ||||||
|  | /*  file (startup_stm32l1xx_xx.s).                                            */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  This function handles PPP interrupt request. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | /*void PPP_IRQHandler(void)
 | ||||||
|  | { | ||||||
|  | }*/ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */  | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */  | ||||||
|  | 
 | ||||||
							
								
								
									
										525
									
								
								fw_dc22_stm32l100/src/system_stm32l1xx.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										525
									
								
								fw_dc22_stm32l100/src/system_stm32l1xx.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,525 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    system_stm32l1xx.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V1.2.2 | ||||||
|  |   * @date    17-November-2021 | ||||||
|  |   * @brief   CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. | ||||||
|  |   *          This file contains the system clock configuration for STM32L1xx Ultra | ||||||
|  |   *          Low Power devices, and is generated by the clock configuration | ||||||
|  |   *          tool "STM32L1xx_Clock_Configuration_V1.1.0.xls". | ||||||
|  |   *              | ||||||
|  |   * 1.  This file provides two functions and one global variable to be called from  | ||||||
|  |   *     user application: | ||||||
|  |   *      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier | ||||||
|  |   *                      and Divider factors, AHB/APBx prescalers and Flash settings), | ||||||
|  |   *                      depending on the configuration made in the clock xls tool.  | ||||||
|  |   *                      This function is called at startup just after reset and  | ||||||
|  |   *                      before branch to main program. This call is made inside | ||||||
|  |   *                      the "startup_stm32l1xx_xx.s" file. | ||||||
|  |   *                         | ||||||
|  |   *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used | ||||||
|  |   *                                  by the user application to setup the SysTick  | ||||||
|  |   *                                  timer or configure other parameters. | ||||||
|  |   *                                      | ||||||
|  |   *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must | ||||||
|  |   *                                 be called whenever the core clock is changed | ||||||
|  |   *                                 during program execution.    | ||||||
|  |   *       | ||||||
|  |   * 2. After each device reset the MSI (2.1 MHz Range) is used as system clock source. | ||||||
|  |   *    Then SystemInit() function is called, in "startup_stm32l1xx_xx.s" file, to | ||||||
|  |   *    configure the system clock before to branch to main program.     | ||||||
|  |   *     | ||||||
|  |   * 3. If the system clock source selected by user fails to startup, the SystemInit() | ||||||
|  |   *    function will do nothing and MSI still used as system clock source. User can  | ||||||
|  |   *    add some code to deal with this issue inside the SetSysClock() function. | ||||||
|  |   *  | ||||||
|  |   * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define | ||||||
|  |   *    in "stm32l1xx.h" file. When HSE is used as system clock source, directly or | ||||||
|  |   *    through PLL, and you are using different crystal you have to adapt the HSE | ||||||
|  |   *    value to your own configuration. | ||||||
|  |   *  | ||||||
|  |   * 5. This file configures the system clock as follows:   | ||||||
|  |   *============================================================================= | ||||||
|  |   *                         System Clock Configuration | ||||||
|  |   *============================================================================= | ||||||
|  |   *        System Clock source          | PLL(HSE) | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        SYSCLK                       | 32000000 Hz | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        HCLK                         | 32000000 Hz | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        AHB Prescaler                | 1 | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        APB1 Prescaler               | 1 | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        APB2 Prescaler               | 1 | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        HSE Frequency                | 8000000 Hz | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        PLL DIV                      | 3 | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        PLL MUL                      | 12 | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        VDD                          | 3.3 V | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        Vcore                        | 1.8 V (Range 1) | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        Flash Latency                | 1 WS | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        SDIO clock (SDIOCLK)         | 48000000 Hz | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *        Require 48MHz for USB clock  | Disabled | ||||||
|  |   *----------------------------------------------------------------------------- | ||||||
|  |   *============================================================================= | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * Copyright (c) 2015 STMicroelectronics. | ||||||
|  |   * All rights reserved. | ||||||
|  |   * | ||||||
|  |   * This software is licensed under terms that can be found in the LICENSE file | ||||||
|  |   * in the root directory of this software component. | ||||||
|  |   * If no LICENSE file comes with this software, it is provided AS-IS. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /** @addtogroup CMSIS
 | ||||||
|  |   * @{ | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /** @addtogroup stm32l1xx_system
 | ||||||
|  |   * @{ | ||||||
|  |   */   | ||||||
|  |    | ||||||
|  | /** @addtogroup STM32L1xx_System_Private_Includes
 | ||||||
|  |   * @{ | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | #include "stm32l1xx.h" | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /** @addtogroup STM32L1xx_System_Private_TypesDefinitions
 | ||||||
|  |   * @{ | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /** @addtogroup STM32L1xx_System_Private_Defines
 | ||||||
|  |   * @{ | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /*!< Uncomment the following line if you need to use external SRAM mounted
 | ||||||
|  |      on STM32L152D_EVAL board as data memory  */ | ||||||
|  | /* #define DATA_IN_ExtSRAM */ | ||||||
|  |    | ||||||
|  | /*!< Uncomment the following line if you need to relocate your vector Table in
 | ||||||
|  |      Internal SRAM. */  | ||||||
|  | /* #define VECT_TAB_SRAM */ | ||||||
|  | #define VECT_TAB_OFFSET  0x0 /*!< Vector Table base offset field.  | ||||||
|  |                                   This value must be a multiple of 0x200. */ | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /** @addtogroup STM32L1xx_System_Private_Macros
 | ||||||
|  |   * @{ | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /** @addtogroup STM32L1xx_System_Private_Variables
 | ||||||
|  |   * @{ | ||||||
|  |   */ | ||||||
|  | uint32_t SystemCoreClock    = 32000000; | ||||||
|  | __I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48}; | ||||||
|  | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /** @addtogroup STM32L1xx_System_Private_FunctionPrototypes
 | ||||||
|  |   * @{ | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | static void SetSysClock(void); | ||||||
|  | #ifdef DATA_IN_ExtSRAM | ||||||
|  |   static void SystemInit_ExtMemCtl(void);  | ||||||
|  | #endif /* DATA_IN_ExtSRAM */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /** @addtogroup STM32L1xx_System_Private_Functions
 | ||||||
|  |   * @{ | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  Setup the microcontroller system. | ||||||
|  |   *         Initialize the Embedded Flash Interface, the PLL and update the  | ||||||
|  |   *         SystemCoreClock variable. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void SystemInit (void) | ||||||
|  | { | ||||||
|  |   /*!< Set MSION bit */ | ||||||
|  |   RCC->CR |= (uint32_t)0x00000100; | ||||||
|  | 
 | ||||||
|  |   /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */ | ||||||
|  |   RCC->CFGR &= (uint32_t)0x88FFC00C; | ||||||
|  |    | ||||||
|  |   /*!< Reset HSION, HSEON, CSSON and PLLON bits */ | ||||||
|  |   RCC->CR &= (uint32_t)0xEEFEFFFE; | ||||||
|  | 
 | ||||||
|  |   /*!< Reset HSEBYP bit */ | ||||||
|  |   RCC->CR &= (uint32_t)0xFFFBFFFF; | ||||||
|  | 
 | ||||||
|  |   /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */ | ||||||
|  |   RCC->CFGR &= (uint32_t)0xFF02FFFF; | ||||||
|  | 
 | ||||||
|  |   /*!< Disable all interrupts */ | ||||||
|  |   RCC->CIR = 0x00000000; | ||||||
|  | 
 | ||||||
|  | #ifdef DATA_IN_ExtSRAM | ||||||
|  |   SystemInit_ExtMemCtl();  | ||||||
|  | #endif /* DATA_IN_ExtSRAM */ | ||||||
|  |      | ||||||
|  |   /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ | ||||||
|  |   SetSysClock(); | ||||||
|  | 
 | ||||||
|  | #ifdef VECT_TAB_SRAM | ||||||
|  |   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ | ||||||
|  | #else | ||||||
|  |   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  Update SystemCoreClock according to Clock Register Values | ||||||
|  |   *         The SystemCoreClock variable contains the core clock (HCLK), it can | ||||||
|  |   *         be used by the user application to setup the SysTick timer or configure | ||||||
|  |   *         other parameters. | ||||||
|  |   *            | ||||||
|  |   * @note   Each time the core clock (HCLK) changes, this function must be called | ||||||
|  |   *         to update SystemCoreClock variable value. Otherwise, any configuration | ||||||
|  |   *         based on this variable will be incorrect.          | ||||||
|  |   *      | ||||||
|  |   * @note   - The system frequency computed by this function is not the real  | ||||||
|  |   *           frequency in the chip. It is calculated based on the predefined  | ||||||
|  |   *           constant and the selected clock source: | ||||||
|  |   *              | ||||||
|  |   *           - If SYSCLK source is MSI, SystemCoreClock will contain the MSI  | ||||||
|  |   *             value as defined by the MSI range. | ||||||
|  |   *                                    | ||||||
|  |   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) | ||||||
|  |   *                                               | ||||||
|  |   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) | ||||||
|  |   *                           | ||||||
|  |   *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) | ||||||
|  |   *             or HSI_VALUE(*) multiplied/divided by the PLL factors. | ||||||
|  |   *          | ||||||
|  |   *         (*) HSI_VALUE is a constant defined in stm32l1xx.h file (default value | ||||||
|  |   *             16 MHz) but the real value may vary depending on the variations | ||||||
|  |   *             in voltage and temperature.    | ||||||
|  |   *     | ||||||
|  |   *         (**) HSE_VALUE is a constant defined in stm32l1xx.h file (default value | ||||||
|  |   *              8 MHz), user has to ensure that HSE_VALUE is same as the real | ||||||
|  |   *              frequency of the crystal used. Otherwise, this function may | ||||||
|  |   *              have wrong result. | ||||||
|  |   *                 | ||||||
|  |   *         - The result of this function could be not correct when using fractional | ||||||
|  |   *           value for HSE crystal. | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void SystemCoreClockUpdate (void) | ||||||
|  | { | ||||||
|  |   uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, msirange = 0; | ||||||
|  | 
 | ||||||
|  |   /* Get SYSCLK source -------------------------------------------------------*/ | ||||||
|  |   tmp = RCC->CFGR & RCC_CFGR_SWS; | ||||||
|  |    | ||||||
|  |   switch (tmp) | ||||||
|  |   { | ||||||
|  |     case 0x00:  /* MSI used as system clock */ | ||||||
|  |       msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13; | ||||||
|  |       SystemCoreClock = (32768 * (1 << (msirange + 1))); | ||||||
|  |       break; | ||||||
|  |     case 0x04:  /* HSI used as system clock */ | ||||||
|  |       SystemCoreClock = HSI_VALUE; | ||||||
|  |       break; | ||||||
|  |     case 0x08:  /* HSE used as system clock */ | ||||||
|  |       SystemCoreClock = HSE_VALUE; | ||||||
|  |       break; | ||||||
|  |     case 0x0C:  /* PLL used as system clock */ | ||||||
|  |       /* Get PLL clock source and multiplication factor ----------------------*/ | ||||||
|  |       pllmul = RCC->CFGR & RCC_CFGR_PLLMUL; | ||||||
|  |       plldiv = RCC->CFGR & RCC_CFGR_PLLDIV; | ||||||
|  |       pllmul = PLLMulTable[(pllmul >> 18)]; | ||||||
|  |       plldiv = (plldiv >> 22) + 1; | ||||||
|  |        | ||||||
|  |       pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; | ||||||
|  | 
 | ||||||
|  |       if (pllsource == 0x00) | ||||||
|  |       { | ||||||
|  |         /* HSI oscillator clock selected as PLL clock entry */ | ||||||
|  |         SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |         /* HSE selected as PLL clock entry */ | ||||||
|  |         SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv); | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |     default: /* MSI used as system clock */ | ||||||
|  |       msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> 13; | ||||||
|  |       SystemCoreClock = (32768 * (1 << (msirange + 1))); | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |   /* Compute HCLK clock frequency --------------------------------------------*/ | ||||||
|  |   /* Get HCLK prescaler */ | ||||||
|  |   tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; | ||||||
|  |   /* HCLK clock frequency */ | ||||||
|  |   SystemCoreClock >>= tmp; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief  Configures the System clock frequency, AHB/APBx prescalers and Flash  | ||||||
|  |   *         settings. | ||||||
|  |   * @note   This function should be called only once the RCC clock configuration   | ||||||
|  |   *         is reset to the default reset state (done in SystemInit() function). | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | static void SetSysClock(void) | ||||||
|  | { | ||||||
|  |   __IO uint32_t StartUpCounter = 0, HSEStatus = 0; | ||||||
|  |    | ||||||
|  |   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ | ||||||
|  |   /* Enable HSE */ | ||||||
|  |   RCC->CR |= ((uint32_t)RCC_CR_HSEON); | ||||||
|  |   | ||||||
|  |   /* Wait till HSE is ready and if Time out is reached exit */ | ||||||
|  |   do | ||||||
|  |   { | ||||||
|  |     HSEStatus = RCC->CR & RCC_CR_HSERDY; | ||||||
|  |     StartUpCounter++; | ||||||
|  |   } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); | ||||||
|  | 
 | ||||||
|  |   if ((RCC->CR & RCC_CR_HSERDY) != RESET) | ||||||
|  |   { | ||||||
|  |     HSEStatus = (uint32_t)0x01; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     HSEStatus = (uint32_t)0x00; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   if (HSEStatus == (uint32_t)0x01) | ||||||
|  |   { | ||||||
|  |     /* Enable 64-bit access */ | ||||||
|  |     FLASH->ACR |= FLASH_ACR_ACC64; | ||||||
|  |      | ||||||
|  |     /* Enable Prefetch Buffer */ | ||||||
|  |     FLASH->ACR |= FLASH_ACR_PRFTEN; | ||||||
|  | 
 | ||||||
|  |     /* Flash 1 wait state */ | ||||||
|  |     FLASH->ACR |= FLASH_ACR_LATENCY; | ||||||
|  |      | ||||||
|  |     /* Power enable */ | ||||||
|  |     RCC->APB1ENR |= RCC_APB1ENR_PWREN; | ||||||
|  |    | ||||||
|  |     /* Select the Voltage Range 1 (1.8 V) */ | ||||||
|  |     PWR->CR = PWR_CR_VOS_0; | ||||||
|  |    | ||||||
|  |     /* Wait Until the Voltage Regulator is ready */ | ||||||
|  |     while((PWR->CSR & PWR_CSR_VOSF) != RESET) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |          | ||||||
|  |     /* HCLK = SYSCLK /1*/ | ||||||
|  |     RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; | ||||||
|  |    | ||||||
|  |     /* PCLK2 = HCLK /1*/ | ||||||
|  |     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; | ||||||
|  |      | ||||||
|  |     /* PCLK1 = HCLK /1*/ | ||||||
|  |     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; | ||||||
|  |      | ||||||
|  |     /*  PLL configuration */ | ||||||
|  |     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL | | ||||||
|  |                                         RCC_CFGR_PLLDIV)); | ||||||
|  |     RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL12 | RCC_CFGR_PLLDIV3); | ||||||
|  | 
 | ||||||
|  |     /* Enable PLL */ | ||||||
|  |     RCC->CR |= RCC_CR_PLLON; | ||||||
|  | 
 | ||||||
|  |     /* Wait till PLL is ready */ | ||||||
|  |     while((RCC->CR & RCC_CR_PLLRDY) == 0) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |          | ||||||
|  |     /* Select PLL as system clock source */ | ||||||
|  |     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); | ||||||
|  |     RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; | ||||||
|  | 
 | ||||||
|  |     /* Wait till PLL is used as system clock source */ | ||||||
|  |     while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     /* If HSE fails to start-up, the application will have wrong clock
 | ||||||
|  |        configuration. User can add here some code to deal with this error */ | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef DATA_IN_ExtSRAM | ||||||
|  | /**
 | ||||||
|  |   * @brief  Setup the external memory controller. | ||||||
|  |   *         Called in SystemInit() function before jump to main. | ||||||
|  |   *         This function configures the external SRAM mounted on STM32L152D_EVAL board | ||||||
|  |   *         This SRAM will be used as program data memory (including heap and stack). | ||||||
|  |   * @param  None | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  | void SystemInit_ExtMemCtl(void) | ||||||
|  | { | ||||||
|  | /*-- GPIOs Configuration -----------------------------------------------------*/ | ||||||
|  | /*
 | ||||||
|  |  +-------------------+--------------------+------------------+------------------+ | ||||||
|  |  +                       SRAM pins assignment                                   + | ||||||
|  |  +-------------------+--------------------+------------------+------------------+ | ||||||
|  |  | PD0  <-> FSMC_D2  | PE0  <-> FSMC_NBL0 | PF0  <-> FSMC_A0 | PG0 <-> FSMC_A10 | | ||||||
|  |  | PD1  <-> FSMC_D3  | PE1  <-> FSMC_NBL1 | PF1  <-> FSMC_A1 | PG1 <-> FSMC_A11 | | ||||||
|  |  | PD4  <-> FSMC_NOE | PE7  <-> FSMC_D4   | PF2  <-> FSMC_A2 | PG2 <-> FSMC_A12 | | ||||||
|  |  | PD5  <-> FSMC_NWE | PE8  <-> FSMC_D5   | PF3  <-> FSMC_A3 | PG3 <-> FSMC_A13 | | ||||||
|  |  | PD8  <-> FSMC_D13 | PE9  <-> FSMC_D6   | PF4  <-> FSMC_A4 | PG4 <-> FSMC_A14 | | ||||||
|  |  | PD9  <-> FSMC_D14 | PE10 <-> FSMC_D7   | PF5  <-> FSMC_A5 | PG5 <-> FSMC_A15 | | ||||||
|  |  | PD10 <-> FSMC_D15 | PE11 <-> FSMC_D8   | PF12 <-> FSMC_A6 | PG10<-> FSMC_NE2 | | ||||||
|  |  | PD11 <-> FSMC_A16 | PE12 <-> FSMC_D9   | PF13 <-> FSMC_A7 |------------------+ | ||||||
|  |  | PD12 <-> FSMC_A17 | PE13 <-> FSMC_D10  | PF14 <-> FSMC_A8 |  | ||||||
|  |  | PD13 <-> FSMC_A18 | PE14 <-> FSMC_D11  | PF15 <-> FSMC_A9 |  | ||||||
|  |  | PD14 <-> FSMC_D0  | PE15 <-> FSMC_D12  |------------------+ | ||||||
|  |  | PD15 <-> FSMC_D1  |--------------------+  | ||||||
|  |  +-------------------+ | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  |   /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ | ||||||
|  |   RCC->AHBENR   = 0x000080D8; | ||||||
|  |    | ||||||
|  |   /* Connect PDx pins to FSMC Alternate function */ | ||||||
|  |   GPIOD->AFR[0]  = 0x00CC00CC; | ||||||
|  |   GPIOD->AFR[1]  = 0xCCCCCCCC; | ||||||
|  |   /* Configure PDx pins in Alternate function mode */   | ||||||
|  |   GPIOD->MODER   = 0xAAAA0A0A; | ||||||
|  |   /* Configure PDx pins speed to 40 MHz */   | ||||||
|  |   GPIOD->OSPEEDR = 0xFFFF0F0F; | ||||||
|  |   /* Configure PDx pins Output type to push-pull */   | ||||||
|  |   GPIOD->OTYPER  = 0x00000000; | ||||||
|  |   /* No pull-up, pull-down for PDx pins */  | ||||||
|  |   GPIOD->PUPDR   = 0x00000000; | ||||||
|  | 
 | ||||||
|  |   /* Connect PEx pins to FSMC Alternate function */ | ||||||
|  |   GPIOE->AFR[0]  = 0xC00000CC; | ||||||
|  |   GPIOE->AFR[1]  = 0xCCCCCCCC; | ||||||
|  |   /* Configure PEx pins in Alternate function mode */  | ||||||
|  |   GPIOE->MODER   = 0xAAAA800A; | ||||||
|  |   /* Configure PEx pins speed to 40 MHz */  | ||||||
|  |   GPIOE->OSPEEDR = 0xFFFFC00F; | ||||||
|  |   /* Configure PEx pins Output type to push-pull */   | ||||||
|  |   GPIOE->OTYPER  = 0x00000000; | ||||||
|  |   /* No pull-up, pull-down for PEx pins */  | ||||||
|  |   GPIOE->PUPDR   = 0x00000000; | ||||||
|  | 
 | ||||||
|  |   /* Connect PFx pins to FSMC Alternate function */ | ||||||
|  |   GPIOF->AFR[0]  = 0x00CCCCCC; | ||||||
|  |   GPIOF->AFR[1]  = 0xCCCC0000; | ||||||
|  |   /* Configure PFx pins in Alternate function mode */    | ||||||
|  |   GPIOF->MODER   = 0xAA000AAA; | ||||||
|  |   /* Configure PFx pins speed to 40 MHz */  | ||||||
|  |   GPIOF->OSPEEDR = 0xFF000FFF; | ||||||
|  |   /* Configure PFx pins Output type to push-pull */   | ||||||
|  |   GPIOF->OTYPER  = 0x00000000; | ||||||
|  |   /* No pull-up, pull-down for PFx pins */  | ||||||
|  |   GPIOF->PUPDR   = 0x00000000; | ||||||
|  | 
 | ||||||
|  |   /* Connect PGx pins to FSMC Alternate function */ | ||||||
|  |   GPIOG->AFR[0]  = 0x00CCCCCC; | ||||||
|  |   GPIOG->AFR[1]  = 0x00000C00; | ||||||
|  |   /* Configure PGx pins in Alternate function mode */  | ||||||
|  |   GPIOG->MODER   = 0x00200AAA; | ||||||
|  |   /* Configure PGx pins speed to 40 MHz */  | ||||||
|  |   GPIOG->OSPEEDR = 0x00300FFF; | ||||||
|  |   /* Configure PGx pins Output type to push-pull */   | ||||||
|  |   GPIOG->OTYPER  = 0x00000000; | ||||||
|  |   /* No pull-up, pull-down for PGx pins */  | ||||||
|  |   GPIOG->PUPDR   = 0x00000000; | ||||||
|  |    | ||||||
|  | /*-- FSMC Configuration ------------------------------------------------------*/ | ||||||
|  |   /* Enable the FSMC interface clock */ | ||||||
|  |   RCC->AHBENR    = 0x400080D8; | ||||||
|  | 
 | ||||||
|  |   /* Configure and enable Bank1_SRAM3 */ | ||||||
|  |   FSMC_Bank1->BTCR[4]  = 0x00001011; | ||||||
|  |   FSMC_Bank1->BTCR[5]  = 0x00000300; | ||||||
|  |   FSMC_Bank1E->BWTR[4] = 0x0FFFFFFF; | ||||||
|  | /*
 | ||||||
|  |   Bank1_SRAM3 is configured as follow: | ||||||
|  | 
 | ||||||
|  |   p.FSMC_AddressSetupTime = 0; | ||||||
|  |   p.FSMC_AddressHoldTime = 0; | ||||||
|  |   p.FSMC_DataSetupTime = 3; | ||||||
|  |   p.FSMC_BusTurnAroundDuration = 0; | ||||||
|  |   p.FSMC_CLKDivision = 0; | ||||||
|  |   p.FSMC_DataLatency = 0; | ||||||
|  |   p.FSMC_AccessMode = FSMC_AccessMode_A; | ||||||
|  | 
 | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; | ||||||
|  |   FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; | ||||||
|  | 
 | ||||||
|  |   FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);  | ||||||
|  | 
 | ||||||
|  |   FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); | ||||||
|  | */ | ||||||
|  |    | ||||||
|  | } | ||||||
|  | #endif /* DATA_IN_ExtSRAM */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @} | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
							
								
								
									
										1033
									
								
								fw_dc22_stm32l100/src/usb/core/usb_core.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1033
									
								
								fw_dc22_stm32l100/src/usb/core/usb_core.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										259
									
								
								fw_dc22_stm32l100/src/usb/core/usb_core.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								fw_dc22_stm32l100/src/usb/core/usb_core.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,259 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_core.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Standard protocol processing functions prototypes | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_CORE_H | ||||||
|  | #define __USB_CORE_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | typedef enum _CONTROL_STATE | ||||||
|  | { | ||||||
|  |   WAIT_SETUP,       /* 0 */ | ||||||
|  |   SETTING_UP,       /* 1 */ | ||||||
|  |   IN_DATA,          /* 2 */ | ||||||
|  |   OUT_DATA,         /* 3 */ | ||||||
|  |   LAST_IN_DATA,     /* 4 */ | ||||||
|  |   LAST_OUT_DATA,    /* 5 */ | ||||||
|  |   WAIT_STATUS_IN,   /* 7 */ | ||||||
|  |   WAIT_STATUS_OUT,  /* 8 */ | ||||||
|  |   STALLED,          /* 9 */ | ||||||
|  |   PAUSE             /* 10 */ | ||||||
|  | } CONTROL_STATE;    /* The state machine states of a control pipe */ | ||||||
|  | 
 | ||||||
|  | typedef struct OneDescriptor | ||||||
|  | { | ||||||
|  |   uint8_t *Descriptor; | ||||||
|  |   uint16_t Descriptor_Size; | ||||||
|  | } | ||||||
|  | ONE_DESCRIPTOR, *PONE_DESCRIPTOR; | ||||||
|  | /* All the request process routines return a value of this type
 | ||||||
|  |    If the return value is not SUCCESS or NOT_READY, | ||||||
|  |    the software will STALL the correspond endpoint */ | ||||||
|  | typedef enum _RESULT | ||||||
|  | { | ||||||
|  |   USB_SUCCESS = 0,    /* Process successfully */ | ||||||
|  |   USB_ERROR, | ||||||
|  |   USB_UNSUPPORT, | ||||||
|  |   USB_NOT_READY       /* The process has not been finished, endpoint will be
 | ||||||
|  |                          NAK to further request */ | ||||||
|  | } RESULT; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/ | ||||||
|  | typedef struct _ENDPOINT_INFO | ||||||
|  | { | ||||||
|  |   /* When send data out of the device,
 | ||||||
|  |    CopyData() is used to get data buffer 'Length' bytes data | ||||||
|  |    if Length is 0, | ||||||
|  |     CopyData() returns the total length of the data | ||||||
|  |     if the request is not supported, returns 0 | ||||||
|  |     (NEW Feature ) | ||||||
|  |      if CopyData() returns -1, the calling routine should not proceed | ||||||
|  |      further and will resume the SETUP process by the class device | ||||||
|  |    if Length is not 0, | ||||||
|  |     CopyData() returns a pointer to indicate the data location | ||||||
|  |    Usb_wLength is the data remain to be sent, | ||||||
|  |    Usb_wOffset is the Offset of original data | ||||||
|  |   When receive data from the host, | ||||||
|  |    CopyData() is used to get user data buffer which is capable | ||||||
|  |    of Length bytes data to copy data from the endpoint buffer. | ||||||
|  |    if Length is 0, | ||||||
|  |     CopyData() returns the available data length, | ||||||
|  |    if Length is not 0, | ||||||
|  |     CopyData() returns user buffer address | ||||||
|  |    Usb_rLength is the data remain to be received, | ||||||
|  |    Usb_rPointer is the Offset of data buffer | ||||||
|  |   */ | ||||||
|  |   uint16_t  Usb_wLength; | ||||||
|  |   uint16_t  Usb_wOffset; | ||||||
|  |   uint16_t  PacketSize; | ||||||
|  |   uint8_t   *(*CopyData)(uint16_t Length); | ||||||
|  | }ENDPOINT_INFO; | ||||||
|  | 
 | ||||||
|  | /*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/ | ||||||
|  | 
 | ||||||
|  | typedef struct _DEVICE | ||||||
|  | { | ||||||
|  |   uint8_t Total_Endpoint;     /* Number of endpoints that are used */ | ||||||
|  |   uint8_t Total_Configuration;/* Number of configuration available */ | ||||||
|  | } | ||||||
|  | DEVICE; | ||||||
|  | 
 | ||||||
|  | typedef union | ||||||
|  | { | ||||||
|  |   uint16_t w; | ||||||
|  |   struct BW | ||||||
|  |   { | ||||||
|  |     uint8_t bb1; | ||||||
|  |     uint8_t bb0; | ||||||
|  |   } | ||||||
|  |   bw; | ||||||
|  | } uint16_t_uint8_t; | ||||||
|  | 
 | ||||||
|  | typedef struct _DEVICE_INFO | ||||||
|  | { | ||||||
|  |   uint8_t USBbmRequestType;       /* bmRequestType */ | ||||||
|  |   uint8_t USBbRequest;            /* bRequest */ | ||||||
|  |   uint16_t_uint8_t USBwValues;         /* wValue */ | ||||||
|  |   uint16_t_uint8_t USBwIndexs;         /* wIndex */ | ||||||
|  |   uint16_t_uint8_t USBwLengths;        /* wLength */ | ||||||
|  | 
 | ||||||
|  |   uint8_t ControlState;           /* of type CONTROL_STATE */ | ||||||
|  |   uint8_t Current_Feature; | ||||||
|  |   uint8_t Current_Configuration;   /* Selected configuration */ | ||||||
|  |   uint8_t Current_Interface;       /* Selected interface of current configuration */ | ||||||
|  |   uint8_t Current_AlternateSetting;/* Selected Alternate Setting of current
 | ||||||
|  |                                      interface*/ | ||||||
|  | 
 | ||||||
|  |   ENDPOINT_INFO Ctrl_Info; | ||||||
|  | }DEVICE_INFO; | ||||||
|  | 
 | ||||||
|  | typedef struct _DEVICE_PROP | ||||||
|  | { | ||||||
|  |   void (*Init)(void);        /* Initialize the device */ | ||||||
|  |   void (*Reset)(void);       /* Reset routine of this device */ | ||||||
|  | 
 | ||||||
|  |   /* Device dependent process after the status stage */ | ||||||
|  |   void (*Process_Status_IN)(void); | ||||||
|  |   void (*Process_Status_OUT)(void); | ||||||
|  | 
 | ||||||
|  |   /* Procedure of process on setup stage of a class specified request with data stage */ | ||||||
|  |   /* All class specified requests with data stage are processed in Class_Data_Setup
 | ||||||
|  |    Class_Data_Setup() | ||||||
|  |     responses to check all special requests and fills ENDPOINT_INFO | ||||||
|  |     according to the request | ||||||
|  |     If IN tokens are expected, then wLength & wOffset will be filled | ||||||
|  |     with the total transferring bytes and the starting position | ||||||
|  |     If OUT tokens are expected, then rLength & rOffset will be filled | ||||||
|  |     with the total expected bytes and the starting position in the buffer | ||||||
|  | 
 | ||||||
|  |     If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT | ||||||
|  | 
 | ||||||
|  |    CAUTION: | ||||||
|  |     Since GET_CONFIGURATION & GET_INTERFACE are highly related to | ||||||
|  |     the individual classes, they will be checked and processed here. | ||||||
|  |   */ | ||||||
|  |   RESULT (*Class_Data_Setup)(uint8_t RequestNo); | ||||||
|  | 
 | ||||||
|  |   /* Procedure of process on setup stage of a class specified request without data stage */ | ||||||
|  |   /* All class specified requests without data stage are processed in Class_NoData_Setup
 | ||||||
|  |    Class_NoData_Setup | ||||||
|  |     responses to check all special requests and perform the request | ||||||
|  | 
 | ||||||
|  |    CAUTION: | ||||||
|  |     Since SET_CONFIGURATION & SET_INTERFACE are highly related to | ||||||
|  |     the individual classes, they will be checked and processed here. | ||||||
|  |   */ | ||||||
|  |   RESULT (*Class_NoData_Setup)(uint8_t RequestNo); | ||||||
|  | 
 | ||||||
|  |   /*Class_Get_Interface_Setting
 | ||||||
|  |    This function is used by the file usb_core.c to test if the selected Interface | ||||||
|  |    and Alternate Setting (uint8_t Interface, uint8_t AlternateSetting) are supported by | ||||||
|  |    the application. | ||||||
|  |    This function is writing by user. It should return "SUCCESS" if the Interface | ||||||
|  |    and Alternate Setting are supported by the application or "UNSUPPORT" if they | ||||||
|  |    are not supported. */ | ||||||
|  | 
 | ||||||
|  |   RESULT  (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting); | ||||||
|  | 
 | ||||||
|  |   uint8_t* (*GetDeviceDescriptor)(uint16_t Length); | ||||||
|  |   uint8_t* (*GetConfigDescriptor)(uint16_t Length); | ||||||
|  |   uint8_t* (*GetStringDescriptor)(uint16_t Length); | ||||||
|  | 
 | ||||||
|  |   /* This field is not used in current library version. It is kept only for 
 | ||||||
|  |    compatibility with previous versions */ | ||||||
|  |   void* RxEP_buffer; | ||||||
|  |     | ||||||
|  |   uint8_t MaxPacketSize; | ||||||
|  | 
 | ||||||
|  | }DEVICE_PROP; | ||||||
|  | 
 | ||||||
|  | typedef struct _USER_STANDARD_REQUESTS | ||||||
|  | { | ||||||
|  |   void (*User_GetConfiguration)(void);       /* Get Configuration */ | ||||||
|  |   void (*User_SetConfiguration)(void);       /* Set Configuration */ | ||||||
|  |   void (*User_GetInterface)(void);           /* Get Interface */ | ||||||
|  |   void (*User_SetInterface)(void);           /* Set Interface */ | ||||||
|  |   void (*User_GetStatus)(void);              /* Get Status */ | ||||||
|  |   void (*User_ClearFeature)(void);           /* Clear Feature */ | ||||||
|  |   void (*User_SetEndPointFeature)(void);     /* Set Endpoint Feature */ | ||||||
|  |   void (*User_SetDeviceFeature)(void);       /* Set Device Feature */ | ||||||
|  |   void (*User_SetDeviceAddress)(void);       /* Set Device Address */ | ||||||
|  | } | ||||||
|  | USER_STANDARD_REQUESTS; | ||||||
|  | 
 | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | #define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) | ||||||
|  | 
 | ||||||
|  | #define Usb_rLength Usb_wLength | ||||||
|  | #define Usb_rOffset Usb_wOffset | ||||||
|  | 
 | ||||||
|  | #define USBwValue USBwValues.w | ||||||
|  | #define USBwValue0 USBwValues.bw.bb0 | ||||||
|  | #define USBwValue1 USBwValues.bw.bb1 | ||||||
|  | #define USBwIndex USBwIndexs.w | ||||||
|  | #define USBwIndex0 USBwIndexs.bw.bb0 | ||||||
|  | #define USBwIndex1 USBwIndexs.bw.bb1 | ||||||
|  | #define USBwLength USBwLengths.w | ||||||
|  | #define USBwLength0 USBwLengths.bw.bb0 | ||||||
|  | #define USBwLength1 USBwLengths.bw.bb1 | ||||||
|  | 
 | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | uint8_t Setup0_Process(void); | ||||||
|  | uint8_t Post0_Process(void); | ||||||
|  | uint8_t Out0_Process(void); | ||||||
|  | uint8_t In0_Process(void); | ||||||
|  | 
 | ||||||
|  | RESULT Standard_SetEndPointFeature(void); | ||||||
|  | RESULT Standard_SetDeviceFeature(void); | ||||||
|  | 
 | ||||||
|  | uint8_t *Standard_GetConfiguration(uint16_t Length); | ||||||
|  | RESULT Standard_SetConfiguration(void); | ||||||
|  | uint8_t *Standard_GetInterface(uint16_t Length); | ||||||
|  | RESULT Standard_SetInterface(void); | ||||||
|  | uint8_t *Standard_GetDescriptorData(uint16_t Length, PONE_DESCRIPTOR pDesc); | ||||||
|  | 
 | ||||||
|  | uint8_t *Standard_GetStatus(uint16_t Length); | ||||||
|  | RESULT Standard_ClearFeature(void); | ||||||
|  | void SetDeviceAddress(uint8_t); | ||||||
|  | void NOP_Process(void); | ||||||
|  | 
 | ||||||
|  | extern DEVICE_PROP Device_Property; | ||||||
|  | extern  USER_STANDARD_REQUESTS User_Standard_Requests; | ||||||
|  | extern  DEVICE  Device_Table; | ||||||
|  | extern DEVICE_INFO Device_Info; | ||||||
|  | 
 | ||||||
|  | /* cells saving status during interrupt servicing */ | ||||||
|  | extern __IO uint16_t SaveRState; | ||||||
|  | extern __IO uint16_t SaveTState; | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_CORE_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										92
									
								
								fw_dc22_stm32l100/src/usb/core/usb_def.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								fw_dc22_stm32l100/src/usb/core/usb_def.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,92 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_def.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Definitions related to USB Core | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_DEF_H | ||||||
|  | #define __USB_DEF_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | typedef enum _RECIPIENT_TYPE | ||||||
|  | { | ||||||
|  |   DEVICE_RECIPIENT,     /* Recipient device */ | ||||||
|  |   INTERFACE_RECIPIENT,  /* Recipient interface */ | ||||||
|  |   ENDPOINT_RECIPIENT,   /* Recipient endpoint */ | ||||||
|  |   OTHER_RECIPIENT | ||||||
|  | } RECIPIENT_TYPE; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | typedef enum _STANDARD_REQUESTS | ||||||
|  | { | ||||||
|  |   GET_STATUS = 0, | ||||||
|  |   CLEAR_FEATURE, | ||||||
|  |   RESERVED1, | ||||||
|  |   SET_FEATURE, | ||||||
|  |   RESERVED2, | ||||||
|  |   SET_ADDRESS, | ||||||
|  |   GET_DESCRIPTOR, | ||||||
|  |   SET_DESCRIPTOR, | ||||||
|  |   GET_CONFIGURATION, | ||||||
|  |   SET_CONFIGURATION, | ||||||
|  |   GET_INTERFACE, | ||||||
|  |   SET_INTERFACE, | ||||||
|  |   TOTAL_sREQUEST,  /* Total number of Standard request */ | ||||||
|  |   SYNCH_FRAME = 12 | ||||||
|  | } STANDARD_REQUESTS; | ||||||
|  | 
 | ||||||
|  | /* Definition of "USBwValue" */ | ||||||
|  | typedef enum _DESCRIPTOR_TYPE | ||||||
|  | { | ||||||
|  |   DEVICE_DESCRIPTOR = 1, | ||||||
|  |   CONFIG_DESCRIPTOR, | ||||||
|  |   STRING_DESCRIPTOR, | ||||||
|  |   INTERFACE_DESCRIPTOR, | ||||||
|  |   ENDPOINT_DESCRIPTOR | ||||||
|  | } DESCRIPTOR_TYPE; | ||||||
|  | 
 | ||||||
|  | /* Feature selector of a SET_FEATURE or CLEAR_FEATURE */ | ||||||
|  | typedef enum _FEATURE_SELECTOR | ||||||
|  | { | ||||||
|  |   ENDPOINT_STALL, | ||||||
|  |   DEVICE_REMOTE_WAKEUP | ||||||
|  | } FEATURE_SELECTOR; | ||||||
|  | 
 | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Definition of "USBbmRequestType" */ | ||||||
|  | #define REQUEST_TYPE      0x60  /* Mask to get request type */ | ||||||
|  | #define STANDARD_REQUEST  0x00  /* Standard request */ | ||||||
|  | #define CLASS_REQUEST     0x20  /* Class request */ | ||||||
|  | #define VENDOR_REQUEST    0x40  /* Vendor request */ | ||||||
|  | 
 | ||||||
|  | #define RECIPIENT         0x1F  /* Mask to get recipient */ | ||||||
|  | 
 | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_DEF_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										76
									
								
								fw_dc22_stm32l100/src/usb/core/usb_init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								fw_dc22_stm32l100/src/usb/core/usb_init.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_init.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Initialization routines & global variables | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "usb_lib.h" | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | /*  The number of current endpoint, it will be used to specify an endpoint */ | ||||||
|  |  uint8_t	EPindex; | ||||||
|  | /*  The number of current device, it is an index to the Device_Table */ | ||||||
|  | /* uint8_t	Device_no; */ | ||||||
|  | /*  Points to the DEVICE_INFO structure of current device */ | ||||||
|  | /*  The purpose of this register is to speed up the execution */ | ||||||
|  | DEVICE_INFO *pInformation; | ||||||
|  | /*  Points to the DEVICE_PROP structure of current device */ | ||||||
|  | /*  The purpose of this register is to speed up the execution */ | ||||||
|  | DEVICE_PROP *pProperty; | ||||||
|  | /*  Temporary save the state of Rx & Tx status. */ | ||||||
|  | /*  Whenever the Rx or Tx state is changed, its value is saved */ | ||||||
|  | /*  in this variable first and will be set to the EPRB or EPRA */ | ||||||
|  | /*  at the end of interrupt process */ | ||||||
|  | uint16_t	SaveState ; | ||||||
|  | uint16_t  wInterrupt_Mask; | ||||||
|  | DEVICE_INFO	Device_Info; | ||||||
|  | USER_STANDARD_REQUESTS  *pUser_Standard_Requests; | ||||||
|  | 
 | ||||||
|  | /* Extern variables ----------------------------------------------------------*/ | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_Init | ||||||
|  | * Description    : USB system initialization | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USB_Init(void) | ||||||
|  | { | ||||||
|  |   pInformation = &Device_Info; | ||||||
|  |   pInformation->ControlState = 2; | ||||||
|  |   pProperty = &Device_Property; | ||||||
|  |   pUser_Standard_Requests = &User_Standard_Requests; | ||||||
|  |   /* Initialize devices one by one */ | ||||||
|  |   pProperty->Init(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										62
									
								
								fw_dc22_stm32l100/src/usb/core/usb_init.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								fw_dc22_stm32l100/src/usb/core/usb_init.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_init.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Initialization routines & global variables | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_INIT_H | ||||||
|  | #define __USB_INIT_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | void USB_Init(void); | ||||||
|  | 
 | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | /*  The number of current endpoint, it will be used to specify an endpoint */ | ||||||
|  | extern uint8_t	EPindex; | ||||||
|  | /*  The number of current device, it is an index to the Device_Table */ | ||||||
|  | /*extern uint8_t	Device_no; */ | ||||||
|  | /*  Points to the DEVICE_INFO structure of current device */ | ||||||
|  | /*  The purpose of this register is to speed up the execution */ | ||||||
|  | extern DEVICE_INFO*	pInformation; | ||||||
|  | /*  Points to the DEVICE_PROP structure of current device */ | ||||||
|  | /*  The purpose of this register is to speed up the execution */ | ||||||
|  | extern DEVICE_PROP*	pProperty; | ||||||
|  | /*  Temporary save the state of Rx & Tx status. */ | ||||||
|  | /*  Whenever the Rx or Tx state is changed, its value is saved */ | ||||||
|  | /*  in this variable first and will be set to the EPRB or EPRA */ | ||||||
|  | /*  at the end of interrupt process */ | ||||||
|  | extern USER_STANDARD_REQUESTS *pUser_Standard_Requests; | ||||||
|  | 
 | ||||||
|  | extern uint16_t	SaveState ; | ||||||
|  | extern uint16_t wInterrupt_Mask; | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_INIT_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										195
									
								
								fw_dc22_stm32l100/src/usb/core/usb_int.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								fw_dc22_stm32l100/src/usb/core/usb_int.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,195 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_int.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Endpoint CTR (Low and High) interrupt's service routines | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "usb_lib.h" | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | __IO uint16_t SaveRState; | ||||||
|  | __IO uint16_t SaveTState; | ||||||
|  | 
 | ||||||
|  | /* Extern variables ----------------------------------------------------------*/ | ||||||
|  | extern void (*pEpInt_IN[7])(void);    /*  Handles IN  interrupts   */ | ||||||
|  | extern void (*pEpInt_OUT[7])(void);   /*  Handles OUT interrupts   */ | ||||||
|  | 
 | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : CTR_LP. | ||||||
|  | * Description    : Low priority Endpoint Correct Transfer interrupt's service | ||||||
|  | *                  routine. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void CTR_LP(void) | ||||||
|  | { | ||||||
|  |   __IO uint16_t wEPVal = 0; | ||||||
|  |   /* stay in loop while pending interrupts */ | ||||||
|  |   while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) | ||||||
|  |   { | ||||||
|  |     /* extract highest priority endpoint number */ | ||||||
|  |     EPindex = (uint8_t)(wIstr & ISTR_EP_ID); | ||||||
|  |     if (EPindex == 0) | ||||||
|  |     { | ||||||
|  |       /* Decode and service control endpoint interrupt */ | ||||||
|  |       /* calling related service routine */ | ||||||
|  |       /* (Setup0_Process, In0_Process, Out0_Process) */ | ||||||
|  | 
 | ||||||
|  |       /* save RX & TX status */ | ||||||
|  |       /* and set both to NAK */ | ||||||
|  |        | ||||||
|  | 	    SaveRState = _GetENDPOINT(ENDP0); | ||||||
|  | 	    SaveTState = SaveRState & EPTX_STAT; | ||||||
|  | 	    SaveRState &=  EPRX_STAT;	 | ||||||
|  | 
 | ||||||
|  | 	    _SetEPRxTxStatus(ENDP0,EP_RX_NAK,EP_TX_NAK); | ||||||
|  | 
 | ||||||
|  |       /* DIR bit = origin of the interrupt */ | ||||||
|  | 
 | ||||||
|  |       if ((wIstr & ISTR_DIR) == 0) | ||||||
|  |       { | ||||||
|  |         /* DIR = 0 */ | ||||||
|  | 
 | ||||||
|  |         /* DIR = 0      => IN  int */ | ||||||
|  |         /* DIR = 0 implies that (EP_CTR_TX = 1) always  */ | ||||||
|  | 
 | ||||||
|  |         _ClearEP_CTR_TX(ENDP0); | ||||||
|  |         In0_Process(); | ||||||
|  | 
 | ||||||
|  |            /* before terminate set Tx & Rx status */ | ||||||
|  | 
 | ||||||
|  |             _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState); | ||||||
|  | 		  return; | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |         /* DIR = 1 */ | ||||||
|  | 
 | ||||||
|  |         /* DIR = 1 & CTR_RX       => SETUP or OUT int */ | ||||||
|  |         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ | ||||||
|  | 
 | ||||||
|  |         wEPVal = _GetENDPOINT(ENDP0); | ||||||
|  |          | ||||||
|  |         if ((wEPVal &EP_SETUP) != 0) | ||||||
|  |         { | ||||||
|  |           _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */ | ||||||
|  |           Setup0_Process(); | ||||||
|  |           /* before terminate set Tx & Rx status */ | ||||||
|  | 
 | ||||||
|  | 		      _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         else if ((wEPVal & EP_CTR_RX) != 0) | ||||||
|  |         { | ||||||
|  |           _ClearEP_CTR_RX(ENDP0); | ||||||
|  |           Out0_Process(); | ||||||
|  |           /* before terminate set Tx & Rx status */ | ||||||
|  |       | ||||||
|  | 		     _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }/* if(EPindex == 0) */ | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       /* Decode and service non control endpoints interrupt  */ | ||||||
|  | 
 | ||||||
|  |       /* process related endpoint register */ | ||||||
|  |       wEPVal = _GetENDPOINT(EPindex); | ||||||
|  |       if ((wEPVal & EP_CTR_RX) != 0) | ||||||
|  |       { | ||||||
|  |         /* clear int flag */ | ||||||
|  |         _ClearEP_CTR_RX(EPindex); | ||||||
|  | 
 | ||||||
|  |         /* call OUT service function */ | ||||||
|  |         (*pEpInt_OUT[EPindex-1])(); | ||||||
|  | 
 | ||||||
|  |       } /* if((wEPVal & EP_CTR_RX) */ | ||||||
|  | 
 | ||||||
|  |       if ((wEPVal & EP_CTR_TX) != 0) | ||||||
|  |       { | ||||||
|  |         /* clear int flag */ | ||||||
|  |         _ClearEP_CTR_TX(EPindex); | ||||||
|  | 
 | ||||||
|  |         /* call IN service function */ | ||||||
|  |         (*pEpInt_IN[EPindex-1])(); | ||||||
|  |       } /* if((wEPVal & EP_CTR_TX) != 0) */ | ||||||
|  | 
 | ||||||
|  |     }/* if(EPindex == 0) else */ | ||||||
|  | 
 | ||||||
|  |   }/* while(...) */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : CTR_HP. | ||||||
|  | * Description    : High Priority Endpoint Correct Transfer interrupt's service  | ||||||
|  | *                  routine. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void CTR_HP(void) | ||||||
|  | { | ||||||
|  |   uint32_t wEPVal = 0; | ||||||
|  | 
 | ||||||
|  |   while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) | ||||||
|  |   { | ||||||
|  |     _SetISTR((uint16_t)CLR_CTR); /* clear CTR flag */ | ||||||
|  |     /* extract highest priority endpoint number */ | ||||||
|  |     EPindex = (uint8_t)(wIstr & ISTR_EP_ID); | ||||||
|  |     /* process related endpoint register */ | ||||||
|  |     wEPVal = _GetENDPOINT(EPindex); | ||||||
|  |     if ((wEPVal & EP_CTR_RX) != 0) | ||||||
|  |     { | ||||||
|  |       /* clear int flag */ | ||||||
|  |       _ClearEP_CTR_RX(EPindex); | ||||||
|  | 
 | ||||||
|  |       /* call OUT service function */ | ||||||
|  |       (*pEpInt_OUT[EPindex-1])(); | ||||||
|  | 
 | ||||||
|  |     } /* if((wEPVal & EP_CTR_RX) */ | ||||||
|  |     else if ((wEPVal & EP_CTR_TX) != 0) | ||||||
|  |     { | ||||||
|  |       /* clear int flag */ | ||||||
|  |       _ClearEP_CTR_TX(EPindex); | ||||||
|  | 
 | ||||||
|  |       /* call IN service function */ | ||||||
|  |       (*pEpInt_IN[EPindex-1])(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } /* if((wEPVal & EP_CTR_TX) != 0) */ | ||||||
|  | 
 | ||||||
|  |   }/* while(...) */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										45
									
								
								fw_dc22_stm32l100/src/usb/core/usb_int.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								fw_dc22_stm32l100/src/usb/core/usb_int.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_int.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Endpoint CTR (Low and High) interrupt's service routines prototypes | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_INT_H | ||||||
|  | #define __USB_INT_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | void CTR_LP(void); | ||||||
|  | void CTR_HP(void); | ||||||
|  | 
 | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_INT_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										53
									
								
								fw_dc22_stm32l100/src/usb/core/usb_lib.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								fw_dc22_stm32l100/src/usb/core/usb_lib.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_lib.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   USB library include files | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_LIB_H | ||||||
|  | #define __USB_LIB_H | ||||||
|  | 
 | ||||||
|  | #include <pirate.h> | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "usb_type.h" | ||||||
|  | #include "usb_regs.h" | ||||||
|  | #include "usb_def.h" | ||||||
|  | #include "usb_core.h" | ||||||
|  | #include "usb_init.h" | ||||||
|  | #include "usb_sil.h" | ||||||
|  | #include "usb_mem.h" | ||||||
|  | #include "usb_int.h" | ||||||
|  | 
 | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_LIB_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										87
									
								
								fw_dc22_stm32l100/src/usb/core/usb_mem.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								fw_dc22_stm32l100/src/usb/core/usb_mem.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_mem.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Utility functions for memory transfers to/from PMA | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "usb_lib.h" | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | /* Extern variables ----------------------------------------------------------*/ | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : UserToPMABufferCopy | ||||||
|  | * Description    : Copy a buffer from user memory area to packet memory area (PMA) | ||||||
|  | * Input          : - pbUsrBuf: pointer to user memory area. | ||||||
|  | *                  - wPMABufAddr: address into PMA. | ||||||
|  | *                  - wNBytes: no. of bytes to be copied. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None	. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) | ||||||
|  | { | ||||||
|  |   uint32_t n = (wNBytes + 1) >> 1;   /* n = (wNBytes + 1) / 2 */ | ||||||
|  |   uint32_t i, temp1, temp2; | ||||||
|  |   uint16_t *pdwVal; | ||||||
|  |   pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr); | ||||||
|  |   for (i = n; i != 0; i--) | ||||||
|  |   { | ||||||
|  |     temp1 = (uint16_t) * pbUsrBuf; | ||||||
|  |     pbUsrBuf++; | ||||||
|  |     temp2 = temp1 | (uint16_t) * pbUsrBuf << 8; | ||||||
|  |     *pdwVal++ = temp2; | ||||||
|  |     pdwVal++; | ||||||
|  |     pbUsrBuf++; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : PMAToUserBufferCopy | ||||||
|  | * Description    : Copy a buffer from user memory area to packet memory area (PMA) | ||||||
|  | * Input          : - pbUsrBuf    = pointer to user memory area. | ||||||
|  | *                  - wPMABufAddr = address into PMA. | ||||||
|  | *                  - wNBytes     = no. of bytes to be copied. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) | ||||||
|  | { | ||||||
|  |   uint32_t n = (wNBytes + 1) >> 1;/* /2*/ | ||||||
|  |   uint32_t i; | ||||||
|  |   uint32_t *pdwVal; | ||||||
|  |   pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr); | ||||||
|  |   for (i = n; i != 0; i--) | ||||||
|  |   { | ||||||
|  |     *(uint16_t*)pbUsrBuf++ = *pdwVal++; | ||||||
|  |     pbUsrBuf++; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										45
									
								
								fw_dc22_stm32l100/src/usb/core/usb_mem.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								fw_dc22_stm32l100/src/usb/core/usb_mem.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_mem.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Utility prototypes functions for memory/PMA transfers | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_MEM_H | ||||||
|  | #define __USB_MEM_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes); | ||||||
|  | void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes); | ||||||
|  | 
 | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #endif  /*__USB_MEM_H*/ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										760
									
								
								fw_dc22_stm32l100/src/usb/core/usb_regs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										760
									
								
								fw_dc22_stm32l100/src/usb/core/usb_regs.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,760 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_regs.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Interface functions to USB cell registers | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "usb_lib.h" | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | /* Extern variables ----------------------------------------------------------*/ | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetCNTR. | ||||||
|  | * Description    : Set the CNTR register value. | ||||||
|  | * Input          : wRegValue: new register value. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetCNTR(uint16_t wRegValue) | ||||||
|  | { | ||||||
|  |   _SetCNTR(wRegValue); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetCNTR. | ||||||
|  | * Description    : returns the CNTR register value. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : CNTR register Value. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetCNTR(void) | ||||||
|  | { | ||||||
|  |   return(_GetCNTR()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetISTR. | ||||||
|  | * Description    : Set the ISTR register value. | ||||||
|  | * Input          : wRegValue: new register value. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetISTR(uint16_t wRegValue) | ||||||
|  | { | ||||||
|  |   _SetISTR(wRegValue); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetISTR | ||||||
|  | * Description    : Returns the ISTR register value. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : ISTR register Value | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetISTR(void) | ||||||
|  | { | ||||||
|  |   return(_GetISTR()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetFNR | ||||||
|  | * Description    : Returns the FNR register value. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : FNR register Value | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetFNR(void) | ||||||
|  | { | ||||||
|  |   return(_GetFNR()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetDADDR | ||||||
|  | * Description    : Set the DADDR register value. | ||||||
|  | * Input          : wRegValue: new register value. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetDADDR(uint16_t wRegValue) | ||||||
|  | { | ||||||
|  |   _SetDADDR(wRegValue); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetDADDR | ||||||
|  | * Description    : Returns the DADDR register value. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : DADDR register Value | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetDADDR(void) | ||||||
|  | { | ||||||
|  |   return(_GetDADDR()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetBTABLE | ||||||
|  | * Description    : Set the BTABLE. | ||||||
|  | * Input          : wRegValue: New register value. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetBTABLE(uint16_t wRegValue) | ||||||
|  | { | ||||||
|  |   _SetBTABLE(wRegValue); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetBTABLE. | ||||||
|  | * Description    : Returns the BTABLE register value. | ||||||
|  | * Input          : None.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : BTABLE address. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetBTABLE(void) | ||||||
|  | { | ||||||
|  |   return(_GetBTABLE()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetENDPOINT | ||||||
|  | * Description    : Set the Endpoint register value. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  wRegValue. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetENDPOINT(uint8_t bEpNum, uint16_t wRegValue) | ||||||
|  | { | ||||||
|  |   _SetENDPOINT(bEpNum, wRegValue); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetENDPOINT | ||||||
|  | * Description    : Return the Endpoint register value. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Endpoint register value. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetENDPOINT(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetENDPOINT(bEpNum)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPType | ||||||
|  | * Description    : sets the type in the endpoint register. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  wType: type definition. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPType(uint8_t bEpNum, uint16_t wType) | ||||||
|  | { | ||||||
|  |   _SetEPType(bEpNum, wType); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPType | ||||||
|  | * Description    : Returns the endpoint type. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Endpoint Type | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPType(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPType(bEpNum)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPTxStatus | ||||||
|  | * Description    : Set the status of Tx endpoint. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  wState: new state. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPTxStatus(uint8_t bEpNum, uint16_t wState) | ||||||
|  | { | ||||||
|  |   _SetEPTxStatus(bEpNum, wState); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPRxStatus | ||||||
|  | * Description    : Set the status of Rx endpoint. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  wState: new state. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPRxStatus(uint8_t bEpNum, uint16_t wState) | ||||||
|  | { | ||||||
|  |   _SetEPRxStatus(bEpNum, wState); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetDouBleBuffEPStall | ||||||
|  | * Description    : sets the status for Double Buffer Endpoint to STALL | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  bDir: Endpoint direction. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetDouBleBuffEPStall(uint8_t bEpNum, uint8_t bDir) | ||||||
|  | { | ||||||
|  |   uint16_t Endpoint_DTOG_Status; | ||||||
|  |   Endpoint_DTOG_Status = GetENDPOINT(bEpNum); | ||||||
|  |   if (bDir == EP_DBUF_OUT) | ||||||
|  |   { /* OUT double buffered endpoint */ | ||||||
|  |     _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1); | ||||||
|  |   } | ||||||
|  |   else if (bDir == EP_DBUF_IN) | ||||||
|  |   { /* IN double buffered endpoint */ | ||||||
|  |     _SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPTxStatus | ||||||
|  | * Description    : Returns the endpoint Tx status. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Endpoint TX Status | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPTxStatus(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPTxStatus(bEpNum)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPRxStatus | ||||||
|  | * Description    : Returns the endpoint Rx status. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Endpoint RX Status | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPRxStatus(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPRxStatus(bEpNum)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPTxValid | ||||||
|  | * Description    : Valid the endpoint Tx Status. | ||||||
|  | * Input          : bEpNum: Endpoint Number.   | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPTxValid(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _SetEPTxStatus(bEpNum, EP_TX_VALID); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPRxValid | ||||||
|  | * Description    : Valid the endpoint Rx Status. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPRxValid(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _SetEPRxStatus(bEpNum, EP_RX_VALID); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEP_KIND | ||||||
|  | * Description    : Clear the EP_KIND bit. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEP_KIND(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _SetEP_KIND(bEpNum); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ClearEP_KIND | ||||||
|  | * Description    : set the  EP_KIND bit. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void ClearEP_KIND(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _ClearEP_KIND(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Clear_Status_Out | ||||||
|  | * Description    : Clear the Status Out of the related Endpoint | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Clear_Status_Out(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _ClearEP_KIND(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Set_Status_Out | ||||||
|  | * Description    : Set the Status Out of the related Endpoint | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Set_Status_Out(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _SetEP_KIND(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPDoubleBuff | ||||||
|  | * Description    : Enable the double buffer feature for the endpoint.  | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPDoubleBuff(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _SetEP_KIND(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ClearEPDoubleBuff | ||||||
|  | * Description    : Disable the double buffer feature for the endpoint.  | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void ClearEPDoubleBuff(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _ClearEP_KIND(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetTxStallStatus | ||||||
|  | * Description    : Returns the Stall status of the Tx endpoint. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Tx Stall status. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetTxStallStatus(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetTxStallStatus(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetRxStallStatus | ||||||
|  | * Description    : Returns the Stall status of the Rx endpoint.  | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Rx Stall status. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetRxStallStatus(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetRxStallStatus(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ClearEP_CTR_RX | ||||||
|  | * Description    : Clear the CTR_RX bit. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void ClearEP_CTR_RX(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _ClearEP_CTR_RX(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ClearEP_CTR_TX | ||||||
|  | * Description    : Clear the CTR_TX bit. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void ClearEP_CTR_TX(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _ClearEP_CTR_TX(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ToggleDTOG_RX | ||||||
|  | * Description    : Toggle the DTOG_RX bit. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void ToggleDTOG_RX(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _ToggleDTOG_RX(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ToggleDTOG_TX | ||||||
|  | * Description    : Toggle the DTOG_TX bit. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void ToggleDTOG_TX(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _ToggleDTOG_TX(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ClearDTOG_RX. | ||||||
|  | * Description    : Clear the DTOG_RX bit. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void ClearDTOG_RX(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _ClearDTOG_RX(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ClearDTOG_TX. | ||||||
|  | * Description    : Clear the DTOG_TX bit. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void ClearDTOG_TX(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   _ClearDTOG_TX(bEpNum); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPAddress | ||||||
|  | * Description    : Set the endpoint address. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | *                  bAddr: New endpoint address. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPAddress(uint8_t bEpNum, uint8_t bAddr) | ||||||
|  | { | ||||||
|  |   _SetEPAddress(bEpNum, bAddr); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPAddress | ||||||
|  | * Description    : Get the endpoint address. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Endpoint address. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint8_t GetEPAddress(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPAddress(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPTxAddr | ||||||
|  | * Description    : Set the endpoint Tx buffer address. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | *                  wAddr: new address.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPTxAddr(uint8_t bEpNum, uint16_t wAddr) | ||||||
|  | { | ||||||
|  |   _SetEPTxAddr(bEpNum, wAddr); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPRxAddr | ||||||
|  | * Description    : Set the endpoint Rx buffer address. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | *                  wAddr: new address. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPRxAddr(uint8_t bEpNum, uint16_t wAddr) | ||||||
|  | { | ||||||
|  |   _SetEPRxAddr(bEpNum, wAddr); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPTxAddr | ||||||
|  | * Description    : Returns the endpoint Tx buffer address. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Rx buffer address.  | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPTxAddr(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPTxAddr(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPRxAddr. | ||||||
|  | * Description    : Returns the endpoint Rx buffer address. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Rx buffer address. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPRxAddr(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPRxAddr(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPTxCount. | ||||||
|  | * Description    : Set the Tx count. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | *                  wCount: new count value. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPTxCount(uint8_t bEpNum, uint16_t wCount) | ||||||
|  | { | ||||||
|  |   _SetEPTxCount(bEpNum, wCount); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPCountRxReg. | ||||||
|  | * Description    : Set the Count Rx Register value. | ||||||
|  | * Input          : *pdwReg: point to the register. | ||||||
|  | *                  wCount: the new register value. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPCountRxReg(uint32_t *pdwReg, uint16_t wCount) | ||||||
|  | { | ||||||
|  |   _SetEPCountRxReg(dwReg, wCount); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPRxCount | ||||||
|  | * Description    : Set the Rx count. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  wCount: the new count value. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPRxCount(uint8_t bEpNum, uint16_t wCount) | ||||||
|  | { | ||||||
|  |   _SetEPRxCount(bEpNum, wCount); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPTxCount | ||||||
|  | * Description    : Get the Tx count. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None | ||||||
|  | * Return         : Tx count value. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPTxCount(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPTxCount(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPRxCount | ||||||
|  | * Description    : Get the Rx count. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Rx count value. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPRxCount(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPRxCount(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPDblBuffAddr | ||||||
|  | * Description    : Set the addresses of the buffer 0 and 1. | ||||||
|  | * Input          : bEpNum: Endpoint Number.   | ||||||
|  | *                  wBuf0Addr: new address of buffer 0.  | ||||||
|  | *                  wBuf1Addr: new address of buffer 1. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPDblBuffAddr(uint8_t bEpNum, uint16_t wBuf0Addr, uint16_t wBuf1Addr) | ||||||
|  | { | ||||||
|  |   _SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPDblBuf0Addr | ||||||
|  | * Description    : Set the Buffer 1 address. | ||||||
|  | * Input          : bEpNum: Endpoint Number | ||||||
|  | *                  wBuf0Addr: new address. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPDblBuf0Addr(uint8_t bEpNum, uint16_t wBuf0Addr) | ||||||
|  | { | ||||||
|  |   _SetEPDblBuf0Addr(bEpNum, wBuf0Addr); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPDblBuf1Addr | ||||||
|  | * Description    : Set the Buffer 1 address. | ||||||
|  | * Input          : bEpNum: Endpoint Number | ||||||
|  | *                  wBuf1Addr: new address. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPDblBuf1Addr(uint8_t bEpNum, uint16_t wBuf1Addr) | ||||||
|  | { | ||||||
|  |   _SetEPDblBuf1Addr(bEpNum, wBuf1Addr); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPDblBuf0Addr | ||||||
|  | * Description    : Returns the address of the Buffer 0. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPDblBuf0Addr(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPDblBuf0Addr(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPDblBuf1Addr | ||||||
|  | * Description    : Returns the address of the Buffer 1. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Address of the Buffer 1. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPDblBuf1Addr(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPDblBuf1Addr(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPDblBuffCount | ||||||
|  | * Description    : Set the number of bytes for a double Buffer  | ||||||
|  | *                  endpoint. | ||||||
|  | * Input          : bEpNum,bDir, wCount | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPDblBuffCount(uint8_t bEpNum, uint8_t bDir, uint16_t wCount) | ||||||
|  | { | ||||||
|  |   _SetEPDblBuffCount(bEpNum, bDir, wCount); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPDblBuf0Count | ||||||
|  | * Description    : Set the number of bytes in the buffer 0 of a double Buffer  | ||||||
|  | *                  endpoint. | ||||||
|  | * Input          : bEpNum, bDir,  wCount | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPDblBuf0Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount) | ||||||
|  | { | ||||||
|  |   _SetEPDblBuf0Count(bEpNum, bDir, wCount); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SetEPDblBuf1Count | ||||||
|  | * Description    : Set the number of bytes in the buffer 0 of a double Buffer  | ||||||
|  | *                  endpoint. | ||||||
|  | * Input          : bEpNum,  bDir,  wCount | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SetEPDblBuf1Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount) | ||||||
|  | { | ||||||
|  |   _SetEPDblBuf1Count(bEpNum, bDir, wCount); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPDblBuf0Count | ||||||
|  | * Description    : Returns the number of byte received in the buffer 0 of a double | ||||||
|  | *                  Buffer endpoint. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Endpoint Buffer 0 count | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPDblBuf0Count(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPDblBuf0Count(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPDblBuf1Count | ||||||
|  | * Description    : Returns the number of data received in the buffer 1 of a double | ||||||
|  | *                  Buffer endpoint. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Endpoint Buffer 1 count. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t GetEPDblBuf1Count(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   return(_GetEPDblBuf1Count(bEpNum)); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : GetEPDblBufDir | ||||||
|  | * Description    : gets direction of the double buffered endpoint | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : EP_DBUF_OUT, EP_DBUF_IN, | ||||||
|  | *                  EP_DBUF_ERR if the endpoint counter not yet programmed. | ||||||
|  | *******************************************************************************/ | ||||||
|  | EP_DBUF_DIR GetEPDblBufDir(uint8_t bEpNum) | ||||||
|  | { | ||||||
|  |   if ((uint16_t)(*_pEPRxCount(bEpNum) & 0xFC00) != 0) | ||||||
|  |     return(EP_DBUF_OUT); | ||||||
|  |   else if (((uint16_t)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0) | ||||||
|  |     return(EP_DBUF_IN); | ||||||
|  |   else | ||||||
|  |     return(EP_DBUF_ERR); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : FreeUserBuffer | ||||||
|  | * Description    : free buffer used from the application realizing it to the line | ||||||
|  |                    toggles bit SW_BUF in the double buffered endpoint register | ||||||
|  | * Input          : bEpNum, bDir | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void FreeUserBuffer(uint8_t bEpNum, uint8_t bDir) | ||||||
|  | { | ||||||
|  |   if (bDir == EP_DBUF_OUT) | ||||||
|  |   { /* OUT double buffered endpoint */ | ||||||
|  |     _ToggleDTOG_TX(bEpNum); | ||||||
|  |   } | ||||||
|  |   else if (bDir == EP_DBUF_IN) | ||||||
|  |   { /* IN double buffered endpoint */ | ||||||
|  |     _ToggleDTOG_RX(bEpNum); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ToWord | ||||||
|  | * Description    : merge two byte in a word. | ||||||
|  | * Input          : bh: byte high, bl: bytes low. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : resulted word. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t ToWord(uint8_t bh, uint8_t bl) | ||||||
|  | { | ||||||
|  |   uint16_t wRet; | ||||||
|  |   wRet = (uint16_t)bl | ((uint16_t)bh << 8); | ||||||
|  |   return(wRet); | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : ByteSwap | ||||||
|  | * Description    : Swap two byte in a word. | ||||||
|  | * Input          : wSwW: word to Swap. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : resulted word. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint16_t ByteSwap(uint16_t wSwW) | ||||||
|  | { | ||||||
|  |   uint8_t bTemp; | ||||||
|  |   uint16_t wRet; | ||||||
|  |   bTemp = (uint8_t)(wSwW & 0xff); | ||||||
|  |   wRet =  (wSwW >> 8) | ((uint16_t)bTemp << 8); | ||||||
|  |   return(wRet); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										680
									
								
								fw_dc22_stm32l100/src/usb/core/usb_regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										680
									
								
								fw_dc22_stm32l100/src/usb/core/usb_regs.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,680 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_regs.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Interface prototype functions to USB cell registers | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_REGS_H | ||||||
|  | #define __USB_REGS_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | typedef enum _EP_DBUF_DIR | ||||||
|  | { | ||||||
|  |   /* double buffered endpoint direction */ | ||||||
|  |   EP_DBUF_ERR, | ||||||
|  |   EP_DBUF_OUT, | ||||||
|  |   EP_DBUF_IN | ||||||
|  | }EP_DBUF_DIR; | ||||||
|  | 
 | ||||||
|  | /* endpoint buffer number */ | ||||||
|  | enum EP_BUF_NUM | ||||||
|  | { | ||||||
|  |   EP_NOBUF, | ||||||
|  |   EP_BUF0, | ||||||
|  |   EP_BUF1 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | #define RegBase  (0x40005C00L)  /* USB_IP Peripheral Registers base address */ | ||||||
|  | #define PMAAddr  (0x40006000L)  /* USB_IP Packet Memory Area base address   */ | ||||||
|  | 
 | ||||||
|  | /******************************************************************************/ | ||||||
|  | /*                         General registers                                  */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /* Control register */ | ||||||
|  | #define CNTR    ((__IO unsigned *)(RegBase + 0x40)) | ||||||
|  | /* Interrupt status register */ | ||||||
|  | #define ISTR    ((__IO unsigned *)(RegBase + 0x44)) | ||||||
|  | /* Frame number register */ | ||||||
|  | #define FNR     ((__IO unsigned *)(RegBase + 0x48)) | ||||||
|  | /* Device address register */ | ||||||
|  | #define DADDR   ((__IO unsigned *)(RegBase + 0x4C)) | ||||||
|  | /* Buffer Table address register */ | ||||||
|  | #define BTABLE  ((__IO unsigned *)(RegBase + 0x50)) | ||||||
|  | /******************************************************************************/ | ||||||
|  | /*                         Endpoint registers                                 */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | #define EP0REG  ((__IO unsigned *)(RegBase)) /* endpoint 0 register address */ | ||||||
|  | 
 | ||||||
|  | /* Endpoint Addresses (w/direction) */ | ||||||
|  | #define EP0_OUT     ((uint8_t)0x00)   | ||||||
|  | #define EP0_IN      ((uint8_t)0x80)  | ||||||
|  | #define EP1_OUT     ((uint8_t)0x01)   | ||||||
|  | #define EP1_IN      ((uint8_t)0x81)   | ||||||
|  | #define EP2_OUT     ((uint8_t)0x02)   | ||||||
|  | #define EP2_IN      ((uint8_t)0x82)   | ||||||
|  | #define EP3_OUT     ((uint8_t)0x03)   | ||||||
|  | #define EP3_IN      ((uint8_t)0x83)  | ||||||
|  | #define EP4_OUT     ((uint8_t)0x04)   | ||||||
|  | #define EP4_IN      ((uint8_t)0x84) | ||||||
|  | #define EP5_OUT     ((uint8_t)0x05)   | ||||||
|  | #define EP5_IN      ((uint8_t)0x85) | ||||||
|  | #define EP6_OUT     ((uint8_t)0x06)   | ||||||
|  | #define EP6_IN      ((uint8_t)0x86) | ||||||
|  | #define EP7_OUT     ((uint8_t)0x07)   | ||||||
|  | #define EP7_IN      ((uint8_t)0x87) | ||||||
|  | 
 | ||||||
|  | /* endpoints enumeration */ | ||||||
|  | #define ENDP0       ((uint8_t)0) | ||||||
|  | #define ENDP1       ((uint8_t)1) | ||||||
|  | #define ENDP2       ((uint8_t)2) | ||||||
|  | #define ENDP3       ((uint8_t)3) | ||||||
|  | #define ENDP4       ((uint8_t)4) | ||||||
|  | #define ENDP5       ((uint8_t)5) | ||||||
|  | #define ENDP6       ((uint8_t)6) | ||||||
|  | #define ENDP7       ((uint8_t)7) | ||||||
|  | 
 | ||||||
|  | /******************************************************************************/ | ||||||
|  | /*                       ISTR interrupt events                                */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | #define ISTR_CTR    (0x8000) /* Correct TRansfer (clear-only bit) */ | ||||||
|  | #define ISTR_DOVR   (0x4000) /* DMA OVeR/underrun (clear-only bit) */ | ||||||
|  | #define ISTR_ERR    (0x2000) /* ERRor (clear-only bit) */ | ||||||
|  | #define ISTR_WKUP   (0x1000) /* WaKe UP (clear-only bit) */ | ||||||
|  | #define ISTR_SUSP   (0x0800) /* SUSPend (clear-only bit) */ | ||||||
|  | #define ISTR_RESET  (0x0400) /* RESET (clear-only bit) */ | ||||||
|  | #define ISTR_SOF    (0x0200) /* Start Of Frame (clear-only bit) */ | ||||||
|  | #define ISTR_ESOF   (0x0100) /* Expected Start Of Frame (clear-only bit) */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define ISTR_DIR    (0x0010)  /* DIRection of transaction (read-only bit)  */ | ||||||
|  | #define ISTR_EP_ID  (0x000F)  /* EndPoint IDentifier (read-only bit)  */ | ||||||
|  | 
 | ||||||
|  | #define CLR_CTR    (~ISTR_CTR)   /* clear Correct TRansfer bit */ | ||||||
|  | #define CLR_DOVR   (~ISTR_DOVR)  /* clear DMA OVeR/underrun bit*/ | ||||||
|  | #define CLR_ERR    (~ISTR_ERR)   /* clear ERRor bit */ | ||||||
|  | #define CLR_WKUP   (~ISTR_WKUP)  /* clear WaKe UP bit     */ | ||||||
|  | #define CLR_SUSP   (~ISTR_SUSP)  /* clear SUSPend bit     */ | ||||||
|  | #define CLR_RESET  (~ISTR_RESET) /* clear RESET bit      */ | ||||||
|  | #define CLR_SOF    (~ISTR_SOF)   /* clear Start Of Frame bit   */ | ||||||
|  | #define CLR_ESOF   (~ISTR_ESOF)  /* clear Expected Start Of Frame bit */ | ||||||
|  | 
 | ||||||
|  | /******************************************************************************/ | ||||||
|  | /*             CNTR control register bits definitions                         */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | #define CNTR_CTRM   (0x8000) /* Correct TRansfer Mask */ | ||||||
|  | #define CNTR_DOVRM  (0x4000) /* DMA OVeR/underrun Mask */ | ||||||
|  | #define CNTR_ERRM   (0x2000) /* ERRor Mask */ | ||||||
|  | #define CNTR_WKUPM  (0x1000) /* WaKe UP Mask */ | ||||||
|  | #define CNTR_SUSPM  (0x0800) /* SUSPend Mask */ | ||||||
|  | #define CNTR_RESETM (0x0400) /* RESET Mask   */ | ||||||
|  | #define CNTR_SOFM   (0x0200) /* Start Of Frame Mask */ | ||||||
|  | #define CNTR_ESOFM  (0x0100) /* Expected Start Of Frame Mask */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define CNTR_RESUME (0x0010) /* RESUME request */ | ||||||
|  | #define CNTR_FSUSP  (0x0008) /* Force SUSPend */ | ||||||
|  | #define CNTR_LPMODE (0x0004) /* Low-power MODE */ | ||||||
|  | #define CNTR_PDWN   (0x0002) /* Power DoWN */ | ||||||
|  | #define CNTR_FRES   (0x0001) /* Force USB RESet */ | ||||||
|  | 
 | ||||||
|  | /******************************************************************************/ | ||||||
|  | /*                FNR Frame Number Register bit definitions                   */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | #define FNR_RXDP (0x8000) /* status of D+ data line */ | ||||||
|  | #define FNR_RXDM (0x4000) /* status of D- data line */ | ||||||
|  | #define FNR_LCK  (0x2000) /* LoCKed */ | ||||||
|  | #define FNR_LSOF (0x1800) /* Lost SOF */ | ||||||
|  | #define FNR_FN  (0x07FF) /* Frame Number */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | /*               DADDR Device ADDRess bit definitions                         */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | #define DADDR_EF (0x80) | ||||||
|  | #define DADDR_ADD (0x7F) | ||||||
|  | /******************************************************************************/ | ||||||
|  | /*                            Endpoint register                               */ | ||||||
|  | /******************************************************************************/ | ||||||
|  | /* bit positions */ | ||||||
|  | #define EP_CTR_RX      (0x8000) /* EndPoint Correct TRansfer RX */ | ||||||
|  | #define EP_DTOG_RX     (0x4000) /* EndPoint Data TOGGLE RX */ | ||||||
|  | #define EPRX_STAT      (0x3000) /* EndPoint RX STATus bit field */ | ||||||
|  | #define EP_SETUP       (0x0800) /* EndPoint SETUP */ | ||||||
|  | #define EP_T_FIELD     (0x0600) /* EndPoint TYPE */ | ||||||
|  | #define EP_KIND        (0x0100) /* EndPoint KIND */ | ||||||
|  | #define EP_CTR_TX      (0x0080) /* EndPoint Correct TRansfer TX */ | ||||||
|  | #define EP_DTOG_TX     (0x0040) /* EndPoint Data TOGGLE TX */ | ||||||
|  | #define EPTX_STAT      (0x0030) /* EndPoint TX STATus bit field */ | ||||||
|  | #define EPADDR_FIELD   (0x000F) /* EndPoint ADDRess FIELD */ | ||||||
|  | 
 | ||||||
|  | /* EndPoint REGister MASK (no toggle fields) */ | ||||||
|  | #define EPREG_MASK     (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD) | ||||||
|  | 
 | ||||||
|  | /* EP_TYPE[1:0] EndPoint TYPE */ | ||||||
|  | #define EP_TYPE_MASK   (0x0600) /* EndPoint TYPE Mask */ | ||||||
|  | #define EP_BULK        (0x0000) /* EndPoint BULK */ | ||||||
|  | #define EP_CONTROL     (0x0200) /* EndPoint CONTROL */ | ||||||
|  | #define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */ | ||||||
|  | #define EP_INTERRUPT   (0x0600) /* EndPoint INTERRUPT */ | ||||||
|  | #define EP_T_MASK      (~EP_T_FIELD & EPREG_MASK) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* EP_KIND EndPoint KIND */ | ||||||
|  | #define EPKIND_MASK    (~EP_KIND & EPREG_MASK) | ||||||
|  | 
 | ||||||
|  | /* STAT_TX[1:0] STATus for TX transfer */ | ||||||
|  | #define EP_TX_DIS      (0x0000) /* EndPoint TX DISabled */ | ||||||
|  | #define EP_TX_STALL    (0x0010) /* EndPoint TX STALLed */ | ||||||
|  | #define EP_TX_NAK      (0x0020) /* EndPoint TX NAKed */ | ||||||
|  | #define EP_TX_VALID    (0x0030) /* EndPoint TX VALID */ | ||||||
|  | #define EPTX_DTOG1     (0x0010) /* EndPoint TX Data TOGgle bit1 */ | ||||||
|  | #define EPTX_DTOG2     (0x0020) /* EndPoint TX Data TOGgle bit2 */ | ||||||
|  | #define EPTX_DTOGMASK  (EPTX_STAT|EPREG_MASK) | ||||||
|  | 
 | ||||||
|  | /* STAT_RX[1:0] STATus for RX transfer */ | ||||||
|  | #define EP_RX_DIS      (0x0000) /* EndPoint RX DISabled */ | ||||||
|  | #define EP_RX_STALL    (0x1000) /* EndPoint RX STALLed */ | ||||||
|  | #define EP_RX_NAK      (0x2000) /* EndPoint RX NAKed */ | ||||||
|  | #define EP_RX_VALID    (0x3000) /* EndPoint RX VALID */ | ||||||
|  | #define EPRX_DTOG1     (0x1000) /* EndPoint RX Data TOGgle bit1 */ | ||||||
|  | #define EPRX_DTOG2     (0x2000) /* EndPoint RX Data TOGgle bit1 */ | ||||||
|  | #define EPRX_DTOGMASK  (EPRX_STAT|EPREG_MASK) | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* SetCNTR */ | ||||||
|  | #define _SetCNTR(wRegValue)  (*CNTR   = (uint16_t)wRegValue) | ||||||
|  | 
 | ||||||
|  | /* SetISTR */ | ||||||
|  | #define _SetISTR(wRegValue)  (*ISTR   = (uint16_t)wRegValue) | ||||||
|  | 
 | ||||||
|  | /* SetDADDR */ | ||||||
|  | #define _SetDADDR(wRegValue) (*DADDR  = (uint16_t)wRegValue) | ||||||
|  | 
 | ||||||
|  | /* SetBTABLE */ | ||||||
|  | #define _SetBTABLE(wRegValue)(*BTABLE = (uint16_t)(wRegValue & 0xFFF8)) | ||||||
|  | 
 | ||||||
|  | /* GetCNTR */ | ||||||
|  | #define _GetCNTR()   ((uint16_t) *CNTR) | ||||||
|  | 
 | ||||||
|  | /* GetISTR */ | ||||||
|  | #define _GetISTR()   ((uint16_t) *ISTR) | ||||||
|  | 
 | ||||||
|  | /* GetFNR */ | ||||||
|  | #define _GetFNR()    ((uint16_t) *FNR) | ||||||
|  | 
 | ||||||
|  | /* GetDADDR */ | ||||||
|  | #define _GetDADDR()  ((uint16_t) *DADDR) | ||||||
|  | 
 | ||||||
|  | /* GetBTABLE */ | ||||||
|  | #define _GetBTABLE() ((uint16_t) *BTABLE) | ||||||
|  | 
 | ||||||
|  | /* SetENDPOINT */ | ||||||
|  | #define _SetENDPOINT(bEpNum,wRegValue)  (*(EP0REG + bEpNum)= \ | ||||||
|  |     (uint16_t)wRegValue) | ||||||
|  | 
 | ||||||
|  | /* GetENDPOINT */ | ||||||
|  | #define _GetENDPOINT(bEpNum)        ((uint16_t)(*(EP0REG + bEpNum))) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPType | ||||||
|  | * Description    : sets the type in the endpoint register(bits EP_TYPE[1:0]) | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  wType											  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\ | ||||||
|  |                                   ((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType ))) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : GetEPType | ||||||
|  | * Description    : gets the type in the endpoint register(bits EP_TYPE[1:0])  | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Endpoint Type | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPTxStatus | ||||||
|  | * Description    : sets the status for tx transfer (bits STAT_TX[1:0]). | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  wState: new state | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPTxStatus(bEpNum,wState) {\ | ||||||
|  |     register uint16_t _wRegVal;       \ | ||||||
|  |     _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\ | ||||||
|  |     /* toggle first bit ? */     \ | ||||||
|  |     if((EPTX_DTOG1 & wState)!= 0)      \ | ||||||
|  |       _wRegVal ^= EPTX_DTOG1;        \ | ||||||
|  |     /* toggle second bit ?  */         \ | ||||||
|  |     if((EPTX_DTOG2 & wState)!= 0)      \ | ||||||
|  |       _wRegVal ^= EPTX_DTOG2;        \ | ||||||
|  |     _SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX));    \ | ||||||
|  |   } /* _SetEPTxStatus */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPRxStatus | ||||||
|  | * Description    : sets the status for rx transfer (bits STAT_TX[1:0]) | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  wState: new state. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPRxStatus(bEpNum,wState) {\ | ||||||
|  |     register uint16_t _wRegVal;   \ | ||||||
|  |     \ | ||||||
|  |     _wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\ | ||||||
|  |     /* toggle first bit ? */  \ | ||||||
|  |     if((EPRX_DTOG1 & wState)!= 0) \ | ||||||
|  |       _wRegVal ^= EPRX_DTOG1;  \ | ||||||
|  |     /* toggle second bit ? */  \ | ||||||
|  |     if((EPRX_DTOG2 & wState)!= 0) \ | ||||||
|  |       _wRegVal ^= EPRX_DTOG2;  \ | ||||||
|  |     _SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX)); \ | ||||||
|  |   } /* _SetEPRxStatus */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPRxTxStatus | ||||||
|  | * Description    : sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0]) | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | *                  wStaterx: new state. | ||||||
|  | *                  wStatetx: new state. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPRxTxStatus(bEpNum,wStaterx,wStatetx) {\ | ||||||
|  |     register uint32_t _wRegVal;   \ | ||||||
|  |     \ | ||||||
|  |     _wRegVal = _GetENDPOINT(bEpNum) & (EPRX_DTOGMASK |EPTX_STAT) ;\ | ||||||
|  |     /* toggle first bit ? */  \ | ||||||
|  |     if((EPRX_DTOG1 & wStaterx)!= 0) \ | ||||||
|  |       _wRegVal ^= EPRX_DTOG1;  \ | ||||||
|  |     /* toggle second bit ? */  \ | ||||||
|  |     if((EPRX_DTOG2 & wStaterx)!= 0) \ | ||||||
|  |       _wRegVal ^= EPRX_DTOG2;  \ | ||||||
|  |     /* toggle first bit ? */     \ | ||||||
|  |     if((EPTX_DTOG1 & wStatetx)!= 0)      \ | ||||||
|  |       _wRegVal ^= EPTX_DTOG1;        \ | ||||||
|  |     /* toggle second bit ?  */         \ | ||||||
|  |     if((EPTX_DTOG2 & wStatetx)!= 0)      \ | ||||||
|  |       _wRegVal ^= EPTX_DTOG2;        \ | ||||||
|  |     _SetENDPOINT(bEpNum, _wRegVal | EP_CTR_RX|EP_CTR_TX);    \ | ||||||
|  |   } /* _SetEPRxTxStatus */ | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : GetEPTxStatus / GetEPRxStatus  | ||||||
|  | * Description    : gets the status for tx/rx transfer (bits STAT_TX[1:0] | ||||||
|  | *                  /STAT_RX[1:0]) | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : status . | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _GetEPTxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EPTX_STAT) | ||||||
|  | 
 | ||||||
|  | #define _GetEPRxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EPRX_STAT) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPTxValid / SetEPRxValid  | ||||||
|  | * Description    : sets directly the VALID tx/rx-status into the enpoint register | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPTxValid(bEpNum)     (_SetEPTxStatus(bEpNum, EP_TX_VALID)) | ||||||
|  | 
 | ||||||
|  | #define _SetEPRxValid(bEpNum)     (_SetEPRxStatus(bEpNum, EP_RX_VALID)) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : GetTxStallStatus / GetRxStallStatus. | ||||||
|  | * Description    : checks stall condition in an endpoint. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : TRUE = endpoint in stall condition. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \ | ||||||
|  |                                    == EP_TX_STALL) | ||||||
|  | #define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \ | ||||||
|  |                                    == EP_RX_STALL) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEP_KIND / ClearEP_KIND. | ||||||
|  | * Description    : set & clear EP_KIND bit. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEP_KIND(bEpNum)    (_SetENDPOINT(bEpNum, \ | ||||||
|  |                                 (EP_CTR_RX|EP_CTR_TX|((_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK)))) | ||||||
|  | #define _ClearEP_KIND(bEpNum)  (_SetENDPOINT(bEpNum, \ | ||||||
|  |                                 (EP_CTR_RX|EP_CTR_TX|(_GetENDPOINT(bEpNum) & EPKIND_MASK)))) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : Set_Status_Out / Clear_Status_Out. | ||||||
|  | * Description    : Sets/clears directly STATUS_OUT bit in the endpoint register. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _Set_Status_Out(bEpNum)    _SetEP_KIND(bEpNum) | ||||||
|  | #define _Clear_Status_Out(bEpNum)  _ClearEP_KIND(bEpNum) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPDoubleBuff / ClearEPDoubleBuff. | ||||||
|  | * Description    : Sets/clears directly EP_KIND bit in the endpoint register. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPDoubleBuff(bEpNum)   _SetEP_KIND(bEpNum) | ||||||
|  | #define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : ClearEP_CTR_RX / ClearEP_CTR_TX. | ||||||
|  | * Description    : Clears bit CTR_RX / CTR_TX in the endpoint register. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _ClearEP_CTR_RX(bEpNum)   (_SetENDPOINT(bEpNum,\ | ||||||
|  |                                    _GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK)) | ||||||
|  | #define _ClearEP_CTR_TX(bEpNum)   (_SetENDPOINT(bEpNum,\ | ||||||
|  |                                    _GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK)) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : ToggleDTOG_RX / ToggleDTOG_TX . | ||||||
|  | * Description    : Toggles DTOG_RX / DTOG_TX bit in the endpoint register. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _ToggleDTOG_RX(bEpNum)    (_SetENDPOINT(bEpNum, \ | ||||||
|  |                                    EP_CTR_RX|EP_CTR_TX|EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK))) | ||||||
|  | #define _ToggleDTOG_TX(bEpNum)    (_SetENDPOINT(bEpNum, \ | ||||||
|  |                                    EP_CTR_RX|EP_CTR_TX|EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK))) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : ClearDTOG_RX / ClearDTOG_TX. | ||||||
|  | * Description    : Clears DTOG_RX / DTOG_TX bit in the endpoint register. | ||||||
|  | * Input          : bEpNum: Endpoint Number.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _ClearDTOG_RX(bEpNum)  if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\ | ||||||
|  |     _ToggleDTOG_RX(bEpNum) | ||||||
|  | #define _ClearDTOG_TX(bEpNum)  if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\ | ||||||
|  |     _ToggleDTOG_TX(bEpNum) | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPAddress. | ||||||
|  | * Description    : Sets address in an endpoint register. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | *                  bAddr: Address.  | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\ | ||||||
|  |     EP_CTR_RX|EP_CTR_TX|(_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : GetEPAddress. | ||||||
|  | * Description    : Gets address in an endpoint register. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _GetEPAddress(bEpNum) ((uint8_t)(_GetENDPOINT(bEpNum) & EPADDR_FIELD)) | ||||||
|  | 
 | ||||||
|  | #define _pEPTxAddr(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8  )*2 + PMAAddr)) | ||||||
|  | #define _pEPTxCount(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr)) | ||||||
|  | #define _pEPRxAddr(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr)) | ||||||
|  | #define _pEPRxCount(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr)) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPTxAddr / SetEPRxAddr. | ||||||
|  | * Description    : sets address of the tx/rx buffer. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | *                  wAddr: address to be set (must be word aligned). | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1)) | ||||||
|  | #define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1)) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : GetEPTxAddr / GetEPRxAddr. | ||||||
|  | * Description    : Gets address of the tx/rx buffer. | ||||||
|  | * Input          : bEpNum: Endpoint Number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : address of the buffer. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _GetEPTxAddr(bEpNum) ((uint16_t)*_pEPTxAddr(bEpNum)) | ||||||
|  | #define _GetEPRxAddr(bEpNum) ((uint16_t)*_pEPRxAddr(bEpNum)) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPCountRxReg. | ||||||
|  | * Description    : Sets counter of rx buffer with no. of blocks. | ||||||
|  | * Input          : pdwReg: pointer to counter. | ||||||
|  | *                  wCount: Counter. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _BlocksOf32(dwReg,wCount,wNBlocks) {\ | ||||||
|  |     wNBlocks = wCount >> 5;\ | ||||||
|  |     if((wCount & 0x1f) == 0)\ | ||||||
|  |       wNBlocks--;\ | ||||||
|  |     *pdwReg = (uint32_t)((wNBlocks << 10) | 0x8000);\ | ||||||
|  |   }/* _BlocksOf32 */ | ||||||
|  | 
 | ||||||
|  | #define _BlocksOf2(dwReg,wCount,wNBlocks) {\ | ||||||
|  |     wNBlocks = wCount >> 1;\ | ||||||
|  |     if((wCount & 0x1) != 0)\ | ||||||
|  |       wNBlocks++;\ | ||||||
|  |     *pdwReg = (uint32_t)(wNBlocks << 10);\ | ||||||
|  |   }/* _BlocksOf2 */ | ||||||
|  | 
 | ||||||
|  | #define _SetEPCountRxReg(dwReg,wCount)  {\ | ||||||
|  |     uint16_t wNBlocks;\ | ||||||
|  |     if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\ | ||||||
|  |     else {_BlocksOf2(dwReg,wCount,wNBlocks);}\ | ||||||
|  |   }/* _SetEPCountRxReg */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define _SetEPRxDblBuf0Count(bEpNum,wCount) {\ | ||||||
|  |     uint32_t *pdwReg = _pEPTxCount(bEpNum); \ | ||||||
|  |     _SetEPCountRxReg(pdwReg, wCount);\ | ||||||
|  |   } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPTxCount / SetEPRxCount. | ||||||
|  | * Description    : sets counter for the tx/rx buffer. | ||||||
|  | * Input          : bEpNum: endpoint number. | ||||||
|  | *                  wCount: Counter value. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount) | ||||||
|  | #define _SetEPRxCount(bEpNum,wCount) {\ | ||||||
|  |     uint32_t *pdwReg = _pEPRxCount(bEpNum); \ | ||||||
|  |     _SetEPCountRxReg(pdwReg, wCount);\ | ||||||
|  |   } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : GetEPTxCount / GetEPRxCount. | ||||||
|  | * Description    : gets counter of the tx buffer. | ||||||
|  | * Input          : bEpNum: endpoint number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Counter value. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _GetEPTxCount(bEpNum)((uint16_t)(*_pEPTxCount(bEpNum)) & 0x3ff) | ||||||
|  | #define _GetEPRxCount(bEpNum)((uint16_t)(*_pEPRxCount(bEpNum)) & 0x3ff) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPDblBuf0Addr / SetEPDblBuf1Addr. | ||||||
|  | * Description    : Sets buffer 0/1 address in a double buffer endpoint. | ||||||
|  | * Input          : bEpNum: endpoint number. | ||||||
|  | *                : wBuf0Addr: buffer 0 address. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);} | ||||||
|  | #define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);} | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPDblBuffAddr. | ||||||
|  | * Description    : Sets addresses in a double buffer endpoint. | ||||||
|  | * Input          : bEpNum: endpoint number. | ||||||
|  | *                : wBuf0Addr: buffer 0 address. | ||||||
|  | *                : wBuf1Addr = buffer 1 address. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \ | ||||||
|  |     _SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\ | ||||||
|  |     _SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\ | ||||||
|  |   } /* _SetEPDblBuffAddr */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : GetEPDblBuf0Addr / GetEPDblBuf1Addr. | ||||||
|  | * Description    : Gets buffer 0/1 address of a double buffer endpoint. | ||||||
|  | * Input          : bEpNum: endpoint number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum)) | ||||||
|  | #define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum)) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count. | ||||||
|  | * Description    : Gets buffer 0/1 address of a double buffer endpoint. | ||||||
|  | * Input          : bEpNum: endpoint number. | ||||||
|  | *                : bDir: endpoint dir  EP_DBUF_OUT = OUT  | ||||||
|  | *                                      EP_DBUF_IN  = IN  | ||||||
|  | *                : wCount: Counter value     | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _SetEPDblBuf0Count(bEpNum, bDir, wCount)  { \ | ||||||
|  |     if(bDir == EP_DBUF_OUT)\ | ||||||
|  |       /* OUT endpoint */ \ | ||||||
|  |     {_SetEPRxDblBuf0Count(bEpNum,wCount);} \ | ||||||
|  |     else if(bDir == EP_DBUF_IN)\ | ||||||
|  |       /* IN endpoint */ \ | ||||||
|  |       *_pEPTxCount(bEpNum) = (uint32_t)wCount;  \ | ||||||
|  |   } /* SetEPDblBuf0Count*/ | ||||||
|  | 
 | ||||||
|  | #define _SetEPDblBuf1Count(bEpNum, bDir, wCount)  { \ | ||||||
|  |     if(bDir == EP_DBUF_OUT)\ | ||||||
|  |       /* OUT endpoint */ \ | ||||||
|  |     {_SetEPRxCount(bEpNum,wCount);}\ | ||||||
|  |     else if(bDir == EP_DBUF_IN)\ | ||||||
|  |       /* IN endpoint */\ | ||||||
|  |       *_pEPRxCount(bEpNum) = (uint32_t)wCount; \ | ||||||
|  |   } /* SetEPDblBuf1Count */ | ||||||
|  | 
 | ||||||
|  | #define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\ | ||||||
|  |     _SetEPDblBuf0Count(bEpNum, bDir, wCount); \ | ||||||
|  |     _SetEPDblBuf1Count(bEpNum, bDir, wCount); \ | ||||||
|  |   } /* _SetEPDblBuffCount  */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Macro Name     : GetEPDblBuf0Count / GetEPDblBuf1Count. | ||||||
|  | * Description    : Gets buffer 0/1 rx/tx counter for double buffering. | ||||||
|  | * Input          : bEpNum: endpoint number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | #define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum)) | ||||||
|  | #define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | extern __IO uint16_t wIstr;  /* ISTR register last read value */ | ||||||
|  | 
 | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | void SetCNTR(uint16_t /*wRegValue*/); | ||||||
|  | void SetISTR(uint16_t /*wRegValue*/); | ||||||
|  | void SetDADDR(uint16_t /*wRegValue*/); | ||||||
|  | void SetBTABLE(uint16_t /*wRegValue*/); | ||||||
|  | void SetBTABLE(uint16_t /*wRegValue*/); | ||||||
|  | uint16_t GetCNTR(void); | ||||||
|  | uint16_t GetISTR(void); | ||||||
|  | uint16_t GetFNR(void); | ||||||
|  | uint16_t GetDADDR(void); | ||||||
|  | uint16_t GetBTABLE(void); | ||||||
|  | void SetENDPOINT(uint8_t /*bEpNum*/, uint16_t /*wRegValue*/); | ||||||
|  | uint16_t GetENDPOINT(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPType(uint8_t /*bEpNum*/, uint16_t /*wType*/); | ||||||
|  | uint16_t GetEPType(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPTxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/); | ||||||
|  | void SetEPRxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/); | ||||||
|  | void SetDouBleBuffEPStall(uint8_t /*bEpNum*/, uint8_t bDir); | ||||||
|  | uint16_t GetEPTxStatus(uint8_t /*bEpNum*/); | ||||||
|  | uint16_t GetEPRxStatus(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPTxValid(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPRxValid(uint8_t /*bEpNum*/); | ||||||
|  | uint16_t GetTxStallStatus(uint8_t /*bEpNum*/); | ||||||
|  | uint16_t GetRxStallStatus(uint8_t /*bEpNum*/); | ||||||
|  | void SetEP_KIND(uint8_t /*bEpNum*/); | ||||||
|  | void ClearEP_KIND(uint8_t /*bEpNum*/); | ||||||
|  | void Set_Status_Out(uint8_t /*bEpNum*/); | ||||||
|  | void Clear_Status_Out(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPDoubleBuff(uint8_t /*bEpNum*/); | ||||||
|  | void ClearEPDoubleBuff(uint8_t /*bEpNum*/); | ||||||
|  | void ClearEP_CTR_RX(uint8_t /*bEpNum*/); | ||||||
|  | void ClearEP_CTR_TX(uint8_t /*bEpNum*/); | ||||||
|  | void ToggleDTOG_RX(uint8_t /*bEpNum*/); | ||||||
|  | void ToggleDTOG_TX(uint8_t /*bEpNum*/); | ||||||
|  | void ClearDTOG_RX(uint8_t /*bEpNum*/); | ||||||
|  | void ClearDTOG_TX(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPAddress(uint8_t /*bEpNum*/, uint8_t /*bAddr*/); | ||||||
|  | uint8_t GetEPAddress(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPTxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/); | ||||||
|  | void SetEPRxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/); | ||||||
|  | uint16_t GetEPTxAddr(uint8_t /*bEpNum*/); | ||||||
|  | uint16_t GetEPRxAddr(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPCountRxReg(uint32_t * /*pdwReg*/, uint16_t /*wCount*/); | ||||||
|  | void SetEPTxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/); | ||||||
|  | void SetEPRxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/); | ||||||
|  | uint16_t GetEPTxCount(uint8_t /*bEpNum*/); | ||||||
|  | uint16_t GetEPRxCount(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPDblBuf0Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/); | ||||||
|  | void SetEPDblBuf1Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf1Addr*/); | ||||||
|  | void SetEPDblBuffAddr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/, uint16_t /*wBuf1Addr*/); | ||||||
|  | uint16_t GetEPDblBuf0Addr(uint8_t /*bEpNum*/); | ||||||
|  | uint16_t GetEPDblBuf1Addr(uint8_t /*bEpNum*/); | ||||||
|  | void SetEPDblBuffCount(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/); | ||||||
|  | void SetEPDblBuf0Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/); | ||||||
|  | void SetEPDblBuf1Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/); | ||||||
|  | uint16_t GetEPDblBuf0Count(uint8_t /*bEpNum*/); | ||||||
|  | uint16_t GetEPDblBuf1Count(uint8_t /*bEpNum*/); | ||||||
|  | EP_DBUF_DIR GetEPDblBufDir(uint8_t /*bEpNum*/); | ||||||
|  | void FreeUserBuffer(uint8_t bEpNum/*bEpNum*/, uint8_t bDir); | ||||||
|  | uint16_t ToWord(uint8_t, uint8_t); | ||||||
|  | uint16_t ByteSwap(uint16_t); | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_REGS_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										103
									
								
								fw_dc22_stm32l100/src/usb/core/usb_sil.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								fw_dc22_stm32l100/src/usb/core/usb_sil.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_sil.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Simplified Interface Layer for Global Initialization and Endpoint | ||||||
|  |   *          Rea/Write operations. | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "usb_lib.h" | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | /* Extern variables ----------------------------------------------------------*/ | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_SIL_Init | ||||||
|  | * Description    : Initialize the USB Device IP and the Endpoint 0. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Status. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint32_t USB_SIL_Init(void) | ||||||
|  | { | ||||||
|  |   /* USB interrupts initialization */ | ||||||
|  |   /* clear pending interrupts */ | ||||||
|  |   _SetISTR(0); | ||||||
|  |   wInterrupt_Mask = IMR_MSK; | ||||||
|  |   /* set interrupts mask */ | ||||||
|  |   _SetCNTR(wInterrupt_Mask); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_SIL_Write | ||||||
|  | * Description    : Write a buffer of data to a selected endpoint. | ||||||
|  | * Input          : - bEpAddr: The address of the non control endpoint. | ||||||
|  | *                  - pBufferPointer: The pointer to the buffer of data to be written | ||||||
|  | *                    to the endpoint. | ||||||
|  | *                  - wBufferSize: Number of data to be written (in bytes). | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Status. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize) | ||||||
|  | { | ||||||
|  |   /* Use the memory interface function to write to the selected endpoint */ | ||||||
|  |   UserToPMABufferCopy(pBufferPointer, GetEPTxAddr(bEpAddr & 0x7F), wBufferSize); | ||||||
|  | 
 | ||||||
|  |   /* Update the data length in the control register */ | ||||||
|  |   SetEPTxCount((bEpAddr & 0x7F), wBufferSize); | ||||||
|  |    | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_SIL_Read | ||||||
|  | * Description    : Write a buffer of data to a selected endpoint. | ||||||
|  | * Input          : - bEpAddr: The address of the non control endpoint. | ||||||
|  | *                  - pBufferPointer: The pointer to which will be saved the  | ||||||
|  | *                     received data buffer. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Number of received data (in Bytes). | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer) | ||||||
|  | { | ||||||
|  |   uint32_t DataLength = 0; | ||||||
|  | 
 | ||||||
|  |   /* Get the number of received data on the selected Endpoint */ | ||||||
|  |   DataLength = GetEPRxCount(bEpAddr & 0x7F); | ||||||
|  |    | ||||||
|  |   /* Use the memory interface function to write to the selected endpoint */ | ||||||
|  |   PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength); | ||||||
|  | 
 | ||||||
|  |   /* Return the number of received data */ | ||||||
|  |   return DataLength; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										47
									
								
								fw_dc22_stm32l100/src/usb/core/usb_sil.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								fw_dc22_stm32l100/src/usb/core/usb_sil.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_sil.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Simplified Interface Layer function prototypes. | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_SIL_H | ||||||
|  | #define __USB_SIL_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | uint32_t USB_SIL_Init(void); | ||||||
|  | uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize); | ||||||
|  | uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer); | ||||||
|  | 
 | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_SIL_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										54
									
								
								fw_dc22_stm32l100/src/usb/core/usb_type.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								fw_dc22_stm32l100/src/usb/core/usb_type.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_type.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    28-August-2012 | ||||||
|  |   * @brief   Type definitions used by the USB Library | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_TYPE_H | ||||||
|  | #define __USB_TYPE_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "usb_conf.h" | ||||||
|  | 
 | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | #ifndef NULL | ||||||
|  | #define NULL ((void *)0) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | typedef enum | ||||||
|  | { | ||||||
|  |   FALSE = 0, TRUE  = !FALSE | ||||||
|  | } | ||||||
|  | bool; | ||||||
|  | 
 | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_TYPE_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										489
									
								
								fw_dc22_stm32l100/src/usb/glue.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										489
									
								
								fw_dc22_stm32l100/src/usb/glue.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,489 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    hw_config.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   Hardware Configuration & Setup | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #include <stm32l1xx.h> | ||||||
|  | #include "core/usb_lib.h" | ||||||
|  | #include "usb_prop.h" | ||||||
|  | #include "usb_desc.h" | ||||||
|  | #include "glue.h" | ||||||
|  | #include "usb_pwr.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | ErrorStatus HSEStartUpStatus; | ||||||
|  | static USART_InitTypeDef USART_InitStructure; | ||||||
|  | 
 | ||||||
|  | uint8_t  USART_Rx_Buffer[USART_RX_DATA_SIZE]; | ||||||
|  | uint32_t USART_Rx_ptr_in = 0; | ||||||
|  | uint32_t USART_Rx_ptr_out = 0; | ||||||
|  | uint32_t USART_Rx_length  = 0; | ||||||
|  | 
 | ||||||
|  | uint8_t  USB_Tx_State = 0; | ||||||
|  | static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len); | ||||||
|  | /* Extern variables ----------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | extern LINE_CODING linecoding; | ||||||
|  | 
 | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Set_System | ||||||
|  | * Description    : Configures Main system clocks & power | ||||||
|  | * Input          : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USB_Init_System(void) | ||||||
|  | { | ||||||
|  |   // GPIO_InitTypeDef GPIO_InitStructure;
 | ||||||
|  | 
 | ||||||
|  |   /*!< At this stage the microcontroller clock setting is already configured, 
 | ||||||
|  |        this is done through SystemInit() function which is called from startup | ||||||
|  |        file (startup_stm32f10x_xx.s) before to branch to application main. | ||||||
|  |        To reconfigure the default setting of SystemInit() function, refer to | ||||||
|  |        system_stm32f10x.c file | ||||||
|  |      */    | ||||||
|  | 
 | ||||||
|  |   /* lets us configure the USB pullup */ | ||||||
|  |   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); | ||||||
|  | 
 | ||||||
|  |   /*Set PA11,12 as IN - USB_DM,DP*/ | ||||||
|  |   // note: doing this actually seems to BREAK USB, keep it as default
 | ||||||
|  |   /*
 | ||||||
|  |   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); | ||||||
|  |   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12; | ||||||
|  |   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; | ||||||
|  |   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; | ||||||
|  |   GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; | ||||||
|  |   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; | ||||||
|  |   GPIO_Init(GPIOA, &GPIO_InitStructure); | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  |   /*SET PA11,12 for USB: USB_DM,DP*/ | ||||||
|  |   // also unnecessary in practice
 | ||||||
|  |   /*
 | ||||||
|  |   GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_USB); | ||||||
|  |   GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_USB); | ||||||
|  |   */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Set_USBClock | ||||||
|  | * Description    : Configures USB Clock input (48MHz) | ||||||
|  | * Input          : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USB_ClockEna(void) | ||||||
|  | { | ||||||
|  |   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Enter_LowPowerMode | ||||||
|  | * Description    : Power-off system clocks and power while entering suspend mode | ||||||
|  | * Input          : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Enter_LowPowerMode(void) | ||||||
|  | { | ||||||
|  |   /* Set the device state to suspend */ | ||||||
|  |   bDeviceState = SUSPENDED; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Leave_LowPowerMode | ||||||
|  | * Description    : Restores system clocks and power while exiting suspend mode | ||||||
|  | * Input          : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Leave_LowPowerMode(void) | ||||||
|  | { | ||||||
|  |   DEVICE_INFO *pInfo = &Device_Info; | ||||||
|  | 
 | ||||||
|  |   /* Set the device state to the correct state */ | ||||||
|  |   if (pInfo->Current_Configuration != 0) | ||||||
|  |   { | ||||||
|  |     /* Device configured */ | ||||||
|  |     bDeviceState = CONFIGURED; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     bDeviceState = ATTACHED; | ||||||
|  |   } | ||||||
|  |   /*Enable SystemCoreClock*/ | ||||||
|  |   SystemInit(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_Interrupts_Config | ||||||
|  | * Description    : Configures the USB interrupts | ||||||
|  | * Input          : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USB_Interrupts_Config(void) | ||||||
|  | { | ||||||
|  |   NVIC_InitTypeDef NVIC_InitStructure; | ||||||
|  |   EXTI_InitTypeDef EXTI_InitStructure; | ||||||
|  |    | ||||||
|  |   /* 2 bit for pre-emption priority, 2 bits for subpriority */ | ||||||
|  |   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); | ||||||
|  |    | ||||||
|  |   /* set up USB low priority interrupt */ | ||||||
|  |   NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQn; | ||||||
|  |   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; | ||||||
|  |   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; | ||||||
|  |   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; | ||||||
|  |   NVIC_Init(&NVIC_InitStructure); | ||||||
|  |    | ||||||
|  |   /* Enable the USB Wake-up interrupt */ | ||||||
|  |   NVIC_InitStructure.NVIC_IRQChannel = USB_FS_WKUP_IRQn; | ||||||
|  |   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; | ||||||
|  |   NVIC_Init(&NVIC_InitStructure); | ||||||
|  | 
 | ||||||
|  |   /* Enable USART Interrupt */ | ||||||
|  |   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; | ||||||
|  |   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; | ||||||
|  |   NVIC_Init(&NVIC_InitStructure); | ||||||
|  | 
 | ||||||
|  |   /* Configure the EXTI line 18 connected internally to the USB IP */ | ||||||
|  |   EXTI_ClearITPendingBit(EXTI_Line18); | ||||||
|  |   EXTI_InitStructure.EXTI_Line = EXTI_Line18; | ||||||
|  |   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; | ||||||
|  |   EXTI_InitStructure.EXTI_LineCmd = ENABLE; | ||||||
|  |   EXTI_Init(&EXTI_InitStructure); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_Cable_Config | ||||||
|  | * Description    : Software Connection/Disconnection of USB Cable | ||||||
|  | * Input          : None. | ||||||
|  | * Return         : Status | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USB_Cable_Config(FunctionalState NewState) | ||||||
|  | { | ||||||
|  |   if (NewState == DISABLE) { | ||||||
|  | 	  SYSCFG_USBPuCmd(DISABLE); | ||||||
|  |   } else { | ||||||
|  | 	  SYSCFG_USBPuCmd(ENABLE); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  :  USART_Config_Default. | ||||||
|  | * Description    :  configure the EVAL_COM1 with default values. | ||||||
|  | * Input          :  None. | ||||||
|  | * Return         :  None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USART_Config_Default(void) | ||||||
|  | { | ||||||
|  |   GPIO_InitTypeDef gpio; | ||||||
|  | 
 | ||||||
|  |   /* EVAL_COM1 default configuration */ | ||||||
|  |   /* EVAL_COM1 configured as follow:
 | ||||||
|  |         - BaudRate = 115200 baud | ||||||
|  |         - Word Length = 8 Bits | ||||||
|  |         - One Stop Bit | ||||||
|  |         - Parity None | ||||||
|  |         - Hardware flow control disabled | ||||||
|  |         - Receive and transmit enabled | ||||||
|  |   */ | ||||||
|  |   USART_InitStructure.USART_BaudRate = 115200; | ||||||
|  |   USART_InitStructure.USART_WordLength = USART_WordLength_8b; | ||||||
|  |   USART_InitStructure.USART_StopBits = USART_StopBits_1; | ||||||
|  |   USART_InitStructure.USART_Parity = USART_Parity_No; | ||||||
|  |   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; | ||||||
|  |   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; | ||||||
|  | 
 | ||||||
|  |   /* Turn on USART clock */ | ||||||
|  |   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); | ||||||
|  | 
 | ||||||
|  |   /* Set up the USART pins */ | ||||||
|  |   GPIO_PinAFConfig(GPIOA,  GPIO_PinSource9, GPIO_AF_USART1); | ||||||
|  |   GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); | ||||||
|  | 
 | ||||||
|  |   /* Configure USART GPIO */ | ||||||
|  |   gpio.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; | ||||||
|  |   gpio.GPIO_Mode = GPIO_Mode_AF; | ||||||
|  |   gpio.GPIO_OType = GPIO_OType_PP; | ||||||
|  |   gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; | ||||||
|  |   gpio.GPIO_Speed = GPIO_Speed_2MHz; | ||||||
|  |   GPIO_Init(GPIOA, &gpio); | ||||||
|  | 
 | ||||||
|  |   /* Configure and enable the USART */ | ||||||
|  |   USART_Init(USART1, &USART_InitStructure); | ||||||
|  |   USART_Cmd(USART1, ENABLE); | ||||||
|  | 
 | ||||||
|  |   /* Enable the USART Receive interrupt */ | ||||||
|  |   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  :  USART_Config. | ||||||
|  | * Description    :  Configure the EVAL_COM1 according to the line coding structure. | ||||||
|  | * Input          :  None. | ||||||
|  | * Return         :  Configuration status | ||||||
|  |                     TRUE : configuration done with success | ||||||
|  |                     FALSE : configuration aborted. | ||||||
|  | *******************************************************************************/ | ||||||
|  | bool USART_Config(void) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |   /* set the Stop bit*/ | ||||||
|  |   switch (linecoding.format) | ||||||
|  |   { | ||||||
|  |     case 0: | ||||||
|  |       USART_InitStructure.USART_StopBits = USART_StopBits_1; | ||||||
|  |       break; | ||||||
|  |     case 1: | ||||||
|  |       USART_InitStructure.USART_StopBits = USART_StopBits_1_5; | ||||||
|  |       break; | ||||||
|  |     case 2: | ||||||
|  |       USART_InitStructure.USART_StopBits = USART_StopBits_2; | ||||||
|  |       break; | ||||||
|  |     default : | ||||||
|  |     { | ||||||
|  |       USART_Config_Default(); | ||||||
|  |       return (FALSE); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /* set the parity bit*/ | ||||||
|  |   switch (linecoding.paritytype) | ||||||
|  |   { | ||||||
|  |     case 0: | ||||||
|  |       USART_InitStructure.USART_Parity = USART_Parity_No; | ||||||
|  |       break; | ||||||
|  |     case 1: | ||||||
|  |       USART_InitStructure.USART_Parity = USART_Parity_Even; | ||||||
|  |       break; | ||||||
|  |     case 2: | ||||||
|  |       USART_InitStructure.USART_Parity = USART_Parity_Odd; | ||||||
|  |       break; | ||||||
|  |     default : | ||||||
|  |     { | ||||||
|  |       USART_Config_Default(); | ||||||
|  |       return (FALSE); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /*set the data type : only 8bits and 9bits is supported */ | ||||||
|  |   switch (linecoding.datatype) | ||||||
|  |   { | ||||||
|  |     case 0x07: | ||||||
|  |       /* With this configuration a parity (Even or Odd) should be set */ | ||||||
|  |       USART_InitStructure.USART_WordLength = USART_WordLength_8b; | ||||||
|  |       break; | ||||||
|  |     case 0x08: | ||||||
|  |       if (USART_InitStructure.USART_Parity == USART_Parity_No) | ||||||
|  |       { | ||||||
|  |         USART_InitStructure.USART_WordLength = USART_WordLength_8b; | ||||||
|  |       } | ||||||
|  |       else  | ||||||
|  |       { | ||||||
|  |         USART_InitStructure.USART_WordLength = USART_WordLength_9b; | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |       break; | ||||||
|  |     default : | ||||||
|  |     { | ||||||
|  |       USART_Config_Default(); | ||||||
|  |       return (FALSE); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   USART_InitStructure.USART_BaudRate = linecoding.bitrate; | ||||||
|  |   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; | ||||||
|  |   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; | ||||||
|  |   | ||||||
|  |   /* Configure and enable the USART */ | ||||||
|  |   USART_Init(USART1, &USART_InitStructure); | ||||||
|  | 
 | ||||||
|  |   return (TRUE); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_To_USART_Send_Data. | ||||||
|  | * Description    : send the received data from USB to the UART 0. | ||||||
|  | * Input          : data_buffer: data address. | ||||||
|  |                    Nb_bytes: number of bytes to send. | ||||||
|  | * Return         : none. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USB_To_USART_Send_Data(uint8_t* data_buffer, uint8_t Nb_bytes) | ||||||
|  | { | ||||||
|  |    | ||||||
|  |   uint32_t i; | ||||||
|  |    | ||||||
|  |   for (i = 0; i < Nb_bytes; i++) | ||||||
|  |   { | ||||||
|  |     USART_SendData(USART1, *(data_buffer + i)); | ||||||
|  |     while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); | ||||||
|  |   }   | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Handle_USBAsynchXfer. | ||||||
|  | * Description    : send data to USB. | ||||||
|  | * Input          : None. | ||||||
|  | * Return         : none. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Handle_USBAsynchXfer (void) | ||||||
|  | { | ||||||
|  |    | ||||||
|  |   uint16_t USB_Tx_ptr; | ||||||
|  |   uint16_t USB_Tx_length; | ||||||
|  |    | ||||||
|  |   if(USB_Tx_State != 1) | ||||||
|  |   { | ||||||
|  |     if (USART_Rx_ptr_out == USART_RX_DATA_SIZE) | ||||||
|  |     { | ||||||
|  |       USART_Rx_ptr_out = 0; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if(USART_Rx_ptr_out == USART_Rx_ptr_in)  | ||||||
|  |     { | ||||||
|  |       USB_Tx_State = 0;  | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if(USART_Rx_ptr_out > USART_Rx_ptr_in) /* rollback */ | ||||||
|  |     {  | ||||||
|  |       USART_Rx_length = USART_RX_DATA_SIZE - USART_Rx_ptr_out; | ||||||
|  |     } | ||||||
|  |     else  | ||||||
|  |     { | ||||||
|  |       USART_Rx_length = USART_Rx_ptr_in - USART_Rx_ptr_out; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if (USART_Rx_length > VIRTUAL_COM_PORT_DATA_SIZE) | ||||||
|  |     { | ||||||
|  |       USB_Tx_ptr = USART_Rx_ptr_out; | ||||||
|  |       USB_Tx_length = VIRTUAL_COM_PORT_DATA_SIZE; | ||||||
|  |        | ||||||
|  |       USART_Rx_ptr_out += VIRTUAL_COM_PORT_DATA_SIZE;	 | ||||||
|  |       USART_Rx_length -= VIRTUAL_COM_PORT_DATA_SIZE;	 | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       USB_Tx_ptr = USART_Rx_ptr_out; | ||||||
|  |       USB_Tx_length = USART_Rx_length; | ||||||
|  |        | ||||||
|  |       USART_Rx_ptr_out += USART_Rx_length; | ||||||
|  |       USART_Rx_length = 0; | ||||||
|  |     } | ||||||
|  |     USB_Tx_State = 1;  | ||||||
|  |     UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length); | ||||||
|  |     SetEPTxCount(ENDP1, USB_Tx_length); | ||||||
|  |     SetEPTxValid(ENDP1);  | ||||||
|  |   }   | ||||||
|  |    | ||||||
|  | } | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : UART_To_USB_Send_Data. | ||||||
|  | * Description    : send the received data from UART 0 to USB. | ||||||
|  | * Input          : None. | ||||||
|  | * Return         : none. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USART_To_USB_Send_Data(void) | ||||||
|  | { | ||||||
|  |    | ||||||
|  |   if (linecoding.datatype == 7) | ||||||
|  |   { | ||||||
|  |     USART_Rx_Buffer[USART_Rx_ptr_in] = USART_ReceiveData(USART1) & 0x7F; | ||||||
|  |   } | ||||||
|  |   else if (linecoding.datatype == 8) | ||||||
|  |   { | ||||||
|  |     USART_Rx_Buffer[USART_Rx_ptr_in] = USART_ReceiveData(USART1); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   USART_Rx_ptr_in++; | ||||||
|  |    | ||||||
|  |   /* To avoid buffer overflow */ | ||||||
|  |   if(USART_Rx_ptr_in == USART_RX_DATA_SIZE) | ||||||
|  |   { | ||||||
|  |     USART_Rx_ptr_in = 0; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Get_SerialNum. | ||||||
|  | * Description    : Create the serial number string descriptor. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Get_SerialNum(void) | ||||||
|  | { | ||||||
|  |   uint32_t Device_Serial0, Device_Serial1, Device_Serial2; | ||||||
|  | 
 | ||||||
|  |   Device_Serial0 = *(uint32_t*)ID1; | ||||||
|  |   Device_Serial1 = *(uint32_t*)ID2; | ||||||
|  |   Device_Serial2 = *(uint32_t*)ID3;   | ||||||
|  | 
 | ||||||
|  |   Device_Serial0 += Device_Serial2; | ||||||
|  | 
 | ||||||
|  |   if (Device_Serial0 != 0) | ||||||
|  |   { | ||||||
|  |     IntToUnicode (Device_Serial0, &Virtual_Com_Port_StringSerial[2] , 8); | ||||||
|  |     IntToUnicode (Device_Serial1, &Virtual_Com_Port_StringSerial[18], 4); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : HexToChar. | ||||||
|  | * Description    : Convert Hex 32Bits value into char. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len) | ||||||
|  | { | ||||||
|  |   uint8_t idx = 0; | ||||||
|  |    | ||||||
|  |   for( idx = 0 ; idx < len ; idx ++) | ||||||
|  |   { | ||||||
|  |     if( ((value >> 28)) < 0xA ) | ||||||
|  |     { | ||||||
|  |       pbuf[ 2* idx] = (value >> 28) + '0'; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       pbuf[2* idx] = (value >> 28) + 'A' - 10;  | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     value = value << 4; | ||||||
|  |      | ||||||
|  |     pbuf[ 2* idx + 1] = 0; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										66
									
								
								fw_dc22_stm32l100/src/usb/glue.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								fw_dc22_stm32l100/src/usb/glue.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    hw_config.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   Hardware Configuration & Setup | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __HW_CONFIG_H | ||||||
|  | #define __HW_CONFIG_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "core/usb_type.h" | ||||||
|  | 
 | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported define -----------------------------------------------------------*/ | ||||||
|  | #define MASS_MEMORY_START     0x04002000 | ||||||
|  | #define BULK_MAX_PACKET_SIZE  0x00000040 | ||||||
|  | 
 | ||||||
|  | #define USART_RX_DATA_SIZE    1024 | ||||||
|  | 
 | ||||||
|  | #define         ID1          (0x1FF80050) | ||||||
|  | #define         ID2          (0x1FF80054) | ||||||
|  | #define         ID3          (0x1FF80064) | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | void USB_Init_System(void); | ||||||
|  | void USB_ClockEna(void); | ||||||
|  | 
 | ||||||
|  | void Enter_LowPowerMode(void); | ||||||
|  | void Leave_LowPowerMode(void); | ||||||
|  | void USB_Interrupts_Config(void); | ||||||
|  | void USB_Cable_Config (FunctionalState NewState); | ||||||
|  | void USART_Config_Default(void); | ||||||
|  | bool USART_Config(void); | ||||||
|  | void USB_To_USART_Send_Data(uint8_t* data_buffer, uint8_t Nb_bytes); | ||||||
|  | void USART_To_USB_Send_Data(void); | ||||||
|  | void Handle_USBAsynchXfer (void); | ||||||
|  | void Get_SerialNum(void); | ||||||
|  | 
 | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #endif  /*__HW_CONFIG_H*/ | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										50
									
								
								fw_dc22_stm32l100/src/usb/isr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								fw_dc22_stm32l100/src/usb/isr.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | #include <stm32l1xx.h> | ||||||
|  | #include "glue.h" | ||||||
|  | #include "usb_istr.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_IRQHandler | ||||||
|  | * Description    : This function handles USB Low Priority interrupts | ||||||
|  | *                  requests. | ||||||
|  | * Input          : None | ||||||
|  | * Output         : None | ||||||
|  | * Return         : None | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USB_LP_IRQHandler(void) | ||||||
|  | { | ||||||
|  |   USB_Istr(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USART1_IRQHandler | ||||||
|  | * Description    : This function handles USART1 global interrupt request. | ||||||
|  | * Input          : None | ||||||
|  | * Output         : None | ||||||
|  | * Return         : None | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USART1_IRQHandler(void) | ||||||
|  | { | ||||||
|  |   if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) | ||||||
|  |   { | ||||||
|  |     /* Send the received data to the PC Host*/ | ||||||
|  |     USART_To_USB_Send_Data(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /* If overrun condition occurs, clear the ORE flag and recover communication */ | ||||||
|  |   if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) | ||||||
|  |   { | ||||||
|  |     (void)USART_ReceiveData(USART1); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_FS_WKUP_IRQHandler | ||||||
|  | * Description    : This function handles USB WakeUp interrupt request. | ||||||
|  | * Input          : None | ||||||
|  | * Output         : None | ||||||
|  | * Return         : None | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USB_FS_WKUP_IRQHandler(void) | ||||||
|  | { | ||||||
|  |   EXTI_ClearITPendingBit(EXTI_Line18); | ||||||
|  | } | ||||||
							
								
								
									
										174
									
								
								fw_dc22_stm32l100/src/usb/usb_desc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								fw_dc22_stm32l100/src/usb/usb_desc.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,174 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_desc.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   Descriptors for Virtual Com Port Demo | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "core/usb_lib.h" | ||||||
|  | #include "usb_desc.h" | ||||||
|  | 
 | ||||||
|  | /* USB Standard Device Descriptor */ | ||||||
|  | const uint8_t Virtual_Com_Port_DeviceDescriptor[] = | ||||||
|  |   { | ||||||
|  |     0x12,   /* bLength */ | ||||||
|  |     USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */ | ||||||
|  |     0x00, | ||||||
|  |     0x02,   /* bcdUSB = 2.00 */ | ||||||
|  |     0x02,   /* bDeviceClass: CDC */ | ||||||
|  |     0x00,   /* bDeviceSubClass */ | ||||||
|  |     0x00,   /* bDeviceProtocol */ | ||||||
|  |     0x40,   /* bMaxPacketSize0 */ | ||||||
|  |     0xD5, | ||||||
|  |     0xBA,   /* idVendor = 0xBAD5 */ | ||||||
|  |     0x81, | ||||||
|  |     0xAD,   /* idProduct = 0xAD81 */ | ||||||
|  |     0x00, | ||||||
|  |     0x02,   /* bcdDevice = 2.00 */ | ||||||
|  |     1,              /* Index of string descriptor describing vendor */ | ||||||
|  |     2,              /* Index of string descriptor describing product */ | ||||||
|  |     3,              /* Index of string descriptor describing the device's serial number */ | ||||||
|  |     0x01    /* bNumConfigurations */ | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | const uint8_t Virtual_Com_Port_ConfigDescriptor[] = | ||||||
|  |   { | ||||||
|  |     /*Configuration Descriptor*/ | ||||||
|  |     0x09,   /* bLength: Configuration Descriptor size */ | ||||||
|  |     USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */ | ||||||
|  |     VIRTUAL_COM_PORT_SIZ_CONFIG_DESC,       /* wTotalLength:no of returned bytes */ | ||||||
|  |     0x00, | ||||||
|  |     0x02,   /* bNumInterfaces: 2 interface */ | ||||||
|  |     0x01,   /* bConfigurationValue: Configuration value */ | ||||||
|  |     0x00,   /* iConfiguration: Index of string descriptor describing the configuration */ | ||||||
|  |     0xC0,   /* bmAttributes: self powered */ | ||||||
|  |     0x32,   /* MaxPower 0 mA */ | ||||||
|  |     /*Interface Descriptor*/ | ||||||
|  |     0x09,   /* bLength: Interface Descriptor size */ | ||||||
|  |     USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */ | ||||||
|  |     /* Interface descriptor type */ | ||||||
|  |     0x00,   /* bInterfaceNumber: Number of Interface */ | ||||||
|  |     0x00,   /* bAlternateSetting: Alternate setting */ | ||||||
|  |     0x01,   /* bNumEndpoints: One endpoints used */ | ||||||
|  |     0x02,   /* bInterfaceClass: Communication Interface Class */ | ||||||
|  |     0x02,   /* bInterfaceSubClass: Abstract Control Model */ | ||||||
|  |     0x01,   /* bInterfaceProtocol: Common AT commands */ | ||||||
|  |     0x00,   /* iInterface: */ | ||||||
|  |     /*Header Functional Descriptor*/ | ||||||
|  |     0x05,   /* bLength: Endpoint Descriptor size */ | ||||||
|  |     0x24,   /* bDescriptorType: CS_INTERFACE */ | ||||||
|  |     0x00,   /* bDescriptorSubtype: Header Func Desc */ | ||||||
|  |     0x10,   /* bcdCDC: spec release number */ | ||||||
|  |     0x01, | ||||||
|  |     /*Call Management Functional Descriptor*/ | ||||||
|  |     0x05,   /* bFunctionLength */ | ||||||
|  |     0x24,   /* bDescriptorType: CS_INTERFACE */ | ||||||
|  |     0x01,   /* bDescriptorSubtype: Call Management Func Desc */ | ||||||
|  |     0x00,   /* bmCapabilities: D0+D1 */ | ||||||
|  |     0x01,   /* bDataInterface: 1 */ | ||||||
|  |     /*ACM Functional Descriptor*/ | ||||||
|  |     0x04,   /* bFunctionLength */ | ||||||
|  |     0x24,   /* bDescriptorType: CS_INTERFACE */ | ||||||
|  |     0x02,   /* bDescriptorSubtype: Abstract Control Management desc */ | ||||||
|  |     0x02,   /* bmCapabilities */ | ||||||
|  |     /*Union Functional Descriptor*/ | ||||||
|  |     0x05,   /* bFunctionLength */ | ||||||
|  |     0x24,   /* bDescriptorType: CS_INTERFACE */ | ||||||
|  |     0x06,   /* bDescriptorSubtype: Union func desc */ | ||||||
|  |     0x00,   /* bMasterInterface: Communication class interface */ | ||||||
|  |     0x01,   /* bSlaveInterface0: Data Class Interface */ | ||||||
|  |     /*Endpoint 2 Descriptor*/ | ||||||
|  |     0x07,   /* bLength: Endpoint Descriptor size */ | ||||||
|  |     USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */ | ||||||
|  |     0x82,   /* bEndpointAddress: (IN2) */ | ||||||
|  |     0x03,   /* bmAttributes: Interrupt */ | ||||||
|  |     VIRTUAL_COM_PORT_INT_SIZE,      /* wMaxPacketSize: */ | ||||||
|  |     0x00, | ||||||
|  |     0xFF,   /* bInterval: */ | ||||||
|  |     /*Data class interface descriptor*/ | ||||||
|  |     0x09,   /* bLength: Endpoint Descriptor size */ | ||||||
|  |     USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */ | ||||||
|  |     0x01,   /* bInterfaceNumber: Number of Interface */ | ||||||
|  |     0x00,   /* bAlternateSetting: Alternate setting */ | ||||||
|  |     0x02,   /* bNumEndpoints: Two endpoints used */ | ||||||
|  |     0x0A,   /* bInterfaceClass: CDC */ | ||||||
|  |     0x00,   /* bInterfaceSubClass: */ | ||||||
|  |     0x00,   /* bInterfaceProtocol: */ | ||||||
|  |     0x00,   /* iInterface: */ | ||||||
|  |     /*Endpoint 3 Descriptor*/ | ||||||
|  |     0x07,   /* bLength: Endpoint Descriptor size */ | ||||||
|  |     USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */ | ||||||
|  |     0x03,   /* bEndpointAddress: (OUT3) */ | ||||||
|  |     0x02,   /* bmAttributes: Bulk */ | ||||||
|  |     VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */ | ||||||
|  |     0x00, | ||||||
|  |     0x00,   /* bInterval: ignore for Bulk transfer */ | ||||||
|  |     /*Endpoint 1 Descriptor*/ | ||||||
|  |     0x07,   /* bLength: Endpoint Descriptor size */ | ||||||
|  |     USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */ | ||||||
|  |     0x81,   /* bEndpointAddress: (IN1) */ | ||||||
|  |     0x02,   /* bmAttributes: Bulk */ | ||||||
|  |     VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */ | ||||||
|  |     0x00, | ||||||
|  |     0x00    /* bInterval */ | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | /* USB String Descriptors */ | ||||||
|  | const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID] = | ||||||
|  |   { | ||||||
|  |     VIRTUAL_COM_PORT_SIZ_STRING_LANGID, | ||||||
|  |     USB_STRING_DESCRIPTOR_TYPE, | ||||||
|  |     0x09, | ||||||
|  |     0x04 /* LangID = 0x0409: U.S. English */ | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR] = | ||||||
|  |   { | ||||||
|  |     VIRTUAL_COM_PORT_SIZ_STRING_VENDOR,     /* Size of Vendor string */ | ||||||
|  |     USB_STRING_DESCRIPTOR_TYPE,             /* bDescriptorType*/ | ||||||
|  |     /* Manufacturer: "STMicroelectronics" */ | ||||||
|  |     't', 0, 'r', 0, 'u', 0, 'e', 0, 'C', 0, 'o', 0, 'n', 0, 't', 0, | ||||||
|  |     'r', 0, 'o', 0, 'l', 0, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT] = | ||||||
|  |   { | ||||||
|  |     VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT,          /* bLength */ | ||||||
|  |     USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */ | ||||||
|  |     /* Product name: "STM32 Virtual COM Port" */ | ||||||
|  |     'W', 0, 'P', 0, ' ', 0, 'D', 0, 'C', 0, '2', 0, '2', 0, ' ', 0, | ||||||
|  |     'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0, 'a', 0, 'l', 0, ' ', 0, | ||||||
|  |     'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0, ' ', 0, | ||||||
|  |     'P', 0, 'o', 0, 'r', 0, 't', 0, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] = | ||||||
|  |   { | ||||||
|  |     VIRTUAL_COM_PORT_SIZ_STRING_SERIAL,           /* bLength */ | ||||||
|  |     USB_STRING_DESCRIPTOR_TYPE,                   /* bDescriptorType */ | ||||||
|  |     '0', 0, '0', 0, '0', 0, '1', 0, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										66
									
								
								fw_dc22_stm32l100/src/usb/usb_desc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								fw_dc22_stm32l100/src/usb/usb_desc.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_desc.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   Descriptor Header for Virtual COM Port Device | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_DESC_H | ||||||
|  | #define __USB_DESC_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported define -----------------------------------------------------------*/ | ||||||
|  | #define USB_DEVICE_DESCRIPTOR_TYPE              0x01 | ||||||
|  | #define USB_CONFIGURATION_DESCRIPTOR_TYPE       0x02 | ||||||
|  | #define USB_STRING_DESCRIPTOR_TYPE              0x03 | ||||||
|  | #define USB_INTERFACE_DESCRIPTOR_TYPE           0x04 | ||||||
|  | #define USB_ENDPOINT_DESCRIPTOR_TYPE            0x05 | ||||||
|  | 
 | ||||||
|  | #define VIRTUAL_COM_PORT_DATA_SIZE              64 | ||||||
|  | #define VIRTUAL_COM_PORT_INT_SIZE               8 | ||||||
|  | 
 | ||||||
|  | #define VIRTUAL_COM_PORT_SIZ_DEVICE_DESC        18 | ||||||
|  | #define VIRTUAL_COM_PORT_SIZ_CONFIG_DESC        67 | ||||||
|  | #define VIRTUAL_COM_PORT_SIZ_STRING_LANGID      4 | ||||||
|  | #define VIRTUAL_COM_PORT_SIZ_STRING_VENDOR      24 | ||||||
|  | #define VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT     56 | ||||||
|  | #define VIRTUAL_COM_PORT_SIZ_STRING_SERIAL      26 | ||||||
|  | 
 | ||||||
|  | #define STANDARD_ENDPOINT_DESC_SIZE             0x09 | ||||||
|  | 
 | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | extern const uint8_t Virtual_Com_Port_DeviceDescriptor[VIRTUAL_COM_PORT_SIZ_DEVICE_DESC]; | ||||||
|  | extern const uint8_t Virtual_Com_Port_ConfigDescriptor[VIRTUAL_COM_PORT_SIZ_CONFIG_DESC]; | ||||||
|  | 
 | ||||||
|  | extern const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID]; | ||||||
|  | extern const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR]; | ||||||
|  | extern const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT]; | ||||||
|  | extern uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL]; | ||||||
|  | 
 | ||||||
|  | #endif /* __USB_DESC_H */ | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										144
									
								
								fw_dc22_stm32l100/src/usb/usb_endp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								fw_dc22_stm32l100/src/usb/usb_endp.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,144 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_endp.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   Endpoint routines | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "core/usb_lib.h" | ||||||
|  | #include "usb_desc.h" | ||||||
|  | #include "core/usb_mem.h" | ||||||
|  | #include "usb_istr.h" | ||||||
|  | #include "usb_pwr.h" | ||||||
|  | #include "glue.h" | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /* Interval between sending IN packets in frame number (1 frame = 1ms) */ | ||||||
|  | #define VCOMPORT_IN_FRAME_INTERVAL             5 | ||||||
|  | 
 | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | uint8_t USB_Rx_Buffer[VIRTUAL_COM_PORT_DATA_SIZE]; | ||||||
|  | extern  uint8_t USART_Rx_Buffer[]; | ||||||
|  | extern uint32_t USART_Rx_ptr_out; | ||||||
|  | extern uint32_t USART_Rx_length; | ||||||
|  | extern uint8_t  USB_Tx_State; | ||||||
|  | 
 | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : EP1_IN_Callback | ||||||
|  | * Description    : | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void EP1_IN_Callback (void) | ||||||
|  | { | ||||||
|  |   uint16_t USB_Tx_ptr; | ||||||
|  |   uint16_t USB_Tx_length; | ||||||
|  |    | ||||||
|  |   if (USB_Tx_State == 1) | ||||||
|  |   { | ||||||
|  |     if (USART_Rx_length == 0)  | ||||||
|  |     { | ||||||
|  |       USB_Tx_State = 0; | ||||||
|  |     } | ||||||
|  |     else  | ||||||
|  |     { | ||||||
|  |       if (USART_Rx_length > VIRTUAL_COM_PORT_DATA_SIZE){ | ||||||
|  |         USB_Tx_ptr = USART_Rx_ptr_out; | ||||||
|  |         USB_Tx_length = VIRTUAL_COM_PORT_DATA_SIZE; | ||||||
|  |          | ||||||
|  |         USART_Rx_ptr_out += VIRTUAL_COM_PORT_DATA_SIZE; | ||||||
|  |         USART_Rx_length -= VIRTUAL_COM_PORT_DATA_SIZE;     | ||||||
|  |       } | ||||||
|  |       else  | ||||||
|  |       { | ||||||
|  |         USB_Tx_ptr = USART_Rx_ptr_out; | ||||||
|  |         USB_Tx_length = USART_Rx_length; | ||||||
|  |          | ||||||
|  |         USART_Rx_ptr_out += USART_Rx_length; | ||||||
|  |         USART_Rx_length = 0; | ||||||
|  |       } | ||||||
|  |       UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length); | ||||||
|  |       SetEPTxCount(ENDP1, USB_Tx_length); | ||||||
|  |       SetEPTxValid(ENDP1);  | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : EP3_OUT_Callback | ||||||
|  | * Description    : | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void EP3_OUT_Callback(void) | ||||||
|  | { | ||||||
|  |   uint16_t USB_Rx_Cnt; | ||||||
|  |    | ||||||
|  |   /* Get the received data buffer and update the counter */ | ||||||
|  |   USB_Rx_Cnt = USB_SIL_Read(EP3_OUT, USB_Rx_Buffer); | ||||||
|  |    | ||||||
|  |   /* USB data will be immediately processed, this allow next USB traffic being 
 | ||||||
|  |   NAKed till the end of the USART Xfer */ | ||||||
|  |    | ||||||
|  |   USB_To_USART_Send_Data(USB_Rx_Buffer, USB_Rx_Cnt); | ||||||
|  |   | ||||||
|  |   /* Enable the receive of data on EP3 */ | ||||||
|  |   SetEPRxValid(ENDP3); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : SOF_Callback / INTR_SOFINTR_Callback | ||||||
|  | * Description    : | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void SOF_Callback(void) | ||||||
|  | { | ||||||
|  |   static uint32_t FrameCount = 0; | ||||||
|  |    | ||||||
|  |   if(bDeviceState == CONFIGURED) | ||||||
|  |   { | ||||||
|  |     if (FrameCount++ == VCOMPORT_IN_FRAME_INTERVAL) | ||||||
|  |     { | ||||||
|  |       /* Reset the frame counter */ | ||||||
|  |       FrameCount = 0; | ||||||
|  |        | ||||||
|  |       /* Check the data to be sent through IN pipe */ | ||||||
|  |       Handle_USBAsynchXfer(); | ||||||
|  |     } | ||||||
|  |   }   | ||||||
|  | } | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
|  | 
 | ||||||
							
								
								
									
										235
									
								
								fw_dc22_stm32l100/src/usb/usb_istr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								fw_dc22_stm32l100/src/usb/usb_istr.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,235 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_istr.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   ISTR events interrupt service routines | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "core/usb_lib.h" | ||||||
|  | #include "usb_prop.h" | ||||||
|  | #include "usb_pwr.h" | ||||||
|  | #include "usb_istr.h" | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | __IO uint16_t wIstr;  /* ISTR register last read value */ | ||||||
|  | __IO uint8_t bIntPackSOF = 0;  /* SOFs received between 2 consecutive packets */ | ||||||
|  | __IO uint32_t esof_counter =0; /* expected SOF counter */ | ||||||
|  | __IO uint32_t wCNTR=0; | ||||||
|  | 
 | ||||||
|  | /* Extern variables ----------------------------------------------------------*/ | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | /* function pointers to non-control endpoints service routines */ | ||||||
|  | void (*pEpInt_IN[7])(void) = | ||||||
|  |   { | ||||||
|  |     EP1_IN_Callback, | ||||||
|  |     EP2_IN_Callback, | ||||||
|  |     EP3_IN_Callback, | ||||||
|  |     EP4_IN_Callback, | ||||||
|  |     EP5_IN_Callback, | ||||||
|  |     EP6_IN_Callback, | ||||||
|  |     EP7_IN_Callback, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | void (*pEpInt_OUT[7])(void) = | ||||||
|  |   { | ||||||
|  |     EP1_OUT_Callback, | ||||||
|  |     EP2_OUT_Callback, | ||||||
|  |     EP3_OUT_Callback, | ||||||
|  |     EP4_OUT_Callback, | ||||||
|  |     EP5_OUT_Callback, | ||||||
|  |     EP6_OUT_Callback, | ||||||
|  |     EP7_OUT_Callback, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : USB_Istr | ||||||
|  | * Description    : ISTR events interrupt service routine | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void USB_Istr(void) | ||||||
|  | { | ||||||
|  | #if (IMR_MSK & ISTR_ESOF) | ||||||
|  |   uint32_t i=0; | ||||||
|  |   __IO uint32_t EP[8]; | ||||||
|  | #endif | ||||||
|  |    | ||||||
|  |   wIstr = _GetISTR(); | ||||||
|  | 
 | ||||||
|  | #if (IMR_MSK & ISTR_SOF) | ||||||
|  |   if (wIstr & ISTR_SOF & wInterrupt_Mask) | ||||||
|  |   { | ||||||
|  |     _SetISTR((uint16_t)CLR_SOF); | ||||||
|  |     bIntPackSOF++; | ||||||
|  | 
 | ||||||
|  | #ifdef SOF_CALLBACK | ||||||
|  |     SOF_Callback(); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/   | ||||||
|  |    | ||||||
|  | #if (IMR_MSK & ISTR_CTR) | ||||||
|  |   if (wIstr & ISTR_CTR & wInterrupt_Mask) | ||||||
|  |   { | ||||||
|  |     /* servicing of the endpoint correct transfer interrupt */ | ||||||
|  |     /* clear of the CTR flag into the sub */ | ||||||
|  |     CTR_LP(); | ||||||
|  | #ifdef CTR_CALLBACK | ||||||
|  |     CTR_Callback(); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/   | ||||||
|  | #if (IMR_MSK & ISTR_RESET) | ||||||
|  |   if (wIstr & ISTR_RESET & wInterrupt_Mask) | ||||||
|  |   { | ||||||
|  |     _SetISTR((uint16_t)CLR_RESET); | ||||||
|  |     Device_Property.Reset(); | ||||||
|  | #ifdef RESET_CALLBACK | ||||||
|  |     RESET_Callback(); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ | ||||||
|  | #if (IMR_MSK & ISTR_DOVR) | ||||||
|  |   if (wIstr & ISTR_DOVR & wInterrupt_Mask) | ||||||
|  |   { | ||||||
|  |     _SetISTR((uint16_t)CLR_DOVR); | ||||||
|  | #ifdef DOVR_CALLBACK | ||||||
|  |     DOVR_Callback(); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ | ||||||
|  | #if (IMR_MSK & ISTR_ERR) | ||||||
|  |   if (wIstr & ISTR_ERR & wInterrupt_Mask) | ||||||
|  |   { | ||||||
|  |     _SetISTR((uint16_t)CLR_ERR); | ||||||
|  | #ifdef ERR_CALLBACK | ||||||
|  |     ERR_Callback(); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ | ||||||
|  | #if (IMR_MSK & ISTR_WKUP) | ||||||
|  |   if (wIstr & ISTR_WKUP & wInterrupt_Mask) | ||||||
|  |   { | ||||||
|  |     _SetISTR((uint16_t)CLR_WKUP); | ||||||
|  |     Resume(RESUME_EXTERNAL); | ||||||
|  | #ifdef WKUP_CALLBACK | ||||||
|  |     WKUP_Callback(); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ | ||||||
|  | #if (IMR_MSK & ISTR_SUSP) | ||||||
|  |   if (wIstr & ISTR_SUSP & wInterrupt_Mask) | ||||||
|  |   { | ||||||
|  | 
 | ||||||
|  |     /* check if SUSPEND is possible */ | ||||||
|  |     if (fSuspendEnabled) | ||||||
|  |     { | ||||||
|  |       Suspend(); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       /* if not possible then resume after xx ms */ | ||||||
|  |       Resume(RESUME_LATER); | ||||||
|  |     } | ||||||
|  |     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ | ||||||
|  |     _SetISTR((uint16_t)CLR_SUSP); | ||||||
|  | #ifdef SUSP_CALLBACK | ||||||
|  |     SUSP_Callback(); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |   /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ | ||||||
|  | 
 | ||||||
|  | #if (IMR_MSK & ISTR_ESOF) | ||||||
|  |   if (wIstr & ISTR_ESOF & wInterrupt_Mask) | ||||||
|  |   { | ||||||
|  |     /* clear ESOF flag in ISTR */ | ||||||
|  |     _SetISTR((uint16_t)CLR_ESOF); | ||||||
|  |      | ||||||
|  |     if ((_GetFNR()&FNR_RXDP)!=0) | ||||||
|  |     { | ||||||
|  |       /* increment ESOF counter */ | ||||||
|  |       esof_counter ++; | ||||||
|  |        | ||||||
|  |       /* test if we enter in ESOF more than 3 times with FSUSP =0 and RXDP =1=>> possible missing SUSP flag*/ | ||||||
|  |       if ((esof_counter >3)&&((_GetCNTR()&CNTR_FSUSP)==0)) | ||||||
|  |       {            | ||||||
|  |         /* this a sequence to apply a force RESET*/ | ||||||
|  |        | ||||||
|  |         /*Store CNTR value */ | ||||||
|  |         wCNTR = _GetCNTR();  | ||||||
|  |        | ||||||
|  |         /*Store endpoints registers status */ | ||||||
|  |         for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i); | ||||||
|  |        | ||||||
|  |         /*apply FRES */ | ||||||
|  |         wCNTR|=CNTR_FRES; | ||||||
|  |         _SetCNTR(wCNTR); | ||||||
|  |   | ||||||
|  |         /*clear FRES*/ | ||||||
|  |         wCNTR&=~CNTR_FRES; | ||||||
|  |         _SetCNTR(wCNTR); | ||||||
|  |        | ||||||
|  |         /*poll for RESET flag in ISTR*/ | ||||||
|  |         while((_GetISTR()&ISTR_RESET) == 0); | ||||||
|  |    | ||||||
|  |         /* clear RESET flag in ISTR */ | ||||||
|  |         _SetISTR((uint16_t)CLR_RESET); | ||||||
|  |     | ||||||
|  |        /*restore Enpoints*/ | ||||||
|  |         for (i=0;i<8;i++) | ||||||
|  |         _SetENDPOINT(i, EP[i]); | ||||||
|  |        | ||||||
|  |         esof_counter = 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         esof_counter = 0; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* resume handling timing is made with ESOFs */ | ||||||
|  |     Resume(RESUME_ESOF); /* request without change of the machine state */ | ||||||
|  | 
 | ||||||
|  | #ifdef ESOF_CALLBACK | ||||||
|  |     ESOF_Callback(); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  | } /* USB_Istr */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										94
									
								
								fw_dc22_stm32l100/src/usb/usb_istr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								fw_dc22_stm32l100/src/usb/usb_istr.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_istr.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   This file includes the peripherals header files in the user application. | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_ISTR_H | ||||||
|  | #define __USB_ISTR_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "usb_conf.h" | ||||||
|  | 
 | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  |  void USB_Istr(void); | ||||||
|  | 
 | ||||||
|  | /* function prototypes Automatically built defining related macros */ | ||||||
|  | 
 | ||||||
|  | void EP1_IN_Callback(void); | ||||||
|  | void EP2_IN_Callback(void); | ||||||
|  | void EP3_IN_Callback(void); | ||||||
|  | void EP4_IN_Callback(void); | ||||||
|  | void EP5_IN_Callback(void); | ||||||
|  | void EP6_IN_Callback(void); | ||||||
|  | void EP7_IN_Callback(void); | ||||||
|  | 
 | ||||||
|  | void EP1_OUT_Callback(void); | ||||||
|  | void EP2_OUT_Callback(void); | ||||||
|  | void EP3_OUT_Callback(void); | ||||||
|  | void EP4_OUT_Callback(void); | ||||||
|  | void EP5_OUT_Callback(void); | ||||||
|  | void EP6_OUT_Callback(void); | ||||||
|  | void EP7_OUT_Callback(void); | ||||||
|  | 
 | ||||||
|  | #ifdef CTR_CALLBACK | ||||||
|  | void CTR_Callback(void); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef DOVR_CALLBACK | ||||||
|  | void DOVR_Callback(void); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef ERR_CALLBACK | ||||||
|  | void ERR_Callback(void); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef WKUP_CALLBACK | ||||||
|  | void WKUP_Callback(void); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef SUSP_CALLBACK | ||||||
|  | void SUSP_Callback(void); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef RESET_CALLBACK | ||||||
|  | void RESET_Callback(void); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef SOF_CALLBACK | ||||||
|  | void SOF_Callback(void); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef ESOF_CALLBACK | ||||||
|  | void ESOF_Callback(void); | ||||||
|  | #endif | ||||||
|  | #endif /*__USB_ISTR_H*/ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										418
									
								
								fw_dc22_stm32l100/src/usb/usb_prop.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										418
									
								
								fw_dc22_stm32l100/src/usb/usb_prop.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,418 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_prop.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   All processing related to Virtual Com Port Demo | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "core/usb_lib.h" | ||||||
|  | #include "usb_conf.h" | ||||||
|  | #include "usb_prop.h" | ||||||
|  | #include "usb_desc.h" | ||||||
|  | #include "usb_pwr.h" | ||||||
|  | #include "glue.h" | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | uint8_t Request = 0; | ||||||
|  | 
 | ||||||
|  | LINE_CODING linecoding = | ||||||
|  |   { | ||||||
|  |     115200, /* baud rate*/ | ||||||
|  |     0x00,   /* stop bits-1*/ | ||||||
|  |     0x00,   /* parity - none*/ | ||||||
|  |     0x08    /* no. of bits 8*/ | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | /* -------------------------------------------------------------------------- */ | ||||||
|  | /*  Structures initializations */ | ||||||
|  | /* -------------------------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | DEVICE Device_Table = | ||||||
|  |   { | ||||||
|  |     EP_NUM, | ||||||
|  |     1 | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | DEVICE_PROP Device_Property = | ||||||
|  |   { | ||||||
|  |     Virtual_Com_Port_init, | ||||||
|  |     Virtual_Com_Port_Reset, | ||||||
|  |     Virtual_Com_Port_Status_In, | ||||||
|  |     Virtual_Com_Port_Status_Out, | ||||||
|  |     Virtual_Com_Port_Data_Setup, | ||||||
|  |     Virtual_Com_Port_NoData_Setup, | ||||||
|  |     Virtual_Com_Port_Get_Interface_Setting, | ||||||
|  |     Virtual_Com_Port_GetDeviceDescriptor, | ||||||
|  |     Virtual_Com_Port_GetConfigDescriptor, | ||||||
|  |     Virtual_Com_Port_GetStringDescriptor, | ||||||
|  |     0, | ||||||
|  |     0x40 /*MAX PACKET SIZE*/ | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | USER_STANDARD_REQUESTS User_Standard_Requests = | ||||||
|  |   { | ||||||
|  |     Virtual_Com_Port_GetConfiguration, | ||||||
|  |     Virtual_Com_Port_SetConfiguration, | ||||||
|  |     Virtual_Com_Port_GetInterface, | ||||||
|  |     Virtual_Com_Port_SetInterface, | ||||||
|  |     Virtual_Com_Port_GetStatus, | ||||||
|  |     Virtual_Com_Port_ClearFeature, | ||||||
|  |     Virtual_Com_Port_SetEndPointFeature, | ||||||
|  |     Virtual_Com_Port_SetDeviceFeature, | ||||||
|  |     Virtual_Com_Port_SetDeviceAddress | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | ONE_DESCRIPTOR Device_Descriptor = | ||||||
|  |   { | ||||||
|  |     (uint8_t*)Virtual_Com_Port_DeviceDescriptor, | ||||||
|  |     VIRTUAL_COM_PORT_SIZ_DEVICE_DESC | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | ONE_DESCRIPTOR Config_Descriptor = | ||||||
|  |   { | ||||||
|  |     (uint8_t*)Virtual_Com_Port_ConfigDescriptor, | ||||||
|  |     VIRTUAL_COM_PORT_SIZ_CONFIG_DESC | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | ONE_DESCRIPTOR String_Descriptor[4] = | ||||||
|  |   { | ||||||
|  |     {(uint8_t*)Virtual_Com_Port_StringLangID, VIRTUAL_COM_PORT_SIZ_STRING_LANGID}, | ||||||
|  |     {(uint8_t*)Virtual_Com_Port_StringVendor, VIRTUAL_COM_PORT_SIZ_STRING_VENDOR}, | ||||||
|  |     {(uint8_t*)Virtual_Com_Port_StringProduct, VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT}, | ||||||
|  |     {(uint8_t*)Virtual_Com_Port_StringSerial, VIRTUAL_COM_PORT_SIZ_STRING_SERIAL} | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  | /* Extern variables ----------------------------------------------------------*/ | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Extern function prototypes ------------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_init. | ||||||
|  | * Description    : Virtual COM Port Mouse init routine. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Virtual_Com_Port_init(void) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |   /* Update the serial number string descriptor with the data from the unique
 | ||||||
|  |   ID*/ | ||||||
|  |   Get_SerialNum(); | ||||||
|  | 
 | ||||||
|  |   pInformation->Current_Configuration = 0; | ||||||
|  | 
 | ||||||
|  |   /* Connect the device */ | ||||||
|  |   PowerOn(); | ||||||
|  | 
 | ||||||
|  |   /* Perform basic device initialization operations */ | ||||||
|  |   USB_SIL_Init(); | ||||||
|  | 
 | ||||||
|  |   /* configure the USART to the default settings */ | ||||||
|  |   USART_Config_Default(); | ||||||
|  | 
 | ||||||
|  |   bDeviceState = UNCONNECTED; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_Reset | ||||||
|  | * Description    : Virtual_Com_Port reset routine | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Virtual_Com_Port_Reset(void) | ||||||
|  | { | ||||||
|  |   /* Set Virtual_Com_Port DEVICE as not configured */ | ||||||
|  |   pInformation->Current_Configuration = 0; | ||||||
|  | 
 | ||||||
|  |   /* Current Feature initialization */ | ||||||
|  |   pInformation->Current_Feature = Virtual_Com_Port_ConfigDescriptor[7]; | ||||||
|  | 
 | ||||||
|  |   /* Set Virtual_Com_Port DEVICE with the default Interface*/ | ||||||
|  |   pInformation->Current_Interface = 0; | ||||||
|  | 
 | ||||||
|  |   SetBTABLE(BTABLE_ADDRESS); | ||||||
|  | 
 | ||||||
|  |   /* Initialize Endpoint 0 */ | ||||||
|  |   SetEPType(ENDP0, EP_CONTROL); | ||||||
|  |   SetEPTxStatus(ENDP0, EP_TX_STALL); | ||||||
|  |   SetEPRxAddr(ENDP0, ENDP0_RXADDR); | ||||||
|  |   SetEPTxAddr(ENDP0, ENDP0_TXADDR); | ||||||
|  |   Clear_Status_Out(ENDP0); | ||||||
|  |   SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); | ||||||
|  |   SetEPRxValid(ENDP0); | ||||||
|  | 
 | ||||||
|  |   /* Initialize Endpoint 1 */ | ||||||
|  |   SetEPType(ENDP1, EP_BULK); | ||||||
|  |   SetEPTxAddr(ENDP1, ENDP1_TXADDR); | ||||||
|  |   SetEPTxStatus(ENDP1, EP_TX_NAK); | ||||||
|  |   SetEPRxStatus(ENDP1, EP_RX_DIS); | ||||||
|  | 
 | ||||||
|  |   /* Initialize Endpoint 2 */ | ||||||
|  |   SetEPType(ENDP2, EP_INTERRUPT); | ||||||
|  |   SetEPTxAddr(ENDP2, ENDP2_TXADDR); | ||||||
|  |   SetEPRxStatus(ENDP2, EP_RX_DIS); | ||||||
|  |   SetEPTxStatus(ENDP2, EP_TX_NAK); | ||||||
|  | 
 | ||||||
|  |   /* Initialize Endpoint 3 */ | ||||||
|  |   SetEPType(ENDP3, EP_BULK); | ||||||
|  |   SetEPRxAddr(ENDP3, ENDP3_RXADDR); | ||||||
|  |   SetEPRxCount(ENDP3, VIRTUAL_COM_PORT_DATA_SIZE); | ||||||
|  |   SetEPRxStatus(ENDP3, EP_RX_VALID); | ||||||
|  |   SetEPTxStatus(ENDP3, EP_TX_DIS); | ||||||
|  | 
 | ||||||
|  |   /* Set this device to response on default address */ | ||||||
|  |   SetDeviceAddress(0); | ||||||
|  |    | ||||||
|  |   bDeviceState = ATTACHED; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_SetConfiguration. | ||||||
|  | * Description    : Update the device state to configured. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Virtual_Com_Port_SetConfiguration(void) | ||||||
|  | { | ||||||
|  |   DEVICE_INFO *pInfo = &Device_Info; | ||||||
|  | 
 | ||||||
|  |   if (pInfo->Current_Configuration != 0) | ||||||
|  |   { | ||||||
|  |     /* Device configured */ | ||||||
|  |     bDeviceState = CONFIGURED; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_SetConfiguration. | ||||||
|  | * Description    : Update the device state to addressed. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Virtual_Com_Port_SetDeviceAddress (void) | ||||||
|  | { | ||||||
|  |   bDeviceState = ADDRESSED; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_Status_In. | ||||||
|  | * Description    : Virtual COM Port Status In Routine. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Virtual_Com_Port_Status_In(void) | ||||||
|  | { | ||||||
|  |   if (Request == SET_LINE_CODING) | ||||||
|  |   { | ||||||
|  |     USART_Config(); | ||||||
|  |     Request = 0; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_Status_Out | ||||||
|  | * Description    : Virtual COM Port Status OUT Routine. | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Virtual_Com_Port_Status_Out(void) | ||||||
|  | {} | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_Data_Setup | ||||||
|  | * Description    : handle the data class specific requests | ||||||
|  | * Input          : Request Nb. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : USB_UNSUPPORT or USB_SUCCESS. | ||||||
|  | *******************************************************************************/ | ||||||
|  | RESULT Virtual_Com_Port_Data_Setup(uint8_t RequestNo) | ||||||
|  | { | ||||||
|  |   uint8_t    *(*CopyRoutine)(uint16_t); | ||||||
|  | 
 | ||||||
|  |   CopyRoutine = NULL; | ||||||
|  | 
 | ||||||
|  |   if (RequestNo == GET_LINE_CODING) | ||||||
|  |   { | ||||||
|  |     if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) | ||||||
|  |     { | ||||||
|  |       CopyRoutine = Virtual_Com_Port_GetLineCoding; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   else if (RequestNo == SET_LINE_CODING) | ||||||
|  |   { | ||||||
|  |     if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) | ||||||
|  |     { | ||||||
|  |       CopyRoutine = Virtual_Com_Port_SetLineCoding; | ||||||
|  |     } | ||||||
|  |     Request = SET_LINE_CODING; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (CopyRoutine == NULL) | ||||||
|  |   { | ||||||
|  |     return USB_UNSUPPORT; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   pInformation->Ctrl_Info.CopyData = CopyRoutine; | ||||||
|  |   pInformation->Ctrl_Info.Usb_wOffset = 0; | ||||||
|  |   (*CopyRoutine)(0); | ||||||
|  |   return USB_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_NoData_Setup. | ||||||
|  | * Description    : handle the no data class specific requests. | ||||||
|  | * Input          : Request Nb. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : USB_UNSUPPORT or USB_SUCCESS. | ||||||
|  | *******************************************************************************/ | ||||||
|  | RESULT Virtual_Com_Port_NoData_Setup(uint8_t RequestNo) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |   if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) | ||||||
|  |   { | ||||||
|  |     if (RequestNo == SET_COMM_FEATURE) | ||||||
|  |     { | ||||||
|  |       return USB_SUCCESS; | ||||||
|  |     } | ||||||
|  |     else if (RequestNo == SET_CONTROL_LINE_STATE) | ||||||
|  |     { | ||||||
|  |       return USB_SUCCESS; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return USB_UNSUPPORT; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_GetDeviceDescriptor. | ||||||
|  | * Description    : Gets the device descriptor. | ||||||
|  | * Input          : Length. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : The address of the device descriptor. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint8_t *Virtual_Com_Port_GetDeviceDescriptor(uint16_t Length) | ||||||
|  | { | ||||||
|  |   return Standard_GetDescriptorData(Length, &Device_Descriptor); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_GetConfigDescriptor. | ||||||
|  | * Description    : get the configuration descriptor. | ||||||
|  | * Input          : Length. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : The address of the configuration descriptor. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint8_t *Virtual_Com_Port_GetConfigDescriptor(uint16_t Length) | ||||||
|  | { | ||||||
|  |   return Standard_GetDescriptorData(Length, &Config_Descriptor); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_GetStringDescriptor | ||||||
|  | * Description    : Gets the string descriptors according to the needed index | ||||||
|  | * Input          : Length. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : The address of the string descriptors. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint8_t *Virtual_Com_Port_GetStringDescriptor(uint16_t Length) | ||||||
|  | { | ||||||
|  |   uint8_t wValue0 = pInformation->USBwValue0; | ||||||
|  |   if (wValue0 > 4) | ||||||
|  |   { | ||||||
|  |     return NULL; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_Get_Interface_Setting. | ||||||
|  | * Description    : test the interface and the alternate setting according to the | ||||||
|  | *                  supported one. | ||||||
|  | * Input1         : uint8_t: Interface : interface number. | ||||||
|  | * Input2         : uint8_t: AlternateSetting : Alternate Setting number. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : The address of the string descriptors. | ||||||
|  | *******************************************************************************/ | ||||||
|  | RESULT Virtual_Com_Port_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting) | ||||||
|  | { | ||||||
|  |   if (AlternateSetting > 0) | ||||||
|  |   { | ||||||
|  |     return USB_UNSUPPORT; | ||||||
|  |   } | ||||||
|  |   else if (Interface > 1) | ||||||
|  |   { | ||||||
|  |     return USB_UNSUPPORT; | ||||||
|  |   } | ||||||
|  |   return USB_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_GetLineCoding. | ||||||
|  | * Description    : send the linecoding structure to the PC host. | ||||||
|  | * Input          : Length. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Linecoding structure base address. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint8_t *Virtual_Com_Port_GetLineCoding(uint16_t Length) | ||||||
|  | { | ||||||
|  |   if (Length == 0) | ||||||
|  |   { | ||||||
|  |     pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding); | ||||||
|  |     return NULL; | ||||||
|  |   } | ||||||
|  |   return(uint8_t *)&linecoding; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Virtual_Com_Port_SetLineCoding. | ||||||
|  | * Description    : Set the linecoding structure fields. | ||||||
|  | * Input          : Length. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : Linecoding structure base address. | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint8_t *Virtual_Com_Port_SetLineCoding(uint16_t Length) | ||||||
|  | { | ||||||
|  |   if (Length == 0) | ||||||
|  |   { | ||||||
|  |     pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding); | ||||||
|  |     return NULL; | ||||||
|  |   } | ||||||
|  |   return(uint8_t *)&linecoding; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
|  | 
 | ||||||
							
								
								
									
										87
									
								
								fw_dc22_stm32l100/src/usb/usb_prop.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								fw_dc22_stm32l100/src/usb/usb_prop.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_prop.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   All processing related to Virtual COM Port Demo (Endpoint 0) | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __usb_prop_H | ||||||
|  | #define __usb_prop_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   uint32_t bitrate; | ||||||
|  |   uint8_t format; | ||||||
|  |   uint8_t paritytype; | ||||||
|  |   uint8_t datatype; | ||||||
|  | }LINE_CODING; | ||||||
|  | 
 | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported define -----------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | #define Virtual_Com_Port_GetConfiguration          NOP_Process | ||||||
|  | //#define Virtual_Com_Port_SetConfiguration          NOP_Process
 | ||||||
|  | #define Virtual_Com_Port_GetInterface              NOP_Process | ||||||
|  | #define Virtual_Com_Port_SetInterface              NOP_Process | ||||||
|  | #define Virtual_Com_Port_GetStatus                 NOP_Process | ||||||
|  | #define Virtual_Com_Port_ClearFeature              NOP_Process | ||||||
|  | #define Virtual_Com_Port_SetEndPointFeature        NOP_Process | ||||||
|  | #define Virtual_Com_Port_SetDeviceFeature          NOP_Process | ||||||
|  | //#define Virtual_Com_Port_SetDeviceAddress          NOP_Process
 | ||||||
|  | 
 | ||||||
|  | #define SEND_ENCAPSULATED_COMMAND   0x00 | ||||||
|  | #define GET_ENCAPSULATED_RESPONSE   0x01 | ||||||
|  | #define SET_COMM_FEATURE            0x02 | ||||||
|  | #define GET_COMM_FEATURE            0x03 | ||||||
|  | #define CLEAR_COMM_FEATURE          0x04 | ||||||
|  | #define SET_LINE_CODING             0x20 | ||||||
|  | #define GET_LINE_CODING             0x21 | ||||||
|  | #define SET_CONTROL_LINE_STATE      0x22 | ||||||
|  | #define SEND_BREAK                  0x23 | ||||||
|  | 
 | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | void Virtual_Com_Port_init(void); | ||||||
|  | void Virtual_Com_Port_Reset(void); | ||||||
|  | void Virtual_Com_Port_SetConfiguration(void); | ||||||
|  | void Virtual_Com_Port_SetDeviceAddress (void); | ||||||
|  | void Virtual_Com_Port_Status_In (void); | ||||||
|  | void Virtual_Com_Port_Status_Out (void); | ||||||
|  | RESULT Virtual_Com_Port_Data_Setup(uint8_t); | ||||||
|  | RESULT Virtual_Com_Port_NoData_Setup(uint8_t); | ||||||
|  | RESULT Virtual_Com_Port_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting); | ||||||
|  | uint8_t *Virtual_Com_Port_GetDeviceDescriptor(uint16_t ); | ||||||
|  | uint8_t *Virtual_Com_Port_GetConfigDescriptor(uint16_t); | ||||||
|  | uint8_t *Virtual_Com_Port_GetStringDescriptor(uint16_t); | ||||||
|  | 
 | ||||||
|  | uint8_t *Virtual_Com_Port_GetLineCoding(uint16_t Length); | ||||||
|  | uint8_t *Virtual_Com_Port_SetLineCoding(uint16_t Length); | ||||||
|  | 
 | ||||||
|  | #endif /* __usb_prop_H */ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
|  | 
 | ||||||
							
								
								
									
										318
									
								
								fw_dc22_stm32l100/src/usb/usb_pwr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								fw_dc22_stm32l100/src/usb/usb_pwr.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,318 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_pwr.c | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   Connection/disconnection & power management | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | #include "core/usb_lib.h" | ||||||
|  | #include "usb_conf.h" | ||||||
|  | #include "usb_pwr.h" | ||||||
|  | #include "glue.h" | ||||||
|  | 
 | ||||||
|  | /* Private typedef -----------------------------------------------------------*/ | ||||||
|  | /* Private define ------------------------------------------------------------*/ | ||||||
|  | /* Private macro -------------------------------------------------------------*/ | ||||||
|  | /* Private variables ---------------------------------------------------------*/ | ||||||
|  | __IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */ | ||||||
|  | __IO bool fSuspendEnabled = FALSE;  /* true when suspend is possible */ | ||||||
|  | __IO uint32_t EP[8]; | ||||||
|  | 
 | ||||||
|  | struct | ||||||
|  | { | ||||||
|  |   __IO RESUME_STATE eState; | ||||||
|  |   __IO uint8_t bESOFcnt; | ||||||
|  | } | ||||||
|  | ResumeS; | ||||||
|  | 
 | ||||||
|  | __IO uint32_t remotewakeupon=0; | ||||||
|  | 
 | ||||||
|  | /* Extern variables ----------------------------------------------------------*/ | ||||||
|  | /* Private function prototypes -----------------------------------------------*/ | ||||||
|  | /* Extern function prototypes ------------------------------------------------*/ | ||||||
|  | /* Private functions ---------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : PowerOn | ||||||
|  | * Description    : | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : USB_SUCCESS. | ||||||
|  | *******************************************************************************/ | ||||||
|  | RESULT PowerOn(void) | ||||||
|  | { | ||||||
|  |   uint16_t wRegVal; | ||||||
|  | 
 | ||||||
|  |   /*** cable plugged-in ? ***/ | ||||||
|  |   USB_Cable_Config(ENABLE); | ||||||
|  | 
 | ||||||
|  |   /*** CNTR_PWDN = 0 ***/ | ||||||
|  |   wRegVal = CNTR_FRES; | ||||||
|  |   _SetCNTR(wRegVal); | ||||||
|  | 
 | ||||||
|  |   /*** CNTR_FRES = 0 ***/ | ||||||
|  |   wInterrupt_Mask = 0; | ||||||
|  |   _SetCNTR(wInterrupt_Mask); | ||||||
|  |   /*** Clear pending interrupts ***/ | ||||||
|  |   _SetISTR(0); | ||||||
|  |   /*** Set interrupt mask ***/ | ||||||
|  |   wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM; | ||||||
|  |   _SetCNTR(wInterrupt_Mask); | ||||||
|  |    | ||||||
|  |   return USB_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : PowerOff | ||||||
|  | * Description    : handles switch-off conditions | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : USB_SUCCESS. | ||||||
|  | *******************************************************************************/ | ||||||
|  | RESULT PowerOff() | ||||||
|  | { | ||||||
|  |   /* disable all interrupts and force USB reset */ | ||||||
|  |   _SetCNTR(CNTR_FRES); | ||||||
|  |   /* clear interrupt status register */ | ||||||
|  |   _SetISTR(0); | ||||||
|  |   /* Disable the Pull-Up*/ | ||||||
|  |   USB_Cable_Config(DISABLE); | ||||||
|  |   /* switch-off device */ | ||||||
|  |   _SetCNTR(CNTR_FRES + CNTR_PDWN); | ||||||
|  |   /* sw variables reset */ | ||||||
|  |   /* ... */ | ||||||
|  | 
 | ||||||
|  |   return USB_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Suspend | ||||||
|  | * Description    : sets suspend mode operating conditions | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : USB_SUCCESS. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Suspend(void) | ||||||
|  | { | ||||||
|  | 	uint32_t i =0; | ||||||
|  | 	uint16_t wCNTR; | ||||||
|  | 	uint32_t tmpreg = 0; | ||||||
|  |   __IO uint32_t savePWR_CR=0; | ||||||
|  | 	/* suspend preparation */ | ||||||
|  | 	/* ... */ | ||||||
|  | 	 | ||||||
|  | 	/*Store CNTR value */ | ||||||
|  | 	wCNTR = _GetCNTR();   | ||||||
|  | 
 | ||||||
|  |     /* This a sequence to apply a force RESET to handle a robustness case */ | ||||||
|  |      | ||||||
|  | 	/*Store endpoints registers status */ | ||||||
|  |     for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i); | ||||||
|  | 	 | ||||||
|  | 	/* unmask RESET flag */ | ||||||
|  | 	wCNTR|=CNTR_RESETM; | ||||||
|  | 	_SetCNTR(wCNTR); | ||||||
|  | 	 | ||||||
|  | 	/*apply FRES */ | ||||||
|  | 	wCNTR|=CNTR_FRES; | ||||||
|  | 	_SetCNTR(wCNTR); | ||||||
|  | 	 | ||||||
|  | 	/*clear FRES*/ | ||||||
|  | 	wCNTR&=~CNTR_FRES; | ||||||
|  | 	_SetCNTR(wCNTR); | ||||||
|  | 	 | ||||||
|  | 	/*poll for RESET flag in ISTR*/ | ||||||
|  | 	while((_GetISTR()&ISTR_RESET) == 0); | ||||||
|  | 	 | ||||||
|  | 	/* clear RESET flag in ISTR */ | ||||||
|  | 	_SetISTR((uint16_t)CLR_RESET); | ||||||
|  | 	 | ||||||
|  | 	/*restore Enpoints*/ | ||||||
|  | 	for (i=0;i<8;i++) | ||||||
|  | 	_SetENDPOINT(i, EP[i]); | ||||||
|  | 	 | ||||||
|  | 	/* Now it is safe to enter macrocell in suspend mode */ | ||||||
|  | 	wCNTR |= CNTR_FSUSP; | ||||||
|  | 	_SetCNTR(wCNTR); | ||||||
|  | 	 | ||||||
|  | 	/* force low-power mode in the macrocell */ | ||||||
|  | 	wCNTR = _GetCNTR(); | ||||||
|  | 	wCNTR |= CNTR_LPMODE; | ||||||
|  | 	_SetCNTR(wCNTR); | ||||||
|  | 	 | ||||||
|  | 	/*prepare entry in low power mode (STOP mode)*/ | ||||||
|  | 	/* Select the regulator state in STOP mode*/ | ||||||
|  | 	savePWR_CR = PWR->CR; | ||||||
|  | 	tmpreg = PWR->CR; | ||||||
|  | 	/* Clear PDDS and LPDS bits */ | ||||||
|  | 	tmpreg &= ((uint32_t)0xFFFFFFFC); | ||||||
|  | 	/* Set LPDS bit according to PWR_Regulator value */ | ||||||
|  | 	tmpreg |= PWR_Regulator_LowPower; | ||||||
|  | 	/* Store the new value */ | ||||||
|  | 	PWR->CR = tmpreg; | ||||||
|  | 	/* Set SLEEPDEEP bit of Cortex System Control Register */ | ||||||
|  | #if defined (STM32F30X) || defined (STM32F37X) | ||||||
|  |         SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; | ||||||
|  | #else | ||||||
|  |         SCB->SCR |= SCB_SCR_SLEEPDEEP;        | ||||||
|  | #endif | ||||||
|  | 	 | ||||||
|  | 	/* enter system in STOP mode, only when wakeup flag in not set */ | ||||||
|  | 	if((_GetISTR()&ISTR_WKUP)==0) | ||||||
|  | 	{ | ||||||
|  | 		__WFI(); | ||||||
|  | 		/* Reset SLEEPDEEP bit of Cortex System Control Register */ | ||||||
|  | #if defined (STM32F30X) || defined (STM32F37X) | ||||||
|  |                 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);  | ||||||
|  | #else | ||||||
|  |                 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);  | ||||||
|  | #endif | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		/* Clear Wakeup flag */ | ||||||
|  | 		_SetISTR(CLR_WKUP); | ||||||
|  | 		/* clear FSUSP to abort entry in suspend mode  */ | ||||||
|  |         wCNTR = _GetCNTR(); | ||||||
|  |         wCNTR&=~CNTR_FSUSP; | ||||||
|  |         _SetCNTR(wCNTR); | ||||||
|  | 		 | ||||||
|  | 		/*restore sleep mode configuration */  | ||||||
|  | 		/* restore Power regulator config in sleep mode*/ | ||||||
|  | 		PWR->CR = savePWR_CR; | ||||||
|  | 		 | ||||||
|  | 		/* Reset SLEEPDEEP bit of Cortex System Control Register */ | ||||||
|  | #if defined (STM32F30X) || defined (STM32F37X)		 | ||||||
|  |                 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); | ||||||
|  | #else | ||||||
|  |                 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Resume_Init | ||||||
|  | * Description    : Handles wake-up restoring normal operations | ||||||
|  | * Input          : None. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : USB_SUCCESS. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Resume_Init(void) | ||||||
|  | { | ||||||
|  |   uint16_t wCNTR; | ||||||
|  |    | ||||||
|  |   /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */ | ||||||
|  |   /* restart the clocks */ | ||||||
|  |   /* ...  */ | ||||||
|  | 
 | ||||||
|  |   /* CNTR_LPMODE = 0 */ | ||||||
|  |   wCNTR = _GetCNTR(); | ||||||
|  |   wCNTR &= (~CNTR_LPMODE); | ||||||
|  |   _SetCNTR(wCNTR);     | ||||||
|  |    | ||||||
|  |   /* restore full power */ | ||||||
|  |   /* ... on connected devices */ | ||||||
|  |   Leave_LowPowerMode(); | ||||||
|  | 
 | ||||||
|  |   /* reset FSUSP bit */ | ||||||
|  |   _SetCNTR(IMR_MSK); | ||||||
|  | 
 | ||||||
|  |   /* reverse suspend preparation */ | ||||||
|  |   /* ... */  | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : Resume | ||||||
|  | * Description    : This is the state machine handling resume operations and | ||||||
|  | *                 timing sequence. The control is based on the Resume structure | ||||||
|  | *                 variables and on the ESOF interrupt calling this subroutine | ||||||
|  | *                 without changing machine state. | ||||||
|  | * Input          : a state machine value (RESUME_STATE) | ||||||
|  | *                  RESUME_ESOF doesn't change ResumeS.eState allowing | ||||||
|  | *                  decrementing of the ESOF counter in different states. | ||||||
|  | * Output         : None. | ||||||
|  | * Return         : None. | ||||||
|  | *******************************************************************************/ | ||||||
|  | void Resume(RESUME_STATE eResumeSetVal) | ||||||
|  | { | ||||||
|  |   uint16_t wCNTR; | ||||||
|  | 
 | ||||||
|  |   if (eResumeSetVal != RESUME_ESOF) | ||||||
|  |     ResumeS.eState = eResumeSetVal; | ||||||
|  |   switch (ResumeS.eState) | ||||||
|  |   { | ||||||
|  |     case RESUME_EXTERNAL: | ||||||
|  |       if (remotewakeupon ==0) | ||||||
|  |       { | ||||||
|  |         Resume_Init(); | ||||||
|  |         ResumeS.eState = RESUME_OFF; | ||||||
|  |       } | ||||||
|  |       else /* RESUME detected during the RemoteWAkeup signalling => keep RemoteWakeup handling*/ | ||||||
|  |       { | ||||||
|  |         ResumeS.eState = RESUME_ON; | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |     case RESUME_INTERNAL: | ||||||
|  |       Resume_Init(); | ||||||
|  |       ResumeS.eState = RESUME_START; | ||||||
|  |       remotewakeupon = 1; | ||||||
|  |       break; | ||||||
|  |     case RESUME_LATER: | ||||||
|  |       ResumeS.bESOFcnt = 2; | ||||||
|  |       ResumeS.eState = RESUME_WAIT; | ||||||
|  |       break; | ||||||
|  |     case RESUME_WAIT: | ||||||
|  |       ResumeS.bESOFcnt--; | ||||||
|  |       if (ResumeS.bESOFcnt == 0) | ||||||
|  |         ResumeS.eState = RESUME_START; | ||||||
|  |       break; | ||||||
|  |     case RESUME_START: | ||||||
|  |       wCNTR = _GetCNTR(); | ||||||
|  |       wCNTR |= CNTR_RESUME; | ||||||
|  |       _SetCNTR(wCNTR); | ||||||
|  |       ResumeS.eState = RESUME_ON; | ||||||
|  |       ResumeS.bESOFcnt = 10; | ||||||
|  |       break; | ||||||
|  |     case RESUME_ON:     | ||||||
|  |       ResumeS.bESOFcnt--; | ||||||
|  |       if (ResumeS.bESOFcnt == 0) | ||||||
|  |       { | ||||||
|  |         wCNTR = _GetCNTR(); | ||||||
|  |         wCNTR &= (~CNTR_RESUME); | ||||||
|  |         _SetCNTR(wCNTR); | ||||||
|  |         ResumeS.eState = RESUME_OFF; | ||||||
|  |         remotewakeupon = 0; | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |     case RESUME_OFF: | ||||||
|  |     case RESUME_ESOF: | ||||||
|  |     default: | ||||||
|  |       ResumeS.eState = RESUME_OFF; | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										72
									
								
								fw_dc22_stm32l100/src/usb/usb_pwr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								fw_dc22_stm32l100/src/usb/usb_pwr.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    usb_pwr.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @version V4.0.0 | ||||||
|  |   * @date    21-January-2013 | ||||||
|  |   * @brief   Connection/disconnection & power management header | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> | ||||||
|  |   * | ||||||
|  |   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); | ||||||
|  |   * You may not use this file except in compliance with the License. | ||||||
|  |   * You may obtain a copy of the License at: | ||||||
|  |   * | ||||||
|  |   *        http://www.st.com/software_license_agreement_liberty_v2
 | ||||||
|  |   * | ||||||
|  |   * Unless required by applicable law or agreed to in writing, software  | ||||||
|  |   * distributed under the License is distributed on an "AS IS" BASIS,  | ||||||
|  |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   * See the License for the specific language governing permissions and | ||||||
|  |   * limitations under the License. | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __USB_PWR_H | ||||||
|  | #define __USB_PWR_H | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | typedef enum _RESUME_STATE | ||||||
|  | { | ||||||
|  |   RESUME_EXTERNAL, | ||||||
|  |   RESUME_INTERNAL, | ||||||
|  |   RESUME_LATER, | ||||||
|  |   RESUME_WAIT, | ||||||
|  |   RESUME_START, | ||||||
|  |   RESUME_ON, | ||||||
|  |   RESUME_OFF, | ||||||
|  |   RESUME_ESOF | ||||||
|  | } RESUME_STATE; | ||||||
|  | 
 | ||||||
|  | typedef enum _DEVICE_STATE | ||||||
|  | { | ||||||
|  |   UNCONNECTED, | ||||||
|  |   ATTACHED, | ||||||
|  |   POWERED, | ||||||
|  |   SUSPENDED, | ||||||
|  |   ADDRESSED, | ||||||
|  |   CONFIGURED | ||||||
|  | } DEVICE_STATE; | ||||||
|  | 
 | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  | void Suspend(void); | ||||||
|  | void Resume_Init(void); | ||||||
|  | void Resume(RESUME_STATE eResumeSetVal); | ||||||
|  | RESULT PowerOn(void); | ||||||
|  | RESULT PowerOff(void); | ||||||
|  | 
 | ||||||
|  | /* External variables --------------------------------------------------------*/ | ||||||
|  | extern __IO uint32_t bDeviceState; /* USB device status */ | ||||||
|  | extern __IO bool fSuspendEnabled;  /* true when suspend is possible */ | ||||||
|  | 
 | ||||||
|  | #endif  /*__USB_PWR_H*/ | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user