mbed library sources that still uses the stm standard peripheral library
Fork of mbed-src by
Revision 423:a032ac66f24e, committed 2014-12-02
- Comitter:
- mbed_official
- Date:
- Tue Dec 02 15:15:06 2014 +0000
- Parent:
- 422:cc1c4962551c
- Child:
- 424:560d1a9f3083
- Commit message:
- Synchronized with git revision 7442855e9ccc71565c0ed4fdeea9c66a3212c1af
Full URL: https://github.com/mbedmicro/mbed/commit/7442855e9ccc71565c0ed4fdeea9c66a3212c1af/
Targets: RZ_A1H - Fixed I2C bug
Changed in this revision
targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c | Show annotated file Show diff for this revision Revisions of this file |
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c Thu Nov 27 14:00:07 2014 +0000 +++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c Tue Dec 02 15:15:06 2014 +0000 @@ -20,6 +20,8 @@ #include "riic_iodefine.h" +#include "RZ_A1_Init.h" +#include "MBRZA1H.h" volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST; @@ -198,13 +200,66 @@ } void i2c_frequency(i2c_t *obj, int hz) { - uint32_t PCLK = 6666666; - - uint32_t pulse = PCLK / (hz * 2); + int freq; + int oldfreq = 0; + int newfreq = 0; + uint32_t pclk; + uint32_t pclk_base; + uint32_t tmp_width; + uint32_t width = 0; + uint8_t count; + uint8_t pclk_bit = 0; + + /* set PCLK */ + if (false == RZ_A1_IsClockMode0()) + { + pclk_base = (uint32_t)CM1_RENESAS_RZ_A1_P0_CLK; + } else { + pclk_base = (uint32_t)CM0_RENESAS_RZ_A1_P0_CLK; + } + + /* Min 10kHz, Max 400kHz */ + if (hz < 10000) { + freq = 10000; + } else if (hz > 400000) { + freq = 400000; + } else { + freq = hz; + } + + for (count = 0; count < 7; count++) { + // IIC phi = P0 phi / rate + pclk = pclk_base / (2 << count); + // In case of "CLE = 1, NFE = 1, CKS != 000( IIC phi < P0 phi ), nf = 1" + // freq = 1 / {[( BRH + 2 + 1 ) + ( BRL + 2 + 1 )] / pclk } + // BRH is regarded as same value with BRL + // 2( BRH + 3 ) / pclk = 1 / freq + tmp_width = ((pclk / freq) / 2) - 3; + // Carry in a decimal point + tmp_width += 1; + if ((tmp_width >= 0x00000001) && (tmp_width <= 0x0000001F)) { + // Calculate theoretical value, and Choose max value of them + newfreq = pclk / (tmp_width + 3) / 2; + if (newfreq >= oldfreq) { + oldfreq = newfreq; + width = tmp_width; + pclk_bit = (uint8_t)(0x10 * (count + 1)); + } + } + } - // I2C Rate - REG(BRL.UINT32) = pulse; - REG(BRH.UINT32) = pulse; + if (width != 0) { + // I2C Rate + REG(MR1.UINT8[0]) |= pclk_bit; // P_phi / xx + width |= 0x000000E0; + REG(BRL.UINT32) = width; + REG(BRH.UINT32) = width; + } else { + // Default + REG(MR1.UINT8[0]) |= 0x00; // P_phi / 1 + REG(BRL.UINT32) = 0x000000FF; + REG(BRH.UINT32) = 0x000000FF; + } } int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {