Author Topic: PIC16F1459 Problem  (Read 7376 times)

0 Members and 1 Guest are viewing this topic.

Offline cjhofer

  • Contributor
  • Posts: 5
  • Country: us
PIC16F1459 Problem
« on: August 14, 2015, 03:30:13 am »
I am trying to run the I2C module and the USB module together. I have set the USB to run at 48MHz from the internal oscillator. I am using a pll of x3. When I run the USB at this speed, the I2C fails to send a start bit or drive the clock or data line at all. I have tried every CPU divider to try and run the I2C slower. I also set the baud rate register at 255. I am able to run the I2C at 16MHz with no PLL. I am powering this part with 3.3V.

Is the I2C able to run with the PLL enabled?
 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 1750
Re: PIC16F1459 Problem
« Reply #1 on: August 14, 2015, 03:11:48 pm »
I have only been able to get the I2C to work reliably with the 48MHz PLL divided down to a 8MHz cpu clock. I've not tried driving the clock directly from an external source. I'm using 5V.
 

Offline cjhofer

  • Contributor
  • Posts: 5
  • Country: us
Re: PIC16F1459 Problem
« Reply #2 on: August 14, 2015, 04:41:57 pm »
Andy,

What do you set the OSCCON to? Are you using the USB? Do you see problems with the I2C when not using the CPU divide?
 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 1750
Re: PIC16F1459 Problem
« Reply #3 on: August 14, 2015, 05:49:45 pm »
I've not set OSCCON - its important values appear to be overridden by the bits in the configuration words. I have just checked that changing the OSCCON,PLLMULT bit does not alter operation of the USB - and it doesn't - i.e. the chip is following the setting in the configuration word.

I am running USB - which appears to function at both high and low speeds irrespective of the CPUDIV value. However, I can only get the I2C to work properly if I have the CPUDIV set to divide by 6. I sometimes got a response from the faster setting of CPUDIV, but it was, at best, flaky!

Edit: When I said I hadn't tried an external clock source I meant an external oscillator - I am using the HS crystal mode with a 16MHz crystal.

« Last Edit: August 14, 2015, 06:08:42 pm by Andy Watson »
 

Offline cjhofer

  • Contributor
  • Posts: 5
  • Country: us
Re: PIC16F1459 Problem
« Reply #4 on: August 15, 2015, 04:40:00 am »
Turns out I did not wait for the OSCSTAT bits to get set after I changed the OSCCON bits. Now I am able to get I2C to run at CPU/6 when running the USB at 48MHz. When I do this the USB still doesn't connect, it seems like the main loop is running too slow with CPU/6.
 

Online Howardlong

  • Super Contributor
  • ***
  • Posts: 4846
  • Country: gb
Re: PIC16F1459 Problem
« Reply #5 on: August 15, 2015, 11:33:34 am »
I realise you've fixed this now, but in the meantime I'd already breadboarded up a solution with an I2C LCD display. Attached is the code.





 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 1750
Re: PIC16F1459 Problem
« Reply #6 on: August 15, 2015, 12:52:23 pm »
Now I am able to get I2C to run at CPU/6 when running the USB at 48MHz. When I do this the USB still doesn't connect, it seems like the main loop is running too slow with CPU/6.
   

This is the header/configuration for my code (using external 16Mhz crystal):
Code: [Select]
        processor 16F1459
       __config       8007,38c2

;/** USB Speed. defaults to Full Speed if Low_Speed is not defined */
#define Low_Speed

;  Define division for CPU clock (after PLL clock)
#define CPU_Clock  8
;
#if (CPU_Clock == 48)
      __config       8008,19c3     ; Define  48 MHz  No division
#endif
#if (CPU_Clock == 24)
      __config       8008,19d3     ; Define  24 MHz  Divide 2
#endif
#if (CPU_Clock == 16)
      __config       8008,19e3     ; Define  16 MHz  Divide 3
#endif
#if (CPU_Clock == 8)
      __config       8008,19f3     ; Define   8 MHz  Divide 6    Need this option for I2C to work.
#endif

The definition of "Low_Speed" causes the USB UCFG register to be initialised with different value
Code: [Select]
#ifdef Low_Speed
      movlw     010           ; Select pull-up resistors and Low speed osc source
#else
      movlw     014           ; Select pull-up resistors and High speed osc source
#endif
      movwf     UCFG
it also changes part of the USB "device descriptor" message as appropriate.

Are you using library code or rolling your own? It appears that the USB Serial Interface Engine has been lifted from the 18f2455 family, gate for gate including the silicon bugs, and word for word including the erroneous documentation! This is useful to know because there is much more searchable history for the 18f family.
 

Offline cjhofer

  • Contributor
  • Posts: 5
  • Country: us
Re: PIC16F1459 Problem
« Reply #7 on: August 15, 2015, 02:31:06 pm »
I am using a USB stacked based on the Microchip HID example, and stripped down to use less chip resources. It seems to work when the CPU is running with no divide and 48MHz driven from the internal oscillator. I have even tried to setup the USB config register for low speed but Windows did not like this configuration.
 

Online Howardlong

  • Super Contributor
  • ***
  • Posts: 4846
  • Country: gb
Re: PIC16F1459 Problem
« Reply #8 on: August 15, 2015, 06:50:06 pm »
I've tried a number of options with I2C and USB today. I use the HID host app to send an 'x' character to the LCD when the dialogue box button is pressed. All worked. The I2C is operating at 400kHz, although I did try it at 67kHz too and that was successful. Each I2C transaction is 3 bytes.

I haven't determined any problem in connecting or maintaining USB connection.

This is based on the 2013-06-15 MLA stack, and the HID custom demo.

All these alternatives work at both 3.3V and 5V:

o Internal oscillator, no clkdiv
o 12MHz PLLx4, no clkdiv
o Internal oscillator, clkdiv6
o 12MHz PLLx4, clkdiv6



 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 1750
Re: PIC16F1459 Problem
« Reply #9 on: August 15, 2015, 06:57:02 pm »
o Internal oscillator, no clkdiv
o 12MHz PLLx4, no clkdiv

Can you confirm that the CPU core is operating at 48MHz? I have been looking at your code and, with the exception of the external crystal, I can't see any significant difference in the initialisation.
 

Online Howardlong

  • Super Contributor
  • ***
  • Posts: 4846
  • Country: gb
Re: PIC16F1459 Problem
« Reply #10 on: August 15, 2015, 07:26:05 pm »
I am sure you already know this, but for the avoidance of doubt at clkdiv6, the CPU clock will only run at 8MHz, you need noclkdiv for 48MHz. In main.c, the appropriate lines are commented in and out:

Code: [Select]
//        __CONFIG(WRT_OFF & CPUDIV_NOCLKDIV & USBLSCLK_48MHz & PLLMULT_3x & PLLEN_ENABLED & STVREN_ON &  BORV_LO & LPBOR_OFF & LVP_OFF);
        __CONFIG(WRT_OFF & CPUDIV_CLKDIV6 & USBLSCLK_48MHz & PLLMULT_3x & PLLEN_ENABLED & STVREN_ON &  BORV_LO & LPBOR_OFF & LVP_OFF);

As well as this, the main.h defines the _XTAL_FREQ which is used for __delay_xx() and calculating the I2C baud rate.

Also in main.c:

Code: [Select]
    #if defined(_PIC14E)
        //Configure all pins for digital mode, except RB4, which has a POT on it
        ANSELA = 0x00;
        #if defined(_16F1459) || defined(_16LF1459)
// HL***            ANSELB = 0x10;  //RB4 has a POT on it, on the Low Pin Count USB Dev Kit board
ANSELB=0;
        #endif
        ANSELC = 0x00;
        #if defined (USE_INTERNAL_OSC)
            OSCTUNE = 0;
            OSCCON = 0xFC;          //16MHz HFINTOSC with 3x PLL enabled (48MHz operation)
            ACTCON = 0x90;          //Enable active clock tuning with USB
        #endif
// HL***
MyI2CInit(400000UL); // To the I2C LCD
MyLCDInit();
MyLCDPutS("Hello");
       
    #endif


Also in main.c, in the main while (1) loop generates a pulse, allowing you to check the processor frequency, which in this case is 89ns, close enough to suggest the processor's running at 12MHz, indicating a 48MHz clock. It's the green Ch 2 trace:

Code: [Select]
// HL***
    LATBbits.LATB7=1;
    LATBbits.LATB7=0;



Apologies, it's messy, I just hacked the MLA USB code.
 

Offline cjhofer

  • Contributor
  • Posts: 5
  • Country: us
Re: PIC16F1459 Problem
« Reply #11 on: August 16, 2015, 02:18:24 am »
I found the problem with my code related to the I2C. I did not initialize the ANSELB. Once I set this register to 0 the I2C started working with 48 MHz oscillator. Apparently the I2C will work (at low oscillator speeds) with ANSELB set as analog inputs. Thank everyone for all your help!!!!!
 

Online Howardlong

  • Super Contributor
  • ***
  • Posts: 4846
  • Country: gb
Re: PIC16F1459 Problem
« Reply #12 on: August 16, 2015, 08:32:35 am »
I found the problem with my code related to the I2C. I did not initialize the ANSELB. Once I set this register to 0 the I2C started working with 48 MHz oscillator. Apparently the I2C will work (at low oscillator speeds) with ANSELB set as analog inputs. Thank everyone for all your help!!!!!

Coincidentally, the first time I put my I2C code into the MLA stack yesterday, I had exactly the same problem, but luckily I've been there so often placing a watch on ANSELB was the first place I looked, hence these lines in the code:

Code: [Select]
// HL***            ANSELB = 0x10;  //RB4 has a POT on it, on the Low Pin Count USB Dev Kit board
ANSELB=0;

The other gotcha is to set your TRIS bits to 1 on SDA/SCL, but that is made very clear in the DS.

When I write my own code from scratch, I have a habit of setting all the analogue pins to digital on PICs as a matter of course. Quite why Microchip took the decision to default to analogue I have no idea, I don't know how many man hours have been lost in the history of time to that one. But at least they are consistent about it across the entire range. :palm:
 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 1750
Re: PIC16F1459 Problem
« Reply #13 on: August 16, 2015, 11:43:25 pm »
I found the problem with my code related to the I2C. I did not initialize the ANSELB. Once I set this register to 0 the I2C started working with 48 MHz oscillator. Apparently the I2C will work (at low oscillator speeds) with ANSELB set as analog inputs.
I can confirm this is the case. I've spent the afternoon tracking down this problem because I knew that I had defined the state of the analogue inputs:
Spot the error:
Code: [Select]

      banksel ANSELB         ;Turn off analog
      movlw   0
      movfw   ANSELA
      movfw   ANSELB
      movfw   ANSELC
I am using gputils to assemble the code. The MOVFW is not a standard. It appears that a deep thinking code monkey has done the obvious and defined a the complementary to the instruction that I intended to use (MOVWF). So, a typo, some lazy line-copying, several hours of head scratching and I've learnt something new today :)

I was resigned to accepting this as another quirk of the PIC16F1459 - thanks for the inspiration to find this bug.
« Last Edit: August 16, 2015, 11:50:05 pm by Andy Watson »
 

Online Howardlong

  • Super Contributor
  • ***
  • Posts: 4846
  • Country: gb
Re: PIC16F1459 Problem
« Reply #14 on: August 17, 2015, 06:31:04 am »
So one way or another, all three of us have been caught by the default analogue pins thing.  :palm:
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf