Skip to content

Commit ccfe2c8

Browse files
authored
Merge pull request #2481 from NXPmicro/KL27_SPI_Driver_Update
KL27 - fix SPI driver error, ARM linker
2 parents 58897c6 + 2d97246 commit ccfe2c8

File tree

3 files changed

+151
-56
lines changed

3 files changed

+151
-56
lines changed

hal/targets/cmsis/TARGET_Freescale/TARGET_KL27Z/TOOLCHAIN_ARM_STD/MKL27Z64xxx4.sct

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
** Abstract:
1616
** Linker file for the Keil ARM C/C++ Compiler
1717
**
18-
** Copyright (c) 2015 Freescale Semiconductor, Inc.
18+
** Copyright (c) 2016 Freescale Semiconductor, Inc.
1919
** All rights reserved.
2020
**
2121
** Redistribution and use in source and binary forms, with or without modification,
@@ -50,6 +50,10 @@
5050
*/
5151
#define __ram_vector_table__ 1
5252

53+
/* Heap 1/4 of ram and stack 1/8 */
54+
#define __stack_size__ 0x800
55+
#define __heap_size__ 0x1000
56+
5357
#if (defined(__ram_vector_table__))
5458
#define __ram_vector_table_size__ 0x00000200
5559
#else
@@ -71,22 +75,42 @@
7175
#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size)
7276
#define m_data_size (0x00004000 - m_interrupts_ram_size)
7377

78+
/* Sizes */
79+
#if (defined(__stack_size__))
80+
#define Stack_Size __stack_size__
81+
#else
82+
#define Stack_Size 0x0400
83+
#endif
84+
85+
#if (defined(__heap_size__))
86+
#define Heap_Size __heap_size__
87+
#else
88+
#define Heap_Size 0x0400
89+
#endif
7490

75-
LR_m_text m_interrupts_start 0x10000 { ; load region size_region
91+
LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; load region size_region
7692
VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
7793
* (RESET,+FIRST)
7894
}
7995
ER_m_flash_config m_flash_config_start FIXED m_flash_config_size { ; load address = execution address
8096
* (FlashConfig)
8197
}
82-
ER_m_text m_text_start FIXED m_text_size { ; load address = execution address
98+
ER_m_text m_text_start m_text_size { ; load address = execution address
8399
* (InRoot$$Sections)
84100
.ANY (+RO)
85101
}
102+
103+
#if (defined(__ram_vector_table__))
86104
VECTOR_RAM m_interrupts_ram_start EMPTY m_interrupts_ram_size {
87105
}
88-
RW_IRAM1 m_data_start m_data_size { ; RW data
106+
#else
107+
VECTOR_RAM m_interrupts_start EMPTY 0 {
108+
}
109+
#endif
110+
RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
89111
.ANY (+RW +ZI)
90112
}
113+
RW_IRAM1 +0 EMPTY Heap_Size { ; RW data
114+
}
91115
}
92116

hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_spi.c

Lines changed: 104 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ enum _spi_transfer_states_t
4040
kSPI_Busy /*!< SPI is busy tranferring data. */
4141
};
4242

43+
/*! @brief Typedef for spi master interrupt handler. spi master and slave handle is the same. */
44+
typedef void (*spi_isr_t)(SPI_Type *base, spi_master_handle_t *spiHandle);
45+
4346
/*******************************************************************************
4447
* Prototypes
4548
******************************************************************************/
@@ -92,15 +95,18 @@ static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle);
9295
/*******************************************************************************
9396
* Variables
9497
******************************************************************************/
95-
/* SPI internal handle pointer array */
98+
/*! @brief SPI internal handle pointer array */
9699
static spi_master_handle_t *s_spiHandle[FSL_FEATURE_SOC_SPI_COUNT];
97-
/* Base pointer array */
100+
/*! @brief Base pointer array */
98101
static SPI_Type *const s_spiBases[] = SPI_BASE_PTRS;
99-
/* IRQ name array */
102+
/*! @brief IRQ name array */
100103
static const IRQn_Type s_spiIRQ[] = SPI_IRQS;
101-
/* Clock array name */
104+
/*! @brief Clock array name */
102105
static const clock_ip_name_t s_spiClock[] = SPI_CLOCKS;
103106

107+
/*! @brief Pointer to master IRQ handler for each instance. */
108+
static spi_isr_t s_spiIsr;
109+
104110
/*******************************************************************************
105111
* Code
106112
******************************************************************************/
@@ -202,36 +208,64 @@ static void SPI_ReadNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
202208
static void SPI_SendTransfer(SPI_Type *base, spi_master_handle_t *handle)
203209
{
204210
uint8_t bytes = MIN((handle->watermark * 2U), handle->txRemainingBytes);
205-
uint8_t val = 1U;
206211

207212
/* Read S register and ensure SPTEF is 1, otherwise the write would be ignored. */
208213
if (handle->watermark == 1U)
209214
{
210-
val = (base->S & SPI_S_SPTEF_MASK);
211215
if (bytes != 0U)
212216
{
213217
bytes = handle->bytePerFrame;
214218
}
219+
220+
/* Send data */
221+
if (base->C1 & SPI_C1_MSTR_MASK)
222+
{
223+
/* As a master, only write once */
224+
if (base->S & SPI_S_SPTEF_MASK)
225+
{
226+
SPI_WriteNonBlocking(base, handle->txData, bytes);
227+
/* Update handle information */
228+
if (handle->txData)
229+
{
230+
handle->txData += bytes;
231+
}
232+
handle->txRemainingBytes -= bytes;
233+
}
215234
}
216-
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO)
217235
else
218236
{
219-
val = (base->S & SPI_S_TNEAREF_MASK);
237+
/* As a slave, send data until SPTEF cleared */
238+
while ((base->S & SPI_S_SPTEF_MASK) && (handle->txRemainingBytes > 0))
239+
{
240+
SPI_WriteNonBlocking(base, handle->txData, bytes);
241+
242+
/* Update handle information */
243+
if (handle->txData)
244+
{
245+
handle->txData += bytes;
246+
}
247+
handle->txRemainingBytes -= bytes;
248+
}
249+
}
220250
}
221-
#endif
222251

223-
/* Write data */
224-
if (val)
252+
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO)
253+
/* If use FIFO */
254+
else
225255
{
226-
SPI_WriteNonBlocking(base, handle->txData, bytes);
227-
228-
/* Update handle information */
229-
if (handle->txData)
256+
if (base->S & SPI_S_TNEAREF_MASK)
230257
{
231-
handle->txData += bytes;
258+
SPI_WriteNonBlocking(base, handle->txData, bytes);
259+
260+
/* Update handle information */
261+
if (handle->txData)
262+
{
263+
handle->txData += bytes;
264+
}
265+
handle->txRemainingBytes -= bytes;
232266
}
233-
handle->txRemainingBytes -= bytes;
234267
}
268+
#endif
235269
}
236270

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

287321
void SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz)
288322
{
323+
assert(config && srcClock_Hz);
324+
289325
/* Open clock gate for SPI and open interrupt */
290326
CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]);
291327

@@ -345,6 +381,8 @@ void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config)
345381

346382
void SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config)
347383
{
384+
assert(config);
385+
348386
/* Open clock gate for SPI and open interrupt */
349387
CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]);
350388

