/** * Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, * suli_pulse_in() waits for the pin to go HIGH, starts timing, * then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds. * Gives up and returns 0 if no pulse starts within a specified time out. * para - * pin: pins which you want to read the pulse. * state: type of pulse to read: either HIGH or LOW. (int) * timeout (optional): the number of microseconds to wait for the pulse to start; default is one second (unsigned long) */ uint32 suli_pulse_in(IO_T *pio, uint8 state, uint32 timeout) { #define LOOP_CYCLES 38 uint32 width = 0; uint32 numloops = 0; uint32 maxloops = timeout * 32 / (LOOP_CYCLES-5); while(suli_pin_read(pio) == state) { if (numloops++ == maxloops) return 0; } while(suli_pin_read(pio) != state) { if (numloops++ == maxloops) return 0; } while(((u32AHI_DioReadInput() >> (*pio)) & 0x1) == state) { if (numloops++ == maxloops) return 0; width++; } return (width * LOOP_CYCLES + 32) / 32; }
void send16bitData(unsigned int data) { for(int i=0; i<16; i++) { unsigned int state = data&0x8000 ? HIGH : LOW; suli_pin_write(&__pinDta, state); state = suli_pin_read(&__pinClk) ? LOW : HIGH; suli_pin_write(&__pinClk, state); data <<= 1; } }
void GroveLEDBar::sendData(uint16_t data) { for (uint8_t i = 0; i < 16; i++) { uint16_t state = (data & 0x8000) ? SULI_HIGH : SULI_LOW; suli_pin_write(io_data, state); state = suli_pin_read(io_clk) ? SULI_LOW : SULI_HIGH; suli_pin_write(io_clk, state); data <<= 1; } }
bool GroveTempHumPro::_read(IO_T *io) { uint8_t laststate = SULI_HIGH; uint8_t counter = 0; uint8_t j = 0, i; unsigned long currenttime; // pull the pin high and wait 250 milliseconds //digitalWrite(_pin, SULI_HIGH); //suli_pin_write(io, SULI_HIGH); //suli_delay_ms(250); currenttime = suli_millis(); if (currenttime < _lastreadtime) { // ie there was a rollover _lastreadtime = 0; } if (!firstreading && ((currenttime - _lastreadtime) < 2000)) { return true; // return last correct measurement //delay(2000 - (currenttime - _lastreadtime)); } firstreading = false; _lastreadtime = suli_millis(); data[0] = data[1] = data[2] = data[3] = data[4] = 0; // now pull it low for ~20 milliseconds //pinMode(_pin, OUTPUT); suli_pin_dir(io, SULI_OUTPUT); //digitalWrite(_pin, LOW); suli_pin_write(io, SULI_LOW); suli_delay_ms(20); //cli(); //digitalWrite(_pin, SULI_HIGH); suli_pin_write(io, SULI_HIGH); //delayMicroseconds(40); suli_delay_us(40); //pinMode(_pin, INPUT); suli_pin_dir(io, SULI_INPUT); // read in timings for (i = 0; i < MAXTIMINGS; i++) { counter = 0; //while (digitalRead(_pin) == laststate) { while (suli_pin_read(io) == laststate) { counter++; //delayMicroseconds(1); suli_delay_us(1); if (counter == 255) { break; } } //laststate = digitalRead(&_pin); laststate = suli_pin_read(io); if (counter == 255) break; // ignore first 3 transitions if ((i >= 4) && (i % 2 == 0)) { // shove each bit into the storage bytes data[j / 8] <<= 1; if (counter > _count) // data[j / 8] |= 1; j++; } } // check we read 40 bits and that the checksum matches if ((j >= 40) && (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF))) { return true; } return false; }
bool GroveIRDistanceInterrupter::read_approach(uint8_t *approach) { uint8_t v = suli_pin_read(io); *approach = (v == 0) ? 1 : 0; return true; }
bool GroveMagneticSwitch::read_approach(uint8_t *mag_approach) { *mag_approach = suli_pin_read(io); return true; }
bool GroveButton::read_pressed(uint8_t *pressed) { *pressed = suli_pin_read(io); return true; }
bool GroveDryReedRelay::read_onoff_status(int *onoff) { *onoff = suli_pin_read(io); return true; }