Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sat Jun 03 00:22:44 2017 +0000
Revision:
46:b156ef445742
Parent:
18:6a4db94011d3
Final code for internal battlebot competition.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sahilmgandhi 18:6a4db94011d3 1 /* mbed Microcontroller Library
sahilmgandhi 18:6a4db94011d3 2 * Copyright (c) 2006-2013 ARM Limited
sahilmgandhi 18:6a4db94011d3 3 *
sahilmgandhi 18:6a4db94011d3 4 * Licensed under the Apache License, Version 2.0 (the "License");
sahilmgandhi 18:6a4db94011d3 5 * you may not use this file except in compliance with the License.
sahilmgandhi 18:6a4db94011d3 6 * You may obtain a copy of the License at
sahilmgandhi 18:6a4db94011d3 7 *
sahilmgandhi 18:6a4db94011d3 8 * http://www.apache.org/licenses/LICENSE-2.0
sahilmgandhi 18:6a4db94011d3 9 *
sahilmgandhi 18:6a4db94011d3 10 * Unless required by applicable law or agreed to in writing, software
sahilmgandhi 18:6a4db94011d3 11 * distributed under the License is distributed on an "AS IS" BASIS,
sahilmgandhi 18:6a4db94011d3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sahilmgandhi 18:6a4db94011d3 13 * See the License for the specific language governing permissions and
sahilmgandhi 18:6a4db94011d3 14 * limitations under the License.
sahilmgandhi 18:6a4db94011d3 15 */
sahilmgandhi 18:6a4db94011d3 16
sahilmgandhi 18:6a4db94011d3 17 #include "device.h"
sahilmgandhi 18:6a4db94011d3 18 #include "dma_api.h"
sahilmgandhi 18:6a4db94011d3 19 #include "buffer.h"
sahilmgandhi 18:6a4db94011d3 20 #include "spi_api.h"
sahilmgandhi 18:6a4db94011d3 21 #include "pinmap.h"
sahilmgandhi 18:6a4db94011d3 22 #include "spi_driver.h"
sahilmgandhi 18:6a4db94011d3 23 #include "PeripheralPins.h"
sahilmgandhi 18:6a4db94011d3 24 #include "pdc.h"
sahilmgandhi 18:6a4db94011d3 25
sahilmgandhi 18:6a4db94011d3 26
sahilmgandhi 18:6a4db94011d3 27 /* Chip select. */
sahilmgandhi 18:6a4db94011d3 28 #define SPI_CHIP_SEL 0
sahilmgandhi 18:6a4db94011d3 29
sahilmgandhi 18:6a4db94011d3 30 /* Clock polarity. */
sahilmgandhi 18:6a4db94011d3 31 #define SPI_CLK_POLARITY 0
sahilmgandhi 18:6a4db94011d3 32
sahilmgandhi 18:6a4db94011d3 33 /* Clock phase. */
sahilmgandhi 18:6a4db94011d3 34 #define SPI_CLK_PHASE 0
sahilmgandhi 18:6a4db94011d3 35
sahilmgandhi 18:6a4db94011d3 36 /* Last data */
sahilmgandhi 18:6a4db94011d3 37 #define SPI_LAST 0
sahilmgandhi 18:6a4db94011d3 38
sahilmgandhi 18:6a4db94011d3 39
sahilmgandhi 18:6a4db94011d3 40 /* Delay before SPCK. */
sahilmgandhi 18:6a4db94011d3 41 #define SPI_DLYBS 0x40
sahilmgandhi 18:6a4db94011d3 42
sahilmgandhi 18:6a4db94011d3 43 /* Delay between consecutive transfers. */
sahilmgandhi 18:6a4db94011d3 44 #define SPI_DLYBCT 0x10
sahilmgandhi 18:6a4db94011d3 45
sahilmgandhi 18:6a4db94011d3 46 #define MAX_SPI 8
sahilmgandhi 18:6a4db94011d3 47
sahilmgandhi 18:6a4db94011d3 48 /* SPI clock setting (Hz). */
sahilmgandhi 18:6a4db94011d3 49 uint32_t gSPI_clock=500000;
sahilmgandhi 18:6a4db94011d3 50
sahilmgandhi 18:6a4db94011d3 51 extern uint8_t g_sys_init;
sahilmgandhi 18:6a4db94011d3 52
sahilmgandhi 18:6a4db94011d3 53
sahilmgandhi 18:6a4db94011d3 54
sahilmgandhi 18:6a4db94011d3 55 void pinmap_find_spi_info(Spi *sercombase, spi_t *obj)
sahilmgandhi 18:6a4db94011d3 56 {
sahilmgandhi 18:6a4db94011d3 57 if(sercombase==SPI0) {
sahilmgandhi 18:6a4db94011d3 58 obj->spi.flexcom=FLEXCOM0;
sahilmgandhi 18:6a4db94011d3 59 obj->spi.module_number=0;
sahilmgandhi 18:6a4db94011d3 60 obj->spi.pdc =PDC_SPI0;
sahilmgandhi 18:6a4db94011d3 61 obj->spi.irq_type=FLEXCOM0_IRQn;
sahilmgandhi 18:6a4db94011d3 62 } else if(sercombase==SPI1) {
sahilmgandhi 18:6a4db94011d3 63 obj->spi.flexcom=FLEXCOM1;
sahilmgandhi 18:6a4db94011d3 64 obj->spi.module_number=1;
sahilmgandhi 18:6a4db94011d3 65 obj->spi.pdc =PDC_SPI1;
sahilmgandhi 18:6a4db94011d3 66 obj->spi.irq_type=FLEXCOM1_IRQn;
sahilmgandhi 18:6a4db94011d3 67 } else if(sercombase==SPI2) {
sahilmgandhi 18:6a4db94011d3 68 obj->spi.flexcom=FLEXCOM2;
sahilmgandhi 18:6a4db94011d3 69 obj->spi.module_number=2;
sahilmgandhi 18:6a4db94011d3 70 obj->spi.pdc =PDC_SPI2;
sahilmgandhi 18:6a4db94011d3 71 obj->spi.irq_type=FLEXCOM2_IRQn;
sahilmgandhi 18:6a4db94011d3 72 } else if(sercombase==SPI3) {
sahilmgandhi 18:6a4db94011d3 73 obj->spi.flexcom=FLEXCOM3;
sahilmgandhi 18:6a4db94011d3 74 obj->spi.module_number=3;
sahilmgandhi 18:6a4db94011d3 75 obj->spi.pdc =PDC_SPI3;
sahilmgandhi 18:6a4db94011d3 76 obj->spi.irq_type=FLEXCOM3_IRQn;
sahilmgandhi 18:6a4db94011d3 77 } else if(sercombase==SPI4) {
sahilmgandhi 18:6a4db94011d3 78 obj->spi.flexcom=FLEXCOM4;
sahilmgandhi 18:6a4db94011d3 79 obj->spi.module_number=4;
sahilmgandhi 18:6a4db94011d3 80 obj->spi.pdc =PDC_SPI4;
sahilmgandhi 18:6a4db94011d3 81 obj->spi.irq_type=FLEXCOM4_IRQn;
sahilmgandhi 18:6a4db94011d3 82 } else if(sercombase==SPI5) {
sahilmgandhi 18:6a4db94011d3 83 obj->spi.flexcom=FLEXCOM5;
sahilmgandhi 18:6a4db94011d3 84 obj->spi.module_number=5;
sahilmgandhi 18:6a4db94011d3 85 obj->spi.pdc =PDC_SPI5;
sahilmgandhi 18:6a4db94011d3 86 obj->spi.irq_type=FLEXCOM5_IRQn;
sahilmgandhi 18:6a4db94011d3 87 } else if(sercombase==SPI6) {
sahilmgandhi 18:6a4db94011d3 88 obj->spi.flexcom=FLEXCOM6;
sahilmgandhi 18:6a4db94011d3 89 obj->spi.module_number=6;
sahilmgandhi 18:6a4db94011d3 90 obj->spi.pdc =PDC_SPI6;
sahilmgandhi 18:6a4db94011d3 91 obj->spi.irq_type=FLEXCOM6_IRQn;
sahilmgandhi 18:6a4db94011d3 92 } else if(sercombase==SPI7) {
sahilmgandhi 18:6a4db94011d3 93 obj->spi.flexcom=FLEXCOM7;
sahilmgandhi 18:6a4db94011d3 94 obj->spi.module_number=7;
sahilmgandhi 18:6a4db94011d3 95 obj->spi.pdc =PDC_SPI7;
sahilmgandhi 18:6a4db94011d3 96 obj->spi.irq_type=FLEXCOM7_IRQn;
sahilmgandhi 18:6a4db94011d3 97 } else {
sahilmgandhi 18:6a4db94011d3 98 obj->spi.flexcom=(Flexcom *)NC;
sahilmgandhi 18:6a4db94011d3 99 obj->spi.module_number=0;
sahilmgandhi 18:6a4db94011d3 100 obj->spi.pdc =(Pdc *) NC;
sahilmgandhi 18:6a4db94011d3 101 }
sahilmgandhi 18:6a4db94011d3 102 }
sahilmgandhi 18:6a4db94011d3 103
sahilmgandhi 18:6a4db94011d3 104 Spi* pinmap_find_sercom(PinName mosi, PinName miso, PinName sclk)
sahilmgandhi 18:6a4db94011d3 105 {
sahilmgandhi 18:6a4db94011d3 106 Spi* sercomIndex=(Spi*)pinmap_peripheral (mosi,PinMap_SPI_MOSI);
sahilmgandhi 18:6a4db94011d3 107 if(sercomIndex== (Spi*)pinmap_peripheral (miso, PinMap_SPI_MISO) &&
sahilmgandhi 18:6a4db94011d3 108 sercomIndex == (Spi*)pinmap_peripheral (sclk, PinMap_SPI_SCLK))
sahilmgandhi 18:6a4db94011d3 109 return sercomIndex;
sahilmgandhi 18:6a4db94011d3 110
sahilmgandhi 18:6a4db94011d3 111 return (Spi*)NC;
sahilmgandhi 18:6a4db94011d3 112 }
sahilmgandhi 18:6a4db94011d3 113
sahilmgandhi 18:6a4db94011d3 114
sahilmgandhi 18:6a4db94011d3 115 /** Initialize the SPI peripheral
sahilmgandhi 18:6a4db94011d3 116 *
sahilmgandhi 18:6a4db94011d3 117 * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
sahilmgandhi 18:6a4db94011d3 118 * @param[out] obj The SPI object to initialize
sahilmgandhi 18:6a4db94011d3 119 * @param[in] mosi The pin to use for MOSI
sahilmgandhi 18:6a4db94011d3 120 * @param[in] miso The pin to use for MISO
sahilmgandhi 18:6a4db94011d3 121 * @param[in] sclk The pin to use for SCLK
sahilmgandhi 18:6a4db94011d3 122 * @param[in] ssel The pin to use for SSEL <Not Used>
sahilmgandhi 18:6a4db94011d3 123 */
sahilmgandhi 18:6a4db94011d3 124 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel /*Not Used*/)
sahilmgandhi 18:6a4db94011d3 125 {
sahilmgandhi 18:6a4db94011d3 126 MBED_ASSERT(obj);
sahilmgandhi 18:6a4db94011d3 127 MBED_ASSERT(mosi !=NC && miso!=NC && sclk !=NC );
sahilmgandhi 18:6a4db94011d3 128
sahilmgandhi 18:6a4db94011d3 129 if (g_sys_init == 0) {
sahilmgandhi 18:6a4db94011d3 130 sysclk_init();
sahilmgandhi 18:6a4db94011d3 131 system_board_init();
sahilmgandhi 18:6a4db94011d3 132 g_sys_init = 1;
sahilmgandhi 18:6a4db94011d3 133 }
sahilmgandhi 18:6a4db94011d3 134
sahilmgandhi 18:6a4db94011d3 135 Spi *sercombase = pinmap_find_sercom(mosi,miso,sclk);
sahilmgandhi 18:6a4db94011d3 136 MBED_ASSERT(sercombase!=NC);
sahilmgandhi 18:6a4db94011d3 137
sahilmgandhi 18:6a4db94011d3 138 pinmap_find_spi_info(sercombase, obj);
sahilmgandhi 18:6a4db94011d3 139 MBED_ASSERT(obj->spi.flexcom!=NC);
sahilmgandhi 18:6a4db94011d3 140 MBED_ASSERT(obj->spi.pdc!=NC);
sahilmgandhi 18:6a4db94011d3 141
sahilmgandhi 18:6a4db94011d3 142 /* Configure SPI pins */
sahilmgandhi 18:6a4db94011d3 143 pin_function(mosi, pinmap_find_function(mosi, PinMap_SPI_MOSI));
sahilmgandhi 18:6a4db94011d3 144 ioport_disable_pin(mosi);
sahilmgandhi 18:6a4db94011d3 145
sahilmgandhi 18:6a4db94011d3 146 pin_function(miso, pinmap_find_function(miso, PinMap_SPI_MISO));
sahilmgandhi 18:6a4db94011d3 147 ioport_disable_pin(miso);
sahilmgandhi 18:6a4db94011d3 148
sahilmgandhi 18:6a4db94011d3 149 pin_function(sclk, pinmap_find_function(sclk, PinMap_SPI_SCLK));
sahilmgandhi 18:6a4db94011d3 150 ioport_disable_pin(sclk);
sahilmgandhi 18:6a4db94011d3 151
sahilmgandhi 18:6a4db94011d3 152 #if (SAMG55)
sahilmgandhi 18:6a4db94011d3 153 /* Enable the peripheral and set SPI mode. */
sahilmgandhi 18:6a4db94011d3 154 flexcom_enable(obj->spi.flexcom);
sahilmgandhi 18:6a4db94011d3 155 flexcom_set_opmode(obj->spi.flexcom, FLEXCOM_SPI);
sahilmgandhi 18:6a4db94011d3 156 #else
sahilmgandhi 18:6a4db94011d3 157 /* Configure an SPI peripheral. */
sahilmgandhi 18:6a4db94011d3 158 spi_enable_clock(sercombase);
sahilmgandhi 18:6a4db94011d3 159 #endif
sahilmgandhi 18:6a4db94011d3 160 spi_disable(sercombase);
sahilmgandhi 18:6a4db94011d3 161 spi_reset(sercombase);
sahilmgandhi 18:6a4db94011d3 162 spi_set_lastxfer(sercombase);
sahilmgandhi 18:6a4db94011d3 163 spi_set_master_mode(sercombase);
sahilmgandhi 18:6a4db94011d3 164 spi_disable_mode_fault_detect(sercombase);
sahilmgandhi 18:6a4db94011d3 165 spi_set_peripheral_chip_select_value(sercombase, SPI_CHIP_SEL);
sahilmgandhi 18:6a4db94011d3 166 spi_set_clock_polarity(sercombase, SPI_CHIP_SEL, SPI_CLK_POLARITY);
sahilmgandhi 18:6a4db94011d3 167 spi_set_clock_phase(sercombase, SPI_CHIP_SEL, SPI_CLK_PHASE);
sahilmgandhi 18:6a4db94011d3 168 spi_set_bits_per_transfer(sercombase, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT);
sahilmgandhi 18:6a4db94011d3 169 spi_set_baudrate_div(sercombase, SPI_CHIP_SEL,(sysclk_get_cpu_hz() / gSPI_clock));
sahilmgandhi 18:6a4db94011d3 170 spi_set_transfer_delay(sercombase, SPI_CHIP_SEL, SPI_DLYBS,SPI_DLYBCT);
sahilmgandhi 18:6a4db94011d3 171
sahilmgandhi 18:6a4db94011d3 172 spi_enable(sercombase);
sahilmgandhi 18:6a4db94011d3 173
sahilmgandhi 18:6a4db94011d3 174 pdc_disable_transfer(obj->spi.pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
sahilmgandhi 18:6a4db94011d3 175
sahilmgandhi 18:6a4db94011d3 176 obj->spi.spi_base=sercombase;
sahilmgandhi 18:6a4db94011d3 177 obj->spi.cs= SPI_CHIP_SEL;
sahilmgandhi 18:6a4db94011d3 178 obj->spi.polarity=SPI_CLK_POLARITY;
sahilmgandhi 18:6a4db94011d3 179 obj->spi.phase=SPI_CLK_PHASE;
sahilmgandhi 18:6a4db94011d3 180 obj->spi.transferrate=SPI_CSR_BITS_8_BIT;
sahilmgandhi 18:6a4db94011d3 181 obj->spi.is_slave=0;
sahilmgandhi 18:6a4db94011d3 182 }
sahilmgandhi 18:6a4db94011d3 183
sahilmgandhi 18:6a4db94011d3 184 /** Release a SPI object
sahilmgandhi 18:6a4db94011d3 185 *
sahilmgandhi 18:6a4db94011d3 186 * TODO: spi_free is currently unimplemented
sahilmgandhi 18:6a4db94011d3 187 * This will require reference counting at the C++ level to be safe
sahilmgandhi 18:6a4db94011d3 188 *
sahilmgandhi 18:6a4db94011d3 189 * Return the pins owned by the SPI object to their reset state
sahilmgandhi 18:6a4db94011d3 190 * Disable the SPI peripheral
sahilmgandhi 18:6a4db94011d3 191 * Disable the SPI clock
sahilmgandhi 18:6a4db94011d3 192 * @param[in] obj The SPI object to deinitialize
sahilmgandhi 18:6a4db94011d3 193 */
sahilmgandhi 18:6a4db94011d3 194 void spi_free(spi_t *obj)
sahilmgandhi 18:6a4db94011d3 195 {
sahilmgandhi 18:6a4db94011d3 196 MBED_ASSERT(obj);
sahilmgandhi 18:6a4db94011d3 197 spi_disable(obj->spi.spi_base);
sahilmgandhi 18:6a4db94011d3 198 spi_reset(obj->spi.spi_base);
sahilmgandhi 18:6a4db94011d3 199 flexcom_disable((Flexcom *)obj->spi.flexcom);
sahilmgandhi 18:6a4db94011d3 200 }
sahilmgandhi 18:6a4db94011d3 201
sahilmgandhi 18:6a4db94011d3 202 uint32_t get_transfer_rate(int bits)
sahilmgandhi 18:6a4db94011d3 203 {
sahilmgandhi 18:6a4db94011d3 204 switch(bits) {
sahilmgandhi 18:6a4db94011d3 205 case 8:
sahilmgandhi 18:6a4db94011d3 206 return SPI_CSR_BITS_8_BIT;
sahilmgandhi 18:6a4db94011d3 207 case 9:
sahilmgandhi 18:6a4db94011d3 208 return SPI_CSR_BITS_9_BIT;
sahilmgandhi 18:6a4db94011d3 209 case 10:
sahilmgandhi 18:6a4db94011d3 210 return SPI_CSR_BITS_10_BIT;
sahilmgandhi 18:6a4db94011d3 211 case 11:
sahilmgandhi 18:6a4db94011d3 212 return SPI_CSR_BITS_11_BIT;
sahilmgandhi 18:6a4db94011d3 213 case 12:
sahilmgandhi 18:6a4db94011d3 214 return SPI_CSR_BITS_12_BIT;
sahilmgandhi 18:6a4db94011d3 215 case 13:
sahilmgandhi 18:6a4db94011d3 216 return SPI_CSR_BITS_13_BIT;
sahilmgandhi 18:6a4db94011d3 217 case 14:
sahilmgandhi 18:6a4db94011d3 218 return SPI_CSR_BITS_14_BIT;
sahilmgandhi 18:6a4db94011d3 219 case 15:
sahilmgandhi 18:6a4db94011d3 220 return SPI_CSR_BITS_15_BIT;
sahilmgandhi 18:6a4db94011d3 221 case 16:
sahilmgandhi 18:6a4db94011d3 222 return SPI_CSR_BITS_16_BIT;
sahilmgandhi 18:6a4db94011d3 223 default:
sahilmgandhi 18:6a4db94011d3 224 return NC;
sahilmgandhi 18:6a4db94011d3 225 }
sahilmgandhi 18:6a4db94011d3 226 }
sahilmgandhi 18:6a4db94011d3 227
sahilmgandhi 18:6a4db94011d3 228 /** Configure the SPI format
sahilmgandhi 18:6a4db94011d3 229 *
sahilmgandhi 18:6a4db94011d3 230 * Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode
sahilmgandhi 18:6a4db94011d3 231 * @param[in,out] obj The SPI object to configure
sahilmgandhi 18:6a4db94011d3 232 * @param[in] bits The number of bits per frame
sahilmgandhi 18:6a4db94011d3 233 * @param[in] mode The SPI mode (clock polarity, phase, and shift direction)
sahilmgandhi 18:6a4db94011d3 234 * @param[in] slave Zero for master mode or non-zero for slave mode
sahilmgandhi 18:6a4db94011d3 235 */
sahilmgandhi 18:6a4db94011d3 236 void spi_format(spi_t *obj, int bits, int mode, int slave)
sahilmgandhi 18:6a4db94011d3 237 {
sahilmgandhi 18:6a4db94011d3 238 uint32_t transferrate= get_transfer_rate(bits);
sahilmgandhi 18:6a4db94011d3 239 MBED_ASSERT(transferrate!=NC);
sahilmgandhi 18:6a4db94011d3 240
sahilmgandhi 18:6a4db94011d3 241 spi_disable(obj->spi.spi_base);
sahilmgandhi 18:6a4db94011d3 242 obj->spi.transferrate=transferrate;
sahilmgandhi 18:6a4db94011d3 243 if(slave) {
sahilmgandhi 18:6a4db94011d3 244 spi_set_slave_mode(obj->spi.spi_base);
sahilmgandhi 18:6a4db94011d3 245 obj->spi.is_slave=1;
sahilmgandhi 18:6a4db94011d3 246 } else {
sahilmgandhi 18:6a4db94011d3 247 spi_set_master_mode(obj->spi.spi_base);
sahilmgandhi 18:6a4db94011d3 248 obj->spi.is_slave=0;
sahilmgandhi 18:6a4db94011d3 249 }
sahilmgandhi 18:6a4db94011d3 250 spi_set_bits_per_transfer(obj->spi.spi_base, obj->spi.cs, obj->spi.transferrate);
sahilmgandhi 18:6a4db94011d3 251 spi_set_clock_phase(obj->spi.spi_base, SPI_CHIP_SEL, (mode & 0x01));
sahilmgandhi 18:6a4db94011d3 252 spi_set_clock_polarity(obj->spi.spi_base, SPI_CHIP_SEL, (mode & 0x02));
sahilmgandhi 18:6a4db94011d3 253
sahilmgandhi 18:6a4db94011d3 254 obj->spi.phase=(mode & 0x01);
sahilmgandhi 18:6a4db94011d3 255 obj->spi.polarity=(mode & 0x02);
sahilmgandhi 18:6a4db94011d3 256 spi_enable(obj->spi.spi_base);
sahilmgandhi 18:6a4db94011d3 257 }
sahilmgandhi 18:6a4db94011d3 258
sahilmgandhi 18:6a4db94011d3 259 /** Set the SPI baud rate
sahilmgandhi 18:6a4db94011d3 260 *
sahilmgandhi 18:6a4db94011d3 261 * Actual frequency may differ from the desired frequency due to available dividers and bus clock
sahilmgandhi 18:6a4db94011d3 262 * Configures the SPI peripheral's baud rate
sahilmgandhi 18:6a4db94011d3 263 * @param[in,out] obj The SPI object to configure
sahilmgandhi 18:6a4db94011d3 264 * @param[in] hz The baud rate in Hz
sahilmgandhi 18:6a4db94011d3 265 */
sahilmgandhi 18:6a4db94011d3 266
sahilmgandhi 18:6a4db94011d3 267 void spi_frequency(spi_t *obj, int hz)
sahilmgandhi 18:6a4db94011d3 268 {
sahilmgandhi 18:6a4db94011d3 269 spi_disable(obj->spi.spi_base);
sahilmgandhi 18:6a4db94011d3 270 int16_t baudrate_div=spi_calc_baudrate_div(hz, sysclk_get_cpu_hz());
sahilmgandhi 18:6a4db94011d3 271 spi_set_baudrate_div(obj->spi.spi_base,obj->spi.cs,(uint8_t)baudrate_div);
sahilmgandhi 18:6a4db94011d3 272 spi_enable(obj->spi.spi_base);
sahilmgandhi 18:6a4db94011d3 273 }
sahilmgandhi 18:6a4db94011d3 274
sahilmgandhi 18:6a4db94011d3 275 /**@}*/
sahilmgandhi 18:6a4db94011d3 276 /**
sahilmgandhi 18:6a4db94011d3 277 * \defgroup SynchSPI Synchronous SPI Hardware Abstraction Layer
sahilmgandhi 18:6a4db94011d3 278 * @{
sahilmgandhi 18:6a4db94011d3 279 */
sahilmgandhi 18:6a4db94011d3 280
sahilmgandhi 18:6a4db94011d3 281 /** Write a byte out in master mode and receive a value
sahilmgandhi 18:6a4db94011d3 282 *
sahilmgandhi 18:6a4db94011d3 283 * @param[in] obj The SPI peripheral to use for sending
sahilmgandhi 18:6a4db94011d3 284 * @param[in] value The value to send
sahilmgandhi 18:6a4db94011d3 285 * @return Returns the value received during send
sahilmgandhi 18:6a4db94011d3 286 */
sahilmgandhi 18:6a4db94011d3 287 int spi_master_write(spi_t *obj, int value)
sahilmgandhi 18:6a4db94011d3 288 {
sahilmgandhi 18:6a4db94011d3 289 spi_status_t status=spi_write(obj->spi.spi_base,(uint16_t)value,obj->spi.cs,SPI_LAST);
sahilmgandhi 18:6a4db94011d3 290 if(status ==SPI_OK) {
sahilmgandhi 18:6a4db94011d3 291 uint16_t data;
sahilmgandhi 18:6a4db94011d3 292 status =spi_read(obj->spi.spi_base,&data,&obj->spi.cs);
sahilmgandhi 18:6a4db94011d3 293 if(status == SPI_OK)
sahilmgandhi 18:6a4db94011d3 294 return data;
sahilmgandhi 18:6a4db94011d3 295 }
sahilmgandhi 18:6a4db94011d3 296 return 0;
sahilmgandhi 18:6a4db94011d3 297 }
sahilmgandhi 18:6a4db94011d3 298
sahilmgandhi 18:6a4db94011d3 299 /** Check if a value is available to read
sahilmgandhi 18:6a4db94011d3 300 *
sahilmgandhi 18:6a4db94011d3 301 * @param[in] obj The SPI peripheral to check
sahilmgandhi 18:6a4db94011d3 302 * @return non-zero if a value is available
sahilmgandhi 18:6a4db94011d3 303 */
sahilmgandhi 18:6a4db94011d3 304 int spi_slave_receive(spi_t *obj)
sahilmgandhi 18:6a4db94011d3 305 {
sahilmgandhi 18:6a4db94011d3 306 if(obj->spi.spi_base->SPI_SR & SPI_SR_RDRF)
sahilmgandhi 18:6a4db94011d3 307 return 1;
sahilmgandhi 18:6a4db94011d3 308 return 0;
sahilmgandhi 18:6a4db94011d3 309 }
sahilmgandhi 18:6a4db94011d3 310
sahilmgandhi 18:6a4db94011d3 311 /** Get a received value out of the SPI receive buffer in slave mode
sahilmgandhi 18:6a4db94011d3 312 *
sahilmgandhi 18:6a4db94011d3 313 * Blocks until a value is available
sahilmgandhi 18:6a4db94011d3 314 * @param[in] obj The SPI peripheral to read
sahilmgandhi 18:6a4db94011d3 315 * @return The value received
sahilmgandhi 18:6a4db94011d3 316 */
sahilmgandhi 18:6a4db94011d3 317 int spi_slave_read(spi_t *obj)
sahilmgandhi 18:6a4db94011d3 318 {
sahilmgandhi 18:6a4db94011d3 319 uint16_t data;
sahilmgandhi 18:6a4db94011d3 320 spi_status_t status =spi_read(obj->spi.spi_base, &data, &obj->spi.cs);
sahilmgandhi 18:6a4db94011d3 321 if(status == SPI_OK)
sahilmgandhi 18:6a4db94011d3 322 return data;
sahilmgandhi 18:6a4db94011d3 323 return 0;
sahilmgandhi 18:6a4db94011d3 324 }
sahilmgandhi 18:6a4db94011d3 325
sahilmgandhi 18:6a4db94011d3 326 /** Write a value to the SPI peripheral in slave mode
sahilmgandhi 18:6a4db94011d3 327 *
sahilmgandhi 18:6a4db94011d3 328 * Blocks until the SPI peripheral can be written to
sahilmgandhi 18:6a4db94011d3 329 * @param[in] obj The SPI peripheral to write
sahilmgandhi 18:6a4db94011d3 330 * @param[in] value The value to write
sahilmgandhi 18:6a4db94011d3 331 */
sahilmgandhi 18:6a4db94011d3 332 void spi_slave_write(spi_t *obj, int value)
sahilmgandhi 18:6a4db94011d3 333 {
sahilmgandhi 18:6a4db94011d3 334 spi_write(obj->spi.spi_base,(uint16_t)value,obj->spi.cs,SPI_LAST);
sahilmgandhi 18:6a4db94011d3 335 }
sahilmgandhi 18:6a4db94011d3 336
sahilmgandhi 18:6a4db94011d3 337 /** Checks if the specified SPI peripheral is in use
sahilmgandhi 18:6a4db94011d3 338 *
sahilmgandhi 18:6a4db94011d3 339 * @param[in] obj The SPI peripheral to check
sahilmgandhi 18:6a4db94011d3 340 * @return non-zero if the peripheral is currently transmitting
sahilmgandhi 18:6a4db94011d3 341 */
sahilmgandhi 18:6a4db94011d3 342 int spi_busy(spi_t *obj)
sahilmgandhi 18:6a4db94011d3 343 {
sahilmgandhi 18:6a4db94011d3 344 if(obj->spi.spi_base->SPI_SR & SPI_SR_TDRE) //Transmit Data Register Empty
sahilmgandhi 18:6a4db94011d3 345 return 0;
sahilmgandhi 18:6a4db94011d3 346 return 1;
sahilmgandhi 18:6a4db94011d3 347 }
sahilmgandhi 18:6a4db94011d3 348
sahilmgandhi 18:6a4db94011d3 349 /** Get the module number
sahilmgandhi 18:6a4db94011d3 350 *
sahilmgandhi 18:6a4db94011d3 351 * @param[in] obj The SPI peripheral to check
sahilmgandhi 18:6a4db94011d3 352 * @return The module number
sahilmgandhi 18:6a4db94011d3 353 */
sahilmgandhi 18:6a4db94011d3 354 uint8_t spi_get_module(spi_t *obj)
sahilmgandhi 18:6a4db94011d3 355 {
sahilmgandhi 18:6a4db94011d3 356 return obj->spi.module_number;
sahilmgandhi 18:6a4db94011d3 357 }
sahilmgandhi 18:6a4db94011d3 358
sahilmgandhi 18:6a4db94011d3 359
sahilmgandhi 18:6a4db94011d3 360 /**@}*/
sahilmgandhi 18:6a4db94011d3 361 #if DEVICE_SPI_ASYNCH
sahilmgandhi 18:6a4db94011d3 362 /**
sahilmgandhi 18:6a4db94011d3 363 * \defgroup AsynchSPI Asynchronous SPI Hardware Abstraction Layer
sahilmgandhi 18:6a4db94011d3 364 * @{
sahilmgandhi 18:6a4db94011d3 365 */
sahilmgandhi 18:6a4db94011d3 366
sahilmgandhi 18:6a4db94011d3 367 /** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff
sahilmgandhi 18:6a4db94011d3 368 *
sahilmgandhi 18:6a4db94011d3 369 * @param[in] obj The SPI object which holds the transfer information
sahilmgandhi 18:6a4db94011d3 370 * @param[in] tx The buffer to send
sahilmgandhi 18:6a4db94011d3 371 * @param[in] tx_length The number of words to transmit
sahilmgandhi 18:6a4db94011d3 372 * @param[in] rx The buffer to receive
sahilmgandhi 18:6a4db94011d3 373 * @param[in] rx_length The number of words to receive
sahilmgandhi 18:6a4db94011d3 374 * @param[in] bit_width The bit width of buffer words
sahilmgandhi 18:6a4db94011d3 375 * @param[in] event The logical OR of events to be registered
sahilmgandhi 18:6a4db94011d3 376 * @param[in] handler SPI interrupt handler
sahilmgandhi 18:6a4db94011d3 377 * @param[in] hint A suggestion for how to use DMA with this transfer
sahilmgandhi 18:6a4db94011d3 378 */
sahilmgandhi 18:6a4db94011d3 379 #warning "Only DMA async supported by SPI master transfer"
sahilmgandhi 18:6a4db94011d3 380
sahilmgandhi 18:6a4db94011d3 381 void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint)
sahilmgandhi 18:6a4db94011d3 382 {
sahilmgandhi 18:6a4db94011d3 383 uint32_t pdcenable=0;
sahilmgandhi 18:6a4db94011d3 384
sahilmgandhi 18:6a4db94011d3 385 if(bit_width) {
sahilmgandhi 18:6a4db94011d3 386 uint32_t transferrate= get_transfer_rate(bit_width);
sahilmgandhi 18:6a4db94011d3 387 spi_set_bits_per_transfer(obj->spi.spi_base, obj->spi.cs, transferrate);
sahilmgandhi 18:6a4db94011d3 388 }
sahilmgandhi 18:6a4db94011d3 389
sahilmgandhi 18:6a4db94011d3 390 if(tx) {
sahilmgandhi 18:6a4db94011d3 391 pdc_packet_t pdc_packet_tx;
sahilmgandhi 18:6a4db94011d3 392 pdc_packet_tx.ul_addr=(uint32_t)tx;
sahilmgandhi 18:6a4db94011d3 393 pdc_packet_tx.ul_size=tx_length;
sahilmgandhi 18:6a4db94011d3 394
sahilmgandhi 18:6a4db94011d3 395 pdcenable|=PERIPH_PTCR_TXTEN;
sahilmgandhi 18:6a4db94011d3 396 /* Configure PDC for data send */
sahilmgandhi 18:6a4db94011d3 397 pdc_tx_init(obj->spi.pdc, &pdc_packet_tx, NULL);
sahilmgandhi 18:6a4db94011d3 398 }
sahilmgandhi 18:6a4db94011d3 399
sahilmgandhi 18:6a4db94011d3 400 if(rx) {
sahilmgandhi 18:6a4db94011d3 401 pdc_rx_clear_cnt(obj->spi.pdc);
sahilmgandhi 18:6a4db94011d3 402 pdc_packet_t pdc_packet_rx;
sahilmgandhi 18:6a4db94011d3 403 pdc_packet_rx.ul_addr=(uint32_t)rx;
sahilmgandhi 18:6a4db94011d3 404 pdc_packet_rx.ul_size=rx_length;
sahilmgandhi 18:6a4db94011d3 405 pdcenable|=PERIPH_PTCR_RXTEN;
sahilmgandhi 18:6a4db94011d3 406 char *rxbuffer=(char *)rx;
sahilmgandhi 18:6a4db94011d3 407 for(uint8_t index=0; index<rx_length; index++, rxbuffer++)
sahilmgandhi 18:6a4db94011d3 408 *rxbuffer=SPI_FILL_WORD;
sahilmgandhi 18:6a4db94011d3 409
sahilmgandhi 18:6a4db94011d3 410 /* Configure PDC for data receive */
sahilmgandhi 18:6a4db94011d3 411 pdc_rx_init(obj->spi.pdc, &pdc_packet_rx, NULL);
sahilmgandhi 18:6a4db94011d3 412 }
sahilmgandhi 18:6a4db94011d3 413
sahilmgandhi 18:6a4db94011d3 414 obj->spi.dma_usage=hint;
sahilmgandhi 18:6a4db94011d3 415 obj->spi.event=event;
sahilmgandhi 18:6a4db94011d3 416
sahilmgandhi 18:6a4db94011d3 417 NVIC_ClearPendingIRQ(obj->spi.irq_type);
sahilmgandhi 18:6a4db94011d3 418 NVIC_DisableIRQ(obj->spi.irq_type);
sahilmgandhi 18:6a4db94011d3 419 NVIC_SetVector(obj->spi.irq_type,handler);
sahilmgandhi 18:6a4db94011d3 420 NVIC_EnableIRQ(obj->spi.irq_type);
sahilmgandhi 18:6a4db94011d3 421
sahilmgandhi 18:6a4db94011d3 422 /* Enable SPI IRQ */
sahilmgandhi 18:6a4db94011d3 423 spi_enable_interrupt(obj->spi.spi_base, SPI_IER_RXBUFF| SPI_IER_TXBUFE | SPI_IER_MODF | SPI_IER_OVRES);
sahilmgandhi 18:6a4db94011d3 424
sahilmgandhi 18:6a4db94011d3 425 /* Enable PDC transfers */
sahilmgandhi 18:6a4db94011d3 426 pdc_enable_transfer(obj->spi.pdc, pdcenable );
sahilmgandhi 18:6a4db94011d3 427
sahilmgandhi 18:6a4db94011d3 428 }
sahilmgandhi 18:6a4db94011d3 429
sahilmgandhi 18:6a4db94011d3 430 /** The asynchronous IRQ handler
sahilmgandhi 18:6a4db94011d3 431 *
sahilmgandhi 18:6a4db94011d3 432 * Reads the received values out of the RX FIFO, writes values into the TX FIFO and checks for transfer termination
sahilmgandhi 18:6a4db94011d3 433 * conditions, such as buffer overflows or transfer complete.
sahilmgandhi 18:6a4db94011d3 434 * @param[in] obj The SPI object which holds the transfer information
sahilmgandhi 18:6a4db94011d3 435 * @return event flags if a transfer termination condition was met or 0 otherwise.
sahilmgandhi 18:6a4db94011d3 436 */
sahilmgandhi 18:6a4db94011d3 437 uint32_t spi_irq_handler_asynch(spi_t *obj)
sahilmgandhi 18:6a4db94011d3 438 {
sahilmgandhi 18:6a4db94011d3 439 uint32_t event=0;
sahilmgandhi 18:6a4db94011d3 440
sahilmgandhi 18:6a4db94011d3 441 // Data transferred via DMA
sahilmgandhi 18:6a4db94011d3 442 if((obj->spi.spi_base->SPI_SR & SPI_IER_TXBUFE)) {
sahilmgandhi 18:6a4db94011d3 443 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_TXBUFE | SPI_IDR_MODF | SPI_IDR_OVRES);
sahilmgandhi 18:6a4db94011d3 444 if(obj->spi.event | SPI_EVENT_COMPLETE)
sahilmgandhi 18:6a4db94011d3 445 event |=SPI_EVENT_COMPLETE;
sahilmgandhi 18:6a4db94011d3 446 }
sahilmgandhi 18:6a4db94011d3 447
sahilmgandhi 18:6a4db94011d3 448 if((obj->spi.spi_base->SPI_SR & SPI_IER_RXBUFF)) {
sahilmgandhi 18:6a4db94011d3 449 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_RXBUFF | SPI_IDR_MODF | SPI_IDR_OVRES);
sahilmgandhi 18:6a4db94011d3 450 if(obj->spi.event | SPI_EVENT_COMPLETE)
sahilmgandhi 18:6a4db94011d3 451 event |=SPI_EVENT_COMPLETE;
sahilmgandhi 18:6a4db94011d3 452 }
sahilmgandhi 18:6a4db94011d3 453
sahilmgandhi 18:6a4db94011d3 454 if(obj->spi.spi_base->SPI_SR & SPI_SR_MODF) {
sahilmgandhi 18:6a4db94011d3 455 if(obj->spi.event | SPI_EVENT_ERROR)
sahilmgandhi 18:6a4db94011d3 456 event |=SPI_EVENT_ERROR;
sahilmgandhi 18:6a4db94011d3 457 }
sahilmgandhi 18:6a4db94011d3 458
sahilmgandhi 18:6a4db94011d3 459 if(obj->spi.spi_base->SPI_SR & SPI_SR_OVRES) {
sahilmgandhi 18:6a4db94011d3 460 if(obj->spi.event | SPI_EVENT_RX_OVERFLOW)
sahilmgandhi 18:6a4db94011d3 461 event |=SPI_EVENT_RX_OVERFLOW;
sahilmgandhi 18:6a4db94011d3 462 }
sahilmgandhi 18:6a4db94011d3 463
sahilmgandhi 18:6a4db94011d3 464 return event;
sahilmgandhi 18:6a4db94011d3 465 }
sahilmgandhi 18:6a4db94011d3 466
sahilmgandhi 18:6a4db94011d3 467 /** Attempts to determine if the SPI peripheral is already in use.
sahilmgandhi 18:6a4db94011d3 468 *
sahilmgandhi 18:6a4db94011d3 469 * If a temporary DMA channel has been allocated, peripheral is in use.
sahilmgandhi 18:6a4db94011d3 470 * If a permanent DMA channel has been allocated, check if the DMA channel is in use. If not, proceed as though no DMA
sahilmgandhi 18:6a4db94011d3 471 * channel were allocated.
sahilmgandhi 18:6a4db94011d3 472 * If no DMA channel is allocated, check whether tx and rx buffers have been assigned. For each assigned buffer, check
sahilmgandhi 18:6a4db94011d3 473 * if the corresponding buffer position is less than the buffer length. If buffers do not indicate activity, check if
sahilmgandhi 18:6a4db94011d3 474 * there are any bytes in the FIFOs.
sahilmgandhi 18:6a4db94011d3 475 * @param[in] obj The SPI object to check for activity
sahilmgandhi 18:6a4db94011d3 476 * @return non-zero if the SPI port is active or zero if it is not.
sahilmgandhi 18:6a4db94011d3 477 */
sahilmgandhi 18:6a4db94011d3 478
sahilmgandhi 18:6a4db94011d3 479 uint8_t spi_active(spi_t *obj)
sahilmgandhi 18:6a4db94011d3 480 {
sahilmgandhi 18:6a4db94011d3 481 if(obj->spi.spi_base->SPI_SR & SPI_SR_ENDTX && obj->spi.spi_base->SPI_SR & SPI_SR_ENDRX)
sahilmgandhi 18:6a4db94011d3 482 return 0;
sahilmgandhi 18:6a4db94011d3 483 return 1;
sahilmgandhi 18:6a4db94011d3 484 }
sahilmgandhi 18:6a4db94011d3 485
sahilmgandhi 18:6a4db94011d3 486 /** Abort an SPI transfer
sahilmgandhi 18:6a4db94011d3 487 *
sahilmgandhi 18:6a4db94011d3 488 * @param obj The SPI peripheral to stop
sahilmgandhi 18:6a4db94011d3 489 */
sahilmgandhi 18:6a4db94011d3 490 void spi_abort_asynch(spi_t *obj)
sahilmgandhi 18:6a4db94011d3 491 {
sahilmgandhi 18:6a4db94011d3 492 /* Disable PDC transfers */
sahilmgandhi 18:6a4db94011d3 493 pdc_disable_transfer(obj->spi.pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
sahilmgandhi 18:6a4db94011d3 494
sahilmgandhi 18:6a4db94011d3 495 /* Clear PDC buffer receive counter */
sahilmgandhi 18:6a4db94011d3 496 pdc_rx_clear_cnt(obj->spi.pdc);
sahilmgandhi 18:6a4db94011d3 497
sahilmgandhi 18:6a4db94011d3 498 /* Disable SPI IRQ */
sahilmgandhi 18:6a4db94011d3 499 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_TXBUFE);
sahilmgandhi 18:6a4db94011d3 500 spi_disable_interrupt(obj->spi.spi_base, SPI_IDR_RXBUFF);
sahilmgandhi 18:6a4db94011d3 501
sahilmgandhi 18:6a4db94011d3 502 /* Disable SPI interrupt */
sahilmgandhi 18:6a4db94011d3 503 NVIC_DisableIRQ(obj->spi.irq_type);
sahilmgandhi 18:6a4db94011d3 504 }
sahilmgandhi 18:6a4db94011d3 505
sahilmgandhi 18:6a4db94011d3 506 #endif