示例#1
0
/** 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;
}
示例#2
0
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
{
  if(duration > 0)
  {
    pinMode(_pin, OUTPUT_FAST);
    if(frequency > 0)
    {
      delayAmount = (long)(1000000/frequency)/2 - 1;
      loopTime = (long)((duration*1000)/(delayAmount*2));
      for (int x=0;x<loopTime;x++)
      {
        time1 = micros();
        time2 = time1;
        fastDigitalWrite(_pin,HIGH);
        while(((long)(time2 - time1)) <= delayAmount)
        {
          time2 = micros();
        }
        time1 = micros();
        fastDigitalWrite(_pin,LOW);
        while(((long)(time2 - time1)) <= delayAmount)
        {
          time2 = micros();
        }
      }
    }
    else
    {
      //no tone generated, basically a pause or rest note
      time1 = micros();
      time2 = time1;
      delayAmount = duration*1000;
      while(((long)(time2 - time1)) <= delayAmount)
      {
        time2 = micros();
      }
    }
  }
  else
  {
    //tone(pin, frequency) is called with two parameters only or duration is set 0
    //generate a constant tone.
    //since this generates a constant tone, it needs to be non-blocking else we would be stuck in an infinite loop
    pthread_mutex_lock(&pinMutex[_pin]);
    int tempThreadControl = ++threadControl[_pin];
    pthread_mutex_unlock(&pinMutex[_pin]);

    pthread_t toneThread;
    struct tone_thread_param *params;

    params=(tone_thread_param *)malloc(sizeof(tone_thread_param));
    params->tonePin = _pin;
    params->frequency = frequency;
    params->duration = duration;
    params->threadID = tempThreadControl;
    int iret1 = pthread_create( &toneThread, NULL, toneHandler, (void*) params);
    pthread_detach(toneThread);
  }
}
/**
 * @brief Starts serial port
 * @param baud    Baud rate to operate at. Defaults to 2400
 */
void OTSoftSerial::begin(uint16_t _baud)
{
    baud = _baud;
    uint16_t bitCycles = (F_CPU/4) / baud;    // delay function burns 4 cpu instructions per cycle
    halfDelay = bitCycles/2-readTuning;
    fullDelay = bitCycles;

    pinMode(rxPin, INPUT_PULLUP);
    pinMode(txPin, OUTPUT);
    fastDigitalWrite(txPin, HIGH);    // set txPin to high
}
示例#4
0
/** Soft SPI send */
void spiSend(uint8_t data) {
  // no interrupts during byte send - about 8 us
  cli();
  for (uint8_t i = 0; i < 8; i++) {
    fastDigitalWrite(SPI_SCK_PIN, LOW);

    fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);

    data <<= 1;

    fastDigitalWrite(SPI_SCK_PIN, HIGH);
  }
  // hold SCK high for a few ns
  nop;
  nop;
  nop;
  nop;

  fastDigitalWrite(SPI_SCK_PIN, LOW);
  // enable interrupts
  sei();
}
示例#5
0
/** Soft SPI send */
void spiSend(uint8_t data) {
  // no interrupts during byte send - about 8 us
  cli();
  for (uint8_t i = 0; i < 8; i++) {
    fastDigitalWrite(SPI_SCK_PIN, LOW);
	//delayMicroseconds(5);
	//nop;nop;

    fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
	//delayMicroseconds(5);
	nop;nop;

    data <<= 1;

    fastDigitalWrite(SPI_SCK_PIN, HIGH);
	//delayMicroseconds(5);
	nop;nop;
	
  }

  fastDigitalWrite(SPI_SCK_PIN, LOW);
  // enable interrupts
  sei();
}
示例#6
0
// Called from startup() after some initial setup has been done.
// Can abort with panic() if need be.
void POSTalt()
{
#ifdef USE_OTNULLRADIO
// FIXME
#elif defined USE_MODULE_SIM900
//The config for the GSM depends on if you want it stored in flash or EEPROM.
//
//The SIM900LinkConfig object is located at the start of POSTalt() in AltMain.cpp and takes a set of void pointers to a \0 terminated string, either stored in flash or EEPROM.
//
//For EEPROM:
//- Set the first field of SIM900LinkConfig to true.
//- The configs are stored as \0 terminated strings starting at 0x300.
//- You can program the eeprom using ./OTRadioLink/dev/utils/sim900eepromWrite.ino

//  static const void *SIM900_PIN      = (void *)0x0300; // TODO confirm this address
//  static const void *SIM900_APN      = (void *)0x0305;
//  static const void *SIM900_UDP_ADDR = (void *)0x031B;
//  static const void *SIM900_UDP_PORT = (void *)0x0329;
//  static const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config {
//                                                  true,
//                                                  SIM900_PIN,
//                                                  SIM900_APN,
//                                                  SIM900_UDP_ADDR,
//                                                  SIM900_UDP_PORT };
//For Flash:
//- Set the first field of SIM900LinkConfig to false.
//- Make a set of \0 terminated strings with the PROGMEM attribute holding the config details.
//- set the void pointers to point to the strings (or just cast the strings and pass them to SIM900LinkConfig directly)
//
//  const char myPin[] PROGMEM = "0000";
//  const char myAPN[] PROGMEM = "m2mkit.telefonica.com"; // FIXME check this
//  const char myUDPAddr[] PROGMEM = "0.0.0.0";
//  const char myUDPPort[] PROGMEM = "9999";
//  static const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config {
//                                                  false,
//                                                  SIM900_PIN,
//                                                  SIM900_APN,
//                                                  SIM900_UDP_ADDR,
//                                                  SIM900_UDP_PORT };

    static const void *SIM900_PIN      = (void *)myPin;
    static const void *SIM900_APN      = (void *)myAPN;
    static const void *SIM900_UDP_ADDR = (void *)myUDPAddr;
    static const void *SIM900_UDP_PORT = (void *)myUDPPort;
    static const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config {
        false,
        SIM900_PIN,
        SIM900_APN,
        SIM900_UDP_ADDR,
        SIM900_UDP_PORT };
    static const OTRadioLink::OTRadioChannelConfig RFMConfig(&SIM900Config, true, true, true);
    fastDigitalWrite(A3, LOW);  // This turns power to the shield on
    pinMode(A3, OUTPUT);

#elif defined(ENABLE_RADIO_PRIMARY_RFM23B)
    static const OTRadioLink::OTRadioChannelConfig RFMConfig(NULL, true, true, true);
#endif // USE_MODULE_SIM900

#if defined(ENABLE_RADIO_PRIMARY_RFM23B)
    // Initialise the radio, if configured, ASAP because it can suck a lot of power until properly initialised.
    PrimaryRadio.preinit(NULL);
    // Check that the radio is correctly connected; panic if not...
    if(!PrimaryRadio.configure(1, &RFMConfig) || !PrimaryRadio.begin()) {
        panic(F("PANIC!"));
    }
#endif


    // Force initialisation into low-power state.
    const int heat = TemperatureC16.read();
#if 0 && defined(DEBUG)
    DEBUG_SERIAL_PRINT_FLASHSTRING("temp: ");
    DEBUG_SERIAL_PRINT(heat);
    DEBUG_SERIAL_PRINTLN();
#endif
    const int light = AmbLight.read();
//#if 0 && defined(DEBUG)
//  DEBUG_SERIAL_PRINT_FLASHSTRING("light: ");
//  DEBUG_SERIAL_PRINT(light);
//  DEBUG_SERIAL_PRINTLN();
//#endif



    // Trailing setup for the run
    // --------------------------

    // Set up async edge interrupts.
    ATOMIC_BLOCK (ATOMIC_RESTORESTATE)
    {
        //PCMSK0 = PB; PCINT  0--7    (LEARN1 and Radio)
        //PCMSK1 = PC; PCINT  8--15
        //PCMSK2 = PD; PCINT 16--24   (LEARN2 and MODE, RX)

        PCICR =
#if defined(MASK_PB) && (MASK_PB != 0) // If PB interrupts required.
            1 | // 0x1 enables PB/PCMSK0.
#endif
#if defined(MASK_PC) && (MASK_PC != 0) // If PC interrupts required.
            2 | // 0x2 enables PC/PCMSK1.
#endif
#if defined(MASK_PD) && (MASK_PD != 0) // If PD interrupts required.
            4 | // 0x4 enables PD/PCMSK2.
#endif
            0;

#if defined(MASK_PB) && (MASK_PB != 0) // If PB interrupts required.
        PCMSK0 = MASK_PB;
#endif
#if defined(MASK_PC) && (MASK_PC != 0) // If PC interrupts required.
        PCMSK1 = MASK_PC;
#endif
#if defined(MASK_PD) && (MASK_PD != 0) // If PD interrupts required.
        PCMSK2 = MASK_PD;
#endif
    }


//  pinMode(3, INPUT);        // FIXME Move to where they are set automatically
//  digitalWrite(3, LOW);

    bareStatsTX(false, false, false);

}
示例#7
0
void *toneHandler(void *arg)
{
  tone_thread_param *param;
  param = (tone_thread_param*)arg;

  int tPin = param->tonePin;
  pinMode(tPin, OUTPUT_FAST);
  long delayAmount;
  long loopTime;
  unsigned long time1;
  unsigned long time2;
  int currentThreadControlID = param->threadID; //when threadControl[tPin] is modified by another thread it will no longer be equal to currentThreadControlID which exits the loop below allowing it to die

  if((param->frequency) > 0)
  {
    delayAmount = (long)(1000000/(param->frequency))/2 - 1;
    loopTime = (long)((param->duration*1000)/(delayAmount*2));

    if((param->duration) > 0)
    {
      //implementing this way because delayMicroseconds is blocking which makes the generated tone not accurate enough
      for (int x=0;x<loopTime;x++)
      {
        if(currentThreadControlID != threadControl[tPin])
        {
          break;
        }
        time1 = micros();
        time2 = time1;
        fastDigitalWrite(tPin,HIGH);
        while(((long)(time2 - time1)) <= delayAmount)
        {
          time2 = micros();
        }
        time1 = micros();
        fastDigitalWrite(tPin,LOW);
        while(((long)(time2 - time1)) <= delayAmount)
        {
          time2 = micros();
        }
      }
    }
    else
    {
      //infinite loop
      while(true)
      {
        if(currentThreadControlID != threadControl[tPin])
        {
          break;
        }
        time1 = micros();
        time2 = time1;
        fastDigitalWrite(tPin,HIGH);
        while(((long)(time2 - time1)) <= delayAmount)
        {
          time2 = micros();
        }
        time1 = micros();
        fastDigitalWrite(tPin,LOW);
        while(((long)(time2 - time1)) <= delayAmount)
        {
          time2 = micros();
        }
      }
    }
  }
  else
  {
    time1 = micros();
    time2 = time1;
    delayAmount = (param->duration)*1000;
    while(((long)(time2 - time1)) <= delayAmount)
    {
      time2 = micros();
      if(currentThreadControlID != threadControl[tPin])
      {
        break;
      }
    }
  }
}
示例#8
0
// 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;
}