コード例 #1
0
ファイル: main.cpp プロジェクト: JerryLutor/openLRSngDL
void slaveLoop()
{
  watchdogReset();
  uint32_t now = micros();
  bool     needHop=false;
  switch (state) {
  case 0: // waiting for packet
    if (RF_Mode == Received) {
      Green_LED_ON;
      Red_LED_OFF;
      // got packet
      lastReceived = now;
      lostpkts=0;
      linkQuality = (linkQuality << 1) | 1;

      RF_Mode = Receive;

      spiSendAddress(0x7f); // Send the package read command
      for (int16_t i = 0; i < bind_data.packetSize; i++) {
        rx_buf[i] = spiReadData();
      }

      uint8_t payloadBytes = (rx_buf[0] & 0x3f);
      if (payloadBytes > (bind_data.packetSize - 1)) {
        // INVALID DATA
        payloadBytes = 0;
      }

      // Check if this is a new packet from master and not a resent one
      if ((rx_buf[0] ^ tx_buf[0]) & MASTER_SEQ) {
        tx_buf[0] ^= MASTER_SEQ;
        if (payloadBytes) {
          // DATA FRAME
          if (bind_data.flags & PACKET_MODE) {
            serialWrite(0xf0);
            serialWrite(payloadBytes);
            CRCtx = 0;
          }
          for (uint8_t i=0; i < payloadBytes; i++) {
            serialWrite(rx_buf[1 + i]);
            if ((bind_data.flags & PACKET_MODE) && (bind_data.flags & PACKETCRC_MODE)) {
              CRC16_add(&CRCtx, rx_buf[1 + i]);
            }
          }
          if ((bind_data.flags & PACKET_MODE) && (bind_data.flags & PACKETCRC_MODE)) {
            serialWrite(CRCtx >> 8);
            serialWrite(CRCtx & 0xff);
          }
        }
      }
コード例 #2
0
ファイル: MYSBootloader.c プロジェクト: AlfredSch/Arduino
static bool sendAndWait(uint8_t reqType, uint8_t resType) {
	outMsg.type = reqType;
	// outer loop, retries
	for (uint8_t i = 0; i < MAX_RESEND; i++) {
		sendWrite(outMsg);
		// loop 20 times, wait time 0.1s if no/wrong data => 2s
		for (uint8_t j = 0; j < 20; j++) {
			// loop 100 times, wait 1ms if no/wrong data => 0.1s
			for (uint8_t k = 0; k < 100; k++) {
				watchdogReset();
				// Tx FIFO data available? (we don't care about the pipe here)
				if (available(NULL)) {
					// read message from FIFO, skip if size = 0
					if (readMessage(inMsg.array) > 0) {
						// protocol compatible? if not ignore msg
						if ((mGetVersion(inMsg) != PROTOCOL_VERSION)) {
							continue;
						}
						// msg for us?
						if (inMsg.destination == nc.nodeId) {
							// internal command: find parent
							if ((mGetCommand(inMsg) == C_INTERNAL) && (inMsg.type == I_FIND_PARENT_RESPONSE)) {
								// static parent found?
								if (configuredParentID == inMsg.sender) {
									configuredParentFound = true;
								}
								if ( ((inMsg.bValue < nc.distance - 1) && ( !configuredParentFound) ) || (configuredParentID == inMsg.sender)) {
									// got new routing info, update settings
									nc.distance = inMsg.bValue + 1;
									nc.parentNodeId = inMsg.sender;
								}
							}
							// did we receive expected reply?
							if ((mGetCommand(inMsg) == mGetCommand(outMsg)) && (inMsg.type == resType)) {
								return true;
							}
						
						}
					}
				} else { 
					// wait 1ms if no data available
					_delay_ms(1);
				}
				
			}
		}
	}
	return false;
}
コード例 #3
0
void vApplicationIdleHook( void )
{
  static uint32_t tickOfLatestWatchdogReset = M2T(0);

  portTickType tickCount = xTaskGetTickCount();

  if (tickCount - tickOfLatestWatchdogReset > M2T(WATCHDOG_RESET_PERIOD_MS))
  {
    tickOfLatestWatchdogReset = tickCount;
    watchdogReset();
  }

  // Enter sleep mode. Does not work when debugging chip with SWD.
  // Currently saves about 20mA STM32F405 current consumption (~30%).
#ifndef DEBUG
  { __asm volatile ("wfi"); }
#endif
}
コード例 #4
0
ファイル: monome-boot.c プロジェクト: pcbeard/monome-firmware
uint8_t getch(void) {
  uint8_t ch;

  watchdogReset();


	PORTD = 0;              // setup PORTD for input
	DDRD = 0;               // input w/ tristate	
	while((PINC & C1_RXF));	// wait for data
	PORTC |= C2_RD;
	ch = PIND;
	PORTC &= ~(C2_RD);

	return ch;

  // while(!(UCSR0A & _BV(RXC0)));
  // ch = UDR0;

  return ch;
}
コード例 #5
0
ファイル: serial.c プロジェクト: MarekLew/Ariadne-Bootloader
uint8_t getch(void)
{
	uint8_t ch;

	while(!(UCSR0A & _BV(RXC0)));
	if(!(UCSR0A & _BV(FE0))) {
		/*
		 * A Framing Error indicates (probably) that something is talking
		 * to us at the wrong bit rate.  Assume that this is because it
		 * expects to be talking to the application, and DON'T reset the
		 * watchdog.  This should cause the bootloader to abort and run
		 * the application "soon", if it keeps happening.  (Note that we
		 * don't care that an invalid char is returned...)
		 */
		watchdogReset();
	}
	ch = UDR0;

	return ch;
}
コード例 #6
0
ファイル: main.c プロジェクト: ctech4285/opengrab_can
int main(void)
{
    halInit();
    chSysInit();
    sdStart(&STDOUT_SD, NULL);

    watchdogInit(WATCHDOG_TIMEOUT_MS);
    const int wdid = watchdogStart();

    restoreConfig();
    magnetInit();
    consoleInit();

    int res = canasctlInit();
    if (res)
    {
        TRACE("init", "CANAS NOT INITED (%d), FIX CONFIG AND RESTART", res);
        while (1)
        {
            ledOn();
            watchdogReset(wdid);
            chThdSleepMilliseconds(100);
        }
    }

#if RELEASE
    TRACE("init", "debug port will be disabled %d sec later", DEBUG_PORT_DISABLE_DEADLINE_SEC);
#endif

    bool debug_port_disabled = false;
    while (1)
    {
        const bool
            feedback = magnetReadFeedback(),
            requested = magnetGetRequestedState();

        ledOn();

        if (feedback != requested)
        {
            chThdSleepMilliseconds(70);
            ledOff();
            chThdSleepMilliseconds(70);
        }
        else if (feedback)
        {
            chThdSleepMilliseconds(500);
            ledOff();
            chThdSleepMilliseconds(500);
        }
        else
        {
            chThdSleepMilliseconds(70);
            ledOff();
            chThdSleepMilliseconds(930);
        }

        if (!debug_port_disabled)
        {
            if (sysTimestampMicros() / 1000000 > DEBUG_PORT_DISABLE_DEADLINE_SEC)
            {
#if RELEASE
                debugPortDisable();
#endif
                debug_port_disabled = true;
            }
        }

        watchdogReset(wdid);
    }
    return 0;
}
コード例 #7
0
ファイル: MYSBootloader.c プロジェクト: AlfredSch/Arduino
// main start
int main(void) {	
	
	asm volatile ("clr __zero_reg__");
	// reset MCU status register	
	MCUSR = 0;
	
	// enable watchdog to avoid deadlock
	watchdogConfig(WATCHDOG_8S);

	// initialize SPI
	SPIinit();
		
	// initialize RF module	
	RFinit();

	// Read node config from EEPROM, i.e. nodeId, parent nodeId, distance
	eeprom_read_block((void*)&nc, (void*)EEPROM_NODE_ID_ADDRESS, sizeof(struct NodeConfig));
	// Read firmware config from EEPROM, i.e. type, version, CRC, blocks
	eeprom_read_block((void*)&fc, (void*)EEPROM_FIRMWARE_TYPE_ADDRESS, sizeof(NodeFirmwareConfig));
	
	// find nearest node during reboot: invalidate parent node settings, since we have to re-discover them for every single reboot
	configuredParentID = nc.parentNodeId;
	// nc.parentNodeId = 0xFF;
	nc.distance = 0xFF;
	
	// prepare for I_FIND_PARENTS
	outMsg.sender = nc.nodeId;
	outMsg.last = nc.nodeId;
	outMsg.sensor = 0xFF;
	outMsg.destination = BROADCAST_ADDRESS;
	
	// set header
	mSetVersion(outMsg, PROTOCOL_VERSION);
	mSetLength(outMsg, 0);
	mSetCommand(outMsg, C_INTERNAL);
	mSetAck(outMsg,false);
	mSetPayloadType(outMsg, P_STRING);
	
	// set reading & writing pipe address
	setAddress(nc.nodeId);

	// network up? get neighbors, else startup
	if (!sendAndWait(I_FIND_PARENT, I_FIND_PARENT_RESPONSE)) {
		startup();
	}
	
	// all messages to gateway
	outMsg.destination = GATEWAY_ADDRESS;
	
	// if no node id assigned, request new id
	if (nc.nodeId == AUTO) {
		// listen to broadcast
		openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(BROADCAST_ADDRESS));
		if (sendAndWait(I_ID_REQUEST, I_ID_RESPONSE)) {
			// save id to eeprom
			eeprom_update_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, atoi(inMsg.data));
		}
		// we could go on and set everything right here, but rebooting will take care of that - and saves some bytes :)
		reboot();				
	}
	
	// wuff
	watchdogReset();
	// prepare for FW config request
	RequestFirmwareConfig *reqFWConfig = (RequestFirmwareConfig *)outMsg.data;	
	mSetLength(outMsg, sizeof(RequestFirmwareConfig));
	mSetCommand(outMsg, C_STREAM);
	mSetPayloadType(outMsg,P_CUSTOM);
	// copy node settings to reqFWConfig
	memcpy(reqFWConfig,&fc,sizeof(NodeFirmwareConfig));
	// add bootloader information
	reqFWConfig->BLVersion = MYSBOOTLOADER_VERSION;
	
	// send node config and request FW config from controller
	if (!sendAndWait(ST_FIRMWARE_CONFIG_REQUEST, ST_FIRMWARE_CONFIG_RESPONSE)) {
		startup();
	}
	
	NodeFirmwareConfig *firmwareConfigResponse = (NodeFirmwareConfig *)inMsg.data;
	
	// bootloader commands
	if (firmwareConfigResponse->blocks == 0) {
		// verify flag
		if (firmwareConfigResponse->crc == 0xDA7A){
			// cmd 0x01 clear eeprom
			if(firmwareConfigResponse->bl_command == 0x01) {
				for(uint16_t i = 0; i < EEPROM_SIZE; i++) eeprom_update_byte((uint8_t *)i,0xFF);
			} else 
			// cmd 0x02 set id
			if(firmwareConfigResponse->bl_command == 0x02) {
				eeprom_update_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, (uint8_t)firmwareConfigResponse->bl_data);
			}
		}
		// final step
		reboot();
	}
	
	// compare with current node configuration, if equal startup
	if (!memcmp(&fc,firmwareConfigResponse,sizeof(NodeFirmwareConfig))) {
		startup();
	}
	
	// *********** from here on we will fetch new FW
	
	// invalidate current CRC
	fc.crc = 0xFFFF;
	// write fetched type and version in case OTA fails (BL will reboot and re-request FW with stored settings)
	eeprom_update_block(&fc, (void*)EEPROM_FIRMWARE_TYPE_ADDRESS,sizeof(NodeFirmwareConfig));
	
	// copy new FW config
	memcpy(&fc,firmwareConfigResponse,sizeof(NodeFirmwareConfig));
	RequestFWBlock *firmwareRequest = (RequestFWBlock *)outMsg.data;
	mSetLength(outMsg, sizeof(RequestFWBlock));
	
	firmwareRequest->type = fc.type;
	firmwareRequest->version = fc.version;
	
	// request FW from controller, load FW counting backwards
	uint16_t block = fc.blocks;
	do {
		firmwareRequest->block = block - 1;
		
		// request FW block
		if (!sendAndWait(ST_FIRMWARE_REQUEST, ST_FIRMWARE_RESPONSE)) {
			reboot();
		}
		
		ReplyFWBlock *firmwareResponse = (ReplyFWBlock *)inMsg.data;
		
		// did we receive requested block?
		if (!memcmp(firmwareRequest,firmwareResponse,sizeof(RequestFWBlock))) {
			// calculate page offset
			uint8_t offset = ((block - 1) * FIRMWARE_BLOCK_SIZE) % SPM_PAGESIZE;
			// write to buffer
			memcpy(progBuf + offset, firmwareResponse->data, FIRMWARE_BLOCK_SIZE);
			// program if page full
			if (offset == 0) {
				programPage(((block - 1) * FIRMWARE_BLOCK_SIZE), progBuf);
			}
			block--;	
		}	
	} while (block);
	
	// wuff
	watchdogReset();
	
	// all blocks transmitted, calc CRC and write to eeprom if valid	
	if (IsFirmwareValid()) {
		// if FW is valid, write settings to eeprom 
		eeprom_update_block(&fc, (void*)EEPROM_FIRMWARE_TYPE_ADDRESS, sizeof(NodeFirmwareConfig));
	} 
	// final step
	reboot();
}
コード例 #8
0
ファイル: motor.c プロジェクト: branux/sapog
static void control_thread(void* arg)
{
	(void)arg;
	chRegSetThreadName("motor");

	event_listener_t listener;
	chEvtRegisterMask(&_setpoint_update_event, &listener, ALL_EVENTS);

	uint64_t timestamp_hnsec = motor_rtctl_timestamp_hnsec();

	while (1) {
		/*
		 * Control loop period adapts to comm period.
		 */
		const uint32_t comm_period = motor_rtctl_get_comm_period_hnsec();

		unsigned control_period_ms = IDLE_CONTROL_PERIOD_MSEC;
		if (comm_period > 0) {
			control_period_ms = comm_period / HNSEC_PER_MSEC;
		}

		if (control_period_ms < 1) {
			control_period_ms = 1;
		} else if (control_period_ms > IDLE_CONTROL_PERIOD_MSEC) {
			control_period_ms = IDLE_CONTROL_PERIOD_MSEC;
		}

		/*
		 * Thread priority - maximum if the motor is running, normal otherwise
		 */
		const tprio_t desired_thread_priority = (comm_period > 0) ? HIGHPRIO : NORMALPRIO;

		if (desired_thread_priority != chThdGetPriorityX()) {
			const tprio_t old = chThdSetPriority(desired_thread_priority);
			printf("Motor: Priority changed: %i --> %i\n", (int)old, (int)desired_thread_priority);
		}

		/*
		 * The event must be set only when the mutex is unlocked.
		 * Otherwise this thread will take control, stumble upon the locked mutex, return the control
		 * to the thread that holds the mutex, unlock the mutex, then proceed.
		 */
		chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(control_period_ms));

		chMtxLock(&_mutex);

		const uint64_t new_timestamp_hnsec = motor_rtctl_timestamp_hnsec();
		const uint32_t dt_hnsec = new_timestamp_hnsec - timestamp_hnsec;
		const float dt = dt_hnsec / (float)HNSEC_PER_SEC;
		timestamp_hnsec = new_timestamp_hnsec;

		assert(dt > 0);

		update_filters(dt);
		update_setpoint_ttl(dt_hnsec / HNSEC_PER_MSEC);
		update_control(comm_period, dt);

		poll_beep();

		chMtxUnlock(&_mutex);

		watchdogReset(_watchdog_id);
	}

	abort();
}