Forum: Mikrocontroller und Digitale Elektronik pic16f18857 not working - I2C.


von microMan (Gast)


Lesenswert?

Hello,

i tried to get the I2C on my pic16f18857 @ 3V3 running but i only see 
low potential on the lines.

- SCL: RC5
- SDA: RC6
- Both pulled to 3,3V with 2k2
- the pic should be a I2C Master @ 400khz
- Adress of Slave: 0x80

Here is my config generated in MCC 3.15 (ported to the pic16f18857 from 
the generated pic16f18854 files):

i2c1.h:
1
/**
2
  I2C1 Generated Driver File
3
4
  @Company
5
    Microchip Technology Inc.
6
7
  @File Name
8
    i2c1.c
9
10
  @Summary
11
    This is the generated header file for the I2C1 driver using MPLAB(c) Code Configurator
12
13
  @Description
14
    This header file provides APIs for driver for I2C1.
15
    Generation Information :
16
        Product Revision : MPLAB(c) Code Configurator - 3.15.0
17
        Device : PIC16F18854
18
        Driver Version : 2.00
19
    The generated drivers are tested against the following:
20
        Compiler : XC8 1.35
21
        MPLAB : MPLAB X 3.20
22
*/
23
24
/*
25
    (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this
26
    software and any derivatives exclusively with Microchip products.
27
28
    THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
29
    EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
30
    WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
31
    PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
32
    WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
33
34
    IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
35
    INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
36
    WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
37
    BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
38
    FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
39
    ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
40
    THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
41
42
    MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
43
    TERMS.
44
*/
45
46
/**
47
  Section: Included Files
48
*/
49
50
#include "i2c1.h"
51
52
/**
53
  I2C Driver Queue Status Type
54
55
  @Summary
56
    Defines the type used for the transaction queue status.
57
58
  @Description
59
    This defines type used to keep track of the queue status.
60
 */
61
62
typedef union
63
{
64
    struct
65
    {
66
            uint8_t full:1;
67
            uint8_t empty:1;
68
            uint8_t reserved:6;
69
    }s;
70
    uint8_t status;
71
}I2C_TR_QUEUE_STATUS;
72
73
/**
74
  I2C Driver Queue Entry Type
75
76
  @Summary
77
    Defines the object used for an entry in the i2c queue items.
78
79
  @Description
80
    This defines the object in the i2c queue. Each entry is a composed
81
    of a list of TRBs, the number of the TRBs and the status of the
82
    currently processed TRB.
83
 */
84
typedef struct
85
{
86
    uint8_t count; // a count of trb's in the trb list
87
    I2C1_TRANSACTION_REQUEST_BLOCK *ptrb_list; // pointer to the trb list
88
    I2C1_MESSAGE_STATUS *pTrFlag; // set with the error of the last trb sent.
89
                                                        // if all trb's are sent successfully,
90
                                                        // then this is I2C1_MESSAGE_COMPLETE
91
} I2C_TR_QUEUE_ENTRY;
92
93
/**
94
  I2C Master Driver Object Type
95
96
  @Summary
97
    Defines the object that manages the i2c master.
98
99
  @Description
100
    This defines the object that manages the sending and receiving of
101
    i2c master transactions.
102
  */
