test

Committer:
elijahsj
Date:
Mon Nov 09 00:33:19 2020 -0500
Revision:
2:4364577b5ad8
Parent:
1:8a094db1347f
copied mbed library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elijahsj 1:8a094db1347f 1 /**
elijahsj 1:8a094db1347f 2 * @file
elijahsj 1:8a094db1347f 3 * @brief This file contains the function implementations for the I2CS
elijahsj 1:8a094db1347f 4 * (Inter-Integrated Circuit Slave) peripheral module.
elijahsj 1:8a094db1347f 5 */
elijahsj 1:8a094db1347f 6 /* ****************************************************************************
elijahsj 1:8a094db1347f 7 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
elijahsj 1:8a094db1347f 8 *
elijahsj 1:8a094db1347f 9 * Permission is hereby granted, free of charge, to any person obtaining a
elijahsj 1:8a094db1347f 10 * copy of this software and associated documentation files (the "Software"),
elijahsj 1:8a094db1347f 11 * to deal in the Software without restriction, including without limitation
elijahsj 1:8a094db1347f 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
elijahsj 1:8a094db1347f 13 * and/or sell copies of the Software, and to permit persons to whom the
elijahsj 1:8a094db1347f 14 * Software is furnished to do so, subject to the following conditions:
elijahsj 1:8a094db1347f 15 *
elijahsj 1:8a094db1347f 16 * The above copyright notice and this permission notice shall be included
elijahsj 1:8a094db1347f 17 * in all copies or substantial portions of the Software.
elijahsj 1:8a094db1347f 18 *
elijahsj 1:8a094db1347f 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
elijahsj 1:8a094db1347f 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
elijahsj 1:8a094db1347f 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
elijahsj 1:8a094db1347f 22 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
elijahsj 1:8a094db1347f 23 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
elijahsj 1:8a094db1347f 24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
elijahsj 1:8a094db1347f 25 * OTHER DEALINGS IN THE SOFTWARE.
elijahsj 1:8a094db1347f 26 *
elijahsj 1:8a094db1347f 27 * Except as contained in this notice, the name of Maxim Integrated
elijahsj 1:8a094db1347f 28 * Products, Inc. shall not be used except as stated in the Maxim Integrated
elijahsj 1:8a094db1347f 29 * Products, Inc. Branding Policy.
elijahsj 1:8a094db1347f 30 *
elijahsj 1:8a094db1347f 31 * The mere transfer of this software does not imply any licenses
elijahsj 1:8a094db1347f 32 * of trade secrets, proprietary technology, copyrights, patents,
elijahsj 1:8a094db1347f 33 * trademarks, maskwork rights, or any other form of intellectual
elijahsj 1:8a094db1347f 34 * property whatsoever. Maxim Integrated Products, Inc. retains all
elijahsj 1:8a094db1347f 35 * ownership rights.
elijahsj 1:8a094db1347f 36 *
elijahsj 1:8a094db1347f 37 * $Date: 2016-09-08 18:05:59 -0500 (Thu, 08 Sep 2016) $
elijahsj 1:8a094db1347f 38 * $Revision: 24332 $
elijahsj 1:8a094db1347f 39 *
elijahsj 1:8a094db1347f 40 *************************************************************************** */
elijahsj 1:8a094db1347f 41
elijahsj 1:8a094db1347f 42 /* **** Includes **** */
elijahsj 1:8a094db1347f 43 #include <string.h>
elijahsj 1:8a094db1347f 44 #include "mxc_assert.h"
elijahsj 1:8a094db1347f 45 #include "mxc_errors.h"
elijahsj 1:8a094db1347f 46 #include "mxc_sys.h"
elijahsj 1:8a094db1347f 47 #include "i2cs.h"
elijahsj 1:8a094db1347f 48
elijahsj 1:8a094db1347f 49 /**
elijahsj 1:8a094db1347f 50 * @ingroup i2cs
elijahsj 1:8a094db1347f 51 * @{
elijahsj 1:8a094db1347f 52 */
elijahsj 1:8a094db1347f 53 /* **** Definitions **** */
elijahsj 1:8a094db1347f 54
elijahsj 1:8a094db1347f 55 /* **** Globals ***** */
elijahsj 1:8a094db1347f 56
elijahsj 1:8a094db1347f 57
elijahsj 1:8a094db1347f 58 // No Doxygen documentation for the items between here and endcond.
elijahsj 1:8a094db1347f 59 /* Clock divider lookup table */
elijahsj 1:8a094db1347f 60 static const uint32_t clk_div_table[2][8] = {
elijahsj 1:8a094db1347f 61 /* I2CS_SPEED_100KHZ */
elijahsj 1:8a094db1347f 62 {
elijahsj 1:8a094db1347f 63 // 12000000
elijahsj 1:8a094db1347f 64 (6 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS),
elijahsj 1:8a094db1347f 65 // 24000000
elijahsj 1:8a094db1347f 66 (12 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS),
elijahsj 1:8a094db1347f 67 // 36000000 NOT SUPPORTED
elijahsj 1:8a094db1347f 68 0,
elijahsj 1:8a094db1347f 69 // 48000000
elijahsj 1:8a094db1347f 70 (24 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS),
elijahsj 1:8a094db1347f 71 // 60000000 NOT SUPPORTED
elijahsj 1:8a094db1347f 72 0,
elijahsj 1:8a094db1347f 73 // 72000000 NOT SUPPORTED
elijahsj 1:8a094db1347f 74 0,
elijahsj 1:8a094db1347f 75 // 84000000 NOT SUPPORTED
elijahsj 1:8a094db1347f 76 0,
elijahsj 1:8a094db1347f 77 // 96000000
elijahsj 1:8a094db1347f 78 (48 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS)
elijahsj 1:8a094db1347f 79 },
elijahsj 1:8a094db1347f 80 /* I2CS_SPEED_400KHZ */
elijahsj 1:8a094db1347f 81 {
elijahsj 1:8a094db1347f 82 // 12000000
elijahsj 1:8a094db1347f 83 (2 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS),
elijahsj 1:8a094db1347f 84 // 24000000
elijahsj 1:8a094db1347f 85 (3 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS),
elijahsj 1:8a094db1347f 86 // 36000000 NOT SUPPORTED
elijahsj 1:8a094db1347f 87 0,
elijahsj 1:8a094db1347f 88 // 48000000
elijahsj 1:8a094db1347f 89 (6 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS),
elijahsj 1:8a094db1347f 90 // 60000000 NOT SUPPORTED
elijahsj 1:8a094db1347f 91 0,
elijahsj 1:8a094db1347f 92 // 72000000 NOT SUPPORTED
elijahsj 1:8a094db1347f 93 0,
elijahsj 1:8a094db1347f 94 // 84000000 NOT SUPPORTED
elijahsj 1:8a094db1347f 95 0,
elijahsj 1:8a094db1347f 96 // 96000000
elijahsj 1:8a094db1347f 97 (12 << MXC_F_I2CS_CLK_DIV_FS_FILTER_CLOCK_DIV_POS)
elijahsj 1:8a094db1347f 98 },
elijahsj 1:8a094db1347f 99 };
elijahsj 1:8a094db1347f 100
elijahsj 1:8a094db1347f 101
elijahsj 1:8a094db1347f 102 static void (*callbacks[MXC_CFG_I2CS_INSTANCES][MXC_CFG_I2CS_BUFFER_SIZE])(uint8_t);
elijahsj 1:8a094db1347f 103
elijahsj 1:8a094db1347f 104 /* **** Functions **** */
elijahsj 1:8a094db1347f 105
elijahsj 1:8a094db1347f 106 /* ************************************************************************* */
elijahsj 1:8a094db1347f 107 int I2CS_Init(mxc_i2cs_regs_t *i2cs, const sys_cfg_i2cs_t *sys_cfg, i2cs_speed_t speed,
elijahsj 1:8a094db1347f 108 uint16_t address, i2cs_addr_t addr_len)
elijahsj 1:8a094db1347f 109 {
elijahsj 1:8a094db1347f 110 int err, i, i2cs_index;
elijahsj 1:8a094db1347f 111
elijahsj 1:8a094db1347f 112 i2cs_index = MXC_I2CS_GET_IDX(i2cs);
elijahsj 1:8a094db1347f 113 MXC_ASSERT(i2cs_index >= 0);
elijahsj 1:8a094db1347f 114
elijahsj 1:8a094db1347f 115 // Set system level configurations
elijahsj 1:8a094db1347f 116 if ((err = SYS_I2CS_Init(i2cs, sys_cfg)) != E_NO_ERROR) {
elijahsj 1:8a094db1347f 117 return err;
elijahsj 1:8a094db1347f 118 }
elijahsj 1:8a094db1347f 119
elijahsj 1:8a094db1347f 120 // Compute clock array index
elijahsj 1:8a094db1347f 121 int clki = ((SYS_I2CS_GetFreq(i2cs) / 12000000) - 1);
elijahsj 1:8a094db1347f 122
elijahsj 1:8a094db1347f 123 // Get clock divider settings from lookup table
elijahsj 1:8a094db1347f 124 if ((speed == I2CS_SPEED_100KHZ) && (clk_div_table[I2CS_SPEED_100KHZ][clki] > 0)) {
elijahsj 1:8a094db1347f 125 i2cs->clk_div = clk_div_table[I2CS_SPEED_100KHZ][clki];
elijahsj 1:8a094db1347f 126 } else if ((speed == I2CS_SPEED_400KHZ) && (clk_div_table[I2CS_SPEED_400KHZ][clki] > 0)) {
elijahsj 1:8a094db1347f 127 i2cs->clk_div = clk_div_table[I2CS_SPEED_400KHZ][clki];
elijahsj 1:8a094db1347f 128 } else {
elijahsj 1:8a094db1347f 129 MXC_ASSERT_FAIL();
elijahsj 1:8a094db1347f 130 }
elijahsj 1:8a094db1347f 131
elijahsj 1:8a094db1347f 132 // Clear the interrupt callbacks
elijahsj 1:8a094db1347f 133 for(i = 0; i < MXC_CFG_I2CS_BUFFER_SIZE; i++) {
elijahsj 1:8a094db1347f 134 callbacks[i2cs_index][i] = NULL;
elijahsj 1:8a094db1347f 135 }
elijahsj 1:8a094db1347f 136
elijahsj 1:8a094db1347f 137 // Reset module
elijahsj 1:8a094db1347f 138 i2cs->dev_id = MXC_F_I2CS_DEV_ID_SLAVE_RESET;
elijahsj 1:8a094db1347f 139 i2cs->dev_id = ((((address >> 0) << MXC_F_I2CS_DEV_ID_SLAVE_DEV_ID_POS)
elijahsj 1:8a094db1347f 140 & MXC_F_I2CS_DEV_ID_SLAVE_DEV_ID) | addr_len);
elijahsj 1:8a094db1347f 141
elijahsj 1:8a094db1347f 142 return E_NO_ERROR;
elijahsj 1:8a094db1347f 143 }
elijahsj 1:8a094db1347f 144
elijahsj 1:8a094db1347f 145 /* ************************************************************************* */
elijahsj 1:8a094db1347f 146 int I2CS_Shutdown(mxc_i2cs_regs_t *i2cs)
elijahsj 1:8a094db1347f 147 {
elijahsj 1:8a094db1347f 148 int err;
elijahsj 1:8a094db1347f 149
elijahsj 1:8a094db1347f 150 // Disable and clear interrupts
elijahsj 1:8a094db1347f 151 i2cs->inten = 0;
elijahsj 1:8a094db1347f 152 i2cs->intfl = i2cs->intfl;
elijahsj 1:8a094db1347f 153
elijahsj 1:8a094db1347f 154 // clears system level configurations
elijahsj 1:8a094db1347f 155 if ((err = SYS_I2CS_Shutdown(i2cs)) != E_NO_ERROR) {
elijahsj 1:8a094db1347f 156 return err;
elijahsj 1:8a094db1347f 157 }
elijahsj 1:8a094db1347f 158
elijahsj 1:8a094db1347f 159 return E_NO_ERROR;
elijahsj 1:8a094db1347f 160 }
elijahsj 1:8a094db1347f 161
elijahsj 1:8a094db1347f 162 /* ************************************************************************* */
elijahsj 1:8a094db1347f 163 void I2CS_Handler(mxc_i2cs_regs_t *i2cs)
elijahsj 1:8a094db1347f 164 {
elijahsj 1:8a094db1347f 165 uint32_t intfl;
elijahsj 1:8a094db1347f 166 uint8_t i;
elijahsj 1:8a094db1347f 167 int i2cs_index = MXC_I2CS_GET_IDX(i2cs);
elijahsj 1:8a094db1347f 168
elijahsj 1:8a094db1347f 169 // Save and clear the interrupt flags
elijahsj 1:8a094db1347f 170 intfl = i2cs->intfl;
elijahsj 1:8a094db1347f 171 i2cs->intfl = intfl;
elijahsj 1:8a094db1347f 172
elijahsj 1:8a094db1347f 173 // Process each interrupt
elijahsj 1:8a094db1347f 174 for(i = 0; i < 32; i++) {
elijahsj 1:8a094db1347f 175 if(intfl & (0x1 << i)) {
elijahsj 1:8a094db1347f 176 if(callbacks[i2cs_index][i] != NULL) {
elijahsj 1:8a094db1347f 177 callbacks[i2cs_index][i](i);
elijahsj 1:8a094db1347f 178 }
elijahsj 1:8a094db1347f 179 }
elijahsj 1:8a094db1347f 180 }
elijahsj 1:8a094db1347f 181
elijahsj 1:8a094db1347f 182 }
elijahsj 1:8a094db1347f 183
elijahsj 1:8a094db1347f 184 /* ************************************************************************* */
elijahsj 1:8a094db1347f 185 void I2CS_RegisterCallback(mxc_i2cs_regs_t *i2cs, uint8_t addr, i2cs_callback_fn callback)
elijahsj 1:8a094db1347f 186 {
elijahsj 1:8a094db1347f 187 int i2cs_index = MXC_I2CS_GET_IDX(i2cs);
elijahsj 1:8a094db1347f 188
elijahsj 1:8a094db1347f 189 // Make sure we don't overflow
elijahsj 1:8a094db1347f 190 MXC_ASSERT(addr < MXC_CFG_I2CS_BUFFER_SIZE);
elijahsj 1:8a094db1347f 191
elijahsj 1:8a094db1347f 192 if(callback != NULL) {
elijahsj 1:8a094db1347f 193 // Save the callback address
elijahsj 1:8a094db1347f 194 callbacks[i2cs_index][addr] = callback;
elijahsj 1:8a094db1347f 195
elijahsj 1:8a094db1347f 196 // Clear and Enable the interrupt for the given byte
elijahsj 1:8a094db1347f 197 i2cs->intfl = (0x1 << addr);
elijahsj 1:8a094db1347f 198 i2cs->inten |= (0x1 << addr);
elijahsj 1:8a094db1347f 199 } else {
elijahsj 1:8a094db1347f 200 // Disable and clear the interrupt
elijahsj 1:8a094db1347f 201 i2cs->inten &= ~(0x1 << addr);
elijahsj 1:8a094db1347f 202 i2cs->intfl = (0x1 << addr);
elijahsj 1:8a094db1347f 203
elijahsj 1:8a094db1347f 204 // Clear the callback address
elijahsj 1:8a094db1347f 205 callbacks[i2cs_index][addr] = NULL;
elijahsj 1:8a094db1347f 206 }
elijahsj 1:8a094db1347f 207 }
elijahsj 1:8a094db1347f 208
elijahsj 1:8a094db1347f 209 /**@} end of group i2cs*/