├── src ├── libsc │ ├── k60 │ │ ├── MT9V034.cpp │ │ ├── touchscreen_lcd.cpp │ │ ├── ftdi_ft232r.cpp │ │ ├── jy_mcu_bt_106.cpp │ │ └── system.cpp │ ├── kl26 │ │ ├── ftdi_ft232r.cpp │ │ ├── jy_mcu_bt_106.cpp │ │ ├── system.cpp │ │ └── lptmr_timer.cpp │ ├── trs_d05.cpp │ ├── futaba_s3010.cpp │ ├── tower_pro_mg995.cpp │ ├── lib_guard.cpp │ ├── pit_timer.cpp │ ├── sys_tick_delay.cpp │ ├── dir_encoder.cpp │ ├── ab_encoder.cpp │ ├── pit_delay.cpp │ ├── sys_tick_timer.cpp │ ├── battery_meter.cpp │ ├── motor.cpp │ ├── simple_buzzer.cpp │ └── led.cpp ├── libbase │ ├── assert.c │ ├── k60 │ │ ├── crc_utils.cpp │ │ ├── dwt.cpp │ │ ├── spi_utils.cpp │ │ ├── clock_utils.cpp │ │ ├── cache.cpp │ │ ├── dma_mux.cpp │ │ ├── fpu.cpp │ │ └── ftm.cpp │ └── kl26 │ │ ├── watchdog.cpp │ │ ├── clock_utils.cpp │ │ ├── misc_utils.cpp │ │ └── tpm.cpp └── libutil │ ├── string.cpp │ ├── endian_utils.cpp │ ├── math.cpp │ ├── misc.cpp │ └── kalman_filter.cpp ├── .gitignore ├── inc ├── libbase │ ├── k60 │ │ ├── misc_utils.h │ │ ├── fpu_c.h │ │ ├── mcg_c.h │ │ ├── watchdog_c.h │ │ ├── cmsis │ │ │ └── system.h │ │ ├── dwt.h │ │ ├── pinout_macros.h │ │ ├── hardware.h │ │ ├── i2c.h │ │ ├── uart_utils.h │ │ ├── pinout.h │ │ ├── crc_utils.h │ │ ├── i2c_utils.h │ │ ├── dma_mux_utils.h │ │ ├── misc_utils_c.h │ │ ├── cache.h │ │ ├── dac_utils.h │ │ ├── pinout │ │ │ ├── mk60d10_lqfp144_macros.h │ │ │ └── mk60f15_lqfp144_macros.h │ │ ├── pwm_utils.h │ │ ├── spi_utils.h │ │ ├── quad_decoder_interface.h │ │ ├── pin_utils.h │ │ ├── reg_file.h │ │ ├── spi.h │ │ ├── ftm_utils.h │ │ ├── adc_utils.h │ │ ├── crc.h │ │ ├── pwm.h │ │ ├── rand_generator.h │ │ ├── fpu.h │ │ ├── mcg.h │ │ ├── pin_isr_manager.h │ │ ├── soft_sccb_master.h │ │ ├── sys_tick.h │ │ ├── soft_pwm.h │ │ ├── pit.h │ │ ├── dac.h │ │ ├── watchdog.h │ │ ├── ftm.h │ │ ├── soft_quad_decoder.h │ │ └── soft_spi_master.h │ ├── kl26 │ │ ├── misc_utils.h │ │ ├── hardware.h │ │ ├── watchdog_c.h │ │ ├── pinout_macros.h │ │ ├── pinout.h │ │ ├── mcg_c.h │ │ ├── cmsis │ │ │ └── system_MKL26Z4.h │ │ ├── i2c.h │ │ ├── uart_utils.h │ │ ├── i2c_utils.h │ │ ├── misc_utils_c.h │ │ ├── pinout │ │ │ └── mkl26z4_lqfp100_macros.h │ │ ├── spi_utils.h │ │ ├── pwm_utils.h │ │ ├── reg_file.h │ │ ├── quad_decoder_interface.h │ │ ├── spi.h │ │ ├── tpm_utils.h │ │ ├── pin_utils.h │ │ ├── adc_utils.h │ │ ├── pwm.h │ │ ├── tpm_counter.h │ │ ├── mcg.h │ │ ├── pin_isr_manager.h │ │ ├── sys_tick.h │ │ ├── soft_pwm.h │ │ ├── tpm_quad_decoder.h │ │ ├── soft_quad_decoder.h │ │ ├── tpm.h │ │ ├── watchdog.h │ │ ├── pit.h │ │ ├── lptmr.h │ │ ├── soft_spi_master.h │ │ ├── sim.h │ │ ├── spi_master_interface.h │ │ └── vectors.h │ ├── pinout.h │ ├── misc_types.h │ ├── pinout_macros.h │ ├── misc_utils.h │ ├── syscall.h │ ├── misc_utils_c.h │ ├── helper.h │ └── log.h ├── libsc │ ├── device_h │ │ ├── ds18b20.h │ │ ├── ldc1000.h │ │ └── st7735r.h │ ├── trs_d05.h │ ├── futaba_s3010.h │ ├── k60 │ │ ├── dwt_delay.h │ │ ├── ftdi_ft232r.h │ │ ├── led.h │ │ ├── jy_mcu_bt_106.h │ │ ├── config │ │ │ ├── 2014.h │ │ │ └── 2013_magnetic.h │ │ ├── ov7725_configurator.h │ │ └── ov7725_fifo.h │ ├── tower_pro_mg995.h │ ├── kl26 │ │ ├── ftdi_ft232r.h │ │ ├── lptmr_timer.h │ │ └── jy_mcu_bt_106.h │ ├── battery_meter.h │ ├── sys_tick_delay.h │ ├── pit_timer.h │ ├── pit_delay.h │ ├── simple_buzzer.h │ ├── switch.h │ ├── delay.h │ ├── dir_encoder.h │ ├── timer.h │ ├── rgb_led.h │ ├── ds18b20.h │ ├── system.h │ ├── led.h │ ├── sys_tick_timer.h │ ├── ab_encoder.h │ ├── infra_red_sensor.h │ ├── light_sensor.h │ ├── dir_motor.h │ ├── ldc1000.h │ ├── alternate_motor.h │ ├── tsl1401cl.h │ ├── button.h │ ├── joystick.h │ ├── passive_buzzer.h │ ├── us_100.h │ ├── motor.h │ ├── lib_guard.h │ ├── servo.h │ ├── encoder.h │ └── lcd_console.h └── libutil │ ├── math.h │ ├── string.h │ ├── notes.h │ ├── kalman_filter.h │ ├── fixed_circular_buffer.h │ ├── endian_utils.h │ ├── fixed_circular_buffer.tcc │ ├── endian_utils.tcc │ ├── pid_controller.tcc │ ├── incremental_pid_controller.h │ ├── positional_pid_controller.h │ ├── touch_keyboard.h │ ├── misc.h │ ├── incremental_pid_controller.tcc │ ├── positional_pid_controller.tcc │ └── pid_controller.h ├── .travis.yml └── README.md /src/libsc/k60/MT9V034.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkust-smartcar/libsccc/HEAD/src/libsc/k60/MT9V034.cpp -------------------------------------------------------------------------------- /src/libsc/k60/touchscreen_lcd.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkust-smartcar/libsccc/HEAD/src/libsc/k60/touchscreen_lcd.cpp -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all sub-dirs but inc/ and src/ 2 | */* 3 | !inc/* 4 | !src/* 5 | 6 | # Ignore additional files in root dir 7 | # Eclipse 8 | .project 9 | .cproject 10 | /Debug/ 11 | -------------------------------------------------------------------------------- /inc/libbase/k60/misc_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * misc_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/misc_utils.h" 12 | #include "libbase/k60/misc_utils_c.h" 13 | -------------------------------------------------------------------------------- /inc/libbase/kl26/misc_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * misc_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/misc_utils.h" 12 | #include "libbase/kl26/misc_utils_c.h" 13 | -------------------------------------------------------------------------------- /inc/libbase/kl26/hardware.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hardware.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #if defined(MKL26Z4) 12 | #include "libbase/kl26/cmsis/MKL26Z4.h" 13 | 14 | #else 15 | #error Unknown MCU 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /inc/libbase/k60/fpu_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fpu_c.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | void LibbaseK60FpuInit(void); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | -------------------------------------------------------------------------------- /inc/libsc/device_h/ds18b20.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ds18b20.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #define DS18B20_CONVERT_T 0x44 // Convert T 12 | #define DS18B20_READ_SP 0xBE // Read Scratchpad 13 | #define DS18B20_SKIP 0xCC // Skip ROM 14 | -------------------------------------------------------------------------------- /inc/libbase/kl26/watchdog_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * watchdog_c.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | void LibbaseKl26WatchdogInit(void); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | -------------------------------------------------------------------------------- /inc/libbase/kl26/pinout_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pinout_constants.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #if defined(MKL26Z4) 12 | #include "libbase/kl26/pinout/mkl26z4_lqfp100_macros.h" 13 | 14 | #else 15 | #error Unknown MCU 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /inc/libbase/kl26/pinout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pinout.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #if defined(MKL26Z4) 12 | #include "libbase/kl26/pinout/mkl26z4_lqfp100.h" 13 | #define PINOUT libbase::kl26::Mkl26z4Lqfp100 14 | 15 | #else 16 | #error Unknown MCU 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /inc/libbase/pinout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pinout.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #if MK60DZ10 || MK60D10 || MK60F15 12 | #include "libbase/k60/pinout.h" 13 | 14 | #elif MKL26Z4 15 | #include "libbase/kl26/pinout.h" 16 | 17 | #else 18 | #error Unknown MCU 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /inc/libutil/math.h: -------------------------------------------------------------------------------- 1 | /* 2 | * math.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | namespace libutil 12 | { 13 | 14 | class Math 15 | { 16 | public: 17 | static float ArcTan(float x); 18 | static float ArcSin(float x); 19 | static float Sqrt2(const float x); 20 | }; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /inc/libbase/misc_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * misc_types.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | typedef unsigned int Uint; 18 | typedef uint8_t Byte; 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /inc/libbase/k60/mcg_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mcg_c.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | void LibbaseK60McgInit(void); 18 | uint32_t LibbaseK60McgGetCoreClock(void); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /inc/libbase/kl26/mcg_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mcg_c.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | void LibbaseKl26McgInit(void); 18 | uint32_t LibbaseKl26McgGetCoreClock(void); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /inc/libbase/pinout_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pinout_macros.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #if MK60DZ10 || MK60D10 || MK60F15 12 | #include "libbase/k60/pinout_macros.h" 13 | 14 | #elif MKL26Z4 15 | #include "libbase/kl26/pinout_macros.h" 16 | 17 | #else 18 | #error Unknown MCU 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /inc/libbase/misc_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * misc_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/misc_utils_c.h" 14 | #include "log.h" 15 | 16 | #define VOID 17 | #define STATE_GUARD(clz, ret) if (!(*this)) { LOG_W(#clz " in illegal state @%d", __LINE__); return ret; } 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | cache: apt 3 | 4 | env: 5 | - SCCC_CONFIG=VCAN_FX15DEV 6 | - SCCC_CONFIG=HANDTECH_D10DEV 7 | - SCCC_CONFIG=2017_INNO 8 | - SCCC_CONFIG=2018_CREATIVE 9 | - SCCC_CONFIG=2018_CAMERA 10 | 11 | before_install: 12 | - sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded -y 13 | - sudo apt-get update 14 | - sudo apt-get install gcc-arm-none-eabi --allow-unauthenticated 15 | 16 | script: make all 17 | -------------------------------------------------------------------------------- /inc/libbase/k60/watchdog_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * watchdog_c.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/k60/misc_utils_c.h" 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | void LibbaseK60WatchdogInit(void); 18 | __ISR void LibbaseK60WatchdogIsr(void); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /inc/libbase/k60/cmsis/system.h: -------------------------------------------------------------------------------- 1 | /* 2 | * system.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** 16 | * Setup the microcontroller system. This function should be used only after 17 | * reset 18 | */ 19 | void SystemInit(void); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /inc/libbase/kl26/cmsis/system_MKL26Z4.h: -------------------------------------------------------------------------------- 1 | /* 2 | * system.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** 16 | * Setup the microcontroller system. This function should be used only after 17 | * reset 18 | */ 19 | void SystemInit(void); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /inc/libbase/k60/dwt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dwt.h 3 | * Data Watchpoint and Trace, currently only supports utilizing CYCCNT to delay 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace libbase 15 | { 16 | namespace k60 17 | { 18 | 19 | class Dwt 20 | { 21 | public: 22 | static void DelayUs(const uint16_t us); 23 | }; 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /inc/libbase/k60/pinout_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pinout_constants.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #if defined(MK60DZ10) || defined(MK60D10) 12 | #include "libbase/k60/pinout/mk60d10_lqfp144_macros.h" 13 | 14 | #elif defined(MK60F15) 15 | #include "libbase/k60/pinout/mk60f15_lqfp144_macros.h" 16 | 17 | #else 18 | #error Unknown MCU 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /inc/libbase/k60/hardware.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hardware.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #if defined(MK60DZ10) 12 | #include "libbase/k60/cmsis/mk60dz10.h" 13 | 14 | #elif defined(MK60D10) 15 | #include "libbase/k60/cmsis/mk60d10.h" 16 | 17 | #elif defined(MK60F15) 18 | #include "libbase/k60/cmsis/mk60f15.h" 19 | 20 | #else 21 | #error Unknown MCU 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /inc/libbase/k60/i2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i2c.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/k60/pinout_macros.h" 12 | 13 | namespace libbase 14 | { 15 | namespace k60 16 | { 17 | 18 | class I2c 19 | { 20 | public: 21 | enum struct Name 22 | { 23 | kI2c0Scl = 0, 24 | kI2c0Sda, 25 | kI2c1Scl, 26 | kI2c1Sda, 27 | 28 | kDisable 29 | }; 30 | }; 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /inc/libbase/kl26/i2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i2c.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/kl26/pinout_macros.h" 12 | 13 | namespace libbase 14 | { 15 | namespace kl26 16 | { 17 | 18 | class I2c 19 | { 20 | public: 21 | enum struct Name 22 | { 23 | kI2c0Scl = 0, 24 | kI2c0Sda, 25 | kI2c1Scl, 26 | kI2c1Sda, 27 | 28 | kDisable 29 | }; 30 | }; 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /inc/libbase/syscall.h: -------------------------------------------------------------------------------- 1 | /* 2 | * syscall.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef int (*FwriteHandler)(int file, char *ptr, int len); 16 | extern FwriteHandler g_fwrite_handler; 17 | 18 | /** 19 | * Retain all the syscall symbols 20 | */ 21 | void KeepSyscallSymbols(void); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /inc/libsc/trs_d05.h: -------------------------------------------------------------------------------- 1 | /* 2 | * trs_d05.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libsc/servo.h" 14 | 15 | namespace libsc 16 | { 17 | 18 | /** 19 | * TRS-D05 RC servo 20 | */ 21 | class TrsD05 : public Servo 22 | { 23 | public: 24 | struct Config 25 | { 26 | uint8_t id; 27 | }; 28 | 29 | explicit TrsD05(const Config &config); 30 | }; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /inc/libbase/k60/uart_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uart_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/k60/uart.h" 12 | #include "libbase/misc_types.h" 13 | 14 | namespace libbase 15 | { 16 | namespace k60 17 | { 18 | 19 | class UartUtils 20 | { 21 | public: 22 | static Uint GetUartModule(const Uart::Name uart) 23 | { 24 | return static_cast(uart) / 2; 25 | } 26 | }; 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /inc/libbase/kl26/uart_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uart_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/kl26/uart.h" 12 | #include "libbase/misc_types.h" 13 | 14 | namespace libbase 15 | { 16 | namespace kl26 17 | { 18 | 19 | class UartUtils 20 | { 21 | public: 22 | static Uint GetUartModule(const Uart::Name uart) 23 | { 24 | return static_cast(uart) / 2; 25 | } 26 | }; 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /inc/libbase/k60/pinout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pinout.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #if defined(MK60DZ10) || defined(MK60D10) 12 | #include "libbase/k60/pinout/mk60d10_lqfp144.h" 13 | #define PINOUT libbase::k60::Mk60d10Lqfp144 14 | 15 | #elif defined(MK60F15) 16 | #include "libbase/k60/pinout/mk60f15_lqfp144.h" 17 | #define PINOUT libbase::k60::Mk60f15Lqfp144 18 | 19 | #else 20 | #error Unknown MCU 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /inc/libsc/futaba_s3010.h: -------------------------------------------------------------------------------- 1 | /* 2 | * futaba_s3010.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libsc/servo.h" 14 | 15 | namespace libsc 16 | { 17 | 18 | /** 19 | * Futaba S3010 RC servo 20 | */ 21 | class FutabaS3010 : public Servo 22 | { 23 | public: 24 | struct Config 25 | { 26 | uint8_t id; 27 | }; 28 | 29 | explicit FutabaS3010(const Config &config); 30 | }; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /inc/libbase/k60/crc_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * crc_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/k60/crc.h" 15 | #include "libbase/k60/misc_utils.h" 16 | 17 | namespace libbase 18 | { 19 | namespace k60 20 | { 21 | 22 | class CrcUtils 23 | { 24 | public: 25 | static uint32_t Calc(Crc *crc, const Byte *data, const size_t size); 26 | }; 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /inc/libbase/misc_utils_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * misc_utils_c.h 3 | * Subset of misc utils that could be used with plain C 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "libbase/misc_types.h" 13 | 14 | #define SET_BIT(x, n) ((x) |= 1 << (n)) 15 | #define RESET_BIT(x, n) ((x) &= ~(1 << (n))) 16 | #define CLEAR_BIT(x, n) RESET_BIT(x, n) 17 | #define GET_BIT(x, n) (((x) >> (n)) & 1) 18 | #define GET_BITS(x, n, mask) (((x) & (mask)) >> n) 19 | -------------------------------------------------------------------------------- /inc/libsc/k60/dwt_delay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dwt_delay.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/k60/dwt.h" 14 | 15 | #include "libsc/delay.h" 16 | 17 | namespace libsc 18 | { 19 | namespace k60 20 | { 21 | 22 | class DwtDelay : public Delay 23 | { 24 | public: 25 | void DelayUs(const uint16_t us) override 26 | { 27 | libbase::k60::Dwt::DelayUs(us); 28 | } 29 | }; 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /inc/libsc/tower_pro_mg995.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tower_pro_mg995.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libsc/servo.h" 14 | 15 | namespace libsc 16 | { 17 | 18 | /** 19 | * TowerPro MG995 RC servo 20 | */ 21 | class TowerProMg995 : public Servo 22 | { 23 | public: 24 | struct Config 25 | { 26 | uint8_t id; 27 | }; 28 | 29 | explicit TowerProMg995(const Config &config); 30 | }; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /inc/libbase/k60/i2c_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i2c_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/k60/i2c.h" 12 | #include "libbase/k60/misc_utils.h" 13 | #include "libbase/k60/pinout.h" 14 | 15 | namespace libbase 16 | { 17 | namespace k60 18 | { 19 | 20 | class I2cUtils 21 | { 22 | public: 23 | static Uint GetI2cModule(const I2c::Name pin) 24 | { 25 | return static_cast(pin) / PINOUT::GetI2cCount(); 26 | } 27 | }; 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /inc/libsc/k60/ftdi_ft232r.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ftdi_ft232r.h 3 | * Generic class for the FTDI FT232R USB UART IC 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "libsc/k60/uart_device.h" 15 | 16 | namespace libsc 17 | { 18 | namespace k60 19 | { 20 | 21 | class FtdiFt232r : public UartDevice 22 | { 23 | public: 24 | typedef UartDevice::Config Config; 25 | 26 | explicit FtdiFt232r(const Config &config); 27 | }; 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /inc/libbase/kl26/i2c_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i2c_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/kl26/i2c.h" 12 | #include "libbase/kl26/misc_utils.h" 13 | #include "libbase/kl26/pinout.h" 14 | 15 | namespace libbase 16 | { 17 | namespace kl26 18 | { 19 | 20 | class I2cUtils 21 | { 22 | public: 23 | static Uint GetI2cModule(const I2c::Name pin) 24 | { 25 | return static_cast(pin) / PINOUT::GetI2cCount(); 26 | } 27 | }; 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /inc/libsc/kl26/ftdi_ft232r.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ftdi_ft232r.h 3 | * Generic class for the FTDI FT232R USB UART IC 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "libsc/kl26/uart_device.h" 15 | 16 | namespace libsc 17 | { 18 | namespace kl26 19 | { 20 | 21 | class FtdiFt232r : public UartDevice 22 | { 23 | public: 24 | typedef UartDevice::Config Config; 25 | 26 | explicit FtdiFt232r(const Config &config); 27 | }; 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /inc/libbase/k60/dma_mux_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dma_mux_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/k60/misc_utils.h" 12 | 13 | namespace libbase 14 | { 15 | namespace k60 16 | { 17 | 18 | class DmaMuxUtils 19 | { 20 | public: 21 | static Uint GetModule(const Uint ch) 22 | { 23 | return static_cast(ch) >> 4; 24 | } 25 | 26 | static Uint GetChannel(const Uint ch) 27 | { 28 | return static_cast(ch) & 0xF; 29 | } 30 | }; 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /inc/libsc/battery_meter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * battery_meter.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/helper.h" 12 | #include LIBBASE_H(adc) 13 | 14 | namespace libsc 15 | { 16 | 17 | class BatteryMeter 18 | { 19 | public: 20 | struct Config 21 | { 22 | float voltage_ratio; 23 | }; 24 | 25 | explicit BatteryMeter(const Config &config); 26 | 27 | float GetVoltage(); 28 | 29 | private: 30 | LIBBASE_MODULE(Adc) m_adc; 31 | float m_voltage_ratio; 32 | }; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /inc/libutil/string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * string.h 3 | * String utilities 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #ifndef LIBUTIL_STRING_H_ 11 | #define LIBUTIL_STRING_H_ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace libutil 19 | { 20 | 21 | class String 22 | { 23 | public: 24 | static std::string Format(const char *format, ...); 25 | static std::string Format(const char *format, va_list *vl); 26 | }; 27 | 28 | } 29 | 30 | #endif /* LIBUTIL_STRING_UTILS_H_ */ 31 | -------------------------------------------------------------------------------- /inc/libbase/kl26/misc_utils_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * misc_utils_c.h 3 | * Subset of misc utils that could be used with plain C 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "libbase/misc_utils_c.h" 13 | 14 | #define __ISR __attribute__((__interrupt__)) 15 | #define __RAMFUNC __attribute__((__long_call__, __section__(".m_data_2"))) 16 | #ifdef DEBUG 17 | #define __BREAKPOINT() asm("BKPT 255") 18 | 19 | #else 20 | #define __BREAKPOINT() 21 | 22 | #endif 23 | #define __HARDFAULT() *((char*)0) = 42 24 | -------------------------------------------------------------------------------- /inc/libbase/k60/misc_utils_c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * misc_utils_c.h 3 | * Subset of misc utils that could be used with plain C 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "libbase/misc_utils_c.h" 13 | 14 | #define __ISR __attribute__((__interrupt__)) 15 | #define __RAMFUNC __attribute__((__long_call__, __section__(".m_data_20000000"))) 16 | #ifdef DEBUG 17 | #define __BREAKPOINT() asm("BKPT 255") 18 | 19 | #else 20 | #define __BREAKPOINT() 21 | 22 | #endif 23 | #define __HARDFAULT() *((char*)0) = 42 24 | -------------------------------------------------------------------------------- /inc/libbase/k60/cache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cache.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | namespace libbase 12 | { 13 | namespace k60 14 | { 15 | 16 | class Cache 17 | { 18 | public: 19 | struct Config 20 | { 21 | bool is_enable; 22 | }; 23 | 24 | static Cache& Get() 25 | { 26 | static Cache inst; 27 | return inst; 28 | } 29 | 30 | void Init(const Config &config); 31 | 32 | private: 33 | Cache(); 34 | 35 | void InitPc(); 36 | void InitPs(); 37 | 38 | bool m_is_init; 39 | }; 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libsccc 2 | ============== 3 | 4 | [![Build Status](https://travis-ci.org/hkust-smartcar/libsccc.svg?branch=chocolate-cupcake)](https://travis-ci.org/hkust-smartcar/libsccc) 5 | 6 | libsccc (previously libsmartcarcpp) is the library being used among the HKUST SmartCar Team 7 | 8 | ## What's Inside 9 | libbase: Peripheral library for MK60D(Z)10, MK60F15(/12), MKL26Z4 10 | libsc: High-level component library based on libbase 11 | libutil: Useful utilities 12 | 13 | ## Dependency 14 | None 15 | 16 | ## Build 17 | GNU Make 3.81+, [GNU Tools for ARM Embedded Processor 4.8+](https://launchpad.net/gcc-arm-embedded) 18 | -------------------------------------------------------------------------------- /inc/libbase/kl26/pinout/mkl26z4_lqfp100_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mkl26z4_lqfp100_macros.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | // These macros are here to support conditional inclution only, DO NOT use 12 | // directly 13 | #define PINOUT_PIN_COUNT 100 14 | #define PINOUT_ADC_COUNT 1 15 | #define PINOUT_I2C_COUNT 2 16 | #define PINOUT_PORT_COUNT 5 17 | #define PINOUT_PORT_PIN_COUNT 32 18 | #define PINOUT_SPI_COUNT 2 19 | #define PINOUT_TPM_COUNT 3 20 | #define PINOUT_TPM_CHANNEL_COUNT 6 21 | #define PINOUT_UART_COUNT 3 22 | -------------------------------------------------------------------------------- /inc/libsc/sys_tick_delay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sys_tick_delay.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(sys_tick) 15 | 16 | #include "libsc/delay.h" 17 | 18 | namespace libsc 19 | { 20 | 21 | class SysTickDelay : public Delay 22 | { 23 | public: 24 | SysTickDelay(); 25 | 26 | void DelayUs(const uint16_t us) override; 27 | 28 | private: 29 | inline void DelayCount(const uint32_t count); 30 | 31 | LIBBASE_MODULE(SysTick) m_sys_tick; 32 | }; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/libsc/kl26/ftdi_ft232r.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ftdi_ft232r.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libsc/config.h" 12 | #include "libsc/kl26/ftdi_ft232r.h" 13 | 14 | namespace libsc 15 | { 16 | namespace kl26 17 | { 18 | 19 | #ifdef LIBSC_USE_UART 20 | FtdiFt232r::FtdiFt232r(const Config &config) 21 | : UartDevice(Initializer(config)) 22 | {} 23 | 24 | #else /* LIBSC_USE_UART */ 25 | FtdiFt232r::FtdiFt232r(const Config&) 26 | : UartDevice(nullptr) 27 | {} 28 | 29 | #endif /* LIBSC_USE_UART */ 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /inc/libbase/k60/dac_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dac_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/k60/dac.h" 14 | #include "libbase/k60/misc_utils.h" 15 | 16 | namespace libbase 17 | { 18 | namespace k60 19 | { 20 | 21 | class DacUtils 22 | { 23 | public: 24 | static Uint GetModule(const Dac::Name dac) 25 | { 26 | return static_cast(dac); 27 | } 28 | 29 | static Dac::Name GetPin(const Uint module) 30 | { 31 | return static_cast(module); 32 | } 33 | }; 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /inc/libsc/pit_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pit_timer.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(pit) 15 | 16 | #include "libsc/timer.h" 17 | 18 | namespace libsc 19 | { 20 | 21 | class PitTimer : public Timer 22 | { 23 | public: 24 | explicit PitTimer(const uint8_t channel); 25 | 26 | TimerInt Time() override 27 | { 28 | return m_ms; 29 | } 30 | 31 | private: 32 | void OnTick(LIBBASE_MODULE(Pit)*); 33 | 34 | LIBBASE_MODULE(Pit) m_pit; 35 | volatile TimerInt m_ms; 36 | }; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/libsc/k60/ftdi_ft232r.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ftdi_ft232r.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libsc/config.h" 12 | #include "libsc/k60/ftdi_ft232r.h" 13 | 14 | using namespace libbase::k60; 15 | 16 | namespace libsc 17 | { 18 | namespace k60 19 | { 20 | 21 | #ifdef LIBSC_USE_UART 22 | FtdiFt232r::FtdiFt232r(const Config &config) 23 | : UartDevice(Initializer(config)) 24 | {} 25 | 26 | #else /* LIBSC_USE_UART */ 27 | FtdiFt232r::FtdiFt232r(const Config&) 28 | : UartDevice(nullptr) 29 | {} 30 | 31 | #endif /* LIBSC_USE_UART */ 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /inc/libsc/kl26/lptmr_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * lptmr_timer.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/kl26/lptmr.h" 14 | 15 | #include "libsc/timer.h" 16 | 17 | namespace libsc 18 | { 19 | namespace kl26 20 | { 21 | 22 | class LptmrTimer : public Timer 23 | { 24 | public: 25 | LptmrTimer(); 26 | 27 | TimerInt Time() override; 28 | 29 | private: 30 | void OnTick(libbase::kl26::Lptmr*); 31 | 32 | libbase::kl26::Lptmr m_lptmr; 33 | volatile TimerInt m_ms; 34 | volatile uint16_t m_prev_counter; 35 | }; 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /inc/libsc/pit_delay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pit_delay.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(pit) 15 | 16 | #include "libsc/delay.h" 17 | 18 | namespace libsc 19 | { 20 | 21 | class PitDelay : public Delay 22 | { 23 | public: 24 | explicit PitDelay(const uint8_t channel); 25 | 26 | void DelayUs(const uint16_t us) override; 27 | void DelayMs(const uint16_t ms) override; 28 | 29 | private: 30 | inline void DelayCount(const uint32_t count); 31 | 32 | LIBBASE_MODULE(Pit) m_pit; 33 | }; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /inc/libsc/simple_buzzer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * simple_buzzer.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(gpio) 15 | 16 | namespace libsc 17 | { 18 | 19 | class SimpleBuzzer 20 | { 21 | public: 22 | struct Config 23 | { 24 | uint8_t id; 25 | bool is_active_low; 26 | }; 27 | 28 | explicit SimpleBuzzer(const Config &config); 29 | 30 | void SetBeep(const bool is_beep); 31 | bool GetBeep() const; 32 | 33 | private: 34 | LIBBASE_MODULE(Gpo) m_pin; 35 | bool m_is_active_low; 36 | }; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/libbase/assert.c: -------------------------------------------------------------------------------- 1 | /* 2 | * assert.c 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "libbase/k60/misc_utils_c.h" 14 | 15 | void __assert_func(const char *file, int line, const char *fn, 16 | const char *expression) 17 | { 18 | while (1) 19 | { 20 | iprintf("Assertion(%s) failed in %s:%s at line %d\n", expression, file, 21 | fn, line); 22 | // Arbitrary delay 23 | for (uint32_t i = 0; i < 50000000; ++i) 24 | { 25 | asm("nop"); 26 | } 27 | __BREAKPOINT(); 28 | __HARDFAULT(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /inc/libbase/k60/pinout/mk60d10_lqfp144_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mk60d10_lqfp144_macros.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | // These macros are here to support conditional inclution only, DO NOT use 12 | // directly 13 | #define PINOUT_PIN_COUNT 144 14 | #define PINOUT_ADC_COUNT 2 15 | #define PINOUT_DMA_CH_COUNT 16 16 | #define PINOUT_DMA_MUX_COUNT 1 17 | #define PINOUT_FTM_COUNT 3 18 | #define PINOUT_FTM_CHANNEL_COUNT 8 19 | #define PINOUT_I2C_COUNT 2 20 | #define PINOUT_PORT_COUNT 5 21 | #define PINOUT_PORT_PIN_COUNT 32 22 | #define PINOUT_SPI_COUNT 3 23 | #define PINOUT_UART_COUNT 6 24 | -------------------------------------------------------------------------------- /inc/libbase/k60/pinout/mk60f15_lqfp144_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mk60f15_lqfp144_macros.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | // These macros are here to support conditional inclution only, DO NOT use 12 | // directly 13 | #define PINOUT_PIN_COUNT 144 14 | #define PINOUT_ADC_COUNT 4 15 | #define PINOUT_DMA_CH_COUNT 32 16 | #define PINOUT_DMA_MUX_COUNT 2 17 | #define PINOUT_FTM_COUNT 4 18 | #define PINOUT_FTM_CHANNEL_COUNT 8 19 | #define PINOUT_I2C_COUNT 2 20 | #define PINOUT_PORT_COUNT 5 21 | #define PINOUT_PORT_PIN_COUNT 32 22 | #define PINOUT_SPI_COUNT 3 23 | #define PINOUT_UART_COUNT 6 24 | -------------------------------------------------------------------------------- /inc/libsc/switch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * switch.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(gpio) 15 | 16 | namespace libsc 17 | { 18 | 19 | class Switch 20 | { 21 | public: 22 | struct Config 23 | { 24 | uint8_t id; 25 | // on == active 26 | bool is_active_low; 27 | }; 28 | 29 | explicit Switch(const Config &config); 30 | 31 | bool IsOn() const; 32 | bool IsOff() const 33 | { 34 | return !IsOn(); 35 | } 36 | 37 | private: 38 | LIBBASE_MODULE(Gpi) m_pin; 39 | bool m_is_active_low; 40 | }; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /inc/libsc/k60/led.h: -------------------------------------------------------------------------------- 1 | /* 2 | * led.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/k60/dma.h" 14 | #include "libbase/k60/gpio.h" 15 | 16 | #include "libsc/led.h" 17 | 18 | namespace libsc 19 | { 20 | namespace k60 21 | { 22 | 23 | class Led : public libsc::Led 24 | { 25 | public: 26 | using libsc::Led::Led; 27 | 28 | /** 29 | * @param config 30 | * @see Gpo::ConfigToggleAsDmaDst() 31 | */ 32 | void ConfigToggleAsDmaDst(libbase::k60::Dma::Config *config) 33 | { 34 | GetPin()->ConfigToggleAsDmaDst(config); 35 | } 36 | }; 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /inc/libbase/kl26/spi_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/kl26/misc_utils.h" 12 | #include "libbase/kl26/pinout.h" 13 | #include "libbase/kl26/spi.h" 14 | 15 | namespace libbase 16 | { 17 | namespace kl26 18 | { 19 | 20 | class SpiUtils 21 | { 22 | public: 23 | static Uint GetSpiModule(const Spi::PcsName pcs) 24 | { 25 | return static_cast(pcs) / Spi::GetMaxSpiPcsCount(); 26 | } 27 | 28 | static Uint GetSpiPcs(const Spi::PcsName pcs) 29 | { 30 | return static_cast(pcs) % Spi::GetMaxSpiPcsCount(); 31 | } 32 | }; 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /inc/libsc/delay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * delay.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/misc_types.h" 14 | 15 | namespace libsc 16 | { 17 | 18 | class Delay 19 | { 20 | public: 21 | virtual ~Delay() 22 | {} 23 | 24 | virtual void DelayUs(const uint16_t us) = 0; 25 | 26 | virtual void DelayMs(const uint16_t ms) 27 | { 28 | for (Uint i = 0; i < ms; ++i) 29 | { 30 | DelayUs(1000); 31 | } 32 | } 33 | 34 | virtual void DelayS(const uint16_t s) 35 | { 36 | for (Uint i = 0; i < s; ++i) 37 | { 38 | DelayMs(1000); 39 | } 40 | } 41 | }; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /inc/libsc/dir_encoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dir_encoder.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libsc/config.h" 12 | #include "libsc/encoder.h" 13 | 14 | namespace libsc 15 | { 16 | 17 | class DirEncoder : public Encoder 18 | { 19 | public: 20 | typedef Encoder::Config Config; 21 | 22 | explicit DirEncoder(const Config &config); 23 | 24 | protected: 25 | struct Initializer : public Encoder::Initializer 26 | { 27 | explicit Initializer(const Config &config) 28 | : Encoder::Initializer(config) 29 | {} 30 | 31 | QuadDecoder::Config GetQuadDecoderConfig() const override; 32 | }; 33 | }; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /inc/libutil/notes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * notes.h 3 | * 4 | * Created on: 3 May 2016 5 | * Author: Kyle Lei 6 | */ 7 | /*-----s stands for sharp, i.e. F1S=F#-----*/ 8 | #define NOTE_C1 262 9 | #define NOTE_C1S 277 10 | #define NOTE_D1 293 11 | #define NOTE_D1S 311 12 | #define NOTE_E1 329 13 | #define NOTE_F1 349 14 | #define NOTE_F1S 370 15 | #define NOTE_G1 392 16 | #define NOTE_G1S 415 17 | #define NOTE_A1 440 18 | #define NOTE_A1S 466 19 | #define NOTE_B1 494 20 | 21 | #define NOTE_C2 523 22 | #define NOTE_C2S 553 23 | #define NOTE_D2 586 24 | #define NOTE_D2S 621 25 | #define NOTE_E2 658 26 | #define NOTE_F2 697 27 | #define NOTE_F2S 739 28 | #define NOTE_G2 783 29 | #define NOTE_G2S 830 30 | #define NOTE_A2 879 31 | #define NOTE_A2S 931 32 | #define NOTE_B2 987 33 | -------------------------------------------------------------------------------- /inc/libbase/k60/pwm_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pwm_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/misc_types.h" 14 | 15 | namespace libbase 16 | { 17 | namespace k60 18 | { 19 | 20 | class PwmUtils 21 | { 22 | public: 23 | static uint32_t GetPeriodUs(const uint32_t frequency) 24 | { 25 | return 1000000 / frequency; 26 | } 27 | 28 | static uint32_t GetPeriodNs(const uint32_t frequency) 29 | { 30 | return 1000000000 / frequency; 31 | } 32 | 33 | static uint32_t GetPosWidth(const uint32_t period, const Uint duty_1000) 34 | { 35 | return period * duty_1000 / 1000; 36 | } 37 | }; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /inc/libbase/k60/spi_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/k60/misc_utils.h" 12 | #include "libbase/k60/pin.h" 13 | #include "libbase/k60/spi.h" 14 | 15 | namespace libbase 16 | { 17 | namespace k60 18 | { 19 | 20 | class SpiUtils 21 | { 22 | public: 23 | static Uint GetCsNumber(const Pin::Name pin); 24 | 25 | static Uint GetSpiModule(const Spi::PcsName pcs) 26 | { 27 | return static_cast(pcs) / Spi::GetMaxSpiPcsCount(); 28 | } 29 | 30 | static Uint GetSpiPcs(const Spi::PcsName pcs) 31 | { 32 | return static_cast(pcs) % Spi::GetMaxSpiPcsCount(); 33 | } 34 | }; 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /inc/libbase/kl26/pwm_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pwm_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/misc_types.h" 14 | 15 | namespace libbase 16 | { 17 | namespace kl26 18 | { 19 | 20 | class PwmUtils 21 | { 22 | public: 23 | static uint32_t GetPeriodUs(const uint32_t frequency) 24 | { 25 | return 1000000 / frequency; 26 | } 27 | 28 | static uint32_t GetPeriodNs(const uint32_t frequency) 29 | { 30 | return 1000000000 / frequency; 31 | } 32 | 33 | static uint32_t GetPosWidth(const uint32_t period, const Uint duty_1000) 34 | { 35 | return period * duty_1000 / 1000; 36 | } 37 | }; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /inc/libutil/kalman_filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * kalman_filter.h 3 | * 4 | * Author: Tommy Wong 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | namespace libutil 12 | { 13 | 14 | class KalmanFilter 15 | { 16 | public: 17 | KalmanFilter(const float q, const float r, const float x, const float p); 18 | 19 | float Filter(const float data); 20 | 21 | void SetQ(const float lpQ); 22 | void SetR(const float lpR); 23 | void SetX(const float lpX); 24 | void SetP(const float lpP); 25 | 26 | private: 27 | void PredictState(); 28 | void PredictCovariance(); 29 | void UpdateState(const float z); 30 | void UpdateCovariance(); 31 | void Gain(); 32 | protected: 33 | float m_q, m_r, m_k, m_x, m_lx, m_p, m_lp; 34 | }; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/libsc/trs_d05.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * trs_d05.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libsc/trs_d05.h" 12 | 13 | // 300 Hz 14 | #define PERIOD 3333 15 | #define POS_WIDTH_MIN 1500 - 900 16 | #define POS_WIDTH_MAX 1500 + 900 17 | 18 | namespace libsc 19 | { 20 | 21 | namespace 22 | { 23 | 24 | Servo::Config GetServoConfig(const uint8_t id) 25 | { 26 | Servo::Config config; 27 | config.id = id; 28 | config.period = PERIOD; 29 | config.min_pos_width = POS_WIDTH_MIN; 30 | config.max_pos_width = POS_WIDTH_MAX; 31 | return config; 32 | } 33 | 34 | } 35 | 36 | TrsD05::TrsD05(const Config &config) 37 | : Servo(GetServoConfig(config.id)) 38 | {} 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/libsc/futaba_s3010.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * futaba_s3010.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libsc/futaba_s3010.h" 12 | 13 | #define PERIOD 20000 14 | #define POS_WIDTH_MIN 1500 - 500 15 | #define POS_WIDTH_MAX 1500 + 500 16 | 17 | namespace libsc 18 | { 19 | 20 | namespace 21 | { 22 | 23 | Servo::Config GetServoConfig(const uint8_t id) 24 | { 25 | Servo::Config config; 26 | config.id = id; 27 | config.period = PERIOD; 28 | config.min_pos_width = POS_WIDTH_MIN; 29 | config.max_pos_width = POS_WIDTH_MAX; 30 | return config; 31 | } 32 | 33 | } 34 | 35 | FutabaS3010::FutabaS3010(const Config &config) 36 | : Servo(GetServoConfig(config.id)) 37 | {} 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/libsc/tower_pro_mg995.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tower_pro_mg995.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libsc/tower_pro_mg995.h" 12 | 13 | #define PERIOD 20000 14 | #define POS_WIDTH_MIN 500 15 | #define POS_WIDTH_MAX 2500 16 | 17 | namespace libsc 18 | { 19 | 20 | namespace 21 | { 22 | 23 | Servo::Config GetServoConfig(const uint8_t id) 24 | { 25 | Servo::Config config; 26 | config.id = id; 27 | config.period = PERIOD; 28 | config.min_pos_width = POS_WIDTH_MIN; 29 | config.max_pos_width = POS_WIDTH_MAX; 30 | return config; 31 | } 32 | 33 | } 34 | 35 | TowerProMg995::TowerProMg995(const Config &config) 36 | : Servo(GetServoConfig(config.id)) 37 | {} 38 | 39 | } 40 | -------------------------------------------------------------------------------- /inc/libsc/device_h/ldc1000.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ldc1000.h 3 | * 4 | * Author: Petel__ 5 | * Copyright (c) 2014-2016 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | 12 | #define REG_DEV_ID 0x00 13 | #define REG_RP_MAX 0x01 14 | #define REG_RP_MIN 0x02 15 | #define REG_SENSOR_FREQ 0x03 16 | #define REG_LDC_CONFIG 0x04 17 | #define REG_CLK_CONFIG 0x05 18 | #define REG_THRES_HI_LSB 0x06 19 | #define REG_THRES_HI_MSB 0x07 20 | #define REG_THRES_LO_LSB 0x08 21 | #define REG_THRES_LO_MSB 0x09 22 | #define REG_INT_CONFIG 0x0A 23 | #define REG_PWR_CONFIG 0x0B 24 | #define REG_STATUS 0x20 25 | #define REG_PROX_LSB 0x21 26 | #define REG_PROX_MSB 0x22 27 | #define REG_FREQ_LSB 0x23 28 | #define REG_FREQ_MID 0x24 29 | #define REG_FREQ_MSB 0x25 30 | -------------------------------------------------------------------------------- /inc/libbase/k60/quad_decoder_interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * quad_decoder_interface.h 3 | * Generic quadrature decoder interface 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "libbase/k60/pin.h" 15 | 16 | namespace libbase 17 | { 18 | namespace k60 19 | { 20 | 21 | class QuadDecoderInterface 22 | { 23 | public: 24 | struct Config 25 | { 26 | Pin::Name a_pin; 27 | Pin::Name b_pin; 28 | bool is_invert_a_polarity = false; 29 | bool is_invert_b_polarity = false; 30 | }; 31 | 32 | virtual ~QuadDecoderInterface() 33 | {} 34 | 35 | virtual operator bool() const = 0; 36 | 37 | virtual int32_t GetCount() = 0; 38 | virtual void ResetCount() = 0; 39 | }; 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /inc/libbase/kl26/reg_file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * reg_file.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "libbase/misc_types.h" 16 | 17 | namespace libbase 18 | { 19 | namespace kl26 20 | { 21 | 22 | class RegFile 23 | { 24 | public: 25 | static RegFile& Get() 26 | { 27 | static RegFile inst; 28 | return inst; 29 | } 30 | 31 | void Init(); 32 | 33 | void WriteSystem(const Uint seek, const Byte *data, const size_t size); 34 | void WriteSystem(const Uint seek, const Byte data); 35 | Byte ReadSystem(const Uint seek); 36 | std::vector ReadSystem(const Uint seek, const size_t size); 37 | 38 | private: 39 | RegFile(); 40 | }; 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /inc/libsc/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * timer.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace libsc 14 | { 15 | 16 | class Timer 17 | { 18 | public: 19 | typedef uint32_t TimerInt; 20 | 21 | virtual ~Timer() 22 | {} 23 | 24 | /** 25 | * Return the time elapsed, in ms 26 | * 27 | * @return 28 | */ 29 | virtual TimerInt Time() = 0; 30 | 31 | /** 32 | * Return how @a a is apart from @a b 33 | * 34 | * @param a Some time in the future, in terms of @a b 35 | * @param b Some time in the past, in terms of @a a 36 | * @return 37 | */ 38 | static TimerInt TimeDiff(const TimerInt a, const TimerInt b) 39 | { 40 | return (TimerInt)(a - b); 41 | } 42 | }; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /inc/libsc/rgb_led.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rgb_led.h 3 | * 4 | * Author: LeeChunHei 5 | * Copyright (c) 2017-2018 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(gpio) 15 | 16 | namespace libsc 17 | { 18 | 19 | class RGBLed 20 | { 21 | public: 22 | struct Config 23 | { 24 | uint8_t id; 25 | bool is_active_low; 26 | }; 27 | 28 | enum Color { 29 | kWhite, kRed, kGreen, kBlue, kYellow, kMagenta, kCyan 30 | }; 31 | 32 | explicit RGBLed(const Config &config); 33 | 34 | void SetEnable(const bool flag); 35 | void SetColor(const Color color); 36 | 37 | private: 38 | LIBBASE_MODULE(Gpo) m_r_pin;LIBBASE_MODULE(Gpo) m_g_pin;LIBBASE_MODULE(Gpo) m_b_pin; 39 | bool m_is_active_low; 40 | }; 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /inc/libsc/ds18b20.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ds18b20.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(gpio) 15 | 16 | namespace libsc 17 | { 18 | 19 | /** 20 | * DS18B20 digital thermometer 21 | */ 22 | class Ds18b20 23 | { 24 | public: 25 | struct Config 26 | { 27 | uint8_t id; 28 | }; 29 | 30 | explicit Ds18b20(const Config &config); 31 | 32 | void UpdateTemperature(); 33 | 34 | float GetTemperature() const 35 | { 36 | return m_temperature; 37 | } 38 | 39 | private: 40 | bool Init(); 41 | void SendByte(const uint8_t byte); 42 | uint8_t ReceiveByte(); 43 | 44 | LIBBASE_MODULE(Gpio) m_pin; 45 | float m_temperature; 46 | }; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /inc/libbase/kl26/quad_decoder_interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * quad_decoder_interface.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/kl26/pin.h" 14 | 15 | namespace libbase 16 | { 17 | namespace kl26 18 | { 19 | 20 | /** 21 | * Generic quadrature decoder interface 22 | */ 23 | class QuadDecoderInterface 24 | { 25 | public: 26 | struct Config 27 | { 28 | Pin::Name a_pin; 29 | Pin::Name b_pin; 30 | bool is_invert_a_polarity = false; 31 | bool is_invert_b_polarity = false; 32 | }; 33 | 34 | virtual ~QuadDecoderInterface() 35 | {} 36 | 37 | virtual operator bool() const = 0; 38 | 39 | virtual int32_t GetCount() = 0; 40 | virtual void ResetCount() = 0; 41 | }; 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /inc/libbase/kl26/spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | namespace libbase 12 | { 13 | namespace kl26 14 | { 15 | 16 | class Spi 17 | { 18 | public: 19 | enum struct MisoName 20 | { 21 | kSpi0Miso = 0, 22 | kSpi1Miso, 23 | kDisable 24 | }; 25 | 26 | enum struct MosiName 27 | { 28 | kSpi0Mosi = 0, 29 | kSpi1Mosi, 30 | kDisable 31 | }; 32 | 33 | enum struct SckName 34 | { 35 | kSpi0Sck = 0, 36 | kSpi1Sck, 37 | kDisable 38 | }; 39 | 40 | enum struct PcsName 41 | { 42 | kSpi0Pcs0 = 0, 43 | kSpi1Pcs0, 44 | kDisable 45 | }; 46 | 47 | static constexpr int GetMaxSpiPcsCount() 48 | { 49 | return static_cast(PcsName::kSpi1Pcs0); 50 | } 51 | }; 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /inc/libsc/system.h: -------------------------------------------------------------------------------- 1 | /* 2 | * system.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libsc/timer.h" 14 | 15 | #define USE_TIME_IN_125US 16 | 17 | namespace libsc 18 | { 19 | 20 | class System 21 | { 22 | public: 23 | static void Init(); 24 | 25 | static void DelayUs(const uint16_t us); 26 | static void DelayMs(const uint16_t ms); 27 | static void DelayS(const uint16_t s); 28 | 29 | /** 30 | * Return the time elapsed, in ms, since Init() 31 | * 32 | * @return 33 | */ 34 | static Timer::TimerInt Time(); 35 | #ifdef USE_TIME_IN_125US 36 | static Timer::TimerInt TimeIn125us(); 37 | #endif 38 | 39 | private: 40 | struct Impl; 41 | static Impl *m_instance; 42 | }; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/libutil/string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * string_utils.cpp 3 | * String util 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include "libutil/string.h" 18 | 19 | using namespace std; 20 | 21 | namespace libutil 22 | { 23 | 24 | string String::Format(const char *format, ...) 25 | { 26 | va_list vl; 27 | va_start(vl, format); 28 | const string &product = Format(format, &vl); 29 | va_end(vl); 30 | return product; 31 | } 32 | 33 | string String::Format(const char *format, va_list *vl) 34 | { 35 | static char product[64]; 36 | vsnprintf(product, 64 * sizeof(char), format, *vl); 37 | product[63] = '\0'; 38 | return product; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /inc/libbase/kl26/tpm_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tpm_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/kl26/tpm.h" 12 | #include "libbase/misc_types.h" 13 | 14 | namespace libbase 15 | { 16 | namespace kl26 17 | { 18 | 19 | class TpmUtils 20 | { 21 | public: 22 | static Uint GetTpmModule(const Tpm::Name tpm) 23 | { 24 | return static_cast(tpm) / Tpm::GetMaxTpmChannelCount(); 25 | } 26 | 27 | static Uint GetTpmChannel(const Tpm::Name tpm) 28 | { 29 | return static_cast(tpm) % Tpm::GetMaxTpmChannelCount(); 30 | } 31 | 32 | static Tpm::Name GetTpm(const Uint module, const Uint channel) 33 | { 34 | return static_cast(module * Tpm::GetMaxTpmChannelCount() 35 | + channel); 36 | } 37 | }; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /inc/libbase/k60/pin_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pin_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/k60/misc_utils.h" 12 | #include "libbase/k60/pin.h" 13 | #include "libbase/k60/pinout.h" 14 | 15 | namespace libbase 16 | { 17 | namespace k60 18 | { 19 | 20 | class PinUtils 21 | { 22 | public: 23 | static Uint GetPort(const Pin::Name pin) 24 | { 25 | return static_cast(pin) / PINOUT::GetPortPinCount(); 26 | } 27 | 28 | static Uint GetPinNumber(const Pin::Name pin) 29 | { 30 | return static_cast(pin) % PINOUT::GetPortPinCount(); 31 | } 32 | 33 | static Pin::Name GetPin(const Uint port, const Uint pin) 34 | { 35 | return static_cast(port * PINOUT::GetPortPinCount() + pin); 36 | } 37 | }; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /inc/libbase/helper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * helper.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #define QUOTE(str) #str 12 | #if MK60DZ10 || MK60D10 || MK60F15 13 | #define LIBBASE_H(module) QUOTE(libbase/k60/module.h) 14 | #define LIBBASE_NS libbase::k60 15 | #define LIBBASE_MODULE(module) LIBBASE_NS::module 16 | #define LIBSC_H(module) QUOTE(libsc/k60/module.h) 17 | #define LIBSC_NS libsc::k60 18 | #define LIBSC_MODULE(module) LIBSC_NS::module 19 | 20 | 21 | #elif MKL26Z4 22 | #define LIBBASE_H(module) QUOTE(libbase/kl26/module.h) 23 | #define LIBBASE_NS libbase::kl26 24 | #define LIBBASE_MODULE(module) LIBBASE_NS::module 25 | #define LIBSC_H(module) QUOTE(libsc/kl26/module.h) 26 | #define LIBSC_NS libsc::kl26 27 | #define LIBSC_MODULE(module) LIBSC_NS::module 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /inc/libbase/kl26/pin_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pin_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | 10 | #pragma once 11 | 12 | #include "libbase/kl26/misc_utils.h" 13 | #include "libbase/kl26/pin.h" 14 | #include "libbase/kl26/pinout.h" 15 | 16 | namespace libbase 17 | { 18 | namespace kl26 19 | { 20 | 21 | class PinUtils 22 | { 23 | public: 24 | static Uint GetPort(const Pin::Name pin) 25 | { 26 | return static_cast(pin) / PINOUT::GetPortPinCount(); 27 | } 28 | 29 | static Uint GetPinNumber(const Pin::Name pin) 30 | { 31 | return static_cast(pin) % PINOUT::GetPortPinCount(); 32 | } 33 | 34 | static Pin::Name GetPin(const Uint port, const Uint pin) 35 | { 36 | return static_cast(port * PINOUT::GetPortPinCount() + pin); 37 | } 38 | }; 39 | 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /inc/libsc/kl26/jy_mcu_bt_106.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jy_mcu_bt_106.h 3 | * JY-MCU BT Board v1.06 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "libbase/helper.h" 15 | #include LIBBASE_H(uart) 16 | 17 | #include "libsc/kl26/uart_device.h" 18 | 19 | namespace libsc 20 | { 21 | namespace kl26 22 | { 23 | 24 | class JyMcuBt106 : public UartDevice 25 | { 26 | public: 27 | typedef UartDevice::Config Config; 28 | 29 | explicit JyMcuBt106(const Config &config); 30 | 31 | protected: 32 | struct Initializer : public UartDevice::Initializer 33 | { 34 | explicit Initializer(const Config &config) 35 | : UartDevice::Initializer(config) 36 | {} 37 | 38 | LIBBASE_MODULE(Uart)::Config GetUartConfig() const override; 39 | }; 40 | }; 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /inc/libsc/led.h: -------------------------------------------------------------------------------- 1 | /* 2 | * led.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(gpio) 15 | 16 | namespace libsc 17 | { 18 | 19 | /** 20 | * LED 21 | * 22 | * Example: 23 | * @snippet test/src/k60/led_test.cpp conf 24 | * @snippet test/src/k60/led_test.cpp code 25 | */ 26 | class Led 27 | { 28 | public: 29 | struct Config 30 | { 31 | uint8_t id; 32 | bool is_active_low; 33 | }; 34 | 35 | explicit Led(const Config &config); 36 | 37 | void SetEnable(const bool flag); 38 | void Switch(); 39 | 40 | protected: 41 | LIBBASE_MODULE(Gpo)* GetPin() 42 | { 43 | return &m_pin; 44 | } 45 | 46 | private: 47 | LIBBASE_MODULE(Gpo) m_pin; 48 | bool m_is_active_low; 49 | }; 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /inc/libsc/k60/jy_mcu_bt_106.h: -------------------------------------------------------------------------------- 1 | /* 2 | * jy_mcu_bt_106.h 3 | * JY-MCU BT Board v1.06 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "libbase/k60/uart.h" 15 | 16 | #include "libsc/k60/uart_device.h" 17 | 18 | namespace libsc 19 | { 20 | namespace k60 21 | { 22 | 23 | class JyMcuBt106 : public UartDevice 24 | { 25 | public: 26 | typedef UartDevice::Config Config; 27 | 28 | explicit JyMcuBt106(const Config &config); 29 | explicit JyMcuBt106(nullptr_t); 30 | 31 | protected: 32 | struct Initializer : public UartDevice::Initializer 33 | { 34 | explicit Initializer(const Config &config) 35 | : UartDevice::Initializer(config) 36 | {} 37 | 38 | libbase::k60::Uart::Config GetUartConfig() const override; 39 | }; 40 | }; 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/libbase/k60/crc_utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * crc_utils.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include "libbase/k60/crc.h" 13 | #include "libbase/k60/crc_utils.h" 14 | #include "libbase/k60/misc_utils.h" 15 | 16 | namespace libbase 17 | { 18 | namespace k60 19 | { 20 | 21 | uint32_t CrcUtils::Calc(Crc *crc, const Byte *data, const size_t size) 22 | { 23 | crc->NewInstance(); 24 | const size_t size32 = size >> 2; 25 | for (size_t i = 0; i < size32; ++i) 26 | { 27 | uint32_t data32 = 0; 28 | data32 |= data[i * 4] << 24; 29 | data32 |= data[i * 4 + 1] << 16; 30 | data32 |= data[i * 4 + 2] << 8; 31 | data32 |= data[i * 4 + 3]; 32 | crc->PushData(data32); 33 | } 34 | for (size_t i = size32 * 4; i < size; ++i) 35 | { 36 | crc->PushData(data[i]); 37 | } 38 | return crc->GetCrc(); 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /inc/libsc/sys_tick_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sys_tick_timer.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(sys_tick) 15 | 16 | #include "libsc/timer.h" 17 | 18 | namespace libsc 19 | { 20 | 21 | class SysTickTimer : public Timer 22 | { 23 | public: 24 | SysTickTimer(); 25 | 26 | #ifndef USE_TIME_IN_125US 27 | TimerInt Time() override 28 | { 29 | return m_ms; 30 | } 31 | 32 | #else 33 | TimerInt Time() override 34 | { 35 | return m_125us >> 3; 36 | } 37 | 38 | TimerInt TimeIn125us() 39 | { 40 | return m_125us; 41 | } 42 | #endif 43 | 44 | private: 45 | void OnTick(LIBBASE_MODULE(SysTick)*); 46 | 47 | LIBBASE_MODULE(SysTick) m_pit; 48 | 49 | #ifndef USE_TIME_IN_125US 50 | volatile TimerInt m_ms; 51 | #else 52 | volatile TimerInt m_125us; 53 | #endif 54 | }; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /inc/libutil/fixed_circular_buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fixed_circular_buffer.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace libutil 17 | { 18 | 19 | /** 20 | * A fixed size buffer that would reject adding new data if old data are not 21 | * being consumed fast enough 22 | */ 23 | template 24 | class FixedCircularBuffer 25 | { 26 | public: 27 | explicit FixedCircularBuffer(const size_t capacity); 28 | 29 | uint32_t GetSize() const 30 | { 31 | return (uint32_t)(m_end - m_start); 32 | } 33 | 34 | bool PushData(T &&data); 35 | T* GetActiveData(); 36 | T* NextData(); 37 | 38 | private: 39 | const size_t m_capacity; 40 | std::unique_ptr m_data; 41 | uint32_t m_start; 42 | uint32_t m_end; 43 | }; 44 | 45 | } 46 | 47 | #include "fixed_circular_buffer.tcc" 48 | -------------------------------------------------------------------------------- /inc/libsc/ab_encoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ab_encoder.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libsc/config.h" 14 | #include "libsc/encoder.h" 15 | 16 | namespace libsc 17 | { 18 | 19 | /** 20 | * Phase A/B encoder. Provides two mechanisms to read the feedback value, 21 | * interrupt based software emulation and hardware quadrature decoding. Software 22 | * emulation will pose a large overhead to the system 23 | */ 24 | class AbEncoder : public Encoder 25 | { 26 | public: 27 | typedef Encoder::Config Config; 28 | 29 | explicit AbEncoder(const Config &config); 30 | 31 | protected: 32 | struct Initializer : public Encoder::Initializer 33 | { 34 | explicit Initializer(const Config &config) 35 | : Encoder::Initializer(config) 36 | {} 37 | 38 | QuadDecoder::Config GetQuadDecoderConfig() const override; 39 | }; 40 | }; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /inc/libsc/infra_red_sensor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * infra_red_sensor.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "libbase/helper.h" 16 | #include LIBBASE_H(gpio) 17 | 18 | namespace libsc 19 | { 20 | 21 | class InfraRedSensor 22 | { 23 | public: 24 | typedef std::function Listener; 25 | 26 | struct Config 27 | { 28 | enum struct Trigger 29 | { 30 | kEnter, 31 | kLeave, 32 | kBoth, 33 | }; 34 | 35 | uint8_t id; 36 | bool is_active_low; 37 | Listener listener; 38 | /// When to trigger the listener, ignored if Config::listener is not set 39 | Trigger listener_trigger; 40 | }; 41 | 42 | explicit InfraRedSensor(const Config &config); 43 | 44 | bool IsDetected() const; 45 | 46 | private: 47 | LIBBASE_MODULE(Gpi) m_pin; 48 | bool m_is_active_low; 49 | }; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/libsc/lib_guard.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * libsc_guard.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libsc/lib_guard.h" 10 | 11 | namespace libsc 12 | { 13 | 14 | #if defined(K60_INNO) 15 | const int kGuardK60Inno = 0; 16 | 17 | #elif defined(K60_2013_GEN2) 18 | const int kGuardK602013Gen2 = 0; 19 | 20 | #elif defined(K60_2013_CCD) 21 | const int kGuardK602013Ccd = 0; 22 | 23 | #elif defined(K60_2013_MAGNETIC) 24 | const int kGuardK602013Magnetic = 0; 25 | 26 | #elif defined(K60_2014) 27 | const int kGuardK602014 = 0; 28 | 29 | #elif defined(K60_2014_CAMERA) 30 | const int kGuardK602014Camera = 0; 31 | 32 | #elif defined(K60_2014_CCD) 33 | const int kGuardK602014Ccd = 0; 34 | 35 | #elif defined(K60_2014_INNO) 36 | const int kGuardK602014Inno = 0; 37 | 38 | #elif defined(K60_2014_MAGNETIC) 39 | const int kGuardK602014Magnetic = 0; 40 | 41 | #else 42 | const int kGuardNull = 0; 43 | 44 | #endif 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/libsc/pit_timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * timer.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(clock_utils) 15 | #include LIBBASE_H(pit) 16 | 17 | #include "libsc/pit_timer.h" 18 | 19 | using namespace LIBBASE_NS; 20 | 21 | namespace libsc 22 | { 23 | 24 | namespace 25 | { 26 | 27 | Pit::Config GetPitConfig(const uint8_t pit_channel, 28 | const Pit::OnPitTriggerListener &isr) 29 | { 30 | Pit::Config config; 31 | config.channel = pit_channel; 32 | config.count = ClockUtils::GetBusTickPerMs(); 33 | config.isr = isr; 34 | return config; 35 | } 36 | 37 | } 38 | 39 | PitTimer::PitTimer(const uint8_t pit_channel) 40 | : m_pit(GetPitConfig(pit_channel, std::bind(&PitTimer::OnTick, this, 41 | std::placeholders::_1))), 42 | m_ms(0) 43 | {} 44 | 45 | void PitTimer::OnTick(Pit*) 46 | { 47 | ++m_ms; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /inc/libbase/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * log.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #define LOG_E(fmt, ...) printf("E " fmt "\n", ##__VA_ARGS__) 14 | #define LOG_W(fmt, ...) printf("W " fmt "\n", ##__VA_ARGS__) 15 | #define LOG_I(fmt, ...) printf("I " fmt "\n", ##__VA_ARGS__) 16 | #ifdef DEBUG 17 | #define LOG_D(fmt, ...) printf("D " fmt "\n", ##__VA_ARGS__) 18 | #define LOG_V(fmt, ...) printf("V " fmt "\n", ##__VA_ARGS__) 19 | #else 20 | #define LOG_D(fmt, ...) 21 | #define LOG_V(fmt, ...) 22 | #endif /* DEBUG */ 23 | 24 | #define LOG_EL(literal) printf("E " literal "\n") 25 | #define LOG_WL(literal) printf("W " literal "\n") 26 | #define LOG_IL(literal) printf("I " literal "\n") 27 | #ifdef DEBUG 28 | #define LOG_DL(literal) printf("D " literal "\n") 29 | #define LOG_VL(literal) printf("V " literal "\n") 30 | #else 31 | #define LOG_DL(literal) 32 | #define LOG_VL(literal) 33 | #endif /* DEBUG */ 34 | -------------------------------------------------------------------------------- /inc/libsc/light_sensor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * light_sensor.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "libbase/helper.h" 16 | #include LIBBASE_H(gpio) 17 | 18 | namespace libsc 19 | { 20 | 21 | class LightSensor 22 | { 23 | public: 24 | typedef std::function Listener; 25 | 26 | struct Config 27 | { 28 | enum struct Trigger 29 | { 30 | kBright, 31 | kDark, 32 | kBoth, 33 | }; 34 | 35 | uint8_t id; 36 | bool is_active_low; 37 | Listener listener; 38 | /// When to trigger the listener, ignored if Config::listener is not set 39 | Trigger listener_trigger; 40 | }; 41 | 42 | explicit LightSensor(const Config &config); 43 | 44 | bool IsBright() const; 45 | bool IsDark() const 46 | { 47 | return !IsBright(); 48 | } 49 | 50 | private: 51 | LIBBASE_MODULE(Gpi) m_pin; 52 | bool m_is_active_low; 53 | }; 54 | 55 | } 56 | -------------------------------------------------------------------------------- /inc/libbase/k60/reg_file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * reg_file.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "libbase/misc_types.h" 16 | 17 | namespace libbase 18 | { 19 | namespace k60 20 | { 21 | 22 | class RegFile 23 | { 24 | public: 25 | static RegFile& Get() 26 | { 27 | static RegFile inst; 28 | return inst; 29 | } 30 | 31 | void Init(); 32 | 33 | void WriteVbat(const Uint seek, const Byte *data, const size_t size); 34 | void WriteVbat(const Uint seek, const Byte data); 35 | Byte ReadVbat(const Uint seek); 36 | std::vector ReadVbat(const Uint seek, const size_t size); 37 | 38 | void WriteSystem(const Uint seek, const Byte *data, const size_t size); 39 | void WriteSystem(const Uint seek, const Byte data); 40 | Byte ReadSystem(const Uint seek); 41 | std::vector ReadSystem(const Uint seek, const size_t size); 42 | 43 | private: 44 | RegFile(); 45 | }; 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /inc/libutil/endian_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * endian_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace libutil 14 | { 15 | 16 | class EndianUtils 17 | { 18 | public: 19 | static bool IsBigEndian(); 20 | static bool IsLittleEndian() 21 | { 22 | return !IsBigEndian(); 23 | } 24 | 25 | template 26 | static T Translate(const T from); 27 | static uint16_t Translate16(const uint16_t from); 28 | static uint32_t Translate32(const uint32_t from); 29 | 30 | /** 31 | * Host to big-endian encoding 32 | * 33 | * @param host Host byte order data 34 | * @return Big-endian data 35 | */ 36 | template 37 | static T HostToBe(const T host); 38 | /** 39 | * Host to little-endian encoding 40 | * 41 | * @param host Host byte order data 42 | * @return Little-endian data 43 | */ 44 | template 45 | static T HostToLe(const T host); 46 | }; 47 | 48 | } 49 | 50 | #include "endian_utils.tcc" 51 | -------------------------------------------------------------------------------- /inc/libbase/k60/spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | namespace libbase 12 | { 13 | namespace k60 14 | { 15 | 16 | class Spi 17 | { 18 | public: 19 | enum struct SinName 20 | { 21 | kSpi0Sin = 0, 22 | kSpi1Sin, 23 | kSpi2Sin, 24 | kDisable 25 | }; 26 | 27 | enum struct SoutName 28 | { 29 | kSpi0Sout = 0, 30 | kSpi1Sout, 31 | kSpi2Sout, 32 | kDisable 33 | }; 34 | 35 | enum struct SckName 36 | { 37 | kSpi0Sck = 0, 38 | kSpi1Sck, 39 | kSpi2Sck, 40 | kDisable 41 | }; 42 | 43 | enum struct PcsName 44 | { 45 | kSpi0Pcs0 = 0, 46 | kSpi0Pcs1, 47 | kSpi0Pcs2, 48 | kSpi0Pcs3, 49 | kSpi0Pcs4, 50 | kSpi0Pcs5, 51 | 52 | kSpi1Pcs0 = 6, 53 | kSpi1Pcs1, 54 | kSpi1Pcs2, 55 | kSpi1Pcs3, 56 | 57 | kSpi2Pcs0 = 12, 58 | kSpi2Pcs1, 59 | 60 | kDisable = 18 61 | }; 62 | 63 | static constexpr int GetMaxSpiPcsCount() 64 | { 65 | return static_cast(PcsName::kSpi1Pcs0); 66 | } 67 | }; 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/libsc/sys_tick_delay.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * sys_tick_delay.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libbase/helper.h" 12 | #include LIBBASE_H(clock_utils) 13 | #include LIBBASE_H(sys_tick) 14 | 15 | #include "libsc/sys_tick_delay.h" 16 | 17 | using namespace LIBBASE_NS; 18 | 19 | namespace libsc 20 | { 21 | 22 | namespace 23 | { 24 | 25 | SysTick::Config GetSysTickConfig() 26 | { 27 | SysTick::Config sc; 28 | sc.is_enable = false; 29 | return sc; 30 | } 31 | 32 | } 33 | 34 | SysTickDelay::SysTickDelay() 35 | : m_sys_tick(GetSysTickConfig()) 36 | {} 37 | 38 | inline void SysTickDelay::DelayCount(const uint32_t count) 39 | { 40 | m_sys_tick.SetCount(count); 41 | m_sys_tick.SetEnable(true); 42 | m_sys_tick.ConsumeInterrupt(); 43 | while (!m_sys_tick.IsInterruptRequested()) 44 | {} 45 | m_sys_tick.SetEnable(false); 46 | } 47 | 48 | void SysTickDelay::DelayUs(const uint16_t us) 49 | { 50 | DelayCount(ClockUtils::GetCoreTickPerUs(us)); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /inc/libbase/k60/ftm_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ftm_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/k60/ftm.h" 12 | #include "libbase/misc_types.h" 13 | 14 | namespace libbase 15 | { 16 | namespace k60 17 | { 18 | 19 | class FtmUtils 20 | { 21 | public: 22 | static Uint GetFtmModule(const Ftm::Name ftm) 23 | { 24 | return static_cast(ftm) / Ftm::GetMaxFtmChannelCount(); 25 | } 26 | 27 | static Uint GetFtmChannel(const Ftm::Name ftm) 28 | { 29 | return static_cast(ftm) % Ftm::GetMaxFtmChannelCount(); 30 | } 31 | 32 | static Ftm::Name GetFtm(const Uint module, const Uint channel) 33 | { 34 | return static_cast(module * Ftm::GetMaxFtmChannelCount() 35 | + channel); 36 | } 37 | 38 | static Uint GetFtmModule(const Ftm::QdName ftm_qd) 39 | { 40 | return static_cast(ftm_qd) >> 1; 41 | } 42 | 43 | static Uint GetFtmPhase(const Ftm::QdName ftm_qd) 44 | { 45 | return static_cast(ftm_qd) % 2; 46 | } 47 | }; 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/libbase/k60/dwt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * dwt.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/k60/hardware.h" 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/k60/clock_utils.h" 15 | #include "libbase/k60/dwt.h" 16 | #include "libbase/k60/misc_utils.h" 17 | 18 | namespace libbase 19 | { 20 | namespace k60 21 | { 22 | 23 | void Dwt::DelayUs(const uint16_t us) 24 | { 25 | if (GET_BIT(DWT->CTRL, DWT_CTRL_NOCYCCNT_Pos)) 26 | { 27 | // CYCCNT not implemented 28 | assert(false); 29 | return; 30 | } 31 | 32 | SET_BIT(CoreDebug->DEMCR, CoreDebug_DEMCR_TRCENA_Pos); 33 | CLEAR_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Pos); 34 | const uint32_t count = ClockUtils::GetCoreTickPerUs(us); 35 | DWT->CYCCNT = 0; 36 | SET_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Pos); 37 | uint32_t store = 0; 38 | uint32_t curr = 0; 39 | while (store + curr < count) 40 | { 41 | if (curr > DWT->CYCCNT) 42 | { 43 | store += curr; 44 | } 45 | curr = DWT->CYCCNT; 46 | } 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/libbase/kl26/watchdog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * watchdog.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/kl26/hardware.h" 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/kl26/watchdog.h" 15 | #include "libbase/kl26/watchdog_c.h" 16 | 17 | namespace libbase 18 | { 19 | namespace kl26 20 | { 21 | 22 | void Watchdog::Init() 23 | { 24 | const Config &config = GetWatchdogConfig(); 25 | 26 | InitCopcReg(config); 27 | } 28 | 29 | void Watchdog::InitCopcReg(const Config &config) 30 | { 31 | uint32_t reg = 0; 32 | reg |= SIM_COPC_COPT(static_cast(config.timeout)); 33 | 34 | SIM->COPC = reg; 35 | } 36 | 37 | void Watchdog::Refresh() 38 | { 39 | __disable_irq(); 40 | SIM->SRVCOP = SIM_SRVCOP_SRVCOP(0x55); 41 | SIM->SRVCOP = SIM_SRVCOP_SRVCOP(0xAA); 42 | __enable_irq(); 43 | } 44 | 45 | Watchdog::Config Watchdog::GetWatchdogConfig() 46 | { 47 | return {}; 48 | } 49 | 50 | } 51 | } 52 | 53 | void LibbaseKl26WatchdogInit() 54 | { 55 | libbase::kl26::Watchdog::Init(); 56 | } 57 | -------------------------------------------------------------------------------- /src/libsc/dir_encoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * dir_encoder.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/helper.h" 10 | #include LIBBASE_H(soft_quad_decoder) 11 | #if MK60DZ10 || MK60D10 || MK60F15 12 | #include LIBBASE_H(ftm_quad_decoder) 13 | #endif 14 | 15 | #include "libsc/config.h" 16 | #include "libsc/dir_encoder.h" 17 | 18 | using namespace LIBBASE_NS; 19 | 20 | namespace libsc 21 | { 22 | 23 | #if LIBSC_USE_ENCODER 24 | 25 | Encoder::QuadDecoder::Config DirEncoder::Initializer::GetQuadDecoderConfig() const 26 | { 27 | Encoder::QuadDecoder::Config product = 28 | Encoder::Initializer::GetQuadDecoderConfig(); 29 | product.encoding_mode = 30 | Encoder::QuadDecoder::Config::EncodingMode::kCountDirection; 31 | return product; 32 | } 33 | 34 | DirEncoder::DirEncoder(const Config &config) 35 | : Encoder(Initializer(config)) 36 | {} 37 | 38 | #else /* LIBSC_USE_ENCODER */ 39 | DirEncoder::DirEncoder(const Config&) 40 | : Encoder(nullptr) 41 | {} 42 | 43 | #endif /* LIBSC_USE_ENCODER */ 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/libsc/ab_encoder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ab_encoder.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libbase/helper.h" 12 | #include LIBBASE_H(soft_quad_decoder) 13 | #if MK60DZ10 || MK60D10 || MK60F15 14 | #include LIBBASE_H(ftm_quad_decoder) 15 | #endif 16 | 17 | #include "libsc/config.h" 18 | #include "libsc/ab_encoder.h" 19 | 20 | using namespace LIBBASE_NS; 21 | 22 | namespace libsc 23 | { 24 | 25 | #if LIBSC_USE_ENCODER 26 | 27 | Encoder::QuadDecoder::Config AbEncoder::Initializer::GetQuadDecoderConfig() const 28 | { 29 | Encoder::QuadDecoder::Config product = 30 | Encoder::Initializer::GetQuadDecoderConfig(); 31 | product.encoding_mode = 32 | Encoder::QuadDecoder::Config::EncodingMode::kPhaseAB; 33 | return product; 34 | } 35 | 36 | AbEncoder::AbEncoder(const Config &config) 37 | : Encoder(Initializer(config)) 38 | {} 39 | 40 | #else /* LIBSC_USE_ENCODER */ 41 | AbEncoder::AbEncoder(const Config&) 42 | : Encoder(nullptr) 43 | {} 44 | 45 | #endif /* LIBSC_USE_ENCODER */ 46 | 47 | } 48 | -------------------------------------------------------------------------------- /inc/libsc/dir_motor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dir_motor.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include "libbase/pinout_macros.h" 15 | #include LIBBASE_H(gpio) 16 | 17 | #if PINOUT_FTM_COUNT 18 | #include LIBBASE_H(ftm_pwm) 19 | 20 | #elif PINOUT_TPM_COUNT 21 | #include LIBBASE_H(tpm_pwm) 22 | 23 | #endif // PINOUT_FTM_COUNT 24 | 25 | #include "libsc/motor.h" 26 | 27 | namespace libsc 28 | { 29 | 30 | class DirMotor : public Motor 31 | { 32 | public: 33 | #if PINOUT_FTM_COUNT 34 | typedef LIBBASE_MODULE(FtmPwm) Pwm; 35 | 36 | #elif PINOUT_TPM_COUNT 37 | typedef LIBBASE_MODULE(TpmPwm) Pwm; 38 | 39 | #endif // PINOUT_FTM_COUNT 40 | 41 | struct Config : public Motor::Config 42 | { 43 | uint8_t id; 44 | }; 45 | 46 | explicit DirMotor(const Config &config); 47 | 48 | private: 49 | void OnSetPower(const uint16_t power) override; 50 | void OnSetClockwise(const bool flag) override; 51 | 52 | Pwm m_pwm; 53 | LIBBASE_MODULE(Gpo) m_dir; 54 | }; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /inc/libsc/ldc1000.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ldc1000.h 3 | * 4 | * Author: Petel__ 5 | * Copyright (c) 2014-2016 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(gpio) 15 | 16 | using namespace LIBBASE_NS; 17 | 18 | namespace libsc 19 | { 20 | 21 | class Ldc1000 22 | { 23 | 24 | public: 25 | 26 | //Need configuration 27 | struct Config 28 | { 29 | uint8_t id; 30 | }; 31 | 32 | // explicit Lcd1000(const Config &config); 33 | 34 | Ldc1000(const Config &config); 35 | void Update(void); 36 | 37 | uint16_t GetData(void); 38 | uint32_t GetFreq(void); 39 | 40 | private: 41 | 42 | void InitPin(uint8_t id); 43 | 44 | uint8_t DataRW(uint8_t rwData); 45 | uint8_t ReadData(const uint8_t reg); 46 | uint8_t WriteData(const uint8_t reg, const uint8_t data); 47 | void ReadBuffer(void); 48 | 49 | uint8_t m_buf[12]; 50 | 51 | Gpo m_mosi; 52 | Gpo m_cs; 53 | Gpo m_sck; 54 | Gpio m_miso; 55 | 56 | uint16_t m_proxData; 57 | uint32_t m_freq; 58 | 59 | }; 60 | 61 | } 62 | -------------------------------------------------------------------------------- /inc/libbase/k60/adc_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * adc_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/k60/adc.h" 14 | #include "libbase/k60/misc_utils.h" 15 | 16 | namespace libbase 17 | { 18 | namespace k60 19 | { 20 | 21 | class AdcUtils 22 | { 23 | public: 24 | static Uint GetModule(const Adc::Name adc) 25 | { 26 | return static_cast(adc) / Adc::kModuleChannelCount; 27 | } 28 | 29 | static Uint GetChannel(const Adc::Name adc) 30 | { 31 | return static_cast(adc) % Adc::kModuleChannelCount; 32 | } 33 | 34 | static Uint GetChannelNumber(const Adc::Name adc) 35 | { 36 | const Uint channel = GetChannel(adc); 37 | if (channel >= (Uint)Adc::Name::kAdc0Ad4B) 38 | { 39 | return channel - 4; 40 | } 41 | else 42 | { 43 | return channel; 44 | } 45 | } 46 | 47 | static Adc::Name GetPin(const Uint module, const Uint channel) 48 | { 49 | return static_cast(module * Adc::kModuleChannelCount 50 | + channel); 51 | } 52 | }; 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/libutil/endian_utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * endian_utils.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include "libutil/endian_utils.h" 13 | #include "libutil/misc.h" 14 | #include "libbase/misc_types.h" 15 | 16 | namespace libutil 17 | { 18 | 19 | namespace 20 | { 21 | 22 | bool IsBigEndian_() 23 | { 24 | const uint16_t bom = 0xFFFE; 25 | return (reinterpret_cast(&bom)[0] == 0xFF); 26 | } 27 | 28 | } 29 | 30 | bool EndianUtils::IsBigEndian() 31 | { 32 | static const bool is_be = IsBigEndian_(); 33 | return is_be; 34 | } 35 | 36 | uint16_t EndianUtils::Translate16(const uint16_t from) 37 | { 38 | uint16_t to = from; 39 | Byte *bytes = reinterpret_cast(&to); 40 | std::swap(bytes[0], bytes[1]); 41 | return to; 42 | } 43 | 44 | uint32_t EndianUtils::Translate32(const uint32_t from) 45 | { 46 | uint32_t to = from; 47 | Byte *bytes = reinterpret_cast(&to); 48 | std::swap(bytes[0], bytes[3]); 49 | std::swap(bytes[1], bytes[2]); 50 | return to; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /inc/libbase/k60/crc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * crc.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/k60/misc_utils.h" 15 | 16 | namespace libbase 17 | { 18 | namespace k60 19 | { 20 | 21 | class Crc 22 | { 23 | public: 24 | struct Config 25 | { 26 | uint32_t polynomial = 0x04C11DB7; 27 | uint32_t seed = 0xFFFFFFFF; 28 | }; 29 | 30 | explicit Crc(const Config &config); 31 | explicit Crc(nullptr_t); 32 | Crc(const Crc&) = delete; 33 | Crc(Crc &&rhs); 34 | ~Crc(); 35 | 36 | Crc& operator=(const Crc&) = delete; 37 | Crc& operator=(Crc &&rhs); 38 | operator bool() const 39 | { 40 | return m_is_init; 41 | } 42 | 43 | void NewInstance(const uint32_t seed); 44 | void NewInstance() 45 | { 46 | NewInstance(m_seed); 47 | } 48 | 49 | void PushData(const uint32_t data); 50 | void PushData(const Byte data); 51 | 52 | uint32_t GetCrc() const; 53 | 54 | private: 55 | void Uninit(); 56 | 57 | uint32_t m_seed; 58 | 59 | bool m_is_init; 60 | }; 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /inc/libbase/kl26/adc_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * adc_utils.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/kl26/adc.h" 14 | #include "libbase/kl26/misc_utils.h" 15 | 16 | namespace libbase 17 | { 18 | namespace kl26 19 | { 20 | 21 | class AdcUtils 22 | { 23 | public: 24 | static Uint GetModule(const Adc::Name pin) 25 | { 26 | return static_cast(pin) / Adc::kModuleChannelCount; 27 | } 28 | 29 | static Uint GetChannel(const Adc::Name pin) 30 | { 31 | return static_cast(pin) % Adc::kModuleChannelCount; 32 | } 33 | 34 | static Uint GetChannelNumber(const Adc::Name pin) 35 | { 36 | const Uint channel = GetChannel(pin); 37 | if (channel >= (Uint)Adc::Name::kAdc0Ad4B) 38 | { 39 | return channel - 4; 40 | } 41 | else 42 | { 43 | return channel; 44 | } 45 | } 46 | 47 | static Adc::Name GetPin(const Uint module, const Uint channel) 48 | { 49 | return static_cast(module * Adc::kModuleChannelCount 50 | + channel); 51 | } 52 | }; 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /inc/libsc/alternate_motor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * alternate_motor.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include "libbase/pinout_macros.h" 15 | 16 | #if PINOUT_FTM_COUNT 17 | #include LIBBASE_H(ftm_pwm) 18 | 19 | #elif PINOUT_TPM_COUNT 20 | #include LIBBASE_H(tpm_pwm) 21 | 22 | #endif // PINOUT_FTM_COUNT 23 | 24 | #include "libsc/motor.h" 25 | 26 | namespace libsc 27 | { 28 | 29 | class AlternateMotor : public Motor 30 | { 31 | public: 32 | #if PINOUT_FTM_COUNT 33 | typedef LIBBASE_MODULE(FtmPwm) Pwm; 34 | 35 | #elif PINOUT_TPM_COUNT 36 | typedef LIBBASE_MODULE(TpmPwm) Pwm; 37 | 38 | #endif // PINOUT_FTM_COUNT 39 | 40 | struct Config : public Motor::Config 41 | { 42 | uint8_t id; 43 | }; 44 | 45 | explicit AlternateMotor(const Config &config); 46 | 47 | private: 48 | void OnSetPower(const uint16_t power) override; 49 | void OnSetClockwise(const bool flag) override; 50 | 51 | Pwm m_pwms[2]; 52 | Pwm *m_active_pwm; 53 | uint32_t m_pos_width; 54 | }; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/libutil/math.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * math.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libutil/math.h" 12 | 13 | #define SQRT_MAGIC_F 0x5F3759DF 14 | 15 | namespace libutil 16 | { 17 | 18 | /* Formula From Cecil Hastings */ 19 | float Math::ArcTan(float x) 20 | { 21 | float y = (fabs(x) - 1) / (fabs(x) + 1); 22 | float z = y * y; 23 | return (.785398f + (.995354f + (-.288679f + .079331f * z) * z) * y) 24 | * ((x < 0) ? -1 : 1); 25 | } 26 | 27 | 28 | // ArcSin : http://cpp.sh/7po 29 | // http://cpp.sh/5fqt 30 | float Math::ArcSin(float x) 31 | { 32 | return 1.570796f - Sqrt2(1 - x) * (1.570723f - x * (0.212114f + x 33 | * (.074261f + x * (-.018729f)))); 34 | } 35 | 36 | float Math::Sqrt2(const float x) 37 | { 38 | const float xhalf = 0.5f * x; 39 | union // get bits for floating value 40 | { 41 | float x; 42 | int i; 43 | } u; 44 | u.x = x; 45 | u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0 46 | // Newton step, repeating increases accuracy 47 | return x * u.x * (1.5f - xhalf * u.x * u.x); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/libutil/misc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * misc.cpp 3 | * Misc util 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #include 11 | 12 | #include "libbase/helper.h" 13 | #include "libbase/syscall.h" 14 | 15 | #if MK60DZ10 || MK60D10 || MK60F15 16 | #include "libsc/k60/uart_device.h" 17 | 18 | #elif MKL26Z4 19 | #include "libsc/kl26/uart_device.h" 20 | 21 | #endif 22 | 23 | #include "libutil/misc.h" 24 | 25 | #if MK60DZ10 || MK60D10 || MK60F15 26 | using namespace libsc::k60; 27 | 28 | #elif MKL26Z4 29 | using namespace libsc::kl26; 30 | 31 | #endif 32 | 33 | namespace libutil 34 | { 35 | 36 | namespace 37 | { 38 | 39 | UartDevice *g_uart = nullptr; 40 | 41 | int MyFwriteHandler(int, char *ptr, int len) 42 | { 43 | if (g_uart) 44 | { 45 | g_uart->SendBuffer(reinterpret_cast(ptr), len); 46 | } 47 | return len; 48 | } 49 | 50 | } 51 | 52 | void InitDefaultFwriteHandler(UartDevice *uart) 53 | { 54 | g_uart = uart; 55 | g_fwrite_handler = MyFwriteHandler; 56 | } 57 | 58 | void UninitDefaultFwriteHandler() 59 | { 60 | g_uart = nullptr; 61 | g_fwrite_handler = nullptr; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/libsc/pit_delay.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * pit_delay.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libbase/helper.h" 12 | #include LIBBASE_H(clock_utils) 13 | #include LIBBASE_H(pit) 14 | 15 | #include "libsc/pit_delay.h" 16 | 17 | using namespace LIBBASE_NS; 18 | 19 | namespace libsc 20 | { 21 | 22 | namespace 23 | { 24 | 25 | Pit::Config GetPitConfig(const uint8_t channel) 26 | { 27 | Pit::Config pc; 28 | pc.channel = channel; 29 | pc.is_enable = false; 30 | return pc; 31 | } 32 | 33 | } 34 | 35 | PitDelay::PitDelay(const uint8_t channel) 36 | : m_pit(GetPitConfig(channel)) 37 | {} 38 | 39 | inline void PitDelay::DelayCount(const uint32_t count) 40 | { 41 | m_pit.SetCount(count); 42 | m_pit.SetEnable(true); 43 | m_pit.ConsumeInterrupt(); 44 | while (!m_pit.IsInterruptRequested()) 45 | {} 46 | m_pit.SetEnable(false); 47 | } 48 | 49 | void PitDelay::DelayUs(const uint16_t us) 50 | { 51 | DelayCount(ClockUtils::GetBusTickPerUs(us)); 52 | } 53 | 54 | void PitDelay::DelayMs(const uint16_t ms) 55 | { 56 | DelayCount(ClockUtils::GetBusTickPerMs(ms)); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /inc/libbase/k60/pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pwm.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/k60/pin.h" 14 | 15 | namespace libbase 16 | { 17 | namespace k60 18 | { 19 | 20 | class Pwm 21 | { 22 | public: 23 | struct Config 24 | { 25 | enum struct Precision 26 | { 27 | kUs, 28 | kNs, 29 | }; 30 | 31 | Pin::Name pin; 32 | uint32_t period; 33 | uint32_t pos_width; 34 | /** 35 | * Set the unit of Config::period and Config::pos_width. It is useful 36 | * when the period is too small such that the precision is not high 37 | * enough. Otherwise, the default should be kept 38 | * 39 | * @note Should only select Precision::kNs when period < 1000 us. 40 | * Otherwise integer overflow may occur during some calculations 41 | */ 42 | Precision precision = Precision::kUs; 43 | }; 44 | 45 | virtual ~Pwm() 46 | {} 47 | 48 | virtual operator bool() const = 0; 49 | 50 | virtual void SetPeriod(const uint32_t period, const uint32_t pos_width) = 0; 51 | virtual void SetPosWidth(const uint32_t pos_width) = 0; 52 | }; 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /inc/libbase/kl26/pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pwm.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/kl26/pin.h" 14 | 15 | namespace libbase 16 | { 17 | namespace kl26 18 | { 19 | 20 | class Pwm 21 | { 22 | public: 23 | struct Config 24 | { 25 | enum struct Precision 26 | { 27 | kUs, 28 | kNs, 29 | }; 30 | 31 | Pin::Name pin; 32 | uint32_t period; 33 | uint32_t pos_width; 34 | /** 35 | * Set the unit of Config::period and Config::pos_width. It is useful 36 | * when the period is too small such that the precision is not high 37 | * enough. Otherwise, the default should be kept 38 | * 39 | * @note Should only select Precision::kNs when period < 1000 us. 40 | * Otherwise integer overflow may occur during some calculations 41 | */ 42 | Precision precision = Precision::kUs; 43 | }; 44 | 45 | virtual ~Pwm() 46 | {} 47 | 48 | virtual operator bool() const = 0; 49 | 50 | virtual void SetPeriod(const uint32_t period, const uint32_t pos_width) = 0; 51 | virtual void SetPosWidth(const uint32_t pos_width) = 0; 52 | }; 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /inc/libbase/kl26/tpm_counter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tpm_counter.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/kl26/pin.h" 15 | 16 | namespace libbase 17 | { 18 | namespace kl26 19 | { 20 | 21 | class TpmCounter 22 | { 23 | public: 24 | struct Config 25 | { 26 | uint8_t module; 27 | Pin::Name clockin_pin; 28 | }; 29 | 30 | explicit TpmCounter(const Config &config); 31 | explicit TpmCounter(nullptr_t); 32 | TpmCounter(const TpmCounter&) = delete; 33 | TpmCounter(TpmCounter &&rhs); 34 | ~TpmCounter(); 35 | 36 | TpmCounter& operator=(const TpmCounter&) = delete; 37 | TpmCounter& operator=(TpmCounter &&rhs); 38 | operator bool() const 39 | { 40 | return m_is_init; 41 | } 42 | 43 | void Update(); 44 | 45 | uint16_t GetCount() const 46 | { 47 | return m_count; 48 | } 49 | 50 | private: 51 | bool InitSim(const Pin::Name pin); 52 | bool InitClockPin(const Pin::Name pin); 53 | 54 | void Uninit(); 55 | 56 | uint8_t m_module; 57 | uint16_t m_count; 58 | 59 | Pin m_clkin; 60 | 61 | bool m_is_init; 62 | }; 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /inc/libbase/k60/rand_generator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rand_generator.h 3 | * Random Number Generator Accelerator 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | namespace libbase 16 | { 17 | namespace k60 18 | { 19 | 20 | class RandGenerator 21 | { 22 | public: 23 | struct Config 24 | { 25 | /** 26 | * Set the external entropy, should also toggle is_ext_entropy to 27 | * respect this value 28 | */ 29 | uint32_t entropy; 30 | bool is_ext_entropy; 31 | }; 32 | 33 | explicit RandGenerator(const Config &config); 34 | explicit RandGenerator(nullptr_t); 35 | RandGenerator(const RandGenerator&) = delete; 36 | RandGenerator(RandGenerator &&rhs); 37 | ~RandGenerator(); 38 | 39 | RandGenerator& operator=(const RandGenerator&) = delete; 40 | RandGenerator& operator=(RandGenerator &&rhs); 41 | operator bool() const 42 | { 43 | return m_is_init; 44 | } 45 | 46 | void SetEntropy(const uint32_t entropy); 47 | 48 | bool IsReady() const; 49 | uint32_t GetRand() const; 50 | 51 | private: 52 | void Uninit(); 53 | 54 | bool m_is_init; 55 | }; 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/libsc/kl26/jy_mcu_bt_106.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * jy_mcu_bt_106.cpp 3 | * JY-MCU BT Board v1.06 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #include 11 | 12 | #include "libbase/helper.h" 13 | #include LIBBASE_H(pin) 14 | #include LIBBASE_H(uart) 15 | 16 | #include "libsc/config.h" 17 | #include "libsc/kl26/jy_mcu_bt_106.h" 18 | 19 | using namespace LIBBASE_NS; 20 | 21 | namespace libsc 22 | { 23 | namespace kl26 24 | { 25 | 26 | #ifdef LIBSC_USE_UART 27 | 28 | Uart::Config JyMcuBt106::Initializer::GetUartConfig() const 29 | { 30 | Uart::Config product = UartDevice::Initializer::GetUartConfig(); 31 | // On this board, there's a diode connected to the Tx pin, preventing the 32 | // module to correctly send data to the MCU 33 | product.rx_config[Pin::Config::kPullEnable] = true; 34 | product.rx_config[Pin::Config::kPullUp] = true; 35 | return product; 36 | } 37 | 38 | JyMcuBt106::JyMcuBt106(const Config &config) 39 | : UartDevice(Initializer(config)) 40 | {} 41 | 42 | #else /* LIBSC_USE_UART */ 43 | JyMcuBt106::JyMcuBt106(const Config&) 44 | : UartDevice(nullptr) 45 | {} 46 | 47 | #endif /* LIBSC_USE_UART */ 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /inc/libbase/k60/fpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fpu.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | namespace libbase 12 | { 13 | namespace k60 14 | { 15 | 16 | class Fpu 17 | { 18 | public: 19 | struct Config 20 | { 21 | enum struct RoundingMode 22 | { 23 | kNearest = 0, 24 | kPosInf, 25 | kNegInf, 26 | kZero, 27 | }; 28 | 29 | /// Enable the default NaN mode, see p.63 of DDI0403D 30 | bool is_default_nan = true; 31 | /** 32 | * Enable the flush-to-zero mode, which effectively discard subnormal 33 | * numbers, see p.62 of DDI0403D 34 | */ 35 | bool is_flush_to_zero = true; 36 | /** 37 | * Set the floating point rounding mode, has nothing to do with the 38 | * float->int conversion 39 | */ 40 | RoundingMode rounding_mode = RoundingMode::kNearest; 41 | }; 42 | 43 | static Fpu& Get() 44 | { 45 | static Fpu inst; 46 | return inst; 47 | } 48 | 49 | void Init(); 50 | 51 | private: 52 | Fpu(); 53 | 54 | __attribute__((__weak__)) 55 | static Config GetFpuConfig(); 56 | 57 | void InitFpccr(const Config &config); 58 | void InitFpdscr(const Config &config); 59 | }; 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/libsc/kl26/system.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * system.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include "libsc/config.h" 13 | #include "libsc/kl26/lptmr_timer.h" 14 | #include "libsc/system.h" 15 | #include "libsc/sys_tick_delay.h" 16 | 17 | using namespace libbase::kl26; 18 | using namespace libsc::kl26; 19 | 20 | namespace libsc 21 | { 22 | 23 | System::Impl *System::m_instance = nullptr; 24 | 25 | struct System::Impl 26 | { 27 | SysTickDelay delay; 28 | LptmrTimer timer; 29 | }; 30 | 31 | void System::Init() 32 | { 33 | if (!m_instance) 34 | { 35 | m_instance = new Impl; 36 | } 37 | } 38 | 39 | void System::DelayUs(const uint16_t us) 40 | { 41 | assert(m_instance); 42 | m_instance->delay.DelayUs(us); 43 | } 44 | 45 | void System::DelayMs(const uint16_t ms) 46 | { 47 | assert(m_instance); 48 | m_instance->delay.DelayMs(ms); 49 | } 50 | 51 | void System::DelayS(const uint16_t s) 52 | { 53 | assert(m_instance); 54 | m_instance->delay.DelayS(s); 55 | } 56 | 57 | Timer::TimerInt System::Time() 58 | { 59 | assert(m_instance); 60 | return m_instance->timer.Time(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/libsc/kl26/lptmr_timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * lptmr_timer.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include 12 | 13 | #include "libbase/kl26/clock_utils.h" 14 | #include "libbase/kl26/lptmr.h" 15 | 16 | #include "libsc/kl26/lptmr_timer.h" 17 | 18 | using namespace libbase::kl26; 19 | 20 | namespace libsc 21 | { 22 | namespace kl26 23 | { 24 | 25 | namespace 26 | { 27 | 28 | Lptmr::Config GetLptmrConfig(const Lptmr::OnLptmrTriggerListener &isr) 29 | { 30 | Lptmr::Config product; 31 | product.count = UINT16_MAX; 32 | product.isr = isr; 33 | return product; 34 | } 35 | 36 | } 37 | 38 | LptmrTimer::LptmrTimer() 39 | : m_lptmr(GetLptmrConfig(std::bind(&LptmrTimer::OnTick, this, 40 | std::placeholders::_1))), 41 | m_ms(0) 42 | {} 43 | 44 | Timer::TimerInt LptmrTimer::Time() 45 | { 46 | const uint16_t curr_counter = m_lptmr.GetCounter(); 47 | if (curr_counter != m_prev_counter) 48 | { 49 | m_ms += (uint16_t)(curr_counter - m_prev_counter); 50 | m_prev_counter = curr_counter; 51 | } 52 | return m_ms; 53 | } 54 | 55 | void LptmrTimer::OnTick(Lptmr*) 56 | { 57 | Time(); 58 | } 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /inc/libbase/k60/mcg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mcg.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/k60/mcg_c.h" 14 | 15 | namespace libbase 16 | { 17 | namespace k60 18 | { 19 | 20 | class Mcg 21 | { 22 | public: 23 | struct Config 24 | { 25 | Config(); 26 | 27 | uint32_t external_oscillator_khz; 28 | uint32_t core_clock_khz; 29 | uint32_t bus_clock_khz; 30 | uint32_t flexbus_clock_khz; 31 | uint32_t flash_clock_khz; 32 | }; 33 | 34 | static Mcg& Get() 35 | { 36 | static Mcg inst; 37 | return inst; 38 | } 39 | 40 | void Init(); 41 | 42 | uint32_t GetCoreClock() 43 | { 44 | return m_core_clock; 45 | } 46 | 47 | private: 48 | Mcg(); 49 | 50 | /** 51 | * Get the Config object used during initialization, to be implemented by 52 | * user 53 | * 54 | * @return 55 | */ 56 | static Config GetMcgConfig(); 57 | 58 | void InitFbe(const Config &config); 59 | void InitPbe(const Config &config, const uint8_t vdiv); 60 | void InitPee(const Config &config); 61 | void InitClocks(const Config &config, const uint32_t core_clock); 62 | 63 | uint32_t m_core_clock; 64 | }; 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /inc/libsc/tsl1401cl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tsl1401cl.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/helper.h" 15 | #include LIBBASE_H(adc) 16 | #include LIBBASE_H(gpio) 17 | 18 | namespace libsc 19 | { 20 | 21 | /** 22 | * TSL1401CL linear CCD 23 | */ 24 | class Tsl1401cl 25 | { 26 | public: 27 | static constexpr int kSensorW = 128; 28 | 29 | explicit Tsl1401cl(const uint8_t id); 30 | 31 | void StartSample(); 32 | bool SampleProcess(); 33 | /** 34 | * Return the latest completely captured data, where dark pixel is false, 35 | * true otherwise 36 | * 37 | * @return 38 | */ 39 | const std::array& GetData() const 40 | { 41 | return m_front_buffer; 42 | } 43 | 44 | bool IsImageReady() const 45 | { 46 | return (m_index >= kSensorW); 47 | } 48 | 49 | private: 50 | inline void Delay(); 51 | 52 | LIBBASE_MODULE(Adc) m_ad_pin; 53 | LIBBASE_MODULE(Gpo) m_clk_pin; 54 | LIBBASE_MODULE(Gpo) m_si_pin; 55 | 56 | std::array m_front_buffer; 57 | std::array m_back_buffer; 58 | 59 | int m_index; 60 | }; 61 | 62 | } 63 | -------------------------------------------------------------------------------- /inc/libsc/button.h: -------------------------------------------------------------------------------- 1 | /* 2 | * button.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "libbase/helper.h" 17 | #include LIBBASE_H(gpio) 18 | 19 | namespace libsc 20 | { 21 | 22 | class Button 23 | { 24 | public: 25 | typedef std::function Listener; 26 | 27 | struct Config 28 | { 29 | enum struct Trigger 30 | { 31 | kDown, 32 | kUp, 33 | kBoth, 34 | }; 35 | 36 | uint8_t id; 37 | bool is_active_low; 38 | /** 39 | * If set, the internal resistor will be used to hold the pin deserted. 40 | * Useful if the button is not connected to one on the board 41 | */ 42 | bool is_use_pull_resistor = false; 43 | Listener listener; 44 | /// When to trigger the listener, ignored if Config::listener is not set 45 | Trigger listener_trigger; 46 | }; 47 | 48 | explicit Button(const Config &config); 49 | explicit Button(nullptr_t); 50 | 51 | bool IsDown() const; 52 | bool IsUp() const 53 | { 54 | return !IsDown(); 55 | } 56 | 57 | private: 58 | LIBBASE_MODULE(Gpi) m_pin; 59 | bool m_is_active_low; 60 | }; 61 | 62 | } 63 | -------------------------------------------------------------------------------- /inc/libbase/kl26/mcg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mcg.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/kl26/mcg_c.h" 14 | 15 | namespace libbase 16 | { 17 | namespace kl26 18 | { 19 | 20 | class Mcg 21 | { 22 | public: 23 | struct Config 24 | { 25 | Config(); 26 | 27 | uint32_t external_oscillator_khz; 28 | /// The core and the system clock 29 | uint32_t core_clock_khz; 30 | /// The bus and the flash clock 31 | uint32_t bus_clock_khz; 32 | }; 33 | 34 | static Mcg& Get() 35 | { 36 | static Mcg inst; 37 | return inst; 38 | } 39 | 40 | void Init(); 41 | 42 | uint32_t GetCoreClock() 43 | { 44 | return m_core_clock; 45 | } 46 | 47 | private: 48 | Mcg(); 49 | 50 | /** 51 | * Get the Config object used during initialization, to be implemented by 52 | * user 53 | * 54 | * @return 55 | */ 56 | static Config GetMcgConfig(); 57 | 58 | void InitFbe(const Config &config); 59 | void InitPbe(const Config &config, const uint8_t vdiv); 60 | void InitPee(const Config &config); 61 | void InitClocks(const Config &config, const uint32_t core_clock); 62 | 63 | uint32_t m_core_clock; 64 | }; 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /inc/libutil/fixed_circular_buffer.tcc: -------------------------------------------------------------------------------- 1 | /* 2 | * fixed_circular_buffer.tcc 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace libutil 17 | { 18 | 19 | template 20 | FixedCircularBuffer::FixedCircularBuffer(const size_t capacity) 21 | : m_capacity(capacity), 22 | m_data(new T[capacity]), 23 | m_start(0), 24 | m_end(0) 25 | {} 26 | 27 | template 28 | bool FixedCircularBuffer::PushData(T &&data) 29 | { 30 | if (GetSize() == m_capacity) 31 | { 32 | return false; 33 | } 34 | else 35 | { 36 | m_data[m_end++ % m_capacity] = std::move(data); 37 | return true; 38 | } 39 | } 40 | 41 | template 42 | T* FixedCircularBuffer::GetActiveData() 43 | { 44 | if (GetSize() == 0) 45 | { 46 | return nullptr; 47 | } 48 | else 49 | { 50 | return &m_data[m_start % m_capacity]; 51 | } 52 | } 53 | 54 | template 55 | T* FixedCircularBuffer::NextData() 56 | { 57 | if (GetSize() == 0) 58 | { 59 | return nullptr; 60 | } 61 | else 62 | { 63 | ++m_start; 64 | return GetActiveData(); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/libsc/k60/jy_mcu_bt_106.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * jy_mcu_bt_106.cpp 3 | * JY-MCU BT Board v1.06 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #include 11 | 12 | #include "libbase/k60/pin.h" 13 | #include "libbase/k60/uart.h" 14 | 15 | #include "libsc/config.h" 16 | #include "libsc/k60/jy_mcu_bt_106.h" 17 | 18 | using namespace libbase::k60; 19 | 20 | namespace libsc 21 | { 22 | namespace k60 23 | { 24 | 25 | #ifdef LIBSC_USE_UART 26 | 27 | Uart::Config JyMcuBt106::Initializer::GetUartConfig() const 28 | { 29 | Uart::Config product = UartDevice::Initializer::GetUartConfig(); 30 | // On this board, there's a diode connected to the Tx pin, preventing the 31 | // module to correctly send data to the MCU 32 | product.rx_config[Pin::Config::kPullEnable] = true; 33 | product.rx_config[Pin::Config::kPullUp] = true; 34 | return product; 35 | } 36 | 37 | JyMcuBt106::JyMcuBt106(const Config &config) 38 | : UartDevice(Initializer(config)) 39 | {} 40 | 41 | #else /* LIBSC_USE_UART */ 42 | JyMcuBt106::JyMcuBt106(const Config&) 43 | : UartDevice(nullptr) 44 | {} 45 | 46 | JyMcuBt106::JyMcuBt106(nullptr_t) 47 | : 48 | UartDevice(nullptr) 49 | {} 50 | 51 | #endif /* LIBSC_USE_UART */ 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/libsc/sys_tick_timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * sys_tick_timer.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(clock_utils) 15 | #include LIBBASE_H(sys_tick) 16 | 17 | #include "libsc/system.h" 18 | #include "libsc/sys_tick_timer.h" 19 | 20 | using namespace LIBBASE_NS; 21 | 22 | namespace libsc 23 | { 24 | 25 | namespace 26 | { 27 | 28 | SysTick::Config GetSysTickConfig(const SysTick::OnSysTickTriggerListener &isr) 29 | { 30 | SysTick::Config config; 31 | 32 | #ifndef USE_TIME_IN_125US 33 | config.count = ClockUtils::GetCoreTickPerMs(); 34 | #else 35 | config.count = (uint32_t)(ClockUtils::GetCoreTickPerMs() / 8.38); 36 | #endif 37 | 38 | config.isr = isr; 39 | return config; 40 | } 41 | 42 | } 43 | 44 | SysTickTimer::SysTickTimer() 45 | : m_pit(GetSysTickConfig(std::bind(&SysTickTimer::OnTick, this, 46 | std::placeholders::_1))), 47 | #ifndef USE_TIME_IN_125US 48 | m_ms(0) 49 | #else 50 | m_125us(0) 51 | #endif 52 | {} 53 | 54 | void SysTickTimer::OnTick(SysTick*) 55 | { 56 | #ifndef USE_TIME_IN_125US 57 | ++m_ms; 58 | #else 59 | ++m_125us; 60 | #endif 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /inc/libutil/endian_utils.tcc: -------------------------------------------------------------------------------- 1 | /* 2 | * endian_utils.tcc 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libutil/endian_utils.h" 12 | 13 | namespace libutil 14 | { 15 | 16 | namespace internal 17 | { 18 | 19 | template 20 | struct Translate_ 21 | { 22 | static T Do(const T from); 23 | }; 24 | 25 | template 26 | struct Translate_ 27 | { 28 | static T Do(const T from) 29 | { 30 | return EndianUtils::Translate16(from); 31 | } 32 | }; 33 | 34 | template 35 | struct Translate_ 36 | { 37 | static T Do(const T from) 38 | { 39 | return EndianUtils::Translate32(from); 40 | } 41 | }; 42 | 43 | } 44 | 45 | template 46 | T EndianUtils::Translate(const T from) 47 | { 48 | return internal::Translate_::Do(from); 49 | } 50 | 51 | template 52 | T EndianUtils::HostToBe(const T host) 53 | { 54 | if (IsLittleEndian()) 55 | { 56 | return Translate(host); 57 | } 58 | else 59 | { 60 | return host; 61 | } 62 | } 63 | 64 | template 65 | T EndianUtils::HostToLe(const T host) 66 | { 67 | if (IsBigEndian()) 68 | { 69 | return Translate(host); 70 | } 71 | else 72 | { 73 | return host; 74 | } 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /inc/libbase/k60/pin_isr_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pin_isr_manager.h 3 | * Manage ISR for pins 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #include "libbase/k60/gpio.h" 16 | #include "libbase/k60/misc_utils.h" 17 | #include "libbase/k60/pin.h" 18 | #include "libbase/k60/pinout.h" 19 | 20 | namespace libbase 21 | { 22 | namespace k60 23 | { 24 | 25 | class PinIsrManager 26 | { 27 | public: 28 | typedef std::function OnPinIrqListener; 29 | 30 | static void SetPinIsr(libbase::k60::Pin *pin, const OnPinIrqListener &isr) 31 | { 32 | GetInstance()->SetPinIsr_(pin, isr); 33 | } 34 | 35 | private: 36 | struct PinData 37 | { 38 | Pin *pin = nullptr; 39 | OnPinIrqListener isr = nullptr; 40 | }; 41 | 42 | PinIsrManager(); 43 | ~PinIsrManager(); 44 | 45 | void InitPort(const Uint port); 46 | 47 | static PinIsrManager* GetInstance(); 48 | 49 | void SetPinIsr_(libbase::k60::Pin *pin, const OnPinIrqListener &isr); 50 | 51 | template 52 | static __ISR void PortIrqHandler(); 53 | 54 | PinData* m_pin_data[PINOUT::GetPortCount()]; 55 | bool m_is_enable[PINOUT::GetPortCount()]; 56 | 57 | static PinIsrManager *m_instance; 58 | }; 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/libsc/battery_meter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * battery_meter.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/log.h" 10 | #include "libbase/helper.h" 11 | #include LIBBASE_H(adc) 12 | 13 | #include "libsc/config.h" 14 | #include "libsc/battery_meter.h" 15 | 16 | using namespace LIBBASE_NS; 17 | 18 | namespace libsc 19 | { 20 | 21 | #ifdef LIBSC_USE_BATTERY_METER 22 | 23 | namespace 24 | { 25 | 26 | Adc::Config GetAdcConfig() 27 | { 28 | Adc::Config config; 29 | config.adc = LIBSC_BATTERY_METER; 30 | config.speed = Adc::Config::SpeedMode::kExSlow; 31 | config.is_continuous_mode = true; 32 | config.avg_pass = Adc::Config::AveragePass::k32; 33 | return config; 34 | } 35 | 36 | } 37 | 38 | BatteryMeter::BatteryMeter(const Config &config) 39 | : m_adc(GetAdcConfig()), 40 | m_voltage_ratio(1.0f / config.voltage_ratio) 41 | { 42 | m_adc.StartConvert(); 43 | } 44 | 45 | float BatteryMeter::GetVoltage() 46 | { 47 | return m_adc.GetResultF() * m_voltage_ratio; 48 | } 49 | 50 | #else 51 | BatteryMeter::BatteryMeter(const Config&) 52 | : m_adc(nullptr), m_voltage_ratio(0.0f) 53 | { 54 | LOG_DL("Configured not to use BatteryMeter"); 55 | } 56 | float BatteryMeter::GetVoltage() { return 0.0f; } 57 | 58 | #endif /* LIBSC_USE_BATTERY_METER */ 59 | 60 | } 61 | -------------------------------------------------------------------------------- /inc/libbase/kl26/pin_isr_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pin_isr_manager.h 3 | * Manage ISR for pins 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | 16 | #include "libbase/kl26/gpio.h" 17 | #include "libbase/kl26/misc_utils.h" 18 | #include "libbase/kl26/pin.h" 19 | #include "libbase/kl26/pinout.h" 20 | 21 | namespace libbase 22 | { 23 | namespace kl26 24 | { 25 | 26 | class PinIsrManager 27 | { 28 | public: 29 | typedef std::function OnPinIrqListener; 30 | 31 | static void SetPinIsr(libbase::kl26::Pin *pin, const OnPinIrqListener &isr) 32 | { 33 | GetInstance()->SetPinIsr_(pin, isr); 34 | } 35 | 36 | private: 37 | struct PinData 38 | { 39 | Pin *pin = nullptr; 40 | OnPinIrqListener isr = nullptr; 41 | }; 42 | 43 | PinIsrManager(); 44 | ~PinIsrManager(); 45 | 46 | void InitPort(const Uint port); 47 | 48 | static PinIsrManager* GetInstance(); 49 | 50 | void SetPinIsr_(libbase::kl26::Pin *pin, const OnPinIrqListener &isr); 51 | 52 | template 53 | static __ISR void PortIrqHandler(); 54 | 55 | PinData* m_pin_data[PINOUT::GetPortCount()]; 56 | bool m_is_enable[PINOUT::GetPortCount()]; 57 | 58 | static PinIsrManager *m_instance; 59 | }; 60 | 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/libutil/kalman_filter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * kalman_filter.h 3 | * 4 | * Author: Tommy Wong 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libutil/kalman_filter.h" 10 | 11 | namespace libutil 12 | { 13 | 14 | KalmanFilter::KalmanFilter(const float q, const float r, const float x, 15 | const float p) 16 | : m_q(q), m_r(r), m_k(0), m_x(x), m_lx(0), m_p(p), m_lp(0) 17 | {} 18 | 19 | float KalmanFilter::Filter(const float data) 20 | { 21 | PredictState(); 22 | PredictCovariance(); 23 | Gain(); 24 | UpdateState(data); 25 | UpdateCovariance(); 26 | return m_x; 27 | } 28 | 29 | void KalmanFilter::SetQ(const float lpQ) 30 | { 31 | m_q = lpQ; 32 | } 33 | 34 | void KalmanFilter::SetR(const float lpR) 35 | { 36 | m_r = lpR; 37 | } 38 | 39 | void KalmanFilter::SetX(const float lpX) 40 | { 41 | m_x = lpX; 42 | } 43 | 44 | void KalmanFilter::SetP(const float lpP) 45 | { 46 | m_p = lpP; 47 | } 48 | 49 | void KalmanFilter::PredictState() 50 | { 51 | m_lx = m_x; 52 | } 53 | 54 | void KalmanFilter::PredictCovariance() 55 | { 56 | m_lp = m_p + m_q; 57 | } 58 | 59 | void KalmanFilter::UpdateState(const float z) 60 | { 61 | m_x = m_lx + (m_k * (z - m_lx)); 62 | } 63 | 64 | void KalmanFilter::UpdateCovariance() 65 | { 66 | m_p = (1 - m_k) * m_lp; 67 | } 68 | 69 | void KalmanFilter::Gain() 70 | { 71 | m_k = m_lp / (m_lp + m_r); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /inc/libutil/pid_controller.tcc: -------------------------------------------------------------------------------- 1 | /* 2 | * pid_controller.tcc 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014 Ming Tsang 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "libutil/pid_controller.h" 16 | #include "libutil/misc.h" 17 | 18 | namespace libutil 19 | { 20 | 21 | template 22 | PidController::PidController(const InT setpoint, const float kp, 23 | const float ki, const float kd) 24 | : m_setpoint(setpoint), 25 | m_kp(kp), 26 | m_ki(ki), 27 | m_kd(kd), 28 | 29 | m_p(0.0f), 30 | m_i(0.0f), 31 | m_d(0.0f), 32 | 33 | m_min_o(std::numeric_limits::min()), 34 | m_max_o(std::numeric_limits::max()) 35 | { 36 | static_assert(std::is_signed::value, "Input type must be signed"); 37 | } 38 | 39 | template 40 | OutT_ PidController::Calc(const InT current_val) 41 | { 42 | const InT error = m_setpoint - current_val; 43 | OnCalc(error); 44 | m_prev_out = libutil::Clamp(m_min_o, GetControlOut(), m_max_o); 45 | return m_prev_out; 46 | } 47 | 48 | template 49 | void PidController::UpdatePid(const float p, const float i, 50 | const float d) 51 | { 52 | m_p = p; 53 | m_i = i; 54 | m_d = d; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/libbase/kl26/clock_utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * clock_utils.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | 10 | #include "libbase/kl26/hardware.h" 11 | 12 | #include 13 | 14 | #include "libbase/kl26/clock_utils.h" 15 | #include "libbase/kl26/mcg.h" 16 | #include "libbase/kl26/misc_utils.h" 17 | #include "libbase/kl26/sim.h" 18 | 19 | namespace libbase 20 | { 21 | namespace kl26 22 | { 23 | 24 | namespace 25 | { 26 | 27 | uint32_t GetBusClock_() 28 | { 29 | return Mcg::Get().GetCoreClock() / Sim::GetBusClockDivider(); 30 | } 31 | 32 | } 33 | 34 | uint32_t ClockUtils::GetCoreClock() 35 | { 36 | return Mcg::Get().GetCoreClock(); 37 | } 38 | 39 | uint32_t ClockUtils::GetCoreClockKhz() 40 | { 41 | static uint32_t cache = GetCoreClock() / 1000; 42 | return cache; 43 | } 44 | 45 | uint32_t ClockUtils::GetCoreClockMhz() 46 | { 47 | static uint32_t cache = GetCoreClock() / 1000000; 48 | return cache; 49 | } 50 | 51 | uint32_t ClockUtils::GetBusClock() 52 | { 53 | static uint32_t cache = GetBusClock_(); 54 | return cache; 55 | } 56 | 57 | uint32_t ClockUtils::GetBusClockKhz() 58 | { 59 | static uint32_t cache = GetBusClock() / 1000; 60 | return cache; 61 | } 62 | 63 | uint32_t ClockUtils::GetBusClockMhz() 64 | { 65 | static uint32_t cache = GetBusClock() / 1000000; 66 | return cache; 67 | } 68 | 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /inc/libbase/k60/soft_sccb_master.h: -------------------------------------------------------------------------------- 1 | /* 2 | * soft_sccb_master.h 3 | * OmniVision Serial Camera Control Bus master 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "libbase/k60/gpio.h" 13 | #include "libbase/k60/pin.h" 14 | #include "libbase/k60/soft_i2c_master.h" 15 | #include "libbase/misc_types.h" 16 | 17 | namespace libbase 18 | { 19 | namespace k60 20 | { 21 | 22 | class SoftSccbMaster 23 | { 24 | public: 25 | struct Config 26 | { 27 | // 3-Wire SCCB is currently NOT supported 28 | //Pin::Name sccb_e_pin = Pin::Name::kDisable; 29 | Pin::Name sio_c_pin; 30 | Pin::Name sio_d_pin; 31 | }; 32 | 33 | explicit SoftSccbMaster(const Config &config); 34 | explicit SoftSccbMaster(nullptr_t); 35 | SoftSccbMaster(const SoftSccbMaster&) = delete; 36 | SoftSccbMaster(SoftSccbMaster &&rhs); 37 | ~SoftSccbMaster(); 38 | 39 | SoftSccbMaster& operator=(const SoftSccbMaster&) = delete; 40 | SoftSccbMaster& operator=(SoftSccbMaster &&rhs); 41 | operator bool() const 42 | { 43 | return m_is_init; 44 | } 45 | 46 | bool GetByte(const Byte slave_addr, const Byte reg_addr, Byte *out_byte); 47 | bool SendByte(const Byte slave_addr, const Byte reg_addr, const Byte byte); 48 | 49 | private: 50 | void Uninit(); 51 | 52 | //Gpo m_sccb_e; 53 | SoftI2cMaster m_i2c; 54 | 55 | bool m_is_init; 56 | }; 57 | 58 | } 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /inc/libsc/joystick.h: -------------------------------------------------------------------------------- 1 | /* 2 | * joystick.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/helper.h" 15 | #include LIBBASE_H(gpio) 16 | 17 | namespace libsc 18 | { 19 | 20 | class Joystick 21 | { 22 | public: 23 | 24 | enum struct State 25 | { 26 | kUp = 0, 27 | kDown, 28 | kLeft, 29 | kRight, 30 | kSelect, 31 | 32 | kIdle 33 | }; 34 | 35 | typedef std::function Listener; 36 | 37 | struct Config 38 | { 39 | enum struct Trigger 40 | { 41 | kDown, 42 | kUp, 43 | kBoth, 44 | }; 45 | 46 | uint8_t id; 47 | bool is_active_low; 48 | 49 | /** 50 | * Choose either five handlers or one dispatcher to handle all events. 51 | * Once you set dispatcher, all listeners will be ignored. 52 | */ 53 | Listener dispatcher; 54 | Listener handlers[5]; 55 | 56 | /** 57 | * When to trigger the listener, ignored if corresponding listener is 58 | * not set in Config::listeners. The sequence of the array follows the 59 | * State enum 60 | */ 61 | Trigger listener_triggers[5]; 62 | }; 63 | 64 | explicit Joystick(const Config &config); 65 | explicit Joystick(nullptr_t); 66 | 67 | State GetState() const; 68 | 69 | private: 70 | LIBBASE_MODULE(Gpi) m_pins[5]; 71 | bool m_is_active_low; 72 | }; 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/libsc/motor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * motor.cpp 3 | * 4 | * Author: Harrison Ng, Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libbase/log.h" 12 | 13 | #include "libsc/config.h" 14 | #include "libsc/motor.h" 15 | #include "libutil/misc.h" 16 | 17 | namespace libsc 18 | { 19 | 20 | #ifdef LIBSC_USE_MOTOR 21 | 22 | Motor::Motor(const Config &config) 23 | : m_multiplier(config.multiplier), 24 | m_power(0), 25 | m_is_clockwise(true) 26 | {} 27 | 28 | void Motor::SetPower(const uint16_t power) 29 | { 30 | const uint16_t real_power = libutil::Clamp(0, 31 | power * m_multiplier / 100, 1000); 32 | if (m_power == real_power) 33 | { 34 | return; 35 | } 36 | 37 | OnSetPower(real_power); 38 | m_power = real_power; 39 | } 40 | 41 | void Motor::AddPower(const int16_t power) 42 | { 43 | SetPower(libutil::Clamp(0, m_power + power, 1000)); 44 | } 45 | 46 | void Motor::SetClockwise(const bool flag) 47 | { 48 | if (m_is_clockwise == flag) 49 | { 50 | return; 51 | } 52 | 53 | OnSetClockwise(flag); 54 | m_is_clockwise = flag; 55 | } 56 | 57 | #else 58 | Motor::Motor(const Config&) 59 | : m_multiplier(100), m_power(0), m_is_clockwise(true) 60 | { 61 | LOG_DL("Configured not to use Motor"); 62 | } 63 | void Motor::SetPower(const uint16_t) {} 64 | void Motor::AddPower(const int16_t) {} 65 | void Motor::SetClockwise(const bool) {} 66 | 67 | #endif 68 | 69 | } 70 | -------------------------------------------------------------------------------- /inc/libbase/k60/sys_tick.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sys_tick.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "libbase/k60/misc_utils.h" 17 | 18 | #ifdef SysTick 19 | #undef SysTick 20 | #endif 21 | 22 | namespace libbase 23 | { 24 | namespace k60 25 | { 26 | 27 | class SysTick 28 | { 29 | public: 30 | typedef std::function OnSysTickTriggerListener; 31 | 32 | struct Config 33 | { 34 | uint32_t count; 35 | OnSysTickTriggerListener isr; 36 | bool is_enable = true; 37 | }; 38 | 39 | explicit SysTick(const Config &config); 40 | explicit SysTick(nullptr_t); 41 | SysTick(const SysTick&) = delete; 42 | SysTick(SysTick &&rhs); 43 | ~SysTick(); 44 | 45 | SysTick& operator=(const SysTick&) = delete; 46 | SysTick& operator=(SysTick &&rhs); 47 | operator bool() const 48 | { 49 | return m_is_init; 50 | } 51 | 52 | void SetEnable(const bool flag); 53 | 54 | void SetCount(const uint32_t count); 55 | uint32_t GetCountLeft() const; 56 | 57 | void ConsumeInterrupt(); 58 | bool IsInterruptRequested() const; 59 | 60 | private: 61 | void InitCsrReg(const Config &config); 62 | void SetIsr(const OnSysTickTriggerListener &isr); 63 | void Uninit(); 64 | 65 | static __ISR void IrqHandler(); 66 | 67 | OnSysTickTriggerListener m_isr; 68 | 69 | bool m_is_init; 70 | }; 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /inc/libbase/kl26/sys_tick.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sys_tick.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "libbase/kl26/misc_utils.h" 17 | 18 | #ifdef SysTick 19 | #undef SysTick 20 | #endif 21 | 22 | namespace libbase 23 | { 24 | namespace kl26 25 | { 26 | 27 | class SysTick 28 | { 29 | public: 30 | typedef std::function OnSysTickTriggerListener; 31 | 32 | struct Config 33 | { 34 | uint32_t count; 35 | OnSysTickTriggerListener isr; 36 | bool is_enable = true; 37 | }; 38 | 39 | explicit SysTick(const Config &config); 40 | explicit SysTick(nullptr_t); 41 | SysTick(const SysTick&) = delete; 42 | SysTick(SysTick &&rhs); 43 | ~SysTick(); 44 | 45 | SysTick& operator=(const SysTick&) = delete; 46 | SysTick& operator=(SysTick &&rhs); 47 | operator bool() const 48 | { 49 | return m_is_init; 50 | } 51 | 52 | void SetEnable(const bool flag); 53 | 54 | void SetCount(const uint32_t count); 55 | uint32_t GetCountLeft() const; 56 | 57 | void ConsumeInterrupt(); 58 | bool IsInterruptRequested() const; 59 | 60 | private: 61 | void InitCsrReg(const Config &config); 62 | void SetIsr(const OnSysTickTriggerListener &isr); 63 | void Uninit(); 64 | 65 | static __ISR void IrqHandler(); 66 | 67 | OnSysTickTriggerListener m_isr; 68 | 69 | bool m_is_init; 70 | }; 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/libbase/k60/spi_utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * spi_utils.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include "libbase/k60/misc_utils.h" 12 | #include "libbase/k60/pin.h" 13 | #include "libbase/k60/spi_utils.h" 14 | 15 | namespace libbase 16 | { 17 | namespace k60 18 | { 19 | 20 | Uint SpiUtils::GetCsNumber(const Pin::Name pin) 21 | { 22 | switch (pin) 23 | { 24 | case Pin::Name::kPta14: 25 | return 0; 26 | 27 | case Pin::Name::kPtb9: 28 | return 1; 29 | 30 | case Pin::Name::kPtb10: 31 | return 0; 32 | 33 | case Pin::Name::kPtb20: 34 | return 0; 35 | 36 | case Pin::Name::kPtc0: 37 | return 4; 38 | 39 | case Pin::Name::kPtc1: 40 | return 3; 41 | 42 | case Pin::Name::kPtc2: 43 | return 2; 44 | 45 | case Pin::Name::kPtc3: 46 | return 1; 47 | 48 | case Pin::Name::kPtc4: 49 | return 0; 50 | 51 | case Pin::Name::kPtd0: 52 | return 0; 53 | 54 | case Pin::Name::kPtd4: 55 | return 1; 56 | 57 | case Pin::Name::kPtd5: 58 | return 2; 59 | 60 | case Pin::Name::kPtd6: 61 | return 3; 62 | 63 | case Pin::Name::kPtd11: 64 | return 0; 65 | 66 | case Pin::Name::kPtd15: 67 | return 1; 68 | 69 | case Pin::Name::kPte0: 70 | return 1; 71 | 72 | case Pin::Name::kPte4: 73 | return 0; 74 | 75 | case Pin::Name::kPte5: 76 | return 2; 77 | 78 | case Pin::Name::kPte6: 79 | return 3; 80 | 81 | default: 82 | assert(false); 83 | return 0; 84 | } 85 | } 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /inc/libsc/k60/config/2014.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 2014.h 3 | * Config file for 2014 Gen 1 board 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #ifndef LIBSC_2014_H_ 11 | #define LIBSC_2014_H_ 12 | 13 | /* 14 | * The number should represent the number of devices available, e.g., 15 | * define LIBSC_USE_UART to 2 when there are two UART devices connected. Comment 16 | * out the specific defines instead of defining them to 0 for unused devices 17 | */ 18 | #define LIBSC_USE_UART 1 19 | // Support 2 encoders only when using FTM 20 | #define LIBSC_USE_ENCODER 2 21 | #define LIBSC_USE_ENCODER_FTM 22 | //#define LIBSC_USE_LCD 1 23 | //#define LIBSC_USE_LCD_HW_SPI 24 | #define LIBSC_USE_LED 4 25 | #define LIBSC_USE_MOTOR 1 26 | #define LIBSC_USE_SERVO 1 27 | #define LIBSC_USE_LINEAR_CCD 1 28 | 29 | #define LIBSC_BT_UART UART3 30 | #define LIBSC_BT_UART_BAUD 115200 31 | 32 | #ifdef LIBSC_USE_ENCODER_FTM 33 | #define LIBSC_ENCODER0_OUT PTB0 34 | #define LIBSC_ENCODER0_VCC PTB1 35 | #define LIBSC_ENCODER1_OUT PTB18 36 | #define LIBSC_ENCODER1_VCC PTB19 37 | 38 | #else 39 | #define LIBSC_ENCODER0 PTB18 40 | 41 | #endif 42 | 43 | #define LIBSC_LED0 PTE9 44 | #define LIBSC_LED1 PTE10 45 | #define LIBSC_LED2 PTE11 46 | #define LIBSC_LED3 PTE12 47 | #define LIBSC_MOTOR0_PWM PTA8 48 | #define LIBSC_MOTOR0_DIR PTD7 49 | #define LIBSC_SERVO0 PTC2 50 | #define LIBSC_LINEAR_CCD0_AO PTB10 51 | #define LIBSC_LINEAR_CCD0_CLK PTB9 52 | #define LIBSC_LINEAR_CCD0_SI PTB8 53 | 54 | #endif /* LIBSC_2014_H_ */ 55 | -------------------------------------------------------------------------------- /inc/libsc/device_h/st7735r.h: -------------------------------------------------------------------------------- 1 | /* 2 | * st7735r.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #define ST7735R_NOP 0x00 // NOP 12 | #define ST7735R_SWRESET 0x01 // Software Reset 13 | #define ST7735R_RDDID 0x04 // Read Display ID 14 | #define ST7735R_SLPIN 0x10 // Sleep In 15 | #define ST7735R_SLPOUT 0x11 // Sleep Out 16 | #define ST7735R_INVOFF 0x20 // Display Inversion Off 17 | #define ST7735R_INVON 0x21 // Display Inversion On 18 | #define ST7735R_DISPOFF 0x28 // Display Off 19 | #define ST7735R_DISPON 0x29 // Display On 20 | #define ST7735R_CASET 0x2A // Column Address Set 21 | #define ST7735R_RASET 0x2B // Row Address Set 22 | #define ST7735R_RAMWR 0x2C // Memory Write 23 | #define ST7735R_MADCTL 0x36 // Memory Data Access Control 24 | #define ST7735R_COLMOD 0x3A // Interface Pixel Format 25 | #define ST7735R_FRMCTR1 0xB1 // Frame Rate Control (in normal mode) 26 | #define ST7735R_INVCTR 0xB4 // Display Inversion Control 27 | #define ST7735R_PWCTR1 0xC0 // Power Control 1 28 | #define ST7735R_PWCTR2 0xC1 // Power Control 2 29 | #define ST7735R_PWCTR3 0xC2 // Power Control 3 (in normal mode) 30 | #define ST7735R_PWCTR4 0xC3 // Power Control 4 (in idle/8-bit mode) 31 | #define ST7735R_PWCTR5 0xC4 // Power Control 5 (in partial mode) 32 | #define ST7735R_VMCTR1 0xC5 // VCOM Control 1 33 | #define ST7735R_GMCTRP1 0xE0 // Gamma (+ polarity) Correction Characteristics Setting 34 | #define ST7735R_GMCTRN1 0xE1 // Gamma (- polarity) Correction Characteristics Setting 35 | -------------------------------------------------------------------------------- /src/libbase/k60/clock_utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * clock_utils.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/k60/hardware.h" 10 | 11 | #include 12 | 13 | #include "libbase/k60/clock_utils.h" 14 | #include "libbase/k60/mcg.h" 15 | #include "libbase/k60/misc_utils.h" 16 | 17 | namespace libbase 18 | { 19 | namespace k60 20 | { 21 | 22 | namespace 23 | { 24 | 25 | uint32_t GetBusClock_() 26 | { 27 | const Uint core_div = ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) 28 | >> SIM_CLKDIV1_OUTDIV1_SHIFT) + 1; 29 | const Uint bus_div = ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) 30 | >> SIM_CLKDIV1_OUTDIV2_SHIFT) + 1; 31 | return Mcg::Get().GetCoreClock() * core_div / bus_div; 32 | } 33 | 34 | } 35 | 36 | uint32_t ClockUtils::GetCoreClock() 37 | { 38 | return Mcg::Get().GetCoreClock(); 39 | } 40 | 41 | uint32_t ClockUtils::GetCoreClockKhz() 42 | { 43 | static uint32_t cache = GetCoreClock() / 1000; 44 | return cache; 45 | } 46 | 47 | Uint ClockUtils::GetCoreClockMhz() 48 | { 49 | static uint32_t cache = GetCoreClock() / 1000000; 50 | return cache; 51 | } 52 | 53 | uint32_t ClockUtils::GetBusClock() 54 | { 55 | static uint32_t cache = GetBusClock_(); 56 | return cache; 57 | } 58 | 59 | uint32_t ClockUtils::GetBusClockKhz() 60 | { 61 | static uint32_t cache = GetBusClock() / 1000; 62 | return cache; 63 | } 64 | 65 | Uint ClockUtils::GetBusClockMhz() 66 | { 67 | static uint32_t cache = GetBusClock() / 1000000; 68 | return cache; 69 | } 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /inc/libsc/passive_buzzer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * passive_buzzer.h 3 | * 4 | * Author: Kyle Lei 5 | * Copyright (c) 2016 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/helper.h" 15 | #include "libbase/pinout_macros.h" 16 | #include LIBBASE_H(soft_pwm) 17 | 18 | namespace libsc { 19 | 20 | /** 21 | * add "#define LIBSC_PASSSIVE_BUZZER0_PIT_CHANNEL 1" && "#define LIBSC_USE_PASSIVE_BUZZER 1" to config file 22 | * to use passive buzzer 23 | */ 24 | class PassiveBuzzer { 25 | public: 26 | 27 | typedef LIBBASE_MODULE(SoftPwm) Pwm;//used SoftPwm since its freq can be adjusted at any time 28 | 29 | struct Config { 30 | uint32_t freq = 440; 31 | uint32_t pos = 0; 32 | uint8_t id = 0; 33 | }; 34 | 35 | explicit PassiveBuzzer(const Config &config); 36 | 37 | //note in Hz, refer to libutil/notes.h for frequencies 38 | void SetNote(const uint32_t note); 39 | //duty_cycle like the setpower for motors, [0,1000], the sonic texture of the sound will change 40 | //note that when set to 1000, the passive buzzer won't respond since the input is a constant voltage 41 | void SetTexture(const uint32_t duty_cycle); 42 | //set note and texture at the same time 43 | void Set(const uint32_t note,const uint32_t duty_cycle); 44 | 45 | //these two are identical with the simple buzzer 46 | void SetBeep(const bool is_beep); 47 | 48 | bool GetBeep() const {return (bool) m_duty_cycle;}; 49 | 50 | private: 51 | Pwm m_pwm; 52 | 53 | uint32_t m_note; 54 | uint32_t m_duty_cycle; 55 | 56 | }; 57 | 58 | } 59 | -------------------------------------------------------------------------------- /inc/libutil/incremental_pid_controller.h: -------------------------------------------------------------------------------- 1 | /* 2 | * incremental_pid_controller.h 3 | * Generic incremental PID controller 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #if MK60DZ10 || MK60D10 || MK60F15 13 | #include "libsc/system.h" 14 | 15 | #elif MKL26Z4 16 | #include "libsc/kl26/system.h" 17 | 18 | #endif 19 | 20 | #include "libsc/timer.h" 21 | #include "libutil/pid_controller.h" 22 | 23 | namespace libutil 24 | { 25 | 26 | template 27 | class IncrementalPidController : public PidController 28 | { 29 | public: 30 | typedef InT_ InT; 31 | typedef OutT_ OutT; 32 | 33 | IncrementalPidController(const InT setpoint, const float kp, const float ki, 34 | const float kd); 35 | 36 | /** 37 | * Set the upper bound of i, <= 0 means unlimited i 38 | * 39 | * @param value 40 | */ 41 | void SetILimit(const float value) 42 | { 43 | m_i_limit = value; 44 | } 45 | 46 | void Reset() 47 | { 48 | ResetTime(); 49 | } 50 | 51 | void ResetTime() 52 | { 53 | #if MK60DZ10 || MK60D10 || MK60F15 54 | m_prev_time = libsc::System::Time(); 55 | #elif MKL26Z4 56 | m_prev_time = libsc::kl26::System::Time(); 57 | #endif 58 | } 59 | 60 | protected: 61 | void OnCalc(const InT error) override; 62 | OutT GetControlOut() override; 63 | 64 | private: 65 | float m_i_limit; 66 | 67 | InT m_prev_error[2]; 68 | OutT m_prev_output; 69 | libsc::Timer::TimerInt m_prev_time; 70 | }; 71 | 72 | } 73 | 74 | #include "incremental_pid_controller.tcc" 75 | -------------------------------------------------------------------------------- /inc/libsc/us_100.h: -------------------------------------------------------------------------------- 1 | /* 2 | * us_100.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include "libbase/misc_types.h" 15 | #include LIBBASE_H(uart) 16 | 17 | namespace libsc 18 | { 19 | 20 | /** 21 | * Ultra-sonic sensor US-100, communicating through the UART 22 | */ 23 | class Us100 24 | { 25 | public: 26 | struct Config 27 | { 28 | uint8_t id; 29 | }; 30 | 31 | explicit Us100(const Config &config); 32 | ~Us100(); 33 | 34 | /** 35 | * Start shooting waves 36 | */ 37 | void Start(); 38 | /** 39 | * Stop shooting waves after finishing the current one 40 | */ 41 | void Stop(); 42 | 43 | /** 44 | * Return whether a reading is ready. This is only useful to check whether 45 | * the first reading arrived or not as this method will always return true 46 | * afterwards until the next Stop()/Start() 47 | * 48 | * @return 49 | */ 50 | bool IsAvailable() const 51 | { 52 | return m_is_available; 53 | } 54 | 55 | /** 56 | * Return the latest distance reading, in mm 57 | * 58 | * @return 59 | */ 60 | uint16_t GetDistance() const 61 | { 62 | return m_distance; 63 | } 64 | 65 | private: 66 | void OnRxFull(LIBBASE_MODULE(Uart) *uart); 67 | 68 | void Shoot(); 69 | 70 | LIBBASE_MODULE(Uart) m_uart; 71 | 72 | volatile uint16_t m_distance; 73 | Byte m_buffer[2]; 74 | int m_buffer_it; 75 | 76 | bool m_is_shoot; 77 | volatile bool m_is_shooting; 78 | volatile bool m_is_available; 79 | }; 80 | 81 | } 82 | -------------------------------------------------------------------------------- /inc/libsc/motor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * motor.h 3 | * 4 | * Author: Harrison Ng, Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace libsc 14 | { 15 | 16 | class Motor 17 | { 18 | public: 19 | struct Config 20 | { 21 | /** 22 | * A multiplier in percentage to compensate the power output, [0, 200] 23 | */ 24 | uint8_t multiplier = 100; 25 | }; 26 | 27 | /** 28 | * Set the motor power percentage, [0, 100] * 10 (i.e., 84 => 8.4%) 29 | * 30 | * @param power 31 | */ 32 | void SetPower(const uint16_t power); 33 | void AddPower(const int16_t power); 34 | uint16_t GetPower() const 35 | { 36 | return m_power; 37 | } 38 | 39 | /** 40 | * Clockwise (top view): 41 | *
42 | 	 * |-------|   ^
43 | 	 * | Motor |-- ^
44 | 	 * |-------|   ^
45 | 	 * 
46 | * 47 | * @param flag 48 | */ 49 | void SetClockwise(const bool flag); 50 | bool IsClockwise() const 51 | { 52 | return m_is_clockwise; 53 | } 54 | 55 | protected: 56 | /** 57 | * Construct a Motor, deriving class must init in a way that the motor is 58 | * stalled and clockwise 59 | * 60 | * @param config 61 | */ 62 | explicit Motor(const Config &config); 63 | ~Motor() 64 | {} 65 | 66 | uint8_t GetMultiplier() const 67 | { 68 | return m_multiplier; 69 | } 70 | 71 | private: 72 | virtual void OnSetPower(const uint16_t power) = 0; 73 | virtual void OnSetClockwise(const bool flag) = 0; 74 | 75 | const uint8_t m_multiplier; 76 | 77 | uint16_t m_power; 78 | bool m_is_clockwise; 79 | }; 80 | 81 | } 82 | -------------------------------------------------------------------------------- /inc/libutil/positional_pid_controller.h: -------------------------------------------------------------------------------- 1 | /* 2 | * positional_pid_controller.h 3 | * Generic poitional PID controller 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #if MK60DZ10 || MK60D10 || MK60F15 13 | #include "libsc/system.h" 14 | 15 | #elif MKL26Z4 16 | #include "libsc/system.h" 17 | 18 | #endif 19 | 20 | #include "libsc/timer.h" 21 | #include "libutil/pid_controller.h" 22 | 23 | namespace libutil 24 | { 25 | 26 | template 27 | class PositionalPidController : public PidController 28 | { 29 | public: 30 | typedef InT_ InT; 31 | typedef OutT_ OutT; 32 | 33 | PositionalPidController(const InT setpoint, const float kp, const float ki, 34 | const float kd); 35 | 36 | /** 37 | * Set the upper bound of i, <= 0 means unlimited i 38 | * 39 | * @param value 40 | */ 41 | void SetILimit(const float value) 42 | { 43 | m_i_limit = value; 44 | } 45 | 46 | void Reset() 47 | { 48 | m_accumulated_error = 0; 49 | ResetTime(); 50 | } 51 | 52 | void ResetTime() 53 | { 54 | #if MK60DZ10 || MK60D10 || MK60F15 55 | m_prev_time = libsc::System::Time(); 56 | #elif MKL26Z4 57 | m_prev_time = libsc::System::Time(); 58 | #endif 59 | } 60 | 61 | protected: 62 | void OnCalc(const InT error) override; 63 | OutT GetControlOut() override; 64 | 65 | private: 66 | float m_i_limit; 67 | 68 | float m_accumulated_error; 69 | InT m_prev_error; 70 | libsc::Timer::TimerInt m_prev_time; 71 | }; 72 | 73 | } 74 | 75 | #include "positional_pid_controller.tcc" 76 | -------------------------------------------------------------------------------- /inc/libsc/lib_guard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libsc_guard.h 3 | * Protect you from unmatched symbol and linked library 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | namespace libsc 13 | { 14 | 15 | #if defined(K60_INNO) 16 | extern const int kGuardK60Inno; 17 | #define LIBSC_GUARD_VAR kGuardK60Inno 18 | 19 | #elif defined(K60_2013_GEN2) 20 | extern const int kGuardK602013Gen2; 21 | #define LIBSC_GUARD_VAR kGuardK602013Gen2 22 | 23 | #elif defined(K60_2013_CCD) 24 | extern const int kGuardK602013Ccd; 25 | #define LIBSC_GUARD_VAR kGuardK602013Ccd 26 | 27 | #elif defined(K60_2013_MAGNETIC) 28 | extern const int kGuardK602013Magnetic; 29 | #define LIBSC_GUARD_VAR kGuardK602013Magnetic 30 | 31 | #elif defined(K60_2014) 32 | extern const int kGuardK602014; 33 | #define LIBSC_GUARD_VAR kGuardK602014 34 | 35 | #elif defined(K60_2014_CAMERA) 36 | extern const int kGuardK602014Camera; 37 | #define LIBSC_GUARD_VAR kGuardK602014Camera 38 | 39 | #elif defined(K60_2014_CCD) 40 | extern const int kGuardK602014Ccd; 41 | #define LIBSC_GUARD_VAR kGuardK602014Ccd 42 | 43 | #elif defined(K60_2014_INNO) 44 | extern const int kGuardK602014Inno; 45 | #define LIBSC_GUARD_VAR kGuardK602014Inno 46 | 47 | #elif defined(K60_2014_MAGNETIC) 48 | extern const int kGuardK602014Magnetic; 49 | #define LIBSC_GUARD_VAR kGuardK602014Magnetic 50 | 51 | #else 52 | extern const int kGuardNull; 53 | #define LIBSC_GUARD_VAR kGuardNull 54 | 55 | #endif 56 | 57 | #define LIBSC_GUARD() do { if (libsc::LIBSC_GUARD_VAR != 0) { asm("nop"); } } while (false) 58 | 59 | } 60 | -------------------------------------------------------------------------------- /inc/libbase/k60/soft_pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * soft_pwm.h 3 | * Software emulated PWM using PIT and GPIO 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #include "libbase/k60/gpio.h" 16 | #include "libbase/k60/pit.h" 17 | #include "libbase/k60/pwm.h" 18 | 19 | namespace libbase 20 | { 21 | namespace k60 22 | { 23 | 24 | /** 25 | * Generate PWM signal using PIT and GPIO, only guarantee precision down to us 26 | * level 27 | */ 28 | class SoftPwm : public Pwm 29 | { 30 | public: 31 | struct Config : public Pwm::Config 32 | { 33 | // [0 - 3] 34 | uint8_t pit_channel; 35 | }; 36 | 37 | explicit SoftPwm(const Config &config); 38 | explicit SoftPwm(nullptr_t); 39 | SoftPwm(const SoftPwm&) = delete; 40 | SoftPwm(SoftPwm &&rhs); 41 | ~SoftPwm(); 42 | 43 | SoftPwm& operator=(const SoftPwm&) = delete; 44 | SoftPwm& operator=(SoftPwm &&rhs); 45 | operator bool() const override 46 | { 47 | return m_is_init; 48 | } 49 | 50 | void SetPeriod(const uint32_t period, const uint32_t pos_width) override; 51 | void SetPosWidth(const uint32_t pos_width) override; 52 | 53 | private: 54 | void Uninit(); 55 | 56 | void Setup(const uint32_t period, const uint32_t pos_width); 57 | 58 | void OnTick(Pit*); 59 | 60 | Pwm::Config::Precision m_precision; 61 | 62 | Pit m_pit; 63 | Gpo m_pin; 64 | 65 | volatile bool m_flag; 66 | uint32_t m_pos_width; 67 | uint32_t m_pos_count; 68 | uint32_t m_neg_width; 69 | uint32_t m_neg_count; 70 | 71 | bool m_is_init; 72 | }; 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /inc/libbase/kl26/soft_pwm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * soft_pwm.h 3 | * Software emulated PWM using PIT and GPIO 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #include "libbase/kl26/gpio.h" 16 | #include "libbase/kl26/pit.h" 17 | #include "libbase/kl26/pwm.h" 18 | 19 | namespace libbase 20 | { 21 | namespace kl26 22 | { 23 | 24 | /** 25 | * Generate PWM signal using PIT and GPIO, only guarantee precision down to us 26 | * level 27 | */ 28 | class SoftPwm : public Pwm 29 | { 30 | public: 31 | struct Config : public Pwm::Config 32 | { 33 | // [0 - 3] 34 | uint8_t pit_channel; 35 | }; 36 | 37 | explicit SoftPwm(const Config &config); 38 | explicit SoftPwm(nullptr_t); 39 | SoftPwm(const SoftPwm&) = delete; 40 | SoftPwm(SoftPwm &&rhs); 41 | ~SoftPwm(); 42 | 43 | SoftPwm& operator=(const SoftPwm&) = delete; 44 | SoftPwm& operator=(SoftPwm &&rhs); 45 | operator bool() const override 46 | { 47 | return m_is_init; 48 | } 49 | 50 | void SetPeriod(const uint32_t period, const uint32_t pos_width) override; 51 | void SetPosWidth(const uint32_t pos_width) override; 52 | 53 | private: 54 | void Uninit(); 55 | 56 | void Setup(const uint32_t period, const uint32_t pos_width); 57 | 58 | void OnTick(Pit*); 59 | 60 | Pwm::Config::Precision m_precision; 61 | 62 | Pit m_pit; 63 | Gpo m_pin; 64 | 65 | volatile bool m_flag; 66 | uint32_t m_pos_width; 67 | uint32_t m_pos_count; 68 | uint32_t m_neg_width; 69 | uint32_t m_neg_count; 70 | 71 | bool m_is_init; 72 | }; 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /inc/libbase/kl26/tpm_quad_decoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tpm_quad_decoder.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/kl26/gpio.h" 15 | #include "libbase/kl26/quad_decoder_interface.h" 16 | #include "libbase/kl26/tpm_counter.h" 17 | 18 | namespace libbase 19 | { 20 | namespace kl26 21 | { 22 | 23 | class TpmQuadDecoder : public QuadDecoderInterface 24 | { 25 | public: 26 | struct Config : public QuadDecoderInterface::Config 27 | { 28 | /** 29 | * @see libbase::k60::FtmQuadDecoder::Config::EncodingMode 30 | */ 31 | enum struct EncodingMode 32 | { 33 | kPhaseAB, 34 | kCountDirection, 35 | }; 36 | 37 | EncodingMode encoding_mode; 38 | uint8_t tpm_module; 39 | }; 40 | 41 | explicit TpmQuadDecoder(const Config &config); 42 | explicit TpmQuadDecoder(nullptr_t); 43 | TpmQuadDecoder(const TpmQuadDecoder&) = delete; 44 | TpmQuadDecoder(TpmQuadDecoder &&rhs); 45 | ~TpmQuadDecoder(); 46 | 47 | TpmQuadDecoder& operator=(const TpmQuadDecoder&) = delete; 48 | TpmQuadDecoder& operator=(TpmQuadDecoder &&rhs); 49 | operator bool() const override 50 | { 51 | return m_is_init; 52 | } 53 | 54 | int32_t GetCount() override; 55 | void ResetCount() override; 56 | 57 | private: 58 | void Uninit(); 59 | 60 | void OnTick(Gpi*, const bool is_revert); 61 | 62 | bool m_is_invert_b_polarity; 63 | bool m_is_dir_mode; 64 | 65 | TpmCounter m_counter; 66 | Gpi m_qdb; 67 | 68 | volatile int32_t m_count; 69 | 70 | bool m_is_init; 71 | }; 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /inc/libbase/kl26/soft_quad_decoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * soft_quad_decoder.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/kl26/gpio.h" 15 | #include "libbase/kl26/quad_decoder_interface.h" 16 | 17 | namespace libbase 18 | { 19 | namespace kl26 20 | { 21 | 22 | /** 23 | * Software emulated quadrature decoding using pin interrupt and GPIO 24 | */ 25 | class SoftQuadDecoder : public QuadDecoderInterface 26 | { 27 | public: 28 | struct Config : public QuadDecoderInterface::Config 29 | { 30 | /** 31 | * @see libbase::k60::FtmQuadDecoder::Config::EncodingMode 32 | */ 33 | enum struct EncodingMode 34 | { 35 | kPhaseAB, 36 | kCountDirection, 37 | }; 38 | 39 | EncodingMode encoding_mode; 40 | }; 41 | 42 | explicit SoftQuadDecoder(const Config &config); 43 | explicit SoftQuadDecoder(nullptr_t); 44 | SoftQuadDecoder(const SoftQuadDecoder&) = delete; 45 | SoftQuadDecoder(SoftQuadDecoder &&rhs); 46 | ~SoftQuadDecoder(); 47 | 48 | SoftQuadDecoder& operator=(const SoftQuadDecoder&) = delete; 49 | SoftQuadDecoder& operator=(SoftQuadDecoder &&rhs); 50 | operator bool() const override 51 | { 52 | return m_is_init; 53 | } 54 | 55 | int32_t GetCount() override; 56 | void ResetCount() override; 57 | 58 | private: 59 | void Uninit(); 60 | 61 | void OnTick(Gpi*); 62 | 63 | bool m_is_invert_b_polarity; 64 | bool m_is_dir_mode; 65 | 66 | Gpi m_qda; 67 | Gpi m_qdb; 68 | 69 | volatile int32_t m_count; 70 | 71 | bool m_is_init; 72 | }; 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/libbase/kl26/misc_utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * misc_utils.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "libbase/k60/misc_utils.h" 16 | 17 | namespace 18 | { 19 | 20 | uint32_t ReverseUint32(const uint32_t x) 21 | { 22 | uint32_t result = x; 23 | Byte *data = reinterpret_cast(&result); 24 | std::reverse(data, data + 4); 25 | return result; 26 | } 27 | 28 | bool IsBigEndian_() 29 | { 30 | const uint16_t bom = 0xFFFE; 31 | return (reinterpret_cast(&bom)[0] == 0xFF); 32 | } 33 | 34 | bool IsBigEndian() 35 | { 36 | static const bool is_be = IsBigEndian_(); 37 | return is_be; 38 | } 39 | 40 | } 41 | 42 | uint32_t htobe32(const uint32_t host_32bits) 43 | { 44 | if (!IsBigEndian()) 45 | { 46 | return ReverseUint32(host_32bits); 47 | } 48 | else 49 | { 50 | return host_32bits; 51 | } 52 | } 53 | 54 | uint32_t htole32(const uint32_t host_32bits) 55 | { 56 | if (IsBigEndian()) 57 | { 58 | return ReverseUint32(host_32bits); 59 | } 60 | else 61 | { 62 | return host_32bits; 63 | } 64 | } 65 | 66 | uint32_t be32toh(const uint32_t big_endian_32bits) 67 | { 68 | if (!IsBigEndian()) 69 | { 70 | return ReverseUint32(big_endian_32bits); 71 | } 72 | else 73 | { 74 | return big_endian_32bits; 75 | } 76 | } 77 | 78 | uint32_t le32toh(const uint32_t little_endian_32bits) 79 | { 80 | if (IsBigEndian()) 81 | { 82 | return ReverseUint32(little_endian_32bits); 83 | } 84 | else 85 | { 86 | return little_endian_32bits; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/libsc/simple_buzzer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * simple_buzzer.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include "libbase/log.h" 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(gpio) 15 | 16 | #include "libsc/config.h" 17 | #include "libsc/simple_buzzer.h" 18 | 19 | using namespace LIBBASE_NS; 20 | 21 | namespace libsc 22 | { 23 | 24 | #ifdef LIBSC_USE_BUZZER 25 | 26 | namespace 27 | { 28 | 29 | #if LIBSC_USE_BUZZER == 1 30 | inline Pin::Name GetPin(const uint8_t id) 31 | { 32 | if (id != 0) 33 | { 34 | assert(false); 35 | } 36 | return LIBSC_BUZZER0; 37 | } 38 | 39 | #endif 40 | 41 | Gpo::Config GetGpoConfig(const SimpleBuzzer::Config &config) 42 | { 43 | Gpo::Config product; 44 | product.pin = GetPin(config.id); 45 | // Default off 46 | product.is_high = config.is_active_low; 47 | return product; 48 | } 49 | 50 | } 51 | 52 | SimpleBuzzer::SimpleBuzzer(const Config &config) 53 | : m_pin(GetGpoConfig(config)), 54 | m_is_active_low(config.is_active_low) 55 | {} 56 | 57 | void SimpleBuzzer::SetBeep(const bool is_beep) 58 | { 59 | m_pin.Set(is_beep ^ m_is_active_low); 60 | } 61 | 62 | bool SimpleBuzzer::GetBeep() const 63 | { 64 | return (m_pin.Get() ^ m_is_active_low); 65 | } 66 | 67 | #else 68 | SimpleBuzzer::SimpleBuzzer(const Config&) 69 | : m_pin(nullptr), m_is_active_low(false) 70 | { 71 | LOG_DL("Configured not to use SimpleBuzzer"); 72 | } 73 | void SimpleBuzzer::SetBeep(const bool) {} 74 | bool SimpleBuzzer::GetBeep() const { return false; } 75 | 76 | #endif /* LIBSC_USE_BUZZER */ 77 | 78 | } 79 | -------------------------------------------------------------------------------- /inc/libbase/kl26/tpm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tpm.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/kl26/pinout_macros.h" 12 | 13 | namespace libbase 14 | { 15 | namespace kl26 16 | { 17 | 18 | class Tpm 19 | { 20 | public: 21 | enum struct Name 22 | { 23 | kTpm0Ch0 = 0, 24 | kTpm0Ch1, 25 | kTpm0Ch2, 26 | kTpm0Ch3, 27 | kTpm0Ch4, 28 | kTpm0Ch5, 29 | kTpm0Ch6, 30 | kTpm0Ch7, 31 | 32 | kTpm1Ch0 = 8, 33 | kTpm1Ch1, 34 | kTpm1Ch2, 35 | kTpm1Ch3, 36 | kTpm1Ch4, 37 | kTpm1Ch5, 38 | kTpm1Ch6, 39 | kTpm1Ch7, 40 | 41 | kTpm2Ch0 = 16, 42 | kTpm2Ch1, 43 | kTpm2Ch2, 44 | kTpm2Ch3, 45 | kTpm2Ch4, 46 | kTpm2Ch5, 47 | kTpm2Ch6, 48 | kTpm2Ch7, 49 | 50 | kDisable = 24 51 | }; 52 | 53 | enum struct ClkinName 54 | { 55 | kTpmClkin0 = 0, 56 | kTpmClkin1, 57 | kDisable 58 | }; 59 | 60 | static Tpm& Get() 61 | { 62 | static Tpm tpm; 63 | return tpm; 64 | } 65 | 66 | static constexpr int GetMaxTpmChannelCount() 67 | { 68 | return static_cast(Name::kTpm1Ch0); 69 | } 70 | 71 | bool RegTpm(const Tpm::Name tpm, const bool is_exclusive_module); 72 | /** 73 | * Unregister a TPM channel and return whether the module is free or not 74 | * 75 | * @param tpm 76 | * @return 77 | */ 78 | bool UnregTpm(const Tpm::Name tpm); 79 | 80 | private: 81 | enum struct ModuleLockMode 82 | { 83 | kFree, 84 | kExclusive, 85 | kShared, 86 | }; 87 | 88 | Tpm(); 89 | 90 | ModuleLockMode m_module_lock[PINOUT_TPM_COUNT]; 91 | bool m_channel_lock[PINOUT_TPM_COUNT][PINOUT_TPM_CHANNEL_COUNT]; 92 | }; 93 | 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /inc/libbase/kl26/watchdog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * watchdog.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | namespace libbase 12 | { 13 | namespace kl26 14 | { 15 | 16 | class Watchdog 17 | { 18 | public: 19 | struct Config 20 | { 21 | enum struct Timeout 22 | { 23 | kDisable = 0, 24 | k32Ms, 25 | k256Ms, 26 | k1024Ms, 27 | }; 28 | 29 | Timeout timeout = Timeout::kDisable; 30 | }; 31 | 32 | Watchdog() = delete; 33 | 34 | /** 35 | * Must be called at the very beginning in the startup routine 36 | */ 37 | static void Init(); 38 | 39 | /** 40 | * Refresh the Watchdog to prevent it from resetting the system. Should be 41 | * called regularly among the time out value 42 | */ 43 | static void Refresh(); 44 | 45 | ///@{ 46 | /** 47 | * Alias of Refresh(), choose the one you like most! :) 48 | */ 49 | static void Feed() 50 | { 51 | Refresh(); 52 | } 53 | static void Food() 54 | { 55 | Refresh(); 56 | } 57 | static void Bone() 58 | { 59 | Refresh(); 60 | } 61 | static void Play() 62 | { 63 | Refresh(); 64 | } 65 | static void Hand() 66 | { 67 | Refresh(); 68 | } 69 | static void Wan() 70 | { 71 | Refresh(); 72 | } 73 | /// @} 74 | 75 | private: 76 | /** 77 | * Get the Config object used during initialization, could be optionally 78 | * implemented by user. The default implementation will simply disable the 79 | * watchdog 80 | * 81 | * @return 82 | */ 83 | __attribute__((__weak__)) 84 | static Config GetWatchdogConfig(); 85 | 86 | static void InitCopcReg(const Config &config); 87 | }; 88 | 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /inc/libbase/k60/pit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pit.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "libbase/k60/misc_utils.h" 17 | 18 | namespace libbase 19 | { 20 | namespace k60 21 | { 22 | 23 | class Pit 24 | { 25 | public: 26 | typedef std::function OnPitTriggerListener; 27 | 28 | struct Config 29 | { 30 | // [0 - 3] 31 | uint8_t channel; 32 | uint32_t count; 33 | OnPitTriggerListener isr; 34 | bool is_enable = true; 35 | }; 36 | 37 | explicit Pit(const Config &config); 38 | explicit Pit(nullptr_t); 39 | Pit(const Pit&) = delete; 40 | Pit(Pit &&rhs); 41 | ~Pit(); 42 | 43 | Pit& operator=(const Pit&) = delete; 44 | Pit& operator=(Pit &&rhs); 45 | operator bool() const 46 | { 47 | return m_is_init; 48 | } 49 | 50 | void SetEnable(const bool flag); 51 | 52 | void SetCount(const uint32_t count); 53 | uint32_t GetCountLeft() const; 54 | 55 | /** 56 | * Consume an interrupt, this basically clear the IRQ flag for this 57 | * particular PIT channel. Notice that you don't need to call it in a 58 | * OnPitTriggerListener as it has been called for you 59 | */ 60 | void ConsumeInterrupt(); 61 | bool IsInterruptRequested() const; 62 | 63 | uint8_t GetChannel() const 64 | { 65 | return m_channel; 66 | } 67 | 68 | private: 69 | void SetIsr(const OnPitTriggerListener &isr); 70 | void Uninit(); 71 | 72 | static __ISR void IrqHandler(); 73 | 74 | uint8_t m_channel; 75 | OnPitTriggerListener m_isr; 76 | 77 | bool m_is_init; 78 | }; 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /inc/libbase/kl26/pit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pit.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "libbase/kl26/misc_utils.h" 17 | 18 | namespace libbase 19 | { 20 | namespace kl26 21 | { 22 | 23 | class Pit 24 | { 25 | public: 26 | typedef std::function OnPitTriggerListener; 27 | 28 | struct Config 29 | { 30 | // [0 - 1] 31 | uint8_t channel; 32 | uint32_t count; 33 | OnPitTriggerListener isr; 34 | bool is_enable = true; 35 | }; 36 | 37 | explicit Pit(const Config &config); 38 | explicit Pit(nullptr_t); 39 | Pit(const Pit&) = delete; 40 | Pit(Pit &&rhs); 41 | ~Pit(); 42 | 43 | Pit& operator=(const Pit&) = delete; 44 | Pit& operator=(Pit &&rhs); 45 | operator bool() const 46 | { 47 | return m_is_init; 48 | } 49 | 50 | void SetEnable(const bool flag); 51 | 52 | void SetCount(const uint32_t count); 53 | uint32_t GetCountLeft() const; 54 | 55 | /** 56 | * Consume an interrupt, this basically clear the IRQ flag for this 57 | * particular PIT channel. Notice that you don't need to call it in a 58 | * OnPitTriggerListener as it has been called for you 59 | */ 60 | void ConsumeInterrupt(); 61 | bool IsInterruptRequested() const; 62 | 63 | uint8_t GetChannel() const 64 | { 65 | return m_channel; 66 | } 67 | 68 | private: 69 | void SetIsr(const OnPitTriggerListener &isr); 70 | void Uninit(); 71 | 72 | static __ISR void IrqHandler(); 73 | 74 | uint8_t m_channel; 75 | OnPitTriggerListener m_isr; 76 | 77 | bool m_is_init; 78 | }; 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /inc/libsc/servo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * servo.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include "libbase/helper.h" 14 | #include "libbase/pinout_macros.h" 15 | #include LIBBASE_H(soft_pwm) 16 | 17 | #if PINOUT_FTM_COUNT 18 | #include LIBBASE_H(ftm_pwm) 19 | 20 | #elif PINOUT_TPM_COUNT 21 | #include LIBBASE_H(tpm_pwm) 22 | 23 | #else 24 | #define LIBSC_USE_SOFT_SERVO 1 25 | 26 | #endif // PINOUT_FTM_COUNT 27 | 28 | #include "libsc/config.h" 29 | 30 | namespace libsc 31 | { 32 | 33 | /** 34 | * RC servo 35 | */ 36 | class Servo 37 | { 38 | public: 39 | #if LIBSC_USE_SOFT_SERVO 40 | typedef LIBBASE_MODULE(SoftPwm) Pwm; 41 | 42 | #elif PINOUT_FTM_COUNT 43 | typedef LIBBASE_MODULE(FtmPwm) Pwm; 44 | 45 | #elif PINOUT_TPM_COUNT 46 | typedef LIBBASE_MODULE(TpmPwm) Pwm; 47 | 48 | #endif // LIBSC_USE_SOFT_SERVO 49 | 50 | struct Config 51 | { 52 | uint8_t id; 53 | /// The period of the PWM signal, in us 54 | uint16_t period; 55 | /// The min pos width of the PWM signal, in us 56 | uint16_t min_pos_width; 57 | /// The max pos width of the PWM signal, in us 58 | uint16_t max_pos_width; 59 | }; 60 | 61 | explicit Servo(const Config &config); 62 | 63 | /** 64 | * Set the degree(the servo turn in CCW), [0, 180] * 10 (i.e., 84 => 8.4°) 65 | * 66 | * @param degree 67 | */ 68 | void SetDegree(const uint16_t degree); 69 | uint16_t GetDegree() const 70 | { 71 | return m_degree; 72 | } 73 | 74 | private: 75 | const uint16_t m_pos_width_min; 76 | const uint16_t m_pos_width_diff; 77 | 78 | Pwm m_pwm; 79 | 80 | uint16_t m_degree; 81 | }; 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/libsc/k60/system.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * system.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include "libbase/k60/cache.h" 13 | 14 | #include "libsc/config.h" 15 | #include "libsc/k60/dwt_delay.h" 16 | #include "libsc/system.h" 17 | #include "libsc/sys_tick_timer.h" 18 | 19 | using namespace libbase::k60; 20 | using namespace libsc::k60; 21 | 22 | namespace libsc 23 | { 24 | 25 | System::Impl *System::m_instance = nullptr; 26 | 27 | struct System::Impl 28 | { 29 | Impl(); 30 | 31 | DwtDelay delay; 32 | SysTickTimer timer; 33 | }; 34 | 35 | System::Impl::Impl() 36 | { 37 | // Enable cache unless otherwise disabled 38 | #if !LIBSC_NOT_USE_CACHE && MK60F15 39 | Cache::Config cache_conf; 40 | cache_conf.is_enable = true; 41 | Cache::Get().Init(cache_conf); 42 | #endif 43 | } 44 | 45 | void System::Init() 46 | { 47 | if (!m_instance) 48 | { 49 | m_instance = new Impl; 50 | } 51 | } 52 | 53 | void System::DelayUs(const uint16_t us) 54 | { 55 | assert(m_instance); 56 | m_instance->delay.DelayUs(us); 57 | } 58 | 59 | void System::DelayMs(const uint16_t ms) 60 | { 61 | assert(m_instance); 62 | m_instance->delay.DelayMs(ms); 63 | } 64 | 65 | void System::DelayS(const uint16_t s) 66 | { 67 | assert(m_instance); 68 | m_instance->delay.DelayS(s); 69 | } 70 | 71 | Timer::TimerInt System::Time() 72 | { 73 | assert(m_instance); 74 | return m_instance->timer.Time(); 75 | } 76 | 77 | #ifdef USE_TIME_IN_125US 78 | Timer::TimerInt System::TimeIn125us() 79 | { 80 | assert(m_instance); 81 | return m_instance->timer.TimeIn125us(); 82 | } 83 | #endif 84 | 85 | } 86 | -------------------------------------------------------------------------------- /inc/libbase/kl26/lptmr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * lptmr.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "libbase/kl26/misc_utils.h" 17 | 18 | namespace libbase 19 | { 20 | namespace kl26 21 | { 22 | 23 | /*** 24 | * Low power timer clocked by the 1kHz LPO 25 | */ 26 | class Lptmr 27 | { 28 | public: 29 | typedef std::function OnLptmrTriggerListener; 30 | 31 | struct Config 32 | { 33 | uint16_t count; 34 | OnLptmrTriggerListener isr; 35 | bool is_reset_counter_on_irq = false; 36 | bool is_enable = true; 37 | }; 38 | 39 | explicit Lptmr(const Config &config); 40 | explicit Lptmr(nullptr_t); 41 | Lptmr(const Lptmr&) = delete; 42 | Lptmr(Lptmr &&rhs); 43 | ~Lptmr(); 44 | 45 | Lptmr& operator=(const Lptmr&) = delete; 46 | Lptmr& operator=(Lptmr &&rhs); 47 | operator bool() const 48 | { 49 | return m_is_init; 50 | } 51 | 52 | void SetEnable(const bool flag); 53 | /** 54 | * Alter the count value, could only be done when the module is disabled or 55 | * inside ISR 56 | * 57 | * @param count 58 | */ 59 | void SetCount(const uint16_t count); 60 | /** 61 | * Get the current value of the counter 62 | * 63 | * @return 64 | */ 65 | uint16_t GetCounter() const; 66 | 67 | void ConsumeInterrupt(); 68 | bool IsInterruptRequested() const; 69 | 70 | private: 71 | void InitCsrReg(const Config &config); 72 | void InitPsrReg(); 73 | void SetIsr(const OnLptmrTriggerListener &isr); 74 | void Uninit(); 75 | 76 | static __ISR void IrqHandler(); 77 | 78 | OnLptmrTriggerListener m_isr; 79 | 80 | bool m_is_init; 81 | }; 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/libbase/k60/cache.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * cache.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/k60/hardware.h" 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/k60/cache.h" 15 | #include "libbase/k60/misc_utils.h" 16 | 17 | namespace libbase 18 | { 19 | namespace k60 20 | { 21 | 22 | #if MK60F15 23 | 24 | Cache::Cache() 25 | : m_is_init(false) 26 | {} 27 | 28 | void Cache::Init(const Config &config) 29 | { 30 | if (m_is_init) 31 | { 32 | assert(false); 33 | return; 34 | } 35 | 36 | if (config.is_enable) 37 | { 38 | InitPc(); 39 | InitPs(); 40 | LMEM->PSCRMR&=~(LMEM_PSCRMR_R6_MASK); 41 | LMEM->PCCRMR&=~(LMEM_PCCRMR_R6_MASK); 42 | } 43 | m_is_init = true; 44 | } 45 | 46 | void Cache::InitPc() 47 | { 48 | uint32_t ccr_reg = 0; 49 | SET_BIT(ccr_reg, LMEM_PCCCR_INVW0_SHIFT); 50 | SET_BIT(ccr_reg, LMEM_PCCCR_INVW1_SHIFT); 51 | SET_BIT(ccr_reg, LMEM_PCCCR_GO_SHIFT); 52 | 53 | LMEM->PCCCR = ccr_reg; 54 | 55 | // Wait for the LMEM_PCCCR[GO] bit to clear indicating the command has 56 | // completed 57 | while (GET_BIT(LMEM->PCCCR, LMEM_PCCCR_GO_SHIFT)) 58 | {} 59 | 60 | SET_BIT(LMEM->PCCCR, LMEM_PCCCR_ENCACHE_SHIFT); 61 | } 62 | 63 | void Cache::InitPs() 64 | { 65 | uint32_t ccr_reg = 0; 66 | SET_BIT(ccr_reg, LMEM_PSCCR_INVW0_SHIFT); 67 | SET_BIT(ccr_reg, LMEM_PSCCR_INVW1_SHIFT); 68 | SET_BIT(ccr_reg, LMEM_PSCCR_GO_SHIFT); 69 | 70 | LMEM->PSCCR = ccr_reg; 71 | 72 | // Wait for the LMEM_PSCCR[GO] bit to clear indicating the command has 73 | // completed 74 | while (GET_BIT(LMEM->PSCCR, LMEM_PSCCR_GO_SHIFT)) 75 | {} 76 | 77 | SET_BIT(LMEM->PSCCR, LMEM_PSCCR_ENCACHE_SHIFT); 78 | } 79 | 80 | #endif 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /inc/libutil/touch_keyboard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * touch-keyboard.h 3 | * 4 | * Created on: Feb 11, 2018 5 | * Author: dipsy 6 | */ 7 | 8 | #ifndef INC_LIBUTIL_TOUCH_KEYBOARD_H_ 9 | #define INC_LIBUTIL_TOUCH_KEYBOARD_H_ 10 | 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include "libsc/k60/touchscreen_lcd.h" 21 | 22 | using libsc::System; 23 | using std::string; 24 | using libsc::k60::TouchScreenLcd; 25 | 26 | namespace libutil { 27 | 28 | class TouchKeyboard{ 29 | public: 30 | TouchKeyboard(TouchScreenLcd* pLcd):pLcd(pLcd){} 31 | 32 | /** 33 | * Showkeyboard and return entered string 34 | */ 35 | string ShowKeyboard(); 36 | 37 | /** 38 | * ShowKeyboard with default value 39 | */ 40 | string ShowKeyboard(const string& s); 41 | 42 | /** 43 | * Password mode 44 | */ 45 | void SetPasswordMode(bool flag){password_mode = flag;} 46 | 47 | private: 48 | TouchScreenLcd* pLcd; 49 | uint16_t ox=1, oy=451, //offset left, top 50 | kw = 48, kh = 70; //key width key height 51 | char str[35]={}; 52 | uint8_t len=0; 53 | bool cap_lock = false; 54 | const string keys[5] = { 55 | "1234567890", 56 | "qwertyuiop", 57 | "asdfghjkl", 58 | "\tzxcvbnm\b\\", 59 | ",( \\\\).\n\\\\" 60 | }; 61 | const uint8_t pl[5] = {0,0,24,0,0}; 62 | bool password_mode = false; 63 | time_t last_tap = 0; 64 | char last_key = '+'; 65 | 66 | void RenderKeyboard(bool is_upper_case = false); 67 | 68 | void PrintCurrentStr(); 69 | 70 | /** 71 | * get character at this location 72 | */ 73 | char GetKey(uint16_t x, uint16_t y); 74 | 75 | char ToUpperCase(const char& c); 76 | }; 77 | 78 | } 79 | 80 | #endif /* INC_LIBUTIL_TOUCH_KEYBOARD_H_ */ 81 | -------------------------------------------------------------------------------- /inc/libutil/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * misc.h 3 | * Misc util 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include "libbase/helper.h" 17 | #include LIBBASE_H(misc_utils) 18 | 19 | #if MK60DZ10 || MK60D10 || MK60F15 20 | namespace libsc 21 | { 22 | namespace k60 23 | { 24 | 25 | class UartDevice; 26 | 27 | } 28 | } 29 | 30 | #elif MKL26Z4 31 | namespace libsc 32 | { 33 | namespace kl26 34 | { 35 | 36 | class UartDevice; 37 | 38 | } 39 | } 40 | 41 | #endif 42 | 43 | #define SAFE_DELETE(x) do{if (x) {delete x; x = nullptr;}}while(false) 44 | 45 | #define UTIL_JOIN(x, y) x ## y 46 | 47 | namespace libutil 48 | { 49 | 50 | #if MK60DZ10 || MK60D10 || MK60F15 51 | void InitDefaultFwriteHandler(libsc::k60::UartDevice *uart); 52 | 53 | #elif MKL26Z4 54 | void InitDefaultFwriteHandler(libsc::kl26::UartDevice *uart); 55 | 56 | #endif 57 | 58 | void UninitDefaultFwriteHandler(); 59 | 60 | template 61 | inline T Clamp(const T &min, const T &x, const T &max) 62 | { 63 | return std::max(min, std::min(x, max)); 64 | } 65 | 66 | template 67 | inline T ClampVal(const T min, const T x, const T max) 68 | { 69 | return (x > min) ? ((x > max) ? max : x) : min; 70 | } 71 | 72 | inline uint16_t GetRgb565(const uint8_t r, const uint8_t g, const uint8_t b) 73 | { 74 | return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); 75 | } 76 | 77 | template 78 | inline T EnumAdvance(const T e, const int n) 79 | { 80 | return static_cast(static_cast(e) + n); 81 | } 82 | 83 | template 84 | inline T EnumAdvance(const T e, const U n) 85 | { 86 | return EnumAdvance(e, static_cast(n)); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/libbase/k60/dma_mux.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * dma_mux.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/k60/hardware.h" 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/k60/dma_mux.h" 15 | #include "libbase/k60/dma_mux_utils.h" 16 | #include "libbase/k60/misc_utils.h" 17 | #include "libbase/k60/pinout.h" 18 | #include "libbase/k60/sim.h" 19 | 20 | #include "libutil/misc.h" 21 | 22 | constexpr DMAMUX_Type* MEM_MAPS[PINOUT::GetDmaMuxCount()] = 23 | { 24 | #if MK60DZ10 || MK60DZ10 25 | DMAMUX 26 | #elif MK60F15 27 | DMAMUX0, 28 | DMAMUX1, 29 | #else 30 | #error Unknwon MCU 31 | #endif 32 | }; 33 | 34 | namespace libbase 35 | { 36 | namespace k60 37 | { 38 | 39 | bool DmaMux::SetEnableSource(const Source src, const Uint channel) 40 | { 41 | if (DmaMuxUtils::GetModule(channel) >= PINOUT::GetDmaMuxCount()) 42 | { 43 | assert(false); 44 | return false; 45 | } 46 | 47 | uint8_t reg = 0; 48 | if (src != Source::kNull) 49 | { 50 | SET_BIT(reg, DMAMUX_CHCFG_ENBL_SHIFT); 51 | 52 | // Each MUX handles 16 DMA channel 53 | const uint8_t src_num = PINOUT::GetDmaMuxSource(src, channel / 16); 54 | if (src_num == static_cast(-1)) 55 | { 56 | assert(false); 57 | return false; 58 | } 59 | reg |= DMAMUX_CHCFG_SOURCE(src_num); 60 | } 61 | 62 | #if MK60DZ10 || MK60DZ10 63 | Sim::SetEnableClockGate(Sim::ClockGate::kDmaMux, true); 64 | #elif MK60F15 65 | Sim::SetEnableClockGate(libutil::EnumAdvance(Sim::ClockGate::kDmaMux0, 66 | DmaMuxUtils::GetModule(channel)), true); 67 | #else 68 | #error Unknwon MCU 69 | #endif 70 | 71 | MEM_MAPS[DmaMuxUtils::GetModule(channel)] 72 | ->CHCFG[DmaMuxUtils::GetChannel(channel)] = reg; 73 | return true; 74 | } 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /inc/libbase/k60/dac.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dac.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/k60/misc_utils.h" 15 | 16 | namespace libbase 17 | { 18 | namespace k60 19 | { 20 | 21 | class Dac 22 | { 23 | public: 24 | enum struct Name 25 | { 26 | kDac0 = 0, 27 | kDac1, 28 | 29 | kDisable 30 | }; 31 | 32 | struct Config 33 | { 34 | enum struct Source 35 | { 36 | // Currenlty not supported 37 | //kVref, 38 | kVdda, 39 | }; 40 | 41 | enum struct BufferMode 42 | { 43 | // 0 -> MAX, 0 -> MAX, ... 44 | kNormal, 45 | // 0 -> MAX, MAX -> 0, ... 46 | kSwing, 47 | // 0 -> MAX 48 | kOneTimeScan, 49 | }; 50 | 51 | Dac::Name module; 52 | Source src = Source::kVdda; 53 | 54 | uint16_t data[16] = {}; 55 | // [1 - 16] 56 | Uint data_size; 57 | BufferMode buffer_mode = BufferMode::kNormal; 58 | }; 59 | 60 | explicit Dac(const Config &config); 61 | explicit Dac(nullptr_t); 62 | Dac(const Dac&) = delete; 63 | Dac(Dac &&rhs); 64 | ~Dac(); 65 | 66 | Dac& operator=(const Dac&) = delete; 67 | Dac& operator=(Dac &&rhs); 68 | operator bool() const 69 | { 70 | return (m_name != Dac::Name::kDisable); 71 | } 72 | 73 | void SetData(const uint16_t *data, const Uint size, 74 | const Config::BufferMode buffer_mode); 75 | void SetData(const uint16_t *data, const Uint size) 76 | { 77 | SetData(data, size, Config::BufferMode::kNormal); 78 | } 79 | 80 | void SetData(const uint16_t data) 81 | { 82 | SetData(&data, 1); 83 | } 84 | 85 | void AdvanceData(); 86 | void SetDataPosition(const Uint position); 87 | 88 | private: 89 | void InitC0Reg(const Config &config); 90 | void Uninit(); 91 | 92 | Name m_name; 93 | }; 94 | 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /inc/libbase/k60/watchdog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * watchdog.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace libbase 14 | { 15 | namespace k60 16 | { 17 | 18 | class Watchdog 19 | { 20 | public: 21 | typedef void (*OnWatchdogTimeoutListener)(); 22 | 23 | struct Config 24 | { 25 | bool is_enable = false; 26 | /// Set the time out value, [50, 8000] 27 | uint32_t time_out_ms = 1000; 28 | }; 29 | 30 | Watchdog() = delete; 31 | 32 | /** 33 | * Must be called at the very beginning in the startup routine 34 | */ 35 | static void Init(); 36 | 37 | /** 38 | * Refresh the Watchdog to prevent it from resetting the system. Should be 39 | * called regularly among the time out value 40 | */ 41 | static void Refresh(); 42 | 43 | static void SetIsr(OnWatchdogTimeoutListener isr); 44 | 45 | ///@{ 46 | /** 47 | * Alias of Refresh(), choose the one you like most! :) 48 | */ 49 | static void Feed() 50 | { 51 | Refresh(); 52 | } 53 | static void Food() 54 | { 55 | Refresh(); 56 | } 57 | static void Bone() 58 | { 59 | Refresh(); 60 | } 61 | static void Play() 62 | { 63 | Refresh(); 64 | } 65 | static void Hand() 66 | { 67 | Refresh(); 68 | } 69 | static void Wan() 70 | { 71 | Refresh(); 72 | } 73 | /// @} 74 | 75 | private: 76 | /** 77 | * Get the Config object used during initialization, could be optionally 78 | * implemented by user. The default implementation will simply disable the 79 | * watchdog 80 | * 81 | * @return 82 | */ 83 | __attribute__((__weak__)) 84 | static Config GetWatchdogConfig(); 85 | 86 | static void InitStctrlReg(const Config &config); 87 | static void InitTimeOutReg(const Config &config); 88 | static void InitPrescReg(); 89 | }; 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /inc/libutil/incremental_pid_controller.tcc: -------------------------------------------------------------------------------- 1 | /* 2 | * incremental_pid_controller.tcc 3 | * Generic incremental PID controller 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "libsc/system.h" 15 | #include "libsc/timer.h" 16 | #include "libutil/incremental_pid_controller.h" 17 | #include "libutil/misc.h" 18 | 19 | namespace libutil 20 | { 21 | 22 | template 23 | IncrementalPidController::IncrementalPidController( 24 | const InT setpoint, const float kp, const float ki, const float kd) 25 | : PidController(setpoint, kp, ki, kd), 26 | m_i_limit(0.0f), 27 | 28 | m_prev_error{0, 0}, 29 | m_prev_output(0), 30 | m_prev_time(libsc::System::Time()) 31 | {} 32 | 33 | template 34 | void IncrementalPidController::OnCalc(const InT error) 35 | { 36 | using namespace libsc::k60; 37 | using namespace libsc; 38 | 39 | const Timer::TimerInt time = System::Time(); 40 | const float time_diff = Timer::TimeDiff(System::Time(), m_prev_time) 41 | / 1000.0f; 42 | 43 | const float p = this->GetKp() * (error - m_prev_error[0]); 44 | float i = this->GetKi() * (error + m_prev_error[0]) * time_diff * 0.5f; 45 | if (m_i_limit > 0.0f) 46 | { 47 | i = libutil::Clamp(-m_i_limit, i, m_i_limit); 48 | } 49 | const float d = this->GetKd() * (error - 2 * m_prev_error[0] 50 | + m_prev_error[1]) / time_diff; 51 | 52 | std::swap(m_prev_error[0], m_prev_error[1]); 53 | m_prev_error[0] = error; 54 | this->UpdatePid(p, i, d); 55 | } 56 | 57 | template 58 | OutT_ IncrementalPidController::GetControlOut() 59 | { 60 | return this->GetP() + this->GetI() + this->GetD(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /inc/libbase/kl26/soft_spi_master.h: -------------------------------------------------------------------------------- 1 | /* 2 | * soft_spi_master.h 3 | * Emulated SPI through GPIO with a compatible interface with SpiMaster 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #include "libbase/kl26/gpio.h" 16 | #include "libbase/kl26/spi_master_interface.h" 17 | 18 | namespace libbase 19 | { 20 | namespace kl26 21 | { 22 | 23 | class SoftSpiMaster : public SpiMasterInterface 24 | { 25 | public: 26 | typedef SpiMasterInterface::Config Config; 27 | 28 | /** 29 | * Construct a new instance. Only the following parameters are supported, 30 | * others will be ignored: 31 | * sin_pin, sout_pin, sck_pin, frame_size, is_sck_idle_low, is_msb_firt, 32 | * slaves 33 | * 34 | * @param config 35 | */ 36 | explicit SoftSpiMaster(const Config &config); 37 | explicit SoftSpiMaster(nullptr_t); 38 | SoftSpiMaster(const SoftSpiMaster&) = delete; 39 | SoftSpiMaster(SoftSpiMaster &&rhs); 40 | ~SoftSpiMaster(){} 41 | 42 | SoftSpiMaster& operator=(const SoftSpiMaster&) = delete; 43 | SoftSpiMaster& operator=(SoftSpiMaster &&rhs); 44 | operator bool() const override 45 | { 46 | return m_is_init; 47 | } 48 | 49 | uint16_t ExchangeData(const uint8_t slave_id, const uint16_t data) override; 50 | 51 | size_t PushData(const uint8_t slave_id, const uint16_t *data, 52 | const size_t size) override; 53 | size_t PushData(const uint8_t slave_id, const uint8_t *data, 54 | const size_t size) override; 55 | 56 | uint8_t GetFrameSize() const 57 | { 58 | return m_frame_size; 59 | } 60 | 61 | private: 62 | Gpi m_sin; 63 | Gpo m_sout; 64 | Gpo m_sck; 65 | Gpo m_cs; 66 | 67 | uint8_t m_frame_size; 68 | bool m_is_sck_capture_first; 69 | bool m_is_msb_first; 70 | 71 | bool m_is_init; 72 | }; 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /inc/libbase/k60/ftm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ftm.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "libbase/k60/pinout_macros.h" 12 | 13 | namespace libbase 14 | { 15 | namespace k60 16 | { 17 | 18 | class Ftm 19 | { 20 | public: 21 | enum struct Name 22 | { 23 | kFtm0Ch0 = 0, 24 | kFtm0Ch1, 25 | kFtm0Ch2, 26 | kFtm0Ch3, 27 | kFtm0Ch4, 28 | kFtm0Ch5, 29 | kFtm0Ch6, 30 | kFtm0Ch7, 31 | 32 | kFtm1Ch0 = 8, 33 | kFtm1Ch1, 34 | 35 | kFtm2Ch0 = 16, 36 | kFtm2Ch1, 37 | 38 | #if PINOUT_FTM_COUNT > 3 39 | kFtm3Ch0 = 24, 40 | kFtm3Ch1, 41 | kFtm3Ch2, 42 | kFtm3Ch3, 43 | kFtm3Ch4, 44 | kFtm3Ch5, 45 | kFtm3Ch6, 46 | kFtm3Ch7, 47 | #endif 48 | 49 | kDisable = 32 50 | }; 51 | 52 | enum struct QdName 53 | { 54 | kFtm0QdPha = 0, 55 | kFtm0QdPhb, 56 | kFtm1QdPha, 57 | kFtm1QdPhb, 58 | kFtm2QdPha, 59 | kFtm2QdPhb, 60 | #if PINOUT_FTM_COUNT > 3 61 | kFtm3QdPha, 62 | kFtm3QdPhb, 63 | #endif 64 | 65 | kDisable 66 | }; 67 | 68 | static Ftm& Get() 69 | { 70 | static Ftm ftm; 71 | return ftm; 72 | } 73 | 74 | static constexpr int GetMaxFtmChannelCount() 75 | { 76 | return static_cast(Name::kFtm1Ch0); 77 | } 78 | 79 | bool RegFtm(const Ftm::Name ftm, const bool is_exclusive_module); 80 | /** 81 | * Unregister a FTM channel and return whether the module is free or not 82 | * 83 | * @param ftm 84 | * @return 85 | */ 86 | bool UnregFtm(const Ftm::Name ftm); 87 | 88 | private: 89 | enum struct ModuleLockMode 90 | { 91 | kFree, 92 | kExclusive, 93 | kShared, 94 | }; 95 | 96 | Ftm(); 97 | 98 | ModuleLockMode m_module_lock[PINOUT_FTM_COUNT]; 99 | bool m_channel_lock[PINOUT_FTM_COUNT][PINOUT_FTM_CHANNEL_COUNT]; 100 | }; 101 | 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /inc/libbase/k60/soft_quad_decoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * soft_quad_decoder.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/k60/gpio.h" 15 | #include "libbase/k60/quad_decoder_interface.h" 16 | 17 | namespace libbase 18 | { 19 | namespace k60 20 | { 21 | 22 | /** 23 | * Software emulated quadrature decoding using pin interrupt and GPIO. In K60 24 | * under Phase AB mode, the encoder resolution will be extended to 4 times the 25 | * original when using hardware quadrature decoding. We emulate this behavior by 26 | * multiplying the current count by 4 in software mode, so there will be a 27 | * maximum of +-3 error 28 | */ 29 | class SoftQuadDecoder : public QuadDecoderInterface 30 | { 31 | public: 32 | struct Config : public QuadDecoderInterface::Config 33 | { 34 | /** 35 | * @see FtmQuadDecoder::Config::EncodingMode 36 | */ 37 | enum struct EncodingMode 38 | { 39 | kPhaseAB, 40 | kCountDirection, 41 | }; 42 | 43 | EncodingMode encoding_mode; 44 | }; 45 | 46 | explicit SoftQuadDecoder(const Config &config); 47 | explicit SoftQuadDecoder(nullptr_t); 48 | SoftQuadDecoder(const SoftQuadDecoder&) = delete; 49 | SoftQuadDecoder(SoftQuadDecoder &&rhs); 50 | ~SoftQuadDecoder(); 51 | 52 | SoftQuadDecoder& operator=(const SoftQuadDecoder&) = delete; 53 | SoftQuadDecoder& operator=(SoftQuadDecoder &&rhs); 54 | operator bool() const override 55 | { 56 | return m_is_init; 57 | } 58 | 59 | int32_t GetCount() override; 60 | void ResetCount() override; 61 | 62 | private: 63 | void Uninit(); 64 | 65 | void OnTick(Gpi*); 66 | 67 | bool m_is_invert_a_polarity; 68 | bool m_is_invert_b_polarity; 69 | bool m_is_dir_mode; 70 | 71 | Gpi m_qda; 72 | Gpi m_qdb; 73 | 74 | volatile int32_t m_count; 75 | 76 | bool m_is_init; 77 | }; 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /inc/libsc/encoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * encoder.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/helper.h" 15 | #include "libbase/pinout_macros.h" 16 | #include LIBBASE_H(gpio) 17 | #include LIBBASE_H(soft_quad_decoder) 18 | 19 | #if PINOUT_FTM_COUNT 20 | #include LIBBASE_H(ftm_quad_decoder) 21 | 22 | #elif PINOUT_TPM_COUNT 23 | #include LIBBASE_H(tpm_quad_decoder) 24 | 25 | #else 26 | #define LIBSC_USE_SOFT_ENCODER 1 27 | 28 | #endif // PINOUT_FTM_COUNT 29 | 30 | #include "libsc/config.h" 31 | 32 | namespace libsc 33 | { 34 | 35 | class Encoder 36 | { 37 | public: 38 | #if LIBSC_USE_SOFT_ENCODER 39 | typedef LIBBASE_MODULE(SoftQuadDecoder) QuadDecoder; 40 | 41 | #elif PINOUT_FTM_COUNT 42 | typedef LIBBASE_MODULE(FtmQuadDecoder) QuadDecoder; 43 | 44 | #elif PINOUT_TPM_COUNT 45 | typedef LIBBASE_MODULE(TpmQuadDecoder) QuadDecoder; 46 | 47 | #endif // LIBSC_USE_SOFT_ENCODER 48 | 49 | struct Config 50 | { 51 | uint8_t id; 52 | }; 53 | 54 | virtual ~Encoder(); 55 | 56 | void Update(); 57 | 58 | /** 59 | * Return the decoded count 60 | * 61 | * @return 62 | */ 63 | int32_t GetCount() const 64 | { 65 | return m_count; 66 | } 67 | 68 | protected: 69 | /** 70 | * Use to initialize the encoder in possibly a polymorphic way, notice that 71 | * Initializer::config is stored as a reference only 72 | */ 73 | struct Initializer 74 | { 75 | explicit Initializer(const Config &config) 76 | : config(config) 77 | {} 78 | 79 | virtual QuadDecoder::Config GetQuadDecoderConfig() const; 80 | 81 | const Config &config; 82 | }; 83 | 84 | explicit Encoder(const Initializer &initializer); 85 | explicit Encoder(nullptr_t); 86 | Encoder(Encoder &&rhs); 87 | 88 | private: 89 | int32_t m_count; 90 | 91 | QuadDecoder m_quad_decoder; 92 | }; 93 | 94 | } 95 | -------------------------------------------------------------------------------- /inc/libsc/k60/ov7725_configurator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ov7725_configurator.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/helper.h" 15 | #include "libbase/misc_types.h" 16 | #include LIBBASE_H(gpio) 17 | #include LIBBASE_H(soft_sccb_master) 18 | 19 | namespace libsc 20 | { 21 | namespace k60 22 | { 23 | 24 | class Ov7725Configurator 25 | { 26 | public: 27 | struct Config 28 | { 29 | enum struct Fps 30 | { 31 | kLow = 0, 32 | kMid, 33 | kHigh, 34 | }; 35 | 36 | enum struct Format 37 | { 38 | kYuv = 0, 39 | kProcessedBayerRaw, 40 | kRgb, 41 | kBayerRaw, 42 | }; 43 | 44 | enum struct RgbFormat 45 | { 46 | kGbr422 = 0, 47 | kRgb565, 48 | kRgb555, 49 | kRgb444, 50 | }; 51 | 52 | LIBBASE_MODULE(Pin)::Name scl; 53 | LIBBASE_MODULE(Pin)::Name sda; 54 | 55 | /// Width of the image, [1, 640] 56 | Uint w = 320; 57 | /// Height of the image, [1, 480] 58 | Uint h = 240; 59 | Fps fps = Fps::kLow; 60 | Format format = Format::kYuv; 61 | RgbFormat rgb_format = RgbFormat::kGbr422; 62 | 63 | uint8_t brightness = 0x00; 64 | uint8_t contrast = 0x40; 65 | }; 66 | 67 | explicit Ov7725Configurator(const Config &config); 68 | explicit Ov7725Configurator(nullptr_t); 69 | ~Ov7725Configurator(); 70 | 71 | bool Verify(); 72 | 73 | void ChangeSecialDigitalEffect(uint8_t brightness, uint8_t contrast); 74 | 75 | private: 76 | void InitCom2Reg(); 77 | void InitCom3Reg(); 78 | void InitClock(const Config &config); 79 | void InitResolution(const Config &config); 80 | void InitBandingFilter(); 81 | void InitLensCorrection(); 82 | void InitDsp(); 83 | void InitGamma(); 84 | void InitSecialDigitalEffect(const Config &config); 85 | void InitAutoUv(); 86 | 87 | LIBBASE_MODULE(SoftSccbMaster) m_sccb; 88 | }; 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/libbase/k60/fpu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * fpu.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/k60/hardware.h" 10 | 11 | #include 12 | 13 | #include "libbase/k60/fpu.h" 14 | #include "libbase/k60/fpu_c.h" 15 | #include "libbase/k60/misc_utils.h" 16 | 17 | #define FPU_FPDSCR_RMode(x) (((x) << FPU_FPDSCR_RMode_Pos) & FPU_FPDSCR_RMode_Msk) 18 | 19 | namespace libbase 20 | { 21 | namespace k60 22 | { 23 | 24 | #if __FPU_PRESENT 25 | 26 | Fpu::Fpu() 27 | {} 28 | 29 | void Fpu::Init() 30 | { 31 | const Config &config = GetFpuConfig(); 32 | 33 | // Enable full access to the FPU coprocessor 34 | SCB->CPACR |= 0x00F00000; 35 | InitFpccr(config); 36 | InitFpdscr(config); 37 | } 38 | 39 | void Fpu::InitFpccr(const Config&) 40 | { 41 | // ASPEN and LSPEN must not be modified at this stage 42 | uint32_t reg = FPU->FPCCR & (FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk); 43 | SET_BIT(reg, FPU_FPCCR_MONRDY_Pos); 44 | SET_BIT(reg, FPU_FPCCR_BFRDY_Pos); 45 | SET_BIT(reg, FPU_FPCCR_MMRDY_Pos); 46 | SET_BIT(reg, FPU_FPCCR_HFRDY_Pos); 47 | SET_BIT(reg, FPU_FPCCR_THREAD_Pos); 48 | SET_BIT(reg, FPU_FPCCR_USER_Pos); 49 | // enable lazy stacking 50 | SET_BIT(reg, FPU_FPCCR_LSPACT_Pos); 51 | 52 | FPU->FPCCR = reg; 53 | } 54 | 55 | void Fpu::InitFpdscr(const Config &config) 56 | { 57 | uint32_t reg = 0; 58 | if (config.is_default_nan) 59 | { 60 | SET_BIT(reg, FPU_FPDSCR_DN_Pos); 61 | } 62 | if (config.is_flush_to_zero) 63 | { 64 | SET_BIT(reg, FPU_FPDSCR_FZ_Pos); 65 | } 66 | reg |= FPU_FPDSCR_RMode((int)config.rounding_mode); 67 | 68 | FPU->FPDSCR = reg; 69 | } 70 | 71 | __attribute__((__weak__)) 72 | Fpu::Config Fpu::GetFpuConfig() 73 | { 74 | // Just use the default config 75 | return {}; 76 | } 77 | 78 | #endif 79 | 80 | } 81 | } 82 | 83 | void LibbaseK60FpuInit() 84 | { 85 | #if __FPU_PRESENT 86 | libbase::k60::Fpu::Get().Init(); 87 | #endif 88 | } 89 | -------------------------------------------------------------------------------- /inc/libsc/k60/config/2013_magnetic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 2013_magnetic.h 3 | * Config file for 2013 Gen 2/3 board 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #ifndef LIBSC_2013_MAGNETIC_H_ 11 | #define LIBSC_2013_MAGNETIC_H_ 12 | 13 | /* 14 | * The number should represent the number of devices available, e.g., 15 | * define LIBSC_USE_UART to 2 when there are two UART devices connected. Comment 16 | * out the specific defines instead of defining them to 0 for unused devices 17 | */ 18 | #define LIBSC_USE_UART 1 19 | //#define LIBSC_USE_ENCODER 1 20 | //#define LIBSC_USE_ENCODER_FTM 21 | //#define LIBSC_USE_LCD 1 22 | //#define LIBSC_USE_LCD_HW_SPI 23 | #define LIBSC_USE_LED 4 24 | #define LIBSC_USE_MOTOR 2 25 | #define LIBSC_USE_SERVO 1 26 | 27 | #define LIBSC_BT_UART UART3 28 | #define LIBSC_BT_UART_BAUD 115200 29 | 30 | #ifdef LIBSC_USE_ENCODER_FTM 31 | #define LIBSC_ENCODER0_OUT PTB18 32 | #define LIBSC_ENCODER0_VCC PTB19 33 | 34 | #else 35 | #define LIBSC_ENCODER0 PTA6 36 | #define LIBSC_ENCODER1 PTA7 37 | 38 | #endif 39 | 40 | #ifdef LIBSC_USE_LCD_HW_SPI 41 | #define LIBSC_LCD_RST PTA13 42 | #define LIBSC_LCD_DC PTA17 43 | #define LIBSC_LCD_CS PTA14 44 | // Connect SOUT pin with SDAT 45 | #define LIBSC_LCD_MOSI PTA16 46 | // MISO pin is not used (one way transfer) but is needed to get the SPI info 47 | #define LIBSC_LCD_MISO PTA17 48 | #define LIBSC_LCD_SCLK PTA15 49 | 50 | #else 51 | #define LIBSC_LCD_RST PTA13 52 | #define LIBSC_LCD_DC PTA17 53 | #define LIBSC_LCD_CS PTA14 54 | #define LIBSC_LCD_SDAT PTA16 55 | #define LIBSC_LCD_SCLK PTA15 56 | 57 | #endif 58 | 59 | #define LIBSC_LED0 PTE24 60 | #define LIBSC_LED1 PTE25 61 | #define LIBSC_LED2 PTE26 62 | #define LIBSC_LED3 PTE27 63 | #define LIBSC_MOTOR0_PWM PTA8 64 | #define LIBSC_MOTOR0_DIR PTD7 65 | #define LIBSC_MOTOR1_PWM PTA9 66 | #define LIBSC_MOTOR1_DIR PTD9 67 | #define LIBSC_SERVO0 PTA10 68 | 69 | #endif /* LIBSC_2013_MAGNETIC_H_ */ 70 | -------------------------------------------------------------------------------- /inc/libbase/kl26/sim.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sim.h 3 | * System integration module 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include "libbase/kl26/misc_utils.h" 18 | 19 | namespace libbase 20 | { 21 | namespace kl26 22 | { 23 | 24 | class Sim 25 | { 26 | public: 27 | enum struct Kinetis 28 | { 29 | kKl00, 30 | kKl10, 31 | kKl20, 32 | kKl30, 33 | kKl40, 34 | }; 35 | 36 | enum struct ClockGate 37 | { 38 | kAdc0, 39 | kCmp, 40 | kDac0, 41 | kDma, 42 | kDmaMux, 43 | kFlash, 44 | kI2c0, 45 | kI2c1, 46 | kI2s, 47 | kLptimer, 48 | kPit, 49 | kPortA, 50 | kPortB, 51 | kPortC, 52 | kPortD, 53 | kPortE, 54 | kRtc, 55 | kSpi0, 56 | kSpi1, 57 | kTsi, 58 | kTpm0, 59 | kTpm1, 60 | kTpm2, 61 | kUart0, 62 | kUart1, 63 | kUart2, 64 | kUsbOtg, 65 | }; 66 | 67 | enum struct TpmClock 68 | { 69 | kDisable = 0, 70 | kPll, 71 | kOscer, 72 | kMcgir, 73 | }; 74 | 75 | enum struct UartClock 76 | { 77 | kDisable = 0, 78 | kPll, 79 | kOscer, 80 | kMcgir, 81 | }; 82 | 83 | static uint32_t GetRamBytes(); 84 | static Uint GetRamKBytes() 85 | { 86 | return GetRamBytes() >> 10; 87 | } 88 | 89 | static Kinetis GetKinetisFamily(); 90 | static std::array GetUid(); 91 | static std::string GetUidStr(); 92 | 93 | static void SetEnableClockGate(const ClockGate cg, const bool flag); 94 | static void SetTpmClockSource(const TpmClock clock_src); 95 | static void SetUart0ClockSource(const UartClock clock_src); 96 | static void SetTpmExternalClockPin(const Uint module, const Uint clock_pin); 97 | static uint8_t GetCoreClockDivider(); 98 | static uint8_t GetBusClockDivider(); 99 | static uint8_t GetFlashClockDivider(); 100 | }; 101 | 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /inc/libsc/k60/ov7725_fifo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ov7725_fifo.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "libbase/k60/gpio.h" 16 | #include "libbase/misc_types.h" 17 | 18 | #include "libsc/k60/al422b.h" 19 | #include "libsc/k60/ov7725.h" 20 | #include "libsc/k60/ov7725_configurator.h" 21 | 22 | namespace libsc 23 | { 24 | namespace k60 25 | { 26 | 27 | /** 28 | * OV7725 + FIFO camera 29 | */ 30 | class Ov7725Fifo 31 | { 32 | public: 33 | typedef Ov7725::Config Config; 34 | 35 | explicit Ov7725Fifo(const Config &config); 36 | ~Ov7725Fifo(); 37 | 38 | /** 39 | * Start shooting a frame. No effect if the previous frame has not yet 40 | * finished reading 41 | * 42 | * @see ReadStep() 43 | */ 44 | void Start(); 45 | /** 46 | * @see Al422b::ReadStep() 47 | */ 48 | bool ReadStep(); 49 | 50 | /** 51 | * Return the raw data, in RGB565 (so 2 bytes form 1 pixel) 52 | * 53 | * @return 54 | * @note On LE platform, you can't simply cast it to uint16_t* 55 | */ 56 | const std::vector& GetData() const 57 | { 58 | return m_fifo.GetData(); 59 | } 60 | 61 | /** 62 | * Return the transformed data, as a RGB565 array 63 | * 64 | * @return 65 | */ 66 | std::vector GetRgb565Data() const; 67 | 68 | Uint GetW() const 69 | { 70 | return m_w; 71 | } 72 | 73 | Uint GetH() const 74 | { 75 | return m_h; 76 | } 77 | 78 | private: 79 | enum State 80 | { 81 | kIdle, 82 | kReqStart, 83 | kStart, 84 | }; 85 | 86 | void OnVsync(libbase::k60::Gpi *gpi); 87 | 88 | Ov7725Configurator m_config; 89 | Al422b m_fifo; 90 | libbase::k60::Gpo m_wen; 91 | libbase::k60::Gpi m_vsync; 92 | 93 | Uint m_w; 94 | Uint m_h; 95 | 96 | volatile State m_write_state; 97 | }; 98 | 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /inc/libbase/k60/soft_spi_master.h: -------------------------------------------------------------------------------- 1 | /* 2 | * soft_spi_master.h 3 | * Emulated SPI through GPIO with a compatible interface with SpiMaster 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #include "libbase/k60/gpio.h" 16 | #include "libbase/k60/spi_master_interface.h" 17 | 18 | namespace libbase 19 | { 20 | namespace k60 21 | { 22 | 23 | class SoftSpiMaster : public SpiMasterInterface 24 | { 25 | public: 26 | typedef SpiMasterInterface::Config Config; 27 | 28 | static constexpr Uint kSlaveCount = SpiMasterInterface::kSlaveCount; 29 | 30 | /** 31 | * Construct a new instance. Only the following parameters are supported, 32 | * others will be ignored: 33 | * sin_pin, sout_pin, sck_pin, frame_size, is_sck_idle_low, is_msb_firt, 34 | * slaves 35 | * 36 | * @param config 37 | */ 38 | explicit SoftSpiMaster(const Config &config); 39 | explicit SoftSpiMaster(nullptr_t); 40 | SoftSpiMaster(const SoftSpiMaster&) = delete; 41 | SoftSpiMaster(SoftSpiMaster &&rhs); 42 | ~SoftSpiMaster(); 43 | 44 | SoftSpiMaster& operator=(const SoftSpiMaster&) = delete; 45 | SoftSpiMaster& operator=(SoftSpiMaster &&rhs); 46 | operator bool() const override 47 | { 48 | return m_is_init; 49 | } 50 | 51 | uint16_t ExchangeData(const uint8_t slave_id, const uint16_t data) override; 52 | 53 | void KickStart() override; 54 | size_t PushData(const uint8_t slave_id, const uint16_t *data, 55 | const size_t size) override; 56 | size_t PushData(const uint8_t slave_id, const uint8_t *data, 57 | const size_t size) override; 58 | 59 | uint8_t GetFrameSize() const 60 | { 61 | return m_frame_size; 62 | } 63 | 64 | private: 65 | Gpi m_sin; 66 | Gpo m_sout; 67 | Gpo m_sck; 68 | Gpo m_cs[kSlaveCount]; 69 | 70 | uint8_t m_frame_size; 71 | bool m_is_sck_capture_first; 72 | bool m_is_msb_first; 73 | 74 | bool m_is_init; 75 | }; 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/libbase/k60/ftm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ftm.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/k60/hardware.h" 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "libbase/k60/ftm_utils.h" 16 | #include "libbase/k60/pinout.h" 17 | #include "libbase/misc_types.h" 18 | 19 | namespace libbase 20 | { 21 | namespace k60 22 | { 23 | 24 | Ftm::Ftm() 25 | { 26 | for (Uint i = 0; i < PINOUT_FTM_COUNT; ++i) 27 | { 28 | m_module_lock[i] = ModuleLockMode::kFree; 29 | for (Uint j = 0; j < PINOUT_FTM_CHANNEL_COUNT; ++j) 30 | { 31 | m_channel_lock[i][j] = false; 32 | } 33 | } 34 | } 35 | 36 | bool Ftm::RegFtm(const Ftm::Name ftm, const bool is_exclusive_module) 37 | { 38 | const Uint module = FtmUtils::GetFtmModule(ftm); 39 | const Uint channel = FtmUtils::GetFtmChannel(ftm); 40 | assert(module < PINOUT_FTM_COUNT); 41 | assert(channel < PINOUT_FTM_CHANNEL_COUNT); 42 | if (m_module_lock[module] == ModuleLockMode::kExclusive) 43 | { 44 | return false; 45 | } 46 | else if (m_module_lock[module] == ModuleLockMode::kShared 47 | && is_exclusive_module) 48 | { 49 | return false; 50 | } 51 | else if (m_channel_lock[module][channel]) 52 | { 53 | return false; 54 | } 55 | 56 | m_module_lock[module] = is_exclusive_module ? ModuleLockMode::kExclusive 57 | : ModuleLockMode::kShared; 58 | m_channel_lock[module][channel] = true; 59 | return true; 60 | } 61 | 62 | bool Ftm::UnregFtm(const Ftm::Name ftm) 63 | { 64 | const Uint module = FtmUtils::GetFtmModule(ftm); 65 | const Uint channel = FtmUtils::GetFtmChannel(ftm); 66 | assert(module < PINOUT_FTM_COUNT); 67 | assert(channel < PINOUT_FTM_CHANNEL_COUNT); 68 | m_channel_lock[module][channel] = false; 69 | 70 | for (bool l : m_channel_lock[PINOUT_FTM_COUNT]) 71 | { 72 | if (l) 73 | { 74 | return false; 75 | } 76 | } 77 | m_module_lock[module] = ModuleLockMode::kFree; 78 | return true; 79 | } 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/libbase/kl26/tpm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tpm.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include "libbase/kl26/hardware.h" 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "libbase/kl26/tpm_utils.h" 16 | #include "libbase/kl26/pinout.h" 17 | #include "libbase/misc_types.h" 18 | 19 | namespace libbase 20 | { 21 | namespace kl26 22 | { 23 | 24 | Tpm::Tpm() 25 | { 26 | for (Uint i = 0; i < PINOUT_TPM_COUNT; ++i) 27 | { 28 | m_module_lock[i] = ModuleLockMode::kFree; 29 | for (Uint j = 0; j < PINOUT_TPM_CHANNEL_COUNT; ++j) 30 | { 31 | m_channel_lock[i][j] = false; 32 | } 33 | } 34 | } 35 | 36 | bool Tpm::RegTpm(const Tpm::Name tpm, const bool is_exclusive_module) 37 | { 38 | const Uint module = TpmUtils::GetTpmModule(tpm); 39 | const Uint channel = TpmUtils::GetTpmChannel(tpm); 40 | assert(module < PINOUT_TPM_COUNT); 41 | assert(channel < PINOUT_TPM_CHANNEL_COUNT); 42 | if (m_module_lock[module] == ModuleLockMode::kExclusive) 43 | { 44 | return false; 45 | } 46 | else if (m_module_lock[module] == ModuleLockMode::kShared 47 | && is_exclusive_module) 48 | { 49 | return false; 50 | } 51 | else if (m_channel_lock[module][channel]) 52 | { 53 | return false; 54 | } 55 | 56 | m_module_lock[module] = is_exclusive_module ? ModuleLockMode::kExclusive 57 | : ModuleLockMode::kShared; 58 | m_channel_lock[module][channel] = true; 59 | return true; 60 | } 61 | 62 | bool Tpm::UnregTpm(const Tpm::Name tpm) 63 | { 64 | const Uint module = TpmUtils::GetTpmModule(tpm); 65 | const Uint channel = TpmUtils::GetTpmChannel(tpm); 66 | assert(module < PINOUT_TPM_COUNT); 67 | assert(channel < PINOUT_TPM_CHANNEL_COUNT); 68 | m_channel_lock[module][channel] = false; 69 | 70 | for (bool l : m_channel_lock[PINOUT_TPM_COUNT]) 71 | { 72 | if (l) 73 | { 74 | return false; 75 | } 76 | } 77 | m_module_lock[module] = ModuleLockMode::kFree; 78 | return true; 79 | } 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/libsc/led.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * led.cpp 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include "libbase/log.h" 13 | #include "libbase/helper.h" 14 | #include LIBBASE_H(gpio) 15 | 16 | #include "libsc/config.h" 17 | #include "libsc/led.h" 18 | 19 | using namespace LIBBASE_NS; 20 | 21 | namespace libsc 22 | { 23 | 24 | #ifdef LIBSC_USE_LED 25 | 26 | namespace 27 | { 28 | 29 | #if LIBSC_USE_LED == 1 30 | inline Pin::Name GetPin(const uint8_t id) 31 | { 32 | if (id != 0) 33 | { 34 | assert(false); 35 | } 36 | return LIBSC_LED0; 37 | } 38 | 39 | #else 40 | inline Pin::Name GetPin(const uint8_t id) 41 | { 42 | switch (id) 43 | { 44 | default: 45 | assert(false); 46 | // no break 47 | 48 | case 0: 49 | return LIBSC_LED0; 50 | 51 | #if LIBSC_USE_LED > 1 52 | case 1: 53 | return LIBSC_LED1; 54 | #endif 55 | 56 | #if LIBSC_USE_LED > 2 57 | case 2: 58 | return LIBSC_LED2; 59 | #endif 60 | 61 | #if LIBSC_USE_LED > 3 62 | case 3: 63 | return LIBSC_LED3; 64 | #endif 65 | } 66 | } 67 | 68 | #endif 69 | 70 | Gpo::Config GetGpoConfig(const Led::Config &config) 71 | { 72 | Gpo::Config product; 73 | product.pin = GetPin(config.id); 74 | // Default off 75 | product.is_high = config.is_active_low; 76 | return product; 77 | } 78 | 79 | } 80 | 81 | Led::Led(const Config &config) 82 | : m_pin(GetGpoConfig(config)), 83 | m_is_active_low(config.is_active_low) 84 | {} 85 | 86 | void Led::SetEnable(const bool flag) 87 | { 88 | m_pin.Set(flag ^ m_is_active_low); 89 | } 90 | 91 | void Led::Switch() 92 | { 93 | m_pin.Turn(); 94 | } 95 | 96 | #else 97 | Led::Led(const Config&) 98 | : m_pin(nullptr), m_is_active_low(false) 99 | { 100 | LOG_DL("Configured not to use Led"); 101 | } 102 | void Led::SetEnable(const bool) {} 103 | void Led::Switch() {} 104 | 105 | #endif 106 | 107 | } 108 | -------------------------------------------------------------------------------- /inc/libutil/positional_pid_controller.tcc: -------------------------------------------------------------------------------- 1 | /* 2 | * positional_pid_controller.tcc 3 | * Generic poitional PID controller 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | */ 9 | 10 | #pragma once 11 | 12 | #if MK60DZ10 || MK60D10 || MK60F15 13 | #include "libsc/system.h" 14 | 15 | #elif MKL26Z4 16 | #include "libsc/system.h" 17 | 18 | #endif 19 | 20 | #include "libsc/timer.h" 21 | #include "libutil/misc.h" 22 | #include "libutil/positional_pid_controller.h" 23 | 24 | namespace libutil 25 | { 26 | 27 | template 28 | PositionalPidController::PositionalPidController(const InT setpoint, 29 | const float kp, const float ki, const float kd) 30 | : PidController(setpoint, kp, ki, kd), 31 | m_i_limit(0.0f), 32 | 33 | m_accumulated_error(0.0f), 34 | m_prev_error(0), 35 | m_prev_time(libsc::System::Time()) 36 | 37 | {} 38 | 39 | template 40 | void PositionalPidController::OnCalc(const InT error) 41 | { 42 | using namespace libsc; 43 | #if MK60DZ10 || MK60D10 || MK60F15 44 | using namespace libsc::k60; 45 | #elif MKL26Z4 46 | using namespace libsc::kl26; 47 | #endif 48 | 49 | const Timer::TimerInt time = System::Time(); 50 | const float time_diff = Timer::TimeDiff(System::Time(), m_prev_time) 51 | / 1000.0f; 52 | 53 | const float p = this->GetKp() * error; 54 | m_accumulated_error += error * time_diff; 55 | float i = this->GetKi() * m_accumulated_error; 56 | if (m_i_limit > 0.0f) 57 | { 58 | i = Clamp(-m_i_limit, i, m_i_limit); 59 | } 60 | const float slope = (error - m_prev_error) / time_diff; 61 | const float d = this->GetKd() * slope; 62 | 63 | m_prev_error = error; 64 | m_prev_time = time; 65 | this->UpdatePid(p, i, d); 66 | } 67 | 68 | template 69 | OutT_ PositionalPidController::GetControlOut() 70 | { 71 | return this->GetP() + this->GetI() + this->GetD(); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /inc/libsc/lcd_console.h: -------------------------------------------------------------------------------- 1 | /* 2 | * lcd_console.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "libsc/lcd_typewriter.h" 17 | #include "libsc/st7735r.h" 18 | #include "libutil/misc.h" 19 | 20 | namespace libsc 21 | { 22 | 23 | /** 24 | * Print text on screen with a managed buffer. Only changed contents are updated 25 | */ 26 | class LcdConsole 27 | { 28 | public: 29 | // Conditionally select Lcd implementation here. Should prevent working with 30 | // the interface directly (performance) 31 | typedef St7735r Lcd; 32 | 33 | struct Config 34 | { 35 | Lcd *lcd = nullptr; 36 | /// The screen region for this console 37 | Lcd::Rect region; 38 | uint16_t text_color = 0xFFFF; 39 | uint16_t bg_color = 0; 40 | }; 41 | 42 | explicit LcdConsole(const Config &config); 43 | 44 | void WriteChar(const char ch); 45 | void WriteString(const char *str); 46 | void WriteBuffer(const char *buf, const size_t length); 47 | 48 | void Clear(const bool is_clear_screen); 49 | 50 | void SetCursorRow(const uint8_t row) 51 | { 52 | m_cursor_x = 0; 53 | m_cursor_y = libutil::ClampVal(0, row, m_max_text_y); 54 | } 55 | 56 | void SetCursorColumn(const uint8_t col) { 57 | m_cursor_x = col; 58 | } 59 | 60 | void SetTextColor(const uint16_t color) 61 | { 62 | m_typewriter.SetTextColor(color); 63 | } 64 | 65 | void SetBgColor(const uint16_t color) 66 | { 67 | m_typewriter.SetBgColor(color); 68 | } 69 | 70 | private: 71 | struct CellData 72 | { 73 | char ch; 74 | uint16_t color; 75 | uint16_t bg_color; 76 | }; 77 | 78 | inline void NewChar(); 79 | inline void NewLine(); 80 | 81 | Lcd *const m_lcd; 82 | LcdTypewriter m_typewriter; 83 | Lcd::Rect m_region; 84 | Uint m_cursor_x; 85 | Uint m_cursor_y; 86 | 87 | Uint m_max_text_x; 88 | Uint m_max_text_y; 89 | 90 | std::unique_ptr m_buffer; 91 | }; 92 | 93 | } 94 | -------------------------------------------------------------------------------- /inc/libbase/kl26/spi_master_interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spi_master_interface.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014-2015 HKUST SmartCar Team 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include "libbase/misc_types.h" 15 | #include "libbase/kl26/pin.h" 16 | 17 | namespace libbase 18 | { 19 | namespace kl26 20 | { 21 | 22 | class SpiMasterInterface 23 | { 24 | public: 25 | struct Config 26 | { 27 | // At least one among SIN/SOUT have to be set 28 | Pin::Name sin_pin = Pin::Name::kDisable; 29 | Pin::Name sout_pin = Pin::Name::kDisable; 30 | Pin::Name sck_pin; 31 | Pin::Name pcs_pin; 32 | 33 | /** 34 | * # bits transfered per frame, 8 or 16 35 | * @note Only 8 is currently supported 36 | */ 37 | uint8_t frame_size = 8; 38 | /** 39 | * Set the clock polarity 40 | */ 41 | bool is_sck_idle_low = true; 42 | /** 43 | * Specifies whether the LSB or MSB of the frame is transferred first 44 | */ 45 | bool is_msb_firt = true; 46 | /** 47 | * Set the clock phase, if true, data is captured on the leading edge of 48 | * SCK and changed on the following edge 49 | */ 50 | bool is_sck_capture_first = true; 51 | }; 52 | 53 | virtual ~SpiMasterInterface() 54 | {} 55 | 56 | virtual operator bool() const = 0; 57 | 58 | /** 59 | * Exchange data with slave, this is a blocking operation. Do NOT use this 60 | * method with listeners being setup 61 | * 62 | * @param slave_id The target slave, see Config::slaves for details 63 | * @param data The data to be sent, in 3-wire setup without sout, this value 64 | * will be ignored 65 | * @return The received data, or 0 in 3-wire setup without sin 66 | */ 67 | virtual uint16_t ExchangeData(const uint8_t slave_id, const uint16_t data) = 0; 68 | 69 | virtual size_t PushData(const uint8_t slave_id, const uint16_t *data, 70 | const size_t size) = 0; 71 | virtual size_t PushData(const uint8_t slave_id, const uint8_t *data, 72 | const size_t size) = 0; 73 | }; 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /inc/libbase/kl26/vectors.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * vectors.h 4 | * 5 | * Author: Ming Tsang 6 | * Copyright (c) 2014-2015 HKUST SmartCar Team 7 | * Refer to LICENSE for details 8 | 9 | ################################################################### 10 | ** THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT. 11 | ** Filename : Cpu.h 12 | ** Project : ProcessorExpert 13 | ** Processor : Mkl26DN512ZVLQ10 14 | ** Component : Mkl26N512LQ100 15 | ** Version : Component 01.000, Driver 01.04, CPU db: 3.00.001 16 | ** Datasheet : kl26P144M100SF2RM, Rev. 5, 8 May 2011 17 | ** Compiler : GNU C Compiler 18 | ** Date/Time : 2014-01-15, 23:29, # CodeGen: 0 19 | ** Abstract : 20 | ** 21 | ** Settings : 22 | ** 23 | ** Contents : 24 | ** No public methods 25 | ** 26 | ** (c) Freescale Semiconductor, Inc. 27 | ** 2004 All Rights Reserved 28 | ** 29 | ** Copyright : 1997 - 2013 Freescale Semiconductor, Inc. All Rights Reserved. 30 | ** SOURCE DISTRIBUTION PERMISSIBLE as directed in End User License Agreement. 31 | ** 32 | ** http : www.freescale.com 33 | ** mail : support@freescale.com 34 | ** ################################################################### 35 | ** 36 | ** */ 37 | 38 | #pragma once 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | #include "libbase/kl26/hardware.h" 45 | #include "libbase/kl26/misc_utils_c.h" 46 | 47 | // Interrupt handler type definition 48 | typedef void (*tIsrFunc)(void); 49 | 50 | typedef void (*HardFaultHandler)(void); 51 | extern HardFaultHandler g_hard_fault_handler; 52 | 53 | #define GetActiveVector() ((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) >> SCB_ICSR_VECTACTIVE_Pos) 54 | #define VectorToIrq(x) (x - 16) 55 | #define GetActiveIrq() VectorToIrq(GetActiveVector()) 56 | 57 | void InitVectorTable(void); 58 | void SetIsr(IRQn_Type irq, tIsrFunc handler); 59 | void EnableIrq(IRQn_Type irq); 60 | void DisableIrq(IRQn_Type irq); 61 | __ISR void DefaultIsr(void); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /inc/libutil/pid_controller.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pid_controller.h 3 | * 4 | * Author: Ming Tsang 5 | * Copyright (c) 2014 Ming Tsang 6 | * Refer to LICENSE for details 7 | */ 8 | 9 | #pragma once 10 | 11 | namespace libutil 12 | { 13 | 14 | template 15 | class PidController 16 | { 17 | public: 18 | typedef InT_ InT; 19 | typedef OutT_ OutT; 20 | 21 | PidController(const InT setpoint, const float kp, const float ki, 22 | const float kd); 23 | 24 | OutT Calc(const InT current_val); 25 | 26 | void SetSetpoint(const InT setpoint) 27 | { 28 | m_setpoint = setpoint; 29 | } 30 | 31 | InT GetSetpoint() const 32 | { 33 | return m_setpoint; 34 | } 35 | 36 | void SetKp(const float kp) 37 | { 38 | m_kp = kp; 39 | } 40 | 41 | float GetKp() const 42 | { 43 | return m_kp; 44 | } 45 | 46 | void SetKi(const float ki) 47 | { 48 | m_ki = ki; 49 | } 50 | 51 | float GetKi() const 52 | { 53 | return m_ki; 54 | } 55 | 56 | void SetKd(const float kd) 57 | { 58 | m_kd = kd; 59 | } 60 | 61 | float GetKd() const 62 | { 63 | return m_kd; 64 | } 65 | 66 | void SetOutputBound(const OutT min, OutT max) 67 | { 68 | m_min_o = min; 69 | m_max_o = max; 70 | } 71 | 72 | float GetP() const 73 | { 74 | return m_p; 75 | } 76 | 77 | float GetI() const 78 | { 79 | return m_i; 80 | } 81 | 82 | float GetD() const 83 | { 84 | return m_d; 85 | } 86 | 87 | OutT GetPrevOut() const 88 | { 89 | return m_prev_out; 90 | } 91 | 92 | protected: 93 | ~PidController() 94 | {} 95 | 96 | virtual void OnCalc(const InT error) = 0; 97 | virtual OutT GetControlOut() = 0; 98 | void UpdatePid(const float p, const float i, const float d); 99 | 100 | private: 101 | InT m_setpoint; 102 | float m_kp; 103 | float m_ki; 104 | float m_kd; 105 | 106 | float m_p; 107 | float m_i; 108 | float m_d; 109 | 110 | OutT m_min_o; 111 | OutT m_max_o; 112 | OutT m_prev_out; 113 | }; 114 | 115 | } 116 | 117 | #include "pid_controller.tcc" 118 | --------------------------------------------------------------------------------