├── .gitignore ├── CMakeLists.txt ├── LICENSE.txt ├── QAPRSBase.cpp ├── QAPRSBase.h ├── QAPRSCommon.h ├── README.md ├── RS41HUP.coproj ├── RS41HUP └── .readme.md ├── aprs.cpp ├── aprs.h ├── arm-gcc-link.ld ├── cmsis ├── .readme.md ├── core_cm3.h ├── core_cmFunc.h └── core_cmInstr.h ├── cmsis_boot ├── .readme.md ├── startup │ ├── .readme.md │ └── startup_stm32f10x_md_vl.c ├── stm32f10x.h ├── stm32f10x_conf.h ├── system_stm32f10x.c └── system_stm32f10x.h ├── config.h ├── delay.c ├── delay.h ├── docs ├── Si4030-31-32.pdf ├── Si4030_31_32_register_descriptions_AN466.pdf ├── infos_for_sensors.txt ├── pinout_extension_port.txt └── stm32f100c8t6b_en.CD00251732.pdf ├── f_rtty.c ├── f_rtty.h ├── init.c ├── init.h ├── main.c ├── radio.c ├── radio.h ├── stm_lib ├── .readme.md ├── inc │ ├── .readme.md │ ├── misc.h │ ├── stm32f10x_adc.h │ ├── stm32f10x_dma.h │ ├── stm32f10x_flash.h │ ├── stm32f10x_gpio.h │ ├── stm32f10x_pwr.h │ ├── stm32f10x_rcc.h │ ├── stm32f10x_spi.h │ ├── stm32f10x_tim.h │ └── stm32f10x_usart.h └── src │ ├── .readme.md │ ├── misc.c │ ├── stm32f10x_adc.c │ ├── stm32f10x_dma.c │ ├── stm32f10x_flash.c │ ├── stm32f10x_gpio.c │ ├── stm32f10x_pwr.c │ ├── stm32f10x_rcc.c │ ├── stm32f10x_spi.c │ ├── stm32f10x_tim.c │ └── stm32f10x_usart.c ├── syscalls ├── .readme.md └── syscalls.c ├── ublox.c └── ublox.h /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /cmake-build-debug 3 | /rtty/Debug/bin 4 | /rtty/Debug/obj 5 | /RS41HUP 6 | *~ 7 | /RS41HUP.cogui 8 | /RS41HUP.comarker 9 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.6) 2 | include(CMakeForceCompiler) 3 | SET(CMAKE_SYSTEM_NAME "Generic") 4 | SET(CMAKE_SYSTEM_VERSION 1) 5 | 6 | 7 | if (UNIX) 8 | set(TOOLCHAIN_DIR "/opt/gcc-arm-none-eabi-5_4-2016q3/bin/") 9 | # set(CMAKE_C_COMPILER "/opt/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-gcc") 10 | # set(CMAKE_CXX_COMPILER "/opt/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-g++") 11 | CMAKE_FORCE_C_COMPILER(${TOOLCHAIN_DIR}/arm-none-eabi-gcc GNU) 12 | CMAKE_FORCE_CXX_COMPILER(${TOOLCHAIN_DIR}/arm-none-eabi-g++ GNU) 13 | else () 14 | set(TOOLCHAIN_DIR "D:/Programy/GNU Tools ARM Embedded/5.4 2016q3/bin") 15 | CMAKE_FORCE_C_COMPILER(${TOOLCHAIN_DIR}/arm-none-eabi-gcc.exe GNU) 16 | CMAKE_FORCE_CXX_COMPILER(${TOOLCHAIN_DIR}/arm-none-eabi-g++.exe GNU) 17 | endif () 18 | 19 | project(RS41HUP C CXX) 20 | 21 | add_definitions(-DSTM32F100C8) 22 | add_definitions(-DSTM32F10X_MD_VL) 23 | add_definitions(-DUSE_STDPERIPH_DRIVER) 24 | add_definitions(-DSUPPORT_CPLUSPLUS) 25 | add_definitions(-D__ASSEMBLY__) 26 | 27 | SET(LINKER_SCRIPT ${PROJECT_SOURCE_DIR}/arm-gcc-link.ld) 28 | SET(COMMON_FLAGS " -mcpu=cortex-m3 -mthumb -Wall -ffunction-sections -g -O3 -g -nostartfiles ") 29 | SET(CMAKE_CXX_FLAGS "${COMMON_FLAGS} -std=c++11") 30 | SET(CMAKE_C_FLAGS "${COMMON_FLAGS} -std=gnu99") 31 | SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=${CMAKE_BINARY_DIR}/${PROJECT_NAME}.map -lstdc++ -O3 -Wl,--gc-sections --specs=nano.specs -T ${LINKER_SCRIPT}") 32 | 33 | file(GLOB_RECURSE USER_SOURCES "*.c") 34 | file(GLOB_RECURSE USER_SOURCES_CXX "*.cpp") 35 | file(GLOB_RECURSE USER_HEADERS "*.h") 36 | 37 | include_directories(cmsis 38 | cmsis_boot 39 | stm_lib/inc 40 | .) 41 | 42 | add_executable(${PROJECT_NAME}.elf ${USER_SOURCES} ${USER_SOURCES_CXX} ${USER_HEADERS} ${HAL_SOURCES} ${LINKER_SCRIPT}) 43 | 44 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=${CMAKE_BINARY_DIR}/${PROJECT_NAME}.map") 45 | set(HEX_FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.hex) 46 | set(BIN_FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin) 47 | add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD 48 | COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${HEX_FILE} 49 | COMMAND ${CMAKE_OBJCOPY} -Obinary $ ${BIN_FILE} 50 | COMMENT "Building ${HEX_FILE} \nBuilding ${BIN_FILE}" 51 | COMMAND ${TOOLCHAIN_DIR}/arm-none-eabi-size ${PROJECT_NAME}.elf) 52 | 53 | set(CMAKE_CXX_STANDARD 11) 54 | 55 | add_custom_target(program 56 | DEPENDS ${PROJECT_NAME}.elf 57 | 58 | if (UNIX) 59 | #TODO 60 | else () 61 | COMMAND D:/Programy/stlink-1.3.0-win64/bin/st-flash --reset write ${BIN_FILE} 0x08000000 62 | endif () 63 | COMMENT "flashing ${BIN_FILE}") 64 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the -------------------------------------------------------------------------------- /QAPRSBase.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013 Lukasz Nidecki SQ5RWU 3 | 4 | This file is part of ArduinoQAPRS. 5 | 6 | ArduinoQAPRS is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | ArduinoQAPRS is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with ArduinoQAPRS; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | Ten plik jest częścią ArduinoQAPRS. 21 | 22 | ArduinoQAPRS jest wolnym oprogramowaniem; możesz go rozprowadzać dalej 23 | i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, 24 | wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej 25 | Licencji lub (według twojego wyboru) którejś z późniejszych wersji. 26 | 27 | Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on 28 | użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej 29 | gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH 30 | ZASTOSOWAŃ. W celu uzyskania bliższych informacji sięgnij do 31 | Powszechnej Licencji Publicznej GNU. 32 | 33 | Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz 34 | Powszechnej Licencji Publicznej GNU (GNU General Public License); 35 | jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple 36 | Place, Fifth Floor, Boston, MA 02110-1301 USA 37 | 38 | */ 39 | 40 | /** 41 | * @file 42 | * @brief Implementacja klasy QAPRSBase 43 | */ 44 | 45 | #include "QAPRSBase.h" 46 | #include "delay.h" 47 | #include "radio.h" 48 | #include "init.h" 49 | 50 | QAPRSBase * QAPRSGlobalObject; 51 | /** 52 | * Czy można wysyłać dane? 53 | * @return 1 jesli transmisja jest mozliwa, 0 w przeciwnym wypadku 54 | */ 55 | uint8_t QAPRSBase::canTransmit(){ 56 | return 1; 57 | } 58 | 59 | /** 60 | * Rozpocznij nadawanie pakietu ax.25 61 | * Dodatkowo: 62 | * - włącz nadawanie @see enableTransmission 63 | * - zainicjalizuj crc i ton 64 | * Ilosć bajtów synchronizacji okresla @see ax25HeaderFlagFieldCount 65 | */ 66 | void QAPRSBase::ax25SendHeaderBegin() { 67 | this->enableTransmission(); 68 | timerInterruptHandler(); 69 | this->ax25CRC = 0xFFFF; 70 | this->currentTone = QAPRSMark; 71 | //this->currentTone = QAPRSSpace; 72 | 73 | for (uint8_t i=0;iax25HeaderFlagFieldCount;i++) 74 | { 75 | this->ax25SendByte(this->ax25FlagFieldValue); 76 | } 77 | } 78 | 79 | /** 80 | * Wyslij zakończenie pakietu, to jest 2 bajty sumy kontrolnej i znacznik końca pakietu @see QAPRSBase::ax25FlagFieldValue 81 | */ 82 | void QAPRSBase::ax25SendFooter() { 83 | /** 84 | * 16-bit CRC-CCITT 85 | * MBS + LE!!! 86 | * @see: http://www.tapr.org/pub_ax25.html#2.2.7 87 | * @see: http://www.tapr.org/pub_ax25.html#2.2.8 88 | */ 89 | static uint8_t tmp; 90 | tmp = (uint8_t) ((ax25CRC >> 8) ^ 0xff); 91 | 92 | this->ax25SendByte((uint8_t) ((this->ax25CRC) ^ 0xff)); 93 | this->ax25SendByte(tmp); 94 | this->ax25SendByte(this->ax25FlagFieldValue); 95 | this->disableTranssmision(); 96 | } 97 | 98 | /** 99 | * Wysyła bajt ax.25 100 | * @param byte Bajt do wysłania 101 | */ 102 | void QAPRSBase::ax25SendByte(uint8_t byte) { 103 | static uint8_t i; 104 | static uint8_t ls_bit; 105 | static uint8_t is_flag; 106 | static uint8_t bit_stuffing_counter; 107 | 108 | 109 | // zapisujemy sobie czy nadawany bit nie jest aby flagą - bo ją nadajemy w specjalny sposób 110 | is_flag = (uint8_t) (byte == this->ax25FlagFieldValue); 111 | 112 | for(i=0;i<8;i++){ 113 | // nadawanie od najmniejznaczacego bitu 114 | ls_bit = (uint8_t) (byte & 1); 115 | 116 | if (is_flag){ 117 | bit_stuffing_counter = 0; 118 | } else { 119 | this->ax25CalcCRC(ls_bit); 120 | } 121 | 122 | if (ls_bit){ 123 | bit_stuffing_counter++; 124 | if (bit_stuffing_counter == 5){ 125 | // jesli mamy 5 bitow o wartosci 1 z rzedu to 126 | delayuSeconds(this->_toneSendTime); 127 | this->toggleTone(); 128 | bit_stuffing_counter = 0; 129 | } 130 | } else { 131 | bit_stuffing_counter = 0; 132 | this->toggleTone(); 133 | } 134 | byte >>= 1; 135 | delayuSeconds(this->_toneSendTime); 136 | } 137 | } 138 | 139 | /** 140 | * Dodaje bit do sumy kontrolnej ramki 141 | * @param ls_bit Bit danych 142 | */ 143 | void QAPRSBase::ax25CalcCRC(uint8_t ls_bit) { 144 | static unsigned short crc_tmp; 145 | 146 | crc_tmp = this->ax25CRC ^ ls_bit; // XOR lsb of CRC with the latest bit 147 | this->ax25CRC >>= 1; // Shift 16-bit CRC one bit to the right 148 | 149 | if (crc_tmp & 0x0001) // If XOR result from above has lsb set 150 | { 151 | this->ax25CRC ^= 0x8408; // Shift 16-bit CRC one bit to the right 152 | } 153 | } 154 | /** 155 | * Przełącz aktualnie generowany ton. @see QAPRSSendingTone 156 | */ 157 | inline void QAPRSBase::toggleTone() { 158 | this->currentTone = (this->currentTone == QAPRSSpace) ? QAPRSMark : QAPRSSpace; 159 | this->timer1StartValue = (this->currentTone == QAPRSMark) ? MarkTimerValue : SpaceTimerValue; 160 | } 161 | 162 | /** 163 | * Inicjalizuj Timer1 który jest używany do generowania MARK i SPACE 164 | */ 165 | void QAPRSBase::initializeTimer1() { 166 | #if defined(__arm__) 167 | //TODO: przepisać na STM32 168 | #else 169 | noInterrupts(); 170 | TIMSK1 |= _BV(TOIE1); 171 | TCCR1A = 0; 172 | TCCR1C = 0; 173 | interrupts(); 174 | #endif 175 | 176 | } 177 | 178 | /** 179 | * Inicjalizuj radio i piny. 180 | */ 181 | void QAPRSBase::initializeRadio() { 182 | #if defined(__arm__) 183 | //TODO: przepisać na STM32 184 | #else 185 | if (this->sensePin){ 186 | pinMode(abs(this->sensePin), INPUT); 187 | digitalWrite(abs(this->sensePin), LOW); 188 | } 189 | pinMode(abs(this->txEnablePin), OUTPUT); 190 | #endif 191 | 192 | this->disableTranssmision(); 193 | this->initializeTimer1(); 194 | } 195 | 196 | /** 197 | * Włącz nadawanie. Metoda dodatkowo realizuje opóźnienie nadawania jesli ustawiono. @see QAPRSBase::setTxDelay 198 | */ 199 | void QAPRSBase::enableTransmission() { 200 | #if defined(__arm__) 201 | //TODO: przepisać na STM32 202 | #else 203 | digitalWrite(abs(this->txEnablePin), (this->txEnablePin > 0) ? HIGH : LOW); 204 | #endif 205 | 206 | radio_set_tx_frequency(APRS_FREQUENCY); 207 | radio_rw_register(0x72, 5, 1); 208 | GPIO_SetBits(GPIOC, radioNSELpin); 209 | radio_rw_register(0x71, 0b00010010, 1); 210 | spi_deinit(); 211 | this->enabled = 1; 212 | this->doTxDelay(); 213 | } 214 | 215 | /** 216 | * Wyłącz nadawanie. 217 | */ 218 | void QAPRSBase::disableTranssmision() { 219 | #if defined(__arm__) 220 | //TODO: przepisać na STM32 221 | #else 222 | digitalWrite(abs(this->txEnablePin), (this->txEnablePin > 0) ? LOW : HIGH); 223 | #endif 224 | spi_init(); 225 | this->enabled = 0; 226 | radio_set_tx_frequency(RTTY_FREQUENCY); 227 | radio_rw_register(0x71, 0x00, 1); 228 | init_timer(RTTY_SPEED); 229 | } 230 | 231 | /** 232 | * Wyslij bufor danych. @warning Ta metoda zakończy pracę na bajcie o wartosci 0 jesli wystąpi. 233 | * @param buffer Bufor z danymi do wysłania 234 | * @return 235 | */ 236 | QAPRSReturnCode QAPRSBase::send(char * buffer) { 237 | return this->send(buffer, strlen(buffer)); 238 | } 239 | 240 | /** 241 | * Wyslij dane APRS. 242 | * @param from_addr Adres [znak] źródłowy. Max 6 znaków! 243 | * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' 244 | * @param to_addr Adres [znak] docelowy. Max 6 znaków! 245 | * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' 246 | * @param packet_content Bufor z danymi pakietu APRS 247 | * @return 248 | */ 249 | QAPRSReturnCode QAPRSBase::send(char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * packet_content) { 250 | ax25BaseFrame * bf; 251 | bf = (ax25BaseFrame *)tmpData; 252 | memset(bf->from, ' ', 6); 253 | strncpy(bf->from, from_addr,6); 254 | memset(bf->to, ' ', 6); 255 | strncpy(bf->to, to_addr, 6); 256 | bf->to_ssid = to_ssid; 257 | bf->from_ssid = (uint8_t) (from_ssid > '@' ? from_ssid - 6 : from_ssid);; 258 | 259 | strcpy(bf->packet_content, packet_content); 260 | 261 | bf->control_field = 0x03; 262 | bf->protocolID = 0xf0; 263 | 264 | 265 | uint8_t i; 266 | for(i=0;i<14;i++){ 267 | tmpData[i] = SHIFT_BYTE(tmpData[i]); 268 | } 269 | tmpData[13] |= 1; 270 | 271 | return this->send((char*)tmpData); 272 | } 273 | 274 | /** 275 | * Wysyła bufor danych o oznaczonej długosci. 276 | * @param buffer Bufor z danymi do wysłania 277 | * @param length Długosc bufora 278 | * @return 279 | */ 280 | QAPRSReturnCode QAPRSBase::send(char* buffer, size_t length) { 281 | int16_t timeout = this->channelFreeWaitingMS; 282 | 283 | while(timeout > 0){ 284 | // jesli mozna nadawac to nadajemy 285 | if (this->canTransmit()){ 286 | this->ax25SendHeaderBegin(); 287 | while(length--){ 288 | this->ax25SendByte((uint8_t) *buffer); 289 | buffer++; 290 | } 291 | this->ax25SendFooter(); 292 | return QAPRSReturnOK; 293 | } else { 294 | // jesli nie mozna to czekamy 100ms i sprawdzamy ponownie 295 | // maks. czas oczekiwania to channelFreeWaitingMS 296 | #if defined(__arm__) 297 | _delay_ms(100); 298 | #else 299 | delay(100); 300 | #endif 301 | timeout -= 100; 302 | } 303 | } 304 | return QAPRSReturnErrorTimeout; 305 | } 306 | 307 | /** 308 | * Wyslij dane APRS. 309 | * @param from_addr Adres [znak] źródłowy. Max 6 znaków! 310 | * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' 311 | * @param to_addr Adres [znak] docelowy. Max 6 znaków! 312 | * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' 313 | * @param relays Bufor z danymi przekaźników. Np. "WIDE1 1" @warning Jeżeli mają być podane 2 lub więcej pozycji to zapisujemy je BEZ przecinków itp. np. "WIDE1 1WIDE2 1" 314 | * @param packet_content Bufor z danymi pakietu APRS 315 | * @return 316 | */ 317 | QAPRSReturnCode QAPRSBase::send(char* from_addr, uint8_t from_ssid, char* to_addr, uint8_t to_ssid, char* relays, char* packet_content) { 318 | return this->send(from_addr, from_ssid, to_addr, to_ssid, relays, packet_content, strlen(packet_content)); 319 | } 320 | 321 | /** 322 | * Wyslij dane APRS. 323 | * @param from_addr Adres [znak] źródłowy. Max 6 znaków! 324 | * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' 325 | * @param to_addr Adres [znak] docelowy. Max 6 znaków! 326 | * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' 327 | * @param relays Bufor z danymi przekaźników. Np. "WIDE1 1" @warning Jeżeli mają być podane 2 lub więcej pozycji to zapisujemy je BEZ przecinków itp. np. "WIDE1 1WIDE2 1" 328 | * @param packet_content Bufor z danymi pakietu APRS 329 | * @param length Długosć packet_content 330 | * @return 331 | */ 332 | QAPRSReturnCode QAPRSBase::send(char* from_addr, uint8_t from_ssid, char* to_addr, uint8_t to_ssid, char* relays, char* packet_content, size_t length) { 333 | ax25CustomFrameHeader * bf; 334 | bf = (ax25CustomFrameHeader *)tmpData; 335 | memset(bf->from, ' ', 6); 336 | strncpy(bf->from, from_addr,6); 337 | memset(bf->to, ' ', 6); 338 | strncpy(bf->to, to_addr, 6); 339 | bf->to_ssid = to_ssid; 340 | bf->from_ssid = (uint8_t) (from_ssid > '@' ? from_ssid - 6 : from_ssid); 341 | 342 | uint8_t relay_size = (uint8_t) strlen(relays); 343 | strcpy((char*)(tmpData+sizeof(ax25CustomFrameHeader)), relays); 344 | 345 | uint8_t i; 346 | for(i=0;isend((char*)tmpData, (sizeof(ax25CustomFrameHeader)+relay_size+2+length)); 361 | } 362 | 363 | /** 364 | * Wysyła dane APRS @warning Ta metoda zakończy pracę na bajcie o wartosci 0 jesli wystąpi. 365 | * @param buffer Bufor z częscią APRSową ramki - tzn. sam czyste dane APRS, bez SSIDów itp. 366 | * @return Status operacji 367 | */ 368 | QAPRSReturnCode QAPRSBase::sendData(char* buffer) { 369 | return this->send((char*)this->from_addr, this->from_ssid, (char*)this->to_addr, this->to_ssid, (char*)this->relays, buffer); 370 | } 371 | 372 | /** 373 | * Wysyła dane APRS 374 | * @param buffer Bufor z częscią APRSową ramki - tzn. sam czyste dane APRS, bez SSIDów itp. 375 | * @param length Długosć bufora 376 | * @return Status operacji 377 | */ 378 | QAPRSReturnCode QAPRSBase::sendData(char* buffer, size_t length) { 379 | return this->send((char*)this->from_addr, this->from_ssid, (char*)this->to_addr, this->to_ssid, (char*)this->relays, buffer, length); 380 | } 381 | 382 | /** 383 | * Inicjalizacja biblioteki 384 | * @param sensePin Pin [we] Arduino na którym 0 oznacza zgodę na nadwanie a 1 jej brak. 385 | Podanie 0 jako numeru pinu powoduje WYŁACZENIE wykrywania nadawania i zmusza programistę do samodzielnej jego obsługi! 386 | * @param txEnablePin Pin [wy] Arduino na którym 1 oznacza nadawanie 387 | */ 388 | void QAPRSBase::init(int8_t sensePin, int8_t txEnablePin) { 389 | QAPRSGlobalObject = this; 390 | this->sensePin = sensePin; 391 | this->txEnablePin = txEnablePin; 392 | this->txDelay = this->defaultTxDelay; 393 | this->setVariant(); 394 | this->timer1StartValue = MarkTimerValue; 395 | 396 | this->initializeRadio(); 397 | } 398 | 399 | /** 400 | * Zainicjuj bibliotekę na potrzeby metody sendData @see QAPRSBase::sendData 401 | * @param sensePin sensePin Pin [we] Arduino na którym 0 oznacza zgodę na nadwanie a 1 jej brak. 402 | Podanie 0 jako numeru pinu powoduje WYŁACZENIE wykrywania nadawania i zmusza programistę do samodzielnej jego obsługi! 403 | * @param txEnablePin Pin [wy] Arduino na którym 1 oznacza nadawanie 404 | * @param from_addr Adres [znak] źródłowy. Max 6 znaków! 405 | * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' 406 | * @param to_addr Adres [znak] docelowy. Max 6 znaków! 407 | * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' 408 | * @param relays Ścieżki (relaye) np. "WIDE1-1,WIDE2-1". max 3 człony oddzielone przecinkami! 409 | */ 410 | void QAPRSBase::init(int8_t sensePin, int8_t txEnablePin, char* from_addr, uint8_t from_ssid, char* to_addr, uint8_t to_ssid, char* relays) { 411 | this->init(sensePin, txEnablePin); 412 | this->setFromAddress(from_addr, from_ssid); 413 | this->setToAddress(to_addr, to_ssid); 414 | this->setRelays(relays); 415 | } 416 | 417 | /** 418 | * Ustaw adres docelowy na potrzeby metody sendData 419 | * @param from_addr Adres [znak] źródłowy. Max 6 znaków! 420 | * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' 421 | */ 422 | void QAPRSBase::setFromAddress(char* from_addr, uint8_t from_ssid) { 423 | memset(this->from_addr, ' ', 6); 424 | strcpy(this->from_addr, from_addr); 425 | this->from_ssid = from_ssid; 426 | } 427 | 428 | /** 429 | * Ustaw adres docelowy na potrzeby metody sendData 430 | * @param to_addr Adres [znak] docelowy. Max 6 znaków! 431 | * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' 432 | */ 433 | void QAPRSBase::setToAddress(char* to_addr, uint8_t to_ssid) { 434 | memset(this->to_addr, ' ', 6); 435 | strcpy(this->to_addr, to_addr); 436 | this->to_ssid = to_ssid; 437 | } 438 | 439 | /** 440 | * Przetwórz zapis scieżek (relayów) z formatu ludzkiego na format do ramki ax.25 441 | * @param relays np. "WIDE1-1,WIDE2-1". max 3 człony oddzielone przecinkami! @see http://www.aprs.pl/sciezka.htm 442 | * @param dst 443 | */ 444 | void QAPRSBase::parseRelays(const char* relays, char* dst) { 445 | uint8_t relays_len = (uint8_t) strlen(relays); 446 | uint8_t relays_ptr = 0; 447 | uint8_t dst_ptr = 0; 448 | uint8_t fill_length = 0; 449 | 450 | for(relays_ptr=0;relays_ptr 7 && dst_ptr < 7+7){ 460 | fill_length = (uint8_t) (7 + 7 - dst_ptr); 461 | } else if(dst_ptr > 7+7 && dst_ptr < 7+7+7){ 462 | fill_length = (uint8_t) (7 + 7 + 7 - dst_ptr); 463 | } 464 | while(fill_length){ 465 | dst[dst_ptr] = ' '; 466 | fill_length--; 467 | dst_ptr++; 468 | } 469 | } else { 470 | dst[dst_ptr] = relays[relays_ptr] == '-' ? ' ' : relays[relays_ptr]; // zamiana ',' na ' ' 471 | dst_ptr++; 472 | } 473 | } 474 | dst[dst_ptr] = 0; 475 | } 476 | 477 | /** 478 | * Realizuje opóźnienie jeżeli zostało ustawione 479 | */ 480 | void QAPRSBase::doTxDelay() { 481 | if (this->txDelay){ 482 | #if defined(__arm__) 483 | _delay_ms(this->txDelay); 484 | #else 485 | delay(this->txDelay); 486 | #endif 487 | } 488 | } 489 | 490 | void QAPRSBase::setVariant(QAPRSVariant variant) { 491 | this->variant = variant; 492 | switch(variant){ 493 | case QAPRSVHF: 494 | this->_toneSendTime = this->toneSendTime1200; 495 | this->ax25HeaderFlagFieldCount = this->ax25HeaderFlagFieldCount1200; 496 | break; 497 | case QAPRSHF: 498 | this->_toneSendTime = this->toneSendTime300; 499 | this->ax25HeaderFlagFieldCount = this->ax25HeaderFlagFieldCount300; 500 | break; 501 | } 502 | } 503 | 504 | /** 505 | * Ustaw scieżki (relaye) na potrzeby metody sendData @see QAPRSBase::sendData 506 | * @param relays 507 | */ 508 | void QAPRSBase::setRelays(char* relays) { 509 | this->parseRelays(relays, (char*)this->relays); 510 | } 511 | 512 | 513 | /** 514 | * Funkcja opóźniająca. W odróżnieniu do delayMicroseconds z Arduino ta funkcja sprawdza prawdziwy czas. 515 | * @param us 516 | */ 517 | void QAPRSBase::delayuSeconds(uint16_t us) { 518 | #if defined(__arm__) 519 | _delay_us(us, 1); 520 | #else 521 | unsigned long time = micros(); 522 | while(micros() - time < us){ 523 | //asm("nop"); 524 | } 525 | #endif 526 | } 527 | 528 | 529 | /** 530 | * Ustaw czas zwłoki pomiędzy włączeniem nadawania a rozpoczęciem generowania sygnału 531 | * @param txDelay Czas w ms 532 | */ 533 | void QAPRSBase::setTxDelay(uint16_t txDelay) { 534 | this->txDelay = txDelay; 535 | } 536 | 537 | void QAPRSBase::timerInterruptHandler() { 538 | this->togglePin(); 539 | TIM2->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); 540 | 541 | TIM2->ARR = this->timer1StartValue; 542 | TIM2->CNT = 0; 543 | 544 | TIM2->CR1 |= TIM_CR1_CEN; 545 | } 546 | 547 | void QAPRSBase::togglePin() { 548 | if (this->pin){ 549 | this->pin = 0; 550 | GPIO_ResetBits(GPIOB, radioSDIpin); 551 | } else { 552 | this->pin = 1; 553 | GPIO_SetBits(GPIOB, radioSDIpin); 554 | } 555 | } 556 | 557 | #if defined(__arm__) 558 | //TODO: przepisać na STM32 559 | #else 560 | ISR (TIMER1_OVF_vect) // timer1 overflow interrupt 561 | { 562 | QAPRSGlobalObject->timerInterruptHandler(); 563 | } 564 | #endif 565 | -------------------------------------------------------------------------------- /QAPRSBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013 Lukasz Nidecki SQ5RWU 3 | 4 | This file is part of ArduinoQAPRS. 5 | 6 | ArduinoQAPRS is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | ArduinoQAPRS is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with ArduinoQAPRS; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | ArduinoQAPRS jest wolnym oprogramowaniem; możesz go rozprowadzać dalej 21 | i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, 22 | wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej 23 | Licencji lub (według twojego wyboru) którejś z późniejszych wersji. 24 | 25 | Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on 26 | użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej 27 | gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH 28 | ZASTOSOWAŃ. W celu uzyskania bliższych informacji sięgnij do 29 | Powszechnej Licencji Publicznej GNU. 30 | 31 | Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz 32 | Powszechnej Licencji Publicznej GNU (GNU General Public License); 33 | jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple 34 | Place, Fifth Floor, Boston, MA 02110-1301 USA 35 | 36 | */ 37 | 38 | /** 39 | * @file 40 | * @brief Nagłówki dla klasy QAPRSBase 41 | */ 42 | 43 | #ifndef QAPRSBASE_H_ 44 | #define QAPRSBASE_H_ 45 | 46 | #include "QAPRSCommon.h" 47 | 48 | /** 49 | * @brief Klasa bazowa do nadawania APRS 50 | * @details Klasa słuzy jako baza do podimplemntacji generowania AFSK. 51 | */ 52 | class QAPRSBase { 53 | private: 54 | /** 55 | * @brief suma kontrolna pakietu 56 | */ 57 | uint16_t ax25CRC; 58 | /** 59 | * @brief ilosć bajtów synchronizacyjnych do nadania przed zawartoscią pakietu 60 | */ 61 | static const uint8_t ax25HeaderFlagFieldCount1200 = 25; 62 | /** 63 | * @brief ilosć bajtów synchronizacyjnych do nadania przed zawartoscią pakietu 64 | */ 65 | static const uint8_t ax25HeaderFlagFieldCount300 = 45; 66 | /** 67 | * @brief ilosć bajtów synchronizacyjnych do nadania przed zawartoscią pakietu 68 | */ 69 | uint8_t ax25HeaderFlagFieldCount; 70 | /** 71 | * @brief Flaga 72 | * @details 73 | */ 74 | static const uint8_t ax25FlagFieldValue = 0x7E; 75 | /** 76 | * @brief Czas wysyłania podedynczego tonu. W us. 77 | * @details Czas calkowity powinien wynosic 833us. Wartosć podana tutaj uwzględnia zwłokę związaną z wywoływaniem 78 | * funkcji itp. 79 | */ 80 | #if F_CPU == 16000000L 81 | static const uint16_t toneSendTime1200 = 815; 82 | #elif F_CPU == 8000000UL 83 | static const uint16_t toneSendTime1200 = 785; 84 | #else 85 | //static const uint16_t toneSendTime1200 = 1000000/1200; 86 | #endif 87 | /** 88 | * @brief Czas wysyłania podedynczego tonu. W ms. 89 | * @details Czas calkowity powinien wynosic 4*833ms. Wartosć podana tutaj uwzględnia zwłokę związaną z wywoływaniem 90 | * funkcji itp. 91 | */ 92 | static const uint16_t toneSendTime300 = 815 + 3 * 833; 93 | /** 94 | * @brief Czas oczekiwania na zwolnienie kanału. 95 | * @details Co 100ms sprawdzamy czy można już nadawać @see canTransmit 96 | */ 97 | static const uint16_t channelFreeWaitingMS = 1; // 2000 ms 98 | /** 99 | * @brief Domylslny czas pomiędzy włączeniem nadawania a rozpoczęciem generowania AFSK 100 | */ 101 | static const uint16_t defaultTxDelay = 1; // 300 ms 102 | /** 103 | * @brief Pin Arduino na którym ustawiamy logiczną 1 w momencie nadawania 104 | */ 105 | int8_t txEnablePin; 106 | /** 107 | * @brief Bufor tymczasowy 108 | */ 109 | uint8_t tmpData[255]; 110 | /** 111 | * @brief Opóźnienie w ms pomiędzy ustawieniem stanu wysokiego na wyjsciu txEnablePin a rozpoczęciem generowania AFSK 112 | */ 113 | uint16_t txDelay; 114 | /** 115 | * @brief 116 | */ 117 | char from_addr[6]; 118 | /** 119 | * @brief 120 | */ 121 | uint8_t from_ssid; 122 | /** 123 | * @brief 124 | */ 125 | char to_addr[6]; 126 | /** 127 | * @brief 128 | */ 129 | uint8_t to_ssid; 130 | /** 131 | * @brief 132 | */ 133 | char* relays[3*7]; 134 | 135 | uint8_t canTransmit(); 136 | void ax25SendHeaderBegin(); 137 | void ax25SendByte(uint8_t byte); 138 | void ax25SendFooter(); 139 | void ax25CalcCRC(uint8_t ls_bit); 140 | void parseRelays(const char * relays, char * dst); 141 | protected: 142 | /** 143 | * @brief Pin Arduino [we] który musi być w stanie niskim (lub wysokim, jesli numer jest ujemny) aby rozpocząć nadawanie. 144 | */ 145 | int8_t sensePin; 146 | /** 147 | * @brief Obecnie generowany ton 148 | */ 149 | QAPRSSendingTone currentTone; 150 | /** 151 | * @brief Obecnie używany wariant 152 | */ 153 | QAPRSVariant variant; 154 | 155 | void initializeRadio(); 156 | void enableTransmission(); 157 | void disableTranssmision(); 158 | 159 | void toggleTone(); 160 | void initializeTimer1(); 161 | void delayuSeconds(uint16_t us); 162 | void doTxDelay(); 163 | public: 164 | QAPRSBase() {}; 165 | QAPRSReturnCode send(char * buffer); 166 | QAPRSReturnCode send(char * buffer, size_t length); 167 | QAPRSReturnCode send(char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * packet_content); 168 | QAPRSReturnCode send(char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * relays, char * packet_content); 169 | QAPRSReturnCode send(char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * relays, char * packet_content, size_t length); 170 | QAPRSReturnCode sendData(char * buffer); 171 | QAPRSReturnCode sendData(char * buffer, size_t length); 172 | 173 | void init(int8_t sensePin, int8_t txEnablePin); 174 | void init(int8_t sensePin, int8_t txEnablePin, char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * relays); 175 | 176 | void setTxDelay(uint16_t txDelay); 177 | void timerInterruptHandler(); 178 | void setFromAddress(char * from_addr, uint8_t from_ssid); 179 | void setToAddress(char * to_addr, uint8_t to_ssid); 180 | void setRelays(char * relays); 181 | void setVariant(QAPRSVariant variant = QAPRSVHF); 182 | 183 | private: 184 | static const uint16_t toneSendTime = 833; 185 | 186 | static const uint16_t toneSendTime1200 = 795; 187 | static const uint16_t MarkTimerValue = 393; 188 | static const uint16_t SpaceTimerValue = 202; 189 | void togglePin(); 190 | uint8_t pin; 191 | public: 192 | uint8_t enabled; 193 | uint16_t timer1StartValue; 194 | uint16_t _toneSendTime; 195 | }; 196 | 197 | /** 198 | * @brief Przesuń bajt o 1 bit w lewo. Używane w nagłówku ax.25 199 | */ 200 | #define SHIFT_BYTE(x) (x << 1) 201 | 202 | #endif /* QAPRSBASE_H_ */ 203 | -------------------------------------------------------------------------------- /QAPRSCommon.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013 Lukasz Nidecki SQ5RWU 3 | 4 | This file is part of ArduinoQAPRS. 5 | 6 | ArduinoQAPRS is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | ArduinoQAPRS is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with ArduinoQAPRS; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | Ten plik jest częścią ArduinoQAPRS. 21 | 22 | ArduinoQAPRS jest wolnym oprogramowaniem; możesz go rozprowadzać dalej 23 | i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, 24 | wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej 25 | Licencji lub (według twojego wyboru) którejś z późniejszych wersji. 26 | 27 | Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on 28 | użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej 29 | gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH 30 | ZASTOSOWAŃ. W celu uzyskania bliższych informacji sięgnij do 31 | Powszechnej Licencji Publicznej GNU. 32 | 33 | Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz 34 | Powszechnej Licencji Publicznej GNU (GNU General Public License); 35 | jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple 36 | Place, Fifth Floor, Boston, MA 02110-1301 USA 37 | 38 | */ 39 | 40 | /** 41 | * @file 42 | * @brief Wspóldzielone definicje 43 | */ 44 | 45 | #ifndef QAPRSCOMMON_H_ 46 | #define QAPRSCOMMON_H_ 47 | 48 | #include 49 | #include 50 | #include 51 | 52 | /** 53 | * @brief Wyniki zwracane przez metodę send 54 | */ 55 | enum QAPRSReturnCode { 56 | QAPRSReturnOK = 0, //!< Powodzenie 57 | QAPRSReturnError = 1, //!< Nieokreslony błąd 58 | QAPRSReturnErrorTimeout = 2//!< Timeout w oczekiwaniu na nadawanie 59 | }; 60 | 61 | /** 62 | * @brief Generowane znaczniki 63 | */ 64 | enum QAPRSSendingTone { 65 | QAPRSMark = 1, //!< Mark (1200Hz) 66 | QAPRSSpace = 2 //!< Space (2200Hz) 67 | }; 68 | 69 | /** 70 | * @brief Generowane znaczniki 71 | */ 72 | enum QAPRSVariant { 73 | QAPRSVHF = 1, //!< VHF - 1200bodów, 1200Hz/2200Hz 74 | QAPRSHF = 2 //!< HF - 300bodów, 1600Hz/1800Hz 75 | }; 76 | 77 | /** 78 | * @brief Struktura definująca podstawową ramkę ax.25 (bez realyów) 79 | */ 80 | typedef struct { 81 | char to[6]; //!< Odbiorca pakietu [znak] 82 | uint8_t to_ssid; //!< SSID odbiorcy pakietu 83 | char from[6]; //!< Nadawca pakietu [znak] 84 | uint8_t from_ssid; //!< SSID nadawcy pakietu 85 | uint8_t control_field; //!< Pole kontrolne ustawiane zawsze na 0x03 - UI @see http://www.tapr.org/pub_ax25.html#2.3.4.2 86 | uint8_t protocolID; //!< Id protokolu zawsze 0xf0 - bez warstwy 3 OSI @see http://www.tapr.org/pub_ax25.html#2.2.4 87 | char packet_content[]; //!< Zawartosć pakietu. Dane APRS 88 | } ax25BaseFrame; 89 | 90 | /** 91 | * @brief Struktura definiujaca poczatek ramki ax.25 92 | */ 93 | typedef struct { 94 | char to[6]; //!< Odbiorca pakietu [znak] 95 | uint8_t to_ssid; //!< SSID odbiorcy pakietu 96 | char from[6]; //!< Nadawca pakietu [znak] 97 | uint8_t from_ssid; //!< SSID nadawcy pakietu 98 | } ax25CustomFrameHeader; 99 | 100 | 101 | 102 | #endif /* QAPRSCOMMON_H_ */ 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RS41HUP (Ham Use Project) 2 | Firmware for RS41 for HAM use 3 | It is posible to recycle RS41-SGP sondes for amateur radio use without any electrical changes. You just have to build a new firmware (this one) and apply it via a cheap adaptor "ST-Linkv2". Modified sonde now transmits on defineable frequenca in 70cm band GPS and telemetry data in FSK RTTY format which is used by HAB projects and additionally it transmits APRS packets on a seperately defineable TX frequency. 4 | 5 | Released under GPL v2 6 | 7 | 8 | # Windows: 9 | 10 | Use: 11 | https://www.wyzbee.com/download/Utilities/Software/CoIDE-1.7.8.exe 12 | 13 | And: 14 | https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q3-update/+download/gcc-arm-none-eabi-5_4-2016q3-20160926-win32.exe 15 | 16 | 17 | # Linux: 18 | cd into main folder 19 | 20 | cmake . 21 | 22 | make 23 | 24 | # Configuration 25 | All configs in ```config.h``` 26 | 27 | * ```CALLSIGN``` RTTY callsign 28 | * ```APRS_CALLSIGN``` APRS callsign, 6 characters. If your callsign is shorter add spaces 29 | * ```APRS_SSID``` APRS SSID 30 | * ```APRS_COMMENT``` APRS comment 31 | * ```RTTY_TO_APRS_RATIO``` number of RTTY frames between each APRS frame 32 | * ```RTTY_FREQUENCY``` RTTY frequency in MHz 33 | * ```APRS_FREQUENCY``` APRS frequency in MHz 34 | * ```RTTY_DEVIATION``` RTTY shift configurable in 270Hz steps 35 | * ```RTTY_SPEED``` RTTY speed in bauds 36 | * ```RTTY_7BIT``` Use 7 bit RTTY 37 | * ```RTTY_USE_2_STOP_BITS``` use 2 stop bits 38 | * ```TX_POWER``` Power 0-7, (7 means 42.95 mW@434.150 MHz measured on E4406A) 39 | * ```TX_DELAY``` Delay between frames in milliseconds 40 | * ```ALLOW_DISABLE_BY_BUTTON``` Allow disabling device using button 41 | 42 | 43 | Have a nice day ;) 44 | 45 | #Changelog 46 | * 14.12.2016 - Reverse engineeded connections, initial hard work, resulting in working RTTY by SQ7FJB 47 | * 07.01.2017 - GPS now using proprietiary UBLOX protocol, more elastic code to set working frequency by SQ5RWU 48 | * 23.01.2017 - Test APRS code, small fixes in GPS code by SQ5RWU 49 | * 06.06.2017 - APRS code fix, some code cleanup 50 | * June 2017 - starting with Linux support, making configuration more flexible by DF8OE 51 | 52 | 53 | #TODO 54 | * Adding support for EmbiTZ IDE 55 | * Adding support for platform independent IDE Eclipse 56 | * More APRS config options 57 | * Temperature and moisture sensor 58 | * Pressure sensor 59 | * implementing protocol for using external devices on extension header 60 | * Configuration via extension header (serial connection) without need for reflashing firmware 61 | * Possibly add configuration "wireless" using RFID loop present in sonde 62 | -------------------------------------------------------------------------------- /RS41HUP.coproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 28 | 29 | 59 | 60 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /RS41HUP/.readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /aprs.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Admin on 2017-01-09. 3 | // 4 | 5 | #include "aprs.h" 6 | #include "QAPRSBase.h" 7 | #include "stdio.h" 8 | #include "ublox.h" 9 | #include "config.h" 10 | 11 | #if !defined(__OPTIMIZE__) 12 | #error "APRS Works only when optimization enabled at level at least -O2" 13 | #endif 14 | QAPRSBase qaprs; 15 | 16 | void aprs_init(){ 17 | qaprs.init(0, 0, (char *) APRS_CALLSIGN, (const uint8_t) APRS_SSID, (char *) "APZQAP", '0', (char *) "WIDE1-1,WIDE2-1"); 18 | 19 | } 20 | 21 | void aprs_timer_handler() { 22 | qaprs.timerInterruptHandler(); 23 | } 24 | 25 | uint8_t aprs_is_active() { 26 | return qaprs.enabled; 27 | } 28 | 29 | void calcDMH(long x, int8_t* degrees, uint8_t* minutes, uint8_t* h_minutes) { 30 | uint8_t sign = (uint8_t) (x > 0 ? 1 : 0); 31 | if (!sign) { 32 | x = -(x); 33 | } 34 | *degrees = (int8_t) (x / 1000000); 35 | x = x - (*degrees * 1000000); 36 | x = (x) * 60 / 10000; 37 | *minutes = (uint8_t) (x / 100); 38 | *h_minutes = (uint8_t) (x - (*minutes * 100)); 39 | if (!sign) { 40 | *degrees = -*degrees; 41 | } 42 | } 43 | 44 | void aprs_test(){ 45 | char packet_buffer[128]; 46 | sprintf(packet_buffer, 47 | (":TEST1234567890") 48 | ); 49 | qaprs.sendData(packet_buffer); 50 | } 51 | 52 | void aprs_send_position(GPSEntry gpsData, int8_t temperature, uint16_t voltage) { 53 | char packet_buffer[128]; 54 | int8_t la_degrees, lo_degrees; 55 | uint8_t la_minutes, la_h_minutes, lo_minutes, lo_h_minutes; 56 | 57 | calcDMH(gpsData.lat_raw/10, &la_degrees, &la_minutes, &la_h_minutes); 58 | calcDMH(gpsData.lon_raw/10, &lo_degrees, &lo_minutes, &lo_h_minutes); 59 | 60 | static uint16_t aprs_packet_counter = 0; 61 | aprs_packet_counter ++; 62 | 63 | sprintf(packet_buffer, 64 | ("!%02d%02d.%02u%c/%03d%02u.%02u%cO/A=%06ld/P%dS%dT%dV%d%s"), 65 | abs(la_degrees), la_minutes, la_h_minutes, 66 | la_degrees > 0 ? 'N' : 'S', 67 | abs(lo_degrees), lo_minutes, lo_h_minutes, 68 | lo_degrees > 0 ? 'E' : 'W', 69 | (gpsData.alt_raw/1000) * 3280 / 1000, 70 | aprs_packet_counter, 71 | gpsData.sats_raw, 72 | temperature, 73 | voltage, 74 | APRS_COMMENT 75 | ); 76 | qaprs.sendData(packet_buffer); 77 | } 78 | 79 | void aprs_change_tone_time(uint16_t x) { 80 | qaprs._toneSendTime = x; 81 | } 82 | 83 | void t(){ 84 | // // nadanie paketu typu komentarz 85 | // packet_buffer = ":TEST TEST TEST de SQ5RWU"; 86 | // // zmiana adresu źródłowego i ssida 87 | // QAPRS.setFromAddress("SQ5R", '1'); 88 | // QAPRS.sendData(packet_buffer); 89 | // // nadanie pakietu z pozycja i symbolem wahadlowca 90 | // packet_buffer = "!5215.68N/02057.48ES#"; 91 | // // zmiana adresu źródłowego, ssida i ścieżki 92 | // QAPRS.setFromAddress("SQ5RWU", '2'); 93 | // QAPRS.setRelays("WIDE2-2"); 94 | // QAPRS.sendData(packet_buffer); 95 | // // nadanie danych pogodowych bez pozycji 96 | // packet_buffer = "_07071805c025s009g008t030r000p000P000h00b10218"; 97 | // // zmiana ścieżki 98 | // QAPRS.setRelays("WIDE1-1"); 99 | // QAPRS.sendData(packet_buffer); 100 | // delay(5000); 101 | } 102 | -------------------------------------------------------------------------------- /aprs.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Admin on 2017-01-09. 3 | // 4 | 5 | #ifndef RS41HUP_APRS_H 6 | #define RS41HUP_APRS_H 7 | 8 | #ifdef __cplusplus 9 | #include 10 | #include 11 | #include "ublox.h" 12 | 13 | extern "C" { 14 | #endif 15 | void aprs_init(); 16 | void aprs_timer_handler(); 17 | uint8_t aprs_is_active(); 18 | void aprs_send_position(GPSEntry gpsData, int8_t temperature, uint16_t voltage); 19 | void aprs_change_tone_time(uint16_t x); 20 | void aprs_test(); 21 | #ifdef __cplusplus 22 | }; 23 | #endif 24 | #endif //RS41HUP_APRS_H 25 | -------------------------------------------------------------------------------- /arm-gcc-link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 2 | /* Internal Memory Map*/ 3 | MEMORY 4 | { 5 | rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x00010000 6 | ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00002000 7 | } 8 | 9 | _eram = 0x20000000 + 0x00002000; 10 | SECTIONS 11 | { 12 | .text : 13 | { 14 | KEEP(*(.isr_vector)) 15 | *(.text*) 16 | 17 | KEEP(*(.init)) 18 | KEEP(*(.fini)) 19 | 20 | /* .ctors */ 21 | *crtbegin.o(.ctors) 22 | *crtbegin?.o(.ctors) 23 | *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) 24 | *(SORT(.ctors.*)) 25 | *(.ctors) 26 | 27 | /* .dtors */ 28 | *crtbegin.o(.dtors) 29 | *crtbegin?.o(.dtors) 30 | *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) 31 | *(SORT(.dtors.*)) 32 | *(.dtors) 33 | 34 | *(.rodata*) 35 | 36 | KEEP(*(.eh_fram e*)) 37 | } > rom 38 | 39 | .ARM.extab : 40 | { 41 | *(.ARM.extab* .gnu.linkonce.armextab.*) 42 | } > rom 43 | 44 | __exidx_start = .; 45 | .ARM.exidx : 46 | { 47 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 48 | } > rom 49 | __exidx_end = .; 50 | __etext = .; 51 | 52 | /* _sidata is used in coide startup code */ 53 | _sidata = __etext; 54 | 55 | .data : AT (__etext) 56 | { 57 | __data_start__ = .; 58 | 59 | /* _sdata is used in coide startup code */ 60 | _sdata = __data_start__; 61 | 62 | *(vtable) 63 | *(.data*) 64 | 65 | . = ALIGN(4); 66 | /* preinit data */ 67 | PROVIDE_HIDDEN (__preinit_array_start = .); 68 | KEEP(*(.preinit_array)) 69 | PROVIDE_HIDDEN (__preinit_array_end = .); 70 | 71 | . = ALIGN(4); 72 | /* init data */ 73 | PROVIDE_HIDDEN (__init_array_start = .); 74 | KEEP(*(SORT(.init_array.*))) 75 | KEEP(*(.init_array)) 76 | PROVIDE_HIDDEN (__init_array_end = .); 77 | 78 | . = ALIGN(4); 79 | /* finit data */ 80 | PROVIDE_HIDDEN (__fini_array_start = .); 81 | KEEP(*(SORT(.fini_array.*))) 82 | KEEP(*(.fini_array)) 83 | PROVIDE_HIDDEN (__fini_array_end = .); 84 | 85 | KEEP(*(.jcr*)) 86 | . = ALIGN(4); 87 | /* All data end */ 88 | __data_end__ = .; 89 | 90 | /* _edata is used in coide startup code */ 91 | _edata = __data_end__; 92 | } > ram 93 | 94 | .bss : 95 | { 96 | . = ALIGN(4); 97 | __bss_start__ = .; 98 | _sbss = __bss_start__; 99 | *(.bss*) 100 | *(COMMON) 101 | . = ALIGN(4); 102 | __bss_end__ = .; 103 | _ebss = __bss_end__; 104 | } > ram 105 | 106 | .heap (COPY): 107 | { 108 | __end__ = .; 109 | _end = __end__; 110 | end = __end__; 111 | *(.heap*) 112 | __HeapLimit = .; 113 | } > ram 114 | 115 | /* .stack_dummy section doesn't contains any symbols. It is only 116 | * used for linker to calculate size of stack sections, and assign 117 | * values to stack symbols later */ 118 | .co_stack (NOLOAD): 119 | { 120 | . = ALIGN(8); 121 | *(.co_stack .co_stack.*) 122 | } > ram 123 | 124 | /* Set stack top to end of ram , and stack limit move down by 125 | * size of stack_dummy section */ 126 | __StackTop = ORIGIN(ram ) + LENGTH(ram ); 127 | __StackLimit = __StackTop - SIZEOF(.co_stack); 128 | PROVIDE(__stack = __StackTop); 129 | 130 | /* Check if data + heap + stack exceeds ram limit */ 131 | ASSERT(__StackLimit >= __HeapLimit, "region ram overflowed with stack") 132 | } -------------------------------------------------------------------------------- /cmsis/.readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /cmsis/core_cmFunc.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file core_cmFunc.h 3 | * @brief CMSIS Cortex-M Core Function Access Header File 4 | * @version V3.01 5 | * @date 06. March 2012 6 | * 7 | * @note 8 | * Copyright (C) 2009-2012 ARM Limited. All rights reserved. 9 | * 10 | * @par 11 | * ARM Limited (ARM) is supplying this software for use with Cortex-M 12 | * processor based microcontrollers. This file can be freely distributed 13 | * within development tools that are supporting such ARM based processors. 14 | * 15 | * @par 16 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 17 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 19 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR 20 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 21 | * 22 | ******************************************************************************/ 23 | 24 | #ifndef __CORE_CMFUNC_H 25 | #define __CORE_CMFUNC_H 26 | 27 | 28 | /* ########################### Core Function Access ########################### */ 29 | /** \ingroup CMSIS_Core_FunctionInterface 30 | \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions 31 | @{ 32 | */ 33 | 34 | #if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ 35 | /* ARM armcc specific functions */ 36 | 37 | #if (__ARMCC_VERSION < 400677) 38 | #error "Please use ARM Compiler Toolchain V4.0.677 or later!" 39 | #endif 40 | 41 | /* intrinsic void __enable_irq(); */ 42 | /* intrinsic void __disable_irq(); */ 43 | 44 | /** \brief Get Control Register 45 | 46 | This function returns the content of the Control Register. 47 | 48 | \return Control Register value 49 | */ 50 | __STATIC_INLINE uint32_t __get_CONTROL(void) 51 | { 52 | register uint32_t __regControl __ASM("control"); 53 | return(__regControl); 54 | } 55 | 56 | 57 | /** \brief Set Control Register 58 | 59 | This function writes the given value to the Control Register. 60 | 61 | \param [in] control Control Register value to set 62 | */ 63 | __STATIC_INLINE void __set_CONTROL(uint32_t control) 64 | { 65 | register uint32_t __regControl __ASM("control"); 66 | __regControl = control; 67 | } 68 | 69 | 70 | /** \brief Get IPSR Register 71 | 72 | This function returns the content of the IPSR Register. 73 | 74 | \return IPSR Register value 75 | */ 76 | __STATIC_INLINE uint32_t __get_IPSR(void) 77 | { 78 | register uint32_t __regIPSR __ASM("ipsr"); 79 | return(__regIPSR); 80 | } 81 | 82 | 83 | /** \brief Get APSR Register 84 | 85 | This function returns the content of the APSR Register. 86 | 87 | \return APSR Register value 88 | */ 89 | __STATIC_INLINE uint32_t __get_APSR(void) 90 | { 91 | register uint32_t __regAPSR __ASM("apsr"); 92 | return(__regAPSR); 93 | } 94 | 95 | 96 | /** \brief Get xPSR Register 97 | 98 | This function returns the content of the xPSR Register. 99 | 100 | \return xPSR Register value 101 | */ 102 | __STATIC_INLINE uint32_t __get_xPSR(void) 103 | { 104 | register uint32_t __regXPSR __ASM("xpsr"); 105 | return(__regXPSR); 106 | } 107 | 108 | 109 | /** \brief Get Process Stack Pointer 110 | 111 | This function returns the current value of the Process Stack Pointer (PSP). 112 | 113 | \return PSP Register value 114 | */ 115 | __STATIC_INLINE uint32_t __get_PSP(void) 116 | { 117 | register uint32_t __regProcessStackPointer __ASM("psp"); 118 | return(__regProcessStackPointer); 119 | } 120 | 121 | 122 | /** \brief Set Process Stack Pointer 123 | 124 | This function assigns the given value to the Process Stack Pointer (PSP). 125 | 126 | \param [in] topOfProcStack Process Stack Pointer value to set 127 | */ 128 | __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) 129 | { 130 | register uint32_t __regProcessStackPointer __ASM("psp"); 131 | __regProcessStackPointer = topOfProcStack; 132 | } 133 | 134 | 135 | /** \brief Get Main Stack Pointer 136 | 137 | This function returns the current value of the Main Stack Pointer (MSP). 138 | 139 | \return MSP Register value 140 | */ 141 | __STATIC_INLINE uint32_t __get_MSP(void) 142 | { 143 | register uint32_t __regMainStackPointer __ASM("msp"); 144 | return(__regMainStackPointer); 145 | } 146 | 147 | 148 | /** \brief Set Main Stack Pointer 149 | 150 | This function assigns the given value to the Main Stack Pointer (MSP). 151 | 152 | \param [in] topOfMainStack Main Stack Pointer value to set 153 | */ 154 | __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) 155 | { 156 | register uint32_t __regMainStackPointer __ASM("msp"); 157 | __regMainStackPointer = topOfMainStack; 158 | } 159 | 160 | 161 | /** \brief Get Priority Mask 162 | 163 | This function returns the current state of the priority mask bit from the Priority Mask Register. 164 | 165 | \return Priority Mask value 166 | */ 167 | __STATIC_INLINE uint32_t __get_PRIMASK(void) 168 | { 169 | register uint32_t __regPriMask __ASM("primask"); 170 | return(__regPriMask); 171 | } 172 | 173 | 174 | /** \brief Set Priority Mask 175 | 176 | This function assigns the given value to the Priority Mask Register. 177 | 178 | \param [in] priMask Priority Mask 179 | */ 180 | __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) 181 | { 182 | register uint32_t __regPriMask __ASM("primask"); 183 | __regPriMask = (priMask); 184 | } 185 | 186 | 187 | #if (__CORTEX_M >= 0x03) 188 | 189 | /** \brief Enable FIQ 190 | 191 | This function enables FIQ interrupts by clearing the F-bit in the CPSR. 192 | Can only be executed in Privileged modes. 193 | */ 194 | #define __enable_fault_irq __enable_fiq 195 | 196 | 197 | /** \brief Disable FIQ 198 | 199 | This function disables FIQ interrupts by setting the F-bit in the CPSR. 200 | Can only be executed in Privileged modes. 201 | */ 202 | #define __disable_fault_irq __disable_fiq 203 | 204 | 205 | /** \brief Get Base Priority 206 | 207 | This function returns the current value of the Base Priority register. 208 | 209 | \return Base Priority register value 210 | */ 211 | __STATIC_INLINE uint32_t __get_BASEPRI(void) 212 | { 213 | register uint32_t __regBasePri __ASM("basepri"); 214 | return(__regBasePri); 215 | } 216 | 217 | 218 | /** \brief Set Base Priority 219 | 220 | This function assigns the given value to the Base Priority register. 221 | 222 | \param [in] basePri Base Priority value to set 223 | */ 224 | __STATIC_INLINE void __set_BASEPRI(uint32_t basePri) 225 | { 226 | register uint32_t __regBasePri __ASM("basepri"); 227 | __regBasePri = (basePri & 0xff); 228 | } 229 | 230 | 231 | /** \brief Get Fault Mask 232 | 233 | This function returns the current value of the Fault Mask register. 234 | 235 | \return Fault Mask register value 236 | */ 237 | __STATIC_INLINE uint32_t __get_FAULTMASK(void) 238 | { 239 | register uint32_t __regFaultMask __ASM("faultmask"); 240 | return(__regFaultMask); 241 | } 242 | 243 | 244 | /** \brief Set Fault Mask 245 | 246 | This function assigns the given value to the Fault Mask register. 247 | 248 | \param [in] faultMask Fault Mask value to set 249 | */ 250 | __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) 251 | { 252 | register uint32_t __regFaultMask __ASM("faultmask"); 253 | __regFaultMask = (faultMask & (uint32_t)1); 254 | } 255 | 256 | #endif /* (__CORTEX_M >= 0x03) */ 257 | 258 | 259 | #if (__CORTEX_M == 0x04) 260 | 261 | /** \brief Get FPSCR 262 | 263 | This function returns the current value of the Floating Point Status/Control register. 264 | 265 | \return Floating Point Status/Control register value 266 | */ 267 | __STATIC_INLINE uint32_t __get_FPSCR(void) 268 | { 269 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 270 | register uint32_t __regfpscr __ASM("fpscr"); 271 | return(__regfpscr); 272 | #else 273 | return(0); 274 | #endif 275 | } 276 | 277 | 278 | /** \brief Set FPSCR 279 | 280 | This function assigns the given value to the Floating Point Status/Control register. 281 | 282 | \param [in] fpscr Floating Point Status/Control value to set 283 | */ 284 | __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) 285 | { 286 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 287 | register uint32_t __regfpscr __ASM("fpscr"); 288 | __regfpscr = (fpscr); 289 | #endif 290 | } 291 | 292 | #endif /* (__CORTEX_M == 0x04) */ 293 | 294 | 295 | #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ 296 | /* IAR iccarm specific functions */ 297 | 298 | #include 299 | 300 | 301 | #elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ 302 | /* TI CCS specific functions */ 303 | 304 | #include 305 | 306 | 307 | #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ 308 | /* GNU gcc specific functions */ 309 | 310 | /** \brief Enable IRQ Interrupts 311 | 312 | This function enables IRQ interrupts by clearing the I-bit in the CPSR. 313 | Can only be executed in Privileged modes. 314 | */ 315 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) 316 | { 317 | __ASM volatile ("cpsie i"); 318 | } 319 | 320 | 321 | /** \brief Disable IRQ Interrupts 322 | 323 | This function disables IRQ interrupts by setting the I-bit in the CPSR. 324 | Can only be executed in Privileged modes. 325 | */ 326 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) 327 | { 328 | __ASM volatile ("cpsid i"); 329 | } 330 | 331 | 332 | /** \brief Get Control Register 333 | 334 | This function returns the content of the Control Register. 335 | 336 | \return Control Register value 337 | */ 338 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) 339 | { 340 | uint32_t result; 341 | 342 | __ASM volatile ("MRS %0, control" : "=r" (result) ); 343 | return(result); 344 | } 345 | 346 | 347 | /** \brief Set Control Register 348 | 349 | This function writes the given value to the Control Register. 350 | 351 | \param [in] control Control Register value to set 352 | */ 353 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) 354 | { 355 | __ASM volatile ("MSR control, %0" : : "r" (control) ); 356 | } 357 | 358 | 359 | /** \brief Get IPSR Register 360 | 361 | This function returns the content of the IPSR Register. 362 | 363 | \return IPSR Register value 364 | */ 365 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) 366 | { 367 | uint32_t result; 368 | 369 | __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); 370 | return(result); 371 | } 372 | 373 | 374 | /** \brief Get APSR Register 375 | 376 | This function returns the content of the APSR Register. 377 | 378 | \return APSR Register value 379 | */ 380 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) 381 | { 382 | uint32_t result; 383 | 384 | __ASM volatile ("MRS %0, apsr" : "=r" (result) ); 385 | return(result); 386 | } 387 | 388 | 389 | /** \brief Get xPSR Register 390 | 391 | This function returns the content of the xPSR Register. 392 | 393 | \return xPSR Register value 394 | */ 395 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) 396 | { 397 | uint32_t result; 398 | 399 | __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); 400 | return(result); 401 | } 402 | 403 | 404 | /** \brief Get Process Stack Pointer 405 | 406 | This function returns the current value of the Process Stack Pointer (PSP). 407 | 408 | \return PSP Register value 409 | */ 410 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) 411 | { 412 | register uint32_t result; 413 | 414 | __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); 415 | return(result); 416 | } 417 | 418 | 419 | /** \brief Set Process Stack Pointer 420 | 421 | This function assigns the given value to the Process Stack Pointer (PSP). 422 | 423 | \param [in] topOfProcStack Process Stack Pointer value to set 424 | */ 425 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) 426 | { 427 | __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); 428 | } 429 | 430 | 431 | /** \brief Get Main Stack Pointer 432 | 433 | This function returns the current value of the Main Stack Pointer (MSP). 434 | 435 | \return MSP Register value 436 | */ 437 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) 438 | { 439 | register uint32_t result; 440 | 441 | __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); 442 | return(result); 443 | } 444 | 445 | 446 | /** \brief Set Main Stack Pointer 447 | 448 | This function assigns the given value to the Main Stack Pointer (MSP). 449 | 450 | \param [in] topOfMainStack Main Stack Pointer value to set 451 | */ 452 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) 453 | { 454 | __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); 455 | } 456 | 457 | 458 | /** \brief Get Priority Mask 459 | 460 | This function returns the current state of the priority mask bit from the Priority Mask Register. 461 | 462 | \return Priority Mask value 463 | */ 464 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) 465 | { 466 | uint32_t result; 467 | 468 | __ASM volatile ("MRS %0, primask" : "=r" (result) ); 469 | return(result); 470 | } 471 | 472 | 473 | /** \brief Set Priority Mask 474 | 475 | This function assigns the given value to the Priority Mask Register. 476 | 477 | \param [in] priMask Priority Mask 478 | */ 479 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) 480 | { 481 | __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); 482 | } 483 | 484 | 485 | #if (__CORTEX_M >= 0x03) 486 | 487 | /** \brief Enable FIQ 488 | 489 | This function enables FIQ interrupts by clearing the F-bit in the CPSR. 490 | Can only be executed in Privileged modes. 491 | */ 492 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) 493 | { 494 | __ASM volatile ("cpsie f"); 495 | } 496 | 497 | 498 | /** \brief Disable FIQ 499 | 500 | This function disables FIQ interrupts by setting the F-bit in the CPSR. 501 | Can only be executed in Privileged modes. 502 | */ 503 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) 504 | { 505 | __ASM volatile ("cpsid f"); 506 | } 507 | 508 | 509 | /** \brief Get Base Priority 510 | 511 | This function returns the current value of the Base Priority register. 512 | 513 | \return Base Priority register value 514 | */ 515 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) 516 | { 517 | uint32_t result; 518 | 519 | __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); 520 | return(result); 521 | } 522 | 523 | 524 | /** \brief Set Base Priority 525 | 526 | This function assigns the given value to the Base Priority register. 527 | 528 | \param [in] basePri Base Priority value to set 529 | */ 530 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) 531 | { 532 | __ASM volatile ("MSR basepri, %0" : : "r" (value) ); 533 | } 534 | 535 | 536 | /** \brief Get Fault Mask 537 | 538 | This function returns the current value of the Fault Mask register. 539 | 540 | \return Fault Mask register value 541 | */ 542 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) 543 | { 544 | uint32_t result; 545 | 546 | __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); 547 | return(result); 548 | } 549 | 550 | 551 | /** \brief Set Fault Mask 552 | 553 | This function assigns the given value to the Fault Mask register. 554 | 555 | \param [in] faultMask Fault Mask value to set 556 | */ 557 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) 558 | { 559 | __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); 560 | } 561 | 562 | #endif /* (__CORTEX_M >= 0x03) */ 563 | 564 | 565 | #if (__CORTEX_M == 0x04) 566 | 567 | /** \brief Get FPSCR 568 | 569 | This function returns the current value of the Floating Point Status/Control register. 570 | 571 | \return Floating Point Status/Control register value 572 | */ 573 | __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) 574 | { 575 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 576 | uint32_t result; 577 | 578 | __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); 579 | return(result); 580 | #else 581 | return(0); 582 | #endif 583 | } 584 | 585 | 586 | /** \brief Set FPSCR 587 | 588 | This function assigns the given value to the Floating Point Status/Control register. 589 | 590 | \param [in] fpscr Floating Point Status/Control value to set 591 | */ 592 | __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) 593 | { 594 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 595 | __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); 596 | #endif 597 | } 598 | 599 | #endif /* (__CORTEX_M == 0x04) */ 600 | 601 | 602 | #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ 603 | /* TASKING carm specific functions */ 604 | 605 | /* 606 | * The CMSIS functions have been implemented as intrinsics in the compiler. 607 | * Please use "carm -?i" to get an up to date list of all instrinsics, 608 | * Including the CMSIS ones. 609 | */ 610 | 611 | #endif 612 | 613 | /*@} end of CMSIS_Core_RegAccFunctions */ 614 | 615 | 616 | #endif /* __CORE_CMFUNC_H */ 617 | -------------------------------------------------------------------------------- /cmsis_boot/.readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /cmsis_boot/startup/.readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /cmsis_boot/startup/startup_stm32f10x_md_vl.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file startup_stm32f10x_md_vl.c 4 | * @author Coocox 5 | * @version V1.0 6 | * @date 3/4/2011 7 | * @brief STM32F10x Medium Density Value Line Devices Startup code. 8 | * This module performs: 9 | * - Set the initial SP 10 | * - Set the vector table entries with the exceptions ISR address 11 | * - Initialize data and bss 12 | * - Setup the microcontroller system. 13 | * - Call the application's entry point. 14 | * After Reset the Cortex-M3 processor is in Thread mode, 15 | * priority is Privileged, and the Stack is set to Main. 16 | ******************************************************************************* 17 | */ 18 | 19 | 20 | /*----------Stack Configuration-----------------------------------------------*/ 21 | #define STACK_SIZE 0x00000100 /*!< The Stack size suggest using even number */ 22 | __attribute__ ((section(".co_stack"))) 23 | unsigned long pulStack[STACK_SIZE]; 24 | 25 | 26 | /*----------Macro definition--------------------------------------------------*/ 27 | #define WEAK __attribute__ ((weak)) 28 | 29 | 30 | /*----------Declaration of the default fault handlers-------------------------*/ 31 | /* System exception vector handler */ 32 | __attribute__ ((used)) 33 | void WEAK Reset_Handler(void); 34 | void WEAK NMI_Handler(void); 35 | void WEAK HardFault_Handler(void); 36 | void WEAK MemManage_Handler(void); 37 | void WEAK BusFault_Handler(void); 38 | void WEAK UsageFault_Handler(void); 39 | void WEAK SVC_Handler(void); 40 | void WEAK DebugMon_Handler(void); 41 | void WEAK PendSV_Handler(void); 42 | void WEAK SysTick_Handler(void); 43 | void WEAK WWDG_IRQHandler(void); 44 | void WEAK PVD_IRQHandler(void); 45 | void WEAK TAMPER_IRQHandler(void); 46 | void WEAK RTC_IRQHandler(void); 47 | void WEAK FLASH_IRQHandler(void); 48 | void WEAK RCC_IRQHandler(void); 49 | void WEAK EXTI0_IRQHandler(void); 50 | void WEAK EXTI1_IRQHandler(void); 51 | void WEAK EXTI2_IRQHandler(void); 52 | void WEAK EXTI3_IRQHandler(void); 53 | void WEAK EXTI4_IRQHandler(void); 54 | void WEAK DMA1_Channel1_IRQHandler(void); 55 | void WEAK DMA1_Channel2_IRQHandler(void); 56 | void WEAK DMA1_Channel3_IRQHandler(void); 57 | void WEAK DMA1_Channel4_IRQHandler(void); 58 | void WEAK DMA1_Channel5_IRQHandler(void); 59 | void WEAK DMA1_Channel6_IRQHandler(void); 60 | void WEAK DMA1_Channel7_IRQHandler(void); 61 | void WEAK ADC1_IRQHandler(void); 62 | void WEAK EXTI9_5_IRQHandler(void); 63 | void WEAK TIM1_BRK_TIM15_IRQHandler(void); 64 | void WEAK TIM1_UP_TIM16_IRQHandler(void); 65 | void WEAK TIM1_TRG_COM_TIM17_IRQHandler(void); 66 | void WEAK TIM1_CC_IRQHandler(void); 67 | void WEAK TIM2_IRQHandler(void); 68 | void WEAK TIM3_IRQHandler(void); 69 | void WEAK TIM4_IRQHandler(void); 70 | void WEAK I2C1_EV_IRQHandler(void); 71 | void WEAK I2C1_ER_IRQHandler(void); 72 | void WEAK I2C2_EV_IRQHandler(void); 73 | void WEAK I2C2_ER_IRQHandler(void); 74 | void WEAK SPI1_IRQHandler(void); 75 | void WEAK SPI2_IRQHandler(void); 76 | void WEAK USART1_IRQHandler(void); 77 | void WEAK USART2_IRQHandler(void); 78 | void WEAK USART3_IRQHandler(void); 79 | void WEAK EXTI15_10_IRQHandler(void); 80 | void WEAK RTCAlarm_IRQHandler(void); 81 | void WEAK CEC_IRQHandler(void); 82 | void WEAK TIM6_DAC_IRQHandler(void); 83 | void WEAK TIM7_IRQHandler(void); 84 | 85 | /*----------Symbols defined in linker script----------------------------------*/ 86 | extern unsigned long _sidata; /*!< Start address for the initialization 87 | values of the .data section. */ 88 | extern unsigned long _sdata; /*!< Start address for the .data section */ 89 | extern unsigned long _edata; /*!< End address for the .data section */ 90 | extern unsigned long _sbss; /*!< Start address for the .bss section */ 91 | extern unsigned long _ebss; /*!< End address for the .bss section */ 92 | extern void _eram; /*!< End address for ram */ 93 | 94 | 95 | /*----------Function prototypes-----------------------------------------------*/ 96 | extern int main(void); /*!< The entry point for the application. */ 97 | extern void SystemInit(void); /*!< Setup the microcontroller system(CMSIS) */ 98 | void Default_Reset_Handler(void); /*!< Default reset handler */ 99 | static void Default_Handler(void); /*!< Default exception handler */ 100 | 101 | 102 | /** 103 | *@brief The minimal vector table for a Cortex M3. Note that the proper constructs 104 | * must be placed on this to ensure that it ends up at physical address 105 | * 0x00000000. 106 | */ 107 | __attribute__ ((used,section(".isr_vector"))) 108 | void (* const g_pfnVectors[])(void) = 109 | { 110 | /*----------Core Exceptions-------------------------------------------------*/ 111 | (void *)&pulStack[STACK_SIZE], /*!< The initial stack pointer */ 112 | Reset_Handler, /*!< Reset Handler */ 113 | NMI_Handler, /*!< NMI Handler */ 114 | HardFault_Handler, /*!< Hard Fault Handler */ 115 | MemManage_Handler, /*!< MPU Fault Handler */ 116 | BusFault_Handler, /*!< Bus Fault Handler */ 117 | UsageFault_Handler, /*!< Usage Fault Handler */ 118 | 0,0,0,0, /*!< Reserved */ 119 | SVC_Handler, /*!< SVCall Handler */ 120 | DebugMon_Handler, /*!< Debug Monitor Handler */ 121 | 0, /*!< Reserved */ 122 | PendSV_Handler, /*!< PendSV Handler */ 123 | SysTick_Handler, /*!< SysTick Handler */ 124 | 125 | /*----------External Exceptions---------------------------------------------*/ 126 | WWDG_IRQHandler, /*!< 0: Window Watchdog */ 127 | PVD_IRQHandler, /*!< 1: PVD through EXTI Line detect */ 128 | TAMPER_IRQHandler, /*!< 2: Tamper */ 129 | RTC_IRQHandler, /*!< 3: RTC */ 130 | FLASH_IRQHandler, /*!< 4: Flash */ 131 | RCC_IRQHandler, /*!< 5: RCC */ 132 | EXTI0_IRQHandler, /*!< 6: EXTI Line 0 */ 133 | EXTI1_IRQHandler, /*!< 7: EXTI Line 1 */ 134 | EXTI2_IRQHandler, /*!< 8: EXTI Line 2 */ 135 | EXTI3_IRQHandler, /*!< 9: EXTI Line 3 */ 136 | EXTI4_IRQHandler, /*!< 10: EXTI Line 4 */ 137 | DMA1_Channel1_IRQHandler, /*!< 11: DMA1 Channel 1 */ 138 | DMA1_Channel2_IRQHandler, /*!< 12: DMA1 Channel 2 */ 139 | DMA1_Channel3_IRQHandler, /*!< 13: DMA1 Channel 3 */ 140 | DMA1_Channel4_IRQHandler, /*!< 14: DMA1 Channel 4 */ 141 | DMA1_Channel5_IRQHandler, /*!< 15: DMA1 Channel 5 */ 142 | DMA1_Channel6_IRQHandler, /*!< 16: DMA1 Channel 6 */ 143 | DMA1_Channel7_IRQHandler, /*!< 17: DMA1 Channel 7 */ 144 | ADC1_IRQHandler, /*!< 18: ADC1 */ 145 | 0, /*!< 19: USB High Priority or CAN1 TX */ 146 | 0, /*!< 20: USB Low Priority or CAN1 RX0 */ 147 | 0, /*!< 21: CAN1 RX1 */ 148 | 0, /*!< 22: CAN1 SCE */ 149 | EXTI9_5_IRQHandler, /*!< 23: EXTI Line 9..5 */ 150 | TIM1_BRK_TIM15_IRQHandler, /*!< 24: TIM1 Break and TIM15 */ 151 | TIM1_UP_TIM16_IRQHandler, /*!< 25: TIM1 Update and TIM16 */ 152 | TIM1_TRG_COM_TIM17_IRQHandler,/*!< 26: TIM1 Trigger and Commutation and TIM17 */ 153 | TIM1_CC_IRQHandler, /*!< 27: TIM1 Capture Compare */ 154 | TIM2_IRQHandler, /*!< 28: TIM2 */ 155 | TIM3_IRQHandler, /*!< 29: TIM3 */ 156 | TIM4_IRQHandler, /*!< 30: TIM4 */ 157 | I2C1_EV_IRQHandler, /*!< 31: I2C1 Event */ 158 | I2C1_ER_IRQHandler, /*!< 32: I2C1 Error */ 159 | I2C2_EV_IRQHandler, /*!< 33: I2C2 Event */ 160 | I2C2_ER_IRQHandler, /*!< 34: I2C2 Error */ 161 | SPI1_IRQHandler, /*!< 35: SPI1 */ 162 | SPI2_IRQHandler, /*!< 36: SPI2 */ 163 | USART1_IRQHandler, /*!< 37: USART1 */ 164 | USART2_IRQHandler, /*!< 38: USART2 */ 165 | USART3_IRQHandler, /*!< 39: USART3 */ 166 | EXTI15_10_IRQHandler, /*!< 40: EXTI Line 15..10 */ 167 | RTCAlarm_IRQHandler, /*!< 41: RTC Alarm through EXTI Line */ 168 | CEC_IRQHandler, /*!< 42: HDMI-CEC */ 169 | 0,0,0,0,0,0, /*!< Reserved */ 170 | 0,0,0,0,0, /*!< Reserved */ 171 | TIM6_DAC_IRQHandler, /*!< 54: TIM6 and DAC underrun */ 172 | TIM7_IRQHandler, /*!< 55: TIM7 */ 173 | (void *)0xF108F85F /*!< Boot in RAM mode */ 174 | }; 175 | 176 | 177 | /** 178 | * @brief This is the code that gets called when the processor first 179 | * starts execution following a reset event. Only the absolutely 180 | * necessary set is performed, after which the application 181 | * supplied main() routine is called. 182 | * @param None 183 | * @retval None 184 | */ 185 | void Default_Reset_Handler(void) 186 | { 187 | /* Initialize data and bss */ 188 | unsigned long *pulSrc, *pulDest; 189 | 190 | /* Copy the data segment initializers from flash to SRAM */ 191 | pulSrc = &_sidata; 192 | 193 | for(pulDest = &_sdata; pulDest < &_edata; ) 194 | { 195 | *(pulDest++) = *(pulSrc++); 196 | } 197 | 198 | /* Zero fill the bss segment. This is done with inline assembly since this 199 | will clear the value of pulDest if it is not kept in a register. */ 200 | __asm(" ldr r0, =_sbss\n" 201 | " ldr r1, =_ebss\n" 202 | " mov r2, #0\n" 203 | " .thumb_func\n" 204 | " zero_loop:\n" 205 | " cmp r0, r1\n" 206 | " it lt\n" 207 | " strlt r2, [r0], #4\n" 208 | " blt zero_loop"); 209 | 210 | /* Setup the microcontroller system. */ 211 | //SystemInit(); 212 | 213 | /* Call the application's entry point.*/ 214 | main(); 215 | } 216 | 217 | /** 218 | *@brief Provide weak aliases for each Exception handler to the Default_Handler. 219 | * As they are weak aliases, any function with the same name will override 220 | * this definition. 221 | */ 222 | #pragma weak Reset_Handler = Default_Reset_Handler 223 | #pragma weak NMI_Handler = Default_Handler 224 | #pragma weak HardFault_Handler = Default_Handler 225 | #pragma weak MemManage_Handler = Default_Handler 226 | #pragma weak BusFault_Handler = Default_Handler 227 | #pragma weak UsageFault_Handler = Default_Handler 228 | #pragma weak SVC_Handler = Default_Handler 229 | #pragma weak DebugMon_Handler = Default_Handler 230 | #pragma weak PendSV_Handler = Default_Handler 231 | #pragma weak SysTick_Handler = Default_Handler 232 | #pragma weak WWDG_IRQHandler = Default_Handler 233 | #pragma weak PVD_IRQHandler = Default_Handler 234 | #pragma weak TAMPER_IRQHandler = Default_Handler 235 | #pragma weak RTC_IRQHandler = Default_Handler 236 | #pragma weak FLASH_IRQHandler = Default_Handler 237 | #pragma weak RCC_IRQHandler = Default_Handler 238 | #pragma weak EXTI0_IRQHandler = Default_Handler 239 | #pragma weak EXTI1_IRQHandler = Default_Handler 240 | #pragma weak EXTI2_IRQHandler = Default_Handler 241 | #pragma weak EXTI3_IRQHandler = Default_Handler 242 | #pragma weak EXTI4_IRQHandler = Default_Handler 243 | #pragma weak DMA1_Channel1_IRQHandler = Default_Handler 244 | #pragma weak DMA1_Channel2_IRQHandler = Default_Handler 245 | #pragma weak DMA1_Channel3_IRQHandler = Default_Handler 246 | #pragma weak DMA1_Channel4_IRQHandler = Default_Handler 247 | #pragma weak DMA1_Channel5_IRQHandler = Default_Handler 248 | #pragma weak DMA1_Channel6_IRQHandler = Default_Handler 249 | #pragma weak DMA1_Channel7_IRQHandler = Default_Handler 250 | #pragma weak ADC1_IRQHandler = Default_Handler 251 | #pragma weak EXTI9_5_IRQHandler = Default_Handler 252 | #pragma weak TIM1_BRK_TIM15_IRQHandler = Default_Handler 253 | #pragma weak TIM1_UP_TIM16_IRQHandler = Default_Handler 254 | #pragma weak TIM1_TRG_COM_TIM17_IRQHandler = Default_Handler 255 | #pragma weak TIM1_CC_IRQHandler = Default_Handler 256 | #pragma weak TIM2_IRQHandler = Default_Handler 257 | #pragma weak TIM3_IRQHandler = Default_Handler 258 | #pragma weak TIM4_IRQHandler = Default_Handler 259 | #pragma weak I2C1_EV_IRQHandler = Default_Handler 260 | #pragma weak I2C1_ER_IRQHandler = Default_Handler 261 | #pragma weak I2C2_EV_IRQHandler = Default_Handler 262 | #pragma weak I2C2_ER_IRQHandler = Default_Handler 263 | #pragma weak SPI1_IRQHandler = Default_Handler 264 | #pragma weak SPI2_IRQHandler = Default_Handler 265 | #pragma weak USART1_IRQHandler = Default_Handler 266 | #pragma weak USART2_IRQHandler = Default_Handler 267 | #pragma weak USART3_IRQHandler = Default_Handler 268 | #pragma weak EXTI15_10_IRQHandler = Default_Handler 269 | #pragma weak RTCAlarm_IRQHandler = Default_Handler 270 | #pragma weak CEC_IRQHandler = Default_Handler 271 | #pragma weak TIM6_DAC_IRQHandler = Default_Handler 272 | #pragma weak TIM7_IRQHandler = Default_Handler 273 | 274 | /** 275 | * @brief This is the code that gets called when the processor receives an 276 | * unexpected interrupt. This simply enters an infinite loop, 277 | * preserving the system state for examination by a debugger. 278 | * @param None 279 | * @retval None 280 | */ 281 | static void Default_Handler(void) 282 | { 283 | /* Go into an infinite loop. */ 284 | while (1) 285 | { 286 | } 287 | } 288 | 289 | /*********************** (C) COPYRIGHT 2011 Coocox ************END OF FILE*****/ 290 | -------------------------------------------------------------------------------- /cmsis_boot/stm32f10x.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qyon/STM32_RTTY/bf4172669fbd1a5882208ab992ccd62b8037b0aa/cmsis_boot/stm32f10x.h -------------------------------------------------------------------------------- /cmsis_boot/stm32f10x_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file RTC/Calendar/stm32f10x_conf.h 4 | * @author MCD Application Team 5 | * @version V3.4.0 6 | * @date 10/15/2010 7 | * @brief Library configuration file. 8 | ****************************************************************************** 9 | * @copy 10 | * 11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 17 | * 18 | *