@@ -536,21 +574,24 @@ void SPI_MasterSetBaudRate(SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcCl
536574
void SPI_WriteBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
537575
{
538576
uint32_t i = 0;
577+
uint8_t bytesPerFrame = 1U;
578+
579+
#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
580+
/* Check if 16 bits or 8 bits */
581+
bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
582+
#endif
539583

540584
while (i < size)
541585
{
542586
while ((base->S & SPI_S_SPTEF_MASK) == 0)
543587
{
544588
}
545589

546-
/* Send data */
547-
SPI_WriteNonBlocking(base, buffer, size);
590+
/* Send a frame of data */
591+
SPI_WriteNonBlocking(base, buffer, bytesPerFrame);
548592

549-
/* Wait the data to be sent */
550-
while ((base->S & SPI_S_SPTEF_MASK) == 0)
551-
{
552-
}
553-
i++;
593+
i += bytesPerFrame;
594+
buffer += bytesPerFrame;
554595
}
555596
}
556597

@@ -668,6 +709,7 @@ void SPI_MasterTransferCreateHandle(SPI_Type *base,
668709
s_spiHandle[instance] = handle;
669710
handle->callback = callback;
670711
handle->userData = userData;
712+
s_spiIsr = SPI_MasterTransferHandleIRQ;
671713

672714
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
673715
uint8_t txSize = 0U;
@@ -836,38 +878,68 @@ void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle)
836878
}
837879
}
838880

839-
static void SPI_TransferCommonIRQHandler(SPI_Type *base, void *handle)
881+
void SPI_SlaveTransferCreateHandle(SPI_Type *base,
882+
spi_slave_handle_t *handle,
883+
spi_slave_callback_t callback,
884+
void *userData)
885+
{
886+
assert(handle);
887+
888+
/* Slave create handle share same logic with master create handle, the only difference
889+
is the Isr pointer. */
890+
SPI_MasterTransferCreateHandle(base, handle, callback, userData);
891+
s_spiIsr = SPI_SlaveTransferHandleIRQ;
892+
}
893+
894+
void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle)
840895
{
841-
if (base->C1 & SPI_C1_MSTR_MASK)
896+
assert(handle);
897+
898+
/* Do data send first in case of data missing. */
899+
if (handle->txRemainingBytes)
900+
{
901+
SPI_SendTransfer(base, handle);
902+
}
903+
904+
/* If needs to receive data, do a receive */
905+
if (handle->rxRemainingBytes)
842906
{
843-
SPI_MasterTransferHandleIRQ(base, (spi_master_handle_t *)handle);
907+
SPI_ReceiveTransfer(base, handle);
844908
}
845-
else
909+
910+
/* All the transfer finished */
911+
if ((handle->txRemainingBytes == 0) && (handle->rxRemainingBytes == 0))
846912
{
847-
SPI_SlaveTransferHandleIRQ(base, (spi_slave_handle_t *)handle);
913+
/* Complete the transfer */
914+
SPI_SlaveTransferAbort(base, handle);
915+
916+
if (handle->callback)
917+
{
918+
(handle->callback)(base, handle, kStatus_SPI_Idle, handle->userData);
919+
}
848920
}
849921
}
850922

851923
#if defined(SPI0)
852924
void SPI0_DriverIRQHandler(void)
853925
{
854926
assert(s_spiHandle[0]);
855-
SPI_TransferCommonIRQHandler(SPI0, s_spiHandle[0]);
927+
s_spiIsr(SPI0, s_spiHandle[0]);
856928
}
857929
#endif
858930

859931
#if defined(SPI1)
860932
void SPI1_DriverIRQHandler(void)
861933
{
862934
assert(s_spiHandle[1]);
863-
SPI_TransferCommonIRQHandler(SPI1, s_spiHandle[1]);
935+
s_spiIsr(SPI1, s_spiHandle[1]);
864936
}
865937
#endif
866938

867939
#if defined(SPI2)
868940
void SPI2_DriverIRQHandler(void)
869941
{
870942
assert(s_spiHandle[2]);
871-
SPI_TransferCommonIRQHandler(SPI0, s_spiHandle[2]);
943+
s_spiIsr(SPI0, s_spiHandle[2]);
872944
}
873945
#endif

0 commit comments

Comments
 (0)