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; }
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; }
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"); }
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; } }
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; }