103
104
typedef struct
105
{
106
    /* Read/Write Queue */
107
    I2C_TR_QUEUE_ENTRY *pTrTail; // tail of the queue
108
    I2C_TR_QUEUE_ENTRY *pTrHead; // head of the queue
109
    I2C_TR_QUEUE_STATUS trStatus; // status of the last transaction
110
    uint8_t i2cDoneFlag; // flag to indicate the current
111
                                                    // transaction is done
112
    uint8_t i2cErrors; // keeps track of errors
113
114
115
} I2C_OBJECT ;
116
117
/**
118
  I2C Master Driver State Enumeration
119
120
  @Summary
121
    Defines the different states of the i2c master.
122
123
  @Description
124
    This defines the different states that the i2c master
125
    used to process transactions on the i2c bus.
126
*/
127
128
typedef enum
129
{
130
    S_MASTER_IDLE,
131
    S_MASTER_RESTART,
132
    S_MASTER_SEND_ADDR,
133
    S_MASTER_SEND_DATA,
134
    S_MASTER_SEND_STOP,
135
    S_MASTER_ACK_ADDR,
136
    S_MASTER_RCV_DATA,
137
    S_MASTER_RCV_STOP,
138
    S_MASTER_ACK_RCV_DATA,
139
    S_MASTER_NOACK_STOP,
140
    S_MASTER_SEND_ADDR_10BIT_LSB,
141
    S_MASTER_10BIT_RESTART,
142
    
143
} I2C_MASTER_STATES;
144
145
/**
146
 Section: Macro Definitions
147
*/
148
149
/* defined for I2C1 */
150
151
#ifndef I2C1_CONFIG_TR_QUEUE_LENGTH
152
        #define I2C1_CONFIG_TR_QUEUE_LENGTH 1
153
#endif
154
155
#define I2C1_TRANSMIT_REG SSP1BUF // Defines the transmit register used to send data.
156
#define I2C1_RECEIVE_REG SSP1BUF // Defines the receive register used to receive data.
157
158
// The following control bits are used in the I2C state machine to manage
159
// the I2C module and determine next states.
160
#define I2C1_WRITE_COLLISION_STATUS_BIT SSP1CON1bits.WCOL // Defines the write collision status bit.
161
#define I2C1_MODE_SELECT_BITS SSP1CON1bits.SSPM // I2C Master Mode control bit.
162
#define I2C1_MASTER_ENABLE_CONTROL_BITS SSP1CON1bits.SSPEN // I2C port enable control bit.
163
164
#define I2C1_START_CONDITION_ENABLE_BIT SSP1CON2bits.SEN // I2C START control bit.
165
#define I2C1_REPEAT_START_CONDITION_ENABLE_BIT SSP1CON2bits.RSEN // I2C Repeated START control bit.
166
#define I2C1_RECEIVE_ENABLE_BIT SSP1CON2bits.RCEN // I2C Receive enable control bit.
167
#define I2C1_STOP_CONDITION_ENABLE_BIT SSP1CON2bits.PEN // I2C STOP control bit.
168
#define I2C1_ACKNOWLEDGE_ENABLE_BIT SSP1CON2bits.ACKEN // I2C ACK start control bit.
169
#define I2C1_ACKNOWLEDGE_DATA_BIT SSP1CON2bits.ACKDT // I2C ACK data control bit.
170
#define I2C1_ACKNOWLEDGE_STATUS_BIT SSP1CON2bits.ACKSTAT // I2C ACK status bit.
171
172
#define I2C1_7bit true
173
/**
174
 Section: Local Functions
175
*/
176
177
void I2C1_FunctionComplete(void);
178
void I2C1_Stop(I2C1_MESSAGE_STATUS completion_code);
179
180
/**
181
 Section: Local Variables
182
*/
183
184
static I2C_TR_QUEUE_ENTRY i2c1_tr_queue[I2C1_CONFIG_TR_QUEUE_LENGTH];
185
static I2C_OBJECT i2c1_object;
186
static I2C_MASTER_STATES i2c1_state = S_MASTER_IDLE;
187
static uint8_t i2c1_trb_count = 0;
188
189
static I2C1_TRANSACTION_REQUEST_BLOCK *p_i2c1_trb_current = NULL;
190
static I2C_TR_QUEUE_ENTRY *p_i2c1_current = NULL;
191
192
193
/**
194
  Section: Driver Interface
195
*/
196
197
198
void I2C1_Initialize(void)
199
{
200
    i2c1_object.pTrHead = i2c1_tr_queue;
201
    i2c1_object.pTrTail = i2c1_tr_queue;
202
    i2c1_object.trStatus.s.empty = true;
203
    i2c1_object.trStatus.s.full = false;
204
205
    i2c1_object.i2cErrors = 0;
206
207
    // SMP High Speed; CKE disabled; 
208
    SSP1STAT = 0x00;
209
    // SSPEN enabled; CKP Idle:Low, Active:High; SSPM FOSC/4_SSPxADD_I2C; 
210
    SSP1CON1 = 0x28;
211
    // SBCDE disabled; BOEN disabled; SCIE disabled; PCIE disabled; DHEN disabled; SDAHT 100ns; AHEN disabled; 
212
    SSP1CON3 = 0x00;
213
    // Baud Rate Generator Value: SSPADD 3; 
214
    //SSP1ADD = 0x03;
215
    SSP1ADD = 0x19;
216
   
217
    // clear the master interrupt flag
218
    PIR3bits.SSP1IF = 0;
219
    // enable the master interrupt
220
    PIE3bits.SSP1IE = 1;
221
    
222
}
223
224
        
