Exemple #1
0
void 
Waypoints::set_waypoint_with_index(Waypoints::WP wp, uint8_t i)
{
	i = constrain(i, 0, _total);
	uint32_t mem = _start_byte + (i * _wp_size);

	eeprom_busy_wait();
	eeprom_write_byte((uint8_t *) mem, wp.id);

	mem++;
	eeprom_busy_wait();
	eeprom_write_byte((uint8_t *) mem, wp.p1);

	mem++;
	eeprom_busy_wait();
	eeprom_write_dword((uint32_t *) mem, wp.alt);

	mem += 4;
	eeprom_busy_wait();
	eeprom_write_dword((uint32_t *) mem, wp.lat);

	mem += 4;
	eeprom_busy_wait();
	eeprom_write_dword((uint32_t *) mem, wp.lng);
}
void init_lifetime_stats()
{
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 0), LIFETIME_MAGIC);
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 4), 0);
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 8), 0);
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 12), 0);
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 16), 0);
}
static void save_lifetime_stats()
{
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 0), LIFETIME_MAGIC);
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 4), lifetime_minutes);
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 8), lifetime_print_minutes);
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 12), triptime_minutes);
    eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 16), triptime_print_minutes);
}
Exemple #4
0
void heater_save_settings() {
	#ifndef BANG_BANG
		heater_t i;
		for (i = 0; i < NUM_HEATERS; i++) {
			eeprom_write_dword((uint32_t *) &EE_factors[i].EE_p_factor, heaters_pid[i].p_factor);
			eeprom_write_dword((uint32_t *) &EE_factors[i].EE_i_factor, heaters_pid[i].i_factor);
			eeprom_write_dword((uint32_t *) &EE_factors[i].EE_d_factor, heaters_pid[i].d_factor);
			eeprom_write_word((uint16_t *) &EE_factors[i].EE_i_limit, heaters_pid[i].i_limit);
		}
	#endif /* BANG_BANG */
}
Exemple #5
0
void zoSmsRestoreDefaults(void)
{
	eeprom_write_byte((u08*)ZO_EEPROM_ADDRESS_NODE_ID, ZO_DEFAULT_NODE_ID);
	eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_GAIN_P, ZO_DEFAULT_GAIN_P);
	eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_GAIN_I, ZO_DEFAULT_GAIN_I);
	eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_GAIN_D, ZO_DEFAULT_GAIN_D);
	eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_CURRENT_LIMIT, ZO_DEFAULT_CURRENT_LIMIT);
	eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_CURRENT_LIMIT_DURATION, ZO_DEFAULT_CURRENT_LIMIT_DURATION);
	eeprom_write_byte((u08*)ZO_EEPROM_ADDRESS_DIGITAL_IO_CONFIG, ZO_DEFAULT_DIGITAL_IO_CONFIG);
	eeprom_write_dword((u32*)ZO_EEPROM_ADDRESS_BAUD_UART, ZO_DEFAULT_BAUD_UART);
	eeprom_write_dword((u32*)ZO_EEPROM_ADDRESS_BAUD_I2C, ZO_DEFAULT_BAUD_I2C);
	eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_PROFILE_ACCELERATION, ZO_DEFAULT_PROFILE_ACCELERATION);
	eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_PROFILE_VELOCITY, ZO_DEFAULT_PROFILE_VELOCITY);
	eeprom_write_byte((u08*)ZO_EEPROM_ADDRESS_LAM, ZO_DEFAULT_LAM);
	eeprom_write_byte((u08*)ZO_EEPROM_ADDRESS_ERROR_REPORTING_LVL, ZO_DEFAULT_ERROR_REPORTING_LVL);
}
Exemple #6
0
bool import_bank(const uint8_t bank, const char* data)
{
    // Abort if the supplied string is too short
    if (strlen(data) < 8*PROGRAMS_PER_BANK) {
        return false;
    }

    // Abort if the bank index is too big
    if (bank > 11) {
        return false;
    }

    uint8_t offset = bank * PROGRAMS_PER_BANK;
    char* hex_dword = "        ";

    // Store programs
    for (uint8_t i=0; i < PROGRAMS_PER_BANK; ++i) {
        strncpy(hex_dword, data, 8);
        eeprom_write_dword(&program_data_storage[offset+i], strtoul(hex_dword, NULL, 16));
        data += 8;
        wdt_reset();
    }

    return true;
}
Exemple #7
0
/**
 * Write a single 32 bits integer
 */
bool Eeprom::writeLong(int address, uint32_t value)
{
    if (!isWriteOk(address + sizeof(uint32_t)))
        return false;

    eeprom_write_dword((unsigned long *) address, value);
    return true;
}
Exemple #8
0
void seed_rand()
{
	uint32_t next_seed = eeprom_read_dword( (uint32_t*)SEED_ADDR );
	
	srandom( next_seed );
	
	eeprom_write_dword( (uint32_t*)SEED_ADDR, random() );
}
Exemple #9
0
// save a fence point
void AP_Limit_Geofence::set_fence_point_with_index(Vector2l &point, uint8_t i)
{
    uint32_t mem;

    if (i >= (unsigned)fence_total()) {
        // not allowed
        return;
    }

    mem = _eeprom_fence_start + (i * _fence_wp_size);

    eeprom_write_dword((uint32_t *)mem, point.x);
    mem += sizeof(uint32_t);
    eeprom_write_dword((uint32_t *)mem, point.y);

    _boundary_uptodate = false;
}
Exemple #10
0
static void test_overflow_into_4th_byte() {
  test("test_overflow_into_4th_byte");
  uint32_t *memory = (uint32_t *)108;

  eeprom_write_dword(memory, 0x00FFFFFF);
  uint32_t result = increment_eeprom_uint32(memory);
  assert(result == 0x01000000);
  assert(eeprom_read_dword(memory) == 0x01000000);
}
Exemple #11
0
static void test_byte_overflow() {
  test("test_byte_overflow");
  uint32_t *memory = (uint32_t *)104;

  eeprom_write_dword(memory, 0xFF);
  uint32_t result = increment_eeprom_uint32(memory);
  assert(result == 0x100);
  assert(eeprom_read_dword(memory) == 0x100);
}
Exemple #12
0
static void test_simple_increment() {
  test("test_simple_increment");
  uint32_t *memory = (uint32_t *)100;

  eeprom_write_dword(memory, 1);
  uint32_t result = increment_eeprom_uint32(memory);
  assert(result == 2);
  assert(eeprom_read_dword(memory) == 2);
}
void inline eeprom_write_float(float* addr, float f)
{
    union {
        uint32_t i;
        float f;
    } n;
    n.f = f;
    eeprom_write_dword((uint32_t*)addr, n.i);
}
Exemple #14
0
static void test_rollover_to_zero() {
  test("test_rollover_to_zero");
  uint32_t *memory = (uint32_t *)112;

  eeprom_write_dword(memory, 0xFFFFFFFF);
  eeprom_write_byte((uint8_t *)memory + 4, 0xa5);
  uint32_t result = increment_eeprom_uint32(memory);
  assert(result == 0x00000000);
  assert(eeprom_read_dword(memory) == 0x00000000);
  assert(eeprom_read_byte((uint8_t *)memory + 4) == 0xa5);
}
Exemple #15
0
static void do_serialnumber(int direction, unsigned int vWalue)
{
	uint32_t snum;

	if (direction == ENDPOINT_DIR_OUT) {
		Endpoint_Read_Control_Stream_LE(&snum, sizeof(snum));
		eeprom_write_dword(&serialno, snum);
	} else if (direction == ENDPOINT_DIR_IN) {
		snum = eeprom_read_dword(&serialno);
		Endpoint_Write_Control_Stream_LE(&snum, sizeof(snum));
	}
}
ALWBase::ALWBase() {
  /*
   * XXX: For some reason, this messes things up if it runs in init().
   * It must have something to do with the timing: Calling it before
   * Arduino's core init code is okay, but after is not. Bizarre.
   * One thread suggested it's the WDT, but I don't think so.
   */
  static uint32_t EEMEM storedRandomSeed;
  uint32_t randomSeed = eeprom_read_dword(&storedRandomSeed);
  srandom(randomSeed);
  eeprom_write_dword(&storedRandomSeed, random());
}
Exemple #17
0
/* setSerialEEPROM() - sets the Waspmote unique serial identifier to EEPROM
 *
 * The serial id to be stored is specified as input
 */
