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
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 189:f392fc9709a3 1 /* mbed Microcontroller Library
AnnaBridge 189:f392fc9709a3 2 * Copyright (c) 2013-2016 Realtek Semiconductor Corp.
AnnaBridge 189:f392fc9709a3 3 *
AnnaBridge 189:f392fc9709a3 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 189:f392fc9709a3 5 * you may not use this file except in compliance with the License.
AnnaBridge 189:f392fc9709a3 6 * You may obtain a copy of the License at
AnnaBridge 189:f392fc9709a3 7 *
AnnaBridge 189:f392fc9709a3 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 189:f392fc9709a3 9 *
AnnaBridge 189:f392fc9709a3 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 189:f392fc9709a3 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 189:f392fc9709a3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 189:f392fc9709a3 13 * See the License for the specific language governing permissions and
AnnaBridge 189:f392fc9709a3 14 * limitations under the License.
AnnaBridge 189:f392fc9709a3 15 */
AnnaBridge 189:f392fc9709a3 16
AnnaBridge 189:f392fc9709a3 17 #include "objects.h"
AnnaBridge 189:f392fc9709a3 18 #include "spi_api.h"
AnnaBridge 189:f392fc9709a3 19 #include "spi_ex_api.h"
AnnaBridge 189:f392fc9709a3 20 #include "PinNames.h"
AnnaBridge 189:f392fc9709a3 21 #include "pinmap.h"
AnnaBridge 189:f392fc9709a3 22 #include "hal_ssi.h"
AnnaBridge 189:f392fc9709a3 23
AnnaBridge 189:f392fc9709a3 24 #ifdef CONFIG_MBED_ENABLED
AnnaBridge 189:f392fc9709a3 25 #include "platform_stdlib.h"
AnnaBridge 189:f392fc9709a3 26 #endif
AnnaBridge 189:f392fc9709a3 27
AnnaBridge 189:f392fc9709a3 28 extern u32 SystemGetCpuClk(VOID);
AnnaBridge 189:f392fc9709a3 29 extern VOID HAL_GPIO_PullCtrl(u32 pin, u32 mode);
AnnaBridge 189:f392fc9709a3 30
AnnaBridge 189:f392fc9709a3 31 void spi_tx_done_callback(VOID *obj);
AnnaBridge 189:f392fc9709a3 32 void spi_rx_done_callback(VOID *obj);
AnnaBridge 189:f392fc9709a3 33 void spi_bus_tx_done_callback(VOID *obj);
AnnaBridge 189:f392fc9709a3 34
AnnaBridge 189:f392fc9709a3 35 #ifdef CONFIG_GDMA_EN
AnnaBridge 189:f392fc9709a3 36 HAL_GDMA_OP SpiGdmaOp;
AnnaBridge 189:f392fc9709a3 37 #endif
AnnaBridge 189:f392fc9709a3 38
AnnaBridge 189:f392fc9709a3 39 uint8_t SPI0_IS_AS_SLAVE = 0;
AnnaBridge 189:f392fc9709a3 40
AnnaBridge 189:f392fc9709a3 41 //TODO: Load default Setting: It should be loaded from external setting file.
AnnaBridge 189:f392fc9709a3 42 extern const DW_SSI_DEFAULT_SETTING SpiDefaultSetting;
AnnaBridge 189:f392fc9709a3 43
AnnaBridge 189:f392fc9709a3 44 #ifdef CONFIG_MBED_ENABLED
AnnaBridge 189:f392fc9709a3 45 #include "PeripheralPins.h"
AnnaBridge 189:f392fc9709a3 46 #else
AnnaBridge 189:f392fc9709a3 47 static const PinMap PinMap_SSI_MOSI[] = {
AnnaBridge 189:f392fc9709a3 48 {PE_2, RTL_PIN_PERI(SPI0, 0, S0), RTL_PIN_FUNC(SPI0, S0)},
AnnaBridge 189:f392fc9709a3 49 {PC_2, RTL_PIN_PERI(SPI0, 0, S1), RTL_PIN_FUNC(SPI0, S1)},
AnnaBridge 189:f392fc9709a3 50 {PA_1, RTL_PIN_PERI(SPI1, 1, S0), RTL_PIN_FUNC(SPI1, S0)},
AnnaBridge 189:f392fc9709a3 51 {PB_6, RTL_PIN_PERI(SPI1, 1, S1), RTL_PIN_FUNC(SPI1, S1)},
AnnaBridge 189:f392fc9709a3 52 {PD_6, RTL_PIN_PERI(SPI1, 1, S2), RTL_PIN_FUNC(SPI1, S2)},
AnnaBridge 189:f392fc9709a3 53 {PG_2, RTL_PIN_PERI(SPI2, 2, S0), RTL_PIN_FUNC(SPI2, S0)},
AnnaBridge 189:f392fc9709a3 54 {PE_6, RTL_PIN_PERI(SPI2, 2, S1), RTL_PIN_FUNC(SPI2, S1)},
AnnaBridge 189:f392fc9709a3 55 {PD_2, RTL_PIN_PERI(SPI2, 2, S2), RTL_PIN_FUNC(SPI2, S2)},
AnnaBridge 189:f392fc9709a3 56 {NC, NC, 0}
AnnaBridge 189:f392fc9709a3 57 };
AnnaBridge 189:f392fc9709a3 58
AnnaBridge 189:f392fc9709a3 59 static const PinMap PinMap_SSI_MISO[] = {
AnnaBridge 189:f392fc9709a3 60 {PE_3, RTL_PIN_PERI(SPI0, 0, S0), RTL_PIN_FUNC(SPI0, S0)},
AnnaBridge 189:f392fc9709a3 61 {PC_3, RTL_PIN_PERI(SPI0, 0, S1), RTL_PIN_FUNC(SPI0, S1)},
AnnaBridge 189:f392fc9709a3 62 {PA_0, RTL_PIN_PERI(SPI1, 1, S0), RTL_PIN_FUNC(SPI1, S0)},
AnnaBridge 189:f392fc9709a3 63 {PB_7, RTL_PIN_PERI(SPI1, 1, S1), RTL_PIN_FUNC(SPI1, S1)},
AnnaBridge 189:f392fc9709a3 64 {PD_7, RTL_PIN_PERI(SPI1, 1, S2), RTL_PIN_FUNC(SPI1, S2)},
AnnaBridge 189:f392fc9709a3 65 {PG_3, RTL_PIN_PERI(SPI2, 2, S0), RTL_PIN_FUNC(SPI2, S0)},
AnnaBridge 189:f392fc9709a3 66 {PE_7, RTL_PIN_PERI(SPI2, 2, S1), RTL_PIN_FUNC(SPI2, S1)},
AnnaBridge 189:f392fc9709a3 67 {PD_3, RTL_PIN_PERI(SPI2, 2, S2), RTL_PIN_FUNC(SPI2, S2)},
AnnaBridge 189:f392fc9709a3 68 {NC, NC, 0}
AnnaBridge 189:f392fc9709a3 69 };
AnnaBridge 189:f392fc9709a3 70 #endif
AnnaBridge 189:f392fc9709a3 71
AnnaBridge 189:f392fc9709a3 72 void spi_init (spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
AnnaBridge 189:f392fc9709a3 73 {
AnnaBridge 189:f392fc9709a3 74 SSI_DBG_ENTRANCE("spi_init()\n");
AnnaBridge 189:f392fc9709a3 75
AnnaBridge 189:f392fc9709a3 76 int ssi_mosi, ssi_miso, ssi_peri;
AnnaBridge 189:f392fc9709a3 77 uint8_t ssi_idx, ssi_pinmux;
AnnaBridge 189:f392fc9709a3 78 PHAL_SSI_ADAPTOR pHalSsiAdaptor;
AnnaBridge 189:f392fc9709a3 79 PHAL_SSI_OP pHalSsiOp;
AnnaBridge 189:f392fc9709a3 80
AnnaBridge 189:f392fc9709a3 81 _memset((void*)obj, 0, sizeof(spi_t));
AnnaBridge 189:f392fc9709a3 82 obj->state = 0;
AnnaBridge 189:f392fc9709a3 83
AnnaBridge 189:f392fc9709a3 84 uint32_t SystemClock = SystemGetCpuClk();
AnnaBridge 189:f392fc9709a3 85 uint32_t MaxSsiFreq = (SystemClock >> 2) >> 1;
AnnaBridge 189:f392fc9709a3 86
AnnaBridge 189:f392fc9709a3 87 /* SsiClockDivider doesn't support odd number */
AnnaBridge 189:f392fc9709a3 88 DBG_SSI_INFO("SystemClock: %d\n", SystemClock);
AnnaBridge 189:f392fc9709a3 89 DBG_SSI_INFO("MaxSsiFreq : %d\n", MaxSsiFreq);
AnnaBridge 189:f392fc9709a3 90
AnnaBridge 189:f392fc9709a3 91 ssi_mosi = pinmap_peripheral(mosi, PinMap_SSI_MOSI);
AnnaBridge 189:f392fc9709a3 92 ssi_miso = pinmap_peripheral(miso, PinMap_SSI_MISO);
AnnaBridge 189:f392fc9709a3 93
AnnaBridge 189:f392fc9709a3 94 ssi_peri = pinmap_merge(ssi_mosi, ssi_miso);
AnnaBridge 189:f392fc9709a3 95 if (unlikely(ssi_peri == NC)) {
AnnaBridge 189:f392fc9709a3 96 DBG_SSI_ERR("spi_init(): Cannot find matched SSI index.\n");
AnnaBridge 189:f392fc9709a3 97 return;
AnnaBridge 189:f392fc9709a3 98 }
AnnaBridge 189:f392fc9709a3 99 obj->sclk = (u8)sclk;
AnnaBridge 189:f392fc9709a3 100 ssi_idx = RTL_GET_PERI_IDX(ssi_peri);
AnnaBridge 189:f392fc9709a3 101 ssi_pinmux = RTL_GET_PERI_SEL(ssi_peri);
AnnaBridge 189:f392fc9709a3 102 DBG_SSI_INFO("ssi_peri: %d, ssi_idx: %d, ssi_pinmux: %d\n", ssi_peri, ssi_idx, ssi_pinmux);
AnnaBridge 189:f392fc9709a3 103
AnnaBridge 189:f392fc9709a3 104 pHalSsiAdaptor = &obj->spi_adp;
AnnaBridge 189:f392fc9709a3 105 pHalSsiOp = &obj->spi_op;
AnnaBridge 189:f392fc9709a3 106
AnnaBridge 189:f392fc9709a3 107 pHalSsiAdaptor->Index = ssi_idx;
AnnaBridge 189:f392fc9709a3 108 pHalSsiAdaptor->PinmuxSelect = ssi_pinmux;
AnnaBridge 189:f392fc9709a3 109 pHalSsiAdaptor->Role = SSI_MASTER;
AnnaBridge 189:f392fc9709a3 110
AnnaBridge 189:f392fc9709a3 111 HalSsiOpInit((VOID*)pHalSsiOp);
AnnaBridge 189:f392fc9709a3 112
AnnaBridge 189:f392fc9709a3 113 pHalSsiOp->HalSsiSetDeviceRole(pHalSsiAdaptor, pHalSsiAdaptor->Role);
AnnaBridge 189:f392fc9709a3 114
AnnaBridge 189:f392fc9709a3 115 /* Pinmux workaround */
AnnaBridge 189:f392fc9709a3 116 if ((ssi_idx == 0) && (ssi_pinmux == SSI0_MUX_TO_GPIOC)) {
AnnaBridge 189:f392fc9709a3 117 EEPROM_PIN_CTRL(OFF);
AnnaBridge 189:f392fc9709a3 118 }
AnnaBridge 189:f392fc9709a3 119
AnnaBridge 189:f392fc9709a3 120 if ((ssi_idx == 0) && (ssi_pinmux == SSI0_MUX_TO_GPIOE)) {
AnnaBridge 189:f392fc9709a3 121 DBG_SSI_WARN(ANSI_COLOR_MAGENTA"SPI0 Pin may conflict with JTAG\r\n"ANSI_COLOR_RESET);
AnnaBridge 189:f392fc9709a3 122 }
AnnaBridge 189:f392fc9709a3 123
AnnaBridge 189:f392fc9709a3 124 //TODO: Implement default setting structure.
AnnaBridge 189:f392fc9709a3 125 pHalSsiOp->HalSsiLoadSetting(pHalSsiAdaptor, (void*)&SpiDefaultSetting);
AnnaBridge 189:f392fc9709a3 126 pHalSsiAdaptor->DefaultRxThresholdLevel = SpiDefaultSetting.RxThresholdLevel;
AnnaBridge 189:f392fc9709a3 127
AnnaBridge 189:f392fc9709a3 128 if(HalSsiInit(pHalSsiAdaptor) != HAL_OK){
AnnaBridge 189:f392fc9709a3 129 DBG_SSI_ERR(ANSI_COLOR_RED"spi_init(): SPI %x init fails.\n"ANSI_COLOR_RESET,pHalSsiAdaptor->Index);
AnnaBridge 189:f392fc9709a3 130 return;
AnnaBridge 189:f392fc9709a3 131 }
AnnaBridge 189:f392fc9709a3 132
AnnaBridge 189:f392fc9709a3 133 pHalSsiAdaptor->TxCompCallback = spi_tx_done_callback;
AnnaBridge 189:f392fc9709a3 134 pHalSsiAdaptor->TxCompCbPara = (void*)obj;
AnnaBridge 189:f392fc9709a3 135 pHalSsiAdaptor->RxCompCallback = spi_rx_done_callback;
AnnaBridge 189:f392fc9709a3 136 pHalSsiAdaptor->RxCompCbPara = (void*)obj;
AnnaBridge 189:f392fc9709a3 137 pHalSsiAdaptor->TxIdleCallback = spi_bus_tx_done_callback;
AnnaBridge 189:f392fc9709a3 138 pHalSsiAdaptor->TxIdleCbPara = (void*)obj;
AnnaBridge 189:f392fc9709a3 139
AnnaBridge 189:f392fc9709a3 140 #ifdef CONFIG_GDMA_EN
AnnaBridge 189:f392fc9709a3 141 HalGdmaOpInit((VOID*)&SpiGdmaOp);
AnnaBridge 189:f392fc9709a3 142 pHalSsiAdaptor->DmaConfig.pHalGdmaOp = &SpiGdmaOp;
AnnaBridge 189:f392fc9709a3 143 pHalSsiAdaptor->DmaConfig.pRxHalGdmaAdapter = &obj->spi_gdma_adp_rx;
AnnaBridge 189:f392fc9709a3 144 pHalSsiAdaptor->DmaConfig.pTxHalGdmaAdapter = &obj->spi_gdma_adp_tx;
AnnaBridge 189:f392fc9709a3 145 obj->dma_en = 0;
AnnaBridge 189:f392fc9709a3 146 pHalSsiAdaptor->HaveTxChannel = 0;
AnnaBridge 189:f392fc9709a3 147 pHalSsiAdaptor->HaveRxChannel = 0;
AnnaBridge 189:f392fc9709a3 148 #endif
AnnaBridge 189:f392fc9709a3 149 }
AnnaBridge 189:f392fc9709a3 150
AnnaBridge 189:f392fc9709a3 151 void spi_free (spi_t *obj)
AnnaBridge 189:f392fc9709a3 152 {
AnnaBridge 189:f392fc9709a3 153 PHAL_SSI_ADAPTOR pHalSsiAdaptor;
AnnaBridge 189:f392fc9709a3 154 pHalSsiAdaptor = &obj->spi_adp;
AnnaBridge 189:f392fc9709a3 155 HalSsiDeInit(pHalSsiAdaptor);
AnnaBridge 189:f392fc9709a3 156
AnnaBridge 189:f392fc9709a3 157 SPI0_MULTI_CS_CTRL(OFF);
AnnaBridge 189:f392fc9709a3 158
AnnaBridge 189:f392fc9709a3 159 #ifdef CONFIG_GDMA_EN
AnnaBridge 189:f392fc9709a3 160 if (obj->dma_en & SPI_DMA_RX_EN) {
AnnaBridge 189:f392fc9709a3 161 HalSsiRxGdmaDeInit(pHalSsiAdaptor);
AnnaBridge 189:f392fc9709a3 162 }
AnnaBridge 189:f392fc9709a3 163
AnnaBridge 189:f392fc9709a3 164 if (obj->dma_en & SPI_DMA_TX_EN) {
AnnaBridge 189:f392fc9709a3 165 HalSsiTxGdmaDeInit(pHalSsiAdaptor);
AnnaBridge 189:f392fc9709a3 166 }
AnnaBridge 189:f392fc9709a3 167 obj->dma_en = 0;
AnnaBridge 189:f392fc9709a3 168 #endif
AnnaBridge 189:f392fc9709a3 169 }
AnnaBridge 189:f392fc9709a3 170
AnnaBridge 189:f392fc9709a3 171 void spi_format (spi_t *obj, int bits, int mode, int slave)
AnnaBridge 189:f392fc9709a3 172 {
AnnaBridge 189:f392fc9709a3 173 PHAL_SSI_ADAPTOR pHalSsiAdaptor;
AnnaBridge 189:f392fc9709a3 174 PHAL_SSI_OP pHalSsiOp;
AnnaBridge 189:f392fc9709a3 175
AnnaBridge 189:f392fc9709a3 176 pHalSsiAdaptor = &obj->spi_adp;
AnnaBridge 189:f392fc9709a3 177 pHalSsiOp = &obj->spi_op;
AnnaBridge 189:f392fc9709a3 178
AnnaBridge 189:f392fc9709a3 179 pHalSsiAdaptor->DataFrameSize = (bits - 1);
AnnaBridge 189:f392fc9709a3 180
AnnaBridge 189:f392fc9709a3 181 /*
AnnaBridge 189:f392fc9709a3 182 * mode | POL PHA
AnnaBridge 189:f392fc9709a3 183 * -----+--------
AnnaBridge 189:f392fc9709a3 184 * 0 | 0 0
AnnaBridge 189:f392fc9709a3 185 * 1 | 0 1
AnnaBridge 189:f392fc9709a3 186 * 2 | 1 0
AnnaBridge 189:f392fc9709a3 187 * 3 | 1 1
AnnaBridge 189:f392fc9709a3 188 *
AnnaBridge 189:f392fc9709a3 189 * SCPOL_INACTIVE_IS_LOW = 0,
AnnaBridge 189:f392fc9709a3 190 * SCPOL_INACTIVE_IS_HIGH = 1
AnnaBridge 189:f392fc9709a3 191 *
AnnaBridge 189:f392fc9709a3 192 * SCPH_TOGGLES_IN_MIDDLE = 0,
AnnaBridge 189:f392fc9709a3 193 * SCPH_TOGGLES_AT_START = 1
AnnaBridge 189:f392fc9709a3 194 */
AnnaBridge 189:f392fc9709a3 195 switch (mode)
AnnaBridge 189:f392fc9709a3 196 {
AnnaBridge 189:f392fc9709a3 197 case 0:
AnnaBridge 189:f392fc9709a3 198 pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_LOW;
AnnaBridge 189:f392fc9709a3 199 pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_IN_MIDDLE;
AnnaBridge 189:f392fc9709a3 200 break;
AnnaBridge 189:f392fc9709a3 201 case 1:
AnnaBridge 189:f392fc9709a3 202 pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_LOW;
AnnaBridge 189:f392fc9709a3 203 pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_AT_START;
AnnaBridge 189:f392fc9709a3 204 break;
AnnaBridge 189:f392fc9709a3 205 case 2:
AnnaBridge 189:f392fc9709a3 206 pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_HIGH;
AnnaBridge 189:f392fc9709a3 207 pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_IN_MIDDLE;
AnnaBridge 189:f392fc9709a3 208 break;
AnnaBridge 189:f392fc9709a3 209 case 3:
AnnaBridge 189:f392fc9709a3 210 pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_HIGH;
AnnaBridge 189:f392fc9709a3 211 pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_AT_START;
AnnaBridge 189:f392fc9709a3 212 break;
AnnaBridge 189:f392fc9709a3 213 default: // same as 3
AnnaBridge 189:f392fc9709a3 214 pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_HIGH;
AnnaBridge 189:f392fc9709a3 215 pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_AT_START;
AnnaBridge 189:f392fc9709a3 216 break;
AnnaBridge 189:f392fc9709a3 217 }
AnnaBridge 189:f392fc9709a3 218
AnnaBridge 189:f392fc9709a3 219 if (slave == 1) {
AnnaBridge 189:f392fc9709a3 220 if (pHalSsiAdaptor->Index == 0) {
AnnaBridge 189:f392fc9709a3 221 pHalSsiAdaptor->Role = SSI_SLAVE;
AnnaBridge 189:f392fc9709a3 222 pHalSsiAdaptor->SlaveOutputEnable = SLV_TXD_ENABLE; // <-- Slave only
AnnaBridge 189:f392fc9709a3 223 SPI0_IS_AS_SLAVE = 1;
AnnaBridge 189:f392fc9709a3 224 DBG_SSI_INFO("SPI0 is as slave\n");
AnnaBridge 189:f392fc9709a3 225 } else {
AnnaBridge 189:f392fc9709a3 226 DBG_SSI_ERR("The SPI%d cannot work as Slave mode, only SPI0 does.\r\n", pHalSsiAdaptor->Index);
AnnaBridge 189:f392fc9709a3 227 pHalSsiAdaptor->Role = SSI_MASTER;
AnnaBridge 189:f392fc9709a3 228 }
AnnaBridge 189:f392fc9709a3 229 } else {
AnnaBridge 189:f392fc9709a3 230 pHalSsiAdaptor->Role = SSI_MASTER;
AnnaBridge 189:f392fc9709a3 231 }
AnnaBridge 189:f392fc9709a3 232 pHalSsiOp->HalSsiSetDeviceRole(pHalSsiAdaptor, pHalSsiAdaptor->Role);
AnnaBridge 189:f392fc9709a3 233
AnnaBridge 189:f392fc9709a3 234 #ifdef CONFIG_GPIO_EN
AnnaBridge 189:f392fc9709a3 235 if (pHalSsiAdaptor->Role == SSI_SLAVE) {
AnnaBridge 189:f392fc9709a3 236 if (pHalSsiAdaptor->SclkPolarity == SCPOL_INACTIVE_IS_LOW) {
AnnaBridge 189:f392fc9709a3 237 HAL_GPIO_PullCtrl((u32)obj->sclk, hal_PullDown);
AnnaBridge 189:f392fc9709a3 238 } else {
AnnaBridge 189:f392fc9709a3 239 HAL_GPIO_PullCtrl((u32)obj->sclk, hal_PullUp);
AnnaBridge 189:f392fc9709a3 240 }
AnnaBridge 189:f392fc9709a3 241 }
AnnaBridge 189:f392fc9709a3 242 #endif
AnnaBridge 189:f392fc9709a3 243 HalSsiSetFormat(pHalSsiAdaptor);
AnnaBridge 189:f392fc9709a3 244 }
AnnaBridge 189:f392fc9709a3 245
AnnaBridge 189:f392fc9709a3 246 void spi_frequency (spi_t *obj, int hz)
AnnaBridge 189:f392fc9709a3 247 {
AnnaBridge 189:f392fc9709a3 248 PHAL_SSI_ADAPTOR pHalSsiAdaptor;
AnnaBridge 189:f392fc9709a3 249
AnnaBridge 189:f392fc9709a3 250 pHalSsiAdaptor = &obj->spi_adp;
AnnaBridge 189:f392fc9709a3 251 HalSsiSetSclk(pHalSsiAdaptor, (u32)hz);
AnnaBridge 189:f392fc9709a3 252 }
AnnaBridge 189:f392fc9709a3 253
AnnaBridge 189:f392fc9709a3 254 static inline void ssi_write (spi_t *obj, int value)
AnnaBridge 189:f392fc9709a3 255 {
AnnaBridge 189:f392fc9709a3 256 PHAL_SSI_ADAPTOR pHalSsiAdaptor;
AnnaBridge 189:f392fc9709a3 257 PHAL_SSI_OP pHalSsiOp;
AnnaBridge 189:f392fc9709a3 258
AnnaBridge 189:f392fc9709a3 259 pHalSsiAdaptor = &obj->spi_adp;
AnnaBridge 189:f392fc9709a3 260 pHalSsiOp = &obj->spi_op;
AnnaBridge 189:f392fc9709a3 261
AnnaBridge 189:f392fc9709a3 262 while (!pHalSsiOp->HalSsiWriteable(pHalSsiAdaptor));
AnnaBridge 189:f392fc9709a3 263 pHalSsiOp->HalSsiWrite((VOID*)pHalSsiAdaptor, value);
AnnaBridge 189:f392fc9709a3 264 }
AnnaBridge 189:f392fc9709a3 265
AnnaBridge 189:f392fc9709a3 266 static inline int ssi_read(spi_t *obj)
AnnaBridge 189:f392fc9709a3 267 {
AnnaBridge 189:f392fc9709a3 268 PHAL_SSI_ADAPTOR pHalSsiAdaptor;
AnnaBridge 189:f392fc9709a3 269 PHAL_SSI_OP pHalSsiOp;
AnnaBridge 189:f392fc9709a3 270
AnnaBridge 189:f392fc9709a3 271 pHalSsiAdaptor = &obj->spi_adp;
AnnaBridge 189:f392fc9709a3 272 pHalSsiOp = &obj->spi_op;
AnnaBridge 189:f392fc9709a3 273
AnnaBridge 189:f392fc9709a3 274 while (!pHalSsiOp->HalSsiReadable(pHalSsiAdaptor));
AnnaBridge 189:f392fc9709a3 275 return (int)pHalSsiOp->HalSsiRead(pHalSsiAdaptor);
AnnaBridge 189:f392fc9709a3 276 }
AnnaBridge 189:f392fc9709a3 277
AnnaBridge 189:f392fc9709a3 278 int spi_master_write (spi_t *obj, int value)
AnnaBridge 189:f392fc9709a3 279 {
AnnaBridge 189:f392fc9709a3 280 ssi_write(obj, value);
AnnaBridge 189:f392fc9709a3 281 return ssi_read(obj);
AnnaBridge 189:f392fc9709a3 282 }
AnnaBridge 189:f392fc9709a3 283
AnnaBridge 189:f392fc9709a3 284 int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
AnnaBridge 189:f392fc9709a3 285 char *rx_buffer, int rx_length, char write_fill)
AnnaBridge 189:f392fc9709a3 286 {
AnnaBridge 189:f392fc9709a3 287 int total = (tx_length > rx_length) ? tx_length : rx_length;
AnnaBridge 189:f392fc9709a3 288 int i;
AnnaBridge 189:f392fc9709a3 289 char out, in;
AnnaBridge 189:f392fc9709a3 290
AnnaBridge 189:f392fc9709a3 291 for (i = 0; i < total; i++) {
AnnaBridge 189:f392fc9709a3 292 out = (i < tx_length) ? tx_buffer[i] : write_fill;
AnnaBridge 189:f392fc9709a3 293 in = spi_master_write(obj, out);
AnnaBridge 189:f392fc9709a3 294 if (i < rx_length) {
AnnaBridge 189:f392fc9709a3 295 rx_buffer[i] = in;
AnnaBridge 189:f392fc9709a3 296 }
AnnaBridge 189:f392fc9709a3 297 }
AnnaBridge 189:f392fc9709a3 298
AnnaBridge 189:f392fc9709a3 299 return total;
AnnaBridge 189:f392fc9709a3 300 }
AnnaBridge 189:f392fc9709a3 301
AnnaBridge 189:f392fc9709a3 302 int spi_slave_receive (spi_t *obj)
AnnaBridge 189:f392fc9709a3 303 {
AnnaBridge 189:f392fc9709a3 304 PHAL_SSI_ADAPTOR pHalSsiAdaptor;
AnnaBridge 189:f392fc9709a3 305 PHAL_SSI_OP pHalSsiOp;
AnnaBridge 189:f392fc9709a3 306 int Readable;
AnnaBridge 189:f392fc9709a3 307 int Busy;
AnnaBridge 189:f392fc9709a3 308
AnnaBridge 189:f392fc9709a3 309 pHalSsiAdaptor = &obj->spi_adp;
AnnaBridge 189:f392fc9709a3 310 pHalSsiOp = &obj->spi_op;
AnnaBridge 189:f392fc9709a3 311
AnnaBridge 189:f392fc9709a3 312 Readable = pHalSsiOp->HalSsiReadable(pHalSsiAdaptor);
AnnaBridge 189:f392fc9709a3 313 Busy = (int)pHalSsiOp->HalSsiBusy(pHalSsiAdaptor);
AnnaBridge 189:f392fc9709a3 314 return ((Readable && !Busy) ? 1 : 0);
AnnaBridge 189:f392fc9709a3 315 }
AnnaBridge 189:f392fc9709a3 316
AnnaBridge 189:f392fc9709a3 317 int spi_slave_read (spi_t *obj)
AnnaBridge 189:f392fc9709a3 318 {
AnnaBridge 189:f392fc9709a3 319 return ssi_read(obj);
AnnaBridge 189:f392fc9709a3 320 }
AnnaBridge 189:f392fc9709a3 321
AnnaBridge 189:f392fc9709a3 322 void spi_slave_write (spi_t *obj, int value)
AnnaBridge 189:f392fc9709a3 323 {
AnnaBridge 189:f392fc9709a3 324 ssi_write(obj, value);
AnnaBridge 189:f392fc9709a3 325 }
AnnaBridge 189:f392fc9709a3 326
AnnaBridge 189:f392fc9709a3 327 int spi_busy (spi_t *obj)
AnnaBridge 189:f392fc9709a3 328 {
AnnaBridge 189:f392fc9709a3 329 PHAL_SSI_ADAPTOR pHalSsiAdaptor;
AnnaBridge 189:f392fc9709a3 330 PHAL_SSI_OP pHalSsiOp;
AnnaBridge 189:f392fc9709a3 331
AnnaBridge 189:f392fc9709a3 332 pHalSsiAdaptor = &obj->spi_adp;
AnnaBridge 189:f392fc9709a3 333 pHalSsiOp = &obj->spi_op;
AnnaBridge 189:f392fc9709a3 334
AnnaBridge 189:f392fc9709a3 335 return (int)pHalSsiOp->HalSsiBusy(pHalSsiAdaptor);
AnnaBridge 189:f392fc9709a3 336 }
AnnaBridge 189:f392fc9709a3 337
AnnaBridge 189:f392fc9709a3 338 // Bus Idle: Real TX done, TX FIFO empty and bus shift all data out already
AnnaBridge 189:f392fc9709a3 339 void spi_bus_tx_done_callback(VOID *obj)
AnnaBridge 189:f392fc9709a3 340 {
AnnaBridge 189:f392fc9709a3 341 spi_t *spi_obj = (spi_t *)obj;
AnnaBridge 189:f392fc9709a3 342 spi_irq_handler handler;
AnnaBridge 189:f392fc9709a3 343
AnnaBridge 189:f392fc9709a3 344 if (spi_obj->bus_tx_done_handler) {
AnnaBridge 189:f392fc9709a3 345 handler = (spi_irq_handler)spi_obj->bus_tx_done_handler;
AnnaBridge 189:f392fc9709a3 346 handler(spi_obj->bus_tx_done_irq_id, (SpiIrq)0);
AnnaBridge 189:f392fc9709a3 347 }
AnnaBridge 189:f392fc9709a3 348 }
AnnaBridge 189:f392fc9709a3 349
AnnaBridge 189:f392fc9709a3 350 void spi_tx_done_callback(VOID *obj)
AnnaBridge 189:f392fc9709a3 351 {
AnnaBridge 189:f392fc9709a3 352 spi_t *spi_obj = (spi_t *)obj;
AnnaBridge 189:f392fc9709a3 353 spi_irq_handler handler;
AnnaBridge 189:f392fc9709a3 354
AnnaBridge 189:f392fc9709a3 355 if (spi_obj->state & SPI_STATE_TX_BUSY) {
AnnaBridge 189:f392fc9709a3 356 spi_obj->state &= ~SPI_STATE_TX_BUSY;
AnnaBridge 189:f392fc9709a3 357 if (spi_obj->irq_handler) {
AnnaBridge 189:f392fc9709a3 358 handler = (spi_irq_handler)spi_obj->irq_handler;
AnnaBridge 189:f392fc9709a3 359 handler(spi_obj->irq_id, SpiTxIrq);
AnnaBridge 189:f392fc9709a3 360 }
AnnaBridge 189:f392fc9709a3 361 }
AnnaBridge 189:f392fc9709a3 362 }
AnnaBridge 189:f392fc9709a3 363
AnnaBridge 189:f392fc9709a3 364 void spi_rx_done_callback(VOID *obj)
AnnaBridge 189:f392fc9709a3 365 {
AnnaBridge 189:f392fc9709a3 366 spi_t *spi_obj = (spi_t *)obj;
AnnaBridge 189:f392fc9709a3 367 spi_irq_handler handler;
AnnaBridge 189:f392fc9709a3 368
AnnaBridge 189:f392fc9709a3 369 spi_obj->state &= ~SPI_STATE_RX_BUSY;
AnnaBridge 189:f392fc9709a3 370 if (spi_obj->irq_handler) {
AnnaBridge 189:f392fc9709a3 371 handler = (spi_irq_handler)spi_obj->irq_handler;
AnnaBridge 189:f392fc9709a3 372 handler(spi_obj->irq_id, SpiRxIrq);
AnnaBridge 189:f392fc9709a3 373 }
AnnaBridge 189:f392fc9709a3 374 }
AnnaBridge 189:f392fc9709a3 375