Skip to content

Commit 4139f13

Browse files
authored
Merge pull request #6170 from hug-dev/cm3ds-update-drivers
CM3DS Maintenance Pull Request: Driver updates (4/4)
2 parents 56e8c89 + a79a670 commit 4139f13

35 files changed

+5032
-2330
lines changed

targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PeripheralNames.h

100644100755
Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* mbed Microcontroller Library
2-
* Copyright (c) 2006-2017 ARM Limited
2+
* Copyright (c) 2006-2018 ARM Limited
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,11 +23,11 @@ extern "C" {
2323
#endif
2424

2525
typedef enum {
26-
UART_0 = (int)CMSDK_UART0_BASE, /* MCC UART */
27-
UART_1 = (int)CMSDK_UART1_BASE, /* MPS2+ UART */
28-
UART_2 = (int)CMSDK_UART2_BASE, /* Shield 0 UART */
29-
UART_3 = (int)CMSDK_UART3_BASE, /* Shield 1 UART */
30-
UART_4 = (int)CMSDK_UART4_BASE /* Shield BT UART */
26+
UART_0 = 0, /* MCC UART */
27+
UART_1, /* MPS2+ UART */
28+
UART_2, /* Shield 0 UART */
29+
UART_3, /* Shield 1 UART */
30+
UART_4 /* Shield BT UART */
3131
} UARTName;
3232

3333
typedef enum {
@@ -53,11 +53,12 @@ typedef enum {
5353
} ADCName;
5454

5555
typedef enum {
56-
SPI_0 = (int)MPS2_SSP0_BASE,
57-
SPI_1 = (int)MPS2_SSP1_BASE,
58-
SPI_2 = (int)MPS2_SSP2_BASE,
59-
SPI_3 = (int)MPS2_SSP3_BASE,
60-
SPI_4 = (int)MPS2_SSP4_BASE
56+
SPI_0 = 0,
57+
SPI_1,
58+
SPI_2,
59+
SPI_3,
60+
SPI_4,
61+
SPI_NC = (SPI_4 + 1)
6162
} SPIName;
6263

6364
typedef enum {

targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PinNames.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* mbed Microcontroller Library
2-
* Copyright (c) 2006-2017 ARM Limited
2+
* Copyright (c) 2006-2018 ARM Limited
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing software
11+
* distributed under the License is distributed on an "AS IS" BASIS
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* \file cmsdk_ticker.c
19+
* Two abstracted functionalities for CMSDK APB Timers
20+
* 1. Measure elapsed time
21+
* 2. Timer interval interrupt
22+
*
23+
* Passed \ref tick_drv_data_t should be initialized by the caller
24+
* for using these services accordingly.
25+
* See details \ref tick_cfg_t and \ref tick_data_t.
26+
*/
27+
28+
#include "cmsdk_ticker.h"
29+
30+
void cmsdk_ticker_init(const struct tick_drv_data_t* timer_data)
31+
{
32+
if (!timer_data->data->is_initialized) {
33+
timer_cmsdk_init(timer_data->cfg->timer_driver);
34+
timer_cmsdk_set_reload_value(timer_data->cfg->timer_driver,
35+
TIMER_CMSDK_MAX_RELOAD);
36+
timer_cmsdk_enable_interrupt(timer_data->cfg->timer_driver);
37+
NVIC_EnableIRQ(timer_data->cfg->irq_n);
38+
39+
timer_data->data->max_interval_time =
40+
timer_data->cfg->convert_tick_to_time(TIMER_CMSDK_MAX_RELOAD);
41+
timer_data->data->reload_time = timer_data->data->max_interval_time;
42+
timer_data->data->is_initialized = true;
43+
timer_cmsdk_enable(timer_data->cfg->timer_driver);
44+
}
45+
}
46+
47+
uint32_t cmsdk_ticker_read(const struct tick_drv_data_t* timer_data)
48+
{
49+
uint32_t current_elapsed = 0;
50+
51+
if (!timer_data->data->is_initialized) {
52+
cmsdk_ticker_init(timer_data);
53+
}
54+
current_elapsed = timer_cmsdk_get_elapsed_value(timer_data->cfg->timer_driver);
55+
/*
56+
* If for the same reload cycle (ie. cumulated_time is the same) the
57+
* current elapsed time is lower than the previous one, it means that the
58+
* timer has wrapped around without the system logging it. To ensure that
59+
* we are always returning an increasing time in those condition, we return
60+
* the time perviously read.
61+
*/
62+
if ((timer_data->data->previous_cumulated_time ==
63+
timer_data->data->cumulated_time) &&
64+
(current_elapsed < timer_data->data->previous_elapsed)) {
65+
current_elapsed = timer_data->data->previous_elapsed;
66+
}
67+
68+
timer_data->data->previous_elapsed = current_elapsed;
69+
timer_data->data->previous_cumulated_time =
70+
timer_data->data->cumulated_time;
71+
72+
return (timer_data->data->cumulated_time +
73+
timer_data->cfg->convert_tick_to_time(current_elapsed));
74+
}
75+
76+
void cmsdk_ticker_set_interrupt(const struct tick_drv_data_t* timer_data,
77+
uint32_t timestamp)
78+
{
79+
uint32_t interval = 0;
80+
uint32_t interval_reload_tick = 0;
81+
82+
/* Stop before read to avoid race condition with IRQ. */
83+
timer_cmsdk_disable(timer_data->cfg->timer_driver);
84+
uint32_t current_time = cmsdk_ticker_read(timer_data);
85+
86+
timer_data->data->interval_callback_enabled = true;
87+
88+
/*
89+
* We always assume that the event is in the future, even if this
90+
* substraction underflows it is still corect.
91+
*/
92+
interval = (timestamp - current_time);
93+
94+
if (interval >= timer_data->data->max_interval_time) {
95+
/* Event will be in the future but the time is too big: set max */
96+
interval_reload_tick = TIMER_CMSDK_MAX_RELOAD;
97+
timer_data->data->reload_time = timer_data->data->max_interval_time;
98+
} else {
99+
/* Event will be in the future in a time that can be set */
100+
interval_reload_tick =
101+
timer_data->cfg->convert_time_to_tick(interval);
102+
timer_data->data->reload_time = interval;
103+
}
104+
105+
/* Store the current elapsed time, before reset the timer */
106+
timer_data->data->cumulated_time = current_time;
107+
/* Reset the timer with new reload value */
108+
timer_cmsdk_set_reload_value(timer_data->cfg->timer_driver,
109+
interval_reload_tick);
110+
timer_cmsdk_reset(timer_data->cfg->timer_driver);
111+
112+
timer_cmsdk_enable(timer_data->cfg->timer_driver);
113+
}
114+
115+
void cmsdk_ticker_disable_interrupt(const struct tick_drv_data_t* timer_data)
116+
{
117+
if (!timer_data->data->is_initialized) {
118+
cmsdk_ticker_init(timer_data);
119+
}
120+
121+
timer_data->data->interval_callback_enabled = false;
122+
123+
/* Stop before read to avoid race condition with IRQ. */
124+
timer_cmsdk_disable(timer_data->cfg->timer_driver);
125+
/* If interval interrupt is disabled, restore the default max interval,
126+
* but save the current elapsed time before changing the timer. */
127+
timer_data->data->cumulated_time = cmsdk_ticker_read(timer_data);
128+
/* Reset the timer with default reload value */
129+
timer_cmsdk_set_reload_value(timer_data->cfg->timer_driver,
130+
TIMER_CMSDK_MAX_RELOAD);
131+
timer_data->data->reload_time = timer_data->data->max_interval_time;
132+
133+
timer_cmsdk_reset(timer_data->cfg->timer_driver);
134+
timer_cmsdk_enable(timer_data->cfg->timer_driver);
135+
}
136+
137+
void cmsdk_ticker_clear_interrupt(const struct tick_drv_data_t* timer_data)
138+
{
139+
timer_cmsdk_clear_interrupt(timer_data->cfg->timer_driver);
140+
}
141+
142+
void cmsdk_ticker_fire_interrupt(const struct tick_drv_data_t* timer_data)
143+
{
144+
NVIC_SetPendingIRQ(timer_data->cfg->irq_n);
145+
}
146+
147+
void cmsdk_ticker_irq_handler(const struct tick_drv_data_t* timer_data)
148+
{
149+
uint32_t reload_val = 0;
150+
/* If timer's internal interrupt status is not active, then not overflow,
151+
* but explicit interrupt request was fired by cmsdk_ticker_fire_interrupt.
152+
*/
153+
if (timer_cmsdk_is_interrupt_active(timer_data->cfg->timer_driver)) {
154+
/* 1. Calculate cumulated time by overflow */
155+
timer_cmsdk_clear_interrupt(timer_data->cfg->timer_driver);
156+
reload_val = timer_cmsdk_get_reload_value(timer_data->cfg->timer_driver);
157+
timer_data->data->cumulated_time +=
158+
timer_data->cfg->convert_tick_to_time(reload_val);
159+
}
160+
161+
/* 2. Call mbed interval interrupt handler if it's required */
162+
if (timer_data->data->interval_callback_enabled) {
163+
cmsdk_ticker_disable_interrupt(timer_data);
164+
timer_data->cfg->interval_callback();
165+
}
166+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
/**
19+
* \file cmsdk_ticker.h
20+
* CMSDK Ticker implements the functionalities of mbed tickers:
21+
* 1. Elapsed time measurement
22+
* 2. Interval interrupt request
23+
*
24+
* This ticker service is based on CMSDK APB Timers, abstracting
25+
* the HAL logic, the timer driver and interrupt number.
26+
* These parameters should be passed to the functions by
27+
* an initialized \ref tick_drv_data_t pointer.
28+
*/
29+
30+
#ifndef CMSDK_TICKER_H
31+
#define CMSDK_TICKER_H
32+
33+
#include <stdbool.h>
34+
35+
#include "CMSDK_CM3DS.h"
36+
#include "timer_cmsdk_drv.h"
37+
38+
#define SEC_TO_USEC_MULTIPLIER 1000000U
39+
40+
/**
41+
* brief Encapsulating struct for config data \ref tick_cfg_t and
42+
* the current status \ref tick_data_t.
43+
*/
44+
struct tick_drv_data_t {
45+
const struct tick_cfg_t* const cfg;
46+
struct tick_data_t* const data;
47+
};
48+
49+
/**
50+
* brief Configuration data of the CMSDK ticker
51+
*/
52+
struct tick_cfg_t {
53+
/** Pointer to the used CMSDK Timer's device structure */
54+
struct timer_cmsdk_dev_t* const timer_driver;
55+
/** IRQ number of the used CMSDK Timer */
56+
const IRQn_Type irq_n;
57+
/** Interval callback of mbed*/
58+
void (*const interval_callback)();
59+
/** Function pointers to call for conversions of clock ticks and defined
60+
* time unit.
61+
* These conversions define the unit of the measured time.
62+
*/
63+
uint32_t (*const convert_tick_to_time)(uint32_t tick);
64+
uint32_t (*const convert_time_to_tick)(uint32_t time);
65+
};
66+
67+
/**
68+
* brief Current state data of the CMSDK ticker
69+
*/
70+
struct tick_data_t {
71+
/** True if initialized the ticker, false otherwise */
72+
bool is_initialized;
73+
/** Measured elapsed time in the defined unit by
74+
* \ref convert_tick_to_time and \ref convert_time_to_tick */
75+
uint32_t cumulated_time;
76+
/** Max interval time possible to set, in the defined unit by
77+
* \ref convert_tick_to_time and \ref convert_time_to_tick */
78+
uint32_t max_interval_time;
79+
/** Current reload time in the defined unit by
80+
* \ref convert_tick_to_time and \ref convert_time_to_tick */
81+
uint32_t reload_time;
82+
/** Interval IRQ callback is requested */
83+
bool interval_callback_enabled;
84+
/** Previous cumulated time calculated for this ticker. Used in the
85+
* cmsdk_ticker_read function to detect that the timer has wrapped. */
86+
uint32_t previous_cumulated_time;
87+
/** Previous elapsed value for this ticker. Used in the
88+
* cmsdk_ticker_read function to detect that the timer has wrapped. */
89+
uint32_t previous_elapsed;
90+
};
91+
92+
/**
93+
* \brief Init the CMSDK Ticker
94+
*
95+
* \param[in] timer_data Pointer to the used CMSDK Timer's device structure
96+
*/
97+
void cmsdk_ticker_init(const struct tick_drv_data_t* timer_data);
98+
99+
/**
100+
* \brief Read elapsed time by CMSDK Ticker
101+
*
102+
* \param[in] timer_data Pointer to the used CMSDK Timer's device structure
103+
*
104+
* \return Elapsed time in the unit defined by \ref convert_tick_to_time
105+
*/
106+
107+
uint32_t cmsdk_ticker_read(const struct tick_drv_data_t* timer_data);
108+
109+
/**
110+
* \brief Request interval interrupt by time stamp \ref timestamp_t
111+
*
112+
* \param[in] timer_data Pointer to the used CMSDK Timer's device structure
113+
* \param[in] timestamp Absolute time \ref timestamp_t value when the interval
114+
* is requested. Unit of the timestamp is defined by
115+
* \ref convert_tick_to_time and \ref convert_time_to_tick
116+
*/
117+
void cmsdk_ticker_set_interrupt(const struct tick_drv_data_t* timer_data,
118+
uint32_t timestamp);
119+
120+
/**
121+
* \brief Disable interval interrupt
122+
*
123+
* \param[in] timer_data Pointer to the used CMSDK Timer's device structure
124+
*/
125+
void cmsdk_ticker_disable_interrupt(const struct tick_drv_data_t* timer_data);
126+
127+
/**
128+
* \brief Clear interval interrupt
129+
*
130+
* \param[in] timer_data Pointer to the used CMSDK Timer's device structure
131+
*/
132+
void cmsdk_ticker_clear_interrupt(const struct tick_drv_data_t* timer_data);
133+
134+
/**
135+
* \brief Set pending interrupt that should be fired right away.
136+
*
137+
* \param[in] timer_data Pointer to the used CMSDK Timer's device structure
138+
*/
139+
void cmsdk_ticker_fire_interrupt(const struct tick_drv_data_t* timer_data);
140+
141+
/**
142+
* \brief Interrupt handler of the given CMSDK Timer
143+
*
144+
* \warning This function may be called from multiple interrupt handlers,
145+
* so extra care must be taken for re-entrancy!
146+
*
147+
* \param[in] timer_data Pointer to the used CMSDK Timer's device structure
148+
*/
149+
void cmsdk_ticker_irq_handler(const struct tick_drv_data_t* timer_data);
150+
#endif

0 commit comments

Comments
 (0)