未验证 提交 a65e6d16 编写于 作者: W Wayne 提交者: GitHub

Nuvoton drivers updating and more LVGL supporting. (#5647)

上级 d53ff736
# Bring up LVGL demo on Nuvoton platforms
Current supported LVGL running environment on Nuvoton's boards shown in below table:
| **Board Name** | **Default demo** | **Need Expansion** | **Used Configuration filename** |
| -------------- | ------------------------------- | ---------------- | ----------- |
| numaker-iot-m487 | Widgets | Nu-TFT v1.3 | config_lvgl |
| numaker-pfm-m487 | Widgets | Advance v4 | config_lvgl |
| nk-980iot | Music | Nu-TFT v1.3 | config_lvgl |
| numaker-m2354 | Music | Nu-TFT v1.3 | config_lvgl |
| nk-n9h30 | Music | No | .config |
| numaker-m032ki | Widgets | Nu-TFT v1.3 | config_lvgl |
## Download related packages
To execute below commands in env command-line window to download related packages for building.
```bash
# cd <path-to-rt-thread>bsp/nuvoton/<board-name>
# menuconfig --config config_lvgl
# pkgs --update
# scons
```
## Firmware programming
To program built rt-thread.bin into flash. You can refer steps in README.md in corresponding supported board folder or CN quick-start guide in rt-thread documents site.
```
<path-to-rt-thread>/bsp/nuvoton/<board-name>/README.md
```
or
```
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/quick-start/more
```
...@@ -8,9 +8,6 @@ ...@@ -8,9 +8,6 @@
*****************************************************************************/ *****************************************************************************/
#include "M031Series.h" #include "M031Series.h"
static uint8_t u8ChSelect[PDMA_CH_MAX];
/** @addtogroup Standard_Driver Standard Driver /** @addtogroup Standard_Driver Standard Driver
@{ @{
*/ */
...@@ -28,6 +25,7 @@ static uint8_t u8ChSelect[PDMA_CH_MAX]; ...@@ -28,6 +25,7 @@ static uint8_t u8ChSelect[PDMA_CH_MAX];
* @brief PDMA Open * @brief PDMA Open
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
*
* @param[in] u32Mask Channel enable bits. * @param[in] u32Mask Channel enable bits.
* *
* @return None * @return None
...@@ -40,10 +38,9 @@ void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask) ...@@ -40,10 +38,9 @@ void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask)
for (i = 0UL; i < PDMA_CH_MAX; i++) for (i = 0UL; i < PDMA_CH_MAX; i++)
{ {
if((1 << i) & u32Mask) if ((1 << i) & u32Mask)
{ {
pdma->DSCT[i].CTL = 0UL; pdma->DSCT[i].CTL = 0UL;
u8ChSelect[i] = PDMA_MEM;
} }
} }
...@@ -166,59 +163,26 @@ void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uin ...@@ -166,59 +163,26 @@ void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uin
*/ */
void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr) void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
{ {
u8ChSelect[u32Ch] = u32Peripheral; if (u32Ch < PDMA_CH_MAX)
switch (u32Ch)
{ {
case 0ul: __IO uint32_t *pau32REQSEL = (__IO uint32_t *)&pdma->REQSEL0_3;
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC0_Msk) | u32Peripheral; uint32_t u32REQSEL_Pos, u32REQSEL_Msk;
break;
case 1ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC1_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC1_Pos);
break;
case 2ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC2_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC2_Pos);
break;
case 3ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC3_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC3_Pos);
break;
case 4ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC4_Msk) | u32Peripheral;
break;
case 5ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC5_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC5_Pos);
break;
case 6ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC6_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC6_Pos);
break;
case 7ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC7_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC7_Pos);
break;
case 8ul:
pdma->REQSEL8 = (pdma->REQSEL8 & ~PDMA_REQSEL8_REQSRC8_Msk) | u32Peripheral;
break;
default: u32REQSEL_Pos = (u32Ch % 4) * 8 ;
break; u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
} pau32REQSEL[u32Ch / 4] = (pau32REQSEL[u32Ch / 4] & ~u32REQSEL_Msk) | (u32Peripheral << u32REQSEL_Pos);
if (u32ScatterEn) if (u32ScatterEn)
{ {
pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER; pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER;
pdma->DSCT[u32Ch].NEXT = u32DescAddr - (pdma->SCATBA); pdma->DSCT[u32Ch].NEXT = u32DescAddr - (pdma->SCATBA);
} }
else else
{ {
pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC; pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC;
}
} }
else {}
} }
/** /**
...@@ -253,6 +217,7 @@ void PDMA_SetBurstType(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32BurstType, uint ...@@ -253,6 +217,7 @@ void PDMA_SetBurstType(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32BurstType, uint
* @brief Enable timeout function * @brief Enable timeout function
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
*
* @param[in] u32Mask Channel enable bits. * @param[in] u32Mask Channel enable bits.
* *
* @return None * @return None
...@@ -268,6 +233,7 @@ void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask) ...@@ -268,6 +233,7 @@ void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask)
* @brief Disable timeout function * @brief Disable timeout function
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
*
* @param[in] u32Mask Channel enable bits. * @param[in] u32Mask Channel enable bits.
* *
* @return None * @return None
...@@ -294,24 +260,21 @@ void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask) ...@@ -294,24 +260,21 @@ void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask)
*/ */
void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt) void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt)
{ {
switch (u32Ch) if (u32Ch < 2)
{ {
case 0ul: __IO uint32_t *pau32TOC = (__IO uint32_t *)&pdma->TOC0_1;
pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC0_Msk) | u32TimeOutCnt; uint32_t u32TOC_Pos, u32TOC_Msk;
break;
case 1ul: u32TOC_Pos = (u32Ch % 2) * 16 ;
pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC1_Msk) | (u32TimeOutCnt << PDMA_TOC0_1_TOC1_Pos); u32TOC_Msk = PDMA_TOC0_1_TOC0_Msk << u32TOC_Pos;
break; pau32TOC[u32Ch / 2] = (pau32TOC[u32Ch / 2] & ~u32TOC_Msk) | (u32TimeOutCnt << u32TOC_Pos);
default: if (u32OnOff)
break; pdma->TOUTEN |= (1 << u32Ch);
else
pdma->TOUTEN &= ~(1 << u32Ch);
} }
else {}
if (u32OnOff)
pdma->TOUTEN |= (1ul << u32Ch);
else
pdma->TOUTEN &= ~(1ul << u32Ch);
} }
/** /**
...@@ -326,7 +289,15 @@ void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u ...@@ -326,7 +289,15 @@ void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u
*/ */
void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch) void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch)
{ {
if (u8ChSelect[u32Ch] == PDMA_MEM) __IO uint32_t *pau32REQSEL = (__IO uint32_t *)&pdma->REQSEL0_3;
uint32_t u32REQSEL_Pos, u32REQSEL_Msk, u32ChReq;
u32REQSEL_Pos = (u32Ch % 4) * 8 ;
u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
u32ChReq = (pau32REQSEL[u32Ch / 4] & u32REQSEL_Msk) >> u32REQSEL_Pos;
if (u32ChReq == PDMA_MEM)
{ {
pdma->SWREQ = (1ul << u32Ch); pdma->SWREQ = (1ul << u32Ch);
} }
...@@ -354,11 +325,9 @@ void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask) ...@@ -354,11 +325,9 @@ void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
case PDMA_INT_TRANS_DONE: case PDMA_INT_TRANS_DONE:
pdma->INTEN |= (1ul << u32Ch); pdma->INTEN |= (1ul << u32Ch);
break; break;
case PDMA_INT_TEMPTY: case PDMA_INT_TEMPTY:
pdma->DSCT[u32Ch].CTL &= ~PDMA_DSCT_CTL_TBINTDIS_Msk; pdma->DSCT[u32Ch].CTL &= ~PDMA_DSCT_CTL_TBINTDIS_Msk;
break; break;
case PDMA_INT_TIMEOUT: case PDMA_INT_TIMEOUT:
pdma->TOUTIEN |= (1ul << u32Ch); pdma->TOUTIEN |= (1ul << u32Ch);
break; break;
...@@ -389,11 +358,9 @@ void PDMA_DisableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask) ...@@ -389,11 +358,9 @@ void PDMA_DisableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
case PDMA_INT_TRANS_DONE: case PDMA_INT_TRANS_DONE:
pdma->INTEN &= ~(1ul << u32Ch); pdma->INTEN &= ~(1ul << u32Ch);
break; break;
case PDMA_INT_TEMPTY: case PDMA_INT_TEMPTY:
pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_TBINTDIS_Msk; pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_TBINTDIS_Msk;
break; break;
case PDMA_INT_TIMEOUT: case PDMA_INT_TIMEOUT:
pdma->TOUTIEN &= ~(1ul << u32Ch); pdma->TOUTIEN &= ~(1ul << u32Ch);
break; break;
......
...@@ -188,7 +188,7 @@ static void nu_pdma_init(void) ...@@ -188,7 +188,7 @@ static void nu_pdma_init(void)
RT_ASSERT(g_mutex_sg != RT_NULL); RT_ASSERT(g_mutex_sg != RT_NULL);
nu_pdma_chn_mask = ~NU_PDMA_CH_Msk; nu_pdma_chn_mask = ~NU_PDMA_CH_Msk;
rt_memset(nu_pdma_chn_arr, 0x00, NU_PDMA_CH_MAX*sizeof(nu_pdma_chn_t)); rt_memset(nu_pdma_chn_arr, 0x00, NU_PDMA_CH_MAX * sizeof(nu_pdma_chn_t));
NVIC_EnableIRQ(PDMA_IRQn); NVIC_EnableIRQ(PDMA_IRQn);
...@@ -598,11 +598,13 @@ static void nu_pdma_sgtbls_token_free(nu_pdma_desc_t psSgtbls) ...@@ -598,11 +598,13 @@ static void nu_pdma_sgtbls_token_free(nu_pdma_desc_t psSgtbls)
rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num) rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num)
{ {
int i, j, idx; int i, j, idx;
rt_err_t result;
RT_ASSERT(ppsSgtbls != NULL); RT_ASSERT(ppsSgtbls != NULL);
RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE); RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE);
rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER); result = rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
...@@ -617,7 +619,8 @@ rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num) ...@@ -617,7 +619,8 @@ rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num)
ppsSgtbls[i] = (nu_pdma_desc_t)&nu_pdma_sgtbl_arr[idx]; ppsSgtbls[i] = (nu_pdma_desc_t)&nu_pdma_sgtbl_arr[idx];
} }
rt_mutex_release(g_mutex_sg); result = rt_mutex_release(g_mutex_sg);
RT_ASSERT(result == RT_EOK);
return RT_EOK; return RT_EOK;
...@@ -633,18 +636,22 @@ fail_nu_pdma_sgtbls_allocate: ...@@ -633,18 +636,22 @@ fail_nu_pdma_sgtbls_allocate:
ppsSgtbls[j] = NULL; ppsSgtbls[j] = NULL;
} }
rt_mutex_release(g_mutex_sg); result = rt_mutex_release(g_mutex_sg);
RT_ASSERT(result == RT_EOK);
return -RT_ERROR; return -RT_ERROR;
} }
void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num) void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num)
{ {
int i; int i;
rt_err_t result;
RT_ASSERT(ppsSgtbls != NULL); RT_ASSERT(ppsSgtbls != NULL);
RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE); RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE);
rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER); result = rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
...@@ -655,7 +662,8 @@ void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num) ...@@ -655,7 +662,8 @@ void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num)
ppsSgtbls[i] = NULL; ppsSgtbls[i] = NULL;
} }
rt_mutex_release(g_mutex_sg); result = rt_mutex_release(g_mutex_sg);
RT_ASSERT(result == RT_EOK);
} }
static rt_err_t nu_pdma_sgtbls_valid(nu_pdma_desc_t head) static rt_err_t nu_pdma_sgtbls_valid(nu_pdma_desc_t head)
...@@ -843,6 +851,7 @@ static void nu_pdma_memfun_actor_init(void) ...@@ -843,6 +851,7 @@ static void nu_pdma_memfun_actor_init(void)
if (-(RT_ERROR) != (nu_pdma_memfun_actor_arr[i].m_i32ChannID = nu_pdma_channel_allocate(PDMA_MEM))) if (-(RT_ERROR) != (nu_pdma_memfun_actor_arr[i].m_i32ChannID = nu_pdma_channel_allocate(PDMA_MEM)))
{ {
nu_pdma_memfun_actor_arr[i].m_psSemMemFun = rt_sem_create("memactor_sem", 0, RT_IPC_FLAG_FIFO); nu_pdma_memfun_actor_arr[i].m_psSemMemFun = rt_sem_create("memactor_sem", 0, RT_IPC_FLAG_FIFO);
RT_ASSERT(nu_pdma_memfun_actor_arr[i].m_psSemMemFun != RT_NULL);
} }
else else
break; break;
...@@ -851,16 +860,23 @@ static void nu_pdma_memfun_actor_init(void) ...@@ -851,16 +860,23 @@ static void nu_pdma_memfun_actor_init(void)
{ {
nu_pdma_memfun_actor_maxnum = i; nu_pdma_memfun_actor_maxnum = i;
nu_pdma_memfun_actor_mask = ~(((1 << i) - 1)); nu_pdma_memfun_actor_mask = ~(((1 << i) - 1));
nu_pdma_memfun_actor_pool_sem = rt_sem_create("mempool_sem", nu_pdma_memfun_actor_maxnum, RT_IPC_FLAG_FIFO); nu_pdma_memfun_actor_pool_sem = rt_sem_create("mempool_sem", nu_pdma_memfun_actor_maxnum, RT_IPC_FLAG_FIFO);
RT_ASSERT(nu_pdma_memfun_actor_pool_sem != RT_NULL);
nu_pdma_memfun_actor_pool_lock = rt_mutex_create("mempool_lock", RT_IPC_FLAG_PRIO); nu_pdma_memfun_actor_pool_lock = rt_mutex_create("mempool_lock", RT_IPC_FLAG_PRIO);
RT_ASSERT(nu_pdma_memfun_actor_pool_lock != RT_NULL);
} }
} }
static void nu_pdma_memfun_cb(void *pvUserData, uint32_t u32Events) static void nu_pdma_memfun_cb(void *pvUserData, uint32_t u32Events)
{ {
rt_err_t result;
nu_pdma_memfun_actor_t psMemFunActor = (nu_pdma_memfun_actor_t)pvUserData; nu_pdma_memfun_actor_t psMemFunActor = (nu_pdma_memfun_actor_t)pvUserData;
psMemFunActor->m_u32Result = u32Events; psMemFunActor->m_u32Result = u32Events;
rt_sem_release(psMemFunActor->m_psSemMemFun); result = rt_sem_release(psMemFunActor->m_psSemMemFun);
RT_ASSERT(result == RT_EOK);
} }
static int nu_pdma_memfun_employ(void) static int nu_pdma_memfun_employ(void)
...@@ -870,7 +886,10 @@ static int nu_pdma_memfun_employ(void) ...@@ -870,7 +886,10 @@ static int nu_pdma_memfun_employ(void)
/* Headhunter */ /* Headhunter */
if (nu_pdma_memfun_actor_pool_sem && (rt_sem_take(nu_pdma_memfun_actor_pool_sem, RT_WAITING_FOREVER) == RT_EOK)) if (nu_pdma_memfun_actor_pool_sem && (rt_sem_take(nu_pdma_memfun_actor_pool_sem, RT_WAITING_FOREVER) == RT_EOK))
{ {
rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER); rt_err_t result;
result = rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
/* Find the position of first '0' in nu_pdma_memfun_actor_mask. */ /* Find the position of first '0' in nu_pdma_memfun_actor_mask. */
idx = nu_cto(nu_pdma_memfun_actor_mask); idx = nu_cto(nu_pdma_memfun_actor_mask);
if (idx != 32) if (idx != 32)
...@@ -881,7 +900,8 @@ static int nu_pdma_memfun_employ(void) ...@@ -881,7 +900,8 @@ static int nu_pdma_memfun_employ(void)
{ {
idx = -1; idx = -1;
} }
rt_mutex_release(nu_pdma_memfun_actor_pool_lock); result = rt_mutex_release(nu_pdma_memfun_actor_pool_lock);
RT_ASSERT(result == RT_EOK);
} }
return idx; return idx;
...@@ -897,6 +917,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un ...@@ -897,6 +917,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
while (1) while (1)
{ {
rt_err_t result;
/* Employ actor */ /* Employ actor */
if ((idx = nu_pdma_memfun_employ()) < 0) if ((idx = nu_pdma_memfun_employ()) < 0)
continue; continue;
...@@ -925,7 +947,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un ...@@ -925,7 +947,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
0); 0);
/* Wait it done. */ /* Wait it done. */
rt_sem_take(psMemFunActor->m_psSemMemFun, RT_WAITING_FOREVER); result = rt_sem_take(psMemFunActor->m_psSemMemFun, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
/* Give result if get NU_PDMA_EVENT_TRANSFER_DONE.*/ /* Give result if get NU_PDMA_EVENT_TRANSFER_DONE.*/
if (psMemFunActor->m_u32Result & NU_PDMA_EVENT_TRANSFER_DONE) if (psMemFunActor->m_u32Result & NU_PDMA_EVENT_TRANSFER_DONE)
...@@ -945,16 +968,20 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un ...@@ -945,16 +968,20 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
} }
u32TransferCnt -= u32TxCnt; u32TransferCnt -= u32TxCnt;
u32Offset += u32TxCnt; u32Offset += u32TxCnt * (u32DataWidth / 8);
} }
while (u32TransferCnt > 0); while (u32TransferCnt > 0);
rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER); result = rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
nu_pdma_memfun_actor_mask &= ~(1 << idx); nu_pdma_memfun_actor_mask &= ~(1 << idx);
rt_mutex_release(nu_pdma_memfun_actor_pool_lock); result = rt_mutex_release(nu_pdma_memfun_actor_pool_lock);
RT_ASSERT(result == RT_EOK);
/* Fire actor */ /* Fire actor */
rt_sem_release(nu_pdma_memfun_actor_pool_sem); result = rt_sem_release(nu_pdma_memfun_actor_pool_sem);
RT_ASSERT(result == RT_EOK);
break; break;
} }
......
...@@ -96,11 +96,13 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, ...@@ -96,11 +96,13 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device,
uint32_t u32SPIMode; uint32_t u32SPIMode;
uint32_t u32BusClock; uint32_t u32BusClock;
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL); RT_ASSERT(configuration != RT_NULL);
spi_bus = (struct nu_spi *) device->bus; spi_bus = (struct nu_spi *) device->bus;
pvUserData = device->parent.user_data;
/* Check mode */ /* Check mode */
switch (configuration->mode & RT_SPI_MODE_3) switch (configuration->mode & RT_SPI_MODE_3)
...@@ -150,12 +152,29 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, ...@@ -150,12 +152,29 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device,
if (configuration->mode & RT_SPI_CS_HIGH) if (configuration->mode & RT_SPI_CS_HIGH)
{ {
/* Set CS pin to LOW */ /* Set CS pin to LOW */
SPI_SET_SS_LOW(spi_bus->spi_base); if (pvUserData != RT_NULL)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
} }
else else
{ {
/* Set CS pin to HIGH */ /* Set CS pin to HIGH */
SPI_SET_SS_HIGH(spi_bus->spi_base); if (pvUserData != RT_NULL)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
/* Set CS pin to HIGH */
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
} }
if (configuration->mode & RT_SPI_MSB) if (configuration->mode & RT_SPI_MSB)
...@@ -514,6 +533,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -514,6 +533,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
struct nu_spi *spi_bus; struct nu_spi *spi_bus;
struct rt_spi_configuration *configuration; struct rt_spi_configuration *configuration;
uint8_t bytes_per_word; uint8_t bytes_per_word;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus != RT_NULL);
...@@ -522,6 +542,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -522,6 +542,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
spi_bus = (struct nu_spi *) device->bus; spi_bus = (struct nu_spi *) device->bus;
configuration = (struct rt_spi_configuration *)&spi_bus->configuration; configuration = (struct rt_spi_configuration *)&spi_bus->configuration;
bytes_per_word = configuration->data_width / 8; bytes_per_word = configuration->data_width / 8;
pvUserData = device->parent.user_data;
if ((message->length % bytes_per_word) != 0) if ((message->length % bytes_per_word) != 0)
{ {
...@@ -534,13 +555,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -534,13 +555,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
{ {
if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
SPI_SET_SS_HIGH(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
} }
else else
{ {
SPI_SET_SS_LOW(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
else
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
} }
} }
...@@ -548,13 +585,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -548,13 +585,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
SPI_SET_SS_LOW(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
} }
else else
{ {
SPI_SET_SS_HIGH(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
else
{
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
} }
} }
......
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
#include <drv_pdma.h> #include <drv_pdma.h>
#endif #endif
/* Private define ---------------------------------------------------------------*/ /* Private define ---------------------------------------------------------------*/
#ifndef NU_SPI_USE_PDMA_MIN_THRESHOLD
#define NU_SPI_USE_PDMA_MIN_THRESHOLD (128)
#endif
enum enum
{ {
USPI_START = -1, USPI_START = -1,
...@@ -131,11 +136,13 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device, ...@@ -131,11 +136,13 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device,
uint32_t u32SPIMode; uint32_t u32SPIMode;
uint32_t u32BusClock; uint32_t u32BusClock;
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL); RT_ASSERT(configuration != RT_NULL);
uspi_bus = (struct nu_uspi *) device->bus; uspi_bus = (struct nu_uspi *) device->bus;
pvUserData = device->parent.user_data;
/* Check mode */ /* Check mode */
switch (configuration->mode & RT_SPI_MODE_3) switch (configuration->mode & RT_SPI_MODE_3)
...@@ -183,12 +190,29 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device, ...@@ -183,12 +190,29 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device,
if (configuration->mode & RT_SPI_CS_HIGH) if (configuration->mode & RT_SPI_CS_HIGH)
{ {
/* Set CS pin to LOW */ /* Set CS pin to LOW */
USPI_SET_SS_LOW(uspi_bus->uspi_base); if (pvUserData != RT_NULL)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
USPI_SET_SS_LOW(uspi_bus->uspi_base);
}
} }
else else
{ {
/* Set CS pin to HIGH */ /* Set CS pin to HIGH */
USPI_SET_SS_HIGH(uspi_bus->uspi_base); if (pvUserData != RT_NULL)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
/* Set CS pin to HIGH */
USPI_SET_SS_HIGH(uspi_bus->uspi_base);
}
} }
if (configuration->mode & RT_SPI_MSB) if (configuration->mode & RT_SPI_MSB)
...@@ -319,27 +343,40 @@ exit_nu_pdma_uspi_tx_config: ...@@ -319,27 +343,40 @@ exit_nu_pdma_uspi_tx_config:
**/ **/
static rt_size_t nu_uspi_pdma_transmit(struct nu_uspi *uspi_bus, const uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word) static rt_size_t nu_uspi_pdma_transmit(struct nu_uspi *uspi_bus, const uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word)
{ {
rt_err_t result; rt_err_t result = RT_EOK;
rt_uint32_t u32Offset = 0;
rt_uint32_t u32TransferCnt = length / bytes_per_word;
rt_uint32_t u32TxCnt = 0;
/* Get base address of uspi register */ /* Get base address of uspi register */
USPI_T *uspi_base = uspi_bus->uspi_base; USPI_T *uspi_base = uspi_bus->uspi_base;
result = nu_pdma_uspi_rx_config(uspi_bus, recv_addr, length, bytes_per_word); do
RT_ASSERT(result == RT_EOK); {
result = nu_pdma_uspi_tx_config(uspi_bus, send_addr, length, bytes_per_word); u32TxCnt = (u32TransferCnt > NU_PDMA_MAX_TXCNT) ? NU_PDMA_MAX_TXCNT : u32TransferCnt;
RT_ASSERT(result == RT_EOK); result = nu_pdma_uspi_rx_config(uspi_bus, (recv_addr == RT_NULL) ? recv_addr : &recv_addr[u32Offset], (u32TxCnt * bytes_per_word), bytes_per_word);
RT_ASSERT(result == RT_EOK);
/* Trigger TX/RX at the same time. */ result = nu_pdma_uspi_tx_config(uspi_bus, (send_addr == RT_NULL) ? send_addr : &send_addr[u32Offset], (u32TxCnt * bytes_per_word), bytes_per_word);
USPI_TRIGGER_TX_RX_PDMA(uspi_base); RT_ASSERT(result == RT_EOK);
/* Wait PDMA transfer done */ /* Trigger TX/RX PDMA transfer. */
result = rt_sem_take(uspi_bus->m_psSemBus, RT_WAITING_FOREVER); USPI_TRIGGER_TX_RX_PDMA(uspi_base);
RT_ASSERT(result == RT_EOK);
/* Stop DMA TX/RX transfer */ /* Wait RX-PDMA transfer done */
USPI_DISABLE_TX_RX_PDMA(uspi_base); result = rt_sem_take(uspi_bus->m_psSemBus, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
return result; /* Stop TX/RX DMA transfer. */
USPI_DISABLE_TX_RX_PDMA(uspi_base);
u32TransferCnt -= u32TxCnt;
u32Offset += u32TxCnt;
}
while (u32TransferCnt > 0);
return length;
} }
static rt_err_t nu_hw_uspi_pdma_allocate(struct nu_uspi *uspi_bus) static rt_err_t nu_hw_uspi_pdma_allocate(struct nu_uspi *uspi_bus)
...@@ -504,11 +541,14 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus, ...@@ -504,11 +541,14 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus,
static void nu_uspi_transfer(struct nu_uspi *uspi_bus, uint8_t *tx, uint8_t *rx, int length, uint8_t bytes_per_word) static void nu_uspi_transfer(struct nu_uspi *uspi_bus, uint8_t *tx, uint8_t *rx, int length, uint8_t bytes_per_word)
{ {
RT_ASSERT(uspi_bus != RT_NULL);
#if defined(BSP_USING_USPI_PDMA) #if defined(BSP_USING_USPI_PDMA)
/* PDMA transfer constrains */ /* PDMA transfer constrains */
if ((uspi_bus->pdma_chanid_rx >= 0) && if ((uspi_bus->pdma_chanid_rx >= 0) &&
(!((uint32_t)tx % bytes_per_word)) && !((uint32_t)tx % bytes_per_word) &&
(!((uint32_t)rx % bytes_per_word))) !((uint32_t)rx % bytes_per_word) &&
(length >= NU_SPI_USE_PDMA_MIN_THRESHOLD))
nu_uspi_pdma_transmit(uspi_bus, tx, rx, length, bytes_per_word); nu_uspi_pdma_transmit(uspi_bus, tx, rx, length, bytes_per_word);
else else
nu_uspi_transmission_with_poll(uspi_bus, tx, rx, length, bytes_per_word); nu_uspi_transmission_with_poll(uspi_bus, tx, rx, length, bytes_per_word);
...@@ -522,6 +562,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -522,6 +562,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
struct nu_uspi *uspi_bus; struct nu_uspi *uspi_bus;
struct rt_spi_configuration *configuration; struct rt_spi_configuration *configuration;
uint8_t bytes_per_word; uint8_t bytes_per_word;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus != RT_NULL);
...@@ -530,6 +571,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -530,6 +571,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
uspi_bus = (struct nu_uspi *) device->bus; uspi_bus = (struct nu_uspi *) device->bus;
configuration = &uspi_bus->configuration; configuration = &uspi_bus->configuration;
bytes_per_word = configuration->data_width / 8; bytes_per_word = configuration->data_width / 8;
pvUserData = device->parent.user_data;
if ((message->length % bytes_per_word) != 0) if ((message->length % bytes_per_word) != 0)
{ {
...@@ -542,13 +584,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -542,13 +584,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
{ {
if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
USPI_SET_SS_HIGH(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
} }
else else
{ {
USPI_SET_SS_LOW(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
USPI_SET_SS_HIGH(uspi_bus->uspi_base);
}
else
{
USPI_SET_SS_LOW(uspi_bus->uspi_base);
}
} }
} }
...@@ -556,13 +614,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -556,13 +614,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
USPI_SET_SS_LOW(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
} }
else else
{ {
USPI_SET_SS_HIGH(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
USPI_SET_SS_LOW(uspi_bus->uspi_base);
}
else
{
USPI_SET_SS_HIGH(uspi_bus->uspi_base);
}
} }
} }
......
...@@ -8,9 +8,6 @@ ...@@ -8,9 +8,6 @@
*****************************************************************************/ *****************************************************************************/
#include "NuMicro.h" #include "NuMicro.h"
static uint8_t au8ChSelect[PDMA_CH_MAX];
/** @addtogroup Standard_Driver Standard Driver /** @addtogroup Standard_Driver Standard Driver
@{ @{
*/ */
...@@ -28,7 +25,8 @@ static uint8_t au8ChSelect[PDMA_CH_MAX]; ...@@ -28,7 +25,8 @@ static uint8_t au8ChSelect[PDMA_CH_MAX];
* @brief PDMA Open * @brief PDMA Open
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Mask Channel enable bits. *
* @param[in] u32Mask Channel enable bits.
* *
* @return None * @return None
* *
...@@ -38,16 +36,15 @@ void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask) ...@@ -38,16 +36,15 @@ void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask)
{ {
uint32_t i; uint32_t i;
for(i = 0UL; i < (int)PDMA_CH_MAX; i++) for (i = 0UL; i < PDMA_CH_MAX; i++)
{ {
if((1 << i) & u32Mask) if ((1 << i) & u32Mask)
{ {
(pdma)->DSCT[i].CTL = 0UL; pdma->DSCT[i].CTL = 0UL;
au8ChSelect[i] = (uint8_t)PDMA_MEM;
} }
} }
(pdma)->CHCTL |= u32Mask; pdma->CHCTL |= u32Mask;
} }
/** /**
...@@ -61,7 +58,7 @@ void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask) ...@@ -61,7 +58,7 @@ void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask)
*/ */
void PDMA_Close(PDMA_T *pdma) void PDMA_Close(PDMA_T *pdma)
{ {
(pdma)->CHCTL = 0UL; pdma->CHCTL = 0UL;
} }
/** /**
...@@ -81,8 +78,8 @@ void PDMA_Close(PDMA_T *pdma) ...@@ -81,8 +78,8 @@ void PDMA_Close(PDMA_T *pdma)
*/ */
void PDMA_SetTransferCnt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount) void PDMA_SetTransferCnt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount)
{ {
(pdma)->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXCNT_Msk | PDMA_DSCT_CTL_TXWIDTH_Msk); pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXCNT_Msk | PDMA_DSCT_CTL_TXWIDTH_Msk);
(pdma)->DSCT[u32Ch].CTL |= (u32Width | ((u32TransCount - 1UL) << PDMA_DSCT_CTL_TXCNT_Pos)); pdma->DSCT[u32Ch].CTL |= (u32Width | ((u32TransCount - 1UL) << PDMA_DSCT_CTL_TXCNT_Pos));
} }
/** /**
...@@ -118,7 +115,7 @@ void PDMA_SetStride(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32DestLen, uint32_t ...@@ -118,7 +115,7 @@ void PDMA_SetStride(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32DestLen, uint32_t
* *
* @details This function set the selected repeat. * @details This function set the selected repeat.
*/ */
void PDMA_SetRepeat(PDMA_T * pdma, uint32_t u32Ch, uint32_t u32DestInterval, uint32_t u32SrcInterval, uint32_t u32RepeatCount) void PDMA_SetRepeat(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32DestInterval, uint32_t u32SrcInterval, uint32_t u32RepeatCount)
{ {
pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDEEN_Msk; pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDEEN_Msk;
pdma->REPEAT[u32Ch].AICTL = ((u32DestInterval) << 16) | (u32SrcInterval); pdma->REPEAT[u32Ch].AICTL = ((u32DestInterval) << 16) | (u32SrcInterval);
...@@ -134,8 +131,8 @@ void PDMA_SetRepeat(PDMA_T * pdma, uint32_t u32Ch, uint32_t u32DestInterval, uin ...@@ -134,8 +131,8 @@ void PDMA_SetRepeat(PDMA_T * pdma, uint32_t u32Ch, uint32_t u32DestInterval, uin
* @param[in] u32SrcCtrl Source control attribute. Valid values are * @param[in] u32SrcCtrl Source control attribute. Valid values are
* - \ref PDMA_SAR_INC * - \ref PDMA_SAR_INC
* - \ref PDMA_SAR_FIX * - \ref PDMA_SAR_FIX
* @param[in] u32DstAddr destination address * @param[in] u32DstAddr Destination address
* @param[in] u32DstCtrl destination control attribute. Valid values are * @param[in] u32DstCtrl Destination control attribute. Valid values are
* - \ref PDMA_DAR_INC * - \ref PDMA_DAR_INC
* - \ref PDMA_DAR_FIX * - \ref PDMA_DAR_FIX
* *
...@@ -145,10 +142,10 @@ void PDMA_SetRepeat(PDMA_T * pdma, uint32_t u32Ch, uint32_t u32DestInterval, uin ...@@ -145,10 +142,10 @@ void PDMA_SetRepeat(PDMA_T * pdma, uint32_t u32Ch, uint32_t u32DestInterval, uin
*/ */
void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl) void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl)
{ {
(pdma)->DSCT[u32Ch].SA = u32SrcAddr; pdma->DSCT[u32Ch].SA = u32SrcAddr;
(pdma)->DSCT[u32Ch].DA = u32DstAddr; pdma->DSCT[u32Ch].DA = u32DstAddr;
(pdma)->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_SAINC_Msk | PDMA_DSCT_CTL_DAINC_Msk); pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_SAINC_Msk | PDMA_DSCT_CTL_DAINC_Msk);
(pdma)->DSCT[u32Ch].CTL |= (u32SrcCtrl | u32DstCtrl); pdma->DSCT[u32Ch].CTL |= (u32SrcCtrl | u32DstCtrl);
} }
/** /**
...@@ -228,46 +225,26 @@ void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uin ...@@ -228,46 +225,26 @@ void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uin
*/ */
void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr) void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
{ {
au8ChSelect[u32Ch] = (uint8_t)u32Peripheral; if (u32Ch < PDMA_CH_MAX)
switch(u32Ch)
{ {
case 0UL: __IO uint32_t *pau32REQSEL = (__IO uint32_t *)&pdma->REQSEL0_3;
(pdma)->REQSEL0_3 = ((pdma)->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC0_Msk) | u32Peripheral; uint32_t u32REQSEL_Pos, u32REQSEL_Msk;
break;
case 1UL:
(pdma)->REQSEL0_3 = ((pdma)->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC1_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC1_Pos);
break;
case 2UL:
(pdma)->REQSEL0_3 = ((pdma)->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC2_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC2_Pos);
break;
case 3UL:
(pdma)->REQSEL0_3 = ((pdma)->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC3_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC3_Pos);
break;
case 4UL:
(pdma)->REQSEL4_7 = ((pdma)->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC4_Msk) | u32Peripheral;
break;
case 5UL:
(pdma)->REQSEL4_7 = ((pdma)->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC5_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC5_Pos);
break;
case 6UL:
(pdma)->REQSEL4_7 = ((pdma)->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC6_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC6_Pos);
break;
case 7UL:
(pdma)->REQSEL4_7 = ((pdma)->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC7_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC7_Pos);
break;
default:
break;
}
if(u32ScatterEn) u32REQSEL_Pos = (u32Ch % 4) * 8 ;
{ u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
(pdma)->DSCT[u32Ch].CTL = ((pdma)->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER; pau32REQSEL[u32Ch / 4] = (pau32REQSEL[u32Ch / 4] & ~u32REQSEL_Msk) | (u32Peripheral << u32REQSEL_Pos);
(pdma)->DSCT[u32Ch].NEXT = u32DescAddr - ((pdma)->SCATBA);
} if (u32ScatterEn)
else {
{ pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER;
(pdma)->DSCT[u32Ch].CTL = ((pdma)->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC; pdma->DSCT[u32Ch].NEXT = u32DescAddr - (pdma->SCATBA);
}
else
{
pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC;
}
} }
else {}
} }
/** /**
...@@ -294,30 +271,31 @@ void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, ...@@ -294,30 +271,31 @@ void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral,
*/ */
void PDMA_SetBurstType(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize) void PDMA_SetBurstType(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize)
{ {
(pdma)->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXTYPE_Msk | PDMA_DSCT_CTL_BURSIZE_Msk); pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXTYPE_Msk | PDMA_DSCT_CTL_BURSIZE_Msk);
(pdma)->DSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize); pdma->DSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize);
} }
/** /**
* @brief Enable timeout function * @brief Enable timeout function
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
*
* @param[in] u32Mask Channel enable bits. * @param[in] u32Mask Channel enable bits.
* *
* @return None * @return None
* *
* @details This function enable timeout function of the selected channel(s). * @details This function enable timeout function of the selected channel(s).
* @note This function is only supported in channel 0 and channel 1.
*/ */
void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask) void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask)
{ {
(pdma)->TOUTEN |= u32Mask; pdma->TOUTEN |= u32Mask;
} }
/** /**
* @brief Disable timeout function * @brief Disable timeout function
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
*
* @param[in] u32Mask Channel enable bits. * @param[in] u32Mask Channel enable bits.
* *
* @return None * @return None
...@@ -327,7 +305,7 @@ void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask) ...@@ -327,7 +305,7 @@ void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask)
*/ */
void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask) void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask)
{ {
(pdma)->TOUTEN &= ~u32Mask; pdma->TOUTEN &= ~u32Mask;
} }
/** /**
...@@ -335,7 +313,7 @@ void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask) ...@@ -335,7 +313,7 @@ void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask)
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel * @param[in] u32Ch The selected channel
* @param[in] u32OnOff Enable/disable timeout function * @param[in] u32OnOff Enable/disable time out function
* @param[in] u32TimeOutCnt Timeout count * @param[in] u32TimeOutCnt Timeout count
* *
* @return None * @return None
...@@ -345,26 +323,21 @@ void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask) ...@@ -345,26 +323,21 @@ void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask)
*/ */
void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt) void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt)
{ {
switch(u32Ch) if (u32Ch < 2)
{
case 0UL:
(pdma)->TOC0_1 = ((pdma)->TOC0_1 & ~PDMA_TOC0_1_TOC0_Msk) | u32TimeOutCnt;
break;
case 1UL:
(pdma)->TOC0_1 = ((pdma)->TOC0_1 & ~PDMA_TOC0_1_TOC1_Msk) | (u32TimeOutCnt << PDMA_TOC0_1_TOC1_Pos);
break;
default:
break;
}
if(u32OnOff)
{ {
(pdma)->TOUTEN |= (1UL << u32Ch); __IO uint32_t *pau32TOC = (__IO uint32_t *)&pdma->TOC0_1;
} uint32_t u32TOC_Pos, u32TOC_Msk;
else
{ u32TOC_Pos = (u32Ch % 2) * 16 ;
(pdma)->TOUTEN &= ~(1UL << u32Ch); u32TOC_Msk = PDMA_TOC0_1_TOC0_Msk << u32TOC_Pos;
pau32TOC[u32Ch / 2] = (pau32TOC[u32Ch / 2] & ~u32TOC_Msk) | (u32TimeOutCnt << u32TOC_Pos);
if (u32OnOff)
pdma->TOUTEN |= (1 << u32Ch);
else
pdma->TOUTEN &= ~(1 << u32Ch);
} }
else {}
} }
/** /**
...@@ -379,10 +352,19 @@ void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u ...@@ -379,10 +352,19 @@ void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u
*/ */
void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch) void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch)
{ {
if(au8ChSelect[u32Ch] == PDMA_MEM) __IO uint32_t *pau32REQSEL = (__IO uint32_t *)&pdma->REQSEL0_3;
uint32_t u32REQSEL_Pos, u32REQSEL_Msk, u32ChReq;
u32REQSEL_Pos = (u32Ch % 4) * 8 ;
u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
u32ChReq = (pau32REQSEL[u32Ch / 4] & u32REQSEL_Msk) >> u32REQSEL_Pos;
if (u32ChReq == PDMA_MEM)
{ {
(pdma)->SWREQ = (1UL << u32Ch); pdma->SWREQ = (1ul << u32Ch);
} }
else {}
} }
/** /**
...@@ -403,21 +385,21 @@ void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch) ...@@ -403,21 +385,21 @@ void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch)
*/ */
void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask) void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
{ {
switch(u32Mask) switch (u32Mask)
{ {
case PDMA_INT_TRANS_DONE: case PDMA_INT_TRANS_DONE:
case PDMA_INT_ALIGN: case PDMA_INT_ALIGN:
(pdma)->INTEN |= (1UL << u32Ch); (pdma)->INTEN |= (1UL << u32Ch);
break; break;
case PDMA_INT_TABLE: case PDMA_INT_TABLE:
(pdma)->DSCT[u32Ch].CTL &= ~PDMA_DSCT_CTL_TBINTDIS_Msk; (pdma)->DSCT[u32Ch].CTL &= ~PDMA_DSCT_CTL_TBINTDIS_Msk;
break; break;
case PDMA_INT_TIMEOUT: case PDMA_INT_TIMEOUT:
(pdma)->TOUTIEN |= (1UL << u32Ch); (pdma)->TOUTIEN |= (1UL << u32Ch);
break; break;
default: default:
break; break;
} }
} }
...@@ -440,21 +422,21 @@ void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask) ...@@ -440,21 +422,21 @@ void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
*/ */
void PDMA_DisableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask) void PDMA_DisableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
{ {
switch(u32Mask) switch (u32Mask)
{ {
case PDMA_INT_TRANS_DONE: case PDMA_INT_TRANS_DONE:
case PDMA_INT_ALIGN: case PDMA_INT_ALIGN:
(pdma)->INTEN &= ~(1UL << u32Ch); (pdma)->INTEN &= ~(1UL << u32Ch);
break; break;
case PDMA_INT_TABLE: case PDMA_INT_TABLE:
(pdma)->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_TBINTDIS_Msk; (pdma)->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_TBINTDIS_Msk;
break; break;
case PDMA_INT_TIMEOUT: case PDMA_INT_TIMEOUT:
(pdma)->TOUTIEN &= ~(1UL << u32Ch); (pdma)->TOUTIEN &= ~(1UL << u32Ch);
break; break;
default: default:
break; break;
} }
} }
......
...@@ -214,7 +214,7 @@ static void nu_pdma_init(void) ...@@ -214,7 +214,7 @@ static void nu_pdma_init(void)
RT_ASSERT(g_mutex_sg != RT_NULL); RT_ASSERT(g_mutex_sg != RT_NULL);
nu_pdma_chn_mask = ~(NU_PDMA_CH_Msk); nu_pdma_chn_mask = ~(NU_PDMA_CH_Msk);
rt_memset(nu_pdma_chn_arr, 0x00, NU_PDMA_CH_MAX*sizeof(nu_pdma_chn_t)); rt_memset(nu_pdma_chn_arr, 0x00, NU_PDMA_CH_MAX * sizeof(nu_pdma_chn_t));
/* Initialize PDMA0 setting */ /* Initialize PDMA0 setting */
PDMA_Open(PDMA0, NU_PDMA_CH_HALF_Msk); PDMA_Open(PDMA0, NU_PDMA_CH_HALF_Msk);
...@@ -609,11 +609,13 @@ static void nu_pdma_sgtbls_token_free(nu_pdma_desc_t psSgtbls) ...@@ -609,11 +609,13 @@ static void nu_pdma_sgtbls_token_free(nu_pdma_desc_t psSgtbls)
rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num) rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num)
{ {
int i, j, idx; int i, j, idx;
rt_err_t result;
RT_ASSERT(ppsSgtbls != NULL); RT_ASSERT(ppsSgtbls != NULL);
RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE); RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE);
rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER); result = rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
...@@ -628,7 +630,8 @@ rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num) ...@@ -628,7 +630,8 @@ rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num)
ppsSgtbls[i] = (nu_pdma_desc_t)&nu_pdma_sgtbl_arr[idx]; ppsSgtbls[i] = (nu_pdma_desc_t)&nu_pdma_sgtbl_arr[idx];
} }
rt_mutex_release(g_mutex_sg); result = rt_mutex_release(g_mutex_sg);
RT_ASSERT(result == RT_EOK);
return RT_EOK; return RT_EOK;
...@@ -644,18 +647,22 @@ fail_nu_pdma_sgtbls_allocate: ...@@ -644,18 +647,22 @@ fail_nu_pdma_sgtbls_allocate:
ppsSgtbls[j] = NULL; ppsSgtbls[j] = NULL;
} }
rt_mutex_release(g_mutex_sg); result = rt_mutex_release(g_mutex_sg);
RT_ASSERT(result == RT_EOK);
return -RT_ERROR; return -RT_ERROR;
} }
void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num) void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num)
{ {
int i; int i;
rt_err_t result;
RT_ASSERT(ppsSgtbls != NULL); RT_ASSERT(ppsSgtbls != NULL);
RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE); RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE);
rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER); result = rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
...@@ -666,7 +673,8 @@ void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num) ...@@ -666,7 +673,8 @@ void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num)
ppsSgtbls[i] = NULL; ppsSgtbls[i] = NULL;
} }
rt_mutex_release(g_mutex_sg); result = rt_mutex_release(g_mutex_sg);
RT_ASSERT(result == RT_EOK);
} }
static rt_err_t nu_pdma_sgtbls_valid(nu_pdma_desc_t head) static rt_err_t nu_pdma_sgtbls_valid(nu_pdma_desc_t head)
...@@ -881,6 +889,7 @@ static void nu_pdma_memfun_actor_init(void) ...@@ -881,6 +889,7 @@ static void nu_pdma_memfun_actor_init(void)
if (-(RT_ERROR) != (nu_pdma_memfun_actor_arr[i].m_i32ChannID = nu_pdma_channel_allocate(PDMA_MEM))) if (-(RT_ERROR) != (nu_pdma_memfun_actor_arr[i].m_i32ChannID = nu_pdma_channel_allocate(PDMA_MEM)))
{ {
nu_pdma_memfun_actor_arr[i].m_psSemMemFun = rt_sem_create("memactor_sem", 0, RT_IPC_FLAG_FIFO); nu_pdma_memfun_actor_arr[i].m_psSemMemFun = rt_sem_create("memactor_sem", 0, RT_IPC_FLAG_FIFO);
RT_ASSERT(nu_pdma_memfun_actor_arr[i].m_psSemMemFun != RT_NULL);
} }
else else
break; break;
...@@ -889,16 +898,23 @@ static void nu_pdma_memfun_actor_init(void) ...@@ -889,16 +898,23 @@ static void nu_pdma_memfun_actor_init(void)
{ {
nu_pdma_memfun_actor_maxnum = i; nu_pdma_memfun_actor_maxnum = i;
nu_pdma_memfun_actor_mask = ~(((1 << i) - 1)); nu_pdma_memfun_actor_mask = ~(((1 << i) - 1));
nu_pdma_memfun_actor_pool_sem = rt_sem_create("mempool_sem", nu_pdma_memfun_actor_maxnum, RT_IPC_FLAG_FIFO); nu_pdma_memfun_actor_pool_sem = rt_sem_create("mempool_sem", nu_pdma_memfun_actor_maxnum, RT_IPC_FLAG_FIFO);
RT_ASSERT(nu_pdma_memfun_actor_pool_sem != RT_NULL);
nu_pdma_memfun_actor_pool_lock = rt_mutex_create("mempool_lock", RT_IPC_FLAG_PRIO); nu_pdma_memfun_actor_pool_lock = rt_mutex_create("mempool_lock", RT_IPC_FLAG_PRIO);
RT_ASSERT(nu_pdma_memfun_actor_pool_lock != RT_NULL);
} }
} }
static void nu_pdma_memfun_cb(void *pvUserData, uint32_t u32Events) static void nu_pdma_memfun_cb(void *pvUserData, uint32_t u32Events)
{ {
rt_err_t result;
nu_pdma_memfun_actor_t psMemFunActor = (nu_pdma_memfun_actor_t)pvUserData; nu_pdma_memfun_actor_t psMemFunActor = (nu_pdma_memfun_actor_t)pvUserData;
psMemFunActor->m_u32Result = u32Events; psMemFunActor->m_u32Result = u32Events;
rt_sem_release(psMemFunActor->m_psSemMemFun); result = rt_sem_release(psMemFunActor->m_psSemMemFun);
RT_ASSERT(result == RT_EOK);
} }
static int nu_pdma_memfun_employ(void) static int nu_pdma_memfun_employ(void)
...@@ -908,7 +924,10 @@ static int nu_pdma_memfun_employ(void) ...@@ -908,7 +924,10 @@ static int nu_pdma_memfun_employ(void)
/* Headhunter */ /* Headhunter */
if (nu_pdma_memfun_actor_pool_sem && (rt_sem_take(nu_pdma_memfun_actor_pool_sem, RT_WAITING_FOREVER) == RT_EOK)) if (nu_pdma_memfun_actor_pool_sem && (rt_sem_take(nu_pdma_memfun_actor_pool_sem, RT_WAITING_FOREVER) == RT_EOK))
{ {
rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER); rt_err_t result;
result = rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
/* Find the position of first '0' in nu_pdma_memfun_actor_mask. */ /* Find the position of first '0' in nu_pdma_memfun_actor_mask. */
idx = nu_cto(nu_pdma_memfun_actor_mask); idx = nu_cto(nu_pdma_memfun_actor_mask);
if (idx != 32) if (idx != 32)
...@@ -919,7 +938,8 @@ static int nu_pdma_memfun_employ(void) ...@@ -919,7 +938,8 @@ static int nu_pdma_memfun_employ(void)
{ {
idx = -1; idx = -1;
} }
rt_mutex_release(nu_pdma_memfun_actor_pool_lock); result = rt_mutex_release(nu_pdma_memfun_actor_pool_lock);
RT_ASSERT(result == RT_EOK);
} }
return idx; return idx;
...@@ -935,6 +955,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un ...@@ -935,6 +955,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
while (1) while (1)
{ {
rt_err_t result;
/* Employ actor */ /* Employ actor */
if ((idx = nu_pdma_memfun_employ()) < 0) if ((idx = nu_pdma_memfun_employ()) < 0)
continue; continue;
...@@ -963,7 +985,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un ...@@ -963,7 +985,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
0); 0);
/* Wait it done. */ /* Wait it done. */
rt_sem_take(psMemFunActor->m_psSemMemFun, RT_WAITING_FOREVER); result = rt_sem_take(psMemFunActor->m_psSemMemFun, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
/* Give result if get NU_PDMA_EVENT_TRANSFER_DONE.*/ /* Give result if get NU_PDMA_EVENT_TRANSFER_DONE.*/
if (psMemFunActor->m_u32Result & NU_PDMA_EVENT_TRANSFER_DONE) if (psMemFunActor->m_u32Result & NU_PDMA_EVENT_TRANSFER_DONE)
...@@ -983,16 +1006,20 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un ...@@ -983,16 +1006,20 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
} }
u32TransferCnt -= u32TxCnt; u32TransferCnt -= u32TxCnt;
u32Offset += u32TxCnt; u32Offset += u32TxCnt * (u32DataWidth / 8);
} }
while (u32TransferCnt > 0); while (u32TransferCnt > 0);
rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER); result = rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
nu_pdma_memfun_actor_mask &= ~(1 << idx); nu_pdma_memfun_actor_mask &= ~(1 << idx);
rt_mutex_release(nu_pdma_memfun_actor_pool_lock); result = rt_mutex_release(nu_pdma_memfun_actor_pool_lock);
RT_ASSERT(result == RT_EOK);
/* Fire actor */ /* Fire actor */
rt_sem_release(nu_pdma_memfun_actor_pool_sem); result = rt_sem_release(nu_pdma_memfun_actor_pool_sem);
RT_ASSERT(result == RT_EOK);
break; break;
} }
......
...@@ -156,11 +156,13 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, ...@@ -156,11 +156,13 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device,
uint32_t u32SPIMode; uint32_t u32SPIMode;
uint32_t u32BusClock; uint32_t u32BusClock;
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL); RT_ASSERT(configuration != RT_NULL);
spi_bus = (struct nu_spi *) device->bus; spi_bus = (struct nu_spi *) device->bus;
pvUserData = device->parent.user_data;
/* Check mode */ /* Check mode */
switch (configuration->mode & RT_SPI_MODE_3) switch (configuration->mode & RT_SPI_MODE_3)
...@@ -210,12 +212,29 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, ...@@ -210,12 +212,29 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device,
if (configuration->mode & RT_SPI_CS_HIGH) if (configuration->mode & RT_SPI_CS_HIGH)
{ {
/* Set CS pin to LOW */ /* Set CS pin to LOW */
SPI_SET_SS_LOW(spi_bus->spi_base); if (pvUserData != RT_NULL)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
} }
else else
{ {
/* Set CS pin to HIGH */ /* Set CS pin to HIGH */
SPI_SET_SS_HIGH(spi_bus->spi_base); if (pvUserData != RT_NULL)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
/* Set CS pin to HIGH */
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
} }
if (configuration->mode & RT_SPI_MSB) if (configuration->mode & RT_SPI_MSB)
...@@ -574,6 +593,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -574,6 +593,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
struct nu_spi *spi_bus; struct nu_spi *spi_bus;
struct rt_spi_configuration *configuration; struct rt_spi_configuration *configuration;
uint8_t bytes_per_word; uint8_t bytes_per_word;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus != RT_NULL);
...@@ -582,6 +602,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -582,6 +602,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
spi_bus = (struct nu_spi *) device->bus; spi_bus = (struct nu_spi *) device->bus;
configuration = (struct rt_spi_configuration *)&spi_bus->configuration; configuration = (struct rt_spi_configuration *)&spi_bus->configuration;
bytes_per_word = configuration->data_width / 8; bytes_per_word = configuration->data_width / 8;
pvUserData = device->parent.user_data;
if ((message->length % bytes_per_word) != 0) if ((message->length % bytes_per_word) != 0)
{ {
...@@ -594,13 +615,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -594,13 +615,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
{ {
if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
SPI_SET_SS_HIGH(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
} }
else else
{ {
SPI_SET_SS_LOW(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
else
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
} }
} }
...@@ -608,13 +645,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -608,13 +645,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
SPI_SET_SS_LOW(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
} }
else else
{ {
SPI_SET_SS_HIGH(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
else
{
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
} }
} }
......
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
#include <drv_pdma.h> #include <drv_pdma.h>
#endif #endif
/* Private define ---------------------------------------------------------------*/ /* Private define ---------------------------------------------------------------*/
#ifndef NU_SPI_USE_PDMA_MIN_THRESHOLD
#define NU_SPI_USE_PDMA_MIN_THRESHOLD (128)
#endif
enum enum
{ {
USPI_START = -1, USPI_START = -1,
...@@ -131,11 +136,13 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device, ...@@ -131,11 +136,13 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device,
uint32_t u32SPIMode; uint32_t u32SPIMode;
uint32_t u32BusClock; uint32_t u32BusClock;
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL); RT_ASSERT(configuration != RT_NULL);
uspi_bus = (struct nu_uspi *) device->bus; uspi_bus = (struct nu_uspi *) device->bus;
pvUserData = device->parent.user_data;
/* Check mode */ /* Check mode */
switch (configuration->mode & RT_SPI_MODE_3) switch (configuration->mode & RT_SPI_MODE_3)
...@@ -183,12 +190,29 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device, ...@@ -183,12 +190,29 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device,
if (configuration->mode & RT_SPI_CS_HIGH) if (configuration->mode & RT_SPI_CS_HIGH)
{ {
/* Set CS pin to LOW */ /* Set CS pin to LOW */
USPI_SET_SS_LOW(uspi_bus->uspi_base); if (pvUserData != RT_NULL)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
USPI_SET_SS_LOW(uspi_bus->uspi_base);
}
} }
else else
{ {
/* Set CS pin to HIGH */ /* Set CS pin to HIGH */
USPI_SET_SS_HIGH(uspi_bus->uspi_base); if (pvUserData != RT_NULL)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
/* Set CS pin to HIGH */
USPI_SET_SS_HIGH(uspi_bus->uspi_base);
}
} }
if (configuration->mode & RT_SPI_MSB) if (configuration->mode & RT_SPI_MSB)
...@@ -319,27 +343,40 @@ exit_nu_pdma_uspi_tx_config: ...@@ -319,27 +343,40 @@ exit_nu_pdma_uspi_tx_config:
**/ **/
static rt_size_t nu_uspi_pdma_transmit(struct nu_uspi *uspi_bus, const uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word) static rt_size_t nu_uspi_pdma_transmit(struct nu_uspi *uspi_bus, const uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word)
{ {
rt_err_t result; rt_err_t result = RT_EOK;
rt_uint32_t u32Offset = 0;
rt_uint32_t u32TransferCnt = length / bytes_per_word;
rt_uint32_t u32TxCnt = 0;
/* Get base address of uspi register */ /* Get base address of uspi register */
USPI_T *uspi_base = uspi_bus->uspi_base; USPI_T *uspi_base = uspi_bus->uspi_base;
result = nu_pdma_uspi_rx_config(uspi_bus, recv_addr, length, bytes_per_word); do
RT_ASSERT(result == RT_EOK); {
result = nu_pdma_uspi_tx_config(uspi_bus, send_addr, length, bytes_per_word); u32TxCnt = (u32TransferCnt > NU_PDMA_MAX_TXCNT) ? NU_PDMA_MAX_TXCNT : u32TransferCnt;
RT_ASSERT(result == RT_EOK); result = nu_pdma_uspi_rx_config(uspi_bus, (recv_addr == RT_NULL) ? recv_addr : &recv_addr[u32Offset], (u32TxCnt * bytes_per_word), bytes_per_word);
RT_ASSERT(result == RT_EOK);
/* Trigger TX/RX at the same time. */ result = nu_pdma_uspi_tx_config(uspi_bus, (send_addr == RT_NULL) ? send_addr : &send_addr[u32Offset], (u32TxCnt * bytes_per_word), bytes_per_word);
USPI_TRIGGER_TX_RX_PDMA(uspi_base); RT_ASSERT(result == RT_EOK);
/* Wait PDMA transfer done */ /* Trigger TX/RX PDMA transfer. */
result = rt_sem_take(uspi_bus->m_psSemBus, RT_WAITING_FOREVER); USPI_TRIGGER_TX_RX_PDMA(uspi_base);
RT_ASSERT(result == RT_EOK);
/* Stop DMA TX/RX transfer */ /* Wait RX-PDMA transfer done */
USPI_DISABLE_TX_RX_PDMA(uspi_base); result = rt_sem_take(uspi_bus->m_psSemBus, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
return result; /* Stop TX/RX DMA transfer. */
USPI_DISABLE_TX_RX_PDMA(uspi_base);
u32TransferCnt -= u32TxCnt;
u32Offset += u32TxCnt;
}
while (u32TransferCnt > 0);
return length;
} }
static rt_err_t nu_hw_uspi_pdma_allocate(struct nu_uspi *uspi_bus) static rt_err_t nu_hw_uspi_pdma_allocate(struct nu_uspi *uspi_bus)
...@@ -504,11 +541,14 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus, ...@@ -504,11 +541,14 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus,
static void nu_uspi_transfer(struct nu_uspi *uspi_bus, uint8_t *tx, uint8_t *rx, int length, uint8_t bytes_per_word) static void nu_uspi_transfer(struct nu_uspi *uspi_bus, uint8_t *tx, uint8_t *rx, int length, uint8_t bytes_per_word)
{ {
RT_ASSERT(uspi_bus != RT_NULL);
#if defined(BSP_USING_USPI_PDMA) #if defined(BSP_USING_USPI_PDMA)
/* PDMA transfer constrains */ /* PDMA transfer constrains */
if ((uspi_bus->pdma_chanid_rx >= 0) && if ((uspi_bus->pdma_chanid_rx >= 0) &&
(!((uint32_t)tx % bytes_per_word)) && !((uint32_t)tx % bytes_per_word) &&
(!((uint32_t)rx % bytes_per_word))) !((uint32_t)rx % bytes_per_word) &&
(length >= NU_SPI_USE_PDMA_MIN_THRESHOLD))
nu_uspi_pdma_transmit(uspi_bus, tx, rx, length, bytes_per_word); nu_uspi_pdma_transmit(uspi_bus, tx, rx, length, bytes_per_word);
else else
nu_uspi_transmission_with_poll(uspi_bus, tx, rx, length, bytes_per_word); nu_uspi_transmission_with_poll(uspi_bus, tx, rx, length, bytes_per_word);
...@@ -522,6 +562,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -522,6 +562,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
struct nu_uspi *uspi_bus; struct nu_uspi *uspi_bus;
struct rt_spi_configuration *configuration; struct rt_spi_configuration *configuration;
uint8_t bytes_per_word; uint8_t bytes_per_word;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus != RT_NULL);
...@@ -530,6 +571,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -530,6 +571,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
uspi_bus = (struct nu_uspi *) device->bus; uspi_bus = (struct nu_uspi *) device->bus;
configuration = &uspi_bus->configuration; configuration = &uspi_bus->configuration;
bytes_per_word = configuration->data_width / 8; bytes_per_word = configuration->data_width / 8;
pvUserData = device->parent.user_data;
if ((message->length % bytes_per_word) != 0) if ((message->length % bytes_per_word) != 0)
{ {
...@@ -542,13 +584,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -542,13 +584,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
{ {
if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
USPI_SET_SS_HIGH(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
} }
else else
{ {
USPI_SET_SS_LOW(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
USPI_SET_SS_HIGH(uspi_bus->uspi_base);
}
else
{
USPI_SET_SS_LOW(uspi_bus->uspi_base);
}
} }
} }
...@@ -556,13 +614,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -556,13 +614,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
USPI_SET_SS_LOW(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
} }
else else
{ {
USPI_SET_SS_HIGH(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
USPI_SET_SS_LOW(uspi_bus->uspi_base);
}
else
{
USPI_SET_SS_HIGH(uspi_bus->uspi_base);
}
} }
} }
......
...@@ -8,9 +8,6 @@ ...@@ -8,9 +8,6 @@
*****************************************************************************/ *****************************************************************************/
#include "NuMicro.h" #include "NuMicro.h"
static uint8_t u32ChSelect[PDMA_CH_MAX];
/** @addtogroup Standard_Driver Standard Driver /** @addtogroup Standard_Driver Standard Driver
@{ @{
*/ */
...@@ -35,16 +32,15 @@ static uint8_t u32ChSelect[PDMA_CH_MAX]; ...@@ -35,16 +32,15 @@ static uint8_t u32ChSelect[PDMA_CH_MAX];
* *
* @details This function enable the PDMA channels. * @details This function enable the PDMA channels.
*/ */
void PDMA_Open(PDMA_T * pdma,uint32_t u32Mask) void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask)
{ {
uint32_t i; uint32_t i;
for (i=0UL; i<PDMA_CH_MAX; i++) for (i = 0UL; i < PDMA_CH_MAX; i++)
{ {
if((1 << i) & u32Mask) if ((1 << i) & u32Mask)
{ {
pdma->DSCT[i].CTL = 0UL; pdma->DSCT[i].CTL = 0UL;
u32ChSelect[i] = PDMA_MEM;
} }
} }
...@@ -60,7 +56,7 @@ void PDMA_Open(PDMA_T * pdma,uint32_t u32Mask) ...@@ -60,7 +56,7 @@ void PDMA_Open(PDMA_T * pdma,uint32_t u32Mask)
* *
* @details This function disable all PDMA channels. * @details This function disable all PDMA channels.
*/ */
void PDMA_Close(PDMA_T * pdma) void PDMA_Close(PDMA_T *pdma)
{ {
pdma->CHCTL = 0UL; pdma->CHCTL = 0UL;
} }
...@@ -80,7 +76,7 @@ void PDMA_Close(PDMA_T * pdma) ...@@ -80,7 +76,7 @@ void PDMA_Close(PDMA_T * pdma)
* *
* @details This function set the selected channel data width and transfer count. * @details This function set the selected channel data width and transfer count.
*/ */
void PDMA_SetTransferCnt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount) void PDMA_SetTransferCnt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount)
{ {
pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXCNT_Msk | PDMA_DSCT_CTL_TXWIDTH_Msk); pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXCNT_Msk | PDMA_DSCT_CTL_TXWIDTH_Msk);
pdma->DSCT[u32Ch].CTL |= (u32Width | ((u32TransCount - 1UL) << PDMA_DSCT_CTL_TXCNT_Pos)); pdma->DSCT[u32Ch].CTL |= (u32Width | ((u32TransCount - 1UL) << PDMA_DSCT_CTL_TXCNT_Pos));
...@@ -88,7 +84,7 @@ void PDMA_SetTransferCnt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Width, uint32 ...@@ -88,7 +84,7 @@ void PDMA_SetTransferCnt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Width, uint32
/** /**
* @brief Set PDMA Stride Mode * @brief Set PDMA Stride Mode
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel * @param[in] u32Ch The selected channel
* @param[in] u32DestLen Destination stride count * @param[in] u32DestLen Destination stride count
...@@ -99,11 +95,11 @@ void PDMA_SetTransferCnt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Width, uint32 ...@@ -99,11 +95,11 @@ void PDMA_SetTransferCnt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Width, uint32
* *
* @details This function set the selected stride mode. * @details This function set the selected stride mode.
*/ */
void PDMA_SetStride(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32DestLen, uint32_t u32SrcLen, uint32_t u32TransCount) void PDMA_SetStride(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32DestLen, uint32_t u32SrcLen, uint32_t u32TransCount)
{ {
pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDEEN_Msk; (pdma)->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDEEN_Msk;
pdma->STRIDE[u32Ch].ASOCR =((u32DestLen-1)<<16) | (u32SrcLen-1); (pdma)->STRIDE[u32Ch].ASOCR = (u32DestLen << 16) | u32SrcLen;
pdma->STRIDE[u32Ch].STCR = u32TransCount-1; (pdma)->STRIDE[u32Ch].STCR = u32TransCount;
} }
/** /**
...@@ -119,24 +115,24 @@ void PDMA_SetStride(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32DestLen, uint32_t ...@@ -119,24 +115,24 @@ void PDMA_SetStride(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32DestLen, uint32_t
* *
* @details This function set the selected repeat. * @details This function set the selected repeat.
*/ */
void PDMA_SetRepeat(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32DestInterval, uint32_t u32SrcInterval, uint32_t u32RepeatCount) void PDMA_SetRepeat(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32DestInterval, uint32_t u32SrcInterval, uint32_t u32RepeatCount)
{ {
pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDEEN_Msk; pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDEEN_Msk;
pdma->REPEAT[u32Ch].AICTL =((u32DestInterval)<<16) | (u32SrcInterval); pdma->REPEAT[u32Ch].AICTL = ((u32DestInterval) << 16) | (u32SrcInterval);
pdma->REPEAT[u32Ch].RCNT = u32RepeatCount; pdma->REPEAT[u32Ch].RCNT = u32RepeatCount;
} }
/** /**
* @brief Set PDMA Transfer Address * @brief Set PDMA Transfer Address
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel * @param[in] u32Ch The selected channel
* @param[in] u32SrcAddr Source address * @param[in] u32SrcAddr Source address
* @param[in] u32SrcCtrl Source control attribute. Valid values are * @param[in] u32SrcCtrl Source control attribute. Valid values are
* - \ref PDMA_SAR_INC * - \ref PDMA_SAR_INC
* - \ref PDMA_SAR_FIX * - \ref PDMA_SAR_FIX
* @param[in] u32DstAddr destination address * @param[in] u32DstAddr Destination address
* @param[in] u32DstCtrl destination control attribute. Valid values are * @param[in] u32DstCtrl Destination control attribute. Valid values are
* - \ref PDMA_DAR_INC * - \ref PDMA_DAR_INC
* - \ref PDMA_DAR_FIX * - \ref PDMA_DAR_FIX
* *
...@@ -144,7 +140,7 @@ void PDMA_SetRepeat(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32DestInterval, uint ...@@ -144,7 +140,7 @@ void PDMA_SetRepeat(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32DestInterval, uint
* *
* @details This function set the selected channel source/destination address and attribute. * @details This function set the selected channel source/destination address and attribute.
*/ */
void PDMA_SetTransferAddr(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl) void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl)
{ {
pdma->DSCT[u32Ch].SA = u32SrcAddr; pdma->DSCT[u32Ch].SA = u32SrcAddr;
pdma->DSCT[u32Ch].DA = u32DstAddr; pdma->DSCT[u32Ch].DA = u32DstAddr;
...@@ -154,7 +150,7 @@ void PDMA_SetTransferAddr(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32SrcAddr, uin ...@@ -154,7 +150,7 @@ void PDMA_SetTransferAddr(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32SrcAddr, uin
/** /**
* @brief Set PDMA Transfer Mode * @brief Set PDMA Transfer Mode
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel * @param[in] u32Ch The selected channel
* @param[in] u32Peripheral The selected peripheral. Valid values are * @param[in] u32Peripheral The selected peripheral. Valid values are
...@@ -232,72 +228,28 @@ void PDMA_SetTransferAddr(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32SrcAddr, uin ...@@ -232,72 +228,28 @@ void PDMA_SetTransferAddr(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32SrcAddr, uin
* *
* @details This function set the selected channel transfer mode. Include peripheral setting. * @details This function set the selected channel transfer mode. Include peripheral setting.
*/ */
void PDMA_SetTransferMode(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr) void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
{ {
u32ChSelect[u32Ch] = u32Peripheral; if (u32Ch < PDMA_CH_MAX)
switch(u32Ch)
{ {
case 0ul: __IO uint32_t *pau32REQSEL = (__IO uint32_t *)&pdma->REQSEL0_3;
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC0_Msk) | u32Peripheral; uint32_t u32REQSEL_Pos, u32REQSEL_Msk;
break;
case 1ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC1_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC1_Pos);
break;
case 2ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC2_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC2_Pos);
break;
case 3ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC3_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC3_Pos);
break;
case 4ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC4_Msk) | u32Peripheral;
break;
case 5ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC5_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC5_Pos);
break;
case 6ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC6_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC6_Pos);
break;
case 7ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC7_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC7_Pos);
break;
case 8ul:
pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC8_Msk) | u32Peripheral;
break;
case 9ul:
pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC9_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC9_Pos);
break;
case 10ul:
pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC10_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC10_Pos);
break;
case 11ul:
pdma->REQSEL8_11 = (pdma->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC11_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC11_Pos);
break;
case 12ul:
pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC12_Msk) | u32Peripheral;
break;
case 13ul:
pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC13_Msk) | (u32Peripheral << PDMA_REQSEL12_15_REQSRC13_Pos);
break;
case 14ul:
pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC14_Msk) | (u32Peripheral << PDMA_REQSEL12_15_REQSRC14_Pos);
break;
case 15ul:
pdma->REQSEL12_15 = (pdma->REQSEL12_15 & ~PDMA_REQSEL12_15_REQSRC15_Msk) | (u32Peripheral << PDMA_REQSEL12_15_REQSRC15_Pos);
break;
default:
break;
}
if(u32ScatterEn) u32REQSEL_Pos = (u32Ch % 4) * 8 ;
{ u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER; pau32REQSEL[u32Ch / 4] = (pau32REQSEL[u32Ch / 4] & ~u32REQSEL_Msk) | (u32Peripheral << u32REQSEL_Pos);
pdma->DSCT[u32Ch].NEXT = u32DescAddr - (PDMA->SCATBA);
} if (u32ScatterEn)
else {
{ pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER;
pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC; pdma->DSCT[u32Ch].NEXT = u32DescAddr - (pdma->SCATBA);
}
else
{
pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC;
}
} }
else {}
} }
/** /**
...@@ -322,7 +274,7 @@ void PDMA_SetTransferMode(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Peripheral, ...@@ -322,7 +274,7 @@ void PDMA_SetTransferMode(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Peripheral,
* *
* @details This function set the selected channel burst type and size. * @details This function set the selected channel burst type and size.
*/ */
void PDMA_SetBurstType(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize) void PDMA_SetBurstType(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize)
{ {
pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXTYPE_Msk | PDMA_DSCT_CTL_BURSIZE_Msk); pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXTYPE_Msk | PDMA_DSCT_CTL_BURSIZE_Msk);
pdma->DSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize); pdma->DSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize);
...@@ -339,7 +291,7 @@ void PDMA_SetBurstType(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32BurstType, uint ...@@ -339,7 +291,7 @@ void PDMA_SetBurstType(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32BurstType, uint
* *
* @details This function enable timeout function of the selected channel(s). * @details This function enable timeout function of the selected channel(s).
*/ */
void PDMA_EnableTimeout(PDMA_T * pdma,uint32_t u32Mask) void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask)
{ {
pdma->TOUTEN |= u32Mask; pdma->TOUTEN |= u32Mask;
} }
...@@ -355,7 +307,7 @@ void PDMA_EnableTimeout(PDMA_T * pdma,uint32_t u32Mask) ...@@ -355,7 +307,7 @@ void PDMA_EnableTimeout(PDMA_T * pdma,uint32_t u32Mask)
* *
* @details This function disable timeout function of the selected channel(s). * @details This function disable timeout function of the selected channel(s).
*/ */
void PDMA_DisableTimeout(PDMA_T * pdma,uint32_t u32Mask) void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask)
{ {
pdma->TOUTEN &= ~u32Mask; pdma->TOUTEN &= ~u32Mask;
} }
...@@ -364,7 +316,7 @@ void PDMA_DisableTimeout(PDMA_T * pdma,uint32_t u32Mask) ...@@ -364,7 +316,7 @@ void PDMA_DisableTimeout(PDMA_T * pdma,uint32_t u32Mask)
* @brief Set PDMA Timeout Count * @brief Set PDMA Timeout Count
* *
* @param[in] pdma The pointer of the specified PDMA module * @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel, * @param[in] u32Ch The selected channel
* @param[in] u32OnOff Enable/disable time out function * @param[in] u32OnOff Enable/disable time out function
* @param[in] u32TimeOutCnt Timeout count * @param[in] u32TimeOutCnt Timeout count
* *
...@@ -373,24 +325,23 @@ void PDMA_DisableTimeout(PDMA_T * pdma,uint32_t u32Mask) ...@@ -373,24 +325,23 @@ void PDMA_DisableTimeout(PDMA_T * pdma,uint32_t u32Mask)
* @details This function set the timeout count. * @details This function set the timeout count.
* @note M480 only supported channel 0/1. * @note M480 only supported channel 0/1.
*/ */
void PDMA_SetTimeOut(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt) void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt)
{ {
switch(u32Ch) if (u32Ch < 2)
{ {
case 0ul: __IO uint32_t *pau32TOC = (__IO uint32_t *)&pdma->TOC0_1;
pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC0_Msk) | u32TimeOutCnt; uint32_t u32TOC_Pos, u32TOC_Msk;
break;
case 1ul:
pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC1_Msk) | (u32TimeOutCnt << PDMA_TOC0_1_TOC1_Pos);
break;
default:
break;
}
if (u32OnOff) u32TOC_Pos = (u32Ch % 2) * 16 ;
pdma->TOUTEN |= (1 << u32Ch); u32TOC_Msk = PDMA_TOC0_1_TOC0_Msk << u32TOC_Pos;
else pau32TOC[u32Ch / 2] = (pau32TOC[u32Ch / 2] & ~u32TOC_Msk) | (u32TimeOutCnt << u32TOC_Pos);
pdma->TOUTEN &= ~(1 << u32Ch);
if (u32OnOff)
pdma->TOUTEN |= (1 << u32Ch);
else
pdma->TOUTEN &= ~(1 << u32Ch);
}
else {}
} }
/** /**
...@@ -403,9 +354,17 @@ void PDMA_SetTimeOut(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32OnOff, uint32_t u ...@@ -403,9 +354,17 @@ void PDMA_SetTimeOut(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32OnOff, uint32_t u
* *
* @details This function trigger the selected channel. * @details This function trigger the selected channel.
*/ */
void PDMA_Trigger(PDMA_T * pdma,uint32_t u32Ch) void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch)
{ {
if(u32ChSelect[u32Ch] == PDMA_MEM) __IO uint32_t *pau32REQSEL = (__IO uint32_t *)&pdma->REQSEL0_3;
uint32_t u32REQSEL_Pos, u32REQSEL_Msk, u32ChReq;
u32REQSEL_Pos = (u32Ch % 4) * 8 ;
u32REQSEL_Msk = PDMA_REQSEL0_3_REQSRC0_Msk << u32REQSEL_Pos;
u32ChReq = (pau32REQSEL[u32Ch / 4] & u32REQSEL_Msk) >> u32REQSEL_Pos;
if (u32ChReq == PDMA_MEM)
{ {
pdma->SWREQ = (1ul << u32Ch); pdma->SWREQ = (1ul << u32Ch);
} }
...@@ -426,9 +385,9 @@ void PDMA_Trigger(PDMA_T * pdma,uint32_t u32Ch) ...@@ -426,9 +385,9 @@ void PDMA_Trigger(PDMA_T * pdma,uint32_t u32Ch)
* *
* @details This function enable the selected channel interrupt. * @details This function enable the selected channel interrupt.
*/ */
void PDMA_EnableInt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Mask) void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
{ {
switch(u32Mask) switch (u32Mask)
{ {
case PDMA_INT_TRANS_DONE: case PDMA_INT_TRANS_DONE:
pdma->INTEN |= (1ul << u32Ch); pdma->INTEN |= (1ul << u32Ch);
...@@ -459,9 +418,9 @@ void PDMA_EnableInt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Mask) ...@@ -459,9 +418,9 @@ void PDMA_EnableInt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Mask)
* *
* @details This function disable the selected channel interrupt. * @details This function disable the selected channel interrupt.
*/ */
void PDMA_DisableInt(PDMA_T * pdma,uint32_t u32Ch, uint32_t u32Mask) void PDMA_DisableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
{ {
switch(u32Mask) switch (u32Mask)
{ {
case PDMA_INT_TRANS_DONE: case PDMA_INT_TRANS_DONE:
pdma->INTEN &= ~(1ul << u32Ch); pdma->INTEN &= ~(1ul << u32Ch);
......
...@@ -124,7 +124,7 @@ static void *nu_emac_memcpy(void *dest, void *src, unsigned int count) ...@@ -124,7 +124,7 @@ static void *nu_emac_memcpy(void *dest, void *src, unsigned int count)
if (count >= NU_EMAC_PDMA_MEMCOPY_THRESHOLD) if (count >= NU_EMAC_PDMA_MEMCOPY_THRESHOLD)
return nu_pdma_memcpy(dest, src, count); return nu_pdma_memcpy(dest, src, count);
#endif #endif
return memcpy(dest, src, count); return rt_memcpy(dest, src, count);
} }
static void nu_emac_reinit(void) static void nu_emac_reinit(void)
......
...@@ -215,7 +215,7 @@ static void nu_pdma_init(void) ...@@ -215,7 +215,7 @@ static void nu_pdma_init(void)
RT_ASSERT(g_mutex_sg != RT_NULL); RT_ASSERT(g_mutex_sg != RT_NULL);
nu_pdma_chn_mask = ~NU_PDMA_CH_Msk; nu_pdma_chn_mask = ~NU_PDMA_CH_Msk;
rt_memset(nu_pdma_chn_arr, 0x00, NU_PDMA_CH_MAX*sizeof(nu_pdma_chn_t)); rt_memset(nu_pdma_chn_arr, 0x00, NU_PDMA_CH_MAX * sizeof(nu_pdma_chn_t));
NVIC_EnableIRQ(PDMA_IRQn); NVIC_EnableIRQ(PDMA_IRQn);
...@@ -998,7 +998,7 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un ...@@ -998,7 +998,7 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
} }
u32TransferCnt -= u32TxCnt; u32TransferCnt -= u32TxCnt;
u32Offset += u32TxCnt; u32Offset += u32TxCnt * (u32DataWidth / 8);
} }
while (u32TransferCnt > 0); while (u32TransferCnt > 0);
......
...@@ -156,11 +156,13 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, ...@@ -156,11 +156,13 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device,
uint32_t u32SPIMode; uint32_t u32SPIMode;
uint32_t u32BusClock; uint32_t u32BusClock;
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL); RT_ASSERT(configuration != RT_NULL);
spi_bus = (struct nu_spi *) device->bus; spi_bus = (struct nu_spi *) device->bus;
pvUserData = device->parent.user_data;
/* Check mode */ /* Check mode */
switch (configuration->mode & RT_SPI_MODE_3) switch (configuration->mode & RT_SPI_MODE_3)
...@@ -210,12 +212,29 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, ...@@ -210,12 +212,29 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device,
if (configuration->mode & RT_SPI_CS_HIGH) if (configuration->mode & RT_SPI_CS_HIGH)
{ {
/* Set CS pin to LOW */ /* Set CS pin to LOW */
SPI_SET_SS_LOW(spi_bus->spi_base); if (pvUserData != RT_NULL)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
} }
else else
{ {
/* Set CS pin to HIGH */ /* Set CS pin to HIGH */
SPI_SET_SS_HIGH(spi_bus->spi_base); if (pvUserData != RT_NULL)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
/* Set CS pin to HIGH */
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
} }
if (configuration->mode & RT_SPI_MSB) if (configuration->mode & RT_SPI_MSB)
...@@ -574,6 +593,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -574,6 +593,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
struct nu_spi *spi_bus; struct nu_spi *spi_bus;
struct rt_spi_configuration *configuration; struct rt_spi_configuration *configuration;
uint8_t bytes_per_word; uint8_t bytes_per_word;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus != RT_NULL);
...@@ -582,6 +602,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -582,6 +602,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
spi_bus = (struct nu_spi *) device->bus; spi_bus = (struct nu_spi *) device->bus;
configuration = (struct rt_spi_configuration *)&spi_bus->configuration; configuration = (struct rt_spi_configuration *)&spi_bus->configuration;
bytes_per_word = configuration->data_width / 8; bytes_per_word = configuration->data_width / 8;
pvUserData = device->parent.user_data;
if ((message->length % bytes_per_word) != 0) if ((message->length % bytes_per_word) != 0)
{ {
...@@ -594,13 +615,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -594,13 +615,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
{ {
if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
SPI_SET_SS_HIGH(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
} }
else else
{ {
SPI_SET_SS_LOW(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
else
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
} }
} }
...@@ -608,13 +645,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -608,13 +645,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
SPI_SET_SS_LOW(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
} }
else else
{ {
SPI_SET_SS_HIGH(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
else
{
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
} }
} }
......
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
#include <drv_pdma.h> #include <drv_pdma.h>
#endif #endif
/* Private define ---------------------------------------------------------------*/ /* Private define ---------------------------------------------------------------*/
#ifndef NU_SPI_USE_PDMA_MIN_THRESHOLD
#define NU_SPI_USE_PDMA_MIN_THRESHOLD (128)
#endif
enum enum
{ {
USPI_START = -1, USPI_START = -1,
...@@ -131,11 +136,13 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device, ...@@ -131,11 +136,13 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device,
uint32_t u32SPIMode; uint32_t u32SPIMode;
uint32_t u32BusClock; uint32_t u32BusClock;
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL); RT_ASSERT(configuration != RT_NULL);
uspi_bus = (struct nu_uspi *) device->bus; uspi_bus = (struct nu_uspi *) device->bus;
pvUserData = device->parent.user_data;
/* Check mode */ /* Check mode */
switch (configuration->mode & RT_SPI_MODE_3) switch (configuration->mode & RT_SPI_MODE_3)
...@@ -183,12 +190,29 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device, ...@@ -183,12 +190,29 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device,
if (configuration->mode & RT_SPI_CS_HIGH) if (configuration->mode & RT_SPI_CS_HIGH)
{ {
/* Set CS pin to LOW */ /* Set CS pin to LOW */
USPI_SET_SS_LOW(uspi_bus->uspi_base); if (pvUserData != RT_NULL)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
USPI_SET_SS_LOW(uspi_bus->uspi_base);
}
} }
else else
{ {
/* Set CS pin to HIGH */ /* Set CS pin to HIGH */
USPI_SET_SS_HIGH(uspi_bus->uspi_base); if (pvUserData != RT_NULL)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
/* Set CS pin to HIGH */
USPI_SET_SS_HIGH(uspi_bus->uspi_base);
}
} }
if (configuration->mode & RT_SPI_MSB) if (configuration->mode & RT_SPI_MSB)
...@@ -319,27 +343,40 @@ exit_nu_pdma_uspi_tx_config: ...@@ -319,27 +343,40 @@ exit_nu_pdma_uspi_tx_config:
**/ **/
static rt_size_t nu_uspi_pdma_transmit(struct nu_uspi *uspi_bus, const uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word) static rt_size_t nu_uspi_pdma_transmit(struct nu_uspi *uspi_bus, const uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word)
{ {
rt_err_t result; rt_err_t result = RT_EOK;
rt_uint32_t u32Offset = 0;
rt_uint32_t u32TransferCnt = length / bytes_per_word;
rt_uint32_t u32TxCnt = 0;
/* Get base address of uspi register */ /* Get base address of uspi register */
USPI_T *uspi_base = uspi_bus->uspi_base; USPI_T *uspi_base = uspi_bus->uspi_base;
result = nu_pdma_uspi_rx_config(uspi_bus, recv_addr, length, bytes_per_word); do
RT_ASSERT(result == RT_EOK); {
result = nu_pdma_uspi_tx_config(uspi_bus, send_addr, length, bytes_per_word); u32TxCnt = (u32TransferCnt > NU_PDMA_MAX_TXCNT) ? NU_PDMA_MAX_TXCNT : u32TransferCnt;
RT_ASSERT(result == RT_EOK); result = nu_pdma_uspi_rx_config(uspi_bus, (recv_addr == RT_NULL) ? recv_addr : &recv_addr[u32Offset], (u32TxCnt * bytes_per_word), bytes_per_word);
RT_ASSERT(result == RT_EOK);
/* Trigger TX/RX at the same time. */ result = nu_pdma_uspi_tx_config(uspi_bus, (send_addr == RT_NULL) ? send_addr : &send_addr[u32Offset], (u32TxCnt * bytes_per_word), bytes_per_word);
USPI_TRIGGER_TX_RX_PDMA(uspi_base); RT_ASSERT(result == RT_EOK);
/* Wait PDMA transfer done */ /* Trigger TX/RX PDMA transfer. */
result = rt_sem_take(uspi_bus->m_psSemBus, RT_WAITING_FOREVER); USPI_TRIGGER_TX_RX_PDMA(uspi_base);
RT_ASSERT(result == RT_EOK);
/* Stop DMA TX/RX transfer */ /* Wait RX-PDMA transfer done */
USPI_DISABLE_TX_RX_PDMA(uspi_base); result = rt_sem_take(uspi_bus->m_psSemBus, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
return result; /* Stop TX/RX DMA transfer. */
USPI_DISABLE_TX_RX_PDMA(uspi_base);
u32TransferCnt -= u32TxCnt;
u32Offset += u32TxCnt;
}
while (u32TransferCnt > 0);
return length;
} }
static rt_err_t nu_hw_uspi_pdma_allocate(struct nu_uspi *uspi_bus) static rt_err_t nu_hw_uspi_pdma_allocate(struct nu_uspi *uspi_bus)
...@@ -504,11 +541,14 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus, ...@@ -504,11 +541,14 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus,
static void nu_uspi_transfer(struct nu_uspi *uspi_bus, uint8_t *tx, uint8_t *rx, int length, uint8_t bytes_per_word) static void nu_uspi_transfer(struct nu_uspi *uspi_bus, uint8_t *tx, uint8_t *rx, int length, uint8_t bytes_per_word)
{ {
RT_ASSERT(uspi_bus != RT_NULL);
#if defined(BSP_USING_USPI_PDMA) #if defined(BSP_USING_USPI_PDMA)
/* PDMA transfer constrains */ /* PDMA transfer constrains */
if ((uspi_bus->pdma_chanid_rx >= 0) && if ((uspi_bus->pdma_chanid_rx >= 0) &&
(!((uint32_t)tx % bytes_per_word)) && !((uint32_t)tx % bytes_per_word) &&
(!((uint32_t)rx % bytes_per_word))) !((uint32_t)rx % bytes_per_word) &&
(length >= NU_SPI_USE_PDMA_MIN_THRESHOLD))
nu_uspi_pdma_transmit(uspi_bus, tx, rx, length, bytes_per_word); nu_uspi_pdma_transmit(uspi_bus, tx, rx, length, bytes_per_word);
else else
nu_uspi_transmission_with_poll(uspi_bus, tx, rx, length, bytes_per_word); nu_uspi_transmission_with_poll(uspi_bus, tx, rx, length, bytes_per_word);
...@@ -522,6 +562,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -522,6 +562,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
struct nu_uspi *uspi_bus; struct nu_uspi *uspi_bus;
struct rt_spi_configuration *configuration; struct rt_spi_configuration *configuration;
uint8_t bytes_per_word; uint8_t bytes_per_word;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus != RT_NULL);
...@@ -530,6 +571,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -530,6 +571,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
uspi_bus = (struct nu_uspi *) device->bus; uspi_bus = (struct nu_uspi *) device->bus;
configuration = &uspi_bus->configuration; configuration = &uspi_bus->configuration;
bytes_per_word = configuration->data_width / 8; bytes_per_word = configuration->data_width / 8;
pvUserData = device->parent.user_data;
if ((message->length % bytes_per_word) != 0) if ((message->length % bytes_per_word) != 0)
{ {
...@@ -542,13 +584,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -542,13 +584,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
{ {
if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
USPI_SET_SS_HIGH(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
} }
else else
{ {
USPI_SET_SS_LOW(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
USPI_SET_SS_HIGH(uspi_bus->uspi_base);
}
else
{
USPI_SET_SS_LOW(uspi_bus->uspi_base);
}
} }
} }
...@@ -556,13 +614,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_ ...@@ -556,13 +614,29 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
USPI_SET_SS_LOW(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
} }
else else
{ {
USPI_SET_SS_HIGH(uspi_bus->uspi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
USPI_SET_SS_LOW(uspi_bus->uspi_base);
}
else
{
USPI_SET_SS_HIGH(uspi_bus->uspi_base);
}
} }
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
/* Private define ---------------------------------------------------------------*/ /* Private define ---------------------------------------------------------------*/
#define DEF_ADC_TOUCH_SMPL_TICK 40 #define DEF_ADC_TOUCH_SMPL_TICK 40
#define TOUCH_MQ_LENGTH 64
/* Private Typedef --------------------------------------------------------------*/ /* Private Typedef --------------------------------------------------------------*/
struct nu_adc struct nu_adc
......
...@@ -15,14 +15,11 @@ ...@@ -15,14 +15,11 @@
#include <rtthread.h> #include <rtthread.h>
#include "nu_adc.h" #include "nu_adc.h"
#if defined(BSP_USING_ADC_TOUCH) #if defined(BSP_USING_ADC_TOUCH)
#include "touch.h" #include "touch.h"
#endif #endif
#define TOUCH_MQ_LENGTH 64
#define DEF_CAL_POINT_NUM 5
typedef enum typedef enum
{ {
eAdc_MF, //0 eAdc_MF, //0
...@@ -57,28 +54,10 @@ typedef struct ...@@ -57,28 +54,10 @@ typedef struct
typedef nu_adc_cb *nu_adc_cb_t; typedef nu_adc_cb *nu_adc_cb_t;
#if defined(BSP_USING_ADC_TOUCH) #if defined(BSP_USING_ADC_TOUCH)
typedef struct void nu_adc_touch_detect(rt_bool_t bStartDetect);
{ int32_t nu_adc_touch_read_xyz(uint32_t *bufX, uint32_t *bufY, uint32_t *bufZ0, uint32_t *bufZ1, int32_t dataCnt);
int32_t x; rt_err_t nu_adc_touch_enable(rt_touch_t psRtTouch);
int32_t y; rt_err_t nu_adc_touch_disable(void);
} S_COORDINATE_POINT;
typedef struct
{
int32_t a;
int32_t b;
int32_t c;
int32_t d;
int32_t e;
int32_t f;
int32_t div;
} S_CALIBRATION_MATRIX;
int32_t nu_adc_touch_read_xyz(uint32_t *bufX, uint32_t *bufY, uint32_t *bufZ0, uint32_t *bufZ1, int32_t dataCnt);
rt_err_t nu_adc_touch_enable(rt_touch_t psRtTouch);
rt_err_t nu_adc_touch_disable(void);
void nu_adc_touch_detect(rt_bool_t bStartDetect);
void nu_adc_touch_start_conv(void);
#endif #endif
#endif /* __DRV_ADC_H__ */ #endif /* __DRV_ADC_H__ */
...@@ -153,7 +153,7 @@ static void nu_emac_halt(nu_emac_t psNuEmac) ...@@ -153,7 +153,7 @@ static void nu_emac_halt(nu_emac_t psNuEmac)
static void *nu_emac_memcpy(void *dest, void *src, unsigned int count) static void *nu_emac_memcpy(void *dest, void *src, unsigned int count)
{ {
return memcpy(dest, src, count); return rt_memcpy(dest, src, count);
} }
static void nu_emac_reinit(nu_emac_t psNuEmac) static void nu_emac_reinit(nu_emac_t psNuEmac)
......
...@@ -342,6 +342,7 @@ int rt_hw_vpost_init(void) ...@@ -342,6 +342,7 @@ int rt_hw_vpost_init(void)
else else
{ {
uint32_t u32FBSize = psVpost->info.pitch * psVpostLcmInst->u32DevHeight; uint32_t u32FBSize = psVpost->info.pitch * psVpostLcmInst->u32DevHeight;
psVpost->info.smem_len = u32FBSize * DEF_VPOST_BUFFER_NUMBER;
rt_memset(psVpost->info.framebuffer, 0, u32FBSize); rt_memset(psVpost->info.framebuffer, 0, u32FBSize);
} }
......
# RT-Thread building script for component
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
group = []
if GetDepend('NU_PKG_USING_ADC_TOUCH'):
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
group = DefineGroup('nu_pkgs_adc_touch', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <rtconfig.h> #include <rtconfig.h>
#if defined(BSP_USING_ADC_TOUCH) #if defined(NU_PKG_USING_ADC_TOUCH)
#include "NuMicro.h" #include "NuMicro.h"
#include <rtdevice.h> #include <rtdevice.h>
...@@ -20,13 +20,18 @@ ...@@ -20,13 +20,18 @@
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/statfs.h> #include <sys/statfs.h>
#include "drv_adc.h"
#include "touch.h" #include "touch.h"
//#include "drv_adc.h"
#include "adc_touch.h"
#if !defined(PATH_CALIBRATION_FILE) #if !defined(PATH_CALIBRATION_FILE)
#define PATH_CALIBRATION_FILE "/mnt/filesystem/ts_calibration" #define PATH_CALIBRATION_FILE "/mnt/filesystem/ts_calibration"
#endif #endif
rt_err_t nu_adc_touch_disable(void);
rt_err_t nu_adc_touch_enable(rt_touch_t psRtTouch);
void nu_adc_touch_detect(rt_bool_t bStartDetect);
int32_t nu_adc_touch_read_xyz(uint32_t *bufX, uint32_t *bufY, uint32_t *bufZ0, uint32_t *bufZ1, int32_t dataCnt);
typedef struct typedef struct
{ {
...@@ -38,16 +43,9 @@ typedef nu_adc_touch *nu_adc_touch_t; ...@@ -38,16 +43,9 @@ typedef nu_adc_touch *nu_adc_touch_t;
static nu_adc_touch s_NuAdcTouch = {0}; static nu_adc_touch s_NuAdcTouch = {0};
#if (BSP_LCD_WIDTH==480) && (BSP_LCD_HEIGHT==272) /* User can define ADC touch calibration matrix in board_dev.c. */
static S_CALIBRATION_MATRIX g_sCalMat = { 8824, -34, -2261272, -70, -6302, 21805816, 65536 }; RT_WEAK S_CALIBRATION_MATRIX g_sCalMat = { 1, 0, 0, 0, 1, 0, 1 };
static volatile uint32_t g_u32Calibrated = 1;
#elif (BSP_LCD_WIDTH==800) && (BSP_LCD_HEIGHT==480)
static S_CALIBRATION_MATRIX g_sCalMat = { 13230, -66, -1161952, -85, 8600, -1636996, 65536 };
static volatile uint32_t g_u32Calibrated = 1;
#else
static S_CALIBRATION_MATRIX g_sCalMat = { 1, 0, 0, 0, 1, 0, 1 };
static volatile uint32_t g_u32Calibrated = 0; static volatile uint32_t g_u32Calibrated = 0;
#endif
static int nu_adc_touch_readfile(void); static int nu_adc_touch_readfile(void);
...@@ -97,7 +95,7 @@ static int nu_adc_cal_mat_get(const S_COORDINATE_POINT *psDispCP, S_COORDINATE_P ...@@ -97,7 +95,7 @@ static int nu_adc_cal_mat_get(const S_COORDINATE_POINT *psDispCP, S_COORDINATE_P
n = x = y = xx = yy = xy = 0; n = x = y = xx = yy = xy = 0;
for (i = 0; i < DEF_CAL_POINT_NUM; i++) for (i = 0; i < DEF_CAL_POINT_NUM; i++)
{ {
n += 1.0; n += (float)1.0;
x += (float)psADCCP[i].x; x += (float)psADCCP[i].x;
y += (float)psADCCP[i].y; y += (float)psADCCP[i].y;
xx += (float)psADCCP[i].x * psADCCP[i].x; xx += (float)psADCCP[i].x * psADCCP[i].x;
...@@ -106,7 +104,7 @@ static int nu_adc_cal_mat_get(const S_COORDINATE_POINT *psDispCP, S_COORDINATE_P ...@@ -106,7 +104,7 @@ static int nu_adc_cal_mat_get(const S_COORDINATE_POINT *psDispCP, S_COORDINATE_P
} }
d = n * (xx * yy - xy * xy) + x * (xy * y - x * yy) + y * (x * xy - y * xx); d = n * (xx * yy - xy * xy) + x * (xy * y - x * yy) + y * (x * xy - y * xx);
if (d < 0.1 && d > -0.1) if (d < (float)0.1 && d > (float) -0.1)
{ {
return -1; return -1;
} }
...@@ -340,15 +338,42 @@ static void lcd_cleanscreen(void) ...@@ -340,15 +338,42 @@ static void lcd_cleanscreen(void)
{ {
if (info.framebuffer != RT_NULL) if (info.framebuffer != RT_NULL)
{ {
/* Rendering */ if (rt_device_control(lcd_device, RTGRAPHIC_CTRL_PAN_DISPLAY, (void *)info.framebuffer) == RT_EOK)
struct rt_device_rect_info rect; {
/* Sync-type LCD panel, will fill to VRAM directly. */
rt_memset(info.framebuffer, 0, (info.pitch * info.height));
}
else
{
/* MPU-type LCD panel, fill to shadow RAM, then flush. */
struct rt_device_rect_info rectinfo;
int filled_line_num = 0;
int i32LineBufNum = info.smem_len / info.pitch;
int i32RemainLineNum = info.height;
i32LineBufNum = (i32LineBufNum > info.height) ? info.height : i32LineBufNum;
rt_memset(info.framebuffer, 0, (info.pitch * info.height)); while (i32RemainLineNum > 0)
rect.x = 0; {
rect.y = 0; int pixel_count;
rect.width = info.width; rectinfo.x = 0;
rect.height = info.height; rectinfo.y = filled_line_num;
rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect); rectinfo.width = info.width;
rectinfo.height = (i32RemainLineNum > i32LineBufNum) ? i32LineBufNum : i32RemainLineNum ;
pixel_count = info.width * rectinfo.height;
rt_uint16_t *pu16ShadowBuf = (rt_uint16_t *)info.framebuffer;
while (pixel_count > 0)
{
*pu16ShadowBuf++ = 0;
pixel_count--;
}
rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, &rectinfo);
filled_line_num += i32LineBufNum;
i32RemainLineNum -= rectinfo.height;
}
}
} }
else else
{ {
...@@ -367,42 +392,70 @@ static void nu_draw_bots(int x, int y) ...@@ -367,42 +392,70 @@ static void nu_draw_bots(int x, int y)
int i, j; int i, j;
int start_x = x - (DEF_DOT_NUMBER / 2); int start_x = x - (DEF_DOT_NUMBER / 2);
int start_y = y - (DEF_DOT_NUMBER / 2); int start_y = y - (DEF_DOT_NUMBER / 2);
rt_bool_t bDrawDirect;
if (rt_device_control(lcd_device, RTGRAPHIC_CTRL_PAN_DISPLAY, (void *)info.framebuffer) == RT_EOK)
{
/* Sync-type LCD panel, will draw to VRAM directly. */
bDrawDirect = RT_TRUE;
}
else
{
/* MPU-type LCD panel, draw to shadow RAM, then flush. */
bDrawDirect = RT_FALSE;
}
if (info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565) if (info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
{ {
uint16_t *pu16Start = (uint16_t *)((uint32_t)info.framebuffer + (start_y) * info.pitch + (start_x * 2)); uint16_t *pu16Start = (bDrawDirect == RT_TRUE) ? (uint16_t *)((uint32_t)info.framebuffer + (start_y) * info.pitch + (start_x * 2)) : (uint16_t *)info.framebuffer;
for (j = 0; j < DEF_DOT_NUMBER; j++) for (i = 0; i < DEF_DOT_NUMBER; i++)
{ {
for (i = 0; i < DEF_DOT_NUMBER; i++) for (j = 0; j < DEF_DOT_NUMBER; j++)
pu16Start[i] = 0x07E0; //Green, RGB {
pu16Start += info.width; *pu16Start = 0x07E0; //Green, RGB565
pu16Start++;
}
if (bDrawDirect)
pu16Start += (info.width - DEF_DOT_NUMBER);
} }
} }
else if (info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888) else if (info.pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
{ {
uint32_t *pu32Start = (uint32_t *)((uint32_t)info.framebuffer + (start_y) * info.pitch + (start_x * 4)); uint32_t *pu32Start = (bDrawDirect == RT_TRUE) ? (uint32_t *)((uint32_t)info.framebuffer + (start_y) * info.pitch + (start_x * 4)) : (uint32_t *)info.framebuffer;
for (j = 0; j < DEF_DOT_NUMBER; j++) for (i = 0; i < DEF_DOT_NUMBER; i++)
{ {
for (i = 0; i < DEF_DOT_NUMBER; i++) for (j = 0; j < DEF_DOT_NUMBER; j++)
pu32Start[i] = 0xff00ff00; //Green, ARGB {
pu32Start += info.width; *pu32Start = 0xff00ff00; //Green, ARGB888
pu32Start++;
}
if (bDrawDirect)
pu32Start += (info.width - DEF_DOT_NUMBER);
} }
} }
else else
{ {
//Not supported //Not supported
return;
} }
rect.x = 0; if (!bDrawDirect)
rect.y = 0; {
rect.width = info.width; /* Region updating */
rect.height = info.height; rect.x = start_x;
rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect); rect.y = start_y;
rect.width = DEF_DOT_NUMBER;
rect.height = DEF_DOT_NUMBER;
rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect);
}
} }
else else
{ {
// TODO // TODO
} }
return;
} }
#if (DEF_CAL_POINT_NUM==3) #if (DEF_CAL_POINT_NUM==3)
...@@ -574,7 +627,6 @@ static void adc_touch_entry(void *parameter) ...@@ -574,7 +627,6 @@ static void adc_touch_entry(void *parameter)
rt_err_t result; rt_err_t result;
rt_device_t pdev; rt_device_t pdev;
int max_range; int max_range;
adc_touch_sem = rt_sem_create("adc_touch_sem", 0, RT_IPC_FLAG_FIFO); adc_touch_sem = rt_sem_create("adc_touch_sem", 0, RT_IPC_FLAG_FIFO);
...@@ -587,6 +639,9 @@ static void adc_touch_entry(void *parameter) ...@@ -587,6 +639,9 @@ static void adc_touch_entry(void *parameter)
return ; return ;
} }
if (rt_memcmp((void *)&g_sCalMat, (void *)&g_sCalZero, sizeof(S_CALIBRATION_MATRIX)) != 0)
g_u32Calibrated = 1;
nu_adc_touch_readfile(); nu_adc_touch_readfile();
result = rt_device_open(pdev, RT_DEVICE_FLAG_INT_RX); result = rt_device_open(pdev, RT_DEVICE_FLAG_INT_RX);
...@@ -650,8 +705,8 @@ static rt_err_t nu_touch_start(int argc, char **argv) ...@@ -650,8 +705,8 @@ static rt_err_t nu_touch_start(int argc, char **argv)
adc_touch_thread = rt_thread_create("adc_touch_thread", adc_touch_thread = rt_thread_create("adc_touch_thread",
adc_touch_entry, adc_touch_entry,
RT_NULL, RT_NULL,
4096, 2048,
25, 5,
5); 5);
adc_touch_worker_run = 1; adc_touch_worker_run = 1;
if (adc_touch_thread != RT_NULL) if (adc_touch_thread != RT_NULL)
...@@ -685,4 +740,4 @@ static rt_err_t nu_touch_calibration(int argc, char **argv) ...@@ -685,4 +740,4 @@ static rt_err_t nu_touch_calibration(int argc, char **argv)
} }
MSH_CMD_EXPORT(nu_touch_calibration, for adc touch); MSH_CMD_EXPORT(nu_touch_calibration, for adc touch);
#endif //#if defined(BSP_USING_ADC_TOUCH) #endif //#if defined(NU_PKG_USING_ADC_TOUCH)
/**************************************************************************//**
*
* @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-2-21 Wayne First version
*
******************************************************************************/
#ifndef __ADC_TOUCH_CALIBRATE_H__
#define __ADC_TOUCH_CALIBRATE_H__
#include <stdint.h>
#define DEF_CAL_POINT_NUM 5
typedef struct
{
int32_t x;
int32_t y;
} S_COORDINATE_POINT;
typedef struct
{
int32_t a;
int32_t b;
int32_t c;
int32_t d;
int32_t e;
int32_t f;
int32_t div;
} S_CALIBRATION_MATRIX;
#endif /* __ADC_TOUCH_CALIBRATE_H__ */
/**************************************************************************//**
* @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-22 Wayne First version
*
******************************************************************************/
#include <rtthread.h>
#if defined(NU_PKG_USING_ADC_TOUCH_SW)
#include "rtdevice.h"
#include "touch.h"
#include "touch_sw.h"
/* Private define ---------------------------------------------------------------*/
#define DEF_ADC_TOUCH_SMPL_TICK 40
#define TOUCH_MQ_LENGTH 32
/* Private Typedef --------------------------------------------------------------*/
static rt_timer_t g_psRtTouchMenuTimer;
static rt_mq_t g_pmqTouchXYZ;
static S_TOUCH_SW *g_psTouchSW = RT_NULL;
static rt_bool_t bDoSmpling = RT_FALSE;
struct nu_adc_touch_data
{
uint32_t u32X;
uint32_t u32Y;
uint32_t u32Z0;
uint32_t u32Z1;
};
typedef struct nu_adc_touch_data *nu_adc_touch_data_t;
static rt_uint32_t Get_X(S_TOUCH_SW *psTouchSW)
{
/*=== Get X from ADC input ===*/
rt_pin_mode(psTouchSW->pin[evXR], PIN_MODE_OUTPUT);
rt_pin_mode(psTouchSW->pin[evYD], PIN_MODE_INPUT);
rt_pin_mode(psTouchSW->pin[evXL], PIN_MODE_OUTPUT);
rt_pin_write(psTouchSW->pin[evXR], PIN_HIGH);
rt_pin_write(psTouchSW->pin[evXL], PIN_LOW);
psTouchSW->switch_to_digital(psTouchSW->pin[evXR]);
psTouchSW->switch_to_digital(psTouchSW->pin[evYD]);
psTouchSW->switch_to_digital(psTouchSW->pin[evXL]);
/* Disable the digital input path to avoid the leakage current. */
/* Configure the ADC analog input pins. */
psTouchSW->switch_to_analog(psTouchSW->pin[evYU]);
return rt_adc_read((rt_adc_device_t)psTouchSW->adc, psTouchSW->i32ADCChnYU) & 0x0FFF;
}
static rt_uint32_t Get_Y(S_TOUCH_SW *psTouchSW)
{
/*=== Get Y from ADC input ===*/
rt_pin_mode(psTouchSW->pin[evYU], PIN_MODE_OUTPUT);
rt_pin_mode(psTouchSW->pin[evYD], PIN_MODE_OUTPUT);
rt_pin_mode(psTouchSW->pin[evXL], PIN_MODE_INPUT);
rt_pin_write(psTouchSW->pin[evYU], PIN_HIGH);
rt_pin_write(psTouchSW->pin[evYD], PIN_LOW);
psTouchSW->switch_to_digital(psTouchSW->pin[evYU]);
psTouchSW->switch_to_digital(psTouchSW->pin[evYD]);
psTouchSW->switch_to_digital(psTouchSW->pin[evXL]);
/* Disable the digital input path to avoid the leakage current. */
/* Configure the ADC analog input pins. */
psTouchSW->switch_to_analog(psTouchSW->pin[evXR]);
return rt_adc_read((rt_adc_device_t)psTouchSW->adc, psTouchSW->i32ADCChnXR) & 0x0FFF;
}
static void nu_adc_touch_smpl(void *p)
{
static rt_bool_t bDrop = RT_FALSE;
static uint32_t u32LastZ0 = 0xffffu;
struct nu_adc_touch_data point;
S_TOUCH_SW *psTouchSW;
if (!bDoSmpling)
return ;
psTouchSW = (S_TOUCH_SW *)p;
rt_memset(&point, 0, sizeof(struct nu_adc_touch_data));
/* Get X, Y ADC converting data */
point.u32X = Get_X(psTouchSW);
point.u32Y = Get_Y(psTouchSW);
if ((point.u32X < 4000) && (point.u32Y < 4000))
{
point.u32Z0 = point.u32Z1 = 1;
bDrop = RT_FALSE;
}
else
{
bDrop = RT_TRUE;
}
// rt_kprintf("%04x %04x %d %d\n", point.u32X, point.u32Y, point.u32Z0, bDrop);
if ((!bDrop || (u32LastZ0 != 0)) && (rt_mq_send(g_pmqTouchXYZ, (const void *)&point, sizeof(struct nu_adc_touch_data)) == RT_EOK))
{
if (psTouchSW->psRtTouch != RT_NULL)
rt_hw_touch_isr(psTouchSW->psRtTouch);
}
u32LastZ0 = point.u32Z0;
}
int32_t nu_adc_touch_read_xyz(uint32_t *bufX, uint32_t *bufY, uint32_t *bufZ0, uint32_t *bufZ1, int32_t dataCnt)
{
int i;
struct nu_adc_touch_data value;
for (i = 0 ; i < dataCnt; i++)
{
if (rt_mq_recv(g_pmqTouchXYZ, (void *)&value, sizeof(struct nu_adc_touch_data), 0) == -RT_ETIMEOUT)
break;
bufX[i] = value.u32X;
bufY[i] = value.u32Y;
bufZ0[i] = value.u32Z0;
bufZ1[i] = value.u32Z1;
}
return i;
}
void nu_adc_touch_detect(rt_bool_t bStartDetect)
{
}
rt_err_t nu_adc_touch_enable(rt_touch_t psRtTouch)
{
if (g_psTouchSW->adc)
{
g_psTouchSW->psRtTouch = psRtTouch;
rt_adc_enable((rt_adc_device_t)g_psTouchSW->adc, g_psTouchSW->i32ADCChnXR);
rt_adc_enable((rt_adc_device_t)g_psTouchSW->adc, g_psTouchSW->i32ADCChnYU);
bDoSmpling = RT_TRUE;
/* Start sampling procedure. */
rt_timer_start(g_psRtTouchMenuTimer);
return RT_EOK;
}
return RT_ERROR;
}
rt_err_t nu_adc_touch_disable(void)
{
if (g_psTouchSW->adc)
{
/* Stop sampling procedure. */
rt_timer_stop(g_psRtTouchMenuTimer);
bDoSmpling = RT_FALSE;
rt_adc_disable((rt_adc_device_t)g_psTouchSW->adc, g_psTouchSW->i32ADCChnXR);
rt_adc_disable((rt_adc_device_t)g_psTouchSW->adc, g_psTouchSW->i32ADCChnYU);
g_psTouchSW->psRtTouch = RT_NULL;
return RT_EOK;
}
return RT_ERROR;
}
rt_err_t nu_adc_touch_sw_register(S_TOUCH_SW *psTouchSW)
{
RT_ASSERT(psTouchSW);
psTouchSW->adc = rt_device_find(psTouchSW->adc_name);
RT_ASSERT(psTouchSW->adc);
g_pmqTouchXYZ = rt_mq_create("ADC_TOUCH_SW", sizeof(struct nu_adc_touch_data), TOUCH_MQ_LENGTH, RT_IPC_FLAG_FIFO);
RT_ASSERT(g_pmqTouchXYZ);
g_psRtTouchMenuTimer = rt_timer_create("TOUCH_SMPL_TIMER", nu_adc_touch_smpl, (void *)psTouchSW, DEF_ADC_TOUCH_SMPL_TICK, RT_TIMER_FLAG_PERIODIC);
RT_ASSERT(g_psRtTouchMenuTimer);
g_psTouchSW = psTouchSW;
return RT_EOK;
}
#endif //#if defined(NU_PKG_USING_ADC_TOUCH_SW)
/**************************************************************************//**
*
* @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-2-21 Wayne First version
*
******************************************************************************/
#ifndef __TOUCH_SW_H__
#define __TOUCH_SW_H__
#include <rtthread.h>
#include "touch.h"
typedef enum
{
evXL, //X-
evYU, //Y-
evXR, //X+
evYD, //Y+
evTOUCH_PIN_CNT
} E_TOUCH_PIN;
typedef struct
{
char *adc_name;
rt_device_t adc;
int i32ADCChnYU;
int i32ADCChnXR;
rt_touch_t psRtTouch;
rt_base_t pin[evTOUCH_PIN_CNT];
void (*switch_to_analog)(rt_base_t pin);
void (*switch_to_digital)(rt_base_t pin);
} S_TOUCH_SW;
rt_err_t nu_adc_touch_sw_register(S_TOUCH_SW *psTouchSW);
#endif /* __TOUCH_SW_H__ */
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#if defined(NU_PKG_USING_ILI9341_EBI) #if defined(NU_PKG_USING_ILI9341_EBI)
#include <lcd_ili9341.h> #include <lcd_ili9341.h>
#include "drv_pdma.h"
#define ILI9341_ADDR_CMD 0x0 #define ILI9341_ADDR_CMD 0x0
#define ILI9341_ADDR_DATA 0x0030000 #define ILI9341_ADDR_DATA 0x0030000
...@@ -44,11 +45,22 @@ void ili9341_send_pixel_data(rt_uint16_t color) ...@@ -44,11 +45,22 @@ void ili9341_send_pixel_data(rt_uint16_t color)
void ili9341_send_pixels(rt_uint16_t *pixels, int len) void ili9341_send_pixels(rt_uint16_t *pixels, int len)
{ {
int i = 0; int count = len / sizeof(rt_uint16_t);
int size = len / sizeof(rt_uint16_t); if (count < 1024)
{
while (i < size) // CPU feed
ili9341_write_data(pixels[i]); int i = 0;
while (i < count)
{
ili9341_write_data(pixels[i]);
i++;
}
}
else
{
// PDMA-M2M feed
nu_pdma_mempush((void *)(g_uint32_ili9341_base + (ILI9341_ADDR_DATA)), (void *)pixels, 16, count);
}
} }
void ili9341_set_column(uint16_t StartCol, uint16_t EndCol) void ili9341_set_column(uint16_t StartCol, uint16_t EndCol)
......
...@@ -17,12 +17,16 @@ ...@@ -17,12 +17,16 @@
#include <rtdevice.h> #include <rtdevice.h>
#include <lcd_ili9341.h> #include <lcd_ili9341.h>
#if !defined(NU_PKG_USING_ILI9341_SPI_CLK_FREQ)
#define NU_PKG_USING_ILI9341_SPI_CLK_FREQ 48000000
#endif
static struct rt_spi_device ili9341_spi_device; static struct rt_spi_device ili9341_spi_device;
static struct rt_spi_configuration ili9341_cfg = static struct rt_spi_configuration ili9341_cfg =
{ {
.mode = RT_SPI_MODE_0 | RT_SPI_MSB, .mode = RT_SPI_MODE_0 | RT_SPI_MSB,
.data_width = 8, .data_width = 8,
.max_hz = 48000000, .max_hz = NU_PKG_USING_ILI9341_SPI_CLK_FREQ,
}; };
static void ili9341_change_datawidth(int data_width) static void ili9341_change_datawidth(int data_width)
...@@ -190,11 +194,19 @@ void ili9341_lcd_get_pixel(char *color, int x, int y) ...@@ -190,11 +194,19 @@ void ili9341_lcd_get_pixel(char *color, int x, int y)
*(rt_uint16_t *)color = ((bgrx.S.r >> 3) << 11) | ((bgrx.S.g >> 2) << 5) | (bgrx.S.b >> 3); *(rt_uint16_t *)color = ((bgrx.S.r >> 3) << 11) | ((bgrx.S.g >> 2) << 5) | (bgrx.S.b >> 3);
} }
rt_err_t rt_hw_lcd_ili9341_spi_init(const char *spibusname) rt_err_t rt_hw_lcd_ili9341_spi_init(const char *spibusname, void *pvUserData)
{ {
if (rt_spi_bus_attach_device(&ili9341_spi_device, "lcd_ili9341", spibusname, RT_NULL) != RT_EOK) if (rt_spi_bus_attach_device(&ili9341_spi_device, "lcd_ili9341", spibusname, pvUserData) != RT_EOK)
return -RT_ERROR; return -RT_ERROR;
if (pvUserData != RT_NULL)
{
// GPIO CS pin mode to output */
rt_pin_mode(*((rt_base_t *)pvUserData), PIN_MODE_OUTPUT);
}
rt_kprintf("Preferred ili9341 spi clock frequency is %d Hz.\n", NU_PKG_USING_ILI9341_SPI_CLK_FREQ);
return rt_spi_configure(&ili9341_spi_device, &ili9341_cfg); return rt_spi_configure(&ili9341_spi_device, &ili9341_cfg);
} }
......
...@@ -17,6 +17,14 @@ ...@@ -17,6 +17,14 @@
#include <rtdevice.h> #include <rtdevice.h>
#include <lcd_ili9341.h> #include <lcd_ili9341.h>
#if defined(NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER)
#if !defined(NU_PKG_ILI9341_LINE_BUFFER_NUMBER)
#define NU_PKG_ILI9341_LINE_BUFFER_NUMBER YSIZE_PHYS
#endif
#endif
#define ili9341_delay_ms(ms) rt_thread_mdelay(ms)
static struct rt_device_graphic_info g_Ili9341Info = static struct rt_device_graphic_info g_Ili9341Info =
{ {
.bits_per_pixel = 16, .bits_per_pixel = 16,
...@@ -27,11 +35,6 @@ static struct rt_device_graphic_info g_Ili9341Info = ...@@ -27,11 +35,6 @@ static struct rt_device_graphic_info g_Ili9341Info =
.height = YSIZE_PHYS .height = YSIZE_PHYS
}; };
static void ili9341_delay_ms(rt_uint32_t nms)
{
rt_thread_mdelay(nms);
}
static rt_err_t ili9341_pin_init(void) static rt_err_t ili9341_pin_init(void)
{ {
rt_pin_mode(BOARD_USING_ILI9341_PIN_DC, PIN_MODE_OUTPUT); rt_pin_mode(BOARD_USING_ILI9341_PIN_DC, PIN_MODE_OUTPUT);
...@@ -185,15 +188,28 @@ static void ili9341_fillrect(uint16_t *pixels, struct rt_device_rect_info *pRect ...@@ -185,15 +188,28 @@ static void ili9341_fillrect(uint16_t *pixels, struct rt_device_rect_info *pRect
static void ili9341_fillscreen(rt_uint16_t color) static void ili9341_fillscreen(rt_uint16_t color)
{ {
#if defined(NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER) #if defined(NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER)
struct rt_device_rect_info rectinfo = { 0, 0, XSIZE_PHYS, YSIZE_PHYS }; struct rt_device_rect_info rectinfo;
int pixel_count = XSIZE_PHYS * YSIZE_PHYS; int filled_line_num = 0;
rt_uint16_t *pu16ShadowBuf = (rt_uint16_t *)g_Ili9341Info.framebuffer;
while (pixel_count--) while (filled_line_num < YSIZE_PHYS)
{ {
*pu16ShadowBuf++ = color; int pixel_count;
rectinfo.x = 0;
rectinfo.y = filled_line_num;
rectinfo.width = XSIZE_PHYS;
rectinfo.height = (NU_PKG_ILI9341_LINE_BUFFER_NUMBER < YSIZE_PHYS) ? NU_PKG_ILI9341_LINE_BUFFER_NUMBER : YSIZE_PHYS;
pixel_count = XSIZE_PHYS * NU_PKG_ILI9341_LINE_BUFFER_NUMBER;
rt_uint16_t *pu16ShadowBuf = (rt_uint16_t *)g_Ili9341Info.framebuffer;
while (pixel_count > 0)
{
*pu16ShadowBuf++ = color;
pixel_count--;
}
ili9341_fillrect((uint16_t *)g_Ili9341Info.framebuffer, &rectinfo);
filled_line_num += NU_PKG_ILI9341_LINE_BUFFER_NUMBER;
} }
ili9341_fillrect((uint16_t *)g_Ili9341Info.framebuffer, &rectinfo);
#else #else
ili9341_set_column(0, (XSIZE_PHYS - 1)); ili9341_set_column(0, (XSIZE_PHYS - 1));
ili9341_set_page(0, (YSIZE_PHYS - 1)); ili9341_set_page(0, (YSIZE_PHYS - 1));
...@@ -282,7 +298,7 @@ static rt_err_t ili9341_lcd_control(rt_device_t dev, int cmd, void *args) ...@@ -282,7 +298,7 @@ static rt_err_t ili9341_lcd_control(rt_device_t dev, int cmd, void *args)
} }
break; break;
default: default:
break; return -RT_ERROR;
} }
return RT_EOK; return RT_EOK;
...@@ -314,8 +330,9 @@ int rt_hw_lcd_ili9341_init(void) ...@@ -314,8 +330,9 @@ int rt_hw_lcd_ili9341_init(void)
lcd_device.user_data = &ili9341_ops; lcd_device.user_data = &ili9341_ops;
#if defined(NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER) #if defined(NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER)
g_Ili9341Info.framebuffer = rt_malloc_align((g_Ili9341Info.pitch * g_Ili9341Info.height) + 32, 32); g_Ili9341Info.framebuffer = rt_malloc_align((g_Ili9341Info.pitch * NU_PKG_ILI9341_LINE_BUFFER_NUMBER) + 32, 32);
RT_ASSERT(g_Ili9341Info.framebuffer != RT_NULL); RT_ASSERT(g_Ili9341Info.framebuffer != RT_NULL);
g_Ili9341Info.smem_len = g_Ili9341Info.pitch * NU_PKG_ILI9341_LINE_BUFFER_NUMBER;
#endif #endif
/* register graphic device driver */ /* register graphic device driver */
......
...@@ -46,7 +46,7 @@ void ili9341_lcd_get_pixel(char *color, int x, int y); ...@@ -46,7 +46,7 @@ void ili9341_lcd_get_pixel(char *color, int x, int y);
void ili9341_send_pixels(rt_uint16_t *pixels, int len); void ili9341_send_pixels(rt_uint16_t *pixels, int len);
#if defined(NU_PKG_USING_ILI9341_SPI) #if defined(NU_PKG_USING_ILI9341_SPI)
rt_err_t rt_hw_lcd_ili9341_spi_init(const char *spibusname); rt_err_t rt_hw_lcd_ili9341_spi_init(const char *spibusname, void *pvUserData);
#elif defined(NU_PKG_USING_ILI9341_EBI) #elif defined(NU_PKG_USING_ILI9341_EBI)
rt_err_t rt_hw_lcd_ili9341_ebi_init(rt_uint32_t ebi_base); rt_err_t rt_hw_lcd_ili9341_ebi_init(rt_uint32_t ebi_base);
#endif #endif
......
from building import *
Import('rtconfig')
src = []
cwd = GetCurrentDir()
src += Glob('*.c')
path = [cwd]
# add src and include to group.
group = DefineGroup('nu_pkgs_ili_tpc', src, depend = ['NU_PKG_USING_ILI_TPC'], CPPPATH = path)
Return('group')
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-25 Wayne the first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <nu_bitutil.h>
#define DBG_TAG "ili_tpc"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include "ili.h"
#define ILI_MAX_TOUCH 5
#define ILI_ADDRESS 0x41
#define BL_V1_8 0x108
#define BL_V1_7 0x107
#define BL_V1_6 0x106
#define ILITEK_TP_CMD_GET_TP_RES 0x20
#define ILITEK_TP_CMD_GET_SCRN_RES 0x21
#define ILITEK_TP_CMD_SET_IC_SLEEP 0x30
#define ILITEK_TP_CMD_SET_IC_WAKE 0x31
#define ILITEK_TP_CMD_GET_FW_VER 0x40
#define ILITEK_TP_CMD_GET_PRL_VER 0x42
#define ILITEK_TP_CMD_GET_MCU_VER 0x61
#define ILITEK_TP_CMD_GET_IC_MODE 0xC0
#define ILITEK_TP_CMD_RESET 0x60
#define REPORT_COUNT_ADDRESS 61
struct ili_protocol_info
{
rt_uint16_t ver;
rt_uint8_t ver_major;
};
struct ili_ts_data
{
struct rt_touch_device touch_device;
struct rt_i2c_client *client;
rt_base_t reset_pin;
rt_base_t irq_pin;
struct ili_protocol_info ptl;
rt_uint8_t product_id[30];
rt_uint16_t mcu_ver;
rt_uint8_t ic_mode;
rt_uint8_t firmware_ver[8];
rt_int32_t screen_max_x;
rt_int32_t screen_max_y;
rt_int32_t screen_min_x;
rt_int32_t screen_min_y;
rt_int32_t max_tp;
};
typedef struct ili_ts_data *ili_ts_data_t;
// Private data
static struct ili_ts_data g_iliTsData;
static rt_err_t ili_i2c_write_and_read(struct rt_i2c_client *psI2cClient,
rt_uint8_t *cmd, int write_len, int delay,
rt_uint8_t *data, int read_len)
{
struct rt_i2c_msg msgs[] =
{
{
.addr = psI2cClient->client_addr,
.flags = RT_I2C_WR,
.len = write_len,
.buf = cmd,
},
{
.addr = psI2cClient->client_addr,
.flags = RT_I2C_RD,
.len = read_len,
.buf = data,
},
};
if (delay == 0 && write_len > 0 && read_len > 0)
{
if (rt_i2c_transfer(psI2cClient->bus, msgs, 2) != 2)
goto exit_ili_i2c_write_and_read;
}
else
{
if (write_len > 0)
{
if (rt_i2c_transfer(psI2cClient->bus, msgs, 1) != 1)
goto exit_ili_i2c_write_and_read;
}
if (delay > 0)
rt_thread_mdelay(delay);
if (read_len > 0)
{
if (rt_i2c_transfer(psI2cClient->bus, msgs + 1, 1) != 1)
goto exit_ili_i2c_write_and_read;
}
}
return RT_EOK;
exit_ili_i2c_write_and_read:
return -RT_ERROR;
}
static int ili_get_ptl_ver(ili_ts_data_t psIliTs,
rt_uint16_t cmd, rt_uint8_t *inbuf, rt_uint8_t *outbuf)
{
int error;
rt_uint8_t buf[64];
buf[0] = cmd;
error = ili_i2c_write_and_read(psIliTs->client, buf, 1, 5, outbuf, 3);
if (error)
return error;
psIliTs->ptl.ver = nu_get16_be(outbuf);
psIliTs->ptl.ver_major = outbuf[0];
return 0;
}
static int ili_get_mcu_ver(ili_ts_data_t psIliTs,
rt_uint16_t cmd, rt_uint8_t *inbuf, rt_uint8_t *outbuf)
{
int error;
rt_uint8_t buf[64];
buf[0] = cmd;
error = ili_i2c_write_and_read(psIliTs->client, buf, 1, 5, outbuf, 32);
if (error)
return error;
psIliTs->mcu_ver = nu_get16_le(outbuf);
rt_memset(psIliTs->product_id, 0, sizeof(psIliTs->product_id));
rt_memcpy(psIliTs->product_id, outbuf + 6, 26);
return 0;
}
static int ili_get_fw_ver(ili_ts_data_t psIliTs,
rt_uint16_t cmd, rt_uint8_t *inbuf, rt_uint8_t *outbuf)
{
int error;
rt_uint8_t buf[64];
buf[0] = cmd;
error = ili_i2c_write_and_read(psIliTs->client, buf, 1, 5, outbuf, 8);
if (error)
return error;
rt_memcpy(psIliTs->firmware_ver, outbuf, 8);
return 0;
}
static int ili_get_scrn_res(ili_ts_data_t psIliTs,
rt_uint16_t cmd, rt_uint8_t *inbuf, rt_uint8_t *outbuf)
{
int error;
rt_uint8_t buf[64];
buf[0] = cmd;
error = ili_i2c_write_and_read(psIliTs->client, buf, 1, 5, outbuf, 8);
if (error)
return error;
psIliTs->screen_min_x = nu_get16_le(outbuf);
psIliTs->screen_min_y = nu_get16_le(outbuf + 2);
psIliTs->screen_max_x = nu_get16_le(outbuf + 4);
psIliTs->screen_max_y = nu_get16_le(outbuf + 6);
return 0;
}
static int ili_get_tp_res(ili_ts_data_t psIliTs,
rt_uint16_t cmd, rt_uint8_t *inbuf, rt_uint8_t *outbuf)
{
int error;
rt_uint8_t buf[64];
buf[0] = cmd;
error = ili_i2c_write_and_read(psIliTs->client, buf, 1, 5, outbuf, 15);
if (error)
return error;
psIliTs->max_tp = outbuf[8];
if (psIliTs->max_tp > ILI_MAX_TOUCH)
{
return -RT_EINVAL;
}
return 0;
}
static int ili_get_ic_mode(ili_ts_data_t psIliTs,
rt_uint16_t cmd, rt_uint8_t *inbuf, rt_uint8_t *outbuf)
{
int error;
rt_uint8_t buf[64];
buf[0] = cmd;
error = ili_i2c_write_and_read(psIliTs->client, buf, 1, 5, outbuf, 2);
if (error)
return error;
psIliTs->ic_mode = outbuf[0];
return 0;
}
static int ili_send_soft_reset(ili_ts_data_t psIliTs,
rt_uint16_t cmd, rt_uint8_t *inbuf, rt_uint8_t *outbuf)
{
int error;
rt_uint8_t buf[64];
buf[0] = cmd;
error = ili_i2c_write_and_read(psIliTs->client, buf, 1, 0, RT_NULL, 0);
if (error)
return error;
return 0;
}
static void ili_tpc_reset(ili_ts_data_t psIliTs, int delay_ms)
{
if (0)
{
//FIXME
/* hw pin init*/
rt_pin_mode(psIliTs->reset_pin, PIN_MODE_OUTPUT);
/* Reset */
rt_pin_write(psIliTs->reset_pin, PIN_HIGH);
rt_thread_mdelay(10);
rt_pin_write(psIliTs->reset_pin, PIN_LOW);
}
else
{
rt_err_t error;
error = ili_send_soft_reset(psIliTs, ILITEK_TP_CMD_RESET, RT_NULL, RT_NULL);
if (error)
return;
}
rt_thread_mdelay(delay_ms);
}
static rt_err_t ili_get_info(ili_ts_data_t psIliTs, struct rt_touch_info *info)
{
rt_uint8_t outbuf[256];
rt_err_t error;
error = ili_get_ptl_ver(psIliTs, ILITEK_TP_CMD_GET_PRL_VER, RT_NULL, outbuf);
if (error)
goto exit_ili_get_info;
error = ili_get_mcu_ver(psIliTs, ILITEK_TP_CMD_GET_MCU_VER, RT_NULL, outbuf);
if (error)
goto exit_ili_get_info;
error = ili_get_fw_ver(psIliTs, ILITEK_TP_CMD_GET_FW_VER, NULL, outbuf);
if (error)
goto exit_ili_get_info;
error = ili_get_scrn_res(psIliTs, ILITEK_TP_CMD_GET_SCRN_RES, NULL, outbuf);
if (error)
goto exit_ili_get_info;
error = ili_get_tp_res(psIliTs, ILITEK_TP_CMD_GET_TP_RES, NULL, outbuf);
if (error)
goto exit_ili_get_info;
error = ili_get_ic_mode(psIliTs, ILITEK_TP_CMD_GET_IC_MODE, NULL, outbuf);
if (error)
goto exit_ili_get_info;
LOG_I("touch device probed");
return RT_EOK;
exit_ili_get_info:
return -RT_ERROR;
}
static void ili_info_dump(ili_ts_data_t psIliTs)
{
rt_kprintf("reset_pin: %d\n", psIliTs->reset_pin);
rt_kprintf("irq_pin: %d\n", psIliTs->irq_pin);
rt_kprintf("ptl.ver: %x \n", psIliTs->ptl.ver_major);
rt_kprintf("mcu_ver: %x\n", psIliTs->mcu_ver);
rt_kprintf("firmware_ver:[%02X%02X.%02X%02X.%02X%02X.%02X%02X]\n",
psIliTs->firmware_ver[0],
psIliTs->firmware_ver[1],
psIliTs->firmware_ver[2],
psIliTs->firmware_ver[3],
psIliTs->firmware_ver[4],
psIliTs->firmware_ver[5],
psIliTs->firmware_ver[6],
psIliTs->firmware_ver[7]);
rt_kprintf("product_id: %s\n", psIliTs->product_id);
rt_kprintf("screen_max_x: %d\n", psIliTs->screen_max_x);
rt_kprintf("screen_max_y: %d\n", psIliTs->screen_max_y);
rt_kprintf("screen_min_x: %d\n", psIliTs->screen_min_x);
rt_kprintf("screen_min_y: %d\n", psIliTs->screen_min_y);
rt_kprintf("max_tp: %d\n", psIliTs->max_tp);
rt_kprintf("ic_mode: %d\n", psIliTs->ic_mode);
}
static int16_t pre_x[ILI_MAX_TOUCH] = {-1, -1, -1, -1, -1};
static int16_t pre_y[ILI_MAX_TOUCH] = {-1, -1, -1, -1, -1};
static int16_t pre_w[ILI_MAX_TOUCH] = {-1, -1, -1, -1, -1};
static rt_uint8_t s_tp_dowm[ILI_MAX_TOUCH];
static void ili_touch_up(void *buf, int8_t id)
{
struct rt_touch_data *read_data = (struct rt_touch_data *)buf;
if (s_tp_dowm[id] == 1)
{
s_tp_dowm[id] = 0;
read_data[id].event = RT_TOUCH_EVENT_UP;
}
else
{
read_data[id].event = RT_TOUCH_EVENT_NONE;
}
read_data[id].timestamp = rt_touch_get_ts();
read_data[id].width = pre_w[id];
read_data[id].x_coordinate = pre_x[id];
read_data[id].y_coordinate = pre_y[id];
read_data[id].track_id = id;
pre_x[id] = -1; /* last point is none */
pre_y[id] = -1;
pre_w[id] = -1;
}
static void ili_touch_down(void *buf, int8_t id, int16_t x, int16_t y, int16_t w)
{
struct rt_touch_data *read_data = (struct rt_touch_data *)buf;
if (s_tp_dowm[id] == 1)
{
read_data[id].event = RT_TOUCH_EVENT_MOVE;
}
else
{
read_data[id].event = RT_TOUCH_EVENT_DOWN;
s_tp_dowm[id] = 1;
}
read_data[id].timestamp = rt_touch_get_ts();
read_data[id].width = w;
read_data[id].x_coordinate = x;
read_data[id].y_coordinate = y;
read_data[id].track_id = id;
pre_x[id] = x; /* save last point */
pre_y[id] = y;
pre_w[id] = w;
}
static rt_size_t ili_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
{
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
struct ili_ts_data *ts = (ili_ts_data_t)touch;
uint8_t tmpbuf[256] = {0};
rt_err_t error = 0;
int packet_len = 5;
int packet_max_point = 10;
int8_t touch_num;
int i, count;
uint16_t x, y;
int32_t tip, point_id;
static rt_uint8_t pre_touch = 0;
static int8_t pre_id[ILI_MAX_TOUCH] = {0};
error = ili_i2c_write_and_read(ts->client, NULL, 0, 0, tmpbuf, 64);
if (error)
{
LOG_E("get touch info failed, err:%d\n", error);
goto exit_ili_read_point;
}
touch_num = tmpbuf[REPORT_COUNT_ADDRESS];
if (touch_num > ts->max_tp)
{
LOG_E("FW report max point:%d > panel info. max:%d\n", touch_num, ts->max_tp);
goto exit_ili_read_point;
}
count = DIV_ROUND_UP(touch_num, packet_max_point);
for (i = 1; i < count; i++)
{
error = ili_i2c_write_and_read(ts->client, NULL, 0, 0, tmpbuf + i * 64, 64);
if (error)
{
LOG_E("get touch info. failed, cnt:%d, err:%d\n", count, error);
goto exit_ili_read_point;
}
}
if (pre_touch > touch_num) /* point up */
{
for (i = 0; i < pre_touch; i++)
{
rt_uint8_t j;
for (j = 0; j < touch_num; j++) /* this time touch num */
{
point_id = tmpbuf[j * packet_len + 1] & 0x3F;
if (pre_id[i] == point_id) /* this id is not free */
break;
if (j >= touch_num - 1)
{
ili_touch_up(buf, pre_id[i]);
}
}
}
}
if (touch_num > 0)
{
uint32_t range_x = touch->info.range_x;
uint32_t range_y = touch->info.range_y;
for (i = 0; i < touch_num; i++)
{
tip = tmpbuf[i * packet_len + 1] & 0x40;
point_id = tmpbuf[i * packet_len + 1] & 0x3F;
pre_id[i] = point_id;
if (!tip)
{
// Up
ili_touch_up(buf, point_id);
continue;
}
x = nu_get16_le(tmpbuf + i * packet_len + 2);
y = nu_get16_le(tmpbuf + i * packet_len + 4);
if (x > ts->screen_max_x || x < ts->screen_min_x ||
y > ts->screen_max_y || y < ts->screen_min_y)
{
LOG_E("invalid position, X[%d,%u,%d], Y[%d,%u,%d]\n",
ts->screen_min_x, x, ts->screen_max_x,
ts->screen_min_y, y, ts->screen_max_y);
continue;
}
x = (uint16_t)(range_x * x / ts->screen_max_x);
y = (uint16_t)(range_y * y / ts->screen_max_y);
ili_touch_down(buf, point_id, x, y, 255);
}
}
pre_touch = touch_num;
return read_num;
exit_ili_read_point:
return 0;
}
static rt_err_t ili_control(struct rt_touch_device *touch, int cmd, void *arg)
{
switch (cmd)
{
case RT_TOUCH_CTRL_GET_ID:
{
RT_ASSERT(arg);
rt_uint8_t *pu8ID = arg;
rt_memcpy((void *)pu8ID, (void *)&g_iliTsData.product_id[0], 8);
}
break;
case RT_TOUCH_CTRL_GET_INFO:
{
RT_ASSERT(arg);
touch->info.type = RT_TOUCH_TYPE_CAPACITANCE;
touch->info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
touch->info.point_num = g_iliTsData.max_tp;
rt_memcpy(arg, &touch->info, sizeof(struct rt_touch_info));
}
break;
case RT_TOUCH_CTRL_SET_X_RANGE:
{
RT_ASSERT(arg);
uint16_t range_x = *(rt_uint16_t *)arg;
if (range_x > g_iliTsData.screen_max_x || range_x < g_iliTsData.screen_min_x)
{
LOG_E("Set x range failed. %d", range_x);
}
else
{
touch->info.range_x = range_x;
}
}
break;
case RT_TOUCH_CTRL_SET_Y_RANGE:
{
RT_ASSERT(arg);
uint16_t range_y = *(rt_uint16_t *)arg;
if (range_y > g_iliTsData.screen_max_y || range_y < g_iliTsData.screen_min_y)
{
LOG_E("Set y range failed. %d", range_y);
}
else
{
touch->info.range_y = range_y;
}
}
break;
case RT_TOUCH_CTRL_SET_MODE:
{
rt_uint16_t trig_type;
RT_ASSERT(arg);
trig_type = *(rt_uint16_t *)arg;
switch (trig_type)
{
case RT_DEVICE_FLAG_INT_RX:
break;
case RT_DEVICE_FLAG_RDONLY:
break;
default:
break;
}
}
break;
default:
{
}
break;
}
return RT_EOK;
}
static struct rt_touch_ops ili_touch_ops =
{
.touch_readpoint = ili_read_point,
.touch_control = ili_control,
};
int rt_hw_ili_tpc_init(const char *name, struct rt_touch_config *cfg)
{
struct rt_touch_device *touch_device = RT_NULL;
rt_uint32_t bus_speed = 400000;
touch_device = (struct rt_touch_device *)&g_iliTsData.touch_device;
rt_memset((void *)touch_device, 0, sizeof(struct rt_touch_device));
g_iliTsData.client = (struct rt_i2c_client *)rt_malloc(sizeof(struct rt_i2c_client));
if (g_iliTsData.client == RT_NULL)
{
LOG_E("touch device malloc fail");
goto exit_rt_hw_ili_tpc_init;
}
rt_memset((void *)g_iliTsData.client, 0, sizeof(struct rt_i2c_client));
g_iliTsData.reset_pin = *((rt_base_t *)cfg->user_data);
g_iliTsData.irq_pin = cfg->irq_pin.pin;
g_iliTsData.client->client_addr = ILI_ADDRESS;
g_iliTsData.client->bus = (struct rt_i2c_bus_device *)rt_device_find(cfg->dev_name);
if (g_iliTsData.client->bus == RT_NULL)
{
LOG_E("Can't find %s device", cfg->dev_name);
goto exit_rt_hw_ili_tpc_init;
}
if (rt_device_open((rt_device_t)g_iliTsData.client->bus, RT_DEVICE_FLAG_RDWR) != RT_EOK)
{
LOG_E("open %s device failed", cfg->dev_name);
goto exit_rt_hw_ili_tpc_init;
}
/* register touch device */
rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
touch_device->ops = &ili_touch_ops;
if (rt_hw_touch_register(touch_device, name, RT_DEVICE_FLAG_INT_RX, RT_NULL) != RT_EOK)
{
LOG_E("register %s device failed", name);
goto exit_rt_hw_ili_tpc_init;
}
ili_tpc_reset(&g_iliTsData, 300);
if (rt_device_control((rt_device_t)g_iliTsData.client->bus, RT_I2C_DEV_CTRL_CLK, &bus_speed) != RT_EOK)
{
LOG_E("control %s device failed", cfg->dev_name);
goto exit_rt_hw_ili_tpc_init;
}
/* Probe */
if (ili_get_info(&g_iliTsData, &touch_device->info) != RT_EOK)
{
LOG_E("Get info failed");
return -RT_ERROR;
}
ili_info_dump(&g_iliTsData);
return 0;
exit_rt_hw_ili_tpc_init:
if (g_iliTsData.client)
rt_free(g_iliTsData.client);
return -RT_ERROR;
}
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-25 Wayne the first version
*/
#ifndef __ILI_H__
#define __ILI_H__
#include "touch.h"
int rt_hw_ili_tpc_init(const char *name, struct rt_touch_config *cfg);
#endif /* ili2130.h */
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-25 Wayne the first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "ili.h"
#define THREAD_PRIORITY 5
#define THREAD_STACK_SIZE 2048
#define THREAD_TIMESLICE 5
static rt_sem_t tpc_sem = RT_NULL;
RT_WEAK void nu_touch_inputevent_cb(rt_int16_t x, rt_int16_t y, rt_uint8_t state)
{
rt_kprintf("[%d] %d %d\n", state, x, y);
}
static rt_err_t rx_callback(rt_device_t dev, rt_size_t size)
{
return rt_sem_release(tpc_sem);
}
static void tpc_entry(void *parameter)
{
struct rt_touch_data *read_data;
struct rt_touch_info info;
rt_device_t dev = RT_NULL;
const char *name = "ili_tpc";
rt_uint32_t x_range = BSP_LCD_WIDTH;
rt_uint32_t y_range = BSP_LCD_HEIGHT;
dev = rt_device_find(name);
if (dev == RT_NULL)
{
rt_kprintf("can't find device:%s\n", name);
return;
}
if (rt_device_open(dev, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
{
rt_kprintf("open device failed!");
return;
}
rt_kprintf("[%s] x: %d, y: %d\n", __func__, x_range, y_range);
rt_device_control(dev, RT_TOUCH_CTRL_SET_X_RANGE, &x_range); /* if possible you can set your x y coordinate*/
rt_device_control(dev, RT_TOUCH_CTRL_SET_Y_RANGE, &y_range);
tpc_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_FIFO);
if (tpc_sem == RT_NULL)
{
rt_kprintf("create dynamic semaphore failed.\n");
return;
}
rt_device_set_rx_indicate(dev, rx_callback);
rt_device_control(dev, RT_TOUCH_CTRL_GET_INFO, &info);
rt_kprintf("range_x = %d \n", info.range_x);
rt_kprintf("range_y = %d \n", info.range_y);
rt_kprintf("point_num = %d \n", info.point_num);
read_data = (struct rt_touch_data *)rt_malloc(sizeof(struct rt_touch_data) * info.point_num);
RT_ASSERT(read_data);
rt_memset(read_data, 0, sizeof(struct rt_touch_data) * info.point_num);
while (1)
{
rt_sem_take(tpc_sem, RT_WAITING_FOREVER);
rt_device_control(dev, RT_TOUCH_CTRL_DISABLE_INT, RT_NULL);
if (rt_device_read(dev, 0, read_data, info.point_num) == info.point_num)
{
for (rt_uint8_t i = 0; i < 1; i++) // Only report one point.
{
if (read_data[i].event == RT_TOUCH_EVENT_DOWN
|| read_data[i].event == RT_TOUCH_EVENT_UP
|| read_data[i].event == RT_TOUCH_EVENT_MOVE)
{
//rt_kprintf("[%d] %d %d\n", read_data[i].event, read_data[i].x_coordinate, read_data[i].y_coordinate);
nu_touch_inputevent_cb(read_data[i].x_coordinate, read_data[i].y_coordinate, read_data[i].event);
}
}
}
rt_device_control(dev, RT_TOUCH_CTRL_ENABLE_INT, RT_NULL);
}
}
/* Test function */
int tpc_sample(void)
{
rt_thread_t tpc_thread;
tpc_thread = rt_thread_create("tpc",
tpc_entry,
RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY,
THREAD_TIMESLICE);
if (tpc_thread != RT_NULL)
rt_thread_startup(tpc_thread);
return 0;
}
INIT_APP_EXPORT(tpc_sample);
...@@ -57,14 +57,28 @@ menu "Nuvoton Packages Config" ...@@ -57,14 +57,28 @@ menu "Nuvoton Packages Config"
Choose this option if you the ili9341 device is with EBI interface. Choose this option if you the ili9341 device is with EBI interface.
endchoice endchoice
if NU_PKG_USING_ILI9341_SPI
config NU_PKG_USING_ILI9341_SPI_CLK_FREQ
int "Set SPI Clock frequency"
default 48000000
endif
config NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER config NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER
bool "Create an offscreen framebuffer." bool "Create an offscreen framebuffer."
default n default n
if NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER
config NU_PKG_ILI9341_LINE_BUFFER_NUMBER
int "Allocate Line buffer number."
range 1 240
default 240
endif
config NU_PKG_ILI9341_HORIZONTAL config NU_PKG_ILI9341_HORIZONTAL
bool bool
default y default y
config BSP_LCD_BPP config BSP_LCD_BPP
int int
default 16 if NU_PKG_USING_ILI9341 default 16 if NU_PKG_USING_ILI9341
...@@ -79,6 +93,67 @@ menu "Nuvoton Packages Config" ...@@ -79,6 +93,67 @@ menu "Nuvoton Packages Config"
endif endif
config NU_PKG_USING_SSD1963
bool "SSD1963 LCD Panel"
select BSP_USING_GPIO
default n
if NU_PKG_USING_SSD1963
choice
prompt "Select SSD1963 interface"
config NU_PKG_USING_SSD1963_EBI
select BSP_USING_EBI
bool "SSD1963_EBI"
help
Choose this option if you the SSD1963 device is with EBI interface.
endchoice
config NU_PKG_SSD1963_WITH_OFFSCREEN_FRAMEBUFFER
bool "Create an offscreen framebuffer."
default n
if NU_PKG_SSD1963_WITH_OFFSCREEN_FRAMEBUFFER
config NU_PKG_SSD1963_LINE_BUFFER_NUMBER
int "Allocate Line buffer number."
range 16 272
default 272
endif
config BSP_LCD_BPP
int
default 16 if NU_PKG_USING_SSD1963
config BSP_LCD_WIDTH
int
default 480 if NU_PKG_USING_SSD1963
config BSP_LCD_HEIGHT
int
default 272 if NU_PKG_USING_SSD1963
endif
config NU_PKG_USING_ILI_TPC
bool "ILI Series TPC"
select RT_USING_TOUCH
select RT_USING_I2C
select BSP_USING_I2C
default n
config NU_PKG_USING_ADC_TOUCH
bool "ADC touch function"
default n
if NU_PKG_USING_ADC_TOUCH
config NU_PKG_USING_ADC_TOUCH_SW
bool "Using SW ADC touch"
select RT_USING_ADC
default n
endif
config NU_PKG_USING_SPINAND config NU_PKG_USING_SPINAND
bool "SPI NAND flash." bool "SPI NAND flash."
select BSP_USING_QSPI select BSP_USING_QSPI
......
...@@ -14,6 +14,24 @@ ...@@ -14,6 +14,24 @@
#if defined(__ICCARM__) #if defined(__ICCARM__)
#include <arm_math.h> #include <arm_math.h>
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler 6 */
#ifdef __has_include
#if __has_include("cmsis_armclang.h")
#include "cmsis_armclang.h"
#endif
#endif
#elif defined(__ARMCC_VERSION)
#ifdef __has_include
#if __has_include("cmsis_armcc.h")
#include "cmsis_armcc.h"
#endif
#endif
#endif
#include <stdint.h>
#if !defined(__STATIC_INLINE)
#define __STATIC_INLINE static inline
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
...@@ -41,9 +59,10 @@ extern "C" { ...@@ -41,9 +59,10 @@ extern "C" {
Find Highest Set Find Highest Set
nu_clz will start zero-counting from MSB and return the number. nu_clz will start zero-counting from MSB and return the number.
*/ */
__STATIC_INLINE int nu_clz(uint32_t x) __STATIC_INLINE int nu_clz(uint32_t x)
{ {
return x ? __CLZ(x):32; return x ? __CLZ(x) : 32;
} }
/* Count Leading Ones in word - Find Highest Zero /* Count Leading Ones in word - Find Highest Zero
......
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
group = []
src = Split("""
lcd_ssd1963.c
""")
CPPPATH = [cwd]
if GetDepend('NU_PKG_USING_SSD1963_EBI'):
src += Glob('ssd1963_ebi.c')
if GetDepend('NU_PKG_USING_SSD1963'):
group = DefineGroup('nu_pkgs_ssd1963', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
/**************************************************************************//**
*
* @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-2-23 Wayne First version
*
******************************************************************************/
#include <rtconfig.h>
#if defined(NU_PKG_USING_SSD1963)
#include <rtdevice.h>
#include <lcd_ssd1963.h>
#if defined(NU_PKG_SSD1963_WITH_OFFSCREEN_FRAMEBUFFER)
#if !defined(NU_PKG_SSD1963_LINE_BUFFER_NUMBER)
#define NU_PKG_SSD1963_LINE_BUFFER_NUMBER YSIZE_PHYS
#endif
#endif
#define ssd1963_delay_ms(ms) rt_thread_mdelay(ms)
static struct rt_device_graphic_info g_SSD1963Info =
{
.bits_per_pixel = 16,
.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565,
.framebuffer = RT_NULL,
.width = XSIZE_PHYS,
.pitch = XSIZE_PHYS * 2,
.height = YSIZE_PHYS
};
static rt_err_t ssd1963_pin_init(void)
{
rt_pin_mode(BOARD_USING_SSD1963_PIN_DC, PIN_MODE_OUTPUT);
rt_pin_mode(BOARD_USING_SSD1963_PIN_RESET, PIN_MODE_OUTPUT);
rt_pin_mode(BOARD_USING_SSD1963_PIN_BACKLIGHT, PIN_MODE_OUTPUT);
rt_pin_mode(BOARD_USING_SSD1963_PIN_DISPLAY, PIN_MODE_OUTPUT);
CLR_RS;
CLR_RST;
SET_BACKLIGHT_OFF;
SET_DISP_OFF;
return RT_EOK;
}
static rt_err_t ssd1963_lcd_init(rt_device_t dev)
{
/* Hardware reset */
SET_RST;
ssd1963_delay_ms(5); // Delay 5ms
CLR_RST;
ssd1963_delay_ms(20); // Delay 20ms
SET_RST;
ssd1963_delay_ms(40); // Delay 40ms
/* Initial control registers */
ssd1963_send_cmd(0x01); //Software reset
ssd1963_delay_ms(10);
ssd1963_send_cmd(0xe0); //Start PLL. Before the start, the system was operated with the crystal oscillator or clock input.
ssd1963_send_cmd_parameter(0x01); //0: Disable PLL, 1:Enable PLL.
ssd1963_delay_ms(50);
ssd1963_send_cmd(0xe0);
ssd1963_send_cmd_parameter(0x03); //0: Disable PLL, 1:Enable PLL. 3:Enable+LOCK PLL
ssd1963_delay_ms(5);
ssd1963_send_cmd(0xb0); //SET LCD MODE SET TFT MODE
ssd1963_send_cmd_parameter(0x20); //SET 24Bit, Disable TFT FRC & dithering, DCLK in falling edge, LLINE Active low, LFRAME Active low
ssd1963_send_cmd_parameter(0x00); //SET TFT mode
ssd1963_send_cmd_parameter(0x01); //SET horizontal size=480-1 HightByte
ssd1963_send_cmd_parameter(0xdf); //SET horizontal size=480-1 LowByte
ssd1963_send_cmd_parameter(0x01); //SET vertical size=272-1 HightByte
ssd1963_send_cmd_parameter(0x0f); //SET vertical size=272-1 LowByte
ssd1963_send_cmd_parameter(0x00); //SET even/odd line RGB seq.=RGB
ssd1963_send_cmd(0xf0); //SET pixel data I/F format=16bit(565 format)
ssd1963_send_cmd_parameter(0x03);
//ssd1963_send_cmd(0xf0); //SET pixel data I/F format=8bit (666 format)
//ssd1963_send_cmd_parameter(0x00);
ssd1963_send_cmd(0x36); // SET read from frame buffer to the display is RGB
ssd1963_send_cmd_parameter(0x00);
ssd1963_send_cmd(0xe2);
ssd1963_send_cmd_parameter(0x1d);
ssd1963_send_cmd_parameter(0x02);
ssd1963_send_cmd_parameter(0x54);
ssd1963_send_cmd(0xe6); //SET pixel clock frequency
ssd1963_send_cmd_parameter(0x01);
ssd1963_send_cmd_parameter(0x99);
ssd1963_send_cmd_parameter(0x9a);
ssd1963_send_cmd(0xb4); //SET HBP,
ssd1963_send_cmd_parameter(0x02); //SET HSYNC Tatol = 525
ssd1963_send_cmd_parameter(0x0d);
ssd1963_send_cmd_parameter(0x00); //SET HBP = 20
ssd1963_send_cmd_parameter(0x14);
ssd1963_send_cmd_parameter(0x05); //SET VBP 5
ssd1963_send_cmd_parameter(0x00); //SET Hsync pulse start position
ssd1963_send_cmd_parameter(0x00);
ssd1963_send_cmd_parameter(0x00); //SET Hsync pulse subpixel start position
ssd1963_send_cmd(0xb6); //SET VBP,
ssd1963_send_cmd_parameter(0x01); //SET Vsync total 292
ssd1963_send_cmd_parameter(0x24);
ssd1963_send_cmd_parameter(0x00); //SET VBP = 10
ssd1963_send_cmd_parameter(0x0a);
ssd1963_send_cmd_parameter(0x05); //SET Vsync pulse 5
ssd1963_send_cmd_parameter(0x00); //SET Vsync pulse start position
ssd1963_send_cmd_parameter(0x00);
ssd1963_send_cmd(0x29); //SET display on
ssd1963_delay_ms(5);
SET_DISP_ON;
SET_BACKLIGHT_ON;
return RT_EOK;
}
#if defined(NU_PKG_SSD1963_WITH_OFFSCREEN_FRAMEBUFFER)
static void ssd1963_fillrect(uint16_t *pixels, struct rt_device_rect_info *pRectInfo)
{
ssd1963_set_column(pRectInfo->x, pRectInfo->x + pRectInfo->width - 1);
ssd1963_set_page(pRectInfo->y, pRectInfo->y + pRectInfo->height - 1);
ssd1963_send_cmd(0x2c);
ssd1963_send_pixels(pixels, pRectInfo->height * pRectInfo->width * 2);
}
#endif
static void ssd1963_fillscreen(rt_uint16_t color)
{
#if defined(NU_PKG_SSD1963_WITH_OFFSCREEN_FRAMEBUFFER)
struct rt_device_rect_info rectinfo;
int filled_line_num = 0;
while (filled_line_num < YSIZE_PHYS)
{
int pixel_count;
rectinfo.x = 0;
rectinfo.y = filled_line_num;
rectinfo.width = XSIZE_PHYS;
rectinfo.height = (NU_PKG_SSD1963_LINE_BUFFER_NUMBER < YSIZE_PHYS) ? NU_PKG_SSD1963_LINE_BUFFER_NUMBER : YSIZE_PHYS;
pixel_count = XSIZE_PHYS * NU_PKG_SSD1963_LINE_BUFFER_NUMBER;
rt_uint16_t *pu16ShadowBuf = (rt_uint16_t *)g_SSD1963Info.framebuffer;
while (pixel_count > 0)
{
*pu16ShadowBuf++ = color;
pixel_count--;
}
ssd1963_fillrect((uint16_t *)g_SSD1963Info.framebuffer, &rectinfo);
filled_line_num += NU_PKG_SSD1963_LINE_BUFFER_NUMBER;
}
#else
ssd1963_set_column(0, (XSIZE_PHYS - 1));
ssd1963_set_page(0, (YSIZE_PHYS - 1));
ssd1963_send_cmd(0x2c);
for (int i = 0; i < (XSIZE_PHYS * YSIZE_PHYS); i++)
ssd1963_send_pixel_data(color);
#endif
}
static void ssd1963_lcd_set_pixel(const char *color, int x, int y)
{
ssd1963_set_column(x, x);
ssd1963_set_page(y, y);
ssd1963_send_cmd(0x2c);
ssd1963_send_pixel_data(*(uint16_t *)color);
}
static void ssd1963_lcd_draw_hline(const char *pixel, int x1, int x2, int y)
{
ssd1963_set_column(x1, x2);
ssd1963_set_page(y, y);
ssd1963_send_cmd(0x2c);
for (; x1 < x2; x1++)
ssd1963_send_pixel_data(*(uint16_t *)pixel);
}
static void ssd1963_lcd_draw_vline(const char *pixel, int x, int y1, int y2)
{
ssd1963_set_column(x, x);
ssd1963_set_page(y1, y2);
ssd1963_send_cmd(0x2c);
for (; y1 < y2; y1++)
ssd1963_send_pixel_data(*(uint16_t *)pixel);
}
static void ssd1963_lcd_blit_line(const char *pixels, int x, int y, rt_size_t size)
{
rt_uint16_t *ptr = (rt_uint16_t *)pixels;
ssd1963_set_column(x, x + size);
ssd1963_set_page(y, y);
ssd1963_send_cmd(0x2c);
while (size--)
ssd1963_send_pixel_data(*ptr++);
}
static rt_err_t ssd1963_lcd_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}
static rt_err_t ssd1963_lcd_close(rt_device_t dev)
{
return RT_EOK;
}
static rt_err_t ssd1963_lcd_control(rt_device_t dev, int cmd, void *args)
{
switch (cmd)
{
case RTGRAPHIC_CTRL_GET_INFO:
{
struct rt_device_graphic_info *info;
info = (struct rt_device_graphic_info *) args;
RT_ASSERT(info != RT_NULL);
rt_memcpy(args, (void *)&g_SSD1963Info, sizeof(struct rt_device_graphic_info));
}
break;
case RTGRAPHIC_CTRL_RECT_UPDATE:
{
#if defined(NU_PKG_SSD1963_WITH_OFFSCREEN_FRAMEBUFFER)
struct rt_device_rect_info *psRectInfo = (struct rt_device_rect_info *)args;
rt_uint16_t *pixels = (rt_uint16_t *)g_SSD1963Info.framebuffer;
RT_ASSERT(args);
ssd1963_fillrect(pixels, psRectInfo);
#else
/* nothong to be done */
#endif
}
break;
default:
break;
}
return RT_EOK;
}
static struct rt_device lcd_device;
static struct rt_device_graphic_ops ssd1963_ops =
{
ssd1963_lcd_set_pixel,
ssd1963_lcd_get_pixel,
ssd1963_lcd_draw_hline,
ssd1963_lcd_draw_vline,
ssd1963_lcd_blit_line
};
int rt_hw_lcd_ssd1963_init(void)
{
ssd1963_pin_init();
/* register lcd device */
lcd_device.type = RT_Device_Class_Graphic;
lcd_device.init = ssd1963_lcd_init;
lcd_device.open = ssd1963_lcd_open;
lcd_device.close = ssd1963_lcd_close;
lcd_device.control = ssd1963_lcd_control;
lcd_device.read = RT_NULL;
lcd_device.write = RT_NULL;
lcd_device.user_data = &ssd1963_ops;
#if defined(NU_PKG_SSD1963_WITH_OFFSCREEN_FRAMEBUFFER)
g_SSD1963Info.framebuffer = rt_malloc_align((g_SSD1963Info.pitch * NU_PKG_SSD1963_LINE_BUFFER_NUMBER) + 32, 32);
RT_ASSERT(g_SSD1963Info.framebuffer != RT_NULL);
g_SSD1963Info.smem_len = g_SSD1963Info.pitch * NU_PKG_SSD1963_LINE_BUFFER_NUMBER;
#endif
/* register graphic device driver */
rt_device_register(&lcd_device, "lcd", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
return 0;
}
#ifdef RT_USING_FINSH
#define LINE_LEN 32
static void lcd_test(int argc, char *argv[])
{
uint16_t pixels[LINE_LEN];
uint16_t color;
int x, y, i;
x = y = 100;
ssd1963_lcd_init(NULL);
color = 0x0; //Black, RGB
rt_kprintf("Brush 0x%X on screen.\n", color);
ssd1963_fillscreen(color);
ssd1963_lcd_get_pixel((char *)&color, x, y);
rt_kprintf("lcd get pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
color = 0xffff; //White, RGB
rt_kprintf("Brush 0x%X on screen.\n", color);
ssd1963_fillscreen(color);
ssd1963_lcd_get_pixel((char *)&color, x, y);
rt_kprintf("lcd get pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
color = 0x1f; //Blue, RGB
rt_kprintf("Brush 0x%X on screen.\n", color);
ssd1963_fillscreen(color);
ssd1963_lcd_get_pixel((char *)&color, x, y);
rt_kprintf("lcd get pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
color = 0x07e0; //Green, RGB
rt_kprintf("Brush 0x%X on screen.\n", color);
ssd1963_fillscreen(color);
ssd1963_lcd_get_pixel((char *)&color, x, y);
rt_kprintf("lcd get pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
color = 0xf800; //Red, RGB
rt_kprintf("Brush 0x%X on screen.\n", color);
ssd1963_fillscreen(color);
ssd1963_lcd_get_pixel((char *)&color, x, y);
rt_kprintf("lcd get pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
color = 0xffff; //White, RGB
rt_kprintf("lcd draw hline, pixel: 0x%X, x1: %d, x2: %d, y: %d\n", color, x, x + 20, y);
ssd1963_lcd_draw_hline((const char *)&color, x, x + 20, y);
color = 0xffff; //White, RGB
rt_kprintf("lcd draw vline, pixel: 0x%X, x: %d, y: %d\n", color, y, y + 20);
ssd1963_lcd_draw_vline((const char *)&color, x, y, y + 20);
for (i = 0; i < LINE_LEN; i++)
pixels[i] = 20 + i * 5;
x = y = 50;
rt_kprintf("lcd blit line, start: x: %d, y: %d\n", x, y);
ssd1963_lcd_blit_line((const char *)&pixels[0], x, y, LINE_LEN);
x = y = 200;
color = 0x07E0; //Green, RGB
rt_kprintf("lcd set pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
ssd1963_lcd_set_pixel((const char *)&color, x, y);
color = 0x0;
ssd1963_lcd_get_pixel((char *)&color, x, y);
rt_kprintf("lcd get pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
x = y = 200;
color = 0x1f; //Blue, RGB
rt_kprintf("lcd set pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
ssd1963_lcd_set_pixel((const char *)&color, x, y);
color = 0x0;
ssd1963_lcd_get_pixel((char *)&color, x, y);
rt_kprintf("lcd get pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
x = y = 200;
color = 0xf800; //Red, RGB
rt_kprintf("lcd set pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
ssd1963_lcd_set_pixel((const char *)&color, x, y);
color = 0x0;
ssd1963_lcd_get_pixel((char *)&color, x, y);
rt_kprintf("lcd get pixel, pixel: 0x%X, x: %d, y: %d\n", color, x, y);
}
MSH_CMD_EXPORT(lcd_test, test lcd display);
#endif
#endif /* if defined(NU_PKG_USING_SSD1963) */
/**************************************************************************//**
*
* @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-2-23 Wayne First version
*
******************************************************************************/
#ifndef __LCD_SSD1963_H__
#define __LCD_SSD1963_H__
#include <rtconfig.h>
#include <rtdevice.h>
#define SET_RS rt_pin_write(BOARD_USING_SSD1963_PIN_DC, 1)
#define CLR_RS rt_pin_write(BOARD_USING_SSD1963_PIN_DC, 0)
#define SET_RST rt_pin_write(BOARD_USING_SSD1963_PIN_RESET, 1)
#define CLR_RST rt_pin_write(BOARD_USING_SSD1963_PIN_RESET, 0)
#define SET_BACKLIGHT_ON rt_pin_write(BOARD_USING_SSD1963_PIN_BACKLIGHT, 1)
#define SET_BACKLIGHT_OFF rt_pin_write(BOARD_USING_SSD1963_PIN_BACKLIGHT, 0)
#define SET_DISP_ON rt_pin_write(BOARD_USING_SSD1963_PIN_DISPLAY, 1)
#define SET_DISP_OFF rt_pin_write(BOARD_USING_SSD1963_PIN_DISPLAY, 0)
//
// Physical display size
//
//#if defined(NU_PKG_SSD1963_HORIZONTAL)
#define XSIZE_PHYS 480
#define YSIZE_PHYS 272
//#else
// #define XSIZE_PHYS 272
// #define YSIZE_PHYS 480
//#endif
int rt_hw_lcd_ssd1963_init(void);
void ssd1963_send_cmd(rt_uint8_t cmd);
void ssd1963_send_cmd_parameter(rt_uint8_t data);
void ssd1963_set_column(rt_uint16_t StartCol, rt_uint16_t EndCol);
void ssd1963_set_page(rt_uint16_t StartPage, rt_uint16_t EndPage);
void ssd1963_send_pixel_data(rt_uint16_t color);
void ssd1963_lcd_get_pixel(char *color, int x, int y);
void ssd1963_send_pixels(rt_uint16_t *pixels, int len);
#if defined(NU_PKG_USING_SSD1963_EBI)
rt_err_t rt_hw_lcd_ssd1963_ebi_init(rt_uint32_t ebi_base);
#endif
#endif /* __LCD_SSD1963_H__ */
/**************************************************************************//**
*
* @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-2-23 Wayne First version
*
******************************************************************************/
#include <rtconfig.h>
#if defined(NU_PKG_USING_SSD1963_EBI)
#include <lcd_ssd1963.h>
#include "drv_pdma.h"
#define SSD1963_ADDR_CMD 0x0
#define SSD1963_ADDR_DATA 0x0
#define ssd1963_reg_write(u32RegAddr) (*((volatile unsigned short *)(g_uint32_ssd1963_base+(SSD1963_ADDR_CMD))) = (u32RegAddr))
#define ssd1963_read_data() (*((volatile unsigned short *)(g_uint32_ssd1963_base+(SSD1963_ADDR_DATA))))
#define ssd1963_write_data(u32Data) (*((volatile unsigned short *)(g_uint32_ssd1963_base+(SSD1963_ADDR_DATA))) = (u32Data))
static rt_uint32_t g_uint32_ssd1963_base = 0;
void ssd1963_send_cmd(rt_uint8_t cmd)
{
CLR_RS;
ssd1963_reg_write(cmd);
SET_RS;
}
void ssd1963_send_cmd_parameter(rt_uint8_t data)
{
ssd1963_write_data(data);
}
void ssd1963_send_pixel_data(rt_uint16_t color)
{
ssd1963_write_data(color);
}
void ssd1963_send_pixels(rt_uint16_t *pixels, int len)
{
int count = len / sizeof(rt_uint16_t);
if (count < 1024)
{
// CPU feed
int i = 0;
while (i < count)
{
ssd1963_write_data(pixels[i]);
i++;
}
}
else
{
// PDMA-M2M feed
nu_pdma_mempush((void *)(g_uint32_ssd1963_base + (SSD1963_ADDR_DATA)), (void *)pixels, 16, count);
}
}
void ssd1963_set_column(uint16_t StartCol, uint16_t EndCol)
{
ssd1963_send_cmd(0x2A);
ssd1963_write_data((StartCol >> 8) & 0xFF);
ssd1963_write_data(StartCol & 0xFF);
ssd1963_write_data((EndCol >> 8) & 0xFF);
ssd1963_write_data(EndCol & 0xFF);
}
void ssd1963_set_page(uint16_t StartPage, uint16_t EndPage)
{
ssd1963_send_cmd(0x2B);
ssd1963_write_data((StartPage >> 8) & 0xFF);
ssd1963_write_data(StartPage & 0xFF);
ssd1963_write_data((EndPage >> 8) & 0xFF);
ssd1963_write_data(EndPage & 0xFF);
}
void ssd1963_lcd_get_pixel(char *color, int x, int y)
{
rt_uint16_t red = 0;
rt_uint16_t green = 0;
rt_uint16_t blue = 0;
if (x >= XSIZE_PHYS || y >= YSIZE_PHYS)
{
*(rt_uint16_t *)color = 0;
return;
}
ssd1963_set_column(x, x);
ssd1963_set_page(y, y);
ssd1963_send_cmd(0x2E);
ssd1963_read_data(); // Dummy
red = ssd1963_read_data(); // Red[4:0]@D15~D11
blue = ssd1963_read_data(); // Blue[4:0]@D15~D11
green = ssd1963_read_data(); // Green[5:0]@D15~D10
//BGR565: B in High byte, R in low byte
//*(rt_uint16_t *)color = (((blue >> 11) << 11) | ((green >> 10) << 5) | (red >> 11));
//RGB565: R in High byte, B in low byte
*(rt_uint16_t *)color = (((red >> 11) << 11) | ((green >> 10) << 5) | (blue >> 11));
}
rt_err_t rt_hw_lcd_ssd1963_ebi_init(rt_uint32_t ssd1963_base)
{
g_uint32_ssd1963_base = ssd1963_base;
return RT_EOK;
}
#endif /* if defined(NU_PKG_USING_SSD1963_EBI) */
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
/* Private define ---------------------------------------------------------------*/ /* Private define ---------------------------------------------------------------*/
#define DEF_ADC_TOUCH_SMPL_TICK 40 #define DEF_ADC_TOUCH_SMPL_TICK 40
#define TOUCH_MQ_LENGTH 64
/* Private Typedef --------------------------------------------------------------*/ /* Private Typedef --------------------------------------------------------------*/
struct nu_adc struct nu_adc
......
...@@ -15,14 +15,11 @@ ...@@ -15,14 +15,11 @@
#include <rtthread.h> #include <rtthread.h>
#include "nu_adc.h" #include "nu_adc.h"
#if defined(BSP_USING_ADC_TOUCH) #if defined(BSP_USING_ADC_TOUCH)
#include "touch.h" #include "touch.h"
#endif #endif
#define TOUCH_MQ_LENGTH 64
#define DEF_CAL_POINT_NUM 5
typedef enum typedef enum
{ {
eAdc_MF, //0 eAdc_MF, //0
...@@ -57,28 +54,10 @@ typedef struct ...@@ -57,28 +54,10 @@ typedef struct
typedef nu_adc_cb *nu_adc_cb_t; typedef nu_adc_cb *nu_adc_cb_t;
#if defined(BSP_USING_ADC_TOUCH) #if defined(BSP_USING_ADC_TOUCH)
typedef struct void nu_adc_touch_detect(rt_bool_t bStartDetect);
{ int32_t nu_adc_touch_read_xyz(uint32_t *bufX, uint32_t *bufY, uint32_t *bufZ0, uint32_t *bufZ1, int32_t dataCnt);
int32_t x; rt_err_t nu_adc_touch_enable(rt_touch_t psRtTouch);
int32_t y; rt_err_t nu_adc_touch_disable(void);
} S_COORDINATE_POINT;
typedef struct
{
int32_t a;
int32_t b;
int32_t c;
int32_t d;
int32_t e;
int32_t f;
int32_t div;
} S_CALIBRATION_MATRIX;
int32_t nu_adc_touch_read_xyz(uint32_t *bufX, uint32_t *bufY, uint32_t *bufZ0, uint32_t *bufZ1, int32_t dataCnt);
rt_err_t nu_adc_touch_enable(rt_touch_t psRtTouch);
rt_err_t nu_adc_touch_disable(void);
void nu_adc_touch_detect(rt_bool_t bStartDetect);
void nu_adc_touch_start_conv(void);
#endif #endif
#endif /* __DRV_ADC_H__ */ #endif /* __DRV_ADC_H__ */
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <netif/etharp.h> #include <netif/etharp.h>
#include <lwip/icmp.h> #include <lwip/icmp.h>
#include <lwip/pbuf.h> #include <lwip/pbuf.h>
#include <lwip/sys.h>
#include "lwipopts.h" #include "lwipopts.h"
#include "drv_sys.h" #include "drv_sys.h"
......
...@@ -177,7 +177,7 @@ static void nu_pdma_init(void) ...@@ -177,7 +177,7 @@ static void nu_pdma_init(void)
return; return;
nu_pdma_chn_mask = ~(NU_PDMA_CH_Msk); nu_pdma_chn_mask = ~(NU_PDMA_CH_Msk);
rt_memset(nu_pdma_chn_arr, 0x00, NU_PDMA_CH_MAX*sizeof(nu_pdma_chn_t)); rt_memset(nu_pdma_chn_arr, 0x00, NU_PDMA_CH_MAX * sizeof(nu_pdma_chn_t));
nu_sys_ipclk_enable(PDMA0CKEN); nu_sys_ipclk_enable(PDMA0CKEN);
nu_sys_ipclk_enable(PDMA1CKEN); nu_sys_ipclk_enable(PDMA1CKEN);
...@@ -1106,7 +1106,8 @@ void *nu_pdma_memcpy(void *dest, void *src, unsigned int count) ...@@ -1106,7 +1106,8 @@ void *nu_pdma_memcpy(void *dest, void *src, unsigned int count)
uint32_t u32dest = (uint32_t)dest + u32Offset; uint32_t u32dest = (uint32_t)dest + u32Offset;
if (((u32src % i) == (u32dest % i)) && if (((u32src % i) == (u32dest % i)) &&
((u32src % i) == 0) && (RT_ALIGN_DOWN(u32Remaining, i) >= i)) ((u32src % i) == 0) &&
(RT_ALIGN_DOWN(u32Remaining, i) >= i))
{ {
uint32_t u32TXCnt = u32Remaining / i; uint32_t u32TXCnt = u32Remaining / i;
if (u32TXCnt != nu_pdma_memfun((void *)u32dest, (void *)u32src, i * 8, u32TXCnt, eMemCtl_SrcInc_DstInc)) if (u32TXCnt != nu_pdma_memfun((void *)u32dest, (void *)u32src, i * 8, u32TXCnt, eMemCtl_SrcInc_DstInc))
......
...@@ -116,11 +116,13 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, ...@@ -116,11 +116,13 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device,
struct nu_spi *spi_bus; struct nu_spi *spi_bus;
uint32_t u32SPIMode; uint32_t u32SPIMode;
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL); RT_ASSERT(configuration != RT_NULL);
spi_bus = (struct nu_spi *) device->bus; spi_bus = (struct nu_spi *) device->bus;
pvUserData = device->parent.user_data;
/* Check mode */ /* Check mode */
switch (configuration->mode & RT_SPI_MODE_3) switch (configuration->mode & RT_SPI_MODE_3)
...@@ -162,12 +164,29 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, ...@@ -162,12 +164,29 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device,
if (configuration->mode & RT_SPI_CS_HIGH) if (configuration->mode & RT_SPI_CS_HIGH)
{ {
/* Set CS pin to LOW */ /* Set CS pin to LOW */
SPI_SET_SS_LOW(spi_bus->spi_base); if (pvUserData != RT_NULL)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
} }
else else
{ {
/* Set CS pin to HIGH */ /* Set CS pin to HIGH */
SPI_SET_SS_HIGH(spi_bus->spi_base); if (pvUserData != RT_NULL)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
/* Set CS pin to HIGH */
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
} }
if (configuration->mode & RT_SPI_MSB) if (configuration->mode & RT_SPI_MSB)
...@@ -371,6 +390,7 @@ rt_err_t nu_hw_spi_pdma_allocate(struct nu_spi *spi_bus) ...@@ -371,6 +390,7 @@ rt_err_t nu_hw_spi_pdma_allocate(struct nu_spi *spi_bus)
} }
spi_bus->m_psSemBus = rt_sem_create("spibus_sem", 0, RT_IPC_FLAG_FIFO); spi_bus->m_psSemBus = rt_sem_create("spibus_sem", 0, RT_IPC_FLAG_FIFO);
RT_ASSERT(spi_bus->m_psSemBus != RT_NULL);
return RT_EOK; return RT_EOK;
...@@ -550,6 +570,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -550,6 +570,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
struct nu_spi *spi_bus; struct nu_spi *spi_bus;
struct rt_spi_configuration *configuration; struct rt_spi_configuration *configuration;
uint8_t bytes_per_word; uint8_t bytes_per_word;
void *pvUserData;
RT_ASSERT(device != RT_NULL); RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus != RT_NULL);
...@@ -558,6 +579,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -558,6 +579,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
spi_bus = (struct nu_spi *) device->bus; spi_bus = (struct nu_spi *) device->bus;
configuration = (struct rt_spi_configuration *)&spi_bus->configuration; configuration = (struct rt_spi_configuration *)&spi_bus->configuration;
bytes_per_word = configuration->data_width / 8; bytes_per_word = configuration->data_width / 8;
pvUserData = device->parent.user_data;
if ((message->length % bytes_per_word) != 0) if ((message->length % bytes_per_word) != 0)
{ {
...@@ -570,13 +592,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -570,13 +592,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
{ {
if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_take && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
SPI_SET_SS_HIGH(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
else
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
} }
else else
{ {
SPI_SET_SS_LOW(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
else
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
} }
} }
...@@ -584,13 +622,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m ...@@ -584,13 +622,29 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS)) if (message->cs_release && !(configuration->mode & RT_SPI_NO_CS))
{ {
if (configuration->mode & RT_SPI_CS_HIGH) if (pvUserData != RT_NULL)
{ {
SPI_SET_SS_LOW(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
// set to LOW */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_LOW);
}
else
{
// set to HIGH */
rt_pin_write(*((rt_base_t *)pvUserData), PIN_HIGH);
}
} }
else else
{ {
SPI_SET_SS_HIGH(spi_bus->spi_base); if (configuration->mode & RT_SPI_CS_HIGH)
{
SPI_SET_SS_LOW(spi_bus->spi_base);
}
else
{
SPI_SET_SS_HIGH(spi_bus->spi_base);
}
} }
} }
......
...@@ -73,6 +73,7 @@ menu "Hardware Drivers Config" ...@@ -73,6 +73,7 @@ menu "Hardware Drivers Config"
bool "LCD ILI9341 (over spi0)" bool "LCD ILI9341 (over spi0)"
select RT_USING_TOUCH select RT_USING_TOUCH
select BSP_USING_ADC_TOUCH select BSP_USING_ADC_TOUCH
select NU_PKG_USING_ADC_TOUCH
select NU_PKG_USING_ILI9341 select NU_PKG_USING_ILI9341
select NU_PKG_USING_ILI9341_SPI select NU_PKG_USING_ILI9341_SPI
select NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER select NU_PKG_ILI9341_WITH_OFFSCREEN_FRAMEBUFFER
......
...@@ -189,6 +189,12 @@ static int rt_hw_spinand_init(void) ...@@ -189,6 +189,12 @@ static int rt_hw_spinand_init(void)
INIT_COMPONENT_EXPORT(rt_hw_spinand_init); INIT_COMPONENT_EXPORT(rt_hw_spinand_init);
#endif #endif
#if defined(BSP_USING_ADC_TOUCH) && defined(NU_PKG_USING_ADC_TOUCH)
#include "adc_touch.h"
#if (BSP_LCD_WIDTH==320) && (BSP_LCD_HEIGHT==240)
S_CALIBRATION_MATRIX g_sCalMat = { 43, -5839, 21672848, 4193, -11, -747882, 65536 };
#endif
#endif
#if defined(BOARD_USING_LCD_ILI9341) && defined(NU_PKG_USING_ILI9341_SPI) #if defined(BOARD_USING_LCD_ILI9341) && defined(NU_PKG_USING_ILI9341_SPI)
#include <lcd_ili9341.h> #include <lcd_ili9341.h>
...@@ -197,7 +203,7 @@ INIT_COMPONENT_EXPORT(rt_hw_spinand_init); ...@@ -197,7 +203,7 @@ INIT_COMPONENT_EXPORT(rt_hw_spinand_init);
#endif #endif
int rt_hw_ili9341_port(void) int rt_hw_ili9341_port(void)
{ {
if (rt_hw_lcd_ili9341_spi_init("spi0") != RT_EOK) if (rt_hw_lcd_ili9341_spi_init("spi0", RT_NULL) != RT_EOK)
return -1; return -1;
rt_hw_lcd_ili9341_init(); rt_hw_lcd_ili9341_init();
......
此差异已折叠。
...@@ -5,9 +5,13 @@ CPU = 'arm926' ...@@ -5,9 +5,13 @@ CPU = 'arm926'
# toolchains options # toolchains options
CROSS_TOOL = 'gcc' CROSS_TOOL = 'gcc'
#------- toolchains path -------------------------------------------------------
if os.getenv('RTT_CC'): if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC') CROSS_TOOL = os.getenv('RTT_CC')
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
# cross_tool provides the cross compiler
# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
if CROSS_TOOL == 'gcc': if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc' PLATFORM = 'gcc'
...@@ -20,7 +24,7 @@ if os.getenv('RTT_EXEC_PATH'): ...@@ -20,7 +24,7 @@ if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH') EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'debug' BUILD = 'debug'
#BUILD = 'release' #BUILD = ''
CORE = 'arm926ej-s' CORE = 'arm926ej-s'
MAP_FILE = 'rtthread_nuc980.map' MAP_FILE = 'rtthread_nuc980.map'
...@@ -32,9 +36,9 @@ if PLATFORM == 'gcc': ...@@ -32,9 +36,9 @@ if PLATFORM == 'gcc':
# toolchains # toolchains
PREFIX = 'arm-none-eabi-' PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc' CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc' AS = PREFIX + 'gcc'
AR = PREFIX + 'ar' AR = PREFIX + 'ar'
CXX = PREFIX + 'g++'
LINK = PREFIX + 'gcc' LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf' TARGET_EXT = 'elf'
SIZE = PREFIX + 'size' SIZE = PREFIX + 'size'
...@@ -53,11 +57,13 @@ if PLATFORM == 'gcc': ...@@ -53,11 +57,13 @@ if PLATFORM == 'gcc':
LPATH = '' LPATH = ''
if BUILD == 'debug': if BUILD == 'debug':
CFLAGS += ' -O2 -gdwarf-2' CFLAGS += ' -O0 -gdwarf-2 -g'
AFLAGS += ' -gdwarf-2' AFLAGS += ' -gdwarf-2'
else: else:
CFLAGS += ' -O2' CFLAGS += ' -O2'
CXXFLAGS = CFLAGS
POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n' POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n'
POST_ACTION += SIZE + ' $TARGET\n' POST_ACTION += SIZE + ' $TARGET\n'
#------- Keil settings --------------------------------------------------------- #------- Keil settings ---------------------------------------------------------
...@@ -79,7 +85,7 @@ elif PLATFORM == 'armcc': ...@@ -79,7 +85,7 @@ elif PLATFORM == 'armcc':
LFLAGS += ' --scatter ' + LINK_FILE + '.sct' LFLAGS += ' --scatter ' + LINK_FILE + '.sct'
if BUILD == 'debug': if BUILD == 'debug':
CFLAGS += ' -g -O2' CFLAGS += ' -g -O0'
AFLAGS += ' -g' AFLAGS += ' -g'
else: else:
CFLAGS += ' -O2' CFLAGS += ' -O2'
......
baudrate=115200 baudrate=115200
bootdelay=1 bootdelay=1
stderr=serial stderr=serial
stdin=serial stdin=serial
stdout=serial stdout=serial
loadrtt=nand read 0x80000000 0x200000 0x100000 loadrtt=nand read 0x80000000 0x200000 0x100000
bootcmd=run loadrtt;go 0x0 bootcmd=run loadrtt;go 0x0
\ No newline at end of file \ No newline at end of file
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
# RT-Thread Kernel # RT-Thread Kernel
# #
CONFIG_RT_NAME_MAX=16 CONFIG_RT_NAME_MAX=16
# CONFIG_RT_USING_BIG_ENDIAN is not set
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMP is not set # CONFIG_RT_USING_SMP is not set
CONFIG_RT_ALIGN_SIZE=4 CONFIG_RT_ALIGN_SIZE=4
...@@ -247,7 +246,6 @@ CONFIG_RT_USB_MSTORAGE_DISK_NAME="ramdisk1" ...@@ -247,7 +246,6 @@ CONFIG_RT_USB_MSTORAGE_DISK_NAME="ramdisk1"
# #
# POSIX layer and C standard library # POSIX layer and C standard library
# #
# CONFIG_RT_USING_MODULE is not set
CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# #
...@@ -263,7 +261,9 @@ CONFIG_RT_USING_POSIX_SELECT=y ...@@ -263,7 +261,9 @@ CONFIG_RT_USING_POSIX_SELECT=y
# CONFIG_RT_USING_POSIX_MMAN is not set # CONFIG_RT_USING_POSIX_MMAN is not set
# CONFIG_RT_USING_POSIX_DELAY is not set # CONFIG_RT_USING_POSIX_DELAY is not set
# CONFIG_RT_USING_POSIX_CLOCK is not set # CONFIG_RT_USING_POSIX_CLOCK is not set
# CONFIG_RT_USING_POSIX_TIMER is not set
# CONFIG_RT_USING_PTHREADS is not set # CONFIG_RT_USING_PTHREADS is not set
# CONFIG_RT_USING_MODULE is not set
# #
# Interprocess Communication (IPC) # Interprocess Communication (IPC)
...@@ -310,7 +310,6 @@ CONFIG_NETDEV_IPV6=0 ...@@ -310,7 +310,6 @@ CONFIG_NETDEV_IPV6=0
# #
CONFIG_RT_USING_LWIP=y CONFIG_RT_USING_LWIP=y
# CONFIG_RT_USING_LWIP141 is not set # CONFIG_RT_USING_LWIP141 is not set
# CONFIG_RT_USING_LWIP202 is not set
CONFIG_RT_USING_LWIP203=y CONFIG_RT_USING_LWIP203=y
# CONFIG_RT_USING_LWIP212 is not set # CONFIG_RT_USING_LWIP212 is not set
# CONFIG_RT_USING_LWIP_IPV6 is not set # CONFIG_RT_USING_LWIP_IPV6 is not set
...@@ -454,6 +453,7 @@ CONFIG_UTEST_THR_PRIORITY=20 ...@@ -454,6 +453,7 @@ CONFIG_UTEST_THR_PRIORITY=20
# CONFIG_PKG_USING_JOYLINK is not set # CONFIG_PKG_USING_JOYLINK is not set
# CONFIG_PKG_USING_EZ_IOT_OS is not set # CONFIG_PKG_USING_EZ_IOT_OS is not set
# CONFIG_PKG_USING_NIMBLE is not set # CONFIG_PKG_USING_NIMBLE is not set
# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
# CONFIG_PKG_USING_OTA_DOWNLOADER is not set # CONFIG_PKG_USING_OTA_DOWNLOADER is not set
# CONFIG_PKG_USING_IPMSG is not set # CONFIG_PKG_USING_IPMSG is not set
# CONFIG_PKG_USING_LSSDP is not set # CONFIG_PKG_USING_LSSDP is not set
...@@ -517,6 +517,8 @@ CONFIG_UTEST_THR_PRIORITY=20 ...@@ -517,6 +517,8 @@ CONFIG_UTEST_THR_PRIORITY=20
CONFIG_PKG_USING_LVGL=y CONFIG_PKG_USING_LVGL=y
CONFIG_PKG_LVGL_PATH="/packages/multimedia/LVGL/LVGL" CONFIG_PKG_LVGL_PATH="/packages/multimedia/LVGL/LVGL"
# CONFIG_PKG_USING_LVGL_EXAMPLES is not set # CONFIG_PKG_USING_LVGL_EXAMPLES is not set
# CONFIG_PKG_USING_LVGL_DEMOS is not set
# CONFIG_PKG_USING_LVGL_V820 is not set
CONFIG_PKG_USING_LVGL_V810=y CONFIG_PKG_USING_LVGL_V810=y
# CONFIG_PKG_USING_LVGL_LATEST_VERSION is not set # CONFIG_PKG_USING_LVGL_LATEST_VERSION is not set
CONFIG_PKG_LVGL_VER="v8.1.0" CONFIG_PKG_LVGL_VER="v8.1.0"
...@@ -553,6 +555,7 @@ CONFIG_PKG_LV_MUSIC_DEMO_VER="v0.1.1" ...@@ -553,6 +555,7 @@ CONFIG_PKG_LV_MUSIC_DEMO_VER="v0.1.1"
# CONFIG_PKG_USING_MCURSES is not set # CONFIG_PKG_USING_MCURSES is not set
# CONFIG_PKG_USING_TERMBOX is not set # CONFIG_PKG_USING_TERMBOX is not set
# CONFIG_PKG_USING_VT100 is not set # CONFIG_PKG_USING_VT100 is not set
# CONFIG_PKG_USING_QRCODE is not set
# #
# tools packages # tools packages
...@@ -563,7 +566,6 @@ CONFIG_PKG_LV_MUSIC_DEMO_VER="v0.1.1" ...@@ -563,7 +566,6 @@ CONFIG_PKG_LV_MUSIC_DEMO_VER="v0.1.1"
# CONFIG_PKG_USING_SYSTEMVIEW is not set # CONFIG_PKG_USING_SYSTEMVIEW is not set
# CONFIG_PKG_USING_SEGGER_RTT is not set # CONFIG_PKG_USING_SEGGER_RTT is not set
# CONFIG_PKG_USING_RDB is not set # CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_QRCODE is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set # CONFIG_PKG_USING_ULOG_EASYFLASH is not set
# CONFIG_PKG_USING_ULOG_FILE is not set # CONFIG_PKG_USING_ULOG_FILE is not set
# CONFIG_PKG_USING_LOGMGR is not set # CONFIG_PKG_USING_LOGMGR is not set
...@@ -614,6 +616,7 @@ CONFIG_PKG_LV_MUSIC_DEMO_VER="v0.1.1" ...@@ -614,6 +616,7 @@ CONFIG_PKG_LV_MUSIC_DEMO_VER="v0.1.1"
# CONFIG_PKG_USING_POSIX_GETLINE is not set # CONFIG_PKG_USING_POSIX_GETLINE is not set
# CONFIG_PKG_USING_POSIX_WCWIDTH is not set # CONFIG_PKG_USING_POSIX_WCWIDTH is not set
# CONFIG_PKG_USING_POSIX_ITOA is not set # CONFIG_PKG_USING_POSIX_ITOA is not set
# CONFIG_PKG_USING_POSIX_STRINGS is not set
# #
# acceleration: Assembly language or algorithmic acceleration packages # acceleration: Assembly language or algorithmic acceleration packages
...@@ -650,6 +653,7 @@ CONFIG_FAL_DEBUG=1 ...@@ -650,6 +653,7 @@ CONFIG_FAL_DEBUG=1
CONFIG_FAL_PART_HAS_TABLE_CFG=y CONFIG_FAL_PART_HAS_TABLE_CFG=y
CONFIG_FAL_USING_SFUD_PORT=y CONFIG_FAL_USING_SFUD_PORT=y
CONFIG_FAL_USING_NOR_FLASH_DEV_NAME="norflash0" CONFIG_FAL_USING_NOR_FLASH_DEV_NAME="norflash0"
# CONFIG_PKG_USING_FAL_V10000 is not set
# CONFIG_PKG_USING_FAL_V00500 is not set # CONFIG_PKG_USING_FAL_V00500 is not set
# CONFIG_PKG_USING_FAL_V00400 is not set # CONFIG_PKG_USING_FAL_V00400 is not set
# CONFIG_PKG_USING_FAL_V00300 is not set # CONFIG_PKG_USING_FAL_V00300 is not set
...@@ -687,7 +691,7 @@ CONFIG_PKG_RAMDISK_VER="latest" ...@@ -687,7 +691,7 @@ CONFIG_PKG_RAMDISK_VER="latest"
# CONFIG_PKG_USING_ARM_2D is not set # CONFIG_PKG_USING_ARM_2D is not set
# CONFIG_PKG_USING_MCUBOOT is not set # CONFIG_PKG_USING_MCUBOOT is not set
# CONFIG_PKG_USING_TINYUSB is not set # CONFIG_PKG_USING_TINYUSB is not set
# CONFIG_PKG_USING_USB_STACK is not set # CONFIG_PKG_USING_CHERRYUSB is not set
# #
# peripheral libraries and drivers # peripheral libraries and drivers
...@@ -817,6 +821,7 @@ CONFIG_PKG_RAMDISK_VER="latest" ...@@ -817,6 +821,7 @@ CONFIG_PKG_RAMDISK_VER="latest"
# CONFIG_PKG_USING_CANFESTIVAL is not set # CONFIG_PKG_USING_CANFESTIVAL is not set
# CONFIG_PKG_USING_ZLIB is not set # CONFIG_PKG_USING_ZLIB is not set
# CONFIG_PKG_USING_MINIZIP is not set # CONFIG_PKG_USING_MINIZIP is not set
# CONFIG_PKG_USING_HEATSHRINK is not set
# CONFIG_PKG_USING_DSTR is not set # CONFIG_PKG_USING_DSTR is not set
# CONFIG_PKG_USING_TINYFRAME is not set # CONFIG_PKG_USING_TINYFRAME is not set
# CONFIG_PKG_USING_KENDRYTE_DEMO is not set # CONFIG_PKG_USING_KENDRYTE_DEMO is not set
...@@ -832,6 +837,8 @@ CONFIG_PKG_RAMDISK_VER="latest" ...@@ -832,6 +837,8 @@ CONFIG_PKG_RAMDISK_VER="latest"
# CONFIG_PKG_USING_LWGPS is not set # CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_STATE_MACHINE is not set # CONFIG_PKG_USING_STATE_MACHINE is not set
# CONFIG_PKG_USING_DESIGN_PATTERN is not set # CONFIG_PKG_USING_DESIGN_PATTERN is not set
# CONFIG_PKG_USING_CONTROLLER is not set
# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
# #
# Hardware Drivers Config # Hardware Drivers Config
...@@ -959,6 +966,8 @@ CONFIG_NU_PKG_USING_UTILS=y ...@@ -959,6 +966,8 @@ CONFIG_NU_PKG_USING_UTILS=y
CONFIG_NU_PKG_USING_NAU8822=y CONFIG_NU_PKG_USING_NAU8822=y
# CONFIG_NU_PKG_USING_DA9062 is not set # CONFIG_NU_PKG_USING_DA9062 is not set
# CONFIG_NU_PKG_USING_ILI9341 is not set # CONFIG_NU_PKG_USING_ILI9341 is not set
CONFIG_NU_PKG_USING_ADC_TOUCH=y
# CONFIG_NU_PKG_USING_ADC_TOUCH_SW is not set
# CONFIG_NU_PKG_USING_SPINAND is not set # CONFIG_NU_PKG_USING_SPINAND is not set
CONFIG_BOARD_USE_UTEST=y CONFIG_BOARD_USE_UTEST=y
CONFIG_UTEST_CMD_PREFIX="bsp.nuvoton.nk-n9h30.test.utest." CONFIG_UTEST_CMD_PREFIX="bsp.nuvoton.nk-n9h30.test.utest."
# NK-N9H30 # NK-N9H30
## 1. Introduction ## 1. Introduction
Nuvoton offers the emWin platform which is embedded with Nuvoton N9H MPU, it provides complete HMI solutions which are further enhanced by the emWin software. The N9H series with ARM926EJ-S core can operate at up to 300 MHz and can drive up to 1024x768 pixels in parallel port. It integrated TFT LCD controller and 2D graphics accelerator, up to 16 million colors (24-bit) LCD screen output, and provides high resolution and high chroma to deliver gorgeous display effects. To play compressed video in HMI screens smoothly, the N9H series is equipped with H.264 video decompression engine. It also offers built-in voice decoder, which can streamline the peripheral circuits of HMI applications with sound playback. It embedded up to 64 MB DDR memory, along with ample hardware storage and computing space for excellent design flexibility. Nuvoton offers HMI platforms which are embedded with Nuvoton N9H MPU. The N9H series with ARM926EJ-S core can operate at up to 300 MHz and can drive up to 1024x768 pixels in parallel port. It integrated TFT LCD controller and 2D graphics accelerator, up to 16 million colors (24-bit) LCD screen output, and provides high resolution and high chroma to deliver gorgeous display effects. It embedded up to 64 MB DDR memory, along with ample hardware storage and computing space for excellent design flexibility.
[![NK-N9H30](https://i.imgur.com/B04MCCf.png "NK-N9H30")](https://i.imgur.com/B04MCCf.png "NK-N9H30") [![NK-N9H30](https://i.imgur.com/B04MCCf.png "NK-N9H30")](https://i.imgur.com/B04MCCf.png "NK-N9H30")
...@@ -47,7 +47,7 @@ Support GCC, MDK4 and MDK5 IDE/compilers. More information of these compiler ver ...@@ -47,7 +47,7 @@ Support GCC, MDK4 and MDK5 IDE/compilers. More information of these compiler ver
| IDE/Compiler | Tested version | | IDE/Compiler | Tested version |
| ---------- | ---------------------------- | | ---------- | ---------------------------- |
| MDK5 | 5.26.2 | | MDK5 | 5.26.2 |
| GCC | GCC 5.4.1 20160919 (release) | | GCC | 6-2017-q1-update |
Notice: Please install ICE driver for development. Notice: Please install ICE driver for development.
...@@ -87,9 +87,10 @@ You can use Tera Term terminate emulator (or other software) to type commands of ...@@ -87,9 +87,10 @@ You can use Tera Term terminate emulator (or other software) to type commands of
[![Serial settings](https://i.imgur.com/5NYuSNM.png "Serial settings")](https://i.imgur.com/5NYuSNM.png "Serial settings") [![Serial settings](https://i.imgur.com/5NYuSNM.png "Serial settings")](https://i.imgur.com/5NYuSNM.png "Serial settings")
## 5. Purchase ## 5. Purchase
* [Nuvoton Direct](https://direct.nuvoton.com/en/numaker-emwin-n9h30) * [Nuvoton Direct](https://direct.nuvoton.com/en/numaker-hmi-n9h30)
## 6. Resources ## 6. Resources
* [Board Schematic](https://www.nuvoton.com/resource-download.jsp?tp_GUID=HL1020201117191514) * [Board Schematic](https://www.nuvoton.com/resource-download.jsp?tp_GUID=HL1020201117191514)
* [Download NK-N9H30 Quick Start Guide](https://www.nuvoton.com/resource-download.jsp?tp_GUID=UG1320210329155300) * [Download NK-N9H30 Quick Start Guide](https://www.nuvoton.com/resource-download.jsp?tp_GUID=UG1320210329155300)
* [Download NuWriter](https://github.com/OpenNuvoton/NUC970_NuWriter) * [Download NuWriter](https://github.com/OpenNuvoton/NUC970_NuWriter)
* [Download Windows 32-bit 6-2017-q1-update ARM GCC](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads/6-2017-q1-update)
...@@ -102,6 +102,7 @@ menu "Hardware Drivers Config" ...@@ -102,6 +102,7 @@ menu "Hardware Drivers Config"
config BOARD_USING_ADCTOUCH config BOARD_USING_ADCTOUCH
bool "ADC touching" bool "ADC touching"
select BSP_USING_ADC_TOUCH select BSP_USING_ADC_TOUCH
select NU_PKG_USING_ADC_TOUCH
help help
Choose this option if you use internal ADC touching function. Choose this option if you use internal ADC touching function.
......
...@@ -5,9 +5,13 @@ CPU = 'arm926' ...@@ -5,9 +5,13 @@ CPU = 'arm926'
# toolchains options # toolchains options
CROSS_TOOL = 'gcc' CROSS_TOOL = 'gcc'
#------- toolchains path -------------------------------------------------------
if os.getenv('RTT_CC'): if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC') CROSS_TOOL = os.getenv('RTT_CC')
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
# cross_tool provides the cross compiler
# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
if CROSS_TOOL == 'gcc': if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc' PLATFORM = 'gcc'
...@@ -20,7 +24,7 @@ if os.getenv('RTT_EXEC_PATH'): ...@@ -20,7 +24,7 @@ if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH') EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'debug' BUILD = 'debug'
#BUILD = 'release' #BUILD = ''
CORE = 'arm926ej-s' CORE = 'arm926ej-s'
MAP_FILE = 'rtthread_n9h30.map' MAP_FILE = 'rtthread_n9h30.map'
...@@ -32,9 +36,9 @@ if PLATFORM == 'gcc': ...@@ -32,9 +36,9 @@ if PLATFORM == 'gcc':
# toolchains # toolchains
PREFIX = 'arm-none-eabi-' PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc' CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc' AS = PREFIX + 'gcc'
AR = PREFIX + 'ar' AR = PREFIX + 'ar'
CXX = PREFIX + 'g++'
LINK = PREFIX + 'gcc' LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf' TARGET_EXT = 'elf'
SIZE = PREFIX + 'size' SIZE = PREFIX + 'size'
...@@ -53,11 +57,13 @@ if PLATFORM == 'gcc': ...@@ -53,11 +57,13 @@ if PLATFORM == 'gcc':
LPATH = '' LPATH = ''
if BUILD == 'debug': if BUILD == 'debug':
CFLAGS += ' -O2 -gdwarf-2' CFLAGS += ' -O0 -gdwarf-2 -g'
AFLAGS += ' -gdwarf-2' AFLAGS += ' -gdwarf-2'
else: else:
CFLAGS += ' -O2' CFLAGS += ' -O2'
CXXFLAGS = CFLAGS
POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n' POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n'
POST_ACTION += SIZE + ' $TARGET\n' POST_ACTION += SIZE + ' $TARGET\n'
#------- Keil settings --------------------------------------------------------- #------- Keil settings ---------------------------------------------------------
......
...@@ -5,9 +5,13 @@ CPU = 'arm926' ...@@ -5,9 +5,13 @@ CPU = 'arm926'
# toolchains options # toolchains options
CROSS_TOOL = 'gcc' CROSS_TOOL = 'gcc'
#------- toolchains path -------------------------------------------------------
if os.getenv('RTT_CC'): if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC') CROSS_TOOL = os.getenv('RTT_CC')
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
# cross_tool provides the cross compiler
# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
if CROSS_TOOL == 'gcc': if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc' PLATFORM = 'gcc'
...@@ -20,7 +24,7 @@ if os.getenv('RTT_EXEC_PATH'): ...@@ -20,7 +24,7 @@ if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH') EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'debug' BUILD = 'debug'
#BUILD = 'release' #BUILD = ''
CORE = 'arm926ej-s' CORE = 'arm926ej-s'
MAP_FILE = 'rtthread_nuc980.map' MAP_FILE = 'rtthread_nuc980.map'
...@@ -32,9 +36,9 @@ if PLATFORM == 'gcc': ...@@ -32,9 +36,9 @@ if PLATFORM == 'gcc':
# toolchains # toolchains
PREFIX = 'arm-none-eabi-' PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc' CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc' AS = PREFIX + 'gcc'
AR = PREFIX + 'ar' AR = PREFIX + 'ar'
CXX = PREFIX + 'g++'
LINK = PREFIX + 'gcc' LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf' TARGET_EXT = 'elf'
SIZE = PREFIX + 'size' SIZE = PREFIX + 'size'
...@@ -53,11 +57,13 @@ if PLATFORM == 'gcc': ...@@ -53,11 +57,13 @@ if PLATFORM == 'gcc':
LPATH = '' LPATH = ''
if BUILD == 'debug': if BUILD == 'debug':
CFLAGS += ' -O2 -gdwarf-2' CFLAGS += ' -O0 -gdwarf-2 -g'
AFLAGS += ' -gdwarf-2' AFLAGS += ' -gdwarf-2'
else: else:
CFLAGS += ' -O2' CFLAGS += ' -O2'
CXXFLAGS = CFLAGS
POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n' POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n'
POST_ACTION += SIZE + ' $TARGET\n' POST_ACTION += SIZE + ' $TARGET\n'
#------- Keil settings --------------------------------------------------------- #------- Keil settings ---------------------------------------------------------
......
...@@ -3,9 +3,19 @@ ...@@ -3,9 +3,19 @@
from building import * from building import *
cwd = GetCurrentDir() cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
src = Glob('*.c') + Glob('*.cpp') src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd, str(Dir('#'))] CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group') objs = objs + group
Return('objs')
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('LVGL-port', src, depend = ['PKG_USING_LVGL'], CPPPATH = CPPPATH)
Return('group')
此差异已折叠。
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('LVGL-port', src, depend = ['PKG_USING_LVGL'], CPPPATH = CPPPATH)
Return('group')
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -1151,6 +1151,7 @@ struct rt_device_graphic_info ...@@ -1151,6 +1151,7 @@ struct rt_device_graphic_info
rt_uint16_t height; /**< height of graphic device */ rt_uint16_t height; /**< height of graphic device */
rt_uint8_t *framebuffer; /**< frame buffer */ rt_uint8_t *framebuffer; /**< frame buffer */
rt_uint32_t smem_len; /**< allocated frame buffer size */
}; };
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册