225
uint8_t I2C1_ErrorCountGet(void)
226
{
227
    uint8_t ret;
228
229
    ret = i2c1_object.i2cErrors;
230
    return ret;
231
}
232
233
void I2C1_ISR ( void )
234
{
235
  
236
    static uint8_t *pi2c_buf_ptr;
237
    static uint16_t i2c_address = 0;
238
    static uint8_t i2c_bytes_left = 0;
239
    static uint8_t i2c_10bit_address_restart = 0;
240
241
    PIR3bits.SSP1IF = 0;
242
243
    // Check first if there was a collision.
244
    // If we have a Write Collision, reset and go to idle state */
245
    if(I2C1_WRITE_COLLISION_STATUS_BIT)
246
    {
247
        // clear the Write colision
248
        I2C1_WRITE_COLLISION_STATUS_BIT = 0;
249
        i2c1_state = S_MASTER_IDLE;
250
        *(p_i2c1_current->pTrFlag) = I2C1_MESSAGE_FAIL;
251
252
        // reset the buffer pointer
253
        p_i2c1_current = NULL;
254
255
        return;
256
    }
257
258
    /* Handle the correct i2c state */
259
    switch(i2c1_state)
260
    {
261
        case S_MASTER_IDLE: /* In reset state, waiting for data to send */
262
263
            if(i2c1_object.trStatus.s.empty != true)
264
            {
265
                // grab the item pointed by the head
266
                p_i2c1_current = i2c1_object.pTrHead;
267
                i2c1_trb_count = i2c1_object.pTrHead->count;
268
                p_i2c1_trb_current = i2c1_object.pTrHead->ptrb_list;
269
270
                i2c1_object.pTrHead++;
271
272
                // check if the end of the array is reached
273
                if(i2c1_object.pTrHead == (i2c1_tr_queue + I2C1_CONFIG_TR_QUEUE_LENGTH))
274
                {
275
                    // adjust to restart at the beginning of the array
276
                    i2c1_object.pTrHead = i2c1_tr_queue;
277
                }
278
279
                // since we moved one item to be processed, we know
280
                // it is not full, so set the full status to false
281
                i2c1_object.trStatus.s.full = false;
282
283
                // check if the queue is empty
284
                if(i2c1_object.pTrHead == i2c1_object.pTrTail)
285
                {
286
                    // it is empty so set the empty status to true
287
                    i2c1_object.trStatus.s.empty = true;
288
                }
289
290
                // send the start condition
291
                I2C1_START_CONDITION_ENABLE_BIT = 1;
292
                
293
                // start the i2c request
294
                i2c1_state = S_MASTER_SEND_ADDR;
295
            }
296
297
            break;
298
299
        case S_MASTER_RESTART:
300
301
            /* check for pending i2c Request */
302
303
            // ... trigger a REPEATED START
304
            I2C1_REPEAT_START_CONDITION_ENABLE_BIT = 1;
305
306
            // start the i2c request
307
            i2c1_state = S_MASTER_SEND_ADDR;
308
309
            break;
310
311
        case S_MASTER_SEND_ADDR_10BIT_LSB:
312
313
            if(I2C1_ACKNOWLEDGE_STATUS_BIT)
314
            {
315
                i2c1_object.i2cErrors++;
316
                I2C1_Stop(I2C1_MESSAGE_ADDRESS_NO_ACK);
317
            }
318
            else
319
            {
320
                // Remove bit 0 as R/W is never sent here
321
                I2C1_TRANSMIT_REG = (i2c_address >> 1) & 0x00FF;
322
323
                // determine the next state, check R/W
324
                if(i2c_address & 0x01)
325
                {
326
                    // if this is a read we must repeat start
327
                    // the bus to perform a read
328
                    i2c1_state = S_MASTER_10BIT_RESTART;
329
                }
330
                else
331
                {
332
                    // this is a write continue writing data
333
                    i2c1_state = S_MASTER_SEND_DATA;
334
                }
335
            }
336
337
            break;
338
339
        case S_MASTER_10BIT_RESTART:
340
341
            if(I2C1_ACKNOWLEDGE_STATUS_BIT)
342
            {
343
                i2c1_object.i2cErrors++;
344
                I2C1_Stop(I2C1_MESSAGE_ADDRESS_NO_ACK);
345
            }
346
            else
347
            {
348
                // ACK Status is good
349
                // restart the bus
350
                I2C1_REPEAT_START_CONDITION_ENABLE_BIT = 1;
351
352
                // fudge the address so S_MASTER_SEND_ADDR works correctly
353
                // we only do this on a 10-bit address resend
354
                i2c_address = 0x00F0 | ((i2c_address >> 8) & 0x0006);
355
356
                // set the R/W flag
357
                i2c_address |= 0x0001;
358
359
                // set the address restart flag so we do not change the address
360
                i2c_10bit_address_restart = 1;
361
362
                // Resend the address as a read
363
                i2c1_state = S_MASTER_SEND_ADDR;
364
            }
365
366
            break;
367
368
        case S_MASTER_SEND_ADDR:
369
370
            /* Start has been sent, send the address byte */
371
372
            /* Note: 
373
                On a 10-bit address resend (done only during a 10-bit
374
                device read), the original i2c_address was modified in
375
                S_MASTER_10BIT_RESTART state. So the check if this is
376
                a 10-bit address will fail and a normal 7-bit address
377
                is sent with the R/W bit set to read. The flag
378
                i2c_10bit_address_restart prevents the address to
379
                be re-written.
380
             */
381
            if(i2c_10bit_address_restart != 1)
382
            {
383
                // extract the information for this message
384
                i2c_address = p_i2c1_trb_current->address;
385
                pi2c_buf_ptr = p_i2c1_trb_current->pbuffer;
386
                i2c_bytes_left = p_i2c1_trb_current->length;
387
            }
388
389
            // check for 10-bit address
390
            if(!I2C1_7bit && (0x0 != i2c_address))
391
            { 
392
                if (0 == i2c_10bit_address_restart)
393
                {
394
                    // we have a 10 bit address
395
                    // send bits<9:8>
396
                    // mask bit 0 as this is always a write 
397
                    I2C1_TRANSMIT_REG = 0xF0 | ((i2c_address >> 8) & 0x0006);
398
                    i2c1_state = S_MASTER_SEND_ADDR_10BIT_LSB;
399
                }
400
                else
401
                {
402
                    // resending address bits<9:8> to trigger read
403
                    I2C1_TRANSMIT_REG = i2c_address;
404
                    i2c1_state = S_MASTER_ACK_ADDR;
405
                    // reset the flag so the next access is ok
406
                    i2c_10bit_address_restart = 0;
407
                }
408
            }
409
            else
410
            {
411
                // Transmit the address
412
                I2C1_TRANSMIT_REG = i2c_address;
413
                if(i2c_address & 0x01)
414
                {
415
                    // Next state is to wait for address to be acked
416
                    i2c1_state = S_MASTER_ACK_ADDR;
417
                }
418
                else
419
                {
420
                    // Next state is transmit
421
                    i2c1_state = S_MASTER_SEND_DATA;
422
                }
423
            }
424
            break;
425
426
        case S_MASTER_SEND_DATA:
427
428
            // Make sure the previous byte was acknowledged
429
            if(I2C1_ACKNOWLEDGE_STATUS_BIT)
430
            {
431
                // Transmission was not acknowledged
432
                i2c1_object.i2cErrors++;
433
434
                // Reset the Ack flag
435
                I2C1_ACKNOWLEDGE_STATUS_BIT = 0;
436
437
                // Send a stop flag and go back to idle
438
                I2C1_Stop(I2C1_DATA_NO_ACK);
439
440
            }
441
            else
442
            {
443
                // Did we send them all ?
444
                if(i2c_bytes_left-- == 0U)
445
                {
446
                    // yup sent them all!
447
448
                    // update the trb pointer
449
                    p_i2c1_trb_current++;
450
451
                    // are we done with this string of requests?
452
                    if(--i2c1_trb_count == 0)
453
                    {
454
                        I2C1_Stop(I2C1_MESSAGE_COMPLETE);
455
                    }
456
                    else
457
                    {
458
                        // no!, there are more TRB to be sent.
459
                        //I2C1_START_CONDITION_ENABLE_BIT = 1;
460
461
                        // In some cases, the slave may require
462
                        // a restart instead of a start. So use this one
463
                        // instead.
464
                        I2C1_REPEAT_START_CONDITION_ENABLE_BIT = 1;
465
466
                        // start the i2c request
467
                        i2c1_state = S_MASTER_SEND_ADDR;
468
469
                    }
470
                }
471
                else
472
                {
473
                    // Grab the next data to transmit
474
                    I2C1_TRANSMIT_REG = *pi2c_buf_ptr++;
475
                }
476
            }
477
            break;
478
479
        case S_MASTER_ACK_ADDR:
480
481
            /* Make sure the previous byte was acknowledged */
482
            if(I2C1_ACKNOWLEDGE_STATUS_BIT)
483
            {
484
485
                // Transmission was not acknowledged
486
                i2c1_object.i2cErrors++;
487
488
                // Send a stop flag and go back to idle
489
                I2C1_Stop(I2C1_MESSAGE_ADDRESS_NO_ACK);
490
491
                // Reset the Ack flag
492
                I2C1_ACKNOWLEDGE_STATUS_BIT = 0;
493
            }
494
            else
495
            {
496
                I2C1_RECEIVE_ENABLE_BIT = 1;
497
                i2c1_state = S_MASTER_ACK_RCV_DATA;
498
            }
499
            break;
500
501
        case S_MASTER_RCV_DATA:
502
503
            /* Acknowledge is completed. Time for more data */
504
505
            // Next thing is to ack the data
506
            i2c1_state = S_MASTER_ACK_RCV_DATA;
507
508
            // Set up to receive a byte of data
509
            I2C1_RECEIVE_ENABLE_BIT = 1;
510
511
            break;
512
513
        case S_MASTER_ACK_RCV_DATA:
514
515
            // Grab the byte of data received and acknowledge it
516
            *pi2c_buf_ptr++ = I2C1_RECEIVE_REG;
517
518
            // Check if we received them all?
519
            if(--i2c_bytes_left)
520
            {
521
522
                /* No, there's more to receive */
523
524
                // No, bit 7 is clear. Data is ok
525
                // Set the flag to acknowledge the data
526
                I2C1_ACKNOWLEDGE_DATA_BIT = 0;
527
528
                // Wait for the acknowledge to complete, then get more
529
                i2c1_state = S_MASTER_RCV_DATA;
530
            }
531
            else
532
            {
533
534
                // Yes, it's the last byte. Don't ack it
535
                // Flag that we will nak the data
536
                I2C1_ACKNOWLEDGE_DATA_BIT = 1;
537
538
                I2C1_FunctionComplete();
539
            }
540
541
            // Initiate the acknowledge
542
            I2C1_ACKNOWLEDGE_ENABLE_BIT = 1;
543
            break;
544
545
        case S_MASTER_RCV_STOP: 
546
        case S_MASTER_SEND_STOP:
547
548
            // Send the stop flag
549
            I2C1_Stop(I2C1_MESSAGE_COMPLETE);
550
            break;
551
552
        default:
553
554
            // This case should not happen, if it does then
555
            // terminate the transfer
556
            i2c1_object.i2cErrors++;
557
            I2C1_Stop(I2C1_LOST_STATE);
558
            break;
559
560
    }
561
}
562
563
void I2C1_FunctionComplete(void)
564
{
565
566
    // update the trb pointer
567
    p_i2c1_trb_current++;
568
569
    // are we done with this string of requests?
570
    if(--i2c1_trb_count == 0)
571
    {
572
        i2c1_state = S_MASTER_SEND_STOP;
573
    }
574
    else
575
    {
576
        i2c1_state = S_MASTER_RESTART;
577
    }
578
579
}
580
581
void I2C1_Stop(I2C1_MESSAGE_STATUS completion_code)
582
{
583
    // then send a stop
584
    I2C1_STOP_CONDITION_ENABLE_BIT = 1;
585
586
    // make sure the flag pointer is not NULL
587
    if (p_i2c1_current->pTrFlag != NULL)
588
    {
589
        // update the flag with the completion code
590
        *(p_i2c1_current->pTrFlag) = completion_code;
591
    }
592
593
    // Done, back to idle
594
    i2c1_state = S_MASTER_IDLE;
595
    
596
}
597
598
void I2C1_MasterWrite(
599
                                uint8_t *pdata,
600
                                uint8_t length,
601
                                uint16_t address,
602
                                I2C1_MESSAGE_STATUS *pflag)
