/** * @brief Blocking read a single char * @retval value received */ uint8_t OTSoftSerial::read() { uint8_t val = 0; const uint8_t readFullDelay = fullDelay-readTuning; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { uint16_t timer = timeOut; // wait for line to go low while (fastDigitalRead(rxPin)) { if (--timer == 0) return 0; } // wait for mid point of bit _delay_x4cycles(halfDelay); // step through bits and read value // FIXME better way of doing this? for(uint8_t i = 0; i < 8; i++) { _delay_x4cycles(readFullDelay); val |= fastDigitalRead(rxPin) << i; } timer = timeOut; while (!fastDigitalRead(rxPin)) { if (--timer == 0) return 0; } } return val; }
/** Soft SPI receive */ uint8_t spiRec(void) { uint8_t data = 0; // no interrupts during byte receive - about 8 us cli(); // output pin high - like sending 0XFF fastDigitalWrite(SPI_MOSI_PIN, HIGH); for (uint8_t i = 0; i < 8; i++) { fastDigitalWrite(SPI_SCK_PIN, HIGH); // adjust so SCK is nice nop; nop; data <<= 1; if (fastDigitalRead(SPI_MISO_PIN)) { data |= 1; } fastDigitalWrite(SPI_SCK_PIN, LOW); } // enable interrupts sei(); return data; }
/** * @brief Blocking read that times out after ?? seconds * @param buf pointer to array to store read in * @param len max length of array to store read in * @retval Length of read. Returns 0 if nothing received */ uint8_t OTSoftSerial::read(uint8_t *buf, uint8_t _len) { uint8_t len = _len; uint8_t count = 0; const uint8_t readFullDelay = fullDelay-readTuning; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { while (count < len) { // wait for line to go low uint16_t timer = timeOut; uint8_t val; val = 0; while (fastDigitalRead(rxPin)) { if (--timer == 0) return count; } // wait for mid point of bit _delay_x4cycles(halfDelay); // step through bits and read value // FIXME better way of doing this? for(uint8_t i = 0; i < 8; i++) { _delay_x4cycles(readFullDelay); val |= fastDigitalRead(rxPin) << i; } // write val to buf and increment buf and count ready for next char *buf = val; buf++; count++; // wait for stop bit timer = timeOut; while (!fastDigitalRead(rxPin)) { if (--timer == 0) return count; } } } return count; }
long fastPulseIn(const char *pin, int value) { struct timeval tv; double last, time = 0; gettimeofday(&tv, NULL); last = tv.tv_usec; while(1) { if(fastDigitalRead(pin) != value) { break; } gettimeofday(&tv, NULL); time += abs(last - tv.tv_usec); last = tv.tv_usec; } return time; }
// test - watch for input int main(int argc, char **argv) { unsigned char buffer[2048]; unsigned char bitmap[8192]; char temp[256]; Timer playbackTimer; if (argc < 2) { printf("usage: pispi <input.c64>\n"); return 1; } const char *fname = argv[1]; int frameSkip = 5; memset(buffer, 0, 1024); if (argc == 3) { const char *outfname = argv[2]; mp4toc64(fname, outfname, 12.0); printf("done.\n"); exit(1); } // convert mp4 C64FrameDataSource source(fname); //MP4FrameDataSource source(fname, 6.0); wiringPiSetup(); pinMode(0, INPUT); pullUpDnControl(0, PUD_UP); pinMode(1, OUTPUT); pullUpDnControl(1, PUD_OFF); fastDigitalWrite(1, LOW); // reset MCU int spi = wiringPiSPISetup(0, 2000000); delayMicroseconds(100000); fastDigitalWrite(1, HIGH); printf("checking for commands..\n"); int frames = 0; unsigned char *imgptr = NULL; bool done = false; bool started = false; while (!done) { // loop - check for updates unsigned char cmd; while (fastDigitalRead(0) == HIGH) { delayMicroseconds(10); } // get byte int r = read(spi, &cmd, 1); // start a frame if (cmd == 0) { if (!started) { started = true; playbackTimer.start(); } playbackTimer.end(); const unsigned char *frameChunk = source.getFrameChunk(cmd); int s = write(spi, frameChunk, 1024); float currTime = playbackTimer.getCurrentElapsedTime(); float currFps = (float)frames / currTime; } else if (cmd < 9) { const unsigned char *frameChunk = source.getFrameChunk(cmd); int s = write(spi, frameChunk, 1024); } // wait for deassert while (fastDigitalRead(0) == LOW) { delayMicroseconds(10); } float curr_playback_time = playbackTimer.getCurrentElapsedTime(); source.workForChunk(cmd, curr_playback_time); } return 1; }