Pages: [1] 2   Go Down
Author Topic: Problem with init() (in wiring.c) when my init of the UART (unsolved)  (Read 887 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello.

I have a conflict with the ini() from wiring.c and my own init of the UARTs.

This is working well. The Arduino is doing what it should be.
Code:
void init()
{
    cli();
    v1state = inmsgstate = inmsglen = polarity = bitcnt = 0;

    DDRB = _BV(PB7); // PB7/LED
    // UART init
#include <util/setbaud.h>
UBRR3H = UBRR0H = UBRRH_VALUE;
UBRR3L = UBRR0L = UBRRL_VALUE;
#if USE_2X
    UCSR3A = UCSR0A = _BV(U2X3);
#endif
UCSR3C = UCSR0C = _BV(UCSZ30) | _BV(UCSZ31);       // 8N1
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);    // Enable TX and RX

    // Timer init
    GTCCR = 0;                  //_BV(PSR10);         /* reset prescaler */

    // trigger on falling edge (default), noise cancel
    // lower 3 bits is div, off,1,8,64,256,1024,extfall,extris ; CS12,11,10
    TCCR4B = _BV(ICNC1) | _BV(CS11);

    // clear and enable Input Capture interrupt
    TIFR4 |= _BV(ICF4) | _BV(TOV4) | _BV(OCF4A) | _BV(OCF4B);
    TIMSK4 = _BV(ICIE4);        // enable input capture only

    sei();                      // enable interrupts
    // and sleep between events
    set_sleep_mode(SLEEP_MODE_IDLE);
}

When I want to add this code in py own project, I get a conflict with init() of wiring.c.
This error:

Quote
C:\Users\syrinx\AppData\Local\Temp\build6135219376461108096.tmp\core.a -LC:\Users\syrinx\AppData\Local\Temp\build6135219376461108096.tmp -lm
core.a(wiring.c.o): In function `init':
C:\Portable\Arduino\arduino-1.0.3\hardware\arduino\cores\arduino/wiring.c:193: multiple definition of `init'
bluevirq.c.o:C:\Users\syrinx\AppData\Local\Temp\build6135219376461108096.tmp/bluevirq.c:347: first defined here

Then I've started to change the function and to rename is hwsetup() and to call it from setup(), or even from main(). I don't have compiling error, but the Arduino is not doing its job. I guess the UARTs are not well set. But as I change almost nothing, I think the UARTs are set too late or there is a conflict with init() from wiring.c
But I don't have any error during compiling.

Code:
void hwsetup()
{
    cli();
    v1state = inmsgstate = inmsglen = polarity = bitcnt = 0;

    DDRB = _BV(PB7); // PB7/LED
    // UART init
#include <util/setbaud.h>
UBRR3H = UBRR0H = UBRRH_VALUE;
UBRR3L = UBRR0L = UBRRL_VALUE;
#if USE_2X
    UCSR3A = UCSR0A = _BV(U2X3);
#endif
UCSR3C = UCSR0C = _BV(UCSZ30) | _BV(UCSZ31);       // 8N1
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);    // Enable TX and RX

    // Timer init
    GTCCR = 0;                  //_BV(PSR10);         /* reset prescaler */

    // trigger on falling edge (default), noise cancel
    // lower 3 bits is div, off,1,8,64,256,1024,extfall,extris ; CS12,11,10
    TCCR4B = _BV(ICNC1) | _BV(CS11);

    // clear and enable Input Capture interrupt
    TIFR4 |= _BV(ICF4) | _BV(TOV4) | _BV(OCF4A) | _BV(OCF4B);
    TIMSK4 = _BV(ICIE4);        // enable input capture only

    sei();                      // enable interrupts
    // and sleep between events
    set_sleep_mode(SLEEP_MODE_IDLE);
}

Code:
void loop()
{   hwsetup();
....
}

I should add that all is in 2 different files but it's working well before to add some codes of my own. I use <EEPROM.h> and "XBee.h".

Do you how to solve this? Should I create a library which, I guess, will be called before setup()?

Thank you.
« Last Edit: January 20, 2013, 02:09:49 pm by syrinx » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46026
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Do you how to solve this?
Rename your init() function. The Arduino provides one. You shouldn't.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's what I did: I rename it into hwsetup(). I call it from main() or even setup(), I don't have compiling error, but the Arduino is not working well.

(sorry, I didn't write correctly the hwsetup(), I've just changed)
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46026
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
but the Arduino is not working well.
Oh, well, that's a real shame.