603
{
604
    static I2C1_TRANSACTION_REQUEST_BLOCK trBlock;
605
606
    // check if there is space in the queue
607
    if (i2c1_object.trStatus.s.full != true)
608
    {
609
        I2C1_MasterWriteTRBBuild(&trBlock, pdata, length, address);
610
        I2C1_MasterTRBInsert(1, &trBlock, pflag);
611
    }
612
    else
613
    {
614
        *pflag = I2C1_MESSAGE_FAIL;
615
    }
616
617
}
618
619
void I2C1_MasterRead(
620
                                uint8_t *pdata,
621
                                uint8_t length,
622
                                uint16_t address,
623
                                I2C1_MESSAGE_STATUS *pflag)
624
{
625
    static I2C1_TRANSACTION_REQUEST_BLOCK trBlock;
626
627
628
    // check if there is space in the queue
629
    if (i2c1_object.trStatus.s.full != true)
630
    {
631
        I2C1_MasterReadTRBBuild(&trBlock, pdata, length, address);
632
        I2C1_MasterTRBInsert(1, &trBlock, pflag);
633
    }
634
    else
635
    {
636
        *pflag = I2C1_MESSAGE_FAIL;
637
    }
638
639
}
640
641
void I2C1_MasterTRBInsert(
642
                                uint8_t count,
643
                                I2C1_TRANSACTION_REQUEST_BLOCK *ptrb_list,
644
                                I2C1_MESSAGE_STATUS *pflag)
645
{
646
647
    // check if there is space in the queue
648
    if (i2c1_object.trStatus.s.full != true)
649
    {
650
        *pflag = I2C1_MESSAGE_PENDING;
651
652
        i2c1_object.pTrTail->ptrb_list = ptrb_list;
653
        i2c1_object.pTrTail->count = count;
654
        i2c1_object.pTrTail->pTrFlag = pflag;
655
        i2c1_object.pTrTail++;
656
657
        // check if the end of the array is reached
658
        if (i2c1_object.pTrTail == (i2c1_tr_queue + I2C1_CONFIG_TR_QUEUE_LENGTH))
659
        {
660
            // adjust to restart at the beginning of the array
661
            i2c1_object.pTrTail = i2c1_tr_queue;
662
        }
663
664
        // since we added one item to be processed, we know
665
        // it is not empty, so set the empty status to false
666
        i2c1_object.trStatus.s.empty = false;
667
668
        // check if full
669
        if (i2c1_object.pTrHead == i2c1_object.pTrTail)
670
        {
671
            // it is full, set the full status to true
672
            i2c1_object.trStatus.s.full = true;
673
        }
674
675
    }
676
    else
677
    {
678
        *pflag = I2C1_MESSAGE_FAIL;
679
    }
680
681
    // for interrupt based
682
    if (*pflag == I2C1_MESSAGE_PENDING)
683
    {
684
        while(i2c1_state != S_MASTER_IDLE);
685
        {
686
            // force the task to run since we know that the queue has
687
            // something that needs to be sent
688
            PIR3bits.SSP1IF = true;
689
        }
690
    } // block until request is complete
691
692
}
693
694
void I2C1_MasterReadTRBBuild(
695
                                I2C1_TRANSACTION_REQUEST_BLOCK *ptrb,
696
                                uint8_t *pdata,
697
                                uint8_t length,
698
                                uint16_t address)