© COPYRIGHT 2010 STMicroelectronics

19 | */ 20 | 21 | /* Define to prevent recursive inclusion -------------------------------------*/ 22 | #ifndef __STM32F10x_CONF_H 23 | #define __STM32F10x_CONF_H 24 | 25 | /* Includes ------------------------------------------------------------------*/ 26 | /* Uncomment the line below to enable peripheral header file inclusion */ 27 | /* #include "stm32f10x_adc.h" */ 28 | /* #include "stm32f10x_bkp.h" */ 29 | /* #include "stm32f10x_can.h" */ 30 | /* #include "stm32f10x_cec.h" */ 31 | /* #include "stm32f10x_crc.h" */ 32 | /* #include "stm32f10x_dac.h" */ 33 | /* #include "stm32f10x_dbgmcu.h" */ 34 | /* #include "stm32f10x_dma.h" */ 35 | /* #include "stm32f10x_exti.h" */ 36 | /* #include "stm32f10x_flash.h" */ 37 | /* #include "stm32f10x_fsmc.h" */ 38 | /* #include "stm32f10x_gpio.h" */ 39 | /* #include "stm32f10x_i2c.h" */ 40 | /* #include "stm32f10x_iwdg.h" */ 41 | /* #include "stm32f10x_pwr.h" */ 42 | /* #include "stm32f10x_rcc.h" */ 43 | /* #include "stm32f10x_rtc.h" */ 44 | /* #include "stm32f10x_sdio.h" */ 45 | /* #include "stm32f10x_spi.h" */ 46 | /* #include "stm32f10x_tim.h" */ 47 | /* #include "stm32f10x_usart.h" */ 48 | /* #include "stm32f10x_wwdg.h" */ 49 | /* #include "misc.h" */ /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ 50 | 51 | 52 | /* Exported types ------------------------------------------------------------*/ 53 | /* Exported constants --------------------------------------------------------*/ 54 | /* Uncomment the line below to expanse the "assert_param" macro in the 55 | Standard Peripheral Library drivers code */ 56 | /* #define USE_FULL_ASSERT 1 */ 57 | 58 | /* Exported macro ------------------------------------------------------------*/ 59 | #ifdef USE_FULL_ASSERT 60 | 61 | /** 62 | * @brief The assert_param macro is used for function's parameters check. 63 | * @param expr: If expr is false, it calls assert_failed function 64 | * which reports the name of the source file and the source 65 | * line number of the call that failed. 66 | * If expr is true, it returns no value. 67 | * @retval None 68 | */ 69 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) 70 | /* Exported functions ------------------------------------------------------- */ 71 | void assert_failed(uint8_t* file, uint32_t line); 72 | #else 73 | #define assert_param(expr) ((void)0) 74 | #endif /* USE_FULL_ASSERT */ 75 | 76 | #endif /* __STM32F10x_CONF_H */ 77 | 78 | /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ 79 | -------------------------------------------------------------------------------- /cmsis_boot/system_stm32f10x.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.h 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 11-March-2011 7 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 17 | * 18 | *

© COPYRIGHT 2011 STMicroelectronics

19 | ****************************************************************************** 20 | */ 21 | 22 | /** @addtogroup CMSIS 23 | * @{ 24 | */ 25 | 26 | /** @addtogroup stm32f10x_system 27 | * @{ 28 | */ 29 | 30 | /** 31 | * @brief Define to prevent recursive inclusion 32 | */ 33 | #ifndef __SYSTEM_STM32F10X_H 34 | #define __SYSTEM_STM32F10X_H 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /** @addtogroup STM32F10x_System_Includes 41 | * @{ 42 | */ 43 | 44 | /** 45 | * @} 46 | */ 47 | 48 | 49 | /** @addtogroup STM32F10x_System_Exported_types 50 | * @{ 51 | */ 52 | 53 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /** @addtogroup STM32F10x_System_Exported_Constants 60 | * @{ 61 | */ 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** @addtogroup STM32F10x_System_Exported_Macros 68 | * @{ 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | 75 | /** @addtogroup STM32F10x_System_Exported_Functions 76 | * @{ 77 | */ 78 | 79 | extern void SystemInit(void); 80 | extern void SystemCoreClockUpdate(void); 81 | /** 82 | * @} 83 | */ 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif /*__SYSTEM_STM32F10X_H */ 90 | 91 | /** 92 | * @} 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 99 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by SQ5RWU on 2016-12-24. 3 | // 4 | 5 | #ifndef RS41HUP_CONFIG_H 6 | #define RS41HUP_CONFIG_H 7 | 8 | #ifdef USE_EXTERNAL_CONFIG 9 | #include "config_external.h" 10 | #else 11 | 12 | 13 | //**************RTTY Data Format********************** 14 | // $$,,,,,,,,,,,, 15 | 16 | 17 | //**************config********************** 18 | #define CALLSIGN "NOCALL" // put your RTTY callsign here 19 | #define APRS_CALLSIGN "NOCALL" // put your APRS callsign here, 6 characters. If your callsign is shorter add spaces 20 | #define APRS_SSID 'B' // put your APRS SSID here 21 | // 0 --> Your primary station usually fixed and message capable 22 | // 1 --> generic additional station, digi, mobile, wx, etc. 23 | // 2 --> generic additional station, digi, mobile, wx, etc. 24 | // 3 --> generic additional station, digi, mobile, wx, etc. 25 | // 4 --> generic additional station, digi, mobile, wx, etc. 26 | // 5 --> Other network sources (Dstar, Iphones, Blackberry's etc) 27 | // 6 --> Special activity, Satellite ops, camping or 6 meters, etc. 28 | // 7 --> walkie talkies, HT's or other human portable 29 | // 8 --> boats, sailboats, RV's or second main mobile 30 | // 9 --> Primary Mobile (usually message capable) 31 | // A --> internet, Igates, echolink, winlink, AVRS, APRN, etc. 32 | // B --> balloons, aircraft, spacecraft, etc. 33 | // C --> APRStt, DTMF, RFID, devices, one-way trackers*, etc. 34 | // D --> Weather stations 35 | // E --> Truckers or generally full time drivers 36 | // F --> generic additional station, digi, mobile, wx, etc. 37 | 38 | #define APRS_COMMENT " Hello from the sky!" 39 | #define RTTY_TO_APRS_RATIO 5 //transmit APRS packet with each x RTTY packet 40 | 41 | //*************TX Frequencies******************** 42 | #define RTTY_FREQUENCY 434.500f //Mhz middle frequency 43 | #define APRS_FREQUENCY 432.500f //Mhz middle frequency 44 | 45 | //************RTTY Shift*********************** si4032 46 | #define RTTY_DEVIATION 0x2 // RTTY shift = RTTY_DEVIATION x 270Hz 47 | 48 | //************RTTY Speed*********************** si4032 49 | #define RTTY_SPEED 75 // RTTY baudrate 50 | 51 | //************rtty bits************************ si4032 52 | #define RTTY_7BIT 1 // if 0 --> 5 bits 53 | 54 | //************rtty stop bits******************* si4032 55 | #define RTTY_USE_2_STOP_BITS 0 56 | 57 | //********* power definition************************** 58 | #define TX_POWER 0 // PWR 0...7 0- MIN ... 7 - MAX 59 | // 0 --> -1dBm 60 | // 1 --> 2dBm 61 | // 2 --> 5dBm 62 | // 3 --> 8dBm 63 | // 4 --> 11dBm 64 | // 5 --> 14dBm 65 | // 6 --> 17dBm 66 | // 7 --> 20dBm 67 | //**************************************************** 68 | 69 | // Switch sonde ON/OFF via Button 70 | // If this is a flight you might prevent sonde from powered off by button 71 | #define ALLOW_DISABLE_BY_BUTTON 1 72 | 73 | //********** Frame Delay in msec********************** 74 | #define TX_DELAY 5000 75 | #endif 76 | 77 | #endif //RS41HUP_CONFIG_H 78 | -------------------------------------------------------------------------------- /delay.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "delay.h" 7 | 8 | volatile uint8_t done; 9 | 10 | void delay_init() { 11 | TIM_TimeBaseInitTypeDef ts; 12 | // TIM3 @ APB1 -> 6MHz WTF?! 13 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 14 | RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); 15 | 16 | ts.TIM_Prescaler = 6 - 1; 17 | ts.TIM_CounterMode = TIM_CounterMode_Up; 18 | ts.TIM_Period = 0; 19 | ts.TIM_ClockDivision = TIM_CKD_DIV1; 20 | ts.TIM_RepetitionCounter = 0; 21 | 22 | TIM_TimeBaseInit(TIM3,&ts); 23 | TIM_ClearITPendingBit(TIM3, TIM_IT_Update); 24 | TIM_ITConfig(TIM3,TIM_IT_Update, ENABLE); 25 | NVIC_InitTypeDef NVIC_InitStructure; //create NVIC structure 26 | NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; 27 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 28 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 29 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 30 | NVIC_Init(&NVIC_InitStructure); 31 | TIM_Cmd(TIM3, DISABLE); 32 | } 33 | 34 | void _delay_us(uint16_t us, uint8_t precise) { 35 | TIM_Cmd(TIM3, DISABLE); 36 | TIM_SetAutoreload(TIM3, us); 37 | TIM_SetCounter(TIM3, 0); 38 | TIM_Cmd(TIM3, ENABLE); 39 | done = 0; 40 | while(!done){ 41 | 42 | } 43 | TIM_Cmd(TIM3, DISABLE); 44 | } 45 | 46 | inline void _delay_ms(uint32_t ms) { 47 | while(ms-- > 0){ 48 | _delay_us(1000, 0); 49 | } 50 | } 51 | 52 | void TIM3_IRQHandler(void) { 53 | if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { 54 | TIM_ClearITPendingBit(TIM3, TIM_IT_Update); 55 | done = 1; 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /delay.h: -------------------------------------------------------------------------------- 1 | #ifndef __DELAY_H_ 2 | #define __DELAY_H_ 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | /** Initialize delay core - configure SysTick timer */ 8 | void delay_init(); 9 | 10 | void _delay_us(uint16_t us, uint8_t precise); 11 | 12 | void _delay_ms(uint32_t ms); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /docs/Si4030-31-32.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qyon/STM32_RTTY/bf4172669fbd1a5882208ab992ccd62b8037b0aa/docs/Si4030-31-32.pdf -------------------------------------------------------------------------------- /docs/Si4030_31_32_register_descriptions_AN466.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qyon/STM32_RTTY/bf4172669fbd1a5882208ab992ccd62b8037b0aa/docs/Si4030_31_32_register_descriptions_AN466.pdf -------------------------------------------------------------------------------- /docs/infos_for_sensors.txt: -------------------------------------------------------------------------------- 1 | DF8OEs investigations about sensor access 2 | ------------------------------------------ 3 | 4 | 5 | 6 | Temperature and humidity sensor directly goes to STM. There is no interface 7 | chip to handle them - all is done by software. 8 | 9 | 10 | 11 | Pinout of sensor boom: 12 | ---------------------- 13 | 1 - GND 14 | 2 - temperature sensor (1) 15 | 3 - GND 16 | 4 - humidity sensor1 (1) 17 | 5 - GND 18 | 6 - humidity sensor1 (2) 19 | 7 - GND 20 | 8 - heater humidity sensor 21 | 9 - heater humidity sensor 22 | 10 - GND 23 | 11 - humidity sensor2 (1) 24 | 12 - GND 25 | 13 - temperature sensor (2) and humidity sensor2 (2) 26 | 14 - GND 27 | 15 - GND 28 | 16 - GND 29 | 17 - GND 30 | 18 - GND 31 | 19 - GND 32 | 20 - GND 33 | 34 | Counted from left to right if you position flexsensor in front of you, pins near 35 | to you, sensor away from you, copper upside 36 | 37 | 38 | 39 | All connections leading to sensor boom do have corresponding test points on PCB: 40 | -------------------------------------------------------------------------------- 41 | Position PCB in front of you, flatconnector upside, sensor boom showing away from 42 | you, TX antenna leading to you. I draw connector as a row of "+++". Testpoints are 43 | small round copper isles (numbers correspond to sensor boom, G == GND, ? == unknown): 44 | 45 | 46 | 47 | 48 | 11 49 | +++++++++++++++++++++++ 50 | 51 | G 4 52 | 53 | 54 | 8 6 2 55 | 56 | 57 | 13 ? 9 58 | 59 | 60 | Investigations about temperature sensor: 61 | ---------------------------------------- 62 | Temperature sensor is resistance-based. If you insert a resistor between 63 | pin2 and pin13 of flatconnector, the following telemetry is transmitted: 64 | 65 | 330R --> -168° 66 | 560R --> -113° 67 | 820R --> -52° 68 | 1K --> -4.1° 69 | 1.5K --> 121° 70 | 2.2K --> 319° 71 | 72 | 73 | Pressure sensor module: 74 | ----------------------- 75 | 76 | This module is connected to SPI2 of STM. It uses SPI_NSS and only data output 77 | from module - SPI output from STM is not connected to module. So I think it is 78 | a kind of polling. 79 | 80 | 81 | 82 | 2 be continued -------------------------------------------------------------------------------- /docs/pinout_extension_port.txt: -------------------------------------------------------------------------------- 1 | Created by DF8OE 2 | ---------------- 3 | 4 | 5 | 6 | view into port from outside 7 | 8 | 9 | ______________________| |______________________ 10 | | | 11 | | 1 2 3 4 5 | 12 | | | 13 | | 6 7 8 9 10 | 14 | |_______________________________________________________| 15 | 16 | 17 | 1 - SWDIO (PA13) 18 | 2 - RST 19 | 3 - MCU switched 3.3V out to external device 20 | 4 - I2C2_SCL (PB10) 21 | 5 - GND 22 | 6 - GND 23 | 7 - SWCLK (PA14) 24 | 8 - +U_Battery 25 | 9 - +VDD_MCU 26 | 10 - I2C2_SDA (PB11) -------------------------------------------------------------------------------- /docs/stm32f100c8t6b_en.CD00251732.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qyon/STM32_RTTY/bf4172669fbd1a5882208ab992ccd62b8037b0aa/docs/stm32f100c8t6b_en.CD00251732.pdf -------------------------------------------------------------------------------- /f_rtty.c: -------------------------------------------------------------------------------- 1 | #include "f_rtty.h" 2 | 3 | uint8_t start_bits; 4 | rttyStates send_rtty(char *buffer) { 5 | static uint8_t nr_bit = 0; 6 | nr_bit++; 7 | if (start_bits){ 8 | start_bits--; 9 | return rttyOne; 10 | } 11 | 12 | if (nr_bit == 1) { 13 | return rttyZero; 14 | } 15 | if (nr_bit > 1 && nr_bit < (RTTY_7BIT ? 9 : 10)) { 16 | if ((*(buffer) >> (nr_bit - 2)) & 0x01) { 17 | return rttyOne; 18 | } else { 19 | return rttyZero; 20 | } 21 | } 22 | 23 | #ifdef RTTY_7BIT 24 | nr_bit++; 25 | #endif 26 | 27 | if (nr_bit == 10) { 28 | return rttyOne; 29 | } 30 | #ifdef RTTY_USE_2_STOP_BITS 31 | if (nr_bit == 11) { 32 | return rttyOne; 33 | } 34 | #endif 35 | nr_bit = 0; 36 | return rttyEnd; 37 | } 38 | -------------------------------------------------------------------------------- /f_rtty.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "config.h" 3 | 4 | typedef enum { 5 | rttyZero = 0, 6 | rttyOne = 1, 7 | rttyEnd = 2 8 | } rttyStates; 9 | static const uint8_t RTTY_PRE_START_BITS = 10; 10 | 11 | rttyStates send_rtty(char *); 12 | extern uint8_t start_bits; 13 | -------------------------------------------------------------------------------- /init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "init.h" 12 | #include "radio.h" 13 | 14 | SPI_InitTypeDef SPI_InitStructure; 15 | USART_InitTypeDef USART_InitStructure; 16 | GPIO_InitTypeDef GPIO_Conf; 17 | ADC_InitTypeDef ADC_InitStructure; 18 | DMA_InitTypeDef DMA_InitStructure; 19 | 20 | 21 | #define ADC1_DR_Address ((uint32_t)0x4001244C) 22 | #if defined(STM32F10X_CL) 23 | #error "clock oscillator problem!" 24 | #endif 25 | void init_usart_gps(const uint32_t speed, const uint8_t enable_irq) { 26 | NVIC_DisableIRQ(USART1_IRQn); 27 | USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); 28 | USART_ClearITPendingBit(USART1, USART_IT_RXNE); 29 | USART_ClearITPendingBit(USART1, USART_IT_ORE); 30 | 31 | USART_Cmd(USART1, DISABLE); 32 | 33 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 34 | USART_InitStructure.USART_BaudRate = speed; 35 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 36 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 37 | USART_InitStructure.USART_Parity = USART_Parity_No; 38 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 39 | USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; 40 | USART_Init(USART1, &USART_InitStructure); 41 | 42 | NVIC_InitTypeDef NVIC_InitStructure; //create NVIC structure 43 | NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 44 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15; 45 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; 46 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 47 | NVIC_Init(&NVIC_InitStructure); 48 | 49 | USART_Cmd(USART1, ENABLE); 50 | if (enable_irq){ 51 | USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 52 | NVIC_EnableIRQ(USART1_IRQn); 53 | } 54 | } 55 | 56 | void init_usart_debug() { 57 | NVIC_DisableIRQ(USART3_IRQn); 58 | USART_Cmd(USART3, DISABLE); 59 | 60 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); 61 | USART_InitStructure.USART_BaudRate = 19200; //0x9c4; 62 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; 63 | USART_InitStructure.USART_StopBits = USART_StopBits_1; 64 | USART_InitStructure.USART_Parity = USART_Parity_No; 65 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 66 | USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; 67 | USART_Init(USART3, &USART_InitStructure); 68 | USART_Cmd(USART3, ENABLE); 69 | } 70 | 71 | void NVIC_Conf() 72 | { 73 | #ifdef VECT_TAB_RAM 74 | NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 75 | #else // VECT_TAB_FLASH 76 | NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 77 | #endif 78 | } 79 | 80 | void RCC_Conf() 81 | { 82 | ErrorStatus HSEStartUpStatus; 83 | RCC_DeInit(); 84 | RCC_HSEConfig(RCC_HSE_ON); 85 | HSEStartUpStatus = RCC_WaitForHSEStartUp(); 86 | if(HSEStartUpStatus == SUCCESS) 87 | { 88 | FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); 89 | FLASH_SetLatency(FLASH_Latency_2); 90 | RCC_HCLKConfig(RCC_SYSCLK_Div4); 91 | RCC_PCLK2Config(RCC_HCLK_Div4); 92 | RCC_PCLK1Config(RCC_HCLK_Div2); 93 | RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); 94 | while(RCC_GetSYSCLKSource() != 0x04); 95 | } 96 | } 97 | 98 | void init_port() 99 | { 100 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 101 | GPIO_Conf.GPIO_Pin = GPIO_Pin_12; 102 | GPIO_Conf.GPIO_Mode = GPIO_Mode_Out_PP; 103 | GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; 104 | GPIO_Init(GPIOA, &GPIO_Conf); 105 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 106 | GPIO_Conf.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8; 107 | GPIO_Conf.GPIO_Mode = GPIO_Mode_Out_PP; 108 | GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; 109 | GPIO_Init(GPIOB, &GPIO_Conf); 110 | 111 | // SPI2_SCK & SPI2_MOSI 112 | GPIO_Conf.GPIO_Pin = GPIO_Pin_13 | radioSDIpin; 113 | GPIO_Conf.GPIO_Mode = GPIO_Mode_AF_PP; 114 | GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; 115 | GPIO_Init(GPIOB, &GPIO_Conf); 116 | 117 | // SPI2_MISO 118 | GPIO_Conf.GPIO_Pin = GPIO_Pin_14; 119 | GPIO_Conf.GPIO_Mode = GPIO_Mode_IN_FLOATING; 120 | GPIO_Init(GPIOB, &GPIO_Conf); 121 | 122 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); 123 | 124 | // radioNSELpin 125 | GPIO_Conf.GPIO_Pin = radioNSELpin; 126 | GPIO_Conf.GPIO_Mode = GPIO_Mode_Out_PP; 127 | GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; 128 | GPIO_Init(GPIOC,&GPIO_Conf); 129 | 130 | spi_init(); 131 | 132 | GPIO_Conf.GPIO_Pin = GPIO_Pin_9; 133 | GPIO_Conf.GPIO_Mode = GPIO_Mode_AF_PP; 134 | GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; 135 | GPIO_Init(GPIOA, &GPIO_Conf); 136 | GPIO_Conf.GPIO_Pin = GPIO_Pin_10; 137 | GPIO_Conf.GPIO_Mode = GPIO_Mode_IN_FLOATING; 138 | GPIO_Init(GPIOA, &GPIO_Conf); 139 | 140 | init_usart_gps(9600, 0); 141 | 142 | GPIO_Conf.GPIO_Pin = GPIO_Pin_10; 143 | GPIO_Conf.GPIO_Mode = GPIO_Mode_AF_PP; 144 | GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; 145 | GPIO_Init(GPIOB, &GPIO_Conf); 146 | GPIO_Conf.GPIO_Pin = GPIO_Pin_11; 147 | GPIO_Conf.GPIO_Mode = GPIO_Mode_IN_FLOATING; 148 | GPIO_Init(GPIOB, &GPIO_Conf); 149 | 150 | init_usart_debug(); 151 | 152 | RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_DMA1 , ENABLE ) ; 153 | DMA_DeInit(DMA1_Channel1); 154 | DMA_InitStructure.DMA_BufferSize = 2; 155 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 156 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 157 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &ADCVal; 158 | ADC_DMACmd(ADC1, ENABLE); 159 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 160 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 161 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; 162 | DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; 163 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 164 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 165 | DMA_InitStructure.DMA_Priority = DMA_Priority_High; 166 | DMA_Init(DMA1_Channel1, &DMA_InitStructure); 167 | DMA_Cmd(DMA1_Channel1, ENABLE); 168 | GPIO_Conf.GPIO_Mode = GPIO_Mode_AIN; 169 | GPIO_Conf.GPIO_Pin = GPIO_Pin_6 ; // that's ADC1 (PA5 on STM32) 170 | GPIO_Init(GPIOA, &GPIO_Conf); 171 | GPIO_Conf.GPIO_Mode = GPIO_Mode_AIN; 172 | GPIO_Conf.GPIO_Pin = GPIO_Pin_5 ; // that's ADC1 (PA3 on STM32) 173 | GPIO_Init(GPIOA, &GPIO_Conf); 174 | RCC_ADCCLKConfig (RCC_PCLK2_Div2); 175 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 176 | ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 177 | ADC_InitStructure.ADC_ScanConvMode = ENABLE; 178 | ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // we work in continuous sampling mode 179 | ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 180 | ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 181 | ADC_InitStructure.ADC_NbrOfChannel = 2; 182 | ADC_Init ( ADC1, &ADC_InitStructure); //set config of ADC1 183 | ADC_RegularChannelConfig(ADC1,ADC_Channel_5, 1,ADC_SampleTime_28Cycles5); // define regular conversion config 184 | ADC_RegularChannelConfig(ADC1,ADC_Channel_6, 2,ADC_SampleTime_28Cycles5); // define regular conversion config 185 | ADC_DMACmd(ADC1, ENABLE); 186 | ADC_Cmd (ADC1,ENABLE); //enable ADC 187 | ADC_ResetCalibration(ADC1); // Reset previous calibration 188 | while(ADC_GetResetCalibrationStatus(ADC1)); 189 | ADC_StartCalibration(ADC1); // start new calibration (ADC must be off at that time) 190 | while(ADC_GetCalibrationStatus(ADC1)); 191 | ADC_SoftwareStartConvCmd(ADC1, ENABLE); // start conversion (will be endless as we are in continuous mode) 192 | } 193 | 194 | void spi_init() { 195 | GPIO_Conf.GPIO_Pin = radioSDIpin; 196 | GPIO_Conf.GPIO_Mode = GPIO_Mode_AF_PP; 197 | GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; 198 | GPIO_Init(GPIOB, &GPIO_Conf); 199 | 200 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); 201 | SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 202 | SPI_InitStructure.SPI_Mode = SPI_Mode_Master; 203 | SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; 204 | SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; 205 | SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; 206 | SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; 207 | SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; 208 | SPI_InitStructure.SPI_CRCPolynomial = 7; 209 | SPI_Init(SPI2, &SPI_InitStructure); 210 | SPI_SSOutputCmd(SPI2, ENABLE); 211 | SPI_Cmd(SPI2, ENABLE); 212 | SPI_InitStructure.SPI_Mode = SPI_Mode_Master; 213 | SPI_Init(SPI2, &SPI_InitStructure); 214 | } 215 | 216 | void spi_deinit() { 217 | SPI_I2S_DeInit(SPI2); 218 | GPIO_Conf.GPIO_Pin = radioSDIpin; 219 | GPIO_Conf.GPIO_Mode = GPIO_Mode_Out_PP; 220 | GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; 221 | GPIO_Init(GPIOB, &GPIO_Conf); 222 | 223 | } 224 | 225 | void init_timer(const int rtty_speed) { 226 | TIM_TimeBaseInitTypeDef TIM2_TimeBaseInitStruct; 227 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 228 | RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE); 229 | 230 | TIM2_TimeBaseInitStruct.TIM_Prescaler = 6 - 1; // tick every 1/1000000 s 231 | TIM2_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; 232 | TIM2_TimeBaseInitStruct.TIM_Period = (uint16_t) ((1000000 / rtty_speed) - 1); 233 | TIM2_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; 234 | TIM2_TimeBaseInitStruct.TIM_RepetitionCounter = 0; 235 | 236 | TIM_TimeBaseInit(TIM2,&TIM2_TimeBaseInitStruct); 237 | TIM_ClearITPendingBit(TIM2, TIM_IT_Update); 238 | TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE); 239 | NVIC_InitTypeDef NVIC_InitStructure; //create NVIC structure 240 | NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; 241 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 242 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 243 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 244 | NVIC_Init(&NVIC_InitStructure); 245 | TIM_Cmd(TIM2,ENABLE); 246 | } 247 | -------------------------------------------------------------------------------- /init.h: -------------------------------------------------------------------------------- 1 | __IO uint16_t ADCVal[2]; 2 | #ifdef __cplusplus 3 | extern "C" { 4 | #endif 5 | 6 | void NVIC_Conf(); 7 | 8 | void RCC_Conf(); 9 | 10 | void init_port(); 11 | 12 | void init_timer(const int rtty_speed); 13 | 14 | void init_usart_gps(const uint32_t speed, const uint8_t enable_irq); 15 | 16 | void spi_init(); 17 | 18 | void spi_deinit(); 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | // STM32F100 and SI4032 RTTY transmitter 2 | // released under GPL v.2 by anonymous developer 3 | // enjoy and have a nice day 4 | // ver 1.5a 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "stdlib.h" 13 | #include 14 | #include 15 | #include 16 | #include "f_rtty.h" 17 | #include "init.h" 18 | #include "config.h" 19 | #include "radio.h" 20 | #include "ublox.h" 21 | #include "delay.h" 22 | #include "aprs.h" 23 | ///////////////////////////// test mode ///////////// 24 | const unsigned char test = 0; // 0 - normal, 1 - short frame only cunter, height, flag 25 | char callsign[15] = {CALLSIGN}; 26 | 27 | 28 | #define GREEN GPIO_Pin_7 29 | #define RED GPIO_Pin_8 30 | 31 | unsigned int send_cun; //frame counter 32 | char status[2] = {'N'}; 33 | int voltage; 34 | volatile int adc_bottom = 2000; 35 | 36 | volatile char flaga = 0; 37 | uint16_t CRC_rtty = 0x12ab; //checksum 38 | char buf_rtty[200]; 39 | 40 | volatile unsigned char pun = 0; 41 | volatile unsigned int cun = 10; 42 | volatile unsigned char tx_on = 0; 43 | volatile unsigned int tx_on_delay; 44 | volatile unsigned char tx_enable = 0; 45 | rttyStates send_rtty_status = rttyZero; 46 | volatile char *rtty_buf; 47 | volatile uint16_t button_pressed = 0; 48 | volatile uint8_t disable_armed = 0; 49 | 50 | void send_rtty_packet(); 51 | uint16_t gps_CRC16_checksum (char *string); 52 | 53 | 54 | /** 55 | * GPS data processing 56 | */ 57 | void USART1_IRQHandler(void) { 58 | if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { 59 | ublox_handle_incoming_byte((uint8_t) USART_ReceiveData(USART1)); 60 | }else if (USART_GetITStatus(USART1, USART_IT_ORE) != RESET) { 61 | USART_ReceiveData(USART1); 62 | } else { 63 | USART_ReceiveData(USART1); 64 | } 65 | } 66 | 67 | void TIM2_IRQHandler(void) { 68 | if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { 69 | TIM_ClearITPendingBit(TIM2, TIM_IT_Update); 70 | 71 | if (aprs_is_active()){ 72 | aprs_timer_handler(); 73 | } else { 74 | if (ALLOW_DISABLE_BY_BUTTON){ 75 | if (ADCVal[1] > adc_bottom){ 76 | button_pressed++; 77 | if (button_pressed > (RTTY_SPEED / 3)){ 78 | disable_armed = 1; 79 | GPIO_SetBits(GPIOB, RED); 80 | GPIO_SetBits(GPIOB, GREEN); 81 | } 82 | } else { 83 | if (disable_armed){ 84 | GPIO_SetBits(GPIOA, GPIO_Pin_12); 85 | } 86 | button_pressed = 0; 87 | } 88 | if (button_pressed == 0) { 89 | adc_bottom = ADCVal[1] * 1.1; // dynamical reference for power down level 90 | } 91 | } 92 | if (tx_on) { 93 | send_rtty_status = send_rtty((char *) rtty_buf); 94 | if (!disable_armed){ 95 | if (send_rtty_status == rttyEnd) { 96 | GPIO_SetBits(GPIOB, RED); 97 | if (*(++rtty_buf) == 0) { 98 | tx_on = 0; 99 | tx_on_delay = TX_DELAY / (1000/RTTY_SPEED); 100 | tx_enable = 0; 101 | radio_disable_tx(); 102 | } 103 | } else if (send_rtty_status == rttyOne) { 104 | radio_rw_register(0x73, RTTY_DEVIATION, 1); 105 | GPIO_SetBits(GPIOB, RED); 106 | } else if (send_rtty_status == rttyZero) { 107 | radio_rw_register(0x73, 0x00, 1); 108 | GPIO_ResetBits(GPIOB, RED); 109 | } 110 | } 111 | } 112 | if (!tx_on && --tx_on_delay == 0) { 113 | tx_enable = 1; 114 | tx_on_delay--; 115 | } 116 | if (--cun == 0) { 117 | if (pun) { 118 | GPIO_ResetBits(GPIOB, GREEN); 119 | pun = 0; 120 | } else { 121 | if (flaga & 0x80) { 122 | GPIO_SetBits(GPIOB, GREEN); 123 | } 124 | pun = 1; 125 | } 126 | cun = 200; 127 | } 128 | } 129 | 130 | } 131 | 132 | } 133 | 134 | int main(void) { 135 | #ifdef DEBUG 136 | debug(); 137 | #endif 138 | RCC_Conf(); 139 | NVIC_Conf(); 140 | init_port(); 141 | 142 | init_timer(RTTY_SPEED); 143 | delay_init(); 144 | ublox_init(); 145 | 146 | GPIO_SetBits(GPIOB, RED); 147 | USART_SendData(USART3, 0xc); 148 | 149 | radio_soft_reset(); 150 | // setting RTTY TX frequency 151 | radio_set_tx_frequency(RTTY_FREQUENCY); 152 | 153 | // setting TX power 154 | radio_rw_register(0x6D, 00 | (TX_POWER & 0x0007), 1); 155 | 156 | // initial RTTY modulation 157 | radio_rw_register(0x71, 0x00, 1); 158 | 159 | // Temperature Value Offset 160 | radio_rw_register(0x13, 0xF0, 1); 161 | 162 | // Temperature Sensor Calibration 163 | radio_rw_register(0x12, 0x00, 1); 164 | 165 | // ADC configuration 166 | radio_rw_register(0x0f, 0x80, 1); 167 | rtty_buf = buf_rtty; 168 | tx_on = 0; 169 | tx_enable = 1; 170 | 171 | aprs_init(); 172 | radio_enable_tx(); 173 | 174 | uint8_t rtty_before_aprs_left = RTTY_TO_APRS_RATIO; 175 | 176 | 177 | while (1) { 178 | if (tx_on == 0 && tx_enable) { 179 | if (rtty_before_aprs_left){ 180 | send_rtty_packet(); 181 | rtty_before_aprs_left --; 182 | } else { 183 | rtty_before_aprs_left = RTTY_TO_APRS_RATIO; 184 | radio_enable_tx(); 185 | GPSEntry gpsData; 186 | ublox_get_last_data(&gpsData); 187 | USART_Cmd(USART1, DISABLE); 188 | int8_t temperature = radio_read_temperature(); 189 | uint16_t voltage = (uint16_t) ADCVal[0] * 600 / 4096; 190 | aprs_send_position(gpsData, temperature, voltage); 191 | USART_Cmd(USART1, ENABLE); 192 | radio_disable_tx(); 193 | } 194 | 195 | } else { 196 | NVIC_SystemLPConfig(NVIC_LP_SEVONPEND, DISABLE); 197 | __WFI(); 198 | } 199 | } 200 | } 201 | 202 | void send_rtty_packet() { 203 | start_bits = RTTY_PRE_START_BITS; 204 | int8_t si4032_temperature = radio_read_temperature(); 205 | 206 | voltage = ADCVal[0] * 600 / 4096; 207 | GPSEntry gpsData; 208 | ublox_get_last_data(&gpsData); 209 | if (gpsData.fix >= 3) { 210 | flaga |= 0x80; 211 | } else { 212 | flaga &= ~0x80; 213 | } 214 | uint8_t lat_d = (uint8_t) abs(gpsData.lat_raw / 10000000); 215 | uint32_t lat_fl = (uint32_t) abs(abs(gpsData.lat_raw) - lat_d * 10000000) / 100; 216 | uint8_t lon_d = (uint8_t) abs(gpsData.lon_raw / 10000000); 217 | uint32_t lon_fl = (uint32_t) abs(abs(gpsData.lon_raw) - lon_d * 10000000) / 100; 218 | 219 | sprintf(buf_rtty, "$$$$%s,%d,%02u%02u%02u,%s%d.%05ld,%s%d.%05ld,%ld,%d,%d.%d,%d,%d,%d,%02x", callsign, send_cun, 220 | gpsData.hours, gpsData.minutes, gpsData.seconds, 221 | gpsData.lat_raw < 0 ? "-" : "", lat_d, lat_fl, 222 | gpsData.lon_raw < 0 ? "-" : "", lon_d, lon_fl, 223 | (gpsData.alt_raw / 1000), si4032_temperature, voltage/100, voltage-voltage/100*100, gpsData.sats_raw, 224 | gpsData.ok_packets, gpsData.bad_packets, 225 | flaga); 226 | // CRC_rtty = 0xffff; //possibly not neccessary?? 227 | CRC_rtty = gps_CRC16_checksum(buf_rtty + 4); 228 | sprintf(buf_rtty, "%s*%04X\n", buf_rtty, CRC_rtty & 0xffff); 229 | rtty_buf = buf_rtty; 230 | radio_enable_tx(); 231 | tx_on = 1; 232 | 233 | send_cun++; 234 | } 235 | 236 | uint16_t gps_CRC16_checksum(char *string) { 237 | uint16_t crc = 0xffff; 238 | char i; 239 | while (*(string) != 0) { 240 | crc = crc ^ (*(string++) << 8); 241 | for (i = 0; i < 8; i++) { 242 | if (crc & 0x8000) 243 | crc = (uint16_t) ((crc << 1) ^ 0x1021); 244 | else 245 | crc <<= 1; 246 | } 247 | } 248 | return crc; 249 | } 250 | 251 | 252 | #ifdef DEBUG 253 | void assert_failed(uint8_t* file, uint32_t line) 254 | { 255 | while (1); 256 | } 257 | #endif -------------------------------------------------------------------------------- /radio.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by SQ5RWU on 2016-12-24. 3 | // 4 | 5 | #include "radio.h" 6 | 7 | uint8_t _spi_sendrecv(const uint16_t data_word) { 8 | GPIO_ResetBits(GPIOC, radioNSELpin); 9 | // wait for tx buffer 10 | while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); 11 | SPI_I2S_SendData(SPI2, data_word); 12 | 13 | // wait for data in rx buffer 14 | while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); 15 | GPIO_SetBits(GPIOC, radioNSELpin); 16 | return (uint8_t) SPI_I2S_ReceiveData(SPI2); 17 | } 18 | 19 | inline uint8_t radio_rw_register(const uint8_t register_addr, uint8_t value, uint8_t write){ 20 | return _spi_sendrecv(((write ? register_addr | WR : register_addr) << 8) | value); 21 | } 22 | 23 | void radio_set_tx_frequency(const float freq_in_mhz) { 24 | uint8_t hbsel = (uint8_t) ((freq_in_mhz * (30.0f / SI4032_CLOCK)) >= 480.0f ? 1 : 0); 25 | 26 | uint8_t fb = (uint8_t) ((((uint8_t)((freq_in_mhz * (30.0f / SI4032_CLOCK)) / 10) - 24) - (24 * hbsel)) / (1 + hbsel)); 27 | uint8_t gen_div = 3; // constant - not possible to change! 28 | uint16_t fc = (uint16_t) (((freq_in_mhz / ((SI4032_CLOCK / gen_div) * (hbsel + 1))) - fb - 24) * 64000); 29 | radio_rw_register(0x75, (uint8_t) (0b01000000 | (fb & 0b11111) | ((hbsel & 0b1) << 5)), 1); 30 | radio_rw_register(0x76, (uint8_t) (((uint16_t)fc >> 8) & 0xff), 1); 31 | radio_rw_register(0x77, (uint8_t) ((uint16_t)fc & 0xff), 1); 32 | } 33 | 34 | void radio_disable_tx() { 35 | radio_rw_register(0x07, 0x40, 1); 36 | } 37 | 38 | void radio_soft_reset() { 39 | radio_rw_register(0x07, 0x80, 1); 40 | } 41 | 42 | void radio_enable_tx() { 43 | radio_rw_register(0x07, 0x48, 1); 44 | } 45 | 46 | int8_t radio_read_temperature() { 47 | uint8_t temp; 48 | temp = radio_rw_register(0x11, 0xff, 0); // read ADC 49 | int8_t temperatura = (int8_t) (-64 + (temp * 5 / 10) - 16); 50 | radio_rw_register(0x0f, 0x80, 1); 51 | return temperatura; 52 | } 53 | -------------------------------------------------------------------------------- /radio.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by SQ5RWU on 2016-12-24. 3 | // 4 | 5 | #ifndef RS41HUP_RADIO_H 6 | #define RS41HUP_RADIO_H 7 | 8 | #include "config.h" 9 | #include 10 | #include 11 | #include 12 | 13 | static const uint16_t radioNSELpin = GPIO_Pin_13; // @ GPIOC 14 | static const uint16_t radioSDIpin = GPIO_Pin_15; // @ GPIOB! 15 | static const uint8_t WR = 0x80; 16 | static const float SI4032_CLOCK = 26.0; 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | uint8_t _spi_sendrecv(const uint16_t data_word); 23 | 24 | uint8_t radio_rw_register(const uint8_t register_addr, uint8_t value, uint8_t write); 25 | 26 | void radio_set_tx_frequency(const float radio_set_tx_frequency); 27 | 28 | void radio_disable_tx(); 29 | 30 | void radio_soft_reset(); 31 | 32 | void radio_enable_tx(); 33 | 34 | int8_t radio_read_temperature(); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif //RS41HUP_RADIO_H 41 | -------------------------------------------------------------------------------- /stm_lib/.readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /stm_lib/inc/.readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /stm_lib/inc/misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file misc.h 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 11-March-2011 7 | * @brief This file contains all the functions prototypes for the miscellaneous 8 | * firmware library functions (add-on to CMSIS functions). 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 13 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 14 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 15 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 16 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 17 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 18 | * 19 | *

