Merge pull request #2866 from pradeep-gr/master

MBED OS 3 to 5 changes added for SPI
pull/3004/head
Sam Grove 2016-10-12 17:13:54 -05:00 committed by GitHub
commit ffe05f706a
64 changed files with 1155 additions and 1119 deletions

View File

@ -89,8 +89,16 @@ const PinMap PinMap_SPI_MISO[] = {
const PinMap PinMap_SPI_SSEL[] = {
/*todo: other pins are possible, need to add */
/* TODO what about SSNO */
{SPI1_SSNO0_1, SPI_0, 6},
{SPI1_SSNO1_1, SPI_0, 6},
{SPI1_SSNO2_1, SPI_0, 6},
{SPI1_SSNO3_1, SPI_0, 6},
{SPI1_SSNI_2, SPI_0, 6},
{SPI1_SSNO0_2, SPI_0, 6},
{SPI1_SSNO1_2, SPI_0, 6},
{SPI1_SSNO2_2, SPI_0, 6},
{SPI2_SSNI, SPI_1, 6},
{SPI2_SSNO0, SPI_1, 6},
{NC, NC, 0}
};

View File

@ -31,8 +31,7 @@
* ---------- Interrupt Number Definition -----------------------------------
* ==========================================================================
*/
typedef enum IRQn
{
typedef enum IRQn {
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Cortex-M3 Non Maskable Interrupt */
HardFault_IRQn = -13, /*!< 3 Cortex-M3 Hard Fault Interrupt */

View File

@ -2,8 +2,7 @@
* NCS36510 ARM GCC linker script file
*/
MEMORY
{
MEMORY {
VECTORS (rx) : ORIGIN = 0x00003000, LENGTH = 0x00000090
FLASH (rx) : ORIGIN = 0x00003090, LENGTH = 320K - 4K - 0x90
RAM (rwx) : ORIGIN = 0x3FFF4000, LENGTH = 48K
@ -37,8 +36,7 @@ MEMORY
*/
ENTRY(Reset_Handler)
SECTIONS
{
SECTIONS {
.isr_vector :
{
__vector_table = .;

View File

@ -1,4 +1,4 @@
;/**************************************************************************//**
;/******************************************************************************
; * @file startup_ARMCM3.s
; * @brief CMSIS Cortex-M4 Core Device Startup File
; * for CM3 Device Series

View File

@ -44,7 +44,8 @@ uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Cloc
Clock functions
*----------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
{ /*Function not implimented */
{
/*Function not implimented */
SystemCoreClock = __SYSTEM_CLOCK;
}

View File

@ -60,50 +60,12 @@ void lp_ticker_set_interrupt(timestamp_t timestamp)
fRtcSetInterrupt(timestamp);
}
/*Return the time that gets cut off when you return just a 32 bit us resolution number */
uint32_t lp_ticker_get_overflows_counter(void)
{
/* To check; do we need an counter in software in RTC to find overflows */
uint64_t now = fRtcRead();
uint32_t overflow = (now & 0xFFFFFFFF00000000) >> 32;
return overflow;
}
/* Return the RTC Match counter contents */
uint32_t lp_ticker_get_compare_match()
{
/* read the alarms and convert to us */
uint16_t sub_second_alarm = RTCREG->SUB_SECOND_ALARM;
uint32_t second_alarm = RTCREG->SECOND_ALARM;
uint64_t alarm_us = (uint64_t)((((float)sub_second_alarm / RTC_CLOCK_HZ) * RTC_SEC_TO_US) +
(second_alarm * RTC_SEC_TO_US));
/* TODO truncating to 32 bits */
return (uint32_t)(alarm_us & 0xFFFFFFFF);
}
/* sleep until alarm */
void lp_ticker_sleep_until(uint32_t now, uint32_t time)
{
/* Set the interrupt */
lp_ticker_set_interrupt(time);
/* Go to sleep */
sleep_t obj;
obj.SleepType = SLEEP_TYPE_NONE;
obj.timeToSleep = time - now;
mbed_enter_sleep(&obj);
/* TBD: This is dummy exit for now; once the entered sleep it should be
removed and sleep exit should happen through interrupt */
mbed_exit_sleep(&obj);
}
/** Disable low power ticker interrupt
*
*/
void lp_ticker_disable_interrupt(void)
{
/* TODO : This is an empty implementation for now */
fRtcDisableInterrupt();
}
/** Clear the low power ticker interrupt
@ -111,7 +73,7 @@ void lp_ticker_disable_interrupt(void)
*/
void lp_ticker_clear_interrupt(void)
{
/* TODO : This is an empty implementation for now */
fRtcClearInterrupt();
}
#endif /* DEVICE_LOWPOWERTIMER */

View File

@ -58,7 +58,7 @@ void fSpiInit(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
SPIName spi_ssel = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SSEL);
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
SPIName spi_data_1 = (SPIName)pinmap_merge(spi_mosi, spi_miso);
SPIName spi_data_2 = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
@ -75,62 +75,61 @@ void fSpiInit(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
CLOCK_ENABLE(CLOCK_SPI2); /* Enable clock */
}
CLOCK_ENABLE(CLOCK_CROSSB);
/* Cross bar setting: Map GPIOs to SPI */
pinmap_pinout(sclk, PinMap_SPI_SCLK);
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(miso, PinMap_SPI_SSEL);/* TODO Need to implement as per morpheus */
/* TODO Do we need GPIO direction settings done here or at init phase? */
/* GPIO config */
/* Configure GPIO Direction */
CLOCK_ENABLE(CLOCK_GPIO);
GPIOREG->W_OUT |= ((0x1 << sclk) | (0x1 << mosi)); /* Set pins as output */
GPIOREG->W_IN |= (0x1 << miso); /* Set pin as input */
GPIOREG->W_OUT |= ((True << sclk) | (True << mosi) | (True << ssel)); /* Set pins as output */
GPIOREG->W_IN |= (True << miso); /* Set pin as input */
pin_mode(sclk, PushPullNoPull);
pin_mode(mosi, PushPullPullUp);
pin_mode(miso, OpenDrainPullUp);
/* Pad settings */
CLOCK_ENABLE(CLOCK_PAD);
pin_mode(sclk, PushPullPullDown);
pin_mode(mosi, PushPullPullDown);
/* PAD drive strength */
PadReg_t *padRegOffset = (PadReg_t*)(PADREG_BASE + (sclk * PAD_REG_ADRS_BYTE_SIZE));
CLOCK_ENABLE(CLOCK_PAD);
padRegOffset->PADIO0.BITS.POWER = 1; /* sclk: Drive strength */
padRegOffset->PADIO1.BITS.POWER = 1; /* mosi: Drive strength */
padRegOffset->PADIO2.BITS.POWER = 1; /* miso: Drive strength */
padRegOffset->PADIO0.BITS.POWER = True; /* sclk: Drive strength */
padRegOffset->PADIO1.BITS.POWER = True; /* mosi: Drive strength */
if(miso != NC) {
pinmap_pinout(miso, PinMap_SPI_MISO); /* Cross bar settings */
pin_mode(miso, OpenDrainNoPull); /* Pad setting */
padRegOffset->PADIO2.BITS.POWER = True; /* miso: Drive strength */
}
if(ssel != NC) {
pinmap_pinout(ssel, PinMap_SPI_SSEL); /* Cross bar settings */
pin_mode(ssel, PushPullPullUp); /* Pad setting */
padRegOffset->PADIO3.BITS.POWER = True; /* ssel: Drive strength */
SPI1REG->SLAVE_SELECT.BITS.SS_ENABLE = SPI_SLAVE_SELECT_NORM_BEHAVE; /* Slave select: Normal behavior */
}
CLOCK_DISABLE(CLOCK_PAD);
CLOCK_DISABLE(CLOCK_GPIO);
CLOCK_DISABLE(CLOCK_CROSSB);
/* disable/reset the spi port */
obj->membase->CONTROL.BITS.ENABLE = False;
/* disable/reset the spi port: Clear control register*/
obj->membase->CONTROL.WORD = False;
/* set default baud rate to 1MHz */
clockDivisor = ((fClockGetPeriphClockfrequency() / 1000000) >> 1) - 1;
clockDivisor = ((fClockGetPeriphClockfrequency() / SPI_DEFAULT_SPEED) >> True) - True;
obj->membase->FDIV = clockDivisor;
/* set tx/rx fifos watermarks */ /* TODO water mark level 1 byte ?*/
obj->membase->TX_WATERMARK = 1;
obj->membase->RX_WATERMARK = 1;
obj->membase->TX_WATERMARK = True;
obj->membase->RX_WATERMARK = True;
/* DIsable and clear IRQs */ /* TODO sync api, do not need irq ?*/
obj->membase->IRQ_ENABLE = False;
obj->membase->IRQ_CLEAR = 0xFF; /* Clear all */
obj->membase->IRQ_CLEAR = SPI_BYTE_MASK; /* Clear all */
/* configure slave select */
obj->membase->SLAVE_SELECT.BITS.SS_ENABLE = False;
obj->membase->SLAVE_SELECT.BITS.SS_BURST = True;
obj->membase->SLAVE_SELECT.WORD = SPI_SLAVE_SELECT_DEFAULT;
obj->membase->SLAVE_SELECT_POLARITY = False;
/* set control register parameters */
obj->membase->CONTROL.BITS.WORD_WIDTH = False; /* 8 bits */
obj->membase->CONTROL.BITS.MODE = 1; /* master */
obj->membase->CONTROL.BITS.CPOL = 0; /* CPOL = 0, Idle low */
obj->membase->CONTROL.BITS.CPHA = 0; /* CPHA = 0, First transmit occurs before first edge of SCLK*/
obj->membase->CONTROL.BITS.ENDIAN = 0; /* Little endian */
obj->membase->CONTROL.BITS.SAMPLING_EDGE = False; /* Sample incoming data on opposite edge of SCLK from when outgoing data is driven */
/* SPI1REG->SLAVE_SELECT.BITS.SS_ENABLE = 0; Slave select TODO do we need? */
/* enable the spi port */
obj->membase->CONTROL.BITS.ENABLE = True;
/* Configure control register parameters: 8 bits, master, CPOL = 0, Idle low. CPHA = 0, First transmit occurs before first edge of SCLK. MSB first. Sample incoming data on opposite edge of SCLK from when outgoing data is driven. enable the spi port */
obj->membase->CONTROL.WORD = SPI_DEFAULT_CONFIG;
}
/** Close a spi device.
@ -161,10 +160,10 @@ int fSpiWriteB(spi_t *obj, uint32_t const buf)
{
int byte;
while((obj->membase->STATUS.BITS.TX_FULL == 1) && (obj->membase->STATUS.BITS.RX_FULL == 1)); /* Wait till Tx/Rx status is full */
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 = buf;
while (obj->membase->STATUS.BITS.RX_EMPTY == 1); /* Wait till Receive status is empty */
while (obj->membase->STATUS.BITS.RX_EMPTY == True); /* Wait till Receive status is empty */
byte = obj->membase->RX_DATA;
return byte;
}

View File

@ -68,7 +68,7 @@ typedef struct _gpio_t {
* with the sleep API implementation
*/
typedef struct sleep_s {
uint32_t timeToSleep; /* 0: Use sleep type variable; Noz-zero: Selects sleep type based on duration using table 1. sleep below */
uint32_t timeToSleep; /* 0: Use sleep type variable to select low power mode; Noz-zero: Selects sleep type based on timeToSleep duration using table 1. sleep below */
uint8_t SleepType; /* 0: Sleep; 1: DeepSleep; 2: Coma */
} sleep_t;

View File

@ -76,24 +76,6 @@ typedef struct {
__IO uint32_t WORD;
} STATUS; /* 0x4001D004 */
#ifdef REVB
__IO uint32_t RAMBIAS;
__IO uint32_t RETAINA_T; /**< RAM retain make/break time. This is clocked using FCLK, so its range & resolution are determined by the FCLK divider register in the Clock Control Section. */
__IO uint32_t RETAINB_T; /**< RAM retain make/break time. This is clocked using FCLK, so its range & resolution are determined by the FCLK divider register in the Clock Control Section. */
__IO uint32_t FVDD_TSTARTUP; /**< Regulator start time. */
__IO uint32_t FVDD_TSETTLE; /**< Regulator settle time. */
union {
struct {
__IO uint32_t TH:6; /**< Threshold */
__I uint32_t PAD:2;
__I uint32_t UVIVAL; /**< UVI value */
} BITS;
__IO uint32_t WORD;
} UVI_TBASE;
__IO uint32_t UVI_LIM;
#endif /* REVB */
#ifdef REVD
__IO uint32_t PLACEHOLDER; /* 0x4001D008 */
__IO uint32_t FVDD_TSTARTUP; /**< Regulator start time. */ /* 0x4001D00C */
__IO uint32_t PLACEHOLDER1; /* 0x4001D010 */
@ -107,7 +89,7 @@ typedef struct {
__IO uint32_t WORD;
} UVI_TBASE; /* 0x4001D018 */
__IO uint32_t SRAM_TRIM; /* 0x4001D01C */
#endif /* REVD */
} PmuReg_t, *PmuReg_pt;
#endif /* PMU_MAP_H_ */

View File

@ -79,7 +79,7 @@ void fRtcInit(void)
NVIC_ClearPendingIRQ(Rtc_IRQn);
NVIC_EnableIRQ(Rtc_IRQn);
while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/
while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/
return;
}
@ -93,7 +93,7 @@ void fRtcFree(void)
/* disable interruption associated with the rtc */
NVIC_DisableIRQ(Rtc_IRQn);
while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/
while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/
}
/* See rtc.h for details */
@ -122,7 +122,7 @@ void fRtcSetInterrupt(uint32_t timestamp)
}
volatile uint64_t Temp = (timestamp / DividerAdjust * RTC_CLOCK_HZ);
timestamp = (uint64_t)(Temp / RTC_SEC_TO_US * DividerAdjust);
Temp = (uint64_t)(Temp / RTC_SEC_TO_US * DividerAdjust);
SubSecond = Temp & RTC_SUB_SEC_MASK;
if(SubSecond <= 5) {
@ -137,6 +137,7 @@ void fRtcSetInterrupt(uint32_t timestamp)
RTCREG->SUB_SECOND_ALARM = SubSecond; /* Write to sub second alarm */
/* Enable sub second interrupt */
while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True);
RTCREG->CONTROL.WORD |= (True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS);
}
}
@ -151,7 +152,7 @@ void fRtcDisableInterrupt(void)
{
/* Disable subsec/sec interrupt */
RTCREG->CONTROL.WORD &= ~((RTC_ALL_INTERRUPT_BIT_VAL) << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS);
while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/
while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/
}
/* See rtc.h for details */
@ -159,7 +160,7 @@ void fRtcEnableInterrupt(void)
{
/* Disable subsec/sec interrupt */
RTCREG->CONTROL.WORD |= ((RTC_ALL_INTERRUPT_BIT_VAL) << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS);
while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/
while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/
}
/* See rtc.h for details */
@ -240,36 +241,38 @@ void fRtcHandler(void)
/* SUB_SECOND/SECOND interrupt occured */
volatile uint32_t TempStatus = RTCREG->STATUS.WORD;
/* disable all interrupts */
RTCREG->CONTROL.WORD &= ~((RTC_ALL_INTERRUPT_BIT_VAL) << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS);
/* Disable RTC interrupt */
NVIC_DisableIRQ(Rtc_IRQn);
/* Clear sec & sub_sec interrupts */
RTCREG->INT_CLEAR.WORD = ((True << RTC_INT_CLR_SUB_SEC_BIT_POS) |
(True << RTC_INT_CLR_SEC_BIT_POS));
/* TODO ANDing SUB_SEC & SEC interrupt - work around for RTC issue - will be solved in REV G */
/* TODO ANDing SUB_SEC & SEC interrupt - work around for RTC issue - will be resolved in REV G */
if(TempStatus & RTC_SEC_INT_STATUS_MASK) {
/* Second interrupt occured */
if(SubSecond > False) {
/* Set SUB SEC_ALARM */
RTCREG->SUB_SECOND_ALARM = SubSecond + RTCREG->SUB_SECOND_COUNTER;
/* Enable sub second interrupt */
while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True);
RTCREG->CONTROL.WORD |= (True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS);
} else {
/* We reach here after second interrupt is occured */
while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True);
RTCREG->CONTROL.WORD &= ~(True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS) |
(True << RTC_CONTROL_SEC_CNT_INT_BIT_POS);
}
} else {
/* We reach here after sub_second or (Sub second + second) interrupt occured */
while(RTCREG->STATUS.BITS.BSY_CTRL_REG_WRT == True);
/* Disable Second and sub_second interrupt */
RTCREG->CONTROL.WORD &= ~(True << RTC_CONTROL_SUBSEC_CNT_INT_BIT_POS) |
(True << RTC_CONTROL_SEC_CNT_INT_BIT_POS);
}
NVIC_EnableIRQ(Rtc_IRQn);
while(RTCREG->STATUS.BITS.BSY_ANY_WRT == True); /* Wait for RTC to finish writing register - RTC operates on 32K clock as compared to 32M core*/
lp_ticker_irq_handler();
}
boolean fIsRtcEnabled(void)