699
{
700
    ptrb->address = address << 1;
701
    // make this a read
702
    ptrb->address |= 0x01;
703
    ptrb->length = length;
704
    ptrb->pbuffer = pdata;
705
}
706
707
void I2C1_MasterWriteTRBBuild(
708
                                I2C1_TRANSACTION_REQUEST_BLOCK *ptrb,
709
                                uint8_t *pdata,
710
                                uint8_t length,
711
                                uint16_t address)
712
{
713
    ptrb->address = address << 1;
714
    ptrb->length = length;
715
    ptrb->pbuffer = pdata;
716
}
717
718
bool I2C1_MasterQueueIsEmpty(void)
719
{
720
    return(i2c1_object.trStatus.s.empty);
721
}
722
723
bool I2C1_MasterQueueIsFull(void)
724
{
725
    return(i2c1_object.trStatus.s.full);
726
} 
727
        
728
void I2C1_BusCollisionISR( void )
729
{
730
    // enter bus collision handling code here
731
} 
732
        
733
        
734
/**
735
 End of File
736
*/

Pinmanager:
1
void PIN_MANAGER_Initialize(void)
2
{
3
    LATB = 0x0;
4
    WPUE = 0x0;
5
    LATA = 0x0;
6
    LATC = 0x0;
7
    WPUA = 0x0;
8
    WPUB = 0x0;
9
    WPUC = 0x0;
10
    ANSELA = 0xE7;
11
    ANSELB = 0xC8;
12
    ANSELC = 0x7;
13
    //TRISB = 0xF3;
14
    TRISB = 0xF7;
15
    //TRISC = 0x72;
16
    TRISC = 0x70;
17
    TRISA = 0x27;
18
    
19
   // enable interrupt-on-change individually 
20
 IOCBNbits.IOCBN1 = 1; // Pin : RB1
21
 IOCBPbits.IOCBP1 = 1; // Pin : RB1
22
 IOCBNbits.IOCBN2 = 1; // Pin : RB2
23
    
24
25
    // enable interrupt-on-change globally
26
    PIE0bits.IOCIE = 1;
27
28
    bool state = GIE;
29
    GIE = 0;
30
    PPSLOCK = 0x55;
31
    PPSLOCK = 0xAA;
32
    PPSLOCKbits.PPSLOCKED = 0x00; // unlock PPS
33
34
    T2AINPPSbits.T2AINPPS = 0x13; //RC3->TMR2:T2IN;
35
    
36
    //SSP1CLKPPSbits.SSP1CLKPPS = 0x15; //RC5->MSSP1:SCL1;
37
    //SSP1DATPPSbits.SSP1DATPPS = 0x16; //RC6->MSSP1:SDA1;
38
    SSP1CLKPPS = 0x15; //RC5->MSSP1:SCL1;
39
    SSP1DATPPS = 0x16; //RC6->MSSP1:SDA1;
40
    
41
    T3CKIPPSbits.T3CKIPPS = 0x10; //RC0->TMR3:T3CKI;
42
    RC3PPS = 0x17; //RC3->MSSP2:SDO2;
43
    ADCACTPPS = 0x0C; //RB4->ADCC:ADCACT;
44
    RC2PPS = 0x16; //RC2->MSSP2:SCK2;
45
    RC5PPS = 0x14; //RC5->MSSP1:SCL1;
46
    RC6PPS = 0x15; //RC6->MSSP1:SDA1;
47
    
48
    //Test
49
    RC1PPS = 0x0E; //RC1->PWM6OUT;
50
    
51
    //SSP2DATPPSbits.SSP2DATPPS = 0x14; //RC4->MSSP2:SDI2;
52
    SSP2DATPPS = 0x14; //RC4->MSSP2:SDI2;
53
54
    PPSLOCK = 0x55;
55
    PPSLOCK = 0xAA;
56
    PPSLOCKbits.PPSLOCKED = 0x01; // lock PPS
57
58
    GIE = state;
59
60
}

