├── pcb ├── pcb-photo.jpg ├── pcb-preview.pdf ├── schematics.pdf └── untitled.brd ├── decadriver ├── deca_regs.h ├── deca_device.c ├── deca_device_api.h ├── deca_version.h ├── deca_types.h ├── deca_param_types.h └── deca_params_init.c ├── .gitmodules ├── .gitignore ├── os ├── tick.h ├── os.h ├── tick.c └── os.c ├── README.md ├── decartls ├── instance_calib.c ├── instance_common.c ├── instance_tag.c ├── instance.h └── deca_range_tables.c ├── Makefile ├── main.c └── LICENSE /pcb/pcb-photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dword1511/stm32-tinyuwb/HEAD/pcb/pcb-photo.jpg -------------------------------------------------------------------------------- /pcb/pcb-preview.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dword1511/stm32-tinyuwb/HEAD/pcb/pcb-preview.pdf -------------------------------------------------------------------------------- /pcb/schematics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dword1511/stm32-tinyuwb/HEAD/pcb/schematics.pdf -------------------------------------------------------------------------------- /decadriver/deca_regs.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dword1511/stm32-tinyuwb/HEAD/decadriver/deca_regs.h -------------------------------------------------------------------------------- /decadriver/deca_device.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dword1511/stm32-tinyuwb/HEAD/decadriver/deca_device.c -------------------------------------------------------------------------------- /decadriver/deca_device_api.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dword1511/stm32-tinyuwb/HEAD/decadriver/deca_device_api.h -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libopencm3"] 2 | path = libopencm3 3 | url = https://github.com/libopencm3/libopencm3.git 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.swp 3 | *.kate-swp 4 | 5 | *.o 6 | *.bin 7 | *.elf 8 | *.hex 9 | *.map 10 | *.out 11 | *.d 12 | *.Td 13 | -------------------------------------------------------------------------------- /os/tick.h: -------------------------------------------------------------------------------- 1 | #ifndef __RANGING_TICK_H__ 2 | #define __RANGING_TICK_H__ 3 | 4 | #include 5 | 6 | extern void tick_setup(void); 7 | extern volatile uint32_t tick_get_uptime(void); /* Get uptime in milliseconds (warps every 49 days). */ 8 | extern void tick_sleep(uint32_t ms); /* Sleep for milliseconds, w.r.t uptime. */ 9 | extern void tick_sleep_until(uint32_t target_ms); /* Sleep till target uptime in milliseconds */ 10 | extern void tick_delay_us(uint32_t us); /* Busy waiting for some approximate microseconds */ 11 | extern void tick_pause(void); /* Pause counter and compute remaining uptime fraction before DVFS */ 12 | 13 | #endif /* __RANGING_TICK_H__ */ 14 | -------------------------------------------------------------------------------- /os/os.h: -------------------------------------------------------------------------------- 1 | #ifndef __RANGING_OS_H__ 2 | #define __RANGING_OS_H__ 3 | 4 | #include 5 | 6 | 7 | /* Goodies from linux kernel */ 8 | 9 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) 10 | 11 | #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) 12 | 13 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) 14 | 15 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) 16 | 17 | #define container_of(ptr, type, member) ({ \ 18 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 19 | (type *)( (char *)__mptr - offsetof(type,member) );}) 20 | 21 | 22 | extern void os_init(void); 23 | extern void os_halt(void); 24 | extern void os_pm_sleep_until(unsigned target_ms); 25 | extern void os_panic(void); 26 | 27 | extern void os_dvfs_msi(void); 28 | extern void os_dvfs_hsi16(void); 29 | 30 | #endif /* __RANGING_OS_H__ */ 31 | -------------------------------------------------------------------------------- /decadriver/deca_version.h: -------------------------------------------------------------------------------- 1 | /*! ---------------------------------------------------------------------------- 2 | * @file deca_version.h 3 | * @brief Defines the version info for the DW1000 device driver including its API 4 | * 5 | * @attention 6 | * 7 | * Copyright 2013 (c) Decawave Ltd, Dublin, Ireland. 8 | * 9 | * All rights reserved. 10 | * 11 | */ 12 | 13 | #ifndef _DECA_VERSION_H_ 14 | #define _DECA_VERSION_H_ 15 | 16 | // 17 | // The DW1000 device driver is separately version numbered to any version the application using it may have 18 | // 19 | // Two symbols are defined here: one hexadecimal value and one string that includes the hex bytes. 20 | // Both should be updated together in a consistent way when the software is being modified. 21 | // 22 | // The format of the hex version is 0xAABBCC and the string ends with AA.BB.CC, where... 23 | // 24 | // Quantity CC is updated for minor changes/bug fixes that should not need user code changes 25 | // Quantity BB is updated for changes/bug fixes that may need user code changes 26 | // Quantity AA is updated for major changes that will need user code changes 27 | // 28 | 29 | #define DW1000_DRIVER_VERSION 0x040005 30 | #define DW1000_DEVICE_DRIVER_VER_STRING "DW1000 Device Driver Version 04.00.05" 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /decadriver/deca_types.h: -------------------------------------------------------------------------------- 1 | /*! ---------------------------------------------------------------------------- 2 | * @file deca_types.h 3 | * @brief Decawave general type definitions 4 | * 5 | * @attention 6 | * 7 | * Copyright 2013 (c) Decawave Ltd, Dublin, Ireland. 8 | * 9 | * All rights reserved. 10 | * 11 | */ 12 | 13 | #ifndef _DECA_TYPES_H_ 14 | #define _DECA_TYPES_H_ 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | #ifndef uint8 21 | #ifndef _DECA_UINT8_ 22 | #define _DECA_UINT8_ 23 | typedef unsigned char uint8; 24 | #endif 25 | #endif 26 | 27 | #ifndef uint16 28 | #ifndef _DECA_UINT16_ 29 | #define _DECA_UINT16_ 30 | typedef unsigned short uint16; 31 | #endif 32 | #endif 33 | 34 | #ifndef uint32 35 | #ifndef _DECA_UINT32_ 36 | #define _DECA_UINT32_ 37 | typedef unsigned long uint32; 38 | #endif 39 | #endif 40 | 41 | #ifndef int8 42 | #ifndef _DECA_INT8_ 43 | #define _DECA_INT8_ 44 | typedef signed char int8; 45 | #endif 46 | #endif 47 | 48 | #ifndef int16 49 | #ifndef _DECA_INT16_ 50 | #define _DECA_INT16_ 51 | typedef signed short int16; 52 | #endif 53 | #endif 54 | 55 | #ifndef int32 56 | #ifndef _DECA_INT32_ 57 | #define _DECA_INT32_ 58 | typedef signed long int32; 59 | #endif 60 | #endif 61 | 62 | #ifndef NULL 63 | #define NULL ((void *)0UL) 64 | #endif 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif /* DECA_TYPES_H_ */ 71 | 72 | 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tiny, Ultra-low-power UWB Localization Tag 2 | 3 | This is a UWB localization tag based on Decawave `DWM1000` module and STMicro `STM32L031F6P6` ultra-low-power MCU. 4 | The average power consumption is less than 5 mW in 6.8 Mbps mode (10 Hz update rate). 5 | 6 | The tag has a built-in `LTC3588-1` energy harvester. WARNING: do not use `LTC3588-2`, their functionalities are very different! 7 | The harvester can be left unpopulated and bypassed by connecting +3V3 directly to an external power source, 8 | and then disabling the power-good logic in the source code. 9 | 10 | ## General Build Instructions 11 | 12 | You will need the following packages (Debian/Ubuntu): 13 | 14 | * build-essential 15 | * gcc-arm-none-eabi 16 | * git 17 | * stlink-tools 18 | * gdb-multiarch 19 | 20 | You will have to flash and debug via the SWD test-points. Fine air-wire soldering skill required. 21 | 22 | This project uses `libopencm3`. It will be automatically checked out during the building process. 23 | To build the firmware, run `make`. To flash it, connect the board to a ST-Link, and then run `make flash`. 24 | Alternatively, you can use `openocd` and any SWD debugger you fancy. 25 | 26 | ## Publication 27 | 28 | This project was part of the following work. Please kindly consider citing the paper as shown: 29 | 30 | ``` 31 | @inproceedings{Capttery, 32 | author = {Zhang, Chi and Kumar, Sidharth and Bharadia, Dinesh}, 33 | title = {{Capttery: Scalable Battery-like Room-level Wireless Power}}, 34 | booktitle = {Proc. of ACM MobiSys}, 35 | year = {2019}, 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /os/tick.c: -------------------------------------------------------------------------------- 1 | /* Universal tick driver for ARM CPUs */ 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | 12 | #define SYSCLK_PERIOD_MS (1000 / (TICK_HZ)) 13 | 14 | 15 | static volatile uint32_t uptime_ms = 0; 16 | static unsigned cycle_per_us = 0; 17 | 18 | 19 | void sys_tick_handler(void) { 20 | uptime_ms += SYSCLK_PERIOD_MS; 21 | } 22 | 23 | void tick_setup(void) { 24 | unsigned period = rcc_ahb_frequency * SYSCLK_PERIOD_MS / 1000 - 1; 25 | 26 | systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); 27 | systick_set_reload(period); 28 | systick_clear(); 29 | 30 | nvic_set_priority(NVIC_SYSTICK_IRQ, 80); 31 | systick_interrupt_enable(); 32 | systick_counter_enable(); 33 | 34 | cycle_per_us = rcc_ahb_frequency / 1000000; 35 | } 36 | 37 | void tick_pause(void) { 38 | unsigned counter; 39 | unsigned period = systick_get_reload(); 40 | 41 | systick_counter_disable(); 42 | systick_interrupt_disable(); 43 | 44 | counter = systick_get_value(); 45 | counter = (period - counter) * SYSCLK_PERIOD_MS; 46 | uptime_ms += counter / period; 47 | 48 | if ((counter % period) > (period / 2)) { 49 | uptime_ms ++; 50 | } 51 | } 52 | 53 | /* NOTE: Warps every 49 days... */ 54 | volatile uint32_t tick_get_uptime(void) { 55 | return uptime_ms; 56 | } 57 | 58 | void tick_sleep_until(uint32_t target_ms) { 59 | while (uptime_ms < target_ms) { 60 | asm("wfi"); 61 | } 62 | } 63 | 64 | void tick_sleep(uint32_t ms) { 65 | uint32_t t_entry = uptime_ms; 66 | uint32_t target = t_entry + ms; 67 | 68 | tick_sleep_until(target); 69 | } 70 | 71 | __attribute__((optimize("unroll-loops"))) 72 | void tick_delay_us(uint32_t us) { 73 | uint32_t i, j; 74 | 75 | for (i = 0; i < us; i ++) { 76 | for (j = 0; j < cycle_per_us; j ++) { 77 | asm("nop"); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /decadriver/deca_param_types.h: -------------------------------------------------------------------------------- 1 | /*! ---------------------------------------------------------------------------- 2 | * @file deca_param_types.h 3 | * @brief Decawave general type definitions for configuration structures 4 | * 5 | * @attention 6 | * 7 | * Copyright 2013 (c) Decawave Ltd, Dublin, Ireland. 8 | * 9 | * All rights reserved. 10 | * 11 | */ 12 | #ifndef _DECA_PARAM_TYPES_H_ 13 | #define _DECA_PARAM_TYPES_H_ 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | #include "deca_types.h" 19 | 20 | #define NUM_BR 3 21 | #define NUM_PRF 2 22 | #define NUM_PACS 4 23 | #define NUM_BW 2 //2 bandwidths are supported 24 | #define NUM_SFD 2 //supported number of SFDs - standard = 0, non-standard = 1 25 | #define NUM_CH 6 //supported channels are 1, 2, 3, 4, 5, 7 26 | #define NUM_CH_SUPPORTED 8 //supported channels are '0', 1, 2, 3, 4, 5, '6', 7 27 | #define PCODES 25 //supported preamble codes 28 | 29 | 30 | typedef struct { 31 | uint32 lo32; 32 | uint16 target[NUM_PRF]; 33 | } agc_cfg_struct ; 34 | 35 | extern const agc_cfg_struct agc_config ; 36 | 37 | //SFD threshold settings for 110k, 850k, 6.8Mb standard and non-standard 38 | extern const uint16 sftsh[NUM_BR][NUM_SFD]; 39 | 40 | extern const uint16 dtune1[NUM_PRF]; 41 | 42 | #define XMLPARAMS_VERSION (1.17f) 43 | 44 | extern const uint32 fs_pll_cfg[NUM_CH]; 45 | extern const uint8 fs_pll_tune[NUM_CH]; 46 | extern const uint8 rx_config[NUM_BW]; 47 | extern const uint32 tx_config[NUM_CH]; 48 | extern const uint8 dwnsSFDlen[NUM_BR]; //length of SFD for each of the bitrates 49 | extern const uint32 digital_bb_config[NUM_PRF][NUM_PACS]; 50 | extern const uint8 chan_idx[NUM_CH_SUPPORTED]; 51 | extern const float txpwr_compensation[NUM_CH]; 52 | 53 | #define PEAK_MULTPLIER (0x60) //3 -> (0x3 * 32) & 0x00E0 54 | #define N_STD_FACTOR (13) 55 | #define LDE_PARAM1 (PEAK_MULTPLIER | N_STD_FACTOR) 56 | 57 | #define LDE_PARAM3_16 (0x1607) 58 | #define LDE_PARAM3_64 (0x0607) 59 | 60 | #define MIXER_GAIN_STEP (0.5) 61 | #define DA_ATTN_STEP (2.5) 62 | 63 | extern const uint16 lde_replicaCoeff[PCODES]; 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif 70 | 71 | 72 | -------------------------------------------------------------------------------- /decartls/instance_calib.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | 6 | // The table below specifies the default TX spectrum configuration parameters... this has been tuned for DW EVK hardware units 7 | // the table is set for smart power - see below in the instance_config function how this is used when not using smart power 8 | const tx_struct txSpectrumConfig[8] = { 9 | //Channel 0 ----- this is just a place holder so the next array element is channel 1 10 | { 11 | 0x0, //0 12 | { 13 | 0x0, //0 14 | 0x0 //0 15 | } 16 | }, 17 | //Channel 1 18 | { 19 | 0xc9, //PG_DELAY 20 | { 21 | 0x15355575, //16M prf power 22 | 0x07274767 //64M prf power 23 | } 24 | 25 | }, 26 | //Channel 2 27 | { 28 | 0xc2, //PG_DELAY 29 | { 30 | 0x15355575, //16M prf power 31 | 0x07274767 //64M prf power 32 | } 33 | }, 34 | //Channel 3 35 | { 36 | 0xc5, //PG_DELAY 37 | { 38 | 0x0f2f4f6f, //16M prf power 39 | 0x2b4b6b8b //64M prf power 40 | } 41 | }, 42 | //Channel 4 43 | { 44 | 0x95, //PG_DELAY 45 | { 46 | 0x1f1f3f5f, //16M prf power 47 | 0x3a5a7a9a //64M prf power 48 | } 49 | }, 50 | //Channel 5 51 | { 52 | 0xc0, //PG_DELAY 53 | { 54 | 0x0E082848, //16M prf power 55 | 0x25456585 //64M prf power 56 | } 57 | }, 58 | //Channel 6 ----- this is just a place holder so the next array element is channel 7 59 | { 60 | 0x0, //0 61 | { 62 | 0x0, //0 63 | 0x0 //0 64 | } 65 | }, 66 | //Channel 7 67 | { 68 | 0x93, //PG_DELAY 69 | { 70 | 0x32527292, //16M prf power 71 | 0x5171B1d1 //64M prf power 72 | } 73 | } 74 | }; 75 | 76 | /* TODO: These won't be useful for us as they are board-dependent. DWM1000 has those in OTP, and will be accounted by end-to-end calibration anyways. */ 77 | 78 | //these are default antenna delays for EVB1000, these can be used if there is no calibration data in the DW1000, 79 | //or instead of the calibration data 80 | const uint16 rfDelays[2] = { 81 | (uint16) ((513.9067f / 2.0) * 1e-9 / DWT_TIME_UNITS),//PRF 16 82 | (uint16) ((514.462f / 2.0) * 1e-9 / DWT_TIME_UNITS) 83 | }; 84 | 85 | //these are default TREK Tag/Anchor antenna delays 86 | const uint16 rfDelaysTREK[2] = { 87 | (uint16) ((514.83f / 2.0) * 1e-9 / DWT_TIME_UNITS),//channel 2 88 | (uint16) ((514.65f / 2.0) * 1e-9 / DWT_TIME_UNITS) //channel 5 89 | }; 90 | -------------------------------------------------------------------------------- /decadriver/deca_params_init.c: -------------------------------------------------------------------------------- 1 | /*! ---------------------------------------------------------------------------- 2 | * @file deca_params_init.c 3 | * @brief DW1000 configuration parameters 4 | * 5 | * @attention 6 | * 7 | * Copyright 2013 (c) Decawave Ltd, Dublin, Ireland. 8 | * 9 | * All rights reserved. 10 | * 11 | * 12 | * ------------------------------------------------------------------------------------------------------------------- 13 | **/ 14 | #include 15 | #include 16 | 17 | #include "deca_regs.h" 18 | #include "deca_device_api.h" 19 | #include "deca_param_types.h" 20 | 21 | 22 | //----------------------------------------- 23 | // map the channel number to the index in the configuration arrays below 24 | // 0th element is chan 1, 1st is chan 2, 2nd is chan 3, 3rd is chan 4, 4th is chan 5, 5th is chan 7 25 | const uint8 chan_idx[NUM_CH_SUPPORTED] = {0, 0, 1, 2, 3, 4, 0, 5}; 26 | 27 | //----------------------------------------- 28 | const uint32 tx_config[NUM_CH] = 29 | { 30 | RF_TXCTRL_CH1, 31 | RF_TXCTRL_CH2, 32 | RF_TXCTRL_CH3, 33 | RF_TXCTRL_CH4, 34 | RF_TXCTRL_CH5, 35 | RF_TXCTRL_CH7, 36 | }; 37 | 38 | //Frequency Synthesiser - PLL configuration 39 | const uint32 fs_pll_cfg[NUM_CH] = 40 | { 41 | FS_PLLCFG_CH1, 42 | FS_PLLCFG_CH2, 43 | FS_PLLCFG_CH3, 44 | FS_PLLCFG_CH4, 45 | FS_PLLCFG_CH5, 46 | FS_PLLCFG_CH7 47 | }; 48 | 49 | //Frequency Synthesiser - PLL tuning 50 | const uint8 fs_pll_tune[NUM_CH] = 51 | { 52 | FS_PLLTUNE_CH1, 53 | FS_PLLTUNE_CH2, 54 | FS_PLLTUNE_CH3, 55 | FS_PLLTUNE_CH4, 56 | FS_PLLTUNE_CH5, 57 | FS_PLLTUNE_CH7 58 | }; 59 | 60 | //bandwidth configuration 61 | const uint8 rx_config[NUM_BW] = 62 | { 63 | RF_RXCTRLH_NBW, 64 | RF_RXCTRLH_WBW 65 | }; 66 | 67 | 68 | const agc_cfg_struct agc_config = 69 | { 70 | AGC_TUNE2_VAL, 71 | { AGC_TUNE1_16M , AGC_TUNE1_64M } //adc target 72 | }; 73 | 74 | //DW non-standard SFD length for 110k, 850k and 6.81M 75 | const uint8 dwnsSFDlen[NUM_BR] = 76 | { 77 | DW_NS_SFD_LEN_110K, 78 | DW_NS_SFD_LEN_850K, 79 | DW_NS_SFD_LEN_6M8 80 | }; 81 | 82 | // SFD Threshold 83 | const uint16 sftsh[NUM_BR][NUM_SFD] = 84 | { 85 | { 86 | DRX_TUNE0b_110K_STD, 87 | DRX_TUNE0b_110K_NSTD 88 | }, 89 | { 90 | DRX_TUNE0b_850K_STD, 91 | DRX_TUNE0b_850K_NSTD 92 | }, 93 | { 94 | DRX_TUNE0b_6M8_STD, 95 | DRX_TUNE0b_6M8_NSTD 96 | } 97 | }; 98 | 99 | const uint16 dtune1[NUM_PRF] = 100 | { 101 | DRX_TUNE1a_PRF16, 102 | DRX_TUNE1a_PRF64 103 | }; 104 | 105 | const uint32 digital_bb_config[NUM_PRF][NUM_PACS] = 106 | { 107 | { 108 | DRX_TUNE2_PRF16_PAC8, 109 | DRX_TUNE2_PRF16_PAC16, 110 | DRX_TUNE2_PRF16_PAC32, 111 | DRX_TUNE2_PRF16_PAC64 112 | }, 113 | { 114 | DRX_TUNE2_PRF64_PAC8, 115 | DRX_TUNE2_PRF64_PAC16, 116 | DRX_TUNE2_PRF64_PAC32, 117 | DRX_TUNE2_PRF64_PAC64 118 | } 119 | }; 120 | 121 | const uint16 lde_replicaCoeff[PCODES] = 122 | { 123 | 0, // No preamble code 0 124 | LDE_REPC_PCODE_1, 125 | LDE_REPC_PCODE_2, 126 | LDE_REPC_PCODE_3, 127 | LDE_REPC_PCODE_4, 128 | LDE_REPC_PCODE_5, 129 | LDE_REPC_PCODE_6, 130 | LDE_REPC_PCODE_7, 131 | LDE_REPC_PCODE_8, 132 | LDE_REPC_PCODE_9, 133 | LDE_REPC_PCODE_10, 134 | LDE_REPC_PCODE_11, 135 | LDE_REPC_PCODE_12, 136 | LDE_REPC_PCODE_13, 137 | LDE_REPC_PCODE_14, 138 | LDE_REPC_PCODE_15, 139 | LDE_REPC_PCODE_16, 140 | LDE_REPC_PCODE_17, 141 | LDE_REPC_PCODE_18, 142 | LDE_REPC_PCODE_19, 143 | LDE_REPC_PCODE_20, 144 | LDE_REPC_PCODE_21, 145 | LDE_REPC_PCODE_22, 146 | LDE_REPC_PCODE_23, 147 | LDE_REPC_PCODE_24 148 | }; 149 | 150 | const float txpwr_compensation[NUM_CH] = { 151 | 0.0, 152 | 0.035, 153 | 0.0, 154 | 0.0, 155 | 0.065, 156 | 0.0 157 | }; 158 | 159 | -------------------------------------------------------------------------------- /os/os.c: -------------------------------------------------------------------------------- 1 | /* Power management and DVFS for STM32L0 */ 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | 17 | /* NOTE: clock functions does not expect interrupts (NOT thread-safe) */ 18 | /* Maximum speed shortens DW1000 active time, might be beneficial */ 19 | void os_dvfs_hsi16(void) { 20 | flash_set_ws(FLASH_ACR_LATENCY_1WS); /* 1WS in range 2, 0WS in range 1 */ 21 | rcc_periph_clock_enable(RCC_PWR); 22 | pwr_set_vos_scale(PWR_SCALE2); 23 | rcc_periph_clock_disable(RCC_PWR); 24 | 25 | rcc_osc_on(RCC_HSI16); 26 | 27 | rcc_wait_for_osc_ready(RCC_HSI16); 28 | rcc_set_sysclk_source(RCC_HSI16); 29 | rcc_osc_off(RCC_MSI); 30 | 31 | rcc_ahb_frequency = 16000000; 32 | rcc_apb1_frequency = 16000000; 33 | rcc_apb2_frequency = 16000000; 34 | 35 | tick_setup(); 36 | } 37 | 38 | /* 39 | static const unsigned msi_range[] = { 40 | RCC_ICSCR_MSIRANGE_65KHZ, RCC_ICSCR_MSIRANGE_131KHZ, RCC_ICSCR_MSIRANGE_262KHZ, RCC_ICSCR_MSIRANGE_524KHZ, RCC_ICSCR_MSIRANGE_1MHZ, RCC_ICSCR_MSIRANGE_2MHZ, RCC_ICSCR_MSIRANGE_4MHZ, 41 | }; 42 | 43 | static const unsigned msi_freq[] = { 44 | 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 45 | }; 46 | 47 | static_assert(ARRAY_SIZE(msi_range) == ARRAY_SIZE(msi_freq), "Check msi_range[] and msi_freq[]!"); 48 | */ 49 | 50 | void os_dvfs_msi() { 51 | rcc_osc_on(RCC_MSI); 52 | RCC_ICSCR = (RCC_ICSCR & (~(RCC_ICSCR_MSIRANGE_MASK << RCC_ICSCR_MSIRANGE_SHIFT))) | (RCC_ICSCR_MSIRANGE_131KHZ << RCC_ICSCR_MSIRANGE_SHIFT); 53 | 54 | rcc_wait_for_osc_ready(RCC_MSI); 55 | rcc_set_sysclk_source(RCC_MSI); 56 | rcc_osc_off(RCC_HSI16); 57 | 58 | rcc_periph_clock_enable(RCC_PWR); 59 | pwr_set_vos_scale(PWR_SCALE3); 60 | rcc_periph_clock_disable(RCC_PWR); 61 | flash_set_ws(FLASH_ACR_LATENCY_0WS); 62 | 63 | rcc_ahb_frequency = 131072; 64 | rcc_apb1_frequency = 131072; 65 | rcc_apb2_frequency = 131072; 66 | 67 | tick_setup(); 68 | } 69 | 70 | /* NOTE: LSI is for IWDG/RTC only */ 71 | 72 | 73 | void os_init(void) { 74 | flash_prefetch_disable(); /* Slightly slower but more energy-efficient */ 75 | 76 | /* Configure GPIO for LP */ 77 | rcc_periph_clock_enable(RCC_GPIOA); 78 | //gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_ALL); 79 | gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_ALL & (~(GPIO13 | GPIO14))); /* Keep SWD active during development */ 80 | rcc_periph_clock_disable(RCC_GPIOA); 81 | // 82 | rcc_periph_clock_enable(RCC_GPIOB); 83 | gpio_mode_setup(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_ALL); 84 | rcc_periph_clock_disable(RCC_GPIOB); 85 | // 86 | rcc_periph_clock_enable(RCC_GPIOC); 87 | gpio_mode_setup(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_ALL); 88 | rcc_periph_clock_disable(RCC_GPIOC); 89 | 90 | rcc_periph_clock_enable(RCC_PWR); 91 | pwr_voltage_regulator_low_power_in_stop(); 92 | PWR_CR |= PWR_CR_LPSDSR; 93 | //PWR_CR |= PWR_CR_LPRUN; /* NOTE: LPRUN is for kHz only, and does not work for our system for some reason */ 94 | rcc_periph_clock_disable(RCC_PWR); 95 | 96 | tick_setup(); 97 | } 98 | 99 | void os_pm_sleep_until(unsigned target_ms) { 100 | /* WARNING: not having this will result in system lock-up */ 101 | /* The whole thing can take a few ms while stalling the clock */ 102 | if (target_ms <= tick_get_uptime()) { 103 | return; 104 | } 105 | 106 | tick_pause(); 107 | os_dvfs_msi(); 108 | tick_setup(); 109 | 110 | tick_sleep_until(target_ms); 111 | 112 | tick_pause(); 113 | os_dvfs_hsi16(); /* FIXME: this is adhoc and will break under other settings */ 114 | tick_setup(); 115 | } 116 | 117 | void os_halt(void) { 118 | rcc_periph_clock_enable(RCC_PWR); 119 | pwr_disable_power_voltage_detect(); 120 | pwr_disable_wakeup_pin(); 121 | 122 | /* According to ST App note... */ 123 | SCB_SCR |= SCB_SCR_SLEEPDEEP; 124 | /* Only sets PDDS... Well, others are universal to CM3 anyway. */ 125 | pwr_set_standby_mode(); 126 | pwr_clear_wakeup_flag(); 127 | /* Enter standby */ 128 | asm("wfi"); 129 | } 130 | 131 | void os_panic(void) { 132 | while (true) { 133 | asm("nop"); 134 | } 135 | } 136 | 137 | void nmi_handler(void) 138 | __attribute__ ((alias ("os_panic"))); 139 | 140 | void hard_fault_handler(void) 141 | __attribute__ ((alias ("os_panic"))); 142 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM := tinyuwb 2 | SRCS := $(wildcard *.c) $(wildcard decadriver/*.c) $(wildcard decartls/*.c) $(wildcard os/*.c) 3 | CROSS ?= arm-none-eabi- 4 | 5 | # NOTE: TICK_HZ has to be large enough for ranging to be accurate 6 | CONFIG_TICK_HZ := 500 7 | CONFIG_DEEP_SLEEP := 1 8 | CONFIG_ENABLE_LEDS := 1 9 | 10 | 11 | ############################################################################### 12 | 13 | # Clear implicit rules 14 | .SUFFIXES: 15 | 16 | AR := $(CROSS)ar 17 | CC := $(CROSS)gcc 18 | LD := $(CROSS)ld 19 | OBJCOPY := $(CROSS)objcopy 20 | OBJDUMP := $(CROSS)objdump 21 | SIZE := $(CROSS)size 22 | NM := $(CROSS)nm 23 | GDB := gdb-multiarch 24 | 25 | ELF := $(PROGRAM).elf 26 | BIN := $(PROGRAM).bin 27 | HEX := $(PROGRAM).hex 28 | MAP := $(PROGRAM).map 29 | DMP := $(PROGRAM).out 30 | 31 | TOPDIR := $(shell pwd) 32 | DEPDIR := $(TOPDIR)/.dep 33 | OBJS := $(SRCS:.c=.o) 34 | 35 | # Debugging 36 | CFLAGS += -Wall -Wdouble-promotion -g3 -gdwarf-4 37 | # Optimizations 38 | # NOTE: without optimization everything will fail... Computational power is marginal. 39 | CFLAGS += -O2 -fbranch-target-load-optimize -fipa-pta -frename-registers -fgcse-sm -fgcse-las -fsplit-loops -fstdarg-opt 40 | # Selected flags from -O3 41 | CFLAGS += -funswitch-loops -fpredictive-commoning -fgcse-after-reload \ 42 | -fsplit-paths -ftree-slp-vectorize -fvect-cost-model -ftree-partial-pre -fipa-cp-clone 43 | # -ftree-loop-vectorize -ftree-loop-distribution -ftree-loop-distribute-patterns -floop-interchange \ 44 | # Use these for debugging-friendly binary 45 | #CFLAGS += -O0 46 | #CFLAGS += -Og 47 | # Disabling aggressive loop optimizations since it does not work for loops longer than certain iterations 48 | CFLAGS += -fno-aggressive-loop-optimizations 49 | # Aggressive optimizations (unstable or causes huge binaries, e.g. peel-loops gives huge gpio_mode_setup, which is rarely used) 50 | #CFLAGS += -finline-functions -fpeel-loops -funroll-loops -floop-unroll-and-jam -fbranch-target-load-optimize2 51 | # Includes 52 | CFLAGS += -Ilibopencm3/include/ -I$(TOPDIR) 53 | # Config 54 | CONFIG := TICK_HZ=$(CONFIG_TICK_HZ) DEEP_SLEEP=$(CONFIG_DEEP_SLEEP) ENABLE_LEDS=$(CONFIG_ENABLE_LEDS) 55 | CFLAGS += $(addprefix -D,$(CONFIG)) 56 | 57 | # Generate dependency information 58 | CFLAGS += -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td 59 | $(shell mkdir -p $(DEPDIR) >/dev/null) 60 | PRECOMPILE = mkdir -p $(dir $(DEPDIR)/$*.Td) 61 | POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@ 62 | 63 | # Architecture-dependent 64 | LDSCRIPT := libopencm3/lib/stm32/l0/stm32l0xx6.ld 65 | ARCH_FLAGS := -DSTM32L0 -mthumb -mcpu=cortex-m0plus -msoft-float -fsingle-precision-constant -ffast-math -flto --specs=nano.specs 66 | OPENCM3_MK := lib/stm32/l0 67 | LIBOPENCM3 := libopencm3/lib/libopencm3_stm32l0.a 68 | CFLAGS += $(ARCH_FLAGS) 69 | CFLAGS += -fno-common -ffunction-sections -fdata-sections 70 | # LDPATH is required for libopencm3's ld scripts to work. 71 | LDPATH := libopencm3/lib/ 72 | # NOTE: the rule will ensure CFLAGS are added during linking 73 | LDFLAGS += -nostdlib -L$(LDPATH) -T$(LDSCRIPT) -Wl,-Map -Wl,$(MAP) -Wl,--gc-sections -Wl,--relax 74 | LDLIBS += $(LIBOPENCM3) -lc -lgcc 75 | 76 | 77 | default: $(BIN) $(HEX) $(DMP) size 78 | 79 | $(ELF): $(LDSCRIPT) $(OBJS) $(LIBOPENCM3) Makefile 80 | $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) 81 | 82 | $(DMP): $(ELF) 83 | $(OBJDUMP) -d $< > $@ 84 | 85 | %.hex: %.elf 86 | $(OBJCOPY) -S -O ihex $< $@ 87 | 88 | %.bin: %.elf 89 | $(OBJCOPY) -S -O binary $< $@ 90 | 91 | %.o: %.c $(LIBOPENCM3) Makefile 92 | $(PRECOMPILE) 93 | $(CC) $(CFLAGS) -c $< -o $@ 94 | $(POSTCOMPILE) 95 | 96 | # NOTE: libopencm3's Makefile is unaware of top-level Makefile changes, so force remake 97 | # NOTE: update ld script modified time to avoid unnecessary remaking 98 | $(LIBOPENCM3) $(LDSCRIPT): Makefile 99 | git submodule update --init 100 | make -B -C libopencm3 CFLAGS="$(CFLAGS)" PREFIX=$(patsubst %-,%,$(CROSS)) $(OPENCM3_MK) 101 | if [ -e $(LDSCRIPT) ]; then touch $(LDSCRIPT); fi 102 | 103 | 104 | .PHONY: clean distclean size symbols symbols_bss flash erase debug monitor check 105 | 106 | clean: 107 | rm -f $(OBJS) $(ELF) $(HEX) $(BIN) $(MAP) $(DMP) 108 | rm -rf $(DEPDIR) 109 | 110 | distclean: clean 111 | make -C libopencm3 clean 112 | rm -f *.o *~ *.swp *.hex 113 | 114 | # These targets want clean terminal output 115 | size: $(ELF) 116 | @echo "" 117 | @$(SIZE) $< 118 | @echo "" 119 | 120 | symbols: $(ELF) 121 | @$(NM) --demangle --size-sort -S $< | grep -v ' [bB] ' 122 | 123 | symbols_bss: $(ELF) 124 | @$(NM) --demangle --size-sort -S $< | grep ' [bB] ' 125 | 126 | flash: $(HEX) 127 | @killall st-util || echo 128 | @st-flash --reset --format ihex write $< 129 | 130 | erase: 131 | @killall st-util || echo 132 | @st-flash erase 133 | 134 | debug: $(ELF) 135 | @killall st-util || echo 136 | @setsid st-util & 137 | @-$(GDB) $< -q -ex 'target extended-remote localhost:4242' -ex 'load' 138 | 139 | # Dependencies 140 | $(DEPDIR)/%.d: 141 | .PRECIOUS: $(DEPDIR)/%.d 142 | include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS)))) 143 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | 16 | 17 | /* NOTE: we only use GPIOA */ 18 | #define DECA_IRQ_PIN GPIO3 19 | #define DECA_IRQ_EXTI EXTI3 20 | #define DECA_IRQ NVIC_EXTI2_3_IRQ 21 | #define DECA_IRQ_ISR exti2_3_isr 22 | 23 | #define DECA_RST_PIN GPIO2 24 | 25 | #define LTC_PG_PIN GPIO0 26 | 27 | #define DECA_NODE_MODE 1 /* Mode 0 has lower power than mode 1 according to datasheet, but mode 1 consumes much less energy */ 28 | #define DECA_NODE_ADDR 0x00 29 | 30 | /* NOTE: although BSS is only around 1KB, the application needs quite some stack for packet handling. Minimum requirement would be a STM32L031 */ 31 | 32 | 33 | static const instanceConfig_t iconfig = { 34 | #if DECA_NODE_MODE == 0 35 | /* TREK1000 mode 1 */ 36 | .channelNumber = 2, 37 | .preambleCode = 4, 38 | .pulseRepFreq = DWT_PRF_16M, 39 | .dataRate = DWT_BR_110K, 40 | .preambleLen = DWT_PLEN_1024, 41 | .pacSize = DWT_PAC32, 42 | .nsSFD = 1, 43 | .sfdTO = 1025 + 64 - 32, 44 | #else 45 | /* TREK1000 mode 2 */ 46 | .channelNumber = 2, 47 | .preambleCode = 4, 48 | .pulseRepFreq = DWT_PRF_16M, 49 | .dataRate = DWT_BR_6M8, 50 | .preambleLen = DWT_PLEN_128, 51 | .pacSize = DWT_PAC8, 52 | .nsSFD = 0, 53 | .sfdTO = 129 + 8 - 8, 54 | #endif 55 | }; 56 | 57 | static const sfConfig_t sconfig = { 58 | #if DECA_NODE_MODE == 0 59 | /* TREK1000 mode 1 */ 60 | .slotDuration_ms = 28, 61 | .numSlots = 10, 62 | .sfPeriod_ms = 10 * 28, /* Localization rate */ 63 | .tagPeriod_ms = 10 * 28, 64 | .pollTxToFinalTxDly_us = 20000 65 | #else 66 | /* TREK1000 mode 2 */ 67 | .slotDuration_ms = 10, 68 | .numSlots = 10, 69 | .sfPeriod_ms = 10 * 10, /* Localization rate */ 70 | .tagPeriod_ms = 10 * 10, 71 | .pollTxToFinalTxDly_us = 2700, /* Was 2500, slacked a bit (should not exceed 5000). Debug with 'b instance_tag.c:244' */ 72 | #endif 73 | }; 74 | 75 | static dwt_local_data_t dw1000local; 76 | static instance_data_t instance; 77 | 78 | 79 | /* Wake-up is triggered when NSS driven low (here by enabling SPI), but oscillator needs 5ms to stabilize. */ 80 | static void __attribute__((unused)) wakeup_chip(void) { 81 | spi_enable(SPI1); 82 | tick_sleep(1); 83 | spi_disable(SPI1); 84 | tick_sleep(7); 85 | } 86 | 87 | /* DW1000 mode 0, < 3 MHz before PLL lock, < 20 MHz after PLL lock */ 88 | /* Always run SPI as fast as we can, tune system clock instead to conserve power */ 89 | /* TODO: FIFO and interrupts (but libopencm3 do not sleep during SPI operation anyways) */ 90 | static void spi_setup(unsigned clk_div) { 91 | rcc_periph_clock_enable(RCC_SPI1); 92 | spi_reset(SPI1); 93 | spi_init_master(SPI1, clk_div, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); 94 | spi_disable_software_slave_management(SPI1); 95 | spi_enable_ss_output(SPI1); 96 | spi_disable_crc(SPI1); 97 | spi_set_full_duplex_mode(SPI1); 98 | spi_set_unidirectional_mode(SPI1); 99 | spi_set_dff_8bit(SPI1); 100 | } 101 | 102 | static void wait_pgood(void) { 103 | rcc_periph_clock_enable(RCC_GPIOA); 104 | #if 1 105 | while (!gpio_get(GPIOA, LTC_PG_PIN)) { 106 | asm("wfi"); 107 | } 108 | #else 109 | /* For debugging start-up process power consumption */ 110 | while (tick_get_uptime() < 2000); 111 | #endif 112 | rcc_periph_clock_disable(RCC_GPIOA); 113 | } 114 | 115 | 116 | int main(void) { 117 | os_init(); /* NOTE: system clock is now 4MHz */ 118 | 119 | rcc_periph_clock_enable(RCC_GPIOA); 120 | 121 | /* NOTE: DW1000 still consumes 4mA even when RST driven down. Needs to enter deep sleep ASAP by finishing instance_init(). */ 122 | 123 | gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, DECA_IRQ_PIN); /* TODO: use external pull-down with higher resistance? may not help much */ 124 | nvic_set_priority(DECA_IRQ, 60); 125 | nvic_enable_irq(DECA_IRQ); 126 | exti_select_source(DECA_IRQ_EXTI, GPIOA); 127 | exti_set_trigger(DECA_IRQ_EXTI, EXTI_TRIGGER_RISING); 128 | exti_enable_request(DECA_IRQ_EXTI); 129 | 130 | gpio_set_af(GPIOA, GPIO_AF0, GPIO4 | GPIO5 | GPIO6 | GPIO7); 131 | gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO4 | GPIO5 | GPIO6 | GPIO7); 132 | gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO4 | GPIO5 | GPIO6 | GPIO7); 133 | 134 | gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, LTC_PG_PIN); 135 | //rcc_periph_clock_disable(RCC_GPIOA); /* wait_pgood() does this for us */ 136 | 137 | dwt_setdevicedataptr(&dw1000local); 138 | spi_setup(SPI_CR1_BAUDRATE_FPCLK_DIV_2); 139 | /* 140 | wakeup_chip(); 141 | if (DWT_DEVICE_ID != instance_readdeviceid()) { 142 | os_panic(); 143 | } 144 | */ 145 | dwt_softreset(); /* Clear sleep bit if any, as good as hardware reset in most cases */ 146 | if (instance_init() != 0) { 147 | os_panic(); 148 | } 149 | instance_set_16bit_address(DECA_NODE_ADDR); 150 | instance_config(&iconfig, &sconfig); 151 | #if DEEP_SLEEP == 1 152 | tag_run(); /* Run once to complete tag INIT and enter deep sleep */ 153 | #endif 154 | 155 | rcc_periph_clock_disable(RCC_SPI1); /* Shouldn't have communication for a while */ 156 | 157 | wait_pgood(); 158 | os_dvfs_hsi16(); 159 | 160 | while (true) { 161 | wait_pgood(); 162 | 163 | rcc_periph_clock_enable(RCC_SPI1); 164 | exti_enable_request(DECA_IRQ_EXTI); 165 | do { 166 | tag_run(); 167 | } while (instance.testAppState != TA_SLEEP_DONE); 168 | exti_disable_request(DECA_IRQ_EXTI); /* Make sure nothing interrupts sleep :) */ 169 | rcc_periph_clock_disable(RCC_SPI1); 170 | 171 | os_pm_sleep_until(instance.instanceWakeTime_ms + instance.tagPeriod_ms - 1); 172 | } 173 | 174 | return 0; 175 | } 176 | 177 | /* Implementations of low-level deca_device_api */ 178 | 179 | static void spi_rx(uint32_t spi, uint8_t *rxbuf, uint32_t len) { 180 | uint32_t i; 181 | 182 | for (i = 0; i < len; i ++) { 183 | rxbuf[i] = spi_xfer(spi, 0x00); /* Need to feed to get */ 184 | } 185 | } 186 | 187 | static void spi_tx(uint32_t spi, const uint8_t *txbuf, uint32_t len) { 188 | uint32_t i; 189 | 190 | for (i = 0; i < len; i ++) { 191 | spi_xfer(spi, txbuf[i]); /* One in, one out. Read it is critical, even if it is garbage. */ 192 | } 193 | return; 194 | } 195 | 196 | /* A bit different from spi_clean_disable() */ 197 | static void spi_disable_after_io(uint32_t spi) { 198 | while (!(SPI_SR(spi) & SPI_SR_TXE)); 199 | while (SPI_SR(spi) & SPI_SR_BSY); 200 | SPI_CR1(spi) &= ~SPI_CR1_SPE; 201 | } 202 | 203 | int writetospi(uint16 headerLength, const uint8 *headerBuffer, uint32 bodylength, const uint8 *bodyBuffer) { 204 | spi_enable(SPI1); 205 | spi_tx(SPI1, headerBuffer, headerLength); 206 | spi_tx(SPI1, bodyBuffer, bodylength); 207 | spi_disable_after_io(SPI1); 208 | 209 | return DWT_SUCCESS; 210 | } 211 | 212 | int readfromspi(uint16 headerLength, const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer) { 213 | spi_enable(SPI1); 214 | spi_tx(SPI1, headerBuffer, headerLength); 215 | spi_rx(SPI1, readBuffer, readlength); 216 | spi_disable_after_io(SPI1); 217 | 218 | return DWT_SUCCESS; 219 | } 220 | 221 | /* Does not seem to be useful */ 222 | decaIrqStatus_t decamutexon(void) { 223 | //exti_disable_request(DECA_IRQ_EXTI); 224 | return 0; 225 | } 226 | 227 | void decamutexoff(__attribute__((unused)) decaIrqStatus_t s) { 228 | //exti_enable_request(DECA_IRQ_EXTI); 229 | } 230 | 231 | void deca_sleep(unsigned int time_ms) { 232 | tick_sleep(time_ms); 233 | } 234 | 235 | /* Implementations of deca_rtls_port */ 236 | 237 | void port_wakeup_dw1000_fast(void) { 238 | spi_enable(SPI1); 239 | tick_sleep(1); 240 | spi_disable(SPI1); 241 | tick_delay_us(35); 242 | } 243 | 244 | instance_data_t* instance_get_local_structure_ptr(__attribute__((unused)) unsigned int x) { 245 | return &instance; 246 | } 247 | 248 | 249 | /* IRQ handler */ 250 | void DECA_IRQ_ISR(void) { 251 | exti_reset_request(DECA_IRQ_EXTI); 252 | dwt_isr(); 253 | } 254 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /decartls/instance_common.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | /* instance_calib.c */ 10 | extern const uint16 rfDelays[2]; 11 | extern const uint16 rfDelaysTREK[2]; 12 | extern const tx_struct txSpectrumConfig[8]; 13 | /* deca_params_init.c */ 14 | extern uint8 dwnsSFDlen[]; 15 | extern uint8 chan_idx[]; 16 | 17 | 18 | static uint64 instance_convert_usec_to_devtimeu(float microsecu) { 19 | /* NOTE: float to uint64_t calls __aeabi_f2ulz(), which then calls __aeabi_dsub()/__aeabi_d2uiz(). */ 20 | /* To avoid double-precision float points, we need to eliminate this stuff */ 21 | uint32_t hi, lo; 22 | microsecu = (microsecu / DWT_TIME_UNITS) / 1e6f; 23 | hi = microsecu / ((1 << 31) * 2.0f); 24 | lo = microsecu - (hi * ((1 << 31) * 2.0f)); 25 | return ((uint64_t)hi) << 32 | lo; 26 | } 27 | 28 | static unsigned calc_length_data(unsigned msgdatalen) { 29 | instance_data_t* inst = instance_get_local_structure_ptr(0); 30 | int x = msgdatalen * 8 / 330; 31 | 32 | if (msgdatalen * 8 % 330) { 33 | x ++; 34 | } 35 | 36 | msgdatalen = msgdatalen * 8 + x * 48; 37 | 38 | /* assume PHR length is 172308ns for 110k and 21539ns for 850k/6.81M */ 39 | if (inst->configData.dataRate == DWT_BR_110K) { 40 | msgdatalen *= 8205.13f; 41 | msgdatalen += 172308; 42 | 43 | } else if (inst->configData.dataRate == DWT_BR_850K) { 44 | msgdatalen *= 1025.64f; 45 | msgdatalen += 21539; 46 | } else { 47 | msgdatalen *= 128.21f; 48 | msgdatalen += 21539; 49 | } 50 | 51 | return msgdatalen; 52 | } 53 | 54 | static void instance_set_replydelay(int delayus) { 55 | instance_data_t *inst = instance_get_local_structure_ptr(0); 56 | 57 | int margin = 1000; /* Was 3000 */ 58 | int respframe = 0; 59 | int respframe_sy = 0; 60 | int pollframe_sy = 0; 61 | unsigned msgdatalen_resp = 0; 62 | unsigned msgdatalen_poll = 0; 63 | unsigned preamblelen = 0; 64 | int sfdlen = 0; 65 | 66 | msgdatalen_resp = calc_length_data(ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC); 67 | msgdatalen_poll = calc_length_data(TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC); 68 | 69 | sfdlen = dwnsSFDlen[inst->configData.dataRate]; 70 | 71 | /* TODO: make it a look-up table rather than this... */ 72 | switch (inst->configData.txPreambLength) { 73 | case DWT_PLEN_4096: 74 | preamblelen = 4096; 75 | break; 76 | case DWT_PLEN_2048: 77 | preamblelen = 2048; 78 | break; 79 | case DWT_PLEN_1536: 80 | preamblelen = 1536; 81 | break; 82 | case DWT_PLEN_1024: 83 | preamblelen = 1024; 84 | break; 85 | case DWT_PLEN_512: 86 | preamblelen = 512; 87 | break; 88 | case DWT_PLEN_256: 89 | preamblelen = 256; 90 | break; 91 | case DWT_PLEN_128: 92 | preamblelen = 128; 93 | break; 94 | case DWT_PLEN_64: 95 | preamblelen = 64; 96 | break; 97 | } 98 | 99 | if (inst->configData.prf == DWT_PRF_16M) { 100 | preamblelen = (sfdlen + preamblelen) * 0.99359f; 101 | } else { 102 | preamblelen = (sfdlen + preamblelen) * 1.01763f; 103 | } 104 | 105 | respframe_sy = (DW_RX_ON_DELAY + (int)((preamblelen + ((msgdatalen_resp + margin) / 1000)) / 1.0256)); 106 | pollframe_sy = (DW_RX_ON_DELAY + (int)((preamblelen + ((msgdatalen_poll + margin) / 1000)) / 1.0256)); 107 | 108 | inst->pollTx2FinalTxDelay = instance_convert_usec_to_devtimeu(delayus); 109 | 110 | respframe = (int)(preamblelen + (msgdatalen_resp / 1000)); 111 | if (inst->configData.dataRate == DWT_BR_110K) { 112 | inst->preambleDuration32h = (uint32) (((uint64) instance_convert_usec_to_devtimeu (preamblelen)) >> 8) + DW_RX_ON_DELAY; 113 | } else { 114 | inst->preambleDuration32h = (uint32) (((uint64) instance_convert_usec_to_devtimeu (preamblelen)) >> 8) + DW_RX_ON_DELAY; 115 | } 116 | 117 | inst->tagRespRxDelay_sy = RX_RESPONSE_TURNAROUND + respframe_sy - pollframe_sy; 118 | inst->fixedReplyDelayAnc32h = ((uint64)instance_convert_usec_to_devtimeu (respframe + RX_RESPONSE_TURNAROUND) >> 8); 119 | inst->fwto4RespFrame_sy = respframe_sy; 120 | } 121 | 122 | int instance_init(void) { 123 | instance_data_t* inst = instance_get_local_structure_ptr(0); 124 | 125 | inst->testAppState = TA_INIT; 126 | inst->instToSleep = FALSE; 127 | 128 | if (DWT_SUCCESS != dwt_initialise(DWT_LOADUCODE)) { 129 | return -1; 130 | } 131 | 132 | /* Enable TXLED and RXLED. Do not blink after init to conserve power if deep sleep enabled. */ 133 | #if ENABLE_LEDS && !DEEP_SLEEP 134 | dwt_setleds(3); 135 | #endif 136 | 137 | inst->frameSN = 0; 138 | inst->wait4ack = 0; 139 | inst->instanceTimerEn = 0; 140 | 141 | instance_clearevents(); 142 | 143 | memset(inst->eui64, 0, ADDR_BYTE_SIZE_L); 144 | inst->panID = 0xdeca; 145 | inst->tagSleepCorrection_ms = 0; 146 | 147 | dwt_setdblrxbuffmode(0); 148 | 149 | /* if using auto CRC check (DWT_INT_RFCG and DWT_INT_RFCE) are used instead of DWT_INT_RDFR flag 150 | * other errors which need to be checked (as they disable receiver) are 151 | */ 152 | //dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_SFDT | DWT_INT_RFTO /*| DWT_INT_RXPTO*/), 1); 153 | dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_ARFE | DWT_INT_RFSL | DWT_INT_SFDT | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFTO | DWT_INT_RXPTO), 1); 154 | dwt_setcallbacks(tx_conf_cb, rx_ok_cb_tag, rx_err_cb_tag, rx_err_cb_tag); 155 | 156 | inst->remainingRespToRx = -1; 157 | 158 | dwt_setlnapamode(1, 1); 159 | 160 | inst->delayedTRXTime32h = 0; 161 | 162 | return 0; 163 | } 164 | 165 | /* OTP memory addresses for TREK calibration data */ 166 | #define TXCFG_ADDRESS (0x10) 167 | #define ANTDLY_ADDRESS (0x1c) 168 | #define TREK_ANTDLY_1 (0x0d) 169 | #define TREK_ANTDLY_2 (0x0e) 170 | #define TREK_ANTDLY_3 (0x0f) 171 | #define TREK_ANTDLY_4 (0x1d) 172 | 173 | void instance_config(const instanceConfig_t *config, const sfConfig_t *sfConfig) { 174 | instance_data_t* inst = instance_get_local_structure_ptr(0); 175 | uint32 power = 0; 176 | uint8 otprev; 177 | 178 | inst->configData.chan = config->channelNumber; 179 | inst->configData.rxCode = config->preambleCode; 180 | inst->configData.txCode = config->preambleCode; 181 | inst->configData.prf = config->pulseRepFreq; 182 | inst->configData.dataRate = config->dataRate; 183 | inst->configData.txPreambLength = config->preambleLen; 184 | inst->configData.rxPAC = config->pacSize; 185 | inst->configData.nsSFD = config->nsSFD; 186 | inst->configData.phrMode = DWT_PHRMODE_STD; 187 | inst->configData.sfdTO = config->sfdTO; 188 | 189 | dwt_configure(&inst->configData); 190 | 191 | /* NOTE: main.c ensures this function is only called when SPI is slow */ 192 | dwt_otpread(TXCFG_ADDRESS+(config->pulseRepFreq - DWT_PRF_16M) + (chan_idx[inst->configData.chan] * 2), &power, 1); 193 | if ((power == 0x0) || (power == 0xffffffff)) { 194 | /* No cal found, load defaults */ 195 | power = txSpectrumConfig[config->channelNumber].txPwr[config->pulseRepFreq - DWT_PRF_16M]; 196 | } 197 | 198 | inst->configTX.power = power; 199 | inst->configTX.PGdly = txSpectrumConfig[config->channelNumber].pgDelay; 200 | dwt_configuretxrf(&inst->configTX); 201 | 202 | otprev = dwt_otprevision(); 203 | 204 | if ((2 == otprev) || (3 == otprev)) { 205 | /* board is calibrated with TREK1000 with antenna delays set for each use case) */ 206 | uint8 mode = 0; /* TAG */ 207 | uint32 dly = 0; 208 | 209 | switch(inst->configData.chan) { 210 | case 2: { 211 | if (inst->configData.dataRate == DWT_BR_6M8) { 212 | dwt_otpread(TREK_ANTDLY_1, &dly, 1); 213 | } else if (inst->configData.dataRate == DWT_BR_110K) { 214 | dwt_otpread(TREK_ANTDLY_2, &dly, 1); 215 | } 216 | break; 217 | } 218 | 219 | case 5: { 220 | if (inst->configData.dataRate == DWT_BR_6M8) { 221 | dwt_otpread(TREK_ANTDLY_3, &dly, 1); 222 | } else if (inst->configData.dataRate == DWT_BR_110K) { 223 | dwt_otpread(TREK_ANTDLY_4, &dly, 1); 224 | } 225 | break; 226 | } 227 | 228 | default: { 229 | dly = 0; 230 | break; 231 | } 232 | } 233 | 234 | if ((dly == 0) || (dly == 0xffffffff)) { 235 | uint8 chanindex = (inst->configData.chan == 5) ? 1 : 0; 236 | inst->txAntennaDelay = rfDelaysTREK[chanindex]; 237 | } else { 238 | inst->txAntennaDelay = (dly >> (16 * (mode & 0x1))) & 0xFFFF; 239 | } 240 | } else { 241 | uint32 antennaDly; 242 | 243 | dwt_otpread(ANTDLY_ADDRESS, &antennaDly, 1); 244 | if ((antennaDly == 0) || (antennaDly == 0xffffffff)) { 245 | inst->txAntennaDelay = rfDelays[config->pulseRepFreq - DWT_PRF_16M]; 246 | } else { 247 | inst->txAntennaDelay = ((antennaDly >> (16 * (inst->configData.prf-DWT_PRF_16M))) & 0xFFFF) >> 1; 248 | } 249 | } 250 | 251 | dwt_setrxantennadelay(inst->txAntennaDelay); 252 | dwt_settxantennadelay(inst->txAntennaDelay); 253 | 254 | if (config->preambleLen == DWT_PLEN_64) { 255 | dwt_loadopsettabfromotp(0); 256 | } 257 | 258 | inst->tagPeriod_ms = sfConfig->tagPeriod_ms; 259 | inst->tagSleepRnd_ms = sfConfig->slotDuration_ms; 260 | instance_set_replydelay(sfConfig->pollTxToFinalTxDly_us); 261 | } 262 | 263 | void instance_set_16bit_address(uint16 address) { 264 | instance_data_t* inst = instance_get_local_structure_ptr(0); 265 | inst->instanceAddress16 = address; 266 | } 267 | 268 | void instance_config_frameheader_16bit(instance_data_t *inst) { 269 | /* set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6) */ 270 | inst->msg_f.frameCtrl[0] = 0x1 /* frame type 0x1 == data */ | 0x40 /* PID comp */; 271 | inst->msg_f.frameCtrl[1] = 0x8 /* dest extended address (16bits) */ | 0x80 /* src extended address (16bits) */; 272 | 273 | inst->msg_f.panID[0] = (inst->panID) & 0xff; 274 | inst->msg_f.panID[1] = inst->panID >> 8; 275 | 276 | inst->msg_f.seqNum = 0; 277 | } 278 | 279 | int instance_send_delayed_frame(instance_data_t *inst, int delayedTx) { 280 | int result = 0; 281 | 282 | dwt_writetxfctrl(inst->psduLength, 0, 1); 283 | if (delayedTx == DWT_START_TX_DELAYED) { 284 | dwt_setdelayedtrxtime(inst->delayedTRXTime32h); 285 | } 286 | 287 | if (dwt_starttx(delayedTx | inst->wait4ack)) { 288 | /* delayed start was too late */ 289 | result = 1; 290 | } 291 | return result; 292 | } 293 | 294 | void tx_conf_cb(const dwt_cb_data_t *txd) { 295 | instance_data_t* inst = instance_get_local_structure_ptr(0); 296 | uint8 txTimeStamp[5] = {0, 0, 0, 0, 0}; 297 | event_data_t dw_event; 298 | 299 | dwt_readtxtimestamp(txTimeStamp); 300 | instance_seteventtime(&dw_event, txTimeStamp); 301 | 302 | dw_event.rxLength = inst->psduLength; 303 | dw_event.type = 0; 304 | dw_event.typePend = 0; 305 | 306 | memcpy((uint8 *)&dw_event.msgu.frame[0], (uint8 *)&inst->msg_f, inst->psduLength); 307 | 308 | instance_putevent(dw_event, DWT_SIG_TX_DONE); 309 | } 310 | 311 | void instance_seteventtime(event_data_t *dw_event, uint8* timeStamp) { 312 | dw_event->timeStamp32l = (uint32)timeStamp[0] + ((uint32)timeStamp[1] << 8) + ((uint32)timeStamp[2] << 16) + ((uint32)timeStamp[3] << 24); 313 | dw_event->timeStamp = timeStamp[4]; 314 | dw_event->timeStamp <<= 32; 315 | dw_event->timeStamp += dw_event->timeStamp32l; 316 | dw_event->timeStamp32h = ((uint32)timeStamp[4] << 24) + (dw_event->timeStamp32l >> 8); 317 | } 318 | 319 | int instance_peekevent(void) { 320 | instance_data_t* inst = instance_get_local_structure_ptr(0); 321 | return inst->dwevent[inst->dweventIdxOut].type; //return the type of event that is in front of the queue 322 | } 323 | 324 | void instance_putevent(event_data_t newevent, uint8 etype) { 325 | instance_data_t* inst = instance_get_local_structure_ptr(0); 326 | 327 | inst->dwevent[inst->dweventIdxIn] = newevent; 328 | inst->dwevent[inst->dweventIdxIn].type = etype; 329 | inst->dweventIdxIn ++; 330 | 331 | if (MAX_EVENT_NUMBER == inst->dweventIdxIn) { 332 | inst->dweventIdxIn = 0; 333 | } 334 | } 335 | 336 | event_data_t* instance_getevent(int x) { 337 | instance_data_t* inst = instance_get_local_structure_ptr(0); 338 | int indexOut = inst->dweventIdxOut; 339 | 340 | if (inst->dwevent[indexOut].type == 0) { 341 | /* exit with "no event" */ 342 | inst->dw_event_g.type = 0; 343 | return &(inst->dw_event_g); 344 | } 345 | 346 | memcpy(&(inst->dw_event_g), &(inst->dwevent[indexOut]), sizeof(inst->dw_event_g)); 347 | memcpy(&(inst->dw_event_g.msgu), &inst->dwevent[indexOut].msgu, sizeof(inst->dwevent[indexOut].msgu)); 348 | 349 | /* clear the event */ 350 | inst->dwevent[indexOut].type = 0; 351 | 352 | inst->dweventIdxOut++; 353 | if (MAX_EVENT_NUMBER == inst->dweventIdxOut) { 354 | inst->dweventIdxOut = 0; 355 | } 356 | 357 | return &(inst->dw_event_g); 358 | } 359 | 360 | void instance_clearevents(void) { 361 | int i; 362 | instance_data_t* inst = instance_get_local_structure_ptr(0); 363 | 364 | for(i = 0; i < MAX_EVENT_NUMBER; i++) { 365 | memset(&inst->dwevent[i], 0, sizeof(event_data_t)); 366 | } 367 | 368 | inst->dweventIdxIn = 0; 369 | inst->dweventIdxOut = 0; 370 | } 371 | 372 | void instance_config_txpower(uint32 txpower) { 373 | instance_data_t* inst = instance_get_local_structure_ptr(0); 374 | inst->txPower = txpower; 375 | inst->txPowerChanged = 1; 376 | } 377 | 378 | void instance_set_txpower(void) { 379 | instance_data_t* inst = instance_get_local_structure_ptr(0); 380 | if (inst->txPowerChanged == 1) { 381 | dwt_write32bitreg(0x1e, inst->txPower); 382 | inst->txPowerChanged = 0; 383 | } 384 | } 385 | -------------------------------------------------------------------------------- /decartls/instance_tag.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | // NOTE: the maximum RX timeout is ~ 65ms 11 | 12 | #define ADDR16_TO_ANCHOR_N(x) (x & (~0x80)) 13 | 14 | 15 | static void tag_enable_rx(uint32 dlyTime) { 16 | instance_data_t* inst = instance_get_local_structure_ptr(0); 17 | 18 | dwt_setdelayedtrxtime(dlyTime - inst->preambleDuration32h); 19 | if (dwt_rxenable(DWT_START_RX_DELAYED | DWT_IDLE_ON_DLY_ERR)) { 20 | dwt_setpreambledetecttimeout(0); 21 | dwt_setrxtimeout((uint16)inst->fwto4RespFrame_sy * 2); 22 | dwt_rxenable(DWT_START_RX_IMMEDIATE); 23 | dwt_setpreambledetecttimeout(PTO_PACS); 24 | dwt_setrxtimeout((uint16)inst->fwto4RespFrame_sy); 25 | } 26 | } 27 | 28 | static void tag_process_rx_timeout(instance_data_t *inst) { 29 | if (inst->rxResponseMask == 0) { 30 | inst->instToSleep = TRUE; 31 | inst->testAppState = TA_TXE_WAIT; 32 | inst->nextState = TA_TXPOLL_WAIT_SEND; 33 | } else if (inst->previousState == TA_TXFINAL_WAIT_SEND) { 34 | dwt_forcetrxoff(); /* this will clear all events */ 35 | inst->instToSleep = TRUE; 36 | inst->testAppState = TA_TXE_WAIT; 37 | inst->nextState = TA_TXPOLL_WAIT_SEND; 38 | } else { 39 | inst->testAppState = TA_TXE_WAIT; 40 | inst->nextState = TA_TXFINAL_WAIT_SEND; 41 | } 42 | } 43 | 44 | static uint8 tag_rx_reenable(uint16 sourceAddress, uint8 error) { 45 | instance_data_t* inst = instance_get_local_structure_ptr(0); 46 | uint8 anc = ADDR16_TO_ANCHOR_N(sourceAddress); 47 | 48 | if (anc != NUM_EXPECTED_RESPONSES) { 49 | /* Not last anchor */ 50 | if (inst->remainingRespToRx > 0) { 51 | if (error == 0) { 52 | inst->remainingRespToRx = NUM_EXPECTED_RESPONSES - anc; 53 | } 54 | tag_enable_rx(inst->tagPollTxTime32h + (MAX_ANCHOR_LIST_SIZE - inst->remainingRespToRx + 1) * (inst->fixedReplyDelayAnc32h)); 55 | 56 | return DWT_SIG_RX_PENDING; 57 | } else { 58 | return DWT_SIG_DW_IDLE; 59 | } 60 | } else { 61 | return DWT_SIG_DW_IDLE; 62 | } 63 | } 64 | 65 | static void tag_handle_error_unknownframe(event_data_t dw_event) { 66 | instance_data_t* inst = instance_get_local_structure_ptr(0); 67 | 68 | inst->remainingRespToRx--; 69 | dw_event.typePend = tag_rx_reenable(0, 1); 70 | dw_event.type = 0; 71 | dw_event.rxLength = 0; 72 | 73 | instance_putevent(dw_event, DWT_SIG_RX_TIMEOUT); 74 | } 75 | 76 | void rx_err_cb_tag(const dwt_cb_data_t *rxd) { 77 | event_data_t dw_event; 78 | tag_handle_error_unknownframe(dw_event); 79 | } 80 | 81 | void rx_ok_cb_tag(const dwt_cb_data_t *rxd) { 82 | instance_data_t* inst = instance_get_local_structure_ptr(0); 83 | uint8 rxTimeStamp[5] = {0, 0, 0, 0, 0}; 84 | uint8 rxd_event = SIG_RX_UNKNOWN; 85 | uint8 fcode_index = 0; 86 | uint8 srcAddr_index = 0; 87 | event_data_t dw_event; 88 | 89 | dw_event.rxLength = rxd->datalength; 90 | 91 | if (rxd->fctrl[0] == 0x41) { 92 | if ((rxd->fctrl[1] & 0xcc) == 0x88) { 93 | fcode_index = FRAME_CRTL_AND_ADDRESS_S; 94 | srcAddr_index = FRAME_CTRLP + ADDR_BYTE_SIZE_S; 95 | rxd_event = DWT_SIG_RX_OKAY; 96 | } 97 | } 98 | 99 | dwt_readrxtimestamp(rxTimeStamp); 100 | dwt_readrxdata((uint8 *)&dw_event.msgu.frame[0], rxd->datalength, 0); 101 | instance_seteventtime(&dw_event, rxTimeStamp); 102 | 103 | dw_event.type = 0; 104 | dw_event.typePend = DWT_SIG_DW_IDLE; 105 | 106 | if (rxd_event == DWT_SIG_RX_OKAY) { 107 | if (dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_ANCH_RESP) { 108 | uint16 sourceAddress = (((uint16)dw_event.msgu.frame[srcAddr_index + 1]) << 8) + dw_event.msgu.frame[srcAddr_index]; 109 | uint8 index = RRXT0 + 5 * ADDR16_TO_ANCHOR_N(sourceAddress); 110 | 111 | inst->remainingRespToRx--; 112 | dw_event.typePend = tag_rx_reenable(sourceAddress, 0); 113 | inst->rxResponseMask |= (1 << ADDR16_TO_ANCHOR_N(sourceAddress)); 114 | memcpy(&(inst->msg_f.messageData[index]), rxTimeStamp, 5); 115 | instance_putevent(dw_event, rxd_event); 116 | return; 117 | } 118 | } 119 | 120 | tag_handle_error_unknownframe(dw_event); 121 | } 122 | 123 | static int tag_do_ta_init(instance_data_t *inst) { 124 | dwt_enableframefilter(DWT_FF_DATA_EN | DWT_FF_ACK_EN); //allow data, ack frames; 125 | 126 | inst->eui64[0] += inst->instanceAddress16; 127 | dwt_seteui(inst->eui64); 128 | dwt_setpanid(inst->panID); 129 | memcpy(inst->eui64, &inst->instanceAddress16, ADDR_BYTE_SIZE_S); 130 | dwt_setaddress16(inst->instanceAddress16); 131 | 132 | inst->instToSleep = TRUE; 133 | inst->tagSleepTime_ms = inst->tagPeriod_ms; 134 | inst->rangeNum = 0; 135 | inst->tagSleepCorrection_ms = 0; 136 | 137 | #if (DEEP_SLEEP == 1) 138 | { 139 | uint16 sleep_mode = (DWT_PRESRV_SLEEP | DWT_CONFIG | DWT_TANDV); 140 | 141 | if (inst->configData.txPreambLength == DWT_PLEN_64) { 142 | sleep_mode |= DWT_LOADOPSET; 143 | } 144 | 145 | dwt_configuresleep(sleep_mode, DWT_WAKE_WK | DWT_WAKE_CS | DWT_SLP_EN); //configure the on wake parameters (upload the IC config settings) 146 | } 147 | #endif 148 | instance_config_frameheader_16bit(inst); 149 | 150 | inst->nextState = TA_TXPOLL_WAIT_SEND; 151 | inst->testAppState = TA_TXE_WAIT; 152 | inst->instanceWakeTime_ms = portGetTickCnt(); 153 | return INST_NOT_DONE_YET; 154 | } 155 | 156 | static int tag_do_ta_sleep_done(instance_data_t *inst) { 157 | event_data_t* dw_event = instance_getevent(10); //clear the event from the queue 158 | 159 | if (dw_event->type != DWT_SIG_RX_TIMEOUT) { 160 | /* Wait for sleep timeout */ 161 | return INST_DONE_WAIT_FOR_NEXT_EVENT; 162 | } 163 | 164 | inst->instToSleep = FALSE; 165 | inst->testAppState = inst->nextState; 166 | inst->nextState = 0; //clear 167 | inst->instanceWakeTime_ms = portGetTickCnt(); 168 | #if DEEP_SLEEP 169 | port_wakeup_dw1000_fast(); 170 | #if ENABLE_LEDS 171 | dwt_setleds(1); 172 | #endif 173 | /* MP bug - TX antenna delay needs reprogramming as it is not preserved (only RX) */ 174 | dwt_settxantennadelay(inst->txAntennaDelay); 175 | /* set EUI (not preserved) */ 176 | dwt_seteui(inst->eui64); 177 | #endif 178 | 179 | instance_set_txpower(); 180 | 181 | return INST_NOT_DONE_YET; 182 | } 183 | 184 | static int tag_do_ta_txe_wait(instance_data_t *inst) { 185 | /* if we are scheduled to go to sleep before next transmission then sleep first. */ 186 | if ((inst->nextState == TA_TXPOLL_WAIT_SEND) && (inst->instToSleep)) { 187 | inst->rangeNum ++; 188 | inst->testAppState = TA_SLEEP_DONE; 189 | #if DEEP_SLEEP 190 | dwt_entersleep(); 191 | #endif 192 | if (inst->rxResponseMask != 0) { 193 | inst->rxResponseMask = 0; 194 | } 195 | return INST_DONE_WAIT_FOR_NEXT_EVENT_TO; 196 | } else { 197 | /* Proceed */ 198 | inst->testAppState = inst->nextState; 199 | inst->nextState = 0; 200 | return INST_NOT_DONE_YET; 201 | } 202 | } 203 | 204 | static int tag_do_ta_txpoll_wait_send(instance_data_t *inst) { 205 | inst->msg_f.messageData[POLL_RNUM] = inst->rangeNum; 206 | inst->msg_f.messageData[FCODE] = RTLS_DEMO_MSG_TAG_POLL; 207 | inst->psduLength = (TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC); 208 | inst->msg_f.seqNum = inst->frameSN ++; 209 | inst->msg_f.sourceAddr[0] = inst->instanceAddress16 & 0xff; 210 | inst->msg_f.sourceAddr[1] = (inst->instanceAddress16 >> 8) & 0xff; 211 | inst->msg_f.destAddr[0] = 0xff; 212 | inst->msg_f.destAddr[1] = 0xff; 213 | dwt_writetxdata(inst->psduLength, (uint8 *)&inst->msg_f, 0); 214 | 215 | dwt_setrxaftertxdelay((uint32)inst->tagRespRxDelay_sy); 216 | 217 | inst->remainingRespToRx = MAX_ANCHOR_LIST_SIZE; 218 | dwt_setrxtimeout((uint16)inst->fwto4RespFrame_sy); 219 | dwt_setpreambledetecttimeout(PTO_PACS); 220 | 221 | inst->rxResponseMask = 0; 222 | inst->wait4ack = DWT_RESPONSE_EXPECTED; 223 | 224 | dwt_writetxfctrl(inst->psduLength, 0, 1); 225 | dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED); 226 | 227 | inst->testAppState = TA_TX_WAIT_CONF; 228 | inst->previousState = TA_TXPOLL_WAIT_SEND; 229 | 230 | return INST_DONE_WAIT_FOR_NEXT_EVENT; 231 | } 232 | 233 | static int tag_do_ta_txfinal_wait_send(instance_data_t *inst) { 234 | inst->msg_f.messageData[POLL_RNUM] = inst->rangeNum; 235 | inst->msg_f.messageData[VRESP] = inst->rxResponseMask; 236 | inst->msg_f.messageData[FCODE] = RTLS_DEMO_MSG_TAG_FINAL; 237 | inst->psduLength = (TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC); 238 | inst->msg_f.seqNum = inst->frameSN ++; 239 | dwt_writetxdata(inst->psduLength, (uint8 *) &inst->msg_f, 0); 240 | 241 | inst->wait4ack = 0; 242 | 243 | if (instance_send_delayed_frame(inst, DWT_START_TX_DELAYED)) { 244 | /* go to TA_TXE_WAIT first to check if it's sleep time */ 245 | inst->testAppState = TA_TXE_WAIT; 246 | inst->nextState = TA_TXPOLL_WAIT_SEND; 247 | inst->instToSleep = TRUE; 248 | return INST_NOT_DONE_YET; 249 | } else { 250 | inst->testAppState = TA_TX_WAIT_CONF; 251 | inst->previousState = TA_TXFINAL_WAIT_SEND; 252 | inst->instToSleep = TRUE; 253 | return INST_DONE_WAIT_FOR_NEXT_EVENT; 254 | } 255 | } 256 | 257 | static int tag_do_ta_rx_wait_data(instance_data_t *inst) { 258 | int message = instance_peekevent(); 259 | 260 | if (message == DWT_SIG_RX_OKAY) { 261 | event_data_t* dw_event = instance_getevent(15); 262 | uint8 srcAddr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 263 | int fcode = 0; 264 | uint8 *messageData; 265 | 266 | memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_ss.sourceAddr[0]), ADDR_BYTE_SIZE_S); 267 | fcode = dw_event->msgu.rxmsg_ss.messageData[FCODE]; 268 | messageData = &dw_event->msgu.rxmsg_ss.messageData[0]; 269 | 270 | if (fcode == RTLS_DEMO_MSG_ANCH_RESP) { 271 | if (GATEWAY_ANCHOR_ADDR == (srcAddr[0] | ((uint32)(srcAddr[1] << 8)))) { 272 | inst->tagSleepCorrection_ms = (int16) (((uint16) messageData[RES_TAG_SLP1] << 8) + messageData[RES_TAG_SLP0]); 273 | inst->tagSleepRnd_ms = 0; 274 | } 275 | 276 | if (dw_event->typePend != DWT_SIG_RX_PENDING) { 277 | inst->testAppState = TA_TXFINAL_WAIT_SEND; 278 | } 279 | } else { 280 | tag_process_rx_timeout(inst); 281 | } 282 | 283 | return INST_NOT_DONE_YET; 284 | } 285 | 286 | if (message == RTLS_DEMO_MSG_RNG_INIT) { 287 | event_data_t* dw_event = instance_getevent(16); 288 | uint8 srcAddr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 289 | uint8* messageData = &dw_event->msgu.rxmsg_ls.messageData[0]; 290 | 291 | memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_ls.sourceAddr[0]), ADDR_BYTE_SIZE_S); 292 | 293 | if (GATEWAY_ANCHOR_ADDR == (srcAddr[0] | ((uint32)(srcAddr[1] << 8)))) { 294 | inst->tagSleepCorrection_ms = (int16) (((uint16) messageData[RES_TAG_SLP1] << 8) + messageData[RES_TAG_SLP0]); 295 | inst->tagSleepRnd_ms = 0; 296 | } 297 | 298 | inst->instanceAddress16 = (int16) (((uint16) messageData[RES_TAG_ADD1] << 8) + messageData[RES_TAG_ADD0]); 299 | dwt_setaddress16(inst->instanceAddress16); 300 | 301 | inst->nextState = TA_TXPOLL_WAIT_SEND; 302 | inst->testAppState = TA_TXE_WAIT; 303 | inst->instToSleep = TRUE; 304 | inst->tagSleepTime_ms = inst->tagPeriod_ms; 305 | 306 | return INST_NOT_DONE_YET; 307 | } 308 | 309 | if (message == DWT_SIG_RX_TIMEOUT) { 310 | event_data_t* dw_event = instance_getevent(17); 311 | 312 | if (dw_event->typePend == DWT_SIG_TX_PENDING) { 313 | inst->testAppState = TA_TX_WAIT_CONF; 314 | inst->previousState = TA_TXRESPONSE_SENT_TORX; 315 | } else if (dw_event->typePend == DWT_SIG_DW_IDLE) { 316 | tag_process_rx_timeout(inst); 317 | } 318 | return INST_NOT_DONE_YET; 319 | } 320 | 321 | return INST_DONE_WAIT_FOR_NEXT_EVENT; 322 | } 323 | 324 | static int tag_do_ta_wait_conf(instance_data_t *inst) { 325 | event_data_t* dw_event = instance_getevent(11); //get and clear this event 326 | 327 | if (dw_event->type != DWT_SIG_TX_DONE) { 328 | return INST_DONE_WAIT_FOR_NEXT_EVENT; 329 | } 330 | 331 | if (inst->previousState == TA_TXFINAL_WAIT_SEND) { 332 | inst->testAppState = TA_TXE_WAIT; 333 | inst->nextState = TA_TXPOLL_WAIT_SEND; 334 | return INST_NOT_DONE_YET; 335 | } else { 336 | inst->txu.txTimeStamp = dw_event->timeStamp; 337 | inst->tagPollTxTime32h = dw_event->timeStamp32h; 338 | 339 | if (inst->previousState == TA_TXPOLL_WAIT_SEND) { 340 | uint64 tagCalculatedFinalTxTime = (inst->txu.txTimeStamp + inst->pollTx2FinalTxDelay) & MASK_TXDTS; 341 | 342 | inst->delayedTRXTime32h = tagCalculatedFinalTxTime >> 8; 343 | tagCalculatedFinalTxTime += inst->txAntennaDelay; 344 | tagCalculatedFinalTxTime &= MASK_40BIT; 345 | 346 | memcpy(&(inst->msg_f.messageData[FTXT]), (uint8 *)&tagCalculatedFinalTxTime, 5); 347 | memcpy(&(inst->msg_f.messageData[PTXT]), (uint8 *)&inst->txu.tagPollTxTime, 5); 348 | } 349 | 350 | inst->testAppState = TA_RX_WAIT_DATA; 351 | 352 | return INST_DONE_WAIT_FOR_NEXT_EVENT; 353 | } 354 | } 355 | 356 | static int tag_app_run(instance_data_t *inst) { 357 | int instDone = INST_NOT_DONE_YET; 358 | 359 | switch (inst->testAppState) { 360 | case TA_INIT: { 361 | instDone = tag_do_ta_init(inst); 362 | break; 363 | } 364 | 365 | case TA_SLEEP_DONE: { 366 | instDone = tag_do_ta_sleep_done(inst); 367 | break; 368 | } 369 | 370 | case TA_TXE_WAIT: { 371 | instDone = tag_do_ta_txe_wait(inst); 372 | break; 373 | } 374 | 375 | case TA_TXPOLL_WAIT_SEND: { 376 | instDone = tag_do_ta_txpoll_wait_send(inst); 377 | break; 378 | } 379 | 380 | case TA_TXFINAL_WAIT_SEND: { 381 | instDone = tag_do_ta_txfinal_wait_send(inst); 382 | break; 383 | } 384 | 385 | case TA_TX_WAIT_CONF: { 386 | instDone = tag_do_ta_wait_conf(inst); 387 | break; 388 | } 389 | 390 | case TA_RX_WAIT_DATA: { 391 | instDone = tag_do_ta_rx_wait_data(inst); 392 | break; 393 | } 394 | 395 | default: { 396 | os_panic(); 397 | break; 398 | } 399 | } 400 | 401 | return instDone; 402 | } 403 | 404 | void tag_run(void) { 405 | instance_data_t* inst = instance_get_local_structure_ptr(0); 406 | int done = INST_NOT_DONE_YET; 407 | 408 | while(done == INST_NOT_DONE_YET) { 409 | done = tag_app_run(inst); 410 | } 411 | 412 | if (done == INST_DONE_WAIT_FOR_NEXT_EVENT_TO) { 413 | int32 nextPeriod = inst->tagSleepRnd_ms + inst->tagSleepTime_ms + inst->tagSleepCorrection_ms; 414 | 415 | inst->nextWakeUpTime_ms = (uint32)nextPeriod; 416 | inst->tagSleepCorrection_ms = 0; 417 | inst->instanceTimerEn = 1; 418 | } 419 | 420 | if (inst->instanceTimerEn == 1) { 421 | if (portGetTickCnt() > (inst->nextWakeUpTime_ms + inst->instanceWakeTime_ms)) { 422 | /* We missed an expected event */ 423 | event_data_t dw_event; 424 | 425 | inst->instanceTimerEn = 0; 426 | dw_event.rxLength = 0; 427 | dw_event.type = 0; 428 | instance_putevent(dw_event, DWT_SIG_RX_TIMEOUT); 429 | } 430 | } 431 | } 432 | -------------------------------------------------------------------------------- /decartls/instance.h: -------------------------------------------------------------------------------- 1 | #ifndef _INSTANCE_H_ 2 | #define _INSTANCE_H_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | /* You have stdint.h, why do this? */ 12 | typedef uint64_t uint64; 13 | typedef int64_t int64; 14 | /* You have stdbool.h, why do this? */ 15 | #define FALSE 0 16 | #define TRUE 1 17 | 18 | 19 | #define SPEED_OF_LIGHT (299702547.0) // in m/s in air 20 | #define MASK_40BIT (0x00FFFFFFFFFF) // DW1000 counter is 40 bits 21 | #define MASK_TXDTS (0x00FFFFFFFE00) // The TX timestamp will snap to 8 ns resolution - mask lower 9 bits. 22 | 23 | //! callback events 24 | #define DWT_SIG_RX_NOERR 0 25 | #define DWT_SIG_TX_DONE 1 // Frame has been sent 26 | #define DWT_SIG_RX_OKAY 2 // Frame Received with Good CRC 27 | #define DWT_SIG_RX_ERROR 3 // Frame Received but CRC is wrong 28 | #define DWT_SIG_RX_TIMEOUT 4 // Timeout on receive has elapsed 29 | #define DWT_SIG_TX_AA_DONE 6 // ACK frame has been sent (as a result of auto-ACK) 30 | #define DWT_SIG_RX_BLINK 7 // Received ISO EUI 64 blink message 31 | #define DWT_SIG_RX_PHR_ERROR 8 // Error found in PHY Header 32 | #define DWT_SIG_RX_SYNCLOSS 9 // Un-recoverable error in Reed Solomon Decoder 33 | #define DWT_SIG_RX_SFDTIMEOUT 10 // Saw preamble but got no SFD within configured time 34 | #define DWT_SIG_RX_PTOTIMEOUT 11 // Got preamble detection timeout (no preamble detected) 35 | 36 | #define DWT_SIG_TX_PENDING 12 // TX is pending 37 | #define DWT_SIG_TX_ERROR 13 // TX failed 38 | #define DWT_SIG_RX_PENDING 14 // RX has been re-enabled 39 | #define DWT_SIG_DW_IDLE 15 // DW radio is in IDLE (no TX or RX pending) 40 | 41 | #define SIG_RX_UNKNOWN 99 // Received an unknown frame 42 | 43 | //DecaRTLS frame function codes 44 | #define RTLS_DEMO_MSG_RNG_INIT (0x71) // Ranging initiation message 45 | #define RTLS_DEMO_MSG_TAG_POLL (0x81) // Tag poll message 46 | #define RTLS_DEMO_MSG_ANCH_RESP (0x70) // Anchor response to poll 47 | #define RTLS_DEMO_MSG_ANCH_POLL (0x7A) // Anchor to anchor poll message 48 | #define RTLS_DEMO_MSG_ANCH_RESP2 (0x7B) // Anchor response to poll from anchor 49 | #define RTLS_DEMO_MSG_ANCH_FINAL (0x7C) // Anchor final massage back to Anchor 50 | #define RTLS_DEMO_MSG_TAG_FINAL (0x82) // Tag final massage back to Anchor 51 | 52 | 53 | //lengths including the Decaranging Message Function Code byte 54 | //absolute length = 17 + 55 | #define RANGINGINIT_MSG_LEN 5 // FunctionCode(1), Sleep Correction Time (2), Tag Address (2) 56 | 57 | //absolute length = 11 + 58 | #define TAG_POLL_MSG_LEN 2 // FunctionCode(1), Range Num (1) 59 | #define ANCH_RESPONSE_MSG_LEN 8 // FunctionCode(1), Sleep Correction Time (2), Measured_TOF_Time(4), Range Num (1) (previous) 60 | #define TAG_FINAL_MSG_LEN 33 // FunctionCode(1), Range Num (1), Poll_TxTime(5), 61 | // Resp0_RxTime(5), Resp1_RxTime(5), Resp2_RxTime(5), Resp3_RxTime(5), Final_TxTime(5), Valid Response Mask (1) 62 | #define ANCH_POLL_MSG_LEN_S 2 // FunctionCode(1), Range Num (1), 63 | #define ANCH_POLL_MSG_LEN 4 // FunctionCode(1), Range Num (1), Next Anchor (2) 64 | #define ANCH_FINAL_MSG_LEN 33 // FunctionCode(1), Range Num (1), Poll_TxTime(5), 65 | // Resp0_RxTime(5), Resp1_RxTime(5), Resp2_RxTime(5), Resp3_RxTime(5), Final_TxTime(5), Valid Response Mask (1) 66 | #define MAX_MAC_MSG_DATA_LEN (TAG_FINAL_MSG_LEN) //max message len of the above 67 | 68 | #define STANDARD_FRAME_SIZE 127 69 | 70 | #define ADDR_BYTE_SIZE_L (8) 71 | #define ADDR_BYTE_SIZE_S (2) 72 | 73 | #define FRAME_CONTROL_BYTES 2 74 | #define FRAME_SEQ_NUM_BYTES 1 75 | #define FRAME_PANID 2 76 | #define FRAME_CRC 2 77 | #define FRAME_SOURCE_ADDRESS_S (ADDR_BYTE_SIZE_S) 78 | #define FRAME_DEST_ADDRESS_S (ADDR_BYTE_SIZE_S) 79 | #define FRAME_SOURCE_ADDRESS_L (ADDR_BYTE_SIZE_L) 80 | #define FRAME_DEST_ADDRESS_L (ADDR_BYTE_SIZE_L) 81 | #define FRAME_CTRLP (FRAME_CONTROL_BYTES + FRAME_SEQ_NUM_BYTES + FRAME_PANID) //5 82 | #define FRAME_CRTL_AND_ADDRESS_L (FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_L + FRAME_CTRLP) //21 bytes for 64-bit addresses) 83 | #define FRAME_CRTL_AND_ADDRESS_S (FRAME_DEST_ADDRESS_S + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) //9 bytes for 16-bit addresses) 84 | #define FRAME_CRTL_AND_ADDRESS_LS (FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) //15 bytes for one 16-bit address and one 64-bit address) 85 | #define MAX_USER_PAYLOAD_STRING_LL (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_L-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 21 - 16 - 2 = 88 86 | #define MAX_USER_PAYLOAD_STRING_SS (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_S-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 9 - 16 - 2 = 100 87 | #define MAX_USER_PAYLOAD_STRING_LS (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_LS-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 15 - 16 - 2 = 94 88 | 89 | //NOTE: the user payload assumes that there are only 88 "free" bytes to be used for the user message (it does not scale according to the addressing modes) 90 | #define MAX_USER_PAYLOAD_STRING MAX_USER_PAYLOAD_STRING_LL 91 | 92 | #define BLINK_FRAME_CONTROL_BYTES (1) 93 | #define BLINK_FRAME_SEQ_NUM_BYTES (1) 94 | #define BLINK_FRAME_CRC (FRAME_CRC) 95 | #define BLINK_FRAME_SOURCE_ADDRESS (ADDR_BYTE_SIZE_L) 96 | #define BLINK_FRAME_CTRLP (BLINK_FRAME_CONTROL_BYTES + BLINK_FRAME_SEQ_NUM_BYTES) //2 97 | #define BLINK_FRAME_CRTL_AND_ADDRESS (BLINK_FRAME_SOURCE_ADDRESS + BLINK_FRAME_CTRLP) //10 bytes 98 | #define BLINK_FRAME_LEN_BYTES (BLINK_FRAME_CRTL_AND_ADDRESS + BLINK_FRAME_CRC) 99 | 100 | 101 | #if (DISCOVERY == 0) 102 | #define MAX_TAG_LIST_SIZE (8) 103 | #else 104 | #define MAX_TAG_LIST_SIZE (100) 105 | #endif 106 | 107 | 108 | #define MAX_ANCHOR_LIST_SIZE (4) //this is limited to 4 in this application 109 | #define NUM_EXPECTED_RESPONSES (3) //e.g. MAX_ANCHOR_LIST_SIZE - 1 110 | 111 | #define GATEWAY_ANCHOR_ADDR (0x8000) 112 | #define A1_ANCHOR_ADDR (0x8001) 113 | #define A2_ANCHOR_ADDR (0x8002) 114 | #define A3_ANCHOR_ADDR (0x8003) 115 | 116 | #define WAIT4TAGFINAL 2 117 | #define WAIT4ANCFINAL 1 118 | 119 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 120 | // NOTE: the maximum RX timeout is ~ 65ms 121 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 122 | 123 | #define INST_DONE_WAIT_FOR_NEXT_EVENT 1 //this signifies that the current event has been processed and instance is ready for next one 124 | #define INST_DONE_WAIT_FOR_NEXT_EVENT_TO 2 //this signifies that the current event has been processed and that instance is waiting for next one with a timeout 125 | //which will trigger if no event coming in specified time 126 | #define INST_NOT_DONE_YET 0 //this signifies that the instance is still processing the current event 127 | 128 | //application data message byte offsets 129 | #define FCODE 0 // Function code is 1st byte of messageData 130 | #define PTXT 2 // Poll TX time 131 | #define RRXT0 7 // A0 Response RX time 132 | #define RRXT1 12 // A1 Response RX time 133 | #define RRXT2 17 // A2 Response RX time 134 | #define RRXT3 22 // A3 Response RX time 135 | #define FTXT 27 // Final TX time 136 | #define VRESP 32 // Mask of valid response times (e.g. if bit 1 = A0's response time is valid) 137 | #define RES_TAG_SLP0 1 // Response tag sleep correction LSB 138 | #define RES_TAG_SLP1 2 // Response tag sleep correction MSB 139 | #define TOFR 3 // ToF (n-1) 4 bytes 140 | #define TOFRN 7 // range number 1 byte 141 | #define POLL_RNUM 1 // Poll message range number 142 | #define POLL_NANC 2 // Address of next anchor to send a poll message (e.g. A1) 143 | #define RES_TAG_ADD0 3 // Tag's short address (slot num) LSB 144 | #define RES_TAG_ADD1 4 // Tag's short address (slot num) MSB 145 | 146 | #define DW_RX_ON_DELAY (16) //us - the DW RX has 16 us RX on delay before it will receive any data 147 | 148 | //this it the delay used for configuring the receiver on delay (wait for response delay) 149 | //NOTE: this RX_RESPONSE_TURNAROUND is dependent on the microprocessor and code optimisations 150 | /* TODO: optimize this... value would be different when we have logging. Unit should be in usec. Originally 300. With logging it gets huge... */ 151 | #define RX_RESPONSE_TURNAROUND (300) //this takes into account any turnaround/processing time (reporting received poll and sending the response) 152 | 153 | #define PTO_PACS (3) //tag will use PTO to reduce power consumption (if no response coming stop RX) // TODO: should we get rid of this? 154 | 155 | //Tag will range to 3 or 4 anchors 156 | //Each ranging exchange will consist of minimum of 3 messages (Poll, Response, Final) 157 | //and a maximum of 6 messages (Poll, Response x 4, Final) 158 | //Thus the ranging exchange will take either 28 ms for 110 kbps and 5 ms for 6.81 Mbps. 159 | //NOTE: the above times are for 110k rate with 64 symb non-standard SFD and 1024 preamble length 160 | 161 | #define TOF_REPORT_NUL 0 162 | #define TOF_REPORT_T2A 1 163 | #define TOF_REPORT_A2A 2 164 | 165 | #define INVALID_TOF (0xABCDFFFF) 166 | 167 | typedef enum inst_states { 168 | TA_INIT, //0 169 | 170 | TA_TXE_WAIT, //1 - state in which the instance will enter sleep (if ranging finished) or proceed to transmit a message 171 | TA_TXBLINK_WAIT_SEND, //2 - configuration and sending of Blink message 172 | TA_TXPOLL_WAIT_SEND, //2 - configuration and sending of Poll message 173 | TA_TXFINAL_WAIT_SEND, //3 - configuration and sending of Final message 174 | TA_TXRESPONSE_WAIT_SEND, //4 - a place holder - response is sent from call back 175 | TA_TX_WAIT_CONF, //5 - confirmation of TX done message 176 | 177 | TA_RXE_WAIT, //6 178 | TA_RX_WAIT_DATA, //7 179 | 180 | TA_SLEEP_DONE, //8 181 | TA_TXRESPONSE_SENT_POLLRX, //9 182 | TA_TXRESPONSE_SENT_RESPRX, //10 183 | TA_TXRESPONSE_SENT_TORX, //11 184 | TA_TXRESPONSE_SENT_APOLLRX, //12 185 | TA_TXRESPONSE_SENT_ARESPRX //13 186 | 187 | } INST_STATES; 188 | 189 | 190 | typedef struct { 191 | uint8 frameCtrl[2]; 192 | uint8 seqNum; 193 | uint8 panID[2]; 194 | uint8 destAddr[ADDR_BYTE_SIZE_L]; 195 | uint8 sourceAddr[ADDR_BYTE_SIZE_S]; 196 | uint8 messageData[MAX_USER_PAYLOAD_STRING_LS]; 197 | uint8 fcs[2]; 198 | } srd_msg_dlss; 199 | 200 | typedef struct { 201 | uint8 frameCtrl[2]; 202 | uint8 seqNum; 203 | uint8 panID[2]; 204 | uint8 destAddr[ADDR_BYTE_SIZE_S]; 205 | uint8 sourceAddr[ADDR_BYTE_SIZE_S]; 206 | uint8 messageData[MAX_USER_PAYLOAD_STRING_SS]; 207 | uint8 fcs[2]; 208 | } srd_msg_dsss; 209 | 210 | typedef struct { 211 | uint8 channelNumber; 212 | uint8 preambleCode; 213 | uint8 pulseRepFreq; 214 | uint8 dataRate; 215 | uint8 preambleLen; 216 | uint8 pacSize; 217 | uint8 nsSFD; 218 | uint16 sfdTO; 219 | } instanceConfig_t ; 220 | 221 | typedef struct { 222 | uint16 slotDuration_ms; 223 | uint16 numSlots; 224 | uint16 sfPeriod_ms; 225 | uint16 tagPeriod_ms; 226 | uint16 pollTxToFinalTxDly_us; 227 | } sfConfig_t; 228 | 229 | //size of the event queue, in this application there should be at most 2 unprocessed events, 230 | //i.e. if there is a transmission with wait for response then the TX callback followed by RX callback could be executed 231 | //in turn and the event queued up before the instance processed the TX event. 232 | #define MAX_EVENT_NUMBER (4) 233 | 234 | typedef struct { 235 | uint8 type; // if 0 there is no event in the queue 236 | uint8 typePend; // DW is not in IDLE (TX/RX pending) 237 | uint16 rxLength; 238 | 239 | uint64 timeStamp; // 40 bit DW1000 time 240 | 241 | uint32 timeStamp32l; // low 32 bits of the 40 bit DW1000 time 242 | uint32 timeStamp32h; // high 32 bits of the 40 bit DW1000 time 243 | 244 | union { 245 | uint8 frame[STANDARD_FRAME_SIZE]; 246 | srd_msg_dlss rxmsg_ls; 247 | srd_msg_dsss rxmsg_ss; //16 bit addresses 248 | } msgu; 249 | } event_data_t ; 250 | 251 | // TX power and PG delay configuration structure 252 | typedef struct { 253 | uint8 pgDelay; 254 | 255 | //TX POWER 256 | //31:24 BOOST_0.125ms_PWR 257 | //23:16 BOOST_0.25ms_PWR-TX_SHR_PWR 258 | //15:8 BOOST_0.5ms_PWR-TX_PHR_PWR 259 | //7:0 DEFAULT_PWR-TX_DATA_PWR 260 | uint32 txPwr[2]; 261 | } tx_struct; 262 | 263 | typedef struct { 264 | INST_STATES testAppState; 265 | INST_STATES nextState; 266 | INST_STATES previousState; 267 | 268 | //configuration structures 269 | dwt_config_t configData; /* TODO: should be const */ 270 | dwt_txconfig_t configTX; /* TODO: should be const */ 271 | uint16 txAntennaDelay; 272 | uint32 txPower; 273 | uint8 txPowerChanged; 274 | 275 | uint16 instanceAddress16; 276 | 277 | int32 tagPeriod_ms; /* TODO: should be const */ 278 | int32 tagSleepTime_ms; /* TODO: should be const */ 279 | int32 tagSleepRnd_ms; 280 | 281 | uint64 pollTx2FinalTxDelay; 282 | uint32 fixedReplyDelayAnc32h; 283 | uint32 preambleDuration32h; 284 | uint32 tagRespRxDelay_sy; 285 | 286 | int32 fwto4RespFrame_sy; 287 | uint32 delayedTRXTime32h; 288 | 289 | srd_msg_dsss msg_f; 290 | 291 | //Tag function address/message configuration 292 | uint8 eui64[8]; 293 | uint16 psduLength; 294 | uint8 frameSN; 295 | uint16 panID; /* TODO: should be const */ 296 | 297 | //64 bit timestamps 298 | union { 299 | uint64 txTimeStamp; 300 | uint64 tagPollTxTime; 301 | } txu; 302 | uint32 tagPollTxTime32h; 303 | 304 | //application control parameters 305 | uint8 wait4ack; 306 | 307 | uint8 instToSleep; 308 | uint8 instanceTimerEn; 309 | uint32 instanceWakeTime_ms; 310 | uint32 nextWakeUpTime_ms; 311 | 312 | /* NOTE: this field needs expansion if we change MAX_ANCHOR_LIST_SIZE */ 313 | uint8 rxResponseMask; 314 | uint8 rangeNum; 315 | 316 | int8 remainingRespToRx; 317 | 318 | int32 tagSleepCorrection_ms; 319 | 320 | //event queue - used to store DW1000 events as they are processed by the dw_isr/callback functions 321 | event_data_t dwevent[MAX_EVENT_NUMBER]; //this holds any TX/RX events and associated message data 322 | uint8 dweventIdxOut; 323 | uint8 dweventIdxIn; 324 | 325 | event_data_t dw_event_g; /* Was in instance_common.c used by instance_getevent(). */ 326 | } instance_data_t; 327 | 328 | 329 | #define portGetTickCnt() tick_get_uptime() 330 | extern void port_wakeup_dw1000_fast(void); 331 | 332 | 333 | int instance_init(void); 334 | void instance_config(const instanceConfig_t *config, const sfConfig_t *sfconfig); 335 | void tag_run(void); 336 | 337 | // configure the MAC address 338 | void instance_set_16bit_address(uint16 address) ; 339 | void instance_config_frameheader_16bit(instance_data_t *inst); 340 | 341 | // TX/RX callback functions called from DW1000 ISR 342 | void rx_ok_cb_tag(const dwt_cb_data_t *cb_data); 343 | void rx_err_cb_tag(const dwt_cb_data_t *cb_data); 344 | void tx_conf_cb(const dwt_cb_data_t *cb_data); 345 | 346 | #define instance_readdeviceid() dwt_readdevid() 347 | 348 | int instance_send_delayed_frame(instance_data_t *inst, int delayedTx); 349 | 350 | void instance_seteventtime(event_data_t *dw_event, uint8* timeStamp); 351 | int instance_peekevent(void); 352 | void instance_saveevent(event_data_t newevent, uint8 etype); 353 | event_data_t instance_getsavedevent(void); 354 | void instance_putevent(event_data_t newevent, uint8 etype); 355 | event_data_t* instance_getevent(int x); 356 | void instance_clearevents(void); 357 | 358 | // configure the TX power 359 | void instance_config_txpower(uint32 txpower); 360 | void instance_set_txpower(void); 361 | 362 | instance_data_t* instance_get_local_structure_ptr(unsigned int x); 363 | 364 | #endif 365 | -------------------------------------------------------------------------------- /decartls/deca_range_tables.c: -------------------------------------------------------------------------------- 1 | /*! ---------------------------------------------------------------------------- 2 | * @file deca_range_tables.c 3 | * @brief DW1000 range correction tables 4 | * 5 | * @attention 6 | * 7 | * Copyright 2015 (c) DecaWave Ltd, Dublin, Ireland. 8 | * 9 | * All rights reserved. 10 | * 11 | */ 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #define NUM_16M_OFFSET (37) 19 | #define NUM_16M_OFFSETWB (68) 20 | #define NUM_64M_OFFSET (26) 21 | #define NUM_64M_OFFSETWB (59) 22 | 23 | const uint8 chan_idxnb[NUM_CH_SUPPORTED] = {0, 0, 1, 2, 0, 3, 0, 0}; //only channels 1,2,3 and 5 are in the narrow band tables 24 | const uint8 chan_idxwb[NUM_CH_SUPPORTED] = {0, 0, 0, 0, 0, 0, 0, 1}; //only channels 4 and 7 are in in the wide band tables 25 | 26 | //--------------------------------------------------------------------------------------------------------------------------- 27 | // Range Bias Correction TABLES of range values in integer units of 25 CM, for 8-bit unsigned storage, MUST END IN 255 !!!!!! 28 | //--------------------------------------------------------------------------------------------------------------------------- 29 | 30 | // offsets to nearest centimeter for index 0, all rest are +1 cm per value 31 | 32 | #define CM_OFFSET_16M_NB (-23) // for normal band channels at 16 MHz PRF 33 | #define CM_OFFSET_16M_WB (-28) // for wider band channels at 16 MHz PRF 34 | #define CM_OFFSET_64M_NB (-17) // for normal band channels at 64 MHz PRF 35 | #define CM_OFFSET_64M_WB (-30) // for wider band channels at 64 MHz PRF 36 | 37 | 38 | //--------------------------------------------------------------------------------------------------------------------------- 39 | // range25cm16PRFnb: Range Bias Correction table for narrow band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!! 40 | //--------------------------------------------------------------------------------------------------------------------------- 41 | 42 | const uint8 range25cm16PRFnb[4][NUM_16M_OFFSET] = 43 | { 44 | // ch 1 - range25cm16PRFnb 45 | { 46 | 1, 47 | 3, 48 | 4, 49 | 5, 50 | 7, 51 | 9, 52 | 11, 53 | 12, 54 | 13, 55 | 15, 56 | 18, 57 | 20, 58 | 23, 59 | 25, 60 | 28, 61 | 30, 62 | 33, 63 | 36, 64 | 40, 65 | 43, 66 | 47, 67 | 50, 68 | 54, 69 | 58, 70 | 63, 71 | 66, 72 | 71, 73 | 76, 74 | 82, 75 | 89, 76 | 98, 77 | 109, 78 | 127, 79 | 155, 80 | 222, 81 | 255, 82 | 255 83 | }, 84 | 85 | // ch 2 - range25cm16PRFnb 86 | { 87 | 1, 88 | 2, 89 | 4, 90 | 5, 91 | 6, 92 | 8, 93 | 9, 94 | 10, 95 | 12, 96 | 13, 97 | 15, 98 | 18, 99 | 20, 100 | 22, 101 | 24, 102 | 27, 103 | 29, 104 | 32, 105 | 35, 106 | 38, 107 | 41, 108 | 44, 109 | 47, 110 | 51, 111 | 55, 112 | 58, 113 | 62, 114 | 66, 115 | 71, 116 | 78, 117 | 85, 118 | 96, 119 | 111, 120 | 135, 121 | 194, 122 | 240, 123 | 255 124 | }, 125 | 126 | // ch 3 - range25cm16PRFnb 127 | { 128 | 1, 129 | 2, 130 | 3, 131 | 4, 132 | 5, 133 | 7, 134 | 8, 135 | 9, 136 | 10, 137 | 12, 138 | 14, 139 | 16, 140 | 18, 141 | 20, 142 | 22, 143 | 24, 144 | 26, 145 | 28, 146 | 31, 147 | 33, 148 | 36, 149 | 39, 150 | 42, 151 | 45, 152 | 49, 153 | 52, 154 | 55, 155 | 59, 156 | 63, 157 | 69, 158 | 76, 159 | 85, 160 | 98, 161 | 120, 162 | 173, 163 | 213, 164 | 255 165 | }, 166 | 167 | // ch 5 - range25cm16PRFnb 168 | { 169 | 1, 170 | 1, 171 | 2, 172 | 3, 173 | 4, 174 | 5, 175 | 6, 176 | 6, 177 | 7, 178 | 8, 179 | 9, 180 | 11, 181 | 12, 182 | 14, 183 | 15, 184 | 16, 185 | 18, 186 | 20, 187 | 21, 188 | 23, 189 | 25, 190 | 27, 191 | 29, 192 | 31, 193 | 34, 194 | 36, 195 | 38, 196 | 41, 197 | 44, 198 | 48, 199 | 53, 200 | 59, 201 | 68, 202 | 83, 203 | 120, 204 | 148, 205 | 255 206 | } 207 | }; // end range25cm16PRFnb 208 | 209 | 210 | //--------------------------------------------------------------------------------------------------------------------------- 211 | // range25cm16PRFwb: Range Bias Correction table for wide band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!! 212 | //--------------------------------------------------------------------------------------------------------------------------- 213 | 214 | const uint8 range25cm16PRFwb[2][NUM_16M_OFFSETWB] = 215 | { 216 | // ch 4 - range25cm16PRFwb 217 | { 218 | 7, 219 | 7, 220 | 8, 221 | 9, 222 | 9, 223 | 10, 224 | 11, 225 | 11, 226 | 12, 227 | 13, 228 | 14, 229 | 15, 230 | 16, 231 | 17, 232 | 18, 233 | 19, 234 | 20, 235 | 21, 236 | 22, 237 | 23, 238 | 24, 239 | 26, 240 | 27, 241 | 28, 242 | 30, 243 | 31, 244 | 32, 245 | 34, 246 | 36, 247 | 38, 248 | 40, 249 | 42, 250 | 44, 251 | 46, 252 | 48, 253 | 50, 254 | 52, 255 | 55, 256 | 57, 257 | 59, 258 | 61, 259 | 63, 260 | 66, 261 | 68, 262 | 71, 263 | 74, 264 | 78, 265 | 81, 266 | 85, 267 | 89, 268 | 94, 269 | 99, 270 | 104, 271 | 110, 272 | 116, 273 | 123, 274 | 130, 275 | 139, 276 | 150, 277 | 164, 278 | 182, 279 | 207, 280 | 238, 281 | 255, 282 | 255, 283 | 255, 284 | 255, 285 | 255 286 | }, 287 | 288 | // ch 7 - range25cm16PRFwb 289 | { 290 | 4, 291 | 5, 292 | 5, 293 | 5, 294 | 6, 295 | 6, 296 | 7, 297 | 7, 298 | 7, 299 | 8, 300 | 9, 301 | 9, 302 | 10, 303 | 10, 304 | 11, 305 | 11, 306 | 12, 307 | 13, 308 | 13, 309 | 14, 310 | 15, 311 | 16, 312 | 17, 313 | 17, 314 | 18, 315 | 19, 316 | 20, 317 | 21, 318 | 22, 319 | 23, 320 | 25, 321 | 26, 322 | 27, 323 | 29, 324 | 30, 325 | 31, 326 | 32, 327 | 34, 328 | 35, 329 | 36, 330 | 38, 331 | 39, 332 | 40, 333 | 42, 334 | 44, 335 | 46, 336 | 48, 337 | 50, 338 | 52, 339 | 55, 340 | 58, 341 | 61, 342 | 64, 343 | 68, 344 | 72, 345 | 75, 346 | 80, 347 | 85, 348 | 92, 349 | 101, 350 | 112, 351 | 127, 352 | 147, 353 | 168, 354 | 182, 355 | 194, 356 | 205, 357 | 255 358 | } 359 | }; // end range25cm16PRFwb 360 | 361 | //--------------------------------------------------------------------------------------------------------------------------- 362 | // range25cm64PRFnb: Range Bias Correction table for narrow band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!! 363 | //--------------------------------------------------------------------------------------------------------------------------- 364 | 365 | const uint8 range25cm64PRFnb[4][NUM_64M_OFFSET] = 366 | { 367 | // ch 1 - range25cm64PRFnb 368 | { 369 | 1, 370 | 2, 371 | 2, 372 | 3, 373 | 4, 374 | 5, 375 | 7, 376 | 10, 377 | 13, 378 | 16, 379 | 19, 380 | 22, 381 | 24, 382 | 27, 383 | 30, 384 | 32, 385 | 35, 386 | 38, 387 | 43, 388 | 48, 389 | 56, 390 | 78, 391 | 101, 392 | 120, 393 | 157, 394 | 255 395 | }, 396 | 397 | // ch 2 - range25cm64PRFnb 398 | { 399 | 1, 400 | 2, 401 | 2, 402 | 3, 403 | 4, 404 | 4, 405 | 6, 406 | 9, 407 | 12, 408 | 14, 409 | 17, 410 | 19, 411 | 21, 412 | 24, 413 | 26, 414 | 28, 415 | 31, 416 | 33, 417 | 37, 418 | 42, 419 | 49, 420 | 68, 421 | 89, 422 | 105, 423 | 138, 424 | 255 425 | }, 426 | 427 | // ch 3 - range25cm64PRFnb 428 | { 429 | 1, 430 | 1, 431 | 2, 432 | 3, 433 | 3, 434 | 4, 435 | 5, 436 | 8, 437 | 10, 438 | 13, 439 | 15, 440 | 17, 441 | 19, 442 | 21, 443 | 23, 444 | 25, 445 | 27, 446 | 30, 447 | 33, 448 | 37, 449 | 44, 450 | 60, 451 | 79, 452 | 93, 453 | 122, 454 | 255 455 | }, 456 | 457 | // ch 5 - range25cm64PRFnb 458 | { 459 | 1, 460 | 1, 461 | 1, 462 | 2, 463 | 2, 464 | 3, 465 | 4, 466 | 6, 467 | 7, 468 | 9, 469 | 10, 470 | 12, 471 | 13, 472 | 15, 473 | 16, 474 | 17, 475 | 19, 476 | 21, 477 | 23, 478 | 26, 479 | 30, 480 | 42, 481 | 55, 482 | 65, 483 | 85, 484 | 255 485 | } 486 | }; // end range25cm64PRFnb 487 | 488 | //--------------------------------------------------------------------------------------------------------------------------- 489 | // range25cm64PRFwb: Range Bias Correction table for wide band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!! 490 | //--------------------------------------------------------------------------------------------------------------------------- 491 | 492 | const uint8 range25cm64PRFwb[2][NUM_64M_OFFSETWB] = 493 | { 494 | // ch 4 - range25cm64PRFwb 495 | { 496 | 7, 497 | 8, 498 | 8, 499 | 9, 500 | 9, 501 | 10, 502 | 11, 503 | 12, 504 | 13, 505 | 13, 506 | 14, 507 | 15, 508 | 16, 509 | 16, 510 | 17, 511 | 18, 512 | 19, 513 | 19, 514 | 20, 515 | 21, 516 | 22, 517 | 24, 518 | 25, 519 | 27, 520 | 28, 521 | 29, 522 | 30, 523 | 32, 524 | 33, 525 | 34, 526 | 35, 527 | 37, 528 | 39, 529 | 41, 530 | 43, 531 | 45, 532 | 48, 533 | 50, 534 | 53, 535 | 56, 536 | 60, 537 | 64, 538 | 68, 539 | 74, 540 | 81, 541 | 89, 542 | 98, 543 | 109, 544 | 122, 545 | 136, 546 | 146, 547 | 154, 548 | 162, 549 | 178, 550 | 220, 551 | 249, 552 | 255, 553 | 255, 554 | 255 555 | }, 556 | 557 | // ch 7 - range25cm64PRFwb 558 | { 559 | 4, 560 | 5, 561 | 5, 562 | 5, 563 | 6, 564 | 6, 565 | 7, 566 | 7, 567 | 8, 568 | 8, 569 | 9, 570 | 9, 571 | 10, 572 | 10, 573 | 10, 574 | 11, 575 | 11, 576 | 12, 577 | 13, 578 | 13, 579 | 14, 580 | 15, 581 | 16, 582 | 16, 583 | 17, 584 | 18, 585 | 19, 586 | 19, 587 | 20, 588 | 21, 589 | 22, 590 | 23, 591 | 24, 592 | 25, 593 | 26, 594 | 28, 595 | 29, 596 | 31, 597 | 33, 598 | 35, 599 | 37, 600 | 39, 601 | 42, 602 | 46, 603 | 50, 604 | 54, 605 | 60, 606 | 67, 607 | 75, 608 | 83, 609 | 90, 610 | 95, 611 | 100, 612 | 110, 613 | 135, 614 | 153, 615 | 172, 616 | 192, 617 | 255 618 | } 619 | }; // end range25cm64PRFwb 620 | 621 | 622 | /*! ------------------------------------------------------------------------------------------------------------------ 623 | * Function: dwt_getrangebias() 624 | * 625 | * Description: This function is used to return the range bias correction need for TWR with DW1000 units. 626 | * 627 | * input parameters: 628 | * @param chan - specifies the operating channel (e.g. 1, 2, 3, 4, 5, 6 or 7) 629 | * @param range - the calculated distance before correction 630 | * @param prf - this is the PRF e.g. DWT_PRF_16M or DWT_PRF_64M 631 | * 632 | * output parameters 633 | * 634 | * returns correction needed in meters 635 | */ 636 | float dwt_getrangebias(uint8 chan, float range, uint8 prf) 637 | { 638 | //first get the lookup index that corresponds to given range for a particular channel at 16M PRF 639 | int i = 0 ; 640 | int chanIdx ; 641 | int cmoffseti ; // integer number of CM offset 642 | 643 | float mOffset ; // final offset result in metres 644 | 645 | // NB: note we may get some small negitive values e.g. up to -50 cm. 646 | 647 | int rangeint25cm = (int) (range * 4.00) ; // convert range to integer number of 25cm values. 648 | 649 | if (rangeint25cm > 255) rangeint25cm = 255 ; // make sure it matches largest value in table (all tables end in 255 !!!!) 650 | 651 | if (prf == DWT_PRF_16M) 652 | { 653 | switch(chan) 654 | { 655 | case 4: 656 | case 7: 657 | { 658 | chanIdx = chan_idxwb[chan]; 659 | while (rangeint25cm > range25cm16PRFwb[chanIdx][i]) i++ ; // find index in table corresponding to range 660 | cmoffseti = i + CM_OFFSET_16M_WB ; // nearest centimeter correction 661 | } 662 | break; 663 | default: 664 | { 665 | chanIdx = chan_idxnb[chan]; 666 | while (rangeint25cm > range25cm16PRFnb[chanIdx][i]) i++ ; // find index in table corresponding to range 667 | cmoffseti = i + CM_OFFSET_16M_NB ; // nearest centimeter correction 668 | } 669 | }//end of switch 670 | } 671 | else // 64M PRF 672 | { 673 | switch(chan) 674 | { 675 | case 4: 676 | case 7: 677 | { 678 | chanIdx = chan_idxwb[chan]; 679 | while (rangeint25cm > range25cm64PRFwb[chanIdx][i]) i++ ; // find index in table corresponding to range 680 | cmoffseti = i + CM_OFFSET_64M_WB ; // nearest centimeter correction 681 | } 682 | break; 683 | default: 684 | { 685 | chanIdx = chan_idxnb[chan]; 686 | while (rangeint25cm > range25cm64PRFnb[chanIdx][i]) i++ ; // find index in table corresponding to range 687 | cmoffseti = i + CM_OFFSET_64M_NB ; // nearest centimeter correction 688 | } 689 | }//end of switch 690 | } // end else 691 | 692 | 693 | mOffset = (float) cmoffseti ; // offset result in centimmetres 694 | 695 | mOffset *= 0.01 ; // convert to metres 696 | 697 | return (mOffset) ; 698 | } 699 | -------------------------------------------------------------------------------- /pcb/untitled.brd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | RX 96 | TX 97 | PG 98 | RST 99 | AC 100 | DCK 101 | DIO 102 | + 103 | - 104 | 3V3 105 | TinyUWB 106 | 107 | 108 | 109 | Resistors, capacitors, inductors, crystals, etc. 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | >NAME 121 | >VALUE 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | >NAME 136 | >VALUE 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | <b>Resistors, Capacitors, Inductors</b><p> 146 | Based on the previous libraries: 147 | <ul> 148 | <li>r.lbr 149 | <li>cap.lbr 150 | <li>cap-fe.lbr 151 | <li>captant.lbr 152 | <li>polcap.lbr 153 | <li>ipc-smd.lbr 154 | </ul> 155 | All SMD packages are defined according to the IPC specifications and CECC<p> 156 | <author>Created by librarian@cadsoft.de</author><p> 157 | <p> 158 | for Electrolyt Capacitors see also :<p> 159 | www.bccomponents.com <p> 160 | www.panasonic.com<p> 161 | www.kemet.com<p> 162 | http://www.secc.co.jp/pdf/os_e/2004/e_os_all.pdf <b>(SANYO)</b> 163 | <p> 164 | for trimmer refence see : <u>www.electrospec-inc.com/cross_references/trimpotcrossref.asp</u><p> 165 | 166 | <table border=0 cellspacing=0 cellpadding=0 width="100%" cellpaddding=0> 167 | <tr valign="top"> 168 | 169 | <! <td width="10">&nbsp;</td> 170 | <td width="90%"> 171 | 172 | <b><font color="#0000FF" size="4">TRIM-POT CROSS REFERENCE</font></b> 173 | <P> 174 | <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2> 175 | <TR> 176 | <TD COLSPAN=8> 177 | <FONT SIZE=3 FACE=ARIAL><B>RECTANGULAR MULTI-TURN</B></FONT> 178 | </TD> 179 | </TR> 180 | <TR> 181 | <TD ALIGN=CENTER> 182 | <B> 183 | <FONT SIZE=3 FACE=ARIAL color="#FF0000">BOURNS</FONT> 184 | </B> 185 | </TD> 186 | <TD ALIGN=CENTER> 187 | <B> 188 | <FONT SIZE=3 FACE=ARIAL color="#FF0000">BI&nbsp;TECH</FONT> 189 | </B> 190 | </TD> 191 | <TD ALIGN=CENTER> 192 | <B> 193 | <FONT SIZE=3 FACE=ARIAL color="#FF0000">DALE-VISHAY</FONT> 194 | </B> 195 | </TD> 196 | <TD ALIGN=CENTER> 197 | <B> 198 | <FONT SIZE=3 FACE=ARIAL color="#FF0000">PHILIPS/MEPCO</FONT> 199 | </B> 200 | </TD> 201 | <TD ALIGN=CENTER> 202 | <B> 203 | <FONT SIZE=3 FACE=ARIAL color="#FF0000">MURATA</FONT> 204 | </B> 205 | </TD> 206 | <TD ALIGN=CENTER> 207 | <B> 208 | <FONT SIZE=3 FACE=ARIAL color="#FF0000">PANASONIC</FONT> 209 | </B> 210 | </TD> 211 | <TD ALIGN=CENTER> 212 | <B> 213 | <FONT SIZE=3 FACE=ARIAL color="#FF0000">SPECTROL</FONT> 214 | </B> 215 | </TD> 216 | <TD ALIGN=CENTER> 217 | <B> 218 | <FONT SIZE=3 FACE=ARIAL color="#FF0000">MILSPEC</FONT> 219 | </B> 220 | </TD><TD>&nbsp;</TD> 221 | </TR> 222 | <TR> 223 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3 > 224 | 3005P<BR> 225 | 3006P<BR> 226 | 3006W<BR> 227 | 3006Y<BR> 228 | 3009P<BR> 229 | 3009W<BR> 230 | 3009Y<BR> 231 | 3057J<BR> 232 | 3057L<BR> 233 | 3057P<BR> 234 | 3057Y<BR> 235 | 3059J<BR> 236 | 3059L<BR> 237 | 3059P<BR> 238 | 3059Y<BR></FONT> 239 | </TD> 240 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 241 | -<BR> 242 | 89P<BR> 243 | 89W<BR> 244 | 89X<BR> 245 | 89PH<BR> 246 | 76P<BR> 247 | 89XH<BR> 248 | 78SLT<BR> 249 | 78L&nbsp;ALT<BR> 250 | 56P&nbsp;ALT<BR> 251 | 78P&nbsp;ALT<BR> 252 | T8S<BR> 253 | 78L<BR> 254 | 56P<BR> 255 | 78P<BR></FONT> 256 | </TD> 257 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 258 | -<BR> 259 | T18/784<BR> 260 | 783<BR> 261 | 781<BR> 262 | -<BR> 263 | -<BR> 264 | -<BR> 265 | 2199<BR> 266 | 1697/1897<BR> 267 | 1680/1880<BR> 268 | 2187<BR> 269 | -<BR> 270 | -<BR> 271 | -<BR> 272 | -<BR></FONT> 273 | </TD> 274 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 275 | -<BR> 276 | 8035EKP/CT20/RJ-20P<BR> 277 | -<BR> 278 | RJ-20X<BR> 279 | -<BR> 280 | -<BR> 281 | -<BR> 282 | 1211L<BR> 283 | 8012EKQ&nbsp;ALT<BR> 284 | 8012EKR&nbsp;ALT<BR> 285 | 1211P<BR> 286 | 8012EKJ<BR> 287 | 8012EKL<BR> 288 | 8012EKQ<BR> 289 | 8012EKR<BR></FONT> 290 | </TD> 291 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 292 | -<BR> 293 | 2101P<BR> 294 | 2101W<BR> 295 | 2101Y<BR> 296 | -<BR> 297 | -<BR> 298 | -<BR> 299 | -<BR> 300 | -<BR> 301 | -<BR> 302 | -<BR> 303 | -<BR> 304 | 2102L<BR> 305 | 2102S<BR> 306 | 2102Y<BR></FONT> 307 | </TD> 308 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 309 | -<BR> 310 | EVMCOG<BR> 311 | -<BR> 312 | -<BR> 313 | -<BR> 314 | -<BR> 315 | -<BR> 316 | -<BR> 317 | -<BR> 318 | -<BR> 319 | -<BR> 320 | -<BR> 321 | -<BR> 322 | -<BR> 323 | -<BR></FONT> 324 | </TD> 325 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 326 | -<BR> 327 | 43P<BR> 328 | 43W<BR> 329 | 43Y<BR> 330 | -<BR> 331 | -<BR> 332 | -<BR> 333 | -<BR> 334 | 40L<BR> 335 | 40P<BR> 336 | 40Y<BR> 337 | 70Y-T602<BR> 338 | 70L<BR> 339 | 70P<BR> 340 | 70Y<BR></FONT> 341 | </TD> 342 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 343 | -<BR> 344 | -<BR> 345 | -<BR> 346 | -<BR> 347 | -<BR> 348 | -<BR> 349 | -<BR> 350 | -<BR> 351 | RT/RTR12<BR> 352 | RT/RTR12<BR> 353 | RT/RTR12<BR> 354 | -<BR> 355 | RJ/RJR12<BR> 356 | RJ/RJR12<BR> 357 | RJ/RJR12<BR></FONT> 358 | </TD> 359 | </TR> 360 | <TR> 361 | <TD COLSPAN=8>&nbsp; 362 | </TD> 363 | </TR> 364 | <TR> 365 | <TD COLSPAN=8> 366 | <FONT SIZE=4 FACE=ARIAL><B>SQUARE MULTI-TURN</B></FONT> 367 | </TD> 368 | </TR> 369 | <TR> 370 | <TD ALIGN=CENTER> 371 | <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT> 372 | </TD> 373 | <TD ALIGN=CENTER> 374 | <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> 375 | </TD> 376 | <TD ALIGN=CENTER> 377 | <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> 378 | </TD> 379 | <TD ALIGN=CENTER> 380 | <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> 381 | </TD> 382 | <TD ALIGN=CENTER> 383 | <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT> 384 | </TD> 385 | <TD ALIGN=CENTER> 386 | <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> 387 | </TD> 388 | <TD ALIGN=CENTER> 389 | <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT> 390 | </TD> 391 | <TD ALIGN=CENTER> 392 | <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT> 393 | </TD> 394 | </TR> 395 | <TR> 396 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 397 | 3250L<BR> 398 | 3250P<BR> 399 | 3250W<BR> 400 | 3250X<BR> 401 | 3252P<BR> 402 | 3252W<BR> 403 | 3252X<BR> 404 | 3260P<BR> 405 | 3260W<BR> 406 | 3260X<BR> 407 | 3262P<BR> 408 | 3262W<BR> 409 | 3262X<BR> 410 | 3266P<BR> 411 | 3266W<BR> 412 | 3266X<BR> 413 | 3290H<BR> 414 | 3290P<BR> 415 | 3290W<BR> 416 | 3292P<BR> 417 | 3292W<BR> 418 | 3292X<BR> 419 | 3296P<BR> 420 | 3296W<BR> 421 | 3296X<BR> 422 | 3296Y<BR> 423 | 3296Z<BR> 424 | 3299P<BR> 425 | 3299W<BR> 426 | 3299X<BR> 427 | 3299Y<BR> 428 | 3299Z<BR></FONT> 429 | </TD> 430 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 431 | -<BR> 432 | 66P&nbsp;ALT<BR> 433 | 66W&nbsp;ALT<BR> 434 | 66X&nbsp;ALT<BR> 435 | 66P&nbsp;ALT<BR> 436 | 66W&nbsp;ALT<BR> 437 | 66X&nbsp;ALT<BR> 438 | -<BR> 439 | 64W&nbsp;ALT<BR> 440 | -<BR> 441 | 64P&nbsp;ALT<BR> 442 | 64W&nbsp;ALT<BR> 443 | 64X&nbsp;ALT<BR> 444 | 64P<BR> 445 | 64W<BR> 446 | 64X<BR> 447 | 66X&nbsp;ALT<BR> 448 | 66P&nbsp;ALT<BR> 449 | 66W&nbsp;ALT<BR> 450 | 66P<BR> 451 | 66W<BR> 452 | 66X<BR> 453 | 67P<BR> 454 | 67W<BR> 455 | 67X<BR> 456 | 67Y<BR> 457 | 67Z<BR> 458 | 68P<BR> 459 | 68W<BR> 460 | 68X<BR> 461 | 67Y&nbsp;ALT<BR> 462 | 67Z&nbsp;ALT<BR></FONT> 463 | </TD> 464 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 465 | 5050<BR> 466 | 5091<BR> 467 | 5080<BR> 468 | 5087<BR> 469 | -<BR> 470 | -<BR> 471 | -<BR> 472 | -<BR> 473 | -<BR> 474 | -<BR> 475 | -<BR> 476 | T63YB<BR> 477 | T63XB<BR> 478 | -<BR> 479 | -<BR> 480 | -<BR> 481 | 5887<BR> 482 | 5891<BR> 483 | 5880<BR> 484 | -<BR> 485 | -<BR> 486 | -<BR> 487 | T93Z<BR> 488 | T93YA<BR> 489 | T93XA<BR> 490 | T93YB<BR> 491 | T93XB<BR> 492 | -<BR> 493 | -<BR> 494 | -<BR> 495 | -<BR> 496 | -<BR></FONT> 497 | </TD> 498 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 499 | -<BR> 500 | -<BR> 501 | -<BR> 502 | -<BR> 503 | -<BR> 504 | -<BR> 505 | -<BR> 506 | -<BR> 507 | -<BR> 508 | -<BR> 509 | 8026EKP<BR> 510 | 8026EKW<BR> 511 | 8026EKM<BR> 512 | 8026EKP<BR> 513 | 8026EKB<BR> 514 | 8026EKM<BR> 515 | 1309X<BR> 516 | 1309P<BR> 517 | 1309W<BR> 518 | 8024EKP<BR> 519 | 8024EKW<BR> 520 | 8024EKN<BR> 521 | RJ-9P/CT9P<BR> 522 | RJ-9W<BR> 523 | RJ-9X<BR> 524 | -<BR> 525 | -<BR> 526 | -<BR> 527 | -<BR> 528 | -<BR> 529 | -<BR> 530 | -<BR></FONT> 531 | </TD> 532 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 533 | -<BR> 534 | -<BR> 535 | -<BR> 536 | -<BR> 537 | -<BR> 538 | -<BR> 539 | -<BR> 540 | -<BR> 541 | -<BR> 542 | -<BR> 543 | 3103P<BR> 544 | 3103Y<BR> 545 | 3103Z<BR> 546 | 3103P<BR> 547 | 3103Y<BR> 548 | 3103Z<BR> 549 | -<BR> 550 | -<BR> 551 | -<BR> 552 | -<BR> 553 | -<BR> 554 | -<BR> 555 | 3105P/3106P<BR> 556 | 3105W/3106W<BR> 557 | 3105X/3106X<BR> 558 | 3105Y/3106Y<BR> 559 | 3105Z/3105Z<BR> 560 | 3102P<BR> 561 | 3102W<BR> 562 | 3102X<BR> 563 | 3102Y<BR> 564 | 3102Z<BR></FONT> 565 | </TD> 566 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 567 | -<BR> 568 | -<BR> 569 | -<BR> 570 | -<BR> 571 | -<BR> 572 | -<BR> 573 | -<BR> 574 | -<BR> 575 | -<BR> 576 | -<BR> 577 | -<BR> 578 | -<BR> 579 | -<BR> 580 | -<BR> 581 | -<BR> 582 | -<BR> 583 | -<BR> 584 | -<BR> 585 | -<BR> 586 | -<BR> 587 | -<BR> 588 | -<BR> 589 | EVMCBG<BR> 590 | EVMCCG<BR> 591 | -<BR> 592 | -<BR> 593 | -<BR> 594 | -<BR> 595 | -<BR> 596 | -<BR> 597 | -<BR> 598 | -<BR></FONT> 599 | </TD> 600 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 601 | 55-1-X<BR> 602 | 55-4-X<BR> 603 | 55-3-X<BR> 604 | 55-2-X<BR> 605 | -<BR> 606 | -<BR> 607 | -<BR> 608 | -<BR> 609 | -<BR> 610 | -<BR> 611 | -<BR> 612 | -<BR> 613 | -<BR> 614 | -<BR> 615 | -<BR> 616 | -<BR> 617 | 50-2-X<BR> 618 | 50-4-X<BR> 619 | 50-3-X<BR> 620 | -<BR> 621 | -<BR> 622 | -<BR> 623 | 64P<BR> 624 | 64W<BR> 625 | 64X<BR> 626 | 64Y<BR> 627 | 64Z<BR> 628 | -<BR> 629 | -<BR> 630 | -<BR> 631 | -<BR> 632 | -<BR></FONT> 633 | </TD> 634 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 635 | RT/RTR22<BR> 636 | RT/RTR22<BR> 637 | RT/RTR22<BR> 638 | RT/RTR22<BR> 639 | RJ/RJR22<BR> 640 | RJ/RJR22<BR> 641 | RJ/RJR22<BR> 642 | RT/RTR26<BR> 643 | RT/RTR26<BR> 644 | RT/RTR26<BR> 645 | RJ/RJR26<BR> 646 | RJ/RJR26<BR> 647 | RJ/RJR26<BR> 648 | RJ/RJR26<BR> 649 | RJ/RJR26<BR> 650 | RJ/RJR26<BR> 651 | RT/RTR24<BR> 652 | RT/RTR24<BR> 653 | RT/RTR24<BR> 654 | RJ/RJR24<BR> 655 | RJ/RJR24<BR> 656 | RJ/RJR24<BR> 657 | RJ/RJR24<BR> 658 | RJ/RJR24<BR> 659 | RJ/RJR24<BR> 660 | -<BR> 661 | -<BR> 662 | -<BR> 663 | -<BR> 664 | -<BR> 665 | -<BR> 666 | -<BR></FONT> 667 | </TD> 668 | </TR> 669 | <TR> 670 | <TD COLSPAN=8>&nbsp; 671 | </TD> 672 | </TR> 673 | <TR> 674 | <TD COLSPAN=8> 675 | <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT> 676 | </TD> 677 | </TR> 678 | <TR> 679 | <TD ALIGN=CENTER> 680 | <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT> 681 | </TD> 682 | <TD ALIGN=CENTER> 683 | <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> 684 | </TD> 685 | <TD ALIGN=CENTER> 686 | <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> 687 | </TD> 688 | <TD ALIGN=CENTER> 689 | <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> 690 | </TD> 691 | <TD ALIGN=CENTER> 692 | <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT> 693 | </TD> 694 | <TD ALIGN=CENTER> 695 | <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> 696 | </TD> 697 | <TD ALIGN=CENTER> 698 | <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT> 699 | </TD> 700 | <TD ALIGN=CENTER> 701 | <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT> 702 | </TD> 703 | </TR> 704 | <TR> 705 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 706 | 3323P<BR> 707 | 3323S<BR> 708 | 3323W<BR> 709 | 3329H<BR> 710 | 3329P<BR> 711 | 3329W<BR> 712 | 3339H<BR> 713 | 3339P<BR> 714 | 3339W<BR> 715 | 3352E<BR> 716 | 3352H<BR> 717 | 3352K<BR> 718 | 3352P<BR> 719 | 3352T<BR> 720 | 3352V<BR> 721 | 3352W<BR> 722 | 3362H<BR> 723 | 3362M<BR> 724 | 3362P<BR> 725 | 3362R<BR> 726 | 3362S<BR> 727 | 3362U<BR> 728 | 3362W<BR> 729 | 3362X<BR> 730 | 3386B<BR> 731 | 3386C<BR> 732 | 3386F<BR> 733 | 3386H<BR> 734 | 3386K<BR> 735 | 3386M<BR> 736 | 3386P<BR> 737 | 3386S<BR> 738 | 3386W<BR> 739 | 3386X<BR></FONT> 740 | </TD> 741 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 742 | 25P<BR> 743 | 25S<BR> 744 | 25RX<BR> 745 | 82P<BR> 746 | 82M<BR> 747 | 82PA<BR> 748 | -<BR> 749 | -<BR> 750 | -<BR> 751 | 91E<BR> 752 | 91X<BR> 753 | 91T<BR> 754 | 91B<BR> 755 | 91A<BR> 756 | 91V<BR> 757 | 91W<BR> 758 | 25W<BR> 759 | 25V<BR> 760 | 25P<BR> 761 | -<BR> 762 | 25S<BR> 763 | 25U<BR> 764 | 25RX<BR> 765 | 25X<BR> 766 | 72XW<BR> 767 | 72XL<BR> 768 | 72PM<BR> 769 | 72RX<BR> 770 | -<BR> 771 | 72PX<BR> 772 | 72P<BR> 773 | 72RXW<BR> 774 | 72RXL<BR> 775 | 72X<BR></FONT> 776 | </TD> 777 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 778 | -<BR> 779 | -<BR> 780 | -<BR> 781 | T7YB<BR> 782 | T7YA<BR> 783 | -<BR> 784 | -<BR> 785 | -<BR> 786 | -<BR> 787 | -<BR> 788 | -<BR> 789 | -<BR> 790 | -<BR> 791 | -<BR> 792 | -<BR> 793 | -<BR> 794 | -<BR> 795 | TXD<BR> 796 | TYA<BR> 797 | TYP<BR> 798 | -<BR> 799 | TYD<BR> 800 | TX<BR> 801 | -<BR> 802 | 150SX<BR> 803 | 100SX<BR> 804 | 102T<BR> 805 | 101S<BR> 806 | 190T<BR> 807 | 150TX<BR> 808 | 101<BR> 809 | -<BR> 810 | -<BR> 811 | 101SX<BR></FONT> 812 | </TD> 813 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 814 | ET6P<BR> 815 | ET6S<BR> 816 | ET6X<BR> 817 | RJ-6W/8014EMW<BR> 818 | RJ-6P/8014EMP<BR> 819 | RJ-6X/8014EMX<BR> 820 | TM7W<BR> 821 | TM7P<BR> 822 | TM7X<BR> 823 | -<BR> 824 | 8017SMS<BR> 825 | -<BR> 826 | 8017SMB<BR> 827 | 8017SMA<BR> 828 | -<BR> 829 | -<BR> 830 | CT-6W<BR> 831 | CT-6H<BR> 832 | CT-6P<BR> 833 | CT-6R<BR> 834 | -<BR> 835 | CT-6V<BR> 836 | CT-6X<BR> 837 | -<BR> 838 | -<BR> 839 | 8038EKV<BR> 840 | -<BR> 841 | 8038EKX<BR> 842 | -<BR> 843 | -<BR> 844 | 8038EKP<BR> 845 | 8038EKZ<BR> 846 | 8038EKW<BR> 847 | -<BR></FONT> 848 | </TD> 849 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 850 | -<BR> 851 | -<BR> 852 | -<BR> 853 | 3321H<BR> 854 | 3321P<BR> 855 | 3321N<BR> 856 | 1102H<BR> 857 | 1102P<BR> 858 | 1102T<BR> 859 | RVA0911V304A<BR> 860 | -<BR> 861 | RVA0911H413A<BR> 862 | RVG0707V100A<BR> 863 | RVA0607V(H)306A<BR> 864 | RVA1214H213A<BR> 865 | -<BR> 866 | -<BR> 867 | -<BR> 868 | -<BR> 869 | -<BR> 870 | -<BR> 871 | -<BR> 872 | -<BR> 873 | -<BR> 874 | 3104B<BR> 875 | 3104C<BR> 876 | 3104F<BR> 877 | 3104H<BR> 878 | -<BR> 879 | 3104M<BR> 880 | 3104P<BR> 881 | 3104S<BR> 882 | 3104W<BR> 883 | 3104X<BR></FONT> 884 | </TD> 885 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 886 | EVMQ0G<BR> 887 | EVMQIG<BR> 888 | EVMQ3G<BR> 889 | EVMS0G<BR> 890 | EVMQ0G<BR> 891 | EVMG0G<BR> 892 | -<BR> 893 | -<BR> 894 | -<BR> 895 | EVMK4GA00B<BR> 896 | EVM30GA00B<BR> 897 | EVMK0GA00B<BR> 898 | EVM38GA00B<BR> 899 | EVMB6<BR> 900 | EVLQ0<BR> 901 | -<BR> 902 | EVMMSG<BR> 903 | EVMMBG<BR> 904 | EVMMAG<BR> 905 | -<BR> 906 | -<BR> 907 | EVMMCS<BR> 908 | -<BR> 909 | -<BR> 910 | -<BR> 911 | -<BR> 912 | -<BR> 913 | EVMM1<BR> 914 | -<BR> 915 | -<BR> 916 | EVMM0<BR> 917 | -<BR> 918 | -<BR> 919 | EVMM3<BR></FONT> 920 | </TD> 921 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 922 | -<BR> 923 | -<BR> 924 | -<BR> 925 | 62-3-1<BR> 926 | 62-1-2<BR> 927 | -<BR> 928 | -<BR> 929 | -<BR> 930 | -<BR> 931 | -<BR> 932 | -<BR> 933 | -<BR> 934 | -<BR> 935 | -<BR> 936 | -<BR> 937 | -<BR> 938 | 67R<BR> 939 | -<BR> 940 | 67P<BR> 941 | -<BR> 942 | -<BR> 943 | -<BR> 944 | -<BR> 945 | 67X<BR> 946 | 63V<BR> 947 | 63S<BR> 948 | 63M<BR> 949 | -<BR> 950 | -<BR> 951 | 63H<BR> 952 | 63P<BR> 953 | -<BR> 954 | -<BR> 955 | 63X<BR></FONT> 956 | </TD> 957 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 958 | -<BR> 959 | -<BR> 960 | -<BR> 961 | RJ/RJR50<BR> 962 | RJ/RJR50<BR> 963 | RJ/RJR50<BR> 964 | -<BR> 965 | -<BR> 966 | -<BR> 967 | -<BR> 968 | -<BR> 969 | -<BR> 970 | -<BR> 971 | -<BR> 972 | -<BR> 973 | -<BR> 974 | -<BR> 975 | -<BR> 976 | -<BR> 977 | -<BR> 978 | -<BR> 979 | -<BR> 980 | -<BR> 981 | -<BR> 982 | -<BR> 983 | -<BR> 984 | -<BR> 985 | -<BR> 986 | -<BR> 987 | -<BR> 988 | -<BR> 989 | -<BR> 990 | -<BR> 991 | -<BR></FONT> 992 | </TD> 993 | </TR> 994 | </TABLE> 995 | <P>&nbsp;<P> 996 | <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=3> 997 | <TR> 998 | <TD COLSPAN=7> 999 | <FONT color="#0000FF" SIZE=4 FACE=ARIAL><B>SMD TRIM-POT CROSS REFERENCE</B></FONT> 1000 | <P> 1001 | <FONT SIZE=4 FACE=ARIAL><B>MULTI-TURN</B></FONT> 1002 | </TD> 1003 | </TR> 1004 | <TR> 1005 | <TD> 1006 | <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT> 1007 | </TD> 1008 | <TD> 1009 | <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> 1010 | </TD> 1011 | <TD> 1012 | <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> 1013 | </TD> 1014 | <TD> 1015 | <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> 1016 | </TD> 1017 | <TD> 1018 | <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> 1019 | </TD> 1020 | <TD> 1021 | <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT> 1022 | </TD> 1023 | <TD> 1024 | <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT> 1025 | </TD> 1026 | </TR> 1027 | <TR> 1028 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1029 | 3224G<BR> 1030 | 3224J<BR> 1031 | 3224W<BR> 1032 | 3269P<BR> 1033 | 3269W<BR> 1034 | 3269X<BR></FONT> 1035 | </TD> 1036 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1037 | 44G<BR> 1038 | 44J<BR> 1039 | 44W<BR> 1040 | 84P<BR> 1041 | 84W<BR> 1042 | 84X<BR></FONT> 1043 | </TD> 1044 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1045 | -<BR> 1046 | -<BR> 1047 | -<BR> 1048 | ST63Z<BR> 1049 | ST63Y<BR> 1050 | -<BR></FONT> 1051 | </TD> 1052 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1053 | -<BR> 1054 | -<BR> 1055 | -<BR> 1056 | ST5P<BR> 1057 | ST5W<BR> 1058 | ST5X<BR></FONT> 1059 | </TD> 1060 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1061 | -<BR> 1062 | -<BR> 1063 | -<BR> 1064 | -<BR> 1065 | -<BR> 1066 | -<BR></FONT> 1067 | </TD> 1068 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1069 | -<BR> 1070 | -<BR> 1071 | -<BR> 1072 | -<BR> 1073 | -<BR> 1074 | -<BR></FONT> 1075 | </TD> 1076 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1077 | -<BR> 1078 | -<BR> 1079 | -<BR> 1080 | -<BR> 1081 | -<BR> 1082 | -<BR></FONT> 1083 | </TD> 1084 | </TR> 1085 | <TR> 1086 | <TD COLSPAN=7>&nbsp; 1087 | </TD> 1088 | </TR> 1089 | <TR> 1090 | <TD COLSPAN=7> 1091 | <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT> 1092 | </TD> 1093 | </TR> 1094 | <TR> 1095 | <TD> 1096 | <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT> 1097 | </TD> 1098 | <TD> 1099 | <FONT SIZE=3 FACE=ARIAL><B>BI&nbsp;TECH</B></FONT> 1100 | </TD> 1101 | <TD> 1102 | <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT> 1103 | </TD> 1104 | <TD> 1105 | <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT> 1106 | </TD> 1107 | <TD> 1108 | <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT> 1109 | </TD> 1110 | <TD> 1111 | <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT> 1112 | </TD> 1113 | <TD> 1114 | <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT> 1115 | </TD> 1116 | </TR> 1117 | <TR> 1118 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1119 | 3314G<BR> 1120 | 3314J<BR> 1121 | 3364A/B<BR> 1122 | 3364C/D<BR> 1123 | 3364W/X<BR> 1124 | 3313G<BR> 1125 | 3313J<BR></FONT> 1126 | </TD> 1127 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1128 | 23B<BR> 1129 | 23A<BR> 1130 | 21X<BR> 1131 | 21W<BR> 1132 | -<BR> 1133 | 22B<BR> 1134 | 22A<BR></FONT> 1135 | </TD> 1136 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1137 | ST5YL/ST53YL<BR> 1138 | ST5YJ/5T53YJ<BR> 1139 | ST-23A<BR> 1140 | ST-22B<BR> 1141 | ST-22<BR> 1142 | -<BR> 1143 | -<BR></FONT> 1144 | </TD> 1145 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1146 | ST-4B<BR> 1147 | ST-4A<BR> 1148 | -<BR> 1149 | -<BR> 1150 | -<BR> 1151 | ST-3B<BR> 1152 | ST-3A<BR></FONT> 1153 | </TD> 1154 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1155 | -<BR> 1156 | EVM-6YS<BR> 1157 | EVM-1E<BR> 1158 | EVM-1G<BR> 1159 | EVM-1D<BR> 1160 | -<BR> 1161 | -<BR></FONT> 1162 | </TD> 1163 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1164 | G4B<BR> 1165 | G4A<BR> 1166 | TR04-3S1<BR> 1167 | TRG04-2S1<BR> 1168 | -<BR> 1169 | -<BR> 1170 | -<BR></FONT> 1171 | </TD> 1172 | <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3> 1173 | -<BR> 1174 | -<BR> 1175 | DVR-43A<BR> 1176 | CVR-42C<BR> 1177 | CVR-42A/C<BR> 1178 | -<BR> 1179 | -<BR></FONT> 1180 | </TD> 1181 | </TR> 1182 | </TABLE> 1183 | <P> 1184 | <FONT SIZE=4 FACE=ARIAL><B>ALT =&nbsp;ALTERNATE</B></FONT> 1185 | <P> 1186 | 1187 | &nbsp; 1188 | <P> 1189 | </td> 1190 | </tr> 1191 | </table> 1192 | 1193 | 1194 | <b>CAPACITOR</b> 1195 | 1196 | 1197 | 1198 | 1199 | 1200 | 1201 | 1202 | 1203 | >NAME 1204 | >VALUE 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | <b>CAPACITOR</b> 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | >NAME 1220 | >VALUE 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | <b>CAPACITOR</b> 1227 | 1228 | 1229 | 1230 | 1231 | 1232 | 1233 | 1234 | 1235 | >NAME 1236 | >VALUE 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | <b>RESISTOR</b> 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | >NAME 1252 | >VALUE 1253 | 1254 | 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | <b>LEDs</b><p> 1261 | <author>Created by librarian@cadsoft.de</author><br> 1262 | Extended by Federico Battaglin <author>&lt;federico.rd@fdpinternational.com&gt;</author> with DUOLED 1263 | 1264 | 1265 | <b>SML0603-XXX (HIGH INTENSITY) LED</b><p> 1266 | <table> 1267 | <tr><td>AG3K</td><td>AQUA GREEN</td></tr> 1268 | <tr><td>B1K</td><td>SUPER BLUE</td></tr> 1269 | <tr><td>R1K</td><td>SUPER RED</td></tr> 1270 | <tr><td>R3K</td><td>ULTRA RED</td></tr> 1271 | <tr><td>O3K</td><td>SUPER ORANGE</td></tr> 1272 | <tr><td>O3KH</td><td>SOFT ORANGE</td></tr> 1273 | <tr><td>Y3KH</td><td>SUPER YELLOW</td></tr> 1274 | <tr><td>Y3K</td><td>SUPER YELLOW</td></tr> 1275 | <tr><td>2CW</td><td>WHITE</td></tr> 1276 | </table> 1277 | Source: http://www.ledtronics.com/ds/smd-0603/Dstr0092.pdf 1278 | 1279 | 1280 | 1281 | 1282 | 1283 | 1284 | 1285 | 1286 | 1287 | 1288 | >NAME 1289 | >VALUE 1290 | 1291 | 1292 | 1293 | 1294 | 1295 | 1296 | <b>Test Pins/Pads</b><p> 1297 | Cream on SMD OFF.<br> 1298 | new: Attribute TP_SIGNAL_NAME<br> 1299 | <author>Created by librarian@cadsoft.de</author> 1300 | 1301 | 1302 | <b>TEST PAD</b> 1303 | 1304 | 1305 | 1306 | >NAME 1307 | >VALUE 1308 | >TP_SIGNAL_NAME 1309 | 1310 | 1311 | 1312 | 1313 | 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | >NAME 1321 | >VALUE 1322 | 1323 | 1324 | 1325 | 1326 | 1327 | 1328 | 1329 | 1330 | 1331 | 1332 | 1333 | 1334 | 1335 | 1336 | 1337 | 1338 | 1339 | 1340 | 1341 | 1342 | 1343 | 1344 | 1345 | 1346 | 1347 | 1348 | 1349 | 1350 | 1351 | 1352 | 1353 | 1354 | 1355 | 1356 | 1357 | 1358 | 1359 | 1360 | 1361 | 1362 | 1363 | 1364 | 1365 | 1366 | 1367 | 1368 | 1369 | 1370 | 1371 | 1372 | 1373 | 1374 | 1375 | 1376 | 1377 | 1378 | 1379 | 1380 | 1381 | 1382 | 1383 | 1384 | 1385 | 1386 | 1387 | 1388 | 1389 | 1390 | 1391 | 1392 | 1393 | 1394 | 1395 | 1396 | 1397 | 1398 | 1399 | 1400 | 1401 | 1402 | 1403 | 1404 | 1405 | 1406 | 1407 | 1408 | 1409 | 1410 | 1411 | 1412 | 1413 | 1414 | 1415 | 1416 | 1417 | 1418 | 1419 | 1420 | 1421 | 1422 | 1423 | 1424 | 1425 | 1426 | 1427 | 1428 | 1429 | >NAME 1430 | >VALUE 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | 1442 | 1443 | 1444 | 1445 | 1446 | 1447 | 1448 | 1449 | 1450 | 1451 | 1452 | 1453 | 1454 | 1455 | DC-DC controllers and converters 1456 | 1457 | 1458 | 1459 | 1460 | 1461 | 1462 | 1463 | 1464 | >NAME 1465 | >VALUE 1466 | 1467 | 1468 | 1469 | 1470 | 1471 | 1472 | 1473 | 1474 | 1475 | 1476 | 1477 | 1478 | 1479 | 1480 | 1481 | 1482 | 1483 | 1484 | 1485 | 1486 | 1487 | 1488 | 1489 | 1490 | 1491 | 1492 | 1493 | 1494 | 1495 | 1496 | 1497 | 1498 | 1499 | 1500 | 1501 | 1502 | 1503 | <b>EAGLE Design Rules</b> 1504 | <p> 1505 | Die Standard-Design-Rules sind so gewählt, dass sie für 1506 | die meisten Anwendungen passen. Sollte ihre Platine 1507 | besondere Anforderungen haben, treffen Sie die erforderlichen 1508 | Einstellungen hier und speichern die Design Rules unter 1509 | einem neuen Namen ab. 1510 | <b>Laen's PCB Order Design Rules</b> 1511 | <p> 1512 | Please make sure your boards conform to these design rules. 1513 | 1514 | 1515 | 1516 | 1517 | 1518 | 1519 | 1520 | 1521 | 1522 | 1523 | 1524 | 1525 | 1526 | 1527 | 1528 | 1529 | 1530 | 1531 | 1532 | 1533 | 1534 | 1535 | 1536 | 1537 | 1538 | 1539 | 1540 | 1541 | 1542 | 1543 | 1544 | 1545 | 1546 | 1547 | 1548 | 1549 | 1550 | 1551 | 1552 | 1553 | 1554 | 1555 | 1556 | 1557 | 1558 | 1559 | 1560 | 1561 | 1562 | 1563 | 1564 | 1565 | 1566 | 1567 | 1568 | 1569 | 1570 | 1571 | 1572 | 1573 | 1574 | 1575 | 1576 | 1577 | 1578 | 1579 | 1580 | 1581 | 1582 | 1583 | 1584 | 1585 | 1586 | 1587 | 1588 | 1589 | 1590 | 1591 | 1592 | 1593 | 1594 | 1595 | 1596 | 1597 | 1598 | 1599 | 1600 | 1601 | 1602 | 1603 | 1604 | 1605 | 1606 | 1607 | 1608 | 1609 | 1610 | 1611 | 1612 | 1613 | 1614 | 1615 | 1616 | 1617 | 1618 | 1619 | 1620 | 1621 | 1622 | 1623 | 1624 | 1625 | 1626 | 1627 | 1628 | 1629 | 1630 | 1631 | 1632 | 1633 | 1634 | 1635 | 1636 | 1637 | 1638 | 1639 | 1640 | 1641 | 1642 | 1643 | 1644 | 1645 | 1646 | 1647 | 1648 | 1649 | 1650 | 1651 | 1652 | 1653 | 1654 | 1655 | 1656 | 1657 | 1658 | 1659 | 1660 | 1661 | 1662 | 1663 | 1664 | 1665 | 1666 | 1667 | 1668 | 1669 | 1670 | 1671 | 1672 | 1673 | 1674 | 1675 | 1676 | 1677 | 1678 | 1679 | 1680 | 1681 | 1682 | 1683 | 1684 | 1685 | 1686 | 1687 | 1688 | 1689 | 1690 | 1691 | 1692 | 1693 | 1694 | 1695 | 1696 | 1697 | 1698 | 1699 | 1700 | 1701 | 1702 | 1703 | 1704 | 1705 | 1706 | 1707 | 1708 | 1709 | 1710 | 1711 | 1712 | 1713 | 1714 | 1715 | 1716 | 1717 | 1718 | 1719 | 1720 | 1721 | 1722 | 1723 | 1724 | 1725 | 1726 | 1727 | 1728 | 1729 | 1730 | 1731 | 1732 | 1733 | 1734 | 1735 | 1736 | 1737 | 1738 | 1739 | 1740 | 1741 | 1742 | 1743 | 1744 | 1745 | 1746 | 1747 | 1748 | 1749 | 1750 | 1751 | 1752 | 1753 | 1754 | 1755 | 1756 | 1757 | 1758 | 1759 | 1760 | 1761 | 1762 | 1763 | 1764 | 1765 | 1766 | 1767 | 1768 | 1769 | 1770 | 1771 | 1772 | 1773 | 1774 | 1775 | 1776 | 1777 | 1778 | 1779 | 1780 | 1781 | 1782 | 1783 | 1784 | 1785 | 1786 | 1787 | 1788 | 1789 | 1790 | 1791 | 1792 | 1793 | 1794 | 1795 | 1796 | 1797 | 1798 | 1799 | 1800 | 1801 | 1802 | 1803 | 1804 | 1805 | 1806 | 1807 | 1808 | 1809 | 1810 | 1811 | 1812 | 1813 | 1814 | 1815 | 1816 | 1817 | 1818 | 1819 | 1820 | 1821 | 1822 | 1823 | 1824 | 1825 | 1826 | 1827 | 1828 | 1829 | 1830 | 1831 | 1832 | 1833 | 1834 | 1835 | 1836 | 1837 | 1838 | 1839 | 1840 | 1841 | 1842 | 1843 | 1844 | 1845 | 1846 | 1847 | 1848 | 1849 | 1850 | 1851 | 1852 | 1853 | 1854 | 1855 | 1856 | 1857 | 1858 | 1859 | 1860 | 1861 | 1862 | 1863 | 1864 | 1865 | 1866 | 1867 | 1868 | 1869 | 1870 | 1871 | 1872 | 1873 | 1874 | 1875 | 1876 | 1877 | 1878 | 1879 | 1880 | 1881 | 1882 | 1883 | 1884 | 1885 | 1886 | 1887 | 1888 | 1889 | 1890 | 1891 | 1892 | 1893 | 1894 | 1895 | 1896 | 1897 | 1898 | 1899 | 1900 | 1901 | 1902 | 1903 | 1904 | 1905 | 1906 | 1907 | 1908 | 1909 | 1910 | 1911 | 1912 | 1913 | 1914 | 1915 | 1916 | 1917 | 1918 | 1919 | 1920 | 1921 | 1922 | 1923 | 1924 | 1925 | 1926 | 1927 | 1928 | 1929 | 1930 | 1931 | 1932 | 1933 | 1934 | 1935 | 1936 | 1937 | 1938 | 1939 | 1940 | 1941 | 1942 | 1943 | 1944 | 1945 | 1946 | 1947 | 1948 | 1949 | 1950 | 1951 | 1952 | 1953 | 1954 | 1955 | 1956 | 1957 | 1958 | 1959 | 1960 | 1961 | 1962 | 1963 | 1964 | 1965 | 1966 | 1967 | 1968 | 1969 | 1970 | 1971 | 1972 | 1973 | 1974 | 1975 | 1976 | 1977 | 1978 | 1979 | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986 | 1987 | 1988 | 1989 | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | 2032 | 2033 | 2034 | 2035 | 2036 | 2037 | 2038 | 2039 | 2040 | 2041 | 2042 | 2043 | 2044 | 2045 | 2046 | 2047 | 2048 | 2049 | 2050 | 2051 | 2052 | 2053 | 2054 | 2055 | 2056 | 2057 | 2058 | 2059 | 2060 | 2061 | 2062 | 2063 | 2064 | 2065 | 2066 | 2067 | 2068 | 2069 | 2070 | 2071 | 2072 | 2073 | 2074 | 2075 | 2076 | 2077 | 2078 | 2079 | 2080 | 2081 | 2082 | 2083 | 2084 | 2085 | 2086 | 2087 | 2088 | 2089 | 2090 | 2091 | 2092 | 2093 | 2094 | 2095 | 2096 | 2097 | 2098 | 2099 | 2100 | 2101 | 2102 | 2103 | 2104 | 2105 | 2106 | 2107 | 2108 | 2109 | 2110 | 2111 | 2112 | 2113 | 2114 | 2115 | 2116 | 2117 | 2118 | 2119 | 2120 | 2121 | 2122 | 2123 | 2124 | 2125 | --------------------------------------------------------------------------------