Example #1
0
uint16_t mem_write(uint16_t id, uint16_t offset, const void *buf, uint16_t count) {
#if 0
	debug_puts("Writing to ");
	debug_puthex(id+offset);
	debug_nl();
	print_buf(buf, count);
	debug_nl();
#endif
	spi_mem_write(id+offset, buf, count);
	return count;
}
Example #2
0
uint16_t mem_read(uint16_t id, uint16_t offset, void *buf, uint16_t count) {
	spi_mem_read(id+offset, buf, count);
#if 0
	debug_puts("Read from ");
	debug_puthex(id+offset);
	debug_nl();
	print_buf(buf, count);
	debug_nl();
#endif

	return count;
}
uint8_t BT::init(void)
{
	_delay_ms(100);
	present = true;
	debug(STR("BT Init\n\r"));

//	sendCMD(STR("ATRST\r")); // Reset module
//	_delay_ms(200);

	while(read()); // Flush buffer

	sendCMD(STR("AT\r")); // Check connection

	debug(STR("Data: "));
	debug(data);
	debug_nl();

	if(checkOK() == 0)
	{
		present = false;
		return 0;
	}

	sendCMD(STR("ATSDBLE,0,0\r")); // Default to Idle (don't advertise)

	if(checkOK() == 0)
		return 0;

	sendCMD(STR("ATSN,Timelapse+\r")); // Set Name

	if(checkOK() == 0)
		return 0;

	sendCMD(STR("ATSZ,1,1,0\r")); // Configure Sleep mode (sleep on reset, wake on UART)

	if(checkOK() == 0)
		return 0;

	sendCMD(STR("ATSDIF,782,1,1\r")); // Configure discovery display

	if(checkOK() == 0)
		return 0;

	sendCMD(STR("ATFC\r")); // Save configuration

	if(checkOK() == 0)
		return 0;

	debug(STR("BT Init: Saved configuration\r\n"));

	state = BT_ST_IDLE;
	mode = BT_MODE_CMD;

	devices = 0;
	newDevices = 0;

//	updateVersion();

	return power(3);
}
uint8_t BT::sendDATA(uint8_t id, uint8_t type, void* buffer, uint16_t bytes)
{
	if(!present)
		return 1;

	debug(PSTR("Sending: "));
	debug(id);
	debug(PSTR(", "));
	debug(type);
	debug(PSTR(", "));
	debug(bytes);
	debug_nl();
	if(dataMode())
	{
		waitRTS();
		if(BT_RTS)
		{
			char* byte;

			char s1 = (char)(bytes & 0xff);
			char s2 = (char)((bytes >> 8) & 0xff);

			if(waitRTS()) return 1;
			Serial_SendByte('$');
			if(waitRTS()) return 1;
			Serial_SendByte((char) id);
			if(waitRTS()) return 1;
			Serial_SendByte((char) type);
			if(waitRTS()) return 1;
			Serial_SendByte((char) s1);
			if(waitRTS()) return 1;
			Serial_SendByte((char) s2);
			if(waitRTS()) return 1;
			Serial_SendByte(':');

			byte = (char *) buffer;
			if(bytes > 0)
			{
				while(bytes--)
				{
					if(waitRTS()) break;
					Serial_SendByte(*byte);
					byte++;
					wdt_reset();
				}
			}
			return 1;
		}
		else
		{
			debug(PSTR("BT RTS Failed!\r\n"));
		}
	}
uint8_t BT::sendDATA(uint8_t id, uint8_t type, void* buffer, uint16_t bytes)
{
	if(!present)
		return 1;

	debug(STR("Sending: "));
	debug(id);
	debug(STR(", "));
	debug(type);
	debug_nl();
	if(dataMode())
	{
		waitRTS();
		if(BT_RTS)
		{
			char* byte;

			if(waitRTS()) return 1;
			Serial_SendByte('$');
			if(waitRTS()) return 1;
			Serial_SendByte((char) id);
			if(waitRTS()) return 1;
			Serial_SendByte((char) type);
			if(waitRTS()) return 1;
			Serial_SendByte((char) *(&bytes));
			if(waitRTS()) return 1;
			Serial_SendByte((char) *(&bytes + 1));
			if(waitRTS()) return 1;
			Serial_SendByte(':');

			byte = (char *) buffer;
			if(bytes > 0)
			{
				while(bytes--)
				{
					if(waitRTS()) break;
					Serial_SendByte(*byte);
					byte++;
				}
			}
			return 1;
		}
		else
		{
			debug(STR("BT RTS Failed!\r\n"));
		}
	}

	return 0;
}
Example #6
0
void delay_us(unsigned count){
    unsigned startTime=ReadCoreTimer();
    unsigned endTime= startTime + (count* SYS_FREQ/1E6);
    if(endTime>UINT_MAX-100)// margin for safety. we don't want to wait a whole round
        endTime=0;
    debug_str("delay from ");
    debug_int_hex_16bit(startTime>>16);
    debug_int_hex_16bit(startTime>>00);
    debug_str("\r\nuntil      ");
    debug_int_hex_16bit(endTime>>16);
    debug_int_hex_16bit(endTime>>00);
    debug_nl();
    unsigned time;
    while((time=ReadCoreTimer())<endTime || (time>startTime && endTime<startTime) )//the second check is because the coreTimer regularly overflows
    {
        int c;
         for(c=0; c<10; c++)
            Nop();
    }
    debug_str(" done \r\n");

}
Example #7
0
char shutter::run()
{
	char cancel = 0;
	static uint8_t enter, photos, exps, run_state = RUN_DELAY, old_state = 255;    
	static uint32_t last_photo_ms;

	if(MIRROR_IS_DOWN)
	{
		CHECK_CABLE;
	}
	if(!running)
	{
	if(enter) cancel = 1; else return 0;
	}

	uint16_t value;

	if(enter == 0) // Initialize variables and setup I/O pins
	{
		enter = 1;
		run_state = RUN_DELAY;
		clock.tare();
		photos = 0;
		exps = 0;
		
		ENABLE_MIRROR;
		ENABLE_SHUTTER;
		MIRROR_DOWN;
		SHUTTER_CLOSE;
	}	

	/////// RUNNING PROCEDURE ///////
	if(run_state == RUN_DELAY)
	{
		#ifdef DEBUG
		if(old_state != run_state)
		{
			if(conf.devMode)
			{
				debug("State: RUN_DELAY");
				debug_nl();
			}
			old_state = run_state;
		}
		#endif

		if(((unsigned long) clock.event_ms / 1000) > current.Delay)
		{
			clock.tare();
			clock.reset();
			last_photo_ms = 0;
			run_state = RUN_PHOTO;
		}
		else
		{
			if(((unsigned long) clock.event_ms / 1000) + settings_mirror_up_time >= current.Delay)
			{
	    		// Mirror Up //
				half();
			}	
			if((settings_warn_time > 0) && (((unsigned long) clock.event_ms / 1000) + settings_warn_time >= current.Delay))
			{
	    		// Flash Light //
				_delay_ms(50);
			}	
		}
	}
	if(run_state == RUN_PHOTO)
	{
		#ifdef DEBUG
		if(old_state != run_state)
		{
			if(conf.devMode)
			{
				debug("State: RUN_PHOTO");
				debug_nl();
			}
			old_state = run_state;
		}
		#endif

		if(current.Exp > 0 || (current.Mode & RAMP))
		{
			clock.tare();
			run_state = RUN_BULB;
		}
		else
		{
			exps++;
	 		bulb = false;
			full();
			_delay_ms(50);
			off();
			_delay_ms(50);
			if(current.Gap <= settings_mirror_up_time) half(); // Mirror Up //
			run_state = RUN_NEXT;
		}
	}
	if(run_state == RUN_BULB)
	{
		#ifdef DEBUG
		if(old_state != run_state)
		{
			if(conf.devMode)
			{
				debug("State: RUN_BULB");
				debug_nl();
			}
			old_state = run_state;
		}
		#endif

		bulb = true;
		full();
		static uint8_t calc = true;
		static uint16_t bulb_length, exp;
		if(calc)
		{
			calc = false;
			exp = current.Exp * 100;
			if(current.Mode & RAMP)
			{
				float key1, key2, key3, key4;
				char found = 0;
				uint8_t i;

				// Bulb ramp algorithm goes here
				for(i = 1; i <= current.Keyframes; i++)
				{
					if(clock.Seconds() <= current.Key[i - 1])
					{
						found = 1;
						key1 = (float) current.Bulb[i > 1 ? i - 2 : i - 1] * 100;
						key2 = (float) current.Bulb[i - 1] * 100;
						key3 = (float) current.Bulb[i] * 100;
						key4 = (float) current.Bulb[i < current.Keyframes ? i + 1 : i] * 100;
						break;
					}
				}
				if(found)
				{
					exp = (uint16_t) curve(key1, key2, key3, key4, ((float)clock.Seconds() - (i > 1 ? (float)current.Key[i - 2] : 0.0) ) / ((float)current.Key[i - 1] - (i > 1 ? (float)current.Key[i - 2] : 0.0)) );
				}
				else
				{
					exp = current.Bulb[current.Keyframes] * 100;
				}
				bulb_length = exp;
				if(conf.devMode)
				{
					debug("Seconds: ");
					debug((uint16_t) clock.Seconds());
					debug_nl();
					debug("Ramp: ");
					debug(bulb_length);
					if(found) debug(" (calculated)");
					debug_nl();
				}
			}
			if(current.Mode & HDR)
			{
				uint16_t tmp = exps - (current.Exps >> 1); 
				bulb_length = (tmp < 32768) ? exp * (1 << tmp) : exp / (1 << (0 - tmp));

				if(conf.devMode)
				{
					debug("exps - (current.Exps >> 1): ");
					if(tmp < 32768)
					{
						debug(tmp);
					}
					else
					{
						debug("-");
						debug(0 - tmp);
					}
					debug_nl();
					debug("Bulb: ");
					debug(bulb_length);
					debug_nl();
				}
			}
			if((current.Mode & (HDR | RAMP)) == 0)
			{
				if(conf.devMode)
				{
					debug("***Using exp");
					debug_nl();
				}
				bulb_length = exp;
			}
		}
		if(((unsigned long) clock.eventMs()) >= bulb_length )
		{
			calc = true;
			exps++;
			off();
			_delay_ms(50);
			if(current.Gap <= settings_mirror_up_time) half(); // Mirror Up //
			run_state = RUN_NEXT;
		}
	}
Example #8
0
void handle_icmp(uint8_t *macSource, uint8_t *sourceAddr, uint8_t *destIPAddr,
		uint16_t length, DATA_CB dataCb, void *priv) {
	/**
	 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 |     Type      |     Code      |          Checksum             |
	 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 |                                                               |
	 +                         Message Body                          +
	 |                                                               |
	 */

	/* Allocate just enough data to handle the type, code, and checksum fields */
	uint8_t buf[4];
	uint8_t type;
	CHECK_SP("handle_icmp: ");
#ifdef DEBUG_ICMP
	PRINT_SP("handle_icmp: ");
#endif

	dataCb(buf, 4, priv);

	type = buf[0];

#ifdef DEBUG_ICMP
	debug_puts("Payload size: ");
	debug_puthex(length);
	debug_nl();
	debug_puts("ICMP Type:");
	debug_puthex(type);
	debug_nl();
#endif

	/*calc_checksum(payload, 4);

	 uint16_t r = dataCb(payload, length - 4, priv);

	 calc_checksum(payload, length - 4);

	 if (checksum != 0xFFFF) {
	 debug_puts("Checksum error");
	 debug_nl();
	 return;
	 }*/

	if (net_state != STATE_IDLE && type != ICMP_TYPE_NEIGHBOR_SOLICITATION
			&& type != ICMP_TYPE_NEIGHBOR_ADVERTISMENT) {
		debug_puts("Not in a state to receive ICMP message");
		debug_nl();
		return;
	}

	switch (type) {
	case ICMP_TYPE_NEIGHBOR_SOLICITATION:
		/* First 4 bytes are 'reserved', we ignore them. but must read them */
		dataCb(buf, 4, priv);

		/* Next 16 bytes are the target address. We assume it's one of our addresses as it was passed to us
		 by handle_ipv6()
		 */

		/* We only reply if there is a source link-layer address option */
		if (length > 20) {
			uint8_t addr[16];

			/* Read address*/
			dataCb(addr, 16, priv);

			/* Read option 'header' */
			dataCb(buf, 2, priv);
			if (buf[0] == 0x01) {
				uint8_t mac_addr[6];

				dataCb(mac_addr, 6, priv);
				/* We now got the link-layer address and IPv6 address of someone, store it */
				register_mac_addr(mac_addr, sourceAddr);
				send_neighbor_advertisment(mac_addr, addr, sourceAddr, addr);
			}
		}
		break;
	case ICMP_TYPE_NEIGHBOR_ADVERTISMENT: {
		/* We ignore first 4 bytes */
		uint8_t received_addr[16];
		dataCb(buf, 4, priv);
		dataCb(received_addr, 16, priv);
		if (net_state == STATE_DAD) {
			uint8_t addr[16];

			net_get_address(ADDRESS_STORE_LINK_LOCAL_OFFSET, addr);
			if (memcmp(received_addr, addr, 16) == 0) {
				net_state = STATE_INVALID;
				return;
			}
		}

		register_mac_addr(macSource, received_addr);
		net_state = STATE_IDLE;
	}
		break;
	case ICMP_TYPE_ECHO_REQUEST:
		if (length >= 8) {
			dataCb(buf, 4, priv);
			uint16_t id = (buf[0] << 8) | buf[1];
			uint16_t seqNo = (buf[2] << 8) | buf[3];
			struct ipv6_packet_arg arg;
			arg.dst_mac_addr = null_mac;
			arg.dst_ipv6_addr = sourceAddr;
			arg.src_ipv6_addr = destIPAddr;
			//arg.payload_length = SIZE_ICMP_HEADER + length;
			arg.protocol = PROTO_ICMP;

			net_start_ipv6_packet(&arg);
			net_send_icmp_start(ICMP_TYPE_ECHO_REPLY, 0);
			net_send_data(buf, 4);
			calc_checksum(buf, 4);
			uint16_t count;
			length -= 8;
			while( (count=dataCb(buf, 4, priv)) > 0 && length > 0) {
				net_send_data(buf, count);
				calc_checksum(buf, count);
			}
			//net_send_icmp(ICMP_TYPE_ECHO_REPLY, 0, payload, length);
			net_end_ipv6_packet();
		}
		break;
	case ICMP_TYPE_ROUTER_ADVERTISMENT:
		/* Ignore first 12 bytes, as we are only interested in
		 addresses. Next, loop through the options in the payload
		 */
	{
		if( length > 140 ) {
			debug_puts("Lengths exceeds 140 Bytes, ignore router advertisment in order to avoid trouble");
			debug_nl();
			return;
		}
		uint8_t payload[length-4];
		CHECK_SP("handle_icmp, ICMP_TYPE_ROUTER_ADVERTISMENT: ");
		dataCb(payload, length-4, priv);
		uint8_t *c = payload + 12;
		while (c < payload + length - 4) {
			if (c[0] == 3) {
				uint8_t prefixLength = c[2];
				/* Prefix starts at offset 16 */
				uint8_t buf[16];
				net_get_address(ADDRESS_STORE_MAIN_OFFSET, buf);
				if (buf[0] == 0x00) {
					// null_mac as destination means link-local (go figure)
					routing_table_add(c + 16, prefixLength / 8, null_mac);

					// Default route
					routing_table_add(unspec_addr, 0, macSource);
					assign_address_from_prefix(c + 16, prefixLength);
					//mem_write(default_route_mac_id, 0, macSource, 6);
				} else {

				}
			}
			c += c[1] * 8;
		}
	}
		break;
	}
}
uint8_t BT::task(void)
{
	if(!present)
		return 1;

	uint8_t pos = 0, len, ret = BT_EVENT_NULL;

	len = read();

	if(len)
	{
		if(mode == BT_MODE_CMD) debug(STR("CMD:\r\n")); else debug(STR("DATA:\r\n"));
		debug(buf);
		debug_nl();
		if(mode == BT_MODE_CMD)
		{
			if(strncmp(buf, STR("DISCOVERY"), 9) == 0)
			{
				if(*(buf + 10) == '6' && newDevices < BT_MAX_SCAN)
				{
					ret = BT_EVENT_DISCOVERY;
					uint8_t i;
					for(i = 0; i < BT_ADDR_LEN; i++)
					{
						device[newDevices].addr[i] = *(buf + 12 + i);
					}
					device[newDevices].addr[BT_ADDR_LEN - 1] = '\0';
					for(i = 0; i < BT_NAME_LEN; i++)
					{
						if(*(buf + 38 + i) == '\r') break;
						device[newDevices].name[i] = *(buf + 38 + i);
					}
					device[newDevices].name[i] = '\0';
					newDevices++;
					if(newDevices > devices) devices = newDevices;
				}
			}
			if(strncmp(buf, STR("CONNECT"), 7) == 0)
			{
				if(state == BT_ST_SCAN) cancelScan();
				//ret = BT_EVENT_CONNECT;
				devices = 0;
				state = BT_ST_CONNECTED;
			}
			if(strncmp(buf, STR("BRSP"), 4) == 0)
			{
				ret = BT_EVENT_CONNECT;
				mode = BT_MODE_DATA;
				state = BT_ST_CONNECTED;
			}
			if(strncmp(buf, STR("DISCONNECT"), 10) == 0)
			{
				ret = BT_EVENT_DISCONNECT;
				mode = BT_MODE_CMD;
				state = BT_ST_IDLE;
			}
			if(strncmp(buf, STR("DONE"), 4) == 0)
			{
				ret = BT_EVENT_SCAN_COMPLETE;
				devices = newDevices;
			}
		}
		else
		{
			while(*(buf + pos) == '\r' || *(buf + pos) == '\n') // strip any leftover whitespace
			{
				pos++;
			}			
			if(strncmp(buf + pos, STR("DISCONNECT"), 10) == 0)
			{
				ret = BT_EVENT_DISCONNECT;
				mode = BT_MODE_CMD;
				state = BT_ST_IDLE;
			}
			else if(dataId > 0)
			{
				debug(STR("Received Packet: "));
				debug(dataId);
				debug(STR(" ("));
				debug(dataSize);
				debug(STR(" bytes)\r\n"));
				ret = BT_EVENT_DATA;
			}
		}
	}
	event = ret;
	return ret;
}