bool WaspUtils::setSerialEEPROM( unsigned long serial )
{		
	// Store to EEPROM
	eeprom_write_dword( (uint32_t*)EEPROM_SERIALID_START, serial );
	
	// check EEPROM
	if( serial == getSerialEEPROM() )
	{		
		return true;
	}
	
	return false;
}
Exemple #18
0
uint32_t get_seed(uint32_t* eeprom_begin, uint32_t* eeprom_end)
{
  uint32_t* ptr;
  uint32_t seed = eeprom_read_dword(eeprom_begin);

  for (ptr=eeprom_begin+1; ptr<eeprom_end; ++ptr)
    if (++seed != eeprom_read_dword(ptr)) break;

  if (ptr >= eeprom_end) ptr = eeprom_begin;

  eeprom_write_dword(ptr, seed);

  if (seed == 0) seed = 0xaaaaaaaa;

  return seed;
}
Exemple #19
0
const char PROGMEM *settingsLineSetNotifyValue(char *buf, uint16_t len, uint8_t index) {
    if (index > 3) {
        return TOO_MANY_NOTIFY;
    }
    if (currentSetLineIdx >= lineInputSize){
        return NO_NOTIFY_OUTPUT;
    }
    float value = atof(buf);
    uint8_t type = pgm_read_byte(&lineInputDescription[currentSetLineIdx].type);
    LineInputConversion conversion = (LineInputConversion) pgm_read_word(&(lineInputDescription[currentSetLineIdx].convertValue));
    if (value > conversion(type == ANALOG ? 1023 : 1) || value < conversion(0)) {
        return PSTR("notify value overflow");
    }
    eeprom_write_dword((uint32_t *) &lineInputSettings[currentSetLineIdx].notifies[index].value, *((unsigned long *)&value));
    return 0;
}
Exemple #20
0
void send_dimmer_status(void)
{
	UART_PUTS("Sending Dimmer Status:\r\n");

	// set device ID
	bufx[0] = device_id;
	
	// update packet counter
	packetcounter++;
	
	if (packetcounter % PACKET_COUNTER_WRITE_CYCLE == 0)
	{
		eeprom_write_dword((uint32_t*)0, packetcounter);
	}

	setBuf32(1, packetcounter);

	// set command ID "Dimmer Status"
	bufx[5] = 30; // TODO: Move command IDs to global definition file as defines

	// set current brightness
	bufx[6] = (uint8_t)(current_brightness * 255 / 100);
	
	// set end brightness
	bufx[7] = end_brightness;
	
	// set total animation time
	setBuf16(8, (uint16_t)(animation_length * ANIMATION_CYCLE_MS / 1000));

	// set time until animation finishes
	setBuf16(10, (uint16_t)((animation_length - animation_position) * ANIMATION_CYCLE_MS / 1000));

	// set CRC32
	uint32_t crc = crc32(bufx, 12);
	setBuf32(12, crc);

	// show info
	UART_PUTF("CRC32: %lx\r\n", crc);
	uart_putstr("Unencrypted: ");
	printbytearray(bufx, 16);

	rfm12_sendbuf();
	
	UART_PUTS("Send encrypted: ");
	printbytearray(bufx, 16);
	UART_PUTS("\r\n");
}
int main()
{
  stdout = &mystdout;

  // read the eeprom value
  uint32_t c = eeprom_read_dword((void*)&value);
  printf("Read from eeprom 0x%08lx -- should be 0xdeadbeef\n", c);
  // change the eeprom
  eeprom_write_dword((void*)&value, 0xcafef00d);
  // re-read it
  c = eeprom_read_dword((void*)&value);
  printf("Read from eeprom 0x%08lx -- should be 0xcafef00d\n", c);

  // this quits the simulator, since interupts are off
  // this is a "feature" that allows running tests cases and exit
  sleep_cpu();
}
Exemple #22
0
void send_packet(uint8_t aes_key_nr, uint8_t data_len)
{
	// set device ID (base station has ID 0 by definition)
	bufx[0] = 0;

	// update packet counter
	packetcounter++;
	
	if (packetcounter % PACKET_COUNTER_WRITE_CYCLE == 0)
	{
		eeprom_write_dword((uint32_t*)0, packetcounter);
	}

	setBuf32(1, packetcounter);

	// set CRC32
	uint32_t crc = crc32(bufx, data_len + 6);
	setBuf32(data_len + 6, crc);

	// load AES key (0 is first AES key)
	if (aes_key_nr >= AES_KEY_EEPROM_COUNT)
	{
		aes_key_nr = AES_KEY_EEPROM_COUNT - 1;
	}
	
	eeprom_read_block (aes_key, (uint8_t *)(EEPROM_POS_AES_KEY + aes_key_nr * 32), 32);
	
	// show info
	decode_data(data_len + 6);
	UART_PUTF("       AES key: %u\r\n", aes_key_nr);
	
	UART_PUTF("         CRC32: %02lx\r\n", crc);
	UART_PUTS("   Unencrypted: ");
	printbytearray(bufx, data_len + 10);

	// encrypt and send
	uint8_t aes_byte_count = rfm12_sendbuf(data_len + 10);
	
	UART_PUTS("Send encrypted: ");
	printbytearray(bufx, aes_byte_count);

	UART_PUTS("\r\n");
}
Exemple #23
0
int answer_record(char* filename1, char* filename2, char use_beep) // Отвечает, записывает сообщение,
{
	if (answer_play(filename1)) return 1; // Отвечаем, предлагаем оставить сообщение
	if (use_beep) beep(3000, 500);	// Биип
	sprintf(buffer, "/%08lu.wav", record_num); // Формируем имя файла
	clunet_send(CLUNET_BROADCAST_ADDRESS, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_MESSAGE, (char*)&record_num, sizeof(record_num)); // Отправляем в сеть сообщение
	record_num++;
	eeprom_write_dword((void*)0, record_num); // Запоминаем кол-во записей
	if (rec_wav(buffer) == 0) // Пишем сообщение
	{
		int s = 0;
		long int totalSize = 0;
		while (s >= 0 && totalSize < 8000UL*RECORD_MAX_LENGTH)
		{
			s = sound_write();
			totalSize += s;
			if (!LINE_POWER || OFFHOOK) // Сняли трубку, или сигнал исчез
			{
				sound_stop();
				return 1;
			}
		}
		sound_stop();
	}	
	if (play_wav_pgm(filename2) == 0) // Если пациент дождался, благодарим
	{
		while (sound_read() >= 0)
		{
			if (!LINE_POWER || OFFHOOK) // Сняли трубку, или сигнал исчез
			{
				sound_stop();
				return 1;
			}
		}
		sound_stop();
	}
	return 0;
}
Exemple #24
0
void settingsLineOutputSetValue(uint8_t outputIdx, float value) {
    eeprom_write_dword((uint32_t *) &lineOutputSettings[outputIdx].lastValue, *((unsigned long *)&value));
}
Exemple #25
0
int main ( void )
{
	uint8_t aes_key_nr;
	uint8_t loop = 0;
	uint8_t loop2 = 0;
	
	uint8_t data[22];

	sbi(LED_DDR, LED_PIN);

	// delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms...
	_delay_ms(1000);

	request_queue_init();
	
	// read packetcounter, increase by cycle and write back
	packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER) + PACKET_COUNTER_WRITE_CYCLE;
	eeprom_write_dword((uint32_t*)0, packetcounter);

	uart_init(true);
	UART_PUTS ("\r\n");
	UART_PUTS ("Open Home Control Base Station V1.0\r\n");
	UART_PUTS ("(c) 2012 Uwe Freese, www.open-home-control.com\r\n");
	UART_PUTF ("Packet counter: %lu\r\n", packetcounter);
	UART_PUTS ("Waiting for incoming data. Press h for help.\r\n");

	rfm12_init();
	sei();
	
	// ENCODE TEST
	/*
	uint8_t testlen = 64;
	
	eeprom_read_block (aes_key, (uint8_t *)EEPROM_POS_AES_KEY, 32);
	UART_PUTS("Using AES key ");
	printbytearray((uint8_t *)aes_key, 32);
			
	UART_PUTS("Before encryption: ");
	printbytearray(bufx, testlen);
  
	unsigned long crc = crc32(bufx, testlen);
	UART_PUTF("CRC32 is %lx (added as last 4 bytes)\r\n", crc);
	
	UART_PUTS("1\r\n");
	crc = crc32(bufx, testlen - 4);
	UART_PUTS("2\r\n");
	setBuf32(testlen - 4, crc);
	
	UART_PUTS("Before encryption (CRC added): ");
	printbytearray(bufx, testlen);

	UART_PUTS("1\r\n");
	uint8_t aes_byte_count = aes256_encrypt_cbc(bufx, testlen);
	UART_PUTS("2\r\n");
  
	UART_PUTS("After encryption: ");
	printbytearray(bufx, aes_byte_count);
	
	UART_PUTF("String len = %u\r\n", aes_byte_count);
	
	UART_PUTS("1\r\n");
	aes256_decrypt_cbc(bufx, aes_byte_count);
	UART_PUTS("2\r\n");
  
	UART_PUTS("After decryption: ");
	printbytearray(bufx, testlen);
	
	crc = getBuf32(testlen - 4);
	UART_PUTF("CRC32 is %lx (last 4 bytes from decrypted message)\r\n", crc);
	printbytearray(bufx, testlen);
	
	UART_PUTS("After decryption (CRC removed): ");
	printbytearray(bufx, testlen);
	
	UART_PUTF("String len = %u\r\n", testlen);
  
	while(1);
	*/

	while (42)
	{
		if (rfm12_rx_status() == STATUS_COMPLETE)
		{
			uint8_t len = rfm12_rx_len();
			
			if ((len == 0) || (len % 16 != 0))
			{
				UART_PUTF("Received garbage (%u bytes not multiple of 16): ", len);
				printbytearray(bufx, len);
			}
			else // try to decrypt with all keys stored in EEPROM
			{
				uint32_t assumed_crc;
				uint32_t actual_crc;

				for(aes_key_nr = 0; aes_key_nr < AES_KEY_EEPROM_COUNT ; aes_key_nr++)
				{
					//strncpy((char *)bufx, (char *)rfm12_rx_buffer(), len);
					memcpy(bufx, rfm12_rx_buffer(), len);

					/*if (aes_key_nr == 0)
					{
						UART_PUTS("Before decryption: ");
						printbytearray(bufx, len);
					}*/
				
					eeprom_read_block (aes_key, (uint8_t *)(EEPROM_POS_AES_KEY + aes_key_nr * 32), 32);
					//UART_PUTS("Trying AES key ");
					//printbytearray((uint8_t *)aes_key, 32);

					aes256_decrypt_cbc(bufx, len);

					//UART_PUTS("Decrypted bytes: ");
					//printbytearray(bufx, len);

					assumed_crc = getBuf32(len - 4);
					actual_crc = crc32(bufx, len - 4);
					
					//UART_PUTF("Received CRC32 would be %lx\r\n", assumed_crc);
					//UART_PUTF("Re-calculated CRC32 is  %lx\r\n", actual_crc);
					
					if (assumed_crc == actual_crc)
					{
						//UART_PUTS("CRC correct, AES key found!\r\n");
						UART_PUTF("Received (AES key %u): ", aes_key_nr);
						printbytearray(bufx, len - 4);
						
						decode_data(len - 4);
						
						break;
					}
				}
				
				if (assumed_crc != actual_crc)
				{
					UART_PUTS("Received garbage (CRC wrong after decryption).\r\n");
				}
				
				UART_PUTS("\r\n");
			}

			//uart_hexdump((char *)bufcontents, rfm12_rx_len());
			//UART_PUTS("\r\n");

			// tell the implementation that the buffer can be reused for the next data.
			rfm12_rx_clear();
		}

		// send data, if waiting in send buffer
		if (send_data_avail)
		{
			uint8_t i;
			
			uint8_t data_len_raw = strlen(sendbuf) / 2 - 2;
			
			// round data length to 6 + 16 bytes (including padding bytes)
			uint8_t data_len = (((data_len_raw + 9) / 16) + 1) * 16 - 10;
	
			// set aes key nr
			aes_key_nr = hex_to_uint8((uint8_t *)sendbuf, 0);
			
			//UART_PUTF("AES KEY = %u\r\n", aes_key_nr);

			// set command id
			uint8_t command_id = hex_to_uint8((uint8_t *)sendbuf, 2);

			// set data
			for (i = 0; i < data_len_raw; i++)
			{
				data[i] = hex_to_uint8((uint8_t *)sendbuf, 4 + 2 * i);
			}
			
			// set padding bytes
			for (i = data_len_raw; i < data_len; i++)
			{
				data[i] = 0;
			}

			// send status packet immediately (command IDs are less than 128)
			if (command_id < 128)
			{
				// set command id
				bufx[5] = command_id;
				
				// set data
				memcpy(bufx + 6, data, data_len);
				
				send_packet(aes_key_nr, data_len);
			}
			else // enqueue request (don't send immediately)
			{
				if (queue_request(data[0], command_id, aes_key_nr, data + 1))
				{
					UART_PUTS("Adding request to queue.\r\n");
				}
				else
				{
					UART_PUTS("Warning! Request queue full. Packet will not be sent.\r\n");
				}

				print_request_queue();
			}
		
			// clear send text buffer
			send_data_avail = false;

			rfm12_tick();

			led_blink(200, 0, 1);
		}

		// flash LED every second to show the device is alive
		if (loop == 50)
		{
			led_blink(10, 10, 1);
			
			loop = 0;

			if (set_repeat_request(packetcounter + 1)) // if request to repeat was found in queue
			{
				UART_PUTS("Repeating request.\r\n");					
				send_packet(0, 6);
				print_request_queue();
			}
			
			// Auto-send something for debugging purposes...
			if (loop2 == 50)
			{
				//strcpy(sendbuf, "008c0001003d");
				//send_data_avail = true;
				
				loop2 = 0;
			}
			else
			{
				loop2++;
			}
		}
		else
		{
			_delay_ms(20);
		}

		rfm12_tick();

		loop++;
		
		process_rxbuf();
		
		if (uart_timeout > 0)
		{
			uart_timeout--;
			
			if (uart_timeout == 0)
			{
				UART_PUTS("*** UART user timeout. Input was ignored. ***\r\n");
			}
		}
	}
	
	// never called
	// aes256_done(&aes_ctx);
}
Exemple #26
0
inline void epr_set_long(uint pos,long value) {
  eeprom_write_dword((unsigned long*)(EEPROM_OFFSET+pos),value);
}
void ReefAngel_EEPROMClass::write_dword(int address, const uint32_t value)
{
	eeprom_write_dword((uint32_t *) address, (uint32_t) value);
}
Exemple #28
0
int main(void)
{
	uint16_t send_status_timeout = 25;
	uint32_t station_packetcounter;
	uint32_t pos;
	uint8_t button_state = 0;
	uint8_t manual_dim_direction = 0;

	// delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms...
	_delay_ms(1000);

	util_init();
	check_eeprom_compatibility(DEVICE_TYPE_DIMMER);

	osccal_init();
	
	// read packetcounter, increase by cycle and write back
	packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER) + PACKET_COUNTER_WRITE_CYCLE;
	eeprom_write_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER, packetcounter);

	// read device id and write to send buffer
	device_id = eeprom_read_byte((uint8_t*)EEPROM_POS_DEVICE_ID);	
	use_pwm_translation = 1; //eeprom_read_byte((uint8_t*)EEPROM_POS_USE_PWM_TRANSLATION);	
	
	// TODO: read (saved) dimmer state from before the eventual powerloss
	/*for (i = 0; i < SWITCH_COUNT; i++)
	{
		uint16_t u16 = eeprom_read_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2);
		switch_state[i] = (uint8_t)(u16 & 0b1);
		switch_timeout[i] = u16 >> 1;
	}*/
	
	// read last received station packetcounter
	station_packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_STATION_PACKET_COUNTER);

	led_blink(200, 200, 5);

