Development mbed library for MAX32630FTHR

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Dec 16 16:27:57 2016 +0000
Revision:
3:1198227e6421
Parent:
0:5c4d7b2438d3
Changed ADC scale for MAX32625 platforms to 1.2V full scale to match MAX32630 platforms

Who changed what in which revision?

UserRevisionLine numberNew contents of line
switches 0:5c4d7b2438d3 1 /*----------------------------------------------------------------------------
switches 0:5c4d7b2438d3 2 * RL-ARM - RTX
switches 0:5c4d7b2438d3 3 *----------------------------------------------------------------------------
switches 0:5c4d7b2438d3 4 * Name: RT_SYSTEM.C
switches 0:5c4d7b2438d3 5 * Purpose: System Task Manager
switches 0:5c4d7b2438d3 6 * Rev.: 8 April 2015
switches 0:5c4d7b2438d3 7 *----------------------------------------------------------------------------
switches 0:5c4d7b2438d3 8 *
switches 0:5c4d7b2438d3 9 * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
switches 0:5c4d7b2438d3 10 * All rights reserved.
switches 0:5c4d7b2438d3 11 * Redistribution and use in source and binary forms, with or without
switches 0:5c4d7b2438d3 12 * modification, are permitted provided that the following conditions are met:
switches 0:5c4d7b2438d3 13 * - Redistributions of source code must retain the above copyright
switches 0:5c4d7b2438d3 14 * notice, this list of conditions and the following disclaimer.
switches 0:5c4d7b2438d3 15 * - Redistributions in binary form must reproduce the above copyright
switches 0:5c4d7b2438d3 16 * notice, this list of conditions and the following disclaimer in the
switches 0:5c4d7b2438d3 17 * documentation and/or other materials provided with the distribution.
switches 0:5c4d7b2438d3 18 * - Neither the name of ARM nor the names of its contributors may be used
switches 0:5c4d7b2438d3 19 * to endorse or promote products derived from this software without
switches 0:5c4d7b2438d3 20 * specific prior written permission.
switches 0:5c4d7b2438d3 21 *
switches 0:5c4d7b2438d3 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
switches 0:5c4d7b2438d3 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
switches 0:5c4d7b2438d3 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
switches 0:5c4d7b2438d3 25 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
switches 0:5c4d7b2438d3 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
switches 0:5c4d7b2438d3 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
switches 0:5c4d7b2438d3 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
switches 0:5c4d7b2438d3 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
switches 0:5c4d7b2438d3 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
switches 0:5c4d7b2438d3 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
switches 0:5c4d7b2438d3 32 * POSSIBILITY OF SUCH DAMAGE.
switches 0:5c4d7b2438d3 33 *---------------------------------------------------------------------------*/
switches 0:5c4d7b2438d3 34
switches 0:5c4d7b2438d3 35 #include "rt_TypeDef.h"
switches 0:5c4d7b2438d3 36 #include "RTX_Config.h"
switches 0:5c4d7b2438d3 37 #include "rt_Task.h"
switches 0:5c4d7b2438d3 38 #include "rt_System.h"
switches 0:5c4d7b2438d3 39 #include "rt_Event.h"
switches 0:5c4d7b2438d3 40 #include "rt_List.h"
switches 0:5c4d7b2438d3 41 #include "rt_Mailbox.h"
switches 0:5c4d7b2438d3 42 #include "rt_Semaphore.h"
switches 0:5c4d7b2438d3 43 #include "rt_Time.h"
switches 0:5c4d7b2438d3 44 #include "rt_Timer.h"
switches 0:5c4d7b2438d3 45 #include "rt_Robin.h"
switches 0:5c4d7b2438d3 46 #ifdef __CORTEX_A9
switches 0:5c4d7b2438d3 47 #include "rt_HAL_CA.h"
switches 0:5c4d7b2438d3 48 #else
switches 0:5c4d7b2438d3 49 #include "rt_HAL_CM.h"
switches 0:5c4d7b2438d3 50 #endif
switches 0:5c4d7b2438d3 51
switches 0:5c4d7b2438d3 52 /*----------------------------------------------------------------------------
switches 0:5c4d7b2438d3 53 * Global Variables
switches 0:5c4d7b2438d3 54 *---------------------------------------------------------------------------*/
switches 0:5c4d7b2438d3 55
switches 0:5c4d7b2438d3 56 int os_tick_irqn;
switches 0:5c4d7b2438d3 57 U8 scheduler_suspended = 0; // flag set by rt_suspend, cleared by rt_resume, read by SVC_Handler
switches 0:5c4d7b2438d3 58
switches 0:5c4d7b2438d3 59 /*----------------------------------------------------------------------------
switches 0:5c4d7b2438d3 60 * Local Variables
switches 0:5c4d7b2438d3 61 *---------------------------------------------------------------------------*/
switches 0:5c4d7b2438d3 62
switches 0:5c4d7b2438d3 63 static volatile BIT os_lock;
switches 0:5c4d7b2438d3 64 static volatile BIT os_psh_flag;
switches 0:5c4d7b2438d3 65 #ifndef __CORTEX_A9
switches 0:5c4d7b2438d3 66 static U8 pend_flags;
switches 0:5c4d7b2438d3 67 #endif
switches 0:5c4d7b2438d3 68 /*----------------------------------------------------------------------------
switches 0:5c4d7b2438d3 69 * Global Functions
switches 0:5c4d7b2438d3 70 *---------------------------------------------------------------------------*/
switches 0:5c4d7b2438d3 71
switches 0:5c4d7b2438d3 72 #define RL_RTX_VER 0x473
switches 0:5c4d7b2438d3 73
switches 0:5c4d7b2438d3 74 #if defined (__CC_ARM)
switches 0:5c4d7b2438d3 75 __asm void $$RTX$$version (void) {
switches 0:5c4d7b2438d3 76 /* Export a version number symbol for a version control. */
switches 0:5c4d7b2438d3 77
switches 0:5c4d7b2438d3 78 EXPORT __RL_RTX_VER
switches 0:5c4d7b2438d3 79
switches 0:5c4d7b2438d3 80 __RL_RTX_VER EQU RL_RTX_VER
switches 0:5c4d7b2438d3 81 }
switches 0:5c4d7b2438d3 82 #endif
switches 0:5c4d7b2438d3 83
switches 0:5c4d7b2438d3 84
switches 0:5c4d7b2438d3 85 /*--------------------------- rt_suspend ------------------------------------*/
switches 0:5c4d7b2438d3 86
switches 0:5c4d7b2438d3 87 extern U32 sysUserTimerWakeupTime(void);
switches 0:5c4d7b2438d3 88
switches 0:5c4d7b2438d3 89 U32 rt_suspend (void) {
switches 0:5c4d7b2438d3 90 /* Suspend OS scheduler */
switches 0:5c4d7b2438d3 91 U32 delta = 0xFFFF;
switches 0:5c4d7b2438d3 92 #ifdef __CMSIS_RTOS
switches 0:5c4d7b2438d3 93 U32 sleep;
switches 0:5c4d7b2438d3 94 #endif
switches 0:5c4d7b2438d3 95
switches 0:5c4d7b2438d3 96 rt_tsk_lock();
switches 0:5c4d7b2438d3 97 scheduler_suspended = 1;
switches 0:5c4d7b2438d3 98
switches 0:5c4d7b2438d3 99 if (os_dly.p_dlnk) {
switches 0:5c4d7b2438d3 100 delta = os_dly.delta_time;
switches 0:5c4d7b2438d3 101 }
switches 0:5c4d7b2438d3 102 #ifdef __CMSIS_RTOS
switches 0:5c4d7b2438d3 103 sleep = sysUserTimerWakeupTime();
switches 0:5c4d7b2438d3 104 if (sleep < delta) delta = sleep;
switches 0:5c4d7b2438d3 105 #else
switches 0:5c4d7b2438d3 106 if (os_tmr.next) {
switches 0:5c4d7b2438d3 107 if (os_tmr.tcnt < delta) delta = os_tmr.tcnt;
switches 0:5c4d7b2438d3 108 }
switches 0:5c4d7b2438d3 109 #endif
switches 0:5c4d7b2438d3 110
switches 0:5c4d7b2438d3 111 return (delta);
switches 0:5c4d7b2438d3 112 }
switches 0:5c4d7b2438d3 113
switches 0:5c4d7b2438d3 114
switches 0:5c4d7b2438d3 115 /*--------------------------- rt_resume -------------------------------------*/
switches 0:5c4d7b2438d3 116
switches 0:5c4d7b2438d3 117 extern void sysUserTimerUpdate (U32 sleep_time);
switches 0:5c4d7b2438d3 118
switches 0:5c4d7b2438d3 119 void rt_resume (U32 sleep_time) {
switches 0:5c4d7b2438d3 120 /* Resume OS scheduler after suspend */
switches 0:5c4d7b2438d3 121 P_TCB next;
switches 0:5c4d7b2438d3 122 U32 delta;
switches 0:5c4d7b2438d3 123
switches 0:5c4d7b2438d3 124 os_tsk.run->state = READY;
switches 0:5c4d7b2438d3 125 rt_put_rdy_first (os_tsk.run);
switches 0:5c4d7b2438d3 126
switches 0:5c4d7b2438d3 127 os_robin.task = NULL;
switches 0:5c4d7b2438d3 128
switches 0:5c4d7b2438d3 129 /* Update delays. */
switches 0:5c4d7b2438d3 130 if (os_dly.p_dlnk) {
switches 0:5c4d7b2438d3 131 delta = sleep_time;
switches 0:5c4d7b2438d3 132 if (delta >= os_dly.delta_time) {
switches 0:5c4d7b2438d3 133 delta -= os_dly.delta_time;
switches 0:5c4d7b2438d3 134 os_time += os_dly.delta_time;
switches 0:5c4d7b2438d3 135 os_dly.delta_time = 1;
switches 0:5c4d7b2438d3 136 while (os_dly.p_dlnk) {
switches 0:5c4d7b2438d3 137 rt_dec_dly();
switches 0:5c4d7b2438d3 138 if (delta == 0) break;
switches 0:5c4d7b2438d3 139 delta--;
switches 0:5c4d7b2438d3 140 os_time++;
switches 0:5c4d7b2438d3 141 }
switches 0:5c4d7b2438d3 142 } else {
switches 0:5c4d7b2438d3 143 os_time += delta;
switches 0:5c4d7b2438d3 144 os_dly.delta_time -= delta;
switches 0:5c4d7b2438d3 145 }
switches 0:5c4d7b2438d3 146 } else {
switches 0:5c4d7b2438d3 147 os_time += sleep_time;
switches 0:5c4d7b2438d3 148 }
switches 0:5c4d7b2438d3 149
switches 0:5c4d7b2438d3 150 /* Check the user timers. */
switches 0:5c4d7b2438d3 151 #ifdef __CMSIS_RTOS
switches 0:5c4d7b2438d3 152 sysUserTimerUpdate(sleep_time);
switches 0:5c4d7b2438d3 153 #else
switches 0:5c4d7b2438d3 154 if (os_tmr.next) {
switches 0:5c4d7b2438d3 155 delta = sleep_time;
switches 0:5c4d7b2438d3 156 if (delta >= os_tmr.tcnt) {
switches 0:5c4d7b2438d3 157 delta -= os_tmr.tcnt;
switches 0:5c4d7b2438d3 158 os_tmr.tcnt = 1;
switches 0:5c4d7b2438d3 159 while (os_tmr.next) {
switches 0:5c4d7b2438d3 160 rt_tmr_tick();
switches 0:5c4d7b2438d3 161 if (delta == 0) break;
switches 0:5c4d7b2438d3 162 delta--;
switches 0:5c4d7b2438d3 163 }
switches 0:5c4d7b2438d3 164 } else {
switches 0:5c4d7b2438d3 165 os_tmr.tcnt -= delta;
switches 0:5c4d7b2438d3 166 }
switches 0:5c4d7b2438d3 167 }
switches 0:5c4d7b2438d3 168 #endif
switches 0:5c4d7b2438d3 169
switches 0:5c4d7b2438d3 170 /* Switch back to highest ready task */
switches 0:5c4d7b2438d3 171 next = rt_get_first (&os_rdy);
switches 0:5c4d7b2438d3 172 rt_switch_req (next);
switches 0:5c4d7b2438d3 173
switches 0:5c4d7b2438d3 174 scheduler_suspended = 0;
switches 0:5c4d7b2438d3 175 rt_tsk_unlock();
switches 0:5c4d7b2438d3 176 }
switches 0:5c4d7b2438d3 177
switches 0:5c4d7b2438d3 178
switches 0:5c4d7b2438d3 179 /*--------------------------- rt_tsk_lock -----------------------------------*/
switches 0:5c4d7b2438d3 180
switches 0:5c4d7b2438d3 181 void rt_tsk_lock (void) {
switches 0:5c4d7b2438d3 182 /* Prevent task switching by locking out scheduler */
switches 0:5c4d7b2438d3 183 if (os_lock == __TRUE) // don't lock again if already locked
switches 0:5c4d7b2438d3 184 return;
switches 0:5c4d7b2438d3 185
switches 0:5c4d7b2438d3 186 if (os_tick_irqn < 0) {
switches 0:5c4d7b2438d3 187 OS_LOCK();
switches 0:5c4d7b2438d3 188 os_lock = __TRUE;
switches 0:5c4d7b2438d3 189 OS_UNPEND (&pend_flags);
switches 0:5c4d7b2438d3 190 } else {
switches 0:5c4d7b2438d3 191 OS_X_LOCK(os_tick_irqn);
switches 0:5c4d7b2438d3 192 os_lock = __TRUE;
switches 0:5c4d7b2438d3 193 OS_X_UNPEND (&pend_flags);
switches 0:5c4d7b2438d3 194 }
switches 0:5c4d7b2438d3 195 }
switches 0:5c4d7b2438d3 196
switches 0:5c4d7b2438d3 197
switches 0:5c4d7b2438d3 198 /*--------------------------- rt_tsk_unlock ---------------------------------*/
switches 0:5c4d7b2438d3 199
switches 0:5c4d7b2438d3 200 void rt_tsk_unlock (void) {
switches 0:5c4d7b2438d3 201 /* Unlock scheduler and re-enable task switching */
switches 0:5c4d7b2438d3 202 if (os_tick_irqn < 0) {
switches 0:5c4d7b2438d3 203 OS_UNLOCK();
switches 0:5c4d7b2438d3 204 os_lock = __FALSE;
switches 0:5c4d7b2438d3 205 OS_PEND (pend_flags, os_psh_flag);
switches 0:5c4d7b2438d3 206 os_psh_flag = __FALSE;
switches 0:5c4d7b2438d3 207 } else {
switches 0:5c4d7b2438d3 208 OS_X_UNLOCK(os_tick_irqn);
switches 0:5c4d7b2438d3 209 os_lock = __FALSE;
switches 0:5c4d7b2438d3 210 OS_X_PEND (pend_flags, os_psh_flag);
switches 0:5c4d7b2438d3 211 os_psh_flag = __FALSE;
switches 0:5c4d7b2438d3 212 }
switches 0:5c4d7b2438d3 213 }
switches 0:5c4d7b2438d3 214
switches 0:5c4d7b2438d3 215
switches 0:5c4d7b2438d3 216 /*--------------------------- rt_psh_req ------------------------------------*/
switches 0:5c4d7b2438d3 217
switches 0:5c4d7b2438d3 218 void rt_psh_req (void) {
switches 0:5c4d7b2438d3 219 /* Initiate a post service handling request if required. */
switches 0:5c4d7b2438d3 220 if (os_lock == __FALSE) {
switches 0:5c4d7b2438d3 221 OS_PEND_IRQ ();
switches 0:5c4d7b2438d3 222 }
switches 0:5c4d7b2438d3 223 else {
switches 0:5c4d7b2438d3 224 os_psh_flag = __TRUE;
switches 0:5c4d7b2438d3 225 }
switches 0:5c4d7b2438d3 226 }
switches 0:5c4d7b2438d3 227
switches 0:5c4d7b2438d3 228
switches 0:5c4d7b2438d3 229 /*--------------------------- rt_pop_req ------------------------------------*/
switches 0:5c4d7b2438d3 230
switches 0:5c4d7b2438d3 231 void rt_pop_req (void) {
switches 0:5c4d7b2438d3 232 /* Process an ISR post service requests. */
switches 0:5c4d7b2438d3 233 struct OS_XCB *p_CB;
switches 0:5c4d7b2438d3 234 P_TCB next;
switches 0:5c4d7b2438d3 235 U32 idx;
switches 0:5c4d7b2438d3 236
switches 0:5c4d7b2438d3 237 os_tsk.run->state = READY;
switches 0:5c4d7b2438d3 238 rt_put_rdy_first (os_tsk.run);
switches 0:5c4d7b2438d3 239
switches 0:5c4d7b2438d3 240 idx = os_psq->last;
switches 0:5c4d7b2438d3 241 while (os_psq->count) {
switches 0:5c4d7b2438d3 242 p_CB = os_psq->q[idx].id;
switches 0:5c4d7b2438d3 243 if (p_CB->cb_type == TCB) {
switches 0:5c4d7b2438d3 244 /* Is of TCB type */
switches 0:5c4d7b2438d3 245 rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg);
switches 0:5c4d7b2438d3 246 }
switches 0:5c4d7b2438d3 247 else if (p_CB->cb_type == MCB) {
switches 0:5c4d7b2438d3 248 /* Is of MCB type */
switches 0:5c4d7b2438d3 249 rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg);
switches 0:5c4d7b2438d3 250 }
switches 0:5c4d7b2438d3 251 else {
switches 0:5c4d7b2438d3 252 /* Must be of SCB type */
switches 0:5c4d7b2438d3 253 rt_sem_psh ((P_SCB)p_CB);
switches 0:5c4d7b2438d3 254 }
switches 0:5c4d7b2438d3 255 if (++idx == os_psq->size) idx = 0;
switches 0:5c4d7b2438d3 256 rt_dec (&os_psq->count);
switches 0:5c4d7b2438d3 257 }
switches 0:5c4d7b2438d3 258 os_psq->last = idx;
switches 0:5c4d7b2438d3 259
switches 0:5c4d7b2438d3 260 next = rt_get_first (&os_rdy);
switches 0:5c4d7b2438d3 261 rt_switch_req (next);
switches 0:5c4d7b2438d3 262 }
switches 0:5c4d7b2438d3 263
switches 0:5c4d7b2438d3 264
switches 0:5c4d7b2438d3 265 /*--------------------------- os_tick_init ----------------------------------*/
switches 0:5c4d7b2438d3 266
switches 0:5c4d7b2438d3 267 __weak int os_tick_init (void) {
switches 0:5c4d7b2438d3 268 /* Initialize SysTick timer as system tick timer. */
switches 0:5c4d7b2438d3 269 rt_systick_init ();
switches 0:5c4d7b2438d3 270 return (-1); /* Return IRQ number of SysTick timer */
switches 0:5c4d7b2438d3 271 }
switches 0:5c4d7b2438d3 272
switches 0:5c4d7b2438d3 273 /*--------------------------- os_tick_val -----------------------------------*/
switches 0:5c4d7b2438d3 274
switches 0:5c4d7b2438d3 275 __weak U32 os_tick_val (void) {
switches 0:5c4d7b2438d3 276 /* Get SysTick timer current value (0 .. OS_TRV). */
switches 0:5c4d7b2438d3 277 return rt_systick_val();
switches 0:5c4d7b2438d3 278 }
switches 0:5c4d7b2438d3 279
switches 0:5c4d7b2438d3 280 /*--------------------------- os_tick_ovf -----------------------------------*/
switches 0:5c4d7b2438d3 281
switches 0:5c4d7b2438d3 282 __weak U32 os_tick_ovf (void) {
switches 0:5c4d7b2438d3 283 /* Get SysTick timer overflow flag */
switches 0:5c4d7b2438d3 284 return rt_systick_ovf();
switches 0:5c4d7b2438d3 285 }
switches 0:5c4d7b2438d3 286
switches 0:5c4d7b2438d3 287 /*--------------------------- os_tick_irqack --------------------------------*/
switches 0:5c4d7b2438d3 288
switches 0:5c4d7b2438d3 289 __weak void os_tick_irqack (void) {
switches 0:5c4d7b2438d3 290 /* Acknowledge timer interrupt. */
switches 0:5c4d7b2438d3 291 }
switches 0:5c4d7b2438d3 292
switches 0:5c4d7b2438d3 293
switches 0:5c4d7b2438d3 294 /*--------------------------- rt_systick ------------------------------------*/
switches 0:5c4d7b2438d3 295
switches 0:5c4d7b2438d3 296 extern void sysTimerTick(void);
switches 0:5c4d7b2438d3 297
switches 0:5c4d7b2438d3 298 void rt_systick (void) {
switches 0:5c4d7b2438d3 299 /* Check for system clock update, suspend running task. */
switches 0:5c4d7b2438d3 300 P_TCB next;
switches 0:5c4d7b2438d3 301
switches 0:5c4d7b2438d3 302 os_tsk.run->state = READY;
switches 0:5c4d7b2438d3 303 rt_put_rdy_first (os_tsk.run);
switches 0:5c4d7b2438d3 304
switches 0:5c4d7b2438d3 305 /* Check Round Robin timeout. */
switches 0:5c4d7b2438d3 306 rt_chk_robin ();
switches 0:5c4d7b2438d3 307
switches 0:5c4d7b2438d3 308 /* Update delays. */
switches 0:5c4d7b2438d3 309 os_time++;
switches 0:5c4d7b2438d3 310 rt_dec_dly ();
switches 0:5c4d7b2438d3 311
switches 0:5c4d7b2438d3 312 /* Check the user timers. */
switches 0:5c4d7b2438d3 313 #ifdef __CMSIS_RTOS
switches 0:5c4d7b2438d3 314 sysTimerTick();
switches 0:5c4d7b2438d3 315 #else
switches 0:5c4d7b2438d3 316 rt_tmr_tick ();
switches 0:5c4d7b2438d3 317 #endif
switches 0:5c4d7b2438d3 318
switches 0:5c4d7b2438d3 319 /* Switch back to highest ready task */
switches 0:5c4d7b2438d3 320 next = rt_get_first (&os_rdy);
switches 0:5c4d7b2438d3 321 rt_switch_req (next);
switches 0:5c4d7b2438d3 322 }
switches 0:5c4d7b2438d3 323
switches 0:5c4d7b2438d3 324 /*--------------------------- rt_stk_check ----------------------------------*/
switches 0:5c4d7b2438d3 325
switches 0:5c4d7b2438d3 326 __weak void rt_stk_check (void) {
switches 0:5c4d7b2438d3 327 /* Check for stack overflow. */
switches 0:5c4d7b2438d3 328 if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
switches 0:5c4d7b2438d3 329 (os_tsk.run->stack[0] != MAGIC_WORD)) {
switches 0:5c4d7b2438d3 330 os_error (OS_ERR_STK_OVF);
switches 0:5c4d7b2438d3 331 }
switches 0:5c4d7b2438d3 332 }
switches 0:5c4d7b2438d3 333
switches 0:5c4d7b2438d3 334 /*----------------------------------------------------------------------------
switches 0:5c4d7b2438d3 335 * end of file
switches 0:5c4d7b2438d3 336 *---------------------------------------------------------------------------*/
switches 0:5c4d7b2438d3 337