View File

@ -47,13 +47,13 @@
#define SLEEP_TYPE_DEEPSLEEP 2
#define SLEEP_TYPE_COMA 3
#define SLEEP_TYPE_DEFAULT SLEEP_TYPE_DEEPSLEEP
#define SLEEP_DURATION_SLEEP_MIN 10 /* msec */
#define SLEEP_DURATION_SLEEP_MAX 200 /* msec */
#define SLEEP_DURATION_DEEPSLEEP_MAX 500 /* msec */
#define SLEEP_DURATION_COMA_MAX 1000000000 /* TODO 1000 sec */
void sleep(void);
void deepsleep(void);
void coma(void);
#endif // SLEEP_H_

View File

@ -39,11 +39,52 @@
void mbed_enter_sleep(sleep_t *obj)
{
/* Empty implementation, this will be implemented for mbed5.0 */
#ifdef SLEEP_TYPE_DEFAULT
if(SLEEP_TYPE_DEFAULT == SLEEP_TYPE_SLEEP) {
/* Sleep mode */
sleep();
} else if(SLEEP_TYPE_DEFAULT == SLEEP_TYPE_DEEPSLEEP) {
/* Deep Sleep mode */
deepsleep();
} else {
/* Coma mode */
coma();
}
#else
if(obj->SleepType == SLEEP_TYPE_NONE) {
/* Select low power mode based on sleep duration */
if(obj->timeToSleep <= SLEEP_DURATION_SLEEP_MAX) {
/* Sleep mode */
sleep();
} else if(obj->timeToSleep <= SLEEP_DURATION_DEEPSLEEP_MAX) {
/* Deep sleep */
deepsleep();
} else {
/* Coma */
coma();
}
} else if(obj->SleepType == SLEEP_TYPE_SLEEP) {
/* Sleep mode */
sleep();
} else if(obj->SleepType == SLEEP_TYPE_DEEPSLEEP) {
/* Deep Sleep mode */
deepsleep();
} else {
/* Coma mode */
coma();
}
#endif
}
void mbed_exit_sleep(sleep_t *obj)
{
(void)obj;
}
#endif /* DEVICE_SLEEP */

