added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /**
<> 144:ef7eb2e8f9f7 2 ******************************************************************************
<> 144:ef7eb2e8f9f7 3 * @file i2c.c
<> 144:ef7eb2e8f9f7 4 * @brief I2C driver
<> 144:ef7eb2e8f9f7 5 * @internal
<> 144:ef7eb2e8f9f7 6 * @author ON Semiconductor
<> 144:ef7eb2e8f9f7 7 * $Rev: $
<> 144:ef7eb2e8f9f7 8 * $Date: 2016-04-12 $
<> 144:ef7eb2e8f9f7 9 ******************************************************************************
<> 144:ef7eb2e8f9f7 10 * @copyright (c) 2012 ON Semiconductor. All rights reserved.
<> 144:ef7eb2e8f9f7 11 * ON Semiconductor is supplying this software for use with ON Semiconductor
<> 144:ef7eb2e8f9f7 12 * processor based microcontrollers only.
<> 144:ef7eb2e8f9f7 13 *
<> 144:ef7eb2e8f9f7 14 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
<> 144:ef7eb2e8f9f7 15 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
<> 144:ef7eb2e8f9f7 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
<> 144:ef7eb2e8f9f7 17 * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
<> 144:ef7eb2e8f9f7 18 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
<> 144:ef7eb2e8f9f7 19 * @endinternal
<> 144:ef7eb2e8f9f7 20 *
<> 144:ef7eb2e8f9f7 21 * @ingroup i2c
<> 144:ef7eb2e8f9f7 22 *
<> 144:ef7eb2e8f9f7 23 * @details
<> 144:ef7eb2e8f9f7 24 *
<> 144:ef7eb2e8f9f7 25 * <h1> Reference document(s) </h1>
<> 144:ef7eb2e8f9f7 26 * <p>
<> 144:ef7eb2e8f9f7 27 * IPC7208 APB I2C Master Design Specification v1.3
<> 144:ef7eb2e8f9f7 28 * </p>
<> 144:ef7eb2e8f9f7 29 * The I2C bus is an industry-standard two-wire (clock and data) serial communication bus between master(initiator) and slave device.
<> 144:ef7eb2e8f9f7 30 * Within the procedure of the I2C-bus, unique situations arise which are defined as START and STOP conditions .A HIGH to LOW transition on
<> 144:ef7eb2e8f9f7 31 * the SDA line while SCL is HIGH is one such unique case. This situation indicates a START condition.A LOW to HIGH transition on the
<> 144:ef7eb2e8f9f7 32 * SDA line while SCL is HIGH defines a STOP condition.START and STOP conditions are always generated by the master. The bus is considered
<> 144:ef7eb2e8f9f7 33 * to be busy after the START condition. The bus is considered to be free again a certain time after the STOP condition.
<> 144:ef7eb2e8f9f7 34 * A master may start a transfer only if the bus is free. Two or more masters may generate a START condition.
<> 144:ef7eb2e8f9f7 35 * Every byte put on the SDA line must be 8-bits long.Each byte has to be followed by an acknowledge bit.
<> 144:ef7eb2e8f9f7 36 * This APB(Advanced peripheral bus) I2C Master is an APB Slave peripheral that can also serves as an I2C bus Master. The Command register
<> 144:ef7eb2e8f9f7 37 * is the programming interface to the I2C Engine. The commands arrive at the I2C Engine via the Command FIFO,so the first valid command
<> 144:ef7eb2e8f9f7 38 * that is written to the Command register is the first I2C instruction implemented on the I2C bus.Because the command interface provides
<> 144:ef7eb2e8f9f7 39 * the basic building blocks for any I2C transaction, access to a wide range of I2C slave devices is supported.
<> 144:ef7eb2e8f9f7 40 * I2C can be enabled by setting bit 7 of the control register .
<> 144:ef7eb2e8f9f7 41 * There is a generated clock (a divided version of the APB clock) in this module that may be used as the I2C System Clock.
<> 144:ef7eb2e8f9f7 42 * There are two FIFO in the I2C; Command FIFO and Read data FIFO
<> 144:ef7eb2e8f9f7 43 * The commands(I2C instructions) and data arrive at the I2C Engine via the Command FIFO.
<> 144:ef7eb2e8f9f7 44 * if the command FIFO is empty , up to 32 commands can be written to the command interface , it is programmer's responsibility to keep
<> 144:ef7eb2e8f9f7 45 * the track of command FIFO's status either by interrupt or by polling method by reading status register, which represents Operational
<> 144:ef7eb2e8f9f7 46 * Status of the I2C Module and its sub-modules.The action from the processor may be necessary after reading the status register.Reading
<> 144:ef7eb2e8f9f7 47 * the Status register clears the blkInt Interrupt signal.Read data FIFO is where data read by the processor from I2C slave is placed .
<> 144:ef7eb2e8f9f7 48 *
<> 144:ef7eb2e8f9f7 49 *
<> 144:ef7eb2e8f9f7 50 * <h1> Functional description (internal) </h1>
<> 144:ef7eb2e8f9f7 51 * <p>
<> 144:ef7eb2e8f9f7 52 *
<> 144:ef7eb2e8f9f7 53 * </p>
<> 144:ef7eb2e8f9f7 54 */
<> 144:ef7eb2e8f9f7 55 #if DEVICE_I2C
<> 144:ef7eb2e8f9f7 56 #include "i2c.h"
<> 144:ef7eb2e8f9f7 57
<> 144:ef7eb2e8f9f7 58 /* See i2c.h for details */
<> 144:ef7eb2e8f9f7 59 void fI2cInit(i2c_t *obj,PinName sda,PinName scl)
<> 144:ef7eb2e8f9f7 60 {
<> 144:ef7eb2e8f9f7 61 uint32_t clockDivisor;
<> 144:ef7eb2e8f9f7 62 /* determine the I2C to use */
<> 144:ef7eb2e8f9f7 63 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
<> 144:ef7eb2e8f9f7 64 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
<> 144:ef7eb2e8f9f7 65 obj->membase = (I2cIpc7208Reg_pt)pinmap_merge(i2c_sda, i2c_scl);
<> 144:ef7eb2e8f9f7 66 MBED_ASSERT((int)obj->membase != NC);
<> 144:ef7eb2e8f9f7 67
<> 144:ef7eb2e8f9f7 68 /* By default disbale interrupts */
<> 144:ef7eb2e8f9f7 69 obj->membase->IER.WORD = False;
<> 144:ef7eb2e8f9f7 70
<> 144:ef7eb2e8f9f7 71 /* enable interrupt associated with the device */
<> 144:ef7eb2e8f9f7 72 if(obj->membase == I2C1REG) {
<> 144:ef7eb2e8f9f7 73 CLOCK_ENABLE(CLOCK_I2C); /* enable i2c peripheral */
<> 144:ef7eb2e8f9f7 74 NVIC_ClearPendingIRQ(I2C_IRQn);
<> 144:ef7eb2e8f9f7 75 NVIC_EnableIRQ(I2C_IRQn);
<> 144:ef7eb2e8f9f7 76 } else {
<> 144:ef7eb2e8f9f7 77 CLOCK_ENABLE(CLOCK_I2C2); /* enable i2c peripheral */
<> 144:ef7eb2e8f9f7 78 NVIC_ClearPendingIRQ(I2C2_IRQn);
<> 144:ef7eb2e8f9f7 79 NVIC_EnableIRQ(I2C2_IRQn);
<> 144:ef7eb2e8f9f7 80 }
<> 144:ef7eb2e8f9f7 81
<> 144:ef7eb2e8f9f7 82 /*select I2C clock source */
<> 144:ef7eb2e8f9f7 83 obj->membase->CR.BITS.I2C_CLK_SRC = True;
<> 144:ef7eb2e8f9f7 84
<> 144:ef7eb2e8f9f7 85 /* enable I2C clock divider */
<> 144:ef7eb2e8f9f7 86 obj->membase->CR.BITS.I2C_APB_CD_EN = True;
<> 144:ef7eb2e8f9f7 87
<> 144:ef7eb2e8f9f7 88 /* set default baud rate at 100k */
<> 144:ef7eb2e8f9f7 89 clockDivisor = ((fClockGetPeriphClockfrequency() / 100000) >> 2) - 2;
<> 144:ef7eb2e8f9f7 90 obj->membase->CR.BITS.CD_VAL = (clockDivisor & I2C_CLOCKDIVEDER_VAL_MASK);
<> 144:ef7eb2e8f9f7 91 obj->membase->PRE_SCALE_REG = (clockDivisor & I2C_APB_CLK_DIVIDER_VAL_MASK) >> 5; /**< Zero pre-scale value not allowed */
<> 144:ef7eb2e8f9f7 92
<> 144:ef7eb2e8f9f7 93 /* Cross bar setting */
<> 144:ef7eb2e8f9f7 94 pinmap_pinout(sda, PinMap_I2C_SDA);
<> 144:ef7eb2e8f9f7 95 pinmap_pinout(scl, PinMap_I2C_SCL);
<> 144:ef7eb2e8f9f7 96
<> 144:ef7eb2e8f9f7 97 /*Enable open drain & pull up for sda & scl pin */
<> 144:ef7eb2e8f9f7 98 pin_mode(sda, OpenDrainPullUp);
<> 144:ef7eb2e8f9f7 99 pin_mode(scl, OpenDrainPullUp);
<> 144:ef7eb2e8f9f7 100
<> 144:ef7eb2e8f9f7 101 /* PAD drive strength */
<> 144:ef7eb2e8f9f7 102 PadReg_t *padRegSda = (PadReg_t*)(PADREG_BASE + (sda * PAD_REG_ADRS_BYTE_SIZE));
<> 144:ef7eb2e8f9f7 103 PadReg_t *padRegScl = (PadReg_t*)(PADREG_BASE + (scl * PAD_REG_ADRS_BYTE_SIZE));
<> 144:ef7eb2e8f9f7 104
<> 144:ef7eb2e8f9f7 105 CLOCK_ENABLE(CLOCK_PAD);
<> 144:ef7eb2e8f9f7 106 padRegSda->PADIO0.BITS.POWER = 1; /* sda: Drive strength */
<> 144:ef7eb2e8f9f7 107 padRegScl->PADIO0.BITS.POWER = 1; /* scl: Drive strength */
<> 144:ef7eb2e8f9f7 108 CLOCK_DISABLE(CLOCK_PAD);
<> 144:ef7eb2e8f9f7 109
<> 144:ef7eb2e8f9f7 110 CLOCK_ENABLE(CLOCK_GPIO);
<> 144:ef7eb2e8f9f7 111 GPIOREG->W_OUT |= ((True << sda) | (True << scl));
<> 144:ef7eb2e8f9f7 112 CLOCK_DISABLE(CLOCK_GPIO);
<> 144:ef7eb2e8f9f7 113
<> 144:ef7eb2e8f9f7 114 /* Enable i2c module */
<> 144:ef7eb2e8f9f7 115 obj->membase->CR.BITS.I2C_MODULE_EN = True;
<> 144:ef7eb2e8f9f7 116 }
<> 144:ef7eb2e8f9f7 117
<> 144:ef7eb2e8f9f7 118 /* See i2c.h for details */
<> 144:ef7eb2e8f9f7 119 void fI2cFrequency(i2c_t *obj, uint32_t hz)
<> 144:ef7eb2e8f9f7 120 {
<> 144:ef7eb2e8f9f7 121 /* Set user baud rate */
<> 144:ef7eb2e8f9f7 122 uint32_t clockDivisor;
<> 144:ef7eb2e8f9f7 123 clockDivisor = ((fClockGetPeriphClockfrequency() / hz) >> 2) - 2;
<> 144:ef7eb2e8f9f7 124 obj->membase->CR.BITS.CD_VAL = (clockDivisor & I2C_CLOCKDIVEDER_VAL_MASK);
<> 144:ef7eb2e8f9f7 125 obj->membase->PRE_SCALE_REG = (clockDivisor & I2C_APB_CLK_DIVIDER_VAL_MASK) >> 5; /**< Zero pre-scale value not allowed */
<> 144:ef7eb2e8f9f7 126 }
<> 144:ef7eb2e8f9f7 127
<> 144:ef7eb2e8f9f7 128 /* See i2c.h for details */
<> 144:ef7eb2e8f9f7 129 int32_t fI2cStart(i2c_t *obj)
<> 144:ef7eb2e8f9f7 130 {
<> 144:ef7eb2e8f9f7 131 /* Send start bit */
<> 144:ef7eb2e8f9f7 132 obj->membase->CMD_REG = I2C_CMD_START;
<> 144:ef7eb2e8f9f7 133 return I2C_API_STATUS_SUCCESS;
<> 144:ef7eb2e8f9f7 134 }
<> 144:ef7eb2e8f9f7 135
<> 144:ef7eb2e8f9f7 136 /* See i2c.h for details */
<> 144:ef7eb2e8f9f7 137 int32_t fI2cStop(i2c_t *obj)
<> 144:ef7eb2e8f9f7 138 {
<> 144:ef7eb2e8f9f7 139 /* Send stop bit */
<> 144:ef7eb2e8f9f7 140 obj->membase->CMD_REG = I2C_CMD_STOP;
<> 144:ef7eb2e8f9f7 141 if (obj->membase->STATUS.WORD & (I2C_STATUS_CMD_FIFO_FULL_BIT |
<> 144:ef7eb2e8f9f7 142 I2C_STATUS_CMD_FIFO_OFL_BIT |
<> 144:ef7eb2e8f9f7 143 I2C_STATUS_BUS_ERR_BIT)) {
<> 144:ef7eb2e8f9f7 144 /* I2c error occured */
<> 144:ef7eb2e8f9f7 145 return I2C_ERROR_BUS_BUSY;
<> 144:ef7eb2e8f9f7 146 }
<> 144:ef7eb2e8f9f7 147 return I2C_API_STATUS_SUCCESS;
<> 144:ef7eb2e8f9f7 148 }
<> 144:ef7eb2e8f9f7 149
<> 144:ef7eb2e8f9f7 150 /* See i2c.h for details */
<> 144:ef7eb2e8f9f7 151 int32_t fI2cReadB(i2c_t *d, char *buf, int len)
<> 144:ef7eb2e8f9f7 152 {
<> 144:ef7eb2e8f9f7 153 int32_t read = 0;
<> 144:ef7eb2e8f9f7 154
<> 144:ef7eb2e8f9f7 155 while (read < len) {
<> 144:ef7eb2e8f9f7 156 /* Send read command */
<> 144:ef7eb2e8f9f7 157 d->membase->CMD_REG = I2C_CMD_RDAT8;
<> 144:ef7eb2e8f9f7 158 while(!RD_DATA_READY) {
<> 144:ef7eb2e8f9f7 159 if (I2C_BUS_ERR_CHECK) {
<> 144:ef7eb2e8f9f7 160 /* Bus error occured */
<> 144:ef7eb2e8f9f7 161 return I2C_ERROR_BUS_BUSY;
<> 144:ef7eb2e8f9f7 162 }
<> 144:ef7eb2e8f9f7 163 }
<> 144:ef7eb2e8f9f7 164 buf[read++] = d->membase->RD_FIFO_REG; /**< Reading 'read FIFO register' will clear status register */
<> 144:ef7eb2e8f9f7 165
<> 144:ef7eb2e8f9f7 166 if(!(read>=len)) { /* No ACK will be generated for the last read, upper level I2C protocol should generate */
<> 144:ef7eb2e8f9f7 167 d->membase->CMD_REG=I2C_CMD_WDAT0; /* TODO based on requirement generate ACK or NACK Based on the requirement. */
<> 144:ef7eb2e8f9f7 168 }
<> 144:ef7eb2e8f9f7 169
<> 144:ef7eb2e8f9f7 170 /* check for FIFO underflow */
<> 144:ef7eb2e8f9f7 171 if(I2C_UFL_CHECK) {
<> 144:ef7eb2e8f9f7 172 return I2C_ERROR_NO_SLAVE; /* TODO No error available for this in i2c_api.h */
<> 144:ef7eb2e8f9f7 173 }
<> 144:ef7eb2e8f9f7 174 if(I2C_BUS_ERR_CHECK) {
<> 144:ef7eb2e8f9f7 175 /* Bus error */
<> 144:ef7eb2e8f9f7 176 return I2C_ERROR_BUS_BUSY;
<> 144:ef7eb2e8f9f7 177 }
<> 144:ef7eb2e8f9f7 178 }
<> 144:ef7eb2e8f9f7 179
<> 144:ef7eb2e8f9f7 180 return read;
<> 144:ef7eb2e8f9f7 181 }
<> 144:ef7eb2e8f9f7 182
<> 144:ef7eb2e8f9f7 183 /* See i2c.h for details */
<> 144:ef7eb2e8f9f7 184 int32_t fI2cWriteB(i2c_t *d, const char *buf, int len)
<> 144:ef7eb2e8f9f7 185 {
<> 144:ef7eb2e8f9f7 186 int32_t write = 0;
<> 144:ef7eb2e8f9f7 187
<> 144:ef7eb2e8f9f7 188 while (write < len) {
<> 144:ef7eb2e8f9f7 189 /* Send write command */
<> 144:ef7eb2e8f9f7 190 d->membase->CMD_REG = I2C_CMD_WDAT8;
<> 144:ef7eb2e8f9f7 191 if(buf[write] == I2C_CMD_RDAT8) {
<> 144:ef7eb2e8f9f7 192 /* SW work around to counter FSM issue. If the only command in the CMD FIFO is the WDAT8 command (data of 0x13)
<> 144:ef7eb2e8f9f7 193 then as the command is read out (i.e. the FIFO goes empty), the WDAT8 command will be misinterpreted as a
<> 144:ef7eb2e8f9f7 194 RDAT8 command by the data FSM; resulting in an I2C bus error (NACK instead of an ACK). */
<> 144:ef7eb2e8f9f7 195 /* Send 0x13 bit wise */
<> 144:ef7eb2e8f9f7 196 d->membase->CMD_REG = I2C_CMD_WDAT0;
<> 144:ef7eb2e8f9f7 197 d->membase->CMD_REG = I2C_CMD_WDAT0;
<> 144:ef7eb2e8f9f7 198 d->membase->CMD_REG = I2C_CMD_WDAT0;
<> 144:ef7eb2e8f9f7 199 d->membase->CMD_REG = I2C_CMD_WDAT1;
<> 144:ef7eb2e8f9f7 200
<> 144:ef7eb2e8f9f7 201 d->membase->CMD_REG = I2C_CMD_WDAT0;
<> 144:ef7eb2e8f9f7 202 d->membase->CMD_REG = I2C_CMD_WDAT0;
<> 144:ef7eb2e8f9f7 203 d->membase->CMD_REG = I2C_CMD_WDAT1;
<> 144:ef7eb2e8f9f7 204 d->membase->CMD_REG = I2C_CMD_WDAT1;
<> 144:ef7eb2e8f9f7 205 } else {
<> 144:ef7eb2e8f9f7 206 /* Send data */
<> 144:ef7eb2e8f9f7 207 d->membase->CMD_REG = buf[write++];
<> 144:ef7eb2e8f9f7 208 }
<> 144:ef7eb2e8f9f7 209 d->membase->CMD_REG = I2C_CMD_VRFY_ACK; /* TODO Verify ACK based on requirement, Do we need? */
<> 144:ef7eb2e8f9f7 210
<> 144:ef7eb2e8f9f7 211 while(FIFO_OFL_CHECK); /* Wait till command overflow ends */
<> 144:ef7eb2e8f9f7 212
<> 144:ef7eb2e8f9f7 213 if (I2C_BUS_ERR_CHECK) {
<> 144:ef7eb2e8f9f7 214 /* Bus error */
<> 144:ef7eb2e8f9f7 215 return I2C_ERROR_BUS_BUSY;
<> 144:ef7eb2e8f9f7 216 }
<> 144:ef7eb2e8f9f7 217 }
<> 144:ef7eb2e8f9f7 218
<> 144:ef7eb2e8f9f7 219 return write;
<> 144:ef7eb2e8f9f7 220 }
<> 144:ef7eb2e8f9f7 221
<> 144:ef7eb2e8f9f7 222 #endif /* DEVICE_I2C */