Changeset 374 for asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal
- Timestamp:
- Apr 5, 2019, 9:26:53 PM (5 years ago)
- Location:
- asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal
- Files:
-
- 8 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/can_api.h
r352 r374 59 59 60 60 void can_init (can_t *obj, PinName rd, PinName td); 61 void can_init_freq(can_t *obj, PinName rd, PinName td, int hz); 61 62 void can_free (can_t *obj); 62 63 int can_frequency(can_t *obj, int hz); -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/can_helper.h
r352 r374 26 26 #endif 27 27 28 /** 29 * 30 * \enum CANFormat 31 * 32 * \brief Values that represent CAN Format 33 **/ 28 34 enum CANFormat { 29 35 CANStandard = 0, … … 33 39 typedef enum CANFormat CANFormat; 34 40 41 /** 42 * 43 * \enum CANType 44 * 45 * \brief Values that represent CAN Type 46 **/ 35 47 enum CANType { 36 48 CANData = 0, … … 39 51 typedef enum CANType CANType; 40 52 53 /** 54 * 55 * \struct CAN_Message 56 * 57 * \brief Holder for single CAN message. 58 * 59 **/ 41 60 struct CAN_Message { 42 61 unsigned int id; // 29 bit identifier 43 62 unsigned char data[8]; // Data field 44 63 unsigned char len; // Length of data field in bytes 45 CANFormat format; // 0 - STANDARD, 1- EXTENDED IDENTIFIER46 CANType type; // 0 - DATA FRAME, 1 - REMOTE FRAME64 CANFormat format; // Format ::CANFormat 65 CANType type; // Type ::CANType 47 66 }; 48 67 typedef struct CAN_Message CAN_Message; -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/ethernet_api.h
r352 r374 45 45 int ethernet_send(void); 46 46 47 // rec ieve from ethernet buffer, returning packet size, or 0 if no packet47 // receive from ethernet buffer, returning packet size, or 0 if no packet 48 48 int ethernet_receive(void); 49 49 -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/gpio_api.h
r352 r374 84 84 /** Init the input pin and set mode to PullDefault 85 85 * 86 * @param objThe GPIO object86 * @param gpio The GPIO object 87 87 * @param pin The pin name 88 88 */ … … 91 91 /** Init the input pin and set the mode 92 92 * 93 * @param objThe GPIO object93 * @param gpio The GPIO object 94 94 * @param pin The pin name 95 95 * @param mode The pin mode to be set … … 99 99 /** Init the output pin as an output, with predefined output value 0 100 100 * 101 * @param objThe GPIO object101 * @param gpio The GPIO object 102 102 * @param pin The pin name 103 103 * @return An integer value 1 or 0 … … 107 107 /** Init the pin as an output and set the output value 108 108 * 109 * @param objThe GPIO object109 * @param gpio The GPIO object 110 110 * @param pin The pin name 111 111 * @param value The value to be set … … 115 115 /** Init the pin to be in/out 116 116 * 117 * @param objThe GPIO object117 * @param gpio The GPIO object 118 118 * @param pin The pin name 119 119 * @param direction The pin direction to be set -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/i2c_api.h
r352 r374 157 157 /** Configure I2C as slave or master. 158 158 * @param obj The I2C object 159 * @param enable_slave Enable i2c hardware so you can receive events with ::i2c_slave_receive 159 160 * @return non-zero if a value is available 160 161 */ … … 170 171 /** Configure I2C as slave or master. 171 172 * @param obj The I2C object 173 * @param data The buffer for receiving 174 * @param length Number of bytes to read 172 175 * @return non-zero if a value is available 173 176 */ … … 176 179 /** Configure I2C as slave or master. 177 180 * @param obj The I2C object 181 * @param data The buffer for sending 182 * @param length Number of bytes to write 178 183 * @return non-zero if a value is available 179 184 */ … … 209 214 * @param stop If true, stop will be generated after the transfer is done 210 215 * @param handler The I2C IRQ handler to be set 216 * @param event Event mask for the transfer. See \ref hal_I2CEvents 211 217 * @param hint DMA hint usage 212 218 */ -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/lp_ticker_api.h
r352 r374 22 22 #include "device.h" 23 23 24 #if DEVICE_L OWPOWERTIMER24 #if DEVICE_LPTICKER 25 25 26 26 #include "hal/ticker_api.h" … … 31 31 32 32 /** 33 * \defgroup hal_LpTicker Low Power Ticker Functions 33 * \defgroup hal_lp_ticker Low Power Ticker 34 * Low level interface to the low power ticker of a target 35 * 36 * # Defined behavior 37 * * Has a reported frequency between 4KHz and 64KHz - verified by ::lp_ticker_info_test 38 * * Has a counter that is at least 12 bits wide - verified by ::lp_ticker_info_test 39 * * Continues operating in deep sleep mode - verified by ::lp_ticker_deepsleep_test 40 * * All behavior defined by the @ref hal_ticker_shared "ticker specification" 41 * 42 * # Undefined behavior 43 * * See the @ref hal_ticker_shared "ticker specification" 44 * * Calling any function other than lp_ticker_init after calling lp_ticker_free 45 * 46 * # Potential bugs 47 * * Glitches due to ripple counter - Verified by ::lp_ticker_glitch_test 48 * 49 * @see hal_lp_ticker_tests 50 * 34 51 * @{ 35 52 */ 36 53 54 /** 55 * \defgroup hal_lp_ticker_tests Low Power Ticker tests 56 * Tests to validate the proper implementation of the low power ticker 57 * 58 * To run the low power ticker hal tests use the command: 59 * 60 * mbed test -t <toolchain> -m <target> -n tests-mbed_hal-common_ticker*,tests-mbed_hal-lp_ticker* 61 * 62 */ 63 64 typedef void (*ticker_irq_handler_type)(const ticker_data_t *const); 65 66 /** Set low power ticker IRQ handler 67 * 68 * @param ticker_irq_handler IRQ handler to be connected 69 * 70 * @return previous ticker IRQ handler 71 * 72 * @note by default IRQ handler is set to ::ticker_irq_handler 73 * @note this function is primarily for testing purposes and it's not required part of HAL implementation 74 * 75 */ 76 ticker_irq_handler_type set_lp_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler); 77 37 78 /** Get low power ticker's data 38 79 * 39 80 * @return The low power ticker data 40 81 */ 41 const ticker_data_t *get_lp_ticker_data(void);82 const ticker_data_t *get_lp_ticker_data(void); 42 83 43 84 /** The wrapper for ticker_irq_handler, to pass lp ticker's data … … 50 91 /** Initialize the low power ticker 51 92 * 93 * Initialize or re-initialize the ticker. This resets all the 94 * clocking and prescaler registers, along with disabling 95 * the compare interrupt. 96 * 97 * Pseudo Code: 98 * @code 99 * void lp_ticker_init() 100 * { 101 * // Enable clock gate so processor can read LPTMR registers 102 * POWER_CTRL |= POWER_CTRL_LPTMR_Msk; 103 * 104 * // Disable the timer and ensure it is powered down 105 * LPTMR_CTRL &= ~(LPTMR_CTRL_ENABLE_Msk | LPTMR_CTRL_COMPARE_ENABLE_Msk); 106 * 107 * // Configure divisors - no division necessary 108 * LPTMR_PRESCALE = 0; 109 * LPTMR_CTRL |= LPTMR_CTRL_ENABLE_Msk; 110 * 111 * // Install the interrupt handler 112 * NVIC_SetVector(LPTMR_IRQn, (uint32_t)lp_ticker_irq_handler); 113 * NVIC_EnableIRQ(LPTMR_IRQn); 114 * } 115 * @endcode 52 116 */ 53 117 void lp_ticker_init(void); 54 118 55 /** Read the current counter 56 * 57 * @return The current timer's counter value in microseconds 119 /** Deinitialize the lower power ticker 120 * 121 * Powerdown the lp ticker in preparation for sleep, powerdown, or reset. 122 * 123 * After calling this function no other ticker functions should be called except 124 * lp_ticker_init(). Calling any function other than init after freeing is 125 * undefined. 126 * 127 * @note This function stops the ticker from counting. 128 */ 129 void lp_ticker_free(void); 130 131 /** Read the current tick 132 * 133 * If no rollover has occurred, the seconds passed since lp_ticker_init() 134 * was called can be found by dividing the ticks returned by this function 135 * by the frequency returned by ::lp_ticker_get_info. 136 * 137 * @return The current timer's counter value in ticks 138 * 139 * Pseudo Code: 140 * @code 141 * uint32_t lp_ticker_read() 142 * { 143 * uint16_t count; 144 * uint16_t last_count; 145 * 146 * // Loop until the same tick is read twice since this 147 * // is ripple counter on a different clock domain. 148 * count = LPTMR_COUNT; 149 * do { 150 * last_count = count; 151 * count = LPTMR_COUNT; 152 * } while (last_count != count); 153 * 154 * return count; 155 * } 156 * @endcode 58 157 */ 59 158 uint32_t lp_ticker_read(void); … … 61 160 /** Set interrupt for specified timestamp 62 161 * 63 * @param timestamp The time in microseconds to be set 162 * @param timestamp The time in ticks to be set 163 * 164 * @note no special handling needs to be done for times in the past 165 * as the common timer code will detect this and call 166 * lp_ticker_fire_interrupt() if this is the case 167 * 168 * @note calling this function with timestamp of more than the supported 169 * number of bits returned by ::lp_ticker_get_info results in undefined 170 * behavior. 171 * 172 * Pseudo Code: 173 * @code 174 * void lp_ticker_set_interrupt(timestamp_t timestamp) 175 * { 176 * LPTMR_COMPARE = timestamp; 177 * LPTMR_CTRL |= LPTMR_CTRL_COMPARE_ENABLE_Msk; 178 * } 179 * @endcode 64 180 */ 65 181 void lp_ticker_set_interrupt(timestamp_t timestamp); … … 67 183 /** Disable low power ticker interrupt 68 184 * 185 * Pseudo Code: 186 * @code 187 * void lp_ticker_disable_interrupt(void) 188 * { 189 * // Disable the compare interrupt 190 * LPTMR_CTRL &= ~LPTMR_CTRL_COMPARE_ENABLE_Msk; 191 * } 192 * @endcode 69 193 */ 70 194 void lp_ticker_disable_interrupt(void); … … 72 196 /** Clear the low power ticker interrupt 73 197 * 198 * Pseudo Code: 199 * @code 200 * void lp_ticker_clear_interrupt(void) 201 * { 202 * // Write to the ICR (interrupt clear register) of the LPTMR 203 * LPTMR_ICR = LPTMR_ICR_COMPARE_Msk; 204 * } 205 * @endcode 74 206 */ 75 207 void lp_ticker_clear_interrupt(void); 208 209 /** Set pending interrupt that should be fired right away. 210 * 211 * Pseudo Code: 212 * @code 213 * void lp_ticker_fire_interrupt(void) 214 * { 215 * NVIC_SetPendingIRQ(LPTMR_IRQn); 216 * } 217 * @endcode 218 */ 219 void lp_ticker_fire_interrupt(void); 220 221 /** Get frequency and counter bits of this ticker. 222 * 223 * Pseudo Code: 224 * @code 225 * const ticker_info_t* lp_ticker_get_info() 226 * { 227 * static const ticker_info_t info = { 228 * 32768, // 32KHz 229 * 16 // 16 bit counter 230 * }; 231 * return &info; 232 * } 233 * @endcode 234 */ 235 const ticker_info_t *lp_ticker_get_info(void); 76 236 77 237 /**@}*/ -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_gpio.c
r352 r374 35 35 } 36 36 37 void gpio_init_in(gpio_t* gpio, PinName pin) { 37 void gpio_init_in(gpio_t *gpio, PinName pin) 38 { 38 39 gpio_init_in_ex(gpio, pin, PullDefault); 39 40 } 40 41 41 void gpio_init_in_ex(gpio_t* gpio, PinName pin, PinMode mode) { 42 void gpio_init_in_ex(gpio_t *gpio, PinName pin, PinMode mode) 43 { 42 44 _gpio_init_in(gpio, pin, mode); 43 45 } 44 46 45 void gpio_init_out(gpio_t* gpio, PinName pin) { 47 void gpio_init_out(gpio_t *gpio, PinName pin) 48 { 46 49 gpio_init_out_ex(gpio, pin, 0); 47 50 } 48 51 49 void gpio_init_out_ex(gpio_t* gpio, PinName pin, int value) { 52 void gpio_init_out_ex(gpio_t *gpio, PinName pin, int value) 53 { 50 54 _gpio_init_out(gpio, pin, PullNone, value); 51 55 } 52 56 53 void gpio_init_inout(gpio_t* gpio, PinName pin, PinDirection direction, PinMode mode, int value) { 57 void gpio_init_inout(gpio_t *gpio, PinName pin, PinDirection direction, PinMode mode, int value) 58 { 54 59 if (direction == PIN_INPUT) { 55 60 _gpio_init_in(gpio, pin, mode); 56 if (pin != NC) 61 if (pin != NC) { 57 62 gpio_write(gpio, value); // we prepare the value in case it is switched later 63 } 58 64 } else { 59 65 _gpio_init_out(gpio, pin, mode, value); -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_lp_ticker_api.c
r352 r374 15 15 */ 16 16 #include "hal/lp_ticker_api.h" 17 #include "hal/mbed_lp_ticker_wrapper.h" 17 18 18 #if DEVICE_L OWPOWERTIMER19 #if DEVICE_LPTICKER 19 20 20 static ticker_event_queue_t events; 21 static ticker_event_queue_t events = { 0 }; 22 23 static ticker_irq_handler_type irq_handler = ticker_irq_handler; 21 24 22 25 static const ticker_interface_t lp_interface = { … … 26 29 .clear_interrupt = lp_ticker_clear_interrupt, 27 30 .set_interrupt = lp_ticker_set_interrupt, 31 .fire_interrupt = lp_ticker_fire_interrupt, 32 .get_info = lp_ticker_get_info, 33 .free = lp_ticker_free, 28 34 }; 29 35 … … 33 39 }; 34 40 35 const ticker_data_t *get_lp_ticker_data(void)41 const ticker_data_t *get_lp_ticker_data(void) 36 42 { 43 #if LPTICKER_DELAY_TICKS > 0 44 return get_lp_ticker_wrapper_data(&lp_data); 45 #else 37 46 return &lp_data; 47 #endif 48 } 49 50 ticker_irq_handler_type set_lp_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler) 51 { 52 ticker_irq_handler_type prev_irq_handler = irq_handler; 53 54 irq_handler = ticker_irq_handler; 55 56 return prev_irq_handler; 38 57 } 39 58 40 59 void lp_ticker_irq_handler(void) 41 60 { 42 ticker_irq_handler(&lp_data); 61 #if LPTICKER_DELAY_TICKS > 0 62 lp_ticker_wrapper_irq_handler(irq_handler); 63 #else 64 if (irq_handler) { 65 irq_handler(&lp_data); 66 } 67 #endif 43 68 } 44 69 -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_pinmap_common.c
r352 r374 17 17 #include "platform/mbed_error.h" 18 18 19 void pinmap_pinout(PinName pin, const PinMap *map) { 20 if (pin == NC) 19 void pinmap_pinout(PinName pin, const PinMap *map) 20 { 21 if (pin == NC) { 21 22 return; 23 } 22 24 23 25 while (map->pin != NC) { … … 30 32 map++; 31 33 } 32 error("could not pinout");34 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_PINMAP_INVALID), "could not pinout", pin); 33 35 } 34 36 35 uint32_t pinmap_merge(uint32_t a, uint32_t b) { 37 uint32_t pinmap_merge(uint32_t a, uint32_t b) 38 { 36 39 // both are the same (inc both NC) 37 if (a == b) 40 if (a == b) { 38 41 return a; 42 } 39 43 40 44 // one (or both) is not connected 41 if (a == (uint32_t)NC) 45 if (a == (uint32_t)NC) { 42 46 return b; 43 if (b == (uint32_t)NC) 47 } 48 if (b == (uint32_t)NC) { 44 49 return a; 50 } 45 51 46 52 // mis-match error case 47 error("pinmap mis-match");53 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_PINMAP_INVALID), "pinmap mis-match", a); 48 54 return (uint32_t)NC; 49 55 } 50 56 51 uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map) { 57 uint32_t pinmap_find_peripheral(PinName pin, const PinMap *map) 58 { 52 59 while (map->pin != NC) { 53 if (map->pin == pin) 60 if (map->pin == pin) { 54 61 return map->peripheral; 62 } 55 63 map++; 56 64 } … … 58 66 } 59 67 60 uint32_t pinmap_peripheral(PinName pin, const PinMap* map) { 68 uint32_t pinmap_peripheral(PinName pin, const PinMap *map) 69 { 61 70 uint32_t peripheral = (uint32_t)NC; 62 71 63 if (pin == (PinName)NC) 72 if (pin == (PinName)NC) { 64 73 return (uint32_t)NC; 74 } 65 75 peripheral = pinmap_find_peripheral(pin, map); 66 if ((uint32_t)NC == peripheral) // no mapping available 67 error("pinmap not found for peripheral"); 76 if ((uint32_t)NC == peripheral) { // no mapping available 77 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_PINMAP_INVALID), "pinmap not found for peripheral", peripheral); 78 } 68 79 return peripheral; 69 80 } 70 81 71 uint32_t pinmap_find_function(PinName pin, const PinMap* map) { 82 uint32_t pinmap_find_function(PinName pin, const PinMap *map) 83 { 72 84 while (map->pin != NC) { 73 if (map->pin == pin) 85 if (map->pin == pin) { 74 86 return map->function; 87 } 75 88 map++; 76 89 } … … 78 91 } 79 92 80 uint32_t pinmap_function(PinName pin, const PinMap* map) { 93 uint32_t pinmap_function(PinName pin, const PinMap *map) 94 { 81 95 uint32_t function = (uint32_t)NC; 82 96 83 if (pin == (PinName)NC) 97 if (pin == (PinName)NC) { 84 98 return (uint32_t)NC; 99 } 85 100 function = pinmap_find_function(pin, map); 86 if ((uint32_t)NC == function) // no mapping available 87 error("pinmap not found for function"); 101 if ((uint32_t)NC == function) { // no mapping available 102 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_PINMAP_INVALID), "pinmap not found for function", function); 103 } 88 104 return function; 89 105 } -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_ticker_api.c
r352 r374 14 14 * limitations under the License. 15 15 */ 16 #include <stdio.h> 16 17 #include <stddef.h> 17 18 #include "hal/ticker_api.h" 18 19 #include "platform/mbed_critical.h" 19 20 void ticker_set_handler(const ticker_data_t *const data, ticker_event_handler handler) { 21 data->interface->init(); 22 23 data->queue->event_handler = handler; 24 } 25 26 void ticker_irq_handler(const ticker_data_t *const data) { 27 data->interface->clear_interrupt(); 20 #include "platform/mbed_assert.h" 21 22 static void schedule_interrupt(const ticker_data_t *const ticker); 23 static void update_present_time(const ticker_data_t *const ticker); 24 25 /* 26 * Initialize a ticker instance. 27 */ 28 static void initialize(const ticker_data_t *ticker) 29 { 30 // return if the queue has already been initialized, in that case the 31 // interface used by the queue is already initialized. 32 if (ticker->queue->initialized) { 33 return; 34 } 35 if (ticker->queue->suspended) { 36 return; 37 } 38 39 ticker->interface->init(); 40 41 const ticker_info_t *info = ticker->interface->get_info(); 42 uint32_t frequency = info->frequency; 43 if (info->frequency == 0) { 44 MBED_ASSERT(0); 45 frequency = 1000000; 46 } 47 48 uint8_t frequency_shifts = 0; 49 for (uint8_t i = 31; i > 0; --i) { 50 if ((1 << i) == frequency) { 51 frequency_shifts = i; 52 break; 53 } 54 } 55 56 uint32_t bits = info->bits; 57 if ((info->bits > 32) || (info->bits < 4)) { 58 MBED_ASSERT(0); 59 bits = 32; 60 } 61 uint32_t max_delta = 0x7 << (bits - 4); // 7/16th 62 uint64_t max_delta_us = 63 ((uint64_t)max_delta * 1000000 + frequency - 1) / frequency; 64 65 ticker->queue->event_handler = NULL; 66 ticker->queue->head = NULL; 67 ticker->queue->tick_last_read = ticker->interface->read(); 68 ticker->queue->tick_remainder = 0; 69 ticker->queue->frequency = frequency; 70 ticker->queue->frequency_shifts = frequency_shifts; 71 ticker->queue->bitmask = ((uint64_t)1 << bits) - 1; 72 ticker->queue->max_delta = max_delta; 73 ticker->queue->max_delta_us = max_delta_us; 74 ticker->queue->present_time = 0; 75 ticker->queue->dispatching = false; 76 ticker->queue->suspended = false; 77 ticker->queue->initialized = true; 78 79 update_present_time(ticker); 80 schedule_interrupt(ticker); 81 } 82 83 /** 84 * Set the event handler function of a ticker instance. 85 */ 86 static void set_handler(const ticker_data_t *const ticker, ticker_event_handler handler) 87 { 88 ticker->queue->event_handler = handler; 89 } 90 91 /* 92 * Convert a 32 bit timestamp into a 64 bit timestamp. 93 * 94 * A 64 bit timestamp is used as the point of time of reference while the 95 * timestamp to convert is relative to this point of time. 96 * 97 * The lower 32 bits of the timestamp returned will be equal to the timestamp to 98 * convert. 99 * 100 * If the timestamp to convert is less than the lower 32 bits of the time 101 * reference then the timestamp to convert is seen as an overflowed value and 102 * the upper 32 bit of the timestamp returned will be equal to the upper 32 bit 103 * of the reference point + 1. 104 * Otherwise, the upper 32 bit returned will be equal to the upper 32 bit of the 105 * reference point. 106 * 107 * @param ref: The 64 bit timestamp of reference. 108 * @param timestamp: The timestamp to convert. 109 */ 110 static us_timestamp_t convert_timestamp(us_timestamp_t ref, timestamp_t timestamp) 111 { 112 bool overflow = timestamp < ((timestamp_t) ref) ? true : false; 113 114 us_timestamp_t result = (ref & ~((us_timestamp_t)UINT32_MAX)) | timestamp; 115 if (overflow) { 116 result += (1ULL << 32); 117 } 118 119 return result; 120 } 121 122 /** 123 * Update the present timestamp value of a ticker. 124 */ 125 static void update_present_time(const ticker_data_t *const ticker) 126 { 127 ticker_event_queue_t *queue = ticker->queue; 128 if (queue->suspended) { 129 return; 130 } 131 uint32_t ticker_time = ticker->interface->read(); 132 if (ticker_time == ticker->queue->tick_last_read) { 133 // No work to do 134 return; 135 } 136 137 uint64_t elapsed_ticks = (ticker_time - queue->tick_last_read) & queue->bitmask; 138 queue->tick_last_read = ticker_time; 139 140 uint64_t elapsed_us; 141 if (1000000 == queue->frequency) { 142 // Optimized for 1MHz 143 144 elapsed_us = elapsed_ticks; 145 } else if (0 != queue->frequency_shifts) { 146 // Optimized for frequencies divisible by 2 147 uint64_t us_x_ticks = elapsed_ticks * 1000000; 148 elapsed_us = us_x_ticks >> queue->frequency_shifts; 149 150 // Update remainder 151 queue->tick_remainder += us_x_ticks - (elapsed_us << queue->frequency_shifts); 152 if (queue->tick_remainder >= queue->frequency) { 153 elapsed_us += 1; 154 queue->tick_remainder -= queue->frequency; 155 } 156 } else { 157 // General case 158 159 uint64_t us_x_ticks = elapsed_ticks * 1000000; 160 elapsed_us = us_x_ticks / queue->frequency; 161 162 // Update remainder 163 queue->tick_remainder += us_x_ticks - elapsed_us * queue->frequency; 164 if (queue->tick_remainder >= queue->frequency) { 165 elapsed_us += 1; 166 queue->tick_remainder -= queue->frequency; 167 } 168 } 169 170 // Update current time 171 queue->present_time += elapsed_us; 172 } 173 174 /** 175 * Given the absolute timestamp compute the hal tick timestamp rounded up. 176 */ 177 static timestamp_t compute_tick_round_up(const ticker_data_t *const ticker, us_timestamp_t timestamp) 178 { 179 ticker_event_queue_t *queue = ticker->queue; 180 us_timestamp_t delta_us = timestamp - queue->present_time; 181 182 timestamp_t delta = ticker->queue->max_delta; 183 if (delta_us <= ticker->queue->max_delta_us) { 184 // Checking max_delta_us ensures the operation will not overflow 185 186 if (1000000 == queue->frequency) { 187 // Optimized for 1MHz 188 189 delta = delta_us; 190 if (delta > ticker->queue->max_delta) { 191 delta = ticker->queue->max_delta; 192 } 193 } else if (0 != queue->frequency_shifts) { 194 // Optimized frequencies divisible by 2 195 196 delta = ((delta_us << ticker->queue->frequency_shifts) + 1000000 - 1) / 1000000; 197 if (delta > ticker->queue->max_delta) { 198 delta = ticker->queue->max_delta; 199 } 200 } else { 201 // General case 202 203 delta = (delta_us * queue->frequency + 1000000 - 1) / 1000000; 204 if (delta > ticker->queue->max_delta) { 205 delta = ticker->queue->max_delta; 206 } 207 } 208 } 209 return (queue->tick_last_read + delta) & queue->bitmask; 210 } 211 212 /** 213 * Return 1 if the tick has incremented to or past match_tick, otherwise 0. 214 */ 215 int _ticker_match_interval_passed(timestamp_t prev_tick, timestamp_t cur_tick, timestamp_t match_tick) 216 { 217 if (match_tick > prev_tick) { 218 return (cur_tick >= match_tick) || (cur_tick < prev_tick); 219 } else { 220 return (cur_tick < prev_tick) && (cur_tick >= match_tick); 221 } 222 } 223 224 /** 225 * Compute the time when the interrupt has to be triggered and schedule it. 226 * 227 * If there is no event in the queue or the next event to execute is in more 228 * than ticker.queue.max_delta ticks from now then the ticker irq will be 229 * scheduled in ticker.queue.max_delta ticks. Otherwise the irq will be 230 * scheduled to happen when the running counter reach the timestamp of the 231 * first event in the queue. 232 * 233 * @note If there is no event in the queue then the interrupt is scheduled to 234 * in ticker.queue.max_delta. This is necessary to keep track 235 * of the timer overflow. 236 */ 237 static void schedule_interrupt(const ticker_data_t *const ticker) 238 { 239 ticker_event_queue_t *queue = ticker->queue; 240 if (queue->suspended || ticker->queue->dispatching) { 241 // Don't schedule the next interrupt until dispatching is 242 // finished. This prevents repeated calls to interface->set_interrupt 243 return; 244 } 245 246 update_present_time(ticker); 247 248 if (ticker->queue->head) { 249 us_timestamp_t present = ticker->queue->present_time; 250 us_timestamp_t match_time = ticker->queue->head->timestamp; 251 252 // if the event at the head of the queue is in the past then schedule 253 // it immediately. 254 if (match_time <= present) { 255 ticker->interface->fire_interrupt(); 256 return; 257 } 258 259 timestamp_t match_tick = compute_tick_round_up(ticker, match_time); 260 261 // The same tick should never occur since match_tick is rounded up. 262 // If the same tick is returned scheduling will not work correctly. 263 MBED_ASSERT(match_tick != queue->tick_last_read); 264 265 ticker->interface->set_interrupt(match_tick); 266 timestamp_t cur_tick = ticker->interface->read(); 267 268 if (_ticker_match_interval_passed(queue->tick_last_read, cur_tick, match_tick)) { 269 ticker->interface->fire_interrupt(); 270 } 271 } else { 272 uint32_t match_tick = 273 (queue->tick_last_read + queue->max_delta) & queue->bitmask; 274 ticker->interface->set_interrupt(match_tick); 275 } 276 } 277 278 void ticker_set_handler(const ticker_data_t *const ticker, ticker_event_handler handler) 279 { 280 initialize(ticker); 281 282 core_util_critical_section_enter(); 283 set_handler(ticker, handler); 284 core_util_critical_section_exit(); 285 } 286 287 void ticker_irq_handler(const ticker_data_t *const ticker) 288 { 289 core_util_critical_section_enter(); 290 291 ticker->interface->clear_interrupt(); 292 if (ticker->queue->suspended) { 293 core_util_critical_section_exit(); 294 return; 295 } 28 296 29 297 /* Go through all the pending TimerEvents */ 298 ticker->queue->dispatching = true; 30 299 while (1) { 31 if (data->queue->head == NULL) { 32 // There are no more TimerEvents left, so disable matches. 33 data->interface->disable_interrupt(); 34 return; 35 } 36 37 if ((int)(data->queue->head->timestamp - data->interface->read()) <= 0) { 300 if (ticker->queue->head == NULL) { 301 break; 302 } 303 304 // update the current timestamp used by the queue 305 update_present_time(ticker); 306 307 if (ticker->queue->head->timestamp <= ticker->queue->present_time) { 38 308 // This event was in the past: 39 309 // point to the following one and execute its handler 40 ticker_event_t *p = data->queue->head;41 data->queue->head = data->queue->head->next;42 if ( data->queue->event_handler != NULL) {43 (* data->queue->event_handler)(p->id); // NOTE: the handler can set new events310 ticker_event_t *p = ticker->queue->head; 311 ticker->queue->head = ticker->queue->head->next; 312 if (ticker->queue->event_handler != NULL) { 313 (*ticker->queue->event_handler)(p->id); // NOTE: the handler can set new events 44 314 } 45 315 /* Note: We continue back to examining the head because calling the 46 316 * event handler may have altered the chain of pending events. */ 47 317 } else { 48 // This event and the following ones in the list are in the future: 49 // set it as next interrupt and return 50 data->interface->set_interrupt(data->queue->head->timestamp); 51 return; 52 } 53 } 54 } 55 56 void ticker_insert_event(const ticker_data_t *const data, ticker_event_t *obj, timestamp_t timestamp, uint32_t id) { 57 /* disable interrupts for the duration of the function */ 58 core_util_critical_section_enter(); 318 break; 319 } 320 } 321 ticker->queue->dispatching = false; 322 323 schedule_interrupt(ticker); 324 325 core_util_critical_section_exit(); 326 } 327 328 void ticker_insert_event(const ticker_data_t *const ticker, ticker_event_t *obj, timestamp_t timestamp, uint32_t id) 329 { 330 core_util_critical_section_enter(); 331 332 // update the current timestamp 333 update_present_time(ticker); 334 us_timestamp_t absolute_timestamp = convert_timestamp( 335 ticker->queue->present_time, 336 timestamp 337 ); 338 339 // defer to ticker_insert_event_us 340 ticker_insert_event_us( 341 ticker, 342 obj, absolute_timestamp, id 343 ); 344 345 core_util_critical_section_exit(); 346 } 347 348 void ticker_insert_event_us(const ticker_data_t *const ticker, ticker_event_t *obj, us_timestamp_t timestamp, uint32_t id) 349 { 350 core_util_critical_section_enter(); 351 352 // update the current timestamp 353 update_present_time(ticker); 59 354 60 355 // initialise our data … … 65 360 an element this should come before (which is possibly the 66 361 head). */ 67 ticker_event_t *prev = NULL, *p = data->queue->head;362 ticker_event_t *prev = NULL, *p = ticker->queue->head; 68 363 while (p != NULL) { 69 364 /* check if we come before p */ 70 if ( (int)(timestamp - p->timestamp) < 0) {365 if (timestamp < p->timestamp) { 71 366 break; 72 367 } … … 75 370 p = p->next; 76 371 } 77 372 78 373 /* if we're at the end p will be NULL, which is correct */ 79 374 obj->next = p; … … 81 376 /* if prev is NULL we're at the head */ 82 377 if (prev == NULL) { 83 data->queue->head = obj;84 data->interface->set_interrupt(timestamp);378 ticker->queue->head = obj; 379 schedule_interrupt(ticker); 85 380 } else { 86 381 prev->next = obj; … … 90 385 } 91 386 92 void ticker_remove_event(const ticker_data_t *const data, ticker_event_t *obj) { 387 void ticker_remove_event(const ticker_data_t *const ticker, ticker_event_t *obj) 388 { 93 389 core_util_critical_section_enter(); 94 390 95 391 // remove this object from the list 96 if ( data->queue->head == obj) {392 if (ticker->queue->head == obj) { 97 393 // first in the list, so just drop me 98 data->queue->head = obj->next; 99 if (data->queue->head == NULL) { 100 data->interface->disable_interrupt(); 101 } else { 102 data->interface->set_interrupt(data->queue->head->timestamp); 103 } 394 ticker->queue->head = obj->next; 395 schedule_interrupt(ticker); 104 396 } else { 105 397 // find the object before me, then drop me 106 ticker_event_t * p = data->queue->head;398 ticker_event_t *p = ticker->queue->head; 107 399 while (p != NULL) { 108 400 if (p->next == obj) { … … 117 409 } 118 410 119 timestamp_t ticker_read(const ticker_data_t *const data) 120 { 121 return data->interface->read(); 411 timestamp_t ticker_read(const ticker_data_t *const ticker) 412 { 413 return ticker_read_us(ticker); 414 } 415 416 us_timestamp_t ticker_read_us(const ticker_data_t *const ticker) 417 { 418 initialize(ticker); 419 420 core_util_critical_section_enter(); 421 update_present_time(ticker); 422 core_util_critical_section_exit(); 423 424 return ticker->queue->present_time; 122 425 } 123 426 … … 136 439 return ret; 137 440 } 441 442 void ticker_suspend(const ticker_data_t *const ticker) 443 { 444 core_util_critical_section_enter(); 445 446 ticker->queue->suspended = true; 447 448 core_util_critical_section_exit(); 449 } 450 451 void ticker_resume(const ticker_data_t *const ticker) 452 { 453 core_util_critical_section_enter(); 454 455 ticker->queue->suspended = false; 456 if (ticker->queue->initialized) { 457 ticker->queue->tick_last_read = ticker->interface->read(); 458 459 update_present_time(ticker); 460 schedule_interrupt(ticker); 461 } else { 462 initialize(ticker); 463 } 464 465 core_util_critical_section_exit(); 466 } -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_us_ticker_api.c
r352 r374 16 16 #include "hal/us_ticker_api.h" 17 17 18 static ticker_event_queue_t events; 18 static ticker_event_queue_t events = { 0 }; 19 20 static ticker_irq_handler_type irq_handler = ticker_irq_handler; 19 21 20 22 static const ticker_interface_t us_interface = { … … 24 26 .clear_interrupt = us_ticker_clear_interrupt, 25 27 .set_interrupt = us_ticker_set_interrupt, 28 .fire_interrupt = us_ticker_fire_interrupt, 29 .get_info = us_ticker_get_info, 30 .free = us_ticker_free, 26 31 }; 27 32 28 33 static const ticker_data_t us_data = { 29 34 .interface = &us_interface, 30 .queue = &events ,35 .queue = &events 31 36 }; 32 37 33 const ticker_data_t *get_us_ticker_data(void)38 const ticker_data_t *get_us_ticker_data(void) 34 39 { 35 40 return &us_data; 36 41 } 37 42 43 ticker_irq_handler_type set_us_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler) 44 { 45 ticker_irq_handler_type prev_irq_handler = irq_handler; 46 47 irq_handler = ticker_irq_handler; 48 49 return prev_irq_handler; 50 } 51 38 52 void us_ticker_irq_handler(void) 39 53 { 40 ticker_irq_handler(&us_data); 54 if (irq_handler) { 55 irq_handler(&us_data); 56 } 41 57 } -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/rtc_api.h
r352 r374 1 2 /** \addtogroup hal */3 /** @{*/4 1 /* mbed Microcontroller Library 5 2 * Copyright (c) 2006-2013 ARM Limited … … 17 14 * limitations under the License. 18 15 */ 16 17 /** \addtogroup hal */ 18 /** @{*/ 19 19 20 #ifndef MBED_RTC_API_H 20 21 #define MBED_RTC_API_H 21 22 22 23 #include "device.h" 23 24 #if DEVICE_RTC25 24 26 25 #include <time.h> … … 31 30 32 31 /** 33 * \defgroup hal_rtc RTC hal functions 32 * \defgroup hal_rtc RTC hal 33 * 34 * The RTC hal provides a low level interface to the Real Time Counter (RTC) of a 35 * target. 36 * 37 * # Defined behaviour 38 * * The function ::rtc_init is safe to call repeatedly - Verified by test ::rtc_init_test. 39 * * RTC accuracy is at least 10% - Verified by test ::rtc_accuracy_test. 40 * * Init/free doesn't stop RTC from counting - Verified by test ::rtc_persist_test. 41 * * Software reset doesn't stop RTC from counting - Verified by test ::rtc_reset_test. 42 * * Sleep modes don't stop RTC from counting - Verified by test ::rtc_sleep_test. 43 * * Shutdown mode doesn't stop RTC from counting - Not verified. 44 * * The functions ::rtc_write/::rtc_read provides availability to set/get RTC time 45 * - Verified by test ::rtc_write_read_test. 46 * * The functions ::rtc_isenabled returns 1 if the RTC is counting and the time has been set, 47 * 0 otherwise - Verified by test ::rtc_enabled_test. 48 * 49 * # Undefined behaviour 50 * * Calling any function other than ::rtc_init before the initialisation of the RTC 51 * 52 * # Potential bugs 53 * * Incorrect overflow handling - Verified by ::rtc_range_test 54 * * Glitches due to ripple counter - Verified by ::rtc_glitch_test 55 * 56 * @see hal_rtc_tests 57 * 34 58 * @{ 35 59 */ 36 60 61 /** 62 * \defgroup hal_rtc_tests RTC hal tests 63 * The RTC test validate proper implementation of the RTC hal. 64 * 65 * To run the RTC hal tests use the command: 66 * 67 * mbed test -t <toolchain> -m <target> -n tests-mbed_hal-rtc* 68 */ 69 70 37 71 /** Initialize the RTC peripheral 38 72 * 73 * Powerup the RTC in perpetration for access. This function must be called 74 * before any other RTC functions ares called. This does not change the state 75 * of the RTC. It just enables access to it. 76 * 77 * @note This function is safe to call repeatedly - Tested by ::rtc_init_test 78 * 79 * Example Implementation Pseudo Code: 80 * @code 81 * void rtc_init() 82 * { 83 * // Enable clock gate so processor can read RTC registers 84 * POWER_CTRL |= POWER_CTRL_RTC_Msk; 85 * 86 * // See if the RTC is already setup 87 * if (!(RTC_STATUS & RTC_STATUS_COUNTING_Msk)) { 88 * 89 * // Setup the RTC clock source 90 * RTC_CTRL |= RTC_CTRL_CLK32_Msk; 91 * } 92 * } 93 * @endcode 39 94 */ 40 95 void rtc_init(void); … … 42 97 /** Deinitialize RTC 43 98 * 44 * TODO: The function is not used by rtc api in mbed-drivers. 99 * Powerdown the RTC in preparation for sleep, powerdown or reset. That should only 100 * affect the CPU domain and not the time keeping logic. 101 * After this function is called no other RTC functions should be called 102 * except for ::rtc_init. 103 * 104 * @note This function does not stop the RTC from counting - Tested by ::rtc_persist_test 105 * 106 * Example Implementation Pseudo Code: 107 * @code 108 * void rtc_free() 109 * { 110 * // Disable clock gate since processor no longer needs to read RTC registers 111 * POWER_CTRL &= ~POWER_CTRL_RTC_Msk; 112 * } 113 * @endcode 45 114 */ 46 115 void rtc_free(void); 47 116 48 /** Get the RTC enable status117 /** Check if the RTC has the time set and is counting 49 118 * 50 * @retval 0 disabled 51 * @retval 1 enabled 119 * @retval 0 The time reported by the RTC is not valid 120 * @retval 1 The time has been set the RTC is counting 121 * 122 * Example Implementation Pseudo Code: 123 * @code 124 * int rtc_isenabled() 125 * { 126 * if (RTC_STATUS & RTC_STATUS_COUNTING_Msk) { 127 * return 1; 128 * } else { 129 * return 0; 130 * } 131 * } 132 * @endcode 52 133 */ 53 134 int rtc_isenabled(void); … … 55 136 /** Get the current time from the RTC peripheral 56 137 * 57 * @return The current time 138 * @return The current time in seconds 139 * 140 * @note Some RTCs are not synchronized with the main clock. If 141 * this is the case with your RTC then you must read the RTC time 142 * in a loop to prevent reading the wrong time due to a glitch. 143 * The test ::rtc_glitch_test is intended to catch this bug. 144 * 145 * Example implementation for an unsynchronized ripple counter: 146 * @code 147 * time_t rtc_read() 148 * { 149 * uint32_t val; 150 * uint32_t last_val; 151 * 152 * // Loop until the same value is read twice 153 * val = RTC_SECONDS; 154 * do { 155 * last_val = val; 156 * val = RTC_SECONDS; 157 * } while (last_val != val); 158 * 159 * return (time_t)val; 160 * } 161 * @endcode 58 162 */ 59 163 time_t rtc_read(void); 60 164 61 /** Set the current timeto the RTC peripheral165 /** Write the current time in seconds to the RTC peripheral 62 166 * 63 * @param t The current time to be set 167 * @param t The current time to be set in seconds. 168 * 169 * Example Implementation Pseudo Code: 170 * @code 171 * void rtc_write(time_t t) 172 * { 173 * RTC_SECONDS = t; 174 * } 175 * @endcode 64 176 */ 65 177 void rtc_write(time_t t); … … 73 185 #endif 74 186 75 #endif76 77 187 /** @}*/ -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/sleep_api.h
r352 r374 28 28 #endif 29 29 30 /** 31 * \defgroup hal_sleep sleep hal requirements 32 * Low level interface to the sleep mode of a target. 33 * 34 * # Defined behaviour 35 * 36 * * Sleep mode 37 * * wake-up time should be less than 10 us - Verified by sleep_usticker_test(). 38 * * the processor can be woken up by any internal peripheral interrupt - Verified by sleep_usticker_test(). 39 * * all peripherals operate as in run mode - not verified. 40 * * the processor can be woken up by external pin interrupt - not verified. 41 * * Deep sleep 42 * * the wake-up time should be less than 10 ms - Verified by deepsleep_lpticker_test(). 43 * * lp ticker should wake up a target from this mode - Verified by deepsleep_lpticker_test(). 44 * * RTC should wake up a target from this mode - not verified. 45 * * an external interrupt on a pin should wake up a target from this mode - not verified. 46 * * a watchdog timer should wake up a target from this mode - not verified. 47 * * High-speed clocks are turned off - Verified by deepsleep_high_speed_clocks_turned_off_test(). 48 * * RTC keeps time - Verified by rtc_sleep_test(). 49 * 50 * # Undefined behaviour 51 * 52 * * peripherals aside from RTC, GPIO and lp ticker result in undefined behaviour in deep sleep. 53 * @{ 54 */ 55 56 /** 57 * \defgroup hal_sleep_tests sleep hal tests 58 * The sleep HAL tests ensure driver conformance to defined behaviour. 59 * 60 * To run the sleep hal tests use the command: 61 * 62 * mbed test -t <toolchain> -m <target> -n tests-mbed_hal-sleep* 63 * 64 */ 65 30 66 /** Send the microcontroller to sleep 31 67 * 32 * The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the68 * The processor is setup ready for sleep, and sent to sleep. In this mode, the 33 69 * system clock to the core is stopped until a reset or an interrupt occurs. This eliminates 34 70 * dynamic power used by the processor, memory systems and buses. The processor, peripheral and … … 37 73 * The processor can be woken up by any internal peripheral interrupt or external pin interrupt. 38 74 * 39 * @note 40 * The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored. 41 * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be 42 * able to access the LocalFileSystem 75 * The wake-up time shall be less than 10 us. 76 * 43 77 */ 44 78 void hal_sleep(void); … … 47 81 * 48 82 * This processor is setup ready for deep sleep, and sent to sleep using __WFI(). This mode 49 * has the same sleep features as sleep plus it powers down peripherals and clocks. All state50 * is still maintained.83 * has the same sleep features as sleep plus it powers down peripherals and high frequency clocks. 84 * All state is still maintained. 51 85 * 52 * The processor can only be woken up by an external interrupt on a pin or a watchdog timer.86 * The processor can only be woken up by low power ticker, RTC, an external interrupt on a pin or a watchdog timer. 53 87 * 54 * @note 55 * The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored. 56 * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be 57 * able to access the LocalFileSystem 88 * The wake-up time shall be less than 10 ms. 58 89 */ 59 90 void hal_deepsleep(void); 91 92 /**@}*/ 60 93 61 94 #ifdef __cplusplus -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/spi_api.h
r364 r374 34 34 35 35 #define SPI_FILL_WORD (0xFFFF) 36 #define SPI_FILL_CHAR (0xFF) 36 37 37 38 #if DEVICE_SPI_ASYNCH -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/ticker_api.h
r352 r374 21 21 22 22 #include <stdint.h> 23 #include <stdbool.h> 23 24 #include "device.h" 24 25 26 /** 27 * Legacy format representing a timestamp in us. 28 * Given it is modeled as a 32 bit integer, this type can represent timestamp 29 * up to 4294 seconds (71 minutes). 30 * Prefer using us_timestamp_t which store timestamp as 64 bits integer. 31 */ 25 32 typedef uint32_t timestamp_t; 26 33 34 /** 35 * A us timestamp stored in a 64 bit integer. 36 * Can store timestamp up to 584810 years. 37 */ 38 typedef uint64_t us_timestamp_t; 39 27 40 /** Ticker's event structure 28 41 */ 29 42 typedef struct ticker_event_s { 30 timestamp_ttimestamp; /**< Event's timestamp */43 us_timestamp_t timestamp; /**< Event's timestamp */ 31 44 uint32_t id; /**< TimerEvent object */ 32 45 struct ticker_event_s *next; /**< Next event in the queue */ … … 34 47 35 48 typedef void (*ticker_event_handler)(uint32_t id); 49 50 /** Information about the ticker implementation 51 */ 52 typedef struct { 53 uint32_t frequency; /**< Frequency in Hz this ticker runs at */ 54 uint32_t bits; /**< Number of bits this ticker supports */ 55 } ticker_info_t; 56 36 57 37 58 /** Ticker's interface structure - required API for a ticker … … 43 64 void (*clear_interrupt)(void); /**< Clear interrupt function */ 44 65 void (*set_interrupt)(timestamp_t timestamp); /**< Set interrupt function */ 66 void (*fire_interrupt)(void); /**< Fire interrupt right-away */ 67 void (*free)(void); /**< Disable function */ 68 const ticker_info_t *(*get_info)(void); /**< Return info about this ticker's implementation */ 45 69 } ticker_interface_t; 46 70 … … 50 74 ticker_event_handler event_handler; /**< Event handler */ 51 75 ticker_event_t *head; /**< A pointer to head */ 76 uint32_t frequency; /**< Frequency of the timer in Hz */ 77 uint32_t bitmask; /**< Mask to be applied to time values read */ 78 uint32_t max_delta; /**< Largest delta in ticks that can be used when scheduling */ 79 uint64_t max_delta_us; /**< Largest delta in us that can be used when scheduling */ 80 uint32_t tick_last_read; /**< Last tick read */ 81 uint64_t tick_remainder; /**< Ticks that have not been added to base_time */ 82 us_timestamp_t present_time; /**< Store the timestamp used for present time */ 83 bool initialized; /**< Indicate if the instance is initialized */ 84 bool dispatching; /**< The function ticker_irq_handler is dispatching */ 85 bool suspended; /**< Indicate if the instance is suspended */ 86 uint8_t frequency_shifts; /**< If frequency is a value of 2^n, this is n, otherwise 0 */ 52 87 } ticker_event_queue_t; 53 88 … … 70 105 /** Initialize a ticker and set the event handler 71 106 * 72 * @param data The ticker's data107 * @param ticker The ticker object. 73 108 * @param handler A handler to be set 74 109 */ 75 void ticker_set_handler(const ticker_data_t *const data, ticker_event_handler handler);110 void ticker_set_handler(const ticker_data_t *const ticker, ticker_event_handler handler); 76 111 77 112 /** IRQ handler that goes through the events to trigger overdue events. 78 113 * 79 * @param data The ticker's data80 */ 81 void ticker_irq_handler(const ticker_data_t *const data);114 * @param ticker The ticker object. 115 */ 116 void ticker_irq_handler(const ticker_data_t *const ticker); 82 117 83 118 /** Remove an event from the queue 84 119 * 85 * @param data The ticker's data120 * @param ticker The ticker object. 86 121 * @param obj The event object to be removed from the queue 87 122 */ 88 void ticker_remove_event(const ticker_data_t *const data, ticker_event_t *obj);123 void ticker_remove_event(const ticker_data_t *const ticker, ticker_event_t *obj); 89 124 90 125 /** Insert an event to the queue 91 126 * 92 * @param data The ticker's data 127 * The event will be executed in timestamp - ticker_read(). 128 * 129 * @warning This function does not consider timestamp in the past. If an event 130 * is inserted with a timestamp less than the current timestamp then the event 131 * will be executed in timestamp - ticker_read() us. 132 * The internal counter wrap very quickly it is hard to decide weither an 133 * event is in the past or in 1 hour. 134 * 135 * @note prefer the use of ticker_insert_event_us which allows registration of 136 * absolute timestamp. 137 * 138 * @param ticker The ticker object. 93 139 * @param obj The event object to be inserted to the queue 94 140 * @param timestamp The event's timestamp 95 141 * @param id The event object 96 142 */ 97 void ticker_insert_event(const ticker_data_t *const data, ticker_event_t *obj, timestamp_t timestamp, uint32_t id); 98 99 /** Read the current ticker's timestamp 100 * 101 * @param data The ticker's data 143 void ticker_insert_event(const ticker_data_t *const ticker, ticker_event_t *obj, timestamp_t timestamp, uint32_t id); 144 145 /** Insert an event to the queue 146 * 147 * The event will be executed in timestamp - ticker_read_us() us. 148 * 149 * @note If an event is inserted with a timestamp less than the current 150 * timestamp then the event will be scheduled immediately resulting in 151 * an instant call to event handler. 152 * 153 * @param ticker The ticker object. 154 * @param obj The event object to be inserted to the queue 155 * @param timestamp The event's timestamp 156 * @param id The event object 157 */ 158 void ticker_insert_event_us(const ticker_data_t *const ticker, ticker_event_t *obj, us_timestamp_t timestamp, uint32_t id); 159 160 /** Read the current (relative) ticker's timestamp 161 * 162 * @warning Return a relative timestamp because the counter wrap every 4294 163 * seconds. 164 * 165 * @param ticker The ticker object. 102 166 * @return The current timestamp 103 167 */ 104 timestamp_t ticker_read(const ticker_data_t *const data); 168 timestamp_t ticker_read(const ticker_data_t *const ticker); 169 170 /** Read the current (absolute) ticker's timestamp 171 * 172 * @warning Return an absolute timestamp counting from the initialization of the 173 * ticker. 174 * 175 * @param ticker The ticker object. 176 * @return The current timestamp 177 */ 178 us_timestamp_t ticker_read_us(const ticker_data_t *const ticker); 105 179 106 180 /** Read the next event's timestamp 107 181 * 108 * @param data The ticker's data 182 * @param ticker The ticker object. 183 * @param timestamp The timestamp object. 109 184 * @return 1 if timestamp is pending event, 0 if there's no event pending 110 185 */ 111 int ticker_get_next_timestamp(const ticker_data_t *const data, timestamp_t *timestamp); 186 int ticker_get_next_timestamp(const ticker_data_t *const ticker, timestamp_t *timestamp); 187 188 /** Suspend this ticker 189 * 190 * When suspended reads will always return the same time and no 191 * events will be dispatched. When suspended the common layer 192 * will only ever call the interface function clear_interrupt() 193 * and that is only if ticker_irq_handler is called. 194 * 195 * 196 * @param ticker The ticker object. 197 */ 198 void ticker_suspend(const ticker_data_t *const ticker); 199 200 /** Resume this ticker 201 * 202 * When resumed the ticker will ignore any time that has passed 203 * and continue counting up where it left off. 204 * 205 * @param ticker The ticker object. 206 */ 207 void ticker_resume(const ticker_data_t *const ticker); 208 209 /* Private functions 210 * 211 * @cond PRIVATE 212 * 213 */ 214 215 int _ticker_match_interval_passed(timestamp_t prev_tick, timestamp_t cur_tick, timestamp_t match_tick); 216 217 /* 218 * @endcond PRIVATE 219 * 220 */ 112 221 113 222 /**@}*/ -
asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/us_ticker_api.h
r352 r374 28 28 29 29 /** 30 * \defgroup hal_UsTicker Microseconds Ticker Functions 30 * \defgroup hal_us_ticker Microsecond Ticker 31 * Low level interface to the microsecond ticker of a target 32 * 33 * # Defined behavior 34 * * Has a reported frequency between 250KHz and 8MHz - Verified by test ::us_ticker_info_test 35 * * Has a counter that is at least 16 bits wide - Verified by test ::us_ticker_info_test 36 * * All behavior defined by the @ref hal_ticker_shared "ticker specification" 37 * 38 * # Undefined behavior 39 * * See the @ref hal_ticker_shared "ticker specification" 40 * 41 * @see hal_us_ticker_tests 42 * 31 43 * @{ 32 44 */ 33 45 46 /** 47 * \defgroup hal_us_ticker_tests Microsecond Ticker tests 48 * Tests to validate the proper implementation of the microsecond ticker 49 * 50 * To run the microsecond ticker hal tests use the command: 51 * 52 * mbed test -t <toolchain> -m <target> -n tests-mbed_hal-common_ticker*,tests-mbed_hal-us_ticker* 53 * 54 * @see hal_ticker_tests 55 * 56 */ 57 58 /** 59 * \defgroup hal_ticker_shared Ticker Hal 60 * Low level interface to the ticker of a target 61 * 62 * # Defined behavior 63 * * The function ticker_init is safe to call repeatedly - Verified by test ::ticker_init_test 64 * * The function ticker_init allows the ticker to keep counting and disables the ticker interrupt - Verified by test ::ticker_init_test 65 * * Ticker frequency is non-zero and counter is at least 8 bits - Verified by ::ticker_info_test 66 * * The ticker rolls over at (1 << bits) and continues counting starting from 0 - Verified by ::ticker_overflow_test 67 * * The ticker counts at the specified frequency +- 10% - Verified by ::ticker_frequency_test 68 * * The ticker increments by 1 each tick - Verified by ::ticker_increment_test 69 * * The ticker interrupt fires only when the ticker times increments to or past the value set by ticker_set_interrupt. 70 * Verified by ::ticker_interrupt_test and ::ticker_past_test 71 * * It is safe to call ticker_set_interrupt repeatedly before the handler is called - Verified by ::ticker_repeat_reschedule_test 72 * * The function ticker_fire_interrupt causes ticker_irq_handler to be called immediately from interrupt context - 73 * Verified by ::ticker_fire_now_test 74 * * The ticker operations ticker_read, ticker_clear_interrupt, ticker_set_interrupt and ticker_fire_interrupt 75 * take less than 20us to complete - Verified by ::ticker_speed_test 76 * 77 * # Undefined behavior 78 * * Calling any function other than ticker_init before the initialization of the ticker 79 * * Whether ticker_irq_handler is called a second time if the time wraps and matches the value set by ticker_set_interrupt again 80 * * Calling ticker_set_interrupt with a value that has more than the supported number of bits 81 * * Calling any function other than us_ticker_init after calling us_ticker_free 82 * 83 * # Potential bugs 84 * * Drift due to reschedule - Verified by ::ticker_repeat_reschedule_test 85 * * Incorrect overflow handling of timers - Verified by ::ticker_overflow_test 86 * * Interrupting at a time of 0 - Verified by ::ticker_overflow_test 87 * * Interrupt triggered more than once - Verified by ::ticker_interrupt_test 88 * 89 * @ingroup hal_us_ticker 90 * @ingroup hal_lp_ticker 91 */ 92 93 /** 94 * \defgroup hal_ticker_tests Ticker Tests 95 * Tests to validate the proper implementation of a ticker 96 * 97 * To run the ticker hal tests use the command: 98 * 99 * mbed test -t <toolchain> -m <target> -n tests-mbed_hal-common_ticker* 100 * 101 * @ingroup hal_us_ticker 102 * @ingroup hal_lp_ticker 103 */ 104 105 106 typedef void (*ticker_irq_handler_type)(const ticker_data_t *const); 107 108 /** Set ticker IRQ handler 109 * 110 * @param ticker_irq_handler IRQ handler to be connected 111 * 112 * @return previous ticker IRQ handler 113 * 114 * @note by default IRQ handler is set to ::ticker_irq_handler 115 * @note this function is primarily for testing purposes and it's not required part of HAL implementation 116 * 117 */ 118 ticker_irq_handler_type set_us_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler); 119 34 120 /** Get ticker's data 35 121 * 36 * @return The low powerticker data37 */ 38 const ticker_data_t *get_us_ticker_data(void);122 * @return The microsecond ticker data 123 */ 124 const ticker_data_t *get_us_ticker_data(void); 39 125 40 126 … … 48 134 /** Initialize the ticker 49 135 * 136 * Initialize or re-initialize the ticker. This resets all the 137 * clocking and prescaler registers, along with disabling 138 * the compare interrupt. 139 * 140 * @note Initialization properties tested by ::ticker_init_test 141 * 142 * Pseudo Code: 143 * @code 144 * void us_ticker_init() 145 * { 146 * // Enable clock gate so processor can read TIMER registers 147 * POWER_CTRL |= POWER_CTRL_TIMER_Msk; 148 * 149 * // Disable the timer and ensure it is powered down 150 * TIMER_CTRL &= ~(TIMER_CTRL_ENABLE_Msk | TIMER_CTRL_COMPARE_ENABLE_Msk); 151 * 152 * // Configure divisors 153 * uint32_t prescale = SystemCoreClock / 1000000; 154 * TIMER_PRESCALE = prescale - 1; 155 * TIMER_CTRL |= TIMER_CTRL_ENABLE_Msk; 156 * 157 * // Install the interrupt handler 158 * NVIC_SetVector(TIMER_IRQn, (uint32_t)us_ticker_irq_handler); 159 * NVIC_EnableIRQ(TIMER_IRQn); 160 * } 161 * @endcode 50 162 */ 51 163 void us_ticker_init(void); 52 164 165 /** Deinitialize the us ticker 166 * 167 * Powerdown the us ticker in preparation for sleep, powerdown, or reset. 168 * 169 * After this function is called, no other ticker functions should be called 170 * except us_ticker_init(), calling any function other than init is undefined. 171 * 172 * @note This function stops the ticker from counting. 173 * 174 * Pseudo Code: 175 * @code 176 * uint32_t us_ticker_free() 177 * { 178 * // Disable timer 179 * TIMER_CTRL &= ~TIMER_CTRL_ENABLE_Msk; 180 * 181 * // Disable the compare interrupt 182 * TIMER_CTRL &= ~TIMER_CTRL_COMPARE_ENABLE_Msk; 183 * 184 * // Disable timer interrupt 185 * NVIC_DisableIRQ(TIMER_IRQn); 186 * 187 * // Disable clock gate so processor cannot read TIMER registers 188 * POWER_CTRL &= ~POWER_CTRL_TIMER_Msk; 189 * } 190 * @endcode 191 * 192 */ 193 void us_ticker_free(void); 194 53 195 /** Read the current counter 54 196 * 55 * @return The current timer's counter value in microseconds 197 * Read the current counter value without performing frequency conversions. 198 * If no rollover has occurred, the seconds passed since us_ticker_init() 199 * was called can be found by dividing the ticks returned by this function 200 * by the frequency returned by ::us_ticker_get_info. 201 * 202 * @return The current timer's counter value in ticks 203 * 204 * Pseudo Code: 205 * @code 206 * uint32_t us_ticker_read() 207 * { 208 * return TIMER_COUNT; 209 * } 210 * @endcode 56 211 */ 57 212 uint32_t us_ticker_read(void); … … 59 214 /** Set interrupt for specified timestamp 60 215 * 61 * @param timestamp The time in microseconds to be set 216 * @param timestamp The time in ticks to be set 217 * 218 * @note no special handling needs to be done for times in the past 219 * as the common timer code will detect this and call 220 * us_ticker_fire_interrupt() if this is the case 221 * 222 * @note calling this function with timestamp of more than the supported 223 * number of bits returned by ::us_ticker_get_info results in undefined 224 * behavior. 225 * 226 * Pseudo Code: 227 * @code 228 * void us_ticker_set_interrupt(timestamp_t timestamp) 229 * { 230 * TIMER_COMPARE = timestamp; 231 * TIMER_CTRL |= TIMER_CTRL_COMPARE_ENABLE_Msk; 232 * } 233 * @endcode 62 234 */ 63 235 void us_ticker_set_interrupt(timestamp_t timestamp); … … 65 237 /** Disable us ticker interrupt 66 238 * 239 * Pseudo Code: 240 * @code 241 * void us_ticker_disable_interrupt(void) 242 * { 243 * // Disable the compare interrupt 244 * TIMER_CTRL &= ~TIMER_CTRL_COMPARE_ENABLE_Msk; 245 * } 246 * @endcode 67 247 */ 68 248 void us_ticker_disable_interrupt(void); … … 70 250 /** Clear us ticker interrupt 71 251 * 252 * Pseudo Code: 253 * @code 254 * void us_ticker_clear_interrupt(void) 255 * { 256 * // Write to the ICR (interrupt clear register) of the TIMER 257 * TIMER_ICR = TIMER_ICR_COMPARE_Msk; 258 * } 259 * @endcode 72 260 */ 73 261 void us_ticker_clear_interrupt(void); 262 263 /** Set pending interrupt that should be fired right away. 264 * 265 * The ticker should be initialized prior calling this function. 266 * 267 * Pseudo Code: 268 * @code 269 * void us_ticker_fire_interrupt(void) 270 * { 271 * NVIC_SetPendingIRQ(TIMER_IRQn); 272 * } 273 * @endcode 274 */ 275 void us_ticker_fire_interrupt(void); 276 277 /** Get frequency and counter bits of this ticker. 278 * 279 * Pseudo Code: 280 * @code 281 * const ticker_info_t* us_ticker_get_info() 282 * { 283 * static const ticker_info_t info = { 284 * 1000000, // 1 MHz 285 * 32 // 32 bit counter 286 * }; 287 * return &info; 288 * } 289 * @endcode 290 */ 291 const ticker_info_t *us_ticker_get_info(void); 74 292 75 293 /**@}*/
Note:
See TracChangeset
for help on using the changeset viewer.