aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/fx3/b200/b200_i2c.c
blob: c6fa67c77e6d7dc63ca29d92ce37140473380266 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//
// Copyright 2013-2014 Ettus Research LLC
//

#include "b200_i2c.h"

#include "cyu3i2c.h"

/* I2c initialization for EEPROM programming. */
void CyFxI2cInit (uint16_t pageLen) {
    CyU3PI2cConfig_t i2cConfig;

    /* Initialize and configure the I2C master module. */
    CyU3PI2cInit ();

    /* Start the I2C master block. The bit rate is set at 100KHz.
     * The data transfer is done via DMA. */
    CyU3PMemSet ((uint8_t *)&i2cConfig, 0, sizeof(i2cConfig));
    i2cConfig.bitRate    = CY_FX_USBI2C_I2C_BITRATE;
    i2cConfig.busTimeout = 0xFFFFFFFF;
    i2cConfig.dmaTimeout = 0xFFFF;
    i2cConfig.isDma      = CyFalse;

    CyU3PI2cSetConfig (&i2cConfig, NULL);
    glI2cPageSize = pageLen;
}

/* I2C read / write for programmer application. */
void CyFxUsbI2cTransfer (
        uint16_t  byteAddress,
        uint8_t   devAddr,
        uint16_t  byteCount,
        uint8_t  *buffer,
        CyBool_t  isRead)
{
    CyU3PI2cPreamble_t preamble;
    uint16_t pageCount = (byteCount / glI2cPageSize);
    uint16_t resCount = glI2cPageSize;

    if (byteCount == 0) {
        return;
    }

    if ((byteCount % glI2cPageSize) != 0) {
        pageCount ++;
        resCount = byteCount % glI2cPageSize;
    }

    while (pageCount != 0) {
        if (isRead) {
            /* Update the preamble information. */
            preamble.length    = 4;
            preamble.buffer[0] = devAddr;
            preamble.buffer[1] = (uint8_t)(byteAddress >> 8);
            preamble.buffer[2] = (uint8_t)(byteAddress & 0xFF);
            preamble.buffer[3] = (devAddr | 0x01);
            preamble.ctrlMask  = 0x0004;

            CyU3PI2cReceiveBytes (&preamble, buffer, (pageCount == 1) ? resCount : glI2cPageSize, 0);
        } else {
            /* Write. Update the preamble information. */
            preamble.length    = 3;
            preamble.buffer[0] = devAddr;
            preamble.buffer[1] = (uint8_t)(byteAddress >> 8);
            preamble.buffer[2] = (uint8_t)(byteAddress & 0xFF);
            preamble.ctrlMask  = 0x0000;

            CyU3PI2cTransmitBytes (&preamble, buffer, (pageCount == 1) ? resCount : glI2cPageSize, 0);
            /* Wait for the write to complete. */
            preamble.length = 1;
            CyU3PI2cWaitForAck(&preamble, 200);
        }

        /* An additional delay seems to be required after receiving an ACK. */
        CyU3PThreadSleep (1);

        /* Update the parameters */
        byteAddress  += glI2cPageSize;
        buffer += glI2cPageSize;
        pageCount --;
    }
}