• AVR Freaks

Hot!PIC32mz1024efe100 and MCP7940 - I2C, Harmony

Author
vibhu
Starting Member
  • Total Posts : 49
  • Reward points : 0
  • Joined: 2019/02/25 05:37:34
  • Location: 0
  • Status: offline
2019/04/12 23:23:08 (permalink)
0

PIC32mz1024efe100 and MCP7940 - I2C, Harmony

Hey Guys,

I am trying to read the register 00 from RTC - MCP7940N using I2C in Harmony.

I am not able read the correct values.

I read some blogs and found that I have to turn on the oscillator first, So I modified the code such that the first time the oscillator turns on.

Here is my code,



/*******************************************************************************
MPLAB Harmony Application Source File

Company:
Microchip Technology Inc.

File Name:
app.c

Summary:
This file contains the source code for the MPLAB Harmony application.

Description:
This file contains the source code for the MPLAB Harmony application. It
implements the logic of the application's state machine and it may call
API routines of other MPLAB Harmony modules in the system, such as drivers,
system services, and middleware. However, it does not call any of the
system interfaces (such as the "Initialize" and "Tasks" functions) of any of
the modules in the system or make any assumptions about when those functions
are called. That is the responsibility of the configuration-specific system
files.
*******************************************************************************/

// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved.

Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).

You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.

SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*******************************************************************************/
// DOM-IGNORE-END


// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************


#include "app.h"

static uint32_t ReadCoreTimer(void);

static uint32_t ReadCoreTimer()
{
volatile uint32_t timer;

// get the count reg
asm volatile("mfc0 %0, $9" : "=r"(timer));

return(timer);
}

#define GetSystemClock() (SYS_CLK_FREQ)
#define us_SCALE (GetSystemClock()/2000000)
#define ms_SCALE (GetSystemClock()/2000)

/* Address of slave devices */
#define RTCC_SLAVE_ADDRESS 0x6F

// *****************************************************************************
// *****************************************************************************
// Section: Global Data Definitions
// *****************************************************************************
// *****************************************************************************

DRV_I2C_BUFFER_EVENT i2cOpStatus;

uint8_t operationStatus;

uint8_t deviceAddressSlave =(RTCC_SLAVE_ADDRESS << 1);

//uint8_t deviceAddressSlave1 = RTCC_SLAVE_ADDRESS;

uint8_t numOfTXBytes = 1;

uint8_t numOfRXBytes = 1;

uint8_t indexRegByteSize;

/* I2C Driver TX buffer */
uint8_t OSCCON_REG = 0x00;

/* I2C Driver TX buffer */
uint8_t OSCCON_VAL = 0x80;

/* I2C Driver TX buffer */
uint8_t TXbuffer = 0x00;

/* I2C Driver RX buffer */
uint8_t RXbuffer;

/* I2C driver RX Buffer */
uint8_t OSCCON_FLAG = 0;

uint8_t temp;

uint8_t dec_val;
// *****************************************************************************
/* Application Data

Summary:
Holds application data

Description:
This structure holds the application's data.

Remarks:
This structure should be initialized by the APP_Initialize function.

Application strings and buffers are be defined outside this structure.
*/

APP_DATA appData;

// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Functions
// *****************************************************************************
// *****************************************************************************

void I2CMasterOpStatusCb ( DRV_I2C_BUFFER_EVENT event,
DRV_I2C_BUFFER_HANDLE bufferHandle,
uintptr_t context);

void I2CSlaveOpStatusCb ( DRV_I2C_BUFFER_EVENT event,
DRV_I2C_BUFFER_HANDLE bufferHandle,
uintptr_t context);

// *****************************************************************************
// *****************************************************************************
// Section: Application Local Functions
// *****************************************************************************
// *****************************************************************************

DRV_I2C_BUFFER_EVENT APP_Check_Transfer_Status(DRV_HANDLE drvOpenHandle, DRV_I2C_BUFFER_HANDLE drvBufferHandle);

void DelayMs(unsigned long int msDelay );

void DelayMs(unsigned long int msDelay );


// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

/* State Machine for Master Write */
bool APP_Write_Tasks(void);

/* State Machine for Master Read */
bool APP_Read_Tasks(void);


typedef enum{

TxRx_TO_EXTERNAL_SLAVE_1 = 0,
TxRx_EXTERNAL_SLAVE_STATUS_CHECK_1,
TxRx_TO_EXTERNAL_SLAVE_2,
TxRx_EXTERNAL_SLAVE_STATUS_CHECK_2,
TxRx_TO_EXTERNAL_SLAVE_3,
TxRx_EXTERNAL_SLAVE_STATUS_CHECK_3,
TxRx_STATUS_CHECK,
TxRx_COMPLETED

}APP_EEPROM_WR_STATES;

static APP_EEPROM_WR_STATES appWriteState = TxRx_TO_EXTERNAL_SLAVE_1;

/*******************************************************************************
Function:
void APP_Initialize ( void )

Remarks:
See prototype in app.h.
*/

void APP_Initialize ( void )
{
/* Place the App state machine in its initial state. */
appData.state = APP_STATE_INIT;

/* TODO: Initialize your application's state machine and other
* parameters.
*/
}


/******************************************************************************
Function:
void APP_Tasks ( void )

Remarks:
See prototype in app.h.
*/

void APP_Tasks ( void )
{
/* Check the application's current state. */
switch ( appData.state )
{
/* Application's initial state. */
case APP_STATE_INIT:
{
OSCCON_FLAG = 1;
appData.drvI2CHandle_Master = DRV_I2C_Open(DRV_I2C_INDEX_0, DRV_IO_INTENT_READWRITE);
/* event-handler set up receive callback from DRV_I2C_Tasks */
DRV_I2C_BufferEventHandlerSet(appData.drvI2CHandle_Master, I2CMasterOpStatusCb, i2cOpStatus );

if(appData.drvI2CHandle_Master != (DRV_HANDLE) NULL)
{
appData.state = APP_WRITE_READ_DATA;
}
else
{
appData.state = APP_STATE_ERROR;
}

break;
}
case APP_WRITE_READ_DATA:
{
/* completes write task to the slave */
if(APP_Write_Tasks())
{
appData.state = APP_STATE_IDLE;
}
break;
}
case APP_STATE_IDLE:
{
Nop();
break;
}
default:
{
/* TODO: Handle error in application's state machine. */
break;
}
}
}

bool APP_Write_Tasks(void)
{
switch (appWriteState)
{
case TxRx_TO_EXTERNAL_SLAVE_1:
{
if(OSCCON_FLAG == 1)
{
/* Write Transaction - 1 to RTCC */

if ( (appData.drvI2CTxRxBufferHandle[0] == (DRV_I2C_BUFFER_HANDLE) NULL) ||
(APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[0]) == DRV_I2C_BUFFER_EVENT_COMPLETE) ||
(APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[0]) == DRV_I2C_BUFFER_EVENT_ERROR) )
{

appData.drvI2CTxRxBufferHandle[0] = DRV_I2C_Transmit ( appData.drvI2CHandle_Master,
deviceAddressSlave,
&OSCCON_REG,
numOfTXBytes,
NULL);
}
OSCCON_FLAG = 0;
appWriteState = TxRx_EXTERNAL_SLAVE_STATUS_CHECK_1;
}
else
{
appWriteState = TxRx_TO_EXTERNAL_SLAVE_3;
}
break;
}
case TxRx_EXTERNAL_SLAVE_STATUS_CHECK_1:
{
if ( (APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[0]) == DRV_I2C_BUFFER_EVENT_COMPLETE ) ||
(APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[0]) == DRV_I2C_BUFFER_EVENT_ERROR) )

appWriteState = TxRx_TO_EXTERNAL_SLAVE_2;
else
appWriteState = TxRx_EXTERNAL_SLAVE_STATUS_CHECK_1;

break;
}
case TxRx_TO_EXTERNAL_SLAVE_2:
{

if ( (appData.drvI2CTxRxBufferHandle[1] == (DRV_I2C_BUFFER_HANDLE) NULL) ||
(APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[1]) == DRV_I2C_BUFFER_EVENT_COMPLETE) ||
(APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[1]) == DRV_I2C_BUFFER_EVENT_ERROR) )
{
appData.drvI2CTxRxBufferHandle[1] = DRV_I2C_Transmit ( appData.drvI2CHandle_Master,
deviceAddressSlave,
&OSCCON_VAL,
numOfTXBytes,
NULL);
}

appWriteState = TxRx_EXTERNAL_SLAVE_STATUS_CHECK_2;
break;
}
case TxRx_EXTERNAL_SLAVE_STATUS_CHECK_2:
{
if ( (APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[1]) == DRV_I2C_BUFFER_EVENT_COMPLETE) ||
(APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[1]) == DRV_I2C_BUFFER_EVENT_ERROR) )
appWriteState = TxRx_TO_EXTERNAL_SLAVE_3;
else
appWriteState = TxRx_EXTERNAL_SLAVE_STATUS_CHECK_2;

break;
}

case TxRx_TO_EXTERNAL_SLAVE_3:
{

if ( (appData.drvI2CTxRxBufferHandle[2] == (DRV_I2C_BUFFER_HANDLE) NULL) ||
(APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[5]) == DRV_I2C_BUFFER_EVENT_COMPLETE) ||
(APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[5]) == DRV_I2C_BUFFER_EVENT_ERROR) )
{
appData.drvI2CTxRxBufferHandle[2] = DRV_I2C_TransmitThenReceive ( appData.drvI2CHandle_Master,
deviceAddressSlave,
&TXbuffer,
numOfTXBytes,
&RXbuffer,
numOfRXBytes,
NULL);
temp = RXbuffer;
temp = temp & 0x7F;
dec_val = (temp/16)*10+(temp%16);
SYS_PRINT("RX BUFFER : %d",dec_val);
}


appWriteState = TxRx_EXTERNAL_SLAVE_STATUS_CHECK_3;

break;
}
case TxRx_EXTERNAL_SLAVE_STATUS_CHECK_3:
{
if ( (APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[2]) == DRV_I2C_BUFFER_EVENT_COMPLETE) ||
(APP_Check_Transfer_Status(appData.drvI2CHandle_Master, appData.drvI2CTxRxBufferHandle[2]) == DRV_I2C_BUFFER_EVENT_ERROR) )
appWriteState = TxRx_STATUS_CHECK;
else
appWriteState = TxRx_EXTERNAL_SLAVE_STATUS_CHECK_3;

break;
}
case TxRx_STATUS_CHECK:
{
DelayMs(300);
appWriteState = TxRx_TO_EXTERNAL_SLAVE_1;

break;
}
case TxRx_COMPLETED:
{
return true;
break;
}
}

return false;
}

//****************************************************************************/
// Function: APP_Check_Transfer_Status
//
// Returns the status of Buffer operation from the driver; The application
// can probe this function to see if the status of a particular I2C
// transfer is in its execution
//****************************************************************************/
DRV_I2C_BUFFER_EVENT APP_Check_Transfer_Status(DRV_HANDLE drvOpenHandle, DRV_I2C_BUFFER_HANDLE drvBufferHandle)
{
return (DRV_I2C_TransferStatusGet (appData.drvI2CHandle_Master, drvBufferHandle));
}

//****************************************************************************/
// Function: Master Callback Function
//
// Callback from DRV_I2C_Tasks when I2C is configured in Master mode
//****************************************************************************/

void I2CMasterOpStatusCb ( DRV_I2C_BUFFER_EVENT event,
DRV_I2C_BUFFER_HANDLE bufferHandle,
uintptr_t context)
{
static uint32_t successCount = 0;

switch (event)
{
case DRV_I2C_BUFFER_EVENT_COMPLETE:
successCount++;
Nop();
break;
case DRV_I2C_BUFFER_EVENT_ERROR:
successCount--;
break;
default:
break;
}
}

//****************************************************************************/
// Function: Slave Callback Function
//
// Callback from DRV_I2C_Tasks when I2C is configured in Slave mode
//****************************************************************************/

void I2CSlaveOpStatusCb ( DRV_I2C_BUFFER_EVENT event,
DRV_I2C_BUFFER_HANDLE bufferHandle,
uintptr_t context)
{
Nop();
}

/***********************************************************
* Millisecond Delay function using the Count register
* in coprocessor 0 in the MIPS core.
* When running 200 MHz, CoreTimer frequency is 100 MHz
* CoreTimer increments every 2 SYS_CLK, CoreTimer period = 10ns
* 1 ms = N x CoreTimer_period;
* To count 1ms, N = 100000 counts of CoreTimer
* 1 ms = 10 ns * 100000 = 10e6 ns = 1 ms
* When running 80 MHz, CoreTimer frequency is 40 MHz
* CoreTimer increments every 2 SYS_CLK, CoreTimer period = 25ns
* To count 1ms, N = 40000 counts of CoreTimer
* 1ms = 25 ns * 40000 = 10e6 ns = 1 ms
* ms_SCALE = (GetSystemClock()/2000) @ 200 MHz = 200e6/2e3 = 100e3 = 100000
* ms_SCLAE = (GetSystemClock()/2000) @ = 80e6/2e3 = 40e3 = 40000
*/

void DelayMs(unsigned long int msDelay )
{
register unsigned int startCntms = ReadCoreTimer();
register unsigned int waitCntms = msDelay * ms_SCALE;

while( ReadCoreTimer() - startCntms < waitCntms );
}

/***********************************************************
* Microsecond Delay function using the Count register
* in coprocessor 0 in the MIPS core.
* When running 200 MHz, CoreTimer frequency is 100 MHz
* CoreTimer increments every 2 SYS_CLK, CoreTimer period = 10ns
* 1 us = N x CoreTimer_period;
* To count 1us, N = 100 counts of CoreTimer
* 1 us = 10 ns * 100 = 1000 ns = 1us
* When running 80 MHz, CoreTimer frequency is 40 MHz
* CoreTimer increments every 2 SYS_CLK, CoreTimer period = 25ns
* To count 1us, N = 40 counts of CoreTimer
* 1us = 25 ns * 40 = 1000 ns = 1 us
* us_SCALE = (GetSystemClock()/2000) @ 200 MHz = 200e6/2e6 = 100
* us_SCLAE = (GetSystemClock()/2000) @ 80 MHz = 80e6/2e6 = 40
*/

void DelayUs(unsigned long int usDelay )
{
register unsigned int startCnt = ReadCoreTimer();
register unsigned int waitCnt = usDelay * us_SCALE;

while( ReadCoreTimer() - startCnt < waitCnt );
}

/*******************************************************************************
End of File
*/





So the address of the slave which I am using is 0x6F.

I first have to enable the oscillator so the sequence is,

write 0x80 value to 0x00 register of my slave

then write 0x00(the register which I have to read) and read from the register.

So here am doing two I2C_transmit and a I2C_transmitandthenreceive.



I am getting only zeros and I am not able to debug the code.

Since the sensor gives out BCD values I am converting it into Decimal before printing it.

When I try to debug the code, am getting

PIC32 runtime exception detected. Use Call Stack window to resolve source line location.

I have attached the screenshot of the error when I tried to use the call stack window.



I tried probing the pins in the CRO and the result also am attaching along.



I am using MPLAB XIDE V5.15 and MHC v2.0.5.2.

Can anyone help me out in getting the data from the RTC.



Thanks,

Vibhu.

Attached Image(s)

#1

