Senet-ized LMIC for MOTE_L152RC

Fork of lmic_MOTE_L152RC by Semtech

Committer:
dudmuck
Date:
Mon Nov 16 23:52:45 2015 +0000
Revision:
9:83ae7f34e88c
Parent:
6:dfc048cda33f
correct join behavior after link dead (joining again)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:f2716e543d97 1 /* HAL for MOTE_L152RC */
dudmuck 0:f2716e543d97 2
dudmuck 0:f2716e543d97 3 #include "mbed.h"
dudmuck 0:f2716e543d97 4 #include "oslmic.h"
dudmuck 0:f2716e543d97 5 #include "debug.h"
dudmuck 0:f2716e543d97 6
dudmuck 0:f2716e543d97 7 #define RADIO_MOSI PB_15
dudmuck 0:f2716e543d97 8 #define RADIO_MISO PB_14
dudmuck 0:f2716e543d97 9 #define RADIO_SCLK PB_13
dudmuck 0:f2716e543d97 10 #define RADIO_NSS PB_12
dudmuck 0:f2716e543d97 11 #define RESET_PIN PC_2
dudmuck 0:f2716e543d97 12
dudmuck 0:f2716e543d97 13 #define RFSW1 PC_4 //NorAm_Mote RFSwitch_CNTR_1
dudmuck 0:f2716e543d97 14 #define RFSW2 PC_13 //NorAm_Mote RFSwitch_CNTR_2
dudmuck 0:f2716e543d97 15
dudmuck 0:f2716e543d97 16 static DigitalOut nss(RADIO_NSS);
dudmuck 0:f2716e543d97 17 static SPI spi(RADIO_MOSI, RADIO_MISO, RADIO_SCLK); // (mosi, miso, sclk)
dudmuck 0:f2716e543d97 18
dudmuck 0:f2716e543d97 19 static DigitalInOut rst(RESET_PIN);
dudmuck 0:f2716e543d97 20
dudmuck 0:f2716e543d97 21 DigitalOut rfsw1(RFSW1);
dudmuck 0:f2716e543d97 22 DigitalOut rfsw2(RFSW2);
dudmuck 0:f2716e543d97 23
dudmuck 6:dfc048cda33f 24 DigitalOut hdr_fem_csd(PC_0);
dudmuck 0:f2716e543d97 25
dudmuck 0:f2716e543d97 26 static InterruptIn dio0(PC_6);
dudmuck 0:f2716e543d97 27 static InterruptIn dio1(PC_10);
dudmuck 0:f2716e543d97 28 static InterruptIn dio2(PC_11);
dudmuck 0:f2716e543d97 29
dudmuck 0:f2716e543d97 30 extern RTC_HandleTypeDef RtcHandle;
dudmuck 0:f2716e543d97 31
dudmuck 0:f2716e543d97 32 // HAL state
dudmuck 0:f2716e543d97 33 static struct {
dudmuck 0:f2716e543d97 34 int irqlevel;
dudmuck 0:f2716e543d97 35 } HAL;
dudmuck 0:f2716e543d97 36
dudmuck 0:f2716e543d97 37 void radio_irq_handler (u1_t dio);
dudmuck 0:f2716e543d97 38
dudmuck 0:f2716e543d97 39 static void dio0Irq( void ){
dudmuck 0:f2716e543d97 40 radio_irq_handler( 0 );
dudmuck 0:f2716e543d97 41 }
dudmuck 0:f2716e543d97 42 static void dio1Irq( void ){
dudmuck 0:f2716e543d97 43 radio_irq_handler( 1 );
dudmuck 0:f2716e543d97 44 }
dudmuck 0:f2716e543d97 45 static void dio2Irq( void ){
dudmuck 0:f2716e543d97 46 radio_irq_handler( 2 );
dudmuck 0:f2716e543d97 47 }
dudmuck 0:f2716e543d97 48
dudmuck 0:f2716e543d97 49 void hal_disableIRQs()
dudmuck 0:f2716e543d97 50 {
dudmuck 0:f2716e543d97 51 __disable_irq();
dudmuck 0:f2716e543d97 52 HAL.irqlevel++;
dudmuck 0:f2716e543d97 53 }
dudmuck 0:f2716e543d97 54
dudmuck 0:f2716e543d97 55 void hal_enableIRQs()
dudmuck 0:f2716e543d97 56 {
dudmuck 0:f2716e543d97 57 if (--HAL.irqlevel == 0) {
dudmuck 0:f2716e543d97 58 __enable_irq();
dudmuck 0:f2716e543d97 59 }
dudmuck 0:f2716e543d97 60 }
dudmuck 0:f2716e543d97 61
dudmuck 0:f2716e543d97 62 void hal_failed ()
dudmuck 0:f2716e543d97 63 {
dudmuck 0:f2716e543d97 64 while (1)
dudmuck 0:f2716e543d97 65 asm("nop");
dudmuck 0:f2716e543d97 66 }
dudmuck 0:f2716e543d97 67
dudmuck 0:f2716e543d97 68 static void rtc_wkup_irq(void)
dudmuck 0:f2716e543d97 69 {
dudmuck 0:f2716e543d97 70 HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle);
dudmuck 0:f2716e543d97 71 }
dudmuck 0:f2716e543d97 72
dudmuck 0:f2716e543d97 73 void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
dudmuck 0:f2716e543d97 74 {
dudmuck 0:f2716e543d97 75 /* Clear Wake Up Flag */
dudmuck 0:f2716e543d97 76 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
dudmuck 0:f2716e543d97 77 }
dudmuck 0:f2716e543d97 78
dudmuck 0:f2716e543d97 79 /*void HAL_RCC_CCSCallback()
dudmuck 0:f2716e543d97 80 {
dudmuck 0:f2716e543d97 81 for (;;) asm("nop");
dudmuck 0:f2716e543d97 82 }*/
dudmuck 0:f2716e543d97 83
dudmuck 0:f2716e543d97 84
dudmuck 0:f2716e543d97 85 volatile uint32_t /*rcc_cr_a, rcc_cr_b,*/ rcc_cr_c;
dudmuck 0:f2716e543d97 86 void hal_init (void)
dudmuck 0:f2716e543d97 87 {
dudmuck 0:f2716e543d97 88 memset(&HAL, 0x00, sizeof(HAL));
dudmuck 0:f2716e543d97 89 hal_disableIRQs();
dudmuck 0:f2716e543d97 90
dudmuck 0:f2716e543d97 91 #if USE_SMTC_RADIO_DRIVER
dudmuck 0:f2716e543d97 92
dudmuck 0:f2716e543d97 93 #else
dudmuck 0:f2716e543d97 94 // configure input lines
dudmuck 0:f2716e543d97 95 dio0.mode(PullDown);
dudmuck 0:f2716e543d97 96 dio0.rise(dio0Irq);
dudmuck 0:f2716e543d97 97 dio0.enable_irq();
dudmuck 0:f2716e543d97 98 dio1.mode(PullDown);
dudmuck 0:f2716e543d97 99 dio1.rise(dio1Irq);
dudmuck 0:f2716e543d97 100 dio1.enable_irq();
dudmuck 0:f2716e543d97 101 dio2.mode(PullDown);
dudmuck 0:f2716e543d97 102 dio2.rise(dio2Irq);
dudmuck 0:f2716e543d97 103 dio2.enable_irq();
dudmuck 0:f2716e543d97 104 // configure reset line
dudmuck 0:f2716e543d97 105 rst.input();
dudmuck 0:f2716e543d97 106 // configure spi
dudmuck 0:f2716e543d97 107 spi.frequency(8000000);
dudmuck 0:f2716e543d97 108 spi.format(8, 0);
dudmuck 0:f2716e543d97 109 nss = 1;
dudmuck 0:f2716e543d97 110 //RFSwitch_CNTR_2 = 1;
dudmuck 0:f2716e543d97 111 #endif
dudmuck 0:f2716e543d97 112
dudmuck 0:f2716e543d97 113 set_time(0); // initialize RTC
dudmuck 0:f2716e543d97 114
dudmuck 0:f2716e543d97 115 /* Enable Ultra low power mode */
dudmuck 0:f2716e543d97 116 HAL_PWREx_EnableUltraLowPower();
dudmuck 0:f2716e543d97 117
dudmuck 0:f2716e543d97 118 /* Enable the fast wake up from Ultra low power mode */
dudmuck 0:f2716e543d97 119 HAL_PWREx_EnableFastWakeUp();
dudmuck 0:f2716e543d97 120
dudmuck 0:f2716e543d97 121 __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_WUTF);
dudmuck 0:f2716e543d97 122
dudmuck 0:f2716e543d97 123 NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)rtc_wkup_irq);
dudmuck 0:f2716e543d97 124 NVIC_EnableIRQ(RTC_WKUP_IRQn);
dudmuck 0:f2716e543d97 125
dudmuck 6:dfc048cda33f 126 hdr_fem_csd = 0;
dudmuck 0:f2716e543d97 127
dudmuck 0:f2716e543d97 128 hal_enableIRQs();
dudmuck 0:f2716e543d97 129
dudmuck 0:f2716e543d97 130 GPIOA->MODER |= 0x01415500; // unused pins as outputs: PA4, PA5, PA6, PA7, PA8, (PA11,PA12 USB)
dudmuck 0:f2716e543d97 131 GPIOB->MODER |= 0x00000401; // unused pins as outputs: PB0(HDR_DIO1), PB5 (PB10 pulled hi by LED), PB3-T_SWO
dudmuck 0:f2716e543d97 132 GPIOC->MODER |= 0x00000041; // unused pins as outputs: PC0(HDR_FEM_CSD), PC3(SPI3_enable)
dudmuck 0:f2716e543d97 133
dudmuck 0:f2716e543d97 134
dudmuck 0:f2716e543d97 135 }
dudmuck 0:f2716e543d97 136
dudmuck 0:f2716e543d97 137 u4_t hal_ticks ()
dudmuck 0:f2716e543d97 138 {
dudmuck 0:f2716e543d97 139 RTC_DateTypeDef dateStruct;
dudmuck 0:f2716e543d97 140 RTC_TimeTypeDef timeStruct;
dudmuck 0:f2716e543d97 141 struct tm timeinfo;
dudmuck 0:f2716e543d97 142 uint16_t sub_seconds;
dudmuck 0:f2716e543d97 143
dudmuck 0:f2716e543d97 144 RtcHandle.Instance = RTC;
dudmuck 0:f2716e543d97 145
dudmuck 0:f2716e543d97 146 // Read actual date and time
dudmuck 0:f2716e543d97 147 // Warning: the time must be read first!
dudmuck 0:f2716e543d97 148 HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
dudmuck 0:f2716e543d97 149 HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
dudmuck 0:f2716e543d97 150 sub_seconds = 16384 - timeStruct.SubSeconds; // RTC_SSR counts down
dudmuck 0:f2716e543d97 151
dudmuck 0:f2716e543d97 152 // Setup a tm structure based on the RTC
dudmuck 0:f2716e543d97 153 timeinfo.tm_wday = dateStruct.WeekDay;
dudmuck 0:f2716e543d97 154 timeinfo.tm_mon = dateStruct.Month - 1;
dudmuck 0:f2716e543d97 155 timeinfo.tm_mday = dateStruct.Date;
dudmuck 0:f2716e543d97 156 timeinfo.tm_year = dateStruct.Year + 100;
dudmuck 0:f2716e543d97 157 timeinfo.tm_hour = timeStruct.Hours;
dudmuck 0:f2716e543d97 158 timeinfo.tm_min = timeStruct.Minutes;
dudmuck 0:f2716e543d97 159 timeinfo.tm_sec = timeStruct.Seconds;
dudmuck 0:f2716e543d97 160
dudmuck 0:f2716e543d97 161 // Convert to timestamp
dudmuck 0:f2716e543d97 162 time_t t = mktime(&timeinfo);
dudmuck 0:f2716e543d97 163
dudmuck 0:f2716e543d97 164 // 14: SSR is driven at 16384Hz
dudmuck 1:04fd63382b03 165 t <<= 14;
dudmuck 1:04fd63382b03 166 return t | sub_seconds;
dudmuck 0:f2716e543d97 167 }
dudmuck 0:f2716e543d97 168
dudmuck 0:f2716e543d97 169 void hal_waitUntil (u4_t time)
dudmuck 0:f2716e543d97 170 {
dudmuck 0:f2716e543d97 171 while (hal_ticks() < time)
dudmuck 0:f2716e543d97 172 asm("nop");
dudmuck 0:f2716e543d97 173 }
dudmuck 0:f2716e543d97 174
dudmuck 0:f2716e543d97 175
dudmuck 0:f2716e543d97 176 volatile char deep_sleep;
dudmuck 0:f2716e543d97 177 /* return 1 if target time is soon, return 0 if timer was programmed */
dudmuck 0:f2716e543d97 178 u1_t hal_checkTimer (u4_t time)
dudmuck 0:f2716e543d97 179 {
dudmuck 0:f2716e543d97 180 int d = time - hal_ticks();
dudmuck 0:f2716e543d97 181
dudmuck 0:f2716e543d97 182 HAL_RTCEx_DeactivateWakeUpTimer(&RtcHandle);
dudmuck 0:f2716e543d97 183 __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_WUTF);
dudmuck 0:f2716e543d97 184
dudmuck 0:f2716e543d97 185 if (d < 0x10000) { // less than 4s
dudmuck 0:f2716e543d97 186 deep_sleep = 0;
dudmuck 0:f2716e543d97 187 if (d < 4)
dudmuck 0:f2716e543d97 188 return 1; // very soon
dudmuck 0:f2716e543d97 189 if (d > ms2osticks(100)) {
dudmuck 0:f2716e543d97 190 d -= 13; // HSE_PLL startup time
dudmuck 0:f2716e543d97 191 deep_sleep = 1;
dudmuck 0:f2716e543d97 192 }
dudmuck 0:f2716e543d97 193 // 61.035us steps
dudmuck 0:f2716e543d97 194 HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d, RTC_WAKEUPCLOCK_RTCCLK_DIV2);
dudmuck 0:f2716e543d97 195 } else if (d < 0x20000) { // less than 8s
dudmuck 0:f2716e543d97 196 d -= 6; // HSE_PLL startup time
dudmuck 0:f2716e543d97 197 deep_sleep = 1;
dudmuck 0:f2716e543d97 198 // 122us steps
dudmuck 0:f2716e543d97 199 HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d >> 1, RTC_WAKEUPCLOCK_RTCCLK_DIV4);
dudmuck 0:f2716e543d97 200 } else if (d < 0x40000) { // less than 16s
dudmuck 0:f2716e543d97 201 deep_sleep = 1;
dudmuck 0:f2716e543d97 202 // 244us steps
dudmuck 0:f2716e543d97 203 HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d >> 2, RTC_WAKEUPCLOCK_RTCCLK_DIV8);
dudmuck 0:f2716e543d97 204 } else if (d < 0x80000) { // less than 32s
dudmuck 0:f2716e543d97 205 deep_sleep = 1;
dudmuck 0:f2716e543d97 206 // 488us steps
dudmuck 0:f2716e543d97 207 HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d >> 3, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
dudmuck 0:f2716e543d97 208 } else {
dudmuck 0:f2716e543d97 209 deep_sleep = 1;
dudmuck 0:f2716e543d97 210 // 1s steps to 18hours
dudmuck 0:f2716e543d97 211 HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, d >> 14, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
dudmuck 0:f2716e543d97 212 /* RTC_WAKEUPCLOCK_CK_SPRE_17BITS: 18h to 36h */
dudmuck 0:f2716e543d97 213 /*for (;;)
dudmuck 0:f2716e543d97 214 asm("nop");*/
dudmuck 0:f2716e543d97 215 }
dudmuck 0:f2716e543d97 216
dudmuck 0:f2716e543d97 217 return 0;
dudmuck 0:f2716e543d97 218 }
dudmuck 0:f2716e543d97 219
dudmuck 0:f2716e543d97 220 //#define SLEEP_DEBUG 1
dudmuck 0:f2716e543d97 221
dudmuck 0:f2716e543d97 222 void hal_sleep ()
dudmuck 0:f2716e543d97 223 {
dudmuck 0:f2716e543d97 224 #ifdef SLEEP_DEBUG
dudmuck 0:f2716e543d97 225 u4_t start_tick, end_tick;
dudmuck 0:f2716e543d97 226 volatile uint32_t time_asleep;
dudmuck 0:f2716e543d97 227 #endif /* SLEEP_DEBUG */
dudmuck 0:f2716e543d97 228
dudmuck 0:f2716e543d97 229 #ifdef USE_DEBUGGER
dudmuck 0:f2716e543d97 230 HAL_EnableDBGStopMode();
dudmuck 0:f2716e543d97 231 if (!DBGMCU->CR & DBGMCU_CR_DBG_STOP)
dudmuck 0:f2716e543d97 232 for (;;) asm("nop");
dudmuck 0:f2716e543d97 233 #endif /* USE_DEBUGGER */
dudmuck 0:f2716e543d97 234
dudmuck 1:04fd63382b03 235 //printf("%x cr:%06x isr:%04x %d\r\n", RtcHandle.Instance->WUTR, RtcHandle.Instance->CR, RtcHandle.Instance->ISR, deep_sleep);
dudmuck 1:04fd63382b03 236 //debug_done();
dudmuck 1:04fd63382b03 237
dudmuck 9:83ae7f34e88c 238 if (deep_sleep) {
dudmuck 0:f2716e543d97 239 debug_done(); // wait here if debug still printing
dudmuck 9:83ae7f34e88c 240 }
dudmuck 0:f2716e543d97 241
dudmuck 0:f2716e543d97 242 if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&RtcHandle, RTC_FLAG_WUTF) == 0) {
dudmuck 0:f2716e543d97 243 // set gpio for sleep
dudmuck 0:f2716e543d97 244 #ifdef SLEEP_DEBUG
dudmuck 0:f2716e543d97 245 start_tick = hal_ticks();
dudmuck 0:f2716e543d97 246 #endif /* SLEEP_DEBUG */
dudmuck 6:dfc048cda33f 247
dudmuck 0:f2716e543d97 248
dudmuck 0:f2716e543d97 249 if (deep_sleep) {
dudmuck 0:f2716e543d97 250 #ifndef USE_DEBUGGER
dudmuck 0:f2716e543d97 251 /* PA13 to undriven JTMS/SWDIO pin (from AF0 to GPIO), and PA2 */
dudmuck 0:f2716e543d97 252 GPIOA->MODER &= 0xf7ffffdf;
dudmuck 0:f2716e543d97 253 GPIOB->MODER &= 0xffffdfff; // PB6 UART_TX to input
dudmuck 0:f2716e543d97 254 #endif
dudmuck 0:f2716e543d97 255 deepsleep(); // blocks until waking
dudmuck 0:f2716e543d97 256 #ifndef USE_DEBUGGER
dudmuck 0:f2716e543d97 257 /* PA13 back to JTMS/SWDIO pin (from GPIO to AF0), and PA2 */
dudmuck 0:f2716e543d97 258 GPIOA->MODER |= 0x08000020;
dudmuck 0:f2716e543d97 259 GPIOB->MODER |= 0x00002000; // PB6 input to UART_TX
dudmuck 0:f2716e543d97 260 #endif
dudmuck 0:f2716e543d97 261 } else
dudmuck 0:f2716e543d97 262 sleep(); // blocks until waking
dudmuck 0:f2716e543d97 263
dudmuck 0:f2716e543d97 264 #ifdef SLEEP_DEBUG
dudmuck 0:f2716e543d97 265 end_tick = hal_ticks();
dudmuck 0:f2716e543d97 266 time_asleep = end_tick - start_tick;
dudmuck 1:04fd63382b03 267 printf("%u = %u - %u\r\n", time_asleep, end_tick, start_tick);
dudmuck 0:f2716e543d97 268 #endif /* SLEEP_DEBUG */
dudmuck 0:f2716e543d97 269 // restore gpio from sleep
dudmuck 0:f2716e543d97 270 }
dudmuck 0:f2716e543d97 271 }
dudmuck 0:f2716e543d97 272
dudmuck 0:f2716e543d97 273 void hal_pin_nss (u1_t val)
dudmuck 0:f2716e543d97 274 {
dudmuck 0:f2716e543d97 275 nss = val;
dudmuck 0:f2716e543d97 276 }
dudmuck 0:f2716e543d97 277
dudmuck 0:f2716e543d97 278 u1_t hal_spi (u1_t out)
dudmuck 0:f2716e543d97 279 {
dudmuck 0:f2716e543d97 280 return spi.write(out);
dudmuck 0:f2716e543d97 281 }
dudmuck 0:f2716e543d97 282
dudmuck 0:f2716e543d97 283 // 0=RX 1=TX
dudmuck 0:f2716e543d97 284 /*void hal_pin_rxtx (u1_t val)
dudmuck 0:f2716e543d97 285 {
dudmuck 0:f2716e543d97 286 rxtx = !val;
dudmuck 0:f2716e543d97 287 }*/
dudmuck 0:f2716e543d97 288 #define OPMODE_LORA 0x80
dudmuck 0:f2716e543d97 289 #define OPMODE_MASK 0x07
dudmuck 0:f2716e543d97 290 #define OPMODE_SLEEP 0x00
dudmuck 0:f2716e543d97 291 #define OPMODE_STANDBY 0x01
dudmuck 0:f2716e543d97 292 #define OPMODE_FSTX 0x02
dudmuck 0:f2716e543d97 293 #define OPMODE_TX 0x03
dudmuck 0:f2716e543d97 294 #define OPMODE_FSRX 0x04
dudmuck 0:f2716e543d97 295 #define OPMODE_RX 0x05
dudmuck 0:f2716e543d97 296 #define OPMODE_RX_SINGLE 0x06
dudmuck 0:f2716e543d97 297 #define OPMODE_CAD 0x07
dudmuck 0:f2716e543d97 298 void hal_opmode(u1_t mode, u1_t pa_boost)
dudmuck 0:f2716e543d97 299 {
dudmuck 0:f2716e543d97 300 if (mode == OPMODE_TX) { // start of transmission
dudmuck 0:f2716e543d97 301 if (pa_boost) {
dudmuck 0:f2716e543d97 302 rfsw2 = 0;
dudmuck 0:f2716e543d97 303 rfsw1 = 1;
dudmuck 0:f2716e543d97 304 } else {
dudmuck 0:f2716e543d97 305 rfsw2 = 1;
dudmuck 0:f2716e543d97 306 rfsw1 = 0;
dudmuck 0:f2716e543d97 307 }
dudmuck 6:dfc048cda33f 308 hdr_fem_csd = 0; // debug
dudmuck 0:f2716e543d97 309 } else if (mode == OPMODE_RX || mode == OPMODE_RX_SINGLE || mode == OPMODE_CAD) { // start of reception
dudmuck 0:f2716e543d97 310 rfsw2 = 1;
dudmuck 4:1a9a62cf220f 311 rfsw1 = 1;
dudmuck 6:dfc048cda33f 312 hdr_fem_csd = 1; // debug
dudmuck 0:f2716e543d97 313 } else { // RF switch shutdown
dudmuck 0:f2716e543d97 314 rfsw2 = 0;
dudmuck 0:f2716e543d97 315 rfsw1 = 0;
dudmuck 6:dfc048cda33f 316 hdr_fem_csd = 0; // debug
dudmuck 0:f2716e543d97 317 }
dudmuck 0:f2716e543d97 318 }
dudmuck 0:f2716e543d97 319
dudmuck 0:f2716e543d97 320 void hal_pin_rst (u1_t val)
dudmuck 0:f2716e543d97 321 {
dudmuck 0:f2716e543d97 322 if (val == 0 || val == 1) { // drive pin
dudmuck 0:f2716e543d97 323 rst.output();
dudmuck 0:f2716e543d97 324 rst = val;
dudmuck 0:f2716e543d97 325 } else { // keep pin floating
dudmuck 0:f2716e543d97 326 rst.input();
dudmuck 0:f2716e543d97 327 }
dudmuck 0:f2716e543d97 328 }
dudmuck 0:f2716e543d97 329