#ifdef UART_DEBUG
	uart_init(false);
	UART_PUTS ("\r\n");
	UART_PUTS ("smarthomatic Dimmer V1.0 (c) 2013 Uwe Freese, www.smarthomatic.org\r\n");
	osccal_info();
	UART_PUTF ("Device ID: %u\r\n", device_id);
	UART_PUTF ("Packet counter: %lu\r\n", packetcounter);
	UART_PUTF ("Use PWM translation table: %u\r\n", use_pwm_translation);
	UART_PUTF ("Last received station packet counter: %u\r\n\r\n", station_packetcounter);
#endif

	// init AES key
	eeprom_read_block (aes_key, (uint8_t *)EEPROM_POS_AES_KEY, 32);

	rfm12_init();
	PWM_init();
	io_init();
	setPWMDutyCycle(0);
	timer0_init();

	// DEMO to measure the voltages of different PWM settings to calculate the pwm_lookup table
	/*while (42)
	{
		uint16_t i;
		
		for (i = 0; i <= 1024; i = i + 100)
		{
			UART_PUTF ("PWM value OCR1A: %u\r\n", i);
			OCR1A = i;
			led_blink(500, 6500, 1);
		}
	}*/
	
	// DEMO 0..100..0%, using the pwm_lookup table and the translation table in EEPROM.
	/*while (42)
	{
		float i;
		
		for (i = 0; i <= 100; i = i + 0.05)
		{
			led_blink(10, 10, 1);
			setPWMDutyCycle(i);
		}
		
		for (i = 99.95; i > 0; i = i - 0.05)
		{
			led_blink(10, 10, 1);
			setPWMDutyCycle(i);
		}
	}*/

	// set initial switch state
	/*for (i = 0; i < SWITCH_COUNT; i++)
	{
		switchRelais(i, switch_state[i]);
	}*/

	sei();

	// DEMO 30s
	/*animation_length = 30;
	animation_length = (uint32_t)((float)animation_length * 1000 / ANIMATION_CYCLE_MS);
	start_brightness = 0;
	end_brightness = 255;
	animation_position = 0;*/
	
	while (42)
	{
		if (rfm12_rx_status() == STATUS_COMPLETE)
		{
			uint8_t len = rfm12_rx_len();
			
			if ((len == 0) || (len % 16 != 0))
			{
				UART_PUTF("Received garbage (%u bytes not multiple of 16): ", len);
				printbytearray(bufx, len);
			}
			else // try to decrypt with all keys stored in EEPROM
			{
				memcpy(bufx, rfm12_rx_buffer(), len);
				
				//UART_PUTS("Before decryption: ");
				//printbytearray(bufx, len);
					
				aes256_decrypt_cbc(bufx, len);

				//UART_PUTS("Decrypted bytes: ");
				//printbytearray(bufx, len);

				uint32_t assumed_crc = getBuf32(len - 4);
				uint32_t actual_crc = crc32(bufx, len - 4);
				
				//UART_PUTF("Received CRC32 would be %lx\r\n", assumed_crc);
				//UART_PUTF("Re-calculated CRC32 is  %lx\r\n", actual_crc);
				
				if (assumed_crc != actual_crc)
				{
					UART_PUTS("Received garbage (CRC wrong after decryption).\r\n");
				}
				else
				{
					//UART_PUTS("CRC correct, AES key found!\r\n");
					UART_PUTS("         Received: ");
					printbytearray(bufx, len - 4);
					
					// decode command and react
					uint8_t sender = bufx[0];
					
					UART_PUTF("           Sender: %u\r\n", sender);
					
					if (sender != 0)
					{
						UART_PUTF("Packet not from base station. Ignoring (Sender ID was: %u).\r\n", sender);
					}
					else
					{
						uint32_t packcnt = getBuf32(1);

						UART_PUTF("   Packet Counter: %lu\r\n", packcnt);

						// check received counter
						if (0) //packcnt <= station_packetcounter)
						{
							UART_PUTF2("Received packet counter %lu is lower than last received counter %lu. Ignoring packet.\r\n", packcnt, station_packetcounter);
						}
						else
						{
							// write received counter
							station_packetcounter = packcnt;
							eeprom_write_dword((uint32_t*)EEPROM_POS_STATION_PACKET_COUNTER, station_packetcounter);
							
							// check command ID
							uint8_t cmd = bufx[5];

							UART_PUTF("       Command ID: %u\r\n", cmd);
							
							if (cmd != 141) // ID 141 == Dimmer Request
							{
								UART_PUTF("Received unknown command ID %u. Ignoring packet.\r\n", cmd);
							}
							else
							{
								// check device id
								uint8_t rcv_id = bufx[6];

								UART_PUTF("      Receiver ID: %u\r\n", rcv_id);
								
								if (rcv_id != device_id)
								{
									UART_PUTF("Device ID %u does not match. Ignoring packet.\r\n", rcv_id);
								}
								else
								{
									// read animation mode and parameters
									uint8_t animation_mode = bufx[7] >> 5;
									
									// TODO: Implement support for multiple dimmers (e.g. RGB)
									// uint8_t dimmer_bitmask = bufx[7] & 0b111;
									
									animation_length = getBuf16(8);
									start_brightness = bufx[10];
									end_brightness = bufx[11];

									UART_PUTF("   Animation Mode: %u\r\n", animation_mode); // TODO: Set binary mode like 00010110
									//UART_PUTF("   Dimmer Bitmask: %u\r\n", dimmer_bitmask);
									UART_PUTF("   Animation Time: %us\r\n", animation_length);
									UART_PUTF(" Start Brightness: %u\r\n", start_brightness);
									UART_PUTF("   End Brightness: %u\r\n", end_brightness);
									
									animation_length = (uint32_t)((float)animation_length * 1000 / ANIMATION_CYCLE_MS);
									animation_position = 0;
									
									/* TODO: Write to EEPROM (?)
									// write back switch state to EEPROM
									switch_state[i] = req_state;
									switch_timeout[i] = req_timeout;
									
									eeprom_write_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2, u16);
									
									*/
									
									// send acknowledge
									UART_PUTS("Sending ACK:\r\n");

									// set device ID (base station has ID 0 by definition)
									bufx[0] = device_id;
									
									// update packet counter
									packetcounter++;
									
									if (packetcounter % PACKET_COUNTER_WRITE_CYCLE == 0)
									{
										eeprom_write_dword((uint32_t*)0, packetcounter);
									}

									setBuf32(1, packetcounter);

									// set command ID "Generic Acknowledge"
									bufx[5] = 1;
									
									// set sender ID of request
									bufx[6] = sender;
									
									// set Packet counter of request
									setBuf32(7, station_packetcounter);

									// zero unused bytes
									bufx[11] = 0;
									
									// set CRC32
									uint32_t crc = crc32(bufx, 12);
									setBuf32(12, crc);

									// show info
									UART_PUTF("            CRC32: %lx\r\n", crc);
									uart_putstr("      Unencrypted: ");
									printbytearray(bufx, 16);

									rfm12_sendbuf();
									
									UART_PUTS("   Send encrypted: ");
									printbytearray(bufx, 16);
									UART_PUTS("\r\n");
								
									rfm12_tick();
									
									led_blink(200, 0, 1);
									
									send_status_timeout = 25;
								}
							}
						}
					}
				}
				
			}

			// tell the implementation that the buffer can be reused for the next data.
			rfm12_rx_clear();
		}

		_delay_ms(ANIMATION_UPDATE_MS);
		
		// React on button press.
		// - abort animation
		// - switch off, when brightness > 0
		// - switch on otherwise
		if (!(BUTTON_PORT & (1 << BUTTON_PIN))) // button press
		{
			if (button_state == 0)
			{
				UART_PUTS("Button pressed\r\n");
				animation_length = 0;
				animation_position = 0;
			}
			
			if (button_state < 5)
			{
				button_state++;
			}
			else // manual dimming
			{
				if (manual_dim_direction) // UP
				{
					if (current_brightness < 100)
					{
						current_brightness = (uint8_t)current_brightness / 2 * 2 + 2;
						setPWMDutyCycle(current_brightness);
					}
					else
					{
						UART_PUTS("manual dimming DOWN\r\n");
						manual_dim_direction = 0;
					}
				}
				else // DOWN
				{
					if (current_brightness > 0)
					{
						current_brightness = (((uint8_t)current_brightness - 1) / 2) * 2;
						setPWMDutyCycle(current_brightness);
					}
					else
					{
						UART_PUTS("manual dimming UP\r\n");
						manual_dim_direction = 1;
					}
				}
				
			}
		}
		else if (button_state && (BUTTON_PORT & (1 << BUTTON_PIN))) // button release
		{
			UART_PUTS("Button released\r\n");
			
			if (button_state < 5) // short button press
			{
				if (current_brightness > 0)
				{
					UART_PUTS(" -> 0%\r\n");
					setPWMDutyCycle(0);
				}
				else
				{
					UART_PUTS(" -> 100%\r\n");
					setPWMDutyCycle(100);
				}
			}
			else
			{
				// reverse dim direction
				manual_dim_direction = !manual_dim_direction;
			}
			
			button_state = 0;
		}
				
		// update brightness according animation_position, updated by timer0
		if (animation_length > 0)
		{
			pos = animation_position; // copy value to avoid that it changes in between by timer interrupt
			UART_PUTF2("%lu/%lu, ", pos, animation_length);
			
			if (pos == animation_length)
			{
				UART_PUTF("END Brightness %u%%, ", end_brightness * 100 / 255);
				setPWMDutyCycle((float)end_brightness * 100 / 255);
				animation_length = 0;
				animation_position = 0;
			}
			else
			{			
				float brightness = (start_brightness + ((float)end_brightness - start_brightness) * pos / animation_length) * 100 / 255;
				UART_PUTF("Br.%u%%, ", (uint32_t)(brightness));
				setPWMDutyCycle(brightness);
			}
		}			
		
		// send status from time to time
		if (send_status_timeout == 0)
		{
			send_status_timeout = SEND_STATUS_EVERY_SEC * (1000 / ANIMATION_UPDATE_MS);
			send_dimmer_status();
			led_blink(200, 0, 1);
		}

		rfm12_tick();
		send_status_timeout--;
		checkSwitchOff();
	}
