PIC16F1619 and OLED SSD1306 on I2C Driving me MAD

Enhanced mid-range devices. PIC12F1xxx and PIC16F1xxx

PIC16F1619 and OLED SSD1306 on I2C Driving me MAD

Postby sgdelectronics » Fri Nov 11, 2016 10:11 pm

Hi everyone,

This is my first time posting after nearly 4 weeks of being driven mad by this issue. I am new to PIC development so please bare with me, also, I notice there are a number of posts but very few I can find that are using I2C_MasterWrite().

Please could anyone have a look through my code and see where I might be going wrong?

I am using the PIC16F1619 on the Microchip Curiosity board and trying to initialise the OLED module based on the SSD1306 driver which has the address 0x78 AND 0x7A on the back.

I am using the internal oscillator on 16 MHz and the MSSP Module/IC2 on 400 kHz.

I am using PIN 13/RB4 as SDA and PIN 11/RB6 as SCL (Default settings from Code Configuration)
The link to the datasheet if required is: https://cdn-shop.adafruit../datasheets/SSD1306.pdf

I am also coding in C using XC8 and used MPLAB Code Configuration, also, I should mention that I have gotten this device running no issues on an Arduino board so I know the device is not faulty, and I am using 10K pull up resistors.

I do know this chip is not ideal only having 1KB ram but I am only trying to get the initialise running and not trying to do anything special at this stage, I plan to move to a higher spec PIC.

Last but not least, I have what seems to be valid readings on my Osciliscope, and due to issues with address bit shifting it appears that Ox3C is the correct address as I get the status I2C_MESSAGE_SENT but if I use any other address I get the ACK not received or MESSSAGE_FAIL, so I really think I am so close.

Here is my code and settings, and thank you very much in advance for any support provided.

1. Main code:

Code: Select all
#include "mcc_generated_files/mcc.h"

I2C_MESSAGE_STATUS MSG_STATUS;
I2C_MESSAGE_STATUS* PT_MSG_STATUS;
   


   
uint8_t DeviceAddress = 0x3c;




#define SSD1306_SETCONTRAST 0x81
#define SSD1306_ENTIREDISPLAYON_RESUME 0xA4
#define SSD1306_ENTIREDISPLAYON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF

/* Scrolling Command */
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_ACTIVATE_SCROLL 0x2F
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3

/* Addressing Setting Command */
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR 0x22
#define SSD1306_PAGESTARTADDR 0xB0



#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_SETMULTIPLEXRATIO 0xA8
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA

/* Timing and Driving Scheme Setting Command */
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_NOP 0xE3

#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2

#define SSD1306_CL_WHITE 0
#define SSD1306_CL_BLACK 1



void Oled_Command(uint8_t command)
{
   PT_MSG_STATUS = &MSG_STATUS;

   I2C_MasterWrite(DeviceAddress,1,DeviceAddress,PT_MSG_STATUS);
   
   I2C_MasterWrite(0x00,1,DeviceAddress,PT_MSG_STATUS);
   
   I2C_MasterWrite(command,1,DeviceAddress,PT_MSG_STATUS);
   
   
}





void main(void)
{
    // initialize the device
    SYSTEM_Initialize();

    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:

    // Enable the Global Interrupts
    INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts
    INTERRUPT_PeripheralInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();
   
   
 
   
Oled_Command(0xAE); // Set Display OFF
Oled_Command(0x81); Oled_Command(0xCF); // Set Contrast Control
Oled_Command(0xA4); // Entire Display ON
Oled_Command(0xA6); // Set Normal

Oled_Command(0x20); Oled_Command(0x02); // Set Memory Addressing Mode
Oled_Command(0x00); // Set Lower Column
Oled_Command(0x10); // Set Higher Column
Oled_Command(0xB0); // Set Page Start

Oled_Command(0x40); // Set Display Start Line
Oled_Command(0xA1); // Set Segment Re-map
Oled_Command(0xA8); Oled_Command(0x3F); // Set Multiplex Ratio
Oled_Command(0xC8); // Set COM Output
Oled_Command(0xD3); Oled_Command(0x00); // Set Display Offset
Oled_Command(0xDA); Oled_Command(0x12); // Set COM Pins Hardware Configuration

Oled_Command(0xD5); Oled_Command(0x80); // Set Display Clock
Oled_Command(0xD9); Oled_Command(0xF1); // Set Pre-charge Period
Oled_Command(0xDB); Oled_Command(0x40); // Set VCOMH Deselect Level
Oled_Command(0x8D); Oled_Command(0x14); // Charge Pump Setting

Oled_Command(0xAF); // Set Display ON


   
   
   
    while (1)
    {
        // Add your application code
    }
}
/**
 End of File
*/


2. Pin Configuration:

Code: Select all
#include <xc.h>
#include "pin_manager.h"
#include "stdbool.h"


