Skip to content

KL27 update #2481

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
** Abstract:
** Linker file for the Keil ARM C/C++ Compiler
**
** Copyright (c) 2015 Freescale Semiconductor, Inc.
** Copyright (c) 2016 Freescale Semiconductor, Inc.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification,
Expand Down Expand Up @@ -50,6 +50,10 @@
*/
#define __ram_vector_table__ 1

/* Heap 1/4 of ram and stack 1/8 */
#define __stack_size__ 0x800
#define __heap_size__ 0x1000

#if (defined(__ram_vector_table__))
#define __ram_vector_table_size__ 0x00000200
#else
Expand All @@ -71,22 +75,42 @@
#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size)
#define m_data_size (0x00004000 - m_interrupts_ram_size)

/* Sizes */
#if (defined(__stack_size__))
#define Stack_Size __stack_size__
#else
#define Stack_Size 0x0400
#endif

#if (defined(__heap_size__))
#define Heap_Size __heap_size__
#else
#define Heap_Size 0x0400
#endif

LR_m_text m_interrupts_start 0x10000 { ; load region size_region
LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region
VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
* (RESET,+FIRST)
}
ER_m_flash_config m_flash_config_start FIXED m_flash_config_size { ; load address = execution address
* (FlashConfig)
}
ER_m_text m_text_start FIXED m_text_size { ; load address = execution address
ER_m_text m_text_start m_text_size { ; load address = execution address
* (InRoot$$Sections)
.ANY (+RO)
}

#if (defined(__ram_vector_table__))
VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size {
}
RW_IRAM1 m_data_start m_data_size { ; RW data
#else
VECTOR_RAM m_interrupts_start EMPTY 0 {
}
#endif
RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM1 +0 EMPTY Heap_Size { ; RW data
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ enum _spi_transfer_states_t
kSPI_Busy /*!< SPI is busy tranferring data. */
};

/*! @brief Typedef for spi master interrupt handler. spi master and slave handle is the same. */
typedef void (*spi_isr_t)(SPI_Type *base, spi_master_handle_t *spiHandle);

/*******************************************************************************
* Prototypes
******************************************************************************/
Expand Down Expand Up @@ -92,15 +95,18 @@ static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle);
/*******************************************************************************
* Variables
******************************************************************************/
/* SPI internal handle pointer array */
/*! @brief SPI internal handle pointer array */
static spi_master_handle_t *s_spiHandle[FSL_FEATURE_SOC_SPI_COUNT];
/* Base pointer array */
/*! @brief Base pointer array */
static SPI_Type *const s_spiBases[] = SPI_BASE_PTRS;
/* IRQ name array */
/*! @brief IRQ name array */
static const IRQn_Type s_spiIRQ[] = SPI_IRQS;
/* Clock array name */
/*! @brief Clock array name */
static const clock_ip_name_t s_spiClock[] = SPI_CLOCKS;

/*! @brief Pointer to master IRQ handler for each instance. */
static spi_isr_t s_spiIsr;

/*******************************************************************************
* Code
******************************************************************************/
Expand Down Expand Up @@ -202,36 +208,64 @@ static void SPI_ReadNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
static void SPI_SendTransfer(SPI_Type *base, spi_master_handle_t *handle)
{
uint8_t bytes = MIN((handle->watermark * 2U), handle->txRemainingBytes);
uint8_t val = 1U;

/* Read S register and ensure SPTEF is 1, otherwise the write would be ignored. */
if (handle->watermark == 1U)
{
val = (base->S & SPI_S_SPTEF_MASK);
if (bytes != 0U)
{
bytes = handle->bytePerFrame;
}

/* Send data */
if (base->C1 & SPI_C1_MSTR_MASK)
{
/* As a master, only write once */
if (base->S & SPI_S_SPTEF_MASK)
{
SPI_WriteNonBlocking(base, handle->txData, bytes);
/* Update handle information */
if (handle->txData)
{
handle->txData += bytes;
}
handle->txRemainingBytes -= bytes;
}
}
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO)
else
{
val = (base->S & SPI_S_TNEAREF_MASK);
/* As a slave, send data until SPTEF cleared */
while ((base->S & SPI_S_SPTEF_MASK) && (handle->txRemainingBytes > 0))
{
SPI_WriteNonBlocking(base, handle->txData, bytes);

/* Update handle information */
if (handle->txData)
{
handle->txData += bytes;
}
handle->txRemainingBytes -= bytes;
}
}
}
#endif

/* Write data */
if (val)
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO)
/* If use FIFO */
else
{
SPI_WriteNonBlocking(base, handle->txData, bytes);

/* Update handle information */
if (handle->txData)
if (base->S & SPI_S_TNEAREF_MASK)
{
handle->txData += bytes;
SPI_WriteNonBlocking(base, handle->txData, bytes);

/* Update handle information */
if (handle->txData)
{
handle->txData += bytes;
}
handle->txRemainingBytes -= bytes;
}
handle->txRemainingBytes -= bytes;
}
#endif
}

static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle)
Expand Down Expand Up @@ -286,6 +320,8 @@ void SPI_MasterGetDefaultConfig(spi_master_config_t *config)

void SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz)
{
assert(config && srcClock_Hz);

/* Open clock gate for SPI and open interrupt */
CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]);

Expand Down Expand Up @@ -345,6 +381,8 @@ void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config)

void SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config)
{
assert(config);

/* Open clock gate for SPI and open interrupt */
CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]);

Expand Down Expand Up @@ -536,21 +574,24 @@ void SPI_MasterSetBaudRate(SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcCl
void SPI_WriteBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
{
uint32_t i = 0;
uint8_t bytesPerFrame = 1U;

#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
/* Check if 16 bits or 8 bits */
bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
#endif

while (i < size)
{
while ((base->S & SPI_S_SPTEF_MASK) == 0)
{
}

/* Send data */
SPI_WriteNonBlocking(base, buffer, size);
/* Send a frame of data */
SPI_WriteNonBlocking(base, buffer, bytesPerFrame);

/* Wait the data to be sent */
while ((base->S & SPI_S_SPTEF_MASK) == 0)
{
}
i++;
i += bytesPerFrame;
buffer += bytesPerFrame;
}
}

Expand Down Expand Up @@ -668,6 +709,7 @@ void SPI_MasterTransferCreateHandle(SPI_Type *base,
s_spiHandle[instance] = handle;
handle->callback = callback;
handle->userData = userData;
s_spiIsr = SPI_MasterTransferHandleIRQ;

#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
uint8_t txSize = 0U;
Expand Down Expand Up @@ -836,38 +878,68 @@ void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle)
}
}

static void SPI_TransferCommonIRQHandler(SPI_Type *base, void *handle)
void SPI_SlaveTransferCreateHandle(SPI_Type *base,
spi_slave_handle_t *handle,
spi_slave_callback_t callback,
void *userData)
{
assert(handle);

/* Slave create handle share same logic with master create handle, the only difference
is the Isr pointer. */
SPI_MasterTransferCreateHandle(base, handle, callback, userData);
s_spiIsr = SPI_SlaveTransferHandleIRQ;
}

void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle)
{
if (base->C1 & SPI_C1_MSTR_MASK)
assert(handle);

/* Do data send first in case of data missing. */
if (handle->txRemainingBytes)
{
SPI_SendTransfer(base, handle);
}

/* If needs to receive data, do a receive */
if (handle->rxRemainingBytes)
{
SPI_MasterTransferHandleIRQ(base, (spi_master_handle_t *)handle);
SPI_ReceiveTransfer(base, handle);
}
else

/* All the transfer finished */
if ((handle->txRemainingBytes == 0) && (handle->rxRemainingBytes == 0))
{
SPI_SlaveTransferHandleIRQ(base, (spi_slave_handle_t *)handle);
/* Complete the transfer */
SPI_SlaveTransferAbort(base, handle);

if (handle->callback)
{
(handle->callback)(base, handle, kStatus_SPI_Idle, handle->userData);
}
}
}

#if defined(SPI0)
void SPI0_DriverIRQHandler(void)
{
assert(s_spiHandle[0]);
SPI_TransferCommonIRQHandler(SPI0, s_spiHandle[0]);
s_spiIsr(SPI0, s_spiHandle[0]);
}
#endif

#if defined(SPI1)
void SPI1_DriverIRQHandler(void)
{
assert(s_spiHandle[1]);
SPI_TransferCommonIRQHandler(SPI1, s_spiHandle[1]);
s_spiIsr(SPI1, s_spiHandle[1]);
}
#endif

#if defined(SPI2)
void SPI2_DriverIRQHandler(void)
{
assert(s_spiHandle[2]);
SPI_TransferCommonIRQHandler(SPI0, s_spiHandle[2]);
s_spiIsr(SPI0, s_spiHandle[2]);
}
#endif
Loading