| @@ -119,3 +119,151 @@ void pinMode(uint8_t pin, uint8_t mode) | |||
| *(p->mux) = 5 | 0x10; | |||
| } | |||
| void pinMode(uint8_t pin, uint8_t mode) | |||
| { | |||
| const struct digital_pin_bitband_and_config_table_struct *p; | |||
| if (pin >= CORE_NUM_DIGITAL) return; | |||
| p = digital_pin_to_info_PGM + pin; | |||
| if (mode == OUTPUT || mode == OUTPUT_OPENDRAIN) { | |||
| *(p->reg + 1) |= p->mask; // TODO: atomic | |||
| if (mode == OUTPUT) { | |||
| *(p->pad) = IOMUXC_PAD_DSE(7); | |||
| } else { // OUTPUT_OPENDRAIN | |||
| *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_ODE; | |||
| } | |||
| } else { | |||
| *(p->reg + 1) &= ~(p->mask); // TODO: atomic | |||
| if (mode == INPUT) { | |||
| *(p->pad) = 0; | |||
| } else if (mode == INPUT_PULLUP) { | |||
| *(p->pad) = IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS; | |||
| } else if (mode == INPUT_PULLDOWN) { | |||
| *(p->pad) = IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(0) | IOMUXC_PAD_HYS; | |||
| } else { // INPUT_DISABLE | |||
| *(p->pad) = IOMUXC_PAD_HYS; | |||
| } | |||
| } | |||
| *(p->mux) = 5 | 0x10; | |||
| } | |||
| void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value) | |||
| { | |||
| if (bitOrder == LSBFIRST) { | |||
| shiftOut_lsbFirst(dataPin, clockPin, value); | |||
| } else { | |||
| shiftOut_msbFirst(dataPin, clockPin, value); | |||
| } | |||
| } | |||
| void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value) | |||
| { | |||
| uint8_t mask; | |||
| for (mask=0x01; mask; mask <<= 1) { | |||
| digitalWrite(dataPin, value & mask); | |||
| digitalWrite(clockPin, HIGH); | |||
| digitalWrite(clockPin, LOW); | |||
| } | |||
| } | |||
| void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value) | |||
| { | |||
| uint8_t mask; | |||
| for (mask=0x80; mask; mask >>= 1) { | |||
| digitalWrite(dataPin, value & mask); | |||
| digitalWrite(clockPin, HIGH); | |||
| digitalWrite(clockPin, LOW); | |||
| } | |||
| } | |||
| uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) | |||
| { | |||
| if (bitOrder == LSBFIRST) { | |||
| return shiftIn_lsbFirst(dataPin, clockPin); | |||
| } else { | |||
| return shiftIn_msbFirst(dataPin, clockPin); | |||
| } | |||
| } | |||
| uint8_t shiftIn_lsbFirst(uint8_t dataPin, uint8_t clockPin) | |||
| { | |||
| uint8_t mask, value=0; | |||
| for (mask=0x01; mask; mask <<= 1) { | |||
| digitalWrite(clockPin, HIGH); | |||
| if (digitalRead(dataPin)) value |= mask; | |||
| digitalWrite(clockPin, LOW); | |||
| } | |||
| return value; | |||
| } | |||
| uint8_t shiftIn_msbFirst(uint8_t dataPin, uint8_t clockPin) | |||
| { | |||
| uint8_t mask, value=0; | |||
| for (mask=0x80; mask; mask >>= 1) { | |||
| digitalWrite(clockPin, HIGH); | |||
| if (digitalRead(dataPin)) value |= mask; | |||
| digitalWrite(clockPin, LOW); | |||
| } | |||
| return value; | |||
| } | |||
| //(*portInputRegister(pin) & digitalPinToBitMask(pin)) | |||
| uint32_t pulseIn_high(uint8_t pin, uint32_t timeout) | |||
| { | |||
| const struct digital_pin_bitband_and_config_table_struct *p; | |||
| p = digital_pin_to_info_PGM + pin; | |||
| uint32_t usec_start, usec_stop; | |||
| // wait for any previous pulse to end | |||
| usec_start = micros(); | |||
| while ((*(p->reg + 2) & p->mask)) { | |||
| if (micros()-usec_start > timeout) return 0; | |||
| } | |||
| // wait for the pulse to start | |||
| usec_start = micros(); | |||
| while (!(*(p->reg + 2) & p->mask)) { | |||
| if (micros()-usec_start > timeout) return 0; | |||
| } | |||
| usec_start = micros(); | |||
| // wait for the pulse to stop | |||
| while ((*(p->reg + 2) & p->mask)) { | |||
| if (micros()-usec_start > timeout) return 0; | |||
| } | |||
| usec_stop = micros(); | |||
| return usec_stop - usec_start; | |||
| } | |||
| uint32_t pulseIn_low(uint8_t pin, uint32_t timeout) | |||
| { | |||
| const struct digital_pin_bitband_and_config_table_struct *p; | |||
| p = digital_pin_to_info_PGM + pin; | |||
| uint32_t usec_start, usec_stop; | |||
| // wait for any previous pulse to end | |||
| usec_start = micros(); | |||
| while (!(*(p->reg + 2) & p->mask)) { | |||
| if (micros() - usec_start > timeout) return 0; | |||
| } | |||
| // wait for the pulse to start | |||
| usec_start = micros(); | |||
| while ((*(p->reg + 2) & p->mask)) { | |||
| if (micros() - usec_start > timeout) return 0; | |||
| } | |||
| usec_start = micros(); | |||
| // wait for the pulse to stop | |||
| while (!(*(p->reg + 2) & p->mask)) { | |||
| if (micros() - usec_start > timeout) return 0; | |||
| } | |||
| usec_stop = micros(); | |||
| return usec_stop - usec_start; | |||
| } | |||
| // TODO: an inline version should handle the common case where state is const | |||
| uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout) | |||
| { | |||
| if (pin >= CORE_NUM_DIGITAL) return 0; | |||
| if (state) return pulseIn_high(pin, timeout); | |||
| return pulseIn_low(pin, timeout); | |||
| } | |||