Compare commits
	
		
			5 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1ba14d734c | |||
| 0739dca655 | |||
| 8033e2dc5d | |||
| c459375677 | |||
| 7d20f156e1 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -11,6 +11,7 @@ deliver/ | |||||||
| *.ld | *.ld | ||||||
| Debug/ | Debug/ | ||||||
| Release/ | Release/ | ||||||
|  | *.launch | ||||||
| 
 | 
 | ||||||
| # Keil related | # Keil related | ||||||
| Keil/ | Keil/ | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @ -7,3 +7,12 @@ | |||||||
| [submodule "assignment_2/Libraries/STM32CubeF4"] | [submodule "assignment_2/Libraries/STM32CubeF4"] | ||||||
| 	path = assignment_2/Libraries/STM32CubeF4 | 	path = assignment_2/Libraries/STM32CubeF4 | ||||||
| 	url = https://github.com/hoo2/STM32CubeF4.git | 	url = https://github.com/hoo2/STM32CubeF4.git | ||||||
|  | [submodule "assignment_3/thermostat_shield/AltiumLib"] | ||||||
|  | 	path = assignment_3/thermostat_shield/AltiumLib | ||||||
|  | 	url = git@gitlab.com:hoo2/altium-lib.git | ||||||
|  | [submodule "assignment_3/Libraries/STM32CubeF4"] | ||||||
|  | 	path = assignment_3/Libraries/STM32CubeF4 | ||||||
|  | 	url = https://github.com/STMicroelectronics/STM32CubeF4.git | ||||||
|  | [submodule "assignment_3/report/config"] | ||||||
|  | 	path = assignment_3/report/config | ||||||
|  | 	url = https://git.hoo2.net/hoo2/LaTeX_confing.git | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								assignment_3/Libraries/STM32CubeF4
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								assignment_3/Libraries/STM32CubeF4
									
									
									
									
									
										Submodule
									
								
							| @ -0,0 +1 @@ | |||||||
|  | Subproject commit 5d01400afd60410f6e049cbd19179a67d44d53fd | ||||||
							
								
								
									
										319
									
								
								assignment_3/Libraries/drivers/NUCLEO_F401RE.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								assignment_3/Libraries/drivers/NUCLEO_F401RE.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,319 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file | ||||||
|  |  *    NUCLEO_F401RE.h | ||||||
|  |  * \brief | ||||||
|  |  *    Nucleo F401RE port file. This file contain the implementation of driver | ||||||
|  |  *    calls for F401RE board. | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  */ | ||||||
|  | #include "NUCLEO_F401RE.h" | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== System =============== | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | static clock_t volatile __ticks;       //!< CPU time
 | ||||||
|  | static time_t  volatile __now;         //!< Time in UNIX seconds past 1-Jan-70
 | ||||||
|  | static clock_t volatile __sys_freq;    //!< The CPU's time frequency (SysTick freq)
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    This is the SysTick ISR, micro-system time base service for CPU time. | ||||||
|  |  * \note | ||||||
|  |  *    This service implements the SysTick callback function in order | ||||||
|  |  *    to provide micro system - os like functionalities to an application | ||||||
|  |  *    without RTOS | ||||||
|  |  */ | ||||||
|  | void SysTick_Handler(void) { | ||||||
|  |    // Time
 | ||||||
|  |    ++__ticks; | ||||||
|  |    if ( !(__ticks % __sys_freq ) ) | ||||||
|  |       ++__now; // Do not update __now when we have external time system
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief This function configures the source of the time base. | ||||||
|  |  *        The time source is configured  to have 1ms time base with a dedicated | ||||||
|  |  *        Tick interrupt priority. | ||||||
|  |  * \param sf   Tick interrupt frequency. | ||||||
|  |  * \retval     HAL status | ||||||
|  |  */ | ||||||
|  | __weak HAL_StatusTypeDef HAL_SysTick_Init(clock_t sf) { | ||||||
|  |    SystemCoreClockUpdate (); | ||||||
|  | 
 | ||||||
|  |   /* Configure the SysTick to have interrupt in sf time basis */ | ||||||
|  |    if (SysTick_Config (SystemCoreClock/sf) != 0) | ||||||
|  |       return HAL_ERROR; | ||||||
|  |    __sys_freq = sf; | ||||||
|  | 
 | ||||||
|  |   /*Configure the SysTick IRQ priority */ | ||||||
|  |    NVIC_SetPriority (SysTick_IRQn, 3U); | ||||||
|  | 
 | ||||||
|  |    /* Return function status */ | ||||||
|  |   return HAL_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Select the system frequency without calling the Setting functionality | ||||||
|  |  * \param sf   The desired value | ||||||
|  |  * \return     The desired value (enable chaining) | ||||||
|  |  */ | ||||||
|  | __INLINE clock_t HAL_SelectSysTickFreq (clock_t sf){ | ||||||
|  |    return __sys_freq =sf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief Get the __sys_freq. | ||||||
|  |  */ | ||||||
|  | __INLINE clock_t HAL_GetSysTickFreq (void){ | ||||||
|  |    return __sys_freq; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief Reconfigure the SysTick and update __sys_freq | ||||||
|  |  * \param   sf    Tick interrupt frequency (CPU time) | ||||||
|  |  * \return  status of the operation | ||||||
|  |  *    \arg  0     Success | ||||||
|  |  *    \arg  1     Fail | ||||||
|  |  */ | ||||||
|  | int HAL_SetSysTickFreq (clock_t sf) { | ||||||
|  |   /*Configure the SysTick to have interrupt in sf time basis*/ | ||||||
|  |    if (__sys_freq != sf) { | ||||||
|  |       // Time base configuration
 | ||||||
|  |       SystemCoreClockUpdate (); | ||||||
|  |       if (SysTick_Config ( (SystemCoreClock>>3)/sf) != 0) | ||||||
|  |          return 1; | ||||||
|  |       else { | ||||||
|  |          __sys_freq = sf; | ||||||
|  |          return 0; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Take over control of SysTick from HAL library
 | ||||||
|  | 
 | ||||||
|  | //! disable HAL_InitTick implementation
 | ||||||
|  | HAL_StatusTypeDef | ||||||
|  |          HAL_InitTick(uint32_t TickPriority) { return HAL_OK; } | ||||||
|  | 
 | ||||||
|  | //! Chain GetTick to our implementation
 | ||||||
|  | uint32_t HAL_GetTick(void) { return clock(); } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief This function provides minimum delay (in CPU time) based | ||||||
|  |  *        on variable incremented. | ||||||
|  |  * \param Delay specifies the delay time length, in CPU time. | ||||||
|  |  * \note | ||||||
|  |  *    uint32_t is implicitly convertible to clock_t and vice versa. | ||||||
|  |  */ | ||||||
|  | void HAL_Delay(uint32_t Delay) { | ||||||
|  |   uint32_t tickstart = clock(); | ||||||
|  | 
 | ||||||
|  |   while((clock() - tickstart) < Delay) | ||||||
|  |      ; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ================     Jiffies   ====================== | ||||||
|  |  */ | ||||||
|  | /*!
 | ||||||
|  |  * Provide jiffy compatible set frequency functionality | ||||||
|  |  * \param jf_freq    The desire frequency | ||||||
|  |  * \param jiffies    The number of steps (jiffies) | ||||||
|  |  * \return     The status of the operation | ||||||
|  |  *    \arg  0  Success | ||||||
|  |  *    \arg  1  Fail | ||||||
|  |  */ | ||||||
|  | int JF_setfreq (uint32_t jf_freq, uint32_t jiffies) { | ||||||
|  |    uint32_t psc=0; | ||||||
|  | 
 | ||||||
|  |    JF_TIMER_CLK_ENABLE(); | ||||||
|  |    SystemCoreClockUpdate (); | ||||||
|  | 
 | ||||||
|  |    if (jf_freq) | ||||||
|  |       psc = SystemCoreClock / jf_freq - 1; | ||||||
|  | 
 | ||||||
|  |    if (psc < 0xFFFF)       JF_TIMER->PSC = psc; | ||||||
|  |    else                    return 1; | ||||||
|  | 
 | ||||||
|  |    if (jiffies < 0xFFFF)   JF_TIMER->ARR = jiffies; | ||||||
|  |    else                    return 1; | ||||||
|  | 
 | ||||||
|  |    JF_TIMER->CR1 |= TIM_CR1_CEN; | ||||||
|  |    return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ======== OS like Functionalities ============ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //! SysTick frequency getter
 | ||||||
|  | __INLINE clock_t get_freq (void) { | ||||||
|  |    return __sys_freq; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //! SysTick frequency setter
 | ||||||
|  | //! \return True on failure
 | ||||||
|  | int set_freq (clock_t sf) { | ||||||
|  |    return HAL_SetSysTickFreq (sf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    determines the processor time. | ||||||
|  |  * \return | ||||||
|  |  *    the implementation's best approximation to the processor time | ||||||
|  |  *    used by the program since program invocation. The time in | ||||||
|  |  *    seconds is the value returned divided by the value of the macro | ||||||
|  |  *    CLK_TCK or CLOCKS_PER_SEC | ||||||
|  |  */ | ||||||
|  | __INLINE clock_t clock (void) { | ||||||
|  |    return (clock_t) __ticks; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Set the processor time used. | ||||||
|  |  * \param   c  The new CPU time value | ||||||
|  |  * \return | ||||||
|  |  *    The implementation's best approximation to the processor time | ||||||
|  |  *    used by the program since program invocation. The time in | ||||||
|  |  *    seconds is the value returned divided by the value of the macro | ||||||
|  |  *    CLK_TCK or CLOCKS_PER_SEC | ||||||
|  |  */ | ||||||
|  | clock_t setclock (clock_t c) { | ||||||
|  |    return __ticks = c; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    determines the current calendar time. The encoding of the value is | ||||||
|  |  *    unspecified. | ||||||
|  |  * \return | ||||||
|  |  *    The implementations best approximation to the current calendar | ||||||
|  |  *    time. If timer is not a null pointer, the return value | ||||||
|  |  *    is also assigned to the object it points to. | ||||||
|  |  */ | ||||||
|  | time_t time (time_t *timer) { | ||||||
|  |    if (timer) | ||||||
|  |       *timer = (time_t)__now; | ||||||
|  |    return (time_t)__now; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Sets the system's idea of the time and date.  The time, | ||||||
|  |  *    pointed to by t, is measured in seconds since the Epoch, 1970-01-01 | ||||||
|  |  *    00:00:00 +0000 (UTC). | ||||||
|  |  * \param   t  Pointer to new system's time and date. | ||||||
|  |  * \return     On success, zero is returned.  On error, -1 is returned | ||||||
|  |  */ | ||||||
|  | int settime (const time_t *t) { | ||||||
|  |    if (t) { | ||||||
|  |       __now = *t; | ||||||
|  |       return 0; | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |       return -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============== Cycle count ============== | ||||||
|  |  */ | ||||||
|  | /*!
 | ||||||
|  |  * Initialize CPU cycle measurement functionality based on DBG | ||||||
|  |  * \return    The status of the operation | ||||||
|  |  *    \arg  LLD_OK      Success | ||||||
|  |  *    \arg  LLD_ERROR   Failure | ||||||
|  |  */ | ||||||
|  | LLD_Status_en CYCLE_Init (void) { | ||||||
|  |    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;    // enable trace
 | ||||||
|  |    //DWT->LAR = 0xC5ACCE55;                 // <-- added unlock access to DWT (ITM, etc.)registers
 | ||||||
|  |    DWT->CYCCNT = 0;                       // clear DWT cycle counter
 | ||||||
|  |    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;   // enable DWT cycle counter
 | ||||||
|  |    return LLD_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //! CPU cycle getter
 | ||||||
|  | __INLINE clock_t CYCLE_Get (void) { | ||||||
|  |    return (clock_t)DWT->CYCCNT; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //! Helper digital input pin getter
 | ||||||
|  | __INLINE uint8_t _DINx (GPIO_TypeDef *port, uint32_t pin) { | ||||||
|  |    return ((port->IDR & pin) != 0) ? 1:0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //! Helper digital output pin setter
 | ||||||
|  | __INLINE uint8_t _DOUTx (GPIO_TypeDef *port, uint32_t pin, uint8_t st) { | ||||||
|  |    if (st) port->BSRR = (uint32_t)pin; | ||||||
|  |    else    port->BSRR = (uint32_t)pin << 16; | ||||||
|  |    return st; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== Digital I/O =============== | ||||||
|  |  * BTN  -- PC13 | ||||||
|  |  * LED  -- PA5 (SB42 is in place) [SB29: PB13] | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Initialize GPIO port pins for Nucleo Board | ||||||
|  |  * \return     The status of the operation | ||||||
|  |  *    \arg  LLD_OK      Success | ||||||
|  |  *    \arg  LLD_ERROR   Failure | ||||||
|  |  */ | ||||||
|  | LLD_Status_en NUCLEO_Port_Init (void) { | ||||||
|  |    GPIO_InitTypeDef  GPIO_InitType; | ||||||
|  | 
 | ||||||
|  |    // Enable Port clock
 | ||||||
|  |    __HAL_RCC_GPIOA_CLK_ENABLE (); | ||||||
|  |    __HAL_RCC_GPIOC_CLK_ENABLE (); | ||||||
|  | 
 | ||||||
|  |    // BTN port configuration
 | ||||||
|  |    GPIO_InitType.Mode  = GPIO_MODE_INPUT; | ||||||
|  |    GPIO_InitType.Pin   = GPIO_PIN_13; | ||||||
|  |    GPIO_InitType.Pull  = GPIO_NOPULL; | ||||||
|  | 
 | ||||||
|  |    HAL_GPIO_Init(GPIOC, &GPIO_InitType); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitType.Mode  = GPIO_MODE_OUTPUT_PP; | ||||||
|  |    GPIO_InitType.Speed = GPIO_SPEED_LOW; | ||||||
|  |    GPIO_InitType.Pin   = GPIO_PIN_5; | ||||||
|  | 
 | ||||||
|  |    HAL_GPIO_Init(GPIOA, &GPIO_InitType); | ||||||
|  | 
 | ||||||
|  |    return LLD_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //! Nucleo's user button reader
 | ||||||
|  | uint8_t NUCLEO_BTN (void) { | ||||||
|  |    return _DINx (GPIOC, GPIO_PIN_13); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //! Nucleo's LD2 led setter
 | ||||||
|  | void NUCLEO_LED (uint8_t on) { | ||||||
|  |    _DOUTx(GPIOA, GPIO_PIN_5, on); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*! Low level driver init functionality
 | ||||||
|  |  * \return     The status of the operation | ||||||
|  |  *    \arg  LLD_OK      Success | ||||||
|  |  *    \arg  LLD_ERROR   Failure | ||||||
|  |  */ | ||||||
|  | LLD_Status_en NUCLEO_Init (clock_t sys_freq) { | ||||||
|  |    HAL_Init(); | ||||||
|  |    HAL_SysTick_Init (sys_freq); | ||||||
|  |    CYCLE_Init (); | ||||||
|  |    NUCLEO_Port_Init (); | ||||||
|  | 
 | ||||||
|  |    return LLD_OK; | ||||||
|  | } | ||||||
							
								
								
									
										156
									
								
								assignment_3/Libraries/drivers/NUCLEO_F401RE.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								assignment_3/Libraries/drivers/NUCLEO_F401RE.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file | ||||||
|  |  *    NUCLEO_F401RE.h | ||||||
|  |  * \brief | ||||||
|  |  *    Nucleo F401RE port file. This file contain the implementation of driver | ||||||
|  |  *    calls for F401RE board. | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef NUCLEO_F401RE_H_ | ||||||
|  | #define NUCLEO_F401RE_H_ | ||||||
|  | 
 | ||||||
|  | #include <stm32f4xx.h> | ||||||
|  | #include <stm32f4xx_hal.h> | ||||||
|  | #include <core_cm4.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========= Data types ======== | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | //! Driver status return type
 | ||||||
|  | typedef enum { | ||||||
|  |    LLD_OK = 0,    //!< Indicate successful operation
 | ||||||
|  |    LLD_ERROR      //!< Indicate Error
 | ||||||
|  | }LLD_Status_en; | ||||||
|  | 
 | ||||||
|  | typedef  uint8_t              din_t; | ||||||
|  | 
 | ||||||
|  | #define  OFF                  (0) | ||||||
|  | #define  ON                   (!OFF) | ||||||
|  | #ifndef  FALSE | ||||||
|  | #define  FALSE                (0) | ||||||
|  | #endif | ||||||
|  | #ifndef  TRUE | ||||||
|  | #define  TRUE                 (!FALSE) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== System =============== | ||||||
|  |  */ | ||||||
|  | #if defined ( __GNUC__ ) && !defined (__CC_ARM) | ||||||
|  | #include <sys/types.h> | ||||||
|  | #endif | ||||||
|  | #include <limits.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Also defined in types.h | ||||||
|  |  */ | ||||||
|  | #ifndef  _CLOCK_T_ | ||||||
|  | #if defined (__CC_ARM) | ||||||
|  |  #define _CLOCK_T_ unsigned int | ||||||
|  | #else | ||||||
|  |  #define  _CLOCK_T_   unsigned long | ||||||
|  | #endif | ||||||
|  | typedef _CLOCK_T_ clock_t;             /*!< CPU time type */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef _TIME_T_ | ||||||
|  | #if defined (__CC_ARM) | ||||||
|  |  #define _TIME_T_ unsigned int | ||||||
|  | #else | ||||||
|  |  #define  _TIME_T_   unsigned long | ||||||
|  | #endif | ||||||
|  | typedef _TIME_T_ time_t;               /*!< date/time in unix secs past 1-Jan-70 type for 68 years*/ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Helper macros | ||||||
|  |  */ | ||||||
|  | #define _CLOCK_T_MAX_VALUE_            (ULONG_MAX) //!< Helper macro for maximum signed CPU time calculations
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  *  Calculate the positive time difference of _t2_ and _t1_, where | ||||||
|  |  *  _t1_, _t2_ are clock_t values | ||||||
|  |  *  \note | ||||||
|  |  *    _t2_ event comes is AFTER _t1_ | ||||||
|  |  * | ||||||
|  |  *  ex: | ||||||
|  |  *  0   1   2   3   4   5   6   7   8   9 | ||||||
|  |  *      ^                       ^ | ||||||
|  |  *      |                       | | ||||||
|  |  *      a                       b | ||||||
|  |  * | ||||||
|  |  * if : t1=a, t2=b      then  dt = b-a             = t2 - t1 | ||||||
|  |  * if : t1=b, t2=a      then  dt = 9 - (b-a) + 1   = UMAX - (t1-t2) + 1 | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #define _CLOCK_DIFF(_t2_, _t1_)     ( ((_t2_)>(_t1_)) ? ((_t2_)-(_t1_)) : (_CLOCK_T_MAX_VALUE_ - ((_t1_) - (_t2_)) + 1) ) | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * CPU time macros | ||||||
|  |  */ | ||||||
|  | #define  msec2CPUtime(_ms_)      (((_ms_) * get_freq()) / 1000) | ||||||
|  | #define  sec2CPUtime(_s_)        ((_s_) * get_freq()) | ||||||
|  | 
 | ||||||
|  | #define  CPUtime2msec(_t_)       (((_t_) * 1000) / get_freq()) | ||||||
|  | #define  CPUtime2sec(_t_)        ((_t_) / get_freq()) | ||||||
|  | 
 | ||||||
|  | HAL_StatusTypeDef HAL_SysTick_Init(clock_t sf); | ||||||
|  | 
 | ||||||
|  | clock_t HAL_SelectSysTickFreq (clock_t sf); | ||||||
|  | clock_t HAL_GetSysTickFreq (void); | ||||||
|  | int HAL_SetSysTickFreq (clock_t sf); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ================     Jiffies   ===================== | ||||||
|  |  */ | ||||||
|  | #define  JF_TIMER             TIM5 | ||||||
|  | #define  JF_TIM_CLOCK_FREQ    (1000000)      //1MHz it's OK
 | ||||||
|  | #define  JF_TIM_VALUE         (JF_TIMER->CNT) | ||||||
|  | #define  JF_TIMER_CLK_ENABLE  __HAL_RCC_TIM5_CLK_ENABLE | ||||||
|  | 
 | ||||||
|  | int JF_setfreq (uint32_t jf_freq, uint32_t jiffies); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * OS like Functionalities | ||||||
|  |  */ | ||||||
|  | clock_t get_freq (void); | ||||||
|  | int set_freq (clock_t sf); | ||||||
|  | 
 | ||||||
|  | clock_t clock (void); | ||||||
|  | clock_t setclock (clock_t c); | ||||||
|  | 
 | ||||||
|  | time_t time (time_t *timer); | ||||||
|  | int settime (const time_t *t); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============== Cycle count ============== | ||||||
|  |  */ | ||||||
|  | LLD_Status_en CYCLE_Init (void); | ||||||
|  | clock_t CYCLE_Get (void); | ||||||
|  | 
 | ||||||
|  | uint8_t _DINx (GPIO_TypeDef *port, uint32_t pin); | ||||||
|  | uint8_t _DOUTx (GPIO_TypeDef *port, uint32_t pin, uint8_t st); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== Digital I/O =============== | ||||||
|  |  * BTN  -- PC13 | ||||||
|  |  * LED  -- PA5 (SB42 is in place) [SB29: PB13] | ||||||
|  |  */ | ||||||
|  | LLD_Status_en NUCLEO_Port_Init (void); | ||||||
|  | 
 | ||||||
|  | uint8_t NUCLEO_BTN (void); | ||||||
|  | void NUCLEO_LED (uint8_t on); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============= Board Init ============== | ||||||
|  |  */ | ||||||
|  | LLD_Status_en NUCLEO_Init (clock_t sys_freq); | ||||||
|  | 
 | ||||||
|  | #endif /* NUCLEO_F401RE_H_ */ | ||||||
							
								
								
									
										495
									
								
								assignment_3/Libraries/drivers/alcd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										495
									
								
								assignment_3/Libraries/drivers/alcd.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,495 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file alcd.c | ||||||
|  |  * \brief | ||||||
|  |  *    A target independent Alpharithmetic LCD driver | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "alcd.h" | ||||||
|  | 
 | ||||||
|  | static  int _inc_x (alcd_t *alcd); | ||||||
|  | static  int _dec_x (alcd_t *alcd); | ||||||
|  | static void _inc_y (alcd_t *alcd); | ||||||
|  | static void _dec_y (alcd_t *alcd); | ||||||
|  | static void _set_bus (alcd_t *alcd, int8_t db); | ||||||
|  | static void _write_data (alcd_t *alcd, int8_t data); | ||||||
|  | static void _command (alcd_t *alcd, uint8_t c); | ||||||
|  | static void _character (alcd_t *alcd, uint8_t c); | ||||||
|  | static void _set_cursor (alcd_t *alcd, uint8_t x, uint8_t y); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    increase cursor's x position. Positions start from 1. | ||||||
|  |  *    If the cursor loops returns 1, else returns 0. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \return        Change line status | ||||||
|  |  */ | ||||||
|  | static int _inc_x (alcd_t *alcd) { | ||||||
|  |    int ret=0; | ||||||
|  | 
 | ||||||
|  |    if (++alcd->c.x > alcd->columns) { | ||||||
|  |       alcd->c.x = 1; | ||||||
|  |       ret = 1; | ||||||
|  |    } | ||||||
|  |    return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Decrease cursor's x position. Positions start from 1. | ||||||
|  |  *    If the cursor loops returns 1, else returns 0. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | static int _dec_x (alcd_t *alcd) { | ||||||
|  |    int ret = 0; | ||||||
|  | 
 | ||||||
|  |    if (--alcd->c.x < 1) { | ||||||
|  |       alcd->c.x = alcd->columns; | ||||||
|  |       ret = 1; | ||||||
|  |    } | ||||||
|  |    return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    increase cursor's y position. Positions start from 1. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | static void _inc_y (alcd_t *alcd) { | ||||||
|  |    if (++alcd->c.y > alcd->lines) { | ||||||
|  |       alcd->c.y = 1; | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Decrease cursor's y position. Positions start from 1. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | static void _dec_y (alcd_t *alcd) { | ||||||
|  |    if (--alcd->c.y < 1) { | ||||||
|  |       alcd->c.y = alcd->lines; | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Update the bus I/O and send it to the device. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  db     the bus data. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | static void _set_bus (alcd_t *alcd, int8_t db) | ||||||
|  | { | ||||||
|  |    alcd->io.db4 (db & 0x01);   //Update port
 | ||||||
|  |    alcd->io.db5 (db & 0x02); | ||||||
|  |    alcd->io.db6 (db & 0x04); | ||||||
|  |    alcd->io.db7 (db & 0x08); | ||||||
|  |    jf_delay_us (10);     // Wait to settle
 | ||||||
|  | 
 | ||||||
|  |    alcd->io.en (1);      // Pulse out the data
 | ||||||
|  |    jf_delay_us (10); | ||||||
|  |    alcd->io.en (0); | ||||||
|  |    jf_delay_us (10);     // Data hold
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Write the byte date to the bus using _set_bus () | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  data   the data byte. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | static void _write_data (alcd_t *alcd, int8_t data) | ||||||
|  | { | ||||||
|  |    _set_bus (alcd, data >> 4); | ||||||
|  |    _set_bus (alcd, data & 0x0F); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Send a command to alcd | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  c      the command byte. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | static void _command (alcd_t *alcd, uint8_t c) | ||||||
|  | { | ||||||
|  |    alcd->io.rs(0);         // Enter command mode
 | ||||||
|  |    jf_delay_us (100);      // Wait
 | ||||||
|  |    _write_data (alcd, c);  // Send
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Send a character to alcd | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  c      the character byte. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | static void _character (alcd_t *alcd, uint8_t c) | ||||||
|  | { | ||||||
|  |    alcd->io.rs(1);         // Enter character mode
 | ||||||
|  |    jf_delay_us (100);      // Wait
 | ||||||
|  |    _write_data (alcd, c);  // Send
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Set the Cursor to LCD's position line (y), column (x) starts from 1,2,...n | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  x      the x position. | ||||||
|  |  * \param  y      the y position. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | static void _set_cursor (alcd_t *alcd, uint8_t x, uint8_t y) | ||||||
|  | { | ||||||
|  |    uint8_t cmd; | ||||||
|  | 
 | ||||||
|  |    alcd->c.x = x;             // Update alcd data
 | ||||||
|  |    alcd->c.y = y; | ||||||
|  | 
 | ||||||
|  |    // Calculate address
 | ||||||
|  |    switch (y) { | ||||||
|  |       default: | ||||||
|  |       case 1: cmd = 0x0;   break; | ||||||
|  |       case 2: cmd = 0x40;  break; | ||||||
|  |       case 3: cmd = 0x0 + alcd->columns;  break; | ||||||
|  |       case 4: cmd = 0x40 + alcd->columns; break; | ||||||
|  |    } | ||||||
|  |    cmd |= (x - 1); | ||||||
|  | 
 | ||||||
|  |    // Calculate command
 | ||||||
|  |    cmd |= LCD_DDRAMMask; | ||||||
|  | 
 | ||||||
|  |    // Command out the alcd
 | ||||||
|  |    _command (alcd, cmd); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============================ Public Functions ============================ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Link and Glue functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Link driver's db4 pin function to io struct. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  pfun   driver's DB4 pin function | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | inline void alcd_link_db4 (alcd_t *alcd, drv_pinout_ft pfun) { alcd->io.db4 = pfun; } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Link driver's db4 pin function to io struct. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  pfun   driver's DB5 pin function | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | inline void alcd_link_db5 (alcd_t *alcd, drv_pinout_ft pfun) { alcd->io.db5 = pfun; } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Link driver's db4 pin function to io struct. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  pfun   driver's DB6 pin function | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | inline void alcd_link_db6 (alcd_t *alcd, drv_pinout_ft pfun) { alcd->io.db6 = pfun; } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Link driver's db4 pin function to io struct. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  pfun   driver's DB7 pin function | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | inline void alcd_link_db7 (alcd_t *alcd, drv_pinout_ft pfun) { alcd->io.db7 = pfun; } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Link driver's db4 pin function to io struct. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  pfun   driver's RS pin function | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | inline void alcd_link_rs (alcd_t *alcd, drv_pinout_ft pfun) { alcd->io.rs = pfun; } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Link driver's db4 pin function to io struct. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  pfun   driver's EN pin function | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | inline void alcd_link_en (alcd_t *alcd, drv_pinout_ft pfun) { alcd->io.en = pfun; } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Link driver's db4 pin function to io struct. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  pfun   driver's BL pin function | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | inline void alcd_link_bl (alcd_t *alcd, drv_pinout_ft pfun) { alcd->io.bl = pfun; } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Send an ascii character to alcd. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  ch     the character to send | ||||||
|  |  * \return the character send. | ||||||
|  |  * | ||||||
|  |  * \note | ||||||
|  |  *    This is the driver's "putchar()" functionality to glue. | ||||||
|  |  *    Tailor this function to redirect stdout to alcd. | ||||||
|  |  */ | ||||||
|  | int alcd_putchar (alcd_t *alcd, int ch) | ||||||
|  | { | ||||||
|  |    alcd->status = DRV_BUSY; | ||||||
|  |    // LCD Character dispatcher
 | ||||||
|  |    switch (ch) { | ||||||
|  |       case 0: | ||||||
|  |          // don't send null termination to device
 | ||||||
|  |          break; | ||||||
|  |       case '\n': | ||||||
|  |          _inc_y (alcd); | ||||||
|  |          //break; This "no break" is intentional
 | ||||||
|  |       case '\r': | ||||||
|  |          _set_cursor (alcd, 1, alcd->c.y); | ||||||
|  |          break; | ||||||
|  |       case '\v': | ||||||
|  |          alcd->c.x = alcd->c.y = 1; | ||||||
|  |          _command (alcd, LCD_RETHOME); | ||||||
|  |          jf_delay_us(2000); | ||||||
|  |          break; | ||||||
|  |       case '\f': | ||||||
|  |          //alcd->c.x = alcd->c.y = 1;
 | ||||||
|  |          _set_cursor (alcd, 1, 1); | ||||||
|  |            //_command (alcd, LCD_CLRSCR);
 | ||||||
|  |            //jf_delay_us(5000);
 | ||||||
|  |          //_command (alcd, LCD_RETHOME);
 | ||||||
|  |            //_set_cursor (alcd, alcd->c.x, alcd->c.y);
 | ||||||
|  |          jf_delay_us(2000); | ||||||
|  |          break; | ||||||
|  |       case '\b': | ||||||
|  |          if (_dec_x (alcd))   _dec_y (alcd); | ||||||
|  |          _set_cursor (alcd, alcd->c.x, alcd->c.y); | ||||||
|  |          _character (alcd, ' '); | ||||||
|  |          _set_cursor (alcd, alcd->c.x, alcd->c.y); | ||||||
|  |          break; | ||||||
|  |       default: | ||||||
|  |          _character (alcd, ch); | ||||||
|  |          // Increase cursor and loop inside the same line
 | ||||||
|  |          if (_inc_x (alcd))   _set_cursor (alcd, alcd->c.x, alcd->c.y); | ||||||
|  |          break; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Restore status
 | ||||||
|  |    alcd->status = DRV_READY; | ||||||
|  | 
 | ||||||
|  |    //ANSI C (C99) compatible mode
 | ||||||
|  |    return ch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Set functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Set the number of lines for the attached lcd display | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  lines  The number of lines (usually 2 or 4) | ||||||
|  |  * \return None. | ||||||
|  |  */ | ||||||
|  | void alcd_set_lines (alcd_t *alcd, int lines) { | ||||||
|  |    alcd->lines = lines; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Set the number of columns for the attached lcd display | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  lines  The number of columns (usually 16 or 20) | ||||||
|  |  * \return None. | ||||||
|  |  */ | ||||||
|  | void alcd_set_columns (alcd_t *alcd, int columns) { | ||||||
|  |    alcd->columns = columns; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * User Functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    De-initialize the alcd. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | void alcd_deinit (alcd_t *alcd) | ||||||
|  | { | ||||||
|  |    memset ((void*)alcd, 0, sizeof (alcd_t)); | ||||||
|  |    /*!<
 | ||||||
|  |     * This leaves the status DRV_NOINIT | ||||||
|  |     */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Initialize the alcd. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \return Zero on success, non zero on error | ||||||
|  |  */ | ||||||
|  | drv_status_en alcd_init (alcd_t *alcd, alcd_funset_en fs) | ||||||
|  | { | ||||||
|  |    #define _lcd_assert(_x)  if (!_x) return alcd->status = DRV_ERROR; | ||||||
|  | 
 | ||||||
|  |    drv_status_en st = jf_probe (); | ||||||
|  | 
 | ||||||
|  |    if (st == DRV_NODEV || st == DRV_BUSY) | ||||||
|  |       return alcd->status = DRV_ERROR; | ||||||
|  |    _lcd_assert (alcd->io.db4); | ||||||
|  |    _lcd_assert (alcd->io.db5); | ||||||
|  |    _lcd_assert (alcd->io.db6); | ||||||
|  |    _lcd_assert (alcd->io.db7); | ||||||
|  |    _lcd_assert (alcd->io.rs); | ||||||
|  |    _lcd_assert (alcd->io.en); | ||||||
|  |    //_lcd_assert (alcd->io.bl);
 | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |     * We are here, so all its OK. We can (re)initialize alcd. | ||||||
|  |     */ | ||||||
|  |    alcd->status = DRV_NOINIT; | ||||||
|  |    alcd->c.x = alcd->c.y = 1; | ||||||
|  |    alcd->io.en (0); | ||||||
|  |    alcd->io.rs (0); | ||||||
|  |    jf_delay_us (100000); | ||||||
|  | 
 | ||||||
|  |    //Pre-Init phase 8bit at this point
 | ||||||
|  |    _set_bus (alcd, 0x3); | ||||||
|  |       jf_delay_us(50000); | ||||||
|  |    _set_bus (alcd, 0x3); | ||||||
|  |       jf_delay_us(5000); | ||||||
|  |    _set_bus (alcd, 0x3); | ||||||
|  |       jf_delay_us(5000); | ||||||
|  | 
 | ||||||
|  |    _set_bus (alcd, 0x2);              //4bit selection
 | ||||||
|  |       jf_delay_us(10000); | ||||||
|  | 
 | ||||||
|  |    _command (alcd, fs);     //4bit selection and Function Set
 | ||||||
|  |       jf_delay_us(5000); | ||||||
|  |    _command (alcd, LCD_DISP_OFF);    //Display Off Control 4bit for now on
 | ||||||
|  |       jf_delay_us(5000); | ||||||
|  |    _command (alcd, LCD_CLRSCR);      //Clear Display
 | ||||||
|  |       jf_delay_us(5000); | ||||||
|  |    _command (alcd, LCD_ENTRYMODE);   //Entry Mode Set
 | ||||||
|  |       jf_delay_us(5000); | ||||||
|  | 
 | ||||||
|  |    _command (alcd, LCD_RETHOME); | ||||||
|  |       jf_delay_us(10000); | ||||||
|  |    _command (alcd, LCD_DISP_ON); | ||||||
|  |       jf_delay_us(5000); | ||||||
|  |    //alcd_backlight (alcd, 1);
 | ||||||
|  |    return alcd->status = DRV_READY; | ||||||
|  | 
 | ||||||
|  |    #undef _lcd_assert | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Enables and disables the lcd backlight. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  on | ||||||
|  |  *    \arg 0      disable the backlight | ||||||
|  |  *    \arg 1      enable the backlight | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | void alcd_backlight (alcd_t *alcd, uint8_t on) { | ||||||
|  |    if (alcd->io.bl) | ||||||
|  |       alcd->io.bl ((on)?1:0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Enables and disables the entire lcd (+backlight). | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  on | ||||||
|  |  *    \arg 0      disable the backlight | ||||||
|  |  *    \arg 1      enable the backlight | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | void alcd_enable (alcd_t *alcd, uint8_t on) | ||||||
|  | { | ||||||
|  |    if (on) { | ||||||
|  |       _command (alcd, LCD_DISP_ON); | ||||||
|  |       alcd_backlight (alcd, 1); | ||||||
|  |    } else { | ||||||
|  |       _command (alcd, LCD_DISP_OFF); | ||||||
|  |       alcd_backlight (alcd, 0); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Clears screen and returns cursor at home position (1,1). | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | void alcd_cls (alcd_t *alcd) | ||||||
|  | { | ||||||
|  |    _command(alcd, LCD_CLRSCR); | ||||||
|  |    jf_delay_us(2000); | ||||||
|  |    _command (alcd, LCD_RETHOME); | ||||||
|  |    jf_delay_us(2000); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Shift alcd left or right for a \a pos characters. | ||||||
|  |  * \param  alcd   pointer to active alcd. | ||||||
|  |  * \param  pos    The number of position to shift. | ||||||
|  |  *    A positive number shifts lcd data to left, so screen shows the data in the right. | ||||||
|  |  *    A negative number shifts lcd data to right, so screen shows the data in the left. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | void alcd_shift (alcd_t *alcd, int pos) | ||||||
|  | { | ||||||
|  |    uint8_t i, cmd = LCD_SHIFT_LEFT; | ||||||
|  | 
 | ||||||
|  |    if (pos<0) { | ||||||
|  |       pos = -pos; | ||||||
|  |       cmd = LCD_SHIFT_RIGHT; | ||||||
|  |    } | ||||||
|  |    for (i=0 ; i<pos ; ++i) { | ||||||
|  |       _command (alcd, cmd); | ||||||
|  |       jf_delay_us(100); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Allows us to fill the first 8 CGRAM locations
 | ||||||
|  | // with custom characters
 | ||||||
|  | void alcd_createChar (alcd_t *alcd, uint8_t location, uint8_t charmap[]) | ||||||
|  | { | ||||||
|  |    location &= 0x7;        // we only have 8 locations 0-7
 | ||||||
|  |    _command (alcd, LCD_SETCGRAMADDR | (location << 3)); | ||||||
|  | 
 | ||||||
|  |    for (int i=0; i<8; i++) { | ||||||
|  |       _character (alcd, charmap[i]); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										177
									
								
								assignment_3/Libraries/drivers/alcd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								assignment_3/Libraries/drivers/alcd.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,177 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file alcd.c | ||||||
|  |  * \brief | ||||||
|  |  *    A target independent Alpharithmetic LCD driver | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef __alcd_h__ | ||||||
|  | #define __alcd_h__ | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include "jiffies.h" | ||||||
|  | #include "driver_types.h" | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <ctype.h> | ||||||
|  | #include <time.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * General Defines | ||||||
|  |  */ | ||||||
|  | #define ALCD_CLOCK       (CLOCK) | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  *  ---------------------------------------------------- | ||||||
|  |  *      Hitachi HD44780 - Samsung KS0066U | ||||||
|  |  *  ---------------------------------------------------- | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  *  Entry Mode Set -----> 0  0  0  0      0  1  I/D  S | ||||||
|  |  *  ---------------------------------------------------- | ||||||
|  |  *  I/D = 1 -->Inciment Curs     I/D = 0 Decriment | ||||||
|  |  *  S = 1 -->Display shift       S = 0 Not | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  *  DispOnOffControll -->  0  0  0  0     1  D  C  B | ||||||
|  |  *  ------------------------------------------------- | ||||||
|  |  *  D = Display On | ||||||
|  |  *  C = Cursor On | ||||||
|  |  *  B = Blinking On | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  *  Cursor/Display Shift --> 0  0  0  1   S/C R/L  x  x | ||||||
|  |  *  --------------------------------------------------- | ||||||
|  |  *  S/C = 1 -->Display Shift  S/C = 0 -->Cursor Shift | ||||||
|  |  *  R/L = 1 -->Shift Right     R/L = 0 -->Shift left | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  *  FunctionSet     ------>  0  0  1 DL   N   F   x  x | ||||||
|  |  *  --------------------------------------------------- | ||||||
|  |  *  DL = 1 -->8bit         DL = 0 -->4bit | ||||||
|  |  *  N = 1 -->2 lines       N = 0 -->1 line | ||||||
|  |  *  F = 1 -->5x10 dots     F = 0 -->5x8 dots | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | //#define LCD_LINES                   (4)
 | ||||||
|  | //#define LCD_ROWS                    (16)
 | ||||||
|  | 
 | ||||||
|  | #define LCD_CLRSCR                  (0x01)      /*!< Clear Srean Command Number */ | ||||||
|  | #define LCD_RETHOME                 (0x02)      /*!< Cursor home Un-Shift display DDRam as is */ | ||||||
|  | 
 | ||||||
|  | #define LCD_ENTRYMODE               (0x06)      /*!< Inc Cursor, Don't shift display */ | ||||||
|  | #define LCD_DISP_ON                 (0x0C)      /*!< No Cursos and Blink */ | ||||||
|  | #define LCD_DISP_OFF                (0x08) | ||||||
|  | #define LCD_CUR_DISP                (0x14)      /*!< Cursor shift right */ | ||||||
|  | #define LCD_FUNSET_2L8              (0x28)      /*!< 4bit, 2lines, 5x8 dots */ | ||||||
|  | #define LCD_FUNSET_1L8              (0x20)      /*!< 4bit, 1lines, 5x8 dots */ | ||||||
|  | #define LCD_FUNSET_1L10             (0x24)      /*!< 4bit, 1lines, 5x10 dots */ | ||||||
|  | 
 | ||||||
|  | #define LCD_SETCGRAMADDR            (0x40) | ||||||
|  | 
 | ||||||
|  | #define LCD_DDRAMMask               (0x80)      /*!< DDRAM ------------> 1   ADD[7..0] */ | ||||||
|  | #define LCD_BFMask                  (0x80)      /*!< IR    ------------> BF   AC[6..0] */ | ||||||
|  | #define LCD_ACMask                  (0x7f)      /*!<    ____________________________| */ | ||||||
|  | 
 | ||||||
|  | #define LCD_SHIFT_RIGHT             (0x1C) | ||||||
|  | #define LCD_SHIFT_LEFT              (0x18) | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |    ALCD_1Line_5x8 = LCD_FUNSET_1L8, | ||||||
|  |    ALCD_1Line_5x10 = LCD_FUNSET_1L10, | ||||||
|  |    ALCD_2Lines_5x8 = LCD_FUNSET_2L8 | ||||||
|  | } alcd_funset_en; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Alpharithmetic LCD Cursor | ||||||
|  |  */ | ||||||
|  | typedef volatile struct | ||||||
|  | { | ||||||
|  |    uint8_t     x; | ||||||
|  |    uint8_t     y; | ||||||
|  | }alcd_cursor_t; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Alpharithmetic LCD Pin assignements. | ||||||
|  |  * Each one can be called xx.DB4(1); or xx.DB4(0); in order to set | ||||||
|  |  * or clear the corresponding pin. | ||||||
|  |  * | ||||||
|  |  * \note These pointers MUST to be assigned from main application. | ||||||
|  |  */ | ||||||
|  | typedef volatile struct | ||||||
|  | { | ||||||
|  |    //drv_pinout_ft  db0;
 | ||||||
|  |    //drv_pinout_ft  db1;
 | ||||||
|  |    //drv_pinout_ft  db2;
 | ||||||
|  |    //drv_pinout_ft  db3;
 | ||||||
|  |    drv_pinout_ft  db4;     /*!< Pointer for DB4 pin */ | ||||||
|  |    drv_pinout_ft  db5;     /*!< Pointer for DB5 pin */ | ||||||
|  |    drv_pinout_ft  db6;     /*!< Pointer for DB6 pin */ | ||||||
|  |    drv_pinout_ft  db7;     /*!< Pointer for DB7 pin */ | ||||||
|  |    drv_pinout_ft  rs;      /*!< Pointer for RS pin */ | ||||||
|  |    drv_pinout_ft  en;      /*!< Pointer for EN pin */ | ||||||
|  |    drv_pinout_ft  bl;      /*!< Pointer for Back Light pin*/ | ||||||
|  | }alcd_io_t; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Alpharithmetic LCD Public Data struct | ||||||
|  |  */ | ||||||
|  | typedef volatile struct | ||||||
|  | { | ||||||
|  |    alcd_io_t      io;      //!< Link to IO struct
 | ||||||
|  |    alcd_cursor_t  c;       //!< Link to Cursor struct
 | ||||||
|  |    uint8_t        lines;   //!< The lines of attached lcd
 | ||||||
|  |    uint8_t        columns; //!< The columns of attached lcd
 | ||||||
|  |    //uint8_t        bus;     //!< Bus length, 4 or 8 bit
 | ||||||
|  |    drv_status_en  status;  //!< alcd driver status
 | ||||||
|  | }alcd_t; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  ============= PUBLIC ALCD API ============= | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Link and Glue functions | ||||||
|  |  */ | ||||||
|  | void alcd_link_db4 (alcd_t *alcd, drv_pinout_ft pfun); | ||||||
|  | void alcd_link_db5 (alcd_t *alcd, drv_pinout_ft pfun); | ||||||
|  | void alcd_link_db6 (alcd_t *alcd, drv_pinout_ft pfun); | ||||||
|  | void alcd_link_db7 (alcd_t *alcd, drv_pinout_ft pfun); | ||||||
|  | void alcd_link_rs (alcd_t *alcd, drv_pinout_ft pfun); | ||||||
|  | void alcd_link_en (alcd_t *alcd, drv_pinout_ft pfun); | ||||||
|  | void alcd_link_bl (alcd_t *alcd, drv_pinout_ft pfun); | ||||||
|  | 
 | ||||||
|  | int alcd_putchar (alcd_t *alcd, int ch); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Set functions | ||||||
|  |  */ | ||||||
|  | void alcd_set_lines (alcd_t *alcd, int lines); | ||||||
|  | void alcd_set_columns (alcd_t *alcd, int columns); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * User Functions | ||||||
|  |  */ | ||||||
|  | void alcd_deinit (alcd_t *alcd);                /*!< For compatibility */ | ||||||
|  | drv_status_en alcd_init (alcd_t *alcd, alcd_funset_en fs);         /*!< For compatibility */ | ||||||
|  | 
 | ||||||
|  | void alcd_backlight (alcd_t *alcd, uint8_t on); /*!< For compatibility */ | ||||||
|  | void alcd_enable (alcd_t *alcd, uint8_t on);    /*!< For compatibility */ | ||||||
|  | void alcd_cls (alcd_t *alcd);                   /*!< For compatibility */ | ||||||
|  | void alcd_shift (alcd_t *alcd, int pos);        /*!< For compatibility */ | ||||||
|  | void alcd_createChar (alcd_t *alcd, uint8_t location, uint8_t charmap[]); | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif //#ifndef __alcd_h__
 | ||||||
							
								
								
									
										211
									
								
								assignment_3/Libraries/drivers/deque08.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								assignment_3/Libraries/drivers/deque08.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,211 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file deque08.c | ||||||
|  |  * \brief | ||||||
|  |  *    This file provides double ended queue capability based on a ring buffer | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #include "deque08.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  ============= Private Queue API ============= | ||||||
|  |  */ | ||||||
|  | static iterator_t _preInc(deque08_t *q, iterator_t* it) { | ||||||
|  |    return (++*it >= q->capacity) ? *it=0 : *it; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static iterator_t _preDec(deque08_t *q, iterator_t* it) { | ||||||
|  |    return (--*it < 0) ? *it=q->capacity-1 : *it; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static iterator_t _postInc(deque08_t *q, iterator_t* it) { | ||||||
|  |    iterator_t ret = *it; | ||||||
|  |    if (++*it >= q->capacity) *it=0; | ||||||
|  |    return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static iterator_t _postDec(deque08_t *q, iterator_t* it) { | ||||||
|  |    iterator_t ret = *it; | ||||||
|  |    if (--*it < 0) *it=q->capacity-1; | ||||||
|  |    return ret; | ||||||
|  | } | ||||||
|  | /*
 | ||||||
|  |  *  ============= Public Queue API ============= | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Link and Glue functions | ||||||
|  |  */ | ||||||
|  | void deque08_link_buffer (deque08_t *q, byte_t* buf) { | ||||||
|  |    q->m = buf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Set functions | ||||||
|  |  */ | ||||||
|  | inline void deque08_set_capacity (deque08_t *q, size_t capacity) { | ||||||
|  |    q->capacity = capacity; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * User Functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Check if deque is full | ||||||
|  |  * \param   q     Which deque to check | ||||||
|  |  * \return | ||||||
|  |  *    \arg  0     Not full | ||||||
|  |  *    \arg  1     Full | ||||||
|  |  */ | ||||||
|  | int deque08_is_full (deque08_t *q) { | ||||||
|  |    return (q->items == q->capacity) ? 1:0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Check if deque is empty | ||||||
|  |  * \param   q     Which deque to check | ||||||
|  |  * \return | ||||||
|  |  *    \arg  0     Not empty | ||||||
|  |  *    \arg  1     Empty | ||||||
|  |  */ | ||||||
|  | int deque08_is_empty (deque08_t *q) { | ||||||
|  |    return (q->items) ? 0:1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Return the number of items on deque | ||||||
|  |  * \param   q     Which deque to check | ||||||
|  |  */ | ||||||
|  | int  deque08_size (deque08_t *q) { | ||||||
|  |    return q->items; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Discard all items in deque | ||||||
|  |  * \param   q     Which deque to check | ||||||
|  |  */ | ||||||
|  | void  deque08_flush (deque08_t *q) { | ||||||
|  |    deque08_init(q); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Initialize the queue | ||||||
|  |  * \param   queue    Which queue to init | ||||||
|  |  */ | ||||||
|  | void deque08_init (deque08_t *q) { | ||||||
|  |    q->f = 0; | ||||||
|  |    q->r = -1; | ||||||
|  |    q->items =0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |   * \brief | ||||||
|  |   *   This function push a byte in front of deque. | ||||||
|  |   * \param  q  Pointer to deque to use | ||||||
|  |   * \param  b  byte to push | ||||||
|  |   * \return | ||||||
|  |   *   \arg  0  Full queue | ||||||
|  |   *   \arg  1  Done | ||||||
|  |  */ | ||||||
|  | int deque08_push_front (deque08_t *q, byte_t b) { | ||||||
|  |    if (deque08_is_full (q) == 1)  //full queue
 | ||||||
|  |       return 0; | ||||||
|  |    q->m [_preDec (q, &q->f)] = b; | ||||||
|  |    ++q->items; | ||||||
|  |    return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |   * \brief | ||||||
|  |   *   This function pops a byte from the front of the deque. | ||||||
|  |   * \param  q  Pointer to deque to use | ||||||
|  |   * \param  b  Pointer to byte to return | ||||||
|  |   * \return | ||||||
|  |   *   \arg  0  Empty queue | ||||||
|  |   *   \arg  1  Done | ||||||
|  |  */ | ||||||
|  | int deque08_pop_front (deque08_t *q, byte_t *b) { | ||||||
|  |    if (deque08_is_empty (q) == 1)  //empty queue
 | ||||||
|  |       return 0; | ||||||
|  |    *b = q->m [_postInc (q, &q->f)]; | ||||||
|  |    --q->items; | ||||||
|  |    return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |   * \brief | ||||||
|  |   *   This function push a byte in the back of deque. | ||||||
|  |   * \param  q  Pointer to deque to use | ||||||
|  |   * \param  b  byte to push | ||||||
|  |   * \return | ||||||
|  |   *   \arg  0  Full queue | ||||||
|  |   *   \arg  1  Done | ||||||
|  |  */ | ||||||
|  | int deque08_push_back (deque08_t *q, byte_t b) { | ||||||
|  |    if (deque08_is_full (q) == 1)  //full queue
 | ||||||
|  |       return 0; | ||||||
|  |    q->m [_preInc (q, &q->r)] = b; | ||||||
|  |    ++q->items; | ||||||
|  |    return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |   * \brief | ||||||
|  |   *   This function pops a byte from the back of the deque. | ||||||
|  |   * \param  q  Pointer to deque to use | ||||||
|  |   * \param  b  Pointer to byte to return | ||||||
|  |   * \return | ||||||
|  |   *   \arg  0  Empty queue | ||||||
|  |   *   \arg  1  Done | ||||||
|  |  */ | ||||||
|  | int deque08_pop_back (deque08_t *q, byte_t *b) { | ||||||
|  |    if (deque08_is_empty (q) == 1)  //empty queue
 | ||||||
|  |       return 0; | ||||||
|  |    *b = q->m [_postDec (q, &q->r)]; | ||||||
|  |    --q->items; | ||||||
|  |    return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |   * \brief | ||||||
|  |   *   This function gives the last item in the back of deque. | ||||||
|  |   * \param  q  Pointer to deque to use | ||||||
|  |   * \param  b  Pointer to byte to return | ||||||
|  |   * \return | ||||||
|  |   *   \arg  0  Empty queue | ||||||
|  |   *   \arg  1  Done | ||||||
|  |  */ | ||||||
|  | int deque08_back (deque08_t *q, byte_t *b) { | ||||||
|  |    if (deque08_is_empty (q) == 1)  //empty queue
 | ||||||
|  |       return 0; | ||||||
|  |    *b = q->m [q->r]; | ||||||
|  |    return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |   * \brief | ||||||
|  |   *   This function gives the first item in the front of deque. | ||||||
|  |   * \param  q  Pointer to deque to use | ||||||
|  |   * \param  b  Pointer to byte to return | ||||||
|  |   * \return | ||||||
|  |   *   \arg  0  Empty queue | ||||||
|  |   *   \arg  1  Done | ||||||
|  |  */ | ||||||
|  | int deque08_front (deque08_t *q, byte_t *b) { | ||||||
|  |    if (deque08_is_empty (q) == 1)  //empty queue
 | ||||||
|  |       return 0; | ||||||
|  |    *b = q->m [q->f]; | ||||||
|  |    return 1; | ||||||
|  | } | ||||||
							
								
								
									
										65
									
								
								assignment_3/Libraries/drivers/deque08.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								assignment_3/Libraries/drivers/deque08.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file deque08.h | ||||||
|  |  * \brief | ||||||
|  |  *    This file provides double ended queue capability based on a ring buffer | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #ifndef  __deque08_h__ | ||||||
|  | #define  __deque08_h__ | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include "driver_types.h" | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |    byte_t      *m;         /*!< pointer to queue's buffer */ | ||||||
|  |    iterator_t  capacity;   /*!< queue's max item capacity */ | ||||||
|  |    iterator_t  items;      /*!< current item count */ | ||||||
|  |    iterator_t  f, r;       /*!< queue iterators */ | ||||||
|  | }deque08_t; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  ============= PUBLIC EE API ============= | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Link and Glue functions | ||||||
|  |  */ | ||||||
|  | void deque08_link_buffer (deque08_t *q, byte_t* buf); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Set functions | ||||||
|  |  */ | ||||||
|  | void deque08_set_capacity (deque08_t *q, size_t capacity); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * User Functions | ||||||
|  |  */ | ||||||
|  | int  deque08_is_full (deque08_t *q); | ||||||
|  | int  deque08_is_empty (deque08_t *q); | ||||||
|  | int  deque08_size  (deque08_t *q); | ||||||
|  | void deque08_flush (deque08_t *q); | ||||||
|  | 
 | ||||||
|  | void deque08_init (deque08_t *q); | ||||||
|  | int  deque08_push_front (deque08_t *q, byte_t b); | ||||||
|  | int  deque08_pop_front (deque08_t *q, byte_t *b); | ||||||
|  | int  deque08_push_back (deque08_t *q, byte_t b); | ||||||
|  | int  deque08_pop_back (deque08_t *q, byte_t *b); | ||||||
|  | 
 | ||||||
|  | int  deque08_back (deque08_t *q, byte_t *b); | ||||||
|  | int  deque08_front (deque08_t *q, byte_t *b); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif //#ifndef  __deque08_h__
 | ||||||
							
								
								
									
										64
									
								
								assignment_3/Libraries/drivers/driver_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								assignment_3/Libraries/drivers/driver_types.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file driver_types.h | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef DRIVERS_DRIVER_TYPES_H_ | ||||||
|  | #define DRIVERS_DRIVER_TYPES_H_ | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | typedef uint8_t  byte_t;         /*!< 8 bits wide */ | ||||||
|  | typedef uint16_t word_t;         /*!< 16 bits wide */ | ||||||
|  | typedef uint32_t dword_t;        /*!< 32 bits wide */ | ||||||
|  | 
 | ||||||
|  | typedef int32_t  iterator_t;     /*!< general iterator type */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * This is a driver wide generic driver status type. | ||||||
|  |  * \note | ||||||
|  |  *    DRV_NOINIT = 0, so after memset to zero called by XXXX_deinit() the | ||||||
|  |  *    module/device will automatically set to NOINIT state. | ||||||
|  |  */ | ||||||
|  | typedef enum { | ||||||
|  |    DRV_NODEV=-1,     /*!< No device/module */                      //!< DRV_NODEV
 | ||||||
|  |    DRV_NOINIT=0,     /*!< Module/Device exist but no initialized *///!< DRV_NOINIT
 | ||||||
|  |    DRV_READY,        /*!< Module/Device initialized succesfully */ //!< DRV_READY
 | ||||||
|  |    DRV_BUSY,         /*!< Module/Device busy */                    //!< DRV_BUSY
 | ||||||
|  |    //DRV_COMPLETE,     /*!< Module/device operation complete status */
 | ||||||
|  |    DRV_ERROR         /*!< Module/Device error */                   //!< DRV_ERROR
 | ||||||
|  | }drv_status_en; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |    drv_pin_disable = 0, | ||||||
|  |    drv_pin_input, | ||||||
|  |    drv_pin_output | ||||||
|  | }drv_pin_dir_en; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Pin function pointers | ||||||
|  |  * \note | ||||||
|  |  *    These function pointers do not correspond to pin levels. | ||||||
|  |  *    They correspond to the enable/disable functionality of that pin. | ||||||
|  |  */ | ||||||
|  | //! @{
 | ||||||
|  | typedef uint8_t (*drv_pinin_ft)  (void); | ||||||
|  | typedef    void (*drv_pinout_ft) (uint8_t); | ||||||
|  | typedef uint8_t (*drv_pinio_ft)  (uint8_t); | ||||||
|  | typedef    void (*drv_pindir_ft) (drv_pin_dir_en); | ||||||
|  | //! @}
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* DRIVERS_DRIVER_TYPES_H_ */ | ||||||
							
								
								
									
										221
									
								
								assignment_3/Libraries/drivers/hal.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								assignment_3/Libraries/drivers/hal.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,221 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file hal.c | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #include "hal.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Public data types / classes | ||||||
|  |  */ | ||||||
|  | alcd_t     alcd; | ||||||
|  | ow_uart_t  ow; | ||||||
|  | 
 | ||||||
|  | proximity_t    prox; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Initialize all hardware | ||||||
|  |  */ | ||||||
|  | int hal_hw_init (void) { | ||||||
|  |    // Init base board
 | ||||||
|  |    NUCLEO_Init(1000); | ||||||
|  |    SHIELD_Init (); | ||||||
|  | 
 | ||||||
|  |    // Start Jiffy functionality
 | ||||||
|  |    jf_link_setfreq (JF_setfreq); | ||||||
|  |    jf_link_value ((jiffy_t*)&JF_TIM_VALUE); | ||||||
|  |    jf_init (JF_TIM_CLOCK_FREQ, 1000); | ||||||
|  | 
 | ||||||
|  |    return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========== LCD =========== | ||||||
|  |  */ | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Initialize the lcd data. Not the LCD module | ||||||
|  |  */ | ||||||
|  | void lcd_init (void) { | ||||||
|  |    alcd_link_db4 (&alcd, SHIELD_LCD_DB4); | ||||||
|  |    alcd_link_db5 (&alcd, SHIELD_LCD_DB5); | ||||||
|  |    alcd_link_db6 (&alcd, SHIELD_LCD_DB6); | ||||||
|  |    alcd_link_db7 (&alcd, SHIELD_LCD_DB7); | ||||||
|  |    alcd_link_rs (&alcd, SHIELD_LCD_RS); | ||||||
|  |    alcd_link_en (&alcd, SHIELD_LCD_EN); | ||||||
|  |    alcd_link_bl (&alcd, SHIELD_LCD_BL); | ||||||
|  | 
 | ||||||
|  |    alcd_set_lines (&alcd, 2); | ||||||
|  |    alcd_set_columns (&alcd, 16); | ||||||
|  | 
 | ||||||
|  |    alcd_init (&alcd, (alcd_funset_en)LCD_FUNSET_2L8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //! lcd enable wrapper
 | ||||||
|  | __INLINE void lcd_enable (uint8_t en) { | ||||||
|  |    alcd_enable(&alcd, en); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //!< lcd putchar wrapper
 | ||||||
|  | __INLINE int lcd_putchar (char c) { | ||||||
|  |    return alcd_putchar(&alcd, c); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //! lcd puts wrapper
 | ||||||
|  | int lcd_puts (const char *s) { | ||||||
|  |    int i =0; | ||||||
|  |    while (alcd_putchar(&alcd, *s++)) | ||||||
|  |       ++i; | ||||||
|  |    return i; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========== Led interface ========== | ||||||
|  |  */ | ||||||
|  | __INLINE void led_red (uint8_t en) { LED_RED (en); } | ||||||
|  | __INLINE void led_green (uint8_t en) { LED_GREEN (en); } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========= Relay =========== | ||||||
|  |  */ | ||||||
|  | /*!
 | ||||||
|  |  * Create pulses to re-state reay coil | ||||||
|  |  */ | ||||||
|  | void relay (uint8_t on) { | ||||||
|  |    switch (on) { | ||||||
|  |       case 0: | ||||||
|  |          SHIELD_BR1(1); | ||||||
|  |          HAL_Delay(100); | ||||||
|  |          SHIELD_BR1(0); | ||||||
|  |          break; | ||||||
|  |       default: | ||||||
|  |          SHIELD_BR2(1); | ||||||
|  |          HAL_Delay(100); | ||||||
|  |          SHIELD_BR2(0); | ||||||
|  |          break; | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========= Temperature =========== | ||||||
|  |  */ | ||||||
|  | uint8_t ds18b20_rom[8]; | ||||||
|  | uint8_t zero_rom[8] = {0}; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Initialize temperature measurement system | ||||||
|  |  */ | ||||||
|  | int temp_init (uint8_t resolution) { | ||||||
|  |    if (!IS_TEMP_RESOLUTION(resolution)) | ||||||
|  |       return 1; | ||||||
|  | 
 | ||||||
|  |    // link with hardware
 | ||||||
|  |    ow_uart_link_rw (&ow, (ow_uart_rw_ft)SHIELD_1W_RW); | ||||||
|  |    ow_uart_link_br (&ow, (ow_uart_br_ft)SHIELD_1W_UART_BR); | ||||||
|  |    ow_uart_set_timing (&ow, OW_UART_T_STANDARD); | ||||||
|  | 
 | ||||||
|  |    ow_uart_init (&ow);              // init
 | ||||||
|  |    ow_uart_search(&ow, ds18b20_rom);// do a search
 | ||||||
|  | 
 | ||||||
|  |    if (!memcmp ((const void*)ds18b20_rom, (const void*)zero_rom, 8)) | ||||||
|  |       return 1;                     // if there is no DS18b20 error
 | ||||||
|  | 
 | ||||||
|  |    // set resolution to 9-bit
 | ||||||
|  |    ow_uart_reset(&ow); | ||||||
|  |    ow_uart_tx (&ow, SKIPROM);       // Skip rom
 | ||||||
|  |    ow_uart_tx (&ow, WRITESCRATCH);  // write scratchpad
 | ||||||
|  |    ow_uart_tx (&ow, (byte_t)127);   // Th
 | ||||||
|  |    ow_uart_tx (&ow, (byte_t)-128);  // Tl
 | ||||||
|  |    ow_uart_tx (&ow, resolution);    // Configuration 9 bit
 | ||||||
|  |    HAL_Delay(100); | ||||||
|  |    return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Temperature read functionality | ||||||
|  |  */ | ||||||
|  | float temp_read (void) { | ||||||
|  |    uint8_t t[2]; | ||||||
|  | 
 | ||||||
|  |    ow_uart_reset(&ow); | ||||||
|  |    ow_uart_tx (&ow, SKIPROM);       // Skip rom
 | ||||||
|  |    ow_uart_tx (&ow, STARTCONV);     // convert temperature
 | ||||||
|  |    while (ow_uart_rx(&ow) == 0)     // Wait for slave to free the bus
 | ||||||
|  |       ; | ||||||
|  |    //HAL_Delay (100);
 | ||||||
|  |    ow_uart_reset(&ow); | ||||||
|  |    ow_uart_tx (&ow, SKIPROM);       // Skip rom
 | ||||||
|  |    ow_uart_tx (&ow, READSCRATCH);   // read scratchpad
 | ||||||
|  | 
 | ||||||
|  |    t[0] = ow_uart_rx(&ow);          // LSB
 | ||||||
|  |    t[1] = ow_uart_rx(&ow);          // MSB
 | ||||||
|  |    ow_uart_reset(&ow); | ||||||
|  | 
 | ||||||
|  |    t[1] <<= 4; | ||||||
|  |    t[1] |= (t[0] >> 4); | ||||||
|  |    t[0] &= 0x0F; | ||||||
|  |    return t[1] + t[0]/16.0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========= Proximity =========== | ||||||
|  |  */ | ||||||
|  | /*!
 | ||||||
|  |  * Initialize proximity system | ||||||
|  |  * \param p    Which proximity object to initialize | ||||||
|  |  */ | ||||||
|  | void proximity_init (proximity_t* p){ | ||||||
|  |    for (int i =0 ; i<PROX_READINGS ; ++i) | ||||||
|  |       proximity(p); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Read proximity value in [cm] | ||||||
|  |  * \note | ||||||
|  |  *    This function also implements an embedded averaging filter | ||||||
|  |  * @param p    Which proximity object to use | ||||||
|  |  * @return     The measured distance | ||||||
|  |  */ | ||||||
|  | float_t proximity (proximity_t* p){ | ||||||
|  |    float_t ret; | ||||||
|  |    clock_t t1, t2, mark; | ||||||
|  | 
 | ||||||
|  |    SHIELD_TRIG(1);      // send pulse and mark cycles
 | ||||||
|  |    jf_delay_us(10); | ||||||
|  |    SHIELD_TRIG(0); | ||||||
|  |    // wait for response with timeout
 | ||||||
|  |    mark = clock(); | ||||||
|  |    do { | ||||||
|  |       t1 = CYCLE_Get(); | ||||||
|  |       if (clock() - mark >= PROX_TIME_MAX) | ||||||
|  |          return -1; | ||||||
|  |    } while (!SHIELD_ECHO()); | ||||||
|  | 
 | ||||||
|  |    mark = clock(); | ||||||
|  |    do { | ||||||
|  |       t2 = CYCLE_Get(); | ||||||
|  |       if (clock() - mark >= PROX_TIME_MAX) | ||||||
|  |          return -1; | ||||||
|  |    } while  (SHIELD_ECHO()); | ||||||
|  | 
 | ||||||
|  |    // Calculate distance
 | ||||||
|  |    SystemCoreClockUpdate(); | ||||||
|  |    uint32_t c_usec = SystemCoreClock / 1000000; | ||||||
|  |    // Load value
 | ||||||
|  |    p->readings[p->iter++] = (c_usec) ? ((t2 - t1)/c_usec) / 58.2 : PROX_MAX_DISTANSE; | ||||||
|  |    p->iter %= PROX_READINGS; | ||||||
|  | 
 | ||||||
|  |    // Return filtered distance (moving average filter FIR)
 | ||||||
|  |    ret =0; | ||||||
|  |    for (int i=0 ; i<PROX_READINGS ; ++i) | ||||||
|  |       ret += p->readings[i]; | ||||||
|  |    return ret/PROX_READINGS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										97
									
								
								assignment_3/Libraries/drivers/hal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								assignment_3/Libraries/drivers/hal.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,97 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file hal.h | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #ifndef DRIVERS_HAL_H_ | ||||||
|  | #define DRIVERS_HAL_H_ | ||||||
|  | 
 | ||||||
|  | #include <thermostat_shield.h> | ||||||
|  | #include <alcd.h> | ||||||
|  | #include <jiffies.h> | ||||||
|  | #include <onewire_uart.h> | ||||||
|  | #include <deque08.h> | ||||||
|  | #include <thermostat.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int hal_hw_init (void); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========== LCD =========== | ||||||
|  |  */ | ||||||
|  | void lcd_init (void); | ||||||
|  | void lcd_enable (uint8_t en) ; | ||||||
|  | int lcd_putchar (char c); | ||||||
|  | int lcd_puts (const char *s); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========== Led interface ========== | ||||||
|  |  */ | ||||||
|  | void led_red (uint8_t en); | ||||||
|  | void led_green (uint8_t en); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========= Relay =========== | ||||||
|  |  */ | ||||||
|  | void relay(uint8_t on); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========= Temperature =========== | ||||||
|  |  */ | ||||||
|  | // OneWire commands
 | ||||||
|  | #define SKIPROM         0xCC  // Skip ROM matching transition
 | ||||||
|  | #define STARTCONV       0x44  // Tells device to take a temperature reading and put it on the scratchpad
 | ||||||
|  | #define COPYSCRATCH     0x48  // Copy EEPROM
 | ||||||
|  | #define READSCRATCH     0xBE  // Read EEPROM
 | ||||||
|  | #define WRITESCRATCH    0x4E  // Write to EEPROM
 | ||||||
|  | #define RECALLSCRATCH   0xB8  // Reload from last known
 | ||||||
|  | #define READPOWERSUPPLY 0xB4  // Determine if device needs parasite power
 | ||||||
|  | #define ALARMSEARCH     0xEC  // Query bus for devices with an alarm condition
 | ||||||
|  | 
 | ||||||
|  | // Device resolution
 | ||||||
|  | #define TEMP_9_BIT  0x1F //  9 bit
 | ||||||
|  | #define TEMP_10_BIT 0x3F // 10 bit
 | ||||||
|  | #define TEMP_11_BIT 0x5F // 11 bit
 | ||||||
|  | #define TEMP_12_BIT 0x7F // 12 bit
 | ||||||
|  | #define IS_TEMP_RESOLUTION(x) \ | ||||||
|  |    ((x == TEMP_9_BIT) || (x == TEMP_10_BIT) || (x == TEMP_11_BIT) || (x == TEMP_12_BIT)) | ||||||
|  | 
 | ||||||
|  | int temp_init (uint8_t resolution); | ||||||
|  | float temp_read (void); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========= Proximity =========== | ||||||
|  |  */ | ||||||
|  | #define PROX_TIME_MAX      25    // [msec]
 | ||||||
|  | #define PROX_READINGS      7     // How many readings for averaging
 | ||||||
|  | #define PROX_MAX_DISTANSE  450   // [cm]
 | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |    float_t  readings[7]; | ||||||
|  |    int      iter; | ||||||
|  | } proximity_t; | ||||||
|  | 
 | ||||||
|  | void proximity_init (proximity_t* p); | ||||||
|  | float_t proximity (proximity_t* p); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Public data types / classes | ||||||
|  |  */ | ||||||
|  | extern alcd_t        alcd; | ||||||
|  | extern ow_uart_t     ow; | ||||||
|  | extern proximity_t   prox; | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* DRIVERS_HAL_H_ */ | ||||||
							
								
								
									
										355
									
								
								assignment_3/Libraries/drivers/jiffies.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										355
									
								
								assignment_3/Libraries/drivers/jiffies.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,355 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file jiffies.c | ||||||
|  |  * \brief | ||||||
|  |  *    A target independent jiffy functionality | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #include "jiffies.h" | ||||||
|  | 
 | ||||||
|  | static jf_t _jf; | ||||||
|  | 
 | ||||||
|  | #define JF_MAX_TIM_VALUE      (0xFFFF)    // 16bit counters
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ======================   Public functions   ====================== | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Link and Glue functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Connect the Driver's Set frequency function to jiffy struct | ||||||
|  |  * \note | ||||||
|  |  *    This function get a freq value and returns the timers max jiffy value | ||||||
|  |  *    (usual this refers to timer'sauto reload value). | ||||||
|  |  */ | ||||||
|  | void jf_link_setfreq (jf_setfreq_pt pfun) { | ||||||
|  |    _jf.setfreq = (pfun != 0) ? pfun : 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Connect the timer's value to jiffy struct | ||||||
|  |  */ | ||||||
|  | void jf_link_value (jiffy_t* v) { | ||||||
|  |    _jf.value = (v != 0) ? v : 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * User Functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Check jiffy's status | ||||||
|  |  * \return status | ||||||
|  |  */ | ||||||
|  | inline drv_status_en jf_probe (void) { | ||||||
|  |    return _jf.status; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    De-Initialize the jf data and un-connect the functions | ||||||
|  |  *    from the driver | ||||||
|  |  */ | ||||||
|  | void jf_deinit (void) | ||||||
|  | { | ||||||
|  |    if (_jf.setfreq) _jf.setfreq (0, 0); | ||||||
|  |    memset ((void*)&_jf, 0, sizeof (jf_t)); | ||||||
|  |    _jf.status = DRV_NODEV; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Initialize the jf to a desired jiffy frequency | ||||||
|  |  * \note | ||||||
|  |  *    This function has no effect if the inner jiffy struct | ||||||
|  |  *    is un-connected to driver. So you have to call | ||||||
|  |  *    \sa jf_connect_setfreq() and \sa jf_connect_value() first. | ||||||
|  |  * \return The status of the operation | ||||||
|  |  *    \arg  DRV_ERROR   If the init process fail | ||||||
|  |  *    \arg  DRV_NODEV   If there is no linked jiffy HW, no setfreq function | ||||||
|  |  *    \arg  DRV_READY   Success | ||||||
|  |  */ | ||||||
|  | drv_status_en jf_init (uint32_t jf_freq, jiffy_t jiffies) | ||||||
|  | { | ||||||
|  |    if (_jf.setfreq) { | ||||||
|  |       _jf.status = DRV_NOINIT; | ||||||
|  |       if ( _jf.setfreq (jf_freq, jiffies) ) | ||||||
|  |          return DRV_ERROR; | ||||||
|  |       _jf.jiffies = jiffies; | ||||||
|  |       _jf.freq = jf_freq; | ||||||
|  |       _jf.jp1ms = jf_per_msec (); | ||||||
|  |       _jf.jp1us = jf_per_usec (); | ||||||
|  |       _jf.jp100ns = jf_per_100nsec (); | ||||||
|  |       return _jf.status = DRV_READY; | ||||||
|  |    } | ||||||
|  |    return _jf.status = DRV_NODEV; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Return the maximum jiffy value. | ||||||
|  |  */ | ||||||
|  | jiffy_t jf_get_jiffies (void){ | ||||||
|  |    return _jf.jiffies; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Return the current jiffy value. | ||||||
|  |  * \note | ||||||
|  |  *    Usual this function returns the value of a register from a timer peripheral | ||||||
|  |  *    in the MCU. Keep in mind that its value is a moving target! | ||||||
|  |  */ | ||||||
|  | jiffy_t jf_get_jiffy (void){ | ||||||
|  |    return *_jf.value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Return the systems best approximation for jiffies per msec | ||||||
|  |  * \return | ||||||
|  |  *    The calculated value or zero if no calculation can apply | ||||||
|  |  * | ||||||
|  |  * \note | ||||||
|  |  *    The result tend to differ as the jiffies and freq values decreasing | ||||||
|  |  */ | ||||||
|  | jiffy_t jf_per_msec (void) | ||||||
|  | { | ||||||
|  |    jiffy_t jf = (jiffy_t)(_jf.freq / 1000); | ||||||
|  |    /*            1
 | ||||||
|  |     * 1000Hz = -----  , Its not a magic number | ||||||
|  |     *          1msec | ||||||
|  |     */ | ||||||
|  |    if (jf <= 1)      return 1; | ||||||
|  |    else              return jf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Return the systems best approximation for jiffies per usec | ||||||
|  |  * \return | ||||||
|  |  *    The calculated value or zero if no calculation can apply | ||||||
|  |  * | ||||||
|  |  * \note | ||||||
|  |  *    The result tend to differ as the jiffies and freq values decreasing | ||||||
|  |  */ | ||||||
|  | jiffy_t jf_per_usec (void) | ||||||
|  | { | ||||||
|  |    jiffy_t jf = (jiffy_t)(_jf.freq / 1000000); | ||||||
|  |    /*                1
 | ||||||
|  |     * 1000000Hz = ------  , Its not a magic number | ||||||
|  |     *             1usec | ||||||
|  |     */ | ||||||
|  |    if (jf <= 1)      return 1; | ||||||
|  |    else              return jf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Return the systems best approximation for jiffies per usec | ||||||
|  |  * \return | ||||||
|  |  *    The calculated value or zero if no calculation can apply | ||||||
|  |  * | ||||||
|  |  * \note | ||||||
|  |  *    The result tend to differ as the jiffies and freq values decreasing | ||||||
|  |  */ | ||||||
|  | jiffy_t jf_per_100nsec (void) | ||||||
|  | { | ||||||
|  |    jiffy_t jf = (jiffy_t)(_jf.freq / 10000000); | ||||||
|  |    /*                 1
 | ||||||
|  |     * 10000000Hz = -------  , Its not a magic number | ||||||
|  |     *              100nsec | ||||||
|  |     */ | ||||||
|  |    if (jf <= 1)      return 1; | ||||||
|  |    else              return jf; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    A code based delay implementation, using jiffies for timing. | ||||||
|  |  *    This is NOT accurate but it ensures that the time passed is always | ||||||
|  |  *    more than the requested value. | ||||||
|  |  *    The delay values are multiplications of 1 msec. | ||||||
|  |  * \param   msec     Time in msec for delay | ||||||
|  |  */ | ||||||
|  | void jf_delay_ms (jtime_t msec) | ||||||
|  | { | ||||||
|  |    jtime_t m, m2, m1 = (jtime_t)*_jf.value; | ||||||
|  | 
 | ||||||
|  |    msec *= _jf.jp1ms; | ||||||
|  | 
 | ||||||
|  |    // Eat the time difference from msec value.
 | ||||||
|  |    do { | ||||||
|  |       m2 = (jtime_t)(*_jf.value); | ||||||
|  |       m = m2 - m1; | ||||||
|  |       msec -= (m>=0) ? m : _jf.jiffies + m; | ||||||
|  |       m1 = m2; | ||||||
|  |    } while (msec>0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    A code based delay implementation, using jiffies for timing. | ||||||
|  |  *    This is NOT accurate but it ensures that the time passed is always | ||||||
|  |  *    more than the requested value. | ||||||
|  |  *    The delay values are multiplications of 1 usec. | ||||||
|  |  * \param   usec     Time in usec for delay | ||||||
|  |  */ | ||||||
|  | void jf_delay_us (jtime_t usec) | ||||||
|  | { | ||||||
|  |    jtime_t m, m2, m1 = (jtime_t)*_jf.value; | ||||||
|  | 
 | ||||||
|  |    usec *= _jf.jp1us; | ||||||
|  |    if ((jtime_t)(*_jf.value) - m1 > usec) // Very small delays may return here.
 | ||||||
|  |       return; | ||||||
|  | 
 | ||||||
|  |    // Eat the time difference from usec value.
 | ||||||
|  |    do { | ||||||
|  |       m2 = (jtime_t)(*_jf.value); | ||||||
|  |       m = m2 - m1; | ||||||
|  |       usec -= (m>=0) ? m : _jf.jiffies + m; | ||||||
|  |       m1 = m2; | ||||||
|  |    } while (usec>0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    A code based delay implementation, using jiffies for timing. | ||||||
|  |  *    This is NOT accurate but it ensures that the time passed is always | ||||||
|  |  *    more than the requested value. | ||||||
|  |  *    The delay values are multiplications of 100 nsec. | ||||||
|  |  * \param   _100nsec     Time in 100nsec for delay | ||||||
|  |  */ | ||||||
|  | void jf_delay_100ns (jtime_t _100nsec) | ||||||
|  | { | ||||||
|  |    jtime_t m, m2, m1 = (jtime_t)*_jf.value; | ||||||
|  | 
 | ||||||
|  |    _100nsec *= _jf.jp100ns; | ||||||
|  |    if ((jtime_t)(*_jf.value) - m1 > _100nsec) // Very small delays may return here.
 | ||||||
|  |       return; | ||||||
|  | 
 | ||||||
|  |    // Eat the time difference from _100nsec value.
 | ||||||
|  |    do { | ||||||
|  |       m2 = (jtime_t)(*_jf.value); | ||||||
|  |       m = m2 - m1; | ||||||
|  |       _100nsec -= (m>=0) ? m : _jf.jiffies + m; | ||||||
|  |       m1 = m2; | ||||||
|  |    } while (_100nsec>0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    A code based polling version delay implementation, using jiffies for timing. | ||||||
|  |  *    This is NOT accurate but it ensures that the time passed is always | ||||||
|  |  *    more than the requested value. | ||||||
|  |  *    The delay values are multiplications of 1 msec. | ||||||
|  |  * \param   msec     Time in msec for delay | ||||||
|  |  * \return  The status of ongoing delay | ||||||
|  |  *    \arg  0:    Delay time has passed | ||||||
|  |  *    \arg  1:    Delay is ongoing, keep calling | ||||||
|  |  */ | ||||||
|  | int jf_check_msec (jtime_t msec) | ||||||
|  | { | ||||||
|  |    static jtime_t m1=-1, cnt; | ||||||
|  |    jtime_t m, m2; | ||||||
|  | 
 | ||||||
|  |    if (m1 == -1) { | ||||||
|  |       m1 = *_jf.value; | ||||||
|  |       cnt = _jf.jp1ms * msec; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Eat the time difference from msec value.
 | ||||||
|  |    if (cnt>0) { | ||||||
|  |       m2 = (jtime_t)(*_jf.value); | ||||||
|  |       m = m2-m1; | ||||||
|  |       cnt -= (m>=0) ? m : _jf.jiffies + m; | ||||||
|  |       m1 = m2; | ||||||
|  |       return 1;   // wait
 | ||||||
|  |    } | ||||||
|  |    else { | ||||||
|  |       m1 = -1; | ||||||
|  |       return 0;   // do not wait any more
 | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    A code based polling version delay implementation, using jiffies for timing. | ||||||
|  |  *    This is NOT accurate but it ensures that the time passed is always | ||||||
|  |  *    more than the requested value. | ||||||
|  |  *    The delay values are multiplications of 1 usec. | ||||||
|  |  * \param   usec     Time in usec for delay | ||||||
|  |  * \return  The status of ongoing delay | ||||||
|  |  *    \arg  0:    Delay time has passed | ||||||
|  |  *    \arg  1:    Delay is ongoing, keep calling | ||||||
|  |  */ | ||||||
|  | int jf_check_usec (jtime_t usec) | ||||||
|  | { | ||||||
|  |    static jtime_t m1=-1, cnt; | ||||||
|  |    jtime_t m, m2; | ||||||
|  | 
 | ||||||
|  |    if (m1 == -1) { | ||||||
|  |       m1 = *_jf.value; | ||||||
|  |       cnt = _jf.jp1us * usec; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Eat the time difference from usec value.
 | ||||||
|  |    if (cnt>0) { | ||||||
|  |       m2 = (jtime_t)(*_jf.value); | ||||||
|  |       m = m2-m1; | ||||||
|  |       cnt -= (m>=0) ? m : _jf.jiffies + m; | ||||||
|  |       m1 = m2; | ||||||
|  |       return 1;   // wait
 | ||||||
|  |    } | ||||||
|  |    else { | ||||||
|  |       m1 = -1; | ||||||
|  |       return 0;   // do not wait any more
 | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    A code based polling version delay implementation, using jiffies for timing. | ||||||
|  |  *    This is NOT accurate but it ensures that the time passed is always | ||||||
|  |  *    more than the requested value. | ||||||
|  |  *    The delay values are multiplications of 100 nsec. | ||||||
|  |  * \param | ||||||
|  |  *    _100nsec     Time in 100nsec for delay | ||||||
|  |  * \return  The status of ongoing delay | ||||||
|  |  *    \arg  0:    Delay time has passed | ||||||
|  |  *    \arg  1:    Delay is ongoing, keep calling | ||||||
|  |  */ | ||||||
|  | int jf_check_100nsec (jtime_t _100nsec) | ||||||
|  | { | ||||||
|  |    static jtime_t m1=-1, cnt; | ||||||
|  |    jtime_t m, m2; | ||||||
|  | 
 | ||||||
|  |    if (m1 == -1) { | ||||||
|  |       m1 = *_jf.value; | ||||||
|  |       cnt = _jf.jp100ns * _100nsec; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Eat the time difference from _100nsec value.
 | ||||||
|  |    if (cnt>0) { | ||||||
|  |       m2 = (jtime_t)(*_jf.value); | ||||||
|  |       m = m2-m1; | ||||||
|  |       cnt -= (m>=0) ? m : _jf.jiffies + m; | ||||||
|  |       m1 = m2; | ||||||
|  |       return 1;   // wait
 | ||||||
|  |    } | ||||||
|  |    else { | ||||||
|  |       m1 = -1; | ||||||
|  |       return 0;   // do not wait any more
 | ||||||
|  |    } | ||||||
|  | } | ||||||
							
								
								
									
										96
									
								
								assignment_3/Libraries/drivers/jiffies.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								assignment_3/Libraries/drivers/jiffies.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file jiffies.h | ||||||
|  |  * \brief | ||||||
|  |  *    A target independent jiffy functionality | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #ifndef __jiffies_h__ | ||||||
|  | #define __jiffies_h__ | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include "driver_types.h" | ||||||
|  | 
 | ||||||
|  | typedef uint16_t     jiffy_t;       //!< Jiffy type 2 byte unsigned integer
 | ||||||
|  | typedef int32_t      jtime_t;        //!< Jiffy time type for delay functionalities usec/msec
 | ||||||
|  | typedef int          (*jf_setfreq_pt) (uint32_t, uint32_t);   //!< Pointer to setfreq function \sa setfreq
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Jiffy inner structure, | ||||||
|  |  * \info | ||||||
|  |  *    We use jiffies to count small time intervals and usually this is | ||||||
|  |  *    below SysTick Interrupt. So we use an indepentend counter for that. | ||||||
|  |  *    Linux names jiffies the Tick per sec. This is toooo big for us. | ||||||
|  |  *    We name jiffy each tick of the extra timer. | ||||||
|  |  *    The equalivent of linux jiffies is the return value of clock (). | ||||||
|  |  */ | ||||||
|  | typedef volatile struct { | ||||||
|  |    jf_setfreq_pt  setfreq;       /*!< Pointer to driver's timer set freq function */ | ||||||
|  |    /*
 | ||||||
|  |     * \note | ||||||
|  |     *   This function must get an integer value for timer's desired | ||||||
|  |     *   frequency and returns the  maximum jiffy value. This usual | ||||||
|  |     *   refers to timer's auto reload value. | ||||||
|  |     */ | ||||||
|  |    jiffy_t        *value;        /*!< Pointer to timers current value */ | ||||||
|  |    uint32_t       freq;          /*!< timer's  frequency */ | ||||||
|  |    jiffy_t        jiffies;       /*!< jiffies max value (timer's max value) */ | ||||||
|  |    jiffy_t        jp1ms;         /*!< Jiffies per 1 msec to use in delay function */ | ||||||
|  |    jiffy_t        jp1us;         /*!< Jiffies per 1 usec to use in delay function */ | ||||||
|  |    jiffy_t        jp100ns;       /*!< Jiffies per 100 nsec to use in delay function */ | ||||||
|  |    drv_status_en  status; | ||||||
|  | }jf_t; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  ============= PUBLIC jiffy API ============= | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Link and Glue functions | ||||||
|  |  */ | ||||||
|  | void jf_link_setfreq (jf_setfreq_pt pfun); | ||||||
|  | void jf_link_value (jiffy_t* v); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Set functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * User Functions | ||||||
|  |  */ | ||||||
|  | drv_status_en jf_probe (void); | ||||||
|  | void jf_deinit (void); | ||||||
|  | drv_status_en jf_init (uint32_t jf_freq, jiffy_t jiffies); | ||||||
|  | 
 | ||||||
|  | jiffy_t jf_get_jiffies (void); | ||||||
|  | jiffy_t jf_get_jiffy (void); | ||||||
|  | jiffy_t jf_per_msec (void); | ||||||
|  | jiffy_t jf_per_usec (void); | ||||||
|  | jiffy_t jf_per_100nsec (void); | ||||||
|  | 
 | ||||||
|  | void jf_delay_ms (jtime_t msec); | ||||||
|  | void jf_delay_us (jtime_t usec); | ||||||
|  | void jf_delay_100ns (jtime_t _100nsec); | ||||||
|  | int jf_check_msec (jtime_t msec); | ||||||
|  | int jf_check_usec (jtime_t usec); | ||||||
|  | int jf_check_100nsec (jtime_t _100nsec); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \note | ||||||
|  |  * The Jiffy lib has no jiffy_t target pointer in the API. This means | ||||||
|  |  * that IT CAN BE ONLY ONE jiffy timer per application. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif   //#ifndef __jiffies_h__
 | ||||||
							
								
								
									
										527
									
								
								assignment_3/Libraries/drivers/onewire_uart.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										527
									
								
								assignment_3/Libraries/drivers/onewire_uart.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,527 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file onewire_uart.c | ||||||
|  |  * \brief | ||||||
|  |  *    A target independent 1-wire implementation using a microprocessor's uart | ||||||
|  |  *    for bit timing | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #include "onewire_uart.h" | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ========= Private helper macros =========== | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Clear a virtual 64bit unsigned register. | ||||||
|  |  * \note | ||||||
|  |  *    We use a uint8_t array[8] to represent that kind | ||||||
|  |  *    of data for this module | ||||||
|  |  * \param   _reg  Pointer to register location. Usual the name of | ||||||
|  |  *                The array | ||||||
|  |  */ | ||||||
|  | #define  _clear_u64(_reg_)                      \ | ||||||
|  |    memset ((void*)(_reg_), 0, 8*sizeof(uint8_t)) | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Read a bit value of a virtual 64bit unsigned register. | ||||||
|  |  * \note | ||||||
|  |  *    We use a uint8_t array[8] to represent that kind | ||||||
|  |  *    of data for this module | ||||||
|  |  * \param   _reg  Pointer to register location. Usual the name of | ||||||
|  |  *                The array | ||||||
|  |  * \param   _bit  The bit location we want to read | ||||||
|  |  */ | ||||||
|  | #define  _read_bit_u64(_reg_, _bit_)            \ | ||||||
|  |    (_reg_[(_bit_)/8] & (1<<((_bit_)%8))) ? 1:0 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Write/modify a bit value from a virtual 64bit unsigned register. | ||||||
|  |  * \note | ||||||
|  |  *    We use a uint8_t array[8] to represent that kind | ||||||
|  |  *    of data for this module | ||||||
|  |  * \param   _reg  Pointer to register location. Usual the name of | ||||||
|  |  *                The array | ||||||
|  |  * \param   _bit  The bit location we want to set | ||||||
|  |  * \param   _v    The value we want to set | ||||||
|  |  *    \arg  0     Set to zero | ||||||
|  |  *    \arg  !0    Set to One | ||||||
|  |  */ | ||||||
|  | #define  _write_bit_u64(_reg_, _bit_, _v_)               \ | ||||||
|  |    do {                                                  \ | ||||||
|  |       if (_v_) _reg_[(_bit_)/8] |=   1 << ((_bit_)%8);   \ | ||||||
|  |       else     _reg_[(_bit_)/8] &= ~(1 << ((_bit_)%8));  \ | ||||||
|  |    } while (0) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============= Private functions =========== | ||||||
|  |  */ | ||||||
|  | /* Data manipulation functions */ | ||||||
|  | static int _cmp_u64 (uint8_t *reg1, uint8_t *reg2); | ||||||
|  | 
 | ||||||
|  | /* Set functions */ | ||||||
|  | static drv_status_en _set_baudrate (ow_uart_t *ow, ow_uart_state_en st); | ||||||
|  | 
 | ||||||
|  | /* Bus functions */ | ||||||
|  | static uint8_t _write_bit (ow_uart_t *ow, uint8_t b); | ||||||
|  | static uint8_t _read_bit (ow_uart_t *ow); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Compare two 64bit virtual unsigned registers | ||||||
|  |  * \note | ||||||
|  |  *    We use a uint8_t array[8] to represent that kind | ||||||
|  |  *    of data for this module | ||||||
|  |  * \param   reg1  Pointer to first register location. Usual the name of | ||||||
|  |  *                the array | ||||||
|  |  * \param   reg1  Pointer to 2nd register location. Usual the name of | ||||||
|  |  *                the array | ||||||
|  |  * \return  The comparison result | ||||||
|  |  *    \arg  0     Registers are equal | ||||||
|  |  *    \arg  1     Register 1 is larger than register 2 | ||||||
|  |  *    \arg  -1    Register 2 is larger than register 1 | ||||||
|  |  */ | ||||||
|  | static int _cmp_u64 (uint8_t *reg1, uint8_t *reg2) { | ||||||
|  |    int i; | ||||||
|  |    for (i=7 ; i>=0 ; --i) { | ||||||
|  |       if (reg1[i] > reg2[i])        return 1;   /* reg1 > reg2 */ | ||||||
|  |       else if (reg1[i] < reg2[i])   return -1;  /* reg1 < reg2 */ | ||||||
|  |    } | ||||||
|  |    return 0;   /* reg1 equal reg2 */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Set UART Baudrate and handle all function calls and data | ||||||
|  |  *    manipulation | ||||||
|  |  * \param   ow    Pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \param   st    The 1-Wire operational state \sa ow_uart_state_en | ||||||
|  |  * \return        The status of the operation | ||||||
|  |  *    \arg  DRV_ERROR   Could not set baudrate (callback pointer function error) | ||||||
|  |  *    \arg  DRV_READY   Success | ||||||
|  |  */ | ||||||
|  | static drv_status_en _set_baudrate (ow_uart_t *ow, ow_uart_state_en st) | ||||||
|  | { | ||||||
|  |    uint32_t       st_br; | ||||||
|  | 
 | ||||||
|  |    /* Get the desired baudrate */ | ||||||
|  |    switch (st) { | ||||||
|  |       case OWS_RESET:   st_br = ow->baudrate.reset;   break; | ||||||
|  |       default: | ||||||
|  |       case OWS_OPER:    st_br = ow->baudrate.oper;    break; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (ow->baudrate.current != st_br) { | ||||||
|  |       if (ow->io.br (st_br) != DRV_READY)    return DRV_ERROR; | ||||||
|  |       ow->baudrate.current = st_br; | ||||||
|  |    } | ||||||
|  |    return DRV_READY; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Send a 1-Wire write bit | ||||||
|  |  * | ||||||
|  |  *           ---       -------------------------------------- | ||||||
|  |  * Write 1      \     / | ||||||
|  |  *               ---- | ||||||
|  |  *  RS:          |   |   |   |   |   |   |   |   |   |   | | ||||||
|  |  *  bit:          st   0   1   2   3   4   5   6   7   st | ||||||
|  |  *               < ------------- 87/11 usec -------------> | ||||||
|  |  *  8 bits, no parity, 1 stop | ||||||
|  |  *  standard:  BR: 115200              Overdrive: BR: 921600 | ||||||
|  |  *  TX: 0xFF | ||||||
|  |  *  RX: 0xFF | ||||||
|  |  * | ||||||
|  |  *           ---                                       ------ | ||||||
|  |  * Write 0      \                                     / | ||||||
|  |  *               ------------------------------------- | ||||||
|  |  *  RS:          |   |   |   |   |   |   |   |   |   |   | | ||||||
|  |  *  bit:          st   0   1   2   3   4   5   6   7   st | ||||||
|  |  *               < ------------- 87/11 usec -------------> | ||||||
|  |  *  8 bits, no parity, 1 stop | ||||||
|  |  *  standard:  BR: 115200              Overdrive: BR: 921600 | ||||||
|  |  *  TX: 0x00 | ||||||
|  |  *  RX: 0x00 | ||||||
|  |  * | ||||||
|  |  * \param   ow    Pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \param   b     The bit to send | ||||||
|  |  * \return        Status of the operation | ||||||
|  |  *    \arg  0     Success | ||||||
|  |  *    \arg  1     Fail | ||||||
|  |  */ | ||||||
|  | static uint8_t _write_bit (ow_uart_t *ow, uint8_t b) | ||||||
|  | { | ||||||
|  |    uint8_t  w; | ||||||
|  |    uint16_t r; | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |     * Make sure we are at the right baudrate | ||||||
|  |     */ | ||||||
|  |    if (_set_baudrate (ow, OWS_OPER) != DRV_READY) | ||||||
|  |       return 1; | ||||||
|  | 
 | ||||||
|  |    /* Select frame to send and check the bus by evaluating the return value */ | ||||||
|  |    w = (b) ? 0xFF : 0x00; | ||||||
|  |    r = ow->io.rw (w); | ||||||
|  | 
 | ||||||
|  |    if (r != w)    return 1; | ||||||
|  |    else           return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Read a bit from the 1-Wire bus, return it and provide | ||||||
|  |  *    the recovery time. | ||||||
|  |  * | ||||||
|  |  *           ---       -  -  -  -  -  -  -  -  -  -  - ------ | ||||||
|  |  * Read         \     / X X X X X X X X X X X X X X X / | ||||||
|  |  *               ----  -  -  -  -  -  -  -  -  -  - - | ||||||
|  |  *  RS:          |   |   |   |   |   |   |   |   |   |   | | ||||||
|  |  *  bit:          st   0   1   2   3   4   5   6   7   st | ||||||
|  |  *               < ------------- 87/11 usec -------------> | ||||||
|  |  *                     ^ | ||||||
|  |  *                     | | ||||||
|  |  *                Master sample | ||||||
|  |  * | ||||||
|  |  *  8 bits, no parity, 1 stop | ||||||
|  |  *  standard:  BR: 115200              Overdrive: BR: 921600 | ||||||
|  |  *  TX: 0xFF | ||||||
|  |  *  RX: {1 - 0xFF,   0 - [0x00 - 0xFE] } | ||||||
|  |  * | ||||||
|  |  * \return  The answer | ||||||
|  |  *    \arg  0  Read 0 | ||||||
|  |  *    \arg  1  Read 1 (This is also returned on transition error). | ||||||
|  |  */ | ||||||
|  | static uint8_t _read_bit (ow_uart_t *ow) | ||||||
|  | { | ||||||
|  |    uint16_t  r; | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |     * Make sure we are at the right baudrate | ||||||
|  |     */ | ||||||
|  |    if (_set_baudrate (ow, OWS_OPER) != DRV_READY) | ||||||
|  |       return 1; | ||||||
|  | 
 | ||||||
|  |    /* Send frame for read */ | ||||||
|  |    r = ow->io.rw (0xFF); | ||||||
|  | 
 | ||||||
|  |    /* Dispatch answer */ | ||||||
|  |    if (r < 0xFF)  return 0; | ||||||
|  |    else           return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  ============= PUBLIC 1-Wire API ============= | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Link and Glue functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief   link driver's UART read-write function | ||||||
|  |  * \param   ow    pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \param   tx    ow_uart_rx_ft pointer to drivers UART rx function | ||||||
|  |  */ | ||||||
|  | void ow_uart_link_rw (ow_uart_t *ow, ow_uart_rw_ft rw) { | ||||||
|  |    ow->io.rw = (ow_uart_rw_ft)((rw != 0) ? rw : 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief   link driver's UART baudrate function | ||||||
|  |  * \param   ow    pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \param   tx    ow_uart_tx_ft pointer to drivers UART baudrate function | ||||||
|  |  */ | ||||||
|  | void ow_uart_link_br (ow_uart_t *ow, ow_uart_br_ft br) { | ||||||
|  |    ow->io.br = (ow_uart_br_ft)((br != 0) ? br : 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Set functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief  set 1-wire timing mode and update baudrate table. | ||||||
|  |  *          If the owt parameter is not a valid ow_uart_timing_en | ||||||
|  |  *          then set timings to OW_STANDTARD. | ||||||
|  |  * \param  ow     pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \param  owt    Timing type | ||||||
|  |  *    \arg  OWT_STANDARD      Use standard timing | ||||||
|  |  *    \arg  OWT_OVERDRIVE     Use overdrive timing | ||||||
|  |  */ | ||||||
|  | void ow_uart_set_timing (ow_uart_t *ow, uint32_t owt) { | ||||||
|  |    ow->timing = (_ow_uart_is_timings(owt)) ? owt : OW_UART_T_STANDARD; | ||||||
|  | 
 | ||||||
|  |    switch (owt) { | ||||||
|  |       case OW_UART_T_STANDARD:   _ow_baudrate_standard (ow->baudrate);  break; | ||||||
|  |       case OW_UART_T_OVERDRIVE:  _ow_baudrate_overdrive (ow->baudrate); break; | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * User Functions | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    De-Initialize the 1-Wire interface and leave bus pin in input state | ||||||
|  |  * \param  ow    pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \return none | ||||||
|  |  */ | ||||||
|  | void ow_uart_deinit (ow_uart_t *ow) | ||||||
|  | { | ||||||
|  |    // Clear data
 | ||||||
|  |    memset ((void*)ow, 0, sizeof (ow_uart_t)); | ||||||
|  |    /*!<
 | ||||||
|  |     * This leaves the status = DRV_NOINIT | ||||||
|  |     */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Initialize the 1-Wire interface and leave bus high | ||||||
|  |  * \param  ow    pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \return The driver status after init. | ||||||
|  |  *    \arg DRV_READY | ||||||
|  |  *    \arg DRV_ERROR | ||||||
|  |  */ | ||||||
|  | drv_status_en ow_uart_init (ow_uart_t *ow) | ||||||
|  | { | ||||||
|  |    // Check requirements
 | ||||||
|  |    if (!ow->io.rw)      return ow->status = DRV_ERROR; | ||||||
|  |    if (!ow->io.br)      return ow->status = DRV_ERROR; | ||||||
|  | 
 | ||||||
|  |    // Init the bus
 | ||||||
|  |    ow->status = DRV_BUSY; | ||||||
|  |    if ( _ow_uart_is_timings(ow->timing) != 1) { | ||||||
|  |       ow->timing = OW_UART_T_STANDARD; | ||||||
|  |       _ow_baudrate_standard (ow->baudrate); | ||||||
|  |    } | ||||||
|  |    switch (ow->timing) { | ||||||
|  |       case OW_UART_T_STANDARD:   _ow_baudrate_standard (ow->baudrate);  break; | ||||||
|  |       case OW_UART_T_OVERDRIVE:  _ow_baudrate_overdrive (ow->baudrate); break; | ||||||
|  |    } | ||||||
|  |    if (_set_baudrate (ow, OWS_RESET) != DRV_READY) | ||||||
|  |       return ow->status = DRV_ERROR; | ||||||
|  |    return ow->status = DRV_READY; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Generate a 1-wire reset | ||||||
|  |  * | ||||||
|  |  *           ---                      ----  -  -  -  ------- | ||||||
|  |  * Reset        \                    /    \ X  X  X / | ||||||
|  |  *               --------------------      -  -  - - | ||||||
|  |  *  RS:          |   |   |   |   |   |   |   |   |   |   | | ||||||
|  |  *  bit:          st   0   1   2   3   4   5   6   7   st | ||||||
|  |  *               < ---------- 1024/174 usec -------------> | ||||||
|  |  * | ||||||
|  |  *  8 bits, no parity, 1 stop | ||||||
|  |  *  Standard:                          Overdrive : | ||||||
|  |  *  BR: 9600,                          BR: 57600 | ||||||
|  |  *  TX: 0xF0,                          TX: 0xF8 | ||||||
|  |  *  RX: 0xF0 not present               RX: 0xF8 not present | ||||||
|  |  *      less if present                    less if present | ||||||
|  |  * | ||||||
|  |  * \note    Does not handle alarm presence from DS2404/DS1994 | ||||||
|  |  * \param   None | ||||||
|  |  * \return  The status of the operation | ||||||
|  |  *    \arg  DRV_ERROR      Error, callback baudrate error or bus error | ||||||
|  |  *    \arg  DRV_NODEV      If no presence detect was found | ||||||
|  |  *    \arg  DRV_READY      Otherwise | ||||||
|  |  */ | ||||||
|  | drv_status_en ow_uart_reset (ow_uart_t *ow) | ||||||
|  | { | ||||||
|  |    uint8_t  w; | ||||||
|  |    uint16_t r; | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |     * Make sure we are at the write baudrate | ||||||
|  |     */ | ||||||
|  |    if (_set_baudrate (ow, OWS_RESET) != DRV_READY) | ||||||
|  |       return DRV_ERROR; | ||||||
|  | 
 | ||||||
|  |    /* Select frame to send */ | ||||||
|  |    w = (ow->timing == OW_UART_T_OVERDRIVE) ? 0xF8 : 0xF0; | ||||||
|  | 
 | ||||||
|  |    r = ow->io.rw (w); | ||||||
|  |    r = ow->io.rw (w);   // Send it twice to make sure
 | ||||||
|  | 
 | ||||||
|  |    if (w>r)       return DRV_READY; | ||||||
|  |    else if (w==r) return DRV_NODEV; | ||||||
|  |    else           return DRV_ERROR; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Read a byte from 1-Wire bus | ||||||
|  |  * \param  ow    pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \return  The byte received. | ||||||
|  |  */ | ||||||
|  | uint8_t ow_uart_rx (ow_uart_t *ow) | ||||||
|  | { | ||||||
|  |    uint8_t  i; | ||||||
|  |    byte_t byte; | ||||||
|  | 
 | ||||||
|  |    for (i=8, byte=0 ; i>0 ; --i) { | ||||||
|  |       byte >>= 1;       /* shift bits to right as LSB comes first */ | ||||||
|  |       if (_read_bit (ow) != 0)  byte |= 0x80;  /* Mask bit to MSB */ | ||||||
|  |    } | ||||||
|  |    return byte; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Write a byte to 1-Wire bus | ||||||
|  |  * \param  ow    pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \param  b:    The byte to write | ||||||
|  |  * \return  none | ||||||
|  |  */ | ||||||
|  | void ow_uart_tx (ow_uart_t *ow, byte_t byte) | ||||||
|  | { | ||||||
|  |    uint8_t  i; | ||||||
|  | 
 | ||||||
|  |    for (i=8 ; i>0 ; --i) { | ||||||
|  |       _write_bit (ow, byte & 0x01);    /* Send LSB */ | ||||||
|  |       byte >>= 1;           /* shift bits to right */ | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Write a byte to 1-Wire bus and read the response | ||||||
|  |  * \param  ow    Pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \param   byte  The byte to write | ||||||
|  |  * \return  The byte received. | ||||||
|  |  */ | ||||||
|  | uint8_t ow_uart_rw (ow_uart_t *ow, byte_t byte) | ||||||
|  | { | ||||||
|  |    uint8_t  i; | ||||||
|  |    byte_t ret; | ||||||
|  | 
 | ||||||
|  |    for (i=8, ret=0 ; i>0 ; --i) { | ||||||
|  |       ret >>= 1;     /* shift read bits to right as LSB comes first */ | ||||||
|  |       if ((byte & 0x01) != 0)    ret |= (_read_bit (ow) != 0) ? 0x80 : 0x0; | ||||||
|  |       else                       _write_bit (ow, 0); | ||||||
|  |       byte >>= 1;    /* shift bits to right */ | ||||||
|  | 
 | ||||||
|  |       /*!<
 | ||||||
|  |        * If the bit is 1 we use the read sequence, as it has the same | ||||||
|  |        * waveform with write-1 and we get the slave response | ||||||
|  |        * If the bit is 0, we can not read the slave response so we just write-0 | ||||||
|  |        */ | ||||||
|  |    } | ||||||
|  |    return byte; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    1-Wire search algorithm based on maxim-ic application note 187 | ||||||
|  |  * | ||||||
|  |  * \param   ow       Pointer to select 1-Wire structure for the operation. | ||||||
|  |  * \param   romid    Pointer to romid to return. If the search is success | ||||||
|  |  *                   this points to and 64bit long array with ROM ID | ||||||
|  |  * \return  The status of the search | ||||||
|  |  *    \arg  DRV_NODEV (-1) Search was failed, No device found | ||||||
|  |  *    \arg  DRV_READY (1)  Search is complete, all ROM IDs was found. This was the last | ||||||
|  |  *    \arg  DRV_BUSY  (2)  Search is succeed, plus there are more ROM IDs to found | ||||||
|  |  *    \arg  DRV_ERROR (3)  Search failed, Reading error | ||||||
|  |  */ | ||||||
|  | drv_status_en ow_uart_search (ow_uart_t *ow, uint8_t *romid) | ||||||
|  | { | ||||||
|  |    static uint8_t dec[8];  /*!<
 | ||||||
|  |                             * Hold the algorithm's select bit when a discrepancy | ||||||
|  |                             * is detected. We use this variable to navigate to the | ||||||
|  |                             * ROM tree as we store the path we take each time (0-1). | ||||||
|  |                             * Each bit represent a bit position in the ROM ID. | ||||||
|  |                             */ | ||||||
|  |    static uint8_t pos[8];  /*!<
 | ||||||
|  |                             * Hold the discrepancy position. We use this variable to | ||||||
|  |                             * navigate to the ROM tree as we store the crossroads(1) we encounter. | ||||||
|  |                             * Each bit represent a bit position in the ROM ID. | ||||||
|  |                             */ | ||||||
|  |    uint8_t i, cur[8];      /* Current pass bit position, in a pos[8] like representation of it */ | ||||||
|  |    uint8_t  b, b1, b2;     /* bit helper vars */ | ||||||
|  | 
 | ||||||
|  |    if (ow_uart_reset (ow) != DRV_READY) | ||||||
|  |       return DRV_NODEV; | ||||||
|  |    ow_uart_tx (ow, 0xF0);    /* Issue search command */ | ||||||
|  | 
 | ||||||
|  |    for (i=0 ; i<64 ; ++i) { | ||||||
|  |       /* Get response pair bits */ | ||||||
|  |       b1 = _read_bit (ow); | ||||||
|  |       b2 = _read_bit (ow); | ||||||
|  | 
 | ||||||
|  |       switch (b1 | (b2<<1)) { | ||||||
|  |          case 0x00:  /* 00 - We have discrepancy */ | ||||||
|  |             _write_bit_u64 (cur, i, 1); | ||||||
|  |             switch (_cmp_u64 (pos, cur)) { | ||||||
|  |                default: | ||||||
|  |                case -1: b = 0; | ||||||
|  |                         _write_bit_u64 (pos, i, 1);   break; | ||||||
|  |                case 0:  b = 1; | ||||||
|  |                         _write_bit_u64 (dec, i, 1);   break; | ||||||
|  |                case 1:  b = _read_bit_u64 (dec, i);   break; | ||||||
|  |                /*<
 | ||||||
|  |                 * -1) pos < cur: This discrepancy is the most far for now. | ||||||
|  |                 *       Mark position and select 0. | ||||||
|  |                 *  0) pos == cur: This was the last discrepancy in the last pass. | ||||||
|  |                 *       Select the other branch this time (1). | ||||||
|  |                 *  1) pos > cur: We had a discrepancy in a MSB than that, in a previous pass. | ||||||
|  |                 *       Continue with the last pass decision. | ||||||
|  |                 */ | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /* Send selection and update romid */ | ||||||
|  |             _write_bit (ow, b); | ||||||
|  |             _write_bit_u64 (romid, i, b); | ||||||
|  |             break; | ||||||
|  | 
 | ||||||
|  |          case 0x01:  /* 01 - All bits of all ROMs are 1s */ | ||||||
|  |             _write_bit (ow, 1); | ||||||
|  |             _write_bit_u64 (romid, i, 1);   break; | ||||||
|  | 
 | ||||||
|  |          case 0x02:  /* 10 - All bits of all ROMs are 0s */ | ||||||
|  |             _write_bit (ow, 0); | ||||||
|  |             _write_bit_u64 (romid, i, 0);   break; | ||||||
|  | 
 | ||||||
|  |          default: | ||||||
|  |          case 0x03:  /* 11 - No device on the bus */ | ||||||
|  |             _clear_u64 (romid); | ||||||
|  |             return DRV_NODEV; | ||||||
|  |       }  /* switch (b1 | (b2<<1)) */ | ||||||
|  |    }  /* for */ | ||||||
|  | 
 | ||||||
|  |    switch (_cmp_u64 (dec, pos)) { | ||||||
|  |       case -1: return DRV_BUSY; | ||||||
|  |       case 0:  _clear_u64 (dec); | ||||||
|  |                _clear_u64 (pos); | ||||||
|  |                return DRV_READY; | ||||||
|  |       default: | ||||||
|  |       case 1:  _clear_u64 (dec); | ||||||
|  |                _clear_u64 (pos); | ||||||
|  |                return DRV_ERROR; | ||||||
|  |       /*<
 | ||||||
|  |        * -1) des < pos:  We have more leafs(ROMs) to found | ||||||
|  |        *  0) des == pos: We have found all the leafs(ROMs) | ||||||
|  |        *  1) des > pos:  We have more decision that discrepancies ?!?!?, Error. | ||||||
|  |        */ | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #undef  _clear_u64 | ||||||
|  | #undef  _read_bit_u64 | ||||||
|  | #undef  _write_bit_u64 | ||||||
|  | #undef  _ow_is_timings | ||||||
							
								
								
									
										194
									
								
								assignment_3/Libraries/drivers/onewire_uart.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								assignment_3/Libraries/drivers/onewire_uart.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,194 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file onewire_uart.h | ||||||
|  |  * \brief | ||||||
|  |  *    A target independent 1-wire implementation using a microprocessor's uart | ||||||
|  |  *    for bit timing | ||||||
|  |  * \note | ||||||
|  |  *    This 1-wire implementation is based on MCU UART io functionality. In order | ||||||
|  |  *    to work it needs: | ||||||
|  |  *    1) A Open drain tx and floating(or pull-up) rx UART pin configuration with both pins | ||||||
|  |  *       connected to the 1-wire bus wire | ||||||
|  |  *    2) A Transmit function even in blocking/polling mode | ||||||
|  |  *    3) A receive function even in blocking/polling mode | ||||||
|  |  *    4) A baudrate set function | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #ifndef __onewire_uart_h__ | ||||||
|  | #define __onewire_uart_h__ | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include "driver_types.h" | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | /* ================   General Defines   ====================*/ | ||||||
|  | 
 | ||||||
|  | typedef uint16_t (*ow_uart_rw_ft) (uint8_t);           /*!< UART read-write function pointer */ | ||||||
|  | typedef drv_status_en (*ow_uart_br_ft) (uint32_t);    /*!< UART baudrate modify function pointer */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * 1-Wire operational state | ||||||
|  |  */ | ||||||
|  | typedef enum { | ||||||
|  |    OWS_RESET = 0,       /*!< 1-Wire bus is during in Reset state */ | ||||||
|  |    OWS_OPER             /*!< 1-Wire bus is during normal operation */ | ||||||
|  | }ow_uart_state_en; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * 1-Wire UART baudrate table | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |    uint32_t    reset;      /*!< Baudrate during reset */ | ||||||
|  |    uint32_t    oper;       /*!< Baudrate during normal operation */ | ||||||
|  |    uint32_t    current;    /*!< The current baudrate to use as flag */ | ||||||
|  | }ow_uart_br_t; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * 1-Wire driver function callback pointers | ||||||
|  |  * \note | ||||||
|  |  *    The function in this structure provided from the low level driver (usually). | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |    ow_uart_rw_ft  rw;      /*!< Pointer UART read-write function */ | ||||||
|  |    ow_uart_br_ft  br;      /*!< Pointer to UART baudrate function */ | ||||||
|  | }ow_uart_io_t; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * 1-Wire Data type | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |    ow_uart_io_t      io;         /*!< Callback pointers and direction state */ | ||||||
|  |    uint32_t          timing;     /*!< The selected timing mode */ | ||||||
|  |    ow_uart_br_t      baudrate;   /*!< The current baudrate configuration */ | ||||||
|  |    drv_status_en     status;     /*!< Toolbox driver status */ | ||||||
|  | }ow_uart_t; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============ Helper Macros ============= | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * 1-Wire speed | ||||||
|  |  */ | ||||||
|  | #define  OW_UART_T_STANDARD         (0) | ||||||
|  | #define  OW_UART_T_OVERDRIVE        (1) | ||||||
|  | /*!
 | ||||||
|  |  * Check if the timing is a valid \ref ow_uart_timing_en value | ||||||
|  |  */ | ||||||
|  | #define  _ow_uart_is_timings(_t_)     ( ((_t_) == OW_UART_T_STANDARD) || ((_t_) == OW_UART_T_OVERDRIVE) ) | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *                   Timing Diagram | ||||||
|  |  * -------------------------------------------------- | ||||||
|  |  * Based on Application Note 214 (www.maxim-ic.com) | ||||||
|  |  * | ||||||
|  |  *           ---                      ----  -  -  -  ------- | ||||||
|  |  * Reset        \                    /    \ X  X  X / | ||||||
|  |  *               --------------------      -  -  - - | ||||||
|  |  *  RS:          |   |   |   |   |   |   |   |   |   |   | | ||||||
|  |  *  bit:          st   0   1   2   3   4   5   6   7   st | ||||||
|  |  *               < ---------- 1024/174 usec -------------> | ||||||
|  |  * | ||||||
|  |  *  8 bits, no parity, 1 stop | ||||||
|  |  *  Standard:                          Overdrive : | ||||||
|  |  *  BR: 9600,                          BR: 57600 | ||||||
|  |  *  TX: 0xF0,                          TX: 0xF8 | ||||||
|  |  *  RX: 0xF0 not present               RX: 0xF8 not present | ||||||
|  |  *      less if present                    less if present | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  *           ---       -------------------------------------- | ||||||
|  |  * Write 1      \     / | ||||||
|  |  *               ---- | ||||||
|  |  *  RS:          |   |   |   |   |   |   |   |   |   |   | | ||||||
|  |  *  bit:          st   0   1   2   3   4   5   6   7   st | ||||||
|  |  *               < ------------- 87/11 usec -------------> | ||||||
|  |  *  8 bits, no parity, 1 stop | ||||||
|  |  *  standard:  BR: 115200              Overdrive: BR: 921600 | ||||||
|  |  *  TX: 0xFF | ||||||
|  |  *  RX: 0xFF | ||||||
|  |  * | ||||||
|  |  *           ---                                       ------ | ||||||
|  |  * Write 0      \                                     / | ||||||
|  |  *               ------------------------------------- | ||||||
|  |  *  RS:          |   |   |   |   |   |   |   |   |   |   | | ||||||
|  |  *  bit:          st   0   1   2   3   4   5   6   7   st | ||||||
|  |  *               < ------------- 87/11 usec -------------> | ||||||
|  |  *  8 bits, no parity, 1 stop | ||||||
|  |  *  standard:  BR: 115200              Overdrive: BR: 921600 | ||||||
|  |  *  TX: 0x00 | ||||||
|  |  *  RX: 0x00 | ||||||
|  |  * | ||||||
|  |  *           ---       -  -  -  -  -  -  -  -  -  -  - ------ | ||||||
|  |  * Read         \     / X X X X X X X X X X X X X X X / | ||||||
|  |  *               ----  -  -  -  -  -  -  -  -  -  - - | ||||||
|  |  *  RS:          |   |   |   |   |   |   |   |   |   |   | | ||||||
|  |  *  bit:          st   0   1   2   3   4   5   6   7   st | ||||||
|  |  *               < ------------- 87/11 usec -------------> | ||||||
|  |  *                     ^ | ||||||
|  |  *                     | | ||||||
|  |  *                Master sample | ||||||
|  |  * | ||||||
|  |  *  8 bits, no parity, 1 stop | ||||||
|  |  *  standard:  BR: 115200              Overdrive: BR: 921600 | ||||||
|  |  *  TX: 0xFF | ||||||
|  |  *  RX: {1 - 0xFF,   0 - [0x00 - 0xFE] } | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | #define  _ow_baudrate_standard(_br_)   \ | ||||||
|  |    do {                       \ | ||||||
|  |       _br_.reset = 9600;      \ | ||||||
|  |       _br_.oper = 115200;     \ | ||||||
|  |       _br_.current = 9600;    \ | ||||||
|  |    } while (0) | ||||||
|  | 
 | ||||||
|  | #define  _ow_baudrate_overdrive(_br_)  \ | ||||||
|  |    do {                          \ | ||||||
|  |       _br_.reset = 115200;       \ | ||||||
|  |       _br_.oper = 921600;        \ | ||||||
|  |       _br_.current = 115200;     \ | ||||||
|  |    } while (0) | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  ============= PUBLIC ALCD API ============= | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Link and Glue functions | ||||||
|  |  */ | ||||||
|  | void ow_uart_link_rw (ow_uart_t *ow, ow_uart_rw_ft tx);    /*!< link driver's read-write function */ | ||||||
|  | void ow_uart_link_br (ow_uart_t *ow, ow_uart_br_ft br);    /*!< link driver's baudrate function*/ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Set functions | ||||||
|  |  */ | ||||||
|  | void ow_uart_set_timing (ow_uart_t *ow, uint32_t owt);      /*!< set 1-wire timing mode */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * User Functions | ||||||
|  |  */ | ||||||
|  | void ow_uart_deinit (ow_uart_t *ow);             /*!< for compatibility */ | ||||||
|  | drv_status_en ow_uart_init (ow_uart_t *ow);      /*!< for compatibility */ | ||||||
|  | 
 | ||||||
|  | drv_status_en | ||||||
|  |          ow_uart_reset (ow_uart_t *ow); | ||||||
|  | uint8_t  ow_uart_rx (ow_uart_t *ow); | ||||||
|  | void     ow_uart_tx (ow_uart_t *ow, byte_t byte); | ||||||
|  | uint8_t  ow_uart_rw (ow_uart_t *ow, byte_t byte); | ||||||
|  | drv_status_en | ||||||
|  |          ow_uart_search (ow_uart_t *ow, uint8_t *romid); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* #ifndef __onewire_uart_h__ */ | ||||||
							
								
								
									
										495
									
								
								assignment_3/Libraries/drivers/stm32f4xx_hal_conf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										495
									
								
								assignment_3/Libraries/drivers/stm32f4xx_hal_conf.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,495 @@ | |||||||
|  | /**
 | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @file    stm32f4xx_hal_conf_template.h | ||||||
|  |   * @author  MCD Application Team | ||||||
|  |   * @brief   HAL configuration template file.  | ||||||
|  |   *          This file should be copied to the application folder and renamed | ||||||
|  |   *          to stm32f4xx_hal_conf.h. | ||||||
|  |   ****************************************************************************** | ||||||
|  |   * @attention | ||||||
|  |   * | ||||||
|  |   * <h2><center>© Copyright (c) 2017 STMicroelectronics. | ||||||
|  |   * All rights reserved.</center></h2> | ||||||
|  |   * | ||||||
|  |   * This software component is licensed by ST under BSD 3-Clause license, | ||||||
|  |   * the "License"; You may not use this file except in compliance with the | ||||||
|  |   * License. You may obtain a copy of the License at: | ||||||
|  |   *                        opensource.org/licenses/BSD-3-Clause | ||||||
|  |   * | ||||||
|  |   ****************************************************************************** | ||||||
|  |   */  | ||||||
|  | 
 | ||||||
|  | /* Define to prevent recursive inclusion -------------------------------------*/ | ||||||
|  | #ifndef __STM32F4xx_HAL_CONF_H | ||||||
|  | #define __STM32F4xx_HAL_CONF_H | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* Exported types ------------------------------------------------------------*/ | ||||||
|  | /* Exported constants --------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /* ########################## Module Selection ############################## */ | ||||||
|  | /**
 | ||||||
|  |   * @brief This is the list of modules to be used in the HAL driver  | ||||||
|  |   */ | ||||||
|  | #define HAL_MODULE_ENABLED   | ||||||
|  | #define HAL_ADC_MODULE_ENABLED | ||||||
|  | #define HAL_CAN_MODULE_ENABLED | ||||||
|  | /* #define HAL_CAN_LEGACY_MODULE_ENABLED */ | ||||||
|  | #define HAL_CRC_MODULE_ENABLED | ||||||
|  | #define HAL_CEC_MODULE_ENABLED | ||||||
|  | #define HAL_CRYP_MODULE_ENABLED | ||||||
|  | #define HAL_DAC_MODULE_ENABLED | ||||||
|  | #define HAL_DCMI_MODULE_ENABLED | ||||||
|  | #define HAL_DMA_MODULE_ENABLED | ||||||
|  | #define HAL_DMA2D_MODULE_ENABLED | ||||||
|  | #define HAL_ETH_MODULE_ENABLED | ||||||
|  | #define HAL_FLASH_MODULE_ENABLED | ||||||
|  | #define HAL_NAND_MODULE_ENABLED | ||||||
|  | #define HAL_NOR_MODULE_ENABLED | ||||||
|  | #define HAL_PCCARD_MODULE_ENABLED | ||||||
|  | #define HAL_SRAM_MODULE_ENABLED | ||||||
|  | #define HAL_SDRAM_MODULE_ENABLED | ||||||
|  | #define HAL_HASH_MODULE_ENABLED | ||||||
|  | #define HAL_GPIO_MODULE_ENABLED | ||||||
|  | #define HAL_EXTI_MODULE_ENABLED | ||||||
|  | #define HAL_I2C_MODULE_ENABLED | ||||||
|  | #define HAL_SMBUS_MODULE_ENABLED | ||||||
|  | #define HAL_I2S_MODULE_ENABLED | ||||||
|  | #define HAL_IWDG_MODULE_ENABLED | ||||||
|  | #define HAL_LTDC_MODULE_ENABLED | ||||||
|  | #define HAL_DSI_MODULE_ENABLED | ||||||
|  | #define HAL_PWR_MODULE_ENABLED | ||||||
|  | #define HAL_QSPI_MODULE_ENABLED | ||||||
|  | #define HAL_RCC_MODULE_ENABLED | ||||||
|  | #define HAL_RNG_MODULE_ENABLED | ||||||
|  | #define HAL_RTC_MODULE_ENABLED | ||||||
|  | #define HAL_SAI_MODULE_ENABLED | ||||||
|  | #define HAL_SD_MODULE_ENABLED | ||||||
|  | #define HAL_SPI_MODULE_ENABLED | ||||||
|  | #define HAL_TIM_MODULE_ENABLED | ||||||
|  | #define HAL_UART_MODULE_ENABLED | ||||||
|  | #define HAL_USART_MODULE_ENABLED | ||||||
|  | #define HAL_IRDA_MODULE_ENABLED | ||||||
|  | #define HAL_SMARTCARD_MODULE_ENABLED | ||||||
|  | #define HAL_WWDG_MODULE_ENABLED | ||||||
|  | #define HAL_CORTEX_MODULE_ENABLED | ||||||
|  | #define HAL_PCD_MODULE_ENABLED | ||||||
|  | #define HAL_HCD_MODULE_ENABLED | ||||||
|  | #define HAL_FMPI2C_MODULE_ENABLED | ||||||
|  | #define HAL_SPDIFRX_MODULE_ENABLED | ||||||
|  | #define HAL_DFSDM_MODULE_ENABLED | ||||||
|  | #define HAL_LPTIM_MODULE_ENABLED | ||||||
|  | #define HAL_MMC_MODULE_ENABLED | ||||||
|  | 
 | ||||||
|  | /* ########################## HSE/HSI Values adaptation ##################### */ | ||||||
|  | /**
 | ||||||
|  |   * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. | ||||||
|  |   *        This value is used by the RCC HAL module to compute the system frequency | ||||||
|  |   *        (when HSE is used as system clock source, directly or through the PLL).   | ||||||
|  |   */ | ||||||
|  | #if !defined  (HSE_VALUE)  | ||||||
|  |   #define HSE_VALUE              25000000U /*!< Value of the External oscillator in Hz */ | ||||||
|  | #endif /* HSE_VALUE */ | ||||||
|  | 
 | ||||||
|  | #if !defined  (HSE_STARTUP_TIMEOUT) | ||||||
|  |   #define HSE_STARTUP_TIMEOUT    100U      /*!< Time out for HSE start up, in ms */ | ||||||
|  | #endif /* HSE_STARTUP_TIMEOUT */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief Internal High Speed oscillator (HSI) value. | ||||||
|  |   *        This value is used by the RCC HAL module to compute the system frequency | ||||||
|  |   *        (when HSI is used as system clock source, directly or through the PLL).  | ||||||
|  |   */ | ||||||
|  | #if !defined  (HSI_VALUE) | ||||||
|  |   #define HSI_VALUE              16000000U /*!< Value of the Internal oscillator in Hz */ | ||||||
|  | #endif /* HSI_VALUE */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief Internal Low Speed oscillator (LSI) value. | ||||||
|  |   */ | ||||||
|  | #if !defined  (LSI_VALUE)  | ||||||
|  |  #define LSI_VALUE               32000U    /*!< LSI Typical Value in Hz */ | ||||||
|  | #endif /* LSI_VALUE */                     /*!< Value of the Internal Low Speed oscillator in Hz | ||||||
|  |                                                 The real value may vary depending on the variations | ||||||
|  |                                                 in voltage and temperature. */ | ||||||
|  | /**
 | ||||||
|  |   * @brief External Low Speed oscillator (LSE) value. | ||||||
|  |   */ | ||||||
|  | #if !defined  (LSE_VALUE) | ||||||
|  |  #define LSE_VALUE               32768U    /*!< Value of the External Low Speed oscillator in Hz */ | ||||||
|  | #endif /* LSE_VALUE */ | ||||||
|  | 
 | ||||||
|  | #if !defined  (LSE_STARTUP_TIMEOUT) | ||||||
|  |   #define LSE_STARTUP_TIMEOUT    5000U     /*!< Time out for LSE start up, in ms */ | ||||||
|  | #endif /* LSE_STARTUP_TIMEOUT */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * @brief External clock source for I2S peripheral | ||||||
|  |   *        This value is used by the I2S HAL module to compute the I2S clock source  | ||||||
|  |   *        frequency, this source is inserted directly through I2S_CKIN pad.  | ||||||
|  |   */ | ||||||
|  | #if !defined  (EXTERNAL_CLOCK_VALUE) | ||||||
|  |   #define EXTERNAL_CLOCK_VALUE     12288000U /*!< Value of the External oscillator in Hz*/ | ||||||
|  | #endif /* EXTERNAL_CLOCK_VALUE */ | ||||||
|  | 
 | ||||||
|  | /* Tip: To avoid modifying this file each time you need to use different HSE,
 | ||||||
|  |    ===  you can define the HSE value in your toolchain compiler preprocessor. */ | ||||||
|  | 
 | ||||||
|  | /* ########################### System Configuration ######################### */ | ||||||
|  | /**
 | ||||||
|  |   * @brief This is the HAL system configuration section | ||||||
|  |   */      | ||||||
|  | #define  VDD_VALUE                    3300U /*!< Value of VDD in mv */ | ||||||
|  | #define  TICK_INT_PRIORITY            0x0FU /*!< tick interrupt priority */ | ||||||
|  | #define  USE_RTOS                     0U | ||||||
|  | #define  PREFETCH_ENABLE              1U | ||||||
|  | #define  INSTRUCTION_CACHE_ENABLE     1U | ||||||
|  | #define  DATA_CACHE_ENABLE            1U | ||||||
|  | 
 | ||||||
|  | #define  USE_HAL_ADC_REGISTER_CALLBACKS         0U /* ADC register callback disabled       */ | ||||||
|  | #define  USE_HAL_CAN_REGISTER_CALLBACKS         0U /* CAN register callback disabled       */ | ||||||
|  | #define  USE_HAL_CEC_REGISTER_CALLBACKS         0U /* CEC register callback disabled       */ | ||||||
|  | #define  USE_HAL_CRYP_REGISTER_CALLBACKS        0U /* CRYP register callback disabled      */ | ||||||
|  | #define  USE_HAL_DAC_REGISTER_CALLBACKS         0U /* DAC register callback disabled       */ | ||||||
|  | #define  USE_HAL_DCMI_REGISTER_CALLBACKS        0U /* DCMI register callback disabled      */ | ||||||
|  | #define  USE_HAL_DFSDM_REGISTER_CALLBACKS       0U /* DFSDM register callback disabled     */ | ||||||
|  | #define  USE_HAL_DMA2D_REGISTER_CALLBACKS       0U /* DMA2D register callback disabled     */ | ||||||
|  | #define  USE_HAL_DSI_REGISTER_CALLBACKS         0U /* DSI register callback disabled       */ | ||||||
|  | #define  USE_HAL_ETH_REGISTER_CALLBACKS         0U /* ETH register callback disabled       */ | ||||||
|  | #define  USE_HAL_HASH_REGISTER_CALLBACKS        0U /* HASH register callback disabled      */ | ||||||
|  | #define  USE_HAL_HCD_REGISTER_CALLBACKS         0U /* HCD register callback disabled       */ | ||||||
|  | #define  USE_HAL_I2C_REGISTER_CALLBACKS         0U /* I2C register callback disabled       */ | ||||||
|  | #define  USE_HAL_FMPI2C_REGISTER_CALLBACKS      0U /* FMPI2C register callback disabled    */ | ||||||
|  | #define  USE_HAL_I2S_REGISTER_CALLBACKS         0U /* I2S register callback disabled       */ | ||||||
|  | #define  USE_HAL_IRDA_REGISTER_CALLBACKS        0U /* IRDA register callback disabled      */ | ||||||
|  | #define  USE_HAL_LPTIM_REGISTER_CALLBACKS       0U /* LPTIM register callback disabled     */ | ||||||
|  | #define  USE_HAL_LTDC_REGISTER_CALLBACKS        0U /* LTDC register callback disabled      */ | ||||||
|  | #define  USE_HAL_MMC_REGISTER_CALLBACKS         0U /* MMC register callback disabled       */ | ||||||
|  | #define  USE_HAL_NAND_REGISTER_CALLBACKS        0U /* NAND register callback disabled      */ | ||||||
|  | #define  USE_HAL_NOR_REGISTER_CALLBACKS         0U /* NOR register callback disabled       */ | ||||||
|  | #define  USE_HAL_PCCARD_REGISTER_CALLBACKS      0U /* PCCARD register callback disabled    */ | ||||||
|  | #define  USE_HAL_PCD_REGISTER_CALLBACKS         0U /* PCD register callback disabled       */ | ||||||
|  | #define  USE_HAL_QSPI_REGISTER_CALLBACKS        0U /* QSPI register callback disabled      */ | ||||||
|  | #define  USE_HAL_RNG_REGISTER_CALLBACKS         0U /* RNG register callback disabled       */ | ||||||
|  | #define  USE_HAL_RTC_REGISTER_CALLBACKS         0U /* RTC register callback disabled       */ | ||||||
|  | #define  USE_HAL_SAI_REGISTER_CALLBACKS         0U /* SAI register callback disabled       */ | ||||||
|  | #define  USE_HAL_SD_REGISTER_CALLBACKS          0U /* SD register callback disabled        */ | ||||||
|  | #define  USE_HAL_SMARTCARD_REGISTER_CALLBACKS   0U /* SMARTCARD register callback disabled */ | ||||||
|  | #define  USE_HAL_SDRAM_REGISTER_CALLBACKS       0U /* SDRAM register callback disabled     */ | ||||||
|  | #define  USE_HAL_SRAM_REGISTER_CALLBACKS        0U /* SRAM register callback disabled      */ | ||||||
|  | #define  USE_HAL_SPDIFRX_REGISTER_CALLBACKS     0U /* SPDIFRX register callback disabled   */ | ||||||
|  | #define  USE_HAL_SMBUS_REGISTER_CALLBACKS       0U /* SMBUS register callback disabled     */ | ||||||
|  | #define  USE_HAL_SPI_REGISTER_CALLBACKS         0U /* SPI register callback disabled       */ | ||||||
|  | #define  USE_HAL_TIM_REGISTER_CALLBACKS         0U /* TIM register callback disabled       */ | ||||||
|  | #define  USE_HAL_UART_REGISTER_CALLBACKS        0U /* UART register callback disabled      */ | ||||||
|  | #define  USE_HAL_USART_REGISTER_CALLBACKS       0U /* USART register callback disabled     */ | ||||||
|  | #define  USE_HAL_WWDG_REGISTER_CALLBACKS        0U /* WWDG register callback disabled      */ | ||||||
|  | 
 | ||||||
|  | /* ########################## Assert Selection ############################## */ | ||||||
|  | /**
 | ||||||
|  |   * @brief Uncomment the line below to expanse the "assert_param" macro in the  | ||||||
|  |   *        HAL drivers code | ||||||
|  |   */ | ||||||
|  | /* #define USE_FULL_ASSERT    1U */ | ||||||
|  | 
 | ||||||
|  | /* ################## Ethernet peripheral configuration ##################### */ | ||||||
|  | 
 | ||||||
|  | /* Section 1 : Ethernet peripheral configuration */ | ||||||
|  | 
 | ||||||
|  | /* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ | ||||||
|  | #define MAC_ADDR0   2U | ||||||
|  | #define MAC_ADDR1   0U | ||||||
|  | #define MAC_ADDR2   0U | ||||||
|  | #define MAC_ADDR3   0U | ||||||
|  | #define MAC_ADDR4   0U | ||||||
|  | #define MAC_ADDR5   0U | ||||||
|  | 
 | ||||||
|  | /* Definition of the Ethernet driver buffers size and count */    | ||||||
|  | #define ETH_RX_BUF_SIZE                ETH_MAX_PACKET_SIZE /* buffer size for receive               */ | ||||||
|  | #define ETH_TX_BUF_SIZE                ETH_MAX_PACKET_SIZE /* buffer size for transmit              */ | ||||||
|  | #define ETH_RXBUFNB                    4U                  /* 4 Rx buffers of size ETH_RX_BUF_SIZE  */ | ||||||
|  | #define ETH_TXBUFNB                    4U                  /* 4 Tx buffers of size ETH_TX_BUF_SIZE  */ | ||||||
|  | 
 | ||||||
|  | /* Section 2: PHY configuration section */ | ||||||
|  | 
 | ||||||
|  | /* DP83848 PHY Address*/  | ||||||
|  | #define DP83848_PHY_ADDRESS             0x01U | ||||||
|  | /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/  | ||||||
|  | #define PHY_RESET_DELAY                 0x000000FFU | ||||||
|  | /* PHY Configuration delay */ | ||||||
|  | #define PHY_CONFIG_DELAY                0x00000FFFU | ||||||
|  | 
 | ||||||
|  | #define PHY_READ_TO                     0x0000FFFFU | ||||||
|  | #define PHY_WRITE_TO                    0x0000FFFFU | ||||||
|  | 
 | ||||||
|  | /* Section 3: Common PHY Registers */ | ||||||
|  | 
 | ||||||
|  | #define PHY_BCR                         ((uint16_t)0x0000)  /*!< Transceiver Basic Control Register   */ | ||||||
|  | #define PHY_BSR                         ((uint16_t)0x0001)  /*!< Transceiver Basic Status Register    */ | ||||||
|  |   | ||||||
|  | #define PHY_RESET                       ((uint16_t)0x8000)  /*!< PHY Reset */ | ||||||
|  | #define PHY_LOOPBACK                    ((uint16_t)0x4000)  /*!< Select loop-back mode */ | ||||||
|  | #define PHY_FULLDUPLEX_100M             ((uint16_t)0x2100)  /*!< Set the full-duplex mode at 100 Mb/s */ | ||||||
|  | #define PHY_HALFDUPLEX_100M             ((uint16_t)0x2000)  /*!< Set the half-duplex mode at 100 Mb/s */ | ||||||
|  | #define PHY_FULLDUPLEX_10M              ((uint16_t)0x0100)  /*!< Set the full-duplex mode at 10 Mb/s  */ | ||||||
|  | #define PHY_HALFDUPLEX_10M              ((uint16_t)0x0000)  /*!< Set the half-duplex mode at 10 Mb/s  */ | ||||||
|  | #define PHY_AUTONEGOTIATION             ((uint16_t)0x1000)  /*!< Enable auto-negotiation function     */ | ||||||
|  | #define PHY_RESTART_AUTONEGOTIATION     ((uint16_t)0x0200)  /*!< Restart auto-negotiation function    */ | ||||||
|  | #define PHY_POWERDOWN                   ((uint16_t)0x0800)  /*!< Select the power down mode           */ | ||||||
|  | #define PHY_ISOLATE                     ((uint16_t)0x0400)  /*!< Isolate PHY from MII                 */ | ||||||
|  | 
 | ||||||
|  | #define PHY_AUTONEGO_COMPLETE           ((uint16_t)0x0020)  /*!< Auto-Negotiation process completed   */ | ||||||
|  | #define PHY_LINKED_STATUS               ((uint16_t)0x0004)  /*!< Valid link established               */ | ||||||
|  | #define PHY_JABBER_DETECTION            ((uint16_t)0x0002)  /*!< Jabber condition detected            */ | ||||||
|  |    | ||||||
|  | /* Section 4: Extended PHY Registers */ | ||||||
|  | 
 | ||||||
|  | #define PHY_SR                          ((uint16_t)0x0010)  /*!< PHY status register Offset                      */ | ||||||
|  | #define PHY_MICR                        ((uint16_t)0x0011)  /*!< MII Interrupt Control Register                  */ | ||||||
|  | #define PHY_MISR                        ((uint16_t)0x0012)  /*!< MII Interrupt Status and Misc. Control Register */ | ||||||
|  |   | ||||||
|  | #define PHY_LINK_STATUS                 ((uint16_t)0x0001)  /*!< PHY Link mask                                   */ | ||||||
|  | #define PHY_SPEED_STATUS                ((uint16_t)0x0002)  /*!< PHY Speed mask                                  */ | ||||||
|  | #define PHY_DUPLEX_STATUS               ((uint16_t)0x0004)  /*!< PHY Duplex mask                                 */ | ||||||
|  | 
 | ||||||
|  | #define PHY_MICR_INT_EN                 ((uint16_t)0x0002)  /*!< PHY Enable interrupts                           */ | ||||||
|  | #define PHY_MICR_INT_OE                 ((uint16_t)0x0001)  /*!< PHY Enable output interrupt events              */ | ||||||
|  | 
 | ||||||
|  | #define PHY_MISR_LINK_INT_EN            ((uint16_t)0x0020)  /*!< Enable Interrupt on change of link status       */ | ||||||
|  | #define PHY_LINK_INTERRUPT              ((uint16_t)0x2000)  /*!< PHY link status interrupt mask                  */ | ||||||
|  | 
 | ||||||
|  | /* ################## SPI peripheral configuration ########################## */ | ||||||
|  | 
 | ||||||
|  | /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
 | ||||||
|  | * Activated: CRC code is present inside driver | ||||||
|  | * Deactivated: CRC code cleaned from driver | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define USE_SPI_CRC                     1U | ||||||
|  | 
 | ||||||
|  | /* Includes ------------------------------------------------------------------*/ | ||||||
|  | /**
 | ||||||
|  |   * @brief Include module's header file  | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_RCC_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_rcc.h" | ||||||
|  | #endif /* HAL_RCC_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_GPIO_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_gpio.h" | ||||||
|  | #endif /* HAL_GPIO_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_EXTI_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_exti.h" | ||||||
|  | #endif /* HAL_EXTI_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_DMA_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_dma.h" | ||||||
|  | #endif /* HAL_DMA_MODULE_ENABLED */ | ||||||
|  |     | ||||||
|  | #ifdef HAL_CORTEX_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_cortex.h" | ||||||
|  | #endif /* HAL_CORTEX_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_ADC_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_adc.h" | ||||||
|  | #endif /* HAL_ADC_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_CAN_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_can.h" | ||||||
|  | #endif /* HAL_CAN_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_CAN_LEGACY_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_can_legacy.h" | ||||||
|  | #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_CRC_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_crc.h" | ||||||
|  | #endif /* HAL_CRC_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_CRYP_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_cryp.h"  | ||||||
|  | #endif /* HAL_CRYP_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_DMA2D_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_dma2d.h" | ||||||
|  | #endif /* HAL_DMA2D_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_DAC_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_dac.h" | ||||||
|  | #endif /* HAL_DAC_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_DCMI_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_dcmi.h" | ||||||
|  | #endif /* HAL_DCMI_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_ETH_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_eth.h" | ||||||
|  | #endif /* HAL_ETH_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_FLASH_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_flash.h" | ||||||
|  | #endif /* HAL_FLASH_MODULE_ENABLED */ | ||||||
|  |   | ||||||
|  | #ifdef HAL_SRAM_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_sram.h" | ||||||
|  | #endif /* HAL_SRAM_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_NOR_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_nor.h" | ||||||
|  | #endif /* HAL_NOR_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_NAND_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_nand.h" | ||||||
|  | #endif /* HAL_NAND_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_PCCARD_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_pccard.h" | ||||||
|  | #endif /* HAL_PCCARD_MODULE_ENABLED */  | ||||||
|  |    | ||||||
|  | #ifdef HAL_SDRAM_MODULE_ENABLED | ||||||
|  |   #include "stm32f4xx_hal_sdram.h" | ||||||
|  | #endif /* HAL_SDRAM_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_HASH_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_hash.h" | ||||||
|  | #endif /* HAL_HASH_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_I2C_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_i2c.h" | ||||||
|  | #endif /* HAL_I2C_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_SMBUS_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_smbus.h" | ||||||
|  | #endif /* HAL_SMBUS_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_I2S_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_i2s.h" | ||||||
|  | #endif /* HAL_I2S_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_IWDG_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_iwdg.h" | ||||||
|  | #endif /* HAL_IWDG_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_LTDC_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_ltdc.h" | ||||||
|  | #endif /* HAL_LTDC_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_PWR_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_pwr.h" | ||||||
|  | #endif /* HAL_PWR_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_RNG_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_rng.h" | ||||||
|  | #endif /* HAL_RNG_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_RTC_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_rtc.h" | ||||||
|  | #endif /* HAL_RTC_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_SAI_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_sai.h" | ||||||
|  | #endif /* HAL_SAI_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_SD_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_sd.h" | ||||||
|  | #endif /* HAL_SD_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_SPI_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_spi.h" | ||||||
|  | #endif /* HAL_SPI_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_TIM_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_tim.h" | ||||||
|  | #endif /* HAL_TIM_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_UART_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_uart.h" | ||||||
|  | #endif /* HAL_UART_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_USART_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_usart.h" | ||||||
|  | #endif /* HAL_USART_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_IRDA_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_irda.h" | ||||||
|  | #endif /* HAL_IRDA_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_SMARTCARD_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_smartcard.h" | ||||||
|  | #endif /* HAL_SMARTCARD_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_WWDG_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_wwdg.h" | ||||||
|  | #endif /* HAL_WWDG_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_PCD_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_pcd.h" | ||||||
|  | #endif /* HAL_PCD_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_HCD_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_hcd.h" | ||||||
|  | #endif /* HAL_HCD_MODULE_ENABLED */ | ||||||
|  |     | ||||||
|  | #ifdef HAL_DSI_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_dsi.h" | ||||||
|  | #endif /* HAL_DSI_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_QSPI_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_qspi.h" | ||||||
|  | #endif /* HAL_QSPI_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_CEC_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_cec.h" | ||||||
|  | #endif /* HAL_CEC_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_FMPI2C_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_fmpi2c.h" | ||||||
|  | #endif /* HAL_FMPI2C_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_SPDIFRX_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_spdifrx.h" | ||||||
|  | #endif /* HAL_SPDIFRX_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_DFSDM_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_dfsdm.h" | ||||||
|  | #endif /* HAL_DFSDM_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_LPTIM_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_lptim.h" | ||||||
|  | #endif /* HAL_LPTIM_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | #ifdef HAL_MMC_MODULE_ENABLED | ||||||
|  |  #include "stm32f4xx_hal_mmc.h" | ||||||
|  | #endif /* HAL_MMC_MODULE_ENABLED */ | ||||||
|  | 
 | ||||||
|  | /* Exported macro ------------------------------------------------------------*/ | ||||||
|  | #ifdef  USE_FULL_ASSERT | ||||||
|  | /**
 | ||||||
|  |   * @brief  The assert_param macro is used for function's parameters check. | ||||||
|  |   * @param  expr If expr is false, it calls assert_failed function | ||||||
|  |   *         which reports the name of the source file and the source | ||||||
|  |   *         line number of the call that failed.  | ||||||
|  |   *         If expr is true, it returns no value. | ||||||
|  |   * @retval None | ||||||
|  |   */ | ||||||
|  |   #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) | ||||||
|  | /* Exported functions ------------------------------------------------------- */ | ||||||
|  |   void assert_failed(uint8_t* file, uint32_t line); | ||||||
|  | #else | ||||||
|  |   #define assert_param(expr) ((void)0U) | ||||||
|  | #endif /* USE_FULL_ASSERT */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* __STM32F4xx_HAL_CONF_H */ | ||||||
|  |   | ||||||
|  | 
 | ||||||
|  | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ | ||||||
							
								
								
									
										651
									
								
								assignment_3/Libraries/drivers/thermostat_shield.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										651
									
								
								assignment_3/Libraries/drivers/thermostat_shield.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,651 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file | ||||||
|  |  *    thermostat_shield.c | ||||||
|  |  * \brief | ||||||
|  |  *    Nucleo thermostat shield port file. This file contain the implementation of driver | ||||||
|  |  *    calls for the shield. | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  */ | ||||||
|  | #include "thermostat_shield.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== Digital I/O =============== | ||||||
|  |  */ | ||||||
|  | static void SHIELD_LCD_Port_Init (void); | ||||||
|  | static void SHIELD_LED_Port_Init (void); | ||||||
|  | static void SHIELD_BRIDGE_Port_Init (void); | ||||||
|  | static void SHIELD_SR04_Port_Init (void); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== LCD =============== | ||||||
|  |  * LCD_BD4  -- D8  -- PA9 | ||||||
|  |  * LCD_BD5  -- D7  -- PA8 | ||||||
|  |  * LCD_BD6  -- D6  -- PB10 | ||||||
|  |  * LCD_BD7  -- D5  -- PB4 | ||||||
|  |  * LCD_RS   -- D15 -- PB8 | ||||||
|  |  * LCD_EN   -- D14 -- PB9 | ||||||
|  |  * LCD_BL   -- D2  -- PA10 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * LCD pin Initialize | ||||||
|  |  */ | ||||||
|  | static void SHIELD_LCD_Port_Init (void) { | ||||||
|  |    GPIO_InitTypeDef  GPIO_InitType; | ||||||
|  | 
 | ||||||
|  |    __HAL_RCC_GPIOA_CLK_ENABLE (); | ||||||
|  |    __HAL_RCC_GPIOB_CLK_ENABLE (); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitType.Mode  = GPIO_MODE_OUTPUT_PP; | ||||||
|  |    GPIO_InitType.Speed = GPIO_SPEED_LOW; | ||||||
|  |    GPIO_InitType.Pin   = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10; | ||||||
|  |    HAL_GPIO_Init(GPIOA, &GPIO_InitType); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitType.Pin   = GPIO_PIN_4 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10; | ||||||
|  |    HAL_GPIO_Init(GPIOB, &GPIO_InitType); | ||||||
|  | } | ||||||
|  | void SHIELD_LCD_DB4 (uint8_t en) { _DOUTx(GPIOA, GPIO_PIN_9, en); } | ||||||
|  | void SHIELD_LCD_DB5 (uint8_t en) { _DOUTx(GPIOA, GPIO_PIN_8, en); } | ||||||
|  | void SHIELD_LCD_DB6 (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_10, en); } | ||||||
|  | void SHIELD_LCD_DB7 (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_4, en); } | ||||||
|  | void SHIELD_LCD_RS (uint8_t en)  { _DOUTx(GPIOB, GPIO_PIN_8, en); } | ||||||
|  | void SHIELD_LCD_EN (uint8_t en)  { _DOUTx(GPIOB, GPIO_PIN_9, en); } | ||||||
|  | void SHIELD_LCD_BL (uint8_t en)  { _DOUTx(GPIOA, GPIO_PIN_10, en); } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== LED =============== | ||||||
|  |  * LED0 -- D4 -- PB5 | ||||||
|  |  * LED1 -- D3 -- PB3 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * LED pin initialize | ||||||
|  |  */ | ||||||
|  | static void SHIELD_LED_Port_Init (void) { | ||||||
|  |    GPIO_InitTypeDef  GPIO_InitType; | ||||||
|  | 
 | ||||||
|  |    __HAL_RCC_GPIOB_CLK_ENABLE (); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitType.Mode  = GPIO_MODE_OUTPUT_PP; | ||||||
|  |    GPIO_InitType.Speed = GPIO_SPEED_LOW; | ||||||
|  |    GPIO_InitType.Pin   = GPIO_PIN_3 | GPIO_PIN_5; | ||||||
|  |    HAL_GPIO_Init(GPIOB, &GPIO_InitType); | ||||||
|  | } | ||||||
|  | void SHIELD_LED0 (uint8_t on) { _DOUTx(GPIOB, GPIO_PIN_5, on); } | ||||||
|  | void SHIELD_LED1 (uint8_t on) { _DOUTx(GPIOB, GPIO_PIN_3, on); } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== BRIDGE =============== | ||||||
|  |  * BR1 -- D10 -- PB6 | ||||||
|  |  * BR2 -- D9  -- PC7 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * H-Bridge pin initialize | ||||||
|  |  */ | ||||||
|  | static void SHIELD_BRIDGE_Port_Init (void) { | ||||||
|  |    GPIO_InitTypeDef  GPIO_InitType; | ||||||
|  | 
 | ||||||
|  |    __HAL_RCC_GPIOB_CLK_ENABLE (); | ||||||
|  |    __HAL_RCC_GPIOC_CLK_ENABLE (); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitType.Mode  = GPIO_MODE_OUTPUT_PP; | ||||||
|  |    GPIO_InitType.Speed = GPIO_SPEED_LOW; | ||||||
|  |    GPIO_InitType.Pin   = GPIO_PIN_6; | ||||||
|  |    HAL_GPIO_Init(GPIOB, &GPIO_InitType); | ||||||
|  |    GPIO_InitType.Pin   = GPIO_PIN_7; | ||||||
|  |    HAL_GPIO_Init(GPIOC, &GPIO_InitType); | ||||||
|  | } | ||||||
|  | void SHIELD_BR1 (uint8_t on)  { _DOUTx(GPIOB, GPIO_PIN_6, on); } | ||||||
|  | void SHIELD_BR2 (uint8_t on)  { _DOUTx(GPIOC, GPIO_PIN_7, on); } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  =============== SR04 =============== | ||||||
|  |  *  TRIG -- D11 -- PA7 | ||||||
|  |  *  ECHO -- D12 -- PA6 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * SR04 pin initialize | ||||||
|  |  */ | ||||||
|  | static void SHIELD_SR04_Port_Init (void) { | ||||||
|  |    GPIO_InitTypeDef  GPIO_InitType; | ||||||
|  | 
 | ||||||
|  |    __HAL_RCC_GPIOA_CLK_ENABLE (); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitType.Mode  = GPIO_MODE_OUTPUT_PP; | ||||||
|  |    GPIO_InitType.Speed = GPIO_SPEED_LOW; | ||||||
|  |    GPIO_InitType.Pin   = GPIO_PIN_7; | ||||||
|  |    HAL_GPIO_Init(GPIOA, &GPIO_InitType); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitType.Mode = GPIO_MODE_INPUT; | ||||||
|  |    GPIO_InitType.Pull = GPIO_NOPULL; | ||||||
|  |    GPIO_InitType.Pin  = GPIO_PIN_6; | ||||||
|  |    HAL_GPIO_Init(GPIOA, &GPIO_InitType); | ||||||
|  | } | ||||||
|  | void SHIELD_TRIG (uint8_t on) { _DOUTx(GPIOA, GPIO_PIN_7, on); } | ||||||
|  | uint8_t SHIELD_ECHO (void)    { return _DINx (GPIOA, GPIO_PIN_6); } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============= 1 Wire UART6 (AF08)=============== | ||||||
|  |  *  1W_Tx   -- PA11 (OD+PU) | ||||||
|  |  *  1W_Rx   -- PA12 (I) | ||||||
|  |  */ | ||||||
|  | static UART_HandleTypeDef h1w_uart;    //!< 1-wire uart handle
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    This function handles UART Communication Timeout. | ||||||
|  |  * \param  huart:    Pointer to a UART_HandleTypeDef structure that contains | ||||||
|  |  *                   the configuration information for the specified UART module. | ||||||
|  |  * \param  Flag:     specifies the UART flag to check. | ||||||
|  |  * \param  Status:   The new Flag status (SET or RESET). | ||||||
|  |  * \param  Timeout:  Timeout duration | ||||||
|  |  * \return           HAL status | ||||||
|  |  */ | ||||||
|  | static HAL_StatusTypeDef _WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) { | ||||||
|  |   uint32_t tickstart = HAL_GetTick(); | ||||||
|  | 
 | ||||||
|  |   if (Status != RESET)  Status = SET;  /* Catch wrong Status */ | ||||||
|  | 
 | ||||||
|  |   /* Wait until flag is on FlagStatus Status */ | ||||||
|  |   while (__HAL_UART_GET_FLAG (huart, Flag) == Status) { | ||||||
|  |      if ((Timeout == 0) || ((HAL_GetTick() - tickstart ) > Timeout)) { | ||||||
|  |        /* Give up */ | ||||||
|  |        huart->gState= HAL_UART_STATE_READY;  /* Mark Timeout as ready */ | ||||||
|  |        __HAL_UNLOCK (huart);                 /* Process Unlocked */ | ||||||
|  |        return HAL_TIMEOUT;                   /* Return the TIMEOUT */ | ||||||
|  |      } | ||||||
|  |   } | ||||||
|  |   return HAL_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Initialize 1-Wire UART to 8bits, no parity, 1 stop, so it can | ||||||
|  |  *    be used for 1-Wire communication | ||||||
|  |  * \return  The status of the operation | ||||||
|  |  *    \arg  LLD_OK      Success | ||||||
|  |  *    \arg  LLD_ERROR   The Init failed. | ||||||
|  |  */ | ||||||
|  | static LLD_Status_en _1W_UART_Init (void) { | ||||||
|  |    _1WIRE_UART_CLK_ENABLE (); // Enable 1-wire's USART clock
 | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |     * USART configured as follows: | ||||||
|  |     *  - Word Length = 8 Bits | ||||||
|  |     *  - Stop Bit    = One Stop bit | ||||||
|  |     *  - Parity      = No parity | ||||||
|  |     *  - BaudRate    = _1WIRE_UART_INIT_BR baud | ||||||
|  |     *  - Hardware flow control disabled (RTS and CTS signals) | ||||||
|  |     */ | ||||||
|  |    h1w_uart.Instance        = _1WIRE_UART_INSTANCE; | ||||||
|  |    h1w_uart.Init.BaudRate   = _1WIRE_UART_INIT_BR; | ||||||
|  |    h1w_uart.Init.WordLength = UART_WORDLENGTH_8B; | ||||||
|  |    h1w_uart.Init.StopBits   = UART_STOPBITS_1; | ||||||
|  |    h1w_uart.Init.Parity     = UART_PARITY_NONE; | ||||||
|  |    h1w_uart.Init.Mode       = UART_MODE_TX_RX; | ||||||
|  | 
 | ||||||
|  |    if (HAL_UART_Init(&h1w_uart) != HAL_OK) | ||||||
|  |       return LLD_ERROR; | ||||||
|  |    return LLD_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Init the 1wire interface and allocate all resources for it | ||||||
|  |  * \return  The status of the operation | ||||||
|  |  *    \arg  LLD_OK      Success | ||||||
|  |  *    \arg  LLD_ERROR   The Init failed. | ||||||
|  |  */ | ||||||
|  | LLD_Status_en SHIELD_1W_Init (void) { | ||||||
|  |    GPIO_InitTypeDef GPIO_InitStruct; | ||||||
|  | 
 | ||||||
|  |    __HAL_RCC_GPIOA_CLK_ENABLE (); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitStruct.Pin = GPIO_PIN_11; | ||||||
|  |    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; | ||||||
|  |    GPIO_InitStruct.Pull = GPIO_PULLUP; | ||||||
|  |    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; | ||||||
|  |    GPIO_InitStruct.Alternate = GPIO_AF8_USART6; | ||||||
|  |    HAL_GPIO_WritePin (GPIOA, GPIO_InitStruct.Pin, GPIO_PIN_SET); | ||||||
|  |    HAL_GPIO_Init (GPIOA, &GPIO_InitStruct); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitStruct.Pin = GPIO_PIN_12; | ||||||
|  |    //GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 | ||||||
|  |    GPIO_InitStruct.Pull = GPIO_NOPULL; | ||||||
|  |    GPIO_InitStruct.Alternate = GPIO_AF8_USART6; | ||||||
|  |    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; | ||||||
|  |    /*^
 | ||||||
|  |     * Mark as alternate because HAL_GPIO_Init () | ||||||
|  |     * can not configure Input + alternate | ||||||
|  |     */ | ||||||
|  |    HAL_GPIO_Init (GPIOA, &GPIO_InitStruct); | ||||||
|  | 
 | ||||||
|  |    return _1W_UART_Init (); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Set a Baudrate to the UART, to use for 1-Wire communication | ||||||
|  |  * \param   br    The desired baudrate | ||||||
|  |  * \return  The status of the operation (part of toolbox) | ||||||
|  |  *    \arg  DRV_ERROR   Fail | ||||||
|  |  *    \arg  DRV_READY   Success | ||||||
|  |  */ | ||||||
|  | drv_status_en SHIELD_1W_UART_BR (uint32_t br) { | ||||||
|  |    /*
 | ||||||
|  |     * Keep USART configured as already set by Init: | ||||||
|  |     *  - Word Length = 8 Bits | ||||||
|  |     *  - Stop Bit    = One Stop bit | ||||||
|  |     *  - Parity      = No parity | ||||||
|  |     *  - Hardware flow control disabled (RTS and CTS signals) | ||||||
|  |     */ | ||||||
|  |    if (! IS_UART_BAUDRATE (br) ) | ||||||
|  |       return DRV_ERROR; | ||||||
|  |    h1w_uart.Init.BaudRate = br; | ||||||
|  | 
 | ||||||
|  |    /* Check the Over Sampling */ | ||||||
|  |    if(h1w_uart.Init.OverSampling == UART_OVERSAMPLING_8) { | ||||||
|  |       /*------- UART-associated USART registers setting : BRR Configuration ------*/ | ||||||
|  |       if((h1w_uart.Instance == USART1)){ | ||||||
|  |          h1w_uart.Instance->BRR = UART_BRR_SAMPLING8 (HAL_RCC_GetPCLK2Freq(), h1w_uart.Init.BaudRate); | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |          h1w_uart.Instance->BRR = UART_BRR_SAMPLING8 (HAL_RCC_GetPCLK1Freq(), h1w_uart.Init.BaudRate); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else { | ||||||
|  |       /*------- UART-associated USART registers setting : BRR Configuration ------*/ | ||||||
|  |       if((h1w_uart.Instance == USART1)) { | ||||||
|  |          h1w_uart.Instance->BRR = UART_BRR_SAMPLING16 (HAL_RCC_GetPCLK2Freq(), h1w_uart.Init.BaudRate); | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |          h1w_uart.Instance->BRR = UART_BRR_SAMPLING16 (HAL_RCC_GetPCLK1Freq(), h1w_uart.Init.BaudRate); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    return DRV_READY; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Read-Write functionality. We use the following USART configuration. | ||||||
|  |  *       - Word Length = 8 Bits | ||||||
|  |  *       - Stop Bit    = One Stop bit | ||||||
|  |  *       - Parity      = No parity | ||||||
|  |  * \return  The byte received. On failure return 0xFFFF (bus released state) | ||||||
|  |  * \note | ||||||
|  |  *    Due to the nature of the PCB, the received byte is the actual bus | ||||||
|  |  *    condition during the communication frame (time slot) | ||||||
|  |  */ | ||||||
|  | uint16_t SHIELD_1W_RW (uint8_t byte) | ||||||
|  | { | ||||||
|  |    if (h1w_uart.Init.WordLength != UART_WORDLENGTH_8B)   return (uint8_t)0xFFFF; | ||||||
|  |    if (h1w_uart.Init.Parity != UART_PARITY_NONE)         return (uint8_t)0xFFFF; | ||||||
|  | 
 | ||||||
|  |    if (_WaitOnFlagUntilTimeout (&h1w_uart, UART_FLAG_TXE, RESET, _1WIRE_UART_TIMEOUT) != HAL_OK) | ||||||
|  |      return 0x1FF; | ||||||
|  |    WRITE_REG (h1w_uart.Instance->DR, (byte & (uint8_t)0xFF)); | ||||||
|  |    if (_WaitOnFlagUntilTimeout (&h1w_uart, UART_FLAG_TC, RESET, _1WIRE_UART_TIMEOUT) != HAL_OK) | ||||||
|  |       return 0x2FF; | ||||||
|  |    //if (_WaitOnFlagUntilTimeout (&h1w_uart, UART_FLAG_RXNE, RESET, _1WIRE_UART_TIMEOUT) != HAL_OK)
 | ||||||
|  |    //     return 0xFFFF;
 | ||||||
|  |    return (uint8_t)(h1w_uart.Instance->DR & (uint8_t)0x00FF); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Receive functionality. We use USART blocking mode. | ||||||
|  |  * \return  The byte received. On failure return 0xFF (bus released state) | ||||||
|  |  * \note | ||||||
|  |  *    Due to the nature of the PCB, the received byte is the actual bus | ||||||
|  |  *    condition during the communication frame (time slot) | ||||||
|  |  */ | ||||||
|  | uint8_t SHIELD_1W_Rx (void) { | ||||||
|  |    uint8_t rx; | ||||||
|  |    if (HAL_UART_Receive (&h1w_uart, &rx, sizeof (uint8_t), _1WIRE_UART_TIMEOUT) != HAL_OK) | ||||||
|  |       rx = 0xFF; | ||||||
|  |    return rx; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Transmit functionality. We use USART blocking mode. | ||||||
|  |  * \return  The status of transition | ||||||
|  |  *    \arg  0  Success | ||||||
|  |  *    \arg  1  Fail | ||||||
|  |  */ | ||||||
|  | uint8_t SHIELD_1W_Tx (uint8_t byte) { | ||||||
|  |    if (HAL_UART_Transmit (&h1w_uart, &byte, sizeof (uint8_t), _1WIRE_UART_TIMEOUT) != HAL_OK) | ||||||
|  |       return 1; | ||||||
|  |    return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Shield hardware initialization | ||||||
|  |  */ | ||||||
|  | LLD_Status_en SHIELD_Init (void) { | ||||||
|  |    SHIELD_LCD_Port_Init (); | ||||||
|  |    SHIELD_LED_Port_Init (); | ||||||
|  |    SHIELD_BRIDGE_Port_Init (); | ||||||
|  |    SHIELD_SR04_Port_Init (); | ||||||
|  | 
 | ||||||
|  |    SHIELD_1W_Init (); | ||||||
|  |    COM_Init (); | ||||||
|  |    return LLD_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============= Serial console UART2 (AF07)=============== | ||||||
|  |  *  COM_Tx -- PA2 (PP) | ||||||
|  |  *  COM_Rx -- PA3 (I) | ||||||
|  |  */ | ||||||
|  | static UART_HandleTypeDef com_huart;   //!< com uart handle
 | ||||||
|  | static deque08_t  _com_rxq;            //!< deque object
 | ||||||
|  | static byte_t     _com_rxbuffer[COM_BUFFER_SIZE];  //!< buffer for deque
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Called from USART IRQ to put the read character to queue | ||||||
|  |  * \param      Pointer to a UART_HandleTypeDef structure that contains | ||||||
|  |  *             the configuration information for the specified UART module. | ||||||
|  |  * | ||||||
|  |  * \return     The status of the operation | ||||||
|  |  *    \arg     HAL_ERROR      Fail | ||||||
|  |  *    \arg     HAL_OK         Success | ||||||
|  |  */ | ||||||
|  | static HAL_StatusTypeDef _UART_read_data (UART_HandleTypeDef *huart, deque08_t *q) { | ||||||
|  |    uint8_t  r; | ||||||
|  | 
 | ||||||
|  |    __HAL_LOCK(huart);   /*
 | ||||||
|  |                          * We don't try to receive valid data while the USART is | ||||||
|  |                          * locked from transmitter. It's OK ;) | ||||||
|  |                          */ | ||||||
|  | 
 | ||||||
|  |    /* Receive data based on Word length and parity */ | ||||||
|  |    switch (huart->Init.WordLength) { | ||||||
|  |       default: | ||||||
|  |       case UART_WORDLENGTH_8B: | ||||||
|  |          if(huart->Init.Parity == UART_PARITY_NONE) | ||||||
|  |             r = (uint8_t)(huart->Instance->DR & (uint16_t)0x00FF); | ||||||
|  |          else | ||||||
|  |             r = (uint8_t)(huart->Instance->DR & (uint16_t)0x007F); | ||||||
|  |          break; | ||||||
|  |       case UART_WORDLENGTH_9B: | ||||||
|  |          if(huart->Init.Parity == UART_PARITY_NONE) { | ||||||
|  |             r = (uint8_t)(huart->Instance->DR & (uint16_t)0x01FF); | ||||||
|  |             __HAL_UNLOCK(huart); | ||||||
|  |             return HAL_ERROR; | ||||||
|  |             /* Not supported Configuration */ | ||||||
|  |          } else | ||||||
|  |             r = (uint8_t)(huart->Instance->DR & (uint16_t)0x00FF); | ||||||
|  |          break; | ||||||
|  |    } | ||||||
|  |    deque08_push_back (q, r); | ||||||
|  |    /*!<
 | ||||||
|  |     * \note | ||||||
|  |     *    We queue the received bytes. The user application MUST | ||||||
|  |     *    read the queue in a regular basis, or else this IRQ will | ||||||
|  |     *    find queue full and we will have data loss. | ||||||
|  |     */ | ||||||
|  | 
 | ||||||
|  |    __HAL_UNLOCK(huart); | ||||||
|  |    return HAL_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) | ||||||
|  | { | ||||||
|  |    __HAL_UART_CLEAR_PEFLAG (huart); | ||||||
|  |    huart->ErrorCode = HAL_UART_ERROR_NONE; | ||||||
|  |    huart->gState = HAL_UART_STATE_READY; | ||||||
|  |    /*
 | ||||||
|  |     * Clear all the error flag at once, | ||||||
|  |     * Set USART READY for re-start, | ||||||
|  |     * Error Callback | ||||||
|  |     */ | ||||||
|  | } | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    USART serial handler. Pushes every received character to a queue. | ||||||
|  |  * | ||||||
|  |  * In the IRQ handler there is only Rx functionality provided by this driver. | ||||||
|  |  * The Error handling call the HAL's callback (which are empty) | ||||||
|  |  * The Tx part, is not implemented | ||||||
|  |  */ | ||||||
|  | void USART2_IRQHandler (void) { | ||||||
|  |    uint32_t tmp_flag = 0, tmp_it_source = 0; | ||||||
|  | 
 | ||||||
|  |    // ======= Error handler =========
 | ||||||
|  |    if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_PE)) != RESET) && | ||||||
|  |       ((tmp_it_source = __HAL_UART_GET_IT_SOURCE(&com_huart, UART_IT_PE)) != RESET)) { | ||||||
|  |       /* UART parity error interrupt occurred */ | ||||||
|  |       com_huart.ErrorCode |= HAL_UART_ERROR_PE; | ||||||
|  |    } | ||||||
|  |    if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_FE)) != RESET) && | ||||||
|  |       ((tmp_it_source = __HAL_UART_GET_IT_SOURCE(&com_huart, UART_IT_ERR)) != RESET)) { | ||||||
|  |       /* UART frame error interrupt occurred */ | ||||||
|  |       com_huart.ErrorCode |= HAL_UART_ERROR_FE; | ||||||
|  |    } | ||||||
|  |    if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_NE)) != RESET) && | ||||||
|  |        (tmp_it_source != RESET)){ | ||||||
|  |       /* UART noise error interrupt occurred */ | ||||||
|  |       com_huart.ErrorCode |= HAL_UART_ERROR_NE; | ||||||
|  |    } | ||||||
|  |    if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_ORE)) != RESET) && | ||||||
|  |        (tmp_it_source != RESET)){ | ||||||
|  |       /* USART Over-Run interrupt occurred */ | ||||||
|  |       com_huart.ErrorCode |= HAL_UART_ERROR_ORE; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if(com_huart.ErrorCode != HAL_UART_ERROR_NONE) { | ||||||
|  |       HAL_UART_ErrorCallback (&com_huart); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // ====== Get Data =========
 | ||||||
|  |    if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_RXNE)) != RESET) && | ||||||
|  |       ((tmp_it_source = __HAL_UART_GET_IT_SOURCE(&com_huart, UART_IT_RXNE)) != RESET)) { | ||||||
|  |       // Read byte
 | ||||||
|  |       _UART_read_data (&com_huart, &_com_rxq);  // Don't check return status
 | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Initialize the UART and UART IRQ handler | ||||||
|  |  * \return  The status of the operation | ||||||
|  |  *    \arg  LLD_ERROR      Fail | ||||||
|  |  *    \arg  LLD_OK         Success | ||||||
|  |  */ | ||||||
|  | static LLD_Status_en _COM_UART_Init (void) { | ||||||
|  |    /*
 | ||||||
|  |     * Enable UART clock | ||||||
|  |     */ | ||||||
|  |    _COM_CLK_ENABLE(); | ||||||
|  | 
 | ||||||
|  |    deque08_link_buffer (&_com_rxq, _com_rxbuffer); | ||||||
|  |    deque08_set_capacity (&_com_rxq, COM_BUFFER_SIZE); | ||||||
|  |    deque08_init (&_com_rxq); | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |     * USART configured as follows: | ||||||
|  |     *  - Word Length = 8 Bits | ||||||
|  |     *  - Stop Bit    = One Stop bit | ||||||
|  |     *  - Parity      = No parity | ||||||
|  |     *  - BaudRate    = COM_BAUDRATE baud | ||||||
|  |     *  - Hardware flow control disabled (RTS and CTS signals) | ||||||
|  |     */ | ||||||
|  |    com_huart.Instance        = COM_UART_INSTANCE; | ||||||
|  |    com_huart.Init.BaudRate   = COM_UART_BAUDRATE; | ||||||
|  |    com_huart.Init.WordLength = UART_WORDLENGTH_8B; | ||||||
|  |    com_huart.Init.StopBits   = UART_STOPBITS_1; | ||||||
|  |    com_huart.Init.Parity     = UART_PARITY_NONE; | ||||||
|  |    com_huart.Init.Mode       = UART_MODE_TX_RX; | ||||||
|  | 
 | ||||||
|  |    if (HAL_UART_Init(&com_huart) != HAL_OK) | ||||||
|  |       return LLD_ERROR; | ||||||
|  | 
 | ||||||
|  |    /*
 | ||||||
|  |     * Enable IRQ for Rx | ||||||
|  |     * Tx IRQ enabled by COM_transmit () | ||||||
|  |     */ | ||||||
|  |    HAL_NVIC_SetPriority (COM_UART_IRQ, 0x0D, 0); | ||||||
|  |    HAL_NVIC_EnableIRQ (COM_UART_IRQ); | ||||||
|  | 
 | ||||||
|  |    /* Enable the UART Data Register not empty Interrupt */ | ||||||
|  |    __HAL_UART_ENABLE_IT(&com_huart, UART_IT_RXNE); | ||||||
|  |    /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ | ||||||
|  |    //__HAL_UART_ENABLE_IT(&com_huart, UART_IT_ERR);
 | ||||||
|  | 
 | ||||||
|  |    return LLD_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Initialize the COM dedicated I/O and allocate resources | ||||||
|  |  * \return The status of the operation | ||||||
|  |  */ | ||||||
|  | LLD_Status_en COM_Init (void) { | ||||||
|  |    GPIO_InitTypeDef GPIO_InitStruct; | ||||||
|  | 
 | ||||||
|  |    __HAL_RCC_GPIOA_CLK_ENABLE (); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitStruct.Pin = GPIO_PIN_2; | ||||||
|  |    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; | ||||||
|  |    GPIO_InitStruct.Pull = GPIO_NOPULL; | ||||||
|  |    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; | ||||||
|  |    GPIO_InitStruct.Alternate = GPIO_AF7_USART2; | ||||||
|  |    HAL_GPIO_Init (GPIOA, &GPIO_InitStruct); | ||||||
|  | 
 | ||||||
|  |    GPIO_InitStruct.Pin = GPIO_PIN_3; | ||||||
|  |    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; | ||||||
|  | //   GPIO_InitStruct.Pull = GPIO_NOPULL;
 | ||||||
|  | //   GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
 | ||||||
|  |    HAL_GPIO_Init (GPIOA, &GPIO_InitStruct); | ||||||
|  | 
 | ||||||
|  |    return _COM_UART_Init(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Set UART baudrate | ||||||
|  |  * \param   br The desired baudrate | ||||||
|  |  * \return  The status of the operation | ||||||
|  |  *    \arg  LLD_ERROR      Fail | ||||||
|  |  *    \arg  LLD_OK         Success | ||||||
|  |  */ | ||||||
|  | LLD_Status_en COM_baudrate (uint32_t br) { | ||||||
|  |    // Change only the Baudrate
 | ||||||
|  |    com_huart.Init.BaudRate   = br; | ||||||
|  |    if (HAL_UART_Init(&com_huart) != HAL_OK) | ||||||
|  |       return LLD_ERROR; | ||||||
|  |    return LLD_OK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    USART's putchar functionality to link with io system | ||||||
|  |  * This function is compatible with putchar() in "stdio.h" | ||||||
|  |  */ | ||||||
|  | int COM_putchar (char c) { | ||||||
|  |    if (_WaitOnFlagUntilTimeout (&com_huart, UART_FLAG_TC, RESET, COM_UART_PUTCHAR_TIMEOUT) != HAL_OK) | ||||||
|  |      return 0xFFFF; | ||||||
|  |    WRITE_REG (COM_UART_INSTANCE->DR, (c & (uint8_t)0xFF)); | ||||||
|  |    /*!<
 | ||||||
|  |     * \note | ||||||
|  |     *    The sequence: | ||||||
|  |     *    - Read operation to USART_SR register  [USART_GetFlagStatus()] | ||||||
|  |     *    - Write operation to USART_DR register [USART_SendData()] | ||||||
|  |     *    clears the TC Flag | ||||||
|  |     * | ||||||
|  |     *    The TXE Flag is cleared by the write operation to USART_DR register | ||||||
|  |     *    [USART_SendData()] | ||||||
|  |     */ | ||||||
|  |    return (int)c; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    USART's getchar functionality to link with io system | ||||||
|  |  * This function is compatible with getchar() in "stdio.h" | ||||||
|  |  */ | ||||||
|  | int COM_getchar (void) { | ||||||
|  |    clock_t mark = clock (); | ||||||
|  |    clock_t to   = COM_UART_GETCHAR_TIMEOUT*get_freq(); | ||||||
|  |    clock_t now; | ||||||
|  |    byte_t  r=0; | ||||||
|  | 
 | ||||||
|  |    while (deque08_pop_front (&_com_rxq, &r) == 0) { | ||||||
|  |       now = clock (); | ||||||
|  |       if (_CLOCK_DIFF(now, mark) >= to) | ||||||
|  |          return 0; | ||||||
|  |    } | ||||||
|  |    return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Transmit functionality to link with io system | ||||||
|  |  * This function is compatible with htp tx functionality | ||||||
|  |  * | ||||||
|  |  * \param   data  Pointer to data buffer | ||||||
|  |  * \param   size  Size of buffer (number of bytes) | ||||||
|  |  * \return  The number of bytes to transmit | ||||||
|  |  */ | ||||||
|  | int COM_Transmit (uint8_t *data, int size) { | ||||||
|  |    int r = size; | ||||||
|  | 
 | ||||||
|  |    while (size--) { | ||||||
|  |       //queue08_push (&_com_txq, (byte_t)*data);
 | ||||||
|  |       COM_putchar(*data++); | ||||||
|  |    } | ||||||
|  |    _WaitOnFlagUntilTimeout (&com_huart, UART_FLAG_TC, SET, COM_UART_PUTCHAR_TIMEOUT); | ||||||
|  |    return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Check receive functionality synchronized to IRQ | ||||||
|  |  * This function is compatible with htp rx functionality | ||||||
|  |  * | ||||||
|  |  * \return  The number of bytes on queue (<package_size> indicates done) | ||||||
|  |  */ | ||||||
|  | int COM_CheckReceive (void) { | ||||||
|  |    return deque08_size (&_com_rxq); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Receive flush functionality to link with io system | ||||||
|  |  * This function is compatible with htp rx functionality | ||||||
|  |  * | ||||||
|  |  * \param   data  Pointer to data buffer | ||||||
|  |  * \param   size  Size of buffer (number of bytes) | ||||||
|  |  * \return  The number of received bytes | ||||||
|  |  */ | ||||||
|  | void COM_ReceiveFlush (void) { | ||||||
|  |    deque08_flush (&_com_rxq); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * \brief | ||||||
|  |  *    Receive functionality to link with io system | ||||||
|  |  * This function is compatible with htp rx functionality | ||||||
|  |  * | ||||||
|  |  * \param   data  Pointer to data buffer | ||||||
|  |  * \param   size  Size of buffer (number of bytes) | ||||||
|  |  * \return  The number of received bytes | ||||||
|  |  */ | ||||||
|  | int COM_Receive (uint8_t *data, int size) { | ||||||
|  |    int i; | ||||||
|  |    uint8_t r=1, b; | ||||||
|  | 
 | ||||||
|  |    for (i=0 ; r !=0 && i<size ; ++i) { | ||||||
|  |       r = deque08_pop_front (&_com_rxq, &b); | ||||||
|  |       data[i] = b; | ||||||
|  |    } | ||||||
|  |    return i; | ||||||
|  | } | ||||||
							
								
								
									
										124
									
								
								assignment_3/Libraries/drivers/thermostat_shield.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								assignment_3/Libraries/drivers/thermostat_shield.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,124 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file | ||||||
|  |  *    thermostat_shield.h | ||||||
|  |  * \brief | ||||||
|  |  *    Nucleo thermostat shield port file. This file contain the implementation of driver | ||||||
|  |  *    calls for the shield. | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef DRIVERS_THERMOSTAT_SHIELD_H_ | ||||||
|  | #define DRIVERS_THERMOSTAT_SHIELD_H_ | ||||||
|  | 
 | ||||||
|  | #include "NUCLEO_F401RE.h" | ||||||
|  | #include "driver_types.h" | ||||||
|  | #include "deque08.h" | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== Digital I/O =============== | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== LCD =============== | ||||||
|  |  * LCD_BD4  -- D8  -- PA9 | ||||||
|  |  * LCD_BD5  -- D7  -- PA8 | ||||||
|  |  * LCD_BD6  -- D6  -- PB10 | ||||||
|  |  * LCD_BD7  -- D5  -- PB4 | ||||||
|  |  * LCD_RS   -- D15 -- PB8 | ||||||
|  |  * LCD_EN   -- D14 -- PB9 | ||||||
|  |  * LCD_BL   -- D2  -- PA10 | ||||||
|  |  */ | ||||||
|  | void SHIELD_LCD_DB4 (uint8_t en); | ||||||
|  | void SHIELD_LCD_DB5 (uint8_t en); | ||||||
|  | void SHIELD_LCD_DB6 (uint8_t en); | ||||||
|  | void SHIELD_LCD_DB7 (uint8_t en); | ||||||
|  | void SHIELD_LCD_RS (uint8_t en); | ||||||
|  | void SHIELD_LCD_EN (uint8_t en); | ||||||
|  | void SHIELD_LCD_BL (uint8_t en); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== LED =============== | ||||||
|  |  * LED0 -- D4 -- PB5 | ||||||
|  |  * LED1 -- D3 -- PB3 | ||||||
|  |  */ | ||||||
|  | void SHIELD_LED0 (uint8_t on); | ||||||
|  | void SHIELD_LED1 (uint8_t on); | ||||||
|  | 
 | ||||||
|  | #define LED_RED      SHIELD_LED0 | ||||||
|  | #define LED_GREEN    SHIELD_LED1 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * =============== BRIDGE =============== | ||||||
|  |  * BR1 -- D10 -- PB6 | ||||||
|  |  * BR2 -- D9  -- PC7 | ||||||
|  |  */ | ||||||
|  | void SHIELD_BR1 (uint8_t on); | ||||||
|  | void SHIELD_BR2 (uint8_t on); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  *  =============== SR04 =============== | ||||||
|  |  *  TRIG -- D11 -- PA7 | ||||||
|  |  *  ECHO -- D12 -- PA6 | ||||||
|  |  */ | ||||||
|  | void SHIELD_TRIG (uint8_t on); | ||||||
|  | uint8_t SHIELD_ECHO (void); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============= 1 Wire USART6 (AF08)=============== | ||||||
|  |  *  1W_Tx   -- PA11 (OD+PU) | ||||||
|  |  *  1W_Rx   -- PA12 (I) | ||||||
|  |  */ | ||||||
|  | // non-shared resources
 | ||||||
|  | #define  _1WIRE_UART_INSTANCE          (USART6) | ||||||
|  | #define  _1WIRE_UART_INIT_BR           (9600) | ||||||
|  | #define  _1WIRE_UART_TIMEOUT           (10)     /*!< 10msec is good enough */ | ||||||
|  | /*!
 | ||||||
|  |  * Helper Macros linked to USART used | ||||||
|  |  */ | ||||||
|  | #define _1WIRE_UART_CLK_ENABLE       __HAL_RCC_USART6_CLK_ENABLE | ||||||
|  | #define _1WIRE_UART_CLK_DISABLE      __HAL_RCC_USART6_CLK_DISABLE | ||||||
|  | 
 | ||||||
|  | LLD_Status_en SHIELD_1W_Init (void); | ||||||
|  | 
 | ||||||
|  | drv_status_en SHIELD_1W_UART_BR (uint32_t br); | ||||||
|  | uint16_t SHIELD_1W_RW (uint8_t byte); | ||||||
|  | uint8_t  SHIELD_1W_Rx (void); | ||||||
|  | uint8_t  SHIELD_1W_Tx (uint8_t byte); | ||||||
|  | 
 | ||||||
|  | LLD_Status_en SHIELD_Init (void); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * ============= Serial console UART2 (AF07)=============== | ||||||
|  |  *  COM_Tx -- PA2 (PP) | ||||||
|  |  *  COM_Rx -- PA3 (I) | ||||||
|  |  */ | ||||||
|  | #define COM_UART_INSTANCE          USART2 | ||||||
|  | #define COM_UART_IRQ               USART2_IRQn | ||||||
|  | #define COM_UART_BAUDRATE          (57600) | ||||||
|  | #define COM_UART_GETCHAR_TIMEOUT   (5)         // 5sec
 | ||||||
|  | #define COM_UART_PUTCHAR_TIMEOUT   (10)        // 1 [CPU time]
 | ||||||
|  | 
 | ||||||
|  | #define COM_BUFFER_SIZE            (256) | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Helper Macros linked to USART used | ||||||
|  |  */ | ||||||
|  | #define _COM_CLK_ENABLE      __HAL_RCC_USART2_CLK_ENABLE | ||||||
|  | #define _COM_CLK_DISNABLE    __HAL_RCC_USART2_CLK_DISABLE | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | LLD_Status_en COM_Init (void); | ||||||
|  | LLD_Status_en COM_baudrate (uint32_t br); | ||||||
|  | int COM_putchar (char c); | ||||||
|  | int COM_getchar (void); | ||||||
|  | int COM_Transmit (uint8_t *data, int size); | ||||||
|  | int COM_CheckReceive (void); | ||||||
|  | void COM_ReceiveFlush (void); | ||||||
|  | int COM_Receive (uint8_t *data, int size); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* DRIVERS_THERMOSTAT_SHIELD_H_ */ | ||||||
							
								
								
									
										1
									
								
								assignment_3/report/config
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								assignment_3/report/config
									
									
									
									
									
										Submodule
									
								
							| @ -0,0 +1 @@ | |||||||
|  | Subproject commit c27d16e915615bc56a7b09f56e882661ac69b860 | ||||||
							
								
								
									
										
											BIN
										
									
								
								assignment_3/report/images/console.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/report/images/console.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 55 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assignment_3/report/images/shield_pcb.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/report/images/shield_pcb.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 499 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assignment_3/report/images/ui_states.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/report/images/ui_states.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 262 KiB | 
							
								
								
									
										601
									
								
								assignment_3/report/images/ui_states.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										601
									
								
								assignment_3/report/images/ui_states.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,601 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||||
|  | 
 | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    width="210mm" | ||||||
|  |    height="297mm" | ||||||
|  |    viewBox="0 0 210 297" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg8" | ||||||
|  |    inkscape:version="0.92.4 (5da689c313, 2019-01-14)" | ||||||
|  |    sodipodi:docname="ui_states.svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs2"> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0.0" | ||||||
|  |        refX="0.0" | ||||||
|  |        id="Arrow1Lend" | ||||||
|  |        style="overflow:visible;" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          id="path991" | ||||||
|  |          d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " | ||||||
|  |          style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" | ||||||
|  |          transform="scale(0.8) rotate(180) translate(12.5,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lstart" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0.0" | ||||||
|  |        refX="0.0" | ||||||
|  |        id="Arrow1Lstart" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          id="path988" | ||||||
|  |          d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " | ||||||
|  |          style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" | ||||||
|  |          transform="scale(0.8) translate(12.5,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-6" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-0" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-6-1" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-0-3" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-6-2" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-0-9" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-6-2-0" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-0-9-9" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-6-2-5" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-0-9-4" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-6-2-4" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-0-9-3" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-6-2-0-9" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-0-9-9-1" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-9" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-4" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-9-6" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-4-2" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-9-6-9" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-4-2-1" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-9-7" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-4-7" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-9-7-1" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-4-7-9" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-9-7-1-3" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-4-7-9-8" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |     <marker | ||||||
|  |        inkscape:stockid="Arrow1Lend" | ||||||
|  |        orient="auto" | ||||||
|  |        refY="0" | ||||||
|  |        refX="0" | ||||||
|  |        id="Arrow1Lend-9-6-9-4" | ||||||
|  |        style="overflow:visible" | ||||||
|  |        inkscape:isstock="true"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path991-4-2-1-9" | ||||||
|  |          d="M 0,0 5,-5 -12.5,0 5,5 Z" | ||||||
|  |          style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" | ||||||
|  |          transform="matrix(-0.8,0,0,-0.8,-10,0)" /> | ||||||
|  |     </marker> | ||||||
|  |   </defs> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      id="base" | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1.0" | ||||||
|  |      inkscape:pageopacity="0.0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:zoom="0.7" | ||||||
|  |      inkscape:cx="305.44261" | ||||||
|  |      inkscape:cy="594.04646" | ||||||
|  |      inkscape:document-units="mm" | ||||||
|  |      inkscape:current-layer="layer1" | ||||||
|  |      showgrid="false" | ||||||
|  |      inkscape:window-width="1920" | ||||||
|  |      inkscape:window-height="1011" | ||||||
|  |      inkscape:window-x="0" | ||||||
|  |      inkscape:window-y="32" | ||||||
|  |      inkscape:window-maximized="1" /> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata5"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title></dc:title> | ||||||
|  |       </cc:Work> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <g | ||||||
|  |      inkscape:label="Layer 1" | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer1"> | ||||||
|  |     <g | ||||||
|  |        style="stroke-width:1.43562889" | ||||||
|  |        id="g911" | ||||||
|  |        transform="matrix(0.69672537,0,0,0.69639235,43.060245,27.179579)"> | ||||||
|  |       <ellipse | ||||||
|  |          ry="11.496272" | ||||||
|  |          rx="24.379465" | ||||||
|  |          cy="97.585548" | ||||||
|  |          cx="92.793152" | ||||||
|  |          id="path815" | ||||||
|  |          style="fill:none;stroke:#000000;stroke-width:0.71781445;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |       <flowRoot | ||||||
|  |          transform="matrix(0.18461171,0,0,0.18461171,38.065515,17.935472)" | ||||||
|  |          style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.05752659" | ||||||
|  |          id="flowRoot817" | ||||||
|  |          xml:space="preserve"><flowRegion | ||||||
|  |            style="stroke-width:2.05752659" | ||||||
|  |            id="flowRegion819"><rect | ||||||
|  |              style="stroke-width:2.05752659" | ||||||
|  |              y="408.94824" | ||||||
|  |              x="210.71428" | ||||||
|  |              height="219.28572" | ||||||
|  |              width="340.71429" | ||||||
|  |              id="rect821" /></flowRegion><flowPara | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';stroke-width:2.67305756" | ||||||
|  |            id="flowPara823">ST_INIT</flowPara></flowRoot>    </g> | ||||||
|  |     <g | ||||||
|  |        style="stroke-width:1.43562889" | ||||||
|  |        id="g918" | ||||||
|  |        transform="matrix(0.69672537,0,0,0.69639235,54.309168,82.301952)"> | ||||||
|  |       <ellipse | ||||||
|  |          ry="11.496272" | ||||||
|  |          rx="30.33259" | ||||||
|  |          cy="157.90475" | ||||||
|  |          cx="62.271572" | ||||||
|  |          id="path815-9" | ||||||
|  |          style="fill:none;stroke:#000000;stroke-width:0.71781445;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |       <flowRoot | ||||||
|  |          transform="matrix(0.18461171,0,0,0.18461171,1.3854042,78.254686)" | ||||||
|  |          style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.05752659" | ||||||
|  |          id="flowRoot817-0" | ||||||
|  |          xml:space="preserve"><flowRegion | ||||||
|  |            style="stroke-width:2.05752659" | ||||||
|  |            id="flowRegion819-0"><rect | ||||||
|  |              style="stroke-width:2.05752659" | ||||||
|  |              y="408.94824" | ||||||
|  |              x="210.71428" | ||||||
|  |              height="219.28572" | ||||||
|  |              width="340.71429" | ||||||
|  |              id="rect821-2" /></flowRegion><flowPara | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';stroke-width:2.67305756" | ||||||
|  |            id="flowPara823-2">ST_COUNT</flowPara></flowRoot>    </g> | ||||||
|  |     <g | ||||||
|  |        style="stroke-width:1.43562889" | ||||||
|  |        id="g925" | ||||||
|  |        transform="matrix(0.69672537,0,0,0.69639235,50.056064,4.1485435)"> | ||||||
|  |       <ellipse | ||||||
|  |          ry="11.496272" | ||||||
|  |          rx="24.379465" | ||||||
|  |          cy="197.843" | ||||||
|  |          cx="132.29842" | ||||||
|  |          id="path815-6" | ||||||
|  |          style="fill:none;stroke:#000000;stroke-width:0.71781445;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |       <flowRoot | ||||||
|  |          transform="matrix(0.18461171,0,0,0.18461171,74.790787,118.19293)" | ||||||
|  |          style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.05752659" | ||||||
|  |          id="flowRoot817-9" | ||||||
|  |          xml:space="preserve"><flowRegion | ||||||
|  |            style="stroke-width:2.05752659" | ||||||
|  |            id="flowRegion819-03"><rect | ||||||
|  |              style="stroke-width:2.05752659" | ||||||
|  |              y="408.94824" | ||||||
|  |              x="210.71428" | ||||||
|  |              height="219.28572" | ||||||
|  |              width="340.71429" | ||||||
|  |              id="rect821-5" /></flowRegion><flowPara | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';stroke-width:2.67305756" | ||||||
|  |            id="flowPara823-5">ST_USER</flowPara></flowRoot>    </g> | ||||||
|  |     <g | ||||||
|  |        style="stroke-width:1.43562889" | ||||||
|  |        id="g932" | ||||||
|  |        transform="matrix(0.69672537,0,0,0.69639235,-53.783037,38.526733)"> | ||||||
|  |       <ellipse | ||||||
|  |          ry="11.496272" | ||||||
|  |          rx="33.673458" | ||||||
|  |          cy="147.0618" | ||||||
|  |          cx="167.44435" | ||||||
|  |          id="path815-9-8" | ||||||
|  |          style="fill:none;stroke:#000000;stroke-width:0.71781445;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |       <flowRoot | ||||||
|  |          transform="matrix(0.18461171,0,0,0.18461171,101.78244,67.411724)" | ||||||
|  |          style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.05752659" | ||||||
|  |          id="flowRoot817-0-7" | ||||||
|  |          xml:space="preserve"><flowRegion | ||||||
|  |            style="stroke-width:2.05752659" | ||||||
|  |            id="flowRegion819-0-1"><rect | ||||||
|  |              style="stroke-width:2.05752659" | ||||||
|  |              y="408.94824" | ||||||
|  |              x="210.71428" | ||||||
|  |              height="219.28572" | ||||||
|  |              width="340.71429" | ||||||
|  |              id="rect821-2-7" /></flowRegion><flowPara | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';stroke-width:2.67305756" | ||||||
|  |            id="flowPara823-2-0">ST_AVERAGE</flowPara></flowRoot>    </g> | ||||||
|  |     <path | ||||||
|  |        style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)" | ||||||
|  |        d="m 122.93134,66.023775 c -3.65925,1.681276 -3.39681,0.755032 -7.29274,4.00432 -6.63268,5.531786 -8.54054,17.112752 -8.54054,17.112752" | ||||||
|  |        id="path986" | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        sodipodi:nodetypes="csc" /> | ||||||
|  |     <path | ||||||
|  |        style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-9)" | ||||||
|  |        d="m 91.594559,98.052048 c -3.65925,1.68128 -8.717171,3.761652 -16.914443,11.621502 -10.334873,9.90947 -12.282313,22.72541 -12.282313,22.72541" | ||||||
|  |        id="path986-5" | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        sodipodi:nodetypes="csc" /> | ||||||
|  |     <path | ||||||
|  |        style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-9-6)" | ||||||
|  |        d="m 122.0064,99.60807 c 3.62159,1.6499 10.23233,5.15907 15.44446,11.6215 4.95933,6.14898 11.21324,22.72541 11.21324,22.72541" | ||||||
|  |        id="path986-5-5" | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        sodipodi:nodetypes="csc" /> | ||||||
|  |     <path | ||||||
|  |        style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-9-7)" | ||||||
|  |        d="m 77.19729,189.78093 c -3.65925,-1.68128 -9.891429,-3.88611 -13.60715,-11.24353 -5.377559,-10.648 -4.423096,-29.22929 -4.423096,-29.22929" | ||||||
|  |        id="path986-5-4" | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        sodipodi:nodetypes="csc" /> | ||||||
|  |     <path | ||||||
|  |        style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-9-6-9)" | ||||||
|  |        d="m 118.37195,189.72846 c 4.32742,-0.47857 8.96054,-1.33731 18.6517,-11.22059 9.08993,-9.27014 12.41595,-29.00625 12.41595,-29.00625" | ||||||
|  |        id="path986-5-5-1" | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        sodipodi:nodetypes="csc" /> | ||||||
|  |     <path | ||||||
|  |        style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-9-7-1)" | ||||||
|  |        d="m 77.971786,147.26982 c 3.65925,1.68128 7.899204,6.35401 11.339294,12.84994 4.243174,8.01239 5.462526,24.03211 5.462526,24.03211" | ||||||
|  |        id="path986-5-4-1" | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        sodipodi:nodetypes="csc" /> | ||||||
|  |     <path | ||||||
|  |        style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-9-7-1-3)" | ||||||
|  |        d="m 74.663683,133.51806 c 2.750358,-2.45653 16.924642,-8.98074 31.132187,-8.89636 11.57642,0.0688 28.4717,9.76743 28.4717,9.76743" | ||||||
|  |        id="path986-5-4-1-7" | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        sodipodi:nodetypes="csc" /> | ||||||
|  |     <path | ||||||
|  |        style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend-9-6-9-4)" | ||||||
|  |        d="m 130.12937,147.76437 c -4.06015,2.34945 -7.62996,7.43829 -11.30178,14.02692 -4.21244,7.55875 -7.33783,23.66086 -7.33783,23.66086" | ||||||
|  |        id="path986-5-5-1-3" | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        sodipodi:nodetypes="csc" /> | ||||||
|  |     <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,83.615792,43.243707)"><flowRegion | ||||||
|  |          id="flowRegion24700" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702" | ||||||
|  |            width="106.06602" | ||||||
|  |            height="97.984795" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          id="flowPara24704" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355">start</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-8" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,108.63996,81.165381)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-6" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-9" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara24734-0-3">proximity</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-7" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,32.720964,77.378204)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-4" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-3" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara24734-0-7">done</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-8-1" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,33.785864,80.708472)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-6-3" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-9-9" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara24734-0-3-6">measuring</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-8-4" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,70.145367,97.280685)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-6-2" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-9-0" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara24734-0-3-2">proximity</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-8-9" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,111.36366,155.62052)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-6-5" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-9-7" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara24734-0-3-4">proximity</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-7-6" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,22.41547,157.56353)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-4-4" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-3-9" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara24734-0-7-1">done</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-8-1-2" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,23.480368,160.89379)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-6-3-3" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-9-9-1" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara24734-0-3-6-8">measuring</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-8-9-1" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,60.534626,134.15952)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-6-5-3" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-9-7-8" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara24734-0-3-4-9">10 sec</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-7-6-2" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,80.546592,133.6429)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-4-4-4" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-3-9-5" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara25034">lost</flowPara></flowRoot>    <flowRoot | ||||||
|  |        xml:space="preserve" | ||||||
|  |        id="flowRoot24698-5-2-8-9-3" | ||||||
|  |        style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.6914711" | ||||||
|  |        transform="matrix(0.09830435,0,0,0.09830435,79.625403,129.56174)"><flowRegion | ||||||
|  |          id="flowRegion24700-3-8-6-5-0" | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:3.79738355"><rect | ||||||
|  |            id="rect24702-3-5-9-7-0" | ||||||
|  |            width="207.95738" | ||||||
|  |            height="110.4809" | ||||||
|  |            x="244.45691" | ||||||
|  |            y="225.50423" | ||||||
|  |            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial;stroke-width:2.6914711" /></flowRegion><flowPara | ||||||
|  |          style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0;font-family:Arial;-inkscape-font-specification:Arial;text-align:center;letter-spacing:0px;text-anchor:middle;stroke-width:3.79738355" | ||||||
|  |          id="flowPara24734-0-3-4-0">proximity</flowPara></flowRoot>  </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 32 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assignment_3/report/report.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/report/report.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										208
									
								
								assignment_3/report/report.tex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								assignment_3/report/report.tex
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,208 @@ | |||||||
|  | %  | ||||||
|  | % Microprocessors and peripherals 3nd assignement. | ||||||
|  | % | ||||||
|  | % author: | ||||||
|  | %   Χρήστος Χουτουρίδης ΑΕΜ 8997 | ||||||
|  | %   cchoutou@ece.auth.gr | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | % Document configuration | ||||||
|  | \newcommand{\ClassName}{Μικροεπεξεργαστές και Περιφερειακά} | ||||||
|  | \newcommand{\DocTitle}{3η Εργασία} | ||||||
|  | \newcommand{\InstructorName}{Παπαευσταθίου Ιωάννης} | ||||||
|  | \newcommand{\InstructorMail}{ygp@ece.auth.gr} | ||||||
|  | \newcommand{\CurrentDate}{\today} | ||||||
|  | 
 | ||||||
|  | \input{config/AuthReportConfig.tex} | ||||||
|  | 
 | ||||||
|  | %\renewcommand{\AuthorName}{Χρήστος Χουτουρίδης} | ||||||
|  | %\renewcommand{\AuthorMail}{cchoutou@ece.auth.gr} | ||||||
|  | %\renewcommand{\AuthorAEM}{8997} | ||||||
|  | 
 | ||||||
|  | \setFancyHeadLR{\ClassName}{\DocTitle} | ||||||
|  | %\setFancyHeadLERO{\ClassName}{\DocTitle} | ||||||
|  | 
 | ||||||
|  | % Document | ||||||
|  | % ================= | ||||||
|  | \begin{document} | ||||||
|  | 
 | ||||||
|  | \FirstPage | ||||||
|  | %\TitleHeader | ||||||
|  | 
 | ||||||
|  | %\tableofcontents | ||||||
|  | %\listoffigures | ||||||
|  | %\listoftables | ||||||
|  | 
 | ||||||
|  | \section{Εισαγωγή}  | ||||||
|  | Στην παρούσα εργασία το ζητούμενο ήταν η υλοποίηση ενός “έξυπνου θερμοστάτη” χρησιμοποιώντας αναπτυξιακό \eng{Nucleo-F401RE} της εταιρίας \eng{ST Microelectronics.} | ||||||
|  | Η τελική εφαρμογή θα πρέπει να έχει οθόνη, \eng{leds} αισθητήρα  θερμοκρασίας και αισθητήρα εγγύτητας, υλικά που δεν είναι διαθέσιμα από το αναπτυξιακό. | ||||||
|  | Για το σκοπό αυτό αποφασίσαμε να προχωρήσουμε την εργασία λιγάκι παραπάνω και να κατασκευάσουμε ένα \eng{shield} για το \eng{Nucleo,} το οποίο ενσωματώνει σε ένα τυπωμένο κύκλωμα όλα τα απαραίτητα στοιχεία. | ||||||
|  | Τέλος, λόγο του ότι η διεπαφή χρήστη της εκφώνησης ήταν λιγάκι “φτωχή”, πήραμε την πρωτοβουλία και υλοποιήσαμε ένα μικρό \eng{serial interface} το οποίο μπορεί να χρησιμοποιηθεί και για να ρυθμίσει τον θερμοστάτη. | ||||||
|  | Η ανάπτυξη έγινε σε γλώσσα \eng{C} και χρησιμοποιήθηκε το εργαλείο \eng{Keil uVision.} | ||||||
|  | Ο κώδικας της εργασίας, της παρούσας αναφοράς, αλλά και τα σχέδια της κατασκευής υπάρχουν και στον προσωπικό \eng{server}του συντάκτη, στο \href{https://git.hoo2.net/hoo2/Micro2020/src/branch/master/assignment_3}{αποθετήριο} για την εργασία. | ||||||
|  | 
 | ||||||
|  | \section{Παραδοτέα} | ||||||
|  | Στο παραδοτέο \eng{.zip} αρχείο μπορείτε να βρείτε: | ||||||
|  | \begin{itemize} | ||||||
|  |     \item Τον κατάλογο \textbf{\eng{/src}} που περιέχει τον κώδικα της εφαρμογής. | ||||||
|  |     \item Τον κατάλογο \textbf{\eng{/Libraries}} που περιέχει τον κώδικα των βιβλιοθηκών που χρησιμοποιήσαμε, όπως το \eng{CMSIS} και το \eng{ST HAL,} αλλά και τους \eng{drivers} για τα περιφερειακά. | ||||||
|  |     \item Το αρχείο \textbf{\eng{report.pdf}} που είναι η παρούσα αναφορά. | ||||||
|  |     \item Τον κατάλογο \textbf{\eng{/Keil}} που περιέχει το \eng{project} που χρησιμοποιήθηκε στο \eng{Keil.}\\ | ||||||
|  |     Στο \eng{project} αυτό περιέχονται επιπλέων οι ρυθμίσεις καθώς και τα αρχεία από τις βιβλιοθήκες που χρησιμοποιήθηκαν. | ||||||
|  | \end{itemize} | ||||||
|  | \par | ||||||
|  | Για την παρούσα εργασία χρησιμοποιήσαμε το \eng{CMSIS} και το \eng{STM32F4xx\_HAL} που παρέχει η εταιρία \eng{ST} στο επίσημο αποθετήριό της. | ||||||
|  | Η επιλογή αυτού έναντι των αρχείων από το \eng{STM32F4xx Std\_Peripheral} που περιεχόταν στο \eng{e-learning} του μαθήματος έγινε για να συμβαδίσουμε με τις βιβλιοθήκες που προτείνει η κατασκευάστρια εταιρία. | ||||||
|  | Επίσης η χρήση τους έγινε στο ίδιο χαμηλό επίπεδο της \eng{STM32F4xx\_Std\_Peripheral} κάτι το οποίο προτείνεται και από τον διδάσκοντα. | ||||||
|  | \emph{\textbf{Εξάλλου μια υψηλότερου επιπέδου χρήση δεν θα είχε νόημα καθώς θα ξέφευγε από τον μαθησιακό χαρακτήρα της εργασίας}}. | ||||||
|  | 
 | ||||||
|  | \section{Υλοποίηση} | ||||||
|  | \subsection{Κατασκευή του\eng{shiled}} | ||||||
|  | \InsertFigure{0.8}{fig:shield_pcb}{shield_pcb.png}{ | ||||||
|  |     \eng{3D} απεικόνιση του \eng{PCB.} | ||||||
|  | } | ||||||
|  | Η υλοποίηση της εφαρμογής έγινε σε δύο φάσεις. | ||||||
|  | Η πρώτη ήταν η ανάπτυξη και κατασκευή του \eng{shiled.} | ||||||
|  | Αυτό το κομμάτι δεν ήταν στα απαιτούμενα και γιαυτό δεν θα ασχοληθούμε πολύ παρουσιάζοντάς το. | ||||||
|  | Θα πρέπει όμως να αναφέρουμε κάποια βασικά στοιχεία. | ||||||
|  | Έτσι εν συντομία η κατασκευή απαρτίζεται από: | ||||||
|  | \begin{itemize} | ||||||
|  |     \item Μια \textbf{οθόνη} υγρών κρυστάλλων \eng{2 x 16,} σε \eng{4bit} παράλληλη επικοινωνία με τον επεξεργαστή.\\ | ||||||
|  |     Εκτός από την επικοινωνία ο επεξεργαστής ελέγχει και το \eng{back light} μέσω ενός μικρού \eng{MOSFET,} του \eng{MMBF170.} | ||||||
|  |     Η οθόνη είναι σε μόνιμο \eng{write mode,} μιας και ο ακροδέκτης \eng{RW} είναι συνδεδεμένος μόνιμα στην γείωση. | ||||||
|  |     \item Ένα \eng{\textbf{relay}} τύπου \eng{latching,} το\eng{\textbf{G2SU-2}} συνδεδεμένο μέσω Η-γέφυρας.\\ | ||||||
|  |     Η επιλογή \eng{latching relay} έγινε με γνώμονα την πιθανή κατανάλωση της κατασκευής σε περίπτωση μελλοντικής χρήσης της. | ||||||
|  |     Σε μια τέτοια περίπτωση ενώ τα υπόλοιπα υλικά της κατασκευής λίγο πολύ θα μπορούσαν να περιορίσουν την κατανάλωση τους, το \eng{relay} θα έπρεπε να καταναλώνει συνέχεια ρεύμα για να παραμένει οπλισμένο. | ||||||
|  |     \item Ένα αισθητήριο θερμοκρασίας τύπου\eng{\textbf{DS18B20}.}\\ | ||||||
|  |     Το αισθητήριο αυτό κάνει χρήση του πρωτοκόλλου επικοινωνίας \eng{1-wire} της \eng{Dallas semiconductors.} | ||||||
|  |     Παρόλα αυτά στην κατασκευή είναι συνδεδεμένο στη σειριακή επικοινωνία του \eng{shield,} επιτρέποντας έτσι τη χρήση του \eng{\href{https://www.maximintegrated.com/en/design/technical-documents/tutorials/2/214.html}{application note 214}} της \eng{maxim,} όπου περιγράφεται ένας τρόπος δημιουργίας του χρονισμού του \eng{1-wire bus} χρησιμοποιώντας τη σειριακή θύρα. | ||||||
|  |     Με τον τρόπο αυτό ο επεξεργαστής αποδεσμεύεται από τον φόρτο να δημιουργεί ακριβείς χρονοκαθυστερήσεις, πιθανότατα απενεργοποιώντας τα \eng{interrupts} και αφήνει ένα περιφερειακό του να εκτελέσει αυτή τη δουλειά. | ||||||
|  |     \item Ένα αισθητήριο εγγύτητας \eng{\textbf{HC-SR04}} που λειτουργεί με υπερήχους. | ||||||
|  |     \item Διάφορα “\textbf{μικρούτσικα}” υλικά, όπως τρανζιστορ-άκια, αντιστάσεις, πυκνωτές, \eng{leds} κ.α. | ||||||
|  | \end{itemize} | ||||||
|  | 
 | ||||||
|  | \subsection{Οδηγός του \eng{Nucleo} και του \eng{shiled}} | ||||||
|  | Η δεύτερη φάση της ανάπτυξης ήταν ο προγραμματισμός. | ||||||
|  | Ο επεξεργαστής που φέρει το εν λόγο αναπτυξιακό είναι πολύ μεγαλύτερος από τις ανάγκες της παρούσας εργασίας. | ||||||
|  | Έτσι τα υποσυστήματα που χρησιμοποιήσαμε ήταν ελάχιστα. | ||||||
|  | Για την ακρίβεια έγινε χρήση: | ||||||
|  | \begin{itemize} | ||||||
|  |     \item Του \eng{\textbf{SysTick timer}} ώς βάση μέτρησης χρόνου.\\ | ||||||
|  |     Η συχνότητα που επιλέξαμε είναι το \eng{1Khz,} το οποίο μας οδηγεί σε επαρκές βήμα \eng{1msec}. | ||||||
|  |     \item Του \eng{\textbf{GPIO}} για την ανάγνωση του κουμπιού και την οδήγηση του \eng{LED} της πλακέτας, αλλά και την οδήγηση όλων των ψηφιακών σημάτων του \eng{shield.} | ||||||
|  |     \item Του \eng{\textbf{RCC}} για τον έλεγχο και των σημάτων ρολογιού εσωτερικά του επεξεργαστή στα διάφορα υποσυστήματα. | ||||||
|  |     \item Του \eng{\textbf{Cycle count}} μηχανισμού στον \eng{debugger.}\\ | ||||||
|  |     Ο εν λόγο μηχανισμός χρησιμοποιήθηκε για την μέτρηση του χρόνου απόκρισης του αισθητηρίου εγγύτητας. | ||||||
|  | \end{itemize} | ||||||
|  | \par | ||||||
|  | Αξίζει ίσως σε αυτό το σημείο να αναφέρουμε πως για την μέτρηση χρόνου χρησιμοποιήσαμε μεταβλητές για απαρίθμηση των διακοπών του \eng{SysTick.} | ||||||
|  | Η εφαρμογή έτσι μπορούσε βλέποντας την τιμή τους να έχει εικόνα του χρόνου που έχει περάσει από το \eng{power up.} | ||||||
|  | 
 | ||||||
|  | \par | ||||||
|  | Για την οδήγηση των περιφερειακών του \eng{shield} χρησιμοποιήσαμε επιπλέον: | ||||||
|  | \begin{itemize} | ||||||
|  |     \item Τη σειριακή \eng{\textbf{USART2}} για την επικοινωνία με το υπολογιστή.\\ | ||||||
|  |     Τη θύρα αυτή τη χρησιμοποιήσαμε για την δημιουργία ενός \eng{command interface,} μέσω του οποίου μπορούμε να δούμε την κατάσταση του θερμοστάτη, αλλά και να του αλλάξουμε τις ρυθμίσεις. | ||||||
|  |     \item Τη σειριακή \eng{\textbf{USART6}} για το \eng{1-wire.}\\ | ||||||
|  |     Η χρήση αυτής της θύρας έγινε όπως αναφέρθηκε και παραπάνω σύμφωνα με τις οδηγίες της \eng{maxim-ic (Dallas semiconductors).} | ||||||
|  | \end{itemize} | ||||||
|  | \par | ||||||
|  | Εδώ θα πρέπει να αναφέρουμε πως στο \eng{nucleo} οι ακροδέκτες της σειριακής επικοινωνίας\eng{(D0-D1)} είναι συνδεμένοι στην σειριακή του \eng{”USB to serial”} του \eng{ST-LINK2.} | ||||||
|  | Για να συνδέαμε μέσω αυτών των ακροδεκτών τη σειριακή για το \eng{1-wire} του \eng{shield} στον επεξεργαστή, θα έπρεπε να τοποθετούσαμε τα \eng{jumpers SB62, SB63.} | ||||||
|  | Έτσι η κατασκευή μας θα πληρούσε τις προδιαγραφές της εκφώνησης, αλλά δεν θα είχε την έξτρα δυνατότητα του \eng{serial console.} | ||||||
|  | Ανταυτού λοιπόν “αφήσαμε” το \eng{nucleo} απείραχτο και συνδέσαμε τη σειριακή του \eng{shield} στη θύρα \eng{USART6,} μέσω των \eng{morpho headers.} | ||||||
|  | Αυτό μας αφήνει με το \eng{configuration} που περιγράψαμε παραπάνω, ενώ η κατασκευή μας είναι η ίδια είτε υλοποιήσουμε μόνο τις προδιαγραφές της εκφώνησης είτε υλοποιήσουμε και το έξτρα \eng{command interface.} | ||||||
|  | 
 | ||||||
|  | \subsection{Οδηγός περιφερειακών} | ||||||
|  | Στον κατάλογο \eng{Libraries/drivers/} εκτός από τους οδηγούς του \eng{nucleo} και του \eng{shield,} υπάρχουν οι οδηγοί των περιφερειακών πάνω στο \eng{shield,} αλλά και οι επιπλέων λειτουργίες που χρειαστήκαμε για την ορθή λειτουργία τους. | ||||||
|  | Οι οδηγοί είναι σε ζεύγη αρχείων κώδικα-κεφαλίδας(\eng{.c/.h}) και ο καθένας αποτελεί ένα \eng{module.}  | ||||||
|  | Η αναλυτική παρουσίαση του κώδικα εδώ θα πλάτιαζε χωρίς να προσφέρει τίποτε χρήσιμο. | ||||||
|  | Θα αναφέρουμε όμως συνοπτικά το κάθε \eng{modul-}άκι και τον τρόπο λειτουργίας του γενικά. | ||||||
|  | \begin{itemize} | ||||||
|  |     \item \textbf{\eng{jiffies:}}\\ | ||||||
|  |     Στο \eng{module} αυτό ρυθμίζουμε ένα \eng{timer} του επεξεργαστή ώστε να μετράει αδιάκοπα μέχρι μία τιμή με \eng{auto-reload.} | ||||||
|  |     Κάνοντας χρήση αυτού του \eng{timer} μπορούμε στη συνέχεια να δημιουργήσουμε χρονοκαθυστερήσεις μικρότερες από το \eng{time base} της εφαρμογής. | ||||||
|  |     \item \textbf{\eng{deque08:}}\\ | ||||||
|  |     Το \eng{module} αυτό υλοποιεί μια \eng{double-ended queue.} | ||||||
|  |     Την ουρά αυτή τη χρησιμοποιούμε στη σειριακή επικοινωνία με τον υπολογιστή για το \eng{serial console.} | ||||||
|  |     Η υλοποίηση είναι “όσο \eng{object oriented} γίνεται”. | ||||||
|  |     Οι συναρτήσεις δηλαδή του \eng{module} έχουν όλες ένα δείκτη σ' ένα “αντικείμενο” τύπου ουράς που παίζει το ρόλο του \eng{this pointer} άλλων γλωσσών. | ||||||
|  |     Έτσι μπορούμε να χρησιμοποιήσουμε περισσότερες από μία ουρές στο ίδιο \eng{project} με τον ίδιο κώδικα. | ||||||
|  |     \item \textbf{\eng{onewire\_uart:}}\\ | ||||||
|  |     Το \eng{module} αυτό υλοποιεί το πρωτόκολλο επικοινωνίας \eng{1-wire} κάνοντας χρήση της σειριακής. | ||||||
|  |     Ομοίως και εδώ η υλοποίηση είναι \eng{object oriented like.} | ||||||
|  |     Εδώ όμως \textbf{κάνουμε ένα ακόμη κόλπο}. | ||||||
|  |     Αρχικά το \eng{module} προϋποθέτει πως οι ακροδέκτες \eng{Tx-Rx} της θύρας είναι βραχυκυκλωμένοι. | ||||||
|  |     Το βασικό “αντικείμενο” του \eng{module} εσωτερικά έχει δύο δείκτες σε συναρτήσεις. | ||||||
|  |     Τη μία την καλεί για να γράψει στη σειριακή και ταυτόχρονα να διαβάσει τo αποτέλεσμα της πραγματικής κατάστασης του \eng{bus} κατά την προσπάθεια. | ||||||
|  |     Την άλλη τη χρησιμοποιεί για να αλλάξει το \eng{baudrate} της θύρας. | ||||||
|  |     Σε όλο το σώμα του κώδικα του \eng{module} γίνεται χρήση μόνο αυτών των δύο δεικτών και έτσι \textbf{\textit{δεν υπάρχει καμία εξάρτηση από το \eng{hardware.}}} | ||||||
|  |     Ο χρήστης του \eng{module} μπορεί να το χρησιμοποιήσει σε οποιαδήποτε κατασκευή που πληροί τις προϋποθέσεις, να υλοποιήσει για το δικό του \eng{hardware} τις δύο παραπάνω συναρτήσεις και να τις συνδέσει με το \eng{module.} | ||||||
|  |     Κάτι τέτοιο κάναμε και εμείς εδώ, όπου υλοποιήσαμε τις συναρτήσεις \eng{\textit{SHIELD\_1W\_RW()}} και \eng{\textit{SHIELD\_1W\_UART\_BR()}} και τις συνδέσαμε με το \eng{module.} | ||||||
|  |     \item \textbf{\eng{alcd:}}\\ | ||||||
|  |     Το \eng{module} αυτό υλοποιεί ένα οδηγό για την οθόνη. | ||||||
|  |     Ομοίως και εδώ η υλοποίηση είναι \eng{object oriented like,} αλλά και απεξαρτημένη από το \eng{hardware} μέσω δεικτών σε συναρτήσεις για τα \eng{pins DB[4..7], RS, EN, Back-light.} | ||||||
|  |     Για τον χρονισμό των σημάτων εδώ κάνουμε χρήση των \eng{jiffies,} καθώς οι χρόνοι που χρειαζόμαστε είναι πολύ μικρότεροι από το \eng{time base.} | ||||||
|  |     \item Τέλος το \eng{\textbf{hal:}}\\ | ||||||
|  |     Το \eng{module} αυτό είναι ο συνδετικός κρίκος της εφαρμογής με τους οδηγούς. | ||||||
|  |     Σε αυτό το αρχείο επίσης είναι υλοποιημένες και οι λειτουργίες για την αναγνώριση της εγγύτητας και η ανάγνωση της θερμοκρασίας. | ||||||
|  |     \textit{Αυτές \textbf{οι τελευταίες λειτουργίες είναι οι πιο “ριγμένες”} της εργασίας, καθώς ο συντάκτης από καθαρή τεμπελιά δεν αξιώθηκε να τις κάνει ξεχωριστά \eng{modules.}} | ||||||
|  |     Εξάλλου φαίνεται και με μια ματιά πως οι λειτουργίες που είναι υλοποιημένες είναι οι άκρως απαραίτητες για την εφαρμογή μας. | ||||||
|  | \end{itemize} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | \subsection{Εφαρμογή} | ||||||
|  | \WrapFigure{0.45}{r}{fig:uistates}{ui_states.png}{ | ||||||
|  |     Μηχανή καταστάσεων της διεπαφής χρήστη. | ||||||
|  | } | ||||||
|  | Έχοντας υλοποιήσει όλα τα παραπάνω η δουλειά μας για την εφαρμογή ήταν πολύ εύκολη. | ||||||
|  | Έτσι στην βασική λειτουργία της εκφώνησης προσθέσαμε ορισμένα πράγματα. | ||||||
|  | Για παράδειγμα η εφαρμογή έχει μια δομή \eng{\textbf{settings}} στην οποία υπάρχουν οι ρυθμίσεις του θερμοστάτη. | ||||||
|  | Πιο συγκεκριμένα αποθηκεύουμε τον τρόπο λειτουργίας, αν δηλαδή ο θερμοστάτης δουλεύει για \textbf{ψύξη ή θέρμανση}. | ||||||
|  | Την θερμοκρασία λειτουργίας και μια υστέρηση για αυτήν. | ||||||
|  | Την απόσταση κάτω από την οποία θεωρεί ο θερμοστάτης ότι έχει εγγύτητα και ομοίως μια απόσταση υστέρησης. | ||||||
|  | 
 | ||||||
|  | \par | ||||||
|  | Ο κώδικας της εφαρμογής μας χωρίζεται σε τέσσερεις \eng{non-blocking} συναρτήσεις που καλούνται σε βρόχο επανάληψης από την \eng{main.} | ||||||
|  | \\ | ||||||
|  | 1. \textbf{\eng{control():}}\\ | ||||||
|  | Η συνάρτηση αυτή αναλαμβάνει να διαβάσει τα αισθητήρια εγγύτητας και θερμοκρασίας και να υπολογίσει τη μέση τιμή τις θερμοκρασίας στο τέλος του κάθε παράθυρου. | ||||||
|  | Η επικοινωνία με τις άλλες συναρτήσεις για την εγγύτητα και την ολοκλήρωση του κύκλου μετρήσεων γίνεται μέσω των σημαιών \eng{flag\_proximity}και\eng{signal\_cycle}αντίστοιχα. | ||||||
|  | Ακόμα με βάση τις ρυθμίσεις και την τρέχουσα μέση θερμοκρασία, ορίζει τη σημαία της κατάστασης εξόδου \eng{flag\_output.} | ||||||
|  | \\ | ||||||
|  | 2. \textbf{\eng{display():}}\\ | ||||||
|  | Η συνάρτηση αυτή υλοποιεί μια μηχανή καταστάσεων και αναλαμβάνει να εμφανίζει τα μηνύματα της οθόνης. | ||||||
|  | Στο διάγραμμα \ref{fig:uistates} φαίνονται οι καταστάσεις και ο τρόπος με τον οποίο γίνεται η εναλλαγή. | ||||||
|  | Σε κάθε κατάσταση η συνάρτηση διαμορφώνει ανάλογα το κείμενο στην οθόνη ώστε να πληρούνται οι προδιαγραφές της εργασίας. | ||||||
|  | \\ | ||||||
|  | 3. \textbf{\eng{outputs():}}\\ | ||||||
|  | Η συνάρτηση αυτή ενεργοποιεί ή απενεργοποιεί τις εξόδους της κατασκευής μας, δηλαδή τα δύο \eng{led} και το \eng{relay.} | ||||||
|  | Το πράσινο \eng{led} ενεργοποιείται όταν ο θερμοστάτης είναι ρυθμισμένος για ψύξη και η μέση θερμοκρασία είναι πάνω από τη ρύθμιση. | ||||||
|  | Το κόκκινο αντίστοιχα όταν ο θερμοστάτης είναι ρυθμισμένος για θέρμανση και η μέση θερμοκρασία είναι κάτω από τη ρύθμιση. | ||||||
|  | Το \eng{relay} ενεργοποιείται όταν θέλουμε ψύξη ή θέρμανση. | ||||||
|  | \\ | ||||||
|  | 4. \textbf{\eng{console():}}\\ | ||||||
|  | Η συνάρτηση αυτή υλοποιεί ένα πολύ απλό \eng{command interface} μέσω του οποίου μπορούμε από την σειριακή του υπολογιστή να δούμε όλες τις θερμοκρασίες και ρυθμίσεις της συσκευής. | ||||||
|  | Ακόμα μπορούμε να αλλάξουμε όλες τις ρυθμίσεις. | ||||||
|  | \InsertFigure{0.8}{fig:console}{console.png}{ | ||||||
|  |     Στιγμιότυπο από την σειριακή επικοινωνία με τον θερμοστάτη. | ||||||
|  | } | ||||||
|  | \par | ||||||
|  | Στο σημείο αυτό θα πρέπει να αναφέρουμε πως η λειτουργία των \eng{led} είναι λιγάκι αλλαγμένη από την εκφώνηση. | ||||||
|  | Ο λόγος είναι ότι ο εν λόγο θερμοστάτης πλέον έχει λειτουργία και ψύξης και θέρμανσης και θέλαμε να δώσουμε στο \eng{user interface} ένα πιο “δεμένο” ύφος. | ||||||
|  | 
 | ||||||
|  | \section{Συμπεράσματα - Παρατηρήσεις} | ||||||
|  | Συνοψίζοντας την εμπειρία μας με την παρούσα εργασία δεν έχουμε να αναφέρουμε κάποιο ιδιαίτερο πρόβλημα ή δυσκολία. | ||||||
|  | Η κατασκευή του τυπωμένου ευτυχώς δεν δημιούργησε εκπλήξεις με αποτέλεσμα η συγγραφή του κώδικα να γίνει απρόσκοπτα, αν και ομολογούμε ότι την κάναμε τελευταία στιγμή. | ||||||
|  | Παρατηρώντας την υλοποίηση βέβαια δεν μπορούμε παρά να τονίσουμε και μια παράβλεψη. | ||||||
|  | Ο θερμοστάτης δεν έχει κάποιο τρόπο να αποθηκεύει τις ρυθμίσεις στη \eng{flash.} | ||||||
|  | Αυτή η λειτουργία θα μπορούσε να είναι αιτία για να ξανασχοληθούμε στο μέλλον με την εργασία και ελπίζουμε αυτή μας η παράβλεψη να πέσει στην κατηγορία \textit{“για το μάτι”}. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | % References | ||||||
|  | % ============================ | ||||||
|  | %\begin{thebibliography}{100} | ||||||
|  | %\bibitem{item}item... | ||||||
|  | %\end{thebibliography} | ||||||
|  | 
 | ||||||
|  | \end{document} | ||||||
							
								
								
									
										138
									
								
								assignment_3/src/console.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								assignment_3/src/console.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,138 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file console.c | ||||||
|  |  * \brief | ||||||
|  |  *    A simple serial console implementation for out thermostat | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  */ | ||||||
|  | #include "console.h" | ||||||
|  | 
 | ||||||
|  | static char _buffer[COM_BUFFER_SIZE]; | ||||||
|  | static int  _cursor; | ||||||
|  | 
 | ||||||
|  | static char _ans[512]; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Parse and respond funcionality for serial console | ||||||
|  |  * \param buffer  Pointer to buffer | ||||||
|  |  */ | ||||||
|  | void parse (char* buffer) { | ||||||
|  |    int i; | ||||||
|  |    float_t s; | ||||||
|  | 
 | ||||||
|  |    if ((strncmp((const void*)buffer, "help", 4) == 0) || | ||||||
|  |        (strncmp((const void*)buffer, "?", 1) == 0) ) { | ||||||
|  |       i  = sprintf (_ans,     "\r\nThermostat commands:\r\n"); | ||||||
|  |       i += sprintf (&_ans[i], "info              : Get information\r\n"); | ||||||
|  |       i += sprintf (&_ans[i], "set Tset  <val>   : Set Thermostat\'s temperature\r\n"); | ||||||
|  |       i += sprintf (&_ans[i], "set Thyst <val>   : Set Thermostat\'s hysteresis\r\n"); | ||||||
|  |       i += sprintf (&_ans[i], "set Pset  <val>   : Set Proximity\r\n"); | ||||||
|  |       i += sprintf (&_ans[i], "set Physt <val>   : Set Proximity\'s hysteresis\r\n"); | ||||||
|  |       i += sprintf (&_ans[i], "set mode heating  : Set Thermostat to heating mode\r\n"); | ||||||
|  |       i += sprintf (&_ans[i], "set mode cooling  : Set Thermostat to cooling mode\r\n"); | ||||||
|  |       i += sprintf (&_ans[i], "\r\n"); | ||||||
|  |       _ans[i] =0; | ||||||
|  |    } | ||||||
|  |    else if (strncmp((const void*)buffer, "info", 4) == 0) { | ||||||
|  |       i  = sprintf (_ans,     "\r\nThermostat data:\r\n"); | ||||||
|  |       i += sprintf (&_ans[i], "Tcur   = %4.1f\r\n", temp_get_current ()); | ||||||
|  |       i += sprintf (&_ans[i], "Tav    = %4.1f\r\n", app_data.Tav); | ||||||
|  |       i += sprintf (&_ans[i], "Mode   = %s\r\n", (settings.mode == HEATING) ? "Heating" : "Cooling"); | ||||||
|  |       i += sprintf (&_ans[i], "Output = %s\r\n", (app_data.flag_output) ? "On" : "Off"); | ||||||
|  |       i += sprintf (&_ans[i], "Tset   = %4.1f, Hyst = %4.1f\r\n", settings.Tset, settings.Thyst); | ||||||
|  |       i += sprintf (&_ans[i], "Pset   = %4.1f, Hyst = %4.1f\r\n", settings.Pset, settings.Physt); | ||||||
|  |       i += sprintf (&_ans[i], "\r\n"); | ||||||
|  |       _ans[i] =0; | ||||||
|  |    } | ||||||
|  |    else if (strncmp((const void*)buffer, "set ", 4) == 0) { | ||||||
|  |       if (strncmp((const void*)&buffer[4], "Tset ", 5) == 0) { | ||||||
|  |          sscanf((const void*)&buffer[9], "%f", &s); | ||||||
|  |          if (s > -20 && s < 80) { | ||||||
|  |             settings.Tset = s; | ||||||
|  |             i = sprintf (_ans, "OK\r\n"); | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |             i = sprintf (_ans, "Error\r\n"); | ||||||
|  |          _ans[i] =0; | ||||||
|  |       } | ||||||
|  |       else if (strncmp((const void*)&buffer[4], "Thyst ", 6) == 0) { | ||||||
|  |          sscanf((const void*)&buffer[10], "%f", &s); | ||||||
|  |          if (s > 0 && s < 20) { | ||||||
|  |             settings.Thyst = s; | ||||||
|  |             i = sprintf (_ans, "OK\r\n"); | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |             i = sprintf (_ans, "Error\r\n"); | ||||||
|  |          _ans[i] =0; | ||||||
|  |       } | ||||||
|  |       else if (strncmp((const void*)&buffer[4], "Pset ", 5) == 0) { | ||||||
|  |          sscanf((const void*)&buffer[9], "%f", &s); | ||||||
|  |          if (s > 0 && s < 100) | ||||||
|  |             settings.Pset = s; | ||||||
|  |          i = sprintf (_ans, "OK\r\n"); | ||||||
|  |          _ans[i] =0; | ||||||
|  |       } | ||||||
|  |       else if (strncmp((const void*)&buffer[4], "Physt ", 6) == 0) { | ||||||
|  |          sscanf((const void*)&buffer[10], "%f", &s); | ||||||
|  |          if (s > 0 && s < 50) { | ||||||
|  |             settings.Physt = s; | ||||||
|  |             i = sprintf (_ans, "OK\r\n"); | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |             i = sprintf (_ans, "Error\r\n"); | ||||||
|  |          _ans[i] =0; | ||||||
|  |       } | ||||||
|  |       else if (strncmp((const void*)&buffer[4], "mode ", 5) == 0) { | ||||||
|  |          if (strncmp((const void*)&buffer[9], "heating", 7) == 0) { | ||||||
|  |             settings.mode = HEATING; | ||||||
|  |             i = sprintf (_ans, "OK\r\n"); | ||||||
|  |             _ans[i] =0; | ||||||
|  |          } | ||||||
|  |          else if (strncmp((const void*)&buffer[9], "cooling", 7) == 0) { | ||||||
|  |             settings.mode = COOLING; | ||||||
|  |             i = sprintf (_ans, "OK\r\n"); | ||||||
|  |             _ans[i] =0; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |          i = sprintf (_ans, "Error\r\n"); | ||||||
|  |          _ans[i] =0; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |    else { | ||||||
|  |       i = sprintf (_ans, "Error\r\n"); | ||||||
|  |       _ans[i] =0; | ||||||
|  |    } | ||||||
|  |    COM_Transmit((uint8_t*)_ans, i); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * A simple terminal with echo | ||||||
|  |  */ | ||||||
|  | void console (void) { | ||||||
|  |    int ch; | ||||||
|  | 
 | ||||||
|  |    if (COM_CheckReceive()) { | ||||||
|  |       ch = COM_getchar();        // get character
 | ||||||
|  |       COM_putchar((char)ch);     // Echo back
 | ||||||
|  |       _buffer[_cursor++] = ch;   // store
 | ||||||
|  | 
 | ||||||
|  |       // Backspace, delete
 | ||||||
|  |       if (ch == 0x08 || ch == 0x7F) | ||||||
|  |             --_cursor; | ||||||
|  | 
 | ||||||
|  |       if (ch == 0 || ch == '\n' || ch == '\r') { | ||||||
|  |          COM_putchar('\n');     // Echo an extra '\n'
 | ||||||
|  |          _buffer[_cursor -1] = 0; | ||||||
|  |          _cursor =0; | ||||||
|  |          parse(_buffer); | ||||||
|  |       } | ||||||
|  |       if (_cursor >= COM_BUFFER_SIZE) { | ||||||
|  |          _buffer[_cursor -1] = 0; | ||||||
|  |          _cursor =0; | ||||||
|  |          parse(_buffer); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										20
									
								
								assignment_3/src/console.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								assignment_3/src/console.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file console.h | ||||||
|  |  * \brief | ||||||
|  |  *    A simple serial console implementation for out thermostat | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  */ | ||||||
|  | #ifndef CONSOLE_H_ | ||||||
|  | #define CONSOLE_H_ | ||||||
|  | 
 | ||||||
|  | #include <hal.h> | ||||||
|  | #include "thermostat.h" | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | extern float_t temp_get_current (void); | ||||||
|  | 
 | ||||||
|  | void console (void); | ||||||
|  | 
 | ||||||
|  | #endif /* CONSOLE_H_ */ | ||||||
							
								
								
									
										206
									
								
								assignment_3/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								assignment_3/src/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,206 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file | ||||||
|  |  *    main.c | ||||||
|  |  * \brief | ||||||
|  |  *    Main application file | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  */ | ||||||
|  | #include <hal.h> | ||||||
|  | #include "thermostat.h" | ||||||
|  | #include "console.h" | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Zero initialized globals | ||||||
|  |  */ | ||||||
|  | app_data_t     app_data; | ||||||
|  | state_en       state; | ||||||
|  | 
 | ||||||
|  | // Value initialized globals
 | ||||||
|  | settings_t     _Init_settings(settings); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * helper api | ||||||
|  |  */ | ||||||
|  | float_t temp_get_current (void) { | ||||||
|  |    return (app_data.cur) ? app_data.T[app_data.cur-1] : app_data.T[MEASUREMENTS-1]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Control functionality | ||||||
|  |  * Handles: | ||||||
|  |  *    * Sensor reading | ||||||
|  |  *    * Temp averaging | ||||||
|  |  *    * Output calculation | ||||||
|  |  * \note    Non-blocking | ||||||
|  |  */ | ||||||
|  | void control (void) { | ||||||
|  |    static time_t sample =0; | ||||||
|  |    time_t now = time(0);   // get time
 | ||||||
|  | 
 | ||||||
|  |    // Proximity
 | ||||||
|  |    if (proximity(&prox) < settings.Pset) | ||||||
|  |       app_data.flag_proximity = 1; | ||||||
|  |    else if (proximity(&prox) < settings.Pset + settings.Physt) | ||||||
|  |       ; | ||||||
|  |    else | ||||||
|  |       app_data.flag_proximity = 0; | ||||||
|  | 
 | ||||||
|  |    // Temperature calculation
 | ||||||
|  |    if (now - sample >= MEAS_INTERVAL) { | ||||||
|  |       sample = now; | ||||||
|  |       app_data.T[app_data.cur] = temp_read(); | ||||||
|  |       if (++app_data.cur >= MEASUREMENTS) { | ||||||
|  |          app_data.cur =0; | ||||||
|  |          float_t f =0; | ||||||
|  |          for (int i=0 ; i<MEASUREMENTS ; ++i) { | ||||||
|  |             f += app_data.T[i]; | ||||||
|  |          } | ||||||
|  |          app_data.Tav = f / MEASUREMENTS; | ||||||
|  |          app_data.signal_cycle = 1; | ||||||
|  |          app_data.flag_init = 0; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Output handling
 | ||||||
|  |    if (!app_data.flag_init) { | ||||||
|  |       switch (settings.mode) { | ||||||
|  |          case HEATING: { | ||||||
|  |             if (app_data.Tav <= settings.Tset) | ||||||
|  |                app_data.flag_output = 1; | ||||||
|  |             else if (app_data.Tav < settings.Tset + settings.Thyst) | ||||||
|  |                ; | ||||||
|  |             else | ||||||
|  |                app_data.flag_output = 0; | ||||||
|  |          } | ||||||
|  |          break; | ||||||
|  | 
 | ||||||
|  |          case COOLING: { | ||||||
|  |             if (app_data.Tav <= settings.Tset - settings.Thyst) | ||||||
|  |                app_data.flag_output = 0; | ||||||
|  |             else if (app_data.Tav < settings.Tset) | ||||||
|  |                ; | ||||||
|  |             else | ||||||
|  |                app_data.flag_output = 1; | ||||||
|  |          } | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Display functionality | ||||||
|  |  * Implement a state machine for lcd display | ||||||
|  |  * \note    Non-blocking | ||||||
|  |  */ | ||||||
|  | void display (void) { | ||||||
|  |    static time_t mark =0; | ||||||
|  | 
 | ||||||
|  |    char line1[18]; | ||||||
|  |    char line2[18]; | ||||||
|  |    time_t now = time(0); | ||||||
|  | 
 | ||||||
|  |    switch (state) { | ||||||
|  |       case ST_INIT: | ||||||
|  |          sprintf(line1, "\fInitializing %c  ", (time(0)%2) ? '*' : ' '); | ||||||
|  |          sprintf(line2, "\n                "); | ||||||
|  | 
 | ||||||
|  |          // escapes
 | ||||||
|  |          if (app_data.flag_proximity) | ||||||
|  |             state = ST_USER; | ||||||
|  |          else if (app_data.signal_cycle) { | ||||||
|  |             app_data.signal_cycle =0; | ||||||
|  |             mark = now; | ||||||
|  |             state = ST_AVERAGE; | ||||||
|  |          } | ||||||
|  |       break; | ||||||
|  | 
 | ||||||
|  |       case ST_COUNT: | ||||||
|  |          sprintf(line1, "\fMeasuring %c     ", (time(0)%2) ? '*' : ' '); | ||||||
|  |          sprintf(line2, "\n%s: %s    ", | ||||||
|  |                (settings.mode == HEATING) ? "Heating" : "Cooling", | ||||||
|  |                (app_data.flag_output) ? "On " : "Off" | ||||||
|  |          ); | ||||||
|  | 
 | ||||||
|  |          // escapes
 | ||||||
|  |          if (app_data.flag_proximity) | ||||||
|  |             state = ST_USER; | ||||||
|  |          else if (app_data.signal_cycle) { | ||||||
|  |             app_data.signal_cycle =0; | ||||||
|  |             mark = now; | ||||||
|  |             state = ST_AVERAGE; | ||||||
|  |          } | ||||||
|  |       break; | ||||||
|  | 
 | ||||||
|  |       case ST_AVERAGE: | ||||||
|  |          sprintf(line1, "\fTav=%4.1f        ", app_data.Tav); | ||||||
|  |          sprintf(line2, "\n%s: %s    ", | ||||||
|  |                (settings.mode == HEATING) ? "Heating" : "Cooling", | ||||||
|  |                (app_data.flag_output) ? "On " : "Off" | ||||||
|  |          ); | ||||||
|  | 
 | ||||||
|  |          // escapes
 | ||||||
|  |          if (app_data.flag_proximity) | ||||||
|  |             state = ST_USER; | ||||||
|  |          else if (now - mark >= UI_AVERAGE_TIME) | ||||||
|  |             state = ST_COUNT; | ||||||
|  |       break; | ||||||
|  | 
 | ||||||
|  |       case ST_USER: | ||||||
|  |          sprintf(line1, "\fTav=%4.1f  T=%4.1f", app_data.Tav, temp_get_current()); | ||||||
|  |          sprintf(line2, "\n%s: %s    ", | ||||||
|  |                (settings.mode == HEATING) ? "Heating" : "Cooling", | ||||||
|  |                (app_data.flag_output) ? "On " : "Off" | ||||||
|  |          ); | ||||||
|  | 
 | ||||||
|  |          // escapes
 | ||||||
|  |          if (!app_data.flag_proximity) | ||||||
|  |             state = ST_COUNT; | ||||||
|  |       break; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    lcd_puts(line1); | ||||||
|  |    lcd_puts(line2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Set outputs | ||||||
|  |  * \note    Non-blocking | ||||||
|  |  */ | ||||||
|  | void outputs (void) { | ||||||
|  |    static uint8_t pr_output =0; | ||||||
|  | 
 | ||||||
|  |    if (app_data.flag_init) | ||||||
|  |       return; | ||||||
|  |    led_green(app_data.flag_output && settings.mode == COOLING); | ||||||
|  |    led_red (app_data.flag_output && settings.mode == HEATING); | ||||||
|  | 
 | ||||||
|  |    if (app_data.flag_output != pr_output) { | ||||||
|  |       relay(app_data.flag_output); | ||||||
|  |       pr_output = app_data.flag_output; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Main loop | ||||||
|  |  */ | ||||||
|  | int main(void) { | ||||||
|  | 
 | ||||||
|  |    hal_hw_init (); | ||||||
|  |    lcd_init (); | ||||||
|  |    proximity_init(&prox); | ||||||
|  |    temp_init (TEMP_11_BIT); | ||||||
|  | 
 | ||||||
|  |    lcd_enable(1); | ||||||
|  |    app_data.flag_init = 1; | ||||||
|  | 
 | ||||||
|  |    while (1) { | ||||||
|  |       control (); | ||||||
|  |       display (); | ||||||
|  |       outputs(); | ||||||
|  |       console (); | ||||||
|  |       HAL_Delay(10); | ||||||
|  |    } | ||||||
|  | } | ||||||
							
								
								
									
										84
									
								
								assignment_3/src/thermostat.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								assignment_3/src/thermostat.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | |||||||
|  | /*!
 | ||||||
|  |  * \file thermostat.h | ||||||
|  |  * \brief | ||||||
|  |  *    Application wide data type declarations | ||||||
|  |  * | ||||||
|  |  * Author: Christos Choutouridis AEM: 8997 | ||||||
|  |  * email : <cchoutou@ece.auth.gr> | ||||||
|  |  */ | ||||||
|  | #ifndef THERMOSTAT_H_ | ||||||
|  | #define THERMOSTAT_H_ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Hard coded user settings | ||||||
|  |  */ | ||||||
|  | #define  MEAS_WINDOW       (120)    // [sec]
 | ||||||
|  | #define  MEAS_INTERVAL     (5)      // [sec]
 | ||||||
|  | #define  MEASUREMENTS      (MEAS_WINDOW / MEAS_INTERVAL)    // keep this integer
 | ||||||
|  | #define  UI_AVERAGE_TIME   (10)     // [sec]
 | ||||||
|  | //#define  UI_USER_TIME      (10)
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | typedef float  float_t;    //!< Select the floating point type for application
 | ||||||
|  | typedef int    int_t;      //!< Select the integer type for application
 | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Thermostat mode enumerator | ||||||
|  |  */ | ||||||
|  | typedef enum { | ||||||
|  |    HEATING =0, //!< HEATING
 | ||||||
|  |    COOLING     //!< COOLING
 | ||||||
|  | } mode_en; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Application common data type | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |    float_t  T[MEASUREMENTS];  //!< Temperature samples
 | ||||||
|  |    float_t  Tav;              //!< Average temperature
 | ||||||
|  |    uint32_t cur;              //!< Cursor on sample array
 | ||||||
|  |    uint8_t  flag_output;      //!< Momentary flag to indicate the relay state
 | ||||||
|  |    uint8_t  flag_init;        //!< Momentary flag to indicate the end of initialization state
 | ||||||
|  |    uint8_t  flag_proximity;   //!< Momentary flag to indicate that the user is near
 | ||||||
|  |    uint8_t  signal_cycle;     //!< Acknolegable flag to indicate the end of measurement cycle
 | ||||||
|  | } app_data_t; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Settings struct | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |    mode_en  mode;    //!< Operational mode
 | ||||||
|  |    float_t  Tset;    //!< Target temperature
 | ||||||
|  |    float_t  Thyst;   //!< Target temperature hysteresis
 | ||||||
|  |    float_t  Pset;    //!< Proximity distance
 | ||||||
|  |    float_t  Physt;   //!< Proximity distance hysteresis
 | ||||||
|  | } settings_t; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * User interface states | ||||||
|  |  */ | ||||||
|  | typedef enum { | ||||||
|  |    ST_INIT =0, //!< ST_INIT:     Still initializing
 | ||||||
|  |    ST_COUNT,   //!< ST_COUNT:    Measurement cycle
 | ||||||
|  |    ST_AVERAGE, //!< ST_AVERAGE:  Display average
 | ||||||
|  |    ST_USER     //!< ST_USER:     Display when a user is near
 | ||||||
|  | } state_en; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * globals | ||||||
|  |  */ | ||||||
|  | extern app_data_t     app_data; | ||||||
|  | extern state_en       state; | ||||||
|  | extern settings_t     settings; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * Factory defaults | ||||||
|  |  */ | ||||||
|  | #define _Init_settings(s)  s = { \ | ||||||
|  |       .mode = HEATING,           \ | ||||||
|  |       .Tset = 21.0,              \ | ||||||
|  |       .Thyst = 2.0,              \ | ||||||
|  |       .Pset = 75.0,              \ | ||||||
|  |       .Physt = 10.0              \ | ||||||
|  | } | ||||||
|  | #endif /* THERMOSTAT_H_ */ | ||||||
							
								
								
									
										3
									
								
								assignment_3/thermostat_shield/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								assignment_3/thermostat_shield/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | History/ | ||||||
|  | __Previews/ | ||||||
|  | Project\ Logs\ for\ Thermostat/ | ||||||
							
								
								
									
										1
									
								
								assignment_3/thermostat_shield/AltiumLib
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								assignment_3/thermostat_shield/AltiumLib
									
									
									
									
									
										Submodule
									
								
							| @ -0,0 +1 @@ | |||||||
|  | Subproject commit 430c900e41cda0cc88fd8b8b59c48bee025d8b41 | ||||||
							
								
								
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Main.SchDoc
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Main.SchDoc
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Output/Thermostat.pdf
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Output/Thermostat.pdf
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Output/Thermostat_All.pdf
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Output/Thermostat_All.pdf
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Output/Thermostat_Copper.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Output/Thermostat_Copper.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Relay.SchDoc
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Relay.SchDoc
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										143
									
								
								assignment_3/thermostat_shield/Thermostat.OutJob
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										143
									
								
								assignment_3/thermostat_shield/Thermostat.OutJob
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,143 @@ | |||||||
|  | [OutputJobFile] | ||||||
|  | Version=1.0 | ||||||
|  | Caption= | ||||||
|  | Description= | ||||||
|  | VaultGUID= | ||||||
|  | ItemGUID= | ||||||
|  | ItemHRID= | ||||||
|  | RevisionGUID= | ||||||
|  | RevisionId= | ||||||
|  | VaultHRID= | ||||||
|  | AutoItemHRID= | ||||||
|  | NextRevId= | ||||||
|  | FolderGUID= | ||||||
|  | LifeCycleDefinitionGUID= | ||||||
|  | RevisionNamingSchemeGUID= | ||||||
|  | 
 | ||||||
|  | [PublishSettings] | ||||||
|  | OutputFilePath2=\\vmware-host\Shared Folders\Shares\Micro\assignment_3\thermostat_shield\.PDF | ||||||
|  | ReleaseManaged2=0 | ||||||
|  | OutputBasePath2=\\vmware-host\Shared Folders\Shares\Micro\assignment_3\thermostat_shield\ | ||||||
|  | OutputPathMedia2= | ||||||
|  | OutputPathMediaValue2= | ||||||
|  | OutputPathOutputer2=[Output Type] | ||||||
|  | OutputPathOutputerPrefix2= | ||||||
|  | OutputPathOutputerValue2= | ||||||
|  | OutputFileName2=Thermostat.pdf | ||||||
|  | OutputFileNameMulti2= | ||||||
|  | UseOutputNameForMulti2=1 | ||||||
|  | OutputFileNameSpecial2= | ||||||
|  | OpenOutput2=1 | ||||||
|  | PromptOverwrite2=1 | ||||||
|  | PublishMethod2=0 | ||||||
|  | ZoomLevel2=50 | ||||||
|  | FitSCHPrintSizeToDoc2=0 | ||||||
|  | FitPCBPrintSizeToDoc2=0 | ||||||
|  | GenerateNetsInfo2=1 | ||||||
|  | MarkPins2=1 | ||||||
|  | MarkNetLabels2=1 | ||||||
|  | MarkPortsId2=1 | ||||||
|  | GenerateTOC=1 | ||||||
|  | ShowComponentParameters2=1 | ||||||
|  | GlobalBookmarks2=0 | ||||||
|  | OutputFilePath3= | ||||||
|  | ReleaseManaged3=1 | ||||||
|  | OutputBasePath3= | ||||||
|  | OutputPathMedia3= | ||||||
|  | OutputPathMediaValue3= | ||||||
|  | OutputPathOutputer3=[Output Type] | ||||||
|  | OutputPathOutputerPrefix3= | ||||||
|  | OutputPathOutputerValue3= | ||||||
|  | OutputFileName3= | ||||||
|  | OutputFileNameMulti3= | ||||||
|  | UseOutputNameForMulti3=1 | ||||||
|  | OutputFileNameSpecial3= | ||||||
|  | OpenOutput3=1 | ||||||
|  | OutputFilePath4= | ||||||
|  | ReleaseManaged4=1 | ||||||
|  | OutputBasePath4= | ||||||
|  | OutputPathMedia4= | ||||||
|  | OutputPathMediaValue4= | ||||||
|  | OutputPathOutputer4=[Output Type] | ||||||
|  | OutputPathOutputerPrefix4= | ||||||
|  | OutputPathOutputerValue4= | ||||||
|  | OutputFileName4= | ||||||
|  | OutputFileNameMulti4= | ||||||
|  | UseOutputNameForMulti4=1 | ||||||
|  | OutputFileNameSpecial4= | ||||||
|  | OpenOutput4=1 | ||||||
|  | PromptOverwrite4=1 | ||||||
|  | PublishMethod4=5 | ||||||
|  | ZoomLevel4=50 | ||||||
|  | FitSCHPrintSizeToDoc4=1 | ||||||
|  | FitPCBPrintSizeToDoc4=1 | ||||||
|  | GenerateNetsInfo4=1 | ||||||
|  | MarkPins4=1 | ||||||
|  | MarkNetLabels4=1 | ||||||
|  | MarkPortsId4=1 | ||||||
|  | MediaFormat4=Windows Media file (*.wmv,*.wma,*.asf) | ||||||
|  | FixedDimensions4=1 | ||||||
|  | Width4=352 | ||||||
|  | Height4=288 | ||||||
|  | MultiFile4=0 | ||||||
|  | FramesPerSecond4=25 | ||||||
|  | FramesPerSecondDenom4=1 | ||||||
|  | AviPixelFormat4=7 | ||||||
|  | AviCompression4=MP42 MS-MPEG4 V2 | ||||||
|  | AviQuality4=100 | ||||||
|  | FFmpegVideoCodecId4=13 | ||||||
|  | FFmpegPixelFormat4=0 | ||||||
|  | FFmpegQuality4=80 | ||||||
|  | WmvVideoCodecName4=Windows Media Video V7 | ||||||
|  | WmvQuality4=80 | ||||||
|  | 
 | ||||||
|  | [GeneratedFilesSettings] | ||||||
|  | RelativeOutputPath2=\\vmware-host\Shared Folders\Shares\Micro\assignment_3\thermostat_shield\.PDF | ||||||
|  | OpenOutputs2=1 | ||||||
|  | RelativeOutputPath3= | ||||||
|  | OpenOutputs3=1 | ||||||
|  | AddToProject3=1 | ||||||
|  | TimestampFolder3=0 | ||||||
|  | UseOutputName3=0 | ||||||
|  | OpenODBOutput3=0 | ||||||
|  | OpenGerberOutput3=0 | ||||||
|  | OpenNCDrillOutput3=0 | ||||||
|  | OpenIPCOutput3=0 | ||||||
|  | EnableReload3=0 | ||||||
|  | RelativeOutputPath4= | ||||||
|  | OpenOutputs4=1 | ||||||
|  | 
 | ||||||
|  | [OutputGroup1] | ||||||
|  | Name= | ||||||
|  | Description= | ||||||
|  | TargetOutputMedium=PDF | ||||||
|  | VariantName=[No Variations] | ||||||
|  | VariantScope=0 | ||||||
|  | CurrentConfigurationName= | ||||||
|  | TargetPrinter=Virtual Printer | ||||||
|  | PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 | ||||||
|  | OutputMedium1=Print Job | ||||||
|  | OutputMedium1_Type=Printer | ||||||
|  | OutputMedium1_Printer= | ||||||
|  | OutputMedium1_PrinterOptions=Record=PrinterOptions|Copies=1|Duplex=1|TrueTypeOptions=3|Collate=1|PrintJobKind=1|PrintWhat=1 | ||||||
|  | OutputMedium2=PDF | ||||||
|  | OutputMedium2_Type=Publish | ||||||
|  | OutputMedium3=Folder Structure | ||||||
|  | OutputMedium3_Type=GeneratedFiles | ||||||
|  | OutputMedium4=Video | ||||||
|  | OutputMedium4_Type=Multimedia | ||||||
|  | OutputType1=Schematic Print | ||||||
|  | OutputName1=Schematic Prints | ||||||
|  | OutputCategory1=Documentation | ||||||
|  | OutputDocumentPath1= | ||||||
|  | OutputVariantName1= | ||||||
|  | OutputEnabled1=1 | ||||||
|  | OutputEnabled1_OutputMedium1=0 | ||||||
|  | OutputEnabled1_OutputMedium2=1 | ||||||
|  | OutputEnabled1_OutputMedium3=0 | ||||||
|  | OutputEnabled1_OutputMedium4=0 | ||||||
|  | OutputDefault1=0 | ||||||
|  | PageOptions1=Record=PageOptions|CenterHorizontal=True|CenterVertical=True|PrintScale=1.09|XCorrection=1.00|YCorrection=1.00|PrintKind=0|BorderSize=5000000|LeftOffset=0|BottomOffset=0|Orientation=2|PaperLength=1000|PaperWidth=1000|Scale=100|PaperSource=7|PrintQuality=-3|MediaType=1|DitherType=10|PrintScaleMode=1|PaperKind=A4|PaperIndex=9 | ||||||
|  | Configuration1_Name1=OutputConfigurationParameter1 | ||||||
|  | Configuration1_Item1=Record=SchPrintView|ShowNoERC=True|ShowParamSet=True|ShowProbe=True|ShowBlanket=True|NoERCSymbolsToShow="Thin Cross","Thick Cross","Small Cross",Checkbox,Triangle|ShowNote=True|ShowNoteCollapsed=True|ExpandDesignator=True|ExpandNetLabel=False|ExpandPort=False|ExpandSheetNum=False|ExpandDocNum=False|PrintArea=0|PrintAreaRect.X1=0|PrintAreaRect.Y1=0|PrintAreaRect.X2=0|PrintAreaRect.Y2=0 | ||||||
|  | 
 | ||||||
							
								
								
									
										1219
									
								
								assignment_3/thermostat_shield/Thermostat.PrjPCB
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1219
									
								
								assignment_3/thermostat_shield/Thermostat.PrjPCB
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2
									
								
								assignment_3/thermostat_shield/Thermostat.PrjPCBStructure
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								assignment_3/thermostat_shield/Thermostat.PrjPCBStructure
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | Record=TopLevelDocument|FileName=Main.SchDoc | ||||||
|  | Record=SheetSymbol|Record=SheetSymbol|SourceDocument=Main.SchDoc|Designator=R|SchDesignator=R|FileName=Relay.SchDoc|SymbolType=Normal|RawFileName=Relay.SchDoc|DesignItemId= |SourceLibraryName= |ObjectKind=Sheet Symbol|RevisionGUID= |ItemGUID= |VaultGUID=  | ||||||
							
								
								
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Thermostat_Shield.PcbDoc
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/Thermostat_Shield.PcbDoc
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/datasheets/DS18B20.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/datasheets/DS18B20.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/datasheets/HCSR04.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assignment_3/thermostat_shield/datasheets/HCSR04.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user