mbed-os
Fork of mbed-os by
Diff: targets/TARGET_ONSEMI/TARGET_NCS36510/spi_api.c
- Revision:
- 0:f269e3021894
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/spi_api.c Sun Oct 23 15:10:02 2016 +0000 @@ -0,0 +1,213 @@ +/** + ******************************************************************************* + * @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 implemented yet */ + +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 */ \ No newline at end of file