Writing is done by: (e.g. with data 0x12, 0x24)

In .h: #define IC_ADDR 0x80
1
    writeBuffer[0] = 0x12;
2
    writeBuffer[1] = 0x24;
3
    
4
    while(status != I2C1_MESSAGE_FAIL) {
5
        // write one byte to EEPROM (2 is the count of bytes to write)
6
        I2C1_MasterWrite(writeBuffer, 2, IC_ADDR, &status);
7
8
        // wait for the message to be sent or status has changed.
9
        while(status == I2C1_MESSAGE_PENDING);
10
11
        if (status == I2C1_MESSAGE_COMPLETE)
12
            break;
13
14
        // if status is I2C1_MESSAGE_ADDRESS_NO_ACK,
15
        // or I2C1_DATA_NO_ACK,
16
        // The device may be busy and needs more time for the last
17
        // write so we can retry writing the data, this is why we
18
        // use a while loop here
19
20
        // check for max retry and skip this byte
21
        if (timeOut == IC_RETRY_MAX) 
22
            break;
23
        else
24
            timeOut++;

Thanks!

von Daniel E. (everyday_fun69)


Lesenswert?

Hi, I'm using PIC18F but no I2C. There is also a good forum on the 
microchip website in English or might be one of the user here can help 
you. A lot of them here are using Atmel. Good luck!

von microMan (Gast)


Lesenswert?

mh, sadly this one is not working at the moment :( (can't make a new 
thread)

von microMan (Gast)


Lesenswert?

No more ideas? :/

von Dominik B. (odysseus1710)


Lesenswert?

microMan schrieb:
> i only see low potential on the lines.

if this is the case, even in idle state, there is a general problem.
My suggestion is:
- the pin configuration is wrong or
- RC5/RC6 are not the I2C lines (these are not the standard pins for 
SCL/SDA, check your assignment)

I never programmed a pic before, so I cant really help to check your 
code :/
But with your pullup configuration the pins can only become low 
potential if they are driven low all the time

von Volker S. (vloki)


Lesenswert?

Dominik B. schrieb:
> My suggestion is:
> - the pin configuration is wrong or
> - RC5/RC6 are not the I2C lines (these are not the standard pins for
> SCL/SDA, check your assignment)

I think this is correct. You can not map the I2C functions to every pin.
You have to stay with the default pins or choose any of the one shown in 
TABLE 2: 28-PIN ALLOCATION TABLE (PIC16(L)F18857) of the data sheet.


microMan schrieb:
> mh, sadly this one is not working at the moment :( (can't make a new
> thread)
The microchip forum is really fucked up. You may have more luck here -> 
http://picforum.ric323.com/

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.