View File

@ -46,6 +46,32 @@ extern "C" {
#define SPI_IPC7207_IOCTL_SET_SLAVE_SELECT (0x2) /**< <b>Ioctl request code</b>: Setting slaveSelect register */
#define SPI_IPC7207_IOCTL_FLUSH (0x3) /**< <b>Ioctl request code</b>: Flushin FIFOs and serial shift registers */
/* Control register bit positions */
#define SPI_WORD_WIDTH_BIT_POS 6
#define SPI_SLAVE_MASTER_BIT_POS 5
#define SPI_CPOL_BIT_POS 4
#define SPI_CPHA_BIT_POS 3
#define SPI_ENDIAN_BIT_POS 2
#define SPI_SAMPLE_EDGE_BIT_POS 1
#define SPI_PORT_ENABLE_BIT_POS 0
/* COntrol register bits */
#define SPI_ENDIAN_MSB_FIRST 1
#define SPI_CPOL_IDLE_LOW 0
#define SPI_CPHA_BEFORE_1ST_EDGE 0
#define SPI_MASTER_MODE 1
#define SPI_WORD_WIDTH_8_BITS 0
#define SPI_SAMPLE_OPP_CLK_EDGE_DATA 0
#define SPI_SLAVE_SELECT_NORM_BEHAVE 0
#define SPI_PORT_ENABLE 1
#define SPI_SLAVE_SELECT_DEFAULT 0x10
#define SPI_DEFAULT_CONFIG 0x25
#define SPI_DEFAULT_SPEED 1000000
#define SPI_BYTE_MASK 0xFF
extern void fSpiInit(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel);
extern void fSpiClose(spi_t *obj);
extern int fSpiWriteB(spi_t *obj, uint32_t const buf);

View File

@ -44,9 +44,6 @@
#define SPI_FREQ_MAX 4000000
#define SPI_ENDIAN_LSB_FIRST 0
#define SPI_MASTER_MODE 1
#define SPI_SLAVE_MODE 0
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
@ -59,18 +56,15 @@ void spi_free(spi_t *obj)
void spi_format(spi_t *obj, int bits, int mode, int slave)
{
if(slave) {
/* Slave mode */
obj->membase->CONTROL.BITS.MODE = SPI_SLAVE_MODE;
} else {
/* Master mode */
obj->membase->CONTROL.BITS.MODE = SPI_MASTER_MODE;
}
obj->membase->CONTROL.BITS.WORD_WIDTH = bits >> 0x4; /* word width */
obj->membase->CONTROL.BITS.CPOL = mode >> 0x1; /* CPOL */
obj->membase->CONTROL.BITS.CPHA = mode & 0x1; /* CPHA */
/* 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));
obj->membase->CONTROL.BITS.ENDIAN = SPI_ENDIAN_LSB_FIRST; /* Endian */
/* 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)
@ -103,6 +97,29 @@ uint8_t spi_get_module(spi_t *obj)
}
}
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)

View File

@ -2020,7 +2020,7 @@
"post_binary_hook": {"function": "NCS36510TargetCode.ncs36510_addfib"},
"macros": ["REVD", "CM3", "CPU_NCS36510", "TARGET_NCS36510"],
"supported_toolchains": ["GCC_ARM", "ARM", "IAR"],
"device_has": ["ANALOGIN", "SERIAL", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI"],
"device_has": ["ANALOGIN", "SERIAL", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "LOWPOWERTIMER"],
"release_versions": ["2", "5"]
},
"NUMAKER_PFM_M453": {