Exemple #29
0
void write_program(uint8_t number, uint32_t data)
{
    eeprom_write_dword(&program_data_storage[number], data);
}
Exemple #30
0
int main()
{
	long int savedfreq = 0;
	int s, c;
	unsigned char sw=0;

	// PORTB output for LCD
	DDRB = 0xff;
	PORTB = 0xff;

#ifdef BOARD2
	// PORTC PC0-4 output, PC5 input
	DDRC = 0x1f;
	PORTC = 0x00;
	sbi(PORTC, MUTE);
#endif
#ifdef BOARD1
	// PORTC PC0,2-5 output, PC1 input
	DDRC = 0x3d;
	PORTC = 0x00;
	sbi(PORTC, MUTE);
#endif

	// PORTD is input with pullup
	DDRD = 0x00;
	PORTD = 0xff;

	initLcd();
	initADC();

	// set reference freq
	fref = eeprom_read_word((unsigned int *)0x00);
	if (fref < 2000 || (fref % 100) != 0) {
		fref = 12000;
		eeprom_write_word((unsigned int *)0x00, fref);
	}

	// read squelch level from eeprom
	muteval = eeprom_read_word((unsigned int *)0x0c);
	if (muteval < 0 || muteval > 100) {
		muteval = 0;
		eeprom_write_word((unsigned int *)0x0c, muteval);
	}

	// read last frequency from eeprom
	freq = eeprom_read_dword((unsigned long int *)0x10);
	if (freq < 1240000UL || freq > 1300000UL) {
		freq = 1298375UL;
		eeprom_write_dword((unsigned long int *)0x10, freq);
	}

	// read shift from eeprom
	shift = eeprom_read_word((unsigned int *)0x18);
	if (shift < 60000UL || shift > 60000UL) {
		shift = -28000UL;
		eeprom_write_word((unsigned int *)0x18, shift);
	}

	// read tone (*10) from eeprom
	tone = eeprom_read_word((unsigned int *)0x1c);
	if (tone < 650 || tone > 1500) {
		tone = 650;
		eeprom_write_word((unsigned int *)0x1c, tone);
	}

	initInterrupts();
    initPLL(freq - IF);
	update();

	sprintf(str, "JPD 23cm v%s", version);
	lcdCmd(0x80);
	lcdStr(str);
	_delay_ms(500);

	for (;;) {

		lcdCmd(0x80);
		lcdStr("VFO             ");
		lcdCmd(0xc0);
		lcdStr("                ");
		update();

		for (;;) {
			// read switches on PORTD
			sw = PIND;

			// switch from tx to rx??
			if (tx && (sw & (1<<PTT) )) {
				cbi(PORTC, TXON);
				// switch TX off
				tx = FALSE;
//  				TCCR2A  &= ~(1<<COM2A1);
				update();
			}

			// switch from rx to tx?
			else if (!tx && !(sw & (1<<PTT) )) {
				tx = TRUE;
				displaySmeter(0);
				// switch TX on
				sbi(PORTC, TXON);
				sbi(PORTC, MUTE);
//				if (tone > 650) {
//	   				TCCR2A  |= (1<<COM2A1);
//				}
				update();
			}

			if (!tx) {
				s = readSmeter();
				displaySmeter(s);
				if (s > muteval)
					cbi(PORTC, MUTE);
				else
					sbi(PORTC, MUTE);
			}

			// switch shift off
			if ( (shiftSwitch == TRUE) && (sw & (1<<SHIFTKEY) )) {
				shiftSwitch = FALSE;
				update();
			}
			// switch shift on
			else if ( (shiftSwitch == FALSE) && !(sw & (1<<SHIFTKEY) )) {
				shiftSwitch = TRUE;
				update();
			}

			// save vfo frequency in eeprom after ~2 secs inactivity
			if (tick > 200) {
				if (freq != savedfreq) {
					eeprom_write_dword((unsigned long int *)0x10, freq);
					savedfreq = freq;
				}
			}
	
			// handle encoder pulses
			c = handleRotary();
			if (c!=0) {
				if (c>0) {
					freq += step;
				}
				else {
					freq -= step;
				}
				tick = 0;
				update();
			}

			if (rotaryPushed()) {
				doMenu();
				break;
			}
		}
	}
}