© COPYRIGHT 2011 STMicroelectronics

20 | ****************************************************************************** 21 | */ 22 | 23 | /* Define to prevent recursive inclusion -------------------------------------*/ 24 | #ifndef __MISC_H 25 | #define __MISC_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /* Includes ------------------------------------------------------------------*/ 32 | #include "stm32f10x.h" 33 | 34 | /** @addtogroup STM32F10x_StdPeriph_Driver 35 | * @{ 36 | */ 37 | 38 | /** @addtogroup MISC 39 | * @{ 40 | */ 41 | 42 | /** @defgroup MISC_Exported_Types 43 | * @{ 44 | */ 45 | 46 | /** 47 | * @brief NVIC Init Structure definition 48 | */ 49 | 50 | typedef struct 51 | { 52 | uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. 53 | This parameter can be a value of @ref IRQn_Type 54 | (For the complete STM32 Devices IRQ Channels list, please 55 | refer to stm32f10x.h file) */ 56 | 57 | uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel 58 | specified in NVIC_IRQChannel. This parameter can be a value 59 | between 0 and 15 as described in the table @ref NVIC_Priority_Table */ 60 | 61 | uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified 62 | in NVIC_IRQChannel. This parameter can be a value 63 | between 0 and 15 as described in the table @ref NVIC_Priority_Table */ 64 | 65 | FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel 66 | will be enabled or disabled. 67 | This parameter can be set either to ENABLE or DISABLE */ 68 | } NVIC_InitTypeDef; 69 | 70 | /** 71 | * @} 72 | */ 73 | 74 | /** @defgroup NVIC_Priority_Table 75 | * @{ 76 | */ 77 | 78 | /** 79 | @code 80 | The table below gives the allowed values of the pre-emption priority and subpriority according 81 | to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function 82 | ============================================================================================================================ 83 | NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description 84 | ============================================================================================================================ 85 | NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority 86 | | | | 4 bits for subpriority 87 | ---------------------------------------------------------------------------------------------------------------------------- 88 | NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority 89 | | | | 3 bits for subpriority 90 | ---------------------------------------------------------------------------------------------------------------------------- 91 | NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority 92 | | | | 2 bits for subpriority 93 | ---------------------------------------------------------------------------------------------------------------------------- 94 | NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority 95 | | | | 1 bits for subpriority 96 | ---------------------------------------------------------------------------------------------------------------------------- 97 | NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority 98 | | | | 0 bits for subpriority 99 | ============================================================================================================================ 100 | @endcode 101 | */ 102 | 103 | /** 104 | * @} 105 | */ 106 | 107 | /** @defgroup MISC_Exported_Constants 108 | * @{ 109 | */ 110 | 111 | /** @defgroup Vector_Table_Base 112 | * @{ 113 | */ 114 | 115 | #define NVIC_VectTab_RAM ((uint32_t)0x20000000) 116 | #define NVIC_VectTab_FLASH ((uint32_t)0x08000000) 117 | #define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ 118 | ((VECTTAB) == NVIC_VectTab_FLASH)) 119 | /** 120 | * @} 121 | */ 122 | 123 | /** @defgroup System_Low_Power 124 | * @{ 125 | */ 126 | 127 | #define NVIC_LP_SEVONPEND ((uint8_t)0x10) 128 | #define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) 129 | #define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) 130 | #define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ 131 | ((LP) == NVIC_LP_SLEEPDEEP) || \ 132 | ((LP) == NVIC_LP_SLEEPONEXIT)) 133 | /** 134 | * @} 135 | */ 136 | 137 | /** @defgroup Preemption_Priority_Group 138 | * @{ 139 | */ 140 | 141 | #define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 142 | 4 bits for subpriority */ 143 | #define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 144 | 3 bits for subpriority */ 145 | #define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 146 | 2 bits for subpriority */ 147 | #define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 148 | 1 bits for subpriority */ 149 | #define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 150 | 0 bits for subpriority */ 151 | 152 | #define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ 153 | ((GROUP) == NVIC_PriorityGroup_1) || \ 154 | ((GROUP) == NVIC_PriorityGroup_2) || \ 155 | ((GROUP) == NVIC_PriorityGroup_3) || \ 156 | ((GROUP) == NVIC_PriorityGroup_4)) 157 | 158 | #define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) 159 | 160 | #define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) 161 | 162 | #define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF) 163 | 164 | /** 165 | * @} 166 | */ 167 | 168 | /** @defgroup SysTick_clock_source 169 | * @{ 170 | */ 171 | 172 | #define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) 173 | #define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) 174 | #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ 175 | ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) 176 | /** 177 | * @} 178 | */ 179 | 180 | /** 181 | * @} 182 | */ 183 | 184 | /** @defgroup MISC_Exported_Macros 185 | * @{ 186 | */ 187 | 188 | /** 189 | * @} 190 | */ 191 | 192 | /** @defgroup MISC_Exported_Functions 193 | * @{ 194 | */ 195 | 196 | void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); 197 | void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); 198 | void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); 199 | void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); 200 | void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); 201 | 202 | #ifdef __cplusplus 203 | } 204 | #endif 205 | 206 | #endif /* __MISC_H */ 207 | 208 | /** 209 | * @} 210 | */ 211 | 212 | /** 213 | * @} 214 | */ 215 | 216 | /** 217 | * @} 218 | */ 219 | 220 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 221 | -------------------------------------------------------------------------------- /stm_lib/inc/stm32f10x_pwr.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f10x_pwr.h 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 11-March-2011 7 | * @brief This file contains all the functions prototypes for the PWR firmware 8 | * library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 13 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 14 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 15 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 16 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 17 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 18 | * 19 | *

© COPYRIGHT 2011 STMicroelectronics

20 | ****************************************************************************** 21 | */ 22 | 23 | /* Define to prevent recursive inclusion -------------------------------------*/ 24 | #ifndef __STM32F10x_PWR_H 25 | #define __STM32F10x_PWR_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /* Includes ------------------------------------------------------------------*/ 32 | #include "stm32f10x.h" 33 | 34 | /** @addtogroup STM32F10x_StdPeriph_Driver 35 | * @{ 36 | */ 37 | 38 | /** @addtogroup PWR 39 | * @{ 40 | */ 41 | 42 | /** @defgroup PWR_Exported_Types 43 | * @{ 44 | */ 45 | 46 | /** 47 | * @} 48 | */ 49 | 50 | /** @defgroup PWR_Exported_Constants 51 | * @{ 52 | */ 53 | 54 | /** @defgroup PVD_detection_level 55 | * @{ 56 | */ 57 | 58 | #define PWR_PVDLevel_2V2 ((uint32_t)0x00000000) 59 | #define PWR_PVDLevel_2V3 ((uint32_t)0x00000020) 60 | #define PWR_PVDLevel_2V4 ((uint32_t)0x00000040) 61 | #define PWR_PVDLevel_2V5 ((uint32_t)0x00000060) 62 | #define PWR_PVDLevel_2V6 ((uint32_t)0x00000080) 63 | #define PWR_PVDLevel_2V7 ((uint32_t)0x000000A0) 64 | #define PWR_PVDLevel_2V8 ((uint32_t)0x000000C0) 65 | #define PWR_PVDLevel_2V9 ((uint32_t)0x000000E0) 66 | #define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_2V2) || ((LEVEL) == PWR_PVDLevel_2V3)|| \ 67 | ((LEVEL) == PWR_PVDLevel_2V4) || ((LEVEL) == PWR_PVDLevel_2V5)|| \ 68 | ((LEVEL) == PWR_PVDLevel_2V6) || ((LEVEL) == PWR_PVDLevel_2V7)|| \ 69 | ((LEVEL) == PWR_PVDLevel_2V8) || ((LEVEL) == PWR_PVDLevel_2V9)) 70 | /** 71 | * @} 72 | */ 73 | 74 | /** @defgroup Regulator_state_is_STOP_mode 75 | * @{ 76 | */ 77 | 78 | #define PWR_Regulator_ON ((uint32_t)0x00000000) 79 | #define PWR_Regulator_LowPower ((uint32_t)0x00000001) 80 | #define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ 81 | ((REGULATOR) == PWR_Regulator_LowPower)) 82 | /** 83 | * @} 84 | */ 85 | 86 | /** @defgroup STOP_mode_entry 87 | * @{ 88 | */ 89 | 90 | #define PWR_STOPEntry_WFI ((uint8_t)0x01) 91 | #define PWR_STOPEntry_WFE ((uint8_t)0x02) 92 | #define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE)) 93 | 94 | /** 95 | * @} 96 | */ 97 | 98 | /** @defgroup PWR_Flag 99 | * @{ 100 | */ 101 | 102 | #define PWR_FLAG_WU ((uint32_t)0x00000001) 103 | #define PWR_FLAG_SB ((uint32_t)0x00000002) 104 | #define PWR_FLAG_PVDO ((uint32_t)0x00000004) 105 | #define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ 106 | ((FLAG) == PWR_FLAG_PVDO)) 107 | 108 | #define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB)) 109 | /** 110 | * @} 111 | */ 112 | 113 | /** 114 | * @} 115 | */ 116 | 117 | /** @defgroup PWR_Exported_Macros 118 | * @{ 119 | */ 120 | 121 | /** 122 | * @} 123 | */ 124 | 125 | /** @defgroup PWR_Exported_Functions 126 | * @{ 127 | */ 128 | 129 | void PWR_DeInit(void); 130 | void PWR_BackupAccessCmd(FunctionalState NewState); 131 | void PWR_PVDCmd(FunctionalState NewState); 132 | void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel); 133 | void PWR_WakeUpPinCmd(FunctionalState NewState); 134 | void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); 135 | void PWR_EnterSTANDBYMode(void); 136 | FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); 137 | void PWR_ClearFlag(uint32_t PWR_FLAG); 138 | 139 | #ifdef __cplusplus 140 | } 141 | #endif 142 | 143 | #endif /* __STM32F10x_PWR_H */ 144 | /** 145 | * @} 146 | */ 147 | 148 | /** 149 | * @} 150 | */ 151 | 152 | /** 153 | * @} 154 | */ 155 | 156 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 157 | -------------------------------------------------------------------------------- /stm_lib/inc/stm32f10x_spi.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f10x_spi.h 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 11-March-2011 7 | * @brief This file contains all the functions prototypes for the SPI firmware 8 | * library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 13 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 14 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 15 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 16 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 17 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 18 | * 19 | *

© COPYRIGHT 2011 STMicroelectronics

20 | ****************************************************************************** 21 | */ 22 | 23 | /* Define to prevent recursive inclusion -------------------------------------*/ 24 | #ifndef __STM32F10x_SPI_H 25 | #define __STM32F10x_SPI_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /* Includes ------------------------------------------------------------------*/ 32 | #include "stm32f10x.h" 33 | 34 | /** @addtogroup STM32F10x_StdPeriph_Driver 35 | * @{ 36 | */ 37 | 38 | /** @addtogroup SPI 39 | * @{ 40 | */ 41 | 42 | /** @defgroup SPI_Exported_Types 43 | * @{ 44 | */ 45 | 46 | /** 47 | * @brief SPI Init structure definition 48 | */ 49 | 50 | typedef struct 51 | { 52 | uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode. 53 | This parameter can be a value of @ref SPI_data_direction */ 54 | 55 | uint16_t SPI_Mode; /*!< Specifies the SPI operating mode. 56 | This parameter can be a value of @ref SPI_mode */ 57 | 58 | uint16_t SPI_DataSize; /*!< Specifies the SPI data size. 59 | This parameter can be a value of @ref SPI_data_size */ 60 | 61 | uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. 62 | This parameter can be a value of @ref SPI_Clock_Polarity */ 63 | 64 | uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. 65 | This parameter can be a value of @ref SPI_Clock_Phase */ 66 | 67 | uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by 68 | hardware (NSS pin) or by software using the SSI bit. 69 | This parameter can be a value of @ref SPI_Slave_Select_management */ 70 | 71 | uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be 72 | used to configure the transmit and receive SCK clock. 73 | This parameter can be a value of @ref SPI_BaudRate_Prescaler. 74 | @note The communication clock is derived from the master 75 | clock. The slave clock does not need to be set. */ 76 | 77 | uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. 78 | This parameter can be a value of @ref SPI_MSB_LSB_transmission */ 79 | 80 | uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */ 81 | }SPI_InitTypeDef; 82 | 83 | /** 84 | * @brief I2S Init structure definition 85 | */ 86 | 87 | typedef struct 88 | { 89 | 90 | uint16_t I2S_Mode; /*!< Specifies the I2S operating mode. 91 | This parameter can be a value of @ref I2S_Mode */ 92 | 93 | uint16_t I2S_Standard; /*!< Specifies the standard used for the I2S communication. 94 | This parameter can be a value of @ref I2S_Standard */ 95 | 96 | uint16_t I2S_DataFormat; /*!< Specifies the data format for the I2S communication. 97 | This parameter can be a value of @ref I2S_Data_Format */ 98 | 99 | uint16_t I2S_MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. 100 | This parameter can be a value of @ref I2S_MCLK_Output */ 101 | 102 | uint32_t I2S_AudioFreq; /*!< Specifies the frequency selected for the I2S communication. 103 | This parameter can be a value of @ref I2S_Audio_Frequency */ 104 | 105 | uint16_t I2S_CPOL; /*!< Specifies the idle state of the I2S clock. 106 | This parameter can be a value of @ref I2S_Clock_Polarity */ 107 | }I2S_InitTypeDef; 108 | 109 | /** 110 | * @} 111 | */ 112 | 113 | /** @defgroup SPI_Exported_Constants 114 | * @{ 115 | */ 116 | 117 | #define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \ 118 | ((PERIPH) == SPI2) || \ 119 | ((PERIPH) == SPI3)) 120 | 121 | #define IS_SPI_23_PERIPH(PERIPH) (((PERIPH) == SPI2) || \ 122 | ((PERIPH) == SPI3)) 123 | 124 | /** @defgroup SPI_data_direction 125 | * @{ 126 | */ 127 | 128 | #define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000) 129 | #define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400) 130 | #define SPI_Direction_1Line_Rx ((uint16_t)0x8000) 131 | #define SPI_Direction_1Line_Tx ((uint16_t)0xC000) 132 | #define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \ 133 | ((MODE) == SPI_Direction_2Lines_RxOnly) || \ 134 | ((MODE) == SPI_Direction_1Line_Rx) || \ 135 | ((MODE) == SPI_Direction_1Line_Tx)) 136 | /** 137 | * @} 138 | */ 139 | 140 | /** @defgroup SPI_mode 141 | * @{ 142 | */ 143 | 144 | #define SPI_Mode_Master ((uint16_t)0x0104) 145 | #define SPI_Mode_Slave ((uint16_t)0x0000) 146 | #define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ 147 | ((MODE) == SPI_Mode_Slave)) 148 | /** 149 | * @} 150 | */ 151 | 152 | /** @defgroup SPI_data_size 153 | * @{ 154 | */ 155 | 156 | #define SPI_DataSize_16b ((uint16_t)0x0800) 157 | #define SPI_DataSize_8b ((uint16_t)0x0000) 158 | #define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_16b) || \ 159 | ((DATASIZE) == SPI_DataSize_8b)) 160 | /** 161 | * @} 162 | */ 163 | 164 | /** @defgroup SPI_Clock_Polarity 165 | * @{ 166 | */ 167 | 168 | #define SPI_CPOL_Low ((uint16_t)0x0000) 169 | #define SPI_CPOL_High ((uint16_t)0x0002) 170 | #define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ 171 | ((CPOL) == SPI_CPOL_High)) 172 | /** 173 | * @} 174 | */ 175 | 176 | /** @defgroup SPI_Clock_Phase 177 | * @{ 178 | */ 179 | 180 | #define SPI_CPHA_1Edge ((uint16_t)0x0000) 181 | #define SPI_CPHA_2Edge ((uint16_t)0x0001) 182 | #define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ 183 | ((CPHA) == SPI_CPHA_2Edge)) 184 | /** 185 | * @} 186 | */ 187 | 188 | /** @defgroup SPI_Slave_Select_management 189 | * @{ 190 | */ 191 | 192 | #define SPI_NSS_Soft ((uint16_t)0x0200) 193 | #define SPI_NSS_Hard ((uint16_t)0x0000) 194 | #define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \ 195 | ((NSS) == SPI_NSS_Hard)) 196 | /** 197 | * @} 198 | */ 199 | 200 | /** @defgroup SPI_BaudRate_Prescaler 201 | * @{ 202 | */ 203 | 204 | #define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000) 205 | #define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008) 206 | #define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010) 207 | #define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018) 208 | #define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020) 209 | #define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028) 210 | #define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030) 211 | #define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038) 212 | #define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \ 213 | ((PRESCALER) == SPI_BaudRatePrescaler_4) || \ 214 | ((PRESCALER) == SPI_BaudRatePrescaler_8) || \ 215 | ((PRESCALER) == SPI_BaudRatePrescaler_16) || \ 216 | ((PRESCALER) == SPI_BaudRatePrescaler_32) || \ 217 | ((PRESCALER) == SPI_BaudRatePrescaler_64) || \ 218 | ((PRESCALER) == SPI_BaudRatePrescaler_128) || \ 219 | ((PRESCALER) == SPI_BaudRatePrescaler_256)) 220 | /** 221 | * @} 222 | */ 223 | 224 | /** @defgroup SPI_MSB_LSB_transmission 225 | * @{ 226 | */ 227 | 228 | #define SPI_FirstBit_MSB ((uint16_t)0x0000) 229 | #define SPI_FirstBit_LSB ((uint16_t)0x0080) 230 | #define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \ 231 | ((BIT) == SPI_FirstBit_LSB)) 232 | /** 233 | * @} 234 | */ 235 | 236 | /** @defgroup I2S_Mode 237 | * @{ 238 | */ 239 | 240 | #define I2S_Mode_SlaveTx ((uint16_t)0x0000) 241 | #define I2S_Mode_SlaveRx ((uint16_t)0x0100) 242 | #define I2S_Mode_MasterTx ((uint16_t)0x0200) 243 | #define I2S_Mode_MasterRx ((uint16_t)0x0300) 244 | #define IS_I2S_MODE(MODE) (((MODE) == I2S_Mode_SlaveTx) || \ 245 | ((MODE) == I2S_Mode_SlaveRx) || \ 246 | ((MODE) == I2S_Mode_MasterTx) || \ 247 | ((MODE) == I2S_Mode_MasterRx) ) 248 | /** 249 | * @} 250 | */ 251 | 252 | /** @defgroup I2S_Standard 253 | * @{ 254 | */ 255 | 256 | #define I2S_Standard_Phillips ((uint16_t)0x0000) 257 | #define I2S_Standard_MSB ((uint16_t)0x0010) 258 | #define I2S_Standard_LSB ((uint16_t)0x0020) 259 | #define I2S_Standard_PCMShort ((uint16_t)0x0030) 260 | #define I2S_Standard_PCMLong ((uint16_t)0x00B0) 261 | #define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_Standard_Phillips) || \ 262 | ((STANDARD) == I2S_Standard_MSB) || \ 263 | ((STANDARD) == I2S_Standard_LSB) || \ 264 | ((STANDARD) == I2S_Standard_PCMShort) || \ 265 | ((STANDARD) == I2S_Standard_PCMLong)) 266 | /** 267 | * @} 268 | */ 269 | 270 | /** @defgroup I2S_Data_Format 271 | * @{ 272 | */ 273 | 274 | #define I2S_DataFormat_16b ((uint16_t)0x0000) 275 | #define I2S_DataFormat_16bextended ((uint16_t)0x0001) 276 | #define I2S_DataFormat_24b ((uint16_t)0x0003) 277 | #define I2S_DataFormat_32b ((uint16_t)0x0005) 278 | #define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DataFormat_16b) || \ 279 | ((FORMAT) == I2S_DataFormat_16bextended) || \ 280 | ((FORMAT) == I2S_DataFormat_24b) || \ 281 | ((FORMAT) == I2S_DataFormat_32b)) 282 | /** 283 | * @} 284 | */ 285 | 286 | /** @defgroup I2S_MCLK_Output 287 | * @{ 288 | */ 289 | 290 | #define I2S_MCLKOutput_Enable ((uint16_t)0x0200) 291 | #define I2S_MCLKOutput_Disable ((uint16_t)0x0000) 292 | #define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOutput_Enable) || \ 293 | ((OUTPUT) == I2S_MCLKOutput_Disable)) 294 | /** 295 | * @} 296 | */ 297 | 298 | /** @defgroup I2S_Audio_Frequency 299 | * @{ 300 | */ 301 | 302 | #define I2S_AudioFreq_192k ((uint32_t)192000) 303 | #define I2S_AudioFreq_96k ((uint32_t)96000) 304 | #define I2S_AudioFreq_48k ((uint32_t)48000) 305 | #define I2S_AudioFreq_44k ((uint32_t)44100) 306 | #define I2S_AudioFreq_32k ((uint32_t)32000) 307 | #define I2S_AudioFreq_22k ((uint32_t)22050) 308 | #define I2S_AudioFreq_16k ((uint32_t)16000) 309 | #define I2S_AudioFreq_11k ((uint32_t)11025) 310 | #define I2S_AudioFreq_8k ((uint32_t)8000) 311 | #define I2S_AudioFreq_Default ((uint32_t)2) 312 | 313 | #define IS_I2S_AUDIO_FREQ(FREQ) ((((FREQ) >= I2S_AudioFreq_8k) && \ 314 | ((FREQ) <= I2S_AudioFreq_192k)) || \ 315 | ((FREQ) == I2S_AudioFreq_Default)) 316 | /** 317 | * @} 318 | */ 319 | 320 | /** @defgroup I2S_Clock_Polarity 321 | * @{ 322 | */ 323 | 324 | #define I2S_CPOL_Low ((uint16_t)0x0000) 325 | #define I2S_CPOL_High ((uint16_t)0x0008) 326 | #define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_Low) || \ 327 | ((CPOL) == I2S_CPOL_High)) 328 | /** 329 | * @} 330 | */ 331 | 332 | /** @defgroup SPI_I2S_DMA_transfer_requests 333 | * @{ 334 | */ 335 | 336 | #define SPI_I2S_DMAReq_Tx ((uint16_t)0x0002) 337 | #define SPI_I2S_DMAReq_Rx ((uint16_t)0x0001) 338 | #define IS_SPI_I2S_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((DMAREQ) != 0x00)) 339 | /** 340 | * @} 341 | */ 342 | 343 | /** @defgroup SPI_NSS_internal_software_management 344 | * @{ 345 | */ 346 | 347 | #define SPI_NSSInternalSoft_Set ((uint16_t)0x0100) 348 | #define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF) 349 | #define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \ 350 | ((INTERNAL) == SPI_NSSInternalSoft_Reset)) 351 | /** 352 | * @} 353 | */ 354 | 355 | /** @defgroup SPI_CRC_Transmit_Receive 356 | * @{ 357 | */ 358 | 359 | #define SPI_CRC_Tx ((uint8_t)0x00) 360 | #define SPI_CRC_Rx ((uint8_t)0x01) 361 | #define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx)) 362 | /** 363 | * @} 364 | */ 365 | 366 | /** @defgroup SPI_direction_transmit_receive 367 | * @{ 368 | */ 369 | 370 | #define SPI_Direction_Rx ((uint16_t)0xBFFF) 371 | #define SPI_Direction_Tx ((uint16_t)0x4000) 372 | #define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \ 373 | ((DIRECTION) == SPI_Direction_Tx)) 374 | /** 375 | * @} 376 | */ 377 | 378 | /** @defgroup SPI_I2S_interrupts_definition 379 | * @{ 380 | */ 381 | 382 | #define SPI_I2S_IT_TXE ((uint8_t)0x71) 383 | #define SPI_I2S_IT_RXNE ((uint8_t)0x60) 384 | #define SPI_I2S_IT_ERR ((uint8_t)0x50) 385 | #define IS_SPI_I2S_CONFIG_IT(IT) (((IT) == SPI_I2S_IT_TXE) || \ 386 | ((IT) == SPI_I2S_IT_RXNE) || \ 387 | ((IT) == SPI_I2S_IT_ERR)) 388 | #define SPI_I2S_IT_OVR ((uint8_t)0x56) 389 | #define SPI_IT_MODF ((uint8_t)0x55) 390 | #define SPI_IT_CRCERR ((uint8_t)0x54) 391 | #define I2S_IT_UDR ((uint8_t)0x53) 392 | #define IS_SPI_I2S_CLEAR_IT(IT) (((IT) == SPI_IT_CRCERR)) 393 | #define IS_SPI_I2S_GET_IT(IT) (((IT) == SPI_I2S_IT_RXNE) || ((IT) == SPI_I2S_IT_TXE) || \ 394 | ((IT) == I2S_IT_UDR) || ((IT) == SPI_IT_CRCERR) || \ 395 | ((IT) == SPI_IT_MODF) || ((IT) == SPI_I2S_IT_OVR)) 396 | /** 397 | * @} 398 | */ 399 | 400 | /** @defgroup SPI_I2S_flags_definition 401 | * @{ 402 | */ 403 | 404 | #define SPI_I2S_FLAG_RXNE ((uint16_t)0x0001) 405 | #define SPI_I2S_FLAG_TXE ((uint16_t)0x0002) 406 | #define I2S_FLAG_CHSIDE ((uint16_t)0x0004) 407 | #define I2S_FLAG_UDR ((uint16_t)0x0008) 408 | #define SPI_FLAG_CRCERR ((uint16_t)0x0010) 409 | #define SPI_FLAG_MODF ((uint16_t)0x0020) 410 | #define SPI_I2S_FLAG_OVR ((uint16_t)0x0040) 411 | #define SPI_I2S_FLAG_BSY ((uint16_t)0x0080) 412 | #define IS_SPI_I2S_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR)) 413 | #define IS_SPI_I2S_GET_FLAG(FLAG) (((FLAG) == SPI_I2S_FLAG_BSY) || ((FLAG) == SPI_I2S_FLAG_OVR) || \ 414 | ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \ 415 | ((FLAG) == I2S_FLAG_UDR) || ((FLAG) == I2S_FLAG_CHSIDE) || \ 416 | ((FLAG) == SPI_I2S_FLAG_TXE) || ((FLAG) == SPI_I2S_FLAG_RXNE)) 417 | /** 418 | * @} 419 | */ 420 | 421 | /** @defgroup SPI_CRC_polynomial 422 | * @{ 423 | */ 424 | 425 | #define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1) 426 | /** 427 | * @} 428 | */ 429 | 430 | /** 431 | * @} 432 | */ 433 | 434 | /** @defgroup SPI_Exported_Macros 435 | * @{ 436 | */ 437 | 438 | /** 439 | * @} 440 | */ 441 | 442 | /** @defgroup SPI_Exported_Functions 443 | * @{ 444 | */ 445 | 446 | void SPI_I2S_DeInit(SPI_TypeDef* SPIx); 447 | void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); 448 | void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct); 449 | void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct); 450 | void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct); 451 | void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); 452 | void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); 453 | void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); 454 | void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); 455 | void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); 456 | uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx); 457 | void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft); 458 | void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState); 459 | void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize); 460 | void SPI_TransmitCRC(SPI_TypeDef* SPIx); 461 | void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState); 462 | uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC); 463 | uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx); 464 | void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction); 465 | FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); 466 | void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); 467 | ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); 468 | void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); 469 | 470 | #ifdef __cplusplus 471 | } 472 | #endif 473 | 474 | #endif /*__STM32F10x_SPI_H */ 475 | /** 476 | * @} 477 | */ 478 | 479 | /** 480 | * @} 481 | */ 482 | 483 | /** 484 | * @} 485 | */ 486 | 487 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 488 | -------------------------------------------------------------------------------- /stm_lib/inc/stm32f10x_usart.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f10x_usart.h 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 11-March-2011 7 | * @brief This file contains all the functions prototypes for the USART 8 | * firmware library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 13 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 14 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 15 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 16 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 17 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 18 | * 19 | *

© COPYRIGHT 2011 STMicroelectronics

20 | ****************************************************************************** 21 | */ 22 | 23 | /* Define to prevent recursive inclusion -------------------------------------*/ 24 | #ifndef __STM32F10x_USART_H 25 | #define __STM32F10x_USART_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /* Includes ------------------------------------------------------------------*/ 32 | #include "stm32f10x.h" 33 | 34 | /** @addtogroup STM32F10x_StdPeriph_Driver 35 | * @{ 36 | */ 37 | 38 | /** @addtogroup USART 39 | * @{ 40 | */ 41 | 42 | /** @defgroup USART_Exported_Types 43 | * @{ 44 | */ 45 | 46 | /** 47 | * @brief USART Init Structure definition 48 | */ 49 | 50 | typedef struct 51 | { 52 | uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. 53 | The baud rate is computed using the following formula: 54 | - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))) 55 | - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */ 56 | 57 | uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. 58 | This parameter can be a value of @ref USART_Word_Length */ 59 | 60 | uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. 61 | This parameter can be a value of @ref USART_Stop_Bits */ 62 | 63 | uint16_t USART_Parity; /*!< Specifies the parity mode. 64 | This parameter can be a value of @ref USART_Parity 65 | @note When parity is enabled, the computed parity is inserted 66 | at the MSB position of the transmitted data (9th bit when 67 | the word length is set to 9 data bits; 8th bit when the 68 | word length is set to 8 data bits). */ 69 | 70 | uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. 71 | This parameter can be a value of @ref USART_Mode */ 72 | 73 | uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled 74 | or disabled. 75 | This parameter can be a value of @ref USART_Hardware_Flow_Control */ 76 | } USART_InitTypeDef; 77 | 78 | /** 79 | * @brief USART Clock Init Structure definition 80 | */ 81 | 82 | typedef struct 83 | { 84 | 85 | uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled. 86 | This parameter can be a value of @ref USART_Clock */ 87 | 88 | uint16_t USART_CPOL; /*!< Specifies the steady state value of the serial clock. 89 | This parameter can be a value of @ref USART_Clock_Polarity */ 90 | 91 | uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made. 92 | This parameter can be a value of @ref USART_Clock_Phase */ 93 | 94 | uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted 95 | data bit (MSB) has to be output on the SCLK pin in synchronous mode. 96 | This parameter can be a value of @ref USART_Last_Bit */ 97 | } USART_ClockInitTypeDef; 98 | 99 | /** 100 | * @} 101 | */ 102 | 103 | /** @defgroup USART_Exported_Constants 104 | * @{ 105 | */ 106 | 107 | #define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \ 108 | ((PERIPH) == USART2) || \ 109 | ((PERIPH) == USART3) || \ 110 | ((PERIPH) == UART4) || \ 111 | ((PERIPH) == UART5)) 112 | 113 | #define IS_USART_123_PERIPH(PERIPH) (((PERIPH) == USART1) || \ 114 | ((PERIPH) == USART2) || \ 115 | ((PERIPH) == USART3)) 116 | 117 | #define IS_USART_1234_PERIPH(PERIPH) (((PERIPH) == USART1) || \ 118 | ((PERIPH) == USART2) || \ 119 | ((PERIPH) == USART3) || \ 120 | ((PERIPH) == UART4)) 121 | /** @defgroup USART_Word_Length 122 | * @{ 123 | */ 124 | 125 | #define USART_WordLength_8b ((uint16_t)0x0000) 126 | #define USART_WordLength_9b ((uint16_t)0x1000) 127 | 128 | #define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \ 129 | ((LENGTH) == USART_WordLength_9b)) 130 | /** 131 | * @} 132 | */ 133 | 134 | /** @defgroup USART_Stop_Bits 135 | * @{ 136 | */ 137 | 138 | #define USART_StopBits_1 ((uint16_t)0x0000) 139 | #define USART_StopBits_0_5 ((uint16_t)0x1000) 140 | #define USART_StopBits_2 ((uint16_t)0x2000) 141 | #define USART_StopBits_1_5 ((uint16_t)0x3000) 142 | #define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \ 143 | ((STOPBITS) == USART_StopBits_0_5) || \ 144 | ((STOPBITS) == USART_StopBits_2) || \ 145 | ((STOPBITS) == USART_StopBits_1_5)) 146 | /** 147 | * @} 148 | */ 149 | 150 | /** @defgroup USART_Parity 151 | * @{ 152 | */ 153 | 154 | #define USART_Parity_No ((uint16_t)0x0000) 155 | #define USART_Parity_Even ((uint16_t)0x0400) 156 | #define USART_Parity_Odd ((uint16_t)0x0600) 157 | #define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \ 158 | ((PARITY) == USART_Parity_Even) || \ 159 | ((PARITY) == USART_Parity_Odd)) 160 | /** 161 | * @} 162 | */ 163 | 164 | /** @defgroup USART_Mode 165 | * @{ 166 | */ 167 | 168 | #define USART_Mode_Rx ((uint16_t)0x0004) 169 | #define USART_Mode_Tx ((uint16_t)0x0008) 170 | #define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00)) 171 | /** 172 | * @} 173 | */ 174 | 175 | /** @defgroup USART_Hardware_Flow_Control 176 | * @{ 177 | */ 178 | #define USART_HardwareFlowControl_None ((uint16_t)0x0000) 179 | #define USART_HardwareFlowControl_RTS ((uint16_t)0x0100) 180 | #define USART_HardwareFlowControl_CTS ((uint16_t)0x0200) 181 | #define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300) 182 | #define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\ 183 | (((CONTROL) == USART_HardwareFlowControl_None) || \ 184 | ((CONTROL) == USART_HardwareFlowControl_RTS) || \ 185 | ((CONTROL) == USART_HardwareFlowControl_CTS) || \ 186 | ((CONTROL) == USART_HardwareFlowControl_RTS_CTS)) 187 | /** 188 | * @} 189 | */ 190 | 191 | /** @defgroup USART_Clock 192 | * @{ 193 | */ 194 | #define USART_Clock_Disable ((uint16_t)0x0000) 195 | #define USART_Clock_Enable ((uint16_t)0x0800) 196 | #define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \ 197 | ((CLOCK) == USART_Clock_Enable)) 198 | /** 199 | * @} 200 | */ 201 | 202 | /** @defgroup USART_Clock_Polarity 203 | * @{ 204 | */ 205 | 206 | #define USART_CPOL_Low ((uint16_t)0x0000) 207 | #define USART_CPOL_High ((uint16_t)0x0400) 208 | #define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High)) 209 | 210 | /** 211 | * @} 212 | */ 213 | 214 | /** @defgroup USART_Clock_Phase 215 | * @{ 216 | */ 217 | 218 | #define USART_CPHA_1Edge ((uint16_t)0x0000) 219 | #define USART_CPHA_2Edge ((uint16_t)0x0200) 220 | #define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge)) 221 | 222 | /** 223 | * @} 224 | */ 225 | 226 | /** @defgroup USART_Last_Bit 227 | * @{ 228 | */ 229 | 230 | #define USART_LastBit_Disable ((uint16_t)0x0000) 231 | #define USART_LastBit_Enable ((uint16_t)0x0100) 232 | #define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \ 233 | ((LASTBIT) == USART_LastBit_Enable)) 234 | /** 235 | * @} 236 | */ 237 | 238 | /** @defgroup USART_Interrupt_definition 239 | * @{ 240 | */ 241 | 242 | #define USART_IT_PE ((uint16_t)0x0028) 243 | #define USART_IT_TXE ((uint16_t)0x0727) 244 | #define USART_IT_TC ((uint16_t)0x0626) 245 | #define USART_IT_RXNE ((uint16_t)0x0525) 246 | #define USART_IT_IDLE ((uint16_t)0x0424) 247 | #define USART_IT_LBD ((uint16_t)0x0846) 248 | #define USART_IT_CTS ((uint16_t)0x096A) 249 | #define USART_IT_ERR ((uint16_t)0x0060) 250 | #define USART_IT_ORE ((uint16_t)0x0360) 251 | #define USART_IT_NE ((uint16_t)0x0260) 252 | #define USART_IT_FE ((uint16_t)0x0160) 253 | #define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ 254 | ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ 255 | ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ 256 | ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR)) 257 | #define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ 258 | ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ 259 | ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ 260 | ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \ 261 | ((IT) == USART_IT_NE) || ((IT) == USART_IT_FE)) 262 | #define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ 263 | ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS)) 264 | /** 265 | * @} 266 | */ 267 | 268 | /** @defgroup USART_DMA_Requests 269 | * @{ 270 | */ 271 | 272 | #define USART_DMAReq_Tx ((uint16_t)0x0080) 273 | #define USART_DMAReq_Rx ((uint16_t)0x0040) 274 | #define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00)) 275 | 276 | /** 277 | * @} 278 | */ 279 | 280 | /** @defgroup USART_WakeUp_methods 281 | * @{ 282 | */ 283 | 284 | #define USART_WakeUp_IdleLine ((uint16_t)0x0000) 285 | #define USART_WakeUp_AddressMark ((uint16_t)0x0800) 286 | #define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \ 287 | ((WAKEUP) == USART_WakeUp_AddressMark)) 288 | /** 289 | * @} 290 | */ 291 | 292 | /** @defgroup USART_LIN_Break_Detection_Length 293 | * @{ 294 | */ 295 | 296 | #define USART_LINBreakDetectLength_10b ((uint16_t)0x0000) 297 | #define USART_LINBreakDetectLength_11b ((uint16_t)0x0020) 298 | #define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \ 299 | (((LENGTH) == USART_LINBreakDetectLength_10b) || \ 300 | ((LENGTH) == USART_LINBreakDetectLength_11b)) 301 | /** 302 | * @} 303 | */ 304 | 305 | /** @defgroup USART_IrDA_Low_Power 306 | * @{ 307 | */ 308 | 309 | #define USART_IrDAMode_LowPower ((uint16_t)0x0004) 310 | #define USART_IrDAMode_Normal ((uint16_t)0x0000) 311 | #define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \ 312 | ((MODE) == USART_IrDAMode_Normal)) 313 | /** 314 | * @} 315 | */ 316 | 317 | /** @defgroup USART_Flags 318 | * @{ 319 | */ 320 | 321 | #define USART_FLAG_CTS ((uint16_t)0x0200) 322 | #define USART_FLAG_LBD ((uint16_t)0x0100) 323 | #define USART_FLAG_TXE ((uint16_t)0x0080) 324 | #define USART_FLAG_TC ((uint16_t)0x0040) 325 | #define USART_FLAG_RXNE ((uint16_t)0x0020) 326 | #define USART_FLAG_IDLE ((uint16_t)0x0010) 327 | #define USART_FLAG_ORE ((uint16_t)0x0008) 328 | #define USART_FLAG_NE ((uint16_t)0x0004) 329 | #define USART_FLAG_FE ((uint16_t)0x0002) 330 | #define USART_FLAG_PE ((uint16_t)0x0001) 331 | #define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \ 332 | ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \ 333 | ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \ 334 | ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \ 335 | ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE)) 336 | 337 | #define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00)) 338 | #define IS_USART_PERIPH_FLAG(PERIPH, USART_FLAG) ((((*(uint32_t*)&(PERIPH)) != UART4_BASE) &&\ 339 | ((*(uint32_t*)&(PERIPH)) != UART5_BASE)) \ 340 | || ((USART_FLAG) != USART_FLAG_CTS)) 341 | #define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 0x0044AA21)) 342 | #define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF) 343 | #define IS_USART_DATA(DATA) ((DATA) <= 0x1FF) 344 | 345 | /** 346 | * @} 347 | */ 348 | 349 | /** 350 | * @} 351 | */ 352 | 353 | /** @defgroup USART_Exported_Macros 354 | * @{ 355 | */ 356 | 357 | /** 358 | * @} 359 | */ 360 | 361 | /** @defgroup USART_Exported_Functions 362 | * @{ 363 | */ 364 | 365 | void USART_DeInit(USART_TypeDef* USARTx); 366 | void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); 367 | void USART_StructInit(USART_InitTypeDef* USART_InitStruct); 368 | void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct); 369 | void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct); 370 | void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); 371 | void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); 372 | void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); 373 | void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address); 374 | void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp); 375 | void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState); 376 | void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength); 377 | void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState); 378 | void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); 379 | uint16_t USART_ReceiveData(USART_TypeDef* USARTx); 380 | void USART_SendBreak(USART_TypeDef* USARTx); 381 | void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime); 382 | void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler); 383 | void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState); 384 | void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState); 385 | void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState); 386 | void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState); 387 | void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState); 388 | void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode); 389 | void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState); 390 | FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); 391 | void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); 392 | ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); 393 | void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); 394 | 395 | #ifdef __cplusplus 396 | } 397 | #endif 398 | 399 | #endif /* __STM32F10x_USART_H */ 400 | /** 401 | * @} 402 | */ 403 | 404 | /** 405 | * @} 406 | */ 407 | 408 | /** 409 | * @} 410 | */ 411 | 412 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 413 | -------------------------------------------------------------------------------- /stm_lib/src/.readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /stm_lib/src/misc.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file misc.c 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 11-March-2011 7 | * @brief This file provides all the miscellaneous firmware functions (add-on 8 | * to CMSIS functions). 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 13 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 14 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 15 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 16 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 17 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 18 | * 19 | *

© COPYRIGHT 2011 STMicroelectronics

20 | ****************************************************************************** 21 | */ 22 | 23 | /* Includes ------------------------------------------------------------------*/ 24 | #include "misc.h" 25 | 26 | /** @addtogroup STM32F10x_StdPeriph_Driver 27 | * @{ 28 | */ 29 | 30 | /** @defgroup MISC 31 | * @brief MISC driver modules 32 | * @{ 33 | */ 34 | 35 | /** @defgroup MISC_Private_TypesDefinitions 36 | * @{ 37 | */ 38 | 39 | /** 40 | * @} 41 | */ 42 | 43 | /** @defgroup MISC_Private_Defines 44 | * @{ 45 | */ 46 | 47 | #define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) 48 | /** 49 | * @} 50 | */ 51 | 52 | /** @defgroup MISC_Private_Macros 53 | * @{ 54 | */ 55 | 56 | /** 57 | * @} 58 | */ 59 | 60 | /** @defgroup MISC_Private_Variables 61 | * @{ 62 | */ 63 | 64 | /** 65 | * @} 66 | */ 67 | 68 | /** @defgroup MISC_Private_FunctionPrototypes 69 | * @{ 70 | */ 71 | 72 | /** 73 | * @} 74 | */ 75 | 76 | /** @defgroup MISC_Private_Functions 77 | * @{ 78 | */ 79 | 80 | /** 81 | * @brief Configures the priority grouping: pre-emption priority and subpriority. 82 | * @param NVIC_PriorityGroup: specifies the priority grouping bits length. 83 | * This parameter can be one of the following values: 84 | * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority 85 | * 4 bits for subpriority 86 | * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority 87 | * 3 bits for subpriority 88 | * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority 89 | * 2 bits for subpriority 90 | * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority 91 | * 1 bits for subpriority 92 | * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority 93 | * 0 bits for subpriority 94 | * @retval None 95 | */ 96 | void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) 97 | { 98 | /* Check the parameters */ 99 | assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); 100 | 101 | /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ 102 | SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; 103 | } 104 | 105 | /** 106 | * @brief Initializes the NVIC peripheral according to the specified 107 | * parameters in the NVIC_InitStruct. 108 | * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains 109 | * the configuration information for the specified NVIC peripheral. 110 | * @retval None 111 | */ 112 | void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) 113 | { 114 | uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; 115 | 116 | /* Check the parameters */ 117 | assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); 118 | assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); 119 | assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); 120 | 121 | if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) 122 | { 123 | /* Compute the Corresponding IRQ Priority --------------------------------*/ 124 | tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; 125 | tmppre = (0x4 - tmppriority); 126 | tmpsub = tmpsub >> tmppriority; 127 | 128 | tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; 129 | tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; 130 | tmppriority = tmppriority << 0x04; 131 | 132 | NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; 133 | 134 | /* Enable the Selected IRQ Channels --------------------------------------*/ 135 | NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = 136 | (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); 137 | } 138 | else 139 | { 140 | /* Disable the Selected IRQ Channels -------------------------------------*/ 141 | NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = 142 | (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); 143 | } 144 | } 145 | 146 | /** 147 | * @brief Sets the vector table location and Offset. 148 | * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. 149 | * This parameter can be one of the following values: 150 | * @arg NVIC_VectTab_RAM 151 | * @arg NVIC_VectTab_FLASH 152 | * @param Offset: Vector Table base offset field. This value must be a multiple 153 | * of 0x200. 154 | * @retval None 155 | */ 156 | void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) 157 | { 158 | /* Check the parameters */ 159 | assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); 160 | assert_param(IS_NVIC_OFFSET(Offset)); 161 | 162 | SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); 163 | } 164 | 165 | /** 166 | * @brief Selects the condition for the system to enter low power mode. 167 | * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. 168 | * This parameter can be one of the following values: 169 | * @arg NVIC_LP_SEVONPEND 170 | * @arg NVIC_LP_SLEEPDEEP 171 | * @arg NVIC_LP_SLEEPONEXIT 172 | * @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE. 173 | * @retval None 174 | */ 175 | void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) 176 | { 177 | /* Check the parameters */ 178 | assert_param(IS_NVIC_LP(LowPowerMode)); 179 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 180 | 181 | if (NewState != DISABLE) 182 | { 183 | SCB->SCR |= LowPowerMode; 184 | } 185 | else 186 | { 187 | SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); 188 | } 189 | } 190 | 191 | /** 192 | * @brief Configures the SysTick clock source. 193 | * @param SysTick_CLKSource: specifies the SysTick clock source. 194 | * This parameter can be one of the following values: 195 | * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. 196 | * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. 197 | * @retval None 198 | */ 199 | void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) 200 | { 201 | /* Check the parameters */ 202 | assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); 203 | if (SysTick_CLKSource == SysTick_CLKSource_HCLK) 204 | { 205 | SysTick->CTRL |= SysTick_CLKSource_HCLK; 206 | } 207 | else 208 | { 209 | SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; 210 | } 211 | } 212 | 213 | /** 214 | * @} 215 | */ 216 | 217 | /** 218 | * @} 219 | */ 220 | 221 | /** 222 | * @} 223 | */ 224 | 225 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 226 | -------------------------------------------------------------------------------- /stm_lib/src/stm32f10x_flash.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qyon/STM32_RTTY/bf4172669fbd1a5882208ab992ccd62b8037b0aa/stm_lib/src/stm32f10x_flash.c -------------------------------------------------------------------------------- /stm_lib/src/stm32f10x_pwr.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f10x_pwr.c 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 11-March-2011 7 | * @brief This file provides all the PWR firmware functions. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 17 | * 18 | *

© COPYRIGHT 2011 STMicroelectronics

19 | ****************************************************************************** 20 | */ 21 | 22 | /* Includes ------------------------------------------------------------------*/ 23 | #include "stm32f10x_pwr.h" 24 | #include "stm32f10x_rcc.h" 25 | 26 | /** @addtogroup STM32F10x_StdPeriph_Driver 27 | * @{ 28 | */ 29 | 30 | /** @defgroup PWR 31 | * @brief PWR driver modules 32 | * @{ 33 | */ 34 | 35 | /** @defgroup PWR_Private_TypesDefinitions 36 | * @{ 37 | */ 38 | 39 | /** 40 | * @} 41 | */ 42 | 43 | /** @defgroup PWR_Private_Defines 44 | * @{ 45 | */ 46 | 47 | /* --------- PWR registers bit address in the alias region ---------- */ 48 | #define PWR_OFFSET (PWR_BASE - PERIPH_BASE) 49 | 50 | /* --- CR Register ---*/ 51 | 52 | /* Alias word address of DBP bit */ 53 | #define CR_OFFSET (PWR_OFFSET + 0x00) 54 | #define DBP_BitNumber 0x08 55 | #define CR_DBP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (DBP_BitNumber * 4)) 56 | 57 | /* Alias word address of PVDE bit */ 58 | #define PVDE_BitNumber 0x04 59 | #define CR_PVDE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PVDE_BitNumber * 4)) 60 | 61 | /* --- CSR Register ---*/ 62 | 63 | /* Alias word address of EWUP bit */ 64 | #define CSR_OFFSET (PWR_OFFSET + 0x04) 65 | #define EWUP_BitNumber 0x08 66 | #define CSR_EWUP_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (EWUP_BitNumber * 4)) 67 | 68 | /* ------------------ PWR registers bit mask ------------------------ */ 69 | 70 | /* CR register bit mask */ 71 | #define CR_DS_MASK ((uint32_t)0xFFFFFFFC) 72 | #define CR_PLS_MASK ((uint32_t)0xFFFFFF1F) 73 | 74 | 75 | /** 76 | * @} 77 | */ 78 | 79 | /** @defgroup PWR_Private_Macros 80 | * @{ 81 | */ 82 | 83 | /** 84 | * @} 85 | */ 86 | 87 | /** @defgroup PWR_Private_Variables 88 | * @{ 89 | */ 90 | 91 | /** 92 | * @} 93 | */ 94 | 95 | /** @defgroup PWR_Private_FunctionPrototypes 96 | * @{ 97 | */ 98 | 99 | /** 100 | * @} 101 | */ 102 | 103 | /** @defgroup PWR_Private_Functions 104 | * @{ 105 | */ 106 | 107 | /** 108 | * @brief Deinitializes the PWR peripheral registers to their default reset values. 109 | * @param None 110 | * @retval None 111 | */ 112 | void PWR_DeInit(void) 113 | { 114 | RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); 115 | RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE); 116 | } 117 | 118 | /** 119 | * @brief Enables or disables access to the RTC and backup registers. 120 | * @param NewState: new state of the access to the RTC and backup registers. 121 | * This parameter can be: ENABLE or DISABLE. 122 | * @retval None 123 | */ 124 | void PWR_BackupAccessCmd(FunctionalState NewState) 125 | { 126 | /* Check the parameters */ 127 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 128 | *(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState; 129 | } 130 | 131 | /** 132 | * @brief Enables or disables the Power Voltage Detector(PVD). 133 | * @param NewState: new state of the PVD. 134 | * This parameter can be: ENABLE or DISABLE. 135 | * @retval None 136 | */ 137 | void PWR_PVDCmd(FunctionalState NewState) 138 | { 139 | /* Check the parameters */ 140 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 141 | *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)NewState; 142 | } 143 | 144 | /** 145 | * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). 146 | * @param PWR_PVDLevel: specifies the PVD detection level 147 | * This parameter can be one of the following values: 148 | * @arg PWR_PVDLevel_2V2: PVD detection level set to 2.2V 149 | * @arg PWR_PVDLevel_2V3: PVD detection level set to 2.3V 150 | * @arg PWR_PVDLevel_2V4: PVD detection level set to 2.4V 151 | * @arg PWR_PVDLevel_2V5: PVD detection level set to 2.5V 152 | * @arg PWR_PVDLevel_2V6: PVD detection level set to 2.6V 153 | * @arg PWR_PVDLevel_2V7: PVD detection level set to 2.7V 154 | * @arg PWR_PVDLevel_2V8: PVD detection level set to 2.8V 155 | * @arg PWR_PVDLevel_2V9: PVD detection level set to 2.9V 156 | * @retval None 157 | */ 158 | void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel) 159 | { 160 | uint32_t tmpreg = 0; 161 | /* Check the parameters */ 162 | assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel)); 163 | tmpreg = PWR->CR; 164 | /* Clear PLS[7:5] bits */ 165 | tmpreg &= CR_PLS_MASK; 166 | /* Set PLS[7:5] bits according to PWR_PVDLevel value */ 167 | tmpreg |= PWR_PVDLevel; 168 | /* Store the new value */ 169 | PWR->CR = tmpreg; 170 | } 171 | 172 | /** 173 | * @brief Enables or disables the WakeUp Pin functionality. 174 | * @param NewState: new state of the WakeUp Pin functionality. 175 | * This parameter can be: ENABLE or DISABLE. 176 | * @retval None 177 | */ 178 | void PWR_WakeUpPinCmd(FunctionalState NewState) 179 | { 180 | /* Check the parameters */ 181 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 182 | *(__IO uint32_t *) CSR_EWUP_BB = (uint32_t)NewState; 183 | } 184 | 185 | /** 186 | * @brief Enters STOP mode. 187 | * @param PWR_Regulator: specifies the regulator state in STOP mode. 188 | * This parameter can be one of the following values: 189 | * @arg PWR_Regulator_ON: STOP mode with regulator ON 190 | * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode 191 | * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. 192 | * This parameter can be one of the following values: 193 | * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction 194 | * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction 195 | * @retval None 196 | */ 197 | void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) 198 | { 199 | uint32_t tmpreg = 0; 200 | /* Check the parameters */ 201 | assert_param(IS_PWR_REGULATOR(PWR_Regulator)); 202 | assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); 203 | 204 | /* Select the regulator state in STOP mode ---------------------------------*/ 205 | tmpreg = PWR->CR; 206 | /* Clear PDDS and LPDS bits */ 207 | tmpreg &= CR_DS_MASK; 208 | /* Set LPDS bit according to PWR_Regulator value */ 209 | tmpreg |= PWR_Regulator; 210 | /* Store the new value */ 211 | PWR->CR = tmpreg; 212 | /* Set SLEEPDEEP bit of Cortex System Control Register */ 213 | SCB->SCR |= SCB_SCR_SLEEPDEEP; 214 | 215 | /* Select STOP mode entry --------------------------------------------------*/ 216 | if(PWR_STOPEntry == PWR_STOPEntry_WFI) 217 | { 218 | /* Request Wait For Interrupt */ 219 | __WFI(); 220 | } 221 | else 222 | { 223 | /* Request Wait For Event */ 224 | __WFE(); 225 | } 226 | 227 | /* Reset SLEEPDEEP bit of Cortex System Control Register */ 228 | SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); 229 | } 230 | 231 | /** 232 | * @brief Enters STANDBY mode. 233 | * @param None 234 | * @retval None 235 | */ 236 | void PWR_EnterSTANDBYMode(void) 237 | { 238 | /* Clear Wake-up flag */ 239 | PWR->CR |= PWR_CR_CWUF; 240 | /* Select STANDBY mode */ 241 | PWR->CR |= PWR_CR_PDDS; 242 | /* Set SLEEPDEEP bit of Cortex System Control Register */ 243 | SCB->SCR |= SCB_SCR_SLEEPDEEP; 244 | /* This option is used to ensure that store operations are completed */ 245 | #if defined ( __CC_ARM ) 246 | __force_stores(); 247 | #endif 248 | /* Request Wait For Interrupt */ 249 | __WFI(); 250 | } 251 | 252 | /** 253 | * @brief Checks whether the specified PWR flag is set or not. 254 | * @param PWR_FLAG: specifies the flag to check. 255 | * This parameter can be one of the following values: 256 | * @arg PWR_FLAG_WU: Wake Up flag 257 | * @arg PWR_FLAG_SB: StandBy flag 258 | * @arg PWR_FLAG_PVDO: PVD Output 259 | * @retval The new state of PWR_FLAG (SET or RESET). 260 | */ 261 | FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG) 262 | { 263 | FlagStatus bitstatus = RESET; 264 | /* Check the parameters */ 265 | assert_param(IS_PWR_GET_FLAG(PWR_FLAG)); 266 | 267 | if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET) 268 | { 269 | bitstatus = SET; 270 | } 271 | else 272 | { 273 | bitstatus = RESET; 274 | } 275 | /* Return the flag status */ 276 | return bitstatus; 277 | } 278 | 279 | /** 280 | * @brief Clears the PWR's pending flags. 281 | * @param PWR_FLAG: specifies the flag to clear. 282 | * This parameter can be one of the following values: 283 | * @arg PWR_FLAG_WU: Wake Up flag 284 | * @arg PWR_FLAG_SB: StandBy flag 285 | * @retval None 286 | */ 287 | void PWR_ClearFlag(uint32_t PWR_FLAG) 288 | { 289 | /* Check the parameters */ 290 | assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG)); 291 | 292 | PWR->CR |= PWR_FLAG << 2; 293 | } 294 | 295 | /** 296 | * @} 297 | */ 298 | 299 | /** 300 | * @} 301 | */ 302 | 303 | /** 304 | * @} 305 | */ 306 | 307 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 308 | -------------------------------------------------------------------------------- /stm_lib/src/stm32f10x_usart.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qyon/STM32_RTTY/bf4172669fbd1a5882208ab992ccd62b8037b0aa/stm_lib/src/stm32f10x_usart.c -------------------------------------------------------------------------------- /syscalls/.readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /syscalls/syscalls.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************//***** 2 | * @file stdio.c 3 | * @brief Implementation of newlib syscall 4 | ********************************************************************************/ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #undef errno 12 | extern int errno; 13 | extern int _end; 14 | 15 | /*This function is used for handle heap option*/ 16 | __attribute__ ((used)) 17 | caddr_t _sbrk ( int incr ) 18 | { 19 | static unsigned char *heap = NULL; 20 | unsigned char *prev_heap; 21 | 22 | if (heap == NULL) { 23 | heap = (unsigned char *)&_end; 24 | } 25 | prev_heap = heap; 26 | 27 | heap += incr; 28 | 29 | return (caddr_t) prev_heap; 30 | } 31 | 32 | __attribute__ ((used)) 33 | int link(char *old, char *new) 34 | { 35 | return -1; 36 | } 37 | 38 | __attribute__ ((used)) 39 | int _close(int file) 40 | { 41 | return -1; 42 | } 43 | 44 | __attribute__ ((used)) 45 | int _fstat(int file, struct stat *st) 46 | { 47 | st->st_mode = S_IFCHR; 48 | return 0; 49 | } 50 | 51 | __attribute__ ((used)) 52 | int _isatty(int file) 53 | { 54 | return 1; 55 | } 56 | 57 | __attribute__ ((used)) 58 | int _lseek(int file, int ptr, int dir) 59 | { 60 | return 0; 61 | } 62 | 63 | /*Low layer read(input) function*/ 64 | __attribute__ ((used)) 65 | int _read(int file, char *ptr, int len) 66 | { 67 | 68 | #if 0 69 | //user code example 70 | int i; 71 | (void)file; 72 | 73 | for(i = 0; i < len; i++) 74 | { 75 | // UART_GetChar is user's basic input function 76 | *ptr++ = UART_GetChar(); 77 | } 78 | 79 | #endif 80 | 81 | return len; 82 | } 83 | 84 | 85 | /*Low layer write(output) function*/ 86 | __attribute__ ((used)) 87 | int _write(int file, char *ptr, int len) 88 | { 89 | 90 | #if 0 91 | //user code example 92 | 93 | int i; 94 | (void)file; 95 | 96 | for(i = 0; i < len; i++) 97 | { 98 | // UART_PutChar is user's basic output function 99 | UART_PutChar(*ptr++); 100 | } 101 | #endif 102 | 103 | return len; 104 | } 105 | 106 | __attribute__ ((used)) 107 | void abort(void) 108 | { 109 | /* Abort called */ 110 | while(1); 111 | } 112 | 113 | /* --------------------------------- End Of File ------------------------------ */ 114 | -------------------------------------------------------------------------------- /ublox.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by SQ5RWU on 2016-12-27. 3 | // 4 | 5 | #include 6 | #include 7 | #include "ublox.h" 8 | #include "delay.h" 9 | #include "init.h" 10 | 11 | GPSEntry currentGPSData; 12 | volatile uint8_t active = 0; 13 | volatile uint8_t ack_received = 0; 14 | volatile uint8_t nack_received = 0; 15 | 16 | void _sendSerialByte(uint8_t message) { 17 | while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) { 18 | } 19 | USART_SendData(USART1, message); 20 | while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) { 21 | } 22 | } 23 | 24 | void send_ublox(uint8_t msgClass, uint8_t msgId, uint8_t *payload, uint16_t payloadSize) { 25 | uBloxChecksum chksum = ublox_calc_checksum(msgClass, msgId, payload, payloadSize); 26 | 27 | _sendSerialByte(0xB5); 28 | _sendSerialByte(0x62); 29 | _sendSerialByte(msgClass); 30 | _sendSerialByte(msgId); 31 | _sendSerialByte((uint8_t) (payloadSize & 0xff)); 32 | _sendSerialByte((uint8_t) (payloadSize >> 8)); 33 | 34 | uint16_t i; 35 | for (i = 0; i < payloadSize; ++i) { 36 | _sendSerialByte(payload[i]); 37 | } 38 | _sendSerialByte(chksum.ck_a); 39 | _sendSerialByte(chksum.ck_b); 40 | } 41 | 42 | void send_ublox_packet(uBloxPacket * packet){ 43 | send_ublox(packet->header.messageClass, packet->header.messageId, (uint8_t*)&packet->data, packet->header.payloadSize); 44 | } 45 | 46 | uBloxChecksum ublox_calc_checksum(const uint8_t msgClass, const uint8_t msgId, const uint8_t *message, uint16_t size) { 47 | uBloxChecksum ck = {0, 0}; 48 | uint8_t i; 49 | ck.ck_a += msgClass; 50 | ck.ck_b += ck.ck_a; 51 | ck.ck_a += msgId; 52 | ck.ck_b += ck.ck_a; 53 | 54 | ck.ck_a += size & 0xff; 55 | ck.ck_b += ck.ck_a; 56 | ck.ck_a += size >> 8; 57 | ck.ck_b += ck.ck_a; 58 | 59 | 60 | for (i =0;iheader.sc1 = data; 135 | } else if (buffer_pos == 1 && data == 0x62){ 136 | sync = 1; 137 | buffer_pos = 2; 138 | incoming_packet->header.sc2 = data; 139 | } else { 140 | buffer_pos = 0; 141 | } 142 | } else { 143 | ((uint8_t *)incoming_packet)[buffer_pos] = data; 144 | if ((buffer_pos >= sizeof(uBloxHeader)-1) && (buffer_pos-1 == (incoming_packet->header.payloadSize + sizeof(uBloxHeader) + sizeof(uBloxChecksum)))){ 145 | ublox_handle_packet((uBloxPacket *) incoming_packet); 146 | buffer_pos = 0; 147 | sync = 0; 148 | } else { 149 | buffer_pos++; 150 | if (buffer_pos >= sizeof(uBloxPacket) + sizeof(uBloxChecksum)) { 151 | buffer_pos = 0; 152 | sync = 0; 153 | } 154 | } 155 | } 156 | } 157 | 158 | void ublox_handle_packet(uBloxPacket *pkt) { 159 | uBloxChecksum cksum = ublox_calc_checksum(pkt->header.messageClass, pkt->header.messageId, (const uint8_t *) &pkt->data, pkt->header.payloadSize); 160 | uBloxChecksum *checksum = (uBloxChecksum *)(((uint8_t*)&pkt->data) + pkt->header.payloadSize); 161 | if (cksum.ck_a != checksum->ck_a || cksum.ck_b != checksum->ck_b) { 162 | currentGPSData.bad_packets += 1; 163 | } else { 164 | 165 | if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x07){ 166 | currentGPSData.ok_packets += 1; 167 | currentGPSData.fix = pkt->data.navpvt.fixType; 168 | currentGPSData.lat_raw = pkt->data.navpvt.lat; 169 | currentGPSData.lon_raw = pkt->data.navpvt.lon; 170 | currentGPSData.alt_raw = pkt->data.navpvt.hMSL; 171 | currentGPSData.hours = pkt->data.navpvt.hour; 172 | currentGPSData.minutes = pkt->data.navpvt.min; 173 | currentGPSData.seconds = pkt->data.navpvt.sec; 174 | currentGPSData.sats_raw = pkt->data.navpvt.numSV; 175 | currentGPSData.speed_raw = pkt->data.navpvt.gSpeed; 176 | 177 | } else if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x02){ 178 | currentGPSData.ok_packets += 1; 179 | currentGPSData.lat_raw = pkt->data.navposllh.lat; 180 | currentGPSData.lon_raw = pkt->data.navposllh.lon; 181 | currentGPSData.alt_raw = pkt->data.navposllh.hMSL; 182 | } else if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x06){ 183 | currentGPSData.fix = pkt->data.navsol.gpsFix; 184 | currentGPSData.sats_raw = pkt->data.navsol.numSV; 185 | } else if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x21){ 186 | currentGPSData.hours = pkt->data.navtimeutc.hour; 187 | currentGPSData.minutes = pkt->data.navtimeutc.min; 188 | currentGPSData.seconds = pkt->data.navtimeutc.sec; 189 | } else if (pkt->header.messageClass == 0x05 && pkt->header.messageId == 0x01){ 190 | ack_received = 1; 191 | } else if (pkt->header.messageClass == 0x05 && pkt->header.messageId == 0x00){ 192 | nack_received = 1; 193 | } 194 | } 195 | 196 | } 197 | uint8_t ublox_wait_for_ack() { 198 | ack_received = 0; 199 | nack_received = 0; 200 | uint8_t timeout = 200; 201 | while(!ack_received && !nack_received){ 202 | _delay_ms(1); 203 | if (!timeout--){ 204 | break; 205 | } 206 | } 207 | 208 | return ack_received; 209 | } 210 | 211 | 212 | -------------------------------------------------------------------------------- /ublox.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by SQ5RWU on 2016-12-27. 3 | // 4 | 5 | #ifndef RS41HUP_UBLOX_H 6 | #define RS41HUP_UBLOX_H 7 | #include 8 | 9 | typedef struct { 10 | int32_t lat_raw; 11 | int32_t lon_raw; 12 | int32_t alt_raw; 13 | int32_t speed_raw; 14 | uint8_t sats_raw; 15 | uint8_t seconds; 16 | uint8_t minutes; 17 | uint8_t hours; 18 | uint8_t fix; 19 | uint16_t ok_packets; 20 | uint16_t bad_packets; 21 | } GPSEntry; 22 | 23 | typedef struct __attribute__((packed)){ 24 | uint8_t sc1; // 0xB5 25 | uint8_t sc2; // 0x62 26 | uint8_t messageClass; 27 | uint8_t messageId; 28 | uint16_t payloadSize; 29 | } uBloxHeader; 30 | 31 | typedef struct { 32 | uint8_t ck_a; 33 | uint8_t ck_b; 34 | } uBloxChecksum; 35 | 36 | typedef struct { 37 | uint32_t iTOW; //GPS time of week of the navigation epoch. [- ms] 38 | uint16_t year; //Year (UTC) [- y] 39 | uint8_t month; //Month, range 1..12 (UTC) [- month] 40 | uint8_t day; //Day of month, range 1..31 (UTC) [- d] 41 | uint8_t hour; //Hour of day, range 0..23 (UTC) [- h] 42 | uint8_t min; //Minute of hour, range 0..59 (UTC) [- min] 43 | uint8_t sec; //Seconds of minute, range 0..60 (UTC) [- s] 44 | uint8_t valid; //Validity flags (see graphic below) [- -] 45 | uint32_t tAcc; //Time accuracy estimate (UTC) [- ns] 46 | int32_t nano; //Fraction of second, range -1e9 .. 1e9 (UTC) [- ns] 47 | uint8_t fixType; //GNSSfix Type: [- -] 48 | uint8_t flags; //Fix status flags (see graphic below) [- -] 49 | uint8_t flags2; //Additional flags (see graphic below) [- -] 50 | uint8_t numSV; //Number of satellites used in Nav Solution [- -] 51 | int32_t lon; //Longitude [1e-7 deg] 52 | int32_t lat; //Latitude [1e-7 deg] 53 | int32_t height; //Height above ellipsoid [- mm] 54 | int32_t hMSL; //Height above mean sea level [- mm] 55 | uint32_t hAcc; //Horizontal accuracy estimate [- mm] 56 | uint32_t vAcc; //Vertical accuracy estimate [- mm] 57 | int32_t velN; //NED north velocity [- mm/s] 58 | int32_t velE; //NED east velocity [- mm/s] 59 | int32_t velD; //NED down velocity [- mm/s] 60 | int32_t gSpeed; //Ground Speed (2-D) [- mm/s] 61 | int32_t headMot; //Heading of motion (2-D) [1e-5 deg] 62 | uint32_t sAcc; //Speed accuracy estimate [- mm/s] 63 | uint32_t headAcc; //Heading accuracy estimate (both motion and vehicle) [1e-5 deg] 64 | uint16_t pDOP; //Position DOP [0.01 -] 65 | uint8_t reserved1[6]; //Reserved [- -] 66 | int32_t headVeh; //Heading of vehicle (2-D) [1e-5 deg] 67 | uint8_t reserved2[4]; //Reserved [- -] 68 | } uBloxNAVPVTPayload; 69 | 70 | typedef struct { 71 | uint32_t iTOW; //GPS Millisecond Time of Week [- ms] 72 | int32_t lon; //Longitude [1e-7 deg] 73 | int32_t lat; //Latitude [1e-7 deg] 74 | int32_t height; //Height above Ellipsoid [- mm] 75 | int32_t hMSL; //Height above mean sea level [- mm] 76 | uint32_t hAcc; //Horizontal Accuracy Estimate [- mm] 77 | uint32_t vAcc; //Vertical Accuracy Estimate [- mm] 78 | } uBloxNAVPOSLLHPayload; 79 | 80 | typedef struct { 81 | uint32_t iTOW; //GPS Millisecond Time of Week [- ms] 82 | int32_t fTOW; //Fractional Nanoseconds remainder of rounded ms above, range -500000 .. 500000 [- ns] 83 | int16_t week; //GPS week (GPS time) [- -] 84 | uint8_t gpsFix; //GPSfix Type, range 0..5 0x00 = No Fix 0x01 = Dead Reckoning only 0x02 = 2D-Fix 0x03 = 3D-Fix 0x04 = GPS + dead reckoning combined 0x05 = Time only fix 0x06..0xff: reserved [- -] 85 | uint8_t flags; //Fix Status Flags (see graphic below) [- -] 86 | int32_t ecefX; //ECEF X coordinate [- cm] 87 | int32_t ecefY; //ECEF Y coordinate [- cm] 88 | int32_t ecefZ; //ECEF Z coordinate [- cm] 89 | uint32_t pAcc; //3D Position Accuracy Estimate [- cm] 90 | int32_t ecefVX; //ECEF X velocity [- cm/s] 91 | int32_t ecefVY; //ECEF Y velocity [- cm/s] 92 | int32_t ecefVZ; //ECEF Z velocity [- cm/s] 93 | uint32_t sAcc; //Speed Accuracy Estimate [- cm/s] 94 | uint16_t pDOP; //Position DOP [0.01 -] 95 | uint8_t reserved1; //Reserved [- -] 96 | uint8_t numSV; //Number of SVs used in Nav Solution [- -] 97 | uint32_t reserved2; //Reserved [- -] 98 | 99 | } uBloxNAVSOLPayload; 100 | 101 | typedef struct { 102 | uint32_t iTOW; //GPS Millisecond Time of Week [- ms] 103 | uint32_t tAcc; //Time Accuracy Estimate [- ns] 104 | int32_t nano; //Nanoseconds of second, range -1e9 .. 1e9 (UTC) [- ns] 105 | uint16_t year; //Year, range 1999..2099 (UTC) [- y] 106 | uint8_t month; //Month, range 1..12 (UTC) [- month] 107 | uint8_t day; //Day of Month, range 1..31 (UTC) [- d] 108 | uint8_t hour; //Hour of Day, range 0..23 (UTC) [- h] 109 | uint8_t min; //Minute of Hour, range 0..59 (UTC) [- min] 110 | uint8_t sec; //Seconds of Minute, range 0..59 (UTC) [- s] 111 | uint8_t valid; //Validity Flags (see graphic below) [- -] 112 | 113 | } uBloxNAVTIMEUTCPayload; 114 | 115 | typedef struct { 116 | uint8_t portID; //Port Identifier Number (see Serial [- -] 117 | uint8_t reserved1; //Reserved [- -] 118 | uint16_t txReady; //TX ready PIN configuration [- -] 119 | uint32_t mode; //A bit mask describing the UART mode [- -] 120 | uint32_t baudRate; //Baud rate in bits/second [- Bits/s] 121 | uint16_t inProtoMask; //A mask describing which input protocols are active. [- -] 122 | uint16_t outProtoMask; //A mask describing which output protocols are active. [- -] 123 | uint16_t flags; //Flags bit mask (see graphic below) [- -] 124 | uint8_t reserved2[2]; //Reserved [- -] 125 | 126 | } uBloxCFGPRTPayload; 127 | 128 | typedef struct { 129 | uint8_t clsID; //Message Class [- -] 130 | uint8_t msgID; //Message Identifier [- -] 131 | uint8_t ck_a; 132 | uint8_t ck_b; 133 | } uBloxACKACKayload; 134 | 135 | 136 | typedef struct { 137 | uint8_t msgClass; //Message Class [- -] 138 | uint8_t msgID; //Message Identifier [- -] 139 | uint8_t rate; //Send rate on current Port [- -] 140 | } uBloxCFGMSGPayload; 141 | 142 | 143 | typedef struct { 144 | uint16_t navBbrMask; //BBR Sections to clear. The following Special Sets apply: 145 | // 0x0000 Hotstart 146 | // 0x0001 Warmstart 147 | // 0xFFFF Coldstart [- -] 148 | uint8_t resetMode; //Reset Type 149 | // - 0x00 - Hardware reset (Watchdog) immediately 150 | // - 0x01 - Controlled Software reset 151 | // - 0x02 - Controlled Software reset (GPS only) 152 | // - 0x04 - Hardware reset (Watchdog) after shutdown (>=FW6.0) 153 | // - 0x08 - Controlled GPS stop 154 | // - 0x09 - Controlled GPS start [- -] 155 | // - 0x09 - Controlled GPS start [- -] 156 | uint8_t reserved1; //Reserved [- -] 157 | } uBloxCFGRSTPayload; 158 | 159 | typedef struct { 160 | uint16_t mask; //Parameters Bitmask. Only the masked parameters will be applied. (see graphic below) [- -] 161 | uint8_t dynModel; //Dynamic Platform model: - 0 􀀀 Portable - 2 􀀀 Stationary - 3 􀀀 Pedestrian - 4 􀀀 Automotive - 5 􀀀 Sea - 6 􀀀 Airborne with <1g Acceleration - 7 􀀀 Airborne with <2g Acceleration - 8 􀀀 Airborne with <4g Acceleration [- -] 162 | uint8_t fixMode; //Position Fixing Mode. - 1: 2D only - 2: 3D only - 3: Auto 2D/3D [- -] 163 | int32_t fixedAlt; //Fixed altitude (mean sea level) for 2D fix mode. [0.01 m] 164 | uint32_t fixedAltVar; //Fixed altitude variance for 2D mode. [0.0001 m^2] 165 | int8_t minElev; //Minimum Elevation for a GNSS satellite to be used in NAV [- deg] 166 | uint8_t drLimit; //Maximum time to perform dead reckoning (linear extrapolation) in case of GPS signal loss [- s] 167 | uint16_t pDop; //Position DOP Mask to use [0.1 -] 168 | uint16_t tDop; //Time DOP Mask to use [0.1 -] 169 | uint16_t pAcc; //Position Accuracy Mask [- m] 170 | uint16_t tAcc; //Time Accuracy Mask [- m] 171 | uint8_t staticHoldThresh; //Static hold threshold [- cm/s] 172 | uint8_t dgpsTimeOut; //DGPS timeout, firmware 7 and newer only [- s] 173 | uint32_t reserved2; //Always set to zero [- -] 174 | uint32_t reserved3; //Always set to zero [- -] 175 | uint32_t reserved4; //Always set to zero [- -] 176 | } uBloxCFGNAV5Payload; 177 | 178 | typedef struct { 179 | uint8_t reserved1; //Always set to 8 [- -] 180 | uint8_t lpMode; //Low Power Mode 0: Max. performance mode 1: Power Save Mode (>= FW 6.00 only) 2-3: reserved 4: Eco mode 5-255: reserved [- -] 181 | } uBloxCFGRXMPayload; 182 | 183 | typedef union { 184 | uBloxNAVPVTPayload navpvt; 185 | uBloxCFGPRTPayload cfgprt; 186 | uBloxCFGMSGPayload cfgmsg; 187 | uBloxCFGNAV5Payload cfgnav5; 188 | uBloxNAVPOSLLHPayload navposllh; 189 | uBloxNAVSOLPayload navsol; 190 | uBloxNAVTIMEUTCPayload navtimeutc; 191 | uBloxACKACKayload ackack; 192 | uBloxCFGRSTPayload cfgrst; 193 | uBloxCFGRXMPayload cfgrxm; 194 | } ubloxPacketData; 195 | 196 | typedef struct __attribute__((packed)){ 197 | uBloxHeader header; 198 | ubloxPacketData data; 199 | } uBloxPacket; 200 | 201 | void ublox_init(); 202 | void send_ublox(uint8_t msgClass, uint8_t msgId, uint8_t *payload, uint16_t payloadSize); 203 | void send_ublox_packet(uBloxPacket * packet); 204 | void ublox_get_last_data(GPSEntry * gpsEntry); 205 | uBloxChecksum ublox_calc_checksum(const uint8_t msgClass, const uint8_t msgId, const uint8_t *message, uint16_t size); 206 | void ublox_handle_incoming_byte(uint8_t data); 207 | void ublox_handle_packet(uBloxPacket *pkt); 208 | uint8_t ublox_wait_for_ack(); 209 | 210 | #endif //RS41HUP_UBLOX_H 211 | --------------------------------------------------------------------------------