If you showed some code, and explained what "is not working well" means, perhaps we could do more than sympathize.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Main .ino file:
Code:
#include "bluevmega.cpp"

void setup()
{
 
 Serial.begin(57600);
 delay(1000);
}

void loop()
{  
hwsetup(); [b]// GLOW: added beacuse I've renamed init() into hwsetup() !!!!!!!!!!!![/b]

int ret;
    unsigned char lastdisp[12];
Serial.println("V1MegaTool");
    for (;;) {
for (;;) {
ret = readpkt(respget); [b]// FX: STAY BLOCKED HERE !!! (GLOW)[/b]
if (ret < 5)
                continue;
            if (respget[3] == INFDISPLAYDATA)
                break;
        }
        if(legacy > 32)
            printser(pullp(PSTR("LEGACY! only V works\r\n")));  
inbuf[inhead++] = Serial.read();
            printser(pullp(PSTR("Mute (ESP)Hold systemUp mainDisp Euro Custom\r\n")));
            lastdisp[0] = 0;
            while (1) {
ret = readpkt(respget);
                if (ret < 5) {
                    continue;
}
                if (respget[3] == INFDISPLAYDATA && memcmp(lastdisp, respget, 12)) {
showinfdisp();
                    memcpy(lastdisp, respget, 12);
                }
if (Serial.available() >= 1 ) {
inbuf[inhead++] = Serial.read();
}
   }
            break;
        }
}
« Last Edit: January 20, 2013, 01:55:20 am by syrinx » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A part of the file bluevirq.c:
Please notice that there if hwsetup() was name init() the Arduino will work.

Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

//#define F_CPU         18432000
#ifndef F_CPU
#define F_CPU   16000000
#endif
#define BAUD 57600

#define PRESCALE1 8
#define BITTIME(x) ( ((x) * F_CPU) / PRESCALE1 / BAUD)

/*-------------------------------------------------------------------------*/
#define INMSGSIZE 24
unsigned char inbuf[256], v1buf[256];
volatile unsigned char v1head = 0, v1tail = 0, inhead = 0, intail = 0;
static volatile unsigned int bitcnt;
static unsigned int frametime;
// Time Slice processor
// This counts character times to find the slot to transmit.  
// Each slot is 45 character times wide
// FIXME - doesn't try to resync or otherwise avoid collisions with other devices
ISR(TIMER4_COMPB_vect)
{
    OCR4B += BITTIME(10);
    frametime++;

    if (frametime < 45 * slice)
        return;

    if (inmsgstate != 4) {      // nothing for this frame
        TIMSK4 &= ~_BV(OCIE4B); // slice processor off
        UCSR3B &= ~_BV(TXEN0);  // TX off - just in case
        frametime = 0;
        return;
    }
    if (
#ifdef ANYSLICE
      (slice == 0 && frametime == 1) ||
#endif
      frametime == 45 * slice) {        // At current time slice

        // Holdoff for late previous time slice
        if (bitcnt)
            frametime--;
        else
            UCSR3B |= _BV(TXEN0);       // TX on
        return;
    }

    if (frametime >= 45 * (slice + 1)) {        // end of time slice
        TIMSK4 &= ~_BV(OCIE4B); // slice processor off
        UCSR3B &= ~_BV(TXEN0);  // TX off
        frametime = 0;
        inmsgstate = 0;
        return;
    }

    if (!(frametime & 1)) {     // Data Out Pacing, every other frame until done
        unsigned char ptr = (frametime - (45 * slice + 1)) >> 1;
        if (ptr < inmsglen)
            UDR3 = inmsgbuf[ptr];
        if (ptr > inmsglen)
            UCSR3B &= ~_BV(TXEN0);      // TX off
    }
}
static unsigned char outchar;   // bitbang UART receive register
static unsigned char polarity;  // which edge are we looking for
volatile unsigned legacy;
//Stopbit for software UART
ISR(TIMER4_COMPA_vect)
{
    TIMSK4 &= ~_BV(OCIE4A);     // disable
    if (!polarity) {            // not break condition
        while (bitcnt < 10) {   // fill in one bits up to stop bit
            bitcnt++;
            outchar >>= 1;
            outchar |= 0x80;
        }
        if (transp)
            UDR0 = outchar;
        else
            v1buf[v1head++] = outchar;
        dostate(outchar);
        if(legacy)
            legacy--;
    }
    else {                      // break, reset things for next start bit
        TCCR4B &= ~_BV(ICES1);
        polarity = 0;
    }
    bitcnt = 0;
}

