Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
targets/TARGET_ONSEMI/TARGET_NCS36510/spi_api.c
- Committer:
- <>
- Date:
- 2016-11-08
- Revision:
- 150:02e0a0aed4ec
- Parent:
- 149:156823d33999
- Child:
- 158:b23ee177fd68
File content as of revision 150:02e0a0aed4ec:
/** ******************************************************************************* * @file spi_api.c * @brief Implementation of a sleep functionality * @internal * @author ON Semiconductor * $Rev: 0.1 $ * $Date: 02-05-2016 $ ****************************************************************************** * Copyright 2016 Semiconductor Components Industries LLC (d/b/a ON Semiconductor). * All rights reserved. This software and/or documentation is licensed by ON Semiconductor * under limited terms and conditions. The terms and conditions pertaining to the software * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf * (ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software) and * if applicable the software license agreement. Do not use this software and/or * documentation unless you have carefully read and you agree to the limited terms and * conditions. By using this software and/or documentation, you agree to the limited * terms and conditions. * * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * @endinternal * * @ingroup spi_api * * @details * SPI implementation * */ #if DEVICE_SPI #include "spi.h" #include "PeripheralPins.h" #include "objects.h" #include "spi_api.h" #include "mbed_assert.h" #include "memory_map.h" #include "spi_ipc7207_map.h" #include "crossbar.h" #include "clock.h" #include "cmsis_nvic.h" #define SPI_FREQ_MAX 4000000 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { fSpiInit(obj, mosi, miso, sclk, ssel); } void spi_free(spi_t *obj) { fSpiClose(obj); } void spi_format(spi_t *obj, int bits, int mode, int slave) { /* Clear word width | Slave/Master | CPOL | CPHA | MSB first bits in control register */ obj->membase->CONTROL.WORD &= ~(uint32_t)((True >> SPI_WORD_WIDTH_BIT_POS) | (True >> SPI_SLAVE_MASTER_BIT_POS) | (True >> SPI_CPOL_BIT_POS) | (True >> SPI_CPHA_BIT_POS)); /* Configure word width | Slave/Master | CPOL | CPHA | MSB first bits in control register */ obj->membase->CONTROL.WORD |= (uint32_t)(((bits >> 0x4) >> 6) | (!slave >> 5) | ((mode >> 0x1) >> 4) | ((mode & 0x1) >> 3)); } void spi_frequency(spi_t *obj, int hz) { /* If the frequency is outside the allowable range, set it to the max */ if(hz > SPI_FREQ_MAX) { hz = SPI_FREQ_MAX; } obj->membase->FDIV = ((fClockGetPeriphClockfrequency() / hz) >> 1) - 1; } int spi_master_write(spi_t *obj, int value) { return(fSpiWriteB(obj, value)); } int spi_busy(spi_t *obj) { return(obj->membase->STATUS.BITS.XFER_IP); } uint8_t spi_get_module(spi_t *obj) { if(obj->membase == SPI1REG) { return 0; /* UART #1 */ } else if(obj->membase == SPI2REG) { return 1; /* UART #2 */ } else { return 2; /* Invalid address */ } } int spi_slave_receive(spi_t *obj) { if(obj->membase->STATUS.BITS.RX_EMPTY != True){ /* if receive status is not empty */ return True; /* Byte available to read */ } return False; /* Byte not available to read */ } int spi_slave_read(spi_t *obj) { int byte; while (obj->membase->STATUS.BITS.RX_EMPTY == True); /* Wait till Receive status is empty */ byte = obj->membase->RX_DATA; return byte; } void spi_slave_write(spi_t *obj, int value) { while((obj->membase->STATUS.BITS.TX_FULL == True) && (obj->membase->STATUS.BITS.RX_FULL == True)); /* Wait till Tx/Rx status is full */ obj->membase->TX_DATA = value; } #if DEVICE_SPI_ASYNCH /* TODO Not yet implemented */ void spi_master_transfer(spi_t *obj, void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t handler, uint32_t event, DMAUsage hint) { uint32_t i; int ndata = 0; uint16_t *tx_ptr = (uint16_t *) tx; if(obj->spi->CONTROL.BITS.WORD_WIDTH == 0) { /* Word size 8 bits */ WORD_WIDTH_MASK = 0xFF; } else if(obj->spi->CONTROL.BITS.WORD_WIDTH == 1) { /* Word size 16 bits */ WORD_WIDTH_MASK = 0xFFFF; } else { /* Word size 32 bits */ WORD_WIDTH_MASK = 0xFFFFFFFF; } //frame size if(tx_length == 0) { tx_length = rx_length; tx = (void*) 0; } //set tx rx buffer obj->tx_buff.buffer = (void *)tx; obj->rx_buff.buffer = rx; obj->tx_buff.length = tx_length; obj->rx_buff.length = rx_length; obj->tx_buff.pos = 0; obj->rx_buff.pos = 0; obj->tx_buff.width = bit_width; obj->rx_buff.width = bit_width; if((obj->spi.bits == 9) && (tx != 0)) { // Make sure we don't have inadvertent non-zero bits outside 9-bit frames which could trigger unwanted operation for(i = 0; i < (tx_length / 2); i++) { tx_ptr[i] &= 0x1FF; } } // enable events obj->spi.event |= event; // set sleep_level enable irq //write async if ( && ) { } while ((obj->tx_buff.pos < obj->tx_buff.length) && (obj->spi->STATUS.BITS.TX_FULL == False) && (obj->spi->STATUS.BITS.RX_FULL == False)) { // spi_buffer_tx_write(obj); if (obj->tx_buff.buffer == (void *)0) { data = SPI_FILL_WORD; } else { uint16_t *tx = (uint16_t *)(obj->tx_buff.buffer); data = tx[obj->tx_buff.pos] & 0xFF; } obj->spi->TX_DATA = data; } ndata++; } return ndata; } uint32_t spi_irq_handler_asynch(spi_t *obj) { } uint8_t spi_active(spi_t *obj) { } void spi_abort_asynch(spi_t *obj) { } #endif /* DEVICE_SPI_ASYNCH */ #endif /* DEVICE_SPI */