mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
186:707f6e361f3e
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Anna Bridge 186:707f6e361f3e 1 /*******************************************************************************
Anna Bridge 186:707f6e361f3e 2 * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
Anna Bridge 186:707f6e361f3e 3 *
Anna Bridge 186:707f6e361f3e 4 * Permission is hereby granted, free of charge, to any person obtaining a
Anna Bridge 186:707f6e361f3e 5 * copy of this software and associated documentation files (the "Software"),
Anna Bridge 186:707f6e361f3e 6 * to deal in the Software without restriction, including without limitation
Anna Bridge 186:707f6e361f3e 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Anna Bridge 186:707f6e361f3e 8 * and/or sell copies of the Software, and to permit persons to whom the
Anna Bridge 186:707f6e361f3e 9 * Software is furnished to do so, subject to the following conditions:
Anna Bridge 186:707f6e361f3e 10 *
Anna Bridge 186:707f6e361f3e 11 * The above copyright notice and this permission notice shall be included
Anna Bridge 186:707f6e361f3e 12 * in all copies or substantial portions of the Software.
Anna Bridge 186:707f6e361f3e 13 *
Anna Bridge 186:707f6e361f3e 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Anna Bridge 186:707f6e361f3e 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Anna Bridge 186:707f6e361f3e 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Anna Bridge 186:707f6e361f3e 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
Anna Bridge 186:707f6e361f3e 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
Anna Bridge 186:707f6e361f3e 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Anna Bridge 186:707f6e361f3e 20 * OTHER DEALINGS IN THE SOFTWARE.
Anna Bridge 186:707f6e361f3e 21 *
Anna Bridge 186:707f6e361f3e 22 * Except as contained in this notice, the name of Maxim Integrated
Anna Bridge 186:707f6e361f3e 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
Anna Bridge 186:707f6e361f3e 24 * Products, Inc. Branding Policy.
Anna Bridge 186:707f6e361f3e 25 *
Anna Bridge 186:707f6e361f3e 26 * The mere transfer of this software does not imply any licenses
Anna Bridge 186:707f6e361f3e 27 * of trade secrets, proprietary technology, copyrights, patents,
Anna Bridge 186:707f6e361f3e 28 * trademarks, maskwork rights, or any other form of intellectual
Anna Bridge 186:707f6e361f3e 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
Anna Bridge 186:707f6e361f3e 30 * ownership rights.
Anna Bridge 186:707f6e361f3e 31 *******************************************************************************
Anna Bridge 186:707f6e361f3e 32 */
Anna Bridge 186:707f6e361f3e 33
Anna Bridge 186:707f6e361f3e 34 #include "mbed_assert.h"
Anna Bridge 186:707f6e361f3e 35 #include "mbed_critical.h"
Anna Bridge 186:707f6e361f3e 36 #include "spi_api.h" // mbed HAL
Anna Bridge 186:707f6e361f3e 37 #include "spim_regs.h" // bare metal
Anna Bridge 186:707f6e361f3e 38 #include "spim.h" // Maxim CMSIS driver
Anna Bridge 186:707f6e361f3e 39 #include "pinmap.h"
Anna Bridge 186:707f6e361f3e 40 #include "PeripheralPins.h"
Anna Bridge 186:707f6e361f3e 41
Anna Bridge 186:707f6e361f3e 42 //******************************************************************************
Anna Bridge 186:707f6e361f3e 43 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
Anna Bridge 186:707f6e361f3e 44 {
Anna Bridge 186:707f6e361f3e 45 // Make sure pins are pointing to the same SPI instance
Anna Bridge 186:707f6e361f3e 46 SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
Anna Bridge 186:707f6e361f3e 47 SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
Anna Bridge 186:707f6e361f3e 48 SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
Anna Bridge 186:707f6e361f3e 49 SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
Anna Bridge 186:707f6e361f3e 50
Anna Bridge 186:707f6e361f3e 51 SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
Anna Bridge 186:707f6e361f3e 52 SPIName spi_cntl;
Anna Bridge 186:707f6e361f3e 53
Anna Bridge 186:707f6e361f3e 54 // Control is SCK and optionaly SS
Anna Bridge 186:707f6e361f3e 55 if ((SPIName)spi_ssel != (SPIName)NC) {
Anna Bridge 186:707f6e361f3e 56 spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
Anna Bridge 186:707f6e361f3e 57 } else {
Anna Bridge 186:707f6e361f3e 58 spi_cntl = spi_sclk;
Anna Bridge 186:707f6e361f3e 59 }
Anna Bridge 186:707f6e361f3e 60
Anna Bridge 186:707f6e361f3e 61 SPIName spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
Anna Bridge 186:707f6e361f3e 62
Anna Bridge 186:707f6e361f3e 63 MBED_ASSERT((SPIName)spi != (SPIName)NC);
Anna Bridge 186:707f6e361f3e 64
Anna Bridge 186:707f6e361f3e 65 obj->spi = (mxc_spim_regs_t *)spi;
Anna Bridge 186:707f6e361f3e 66
Anna Bridge 186:707f6e361f3e 67 // Merge pin function requests for use with CMSIS init func
Anna Bridge 186:707f6e361f3e 68 ioman_req_t io_req;
Anna Bridge 186:707f6e361f3e 69 pin_function_t *pin_func;
Anna Bridge 186:707f6e361f3e 70 pin_func = (pin_function_t *)pinmap_find_function(mosi, PinMap_SPI_MOSI);
Anna Bridge 186:707f6e361f3e 71 io_req.value = pin_func->req_val;
Anna Bridge 186:707f6e361f3e 72 pin_func = (pin_function_t *)pinmap_find_function(miso, PinMap_SPI_MISO);
Anna Bridge 186:707f6e361f3e 73 io_req.value |= pin_func->req_val;
Anna Bridge 186:707f6e361f3e 74 pin_func = (pin_function_t *)pinmap_find_function(sclk, PinMap_SPI_SCLK);
Anna Bridge 186:707f6e361f3e 75 io_req.value |= pin_func->req_val;
Anna Bridge 186:707f6e361f3e 76 if ((SPIName)spi_ssel != (SPIName)NC) {
Anna Bridge 186:707f6e361f3e 77 pin_func = (pin_function_t *)pinmap_find_function(ssel, PinMap_SPI_SSEL);
Anna Bridge 186:707f6e361f3e 78 io_req.value |= pin_func->req_val;
Anna Bridge 186:707f6e361f3e 79 }
Anna Bridge 186:707f6e361f3e 80
Anna Bridge 186:707f6e361f3e 81 // Using req and ack pointers of last pin function lookup
Anna Bridge 186:707f6e361f3e 82 sys_cfg_spim_t sys_cfg;
Anna Bridge 186:707f6e361f3e 83 sys_cfg.io_cfg.req_reg = pin_func->reg_req;
Anna Bridge 186:707f6e361f3e 84 sys_cfg.io_cfg.ack_reg = pin_func->reg_ack;
Anna Bridge 186:707f6e361f3e 85 sys_cfg.io_cfg.req_val = io_req;
Anna Bridge 186:707f6e361f3e 86 sys_cfg.clk_scale = CLKMAN_SCALE_AUTO;
Anna Bridge 186:707f6e361f3e 87
Anna Bridge 186:707f6e361f3e 88 // Defaults
Anna Bridge 186:707f6e361f3e 89 spim_cfg_t spim_cfg;
Anna Bridge 186:707f6e361f3e 90 spim_cfg.mode = 0;
Anna Bridge 186:707f6e361f3e 91 spim_cfg.ssel_pol = 0;
Anna Bridge 186:707f6e361f3e 92 spim_cfg.baud = 1000000;
Anna Bridge 186:707f6e361f3e 93
Anna Bridge 186:707f6e361f3e 94 SPIM_Init(obj->spi, &spim_cfg, &sys_cfg);
Anna Bridge 186:707f6e361f3e 95
Anna Bridge 186:707f6e361f3e 96 obj->index = MXC_SPIM_GET_IDX(obj->spi);
Anna Bridge 186:707f6e361f3e 97 }
Anna Bridge 186:707f6e361f3e 98
Anna Bridge 186:707f6e361f3e 99 //******************************************************************************
Anna Bridge 186:707f6e361f3e 100 void spi_format(spi_t *obj, int bits, int mode, int slave)
Anna Bridge 186:707f6e361f3e 101 {
Anna Bridge 186:707f6e361f3e 102 // Check the validity of the inputs
Anna Bridge 186:707f6e361f3e 103 MBED_ASSERT(bits == 8);
Anna Bridge 186:707f6e361f3e 104
Anna Bridge 186:707f6e361f3e 105 // Only supports master mode
Anna Bridge 186:707f6e361f3e 106 MBED_ASSERT(!slave);
Anna Bridge 186:707f6e361f3e 107
Anna Bridge 186:707f6e361f3e 108 // Set the mode
Anna Bridge 186:707f6e361f3e 109 obj->spi->mstr_cfg &= ~(MXC_F_SPIM_MSTR_CFG_SPI_MODE);
Anna Bridge 186:707f6e361f3e 110 obj->spi->mstr_cfg |= (mode << MXC_F_SPIM_MSTR_CFG_SPI_MODE_POS);
Anna Bridge 186:707f6e361f3e 111 }
Anna Bridge 186:707f6e361f3e 112
Anna Bridge 186:707f6e361f3e 113 //******************************************************************************
Anna Bridge 186:707f6e361f3e 114 void spi_frequency(spi_t *obj, int hz)
Anna Bridge 186:707f6e361f3e 115 {
Anna Bridge 186:707f6e361f3e 116 // Maximum frequency is half the system frequency
Anna Bridge 186:707f6e361f3e 117 MBED_ASSERT((unsigned int)hz <= (SystemCoreClock / 2));
Anna Bridge 186:707f6e361f3e 118 unsigned clocks = ((SystemCoreClock / 2) / hz);
Anna Bridge 186:707f6e361f3e 119
Anna Bridge 186:707f6e361f3e 120 // Figure out the divider ratio
Anna Bridge 186:707f6e361f3e 121 int clk_div = 1;
Anna Bridge 186:707f6e361f3e 122 while(clk_div < 10) {
Anna Bridge 186:707f6e361f3e 123 if(clocks < 0x10) {
Anna Bridge 186:707f6e361f3e 124 break;
Anna Bridge 186:707f6e361f3e 125 }
Anna Bridge 186:707f6e361f3e 126 clk_div++;
Anna Bridge 186:707f6e361f3e 127 clocks = clocks >> 1;
Anna Bridge 186:707f6e361f3e 128 }
Anna Bridge 186:707f6e361f3e 129
Anna Bridge 186:707f6e361f3e 130 // Turn on the SPI clock
Anna Bridge 186:707f6e361f3e 131 if(obj->index == 0) {
Anna Bridge 186:707f6e361f3e 132 MXC_CLKMAN->sys_clk_ctrl_11_spi0 = clk_div;
Anna Bridge 186:707f6e361f3e 133 } else if(obj->index == 1) {
Anna Bridge 186:707f6e361f3e 134 MXC_CLKMAN->sys_clk_ctrl_12_spi1 = clk_div;
Anna Bridge 186:707f6e361f3e 135 } else if(obj->index == 2) {
Anna Bridge 186:707f6e361f3e 136 MXC_CLKMAN->sys_clk_ctrl_13_spi2 = clk_div;
Anna Bridge 186:707f6e361f3e 137 } else {
Anna Bridge 186:707f6e361f3e 138 MBED_ASSERT(0);
Anna Bridge 186:707f6e361f3e 139 }
Anna Bridge 186:707f6e361f3e 140
Anna Bridge 186:707f6e361f3e 141 // Set the number of clocks to hold sclk high and low
Anna Bridge 186:707f6e361f3e 142 MXC_SET_FIELD(&obj->spi->mstr_cfg,
Anna Bridge 186:707f6e361f3e 143 (MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK | MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK),
Anna Bridge 186:707f6e361f3e 144 ((clocks << MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK_POS) | (clocks << MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK_POS)));
Anna Bridge 186:707f6e361f3e 145 }
Anna Bridge 186:707f6e361f3e 146
Anna Bridge 186:707f6e361f3e 147 //******************************************************************************
Anna Bridge 186:707f6e361f3e 148 int spi_master_write(spi_t *obj, int value)
Anna Bridge 186:707f6e361f3e 149 {
Anna Bridge 186:707f6e361f3e 150 spim_req_t req;
Anna Bridge 186:707f6e361f3e 151 uint8_t out;
Anna Bridge 186:707f6e361f3e 152 uint8_t in;
Anna Bridge 186:707f6e361f3e 153
Anna Bridge 186:707f6e361f3e 154 out = value;
Anna Bridge 186:707f6e361f3e 155
Anna Bridge 186:707f6e361f3e 156 req.ssel = 0;
Anna Bridge 186:707f6e361f3e 157 req.deass = 0;
Anna Bridge 186:707f6e361f3e 158 req.tx_data = &out;
Anna Bridge 186:707f6e361f3e 159 req.rx_data = &in;
Anna Bridge 186:707f6e361f3e 160 req.width = SPIM_WIDTH_1;
Anna Bridge 186:707f6e361f3e 161 req.len = 1;
Anna Bridge 186:707f6e361f3e 162 req.ssel = 0;
Anna Bridge 186:707f6e361f3e 163 req.deass = 1;
Anna Bridge 186:707f6e361f3e 164 req.callback = NULL;
Anna Bridge 186:707f6e361f3e 165
Anna Bridge 186:707f6e361f3e 166 SPIM_Trans(obj->spi, &req);
Anna Bridge 186:707f6e361f3e 167
Anna Bridge 186:707f6e361f3e 168 return *req.rx_data;
Anna Bridge 186:707f6e361f3e 169 }
Anna Bridge 186:707f6e361f3e 170
Anna Bridge 186:707f6e361f3e 171 //******************************************************************************
Anna Bridge 186:707f6e361f3e 172 int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill)
Anna Bridge 186:707f6e361f3e 173 {
Anna Bridge 186:707f6e361f3e 174 spim_req_t req;
Anna Bridge 186:707f6e361f3e 175
Anna Bridge 186:707f6e361f3e 176 if (!(tx_length | rx_length) ||
Anna Bridge 186:707f6e361f3e 177 (tx_length < 0) ||
Anna Bridge 186:707f6e361f3e 178 (rx_length < 0)) {
Anna Bridge 186:707f6e361f3e 179 return 0;
Anna Bridge 186:707f6e361f3e 180 }
Anna Bridge 186:707f6e361f3e 181
Anna Bridge 186:707f6e361f3e 182 req.width = SPIM_WIDTH_1;
Anna Bridge 186:707f6e361f3e 183 req.ssel = 0;
Anna Bridge 186:707f6e361f3e 184 req.deass = 1;
Anna Bridge 186:707f6e361f3e 185 req.callback = NULL;
Anna Bridge 186:707f6e361f3e 186
Anna Bridge 186:707f6e361f3e 187 core_util_critical_section_enter();
Anna Bridge 186:707f6e361f3e 188 if (tx_length == rx_length) {
Anna Bridge 186:707f6e361f3e 189 req.tx_data = (uint8_t *)tx_buffer;
Anna Bridge 186:707f6e361f3e 190 req.rx_data = (uint8_t *)rx_buffer;
Anna Bridge 186:707f6e361f3e 191 req.len = tx_length;
Anna Bridge 186:707f6e361f3e 192 SPIM_Trans(obj->spi, &req);
Anna Bridge 186:707f6e361f3e 193 } else if (tx_length < rx_length) {
Anna Bridge 186:707f6e361f3e 194 req.tx_data = (tx_length > 0) ? (uint8_t *)tx_buffer : NULL;
Anna Bridge 186:707f6e361f3e 195 req.rx_data = (uint8_t *)rx_buffer;
Anna Bridge 186:707f6e361f3e 196 req.len = (tx_length > 0) ? tx_length : rx_length;
Anna Bridge 186:707f6e361f3e 197 SPIM_Trans(obj->spi, &req);
Anna Bridge 186:707f6e361f3e 198
Anna Bridge 186:707f6e361f3e 199 if (tx_length) {
Anna Bridge 186:707f6e361f3e 200 req.tx_data = NULL;
Anna Bridge 186:707f6e361f3e 201 req.rx_data = (uint8_t *)(rx_buffer + tx_length);
Anna Bridge 186:707f6e361f3e 202 req.len = rx_length - tx_length;
Anna Bridge 186:707f6e361f3e 203 SPIM_Trans(obj->spi, &req);
Anna Bridge 186:707f6e361f3e 204 }
Anna Bridge 186:707f6e361f3e 205 } else {
Anna Bridge 186:707f6e361f3e 206 req.tx_data = (uint8_t *)tx_buffer;
Anna Bridge 186:707f6e361f3e 207 req.rx_data = (rx_length > 0) ? (uint8_t *)rx_buffer : NULL;
Anna Bridge 186:707f6e361f3e 208 req.len = (rx_length > 0) ? rx_length : tx_length;
Anna Bridge 186:707f6e361f3e 209 SPIM_Trans(obj->spi, &req);
Anna Bridge 186:707f6e361f3e 210
Anna Bridge 186:707f6e361f3e 211 if (rx_length) {
Anna Bridge 186:707f6e361f3e 212 req.tx_data = (uint8_t *)(tx_buffer + rx_length);
Anna Bridge 186:707f6e361f3e 213 req.rx_data = NULL;
Anna Bridge 186:707f6e361f3e 214 req.len = tx_length - rx_length;
Anna Bridge 186:707f6e361f3e 215 SPIM_Trans(obj->spi, &req);
Anna Bridge 186:707f6e361f3e 216 }
Anna Bridge 186:707f6e361f3e 217 }
Anna Bridge 186:707f6e361f3e 218 core_util_critical_section_exit();
Anna Bridge 186:707f6e361f3e 219
Anna Bridge 186:707f6e361f3e 220 while (SPIM_Busy(obj->spi));
Anna Bridge 186:707f6e361f3e 221
Anna Bridge 186:707f6e361f3e 222 return tx_length > rx_length ? tx_length : rx_length;
Anna Bridge 186:707f6e361f3e 223 }
Anna Bridge 186:707f6e361f3e 224
Anna Bridge 186:707f6e361f3e 225 //******************************************************************************
Anna Bridge 186:707f6e361f3e 226 int spi_busy(spi_t *obj)
Anna Bridge 186:707f6e361f3e 227 {
Anna Bridge 186:707f6e361f3e 228 return SPIM_Busy(obj->spi);
Anna Bridge 186:707f6e361f3e 229 }
Anna Bridge 186:707f6e361f3e 230
Anna Bridge 186:707f6e361f3e 231 //******************************************************************************
Anna Bridge 186:707f6e361f3e 232 uint8_t spi_get_module(spi_t *obj)
Anna Bridge 186:707f6e361f3e 233 {
Anna Bridge 186:707f6e361f3e 234 return obj->index;
Anna Bridge 186:707f6e361f3e 235 }