16 Replies Related Threads

    NKurzman
    A Guy on the Net
    • Total Posts : 17236
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/13 00:05:17 (permalink)
    0
    If you do not get it working by late Monday (EST), bump the thread. I have it working.
    #2
    NKurzman
    A Guy on the Net
    • Total Posts : 17236
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/15 14:20:01 (permalink)
    0
    Read reg 7
    if  oscrun == 3 or vbat_en == 0 then you need to init the MCP7940
    set start = 1
    vbat_en  = 1
    pwr_fail  =  0
    mode12hour to the mode you need.
    Additionally you can set RTC_REG_CNTRL and RTC_REG_OSCTRIM to 0 to insure they are at defaults.
    And you will need to set the Time.
     
    Note if the Power fail is set , then the RAM is not valid.
     
     
     
     
     
     
     
    #3
    vibhu
    Starting Member
    • Total Posts : 49
    • Reward points : 0
    • Joined: 2019/02/25 05:37:34
    • Location: 0
    • Status: offline
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/15 21:31:52 (permalink)
    0
    If we just read the register 0x00 without any time settings wont it give output from 0 to 59 ?
    Even in 0x01 wont it give starting from 0?
    I mean the initial values for time will be zero right ? I should be able to read that without setting the time?
     
     
    post edited by vibhu - 2019/04/15 21:34:45
    #4
    NKurzman
    A Guy on the Net
    • Total Posts : 17236
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/15 22:17:34 (permalink)
    0
    I do not know what they have. I did this over 2 years ago. You would have to read the data sheet
    But you need to set the flags I noted to make it run.
    #5
    vibhu
    Starting Member
    • Total Posts : 49
    • Reward points : 0
    • Joined: 2019/02/25 05:37:34
    • Location: 0
    • Status: offline
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/15 22:24:27 (permalink)
    0
    If I use a non-harmony, standalone code, I am able to read the register and its giving from 0.
    Only in the above code which I have mentioned its not working.
    Is there any corrections in the code ? I think the write is also not happening.
    Is the slave address correct ? The slave address is 0x6F. Should I give it as such and it will shift the bits or should I shift and then give ?
     
    #6
    NKurzman
    A Guy on the Net
    • Total Posts : 17236
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/15 23:45:11 (permalink)
    0
    The register? Which one?
    #7
    vibhu
    Starting Member
    • Total Posts : 49
    • Reward points : 0
    • Joined: 2019/02/25 05:37:34
    • Location: 0
    • Status: offline
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/16 00:25:30 (permalink)
    0
    NKurzman
    The register? Which one?

    If I read 0x00 for every second its giving values from 0 to 59 and even 0x01 if I read its changing for every minute starting from 0.
    #8
    vibhu
    Starting Member
    • Total Posts : 49
    • Reward points : 0
    • Joined: 2019/02/25 05:37:34
    • Location: 0
    • Status: offline
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/16 23:52:48 (permalink)
    0
    Do you have a working Harmony code for the RTC?
    #9
    NKurzman
    A Guy on the Net
    • Total Posts : 17236
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/17 00:24:38 (permalink)
    0
    Yes but not with the Harmony I2C library.
    And no I can’t give you a copy, it is a work for hire.
    #10
    vibhu
    Starting Member
    • Total Posts : 49
    • Reward points : 0
    • Joined: 2019/02/25 05:37:34
    • Location: 0
    • Status: offline
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/17 04:39:58 (permalink)
    0

    // PIC32MZ1024EFE100 Configuration Bit Settings
    // 'C' source line config statements
    // DEVCFG3
    #pragma config USERID = 0xFFFF // Enter Hexadecimal value (Enter Hexadecimal value)
    #pragma config FMIIEN = OFF
    #pragma config FETHIO = OFF
    #pragma config PGL1WAY = OFF
    #pragma config PMDL1WAY = OFF
    #pragma config IOL1WAY = OFF
    #pragma config FUSBIDIO = OFF
    // DEVCFG2
    #pragma config FPLLIDIV = DIV_3 // System PLL Input Divider (3x Divider)
    #pragma config FPLLRNG = RANGE_5_10_MHZ // System PLL Input Range (5-10 MHz Input)
    #pragma config FPLLICLK = PLL_POSC // System PLL Input Clock Selection (POSC is input to the System PLL)
    #pragma config FPLLMULT = MUL_50 // System PLL Multiplier (PLL Multiply by 100)
    #pragma config FPLLODIV = DIV_2 // System PLL Output Clock Divider (2x Divider)
    #pragma config UPLLFSEL = FREQ_12MHZ // USB PLL Input Frequency Selection (USB PLL input is 12 MHz)
    // DEVCFG1
    #pragma config FNOSC = SPLL // Oscillator Selection Bits (System PLL)
    #pragma config DMTINTV = WIN_127_128 // DMT Count Window Interval (Window/Interval value is 127/128 counter value)
    #pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disable SOSC)
    #pragma config IESO = OFF // Internal/External Switch Over (Disabled)
    #pragma config POSCMOD = OFF // Primary Oscillator Configuration (External Clock signal)
    #pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
    #pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disabled, FSCM Disabled)
    #pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
    #pragma config WDTSPGM = STOP // Watchdog Timer Stop During Flash Programming (WDT stops during Flash programming)
    #pragma config WINDIS = NORMAL // Watchdog Timer Window Mode (Watchdog Timer is in non-Window mode)
    #pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled)
    #pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size (Window size is 25%)
    #pragma config DMTCNT = DMT31 // Deadman Timer Count Selection (2^31 (2147483648))
    #pragma config FDMTEN = OFF // Deadman Timer Enable (Deadman Timer is disabled)
    // DEVCFG0
    #pragma config DEBUG = ON // Background Debugger Enable (Debugger is disabled)
    #pragma config JTAGEN = ON // JTAG Enable (JTAG Disabled)
    #pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (Communicate on PGEC2/PGED2)
    #pragma config TRCEN = OFF // Trace Enable (Trace features in the CPU are disabled)
    #pragma config BOOTISA = MIPS32 // Boot ISA Selection (Boot code and Exception code is MIPS32)
    #pragma config FECCCON = OFF_UNLOCKED // Dynamic Flash ECC Configuration (ECC and Dynamic ECC are disabled (ECCCON bits are writable))
    #pragma config FSLEEP = OFF // Flash Sleep Mode (Flash is powered down when the device is in Sleep mode)
    #pragma config DBGPER = PG_ALL // Debug Mode CPU Access Permission (Allow CPU access to all permission regions)
    #pragma config SMCLR = MCLR_NORM // Soft Master Clear Enable bit (MCLR pin generates a normal system Reset)
    #pragma config SOSCGAIN = GAIN_2X // Secondary Oscillator Gain Control bits (2x gain setting)
    #pragma config SOSCBOOST = ON // Secondary Oscillator Boost Kick Start Enable bit (Boost the kick start of the oscillator)
    #pragma config POSCGAIN = GAIN_2X // Primary Oscillator Gain Control bits (2x gain setting)
    #pragma config POSCBOOST = ON // Primary Oscillator Boost Kick Start Enable bit (Boost the kick start of the oscillator)
    #pragma config EJTAGBEN = NORMAL // EJTAG Boot (Normal EJTAG functionality)
    // DEVCP0
    #pragma config CP = OFF // Code Protect (Protection Disabled)
    #include <xc.h>
    #define SYS_FREQ 200000000
    #define dev_address 0x6F // Slave address
    #define register_add 0x00 // Register to be read
    #define OSC_ON_REG 0x00 // Register to ON the oscillator

    unsigned char value;
    unsigned char val;
    void delay_us(unsigned int us)
    {

    // Convert microseconds us into how many clock ticks it will take
    us *= (SYS_FREQ / 1000000) / 2; // Core Timer updates every 2 ticks
    _CP0_SET_COUNT(0); // Set Core Timer count to 0
    while (us > _CP0_GET_COUNT()); // Wait until Core Timer count reaches the number we calculated earlier
    }
    void delay_ms(unsigned int ms)
    {
    delay_us(ms * 1000);
    }
    // I2C_wait_for_idle() waits until the I2C peripheral is no longer doing anything
    void I2C_wait_for_idle(void)
    {
    while(I2C1CON & 0x1F); // Acknowledge sequence not in progress
    // Receive sequence not in progress
    // Stop condition not in progress
    // Repeated Start condition not in progress
    // Start condition not in progress
    while(I2C1STATbits.TRSTAT); // Bit = 0 ? Master transmit is not in progress
    }
    // I2C_start() sends a start condition
    void I2C_start()
    {
    I2C_wait_for_idle();
    I2C1CONbits.SEN = 1;
    while (I2C1CONbits.SEN == 1);
    }
    // I2C_stop() sends a stop condition
    void I2C_stop()
    {
    I2C_wait_for_idle();
    I2C1CONbits.PEN = 1;
    while (I2C1CONbits.PEN == 1);
    }
    // I2C_restart() sends a repeated start/restart condition
    void I2C_restart()
    {
    I2C_wait_for_idle();
    I2C1CONbits.RSEN = 1;
    while (I2C1CONbits.RSEN == 1);
    }
    // I2C_ack() sends an ACK condition
    void I2C_ack(void)
    {
    I2C_wait_for_idle();
    I2C1CONbits.ACKDT = 0; // Set hardware to send ACK bit
    I2C1CONbits.ACKEN = 1; // Send ACK bit, will be automatically cleared by hardware when sent
    while(I2C1CONbits.ACKEN); // Wait until ACKEN bit is cleared, meaning ACK bit has been sent
    }
    // I2C_nack() sends a NACK condition
    void I2C_nack(void) // Acknowledge Data bit
    {
    I2C_wait_for_idle();
    I2C1CONbits.ACKDT = 1; // Set hardware to send NACK bit
    I2C1CONbits.ACKEN = 1; // Send NACK bit, will be automatically cleared by hardware when sent
    while(I2C1CONbits.ACKEN); // Wait until ACKEN bit is cleared, meaning NACK bit has been sent
    }
    // address is I2C slave address, set wait_ack to 1 to wait for ACK bit or anything else to skip ACK checking
    void I2C_write(unsigned char address, char wait_ack)
    {
    I2C1TRN = address; //| 0 // Send slave address with Read/Write bit cleared
    I2C_wait_for_idle(); // Wait until I2C bus is idle
    if (wait_ack)
    while (I2C1STATbits.ACKSTAT == 1); // Wait until ACK is received
    }
    // value is the value of the data we want to send, set ack_nack to 0 to send an ACK or anything else to send a NACK
    unsigned char I2C_read(char ack_nack)
    {
    I2C1CONbits.RCEN = 1; // Receive enable
    value = I2C1RCV;
    if (ack_nack == 1) // Do we need to send an ACK or a NACK?
    I2C_ack(); // Send ACK
    else
    I2C_nack(); // Send NACK
    }
    void Write(unsigned char reg_address, unsigned char value)
    {
    I2C_start(); /* Send start condition */
    I2C_write(dev_address << 1 | 0, 1); /* Send device address, read/write bit set AD */
    I2C_write(reg_address, 1); /* Send the register address (RA) */
    I2C_write(value, 1); /* Send the value to set it to */
    I2C_stop();
    }
    unsigned char Read(unsigned char reg_address)
    {
    I2C_start(); /* Send start condition */
    I2C_write(dev_address << 1 | 0, 1); /* Send device address */
    I2C_write(reg_address, 1); /* Send the register address (RA) */
    I2C_restart(); /* Send repeated start condition */
    I2C_write(dev_address << 1 | 1, 1); /* Send device address */
    val = I2C_read(0); /* Read value from the I2C bus */
    I2C_stop(); /* Send stop condition */
    return value;
    }
    // I2C_init() initialises I2C1 at frequency of [frequency]Hz
    void I2C_init(double frequency)
    {
    double BRG;

    I2C1CON = 0; // Turn off I2C1 module
    I2C1CONbits.DISSLW = 1; // Disable slew rate for 100kHz

    BRG = (1 / (2 * frequency)) - 0.000000104;
    BRG *= (SYS_FREQ / 2) - 2;

    I2C1BRG = (int)BRG; // Set baud rate
    I2C1CONbits.ON = 1;
    }
    void uart_init()
    {
    RPD5Rbits.RPD5R = 2; 
    U2RXRbits.U2RXR = 4; 
    ANSELBbits.ANSB5 = 0;
    LATBbits.LATB5 = 0;
    LATFbits.LATF5 = 0;


    TRISDbits.TRISD5 = 0;
    TRISDbits.TRISD4 = 1; /* U2RX must be Input. */
    U2MODEbits.ON = 0; /* Do Not enable peripheral until setup is complete. */
    U2MODEbits.BRGH = 0;
    U2BRG = 55; // 4800 Baud rate
    U2MODEbits.STSEL = 0;
    U2MODEbits.PDSEL = 0b00;
    U2STAbits.UTXISEL = 0b10;
    U2STAbits.UTXEN = 1;
    U2MODEbits.UEN = 0b00;
    U2MODEbits.ON = 1;
    }
    unsigned char main()
    {
    uint8_t dec_val;
    // Enable multi-vectored interrupts mode
    INTCONbits.MVEC = 1;
    // Initialise I2C1 at 100kHz
    I2C_init(100000);
    uart_init();
    Write(OSC_ON_REG,0x80);
    while (1)
    {
    val = Read(register_add);
    val = val & 0x7F;
    dec_val = (val/16)*10+(val%16);
    while (U2STAbits.UTXBF); // Wait while buffer is full
    U2TXREG = (unsigned char)dec_val;
    delay_ms(44);
    }
    }

    This code is working fine and I am trying to implement same in Harmony.
    If I read 0x00 for every second its giving incremental values from 0 to 59 and even 0x01 if I read its changing for every minute starting from 0.
    Can you please tell me where I am going wrong in the Harmony code?
     
     
    #11
    NKurzman
    A Guy on the Net
    • Total Posts : 17236
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/17 09:26:39 (permalink)
    0
    The first 7 bits of Byte 0 is seconds so 0-59 is correct.  The MSB is the Start bit.  You need to set that to 1  (0x80)  start bit must be set to start the oscillator.
    Byte one is Minutes
    Byte 2 is Hours.
    the Chip Address is 0b11011110  (0xDE)  or 0x6F in 7 bit format
     
    I am no longer clear about what you problem is.
    Please restate it.
    #12
    vibhu
    Starting Member
    • Total Posts : 49
    • Reward points : 0
    • Joined: 2019/02/25 05:37:34
    • Location: 0
    • Status: offline
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/18 06:00:11 (permalink)
    0
    The code which I shared in #11 is working.
    But the code which I shared in #1 is not working.
    In code #1 I am trying to do the same as in code #11 but in Harmony, and its not working.
    I am new to harmony and I am not sure where the problem is.
    So can you please tell me what is wrong with #1 code and why it is not working and code #11 is working? I guess am doing the same operations as in code #11 in code  #1.
    #13
    NKurzman
    A Guy on the Net
    • Total Posts : 17236
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/18 06:39:15 (permalink)
    0
    What does “not working” mean?
    The code in #11 works on that chip? Or is it from a different project?
    #14
    vibhu
    Starting Member
    • Total Posts : 49
    • Reward points : 0
    • Joined: 2019/02/25 05:37:34
    • Location: 0
    • Status: offline
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/18 20:25:59 (permalink)
    0
    Code #11 works on the same chip, but code #1 is not. I am using pic32mz1024efe100. I think there is some problem in the code. There is only 00 in the RX_buffer.
    #15
    NKurzman
    A Guy on the Net
    • Total Posts : 17236
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/18 23:49:48 (permalink)
    0
    If your problem is with harmony and not the communication with the chip, then I can’t help you I’m not familiar with the harmony I2C Driver.
    #16
    vibhu
    Starting Member
    • Total Posts : 49
    • Reward points : 0
    • Joined: 2019/02/25 05:37:34
    • Location: 0
    • Status: offline
    Re: PIC32mz1024efe100 and MCP7940 - I2C, Harmony 2019/04/19 08:25:19 (permalink)
    0
    Can anyone else help me with it?
    #17
    Jump to:
    © 2019 APG vNext Commercial Version 4.5