// Software UART via edges
char legbits[36] = "+medcbap87654321gfKALFFFSSSRRRIXMNOP";
unsigned long legimg;
ISR(TIMER4_CAPT_vect)
{
    static unsigned lastedge;
    unsigned thisedge = ICR4;
    TCCR4B ^= _BV(ICES1);
    unsigned width = thisedge - lastedge;
    lastedge = thisedge;
    polarity ^= 1;

// Legacy Mode
#define LEGABIT (504)
#define USTICS(us) ((us) * (F_CPU/PRESCALE1)/1000000)
    if( legacy > 100 ) {
        if( width < USTICS(LEGABIT)/5 ) { // normal bits for ESP
            bitcnt = 0;
            legacy--;
            return;
        }
        if( width > USTICS(LEGABIT)*2 ) { // 9.58 mS nominal
            PORTB ^= _BV(PB7);
            bitcnt = 0;
            ;//UDR2 = UDR0 = '\n';
            return;
        }
        if( polarity )
            return;
        ++bitcnt;
        legimg <<= 1;
        if( width <  USTICS(LEGABIT)/2 ) {
            if( bitcnt < 37 ) {
                ;//UDR2 = UDR0 = legbits[bitcnt-1];
                legimg |= 1;
            }
        return;
    }
    if(width > USTICS(LEGABIT) - 25 && width < USTICS(LEGABIT) + 25 ) {
        if( (++legacy & 1023) == 0 ) {
            PORTB ^= _BV(PB7);
            UDR0 = 'L';
        }
        legacy &= 4095;
    }
    /* toggle interrupt on rising/falling edge */
    if (polarity && !bitcnt) { // start bit
        OCR4A = lastedge + BITTIME(9) + BITTIME(1) / 2;
        TIFR4 |= _BV(OCF4A);    /* clear compare match interrupt */
        TIMSK4 |= _BV(OCIE4A);  /* enable compare match interrupt */
        bitcnt = 1;
        return;
    }
    width += BITTIME(1) / 2;    // round up
    while (width >= BITTIME(1)) {       // Shift in bits based on width
        width -= BITTIME(1);
        bitcnt++;
        outchar >>= 1;
        if (polarity)
            outchar |= 0x80;
    }
}

//void init() // GLOW: if it is 'void init()' it will work !!!!!!!!!!!!!!
void hwsetup()
{
    cli();
    v1state = inmsgstate = inmsglen = polarity = bitcnt = 0;

    DDRB = _BV(PB7); // PB7/LED
    // UART init
#include <util/setbaud.h>
UBRR3H = UBRR0H = UBRRH_VALUE;
UBRR3L = UBRR0L = UBRRL_VALUE;
#if USE_2X
    UCSR3A = UCSR0A = _BV(U2X3);
#endif
UCSR3C = UCSR0C = _BV(UCSZ30) | _BV(UCSZ31);       // 8N1
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);    // Enable TX and RX
    // for UART1, only TX is enabled, and only when sending in the right timeslice

    // Timer init
    GTCCR = 0;                  //_BV(PSR10);         /* reset prescaler */

    // trigger on falling edge (default), noise cancel
    // lower 3 bits is div, off,1,8,64,256,1024,extfall,extris ; CS12,11,10
    TCCR4B = _BV(ICNC1) | _BV(CS11);

    // clear and enable Input Capture interrupt
    TIFR4 |= _BV(ICF4) | _BV(TOV4) | _BV(OCF4A) | _BV(OCF4B);
    TIMSK4 = _BV(ICIE4);        // enable input capture only

    sei();                      // enable interrupts
    // and sleep between events
    set_sleep_mode(SLEEP_MODE_IDLE);
}

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Some functions used in bluevmega.c. I've extracted what you need to see to undertsand the issue.

