├── README.md ├── src ├── drv │ └── stm32f0xx │ │ ├── cortexm.h │ │ ├── AdcDriver.h │ │ ├── led.h │ │ ├── GpioDrv.h │ │ ├── Timer.h │ │ ├── CanDriver.h │ │ ├── CmdUart.h │ │ ├── SysutilitySTM32F0xx.cpp │ │ ├── led.cpp │ │ ├── AdcSTM32F0xx.cpp │ │ ├── GpioDrvSTM32F0xx.cpp │ │ ├── TimerSTM32F0xx.cpp │ │ ├── UartSTM32F0xx.h │ │ ├── CmdUartSTM32F0xx.cpp │ │ └── CanDriverSTM32F0xx.cpp ├── adapter │ ├── adapterdefs.h │ ├── obd │ │ ├── autoadapter.h │ │ ├── autoadapter.cpp │ │ ├── obdprofile.h │ │ ├── canhistory.h │ │ ├── padapter.cpp │ │ ├── padapter.h │ │ ├── canhistory.cpp │ │ ├── isocan.h │ │ ├── obdprofile.cpp │ │ └── isocan.cpp │ ├── adapterconfig.cpp │ ├── adapter.cpp │ ├── adaptertypes.h │ ├── functions.cpp │ └── dispatcher.cpp └── util │ ├── algorithms.h │ ├── canmsgbuffer.cpp │ ├── canmsgbuffer.h │ ├── lstring.h │ ├── algorithms.cpp │ └── lstring.cpp ├── STM32F0xx_StdPeriph_Driver ├── inc │ ├── stm32f0xx_gpio.h │ └── stm32f0xx_adc.h └── src │ └── stm32f0xx_gpio.c ├── elm329.uvoptx └── elm329.uvprojx /README.md: -------------------------------------------------------------------------------- 1 | # ELM329 2 | Open-source ELM329 OBD adapter 3 | 4 | http://www.obddiag.net/elm329.html 5 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/cortexm.h: -------------------------------------------------------------------------------- 1 | #ifndef __CORTEX_M_H__ 2 | #define __CORTEX_M_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/AdcDriver.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __ADC_DRIVER_H__ 9 | #define __ADC_DRIVER_H__ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | class AdcDriver { 16 | public: 17 | static void configure(); 18 | static uint32_t read(); 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/adapter/adapterdefs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __ADAPTER_DEFS_H__ 9 | #define __ADAPTER_DEFS_H__ 10 | 11 | #ifdef __CC_ARM 12 | #define unique_ptr auto_ptr 13 | #define nullptr NULL 14 | #elif __GNUC__ 15 | #endif 16 | 17 | const int TX_LED_PORT = 0; 18 | const int RX_LED_PORT = 0; 19 | const int TX_LED_NUM = 7; 20 | const int RX_LED_NUM = 6; 21 | 22 | #endif //__ADAPTER_DEFS_H__ 23 | -------------------------------------------------------------------------------- /src/util/algorithms.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __ALGORITHMS_H__ 9 | #define __ALGORITHMS_H__ 10 | 11 | #include "lstring.h" 12 | 13 | namespace util { 14 | 15 | void to_lower(string& str); 16 | void to_upper(string& str); 17 | void remove_space(string& str); 18 | uint32_t stoul(const string& str, uint32_t* pos = 0, int base = 10); 19 | bool is_xdigits(const string& str); 20 | char to_ascii(uint8_t byte); 21 | 22 | } 23 | 24 | #endif //__ALGORITHMS_H__ 25 | -------------------------------------------------------------------------------- /src/adapter/obd/autoadapter.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __AUTO_PROFILE_H__ 9 | #define __AUTO_PROFILE_H__ 10 | 11 | #include "padapter.h" 12 | 13 | class AutoAdapter : public ProtocolAdapter { 14 | public: 15 | AutoAdapter() { connected_ = false; } 16 | virtual int onConnectEcu(bool sendReply); 17 | virtual int onRequest(const uint8_t* data, int len); 18 | virtual void getDescription(); 19 | virtual void getDescriptionNum(); 20 | virtual int getProtocol() const { return PROT_AUTO; } 21 | virtual void wiringCheck() {} 22 | private: 23 | }; 24 | 25 | #endif //__AUTO_PROFILE_H__ 26 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/led.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __LED_H__ 9 | #define __LED_H__ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | class PeriodicTimer; 16 | 17 | class AdptLED { 18 | public: 19 | static void configure(); 20 | static AdptLED* instance(); 21 | void startTimer(); 22 | void stopTimer(); 23 | void blinkTx(); 24 | void blinkRx(); 25 | private: 26 | AdptLED(); 27 | static void TimerCallback(); 28 | static volatile uint32_t txCount_; 29 | static volatile uint32_t rxCount_; 30 | PeriodicTimer* timer_; 31 | }; 32 | 33 | 34 | #endif //__LED_H__ 35 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/GpioDrv.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __GPIO_DRV_H__ 9 | #define __GPIO_DRV_H__ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | // GPIO Direction 16 | const uint32_t GPIO_INPUT = 0x0; 17 | const uint32_t GPIO_OUTPUT = 0x1; 18 | 19 | // Port attributes 20 | const uint32_t GPIO_OPEN_DRAIN = 0x400; 21 | 22 | void GPIOConfigure(uint32_t portNum); 23 | void GPIOSetDir(uint32_t portNum, uint32_t pinNum, uint32_t dir); 24 | void GPIOPinWrite(uint32_t portNum, uint32_t pinNum, uint32_t val); 25 | void GPIOPinConfig(uint32_t portNum, uint32_t pinNum, uint32_t val); 26 | uint32_t GPIOPinRead(uint32_t port_num, uint32_t pin_num); 27 | 28 | 29 | #endif //__GPIO_DRV_H__ 30 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/Timer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __TIMER_H__ 9 | #define __TIMER_H__ 10 | 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | 17 | class Timer { 18 | public: 19 | const static int TIMER0 = 0; 20 | const static int TIMER1 = 1; 21 | static void configure(); 22 | static Timer* instance(int timerNum); 23 | void start(uint32_t interval); 24 | bool isExpired() const; 25 | protected: 26 | Timer(int timerNum); 27 | TIM_TypeDef* timer_; 28 | }; 29 | 30 | // For use with Rx/Tx LEDs 31 | typedef void (*PeriodicCallbackT)(); 32 | class PeriodicTimer { 33 | public: 34 | PeriodicTimer(PeriodicCallbackT callback); 35 | void start(uint32_t interval); 36 | void stop(); 37 | }; 38 | 39 | #endif //__TIMER_H__ 40 | -------------------------------------------------------------------------------- /src/adapter/obd/autoadapter.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include "autoadapter.h" 9 | 10 | void AutoAdapter::getDescription() 11 | { 12 | AdptSendReply("AUTO"); 13 | } 14 | 15 | void AutoAdapter::getDescriptionNum() 16 | { 17 | AdptSendReply("0"); 18 | } 19 | 20 | int AutoAdapter::onRequest(const uint8_t* data, int len) 21 | { 22 | return REPLY_NO_DATA; 23 | } 24 | 25 | int AutoAdapter::onConnectEcu(bool sendReply) 26 | { 27 | // PWM 28 | int protocol = 0; 29 | // CAN 30 | protocol = ProtocolAdapter::getAdapter(ADPTR_CAN)->onConnectEcu(sendReply); 31 | if (protocol != 0) 32 | return protocol; 33 | // CAN 29 34 | protocol = ProtocolAdapter::getAdapter(ADPTR_CAN_EXT)->onConnectEcu(sendReply); 35 | if (protocol != 0) 36 | return protocol; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /src/adapter/obd/obdprofile.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __OBD_PROFILE_H__ 9 | #define __OBD_PROFILE_H__ 10 | 11 | #include "padapter.h" 12 | 13 | class OBDProfile { 14 | private: 15 | OBDProfile(); 16 | public: 17 | static OBDProfile* instance(); 18 | void getProfileDescription() const; 19 | void getProtocolDescription() const; 20 | void getProtocolDescriptionNum() const; 21 | int setProtocol(int protocol, bool refreshConnection); 22 | void dumpBuffer(); 23 | void closeProtocol(); 24 | void onRequest(const util::string& cmdString); 25 | int getProtocol() const; 26 | void wiringCheck(); 27 | private: 28 | bool sendLengthCheck(const uint8_t* msg, int len); 29 | int onRequestImpl(const util::string& cmdString); 30 | ProtocolAdapter* adapter_; 31 | }; 32 | 33 | #endif //__OBD_PROFILE_H__ 34 | -------------------------------------------------------------------------------- /src/util/canmsgbuffer.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include "canmsgbuffer.h" 10 | 11 | using namespace std; 12 | 13 | 14 | CanMsgBuffer::CanMsgBuffer() 15 | : id(0), extended(false), dlc(0), msgnum(0) 16 | { 17 | memset(data, 0, sizeof (data)); 18 | } 19 | 20 | CanMsgBuffer::CanMsgBuffer(uint32_t _id, bool _extended, uint8_t _dlc, 21 | uint8_t _data0, 22 | uint8_t _data1, 23 | uint8_t _data2, 24 | uint8_t _data3, 25 | uint8_t _data4, 26 | uint8_t _data5, 27 | uint8_t _data6, 28 | uint8_t _data7) 29 | { 30 | id = _id; 31 | extended = _extended; 32 | dlc = _dlc; 33 | data[0] = _data0; 34 | data[1] = _data1; 35 | data[2] = _data2; 36 | data[3] = _data3; 37 | data[4] = _data4; 38 | data[5] = _data5; 39 | data[6] = _data6; 40 | data[7] = _data7; 41 | } 42 | -------------------------------------------------------------------------------- /src/adapter/obd/canhistory.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __CAN_HISTORY_H__ 9 | #define __CAN_HISTORY_H__ 10 | 11 | #include 12 | 13 | using namespace util; 14 | 15 | struct MsgEntry { 16 | MsgEntry() : id(0), dir(false), ext(false), dlc(0), mid(0) 17 | { 18 | memset(data, 0, sizeof(data)); 19 | } 20 | uint32_t id; 21 | bool dir; 22 | bool ext; 23 | uint8_t dlc; 24 | uint8_t mid; 25 | uint8_t data[8]; 26 | }; 27 | 28 | struct CanMsgBuffer; 29 | 30 | class CanHistory { 31 | public: 32 | CanHistory() : currMsgPos_(0), numOfEntries_(0) {} 33 | void dumpCurrentBuffer(); 34 | void add2Buffer(const CanMsgBuffer* buff, bool dir, uint8_t mid) 35 | ; 36 | private: 37 | const static int HISTORY_LEN = 16; 38 | int currMsgPos_; 39 | int numOfEntries_; 40 | MsgEntry msglog_[HISTORY_LEN]; 41 | }; 42 | 43 | 44 | #endif //__CAN_HISTORY_H 45 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/CanDriver.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __CAND_RIVER_H__ 9 | #define __CAND_RIVER_H__ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | typedef void *CAN_HANDLE_T; 16 | struct CanMsgBuffer; 17 | 18 | class CanDriver { 19 | public: 20 | static CanDriver* instance(); 21 | static void configure(); 22 | bool send(const CanMsgBuffer* buff); 23 | bool setFilterAndMask(uint32_t filter, uint32_t mask, bool extended); 24 | bool isReady() const; 25 | bool read(CanMsgBuffer* buff); 26 | bool wakeUp(); 27 | bool sleep(); 28 | void setBitBang(bool val); 29 | void setBit(uint32_t val); 30 | uint32_t getBit(); 31 | static CAN_HANDLE_T handle_; 32 | private: 33 | CanDriver(); 34 | //void configRxMsgobj(uint32_t filter, uint32_t mask, uint8_t msgobj, bool can29bit, bool fifoLast); 35 | }; 36 | 37 | #endif //__CAN_DRIVER_H__ 38 | -------------------------------------------------------------------------------- /src/util/canmsgbuffer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __CAN_MSG_BUFFER_H__ 9 | #define __CAN_MSG_BUFFER_H__ 10 | 11 | #include 12 | 13 | using namespace std; 14 | 15 | // 16 | // To exchange messages with CAN controller 17 | // 18 | 19 | struct CanMsgBuffer { 20 | const static uint8_t DefaultByte = 0x55; 21 | CanMsgBuffer(); 22 | CanMsgBuffer(uint32_t _id, bool _extended, uint8_t _dlc, 23 | uint8_t _data0, 24 | uint8_t _data1 = DefaultByte, 25 | uint8_t _data2 = DefaultByte, 26 | uint8_t _data3 = DefaultByte, 27 | uint8_t _data4 = DefaultByte, 28 | uint8_t _data5 = DefaultByte, 29 | uint8_t _data6 = DefaultByte, 30 | uint8_t _data7 = DefaultByte); 31 | uint32_t id; 32 | bool extended; 33 | uint8_t dlc; 34 | uint8_t data[8]; 35 | uint8_t msgnum; 36 | }; 37 | 38 | #endif //__CAN_MSG_BUFFER_H__ 39 | 40 | -------------------------------------------------------------------------------- /src/adapter/obd/padapter.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include "padapter.h" 9 | #include "autoadapter.h" 10 | #include "isocan.h" 11 | 12 | using namespace util; 13 | 14 | /** 15 | * ProtocolAdapter object factory 16 | * @param[in] adapterType The adapter type number 17 | * @return The ProtocolAdapter pointer 18 | **/ 19 | ProtocolAdapter* ProtocolAdapter::getAdapter(int adapterType) 20 | { 21 | static AutoAdapter autoAdapter; 22 | static IsoCan11Adapter canAdapter; 23 | static IsoCan29Adapter canExtAdapter; 24 | 25 | switch (adapterType) { 26 | case ADPTR_AUTO: 27 | return &autoAdapter; 28 | case ADPTR_CAN: 29 | return &canAdapter; 30 | case ADPTR_CAN_EXT: 31 | return &canExtAdapter; 32 | default: 33 | return nullptr; 34 | } 35 | } 36 | 37 | /** 38 | * Print the current history for debug purposes 39 | */ 40 | void ProtocolAdapter::dumpBuffer() 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/CmdUart.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __CMD_UART_H__ 9 | #define __CMD_UART_H__ 10 | 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | const int TX_BUFFER_LEN = 100; 17 | 18 | typedef bool (*UartRecvHandler)(uint8_t ch); 19 | 20 | class CmdUart { 21 | public: 22 | static CmdUart* instance(); 23 | static void configure(); 24 | void irqHandler(); 25 | void init(uint32_t speed); 26 | void send(const util::string& str); 27 | void send(uint8_t ch); 28 | bool ready() const { return ready_; } 29 | void ready(bool val) { ready_ = val; } 30 | void handler(UartRecvHandler handler) { handler_ = handler; } 31 | private: 32 | CmdUart(); 33 | void txIrqHandler(); 34 | void rxIrqHandler(); 35 | 36 | char txData_[TX_BUFFER_LEN]; 37 | util::string rdData_; 38 | uint16_t txLen_; 39 | uint16_t txPos_; 40 | volatile bool ready_; 41 | UartRecvHandler handler_; 42 | }; 43 | 44 | 45 | #endif //__CMD_UART_H__ 46 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/SysutilitySTM32F0xx.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace util; 14 | 15 | /** 16 | * Format the UID as string 17 | * @paramer[in] uid UID 3 x uint32_t array 18 | * @return UID as a string 19 | */ 20 | static string UIDToString(uint32_t uid[]) 21 | { 22 | string str(40); 23 | 24 | for (int j = 0; j < 4; j++) { 25 | NumericType value(uid[j]); 26 | 27 | for (int i = 3; i >= 0; i--) { 28 | str += to_ascii(value.bvalue[i] >> 4); 29 | str += to_ascii(value.bvalue[i] & 0x0F); 30 | } 31 | str += '-'; 32 | } 33 | str.resize(str.length() - 1); 34 | return str; 35 | } 36 | 37 | /** 38 | * Display the LPC15XX CPU UID 39 | */ 40 | void AdptReadSerialNum() 41 | { 42 | uint32_t* uidBlock = reinterpret_cast(0x1FFFF7AC); 43 | AdptSendReply(UIDToString(uidBlock)); 44 | } 45 | 46 | /** 47 | * Defines the low power mode 48 | */ 49 | void AdptPowerModeConfigure() 50 | { 51 | } 52 | -------------------------------------------------------------------------------- /src/adapter/adapterconfig.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | const uint64_t onebit = 1; 13 | 14 | // 15 | // Configuration settings, storing/retrieving properties 16 | // 17 | 18 | AdapterConfig::AdapterConfig() : values_(0) 19 | { 20 | memset(intProps_, 0, sizeof(intProps_)); 21 | } 22 | 23 | void AdapterConfig::setBoolProperty(int id, bool val) 24 | { 25 | if (id > 64) 26 | return; 27 | values_ = val ? (values_ | (onebit << id)) : (values_ & ~(onebit << id)); 28 | } 29 | 30 | bool AdapterConfig::getBoolProperty(int id) const 31 | { 32 | if (id > 64) 33 | return false; 34 | return values_ & (onebit << id); 35 | } 36 | 37 | void AdapterConfig::setIntProperty(int id, uint32_t val) 38 | { 39 | int idx = id - INT_PROPS_START; 40 | intProps_[idx] = val; 41 | } 42 | 43 | uint32_t AdapterConfig::getIntProperty(int id) const 44 | { 45 | int idx = id - INT_PROPS_START; 46 | return intProps_[idx]; 47 | } 48 | 49 | void AdapterConfig::setBytesProperty(int id, const ByteArray* bytes) 50 | { 51 | int idx = id - BYTES_PROPS_START; 52 | bytesProps_[idx] = *bytes; 53 | } 54 | 55 | const ByteArray* AdapterConfig::getBytesProperty(int id) const 56 | { 57 | int idx = id - BYTES_PROPS_START; 58 | return &bytesProps_[idx]; 59 | } 60 | 61 | AdapterConfig* AdapterConfig::instance() 62 | { 63 | static AdapterConfig instance; 64 | return &instance; 65 | } 66 | -------------------------------------------------------------------------------- /src/adapter/obd/padapter.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __PROTOCOL_ADAPTER_H__ 9 | #define __PROTOCOL_ADAPTER_H__ 10 | 11 | #include 12 | 13 | // Command results 14 | // 15 | enum ReplyTypes { 16 | REPLY_OK = 1, 17 | REPLY_CMD_WRONG, 18 | REPLY_DATA_ERROR, 19 | REPLY_NO_DATA, 20 | REPLY_ERROR, 21 | REPLY_UNBL_2_CNNCT, 22 | REPLY_NONE, 23 | REPLY_BUS_BUSY, 24 | REPLY_BUS_ERROR, 25 | REPLY_CHKS_ERROR, 26 | REPLY_WIRING_ERROR 27 | }; 28 | 29 | // Protocols 30 | // 31 | enum ProtocolTypes { 32 | PROT_AUTO = 0, 33 | PROT_ISO15765_1150 = 6, 34 | PROT_ISO15765_2950 = 7, 35 | PROT_ISO15765_1125, 36 | PROT_ISO15765_2925 37 | }; 38 | 39 | // Adapters 40 | // 41 | enum AdapterTypes { 42 | ADPTR_AUTO, 43 | ADPTR_CAN, 44 | ADPTR_CAN_EXT 45 | }; 46 | 47 | class ProtocolAdapter { 48 | public: 49 | static ProtocolAdapter* getAdapter(int adapterType); 50 | virtual int onConnectEcu(bool sendReply) = 0; 51 | virtual int onRequest(const uint8_t* data, int len) = 0; 52 | virtual void getDescription() = 0; 53 | virtual void getDescriptionNum() = 0; 54 | virtual void dumpBuffer(); 55 | virtual void setProtocol(int protocol) { connected_ = true; } 56 | virtual void closeProtocol() { connected_ = false; } 57 | virtual void open() { connected_ = false; } 58 | virtual void close() {} 59 | virtual void wiringCheck() = 0; 60 | virtual int getProtocol() const = 0; 61 | bool isConnected() const { return connected_; } 62 | protected: 63 | ProtocolAdapter(); 64 | bool connected_; 65 | AdapterConfig* config_; 66 | }; 67 | 68 | #endif //__PROTOCOL_ADAPTER_H__ 69 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/led.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include "led.h" 12 | 13 | const int TimerBlinkNum = 10; // The blink longevity 14 | const int TimerInteral = 10; // 10ms 15 | 16 | volatile uint32_t AdptLED::txCount_; 17 | volatile uint32_t AdptLED::rxCount_; 18 | 19 | /** 20 | * Configure GPIO for RX and TX LEDs 21 | */ 22 | void AdptLED::configure() 23 | { 24 | GPIOSetDir(RX_LED_PORT, RX_LED_NUM, GPIO_OUTPUT); // yellow 25 | GPIOSetDir(TX_LED_PORT, TX_LED_NUM, GPIO_OUTPUT); // red 26 | //GPIOPinConfig(RX_LED_PORT, RX_LED_NUM, GPIO_OPEN_DRAIN); 27 | //GPIOPinConfig(TX_LED_PORT, TX_LED_NUM, GPIO_OPEN_DRAIN); 28 | RX_LED(0); 29 | TX_LED(0); 30 | txCount_ = rxCount_ = 0; 31 | } 32 | 33 | /** 34 | * AdptLED singleton 35 | * @return The AdptLED class instance 36 | */ 37 | AdptLED* AdptLED::instance() 38 | { 39 | static AdptLED instance; 40 | return &instance;; 41 | } 42 | 43 | /** 44 | * Constructo AdpLED object 45 | */ 46 | AdptLED::AdptLED() 47 | { 48 | timer_ = new PeriodicTimer(TimerCallback); 49 | } 50 | 51 | /** 52 | * Start the LED periodic timer with TimerInteral interval 53 | */ 54 | void AdptLED::startTimer() 55 | { 56 | timer_->start(TimerInteral); 57 | } 58 | 59 | /** 60 | * Stop the LED periodic timer 61 | */ 62 | void AdptLED::stopTimer() 63 | { 64 | timer_->stop(); 65 | } 66 | 67 | /** 68 | * Initiate the TX LED blink 69 | */ 70 | void AdptLED::blinkTx() 71 | { 72 | txCount_ = TimerBlinkNum; 73 | TX_LED(1); 74 | } 75 | 76 | /** 77 | * Initiate the RX LED blink 78 | */ 79 | void AdptLED::blinkRx() 80 | { 81 | rxCount_ = TimerBlinkNum; 82 | RX_LED(1); 83 | } 84 | 85 | /** 86 | * Periodic timer callback function, decrement the LED tick counters 87 | */ 88 | void AdptLED::TimerCallback() 89 | { 90 | if (rxCount_ && (--rxCount_ == 0)) { 91 | RX_LED(0); 92 | } 93 | if (txCount_ && (--txCount_ == 0)) { 94 | TX_LED(0); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/AdcSTM32F0xx.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include "cortexm.h" 9 | #include "AdcDriver.h" 10 | 11 | const uint16_t AdcPin = GPIO_Pin_0; 12 | const uint32_t AdcChannel = ADC_Channel_8; 13 | const GPIO_TypeDef* GPIOx = GPIOB; 14 | 15 | /** 16 | * Configuring comparator 17 | */ 18 | void AdcDriver::configure() 19 | { 20 | // Configure the ADC clock 21 | RCC_PCLKConfig(ADC_ClockMode_SynClkDiv2); 22 | 23 | // Enable ADC1 clock 24 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 25 | 26 | // GPIOA Periph clock enableed in PalGPIO_InitClock() 27 | 28 | // Configure ADC Channel0 as analog input 29 | GPIO_InitTypeDef GPIO_InitStruct; 30 | GPIO_InitStruct.GPIO_Pin = AdcPin ; 31 | GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; 32 | GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 33 | GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; 34 | GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; 35 | GPIO_Init(const_cast(GPIOB), &GPIO_InitStruct); 36 | 37 | // Initialize ADC structure 38 | ADC_InitTypeDef ADC_InitStruct; 39 | ADC_StructInit(&ADC_InitStruct); 40 | ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; 41 | ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // Trigger detection disabled 42 | ADC_InitStruct.ADC_ExternalTrigConv = 0; // Do not care 43 | ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; 44 | ADC_Init(ADC1, &ADC_InitStruct); 45 | 46 | // Convert the ADC1 Channel 0 with 239.5 Cycles as sampling time 47 | ADC_ChannelConfig(ADC1, AdcChannel, ADC_SampleTime_239_5Cycles); 48 | } 49 | 50 | uint32_t AdcDriver::read() 51 | { 52 | // ADC Calibration 53 | ADC_GetCalibrationFactor(ADC1); 54 | 55 | // Enable ADC 56 | ADC_Cmd(ADC1, ENABLE); 57 | 58 | // Start ADC1 Software Conversion 59 | ADC_StartOfConversion(ADC1); 60 | 61 | // Test EOC flag 62 | while(!ADC_GetFlagStatus(ADC1, ADC_ISR_EOC)); 63 | 64 | // Get ADC1 converted data 65 | uint16_t adcValue = ADC_GetConversionValue(ADC1); 66 | 67 | ADC_Cmd(ADC1, DISABLE); 68 | return adcValue; 69 | } 70 | -------------------------------------------------------------------------------- /src/adapter/obd/canhistory.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include "canhistory.h" 10 | #include "canmsgbuffer.h" 11 | 12 | using namespace std; 13 | using namespace util; 14 | 15 | /** 16 | * Display the message history 17 | */ 18 | void CanHistory::dumpCurrentBuffer() 19 | { 20 | const int can11Pos = 5; 21 | const int can29Pos = 10; 22 | int i, endp; 23 | 24 | // Calculate the end of the buffer 25 | if (numOfEntries_ <= HISTORY_LEN) 26 | i = endp = 0; 27 | else 28 | i = endp = currMsgPos_; 29 | 30 | // Calculate the message ID length, 11bit or 29bit 31 | bool extended = false; 32 | int pos1 = can11Pos; int j = i; 33 | do { 34 | if (msglog_[j].ext) { pos1 = can29Pos; extended = true; break; } 35 | // Advance the position 36 | j = (j == HISTORY_LEN-1) ? 0 : j + 1; 37 | } while (j != endp); 38 | 39 | const int pos2 = pos1 + 3; 40 | const int pos3 = pos2 + 3; 41 | string out; 42 | 43 | do { 44 | out.resize(0); 45 | CanIDToString(msglog_[i].id, out, extended); 46 | out.resize(pos1, ' '); 47 | out += msglog_[i].dir ? 'S' : 'R'; 48 | out.resize(pos2, ' '); 49 | out += msglog_[i].dlc + '0'; 50 | out.resize(pos3, ' '); 51 | to_ascii(msglog_[i].data, 8, out); 52 | out += " -> "; 53 | to_ascii(&msglog_[i].mid, 1, out); 54 | 55 | AdptSendReply(out); 56 | // Advance the position 57 | i = (i == HISTORY_LEN-1) ? 0 : i + 1; 58 | } while (i != endp); 59 | } 60 | 61 | /** 62 | * Add the CAN message to history log 63 | * @param[in] buff The CanMsgBuffer pointer to add 64 | * @param[in] dir The direction, false - receive, true send 65 | * @param[in] mid CAN receiver message buffer id 66 | */ 67 | void CanHistory::add2Buffer(const CanMsgBuffer* buff, bool dir, uint8_t mid) 68 | { 69 | int i = currMsgPos_++; 70 | 71 | msglog_[i].id = buff->id; 72 | msglog_[i].dir = dir; 73 | msglog_[i].ext = buff->extended; 74 | msglog_[i].dlc = buff->dlc; 75 | memcpy(msglog_[i].data, buff->data, sizeof(buff->data)); 76 | msglog_[i].mid = mid; 77 | 78 | if (currMsgPos_ >= HISTORY_LEN) { // curMsgPos = [0...15] 79 | currMsgPos_ = 0; 80 | } 81 | numOfEntries_++; 82 | } 83 | -------------------------------------------------------------------------------- /src/util/lstring.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | // 9 | // Lightweight string class 10 | // 11 | 12 | #ifndef __LSTRING_H__ 13 | #define __LSTRING_H__ 14 | 15 | #include 16 | 17 | using namespace std; 18 | 19 | //#define LSTRING_VALIDATE 20 | 21 | namespace util { 22 | 23 | class string { 24 | public: 25 | const static uint32_t STRING_SIZE = 50; 26 | const static uint32_t npos = 0xFFFFFFFF; 27 | string(uint32_t size = STRING_SIZE); 28 | string(const char* s); 29 | string(const string& other); 30 | string(uint32_t count, char ch); 31 | ~string(); 32 | void resize(uint32_t count); 33 | void resize(uint32_t count, char ch); 34 | string& append(const char* s); 35 | string& append(const char* s, uint32_t count); 36 | string& append(uint32_t count, char ch); 37 | string& assign(uint32_t count, char ch); 38 | void clear(); 39 | uint32_t copy(char* dest, uint32_t count, uint32_t pos = 0) const; 40 | const char* c_str() const { return data_; } 41 | bool empty() const { return (length_ == 0); } 42 | uint32_t find(const string& str, uint32_t pos = 0) const; 43 | uint32_t find(char ch, uint32_t pos = 0) const; 44 | uint32_t length() const { return length_; } 45 | string substr(uint32_t pos, uint32_t count = npos) const; 46 | string& operator+=(const string& other); 47 | string& operator+=(const char* s); 48 | string& operator+=(char ch); 49 | char operator[](uint32_t pos) const { return data_[pos]; } 50 | char& operator[](uint32_t pos) { return data_[pos]; } 51 | string& operator=(const string& str); 52 | string& operator=(const char* s); 53 | private: 54 | void init(uint32_t size); 55 | char* data_; 56 | uint16_t length_; 57 | uint16_t allocatedLength_; 58 | #ifdef LSTRING_VALIDATE 59 | void validate(uint32_t size); 60 | #endif 61 | }; 62 | 63 | bool operator==(const string& lhs, const char* rhs); 64 | bool operator!=(const string& lhs, const char* rhs); 65 | bool operator==(const string& lhs, const string& rhs); 66 | string operator+(const string& lhs, const string& rhs); 67 | string operator+(const char* lhs, const string& rhs); 68 | string operator+(char ch, const string& rhs); 69 | string operator+(const string& lhs, const char* rhs); 70 | string operator+(const string& lhs, char ch); 71 | 72 | } 73 | 74 | #endif //__LSTRING_H__ 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/GpioDrvSTM32F0xx.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include "cortexm.h" 9 | #include "GpioDrv.h" 10 | 11 | static GPIO_TypeDef* const GPIOPtr[] = { GPIOA, GPIOB, GPIOC }; 12 | 13 | /** 14 | * Enabling GPIOx clock 15 | * @param[in] portNum GPIO number (0..7) 16 | */ 17 | void GPIOConfigure(uint32_t portNum) 18 | { 19 | RCC->AHBENR |= (1UL << (portNum + 17)); 20 | } 21 | 22 | /** 23 | * Setting GPIO pin direction 24 | * @param[in] portNum GPIO number (0..7) 25 | * @param[in] pinNum Port pin number 26 | * @param[in] dir GPIO_DIR_INPUT, GPIO_DIR_OUTPUT 27 | */ 28 | void GPIOSetDir(uint32_t portNum, uint32_t pinNum, uint32_t dir) 29 | { 30 | GPIO_TypeDef* gpio = GPIOPtr[portNum]; 31 | if (dir == GPIO_OUTPUT) { 32 | gpio->ODR &= ~(1UL << 8); // Output data, set to 0 33 | gpio->MODER &= ~(3UL << 2 * pinNum); 34 | gpio->MODER |= (1UL << 2 * pinNum); // Output mode 35 | gpio->OTYPER &= ~(1UL << pinNum); // Output push-pull 36 | gpio->OSPEEDR |= (3UL << 2 * pinNum); // Port output 50 MHz High speed 37 | gpio->PUPDR &= ~(3UL << 2 * pinNum); // No pull-up, pull-down 38 | } 39 | else { 40 | gpio->MODER &= ~(3UL << 2 * pinNum); // Input mode 41 | gpio->PUPDR &= ~(3UL << 2 * pinNum); // No pull-up, pull-down 42 | } 43 | } 44 | 45 | /** 46 | * Setting the port pin value 47 | * @param[in] portNum GPIO number (0..7) 48 | * @param[in] pinNum Port pin number 49 | * @param[in] val Port pin value (0 or 1) 50 | */ 51 | void GPIOPinWrite(uint32_t portNum, uint32_t pinNum, uint32_t val) 52 | { 53 | GPIOPtr[portNum]->BSRR = val ? (1UL << pinNum) : (1UL << (pinNum + 16)); 54 | } 55 | 56 | /** 57 | * Read port pin 58 | * @param[in] portNum GPIO number (0..7) 59 | * @param[in] pinNum Port pin number 60 | * @return pin value (0 or 1) 61 | */ 62 | uint32_t GPIOPinRead (uint32_t portNum, uint32_t pinNum) 63 | { 64 | return (GPIOPtr[portNum]->IDR & (1UL << pinNum)) ? 1 : 0; 65 | } 66 | 67 | 68 | /** 69 | * Setting CPU-specific port attributes, like open drain and etc. 70 | * @param[in] portNum GPIO number (0..7) 71 | * @param[in] pinNum Port pin number 72 | * @param[in] val Port attribute 73 | */ 74 | void GPIOPinConfig(uint32_t portNum, uint32_t pinNum, uint32_t val) 75 | { 76 | GPIO_TypeDef* gpio = GPIOPtr[portNum]; 77 | if (val == GPIO_OPEN_DRAIN) { 78 | gpio->OTYPER |= (1UL << pinNum); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/util/algorithms.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include "algorithms.h" 11 | 12 | using namespace std; 13 | 14 | namespace util { 15 | 16 | /** 17 | * Convert string to lowercase 18 | * @param[in,out] str String to convert 19 | */ 20 | void to_lower(string& str) 21 | { 22 | for (int i = 0; i < str.length(); i++) { 23 | str[i] = tolower(str[i]); 24 | } 25 | } 26 | 27 | /** 28 | * Convert string to uppercase 29 | * @param[in,out] str String to convert 30 | */ 31 | void to_upper(string& str) 32 | { 33 | for (int i = 0; i < str.length(); i++) { 34 | str[i] = toupper(str[i]); 35 | } 36 | } 37 | 38 | /** 39 | * Checks if string is a valid ASCII hex string 40 | * @param[in] str String to validate 41 | * @return 1 if valid, 0 otherwise 42 | */ 43 | bool is_xdigits(const string& str) 44 | { 45 | int len = str.length(); 46 | if (len == 0 || len % 2) { 47 | return false; // Invalid string 48 | } 49 | 50 | for (int i = 0; i < len; i++) { 51 | if (!isxdigit(str[i])) { 52 | return false; 53 | } 54 | } 55 | return true; 56 | } 57 | 58 | /** 59 | * Do string space compression and uppercase conversion 60 | * @param[in,out] str String to perform action to 61 | */ 62 | void remove_space(string& str) 63 | { 64 | int len = str.length(); 65 | int j = 0; 66 | for (int i = 0; i < len; i++) { 67 | if (str[i] > ' ') { // Skip space or non-printable 68 | str[j++] = str[i]; 69 | } 70 | } 71 | str.resize(j); 72 | } 73 | 74 | /** 75 | * Standard library stoul implementation 76 | * @param[in] str String to perform action to 77 | * @param[out] pos The result length 78 | * @param[in] base Base 79 | * @return The result value 80 | */ 81 | uint32_t stoul(const string& str, uint32_t* pos, int base) 82 | { 83 | if (pos) 84 | *pos = str.length(); 85 | return strtoul(str.c_str(), 0, base);; 86 | } 87 | 88 | /** 89 | * Byte to Ascii converter 90 | * @param[in] byte Byte to convert 91 | * @return An ASCII characher 92 | */ 93 | char to_ascii(uint8_t byte) 94 | { 95 | const char dispthTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', 96 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 97 | return (byte <= 0xF) ? dispthTable[byte] : 0; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/adapter/obd/isocan.h: -------------------------------------------------------------------------------- 1 | // 2 | // IsoCanAdapter structures and definitions 3 | // 4 | 5 | #ifndef __ISO_CAN_H__ 6 | #define __ISO_CAN_H__ 7 | 8 | #include "padapter.h" 9 | 10 | const int CAN_P2_MAX_TIMEOUT = 50; 11 | 12 | class CanDriver; 13 | class CanHistory; 14 | struct CanMsgBuffer; 15 | 16 | class IsoCanAdapter : public ProtocolAdapter { 17 | public: 18 | static const int CANSingleFrame = 0; 19 | static const int CANFirstFrame = 1; 20 | static const int CANConsecutiveFrame = 2; 21 | static const int CANFlowControlFrame = 3; 22 | public: 23 | virtual int onRequest(const uint8_t* data, int len); 24 | virtual int onConnectEcu(bool sendReply); 25 | virtual void setFilter(const uint8_t* filter); 26 | virtual void setMask(const uint8_t* mask); 27 | virtual void setCanCAF(bool val) {} 28 | virtual void setPriorityByte(uint8_t val) { canPriority_ = val; } 29 | virtual void wiringCheck(); 30 | virtual void dumpBuffer(); 31 | protected: 32 | IsoCanAdapter(); 33 | virtual uint32_t getID() const = 0; 34 | virtual void setFilterAndMask() = 0; 35 | virtual void processFlowFrame(const CanMsgBuffer* msgBuffer) = 0; 36 | bool sendToEcu(const uint8_t* data, int len); 37 | bool receiveFromEcu(bool sendReply); 38 | bool isCustomMask() const { return mask_[0] != 0; } 39 | bool isCustomFilter() const { return filter_[0] != 0; } 40 | void processFrame(const CanMsgBuffer* msg); 41 | void formatReplyWithHeader(const CanMsgBuffer* msg, util::string& str); 42 | int getP2MaxTimeout() const; 43 | // 44 | CanDriver* driver_; 45 | CanHistory* history_; 46 | bool extended_; 47 | uint8_t canPriority_; 48 | uint8_t filter_[5]; // 4 bytes + length 49 | uint8_t mask_[5]; // 4 bytes + length 50 | }; 51 | 52 | class IsoCan11Adapter : public IsoCanAdapter { 53 | public: 54 | IsoCan11Adapter() {} 55 | virtual void getDescription(); 56 | virtual void getDescriptionNum(); 57 | virtual uint32_t getID() const; 58 | virtual void setFilterAndMask(); 59 | virtual void processFlowFrame(const CanMsgBuffer* msgBuffer); 60 | virtual int getProtocol() const { return PROT_ISO15765_1150; } 61 | virtual void open(); 62 | private: 63 | }; 64 | 65 | class IsoCan29Adapter : public IsoCanAdapter { 66 | public: 67 | IsoCan29Adapter() { extended_ = true; } 68 | virtual void getDescription(); 69 | virtual void getDescriptionNum(); 70 | virtual uint32_t getID() const; 71 | virtual void setFilterAndMask(); 72 | virtual void processFlowFrame(const CanMsgBuffer* msgBuffer); 73 | virtual int getProtocol() const { return PROT_ISO15765_2950; } 74 | virtual void open(); 75 | private: 76 | }; 77 | 78 | #endif //__ISO_CAN_H__ 79 | -------------------------------------------------------------------------------- /src/adapter/adapter.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | using namespace util; 20 | 21 | static string CmdBuffer(RX_CMD_LEN); 22 | static CmdUart* glblUart; 23 | 24 | /** 25 | * Enable the clocks and peripherals, initialize the drivers 26 | */ 27 | static void SetAllRegisters() 28 | { 29 | Timer::configure(); 30 | GPIOConfigure(0); 31 | GPIOConfigure(1); 32 | CmdUart::configure(); 33 | CanDriver::configure(); 34 | AdptLED::configure(); 35 | AdcDriver::configure(); 36 | } 37 | 38 | /** 39 | * Outer interface UART receive callback 40 | * @param[in] ch Character received from UART 41 | */ 42 | static bool UserUartRcvHandler(uint8_t ch) 43 | { 44 | static string cmdBuffer(RX_BUFFER_LEN); 45 | bool ready = false; 46 | 47 | if (cmdBuffer.length() >= (RX_BUFFER_LEN - 1)) { 48 | cmdBuffer.resize(0); // Truncate it 49 | } 50 | 51 | if (AdapterConfig::instance()->getBoolProperty(PAR_ECHO) && ch != '\n') { 52 | glblUart->send(ch); 53 | if (ch == '\r' && AdapterConfig::instance()->getBoolProperty(PAR_LINEFEED)) { 54 | glblUart->send('\n'); 55 | } 56 | } 57 | 58 | if (ch == '\r') { // Got cmd terminator 59 | CmdBuffer = cmdBuffer; 60 | cmdBuffer.resize(0); 61 | ready = true; 62 | } 63 | else if (isprint(ch)) { // this will skip '\n' as well 64 | cmdBuffer += ch; 65 | } 66 | 67 | return ready; 68 | } 69 | 70 | /** 71 | * Send string to UART 72 | * @param[in] str String to send 73 | */ 74 | void AdptSendString(const util::string& str) 75 | { 76 | glblUart->send(str); 77 | } 78 | 79 | const int UART_SPEED = 115200; 80 | 81 | /** 82 | * Adapter main loop 83 | */ 84 | static void AdapterRun() 85 | { 86 | glblUart = CmdUart::instance(); 87 | glblUart->init(UART_SPEED); 88 | glblUart->handler(UserUartRcvHandler); 89 | AdptPowerModeConfigure(); 90 | AdptDispatcherInit(); 91 | 92 | for(;;) { 93 | if (glblUart->ready()) { 94 | glblUart->ready(false); 95 | AdptOnCmd(CmdBuffer); 96 | } 97 | //__WFI(); // goto sleep 98 | } 99 | } 100 | 101 | int main(void) 102 | { 103 | SystemCoreClockUpdate(); 104 | 105 | SetAllRegisters(); 106 | AdapterRun(); 107 | } 108 | 109 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/TimerSTM32F0xx.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include "cortexm.h" 9 | #include "Timer.h" 10 | 11 | const uint16_t tickDiv = (SystemCoreClock / 1000); 12 | static TIM_TypeDef* TimerPtr[] = { TIM3, TIM14 }; 13 | 14 | /** 15 | * Configuring timers 16 | */ 17 | void Timer::configure() 18 | { 19 | // Enable timer clock 20 | RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; 21 | RCC->APB1ENR |= RCC_APB1ENR_TIM14EN; 22 | RCC->APB2ENR |= RCC_APB2ENR_TIM16EN; 23 | } 24 | 25 | /** 26 | * Construct the Timer object 27 | * @param[in] timerNum Logical timer number (0..2) 28 | */ 29 | Timer::Timer(int timerNum) 30 | { 31 | timer_ = TimerPtr[timerNum]; 32 | TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; 33 | TIM_TimeBaseStruct.TIM_Period = 0xFFFF; // Autoload register 34 | TIM_TimeBaseStruct.TIM_Prescaler = (tickDiv - 1); // Divide to 1ms 35 | TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; 36 | TIM_TimeBaseStruct.TIM_CounterMode = (TIM_CounterMode_Up | TIM_OPMode_Single); 37 | TIM_TimeBaseInit(timer_, &TIM_TimeBaseStruct); 38 | } 39 | 40 | /** 41 | * Start/restart the timer, interval <= 349 ms 42 | * @param[in] interval Timer interval in milliseconds 43 | */ 44 | void Timer::start(uint32_t interval) 45 | { 46 | timer_->ARR = interval; 47 | timer_->CNT = 0; 48 | timer_->SR = 0; // Clear the flags 49 | timer_->CR1 |= TIM_CR1_CEN; // Enable the TIMn timer 50 | } 51 | 52 | /** 53 | * Check if timer is still running 54 | * @return Timer interrupt status (false or true) 55 | */ 56 | bool Timer::isExpired() const 57 | { 58 | return (timer_->SR & TIM_FLAG_Update); 59 | } 60 | 61 | /** 62 | * Factory method to construct the Timer object 63 | * @param[in] timerNum Logical timer number (0..1) 64 | * @return Timer pointer 65 | */ 66 | Timer* Timer::instance(int timerNum) 67 | { 68 | static Timer timer0(0); 69 | static Timer timer1(1); 70 | 71 | switch (timerNum) { 72 | case Timer::TIMER0: 73 | return &timer0; 74 | 75 | case Timer::TIMER1: 76 | return &timer1; 77 | 78 | default: 79 | return 0; 80 | } 81 | } 82 | 83 | static PeriodicCallbackT irqCallback; 84 | 85 | extern "C" void TIM16_IRQHandler(void) 86 | { 87 | if (TIM16->SR & TIM_FLAG_Update) { 88 | TIM16->SR &= ~TIM_FLAG_Update; // Clear TIM16 update interrupt 89 | if (irqCallback) { 90 | (*irqCallback)(); 91 | } 92 | } 93 | } 94 | 95 | /** 96 | * Construct the PeriodicTimer instance 97 | * @param[in] callback Timer callback handler 98 | */ 99 | PeriodicTimer::PeriodicTimer(PeriodicCallbackT callback) 100 | { 101 | irqCallback = callback; 102 | 103 | TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; 104 | TIM_TimeBaseStruct.TIM_Period = 0xFFFF; // Autoload register 105 | TIM_TimeBaseStruct.TIM_Prescaler = (tickDiv - 1); // Divide to 1ms 106 | TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; 107 | TIM_TimeBaseStruct.TIM_CounterMode = (TIM_CounterMode_Up | TIM_OPMode_Repetitive); 108 | TIM_TimeBaseInit(TIM16, &TIM_TimeBaseStruct); 109 | TIM16->DIER |= TIM_IT_Update; 110 | NVIC_EnableIRQ(TIM16_IRQn); 111 | } 112 | 113 | /** 114 | * Start/restart the timer 115 | * @param[in] interval Timer interval in milliseconds 116 | */ 117 | void PeriodicTimer::start(uint32_t interval) 118 | { 119 | TIM16->ARR = interval; 120 | TIM16->CNT = 0; 121 | TIM16->SR = 0; // Clear the flags 122 | TIM16->CR1 |= TIM_CR1_CEN; // Enable the TIM16 time 123 | } 124 | 125 | /** 126 | * Stop the timer 127 | */ 128 | void PeriodicTimer::stop() 129 | { 130 | TIM16->CR1 &= ~TIM_CR1_CEN; 131 | } 132 | -------------------------------------------------------------------------------- /src/adapter/adaptertypes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #ifndef __ADAPTER_TYPES_H__ 9 | #define __ADAPTER_TYPES_H__ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | // Config settings 19 | const int OBD_IN_MSG_DLEN = 7; 20 | const int OBD_IN_MSG_LEN = OBD_IN_MSG_DLEN + 5; // 7 data + 4 header + 1 reserved 21 | const int RX_BUFFER_LEN = 100; 22 | const int RX_CMD_LEN = 20; // The incoming cmd 23 | const int USER_BUF_LEN = RX_CMD_LEN; // The previous cmd 24 | 25 | // 26 | // Command dispatch values 27 | // 28 | const int INT_PROPS_START = 100; 29 | const int BYTES_PROPS_START = 1000; 30 | 31 | enum AT_Requests { 32 | // bool properties 33 | PAR_BUFFER_DUMP = 0, 34 | PAR_CALIBRATE_VOLT, 35 | PAR_CAN_CAF, 36 | PAR_CAN_DLC, 37 | PAR_CAN_MONITORING, 38 | PAR_CHIP_COPYRIGHT, 39 | PAR_DESCRIBE_PROTCL_N, 40 | PAR_DESCRIBE_PROTOCOL, 41 | PAR_ECHO, 42 | PAR_GET_SERIAL, 43 | PAR_HEADER_SHOW, 44 | PAR_INFO, 45 | PAR_J1939_FMT, 46 | PAR_J1939_HEADER, 47 | PAR_J1939_MLTPR5, 48 | PAR_LINEFEED, 49 | PAR_MEMORY, 50 | PAR_PROTOCOL_CLOSE, 51 | PAR_READ_VOLT, 52 | PAR_RESET_CPU, 53 | PAR_RESPONSES, 54 | PAR_SET_DEFAULT, 55 | PAR_PROTOCOL, 56 | PAR_SERIAL, 57 | PAR_SPACES, 58 | PAR_TRY_PROTOCOL, 59 | PAR_VERSION, 60 | PAR_WARMSTART, 61 | PAR_WIRING_TEST, 62 | PAR_USE_AUTO_SP, 63 | PAR_ADPTV_TIM0, 64 | PAR_ADPTV_TIM1, 65 | PAR_ADPTV_TIM2, 66 | PAR_CAN_SHOW_STATUS, 67 | PAR_J1939_DM1_MONITOR, 68 | PAR_LOW_POWER_MODE, 69 | PAR_CAN_SEND_RTR, 70 | PAR_CAN_VAIDATE_DLC, 71 | PAR_J1939_MONITOR, 72 | // int properties 73 | PAR_CAN_CF = INT_PROPS_START, 74 | PAR_CAN_CM, 75 | PAR_CAN_CP, 76 | PAR_CAN_EXT, 77 | PAR_CAN_SET_ADDRESS, 78 | PAR_CAN_FLOW_CONTROL, 79 | PAR_CAN_FLOW_CTRL_HDR, 80 | PAR_TESTER_ADDRESS, 81 | PAR_TRY_BRD, 82 | PAR_SET_BRD, 83 | PAR_TIMEOUT, 84 | PAR_WAKEUP_VAL, 85 | // bytes properties 86 | PAR_HEADER_BYTES = BYTES_PROPS_START, 87 | PAR_CAN_FLOW_CTRL_DAT, 88 | PAR_WM_HEADER 89 | }; 90 | 91 | struct ByteArray { 92 | const static int ARRAY_SIZE = 7; 93 | ByteArray() : length(0) { 94 | memset(data, 0, sizeof(data)); 95 | } 96 | uint8_t data[ARRAY_SIZE]; 97 | uint8_t length; 98 | }; 99 | 100 | // Configuration settings 101 | // 102 | class AdapterConfig { 103 | public: 104 | static AdapterConfig* instance(); 105 | void setBoolProperty(int parameter, bool val); 106 | bool getBoolProperty(int parameter) const; 107 | void setIntProperty(int parameter, uint32_t val); 108 | uint32_t getIntProperty(int parameter) const; 109 | void setBytesProperty(int parameter, const ByteArray* bytes); 110 | const ByteArray* getBytesProperty(int parameter) const; 111 | private: 112 | const static int BYTE_PROP_LEN = 10; 113 | const static int INT_PROP_LEN = 10; 114 | const static int BYTES_PROP_LEN = 10; 115 | 116 | AdapterConfig(); 117 | uint64_t values_; 118 | uint8_t byteProps_ [BYTE_PROP_LEN]; 119 | uint32_t intProps_ [INT_PROP_LEN]; 120 | ByteArray bytesProps_[BYTES_PROP_LEN]; 121 | }; 122 | 123 | union NumericType 124 | { 125 | uint32_t lvalue; 126 | uint8_t bvalue[4]; 127 | NumericType() { lvalue = 0; } 128 | NumericType(uint32_t val) { lvalue = val; } 129 | NumericType(uint8_t b0, uint8_t b1, uint8_t b2 = 0, uint8_t b3 = 0) { 130 | bvalue[0] = b0; 131 | bvalue[1] = b1; 132 | bvalue[2] = b2; 133 | bvalue[3] = b3; 134 | } 135 | }; 136 | 137 | void AdptSendString(const util::string& str); 138 | void AdptSendReply(const util::string& str); 139 | void AdptDispatcherInit(); 140 | void AdptOnCmd(util::string& cmdString); 141 | void AdptReadSerialNum(); 142 | void AdptPowerModeConfigure(); 143 | 144 | // Utilities 145 | void Delay1ms(uint32_t value); 146 | void Delay1us(uint32_t value); 147 | void CanIDToString(uint32_t num, util::string& str, bool extended) 148 | ; 149 | 150 | uint32_t to_bytes(const util::string& str, uint8_t* bytes); 151 | void to_ascii(const uint8_t* bytes, uint32_t length, util::string& str); 152 | 153 | // LEDs 154 | #define TX_LED(val) GPIOPinWrite(TX_LED_PORT, TX_LED_NUM, val) 155 | #define RX_LED(val) GPIOPinWrite(RX_LED_PORT, RX_LED_NUM, val) 156 | 157 | #endif //__ADAPTER_TYPES_H__ 158 | -------------------------------------------------------------------------------- /src/adapter/functions.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | using namespace util; 16 | 17 | /** 18 | * Do Binary/ASCII conversion for CAN identifier 19 | * @param[in] num The number to convert 20 | * @param[out] str The output string 21 | * @param[in] extended CAN 29 bit flag 22 | */ 23 | void CanIDToString(uint32_t num, string& str, bool extended) 24 | { 25 | NumericType value(num); 26 | 27 | if (!extended) { // 11 bit standard CAN identifier 28 | str += to_ascii(value.bvalue[1] & 0x0F); 29 | str += to_ascii(value.bvalue[0] >> 4); 30 | str += to_ascii(value.bvalue[0] & 0x0F); 31 | } 32 | else { // 29 bit extended CAN identifier 33 | str += to_ascii(value.bvalue[3] >> 4); 34 | str += to_ascii(value.bvalue[3] & 0x0F); 35 | //if (Settings.useSpaces) 36 | // str += ' '; 37 | str += to_ascii(value.bvalue[2] >> 4); 38 | str += to_ascii(value.bvalue[2] & 0x0F); 39 | //if (Settings.useSpaces) 40 | // str += ' '; 41 | str += to_ascii(value.bvalue[1] >> 4); 42 | str += to_ascii(value.bvalue[1] & 0x0F); 43 | //if (Settings.useSpaces) 44 | // str += ' '; 45 | str += to_ascii(value.bvalue[0] >> 4); 46 | str += to_ascii(value.bvalue[0] & 0x0F); 47 | } 48 | } 49 | 50 | /** 51 | * Delay for number of milliseconds using SysTick timer 52 | * @param[in] value The number of millisecond to delay 53 | */ 54 | void Delay1ms(uint32_t value) 55 | { 56 | if (value == 0) return; 57 | 58 | // Use the SysTick to generate the timeout in msecs 59 | SysTick->LOAD = value * (SystemCoreClock / 1000); 60 | SysTick->VAL = 0; 61 | SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; 62 | 63 | while (!(SysTick->CTRL & 0x10000)) { 64 | ; 65 | } 66 | } 67 | 68 | /** 69 | * Delay for number of microseconds using SysTick timer 70 | * @param[in] value The number of microseconds to delay 71 | */ 72 | void Delay1us(uint32_t value) 73 | { 74 | const uint32_t AdjustValue = 50; 75 | // Use the SysTick to generate the timeout in us 76 | SysTick->LOAD = value * (SystemCoreClock / 1000000) - AdjustValue; 77 | SysTick->VAL = 0; 78 | SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; 79 | 80 | while (!(SysTick->CTRL & 0x10000)) { 81 | ; 82 | } 83 | } 84 | 85 | /** 86 | * Binary/ASCII ISO 9141/14230 key words conversion 87 | * @param[in] kw Keyword byte to convert 88 | * @param[out] str The output string 89 | */ 90 | void KWordsToString(const uint8_t* kw, string& str) 91 | { 92 | const char pattern[] = "1:-- 2:--"; 93 | str = pattern; 94 | if (kw[0]) { 95 | str[2] = to_ascii(kw[0] >> 4); 96 | str[3] = to_ascii(kw[0] & 0x0F); 97 | str[7] = to_ascii(kw[1] >> 4); 98 | str[8] = to_ascii(kw[1] & 0x0F); 99 | } 100 | } 101 | 102 | /** 103 | * Generic string to binary conversion function. 104 | * @param[in] str String to convert 105 | * @param[out] bytes The result as sequence of bytes 106 | * @return The length of output 107 | **/ 108 | uint32_t to_bytes(const string& str, uint8_t* bytes) 109 | { 110 | int len = str.length(); 111 | 112 | if ((len % 2) != 0) 113 | return 0; 114 | 115 | int j = 0; 116 | for (int i = 0; i < len / 2; i++) { 117 | uint32_t hexValue = stoul(str.substr(j, 2), 0, 16); 118 | if (hexValue == ULONG_MAX) 119 | return 0; 120 | bytes[i] = hexValue; 121 | j += 2; 122 | } 123 | return len / 2; 124 | } 125 | 126 | 127 | /** 128 | * Generic binary to string conversion function. 129 | * @param[in] bytes The byte array to convert 130 | * @param[in] length The buffer length 131 | * @param[out] str The output string 132 | **/ 133 | void to_ascii(const uint8_t* bytes, uint32_t length, string& str) 134 | { 135 | bool useSpaces = AdapterConfig::instance()->getBoolProperty(PAR_SPACES); 136 | for (int i = 0; i < length; i++) { 137 | str += to_ascii(bytes[i] >> 4); 138 | str += to_ascii(bytes[i] & 0x0F); 139 | if (useSpaces) { 140 | str += ' '; 141 | } 142 | } 143 | if (useSpaces && str.length() > 0) { 144 | str.resize(str.length() - 1); // Truncate the last space 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/UartSTM32F0xx.h: -------------------------------------------------------------------------------- 1 | #ifndef __UART_LPC15xx_H__ 2 | #define __UART_LPC15xx_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | /** 11 | * UART CFG register definitions 12 | */ 13 | const uint32_t UART_CFG_ENABLE (0x01 << 0); 14 | const uint32_t UART_CFG_DATALEN_7 (0x00 << 2); // UART 7 bit length mode 15 | const uint32_t UART_CFG_DATALEN_8 (0x01 << 2); // UART 8 bit length mode 16 | const uint32_t UART_CFG_DATALEN_9 (0x02 << 2); // UART 9 bit length mode 17 | const uint32_t UART_CFG_PARITY_NONE (0x00 << 4); // No parity 18 | const uint32_t UART_CFG_PARITY_EVEN (0x02 << 4); // Even parity 19 | const uint32_t UART_CFG_PARITY_ODD (0x03 << 4); // Odd parity 20 | const uint32_t UART_CFG_STOPLEN_1 (0x00 << 6); // UART One Stop Bit Select 21 | const uint32_t UART_CFG_STOPLEN_2 (0x01 << 6); // UART Two Stop Bits Select 22 | const uint32_t UART_MODE_32K (0x01 << 7); // Selects the 32 kHz clock from the RTC oscillator as the clock source to the BRG 23 | const uint32_t UART_CFG_CTSEN (0x01 << 9); // CTS enable bit 24 | const uint32_t UART_CFG_SYNCEN (0x01 << 11); // Synchronous mode enable bit 25 | const uint32_t UART_CFG_CLKPOL (0x01 << 12); // Un_RXD rising edge sample enable bit 26 | const uint32_t UART_CFG_SYNCMST (0x01 << 14); // Select master mode (synchronous mode) enable bit 27 | const uint32_t UART_CFG_LOOP (0x01 << 15); // Loopback mode enable bit 28 | 29 | /** 30 | * UART STAT register definitions 31 | */ 32 | const uint32_t UART_STAT_RXRDY = (0x01 << 0); // Receiver ready 33 | const uint32_t UART_STAT_RXIDLE = (0x01 << 1); // Receiver idle 34 | const uint32_t UART_STAT_TXRDY = (0x01 << 2); // Transmitter ready for data 35 | const uint32_t UART_STAT_TXIDLE = (0x01 << 3); // Transmitter idle 36 | const uint32_t UART_STAT_CTS = (0x01 << 4); // Status of CTS signal 37 | const uint32_t UART_STAT_DELTACTS = (0x01 << 5); // Change in CTS state 38 | const uint32_t UART_STAT_TXDISINT = (0x01 << 6); // Transmitter disabled 39 | const uint32_t UART_STAT_OVERRUNINT = (0x01 << 8); // Overrun Error interrupt flag 40 | const uint32_t UART_STAT_RXBRK = (0x01 << 10); // Received break 41 | const uint32_t UART_STAT_DELTARXBRK = (0x01 << 11); // Change in receive break detection 42 | const uint32_t UART_STAT_START = (0x01 << 12); // Start detected 43 | const uint32_t UART_STAT_FRM_ERRINT = (0x01 << 13); // Framing Error interrupt flag 44 | const uint32_t UART_STAT_PAR_ERRINT = (0x01 << 14); // Parity Error interrupt flag 45 | const uint32_t UART_STAT_RXNOISEINT = (0x01 << 15); // Received Noise interrupt flag 46 | 47 | /** 48 | * UART INTENSET/INTENCLR register definitions 49 | */ 50 | const uint32_t UART_INTEN_RXRDY = (0x01 << 0); // Receive Ready interrupt 51 | const uint32_t UART_INTEN_TXRDY = (0x01 << 2); // Transmit Ready interrupt 52 | const uint32_t UART_INTEN_DELTACTS = (0x01 << 5); // Change in CTS state interrupt 53 | const uint32_t UART_INTEN_TXDIS = (0x01 << 6); // Transmitter disable interrupt 54 | const uint32_t UART_INTEN_OVERRUN = (0x01 << 8); // Overrun error interrupt 55 | const uint32_t UART_INTEN_DELTARXBRK = (0x01 << 11); // Change in receiver break detection interrupt 56 | const uint32_t UART_INTEN_START = (0x01 << 12); // Start detect interrupt 57 | const uint32_t UART_INTEN_FRAMERR = (0x01 << 13); // Frame error interrupt 58 | const uint32_t UART_INTEN_PARITYERR = (0x01 << 14); // Parity error interrupt 59 | const uint32_t UART_INTEN_RXNOISE = (0x01 << 15); // Received noise interrupt 60 | 61 | 62 | inline void UARTIntEnable(LPC_USART0_Type *pUART, uint32_t intMask) 63 | { 64 | pUART->INTENSET = intMask; 65 | } 66 | 67 | inline void UARTIntDisable(LPC_USART0_Type *pUART, uint32_t intMask) 68 | { 69 | pUART->INTENCLR = intMask; 70 | } 71 | 72 | inline uint32_t UARTGetStatus(LPC_USART0_Type *pUART) 73 | { 74 | return pUART->STAT; 75 | } 76 | 77 | inline uint32_t UARTGetIntStatus(LPC_USART0_Type *pUART) 78 | { 79 | return pUART->INTSTAT; 80 | } 81 | 82 | inline uint32_t UARTGetIntsEnabled(LPC_USART0_Type *pUART) 83 | { 84 | return pUART->INTENSET; 85 | } 86 | 87 | inline void UARTSendByte(LPC_USART0_Type *pUART, uint8_t data) 88 | { 89 | pUART->TXDATA = (uint32_t) data; 90 | } 91 | 92 | inline uint8_t UARTReadByte(LPC_USART0_Type *pUART) 93 | { 94 | return pUART->RXDATA & 0xFF; 95 | } 96 | 97 | inline void UART_Enable(LPC_USART0_Type *pUART) 98 | { 99 | pUART->CFG |= UART_CFG_ENABLE; 100 | } 101 | 102 | /** 103 | * Disable the UART 104 | * @param[in] pUART pointer to selected UARTx peripheral 105 | */ 106 | inline void UART_Disable(LPC_USART0_Type *pUART) 107 | { 108 | pUART->CFG &= ~UART_CFG_ENABLE; 109 | } 110 | 111 | #endif //__UART_LPC15xx_H__ 112 | 113 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/CmdUartSTM32F0xx.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include "cortexm.h" 10 | #include "GPIODrv.h" 11 | #include "CmdUart.h" 12 | 13 | using namespace std; 14 | 15 | const int TxPin = 9; 16 | const int RxPin = 10; 17 | const int USER_AF = GPIO_AF_1; 18 | #define RxPort GPIOA 19 | #define TxPort GPIOA 20 | 21 | 22 | /** 23 | * Constructor 24 | */ 25 | CmdUart::CmdUart() 26 | : txLen_(0), 27 | txPos_(0), 28 | ready_(false), 29 | handler_(0) 30 | { 31 | } 32 | 33 | /** 34 | * CmdUart singleton 35 | */ 36 | CmdUart* CmdUart::instance() 37 | { 38 | static CmdUart instance; 39 | return &instance;; 40 | } 41 | 42 | /** 43 | * Configure UART0 44 | */ 45 | void CmdUart::configure() 46 | { 47 | // Enable the peripheral clock of GPIOA 48 | RCC->AHBENR |= RCC_AHBENR_GPIOAEN; 49 | 50 | // Enable the peripheral clock USART1 51 | RCC->APB2ENR |= RCC_APB2ENR_USART1EN; 52 | 53 | // GPIO configuration for USART1 signals 54 | // Select AF mode on PA9 and PA10 55 | GPIO_InitTypeDef GPIO_InitStruct; 56 | GPIO_InitStruct.GPIO_Pin = (1 << TxPin) | (1 << RxPin); 57 | GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; 58 | GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 59 | GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; 60 | GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; 61 | GPIO_Init(GPIOA, &GPIO_InitStruct); 62 | 63 | // Connect PA9 to USART1_Tx, PA10 to USART1_Rx, use alternate function AF1, p165 64 | GPIO_PinAFConfig(TxPort, TxPin, USER_AF); 65 | GPIO_PinAFConfig(RxPort, RxPin, USER_AF); 66 | } 67 | 68 | /** 69 | * Use UART ROM API to configuring speed and interrupt for UART0, 70 | * discard the allocated UART memory block afterwards 71 | * @parameter[in] speed Speed to configure 72 | */ 73 | void CmdUart::init(uint32_t speed) 74 | { 75 | USART_InitTypeDef USART_InitStruct; 76 | USART_InitStruct.USART_BaudRate = 115200; 77 | USART_InitStruct.USART_WordLength = USART_WordLength_8b; 78 | USART_InitStruct.USART_StopBits = USART_StopBits_1; 79 | USART_InitStruct.USART_Parity = USART_Parity_No; 80 | USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 81 | USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 82 | USART_Init(USART1, &USART_InitStruct); 83 | 84 | // Enable USART 85 | USART1->CR1 |= USART_CR1_UE; 86 | 87 | // Enable the USART Receive interrupt 88 | USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 89 | 90 | // Clear TC flag 91 | USART1->ICR |= USART_ICR_TCCF; 92 | 93 | NVIC_SetPriority(USART1_IRQn, 2); 94 | NVIC_EnableIRQ(USART1_IRQn); 95 | } 96 | 97 | /** 98 | * CmdUart TX handler 99 | */ 100 | void CmdUart::txIrqHandler() 101 | { 102 | // Fill TX until full or until TX buffer is empty 103 | if (txPos_ < txLen_) { 104 | if (USART1->ISR & USART_FLAG_TXE) { 105 | USART1->TDR = txData_[txPos_++]; 106 | } 107 | } 108 | else { 109 | USART1->ICR |= USART_ICR_TCCF; 110 | USART_ITConfig(USART1, USART_IT_TC, DISABLE); 111 | } 112 | } 113 | 114 | /** 115 | * CmdUart RX handler 116 | */ 117 | void CmdUart::rxIrqHandler() 118 | { 119 | // Receive data, clear flag 120 | uint8_t ch = USART1->RDR; 121 | if (handler_) 122 | ready_ = (*handler_)(ch); 123 | } 124 | 125 | /** 126 | * CmdUart IRQ handler 127 | */ 128 | void CmdUart::irqHandler() 129 | { 130 | // If overrun condition occurs, clear the ORE flag and recover communication 131 | if (USART1->ISR & USART_ISR_ORE) { 132 | USART1->ICR |= USART_ICR_ORECF; 133 | } 134 | 135 | if(USART1->ISR & USART_ISR_TC) { 136 | txIrqHandler(); 137 | } 138 | if (USART1->ISR & USART_ISR_RXNE) { 139 | rxIrqHandler(); 140 | } 141 | } 142 | 143 | /** 144 | * Send one character, blocking call for echo purposes 145 | * Note: Do not have USART FIFO in STM32F37x, always have to 146 | * check the TXE status before sending byte 147 | * @parameter[in] ch Character to send 148 | */ 149 | void CmdUart::send(uint8_t ch) 150 | { 151 | while ((USART1->ISR & USART_FLAG_TXE) == 0) 152 | ; 153 | USART1->TDR = ch; 154 | } 155 | 156 | /** 157 | * Send the string asynch 158 | * @parameter[in] str String to send 159 | */ 160 | void CmdUart::send(const util::string& str) 161 | { 162 | // wait for TX interrupt disabled when the previous transmission completed 163 | while (USART1->CR1 & USART_CR1_TCIE) { 164 | ; 165 | } 166 | 167 | // start the new transmission 168 | txPos_ = 0; 169 | txLen_ = str.length(); 170 | memcpy(txData_, str.c_str(), txLen_); 171 | if (txLen_ > 0) { 172 | // Initialize the transfer && Enable the USART Transmit complete interrupt 173 | USART_ITConfig(USART1, USART_IT_TC, ENABLE); 174 | send(txData_[txPos_++]); 175 | //USART1->TDR = txData_[txPos_++]; 176 | } 177 | } 178 | 179 | /** 180 | * UART1 IRQ Handler, redirect to irqHandler 181 | */ 182 | extern "C" void USART1_IRQHandler(void) 183 | { 184 | if (CmdUart::instance()) 185 | CmdUart::instance()->irqHandler(); 186 | } 187 | -------------------------------------------------------------------------------- /src/util/lstring.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "lstring.h" 14 | 15 | #ifdef LSTRING_VALIDATE 16 | #define VALIDATE(size) validate(size) 17 | #else 18 | #define VALIDATE(size) 19 | #endif 20 | 21 | using namespace std; 22 | 23 | namespace util { 24 | 25 | void string::init(uint32_t size) 26 | { 27 | allocatedLength_ = size > STRING_SIZE ? size : STRING_SIZE; 28 | allocatedLength_++; 29 | data_ = new char[allocatedLength_]; // Including null terminator 30 | } 31 | 32 | string::string(uint32_t size) 33 | { 34 | init(size); 35 | data_[0] = 0; 36 | length_ = 0; 37 | } 38 | 39 | // 40 | // Validate the string memory overrun, throws exception 41 | // 42 | #ifdef LSTRING_VALIDATE 43 | void string::validate(uint32_t size) 44 | { 45 | if (size >= allocatedLength_) { 46 | abort(); 47 | } 48 | } 49 | #endif 50 | 51 | string::string(const char* s) 52 | { 53 | length_ = strlen(s); 54 | init(length_); 55 | strcpy(data_, s); 56 | } 57 | 58 | string::string(const string& str) 59 | { 60 | length_ = str.length_; 61 | init(length_); 62 | strcpy(data_, str.data_); 63 | } 64 | 65 | string::string(uint32_t count, char ch) 66 | { 67 | length_ = count; 68 | init(length_); 69 | memset(data_, ch, length_); 70 | data_[length_] = 0; 71 | } 72 | 73 | string::~string() 74 | { 75 | delete[] data_; 76 | } 77 | 78 | void string::resize(uint32_t count) 79 | { 80 | if (count < length_) { 81 | length_ = count; 82 | data_[length_] = 0; 83 | } 84 | else { 85 | ; // nothing 86 | } 87 | } 88 | 89 | void string::resize(uint32_t count, char ch) 90 | { 91 | if (count < length_) { 92 | length_ = count; 93 | data_[length_] = 0; 94 | } 95 | else if (count > length_) { 96 | VALIDATE(count); 97 | memset(data_ + length_, ch, count - length_); 98 | length_ = count; 99 | data_[length_] = 0; 100 | } 101 | } 102 | 103 | string& string::append(const char* s) 104 | { 105 | int len = strlen(s); 106 | VALIDATE(length_ + len); 107 | strcpy(data_ + length_, s); 108 | length_ += len; 109 | return *this; 110 | } 111 | 112 | string& string::append(const char* s, uint32_t count) 113 | { 114 | VALIDATE(length_ + count); 115 | memcpy(data_ + length_, s, count); 116 | length_ += count; 117 | data_[length_] = 0; 118 | return *this; 119 | } 120 | 121 | string& string::append(uint32_t count, char ch) 122 | { 123 | VALIDATE(length_ + count); 124 | for (uint32_t i = 0; i < count; i++) { 125 | (*this) += ch; 126 | } 127 | return *this; 128 | } 129 | 130 | string& string::assign(uint32_t count, char ch) 131 | { 132 | length_ = count; 133 | VALIDATE(length_ + count); 134 | memset(data_, ch, count); 135 | data_[count] = 0; 136 | return *this; 137 | } 138 | 139 | string& string::operator+=(const string& str) 140 | { 141 | return append(str.data_, str.length_); 142 | } 143 | 144 | string& string::operator+=(const char* s) 145 | { 146 | return append(s); 147 | } 148 | 149 | string& string::operator+=(char ch) 150 | { 151 | VALIDATE(length_ + 1); 152 | data_[length_] = ch; 153 | data_[++length_] = 0; 154 | return *this; 155 | } 156 | 157 | uint32_t string::find(const string& str, uint32_t pos) const 158 | { 159 | const char* p = strstr(data_ + pos, str.data_); 160 | return p ? (p - data_) : npos; 161 | } 162 | 163 | uint32_t string::find(char ch, uint32_t pos) const 164 | { 165 | const char* p = strchr(data_ + pos, ch); 166 | return p ? (p - data_) : npos; 167 | } 168 | 169 | string string::substr(uint32_t pos, uint32_t count) const 170 | { 171 | uint32_t p = (pos >= length_) ? 0 : pos; // should be an exception 172 | uint32_t l = (length_ < count) ? (length_ - p) : count; 173 | string s(l + 1); 174 | s.append(data_ + p, l); 175 | return s; 176 | } 177 | 178 | string& string::operator=(const string& str) 179 | { 180 | VALIDATE(str.length_); 181 | memcpy(data_, str.data_, str.length_ + 1); // including null terminator 182 | length_ = str.length_; 183 | return *this; 184 | } 185 | 186 | string& string::operator=(const char* s) 187 | { 188 | length_ = strlen(s); 189 | VALIDATE(length_); 190 | strcpy(data_, s); 191 | return *this; 192 | } 193 | void string::clear() 194 | { 195 | length_ = 0; 196 | data_[0] = 0; 197 | } 198 | 199 | uint32_t string::copy(char* dest, uint32_t count, uint32_t pos) const 200 | { 201 | memcpy(dest, data_ + pos, count); 202 | return count; 203 | } 204 | 205 | bool operator==(const string& lhs, const char* rhs) 206 | { 207 | return (strcmp(lhs.c_str(), rhs) == 0); 208 | } 209 | 210 | bool operator!=(const string& lhs, const char* rhs) 211 | { 212 | return (strcmp(lhs.c_str(), rhs) != 0); 213 | } 214 | 215 | bool operator==(const string& lhs, const string& rhs) 216 | { 217 | return (strcmp(lhs.c_str(), rhs.c_str()) == 0); 218 | } 219 | 220 | string operator+(const string& lhs, const string& rhs) 221 | { 222 | string s(lhs); 223 | s += rhs; 224 | return s; 225 | } 226 | 227 | string operator+(const char* lhs, const string& rhs) 228 | { 229 | int len = strlen(lhs) + rhs.length(); 230 | string s(len + 1); 231 | s += lhs; 232 | s += rhs; 233 | return s; 234 | } 235 | 236 | string operator+(char ch, const string& rhs) 237 | { 238 | int len = rhs.length() + 1; 239 | string s(len + 1); 240 | s += ch; 241 | s += rhs; 242 | return s; 243 | } 244 | 245 | string operator+(const string& lhs, const char* rhs) 246 | { 247 | int len = lhs.length() + strlen(rhs); 248 | string s(len + 1); 249 | s += lhs; 250 | s += rhs; 251 | return s; 252 | } 253 | 254 | string operator+(const string& lhs, char ch) 255 | { 256 | int len = lhs.length() + 1; 257 | string s(len + 1); 258 | s += lhs; 259 | s += ch; 260 | return s; 261 | } 262 | 263 | } // end util namespace 264 | -------------------------------------------------------------------------------- /src/adapter/obd/obdprofile.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include "obdprofile.h" 9 | 10 | using namespace util; 11 | 12 | // 13 | // Reply error string constants 14 | // 15 | static const char ErrMessage [] = "?"; 16 | static const char Err1Message[] = "DATA ERROR"; // Bad ECU response 17 | static const char Err2Message[] = "NO DATA"; // No response 18 | static const char Err3Message[] = "ERROR"; // Got response but invalid 19 | static const char Err4Message[] = "UNABLE TO CONNECT"; // All attempts to connect failed (for auto connect) 20 | static const char Err5Message[] = "FB ERROR"; // Wiring 21 | static const char Err6Message[] = "BUS BUSY"; // Bus collision or busy 22 | static const char Err7Message[] = "BUS ERROR"; // Bus error 23 | static const char Err8Message[] = "DATA ERROR>"; // Checksum 24 | static const char Err0Message[] = "Program Error"; // Wrong coding? 25 | 26 | 27 | /** 28 | * Instance accessor 29 | * @return The OBDProfile instace pointer 30 | **/ 31 | OBDProfile* OBDProfile::instance() 32 | { 33 | static OBDProfile obdProfile; 34 | return &obdProfile; 35 | } 36 | /** 37 | * Construct OBDProfile object 38 | */ 39 | OBDProfile::OBDProfile() 40 | { 41 | adapter_ = ProtocolAdapter::getAdapter(ADPTR_AUTO); 42 | } 43 | 44 | /** 45 | * Proxies.... 46 | */ 47 | void OBDProfile::getProtocolDescription() const 48 | { 49 | adapter_->getDescription(); 50 | } 51 | 52 | void OBDProfile::getProtocolDescriptionNum() const 53 | { 54 | adapter_->getDescriptionNum(); 55 | } 56 | 57 | void OBDProfile::dumpBuffer() 58 | { 59 | adapter_->dumpBuffer(); 60 | } 61 | 62 | /** 63 | * Set the protocol number 64 | * @param[in] num The protocol number 65 | * @param[in] refreshConnection The flag 66 | * @return The completion status 67 | */ 68 | int OBDProfile::setProtocol(int num, bool refreshConnection) 69 | { 70 | ProtocolAdapter* pvadapter = adapter_; 71 | switch (num) { 72 | case PROT_AUTO: 73 | adapter_ = ProtocolAdapter::getAdapter(ADPTR_AUTO); 74 | break; 75 | case PROT_ISO15765_1150: 76 | adapter_ = ProtocolAdapter::getAdapter(ADPTR_CAN); 77 | break; 78 | case PROT_ISO15765_2950: 79 | adapter_ = ProtocolAdapter::getAdapter(ADPTR_CAN_EXT); 80 | break; 81 | default: 82 | return REPLY_CMD_WRONG; 83 | } 84 | // Do this if only "ATSP" executed 85 | if (refreshConnection) { 86 | if (pvadapter != adapter_) { 87 | pvadapter->close(); 88 | adapter_->open(); 89 | } 90 | } 91 | return REPLY_OK; 92 | } 93 | 94 | /** 95 | * The entry for ECU send/receive function 96 | * @param[in] cmdString The command 97 | * @return The status code 98 | */ 99 | void OBDProfile::onRequest(const string& cmdString) 100 | { 101 | int result = onRequestImpl(cmdString); 102 | switch(result) { 103 | case REPLY_CMD_WRONG: 104 | AdptSendReply(ErrMessage); 105 | break; 106 | case REPLY_DATA_ERROR: 107 | AdptSendReply(Err1Message); 108 | break; 109 | case REPLY_NO_DATA: 110 | AdptSendReply(Err2Message); 111 | break; 112 | case REPLY_ERROR: 113 | AdptSendReply(Err3Message); 114 | break; 115 | case REPLY_UNBL_2_CNNCT: 116 | AdptSendReply(Err4Message); 117 | break; 118 | case REPLY_BUS_BUSY: 119 | AdptSendReply(Err6Message); 120 | break; 121 | case REPLY_BUS_ERROR: 122 | AdptSendReply(Err7Message); 123 | break; 124 | case REPLY_CHKS_ERROR: 125 | AdptSendReply(Err8Message); 126 | break; 127 | case REPLY_WIRING_ERROR: 128 | AdptSendReply(Err5Message); 129 | break; 130 | case REPLY_NONE: 131 | break; 132 | default: 133 | AdptSendReply(Err0Message); 134 | break; 135 | } 136 | } 137 | 138 | /** 139 | * The actual implementation of request handler 140 | * @param[in] cmdString The command 141 | * @return The status code 142 | */ 143 | int OBDProfile::onRequestImpl(const string& cmdString) 144 | { 145 | const char* OBD_TEST_SEQ = "0100"; 146 | uint8_t data[OBD_IN_MSG_LEN]; 147 | 148 | // Buffer overrun check, 149 | // should be less then (11 * 2) => 22 characters 150 | if (cmdString.length() > (sizeof(data) * 2)) { 151 | return REPLY_CMD_WRONG; 152 | } 153 | 154 | int len = to_bytes(cmdString, data); 155 | 156 | // Valid request length? 157 | if (!sendLengthCheck(data, len)) { 158 | return REPLY_DATA_ERROR; 159 | } 160 | 161 | // The regular flow stops here 162 | if (adapter_->isConnected()) { 163 | return adapter_->onRequest(data, len); 164 | } 165 | 166 | // The convoluted logic 167 | // 168 | bool sendReply = (cmdString == OBD_TEST_SEQ); 169 | 170 | int protocol = 0; 171 | int sts = REPLY_NO_DATA; 172 | ProtocolAdapter* autoAdapter = ProtocolAdapter::getAdapter(ADPTR_AUTO); 173 | if (adapter_ == autoAdapter) { 174 | protocol = autoAdapter->onConnectEcu(sendReply); 175 | } 176 | else { 177 | protocol = adapter_->onConnectEcu(sendReply); 178 | bool useAutoSP = AdapterConfig::instance()->getBoolProperty(PAR_USE_AUTO_SP); 179 | if (protocol == 0 && useAutoSP) { 180 | protocol = autoAdapter->onConnectEcu(sendReply); 181 | } 182 | } 183 | if (protocol) { 184 | setProtocol(protocol, false); 185 | if (!sendReply) { 186 | sts = adapter_->onRequest(data, len); 187 | } 188 | else { 189 | sts = REPLY_NONE; //the command sent already as part of autoconnect 190 | } 191 | } 192 | return sts; 193 | } 194 | 195 | /** 196 | * Check the maximum length for OBD request 197 | * @param[in] msg The request bytes 198 | * @param[in] len The request length 199 | * @return true if set, false otherwise 200 | */ 201 | bool OBDProfile::sendLengthCheck(const uint8_t* msg, int len) 202 | { 203 | int maxLen = OBD_IN_MSG_DLEN; 204 | 205 | if ((len == 0) ||len > maxLen) { 206 | return false; 207 | } 208 | return true; 209 | } 210 | 211 | int OBDProfile::getProtocol() const 212 | { 213 | return adapter_->getProtocol(); 214 | } 215 | 216 | void OBDProfile::closeProtocol() 217 | { 218 | adapter_->closeProtocol(); 219 | } 220 | 221 | /** 222 | * Test wiring connectivity for all protocols 223 | */ 224 | void OBDProfile::wiringCheck() 225 | { 226 | ProtocolAdapter::getAdapter(ADPTR_CAN)->wiringCheck(); 227 | } 228 | 229 | /** 230 | * Constructs ProtocolAdapter 231 | */ 232 | ProtocolAdapter::ProtocolAdapter() 233 | { 234 | connected_ = false; 235 | config_ = AdapterConfig::instance(); 236 | } 237 | -------------------------------------------------------------------------------- /src/drv/stm32f0xx/CanDriverSTM32F0xx.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include "cortexm.h" 12 | #include "CanDriver.h" 13 | #include "GPIODrv.h" 14 | #include 15 | #include 16 | 17 | using namespace std; 18 | 19 | // The adapter specifics 20 | const int CanTxPin = 12; 21 | const int CanRxPin = 11; 22 | const int CanRxPort = 0; 23 | const int CanTxPort = 0; 24 | const int CAN_AF = GPIO_AF_4; 25 | 26 | const int CAN_PRESCALER = 6 ; // For bus clock 48Mhz 27 | const uint32_t FMR_FINIT = 0x00000001; 28 | const uint32_t MCR_DBF = 0x00010000; 29 | static GPIO_TypeDef* const GPIOPtr[] = { GPIOA, GPIOB, GPIOC }; 30 | 31 | 32 | // FIFO stuff 33 | const int FIFO_NUM = 10; 34 | static CanRxMsg RxFifo[FIFO_NUM]; 35 | static volatile uint32_t RxFifoFlag; 36 | static volatile uint32_t FifoReadPos; 37 | static volatile uint32_t FifoWritePos; 38 | 39 | 40 | extern "C" void CEC_CAN_IRQHandler(void) 41 | { 42 | // Blink LED from here, when RX operation is completed 43 | AdptLED::instance()->blinkRx(); 44 | 45 | CanRxMsg* msg = &RxFifo[FifoWritePos]; 46 | CAN_Receive(CAN, CAN_FIFO0, msg); 47 | 48 | // Advance the FIFO next writing position 49 | uint32_t mask = 0x1 << FifoWritePos; 50 | RxFifoFlag |= mask; 51 | FifoWritePos = (FifoWritePos == FIFO_NUM-1) ? 0 : FifoWritePos + 1; 52 | } 53 | 54 | /** 55 | * Configure I/O pins as CAN driver 56 | */ 57 | static void configureCANPins() 58 | { 59 | GPIO_InitTypeDef GPIO_InitStruct; 60 | GPIO_InitStruct.GPIO_Pin = (1 << CanTxPin) | (1 << CanRxPin); 61 | GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; 62 | GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 63 | GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; 64 | GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; 65 | GPIO_Init(GPIOA, &GPIO_InitStruct); 66 | } 67 | 68 | /** 69 | * Configuring CanDriver 70 | */ 71 | void CanDriver::configure() 72 | { 73 | // Enable the clock for the CAN 74 | RCC->APB1ENR |= RCC_APB1Periph_CAN; 75 | 76 | // Connect PA12 to CAN_Tx, PA11 to CAN_Rx, use alternate function AF4 77 | GPIO_PinAFConfig(GPIOPtr[CanRxPort], CanRxPin, CAN_AF); 78 | GPIO_PinAFConfig(GPIOPtr[CanTxPort], CanTxPin, CAN_AF); 79 | 80 | // Configure these CAN pins in alternate function mode 81 | configureCANPins(); 82 | 83 | CAN_InitTypeDef CAN_InitStruct; 84 | CAN_DeInit(CAN); 85 | CAN_StructInit(&CAN_InitStruct); 86 | CAN_InitStruct.CAN_Prescaler = CAN_PRESCALER; // Specifies the length of a time quantum. It ranges from 1 to 1024. 87 | CAN_InitStruct.CAN_Mode = CAN_Mode_Normal; // Specifies the CAN operating mode. 88 | CAN_InitStruct.CAN_SJW = CAN_SJW_3tq; // Specifies the synchronization jump 89 | CAN_InitStruct.CAN_BS1 = CAN_BS1_12tq; // Specifies the number of time quanta in Bit Segment 1. 90 | CAN_InitStruct.CAN_BS2 = CAN_BS2_3tq; // Specifies the number of time quanta in Bit Segment 2. 91 | CAN_InitStruct.CAN_TTCM = DISABLE; // Enable or disable the time triggered communication mode. 92 | CAN_InitStruct.CAN_ABOM = ENABLE; // Enable or disable the automatic bus-off management. 93 | CAN_InitStruct.CAN_AWUM = DISABLE; // Enable or disable the automatic wake-up mode. 94 | CAN_InitStruct.CAN_NART = DISABLE; // Enable or disable the non-automatic retransmission mode. 95 | CAN_InitStruct.CAN_RFLM = DISABLE; // Enable or disable the Receive FIFO Locked mode. 96 | CAN_InitStruct.CAN_TXFP = DISABLE; // Enable or disable the transmit FIFO priority. 97 | CAN_Init(CAN, &CAN_InitStruct); 98 | 99 | // Enable FIFO 0 message pending Interrupt 100 | CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE); 101 | 102 | CAN->ESR = 0; 103 | 104 | // Disable Debug Freeze 105 | CAN->MCR &= ~MCR_DBF; 106 | } 107 | 108 | /** 109 | * CanDriver singleton 110 | * @return The pointer to CandRiver instance 111 | */ 112 | CanDriver* CanDriver::instance() 113 | { 114 | static CanDriver instance; 115 | return &instance; 116 | } 117 | 118 | /** 119 | * Intialize the CAN controller and interrupt handler 120 | */ 121 | CanDriver::CanDriver() 122 | { 123 | // Enable the CAN Interrupt 124 | NVIC_SetPriority(CEC_CAN_IRQn, 0); 125 | NVIC_EnableIRQ(CEC_CAN_IRQn); 126 | } 127 | 128 | /** 129 | * Transmits a sequence of bytes to the ECU over CAN bus 130 | * @parameter buff CanMsgBuffer instance 131 | * @return the send operation completion status 132 | */ 133 | bool CanDriver::send(const CanMsgBuffer* buff) 134 | { 135 | // Blink LED from here, when TX operation is completed 136 | AdptLED::instance()->blinkTx(); 137 | 138 | CanTxMsg msg; 139 | msg.StdId = msg.ExtId = buff->id; 140 | msg.IDE = buff->extended ? CAN_ID_EXT : CAN_ID_STD; 141 | msg.RTR = CAN_RTR_Data; 142 | msg.DLC = buff->dlc; 143 | memcpy(msg.Data, buff->data, 8); 144 | uint8_t val = CAN_Transmit(CAN, &msg); 145 | return (val != CAN_TxStatus_NoMailBox); 146 | } 147 | 148 | /** 149 | * Set the CAN filter for FIFO buffer 150 | * @parameter filter CAN filter value 151 | * @parameter mask CAN mask value 152 | * @parameter extended CAN extended message flag 153 | * @return the operation completion status 154 | */ 155 | bool CanDriver::setFilterAndMask(uint32_t filter, uint32_t mask, bool extended) 156 | { 157 | const uint32_t filterNum = 0; 158 | const uint32_t filterNumberBitPos = 1 << filterNum; 159 | 160 | // Initialisation mode for the filter 161 | CAN->FMR |= FMR_FINIT; 162 | 163 | // Filter Deactivation 164 | CAN->FA1R &= ~filterNumberBitPos; 165 | 166 | // 32-bit scale for the filter 167 | CAN->FS1R |= filterNumberBitPos; 168 | 169 | // 32-bit identifier 170 | // STDID[10:0], EXTID[17:0], IDE and RTR bits. 171 | CAN->sFilterRegister[filterNum].FR1 = extended ? ((filter << 3) | 0x0000004) : (filter << 21); 172 | 173 | // FIFO 0 assignation for the filter 174 | CAN->FFA1R &= ~filterNumberBitPos; 175 | 176 | // 32-bit mask 177 | // STDID[10:0], EXTID[17:0], IDE and RTR bits. 178 | CAN->sFilterRegister[filterNum].FR2 = extended ? ((mask << 3) | 0x0000004) : (mask << 21); 179 | 180 | // Id/Mask mode for the filter 181 | CAN->FM1R &= ~filterNumberBitPos; 182 | 183 | // Filter activation 184 | CAN->FA1R |= filterNumberBitPos; 185 | 186 | // Leave the initialisation mode for the filter 187 | CAN->FMR &= ~FMR_FINIT; 188 | 189 | return true; 190 | } 191 | 192 | /** 193 | * Read the CAN frame from FIFO buffer 194 | * @return true if read the frame / false if no frame 195 | */ 196 | bool CanDriver::read(CanMsgBuffer* buff) 197 | { 198 | if (RxFifoFlag) { 199 | const CanRxMsg* msg = &RxFifo[FifoReadPos]; 200 | buff->id = msg->IDE ? msg->ExtId : msg->StdId; 201 | buff->extended = (msg->IDE == CAN_ID_EXT); 202 | buff->dlc = msg->DLC; 203 | memcpy(buff->data, msg->Data, 8); 204 | 205 | // Advance the FIFO next reading position 206 | uint32_t mask = 0x1 << FifoReadPos; 207 | 208 | CAN_ITConfig(CAN, CAN_IT_FMP0, DISABLE); 209 | RxFifoFlag &= ~mask; 210 | CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE); 211 | FifoReadPos = (FifoReadPos == FIFO_NUM-1) ? 0 : FifoReadPos + 1; 212 | return true; 213 | } 214 | else { 215 | return false; 216 | } 217 | } 218 | 219 | /** 220 | * Read CAN frame received status 221 | * @return true/false 222 | */ 223 | bool CanDriver::isReady() const 224 | { 225 | return (RxFifoFlag != 0x0); 226 | } 227 | 228 | /** 229 | * Wakes up the CAN peripheral from sleep mode 230 | * @return true/false 231 | */ 232 | bool CanDriver::wakeUp() 233 | { 234 | return CAN_WakeUp(CAN) == CAN_WakeUp_Ok; 235 | } 236 | 237 | /** 238 | * Enters the sleep (low power) mode 239 | * @return true/false 240 | */ 241 | bool CanDriver::sleep() 242 | { 243 | return false; 244 | } 245 | 246 | /** 247 | * Switch on/off CAN and let the CAN pins controlled directly (testing mode) 248 | * @parameter val CAN testing mode flag 249 | */ 250 | void CanDriver::setBitBang(bool val) 251 | { 252 | if (!val) { 253 | configureCANPins(); 254 | } 255 | else { 256 | GPIOSetDir(CanRxPort, CanRxPin, GPIO_INPUT); 257 | GPIOSetDir(CanTxPort, CanTxPin, GPIO_OUTPUT); 258 | } 259 | } 260 | 261 | /** 262 | * Set the CAN transmitter pin status 263 | * @parameter bit CAN TX pin value 264 | */ 265 | void CanDriver::setBit(uint32_t bit) 266 | { 267 | GPIOPinWrite(CanTxPort, CanTxPin, bit); 268 | } 269 | 270 | /** 271 | * Read CAN RX pin status 272 | * @return pin status, 1 if set, 0 otherwise 273 | */ 274 | uint32_t CanDriver::getBit() 275 | { 276 | return GPIOPinRead(CanRxPort, CanRxPin); 277 | } 278 | -------------------------------------------------------------------------------- /src/adapter/obd/isocan.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "canmsgbuffer.h" 14 | #include "obdprofile.h" 15 | #include "isocan.h" 16 | #include "canhistory.h" 17 | 18 | using namespace std; 19 | using namespace util; 20 | 21 | const int ISO_CAN_LEN = 7; 22 | 23 | IsoCanAdapter::IsoCanAdapter() 24 | { 25 | extended_ = false; 26 | canPriority_ = 0; 27 | filter_[0] = mask_[0] = 0; 28 | driver_ = CanDriver::instance(); 29 | history_ = new CanHistory(); 30 | } 31 | 32 | /** 33 | 34 | * Setting CAN custom filter 35 | * @param[in] filter The filter bytes 36 | */ 37 | void IsoCanAdapter::setFilter(const uint8_t* filter) 38 | { 39 | memcpy(filter_, filter, sizeof(filter_)); 40 | setFilterAndMask(); 41 | } 42 | 43 | /** 44 | * Setting CAN custom mask 45 | * @param[in] mask The mask bytes 46 | */ 47 | void IsoCanAdapter::setMask(const uint8_t* mask) 48 | { 49 | memcpy(mask_, mask, sizeof(mask_)); 50 | setFilterAndMask(); 51 | } 52 | 53 | /** 54 | * Send buffer to ECU using CAN 55 | * @param[in] data The message data bytes 56 | * @param[in] len The message length 57 | * @return true if OK, false if data issues 58 | */ 59 | bool IsoCanAdapter::sendToEcu(const uint8_t* data, int len) 60 | { 61 | if (len > ISO_CAN_LEN) { 62 | return false; // REPLY_DATA_ERROR 63 | } 64 | CanMsgBuffer msgBuffer(getID(), extended_, 8, 0); 65 | msgBuffer.data[0] = len; 66 | memcpy(msgBuffer.data + 1, data, len); 67 | 68 | // Message log 69 | history_->add2Buffer(&msgBuffer, true, 0); 70 | 71 | if (!driver_->send(&msgBuffer)) { 72 | return false; // REPLY_DATA_ERROR 73 | } 74 | return true; 75 | } 76 | 77 | /** 78 | * Format reply for "H1" option 79 | * @param[in] msg CanMsgbuffer instance pointer 80 | * @param[out] str The output string 81 | */ 82 | void IsoCanAdapter::formatReplyWithHeader(const CanMsgBuffer* msg, util::string& str) 83 | { 84 | CanIDToString(msg->id, str, msg->extended); 85 | bool useSpaces = AdapterConfig::instance()->getBoolProperty(PAR_SPACES); 86 | bool isDLC = AdapterConfig::instance()->getBoolProperty(PAR_CAN_DLC); 87 | if (useSpaces) { 88 | str += ' '; // number of chars + space 89 | } 90 | if (isDLC) { 91 | str += msg->dlc + '0'; // add DLC byte 92 | if (useSpaces) { 93 | str += ' '; 94 | } 95 | } 96 | to_ascii(msg->data, 8, str); 97 | } 98 | 99 | /** 100 | * Process first/next/single frames 101 | * @param[in] msg CanMsgbuffer instance pointer 102 | */ 103 | void IsoCanAdapter::processFrame(const CanMsgBuffer* msg) 104 | { 105 | util::string str; 106 | if (config_->getBoolProperty(PAR_HEADER_SHOW)) { 107 | formatReplyWithHeader(msg, str); 108 | } 109 | else { 110 | to_ascii(msg->data, 8, str); 111 | } 112 | AdptSendReply(str); 113 | } 114 | 115 | /** 116 | * Receives a sequence of bytes from the CAN bus 117 | * @param[in] sendReply send reply to user flag 118 | * @return true if message received, false otherwise 119 | */ 120 | bool IsoCanAdapter::receiveFromEcu(bool sendReply) 121 | { 122 | const int p2Timeout = getP2MaxTimeout(); 123 | CanMsgBuffer msgBuffer; 124 | bool msgReceived = false; 125 | 126 | Timer* timer = Timer::instance(0); 127 | timer->start(p2Timeout); 128 | 129 | do { 130 | if (!driver_->isReady()) 131 | continue; 132 | driver_->read(&msgBuffer); 133 | 134 | // Message log 135 | history_->add2Buffer(&msgBuffer, false, msgBuffer.msgnum); 136 | 137 | // Reload the timer 138 | timer->start(p2Timeout); 139 | 140 | msgReceived = true; 141 | if (!sendReply) 142 | continue; 143 | switch ((msgBuffer.data[0] & 0xF0) >> 4) { 144 | case CANSingleFrame: 145 | processFrame(&msgBuffer); 146 | break; 147 | case CANFirstFrame: 148 | processFlowFrame(&msgBuffer); 149 | processFrame(&msgBuffer); 150 | break; 151 | case CANConsecutiveFrame: 152 | processFrame(&msgBuffer); 153 | break; 154 | } 155 | } while (!timer->isExpired()); 156 | 157 | return msgReceived; 158 | } 159 | 160 | 161 | int IsoCanAdapter::getP2MaxTimeout() const 162 | { 163 | int p2Timeout = config_->getIntProperty(PAR_TIMEOUT); 164 | return p2Timeout ? p2Timeout : CAN_P2_MAX_TIMEOUT; 165 | } 166 | 167 | /** 168 | * Global entry ECU send/receive function 169 | * @param[in] data The message data bytes 170 | * @param[in] len The message length 171 | * @return The completion status code 172 | */ 173 | int IsoCanAdapter::onRequest(const uint8_t* data, int len) 174 | { 175 | if (!sendToEcu(data, len)) 176 | return REPLY_DATA_ERROR; 177 | return receiveFromEcu(true) ? REPLY_NONE : REPLY_NO_DATA; 178 | } 179 | 180 | /** 181 | * Will try to send PID0 to query the CAN protocol 182 | * @param[in] sendReply Reply flag 183 | * @return Protocol value if ECU is supporting CAN protocol, 0 otherwise 184 | */ 185 | int IsoCanAdapter::onConnectEcu(bool sendReply) 186 | { 187 | CanMsgBuffer msgBuffer(getID(), extended_, 8, 0x02, 0x01, 0x00); 188 | 189 | open(); 190 | 191 | switch (OBDProfile::instance()->getProtocol()) { 192 | case PROT_ISO15765_1150: 193 | connected_ = true; 194 | return PROT_ISO15765_1150; 195 | case PROT_ISO15765_2950: 196 | connected_ = true; 197 | return PROT_ISO15765_2950; 198 | 199 | } 200 | 201 | if (driver_->send(&msgBuffer)) { 202 | if (receiveFromEcu(sendReply)) { 203 | connected_ = true; 204 | return extended_ ? PROT_ISO15765_2950 : PROT_ISO15765_1150; 205 | } 206 | } 207 | close(); // Close only if not succeeded 208 | return 0; 209 | } 210 | 211 | /** 212 | * Print the messages buffer 213 | */ 214 | void IsoCanAdapter::dumpBuffer() 215 | { 216 | history_->dumpCurrentBuffer(); 217 | } 218 | 219 | /** 220 | * Test wiring connectivity for CAN 221 | */ 222 | void IsoCanAdapter::wiringCheck() 223 | { 224 | bool failed = false; 225 | driver_->setBitBang(true); 226 | 227 | driver_->setBit(0); 228 | Delay1us(100); 229 | if (driver_->getBit() != 0) { 230 | AdptSendReply("CAN wiring failed [0->1]"); 231 | failed = true; 232 | } 233 | 234 | driver_->setBit(1); 235 | Delay1us(100); 236 | if (driver_->getBit() != 1) { 237 | AdptSendReply("CAN wiring failed [1->0]"); 238 | failed = true; 239 | } 240 | 241 | if (!failed) { 242 | AdptSendReply("CAN wiring is OK"); 243 | } 244 | 245 | driver_->setBitBang(false); 246 | } 247 | 248 | /** 249 | * IsoCan11Adapter class members 250 | */ 251 | void IsoCan11Adapter::open() 252 | { 253 | setFilterAndMask(); 254 | 255 | //Start using LED timer 256 | AdptLED::instance()->startTimer(); 257 | } 258 | 259 | uint32_t IsoCan11Adapter::getID() const 260 | { 261 | NumericType id; 262 | 263 | const ByteArray* bytes = config_->getBytesProperty(PAR_WM_HEADER); 264 | if (bytes->length) { 265 | const uint8_t* customHdr = bytes->data; 266 | id.bvalue[1] = customHdr[2] & 0x07; 267 | id.bvalue[0] = customHdr[3]; 268 | } 269 | else { 270 | id.lvalue = 0x7DF; 271 | } 272 | return id.lvalue; 273 | } 274 | 275 | void IsoCan11Adapter::setFilterAndMask() 276 | { 277 | // Mask 11 bit 278 | NumericType mask; 279 | 280 | if (isCustomMask()) { 281 | mask.bvalue[1] = mask_[3] & 0x07; 282 | mask.bvalue[0] = mask_[4]; 283 | } 284 | else { // Default mask for 11 bit CAN 285 | mask.lvalue = 0x7F8; 286 | } 287 | // Filter 11 bit 288 | NumericType filter; 289 | if (isCustomFilter()) { 290 | filter.bvalue[1] = filter_[3] & 0x07; 291 | filter.bvalue[0] = filter_[4]; 292 | } 293 | else { // Default filter for 11 bit CAN 294 | filter.lvalue = 0x7E8; 295 | } 296 | // Set mask and filter 11 bit 297 | driver_->setFilterAndMask(filter.lvalue, mask.lvalue, false); 298 | } 299 | 300 | void IsoCan11Adapter::processFlowFrame(const CanMsgBuffer* msg) 301 | { 302 | CanMsgBuffer ctrlData(getID(), false, 8, 0x30, 0x0, 0x00); 303 | ctrlData.id |= (msg->id & 0x07); 304 | driver_->send(&ctrlData); 305 | 306 | // Message log 307 | history_->add2Buffer(&ctrlData, true, 0); 308 | } 309 | 310 | void IsoCan11Adapter::getDescription() 311 | { 312 | bool useAutoSP = config_->getBoolProperty(PAR_USE_AUTO_SP); 313 | AdptSendReply(useAutoSP ? "AUTO, ISO 15765-4 (CAN 11/500)" : "ISO 15765-4 (CAN 11/500)"); 314 | } 315 | 316 | void IsoCan11Adapter::getDescriptionNum() 317 | { 318 | bool useAutoSP = config_->getBoolProperty(PAR_USE_AUTO_SP); 319 | AdptSendReply(useAutoSP ? "A6" : "6"); 320 | } 321 | 322 | /** 323 | * IsoCan29Adapter class members 324 | */ 325 | void IsoCan29Adapter::open() 326 | { 327 | setFilterAndMask(); 328 | 329 | // Start using LED timer 330 | AdptLED::instance()->startTimer(); 331 | } 332 | 333 | uint32_t IsoCan29Adapter::getID() const 334 | { 335 | NumericType id; 336 | 337 | const ByteArray* bytes = config_->getBytesProperty(PAR_WM_HEADER); 338 | if (bytes->length) { 339 | const uint8_t* customHdr = bytes->data; 340 | id.bvalue[3] = canPriority_; 341 | id.bvalue[2] = customHdr[1]; 342 | id.bvalue[1] = customHdr[2]; 343 | id.bvalue[0] = customHdr[3]; 344 | } 345 | else { 346 | id.lvalue = 0x18DB33F1; 347 | } 348 | return id.lvalue; 349 | } 350 | 351 | void IsoCan29Adapter::setFilterAndMask() 352 | { 353 | // Mask 29 bit 354 | NumericType mask; 355 | 356 | if (isCustomMask()) { 357 | mask.bvalue[3] = mask_[1]; 358 | mask.bvalue[2] = mask_[2]; 359 | mask.bvalue[1] = mask_[3]; 360 | mask.bvalue[0] = mask_[4]; 361 | } 362 | else { // Default for 29 bit CAN 363 | mask.lvalue = 0x1FFFFF00; 364 | } 365 | // Filter 29 bit 366 | NumericType filter; 367 | if (isCustomFilter()) { 368 | filter.bvalue[3] = filter_[1]; 369 | filter.bvalue[2] = filter_[2]; 370 | filter.bvalue[1] = filter_[3]; 371 | filter.bvalue[0] = filter_[4]; 372 | } 373 | else { // Default for 29 bit CAN 374 | filter.lvalue = 0x18DAF100; 375 | } 376 | // Set mask and filter 29 bit 377 | driver_->setFilterAndMask(filter.lvalue, mask.lvalue, true); 378 | } 379 | 380 | void IsoCan29Adapter::processFlowFrame(const CanMsgBuffer* msg) 381 | { 382 | CanMsgBuffer ctrlData(getID(), true, 8, 0x30, 0x0, 0x00); 383 | ctrlData.id |= (msg->id & 0xFF) << 8; 384 | driver_->send(&ctrlData); 385 | 386 | // Message log 387 | history_->add2Buffer(&ctrlData, true, 0); 388 | } 389 | 390 | void IsoCan29Adapter::getDescription() 391 | { 392 | bool useAutoSP = config_->getBoolProperty(PAR_USE_AUTO_SP); 393 | AdptSendReply(useAutoSP ? "AUTO, ISO 15765-4 (CAN 29/500)" : "ISO 15765-4 (CAN 29/500)"); 394 | } 395 | 396 | void IsoCan29Adapter::getDescriptionNum() 397 | { 398 | bool useAutoSP = config_->getBoolProperty(PAR_USE_AUTO_SP); 399 | AdptSendReply(useAutoSP ? "A7" : "7"); 400 | } 401 | -------------------------------------------------------------------------------- /STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_gpio.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f0xx_gpio.h 4 | * @author MCD Application Team 5 | * @version V1.3.0 6 | * @date 16-January-2014 7 | * @brief This file contains all the functions prototypes for the GPIO 8 | * firmware library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2014 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F0XX_GPIO_H 31 | #define __STM32F0XX_GPIO_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f0xx.h" 39 | 40 | /** @addtogroup STM32F0xx_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup GPIO 45 | * @{ 46 | */ 47 | /* Exported types ------------------------------------------------------------*/ 48 | 49 | #define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ 50 | ((PERIPH) == GPIOB) || \ 51 | ((PERIPH) == GPIOC) || \ 52 | ((PERIPH) == GPIOD) || \ 53 | ((PERIPH) == GPIOE) || \ 54 | ((PERIPH) == GPIOF)) 55 | 56 | #define IS_GPIO_LIST_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ 57 | ((PERIPH) == GPIOB)) 58 | 59 | /** @defgroup Configuration_Mode_enumeration 60 | * @{ 61 | */ 62 | typedef enum 63 | { 64 | GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ 65 | GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ 66 | GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ 67 | GPIO_Mode_AN = 0x03 /*!< GPIO Analog In/Out Mode */ 68 | }GPIOMode_TypeDef; 69 | 70 | #define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN)|| ((MODE) == GPIO_Mode_OUT) || \ 71 | ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) 72 | /** 73 | * @} 74 | */ 75 | 76 | /** @defgroup Output_type_enumeration 77 | * @{ 78 | */ 79 | typedef enum 80 | { 81 | GPIO_OType_PP = 0x00, 82 | GPIO_OType_OD = 0x01 83 | }GPIOOType_TypeDef; 84 | 85 | #define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) 86 | 87 | /** 88 | * @} 89 | */ 90 | 91 | /** @defgroup Output_Maximum_frequency_enumeration 92 | * @{ 93 | */ 94 | typedef enum 95 | { 96 | GPIO_Speed_Level_1 = 0x00, /*!< I/O output speed: Low 2 MHz */ 97 | GPIO_Speed_Level_2 = 0x01, /*!< I/O output speed: Medium 10 MHz */ 98 | GPIO_Speed_Level_3 = 0x03 /*!< I/O output speed: High 50 MHz */ 99 | }GPIOSpeed_TypeDef; 100 | 101 | #define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_Level_1) || ((SPEED) == GPIO_Speed_Level_2) || \ 102 | ((SPEED) == GPIO_Speed_Level_3)) 103 | /** 104 | * @} 105 | */ 106 | 107 | /** @defgroup Configuration_Pull-Up_Pull-Down_enumeration 108 | * @{ 109 | */ 110 | typedef enum 111 | { 112 | GPIO_PuPd_NOPULL = 0x00, 113 | GPIO_PuPd_UP = 0x01, 114 | GPIO_PuPd_DOWN = 0x02 115 | }GPIOPuPd_TypeDef; 116 | 117 | #define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ 118 | ((PUPD) == GPIO_PuPd_DOWN)) 119 | /** 120 | * @} 121 | */ 122 | 123 | /** @defgroup Bit_SET_and_Bit_RESET_enumeration 124 | * @{ 125 | */ 126 | typedef enum 127 | { 128 | Bit_RESET = 0, 129 | Bit_SET 130 | }BitAction; 131 | 132 | #define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) 133 | /** 134 | * @} 135 | */ 136 | 137 | /** 138 | * @brief GPIO Init structure definition 139 | */ 140 | typedef struct 141 | { 142 | uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. 143 | This parameter can be any value of @ref GPIO_pins_define */ 144 | 145 | GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. 146 | This parameter can be a value of @ref GPIOMode_TypeDef */ 147 | 148 | GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. 149 | This parameter can be a value of @ref GPIOSpeed_TypeDef */ 150 | 151 | GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. 152 | This parameter can be a value of @ref GPIOOType_TypeDef */ 153 | 154 | GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. 155 | This parameter can be a value of @ref GPIOPuPd_TypeDef */ 156 | }GPIO_InitTypeDef; 157 | 158 | /* Exported constants --------------------------------------------------------*/ 159 | 160 | /** @defgroup GPIO_Exported_Constants 161 | * @{ 162 | */ 163 | 164 | /** @defgroup GPIO_pins_define 165 | * @{ 166 | */ 167 | #define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ 168 | #define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ 169 | #define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ 170 | #define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */ 171 | #define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */ 172 | #define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */ 173 | #define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */ 174 | #define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */ 175 | #define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */ 176 | #define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */ 177 | #define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */ 178 | #define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */ 179 | #define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */ 180 | #define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */ 181 | #define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */ 182 | #define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */ 183 | #define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */ 184 | 185 | #define IS_GPIO_PIN(PIN) ((PIN) != (uint16_t)0x00) 186 | 187 | #define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ 188 | ((PIN) == GPIO_Pin_1) || \ 189 | ((PIN) == GPIO_Pin_2) || \ 190 | ((PIN) == GPIO_Pin_3) || \ 191 | ((PIN) == GPIO_Pin_4) || \ 192 | ((PIN) == GPIO_Pin_5) || \ 193 | ((PIN) == GPIO_Pin_6) || \ 194 | ((PIN) == GPIO_Pin_7) || \ 195 | ((PIN) == GPIO_Pin_8) || \ 196 | ((PIN) == GPIO_Pin_9) || \ 197 | ((PIN) == GPIO_Pin_10) || \ 198 | ((PIN) == GPIO_Pin_11) || \ 199 | ((PIN) == GPIO_Pin_12) || \ 200 | ((PIN) == GPIO_Pin_13) || \ 201 | ((PIN) == GPIO_Pin_14) || \ 202 | ((PIN) == GPIO_Pin_15)) 203 | 204 | /** 205 | * @} 206 | */ 207 | 208 | /** @defgroup GPIO_Pin_sources 209 | * @{ 210 | */ 211 | #define GPIO_PinSource0 ((uint8_t)0x00) 212 | #define GPIO_PinSource1 ((uint8_t)0x01) 213 | #define GPIO_PinSource2 ((uint8_t)0x02) 214 | #define GPIO_PinSource3 ((uint8_t)0x03) 215 | #define GPIO_PinSource4 ((uint8_t)0x04) 216 | #define GPIO_PinSource5 ((uint8_t)0x05) 217 | #define GPIO_PinSource6 ((uint8_t)0x06) 218 | #define GPIO_PinSource7 ((uint8_t)0x07) 219 | #define GPIO_PinSource8 ((uint8_t)0x08) 220 | #define GPIO_PinSource9 ((uint8_t)0x09) 221 | #define GPIO_PinSource10 ((uint8_t)0x0A) 222 | #define GPIO_PinSource11 ((uint8_t)0x0B) 223 | #define GPIO_PinSource12 ((uint8_t)0x0C) 224 | #define GPIO_PinSource13 ((uint8_t)0x0D) 225 | #define GPIO_PinSource14 ((uint8_t)0x0E) 226 | #define GPIO_PinSource15 ((uint8_t)0x0F) 227 | 228 | #define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ 229 | ((PINSOURCE) == GPIO_PinSource1) || \ 230 | ((PINSOURCE) == GPIO_PinSource2) || \ 231 | ((PINSOURCE) == GPIO_PinSource3) || \ 232 | ((PINSOURCE) == GPIO_PinSource4) || \ 233 | ((PINSOURCE) == GPIO_PinSource5) || \ 234 | ((PINSOURCE) == GPIO_PinSource6) || \ 235 | ((PINSOURCE) == GPIO_PinSource7) || \ 236 | ((PINSOURCE) == GPIO_PinSource8) || \ 237 | ((PINSOURCE) == GPIO_PinSource9) || \ 238 | ((PINSOURCE) == GPIO_PinSource10) || \ 239 | ((PINSOURCE) == GPIO_PinSource11) || \ 240 | ((PINSOURCE) == GPIO_PinSource12) || \ 241 | ((PINSOURCE) == GPIO_PinSource13) || \ 242 | ((PINSOURCE) == GPIO_PinSource14) || \ 243 | ((PINSOURCE) == GPIO_PinSource15)) 244 | /** 245 | * @} 246 | */ 247 | 248 | /** @defgroup GPIO_Alternate_function_selection_define 249 | * @{ 250 | */ 251 | 252 | /** 253 | * @brief AF 0 selection 254 | */ 255 | #define GPIO_AF_0 ((uint8_t)0x00) /* WKUP, EVENTOUT, TIM15, SPI1, TIM17, 256 | MCO, SWDAT, SWCLK, TIM14, BOOT, 257 | USART1, CEC, IR_OUT, SPI2, TS, TIM3, 258 | USART4, CAN, TIM3, USART2, USART3, 259 | CRS, TIM16, TIM1 */ 260 | /** 261 | * @brief AF 1 selection 262 | */ 263 | #define GPIO_AF_1 ((uint8_t)0x01) /* USART2, CEC, TIM3, USART1, IR, 264 | EVENTOUT, I2C1, I2C2, TIM15, SPI2, 265 | USART3, TS, SPI1 */ 266 | /** 267 | * @brief AF 2 selection 268 | */ 269 | #define GPIO_AF_2 ((uint8_t)0x02) /* TIM2, TIM1, EVENTOUT, TIM16, TIM17, 270 | USB */ 271 | /** 272 | * @brief AF 3 selection 273 | */ 274 | #define GPIO_AF_3 ((uint8_t)0x03) /* TS, I2C1, TIM15, EVENTOUT */ 275 | 276 | /** 277 | * @brief AF 4 selection 278 | */ 279 | #define GPIO_AF_4 ((uint8_t)0x04) /* TIM14, USART4, USART3, CRS, CAN, 280 | I2C1 */ 281 | 282 | /** 283 | * @brief AF 5 selection 284 | */ 285 | #define GPIO_AF_5 ((uint8_t)0x05) /* TIM16, TIM17, TIM15, SPI2, I2C2, 286 | MCO, I2C1, USB */ 287 | 288 | /** 289 | * @brief AF 6 selection 290 | */ 291 | #define GPIO_AF_6 ((uint8_t)0x06) /* EVENTOUT */ 292 | /** 293 | * @brief AF 7 selection 294 | */ 295 | #define GPIO_AF_7 ((uint8_t)0x07) /* COMP1 OUT and COMP2 OUT */ 296 | 297 | #define IS_GPIO_AF(AF) (((AF) == GPIO_AF_0) || ((AF) == GPIO_AF_1) || \ 298 | ((AF) == GPIO_AF_2) || ((AF) == GPIO_AF_3) || \ 299 | ((AF) == GPIO_AF_4) || ((AF) == GPIO_AF_5) || \ 300 | ((AF) == GPIO_AF_6) || ((AF) == GPIO_AF_7)) 301 | 302 | /** 303 | * @} 304 | */ 305 | 306 | /** @defgroup GPIO_Speed_Legacy 307 | * @{ 308 | */ 309 | 310 | #define GPIO_Speed_2MHz GPIO_Speed_Level_1 /*!< I/O output speed: Low 2 MHz */ 311 | #define GPIO_Speed_10MHz GPIO_Speed_Level_2 /*!< I/O output speed: Medium 10 MHz */ 312 | #define GPIO_Speed_50MHz GPIO_Speed_Level_3 /*!< I/O output speed: High 50 MHz */ 313 | 314 | /** 315 | * @} 316 | */ 317 | 318 | /** 319 | * @} 320 | */ 321 | 322 | /* Exported macro ------------------------------------------------------------*/ 323 | /* Exported functions ------------------------------------------------------- */ 324 | /* Function used to set the GPIO configuration to the default reset state *****/ 325 | void GPIO_DeInit(GPIO_TypeDef* GPIOx); 326 | 327 | /* Initialization and Configuration functions *********************************/ 328 | void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); 329 | void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); 330 | void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 331 | 332 | /* GPIO Read and Write functions **********************************************/ 333 | uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 334 | uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); 335 | uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 336 | uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); 337 | void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 338 | void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 339 | void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); 340 | void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); 341 | 342 | /* GPIO Alternate functions configuration functions ***************************/ 343 | void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); 344 | 345 | #ifdef __cplusplus 346 | } 347 | #endif 348 | 349 | #endif /* __STM32F0XX_GPIO_H */ 350 | /** 351 | * @} 352 | */ 353 | 354 | /** 355 | * @} 356 | */ 357 | 358 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 359 | -------------------------------------------------------------------------------- /src/adapter/dispatcher.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * See the file LICENSE for redistribution information. 3 | * 4 | * Copyright (c) 2009-2016 ObdDiag.Net. All rights reserved. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include "obd/obdprofile.h" 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace util; 17 | 18 | // 19 | // Reply string constants 20 | // 21 | static const char ErrMessage [] = "?"; 22 | static const char OkMessage [] = "OK"; 23 | static const char Version [] = "1.10"; 24 | static const char Interface [] = "ELM329 v2.1"; 25 | static const char Copyright [] = "Copyright (c) 2009-2016 ObdDiag.Net"; 26 | static const char Copyright2 [] = "This is free software; see the source for copying conditions. There is NO"; 27 | static const char Copyright3 [] = "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."; 28 | 29 | 30 | /** 31 | * Store the boolean true property 32 | * @param[in] cmd Command line, ignored 33 | * @param[in[ par The number in dispatch table 34 | */ 35 | static void OnSetValueTrue(const string& cmd, int par) 36 | { 37 | AdapterConfig::instance()->setBoolProperty(par, true); 38 | AdptSendReply(OkMessage); 39 | } 40 | 41 | /** 42 | * Store the boolean false property 43 | * @param[in[ cmd Command line, ignored 44 | * @param[in] par The number in dispatch table 45 | */ 46 | static void OnSetValueFalse(const string& cmd, int par) 47 | { 48 | AdapterConfig::instance()->setBoolProperty(par, false); 49 | AdptSendReply(OkMessage); 50 | } 51 | 52 | /** 53 | * Store the int property 54 | * @param[in] cmd Command line 55 | * @param[in] par The number in dispatch table 56 | */ 57 | static void OnSetValueInt(const string& cmd, int par) 58 | { 59 | uint32_t val = stoul(cmd, 0, 16); 60 | if (val != ULONG_MAX) { 61 | AdapterConfig::instance()->setIntProperty(par, val); 62 | AdptSendReply(OkMessage); 63 | } 64 | else { 65 | AdptSendReply(ErrMessage); 66 | } 67 | } 68 | 69 | /** 70 | * Reset the int property to 0 71 | * @param[in] cmd Command line 72 | * @param[in] par The number in dispatch table 73 | */ 74 | static void OnResetValueInt(const string& cmd, int par) 75 | { 76 | AdapterConfig::instance()->setIntProperty(par, 0); 77 | AdptSendReply(OkMessage); 78 | } 79 | 80 | /** 81 | * Store the byte sequence property 82 | * @param[in] cmd Command line 83 | * @param[in] par The number in dispatch table 84 | */ 85 | static void OnSetBytes(const string& cmd, int par) 86 | { 87 | string cmdData = cmd; 88 | bool sts = false; 89 | ByteArray bytes; 90 | 91 | if (cmdData.length() == 3) { 92 | cmdData = "0" + cmdData; //1.5 bytes 93 | sts = to_bytes(cmdData, bytes.data); 94 | } 95 | else { 96 | sts = to_bytes(cmdData, bytes.data); 97 | } 98 | 99 | if (sts) { 100 | bytes.length = cmdData.length() / 2; 101 | AdapterConfig::instance()->setBytesProperty(par, &bytes); 102 | AdptSendReply(OkMessage); 103 | } 104 | else { 105 | AdptSendReply(ErrMessage); 106 | } 107 | } 108 | 109 | /** 110 | * Reply with "OK" message 111 | * @param[in] cmd Command line, ignored 112 | * @param[in] par The number in dispatch table, ignored 113 | */ 114 | static void OnSetOK(const string& cmd, int par) 115 | { 116 | AdptSendReply(OkMessage); 117 | } 118 | 119 | static void OnCanShowStatus(const string& cmd, int par) 120 | { 121 | return; 122 | } 123 | 124 | /** 125 | * The adapter firmware string 126 | * @param[in] cmd Command line, ignored 127 | * @param[in] par The number in dispatch table, ignored 128 | */ 129 | static void OnSendReplyCopyright(const string& cmd, int par) 130 | { 131 | AdptSendReply(Copyright); 132 | AdptSendReply(Copyright2); 133 | AdptSendReply(Copyright3); 134 | } 135 | 136 | /** 137 | * Run the adapter connectivity test 138 | * @param[in] cmd Command line, ignored 139 | * @param[in] par The number in dispatch table, ignored 140 | */ 141 | static void OnWiringTest(const string& cmd, int par) 142 | { 143 | OBDProfile::instance()->wiringCheck(); 144 | } 145 | 146 | /** 147 | * The serial #, hardware-related 148 | * @param[in] cmd Command line, ignored 149 | * @param[in] par The number in dispatch table, ignored 150 | */ 151 | static void OnGetSerial(const string& cmd, int par) 152 | { 153 | AdptReadSerialNum(); 154 | } 155 | 156 | /** 157 | * The firmware version 158 | * @param[in] cmd Command line, ignored 159 | * @param[in] par The number in dispatch table, ignored 160 | */ 161 | static void OnSendReplyVersion(const string& cmd, int par) 162 | { 163 | AdptSendReply(Version); 164 | } 165 | 166 | /** 167 | * Dump the transmit/receive adapter buffer, "ATBD" 168 | * @param[in] cmd Command line, ignored 169 | * @param[in] par The number in dispatch table, ignored 170 | */ 171 | static void OnBufferDump(const string& cmd, int par) 172 | { 173 | OBDProfile::instance()->dumpBuffer(); 174 | } 175 | 176 | /** 177 | * Set adapter default parameters 178 | */ 179 | static void SetDefault() 180 | { 181 | AdapterConfig* config = AdapterConfig::instance(); 182 | config->setBoolProperty(PAR_HEADER_SHOW, false); 183 | config->setBoolProperty(PAR_LINEFEED, true); 184 | config->setBoolProperty(PAR_ECHO, true); 185 | config->setBoolProperty(PAR_SPACES, true); 186 | config->setIntProperty(PAR_TIMEOUT, 0); 187 | AdptSendReply(OkMessage); 188 | } 189 | 190 | /** 191 | * Reset to defaults, "ATD" 192 | * @param[in] cmd Command line, ignored 193 | * @param[in] par The number in dispatch table, ignored 194 | */ 195 | static void OnSetDefault(const string& cmd, int par) 196 | { 197 | SetDefault(); 198 | AdptSendReply(OkMessage); 199 | } 200 | 201 | /** 202 | * Get the current protocol description, "ATDP" 203 | * @param[in] cmd Command line, ignored 204 | * @param[in] par The number in dispatch table, ignored 205 | */ 206 | static void OnProtocolDescribe(const string& cmd, int par) 207 | { 208 | OBDProfile::instance()->getProtocolDescription(); 209 | } 210 | 211 | /** 212 | * Get the current protocol number, "ATDPN" 213 | * @param[in] cmd Command line, ignored 214 | * @param[in] par The number in dispatch table, ignored 215 | */ 216 | static void OnProtocolDescribeNum(const string& cmd, int par) 217 | { 218 | OBDProfile::instance()->getProtocolDescriptionNum(); 219 | } 220 | 221 | static void OnJ1939Monitor(const string& cmd, int par) 222 | { 223 | return; 224 | } 225 | 226 | /** 227 | * Close the protocol, set the disconnected status, "ATPC" 228 | * @param[in] cmd Command line, ignored 229 | * @param[in] par The number in dispatch table, ignored 230 | */ 231 | static void OnProtocolClose(const string& cmd, int par) 232 | { 233 | OBDProfile::instance()->closeProtocol(); 234 | } 235 | 236 | /** 237 | * Read the car voltage level, "ATRV" 238 | * @param[in] cmd Command line, ignored 239 | * @param]in] par The number in dispatch table, ignored 240 | */ 241 | static void OnReadVoltage(const string& cmd, int par) 242 | { 243 | const uint32_t actualVoltage = 1212; 244 | const uint32_t adcDivdr = 0x0A3D; 245 | 246 | uint32_t adcValue = AdcDriver::read(); 247 | 248 | // Compute the voltage 249 | uint32_t val = (adcValue * actualVoltage / adcDivdr + 5); 250 | int valInt = val / 100; 251 | int valFraction = (val % 100) / 10; 252 | 253 | char out[10]; 254 | sprintf(out, "%d.%1dV", valInt, valFraction); 255 | AdptSendReply(out); 256 | } 257 | 258 | /** 259 | * Set the protocol, "ATSP" 260 | * @param[in] cmd Command line 261 | * @param[in] par The number in dispatch table, ignored 262 | */ 263 | static void OnSetProtocol(const string& cmd, int par) 264 | { 265 | bool useAutoSP = false; 266 | uint8_t protocol = 0; 267 | 268 | if (cmd[0] == 'A' && cmd.length() == 2) { 269 | protocol = cmd[1] - '0'; 270 | useAutoSP = true; 271 | } 272 | else if (cmd.length() == 1) { 273 | protocol = cmd[0] - '0'; 274 | useAutoSP = false; 275 | } 276 | else { 277 | AdptSendReply(ErrMessage); 278 | return; 279 | } 280 | 281 | AdapterConfig::instance()->setBoolProperty(PAR_USE_AUTO_SP, useAutoSP); 282 | if (OBDProfile::instance()->setProtocol(protocol, true) == REPLY_OK) { 283 | AdptSendReply(OkMessage); 284 | } 285 | else { 286 | AdptSendReply(ErrMessage); 287 | } 288 | } 289 | 290 | /** 291 | * The adapter interface string, "ATI" 292 | * @param[in] cmd Command line, ignored 293 | * @param[in] par The number in dispatch table, ignored 294 | */ 295 | static void OnSendReplyInterface(const string& cmd, int par) 296 | { 297 | AdptSendReply(Interface); 298 | } 299 | 300 | /** 301 | * Set adapter parameters on reset, "ATZ" 302 | * @param[in] cmd Command line, ignored 303 | * @param[in] par The number in dispatch table, ignored 304 | */ 305 | static void OnReset(const string& cmd, int par) 306 | { 307 | SetDefault(); 308 | AdptSendReply(Interface); 309 | } 310 | 311 | typedef void (*ParCallbackT)(const string& cmd, int par); 312 | 313 | struct DispatchType { 314 | const char* name; 315 | int id; 316 | uint8_t minParNum; 317 | uint8_t maxParNum; 318 | ParCallbackT callback; 319 | }; 320 | 321 | static const DispatchType dispatchTbl[] = { 322 | { "#1", PAR_CHIP_COPYRIGHT, 0, 0, OnSendReplyCopyright }, 323 | { "#3", PAR_WIRING_TEST, 0, 0, OnWiringTest }, 324 | { "#RSN", PAR_GET_SERIAL, 0, 0, OnGetSerial }, 325 | { "@1", PAR_VERSION, 0, 0, OnSendReplyVersion }, 326 | { "AT0", PAR_ADPTV_TIM0, 0, 0, OnSetOK }, 327 | { "AT1", PAR_ADPTV_TIM1, 0, 0, OnSetOK }, 328 | { "AT2", PAR_ADPTV_TIM2, 0, 0, OnSetOK }, 329 | { "BD", PAR_BUFFER_DUMP, 0, 0, OnBufferDump }, 330 | { "BRD", PAR_TRY_BRD, 2, 2, OnSetValueInt }, 331 | { "BRT", PAR_SET_BRD, 2, 2, OnSetValueInt }, 332 | { "CAF0", PAR_CAN_CAF, 0, 0, OnSetValueFalse }, 333 | { "CAF1", PAR_CAN_CAF, 0, 0, OnSetValueTrue }, 334 | { "CF", PAR_CAN_CF, 3, 3, OnSetValueInt }, 335 | { "CF", PAR_CAN_CF, 8, 8, OnSetValueInt }, 336 | { "CEA", PAR_CAN_EXT, 0, 0, OnResetValueInt }, 337 | { "CEA", PAR_CAN_EXT, 2, 2, OnSetValueInt }, 338 | { "CFC0", PAR_CAN_FLOW_CONTROL, 0, 0, OnSetValueFalse }, 339 | { "CFC1", PAR_CAN_FLOW_CONTROL, 0, 0, OnSetValueTrue }, 340 | { "CM", PAR_CAN_CM, 3, 3, OnSetValueInt }, 341 | { "CM", PAR_CAN_CM, 8, 8, OnSetValueInt }, 342 | { "CP", PAR_CAN_CP, 2, 2, OnSetValueInt }, 343 | { "CRA", PAR_CAN_SET_ADDRESS, 0, 0, OnResetValueInt }, 344 | { "CRA", PAR_CAN_SET_ADDRESS, 3, 3, OnSetValueInt }, 345 | { "CRA", PAR_CAN_SET_ADDRESS, 8, 8, OnSetValueInt }, 346 | { "CS", PAR_CAN_SHOW_STATUS, 0, 0, OnCanShowStatus }, 347 | { "CSM0", PAR_CAN_MONITORING, 0, 0, OnSetValueFalse }, 348 | { "CSM1", PAR_CAN_MONITORING, 0, 0, OnSetValueTrue }, 349 | { "CV", PAR_CALIBRATE_VOLT, 4, 4, OnSetOK }, 350 | { "D", PAR_SET_DEFAULT, 0, 0, OnSetDefault }, 351 | { "D0", PAR_CAN_DLC, 0, 0, OnSetValueFalse }, 352 | { "D1", PAR_CAN_DLC, 0, 0, OnSetValueTrue }, 353 | { "DM1", PAR_J1939_DM1_MONITOR, 0, 0, OnSetOK }, 354 | { "DP", PAR_DESCRIBE_PROTOCOL, 0, 0, OnProtocolDescribe }, 355 | { "DPN", PAR_DESCRIBE_PROTCL_N, 0, 0, OnProtocolDescribeNum }, 356 | { "E0", PAR_ECHO, 0, 0, OnSetValueFalse }, 357 | { "E1", PAR_ECHO, 0, 0, OnSetValueTrue }, 358 | { "FCSD", PAR_CAN_FLOW_CTRL_DAT, 1, 5, OnSetBytes }, 359 | { "FCSH", PAR_CAN_FLOW_CTRL_HDR, 3, 3, OnSetValueInt }, 360 | { "FCSH", PAR_CAN_FLOW_CTRL_HDR, 8, 8, OnSetValueInt }, 361 | { "FCSM", PAR_CAN_FLOW_CONTROL, 1, 1, OnSetValueInt }, 362 | { "H0", PAR_HEADER_SHOW, 0, 0, OnSetValueFalse }, 363 | { "H1", PAR_HEADER_SHOW, 0, 0, OnSetValueTrue }, 364 | { "I", PAR_INFO, 0, 0, OnSendReplyInterface }, 365 | { "JE", PAR_J1939_FMT, 0, 0, OnSetValueTrue }, 366 | { "JHF0", PAR_J1939_HEADER, 0, 0, OnSetValueFalse }, 367 | { "JHF1", PAR_J1939_HEADER, 0, 0, OnSetValueTrue }, 368 | { "JS", PAR_J1939_FMT, 0, 0, OnSetValueFalse }, 369 | { "JTM1", PAR_J1939_MLTPR5, 0, 0, OnSetValueFalse }, 370 | { "JTM5", PAR_J1939_MLTPR5, 0, 0, OnSetValueTrue }, 371 | { "L0", PAR_LINEFEED, 0, 0, OnSetValueFalse }, 372 | { "LP", PAR_LOW_POWER_MODE, 0, 0, OnSetOK }, 373 | { "L1", PAR_LINEFEED, 0, 0, OnSetValueTrue }, 374 | { "M0", PAR_MEMORY, 0, 0, OnSetValueFalse }, 375 | { "M1", PAR_MEMORY, 0, 0, OnSetValueTrue }, 376 | { "MP", PAR_J1939_MONITOR, 4, 7, OnJ1939Monitor }, 377 | { "PC", PAR_PROTOCOL_CLOSE, 0, 0, OnProtocolClose }, 378 | { "R0", PAR_RESPONSES, 0, 0, OnSetValueFalse }, 379 | { "R1", PAR_RESPONSES, 0, 0, OnSetValueTrue }, 380 | { "RTR", PAR_CAN_SEND_RTR, 0, 0, OnSetOK }, 381 | { "RV", PAR_READ_VOLT, 0, 0, OnReadVoltage }, 382 | { "S0", PAR_SPACES, 0, 0, OnSetValueFalse }, 383 | { "S1", PAR_SPACES, 0, 0, OnSetValueTrue }, 384 | { "SH", PAR_HEADER_BYTES, 3, 3, OnSetBytes }, 385 | { "SH", PAR_HEADER_BYTES, 6, 6, OnSetBytes }, 386 | { "SP", PAR_PROTOCOL, 1, 2, OnSetProtocol }, 387 | { "ST", PAR_TIMEOUT, 2, 2, OnSetValueInt }, 388 | { "SW", PAR_WAKEUP_VAL, 2, 2, OnSetValueInt }, 389 | { "TA", PAR_TESTER_ADDRESS, 2, 2, OnSetValueInt }, 390 | { "TP", PAR_TRY_PROTOCOL, 1, 1, OnSetProtocol }, 391 | { "TP", PAR_TRY_PROTOCOL, 2, 2, OnSetProtocol }, 392 | { "V0", PAR_CAN_VAIDATE_DLC, 0, 0, OnSetValueFalse }, 393 | { "V1", PAR_CAN_VAIDATE_DLC, 0, 0, OnSetValueTrue }, 394 | { "WM", PAR_WM_HEADER, 1, 6, OnSetBytes }, 395 | { "WS", PAR_WARMSTART, 0, 0, OnReset }, 396 | { "Z", PAR_RESET_CPU, 0, 0, OnReset } 397 | }; 398 | 399 | static bool ValidateArgLength(const DispatchType& entry, const string& arg) 400 | { 401 | int len = arg.length(); 402 | return len >= entry.minParNum && len <= entry.maxParNum; 403 | } 404 | 405 | /** 406 | * Dispatch the AT command to the proper handler with particular type 407 | * @param[in] cmdString Command line 408 | * @return true if command was dispatched, false otherwise 409 | */ 410 | static bool DispatchATCmd(const string& cmdString, int numOfChar, int type) 411 | { 412 | // Ignore first two "AT" chars 413 | string atcmd = (type == 0) ? cmdString.substr(2) : cmdString.substr(2, numOfChar); 414 | 415 | for (int i = 0; i < sizeof(dispatchTbl)/sizeof(dispatchTbl[0]); i++) { 416 | int cmdType = (dispatchTbl[i].minParNum > 0) ? 1 : 0; 417 | 418 | if ((cmdType == type) && (atcmd == dispatchTbl[i].name)) { 419 | string arg = (type == 1) ? cmdString.substr(numOfChar + 2) : ""; 420 | 421 | // Argument length validation if we have argument 422 | if (type && !ValidateArgLength(dispatchTbl[i], arg)) { 423 | continue; 424 | } 425 | 426 | // Have callback? 427 | if (!dispatchTbl[i].callback) 428 | return false; 429 | 430 | dispatchTbl[i].callback(arg, dispatchTbl[i].id); 431 | return true; 432 | } 433 | } 434 | return false; 435 | } 436 | 437 | /** 438 | * Parse and dispatch AT sequence 439 | * @param[in] cmdString The user command 440 | * @return true if command was parsed, false otherwise 441 | */ 442 | static bool ParseGenericATCmd(const string& cmdString) 443 | { 444 | bool dispatched = DispatchATCmd(cmdString, 4, 0); // Do exact string match, like "AT#DP" 445 | if (dispatched) 446 | return true; 447 | dispatched = DispatchATCmd(cmdString, 3, 1); // Three char sequence prefixes 448 | if (dispatched) 449 | return true; 450 | return DispatchATCmd(cmdString, 2, 1); // Two char sequence prefixes 451 | } 452 | 453 | /** 454 | * Get the new command, do the processing. The "entry point" is here! 455 | * @param[in] cmdString The user command 456 | */ 457 | void AdptOnCmd(string& cmdString) 458 | { 459 | static string PreviousCmd(USER_BUF_LEN); 460 | bool succeeded = false; 461 | 462 | // Compress and convert to uppercase 463 | to_upper(cmdString); 464 | remove_space(cmdString); 465 | 466 | // Repeat the previous ? 467 | if (cmdString.empty()) { 468 | cmdString = PreviousCmd; 469 | } 470 | else { 471 | PreviousCmd = cmdString; 472 | } 473 | 474 | // Do we have AT sequence here? 475 | if (cmdString.substr(0,2) != "AT") { // Not AT sequence 476 | if (is_xdigits(cmdString)) { // Should be only digits 477 | OBDProfile::instance()->onRequest(cmdString); 478 | succeeded = true; 479 | } 480 | } 481 | else { // AT sequence 482 | succeeded = ParseGenericATCmd(cmdString); // String cmd->numeric 483 | } 484 | 485 | if (!succeeded) { 486 | AdptSendReply(ErrMessage); 487 | } 488 | AdptSendString(">"); 489 | } 490 | 491 | /** 492 | * Initialize buffers, flags and etc. 493 | */ 494 | void AdptDispatcherInit() 495 | { 496 | OnReset("", PAR_RESET_CPU); 497 | AdptSendString(">"); 498 | } 499 | 500 | /** 501 | * Send out string with 502 | * @param[in] str String to send 503 | */ 504 | void AdptSendReply(const string& str) 505 | { 506 | string s = str; 507 | if (AdapterConfig::instance()->getBoolProperty(PAR_LINEFEED)) { 508 | s += "\r\n"; 509 | AdptSendString(s); 510 | } 511 | else { 512 | s += "\r"; 513 | AdptSendString(s); 514 | } 515 | } 516 | -------------------------------------------------------------------------------- /STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_adc.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f0xx_adc.h 4 | * @author MCD Application Team 5 | * @version V1.3.0 6 | * @date 16-January-2014 7 | * @brief This file contains all the functions prototypes for the ADC firmware 8 | * library 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2014 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F0XX_ADC_H 31 | #define __STM32F0XX_ADC_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f0xx.h" 39 | 40 | /** @addtogroup STM32F0xx_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup ADC 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | 50 | /** 51 | * @brief ADC Init structure definition 52 | */ 53 | 54 | typedef struct 55 | { 56 | uint32_t ADC_Resolution; /*!< Selects the resolution of the conversion. 57 | This parameter can be a value of @ref ADC_Resolution */ 58 | 59 | FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in 60 | Continuous or Single mode. 61 | This parameter can be set to ENABLE or DISABLE. */ 62 | 63 | uint32_t ADC_ExternalTrigConvEdge; /*!< Selects the external trigger Edge and enables the 64 | trigger of a regular group. This parameter can be a value 65 | of @ref ADC_external_trigger_edge_conversion */ 66 | 67 | uint32_t ADC_ExternalTrigConv; /*!< Defines the external trigger used to start the analog 68 | to digital conversion of regular channels. This parameter 69 | can be a value of @ref ADC_external_trigger_sources_for_channels_conversion */ 70 | 71 | uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right. 72 | This parameter can be a value of @ref ADC_data_align */ 73 | 74 | uint32_t ADC_ScanDirection; /*!< Specifies in which direction the channels will be scanned 75 | in the sequence. 76 | This parameter can be a value of @ref ADC_Scan_Direction */ 77 | }ADC_InitTypeDef; 78 | 79 | 80 | /* Exported constants --------------------------------------------------------*/ 81 | 82 | /** @defgroup ADC_Exported_Constants 83 | * @{ 84 | */ 85 | #define IS_ADC_ALL_PERIPH(PERIPH) ((PERIPH) == ADC1) 86 | 87 | /** @defgroup ADC_JitterOff 88 | * @{ 89 | */ 90 | /* These defines are obsolete and maintained for legacy purpose only. They are replaced by the ADC_ClockMode */ 91 | #define ADC_JitterOff_PCLKDiv2 ADC_CFGR2_JITOFFDIV2 92 | #define ADC_JitterOff_PCLKDiv4 ADC_CFGR2_JITOFFDIV4 93 | 94 | #define IS_ADC_JITTEROFF(JITTEROFF) (((JITTEROFF) & 0x3FFFFFFF) == (uint32_t)RESET) 95 | 96 | /** 97 | * @} 98 | */ 99 | 100 | /** @defgroup ADC_ClockMode 101 | * @{ 102 | */ 103 | #define ADC_ClockMode_AsynClk ((uint32_t)0x00000000) /*!< ADC Asynchronous clock mode */ 104 | #define ADC_ClockMode_SynClkDiv2 ADC_CFGR2_CKMODE_0 /*!< Synchronous clock mode divided by 2 */ 105 | #define ADC_ClockMode_SynClkDiv4 ADC_CFGR2_CKMODE_1 /*!< Synchronous clock mode divided by 4 */ 106 | #define IS_ADC_CLOCKMODE(CLOCK) (((CLOCK) == ADC_ClockMode_AsynClk) ||\ 107 | ((CLOCK) == ADC_ClockMode_SynClkDiv2) ||\ 108 | ((CLOCK) == ADC_ClockMode_SynClkDiv4)) 109 | 110 | /** 111 | * @} 112 | */ 113 | 114 | /** @defgroup ADC_Resolution 115 | * @{ 116 | */ 117 | #define ADC_Resolution_12b ((uint32_t)0x00000000) 118 | #define ADC_Resolution_10b ADC_CFGR1_RES_0 119 | #define ADC_Resolution_8b ADC_CFGR1_RES_1 120 | #define ADC_Resolution_6b ADC_CFGR1_RES 121 | 122 | #define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \ 123 | ((RESOLUTION) == ADC_Resolution_10b) || \ 124 | ((RESOLUTION) == ADC_Resolution_8b) || \ 125 | ((RESOLUTION) == ADC_Resolution_6b)) 126 | 127 | /** 128 | * @} 129 | */ 130 | 131 | /** @defgroup ADC_external_trigger_edge_conversion 132 | * @{ 133 | */ 134 | #define ADC_ExternalTrigConvEdge_None ((uint32_t)0x00000000) 135 | #define ADC_ExternalTrigConvEdge_Rising ADC_CFGR1_EXTEN_0 136 | #define ADC_ExternalTrigConvEdge_Falling ADC_CFGR1_EXTEN_1 137 | #define ADC_ExternalTrigConvEdge_RisingFalling ADC_CFGR1_EXTEN 138 | 139 | #define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigConvEdge_None) || \ 140 | ((EDGE) == ADC_ExternalTrigConvEdge_Rising) || \ 141 | ((EDGE) == ADC_ExternalTrigConvEdge_Falling) || \ 142 | ((EDGE) == ADC_ExternalTrigConvEdge_RisingFalling)) 143 | /** 144 | * @} 145 | */ 146 | 147 | /** @defgroup ADC_external_trigger_sources_for_channels_conversion 148 | * @{ 149 | */ 150 | 151 | /* TIM1 */ 152 | #define ADC_ExternalTrigConv_T1_TRGO ((uint32_t)0x00000000) 153 | #define ADC_ExternalTrigConv_T1_CC4 ADC_CFGR1_EXTSEL_0 154 | 155 | /* TIM2 */ 156 | #define ADC_ExternalTrigConv_T2_TRGO ADC_CFGR1_EXTSEL_1 157 | 158 | /* TIM3 */ 159 | #define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_0 | ADC_CFGR1_EXTSEL_1)) 160 | 161 | /* TIM15 */ 162 | #define ADC_ExternalTrigConv_T15_TRGO ADC_CFGR1_EXTSEL_2 163 | 164 | #define IS_ADC_EXTERNAL_TRIG_CONV(CONV) (((CONV) == ADC_ExternalTrigConv_T1_TRGO) || \ 165 | ((CONV) == ADC_ExternalTrigConv_T1_CC4) || \ 166 | ((CONV) == ADC_ExternalTrigConv_T2_TRGO) || \ 167 | ((CONV) == ADC_ExternalTrigConv_T3_TRGO) || \ 168 | ((CONV) == ADC_ExternalTrigConv_T15_TRGO)) 169 | /** 170 | * @} 171 | */ 172 | 173 | /** @defgroup ADC_data_align 174 | * @{ 175 | */ 176 | 177 | #define ADC_DataAlign_Right ((uint32_t)0x00000000) 178 | #define ADC_DataAlign_Left ADC_CFGR1_ALIGN 179 | 180 | #define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \ 181 | ((ALIGN) == ADC_DataAlign_Left)) 182 | /** 183 | * @} 184 | */ 185 | 186 | /** @defgroup ADC_Scan_Direction 187 | * @{ 188 | */ 189 | 190 | #define ADC_ScanDirection_Upward ((uint32_t)0x00000000) 191 | #define ADC_ScanDirection_Backward ADC_CFGR1_SCANDIR 192 | 193 | #define IS_ADC_SCAN_DIRECTION(DIRECTION) (((DIRECTION) == ADC_ScanDirection_Upward) || \ 194 | ((DIRECTION) == ADC_ScanDirection_Backward)) 195 | /** 196 | * @} 197 | */ 198 | 199 | /** @defgroup ADC_DMA_Mode 200 | * @{ 201 | */ 202 | 203 | #define ADC_DMAMode_OneShot ((uint32_t)0x00000000) 204 | #define ADC_DMAMode_Circular ADC_CFGR1_DMACFG 205 | 206 | #define IS_ADC_DMA_MODE(MODE) (((MODE) == ADC_DMAMode_OneShot) || \ 207 | ((MODE) == ADC_DMAMode_Circular)) 208 | /** 209 | * @} 210 | */ 211 | 212 | /** @defgroup ADC_analog_watchdog_selection 213 | * @{ 214 | */ 215 | 216 | #define ADC_AnalogWatchdog_Channel_0 ((uint32_t)0x00000000) 217 | #define ADC_AnalogWatchdog_Channel_1 ((uint32_t)0x04000000) 218 | #define ADC_AnalogWatchdog_Channel_2 ((uint32_t)0x08000000) 219 | #define ADC_AnalogWatchdog_Channel_3 ((uint32_t)0x0C000000) 220 | #define ADC_AnalogWatchdog_Channel_4 ((uint32_t)0x10000000) 221 | #define ADC_AnalogWatchdog_Channel_5 ((uint32_t)0x14000000) 222 | #define ADC_AnalogWatchdog_Channel_6 ((uint32_t)0x18000000) 223 | #define ADC_AnalogWatchdog_Channel_7 ((uint32_t)0x1C000000) 224 | #define ADC_AnalogWatchdog_Channel_8 ((uint32_t)0x20000000) 225 | #define ADC_AnalogWatchdog_Channel_9 ((uint32_t)0x24000000) 226 | #define ADC_AnalogWatchdog_Channel_10 ((uint32_t)0x28000000) /*!< Not available for STM32F031 devices */ 227 | #define ADC_AnalogWatchdog_Channel_11 ((uint32_t)0x2C000000) /*!< Not available for STM32F031 devices */ 228 | #define ADC_AnalogWatchdog_Channel_12 ((uint32_t)0x30000000) /*!< Not available for STM32F031 devices */ 229 | #define ADC_AnalogWatchdog_Channel_13 ((uint32_t)0x34000000) /*!< Not available for STM32F031 devices */ 230 | #define ADC_AnalogWatchdog_Channel_14 ((uint32_t)0x38000000) /*!< Not available for STM32F031 devices */ 231 | #define ADC_AnalogWatchdog_Channel_15 ((uint32_t)0x3C000000) /*!< Not available for STM32F031 devices */ 232 | #define ADC_AnalogWatchdog_Channel_16 ((uint32_t)0x40000000) 233 | #define ADC_AnalogWatchdog_Channel_17 ((uint32_t)0x44000000) 234 | #define ADC_AnalogWatchdog_Channel_18 ((uint32_t)0x48000000) 235 | 236 | 237 | #define IS_ADC_ANALOG_WATCHDOG_CHANNEL(CHANNEL) (((CHANNEL) == ADC_AnalogWatchdog_Channel_0) || \ 238 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_1) || \ 239 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_2) || \ 240 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_3) || \ 241 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_4) || \ 242 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_5) || \ 243 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_6) || \ 244 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_7) || \ 245 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_8) || \ 246 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_9) || \ 247 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_10) || \ 248 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_11) || \ 249 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_12) || \ 250 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_13) || \ 251 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_14) || \ 252 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_15) || \ 253 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_16) || \ 254 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_17) || \ 255 | ((CHANNEL) == ADC_AnalogWatchdog_Channel_18)) 256 | /** 257 | * @} 258 | */ 259 | 260 | /** @defgroup ADC_sampling_times 261 | * @{ 262 | */ 263 | 264 | #define ADC_SampleTime_1_5Cycles ((uint32_t)0x00000000) 265 | #define ADC_SampleTime_7_5Cycles ((uint32_t)0x00000001) 266 | #define ADC_SampleTime_13_5Cycles ((uint32_t)0x00000002) 267 | #define ADC_SampleTime_28_5Cycles ((uint32_t)0x00000003) 268 | #define ADC_SampleTime_41_5Cycles ((uint32_t)0x00000004) 269 | #define ADC_SampleTime_55_5Cycles ((uint32_t)0x00000005) 270 | #define ADC_SampleTime_71_5Cycles ((uint32_t)0x00000006) 271 | #define ADC_SampleTime_239_5Cycles ((uint32_t)0x00000007) 272 | 273 | #define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_1_5Cycles) || \ 274 | ((TIME) == ADC_SampleTime_7_5Cycles) || \ 275 | ((TIME) == ADC_SampleTime_13_5Cycles) || \ 276 | ((TIME) == ADC_SampleTime_28_5Cycles) || \ 277 | ((TIME) == ADC_SampleTime_41_5Cycles) || \ 278 | ((TIME) == ADC_SampleTime_55_5Cycles) || \ 279 | ((TIME) == ADC_SampleTime_71_5Cycles) || \ 280 | ((TIME) == ADC_SampleTime_239_5Cycles)) 281 | /** 282 | * @} 283 | */ 284 | 285 | /** @defgroup ADC_thresholds 286 | * @{ 287 | */ 288 | 289 | #define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF) 290 | 291 | /** 292 | * @} 293 | */ 294 | 295 | /** @defgroup ADC_channels 296 | * @{ 297 | */ 298 | 299 | #define ADC_Channel_0 ADC_CHSELR_CHSEL0 300 | #define ADC_Channel_1 ADC_CHSELR_CHSEL1 301 | #define ADC_Channel_2 ADC_CHSELR_CHSEL2 302 | #define ADC_Channel_3 ADC_CHSELR_CHSEL3 303 | #define ADC_Channel_4 ADC_CHSELR_CHSEL4 304 | #define ADC_Channel_5 ADC_CHSELR_CHSEL5 305 | #define ADC_Channel_6 ADC_CHSELR_CHSEL6 306 | #define ADC_Channel_7 ADC_CHSELR_CHSEL7 307 | #define ADC_Channel_8 ADC_CHSELR_CHSEL8 308 | #define ADC_Channel_9 ADC_CHSELR_CHSEL9 309 | #define ADC_Channel_10 ADC_CHSELR_CHSEL10 /*!< Not available for STM32F031 devices */ 310 | #define ADC_Channel_11 ADC_CHSELR_CHSEL11 /*!< Not available for STM32F031 devices */ 311 | #define ADC_Channel_12 ADC_CHSELR_CHSEL12 /*!< Not available for STM32F031 devices */ 312 | #define ADC_Channel_13 ADC_CHSELR_CHSEL13 /*!< Not available for STM32F031 devices */ 313 | #define ADC_Channel_14 ADC_CHSELR_CHSEL14 /*!< Not available for STM32F031 devices */ 314 | #define ADC_Channel_15 ADC_CHSELR_CHSEL15 /*!< Not available for STM32F031 devices */ 315 | #define ADC_Channel_16 ADC_CHSELR_CHSEL16 316 | #define ADC_Channel_17 ADC_CHSELR_CHSEL17 317 | #define ADC_Channel_18 ADC_CHSELR_CHSEL18 /*!< Not available for STM32F030 devices */ 318 | 319 | #define ADC_Channel_TempSensor ((uint32_t)ADC_Channel_16) 320 | #define ADC_Channel_Vrefint ((uint32_t)ADC_Channel_17) 321 | #define ADC_Channel_Vbat ((uint32_t)ADC_Channel_18) /*!< Not available for STM32F030 devices */ 322 | 323 | #define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) != (uint32_t)RESET) && (((CHANNEL) & 0xFFF80000) == (uint32_t)RESET)) 324 | 325 | /** 326 | * @} 327 | */ 328 | 329 | /** @defgroup ADC_interrupts_definition 330 | * @{ 331 | */ 332 | 333 | #define ADC_IT_ADRDY ADC_IER_ADRDYIE 334 | #define ADC_IT_EOSMP ADC_IER_EOSMPIE 335 | #define ADC_IT_EOC ADC_IER_EOCIE 336 | #define ADC_IT_EOSEQ ADC_IER_EOSEQIE 337 | #define ADC_IT_OVR ADC_IER_OVRIE 338 | #define ADC_IT_AWD ADC_IER_AWDIE 339 | 340 | #define IS_ADC_CONFIG_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFFFF60) == (uint32_t)RESET)) 341 | 342 | #define IS_ADC_GET_IT(IT) (((IT) == ADC_IT_ADRDY) || ((IT) == ADC_IT_EOSMP) || \ 343 | ((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_EOSEQ) || \ 344 | ((IT) == ADC_IT_OVR) || ((IT) == ADC_IT_AWD)) 345 | 346 | #define IS_ADC_CLEAR_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFFFF60) == (uint32_t)RESET)) 347 | 348 | /** 349 | * @} 350 | */ 351 | 352 | /** @defgroup ADC_flags_definition 353 | * @{ 354 | */ 355 | 356 | #define ADC_FLAG_ADRDY ADC_ISR_ADRDY 357 | #define ADC_FLAG_EOSMP ADC_ISR_EOSMP 358 | #define ADC_FLAG_EOC ADC_ISR_EOC 359 | #define ADC_FLAG_EOSEQ ADC_ISR_EOSEQ 360 | #define ADC_FLAG_OVR ADC_ISR_OVR 361 | #define ADC_FLAG_AWD ADC_ISR_AWD 362 | 363 | #define ADC_FLAG_ADEN ((uint32_t)0x01000001) 364 | #define ADC_FLAG_ADDIS ((uint32_t)0x01000002) 365 | #define ADC_FLAG_ADSTART ((uint32_t)0x01000004) 366 | #define ADC_FLAG_ADSTP ((uint32_t)0x01000010) 367 | #define ADC_FLAG_ADCAL ((uint32_t)0x81000000) 368 | 369 | #define IS_ADC_CLEAR_FLAG(FLAG) (((FLAG) != (uint32_t)RESET) && (((FLAG) & 0xFFFFFF60) == (uint32_t)RESET)) 370 | 371 | #define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_ADRDY) || ((FLAG) == ADC_FLAG_EOSMP) || \ 372 | ((FLAG) == ADC_FLAG_EOC) || ((FLAG) == ADC_FLAG_EOSEQ) || \ 373 | ((FLAG) == ADC_FLAG_AWD) || ((FLAG) == ADC_FLAG_OVR) || \ 374 | ((FLAG) == ADC_FLAG_ADEN) || ((FLAG) == ADC_FLAG_ADDIS) || \ 375 | ((FLAG) == ADC_FLAG_ADSTART) || ((FLAG) == ADC_FLAG_ADSTP) || \ 376 | ((FLAG) == ADC_FLAG_ADCAL)) 377 | /** 378 | * @} 379 | */ 380 | 381 | /** 382 | * @} 383 | */ 384 | 385 | /* Exported macro ------------------------------------------------------------*/ 386 | /* Exported functions ------------------------------------------------------- */ 387 | 388 | /* Function used to set the ADC configuration to the default reset state *****/ 389 | void ADC_DeInit(ADC_TypeDef* ADCx); 390 | 391 | /* Initialization and Configuration functions *********************************/ 392 | void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); 393 | void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); 394 | void ADC_ClockModeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ClockMode); 395 | void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); 396 | /* This Function is obsolete and maintained for legacy purpose only. 397 | ADC_ClockModeConfig() function should be used instead */ 398 | void ADC_JitterCmd(ADC_TypeDef* ADCx, uint32_t ADC_JitterOff, FunctionalState NewState); 399 | 400 | /* Power saving functions *****************************************************/ 401 | void ADC_AutoPowerOffCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 402 | void ADC_WaitModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 403 | 404 | /* Analog Watchdog configuration functions ************************************/ 405 | void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 406 | void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold); 407 | void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog_Channel); 408 | void ADC_AnalogWatchdogSingleChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 409 | 410 | /* Temperature Sensor , Vrefint and Vbat management function ******************/ 411 | void ADC_TempSensorCmd(FunctionalState NewState); 412 | void ADC_VrefintCmd(FunctionalState NewState); 413 | void ADC_VbatCmd(FunctionalState NewState); /*!< Not applicable for STM32F030 devices */ 414 | 415 | /* Channels Configuration functions *******************************************/ 416 | void ADC_ChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_Channel, uint32_t ADC_SampleTime); 417 | void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 418 | void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 419 | void ADC_OverrunModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); 420 | uint32_t ADC_GetCalibrationFactor(ADC_TypeDef* ADCx); 421 | void ADC_StopOfConversion(ADC_TypeDef* ADCx); 422 | void ADC_StartOfConversion(ADC_TypeDef* ADCx); 423 | uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); 424 | 425 | /* Regular Channels DMA Configuration functions *******************************/ 426 | void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); 427 | void ADC_DMARequestModeConfig(ADC_TypeDef* ADCx, uint32_t ADC_DMARequestMode); 428 | 429 | /* Interrupts and flags management functions **********************************/ 430 | void ADC_ITConfig(ADC_TypeDef* ADCx, uint32_t ADC_IT, FunctionalState NewState); 431 | FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG); 432 | void ADC_ClearFlag(ADC_TypeDef* ADCx, uint32_t ADC_FLAG); 433 | ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint32_t ADC_IT); 434 | void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint32_t ADC_IT); 435 | 436 | #ifdef __cplusplus 437 | } 438 | #endif 439 | 440 | #endif /*__STM32F0XX_ADC_H */ 441 | 442 | /** 443 | * @} 444 | */ 445 | 446 | /** 447 | * @} 448 | */ 449 | 450 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 451 | -------------------------------------------------------------------------------- /STM32F0xx_StdPeriph_Driver/src/stm32f0xx_gpio.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f0xx_gpio.c 4 | * @author MCD Application Team 5 | * @version V1.3.0 6 | * @date 16-January-2014 7 | * @brief This file provides firmware functions to manage the following 8 | * functionalities of the GPIO peripheral: 9 | * + Initialization and Configuration functions 10 | * + GPIO Read and Write functions 11 | * + GPIO Alternate functions configuration functions 12 | * 13 | * @verbatim 14 | * 15 | * 16 | =========================================================================== 17 | ##### How to use this driver ##### 18 | =========================================================================== 19 | [..] 20 | (#) Enable the GPIO AHB clock using RCC_AHBPeriphClockCmd() 21 | (#) Configure the GPIO pin(s) using GPIO_Init() 22 | Four possible configuration are available for each pin: 23 | (++) Input: Floating, Pull-up, Pull-down. 24 | (++) Output: Push-Pull (Pull-up, Pull-down or no Pull) 25 | Open Drain (Pull-up, Pull-down or no Pull). 26 | In output mode, the speed is configurable: Low, Medium, Fast or High. 27 | (++) Alternate Function: Push-Pull (Pull-up, Pull-down or no Pull) 28 | Open Drain (Pull-up, Pull-down or no Pull). 29 | (++) Analog: required mode when a pin is to be used as ADC channel, 30 | DAC output or comparator input. 31 | (#) Peripherals alternate function: 32 | (++) For ADC, DAC and comparators, configure the desired pin in analog 33 | mode using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN 34 | (++) For other peripherals (TIM, USART...): 35 | (+++) Connect the pin to the desired peripherals' Alternate 36 | Function (AF) using GPIO_PinAFConfig() function. For PortC, 37 | PortD and PortF, no configuration is needed. 38 | (+++) Configure the desired pin in alternate function mode using 39 | GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF 40 | (+++) Select the type, pull-up/pull-down and output speed via 41 | GPIO_PuPd, GPIO_OType and GPIO_Speed members 42 | (+++) Call GPIO_Init() function 43 | (#) To get the level of a pin configured in input mode use GPIO_ReadInputDataBit() 44 | (#) To set/reset the level of a pin configured in output mode use 45 | GPIO_SetBits()/GPIO_ResetBits() 46 | (#) During and just after reset, the alternate functions are not active and 47 | the GPIO pins are configured in input floating mode (except JTAG pins). 48 | (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as 49 | general-purpose (PC14 and PC15, respectively) when the LSE oscillator 50 | is off. The LSE has priority over the GPIO function. 51 | (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as general-purpose 52 | PD0 and PD1, respectively, when the HSE oscillator is off. The HSE has 53 | priority over the GPIO function. 54 | @endverbatim 55 | ****************************************************************************** 56 | * @attention 57 | * 58 | *

© COPYRIGHT 2014 STMicroelectronics

59 | * 60 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 61 | * You may not use this file except in compliance with the License. 62 | * You may obtain a copy of the License at: 63 | * 64 | * http://www.st.com/software_license_agreement_liberty_v2 65 | * 66 | * Unless required by applicable law or agreed to in writing, software 67 | * distributed under the License is distributed on an "AS IS" BASIS, 68 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 69 | * See the License for the specific language governing permissions and 70 | * limitations under the License. 71 | * 72 | ****************************************************************************** 73 | */ 74 | 75 | /* Includes ------------------------------------------------------------------*/ 76 | #include "stm32f0xx_gpio.h" 77 | #include "stm32f0xx_rcc.h" 78 | 79 | /** @addtogroup STM32F0xx_StdPeriph_Driver 80 | * @{ 81 | */ 82 | 83 | /** @defgroup GPIO 84 | * @brief GPIO driver modules 85 | * @{ 86 | */ 87 | 88 | #define assert_param(expr) ((void)0) 89 | 90 | /* Private typedef -----------------------------------------------------------*/ 91 | /* Private define ------------------------------------------------------------*/ 92 | /* Private macro -------------------------------------------------------------*/ 93 | /* Private variables ---------------------------------------------------------*/ 94 | /* Private function prototypes -----------------------------------------------*/ 95 | /* Private functions ---------------------------------------------------------*/ 96 | 97 | /** @defgroup GPIO_Private_Functions 98 | * @{ 99 | */ 100 | 101 | /** @defgroup GPIO_Group1 Initialization and Configuration 102 | * @brief Initialization and Configuration 103 | * 104 | @verbatim 105 | =============================================================================== 106 | ##### Initialization and Configuration ##### 107 | =============================================================================== 108 | 109 | @endverbatim 110 | * @{ 111 | */ 112 | 113 | /** 114 | * @brief Deinitializes the GPIOx peripheral registers to their default reset 115 | * values. 116 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 117 | * @note GPIOE is available only for STM32F072. 118 | * @note GPIOD is not available for STM32F031. 119 | * @retval None 120 | */ 121 | void GPIO_DeInit(GPIO_TypeDef* GPIOx) 122 | { 123 | /* Check the parameters */ 124 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 125 | 126 | if(GPIOx == GPIOA) 127 | { 128 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, ENABLE); 129 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, DISABLE); 130 | } 131 | else if(GPIOx == GPIOB) 132 | { 133 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, ENABLE); 134 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, DISABLE); 135 | } 136 | else if(GPIOx == GPIOC) 137 | { 138 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, ENABLE); 139 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, DISABLE); 140 | } 141 | else if(GPIOx == GPIOD) 142 | { 143 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, ENABLE); 144 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, DISABLE); 145 | } 146 | else if(GPIOx == GPIOE) 147 | { 148 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOE, ENABLE); 149 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOE, DISABLE); 150 | } 151 | else 152 | { 153 | if(GPIOx == GPIOF) 154 | { 155 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOF, ENABLE); 156 | RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOF, DISABLE); 157 | } 158 | } 159 | } 160 | 161 | /** 162 | * @brief Initializes the GPIOx peripheral according to the specified 163 | * parameters in the GPIO_InitStruct. 164 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 165 | * @note GPIOE is available only for STM32F072. 166 | * @note GPIOD is not available for STM32F031. 167 | * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains 168 | * the configuration information for the specified GPIO peripheral. 169 | * @retval None 170 | */ 171 | void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) 172 | { 173 | uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00; 174 | 175 | /* Check the parameters */ 176 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 177 | assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); 178 | assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); 179 | assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd)); 180 | 181 | /*-------------------------- Configure the port pins -----------------------*/ 182 | /*-- GPIO Mode Configuration --*/ 183 | for (pinpos = 0x00; pinpos < 0x10; pinpos++) 184 | { 185 | pos = ((uint32_t)0x01) << pinpos; 186 | 187 | /* Get the port pins position */ 188 | currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; 189 | 190 | if (currentpin == pos) 191 | { 192 | if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF)) 193 | { 194 | /* Check Speed mode parameters */ 195 | assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); 196 | 197 | /* Speed mode configuration */ 198 | GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2)); 199 | GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2)); 200 | 201 | /* Check Output mode parameters */ 202 | assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType)); 203 | 204 | /* Output mode configuration */ 205 | GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)); 206 | GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos)); 207 | } 208 | 209 | GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2)); 210 | 211 | GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2)); 212 | 213 | /* Pull-up Pull down resistor configuration */ 214 | GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2)); 215 | GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2)); 216 | } 217 | } 218 | } 219 | 220 | /** 221 | * @brief Fills each GPIO_InitStruct member with its default value. 222 | * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure which will 223 | * be initialized. 224 | * @retval None 225 | */ 226 | void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) 227 | { 228 | /* Reset GPIO init structure parameters values */ 229 | GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; 230 | GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN; 231 | GPIO_InitStruct->GPIO_Speed = GPIO_Speed_Level_2; 232 | GPIO_InitStruct->GPIO_OType = GPIO_OType_PP; 233 | GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL; 234 | } 235 | 236 | /** 237 | * @brief Locks GPIO Pins configuration registers. 238 | * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, 239 | * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. 240 | * @note The configuration of the locked GPIO pins can no longer be modified 241 | * until the next device reset. 242 | * @param GPIOx: where x can be (A or B) to select the GPIO peripheral. 243 | * @param GPIO_Pin: specifies the port bit to be written. 244 | * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). 245 | * @retval None 246 | */ 247 | void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 248 | { 249 | __IO uint32_t tmp = 0x00010000; 250 | 251 | /* Check the parameters */ 252 | assert_param(IS_GPIO_LIST_PERIPH(GPIOx)); 253 | assert_param(IS_GPIO_PIN(GPIO_Pin)); 254 | 255 | tmp |= GPIO_Pin; 256 | /* Set LCKK bit */ 257 | GPIOx->LCKR = tmp; 258 | /* Reset LCKK bit */ 259 | GPIOx->LCKR = GPIO_Pin; 260 | /* Set LCKK bit */ 261 | GPIOx->LCKR = tmp; 262 | /* Read LCKK bit */ 263 | tmp = GPIOx->LCKR; 264 | /* Read LCKK bit */ 265 | tmp = GPIOx->LCKR; 266 | } 267 | 268 | /** 269 | * @} 270 | */ 271 | 272 | /** @defgroup GPIO_Group2 GPIO Read and Write 273 | * @brief GPIO Read and Write 274 | * 275 | @verbatim 276 | =============================================================================== 277 | ##### GPIO Read and Write ##### 278 | =============================================================================== 279 | 280 | @endverbatim 281 | * @{ 282 | */ 283 | 284 | /** 285 | * @brief Reads the specified input port pin. 286 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 287 | * @note GPIOE is available only for STM32F072. 288 | * @note GPIOD is not available for STM32F031. 289 | * @param GPIO_Pin: specifies the port bit to read. 290 | * @note This parameter can be GPIO_Pin_x where x can be: 291 | * For STM32F051 and STM32F030: (0..15) for GPIOA, GPIOB, GPIOC, (2) for GPIOD and (0..1, 4..7) for GIIOF. 292 | * For STM32F072: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF. 293 | * For STM32F031: (0..15) for GPIOA, GPIOB, (13..15) for GPIOC and (0..1, 6..7) for GPIOF. 294 | * @retval The input port pin value. 295 | */ 296 | uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 297 | { 298 | uint8_t bitstatus = 0x00; 299 | 300 | /* Check the parameters */ 301 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 302 | assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); 303 | 304 | if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) 305 | { 306 | bitstatus = (uint8_t)Bit_SET; 307 | } 308 | else 309 | { 310 | bitstatus = (uint8_t)Bit_RESET; 311 | } 312 | return bitstatus; 313 | } 314 | 315 | /** 316 | * @brief Reads the specified input port pin. 317 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 318 | * @note GPIOE is available only for STM32F072. 319 | * @note GPIOD is not available for STM32F031. 320 | * @retval The input port pin value. 321 | */ 322 | uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) 323 | { 324 | /* Check the parameters */ 325 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 326 | 327 | return ((uint16_t)GPIOx->IDR); 328 | } 329 | 330 | /** 331 | * @brief Reads the specified output data port bit. 332 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 333 | * @note GPIOE is available only for STM32F072. 334 | * @note GPIOD is not available for STM32F031. 335 | * @param GPIO_Pin: Specifies the port bit to read. 336 | * @note This parameter can be GPIO_Pin_x where x can be: 337 | * For STM32F051 and STM32F030: (0..15) for GPIOA, GPIOB, GPIOC, (2) for GPIOD and (0..1, 4..7) for GIIOF. 338 | * For STM32F072: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF. 339 | * For STM32F031: (0..15) for GPIOA, GPIOB, (13..15) for GPIOC and (0..1, 6..7) for GPIOF. 340 | * @retval The output port pin value. 341 | */ 342 | uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 343 | { 344 | uint8_t bitstatus = 0x00; 345 | 346 | /* Check the parameters */ 347 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 348 | assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); 349 | 350 | if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET) 351 | { 352 | bitstatus = (uint8_t)Bit_SET; 353 | } 354 | else 355 | { 356 | bitstatus = (uint8_t)Bit_RESET; 357 | } 358 | return bitstatus; 359 | } 360 | 361 | /** 362 | * @brief Reads the specified GPIO output data port. 363 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 364 | * @note GPIOE is available only for STM32F072. 365 | * @note GPIOD is not available for STM32F031. 366 | * @retval GPIO output data port value. 367 | */ 368 | uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) 369 | { 370 | /* Check the parameters */ 371 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 372 | 373 | return ((uint16_t)GPIOx->ODR); 374 | } 375 | 376 | /** 377 | * @brief Sets the selected data port bits. 378 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 379 | * @note GPIOE is available only for STM32F072. 380 | * @note GPIOD is not available for STM32F031. 381 | * @param GPIO_Pin: specifies the port bits to be written. 382 | * @note This parameter can be GPIO_Pin_x where x can be: 383 | * For STM32F051 and STM32F030: (0..15) for GPIOA, GPIOB, GPIOC, (2) for GPIOD and (0..1, 4..7) for GIIOF. 384 | * For STM32F072: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF. 385 | * For STM32F031: (0..15) for GPIOA, GPIOB, (13..15) for GPIOC and (0..1, 6..7) for GPIOF. 386 | * @retval None 387 | */ 388 | void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 389 | { 390 | /* Check the parameters */ 391 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 392 | assert_param(IS_GPIO_PIN(GPIO_Pin)); 393 | 394 | GPIOx->BSRR = GPIO_Pin; 395 | } 396 | 397 | /** 398 | * @brief Clears the selected data port bits. 399 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 400 | * @note GPIOE is available only for STM32F072. 401 | * @note GPIOD is not available for STM32F031. 402 | * @param GPIO_Pin: specifies the port bits to be written. 403 | * @note This parameter can be GPIO_Pin_x where x can be: 404 | * For STM32F051 and STM32F030: (0..15) for GPIOA, GPIOB, GPIOC, (2) for GPIOD and (0..1, 4..7) for GIIOF. 405 | * For STM32F072: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF. 406 | * For STM32F031: (0..15) for GPIOA, GPIOB, (13..15) for GPIOC and (0..1, 6..7) for GPIOF. 407 | * @retval None 408 | */ 409 | void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 410 | { 411 | /* Check the parameters */ 412 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 413 | assert_param(IS_GPIO_PIN(GPIO_Pin)); 414 | 415 | GPIOx->BRR = GPIO_Pin; 416 | } 417 | 418 | /** 419 | * @brief Sets or clears the selected data port bit. 420 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 421 | * @note GPIOE is available only for STM32F072. 422 | * @note GPIOD is not available for STM32F031. 423 | * @param GPIO_Pin: specifies the port bit to be written. 424 | * @param BitVal: specifies the value to be written to the selected bit. 425 | * This parameter can be one of the BitAction enumeration values: 426 | * @arg Bit_RESET: to clear the port pin 427 | * @arg Bit_SET: to set the port pin 428 | * @note This parameter can be GPIO_Pin_x where x can be: 429 | * For STM32F051 and STM32F030: (0..15) for GPIOA, GPIOB, GPIOC, (2) for GPIOD and (0..1, 4..7) for GIIOF. 430 | * For STM32F072: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF. 431 | * For STM32F031: (0..15) for GPIOA, GPIOB, (13..15) for GPIOC and (0..1, 6..7) for GPIOF. 432 | * @retval None 433 | */ 434 | void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) 435 | { 436 | /* Check the parameters */ 437 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 438 | assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); 439 | assert_param(IS_GPIO_BIT_ACTION(BitVal)); 440 | 441 | if (BitVal != Bit_RESET) 442 | { 443 | GPIOx->BSRR = GPIO_Pin; 444 | } 445 | else 446 | { 447 | GPIOx->BRR = GPIO_Pin ; 448 | } 449 | } 450 | 451 | /** 452 | * @brief Writes data to the specified GPIO data port. 453 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 454 | * @note GPIOE is available only for STM32F072. 455 | * @note GPIOD is not available for STM32F031. 456 | * @param PortVal: specifies the value to be written to the port output data register. 457 | * @retval None 458 | */ 459 | void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) 460 | { 461 | /* Check the parameters */ 462 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 463 | 464 | GPIOx->ODR = PortVal; 465 | } 466 | 467 | /** 468 | * @} 469 | */ 470 | 471 | /** @defgroup GPIO_Group3 GPIO Alternate functions configuration functions 472 | * @brief GPIO Alternate functions configuration functions 473 | * 474 | @verbatim 475 | =============================================================================== 476 | ##### GPIO Alternate functions configuration functions ##### 477 | =============================================================================== 478 | 479 | @endverbatim 480 | * @{ 481 | */ 482 | 483 | /** 484 | * @brief Writes data to the specified GPIO data port. 485 | * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral. 486 | * @note GPIOC, GPIOD, GPIOE and GPIOF are available only for STM32F072. 487 | * @param GPIO_PinSource: specifies the pin for the Alternate function. 488 | * This parameter can be GPIO_PinSourcex where x can be (0..15) for GPIOA, GPIOB, GPIOD, GPIOE 489 | * and (0..12) for GPIOC and (0, 2..5, 9..10) for GPIOF. 490 | * @param GPIO_AF: selects the pin to used as Alternate function. 491 | * This parameter can be one of the following value: 492 | * @arg GPIO_AF_0: WKUP, EVENTOUT, TIM15, SPI1, TIM17, MCO, SWDAT, SWCLK, 493 | * TIM14, BOOT, USART1, CEC, IR_OUT, SPI2, TIM3, USART4, 494 | * CAN, USART2, CRS, TIM16, TIM1, TS 495 | * @arg GPIO_AF_1: USART2, CEC, TIM3, USART1, USART2, EVENTOUT, I2C1, 496 | * I2C2, TIM15, SPI2, USART3, TS, SPI1 497 | * @arg GPIO_AF_2: TIM2, TIM1, EVENTOUT, TIM16, TIM17, USB 498 | * @arg GPIO_AF_3: TS, I2C1, TIM15, EVENTOUT 499 | * @arg GPIO_AF_4: TIM14, USART4, USART3, CRS, CAN 500 | * @arg GPIO_AF_5: TIM16, TIM17, TIM15, SPI2, I2C2 501 | * @arg GPIO_AF_6: EVENTOUT 502 | * @arg GPIO_AF_7: COMP1 OUT, COMP2 OUT 503 | * @note The pin should already been configured in Alternate Function mode(AF) 504 | * using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF 505 | * @note Refer to the Alternate function mapping table in the device datasheet 506 | * for the detailed mapping of the system and peripherals'alternate 507 | * function I/O pins. 508 | * @retval None 509 | */ 510 | void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) 511 | { 512 | uint32_t temp = 0x00; 513 | uint32_t temp_2 = 0x00; 514 | 515 | /* Check the parameters */ 516 | assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 517 | assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); 518 | assert_param(IS_GPIO_AF(GPIO_AF)); 519 | 520 | temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)); 521 | GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)); 522 | temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp; 523 | GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2; 524 | } 525 | 526 | /** 527 | * @} 528 | */ 529 | 530 | /** 531 | * @} 532 | */ 533 | 534 | /** 535 | * @} 536 | */ 537 | 538 | /** 539 | * @} 540 | */ 541 | 542 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 543 | -------------------------------------------------------------------------------- /elm329.uvoptx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1.0 5 | 6 |
### uVision Project, (C) Keil Software
7 | 8 | 9 | *.c 10 | *.s*; *.src; *.a* 11 | *.obj 12 | *.lib 13 | *.txt; *.h; *.inc 14 | *.plm 15 | *.cpp 16 | 17 | 18 | 19 | 0 20 | 0 21 | 22 | 23 | 24 | adapter 25 | 0x4 26 | ARM-ADS 27 | 28 | 12000000 29 | 30 | 1 31 | 1 32 | 0 33 | 1 34 | 35 | 36 | 1 37 | 65535 38 | 0 39 | 0 40 | 0 41 | 42 | 43 | 79 44 | 66 45 | 8 46 | .\Listings\ 47 | 48 | 49 | 1 50 | 1 51 | 1 52 | 0 53 | 1 54 | 1 55 | 0 56 | 1 57 | 0 58 | 0 59 | 0 60 | 0 61 | 62 | 63 | 1 64 | 1 65 | 1 66 | 1 67 | 1 68 | 1 69 | 1 70 | 0 71 | 0 72 | 73 | 74 | 1 75 | 0 76 | 1 77 | 78 | 18 79 | 80 | 0 81 | 1 82 | 1 83 | 1 84 | 1 85 | 1 86 | 1 87 | 1 88 | 1 89 | 1 90 | 0 91 | 1 92 | 1 93 | 1 94 | 0 95 | 1 96 | 1 97 | 1 98 | 1 99 | 0 100 | 0 101 | 11 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | STLink\ST-LINKIII-KEIL_SWO.dll 113 | 114 | 115 | 116 | 0 117 | DLGTARM 118 | (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0) 119 | 120 | 121 | 0 122 | ARMDBGFLAGS 123 | 124 | 125 | 126 | 0 127 | DLGUARM 128 | (105=-1,-1,-1,-1,0) 129 | 130 | 131 | 0 132 | ST-LINKIII-KEIL_SWO 133 | -U-O206 -O8398 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(0BB11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F0xx_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32F042K6$Flash\STM32F0xx_32.FLM) 134 | 135 | 136 | 0 137 | UL2CM3 138 | UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32F0xx_32 -FL08000 -FS08000000 -FP0($$Device:STM32F042K6$Flash\STM32F0xx_32.FLM) 139 | 140 | 141 | 142 | 143 | 0 144 | 0 145 | 106 146 | 1 147 |
134218260
148 | 0 149 | 0 150 | 0 151 | 0 152 | 0 153 | 1 154 | .\src\adapter\adapter.cpp 155 | 156 | 157 |
158 | 159 | 1 160 | 0 161 | 24 162 | 1 163 |
0
164 | 0 165 | 0 166 | 0 167 | 0 168 | 0 169 | 0 170 | .\src\drv\stm32f0xx\led.cpp 171 | 172 | 173 |
174 |
175 | 176 | 177 | 0 178 | 1 179 | SystemCoreClock,0x0A 180 | 181 | 182 | 1 183 | 1 184 | SystemCoreClock 185 | 186 | 187 | 2 188 | 1 189 | abc 190 | 191 | 192 | 3 193 | 1 194 | uid 195 | 196 | 197 | 4 198 | 1 199 | SystemCoreClock 200 | 201 | 202 | 5 203 | 1 204 | pinpos 205 | 206 | 207 | 6 208 | 1 209 | ch 210 | 211 | 212 | 7 213 | 1 214 | ((uint32_t)8000000) 215 | 216 | 217 | 218 | 219 | 1 220 | 8 221 | 0x20000c38 222 | 0 223 | 224 | 225 | 226 | 227 | 2 228 | 2 229 | uidBlock 230 | 0 231 | 232 | 233 | 234 | 0 235 | 236 | 237 | 0 238 | 1 239 | 0 240 | 0 241 | 0 242 | 0 243 | 0 244 | 1 245 | 0 246 | 0 247 | 0 248 | 0 249 | 0 250 | 0 251 | 0 252 | 0 253 | 0 254 | 0 255 | 0 256 | 0 257 | 0 258 | 0 259 | 0 260 | 0 261 | 262 | 263 | 264 | 265 | 266 | System Viewer\CAN 267 | 35905 268 | 269 | 270 | System Viewer\GPIOA 271 | 35904 272 | 273 | 274 | System Viewer\RCC 275 | 35903 276 | 277 | 278 |
279 |
280 | 281 | 282 | app 283 | 1 284 | 0 285 | 0 286 | 0 287 | 288 | 1 289 | 1 290 | 8 291 | 0 292 | 0 293 | 0 294 | 0 295 | .\src\adapter\adapter.cpp 296 | adapter.cpp 297 | 0 298 | 0 299 | 300 | 301 | 1 302 | 2 303 | 8 304 | 0 305 | 0 306 | 0 307 | 0 308 | .\src\adapter\adapterconfig.cpp 309 | adapterconfig.cpp 310 | 0 311 | 0 312 | 313 | 314 | 1 315 | 3 316 | 8 317 | 0 318 | 0 319 | 0 320 | 0 321 | .\src\util\algorithms.cpp 322 | algorithms.cpp 323 | 0 324 | 0 325 | 326 | 327 | 1 328 | 4 329 | 8 330 | 0 331 | 0 332 | 0 333 | 0 334 | .\src\util\canmsgbuffer.cpp 335 | canmsgbuffer.cpp 336 | 0 337 | 0 338 | 339 | 340 | 1 341 | 5 342 | 8 343 | 0 344 | 0 345 | 0 346 | 0 347 | .\src\adapter\dispatcher.cpp 348 | dispatcher.cpp 349 | 0 350 | 0 351 | 352 | 353 | 1 354 | 6 355 | 8 356 | 0 357 | 0 358 | 0 359 | 0 360 | .\src\adapter\functions.cpp 361 | functions.cpp 362 | 0 363 | 0 364 | 365 | 366 | 1 367 | 7 368 | 8 369 | 0 370 | 0 371 | 0 372 | 0 373 | .\src\util\lstring.cpp 374 | lstring.cpp 375 | 0 376 | 0 377 | 378 | 379 | 380 | 381 | driver 382 | 1 383 | 0 384 | 0 385 | 0 386 | 387 | 2 388 | 8 389 | 8 390 | 0 391 | 0 392 | 0 393 | 0 394 | .\src\drv\stm32f0xx\AdcSTM32F0xx.cpp 395 | AdcSTM32F0xx.cpp 396 | 0 397 | 0 398 | 399 | 400 | 2 401 | 9 402 | 8 403 | 0 404 | 0 405 | 0 406 | 0 407 | .\src\drv\stm32f0xx\CanDriverSTM32F0xx.cpp 408 | CanDriverSTM32F0xx.cpp 409 | 0 410 | 0 411 | 412 | 413 | 2 414 | 10 415 | 8 416 | 0 417 | 0 418 | 0 419 | 0 420 | .\src\drv\stm32f0xx\CmdUartSTM32F0xx.cpp 421 | CmdUartSTM32F0xx.cpp 422 | 0 423 | 0 424 | 425 | 426 | 2 427 | 11 428 | 8 429 | 0 430 | 0 431 | 0 432 | 0 433 | .\src\drv\stm32f0xx\GpioDrvSTM32F0xx.cpp 434 | GpioDrvSTM32F0xx.cpp 435 | 0 436 | 0 437 | 438 | 439 | 2 440 | 12 441 | 8 442 | 0 443 | 0 444 | 0 445 | 0 446 | .\src\drv\stm32f0xx\SysutilitySTM32F0xx.cpp 447 | SysutilitySTM32F0xx.cpp 448 | 0 449 | 0 450 | 451 | 452 | 2 453 | 13 454 | 8 455 | 0 456 | 0 457 | 0 458 | 0 459 | .\src\drv\stm32f0xx\TimerSTM32F0xx.cpp 460 | TimerSTM32F0xx.cpp 461 | 0 462 | 0 463 | 464 | 465 | 2 466 | 14 467 | 8 468 | 0 469 | 0 470 | 0 471 | 0 472 | .\src\drv\stm32f0xx\led.cpp 473 | led.cpp 474 | 0 475 | 0 476 | 477 | 478 | 2 479 | 15 480 | 1 481 | 0 482 | 0 483 | 0 484 | 0 485 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_gpio.c 486 | stm32f0xx_gpio.c 487 | 0 488 | 0 489 | 490 | 491 | 2 492 | 16 493 | 1 494 | 0 495 | 0 496 | 0 497 | 0 498 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_rcc.c 499 | stm32f0xx_rcc.c 500 | 0 501 | 0 502 | 503 | 504 | 2 505 | 17 506 | 1 507 | 0 508 | 0 509 | 0 510 | 0 511 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_tim.c 512 | stm32f0xx_tim.c 513 | 0 514 | 0 515 | 516 | 517 | 2 518 | 18 519 | 1 520 | 0 521 | 0 522 | 0 523 | 0 524 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_usart.c 525 | stm32f0xx_usart.c 526 | 0 527 | 0 528 | 529 | 530 | 2 531 | 19 532 | 1 533 | 0 534 | 0 535 | 0 536 | 0 537 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_can.c 538 | stm32f0xx_can.c 539 | 0 540 | 0 541 | 542 | 543 | 2 544 | 20 545 | 1 546 | 0 547 | 0 548 | 0 549 | 0 550 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_adc.c 551 | stm32f0xx_adc.c 552 | 0 553 | 0 554 | 555 | 556 | 557 | 558 | obd 559 | 1 560 | 0 561 | 0 562 | 0 563 | 564 | 3 565 | 21 566 | 8 567 | 0 568 | 0 569 | 0 570 | 0 571 | .\src\adapter\obd\autoadapter.cpp 572 | autoadapter.cpp 573 | 0 574 | 0 575 | 576 | 577 | 3 578 | 22 579 | 8 580 | 0 581 | 0 582 | 0 583 | 0 584 | .\src\adapter\obd\canhistory.cpp 585 | canhistory.cpp 586 | 0 587 | 0 588 | 589 | 590 | 3 591 | 23 592 | 8 593 | 0 594 | 0 595 | 0 596 | 0 597 | .\src\adapter\obd\isocan.cpp 598 | isocan.cpp 599 | 0 600 | 0 601 | 602 | 603 | 3 604 | 24 605 | 8 606 | 0 607 | 0 608 | 0 609 | 0 610 | .\src\adapter\obd\obdprofile.cpp 611 | obdprofile.cpp 612 | 0 613 | 0 614 | 615 | 616 | 3 617 | 25 618 | 8 619 | 0 620 | 0 621 | 0 622 | 0 623 | .\src\adapter\obd\padapter.cpp 624 | padapter.cpp 625 | 0 626 | 0 627 | 628 | 629 | 630 | 631 | ::CMSIS 632 | 0 633 | 0 634 | 0 635 | 1 636 | 637 | 638 | 639 | ::Device 640 | 1 641 | 0 642 | 0 643 | 1 644 | 645 | 5 646 | 26 647 | 2 648 | 0 649 | 0 650 | 0 651 | 0 652 | RTE\Device\STM32F042K6\startup_stm32f042.s 653 | startup_stm32f042.s 654 | 1 655 | 0 656 | 657 | 658 | 5 659 | 27 660 | 1 661 | 1 662 | 0 663 | 0 664 | 0 665 | RTE\Device\STM32F042K6\system_stm32f0xx.c 666 | system_stm32f0xx.c 667 | 1 668 | 0 669 | 670 | 671 | 672 |
673 | -------------------------------------------------------------------------------- /elm329.uvprojx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.1 5 | 6 |
### uVision Project, (C) Keil Software
7 | 8 | 9 | 10 | adapter 11 | 0x4 12 | ARM-ADS 13 | 14 | 15 | STM32F042K6 16 | STMicroelectronics 17 | Keil.STM32F0xx_DFP.1.4.0 18 | http://www.keil.com/pack/ 19 | IROM(0x08000000,0x8000) IRAM(0x20000000,0x1800) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE 20 | 21 | 22 | UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F0xx_32 -FS08000000 -FL08000 -FP0($$Device:STM32F042K6$Flash\STM32F0xx_32.FLM)) 23 | 0 24 | $$Device:STM32F042K6$Device\Include\stm32f0xx.h 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | $$Device:STM32F042K6$SVD\STM32F042x.svd 35 | 0 36 | 0 37 | 38 | 39 | 40 | 41 | 42 | 43 | 0 44 | 0 45 | 0 46 | 0 47 | 1 48 | 49 | .\Objects\ 50 | obdst16 51 | 1 52 | 0 53 | 0 54 | 1 55 | 1 56 | .\Listings\ 57 | 1 58 | 0 59 | 0 60 | 61 | 0 62 | 0 63 | 64 | 65 | 0 66 | 0 67 | 0 68 | 0 69 | 70 | 71 | 0 72 | 0 73 | 74 | 75 | 0 76 | 0 77 | 0 78 | 0 79 | 80 | 81 | 0 82 | 0 83 | 84 | 85 | 0 86 | 0 87 | 88 | 0 89 | 90 | 91 | 92 | 0 93 | 0 94 | 0 95 | 0 96 | 0 97 | 1 98 | 0 99 | 0 100 | 0 101 | 0 102 | 3 103 | 104 | 105 | 1 106 | 107 | 108 | SARMCM3.DLL 109 | 110 | DARMCM1.DLL 111 | -pCM0 112 | SARMCM3.DLL 113 | 114 | TARMCM1.DLL 115 | -pCM0 116 | 117 | 118 | 119 | 1 120 | 0 121 | 0 122 | 0 123 | 16 124 | 125 | 126 | 0 127 | 1 128 | 1 129 | 1 130 | 1 131 | 1 132 | 1 133 | 1 134 | 0 135 | 1 136 | 137 | 138 | 1 139 | 1 140 | 0 141 | 1 142 | 1 143 | 1 144 | 0 145 | 1 146 | 1 147 | 1 148 | 149 | 0 150 | 11 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | STLink\ST-LINKIII-KEIL_SWO.dll 165 | 166 | 167 | 168 | 169 | 1 170 | 0 171 | 0 172 | 1 173 | 0 174 | -1 175 | 176 | 1 177 | BIN\UL2CM3.DLL 178 | 179 | 180 | 181 | 182 | 183 | 0 184 | 185 | 186 | 187 | 0 188 | 1 189 | 1 190 | 1 191 | 1 192 | 1 193 | 1 194 | 1 195 | 0 196 | 1 197 | 1 198 | 0 199 | 0 200 | 1 201 | 0 202 | 0 203 | 1 204 | 1 205 | 1 206 | 1 207 | 1 208 | 1 209 | 1 210 | 1 211 | 1 212 | 0 213 | 0 214 | "Cortex-M0" 215 | 216 | 0 217 | 0 218 | 0 219 | 1 220 | 1 221 | 0 222 | 0 223 | 0 224 | 0 225 | 0 226 | 8 227 | 1 228 | 0 229 | 0 230 | 3 231 | 3 232 | 0 233 | 1 234 | 0 235 | 0 236 | 0 237 | 0 238 | 0 239 | 0 240 | 0 241 | 0 242 | 1 243 | 0 244 | 0 245 | 0 246 | 0 247 | 1 248 | 0 249 | 250 | 251 | 0 252 | 0x0 253 | 0x0 254 | 255 | 256 | 0 257 | 0x0 258 | 0x0 259 | 260 | 261 | 0 262 | 0x0 263 | 0x0 264 | 265 | 266 | 0 267 | 0x0 268 | 0x0 269 | 270 | 271 | 0 272 | 0x0 273 | 0x0 274 | 275 | 276 | 0 277 | 0x0 278 | 0x0 279 | 280 | 281 | 0 282 | 0x20000000 283 | 0x1800 284 | 285 | 286 | 1 287 | 0x8000000 288 | 0x8000 289 | 290 | 291 | 0 292 | 0x0 293 | 0x0 294 | 295 | 296 | 1 297 | 0x0 298 | 0x0 299 | 300 | 301 | 1 302 | 0x0 303 | 0x0 304 | 305 | 306 | 1 307 | 0x0 308 | 0x0 309 | 310 | 311 | 1 312 | 0x8000000 313 | 0x8000 314 | 315 | 316 | 1 317 | 0x0 318 | 0x0 319 | 320 | 321 | 0 322 | 0x0 323 | 0x0 324 | 325 | 326 | 0 327 | 0x0 328 | 0x0 329 | 330 | 331 | 0 332 | 0x0 333 | 0x0 334 | 335 | 336 | 0 337 | 0x20000000 338 | 0x1800 339 | 340 | 341 | 0 342 | 0x0 343 | 0x0 344 | 345 | 346 | 347 | 348 | 349 | 1 350 | 3 351 | 0 352 | 0 353 | 0 354 | 0 355 | 0 356 | 0 357 | 0 358 | 0 359 | 2 360 | 0 361 | 0 362 | 0 363 | 0 364 | 365 | -DHSE_VALUE=12000000 366 | 367 | 368 | .\src\drv\stm32f0xx;.\src\util;.\STM32F0xx_StdPeriph_Driver\inc;.\src\adapter 369 | 370 | 371 | 372 | 1 373 | 0 374 | 0 375 | 0 376 | 0 377 | 0 378 | 0 379 | 0 380 | 0 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 1 390 | 0 391 | 0 392 | 0 393 | 1 394 | 0 395 | 0x08000000 396 | 0x20000000 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | app 410 | 411 | 412 | adapter.cpp 413 | 8 414 | .\src\adapter\adapter.cpp 415 | 416 | 417 | adapterconfig.cpp 418 | 8 419 | .\src\adapter\adapterconfig.cpp 420 | 421 | 422 | algorithms.cpp 423 | 8 424 | .\src\util\algorithms.cpp 425 | 426 | 427 | canmsgbuffer.cpp 428 | 8 429 | .\src\util\canmsgbuffer.cpp 430 | 431 | 432 | dispatcher.cpp 433 | 8 434 | .\src\adapter\dispatcher.cpp 435 | 436 | 437 | functions.cpp 438 | 8 439 | .\src\adapter\functions.cpp 440 | 441 | 442 | lstring.cpp 443 | 8 444 | .\src\util\lstring.cpp 445 | 446 | 447 | 448 | 449 | driver 450 | 451 | 452 | AdcSTM32F0xx.cpp 453 | 8 454 | .\src\drv\stm32f0xx\AdcSTM32F0xx.cpp 455 | 456 | 457 | CanDriverSTM32F0xx.cpp 458 | 8 459 | .\src\drv\stm32f0xx\CanDriverSTM32F0xx.cpp 460 | 461 | 462 | CmdUartSTM32F0xx.cpp 463 | 8 464 | .\src\drv\stm32f0xx\CmdUartSTM32F0xx.cpp 465 | 466 | 467 | GpioDrvSTM32F0xx.cpp 468 | 8 469 | .\src\drv\stm32f0xx\GpioDrvSTM32F0xx.cpp 470 | 471 | 472 | SysutilitySTM32F0xx.cpp 473 | 8 474 | .\src\drv\stm32f0xx\SysutilitySTM32F0xx.cpp 475 | 476 | 477 | TimerSTM32F0xx.cpp 478 | 8 479 | .\src\drv\stm32f0xx\TimerSTM32F0xx.cpp 480 | 481 | 482 | led.cpp 483 | 8 484 | .\src\drv\stm32f0xx\led.cpp 485 | 486 | 487 | stm32f0xx_gpio.c 488 | 1 489 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_gpio.c 490 | 491 | 492 | stm32f0xx_rcc.c 493 | 1 494 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_rcc.c 495 | 496 | 497 | stm32f0xx_tim.c 498 | 1 499 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_tim.c 500 | 501 | 502 | stm32f0xx_usart.c 503 | 1 504 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_usart.c 505 | 506 | 507 | stm32f0xx_can.c 508 | 1 509 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_can.c 510 | 511 | 512 | stm32f0xx_adc.c 513 | 1 514 | .\STM32F0xx_StdPeriph_Driver\src\stm32f0xx_adc.c 515 | 516 | 517 | 518 | 519 | obd 520 | 521 | 522 | autoadapter.cpp 523 | 8 524 | .\src\adapter\obd\autoadapter.cpp 525 | 526 | 527 | canhistory.cpp 528 | 8 529 | .\src\adapter\obd\canhistory.cpp 530 | 531 | 532 | isocan.cpp 533 | 8 534 | .\src\adapter\obd\isocan.cpp 535 | 536 | 537 | obdprofile.cpp 538 | 8 539 | .\src\adapter\obd\obdprofile.cpp 540 | 541 | 542 | padapter.cpp 543 | 8 544 | .\src\adapter\obd\padapter.cpp 545 | 546 | 547 | 548 | 549 | ::CMSIS 550 | 551 | 552 | ::Device 553 | 554 | 555 | startup_stm32f042.s 556 | 2 557 | RTE\Device\STM32F042K6\startup_stm32f042.s 558 | 559 | 560 | system_stm32f0xx.c 561 | 1 562 | RTE\Device\STM32F042K6\system_stm32f0xx.c 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | RTE\Device\STM32F042K6\startup_stm32f042.s 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | RTE\Device\STM32F042K6\system_stm32f0xx.c 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 |
607 | --------------------------------------------------------------------------------