5.2.1 - Updated I2C files

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Committer:
group-onsemi
Date:
Wed Jan 25 20:34:15 2017 +0000
Revision:
0:098463de4c5d
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
group-onsemi 0:098463de4c5d 1 /* mbed Microcontroller Library
group-onsemi 0:098463de4c5d 2 * Copyright (c) 2006-2013 ARM Limited
group-onsemi 0:098463de4c5d 3 *
group-onsemi 0:098463de4c5d 4 * Licensed under the Apache License, Version 2.0 (the "License");
group-onsemi 0:098463de4c5d 5 * you may not use this file except in compliance with the License.
group-onsemi 0:098463de4c5d 6 * You may obtain a copy of the License at
group-onsemi 0:098463de4c5d 7 *
group-onsemi 0:098463de4c5d 8 * http://www.apache.org/licenses/LICENSE-2.0
group-onsemi 0:098463de4c5d 9 *
group-onsemi 0:098463de4c5d 10 * Unless required by applicable law or agreed to in writing, software
group-onsemi 0:098463de4c5d 11 * distributed under the License is distributed on an "AS IS" BASIS,
group-onsemi 0:098463de4c5d 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
group-onsemi 0:098463de4c5d 13 * See the License for the specific language governing permissions and
group-onsemi 0:098463de4c5d 14 * limitations under the License.
group-onsemi 0:098463de4c5d 15 */
group-onsemi 0:098463de4c5d 16 #include "mbed_assert.h"
group-onsemi 0:098463de4c5d 17
group-onsemi 0:098463de4c5d 18 #include "spi_api.h"
group-onsemi 0:098463de4c5d 19 #include "cmsis.h"
group-onsemi 0:098463de4c5d 20 #include "pinmap.h"
group-onsemi 0:098463de4c5d 21 #include "mbed_error.h"
group-onsemi 0:098463de4c5d 22
group-onsemi 0:098463de4c5d 23 #if DEVICE_SPI
group-onsemi 0:098463de4c5d 24
group-onsemi 0:098463de4c5d 25 static const SWM_Map SWM_SPI_SSEL[] = {
group-onsemi 0:098463de4c5d 26 {4, 16},
group-onsemi 0:098463de4c5d 27 {6, 8},
group-onsemi 0:098463de4c5d 28 };
group-onsemi 0:098463de4c5d 29
group-onsemi 0:098463de4c5d 30 static const SWM_Map SWM_SPI_SCLK[] = {
group-onsemi 0:098463de4c5d 31 {3, 24},
group-onsemi 0:098463de4c5d 32 {5, 16},
group-onsemi 0:098463de4c5d 33 };
group-onsemi 0:098463de4c5d 34
group-onsemi 0:098463de4c5d 35 static const SWM_Map SWM_SPI_MOSI[] = {
group-onsemi 0:098463de4c5d 36 {4, 0},
group-onsemi 0:098463de4c5d 37 {5, 24},
group-onsemi 0:098463de4c5d 38 };
group-onsemi 0:098463de4c5d 39
group-onsemi 0:098463de4c5d 40 static const SWM_Map SWM_SPI_MISO[] = {
group-onsemi 0:098463de4c5d 41 {4, 8},
group-onsemi 0:098463de4c5d 42 {6, 0},
group-onsemi 0:098463de4c5d 43 };
group-onsemi 0:098463de4c5d 44
group-onsemi 0:098463de4c5d 45 // bit flags for used SPIs
group-onsemi 0:098463de4c5d 46 static unsigned char spi_used = 0;
group-onsemi 0:098463de4c5d 47
group-onsemi 0:098463de4c5d 48 static int get_available_spi(void)
group-onsemi 0:098463de4c5d 49 {
group-onsemi 0:098463de4c5d 50 int i;
group-onsemi 0:098463de4c5d 51 for (i=0; i<2; i++) {
group-onsemi 0:098463de4c5d 52 if ((spi_used & (1 << i)) == 0)
group-onsemi 0:098463de4c5d 53 return i;
group-onsemi 0:098463de4c5d 54 }
group-onsemi 0:098463de4c5d 55 return -1;
group-onsemi 0:098463de4c5d 56 }
group-onsemi 0:098463de4c5d 57
group-onsemi 0:098463de4c5d 58 static inline void spi_disable(spi_t *obj);
group-onsemi 0:098463de4c5d 59 static inline void spi_enable(spi_t *obj);
group-onsemi 0:098463de4c5d 60
group-onsemi 0:098463de4c5d 61 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
group-onsemi 0:098463de4c5d 62 {
group-onsemi 0:098463de4c5d 63 int spi_n = get_available_spi();
group-onsemi 0:098463de4c5d 64 if (spi_n == -1) {
group-onsemi 0:098463de4c5d 65 error("No available SPI");
group-onsemi 0:098463de4c5d 66 }
group-onsemi 0:098463de4c5d 67 obj->spi_n = spi_n;
group-onsemi 0:098463de4c5d 68 spi_used |= (1 << spi_n);
group-onsemi 0:098463de4c5d 69
group-onsemi 0:098463de4c5d 70 obj->spi = (spi_n) ? (LPC_SPI0_Type *)(LPC_SPI1_BASE) : (LPC_SPI0_Type *)(LPC_SPI0_BASE);
group-onsemi 0:098463de4c5d 71
group-onsemi 0:098463de4c5d 72 const SWM_Map *swm;
group-onsemi 0:098463de4c5d 73 uint32_t regVal;
group-onsemi 0:098463de4c5d 74
group-onsemi 0:098463de4c5d 75 if (sclk != (PinName)NC) {
group-onsemi 0:098463de4c5d 76 swm = &SWM_SPI_SCLK[obj->spi_n];
group-onsemi 0:098463de4c5d 77 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
group-onsemi 0:098463de4c5d 78 LPC_SWM->PINASSIGN[swm->n] = regVal | ((sclk >> PIN_SHIFT) << swm->offset);
group-onsemi 0:098463de4c5d 79 }
group-onsemi 0:098463de4c5d 80
group-onsemi 0:098463de4c5d 81 if (mosi != (PinName)NC) {
group-onsemi 0:098463de4c5d 82 swm = &SWM_SPI_MOSI[obj->spi_n];
group-onsemi 0:098463de4c5d 83 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
group-onsemi 0:098463de4c5d 84 LPC_SWM->PINASSIGN[swm->n] = regVal | ((mosi >> PIN_SHIFT) << swm->offset);
group-onsemi 0:098463de4c5d 85 }
group-onsemi 0:098463de4c5d 86
group-onsemi 0:098463de4c5d 87 if (miso != (PinName)NC) {
group-onsemi 0:098463de4c5d 88 swm = &SWM_SPI_MISO[obj->spi_n];
group-onsemi 0:098463de4c5d 89 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
group-onsemi 0:098463de4c5d 90 LPC_SWM->PINASSIGN[swm->n] = regVal | ((miso >> PIN_SHIFT) << swm->offset);
group-onsemi 0:098463de4c5d 91 }
group-onsemi 0:098463de4c5d 92
group-onsemi 0:098463de4c5d 93 if (ssel != (PinName)NC) {
group-onsemi 0:098463de4c5d 94 swm = &SWM_SPI_SSEL[obj->spi_n];
group-onsemi 0:098463de4c5d 95 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset);
group-onsemi 0:098463de4c5d 96 LPC_SWM->PINASSIGN[swm->n] = regVal | ((ssel >> PIN_SHIFT) << swm->offset);
group-onsemi 0:098463de4c5d 97 }
group-onsemi 0:098463de4c5d 98
group-onsemi 0:098463de4c5d 99 // clear interrupts
group-onsemi 0:098463de4c5d 100 obj->spi->INTENCLR = 0x3f;
group-onsemi 0:098463de4c5d 101
group-onsemi 0:098463de4c5d 102 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (11 + obj->spi_n));
group-onsemi 0:098463de4c5d 103 LPC_SYSCON->PRESETCTRL &= ~(1 << obj->spi_n);
group-onsemi 0:098463de4c5d 104 LPC_SYSCON->PRESETCTRL |= (1 << obj->spi_n);
group-onsemi 0:098463de4c5d 105
group-onsemi 0:098463de4c5d 106 obj->spi->DLY = 2; // 2 SPI clock times pre-delay
group-onsemi 0:098463de4c5d 107 }
group-onsemi 0:098463de4c5d 108
group-onsemi 0:098463de4c5d 109 void spi_free(spi_t *obj)
group-onsemi 0:098463de4c5d 110 {
group-onsemi 0:098463de4c5d 111 }
group-onsemi 0:098463de4c5d 112
group-onsemi 0:098463de4c5d 113 void spi_format(spi_t *obj, int bits, int mode, int slave)
group-onsemi 0:098463de4c5d 114 {
group-onsemi 0:098463de4c5d 115 MBED_ASSERT(((bits >= 1) && (bits <= 16)) && ((mode >= 0) && (mode <= 3)));
group-onsemi 0:098463de4c5d 116 spi_disable(obj);
group-onsemi 0:098463de4c5d 117
group-onsemi 0:098463de4c5d 118 obj->spi->CFG &= ~((0x3 << 4) | (1 << 2));
group-onsemi 0:098463de4c5d 119 obj->spi->CFG |= ((mode & 0x3) << 4) | ((slave ? 0 : 1) << 2);
group-onsemi 0:098463de4c5d 120
group-onsemi 0:098463de4c5d 121 obj->spi->TXCTL &= ~( 0xF << 24);
group-onsemi 0:098463de4c5d 122 obj->spi->TXCTL |= ((bits - 1) << 24);
group-onsemi 0:098463de4c5d 123
group-onsemi 0:098463de4c5d 124 spi_enable(obj);
group-onsemi 0:098463de4c5d 125 }
group-onsemi 0:098463de4c5d 126
group-onsemi 0:098463de4c5d 127 void spi_frequency(spi_t *obj, int hz)
group-onsemi 0:098463de4c5d 128 {
group-onsemi 0:098463de4c5d 129 spi_disable(obj);
group-onsemi 0:098463de4c5d 130
group-onsemi 0:098463de4c5d 131 // rise DIV value if it cannot be divided
group-onsemi 0:098463de4c5d 132 obj->spi->DIV = (SystemCoreClock + (hz - 1))/hz - 1;
group-onsemi 0:098463de4c5d 133
group-onsemi 0:098463de4c5d 134 spi_enable(obj);
group-onsemi 0:098463de4c5d 135 }
group-onsemi 0:098463de4c5d 136
group-onsemi 0:098463de4c5d 137 static inline void spi_disable(spi_t *obj)
group-onsemi 0:098463de4c5d 138 {
group-onsemi 0:098463de4c5d 139 obj->spi->CFG &= ~(1 << 0);
group-onsemi 0:098463de4c5d 140 }
group-onsemi 0:098463de4c5d 141
group-onsemi 0:098463de4c5d 142 static inline void spi_enable(spi_t *obj)
group-onsemi 0:098463de4c5d 143 {
group-onsemi 0:098463de4c5d 144 obj->spi->CFG |= (1 << 0);
group-onsemi 0:098463de4c5d 145 }
group-onsemi 0:098463de4c5d 146
group-onsemi 0:098463de4c5d 147 static inline int spi_readable(spi_t *obj)
group-onsemi 0:098463de4c5d 148 {
group-onsemi 0:098463de4c5d 149 return obj->spi->STAT & (1 << 0);
group-onsemi 0:098463de4c5d 150 }
group-onsemi 0:098463de4c5d 151
group-onsemi 0:098463de4c5d 152 static inline int spi_writeable(spi_t *obj)
group-onsemi 0:098463de4c5d 153 {
group-onsemi 0:098463de4c5d 154 return obj->spi->STAT & (1 << 1);
group-onsemi 0:098463de4c5d 155 }
group-onsemi 0:098463de4c5d 156
group-onsemi 0:098463de4c5d 157 static inline void spi_write(spi_t *obj, int value)
group-onsemi 0:098463de4c5d 158 {
group-onsemi 0:098463de4c5d 159 while (!spi_writeable(obj));
group-onsemi 0:098463de4c5d 160 // end of transfer
group-onsemi 0:098463de4c5d 161 obj->spi->TXCTL |= (1 << 20);
group-onsemi 0:098463de4c5d 162 obj->spi->TXDAT = (value & 0xffff);
group-onsemi 0:098463de4c5d 163 }
group-onsemi 0:098463de4c5d 164
group-onsemi 0:098463de4c5d 165 static inline int spi_read(spi_t *obj)
group-onsemi 0:098463de4c5d 166 {
group-onsemi 0:098463de4c5d 167 while (!spi_readable(obj));
group-onsemi 0:098463de4c5d 168 return (obj->spi->RXDAT & 0xFFFF);
group-onsemi 0:098463de4c5d 169 }
group-onsemi 0:098463de4c5d 170
group-onsemi 0:098463de4c5d 171 int spi_master_write(spi_t *obj, int value)
group-onsemi 0:098463de4c5d 172 {
group-onsemi 0:098463de4c5d 173 spi_write(obj, value);
group-onsemi 0:098463de4c5d 174 return spi_read(obj);
group-onsemi 0:098463de4c5d 175 }
group-onsemi 0:098463de4c5d 176
group-onsemi 0:098463de4c5d 177 int spi_busy(spi_t *obj)
group-onsemi 0:098463de4c5d 178 {
group-onsemi 0:098463de4c5d 179 // checking RXOV(Receiver Overrun interrupt flag)
group-onsemi 0:098463de4c5d 180 return obj->spi->STAT & (1 << 2);
group-onsemi 0:098463de4c5d 181 }
group-onsemi 0:098463de4c5d 182
group-onsemi 0:098463de4c5d 183 int spi_slave_receive(spi_t *obj)
group-onsemi 0:098463de4c5d 184 {
group-onsemi 0:098463de4c5d 185 return (spi_readable(obj) && !spi_busy(obj)) ? (1) : (0);
group-onsemi 0:098463de4c5d 186 }
group-onsemi 0:098463de4c5d 187
group-onsemi 0:098463de4c5d 188 int spi_slave_read(spi_t *obj)
group-onsemi 0:098463de4c5d 189 {
group-onsemi 0:098463de4c5d 190 return (obj->spi->RXDAT & 0xFFFF);
group-onsemi 0:098463de4c5d 191 }
group-onsemi 0:098463de4c5d 192
group-onsemi 0:098463de4c5d 193 void spi_slave_write(spi_t *obj, int value)
group-onsemi 0:098463de4c5d 194 {
group-onsemi 0:098463de4c5d 195 while (spi_writeable(obj) == 0);
group-onsemi 0:098463de4c5d 196 obj->spi->TXDAT = value;
group-onsemi 0:098463de4c5d 197 }
group-onsemi 0:098463de4c5d 198
group-onsemi 0:098463de4c5d 199 #endif