mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #1626 from mtkrtk/rz_a1h_async_patch
[Renesas RZ/A1H] Enable asynchronous communicationspull/1697/head
commit
fe9720f24b
|
@ -24,7 +24,7 @@
|
|||
|
||||
#define CTHUNK_ADDRESS 1
|
||||
|
||||
#if defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__thumb2__)
|
||||
#if (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__thumb2__)) && ! defined(__CORTEX_A9)
|
||||
#define CTHUNK_VARIABLES volatile uint32_t code[1]
|
||||
/**
|
||||
* CTHUNK disassembly for Cortex-M3/M4 (thumb2):
|
||||
|
@ -38,7 +38,7 @@
|
|||
*/
|
||||
#define CTHUNK_ASSIGMENT m_thunk.code[0] = 0x8007E89F
|
||||
|
||||
#elif defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0)
|
||||
#elif defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0) || defined(__CORTEX_A9)
|
||||
/*
|
||||
* CTHUNK disassembly for Cortex M0 (thumb):
|
||||
* * push {r0,r1,r2,r3,r4,lr} save touched registers and return address
|
||||
|
@ -194,6 +194,24 @@ class CThunk
|
|||
m_thunk.callback = (uint32_t)&m_callback;
|
||||
m_thunk.trampoline = (uint32_t)&trampoline;
|
||||
|
||||
#if defined(__CORTEX_A9)
|
||||
/* Data cache clean */
|
||||
/* Cache control */
|
||||
{
|
||||
uint32_t start_addr = (uint32_t)&m_thunk & 0xFFFFFFE0;
|
||||
uint32_t end_addr = (uint32_t)&m_thunk + sizeof(m_thunk);
|
||||
uint32_t addr;
|
||||
|
||||
/* Data cache clean and invalid */
|
||||
for (addr = start_addr; addr < end_addr; addr += 0x20) {
|
||||
__v7_clean_inv_dcache_mva((void *)addr);
|
||||
}
|
||||
/* Instruction cache invalid */
|
||||
__v7_inv_icache_all();
|
||||
__ca9u_inv_tlb_all();
|
||||
__v7_inv_btac();
|
||||
}
|
||||
#endif
|
||||
__ISB();
|
||||
__DSB();
|
||||
}
|
||||
|
|
|
@ -124,7 +124,12 @@ int SPI::queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, i
|
|||
if (_transaction_buffer.full()) {
|
||||
return -1; // the buffer is full
|
||||
} else {
|
||||
__disable_irq();
|
||||
_transaction_buffer.push(transaction);
|
||||
if (!spi_active(&_spi)) {
|
||||
dequeue_transaction();
|
||||
}
|
||||
__enable_irq();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -754,11 +754,12 @@ typedef enum IRQn
|
|||
region.outer_norm_t = WB_WA; \
|
||||
region.mem_t = NORMAL; \
|
||||
region.sec_t = NON_SECURE; \
|
||||
region.xn_t = NON_EXECUTE; \
|
||||
region.xn_t = EXECUTE; \
|
||||
region.priv_t = RW; \
|
||||
region.user_t = RW; \
|
||||
region.sh_t = NON_SHARED; \
|
||||
__get_section_descriptor(&descriptor_l1, region);
|
||||
|
||||
//Sect_SO. Strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0
|
||||
#define section_so(descriptor_l1, region) region.rg_t = SECTION; \
|
||||
region.domain = 0x0; \
|
||||
|
@ -788,7 +789,7 @@ typedef enum IRQn
|
|||
region.user_t = READ; \
|
||||
region.sh_t = NON_SHARED; \
|
||||
__get_section_descriptor(&descriptor_l1, region);
|
||||
|
||||
|
||||
//Sect_Device_RW. Sect_Device_RO, but writeable
|
||||
#define section_device_rw(descriptor_l1, region) region.rg_t = SECTION; \
|
||||
region.domain = 0x0; \
|
||||
|
@ -832,6 +833,7 @@ typedef enum IRQn
|
|||
region.user_t = RW; \
|
||||
region.sh_t = NON_SHARED; \
|
||||
__get_page_descriptor(&descriptor_l1, &descriptor_l2, region);
|
||||
|
||||
|
||||
/*@}*/ /* end of group Renesas_RZ_A1_MemoryMap */
|
||||
|
||||
|
|
|
@ -24,45 +24,50 @@
|
|||
#endif
|
||||
/* <-Take measures about optimization problems of web compiler */
|
||||
|
||||
#define DEVICE_PORTIN 1
|
||||
#define DEVICE_PORTOUT 1
|
||||
#define DEVICE_PORTINOUT 1
|
||||
#define DEVICE_PORTIN 1
|
||||
#define DEVICE_PORTOUT 1
|
||||
#define DEVICE_PORTINOUT 1
|
||||
|
||||
#define DEVICE_INTERRUPTIN 1
|
||||
#define DEVICE_INTERRUPTIN 1
|
||||
|
||||
#define DEVICE_ANALOGIN 1
|
||||
#define DEVICE_ANALOGOUT 0
|
||||
#define DEVICE_ANALOGIN 1
|
||||
#define DEVICE_ANALOGOUT 0
|
||||
|
||||
#define DEVICE_SERIAL 1
|
||||
#define DEVICE_SERIAL_FC 1
|
||||
#define DEVICE_SERIAL 1
|
||||
#define DEVICE_SERIAL_FC 1
|
||||
#define DEVICE_SERIAL_ASYNCH 1
|
||||
|
||||
#define DEVICE_I2C 1
|
||||
#define DEVICE_I2CSLAVE 1
|
||||
#define DEVICE_I2C 1
|
||||
#define DEVICE_I2CSLAVE 1
|
||||
#define DEVICE_I2C_ASYNCH 1
|
||||
|
||||
#define DEVICE_SPI 1
|
||||
#define DEVICE_SPISLAVE 1
|
||||
#define DEVICE_SPI 1
|
||||
#define DEVICE_SPISLAVE 1
|
||||
#define DEVICE_SPI_ASYNCH 1
|
||||
#define TRANSACTION_QUEUE_SIZE_SPI 16
|
||||
|
||||
#define DEVICE_CAN 1
|
||||
#define DEVICE_CAN 1
|
||||
|
||||
#define DEVICE_RTC 1
|
||||
#define DEVICE_RTC 1
|
||||
|
||||
#define DEVICE_ETHERNET 1
|
||||
#define DEVICE_ETHERNET 1
|
||||
|
||||
#define DEVICE_PWMOUT 1
|
||||
#define DEVICE_PWMOUT 1
|
||||
|
||||
#define DEVICE_SEMIHOST 0
|
||||
#define DEVICE_LOCALFILESYSTEM 0
|
||||
#define DEVICE_ID_LENGTH 32
|
||||
#define DEVICE_MAC_OFFSET 20
|
||||
#define DEVICE_SEMIHOST 0
|
||||
#define DEVICE_LOCALFILESYSTEM 0
|
||||
#define DEVICE_ID_LENGTH 32
|
||||
#define DEVICE_MAC_OFFSET 20
|
||||
|
||||
#define DEVICE_SLEEP 0
|
||||
#define DEVICE_SLEEP 0
|
||||
|
||||
#define DEVICE_DEBUG_AWARENESS 0
|
||||
#define DEVICE_DEBUG_AWARENESS 0
|
||||
|
||||
#define DEVICE_STDIO_MESSAGES 1
|
||||
#define DEVICE_STDIO_MESSAGES 1
|
||||
|
||||
#define DEVICE_ERROR_PATTERN 1
|
||||
#define DEVICE_ERROR_PATTERN 1
|
||||
|
||||
#include "objects.h"
|
||||
#include "dma_api.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "mbed_assert.h"
|
||||
#include "dma_api.h"
|
||||
#include "i2c_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
|
@ -26,7 +27,7 @@
|
|||
volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
|
||||
|
||||
#define REG(N) \
|
||||
RIIC[obj->i2c]->RIICn##N
|
||||
RIIC[obj->i2c.i2c]->RIICn##N
|
||||
|
||||
/* RIICnCR1 */
|
||||
#define CR1_RST (1 << 6)
|
||||
|
@ -74,7 +75,6 @@ static const PinMap PinMap_I2C_SCL[] = {
|
|||
{NC , NC, 0}
|
||||
};
|
||||
|
||||
|
||||
static inline int i2c_status(i2c_t *obj) {
|
||||
return REG(SR2.UINT8[0]);
|
||||
}
|
||||
|
@ -89,9 +89,9 @@ static void i2c_reg_reset(i2c_t *obj) {
|
|||
REG(SER.UINT8[0]) = 0x00; // no slave addr enabled
|
||||
|
||||
/* set frequency */
|
||||
REG(MR1.UINT8[0]) |= obj->pclk_bit;
|
||||
REG(BRL.UINT8[0]) = obj->width_low;
|
||||
REG(BRH.UINT8[0]) = obj->width_hi;
|
||||
REG(MR1.UINT8[0]) |= obj->i2c.pclk_bit;
|
||||
REG(BRL.UINT8[0]) = obj->i2c.width_low;
|
||||
REG(BRH.UINT8[0]) = obj->i2c.width_hi;
|
||||
|
||||
REG(MR2.UINT8[0]) = 0x07;
|
||||
REG(MR3.UINT8[0]) = 0x00;
|
||||
|
@ -205,7 +205,7 @@ static void i2c_set_MR3_ACK(i2c_t *obj) {
|
|||
|
||||
static inline void i2c_power_enable(i2c_t *obj) {
|
||||
volatile uint8_t dummy;
|
||||
switch ((int)obj->i2c) {
|
||||
switch ((int)obj->i2c.i2c) {
|
||||
case I2C_0:
|
||||
CPGSTBCR9 &= ~(0x80);
|
||||
break;
|
||||
|
@ -226,8 +226,8 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
|||
/* determine the I2C to use */
|
||||
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
|
||||
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
|
||||
obj->i2c = pinmap_merge(i2c_sda, i2c_scl);
|
||||
MBED_ASSERT((int)obj->i2c != NC);
|
||||
obj->i2c.i2c = pinmap_merge(i2c_sda, i2c_scl);
|
||||
MBED_ASSERT((int)obj->i2c.i2c != NC);
|
||||
|
||||
/* enable power */
|
||||
i2c_power_enable(obj);
|
||||
|
@ -238,7 +238,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
|||
pinmap_pinout(sda, PinMap_I2C_SDA);
|
||||
pinmap_pinout(scl, PinMap_I2C_SCL);
|
||||
|
||||
obj->last_stop_flag = 1;
|
||||
obj->i2c.last_stop_flag = 1;
|
||||
}
|
||||
|
||||
inline int i2c_start(i2c_t *obj) {
|
||||
|
@ -246,7 +246,7 @@ inline int i2c_start(i2c_t *obj) {
|
|||
|
||||
while ((REG(CR2.UINT32) & CR2_BBSY) != 0) {
|
||||
timeout ++;
|
||||
if (timeout >= obj->bbsy_wait_cnt) {
|
||||
if (timeout >= obj->i2c.bbsy_wait_cnt) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ static void i2c_set_err_noslave(i2c_t *obj) {
|
|||
(void)i2c_set_STOP(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
obj->last_stop_flag = 1;
|
||||
obj->i2c.last_stop_flag = 1;
|
||||
}
|
||||
|
||||
static inline int i2c_do_write(i2c_t *obj, int value) {
|
||||
|
@ -395,16 +395,16 @@ void i2c_frequency(i2c_t *obj, int hz) {
|
|||
wait_utime = (L_time * 2) * 1000000;
|
||||
/* 1 wait of BBSY bit is about 0.3us. if it's below 0.3us, wait count is set as 1. */
|
||||
if (wait_utime <= 0.3) {
|
||||
obj->bbsy_wait_cnt = 1;
|
||||
obj->i2c.bbsy_wait_cnt = 1;
|
||||
} else {
|
||||
obj->bbsy_wait_cnt = (int)(wait_utime / 0.3);
|
||||
obj->i2c.bbsy_wait_cnt = (int)(wait_utime / 0.3);
|
||||
}
|
||||
|
||||
|
||||
/* I2C Rate */
|
||||
obj->pclk_bit = (uint8_t)(0x10 * wk_cks); /* P_phi / xx */
|
||||
obj->width_low = (uint8_t)(tmp_L_width | 0x000000E0);
|
||||
obj->width_hi = (uint8_t)(tmp_H_width | 0x000000E0);
|
||||
obj->i2c.pclk_bit = (uint8_t)(0x10 * wk_cks); /* P_phi / xx */
|
||||
obj->i2c.width_low = (uint8_t)(tmp_L_width | 0x000000E0);
|
||||
obj->i2c.width_hi = (uint8_t)(tmp_H_width | 0x000000E0);
|
||||
|
||||
/* full reset */
|
||||
i2c_reg_reset(obj);
|
||||
|
@ -421,14 +421,14 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
|||
}
|
||||
i2c_set_MR3_ACK(obj);
|
||||
/* There is a STOP condition for last processing */
|
||||
if (obj->last_stop_flag != 0) {
|
||||
if (obj->i2c.last_stop_flag != 0) {
|
||||
status = i2c_start(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
}
|
||||
obj->last_stop_flag = stop;
|
||||
obj->i2c.last_stop_flag = stop;
|
||||
/* Send Slave address */
|
||||
status = i2c_read_address_write(obj, (address | 0x01));
|
||||
if (status != 0) {
|
||||
|
@ -445,7 +445,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
|||
value = REG(DRR.UINT32);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
obj->last_stop_flag = 1;
|
||||
obj->i2c.last_stop_flag = 1;
|
||||
return I2C_ERROR_NO_SLAVE;
|
||||
}
|
||||
/* Read in all except last byte */
|
||||
|
@ -470,7 +470,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
|||
data[count] = (char)value;
|
||||
}
|
||||
} else if (length == 2) {
|
||||
/* Set MR3 WATI bit is 1 */
|
||||
/* Set MR3 WAIT bit is 1 */
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
/* dummy read */
|
||||
value = REG(DRR.UINT32);
|
||||
|
@ -485,7 +485,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
|
|||
count++;
|
||||
} else {
|
||||
/* length == 1 */
|
||||
/* Set MR3 WATI bit is 1 */;
|
||||
/* Set MR3 WAIT bit is 1 */;
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
i2c_set_MR3_NACK(obj);
|
||||
/* dummy read */
|
||||
|
@ -532,14 +532,14 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
|
|||
}
|
||||
|
||||
/* There is a STOP condition for last processing */
|
||||
if (obj->last_stop_flag != 0) {
|
||||
if (obj->i2c.last_stop_flag != 0) {
|
||||
status = i2c_start(obj);
|
||||
if (status != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
return I2C_ERROR_BUS_BUSY;
|
||||
}
|
||||
}
|
||||
obj->last_stop_flag = stop;
|
||||
obj->i2c.last_stop_flag = stop;
|
||||
/* Send Slave address */
|
||||
status = i2c_do_write(obj, address);
|
||||
if (status != 0) {
|
||||
|
@ -749,3 +749,392 @@ int i2c_slave_write(i2c_t *obj, const char *data, int length) {
|
|||
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
|
||||
REG(SAR0.UINT32) = (address & 0xfffffffe);
|
||||
}
|
||||
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
|
||||
#define IRQ_NUM 4
|
||||
#define IRQ_TX 0
|
||||
#define IRQ_RX 1
|
||||
#define IRQ_ERR1 2
|
||||
#define IRQ_ERR2 3
|
||||
|
||||
static void i2c_irqs_set(i2c_t *obj, uint32_t enable);
|
||||
|
||||
static void i2c0_tx_irq(void);
|
||||
static void i2c1_tx_irq(void);
|
||||
static void i2c2_tx_irq(void);
|
||||
static void i2c3_tx_irq(void);
|
||||
static void i2c0_rx_irq(void);
|
||||
static void i2c1_rx_irq(void);
|
||||
static void i2c2_rx_irq(void);
|
||||
static void i2c3_rx_irq(void);
|
||||
static void i2c0_al_irq(void);
|
||||
static void i2c1_al_irq(void);
|
||||
static void i2c2_al_irq(void);
|
||||
static void i2c3_al_irq(void);
|
||||
static void i2c0_to_irq(void);
|
||||
static void i2c1_to_irq(void);
|
||||
static void i2c2_to_irq(void);
|
||||
static void i2c3_to_irq(void);
|
||||
|
||||
static const IRQn_Type irq_set_tbl[RIIC_COUNT][IRQ_NUM] = {
|
||||
{INTIICTEI0_IRQn, INTIICRI0_IRQn, INTIICALI0_IRQn, INTIICTMOI0_IRQn},
|
||||
{INTIICTEI1_IRQn, INTIICRI1_IRQn, INTIICALI1_IRQn, INTIICTMOI1_IRQn},
|
||||
{INTIICTEI2_IRQn, INTIICRI2_IRQn, INTIICALI2_IRQn, INTIICTMOI2_IRQn},
|
||||
{INTIICTEI3_IRQn, INTIICRI3_IRQn, INTIICALI3_IRQn, INTIICTMOI3_IRQn},
|
||||
};
|
||||
|
||||
static const IRQHandler hander_set_tbl[RIIC_COUNT][IRQ_NUM] = {
|
||||
{i2c0_tx_irq, i2c0_rx_irq, i2c0_al_irq, i2c0_to_irq},
|
||||
{i2c1_tx_irq, i2c1_rx_irq, i2c1_al_irq, i2c1_to_irq},
|
||||
{i2c2_tx_irq, i2c2_rx_irq, i2c2_al_irq, i2c2_to_irq},
|
||||
{i2c3_tx_irq, i2c3_rx_irq, i2c3_al_irq, i2c3_to_irq},
|
||||
};
|
||||
|
||||
struct i2c_global_data_s {
|
||||
i2c_t *async_obj;
|
||||
uint32_t async_callback, event, shouldStop, address;
|
||||
};
|
||||
|
||||
static struct i2c_global_data_s i2c_data[RIIC_COUNT];
|
||||
|
||||
static void i2c_transfer_finished(i2c_t *obj)
|
||||
{
|
||||
i2c_irqs_set(obj, 0);
|
||||
uint32_t index = obj->i2c.i2c;
|
||||
i2c_data[index].event = I2C_EVENT_TRANSFER_COMPLETE;
|
||||
i2c_data[index].async_obj = NULL;
|
||||
((void (*)())i2c_data[index].async_callback)();
|
||||
}
|
||||
|
||||
static void i2c_tx_irq(IRQn_Type irq_num, uint32_t index)
|
||||
{
|
||||
i2c_t *obj = i2c_data[index].async_obj;
|
||||
if ((REG(SR2.UINT32) & SR2_NACKF)) {
|
||||
/* Slave sends NACK */
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK;
|
||||
i2c_abort_asynch(obj);
|
||||
((void (*)())i2c_data[index].async_callback)();
|
||||
return;
|
||||
}
|
||||
if (obj->tx_buff.pos == obj->tx_buff.length) {
|
||||
/* All datas have tranferred */
|
||||
|
||||
/* Clear TEND */
|
||||
REG(SR2.UINT32) &= ~(SR2_TEND);
|
||||
|
||||
/* If not repeated start, send stop. */
|
||||
if (i2c_data[index].shouldStop && obj->rx_buff.length == 0) {
|
||||
(void)i2c_set_STOP(obj);
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
i2c_transfer_finished(obj);
|
||||
} else {
|
||||
(void)i2c_restart(obj);
|
||||
(void)i2c_wait_START(obj);
|
||||
/* SR2.START = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_START;
|
||||
if (obj->rx_buff.length) {
|
||||
/* Ready to read */
|
||||
i2c_set_MR3_ACK(obj);
|
||||
|
||||
/* Disable INTRIICTEI */
|
||||
REG(IER.UINT8[0]) &= ~(1 << 6);
|
||||
|
||||
/* Send Slave address */
|
||||
if (i2c_read_address_write(obj, (i2c_data[index].address | 0x01)) != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
|
||||
i2c_abort_asynch(obj);
|
||||
((void (*)())i2c_data[index].async_callback)();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
i2c_transfer_finished(obj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Send next 1 byte */
|
||||
if (i2c_do_write(obj, *(uint8_t *)obj->tx_buff.buffer) != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
|
||||
i2c_abort_asynch(obj);
|
||||
((void (*)())i2c_data[index].async_callback)();
|
||||
return;
|
||||
}
|
||||
obj->tx_buff.buffer = (uint8_t *)obj->tx_buff.buffer + 1;
|
||||
++obj->tx_buff.pos;
|
||||
}
|
||||
}
|
||||
|
||||
static void i2c_rx_irq(IRQn_Type irq_num, uint32_t index)
|
||||
{
|
||||
i2c_t *obj = i2c_data[index].async_obj;
|
||||
if (obj->rx_buff.pos == SIZE_MAX) {
|
||||
if ((REG(SR2.UINT32) & SR2_NACKF) != 0) {
|
||||
/* Slave sends NACK */
|
||||
(void)i2c_set_STOP(obj);
|
||||
/* dummy read */
|
||||
if (REG(DRR.UINT32)) {}
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
obj->i2c.last_stop_flag = 1;
|
||||
|
||||
i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK;
|
||||
i2c_abort_asynch(obj);
|
||||
((void (*)())i2c_data[index].async_callback)();
|
||||
return;
|
||||
}
|
||||
if (obj->rx_buff.length == 1) {
|
||||
/* length == 1 */
|
||||
/* Set MR3 WAIT bit is 1 */;
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
i2c_set_MR3_NACK(obj);
|
||||
} else if (obj->rx_buff.length == 2) {
|
||||
/* Set MR3 WAIT bit is 1 */
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
}
|
||||
/* dummy read */
|
||||
if (REG(DRR.UINT32)) {}
|
||||
obj->rx_buff.pos = 0;
|
||||
return;
|
||||
}
|
||||
if ((REG(SR2.UINT32) & SR2_NACKF) != 0) {
|
||||
/* Slave sends NACK */
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK;
|
||||
i2c_abort_asynch(obj);
|
||||
((void (*)())i2c_data[index].async_callback)();
|
||||
return;
|
||||
} else {
|
||||
switch (obj->rx_buff.length - obj->rx_buff.pos) {
|
||||
case 1:
|
||||
/* Finished */
|
||||
/* If not repeated start, send stop. */
|
||||
if (i2c_data[index].shouldStop) {
|
||||
(void)i2c_set_STOP(obj);
|
||||
/* RIICnDRR read */
|
||||
*(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF;
|
||||
/* RIICnMR3.WAIT = 0 */
|
||||
REG(MR3.UINT32) &= ~MR3_WAIT;
|
||||
(void)i2c_wait_STOP(obj);
|
||||
i2c_set_SR2_NACKF_STOP(obj);
|
||||
} else {
|
||||
(void)i2c_restart(obj);
|
||||
/* RIICnDRR read */
|
||||
*(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF;
|
||||
/* RIICnMR3.WAIT = 0 */
|
||||
REG(MR3.UINT32) &= ~MR3_WAIT;
|
||||
(void)i2c_wait_START(obj);
|
||||
/* SR2.START = 0 */
|
||||
REG(SR2.UINT32) &= ~SR2_START;
|
||||
}
|
||||
|
||||
i2c_transfer_finished(obj);
|
||||
return;
|
||||
|
||||
case 2:
|
||||
i2c_set_MR3_NACK(obj);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* this time is befor last byte read */
|
||||
/* Set MR3 WAIT bit is 1 */
|
||||
REG(MR3.UINT32) |= MR3_WAIT;
|
||||
break;
|
||||
|
||||
default:
|
||||
i2c_set_MR3_ACK(obj);
|
||||
break;
|
||||
}
|
||||
*(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF;
|
||||
obj->rx_buff.buffer = (uint8_t *)obj->rx_buff.buffer + 1;
|
||||
++obj->rx_buff.pos;
|
||||
}
|
||||
}
|
||||
|
||||
static void i2c_err_irq(IRQn_Type irq_num, uint32_t index)
|
||||
{
|
||||
i2c_t *obj = i2c_data[index].async_obj;
|
||||
i2c_abort_asynch(obj);
|
||||
i2c_data[index].event = I2C_EVENT_ERROR;
|
||||
((void (*)())i2c_data[index].async_callback)();
|
||||
}
|
||||
|
||||
/* TX handler */
|
||||
static void i2c0_tx_irq(void)
|
||||
{
|
||||
i2c_tx_irq(INTIICTEI0_IRQn, 0);
|
||||
}
|
||||
|
||||
static void i2c1_tx_irq(void)
|
||||
{
|
||||
i2c_tx_irq(INTIICTEI1_IRQn, 1);
|
||||
}
|
||||
|
||||
static void i2c2_tx_irq(void)
|
||||
{
|
||||
i2c_tx_irq(INTIICTEI2_IRQn, 2);
|
||||
}
|
||||
|
||||
static void i2c3_tx_irq(void)
|
||||
{
|
||||
i2c_tx_irq(INTIICTEI3_IRQn, 3);
|
||||
}
|
||||
|
||||
/* RX handler */
|
||||
static void i2c0_rx_irq(void)
|
||||
{
|
||||
i2c_rx_irq(INTIICRI0_IRQn, 0);
|
||||
}
|
||||
|
||||
static void i2c1_rx_irq(void)
|
||||
{
|
||||
i2c_rx_irq(INTIICRI1_IRQn, 1);
|
||||
}
|
||||
|
||||
static void i2c2_rx_irq(void)
|
||||
{
|
||||
i2c_rx_irq(INTIICRI2_IRQn, 2);
|
||||
}
|
||||
|
||||
static void i2c3_rx_irq(void)
|
||||
{
|
||||
i2c_rx_irq(INTIICRI3_IRQn, 3);
|
||||
}
|
||||
|
||||
/* Arbitration Lost handler */
|
||||
static void i2c0_al_irq(void)
|
||||
{
|
||||
i2c_err_irq(INTIICALI0_IRQn, 0);
|
||||
}
|
||||
|
||||
static void i2c1_al_irq(void)
|
||||
{
|
||||
i2c_err_irq(INTIICALI1_IRQn, 1);
|
||||
}
|
||||
|
||||
static void i2c2_al_irq(void)
|
||||
{
|
||||
i2c_err_irq(INTIICALI2_IRQn, 2);
|
||||
}
|
||||
|
||||
static void i2c3_al_irq(void)
|
||||
{
|
||||
i2c_err_irq(INTIICALI3_IRQn, 3);
|
||||
}
|
||||
|
||||
/* Timeout handler */
|
||||
static void i2c0_to_irq(void)
|
||||
{
|
||||
i2c_err_irq(INTIICTMOI0_IRQn, 0);
|
||||
}
|
||||
|
||||
static void i2c1_to_irq(void)
|
||||
{
|
||||
i2c_err_irq(INTIICTMOI1_IRQn, 1);
|
||||
}
|
||||
|
||||
static void i2c2_to_irq(void)
|
||||
{
|
||||
i2c_err_irq(INTIICTMOI2_IRQn, 2);
|
||||
}
|
||||
|
||||
static void i2c3_to_irq(void)
|
||||
{
|
||||
i2c_err_irq(INTIICTMOI3_IRQn, 3);
|
||||
}
|
||||
|
||||
static void i2c_irqs_set(i2c_t *obj, uint32_t enable)
|
||||
{
|
||||
int i;
|
||||
const IRQn_Type *irqTable = irq_set_tbl[obj->i2c.i2c];
|
||||
const IRQHandler *handlerTable = hander_set_tbl[obj->i2c.i2c];
|
||||
for (i = 0; i < IRQ_NUM; ++i) {
|
||||
if (enable) {
|
||||
InterruptHandlerRegister(irqTable[i], handlerTable[i]);
|
||||
GIC_SetPriority(irqTable[i], 5);
|
||||
GIC_EnableIRQ(irqTable[i]);
|
||||
} else {
|
||||
GIC_DisableIRQ(irqTable[i]);
|
||||
}
|
||||
}
|
||||
REG(IER.UINT8[0]) = enable ? 0x63 : 0x00;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ASYNCHRONOUS HAL
|
||||
******************************************************************************/
|
||||
|
||||
void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint)
|
||||
{
|
||||
MBED_ASSERT(obj);
|
||||
MBED_ASSERT(tx ? tx_length : 1);
|
||||
MBED_ASSERT(rx ? rx_length : 1);
|
||||
MBED_ASSERT((REG(SER.UINT32) & SER_SAR0E) == 0); /* Slave mode */
|
||||
|
||||
obj->tx_buff.buffer = (void *)tx;
|
||||
obj->tx_buff.length = tx_length;
|
||||
obj->tx_buff.pos = 0;
|
||||
obj->tx_buff.width = 8;
|
||||
obj->rx_buff.buffer = rx;
|
||||
obj->rx_buff.length = rx_length;
|
||||
obj->rx_buff.pos = SIZE_MAX;
|
||||
obj->rx_buff.width = 8;
|
||||
i2c_data[obj->i2c.i2c].async_obj = obj;
|
||||
i2c_data[obj->i2c.i2c].async_callback = handler;
|
||||
i2c_data[obj->i2c.i2c].event = 0;
|
||||
i2c_data[obj->i2c.i2c].shouldStop = stop;
|
||||
i2c_data[obj->i2c.i2c].address = address;
|
||||
i2c_irqs_set(obj, 1);
|
||||
|
||||
/* There is a STOP condition for last processing */
|
||||
if (obj->i2c.last_stop_flag != 0) {
|
||||
if (i2c_start(obj) != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_data[obj->i2c.i2c].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
|
||||
i2c_abort_asynch(obj);
|
||||
((void (*)())handler)();
|
||||
return;
|
||||
}
|
||||
}
|
||||
obj->i2c.last_stop_flag = stop;
|
||||
|
||||
if (rx_length && tx_length == 0) {
|
||||
/* Ready to read */
|
||||
i2c_set_MR3_ACK(obj);
|
||||
|
||||
/* Disable INTRIICTEI */
|
||||
REG(IER.UINT8[0]) &= ~(1 << 6);
|
||||
|
||||
address |= 0x01;
|
||||
}
|
||||
/* Send Slave address */
|
||||
if (i2c_do_write(obj, address) != 0) {
|
||||
i2c_set_err_noslave(obj);
|
||||
i2c_data[obj->i2c.i2c].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
|
||||
i2c_abort_asynch(obj);
|
||||
((void (*)())handler)();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t i2c_irq_handler_asynch(i2c_t *obj)
|
||||
{
|
||||
return i2c_data[obj->i2c.i2c].event;
|
||||
}
|
||||
|
||||
uint8_t i2c_active(i2c_t *obj)
|
||||
{
|
||||
return i2c_data[obj->i2c.i2c].async_obj != NULL;
|
||||
}
|
||||
|
||||
void i2c_abort_asynch(i2c_t *obj)
|
||||
{
|
||||
i2c_data[obj->i2c.i2c].async_obj = NULL;
|
||||
i2c_irqs_set(obj, 0);
|
||||
i2c_reg_reset(obj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,7 @@ struct i2c_s {
|
|||
struct spi_s {
|
||||
struct st_rspi *spi;
|
||||
uint32_t bits;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct gpio_irq_s {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#define PCLK (66666666) // Define the peripheral clock P1 frequency.
|
||||
|
||||
#define UART_NUM 8
|
||||
#define IRQ_NUM 2
|
||||
#define IRQ_NUM 4
|
||||
|
||||
static void uart0_tx_irq(void);
|
||||
static void uart1_tx_irq(void);
|
||||
|
@ -51,7 +51,18 @@ static void uart4_rx_irq(void);
|
|||
static void uart5_rx_irq(void);
|
||||
static void uart6_rx_irq(void);
|
||||
static void uart7_rx_irq(void);
|
||||
static void uart0_er_irq(void);
|
||||
static void uart1_er_irq(void);
|
||||
static void uart2_er_irq(void);
|
||||
static void uart3_er_irq(void);
|
||||
static void uart4_er_irq(void);
|
||||
static void uart5_er_irq(void);
|
||||
static void uart6_er_irq(void);
|
||||
static void uart7_er_irq(void);
|
||||
|
||||
static void serial_put_done(serial_t *obj);
|
||||
static uint8_t serial_available_buffer(serial_t *obj);
|
||||
static void serial_irq_err_set(serial_t *obj, uint32_t enable);
|
||||
|
||||
static const PinMap PinMap_UART_TX[] = {
|
||||
{P2_14 , UART0, 6},
|
||||
|
@ -115,31 +126,34 @@ serial_t stdio_uart;
|
|||
struct serial_global_data_s {
|
||||
uint32_t serial_irq_id;
|
||||
gpio_t sw_rts, sw_cts;
|
||||
uint8_t count, rx_irq_set_flow, rx_irq_set_api;
|
||||
uint8_t rx_irq_set_flow, rx_irq_set_api;
|
||||
serial_t *tranferring_obj, *receiving_obj;
|
||||
uint32_t async_tx_callback, async_rx_callback;
|
||||
int event, wanted_rx_events;
|
||||
};
|
||||
|
||||
static struct serial_global_data_s uart_data[UART_NUM];
|
||||
|
||||
static const IRQn_Type irq_set_tbl[UART_NUM][IRQ_NUM] = {
|
||||
{SCIFRXI0_IRQn, SCIFTXI0_IRQn},
|
||||
{SCIFRXI1_IRQn, SCIFTXI1_IRQn},
|
||||
{SCIFRXI2_IRQn, SCIFTXI2_IRQn},
|
||||
{SCIFRXI3_IRQn, SCIFTXI3_IRQn},
|
||||
{SCIFRXI4_IRQn, SCIFTXI4_IRQn},
|
||||
{SCIFRXI5_IRQn, SCIFTXI5_IRQn},
|
||||
{SCIFRXI6_IRQn, SCIFTXI6_IRQn},
|
||||
{SCIFRXI7_IRQn, SCIFTXI7_IRQn}
|
||||
{SCIFRXI0_IRQn, SCIFTXI0_IRQn, SCIFBRI0_IRQn, SCIFERI0_IRQn},
|
||||
{SCIFRXI1_IRQn, SCIFTXI1_IRQn, SCIFBRI1_IRQn, SCIFERI1_IRQn},
|
||||
{SCIFRXI2_IRQn, SCIFTXI2_IRQn, SCIFBRI2_IRQn, SCIFERI2_IRQn},
|
||||
{SCIFRXI3_IRQn, SCIFTXI3_IRQn, SCIFBRI3_IRQn, SCIFERI3_IRQn},
|
||||
{SCIFRXI4_IRQn, SCIFTXI4_IRQn, SCIFBRI4_IRQn, SCIFERI4_IRQn},
|
||||
{SCIFRXI5_IRQn, SCIFTXI5_IRQn, SCIFBRI5_IRQn, SCIFERI5_IRQn},
|
||||
{SCIFRXI6_IRQn, SCIFTXI6_IRQn, SCIFBRI6_IRQn, SCIFERI6_IRQn},
|
||||
{SCIFRXI7_IRQn, SCIFTXI7_IRQn, SCIFBRI7_IRQn, SCIFERI7_IRQn}
|
||||
};
|
||||
|
||||
static const IRQHandler hander_set_tbl[UART_NUM][IRQ_NUM] = {
|
||||
{uart0_rx_irq, uart0_tx_irq},
|
||||
{uart1_rx_irq, uart1_tx_irq},
|
||||
{uart2_rx_irq, uart2_tx_irq},
|
||||
{uart3_rx_irq, uart3_tx_irq},
|
||||
{uart4_rx_irq, uart4_tx_irq},
|
||||
{uart5_rx_irq, uart5_tx_irq},
|
||||
{uart6_rx_irq, uart6_tx_irq},
|
||||
{uart7_rx_irq, uart7_tx_irq}
|
||||
{uart0_rx_irq, uart0_tx_irq, uart0_er_irq, uart0_er_irq},
|
||||
{uart1_rx_irq, uart1_tx_irq, uart1_er_irq, uart1_er_irq},
|
||||
{uart2_rx_irq, uart2_tx_irq, uart2_er_irq, uart2_er_irq},
|
||||
{uart3_rx_irq, uart3_tx_irq, uart3_er_irq, uart3_er_irq},
|
||||
{uart4_rx_irq, uart4_tx_irq, uart4_er_irq, uart4_er_irq},
|
||||
{uart5_rx_irq, uart5_tx_irq, uart5_er_irq, uart5_er_irq},
|
||||
{uart6_rx_irq, uart6_tx_irq, uart6_er_irq, uart6_er_irq},
|
||||
{uart7_rx_irq, uart7_tx_irq, uart7_er_irq, uart7_er_irq}
|
||||
};
|
||||
|
||||
static __IO uint16_t *SCSCR_MATCH[] = {
|
||||
|
@ -175,7 +189,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
|
||||
MBED_ASSERT((int)uart != NC);
|
||||
|
||||
obj->uart = (struct st_scif *)SCIF[uart];
|
||||
obj->serial.uart = (struct st_scif *)SCIF[uart];
|
||||
// enable power
|
||||
switch (uart) {
|
||||
case UART0:
|
||||
|
@ -208,42 +222,42 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
/* ==== SCIF initial setting ==== */
|
||||
/* ---- Serial control register (SCSCR) setting ---- */
|
||||
/* B'00 : Internal CLK */
|
||||
obj->uart->SCSCR = 0x0000u; /* SCIF transmitting and receiving operations stop */
|
||||
obj->serial.uart->SCSCR = 0x0000u; /* SCIF transmitting and receiving operations stop */
|
||||
|
||||
/* ---- FIFO control register (SCFCR) setting ---- */
|
||||
/* Transmit FIFO reset & Receive FIFO data register reset */
|
||||
obj->uart->SCFCR = 0x0006;
|
||||
obj->serial.uart->SCFCR = 0x0006;
|
||||
|
||||
/* ---- Serial status register (SCFSR) setting ---- */
|
||||
dummy = obj->uart->SCFSR;
|
||||
obj->uart->SCFSR = (dummy & 0xFF6Cu); /* ER,BRK,DR bit clear */
|
||||
dummy = obj->serial.uart->SCFSR;
|
||||
obj->serial.uart->SCFSR = (dummy & 0xFF6Cu); /* ER,BRK,DR bit clear */
|
||||
|
||||
/* ---- Line status register (SCLSR) setting ---- */
|
||||
/* ORER bit clear */
|
||||
obj->uart->SCLSR = 0;
|
||||
obj->serial.uart->SCLSR = 0;
|
||||
|
||||
/* ---- Serial extension mode register (SCEMR) setting ----
|
||||
b7 BGDM - Baud rate generator double-speed mode : Normal mode
|
||||
b0 ABCS - Base clock select in asynchronous mode : Base clock is 16 times the bit rate */
|
||||
obj->uart->SCEMR = 0x0000u;
|
||||
obj->serial.uart->SCEMR = 0x0000u;
|
||||
|
||||
/* ---- Bit rate register (SCBRR) setting ---- */
|
||||
serial_baud (obj, 9600);
|
||||
serial_format(obj, 8, ParityNone, 1);
|
||||
|
||||
/* ---- FIFO control register (SCFCR) setting ---- */
|
||||
obj->uart->SCFCR = 0x0030u;
|
||||
obj->serial.uart->SCFCR = 0x0030u;
|
||||
|
||||
/* ---- Serial port register (SCSPTR) setting ----
|
||||
b1 SPB2IO - Serial port break output : disabled
|
||||
b0 SPB2DT - Serial port break data : High-level */
|
||||
obj->uart->SCSPTR = 0x0003u; // SPB2IO = 1, SPB2DT = 1
|
||||
obj->serial.uart->SCSPTR = 0x0003u; // SPB2IO = 1, SPB2DT = 1
|
||||
|
||||
/* ---- Line status register (SCLSR) setting ----
|
||||
b0 ORER - Overrun error detect : clear */
|
||||
|
||||
if (obj->uart->SCLSR & 0x0001) {
|
||||
obj->uart->SCLSR = 0u; // ORER clear
|
||||
if (obj->serial.uart->SCLSR & 0x0001) {
|
||||
obj->serial.uart->SCLSR = 0u; // ORER clear
|
||||
}
|
||||
|
||||
// pinout the chosen uart
|
||||
|
@ -252,36 +266,36 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
|
||||
switch (uart) {
|
||||
case UART0:
|
||||
obj->index = 0;
|
||||
obj->serial.index = 0;
|
||||
break;
|
||||
case UART1:
|
||||
obj->index = 1;
|
||||
obj->serial.index = 1;
|
||||
break;
|
||||
case UART2:
|
||||
obj->index = 2;
|
||||
obj->serial.index = 2;
|
||||
break;
|
||||
case UART3:
|
||||
obj->index = 3;
|
||||
obj->serial.index = 3;
|
||||
break;
|
||||
case UART4:
|
||||
obj->index = 4;
|
||||
obj->serial.index = 4;
|
||||
break;
|
||||
case UART5:
|
||||
obj->index = 5;
|
||||
obj->serial.index = 5;
|
||||
break;
|
||||
case UART6:
|
||||
obj->index = 6;
|
||||
obj->serial.index = 6;
|
||||
break;
|
||||
case UART7:
|
||||
obj->index = 7;
|
||||
obj->serial.index = 7;
|
||||
break;
|
||||
}
|
||||
uart_data[obj->index].sw_rts.pin = NC;
|
||||
uart_data[obj->index].sw_cts.pin = NC;
|
||||
uart_data[obj->serial.index].sw_rts.pin = NC;
|
||||
uart_data[obj->serial.index].sw_cts.pin = NC;
|
||||
|
||||
/* ---- Serial control register (SCSCR) setting ---- */
|
||||
/* Setting the TE and RE bits enables the TxD and RxD pins to be used. */
|
||||
obj->uart->SCSCR = 0x00F0;
|
||||
obj->serial.uart->SCSCR = 0x0070;
|
||||
|
||||
is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
|
||||
|
||||
|
@ -292,7 +306,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
|
|||
}
|
||||
|
||||
void serial_free(serial_t *obj) {
|
||||
uart_data[obj->index].serial_irq_id = 0;
|
||||
uart_data[obj->serial.index].serial_irq_id = 0;
|
||||
}
|
||||
|
||||
// serial_baud
|
||||
|
@ -300,49 +314,49 @@ void serial_free(serial_t *obj) {
|
|||
void serial_baud(serial_t *obj, int baudrate) {
|
||||
uint16_t DL;
|
||||
|
||||
obj->uart->SCSMR &= ~0x0003;
|
||||
obj->serial.uart->SCSMR &= ~0x0003;
|
||||
|
||||
if (baudrate > 32552) {
|
||||
obj->uart->SCEMR = 0x0081; // BGDM = 1, ABCS = 1
|
||||
obj->serial.uart->SCEMR = 0x0081; // BGDM = 1, ABCS = 1
|
||||
DL = PCLK / (8 * baudrate);
|
||||
if (DL > 0) {
|
||||
DL--;
|
||||
}
|
||||
obj->uart->SCBRR = (uint8_t)DL;
|
||||
obj->serial.uart->SCBRR = (uint8_t)DL;
|
||||
} else if (baudrate > 16276) {
|
||||
obj->uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->uart->SCBRR = PCLK / (16 * baudrate) - 1;
|
||||
obj->serial.uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->serial.uart->SCBRR = PCLK / (16 * baudrate) - 1;
|
||||
} else if (baudrate > 8138) {
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = PCLK / (32 * baudrate) - 1;
|
||||
obj->serial.uart->SCEMR = 0x0000;
|
||||
obj->serial.uart->SCBRR = PCLK / (32 * baudrate) - 1;
|
||||
} else if (baudrate > 4169) {
|
||||
obj->uart->SCSMR |= 0x0001;
|
||||
obj->uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->uart->SCBRR = PCLK / (64 * baudrate) - 1;
|
||||
obj->serial.uart->SCSMR |= 0x0001;
|
||||
obj->serial.uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->serial.uart->SCBRR = PCLK / (64 * baudrate) - 1;
|
||||
} else if (baudrate > 2034) {
|
||||
obj->uart->SCSMR |= 0x0001;
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = PCLK / (128 * baudrate) - 1;
|
||||
obj->serial.uart->SCSMR |= 0x0001;
|
||||
obj->serial.uart->SCEMR = 0x0000;
|
||||
obj->serial.uart->SCBRR = PCLK / (128 * baudrate) - 1;
|
||||
} else if (baudrate > 1017) {
|
||||
obj->uart->SCSMR |= 0x0002;
|
||||
obj->uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->uart->SCBRR = PCLK / (256 * baudrate) - 1;
|
||||
obj->serial.uart->SCSMR |= 0x0002;
|
||||
obj->serial.uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->serial.uart->SCBRR = PCLK / (256 * baudrate) - 1;
|
||||
} else if (baudrate > 508) {
|
||||
obj->uart->SCSMR |= 0x0002;
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = PCLK / (512 * baudrate) - 1;
|
||||
obj->serial.uart->SCSMR |= 0x0002;
|
||||
obj->serial.uart->SCEMR = 0x0000;
|
||||
obj->serial.uart->SCBRR = PCLK / (512 * baudrate) - 1;
|
||||
} else if (baudrate > 254) {
|
||||
obj->uart->SCSMR |= 0x0003;
|
||||
obj->uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->uart->SCBRR = PCLK / (1024 * baudrate) - 1;
|
||||
obj->serial.uart->SCSMR |= 0x0003;
|
||||
obj->serial.uart->SCEMR = 0x0080; // BGDM = 1
|
||||
obj->serial.uart->SCBRR = PCLK / (1024 * baudrate) - 1;
|
||||
} else if (baudrate > 127) {
|
||||
obj->uart->SCSMR |= 0x0003;
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = PCLK / (2048 * baudrate) - 1;
|
||||
obj->serial.uart->SCSMR |= 0x0003;
|
||||
obj->serial.uart->SCEMR = 0x0000;
|
||||
obj->serial.uart->SCBRR = PCLK / (2048 * baudrate) - 1;
|
||||
} else {
|
||||
obj->uart->SCSMR |= 0x0003;
|
||||
obj->uart->SCEMR = 0x0000;
|
||||
obj->uart->SCBRR = 0xFFu;
|
||||
obj->serial.uart->SCSMR |= 0x0003;
|
||||
obj->serial.uart->SCEMR = 0x0000;
|
||||
obj->serial.uart->SCBRR = 0xFFu;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,7 +398,7 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
break;
|
||||
}
|
||||
|
||||
obj->uart->SCSMR = data_bits << 6
|
||||
obj->serial.uart->SCSMR = data_bits << 6
|
||||
| parity_enable << 5
|
||||
| parity_select << 4
|
||||
| stop_bits << 3;
|
||||
|
@ -397,27 +411,133 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
|
|||
static void uart_tx_irq(IRQn_Type irq_num, uint32_t index) {
|
||||
__IO uint16_t *dmy_rd_scscr;
|
||||
__IO uint16_t *dmy_rd_scfsr;
|
||||
|
||||
serial_t *obj;
|
||||
int i;
|
||||
|
||||
dmy_rd_scscr = SCSCR_MATCH[index];
|
||||
*dmy_rd_scscr &= 0x007B; // Clear TIE and Write to bit15~8,2 is always 0
|
||||
dmy_rd_scfsr = SCFSR_MATCH[index];
|
||||
*dmy_rd_scfsr = (*dmy_rd_scfsr & ~0x0020); // Clear TDFE
|
||||
|
||||
*dmy_rd_scfsr = (*dmy_rd_scfsr & ~0x0020); // Set TEND
|
||||
|
||||
obj = uart_data[index].tranferring_obj;
|
||||
if (obj) {
|
||||
i = obj->tx_buff.length - obj->tx_buff.pos;
|
||||
if (0 < i) {
|
||||
if (serial_available_buffer(obj) < i) {
|
||||
i = serial_available_buffer(obj);
|
||||
}
|
||||
do {
|
||||
uint8_t c = *(uint8_t *)obj->tx_buff.buffer;
|
||||
obj->tx_buff.buffer = (uint8_t *)obj->tx_buff.buffer + 1;
|
||||
++obj->tx_buff.pos;
|
||||
obj->serial.uart->SCFTDR = c;
|
||||
} while (--i);
|
||||
serial_put_done(obj);
|
||||
} else {
|
||||
uart_data[index].tranferring_obj = NULL;
|
||||
uart_data[index].event = SERIAL_EVENT_TX_COMPLETE;
|
||||
((void (*)())uart_data[index].async_tx_callback)();
|
||||
}
|
||||
}
|
||||
|
||||
irq_handler(uart_data[index].serial_irq_id, TxIrq);
|
||||
}
|
||||
|
||||
static void uart_rx_irq(IRQn_Type irq_num, uint32_t index) {
|
||||
__IO uint16_t *dmy_rd_scscr;
|
||||
__IO uint16_t *dmy_rd_scfsr;
|
||||
|
||||
serial_t *obj;
|
||||
int c;
|
||||
|
||||
dmy_rd_scscr = SCSCR_MATCH[index];
|
||||
*dmy_rd_scscr &= 0x00B3; // Clear RIE,REIE and Write to bit15~8,2 is always 0
|
||||
dmy_rd_scfsr = SCFSR_MATCH[index];
|
||||
*dmy_rd_scfsr = (*dmy_rd_scfsr & ~0x0003); // Clear RDF,DR
|
||||
|
||||
|
||||
obj = uart_data[index].receiving_obj;
|
||||
if (obj) {
|
||||
if (obj->serial.uart->SCLSR & 1) {
|
||||
if (uart_data[index].wanted_rx_events & SERIAL_EVENT_RX_OVERRUN_ERROR) {
|
||||
serial_rx_abort_asynch(obj);
|
||||
uart_data[index].event = SERIAL_EVENT_RX_OVERRUN_ERROR;
|
||||
((void (*)())uart_data[index].async_rx_callback)();
|
||||
}
|
||||
return;
|
||||
}
|
||||
c = serial_getc(obj);
|
||||
if (c != -1) {
|
||||
((uint8_t *)obj->rx_buff.buffer)[obj->rx_buff.pos] = c;
|
||||
++obj->rx_buff.pos;
|
||||
if (c == obj->char_match && ! obj->char_found) {
|
||||
obj->char_found = 1;
|
||||
if (obj->rx_buff.pos == obj->rx_buff.length) {
|
||||
if (uart_data[index].wanted_rx_events & SERIAL_EVENT_RX_COMPLETE) {
|
||||
uart_data[index].event = SERIAL_EVENT_RX_COMPLETE;
|
||||
}
|
||||
}
|
||||
if (uart_data[index].wanted_rx_events & SERIAL_EVENT_RX_CHARACTER_MATCH) {
|
||||
uart_data[index].event |= SERIAL_EVENT_RX_CHARACTER_MATCH;
|
||||
}
|
||||
if (uart_data[index].event) {
|
||||
uart_data[index].receiving_obj = NULL;
|
||||
((void (*)())uart_data[index].async_rx_callback)();
|
||||
}
|
||||
} else if (obj->rx_buff.pos == obj->rx_buff.length) {
|
||||
uart_data[index].receiving_obj = NULL;
|
||||
if (uart_data[index].wanted_rx_events & SERIAL_EVENT_RX_COMPLETE) {
|
||||
uart_data[index].event = SERIAL_EVENT_RX_COMPLETE;
|
||||
((void (*)())uart_data[index].async_rx_callback)();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
serial_rx_abort_asynch(obj);
|
||||
if (uart_data[index].wanted_rx_events & (SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR)) {
|
||||
uart_data[index].event = SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR;
|
||||
if (obj->serial.uart->SCFSR & 1 << 2) {
|
||||
uart_data[index].event = SERIAL_EVENT_RX_PARITY_ERROR;
|
||||
} else if (obj->serial.uart->SCFSR & 1 << 3) {
|
||||
uart_data[index].event = SERIAL_EVENT_RX_FRAMING_ERROR;
|
||||
}
|
||||
((void (*)())uart_data[index].async_rx_callback)();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
irq_handler(uart_data[index].serial_irq_id, RxIrq);
|
||||
}
|
||||
|
||||
static void uart_err_irq(IRQn_Type irq_num, uint32_t index) {
|
||||
serial_t *obj = uart_data[index].receiving_obj;
|
||||
int was_masked, err_read;
|
||||
|
||||
if (obj) {
|
||||
serial_irq_err_set(obj, 0);
|
||||
if (uart_data[index].wanted_rx_events & (SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR)) {
|
||||
uart_data[index].event = SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR;
|
||||
if (obj->serial.uart->SCFSR & 1 << 2) {
|
||||
uart_data[index].event = SERIAL_EVENT_RX_PARITY_ERROR;
|
||||
} else if (obj->serial.uart->SCFSR & 1 << 3) {
|
||||
uart_data[index].event = SERIAL_EVENT_RX_FRAMING_ERROR;
|
||||
}
|
||||
((void (*)())uart_data[index].async_rx_callback)();
|
||||
}
|
||||
serial_rx_abort_asynch(obj);
|
||||
|
||||
was_masked = __disable_irq();
|
||||
if (obj->serial.uart->SCFSR & 0x93) {
|
||||
err_read = obj->serial.uart->SCFSR;
|
||||
obj->serial.uart->SCFSR = (err_read & ~0x93);
|
||||
}
|
||||
if (obj->serial.uart->SCLSR & 1) {
|
||||
obj->serial.uart->SCLSR = 0;
|
||||
}
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TX handler */
|
||||
static void uart0_tx_irq(void) {
|
||||
uart_tx_irq(SCIFTXI0_IRQn, 0);
|
||||
|
@ -468,39 +588,83 @@ static void uart6_rx_irq(void) {
|
|||
static void uart7_rx_irq(void) {
|
||||
uart_rx_irq(SCIFRXI7_IRQn, 7);
|
||||
}
|
||||
/* Error handler */
|
||||
static void uart0_er_irq(void)
|
||||
{
|
||||
uart_err_irq(SCIFERI0_IRQn, 0);
|
||||
}
|
||||
static void uart1_er_irq(void)
|
||||
{
|
||||
uart_err_irq(SCIFERI0_IRQn, 1);
|
||||
}
|
||||
static void uart2_er_irq(void)
|
||||
{
|
||||
uart_err_irq(SCIFERI0_IRQn, 2);
|
||||
}
|
||||
static void uart3_er_irq(void)
|
||||
{
|
||||
uart_err_irq(SCIFERI0_IRQn, 3);
|
||||
}
|
||||
static void uart4_er_irq(void)
|
||||
{
|
||||
uart_err_irq(SCIFERI0_IRQn, 4);
|
||||
}
|
||||
static void uart5_er_irq(void)
|
||||
{
|
||||
uart_err_irq(SCIFERI0_IRQn, 5);
|
||||
}
|
||||
static void uart6_er_irq(void)
|
||||
{
|
||||
uart_err_irq(SCIFERI0_IRQn, 6);
|
||||
}
|
||||
static void uart7_er_irq(void)
|
||||
{
|
||||
uart_err_irq(SCIFERI0_IRQn, 7);
|
||||
}
|
||||
|
||||
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
|
||||
irq_handler = handler;
|
||||
uart_data[obj->index].serial_irq_id = id;
|
||||
uart_data[obj->serial.index].serial_irq_id = id;
|
||||
}
|
||||
|
||||
static void serial_irq_set_irq(IRQn_Type IRQn, IRQHandler handler, uint32_t enable)
|
||||
{
|
||||
if (enable) {
|
||||
InterruptHandlerRegister(IRQn, (void (*)(uint32_t))handler);
|
||||
GIC_SetPriority(IRQn, 5);
|
||||
GIC_EnableIRQ(IRQn);
|
||||
} else {
|
||||
GIC_DisableIRQ(IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) {
|
||||
IRQn_Type IRQn;
|
||||
IRQHandler handler;
|
||||
|
||||
IRQn = irq_set_tbl[obj->index][irq];
|
||||
handler = hander_set_tbl[obj->index][irq];
|
||||
IRQn = irq_set_tbl[obj->serial.index][irq];
|
||||
handler = hander_set_tbl[obj->serial.index][irq];
|
||||
|
||||
if ((obj->index >= 0) && (obj->index <= 7)) {
|
||||
if (enable) {
|
||||
InterruptHandlerRegister(IRQn, (void (*)(uint32_t))handler);
|
||||
GIC_SetPriority(IRQn, 5);
|
||||
GIC_EnableIRQ(IRQn);
|
||||
} else {
|
||||
GIC_DisableIRQ(IRQn);
|
||||
}
|
||||
if ((obj->serial.index >= 0) && (obj->serial.index <= 7)) {
|
||||
serial_irq_set_irq(IRQn, handler, enable);
|
||||
}
|
||||
}
|
||||
|
||||
static void serial_irq_err_set(serial_t *obj, uint32_t enable)
|
||||
{
|
||||
serial_irq_set_irq(irq_set_tbl[obj->serial.index][2], hander_set_tbl[obj->serial.index][2], enable);
|
||||
serial_irq_set_irq(irq_set_tbl[obj->serial.index][3], hander_set_tbl[obj->serial.index][3], enable);
|
||||
}
|
||||
|
||||
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
|
||||
if (RxIrq == irq) {
|
||||
uart_data[obj->index].rx_irq_set_api = enable;
|
||||
uart_data[obj->serial.index].rx_irq_set_api = enable;
|
||||
}
|
||||
serial_irq_set_internal(obj, irq, enable);
|
||||
}
|
||||
|
||||
static void serial_flow_irq_set(serial_t *obj, uint32_t enable) {
|
||||
uart_data[obj->index].rx_irq_set_flow = enable;
|
||||
uart_data[obj->serial.index].rx_irq_set_flow = enable;
|
||||
serial_irq_set_internal(obj, RxIrq, enable);
|
||||
}
|
||||
|
||||
|
@ -517,29 +681,29 @@ int serial_getc(serial_t *obj) {
|
|||
#else
|
||||
was_masked = __disable_irq();
|
||||
#endif /* __ICCARM__ */
|
||||
if (obj->uart->SCFSR & 0x93) {
|
||||
err_read = obj->uart->SCFSR;
|
||||
obj->uart->SCFSR = (err_read & ~0x93);
|
||||
if (obj->serial.uart->SCFSR & 0x93) {
|
||||
err_read = obj->serial.uart->SCFSR;
|
||||
obj->serial.uart->SCFSR = (err_read & ~0x93);
|
||||
}
|
||||
obj->uart->SCSCR |= 0x0040; // Set RIE
|
||||
obj->serial.uart->SCSCR |= 0x0040; // Set RIE
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
if (obj->uart->SCLSR & 0x0001) {
|
||||
obj->uart->SCLSR = 0u; // ORER clear
|
||||
if (obj->serial.uart->SCLSR & 0x0001) {
|
||||
obj->serial.uart->SCLSR = 0u; // ORER clear
|
||||
}
|
||||
|
||||
while (!serial_readable(obj));
|
||||
data = obj->uart->SCFRDR & 0xff;
|
||||
data = obj->serial.uart->SCFRDR & 0xff;
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
was_masked = __disable_irq_iar();
|
||||
#else
|
||||
was_masked = __disable_irq();
|
||||
#endif /* __ICCARM__ */
|
||||
err_read = obj->uart->SCFSR;
|
||||
obj->uart->SCFSR = (err_read & 0xfffD); // Clear RDF
|
||||
err_read = obj->serial.uart->SCFSR;
|
||||
obj->serial.uart->SCFSR = (err_read & 0xfffD); // Clear RDF
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
|
@ -551,39 +715,35 @@ int serial_getc(serial_t *obj) {
|
|||
}
|
||||
|
||||
void serial_putc(serial_t *obj, int c) {
|
||||
uint16_t dummy_read;
|
||||
int was_masked;
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
was_masked = __disable_irq_iar();
|
||||
#else
|
||||
was_masked = __disable_irq();
|
||||
#endif /* __ICCARM__ */
|
||||
obj->uart->SCSCR |= 0x0080; // Set TIE
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
while (!serial_writable(obj));
|
||||
obj->uart->SCFTDR = c;
|
||||
obj->serial.uart->SCFTDR = c;
|
||||
serial_put_done(obj);
|
||||
}
|
||||
|
||||
static void serial_put_done(serial_t *obj)
|
||||
{
|
||||
int was_masked;
|
||||
volatile uint16_t dummy_read;
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
was_masked = __disable_irq_iar();
|
||||
#else
|
||||
was_masked = __disable_irq();
|
||||
#endif /* __ICCARM__ */
|
||||
dummy_read = obj->uart->SCFSR;
|
||||
obj->uart->SCFSR = (dummy_read & 0xff9f); // Clear TEND/TDFE
|
||||
dummy_read = obj->serial.uart->SCFSR;
|
||||
obj->serial.uart->SCFSR = (dummy_read & 0xff9f); // Clear TEND/TDFE
|
||||
obj->serial.uart->SCSCR |= 0x0080; // Set TIE
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
uart_data[obj->index].count++;
|
||||
}
|
||||
|
||||
int serial_readable(serial_t *obj) {
|
||||
return ((obj->uart->SCFSR & 0x02) != 0); // RDF
|
||||
return ((obj->serial.uart->SCFSR & 0x02) != 0); // RDF
|
||||
}
|
||||
|
||||
int serial_writable(serial_t *obj) {
|
||||
return ((obj->uart->SCFSR & 0x20) != 0); // TDFE
|
||||
return ((obj->serial.uart->SCFSR & 0x20) != 0); // TDFE
|
||||
}
|
||||
|
||||
void serial_clear(serial_t *obj) {
|
||||
|
@ -594,9 +754,9 @@ void serial_clear(serial_t *obj) {
|
|||
was_masked = __disable_irq();
|
||||
#endif /* __ICCARM__ */
|
||||
|
||||
obj->uart->SCFCR |= 0x06; // TFRST = 1, RFRST = 1
|
||||
obj->uart->SCFCR &= ~0x06; // TFRST = 0, RFRST = 0
|
||||
obj->uart->SCFSR &= ~0x0093u; // ER, BRK, RDF, DR = 0
|
||||
obj->serial.uart->SCFCR |= 0x06; // TFRST = 1, RFRST = 1
|
||||
obj->serial.uart->SCFCR &= ~0x06; // TFRST = 0, RFRST = 0
|
||||
obj->serial.uart->SCFSR &= ~0x0093u; // ER, BRK, RDF, DR = 0
|
||||
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
|
@ -615,8 +775,8 @@ void serial_break_set(serial_t *obj) {
|
|||
was_masked = __disable_irq();
|
||||
#endif /* __ICCARM__ */
|
||||
// TxD Output(L)
|
||||
obj->uart->SCSPTR &= ~0x0001u; // SPB2DT = 0
|
||||
obj->uart->SCSCR &= ~0x0020u; // TE = 0 (Output disable)
|
||||
obj->serial.uart->SCSPTR &= ~0x0001u; // SPB2DT = 0
|
||||
obj->serial.uart->SCSCR &= ~0x0020u; // TE = 0 (Output disable)
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
|
@ -629,8 +789,8 @@ void serial_break_clear(serial_t *obj) {
|
|||
#else
|
||||
was_masked = __disable_irq();
|
||||
#endif /* __ICCARM__ */
|
||||
obj->uart->SCSCR |= 0x0020u; // TE = 1 (Output enable)
|
||||
obj->uart->SCSPTR |= 0x0001u; // SPB2DT = 1
|
||||
obj->serial.uart->SCSCR |= 0x0020u; // TE = 1 (Output enable)
|
||||
obj->serial.uart->SCSPTR |= 0x0001u; // SPB2DT = 1
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
|
@ -648,7 +808,7 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
|
|||
#else
|
||||
was_masked = __disable_irq();
|
||||
#endif /* __ICCARM__ */
|
||||
obj->uart->SCFCR = 0x0008u; // CTS/RTS enable
|
||||
obj->serial.uart->SCFCR = 0x0008u; // CTS/RTS enable
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
|
@ -660,13 +820,118 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
|
|||
#else
|
||||
was_masked = __disable_irq();
|
||||
#endif /* __ICCARM__ */
|
||||
obj->uart->SCFCR = 0x0000u; // CTS/RTS diable
|
||||
obj->serial.uart->SCFCR = 0x0000u; // CTS/RTS diable
|
||||
if (!was_masked) {
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t serial_available_buffer(serial_t *obj)
|
||||
{
|
||||
return 1;
|
||||
/* Faster but unstable way */
|
||||
/*
|
||||
uint16_t ret = 16 - ((obj->serial.uart->SCFDR >> 8) & 0x1F);
|
||||
while (ret == 0) {
|
||||
ret = 16 - ((obj->serial.uart->SCFDR >> 8) & 0x1F);
|
||||
}
|
||||
MBED_ASSERT(0 < ret && ret <= 16);
|
||||
return ret;
|
||||
*/
|
||||
}
|
||||
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
|
||||
/******************************************************************************
|
||||
* ASYNCHRONOUS HAL
|
||||
******************************************************************************/
|
||||
|
||||
int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
|
||||
{
|
||||
int i;
|
||||
buffer_t *buf = &obj->tx_buff;
|
||||
struct serial_global_data_s *data = uart_data + obj->serial.index;
|
||||
|
||||
if (tx_length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf->buffer = (void *)tx;
|
||||
buf->length = tx_length * tx_width / 8;
|
||||
buf->pos = 0;
|
||||
buf->width = tx_width;
|
||||
data->tranferring_obj = obj;
|
||||
data->async_tx_callback = handler;
|
||||
serial_irq_set(obj, TxIrq, 1);
|
||||
|
||||
while (!serial_writable(obj));
|
||||
i = buf->length;
|
||||
if (serial_available_buffer(obj) < i) {
|
||||
i = serial_available_buffer(obj);
|
||||
}
|
||||
do {
|
||||
uint8_t c = *(uint8_t *)buf->buffer;
|
||||
obj->tx_buff.buffer = (uint8_t *)obj->tx_buff.buffer + 1;
|
||||
++buf->pos;
|
||||
obj->serial.uart->SCFTDR = c;
|
||||
} while (--i);
|
||||
serial_put_done(obj);
|
||||
|
||||
return buf->length;
|
||||
}
|
||||
|
||||
void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
|
||||
{
|
||||
buffer_t *buf = &obj->rx_buff;
|
||||
struct serial_global_data_s *data = uart_data + obj->serial.index;
|
||||
|
||||
if (rx_length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf->buffer = rx;
|
||||
buf->length = rx_length * rx_width / 8;
|
||||
buf->pos = 0;
|
||||
buf->width = rx_width;
|
||||
obj->char_match = char_match;
|
||||
obj->char_found = 0;
|
||||
data->receiving_obj = obj;
|
||||
data->async_rx_callback = handler;
|
||||
data->event = 0;
|
||||
data->wanted_rx_events = event;
|
||||
|
||||
serial_irq_set(obj, RxIrq, 1);
|
||||
serial_irq_err_set(obj, 1);
|
||||
}
|
||||
|
||||
uint8_t serial_tx_active(serial_t *obj)
|
||||
{
|
||||
return uart_data[obj->serial.index].tranferring_obj != NULL;
|
||||
}
|
||||
|
||||
uint8_t serial_rx_active(serial_t *obj)
|
||||
{
|
||||
return uart_data[obj->serial.index].receiving_obj != NULL;
|
||||
}
|
||||
|
||||
int serial_irq_handler_asynch(serial_t *obj)
|
||||
{
|
||||
return uart_data[obj->serial.index].event;
|
||||
}
|
||||
|
||||
void serial_tx_abort_asynch(serial_t *obj)
|
||||
{
|
||||
uart_data[obj->serial.index].tranferring_obj = NULL;
|
||||
obj->serial.uart->SCFCR |= 1 << 2;
|
||||
obj->serial.uart->SCFCR &= ~(1 << 2);
|
||||
}
|
||||
|
||||
void serial_rx_abort_asynch(serial_t *obj)
|
||||
{
|
||||
uart_data[obj->serial.index].receiving_obj = NULL;
|
||||
obj->serial.uart->SCFCR |= 1 << 1;
|
||||
obj->serial.uart->SCFCR &= ~(1 << 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -76,11 +76,12 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
|
|||
uint32_t spi_data = pinmap_merge(spi_mosi, spi_miso);
|
||||
uint32_t spi_cntl = pinmap_merge(spi_sclk, spi_ssel);
|
||||
uint32_t spi = pinmap_merge(spi_data, spi_cntl);
|
||||
|
||||
|
||||
MBED_ASSERT((int)spi != NC);
|
||||
|
||||
obj->spi = (struct st_rspi *)RSPI[spi];
|
||||
|
||||
|
||||
obj->spi.spi = (struct st_rspi *)RSPI[spi];
|
||||
obj->spi.index = spi;
|
||||
|
||||
// enable power and clocking
|
||||
switch (spi) {
|
||||
case SPI_0: CPGSTBCR10 &= ~(0x80); break;
|
||||
|
@ -89,18 +90,18 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
|
|||
case SPI_3: CPGSTBCR10 &= ~(0x10); break;
|
||||
}
|
||||
dummy = CPGSTBCR10;
|
||||
|
||||
obj->spi->SPCR = 0x00; // CTRL to 0
|
||||
obj->spi->SPSCR = 0x00; // no sequential operation
|
||||
obj->spi->SSLP = 0x00; // SSL 'L' active
|
||||
obj->spi->SPDCR = 0x20; // byte access
|
||||
obj->spi->SPCKD = 0x00; // SSL -> enable CLK delay : 1RSPCK
|
||||
obj->spi->SSLND = 0x00; // CLK end -> SSL neg delay : 1RSPCK
|
||||
obj->spi->SPND = 0x00; // delay between CMD : 1RSPCK + 2P1CLK
|
||||
obj->spi->SPPCR = 0x20; // MOSI Idle fixed value equals 0
|
||||
obj->spi->SPBFCR = 0xf0; // and set trigger count: read 1, write 1
|
||||
obj->spi->SPBFCR = 0x30; // and reset buffer
|
||||
|
||||
|
||||
obj->spi.spi->SPCR = 0x00; // CTRL to 0
|
||||
obj->spi.spi->SPSCR = 0x00; // no sequential operation
|
||||
obj->spi.spi->SSLP = 0x00; // SSL 'L' active
|
||||
obj->spi.spi->SPDCR = 0x20; // byte access
|
||||
obj->spi.spi->SPCKD = 0x00; // SSL -> enable CLK delay : 1RSPCK
|
||||
obj->spi.spi->SSLND = 0x00; // CLK end -> SSL neg delay : 1RSPCK
|
||||
obj->spi.spi->SPND = 0x00; // delay between CMD : 1RSPCK + 2P1CLK
|
||||
obj->spi.spi->SPPCR = 0x20; // MOSI Idle fixed value equals 0
|
||||
obj->spi.spi->SPBFCR = 0xf0; // and set trigger count: read 1, write 1
|
||||
obj->spi.spi->SPBFCR = 0x30; // and reset buffer
|
||||
|
||||
// pin out the spi pins
|
||||
pinmap_pinout(mosi, PinMap_SPI_MOSI);
|
||||
pinmap_pinout(miso, PinMap_SPI_MISO);
|
||||
|
@ -120,7 +121,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
|
|||
uint16_t mask = 0xf03;
|
||||
uint16_t wk_spcmd0;
|
||||
uint8_t splw;
|
||||
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
case 1:
|
||||
|
@ -132,7 +133,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
|
|||
error("SPI format error");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch (bits) {
|
||||
case 8:
|
||||
DSS = 0x7;
|
||||
|
@ -153,18 +154,18 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
|
|||
tmp |= phase;
|
||||
tmp |= (polarity << 1);
|
||||
tmp |= (DSS << 8);
|
||||
obj->bits = bits;
|
||||
|
||||
obj->spi.bits = bits;
|
||||
|
||||
spi_disable(obj);
|
||||
wk_spcmd0 = obj->spi->SPCMD0;
|
||||
wk_spcmd0 = obj->spi.spi->SPCMD0;
|
||||
wk_spcmd0 &= ~mask;
|
||||
wk_spcmd0 |= (mask & tmp);
|
||||
obj->spi->SPCMD0 = wk_spcmd0;
|
||||
obj->spi->SPDCR = splw;
|
||||
obj->spi.spi->SPCMD0 = wk_spcmd0;
|
||||
obj->spi.spi->SPDCR = splw;
|
||||
if (slave) {
|
||||
obj->spi->SPCR &=~(1 << 3); // MSTR to 0
|
||||
obj->spi.spi->SPCR &=~(1 << 3); // MSTR to 0
|
||||
} else {
|
||||
obj->spi->SPCR |= (1 << 3); // MSTR to 1
|
||||
obj->spi.spi->SPCR |= (1 << 3); // MSTR to 1
|
||||
}
|
||||
spi_enable(obj);
|
||||
}
|
||||
|
@ -177,21 +178,21 @@ void spi_frequency(spi_t *obj, int hz) {
|
|||
uint32_t hz_min;
|
||||
uint16_t mask = 0x000c;
|
||||
uint16_t wk_spcmd0;
|
||||
|
||||
|
||||
/* set PCLK */
|
||||
if (RZ_A1_IsClockMode0() == false) {
|
||||
pclk_base = CM1_RENESAS_RZ_A1_P1_CLK;
|
||||
} else {
|
||||
pclk_base = CM0_RENESAS_RZ_A1_P1_CLK;
|
||||
}
|
||||
|
||||
|
||||
hz_min = pclk_base / 2 / 256 / 8;
|
||||
hz_max = pclk_base / 2;
|
||||
if ((hz < hz_min) || (hz > hz_max)) {
|
||||
error("Couldn't setup requested SPI frequency");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
div = (pclk_base / hz / 2);
|
||||
while (div > 256) {
|
||||
div >>= 1;
|
||||
|
@ -199,53 +200,53 @@ void spi_frequency(spi_t *obj, int hz) {
|
|||
}
|
||||
div -= 1;
|
||||
brdv = (brdv << 2);
|
||||
|
||||
|
||||
spi_disable(obj);
|
||||
obj->spi->SPBR = div;
|
||||
wk_spcmd0 = obj->spi->SPCMD0;
|
||||
obj->spi.spi->SPBR = div;
|
||||
wk_spcmd0 = obj->spi.spi->SPCMD0;
|
||||
wk_spcmd0 &= ~mask;
|
||||
wk_spcmd0 |= (mask & brdv);
|
||||
obj->spi->SPCMD0 = wk_spcmd0;
|
||||
obj->spi.spi->SPCMD0 = wk_spcmd0;
|
||||
spi_enable(obj);
|
||||
}
|
||||
|
||||
static inline void spi_disable(spi_t *obj) {
|
||||
obj->spi->SPCR &= ~(1 << 6); // SPE to 0
|
||||
obj->spi.spi->SPCR &= ~(1 << 6); // SPE to 0
|
||||
}
|
||||
|
||||
static inline void spi_enable(spi_t *obj) {
|
||||
obj->spi->SPCR |= (1 << 6); // SPE to 1
|
||||
obj->spi.spi->SPCR |= (1 << 6); // SPE to 1
|
||||
}
|
||||
|
||||
static inline int spi_readable(spi_t *obj) {
|
||||
return obj->spi->SPSR & (1 << 7); // SPRF
|
||||
return obj->spi.spi->SPSR & (1 << 7); // SPRF
|
||||
}
|
||||
|
||||
static inline int spi_tend(spi_t *obj) {
|
||||
return obj->spi->SPSR & (1 << 6); // TEND
|
||||
return obj->spi.spi->SPSR & (1 << 6); // TEND
|
||||
}
|
||||
|
||||
static inline void spi_write(spi_t *obj, int value) {
|
||||
if (obj->bits == 8) {
|
||||
obj->spi->SPDR.UINT8[0] = (uint8_t)value;
|
||||
} else if (obj->bits == 16) {
|
||||
obj->spi->SPDR.UINT16[0] = (uint16_t)value;
|
||||
if (obj->spi.bits == 8) {
|
||||
obj->spi.spi->SPDR.UINT8[0] = (uint8_t)value;
|
||||
} else if (obj->spi.bits == 16) {
|
||||
obj->spi.spi->SPDR.UINT16[0] = (uint16_t)value;
|
||||
} else {
|
||||
obj->spi->SPDR.UINT32 = (uint32_t)value;
|
||||
obj->spi.spi->SPDR.UINT32 = (uint32_t)value;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int spi_read(spi_t *obj) {
|
||||
int read_data;
|
||||
|
||||
if (obj->bits == 8) {
|
||||
read_data = obj->spi->SPDR.UINT8[0];
|
||||
} else if (obj->bits == 16) {
|
||||
read_data = obj->spi->SPDR.UINT16[0];
|
||||
|
||||
if (obj->spi.bits == 8) {
|
||||
read_data = obj->spi.spi->SPDR.UINT8[0];
|
||||
} else if (obj->spi.bits == 16) {
|
||||
read_data = obj->spi.spi->SPDR.UINT16[0];
|
||||
} else {
|
||||
read_data = obj->spi->SPDR.UINT32;
|
||||
read_data = obj->spi.spi->SPDR.UINT32;
|
||||
}
|
||||
|
||||
|
||||
return read_data;
|
||||
}
|
||||
|
||||
|
@ -270,3 +271,307 @@ void spi_slave_write(spi_t *obj, int value) {
|
|||
int spi_busy(spi_t *obj) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
|
||||
#define IRQ_NUM 2
|
||||
|
||||
static void spi_irqs_set(spi_t *obj, uint32_t enable);
|
||||
static void spi_async_write(spi_t *obj);
|
||||
static void spi_async_read(spi_t *obj);
|
||||
|
||||
static void spi0_rx_irq(void);
|
||||
static void spi1_rx_irq(void);
|
||||
static void spi2_rx_irq(void);
|
||||
static void spi3_rx_irq(void);
|
||||
static void spi4_rx_irq(void);
|
||||
static void spi0_er_irq(void);
|
||||
static void spi1_er_irq(void);
|
||||
static void spi2_er_irq(void);
|
||||
static void spi3_er_irq(void);
|
||||
static void spi4_er_irq(void);
|
||||
|
||||
static const IRQn_Type irq_set_tbl[RSPI_COUNT][IRQ_NUM] = {
|
||||
{RSPISPRI0_IRQn, RSPISPEI0_IRQn},
|
||||
{RSPISPRI1_IRQn, RSPISPEI1_IRQn},
|
||||
{RSPISPRI2_IRQn, RSPISPEI2_IRQn},
|
||||
{RSPISPRI3_IRQn, RSPISPEI3_IRQn},
|
||||
{RSPISPRI4_IRQn, RSPISPEI4_IRQn}
|
||||
};
|
||||
|
||||
static const IRQHandler hander_set_tbl[RSPI_COUNT][IRQ_NUM] = {
|
||||
{spi0_rx_irq, spi0_er_irq},
|
||||
{spi1_rx_irq, spi1_er_irq},
|
||||
{spi2_rx_irq, spi2_er_irq},
|
||||
{spi3_rx_irq, spi3_er_irq},
|
||||
{spi4_rx_irq, spi4_er_irq}
|
||||
};
|
||||
|
||||
struct spi_global_data_s {
|
||||
spi_t *async_obj;
|
||||
uint32_t async_callback, event, wanted_events;
|
||||
};
|
||||
|
||||
static struct spi_global_data_s spi_data[RSPI_COUNT];
|
||||
|
||||
static void spi_rx_irq(IRQn_Type irq_num, uint32_t index)
|
||||
{
|
||||
spi_t *obj = spi_data[index].async_obj;
|
||||
if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
|
||||
spi_async_read(obj);
|
||||
} else {
|
||||
if (obj->rx_buff.buffer && obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) {
|
||||
spi_data[obj->spi.index].event = SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
|
||||
if (spi_data[obj->spi.index].wanted_events & SPI_EVENT_COMPLETE) {
|
||||
spi_data[obj->spi.index].event |= SPI_EVENT_COMPLETE;
|
||||
}
|
||||
spi_irqs_set(obj, 0);
|
||||
spi_data[obj->spi.index].async_obj = NULL;
|
||||
((void (*)())spi_data[obj->spi.index].async_callback)();
|
||||
return;
|
||||
}
|
||||
spi_read(obj);
|
||||
}
|
||||
if (obj->tx_buff.buffer) {
|
||||
if (obj->tx_buff.pos == obj->tx_buff.length) {
|
||||
spi_data[obj->spi.index].event = SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
|
||||
if (spi_data[obj->spi.index].wanted_events & SPI_EVENT_COMPLETE) {
|
||||
spi_data[obj->spi.index].event |= SPI_EVENT_COMPLETE;
|
||||
}
|
||||
spi_irqs_set(obj, 0);
|
||||
spi_data[obj->spi.index].async_obj = NULL;
|
||||
((void (*)())spi_data[obj->spi.index].async_callback)();
|
||||
} else {
|
||||
spi_async_write(obj);
|
||||
}
|
||||
} else {
|
||||
if (obj->rx_buff.pos == obj->rx_buff.length) {
|
||||
spi_data[obj->spi.index].event = SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
|
||||
if (spi_data[obj->spi.index].wanted_events & SPI_EVENT_COMPLETE) {
|
||||
spi_data[obj->spi.index].event |= SPI_EVENT_COMPLETE;
|
||||
}
|
||||
spi_irqs_set(obj, 0);
|
||||
spi_data[obj->spi.index].async_obj = NULL;
|
||||
((void (*)())spi_data[obj->spi.index].async_callback)();
|
||||
} else {
|
||||
spi_async_write(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_err_irq(IRQn_Type irq_num, uint32_t index)
|
||||
{
|
||||
spi_t *obj = spi_data[index].async_obj;
|
||||
spi_abort_asynch(obj);
|
||||
spi_data[index].event = SPI_EVENT_ERROR;
|
||||
if (spi_data[index].wanted_events & SPI_EVENT_ERROR) {
|
||||
((void (*)())spi_data[index].async_callback)();
|
||||
}
|
||||
}
|
||||
|
||||
static void spi0_rx_irq(void)
|
||||
{
|
||||
spi_rx_irq(RSPISPRI0_IRQn, 0);
|
||||
}
|
||||
|
||||
static void spi1_rx_irq(void)
|
||||
{
|
||||
spi_rx_irq(RSPISPRI1_IRQn, 1);
|
||||
}
|
||||
|
||||
static void spi2_rx_irq(void)
|
||||
{
|
||||
spi_rx_irq(RSPISPRI2_IRQn, 2);
|
||||
}
|
||||
|
||||
static void spi3_rx_irq(void)
|
||||
{
|
||||
spi_rx_irq(RSPISPRI3_IRQn, 3);
|
||||
}
|
||||
|
||||
static void spi4_rx_irq(void)
|
||||
{
|
||||
spi_rx_irq(RSPISPRI4_IRQn, 4);
|
||||
}
|
||||
|
||||
static void spi0_er_irq(void)
|
||||
{
|
||||
spi_err_irq(RSPISPEI0_IRQn, 0);
|
||||
}
|
||||
|
||||
static void spi1_er_irq(void)
|
||||
{
|
||||
spi_err_irq(RSPISPEI1_IRQn, 1);
|
||||
}
|
||||
|
||||
static void spi2_er_irq(void)
|
||||
{
|
||||
spi_err_irq(RSPISPEI2_IRQn, 2);
|
||||
}
|
||||
|
||||
static void spi3_er_irq(void)
|
||||
{
|
||||
spi_err_irq(RSPISPEI3_IRQn, 3);
|
||||
}
|
||||
|
||||
static void spi4_er_irq(void)
|
||||
{
|
||||
spi_err_irq(RSPISPEI4_IRQn, 4);
|
||||
}
|
||||
|
||||
static void spi_irqs_set(spi_t *obj, uint32_t enable)
|
||||
{
|
||||
int i;
|
||||
const IRQn_Type *irqTable = irq_set_tbl[obj->spi.index];
|
||||
const IRQHandler *handlerTable = hander_set_tbl[obj->spi.index];
|
||||
for (i = 0; i < IRQ_NUM; ++i) {
|
||||
if (enable) {
|
||||
InterruptHandlerRegister(irqTable[i], handlerTable[i]);
|
||||
GIC_SetPriority(irqTable[i], 5);
|
||||
GIC_EnableIRQ(irqTable[i]);
|
||||
} else {
|
||||
GIC_DisableIRQ(irqTable[i]);
|
||||
}
|
||||
}
|
||||
if (enable) {
|
||||
obj->spi.spi->SPCR |= (1 << 4) | (1 << 7);
|
||||
} else {
|
||||
obj->spi.spi->SPCR &= ~((1 << 4) | (1 << 7));
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_async_write(spi_t *obj)
|
||||
{
|
||||
uint8_t **width8;
|
||||
uint16_t **width16;
|
||||
uint32_t **width32;
|
||||
|
||||
if (obj->tx_buff.buffer) {
|
||||
switch (obj->tx_buff.width) {
|
||||
case 8:
|
||||
width8 = (uint8_t **)&obj->tx_buff.buffer;
|
||||
spi_write(obj, **width8);
|
||||
++*width8;
|
||||
obj->tx_buff.pos += sizeof(uint8_t);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
width16 = (uint16_t **)&obj->tx_buff.buffer;
|
||||
spi_write(obj, **width16);
|
||||
++*width16;
|
||||
obj->tx_buff.pos += sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
width32 = (uint32_t **)&obj->tx_buff.buffer;
|
||||
spi_write(obj, **width32);
|
||||
++*width32;
|
||||
obj->tx_buff.pos += sizeof(uint32_t);
|
||||
break;
|
||||
|
||||
default:
|
||||
MBED_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
spi_write(obj, SPI_FILL_WORD);
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_async_read(spi_t *obj)
|
||||
{
|
||||
uint8_t **width8;
|
||||
uint16_t **width16;
|
||||
uint32_t **width32;
|
||||
|
||||
switch (obj->rx_buff.width) {
|
||||
case 8:
|
||||
width8 = (uint8_t **)&obj->rx_buff.buffer;
|
||||
**width8 = spi_read(obj);
|
||||
++*width8;
|
||||
obj->rx_buff.pos += sizeof(uint8_t);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
width16 = (uint16_t **)&obj->rx_buff.buffer;
|
||||
**width16 = spi_read(obj);
|
||||
++*width16;
|
||||
obj->rx_buff.pos += sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
width32 = (uint32_t **)&obj->rx_buff.buffer;
|
||||
**width32 = spi_read(obj);
|
||||
++*width32;
|
||||
obj->rx_buff.pos += sizeof(uint32_t);
|
||||
break;
|
||||
|
||||
default:
|
||||
MBED_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* ASYNCHRONOUS HAL
|
||||
******************************************************************************/
|
||||
|
||||
void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint)
|
||||
{
|
||||
int i;
|
||||
MBED_ASSERT(obj);
|
||||
MBED_ASSERT(tx || rx);
|
||||
MBED_ASSERT(tx && ! rx ? tx_length : 1);
|
||||
MBED_ASSERT(rx && ! tx ? rx_length : 1);
|
||||
MBED_ASSERT(obj->spi.spi->SPCR & (1 << 3)); /* Slave mode */
|
||||
MBED_ASSERT(bit_width == 8 || bit_width == 16 || bit_width == 32);
|
||||
|
||||
if (tx_length) {
|
||||
obj->tx_buff.buffer = (void *)tx;
|
||||
} else {
|
||||
obj->tx_buff.buffer = NULL;
|
||||
}
|
||||
obj->tx_buff.length = tx_length * bit_width / 8;
|
||||
obj->tx_buff.pos = 0;
|
||||
obj->tx_buff.width = bit_width;
|
||||
if (rx_length) {
|
||||
obj->rx_buff.buffer = rx;
|
||||
} else {
|
||||
obj->rx_buff.buffer = NULL;
|
||||
}
|
||||
obj->rx_buff.length = rx_length * bit_width / 8;
|
||||
obj->rx_buff.pos = 0;
|
||||
obj->rx_buff.width = bit_width;
|
||||
for (i = 0; i < obj->rx_buff.length; i++) {
|
||||
((uint8_t *)obj->rx_buff.buffer)[i] = SPI_FILL_WORD;
|
||||
}
|
||||
|
||||
spi_data[obj->spi.index].async_callback = handler;
|
||||
spi_data[obj->spi.index].async_obj = obj;
|
||||
spi_data[obj->spi.index].event = 0;
|
||||
spi_data[obj->spi.index].wanted_events = event;
|
||||
|
||||
spi_irqs_set(obj, 1);
|
||||
|
||||
spi_async_write(obj);
|
||||
}
|
||||
|
||||
uint32_t spi_irq_handler_asynch(spi_t *obj)
|
||||
{
|
||||
return spi_data[obj->spi.index].event;
|
||||
}
|
||||
|
||||
uint8_t spi_active(spi_t *obj)
|
||||
{
|
||||
return spi_data[obj->spi.index].async_obj != NULL;
|
||||
}
|
||||
|
||||
void spi_abort_asynch(spi_t *obj)
|
||||
{
|
||||
spi_disable(obj);
|
||||
spi_irqs_set(obj, 0);
|
||||
spi_data[obj->spi.index].async_obj = NULL;
|
||||
spi_enable(obj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,6 +40,13 @@
|
|||
#define TEST_SDA_PIN PD6
|
||||
#define TEST_SCL_PIN PD7
|
||||
|
||||
#elif defined(TARGET_RZ_A1H)
|
||||
#define TEST_SDA_PIN P1_3
|
||||
#define TEST_SCL_PIN P1_2
|
||||
void sleep()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
#error Target not supported
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
#define TEST_SERIAL_ONE_TX_PIN D1 // UART2
|
||||
#define TEST_SERIAL_TWO_RX_PIN D4 // UART5
|
||||
|
||||
#elif defined(TARGET_RZ_A1H)
|
||||
#define TEST_SERIAL_ONE_TX_PIN P8_14 // UART4
|
||||
#define TEST_SERIAL_TWO_RX_PIN P8_11 // UART5
|
||||
|
||||
#else
|
||||
|
||||
#error Target not supported
|
||||
|
|
|
@ -58,6 +58,12 @@
|
|||
#define TEST_SCLK_PIN PE12
|
||||
#define TEST_CS_PIN PE13
|
||||
|
||||
#elif defined(TARGET_RZ_A1H)
|
||||
#define TEST_MOSI_PIN P10_14
|
||||
#define TEST_MISO_PIN P10_15
|
||||
#define TEST_SCLK_PIN P10_12
|
||||
#define TEST_CS_PIN P10_13
|
||||
|
||||
#else
|
||||
#error Target not supported
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue