├── firmware ├── .gdbinit ├── .gitignore ├── Makefile ├── button.c ├── button.h ├── fatfs │ ├── 00history.txt │ ├── 00readme.txt │ ├── diskio.h │ ├── ff.c │ ├── ff.h │ ├── ffconf.h │ ├── integer.h │ └── option │ │ ├── cc932.c │ │ ├── cc936.c │ │ ├── cc949.c │ │ ├── cc950.c │ │ ├── ccsbcs.c │ │ ├── syscall.c │ │ └── unicode.c ├── flash.ld ├── hal.c ├── hal.h ├── hal_spi.c ├── led.c ├── led.h ├── main.c ├── main.h ├── protocol.c ├── protocol.h ├── protocols │ ├── psk.c │ └── psk.h ├── sd.c ├── sd.h ├── startup.s ├── stm32f0xx_conf.h ├── system_stm32f0xx.c ├── system_stm32f0xx.c.old └── usb │ ├── usb_bsp.c │ ├── usb_conf.h │ ├── usbd_class.c │ ├── usbd_class.h │ ├── usbd_conf.h │ ├── usbd_desc.c │ ├── usbd_desc.h │ ├── usbd_pwr.c │ └── usbd_usr.c ├── fp-lib-table ├── gerber ├── rfid-B.Cu.gbl ├── rfid-B.Mask.gbs ├── rfid-B.SilkS.gbo ├── rfid-Edge.Cuts.gm1 ├── rfid-F.Cu.gtl ├── rfid-F.Mask.gts ├── rfid-F.SilkS.gto ├── rfid-In1.Cu.g2 ├── rfid-In2.Cu.g3 └── rfid.drl ├── python ├── decode.py ├── read_test.py ├── rfid │ ├── __init__.py │ ├── driver.py │ ├── protocol.py │ └── t5577.py └── write_test.py ├── rfid-cache.lib ├── rfid-rescue.lib ├── rfid.bak ├── rfid.cmp ├── rfid.kicad_pcb ├── rfid.kicad_pcb-bak ├── rfid.net ├── rfid.pro ├── rfid.sch ├── rfid_old.kicad_pcb ├── rfid_orig.kicad_pcb ├── rfid_rev1.zip ├── sed.sh ├── spiral.sh ├── spiral.txt └── spiraller.py /firmware/.gdbinit: -------------------------------------------------------------------------------- 1 | tar ext /dev/ttyBMP 2 | mon swdp_scan 3 | attach 1 4 | file rfid.elf 5 | -------------------------------------------------------------------------------- /firmware/.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | *.elf 3 | *.map 4 | lib/CMSIS 5 | lib/STM32F0xx_StdPeriph_Driver 6 | lib/usb-device 7 | lib/usb-fs 8 | *.o 9 | -------------------------------------------------------------------------------- /firmware/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for STM32F373 using cmsis and GNU toolchain. 2 | 3 | # Files to include 4 | C_SRC = $(wildcard *.c) 5 | C_SRC += $(wildcard usb/*.c) 6 | C_SRC += $(wildcard fatfs/*.c) 7 | C_SRC += $(wildcard protocols/*.c) 8 | C_SRC += $(wildcard lib/STM32F0xx_StdPeriph_Driver/src/*.c) 9 | C_SRC += $(wildcard lib/usb-fs/src/*.c) 10 | C_SRC += $(wildcard lib/usb-device/src/*.c) 11 | 12 | OBJECTS = $(patsubst %.c,%.o,$(C_SRC)) startup.o 13 | 14 | PROJECT = rfid 15 | 16 | LIBRARIES = 17 | 18 | INC = -I. -Iusb -Iprotocols -Ifatfs 19 | INC += -Ilib/CMSIS/Include -Ilib/CMSIS/Device/ST/STM32F0xx/Include 20 | INC += -Ilib/STM32F0xx_StdPeriph_Driver/inc 21 | INC += -Ilib/usb-fs/inc 22 | INC += -Ilib/usb-device/inc 23 | 24 | # Assembler, compiler, and linker flags 25 | AFLAGS = -mlittle-endian -mthumb -mcpu=cortex-m0 -g 26 | CFLAGS = $(AFLAGS) -O2 $(INC) -std=c99 -DUSE_STDPERIPH_DRIVER -Wall 27 | CFLAGS += -DSTM32F042 28 | CFLAGS += -DUSE_STDPERIPH_DRIVER 29 | CFLAGS += -fdata-sections -ffunction-sections 30 | CFLAGS += -flto 31 | LFLAGS = $(CFLAGS) -nostartfiles -Wl,--gc-sections 32 | 33 | # Targets 34 | all: $(PROJECT).elf 35 | clean: 36 | -rm -f $(OBJECTS) *.elf *.bin *.map *.hex 37 | $(PROJECT).hex: $(PROJECT).elf 38 | arm-none-eabi-objcopy -R .config $(PROJECT).elf -O ihex $(PROJECT).hex 39 | $(PROJECT).bin: $(PROJECT).elf 40 | arm-none-eabi-objcopy -R .config -O binary $(PROJECT).elf $(PROJECT).bin 41 | $(PROJECT).elf: $(OBJECTS) 42 | arm-none-eabi-gcc $(LFLAGS) -Tflash.ld -Wl,-Map=$(PROJECT).map -o $(PROJECT).elf $(OBJECTS) $(LIBRARIES) 43 | startup.o: startup.s 44 | arm-none-eabi-as $(AFLAGS) startup.s -o startup.o 45 | lib/%.o: lib/%.c 46 | arm-none-eabi-gcc $(CFLAGS) -c -o $@ $< 47 | %.o: %.c 48 | arm-none-eabi-gcc $(CFLAGS) -c -o $@ $< 49 | gdb: $(PROJECT).elf 50 | arm-none-eabi-gdb $(PROJECT).elf -x init.gdb 51 | load: $(PROJECT).elf 52 | arm-none-eabi-gdb $(PROJECT).elf -x init.gdb -ex load 53 | loadquit: $(PROJECT).elf 54 | arm-none-eabi-gdb $(PROJECT).elf -batch -x init.gdb -ex load -ex kill -ex quit 55 | stlink: 56 | st-util -p 4244 57 | stload: $(PROJECT).bin 58 | st-flash write $(PROJECT).bin 0x8000000 59 | sterase: 60 | st-flash erase 61 | dfuload: $(PROJECT).bin 62 | dfu-util -d 0483:df11 -a 0 -s 0x8000000 -D $(PROJECT).bin 63 | -------------------------------------------------------------------------------- /firmware/button.c: -------------------------------------------------------------------------------- 1 | #include "button.h" 2 | #include "hal.h" 3 | 4 | enum button_event button_event() { 5 | static enum { 6 | BUTTON_RELEASED, 7 | BUTTON_DEBOUNCE, 8 | BUTTON_PRESSED, 9 | BUTTON_STILL_PRESSED, 10 | } state = BUTTON_RELEASED; 11 | 12 | enum button_event retval = BUTTON_EVENT_NONE; 13 | 14 | switch(state) { 15 | case BUTTON_RELEASED: 16 | if(button()) { 17 | state = BUTTON_DEBOUNCE; 18 | button_timer = 5; // Debounce period 5ms 19 | } 20 | break; 21 | case BUTTON_DEBOUNCE: 22 | if(!button()) { 23 | state = BUTTON_RELEASED; 24 | } else if(button_timer == 0) { 25 | button_timer = 700; // Long press timer 26 | state = BUTTON_PRESSED; 27 | } 28 | break; 29 | case BUTTON_PRESSED: 30 | if(button_timer == 0) { 31 | retval = BUTTON_EVENT_LONG_PRESS; 32 | state = BUTTON_STILL_PRESSED; 33 | } 34 | else if(!button()) { 35 | retval = BUTTON_EVENT_PRESS; 36 | state = BUTTON_RELEASED; 37 | } 38 | break; 39 | case BUTTON_STILL_PRESSED: 40 | if(!button()) { 41 | state = BUTTON_RELEASED; 42 | } 43 | break; 44 | } 45 | 46 | return retval; 47 | } 48 | -------------------------------------------------------------------------------- /firmware/button.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum button_event { 4 | BUTTON_EVENT_NONE, 5 | BUTTON_EVENT_PRESS, 6 | BUTTON_EVENT_LONG_PRESS, 7 | }; 8 | 9 | enum button_event button_event(); 10 | -------------------------------------------------------------------------------- /firmware/fatfs/00history.txt: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------- 2 | Revision history of FatFs module 3 | ---------------------------------------------------------------------------- 4 | 5 | R0.00 (February 26, 2006) 6 | 7 | Prototype. 8 | 9 | 10 | 11 | R0.01 (April 29, 2006) 12 | 13 | The first release. 14 | 15 | 16 | 17 | R0.02 (June 01, 2006) 18 | 19 | Added FAT12 support. 20 | Removed unbuffered mode. 21 | Fixed a problem on small (<32M) partition. 22 | 23 | 24 | 25 | R0.02a (June 10, 2006) 26 | 27 | Added a configuration option (_FS_MINIMUM). 28 | 29 | 30 | 31 | R0.03 (September 22, 2006) 32 | 33 | Added f_rename(). 34 | Changed option _FS_MINIMUM to _FS_MINIMIZE. 35 | 36 | 37 | 38 | R0.03a (December 11, 2006) 39 | 40 | Improved cluster scan algorithm to write files fast. 41 | Fixed f_mkdir() creates incorrect directory on FAT32. 42 | 43 | 44 | 45 | R0.04 (February 04, 2007) 46 | 47 | Added f_mkfs(). 48 | Supported multiple drive system. 49 | Changed some interfaces for multiple drive system. 50 | Changed f_mountdrv() to f_mount(). 51 | 52 | 53 | 54 | R0.04a (April 01, 2007) 55 | 56 | Supported multiple partitions on a physical drive. 57 | Added a capability of extending file size to f_lseek(). 58 | Added minimization level 3. 59 | Fixed an endian sensitive code in f_mkfs(). 60 | 61 | 62 | 63 | R0.04b (May 05, 2007) 64 | 65 | Added a configuration option _USE_NTFLAG. 66 | Added FSINFO support. 67 | Fixed DBCS name can result FR_INVALID_NAME. 68 | Fixed short seek (<= csize) collapses the file object. 69 | 70 | 71 | 72 | R0.05 (August 25, 2007) 73 | 74 | Changed arguments of f_read(), f_write() and f_mkfs(). 75 | Fixed f_mkfs() on FAT32 creates incorrect FSINFO. 76 | Fixed f_mkdir() on FAT32 creates incorrect directory. 77 | 78 | 79 | 80 | R0.05a (February 03, 2008) 81 | 82 | Added f_truncate() and f_utime(). 83 | Fixed off by one error at FAT sub-type determination. 84 | Fixed btr in f_read() can be mistruncated. 85 | Fixed cached sector is not flushed when create and close without write. 86 | 87 | 88 | 89 | R0.06 (April 01, 2008) 90 | 91 | Added fputc(), fputs(), fprintf() and fgets(). 92 | Improved performance of f_lseek() on moving to the same or following cluster. 93 | 94 | 95 | 96 | R0.07 (April 01, 2009) 97 | 98 | Merged Tiny-FatFs as a configuration option. (_FS_TINY) 99 | Added long file name feature. (_USE_LFN) 100 | Added multiple code page feature. (_CODE_PAGE) 101 | Added re-entrancy for multitask operation. (_FS_REENTRANT) 102 | Added auto cluster size selection to f_mkfs(). 103 | Added rewind option to f_readdir(). 104 | Changed result code of critical errors. 105 | Renamed string functions to avoid name collision. 106 | 107 | 108 | 109 | R0.07a (April 14, 2009) 110 | 111 | Septemberarated out OS dependent code on reentrant cfg. 112 | Added multiple sector size feature. 113 | 114 | 115 | 116 | R0.07c (June 21, 2009) 117 | 118 | Fixed f_unlink() can return FR_OK on error. 119 | Fixed wrong cache control in f_lseek(). 120 | Added relative path feature. 121 | Added f_chdir() and f_chdrive(). 122 | Added proper case conversion to extended character. 123 | 124 | 125 | 126 | R0.07e (November 03, 2009) 127 | 128 | Septemberarated out configuration options from ff.h to ffconf.h. 129 | Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH. 130 | Fixed name matching error on the 13 character boundary. 131 | Added a configuration option, _LFN_UNICODE. 132 | Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. 133 | 134 | 135 | 136 | R0.08 (May 15, 2010) 137 | 138 | Added a memory configuration option. (_USE_LFN = 3) 139 | Added file lock feature. (_FS_SHARE) 140 | Added fast seek feature. (_USE_FASTSEEK) 141 | Changed some types on the API, XCHAR->TCHAR. 142 | Changed .fname in the FILINFO structure on Unicode cfg. 143 | String functions support UTF-8 encoding files on Unicode cfg. 144 | 145 | 146 | 147 | R0.08a (August 16, 2010) 148 | 149 | Added f_getcwd(). (_FS_RPATH = 2) 150 | Added sector erase feature. (_USE_ERASE) 151 | Moved file lock semaphore table from fs object to the bss. 152 | Fixed f_mkfs() creates wrong FAT32 volume. 153 | 154 | 155 | 156 | R0.08b (January 15, 2011) 157 | 158 | Fast seek feature is also applied to f_read() and f_write(). 159 | f_lseek() reports required table size on creating CLMP. 160 | Extended format syntax of f_printf(). 161 | Ignores duplicated directory separators in given path name. 162 | 163 | 164 | 165 | R0.09 (September 06, 2011) 166 | 167 | f_mkfs() supports multiple partition to complete the multiple partition feature. 168 | Added f_fdisk(). 169 | 170 | 171 | 172 | R0.09a (August 27, 2012) 173 | 174 | Changed f_open() and f_opendir() reject null object pointer to avoid crash. 175 | Changed option name _FS_SHARE to _FS_LOCK. 176 | Fixed assertion failure due to OS/2 EA on FAT12/16 volume. 177 | 178 | 179 | 180 | R0.09b (January 24, 2013) 181 | 182 | Added f_setlabel() and f_getlabel(). 183 | 184 | 185 | 186 | R0.10 (October 02, 2013) 187 | 188 | Added selection of character encoding on the file. (_STRF_ENCODE) 189 | Added f_closedir(). 190 | Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO) 191 | Added forced mount feature with changes of f_mount(). 192 | Improved behavior of volume auto detection. 193 | Improved write throughput of f_puts() and f_printf(). 194 | Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write(). 195 | Fixed f_write() can be truncated when the file size is close to 4GB. 196 | Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error. 197 | 198 | 199 | 200 | R0.10a (January 15, 2014) 201 | 202 | Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID) 203 | Added a configuration option of minimum sector size. (_MIN_SS) 204 | 2nd argument of f_rename() can have a drive number and it will be ignored. 205 | Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10) 206 | Fixed f_close() invalidates the file object without volume lock. 207 | Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10) 208 | Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07) 209 | 210 | 211 | 212 | R0.10b (May 19, 2014) 213 | 214 | Fixed a hard error in the disk I/O layer can collapse the directory entry. 215 | Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07) 216 | 217 | 218 | 219 | R0.10c (November 09, 2014) 220 | 221 | Added a configuration option for the platforms without RTC. (_FS_NORTC) 222 | Changed option name _USE_ERASE to _USE_TRIM. 223 | Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b) 224 | Fixed a potential problem of FAT access that can appear on disk error. 225 | Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08) 226 | 227 | 228 | 229 | R0.11 (February 09, 2015) 230 | 231 | Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND) 232 | Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c) 233 | Fixed _FS_NORTC option does not work properly. (appeared at R0.10c) 234 | 235 | 236 | 237 | R0.11a (September 05, 2015) 238 | 239 | Fixed wrong media change can lead a deadlock at thread-safe configuration. 240 | Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE) 241 | Removed some code pages actually not exist on the standard systems. (_CODE_PAGE) 242 | Fixed errors in the case conversion teble of code page 437 and 850 (ff.c). 243 | Fixed errors in the case conversion teble of Unicode (cc*.c). 244 | 245 | 246 | 247 | R0.12 (April 12, 2016) 248 | 249 | Added support for exFAT file system. (_FS_EXFAT) 250 | Added f_expand(). (_USE_EXPAND) 251 | Changed some members in FINFO structure and behavior of f_readdir(). 252 | Added an option _USE_CHMOD. 253 | Removed an option _WORD_ACCESS. 254 | Fixed errors in the case conversion table of Unicode (cc*.c). 255 | 256 | 257 | 258 | R0.12a (July 10, 2016) 259 | 260 | Added support for creating exFAT volume with some changes of f_mkfs(). 261 | Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed. 262 | f_forward() is available regardless of _FS_TINY. 263 | Fixed f_mkfs() creates wrong volume. (appeared at R0.12) 264 | Fixed wrong memory read in create_name(). (appeared at R0.12) 265 | Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD. 266 | 267 | 268 | 269 | R0.12b (September 04, 2016) 270 | 271 | Made f_rename() be able to rename objects with the same name but case. 272 | Fixed an error in the case conversion teble of code page 866. (ff.c) 273 | Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12) 274 | Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12) 275 | Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12) 276 | Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12) 277 | Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12) 278 | Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12) 279 | 280 | 281 | 282 | R0.12c (March 04, 2017) 283 | 284 | Improved write throughput at the fragmented file on the exFAT volume. 285 | Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN. 286 | Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12) 287 | Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c) 288 | 289 | -------------------------------------------------------------------------------- /firmware/fatfs/00readme.txt: -------------------------------------------------------------------------------- 1 | FatFs Module Source Files R0.12c 2 | 3 | 4 | FILES 5 | 6 | 00readme.txt This file. 7 | 00history.txt Revision history. 8 | ff.c FatFs module. 9 | ffconf.h Configuration file of FatFs module. 10 | ff.h Common include file for FatFs and application module. 11 | diskio.h Common include file for FatFs and disk I/O module. 12 | diskio.c An example of glue function to attach existing disk I/O module to FatFs. 13 | integer.h Integer type definitions for FatFs. 14 | option Optional external modules. 15 | 16 | 17 | Low level disk I/O module is not included in this archive because the FatFs 18 | module is only a generic file system layer and it does not depend on any specific 19 | storage device. You have to provide a low level disk I/O module written to 20 | control the storage device that attached to the target system. 21 | 22 | -------------------------------------------------------------------------------- /firmware/fatfs/diskio.h: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------/ 2 | / Low level disk interface modlue include file (C)ChaN, 2014 / 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #include "integer.h" 13 | 14 | 15 | /* Status of Disk Functions */ 16 | typedef BYTE DSTATUS; 17 | 18 | /* Results of Disk Functions */ 19 | typedef enum { 20 | RES_OK = 0, /* 0: Successful */ 21 | RES_ERROR, /* 1: R/W Error */ 22 | RES_WRPRT, /* 2: Write Protected */ 23 | RES_NOTRDY, /* 3: Not Ready */ 24 | RES_PARERR /* 4: Invalid Parameter */ 25 | } DRESULT; 26 | 27 | 28 | /*---------------------------------------*/ 29 | /* Prototypes for disk control functions */ 30 | 31 | 32 | DSTATUS disk_initialize (BYTE pdrv); 33 | DSTATUS disk_status (BYTE pdrv); 34 | DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); 35 | DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); 36 | DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); 37 | 38 | 39 | /* Disk Status Bits (DSTATUS) */ 40 | 41 | #define STA_NOINIT 0x01 /* Drive not initialized */ 42 | #define STA_NODISK 0x02 /* No medium in the drive */ 43 | #define STA_PROTECT 0x04 /* Write protected */ 44 | 45 | 46 | /* Command code for disk_ioctrl fucntion */ 47 | 48 | /* Generic command (Used by FatFs) */ 49 | #define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */ 50 | #define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */ 51 | #define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */ 52 | #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */ 53 | #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */ 54 | 55 | /* Generic command (Not used by FatFs) */ 56 | #define CTRL_POWER 5 /* Get/Set power status */ 57 | #define CTRL_LOCK 6 /* Lock/Unlock media removal */ 58 | #define CTRL_EJECT 7 /* Eject media */ 59 | #define CTRL_FORMAT 8 /* Create physical format on the media */ 60 | 61 | /* MMC/SDC specific ioctl command */ 62 | #define MMC_GET_TYPE 10 /* Get card type */ 63 | #define MMC_GET_CSD 11 /* Get CSD */ 64 | #define MMC_GET_CID 12 /* Get CID */ 65 | #define MMC_GET_OCR 13 /* Get OCR */ 66 | #define MMC_GET_SDSTAT 14 /* Get SD status */ 67 | #define ISDIO_READ 55 /* Read data form SD iSDIO register */ 68 | #define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ 69 | #define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ 70 | 71 | /* ATA/CF specific ioctl command */ 72 | #define ATA_GET_REV 20 /* Get F/W revision */ 73 | #define ATA_GET_MODEL 21 /* Get model name */ 74 | #define ATA_GET_SN 22 /* Get serial number */ 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /firmware/fatfs/ff.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------/ 2 | / FatFs - Generic FAT file system module R0.12c / 3 | /-----------------------------------------------------------------------------/ 4 | / 5 | / Copyright (C) 2017, ChaN, all right reserved. 6 | / 7 | / FatFs module is an open source software. Redistribution and use of FatFs in 8 | / source and binary forms, with or without modification, are permitted provided 9 | / that the following condition is met: 10 | 11 | / 1. Redistributions of source code must retain the above copyright notice, 12 | / this condition and the following disclaimer. 13 | / 14 | / This software is provided by the copyright holder and contributors "AS IS" 15 | / and any warranties related to this software are DISCLAIMED. 16 | / The copyright owner or contributors be NOT LIABLE for any damages caused 17 | / by use of this software. 18 | /----------------------------------------------------------------------------*/ 19 | 20 | 21 | #ifndef _FATFS 22 | #define _FATFS 68300 /* Revision ID */ 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #include "integer.h" /* Basic integer types */ 29 | #include "ffconf.h" /* FatFs configuration options */ 30 | 31 | #if _FATFS != _FFCONF 32 | #error Wrong configuration file (ffconf.h). 33 | #endif 34 | 35 | 36 | 37 | /* Definitions of volume management */ 38 | 39 | #if _MULTI_PARTITION /* Multiple partition configuration */ 40 | typedef struct { 41 | BYTE pd; /* Physical drive number */ 42 | BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ 43 | } PARTITION; 44 | extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ 45 | #endif 46 | 47 | 48 | 49 | /* Type of path name strings on FatFs API */ 50 | 51 | #if _LFN_UNICODE /* Unicode (UTF-16) string */ 52 | #if _USE_LFN == 0 53 | #error _LFN_UNICODE must be 0 at non-LFN cfg. 54 | #endif 55 | #ifndef _INC_TCHAR 56 | typedef WCHAR TCHAR; 57 | #define _T(x) L ## x 58 | #define _TEXT(x) L ## x 59 | #endif 60 | #else /* ANSI/OEM string */ 61 | #ifndef _INC_TCHAR 62 | typedef char TCHAR; 63 | #define _T(x) x 64 | #define _TEXT(x) x 65 | #endif 66 | #endif 67 | 68 | 69 | 70 | /* Type of file size variables */ 71 | 72 | #if _FS_EXFAT 73 | #if _USE_LFN == 0 74 | #error LFN must be enabled when enable exFAT 75 | #endif 76 | typedef QWORD FSIZE_t; 77 | #else 78 | typedef DWORD FSIZE_t; 79 | #endif 80 | 81 | 82 | 83 | /* File system object structure (FATFS) */ 84 | 85 | typedef struct { 86 | BYTE fs_type; /* File system type (0:N/A) */ 87 | BYTE drv; /* Physical drive number */ 88 | BYTE n_fats; /* Number of FATs (1 or 2) */ 89 | BYTE wflag; /* win[] flag (b0:dirty) */ 90 | BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ 91 | WORD id; /* File system mount ID */ 92 | WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ 93 | WORD csize; /* Cluster size [sectors] */ 94 | #if _MAX_SS != _MIN_SS 95 | WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */ 96 | #endif 97 | #if _USE_LFN != 0 98 | WCHAR* lfnbuf; /* LFN working buffer */ 99 | #endif 100 | #if _FS_EXFAT 101 | BYTE* dirbuf; /* Directory entry block scratchpad buffer */ 102 | #endif 103 | #if _FS_REENTRANT 104 | _SYNC_t sobj; /* Identifier of sync object */ 105 | #endif 106 | #if !_FS_READONLY 107 | DWORD last_clst; /* Last allocated cluster */ 108 | DWORD free_clst; /* Number of free clusters */ 109 | #endif 110 | #if _FS_RPATH != 0 111 | DWORD cdir; /* Current directory start cluster (0:root) */ 112 | #if _FS_EXFAT 113 | DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */ 114 | DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */ 115 | DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */ 116 | #endif 117 | #endif 118 | DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */ 119 | DWORD fsize; /* Size of an FAT [sectors] */ 120 | DWORD volbase; /* Volume base sector */ 121 | DWORD fatbase; /* FAT base sector */ 122 | DWORD dirbase; /* Root directory base sector/cluster */ 123 | DWORD database; /* Data base sector */ 124 | DWORD winsect; /* Current sector appearing in the win[] */ 125 | BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ 126 | } FATFS; 127 | 128 | 129 | 130 | /* Object ID and allocation information (_FDID) */ 131 | 132 | typedef struct { 133 | FATFS* fs; /* Pointer to the owner file system object */ 134 | WORD id; /* Owner file system mount ID */ 135 | BYTE attr; /* Object attribute */ 136 | BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, b2:sub-directory stretched) */ 137 | DWORD sclust; /* Object start cluster (0:no cluster or root directory) */ 138 | FSIZE_t objsize; /* Object size (valid when sclust != 0) */ 139 | #if _FS_EXFAT 140 | DWORD n_cont; /* Size of first fragment, clusters - 1 (valid when stat == 3) */ 141 | DWORD n_frag; /* Size of last fragment needs to be written (valid when not zero) */ 142 | DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */ 143 | DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */ 144 | DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */ 145 | #endif 146 | #if _FS_LOCK != 0 147 | UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ 148 | #endif 149 | } _FDID; 150 | 151 | 152 | 153 | /* File object structure (FIL) */ 154 | 155 | typedef struct { 156 | _FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ 157 | BYTE flag; /* File status flags */ 158 | BYTE err; /* Abort flag (error code) */ 159 | FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ 160 | DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */ 161 | DWORD sect; /* Sector number appearing in buf[] (0:invalid) */ 162 | #if !_FS_READONLY 163 | DWORD dir_sect; /* Sector number containing the directory entry */ 164 | BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */ 165 | #endif 166 | #if _USE_FASTSEEK 167 | DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */ 168 | #endif 169 | #if !_FS_TINY 170 | BYTE buf[_MAX_SS]; /* File private data read/write window */ 171 | #endif 172 | } FIL; 173 | 174 | 175 | 176 | /* Directory object structure (DIR) */ 177 | 178 | typedef struct { 179 | _FDID obj; /* Object identifier */ 180 | DWORD dptr; /* Current read/write offset */ 181 | DWORD clust; /* Current cluster */ 182 | DWORD sect; /* Current sector (0:Read operation has terminated) */ 183 | BYTE* dir; /* Pointer to the directory item in the win[] */ 184 | BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */ 185 | #if _USE_LFN != 0 186 | DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */ 187 | #endif 188 | #if _USE_FIND 189 | const TCHAR* pat; /* Pointer to the name matching pattern */ 190 | #endif 191 | } DIR; 192 | 193 | 194 | 195 | /* File information structure (FILINFO) */ 196 | 197 | typedef struct { 198 | FSIZE_t fsize; /* File size */ 199 | WORD fdate; /* Modified date */ 200 | WORD ftime; /* Modified time */ 201 | BYTE fattrib; /* File attribute */ 202 | #if _USE_LFN != 0 203 | TCHAR altname[13]; /* Altenative file name */ 204 | TCHAR fname[_MAX_LFN + 1]; /* Primary file name */ 205 | #else 206 | TCHAR fname[13]; /* File name */ 207 | #endif 208 | } FILINFO; 209 | 210 | 211 | 212 | /* File function return code (FRESULT) */ 213 | 214 | typedef enum { 215 | FR_OK = 0, /* (0) Succeeded */ 216 | FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ 217 | FR_INT_ERR, /* (2) Assertion failed */ 218 | FR_NOT_READY, /* (3) The physical drive cannot work */ 219 | FR_NO_FILE, /* (4) Could not find the file */ 220 | FR_NO_PATH, /* (5) Could not find the path */ 221 | FR_INVALID_NAME, /* (6) The path name format is invalid */ 222 | FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ 223 | FR_EXIST, /* (8) Access denied due to prohibited access */ 224 | FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ 225 | FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ 226 | FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ 227 | FR_NOT_ENABLED, /* (12) The volume has no work area */ 228 | FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ 229 | FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */ 230 | FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ 231 | FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ 232 | FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ 233 | FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */ 234 | FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ 235 | } FRESULT; 236 | 237 | 238 | 239 | /*--------------------------------------------------------------*/ 240 | /* FatFs module application interface */ 241 | 242 | FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ 243 | FRESULT f_close (FIL* fp); /* Close an open file object */ 244 | FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ 245 | FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ 246 | FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ 247 | FRESULT f_truncate (FIL* fp); /* Truncate the file */ 248 | FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */ 249 | FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ 250 | FRESULT f_closedir (DIR* dp); /* Close an open directory */ 251 | FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ 252 | FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ 253 | FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */ 254 | FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ 255 | FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ 256 | FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ 257 | FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ 258 | FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */ 259 | FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */ 260 | FRESULT f_chdir (const TCHAR* path); /* Change current directory */ 261 | FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ 262 | FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ 263 | FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ 264 | FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ 265 | FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ 266 | FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ 267 | FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */ 268 | FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ 269 | FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ 270 | FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ 271 | int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ 272 | int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ 273 | int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ 274 | TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ 275 | 276 | #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) 277 | #define f_error(fp) ((fp)->err) 278 | #define f_tell(fp) ((fp)->fptr) 279 | #define f_size(fp) ((fp)->obj.objsize) 280 | #define f_rewind(fp) f_lseek((fp), 0) 281 | #define f_rewinddir(dp) f_readdir((dp), 0) 282 | #define f_rmdir(path) f_unlink(path) 283 | 284 | #ifndef EOF 285 | #define EOF (-1) 286 | #endif 287 | 288 | 289 | 290 | 291 | /*--------------------------------------------------------------*/ 292 | /* Additional user defined functions */ 293 | 294 | /* RTC function */ 295 | #if !_FS_READONLY && !_FS_NORTC 296 | DWORD get_fattime (void); 297 | #endif 298 | 299 | /* Unicode support functions */ 300 | #if _USE_LFN != 0 /* Unicode - OEM code conversion */ 301 | WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */ 302 | WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */ 303 | #if _USE_LFN == 3 /* Memory functions */ 304 | void* ff_memalloc (UINT msize); /* Allocate memory block */ 305 | void ff_memfree (void* mblock); /* Free memory block */ 306 | #endif 307 | #endif 308 | 309 | /* Sync functions */ 310 | #if _FS_REENTRANT 311 | int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */ 312 | int ff_req_grant (_SYNC_t sobj); /* Lock sync object */ 313 | void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */ 314 | int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */ 315 | #endif 316 | 317 | 318 | 319 | 320 | /*--------------------------------------------------------------*/ 321 | /* Flags and offset address */ 322 | 323 | 324 | /* File access mode and open method flags (3rd argument of f_open) */ 325 | #define FA_READ 0x01 326 | #define FA_WRITE 0x02 327 | #define FA_OPEN_EXISTING 0x00 328 | #define FA_CREATE_NEW 0x04 329 | #define FA_CREATE_ALWAYS 0x08 330 | #define FA_OPEN_ALWAYS 0x10 331 | #define FA_OPEN_APPEND 0x30 332 | 333 | /* Fast seek controls (2nd argument of f_lseek) */ 334 | #define CREATE_LINKMAP ((FSIZE_t)0 - 1) 335 | 336 | /* Format options (2nd argument of f_mkfs) */ 337 | #define FM_FAT 0x01 338 | #define FM_FAT32 0x02 339 | #define FM_EXFAT 0x04 340 | #define FM_ANY 0x07 341 | #define FM_SFD 0x08 342 | 343 | /* Filesystem type (FATFS.fs_type) */ 344 | #define FS_FAT12 1 345 | #define FS_FAT16 2 346 | #define FS_FAT32 3 347 | #define FS_EXFAT 4 348 | 349 | /* File attribute bits for directory entry (FILINFO.fattrib) */ 350 | #define AM_RDO 0x01 /* Read only */ 351 | #define AM_HID 0x02 /* Hidden */ 352 | #define AM_SYS 0x04 /* System */ 353 | #define AM_DIR 0x10 /* Directory */ 354 | #define AM_ARC 0x20 /* Archive */ 355 | 356 | 357 | #ifdef __cplusplus 358 | } 359 | #endif 360 | 361 | #endif /* _FATFS */ 362 | -------------------------------------------------------------------------------- /firmware/fatfs/ffconf.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------/ 2 | / FatFs - FAT file system module configuration file 3 | /---------------------------------------------------------------------------*/ 4 | 5 | #define _FFCONF 68300 /* Revision ID */ 6 | 7 | /*---------------------------------------------------------------------------/ 8 | / Function Configurations 9 | /---------------------------------------------------------------------------*/ 10 | 11 | #define _FS_READONLY 0 12 | /* This option switches read-only configuration. (0:Read/Write or 1:Read-only) 13 | / Read-only configuration removes writing API functions, f_write(), f_sync(), 14 | / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() 15 | / and optional writing functions as well. */ 16 | 17 | 18 | #define _FS_MINIMIZE 0 19 | /* This option defines minimization level to remove some basic API functions. 20 | / 21 | / 0: All basic functions are enabled. 22 | / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() 23 | / are removed. 24 | / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. 25 | / 3: f_lseek() function is removed in addition to 2. */ 26 | 27 | 28 | #define _USE_STRFUNC 0 29 | /* This option switches string functions, f_gets(), f_putc(), f_puts() and 30 | / f_printf(). 31 | / 32 | / 0: Disable string functions. 33 | / 1: Enable without LF-CRLF conversion. 34 | / 2: Enable with LF-CRLF conversion. */ 35 | 36 | 37 | #define _USE_FIND 0 38 | /* This option switches filtered directory read functions, f_findfirst() and 39 | / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ 40 | 41 | 42 | #define _USE_MKFS 0 43 | /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ 44 | 45 | 46 | #define _USE_FASTSEEK 0 47 | /* This option switches fast seek function. (0:Disable or 1:Enable) */ 48 | 49 | 50 | #define _USE_EXPAND 0 51 | /* This option switches f_expand function. (0:Disable or 1:Enable) */ 52 | 53 | 54 | #define _USE_CHMOD 0 55 | /* This option switches attribute manipulation functions, f_chmod() and f_utime(). 56 | / (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */ 57 | 58 | 59 | #define _USE_LABEL 0 60 | /* This option switches volume label functions, f_getlabel() and f_setlabel(). 61 | / (0:Disable or 1:Enable) */ 62 | 63 | 64 | #define _USE_FORWARD 0 65 | /* This option switches f_forward() function. (0:Disable or 1:Enable) */ 66 | 67 | 68 | /*---------------------------------------------------------------------------/ 69 | / Locale and Namespace Configurations 70 | /---------------------------------------------------------------------------*/ 71 | 72 | #define _CODE_PAGE 932 73 | /* This option specifies the OEM code page to be used on the target system. 74 | / Incorrect setting of the code page can cause a file open failure. 75 | / 76 | / 1 - ASCII (No support of extended character. Non-LFN cfg. only) 77 | / 437 - U.S. 78 | / 720 - Arabic 79 | / 737 - Greek 80 | / 771 - KBL 81 | / 775 - Baltic 82 | / 850 - Latin 1 83 | / 852 - Latin 2 84 | / 855 - Cyrillic 85 | / 857 - Turkish 86 | / 860 - Portuguese 87 | / 861 - Icelandic 88 | / 862 - Hebrew 89 | / 863 - Canadian French 90 | / 864 - Arabic 91 | / 865 - Nordic 92 | / 866 - Russian 93 | / 869 - Greek 2 94 | / 932 - Japanese (DBCS) 95 | / 936 - Simplified Chinese (DBCS) 96 | / 949 - Korean (DBCS) 97 | / 950 - Traditional Chinese (DBCS) 98 | */ 99 | 100 | 101 | #define _USE_LFN 0 102 | #define _MAX_LFN 255 103 | /* The _USE_LFN switches the support of long file name (LFN). 104 | / 105 | / 0: Disable support of LFN. _MAX_LFN has no effect. 106 | / 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. 107 | / 2: Enable LFN with dynamic working buffer on the STACK. 108 | / 3: Enable LFN with dynamic working buffer on the HEAP. 109 | / 110 | / To enable the LFN, Unicode handling functions (option/unicode.c) must be added 111 | / to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and 112 | / additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255. 113 | / It should be set 255 to support full featured LFN operations. 114 | / When use stack for the working buffer, take care on stack overflow. When use heap 115 | / memory for the working buffer, memory management functions, ff_memalloc() and 116 | / ff_memfree(), must be added to the project. */ 117 | 118 | 119 | #define _LFN_UNICODE 0 120 | /* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16) 121 | / To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1. 122 | / This option also affects behavior of string I/O functions. */ 123 | 124 | 125 | #define _STRF_ENCODE 3 126 | /* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to 127 | / be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf(). 128 | / 129 | / 0: ANSI/OEM 130 | / 1: UTF-16LE 131 | / 2: UTF-16BE 132 | / 3: UTF-8 133 | / 134 | / This option has no effect when _LFN_UNICODE == 0. */ 135 | 136 | 137 | #define _FS_RPATH 0 138 | /* This option configures support of relative path. 139 | / 140 | / 0: Disable relative path and remove related functions. 141 | / 1: Enable relative path. f_chdir() and f_chdrive() are available. 142 | / 2: f_getcwd() function is available in addition to 1. 143 | */ 144 | 145 | 146 | /*---------------------------------------------------------------------------/ 147 | / Drive/Volume Configurations 148 | /---------------------------------------------------------------------------*/ 149 | 150 | #define _VOLUMES 1 151 | /* Number of volumes (logical drives) to be used. (1-10) */ 152 | 153 | 154 | #define _STR_VOLUME_ID 0 155 | #define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" 156 | /* _STR_VOLUME_ID switches string support of volume ID. 157 | / When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive 158 | / number in the path name. _VOLUME_STRS defines the drive ID strings for each 159 | / logical drives. Number of items must be equal to _VOLUMES. Valid characters for 160 | / the drive ID strings are: A-Z and 0-9. */ 161 | 162 | 163 | #define _MULTI_PARTITION 0 164 | /* This option switches support of multi-partition on a physical drive. 165 | / By default (0), each logical drive number is bound to the same physical drive 166 | / number and only an FAT volume found on the physical drive will be mounted. 167 | / When multi-partition is enabled (1), each logical drive number can be bound to 168 | / arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() 169 | / funciton will be available. */ 170 | 171 | 172 | #define _MIN_SS 512 173 | #define _MAX_SS 512 174 | /* These options configure the range of sector size to be supported. (512, 1024, 175 | / 2048 or 4096) Always set both 512 for most systems, generic memory card and 176 | / harddisk. But a larger value may be required for on-board flash memory and some 177 | / type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured 178 | / to variable sector size and GET_SECTOR_SIZE command needs to be implemented to 179 | / the disk_ioctl() function. */ 180 | 181 | 182 | #define _USE_TRIM 0 183 | /* This option switches support of ATA-TRIM. (0:Disable or 1:Enable) 184 | / To enable Trim function, also CTRL_TRIM command should be implemented to the 185 | / disk_ioctl() function. */ 186 | 187 | 188 | #define _FS_NOFSINFO 0 189 | /* If you need to know correct free space on the FAT32 volume, set bit 0 of this 190 | / option, and f_getfree() function at first time after volume mount will force 191 | / a full FAT scan. Bit 1 controls the use of last allocated cluster number. 192 | / 193 | / bit0=0: Use free cluster count in the FSINFO if available. 194 | / bit0=1: Do not trust free cluster count in the FSINFO. 195 | / bit1=0: Use last allocated cluster number in the FSINFO if available. 196 | / bit1=1: Do not trust last allocated cluster number in the FSINFO. 197 | */ 198 | 199 | 200 | 201 | /*---------------------------------------------------------------------------/ 202 | / System Configurations 203 | /---------------------------------------------------------------------------*/ 204 | 205 | #define _FS_TINY 0 206 | /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) 207 | / At the tiny configuration, size of file object (FIL) is shrinked _MAX_SS bytes. 208 | / Instead of private sector buffer eliminated from the file object, common sector 209 | / buffer in the file system object (FATFS) is used for the file data transfer. */ 210 | 211 | 212 | #define _FS_EXFAT 0 213 | /* This option switches support of exFAT file system. (0:Disable or 1:Enable) 214 | / When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1) 215 | / Note that enabling exFAT discards ANSI C (C89) compatibility. */ 216 | 217 | 218 | #define _FS_NORTC 1 219 | #define _NORTC_MON 1 220 | #define _NORTC_MDAY 1 221 | #define _NORTC_YEAR 2016 222 | /* The option _FS_NORTC switches timestamp functiton. If the system does not have 223 | / any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable 224 | / the timestamp function. All objects modified by FatFs will have a fixed timestamp 225 | / defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time. 226 | / To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be 227 | / added to the project to get current time form real-time clock. _NORTC_MON, 228 | / _NORTC_MDAY and _NORTC_YEAR have no effect. 229 | / These options have no effect at read-only configuration (_FS_READONLY = 1). */ 230 | 231 | 232 | #define _FS_LOCK 0 233 | /* The option _FS_LOCK switches file lock function to control duplicated file open 234 | / and illegal operation to open objects. This option must be 0 when _FS_READONLY 235 | / is 1. 236 | / 237 | / 0: Disable file lock function. To avoid volume corruption, application program 238 | / should avoid illegal open, remove and rename to the open objects. 239 | / >0: Enable file lock function. The value defines how many files/sub-directories 240 | / can be opened simultaneously under file lock control. Note that the file 241 | / lock control is independent of re-entrancy. */ 242 | 243 | 244 | #define _FS_REENTRANT 0 245 | #define _FS_TIMEOUT 1000 246 | #define _SYNC_t HANDLE 247 | /* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs 248 | / module itself. Note that regardless of this option, file access to different 249 | / volume is always re-entrant and volume control functions, f_mount(), f_mkfs() 250 | / and f_fdisk() function, are always not re-entrant. Only file/directory access 251 | / to the same volume is under control of this function. 252 | / 253 | / 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. 254 | / 1: Enable re-entrancy. Also user provided synchronization handlers, 255 | / ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() 256 | / function, must be added to the project. Samples are available in 257 | / option/syscall.c. 258 | / 259 | / The _FS_TIMEOUT defines timeout period in unit of time tick. 260 | / The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, 261 | / SemaphoreHandle_t and etc. A header file for O/S definitions needs to be 262 | / included somewhere in the scope of ff.h. */ 263 | 264 | /* #include // O/S definitions */ 265 | 266 | 267 | 268 | /*--- End of configuration options ---*/ 269 | -------------------------------------------------------------------------------- /firmware/fatfs/integer.h: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------*/ 2 | /* Integer type definitions for FatFs module */ 3 | /*-------------------------------------------*/ 4 | 5 | #ifndef _FF_INTEGER 6 | #define _FF_INTEGER 7 | 8 | #ifdef _WIN32 /* FatFs development platform */ 9 | 10 | #include 11 | #include 12 | typedef unsigned __int64 QWORD; 13 | 14 | 15 | #else /* Embedded platform */ 16 | 17 | /* These types MUST be 16-bit or 32-bit */ 18 | typedef int INT; 19 | typedef unsigned int UINT; 20 | 21 | /* This type MUST be 8-bit */ 22 | typedef unsigned char BYTE; 23 | 24 | /* These types MUST be 16-bit */ 25 | typedef short SHORT; 26 | typedef unsigned short WORD; 27 | typedef unsigned short WCHAR; 28 | 29 | /* These types MUST be 32-bit */ 30 | typedef long LONG; 31 | typedef unsigned long DWORD; 32 | 33 | /* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */ 34 | typedef unsigned long long QWORD; 35 | 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /firmware/fatfs/option/syscall.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------*/ 2 | /* Sample code of OS dependent controls for FatFs */ 3 | /* (C)ChaN, 2014 */ 4 | /*------------------------------------------------------------------------*/ 5 | 6 | 7 | #include "../ff.h" 8 | 9 | 10 | #if _FS_REENTRANT 11 | /*------------------------------------------------------------------------*/ 12 | /* Create a Synchronization Object 13 | /*------------------------------------------------------------------------*/ 14 | /* This function is called in f_mount() function to create a new 15 | / synchronization object, such as semaphore and mutex. When a 0 is returned, 16 | / the f_mount() function fails with FR_INT_ERR. 17 | */ 18 | 19 | int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */ 20 | BYTE vol, /* Corresponding volume (logical drive number) */ 21 | _SYNC_t *sobj /* Pointer to return the created sync object */ 22 | ) 23 | { 24 | int ret; 25 | 26 | 27 | *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */ 28 | ret = (int)(*sobj != INVALID_HANDLE_VALUE); 29 | 30 | // *sobj = SyncObjects[vol]; /* uITRON (give a static sync object) */ 31 | // ret = 1; /* The initial value of the semaphore must be 1. */ 32 | 33 | // *sobj = OSMutexCreate(0, &err); /* uC/OS-II */ 34 | // ret = (int)(err == OS_NO_ERR); 35 | 36 | // *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */ 37 | // ret = (int)(*sobj != NULL); 38 | 39 | return ret; 40 | } 41 | 42 | 43 | 44 | /*------------------------------------------------------------------------*/ 45 | /* Delete a Synchronization Object */ 46 | /*------------------------------------------------------------------------*/ 47 | /* This function is called in f_mount() function to delete a synchronization 48 | / object that created with ff_cre_syncobj() function. When a 0 is returned, 49 | / the f_mount() function fails with FR_INT_ERR. 50 | */ 51 | 52 | int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to any error */ 53 | _SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ 54 | ) 55 | { 56 | int ret; 57 | 58 | 59 | ret = CloseHandle(sobj); /* Win32 */ 60 | 61 | // ret = 1; /* uITRON (nothing to do) */ 62 | 63 | // OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */ 64 | // ret = (int)(err == OS_NO_ERR); 65 | 66 | // vSemaphoreDelete(sobj); /* FreeRTOS */ 67 | // ret = 1; 68 | 69 | return ret; 70 | } 71 | 72 | 73 | 74 | /*------------------------------------------------------------------------*/ 75 | /* Request Grant to Access the Volume */ 76 | /*------------------------------------------------------------------------*/ 77 | /* This function is called on entering file functions to lock the volume. 78 | / When a 0 is returned, the file function fails with FR_TIMEOUT. 79 | */ 80 | 81 | int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */ 82 | _SYNC_t sobj /* Sync object to wait */ 83 | ) 84 | { 85 | int ret; 86 | 87 | ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */ 88 | 89 | // ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */ 90 | 91 | // OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */ 92 | // ret = (int)(err == OS_NO_ERR); 93 | 94 | // ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */ 95 | 96 | return ret; 97 | } 98 | 99 | 100 | 101 | /*------------------------------------------------------------------------*/ 102 | /* Release Grant to Access the Volume */ 103 | /*------------------------------------------------------------------------*/ 104 | /* This function is called on leaving file functions to unlock the volume. 105 | */ 106 | 107 | void ff_rel_grant ( 108 | _SYNC_t sobj /* Sync object to be signaled */ 109 | ) 110 | { 111 | ReleaseMutex(sobj); /* Win32 */ 112 | 113 | // sig_sem(sobj); /* uITRON */ 114 | 115 | // OSMutexPost(sobj); /* uC/OS-II */ 116 | 117 | // xSemaphoreGive(sobj); /* FreeRTOS */ 118 | } 119 | 120 | #endif 121 | 122 | 123 | 124 | 125 | #if _USE_LFN == 3 /* LFN with a working buffer on the heap */ 126 | /*------------------------------------------------------------------------*/ 127 | /* Allocate a memory block */ 128 | /*------------------------------------------------------------------------*/ 129 | /* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE. 130 | */ 131 | 132 | void* ff_memalloc ( /* Returns pointer to the allocated memory block */ 133 | UINT msize /* Number of bytes to allocate */ 134 | ) 135 | { 136 | return malloc(msize); /* Allocate a new memory block with POSIX API */ 137 | } 138 | 139 | 140 | /*------------------------------------------------------------------------*/ 141 | /* Free a memory block */ 142 | /*------------------------------------------------------------------------*/ 143 | 144 | void ff_memfree ( 145 | void* mblock /* Pointer to the memory block to free */ 146 | ) 147 | { 148 | free(mblock); /* Discard the memory block with POSIX API */ 149 | } 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /firmware/fatfs/option/unicode.c: -------------------------------------------------------------------------------- 1 | #include "../ff.h" 2 | 3 | #if _USE_LFN != 0 4 | 5 | #if _CODE_PAGE == 932 /* Japanese Shift_JIS */ 6 | #include "cc932.c" 7 | #elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ 8 | #include "cc936.c" 9 | #elif _CODE_PAGE == 949 /* Korean */ 10 | #include "cc949.c" 11 | #elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ 12 | #include "cc950.c" 13 | #else /* Single Byte Character-Set */ 14 | #include "ccsbcs.c" 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /firmware/flash.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY 4 | { 5 | FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K 6 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 6K 7 | } 8 | _estack = ORIGIN(RAM) + LENGTH(RAM); 9 | 10 | SECTIONS { 11 | /* Interrupt vector table at the beginning of flash */ 12 | .isr_vector ORIGIN(FLASH) : { 13 | KEEP(*(.isr_vector)) 14 | . = ALIGN(4); 15 | } >FLASH 16 | /* Then the text section goes into flash */ 17 | .text : { 18 | . = ALIGN(4); 19 | *(.text) 20 | *(.text*) 21 | *(.rodata) 22 | *(.rodata*) 23 | . = ALIGN(4); 24 | } >FLASH 25 | /* The data section gets a VMA in RAM but an LMA in flash */ 26 | _sidata = .; 27 | .data : AT ( _sidata ) { 28 | . = ALIGN(4); 29 | _sdata = .; 30 | *(.data) 31 | *(.data*) 32 | . = ALIGN(4); 33 | _edata = .; 34 | } >RAM 35 | /* The BSS goes into RAM */ 36 | .bss : { 37 | . = ALIGN(4); 38 | _sbss = .; 39 | *(.bss) 40 | *(.bss*) 41 | *(COMMON) 42 | . = ALIGN(4); 43 | _ebss = .; 44 | } >RAM 45 | } 46 | -------------------------------------------------------------------------------- /firmware/hal.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_H 2 | #define __HAL_H 3 | 4 | #include 5 | 6 | #define SD_TIMEOUT 0xFFF 7 | 8 | void init(); 9 | 10 | void led_read_off(); 11 | void led_read_on(); 12 | void led_write_off(); 13 | void led_write_on(); 14 | void led_spoof_off(); 15 | void led_spoof_on(); 16 | 17 | int button(); 18 | 19 | void coil_drive(); 20 | void coil_float(); 21 | void coil_tune(); 22 | void coil_detune(); 23 | 24 | void stream_read_enable(); 25 | void stream_read_disable(); 26 | void stream_write_enable(); 27 | void stream_write_disable(); 28 | int stream_read_available(); 29 | void stream_read(int16_t* hws, int n); 30 | int stream_write_space(); 31 | void stream_write(int8_t* bytes, int n); 32 | void stream_write_byte(int8_t byte); 33 | 34 | void set_latency(int16_t l); 35 | 36 | extern volatile int stream_read_enabled; 37 | extern volatile int stream_write_enabled; 38 | 39 | extern volatile int led_timer; 40 | extern volatile int button_timer; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /firmware/led.c: -------------------------------------------------------------------------------- 1 | #include "led.h" 2 | #include "hal.h" 3 | 4 | #define RAPID_BLINK_TIME 50 5 | #define SLOW_BLINK_TIME 400 6 | 7 | static enum which_led current_led; 8 | static enum { 9 | LED_SOLID, 10 | LED_RAPID_BLINK, 11 | LED_SLOW_BLINK, 12 | } state; 13 | 14 | static int lit; 15 | 16 | void led_set_current(enum which_led which) { 17 | current_led = which; 18 | state = LED_SOLID; 19 | } 20 | 21 | static void set_led(int state) { 22 | lit = state; 23 | switch(current_led) { 24 | case LED_READ: 25 | if(state) led_read_on(); else led_read_off(); 26 | break; 27 | case LED_WRITE: 28 | if(state) led_write_on(); else led_write_off(); 29 | break; 30 | case LED_SPOOF: 31 | if(state) led_spoof_on(); else led_spoof_off(); 32 | break; 33 | } 34 | } 35 | 36 | void led_event(enum led_event event) { 37 | switch(event) { 38 | case LED_EVENT_ON: 39 | set_led(1); 40 | state = LED_SOLID; 41 | break; 42 | case LED_EVENT_OFF: 43 | set_led(0); 44 | state = LED_SOLID; 45 | break; 46 | case LED_EVENT_RAPID_BLINK: 47 | if(state != LED_RAPID_BLINK) { 48 | set_led(0); 49 | led_timer = RAPID_BLINK_TIME; 50 | state = LED_RAPID_BLINK; 51 | } 52 | break; 53 | case LED_EVENT_SLOW_BLINK: 54 | if(state != LED_SLOW_BLINK) { 55 | set_led(0); 56 | led_timer = SLOW_BLINK_TIME; 57 | state = LED_SLOW_BLINK; 58 | } 59 | break; 60 | } 61 | } 62 | 63 | void led() { 64 | switch(state) { 65 | case LED_SOLID: 66 | break; 67 | case LED_RAPID_BLINK: 68 | if(led_timer == 0) { 69 | set_led(!lit); 70 | led_timer = RAPID_BLINK_TIME; 71 | } 72 | break; 73 | case LED_SLOW_BLINK: 74 | if(led_timer == 0) { 75 | set_led(!lit); 76 | led_timer = SLOW_BLINK_TIME; 77 | } 78 | break; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /firmware/led.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum led_event { 4 | LED_EVENT_ON, 5 | LED_EVENT_OFF, 6 | LED_EVENT_RAPID_BLINK, 7 | LED_EVENT_SLOW_BLINK, 8 | }; 9 | 10 | enum which_led { 11 | LED_READ, 12 | LED_WRITE, 13 | LED_SPOOF, 14 | }; 15 | 16 | void led(); 17 | void led_set_current(enum which_led which); 18 | void led_event(enum led_event event); 19 | -------------------------------------------------------------------------------- /firmware/main.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "hal.h" 3 | #include "button.h" 4 | #include "led.h" 5 | #include "protocol.h" 6 | #include "sd.h" 7 | 8 | enum state state = STATE_REMOTE; 9 | 10 | int main() { 11 | init(); 12 | 13 | //sd_startup(); 14 | //sd_write_f(); 15 | 16 | protocol_change(&protocol_fns[0]); 17 | transition(STATE_READ); 18 | for(;;) { 19 | enum button_event button_ev = button_event(); 20 | led(); 21 | switch(state) { 22 | case STATE_READ: 23 | protocol->read(); 24 | if(button_ev == BUTTON_EVENT_PRESS) transition(STATE_WRITE); 25 | else if(button_ev == BUTTON_EVENT_LONG_PRESS) protocol->trigger_read(); 26 | break; 27 | case STATE_WRITE: 28 | protocol->write(); 29 | if(button_ev == BUTTON_EVENT_PRESS) transition(STATE_SPOOF); 30 | else if(button_ev == BUTTON_EVENT_LONG_PRESS) protocol->trigger_write(); 31 | break; 32 | case STATE_SPOOF: 33 | protocol->spoof(); 34 | if(button_ev == BUTTON_EVENT_PRESS) transition(STATE_READ); 35 | else if(button_ev == BUTTON_EVENT_LONG_PRESS) protocol->trigger_spoof(); 36 | break; 37 | case STATE_REMOTE: 38 | if(button_ev == BUTTON_EVENT_PRESS) transition(STATE_READ); 39 | break; 40 | } 41 | } 42 | } 43 | 44 | void transition(enum state new_state) { 45 | if(new_state == state) return; 46 | 47 | switch(state) { 48 | case STATE_READ: 49 | protocol->exit_read(); 50 | break; 51 | case STATE_WRITE: 52 | protocol->exit_write(); 53 | break; 54 | case STATE_SPOOF: 55 | protocol->exit_spoof(); 56 | break; 57 | case STATE_REMOTE: 58 | break; 59 | } 60 | 61 | state = new_state; 62 | switch(new_state) { 63 | case STATE_READ: 64 | stream_write_disable(); 65 | stream_read_disable(); 66 | stream_read_enable(); 67 | coil_drive(); 68 | led_write_off(); 69 | led_spoof_off(); 70 | led_set_current(LED_READ); 71 | led_event(LED_EVENT_ON); 72 | protocol->enter_read(); 73 | break; 74 | case STATE_WRITE: 75 | stream_write_disable(); 76 | stream_read_disable(); 77 | coil_drive(); 78 | stream_write_enable(); 79 | led_read_off(); 80 | led_spoof_off(); 81 | led_set_current(LED_WRITE); 82 | led_event(LED_EVENT_ON); 83 | protocol->enter_write(); 84 | break; 85 | case STATE_SPOOF: 86 | stream_write_disable(); 87 | stream_read_disable(); 88 | coil_float(); 89 | coil_tune(); 90 | led_read_off(); 91 | led_write_off(); 92 | led_set_current(LED_SPOOF); 93 | led_event(LED_EVENT_ON); 94 | protocol->enter_spoof(); 95 | break; 96 | case STATE_REMOTE: 97 | stream_write_disable(); 98 | stream_read_disable(); 99 | coil_float(); 100 | coil_tune(); 101 | led_read_off(); 102 | led_write_off(); 103 | led_spoof_off(); 104 | led_event(LED_EVENT_OFF); 105 | break; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /firmware/main.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum state { 4 | STATE_READ, 5 | STATE_WRITE, 6 | STATE_SPOOF, 7 | STATE_REMOTE, 8 | }; 9 | 10 | extern enum state state; 11 | 12 | void transition(enum state new_state); 13 | -------------------------------------------------------------------------------- /firmware/protocol.c: -------------------------------------------------------------------------------- 1 | #include "protocol.h" 2 | 3 | const struct protocol_fns protocol_fns[] = { 4 | { 5 | .name = PROTOCOL_PSK_NAME, 6 | .version = PROTOCOL_PSK_VERSION, 7 | 8 | .init = protocol_psk_init, 9 | 10 | .read = protocol_psk_read, 11 | .write = protocol_psk_write, 12 | .spoof = protocol_psk_spoof, 13 | 14 | .enter_read = protocol_psk_enter_read, 15 | .enter_write = protocol_psk_enter_write, 16 | .enter_spoof = protocol_psk_enter_spoof, 17 | 18 | .exit_read = protocol_psk_exit_read, 19 | .exit_write = protocol_psk_exit_write, 20 | .exit_spoof = protocol_psk_exit_spoof, 21 | 22 | .trigger_read = protocol_psk_trigger_read, 23 | .trigger_write = protocol_psk_trigger_write, 24 | .trigger_spoof = protocol_psk_trigger_spoof, 25 | } 26 | }; 27 | 28 | union protocol_state protocol_state; 29 | union protocol_params protocol_params; 30 | 31 | const struct protocol_fns *protocol; 32 | 33 | void protocol_change(const struct protocol_fns *new_protocol) { 34 | protocol = new_protocol; 35 | protocol->init(); 36 | } 37 | -------------------------------------------------------------------------------- /firmware/protocol.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "psk.h" 4 | 5 | extern const struct protocol_fns { 6 | const char *name; 7 | const uint32_t version; 8 | 9 | void (*init)(); 10 | void (*read)(); 11 | void (*write)(); 12 | void (*spoof)(); 13 | 14 | void (*enter_read)(); 15 | void (*enter_write)(); 16 | void (*enter_spoof)(); 17 | 18 | void (*exit_read)(); 19 | void (*exit_write)(); 20 | void (*exit_spoof)(); 21 | 22 | void (*trigger_read)(); 23 | void (*trigger_write)(); 24 | void (*trigger_spoof)(); 25 | } protocol_fns[]; 26 | 27 | extern union protocol_state { 28 | struct protocol_psk_state psk; 29 | } protocol_state; 30 | 31 | extern union protocol_params { 32 | struct protocol_psk_params psk; 33 | } protocol_params; 34 | 35 | extern const struct protocol_fns *protocol; 36 | 37 | void protocol_change(const struct protocol_fns *new_protocol); 38 | -------------------------------------------------------------------------------- /firmware/protocols/psk.c: -------------------------------------------------------------------------------- 1 | #include "psk.h" 2 | #include "protocol.h" 3 | #include "hal.h" 4 | #include 5 | #include "led.h" 6 | 7 | // READ 8 | 9 | // Returns - if o1 < o2 10 | // Returns + in o1 > o2 11 | // Returns 0 in o1 = o2 12 | 13 | static int cmp(int o1, int o2) { 14 | int o1bytes = o1 / 8; 15 | int o2bytes = o2 / 8; 16 | int o1bits = 8 - (o1 & 7); 17 | int o2bits = 8 - (o2 & 7); 18 | int cycle_length_bytes = (protocol_params.psk.cycle_length + 7) / 8; 19 | for(int i=0; i> o1bits) & 0xFF) - ((protocol_state.psk.decoder.cyclotron[o2bytes] >> o2bits) & 0xFF); 21 | if(c != 0) return c; 22 | o1bytes++; 23 | if(o1bytes == cycle_length_bytes) o1bytes = 0; 24 | o2bytes++; 25 | if(o2bytes == cycle_length_bytes) o2bytes = 0; 26 | } 27 | return 0; 28 | } 29 | 30 | // Returns - if ~o1 < o2 31 | // Returns + in ~o1 > o2 32 | // Returns 0 in ~o1 = o2 33 | 34 | static int cmp_inv(int o1, int o2) { 35 | int o1bytes = o1 / 8; 36 | int o2bytes = o2 / 8; 37 | int o1bits = 8 - (o1 & 7); 38 | int o2bits = 8 - (o2 & 7); 39 | int cycle_length_bytes = (protocol_params.psk.cycle_length + 7) / 8; 40 | for(int i=0; i> o1bits) & 0xFF) - ((protocol_state.psk.decoder.cyclotron[o2bytes] >> o2bits) & 0xFF); 42 | if(c != 0) return c; 43 | o1bytes++; 44 | if(o1bytes == cycle_length_bytes) o1bytes = 0; 45 | o2bytes++; 46 | if(o2bytes == cycle_length_bytes) o2bytes = 0; 47 | } 48 | return 0; 49 | } 50 | 51 | static void valid_read() { 52 | int max_so_far = 0; 53 | int min_so_far = 0; 54 | memset(protocol_state.psk.decoder.cyclotron, 0, sizeof(protocol_state.psk.decoder.cyclotron)); 55 | memset(protocol_state.psk.card_data, 0, sizeof(protocol_state.psk.card_data)); 56 | 57 | // Set up the cyclotron bit supercollider 58 | for(int i=0; i= protocol_params.psk.cycle_length) bit -= protocol_params.psk.cycle_length; 62 | protocol_state.psk.decoder.cyclotron[i] |= (uint16_t)protocol_state.psk.decoder.bits[bit] << (15 - j); 63 | } 64 | } 65 | 66 | for(int i=0; i> 8; 68 | } 69 | protocol_state.psk.decoder.cyclotron[sizeof(protocol_state.psk.decoder.cyclotron) / sizeof(uint16_t) - 1] |= protocol_state.psk.decoder.cyclotron[0] >> 8; 70 | 71 | for(int i=1; i 0) max_so_far = i; 73 | else if(cmp(i, min_so_far) < 0) min_so_far = i; 74 | } 75 | 76 | int cycle_length_bytes = (protocol_params.psk.cycle_length + 7) / 8; 77 | 78 | if(cmp_inv(max_so_far, min_so_far) < 0) { 79 | // Inverted max is smaller than min 80 | min_so_far = max_so_far; 81 | for(int i=0; i> obits) & 0xFF; 90 | obytes++; 91 | if(obytes == cycle_length_bytes) obytes = 0; 92 | } 93 | } 94 | 95 | static void read_new_bit(int8_t bit) { 96 | if(protocol_state.psk.decoder.bits[protocol_state.psk.decoder.bits_ptr] != bit) { 97 | protocol_state.psk.decoder.bits[protocol_state.psk.decoder.bits_ptr] = bit; 98 | if(protocol_state.psk.cycle.counter < 0) led_event(LED_EVENT_ON); 99 | protocol_state.psk.cycle.counter = 0; 100 | } 101 | if(protocol_state.psk.cycle.counter >= 0) { 102 | protocol_state.psk.cycle.counter++; 103 | if(protocol_state.psk.cycle.counter >= protocol_params.psk.cycle_length * protocol_params.psk.repeats_until_valid) { 104 | valid_read(); 105 | led_event(LED_EVENT_RAPID_BLINK); 106 | protocol_state.psk.cycle.counter = -1; 107 | } 108 | } 109 | protocol_state.psk.decoder.bits_ptr++; 110 | if(protocol_state.psk.decoder.bits_ptr >= protocol_params.psk.cycle_length) { 111 | protocol_state.psk.decoder.bits_ptr -= protocol_params.psk.cycle_length; 112 | } 113 | } 114 | 115 | void protocol_psk_init() { 116 | memset(&protocol_state.psk, 0, sizeof(protocol_state.psk)); 117 | memset(&protocol_params.psk, 0, sizeof(protocol_params.psk)); 118 | protocol_params.psk.hpf_alpha = 0.95 * 65536; 119 | protocol_params.psk.lpf_alpha = 0.10 * 65536; 120 | protocol_params.psk.bit_width = 32; 121 | protocol_params.psk.cycle_length = 224; 122 | protocol_params.psk.repeats_until_valid = 3; 123 | 124 | protocol_params.psk.write_poweron_time = 1875; 125 | protocol_params.psk.write_programming_time = 1875; 126 | protocol_params.psk.write_one = 56; 127 | protocol_params.psk.write_zero = 24; 128 | protocol_params.psk.write_start_gap = 15; 129 | protocol_params.psk.write_gap = 10; 130 | } 131 | 132 | void protocol_psk_read() { 133 | int available = stream_read_available(); 134 | if(available == 0) return; 135 | if(available > sizeof(protocol_state.psk.read_buffer) / sizeof(int16_t)) available = sizeof(protocol_state.psk.read_buffer) / sizeof(int16_t); 136 | stream_read(protocol_state.psk.read_buffer, available); 137 | 138 | for(int i=0; i> 16; 142 | protocol_state.psk.hpf.prev_x = sample; 143 | protocol_state.psk.hpf.prev_y = hpf_sample; 144 | 145 | // Simplex demodulation using a RF/2 carrier 146 | int32_t demod_sample = hpf_sample * protocol_state.psk.demod.carrier; 147 | protocol_state.psk.demod.carrier *= -1; 148 | 149 | // LPF and threshold current sample 150 | int32_t lpf_sample = protocol_state.psk.lpf.prev_y + ((protocol_params.psk.lpf_alpha * (demod_sample - protocol_state.psk.lpf.prev_y)) >> 16); 151 | protocol_state.psk.lpf.prev_y = lpf_sample; 152 | int lpf_bit = (lpf_sample >= 0) ? 1 : 0; 153 | 154 | // Clock recovery 155 | protocol_state.psk.clock_recovery.t++; 156 | if(protocol_state.psk.clock_recovery.t >= protocol_params.psk.bit_width) { 157 | int32_t bit_val = protocol_state.psk.clock_recovery.bit_sum; 158 | read_new_bit(bit_val >= 0 ? 1 : 0); 159 | protocol_state.psk.clock_recovery.bit_sum = 0; 160 | protocol_state.psk.clock_recovery.t -= protocol_params.psk.bit_width; 161 | } 162 | protocol_state.psk.clock_recovery.bit_sum += demod_sample; 163 | if(lpf_bit != protocol_state.psk.clock_recovery.prev_lpf_bit) { 164 | protocol_state.psk.clock_recovery.prev_lpf_bit = lpf_bit; 165 | if(protocol_state.psk.clock_recovery.t == 0) { 166 | } else if(2*protocol_state.psk.clock_recovery.t < protocol_params.psk.bit_width) { // t < bit_width / 2 167 | protocol_state.psk.clock_recovery.t--; 168 | } else { // t >= bit_width / 2 169 | protocol_state.psk.clock_recovery.t++; 170 | } 171 | } 172 | 173 | } 174 | } 175 | 176 | void protocol_psk_enter_read() { 177 | protocol_state.psk.demod.carrier = 1; 178 | } 179 | 180 | void protocol_psk_trigger_read() { 181 | } 182 | 183 | void protocol_psk_exit_read() { 184 | } 185 | 186 | // WRITE 187 | 188 | static void write_gap() { 189 | protocol_state.psk.write_val = 0; 190 | protocol_state.psk.run_length = protocol_params.psk.write_gap; 191 | } 192 | 193 | static void write_bit(int bit) { 194 | protocol_state.psk.write_val = 1; 195 | protocol_state.psk.run_length = bit ? protocol_params.psk.write_one : protocol_params.psk.write_zero; 196 | } 197 | 198 | static void write_next() { 199 | switch(protocol_state.psk.write_state) { 200 | case WRITE_IDLE: 201 | protocol_state.psk.write_val = 1; 202 | protocol_state.psk.run_length = 0; 203 | return; 204 | case WRITE_POWERON: 205 | led_event(LED_EVENT_RAPID_BLINK); 206 | protocol_state.psk.blocks_to_write = 1 + (protocol_params.psk.cycle_length + 31) / 32; 207 | protocol_state.psk.write_block = 0; 208 | memset(protocol_state.psk.block_data, 0, sizeof(protocol_state.psk.block_data)); 209 | for(int i=0; i < (protocol_params.psk.cycle_length + 7) / 8; i++) { // For each byte 210 | protocol_state.psk.block_data[i / 4 + 1] |= (uint32_t)protocol_state.psk.card_data[i] << ((3 - (i & 3)) * 8); 211 | } 212 | protocol_state.psk.block_data[0] = 0x000810e0; 213 | 214 | // Send a poweron sequence of 6250 1s 215 | protocol_state.psk.write_val = 1; 216 | protocol_state.psk.run_length = protocol_params.psk.write_poweron_time; 217 | protocol_state.psk.write_state = WRITE_START_GAP; 218 | return; 219 | case WRITE_START_GAP: 220 | // Send a start gap 221 | protocol_state.psk.write_bit = 0; 222 | protocol_state.psk.write_val = 0; 223 | protocol_state.psk.run_length = protocol_params.psk.write_start_gap; 224 | protocol_state.psk.write_state = WRITE_DATA; 225 | return; 226 | case WRITE_DATA: 227 | if(protocol_state.psk.write_val == 1) { 228 | write_gap(); 229 | if(protocol_state.psk.write_bit == 37) { 230 | protocol_state.psk.write_state = WRITE_PROGRAMMING_TIME; 231 | } else { 232 | protocol_state.psk.write_bit++; 233 | } 234 | return; 235 | } 236 | protocol_state.psk.write_val = 1; 237 | switch(protocol_state.psk.write_bit) { 238 | case 0: // First opcode bit 239 | write_bit(1); 240 | return; 241 | case 1: // Second opcode bit (page) 242 | write_bit(0); 243 | return; 244 | case 2: // Lock bit 245 | write_bit(0); 246 | return; 247 | case 35: // addr[2] 248 | write_bit(protocol_state.psk.write_block & 4); 249 | return; 250 | case 36: // addr[1] 251 | write_bit(protocol_state.psk.write_block & 2); 252 | return; 253 | case 37: // addr[0] 254 | write_bit(protocol_state.psk.write_block & 1); 255 | return; 256 | default: // Block data 257 | { 258 | uint32_t block_data = protocol_state.psk.block_data[protocol_state.psk.write_block]; 259 | write_bit(block_data & (1 << (34 - protocol_state.psk.write_bit))); 260 | return; 261 | } 262 | } 263 | case WRITE_PROGRAMMING_TIME: 264 | // Allow some time for programming 265 | protocol_state.psk.write_val = 1; 266 | protocol_state.psk.run_length = protocol_params.psk.write_programming_time; 267 | protocol_state.psk.write_block++; 268 | if(protocol_state.psk.write_block == protocol_state.psk.blocks_to_write) { 269 | // Done 270 | led_event(LED_EVENT_ON); 271 | protocol_state.psk.write_state = WRITE_IDLE; 272 | } else { 273 | // Next block 274 | protocol_state.psk.write_state = WRITE_START_GAP; 275 | } 276 | return; 277 | } 278 | } 279 | 280 | void protocol_psk_write() { 281 | int available = stream_write_space(); 282 | while(available > 0) { 283 | if(protocol_state.psk.run_length == 0) { 284 | write_next(); 285 | if(protocol_state.psk.run_length == 0) return; 286 | } 287 | stream_write_byte(protocol_state.psk.write_val); 288 | protocol_state.psk.run_length--; 289 | available--; 290 | } 291 | } 292 | 293 | void protocol_psk_enter_write() { 294 | protocol_state.psk.write_state = WRITE_IDLE; 295 | } 296 | 297 | void protocol_psk_trigger_write() { 298 | if(protocol_state.psk.write_state == WRITE_IDLE) { 299 | protocol_state.psk.write_state = WRITE_POWERON; 300 | } 301 | } 302 | 303 | void protocol_psk_exit_write() { 304 | } 305 | 306 | // SPOOF 307 | 308 | void protocol_psk_spoof() { 309 | } 310 | 311 | void protocol_psk_enter_spoof() { 312 | } 313 | 314 | void protocol_psk_trigger_spoof() { 315 | } 316 | 317 | void protocol_psk_exit_spoof() { 318 | } 319 | 320 | -------------------------------------------------------------------------------- /firmware/protocols/psk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define PROTOCOL_PSK_NAME "PSK/T5577" 5 | #define PROTOCOL_PSK_VERSION 1 6 | 7 | void protocol_psk_init(); 8 | void protocol_psk_read(); 9 | void protocol_psk_write(); 10 | void protocol_psk_spoof(); 11 | 12 | void protocol_psk_enter_read(); 13 | void protocol_psk_enter_write(); 14 | void protocol_psk_enter_spoof(); 15 | 16 | void protocol_psk_exit_read(); 17 | void protocol_psk_exit_write(); 18 | void protocol_psk_exit_spoof(); 19 | 20 | void protocol_psk_trigger_read(); 21 | void protocol_psk_trigger_write(); 22 | void protocol_psk_trigger_spoof(); 23 | 24 | struct protocol_psk_params { 25 | // SHARED 26 | int bit_width; 27 | int cycle_length; 28 | int repeats_until_valid; 29 | 30 | // READER 31 | int32_t hpf_alpha; // Alpha as a 16.16 fixed point number 32 | int32_t lpf_alpha; // Alpha as a 16.16 fixed point number 33 | 34 | // WRITER 35 | int write_poweron_time; 36 | int write_programming_time; 37 | int write_one; 38 | int write_zero; 39 | int write_start_gap; 40 | int write_gap; 41 | }; 42 | 43 | struct protocol_psk_state { 44 | // SHARED 45 | uint8_t card_data[28]; 46 | 47 | // READER 48 | int16_t read_buffer[128]; 49 | struct { 50 | int32_t prev_x; 51 | int32_t prev_y; 52 | } hpf; 53 | struct { 54 | int32_t carrier; 55 | } demod; 56 | struct { 57 | int32_t prev_y; 58 | } lpf; 59 | struct { 60 | int32_t t; 61 | int32_t bit_sum; 62 | int32_t prev_lpf_bit; 63 | } clock_recovery; 64 | struct { 65 | int counter; 66 | } cycle; 67 | 68 | struct { 69 | int8_t bits[224]; 70 | int bits_ptr; 71 | uint16_t cyclotron[28]; 72 | } decoder; 73 | 74 | // WRITER 75 | 76 | int blocks_to_write; 77 | int8_t write_val; 78 | int run_length; 79 | enum { 80 | WRITE_IDLE, 81 | WRITE_POWERON, 82 | WRITE_START_GAP, 83 | WRITE_DATA, 84 | WRITE_PROGRAMMING_TIME, 85 | } write_state; 86 | uint32_t block_data[8]; 87 | int write_bit; 88 | int write_block; 89 | }; 90 | -------------------------------------------------------------------------------- /firmware/sd.c: -------------------------------------------------------------------------------- 1 | #include "ff.h" 2 | 3 | FATFS fatfs; 4 | 5 | #define msg "Hello, world!" 6 | 7 | int sd_startup() { 8 | FRESULT fr; 9 | FIL file; 10 | UINT n; 11 | 12 | f_mount(&fatfs, "", 0); 13 | fr = f_open(&file, "0:hello.txt", FA_WRITE | FA_CREATE_ALWAYS); 14 | if(fr) return fr; 15 | fr = f_write(&file, msg, sizeof(msg)-1, &n); 16 | f_close(&file); 17 | if(fr) return fr; 18 | if(n < sizeof(msg)-1) return -1; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /firmware/sd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int sd_startup(); 4 | int sd_write_f(); 5 | -------------------------------------------------------------------------------- /firmware/startup.s: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file startup_stm32f0xx.s 4 | * @author MCD Application Team 5 | * @version V1.3.1 6 | * @date 17-January-2014 7 | * @brief STM32F030 Devices vector table for RIDE7 toolchain. 8 | * This module performs: 9 | * - Set the initial SP 10 | * - Set the initial PC == Reset_Handler, 11 | * - Set the vector table entries with the exceptions ISR address 12 | * - Configure the system clock 13 | * - Branches to main in the C library (which eventually 14 | * calls main()). 15 | * After Reset the Cortex-M0 processor is in Thread mode, 16 | * priority is Privileged, and the Stack is set to Main. 17 | ****************************************************************************** 18 | * @attention 19 | * 20 | *

© COPYRIGHT 2014 STMicroelectronics

21 | * 22 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 23 | * You may not use this file except in compliance with the License. 24 | * You may obtain a copy of the License at: 25 | * 26 | * http://www.st.com/software_license_agreement_liberty_v2 27 | * 28 | * Unless required by applicable law or agreed to in writing, software 29 | * distributed under the License is distributed on an "AS IS" BASIS, 30 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | * See the License for the specific language governing permissions and 32 | * limitations under the License. 33 | * 34 | ****************************************************************************** 35 | */ 36 | 37 | .syntax unified 38 | .cpu cortex-m0 39 | .fpu softvfp 40 | .thumb 41 | 42 | .global g_pfnVectors 43 | .global Default_Handler 44 | 45 | /* start address for the initialization values of the .data section. 46 | defined in linker script */ 47 | .word _sidata 48 | /* start address for the .data section. defined in linker script */ 49 | .word _sdata 50 | /* end address for the .data section. defined in linker script */ 51 | .word _edata 52 | /* start address for the .bss section. defined in linker script */ 53 | .word _sbss 54 | /* end address for the .bss section. defined in linker script */ 55 | .word _ebss 56 | 57 | .equ BootRAM, 0xF108F85F 58 | /** 59 | * @brief This is the code that gets called when the processor first 60 | * starts execution following a reset event. Only the absolutely 61 | * necessary set is performed, after which the application 62 | * supplied main() routine is called. 63 | * @param None 64 | * @retval : None 65 | */ 66 | 67 | .section .text.Reset_Handler 68 | .weak Reset_Handler 69 | .type Reset_Handler, %function 70 | Reset_Handler: 71 | ldr r0, =_estack 72 | mov sp, r0 /* set stack pointer */ 73 | 74 | /* Copy the data segment initializers from flash to SRAM */ 75 | movs r1, #0 76 | b LoopCopyDataInit 77 | 78 | CopyDataInit: 79 | ldr r3, =_sidata 80 | ldr r3, [r3, r1] 81 | str r3, [r0, r1] 82 | adds r1, r1, #4 83 | 84 | LoopCopyDataInit: 85 | ldr r0, =_sdata 86 | ldr r3, =_edata 87 | adds r2, r0, r1 88 | cmp r2, r3 89 | bcc CopyDataInit 90 | ldr r2, =_sbss 91 | b LoopFillZerobss 92 | /* Zero fill the bss segment. */ 93 | FillZerobss: 94 | movs r3, #0 95 | str r3, [r2] 96 | adds r2, r2, #4 97 | 98 | 99 | LoopFillZerobss: 100 | ldr r3, = _ebss 101 | cmp r2, r3 102 | bcc FillZerobss 103 | 104 | /* Call the clock system intitialization function.*/ 105 | bl SystemInit 106 | 107 | /* Call the application's entry point.*/ 108 | bl main 109 | 110 | LoopForever: 111 | b LoopForever 112 | 113 | .size Reset_Handler, .-Reset_Handler 114 | 115 | /** 116 | * @brief This is the code that gets called when the processor receives an 117 | * unexpected interrupt. This simply enters an infinite loop, preserving 118 | * the system state for examination by a debugger. 119 | * 120 | * @param None 121 | * @retval : None 122 | */ 123 | .section .text.Default_Handler,"ax",%progbits 124 | Default_Handler: 125 | Infinite_Loop: 126 | b Infinite_Loop 127 | .size Default_Handler, .-Default_Handler 128 | /****************************************************************************** 129 | * 130 | * The minimal vector table for a Cortex M0. Note that the proper constructs 131 | * must be placed on this to ensure that it ends up at physical address 132 | * 0x0000.0000. 133 | * 134 | ******************************************************************************/ 135 | .section .isr_vector,"a",%progbits 136 | .type g_pfnVectors, %object 137 | .size g_pfnVectors, .-g_pfnVectors 138 | 139 | 140 | g_pfnVectors: 141 | .word _estack 142 | .word Reset_Handler 143 | 144 | .word NMI_Handler 145 | .word HardFault_Handler 146 | .word 0 147 | .word 0 148 | .word 0 149 | .word 0 150 | .word 0 151 | .word 0 152 | .word 0 153 | .word SVC_Handler 154 | .word 0 155 | .word 0 156 | .word PendSV_Handler 157 | .word SysTick_Handler 158 | 159 | .word WWDG_IRQHandler 160 | .word PVD_VDDIO2_IRQHandler 161 | .word RTC_IRQHandler 162 | .word FLASH_IRQHandler 163 | .word RCC_CRS_IRQHandler 164 | .word EXTI0_1_IRQHandler 165 | .word EXTI2_3_IRQHandler 166 | .word EXTI4_15_IRQHandler 167 | .word TSC_IRQHandler 168 | .word DMA1_Channel1_IRQHandler 169 | .word DMA1_Channel2_3_IRQHandler 170 | .word DMA1_Channel4_5_IRQHandler 171 | .word ADC1_IRQHandler 172 | .word TIM1_BRK_UP_TRG_COM_IRQHandler 173 | .word TIM1_CC_IRQHandler 174 | .word TIM2_IRQHandler 175 | .word TIM3_IRQHandler 176 | .word 0 177 | .word 0 178 | .word TIM14_IRQHandler 179 | .word 0 180 | .word TIM16_IRQHandler 181 | .word TIM17_IRQHandler 182 | .word I2C1_IRQHandler 183 | .word 0 184 | .word SPI1_IRQHandler 185 | .word SPI2_IRQHandler 186 | .word USART1_IRQHandler 187 | .word USART2_IRQHandler 188 | .word 0 189 | .word CEC_CAN_IRQHandler 190 | .word USB_IRQHandler 191 | .word BootRAM /* @0x108. This is for boot in RAM mode for 192 | STM32F0xx devices. */ 193 | 194 | 195 | /******************************************************************************* 196 | * 197 | * Provide weak aliases for each Exception handler to the Default_Handler. 198 | * As they are weak aliases, any function with the same name will override 199 | * this definition. 200 | * 201 | *******************************************************************************/ 202 | 203 | .weak NMI_Handler 204 | .thumb_set NMI_Handler,Default_Handler 205 | 206 | .weak HardFault_Handler 207 | .thumb_set HardFault_Handler,Default_Handler 208 | 209 | .weak SVC_Handler 210 | .thumb_set SVC_Handler,Default_Handler 211 | 212 | .weak PendSV_Handler 213 | .thumb_set PendSV_Handler,Default_Handler 214 | 215 | .weak SysTick_Handler 216 | .thumb_set SysTick_Handler,Default_Handler 217 | 218 | .weak WWDG_IRQHandler 219 | .thumb_set WWDG_IRQHandler,Default_Handler 220 | 221 | .weak PVD_VDDIO2_IRQHandler 222 | .thumb_set PVD_VDDIO2_IRQHandler,Default_Handler 223 | 224 | .weak RTC_IRQHandler 225 | .thumb_set RTC_IRQHandler,Default_Handler 226 | 227 | .weak FLASH_IRQHandler 228 | .thumb_set FLASH_IRQHandler,Default_Handler 229 | 230 | .weak RCC_CRS_IRQHandler 231 | .thumb_set RCC_CRS_IRQHandler,Default_Handler 232 | 233 | .weak EXTI0_1_IRQHandler 234 | .thumb_set EXTI0_1_IRQHandler,Default_Handler 235 | 236 | .weak EXTI2_3_IRQHandler 237 | .thumb_set EXTI2_3_IRQHandler,Default_Handler 238 | 239 | .weak EXTI4_15_IRQHandler 240 | .thumb_set EXTI4_15_IRQHandler,Default_Handler 241 | 242 | .weak TSC_IRQHandler 243 | .thumb_set TSC_IRQHandler,Default_Handler 244 | 245 | .weak DMA1_Channel1_IRQHandler 246 | .thumb_set DMA1_Channel1_IRQHandler,Default_Handler 247 | 248 | .weak DMA1_Channel2_3_IRQHandler 249 | .thumb_set DMA1_Channel2_3_IRQHandler,Default_Handler 250 | 251 | .weak DMA1_Channel4_5_IRQHandler 252 | .thumb_set DMA1_Channel4_5_IRQHandler,Default_Handler 253 | 254 | .weak ADC1_IRQHandler 255 | .thumb_set ADC1_IRQHandler,Default_Handler 256 | 257 | .weak TIM1_BRK_UP_TRG_COM_IRQHandler 258 | .thumb_set TIM1_BRK_UP_TRG_COM_IRQHandler,Default_Handler 259 | 260 | .weak TIM1_CC_IRQHandler 261 | .thumb_set TIM1_CC_IRQHandler,Default_Handler 262 | 263 | .weak TIM2_IRQHandler 264 | .thumb_set TIM2_IRQHandler,Default_Handler 265 | 266 | .weak TIM3_IRQHandler 267 | .thumb_set TIM3_IRQHandler,Default_Handler 268 | 269 | .weak TIM14_IRQHandler 270 | .thumb_set TIM14_IRQHandler,Default_Handler 271 | 272 | .weak TIM16_IRQHandler 273 | .thumb_set TIM16_IRQHandler,Default_Handler 274 | 275 | .weak TIM17_IRQHandler 276 | .thumb_set TIM17_IRQHandler,Default_Handler 277 | 278 | .weak I2C1_IRQHandler 279 | .thumb_set I2C1_IRQHandler,Default_Handler 280 | 281 | .weak SPI1_IRQHandler 282 | .thumb_set SPI1_IRQHandler,Default_Handler 283 | 284 | .weak SPI2_IRQHandler 285 | .thumb_set SPI2_IRQHandler,Default_Handler 286 | 287 | .weak USART1_IRQHandler 288 | .thumb_set USART1_IRQHandler,Default_Handler 289 | 290 | .weak USART2_IRQHandler 291 | .thumb_set USART2_IRQHandler,Default_Handler 292 | 293 | .weak CEC_CAN_IRQHandler 294 | .thumb_set CEC_CAN_IRQHandler,Default_Handler 295 | 296 | 297 | .weak USB_IRQHandler 298 | .thumb_set USB_IRQHandler,Default_Handler 299 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 300 | -------------------------------------------------------------------------------- /firmware/stm32f0xx_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file Project/STM32F0xx_StdPeriph_Templates/stm32f0xx_conf.h 4 | * @author MCD Application Team 5 | * @version V1.4.0 6 | * @date 24-July-2014 7 | * @brief Library configuration file. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2014 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __STM32F0XX_CONF_H 30 | #define __STM32F0XX_CONF_H 31 | 32 | /* Includes ------------------------------------------------------------------*/ 33 | /* Comment the line below to disable peripheral header file inclusion */ 34 | #include "stm32f0xx_adc.h" 35 | #include "stm32f0xx_can.h" 36 | #include "stm32f0xx_cec.h" 37 | #include "stm32f0xx_crc.h" 38 | #include "stm32f0xx_crs.h" 39 | #include "stm32f0xx_comp.h" 40 | #include "stm32f0xx_dac.h" 41 | #include "stm32f0xx_dbgmcu.h" 42 | #include "stm32f0xx_dma.h" 43 | #include "stm32f0xx_exti.h" 44 | #include "stm32f0xx_flash.h" 45 | #include "stm32f0xx_gpio.h" 46 | #include "stm32f0xx_syscfg.h" 47 | #include "stm32f0xx_i2c.h" 48 | #include "stm32f0xx_iwdg.h" 49 | #include "stm32f0xx_pwr.h" 50 | #include "stm32f0xx_rcc.h" 51 | #include "stm32f0xx_rtc.h" 52 | #include "stm32f0xx_spi.h" 53 | #include "stm32f0xx_tim.h" 54 | #include "stm32f0xx_usart.h" 55 | #include "stm32f0xx_wwdg.h" 56 | #include "stm32f0xx_misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ 57 | 58 | /* Exported types ------------------------------------------------------------*/ 59 | /* Exported constants --------------------------------------------------------*/ 60 | /* Uncomment the line below to expanse the "assert_param" macro in the 61 | Standard Peripheral Library drivers code */ 62 | /* #define USE_FULL_ASSERT 1 */ 63 | 64 | /* Exported macro ------------------------------------------------------------*/ 65 | #ifdef USE_FULL_ASSERT 66 | 67 | /** 68 | * @brief The assert_param macro is used for function's parameters check. 69 | * @param expr: If expr is false, it calls assert_failed function which reports 70 | * the name of the source file and the source line number of the call 71 | * that failed. If expr is true, it returns no value. 72 | * @retval None 73 | */ 74 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) 75 | /* Exported functions ------------------------------------------------------- */ 76 | void assert_failed(uint8_t* file, uint32_t line); 77 | #else 78 | #define assert_param(expr) ((void)0) 79 | #endif /* USE_FULL_ASSERT */ 80 | 81 | #endif /* __STM32F0XX_CONF_H */ 82 | 83 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 84 | -------------------------------------------------------------------------------- /firmware/system_stm32f0xx.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f0xx.c 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 31-January-2014 7 | * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. 8 | * This file contains the system clock configuration for STM32F0xx devices, 9 | * and is customized for use with STM32F0x2-USB-FS_Device Library. 10 | * 11 | * 12 | * The STM32F072x is configured to run at 48 MHz, using Internal HSI48 13 | * clock source * 14 | * 15 | * 1. This file provides two functions and one global variable to be called from 16 | * user application: 17 | * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier 18 | * and Divider factors, AHB/APBx prescalers and Flash settings), 19 | * depending on the configuration made in the clock xls tool. 20 | * This function is called at startup just after reset and 21 | * before branch to main program. This call is made inside 22 | * the "startup_stm32f072.s" file. 23 | * 24 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 25 | * by the user application to setup the SysTick 26 | * timer or configure other parameters. 27 | * 28 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 29 | * be called whenever the core clock is changed 30 | * during program execution. 31 | * 32 | * 2. After each device reset the HSI (8 MHz Range) is used as system clock source. 33 | * Then SystemInit() function is called, in "startup_stm32f072.s" file, to 34 | * configure the system clock before to branch to main program. 35 | * 36 | * 3. If the system clock source selected by user fails to startup, the SystemInit() 37 | * function will do nothing and HSI still used as system clock source. User can 38 | * add some code to deal with this issue inside the SetSysClock() function. 39 | * 40 | * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define 41 | * in "stm32f0xx.h" file. When HSE is used as system clock source, directly or 42 | * through PLL, and you are using different crystal you have to adapt the HSE 43 | * value to your own configuration. 44 | * 45 | ****************************************************************************** 46 | * @attention 47 | * 48 | *

© COPYRIGHT 2014 STMicroelectronics

49 | * 50 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 51 | * You may not use this file except in compliance with the License. 52 | * You may obtain a copy of the License at: 53 | * 54 | * http://www.st.com/software_license_agreement_liberty_v2 55 | * 56 | * Unless required by applicable law or agreed to in writing, software 57 | * distributed under the License is distributed on an "AS IS" BASIS, 58 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 59 | * See the License for the specific language governing permissions and 60 | * limitations under the License. 61 | * 62 | ****************************************************************************** 63 | */ 64 | 65 | /** @addtogroup CMSIS 66 | * @{ 67 | */ 68 | 69 | /** @addtogroup stm32f0xx_system 70 | * @{ 71 | */ 72 | 73 | /** @addtogroup STM32F0xx_System_Private_Includes 74 | * @{ 75 | */ 76 | 77 | #include "stm32f0xx.h" 78 | 79 | /** 80 | * @} 81 | */ 82 | 83 | /* Private typedef -----------------------------------------------------------*/ 84 | /* Private define ------------------------------------------------------------*/ 85 | /* Private macro ------------------------------------------------------------*/ 86 | /* Private variables ---------------------------------------------------------*/ 87 | uint32_t SystemCoreClock = 48000000; 88 | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 89 | 90 | /* Private function prototypes -----------------------------------------------*/ 91 | static void SetSysClock(void); 92 | 93 | /* Private functions ---------------------------------------------------------*/ 94 | /** @addtogroup STM32F0xx_System_Private_Functions 95 | * @{ 96 | */ 97 | 98 | /** 99 | * @brief Setup the microcontroller system. 100 | * Initialize the Embedded Flash Interface, the PLL and update the 101 | * SystemCoreClock variable. 102 | * @param None 103 | * @retval None 104 | */ 105 | void SystemInit (void) 106 | { 107 | /* Set HSION bit */ 108 | RCC->CR |= (uint32_t)0x00000001; 109 | 110 | /* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE and MCOSEL[3:0] bits MCOPRE[2:0] */ 111 | RCC->CFGR &= (uint32_t)0x80FFB80C; 112 | 113 | /* Reset HSEON, CSSON and PLLON bits */ 114 | RCC->CR &= (uint32_t)0xFEF6FFFF; 115 | 116 | /* Reset HSEBYP bit */ 117 | RCC->CR &= (uint32_t)0xFFFBFFFF; 118 | 119 | /* Reset PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */ 120 | RCC->CFGR &= (uint32_t)0xFFC07FFF; 121 | 122 | /* Reset PREDIV1[3:0] bits */ 123 | RCC->CFGR2 &= (uint32_t)0xFFFFFFF0; 124 | 125 | /* Reset USARTSW[1:0], I2CSW, CECSW and ADCSW bits */ 126 | RCC->CFGR3 &= (uint32_t)0xFFFFFEAC; 127 | 128 | /* Reset HSI14 & HSI48 bit */ 129 | RCC->CR2 &= (uint32_t)0xFFFEFFFE; 130 | 131 | /* Disable all interrupts */ 132 | RCC->CIR = 0x00000000; 133 | 134 | /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ 135 | SetSysClock(); 136 | } 137 | 138 | /** 139 | * @brief Update SystemCoreClock according to Clock Register Values 140 | * The SystemCoreClock variable contains the core clock (HCLK), it can 141 | * be used by the user application to setup the SysTick timer or configure 142 | * other parameters. 143 | * 144 | * @note Each time the core clock (HCLK) changes, this function must be called 145 | * to update SystemCoreClock variable value. Otherwise, any configuration 146 | * based on this variable will be incorrect. 147 | * 148 | * @note - The system frequency computed by this function is not the real 149 | * frequency in the chip. It is calculated based on the predefined 150 | * constant and the selected clock source: 151 | * 152 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 153 | * 154 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 155 | * 156 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 157 | * or HSI_VALUE(*) multiplied/divided by the PLL factors. 158 | * @note - If SYSCLK source is HSI48, function returns constant HSI48_VALUE(***) 159 | * 160 | * (*) HSI_VALUE is a constant defined in stm32f0xx.h file (default value 161 | * 8 MHz) but the real value may vary depending on the variations 162 | * in voltage and temperature. 163 | * 164 | * (**) HSE_VALUE is a constant defined in stm32f0xx.h file (default value 165 | * 8 MHz), user has to ensure that HSE_VALUE is same as the real 166 | * frequency of the crystal used. Otherwise, this function may 167 | * have wrong result. 168 | * @note (***) HSI48_VALUE is a constant defined in stm32f0xx.h file (default value 169 | * 48 MHz) but the real value may vary depending on the variations 170 | * in voltage and temperature. 171 | * 172 | * - The result of this function could be not correct when using fractional 173 | * value for HSE crystal. 174 | * @param None 175 | * @retval None 176 | */ 177 | void SystemCoreClockUpdate (void) 178 | { 179 | uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0; 180 | 181 | /* Get SYSCLK source -------------------------------------------------------*/ 182 | tmp = RCC->CFGR & RCC_CFGR_SWS; 183 | 184 | switch (tmp) 185 | { 186 | case 0x00: /* HSI used as system clock */ 187 | SystemCoreClock = HSI_VALUE; 188 | break; 189 | case 0x04: /* HSE used as system clock */ 190 | SystemCoreClock = HSE_VALUE; 191 | break; 192 | case 0x08: /* PLL used as system clock */ 193 | /* Get PLL clock source and multiplication factor ----------------------*/ 194 | pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; 195 | pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; 196 | pllmull = ( pllmull >> 18) + 2; 197 | 198 | if (pllsource == 0x00) 199 | { 200 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 201 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 202 | } 203 | else 204 | { 205 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; 206 | /* HSE oscillator clock selected as PREDIV1 clock entry */ 207 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 208 | } 209 | break; 210 | case 0x0C: /* HSI48 used as system clock */ 211 | SystemCoreClock = HSI48_VALUE; 212 | break; 213 | default: /* HSI used as system clock */ 214 | SystemCoreClock = HSI_VALUE; 215 | break; 216 | 217 | } 218 | /* Compute HCLK clock frequency ----------------*/ 219 | /* Get HCLK prescaler */ 220 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 221 | /* HCLK clock frequency */ 222 | SystemCoreClock >>= tmp; 223 | } 224 | 225 | /** 226 | * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash 227 | * settings. 228 | * @note This function should be called only once the RCC clock configuration 229 | * is reset to the default reset state (done in SystemInit() function). 230 | * @param None 231 | * @retval None 232 | */ 233 | static void SetSysClock(void) 234 | { 235 | __IO uint32_t StartUpCounter = 0, HSI48Status = 0; 236 | 237 | /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/ 238 | /* Enable HSI48 */ 239 | RCC->CR2 |= ((uint32_t)RCC_CR2_HSI48ON); 240 | 241 | /* Wait till HSI48 is ready and if Time out is reached exit */ 242 | do 243 | { 244 | HSI48Status = RCC->CR2 & RCC_CR2_HSI48RDY; 245 | StartUpCounter++; 246 | } while((HSI48Status == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT)); 247 | 248 | if ((RCC->CR2 & RCC_CR2_HSI48RDY) != RESET) 249 | { 250 | HSI48Status = (uint32_t)0x01; 251 | } 252 | else 253 | { 254 | HSI48Status = (uint32_t)0x00; 255 | } 256 | 257 | if (HSI48Status == (uint32_t)0x01) 258 | { 259 | /* Enable Prefetch Buffer and set Flash Latency */ 260 | FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; 261 | 262 | /* HCLK = SYSCLK */ 263 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 264 | 265 | /* PCLK = HCLK */ 266 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1; 267 | 268 | /* Select PLL as system clock source */ 269 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 270 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI48; 271 | 272 | /* Wait till PLL is used as system clock source */ 273 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_HSI48) 274 | { 275 | } 276 | 277 | /* Enable automatic calibration of HSI48 from USB SOF */ 278 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_CRS, ENABLE); 279 | CRS_SynchronizationSourceConfig(CRS_SYNCSource_USB); 280 | CRS_AutomaticCalibrationCmd(ENABLE); 281 | CRS_FrequencyErrorCounterCmd(ENABLE); 282 | } 283 | } 284 | 285 | /** 286 | * @} 287 | */ 288 | 289 | /** 290 | * @} 291 | */ 292 | 293 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 294 | -------------------------------------------------------------------------------- /firmware/system_stm32f0xx.c.old: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f0xx.c 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 23-March-2012 7 | * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. 8 | * This file contains the system clock configuration for STM32F0xx devices, 9 | * and is customized for use with STM32F0-DISCOVERY Kit. 10 | * The STM32F0xx is configured to run at 48 MHz, following the three 11 | * configuration below: 12 | * - PLL_SOURCE_HSI (default): HSI (~8MHz) used to clock the PLL, and 13 | * the PLL is used as system clock source. 14 | * - PLL_SOURCE_HSE : HSE (8MHz) used to clock the PLL, and 15 | * the PLL is used as system clock source. 16 | * - PLL_SOURCE_HSE_BYPASS : HSE bypassed with an external clock 17 | * (8MHz, coming from ST-Link) used to clock 18 | * the PLL, and the PLL is used as system 19 | * clock source. 20 | * 21 | * 22 | * 1. This file provides two functions and one global variable to be called from 23 | * user application: 24 | * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier 25 | * and Divider factors, AHB/APBx prescalers and Flash settings), 26 | * depending on the configuration selected (see above). 27 | * This function is called at startup just after reset and 28 | * before branch to main program. This call is made inside 29 | * the "startup_stm32f0xx.s" file. 30 | * 31 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 32 | * by the user application to setup the SysTick 33 | * timer or configure other parameters. 34 | * 35 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 36 | * be called whenever the core clock is changed 37 | * during program execution. 38 | * 39 | * 2. After each device reset the HSI (8 MHz Range) is used as system clock source. 40 | * Then SystemInit() function is called, in "startup_stm32f0xx.s" file, to 41 | * configure the system clock before to branch to main program. 42 | * 43 | * 3. If the system clock source selected by user fails to startup, the SystemInit() 44 | * function will do nothing and HSI still used as system clock source. User can 45 | * add some code to deal with this issue inside the SetSysClock() function. 46 | * 47 | * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define 48 | * in "stm32f0xx.h" file. When HSE is used as system clock source, directly or 49 | * through PLL, and you are using different crystal you have to adapt the HSE 50 | * value to your own configuration. 51 | * 52 | ****************************************************************************** 53 | * @attention 54 | * 55 | *

© COPYRIGHT 2012 STMicroelectronics

56 | * 57 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 58 | * You may not use this file except in compliance with the License. 59 | * You may obtain a copy of the License at: 60 | * 61 | * http://www.st.com/software_license_agreement_liberty_v2 62 | * 63 | * Unless required by applicable law or agreed to in writing, software 64 | * distributed under the License is distributed on an "AS IS" BASIS, 65 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 66 | * See the License for the specific language governing permissions and 67 | * limitations under the License. 68 | * 69 | ****************************************************************************** 70 | */ 71 | 72 | /** @addtogroup CMSIS 73 | * @{ 74 | */ 75 | 76 | /** @addtogroup stm32f0xx_system 77 | * @{ 78 | */ 79 | 80 | /** @addtogroup STM32F0xx_System_Private_Includes 81 | * @{ 82 | */ 83 | 84 | #include "stm32f0xx.h" 85 | 86 | /** 87 | * @} 88 | */ 89 | 90 | /** @addtogroup STM32F0xx_System_Private_TypesDefinitions 91 | * @{ 92 | */ 93 | 94 | /** 95 | * @} 96 | */ 97 | 98 | /** @addtogroup STM32F0xx_System_Private_Defines 99 | * @{ 100 | */ 101 | /* Select the PLL clock source */ 102 | 103 | #define PLL_SOURCE_HSI // HSI (~8MHz) used to clock the PLL, and the PLL is used as system clock source 104 | //#define PLL_SOURCE_HSE // HSE (8MHz) used to clock the PLL, and the PLL is used as system clock source 105 | //#define PLL_SOURCE_HSE_BYPASS // HSE bypassed with an external clock (8MHz, coming from ST-Link) used to clock 106 | // the PLL, and the PLL is used as system clock source 107 | 108 | /** 109 | * @} 110 | */ 111 | 112 | /** @addtogroup STM32F0xx_System_Private_Macros 113 | * @{ 114 | */ 115 | 116 | /** 117 | * @} 118 | */ 119 | 120 | /** @addtogroup STM32F0xx_System_Private_Variables 121 | * @{ 122 | */ 123 | uint32_t SystemCoreClock = 48000000; 124 | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 125 | 126 | /** 127 | * @} 128 | */ 129 | 130 | /** @addtogroup STM32F0xx_System_Private_FunctionPrototypes 131 | * @{ 132 | */ 133 | 134 | static void SetSysClock(void); 135 | 136 | /** 137 | * @} 138 | */ 139 | 140 | /** @addtogroup STM32F0xx_System_Private_Functions 141 | * @{ 142 | */ 143 | 144 | /** 145 | * @brief Setup the microcontroller system. 146 | * Initialize the Embedded Flash Interface, the PLL and update the 147 | * SystemCoreClock variable. 148 | * @param None 149 | * @retval None 150 | */ 151 | void SystemInit (void) 152 | { 153 | /* Set HSION bit */ 154 | RCC->CR |= (uint32_t)0x00000001; 155 | 156 | /* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE and MCOSEL[2:0] bits */ 157 | RCC->CFGR &= (uint32_t)0xF8FFB80C; 158 | 159 | /* Reset HSEON, CSSON and PLLON bits */ 160 | RCC->CR &= (uint32_t)0xFEF6FFFF; 161 | 162 | /* Reset HSEBYP bit */ 163 | RCC->CR &= (uint32_t)0xFFFBFFFF; 164 | 165 | /* Reset PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */ 166 | RCC->CFGR &= (uint32_t)0xFFC0FFFF; 167 | 168 | /* Reset PREDIV1[3:0] bits */ 169 | RCC->CFGR2 &= (uint32_t)0xFFFFFFF0; 170 | 171 | /* Reset USARTSW[1:0], I2CSW, CECSW and ADCSW bits */ 172 | RCC->CFGR3 &= (uint32_t)0xFFFFFEAC; 173 | 174 | /* Reset HSI14 bit */ 175 | RCC->CR2 &= (uint32_t)0xFFFFFFFE; 176 | 177 | /* Disable all interrupts */ 178 | RCC->CIR = 0x00000000; 179 | 180 | /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */ 181 | SetSysClock(); 182 | } 183 | 184 | /** 185 | * @brief Update SystemCoreClock according to Clock Register Values 186 | * The SystemCoreClock variable contains the core clock (HCLK), it can 187 | * be used by the user application to setup the SysTick timer or configure 188 | * other parameters. 189 | * 190 | * @note Each time the core clock (HCLK) changes, this function must be called 191 | * to update SystemCoreClock variable value. Otherwise, any configuration 192 | * based on this variable will be incorrect. 193 | * 194 | * @note - The system frequency computed by this function is not the real 195 | * frequency in the chip. It is calculated based on the predefined 196 | * constant and the selected clock source: 197 | * 198 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 199 | * 200 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 201 | * 202 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 203 | * or HSI_VALUE(*) multiplied/divided by the PLL factors. 204 | * 205 | * (*) HSI_VALUE is a constant defined in stm32f0xx.h file (default value 206 | * 8 MHz) but the real value may vary depending on the variations 207 | * in voltage and temperature. 208 | * 209 | * (**) HSE_VALUE is a constant defined in stm32f0xx.h file (default value 210 | * 8 MHz), user has to ensure that HSE_VALUE is same as the real 211 | * frequency of the crystal used. Otherwise, this function may 212 | * have wrong result. 213 | * 214 | * - The result of this function could be not correct when using fractional 215 | * value for HSE crystal. 216 | * @param None 217 | * @retval None 218 | */ 219 | void SystemCoreClockUpdate (void) 220 | { 221 | uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0; 222 | 223 | /* Get SYSCLK source -------------------------------------------------------*/ 224 | tmp = RCC->CFGR & RCC_CFGR_SWS; 225 | 226 | switch (tmp) 227 | { 228 | case 0x00: /* HSI used as system clock */ 229 | SystemCoreClock = HSI_VALUE; 230 | break; 231 | case 0x04: /* HSE used as system clock */ 232 | SystemCoreClock = HSE_VALUE; 233 | break; 234 | case 0x08: /* PLL used as system clock */ 235 | /* Get PLL clock source and multiplication factor ----------------------*/ 236 | pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; 237 | pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; 238 | pllmull = ( pllmull >> 18) + 2; 239 | 240 | if (pllsource == 0x00) 241 | { 242 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 243 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 244 | } 245 | else 246 | { 247 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; 248 | /* HSE oscillator clock selected as PREDIV1 clock entry */ 249 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 250 | } 251 | break; 252 | default: /* HSI used as system clock */ 253 | SystemCoreClock = HSI_VALUE; 254 | break; 255 | } 256 | /* Compute HCLK clock frequency ----------------*/ 257 | /* Get HCLK prescaler */ 258 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 259 | /* HCLK clock frequency */ 260 | SystemCoreClock >>= tmp; 261 | } 262 | 263 | /** 264 | * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash 265 | * settings. 266 | * @note This function should be called only once the RCC clock configuration 267 | * is reset to the default reset state (done in SystemInit() function). 268 | * @param None 269 | * @retval None 270 | */ 271 | static void SetSysClock(void) 272 | { 273 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 274 | 275 | /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/ 276 | #if defined (PLL_SOURCE_HSI) 277 | /* At this stage the HSI is already enabled */ 278 | 279 | /* Enable Prefetch Buffer and set Flash Latency */ 280 | FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; 281 | 282 | /* HCLK = SYSCLK */ 283 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 284 | 285 | /* PCLK = HCLK */ 286 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1; 287 | 288 | /* PLL configuration = (HSI/2) * 12 = ~48 MHz */ 289 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 290 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL12); 291 | 292 | /* Enable PLL */ 293 | RCC->CR |= RCC_CR_PLLON; 294 | 295 | /* Wait till PLL is ready */ 296 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 297 | { 298 | } 299 | 300 | /* Select PLL as system clock source */ 301 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 302 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 303 | 304 | /* Wait till PLL is used as system clock source */ 305 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) 306 | { 307 | } 308 | #else 309 | #if defined (PLL_SOURCE_HSE) 310 | /* Enable HSE */ 311 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 312 | #elif defined (PLL_SOURCE_HSE_BYPASS) 313 | /* HSE oscillator bypassed with external clock */ 314 | RCC->CR |= (uint32_t)(RCC_CR_HSEON | RCC_CR_HSEBYP); 315 | #endif /* PLL_SOURCE_HSE */ 316 | 317 | /* Wait till HSE is ready and if Time out is reached exit */ 318 | do 319 | { 320 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 321 | StartUpCounter++; 322 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 323 | 324 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 325 | { 326 | HSEStatus = (uint32_t)0x01; 327 | } 328 | else 329 | { 330 | HSEStatus = (uint32_t)0x00; 331 | } 332 | 333 | if (HSEStatus == (uint32_t)0x01) 334 | { 335 | /* Enable Prefetch Buffer and set Flash Latency */ 336 | FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; 337 | 338 | /* HCLK = SYSCLK */ 339 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 340 | 341 | /* PCLK = HCLK */ 342 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1; 343 | 344 | /* PLL configuration = HSE * 6 = 48 MHz */ 345 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 346 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6); 347 | 348 | /* Enable PLL */ 349 | RCC->CR |= RCC_CR_PLLON; 350 | 351 | /* Wait till PLL is ready */ 352 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 353 | { 354 | } 355 | 356 | /* Select PLL as system clock source */ 357 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 358 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 359 | 360 | /* Wait till PLL is used as system clock source */ 361 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL) 362 | { 363 | } 364 | } 365 | else 366 | { /* If HSE fails to start-up, the application will have wrong clock 367 | configuration. User can add here some code to deal with this error */ 368 | } 369 | #endif /* PLL_SOURCE_HSI */ 370 | } 371 | 372 | /** 373 | * @} 374 | */ 375 | 376 | /** 377 | * @} 378 | */ 379 | 380 | /** 381 | * @} 382 | */ 383 | 384 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 385 | -------------------------------------------------------------------------------- /firmware/usb/usb_bsp.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file usb_bsp.c 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 31-January-2014 7 | * @brief This file Provides Device Core configuration Functions 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2014 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "usb_bsp.h" 30 | 31 | /* Private typedef -----------------------------------------------------------*/ 32 | /* Private define ------------------------------------------------------------*/ 33 | /* Private macro -------------------------------------------------------------*/ 34 | /* Private variables ---------------------------------------------------------*/ 35 | /* Private function prototypes -----------------------------------------------*/ 36 | #if defined USB_CLOCK_SOURCE_CRS 37 | static void CRS_Config(void); 38 | #endif /* USB_CLOCK_SOURCE_CRS */ 39 | 40 | /* Private functions ---------------------------------------------------------*/ 41 | 42 | /** 43 | * @brief Initialize BSP configurations 44 | * @param None 45 | * @retval None 46 | */ 47 | 48 | void USB_BSP_Init(USB_CORE_HANDLE *pdev) 49 | { 50 | /* Enable USB clock */ 51 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); 52 | 53 | #if defined USB_CLOCK_SOURCE_CRS 54 | 55 | /*For using CRS, you need to do the following: 56 | - Enable HSI48 (managed by the SystemInit() function at the application startup) 57 | - Select HSI48 as USB clock 58 | - Enable CRS clock 59 | - Set AUTOTRIMEN 60 | - Set CEN 61 | */ 62 | 63 | /* Select HSI48 as USB clock */ 64 | RCC_USBCLKConfig(RCC_USBCLK_HSI48); 65 | 66 | /* Configure the Clock Recovery System */ 67 | CRS_Config(); 68 | #else 69 | /* Configure PLL to be used as USB clock: 70 | - Enable HSE external clock (for this example the system is clocked by HSI48 71 | managed by the SystemInit() function at the application startup) 72 | - Enable PLL 73 | - Select PLL as USB clock */ 74 | /* Enable HSE */ 75 | RCC_HSEConfig(RCC_HSE_ON); 76 | 77 | /* Wait till HSE is ready */ 78 | while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) 79 | {} 80 | 81 | /* Enable PLL */ 82 | RCC_PLLCmd(ENABLE); 83 | 84 | /* Wait till PLL is ready */ 85 | while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) 86 | {} 87 | 88 | /* Configure USBCLK from PLL clock */ 89 | RCC_USBCLKConfig(RCC_USBCLK_PLLCLK); 90 | #endif /*USB_CLOCK_SOURCE_CRS */ 91 | 92 | #ifdef USB_DEVICE_LOW_PWR_MGMT_SUPPORT 93 | 94 | /* Enable the PWR clock */ 95 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 96 | 97 | /* EXTI line 18 is connected to the USB Wakeup from suspend event */ 98 | EXTI_ClearITPendingBit(EXTI_Line18); 99 | EXTI_InitStructure.EXTI_Line = EXTI_Line18; 100 | /*Must Configure the EXTI Line 18 to be sensitive to rising edge*/ 101 | EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; 102 | EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 103 | EXTI_InitStructure.EXTI_LineCmd = ENABLE; 104 | EXTI_Init(&EXTI_InitStructure); 105 | #endif /*USB_DEVICE_LOW_PWR_MGMT_SUPPORT */ 106 | 107 | } 108 | 109 | /** 110 | * @brief Enable USB Global interrupt 111 | * @param None 112 | * @retval None 113 | */ 114 | void USB_BSP_EnableInterrupt(USB_CORE_HANDLE *pdev) 115 | { 116 | NVIC_InitTypeDef NVIC_InitStructure; 117 | 118 | /* Enable the USB interrupt */ 119 | NVIC_InitStructure.NVIC_IRQChannel = USB_IRQn; 120 | NVIC_InitStructure.NVIC_IRQChannelPriority = 1; 121 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 122 | NVIC_Init(&NVIC_InitStructure); 123 | } 124 | 125 | #if defined USB_CLOCK_SOURCE_CRS 126 | 127 | /** 128 | * @brief Configure CRS peripheral to automatically trim the HSI 129 | * oscillator according to USB SOF 130 | * @param None 131 | * @retval None 132 | */ 133 | static void CRS_Config(void) 134 | { 135 | /*Enable CRS Clock*/ 136 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_CRS, ENABLE); 137 | 138 | /* Select USB SOF as synchronization source */ 139 | CRS_SynchronizationSourceConfig(CRS_SYNCSource_USB); 140 | 141 | /*Enables the automatic hardware adjustment of TRIM bits: AUTOTRIMEN:*/ 142 | CRS_AutomaticCalibrationCmd(ENABLE); 143 | 144 | /*Enables the oscillator clock for frequency error counter CEN*/ 145 | CRS_FrequencyErrorCounterCmd(ENABLE); 146 | } 147 | #endif 148 | 149 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 150 | -------------------------------------------------------------------------------- /firmware/usb/usb_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file usb_conf.h 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 31-January-2014 7 | * @brief General low level driver configuration 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2014 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __USB_CONF__H__ 30 | #define __USB_CONF__H__ 31 | 32 | /* Includes ------------------------------------------------------------------*/ 33 | 34 | #include "stm32f0xx.h" 35 | 36 | /* Exported types ------------------------------------------------------------*/ 37 | /* Exported constants --------------------------------------------------------*/ 38 | /* Select D+ pullup: internal or external */ 39 | #define INTERNAL_PULLUP 40 | 41 | /* Define if Low power mode is enabled; it allows entering the device into STOP mode 42 | following USB Suspend event, and wakes up after the USB wakeup event is received. */ 43 | /* #define USB_DEVICE_LOW_PWR_MGMT_SUPPORT */ 44 | 45 | /* Configure the USB clock source as HSI48 with Clock Recovery System(CRS)*/ 46 | #define USB_CLOCK_SOURCE_CRS 47 | 48 | /* Endpoints used by the device */ 49 | #define EP_NUM (3) /* EP0 (IN/OUT) */ 50 | 51 | /* buffer table base address */ 52 | #define BTABLE_ADDRESS (0x000) 53 | 54 | /* EP0, RX/TX buffers base address */ 55 | #define ENDP0_RX_ADDRESS (0x40) 56 | #define ENDP0_TX_ADDRESS (0x80) 57 | 58 | #define BULK_IN_TX_ADDRESS (0xC0) 59 | #define BULK_OUT_RX_ADDRESS (0x110) 60 | 61 | /* Exported macro ------------------------------------------------------------*/ 62 | /* Exported functions ------------------------------------------------------- */ 63 | 64 | #endif /* __USB_CONF__H__ */ 65 | 66 | 67 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 68 | -------------------------------------------------------------------------------- /firmware/usb/usbd_class.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "usbd_class.h" 4 | #include "usbd_desc.h" 5 | #include "usb_conf.h" 6 | #include 7 | #include "hal.h" 8 | #include "main.h" 9 | 10 | #define MAX_PACKET_SIZE 64 11 | 12 | static int need_zlp = 0; 13 | static int packet_sent = 0; 14 | static int rx_open = 0; 15 | static int16_t tx_buf[MAX_PACKET_SIZE / sizeof(int16_t)]; 16 | static int8_t rx_buf[MAX_PACKET_SIZE / sizeof(int8_t)]; 17 | static uint8_t bRequest; 18 | static uint8_t initialized = 0; 19 | 20 | static uint8_t init_cb(void* pdev, uint8_t cfgidx) { 21 | DCD_PMA_Config(pdev, IN_EP, USB_SNG_BUF, BULK_IN_TX_ADDRESS); 22 | DCD_PMA_Config(pdev, OUT_EP, USB_SNG_BUF, BULK_OUT_RX_ADDRESS); 23 | 24 | // Open EPs 25 | DCD_EP_Open(pdev, IN_EP, MAX_PACKET_SIZE, USB_EP_BULK); 26 | DCD_EP_Open(pdev, OUT_EP, MAX_PACKET_SIZE, USB_EP_BULK); 27 | 28 | initialized = 1; 29 | 30 | return USBD_OK; 31 | } 32 | 33 | static uint8_t deinit_cb(void* pdev, uint8_t cfgidx) { 34 | /* Close EP IN */ 35 | DCD_EP_Close(pdev, IN_EP); 36 | DCD_EP_Close(pdev, OUT_EP); 37 | 38 | return USBD_OK; 39 | } 40 | 41 | static uint8_t setup_cb(void* pdev, USB_SETUP_REQ* req) { 42 | // Only accept vendor requests 43 | if((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_VENDOR) { 44 | USBD_CtlError(pdev, req); 45 | return USBD_FAIL; 46 | } 47 | 48 | bRequest = req->bRequest; 49 | 50 | switch(req->bRequest) { 51 | case REQUEST_LED_READ: 52 | transition(STATE_REMOTE); 53 | if(req->wValue) { 54 | led_read_on(); 55 | } else { 56 | led_read_off(); 57 | } 58 | return USBD_OK; 59 | case REQUEST_LED_WRITE: 60 | transition(STATE_REMOTE); 61 | if(req->wValue) { 62 | led_write_on(); 63 | } else { 64 | led_write_off(); 65 | } 66 | return USBD_OK; 67 | case REQUEST_LED_SPOOF: 68 | transition(STATE_REMOTE); 69 | if(req->wValue) { 70 | led_spoof_on(); 71 | } else { 72 | led_spoof_off(); 73 | } 74 | return USBD_OK; 75 | case REQUEST_COIL_DRIVE: 76 | transition(STATE_REMOTE); 77 | if(req->wValue) { 78 | coil_tune(); 79 | coil_drive(); 80 | } else { 81 | coil_float(); 82 | } 83 | return USBD_OK; 84 | case REQUEST_COIL_TUNE: 85 | transition(STATE_REMOTE); 86 | if(req->wValue) { 87 | coil_tune(); 88 | } else { 89 | coil_float(); 90 | coil_detune(); 91 | } 92 | return USBD_OK; 93 | case REQUEST_STREAM_READ: 94 | transition(STATE_REMOTE); 95 | if(req->wValue) { 96 | stream_read_enable(); 97 | } else { 98 | stream_read_disable(); 99 | } 100 | return USBD_OK; 101 | case REQUEST_STREAM_WRITE: 102 | transition(STATE_REMOTE); 103 | if(req->wValue) { 104 | stream_write_enable(); 105 | } else { 106 | stream_write_disable(); 107 | } 108 | return USBD_OK; 109 | case REQUEST_LATENCY: 110 | transition(STATE_REMOTE); 111 | set_latency(req->wValue); 112 | return USBD_OK; 113 | default: 114 | return USBD_FAIL; 115 | } 116 | } 117 | 118 | static uint8_t ctl_rx_cb(void *pdev) { 119 | return USBD_FAIL; 120 | } 121 | 122 | const uint8_t config_descriptor[] = { 123 | 0x09, /* bLength: Configuration Descriptor size */ 124 | USB_CONFIGURATION_DESCRIPTOR_TYPE , /* bDescriptorType: Configuration */ 125 | 0x20, /* wTotalLength (LSB) */ 126 | 0x00, /* wTotalLength (MSB) */ 127 | 0x01, /* bNumberInterfaces: 1 interface */ 128 | 0x01, /* bConfigurationValue */ 129 | 0x00, /* iConfiguration: Index of string descriptor for this config */ 130 | 0x80, /* bmAttributes: bus powered */ 131 | 0x32, /* bMaxPower: 100 mA */ 132 | 133 | 0x09, /* bLength: interface descriptor size */ 134 | USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ 135 | 0x00, /* bInterfaceNumber: Number of Interface */ 136 | 0x00, /* bAlternateSetting: Alternate setting */ 137 | 0x02, /* bNumEndpoints: one endpoint */ 138 | 0xFF, /* bInterfaceClass: user's interface for vendor class */ 139 | 0x00, /* bInterfaceSubClass : */ 140 | 0x00, /* nInterfaceProtocol : None */ 141 | 0x05, /* iInterface: */ 142 | 143 | /*Endpoint IN Descriptor*/ 144 | 0x07, /* bLength: Endpoint Descriptor size */ 145 | USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ 146 | IN_EP, /* bEndpointAddress */ 147 | 0x02, /* bmAttributes: Bulk */ 148 | LOBYTE(MAX_PACKET_SIZE), /* wMaxPacketSize: */ 149 | HIBYTE(MAX_PACKET_SIZE), 150 | 0x00, /* bInterval: ignore for Bulk transfer */ 151 | 152 | /*Endpoint IN Descriptor*/ 153 | 0x07, /* bLength: Endpoint Descriptor size */ 154 | USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ 155 | OUT_EP, /* bEndpointAddress */ 156 | 0x02, /* bmAttributes: Bulk */ 157 | LOBYTE(MAX_PACKET_SIZE), /* wMaxPacketSize: */ 158 | HIBYTE(MAX_PACKET_SIZE), 159 | 0x00 /* bInterval: ignore for Bulk transfer */ 160 | }; 161 | 162 | static uint8_t* config_cb(uint8_t speed, uint16_t* length) { 163 | *length = sizeof(config_descriptor); 164 | return (uint8_t*)config_descriptor; 165 | } 166 | 167 | static void try_tx(void* pdev) { 168 | if(packet_sent) return; 169 | 170 | int samples_available = stream_read_available(); 171 | 172 | if(samples_available >= MAX_PACKET_SIZE / sizeof(int16_t)) { 173 | stream_read(tx_buf, MAX_PACKET_SIZE / sizeof(int16_t)); 174 | need_zlp = 1; 175 | DCD_EP_Tx(pdev, IN_EP, (uint8_t*)tx_buf, MAX_PACKET_SIZE); 176 | packet_sent = 1; 177 | } else if(stream_read_enabled == 0 && (samples_available > 0 || need_zlp)) { 178 | stream_read(tx_buf, samples_available); 179 | need_zlp = 0; 180 | DCD_EP_Tx(pdev, IN_EP, (uint8_t*)tx_buf, samples_available * sizeof(int16_t)); 181 | packet_sent = 1; 182 | } 183 | } 184 | 185 | static void try_rx(void *pdev) { 186 | if(rx_open) return; 187 | 188 | uint16_t free_space = stream_write_space(); 189 | 190 | // If 64 bytes of space are free in TX buffer, open the EP 191 | if(free_space >= MAX_PACKET_SIZE / sizeof(uint8_t)) { 192 | DCD_EP_PrepareRx(pdev, OUT_EP, (uint8_t*)rx_buf, MAX_PACKET_SIZE); 193 | rx_open = 1; 194 | } 195 | } 196 | 197 | static uint8_t tx_cb(void *pdev, uint8_t epnum) { 198 | // If 64 bytes available for read, send them out 199 | packet_sent = 0; 200 | try_tx(pdev); 201 | 202 | return USBD_OK; 203 | } 204 | 205 | static uint8_t rx_cb(void *pdev, uint8_t epnum) { 206 | // Take the newly received data and put it in the write stream 207 | uint16_t length = ((USB_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count; 208 | stream_write(rx_buf, length); 209 | rx_open = 0; 210 | try_rx(pdev); 211 | return USBD_OK; 212 | } 213 | 214 | static uint8_t sof_cb(void *pdev) { 215 | if(!initialized) return USBD_OK; 216 | 217 | try_tx(pdev); 218 | try_rx(pdev); 219 | 220 | return USBD_OK; 221 | } 222 | 223 | USBD_Class_cb_TypeDef USBD_custom_cb = { 224 | init_cb, 225 | deinit_cb, 226 | setup_cb, 227 | NULL, /*EP0_TxSent*/ 228 | ctl_rx_cb, /*EP0_RxReady*/ 229 | tx_cb, /*DataIn*/ 230 | rx_cb, /*DataOut*/ 231 | sof_cb, /*SOF */ 232 | config_cb, 233 | }; 234 | -------------------------------------------------------------------------------- /firmware/usb/usbd_class.h: -------------------------------------------------------------------------------- 1 | #include "usbd_core.h" 2 | 3 | #define USB_REQ_TYPE_VENDOR 0x40 4 | 5 | extern USBD_Class_cb_TypeDef USBD_custom_cb; 6 | 7 | #define REQUEST_LED_READ 0x20 8 | #define REQUEST_LED_WRITE 0x21 9 | #define REQUEST_LED_SPOOF 0x22 10 | #define REQUEST_COIL_DRIVE 0x23 11 | #define REQUEST_COIL_TUNE 0x24 12 | #define REQUEST_STREAM_READ 0x25 13 | #define REQUEST_STREAM_WRITE 0x26 14 | #define REQUEST_LATENCY 0x27 15 | -------------------------------------------------------------------------------- /firmware/usb/usbd_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file usbd_conf.h 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 31-January-2014 7 | * @brief USB Device configuration file 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2014 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __USBD_CONF__H__ 30 | #define __USBD_CONF__H__ 31 | 32 | /* Includes ------------------------------------------------------------------*/ 33 | #include "usb_conf.h" 34 | 35 | /* Exported types ------------------------------------------------------------*/ 36 | /* Exported constants --------------------------------------------------------*/ 37 | #define USBD_CFG_MAX_NUM 1 38 | #define USBD_ITF_MAX_NUM 1 39 | #define USB_MAX_STR_DESC_SIZ 64 40 | 41 | #define MAX_PACKET_SIZE 64 42 | #define IN_EP 0x81 /* EP1 for data IN */ 43 | #define OUT_EP 0x02 /* EP2 for data OUT */ 44 | 45 | /* Exported macro ------------------------------------------------------------*/ 46 | /* Exported functions ------------------------------------------------------- */ 47 | 48 | #endif /* __USBD_CONF__H__ */ 49 | 50 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 51 | 52 | 53 | /** 54 | * @} 55 | */ 56 | 57 | -------------------------------------------------------------------------------- /firmware/usb/usbd_desc.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file usbd_desc.c 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 31-January-2014 7 | * @brief This file provides the USBD descriptors and string formating method. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2014 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "usbd_desc.h" 30 | 31 | /* Private typedef -----------------------------------------------------------*/ 32 | /* Private define ------------------------------------------------------------*/ 33 | #define USBD_VID 0xFFFF 34 | #define USBD_PID 0x2951 35 | 36 | #define USBD_LANGID_STRING 0x409 37 | #define USBD_MANUFACTURER_STRING "Eric Van Albert" 38 | 39 | #define USBD_PRODUCT_FS_STRING "RFID Tool" 40 | 41 | #define USBD_CONFIGURATION_FS_STRING "Default" 42 | #define USBD_INTERFACE_FS_STRING "Default" 43 | 44 | /* Private macro -------------------------------------------------------------*/ 45 | /* Private variables ---------------------------------------------------------*/ 46 | 47 | USBD_DEVICE USR_desc = 48 | { 49 | USBD_USR_DeviceDescriptor, 50 | USBD_USR_LangIDStrDescriptor, 51 | USBD_USR_ManufacturerStrDescriptor, 52 | USBD_USR_ProductStrDescriptor, 53 | USBD_USR_SerialStrDescriptor, 54 | USBD_USR_ConfigStrDescriptor, 55 | USBD_USR_InterfaceStrDescriptor, 56 | }; 57 | 58 | /* USB Standard Device Descriptor */ 59 | const uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] = 60 | { 61 | 0x12, /*bLength */ 62 | USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/ 63 | 0x00, /*bcdUSB */ 64 | 0x02, 65 | 0x00, /*bDeviceClass*/ 66 | 0x00, /*bDeviceSubClass*/ 67 | 0x00, /*bDeviceProtocol*/ 68 | USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ 69 | LOBYTE(USBD_VID), /*idVendor*/ 70 | HIBYTE(USBD_VID), /*idVendor*/ 71 | LOBYTE(USBD_PID), /*idVendor*/ 72 | HIBYTE(USBD_PID), /*idVendor*/ 73 | 0x00, /*bcdDevice rel. 2.00*/ 74 | 0x02, 75 | USBD_IDX_MFC_STR, /*Index of manufacturer string*/ 76 | USBD_IDX_PRODUCT_STR, /*Index of product string*/ 77 | USBD_IDX_SERIAL_STR, /*Index of serial number string*/ 78 | USBD_CFG_MAX_NUM /*bNumConfigurations*/ 79 | }; /* USB_DeviceDescriptor */ 80 | 81 | /* USB Standard Device Descriptor */ 82 | const uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] = 83 | { 84 | USB_LEN_DEV_QUALIFIER_DESC, 85 | USB_DESC_TYPE_DEVICE_QUALIFIER, 86 | 0x00, 87 | 0x02, 88 | 0x00, 89 | 0x00, 90 | 0x00, 91 | 0x40, 92 | 0x01, 93 | 0x00, 94 | }; 95 | 96 | /* USB Standard Device Descriptor */ 97 | const uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID] = 98 | { 99 | USB_SIZ_STRING_LANGID, 100 | USB_DESC_TYPE_STRING, 101 | LOBYTE(USBD_LANGID_STRING), 102 | HIBYTE(USBD_LANGID_STRING), 103 | }; 104 | 105 | uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] = 106 | { 107 | USB_SIZ_STRING_SERIAL, /* bLength */ 108 | USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ 109 | }; 110 | 111 | /* Private function prototypes -----------------------------------------------*/ 112 | static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len); 113 | 114 | /* Private functions ---------------------------------------------------------*/ 115 | 116 | /** 117 | * @brief return the device descriptor 118 | * @param speed : current device speed 119 | * @param length : pointer to data length variable 120 | * @retval pointer to descriptor buffer 121 | */ 122 | uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length) 123 | { 124 | *length = sizeof(USBD_DeviceDesc); 125 | return (uint8_t*)USBD_DeviceDesc; 126 | } 127 | 128 | /** 129 | * @brief return the LangID string descriptor 130 | * @param speed : current device speed 131 | * @param length : pointer to data length variable 132 | * @retval pointer to descriptor buffer 133 | */ 134 | uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length) 135 | { 136 | *length = sizeof(USBD_LangIDDesc); 137 | return (uint8_t*)USBD_LangIDDesc; 138 | } 139 | 140 | /** 141 | * @brief return the product string descriptor 142 | * @param speed : current device speed 143 | * @param length : pointer to data length variable 144 | * @retval pointer to descriptor buffer 145 | */ 146 | uint8_t * USBD_USR_ProductStrDescriptor( uint8_t speed , uint16_t *length) 147 | { 148 | USBD_GetString ( (uint8_t*)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length); 149 | return USBD_StrDesc; 150 | } 151 | 152 | /** 153 | * @brief return the manufacturer string descriptor 154 | * @param speed : current device speed 155 | * @param length : pointer to data length variable 156 | * @retval pointer to descriptor buffer 157 | */ 158 | uint8_t * USBD_USR_ManufacturerStrDescriptor( uint8_t speed , uint16_t *length) 159 | { 160 | USBD_GetString ( (uint8_t*)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); 161 | return USBD_StrDesc; 162 | } 163 | 164 | /** 165 | * @brief return the serial number string descriptor 166 | * @param speed : current device speed 167 | * @param length : pointer to data length variable 168 | * @retval pointer to descriptor buffer 169 | */ 170 | uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length) 171 | { 172 | *length = USB_SIZ_STRING_SERIAL; 173 | return USBD_StringSerial; 174 | } 175 | 176 | /** 177 | * @brief return the configuration string descriptor 178 | * @param speed : current device speed 179 | * @param length : pointer to data length variable 180 | * @retval pointer to descriptor buffer 181 | */ 182 | uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length) 183 | { 184 | USBD_GetString ( (uint8_t*)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length); 185 | return USBD_StrDesc; 186 | } 187 | 188 | 189 | /** 190 | * @brief return the interface string descriptor 191 | * @param speed : current device speed 192 | * @param length : pointer to data length variable 193 | * @retval pointer to descriptor buffer 194 | */ 195 | uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length) 196 | { 197 | USBD_GetString ( (uint8_t*)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length); 198 | return USBD_StrDesc; 199 | } 200 | 201 | /** 202 | * @brief Create the serial number string descriptor 203 | * @param None 204 | * @retval None 205 | */ 206 | void Get_SerialNum(void) 207 | { 208 | uint32_t Device_Serial0, Device_Serial1, Device_Serial2; 209 | 210 | Device_Serial0 = *(uint32_t*)Device1_Identifier; 211 | Device_Serial1 = *(uint32_t*)Device2_Identifier; 212 | Device_Serial2 = *(uint32_t*)Device3_Identifier; 213 | 214 | Device_Serial0 += Device_Serial2; 215 | 216 | if (Device_Serial0 != 0) 217 | { 218 | IntToUnicode (Device_Serial0, &USBD_StringSerial[2] ,8); 219 | IntToUnicode (Device_Serial1, &USBD_StringSerial[18] ,4); 220 | } 221 | } 222 | 223 | /** 224 | * @brief Convert Hex 32Bits value into char 225 | * @param value: value to convert 226 | * @param pbuf: pointer to the buffer 227 | * @param len: buffer length 228 | * @retval None 229 | */ 230 | static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len) 231 | { 232 | uint8_t idx = 0; 233 | 234 | for( idx = 0 ; idx < len ; idx ++) 235 | { 236 | if( ((value >> 28)) < 0xA ) 237 | { 238 | pbuf[ 2* idx] = (value >> 28) + '0'; 239 | } 240 | else 241 | { 242 | pbuf[2* idx] = (value >> 28) + 'A' - 10; 243 | } 244 | 245 | value = value << 4; 246 | 247 | pbuf[ 2* idx + 1] = 0; 248 | } 249 | } 250 | 251 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 252 | -------------------------------------------------------------------------------- /firmware/usb/usbd_desc.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file usbd_desc.h 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 31-January-2014 7 | * @brief header file for the usbd_desc.c file 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2014 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | 30 | #ifndef __USB_DESC_H 31 | #define __USB_DESC_H 32 | 33 | /* Includes ------------------------------------------------------------------*/ 34 | #include "usbd_req.h" 35 | 36 | 37 | /* Exported types ------------------------------------------------------------*/ 38 | /* Exported constants --------------------------------------------------------*/ 39 | #define USB_DEVICE_DESCRIPTOR_TYPE 0x01 40 | #define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 41 | #define USB_STRING_DESCRIPTOR_TYPE 0x03 42 | #define USB_INTERFACE_DESCRIPTOR_TYPE 0x04 43 | #define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05 44 | #define USB_SIZ_DEVICE_DESC 18 45 | #define USB_SIZ_STRING_LANGID 4 46 | #define USB_SIZ_STRING_SERIAL 26 47 | 48 | #define Device1_Identifier (0x1FFFF7AC) 49 | #define Device2_Identifier (0x1FFFF7B0) 50 | #define Device3_Identifier (0x1FFFF7B4) 51 | 52 | /* Exported macro ------------------------------------------------------------*/ 53 | /* Exported variables --------------------------------------------------------*/ 54 | extern uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ]; 55 | extern uint8_t USBD_OtherSpeedCfgDesc[USB_LEN_CFG_DESC]; 56 | extern USBD_DEVICE USR_desc; 57 | extern uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL]; 58 | 59 | /* Exported functions ------------------------------------------------------- */ 60 | void Get_SerialNum(void); 61 | uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length); 62 | uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length); 63 | uint8_t * USBD_USR_ManufacturerStrDescriptor ( uint8_t speed , uint16_t *length); 64 | uint8_t * USBD_USR_ProductStrDescriptor ( uint8_t speed , uint16_t *length); 65 | uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length); 66 | uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length); 67 | uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length); 68 | 69 | #ifdef USB_SUPPORT_USER_STRING_DESC 70 | uint8_t * USBD_USR_USRStringDesc (uint8_t speed, uint8_t idx , uint16_t *length); 71 | #endif /* USB_SUPPORT_USER_STRING_DESC */ 72 | 73 | #endif /* __USBD_DESC_H */ 74 | 75 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 76 | -------------------------------------------------------------------------------- /firmware/usb/usbd_pwr.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file usbd_pwr.c 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 31-January-2014 7 | * @brief This file provides functions for power management 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2014 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "usbd_pwr.h" 30 | 31 | /* Private typedef -----------------------------------------------------------*/ 32 | /* Private define ------------------------------------------------------------*/ 33 | /* Private macro -------------------------------------------------------------*/ 34 | /* Private variables ---------------------------------------------------------*/ 35 | struct 36 | { 37 | __IO RESUME_STATE eState; 38 | __IO uint8_t bESOFcnt; 39 | } 40 | ResumeS; 41 | 42 | __IO uint32_t remotewakeupon=0; 43 | 44 | /* Private function prototypes -----------------------------------------------*/ 45 | /* Private functions ---------------------------------------------------------*/ 46 | 47 | /** 48 | * @brief Sets suspend mode operating conditions 49 | * @param None 50 | * @retval USB_SUCCESS 51 | */ 52 | void Suspend(void) 53 | { 54 | uint16_t wCNTR; 55 | 56 | /*Store CNTR value */ 57 | wCNTR = _GetCNTR(); 58 | /* Set FSUSP bit in USB_CNTR register*/ 59 | wCNTR |= CNTR_FSUSP; 60 | _SetCNTR(wCNTR); 61 | 62 | /* force low-power mode in the macrocell */ 63 | wCNTR = _GetCNTR(); 64 | wCNTR |= CNTR_LPMODE; 65 | _SetCNTR(wCNTR); 66 | 67 | #ifdef USB_DEVICE_LOW_PWR_MGMT_SUPPORT 68 | 69 | /* enter system in STOP mode, only when wakeup flag in not set */ 70 | if((_GetISTR()&ISTR_WKUP)==0) 71 | { 72 | /*Enter STOP mode with SLEEPONEXIT*/ 73 | PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_SLEEPONEXIT); 74 | } 75 | else 76 | { 77 | /* Clear Wakeup flag */ 78 | _SetISTR(CLR_WKUP); 79 | /* clear FSUSP to abort entry in suspend mode */ 80 | wCNTR = _GetCNTR(); 81 | wCNTR&=~CNTR_FSUSP; 82 | _SetCNTR(wCNTR); 83 | } 84 | #endif 85 | } 86 | 87 | /** 88 | * @brief Handles wake-up restoring normal operations 89 | * @param None 90 | * @retval USB_SUCCESS 91 | */ 92 | void Resume_Init(void) 93 | { 94 | uint16_t wCNTR; 95 | 96 | /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */ 97 | /* restart the clocks */ 98 | /* ... */ 99 | 100 | /* CNTR_LPMODE = 0 */ 101 | wCNTR = _GetCNTR(); 102 | wCNTR &= (~CNTR_LPMODE); 103 | _SetCNTR(wCNTR); 104 | #ifdef USB_DEVICE_LOW_PWR_MGMT_SUPPORT 105 | /* restore full power */ 106 | /* ... on connected devices */ 107 | Leave_LowPowerMode(); 108 | #endif 109 | /* reset FSUSP bit */ 110 | _SetCNTR(IMR_MSK); 111 | 112 | } 113 | 114 | 115 | /** 116 | * @brief Provides the state machine handling resume operations and 117 | * timing sequence. The control is based on the Resume structure 118 | * variables and on the ESOF interrupt calling this subroutine 119 | * without changing machine state. 120 | * @param a state machine value (RESUME_STATE) 121 | * RESUME_ESOF doesn't change ResumeS.eState allowing 122 | * decrementing of the ESOF counter in different states. 123 | * @retval Status 124 | */ 125 | void Resume(RESUME_STATE eResumeSetVal) 126 | { 127 | uint16_t wCNTR; 128 | 129 | if (eResumeSetVal != RESUME_ESOF) 130 | ResumeS.eState = eResumeSetVal; 131 | switch (ResumeS.eState) 132 | { 133 | case RESUME_EXTERNAL: 134 | 135 | if (remotewakeupon ==0) 136 | { 137 | Resume_Init(); 138 | ResumeS.eState = RESUME_OFF; 139 | } 140 | else /* RESUME detected during the RemoteWAkeup signalling => keep RemoteWakeup handling*/ 141 | { 142 | ResumeS.eState = RESUME_ON; 143 | } 144 | break; 145 | case RESUME_INTERNAL: 146 | Resume_Init(); 147 | ResumeS.eState = RESUME_START; 148 | remotewakeupon = 1; 149 | break; 150 | case RESUME_LATER: 151 | ResumeS.bESOFcnt = 2; 152 | ResumeS.eState = RESUME_WAIT; 153 | break; 154 | case RESUME_WAIT: 155 | ResumeS.bESOFcnt--; 156 | if (ResumeS.bESOFcnt == 0) 157 | ResumeS.eState = RESUME_START; 158 | break; 159 | case RESUME_START: 160 | wCNTR = _GetCNTR(); 161 | wCNTR |= CNTR_RESUME; 162 | _SetCNTR(wCNTR); 163 | ResumeS.eState = RESUME_ON; 164 | ResumeS.bESOFcnt = 10; 165 | break; 166 | case RESUME_ON: 167 | ResumeS.bESOFcnt--; 168 | if (ResumeS.bESOFcnt == 0) 169 | { 170 | wCNTR = _GetCNTR(); 171 | wCNTR &= (~CNTR_RESUME); 172 | _SetCNTR(wCNTR); 173 | ResumeS.eState = RESUME_OFF; 174 | remotewakeupon = 0; 175 | } 176 | break; 177 | case RESUME_OFF: 178 | case RESUME_ESOF: 179 | default: 180 | ResumeS.eState = RESUME_OFF; 181 | break; 182 | } 183 | } 184 | 185 | /** 186 | * @brief Restores system clocks and power while exiting suspend mode 187 | * @param None 188 | * @retval None 189 | */ 190 | void Leave_LowPowerMode(void) 191 | { 192 | #if defined USB_CLOCK_SOURCE_CRS 193 | /* Enable HSI48 oscillator */ 194 | RCC_HSI48Cmd(ENABLE); 195 | 196 | /* Wait till HSI48RDYF is set */ 197 | while(RCC_GetFlagStatus(RCC_FLAG_HSI48RDY) == RESET) 198 | { 199 | } 200 | /* Select HSI48 as system clock source */ 201 | RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI48); 202 | 203 | #else 204 | 205 | /* After wake-up from STOP mode restore system clock (system clock = PLL clock 206 | from HSE source )*/ 207 | /* Enable HSE */ 208 | RCC_HSEConfig(RCC_HSE_ON); 209 | 210 | /* Wait till HSE is ready */ 211 | while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) 212 | {} 213 | 214 | /* Enable PLL */ 215 | RCC_PLLCmd(ENABLE); 216 | 217 | /* Wait till PLL is ready */ 218 | while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) 219 | {} 220 | 221 | /* Select PLL as system clock source */ 222 | RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 223 | 224 | /* Wait till PLL is used as system clock source */ 225 | while (RCC_GetSYSCLKSource() != 0x08) 226 | {} 227 | #endif /* USB_CLOCK_SOURCE_CRS */ 228 | 229 | /*Low Power Sleep on Exit Disabled*/ 230 | NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT, DISABLE); 231 | } 232 | 233 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 234 | -------------------------------------------------------------------------------- /firmware/usb/usbd_usr.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file usbd_usr.c 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 31-January-2014 7 | * @brief This file contains user callback structure for USB events Management 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2014 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "usbd_usr.h" 30 | 31 | USBD_Usr_cb_TypeDef USR_cb = 32 | { 33 | USBD_USR_Init, 34 | USBD_USR_DeviceReset, 35 | USBD_USR_DeviceConfigured, 36 | USBD_USR_DeviceSuspended, 37 | USBD_USR_DeviceResumed, 38 | }; 39 | 40 | /** 41 | * @brief Device lib initialization 42 | * @param None 43 | * @retval None 44 | */ 45 | void USBD_USR_Init(void) 46 | { 47 | // Nothing to do here 48 | } 49 | 50 | /** 51 | * @brief Reset Event 52 | * @param speed : device speed 53 | * @retval None 54 | */ 55 | void USBD_USR_DeviceReset(uint8_t speed ) 56 | { 57 | } 58 | 59 | /** 60 | * @brief Configuration Event 61 | * @param None 62 | * @retval None 63 | */ 64 | void USBD_USR_DeviceConfigured (void) 65 | { 66 | } 67 | 68 | /** 69 | * @brief Device suspend Event 70 | * @param None 71 | * @retval None 72 | */ 73 | void USBD_USR_DeviceSuspended(void) 74 | { 75 | } 76 | 77 | 78 | /** 79 | * @brief Device resume Event 80 | * @param None 81 | * @retval None 82 | */ 83 | void USBD_USR_DeviceResumed(void) 84 | { 85 | } 86 | 87 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 88 | -------------------------------------------------------------------------------- /fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name tact)(type Legacy)(uri /home/eric/mystuff/documents/kicad/custom/tact.mod)(options "")(descr "")) 3 | (lib (name custom)(type Legacy)(uri /home/eric/mystuff/documents/kicad/custom/custom.mod)(options "")(descr "")) 4 | ) 5 | -------------------------------------------------------------------------------- /gerber/rfid-B.Cu.gbl: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Copper,L4,Bot,Signal* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW 4.0.2-stable) date Sun 10 Apr 2016 09:46:26 PM EDT* 5 | %MOMM*% 6 | G01* 7 | G04 APERTURE LIST* 8 | %ADD10C,0.150000*% 9 | %ADD11R,1.727200X2.032000*% 10 | %ADD12O,1.727200X2.032000*% 11 | %ADD13R,1.500000X1.500000*% 12 | %ADD14C,1.500000*% 13 | %ADD15R,1.450000X0.450000*% 14 | %ADD16R,2.032000X1.727200*% 15 | %ADD17O,2.032000X1.727200*% 16 | %ADD18R,0.600000X0.500000*% 17 | %ADD19R,0.500000X0.600000*% 18 | %ADD20O,1.250000X0.950000*% 19 | %ADD21O,1.000000X1.550000*% 20 | %ADD22R,0.800100X0.800100*% 21 | %ADD23R,0.400000X0.600000*% 22 | %ADD24R,0.600000X0.400000*% 23 | %ADD25R,0.600000X0.700000*% 24 | %ADD26R,0.700000X0.600000*% 25 | %ADD27C,0.762000*% 26 | %ADD28C,0.203200*% 27 | %ADD29C,1.000000*% 28 | %ADD30C,0.500000*% 29 | G04 APERTURE END LIST* 30 | D10* 31 | D11* 32 | X176657000Y-137033000D03* 33 | D12* 34 | X179197000Y-137033000D03* 35 | X181737000Y-137033000D03* 36 | X184277000Y-137033000D03* 37 | D13* 38 | X198882000Y-135128000D03* 39 | D14* 40 | X196342000Y-135128000D03* 41 | D13* 42 | X221107000Y-142113000D03* 43 | D14* 44 | X221107000Y-139573000D03* 45 | D15* 46 | X190598000Y-144444000D03* 47 | X190598000Y-143794000D03* 48 | X190598000Y-143144000D03* 49 | X190598000Y-142494000D03* 50 | X190598000Y-141844000D03* 51 | X190598000Y-141194000D03* 52 | X190598000Y-140544000D03* 53 | X196498000Y-140544000D03* 54 | X196498000Y-141194000D03* 55 | X196498000Y-141844000D03* 56 | X196498000Y-142494000D03* 57 | X196498000Y-143144000D03* 58 | X196498000Y-143794000D03* 59 | X196498000Y-144444000D03* 60 | D16* 61 | X220357000Y-151638000D03* 62 | D17* 63 | X220357000Y-149098000D03* 64 | X220357000Y-146558000D03* 65 | D18* 66 | X194606000Y-138938000D03* 67 | X193506000Y-138938000D03* 68 | D19* 69 | X189230000Y-143468000D03* 70 | X189230000Y-144568000D03* 71 | D20* 72 | X195111100Y-150075460D03* 73 | X200111100Y-150075460D03* 74 | D21* 75 | X194111100Y-152775460D03* 76 | X201111100Y-152775460D03* 77 | D22* 78 | X204150000Y-142986760D03* 79 | X202250000Y-142986760D03* 80 | X203200000Y-140987780D03* 81 | X204200760Y-136972000D03* 82 | X204200760Y-138872000D03* 83 | X202201780Y-137922000D03* 84 | X208010760Y-136972000D03* 85 | X208010760Y-138872000D03* 86 | X206011780Y-137922000D03* 87 | D23* 88 | X196538000Y-137160000D03* 89 | X195638000Y-137160000D03* 90 | X196654000Y-138684000D03* 91 | X197554000Y-138684000D03* 92 | D24* 93 | X200660000Y-139388000D03* 94 | X200660000Y-138488000D03* 95 | X211836000Y-136456000D03* 96 | X211836000Y-137356000D03* 97 | D23* 98 | X191066000Y-137160000D03* 99 | X191966000Y-137160000D03* 100 | X194506000Y-137414000D03* 101 | X193606000Y-137414000D03* 102 | X192728000Y-146050000D03* 103 | X191828000Y-146050000D03* 104 | D24* 105 | X198374000Y-143198000D03* 106 | X198374000Y-142298000D03* 107 | D23* 108 | X194368000Y-146050000D03* 109 | X195268000Y-146050000D03* 110 | D24* 111 | X198374000Y-144330000D03* 112 | X198374000Y-145230000D03* 113 | D25* 114 | X199074000Y-137160000D03* 115 | X197674000Y-137160000D03* 116 | X192216000Y-138684000D03* 117 | X190816000Y-138684000D03* 118 | D26* 119 | X210312000Y-137606000D03* 120 | X210312000Y-136206000D03* 121 | D27* 122 | X210566000Y-140716000D03* 123 | X214884000Y-138922000D03* 124 | X203962000Y-145034000D03* 125 | X204978000Y-147574000D03* 126 | X209042000Y-138684000D03* 127 | X204978000Y-145034000D03* 128 | X205994000Y-145034000D03* 129 | X206502000Y-136906000D03* 130 | X198882000Y-138430000D03* 131 | X196596000Y-146050000D03* 132 | X193548000Y-141986000D03* 133 | X191262000Y-146812000D03* 134 | X188222000Y-138938000D03* 135 | X211852000Y-138684000D03* 136 | X206248000Y-148082000D03* 137 | X218948000Y-144780000D03* 138 | X215646000Y-139954000D03* 139 | X198882000Y-151384000D03* 140 | X192024000Y-153416000D03* 141 | X218440000Y-149098000D03* 142 | X211582000Y-150368000D03* 143 | X218948000Y-153416000D03* 144 | X189738000Y-148844000D03* 145 | X194310000Y-143002000D03* 146 | X190246000Y-147066000D03* 147 | X189230000Y-142494000D03* 148 | X207010000Y-145034000D03* 149 | X201168000Y-143002000D03* 150 | X212598000Y-153023000D03* 151 | X207264000Y-148082000D03* 152 | D28* 153 | X210566000Y-140716000D02* 154 | X214376000Y-140716000D01* 155 | D29* 156 | X214884000Y-138938000D02* 157 | X214376000Y-139446000D01* 158 | X214376000Y-139446000D02* 159 | X214376000Y-140716000D01* 160 | D30* 161 | X214884000Y-138922000D02* 162 | X214884000Y-138938000D01* 163 | D29* 164 | X214376000Y-143117000D02* 165 | X220357000Y-149098000D01* 166 | X214376000Y-140716000D02* 167 | X214376000Y-143117000D01* 168 | D28* 169 | X204150000Y-144846000D02* 170 | X204150000Y-142986760D01* 171 | X203962000Y-145034000D02* 172 | X204150000Y-144846000D01* 173 | X204978000Y-147574000D02* 174 | X205740000Y-146812000D01* 175 | X209042000Y-144526000D02* 176 | X209042000Y-138684000D01* 177 | X206756000Y-146812000D02* 178 | X209042000Y-144526000D01* 179 | X205740000Y-146812000D02* 180 | X206756000Y-146812000D01* 181 | X204978000Y-145034000D02* 182 | X204216000Y-145796000D01* 183 | X198940000Y-145796000D02* 184 | X198374000Y-145230000D01* 185 | X204216000Y-145796000D02* 186 | X198940000Y-145796000D01* 187 | X196498000Y-144444000D02* 188 | X196498000Y-144936000D01* 189 | X196792000Y-145230000D02* 190 | X198374000Y-145230000D01* 191 | X196498000Y-144936000D02* 192 | X196792000Y-145230000D01* 193 | X190598000Y-141194000D02* 194 | X189514000Y-141194000D01* 195 | X189484000Y-146050000D02* 196 | X191828000Y-146050000D01* 197 | X188468000Y-145034000D02* 198 | X189484000Y-146050000D01* 199 | X188468000Y-142240000D02* 200 | X188468000Y-145034000D01* 201 | X189514000Y-141194000D02* 202 | X188468000Y-142240000D01* 203 | X197358000Y-146304000D02* 204 | X204724000Y-146304000D01* 205 | X205994000Y-145034000D02* 206 | X204724000Y-146304000D01* 207 | X191828000Y-146108000D02* 208 | X192532000Y-146812000D01* 209 | X192532000Y-146812000D02* 210 | X196850000Y-146812000D01* 211 | X196850000Y-146812000D02* 212 | X197358000Y-146304000D01* 213 | X191828000Y-146108000D02* 214 | X191828000Y-146050000D01* 215 | X190598000Y-140544000D02* 216 | X190598000Y-141194000D01* 217 | D30* 218 | X206011780Y-137922000D02* 219 | X206502000Y-137431780D01* 220 | X206502000Y-137431780D02* 221 | X206502000Y-136906000D01* 222 | D28* 223 | X198882000Y-138430000D02* 224 | X197808000Y-138430000D01* 225 | X197808000Y-138430000D02* 226 | X197554000Y-138684000D01* 227 | X195268000Y-146050000D02* 228 | X196596000Y-146050000D01* 229 | X193548000Y-141986000D02* 230 | X194564000Y-141986000D01* 231 | X195072000Y-142494000D02* 232 | X196498000Y-142494000D01* 233 | X194564000Y-141986000D02* 234 | X195072000Y-142494000D01* 235 | X193548000Y-141986000D02* 236 | X193548000Y-143510000D01* 237 | X189950000Y-145288000D02* 238 | X189230000Y-144568000D01* 239 | X191770000Y-145288000D02* 240 | X189950000Y-145288000D01* 241 | X193548000Y-143510000D02* 242 | X191770000Y-145288000D01* 243 | X193548000Y-138980000D02* 244 | X193548000Y-141986000D01* 245 | X193548000Y-138980000D02* 246 | X193506000Y-138938000D01* 247 | X193606000Y-137414000D02* 248 | X193506000Y-137514000D01* 249 | X193506000Y-137514000D02* 250 | X193506000Y-138938000D01* 251 | X193606000Y-138838000D02* 252 | X193506000Y-138938000D01* 253 | D30* 254 | X211852000Y-138684000D02* 255 | X211836000Y-138684000D01* 256 | D28* 257 | X189230000Y-143468000D02* 258 | X189230000Y-142494000D01* 259 | X189230000Y-142494000D02* 260 | X190598000Y-142494000D01* 261 | X202250000Y-142986760D02* 262 | X202234760Y-143002000D01* 263 | X202234760Y-143002000D02* 264 | X201168000Y-143002000D01* 265 | D30* 266 | X212598000Y-153023000D02* 267 | X212598000Y-152908000D01* 268 | D28* 269 | X194606000Y-138938000D02* 270 | X194606000Y-141012000D01* 271 | X195438000Y-141844000D02* 272 | X196498000Y-141844000D01* 273 | X194606000Y-141012000D02* 274 | X195438000Y-141844000D01* 275 | X194506000Y-137414000D02* 276 | X194606000Y-137514000D01* 277 | X194606000Y-137514000D02* 278 | X194606000Y-138938000D01* 279 | X194506000Y-137414000D02* 280 | X194506000Y-137254402D01* 281 | X194506000Y-137254402D02* 282 | X194056000Y-136804402D01* 283 | X194056000Y-136804402D02* 284 | X192321598Y-136804402D01* 285 | X192321598Y-136804402D02* 286 | X191966000Y-137160000D01* 287 | X194506000Y-138838000D02* 288 | X194606000Y-138938000D01* 289 | D30* 290 | X198882000Y-135128000D02* 291 | X199136000Y-135128000D01* 292 | X199136000Y-135128000D02* 293 | X200088500Y-136080500D01* 294 | X200088500Y-136080500D02* 295 | X201930000Y-137922000D01* 296 | X201930000Y-137922000D02* 297 | X202201780Y-137922000D01* 298 | D28* 299 | X199074000Y-137160000D02* 300 | X199074000Y-137095000D01* 301 | X199074000Y-137095000D02* 302 | X200088500Y-136080500D01* 303 | X190598000Y-144444000D02* 304 | X191852000Y-144444000D01* 305 | X191852000Y-144444000D02* 306 | X192582804Y-143713196D01* 307 | X192582804Y-143713196D02* 308 | X192582804Y-139050804D01* 309 | X192582804Y-139050804D02* 310 | X192216000Y-138684000D01* 311 | X190816000Y-138684000D02* 312 | X190816000Y-139355598D01* 313 | X190816000Y-139355598D02* 314 | X191008000Y-139547598D01* 315 | X190816000Y-137410000D02* 316 | X190816000Y-138684000D01* 317 | X191008000Y-139547598D02* 318 | X191684338Y-139547598D01* 319 | X191684338Y-139547598D02* 320 | X192176402Y-140039662D01* 321 | X192176402Y-140039662D02* 322 | X192176402Y-143357598D01* 323 | X192176402Y-143357598D02* 324 | X191740000Y-143794000D01* 325 | X191740000Y-143794000D02* 326 | X190598000Y-143794000D01* 327 | X191066000Y-137160000D02* 328 | X190816000Y-137410000D01* 329 | X208010760Y-138872000D02* 330 | X208010760Y-138064240D01* 331 | X208010760Y-138064240D02* 332 | X208153000Y-137922000D01* 333 | D30* 334 | X204200760Y-138872000D02* 335 | X208010760Y-138872000D01* 336 | D28* 337 | X211836000Y-137356000D02* 338 | X211586000Y-137606000D01* 339 | X208153000Y-137922000D02* 340 | X209996000Y-137922000D01* 341 | X210312000Y-137606000D02* 342 | X210312000Y-137606000D01* 343 | X209996000Y-137922000D02* 344 | X210312000Y-137606000D01* 345 | X211586000Y-137606000D02* 346 | X210312000Y-137606000D01* 347 | X210312000Y-136206000D02* 348 | X209546000Y-136972000D01* 349 | X210312000Y-136206000D02* 350 | X211586000Y-136206000D01* 351 | X200660000Y-138488000D02* 352 | X200983000Y-138811000D01* 353 | X204150000Y-136972000D02* 354 | X204200760Y-136972000D01* 355 | X203327000Y-137795000D02* 356 | X204150000Y-136972000D01* 357 | X203327000Y-138303000D02* 358 | X203327000Y-137795000D01* 359 | X202819000Y-138811000D02* 360 | X203327000Y-138303000D01* 361 | X200983000Y-138811000D02* 362 | X202819000Y-138811000D01* 363 | X204200760Y-136972000D02* 364 | X205028760Y-136144000D01* 365 | X205028760Y-136144000D02* 366 | X207182760Y-136144000D01* 367 | X207182760Y-136144000D02* 368 | X208010760Y-136972000D01* 369 | X209546000Y-136972000D02* 370 | X208010760Y-136972000D01* 371 | X200683240Y-138488000D02* 372 | X200660000Y-138488000D01* 373 | X200660000Y-138488000D02* 374 | X200718000Y-138430000D01* 375 | X211586000Y-136206000D02* 376 | X211836000Y-136456000D01* 377 | X190598000Y-141844000D02* 378 | X191770000Y-141844000D01* 379 | X191770000Y-141844000D02* 380 | X191770000Y-141732000D01* 381 | X190754000Y-136398000D02* 382 | X189992000Y-137160000D01* 383 | X195638000Y-137160000D02* 384 | X194876000Y-136398000D01* 385 | X190754000Y-136398000D02* 386 | X194876000Y-136398000D01* 387 | X191374000Y-143144000D02* 388 | X190598000Y-143144000D01* 389 | X191770000Y-142748000D02* 390 | X191374000Y-143144000D01* 391 | X191770000Y-140208000D02* 392 | X191770000Y-141732000D01* 393 | X191770000Y-141732000D02* 394 | X191770000Y-142748000D01* 395 | X191516000Y-139954000D02* 396 | X191770000Y-140208000D01* 397 | X190246000Y-139954000D02* 398 | X191516000Y-139954000D01* 399 | X189992000Y-139700000D02* 400 | X190246000Y-139954000D01* 401 | X189992000Y-137160000D02* 402 | X189992000Y-139700000D01* 403 | X195638000Y-137160000D02* 404 | X195638000Y-137668000D01* 405 | X195638000Y-137668000D02* 406 | X196654000Y-138684000D01* 407 | X196498000Y-143794000D02* 408 | X198374000Y-143794000D01* 409 | X198374000Y-143794000D02* 410 | X198374000Y-143764000D01* 411 | X198374000Y-143198000D02* 412 | X198374000Y-143764000D01* 413 | X198374000Y-143764000D02* 414 | X198374000Y-144330000D01* 415 | X198374000Y-143198000D02* 416 | X198178000Y-143198000D01* 417 | X198374000Y-142298000D02* 418 | X198432000Y-142298000D01* 419 | X196498000Y-141194000D02* 420 | X197836000Y-141194000D01* 421 | X198374000Y-141732000D02* 422 | X198374000Y-142298000D01* 423 | X197836000Y-141194000D02* 424 | X198374000Y-141732000D01* 425 | X196498000Y-141194000D02* 426 | X196498000Y-140544000D01* 427 | X200660000Y-139388000D02* 428 | X202259780Y-140987780D01* 429 | X202259780Y-140987780D02* 430 | X203200000Y-140987780D01* 431 | X196498000Y-143144000D02* 432 | X195438000Y-143144000D01* 433 | X193548000Y-145034000D02* 434 | X193548000Y-146050000D01* 435 | X195438000Y-143144000D02* 436 | X193548000Y-145034000D01* 437 | X192728000Y-146050000D02* 438 | X193548000Y-146050000D01* 439 | X193548000Y-146050000D02* 440 | X194368000Y-146050000D01* 441 | X197674000Y-137160000D02* 442 | X196538000Y-137160000D01* 443 | M02* 444 | -------------------------------------------------------------------------------- /gerber/rfid-B.Mask.gbs: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Soldermask,Bot* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW 4.0.2-stable) date Sun 10 Apr 2016 09:46:26 PM EDT* 5 | %MOMM*% 6 | G01* 7 | G04 APERTURE LIST* 8 | %ADD10C,0.150000*% 9 | %ADD11R,1.727200X2.032000*% 10 | %ADD12O,1.727200X2.032000*% 11 | %ADD13R,1.500000X1.500000*% 12 | %ADD14C,1.500000*% 13 | %ADD15R,1.450000X0.450000*% 14 | %ADD16R,2.032000X1.727200*% 15 | %ADD17O,2.032000X1.727200*% 16 | %ADD18R,0.600000X0.500000*% 17 | %ADD19R,0.500000X0.600000*% 18 | %ADD20O,1.250000X0.950000*% 19 | %ADD21O,1.000000X1.550000*% 20 | %ADD22R,0.800100X0.800100*% 21 | %ADD23R,0.400000X0.600000*% 22 | %ADD24R,0.600000X0.400000*% 23 | %ADD25R,0.600000X0.700000*% 24 | %ADD26R,0.700000X0.600000*% 25 | G04 APERTURE END LIST* 26 | D10* 27 | D11* 28 | X176657000Y-137033000D03* 29 | D12* 30 | X179197000Y-137033000D03* 31 | X181737000Y-137033000D03* 32 | X184277000Y-137033000D03* 33 | D13* 34 | X198882000Y-135128000D03* 35 | D14* 36 | X196342000Y-135128000D03* 37 | D13* 38 | X221107000Y-142113000D03* 39 | D14* 40 | X221107000Y-139573000D03* 41 | D15* 42 | X190598000Y-144444000D03* 43 | X190598000Y-143794000D03* 44 | X190598000Y-143144000D03* 45 | X190598000Y-142494000D03* 46 | X190598000Y-141844000D03* 47 | X190598000Y-141194000D03* 48 | X190598000Y-140544000D03* 49 | X196498000Y-140544000D03* 50 | X196498000Y-141194000D03* 51 | X196498000Y-141844000D03* 52 | X196498000Y-142494000D03* 53 | X196498000Y-143144000D03* 54 | X196498000Y-143794000D03* 55 | X196498000Y-144444000D03* 56 | D16* 57 | X220357000Y-151638000D03* 58 | D17* 59 | X220357000Y-149098000D03* 60 | X220357000Y-146558000D03* 61 | D18* 62 | X194606000Y-138938000D03* 63 | X193506000Y-138938000D03* 64 | D19* 65 | X189230000Y-143468000D03* 66 | X189230000Y-144568000D03* 67 | D20* 68 | X195111100Y-150075460D03* 69 | X200111100Y-150075460D03* 70 | D21* 71 | X194111100Y-152775460D03* 72 | X201111100Y-152775460D03* 73 | D22* 74 | X204150000Y-142986760D03* 75 | X202250000Y-142986760D03* 76 | X203200000Y-140987780D03* 77 | X204200760Y-136972000D03* 78 | X204200760Y-138872000D03* 79 | X202201780Y-137922000D03* 80 | X208010760Y-136972000D03* 81 | X208010760Y-138872000D03* 82 | X206011780Y-137922000D03* 83 | D23* 84 | X196538000Y-137160000D03* 85 | X195638000Y-137160000D03* 86 | X196654000Y-138684000D03* 87 | X197554000Y-138684000D03* 88 | D24* 89 | X200660000Y-139388000D03* 90 | X200660000Y-138488000D03* 91 | X211836000Y-136456000D03* 92 | X211836000Y-137356000D03* 93 | D23* 94 | X191066000Y-137160000D03* 95 | X191966000Y-137160000D03* 96 | X194506000Y-137414000D03* 97 | X193606000Y-137414000D03* 98 | X192728000Y-146050000D03* 99 | X191828000Y-146050000D03* 100 | D24* 101 | X198374000Y-143198000D03* 102 | X198374000Y-142298000D03* 103 | D23* 104 | X194368000Y-146050000D03* 105 | X195268000Y-146050000D03* 106 | D24* 107 | X198374000Y-144330000D03* 108 | X198374000Y-145230000D03* 109 | D25* 110 | X199074000Y-137160000D03* 111 | X197674000Y-137160000D03* 112 | X192216000Y-138684000D03* 113 | X190816000Y-138684000D03* 114 | D26* 115 | X210312000Y-137606000D03* 116 | X210312000Y-136206000D03* 117 | M02* 118 | -------------------------------------------------------------------------------- /gerber/rfid-Edge.Cuts.gm1: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Profile,NP* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW 4.0.2-stable) date Sun 10 Apr 2016 09:46:26 PM EDT* 5 | %MOMM*% 6 | G01* 7 | G04 APERTURE LIST* 8 | %ADD10C,0.150000*% 9 | %ADD11C,0.100000*% 10 | G04 APERTURE END LIST* 11 | D10* 12 | D11* 13 | X200787000Y-135128000D02* 14 | X220472000Y-135128000D01* 15 | X194437000Y-135128000D02* 16 | X174752000Y-135128000D01* 17 | X195707000Y-133858000D02* 18 | X199517000Y-133858000D01* 19 | X200787000Y-135128000D02* 20 | G75* 21 | G03X199517000Y-133858000I-1270000J0D01* 22 | G01* 23 | X195707000Y-133858000D02* 24 | G75* 25 | G03X194437000Y-135128000I0J-1270000D01* 26 | G01* 27 | X220472000Y-135128000D02* 28 | G75* 29 | G03X223012000Y-137668000I2540000J0D01* 30 | G01* 31 | X172212000Y-137668000D02* 32 | G75* 33 | G03X174752000Y-135128000I0J2540000D01* 34 | G01* 35 | X172212000Y-137668000D02* 36 | X172212000Y-154178000D01* 37 | X223012000Y-137668000D02* 38 | X223012000Y-154178000D01* 39 | X172212000Y-154178000D02* 40 | X223012000Y-154178000D01* 41 | M02* 42 | -------------------------------------------------------------------------------- /gerber/rfid-F.Mask.gts: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Soldermask,Top* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW 4.0.2-stable) date Sun 10 Apr 2016 09:46:26 PM EDT* 5 | %MOMM*% 6 | G01* 7 | G04 APERTURE LIST* 8 | %ADD10C,0.150000*% 9 | %ADD11R,1.727200X2.032000*% 10 | %ADD12O,1.727200X2.032000*% 11 | %ADD13R,1.500000X1.500000*% 12 | %ADD14C,1.500000*% 13 | %ADD15R,1.000000X1.600000*% 14 | %ADD16R,1.100000X0.700000*% 15 | %ADD17R,1.400000X0.700000*% 16 | %ADD18R,1.400000X1.000000*% 17 | %ADD19R,1.200000X0.700000*% 18 | %ADD20R,1.200000X1.200000*% 19 | %ADD21R,0.800000X1.200000*% 20 | %ADD22R,3.200000X1.200000*% 21 | %ADD23R,1.900000X1.500000*% 22 | %ADD24R,0.500000X0.500000*% 23 | %ADD25R,0.450000X1.450000*% 24 | %ADD26R,2.032000X1.727200*% 25 | %ADD27O,2.032000X1.727200*% 26 | %ADD28R,0.750000X0.800000*% 27 | %ADD29R,0.600000X0.500000*% 28 | %ADD30R,1.000000X1.250000*% 29 | %ADD31R,0.797560X0.797560*% 30 | %ADD32R,0.400000X1.350000*% 31 | %ADD33O,1.250000X0.950000*% 32 | %ADD34O,1.000000X1.550000*% 33 | %ADD35R,0.800100X0.800100*% 34 | %ADD36R,0.400000X0.600000*% 35 | %ADD37R,0.600000X0.400000*% 36 | %ADD38R,1.060000X0.650000*% 37 | G04 APERTURE END LIST* 38 | D10* 39 | D11* 40 | X176657000Y-137033000D03* 41 | D12* 42 | X179197000Y-137033000D03* 43 | X181737000Y-137033000D03* 44 | X184277000Y-137033000D03* 45 | D13* 46 | X198882000Y-135128000D03* 47 | D14* 48 | X196342000Y-135128000D03* 49 | D13* 50 | X221107000Y-142113000D03* 51 | D14* 52 | X221107000Y-139573000D03* 53 | D15* 54 | X208002000Y-136652000D03* 55 | X205002000Y-136652000D03* 56 | D16* 57 | X195362000Y-142268000D03* 58 | X199862000Y-142268000D03* 59 | X195362000Y-145768000D03* 60 | X199862000Y-145768000D03* 61 | D17* 62 | X188222000Y-143358000D03* 63 | X188222000Y-144458000D03* 64 | X188222000Y-145558000D03* 65 | X188222000Y-146658000D03* 66 | X188222000Y-147758000D03* 67 | X188222000Y-148858000D03* 68 | X188222000Y-149958000D03* 69 | X188222000Y-151058000D03* 70 | D18* 71 | X188222000Y-141458000D03* 72 | D19* 73 | X188322000Y-152058000D03* 74 | D20* 75 | X184022000Y-152858000D03* 76 | D21* 77 | X177822000Y-152858000D03* 78 | D22* 79 | X174222000Y-152858000D03* 80 | D23* 81 | X173222000Y-139558000D03* 82 | D24* 83 | X172522000Y-140558000D03* 84 | D25* 85 | X209427000Y-143608000D03* 86 | X208777000Y-143608000D03* 87 | X208127000Y-143608000D03* 88 | X207477000Y-143608000D03* 89 | X206827000Y-143608000D03* 90 | X206177000Y-143608000D03* 91 | X205527000Y-143608000D03* 92 | X204877000Y-143608000D03* 93 | X204227000Y-143608000D03* 94 | X203577000Y-143608000D03* 95 | X203577000Y-149508000D03* 96 | X204227000Y-149508000D03* 97 | X204877000Y-149508000D03* 98 | X205527000Y-149508000D03* 99 | X206177000Y-149508000D03* 100 | X206827000Y-149508000D03* 101 | X207477000Y-149508000D03* 102 | X208127000Y-149508000D03* 103 | X208777000Y-149508000D03* 104 | X209427000Y-149508000D03* 105 | D26* 106 | X220357000Y-151638000D03* 107 | D27* 108 | X220357000Y-149098000D03* 109 | X220357000Y-146558000D03* 110 | D28* 111 | X217932000Y-151523000D03* 112 | X217932000Y-153023000D03* 113 | X211582000Y-153023000D03* 114 | X211582000Y-151523000D03* 115 | X215646000Y-142482000D03* 116 | X215646000Y-140982000D03* 117 | D29* 118 | X189950000Y-146050000D03* 119 | X191050000Y-146050000D03* 120 | D30* 121 | X213852000Y-139954000D03* 122 | X211852000Y-139954000D03* 123 | D29* 124 | X206544000Y-151130000D03* 125 | X205444000Y-151130000D03* 126 | D30* 127 | X213852000Y-141986000D03* 128 | X211852000Y-141986000D03* 129 | D29* 130 | X213402000Y-143510000D03* 131 | X212302000Y-143510000D03* 132 | D31* 133 | X215912700Y-149098000D03* 134 | X217411300Y-149098000D03* 135 | X191897000Y-150888700D03* 136 | X191897000Y-152387300D03* 137 | X218681300Y-136398000D03* 138 | X217182700Y-136398000D03* 139 | X194437000Y-139814300D03* 140 | X194437000Y-138315700D03* 141 | X197612000Y-139814300D03* 142 | X197612000Y-138315700D03* 143 | X200914000Y-139814300D03* 144 | X200914000Y-138315700D03* 145 | D32* 146 | X196311100Y-150075460D03* 147 | X196961100Y-150075460D03* 148 | X197611100Y-150075460D03* 149 | X198261100Y-150075460D03* 150 | X198911100Y-150075460D03* 151 | D33* 152 | X195111100Y-150075460D03* 153 | X200111100Y-150075460D03* 154 | D34* 155 | X194111100Y-152775460D03* 156 | X201111100Y-152775460D03* 157 | D35* 158 | X213680000Y-137906760D03* 159 | X215580000Y-137906760D03* 160 | X214630000Y-135907780D03* 161 | X210124000Y-137906760D03* 162 | X212024000Y-137906760D03* 163 | X211074000Y-135907780D03* 164 | D36* 165 | X214572000Y-149098000D03* 166 | X213672000Y-149098000D03* 167 | X192474000Y-149606000D03* 168 | X191574000Y-149606000D03* 169 | D37* 170 | X218567000Y-138753000D03* 171 | X218567000Y-137853000D03* 172 | X195707000Y-139885000D03* 173 | X195707000Y-140785000D03* 174 | X198882000Y-139885000D03* 175 | X198882000Y-140785000D03* 176 | X202184000Y-139885000D03* 177 | X202184000Y-140785000D03* 178 | D36* 179 | X216212000Y-147066000D03* 180 | X217112000Y-147066000D03* 181 | D37* 182 | X202184000Y-146500000D03* 183 | X202184000Y-145600000D03* 184 | X210058000Y-140150000D03* 185 | X210058000Y-139250000D03* 186 | D38* 187 | X215857000Y-153223000D03* 188 | X215857000Y-152273000D03* 189 | X215857000Y-151323000D03* 190 | X213657000Y-151323000D03* 191 | X213657000Y-153223000D03* 192 | X217762000Y-145603000D03* 193 | X217762000Y-144653000D03* 194 | X217762000Y-143703000D03* 195 | X215562000Y-143703000D03* 196 | X215562000Y-145603000D03* 197 | M02* 198 | -------------------------------------------------------------------------------- /gerber/rfid.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ;DRILL file {KiCad 4.0.2-stable} date Sun 10 Apr 2016 09:46:27 PM EDT 3 | ;FORMAT={-:-/ absolute / inch / decimal} 4 | FMAT,2 5 | INCH,TZ 6 | T1C0.015 7 | T2C0.020 8 | T3C0.022 9 | T4C0.028 10 | T5C0.040 11 | % 12 | G90 13 | G05 14 | M72 15 | T1 16 | X7.4103Y-5.47 17 | X7.45Y-5.61 18 | X7.47Y-5.86 19 | X7.49Y-5.79 20 | X7.53Y-5.78 21 | X7.56Y-6.04 22 | X7.62Y-5.59 23 | X7.65Y-5.63 24 | X7.74Y-5.75 25 | X7.83Y-5.45 26 | X7.83Y-5.96 27 | X7.92Y-5.63 28 | X8.03Y-5.71 29 | X8.07Y-5.71 30 | X8.07Y-5.81 31 | X8.11Y-5.71 32 | X8.12Y-5.83 33 | X8.13Y-5.39 34 | X8.15Y-5.71 35 | X8.16Y-5.83 36 | X8.23Y-5.46 37 | X8.29Y-5.54 38 | X8.33Y-5.92 39 | X8.3406Y-5.46 40 | X8.37Y-6.0245 41 | X8.46Y-5.4694 42 | X8.49Y-5.51 43 | X8.6Y-5.87 44 | X8.62Y-5.7 45 | X8.62Y-6.04 46 | T4 47 | X7.73Y-5.32 48 | X7.83Y-5.32 49 | X8.705Y-5.495 50 | X8.705Y-5.595 51 | T5 52 | X6.955Y-5.395 53 | X7.055Y-5.395 54 | X7.155Y-5.395 55 | X7.255Y-5.395 56 | X8.6755Y-5.77 57 | X8.6755Y-5.87 58 | X8.6755Y-5.97 59 | T2 60 | X7.6422Y-6.0276G85X7.6422Y-6.002 61 | G05 62 | X7.9178Y-6.0276G85X7.9178Y-6.002 63 | G05 64 | T3 65 | X7.6756Y-5.9085G85X7.6874Y-5.9085 66 | G05 67 | X7.8725Y-5.9085G85X7.8843Y-5.9085 68 | G05 69 | T0 70 | M30 71 | -------------------------------------------------------------------------------- /python/decode.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from math import * 5 | import cmath 6 | 7 | data = (int(line) for line in sys.stdin) 8 | 9 | def hpf(data): 10 | ALPHA = 0.7 11 | 12 | y = 0 13 | lx = 0 14 | for x in data: 15 | y = ALPHA * (y + x - lx) 16 | yield y 17 | lx = x 18 | 19 | def lpf(data): 20 | ALPHA = 0.001 21 | 22 | y = 0 23 | for x in data: 24 | y = ALPHA * x + (1 - ALPHA) * y 25 | yield y 26 | 27 | def thresh(data): 28 | x2 = 0 29 | x3 = 0 30 | 31 | for x in data: 32 | yield int(sum((x > 0, x2 > 0, x3 > 0)) > 1) 33 | x2 = x 34 | x3 = x2 35 | 36 | def rle(data): 37 | prev = None 38 | for x in data: 39 | if x != prev: 40 | if prev is not None: 41 | yield ctr 42 | ctr = 0 43 | prev = x 44 | ctr += 1 45 | 46 | def fsk_decoder(stream, period): 47 | ALPHA = 0.95 48 | 49 | f = 1/period * 2 * pi 50 | 51 | s_1 = 0 52 | s_2 = 0 53 | for x in stream: 54 | s = x + 2 * cos(f) * s_1 * ALPHA - s_2 * ALPHA ** 2 55 | y = s - cmath.exp(-1j*f) * s_1 56 | #y_r = abs(y) * BETA + y_r_1 * (1 - BETA) 57 | y_r = abs(y) ** 2 58 | yield y_r 59 | 60 | s_2 = s_1 61 | s_1 = s 62 | 63 | def evenodd(stream): 64 | odd = False 65 | for x in stream: 66 | if odd: 67 | yield x - prev_even 68 | yield x - prev_even 69 | else: 70 | prev_even = x 71 | odd = not odd 72 | 73 | def selector(data2, data5, data8, data10): 74 | THRESH = 500000 75 | for (d2, d5, d8, d10) in zip(lpf(data2), lpf(data5), lpf(data8), lpf(data10)): 76 | opts = ( 77 | ("psk", d2 * 50), 78 | ("fsk1", d8 + d5), 79 | ("fsk2", d8 + d10) 80 | ) 81 | kind, value = max(opts, key=lambda x: x[1]) 82 | if value < THRESH: 83 | yield None 84 | else: 85 | yield kind 86 | 87 | def dispatch(encodings): 88 | prev_encoding = None 89 | for i in range(len(encodings)): 90 | if encodings[i] != prev_encoding: 91 | if prev_encoding != None: 92 | yield (prev_encoding, start, i) 93 | prev_encoding = encodings[i] 94 | start = i 95 | if prev_encoding != None: 96 | yield (prev_encoding, start, i) 97 | 98 | def decode_fsk(stream): 99 | for x in stream: 100 | if x > 0: 101 | yield 1 102 | else: 103 | yield 0 104 | 105 | def decode_psk(stream): 106 | for x in stream: 107 | if x > 0: 108 | yield 1 109 | else: 110 | yield 0 111 | 112 | data = list(data) 113 | data_hpf = list(hpf(data)) 114 | data2 = list(fsk_decoder(data_hpf, 2)) 115 | 116 | data = list(data) 117 | data_hpf = list(hpf(data)) 118 | data2 = list(fsk_decoder(data_hpf, 2)) 119 | data5 = list(fsk_decoder(data_hpf, 5)) 120 | data8 = list(fsk_decoder(data_hpf, 8)) 121 | data10 = list(fsk_decoder(data_hpf, 10)) 122 | encodings = list(selector(data2, data5, data8, data10)) 123 | 124 | for (encoding, start, end) in dispatch(encodings): 125 | print(encoding, start, end) 126 | if encoding == "psk": 127 | result = decode_psk(evenodd(data_hpf[start:end])) 128 | elif encoding == "fsk1": 129 | result = decode_fsk(np.array(data8[start:end]) - np.array(data5[start:end])) 130 | elif encoding == "fsk2": 131 | result = decode_fsk(np.array(data8[start:end]) - np.array(data10[start:end])) 132 | 133 | result = list(result) 134 | 135 | plt.plot(result) 136 | plt.show() 137 | #plt.plot(data5[0:1000], 'r-') 138 | #plt.plot(data8[0:1000], 'g-') 139 | #plt.plot(data10[0:1000], 'b-') 140 | #plt.plot(data2[0:1000], 'y-') 141 | #plt.plot(np.array(data)[0:1000] * 2, 'ko-') 142 | 143 | 144 | #data = list(thresh(bpf(data))) 145 | #data2 = list(bpf(data)) 146 | #rle_data = list(rle(data)) 147 | #plt.plot(rle_data, 'o-') 148 | #plt.plot(data[1000:2000], 'o-') 149 | #plt.plot(data2[1000:2000], 'o-') 150 | plt.show() 151 | -------------------------------------------------------------------------------- /python/read_test.py: -------------------------------------------------------------------------------- 1 | import rfid 2 | import matplotlib.pyplot as plt 3 | 4 | r = rfid.RFID() 5 | samples = r.raw_read(2**17) 6 | samples = samples[-2**15:] 7 | samples = rfid.hpf(samples) 8 | plt.plot(samples, 'ro') 9 | samples_demod = rfid.fsk_demodulator(samples, p0=8, p1=10) 10 | #samples_demod = rfid.psk_demodulator(samples) 11 | #(decoded_bits, decoded_waveform) = rfid.decoder(samples_demod, bit_width=32) 12 | #(clock_recovery, decoded_waveform, decoded_bits) = rfid.simple_decoder(samples_demod, bit_width=32) 13 | (clock_recovery, decoded_waveform, decoded_bits) = rfid.simple_decoder(samples_demod, bit_width=50) 14 | plt.plot(samples_demod) 15 | #plt.plot(clock_recovery) 16 | plt.plot(decoded_waveform) 17 | plt.show() 18 | cycles = rfid.find_cycles(rfid.thresh(decoded_bits), length=96) 19 | 20 | seen = {} 21 | for cycle in cycles: 22 | cycle_bytes = rfid.binary_string_to_bytes(rfid.sort_cycle(cycle)) 23 | seen[cycle_bytes] = seen.get(cycle_bytes, 0) + 1 24 | 25 | for (cycle, count) in seen.items(): 26 | print("Read {} times: {}".format(count, rfid.pretty_bytes(cycle))) 27 | print(rfid.bytes_to_binary_string(cycle)) 28 | print(rfid.decode_manchester(rfid.bytes_to_binary_string(cycle))) 29 | -------------------------------------------------------------------------------- /python/rfid/__init__.py: -------------------------------------------------------------------------------- 1 | from rfid.driver import * 2 | from rfid.protocol import * 3 | -------------------------------------------------------------------------------- /python/rfid/driver.py: -------------------------------------------------------------------------------- 1 | import usb.core 2 | import struct 3 | import numpy as np 4 | import sys 5 | 6 | class RFID: 7 | VID = 0xffff 8 | PID = 0x2951 9 | 10 | CONTROL_IN = 0xC1 # Host to device 11 | CONTROL_OUT = 0x41 # Device to host 12 | 13 | REQUEST_LED_READ = 0x20 14 | REQUEST_LED_WRITE = 0x21 15 | REQUEST_LED_SPOOF = 0x22 16 | REQUEST_COIL_DRIVE = 0x23 17 | REQUEST_COIL_TUNE = 0x24 18 | REQUEST_STREAM_READ = 0x25 19 | REQUEST_STREAM_WRITE = 0x26 20 | REQUEST_LATENCY = 0x27 21 | 22 | def __init__(self): 23 | self.dev = usb.core.find(idVendor=self.VID, idProduct=self.PID) 24 | self.dev.set_configuration() 25 | 26 | def led_read(self, state): 27 | state = int(bool(state)) 28 | self.dev.ctrl_transfer(self.CONTROL_OUT, self.REQUEST_LED_READ, state, 0, b"") 29 | 30 | def led_write(self, state): 31 | state = int(bool(state)) 32 | self.dev.ctrl_transfer(self.CONTROL_OUT, self.REQUEST_LED_WRITE, state, 0, b"") 33 | 34 | def led_spoof(self, state): 35 | state = int(bool(state)) 36 | self.dev.ctrl_transfer(self.CONTROL_OUT, self.REQUEST_LED_SPOOF, state, 0, b"") 37 | 38 | def coil_drive(self, state): 39 | state = int(bool(state)) 40 | self.dev.ctrl_transfer(self.CONTROL_OUT, self.REQUEST_COIL_DRIVE, state, 0, b"") 41 | 42 | def coil_tune(self, state): 43 | state = int(bool(state)) 44 | self.dev.ctrl_transfer(self.CONTROL_OUT, self.REQUEST_COIL_TUNE, state, 0, b"") 45 | 46 | def stream_read_enable(self, state): 47 | state = int(bool(state)) 48 | self.dev.ctrl_transfer(self.CONTROL_OUT, self.REQUEST_STREAM_READ, state, 0, b"") 49 | 50 | def stream_write_enable(self, state): 51 | state = int(bool(state)) 52 | self.dev.ctrl_transfer(self.CONTROL_OUT, self.REQUEST_STREAM_WRITE, state, 0, b"") 53 | 54 | def stream_read(self, count): 55 | result = self.dev.read(0x81, count * 2, timeout=int(count / 125 * 1.2 + 1000)) 56 | values = struct.unpack("<{}H".format(len(result) // 2), result) 57 | values = np.array(values, dtype=np.float) 58 | return values 59 | 60 | def stream_write(self, data): 61 | data = struct.pack("<{}B".format(len(data)), *list(data)) 62 | result = self.dev.write(0x02, data, timeout=int(len(data) / 125 * 1.2 + 1000)) 63 | assert result == len(data) 64 | 65 | def set_latency(self, latency): 66 | self.dev.ctrl_transfer(self.CONTROL_OUT, self.REQUEST_LATENCY, latency, 0, b"") 67 | 68 | # Higher-level functions 69 | 70 | def raw_read(self, n_samples): 71 | try: 72 | self.led_read(True) 73 | self.coil_drive(True) 74 | self.stream_read_enable(True) 75 | return np.array(self.stream_read(n_samples), dtype=np.int16) 76 | finally: 77 | self.stream_read_enable(False) 78 | self.coil_drive(False) 79 | self.led_read(False) 80 | 81 | def raw_write(self, samples): 82 | try: 83 | self.led_write(True) 84 | self.stream_write_enable(True) 85 | self.stream_write(samples) 86 | finally: 87 | self.stream_write_enable(False) 88 | self.coil_drive(False) 89 | self.led_write(False) 90 | 91 | -------------------------------------------------------------------------------- /python/rfid/protocol.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from scipy import signal 3 | import cmath 4 | import math 5 | 6 | FREQ = 125000. 7 | NYQ_FREQ = FREQ / 2. 8 | 9 | def hpf(data, cutoff=62.5): 10 | b, a = signal.butter(1, 2 / cutoff, 'high') 11 | return signal.lfilter(b, a, data) 12 | 13 | def lpf(data, cutoff=6.25): 14 | b, a = signal.butter(1, 2 / cutoff, 'low') 15 | return signal.lfilter(b, a, data) 16 | 17 | def thresh(data): 18 | return "".join("1" if bit > 0 else "0" for bit in data) 19 | 20 | def sine_sqw(x, period): 21 | x = x % period 22 | if x == 0 or x == period / 2: 23 | return 0. 24 | elif x < period / 2: 25 | return 1. 26 | else: 27 | return -1. 28 | 29 | def cosine_sqw(x, period): 30 | return sine_sqw(x + period / 4, period) 31 | 32 | def carrier(period, length): 33 | return np.cos((np.arange(length) % period) * 2 * np.pi / period) 34 | 35 | def complex_carrier(period, length): 36 | return np.exp(1j * (np.arange(length) % period) * 2 * np.pi / period) 37 | 38 | def psk_demodulator(data): 39 | data = hpf(data) 40 | data = data * carrier(2, len(data)) 41 | #data = lpf(data) 42 | return data 43 | 44 | def fsk_demodulator(data, p0=10, p1=8, alpha=0.95): 45 | data0 = np.abs(goertzel(data, p0, alpha)) 46 | data1 = np.abs(goertzel(data, p1, alpha)) 47 | return hpf(data1 - data0, 1000) 48 | 49 | def goertzel(stream, period, alpha=0.95): 50 | w0 = 1/period * 2 * math.pi 51 | 52 | #a = [1, -2 * math.cos(w0) * alpha, alpha ** 2] 53 | #b = [1] 54 | 55 | #s = signal.lfilter(b, a, stream) 56 | 57 | #a = [1] 58 | #b = [1, -cmath.exp(-1j*w0)] 59 | 60 | #y = signal.lfilter(b, a, s) 61 | 62 | y = signal.lfilter([1], [1, -alpha * cmath.exp(1j*w0)], stream) 63 | 64 | return y 65 | 66 | def decode_manchester(bits): 67 | carrier = ("01" * ((len(bits) + 1) // 2))[0:len(bits)] 68 | carrier = int(carrier, 2) 69 | signal = int(bits, 2) 70 | return ("{:0" + str(len(bits)) + "b}").format(carrier ^ signal) 71 | 72 | def decoder(stream, bit_width=8): 73 | #stream = list(thresh(stream)) 74 | resample_bits = lambda i: np.reshape(np.hstack(((stream[i:], np.zeros((-len(stream) + i) % bit_width)))), (-1, bit_width)) 75 | 76 | resamp = [resample_bits(i) for i in range(bit_width)] 77 | strengths = [np.sum(np.sum(data, axis=1) ** 2) for data in resamp] 78 | i = strengths.index(max(strengths)) 79 | decoded_bits = np.sum(resamp[i], axis=1) / bit_width 80 | decoded_waveform = np.hstack((np.zeros(i), np.reshape(np.tile(decoded_bits, bit_width), (bit_width, -1)).T.flatten())) 81 | return (decoded_bits, decoded_waveform) 82 | 83 | def simple_decoder(stream, bit_width=8): 84 | bits = thresh(lpf(stream)) 85 | t = 0 86 | last_b = bits[0] 87 | t_arr = [] 88 | w_arr = [] 89 | b_arr = [] 90 | bit_sum = 0 91 | bit_count = 0 92 | for b, s in zip(bits, stream): 93 | t = t + 1 94 | if t >= bit_width: 95 | bit_val = bit_sum / bit_count 96 | w_arr += [bit_val] * bit_count 97 | b_arr.append(bit_val) 98 | bit_sum = 0 99 | bit_count = 0 100 | t -= bit_width 101 | t_arr.append(t) 102 | 103 | bit_sum += s 104 | bit_count += 1 105 | if b != last_b: 106 | last_b = b 107 | if t > 0 and t < bit_width / 2: 108 | t -= 1 109 | if t >= bit_width / 2: 110 | t += 1 111 | return (np.array(t_arr), np.array(w_arr), np.array(b_arr)) 112 | 113 | def find_cycles(stream, length): 114 | match = 0 115 | cycle = "" 116 | for x in stream: 117 | if len(cycle) < length: 118 | cycle = cycle + x 119 | continue 120 | 121 | if cycle[0] == x: 122 | match += 1 123 | if match == length: 124 | yield cycle 125 | match = 0 126 | else: 127 | match = 0 128 | cycle = cycle[1:] + x 129 | 130 | def sort_cycle(cycle, reverse_ok=True): 131 | shifted = lambda i: cycle[i:] + cycle[0:i] 132 | fromnum = lambda n: ("{:0" + str(len(cycle)) + "b}").format(n) 133 | 134 | numbers = [int(shifted(i), 2) for i in range(len(cycle))] 135 | if reverse_ok: 136 | numbers += [2**len(cycle)+~int(shifted(i), 2) for i in range(len(cycle))] 137 | best = min(numbers) 138 | return fromnum(best) 139 | 140 | def bytes_to_binary_string(s): 141 | return "".join("{:08b}".format(b) for b in s) 142 | 143 | def binary_string_to_bytes(s): 144 | n = int(s, 2) 145 | return bytes(reversed(bytes((n >> i) & 255 for i in range(0, len(s), 8)))) 146 | 147 | def pretty_bytes(s): 148 | return " ".join("{:02x}".format(b) for b in s) 149 | 150 | #def decoder(stream): 151 | # PREAMBLE = 250 152 | # PERIOD = 16 153 | # LENGTH = 224 154 | # MARGIN = 2 155 | # 156 | # while True: 157 | # dwell = False 158 | # count = 0 159 | # while True: 160 | # s = next(stream) 161 | # if s != dwell: 162 | # dwell = s 163 | # count = 0 164 | # else: 165 | # count += 1 166 | # if count > PREAMBLE: 167 | # break 168 | # 169 | # while next(stream) == dwell: 170 | # pass 171 | # 172 | # bits = [] 173 | # for i in range(LENGTH): 174 | # acc = 0 175 | # cnt = 0 176 | # for j in range(PERIOD): 177 | # s = (next(stream) != dwell) 178 | # if j >= MARGIN and j < PERIOD - MARGIN: 179 | # acc += s 180 | # cnt += 1 181 | # bits.append(acc > cnt / 2) 182 | # bytes_ = [int("".join(["1" if b else "0" for b in bits[i:i+8]]), 2) for i in range(0, len(bits), 8)] 183 | # yield bytes_ 184 | -------------------------------------------------------------------------------- /python/rfid/t5577.py: -------------------------------------------------------------------------------- 1 | import struct 2 | 3 | CONFIG_BASIC_DATA_BIT_RATE = { 4 | 8: 0, 5 | 16: 1, 6 | 32: 2, 7 | 40: 3, 8 | 50: 4, 9 | 64: 5, 10 | 100: 6, 11 | 128: 7, 12 | } 13 | 14 | CONFIG_BASIC_MODULATION = { 15 | "direct": 0, 16 | "psk1": 1, 17 | "psk2": 2, 18 | "psk3": 3, 19 | "fsk1": 4, 20 | "fsk2": 5, 21 | "fsk1a": 6, 22 | "fsk2a": 7, 23 | "manchester": 8, 24 | "biphase": 16, 25 | } 26 | 27 | CONFIG_BASIC_PSK_CF = { 28 | 2: 0, 29 | 4: 1, 30 | 8: 2 31 | } 32 | 33 | RISE_ADJ = 0 34 | START_GAP = (15 - RISE_ADJ) # fifteen sample start gap 35 | WRITE_GAP = (10 - RISE_ADJ) # ten sample write gap 36 | ZERO = (24 + RISE_ADJ) # 24 samples for zero 37 | ONE = (56 + RISE_ADJ) # 56 samples for one 38 | PROGRAMMING_TIME = 1875 # 15 ms programming time 39 | POWER_ON_TIME = 1875 # 15 ms for power on 40 | 41 | def config_block_basic(bit_width=8, modulation="direct", max_block=0, psk_cf=2): 42 | config = 0 43 | config |= CONFIG_BASIC_DATA_BIT_RATE[bit_width] << 18 44 | config |= CONFIG_BASIC_MODULATION[modulation] << 12 45 | config |= CONFIG_BASIC_PSK_CF[psk_cf] << 10 46 | assert max_block in range(1, 8) 47 | config |= max_block << 5 48 | return struct.pack(">I", config) 49 | 50 | def get_bits(num, width): 51 | return [int(c) for c in ("{:0" + str(width) + "b}").format(num)] 52 | 53 | def write_bit(bit): 54 | return ([1] * ONE if bit else [1] * ZERO) + [0] * WRITE_GAP 55 | 56 | def write_block(page, block_id, code, lock=False): 57 | assert page in range(2) 58 | assert block_id in range(8) 59 | code_bits = get_bits(struct.unpack(">I", code)[0], 32) 60 | lock = bool(lock) 61 | 62 | stream = [0] * START_GAP 63 | stream += write_bit(1) # opcode 1 64 | stream += write_bit(page) # opcode 0 65 | stream += write_bit(lock) # lock bit 66 | 67 | for bit in code_bits: # 32 bits of data 68 | stream += write_bit(bit) 69 | 70 | for bit in get_bits(block_id, 3): # 3 bits of block_id 71 | stream += write_bit(bit) 72 | 73 | #block_bits = "{:03b}".format(block_id) 74 | #for bit in block_bits: # 3 bits of block_id 75 | # stream += [1] * ONE if bit == "1" else [1] * ZERO 76 | stream += [1] * PROGRAMMING_TIME 77 | return stream 78 | 79 | def write_card_basic(data, bit_width=8, modulation="direct", psk_cf=2): 80 | assert len(data) % 4 == 0 and len(data) // 4 in range(1, 8) 81 | num_blocks = len(data) // 4 82 | config_block = config_block_basic(bit_width, modulation, num_blocks, psk_cf) 83 | 84 | result = [1] * POWER_ON_TIME 85 | 86 | result = write_block(0, 0, config_block, False) 87 | 88 | for i in range(num_blocks): 89 | result += write_block(0, i + 1, data[i*4:i*4+4]) 90 | 91 | return result 92 | -------------------------------------------------------------------------------- /python/write_test.py: -------------------------------------------------------------------------------- 1 | import rfid 2 | import rfid.t5577 3 | import matplotlib.pyplot as plt 4 | 5 | data = bytes([0, 0, 0x03, 0x55] * 7) 6 | 7 | print("Writing", rfid.pretty_bytes(data)) 8 | print("Writing", rfid.bytes_to_binary_string(data)) 9 | 10 | data_sorted = rfid.binary_string_to_bytes(rfid.sort_cycle(rfid.bytes_to_binary_string(data), False)) 11 | if data_sorted != data: 12 | print("Warning! Data cycles to", rfid.pretty_bytes(data_sorted)) 13 | 14 | r = rfid.RFID() 15 | samples = rfid.t5577.write_card_basic(data, bit_width=50, modulation="fsk2a") 16 | r.raw_write(samples) 17 | 18 | samples = r.raw_read(2**15) 19 | samples_demod = rfid.fsk_demodulator(samples, p0=8, p1=10) 20 | (decoded_bits, decoded_waveform) = rfid.decoder(samples_demod, bit_width=50) 21 | plt.plot(samples_demod) 22 | plt.plot(decoded_waveform) 23 | plt.show() 24 | cycles = rfid.find_cycles(rfid.thresh(decoded_bits), length=96) 25 | for cycle in cycles: 26 | cycle_bytes = rfid.binary_string_to_bytes(rfid.sort_cycle(cycle, False)) 27 | if cycle_bytes == data_sorted: 28 | print("Read back OK!") 29 | else: 30 | print("Bad read:", rfid.pretty_bytes(cycle_bytes)) 31 | print("Bad read", rfid.bytes_to_binary_string(cycle_bytes)) 32 | -------------------------------------------------------------------------------- /rfid-cache.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # +5V 5 | # 6 | DEF +5V #PWR 0 0 Y Y 1 F P 7 | F0 "#PWR" 0 -150 50 H I C CNN 8 | F1 "+5V" 0 140 50 H V C CNN 9 | F2 "" 0 0 50 H V C CNN 10 | F3 "" 0 0 50 H V C CNN 11 | DRAW 12 | P 2 0 1 0 -30 50 0 100 N 13 | P 2 0 1 0 0 0 0 100 N 14 | P 2 0 1 0 0 100 30 50 N 15 | X +5V 1 0 0 0 U 50 50 1 1 W N 16 | ENDDRAW 17 | ENDDEF 18 | # 19 | # +BATT 20 | # 21 | DEF +BATT #PWR 0 0 Y Y 1 F P 22 | F0 "#PWR" 0 -150 50 H I C CNN 23 | F1 "+BATT" 0 140 50 H V C CNN 24 | F2 "" 0 0 50 H V C CNN 25 | F3 "" 0 0 50 H V C CNN 26 | DRAW 27 | P 2 0 1 0 -30 50 0 100 N 28 | P 2 0 1 0 0 0 0 100 N 29 | P 2 0 1 0 0 100 30 50 N 30 | X +BATT 1 0 0 0 U 50 50 1 1 W N 31 | ENDDRAW 32 | ENDDEF 33 | # 34 | # BATTERY 35 | # 36 | DEF BATTERY BT 0 0 Y Y 1 F N 37 | F0 "BT" 0 200 50 H V C CNN 38 | F1 "BATTERY" 0 -190 50 H V C CNN 39 | F2 "" 0 0 60 H V C CNN 40 | F3 "" 0 0 60 H V C CNN 41 | DRAW 42 | C 0 0 150 0 1 6 N 43 | P 2 0 1 0 -100 0 -150 0 N 44 | P 2 0 1 6 -100 90 -100 -89 N 45 | P 2 0 1 6 -31 50 -31 -50 N 46 | P 2 0 1 6 39 90 39 -89 N 47 | P 2 0 1 0 100 0 150 0 N 48 | P 2 0 1 6 100 50 100 -50 N 49 | X + 1 -300 0 150 R 50 50 1 1 P 50 | X - 2 300 0 150 L 50 50 1 1 P 51 | ENDDRAW 52 | ENDDEF 53 | # 54 | # C-RESCUE-rfid 55 | # 56 | DEF C-RESCUE-rfid C 0 10 N Y 1 F N 57 | F0 "C" 0 100 40 H V L CNN 58 | F1 "C-RESCUE-rfid" 6 -85 40 H V L CNN 59 | F2 "" 38 -150 30 H V C CNN 60 | F3 "" 0 0 60 H V C CNN 61 | $FPLIST 62 | SM* 63 | C? 64 | C1-1 65 | $ENDFPLIST 66 | DRAW 67 | P 2 0 1 20 -80 -30 80 -30 N 68 | P 2 0 1 20 -80 30 80 30 N 69 | X ~ 1 0 200 170 D 40 40 1 1 P 70 | X ~ 2 0 -200 170 U 40 40 1 1 P 71 | ENDDRAW 72 | ENDDEF 73 | # 74 | # CONN_01X04 75 | # 76 | DEF CONN_01X04 P 0 40 Y N 1 F N 77 | F0 "P" 0 250 50 H V C CNN 78 | F1 "CONN_01X04" 100 0 50 V V C CNN 79 | F2 "" 0 0 50 H V C CNN 80 | F3 "" 0 0 50 H V C CNN 81 | $FPLIST 82 | Pin_Header_Straight_1X04 83 | Pin_Header_Angled_1X04 84 | Socket_Strip_Straight_1X04 85 | Socket_Strip_Angled_1X04 86 | $ENDFPLIST 87 | DRAW 88 | S -50 -145 10 -155 0 1 0 N 89 | S -50 -45 10 -55 0 1 0 N 90 | S -50 55 10 45 0 1 0 N 91 | S -50 155 10 145 0 1 0 N 92 | S -50 200 50 -200 0 1 0 N 93 | X P1 1 -200 150 150 R 50 50 1 1 P 94 | X P2 2 -200 50 150 R 50 50 1 1 P 95 | X P3 3 -200 -50 150 R 50 50 1 1 P 96 | X P4 4 -200 -150 150 R 50 50 1 1 P 97 | ENDDRAW 98 | ENDDEF 99 | # 100 | # D 101 | # 102 | DEF D D 0 40 N N 1 F N 103 | F0 "D" 0 100 50 H V C CNN 104 | F1 "D" 0 -100 50 H V C CNN 105 | F2 "" 0 0 50 H V C CNN 106 | F3 "" 0 0 50 H V C CNN 107 | $FPLIST 108 | Diode_* 109 | D-Pak_TO252AA 110 | *SingleDiode 111 | *_Diode_* 112 | *SingleDiode* 113 | $ENDFPLIST 114 | DRAW 115 | P 2 0 1 6 -50 50 -50 -50 N 116 | P 3 0 1 0 50 50 -50 0 50 -50 F 117 | X K 1 -150 0 100 R 50 50 1 1 P 118 | X A 2 150 0 100 L 50 50 1 1 P 119 | ENDDRAW 120 | ENDDEF 121 | # 122 | # GND 123 | # 124 | DEF GND #PWR 0 0 Y Y 1 F P 125 | F0 "#PWR" 0 -250 50 H I C CNN 126 | F1 "GND" 0 -150 50 H V C CNN 127 | F2 "" 0 0 50 H V C CNN 128 | F3 "" 0 0 50 H V C CNN 129 | DRAW 130 | P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N 131 | X GND 1 0 0 0 D 50 50 1 1 W N 132 | ENDDRAW 133 | ENDDEF 134 | # 135 | # GND-RESCUE-rfid 136 | # 137 | DEF ~GND-RESCUE-rfid #PWR 0 0 Y Y 1 F P 138 | F0 "#PWR" 0 0 30 H I C CNN 139 | F1 "GND-RESCUE-rfid" 0 -70 30 H I C CNN 140 | F2 "" 0 0 60 H V C CNN 141 | F3 "" 0 0 60 H V C CNN 142 | DRAW 143 | P 4 0 1 0 -50 0 0 -50 50 0 -50 0 N 144 | X GND 1 0 0 0 U 30 30 1 1 W N 145 | ENDDRAW 146 | ENDDEF 147 | # 148 | # INDUCTOR 149 | # 150 | DEF INDUCTOR L 0 40 N N 1 F N 151 | F0 "L" -50 0 50 V V C CNN 152 | F1 "INDUCTOR" 100 0 50 V V C CNN 153 | F2 "" 0 0 50 H V C CNN 154 | F3 "" 0 0 50 H V C CNN 155 | DRAW 156 | A 0 -150 50 -889 889 0 1 0 N 1 -199 1 -100 157 | A 0 -49 51 -889 889 0 1 0 N 1 -99 1 2 158 | A 0 51 51 -889 889 0 1 0 N 1 1 1 102 159 | A 0 148 48 -889 889 0 1 0 N 1 101 1 196 160 | X 1 1 0 300 100 D 50 50 1 1 P 161 | X 2 2 0 -300 100 U 50 50 1 1 P 162 | ENDDRAW 163 | ENDDEF 164 | # 165 | # LED 166 | # 167 | DEF LED D 0 40 Y N 1 F N 168 | F0 "D" 0 100 50 H V C CNN 169 | F1 "LED" 0 -100 50 H V C CNN 170 | F2 "" 0 0 50 H V C CNN 171 | F3 "" 0 0 50 H V C CNN 172 | $FPLIST 173 | LED-3MM 174 | LED-5MM 175 | LED-10MM 176 | LED-0603 177 | LED-0805 178 | LED-1206 179 | LEDV 180 | $ENDFPLIST 181 | DRAW 182 | P 2 0 1 0 -50 50 -50 -50 N 183 | P 3 0 1 0 -80 -25 -125 -65 -120 -40 N 184 | P 3 0 1 0 -65 -40 -110 -80 -105 -55 N 185 | P 3 0 1 0 50 50 -50 0 50 -50 F 186 | X K 1 -200 0 150 R 40 40 1 1 P 187 | X A 2 200 0 150 L 40 40 1 1 P 188 | ENDDRAW 189 | ENDDEF 190 | # 191 | # LM324-RESCUE-rfid 192 | # 193 | DEF LM324-RESCUE-rfid U 0 20 Y Y 4 F N 194 | F0 "U" 50 200 60 H V C CNN 195 | F1 "LM324-RESCUE-rfid" 150 -200 50 H V C CNN 196 | F2 "" 0 0 60 H V C CNN 197 | F3 "" 0 0 60 H V C CNN 198 | DRAW 199 | P 4 0 1 6 -200 200 200 0 -200 -200 -200 200 f 200 | X V+ 4 -100 400 250 D 40 40 0 1 W 201 | X V- 11 -100 -400 250 U 40 40 0 1 W 202 | X ~ 1 500 0 300 L 40 40 1 1 O 203 | X - 2 -500 -100 300 R 40 40 1 1 I 204 | X + 3 -500 100 300 R 40 40 1 1 I 205 | X + 5 -500 100 300 R 40 40 2 1 I 206 | X - 6 -500 -100 300 R 40 40 2 1 I 207 | X ~ 7 500 0 300 L 40 40 2 1 O 208 | X ~ 8 500 0 300 L 40 40 3 1 O 209 | X - 9 -500 -100 300 R 40 40 3 1 I 210 | X + 10 -500 100 300 R 40 40 3 1 I 211 | X + 12 -500 100 300 R 40 40 4 1 I 212 | X - 13 -500 -100 300 R 40 40 4 1 I 213 | X ~ 14 500 0 300 L 40 40 4 1 O 214 | ENDDRAW 215 | ENDDEF 216 | # 217 | # MCP1824 218 | # 219 | DEF MCP1824 U 0 40 Y Y 1 F N 220 | F0 "U" -300 300 60 V V C CNN 221 | F1 "MCP1824" 0 0 60 H V C CNN 222 | F2 "" 0 0 60 H V C CNN 223 | F3 "" 0 0 60 H V C CNN 224 | DRAW 225 | S 250 350 -250 -350 0 1 0 N 226 | X VIN 1 -100 -650 300 U 50 50 1 1 W 227 | X GND 2 0 -650 300 U 50 50 1 1 W 228 | X ~SHDN 3 100 -650 300 U 50 50 1 1 I 229 | X PWRGD 4 100 650 300 D 50 50 1 1 O 230 | X VOUT 5 -100 650 300 D 50 50 1 1 w 231 | ENDDRAW 232 | ENDDEF 233 | # 234 | # MCP7383x 235 | # 236 | DEF MCP7383x U 0 40 Y Y 1 F N 237 | F0 "U" 0 -100 50 H V C CNN 238 | F1 "MCP7383x" 0 100 50 H V C CNN 239 | F2 "MODULE" 0 0 50 H I C CNN 240 | F3 "DOCUMENTATION" 0 0 50 H I C CNN 241 | DRAW 242 | S -450 -300 450 300 1 0 0 N 243 | X STAT 1 -750 100 300 R 50 50 1 1 O 244 | X VSS 2 -750 0 300 R 50 50 1 1 W 245 | X VBAT 3 -750 -100 300 R 50 50 1 1 w 246 | X VDD 4 750 -100 300 L 50 50 1 1 W 247 | X PROG 5 750 100 300 L 50 50 1 1 O 248 | ENDDRAW 249 | ENDDEF 250 | # 251 | # MICRO-SD 252 | # 253 | DEF MICRO-SD U 0 40 Y Y 1 F N 254 | F0 "U" 400 -450 60 H V C CNN 255 | F1 "MICRO-SD" 0 -450 60 H V C CNN 256 | F2 "" 0 0 60 H V C CNN 257 | F3 "" 0 0 60 H V C CNN 258 | DRAW 259 | S -450 500 450 -400 0 1 0 N 260 | X DAT2 1 -350 800 300 D 50 50 1 1 C 261 | X CD/DAT3 2 -250 800 300 D 50 50 1 1 C 262 | X CMD 3 -150 800 300 D 50 50 1 1 C 263 | X VDD 4 -50 800 300 D 50 50 1 1 C 264 | X CLK 5 50 800 300 D 50 50 1 1 C 265 | X VSS 6 150 800 300 D 50 50 1 1 C 266 | X DAT0 7 250 800 300 D 50 50 1 1 C 267 | X DAT1 8 350 800 300 D 50 50 1 1 C 268 | X CDA 9 750 200 300 L 50 50 1 1 C 269 | X CDB 10 750 100 300 L 50 50 1 1 C 270 | X SHIELD1 11 -750 0 300 R 50 50 1 1 C 271 | X SHIELD2 12 -750 -100 300 R 50 50 1 1 C 272 | X SIHELD3 13 -750 -200 300 R 50 50 1 1 C 273 | X SHIELD4 14 -750 -300 300 R 50 50 1 1 I 274 | ENDDRAW 275 | ENDDEF 276 | # 277 | # Q_NMOS_GSD 278 | # 279 | DEF Q_NMOS_GSD Q 0 0 Y N 1 F N 280 | F0 "Q" 300 50 50 H V R CNN 281 | F1 "Q_NMOS_GSD" 650 -50 50 H V R CNN 282 | F2 "" 200 100 50 H V C CNN 283 | F3 "" 0 0 50 H V C CNN 284 | DRAW 285 | C 50 0 111 0 1 10 N 286 | P 2 0 1 0 30 -70 100 -70 N 287 | P 2 0 1 10 30 -50 30 -90 N 288 | P 2 0 1 0 30 0 100 0 N 289 | P 2 0 1 10 30 20 30 -20 N 290 | P 2 0 1 0 30 70 100 70 N 291 | P 2 0 1 10 30 90 30 50 N 292 | P 2 0 1 0 100 -70 100 -100 N 293 | P 2 0 1 0 100 -70 100 0 N 294 | P 2 0 1 0 100 100 100 70 N 295 | P 3 0 1 10 10 75 10 -75 10 -75 N 296 | P 4 0 1 0 40 0 80 15 80 -15 40 0 F 297 | X G 1 -200 0 210 R 50 50 1 1 I 298 | X S 2 100 -200 100 U 50 50 1 1 P 299 | X D 3 100 200 100 D 50 50 1 1 P 300 | ENDDRAW 301 | ENDDEF 302 | # 303 | # Q_PMOS_GSD 304 | # 305 | DEF Q_PMOS_GSD Q 0 0 Y N 1 F N 306 | F0 "Q" 300 50 50 H V R CNN 307 | F1 "Q_PMOS_GSD" 650 -50 50 H V R CNN 308 | F2 "" 200 100 50 H V C CNN 309 | F3 "" 0 0 50 H V C CNN 310 | DRAW 311 | C 50 0 111 0 1 10 N 312 | P 2 0 1 0 30 -70 100 -70 N 313 | P 2 0 1 10 30 -50 30 -90 N 314 | P 2 0 1 0 30 0 100 0 N 315 | P 2 0 1 10 30 20 30 -20 N 316 | P 2 0 1 0 30 70 100 70 N 317 | P 2 0 1 10 30 90 30 50 N 318 | P 2 0 1 0 100 -70 100 -100 N 319 | P 2 0 1 0 100 -70 100 0 N 320 | P 2 0 1 0 100 100 100 70 N 321 | P 3 0 1 10 10 75 10 -75 10 -75 N 322 | P 4 0 1 0 90 0 50 -15 50 15 90 0 F 323 | X G 1 -200 0 210 R 50 50 1 1 I 324 | X S 2 100 -200 100 U 50 50 1 1 P 325 | X D 3 100 200 100 D 50 50 1 1 P 326 | ENDDRAW 327 | ENDDEF 328 | # 329 | # R-RESCUE-rfid 330 | # 331 | DEF R-RESCUE-rfid R 0 0 N Y 1 F N 332 | F0 "R" 80 0 40 V V C CNN 333 | F1 "R-RESCUE-rfid" 7 1 40 V V C CNN 334 | F2 "" -70 0 30 V V C CNN 335 | F3 "" 0 0 30 H V C CNN 336 | $FPLIST 337 | R? 338 | SM0603 339 | SM0805 340 | R?-* 341 | SM1206 342 | $ENDFPLIST 343 | DRAW 344 | S -40 150 40 -150 0 1 12 N 345 | X ~ 1 0 250 100 D 60 60 1 1 P 346 | X ~ 2 0 -250 100 U 60 60 1 1 P 347 | ENDDRAW 348 | ENDDEF 349 | # 350 | # STM32F030-20 351 | # 352 | DEF STM32F030-20 U 0 40 Y Y 1 F N 353 | F0 "U" 0 -100 50 H V C CNN 354 | F1 "STM32F030-20" 0 100 50 H V C CNN 355 | F2 "MODULE" 0 0 50 H I C CNN 356 | F3 "DOCUMENTATION" 0 0 50 H I C CNN 357 | DRAW 358 | S -550 -650 550 650 1 0 0 N 359 | X BOOT0 1 -850 450 300 R 50 50 1 1 I 360 | X PF0/OSC_IN 2 -850 350 300 R 50 50 1 1 B 361 | X PF1/OSC_OUT 3 -850 250 300 R 50 50 1 1 B 362 | X NRST 4 -850 150 300 R 50 50 1 1 I 363 | X VDDA 5 -850 50 300 R 50 50 1 1 W 364 | X PA0 6 -850 -50 300 R 50 50 1 1 B 365 | X PA1 7 -850 -150 300 R 50 50 1 1 B 366 | X PA2 8 -850 -250 300 R 50 50 1 1 B 367 | X PA3 9 -850 -350 300 R 50 50 1 1 B 368 | X PA4 10 -850 -450 300 R 50 50 1 1 B 369 | X PA14 20 850 450 300 L 50 50 1 1 B 370 | X PA5 11 850 -450 300 L 50 50 1 1 B 371 | X PA6 12 850 -350 300 L 50 50 1 1 B 372 | X PA7 13 850 -250 300 L 50 50 1 1 B 373 | X PB1 14 850 -150 300 L 50 50 1 1 B 374 | X VSS 15 850 -50 300 L 50 50 1 1 W 375 | X VDD 16 850 50 300 L 50 50 1 1 W 376 | X PA9 17 850 150 300 L 50 50 1 1 B 377 | X PA10 18 850 250 300 L 50 50 1 1 B 378 | X PA13 19 850 350 300 L 50 50 1 1 B 379 | ENDDRAW 380 | ENDDEF 381 | # 382 | # SWITCH_INV 383 | # 384 | DEF SWITCH_INV SW 0 0 N Y 1 F N 385 | F0 "SW" -200 150 50 H V C CNN 386 | F1 "SWITCH_INV" -150 -150 50 H V C CNN 387 | F2 "" 0 0 50 H V C CNN 388 | F3 "" 0 0 50 H V C CNN 389 | DRAW 390 | C -150 0 50 0 0 0 N 391 | C 150 -100 50 0 0 0 N 392 | C 150 100 50 0 1 0 N 393 | P 2 0 1 0 -100 0 150 50 N 394 | X 1 1 500 100 300 L 50 50 1 1 P 395 | X 2 2 -500 0 300 R 50 50 1 1 P 396 | X 3 3 500 -100 300 L 50 50 1 1 P 397 | ENDDRAW 398 | ENDDEF 399 | # 400 | # TACT 401 | # 402 | DEF TACT SW 0 40 Y Y 1 F N 403 | F0 "SW" 0 300 60 H V C CNN 404 | F1 "TACT" 0 -150 60 H V C CNN 405 | F2 "" 0 0 60 H V C CNN 406 | F3 "" 0 0 60 H V C CNN 407 | DRAW 408 | C -150 0 50 0 1 0 N 409 | C 150 0 50 0 1 0 N 410 | P 2 0 1 0 -300 0 -150 0 N 411 | P 2 0 1 0 -150 0 100 150 N 412 | P 2 0 1 0 150 0 300 0 N 413 | X ~ 1 -300 300 300 D 50 50 1 1 P 414 | X ~ 2 -300 -300 300 U 50 50 1 1 P 415 | X ~ 3 300 300 300 D 50 50 1 1 P 416 | X ~ 4 300 -300 300 U 50 50 1 1 P 417 | ENDDRAW 418 | ENDDEF 419 | # 420 | # USB_OTG 421 | # 422 | DEF USB_OTG P 0 40 Y Y 1 F N 423 | F0 "P" 325 -125 50 H V C CNN 424 | F1 "USB_OTG" 0 200 50 H V C CNN 425 | F2 "" -50 -100 50 V V C CNN 426 | F3 "" -50 -100 50 V V C CNN 427 | $FPLIST 428 | USB* 429 | $ENDFPLIST 430 | DRAW 431 | S -250 -150 250 150 0 1 0 N 432 | S -205 -150 -195 -120 0 1 0 N 433 | S -105 -150 -95 -120 0 1 0 N 434 | S -5 -150 5 -120 0 1 0 N 435 | S 95 -150 105 -120 0 1 0 N 436 | S 195 -150 205 -120 0 1 0 N 437 | X VCC 1 -200 -300 150 U 50 50 1 1 w 438 | X D- 2 -100 -300 150 U 50 50 1 1 P 439 | X D+ 3 0 -300 150 U 50 50 1 1 P 440 | X ID 4 100 -300 150 U 50 50 1 1 W 441 | X GND 5 200 -300 150 U 50 50 1 1 W 442 | X shield 6 400 100 150 L 50 50 1 1 P 443 | ENDDRAW 444 | ENDDEF 445 | # 446 | # VDD 447 | # 448 | DEF VDD #PWR 0 0 Y Y 1 F P 449 | F0 "#PWR" 0 -150 50 H I C CNN 450 | F1 "VDD" 0 150 50 H V C CNN 451 | F2 "" 0 0 50 H V C CNN 452 | F3 "" 0 0 50 H V C CNN 453 | DRAW 454 | C 0 75 25 0 1 0 N 455 | P 2 0 1 0 0 0 0 50 N 456 | X VDD 1 0 0 0 U 50 50 1 1 W N 457 | ENDDRAW 458 | ENDDEF 459 | # 460 | # ZENER 461 | # 462 | DEF ZENER D 0 40 N N 1 F N 463 | F0 "D" 0 100 50 H V C CNN 464 | F1 "ZENER" 0 -100 50 H V C CNN 465 | F2 "" 0 0 50 H V C CNN 466 | F3 "" 0 0 50 H V C CNN 467 | $FPLIST 468 | D? 469 | SO* 470 | SM* 471 | $ENDFPLIST 472 | DRAW 473 | P 5 0 1 8 -70 50 -50 30 -50 -30 -30 -50 -30 -50 N 474 | P 5 0 1 0 -50 0 50 50 50 -50 -50 0 -50 0 F 475 | X K 1 -200 0 150 R 50 50 1 1 P 476 | X A 2 200 0 150 L 50 50 1 1 P 477 | ENDDRAW 478 | ENDDEF 479 | # 480 | #End Library 481 | -------------------------------------------------------------------------------- /rfid-rescue.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # LED-RESCUE-rfid 5 | # 6 | DEF LED-RESCUE-rfid D 0 40 Y N 1 F N 7 | F0 "D" 0 100 50 H V C CNN 8 | F1 "LED-RESCUE-rfid" 0 -100 50 H V C CNN 9 | F2 "" 0 0 50 H V C CNN 10 | F3 "" 0 0 50 H V C CNN 11 | $FPLIST 12 | LED-3MM 13 | LED-5MM 14 | LED-10MM 15 | LED-0603 16 | LED-0805 17 | LED-1206 18 | LEDV 19 | $ENDFPLIST 20 | DRAW 21 | P 2 0 1 0 -50 50 -50 -50 N 22 | P 3 0 1 0 -80 -25 -125 -65 -120 -40 N 23 | P 3 0 1 0 -65 -40 -110 -80 -105 -55 N 24 | P 3 0 1 0 50 50 -50 0 50 -50 F 25 | X K 1 -200 0 150 R 40 40 1 1 P 26 | X A 2 200 0 150 L 40 40 1 1 P 27 | ENDDRAW 28 | ENDDEF 29 | # 30 | # USB_OTG-RESCUE-rfid 31 | # 32 | DEF USB_OTG-RESCUE-rfid P 0 40 Y Y 1 F N 33 | F0 "P" 325 -125 50 H V C CNN 34 | F1 "USB_OTG-RESCUE-rfid" 0 200 50 H V C CNN 35 | F2 "" -50 -100 50 V V C CNN 36 | F3 "" -50 -100 50 V V C CNN 37 | $FPLIST 38 | USB* 39 | $ENDFPLIST 40 | DRAW 41 | S -250 -150 250 150 0 1 0 N 42 | S -205 -150 -195 -120 0 1 0 N 43 | S -105 -150 -95 -120 0 1 0 N 44 | S -5 -150 5 -120 0 1 0 N 45 | S 95 -150 105 -120 0 1 0 N 46 | S 195 -150 205 -120 0 1 0 N 47 | X VCC 1 -200 -300 150 U 50 50 1 1 w 48 | X D- 2 -100 -300 150 U 50 50 1 1 P 49 | X D+ 3 0 -300 150 U 50 50 1 1 P 50 | X ID 4 100 -300 150 U 50 50 1 1 W 51 | X GND 5 200 -300 150 U 50 50 1 1 W 52 | X shield 6 400 100 150 L 50 50 1 1 P 53 | ENDDRAW 54 | ENDDEF 55 | # 56 | #End Library 57 | -------------------------------------------------------------------------------- /rfid.cmp: -------------------------------------------------------------------------------- 1 | Cmp-Mod V01 Created by CvPcb (2013-may-18)-stable date = Sat 19 Dec 2015 08:58:20 PM EST 2 | 3 | BeginCmp 4 | TimeStamp = /5664F34D; 5 | Reference = BT1; 6 | ValeurCmp = BATTERY; 7 | IdModule = SIL-2; 8 | EndCmp 9 | 10 | BeginCmp 11 | TimeStamp = /56650527; 12 | Reference = C1; 13 | ValeurCmp = 1u; 14 | IdModule = SA0805; 15 | EndCmp 16 | 17 | BeginCmp 18 | TimeStamp = /56650534; 19 | Reference = C2; 20 | ValeurCmp = 1u; 21 | IdModule = SA0805; 22 | EndCmp 23 | 24 | BeginCmp 25 | TimeStamp = /56651B3C; 26 | Reference = C3; 27 | ValeurCmp = 1u; 28 | IdModule = SA0805; 29 | EndCmp 30 | 31 | BeginCmp 32 | TimeStamp = /566537E8; 33 | Reference = C4; 34 | ValeurCmp = 100n; 35 | IdModule = SA0402; 36 | EndCmp 37 | 38 | BeginCmp 39 | TimeStamp = /5665071A; 40 | Reference = C5; 41 | ValeurCmp = 47u; 42 | IdModule = SA0402; 43 | EndCmp 44 | 45 | BeginCmp 46 | TimeStamp = /56650FDD; 47 | Reference = C6; 48 | ValeurCmp = 100n; 49 | IdModule = SA0402; 50 | EndCmp 51 | 52 | BeginCmp 53 | TimeStamp = /56650567; 54 | Reference = C7; 55 | ValeurCmp = 2u2; 56 | IdModule = SA0402; 57 | EndCmp 58 | 59 | BeginCmp 60 | TimeStamp = /56650714; 61 | Reference = C8; 62 | ValeurCmp = 100n; 63 | IdModule = SA0402; 64 | EndCmp 65 | 66 | BeginCmp 67 | TimeStamp = /566FCD0F; 68 | Reference = C9; 69 | ValeurCmp = 1n; 70 | IdModule = SA0402; 71 | EndCmp 72 | 73 | BeginCmp 74 | TimeStamp = /566FE89C; 75 | Reference = C10; 76 | ValeurCmp = 100n; 77 | IdModule = SA0402; 78 | EndCmp 79 | 80 | BeginCmp 81 | TimeStamp = /5664F6F8; 82 | Reference = C11; 83 | ValeurCmp = 1n; 84 | IdModule = SA0402; 85 | EndCmp 86 | 87 | BeginCmp 88 | TimeStamp = /56623D6F; 89 | Reference = CON1; 90 | ValeurCmp = USB-MINI-B; 91 | IdModule = USB_MINI_B; 92 | EndCmp 93 | 94 | BeginCmp 95 | TimeStamp = /56656684; 96 | Reference = D1; 97 | ValeurCmp = PWR; 98 | IdModule = SA0603_LED; 99 | EndCmp 100 | 101 | BeginCmp 102 | TimeStamp = /566F7FCD; 103 | Reference = D2; 104 | ValeurCmp = DUAL_LED; 105 | IdModule = SA0605_DUAL_LED; 106 | EndCmp 107 | 108 | BeginCmp 109 | TimeStamp = /56656214; 110 | Reference = D3; 111 | ValeurCmp = READ; 112 | IdModule = SA0603_LED; 113 | EndCmp 114 | 115 | BeginCmp 116 | TimeStamp = /56656221; 117 | Reference = D4; 118 | ValeurCmp = WRITE; 119 | IdModule = SA0603_LED; 120 | EndCmp 121 | 122 | BeginCmp 123 | TimeStamp = /56656227; 124 | Reference = D5; 125 | ValeurCmp = SPOOF; 126 | IdModule = SA0603_LED; 127 | EndCmp 128 | 129 | BeginCmp 130 | TimeStamp = /566FCBB2; 131 | Reference = D6; 132 | ValeurCmp = 1N4148; 133 | IdModule = sod523; 134 | EndCmp 135 | 136 | BeginCmp 137 | TimeStamp = /566FCC69; 138 | Reference = D7; 139 | ValeurCmp = 1N4148; 140 | IdModule = sod523; 141 | EndCmp 142 | 143 | BeginCmp 144 | TimeStamp = /566F783B; 145 | Reference = D8; 146 | ValeurCmp = 5V6; 147 | IdModule = sod523; 148 | EndCmp 149 | 150 | BeginCmp 151 | TimeStamp = /5664F707; 152 | Reference = L1; 153 | ValeurCmp = COIL; 154 | IdModule = SIL-2; 155 | EndCmp 156 | 157 | BeginCmp 158 | TimeStamp = /56624561; 159 | Reference = Q1; 160 | ValeurCmp = FET_P; 161 | IdModule = SOT23GDS; 162 | EndCmp 163 | 164 | BeginCmp 165 | TimeStamp = /566F769B; 166 | Reference = Q2; 167 | ValeurCmp = FET_N; 168 | IdModule = SOT23GDS; 169 | EndCmp 170 | 171 | BeginCmp 172 | TimeStamp = /566F7A90; 173 | Reference = Q3; 174 | ValeurCmp = FET_P; 175 | IdModule = SOT23GDS; 176 | EndCmp 177 | 178 | BeginCmp 179 | TimeStamp = /566F77C4; 180 | Reference = Q4; 181 | ValeurCmp = FET_N; 182 | IdModule = SOT23GDS; 183 | EndCmp 184 | 185 | BeginCmp 186 | TimeStamp = /56678B30; 187 | Reference = Q5; 188 | ValeurCmp = FET_N; 189 | IdModule = SOT23GDS; 190 | EndCmp 191 | 192 | BeginCmp 193 | TimeStamp = /5665668A; 194 | Reference = R1; 195 | ValeurCmp = 330R; 196 | IdModule = SA0402; 197 | EndCmp 198 | 199 | BeginCmp 200 | TimeStamp = /566F7FE6; 201 | Reference = R2; 202 | ValeurCmp = 680R; 203 | IdModule = SA0402; 204 | EndCmp 205 | 206 | BeginCmp 207 | TimeStamp = /566523FF; 208 | Reference = R3; 209 | ValeurCmp = 560R; 210 | IdModule = SA0402; 211 | EndCmp 212 | 213 | BeginCmp 214 | TimeStamp = /56656263; 215 | Reference = R4; 216 | ValeurCmp = 330R; 217 | IdModule = SA0402; 218 | EndCmp 219 | 220 | BeginCmp 221 | TimeStamp = /56656270; 222 | Reference = R5; 223 | ValeurCmp = 330R; 224 | IdModule = SA0402; 225 | EndCmp 226 | 227 | BeginCmp 228 | TimeStamp = /56656276; 229 | Reference = R6; 230 | ValeurCmp = 330R; 231 | IdModule = SA0402; 232 | EndCmp 233 | 234 | BeginCmp 235 | TimeStamp = /56651AF1; 236 | Reference = R7; 237 | ValeurCmp = 2K2; 238 | IdModule = SA0402; 239 | EndCmp 240 | 241 | BeginCmp 242 | TimeStamp = /56623F16; 243 | Reference = R8; 244 | ValeurCmp = 100K; 245 | IdModule = SA0402; 246 | EndCmp 247 | 248 | BeginCmp 249 | TimeStamp = /566FCBC1; 250 | Reference = R9; 251 | ValeurCmp = 470K; 252 | IdModule = SA0402; 253 | EndCmp 254 | 255 | BeginCmp 256 | TimeStamp = /566FCBD0; 257 | Reference = R10; 258 | ValeurCmp = 10K; 259 | IdModule = SA0402; 260 | EndCmp 261 | 262 | BeginCmp 263 | TimeStamp = /566506F2; 264 | Reference = R11; 265 | ValeurCmp = 470R; 266 | IdModule = SA0402; 267 | EndCmp 268 | 269 | BeginCmp 270 | TimeStamp = /566F7AFA; 271 | Reference = R12; 272 | ValeurCmp = 1K; 273 | IdModule = SA0402; 274 | EndCmp 275 | 276 | BeginCmp 277 | TimeStamp = /566F784A; 278 | Reference = R13; 279 | ValeurCmp = 100K; 280 | IdModule = SA0402; 281 | EndCmp 282 | 283 | BeginCmp 284 | TimeStamp = /566FE1E1; 285 | Reference = R14; 286 | ValeurCmp = 100R; 287 | IdModule = SA0402; 288 | EndCmp 289 | 290 | BeginCmp 291 | TimeStamp = /566FCD1E; 292 | Reference = R15; 293 | ValeurCmp = 470K; 294 | IdModule = SA0402; 295 | EndCmp 296 | 297 | BeginCmp 298 | TimeStamp = /566FD45C; 299 | Reference = R16; 300 | ValeurCmp = 1K; 301 | IdModule = SA0402; 302 | EndCmp 303 | 304 | BeginCmp 305 | TimeStamp = /566FD47A; 306 | Reference = R17; 307 | ValeurCmp = 1K; 308 | IdModule = SA0402; 309 | EndCmp 310 | 311 | BeginCmp 312 | TimeStamp = /566FD46B; 313 | Reference = R18; 314 | ValeurCmp = 470K; 315 | IdModule = SA0402; 316 | EndCmp 317 | 318 | BeginCmp 319 | TimeStamp = /566FD489; 320 | Reference = R19; 321 | ValeurCmp = 470K; 322 | IdModule = SA0402; 323 | EndCmp 324 | 325 | BeginCmp 326 | TimeStamp = /5664F5C7; 327 | Reference = SW1; 328 | ValeurCmp = POWER; 329 | IdModule = SIL-3; 330 | EndCmp 331 | 332 | BeginCmp 333 | TimeStamp = /566240F3; 334 | Reference = SW2; 335 | ValeurCmp = MODE; 336 | IdModule = TACT-SW-SMD; 337 | EndCmp 338 | 339 | BeginCmp 340 | TimeStamp = /56657211; 341 | Reference = U1; 342 | ValeurCmp = MCP1824; 343 | IdModule = SOT23-5; 344 | EndCmp 345 | 346 | BeginCmp 347 | TimeStamp = /56651AD8; 348 | Reference = U2; 349 | ValeurCmp = MCP7383X; 350 | IdModule = SOT23-5; 351 | EndCmp 352 | 353 | BeginCmp 354 | TimeStamp = /566537AE; 355 | Reference = U3; 356 | ValeurCmp = MICRO-SD; 357 | IdModule = DM3BT; 358 | EndCmp 359 | 360 | BeginCmp 361 | TimeStamp = /566543CC; 362 | Reference = U4; 363 | ValeurCmp = STM32F030-20; 364 | IdModule = tssop-20; 365 | EndCmp 366 | 367 | BeginCmp 368 | TimeStamp = /566FCAFB; 369 | Reference = U5; 370 | ValeurCmp = LM324; 371 | IdModule = tssop-14; 372 | EndCmp 373 | 374 | EndListe 375 | -------------------------------------------------------------------------------- /rfid.pro: -------------------------------------------------------------------------------- 1 | update=Sat 18 Mar 2017 11:55:42 AM EDT 2 | version=1 3 | last_client=kicad 4 | [cvpcb] 5 | version=1 6 | NetIExt=net 7 | [cvpcb/libraries] 8 | EquName1=devcms 9 | [general] 10 | version=1 11 | [pcbnew] 12 | version=1 13 | LastNetListRead= 14 | UseCmpFile=1 15 | PadDrill=" 0.600000" 16 | PadDrillOvalY=" 0.600000" 17 | PadSizeH=" 1.500000" 18 | PadSizeV=" 1.500000" 19 | PcbTextSizeV=" 1.500000" 20 | PcbTextSizeH=" 1.500000" 21 | PcbTextThickness=" 0.300000" 22 | ModuleTextSizeV=" 1.000000" 23 | ModuleTextSizeH=" 1.000000" 24 | ModuleTextSizeThickness=" 0.150000" 25 | SolderMaskClearance=" 0.000000" 26 | SolderMaskMinWidth=" 0.000000" 27 | DrawSegmentWidth=" 0.200000" 28 | BoardOutlineThickness=" 0.100000" 29 | ModuleOutlineThickness=" 0.150000" 30 | [pcbnew/libraries] 31 | LibDir= 32 | LibName1=sockets 33 | LibName2=connect 34 | LibName3=discret 35 | LibName4=pin_array 36 | LibName5=divers 37 | LibName6=smd_capacitors 38 | LibName7=smd_resistors 39 | LibName8=smd_crystal&oscillator 40 | LibName9=smd_dil 41 | LibName10=smd_transistors 42 | LibName11=libcms 43 | LibName12=display 44 | LibName13=led 45 | LibName14=dip_sockets 46 | LibName15=pga_sockets 47 | LibName16=valves 48 | LibName17=/home/eric/kicad/bat-hld-001 49 | LibName18=/home/eric/kicad/crystal 50 | LibName19=/home/eric/kicad/custom 51 | LibName20=/home/eric/kicad/custom2 52 | LibName21=/home/eric/kicad/diode-MiniMelf 53 | LibName22=/home/eric/kicad/keyed_header 54 | LibName23=/home/eric/kicad/lqfp 55 | LibName24=/home/eric/kicad/lqfp-32 56 | LibName25=/home/eric/kicad/molex 57 | LibName26=/home/eric/kicad/sane_smt 58 | LibName27=/home/eric/kicad/tact 59 | LibName28=/home/eric/kicad/tssop20 60 | LibName29=/home/eric/kicad/tssop-10 61 | LibName30=/home/eric/kicad/TSSOP-28-EP 62 | LibName31=/home/eric/kicad/xt-60 63 | LibName32=/home/eric/kicad/w_smd_diode 64 | [eeschema] 65 | version=1 66 | LibDir= 67 | [eeschema/libraries] 68 | LibName1=rfid-rescue 69 | LibName2=power 70 | LibName3=device 71 | LibName4=transistors 72 | LibName5=conn 73 | LibName6=linear 74 | LibName7=regul 75 | LibName8=74xx 76 | LibName9=cmos4000 77 | LibName10=adc-dac 78 | LibName11=memory 79 | LibName12=xilinx 80 | LibName13=special 81 | LibName14=microcontrollers 82 | LibName15=dsp 83 | LibName16=microchip 84 | LibName17=analog_switches 85 | LibName18=motorola 86 | LibName19=texas 87 | LibName20=intel 88 | LibName21=audio 89 | LibName22=interface 90 | LibName23=digital-audio 91 | LibName24=philips 92 | LibName25=display 93 | LibName26=cypress 94 | LibName27=siliconi 95 | LibName28=opto 96 | LibName29=atmel 97 | LibName30=contrib 98 | LibName31=valves 99 | LibName32=/home/eric/kicad/custom 100 | -------------------------------------------------------------------------------- /rfid_rev1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ervanalb/rfid/3f7f5405db242571d21b380da9c55f51d95c4271/rfid_rev1.zip -------------------------------------------------------------------------------- /sed.sh: -------------------------------------------------------------------------------- 1 | cp rfid.kicad_pcb rfid_old.kicad_pcb 2 | sed -r '/fp_text/N;s/(\(fp_text.+\n.*\(size )[^)]+\) \(thickness [^)]+/\10.762 0.762) (thickness 0.130/' rfid_old.kicad_pcb > rfid.kicad_pcb 3 | -------------------------------------------------------------------------------- /spiral.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sed \$d rfid_orig.kicad_pcb > rfid.kicad_pcb 4 | python spiraller.py >> rfid.kicad_pcb 5 | echo ")" >> rfid.kicad_pcb 6 | -------------------------------------------------------------------------------- /spiraller.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import math 3 | import sys 4 | 5 | UP = 0.381 6 | SPIRALS = 20 7 | OUTSIDE_X_RADIUS = 25.4 - 0.381 8 | INSIDE_X_RADIUS = 9.525 9 | OUTSIDE_Y_RADIUS = 28.575 - UP * 2 10 | INSIDE_Y_RADIUS = 9.525 11 | OUTSIDE_POW = 4 12 | INSIDE_POW = 1 13 | CHANGE_POW = OUTSIDE_POW / 2 14 | N = 5000 15 | WIDTH = 0.6096 16 | LAYER = "F.Cu" 17 | CENTER_X = 197.612 18 | CENTER_Y = 106.553 - UP 19 | START = 0.25 20 | 21 | def sp(x, p): 22 | return math.copysign(abs(x) ** (1 / p), x) 23 | 24 | def f(t): 25 | x_r = (1 - t) * INSIDE_X_RADIUS + t * OUTSIDE_X_RADIUS 26 | y_r = (1 - t) * INSIDE_Y_RADIUS + t * OUTSIDE_Y_RADIUS 27 | theta = (2 * math.pi * (t * SPIRALS + START)) 28 | t2 = t ** CHANGE_POW 29 | p = (1 - t2) * INSIDE_POW + t2 * OUTSIDE_POW 30 | x = x_r * sp(math.cos(theta), p) + CENTER_X 31 | y = y_r * sp(math.sin(theta), p) + CENTER_Y 32 | return (x, y) 33 | 34 | pts = [] 35 | for i in range(0, N + 1): 36 | pts.append(f(i / N)) 37 | 38 | #(x, y) = zip(*pts) 39 | #plt.plot(x, y) 40 | #plt.gca().set_aspect('equal') 41 | #plt.show() 42 | 43 | length = 0 44 | for ((x1, y1), (x2, y2)) in zip(pts[:-1], pts[1:]): 45 | print(" (segment (start {} {}) (end {} {}) (width {}) (layer {}))".format(x1, y1, x2, y2, WIDTH, LAYER)) 46 | length += math.hypot(x2 - x1, y2 - y1) 47 | print(length, file=sys.stderr) 48 | --------------------------------------------------------------------------------