Maintool / mbed-src-v4

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Thu Feb 20 23:00:08 2014 +0000
Revision:
103:9b881da47c92
Child:
222:96162ccfbf43
Synchronized with git revision 1f2da5f6047218c8c45334c11bdaaaeab3c18841

Full URL: https://github.com/mbedmicro/mbed/commit/1f2da5f6047218c8c45334c11bdaaaeab3c18841/

NXP master merge

Who changed what in which revision?

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