void PIN_MANAGER_Initialize(void)
{
    /**
    LATx registers
    */
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;

    /**
    TRISx registers
    */
    TRISA = 0x37;
    TRISB = 0xF0;
    TRISC = 0xFF;

    /**
    ANSELx registers
    */
    ANSELC = 0xCF;
    ANSELB = 0xA0;
    ANSELA = 0x17;

    /**
    WPUx registers
    */
    WPUB = 0xA0;
    WPUA = 0x3F;
    WPUC = 0xFF;
    OPTION_REGbits.nWPUEN = 0;

    /**
    ODx registers
    */
    ODCONA = 0x00;
    ODCONB = 0x00;
    ODCONC = 0x00;
   


   
   
   
    bool state = GIE;
    GIE = 0;
    PPSLOCK = 0x55;
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0x00; // unlock PPS

    SSPCLKPPS = 0x0E; //RB6->MSSP:SCL;
    SSPDATPPS = 0x0C; //RB4->MSSP:SDA;
    RB6PPS = 0x10; //RB6->MSSP:SCL;
    RB4PPS = 0x11; //RB4->MSSP:SDA;

    PPSLOCK = 0x55;
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0x01; // lock PPS

    GIE = state;
}

void PIN_MANAGER_IOC(void)
{

}

/**
 End of File
*/


3. Other:

Code: Select all
#include "interrupt_manager.h"
#include "mcc.h"

void interrupt INTERRUPT_InterruptManager (void)
{
    // interrupt handler
    if(INTCONbits.PEIE == 1 && PIE2bits.BCL1IE == 1 && PIR2bits.BCL1IF == 1)
    {
        I2C_BusCollisionISR();
    }
    else if(INTCONbits.PEIE == 1 && PIE1bits.SSP1IE == 1 && PIR1bits.SSP1IF == 1)
    {
        I2C_ISR();
    }
    else
    {
        //Unhandled Interrupt
    }
}
/**
 End of File
*/

MCC Generated Code:

**
  @Generated MPLAB(c) Code Configurator Source File

  @Company:
    Microchip Technology Inc.

  @File Name:
    mcc.c

  @Summary:
    This is the mcc.c file generated using MPLAB(c) Code Configurator

  @Description:
    This header file provides implementations for driver APIs for all modules selected in the GUI.
    Generation Information :
        Product Revision : MPLAB(c) Code Configurator - 4.0
        Device : PIC16F1619
        Driver Version : 1.02
    The generated drivers are tested against the following:
        Compiler : XC8 1.35
        MPLAB : MPLAB X 3.40
*/

/*
    (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this
    software and any derivatives exclusively with Microchip products.

    THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
    EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
    WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
    PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
    WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.

    IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
    INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
    WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
    BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
    FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
    ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
    THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.

    MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
    TERMS.
*/

// Configuration bits: selected in the GUI

// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection Bits->INTOSC oscillator: I/O function on CLKIN pin
#pragma config PWRTE = OFF // Power-up Timer Enable->PWRT disabled
#pragma config MCLRE = ON // MCLR Pin Function Select->MCLR/VPP pin function is MCLR
#pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled
#pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset enabled
#pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
#pragma config IESO = ON // Internal/External Switch Over->Internal External Switch Over mode is enabled
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is enabled

// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off
#pragma config PPS1WAY = ON // Peripheral Pin Select one-way control->The PPSLOCK bit cannot be cleared once it is set by software
#pragma config ZCD = OFF // Zero Cross Detect Disable Bit->ZCD disable. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
#pragma config PLLEN = ON // PLL Enable Bit->4x PLL is always enabled
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset
#pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected.
#pragma config LPBOR = OFF // Low-Power Brown Out Reset->Low-Power BOR is disabled
#pragma config LVP = ON // Low-Voltage Programming Enable->Low-voltage programming enabled

// CONFIG3
#pragma config WDTCPS = WDTCPS1F // WDT Period Select->Software Control (WDTPS)
#pragma config WDTE = OFF // Watchdog Timer Enable->WDT disabled
#pragma config WDTCWS = WDTCWSSW // WDT Window Select->Software WDT window size control (WDTWS bits)
#pragma config WDTCCS = SWC // WDT Input Clock Selector->Software control, controlled by WDTCS bits

#include "mcc.h"

void SYSTEM_Initialize(void)
{
   
    PIN_MANAGER_Initialize();
    OSCILLATOR_Initialize();
    I2C_Initialize();
}

void OSCILLATOR_Initialize(void)
{
    // SCS FOSC; SPLLEN disabled; IRCF 16MHz_HF;
    OSCCON = 0x78;
    // TUN 0;
    OSCTUNE = 0x00;
    // Set the secondary oscillator
   
    // Wait for PLL to stabilize
    while(PLLR == 0)
    {
    }
}


       
/**
 End of File
*/
sgdelectronics
 
Posts: 1
Joined: Fri Nov 11, 2016 10:05 pm

Re: PIC16F1619 and OLED SSD1306 on I2C Driving me MAD

Postby ric » Sun Nov 27, 2016 12:48 pm

Sorry about the delay approving this post, I missed seeing it waiting for moderation.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products


Return to 14-Bit Core (enhanced)

Who is online

Users browsing this forum: No registered users and 2 guests

cron