Ignore:
Timestamp:
Apr 5, 2019, 9:26:53 PM (5 years ago)
Author:
coas-nagasima
Message:

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

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  
    5959
    6060void          can_init     (can_t *obj, PinName rd, PinName td);
     61void          can_init_freq(can_t *obj, PinName rd, PinName td, int hz);
    6162void          can_free     (can_t *obj);
    6263int           can_frequency(can_t *obj, int hz);
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/can_helper.h

    r352 r374  
    2626#endif
    2727
     28/**
     29 *
     30 * \enum    CANFormat
     31 *
     32 * \brief   Values that represent CAN Format
     33**/
    2834enum CANFormat {
    2935    CANStandard = 0,
     
    3339typedef enum CANFormat CANFormat;
    3440
     41/**
     42 *
     43 * \enum    CANType
     44 *
     45 * \brief   Values that represent CAN Type
     46**/
    3547enum CANType {
    3648    CANData   = 0,
     
    3951typedef enum CANType CANType;
    4052
     53/**
     54 *
     55 * \struct  CAN_Message
     56 *
     57 * \brief   Holder for single CAN message.
     58 *
     59**/
    4160struct CAN_Message {
    4261    unsigned int   id;                 // 29 bit identifier
    4362    unsigned char  data[8];            // Data field
    4463    unsigned char  len;                // Length of data field in bytes
    45     CANFormat      format;             // 0 - STANDARD, 1- EXTENDED IDENTIFIER
    46     CANType        type;               // 0 - DATA FRAME, 1 - REMOTE FRAME
     64    CANFormat      format;             // Format ::CANFormat
     65    CANType        type;               // Type ::CANType
    4766};
    4867typedef struct CAN_Message CAN_Message;
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/ethernet_api.h

    r352 r374  
    4545int ethernet_send(void);
    4646
    47 // recieve from ethernet buffer, returning packet size, or 0 if no packet
     47// receive from ethernet buffer, returning packet size, or 0 if no packet
    4848int ethernet_receive(void);
    4949
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/gpio_api.h

    r352 r374  
    8484/** Init the input pin and set mode to PullDefault
    8585 *
    86  * @param obj The GPIO object
     86 * @param gpio The GPIO object
    8787 * @param pin The pin name
    8888 */
     
    9191/** Init the input pin and set the mode
    9292 *
    93  * @param obj  The GPIO object
     93 * @param gpio  The GPIO object
    9494 * @param pin  The pin name
    9595 * @param mode The pin mode to be set
     
    9999/** Init the output pin as an output, with predefined output value 0
    100100 *
    101  * @param obj The GPIO object
     101 * @param gpio The GPIO object
    102102 * @param pin The pin name
    103103 * @return An integer value 1 or 0
     
    107107/** Init the pin as an output and set the output value
    108108 *
    109  * @param obj   The GPIO object
     109 * @param gpio  The GPIO object
    110110 * @param pin   The pin name
    111111 * @param value The value to be set
     
    115115/** Init the pin to be in/out
    116116 *
    117  * @param obj       The GPIO object
     117 * @param gpio      The GPIO object
    118118 * @param pin       The pin name
    119119 * @param direction The pin direction to be set
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/i2c_api.h

    r352 r374  
    157157/** Configure I2C as slave or master.
    158158 *  @param obj The I2C object
     159 *  @param enable_slave Enable i2c hardware so you can receive events with ::i2c_slave_receive
    159160 *  @return non-zero if a value is available
    160161 */
     
    170171/** Configure I2C as slave or master.
    171172 *  @param obj The I2C object
     173 *  @param data    The buffer for receiving
     174 *  @param length  Number of bytes to read
    172175 *  @return non-zero if a value is available
    173176 */
     
    176179/** Configure I2C as slave or master.
    177180 *  @param obj The I2C object
     181 *  @param data    The buffer for sending
     182 *  @param length  Number of bytes to write
    178183 *  @return non-zero if a value is available
    179184 */
     
    209214 *  @param stop      If true, stop will be generated after the transfer is done
    210215 *  @param handler   The I2C IRQ handler to be set
     216 *  @param event     Event mask for the transfer. See \ref hal_I2CEvents
    211217 *  @param hint      DMA hint usage
    212218 */
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/lp_ticker_api.h

    r352 r374  
    2222#include "device.h"
    2323
    24 #if DEVICE_LOWPOWERTIMER
     24#if DEVICE_LPTICKER
    2525
    2626#include "hal/ticker_api.h"
     
    3131
    3232/**
    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 *
    3451 * @{
    3552 */
    3653
     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
     64typedef 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 */
     76ticker_irq_handler_type set_lp_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler);
     77
    3778/** Get low power ticker's data
    3879 *
    3980 * @return The low power ticker data
    4081 */
    41 const ticker_data_t* get_lp_ticker_data(void);
     82const ticker_data_t *get_lp_ticker_data(void);
    4283
    4384/** The wrapper for ticker_irq_handler, to pass lp ticker's data
     
    5091/** Initialize the low power ticker
    5192 *
     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
    52116 */
    53117void lp_ticker_init(void);
    54118
    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 */
     129void 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
    58157 */
    59158uint32_t lp_ticker_read(void);
     
    61160/** Set interrupt for specified timestamp
    62161 *
    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
    64180 */
    65181void lp_ticker_set_interrupt(timestamp_t timestamp);
     
    67183/** Disable low power ticker interrupt
    68184 *
     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
    69193 */
    70194void lp_ticker_disable_interrupt(void);
     
    72196/** Clear the low power ticker interrupt
    73197 *
     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
    74206 */
    75207void 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 */
     219void 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 */
     235const ticker_info_t *lp_ticker_get_info(void);
    76236
    77237/**@}*/
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_gpio.c

    r352 r374  
    3535}
    3636
    37 void gpio_init_in(gpio_t* gpio, PinName pin) {
     37void gpio_init_in(gpio_t *gpio, PinName pin)
     38{
    3839    gpio_init_in_ex(gpio, pin, PullDefault);
    3940}
    4041
    41 void gpio_init_in_ex(gpio_t* gpio, PinName pin, PinMode mode) {
     42void gpio_init_in_ex(gpio_t *gpio, PinName pin, PinMode mode)
     43{
    4244    _gpio_init_in(gpio, pin, mode);
    4345}
    4446
    45 void gpio_init_out(gpio_t* gpio, PinName pin) {
     47void gpio_init_out(gpio_t *gpio, PinName pin)
     48{
    4649    gpio_init_out_ex(gpio, pin, 0);
    4750}
    4851
    49 void gpio_init_out_ex(gpio_t* gpio, PinName pin, int value) {
     52void gpio_init_out_ex(gpio_t *gpio, PinName pin, int value)
     53{
    5054    _gpio_init_out(gpio, pin, PullNone, value);
    5155}
    5256
    53 void gpio_init_inout(gpio_t* gpio, PinName pin, PinDirection direction, PinMode mode, int value) {
     57void gpio_init_inout(gpio_t *gpio, PinName pin, PinDirection direction, PinMode mode, int value)
     58{
    5459    if (direction == PIN_INPUT) {
    5560        _gpio_init_in(gpio, pin, mode);
    56         if (pin != NC)
     61        if (pin != NC) {
    5762            gpio_write(gpio, value); // we prepare the value in case it is switched later
     63        }
    5864    } else {
    5965        _gpio_init_out(gpio, pin, mode, value);
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_lp_ticker_api.c

    r352 r374  
    1515 */
    1616#include "hal/lp_ticker_api.h"
     17#include "hal/mbed_lp_ticker_wrapper.h"
    1718
    18 #if DEVICE_LOWPOWERTIMER
     19#if DEVICE_LPTICKER
    1920
    20 static ticker_event_queue_t events;
     21static ticker_event_queue_t events = { 0 };
     22
     23static ticker_irq_handler_type irq_handler = ticker_irq_handler;
    2124
    2225static const ticker_interface_t lp_interface = {
     
    2629    .clear_interrupt = lp_ticker_clear_interrupt,
    2730    .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,
    2834};
    2935
     
    3339};
    3440
    35 const ticker_data_t* get_lp_ticker_data(void)
     41const ticker_data_t *get_lp_ticker_data(void)
    3642{
     43#if LPTICKER_DELAY_TICKS > 0
     44    return get_lp_ticker_wrapper_data(&lp_data);
     45#else
    3746    return &lp_data;
     47#endif
     48}
     49
     50ticker_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;
    3857}
    3958
    4059void lp_ticker_irq_handler(void)
    4160{
    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
    4368}
    4469
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_pinmap_common.c

    r352 r374  
    1717#include "platform/mbed_error.h"
    1818
    19 void pinmap_pinout(PinName pin, const PinMap *map) {
    20     if (pin == NC)
     19void pinmap_pinout(PinName pin, const PinMap *map)
     20{
     21    if (pin == NC) {
    2122        return;
     23    }
    2224
    2325    while (map->pin != NC) {
     
    3032        map++;
    3133    }
    32     error("could not pinout");
     34    MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_PINMAP_INVALID), "could not pinout", pin);
    3335}
    3436
    35 uint32_t pinmap_merge(uint32_t a, uint32_t b) {
     37uint32_t pinmap_merge(uint32_t a, uint32_t b)
     38{
    3639    // both are the same (inc both NC)
    37     if (a == b)
     40    if (a == b) {
    3841        return a;
     42    }
    3943
    4044    // one (or both) is not connected
    41     if (a == (uint32_t)NC)
     45    if (a == (uint32_t)NC) {
    4246        return b;
    43     if (b == (uint32_t)NC)
     47    }
     48    if (b == (uint32_t)NC) {
    4449        return a;
     50    }
    4551
    4652    // 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);
    4854    return (uint32_t)NC;
    4955}
    5056
    51 uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map) {
     57uint32_t pinmap_find_peripheral(PinName pin, const PinMap *map)
     58{
    5259    while (map->pin != NC) {
    53         if (map->pin == pin)
     60        if (map->pin == pin) {
    5461            return map->peripheral;
     62        }
    5563        map++;
    5664    }
     
    5866}
    5967
    60 uint32_t pinmap_peripheral(PinName pin, const PinMap* map) {
     68uint32_t pinmap_peripheral(PinName pin, const PinMap *map)
     69{
    6170    uint32_t peripheral = (uint32_t)NC;
    6271
    63     if (pin == (PinName)NC)
     72    if (pin == (PinName)NC) {
    6473        return (uint32_t)NC;
     74    }
    6575    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    }
    6879    return peripheral;
    6980}
    7081
    71 uint32_t pinmap_find_function(PinName pin, const PinMap* map) {
     82uint32_t pinmap_find_function(PinName pin, const PinMap *map)
     83{
    7284    while (map->pin != NC) {
    73         if (map->pin == pin)
     85        if (map->pin == pin) {
    7486            return map->function;
     87        }
    7588        map++;
    7689    }
     
    7891}
    7992
    80 uint32_t pinmap_function(PinName pin, const PinMap* map) {
     93uint32_t pinmap_function(PinName pin, const PinMap *map)
     94{
    8195    uint32_t function = (uint32_t)NC;
    8296
    83     if (pin == (PinName)NC)
     97    if (pin == (PinName)NC) {
    8498        return (uint32_t)NC;
     99    }
    85100    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    }
    88104    return function;
    89105}
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_ticker_api.c

    r352 r374  
    1414 * limitations under the License.
    1515 */
     16#include <stdio.h>
    1617#include <stddef.h>
    1718#include "hal/ticker_api.h"
    1819#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
     22static void schedule_interrupt(const ticker_data_t *const ticker);
     23static void update_present_time(const ticker_data_t *const ticker);
     24
     25/*
     26 * Initialize a ticker instance.
     27 */
     28static 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 */
     86static 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 */
     110static 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 */
     125static 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 */
     177static 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 */
     215int _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 */
     237static 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
     278void 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
     287void 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    }
    28296
    29297    /* Go through all the pending TimerEvents */
     298    ticker->queue->dispatching = true;
    30299    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) {
    38308            // This event was in the past:
    39309            //      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 events
     310            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
    44314            }
    45315            /* Note: We continue back to examining the head because calling the
    46316             * event handler may have altered the chain of pending events. */
    47317        } 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
     328void 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
     348void 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);
    59354
    60355    // initialise our data
     
    65360       an element this should come before (which is possibly the
    66361       head). */
    67     ticker_event_t *prev = NULL, *p = data->queue->head;
     362    ticker_event_t *prev = NULL, *p = ticker->queue->head;
    68363    while (p != NULL) {
    69364        /* check if we come before p */
    70         if ((int)(timestamp - p->timestamp) < 0) {
     365        if (timestamp < p->timestamp) {
    71366            break;
    72367        }
     
    75370        p = p->next;
    76371    }
    77    
     372
    78373    /* if we're at the end p will be NULL, which is correct */
    79374    obj->next = p;
     
    81376    /* if prev is NULL we're at the head */
    82377    if (prev == NULL) {
    83         data->queue->head = obj;
    84         data->interface->set_interrupt(timestamp);
     378        ticker->queue->head = obj;
     379        schedule_interrupt(ticker);
    85380    } else {
    86381        prev->next = obj;
     
    90385}
    91386
    92 void ticker_remove_event(const ticker_data_t *const data, ticker_event_t *obj) {
     387void ticker_remove_event(const ticker_data_t *const ticker, ticker_event_t *obj)
     388{
    93389    core_util_critical_section_enter();
    94390
    95391    // remove this object from the list
    96     if (data->queue->head == obj) {
     392    if (ticker->queue->head == obj) {
    97393        // 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);
    104396    } else {
    105397        // find the object before me, then drop me
    106         ticker_event_t* p = data->queue->head;
     398        ticker_event_t *p = ticker->queue->head;
    107399        while (p != NULL) {
    108400            if (p->next == obj) {
     
    117409}
    118410
    119 timestamp_t ticker_read(const ticker_data_t *const data)
    120 {
    121     return data->interface->read();
     411timestamp_t ticker_read(const ticker_data_t *const ticker)
     412{
     413    return ticker_read_us(ticker);
     414}
     415
     416us_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;
    122425}
    123426
     
    136439    return ret;
    137440}
     441
     442void 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
     451void 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  
    1616#include "hal/us_ticker_api.h"
    1717
    18 static ticker_event_queue_t events;
     18static ticker_event_queue_t events = { 0 };
     19
     20static ticker_irq_handler_type irq_handler = ticker_irq_handler;
    1921
    2022static const ticker_interface_t us_interface = {
     
    2426    .clear_interrupt = us_ticker_clear_interrupt,
    2527    .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,
    2631};
    2732
    2833static const ticker_data_t us_data = {
    2934    .interface = &us_interface,
    30     .queue = &events,
     35    .queue = &events
    3136};
    3237
    33 const ticker_data_t* get_us_ticker_data(void)
     38const ticker_data_t *get_us_ticker_data(void)
    3439{
    3540    return &us_data;
    3641}
    3742
     43ticker_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
    3852void us_ticker_irq_handler(void)
    3953{
    40     ticker_irq_handler(&us_data);
     54    if (irq_handler) {
     55        irq_handler(&us_data);
     56    }
    4157}
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/rtc_api.h

    r352 r374  
    1 
    2 /** \addtogroup hal */
    3 /** @{*/
    41/* mbed Microcontroller Library
    52 * Copyright (c) 2006-2013 ARM Limited
     
    1714 * limitations under the License.
    1815 */
     16
     17/** \addtogroup hal */
     18/** @{*/
     19
    1920#ifndef MBED_RTC_API_H
    2021#define MBED_RTC_API_H
    2122
    2223#include "device.h"
    23 
    24 #if DEVICE_RTC
    2524
    2625#include <time.h>
     
    3130
    3231/**
    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 *
    3458 * @{
    3559 */
    3660
     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
    3771/** Initialize the RTC peripheral
    3872 *
     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
    3994 */
    4095void rtc_init(void);
     
    4297/** Deinitialize RTC
    4398 *
    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
    45114 */
    46115void rtc_free(void);
    47116
    48 /** Get the RTC enable status
     117/** Check if the RTC has the time set and is counting
    49118 *
    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
    52133 */
    53134int rtc_isenabled(void);
     
    55136/** Get the current time from the RTC peripheral
    56137 *
    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
    58162 */
    59163time_t rtc_read(void);
    60164
    61 /** Set the current time to the RTC peripheral
     165/** Write the current time in seconds to the RTC peripheral
    62166 *
    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
    64176 */
    65177void rtc_write(time_t t);
     
    73185#endif
    74186
    75 #endif
    76 
    77187/** @}*/
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/sleep_api.h

    r352 r374  
    2828#endif
    2929
     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
    3066/** Send the microcontroller to sleep
    3167 *
    32  * The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the
     68 * The processor is setup ready for sleep, and sent to sleep. In this mode, the
    3369 * system clock to the core is stopped until a reset or an interrupt occurs. This eliminates
    3470 * dynamic power used by the processor, memory systems and buses. The processor, peripheral and
     
    3773 * The processor can be woken up by any internal peripheral interrupt or external pin interrupt.
    3874 *
    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 *
    4377 */
    4478void hal_sleep(void);
     
    4781 *
    4882 * 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 state
    50  * 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.
    5185 *
    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.
    5387 *
    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.
    5889 */
    5990void hal_deepsleep(void);
     91
     92/**@}*/
    6093
    6194#ifdef __cplusplus
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/spi_api.h

    r364 r374  
    3434
    3535#define SPI_FILL_WORD         (0xFFFF)
     36#define SPI_FILL_CHAR         (0xFF)
    3637
    3738#if DEVICE_SPI_ASYNCH
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/ticker_api.h

    r352 r374  
    2121
    2222#include <stdint.h>
     23#include <stdbool.h>
    2324#include "device.h"
    2425
     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 */
    2532typedef uint32_t timestamp_t;
    2633
     34/**
     35 * A us timestamp stored in a 64 bit integer.
     36 * Can store timestamp up to 584810 years.
     37 */
     38typedef uint64_t us_timestamp_t;
     39
    2740/** Ticker's event structure
    2841 */
    2942typedef struct ticker_event_s {
    30     timestamp_t            timestamp; /**< Event's timestamp */
     43    us_timestamp_t         timestamp; /**< Event's timestamp */
    3144    uint32_t               id;        /**< TimerEvent object */
    3245    struct ticker_event_s *next;      /**< Next event in the queue */
     
    3447
    3548typedef void (*ticker_event_handler)(uint32_t id);
     49
     50/** Information about the ticker implementation
     51 */
     52typedef 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
    3657
    3758/** Ticker's interface structure - required API for a ticker
     
    4364    void (*clear_interrupt)(void);                /**< Clear interrupt function */
    4465    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 */
    4569} ticker_interface_t;
    4670
     
    5074    ticker_event_handler event_handler; /**< Event handler */
    5175    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 */
    5287} ticker_event_queue_t;
    5388
     
    70105/** Initialize a ticker and set the event handler
    71106 *
    72  * @param data    The ticker's data
     107 * @param ticker The ticker object.
    73108 * @param handler A handler to be set
    74109 */
    75 void ticker_set_handler(const ticker_data_t *const data, ticker_event_handler handler);
     110void ticker_set_handler(const ticker_data_t *const ticker, ticker_event_handler handler);
    76111
    77112/** IRQ handler that goes through the events to trigger overdue events.
    78113 *
    79  * @param data    The ticker's data
    80  */
    81 void ticker_irq_handler(const ticker_data_t *const data);
     114 * @param ticker The ticker object.
     115 */
     116void ticker_irq_handler(const ticker_data_t *const ticker);
    82117
    83118/** Remove an event from the queue
    84119 *
    85  * @param data The ticker's data
     120 * @param ticker The ticker object.
    86121 * @param obj  The event object to be removed from the queue
    87122 */
    88 void ticker_remove_event(const ticker_data_t *const data, ticker_event_t *obj);
     123void ticker_remove_event(const ticker_data_t *const ticker, ticker_event_t *obj);
    89124
    90125/** Insert an event to the queue
    91126 *
    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.
    93139 * @param obj       The event object to be inserted to the queue
    94140 * @param timestamp The event's timestamp
    95141 * @param id        The event object
    96142 */
    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
     143void 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 */
     158void 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.
    102166 * @return The current timestamp
    103167 */
    104 timestamp_t ticker_read(const ticker_data_t *const data);
     168timestamp_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 */
     178us_timestamp_t ticker_read_us(const ticker_data_t *const ticker);
    105179
    106180/** Read the next event's timestamp
    107181 *
    108  * @param data The ticker's data
     182 * @param ticker        The ticker object.
     183 * @param timestamp     The timestamp object.
    109184 * @return 1 if timestamp is pending event, 0 if there's no event pending
    110185 */
    111 int ticker_get_next_timestamp(const ticker_data_t *const data, timestamp_t *timestamp);
     186int 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 */
     198void 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 */
     207void ticker_resume(const ticker_data_t *const ticker);
     208
     209/* Private functions
     210 *
     211 * @cond PRIVATE
     212 *
     213 */
     214
     215int _ticker_match_interval_passed(timestamp_t prev_tick, timestamp_t cur_tick, timestamp_t match_tick);
     216
     217/*
     218 * @endcond PRIVATE
     219 *
     220 */
    112221
    113222/**@}*/
  • asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/us_ticker_api.h

    r352 r374  
    2828
    2929/**
    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 *
    3143 * @{
    3244 */
    3345
     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
     106typedef 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 */
     118ticker_irq_handler_type set_us_ticker_irq_handler(ticker_irq_handler_type ticker_irq_handler);
     119
    34120/** Get ticker's data
    35121 *
    36  * @return The low power ticker data
    37  */
    38 const ticker_data_t* get_us_ticker_data(void);
     122 * @return The microsecond ticker data
     123 */
     124const ticker_data_t *get_us_ticker_data(void);
    39125
    40126
     
    48134/** Initialize the ticker
    49135 *
     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
    50162 */
    51163void us_ticker_init(void);
    52164
     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 */
     193void us_ticker_free(void);
     194
    53195/** Read the current counter
    54196 *
    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
    56211 */
    57212uint32_t us_ticker_read(void);
     
    59214/** Set interrupt for specified timestamp
    60215 *
    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
    62234 */
    63235void us_ticker_set_interrupt(timestamp_t timestamp);
     
    65237/** Disable us ticker interrupt
    66238 *
     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
    67247 */
    68248void us_ticker_disable_interrupt(void);
     
    70250/** Clear us ticker interrupt
    71251 *
     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
    72260 */
    73261void 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 */
     275void 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 */
     291const ticker_info_t *us_ticker_get_info(void);
    74292
    75293/**@}*/
Note: See TracChangeset for help on using the changeset viewer.