Nordic FOB Reprogramming

I am trying to reprogram the Nordic FOB. Everytime I send a hex file to it through my usbtiny and avrdude it uploads and says its fine.

The hex file I’m programming looks like:

:1000000010C01DC07DC01BC01AC019C018C017C0C9
:1000100016C015C014C013C012C011C010C00FC04C
:100020000EC011241FBECFEDCDBF10E0A0E6B0E0A2
:1000300001C01D92A436B107E1F7ABD0DFC0E0CF1D
:10004000282F90E080E041E039EC27FF02C0DE9AE3
:1000500001C0DE98DC9A48BF32BF08B600FEFDCF73
:10006000880FCD998160DC9848BF32BF08B600FE8A
:10007000FDCF9F5F983011F0220FE7CF0895C2980F
:10008000DFDFC29A08951F93162FC298D9DF812F00
:10009000D7DFC29A1F910895CF93DF93C298D0DF24
:1000A000C0E6D0E08991CCDF80E0C436D807D1F734
:1000B000C29ADF91CF910895C19880E268E7E3DFAB
:1000C00081E260E0E0DF84E260E0DDDF83E263E0C4
:1000D000DADF86E267E0D7DF85E262E0D4DF87EE31
:1000E000809360008093610080936200809363003E
:1000F00080E3D2DF80E26AE7C6DF8FEFC0DF0895DA
:100100001F920F920FB60F9211240F900FBE0F90F7
:100110001F9018951F9380E58ABB86E087BB1FE878
:100120001BBBC19881E083BFC7DF80E18ABF8BBF63
:1001300012BB80E385BF78941F91089531E026E0DB
:1001400015C038BF22BF08B600FEFDCF38BF22BFA2
:1001500008B600FEFDCF38BF22BF08B600FEFDCFB7
:1001600038BF22BF08B600FEFDCF0197009749F7C0
:10017000089587E26EE787DF80E26AE784DF81EE39
:100180007EDF80EA89DFC19A83E090E0D7DFC19803
:1001900008950F931F93CF93DF93BCDFEADFC0E096
:1001A000D0E000E81FE089B38F788F38B1F0219656
:1001B00029B389B390E08078907033E09595879566
:1001C0003A95E1F72F70282B20936000D0936100BF
:1001D000C093620010926300CCDF80E260E053DFE6
:1001E000C198C29A08B910B98895DDCF91E098BF3F
:1001F000819582BF08B600FEFDCF0895F894FFCF29
:00000001FF

but I read the chip back to a hex file and it comes out looking like:

:2000000010C01DC07DC01BC01AC019C018C017C016C015C014C013C012C011C010C00FC025
:200020000EC011241FBECFEDCDBF10E0A0E6B0E001C01D92A436B107E1F7ABD0DFC0E0CFEF
:20004000282F90E080E041E039EC27FF02C0DE9A01C0DE98DC9A48BF32BF08B600FEFDCFA6
:20006000880FCD998160DC9848BF32BF08B600FEFDCF9F5F983011F0220FE7CF0895C29809
:20008000DFDFC29A08951F93162FC298D9DF812FD7DFC29A1F910895CF93DF93C298D0DFB4
:2000A000C0E6D0E08991CCDF80E0C436D807D1F7C29ADF91CF910895C19880E268E7E3DF8F
:2000C00081E260E0E0DF84E260E0DDDF83E263E0DADF86E267E0D7DF85E262E0D4DF87EEC5
:2000E0008093600080936100809362008093630080E3D2DF80E26AE7C6DF8FEFC0DF089508
:200100001F920F920FB60F9211240F900FBE0F901F9018951F9380E58ABB86E087BB1FE880
:200120001BBBC19881E083BFC7DF80E18ABF8BBF12BB80E385BF78941F91089531E026E06F
:2001400015C038BF22BF08B600FEFDCF38BF22BF08B600FEFDCF38BF22BF08B600FEFDCFAA
:2001600038BF22BF08B600FEFDCF0197009749F7089587E26EE787DF80E26AE784DF81EE6A
:200180007EDF80EA89DFC19A83E090E0D7DFC19808950F931F93CF93DF93BCDFEADFC0E02A
:2001A000D0E000E81FE089B38F788F38B1F0219629B389B390E08078907033E0959587956D
:2001C0003A95E1F72F70282B20936000D0936100C093620010926300CCDF80E260E053DF76
:2001E000C198C29A08B910B98895DDCF91E098BF819582BF08B600FEFDCF0895F894FFCF59
:00000001FF

Is there any reason for this happening. My Nordic FOB hasn’t worked since the first time I used it… but I planned on reprogramming it for my project.

While I can’t help out with reprogramming the FOB, it does look like the hex file you’re writing is the same as the one you’re reading. If you read about the Intel HEX file format (http://en.wikipedia.org/wiki/Intel_HEX), it looks like the one that’s being read back is simply combining two lines of the upper file into one line and recalculating the checksum.

Ok well if it is programing it correctly is there a way I can test it? Like hook it up to a serial monitor and program with to write back to it and see if it works? If so what kind of serial monitor can be used with the usbtiny hooked up to the FOB attiny24.

Actually I finally got it to work. How would I change the Nordic FOB firmware to stop combining keypresses?

The code is:

/*
    2-8-2008
    Copyright Spark Fun Electronics© 2008
    Nathan Seidle
    nathan at sparkfun.com
    
	Key FOB transmitter based on the nRF24L01
	
	2-4uA average current
*/

#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
#define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))

//Define functions
//======================
void ioinit(void);      //Initializes IO
void delay_ms(uint16_t x); //General purpose delay
void delay_us(uint8_t x);

uint8_t data_array[4];

#include "nordic-nRF24L01.c"
//======================
ISR(PCINT0_vect)
{
	//This vector is only here to wake unit up from sleep mode
}

int main (void)
{
	ioinit();
	
	transmit_data(); //Send one packet when we turn on

	while(1)
	{
		
		if( (PINA & 0x8F) != 0x8F )
		{		
			data_array[0] = PINA & 0x0F;
			data_array[0] |= (PINA & 0x80) >> 3; //data_array[0] is the buttons pressed
			
			data_array[1] = 0;
			data_array[2] = 0;

			data_array[3] = 0;

			transmit_data();
		}
		
		tx_send_command(0x20, 0x00); //Power down RF

		cbi(PORTB, TX_CE); //Go into standby mode
		sbi(PORTB, TX_CSN); //Deselect chip
		
		ACSR = (1<<ACD); //Turn off Analog Comparator - this removes about 1uA
		PRR = 0x0F; //Reduce all power right before sleep
		asm volatile ("sleep");
		//Sleep until a button wakes us up on interrupt
	}
	
    return(0);
}

void ioinit (void)
{
	//1 = Output, 0 = Input
	DDRA = 0xFF & ~(1<<TX_MISO | 1<<BUTTON0 | 1<<BUTTON1 | 1<<BUTTON2 | 1<<BUTTON3 | 1<<BUTTON4);
	DDRB = 0b00000110; //(CE on PB1) (CS on PB2)

	//Enable pull-up resistors (page 74)
	PORTA = 0b10001111; //Pulling up a pin that is grounded will cause 90uA current leak

	cbi(PORTB, TX_CE); //Stand by mode
	
    //Init Timer0 for delay_us
    TCCR0B = (1<<CS00); //Set Prescaler to No Prescaling (assume we are running at internal 1MHz). CS00=1 

	/*
	DDRA = 0xFF;
	DDRB = 0xFF;
	while(1)
	{
		PORTA = 0xFF;
		PORTB = 0xFF;
		delay_ms(3000);

		PORTA = 0x00;
		PORTB = 0x00;
		delay_ms(3000);
	}
	*/

	configure_transmitter();

	GIFR = (1<<PCIF0); //Enable the Pin Change interrupts to monitor button presses
	GIMSK = (1<<PCIE0); //Enable Pin Change Interrupt Request
	PCMSK0 = (1<<BUTTON0)|(1<<BUTTON1)|(1<<BUTTON2)|(1<<BUTTON3)|(1<<BUTTON4);

        /* Im not 100% but I think the above line is where the PINA variable comes from... */
	MCUCR = (1<<SM1)|(1<<SE); //Setup Power-down mode and enable sleep
	
	sei(); //Enable interrupts
}

//General short delays
void delay_ms(uint16_t x)
{
	for (; x > 0 ; x--)
	{
		delay_us(250);
		delay_us(250);
		delay_us(250);
		delay_us(250);
	}
}

//General short delays
void delay_us(uint8_t x)
{
	TIFR0 = 0x01; //Clear any interrupt flags on Timer2
	
    TCNT0 = 256 - x; //256 - 125 = 131 : Preload timer 2 for x clicks. Should be 1us per click

	while( (TIFR0 & (1<<TOV0)) == 0);
}

There are a few places I could think would be it but I cant find it for sure or get it working on just sending separate bits for each keypress and not combine keys when pressed together just send the first pressed and ignore the second.

Also it seems to send a signal on the down and up keystrokes. For my project I would like to only have one sent on the up or down keystroke. Is there anything in the coding I could do to achieve this?