40
40
#define LPT_INTERRUPT_PRIORITY 6
41
41
#define LPT_INTERRUPT_SOURCE srss_interrupt_mcwdt_1_IRQn
42
42
#endif
43
- #define LPT_MCWDT_DELAY_WAIT 0 // Recommended value is 93, but then we fail function execution time test.
44
-
43
+ #define LPT_MCWDT_DELAY_WAIT 93 // Recommended value is 93, but then we fail function execution time test.
44
+ #define LPT_MCWDT_DELAY_NO_WAIT 0
45
45
#if !defined (CY_CFG_SYSCLK_CLKLF_FREQ_HZ )
46
46
#define CY_CFG_SYSCLK_CLKLF_FREQ_HZ 32768UL /* Default to 32K ILO */
47
47
#endif /* CY_CFG_SYSCLK_CLKLF_FREQ_HZ */
48
48
49
+ #define MCWDT_COUNTER0_MAX_COUNT (0xffffUL)
50
+ #define MCWDT_COUNTER1_MAX_COUNT (0xffffUL)
51
+ #define MCWDT_COUNTER2_MAX_COUNT (0xffffffffUL)
52
+ #define MAX_MCWDT_DURATION_SEC (35UL*60UL*60UL*1000UL)
53
+ #define PLATFORM_MAX_DEEP_SLEEP_TICKS (MAX_MCWDT_DURATION_SEC*CY_CFG_SYSCLK_CLKLF_FREQ_HZ)
54
+ #define MAX_MCWDT_COUNTER0_DURATION_SEC ((MCWDT_COUNTER0_MAX_COUNT + 1)/(CY_CFG_SYSCLK_CLKLF_FREQ_HZ))
55
+ #define LPT_MCWDT_CTRL (CY_MCWDT_CTR0 | CY_MCWDT_CTR1 | CY_MCWDT_CTR2)
56
+
49
57
static const ticker_info_t lp_ticker_info = {
50
58
.frequency = CY_CFG_SYSCLK_CLKLF_FREQ_HZ ,
51
- .bits = 16UL ,
59
+ .bits = 32UL ,
52
60
};
53
61
54
62
static bool lpt_init_done = false;
63
+
55
64
// Timer h/w configuration.
56
65
static cy_stc_mcwdt_config_t config = {
57
- .c0Match = 0 ,
58
- .c1Match = 0 ,
66
+ .c0Match = MCWDT_COUNTER0_MAX_COUNT ,
67
+ .c1Match = MCWDT_COUNTER1_MAX_COUNT ,
59
68
.c0Mode = CY_MCWDT_MODE_INT ,
60
- .c1Mode = CY_MCWDT_MODE_NONE ,
61
- .c2ToggleBit = 0 ,
69
+ .c1Mode = CY_MCWDT_MODE_INT ,
62
70
.c2Mode = CY_MCWDT_MODE_NONE ,
71
+ .c2ToggleBit = 0 ,
63
72
.c0ClearOnMatch = false,
64
73
.c1ClearOnMatch = false,
65
- .c0c1Cascade = false ,
74
+ .c0c1Cascade = true ,
66
75
.c1c2Cascade = false
67
76
};
68
77
@@ -77,7 +86,6 @@ static cy_stc_sysint_t lpt_sysint_config = {
77
86
.intrPriority = LPT_INTERRUPT_PRIORITY
78
87
};
79
88
80
-
81
89
void lp_ticker_init (void )
82
90
{
83
91
lp_ticker_disable_interrupt ();
@@ -100,14 +108,14 @@ void lp_ticker_init(void)
100
108
Cy_MCWDT_Init (LPT_MCWDT_UNIT , & config );
101
109
Cy_SysInt_Init (& lpt_sysint_config , lp_ticker_irq_handler );
102
110
NVIC_EnableIRQ (lpt_sysint_config .intrSrc );
103
- Cy_MCWDT_Enable (LPT_MCWDT_UNIT , CY_MCWDT_CTR0 , LPT_MCWDT_DELAY_WAIT );
111
+ Cy_MCWDT_Enable (LPT_MCWDT_UNIT , LPT_MCWDT_CTRL , LPT_MCWDT_DELAY_WAIT );
104
112
lpt_init_done = true;
105
113
}
106
114
107
115
void lp_ticker_free (void )
108
116
{
109
117
NVIC_DisableIRQ (lpt_sysint_config .intrSrc );
110
- Cy_MCWDT_Disable (LPT_MCWDT_UNIT , CY_MCWDT_CTR0 , LPT_MCWDT_DELAY_WAIT );
118
+ Cy_MCWDT_Disable (LPT_MCWDT_UNIT , LPT_MCWDT_CTRL , LPT_MCWDT_DELAY_WAIT );
111
119
#ifdef TARGET_MCU_PSOC6_M0
112
120
cy_m0_nvic_release_channel (CY_LP_TICKER_IRQN_ID , lpt_sysint_config .intrSrc );
113
121
lpt_sysint_config .intrSrc = (IRQn_Type )(-1 );
@@ -117,32 +125,55 @@ void lp_ticker_free(void)
117
125
118
126
uint32_t lp_ticker_read (void )
119
127
{
120
- return Cy_MCWDT_GetCount (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER0 );
128
+ return Cy_MCWDT_GetCount (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER2 );
121
129
}
122
130
123
131
void lp_ticker_set_interrupt (timestamp_t timestamp )
124
132
{
125
- uint16_t delay ;
126
- uint16_t current = Cy_MCWDT_GetCount (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER0 );
127
- uint16_t new_ts = (uint16_t )timestamp ;
128
- delay = new_ts - current ;
129
- // Make sure the event is set for the future. Mbed internally will not schedule
130
- // delays longer than 0x7000, so too large delay means it should occur already.
131
- // MCWDT has internal delay of about 1.5 LF clock ticks, so this is the minimum
132
- // that we can schedule.
133
- if ((delay < 3 ) || (delay > (uint16_t )(-3 ))) {
134
- // Cheating a bit here.
135
- new_ts = current + 3 ;
136
- }
133
+ uint32_t delay ;
134
+ uint16_t c0_count = Cy_MCWDT_GetCount (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER0 );
135
+ uint16_t c1_count = Cy_MCWDT_GetCount (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER1 );
136
+ uint32_t c2_count = Cy_MCWDT_GetCount (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER2 );
137
137
138
- // Cypress PDL manual says that valid match range is 1..65535.
139
- if ( new_ts == 0 ) {
140
- new_ts = 1 ;
141
- }
138
+ uint32_t new_ts = ( uint32_t ) timestamp ;
139
+
140
+ delay = new_ts - c2_count ;
141
+ lp_ticker_clear_interrupt ();
142
142
143
- // Set up and enable match interrupt.
144
- Cy_MCWDT_SetMatch (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER0 , new_ts , LPT_MCWDT_DELAY_WAIT );
145
- Cy_MCWDT_SetInterruptMask (LPT_MCWDT_UNIT , CY_MCWDT_CTR0 );
143
+ if (delay > MCWDT_COUNTER0_MAX_COUNT ) {
144
+ uint32_t c0_increment = delay % (MCWDT_COUNTER0_MAX_COUNT + 1 );
145
+ uint32_t counter0_count = (c0_count + delay ) % (MCWDT_COUNTER0_MAX_COUNT + 1 );
146
+ uint32_t counter1_count = (delay - c0_increment ) / (MCWDT_COUNTER1_MAX_COUNT + 1 ) ;
147
+ counter1_count = (c1_count + counter1_count ) % (MCWDT_COUNTER1_MAX_COUNT + 1 );
148
+
149
+ if (counter1_count == 0 ) {
150
+ counter1_count = 1 ;
151
+ }
152
+ if (counter0_count == 0 ) {
153
+ counter0_count = 1 ;
154
+ }
155
+ Cy_MCWDT_SetMatch (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER1 , counter1_count , LPT_MCWDT_DELAY_NO_WAIT );
156
+ Cy_MCWDT_SetMatch (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER0 , counter0_count , LPT_MCWDT_DELAY_NO_WAIT );
157
+ Cy_MCWDT_SetInterruptMask (LPT_MCWDT_UNIT , CY_MCWDT_CTR1 );
158
+
159
+ }
160
+ else {
161
+ uint16_t counter0_count = c0_count + (uint16_t )delay ;
162
+
163
+ // MCWDT has internal delay of about 1.5 LF clock ticks, so this is the minimum
164
+ // that we can schedule.
165
+ if (delay < 3 ) {
166
+ // Cheating a bit here.
167
+ counter0_count = c0_count + 3 ;
168
+ }
169
+
170
+ if (counter0_count == 0 ) {
171
+ counter0_count = 1 ;
172
+ }
173
+ Cy_MCWDT_SetMatch (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER1 , MCWDT_COUNTER1_MAX_COUNT , LPT_MCWDT_DELAY_NO_WAIT );
174
+ Cy_MCWDT_SetMatch (LPT_MCWDT_UNIT , CY_MCWDT_COUNTER0 , counter0_count , LPT_MCWDT_DELAY_NO_WAIT );
175
+ Cy_MCWDT_SetInterruptMask (LPT_MCWDT_UNIT , CY_MCWDT_CTR0 );
176
+ }
146
177
}
147
178
148
179
void lp_ticker_disable_interrupt (void )
@@ -152,7 +183,7 @@ void lp_ticker_disable_interrupt(void)
152
183
153
184
void lp_ticker_clear_interrupt (void )
154
185
{
155
- Cy_MCWDT_ClearInterrupt (LPT_MCWDT_UNIT , CY_MCWDT_CTR0 );
186
+ Cy_MCWDT_ClearInterrupt (LPT_MCWDT_UNIT , ( CY_MCWDT_CTR0 | CY_MCWDT_CTR1 ) );
156
187
}
157
188
158
189
void lp_ticker_fire_interrupt (void )
0 commit comments