N0o0B going mad on butterfly joystick PORTE

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey all,
The title sais it all. I have been progressing from LCD to joystick in an attempt to get my butterfly to clean the house and do the dishes, and am stuck with PORTE not responding as I expect.
I have tried many different examples from this board, and none have worked for me. The ATMEL butterfly example application does work tho.

In desperation I attempted something simple to determine what PORTE was doing. It appears no matter how I set DDRE and PORTE I still get the same thing: PINE=11110011
Randomly this changes after a few seconds to PINE=10000011.
The point here is that ~(PORTE)&((1<<PE3)|(1<<PE3)) never changes from 00001100.
I have not attached LED's nor a multimeter (can I hold the probes still enough) to put the output on PORTD to determine whether its the LCD initialisation.
The aim of course is to have joystick+deans LCD driver+tiny menus +{multitasking state machine}+ dish washing appendages.

Here is the code I used to see what PORTE wasnt doing. What am I doing wrong? (please one thing at a time...)

/* Total frustration at PortE not behaving as it should. I.e PE3,2 
 * change on joystick
 */

 #include  
 #include  
 #include 

 #define PINB_MASK  ((1<<PINB7)|(1<<PINB6)|(1<<PINB4)) 
 #define PINE_MASK  ((1<<PINE3)|(1<<PINE2)) 

//Includes for LCD
#define LCD_CONTRAST_LEVEL(level)  do{ LCDCCR = (0x0F & level); }while(0)
 
 void LCD_Init(void) 
 { 
    // Set the initial contrast level to maximum: 
    LCD_CONTRAST_LEVEL(0x0F); 
     // Select asynchronous clock source, enable all COM pins and enable all segment pins: 
     LCDCRB  = (1<<LCDCS) | (3<<LCDMUX0) | (7<<LCDPM0); 
     // Set LCD prescaler to give a framerate of 64Hz: 
     LCDFRR  = (0<<LCDPS0) | (3<<LCDCD0);    
    // Enable LCD and set low power waveform, enable start of frame interrupt: 
     //LCDCRA  = (1<<LCDEN) | (1<<LCDAB) | (1<<LCDIE); 
     LCDCRA  = (1<<LCDEN); //Only enabled get interrupt out of equation
 } 
 
 void JoyInit () 
 { 
 // set ports B,E to input;  enable pullup on for joy pins 
    //DDRB &= (~PINB_MASK);   PORTB |= PINB_MASK; 
    //DDRE &= (~PINE_MASK);   PORTE |= PINE_MASK; 
    DDRB &= (~((1<<DDB7)|(1<<DDB6)|(1<<DDB4)));
    PORTB |= (1<<PB7)|(1<<PB6)|(1<<PB4);
    DDRE &= ~((1<<DDE3)|(1<<DDE2));
    PORTE |= (1

cheers

jasper[/b]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
      if (!((PINE) & (1<<PE3))){ 
          LCDDR0=0x4; 
          _delay_ms(300); 
          LCDDR0=0x0; 
          _delay_ms(300); 
       } 
      else 
         LCDDR2 = 0x4; 
         _delay_ms(300); 
         LCDDR2=0x0; 
         _delay_ms(300); 

Do you really not want braces around the lines after the else? And why do all of the if-else's do the exact same thing?

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
Do you really not want braces around the lines after the else?

Ignorance is on my side. I assume you are suggesting this is preferred practice.

Quote:
And why do all of the if-else's do the exact same thing?

Not quite the exact same thing. Each if/else is looking at a different bit of PORTE. I would have done this with a for loop if I could remember how. i.e the bashism would have been

for(i=0, i<8, i++){
  if (!((PINE) & (1<<PE$i))){ //note the $i, obv. wrong
 ...}
else{
...}
}

Still.. any ideas why I am getting this o/p?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I assume you are suggesting this is preferred practice.
No, I am suggesting that:

     else 
         LCDDR2 = 0x4; 
         _delay_ms(300); 
         LCDDR2=0x0; 
         _delay_ms(300);

will behave completely differently than:

     else 
    {
         LCDDR2 = 0x4; 
         _delay_ms(300); 
         LCDDR2=0x0; 

         _delay_ms(300);
    }

Quote:
Each if/else is looking at a different bit of PORTE.
But since the response is the same for each pin, how do you know which pins are or are not changing the display?

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
No, I am suggesting that:

     else 
         LCDDR2 = 0x4; 
         _delay_ms(300); 
         LCDDR2=0x0; 
         _delay_ms(300);

will behave completely differently


Than you. It did slightly modify the behaviour. much appreciated.
Quote:
Quote:
Each if/else is looking at a different bit of PORTE.
But since the response is the same for each pin, how do you know which pins are or are not changing the display?

There is a delay between each. so 0100... is 9 pause 1 pause 9 pause 9 pause , long pause.

Can you see any reason why PORTE is behaving like it is. After the third run through PORTE changes still. strange.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

the solution may be lurking just around the corner. Especially if You have bootloader intact:
https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=30379&start=0&postdays=0&postorder=asc&highlight=butterfly+porte+joystick
Sorry if this is not the case; happened to be in the same situation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Damn! this makes no sense! it looks like what you suggested did something, but it didnt really. ALMOST (not always) PINE looks like:

00001100
00001100
00011100
00011100
00111100
01111100

Sometimes the order is a little different. SOmething is changing PINE and its not the joystick. No joystick movement makes any difference here.

Maybe most people are using a non ATMEL bootloader. Is the bf_gcc bootloader safe? (i.e I have no ISProgrammer and would brick the buttterfly like in big buck bunny) and would I get the same issue.

EDIT:
with

DDRE = 0; 
PORTE = _BV(PE2); 
DIDR1 = 0;

Things work as they should for the first run of the if loop only. then its back to random crap on PINE

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can't help with the code, but I do recall the Butterfly acting flaky when the battery was getting low.

Perhaps time to try a new battery?

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So did

DIDR1 = 0

work?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Can you see any reason why PORTE is behaving like it is.
...
SOmething is changing PINE and its not the joystick.
And what is connected to those joystick pins? Have you bothered to look at the schematic?

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
Quote:
Can you see any reason why PORTE is behaving like it is.
...
SOmething is changing PINE and its not the joystick.
And what is connected to those joystick pins? Have you bothered to look at the schematic?

Yes I have. I figured that the special functions were not enabled by default. I suppose I am wrong. Having det DIDR1=0 should have disabled the analogue comparator, That only leaves ensuring that the USART is disabled or not in synchronouse mode. Is this achieved by PRR |= (1<<PRUSART0);?
What else am I missing please.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's strange, since

DIDR1 = 0
DDRB = 0
DDRE = 0 

did a trick for me. Unfortunately can't find an original code for reference.
The issue was exactly as Yours, original bootloader was used. I was lucky finding such a solution, but now methinks outside this forum. IIRC the roots of this evil are about bootloader leaves strange configuration of PORTE.
Short AVRBasic code worked OK transferring joystick readings over serial port to PC.
Edit: would it be possible to ask for the hw/sw version of Butterfly? Are You using that serial bootloader or other (ISP, JTAG) for programming?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have a look at this thread: Butterfly Bug .

That was a while ago, and I suspect the Butterfly's code has undergone an update or two, but still probably worth a read.

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's brilliant, JC!
Now I can recall where found it and why got rid of that bootloader. Refers to an year old butterfly, I expect that's the latest sw revision revision. Oh, sorry, was.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

New batteries,

DDRE = 0; 
   PORTE = _BV(PE2);
   PCMSK0 = 0;
   DIDR1 = 0;
   DIDR0 = 0;

still to no avail. I guess I need to go through the bf_gcc port of the application and see what they do.
ITs pretty weird that it solves the problem for others.
Evertyhing works for the first few seconds tho.
rrrrrrrrrrr!

[edit]
Note I tried to set PCMSK =0; doesnt work. PCINT2 and PCINT3 need to be set...

Last Edited: Wed. Sep 14, 2011 - 11:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

[SOLVED]
I should have done this first 8)
After looking at the bf_gcc port of the Atmel Butterfly application, and Buttons_Init in buttons.c, and including this (With compat/depreciated.h) everything worked fine.
The critical factor: Setting the interrupts. Not DIDR or any fancyness. It seems weird to me, but there we go.
Buttons_Init is included here incase someone stubles across this:

void Button_Init(void)
{
    // Init port pins
    cbi(DDRB,7);
    cbi(DDRB,6);
    cbi(DDRB,4);
    PORTB |= PINB_MASK;
    DDRE = 0x00;
    PORTE |= PINE_MASK;

   // Enable pin change interrupt on PORTB and PORTE
	PCMSK0 = PINE_MASK;
	PCMSK1 = PINB_MASK;
	EIFR = (1<<PCIF0)|(1<<PCIF1);
	EIMSK = (1<<PCIE0)|(1<<PCIE1);
	
	//CountdownTimerHandle = Timer0_AllocateCountdownTimer();
}

I have commented out the CountdownTimerHandle.
So in terms of the original code:

void JoyInit () 
 { 
 // set ports B,E to input;  enable pullup on for joy pins 
    DDRB &= (~PINB_MASK);   PORTB |= PINB_MASK; 
    DDRE &= (~PINE_MASK);   PORTE |= PINE_MASK; 
    // Enable pin change interrupt on PORTB and PORTE
	PCMSK0 = PINE_MASK;
	PCMSK1 = PINB_MASK;
	EIFR = (1<<PCIF0)|(1<<PCIF1);
	EIMSK = (1<<PCIE0)|(1<<PCIE1);
}