Code:
static int readpkt(unsigned char *buf)
{
    unsigned char len, ix;
    buf[0] = 0;
for (;;) {
        while (buf[0] != 0xaa)  // SOF
        {
// GLOW: start to loop here: turning turning turning turning if it's with hwsetup() Working well with init() !!!!!!!!!!!
buf[0] = readv1rx();
        }
buf[1] = readv1rx();    // destination
......

Code:
extern volatile unsigned char v1head, v1tail, inhead, intail;
extern unsigned char v1buf[], inbuf[];
// LOW LEVEL ROUTINES FOR ARDUINO
// Read one character from the V1 data stream
static int readv1rx(void)
{
    while (v1head == v1tail)
        sleep_mode();
    return v1buf[v1tail++];
}

I hope it's understandable.

Any idea? Thx.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

As I know that the libs are initialised before setup(), I tried to make a library with this.

But I get the same, it's not working.

Quote
#include "LED13.h" //include the declaration for this class

#include <util/setbaud.h>
#include <avr/sleep.h>
   

    LED13::LED13(){
      
      cli();
      // v1state = inmsgstate = inmsglen = polarity = bitcnt = 0;
      DDRB = _BV(PB7); // PB7/LED
      // UART init
      //#include <util/setbaud.h>
      // Syrinx it was: UBRR2H = UBRR3H = UBRR0H = UBRRH_VALUE;
      UBRR3H = UBRR0H = UBRRH_VALUE;
      // Syrinx it was: UBRR2L = UBRR3L = UBRR0L = UBRRL_VALUE;
      UBRR3L = UBRR0L = UBRRL_VALUE;
      #if USE_2X
      // Syrinx it was: UCSR2A = UCSR3A = UCSR0A = _BV(U2X3);
      UCSR3A = UCSR0A = _BV(U2X3);
      #endif
      // Syrinx it was: UCSR2C = UCSR3C = UCSR0C = _BV(UCSZ30) | _BV(UCSZ31);       // 8N1
      UCSR3C = UCSR0C = _BV(UCSZ30) | _BV(UCSZ31);       // 8N1
      // Syrinx it was: UCSR2B = UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);    // Enable TX and RX
      UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);    // Enable TX and RX
      // for UART1, only TX is enabled, and only when sending in the right timeslice

      // Timer init
      GTCCR = 0;                  //_BV(PSR10);         /* reset prescaler */

      // trigger on falling edge (default), noise cancel
      // lower 3 bits is div, off,1,8,64,256,1024,extfall,extris ; CS12,11,10
      TCCR4B = _BV(ICNC1) | _BV(CS11);

      // clear and enable Input Capture interrupt
      TIFR4 |= _BV(ICF4) | _BV(TOV4) | _BV(OCF4A) | _BV(OCF4B);
      TIMSK4 = _BV(ICIE4);        // enable input capture only

      sei();                      // enable interrupts
      // and sleep between events
      set_sleep_mode(SLEEP_MODE_IDLE);
      
      
    }
     
    //<<destructor>>
    LED13::~LED13(){/*nothing to destruct*/}
     
    //turn the LED on
    void LED13::on(){

   }
     
    //turn the LED off
    void LED13::off(){
        //digitalWrite(LED_PIN,HIGH); //set the pin HIGH and thus turn LED on
    }
     
    //blink the LED in a period equal to paramterer -time.
    void LED13::blink(int time){
            //on();                   //turn LED on
            //delay(time/2);  //wait half of the wanted period
            //off();                  //turn LED off
            //delay(time/2);  //wait the last half of the wanted period
    }
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Main .ino file:
Code:
#include "bluevmega.cpp"

You shouldn't include .cpp files. Why are you doing that?

Quote
But I get the same, it's not working.

What do you mean? Not compiling?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I use "#include "bluevmega.cpp"" to avoid to declare (extern ...) each variables and functions from blevmega in the main .ino file.

When I said the Arduino is not working: it means that compiling is working, the Arduino starts, but the bytes coming in port 49 (RX in) of Arduino Mega are not OK.

I prefer to repeat that almost the same code but with init() is working very well.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I did:
- I have deleted #include "bluevmega.cpp"
- renamed the 3 files with .ino extension
- moved all the variables at the beginning of the main .ino file

Still not working when the UART init is not named init().
« Last Edit: January 20, 2013, 05:49:00 am by syrinx » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It seems that it works if hwsetup() is launched from main()

Then inside main(), I call loop().
« Last Edit: January 20, 2013, 07:31:37 am by syrinx » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I still have a problem: millis() gives always 0.

It's probably related to interrupts or ini of wiring.c.

Any idea how to solve this?

Thanks.
« Last Edit: January 20, 2013, 02:11:34 pm by syrinx » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

millis() was always at zero. Now it's OK.

I was obliged to add this:

Code:
int main()
// Syrinx was: #else
// Syrinx was: void init()
// Syrinx was: #endif
{
    hwsetup();
// Enable TIMER0 ( used by millis() )
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
sbi(TCCR0B, CS01);
sbi(TCCR0B, CS00);
sbi(TIMSK0, TOIE0);
setup();
loop();
}

Now millis() is working a gain. As my code is not changing TIMER0 somewhere, it means that init() is not well built. I don't know why.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You shouldn't really have a main. The "real" main calls init, setup, and then loop repeatedly. Why not put your setting up in setup?
Logged

Pages: [1] 2   Go Up
Jump to: